Bug 1288976 - Only retry MediaKeySystemAccess requests on 'gmp-changed' notification if the CDM is now installed. r=gerald,a=gchang
authorChris Pearce <cpearce@mozilla.com>
Mon, 25 Jul 2016 13:38:08 +1200
changeset 340167 04a6cd9d45f98ce74288587083bf8e281c4acdbe
parent 340166 4950c39e834e6fc05f53d583bd05e6400c55cb1f
child 340168 07f644f906ca21016f8f6ebbb6e6463af5d88fea
push id6249
push userjlund@mozilla.com
push dateMon, 01 Aug 2016 13:59:36 +0000
treeherdermozilla-beta@bad9d4f5bf7e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgerald, gchang
bugs1288976
milestone49.0a2
Bug 1288976 - Only retry MediaKeySystemAccess requests on 'gmp-changed' notification if the CDM is now installed. r=gerald,a=gchang This ensures we'll only retry requests if we know the install operation has completed for a given GMP. This means if (say) OpenH264 happens to install while we have a Widevine request pending, we won't retry the Widevine request, as that would fail. The Widevine request will retry once the Widevine CDM has downloaded and in turn fires its gmp-changed notification. MozReview-Commit-ID: E3CV9uID4pS
dom/media/eme/MediaKeySystemAccessManager.cpp
--- a/dom/media/eme/MediaKeySystemAccessManager.cpp
+++ b/dom/media/eme/MediaKeySystemAccessManager.cpp
@@ -262,17 +262,40 @@ MediaKeySystemAccessManager::RetryReques
 nsresult
 MediaKeySystemAccessManager::Observe(nsISupports* aSubject,
                                      const char* aTopic,
                                      const char16_t* aData)
 {
   EME_LOG("MediaKeySystemAccessManager::Observe %s", aTopic);
 
   if (!strcmp(aTopic, "gmp-changed")) {
-    nsTArray<PendingRequest> requests(Move(mRequests));
+    // Filter out the requests where the CDM's install-status is no longer
+    // "unavailable". This will be the CDMs which have downloaded since the
+    // initial request.
+    // Note: We don't have a way to communicate from chrome that the CDM has
+    // failed to download, so we'll just let the timeout fail us in that case.
+    nsTArray<PendingRequest> requests;
+    for (size_t i = mRequests.Length(); i > 0; i--) {
+      const size_t index = i - i;
+      PendingRequest& request = mRequests[index];
+      nsAutoCString message;
+      nsAutoCString cdmVersion;
+      MediaKeySystemStatus status =
+        MediaKeySystemAccess::GetKeySystemStatus(request.mKeySystem,
+                                                 NO_CDM_VERSION,
+                                                 message,
+                                                 cdmVersion);
+      if (status == MediaKeySystemStatus::Cdm_not_installed) {
+        // Not yet installed, don't retry. Keep waiting until timeout.
+        continue;
+      }
+      // Status has changed, retry request.
+      requests.AppendElement(Move(request));
+      mRequests.RemoveElementAt(index);
+    }
     // Retry all pending requests, but this time fail if the CDM is not installed.
     for (PendingRequest& request : requests) {
       RetryRequest(request);
     }
   } else if (!strcmp(aTopic, "timer-callback")) {
     // Find the timer that expired and re-run the request for it.
     nsCOMPtr<nsITimer> timer(do_QueryInterface(aSubject));
     for (size_t i = 0; i < mRequests.Length(); i++) {