Bug 1284192 - Make CDMProxy be a base class and move the logic into subclass. r=cpearce
authorJames Cheng <jacheng@mozilla.com>
Mon, 18 Jul 2016 22:13:00 +0200
changeset 305719 813a61c61c6ce325f60801b2c6cc377e1801fd59
parent 305718 564fdbb916ba41e6186031ac633f733d5405ed92
child 305720 340f2259b820df20fe88a489763c9f82eb4918b0
push id30467
push usercbook@mozilla.com
push dateWed, 20 Jul 2016 09:21:53 +0000
treeherdermozilla-central@e904e18d7dfc [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerscpearce
bugs1284192
milestone50.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1284192 - Make CDMProxy be a base class and move the logic into subclass. r=cpearce MozReview-Commit-ID: 4Lr3uqVexFD
dom/media/eme/CDMProxy.cpp
dom/media/eme/CDMProxy.h
dom/media/eme/MediaKeys.cpp
dom/media/eme/moz.build
dom/media/gmp/GMPCDMCallbackProxy.cpp
dom/media/gmp/GMPCDMCallbackProxy.h
dom/media/gmp/GMPCDMProxy.cpp
dom/media/gmp/GMPCDMProxy.h
dom/media/gmp/moz.build
--- a/dom/media/eme/CDMProxy.h
+++ b/dom/media/eme/CDMProxy.h
@@ -3,302 +3,187 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef CDMProxy_h_
 #define CDMProxy_h_
 
 #include "mozilla/CDMCaps.h"
-#include "mozilla/Monitor.h"
 #include "mozilla/MozPromise.h"
 
+#include "mozilla/dom/MediaKeyMessageEvent.h"
 #include "mozilla/dom/MediaKeys.h"
 
 #include "nsIThread.h"
-#include "nsString.h"
-#include "nsAutoPtr.h"
-#include "GMPDecryptorProxy.h"
 
 namespace mozilla {
 class MediaRawData;
-class GMPCDMCallbackProxy;
-
-namespace dom {
-class MediaKeySession;
-} // namespace dom
 
 struct DecryptResult {
   DecryptResult(GMPErr aStatus, MediaRawData* aSample)
     : mStatus(aStatus)
     , mSample(aSample)
   {}
   GMPErr mStatus;
   RefPtr<MediaRawData> mSample;
 };
 
-// Proxies calls GMP/CDM, and proxies calls back.
+// Proxies calls CDM, and proxies calls back.
 // Note: Promises are passed in via a PromiseId, so that the ID can be
 // passed via IPC to the CDM, which can then signal when to reject or
 // resolve the promise using its PromiseId.
 class CDMProxy {
+protected:
   typedef dom::PromiseId PromiseId;
   typedef dom::SessionType SessionType;
 public:
 
-  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CDMProxy)
+  NS_IMETHOD_(MozExternalRefCountType) AddRef(void) = 0;
+  NS_IMETHOD_(MozExternalRefCountType) Release(void) = 0;
 
   typedef MozPromise<DecryptResult, DecryptResult, /* IsExclusive = */ true> DecryptPromise;
 
   // Main thread only.
-  CDMProxy(dom::MediaKeys* aKeys, const nsAString& aKeySystem);
+  CDMProxy(dom::MediaKeys* aKeys, const nsAString& aKeySystem)
+  : mKeys(aKeys), mKeySystem(aKeySystem)
+  {}
 
   // Main thread only.
   // Loads the CDM corresponding to mKeySystem.
   // Calls MediaKeys::OnCDMCreated() when the CDM is created.
-  void Init(PromiseId aPromiseId,
-            const nsAString& aOrigin,
-            const nsAString& aTopLevelOrigin,
-            const nsAString& aGMPName,
-            bool aInPrivateBrowsing,
-            GMPCrashHelper* aHelper);
+  virtual void Init(PromiseId aPromiseId,
+                    const nsAString& aOrigin,
+                    const nsAString& aTopLevelOrigin,
+                    const nsAString& aName,
+                    bool aInPrivateBrowsing) = 0;
 
   // Main thread only.
   // Uses the CDM to create a key session.
   // Calls MediaKeys::OnSessionActivated() when session is created.
   // Assumes ownership of (Move()s) aInitData's contents.
-  void CreateSession(uint32_t aCreateSessionToken,
-                     dom::SessionType aSessionType,
-                     PromiseId aPromiseId,
-                     const nsAString& aInitDataType,
-                     nsTArray<uint8_t>& aInitData);
+  virtual void CreateSession(uint32_t aCreateSessionToken,
+                             dom::SessionType aSessionType,
+                             PromiseId aPromiseId,
+                             const nsAString& aInitDataType,
+                             nsTArray<uint8_t>& aInitData) = 0;
 
   // Main thread only.
   // Uses the CDM to load a presistent session stored on disk.
   // Calls MediaKeys::OnSessionActivated() when session is loaded.
-  void LoadSession(PromiseId aPromiseId,
-                   const nsAString& aSessionId);
+  virtual void LoadSession(PromiseId aPromiseId,
+                           const nsAString& aSessionId) = 0;
 
   // Main thread only.
   // Sends a new certificate to the CDM.
   // Calls MediaKeys->ResolvePromise(aPromiseId) after the CDM has
   // processed the request.
   // Assumes ownership of (Move()s) aCert's contents.
-  void SetServerCertificate(PromiseId aPromiseId,
-                            nsTArray<uint8_t>& aCert);
+  virtual void SetServerCertificate(PromiseId aPromiseId,
+                                    nsTArray<uint8_t>& aCert) = 0;
 
   // Main thread only.
   // Sends an update to the CDM.
   // Calls MediaKeys->ResolvePromise(aPromiseId) after the CDM has
   // processed the request.
   // Assumes ownership of (Move()s) aResponse's contents.
-  void UpdateSession(const nsAString& aSessionId,
-                     PromiseId aPromiseId,
-                     nsTArray<uint8_t>& aResponse);
+  virtual void UpdateSession(const nsAString& aSessionId,
+                             PromiseId aPromiseId,
+                             nsTArray<uint8_t>& aResponse) = 0;
 
   // Main thread only.
   // Calls MediaKeys->ResolvePromise(aPromiseId) after the CDM has
   // processed the request.
   // If processing this operation results in the session actually closing,
   // we also call MediaKeySession::OnClosed(), which in turn calls
   // MediaKeys::OnSessionClosed().
-  void CloseSession(const nsAString& aSessionId,
-                    PromiseId aPromiseId);
+  virtual void CloseSession(const nsAString& aSessionId,
+                            PromiseId aPromiseId) = 0;
 
   // Main thread only.
   // Removes all data for a persisent session.
   // Calls MediaKeys->ResolvePromise(aPromiseId) after the CDM has
   // processed the request.
-  void RemoveSession(const nsAString& aSessionId,
-                     PromiseId aPromiseId);
+  virtual void RemoveSession(const nsAString& aSessionId,
+                             PromiseId aPromiseId) = 0;
 
   // Main thread only.
-  void Shutdown();
+  virtual void Shutdown() = 0;
 
   // Main thread only.
-  void Terminated();
+  virtual void Terminated() = 0;
 
   // Threadsafe.
-  const nsCString& GetNodeId() const;
+  virtual const nsCString& GetNodeId() const = 0;
 
   // Main thread only.
-  void OnSetSessionId(uint32_t aCreateSessionToken,
-                      const nsAString& aSessionId);
+  virtual void OnSetSessionId(uint32_t aCreateSessionToken,
+                              const nsAString& aSessionId) = 0;
 
   // Main thread only.
-  void OnResolveLoadSessionPromise(uint32_t aPromiseId, bool aSuccess);
+  virtual void OnResolveLoadSessionPromise(uint32_t aPromiseId,
+                                           bool aSuccess) = 0;
 
   // Main thread only.
-  void OnSessionMessage(const nsAString& aSessionId,
-                        GMPSessionMessageType aMessageType,
-                        nsTArray<uint8_t>& aMessage);
+  virtual void OnSessionMessage(const nsAString& aSessionId,
+                                dom::MediaKeyMessageType aMessageType,
+                                nsTArray<uint8_t>& aMessage) = 0;
 
   // Main thread only.
-  void OnExpirationChange(const nsAString& aSessionId,
-                          GMPTimestamp aExpiryTime);
+  virtual void OnExpirationChange(const nsAString& aSessionId,
+                                  int64_t aExpiryTime) = 0;
 
   // Main thread only.
-  void OnSessionClosed(const nsAString& aSessionId);
+  virtual void OnSessionClosed(const nsAString& aSessionId) = 0;
 
   // Main thread only.
-  void OnSessionError(const nsAString& aSessionId,
-                      nsresult aException,
-                      uint32_t aSystemCode,
-                      const nsAString& aMsg);
+  virtual void OnSessionError(const nsAString& aSessionId,
+                              nsresult aException,
+                              uint32_t aSystemCode,
+                              const nsAString& aMsg) = 0;
 
   // Main thread only.
-  void OnRejectPromise(uint32_t aPromiseId,
-                       nsresult aDOMException,
-                       const nsCString& aMsg);
+  virtual void OnRejectPromise(uint32_t aPromiseId,
+                               nsresult aDOMException,
+                               const nsCString& aMsg) = 0;
 
-  RefPtr<DecryptPromise> Decrypt(MediaRawData* aSample);
+  virtual RefPtr<DecryptPromise> Decrypt(MediaRawData* aSample) = 0;
+
+  // Owner thread only.
+  virtual void OnDecrypted(uint32_t aId,
+                           GMPErr aResult,
+                           const nsTArray<uint8_t>& aDecryptedData) = 0;
 
   // Reject promise with DOMException corresponding to aExceptionCode.
   // Can be called from any thread.
-  void RejectPromise(PromiseId aId, nsresult aExceptionCode,
-                     const nsCString& aReason);
+  virtual void RejectPromise(PromiseId aId,
+                             nsresult aExceptionCode,
+                             const nsCString& aReason) = 0;
 
   // Resolves promise with "undefined".
   // Can be called from any thread.
-  void ResolvePromise(PromiseId aId);
+  virtual void ResolvePromise(PromiseId aId) = 0;
 
   // Threadsafe.
-  const nsString& KeySystem() const;
-
-  // GMP thread only.
-  void gmp_Decrypted(uint32_t aId,
-                     GMPErr aResult,
-                     const nsTArray<uint8_t>& aDecryptedData);
-
-  CDMCaps& Capabilites();
-
-  // Main thread only.
-  void OnKeyStatusesChange(const nsAString& aSessionId);
-
-  void GetSessionIdsForKeyId(const nsTArray<uint8_t>& aKeyId,
-                             nsTArray<nsCString>& aSessionIds);
-
-#ifdef DEBUG
-  bool IsOnGMPThread();
-#endif
+  virtual const nsString& KeySystem() const = 0;
 
-private:
-  friend class gmp_InitDoneCallback;
-  friend class gmp_InitGetGMPDecryptorCallback;
-
-  struct InitData {
-    uint32_t mPromiseId;
-    nsString mOrigin;
-    nsString mTopLevelOrigin;
-    nsString mGMPName;
-    RefPtr<GMPCrashHelper> mCrashHelper;
-    bool mInPrivateBrowsing;
-  };
-
-  // GMP thread only.
-  void gmp_Init(nsAutoPtr<InitData>&& aData);
-  void gmp_InitDone(GMPDecryptorProxy* aCDM, nsAutoPtr<InitData>&& aData);
-  void gmp_InitGetGMPDecryptor(nsresult aResult,
-                               const nsACString& aNodeId,
-                               nsAutoPtr<InitData>&& aData);
-
-  // GMP thread only.
-  void gmp_Shutdown();
+  virtual  CDMCaps& Capabilites() = 0;
 
   // Main thread only.
-  void OnCDMCreated(uint32_t aPromiseId);
-
-  struct CreateSessionData {
-    dom::SessionType mSessionType;
-    uint32_t mCreateSessionToken;
-    PromiseId mPromiseId;
-    nsCString mInitDataType;
-    nsTArray<uint8_t> mInitData;
-  };
-  // GMP thread only.
-  void gmp_CreateSession(nsAutoPtr<CreateSessionData> aData);
-
-  struct SessionOpData {
-    PromiseId mPromiseId;
-    nsCString mSessionId;
-  };
-  // GMP thread only.
-  void gmp_LoadSession(nsAutoPtr<SessionOpData> aData);
+  virtual void OnKeyStatusesChange(const nsAString& aSessionId) = 0;
 
-  struct SetServerCertificateData {
-    PromiseId mPromiseId;
-    nsTArray<uint8_t> mCert;
-  };
-  // GMP thread only.
-  void gmp_SetServerCertificate(nsAutoPtr<SetServerCertificateData> aData);
-
-  struct UpdateSessionData {
-    PromiseId mPromiseId;
-    nsCString mSessionId;
-    nsTArray<uint8_t> mResponse;
-  };
-  // GMP thread only.
-  void gmp_UpdateSession(nsAutoPtr<UpdateSessionData> aData);
-
-  // GMP thread only.
-  void gmp_CloseSession(nsAutoPtr<SessionOpData> aData);
-
-  // GMP thread only.
-  void gmp_RemoveSession(nsAutoPtr<SessionOpData> aData);
-
-  class DecryptJob {
-  public:
-    NS_INLINE_DECL_THREADSAFE_REFCOUNTING(DecryptJob)
+  virtual void GetSessionIdsForKeyId(const nsTArray<uint8_t>& aKeyId,
+                                     nsTArray<nsCString>& aSessionIds) = 0;
 
-    explicit DecryptJob(MediaRawData* aSample)
-      : mId(0)
-      , mSample(aSample)
-    {
-    }
-
-    void PostResult(GMPErr aResult, const nsTArray<uint8_t>& aDecryptedData);
-    void PostResult(GMPErr aResult);
-
-    RefPtr<DecryptPromise> Ensure() {
-      return mPromise.Ensure(__func__);
-    }
-
-    uint32_t mId;
-    RefPtr<MediaRawData> mSample;
-  private:
-    ~DecryptJob() {}
-    MozPromiseHolder<DecryptPromise> mPromise;
-  };
-  // GMP thread only.
-  void gmp_Decrypt(RefPtr<DecryptJob> aJob);
+#ifdef DEBUG
+  virtual bool IsOnOwnerThread() = 0;
+#endif
 
-  class RejectPromiseTask : public Runnable {
-  public:
-    RejectPromiseTask(CDMProxy* aProxy,
-                      PromiseId aId,
-                      nsresult aCode,
-                      const nsCString& aReason)
-      : mProxy(aProxy)
-      , mId(aId)
-      , mCode(aCode)
-      , mReason(aReason)
-    {
-    }
-    NS_METHOD Run() {
-      mProxy->RejectPromise(mId, mCode, mReason);
-      return NS_OK;
-    }
-  private:
-    RefPtr<CDMProxy> mProxy;
-    PromiseId mId;
-    nsresult mCode;
-    nsCString mReason;
-  };
-
-  ~CDMProxy();
+protected:
+  virtual ~CDMProxy() {}
 
   // Helper to enforce that a raw pointer is only accessed on the main thread.
   template<class Type>
   class MainThreadOnlyRawPtr {
   public:
     explicit MainThreadOnlyRawPtr(Type* aPtr)
       : mPtr(aPtr)
     {
@@ -325,38 +210,21 @@ private:
 
   // Our reference back to the MediaKeys object.
   // WARNING: This is a non-owning reference that is cleared by MediaKeys
   // destructor. only use on main thread, and always nullcheck before using!
   MainThreadOnlyRawPtr<dom::MediaKeys> mKeys;
 
   const nsString mKeySystem;
 
-  // Gecko Media Plugin thread. All interactions with the out-of-process
-  // EME plugin must come from this thread.
-  RefPtr<nsIThread> mGMPThread;
+  // Onwer specified thread. e.g. Gecko Media Plugin thread.
+  // All interactions with the out-of-process EME plugin must come from this thread.
+  RefPtr<nsIThread> mOwnerThread;
 
   nsCString mNodeId;
 
-  GMPDecryptorProxy* mCDM;
   CDMCaps mCapabilites;
-  nsAutoPtr<GMPCDMCallbackProxy> mCallback;
-
-  // Decryption jobs sent to CDM, awaiting result.
-  // GMP thread only.
-  nsTArray<RefPtr<DecryptJob>> mDecryptionJobs;
-
-  // Number of buffers we've decrypted. Used to uniquely identify
-  // decryption jobs sent to CDM. Note we can't just use the length of
-  // mDecryptionJobs as that shrinks as jobs are completed and removed
-  // from it.
-  // GMP thread only.
-  uint32_t mDecryptionJobCount;
-
-  // True if CDMProxy::gmp_Shutdown was called.
-  // GMP thread only.
-  bool mShutdownCalled;
 };
 
 
 } // namespace mozilla
 
 #endif // CDMProxy_h_
--- a/dom/media/eme/MediaKeys.cpp
+++ b/dom/media/eme/MediaKeys.cpp
@@ -8,17 +8,17 @@
 #include "GMPService.h"
 #include "mozilla/dom/HTMLMediaElement.h"
 #include "mozilla/dom/MediaKeysBinding.h"
 #include "mozilla/dom/MediaKeyMessageEvent.h"
 #include "mozilla/dom/MediaKeyError.h"
 #include "mozilla/dom/MediaKeySession.h"
 #include "mozilla/dom/DOMException.h"
 #include "mozilla/dom/UnionTypes.h"
-#include "mozilla/CDMProxy.h"
+#include "GMPCDMProxy.h"
 #include "mozilla/EMEUtils.h"
 #include "nsContentUtils.h"
 #include "nsIScriptObjectPrincipal.h"
 #include "nsContentTypeParser.h"
 #ifdef MOZ_FMP4
 #include "MP4Decoder.h"
 #endif
 #ifdef XP_WIN
@@ -308,17 +308,17 @@ already_AddRefed<DetailedPromise>
 MediaKeys::Init(ErrorResult& aRv)
 {
   RefPtr<DetailedPromise> promise(MakePromise(aRv,
     NS_LITERAL_CSTRING("MediaKeys::Init()")));
   if (aRv.Failed()) {
     return nullptr;
   }
 
-  mProxy = new CDMProxy(this, mKeySystem);
+  mProxy = new GMPCDMProxy(this, mKeySystem, new MediaKeysGMPCrashHelper(this));
 
   // Determine principal (at creation time) of the MediaKeys object.
   nsCOMPtr<nsIScriptObjectPrincipal> sop = do_QueryInterface(GetParentObject());
   if (!sop) {
     promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR,
                          NS_LITERAL_CSTRING("Couldn't get script principal in MediaKeys::Init"));
     return promise.forget();
   }
@@ -382,18 +382,17 @@ MediaKeys::Init(ErrorResult& aRv)
   // rejected.
   MOZ_ASSERT(!mCreatePromiseId, "Should only be created once!");
   mCreatePromiseId = StorePromise(promise);
   AddRef();
   mProxy->Init(mCreatePromiseId,
                origin,
                topLevelOrigin,
                KeySystemToGMPName(mKeySystem),
-               inPrivateBrowsing,
-               new MediaKeysGMPCrashHelper(this));
+               inPrivateBrowsing);
 
   return promise.forget();
 }
 
 void
 MediaKeys::OnCDMCreated(PromiseId aId, const nsACString& aNodeId, const uint32_t aPluginId)
 {
   RefPtr<DetailedPromise> promise(RetrievePromise(aId));
--- a/dom/media/eme/moz.build
+++ b/dom/media/eme/moz.build
@@ -19,17 +19,16 @@ EXPORTS.mozilla += [
     'CDMCaps.h',
     'CDMProxy.h',
     'DetailedPromise.h',
     'EMEUtils.h',
 ]
 
 UNIFIED_SOURCES += [
     'CDMCaps.cpp',
-    'CDMProxy.cpp',
     'DetailedPromise.cpp',
     'EMEUtils.cpp',
     'MediaEncryptedEvent.cpp',
     'MediaKeyError.cpp',
     'MediaKeyMessageEvent.cpp',
     'MediaKeys.cpp',
     'MediaKeySession.cpp',
     'MediaKeyStatusMap.cpp',
--- a/dom/media/gmp/GMPCDMCallbackProxy.cpp
+++ b/dom/media/gmp/GMPCDMCallbackProxy.cpp
@@ -43,17 +43,17 @@ public:
   uint32_t mToken;
   nsString mSid;
 };
 
 void
 GMPCDMCallbackProxy::SetSessionId(uint32_t aToken,
                                   const nsCString& aSessionId)
 {
-  MOZ_ASSERT(mProxy->IsOnGMPThread());
+  MOZ_ASSERT(mProxy->IsOnOwnerThread());
 
   nsCOMPtr<nsIRunnable> task(new SetSessionIdTask(mProxy,
                                                   aToken,
                                                   aSessionId));
   NS_DispatchToMainThread(task);
 }
 
 class LoadSessionTask : public Runnable {
@@ -76,28 +76,28 @@ public:
   dom::PromiseId mPid;
   bool mSuccess;
 };
 
 void
 GMPCDMCallbackProxy::ResolveLoadSessionPromise(uint32_t aPromiseId,
                                                bool aSuccess)
 {
-  MOZ_ASSERT(mProxy->IsOnGMPThread());
+  MOZ_ASSERT(mProxy->IsOnOwnerThread());
 
   nsCOMPtr<nsIRunnable> task(new LoadSessionTask(mProxy,
                                                  aPromiseId,
                                                  aSuccess));
   NS_DispatchToMainThread(task);
 }
 
 void
 GMPCDMCallbackProxy::ResolvePromise(uint32_t aPromiseId)
 {
-  MOZ_ASSERT(mProxy->IsOnGMPThread());
+  MOZ_ASSERT(mProxy->IsOnOwnerThread());
 
   // Note: CDMProxy proxies this from non-main threads to main thread.
   mProxy->ResolvePromise(aPromiseId);
 }
 
 class RejectPromiseTask : public Runnable {
 public:
   RejectPromiseTask(CDMProxy* aProxy,
@@ -123,57 +123,68 @@ public:
 };
 
 
 void
 GMPCDMCallbackProxy::RejectPromise(uint32_t aPromiseId,
                                    nsresult aException,
                                    const nsCString& aMessage)
 {
-  MOZ_ASSERT(mProxy->IsOnGMPThread());
+  MOZ_ASSERT(mProxy->IsOnOwnerThread());
 
   nsCOMPtr<nsIRunnable> task;
   task = new RejectPromiseTask(mProxy,
                                aPromiseId,
                                aException,
                                aMessage);
   NS_DispatchToMainThread(task);
 }
 
+static dom::MediaKeyMessageType
+ToMediaKeyMessageType(GMPSessionMessageType aMessageType) {
+  switch (aMessageType) {
+    case kGMPLicenseRequest: return dom::MediaKeyMessageType::License_request;
+    case kGMPLicenseRenewal: return dom::MediaKeyMessageType::License_renewal;
+    case kGMPLicenseRelease: return dom::MediaKeyMessageType::License_release;
+    case kGMPIndividualizationRequest: return dom::MediaKeyMessageType::Individualization_request;
+    default: return dom::MediaKeyMessageType::License_request;
+  };
+};
+
 class SessionMessageTask : public Runnable {
 public:
   SessionMessageTask(CDMProxy* aProxy,
                      const nsCString& aSessionId,
                      GMPSessionMessageType aMessageType,
                      const nsTArray<uint8_t>& aMessage)
     : mProxy(aProxy)
     , mSid(NS_ConvertUTF8toUTF16(aSessionId))
     , mMsgType(aMessageType)
   {
     mMsg.AppendElements(aMessage);
   }
 
   NS_IMETHOD Run() {
-    mProxy->OnSessionMessage(mSid, mMsgType, mMsg);
+    mProxy->OnSessionMessage(mSid, ToMediaKeyMessageType(mMsgType), mMsg);
     return NS_OK;
   }
 
   RefPtr<CDMProxy> mProxy;
   dom::PromiseId mPid;
   nsString mSid;
   GMPSessionMessageType mMsgType;
   nsTArray<uint8_t> mMsg;
 };
 
 void
 GMPCDMCallbackProxy::SessionMessage(const nsCString& aSessionId,
                                     GMPSessionMessageType aMessageType,
                                     const nsTArray<uint8_t>& aMessage)
 {
-  MOZ_ASSERT(mProxy->IsOnGMPThread());
+  MOZ_ASSERT(mProxy->IsOnOwnerThread());
 
   nsCOMPtr<nsIRunnable> task;
   task = new SessionMessageTask(mProxy,
                                 aSessionId,
                                 aMessageType,
                                 aMessage);
   NS_DispatchToMainThread(task);
 }
@@ -197,29 +208,29 @@ public:
   nsString mSid;
   GMPTimestamp mTimestamp;
 };
 
 void
 GMPCDMCallbackProxy::ExpirationChange(const nsCString& aSessionId,
                                       GMPTimestamp aExpiryTime)
 {
-  MOZ_ASSERT(mProxy->IsOnGMPThread());
+  MOZ_ASSERT(mProxy->IsOnOwnerThread());
 
   nsCOMPtr<nsIRunnable> task;
   task = new ExpirationChangeTask(mProxy,
                                   aSessionId,
                                   aExpiryTime);
   NS_DispatchToMainThread(task);
 }
 
 void
 GMPCDMCallbackProxy::SessionClosed(const nsCString& aSessionId)
 {
-  MOZ_ASSERT(mProxy->IsOnGMPThread());
+  MOZ_ASSERT(mProxy->IsOnOwnerThread());
 
   bool keyStatusesChange = false;
   {
     CDMCaps::AutoLock caps(mProxy->Capabilites());
     keyStatusesChange = caps.RemoveKeysForSession(NS_ConvertUTF8toUTF16(aSessionId));
   }
   if (keyStatusesChange) {
     nsCOMPtr<nsIRunnable> task;
@@ -264,33 +275,33 @@ public:
 };
 
 void
 GMPCDMCallbackProxy::SessionError(const nsCString& aSessionId,
                                   nsresult aException,
                                   uint32_t aSystemCode,
                                   const nsCString& aMessage)
 {
-  MOZ_ASSERT(mProxy->IsOnGMPThread());
+  MOZ_ASSERT(mProxy->IsOnOwnerThread());
 
   nsCOMPtr<nsIRunnable> task;
   task = new SessionErrorTask(mProxy,
                               aSessionId,
                               aException,
                               aSystemCode,
                               aMessage);
   NS_DispatchToMainThread(task);
 }
 
 void
 GMPCDMCallbackProxy::KeyStatusChanged(const nsCString& aSessionId,
                                       const nsTArray<uint8_t>& aKeyId,
                                       GMPMediaKeyStatus aStatus)
 {
-  MOZ_ASSERT(mProxy->IsOnGMPThread());
+  MOZ_ASSERT(mProxy->IsOnOwnerThread());
 
   bool keyStatusesChange = false;
   {
     CDMCaps::AutoLock caps(mProxy->Capabilites());
     keyStatusesChange = caps.SetKeyStatus(aKeyId,
                                           NS_ConvertUTF8toUTF16(aSessionId),
                                           aStatus);
   }
@@ -303,22 +314,22 @@ GMPCDMCallbackProxy::KeyStatusChanged(co
   }
 }
 
 void
 GMPCDMCallbackProxy::Decrypted(uint32_t aId,
                                GMPErr aResult,
                                const nsTArray<uint8_t>& aDecryptedData)
 {
-  MOZ_ASSERT(mProxy->IsOnGMPThread());
+  MOZ_ASSERT(mProxy->IsOnOwnerThread());
 
-  mProxy->gmp_Decrypted(aId, aResult, aDecryptedData);
+  mProxy->OnDecrypted(aId, aResult, aDecryptedData);
 }
 
 void
 GMPCDMCallbackProxy::Terminated()
 {
-  MOZ_ASSERT(mProxy->IsOnGMPThread());
+  MOZ_ASSERT(mProxy->IsOnOwnerThread());
   nsCOMPtr<nsIRunnable> task = NewRunnableMethod(mProxy, &CDMProxy::Terminated);
   NS_DispatchToMainThread(task);
 }
 
 } // namespace mozilla
--- a/dom/media/gmp/GMPCDMCallbackProxy.h
+++ b/dom/media/gmp/GMPCDMCallbackProxy.h
@@ -51,17 +51,17 @@ public:
                  GMPErr aResult,
                  const nsTArray<uint8_t>& aDecryptedData) override;
 
   void Terminated() override;
 
   ~GMPCDMCallbackProxy() {}
 
 private:
