Bug 1321871, part 2 - Remove PContent opens of PGMPService. r=peterv draft
authorAndrew McCreight <continuation@gmail.com>
Thu, 05 Jan 2017 12:55:57 -0800
changeset 465410 e395972b467063f85d3b390b3b42e39b1ac25185
parent 465409 3f0264a9d078353d3c24b4ab637eefac61f7a00a
child 466383 0a110f082dfbb91ee8f3885d5e09d13f95a2ae31
push id42584
push userbmo:continuation@gmail.com
push dateTue, 24 Jan 2017 00:38:38 +0000
reviewerspeterv
bugs1321871
milestone54.0a1
Bug 1321871, part 2 - Remove PContent opens of PGMPService. r=peterv
dom/ipc/ContentChild.cpp
dom/ipc/ContentChild.h
dom/ipc/ContentParent.cpp
dom/ipc/ContentParent.h
dom/ipc/PContent.ipdl
dom/media/gmp/GMPServiceChild.cpp
dom/media/gmp/GMPServiceChild.h
dom/media/gmp/GMPServiceParent.cpp
dom/media/gmp/GMPServiceParent.h
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -1235,21 +1235,23 @@ ContentChild::AllocPContentBridgeParent(
                                         base::ProcessId aOtherProcess)
 {
   MOZ_ASSERT(!mLastBridge);
   mLastBridge = static_cast<ContentBridgeParent*>(
     ContentBridgeParent::Create(aTransport, aOtherProcess));
   return mLastBridge;
 }
 
