From f5c20f47d7c3d2bda837d90327903b8542b9a005 Mon Sep 17 00:00:00 2001 From: Bill McCloskey Date: Tue, 18 Nov 2014 21:46:01 -0800 Subject: [PATCH] Bug 1093693 - [e10s] Don't use sync messages between plugins and chrome process (r=jimm) --- dom/plugins/ipc/PPluginModule.ipdl | 27 +++-- dom/plugins/ipc/PluginModuleChild.cpp | 43 ++++--- dom/plugins/ipc/PluginModuleChild.h | 12 +- dom/plugins/ipc/PluginModuleParent.cpp | 149 +++++++++++++++++++------ dom/plugins/ipc/PluginModuleParent.h | 23 ++-- 5 files changed, 178 insertions(+), 76 deletions(-) diff --git a/dom/plugins/ipc/PPluginModule.ipdl b/dom/plugins/ipc/PPluginModule.ipdl index bb878c4c063c..6d7613f13e26 100644 --- a/dom/plugins/ipc/PPluginModule.ipdl +++ b/dom/plugins/ipc/PPluginModule.ipdl @@ -17,6 +17,21 @@ using struct nsID from "nsID.h"; namespace mozilla { namespace plugins { +struct PluginSettings +{ + // These settings correspond to NPNVariable. They are fetched from + // mozilla::plugins::parent::_getvalue. + bool javascriptEnabled; + bool asdEnabled; + bool isOffline; + bool supportsXembed; + bool supportsWindowless; + + // These settings come from elsewhere. + nsCString userAgent; + bool nativeCursorsSupported; +}; + intr protocol PPluginModule { bridges PContent, PPluginModule; @@ -34,7 +49,7 @@ child: intr NP_GetEntryPoints() returns (NPError rv); - intr NP_Initialize() + intr NP_Initialize(PluginSettings settings) returns (NPError rv); intr PPluginInstance(nsCString aMimeType, @@ -69,6 +84,8 @@ child: intr GeckoGetProfile() returns (nsCString aProfile); + async SettingChanged(PluginSettings settings); + parent: /** * This message is only used on X11 platforms. @@ -83,13 +100,6 @@ parent: */ async BackUpXResources(FileDescriptor aXSocketFd); - intr NPN_UserAgent() - returns (nsCString userAgent); - - intr NPN_GetValue_WithBoolReturn(NPNVariable aVariable) - returns (NPError aError, - bool aBoolVal); - // Wake up and process a few native events. Periodically called by // Gtk-specific code upon detecting that the plugin process has // entered a nested event loop. If the browser doesn't process @@ -108,7 +118,6 @@ parent: async ShowCursor(bool show); async PushCursor(NSCursorInfo cursorInfo); async PopCursor(); - sync GetNativeCursorsSupported() returns (bool supported); sync NPN_SetException(nsCString message); diff --git a/dom/plugins/ipc/PluginModuleChild.cpp b/dom/plugins/ipc/PluginModuleChild.cpp index 3fcb851c314b..08cf0f5a13aa 100644 --- a/dom/plugins/ipc/PluginModuleChild.cpp +++ b/dom/plugins/ipc/PluginModuleChild.cpp @@ -821,10 +821,7 @@ PluginModuleChild::CleanUp() const char* PluginModuleChild::GetUserAgent() { - if (mUserAgent.IsVoid() && !CallNPN_UserAgent(&mUserAgent)) - return nullptr; - - return NullableStringGet(mUserAgent); + return NullableStringGet(Settings().userAgent()); } //----------------------------------------------------------------------------- @@ -1120,18 +1117,21 @@ _getvalue(NPP aNPP, #endif return NPERR_GENERIC_ERROR; - case NPNVjavascriptEnabledBool: // Intentional fall-through - case NPNVasdEnabledBool: // Intentional fall-through - case NPNVisOfflineBool: // Intentional fall-through - case NPNVSupportsXEmbedBool: // Intentional fall-through - case NPNVSupportsWindowless: { // Intentional fall-through - NPError result; - bool value; - PluginModuleChild::GetChrome()-> - CallNPN_GetValue_WithBoolReturn(aVariable, &result, &value); - *(NPBool*)aValue = value ? true : false; - return result; - } + case NPNVjavascriptEnabledBool: + *(NPBool*)aValue = PluginModuleChild::GetChrome()->Settings().javascriptEnabled(); + return NPERR_NO_ERROR; + case NPNVasdEnabledBool: + *(NPBool*)aValue = PluginModuleChild::GetChrome()->Settings().asdEnabled(); + return NPERR_NO_ERROR; + case NPNVisOfflineBool: + *(NPBool*)aValue = PluginModuleChild::GetChrome()->Settings().isOffline(); + return NPERR_NO_ERROR; + case NPNVSupportsXEmbedBool: + *(NPBool*)aValue = PluginModuleChild::GetChrome()->Settings().supportsXembed(); + return NPERR_NO_ERROR; + case NPNVSupportsWindowless: + *(NPBool*)aValue = PluginModuleChild::GetChrome()->Settings().supportsWindowless(); + return NPERR_NO_ERROR; #if defined(MOZ_WIDGET_GTK) case NPNVxDisplay: { if (aNPP) { @@ -1834,6 +1834,13 @@ _urlredirectresponse(NPP instance, void* notifyData, NPBool allow) //----------------------------------------------------------------------------- +bool +PluginModuleChild::RecvSettingChanged(const PluginSettings& aSettings) +{ + mCachedSettings = aSettings; + return true; +} + bool PluginModuleChild::AnswerNP_GetEntryPoints(NPError* _retval) { @@ -1852,12 +1859,14 @@ PluginModuleChild::AnswerNP_GetEntryPoints(NPError* _retval) } bool -PluginModuleChild::AnswerNP_Initialize(NPError* _retval) +PluginModuleChild::AnswerNP_Initialize(const PluginSettings& aSettings, NPError* _retval) { PLUGIN_LOG_DEBUG_METHOD; AssertPluginThread(); MOZ_ASSERT(mIsChrome); + mCachedSettings = aSettings; + #ifdef OS_WIN SetEventHooks(); #endif diff --git a/dom/plugins/ipc/PluginModuleChild.h b/dom/plugins/ipc/PluginModuleChild.h index 7305fe4f9a7b..a161afa608c2 100644 --- a/dom/plugins/ipc/PluginModuleChild.h +++ b/dom/plugins/ipc/PluginModuleChild.h @@ -72,9 +72,11 @@ protected: virtual bool ShouldContinueFromReplyTimeout() MOZ_OVERRIDE; + virtual bool RecvSettingChanged(const PluginSettings& aSettings) MOZ_OVERRIDE; + // Implement the PPluginModuleChild interface virtual bool AnswerNP_GetEntryPoints(NPError* rv) MOZ_OVERRIDE; - virtual bool AnswerNP_Initialize(NPError* rv) MOZ_OVERRIDE; + virtual bool AnswerNP_Initialize(const PluginSettings& aSettings, NPError* rv) MOZ_OVERRIDE; virtual PPluginModuleChild* AllocPPluginModuleChild(mozilla::ipc::Transport* aTransport, @@ -226,9 +228,7 @@ public: } bool GetNativeCursorsSupported() { - bool supported = false; - SendGetNativeCursorsSupported(&supported); - return supported; + return Settings().nativeCursorsSupported(); } #endif @@ -278,6 +278,8 @@ public: int GetQuirks() { return mQuirks; } + const PluginSettings& Settings() const { return mCachedSettings; } + private: void AddQuirk(PluginQuirks quirk) { if (mQuirks == QUIRKS_NOT_INITIALIZED) @@ -318,6 +320,8 @@ private: NPPluginFuncs mFunctions; + PluginSettings mCachedSettings; + #if defined(MOZ_WIDGET_GTK) // If a plugin spins a nested glib event loop in response to a // synchronous IPC message from the browser, the loop might break diff --git a/dom/plugins/ipc/PluginModuleParent.cpp b/dom/plugins/ipc/PluginModuleParent.cpp index 84d8eea5cae9..ee0b8049e46c 100755 --- a/dom/plugins/ipc/PluginModuleParent.cpp +++ b/dom/plugins/ipc/PluginModuleParent.cpp @@ -252,6 +252,8 @@ PluginModuleChromeParent::PluginModuleChromeParent(const char* aFilePath, uint32 Preferences::RegisterCallback(TimeoutChanged, kHangUIMinDisplayPref, this); #endif + RegisterSettingsCallbacks(); + #ifdef MOZ_ENABLE_PROFILER_SPS InitPluginProfiling(); #endif @@ -295,6 +297,8 @@ PluginModuleChromeParent::~PluginModuleChromeParent() Preferences::UnregisterCallback(TimeoutChanged, kHangUITimeoutPref, this); Preferences::UnregisterCallback(TimeoutChanged, kHangUIMinDisplayPref, this); + UnregisterSettingsCallbacks(); + if (mHangUIParent) { delete mHangUIParent; mHangUIParent = nullptr; @@ -903,6 +907,9 @@ PluginModuleChromeParent::ActorDestroy(ActorDestroyReason why) #endif } + // We can't broadcast settings changes anymore. + UnregisterSettingsCallbacks(); + PluginModuleParent::ActorDestroy(why); } @@ -1156,13 +1163,6 @@ PluginModuleParent::NPP_URLRedirectNotify(NPP instance, const char* url, i->NPP_URLRedirectNotify(url, status, notifyData); } -bool -PluginModuleParent::AnswerNPN_UserAgent(nsCString* userAgent) -{ - *userAgent = NullableString(mNPNIface->uagent(nullptr)); - return true; -} - PluginInstanceParent* PluginModuleParent::InstCast(NPP instance) { @@ -1262,6 +1262,107 @@ PluginModuleParent::EndUpdateBackground(NPP instance, return i->EndUpdateBackground(aCtx, aRect); } +class OfflineObserver MOZ_FINAL : public nsIObserver +{ +public: + NS_DECL_ISUPPORTS + NS_DECL_NSIOBSERVER + + explicit OfflineObserver(PluginModuleChromeParent* pmp) + : mPmp(pmp) + {} + +private: + ~OfflineObserver() {} + PluginModuleChromeParent* mPmp; +}; + +NS_IMPL_ISUPPORTS(OfflineObserver, nsIObserver) + +NS_IMETHODIMP +OfflineObserver::Observe(nsISupports *aSubject, + const char *aTopic, + const char16_t *aData) +{ + MOZ_ASSERT(!strcmp(aTopic, "ipc:network:set-offline")); + mPmp->CachedSettingChanged(); + return NS_OK; +} + +static const char* kSettingsPrefs[] = + {"javascript.enabled", + "dom.ipc.plugins.nativeCursorSupport"}; + +void +PluginModuleChromeParent::RegisterSettingsCallbacks() +{ + for (size_t i = 0; i < ArrayLength(kSettingsPrefs); i++) { + Preferences::RegisterCallback(CachedSettingChanged, kSettingsPrefs[i], this); + } + + nsCOMPtr observerService = mozilla::services::GetObserverService(); + if (observerService) { + mOfflineObserver = new OfflineObserver(this); + observerService->AddObserver(mOfflineObserver, "ipc:network:set-offline", false); + } +} + +void +PluginModuleChromeParent::UnregisterSettingsCallbacks() +{ + for (size_t i = 0; i < ArrayLength(kSettingsPrefs); i++) { + Preferences::UnregisterCallback(CachedSettingChanged, kSettingsPrefs[i], this); + } + + nsCOMPtr observerService = mozilla::services::GetObserverService(); + if (observerService) { + observerService->RemoveObserver(mOfflineObserver, "ipc:network:set-offline"); + mOfflineObserver = nullptr; + } +} + +bool +PluginModuleParent::GetSetting(NPNVariable aVariable) +{ + NPBool boolVal = false; + mozilla::plugins::parent::_getvalue(nullptr, aVariable, &boolVal); + return boolVal; +} + +void +PluginModuleParent::GetSettings(PluginSettings* aSettings) +{ + aSettings->javascriptEnabled() = GetSetting(NPNVjavascriptEnabledBool); + aSettings->asdEnabled() = GetSetting(NPNVasdEnabledBool); + aSettings->isOffline() = GetSetting(NPNVisOfflineBool); + aSettings->supportsXembed() = GetSetting(NPNVSupportsXEmbedBool); + aSettings->supportsWindowless() = GetSetting(NPNVSupportsWindowless); + aSettings->userAgent() = NullableString(mNPNIface->uagent(nullptr)); + +#if defined(XP_MACOSX) + aSettings->nativeCursorsSupported() = + Preferences::GetBool("dom.ipc.plugins.nativeCursorSupport", false); +#else + // Need to initialize this to satisfy IPDL. + aSettings->nativeCursorsSupported() = false; +#endif +} + +void +PluginModuleChromeParent::CachedSettingChanged() +{ + PluginSettings settings; + GetSettings(&settings); + unused << SendSettingChanged(settings); +} + +/* static */ void +PluginModuleChromeParent::CachedSettingChanged(const char* aPref, void* aModule) +{ + PluginModuleChromeParent *module = static_cast(aModule); + module->CachedSettingChanged(); +} + #if defined(XP_UNIX) && !defined(XP_MACOSX) && !defined(MOZ_WIDGET_GONK) nsresult PluginModuleParent::NP_Initialize(NPNetscapeFuncs* bFuncs, NPPluginFuncs* pFuncs, NPError* error) @@ -1277,7 +1378,9 @@ PluginModuleParent::NP_Initialize(NPNetscapeFuncs* bFuncs, NPPluginFuncs* pFuncs *error = NPERR_NO_ERROR; if (IsChrome()) { - if (!CallNP_Initialize(error)) { + PluginSettings settings; + GetSettings(&settings); + if (!CallNP_Initialize(settings, error)) { Close(); return NS_ERROR_FAILURE; } @@ -1315,7 +1418,9 @@ PluginModuleChromeParent::NP_Initialize(NPNetscapeFuncs* bFuncs, NPError* error) if (NS_FAILED(rv)) return rv; - if (!CallNP_Initialize(error)) { + PluginSettings settings; + GetSettings(&settings); + if (!CallNP_Initialize(settings, error)) { Close(); return NS_ERROR_FAILURE; } @@ -1539,17 +1644,6 @@ PluginModuleParent::ContentsScaleFactorChanged(NPP instance, double aContentsSca } #endif // #if defined(XP_MACOSX) -bool -PluginModuleParent::AnswerNPN_GetValue_WithBoolReturn(const NPNVariable& aVariable, - NPError* aError, - bool* aBoolVal) -{ - NPBool boolVal = false; - *aError = mozilla::plugins::parent::_getvalue(nullptr, aVariable, &boolVal); - *aBoolVal = boolVal ? true : false; - return true; -} - #if defined(MOZ_WIDGET_QT) static const int kMaxtimeToProcessEvents = 30; bool @@ -1749,21 +1843,6 @@ PluginModuleParent::RecvPopCursor() #endif } -bool -PluginModuleParent::RecvGetNativeCursorsSupported(bool* supported) -{ - PLUGIN_LOG_DEBUG(("%s", FULLFUNCTION)); -#if defined(XP_MACOSX) - *supported = - Preferences::GetBool("dom.ipc.plugins.nativeCursorSupport", false); - return true; -#else - NS_NOTREACHED( - "PluginInstanceParent::RecvGetNativeCursorSupportLevel not implemented!"); - return false; -#endif -} - bool PluginModuleParent::RecvNPN_SetException(const nsCString& aMessage) { diff --git a/dom/plugins/ipc/PluginModuleParent.h b/dom/plugins/ipc/PluginModuleParent.h index 529576d0636f..5868c181bb90 100644 --- a/dom/plugins/ipc/PluginModuleParent.h +++ b/dom/plugins/ipc/PluginModuleParent.h @@ -115,14 +115,6 @@ protected: virtual bool RecvBackUpXResources(const FileDescriptor& aXSocketFd) MOZ_OVERRIDE; - virtual bool - AnswerNPN_UserAgent(nsCString* userAgent) MOZ_OVERRIDE; - - virtual bool - AnswerNPN_GetValue_WithBoolReturn(const NPNVariable& aVariable, - NPError* aError, - bool* aBoolVal) MOZ_OVERRIDE; - virtual bool AnswerProcessSomeEvents() MOZ_OVERRIDE; virtual bool @@ -154,9 +146,6 @@ protected: virtual bool RecvPopCursor() MOZ_OVERRIDE; - virtual bool - RecvGetNativeCursorsSupported(bool* supported) MOZ_OVERRIDE; - virtual bool RecvNPN_SetException(const nsCString& aMessage) MOZ_OVERRIDE; @@ -242,6 +231,9 @@ protected: protected: void NotifyPluginCrashed(); + bool GetSetting(NPNVariable aVariable); + void GetSettings(PluginSettings* aSettings); + bool mIsChrome; bool mShutdown; bool mClearSiteDataSupported; @@ -312,6 +304,8 @@ class PluginModuleChromeParent OnHangUIContinue(); #endif // XP_WIN + void CachedSettingChanged(); + private: virtual void EnteredCxxStack() MOZ_OVERRIDE; @@ -360,8 +354,13 @@ private: void ShutdownPluginProfiling(); #endif + void RegisterSettingsCallbacks(); + void UnregisterSettingsCallbacks(); + virtual bool RecvNotifyContentModuleDestroyed() MOZ_OVERRIDE; + static void CachedSettingChanged(const char* aPref, void* aModule); + PluginProcessParent* mSubprocess; uint32_t mPluginId; @@ -422,6 +421,8 @@ private: DWORD mFlashProcess1; DWORD mFlashProcess2; #endif + + nsCOMPtr mOfflineObserver; }; } // namespace plugins