michael@0: /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef nsNPAPIPluginInstance_h_ michael@0: #define nsNPAPIPluginInstance_h_ michael@0: michael@0: #include "nsCOMPtr.h" michael@0: #include "nsTArray.h" michael@0: #include "nsPIDOMWindow.h" michael@0: #include "nsITimer.h" michael@0: #include "nsIPluginInstanceOwner.h" michael@0: #include "nsIURI.h" michael@0: #include "nsIChannel.h" michael@0: #include "nsInterfaceHashtable.h" michael@0: #include "nsHashKeys.h" michael@0: #include michael@0: #include "js/TypeDecls.h" michael@0: #ifdef MOZ_WIDGET_ANDROID michael@0: #include "nsAutoPtr.h" michael@0: #include "nsIRunnable.h" michael@0: #include "GLContextTypes.h" michael@0: #include "nsSurfaceTexture.h" michael@0: #include "AndroidBridge.h" michael@0: #include michael@0: class PluginEventRunnable; michael@0: class SharedPluginTexture; michael@0: #endif michael@0: michael@0: #include "mozilla/TimeStamp.h" michael@0: #include "mozilla/PluginLibrary.h" michael@0: michael@0: class nsPluginStreamListenerPeer; // browser-initiated stream class michael@0: class nsNPAPIPluginStreamListener; // plugin-initiated stream class michael@0: class nsIPluginInstanceOwner; michael@0: class nsIOutputStream; michael@0: class nsPluginInstanceOwner; michael@0: michael@0: #if defined(OS_WIN) michael@0: const NPDrawingModel kDefaultDrawingModel = NPDrawingModelSyncWin; michael@0: #elif defined(MOZ_X11) michael@0: const NPDrawingModel kDefaultDrawingModel = NPDrawingModelSyncX; michael@0: #elif defined(XP_MACOSX) michael@0: #ifndef NP_NO_QUICKDRAW michael@0: const NPDrawingModel kDefaultDrawingModel = NPDrawingModelQuickDraw; // Not supported michael@0: #else michael@0: const NPDrawingModel kDefaultDrawingModel = NPDrawingModelCoreGraphics; michael@0: #endif michael@0: #else michael@0: const NPDrawingModel kDefaultDrawingModel = static_cast(0); michael@0: #endif michael@0: michael@0: /** michael@0: * Used to indicate whether it's OK to reenter Gecko and repaint, flush frames, michael@0: * run scripts, etc, during this plugin call. michael@0: * When NS_PLUGIN_CALL_UNSAFE_TO_REENTER_GECKO is set, we try to avoid dangerous michael@0: * Gecko activities when the plugin spins a nested event loop, on a best-effort michael@0: * basis. michael@0: */ michael@0: enum NSPluginCallReentry { michael@0: NS_PLUGIN_CALL_SAFE_TO_REENTER_GECKO, michael@0: NS_PLUGIN_CALL_UNSAFE_TO_REENTER_GECKO michael@0: }; michael@0: michael@0: class nsNPAPITimer michael@0: { michael@0: public: michael@0: NPP npp; michael@0: uint32_t id; michael@0: nsCOMPtr timer; michael@0: void (*callback)(NPP npp, uint32_t timerID); michael@0: bool inCallback; michael@0: bool needUnschedule; michael@0: }; michael@0: michael@0: class nsNPAPIPluginInstance : public nsISupports michael@0: { michael@0: private: michael@0: typedef mozilla::PluginLibrary PluginLibrary; michael@0: michael@0: public: michael@0: NS_DECL_THREADSAFE_ISUPPORTS michael@0: michael@0: nsresult Initialize(nsNPAPIPlugin *aPlugin, nsPluginInstanceOwner* aOwner, const char* aMIMEType); michael@0: nsresult Start(); michael@0: nsresult Stop(); michael@0: nsresult SetWindow(NPWindow* window); michael@0: nsresult NewStreamFromPlugin(const char* type, const char* target, nsIOutputStream* *result); michael@0: nsresult Print(NPPrint* platformPrint); michael@0: nsresult HandleEvent(void* event, int16_t* result, michael@0: NSPluginCallReentry aSafeToReenterGecko = NS_PLUGIN_CALL_UNSAFE_TO_REENTER_GECKO); michael@0: nsresult GetValueFromPlugin(NPPVariable variable, void* value); michael@0: nsresult GetDrawingModel(int32_t* aModel); michael@0: nsresult IsRemoteDrawingCoreAnimation(bool* aDrawing); michael@0: nsresult ContentsScaleFactorChanged(double aContentsScaleFactor); michael@0: nsresult GetJSObject(JSContext *cx, JSObject** outObject); michael@0: bool ShouldCache(); michael@0: nsresult IsWindowless(bool* isWindowless); michael@0: nsresult AsyncSetWindow(NPWindow* window); michael@0: nsresult GetImageContainer(mozilla::layers::ImageContainer **aContainer); michael@0: nsresult GetImageSize(nsIntSize* aSize); michael@0: nsresult NotifyPainted(void); michael@0: nsresult GetIsOOP(bool* aIsOOP); michael@0: nsresult SetBackgroundUnknown(); michael@0: nsresult BeginUpdateBackground(nsIntRect* aRect, gfxContext** aContext); michael@0: nsresult EndUpdateBackground(gfxContext* aContext, nsIntRect* aRect); michael@0: nsresult IsTransparent(bool* isTransparent); michael@0: nsresult GetFormValue(nsAString& aValue); michael@0: nsresult PushPopupsEnabledState(bool aEnabled); michael@0: nsresult PopPopupsEnabledState(); michael@0: nsresult GetPluginAPIVersion(uint16_t* version); michael@0: nsresult InvalidateRect(NPRect *invalidRect); michael@0: nsresult InvalidateRegion(NPRegion invalidRegion); michael@0: nsresult GetMIMEType(const char* *result); michael@0: nsresult GetJSContext(JSContext* *outContext); michael@0: nsPluginInstanceOwner* GetOwner(); michael@0: void SetOwner(nsPluginInstanceOwner *aOwner); michael@0: nsresult ShowStatus(const char* message); michael@0: michael@0: nsNPAPIPlugin* GetPlugin(); michael@0: michael@0: nsresult GetNPP(NPP * aNPP); michael@0: michael@0: NPError SetWindowless(bool aWindowless); michael@0: michael@0: NPError SetTransparent(bool aTransparent); michael@0: michael@0: NPError SetWantsAllNetworkStreams(bool aWantsAllNetworkStreams); michael@0: michael@0: NPError SetUsesDOMForCursor(bool aUsesDOMForCursor); michael@0: bool UsesDOMForCursor(); michael@0: michael@0: void SetDrawingModel(NPDrawingModel aModel); michael@0: void RedrawPlugin(); michael@0: #ifdef XP_MACOSX michael@0: void SetEventModel(NPEventModel aModel); michael@0: #endif michael@0: michael@0: #ifdef MOZ_WIDGET_ANDROID michael@0: void NotifyForeground(bool aForeground); michael@0: void NotifyOnScreen(bool aOnScreen); michael@0: void MemoryPressure(); michael@0: void NotifyFullScreen(bool aFullScreen); michael@0: void NotifySize(nsIntSize size); michael@0: michael@0: nsIntSize CurrentSize() { return mCurrentSize; } michael@0: michael@0: bool IsOnScreen() { michael@0: return mOnScreen; michael@0: } michael@0: michael@0: uint32_t GetANPDrawingModel() { return mANPDrawingModel; } michael@0: void SetANPDrawingModel(uint32_t aModel); michael@0: michael@0: void* GetJavaSurface(); michael@0: michael@0: void PostEvent(void* event); michael@0: michael@0: // These are really mozilla::dom::ScreenOrientation, but it's michael@0: // difficult to include that here michael@0: uint32_t FullScreenOrientation() { return mFullScreenOrientation; } michael@0: void SetFullScreenOrientation(uint32_t orientation); michael@0: michael@0: void SetWakeLock(bool aLock); michael@0: michael@0: mozilla::gl::GLContext* GLContext(); michael@0: michael@0: // For ANPOpenGL michael@0: class TextureInfo { michael@0: public: michael@0: TextureInfo() : michael@0: mTexture(0), mWidth(0), mHeight(0), mInternalFormat(0) michael@0: { michael@0: } michael@0: michael@0: TextureInfo(GLuint aTexture, int32_t aWidth, int32_t aHeight, GLuint aInternalFormat) : michael@0: mTexture(aTexture), mWidth(aWidth), mHeight(aHeight), mInternalFormat(aInternalFormat) michael@0: { michael@0: } michael@0: michael@0: GLuint mTexture; michael@0: int32_t mWidth; michael@0: int32_t mHeight; michael@0: GLuint mInternalFormat; michael@0: }; michael@0: michael@0: TextureInfo LockContentTexture(); michael@0: void ReleaseContentTexture(TextureInfo& aTextureInfo); michael@0: michael@0: // For ANPNativeWindow michael@0: void* AcquireContentWindow(); michael@0: michael@0: mozilla::gl::SharedTextureHandle CreateSharedHandle(); michael@0: michael@0: // For ANPVideo michael@0: class VideoInfo { michael@0: public: michael@0: VideoInfo(nsSurfaceTexture* aSurfaceTexture) : michael@0: mSurfaceTexture(aSurfaceTexture) michael@0: { michael@0: } michael@0: michael@0: ~VideoInfo() michael@0: { michael@0: mSurfaceTexture = nullptr; michael@0: } michael@0: michael@0: nsRefPtr mSurfaceTexture; michael@0: gfxRect mDimensions; michael@0: }; michael@0: michael@0: void* AcquireVideoWindow(); michael@0: void ReleaseVideoWindow(void* aWindow); michael@0: void SetVideoDimensions(void* aWindow, gfxRect aDimensions); michael@0: michael@0: void GetVideos(nsTArray& aVideos); michael@0: michael@0: void SetInverted(bool aInverted); michael@0: bool Inverted() { return mInverted; } michael@0: michael@0: static nsNPAPIPluginInstance* GetFromNPP(NPP npp); michael@0: #endif michael@0: michael@0: nsresult NewStreamListener(const char* aURL, void* notifyData, michael@0: nsNPAPIPluginStreamListener** listener); michael@0: michael@0: nsNPAPIPluginInstance(); michael@0: virtual ~nsNPAPIPluginInstance(); michael@0: michael@0: // To be called when an instance becomes orphaned, when michael@0: // it's plugin is no longer guaranteed to be around. michael@0: void Destroy(); michael@0: michael@0: // Indicates whether the plugin is running normally. michael@0: bool IsRunning() { michael@0: return RUNNING == mRunning; michael@0: } michael@0: bool HasStartedDestroying() { michael@0: return mRunning >= DESTROYING; michael@0: } michael@0: michael@0: // Indicates whether the plugin is running normally or being shut down michael@0: bool CanFireNotifications() { michael@0: return mRunning == RUNNING || mRunning == DESTROYING; michael@0: } michael@0: michael@0: // return is only valid when the plugin is not running michael@0: mozilla::TimeStamp StopTime(); michael@0: michael@0: // cache this NPAPI plugin michael@0: void SetCached(bool aCache); michael@0: michael@0: already_AddRefed GetDOMWindow(); michael@0: michael@0: nsresult PrivateModeStateChanged(bool aEnabled); michael@0: michael@0: nsresult IsPrivateBrowsing(bool *aEnabled); michael@0: michael@0: nsresult GetDOMElement(nsIDOMElement* *result); michael@0: michael@0: nsNPAPITimer* TimerWithID(uint32_t id, uint32_t* index); michael@0: uint32_t ScheduleTimer(uint32_t interval, NPBool repeat, void (*timerFunc)(NPP npp, uint32_t timerID)); michael@0: void UnscheduleTimer(uint32_t timerID); michael@0: NPError PopUpContextMenu(NPMenu* menu); michael@0: NPBool ConvertPoint(double sourceX, double sourceY, NPCoordinateSpace sourceSpace, double *destX, double *destY, NPCoordinateSpace destSpace); michael@0: michael@0: michael@0: nsTArray *StreamListeners(); michael@0: michael@0: nsTArray *FileCachedStreamListeners(); michael@0: michael@0: nsresult AsyncSetWindow(NPWindow& window); michael@0: michael@0: void URLRedirectResponse(void* notifyData, NPBool allow); michael@0: michael@0: NPError InitAsyncSurface(NPSize *size, NPImageFormat format, michael@0: void *initData, NPAsyncSurface *surface); michael@0: NPError FinalizeAsyncSurface(NPAsyncSurface *surface); michael@0: void SetCurrentAsyncSurface(NPAsyncSurface *surface, NPRect *changed); michael@0: michael@0: // Called when the instance fails to instantiate beceause the Carbon michael@0: // event model is not supported. michael@0: void CarbonNPAPIFailure(); michael@0: michael@0: // Returns the contents scale factor of the screen the plugin is drawn on. michael@0: double GetContentsScaleFactor(); michael@0: michael@0: static bool InPluginCallUnsafeForReentry() { return gInUnsafePluginCalls > 0; } michael@0: static void BeginPluginCall(NSPluginCallReentry aReentryState) michael@0: { michael@0: if (aReentryState == NS_PLUGIN_CALL_UNSAFE_TO_REENTER_GECKO) { michael@0: ++gInUnsafePluginCalls; michael@0: } michael@0: } michael@0: static void EndPluginCall(NSPluginCallReentry aReentryState) michael@0: { michael@0: if (aReentryState == NS_PLUGIN_CALL_UNSAFE_TO_REENTER_GECKO) { michael@0: NS_ASSERTION(gInUnsafePluginCalls > 0, "Must be in plugin call"); michael@0: --gInUnsafePluginCalls; michael@0: } michael@0: } michael@0: michael@0: protected: michael@0: michael@0: nsresult GetTagType(nsPluginTagType *result); michael@0: nsresult GetAttributes(uint16_t& n, const char*const*& names, michael@0: const char*const*& values); michael@0: nsresult GetParameters(uint16_t& n, const char*const*& names, michael@0: const char*const*& values); michael@0: nsresult GetMode(int32_t *result); michael@0: michael@0: // check if this is a Java applet and affected by bug 750480 michael@0: void CheckJavaC2PJSObjectQuirk(uint16_t paramCount, michael@0: const char* const* names, michael@0: const char* const* values); michael@0: michael@0: // The structure used to communicate between the plugin instance and michael@0: // the browser. michael@0: NPP_t mNPP; michael@0: michael@0: NPDrawingModel mDrawingModel; michael@0: michael@0: #ifdef MOZ_WIDGET_ANDROID michael@0: uint32_t mANPDrawingModel; michael@0: michael@0: friend class PluginEventRunnable; michael@0: michael@0: nsTArray> mPostedEvents; michael@0: void PopPostedEvent(PluginEventRunnable* r); michael@0: void OnSurfaceTextureFrameAvailable(); michael@0: michael@0: uint32_t mFullScreenOrientation; michael@0: bool mWakeLocked; michael@0: bool mFullScreen; michael@0: bool mInverted; michael@0: michael@0: nsRefPtr mContentTexture; michael@0: nsRefPtr mContentSurface; michael@0: #endif michael@0: michael@0: enum { michael@0: NOT_STARTED, michael@0: RUNNING, michael@0: DESTROYING, michael@0: DESTROYED michael@0: } mRunning; michael@0: michael@0: // these are used to store the windowless properties michael@0: // which the browser will later query michael@0: bool mWindowless; michael@0: bool mTransparent; michael@0: bool mCached; michael@0: bool mUsesDOMForCursor; michael@0: michael@0: public: michael@0: // True while creating the plugin, or calling NPP_SetWindow() on it. michael@0: bool mInPluginInitCall; michael@0: michael@0: nsXPIDLCString mFakeURL; michael@0: michael@0: private: michael@0: nsNPAPIPlugin* mPlugin; michael@0: michael@0: nsTArray mStreamListeners; michael@0: michael@0: nsTArray mFileCachedStreamListeners; michael@0: michael@0: nsTArray mPopupStates; michael@0: michael@0: char* mMIMEType; michael@0: michael@0: // Weak pointer to the owner. The owner nulls this out (by calling michael@0: // InvalidateOwner()) when it's no longer our owner. michael@0: nsPluginInstanceOwner *mOwner; michael@0: michael@0: nsTArray mTimers; michael@0: michael@0: // non-null during a HandleEvent call michael@0: void* mCurrentPluginEvent; michael@0: michael@0: // Timestamp for the last time this plugin was stopped. michael@0: // This is only valid when the plugin is actually stopped! michael@0: mozilla::TimeStamp mStopTime; michael@0: michael@0: #ifdef MOZ_WIDGET_ANDROID michael@0: void EnsureSharedTexture(); michael@0: nsSurfaceTexture* CreateSurfaceTexture(); michael@0: michael@0: std::map mVideos; michael@0: bool mOnScreen; michael@0: michael@0: nsIntSize mCurrentSize; michael@0: #endif michael@0: michael@0: // is this instance Java and affected by bug 750480? michael@0: bool mHaveJavaC2PJSObjectQuirk; michael@0: michael@0: static uint32_t gInUnsafePluginCalls; michael@0: }; michael@0: michael@0: // On Android, we need to guard against plugin code leaking entries in the local michael@0: // JNI ref table. See https://bugzilla.mozilla.org/show_bug.cgi?id=780831#c21 michael@0: #ifdef MOZ_WIDGET_ANDROID michael@0: #define MAIN_THREAD_JNI_REF_GUARD mozilla::AutoLocalJNIFrame jniFrame michael@0: #else michael@0: #define MAIN_THREAD_JNI_REF_GUARD michael@0: #endif michael@0: michael@0: PRIntervalTime NS_NotifyBeginPluginCall(NSPluginCallReentry aReentryState); michael@0: void NS_NotifyPluginCall(PRIntervalTime aTime, NSPluginCallReentry aReentryState); michael@0: michael@0: #define NS_TRY_SAFE_CALL_RETURN(ret, fun, pluginInst, pluginCallReentry) \ michael@0: PR_BEGIN_MACRO \ michael@0: MAIN_THREAD_JNI_REF_GUARD; \ michael@0: PRIntervalTime startTime = NS_NotifyBeginPluginCall(pluginCallReentry); \ michael@0: ret = fun; \ michael@0: NS_NotifyPluginCall(startTime, pluginCallReentry); \ michael@0: PR_END_MACRO michael@0: michael@0: #define NS_TRY_SAFE_CALL_VOID(fun, pluginInst, pluginCallReentry) \ michael@0: PR_BEGIN_MACRO \ michael@0: MAIN_THREAD_JNI_REF_GUARD; \ michael@0: PRIntervalTime startTime = NS_NotifyBeginPluginCall(pluginCallReentry); \ michael@0: fun; \ michael@0: NS_NotifyPluginCall(startTime, pluginCallReentry); \ michael@0: PR_END_MACRO michael@0: michael@0: #endif // nsNPAPIPluginInstance_h_