Bug 1156560 - Prefer old CDMs on update if they are in use. r=cpearce, ba=sledru
authorEdwin Flores <eflores@mozilla.com>
Mon, 20 Apr 2015 20:54:00 -0400
changeset 260255 7c66212e4c09
parent 260254 98086516ce8f
child 260256 d20a4e36e508
push id727
push userryanvm@gmail.com
push date2015-04-23 14:45 +0000
treeherdermozilla-release@7c66212e4c09 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerscpearce
bugs1156560
milestone38.0
Bug 1156560 - Prefer old CDMs on update if they are in use. r=cpearce, ba=sledru
dom/media/eme/CDMProxy.cpp
dom/media/gmp/GMPService.cpp
dom/media/gmp/mozIGeckoMediaPluginService.idl
dom/media/gtest/TestGMPCrossOrigin.cpp
--- a/dom/media/eme/CDMProxy.cpp
+++ b/dom/media/eme/CDMProxy.cpp
@@ -93,31 +93,20 @@ CDMProxy::gmp_Init(nsAutoPtr<InitData> a
     RejectPromise(aData->mPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR);
     return;
   }
 
   nsCString version;
   nsTArray<nsCString> tags;
   tags.AppendElement(NS_ConvertUTF16toUTF8(mKeySystem));
 
-  // Add plugin version string to node ID so that we get the same
-  // CDM every time during a stream's playback.
-  nsresult rv =
-    mps->GetPluginVersionForAPI(NS_LITERAL_CSTRING(GMP_API_DECRYPTOR),
-                                &tags, version);
-  if (NS_FAILED(rv)) {
-    RejectPromise(aData->mPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR);
-    return;
-  }
-
-  rv = mps->GetNodeId(aData->mOrigin,
-                      aData->mTopLevelOrigin,
-                      aData->mInPrivateBrowsing,
-                      version,
-                      mNodeId);
+  nsresult rv = mps->GetNodeId(aData->mOrigin,
+                               aData->mTopLevelOrigin,
+                               aData->mInPrivateBrowsing,
+                               mNodeId);
 
   MOZ_ASSERT(!GetNodeId().IsEmpty());
   if (NS_FAILED(rv)) {
     RejectPromise(aData->mPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR);
     return;
   }
 
   EME_LOG("CDMProxy::gmp_Init (%s, %s) %s NodeId=%s",
--- a/dom/media/gmp/GMPService.cpp
+++ b/dom/media/gmp/GMPService.cpp
@@ -883,19 +883,27 @@ GeckoMediaPluginService::SelectPluginFor
           return gmp;
         }
       } else if (gmp->CanBeUsedFrom(aNodeId)) {
         MOZ_ASSERT(!aNodeId.IsEmpty());
         gmp->SetNodeId(aNodeId);
         return gmp;
       }
 
