LCOV - code coverage report
Current view: top level - dom/media/gmp - GMPServiceChild.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 27 272 9.9 %
Date: 2017-07-14 16:53:18 Functions: 4 41 9.8 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* This Source Code Form is subject to the terms of the Mozilla Public
       3             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       4             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       5             : 
       6             : #include "GMPServiceChild.h"
       7             : #include "mozilla/dom/ContentChild.h"
       8             : #include "mozilla/ClearOnShutdown.h"
       9             : #include "mozilla/StaticPtr.h"
      10             : #include "mozIGeckoMediaPluginService.h"
      11             : #include "mozIGeckoMediaPluginChromeService.h"
      12             : #include "nsCOMPtr.h"
      13             : #include "GMPParent.h"
      14             : #include "GMPContentParent.h"
      15             : #include "nsXPCOMPrivate.h"
      16             : #include "mozilla/SyncRunnable.h"
      17             : #include "mozilla/StaticMutex.h"
      18             : #include "runnable_utils.h"
      19             : #include "base/task.h"
      20             : #include "nsIObserverService.h"
      21             : #include "nsComponentManagerUtils.h"
      22             : 
      23             : namespace mozilla {
      24             : 
      25             : #ifdef LOG
      26             : #undef LOG
      27             : #endif
      28             : 
      29             : #define LOGD(msg) MOZ_LOG(GetGMPLog(), mozilla::LogLevel::Debug, msg)
      30             : #define LOG(level, msg) MOZ_LOG(GetGMPLog(), (level), msg)
      31             : 
      32             : #ifdef __CLASS__
      33             : #undef __CLASS__
      34             : #endif
      35             : #define __CLASS__ "GMPService"
      36             : 
      37             : namespace gmp {
      38             : 
      39             : already_AddRefed<GeckoMediaPluginServiceChild>
      40           0 : GeckoMediaPluginServiceChild::GetSingleton()
      41             : {
      42           0 :   MOZ_ASSERT(!XRE_IsParentProcess());
      43             :   RefPtr<GeckoMediaPluginService> service(
      44           0 :     GeckoMediaPluginService::GetGeckoMediaPluginService());
      45             : #ifdef DEBUG
      46           0 :   if (service) {
      47           0 :     nsCOMPtr<mozIGeckoMediaPluginChromeService> chromeService;
      48           0 :     CallQueryInterface(service.get(), getter_AddRefs(chromeService));
      49           0 :     MOZ_ASSERT(!chromeService);
      50             :   }
      51             : #endif
      52           0 :   return service.forget().downcast<GeckoMediaPluginServiceChild>();
      53             : }
      54             : 
      55             : RefPtr<GetGMPContentParentPromise>
      56           0 : GeckoMediaPluginServiceChild::GetContentParent(GMPCrashHelper* aHelper,
      57             :                                                const nsACString& aNodeIdString,
      58             :                                                const nsCString& aAPI,
      59             :                                                const nsTArray<nsCString>& aTags)
      60             : {
      61           0 :   MOZ_ASSERT(mGMPThread->EventTarget()->IsOnCurrentThread());
      62             : 
      63           0 :   MozPromiseHolder<GetGMPContentParentPromise>* rawHolder = new MozPromiseHolder<GetGMPContentParentPromise>();
      64           0 :   RefPtr<GetGMPContentParentPromise> promise = rawHolder->Ensure(__func__);
      65           0 :   RefPtr<AbstractThread> thread(GetAbstractGMPThread());
      66             : 
      67           0 :   nsCString nodeIdString(aNodeIdString);
      68           0 :   nsCString api(aAPI);
      69           0 :   nsTArray<nsCString> tags(aTags);
      70           0 :   RefPtr<GMPCrashHelper> helper(aHelper);
      71           0 :   RefPtr<GeckoMediaPluginServiceChild> self(this);
      72           0 :   GetServiceChild()->Then(
      73             :     thread,
      74             :     __func__,
      75           0 :     [self, nodeIdString, api, tags, helper, rawHolder](GMPServiceChild* child) {
      76           0 :       UniquePtr<MozPromiseHolder<GetGMPContentParentPromise>> holder(rawHolder);
      77             :       nsresult rv;
      78             : 
      79           0 :       nsTArray<base::ProcessId> alreadyBridgedTo;
      80           0 :       child->GetAlreadyBridgedTo(alreadyBridgedTo);
      81             : 
      82             :       base::ProcessId otherProcess;
      83           0 :       nsCString displayName;
      84           0 :       uint32_t pluginId = 0;
      85           0 :       ipc::Endpoint<PGMPContentParent> endpoint;
      86           0 :       bool ok = child->SendLaunchGMP(nodeIdString,
      87             :                                      api,
      88             :                                      tags,
      89             :                                      alreadyBridgedTo,
      90             :                                      &pluginId,
      91             :                                      &otherProcess,
      92             :                                      &displayName,
      93             :                                      &endpoint,
      94           0 :                                      &rv);
      95           0 :       if (helper && pluginId) {
      96             :         // Note: Even if the launch failed, we need to connect the crash
      97             :         // helper so that if the launch failed due to the plugin crashing,
      98             :         // we can report the crash via the crash reporter. The crash
      99             :         // handling notification will arrive shortly if the launch failed
     100             :         // due to the plugin crashing.
     101           0 :         self->ConnectCrashHelper(pluginId, helper);
     102             :       }
     103             : 
     104           0 :       if (!ok || NS_FAILED(rv)) {
     105           0 :         LOGD(("GeckoMediaPluginServiceChild::GetContentParent SendLaunchGMP "
     106             :               "failed rv=0x%x",
     107             :               static_cast<uint32_t>(rv)));
     108           0 :         holder->Reject(rv, __func__);
     109           0 :         return;
     110             :       }
     111             : 
     112             :       RefPtr<GMPContentParent> parent =
     113           0 :         child->GetBridgedGMPContentParent(otherProcess, Move(endpoint));
     114           0 :       if (!alreadyBridgedTo.Contains(otherProcess)) {
     115           0 :         parent->SetDisplayName(displayName);
     116           0 :         parent->SetPluginId(pluginId);
     117             :       }
     118             :       RefPtr<GMPContentParent::CloseBlocker> blocker(
     119           0 :         new GMPContentParent::CloseBlocker(parent));
     120           0 :       holder->Resolve(blocker, __func__);
     121             :     },
     122           0 :     [rawHolder](nsresult rv) {
     123           0 :       UniquePtr<MozPromiseHolder<GetGMPContentParentPromise>> holder(rawHolder);
     124           0 :       holder->Reject(rv, __func__);
     125           0 :     });
     126             : 
     127           0 :   return promise;
     128             : }
     129             : 
     130             : RefPtr<GetGMPContentParentPromise>
     131           0 : GeckoMediaPluginServiceChild::GetContentParent(GMPCrashHelper* aHelper,
     132             :                                                const NodeId& aNodeId,
     133             :                                                const nsCString& aAPI,
     134             :                                                const nsTArray<nsCString>& aTags)
     135             : {
     136           0 :   MOZ_ASSERT(mGMPThread->EventTarget()->IsOnCurrentThread());
     137             : 
     138             :   MozPromiseHolder<GetGMPContentParentPromise>* rawHolder =
     139           0 :     new MozPromiseHolder<GetGMPContentParentPromise>();
     140           0 :   RefPtr<GetGMPContentParentPromise> promise = rawHolder->Ensure(__func__);
     141           0 :   RefPtr<AbstractThread> thread(GetAbstractGMPThread());
     142             : 
     143           0 :   NodeIdData nodeId(aNodeId.mOrigin, aNodeId.mTopLevelOrigin, aNodeId.mGMPName);
     144           0 :   nsCString api(aAPI);
     145           0 :   nsTArray<nsCString> tags(aTags);
     146           0 :   RefPtr<GMPCrashHelper> helper(aHelper);
     147           0 :   RefPtr<GeckoMediaPluginServiceChild> self(this);
     148           0 :   GetServiceChild()->Then(thread, __func__,
     149           0 :     [self, nodeId, api, tags, helper, rawHolder](GMPServiceChild* child) {
     150           0 :       UniquePtr<MozPromiseHolder<GetGMPContentParentPromise>> holder(rawHolder);
     151             :       nsresult rv;
     152             : 
     153           0 :       nsTArray<base::ProcessId> alreadyBridgedTo;
     154           0 :       child->GetAlreadyBridgedTo(alreadyBridgedTo);
     155             : 
     156             :       base::ProcessId otherProcess;
     157           0 :       nsCString displayName;
     158           0 :       uint32_t pluginId = 0;
     159           0 :       ipc::Endpoint<PGMPContentParent> endpoint;
     160             : 
     161           0 :       bool ok = child->SendLaunchGMPForNodeId(nodeId,
     162             :                                               api,
     163             :                                               tags,
     164             :                                               alreadyBridgedTo,
     165             :                                               &pluginId,
     166             :                                               &otherProcess,
     167             :                                               &displayName,
     168             :                                               &endpoint,
     169           0 :                                               &rv);
     170             : 
     171           0 :       if (helper && pluginId) {
     172             :         // Note: Even if the launch failed, we need to connect the crash
     173             :         // helper so that if the launch failed due to the plugin crashing,
     174             :         // we can report the crash via the crash reporter. The crash
     175             :         // handling notification will arrive shortly if the launch failed
     176             :         // due to the plugin crashing.
     177           0 :         self->ConnectCrashHelper(pluginId, helper);
     178             :       }
     179             : 
     180           0 :       if (!ok || NS_FAILED(rv)) {
     181           0 :         LOGD(("GeckoMediaPluginServiceChild::GetContentParent SendLaunchGMP failed rv=%" PRIu32,
     182             :               static_cast<uint32_t>(rv)));
     183           0 :         holder->Reject(rv, __func__);
     184           0 :         return;
     185             :       }
     186             : 
     187           0 :       RefPtr<GMPContentParent> parent = child->GetBridgedGMPContentParent(otherProcess,
     188           0 :                                                                           Move(endpoint));
     189           0 :       if (!alreadyBridgedTo.Contains(otherProcess)) {
     190           0 :         parent->SetDisplayName(displayName);
     191           0 :         parent->SetPluginId(pluginId);
     192             :       }
     193             : 
     194           0 :       RefPtr<GMPContentParent::CloseBlocker> blocker(new GMPContentParent::CloseBlocker(parent));
     195           0 :       holder->Resolve(blocker, __func__);
     196             :     },
     197           0 :     [rawHolder](nsresult rv) {
     198           0 :       UniquePtr<MozPromiseHolder<GetGMPContentParentPromise>> holder(rawHolder);
     199           0 :       holder->Reject(rv, __func__);
     200           0 :     });
     201             : 
     202           0 :   return promise;
     203             : }
     204             : 
     205             : typedef mozilla::dom::GMPCapabilityData GMPCapabilityData;
     206             : typedef mozilla::dom::GMPAPITags GMPAPITags;
     207             : 
     208           7 : struct GMPCapabilityAndVersion
     209             : {
     210           3 :   explicit GMPCapabilityAndVersion(const GMPCapabilityData& aCapabilities)
     211           3 :     : mName(aCapabilities.name())
     212           3 :     , mVersion(aCapabilities.version())
     213             :   {
     214           6 :     for (const GMPAPITags& tags : aCapabilities.capabilities()) {
     215           6 :       GMPCapability cap;
     216           3 :       cap.mAPIName = tags.api();
     217           6 :       for (const nsCString& tag : tags.tags()) {
     218           3 :         cap.mAPITags.AppendElement(tag);
     219             :       }
     220           3 :       mCapabilities.AppendElement(Move(cap));
     221             :     }
     222           3 :   }
     223             : 
     224           0 :   nsCString ToString() const
     225             :   {
     226           0 :     nsCString s;
     227           0 :     s.Append(mName);
     228           0 :     s.Append(" version=");
     229           0 :     s.Append(mVersion);
     230           0 :     s.Append(" tags=[");
     231           0 :     nsCString tags;
     232           0 :     for (const GMPCapability& cap : mCapabilities) {
     233           0 :       if (!tags.IsEmpty()) {
     234           0 :         tags.Append(" ");
     235             :       }
     236           0 :       tags.Append(cap.mAPIName);
     237           0 :       for (const nsCString& tag : cap.mAPITags) {
     238           0 :         tags.Append(":");
     239           0 :         tags.Append(tag);
     240             :       }
     241             :     }
     242           0 :     s.Append(tags);
     243           0 :     s.Append("]");
     244           0 :     return s;
     245             :   }
     246             : 
     247             :   nsCString mName;
     248             :   nsCString mVersion;
     249             :   nsTArray<GMPCapability> mCapabilities;
     250             : };
     251             : 
     252           3 : StaticMutex sGMPCapabilitiesMutex;
     253           3 : StaticAutoPtr<nsTArray<GMPCapabilityAndVersion>> sGMPCapabilities;
     254             : 
     255             : static nsCString
     256           0 : GMPCapabilitiesToString()
     257             : {
     258           0 :   nsCString s;
     259           0 :   for (const GMPCapabilityAndVersion& gmp : *sGMPCapabilities) {
     260           0 :     if (!s.IsEmpty()) {
     261           0 :       s.Append(", ");
     262             :     }
     263           0 :     s.Append(gmp.ToString());
     264             :   }
     265           0 :   return s;
     266             : }
     267             : 
     268             : /* static */
     269             : void
     270           3 : GeckoMediaPluginServiceChild::UpdateGMPCapabilities(nsTArray<GMPCapabilityData>&& aCapabilities)
     271             : {
     272             :   {
     273             :     // The mutex should unlock before sending the "gmp-changed" observer service notification.
     274           6 :     StaticMutexAutoLock lock(sGMPCapabilitiesMutex);
     275           3 :     if (!sGMPCapabilities) {
     276           2 :       sGMPCapabilities = new nsTArray<GMPCapabilityAndVersion>();
     277           2 :       ClearOnShutdown(&sGMPCapabilities);
     278             :     }
     279           3 :     sGMPCapabilities->Clear();
     280           6 :     for (const GMPCapabilityData& plugin : aCapabilities) {
     281           3 :       sGMPCapabilities->AppendElement(GMPCapabilityAndVersion(plugin));
     282             :     }
     283             : 
     284           3 :     LOGD(("UpdateGMPCapabilities {%s}", GMPCapabilitiesToString().get()));
     285             :   }
     286             : 
     287             :   // Fire a notification so that any MediaKeySystemAccess
     288             :   // requests waiting on a CDM to download will retry.
     289           6 :   nsCOMPtr<nsIObserverService> obsService = mozilla::services::GetObserverService();
     290           3 :   MOZ_ASSERT(obsService);
     291           3 :   if (obsService) {
     292           3 :     obsService->NotifyObservers(nullptr, "gmp-changed", nullptr);
     293             :   }
     294           3 : }
     295             : 
     296             : void
     297           0 : GeckoMediaPluginServiceChild::BeginShutdown()
     298             : {
     299           0 :   MOZ_ASSERT(mGMPThread->EventTarget()->IsOnCurrentThread());
     300           0 :   mShuttingDownOnGMPThread = true;
     301           0 : }
     302             : 
     303             : NS_IMETHODIMP
     304           0 : GeckoMediaPluginServiceChild::HasPluginForAPI(const nsACString& aAPI,
     305             :                                               nsTArray<nsCString>* aTags,
     306             :                                               bool* aHasPlugin)
     307             : {
     308           0 :   StaticMutexAutoLock lock(sGMPCapabilitiesMutex);
     309           0 :   if (!sGMPCapabilities) {
     310           0 :     *aHasPlugin = false;
     311           0 :     return NS_OK;
     312             :   }
     313             : 
     314           0 :   nsCString api(aAPI);
     315           0 :   for (const GMPCapabilityAndVersion& plugin : *sGMPCapabilities) {
     316           0 :     if (GMPCapability::Supports(plugin.mCapabilities, api, *aTags)) {
     317           0 :       *aHasPlugin = true;
     318           0 :       return NS_OK;
     319             :     }
     320             :   }
     321             : 
     322           0 :   *aHasPlugin = false;
     323           0 :   return NS_OK;
     324             : }
     325             : 
     326             : NS_IMETHODIMP
     327           0 : GeckoMediaPluginServiceChild::GetNodeId(const nsAString& aOrigin,
     328             :                                         const nsAString& aTopLevelOrigin,
     329             :                                         const nsAString& aGMPName,
     330             :                                         UniquePtr<GetNodeIdCallback>&& aCallback)
     331             : {
     332           0 :   MOZ_ASSERT(mGMPThread->EventTarget()->IsOnCurrentThread());
     333             : 
     334           0 :   GetNodeIdCallback* rawCallback = aCallback.release();
     335           0 :   RefPtr<AbstractThread> thread(GetAbstractGMPThread());
     336           0 :   nsString origin(aOrigin);
     337           0 :   nsString topLevelOrigin(aTopLevelOrigin);
     338           0 :   nsString gmpName(aGMPName);
     339           0 :   GetServiceChild()->Then(thread, __func__,
     340           0 :     [rawCallback, origin, topLevelOrigin, gmpName](GMPServiceChild* child) {
     341           0 :       UniquePtr<GetNodeIdCallback> callback(rawCallback);
     342           0 :       nsCString outId;
     343           0 :       if (!child->SendGetGMPNodeId(origin, topLevelOrigin,
     344             :                                    gmpName, &outId)) {
     345           0 :         callback->Done(NS_ERROR_FAILURE, EmptyCString());
     346           0 :         return;
     347             :       }
     348             : 
     349           0 :       callback->Done(NS_OK, outId);
     350             :     },
     351           0 :     [rawCallback](nsresult rv) {
     352           0 :       UniquePtr<GetNodeIdCallback> callback(rawCallback);
     353           0 :       callback->Done(NS_ERROR_FAILURE, EmptyCString());
     354           0 :     });
     355             : 
     356           0 :   return NS_OK;
     357             : }
     358             : 
     359             : NS_IMETHODIMP
     360           0 : GeckoMediaPluginServiceChild::Observe(nsISupports* aSubject,
     361             :                                       const char* aTopic,
     362             :                                       const char16_t* aSomeData)
     363             : {
     364           0 :   LOGD(("%s::%s: %s", __CLASS__, __FUNCTION__, aTopic));
     365           0 :   if (!strcmp(NS_XPCOM_SHUTDOWN_THREADS_OBSERVER_ID, aTopic)) {
     366           0 :     if (mServiceChild) {
     367           0 :       mozilla::SyncRunnable::DispatchToThread(mGMPThread,
     368           0 :                                               WrapRunnable(mServiceChild.get(),
     369           0 :                                                            &PGMPServiceChild::Close));
     370           0 :       mServiceChild = nullptr;
     371             :     }
     372           0 :     ShutdownGMPThread();
     373             :   }
     374             : 
     375           0 :   return NS_OK;
     376             : }
     377             : 
     378             : RefPtr<GeckoMediaPluginServiceChild::GetServiceChildPromise>
     379           0 : GeckoMediaPluginServiceChild::GetServiceChild()
     380             : {
     381           0 :   MOZ_ASSERT(mGMPThread->EventTarget()->IsOnCurrentThread());
     382             : 
     383           0 :   if (!mServiceChild) {
     384           0 :     if (mShuttingDownOnGMPThread) {
     385             :       // We have begun shutdown. Don't allow a new connection to the main
     386             :       // process to be instantiated. This also prevents new plugins being
     387             :       // instantiated.
     388             :       return GetServiceChildPromise::CreateAndReject(NS_ERROR_FAILURE,
     389           0 :                                                      __func__);
     390             :     }
     391           0 :     dom::ContentChild* contentChild = dom::ContentChild::GetSingleton();
     392           0 :     if (!contentChild) {
     393           0 :       return GetServiceChildPromise::CreateAndReject(NS_ERROR_FAILURE, __func__);
     394             :     }
     395           0 :     MozPromiseHolder<GetServiceChildPromise>* holder = mGetServiceChildPromises.AppendElement();
     396           0 :     RefPtr<GetServiceChildPromise> promise = holder->Ensure(__func__);
     397           0 :     if (mGetServiceChildPromises.Length() == 1) {
     398           0 :       nsCOMPtr<nsIRunnable> r = WrapRunnable(
     399           0 :         contentChild, &dom::ContentChild::SendCreateGMPService);
     400           0 :       SystemGroup::Dispatch("SendCreateGMPService", TaskCategory::Other, r.forget());
     401             :     }
     402           0 :     return promise;
     403             :   }
     404           0 :   return GetServiceChildPromise::CreateAndResolve(mServiceChild.get(), __func__);
     405             : }
     406             : 
     407             : void
     408           0 : GeckoMediaPluginServiceChild::SetServiceChild(UniquePtr<GMPServiceChild>&& aServiceChild)
     409             : {
     410           0 :   MOZ_ASSERT(mGMPThread->EventTarget()->IsOnCurrentThread());
     411             : 
     412           0 :   mServiceChild = Move(aServiceChild);
     413             : 
     414           0 :   nsTArray<MozPromiseHolder<GetServiceChildPromise>> holders;
     415           0 :   holders.SwapElements(mGetServiceChildPromises);
     416           0 :   for (MozPromiseHolder<GetServiceChildPromise>& holder : holders) {
     417           0 :     holder.Resolve(mServiceChild.get(), __func__);
     418             :   }
     419           0 : }
     420             : 
     421             : void
     422           0 : GeckoMediaPluginServiceChild::RemoveGMPContentParent(GMPContentParent* aGMPContentParent)
     423             : {
     424           0 :   MOZ_ASSERT(mGMPThread->EventTarget()->IsOnCurrentThread());
     425             : 
     426           0 :   if (mServiceChild) {
     427           0 :     mServiceChild->RemoveGMPContentParent(aGMPContentParent);
     428           0 :     if (mShuttingDownOnGMPThread && !mServiceChild->HaveContentParents()) {
     429           0 :       mServiceChild->Close();
     430           0 :       mServiceChild = nullptr;
     431             :     }
     432             :   }
     433           0 : }
     434             : 
     435           0 : GMPServiceChild::GMPServiceChild()
     436             : {
     437           0 : }
     438             : 
     439           0 : GMPServiceChild::~GMPServiceChild()
     440             : {
     441           0 : }
     442             : 
     443             : already_AddRefed<GMPContentParent>
     444           0 : GMPServiceChild::GetBridgedGMPContentParent(ProcessId aOtherPid,
     445             :                                             ipc::Endpoint<PGMPContentParent>&& endpoint)
     446             : {
     447           0 :   RefPtr<GMPContentParent> parent;
     448           0 :   mContentParents.Get(aOtherPid, getter_AddRefs(parent));
     449             : 
     450           0 :   if (parent) {
     451           0 :     return parent.forget();
     452             :   }
     453             : 
     454           0 :   MOZ_ASSERT(aOtherPid == endpoint.OtherPid());
     455             : 
     456           0 :   parent = new GMPContentParent();
     457             : 
     458           0 :   DebugOnly<bool> ok = endpoint.Bind(parent);
     459           0 :   MOZ_ASSERT(ok);
     460             : 
     461           0 :   mContentParents.Put(aOtherPid, parent);
     462             : 
     463           0 :   return parent.forget();
     464             : }
     465             : 
     466             : void
     467           0 : GMPServiceChild::RemoveGMPContentParent(GMPContentParent* aGMPContentParent)
     468             : {
     469           0 :   for (auto iter = mContentParents.Iter(); !iter.Done(); iter.Next()) {
     470           0 :     RefPtr<GMPContentParent>& parent = iter.Data();
     471           0 :     if (parent == aGMPContentParent) {
     472           0 :       iter.Remove();
     473           0 :       break;
     474             :     }
     475             :   }
     476           0 : }
     477             : 
     478             : void
     479           0 : GMPServiceChild::GetAlreadyBridgedTo(nsTArray<base::ProcessId>& aAlreadyBridgedTo)
     480             : {
     481           0 :   aAlreadyBridgedTo.SetCapacity(mContentParents.Count());
     482           0 :   for (auto iter = mContentParents.Iter(); !iter.Done(); iter.Next()) {
     483           0 :     const uint64_t& id = iter.Key();
     484           0 :     aAlreadyBridgedTo.AppendElement(id);
     485             :   }
     486           0 : }
     487             : 
     488           0 : class OpenPGMPServiceChild : public mozilla::Runnable
     489             : {
     490             : public:
     491           0 :   OpenPGMPServiceChild(UniquePtr<GMPServiceChild>&& aGMPServiceChild,
     492             :                        ipc::Endpoint<PGMPServiceChild>&& aEndpoint)
     493           0 :     : Runnable("gmp::OpenPGMPServiceChild")
     494           0 :     , mGMPServiceChild(Move(aGMPServiceChild))
     495           0 :     , mEndpoint(Move(aEndpoint))
     496             :   {
     497           0 :   }
     498             : 
     499           0 :   NS_IMETHOD Run() override
     500             :   {
     501             :     RefPtr<GeckoMediaPluginServiceChild> gmp =
     502           0 :       GeckoMediaPluginServiceChild::GetSingleton();
     503           0 :     MOZ_ASSERT(!gmp->mServiceChild);
     504           0 :     if (mEndpoint.Bind(mGMPServiceChild.get())) {
     505           0 :       gmp->SetServiceChild(Move(mGMPServiceChild));
     506             :     } else {
     507           0 :       gmp->SetServiceChild(nullptr);
     508             :     }
     509           0 :     return NS_OK;
     510             :   }
     511             : 
     512             : private:
     513             :   UniquePtr<GMPServiceChild> mGMPServiceChild;
     514             :   ipc::Endpoint<PGMPServiceChild> mEndpoint;
     515             : };
     516             : 
     517             : /* static */
     518             : bool
     519           0 : GMPServiceChild::Create(Endpoint<PGMPServiceChild>&& aGMPService)
     520             : {
     521             :   RefPtr<GeckoMediaPluginServiceChild> gmp =
     522           0 :     GeckoMediaPluginServiceChild::GetSingleton();
     523           0 :   MOZ_ASSERT(!gmp->mServiceChild);
     524             : 
     525           0 :   UniquePtr<GMPServiceChild> serviceChild(new GMPServiceChild());
     526             : 
     527           0 :   nsCOMPtr<nsIThread> gmpThread;
     528           0 :   nsresult rv = gmp->GetThread(getter_AddRefs(gmpThread));
     529           0 :   NS_ENSURE_SUCCESS(rv, false);
     530             : 
     531           0 :   rv = gmpThread->Dispatch(new OpenPGMPServiceChild(Move(serviceChild),
     532           0 :                                                     Move(aGMPService)),
     533           0 :                            NS_DISPATCH_NORMAL);
     534           0 :   return NS_SUCCEEDED(rv);
     535             : }
     536             : 
     537             : ipc::IPCResult
     538           0 : GMPServiceChild::RecvBeginShutdown()
     539             : {
     540             :   RefPtr<GeckoMediaPluginServiceChild> service =
     541           0 :     GeckoMediaPluginServiceChild::GetSingleton();
     542           0 :   MOZ_ASSERT(service && service->mServiceChild.get() == this);
     543           0 :   if (service) {
     544           0 :     service->BeginShutdown();
     545             :   }
     546           0 :   return IPC_OK();
     547             : }
     548             : 
     549             : bool
     550           0 : GMPServiceChild::HaveContentParents() const
     551             : {
     552           0 :   return mContentParents.Count() > 0;
     553             : }
     554             : 
     555             : } // namespace gmp
     556             : } // namespace mozilla

Generated by: LCOV version 1.13