Bug 1396493 - Part2 - Modify the gtest to adapt to the interface change. draft
authorJames Cheng <jacheng@mozilla.com>
Mon, 25 Sep 2017 17:40:01 +0800
changeset 670352 b2cbc117e54947aa7163aed9bb90e73dddddb0f9
parent 670351 df92689679f72679f776822e2667fba2bd78829a
child 670353 8aed548ff61ec0cff6518c3bb67e4f598af142f3
push id81609
push userbmo:jacheng@mozilla.com
push dateTue, 26 Sep 2017 10:07:10 +0000
bugs1396493
milestone58.0a1
Bug 1396493 - Part2 - Modify the gtest to adapt to the interface change. MozReview-Commit-ID: FyuXeSipeRV
dom/media/gtest/TestGMPCrossOrigin.cpp
--- a/dom/media/gtest/TestGMPCrossOrigin.cpp
+++ b/dom/media/gtest/TestGMPCrossOrigin.cpp
@@ -3,30 +3,32 @@
 /* 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 "gtest/gtest.h"
 #include "nsIObserverService.h"
 #include "mozilla/Services.h"
 #include "mozilla/StaticPtr.h"
+#include "ChromiumCDMCallback.h"
 #include "GMPTestMonitor.h"
 #include "GMPVideoDecoderProxy.h"
 #include "GMPVideoEncoderProxy.h"
 #include "GMPDecryptorProxy.h"
 #include "GMPServiceParent.h"
 #include "MediaPrefs.h"
 #include "nsAppDirectoryServiceDefs.h"
 #include "nsIFile.h"
 #include "nsISimpleEnumerator.h"
 #include "mozilla/Atomics.h"
 #include "nsNSSComponent.h"
 #include "mozilla/DebugOnly.h"
 #include "mozilla/dom/MediaKeyStatusMapBinding.h" // For MediaKeyStatus
 #include "mozilla/dom/MediaKeyMessageEventBinding.h" // For MediaKeyMessageType
+#include "nsThreadUtils.h"
 
 using namespace std;
 
 using namespace mozilla;
 using namespace mozilla::gmp;
 
 struct GMPTestRunner
 {
@@ -232,16 +234,23 @@ GetGMPThread()
 {
   RefPtr<GeckoMediaPluginService> service =
     GeckoMediaPluginService::GetGeckoMediaPluginService();
   nsCOMPtr<nsIThread> thread;
   EXPECT_TRUE(NS_SUCCEEDED(service->GetThread(getter_AddRefs(thread))));
   return thread.forget();
 }
 
+static RefPtr<AbstractThread>
+GetAbstractGMPThread()
+{
+  RefPtr<GeckoMediaPluginService> service =
+    GeckoMediaPluginService::GetGeckoMediaPluginService();
+  return service->GetAbstractGMPThread();
+}
 /**
  * Enumerate files under |aPath| (non-recursive).
  */
 template<typename T>
 static nsresult
 EnumerateDir(nsIFile* aPath, T&& aDirIter)
 {
   nsCOMPtr<nsISimpleEnumerator> iter;
@@ -453,16 +462,38 @@ public:
     mNodeId = aNodeId;
   }
 
 private:
   nsCString& mNodeId;
   nsresult& mResult;
 };
 