-  friend class CDMProxy;
+  friend class GMPCDMProxy;
   explicit GMPCDMCallbackProxy(CDMProxy* aProxy);
 
   // Warning: Weak ref.
   CDMProxy* mProxy;
 };
 
 } // namespace mozilla
 
rename from dom/media/eme/CDMProxy.cpp
rename to dom/media/gmp/GMPCDMProxy.cpp
--- a/dom/media/eme/CDMProxy.cpp
+++ b/dom/media/gmp/GMPCDMProxy.cpp
@@ -1,188 +1,191 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#include "mozilla/CDMProxy.h"
-#include "nsString.h"
+#include "GMPCDMProxy.h"
+#include "mozilla/EMEUtils.h"
+#include "mozilla/PodOperations.h"
+
 #include "mozilla/dom/MediaKeys.h"
 #include "mozilla/dom/MediaKeySession.h"
+
 #include "mozIGeckoMediaPluginService.h"
 #include "nsContentCID.h"
+#include "nsIConsoleService.h"
+#include "nsPrintfCString.h"
 #include "nsServiceManagerUtils.h"
-#include "MainThreadUtils.h"
-#include "mozilla/EMEUtils.h"
-#include "nsIConsoleService.h"
+#include "nsString.h"
 #include "prenv.h"