-PGMPServiceChild*
-ContentChild::AllocPGMPServiceChild(mozilla::ipc::Transport* aTransport,
-                                    base::ProcessId aOtherProcess)
+mozilla::ipc::IPCResult
+ContentChild::RecvInitGMPService(Endpoint<PGMPServiceChild>&& aGMPService)
 {
-  return GMPServiceChild::Create(aTransport, aOtherProcess);
+  if (!GMPServiceChild::Create(Move(aGMPService))) {
+    return IPC_FAIL_NO_REASON(this);
+  }
+  return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
 ContentChild::RecvGMPsChanged(nsTArray<GMPCapabilityData>&& capabilities)
 {
   GeckoMediaPluginServiceChild::UpdateGMPCapabilities(Move(capabilities));
   return IPC_OK();
 }
--- a/dom/ipc/ContentChild.h
+++ b/dom/ipc/ContentChild.h
@@ -153,19 +153,18 @@ public:
 
   PContentBridgeParent*
   AllocPContentBridgeParent(mozilla::ipc::Transport* transport,
                             base::ProcessId otherProcess) override;
   PContentBridgeChild*
   AllocPContentBridgeChild(mozilla::ipc::Transport* transport,
                            base::ProcessId otherProcess) override;
 
-  PGMPServiceChild*
-  AllocPGMPServiceChild(mozilla::ipc::Transport* transport,
-                        base::ProcessId otherProcess) override;
+  mozilla::ipc::IPCResult
+  RecvInitGMPService(Endpoint<PGMPServiceChild>&& aGMPService) override;
 
   mozilla::ipc::IPCResult
   RecvGMPsChanged(nsTArray<GMPCapabilityData>&& capabilities) override;
 
   mozilla::ipc::IPCResult
   RecvInitProcessHangMonitor(Endpoint<PProcessHangMonitorChild>&& aHangMonitor) override;
 
   mozilla::ipc::IPCResult
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -830,19 +830,38 @@ static nsIDocShell* GetOpenerDocShellHel
   }
 
   return docShell;
 }
 
 mozilla::ipc::IPCResult
 ContentParent::RecvCreateGMPService()
 {
-  if (!PGMPService::Open(this)) {
+  Endpoint<PGMPServiceParent> parent;
+  Endpoint<PGMPServiceChild> child;
+
+  nsresult rv;
+  rv = PGMPService::CreateEndpoints(base::GetCurrentProcId(),
+                                    OtherPid(),
+                                    &parent, &child);
+  if (NS_FAILED(rv)) {
+    MOZ_ASSERT(false, "CreateEndpoints failed");
     return IPC_FAIL_NO_REASON(this);
   }
+
+  if (!GMPServiceParent::Create(Move(parent))) {
+    MOZ_ASSERT(false, "GMPServiceParent::Create failed");
+    return IPC_FAIL_NO_REASON(this);
+  }
+
+  if (!SendInitGMPService(Move(child))) {
+    MOZ_ASSERT(false, "SendInitGMPService failed");
+    return IPC_FAIL_NO_REASON(this);
+  }
+
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
 ContentParent::RecvLoadPlugin(const uint32_t& aPluginId, nsresult* aRv, uint32_t* aRunID)
 {
   *aRv = NS_OK;
   if (!mozilla::plugins::SetupBridge(aPluginId, this, false, aRv, aRunID)) {
@@ -2459,23 +2478,16 @@ ContentParent::Observe(nsISupports* aSub
   }
 #endif
   else if (!strcmp(aTopic, "cacheservice:empty-cache")) {
     Unused << SendNotifyEmptyHTTPCache();
   }
   return NS_OK;
 }
 
-PGMPServiceParent*
-ContentParent::AllocPGMPServiceParent(mozilla::ipc::Transport* aTransport,
-                                      base::ProcessId aOtherProcess)
-{
-  return GMPServiceParent::Create(aTransport, aOtherProcess);
-}
-
 PBackgroundParent*
 ContentParent::AllocPBackgroundParent(Transport* aTransport,
                                       ProcessId aOtherProcess)
 {
   return BackgroundParent::Alloc(this, aTransport, aOtherProcess);
 }
 
 mozilla::ipc::IPCResult
--- a/dom/ipc/ContentParent.h
+++ b/dom/ipc/ContentParent.h
@@ -700,20 +700,16 @@ private:
   void StartForceKillTimer();
 
   static void ForceKillTimerCallback(nsITimer* aTimer, void* aClosure);
 
   static bool AllocateLayerTreeId(ContentParent* aContent,
                                   TabParent* aTopLevel, const TabId& aTabId,
                                   uint64_t* aId);
 
-  PGMPServiceParent*
-  AllocPGMPServiceParent(mozilla::ipc::Transport* aTransport,
-                         base::ProcessId aOtherProcess) override;
-
   PBackgroundParent*
   AllocPBackgroundParent(Transport* aTransport, ProcessId aOtherProcess)
                          override;
 
   virtual mozilla::ipc::IPCResult RecvGetProcessAttributes(ContentParentId* aCpId,
                                                            bool* aIsForBrowser) override;
 
   virtual mozilla::ipc::IPCResult
--- a/dom/ipc/PContent.ipdl
+++ b/dom/ipc/PContent.ipdl
@@ -351,17 +351,16 @@ struct GfxInfoFeatureStatus
  * The PContent protocol is a top-level protocol between the UI process
  * and a content process. There is exactly one PContentParent/PContentChild pair
  * for each content process.
  */
 nested(upto inside_cpow) sync protocol PContent
 {
     parent spawns PPluginModule;
 
-    parent opens PGMPService;
     child opens PBackground;
 
     manages PBlob;
     manages PBrowser;
     manages PContentPermissionRequest;
     manages PCrashReporter;
     manages PCycleCollectWithLogs;
     manages PDeviceStorageRequest;
@@ -418,16 +417,17 @@ both:
     // For parent->child, aBrowser must be non-null; aOuterWindowID can
     // be 0 to indicate the browser's current root document, or nonzero
     // to persist a subdocument.  For child->parent, arguments are
     // ignored and should be null/zero.
     async PWebBrowserPersistDocument(nullable PBrowser aBrowser,
                                      uint64_t aOuterWindowID);
 
 child:
+    async InitGMPService(Endpoint<PGMPServiceChild> service);
     async InitProcessHangMonitor(Endpoint<PProcessHangMonitorChild> hangMonitor);
 
     // Give the content process its endpoints to the compositor.
     async InitRendering(
       Endpoint<PCompositorBridgeChild> compositor,
       Endpoint<PImageBridgeChild> imageBridge,
       Endpoint<PVRManagerChild> vr,
       Endpoint<PVideoDecoderManagerChild> video);
--- a/dom/media/gmp/GMPServiceChild.cpp
+++ b/dom/media/gmp/GMPServiceChild.cpp
@@ -391,64 +391,54 @@ GMPServiceChild::GetAlreadyBridgedTo(nsT
     aAlreadyBridgedTo.AppendElement(id);
   }
 }
 
 class OpenPGMPServiceChild : public mozilla::Runnable
 {
 public:
   OpenPGMPServiceChild(UniquePtr<GMPServiceChild>&& aGMPServiceChild,
-                       mozilla::ipc::Transport* aTransport,
-                       base::ProcessId aOtherPid)
+                       ipc::Endpoint<PGMPServiceChild>&& aEndpoint)
     : mGMPServiceChild(Move(aGMPServiceChild)),
-      mTransport(aTransport),
-      mOtherPid(aOtherPid)
+      mEndpoint(Move(aEndpoint))
   {
   }
 
   NS_IMETHOD Run() override
   {
     RefPtr<GeckoMediaPluginServiceChild> gmp =
       GeckoMediaPluginServiceChild::GetSingleton();
     MOZ_ASSERT(!gmp->mServiceChild);
-    if (mGMPServiceChild->Open(mTransport, mOtherPid, XRE_GetIOMessageLoop(),
-                               ipc::ChildSide)) {
+    if (mEndpoint.Bind(mGMPServiceChild.get())) {
       gmp->SetServiceChild(Move(mGMPServiceChild));
     } else {
       gmp->SetServiceChild(nullptr);
     }
     return NS_OK;
   }
 
 private:
   UniquePtr<GMPServiceChild> mGMPServiceChild;
-  mozilla::ipc::Transport* mTransport;
-  base::ProcessId mOtherPid;
+  ipc::Endpoint<PGMPServiceChild> mEndpoint;
 };
 
 /* static */
-PGMPServiceChild*
-GMPServiceChild::Create(Transport* aTransport, ProcessId aOtherPid)
+bool
+GMPServiceChild::Create(Endpoint<PGMPServiceChild>&& aGMPService)
 {
   RefPtr<GeckoMediaPluginServiceChild> gmp =
     GeckoMediaPluginServiceChild::GetSingleton();
   MOZ_ASSERT(!gmp->mServiceChild);
 
   UniquePtr<GMPServiceChild> serviceChild(new GMPServiceChild());
 
   nsCOMPtr<nsIThread> gmpThread;
   nsresult rv = gmp->GetThread(getter_AddRefs(gmpThread));
-  NS_ENSURE_SUCCESS(rv, nullptr);
+  NS_ENSURE_SUCCESS(rv, false);
 
-  GMPServiceChild* result = serviceChild.get();
   rv = gmpThread->Dispatch(new OpenPGMPServiceChild(Move(serviceChild),
-                                                    aTransport,
-                                                    aOtherPid),
+                                                    Move(aGMPService)),
                            NS_DISPATCH_NORMAL);
-  if (NS_FAILED(rv)) {
-    return nullptr;
-  }
-
-  return result;
+  return NS_SUCCEEDED(rv);
 }
 
 } // namespace gmp
 } // namespace mozilla
