Bug 1396493 - Part2 - Modify the gtest to adapt to the interface change. r=cpearce
authorJames Cheng <jacheng@mozilla.com>
Mon, 25 Sep 2017 17:40:01 +0800
changeset 383437 2dcc72594553867e363631189577fb6140045af0
parent 383436 4dcf9f51015d7df4a374922634378586509aa265
child 383438 8e98418e6c1b2998c9d497afce270442b75d41a9
push id32594
push userkwierso@gmail.com
push dateThu, 28 Sep 2017 22:49:33 +0000
treeherdermozilla-central@6dea0ee45b66 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerscpearce
bugs1396493
milestone58.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 1396493 - Part2 - Modify the gtest to adapt to the interface change. r=cpearce 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&>(