Bug 1231306 - Handle plugin state changes correctly in content process (r=jimm)
authorBill McCloskey <billm@mozilla.com>
Wed, 23 Dec 2015 17:18:57 -0800
changeset 277865 67458bc680b23fc2ec5ad6b87675d39bf6d0fe01
parent 277864 6ae2e882c357d114b9066b848d8bf225787be6ab
child 277866 63bb81bf85174acf9e70f244a9ef0e0449939fca
push id29835
push usercbook@mozilla.com
push dateWed, 30 Dec 2015 11:00:19 +0000
treeherdermozilla-central@c690c50b2b54 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjimm
bugs1231306
milestone46.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 1231306 - Handle plugin state changes correctly in content process (r=jimm)
dom/plugins/base/nsPluginHost.cpp
dom/plugins/base/nsPluginHost.h
dom/plugins/base/nsPluginTags.cpp
--- a/dom/plugins/base/nsPluginHost.cpp
+++ b/dom/plugins/base/nsPluginHost.cpp
@@ -2421,27 +2421,31 @@ nsPluginHost::FindPluginsInContent(bool 
   nsTArray<PluginTag> plugins;
   uint32_t parentEpoch;
   if (!cp->SendFindPlugins(ChromeEpochForContent(), &rv, &plugins, &parentEpoch) ||
       NS_FAILED(rv)) {
     return NS_ERROR_NOT_AVAILABLE;
   }
 
   if (parentEpoch != ChromeEpochForContent()) {
-    SetChromeEpochForContent(parentEpoch);
     *aPluginsChanged = true;
     if (!aCreatePluginList) {
       return NS_OK;
     }
 
+    // Don't do this if aCreatePluginList is false. Otherwise, when we actually
+    // want to create the list, we'll come back here and do nothing.
+    SetChromeEpochForContent(parentEpoch);
+
     for (size_t i = 0; i < plugins.Length(); i++) {
       PluginTag& tag = plugins[i];
 
       // Don't add the same plugin again.
-      if (PluginWithId(tag.id())) {
+      if (nsPluginTag* existing = PluginWithId(tag.id())) {
+        UpdateInMemoryPluginInfo(existing);
         continue;
       }
 
       nsPluginTag *pluginTag = new nsPluginTag(tag.id(),
                                                tag.name().get(),
                                                tag.description().get(),
                                                tag.filename().get(),
                                                "", // aFullPath
@@ -2694,24 +2698,19 @@ nsPluginHost::FindPluginsForContent(uint
                                       tag->FileName(),
                                       tag->Version(),
                                       tag->mLastModifiedTime,
                                       tag->IsFromExtension()));
   }
   return NS_OK;
 }
 
-// This function is not relevant for fake plugins.
 void
-nsPluginHost::UpdatePluginInfo(nsPluginTag* aPluginTag)
+nsPluginHost::UpdateInMemoryPluginInfo(nsPluginTag* aPluginTag)
 {
-  MOZ_ASSERT(XRE_IsParentProcess());
-
-  ReadPluginInfo();
-  WritePluginInfo();
   NS_ITERATIVE_UNREF_LIST(RefPtr<nsPluginTag>, mCachedPlugins, mNext);
   NS_ITERATIVE_UNREF_LIST(RefPtr<nsInvalidPluginTag>, mInvalidPlugins, mNext);
 
   if (!aPluginTag) {
     return;
   }
 
   // Update types with category manager
@@ -2732,16 +2731,30 @@ nsPluginHost::UpdatePluginInfo(nsPluginT
   }
 
   nsCOMPtr<nsIObserverService> obsService =
     mozilla::services::GetObserverService();
   if (obsService)
     obsService->NotifyObservers(nullptr, "plugin-info-updated", nullptr);
 }
 
+// This function is not relevant for fake plugins.
+void
+nsPluginHost::UpdatePluginInfo(nsPluginTag* aPluginTag)
+{
+  MOZ_ASSERT(XRE_IsParentProcess());
+
+  ReadPluginInfo();
+  WritePluginInfo();
+
+  IncrementChromeEpoch();
+
+  UpdateInMemoryPluginInfo(aPluginTag);
+}
+
 /* static */ bool
 nsPluginHost::IsTypeWhitelisted(const char *aMimeType)
 {
   nsAdoptingCString whitelist = Preferences::GetCString(kPrefWhitelist);
   if (!whitelist.Length()) {
     return true;
   }
   nsDependentCString wrap(aMimeType);
--- a/dom/plugins/base/nsPluginHost.h
+++ b/dom/plugins/base/nsPluginHost.h
@@ -358,16 +358,18 @@ private:
   // To be used by the chrome process; returns the current epoch.
   uint32_t ChromeEpoch();
 
   // To be used by the content process to get/set the last observed epoch value
   // from the chrome process.
   uint32_t ChromeEpochForContent();
   void SetChromeEpochForContent(uint32_t aEpoch);
 
+  void UpdateInMemoryPluginInfo(nsPluginTag* aPluginTag);
+
   // On certain platforms, we only want to load certain plugins. This function
   // centralizes loading rules.
   bool ShouldAddPlugin(nsPluginTag* aPluginTag);
 
   RefPtr<nsPluginTag> mPlugins;
   RefPtr<nsPluginTag> mCachedPlugins;
   RefPtr<nsInvalidPluginTag> mInvalidPlugins;
 
--- a/dom/plugins/base/nsPluginTags.cpp
+++ b/dom/plugins/base/nsPluginTags.cpp
@@ -571,17 +571,18 @@ nsPluginTag::IsClicktoplay()
 NS_IMETHODIMP
 nsPluginTag::GetClicktoplay(bool *aClicktoplay)
 {
   *aClicktoplay = IsClicktoplay();
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsPluginTag::GetEnabledState(uint32_t *aEnabledState) {
+nsPluginTag::GetEnabledState(uint32_t *aEnabledState)
+{
   int32_t enabledState;
   nsresult rv = Preferences::GetInt(GetStatePrefNameForPlugin(this).get(),
                                     &enabledState);
   if (NS_SUCCEEDED(rv) &&
       enabledState >= nsIPluginTag::STATE_DISABLED &&
       enabledState <= nsIPluginTag::STATE_ENABLED) {
     *aEnabledState = (uint32_t)enabledState;
     return rv;
@@ -596,17 +597,18 @@ nsPluginTag::GetEnabledState(uint32_t *a
     *aEnabledState = (uint32_t)enabledState;
     return NS_OK;
   }
 
   return NS_ERROR_UNEXPECTED;
 }
 
 NS_IMETHODIMP
-nsPluginTag::SetEnabledState(uint32_t aEnabledState) {
+nsPluginTag::SetEnabledState(uint32_t aEnabledState)
+{
   if (aEnabledState >= ePluginState_MaxValue)
     return NS_ERROR_ILLEGAL_VALUE;
   uint32_t oldState = nsIPluginTag::STATE_DISABLED;
   GetEnabledState(&oldState);
   if (oldState != aEnabledState) {
     Preferences::SetInt(GetStatePrefNameForPlugin(this).get(), aEnabledState);
     if (RefPtr<nsPluginHost> host = nsPluginHost::GetInst()) {
       host->UpdatePluginInfo(this);