-#include "mozilla/PodOperations.h"
 #include "GMPCDMCallbackProxy.h"
+#include "GMPService.h"
+#include "MainThreadUtils.h"
 #include "MediaData.h"
-#include "nsPrintfCString.h"
-#include "GMPService.h"
 
 namespace mozilla {
 
-CDMProxy::CDMProxy(dom::MediaKeys* aKeys, const nsAString& aKeySystem)
-  : mKeys(aKeys)
-  , mKeySystem(aKeySystem)
+GMPCDMProxy::GMPCDMProxy(dom::MediaKeys* aKeys,
+                         const nsAString& aKeySystem,
+                         GMPCrashHelper* aCrashHelper)
+  : CDMProxy(aKeys, aKeySystem)
+  , mCrashHelper(aCrashHelper)
   , mCDM(nullptr)
   , mDecryptionJobCount(0)
   , mShutdownCalled(false)
 {
   MOZ_ASSERT(NS_IsMainThread());
-  MOZ_COUNT_CTOR(CDMProxy);
+  MOZ_COUNT_CTOR(GMPCDMProxy);
 }
 
-CDMProxy::~CDMProxy()
+GMPCDMProxy::~GMPCDMProxy()
 {
-  MOZ_COUNT_DTOR(CDMProxy);
+  MOZ_COUNT_DTOR(GMPCDMProxy);
 }
 
 void
-CDMProxy::Init(PromiseId aPromiseId,
-               const nsAString& aOrigin,
-               const nsAString& aTopLevelOrigin,
-               const nsAString& aGMPName,
-               bool aInPrivateBrowsing,
-               GMPCrashHelper* aCrashHelper)
+GMPCDMProxy::Init(PromiseId aPromiseId,
+                  const nsAString& aOrigin,
+                  const nsAString& aTopLevelOrigin,
+                  const nsAString& aGMPName,
+                  bool aInPrivateBrowsing)
 {
   MOZ_ASSERT(NS_IsMainThread());
   NS_ENSURE_TRUE_VOID(!mKeys.IsNull());
 
-  EME_LOG("CDMProxy::Init (%s, %s) %s",
+  EME_LOG("GMPCDMProxy::Init (%s, %s) %s",
           NS_ConvertUTF16toUTF8(aOrigin).get(),
           NS_ConvertUTF16toUTF8(aTopLevelOrigin).get(),
           (aInPrivateBrowsing ? "PrivateBrowsing" : "NonPrivateBrowsing"));
 
   nsCString pluginVersion;
-  if (!mGMPThread) {
+  if (!mOwnerThread) {
     nsCOMPtr<mozIGeckoMediaPluginService> mps =
       do_GetService("@mozilla.org/gecko-media-plugin-service;1");
     if (!mps) {
       RejectPromise(aPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
-                    NS_LITERAL_CSTRING("Couldn't get MediaPluginService in CDMProxy::Init"));
+                    NS_LITERAL_CSTRING("Couldn't get MediaPluginService in GMPCDMProxy::Init"));
       return;
     }
-    mps->GetThread(getter_AddRefs(mGMPThread));
-    if (!mGMPThread) {
+    mps->GetThread(getter_AddRefs(mOwnerThread));
+    if (!mOwnerThread) {
       RejectPromise(aPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
-                    NS_LITERAL_CSTRING("Couldn't get GMP thread CDMProxy::Init"));
+                    NS_LITERAL_CSTRING("Couldn't get GMP thread GMPCDMProxy::Init"));
       return;
     }
   }
 
   if (aGMPName.IsEmpty()) {
     RejectPromise(aPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
       nsPrintfCString("Unknown GMP for keysystem '%s'", NS_ConvertUTF16toUTF8(mKeySystem).get()));
     return;
   }
 
   nsAutoPtr<InitData> data(new InitData());
   data->mPromiseId = aPromiseId;
   data->mOrigin = aOrigin;
   data->mTopLevelOrigin = aTopLevelOrigin;
   data->mGMPName = aGMPName;
   data->mInPrivateBrowsing = aInPrivateBrowsing;
-  data->mCrashHelper = aCrashHelper;
+  data->mCrashHelper = mCrashHelper;
   nsCOMPtr<nsIRunnable> task(
     NewRunnableMethod<nsAutoPtr<InitData>>(this,
-                                           &CDMProxy::gmp_Init,
+                                           &GMPCDMProxy::gmp_Init,
                                            Move(data)));
-  mGMPThread->Dispatch(task, NS_DISPATCH_NORMAL);
+  mOwnerThread->Dispatch(task, NS_DISPATCH_NORMAL);
 }
 
 #ifdef DEBUG
 bool
-CDMProxy::IsOnGMPThread()
+GMPCDMProxy::IsOnOwnerThread()
 {
-  return NS_GetCurrentThread() == mGMPThread;
+  return NS_GetCurrentThread() == mOwnerThread;
 }
 #endif
 
 void
-CDMProxy::gmp_InitDone(GMPDecryptorProxy* aCDM, nsAutoPtr<InitData>&& aData)
+GMPCDMProxy::gmp_InitDone(GMPDecryptorProxy* aCDM, nsAutoPtr<InitData>&& aData)
 {
-  EME_LOG("CDMProxy::gmp_InitDone");
+  EME_LOG("GMPCDMProxy::gmp_InitDone");
   if (mShutdownCalled) {
     if (aCDM) {
       aCDM->Close();
     }
     RejectPromise(aData->mPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
-                  NS_LITERAL_CSTRING("CDMProxy was shut down before init could complete"));
+                  NS_LITERAL_CSTRING("GMPCDMProxy was shut down before init could complete"));
     return;
   }
   if (!aCDM) {
     RejectPromise(aData->mPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
                   NS_LITERAL_CSTRING("GetGMPDecryptor failed to return a CDM"));
     return;
   }
 
   mCDM = aCDM;
   mCallback = new GMPCDMCallbackProxy(this);
   mCDM->Init(mCallback);
   nsCOMPtr<nsIRunnable> task(
     NewRunnableMethod<uint32_t>(this,
-                                &CDMProxy::OnCDMCreated,
+                                &GMPCDMProxy::OnCDMCreated,
                                 aData->mPromiseId));
   NS_DispatchToMainThread(task);
 }
 
 class gmp_InitDoneCallback : public GetGMPDecryptorCallback
 {
 public:
-  gmp_InitDoneCallback(CDMProxy* aCDMProxy,
-                       nsAutoPtr<CDMProxy::InitData>&& aData)
-    : mCDMProxy(aCDMProxy),
+  gmp_InitDoneCallback(GMPCDMProxy* aGMPCDMProxy,
+                       nsAutoPtr<GMPCDMProxy::InitData>&& aData)
+    : mGMPCDMProxy(aGMPCDMProxy),
       mData(Move(aData))
   {
   }
 
   void Done(GMPDecryptorProxy* aCDM)
   {
-    mCDMProxy->gmp_InitDone(aCDM, Move(mData));
+    mGMPCDMProxy->gmp_InitDone(aCDM, Move(mData));
   }
 
 private:
-  RefPtr<CDMProxy> mCDMProxy;
-  nsAutoPtr<CDMProxy::InitData> mData;
+  RefPtr<GMPCDMProxy> mGMPCDMProxy;
+  nsAutoPtr<GMPCDMProxy::InitData> mData;
 };
 
 class gmp_InitGetGMPDecryptorCallback : public GetNodeIdCallback
 {
 public:
-  gmp_InitGetGMPDecryptorCallback(CDMProxy* aCDMProxy,
-                                  nsAutoPtr<CDMProxy::InitData>&& aData)
-    : mCDMProxy(aCDMProxy),
+  gmp_InitGetGMPDecryptorCallback(GMPCDMProxy* aGMPCDMProxy,
+                                  nsAutoPtr<GMPCDMProxy::InitData>&& aData)
+    : mGMPCDMProxy(aGMPCDMProxy),
       mData(aData)
   {
   }
 
   void Done(nsresult aResult, const nsACString& aNodeId)
   {
-    mCDMProxy->gmp_InitGetGMPDecryptor(aResult, aNodeId, Move(mData));
+    mGMPCDMProxy->gmp_InitGetGMPDecryptor(aResult, aNodeId, Move(mData));
   }
 
 private:
-  RefPtr<CDMProxy> mCDMProxy;
-  nsAutoPtr<CDMProxy::InitData> mData;
+  RefPtr<GMPCDMProxy> mGMPCDMProxy;
+  nsAutoPtr<GMPCDMProxy::InitData> mData;
 };
 
 void
-CDMProxy::gmp_Init(nsAutoPtr<InitData>&& aData)
+GMPCDMProxy::gmp_Init(nsAutoPtr<InitData>&& aData)
 {
-  MOZ_ASSERT(IsOnGMPThread());
+  MOZ_ASSERT(IsOnOwnerThread());
 
   nsCOMPtr<mozIGeckoMediaPluginService> mps =
     do_GetService("@mozilla.org/gecko-media-plugin-service;1");
   if (!mps) {
     RejectPromise(aData->mPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
-                  NS_LITERAL_CSTRING("Couldn't get MediaPluginService in CDMProxy::gmp_Init"));
+                  NS_LITERAL_CSTRING("Couldn't get MediaPluginService in GMPCDMProxy::gmp_Init"));
     return;
   }
 
   // Make a copy before we transfer ownership of aData to the
   // gmp_InitGetGMPDecryptorCallback.
   InitData data(*aData);
   UniquePtr<GetNodeIdCallback> callback(
     new gmp_InitGetGMPDecryptorCallback(this, Move(aData)));
@@ -193,39 +196,39 @@ CDMProxy::gmp_Init(nsAutoPtr<InitData>&&
                                Move(callback));
   if (NS_FAILED(rv)) {
     RejectPromise(data.mPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
                   NS_LITERAL_CSTRING("Call to GetNodeId() failed early"));
   }
 }
 
 void
