Bug 1386972 - Remove NS_DispatchToMainThread and use nsIEventTarget to dispatch instead. r?cpearce draft
authorJames Cheng <jacheng@mozilla.com>
Thu, 03 Aug 2017 18:04:34 +0800
changeset 620343 4bf373558d5f167c3346c9fc8539dc1d527ac0c3
parent 620189 c95a182cc1c28c2ca749dc1c1731f8347f6d7d23
child 620940 b1ab286a0e36f142edf2b17c35bcba682a7cf2bf
push id72002
push userbmo:jacheng@mozilla.com
push dateThu, 03 Aug 2017 10:04:58 +0000
reviewerscpearce
bugs1386972
milestone57.0a1
Bug 1386972 - Remove NS_DispatchToMainThread and use nsIEventTarget to dispatch instead. r?cpearce MozReview-Commit-ID: JGPrNw5amqg
dom/media/gmp/ChromiumCDMParent.cpp
dom/media/gmp/ChromiumCDMParent.h
dom/media/gmp/ChromiumCDMProxy.cpp
--- a/dom/media/gmp/ChromiumCDMParent.cpp
+++ b/dom/media/gmp/ChromiumCDMParent.cpp
@@ -14,16 +14,18 @@
 #include "MediaPrefs.h"
 #include "mozilla/dom/MediaKeyMessageEventBinding.h"
 #include "mozilla/gmp/GMPTypes.h"
 #include "mozilla/Telemetry.h"
 #include "mozilla/Unused.h"
 #include "mp4_demuxer/AnnexB.h"
 #include "mp4_demuxer/H264.h"
 
+#define NS_DispatchToMainThread(...) CompileError_UseAbstractMainThreadInstead
+
 namespace mozilla {
 namespace gmp {
 
 using namespace eme;
 
 ChromiumCDMParent::ChromiumCDMParent(GMPContentParent* aContentParent,
                                      uint32_t aPluginId)
   : mPluginId(aPluginId)
@@ -35,23 +37,25 @@ ChromiumCDMParent::ChromiumCDMParent(GMP
     this,
     aContentParent,
     aPluginId);
 }
 
 bool
 ChromiumCDMParent::Init(ChromiumCDMProxy* aProxy,
                         bool aAllowDistinctiveIdentifier,
-                        bool aAllowPersistentState)
+                        bool aAllowPersistentState,
+                        nsIEventTarget* aMainThread)
 {
   GMP_LOG("ChromiumCDMParent::Init(this=%p)", this);
-  if (!aProxy) {
+  if (!aProxy || !aMainThread) {
     return false;
   }
   mProxy = aProxy;
+  mMainThread = aMainThread;
   return SendInit(aAllowDistinctiveIdentifier, aAllowPersistentState);
 }
 
 void
 ChromiumCDMParent::CreateSession(uint32_t aCreateSessionToken,
                                  uint32_t aSessionType,
                                  uint32_t aInitDataType,
                                  uint32_t aPromiseId,
@@ -282,23 +286,23 @@ ChromiumCDMParent::RecvOnResolveNewSessi
   Maybe<uint32_t> token = mPromiseToCreateSessionToken.GetAndRemove(aPromiseId);
   if (token.isNothing()) {
     RejectPromise(aPromiseId,
                   NS_ERROR_DOM_INVALID_STATE_ERR,
                   NS_LITERAL_CSTRING("Lost session token for new session."));
     return IPC_OK();
   }
 
-  RefPtr<Runnable> task =
+  mMainThread->Dispatch(
     NewRunnableMethod<uint32_t, nsString>("ChromiumCDMProxy::OnSetSessionId",
                                           mProxy,
                                           &ChromiumCDMProxy::OnSetSessionId,
                                           token.value(),
-                                          NS_ConvertUTF8toUTF16(aSessionId));
-  NS_DispatchToMainThread(task);
+                                          NS_ConvertUTF8toUTF16(aSessionId)),
+    NS_DISPATCH_NORMAL);
 
   ResolvePromise(aPromiseId);
 
   return IPC_OK();
 }
 
 ipc::IPCResult
 ChromiumCDMParent::RecvResolveLoadSessionPromise(const uint32_t& aPromiseId,
@@ -308,40 +312,45 @@ ChromiumCDMParent::RecvResolveLoadSessio
           "successful=%d)",
           this,
           aPromiseId,
           aSuccessful);
   if (!mProxy || mIsShutdown) {
     return IPC_OK();
   }
 
