Bug 558184 - Part 6 - Return fake plugins in e10s too. r=bz.
authorPeter Van der Beken <peterv@propagandism.org>
Thu, 21 May 2015 15:15:08 +0200
changeset 361798 0aa594d8fb39d096c685a04ca69e1b68e081952d
parent 361797 675c893a028dfe609ee6812cba0d1e86b2853d23
child 361799 e69bf3dbf73c58fb3e85ab95d8cb18a70aad6914
push id31943
push userryanvm@gmail.com
push dateThu, 01 Jun 2017 15:54:45 +0000
treeherdermozilla-central@62005e6aecdf [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz
bugs558184
milestone55.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 558184 - Part 6 - Return fake plugins in e10s too. r=bz.
dom/ipc/ContentParent.cpp
dom/ipc/ContentParent.h
dom/ipc/PContent.ipdl
dom/plugins/base/nsPluginHost.cpp
dom/plugins/base/nsPluginHost.h
dom/plugins/base/nsPluginTags.cpp
dom/plugins/base/nsPluginTags.h
dom/plugins/ipc/PluginBridge.h
dom/plugins/ipc/PluginTypes.ipdlh
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -1120,19 +1120,20 @@ ContentParent::RecvGetBlocklistState(con
   }
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
 ContentParent::RecvFindPlugins(const uint32_t& aPluginEpoch,
                                nsresult* aRv,
                                nsTArray<PluginTag>* aPlugins,
+                               nsTArray<FakePluginTag>* aFakePlugins,
                                uint32_t* aNewPluginEpoch)
 {
-  *aRv = mozilla::plugins::FindPluginsForContent(aPluginEpoch, aPlugins, aNewPluginEpoch);
+  *aRv = mozilla::plugins::FindPluginsForContent(aPluginEpoch, aPlugins, aFakePlugins, aNewPluginEpoch);
   return IPC_OK();
 }
 
 /*static*/ TabParent*
 ContentParent::CreateBrowser(const TabContext& aContext,
                              Element* aFrameElement,
                              ContentParent* aOpenerContentParent,
                              TabParent* aSameTabGroupAs,
--- a/dom/ipc/ContentParent.h
+++ b/dom/ipc/ContentParent.h
@@ -294,16 +294,17 @@ public:
                                                           Endpoint<PPluginModuleParent>* aEndpoint) override;
 
   virtual mozilla::ipc::IPCResult RecvGetBlocklistState(const uint32_t& aPluginId,
                                                         uint32_t* aIsBlocklisted) override;
 
   virtual mozilla::ipc::IPCResult RecvFindPlugins(const uint32_t& aPluginEpoch,
                                                   nsresult* aRv,
                                                   nsTArray<PluginTag>* aPlugins,
+                                                  nsTArray<FakePluginTag>* aFakePlugins,
                                                   uint32_t* aNewPluginEpoch) override;
 
   virtual mozilla::ipc::IPCResult RecvUngrabPointer(const uint32_t& aTime) override;
 
   virtual mozilla::ipc::IPCResult RecvRemovePermission(const IPC::Principal& aPrincipal,
                                                        const nsCString& aPermissionType,
                                                        nsresult* aRv) override;
 
--- a/dom/ipc/PContent.ipdl
+++ b/dom/ipc/PContent.ipdl
@@ -653,17 +653,17 @@ parent:
      * epoch number every time the set of plugins changes. The content process
      * sends up the last epoch it observed. If the epochs are the same, the
      * chrome process returns no plugins. Otherwise it returns a complete list.
      *
      * |pluginEpoch| is the epoch last observed by the content
      * process. |newPluginEpoch| is the current epoch in the chrome process. If
      * |pluginEpoch == newPluginEpoch|, then |plugins| will be left empty.
      */
-    sync FindPlugins(uint32_t pluginEpoch) returns (nsresult aResult, PluginTag[] plugins, uint32_t newPluginEpoch);
+    sync FindPlugins(uint32_t pluginEpoch) returns (nsresult aResult, PluginTag[] plugins, FakePluginTag[] fakePlugins, uint32_t newPluginEpoch);
 
     async PJavaScript();
 
     async PRemoteSpellcheckEngine();
 
     async InitCrashReporter(Shmem shmem, NativeThreadId tid);
 
     /**
--- a/dom/plugins/base/nsPluginHost.cpp
+++ b/dom/plugins/base/nsPluginHost.cpp
@@ -52,16 +52,17 @@
 #include "nsPluginStreamListenerPeer.h"
 #include "mozilla/dom/ContentChild.h"
 #include "mozilla/dom/FakePluginTagInitBinding.h"
 #include "mozilla/LoadInfo.h"
 #include "mozilla/plugins/PluginAsyncSurrogate.h"
 #include "mozilla/plugins/PluginBridge.h"
 #include "mozilla/plugins/PluginTypes.h"
 #include "mozilla/Preferences.h"
+#include "mozilla/ipc/URIUtils.h"
 
 #include "nsEnumeratorUtils.h"
 #include "nsXPCOM.h"
 #include "nsXPCOMCID.h"
 #include "nsISupportsPrimitives.h"
 
 #include "nsXULAppAPI.h"
 #include "nsIXULRuntime.h"
@@ -111,16 +112,17 @@
 #if MOZ_CRASHREPORTER
 #include "nsExceptionHandler.h"
 #endif
 
 #include "npapi.h"
 
 using namespace mozilla;
 using mozilla::TimeStamp;
+using mozilla::plugins::FakePluginTag;
 using mozilla::plugins::PluginTag;
 using mozilla::plugins::PluginAsyncSurrogate;
 using mozilla::dom::FakePluginTagInit;
 
 // Null out a strong ref to a linked list iteratively to avoid
 // exhausting the stack (bug 486349).
 #define NS_ITERATIVE_UNREF_LIST(type_, list_, mNext_)                \
   {                                                                  \
@@ -2275,18 +2277,19 @@ nsresult nsPluginHost::LoadPlugins()
 nsresult
 nsPluginHost::FindPluginsInContent(bool aCreatePluginList, bool* aPluginsChanged)
 {
   MOZ_ASSERT(XRE_IsContentProcess());
 
   dom::ContentChild* cp = dom::ContentChild::GetSingleton();
   nsresult rv;
   nsTArray<PluginTag> plugins;
+  nsTArray<FakePluginTag> fakePlugins;
   uint32_t parentEpoch;
-  if (!cp->SendFindPlugins(ChromeEpochForContent(), &rv, &plugins, &parentEpoch) ||
+  if (!cp->SendFindPlugins(ChromeEpochForContent(), &rv, &plugins, &fakePlugins, &parentEpoch) ||
       NS_FAILED(rv)) {
     return NS_ERROR_NOT_AVAILABLE;
   }
 
   if (parentEpoch != ChromeEpochForContent()) {
     *aPluginsChanged = true;
     if (!aCreatePluginList) {
       return NS_OK;
@@ -2318,16 +2321,34 @@ nsPluginHost::FindPluginsInContent(bool 
                                                tag.isFlashPlugin(),
                                                tag.supportsAsyncInit(),
                                                tag.supportsAsyncRender(),
                                                tag.lastModifiedTime(),
                                                tag.isFromExtension(),
                                                tag.sandboxLevel());
       AddPluginTag(pluginTag);
     }
+
+    for (const auto& tag : fakePlugins) {
+      // Don't add the same plugin again.
+      for (const auto& existingTag : mFakePlugins) {
+        if (existingTag->Id() == tag.id()) {
+          continue;
+        }
+      }
+
+      mFakePlugins.AppendElement(new nsFakePluginTag(tag.id(),
+                                                     mozilla::ipc::DeserializeURI(tag.handlerURI()),
+                                                     tag.name().get(),
+                                                     tag.description().get(),
+                                                     tag.mimeTypes(),
+                                                     tag.mimeDescriptions(),
+                                                     tag.extensions(),
+                                                     tag.niceName()));
+    }
   }
 
   mPluginsLoaded = true;
   return NS_OK;
 }
 
 // if aCreatePluginList is false we will just scan for plugins
 // and see if any changes have been made to the plugins.
@@ -2467,27 +2488,29 @@ nsresult nsPluginHost::FindPlugins(bool 
   NS_ITERATIVE_UNREF_LIST(RefPtr<nsInvalidPluginTag>, mInvalidPlugins, mNext);
 
   return NS_OK;
 }
 
 nsresult
 mozilla::plugins::FindPluginsForContent(uint32_t aPluginEpoch,
                                         nsTArray<PluginTag>* aPlugins,
+                                        nsTArray<FakePluginTag>* aFakePlugins,
                                         uint32_t* aNewPluginEpoch)
 {
   MOZ_ASSERT(XRE_IsParentProcess());
 
   RefPtr<nsPluginHost> host = nsPluginHost::GetInst();
-  return host->FindPluginsForContent(aPluginEpoch, aPlugins, aNewPluginEpoch);
+  return host->FindPluginsForContent(aPluginEpoch, aPlugins, aFakePlugins, aNewPluginEpoch);
 }
 
 nsresult
 nsPluginHost::FindPluginsForContent(uint32_t aPluginEpoch,
                                     nsTArray<PluginTag>* aPlugins,
+                                    nsTArray<FakePluginTag>* aFakePlugins,
                                     uint32_t* aNewPluginEpoch)
 {
   MOZ_ASSERT(XRE_IsParentProcess());
 
   // Load plugins so that the epoch is correct.
   nsresult rv = LoadPlugins();
   if (NS_FAILED(rv)) {
     return rv;
@@ -2501,19 +2524,29 @@ nsPluginHost::FindPluginsForContent(uint
   nsTArray<nsCOMPtr<nsIInternalPluginTag>> plugins;
   GetPlugins(plugins, true);
 
   for (size_t i = 0; i < plugins.Length(); i++) {
     nsCOMPtr<nsIInternalPluginTag> basetag = plugins[i];
 
     nsCOMPtr<nsIFakePluginTag> faketag = do_QueryInterface(basetag);
     if (faketag) {
-      /// FIXME-jsplugins - We need to make content processes properly
-      /// aware of jsplugins (and add a nsIInternalPluginTag->AsNative() to
-      /// avoid this hacky static cast)
+      /// FIXME-jsplugins - We need to add a nsIInternalPluginTag->AsNative() to
+      /// avoid this hacky static cast
+      nsFakePluginTag* tag = static_cast<nsFakePluginTag*>(basetag.get());
+      mozilla::ipc::URIParams handlerURI;
+      SerializeURI(tag->HandlerURI(), handlerURI);
+      aFakePlugins->AppendElement(FakePluginTag(tag->Id(),
+                                                handlerURI,
+                                                tag->Name(),
+                                                tag->Description(),
+                                                tag->MimeTypes(),
+                                                tag->MimeDescriptions(),
+                                                tag->Extensions(),
+                                                tag->GetNiceFileName()));
       continue;
     }
 
     /// FIXME-jsplugins - We need to cleanup the various plugintag classes
     /// to be more sane and avoid this dance
     nsPluginTag *tag = static_cast<nsPluginTag *>(basetag.get());
 
     aPlugins->AppendElement(PluginTag(tag->mId,
--- a/dom/plugins/base/nsPluginHost.h
+++ b/dom/plugins/base/nsPluginHost.h
@@ -29,16 +29,17 @@
 
 #ifdef XP_WIN
 #include <minwindef.h>
 #include "nsIWindowsRegKey.h"
 #endif
 
 namespace mozilla {
 namespace plugins {
+class FakePluginTag;
 class PluginAsyncSurrogate;
 class PluginTag;
 } // namespace plugins
 } // namespace mozilla
 
 class nsNPAPIPlugin;
 class nsIFile;
 class nsIChannel;
@@ -113,16 +114,17 @@ public:
                               /* out */ nsACString & aMimeType,
                               PluginFilter aFilter = eExcludeDisabled);
 
   void GetPlugins(nsTArray<nsCOMPtr<nsIInternalPluginTag>>& aPluginArray,
                   bool aIncludeDisabled = false);
 
   nsresult FindPluginsForContent(uint32_t aPluginEpoch,
                                  nsTArray<mozilla::plugins::PluginTag>* aPlugins,
+                                 nsTArray<mozilla::plugins::FakePluginTag>* aFakePlugins,
                                  uint32_t* aNewPluginEpoch);
 
   nsresult GetURL(nsISupports* pluginInst,
                   const char* url,
                   const char* target,
                   nsNPAPIPluginStreamListener* streamListener,
                   const char* altHost,
                   const char* referrer,
--- a/dom/plugins/base/nsPluginTags.cpp
+++ b/dom/plugins/base/nsPluginTags.cpp
@@ -813,21 +813,40 @@ nsPluginTag::GetLastModifiedTime(PRTime*
 
 bool nsPluginTag::IsFromExtension() const
 {
   return mIsFromExtension;
 }
 
 /* nsFakePluginTag */
 
+uint32_t nsFakePluginTag::sNextId;
+
 nsFakePluginTag::nsFakePluginTag()
-  : mState(nsPluginTag::ePluginState_Disabled)
+  : mId(sNextId++),
+    mState(nsPluginTag::ePluginState_Disabled)
 {
 }
 
+nsFakePluginTag::nsFakePluginTag(uint32_t aId,
+                                 already_AddRefed<nsIURI>&& aHandlerURI,
+                                 const char* aName,
+                                 const char* aDescription,
+                                 const nsTArray<nsCString>& aMimeTypes,
+                                 const nsTArray<nsCString>& aMimeDescriptions,
+                                 const nsTArray<nsCString>& aExtensions,
+                                 const nsCString& aNiceName)
+  : nsIInternalPluginTag(aName, aDescription, nullptr, nullptr,
+                         aMimeTypes, aMimeDescriptions, aExtensions),
+    mId(aId),
+    mHandlerURI(aHandlerURI),
+    mNiceName(aNiceName),
+    mState(nsPluginTag::ePluginState_Enabled)
+{}
+
 nsFakePluginTag::~nsFakePluginTag()
 {
 }
 
 NS_IMPL_ADDREF(nsFakePluginTag)
 NS_IMPL_RELEASE(nsFakePluginTag)
 NS_INTERFACE_TABLE_HEAD(nsFakePluginTag)
   NS_INTERFACE_TABLE_BEGIN
--- a/dom/plugins/base/nsPluginTags.h
+++ b/dom/plugins/base/nsPluginTags.h
@@ -206,31 +206,51 @@ class nsFakePluginTag : public nsIIntern
 {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSIPLUGINTAG
   NS_DECL_NSIFAKEPLUGINTAG
 
   static nsresult Create(const mozilla::dom::FakePluginTagInit& aInitDictionary,
                          nsFakePluginTag** aPluginTag);
+  nsFakePluginTag(uint32_t aId,
+                  already_AddRefed<nsIURI>&& aHandlerURI,
+                  const char* aName,
+                  const char* aDescription,
+                  const nsTArray<nsCString>& aMimeTypes,
+                  const nsTArray<nsCString>& aMimeDescriptions,
+                  const nsTArray<nsCString>& aExtensions,
+                  const nsCString& aNiceName);
 
   bool IsEnabled() override;
   const nsCString& GetNiceFileName() override;
 
   bool HandlerURIMatches(nsIURI* aURI);
 
   nsIURI* HandlerURI() const { return mHandlerURI; }
 
+  uint32_t Id() const { return mId; }
+
 private:
   nsFakePluginTag();
   virtual ~nsFakePluginTag();
 
+  // A unique id for this JS-implemented plugin. Registering a plugin through
+  // nsPluginHost::RegisterFakePlugin assigns a new id. The id is transferred
+  // through IPC when getting the list of JS-implemented plugins from child
+  // processes, so it should be consistent across processes.
+  uint32_t      mId;
+
   // The URI of the handler for our fake plugin.
   // FIXME-jsplugins do we need to sanity check these?
   nsCOMPtr<nsIURI>    mHandlerURI;
 
   nsCString     mFullPath;
   nsCString     mNiceName;
 
   nsPluginTag::PluginState mState;
+
+  // Stores the id to use for the JS-implemented plugin that gets registered
+  // next through nsPluginHost::RegisterFakePlugin.
+  static uint32_t sNextId;
 };
 
 #endif // nsPluginTags_h_
--- a/dom/plugins/ipc/PluginBridge.h
+++ b/dom/plugins/ipc/PluginBridge.h
@@ -27,16 +27,17 @@ class PPluginModuleParent;
 bool
 SetupBridge(uint32_t aPluginId, dom::ContentParent* aContentParent,
             bool aForceBridgeNow, nsresult* aResult, uint32_t* aRunID,
             ipc::Endpoint<PPluginModuleParent>* aEndpoint);
 
 nsresult
 FindPluginsForContent(uint32_t aPluginEpoch,
                       nsTArray<PluginTag>* aPlugins,
+                      nsTArray<FakePluginTag>* aFakePlugins,
                       uint32_t* aNewPluginEpoch);
 
 void
 TakeFullMinidump(uint32_t aPluginId,
                  base::ProcessId aContentProcessId,
                  const nsAString& aBrowserDumpId,
                  nsString& aDumpId);
 
--- a/dom/plugins/ipc/PluginTypes.ipdlh
+++ b/dom/plugins/ipc/PluginTypes.ipdlh
@@ -1,13 +1,15 @@
 /* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+include URIParams;
+
 namespace mozilla {
 namespace plugins {
 
 struct PluginTag
 {
   uint32_t id;
   nsCString name;
   nsCString description;
@@ -20,16 +22,28 @@ struct PluginTag
   bool supportsAsyncRender; // flash specific
   nsCString filename;
   nsCString version;
   int64_t lastModifiedTime;
   bool isFromExtension;
   int32_t sandboxLevel;
 };
 
+struct FakePluginTag
+{
+  uint32_t id;
+  URIParams handlerURI;
+  nsCString name;
+  nsCString description;
+  nsCString[] mimeTypes;
+  nsCString[] mimeDescriptions;
+  nsCString[] extensions;
+  nsCString niceName;
+};
+
 union PluginIdentifier
 {
   nsCString;
   int32_t;
 };
 
 } // namespace plugins
 } // namespace mozilla