-CDMProxy::gmp_InitGetGMPDecryptor(nsresult aResult,
-                                  const nsACString& aNodeId,
-                                  nsAutoPtr<InitData>&& aData)
+GMPCDMProxy::gmp_InitGetGMPDecryptor(nsresult aResult,
+                                     const nsACString& aNodeId,
+                                     nsAutoPtr<InitData>&& aData)
 {
   uint32_t promiseID = aData->mPromiseId;
   if (NS_FAILED(aResult)) {
     RejectPromise(promiseID, NS_ERROR_DOM_INVALID_STATE_ERR,
                   NS_LITERAL_CSTRING("GetNodeId() called back, but with a failure result"));
     return;
   }
 
   mNodeId = aNodeId;
   MOZ_ASSERT(!GetNodeId().IsEmpty());
 
   nsCOMPtr<mozIGeckoMediaPluginService> mps =
     do_GetService("@mozilla.org/gecko-media-plugin-service;1");
   if (!mps) {
     RejectPromise(promiseID, NS_ERROR_DOM_INVALID_STATE_ERR,
-                  NS_LITERAL_CSTRING("Couldn't get MediaPluginService in CDMProxy::gmp_InitGetGMPDecryptor"));
+                  NS_LITERAL_CSTRING("Couldn't get MediaPluginService in GMPCDMProxy::gmp_InitGetGMPDecryptor"));
     return;
   }
 
