Bug 1093693 - [e10s] Don't use sync messages between plugins and chrome process (r=jimm)
authorBill McCloskey <wmccloskey@mozilla.com>
Tue, 18 Nov 2014 21:46:01 -0800
changeset 240724 8c37c5083952ab0b0a645f42c09f46c2abaed07c
parent 240723 d99caaf9ab8c61a8999ca04bcb3d521bf59c4b0e
child 240725 e30507b1a89fe26d8e0631e5375fb9e7462f8764
push id4311
push userraliiev@mozilla.com
push dateMon, 12 Jan 2015 19:37:41 +0000
treeherdermozilla-beta@150c9fed433b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjimm
bugs1093693
milestone36.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1093693 - [e10s] Don't use sync messages between plugins and chrome process (r=jimm)
dom/plugins/ipc/PPluginModule.ipdl
dom/plugins/ipc/PluginModuleChild.cpp
dom/plugins/ipc/PluginModuleChild.h
dom/plugins/ipc/PluginModuleParent.cpp
dom/plugins/ipc/PluginModuleParent.h
--- a/dom/plugins/ipc/PPluginModule.ipdl
+++ b/dom/plugins/ipc/PPluginModule.ipdl
@@ -12,16 +12,31 @@ using NPError from "npapi.h";
 using NPNVariable from "npapi.h";
 using mozilla::dom::NativeThreadId from "mozilla/dom/TabMessageUtils.h";
 using class mac_plugin_interposing::NSCursorInfo from "mozilla/plugins/PluginMessageUtils.h";
 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;
 
   manages PPluginInstance;
   manages PCrashReporter;
 
 both:
@@ -29,17 +44,17 @@ both:
   // a nested event loop for the current interrupt call.
   async ProcessNativeEventsInInterruptCall();
 
 child:
   // Forces the child process to update its plugin function table.
   intr NP_GetEntryPoints()
     returns (NPError rv);
 
-  intr NP_Initialize()
+  intr NP_Initialize(PluginSettings settings)
     returns (NPError rv);
 
   intr PPluginInstance(nsCString aMimeType,
                       uint16_t aMode,
                       nsCString[] aNames,
                       nsCString[] aValues)
     returns (NPError rv);
 
@@ -64,37 +79,32 @@ child:
   async SetParentHangTimeout(uint32_t seconds);
 
   intr PCrashReporter()
     returns (NativeThreadId tid, uint32_t processType);
 
   intr GeckoGetProfile()
     returns (nsCString aProfile);
 
+  async SettingChanged(PluginSettings settings);
+
 parent:
   /**
    * This message is only used on X11 platforms.
    *
    * Send a dup of the plugin process's X socket to the parent
    * process.  In theory, this scheme keeps the plugin's X resources
    * around until after both the plugin process shuts down *and* the
    * parent process closes the dup fd.  This is used to prevent the
    * parent process from crashing on X errors if, e.g., the plugin
    * crashes *just before* a repaint and the parent process tries to
    * use the newly-invalid surface.
    */
   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
   // native events, then "livelock" and some other glitches can occur.
   intr ProcessSomeEvents();
 
   // OS X Specific calls to manage the plugin's window
   // when interposing system calls.
@@ -103,17 +113,16 @@ parent:
                          size_t aWidth, size_t aHeight);
   async PluginHideWindow(uint32_t aWindowId);
 
   // OS X Specific calls to allow the plugin to manage the cursor.
   async SetCursor(NSCursorInfo cursorInfo);
   async ShowCursor(bool show);
   async PushCursor(NSCursorInfo cursorInfo);
   async PopCursor();
-  sync GetNativeCursorsSupported() returns (bool supported);
 
   sync NPN_SetException(nsCString message);
 
   async NPN_ReloadPlugins(bool aReloadPages);
 
   // Notifies the chrome process that a PluginModuleChild linked to a content
   // process was destroyed. The chrome process may choose to asynchronously shut
   // down the plugin process in response.