-  NS_DispatchToMainThread(NewRunnableMethod<uint32_t, bool>(
-    "ChromiumCDMProxy::OnResolveLoadSessionPromise",
-    mProxy,
-    &ChromiumCDMProxy::OnResolveLoadSessionPromise,
-    aPromiseId,
-    aSuccessful));
+  mMainThread->Dispatch(
+    NewRunnableMethod<uint32_t, bool>(
+      "ChromiumCDMProxy::OnResolveLoadSessionPromise",
+      mProxy,
+      &ChromiumCDMProxy::OnResolveLoadSessionPromise,
+      aPromiseId,
+      aSuccessful),
+    NS_DISPATCH_NORMAL);
+
   return IPC_OK();
 }
 void
 ChromiumCDMParent::ResolvePromise(uint32_t aPromiseId)
 {
   GMP_LOG(
     "ChromiumCDMParent::ResolvePromise(this=%p, pid=%u)", this, aPromiseId);
 
   // Note: The MediaKeys rejects all pending DOM promises when it
   // initiates shutdown.
   if (!mProxy || mIsShutdown) {
     return;
   }
-  NS_DispatchToMainThread(
+
+  mMainThread->Dispatch(
     NewRunnableMethod<uint32_t>("ChromiumCDMProxy::ResolvePromise",
                                 mProxy,
                                 &ChromiumCDMProxy::ResolvePromise,
-                                aPromiseId));
+                                aPromiseId),
+    NS_DISPATCH_NORMAL);
 }
 
 ipc::IPCResult
 ChromiumCDMParent::RecvOnResolvePromise(const uint32_t& aPromiseId)
 {
   ResolvePromise(aPromiseId);
   return IPC_OK();
 }