-  EME_LOG("CDMProxy::gmp_Init (%s, %s) %s NodeId=%s",
+  EME_LOG("GMPCDMProxy::gmp_Init (%s, %s) %s NodeId=%s",
           NS_ConvertUTF16toUTF8(aData->mOrigin).get(),
           NS_ConvertUTF16toUTF8(aData->mTopLevelOrigin).get(),
           (aData->mInPrivateBrowsing ? "PrivateBrowsing" : "NonPrivateBrowsing"),
           GetNodeId().get());
 
   nsTArray<nsCString> tags;
   tags.AppendElement(NS_ConvertUTF16toUTF8(mKeySystem));
 
@@ -237,236 +240,236 @@ CDMProxy::gmp_InitGetGMPDecryptor(nsresu
   nsresult rv = mps->GetGMPDecryptor(crashHelper, &tags, GetNodeId(), Move(callback));
   if (NS_FAILED(rv)) {
     RejectPromise(promiseID, NS_ERROR_DOM_INVALID_STATE_ERR,
                   NS_LITERAL_CSTRING("Call to GetGMPDecryptor() failed early"));
   }
 }
 
 void
-CDMProxy::OnCDMCreated(uint32_t aPromiseId)
+GMPCDMProxy::OnCDMCreated(uint32_t aPromiseId)
 {
   MOZ_ASSERT(NS_IsMainThread());
   if (mKeys.IsNull()) {
     return;
   }
   MOZ_ASSERT(!GetNodeId().IsEmpty());
   if (mCDM) {
     mKeys->OnCDMCreated(aPromiseId, GetNodeId(), mCDM->GetPluginId());
   } else {
     // No CDM? Just reject the promise.
     mKeys->RejectPromise(aPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
                          NS_LITERAL_CSTRING("Null CDM in OnCDMCreated()"));
   }
 }
 
 void
-CDMProxy::CreateSession(uint32_t aCreateSessionToken,
-                        dom::SessionType aSessionType,
-                        PromiseId aPromiseId,
-                        const nsAString& aInitDataType,
-                        nsTArray<uint8_t>& aInitData)
+GMPCDMProxy::CreateSession(uint32_t aCreateSessionToken,
+                           dom::SessionType aSessionType,
+                           PromiseId aPromiseId,
+                           const nsAString& aInitDataType,
+                           nsTArray<uint8_t>& aInitData)
 {
   MOZ_ASSERT(NS_IsMainThread());
-  MOZ_ASSERT(mGMPThread);
+  MOZ_ASSERT(mOwnerThread);
 
   nsAutoPtr<CreateSessionData> data(new CreateSessionData());
   data->mSessionType = aSessionType;
   data->mCreateSessionToken = aCreateSessionToken;
   data->mPromiseId = aPromiseId;
   data->mInitDataType = NS_ConvertUTF16toUTF8(aInitDataType);
   data->mInitData = Move(aInitData);
 
   nsCOMPtr<nsIRunnable> task(
-    NewRunnableMethod<nsAutoPtr<CreateSessionData>>(this, &CDMProxy::gmp_CreateSession, data));
-  mGMPThread->Dispatch(task, NS_DISPATCH_NORMAL);
+    NewRunnableMethod<nsAutoPtr<CreateSessionData>>(this, &GMPCDMProxy::gmp_CreateSession, data));
+  mOwnerThread->Dispatch(task, NS_DISPATCH_NORMAL);
 }
 
 GMPSessionType
 ToGMPSessionType(dom::SessionType aSessionType) {
   switch (aSessionType) {
     case dom::SessionType::Temporary: return kGMPTemporySession;
     case dom::SessionType::Persistent: return kGMPPersistentSession;
     default: return kGMPTemporySession;
   };
 };
 
 void
-CDMProxy::gmp_CreateSession(nsAutoPtr<CreateSessionData> aData)
+GMPCDMProxy::gmp_CreateSession(nsAutoPtr<CreateSessionData> aData)
 {
-  MOZ_ASSERT(IsOnGMPThread());
+  MOZ_ASSERT(IsOnOwnerThread());
   if (!mCDM) {
     RejectPromise(aData->mPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
                   NS_LITERAL_CSTRING("Null CDM in gmp_CreateSession"));
     return;
   }
   mCDM->CreateSession(aData->mCreateSessionToken,
                       aData->mPromiseId,
                       aData->mInitDataType,
                       aData->mInitData,
                       ToGMPSessionType(aData->mSessionType));
 }
 
 void
-CDMProxy::LoadSession(PromiseId aPromiseId,
-                      const nsAString& aSessionId)
+GMPCDMProxy::LoadSession(PromiseId aPromiseId,
+                         const nsAString& aSessionId)
 {
   MOZ_ASSERT(NS_IsMainThread());
-  MOZ_ASSERT(mGMPThread);
+  MOZ_ASSERT(mOwnerThread);
 
   nsAutoPtr<SessionOpData> data(new SessionOpData());
   data->mPromiseId = aPromiseId;
   data->mSessionId = NS_ConvertUTF16toUTF8(aSessionId);
   nsCOMPtr<nsIRunnable> task(
-    NewRunnableMethod<nsAutoPtr<SessionOpData>>(this, &CDMProxy::gmp_LoadSession, data));
-  mGMPThread->Dispatch(task, NS_DISPATCH_NORMAL);
+    NewRunnableMethod<nsAutoPtr<SessionOpData>>(this, &GMPCDMProxy::gmp_LoadSession, data));
+  mOwnerThread->Dispatch(task, NS_DISPATCH_NORMAL);
 }
 
 void
-CDMProxy::gmp_LoadSession(nsAutoPtr<SessionOpData> aData)
+GMPCDMProxy::gmp_LoadSession(nsAutoPtr<SessionOpData> aData)
 {
-  MOZ_ASSERT(IsOnGMPThread());
+  MOZ_ASSERT(IsOnOwnerThread());
 
   if (!mCDM) {
     RejectPromise(aData->mPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
                   NS_LITERAL_CSTRING("Null CDM in gmp_LoadSession"));
     return;
   }
   mCDM->LoadSession(aData->mPromiseId, aData->mSessionId);
 }
 
 void
-CDMProxy::SetServerCertificate(PromiseId aPromiseId,
-                               nsTArray<uint8_t>& aCert)
+GMPCDMProxy::SetServerCertificate(PromiseId aPromiseId,
+                                  nsTArray<uint8_t>& aCert)
 {
   MOZ_ASSERT(NS_IsMainThread());
-  MOZ_ASSERT(mGMPThread);
+  MOZ_ASSERT(mOwnerThread);
 
   nsAutoPtr<SetServerCertificateData> data(new SetServerCertificateData());
   data->mPromiseId = aPromiseId;
   data->mCert = Move(aCert);
   nsCOMPtr<nsIRunnable> task(
-    NewRunnableMethod<nsAutoPtr<SetServerCertificateData>>(this, &CDMProxy::gmp_SetServerCertificate, data));
-  mGMPThread->Dispatch(task, NS_DISPATCH_NORMAL);
+    NewRunnableMethod<nsAutoPtr<SetServerCertificateData>>(this, &GMPCDMProxy::gmp_SetServerCertificate, data));
+  mOwnerThread->Dispatch(task, NS_DISPATCH_NORMAL);
 }
 
 void
-CDMProxy::gmp_SetServerCertificate(nsAutoPtr<SetServerCertificateData> aData)
+GMPCDMProxy::gmp_SetServerCertificate(nsAutoPtr<SetServerCertificateData> aData)
 {
-  MOZ_ASSERT(IsOnGMPThread());
+  MOZ_ASSERT(IsOnOwnerThread());
   if (!mCDM) {
     RejectPromise(aData->mPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
                   NS_LITERAL_CSTRING("Null CDM in gmp_SetServerCertificate"));
     return;
   }
   mCDM->SetServerCertificate(aData->mPromiseId, aData->mCert);
 }
 
 void
-CDMProxy::UpdateSession(const nsAString& aSessionId,
-                        PromiseId aPromiseId,
-                        nsTArray<uint8_t>& aResponse)
+GMPCDMProxy::UpdateSession(const nsAString& aSessionId,
+                           PromiseId aPromiseId,
+                           nsTArray<uint8_t>& aResponse)
 {
   MOZ_ASSERT(NS_IsMainThread());
-  MOZ_ASSERT(mGMPThread);
+  MOZ_ASSERT(mOwnerThread);
   NS_ENSURE_TRUE_VOID(!mKeys.IsNull());
 
   nsAutoPtr<UpdateSessionData> data(new UpdateSessionData());
   data->mPromiseId = aPromiseId;
   data->mSessionId = NS_ConvertUTF16toUTF8(aSessionId);
   data->mResponse = Move(aResponse);
   nsCOMPtr<nsIRunnable> task(
-    NewRunnableMethod<nsAutoPtr<UpdateSessionData>>(this, &CDMProxy::gmp_UpdateSession, data));
-  mGMPThread->Dispatch(task, NS_DISPATCH_NORMAL);
+    NewRunnableMethod<nsAutoPtr<UpdateSessionData>>(this, &GMPCDMProxy::gmp_UpdateSession, data));
+  mOwnerThread->Dispatch(task, NS_DISPATCH_NORMAL);
 }
 
 void
-CDMProxy::gmp_UpdateSession(nsAutoPtr<UpdateSessionData> aData)
+GMPCDMProxy::gmp_UpdateSession(nsAutoPtr<UpdateSessionData> aData)
 {
-  MOZ_ASSERT(IsOnGMPThread());
+  MOZ_ASSERT(IsOnOwnerThread());
   if (!mCDM) {
     RejectPromise(aData->mPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
                   NS_LITERAL_CSTRING("Null CDM in gmp_UpdateSession"));
     return;
   }
   mCDM->UpdateSession(aData->mPromiseId,
                       aData->mSessionId,
                       aData->mResponse);
 }
 
 void