--- a/dom/plugins/ipc/PluginModuleChild.cpp
+++ b/dom/plugins/ipc/PluginModuleChild.cpp
@@ -816,20 +816,17 @@ PluginModuleChild::ActorDestroy(ActorDes
 void
 PluginModuleChild::CleanUp()
 {
 }
 
 const char*
 PluginModuleChild::GetUserAgent()
 {
-    if (mUserAgent.IsVoid() && !CallNPN_UserAgent(&mUserAgent))
-        return nullptr;
-
-    return NullableStringGet(mUserAgent);
+    return NullableStringGet(Settings().userAgent());
 }
 
 //-----------------------------------------------------------------------------
 // FIXME/cjones: just getting this out of the way for the moment ...
 
 namespace mozilla {
 namespace plugins {
 namespace child {
@@ -1115,28 +1112,31 @@ NPError
         // Copied from nsNPAPIPlugin.cpp
         case NPNVToolkit:
 #if defined(MOZ_WIDGET_GTK) || defined(MOZ_WIDGET_QT)
             *static_cast<NPNToolkitType*>(aValue) = NPNVGtk2;
             return NPERR_NO_ERROR;
 #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) {
                 return InstCast(aNPP)->NPN_GetValue(aVariable, aValue);
             } 
             else {
                 *(void **)aValue = xt_client_get_display();
             }          
@@ -1830,16 +1830,23 @@ void
 
 } /* namespace child */
 } /* namespace plugins */
 } /* namespace mozilla */
 
 //-----------------------------------------------------------------------------
 
 bool
+PluginModuleChild::RecvSettingChanged(const PluginSettings& aSettings)
+{
+    mCachedSettings = aSettings;
+    return true;
+}
+
+bool
 PluginModuleChild::AnswerNP_GetEntryPoints(NPError* _retval)
 {
     PLUGIN_LOG_DEBUG_METHOD;
     AssertPluginThread();
     MOZ_ASSERT(mIsChrome);
 
 #if defined(OS_LINUX) || defined(OS_BSD)
     return true;
@@ -1847,22 +1854,24 @@ PluginModuleChild::AnswerNP_GetEntryPoin
     *_retval = mGetEntryPointsFunc(&mFunctions);
     return true;
 #else
 #  error Please implement me for your platform
 #endif
 }
 
 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
 
 #ifdef MOZ_X11
     // Send the parent our X socket to act as a proxy reference for our X
     // resources.
     int xSocketFd = ConnectionNumber(DefaultXDisplay());
--- a/dom/plugins/ipc/PluginModuleChild.h
+++ b/dom/plugins/ipc/PluginModuleChild.h
@@ -67,19 +67,21 @@ protected:
     virtual mozilla::ipc::RacyInterruptPolicy
     MediateInterruptRace(const Message& parent, const Message& child) MOZ_OVERRIDE
     {
         return MediateRace(parent, child);
     }
 
     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,
                             base::ProcessId aOtherProcess) MOZ_OVERRIDE;
 
     virtual PPluginInstanceChild*
     AllocPPluginInstanceChild(const nsCString& aMimeType,
                               const uint16_t& aMode,
@@ -221,19 +223,17 @@ public:
         SendPushCursor(cursorInfo);
     }
 
     void PopCursor() {
         SendPopCursor();
     }
 
     bool GetNativeCursorsSupported() {
-        bool supported = false;
-        SendGetNativeCursorsSupported(&supported);
-        return supported;
+        return Settings().nativeCursorsSupported();
     }
 #endif
 
     // Quirks mode support for various plugin mime types
     enum PluginQuirks {
         QUIRKS_NOT_INITIALIZED                          = 0,
         // Silverlight assumes it is transparent in windowless mode. This quirk
         // matches the logic in nsNPAPIPluginInstance::SetWindowless.
@@ -273,16 +273,18 @@ public:
         // in CoreGraphics mode:  The Flash plugin sometimes accesses the
         // CGContextRef we pass to it in NPP_HandleEvent(NPCocoaEventDrawRect)
         // outside of that call.  See bug 804606.
         QUIRK_FLASH_AVOID_CGMODE_CRASHES                = 1 << 10,
     };
 
     int GetQuirks() { return mQuirks; }
 
+    const PluginSettings& Settings() const { return mCachedSettings; }
+
 private:
     void AddQuirk(PluginQuirks quirk) {
       if (mQuirks == QUIRKS_NOT_INITIALIZED)
         mQuirks = 0;
       mQuirks |= quirk;
     }
     void InitQuirksModes(const nsCString& aMimeType);
     bool InitGraphics();
@@ -313,16 +315,18 @@ private:
     NP_PLUGINUNIXINIT mInitializeFunc;
 #elif defined(OS_WIN) || defined(OS_MACOSX)
     NP_PLUGININIT mInitializeFunc;
     NP_GETENTRYPOINTS mGetEntryPointsFunc;
 #endif
 
     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
     // only after the browser responds to a request sent by the
     // plugin.  This can happen if a plugin uses gtk's synchronous
     // copy/paste, for example.  But because the browser is blocked on
     // a condvar, it can't respond to the request.  This situation
     // isn't technically a deadlock, but the symptoms are basically