+static NodeId
+GetNodeId(const nsAString& aOrigin,
+          const nsAString& aTopLevelOrigin,
+          const nsAString & aGmpName,
+          bool aInPBMode)
+{
+  OriginAttributes attrs;
+  attrs.mPrivateBrowsingId = aInPBMode ? 1 : 0;
+
+  nsAutoCString suffix;
+  attrs.CreateSuffix(suffix);
+
+  nsAutoString origin;
+  origin.Assign(aOrigin);
+  origin.Append(NS_ConvertUTF8toUTF16(suffix));
+
+  nsAutoString topLevelOrigin;
+  topLevelOrigin.Assign(aTopLevelOrigin);
+  topLevelOrigin.Append(NS_ConvertUTF8toUTF16(suffix));
+  return NodeId(origin, topLevelOrigin, aGmpName);
+}
+
 static nsCString
 GetNodeId(const nsAString& aOrigin,
           const nsAString& aTopLevelOrigin,
           bool aInPBMode)
 {
   RefPtr<GeckoMediaPluginServiceParent> service =
     GeckoMediaPluginServiceParent::GetSingleton();
   EXPECT_TRUE(service);
@@ -521,41 +552,40 @@ AssertIsOnGMPThread()
   service->GetThread(getter_AddRefs(thread));
   MOZ_ASSERT(thread);
   nsCOMPtr<nsIThread> currentThread;
   DebugOnly<nsresult> rv = NS_GetCurrentThread(getter_AddRefs(currentThread));
   MOZ_ASSERT(NS_SUCCEEDED(rv));
   MOZ_ASSERT(currentThread == thread);
 }
 
