Bug 1315850 - Implement trivial cdm::Host functions. r=gerald draft
authorChris Pearce <cpearce@mozilla.com>
Mon, 13 Mar 2017 13:26:13 +1300
changeset 504157 dd262cc875ece0d82b4af002341ee0566125a401
parent 504156 7c08edea3c11d41eb3ecfa9c7a8ef65cf3b8ddb0
child 504158 94dacb5107e7f098c7dde88e6d246edb9deb6a35
push id50748
push userbmo:cpearce@mozilla.com
push dateFri, 24 Mar 2017 01:10:17 +0000
reviewersgerald
bugs1315850
milestone55.0a1
Bug 1315850 - Implement trivial cdm::Host functions. r=gerald MozReview-Commit-ID: 5OsopZbflf1
dom/media/gmp/ChromiumCDMChild.cpp
dom/media/gmp/ChromiumCDMChild.h
--- a/dom/media/gmp/ChromiumCDMChild.cpp
+++ b/dom/media/gmp/ChromiumCDMChild.cpp
@@ -1,75 +1,237 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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 "ChromiumCDMChild.h"
 #include "GMPContentChild.h"
+#include "WidevineUtils.h"
+#include "GMPLog.h"
+#include "GMPPlatform.h"
+#include "mozilla/Unused.h"
+#include "base/time.h"
 
 namespace mozilla {
 namespace gmp {
 
 ChromiumCDMChild::ChromiumCDMChild(GMPContentChild* aPlugin)
   : mPlugin(aPlugin)
 {
 }
 
 void
 ChromiumCDMChild::Init(cdm::ContentDecryptionModule_8* aCDM)
 {
   mCDM = aCDM;
   MOZ_ASSERT(mCDM);
 }
 
+void
+ChromiumCDMChild::TimerExpired(void* aContext)
+{
+  if (mCDM) {
+    mCDM->TimerExpired(aContext);
+  }
+}
+
+cdm::Buffer*
+ChromiumCDMChild::Allocate(uint32_t aCapacity)
+{
+  return new WidevineBuffer(aCapacity);
+}
+
+void
+ChromiumCDMChild::SetTimer(int64_t aDelayMs, void* aContext)
+{
+  RefPtr<ChromiumCDMChild> self(this);
+  SetTimerOnMainThread(NewGMPTask([self, aContext]() {
+    self->TimerExpired(aContext);
+  }), aDelayMs);
+}
+
+cdm::Time
+ChromiumCDMChild::GetCurrentWallTime()
+{
+  return base::Time::Now().ToDoubleT();
+}
+
+void
+ChromiumCDMChild::OnResolveNewSessionPromise(uint32_t aPromiseId,
+                                             const char* aSessionId,
+                                             uint32_t aSessionIdSize)
+{
+  Unused << SendOnResolveNewSessionPromise(aPromiseId,
+                                           nsCString(aSessionId, aSessionIdSize));
+}
+
+void ChromiumCDMChild::OnResolvePromise(uint32_t aPromiseId)
+{
+  Unused << SendOnResolvePromise(aPromiseId);
+}
+
+void
+ChromiumCDMChild::OnRejectPromise(uint32_t aPromiseId,
+                                  cdm::Error aError,
+                                  uint32_t aSystemCode,
+                                  const char* aErrorMessage,
+                                  uint32_t aErrorMessageSize)
+{
+  Unused << SendOnRejectPromise(aPromiseId,
+                                aError,
+                                aSystemCode,
+                                nsCString(aErrorMessage, aErrorMessageSize));
+}
+
+void
+ChromiumCDMChild::OnSessionMessage(const char* aSessionId,
+                                   uint32_t aSessionIdSize,
+                                   cdm::MessageType aMessageType,
+                                   const char* aMessage,
+                                   uint32_t aMessageSize,
+                                   const char* aLegacyDestinationUrl,
+                                   uint32_t aLegacyDestinationUrlLength)
+{
+  nsTArray<uint8_t> message;
+  message.AppendElements(aMessage, aMessageSize);
+  Unused << SendOnSessionMessage(nsCString(aSessionId, aSessionIdSize),
+                                 aMessageType,
+                                 message);
+}
+
+void
+ChromiumCDMChild::OnSessionKeysChange(const char *aSessionId,
+                                      uint32_t aSessionIdSize,
+                                      bool aHasAdditionalUsableKey,
+                                      const cdm::KeyInformation* aKeysInfo,
+                                      uint32_t aKeysInfoCount)
+{
+  nsTArray<CDMKeyInformation> keys;
+  keys.SetCapacity(aKeysInfoCount);
+  for (uint32_t i = 0; i < aKeysInfoCount; i++) {
+    const cdm::KeyInformation& key = aKeysInfo[i];
+    nsTArray<uint8_t> kid;
+    kid.AppendElements(key.key_id, key.key_id_size);
+    keys.AppendElement(CDMKeyInformation(kid, key.status, key.system_code));
+  }
+  Unused << SendOnSessionKeysChange(nsCString(aSessionId, aSessionIdSize),
+                                    keys);
+}
+
+void
+ChromiumCDMChild::OnExpirationChange(const char* aSessionId,
+                                     uint32_t aSessionIdSize,
+                                     cdm::Time aNewExpiryTime)
+{
+  Unused << SendOnExpirationChange(nsCString(aSessionId, aSessionIdSize),
+                                   aNewExpiryTime);
+}
+
+void
+ChromiumCDMChild::OnSessionClosed(const char* aSessionId,
+                                  uint32_t aSessionIdSize)
+{
+  Unused << SendOnSessionClosed(nsCString(aSessionId, aSessionIdSize));
+}
+
+void
+ChromiumCDMChild::OnLegacySessionError(const char* aSessionId,
+                                       uint32_t aSessionIdLength,
+                                       cdm::Error aError,
+                                       uint32_t aSystemCode,
+                                       const char* aErrorMessage,
+                                       uint32_t aErrorMessageLength)
+{
+  Unused << SendOnLegacySessionError(nsCString(aSessionId, aSessionIdLength),
+                                     aError,
+                                     aSystemCode,
+                                     nsCString(aErrorMessage, aErrorMessageLength));
+}
+
+cdm::FileIO*
+ChromiumCDMChild::CreateFileIO(cdm::FileIOClient * aClient)
+{
+  return nullptr;
+}
+
 mozilla::ipc::IPCResult
 ChromiumCDMChild::RecvInit(const bool& aAllowDistinctiveIdentifier,
                            const bool& aAllowPersistentState)
 {
+  if (mCDM) {
+    mCDM->Initialize(aAllowDistinctiveIdentifier, aAllowPersistentState);
+  }
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
 ChromiumCDMChild::RecvSetServerCertificate(const uint32_t& aPromiseId,
                                            nsTArray<uint8_t>&& aServerCert)
 
 {
+  if (mCDM) {
+    mCDM->SetServerCertificate(aPromiseId,
+                               aServerCert.Elements(),
+                               aServerCert.Length());
+  }
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
 ChromiumCDMChild::RecvCreateSessionAndGenerateRequest(
   const uint32_t& aPromiseId,
   const uint32_t& aSessionType,
   const uint32_t& aInitDataType,
   nsTArray<uint8_t>&& aInitData)
 {
+  MOZ_ASSERT(aSessionType <= cdm::SessionType::kPersistentKeyRelease);
+  MOZ_ASSERT(aInitDataType <= cdm::InitDataType::kWebM);
+  if (mCDM) {
+    mCDM->CreateSessionAndGenerateRequest(aPromiseId,
+                                          static_cast<cdm::SessionType>(aSessionType),
+                                          static_cast<cdm::InitDataType>(aInitDataType),
+                                          aInitData.Elements(),
+                                          aInitData.Length());
+  }
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
 ChromiumCDMChild::RecvUpdateSession(const uint32_t& aPromiseId,
                                     const nsCString& aSessionId,
                                     nsTArray<uint8_t>&& aResponse)
 {
+  if (mCDM) {
+    mCDM->UpdateSession(aPromiseId,
+                        aSessionId.get(),
+                        aSessionId.Length(),
+                        aResponse.Elements(),
+                        aResponse.Length());
+  }
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
 ChromiumCDMChild::RecvCloseSession(const uint32_t& aPromiseId,
                                    const nsCString& aSessionId)
 {
+  if (mCDM) {
+    mCDM->CloseSession(aPromiseId, aSessionId.get(), aSessionId.Length());
+  }
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
 ChromiumCDMChild::RecvRemoveSession(const uint32_t& aPromiseId,
                                     const nsCString& aSessionId)
 {
+  if (mCDM) {
+    mCDM->RemoveSession(aPromiseId, aSessionId.get(), aSessionId.Length());
+  }
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
 ChromiumCDMChild::RecvDecrypt(const CDMInputBuffer& aBuffer)
 {
   return IPC_OK();
 }
@@ -97,13 +259,20 @@ mozilla::ipc::IPCResult
 ChromiumCDMChild::RecvDecryptAndDecodeFrame(const CDMInputBuffer& aBuffer)
 {
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
 ChromiumCDMChild::RecvDestroy()
 {
+  if (mCDM) {
+    mCDM->Destroy();
+    mCDM = nullptr;
+  }
+
+  Unused << Send__delete__(this);
+
   return IPC_OK();
 }
 
 } // namespace gmp
 } // namespace mozilla
--- a/dom/media/gmp/ChromiumCDMChild.h
+++ b/dom/media/gmp/ChromiumCDMChild.h
@@ -2,30 +2,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 ChromiumCDMChild_h_
 #define ChromiumCDMChild_h_
 
 #include "mozilla/gmp/PChromiumCDMChild.h"
+#include "content_decryption_module.h"
 
 namespace mozilla {
 namespace gmp {
 
 class GMPContentChild;
 
 class ChromiumCDMChild : public PChromiumCDMChild
+                       , public cdm::Host_8
 {
 public:
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(ChromiumCDMChild);
 
   explicit ChromiumCDMChild(GMPContentChild* aPlugin);
 
   void Init(cdm::ContentDecryptionModule_8* aCDM);
+
+  void TimerExpired(void* aContext);
+
+  // cdm::Host_8
+  cdm::Buffer* Allocate(uint32_t aCapacity) override;
+  void SetTimer(int64_t aDelayMs, void* aContext) override;
+  cdm::Time GetCurrentWallTime() override;
+  void OnResolveNewSessionPromise(uint32_t aPromiseId,
+                                  const char* aSessionId,
+                                  uint32_t aSessionIdSize) override;
+  void OnResolvePromise(uint32_t aPromiseId) override;
+  void OnRejectPromise(uint32_t aPromiseId,
+                       cdm::Error aError,
+                       uint32_t aSystemCode,
+                       const char* aErrorMessage,
+                       uint32_t aErrorMessageSize) override;
+  void OnSessionMessage(const char* aSessionId,
+                        uint32_t aSessionIdSize,
+                        cdm::MessageType aMessageType,
+                        const char* aMessage,
+                        uint32_t aMessageSize,
+                        const char* aLegacyDestinationUrl,
+                        uint32_t aLegacyDestinationUrlLength) override;
+  void OnSessionKeysChange(const char* aSessionId,
+                           uint32_t aSessionIdSize,
+                           bool aHasAdditionalUsableKey,
+                           const cdm::KeyInformation* aKeysInfo,
+                           uint32_t aKeysInfoCount) override;
+  void OnExpirationChange(const char* aSessionId,
+                          uint32_t aSessionIdSize,
+                          cdm::Time aNewExpiryTime) override;
+  void OnSessionClosed(const char* aSessionId,
+                       uint32_t aSessionIdSize) override;
+  void OnLegacySessionError(const char* aSessionId,
+                            uint32_t aSessionIdLength,
+                            cdm::Error aError,
+                            uint32_t aSystemCode,
+                            const char* aErrorMessage,
+                            uint32_t aErrorMessageLength) override;
+  void SendPlatformChallenge(const char* aServiceId,
+                             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::FileIO* CreateFileIO(cdm::FileIOClient* aClient) override;
 protected:
   ~ChromiumCDMChild() {}
 
   ipc::IPCResult RecvInit(const bool& aAllowDistinctiveIdentifier,
                           const bool& aAllowPersistentState) override;
   ipc::IPCResult RecvSetServerCertificate(
     const uint32_t& aPromiseId,
     nsTArray<uint8_t>&& aServerCert) override;