--- a/dom/plugins/ipc/PluginModuleParent.cpp
+++ b/dom/plugins/ipc/PluginModuleParent.cpp
@@ -247,16 +247,18 @@ PluginModuleChromeParent::PluginModuleCh
 
     Preferences::RegisterCallback(TimeoutChanged, kChildTimeoutPref, this);
     Preferences::RegisterCallback(TimeoutChanged, kParentTimeoutPref, this);
 #ifdef XP_WIN
     Preferences::RegisterCallback(TimeoutChanged, kHangUITimeoutPref, this);
     Preferences::RegisterCallback(TimeoutChanged, kHangUIMinDisplayPref, this);
 #endif
 
+    RegisterSettingsCallbacks();
+
 #ifdef MOZ_ENABLE_PROFILER_SPS
     InitPluginProfiling();
 #endif
 
     mozilla::HangMonitor::RegisterAnnotator(*this);
 }
 
 PluginModuleChromeParent::~PluginModuleChromeParent()
@@ -290,16 +292,18 @@ PluginModuleChromeParent::~PluginModuleC
 #endif
 
     Preferences::UnregisterCallback(TimeoutChanged, kChildTimeoutPref, this);
     Preferences::UnregisterCallback(TimeoutChanged, kParentTimeoutPref, this);
 #ifdef XP_WIN
     Preferences::UnregisterCallback(TimeoutChanged, kHangUITimeoutPref, this);
     Preferences::UnregisterCallback(TimeoutChanged, kHangUIMinDisplayPref, this);
 
+    UnregisterSettingsCallbacks();
+
     if (mHangUIParent) {
         delete mHangUIParent;
         mHangUIParent = nullptr;
     }
 #endif
 
     mozilla::HangMonitor::UnregisterAnnotator(*this);
 }