--- a/dom/media/gmp/GMPServiceChild.h
+++ b/dom/media/gmp/GMPServiceChild.h
@@ -72,17 +72,17 @@ public:
 
   already_AddRefed<GMPContentParent> GetBridgedGMPContentParent(ProcessId aOtherPid,
                                                                 ipc::Endpoint<PGMPContentParent>&& endpoint);
 
   void RemoveGMPContentParent(GMPContentParent* aGMPContentParent);
 
   void GetAlreadyBridgedTo(nsTArray<ProcessId>& aAlreadyBridgedTo);
 
-  static PGMPServiceChild* Create(Transport* aTransport, ProcessId aOtherPid);
+  static bool Create(Endpoint<PGMPServiceChild>&& aGMPService);
 
 private:
   nsRefPtrHashtable<nsUint64HashKey, GMPContentParent> mContentParents;
 };
 
 } // namespace gmp
 } // namespace mozilla
 
--- a/dom/media/gmp/GMPServiceParent.cpp
+++ b/dom/media/gmp/GMPServiceParent.cpp
@@ -1789,64 +1789,64 @@ GMPServiceParent::ActorDestroy(ActorDest
 
   NS_DispatchToCurrentThread(new DeleteGMPServiceParent(this));
 }
 
 class OpenPGMPServiceParent : public mozilla::Runnable
 {
 public:
   OpenPGMPServiceParent(GMPServiceParent* aGMPServiceParent,
-                        mozilla::ipc::Transport* aTransport,
-                        base::ProcessId aOtherPid,
+                        ipc::Endpoint<PGMPServiceParent>&& aEndpoint,
                         bool* aResult)
     : mGMPServiceParent(aGMPServiceParent),
-      mTransport(aTransport),
-      mOtherPid(aOtherPid),
+      mEndpoint(Move(aEndpoint)),
       mResult(aResult)
   {
   }
 
   NS_IMETHOD Run() override
   {
-    *mResult = mGMPServiceParent->Open(mTransport, mOtherPid,
-                                       XRE_GetIOMessageLoop(), ipc::ParentSide);
+    *mResult = mEndpoint.Bind(mGMPServiceParent);
     return NS_OK;
   }
 
 private:
   GMPServiceParent* mGMPServiceParent;
-  mozilla::ipc::Transport* mTransport;
-  base::ProcessId mOtherPid;
+  ipc::Endpoint<PGMPServiceParent> mEndpoint;
   bool* mResult;
 };
 
 /* static */