@@ -380,23 +389,26 @@ ChromiumCDMParent::RejectPromise(uint32_
 {
   GMP_LOG(
     "ChromiumCDMParent::RejectPromise(this=%p, pid=%u)", this, aPromiseId);
   // Note: The MediaKeys rejects all pending DOM promises when it
   // initiates shutdown.
   if (!mProxy || mIsShutdown) {
     return;
   }
-  NS_DispatchToMainThread(NewRunnableMethod<uint32_t, nsresult, nsCString>(
-    "ChromiumCDMProxy::RejectPromise",
-    mProxy,
-    &ChromiumCDMProxy::RejectPromise,
-    aPromiseId,
-    aError,
-    aErrorMessage));
+
+  mMainThread->Dispatch(
+    NewRunnableMethod<uint32_t, nsresult, nsCString>(
+      "ChromiumCDMProxy::RejectPromise",
+      mProxy,
+      &ChromiumCDMProxy::RejectPromise,
+      aPromiseId,
+      aError,
+      aErrorMessage),
+    NS_DISPATCH_NORMAL);
 }
 
 ipc::IPCResult
 ChromiumCDMParent::RecvOnRejectPromise(const uint32_t& aPromiseId,
                                        const uint32_t& aError,
                                        const uint32_t& aSystemCode,
                                        const nsCString& aErrorMessage)
 {
@@ -429,21 +441,23 @@ ChromiumCDMParent::RecvOnSessionMessage(
           aSessionId.get());
   if (!mProxy || mIsShutdown) {
     return IPC_OK();
   }
   RefPtr<CDMProxy> proxy = mProxy;
   nsString sid = NS_ConvertUTF8toUTF16(aSessionId);
   dom::MediaKeyMessageType messageType = ToDOMMessageType(aMessageType);
   nsTArray<uint8_t> msg(Move(aMessage));
-  NS_DispatchToMainThread(
+
+  mMainThread->Dispatch(
     NS_NewRunnableFunction("gmp::ChromiumCDMParent::RecvOnSessionMessage",
                            [proxy, sid, messageType, msg]() mutable {
                              proxy->OnSessionMessage(sid, messageType, msg);
-                           }));
+                           }),
+    NS_DISPATCH_NORMAL);
   return IPC_OK();
 }
 
 static dom::MediaKeyStatus
 ToDOMMediaKeyStatus(uint32_t aStatus)
 {
   switch (static_cast<cdm::KeyStatus>(aStatus)) {
     case cdm::kUsable:
@@ -481,78 +495,86 @@ ChromiumCDMParent::RecvOnSessionKeysChan
       keyStatusesChange |=
         caps.SetKeyStatus(aKeysInfo[i].mKeyId(),
                           NS_ConvertUTF8toUTF16(aSessionId),
                           dom::Optional<dom::MediaKeyStatus>(
                             ToDOMMediaKeyStatus(aKeysInfo[i].mStatus())));
     }
   }
   if (keyStatusesChange) {
-    NS_DispatchToMainThread(
+    mMainThread->Dispatch(
       NewRunnableMethod<nsString>("ChromiumCDMProxy::OnKeyStatusesChange",
                                   mProxy,
                                   &ChromiumCDMProxy::OnKeyStatusesChange,
-                                  NS_ConvertUTF8toUTF16(aSessionId)));
+                                  NS_ConvertUTF8toUTF16(aSessionId)),
+      NS_DISPATCH_NORMAL);
   }
   return IPC_OK();
 }
 
 ipc::IPCResult
 ChromiumCDMParent::RecvOnExpirationChange(const nsCString& aSessionId,
                                           const double& aSecondsSinceEpoch)
 {
   GMP_LOG("ChromiumCDMParent::RecvOnExpirationChange(this=%p) time=%lf",
           this,
           aSecondsSinceEpoch);
   if (!mProxy || mIsShutdown) {
     return IPC_OK();
   }
-  NS_DispatchToMainThread(NewRunnableMethod<nsString, UnixTime>(
-    "ChromiumCDMProxy::OnExpirationChange",
-    mProxy,
-    &ChromiumCDMProxy::OnExpirationChange,
-    NS_ConvertUTF8toUTF16(aSessionId),
-    GMPTimestamp(aSecondsSinceEpoch * 1000)));
+
+  mMainThread->Dispatch(
+    NewRunnableMethod<nsString, UnixTime>(
+      "ChromiumCDMProxy::OnExpirationChange",
+      mProxy,
+      &ChromiumCDMProxy::OnExpirationChange,
+      NS_ConvertUTF8toUTF16(aSessionId),
+      GMPTimestamp(aSecondsSinceEpoch * 1000)),
+    NS_DISPATCH_NORMAL);
   return IPC_OK();
 }
 
 ipc::IPCResult
 ChromiumCDMParent::RecvOnSessionClosed(const nsCString& aSessionId)
 {
   GMP_LOG("ChromiumCDMParent::RecvOnSessionClosed(this=%p)", this);
   if (!mProxy || mIsShutdown) {
     return IPC_OK();
   }
-  NS_DispatchToMainThread(
+
+  mMainThread->Dispatch(
     NewRunnableMethod<nsString>("ChromiumCDMProxy::OnSessionClosed",
                                 mProxy,
                                 &ChromiumCDMProxy::OnSessionClosed,
-                                NS_ConvertUTF8toUTF16(aSessionId)));
+                                NS_ConvertUTF8toUTF16(aSessionId)),
+    NS_DISPATCH_NORMAL);
   return IPC_OK();
 }
 
 ipc::IPCResult
 ChromiumCDMParent::RecvOnLegacySessionError(const nsCString& aSessionId,
                                             const uint32_t& aError,
                                             const uint32_t& aSystemCode,
                                             const nsCString& aMessage)
 {
   GMP_LOG("ChromiumCDMParent::RecvOnLegacySessionError(this=%p)", this);
   if (!mProxy || mIsShutdown) {
     return IPC_OK();
   }
-  NS_DispatchToMainThread(
+
+  mMainThread->Dispatch(
     NewRunnableMethod<nsString, nsresult, uint32_t, nsString>(
       "ChromiumCDMProxy::OnSessionError",
       mProxy,
       &ChromiumCDMProxy::OnSessionError,
       NS_ConvertUTF8toUTF16(aSessionId),
       ToNsresult(aError),
       aSystemCode,
-      NS_ConvertUTF8toUTF16(aMessage)));
+      NS_ConvertUTF8toUTF16(aMessage)),
+    NS_DISPATCH_NORMAL);
   return IPC_OK();
 }
 
 DecryptStatus
 ToDecryptStatus(uint32_t aError)
 {
   switch (static_cast<cdm::Status>(aError)) {
     case cdm::kSuccess:
@@ -922,19 +944,22 @@ ChromiumCDMParent::ActorDestroy(ActorDes
   MOZ_ASSERT(mIsShutdown);
   RefPtr<ChromiumCDMParent> kungFuDeathGrip(this);
   if (mContentParent) {
     mContentParent->ChromiumCDMDestroyed(this);
     mContentParent = nullptr;
   }
   bool abnormalShutdown = (aWhy == AbnormalShutdown);
   if (abnormalShutdown && proxy) {
-    RefPtr<Runnable> task = NewRunnableMethod(
-      "ChromiumCDMProxy::Terminated", proxy, &ChromiumCDMProxy::Terminated);
-    NS_DispatchToMainThread(task);
+    mMainThread->Dispatch(
+      NewRunnableMethod(
+        "ChromiumCDMProxy::Terminated",
+        proxy,
+        &ChromiumCDMProxy::Terminated),
+      NS_DISPATCH_NORMAL);
   }
   MaybeDisconnect(abnormalShutdown);
 }
 
 RefPtr<MediaDataDecoder::InitPromise>
 ChromiumCDMParent::InitializeVideoDecoder(
   const gmp::CDMVideoDecoderConfig& aConfig,
   const VideoInfo& aInfo,
@@ -1161,19 +1186,22 @@ ChromiumCDMParent::Shutdown()
   mIsShutdown = true;
 
   // If we're shutting down due to the plugin shutting down due to application
   // shutdown, we should tell the CDM proxy to also shutdown. Otherwise the
   // proxy will shutdown when the owning MediaKeys is destroyed during cycle
   // collection, and that will not shut down cleanly as the GMP thread will be
   // shutdown by then.
   if (mProxy) {
-    RefPtr<Runnable> task = NewRunnableMethod(
-      "ChromiumCDMProxy::Shutdown", mProxy, &ChromiumCDMProxy::Shutdown);
-    NS_DispatchToMainThread(task.forget());
+    mMainThread->Dispatch(
+      NewRunnableMethod(
+        "ChromiumCDMProxy::Shutdown",
+        mProxy,
+        &ChromiumCDMProxy::Shutdown),
+      NS_DISPATCH_NORMAL);
   }
 
   // We may be called from a task holding the last reference to the proxy, so
   // let's clear our local weak pointer to ensure it will not be used afterward
   // (including from an already-queued task, e.g.: ActorDestroy).
   mProxy = nullptr;
 
   mReorderQueue.Clear();
@@ -1206,8 +1234,10 @@ ChromiumCDMParent::Shutdown()
 
   if (!mActorDestroyed) {
     Unused << SendDestroy();
   }
 }
 
 } // namespace gmp
 } // namespace mozilla