@@ -898,16 +902,19 @@ void
 PluginModuleChromeParent::ActorDestroy(ActorDestroyReason why)
 {
     if (why == AbnormalShutdown) {
 #ifdef MOZ_CRASHREPORTER
         ProcessFirstMinidump();
 #endif
     }
 
+    // We can't broadcast settings changes anymore.
+    UnregisterSettingsCallbacks();
+
     PluginModuleParent::ActorDestroy(why);
 }
 
 void
 PluginModuleParent::NotifyPluginCrashed()
 {
     if (!OkToCleanup()) {
         // there's still plugin code on the C++ stack.  try again
@@ -1151,23 +1158,16 @@ PluginModuleParent::NPP_URLRedirectNotif
 {
   PluginInstanceParent* i = InstCast(instance);
   if (!i)
     return;
 
   i->NPP_URLRedirectNotify(url, status, notifyData);
 }
 
-bool
-PluginModuleParent::AnswerNPN_UserAgent(nsCString* userAgent)
-{
-    *userAgent = NullableString(mNPNIface->uagent(nullptr));
-    return true;
-}
-
 PluginInstanceParent*
 PluginModuleParent::InstCast(NPP instance)
 {
     PluginInstanceParent* ip =
         static_cast<PluginInstanceParent*>(instance->pdata);
 
     // If the plugin crashed and the PluginInstanceParent was deleted,
     // instance->pdata will be nullptr.
@@ -1257,32 +1257,135 @@ PluginModuleParent::EndUpdateBackground(
 {
     PluginInstanceParent* i = InstCast(instance);
     if (!i)
         return NS_ERROR_FAILURE;
 
     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<nsIObserverService> 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<nsIObserverService> 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<PluginModuleChromeParent*>(aModule);
+    module->CachedSettingChanged();
+}
+
 #if defined(XP_UNIX) && !defined(XP_MACOSX) && !defined(MOZ_WIDGET_GONK)
 nsresult
 PluginModuleParent::NP_Initialize(NPNetscapeFuncs* bFuncs, NPPluginFuncs* pFuncs, NPError* error)
 {
     PLUGIN_LOG_DEBUG_METHOD;
 
     mNPNIface = bFuncs;
 
     if (mShutdown) {
         *error = NPERR_GENERIC_ERROR;
         return NS_ERROR_FAILURE;
     }
 
     *error = NPERR_NO_ERROR;
     if (IsChrome()) {
-        if (!CallNP_Initialize(error)) {
+        PluginSettings settings;
+        GetSettings(&settings);
+        if (!CallNP_Initialize(settings, error)) {
             Close();
             return NS_ERROR_FAILURE;
         }
         else if (*error != NPERR_NO_ERROR) {
             Close();
             return NS_OK;
         }
     }
@@ -1310,17 +1413,19 @@ PluginModuleParent::NP_Initialize(NPNets
 
 nsresult
 PluginModuleChromeParent::NP_Initialize(NPNetscapeFuncs* bFuncs, NPError* error)
 {
     nsresult rv = PluginModuleParent::NP_Initialize(bFuncs, 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;
     }
     if (*error != NPERR_NO_ERROR) {
         Close();
         return NS_OK;
     }
 
@@ -1534,27 +1639,16 @@ PluginModuleParent::ContentsScaleFactorC
     PluginInstanceParent* i = InstCast(instance);
     if (!i)
         return NS_ERROR_FAILURE;
 
     return i->ContentsScaleFactorChanged(aContentsScaleFactor);
 }
 #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
 PluginModuleParent::AnswerProcessSomeEvents()
 {
     PLUGIN_LOG_DEBUG(("Spinning mini nested loop ..."));
     QCoreApplication::processEvents(QEventLoop::AllEvents, kMaxtimeToProcessEvents);
 
@@ -1745,31 +1839,16 @@ PluginModuleParent::RecvPopCursor()
 #else
     NS_NOTREACHED(
         "PluginInstanceParent::RecvPopCursor not implemented!");
     return false;
 #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)
 {
     PLUGIN_LOG_DEBUG(("%s", FULLFUNCTION));
 
     // This function ignores its first argument.
     mozilla::plugins::parent::_setexception(nullptr, NullableStringGet(aMessage));
     return true;
 }
--- a/dom/plugins/ipc/PluginModuleParent.h
+++ b/dom/plugins/ipc/PluginModuleParent.h
@@ -110,24 +110,16 @@ protected:
     MediateInterruptRace(const Message& parent, const Message& child) MOZ_OVERRIDE
     {
         return MediateRace(parent, child);
     }
 
     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
     RecvProcessNativeEventsInInterruptCall() MOZ_OVERRIDE;
 
     virtual bool
     RecvPluginShowWindow(const uint32_t& aWindowId, const bool& aModal,
                          const int32_t& aX, const int32_t& aY,
@@ -150,19 +142,16 @@ protected:
 
     virtual bool
     RecvPushCursor(const NSCursorInfo& aCursorInfo) MOZ_OVERRIDE;
 
     virtual bool
     RecvPopCursor() MOZ_OVERRIDE;
 
     virtual bool
-    RecvGetNativeCursorsSupported(bool* supported) MOZ_OVERRIDE;
-
-    virtual bool
     RecvNPN_SetException(const nsCString& aMessage) MOZ_OVERRIDE;
 
     virtual bool
     RecvNPN_ReloadPlugins(const bool& aReloadPages) MOZ_OVERRIDE;
 
     static PluginInstanceParent* InstCast(NPP instance);
     static BrowserStreamParent* StreamCast(NPP instance, NPStream* s);
 
@@ -237,16 +226,19 @@ protected:
 #if defined(XP_MACOSX)
     virtual nsresult IsRemoteDrawingCoreAnimation(NPP instance, bool *aDrawing);
     virtual nsresult ContentsScaleFactorChanged(NPP instance, double aContentsScaleFactor);
 #endif
 
 protected:
     void NotifyPluginCrashed();
 
+    bool GetSetting(NPNVariable aVariable);
+    void GetSettings(PluginSettings* aSettings);
+
     bool mIsChrome;
     bool mShutdown;
     bool mClearSiteDataSupported;
     bool mGetSitesWithDataSupported;
     const NPNetscapeFuncs* mNPNIface;
     nsNPAPIPlugin* mPlugin;
     ScopedMethodFactory<PluginModuleParent> mTaskFactory;
     nsString mPluginDumpID;
@@ -307,16 +299,18 @@ class PluginModuleChromeParent
     /**
      * Called by Plugin Hang UI to notify that the user has clicked continue.
      * Used for chrome hang annotations.
      */
     void
     OnHangUIContinue();
 #endif // XP_WIN
 
+    void CachedSettingChanged();
+
 private:
     virtual void
     EnteredCxxStack() MOZ_OVERRIDE;
 
     void
     ExitedCxxStack() MOZ_OVERRIDE;
 
     virtual void
@@ -355,18 +349,23 @@ private:
 
     virtual void UpdatePluginTimeout() MOZ_OVERRIDE;
 
 #ifdef MOZ_ENABLE_PROFILER_SPS
     void InitPluginProfiling();
     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;
 
     ScopedMethodFactory<PluginModuleChromeParent> mChromeTaskFactory;
 
     enum HangAnnotationFlags
     {
         kInPluginCall = (1u << 0),
@@ -417,14 +416,16 @@ private:
 #ifdef MOZ_CRASHREPORTER_INJECTOR
     void InitializeInjector();
     
     void OnCrash(DWORD processID) MOZ_OVERRIDE;
 
     DWORD mFlashProcess1;
     DWORD mFlashProcess2;
 #endif
+
+    nsCOMPtr<nsIObserver> mOfflineObserver;
 };
 
 } // namespace plugins
 } // namespace mozilla
 
 #endif // mozilla_plugins_PluginModuleParent_h