-PGMPServiceParent*
-GMPServiceParent::Create(Transport* aTransport, ProcessId aOtherPid)
+bool
+GMPServiceParent::Create(Endpoint<PGMPServiceParent>&& aGMPService)
 {
   RefPtr<GeckoMediaPluginServiceParent> gmp =
     GeckoMediaPluginServiceParent::GetSingleton();
 
   if (gmp->mShuttingDown) {
     // Shutdown is initiated. There is no point creating a new actor.
-    return nullptr;
+    return false;
   }
 
   nsCOMPtr<nsIThread> gmpThread;
   nsresult rv = gmp->GetThread(getter_AddRefs(gmpThread));
-  NS_ENSURE_SUCCESS(rv, nullptr);
+  NS_ENSURE_SUCCESS(rv, false);
 
   nsAutoPtr<GMPServiceParent> serviceParent(new GMPServiceParent(gmp));
-
   bool ok;
   rv = gmpThread->Dispatch(new OpenPGMPServiceParent(serviceParent,
-                                                     aTransport,
-                                                     aOtherPid, &ok),
+                                                     Move(aGMPService),
+                                                     &ok),
                            NS_DISPATCH_SYNC);
+
   if (NS_FAILED(rv) || !ok) {
-    return nullptr;
+    return false;
   }
 
-  return serviceParent.forget();
+  // Now that the service parent is set up, it will be destroyed by
+  // ActorDestroy.
+  Unused << serviceParent.forget();
+
+  return true;
 }
 
 } // namespace gmp
 } // namespace mozilla
--- a/dom/media/gmp/GMPServiceParent.h
+++ b/dom/media/gmp/GMPServiceParent.h
@@ -220,17 +220,17 @@ public:
   virtual ~GMPServiceParent();
 
   mozilla::ipc::IPCResult RecvGetGMPNodeId(const nsString& aOrigin,
                                            const nsString& aTopLevelOrigin,
                                            const nsString& aGMPName,
                                            nsCString* aID) override;
   void ActorDestroy(ActorDestroyReason aWhy) override;
 
-  static PGMPServiceParent* Create(Transport* aTransport, ProcessId aOtherPid);
+  static bool Create(Endpoint<PGMPServiceParent>&& aGMPService);
 
   mozilla::ipc::IPCResult RecvLaunchGMP(const nsCString& aNodeId,
                                         const nsCString& aAPI,
                                         nsTArray<nsCString>&& aTags,
                                         nsTArray<ProcessId>&& aAlreadyBridgedTo,
                                         uint32_t* aOutPluginId,
                                         ProcessId* aOutID,
                                         nsCString* aOutDisplayName,