1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* This Source Code Form is subject to the terms of the Mozilla Public 3 * License, v. 2.0. If a copy of the MPL was not distributed with this 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 6 #ifndef nsNPAPIPluginInstance_h_ 7 #define nsNPAPIPluginInstance_h_ 8 9 #include "nsSize.h" 10 #include "nsCOMPtr.h" 11 #include "nsTArray.h" 12 #include "nsPIDOMWindow.h" 13 #include "nsITimer.h" 14 #include "nsIPluginInstanceOwner.h" 15 #include "nsIURI.h" 16 #include "nsIChannel.h" 17 #include "nsHashKeys.h" 18 #include <prinrval.h> 19 #include "js/TypeDecls.h" 20 #include "nsIAudioChannelAgent.h" 21 #ifdef MOZ_WIDGET_ANDROID 22 #include "nsIRunnable.h" 23 #include "GLContextTypes.h" 24 #include "AndroidSurfaceTexture.h" 25 #include "AndroidBridge.h" 26 #include <map> 27 class PluginEventRunnable; 28 #endif 29 30 #include "mozilla/EventForwards.h" 31 #include "mozilla/TimeStamp.h" 32 #include "mozilla/PluginLibrary.h" 33 #include "mozilla/RefPtr.h" 34 #include "mozilla/WeakPtr.h" 35 36 class nsPluginStreamListenerPeer; // browser-initiated stream class 37 class nsNPAPIPluginStreamListener; // plugin-initiated stream class 38 class nsIPluginInstanceOwner; 39 class nsIOutputStream; 40 class nsPluginInstanceOwner; 41 42 #if defined(OS_WIN) 43 const NPDrawingModel kDefaultDrawingModel = NPDrawingModelSyncWin; 44 #elif defined(MOZ_X11) 45 const NPDrawingModel kDefaultDrawingModel = NPDrawingModelSyncX; 46 #elif defined(XP_MACOSX) 47 #ifndef NP_NO_QUICKDRAW 48 const NPDrawingModel kDefaultDrawingModel = NPDrawingModelQuickDraw; // Not supported 49 #else 50 const NPDrawingModel kDefaultDrawingModel = NPDrawingModelCoreGraphics; 51 #endif 52 #else 53 const NPDrawingModel kDefaultDrawingModel = static_cast<NPDrawingModel>(0); 54 #endif 55 56 /** 57 * Used to indicate whether it's OK to reenter Gecko and repaint, flush frames, 58 * run scripts, etc, during this plugin call. 59 * When NS_PLUGIN_CALL_UNSAFE_TO_REENTER_GECKO is set, we try to avoid dangerous 60 * Gecko activities when the plugin spins a nested event loop, on a best-effort 61 * basis. 62 */ 63 enum NSPluginCallReentry { 64 NS_PLUGIN_CALL_SAFE_TO_REENTER_GECKO, 65 NS_PLUGIN_CALL_UNSAFE_TO_REENTER_GECKO 66 }; 67 68 class nsNPAPITimer 69 { 70 public: 71 NPP npp; 72 uint32_t id; 73 nsCOMPtr<nsITimer> timer; 74 void (*callback)(NPP npp, uint32_t timerID); 75 bool inCallback; 76 bool needUnschedule; 77 }; 78 79 class nsNPAPIPluginInstance final : public nsIAudioChannelAgentCallback 80 , public mozilla::SupportsWeakPtr<nsNPAPIPluginInstance> 81 { 82 private: 83 typedef mozilla::PluginLibrary PluginLibrary; 84 85 public: 86 typedef mozilla::gfx::DrawTarget DrawTarget; 87 88 MOZ_DECLARE_WEAKREFERENCE_TYPENAME(nsNPAPIPluginInstance) 89 NS_DECL_THREADSAFE_ISUPPORTS 90 NS_DECL_NSIAUDIOCHANNELAGENTCALLBACK 91 92 nsresult Initialize(nsNPAPIPlugin *aPlugin, nsPluginInstanceOwner* aOwner, const nsACString& aMIMEType); 93 nsresult Start(); 94 nsresult Stop(); 95 nsresult SetWindow(NPWindow* window); 96 nsresult NewStreamFromPlugin(const char* type, const char* target, nsIOutputStream* *result); 97 nsresult Print(NPPrint* platformPrint); 98 nsresult HandleEvent(void* event, int16_t* result, 99 NSPluginCallReentry aSafeToReenterGecko = NS_PLUGIN_CALL_UNSAFE_TO_REENTER_GECKO); 100 nsresult GetValueFromPlugin(NPPVariable variable, void* value); 101 nsresult GetDrawingModel(int32_t* aModel); 102 nsresult IsRemoteDrawingCoreAnimation(bool* aDrawing); 103 nsresult ContentsScaleFactorChanged(double aContentsScaleFactor); 104 nsresult CSSZoomFactorChanged(float aCSSZoomFactor); 105 nsresult GetJSObject(JSContext *cx, JSObject** outObject); 106 bool ShouldCache(); 107 nsresult IsWindowless(bool* isWindowless); 108 nsresult AsyncSetWindow(NPWindow* window); 109 nsresult GetImageContainer(mozilla::layers::ImageContainer **aContainer); 110 nsresult GetImageSize(nsIntSize* aSize); 111 nsresult NotifyPainted(void); 112 nsresult GetIsOOP(bool* aIsOOP); 113 nsresult SetBackgroundUnknown(); 114 nsresult BeginUpdateBackground(nsIntRect* aRect, DrawTarget** aContext); 115 nsresult EndUpdateBackground(nsIntRect* aRect); 116 nsresult IsTransparent(bool* isTransparent); 117 nsresult GetFormValue(nsAString& aValue); 118 nsresult PushPopupsEnabledState(bool aEnabled); 119 nsresult PopPopupsEnabledState(); 120 nsresult GetPluginAPIVersion(uint16_t* version); 121 nsresult InvalidateRect(NPRect *invalidRect); 122 nsresult InvalidateRegion(NPRegion invalidRegion); 123 nsresult GetMIMEType(const char* *result); 124 #if defined(XP_WIN) 125 nsresult GetScrollCaptureContainer(mozilla::layers::ImageContainer **aContainer); 126 #endif 127 nsresult HandledWindowedPluginKeyEvent( 128 const mozilla::NativeEventData& aKeyEventData, 129 bool aIsConsumed); 130 nsPluginInstanceOwner* GetOwner(); 131 void SetOwner(nsPluginInstanceOwner *aOwner); 132 void DidComposite(); 133 HasAudioChannelAgent()134 bool HasAudioChannelAgent() const 135 { 136 return !!mAudioChannelAgent; 137 } 138 139 nsresult GetOrCreateAudioChannelAgent(nsIAudioChannelAgent** aAgent); 140 141 nsresult SetMuted(bool aIsMuted); 142 143 nsNPAPIPlugin* GetPlugin(); 144 145 nsresult GetNPP(NPP * aNPP); 146 147 NPError SetWindowless(bool aWindowless); 148 149 NPError SetTransparent(bool aTransparent); 150 151 NPError SetWantsAllNetworkStreams(bool aWantsAllNetworkStreams); 152 153 NPError SetUsesDOMForCursor(bool aUsesDOMForCursor); 154 bool UsesDOMForCursor(); 155 156 void SetDrawingModel(NPDrawingModel aModel); 157 void RedrawPlugin(); 158 #ifdef XP_MACOSX 159 void SetEventModel(NPEventModel aModel); 160 GetCurrentEvent()161 void* GetCurrentEvent() { 162 return mCurrentPluginEvent; 163 } 164 #endif 165 166 #ifdef MOZ_WIDGET_ANDROID 167 void NotifyForeground(bool aForeground); 168 void NotifyOnScreen(bool aOnScreen); 169 void MemoryPressure(); 170 void NotifyFullScreen(bool aFullScreen); 171 void NotifySize(nsIntSize size); 172 CurrentSize()173 nsIntSize CurrentSize() { return mCurrentSize; } 174 IsOnScreen()175 bool IsOnScreen() { 176 return mOnScreen; 177 } 178 GetANPDrawingModel()179 uint32_t GetANPDrawingModel() { return mANPDrawingModel; } 180 void SetANPDrawingModel(uint32_t aModel); 181 182 void* GetJavaSurface(); 183 184 void PostEvent(void* event); 185 186 // These are really mozilla::dom::ScreenOrientation, but it's 187 // difficult to include that here FullScreenOrientation()188 uint32_t FullScreenOrientation() { return mFullScreenOrientation; } 189 void SetFullScreenOrientation(uint32_t orientation); 190 191 void SetWakeLock(bool aLock); 192 193 mozilla::gl::GLContext* GLContext(); 194 195 // For ANPOpenGL 196 class TextureInfo { 197 public: TextureInfo()198 TextureInfo() : 199 mTexture(0), mWidth(0), mHeight(0), mInternalFormat(0) 200 { 201 } 202 TextureInfo(GLuint aTexture,int32_t aWidth,int32_t aHeight,GLuint aInternalFormat)203 TextureInfo(GLuint aTexture, int32_t aWidth, int32_t aHeight, GLuint aInternalFormat) : 204 mTexture(aTexture), mWidth(aWidth), mHeight(aHeight), mInternalFormat(aInternalFormat) 205 { 206 } 207 208 GLuint mTexture; 209 int32_t mWidth; 210 int32_t mHeight; 211 GLuint mInternalFormat; 212 }; 213 214 // For ANPNativeWindow 215 void* AcquireContentWindow(); 216 217 mozilla::gl::AndroidSurfaceTexture* AsSurfaceTexture(); 218 219 // For ANPVideo 220 class VideoInfo { 221 public: VideoInfo(mozilla::gl::AndroidSurfaceTexture * aSurfaceTexture)222 VideoInfo(mozilla::gl::AndroidSurfaceTexture* aSurfaceTexture) : 223 mSurfaceTexture(aSurfaceTexture) 224 { 225 } 226 ~VideoInfo()227 ~VideoInfo() 228 { 229 mSurfaceTexture = nullptr; 230 } 231 232 RefPtr<mozilla::gl::AndroidSurfaceTexture> mSurfaceTexture; 233 gfxRect mDimensions; 234 }; 235 236 void* AcquireVideoWindow(); 237 void ReleaseVideoWindow(void* aWindow); 238 void SetVideoDimensions(void* aWindow, gfxRect aDimensions); 239 240 void GetVideos(nsTArray<VideoInfo*>& aVideos); 241 SetOriginPos(mozilla::gl::OriginPos aOriginPos)242 void SetOriginPos(mozilla::gl::OriginPos aOriginPos) { 243 mOriginPos = aOriginPos; 244 } OriginPos()245 mozilla::gl::OriginPos OriginPos() const { return mOriginPos; } 246 247 static nsNPAPIPluginInstance* GetFromNPP(NPP npp); 248 #endif 249 250 nsresult NewStreamListener(const char* aURL, void* notifyData, 251 nsNPAPIPluginStreamListener** listener); 252 253 nsNPAPIPluginInstance(); 254 255 // To be called when an instance becomes orphaned, when 256 // it's plugin is no longer guaranteed to be around. 257 void Destroy(); 258 259 // Indicates whether the plugin is running normally. IsRunning()260 bool IsRunning() { 261 return RUNNING == mRunning; 262 } HasStartedDestroying()263 bool HasStartedDestroying() { 264 return mRunning >= DESTROYING; 265 } 266 267 // Indicates whether the plugin is running normally or being shut down CanFireNotifications()268 bool CanFireNotifications() { 269 return mRunning == RUNNING || mRunning == DESTROYING; 270 } 271 272 // return is only valid when the plugin is not running 273 mozilla::TimeStamp StopTime(); 274 275 // cache this NPAPI plugin 276 void SetCached(bool aCache); 277 278 already_AddRefed<nsPIDOMWindowOuter> GetDOMWindow(); 279 280 nsresult PrivateModeStateChanged(bool aEnabled); 281 282 nsresult IsPrivateBrowsing(bool *aEnabled); 283 284 nsresult GetDOMElement(nsIDOMElement* *result); 285 286 nsNPAPITimer* TimerWithID(uint32_t id, uint32_t* index); 287 uint32_t ScheduleTimer(uint32_t interval, NPBool repeat, void (*timerFunc)(NPP npp, uint32_t timerID)); 288 void UnscheduleTimer(uint32_t timerID); 289 NPBool ConvertPoint(double sourceX, double sourceY, NPCoordinateSpace sourceSpace, double *destX, double *destY, NPCoordinateSpace destSpace); 290 291 292 nsTArray<nsNPAPIPluginStreamListener*> *StreamListeners(); 293 294 nsTArray<nsPluginStreamListenerPeer*> *FileCachedStreamListeners(); 295 296 nsresult AsyncSetWindow(NPWindow& window); 297 298 void URLRedirectResponse(void* notifyData, NPBool allow); 299 300 NPError InitAsyncSurface(NPSize *size, NPImageFormat format, 301 void *initData, NPAsyncSurface *surface); 302 NPError FinalizeAsyncSurface(NPAsyncSurface *surface); 303 void SetCurrentAsyncSurface(NPAsyncSurface *surface, NPRect *changed); 304 305 // Called when the instance fails to instantiate beceause the Carbon 306 // event model is not supported. 307 void CarbonNPAPIFailure(); 308 309 // Returns the contents scale factor of the screen the plugin is drawn on. 310 double GetContentsScaleFactor(); 311 312 // Returns the css zoom factor of the document the plugin is drawn on. 313 float GetCSSZoomFactor(); 314 315 nsresult GetRunID(uint32_t *aRunID); 316 InPluginCallUnsafeForReentry()317 static bool InPluginCallUnsafeForReentry() { return gInUnsafePluginCalls > 0; } BeginPluginCall(NSPluginCallReentry aReentryState)318 static void BeginPluginCall(NSPluginCallReentry aReentryState) 319 { 320 if (aReentryState == NS_PLUGIN_CALL_UNSAFE_TO_REENTER_GECKO) { 321 ++gInUnsafePluginCalls; 322 } 323 } EndPluginCall(NSPluginCallReentry aReentryState)324 static void EndPluginCall(NSPluginCallReentry aReentryState) 325 { 326 if (aReentryState == NS_PLUGIN_CALL_UNSAFE_TO_REENTER_GECKO) { 327 NS_ASSERTION(gInUnsafePluginCalls > 0, "Must be in plugin call"); 328 --gInUnsafePluginCalls; 329 } 330 } 331 332 protected: 333 334 virtual ~nsNPAPIPluginInstance(); 335 336 nsresult GetTagType(nsPluginTagType *result); 337 nsresult GetMode(int32_t *result); 338 339 // check if this is a Java applet and affected by bug 750480 340 void CheckJavaC2PJSObjectQuirk(uint16_t paramCount, 341 const char* const* names, 342 const char* const* values); 343 344 // The structure used to communicate between the plugin instance and 345 // the browser. 346 NPP_t mNPP; 347 348 NPDrawingModel mDrawingModel; 349 350 #ifdef MOZ_WIDGET_ANDROID 351 uint32_t mANPDrawingModel; 352 353 friend class PluginEventRunnable; 354 355 nsTArray<RefPtr<PluginEventRunnable>> mPostedEvents; 356 void PopPostedEvent(PluginEventRunnable* r); 357 void OnSurfaceTextureFrameAvailable(); 358 359 uint32_t mFullScreenOrientation; 360 bool mWakeLocked; 361 bool mFullScreen; 362 mozilla::gl::OriginPos mOriginPos; 363 364 RefPtr<mozilla::gl::AndroidSurfaceTexture> mContentSurface; 365 #endif 366 367 enum { 368 NOT_STARTED, 369 RUNNING, 370 DESTROYING, 371 DESTROYED 372 } mRunning; 373 374 // these are used to store the windowless properties 375 // which the browser will later query 376 bool mWindowless; 377 bool mTransparent; 378 bool mCached; 379 bool mUsesDOMForCursor; 380 381 public: 382 // True while creating the plugin, or calling NPP_SetWindow() on it. 383 bool mInPluginInitCall; 384 385 nsXPIDLCString mFakeURL; 386 387 private: 388 RefPtr<nsNPAPIPlugin> mPlugin; 389 390 nsTArray<nsNPAPIPluginStreamListener*> mStreamListeners; 391 392 nsTArray<nsPluginStreamListenerPeer*> mFileCachedStreamListeners; 393 394 nsTArray<PopupControlState> mPopupStates; 395 396 char* mMIMEType; 397 398 // Weak pointer to the owner. The owner nulls this out (by calling 399 // InvalidateOwner()) when it's no longer our owner. 400 nsPluginInstanceOwner *mOwner; 401 402 nsTArray<nsNPAPITimer*> mTimers; 403 404 #ifdef XP_MACOSX 405 // non-null during a HandleEvent call 406 void* mCurrentPluginEvent; 407 #endif 408 409 // Timestamp for the last time this plugin was stopped. 410 // This is only valid when the plugin is actually stopped! 411 mozilla::TimeStamp mStopTime; 412 413 #ifdef MOZ_WIDGET_ANDROID 414 already_AddRefed<mozilla::gl::AndroidSurfaceTexture> CreateSurfaceTexture(); 415 416 std::map<void*, VideoInfo*> mVideos; 417 bool mOnScreen; 418 419 nsIntSize mCurrentSize; 420 #endif 421 422 // is this instance Java and affected by bug 750480? 423 bool mHaveJavaC2PJSObjectQuirk; 424 425 static uint32_t gInUnsafePluginCalls; 426 427 // The arrays can only be released when the plugin instance is destroyed, 428 // because the plugin, in in-process mode, might keep a reference to them. 429 uint32_t mCachedParamLength; 430 char **mCachedParamNames; 431 char **mCachedParamValues; 432 433 nsCOMPtr<nsIAudioChannelAgent> mAudioChannelAgent; 434 bool mMuted; 435 }; 436 437 // On Android, we need to guard against plugin code leaking entries in the local 438 // JNI ref table. See https://bugzilla.mozilla.org/show_bug.cgi?id=780831#c21 439 #ifdef MOZ_WIDGET_ANDROID 440 #define MAIN_THREAD_JNI_REF_GUARD mozilla::AutoLocalJNIFrame jniFrame 441 #else 442 #define MAIN_THREAD_JNI_REF_GUARD 443 #endif 444 445 void NS_NotifyBeginPluginCall(NSPluginCallReentry aReentryState); 446 void NS_NotifyPluginCall(NSPluginCallReentry aReentryState); 447 448 #define NS_TRY_SAFE_CALL_RETURN(ret, fun, pluginInst, pluginCallReentry) \ 449 PR_BEGIN_MACRO \ 450 MAIN_THREAD_JNI_REF_GUARD; \ 451 NS_NotifyBeginPluginCall(pluginCallReentry); \ 452 ret = fun; \ 453 NS_NotifyPluginCall(pluginCallReentry); \ 454 PR_END_MACRO 455 456 #define NS_TRY_SAFE_CALL_VOID(fun, pluginInst, pluginCallReentry) \ 457 PR_BEGIN_MACRO \ 458 MAIN_THREAD_JNI_REF_GUARD; \ 459 NS_NotifyBeginPluginCall(pluginCallReentry); \ 460 fun; \ 461 NS_NotifyPluginCall(pluginCallReentry); \ 462 PR_END_MACRO 463 464 #endif // nsNPAPIPluginInstance_h_ 465