Bug 1267918 - Split LoadGMP message into select and load messages. r=gerald
This will allow us to attach a crash handler to a GMP process after deciding
which GMP to load but before actually loading it.
MozReview-Commit-ID: HwBZU2Q4TX6
--- a/dom/media/gmp/GMPServiceChild.cpp
+++ b/dom/media/gmp/GMPServiceChild.cpp
@@ -62,26 +62,31 @@ public:
void Done(GMPServiceChild* aGMPServiceChild) override
{
if (!aGMPServiceChild) {
mCallback->Done(nullptr);
return;
}
+ uint32_t pluginId;
+ nsresult rv;
+ bool ok = aGMPServiceChild->SendSelectGMP(mNodeId, mAPI, mTags, &pluginId, &rv);
+ if (!ok || rv == NS_ERROR_ILLEGAL_DURING_SHUTDOWN) {
+ mCallback->Done(nullptr);
+ return;
+ }
+
nsTArray<base::ProcessId> alreadyBridgedTo;
aGMPServiceChild->GetAlreadyBridgedTo(alreadyBridgedTo);
base::ProcessId otherProcess;
nsCString displayName;
- uint32_t pluginId;
- nsresult rv;
- bool ok = aGMPServiceChild->SendLoadGMP(mNodeId, mAPI, mTags,
- alreadyBridgedTo, &otherProcess,
- &displayName, &pluginId, &rv);
+ ok = aGMPServiceChild->SendLaunchGMP(pluginId, alreadyBridgedTo, &otherProcess,
+ &displayName, &rv);
if (!ok || rv == NS_ERROR_ILLEGAL_DURING_SHUTDOWN) {
mCallback->Done(nullptr);
return;
}
RefPtr<GMPContentParent> parent;
aGMPServiceChild->GetBridgedGMPContentParent(otherProcess,
getter_AddRefs(parent));
--- a/dom/media/gmp/GMPServiceParent.cpp
+++ b/dom/media/gmp/GMPServiceParent.cpp
@@ -1813,51 +1813,86 @@ GeckoMediaPluginServiceParent::ClearStor
}
// Clear private-browsing storage.
mTempGMPStorage.Clear();
NS_DispatchToMainThread(new NotifyObserversTask("gmp-clear-storage-complete"), NS_DISPATCH_NORMAL);
}
+already_AddRefed<GMPParent>
+GeckoMediaPluginServiceParent::GetById(uint32_t aPluginId)
+{
+ MutexAutoLock lock(mMutex);
+ for (const RefPtr<GMPParent>& gmp : mPlugins) {
+ if (gmp->GetPluginId() == aPluginId) {
+ return do_AddRef(gmp);
+ }
+ }
+ return nullptr;
+}
+
GMPServiceParent::~GMPServiceParent()
{
RefPtr<DeleteTask<Transport>> task = new DeleteTask<Transport>(GetTransport());
XRE_GetIOMessageLoop()->PostTask(task.forget());
}
bool
-GMPServiceParent::RecvLoadGMP(const nsCString& aNodeId,
- const nsCString& aAPI,
- nsTArray<nsCString>&& aTags,
- nsTArray<ProcessId>&& aAlreadyBridgedTo,
- ProcessId* aId,
- nsCString* aDisplayName,
- uint32_t* aPluginId,
- nsresult* aRv)
+GMPServiceParent::RecvSelectGMP(const nsCString& aNodeId,
+ const nsCString& aAPI,
+ nsTArray<nsCString>&& aTags,
+ uint32_t* aOutPluginId,
+ nsresult* aOutRv)
{
- *aRv = NS_OK;
if (mService->IsShuttingDown()) {
- *aRv = NS_ERROR_ILLEGAL_DURING_SHUTDOWN;
+ *aOutRv = NS_ERROR_ILLEGAL_DURING_SHUTDOWN;
return true;
}
RefPtr<GMPParent> gmp = mService->SelectPluginForAPI(aNodeId, aAPI, aTags);
+ if (gmp) {
+ *aOutPluginId = gmp->GetPluginId();
+ *aOutRv = NS_OK;
+ } else {
+ *aOutRv = NS_ERROR_FAILURE;
+ }
nsCString api = aTags[0];
LOGD(("%s: %p returning %p for api %s", __FUNCTION__, (void *)this, (void *)gmp, api.get()));
- if (!gmp || !gmp->EnsureProcessLoaded(aId)) {
+ return true;
+}
+
+bool
+GMPServiceParent::RecvLaunchGMP(const uint32_t& aPluginId,
+ nsTArray<ProcessId>&& aAlreadyBridgedTo,
+ ProcessId* aOutProcessId,
+ nsCString* aOutDisplayName,
+ nsresult* aOutRv)
+{
+ *aOutRv = NS_OK;
+ if (mService->IsShuttingDown()) {
+ *aOutRv = NS_ERROR_ILLEGAL_DURING_SHUTDOWN;
+ return true;
+ }
+
+ RefPtr<GMPParent> gmp(mService->GetById(aPluginId));
+ if (!gmp) {
+ *aOutRv = NS_ERROR_FAILURE;
+ return true;
+ }
+
+ if (!gmp->EnsureProcessLoaded(aOutProcessId)) {
return false;
}
- *aDisplayName = gmp->GetDisplayName();
- *aPluginId = gmp->GetPluginId();
+ *aOutDisplayName = gmp->GetDisplayName();
- return aAlreadyBridgedTo.Contains(*aId) || gmp->Bridge(this);
+ return aAlreadyBridgedTo.Contains(*aOutProcessId) || gmp->Bridge(this);
}
bool
GMPServiceParent::RecvGetGMPNodeId(const nsString& aOrigin,
const nsString& aTopLevelOrigin,
const nsString& aGMPName,
const bool& aInPrivateBrowsing,
nsCString* aID)
--- a/dom/media/gmp/GMPServiceParent.h
+++ b/dom/media/gmp/GMPServiceParent.h
@@ -101,16 +101,18 @@ private:
~DirectoryFilter() {}
};
void ClearNodeIdAndPlugin(DirectoryFilter& aFilter);
void ClearNodeIdAndPlugin(nsIFile* aPluginStorageDir,
DirectoryFilter& aFilter);
void ForgetThisSiteOnGMPThread(const nsACString& aOrigin);
void ClearRecentHistoryOnGMPThread(PRTime aSince);
+ already_AddRefed<GMPParent> GetById(uint32_t aPluginId);
+
protected:
friend class GMPParent;
void ReAddOnGMPThread(const RefPtr<GMPParent>& aOld);
void PluginTerminated(const RefPtr<GMPParent>& aOld);
void InitializePlugins(AbstractThread* aAbstractGMPThread) override;
RefPtr<GenericPromise::AllPromiseType> LoadFromEnvironment();
RefPtr<GenericPromise> AddOnGMPThread(nsString aDirectory);
bool GetContentParentFrom(const nsACString& aNodeId,
@@ -220,37 +222,41 @@ class GMPServiceParent final : public PG
{
public:
explicit GMPServiceParent(GeckoMediaPluginServiceParent* aService)
: mService(aService)
{
}
virtual ~GMPServiceParent();
- bool RecvLoadGMP(const nsCString& aNodeId,
- const nsCString& aApi,
- nsTArray<nsCString>&& aTags,
- nsTArray<ProcessId>&& aAlreadyBridgedTo,
- base::ProcessId* aID,
- nsCString* aDisplayName,
- uint32_t* aPluginId,
- nsresult* aRv) override;
bool RecvGetGMPNodeId(const nsString& aOrigin,
const nsString& aTopLevelOrigin,
const nsString& aGMPName,
const bool& aInPrivateBrowsing,
nsCString* aID) override;
static bool RecvGetGMPPluginVersionForAPI(const nsCString& aAPI,
nsTArray<nsCString>&& aTags,
bool* aHasPlugin,
nsCString* aVersion);
void ActorDestroy(ActorDestroyReason aWhy) override;
static PGMPServiceParent* Create(Transport* aTransport, ProcessId aOtherPid);
+ bool RecvSelectGMP(const nsCString& aNodeId,
+ const nsCString& aAPI,
+ nsTArray<nsCString>&& aTags,
+ uint32_t* aOutPluginId,
+ nsresult* aOutRv) override;
+
+ bool RecvLaunchGMP(const uint32_t& aPluginId,
+ nsTArray<ProcessId>&& aAlreadyBridgedTo,
+ ProcessId* aOutID,
+ nsCString* aOutDisplayName,
+ nsresult* aOutRv) override;
+
private:
RefPtr<GeckoMediaPluginServiceParent> mService;
};
} // namespace gmp
} // namespace mozilla
#endif // GMPServiceParent_h_
--- a/dom/media/gmp/PGMPService.ipdl
+++ b/dom/media/gmp/PGMPService.ipdl
@@ -10,20 +10,23 @@ using base::ProcessId from "base/process
namespace mozilla {
namespace gmp {
sync protocol PGMPService
{
parent spawns PGMP as child;
parent:
- sync LoadGMP(nsCString nodeId, nsCString api, nsCString[] tags,
- ProcessId[] alreadyBridgedTo)
- returns (ProcessId id, nsCString displayName, uint32_t pluginId,
- nsresult aResult);
+
+ sync SelectGMP(nsCString nodeId, nsCString api, nsCString[] tags)
+ returns (uint32_t pluginId, nsresult aResult);
+
+ sync LaunchGMP(uint32_t pluginId, ProcessId[] alreadyBridgedTo)
+ returns (ProcessId id, nsCString displayName, nsresult aResult);
+
sync GetGMPNodeId(nsString origin, nsString topLevelOrigin,
nsString gmpName,
bool inPrivateBrowsing)
returns (nsCString id);
};
} // namespace gmp
} // namespace mozilla