Bug 1420836 - Part2 - Pass the storage id from content process to GMP process then provide it to CDM. r=cpearce
authorJames Cheng <jacheng@mozilla.com>
Wed, 03 Jan 2018 15:37:07 +0800
changeset 399404 5a46db143897c53211818c722f15c510dd708c6c
parent 399403 1595c6002aa6b675c87c4ff4255242bf2252fea4
child 399405 4fbda731082898ff82b807464b2797786f8cf785
push id33263
push userapavel@mozilla.com
push dateTue, 16 Jan 2018 15:58:11 +0000
treeherdermozilla-central@9be7249e74fd [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerscpearce
bugs1420836
milestone59.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 1420836 - Part2 - Pass the storage id from content process to GMP process then provide it to CDM. r=cpearce MozReview-Commit-ID: 2VFNHaL5p73
dom/media/gmp/ChromiumCDMChild.cpp
dom/media/gmp/ChromiumCDMChild.h
dom/media/gmp/GMPChild.cpp
dom/media/gmp/GMPChild.h
dom/media/gmp/GMPContentChild.cpp
dom/media/gmp/GMPParent.cpp
dom/media/gmp/PGMP.ipdl
--- a/dom/media/gmp/ChromiumCDMChild.cpp
+++ b/dom/media/gmp/ChromiumCDMChild.cpp
@@ -10,33 +10,35 @@
 #include "WidevineVideoFrame.h"
 #include "GMPLog.h"
 #include "GMPPlatform.h"
 #include "mozilla/Unused.h"
 #include "nsPrintfCString.h"
 #include "base/time.h"
 #include "GMPUtils.h"
 #include "mozilla/ScopeExit.h"
+#include "CDMStorageIdProvider.h"
 
 namespace mozilla {
 namespace gmp {
 
 ChromiumCDMChild::ChromiumCDMChild(GMPContentChild* aPlugin)
   : mPlugin(aPlugin)
 {
   MOZ_ASSERT(IsOnMessageLoopThread());
   GMP_LOG("ChromiumCDMChild:: ctor this=%p", this);
 }
 
 void
-ChromiumCDMChild::Init(cdm::ContentDecryptionModule_9* aCDM)
+ChromiumCDMChild::Init(cdm::ContentDecryptionModule_9* aCDM, const nsCString& aStorageId)
 {
   MOZ_ASSERT(IsOnMessageLoopThread());
   mCDM = aCDM;
   MOZ_ASSERT(mCDM);
+  mStorageId = aStorageId;
 }
 
 void
 ChromiumCDMChild::TimerExpired(void* aContext)
 {
   MOZ_ASSERT(IsOnMessageLoopThread());
   GMP_LOG("ChromiumCDMChild::TimerExpired(context=0x%p)", aContext);
   if (mCDM) {
@@ -471,16 +473,38 @@ ChromiumCDMChild::CreateFileIO(cdm::File
   MOZ_ASSERT(IsOnMessageLoopThread());
   GMP_LOG("ChromiumCDMChild::CreateFileIO()");
   if (!mPersistentStateAllowed) {
     return nullptr;
   }
   return new WidevineFileIO(aClient);
 }
 
+void
+ChromiumCDMChild::RequestStorageId(uint32_t aVersion)
+{
+  MOZ_ASSERT(IsOnMessageLoopThread());
+  GMP_LOG("ChromiumCDMChild::RequestStorageId() aVersion = %u", aVersion);
+  // aVersion >= 0x80000000 are reserved.
+  if (aVersion >= 0x80000000) {
+    mCDM->OnStorageId(aVersion, nullptr, 0);
+    return;
+  }
+  if (aVersion > CDMStorageIdProvider::kCurrentVersion) {
+    mCDM->OnStorageId(aVersion, nullptr, 0);
+    return;
+  }
+
+  mCDM->OnStorageId(CDMStorageIdProvider::kCurrentVersion,
+                    !mStorageId.IsEmpty()
+                      ? reinterpret_cast<const uint8_t*>(mStorageId.get())
+                      : nullptr,
+                    mStorageId.Length());
+}
+
 ChromiumCDMChild::~ChromiumCDMChild()
 {
   GMP_LOG("ChromiumCDMChild:: dtor this=%p", this);
 }
 
 bool
 ChromiumCDMChild::IsOnMessageLoopThread()
 {
--- a/dom/media/gmp/ChromiumCDMChild.h
+++ b/dom/media/gmp/ChromiumCDMChild.h
@@ -20,17 +20,17 @@ class ChromiumCDMChild : public PChromiu
                        , public cdm::Host_8
                        , public cdm::Host_9
 {
 public:
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(ChromiumCDMChild);
 
   explicit ChromiumCDMChild(GMPContentChild* aPlugin);
 
-  void Init(cdm::ContentDecryptionModule_9* aCDM);
+  void Init(cdm::ContentDecryptionModule_9* aCDM, const nsCString& aStorageId);
 
   void TimerExpired(void* aContext);
 
   // cdm::Host_9 implementation
   cdm::Buffer* Allocate(uint32_t aCapacity) override;
   void SetTimer(int64_t aDelayMs, void* aContext) override;
   cdm::Time GetCurrentWallTime() override;
   // cdm::Host_9 interface
@@ -66,17 +66,17 @@ public:
                              uint32_t aServiceIdSize,
                              const char* aChallenge,
                              uint32_t aChallengeSize) override {}
   void EnableOutputProtection(uint32_t aDesiredProtectionMask) override {}
   void QueryOutputProtectionStatus() override {}
   void OnDeferredInitializationDone(cdm::StreamType aStreamType,
                                     cdm::Status aDecoderStatus) override {}
   // cdm::Host_9 interface
-  void RequestStorageId(uint32_t aVersion) override {}
+  void RequestStorageId(uint32_t aVersion) override;
   cdm::FileIO* CreateFileIO(cdm::FileIOClient* aClient) override;
 
   // cdm::Host_8 implementation
   void OnSessionMessage(const char* aSessionId,
                         uint32_t aSessionIdSize,
                         cdm::MessageType aMessageType,
                         const char* aMessage,
                         uint32_t aMessageSize,
@@ -157,14 +157,15 @@ protected:
   nsTArray<uint32_t> mLoadSessionPromiseIds;
 
   cdm::Size mCodedSize;
   nsTArray<ipc::Shmem> mBuffers;
 
   bool mDecoderInitialized = false;
   bool mPersistentStateAllowed = false;
   bool mDestroyed = false;
+  nsCString mStorageId;
 };
 
 } // namespace gmp
 } // namespace mozilla
 
 #endif // ChromiumCDMChild_h_
--- a/dom/media/gmp/GMPChild.cpp
+++ b/dom/media/gmp/GMPChild.cpp
@@ -249,16 +249,24 @@ GMPChild::Init(const nsAString& aPluginP
 
   CrashReporterClient::InitSingleton(this);
 
   mPluginPath = aPluginPath;
 
   return true;
 }
 
+mozilla::ipc::IPCResult
+GMPChild::RecvProvideStorageId(const nsCString& aStorageId)
+{
+  LOGD("%s", __FUNCTION__);
+  mStorageId = aStorageId;
+  return IPC_OK();
+}
+
 GMPErr
 GMPChild::GetAPI(const char* aAPIName,
                  void* aHostAPI,
                  void** aPluginAPI,
                  uint32_t aDecryptorId)
 {
   if (!mGMPLoader) {
     return GMPGenericErr;
--- a/dom/media/gmp/GMPChild.h
+++ b/dom/media/gmp/GMPChild.h
@@ -41,16 +41,18 @@ public:
 
 private:
   friend class GMPContentChild;
 
   bool ResolveLinks(nsCOMPtr<nsIFile>& aPath);
 
   bool GetUTF8LibPath(nsACString& aOutLibPath);
 
+  mozilla::ipc::IPCResult RecvProvideStorageId(const nsCString& aStorageId) override;
+
   mozilla::ipc::IPCResult AnswerStartPlugin(const nsString& aAdapter) override;
   mozilla::ipc::IPCResult RecvPreloadLibs(const nsCString& aLibs) override;
 
   PGMPTimerChild* AllocPGMPTimerChild() override;
   bool DeallocPGMPTimerChild(PGMPTimerChild* aActor) override;
 
   PGMPStorageChild* AllocPGMPStorageChild() override;
   bool DeallocPGMPStorageChild(PGMPStorageChild* aActor) override;
@@ -71,15 +73,16 @@ private:
 
   nsTArray<UniquePtr<GMPContentChild>> mGMPContentChildren;
 
   RefPtr<GMPTimerChild> mTimerChild;
   RefPtr<GMPStorageChild> mStorage;
 
   MessageLoop* mGMPMessageLoop;
   nsString mPluginPath;
+  nsCString mStorageId;
   UniquePtr<GMPLoader> mGMPLoader;
 };
 
 } // namespace gmp
 } // namespace mozilla
 
 #endif // GMPChild_h_
--- a/dom/media/gmp/GMPContentChild.cpp
+++ b/dom/media/gmp/GMPContentChild.cpp
@@ -300,17 +300,18 @@ GMPContentChild::RecvPChromiumCDMConstru
       return IPC_FAIL_NO_REASON(this);
     }
     cdm =
       new ChromiumCDM8BackwardsCompat(
         host9,
         static_cast<cdm::ContentDecryptionModule_8*>(cdm));
   }
 
-  child->Init(static_cast<cdm::ContentDecryptionModule_9*>(cdm));
+  child->Init(static_cast<cdm::ContentDecryptionModule_9*>(cdm),
+              mGMPChild->mStorageId);
 
   return IPC_OK();
 }
 
 void
 GMPContentChild::CloseActive()
 {
   // Invalidate and remove any remaining API objects.
--- a/dom/media/gmp/GMPParent.cpp
+++ b/dom/media/gmp/GMPParent.cpp
@@ -19,16 +19,17 @@
 #include "mozilla/SyncRunnable.h"
 #include "mozilla/Unused.h"
 #include "nsIObserverService.h"
 #include "GMPTimerParent.h"
 #include "runnable_utils.h"
 #if defined(XP_LINUX) && defined(MOZ_GMP_SANDBOX)
 #include "mozilla/SandboxInfo.h"
 #endif
+#include "CDMStorageIdProvider.h"
 #include "GMPContentParent.h"
 #include "MediaPrefs.h"
 #include "VideoUtils.h"
 
 using mozilla::ipc::GeckoChildProcessHost;
 
 using CrashReporter::AnnotationTable;
 using CrashReporter::GetIDFromMinidump;
@@ -170,16 +171,26 @@ GMPParent::LoadProcess()
     if (!opened) {
       LOGD("%s: Failed to open channel to new child process", __FUNCTION__);
       mProcess->Delete();
       mProcess = nullptr;
       return NS_ERROR_FAILURE;
     }
     LOGD("%s: Opened channel to new child process", __FUNCTION__);
 
+    // ComputeStorageId may return empty string, we leave the error handling to CDM.
+    // The CDM will reject the promise once we provide a empty string of storage id.
+    bool ok = SendProvideStorageId(
+      CDMStorageIdProvider::ComputeStorageId(mNodeId));
+    if (!ok) {
+      LOGD("%s: Failed to send storage id to child process", __FUNCTION__);
+      return NS_ERROR_FAILURE;
+    }
+    LOGD("%s: Sent storage id to child process", __FUNCTION__);
+
 #ifdef XP_WIN
     if (!mLibs.IsEmpty()) {
       bool ok = SendPreloadLibs(mLibs);
       if (!ok) {
         LOGD("%s: Failed to send preload-libs to child process", __FUNCTION__);
         return NS_ERROR_FAILURE;
       }
       LOGD("%s: Sent preload-libs ('%s') to child process", __FUNCTION__, mLibs.get());
--- a/dom/media/gmp/PGMP.ipdl
+++ b/dom/media/gmp/PGMP.ipdl
@@ -22,15 +22,16 @@ parent:
   async PGMPTimer();
   async PGMPStorage();
 
   async PGMPContentChildDestroyed();
 
 child:
   async CrashPluginNow();
   intr StartPlugin(nsString adapter);
+  async ProvideStorageId(nsCString storageId);
   async PreloadLibs(nsCString libs);
   async CloseActive();
   async InitGMPContentChild(Endpoint<PGMPContentChild> endpoint);
 };
 
 } // namespace gmp
 } // namespace mozilla