-      // This GMP has the correct type but has the wrong nodeId; hold on to it
-      // in case we need to clone it.
-      gmpToClone = gmp;
+      if (!gmpToClone ||
+          (gmpToClone->IsMarkedForDeletion() && !gmp->IsMarkedForDeletion())) {
+        // This GMP has the correct type but has the wrong nodeId; hold on to it
+        // in case we need to clone it.
+        // Prefer GMPs in-use for the case where an upgraded plugin version is
+        // waiting for the old one to die. If the old plugin is in use, we
+        // should continue using it so that any persistent state remains
+        // consistent. Otherwise, just check that the plugin isn't scheduled
+        // for deletion.
+        gmpToClone = gmp;
+      }
       // Loop around and try the next plugin; it may be usable from aNodeId.
       index++;
     }
   }
 
   // Plugin exists, but we can't use it due to cross-origin separation. Create a
   // new one.
   if (gmpToClone) {
@@ -1208,17 +1216,16 @@ GeckoMediaPluginService::IsPersistentSto
   *aOutAllowed = mPersistentStorageAllowed.Get(aNodeId);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 GeckoMediaPluginService::GetNodeId(const nsAString& aOrigin,
                                    const nsAString& aTopLevelOrigin,
                                    bool aInPrivateBrowsing,
-                                   const nsACString& aVersion,
                                    nsACString& aOutId)
 {
   MOZ_ASSERT(NS_GetCurrentThread() == mGMPThread);
   LOGD(("%s::%s: (%s, %s), %s", __CLASS__, __FUNCTION__,
        NS_ConvertUTF16toUTF8(aOrigin).get(),
        NS_ConvertUTF16toUTF8(aTopLevelOrigin).get(),
        (aInPrivateBrowsing ? "PrivateBrowsing" : "NonPrivateBrowsing")));
 
@@ -1242,18 +1249,17 @@ GeckoMediaPluginService::GetNodeId(const
       return rv;
     }
     aOutId = salt;
     mPersistentStorageAllowed.Put(salt, false);
     return NS_OK;
   }
 
   const uint32_t hash = AddToHash(HashString(aOrigin),
-                                  HashString(aTopLevelOrigin),
-                                  HashString(aVersion));
+                                  HashString(aTopLevelOrigin));
 
   if (aInPrivateBrowsing) {
     // For PB mode, we store the node id, indexed by the origin pair,
     // so that if the same origin pair is opened in this session, it gets
     // the same node id.
     nsCString* salt = nullptr;
     if (!(salt = mTempNodeIds.Get(hash))) {
       // No salt stored, generate and temporarily store some for this id.
--- a/dom/media/gmp/mozIGeckoMediaPluginService.idl
+++ b/dom/media/gmp/mozIGeckoMediaPluginService.idl
@@ -21,17 +21,17 @@ class GMPVideoHost;
 [ptr] native GMPVideoDecoderProxy(GMPVideoDecoderProxy);
 [ptr] native GMPVideoEncoderProxy(GMPVideoEncoderProxy);
 [ptr] native GMPVideoHost(GMPVideoHost);
 [ptr] native MessageLoop(MessageLoop);
 [ptr] native TagArray(nsTArray<nsCString>);
 [ptr] native GMPDecryptorProxy(GMPDecryptorProxy);
 [ptr] native GMPAudioDecoderProxy(GMPAudioDecoderProxy);
 
-[scriptable, uuid(d520197c-efcf-47c7-8ef9-1589d0c0f588)]
+[scriptable, uuid(46c7cd80-a19d-49e7-a147-ca314ad8d8b0)]
 interface mozIGeckoMediaPluginService : nsISupports
 {
 
   /**
    * The GMP thread. Callable from any thread.
    */
   readonly attribute nsIThread thread;
 
@@ -105,18 +105,17 @@ interface mozIGeckoMediaPluginService : 
   void removeAndDeletePluginDirectory(in AString directory,
                                       [optional] in bool defer);
 
   /**
    * Gets the NodeId for a (origin, urlbarOrigin, isInprivateBrowsing) tuple.
    */
   ACString getNodeId(in AString origin,
                      in AString topLevelOrigin,
-                     in bool inPrivateBrowsingMode,
-                     in ACString version);
+                     in bool inPrivateBrowsingMode);
 
   /**
    * Clears storage data associated with the site.
    */
   void forgetThisSite(in AString site);
 
   /**
    * Returns true if the given node id is allowed to store things
--- a/dom/media/gtest/TestGMPCrossOrigin.cpp
+++ b/dom/media/gtest/TestGMPCrossOrigin.cpp
@@ -319,17 +319,16 @@ GetNodeId(const nsAString& aOrigin,
 {
   nsRefPtr<GeckoMediaPluginService> service =
     GeckoMediaPluginService::GetGeckoMediaPluginService();
   EXPECT_TRUE(service);
   nsCString nodeId;
   nsresult rv = service->GetNodeId(aOrigin,
                                    aTopLevelOrigin,
                                    aInPBMode,
-                                   NS_LITERAL_CSTRING(""),
                                    nodeId);
   EXPECT_TRUE(NS_SUCCEEDED(rv));
   return nodeId;
 }
 
 static bool
 IsGMPStorageIsEmpty()
 {