michael@0: /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- michael@0: * vim: sw=4 ts=4 et : 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 mozilla_plugins_PluginModuleParent_h michael@0: #define mozilla_plugins_PluginModuleParent_h michael@0: michael@0: #include "base/process.h" michael@0: #include "mozilla/FileUtils.h" michael@0: #include "mozilla/PluginLibrary.h" michael@0: #include "mozilla/plugins/ScopedMethodFactory.h" michael@0: #include "mozilla/plugins/PluginProcessParent.h" michael@0: #include "mozilla/plugins/PPluginModuleParent.h" michael@0: #include "mozilla/plugins/PluginMessageUtils.h" michael@0: #include "npapi.h" michael@0: #include "npfunctions.h" michael@0: #include "nsAutoPtr.h" michael@0: #include "nsDataHashtable.h" michael@0: #include "nsHashKeys.h" michael@0: #include "nsIObserver.h" michael@0: michael@0: #ifdef MOZ_CRASHREPORTER michael@0: #include "nsExceptionHandler.h" michael@0: #endif michael@0: michael@0: namespace mozilla { michael@0: namespace dom { michael@0: class PCrashReporterParent; michael@0: class CrashReporterParent; michael@0: } michael@0: michael@0: namespace plugins { michael@0: //----------------------------------------------------------------------------- michael@0: michael@0: class BrowserStreamParent; michael@0: class PluginIdentifierParent; michael@0: class PluginInstanceParent; michael@0: michael@0: #ifdef XP_WIN michael@0: class PluginHangUIParent; michael@0: #endif michael@0: michael@0: /** michael@0: * PluginModuleParent michael@0: * michael@0: * This class implements the NPP API from the perspective of the rest michael@0: * of Gecko, forwarding NPP calls along to the child process that is michael@0: * actually running the plugin. michael@0: * michael@0: * This class /also/ implements a version of the NPN API, because the michael@0: * child process needs to make these calls back into Gecko proper. michael@0: * This class is responsible for "actually" making those function calls. michael@0: */ michael@0: class PluginModuleParent michael@0: : public PPluginModuleParent michael@0: , public PluginLibrary michael@0: #ifdef MOZ_CRASHREPORTER_INJECTOR michael@0: , public CrashReporter::InjectorCrashCallback michael@0: #endif michael@0: { michael@0: private: michael@0: typedef mozilla::PluginLibrary PluginLibrary; michael@0: typedef mozilla::dom::PCrashReporterParent PCrashReporterParent; michael@0: typedef mozilla::dom::CrashReporterParent CrashReporterParent; michael@0: michael@0: protected: michael@0: michael@0: virtual PPluginIdentifierParent* michael@0: AllocPPluginIdentifierParent(const nsCString& aString, michael@0: const int32_t& aInt, michael@0: const bool& aTemporary) MOZ_OVERRIDE; michael@0: michael@0: virtual bool michael@0: DeallocPPluginIdentifierParent(PPluginIdentifierParent* aActor) MOZ_OVERRIDE; michael@0: michael@0: PPluginInstanceParent* michael@0: AllocPPluginInstanceParent(const nsCString& aMimeType, michael@0: const uint16_t& aMode, michael@0: const InfallibleTArray& aNames, michael@0: const InfallibleTArray& aValues, michael@0: NPError* rv) MOZ_OVERRIDE; michael@0: michael@0: virtual bool michael@0: DeallocPPluginInstanceParent(PPluginInstanceParent* aActor) MOZ_OVERRIDE; michael@0: michael@0: public: michael@0: // aFilePath is UTF8, not native! michael@0: PluginModuleParent(const char* aFilePath); michael@0: virtual ~PluginModuleParent(); michael@0: michael@0: virtual void SetPlugin(nsNPAPIPlugin* plugin) MOZ_OVERRIDE michael@0: { michael@0: mPlugin = plugin; michael@0: } michael@0: michael@0: virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE; michael@0: michael@0: /** michael@0: * LoadModule michael@0: * michael@0: * This may or may not launch a plugin child process, michael@0: * and may or may not be very expensive. michael@0: */ michael@0: static PluginLibrary* LoadModule(const char* aFilePath); michael@0: michael@0: const NPNetscapeFuncs* GetNetscapeFuncs() { michael@0: return mNPNIface; michael@0: } michael@0: michael@0: PluginProcessParent* Process() const { return mSubprocess; } michael@0: base::ProcessHandle ChildProcessHandle() { return mSubprocess->GetChildProcessHandle(); } michael@0: michael@0: bool OkToCleanup() const { michael@0: return !IsOnCxxStack(); michael@0: } michael@0: michael@0: /** michael@0: * Get an identifier actor for this NPIdentifier. If this is a temporary michael@0: * identifier, the temporary refcount is increased by one. This method michael@0: * is intended only for use by StackIdentifier and the scriptable michael@0: * Enumerate hook. michael@0: */ michael@0: PluginIdentifierParent* michael@0: GetIdentifierForNPIdentifier(NPP npp, NPIdentifier aIdentifier); michael@0: michael@0: void ProcessRemoteNativeEventsInInterruptCall(); michael@0: michael@0: void TerminateChildProcess(MessageLoop* aMsgLoop); michael@0: michael@0: #ifdef XP_WIN michael@0: void michael@0: ExitedCxxStack() MOZ_OVERRIDE; michael@0: #endif // XP_WIN michael@0: michael@0: protected: michael@0: virtual mozilla::ipc::RacyInterruptPolicy michael@0: MediateInterruptRace(const Message& parent, const Message& child) MOZ_OVERRIDE michael@0: { michael@0: return MediateRace(parent, child); michael@0: } michael@0: michael@0: virtual bool ShouldContinueFromReplyTimeout() MOZ_OVERRIDE; michael@0: michael@0: virtual bool michael@0: RecvBackUpXResources(const FileDescriptor& aXSocketFd) MOZ_OVERRIDE; michael@0: michael@0: virtual bool michael@0: AnswerNPN_UserAgent(nsCString* userAgent) MOZ_OVERRIDE; michael@0: michael@0: virtual bool michael@0: AnswerNPN_GetValue_WithBoolReturn(const NPNVariable& aVariable, michael@0: NPError* aError, michael@0: bool* aBoolVal) MOZ_OVERRIDE; michael@0: michael@0: virtual bool AnswerProcessSomeEvents() MOZ_OVERRIDE; michael@0: michael@0: virtual bool michael@0: RecvProcessNativeEventsInInterruptCall() MOZ_OVERRIDE; michael@0: michael@0: virtual bool michael@0: RecvPluginShowWindow(const uint32_t& aWindowId, const bool& aModal, michael@0: const int32_t& aX, const int32_t& aY, michael@0: const size_t& aWidth, const size_t& aHeight) MOZ_OVERRIDE; michael@0: michael@0: virtual bool michael@0: RecvPluginHideWindow(const uint32_t& aWindowId) MOZ_OVERRIDE; michael@0: michael@0: virtual PCrashReporterParent* michael@0: AllocPCrashReporterParent(mozilla::dom::NativeThreadId* id, michael@0: uint32_t* processType) MOZ_OVERRIDE; michael@0: virtual bool michael@0: DeallocPCrashReporterParent(PCrashReporterParent* actor) MOZ_OVERRIDE; michael@0: michael@0: virtual bool michael@0: RecvSetCursor(const NSCursorInfo& aCursorInfo) MOZ_OVERRIDE; michael@0: michael@0: virtual bool michael@0: RecvShowCursor(const bool& aShow) MOZ_OVERRIDE; michael@0: michael@0: virtual bool michael@0: RecvPushCursor(const NSCursorInfo& aCursorInfo) MOZ_OVERRIDE; michael@0: michael@0: virtual bool michael@0: RecvPopCursor() MOZ_OVERRIDE; michael@0: michael@0: virtual bool michael@0: RecvGetNativeCursorsSupported(bool* supported) MOZ_OVERRIDE; michael@0: michael@0: virtual bool michael@0: RecvNPN_SetException(PPluginScriptableObjectParent* aActor, michael@0: const nsCString& aMessage) MOZ_OVERRIDE; michael@0: michael@0: virtual bool michael@0: RecvNPN_ReloadPlugins(const bool& aReloadPages) MOZ_OVERRIDE; michael@0: michael@0: static PluginInstanceParent* InstCast(NPP instance); michael@0: static BrowserStreamParent* StreamCast(NPP instance, NPStream* s); michael@0: michael@0: private: michael@0: void SetPluginFuncs(NPPluginFuncs* aFuncs); michael@0: michael@0: // Implement the module-level functions from NPAPI; these are michael@0: // normally resolved directly from the DSO. michael@0: #ifdef OS_LINUX michael@0: NPError NP_Initialize(const NPNetscapeFuncs* npnIface, michael@0: NPPluginFuncs* nppIface); michael@0: #else michael@0: NPError NP_Initialize(const NPNetscapeFuncs* npnIface); michael@0: NPError NP_GetEntryPoints(NPPluginFuncs* nppIface); michael@0: #endif michael@0: michael@0: // NPP-like API that Gecko calls are trampolined into. These michael@0: // messages then get forwarded along to the plugin instance, michael@0: // and then eventually the child process. michael@0: michael@0: static NPError NPP_Destroy(NPP instance, NPSavedData** save); michael@0: michael@0: static NPError NPP_SetWindow(NPP instance, NPWindow* window); michael@0: static NPError NPP_NewStream(NPP instance, NPMIMEType type, NPStream* stream, michael@0: NPBool seekable, uint16_t* stype); michael@0: static NPError NPP_DestroyStream(NPP instance, michael@0: NPStream* stream, NPReason reason); michael@0: static int32_t NPP_WriteReady(NPP instance, NPStream* stream); michael@0: static int32_t NPP_Write(NPP instance, NPStream* stream, michael@0: int32_t offset, int32_t len, void* buffer); michael@0: static void NPP_StreamAsFile(NPP instance, michael@0: NPStream* stream, const char* fname); michael@0: static void NPP_Print(NPP instance, NPPrint* platformPrint); michael@0: static int16_t NPP_HandleEvent(NPP instance, void* event); michael@0: static void NPP_URLNotify(NPP instance, const char* url, michael@0: NPReason reason, void* notifyData); michael@0: static NPError NPP_GetValue(NPP instance, michael@0: NPPVariable variable, void *ret_value); michael@0: static NPError NPP_SetValue(NPP instance, NPNVariable variable, michael@0: void *value); michael@0: static void NPP_URLRedirectNotify(NPP instance, const char* url, michael@0: int32_t status, void* notifyData); michael@0: michael@0: virtual bool HasRequiredFunctions(); michael@0: virtual nsresult AsyncSetWindow(NPP instance, NPWindow* window); michael@0: virtual nsresult GetImageContainer(NPP instance, mozilla::layers::ImageContainer** aContainer); michael@0: virtual nsresult GetImageSize(NPP instance, nsIntSize* aSize); michael@0: virtual bool IsOOP() MOZ_OVERRIDE { return true; } michael@0: virtual nsresult SetBackgroundUnknown(NPP instance) MOZ_OVERRIDE; michael@0: virtual nsresult BeginUpdateBackground(NPP instance, michael@0: const nsIntRect& aRect, michael@0: gfxContext** aCtx) MOZ_OVERRIDE; michael@0: virtual nsresult EndUpdateBackground(NPP instance, michael@0: gfxContext* aCtx, michael@0: const nsIntRect& aRect) MOZ_OVERRIDE; michael@0: michael@0: #if defined(XP_UNIX) && !defined(XP_MACOSX) && !defined(MOZ_WIDGET_GONK) michael@0: virtual nsresult NP_Initialize(NPNetscapeFuncs* bFuncs, NPPluginFuncs* pFuncs, NPError* error); michael@0: #else michael@0: virtual nsresult NP_Initialize(NPNetscapeFuncs* bFuncs, NPError* error); michael@0: #endif michael@0: virtual nsresult NP_Shutdown(NPError* error); michael@0: virtual nsresult NP_GetMIMEDescription(const char** mimeDesc); michael@0: virtual nsresult NP_GetValue(void *future, NPPVariable aVariable, michael@0: void *aValue, NPError* error); michael@0: #if defined(XP_WIN) || defined(XP_MACOSX) michael@0: virtual nsresult NP_GetEntryPoints(NPPluginFuncs* pFuncs, NPError* error); michael@0: #endif michael@0: virtual nsresult NPP_New(NPMIMEType pluginType, NPP instance, michael@0: uint16_t mode, int16_t argc, char* argn[], michael@0: char* argv[], NPSavedData* saved, michael@0: NPError* error); michael@0: virtual nsresult NPP_ClearSiteData(const char* site, uint64_t flags, michael@0: uint64_t maxAge); michael@0: virtual nsresult NPP_GetSitesWithData(InfallibleTArray& result); michael@0: michael@0: #if defined(XP_MACOSX) michael@0: virtual nsresult IsRemoteDrawingCoreAnimation(NPP instance, bool *aDrawing); michael@0: virtual nsresult ContentsScaleFactorChanged(NPP instance, double aContentsScaleFactor); michael@0: #endif michael@0: michael@0: private: michael@0: CrashReporterParent* CrashReporter(); michael@0: michael@0: #ifdef MOZ_CRASHREPORTER michael@0: void ProcessFirstMinidump(); michael@0: void WriteExtraDataForMinidump(CrashReporter::AnnotationTable& notes); michael@0: #endif michael@0: void CleanupFromTimeout(const bool aByHangUI); michael@0: void SetChildTimeout(const int32_t aChildTimeout); michael@0: static void TimeoutChanged(const char* aPref, void* aModule); michael@0: void NotifyPluginCrashed(); michael@0: michael@0: #ifdef MOZ_ENABLE_PROFILER_SPS michael@0: void InitPluginProfiling(); michael@0: void ShutdownPluginProfiling(); michael@0: #endif michael@0: michael@0: PluginProcessParent* mSubprocess; michael@0: bool mShutdown; michael@0: bool mClearSiteDataSupported; michael@0: bool mGetSitesWithDataSupported; michael@0: const NPNetscapeFuncs* mNPNIface; michael@0: nsDataHashtable, PluginIdentifierParent*> mIdentifiers; michael@0: nsNPAPIPlugin* mPlugin; michael@0: ScopedMethodFactory mTaskFactory; michael@0: nsString mPluginDumpID; michael@0: nsString mBrowserDumpID; michael@0: nsString mHangID; michael@0: nsRefPtr mProfilerObserver; michael@0: #ifdef XP_WIN michael@0: InfallibleTArray mPluginCpuUsageOnHang; michael@0: PluginHangUIParent *mHangUIParent; michael@0: bool mHangUIEnabled; michael@0: bool mIsTimerReset; michael@0: #ifdef MOZ_CRASHREPORTER michael@0: /** michael@0: * This mutex protects the crash reporter when the Plugin Hang UI event michael@0: * handler is executing off main thread. It is intended to protect both michael@0: * the mCrashReporter variable in addition to the CrashReporterParent object michael@0: * that mCrashReporter refers to. michael@0: */ michael@0: mozilla::Mutex mCrashReporterMutex; michael@0: CrashReporterParent* mCrashReporter; michael@0: #endif // MOZ_CRASHREPORTER michael@0: michael@0: michael@0: void michael@0: EvaluateHangUIState(const bool aReset); michael@0: michael@0: bool michael@0: GetPluginName(nsAString& aPluginName); michael@0: michael@0: /** michael@0: * Launches the Plugin Hang UI. michael@0: * michael@0: * @return true if plugin-hang-ui.exe has been successfully launched. michael@0: * false if the Plugin Hang UI is disabled, already showing, michael@0: * or the launch failed. michael@0: */ michael@0: bool michael@0: LaunchHangUI(); michael@0: michael@0: /** michael@0: * Finishes the Plugin Hang UI and cancels if it is being shown to the user. michael@0: */ michael@0: void michael@0: FinishHangUI(); michael@0: #endif michael@0: michael@0: #ifdef MOZ_X11 michael@0: // Dup of plugin's X socket, used to scope its resources to this michael@0: // object instead of the plugin process's lifetime michael@0: ScopedClose mPluginXSocketFdDup; michael@0: #endif michael@0: michael@0: friend class mozilla::dom::CrashReporterParent; michael@0: michael@0: #ifdef MOZ_CRASHREPORTER_INJECTOR michael@0: void InitializeInjector(); michael@0: michael@0: void OnCrash(DWORD processID) MOZ_OVERRIDE; michael@0: michael@0: DWORD mFlashProcess1; michael@0: DWORD mFlashProcess2; michael@0: #endif michael@0: }; michael@0: michael@0: } // namespace plugins michael@0: } // namespace mozilla michael@0: michael@0: #endif // mozilla_plugins_PluginModuleParent_h