-class GMPStorageTest : public GMPDecryptorProxyCallback
+class GMPStorageTest
 {
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(GMPStorageTest)
 
   void DoTest(void (GMPStorageTest::*aTestMethod)()) {
     EnsureNSSInitializedChromeOrContent();
     nsCOMPtr<nsIThread> thread(GetGMPThread());
     ClearGMPStorage(
       NewRunnableMethod("GMPStorageTest::DoTest", this, aTestMethod), thread);
     AwaitFinished();
   }
 
   GMPStorageTest()
-    : mDecryptor(nullptr)
-    , mMonitor("GMPStorageTest")
+    : mMonitor("GMPStorageTest")
     , mFinished(false)
   {
   }
 
   void
   Update(const nsCString& aMessage)
   {
     nsTArray<uint8_t> msg;
     msg.AppendElements(aMessage.get(), aMessage.Length());
-    mDecryptor->UpdateSession(1, NS_LITERAL_CSTRING("fake-session-id"), msg);
+    mCDM->UpdateSession(NS_LITERAL_CSTRING("fake-session-id"), 1, msg);
   }
 
   void TestGetNodeId()
   {
     AssertIsOnGMPThread();
 
     EXPECT_TRUE(IsGMPStorageIsEmpty());
 
@@ -603,109 +633,59 @@ class GMPStorageTest : public GMPDecrypt
     const nsString origin1 = NS_LITERAL_STRING("http://example1.com");
     const nsString origin2 = NS_LITERAL_STRING("http://example2.org");
     nsCString nodeId3 = GetNodeId(origin1, origin2, false);
     EXPECT_TRUE(!aNodeId1.Equals(nodeId3));
 
     SetFinished();
   }
 
-  class CreateDecryptorDone : public GetGMPDecryptorCallback
-  {
-  public:
-    explicit CreateDecryptorDone(GMPStorageTest* aRunner)
-      : mRunner(aRunner)
-    {
-    }
-
-    void Done(GMPDecryptorProxy* aDecryptor) override
-    {
-      mRunner->mDecryptor = aDecryptor;
-      EXPECT_TRUE(!!mRunner->mDecryptor);
-
-      if (mRunner->mDecryptor) {
-        mRunner->mDecryptor->Init(mRunner, false, true);
-      }
-    }
-
-  private:
-    RefPtr<GMPStorageTest> mRunner;
-  };
-
-  void CreateDecryptor(const nsCString& aNodeId,
-                       const nsCString& aUpdate)
-  {
-    nsTArray<nsCString> updates;
-    updates.AppendElement(aUpdate);
-    nsCOMPtr<nsIRunnable> continuation(new Updates(this, Move(updates)));
-    CreateDecryptor(aNodeId, continuation);
-  }
-
   void CreateDecryptor(const nsAString& aOrigin,
                        const nsAString& aTopLevelOrigin,
                        bool aInPBMode,
                        const nsCString& aUpdate)
   {
     nsTArray<nsCString> updates;
     updates.AppendElement(aUpdate);
     CreateDecryptor(aOrigin, aTopLevelOrigin, aInPBMode, Move(updates));
   }
-  class Updates : public Runnable
-  {
-  public:
-    Updates(GMPStorageTest* aRunner, nsTArray<nsCString>&& aUpdates)
-      : mozilla::Runnable("GMPStorageTest::Updates")
-      , mRunner(aRunner)
-      , mUpdates(Move(aUpdates))
-    {
-    }
 
-    NS_IMETHOD Run() override
-    {
-      for (auto& update : mUpdates) {
-        mRunner->Update(update);
-      }
-      return NS_OK;
-    }
-
-  private:
-    RefPtr<GMPStorageTest> mRunner;
-    nsTArray<nsCString> mUpdates;
-  };
   void CreateDecryptor(const nsAString& aOrigin,
                        const nsAString& aTopLevelOrigin,
                        bool aInPBMode,
                        nsTArray<nsCString>&& aUpdates) {
-    nsCOMPtr<nsIRunnable> updates(new Updates(this, Move(aUpdates)));
-    CreateDecryptor(GetNodeId(aOrigin, aTopLevelOrigin, aInPBMode), updates);
+    CreateDecryptor(GetNodeId(aOrigin, aTopLevelOrigin, NS_LITERAL_STRING("gmp-fake"), aInPBMode), Move(aUpdates));
   }
 
-  void CreateDecryptor(const nsCString& aNodeId,
-                       nsIRunnable* aContinuation) {
+  void CreateDecryptor(const NodeId& aNodeId,
+                       nsTArray<nsCString>&& aUpdates) {
     RefPtr<GeckoMediaPluginService> service =
       GeckoMediaPluginService::GetGeckoMediaPluginService();
     EXPECT_TRUE(service);
 
-    mNodeId = aNodeId;
-    EXPECT_TRUE(!mNodeId.IsEmpty());
-
     nsTArray<nsCString> tags;
     tags.AppendElement(NS_LITERAL_CSTRING("fake"));
 
-    UniquePtr<GetGMPDecryptorCallback> callback(
-      new CreateDecryptorDone(this));
+    RefPtr<GMPStorageTest> self = this;
+    RefPtr<gmp::GetCDMParentPromise> promise =
+          service->GetCDM(aNodeId, Move(tags), nullptr);
+    auto thread = GetAbstractGMPThread();
+    promise->Then(thread,
+                  __func__,
+                  [self, aUpdates](RefPtr<gmp::ChromiumCDMParent> cdm) {
+                    self->mCDM = cdm;
+                    EXPECT_TRUE(!!self->mCDM);
+                    self->mCallback.reset(new CallbackProxy(self));
+                    self->mCDM->Init(self->mCallback.get(), false, true, GetMainThreadEventTarget());
 
-    // Continue after the OnSetDecryptorId message, so that we don't
-    // get warnings in the async shutdown tests due to receiving the
-    // SetDecryptorId message after we've started shutdown.
-    mSetDecryptorIdContinuation = aContinuation;
-
-    nsresult rv =
-      service->GetGMPDecryptor(nullptr, &tags, mNodeId, Move(callback));
-    EXPECT_TRUE(NS_SUCCEEDED(rv));
+                    for (auto& update : aUpdates) {
+                      self->Update(update);
+                    }
+                  },
+                  [](nsresult rv) { EXPECT_TRUE(false); });
   }
 
   void TestBasicStorage() {
     AssertIsOnGMPThread();
     EXPECT_TRUE(IsGMPStorageIsEmpty());
 
     RefPtr<GeckoMediaPluginService> service =
       GeckoMediaPluginService::GetGeckoMediaPluginService();
@@ -1043,17 +1023,17 @@ class GMPStorageTest : public GMPDecrypt
     EXPECT_TRUE(NS_SUCCEEDED(rv));
     // There should be one directory under $profileDir/gmp/$platform/gmp-fake/storage/
     EXPECT_EQ(c2.GetCount(), 1);
 
     SetFinished();
   }
 
   void TestCrossOriginStorage() {
-    EXPECT_TRUE(!mDecryptor);
+    EXPECT_TRUE(!mCDM);
 
     // Send the decryptor the message "store recordid $time"
     // Wait for the decrytor to send us "stored recordid $time"
     auto t = time(0);
     nsCString response("stored crossOriginTestRecordId ");
     response.AppendInt((int64_t)t);
     Expect(response,
            NewRunnableMethod(
@@ -1203,103 +1183,71 @@ class GMPStorageTest : public GMPDecrypt
   }
 
   void AwaitFinished() {
     mozilla::SpinEventLoopUntil([&]() -> bool { return mFinished; });
     mFinished = false;
   }
 
   void ShutdownThen(already_AddRefed<nsIRunnable> aContinuation) {
-    EXPECT_TRUE(!!mDecryptor);
-    if (!mDecryptor) {
+    EXPECT_TRUE(!!mCDM);
+    if (!mCDM) {
       return;
     }
     EXPECT_FALSE(mNodeId.IsEmpty());
     RefPtr<GMPShutdownObserver> task(new GMPShutdownObserver(
       NewRunnableMethod(
         "GMPStorageTest::Shutdown", this, &GMPStorageTest::Shutdown),
       Move(aContinuation),
       mNodeId));
     SystemGroup::Dispatch(TaskCategory::Other, task.forget());
   }
 
   void Shutdown() {
-    if (mDecryptor) {
-      mDecryptor->Close();
-      mDecryptor = nullptr;
+    if (mCDM) {
+      mCDM->Shutdown();
+      mCDM = nullptr;
       mNodeId = EmptyCString();
     }
   }
 
   void Dummy() {
   }
 
   void SetFinished() {
     mFinished = true;
     Shutdown();
     nsCOMPtr<nsIRunnable> task =
       NewRunnableMethod("GMPStorageTest::Dummy", this, &GMPStorageTest::Dummy);
     SystemGroup::Dispatch(TaskCategory::Other, task.forget());
   }
 
-  void SessionMessage(const nsCString& aSessionId,
-                      mozilla::dom::MediaKeyMessageType aMessageType,
-                      const nsTArray<uint8_t>& aMessage) override
+  void SessionMessage(const nsACString& aSessionId,
+                      uint32_t aMessageType,
+                      const nsTArray<uint8_t>& aMessage)
   {
     MonitorAutoLock mon(mMonitor);
 
     nsCString msg((const char*)aMessage.Elements(), aMessage.Length());
     EXPECT_TRUE(mExpected.Length() > 0);
     bool matches = mExpected[0].mMessage.Equals(msg);
     EXPECT_STREQ(mExpected[0].mMessage.get(), msg.get());
     if (mExpected.Length() > 0 && matches) {
       nsCOMPtr<nsIRunnable> continuation = mExpected[0].mContinuation;
       mExpected.RemoveElementAt(0);
       if (continuation) {
         NS_DispatchToCurrentThread(continuation);
       }
     }
   }
 
-  void SetDecryptorId(uint32_t aId) override
-  {
-    if (!mSetDecryptorIdContinuation) {
-      return;
-    }
-    nsCOMPtr<nsIThread> thread(GetGMPThread());
-    thread->Dispatch(mSetDecryptorIdContinuation, NS_DISPATCH_NORMAL);
-    mSetDecryptorIdContinuation = nullptr;
-  }
-
-  void SetSessionId(uint32_t aCreateSessionToken,
-                    const nsCString& aSessionId) override { }
-  void ResolveLoadSessionPromise(uint32_t aPromiseId,
-                                 bool aSuccess) override {}
-  void ResolvePromise(uint32_t aPromiseId) override {}
-  void RejectPromise(uint32_t aPromiseId,
-                     nsresult aException,
-                     const nsCString& aSessionId) override { }
-  void ExpirationChange(const nsCString& aSessionId,
-                        UnixTime aExpiryTime) override {}
-  void SessionClosed(const nsCString& aSessionId) override {}
-  void SessionError(const nsCString& aSessionId,
-                    nsresult aException,
-                    uint32_t aSystemCode,
-                    const nsCString& aMessage) override {}
-  void Decrypted(uint32_t aId,
-                 mozilla::DecryptStatus aResult,
-                 const nsTArray<uint8_t>& aDecryptedData) override { }
-
-  void BatchedKeyStatusChanged(const nsCString& aSessionId,
-                               const nsTArray<CDMKeyInfo>& aKeyInfos) override { }
-
-  void Terminated() override {
-    if (mDecryptor) {
-      mDecryptor->Close();
-      mDecryptor = nullptr;
+  void Terminated() {
+    if (mCDM) {
+      mCDM->Shutdown();
+      mCDM = nullptr;
     }
   }
 
 private:
   ~GMPStorageTest() { }
 
   struct ExpectedMessage {
     ExpectedMessage(const nsCString& aMessage, already_AddRefed<nsIRunnable> aContinuation)
@@ -1310,20 +1258,73 @@ private:
     nsCOMPtr<nsIRunnable> mContinuation;
   };
 
   nsTArray<ExpectedMessage> mExpected;
 
   RefPtr<nsIRunnable> mSetDecryptorIdContinuation;
 
   GMPDecryptorProxy* mDecryptor;
+  RefPtr<gmp::ChromiumCDMParent> mCDM;
   Monitor mMonitor;
   Atomic<bool> mFinished;
   nsCString mNodeId;
-};
+
+  class CallbackProxy : public ChromiumCDMCallback {
+  public:
+
+    CallbackProxy(GMPStorageTest* aRunner)
+      : mRunner(aRunner)
+    {
+    }
+
+    void SetSessionId(uint32_t aPromiseId,
+                      const nsCString& aSessionId) override { }
+
+    void ResolveLoadSessionPromise(uint32_t aPromiseId,
+                                   bool aSuccessful) override { }
+
+    void ResolvePromise(uint32_t aPromiseId) override { }
+
+    void RejectPromise(uint32_t aPromiseId,
+                       nsresult aError,
+                       const nsCString& aErrorMessage) override {  }
+
+    void SessionMessage(const nsACString& aSessionId,
+                        uint32_t aMessageType,
+                        nsTArray<uint8_t>&& aMessage) override
+    {
+      mRunner->SessionMessage(aSessionId, aMessageType, Move(aMessage));
+    }
+
+    void SessionKeysChange(const nsCString& aSessionId,
+                           nsTArray<mozilla::gmp::CDMKeyInformation>&& aKeysInfo) override { }
+
+    void ExpirationChange(const nsCString& aSessionId,
+                          double aSecondsSinceEpoch) override { }
+
+    void SessionClosed(const nsCString& aSessionId) override { }
+
+    void LegacySessionError(const nsCString& aSessionId,
+                            nsresult aError,
+                            uint32_t aSystemCode,
+                            const nsCString& aMessage) override { }
+
+    void Terminated() override { mRunner->Terminated(); }
+
+    void Shutdown() override { mRunner->Shutdown(); }
+
+  private:
+
+    // Warning: Weak ref.
+    GMPStorageTest* mRunner;
+  };
+
+  UniquePtr<CallbackProxy> mCallback;
+}; // class GMPStorageTest
 
 void
 GMPTestRunner::DoTest(void (GMPTestRunner::*aTestMethod)(GMPTestMonitor&))
 {
   nsCOMPtr<nsIThread> thread(GetGMPThread());
 
   GMPTestMonitor monitor;
   thread->Dispatch(NewRunnableMethod<GMPTestMonitor&>(