diff --git a/dom/ipc/ContentParent.cpp b/dom/ipc/ContentParent.cpp index 54e30a16a95..3fdc0a23427 100755 --- a/dom/ipc/ContentParent.cpp +++ b/dom/ipc/ContentParent.cpp @@ -1022,17 +1022,21 @@ ContentParent::RecvGetGMPPluginVersionForAPI(const nsCString& aAPI, } bool -ContentParent::RecvLoadPlugin(const uint32_t& aPluginId, nsresult* aRv) +ContentParent::RecvLoadPlugin(const uint32_t& aPluginId, nsresult* aRv, uint32_t* aRunID) { *aRv = NS_OK; - return mozilla::plugins::SetupBridge(aPluginId, this, false, aRv); + return mozilla::plugins::SetupBridge(aPluginId, this, false, aRv, aRunID); } bool ContentParent::RecvConnectPluginBridge(const uint32_t& aPluginId, nsresult* aRv) { *aRv = NS_OK; - return mozilla::plugins::SetupBridge(aPluginId, this, true, aRv); + // We don't need to get the run ID for the plugin, since we already got it + // in the first call to SetupBridge in RecvLoadPlugin, so we pass in a dummy + // pointer and just throw it away. + uint32_t dummy = 0; + return mozilla::plugins::SetupBridge(aPluginId, this, true, aRv, &dummy); } bool diff --git a/dom/ipc/ContentParent.h b/dom/ipc/ContentParent.h index 7b5049a7469..f1d88acf546 100644 --- a/dom/ipc/ContentParent.h +++ b/dom/ipc/ContentParent.h @@ -174,7 +174,7 @@ public: bool* aHasPlugin, nsCString* aVersion) override; - virtual bool RecvLoadPlugin(const uint32_t& aPluginId, nsresult* aRv) override; + virtual bool RecvLoadPlugin(const uint32_t& aPluginId, nsresult* aRv, uint32_t* aRunID) override; virtual bool RecvConnectPluginBridge(const uint32_t& aPluginId, nsresult* aRv) override; virtual bool RecvFindPlugins(const uint32_t& aPluginEpoch, nsTArray* aPlugins, diff --git a/dom/ipc/PContent.ipdl b/dom/ipc/PContent.ipdl index 2c2f8990024..93137830626 100644 --- a/dom/ipc/PContent.ipdl +++ b/dom/ipc/PContent.ipdl @@ -633,7 +633,7 @@ parent: * via bridging. The corresponding PluginModuleChild will live in the plugin * process. */ - sync LoadPlugin(uint32_t pluginId) returns (nsresult rv); + sync LoadPlugin(uint32_t aPluginId) returns (nsresult aResult, uint32_t aRunID); /** * This call is used by asynchronous plugin instantiation to notify the diff --git a/dom/plugins/ipc/PluginBridge.h b/dom/plugins/ipc/PluginBridge.h index b2b4bcf6a82..761e379f139 100644 --- a/dom/plugins/ipc/PluginBridge.h +++ b/dom/plugins/ipc/PluginBridge.h @@ -17,7 +17,7 @@ namespace plugins { bool SetupBridge(uint32_t aPluginId, dom::ContentParent* aContentParent, - bool aForceBridgeNow, nsresult* rv); + bool aForceBridgeNow, nsresult* aResult, uint32_t* aRunID); bool FindPluginsForContent(uint32_t aPluginEpoch, diff --git a/dom/plugins/ipc/PluginModuleParent.cpp b/dom/plugins/ipc/PluginModuleParent.cpp index e85ccb3319a..d4ebfec0f47 100755 --- a/dom/plugins/ipc/PluginModuleParent.cpp +++ b/dom/plugins/ipc/PluginModuleParent.cpp @@ -96,8 +96,13 @@ bool mozilla::plugins::SetupBridge(uint32_t aPluginId, dom::ContentParent* aContentParent, bool aForceBridgeNow, - nsresult* rv) + nsresult* rv, + uint32_t* runID) { + if (NS_WARN_IF(!rv) || NS_WARN_IF(!runID)) { + return false; + } + PluginModuleChromeParent::ClearInstantiationFlag(); nsRefPtr host = nsPluginHost::GetInst(); nsRefPtr plugin; @@ -106,6 +111,10 @@ mozilla::plugins::SetupBridge(uint32_t aPluginId, return true; } PluginModuleChromeParent* chromeParent = static_cast(plugin->GetLibrary()); + *rv = chromeParent->GetRunID(runID); + if (NS_FAILED(*rv)) { + return true; + } chromeParent->SetContentParent(aContentParent); if (!aForceBridgeNow && chromeParent->IsStartingAsync() && PluginModuleChromeParent::DidInstantiate()) { @@ -365,7 +374,8 @@ PluginModuleContentParent::LoadModule(uint32_t aPluginId) */ dom::ContentChild* cp = dom::ContentChild::GetSingleton(); nsresult rv; - if (!cp->SendLoadPlugin(aPluginId, &rv) || + uint32_t runID; + if (!cp->SendLoadPlugin(aPluginId, &rv, &runID) || NS_FAILED(rv)) { return nullptr; } @@ -381,6 +391,7 @@ PluginModuleContentParent::LoadModule(uint32_t aPluginId) } parent->mPluginId = aPluginId; + parent->mRunID = runID; return parent; } @@ -644,6 +655,10 @@ PluginModuleContentParent::~PluginModuleContentParent() Preferences::UnregisterCallback(TimeoutChanged, kContentTimeoutPref, this); } +// We start the Run IDs at 1 so that we can use 0 as a way of detecting +// errors in retrieving the run ID. +uint32_t PluginModuleChromeParent::sNextRunID = 1; + bool PluginModuleChromeParent::sInstantiated = false; PluginModuleChromeParent::PluginModuleChromeParent(const char* aFilePath, uint32_t aPluginId) @@ -675,6 +690,7 @@ PluginModuleChromeParent::PluginModuleChromeParent(const char* aFilePath, uint32 { NS_ASSERTION(mSubprocess, "Out of memory!"); sInstantiated = true; + mRunID = sNextRunID++; RegisterSettingsCallbacks(); @@ -1499,6 +1515,16 @@ PluginModuleParent::ActorDestroy(ActorDestroyReason why) } } +nsresult +PluginModuleParent::GetRunID(uint32_t* aRunID) +{ + if (NS_WARN_IF(!aRunID)) { + return NS_ERROR_INVALID_POINTER; + } + *aRunID = mRunID; + return NS_OK; +} + void PluginModuleChromeParent::ActorDestroy(ActorDestroyReason why) { diff --git a/dom/plugins/ipc/PluginModuleParent.h b/dom/plugins/ipc/PluginModuleParent.h index a61c04f79dd..7ff8a6f4ebc 100644 --- a/dom/plugins/ipc/PluginModuleParent.h +++ b/dom/plugins/ipc/PluginModuleParent.h @@ -128,6 +128,8 @@ public: return mPluginName + mPluginVersion; } + nsresult GetRunID(uint32_t* aRunID); + protected: virtual mozilla::ipc::RacyInterruptPolicy MediateInterruptRace(const Message& parent, const Message& child) override @@ -305,6 +307,7 @@ protected: bool mNPInitialized; nsTArray> mSurrogateInstances; nsresult mAsyncNewRv; + uint32_t mRunID; }; class PluginModuleContentParent : public PluginModuleParent @@ -551,6 +554,7 @@ private: dom::ContentParent* mContentParent; nsCOMPtr mOfflineObserver; bool mIsBlocklisted; + static uint32_t sNextRunID; static bool sInstantiated; };