-CDMProxy::CloseSession(const nsAString& aSessionId,
-                       PromiseId aPromiseId)
+GMPCDMProxy::CloseSession(const nsAString& aSessionId,
+                          PromiseId aPromiseId)
 {
   MOZ_ASSERT(NS_IsMainThread());
   NS_ENSURE_TRUE_VOID(!mKeys.IsNull());
 
   nsAutoPtr<SessionOpData> data(new SessionOpData());
   data->mPromiseId = aPromiseId;
   data->mSessionId = NS_ConvertUTF16toUTF8(aSessionId);
   nsCOMPtr<nsIRunnable> task(
-    NewRunnableMethod<nsAutoPtr<SessionOpData>>(this, &CDMProxy::gmp_CloseSession, data));
-  mGMPThread->Dispatch(task, NS_DISPATCH_NORMAL);
+    NewRunnableMethod<nsAutoPtr<SessionOpData>>(this, &GMPCDMProxy::gmp_CloseSession, data));
+  mOwnerThread->Dispatch(task, NS_DISPATCH_NORMAL);
 }
 
 void
-CDMProxy::gmp_CloseSession(nsAutoPtr<SessionOpData> aData)
+GMPCDMProxy::gmp_CloseSession(nsAutoPtr<SessionOpData> aData)
 {
-  MOZ_ASSERT(IsOnGMPThread());
+  MOZ_ASSERT(IsOnOwnerThread());
   if (!mCDM) {
     RejectPromise(aData->mPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
                   NS_LITERAL_CSTRING("Null CDM in gmp_CloseSession"));
     return;
   }
   mCDM->CloseSession(aData->mPromiseId, aData->mSessionId);
 }
 
 void
-CDMProxy::RemoveSession(const nsAString& aSessionId,
-                        PromiseId aPromiseId)
+GMPCDMProxy::RemoveSession(const nsAString& aSessionId,
+                           PromiseId aPromiseId)
 {
   MOZ_ASSERT(NS_IsMainThread());
   NS_ENSURE_TRUE_VOID(!mKeys.IsNull());
 
   nsAutoPtr<SessionOpData> data(new SessionOpData());
   data->mPromiseId = aPromiseId;
   data->mSessionId = NS_ConvertUTF16toUTF8(aSessionId);
   nsCOMPtr<nsIRunnable> task(
-    NewRunnableMethod<nsAutoPtr<SessionOpData>>(this, &CDMProxy::gmp_RemoveSession, data));
-  mGMPThread->Dispatch(task, NS_DISPATCH_NORMAL);
+    NewRunnableMethod<nsAutoPtr<SessionOpData>>(this, &GMPCDMProxy::gmp_RemoveSession, data));
+  mOwnerThread->Dispatch(task, NS_DISPATCH_NORMAL);
 }
 
 void
-CDMProxy::gmp_RemoveSession(nsAutoPtr<SessionOpData> aData)
+GMPCDMProxy::gmp_RemoveSession(nsAutoPtr<SessionOpData> aData)
 {
-  MOZ_ASSERT(IsOnGMPThread());
+  MOZ_ASSERT(IsOnOwnerThread());
   if (!mCDM) {
     RejectPromise(aData->mPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
                   NS_LITERAL_CSTRING("Null CDM in gmp_RemoveSession"));
     return;
   }
   mCDM->RemoveSession(aData->mPromiseId, aData->mSessionId);
 }
 
 void