+
+#undef NS_DispatchToMainThread
--- a/dom/media/gmp/ChromiumCDMParent.h
+++ b/dom/media/gmp/ChromiumCDMParent.h
@@ -35,17 +35,18 @@ public:
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(ChromiumCDMParent)
 
   ChromiumCDMParent(GMPContentParent* aContentParent, uint32_t aPluginId);
 
   uint32_t PluginId() const { return mPluginId; }
 
   bool Init(ChromiumCDMProxy* aProxy,
             bool aAllowDistinctiveIdentifier,
-            bool aAllowPersistentState);
+            bool aAllowPersistentState,
+            nsIEventTarget* aMainThread);
 
   void CreateSession(uint32_t aCreateSessionToken,
                      uint32_t aSessionType,
                      uint32_t aInitDataType,
                      uint32_t aPromiseId,
                      const nsTArray<uint8_t>& aInitData);
 
   void LoadSession(uint32_t aPromiseId,
@@ -180,14 +181,17 @@ protected:
   // The H.264 decoder in Widevine CDM versions 970 and later output in decode
   // order rather than presentation order, so we reorder in presentation order
   // before presenting. mMaxRefFrames is non-zero if we have an initialized
   // decoder and we are decoding H.264. If so, it stores the maximum length of
   // the reorder queue that we need. Note we may have multiple decoders for the
   // life time of this object, but never more than one active at once.
   uint32_t mMaxRefFrames = 0;
   ReorderQueue mReorderQueue;
+
+  // The main thread associated with the root document. Must be set in Init().
+    nsCOMPtr<nsIEventTarget> mMainThread;
 };
 
 } // namespace gmp
 } // namespace mozilla
 
 #endif // ChromiumCDMParent_h_
--- a/dom/media/gmp/ChromiumCDMProxy.cpp
+++ b/dom/media/gmp/ChromiumCDMProxy.cpp
@@ -93,17 +93,18 @@ ChromiumCDMProxy::Init(PromiseId aPromis
       RefPtr<gmp::GetCDMParentPromise> promise =
         service->GetCDM(nodeId, { keySystem }, helper);
       promise->Then(
         thread,
         __func__,
         [self, aPromiseId](RefPtr<gmp::ChromiumCDMParent> cdm) {
           if (!cdm->Init(self,
                          self->mDistinctiveIdentifierRequired,
-                         self->mPersistentStateRequired)) {
+                         self->mPersistentStateRequired,
+                         self->mMainThread)) {
             self->RejectPromise(aPromiseId,
                                 NS_ERROR_FAILURE,
                                 NS_LITERAL_CSTRING("GetCDM failed."));
             return;
           }
           {
             MutexAutoLock lock(self->mCDMMutex);
             self->mCDM = cdm;