Bug 1420836 - Part2 - Pass the storage id from content process to GMP process then provide it to CDM.
MozReview-Commit-ID: 2VFNHaL5p73
--- 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