-CDMProxy::Shutdown()
+GMPCDMProxy::Shutdown()
 {
   MOZ_ASSERT(NS_IsMainThread());
   mKeys.Clear();
-  // Note: This may end up being the last owning reference to the CDMProxy.
-  nsCOMPtr<nsIRunnable> task(NewRunnableMethod(this, &CDMProxy::gmp_Shutdown));
-  if (mGMPThread) {
-    mGMPThread->Dispatch(task, NS_DISPATCH_NORMAL);
+  // Note: This may end up being the last owning reference to the GMPCDMProxy.
+  nsCOMPtr<nsIRunnable> task(NewRunnableMethod(this, &GMPCDMProxy::gmp_Shutdown));
+  if (mOwnerThread) {
+    mOwnerThread->Dispatch(task, NS_DISPATCH_NORMAL);
   }
 }
 
 void
-CDMProxy::gmp_Shutdown()
+GMPCDMProxy::gmp_Shutdown()
 {
-  MOZ_ASSERT(IsOnGMPThread());
+  MOZ_ASSERT(IsOnOwnerThread());
 
   mShutdownCalled = true;
 
   // Abort any pending decrypt jobs, to awaken any clients waiting on a job.
   for (size_t i = 0; i < mDecryptionJobs.Length(); i++) {
     DecryptJob* job = mDecryptionJobs[i];
     job->PostResult(GMPAbortedErr);
   }
@@ -474,230 +477,228 @@ CDMProxy::gmp_Shutdown()
 
   if (mCDM) {
     mCDM->Close();
     mCDM = nullptr;
   }
 }
 
 void
-CDMProxy::RejectPromise(PromiseId aId, nsresult aCode,
-                        const nsCString& aReason)
+GMPCDMProxy::RejectPromise(PromiseId aId, nsresult aCode,
+                           const nsCString& aReason)
 {
   if (NS_IsMainThread()) {
     if (!mKeys.IsNull()) {
       mKeys->RejectPromise(aId, aCode, aReason);
     }
   } else {
     nsCOMPtr<nsIRunnable> task(new RejectPromiseTask(this, aId, aCode,
                                                      aReason));
     NS_DispatchToMainThread(task);
   }
 }
 
 void
-CDMProxy::ResolvePromise(PromiseId aId)
+GMPCDMProxy::ResolvePromise(PromiseId aId)
 {
   if (NS_IsMainThread()) {
     if (!mKeys.IsNull()) {
       mKeys->ResolvePromise(aId);
     } else {
-      NS_WARNING("CDMProxy unable to resolve promise!");
+      NS_WARNING("GMPCDMProxy unable to resolve promise!");
     }
   } else {
     nsCOMPtr<nsIRunnable> task;
     task = NewRunnableMethod<PromiseId>(this,
-                                        &CDMProxy::ResolvePromise,
+                                        &GMPCDMProxy::ResolvePromise,
                                         aId);
     NS_DispatchToMainThread(task);
   }
 }
 
 const nsCString&
-CDMProxy::GetNodeId() const
+GMPCDMProxy::GetNodeId() const
 {
   return mNodeId;
 }
 
 void
-CDMProxy::OnSetSessionId(uint32_t aCreateSessionToken,
-                         const nsAString& aSessionId)
+GMPCDMProxy::OnSetSessionId(uint32_t aCreateSessionToken,
+                            const nsAString& aSessionId)
 {
   MOZ_ASSERT(NS_IsMainThread());
   if (mKeys.IsNull()) {
     return;
   }
 
   RefPtr<dom::MediaKeySession> session(mKeys->GetPendingSession(aCreateSessionToken));
   if (session) {
     session->SetSessionId(aSessionId);
   }
 }
 
 void
-CDMProxy::OnResolveLoadSessionPromise(uint32_t aPromiseId, bool aSuccess)
+GMPCDMProxy::OnResolveLoadSessionPromise(uint32_t aPromiseId, bool aSuccess)
 {
   MOZ_ASSERT(NS_IsMainThread());
   if (mKeys.IsNull()) {
     return;
   }
   mKeys->OnSessionLoaded(aPromiseId, aSuccess);
 }
 
-static dom::MediaKeyMessageType
-ToMediaKeyMessageType(GMPSessionMessageType aMessageType) {
-  switch (aMessageType) {
-    case kGMPLicenseRequest: return dom::MediaKeyMessageType::License_request;
-    case kGMPLicenseRenewal: return dom::MediaKeyMessageType::License_renewal;
-    case kGMPLicenseRelease: return dom::MediaKeyMessageType::License_release;
-    case kGMPIndividualizationRequest: return dom::MediaKeyMessageType::Individualization_request;
-    default: return dom::MediaKeyMessageType::License_request;
-  };
-};
-
 void
-CDMProxy::OnSessionMessage(const nsAString& aSessionId,
-                           GMPSessionMessageType aMessageType,
-                           nsTArray<uint8_t>& aMessage)
+GMPCDMProxy::OnSessionMessage(const nsAString& aSessionId,
+                              dom::MediaKeyMessageType aMessageType,
+                              nsTArray<uint8_t>& aMessage)
 {
   MOZ_ASSERT(NS_IsMainThread());
   if (mKeys.IsNull()) {
     return;
   }
   RefPtr<dom::MediaKeySession> session(mKeys->GetSession(aSessionId));
   if (session) {
-    session->DispatchKeyMessage(ToMediaKeyMessageType(aMessageType), aMessage);
+    session->DispatchKeyMessage(aMessageType, aMessage);
   }
 }
 
 void
-CDMProxy::OnKeyStatusesChange(const nsAString& aSessionId)
+GMPCDMProxy::OnKeyStatusesChange(const nsAString& aSessionId)
 {
   MOZ_ASSERT(NS_IsMainThread());
   if (mKeys.IsNull()) {
     return;
   }
   RefPtr<dom::MediaKeySession> session(mKeys->GetSession(aSessionId));
   if (session) {
     session->DispatchKeyStatusesChange();
   }
 }
 
 void
-CDMProxy::OnExpirationChange(const nsAString& aSessionId,
-                             GMPTimestamp aExpiryTime)
+GMPCDMProxy::OnExpirationChange(const nsAString& aSessionId,
+                                GMPTimestamp aExpiryTime)
 {
   MOZ_ASSERT(NS_IsMainThread());
   if (mKeys.IsNull()) {
     return;
   }
   RefPtr<dom::MediaKeySession> session(mKeys->GetSession(aSessionId));
   if (session) {
     session->SetExpiration(static_cast<double>(aExpiryTime));
   }
 }
 
 void
-CDMProxy::OnSessionClosed(const nsAString& aSessionId)
+GMPCDMProxy::OnSessionClosed(const nsAString& aSessionId)
 {
   MOZ_ASSERT(NS_IsMainThread());
   if (mKeys.IsNull()) {
     return;
   }
   RefPtr<dom::MediaKeySession> session(mKeys->GetSession(aSessionId));
   if (session) {
     session->OnClosed();
   }
 }
 
+void
+GMPCDMProxy::OnDecrypted(uint32_t aId,
+                         GMPErr aResult,
+                         const nsTArray<uint8_t>& aDecryptedData)
+{
+  MOZ_ASSERT(IsOnOwnerThread());
+  gmp_Decrypted(aId, aResult, aDecryptedData);
+}
+
 static void
 LogToConsole(const nsAString& aMsg)
 {
   nsCOMPtr<nsIConsoleService> console(
     do_GetService("@mozilla.org/consoleservice;1"));
   if (!console) {
     NS_WARNING("Failed to log message to console.");
     return;
   }
   nsAutoString msg(aMsg);
   console->LogStringMessage(msg.get());
 }
 
 void
-CDMProxy::OnSessionError(const nsAString& aSessionId,
+GMPCDMProxy::OnSessionError(const nsAString& aSessionId,
                          nsresult aException,
                          uint32_t aSystemCode,
                          const nsAString& aMsg)
 {
   MOZ_ASSERT(NS_IsMainThread());
   if (mKeys.IsNull()) {
     return;
   }
   RefPtr<dom::MediaKeySession> session(mKeys->GetSession(aSessionId));
   if (session) {
     session->DispatchKeyError(aSystemCode);
   }
   LogToConsole(aMsg);
 }
 
 void
-CDMProxy::OnRejectPromise(uint32_t aPromiseId,
+GMPCDMProxy::OnRejectPromise(uint32_t aPromiseId,
                           nsresult aDOMException,
                           const nsCString& aMsg)
 {
   MOZ_ASSERT(NS_IsMainThread());
   RejectPromise(aPromiseId, aDOMException, aMsg);
 }
 
 const nsString&
-CDMProxy::KeySystem() const
+GMPCDMProxy::KeySystem() const
 {
   return mKeySystem;
 }
 
 CDMCaps&
-CDMProxy::Capabilites() {
+GMPCDMProxy::Capabilites() {
   return mCapabilites;
 }
 
-RefPtr<CDMProxy::DecryptPromise>
-CDMProxy::Decrypt(MediaRawData* aSample)
+RefPtr<GMPCDMProxy::DecryptPromise>
+GMPCDMProxy::Decrypt(MediaRawData* aSample)
 {
   RefPtr<DecryptJob> job(new DecryptJob(aSample));
   RefPtr<DecryptPromise> promise(job->Ensure());
 
   nsCOMPtr<nsIRunnable> task(
-    NewRunnableMethod<RefPtr<DecryptJob>>(this, &CDMProxy::gmp_Decrypt, job));
-  mGMPThread->Dispatch(task, NS_DISPATCH_NORMAL);
+    NewRunnableMethod<RefPtr<DecryptJob>>(this, &GMPCDMProxy::gmp_Decrypt, job));
+  mOwnerThread->Dispatch(task, NS_DISPATCH_NORMAL);
   return promise;
 }
 
 void
-CDMProxy::gmp_Decrypt(RefPtr<DecryptJob> aJob)
+GMPCDMProxy::gmp_Decrypt(RefPtr<DecryptJob> aJob)
 {
-  MOZ_ASSERT(IsOnGMPThread());
+  MOZ_ASSERT(IsOnOwnerThread());
 
   if (!mCDM) {
     aJob->PostResult(GMPAbortedErr);
     return;
   }
 
   aJob->mId = ++mDecryptionJobCount;
   nsTArray<uint8_t> data;
   data.AppendElements(aJob->mSample->Data(), aJob->mSample->Size());
   mCDM->Decrypt(aJob->mId, aJob->mSample->mCrypto, data);
   mDecryptionJobs.AppendElement(aJob.forget());
 }
 
 void
-CDMProxy::gmp_Decrypted(uint32_t aId,
-                        GMPErr aResult,
-                        const nsTArray<uint8_t>& aDecryptedData)
+GMPCDMProxy::gmp_Decrypted(uint32_t aId,
+                           GMPErr aResult,
+                           const nsTArray<uint8_t>& aDecryptedData)
 {
-  MOZ_ASSERT(IsOnGMPThread());
+  MOZ_ASSERT(IsOnOwnerThread());
 #ifdef DEBUG
   bool jobIdFound = false;
 #endif
   for (size_t i = 0; i < mDecryptionJobs.Length(); i++) {
     DecryptJob* job = mDecryptionJobs[i];
     if (job->mId == aId) {
 #ifdef DEBUG
       jobIdFound = true;
@@ -709,24 +710,25 @@ CDMProxy::gmp_Decrypted(uint32_t aId,
 #ifdef DEBUG
   if (!jobIdFound) {
     NS_WARNING("GMPDecryptorChild returned incorrect job ID");
   }
 #endif
 }
 
 void
-CDMProxy::DecryptJob::PostResult(GMPErr aResult)
+GMPCDMProxy::DecryptJob::PostResult(GMPErr aResult)
 {
   nsTArray<uint8_t> empty;
   PostResult(aResult, empty);
 }
 
 void
-CDMProxy::DecryptJob::PostResult(GMPErr aResult, const nsTArray<uint8_t>& aDecryptedData)
+GMPCDMProxy::DecryptJob::PostResult(GMPErr aResult,
+                                    const nsTArray<uint8_t>& aDecryptedData)
 {
   if (aDecryptedData.Length() != mSample->Size()) {
     NS_WARNING("CDM returned incorrect number of decrypted bytes");
   }
   if (GMP_SUCCEEDED(aResult)) {
     nsAutoPtr<MediaRawDataWriter> writer(mSample->CreateWriter());
     PodCopy(writer->Data(),
             aDecryptedData.Elements(),
@@ -739,25 +741,25 @@ CDMProxy::DecryptJob::PostResult(GMPErr 
     nsAutoCString str("CDM returned decode failure GMPErr=");
     str.AppendInt(aResult);
     NS_WARNING(str.get());
   }
   mPromise.Resolve(DecryptResult(aResult, mSample), __func__);
 }
 
 void
-CDMProxy::GetSessionIdsForKeyId(const nsTArray<uint8_t>& aKeyId,
-                                nsTArray<nsCString>& aSessionIds)
+GMPCDMProxy::GetSessionIdsForKeyId(const nsTArray<uint8_t>& aKeyId,
+                                   nsTArray<nsCString>& aSessionIds)
 {
   CDMCaps::AutoLock caps(Capabilites());
   caps.GetSessionIdsForKeyId(aKeyId, aSessionIds);
 }
 
 void
-CDMProxy::Terminated()
+GMPCDMProxy::Terminated()
 {
   MOZ_ASSERT(NS_IsMainThread());
   NS_WARNING("CDM terminated");
   if (!mKeys.IsNull()) {
     mKeys->Terminated();
   }
 }
 
copy from dom/media/eme/CDMProxy.h
copy to dom/media/gmp/GMPCDMProxy.h
--- a/dom/media/eme/CDMProxy.h
+++ b/dom/media/gmp/GMPCDMProxy.h
@@ -1,188 +1,115 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#ifndef CDMProxy_h_
-#define CDMProxy_h_
+#ifndef GMPCDMProxy_h_
+#define GMPCDMProxy_h_
 
-#include "mozilla/CDMCaps.h"
-#include "mozilla/Monitor.h"
-#include "mozilla/MozPromise.h"
-
-#include "mozilla/dom/MediaKeys.h"
-
-#include "nsIThread.h"
-#include "nsString.h"
-#include "nsAutoPtr.h"
+#include "mozilla/CDMProxy.h"
+#include "GMPCDMCallbackProxy.h"
 #include "GMPDecryptorProxy.h"
 
 namespace mozilla {
 class MediaRawData;
-class GMPCDMCallbackProxy;
 
-namespace dom {
-class MediaKeySession;
-} // namespace dom
-
-struct DecryptResult {
-  DecryptResult(GMPErr aStatus, MediaRawData* aSample)
-    : mStatus(aStatus)
-    , mSample(aSample)
-  {}
-  GMPErr mStatus;
-  RefPtr<MediaRawData> mSample;
-};
-
-// Proxies calls GMP/CDM, and proxies calls back.
-// Note: Promises are passed in via a PromiseId, so that the ID can be
-// passed via IPC to the CDM, which can then signal when to reject or
-// resolve the promise using its PromiseId.
-class CDMProxy {
-  typedef dom::PromiseId PromiseId;
-  typedef dom::SessionType SessionType;
+// Implementation of CDMProxy which is based on GMP architecture.
+class GMPCDMProxy : public CDMProxy {
 public:
 
-  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CDMProxy)
+  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(GMPCDMProxy, override)
 
   typedef MozPromise<DecryptResult, DecryptResult, /* IsExclusive = */ true> DecryptPromise;
 
-  // Main thread only.
-  CDMProxy(dom::MediaKeys* aKeys, const nsAString& aKeySystem);
+  GMPCDMProxy(dom::MediaKeys* aKeys,
+              const nsAString& aKeySystem,
+              GMPCrashHelper* aCrashHelper);
 
-  // Main thread only.
-  // Loads the CDM corresponding to mKeySystem.
-  // Calls MediaKeys::OnCDMCreated() when the CDM is created.
   void Init(PromiseId aPromiseId,
             const nsAString& aOrigin,
             const nsAString& aTopLevelOrigin,
             const nsAString& aGMPName,
-            bool aInPrivateBrowsing,
-            GMPCrashHelper* aHelper);
+            bool aInPrivateBrowsing) override;
 
-  // Main thread only.
-  // Uses the CDM to create a key session.
-  // Calls MediaKeys::OnSessionActivated() when session is created.
-  // Assumes ownership of (Move()s) aInitData's contents.
   void CreateSession(uint32_t aCreateSessionToken,
                      dom::SessionType aSessionType,
                      PromiseId aPromiseId,
                      const nsAString& aInitDataType,
-                     nsTArray<uint8_t>& aInitData);
-
-  // Main thread only.
-  // Uses the CDM to load a presistent session stored on disk.
-  // Calls MediaKeys::OnSessionActivated() when session is loaded.
-  void LoadSession(PromiseId aPromiseId,
-                   const nsAString& aSessionId);
+                     nsTArray<uint8_t>& aInitData) override;
 
-  // Main thread only.
-  // Sends a new certificate to the CDM.
-  // Calls MediaKeys->ResolvePromise(aPromiseId) after the CDM has
-  // processed the request.
-  // Assumes ownership of (Move()s) aCert's contents.
+  void LoadSession(PromiseId aPromiseId,
+                   const nsAString& aSessionId) override;
+
   void SetServerCertificate(PromiseId aPromiseId,
-                            nsTArray<uint8_t>& aCert);
+                            nsTArray<uint8_t>& aCert) override;
 
-  // Main thread only.
-  // Sends an update to the CDM.
-  // Calls MediaKeys->ResolvePromise(aPromiseId) after the CDM has
-  // processed the request.
-  // Assumes ownership of (Move()s) aResponse's contents.
   void UpdateSession(const nsAString& aSessionId,
                      PromiseId aPromiseId,
-                     nsTArray<uint8_t>& aResponse);
+                     nsTArray<uint8_t>& aResponse) override;
 
-  // Main thread only.
-  // Calls MediaKeys->ResolvePromise(aPromiseId) after the CDM has
-  // processed the request.
-  // If processing this operation results in the session actually closing,
-  // we also call MediaKeySession::OnClosed(), which in turn calls
-  // MediaKeys::OnSessionClosed().
   void CloseSession(const nsAString& aSessionId,
-                    PromiseId aPromiseId);
+                    PromiseId aPromiseId) override;
 
-  // Main thread only.
-  // Removes all data for a persisent session.
-  // Calls MediaKeys->ResolvePromise(aPromiseId) after the CDM has
-  // processed the request.
   void RemoveSession(const nsAString& aSessionId,
-                     PromiseId aPromiseId);
+                     PromiseId aPromiseId) override;
+
+  void Shutdown() override;
 
-  // Main thread only.
-  void Shutdown();
+  void Terminated() override;
 
-  // Main thread only.
-  void Terminated();
+  const nsCString& GetNodeId() const override;
 
-  // Threadsafe.
-  const nsCString& GetNodeId() const;
+  void OnSetSessionId(uint32_t aCreateSessionToken,
+                      const nsAString& aSessionId) override;
 
-  // Main thread only.
-  void OnSetSessionId(uint32_t aCreateSessionToken,
-                      const nsAString& aSessionId);
+  void OnResolveLoadSessionPromise(uint32_t aPromiseId, bool aSuccess) override;
 
-  // Main thread only.
-  void OnResolveLoadSessionPromise(uint32_t aPromiseId, bool aSuccess);
-
-  // Main thread only.
   void OnSessionMessage(const nsAString& aSessionId,
-                        GMPSessionMessageType aMessageType,
-                        nsTArray<uint8_t>& aMessage);
+                        dom::MediaKeyMessageType aMessageType,
+                        nsTArray<uint8_t>& aMessage) override;
 
-  // Main thread only.
   void OnExpirationChange(const nsAString& aSessionId,
-                          GMPTimestamp aExpiryTime);
+                          GMPTimestamp aExpiryTime) override;
 
-  // Main thread only.
-  void OnSessionClosed(const nsAString& aSessionId);
+  void OnSessionClosed(const nsAString& aSessionId) override;
 
-  // Main thread only.
   void OnSessionError(const nsAString& aSessionId,
                       nsresult aException,
                       uint32_t aSystemCode,
-                      const nsAString& aMsg);
+                      const nsAString& aMsg) override;
 
-  // Main thread only.
   void OnRejectPromise(uint32_t aPromiseId,
                        nsresult aDOMException,
-                       const nsCString& aMsg);
+                       const nsCString& aMsg) override;
 
-  RefPtr<DecryptPromise> Decrypt(MediaRawData* aSample);
+  RefPtr<DecryptPromise> Decrypt(MediaRawData* aSample) override;
 
-  // Reject promise with DOMException corresponding to aExceptionCode.
-  // Can be called from any thread.
-  void RejectPromise(PromiseId aId, nsresult aExceptionCode,
-                     const nsCString& aReason);
-
-  // Resolves promise with "undefined".
-  // Can be called from any thread.
-  void ResolvePromise(PromiseId aId);
+  void OnDecrypted(uint32_t aId,
+                   GMPErr aResult,
+                   const nsTArray<uint8_t>& aDecryptedData) override;
 
-  // Threadsafe.
-  const nsString& KeySystem() const;
+  void RejectPromise(PromiseId aId, nsresult aExceptionCode,
+                     const nsCString& aReason) override;
+
+  void ResolvePromise(PromiseId aId) override;
 
-  // GMP thread only.
-  void gmp_Decrypted(uint32_t aId,
-                     GMPErr aResult,
-                     const nsTArray<uint8_t>& aDecryptedData);
+  const nsString& KeySystem() const override;
 
-  CDMCaps& Capabilites();
+  CDMCaps& Capabilites() override;
 
-  // Main thread only.
-  void OnKeyStatusesChange(const nsAString& aSessionId);
+  void OnKeyStatusesChange(const nsAString& aSessionId) override;
 
   void GetSessionIdsForKeyId(const nsTArray<uint8_t>& aKeyId,
-                             nsTArray<nsCString>& aSessionIds);
+                             nsTArray<nsCString>& aSessionIds) override;
 
 #ifdef DEBUG
-  bool IsOnGMPThread();
+  bool IsOnOwnerThread() override;
 #endif
 
 private:
   friend class gmp_InitDoneCallback;
   friend class gmp_InitGetGMPDecryptorCallback;
 
   struct InitData {
     uint32_t mPromiseId;
@@ -265,98 +192,66 @@ private:
     RefPtr<MediaRawData> mSample;
   private:
     ~DecryptJob() {}
     MozPromiseHolder<DecryptPromise> mPromise;
   };
   // GMP thread only.
   void gmp_Decrypt(RefPtr<DecryptJob> aJob);
 
+  // GMP thread only.
+  void gmp_Decrypted(uint32_t aId,
+                     GMPErr aResult,
+                     const nsTArray<uint8_t>& aDecryptedData);
+
   class RejectPromiseTask : public Runnable {
   public:
-    RejectPromiseTask(CDMProxy* aProxy,
+    RejectPromiseTask(GMPCDMProxy* aProxy,
                       PromiseId aId,
                       nsresult aCode,
                       const nsCString& aReason)
       : mProxy(aProxy)
       , mId(aId)
       , mCode(aCode)
       , mReason(aReason)
     {
     }
     NS_METHOD Run() {
       mProxy->RejectPromise(mId, mCode, mReason);
       return NS_OK;
     }
   private:
-    RefPtr<CDMProxy> mProxy;
+    RefPtr<GMPCDMProxy> mProxy;
     PromiseId mId;
     nsresult mCode;
     nsCString mReason;
   };
 
-  ~CDMProxy();
-
-  // Helper to enforce that a raw pointer is only accessed on the main thread.
-  template<class Type>
-  class MainThreadOnlyRawPtr {
-  public:
-    explicit MainThreadOnlyRawPtr(Type* aPtr)
-      : mPtr(aPtr)
-    {
-      MOZ_ASSERT(NS_IsMainThread());
-    }
-
-    bool IsNull() const {
-      MOZ_ASSERT(NS_IsMainThread());
-      return !mPtr;
-    }
+  ~GMPCDMProxy();
 
-    void Clear() {
-      MOZ_ASSERT(NS_IsMainThread());
-      mPtr = nullptr;
-    }
-
-    Type* operator->() const MOZ_NO_ADDREF_RELEASE_ON_RETURN {
-      MOZ_ASSERT(NS_IsMainThread());
-      return mPtr;
-    }
-  private:
-    Type* mPtr;
-  };
-
-  // Our reference back to the MediaKeys object.
-  // WARNING: This is a non-owning reference that is cleared by MediaKeys
-  // destructor. only use on main thread, and always nullcheck before using!
-  MainThreadOnlyRawPtr<dom::MediaKeys> mKeys;
-
-  const nsString mKeySystem;
-
-  // Gecko Media Plugin thread. All interactions with the out-of-process
-  // EME plugin must come from this thread.
-  RefPtr<nsIThread> mGMPThread;
-
-  nsCString mNodeId;
+  GMPCrashHelper* mCrashHelper;
 
   GMPDecryptorProxy* mCDM;
+
   CDMCaps mCapabilites;
+
   nsAutoPtr<GMPCDMCallbackProxy> mCallback;
 
   // Decryption jobs sent to CDM, awaiting result.
   // GMP thread only.
   nsTArray<RefPtr<DecryptJob>> mDecryptionJobs;
 
   // Number of buffers we've decrypted. Used to uniquely identify
   // decryption jobs sent to CDM. Note we can't just use the length of
   // mDecryptionJobs as that shrinks as jobs are completed and removed
   // from it.
   // GMP thread only.
   uint32_t mDecryptionJobCount;
 
-  // True if CDMProxy::gmp_Shutdown was called.
+  // True if GMPCDMProxy::gmp_Shutdown was called.
   // GMP thread only.
   bool mShutdownCalled;
 };
 
 
 } // namespace mozilla
 
-#endif // CDMProxy_h_
+#endif // GMPCDMProxy_h_
--- a/dom/media/gmp/moz.build
+++ b/dom/media/gmp/moz.build
@@ -31,16 +31,17 @@ EXPORTS += [
     'gmp-api/gmp-video-host.h',
     'gmp-api/gmp-video-plane.h',
     'GMPAudioDecoderChild.h',
     'GMPAudioDecoderParent.h',
     'GMPAudioDecoderProxy.h',
     'GMPAudioHost.h',
     'GMPCallbackBase.h',
     'GMPCDMCallbackProxy.h',
+    'GMPCDMProxy.h',
     'GMPChild.h',
     'GMPContentChild.h',
     'GMPContentParent.h',
     'GMPCrashHelperHolder.h',
     'GMPDecryptorChild.h',
     'GMPDecryptorParent.h',
     'GMPDecryptorProxy.h',
     'GMPEncryptedBufferDataImpl.h',
@@ -82,16 +83,17 @@ if CONFIG['OS_TARGET'] == 'Android':
         'rlz',
     ]
 
 UNIFIED_SOURCES += [
     'GMPAudioDecoderChild.cpp',
     'GMPAudioDecoderParent.cpp',
     'GMPAudioHost.cpp',
     'GMPCDMCallbackProxy.cpp',
+    'GMPCDMProxy.cpp',
     'GMPChild.cpp',
     'GMPContentChild.cpp',
     'GMPContentParent.cpp',
     'GMPDecryptorChild.cpp',
     'GMPDecryptorParent.cpp',
     'GMPDiskStorage.cpp',
     'GMPEncryptedBufferDataImpl.cpp',
     'GMPMemoryStorage.cpp',