Bug 1174566 - More helpful MediaKeySystemAccess error messages. r=edwin
authorChris Pearce <cpearce@mozilla.com>
Fri, 26 Jun 2015 15:16:52 -0700
changeset 268541 fd6fb494c3493aa9c6e09eebd8e3aeaff4c49532
parent 268540 18039b7d024d89f7d136940dcb14682e777c8c9c
child 268542 3bec99cdf27ae761a8a2744f198625b51b79610b
push id4932
push userjlund@mozilla.com
push dateMon, 10 Aug 2015 18:23:06 +0000
treeherdermozilla-esr52@6dd5a4f5f745 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersedwin
bugs1174566
milestone41.0a1
Bug 1174566 - More helpful MediaKeySystemAccess error messages. r=edwin
dom/media/eme/MediaKeySystemAccess.cpp
dom/media/eme/MediaKeySystemAccess.h
dom/media/eme/MediaKeySystemAccessManager.cpp
--- a/dom/media/eme/MediaKeySystemAccess.cpp
+++ b/dom/media/eme/MediaKeySystemAccess.cpp
@@ -136,101 +136,117 @@ AdobePluginVoucherExists(const nsACStrin
 {
   return AdobePluginFileExists(aVersionStr, NS_LITERAL_STRING("eme-adobe.voucher"));
 }
 #endif
 
 static MediaKeySystemStatus
 EnsureMinCDMVersion(mozIGeckoMediaPluginService* aGMPService,
                     const nsAString& aKeySystem,
-                    int32_t aMinCdmVersion)
+                    int32_t aMinCdmVersion,
+                    nsACString& aOutMessage)
 {
   nsTArray<nsCString> tags;
   tags.AppendElement(NS_ConvertUTF16toUTF8(aKeySystem));
   bool hasPlugin;
   nsAutoCString versionStr;
   if (NS_FAILED(aGMPService->GetPluginVersionForAPI(NS_LITERAL_CSTRING(GMP_API_DECRYPTOR),
                                                     &tags,
                                                     &hasPlugin,
                                                     versionStr))) {
+    aOutMessage = NS_LITERAL_CSTRING("GetPluginVersionForAPI failed");
     return MediaKeySystemStatus::Error;
   }
 
   if (!hasPlugin) {
+    aOutMessage = NS_LITERAL_CSTRING("CDM is not installed");
     return MediaKeySystemStatus::Cdm_not_installed;
   }
 
   if (aMinCdmVersion == NO_CDM_VERSION) {
     return MediaKeySystemStatus::Available;
   }
 
   nsresult rv;
   int32_t version = versionStr.ToInteger(&rv);
   if (NS_FAILED(rv) || version < 0 || aMinCdmVersion > version) {
+    aOutMessage = NS_LITERAL_CSTRING("Installed CDM version insufficient");
     return MediaKeySystemStatus::Cdm_insufficient_version;
   }
 
 #ifdef XP_WIN
   if (aKeySystem.EqualsLiteral("com.adobe.access") ||
       aKeySystem.EqualsLiteral("com.adobe.primetime")) {
     // Verify that anti-virus hasn't "helpfully" deleted the Adobe GMP DLL,
     // as we suspect may happen (Bug 1160382).
-    if (!AdobePluginDLLExists(versionStr) ||
-        !AdobePluginVoucherExists(versionStr)) {
+    bool somethingMissing = false;
+    if (!AdobePluginDLLExists(versionStr)) {
+      aOutMessage = NS_LITERAL_CSTRING("Adobe DLL was expected to be on disk but was not");
+      somethingMissing = true;
+    }
+    if (!AdobePluginVoucherExists(versionStr)) {
+      aOutMessage = NS_LITERAL_CSTRING("Adobe plugin voucher was expected to be on disk but was not");
+      somethingMissing = true;
+    }
+    if (somethingMissing) {    
       NS_WARNING("Adobe EME plugin or voucher disappeared from disk!");
       // Reset the prefs that Firefox's GMP downloader sets, so that
       // Firefox will try to download the plugin next time the updater runs.
       Preferences::ClearUser("media.gmp-eme-adobe.lastUpdate");
       Preferences::ClearUser("media.gmp-eme-adobe.version");
       return MediaKeySystemStatus::Cdm_not_installed;
     }
   }
 #endif
 
   return MediaKeySystemStatus::Available;
 }
 
 /* static */
 MediaKeySystemStatus
 MediaKeySystemAccess::GetKeySystemStatus(const nsAString& aKeySystem,
-                                         int32_t aMinCdmVersion)
+                                         int32_t aMinCdmVersion,
+                                         nsACString& aOutMessage)
 {
   MOZ_ASSERT(Preferences::GetBool("media.eme.enabled", false));
   nsCOMPtr<mozIGeckoMediaPluginService> mps =
     do_GetService("@mozilla.org/gecko-media-plugin-service;1");
   if (NS_WARN_IF(!mps)) {
+    aOutMessage = NS_LITERAL_CSTRING("Failed to get GMP service");
     return MediaKeySystemStatus::Error;
   }
 
   if (aKeySystem.EqualsLiteral("org.w3.clearkey")) {
     if (!Preferences::GetBool("media.eme.clearkey.enabled", true)) {
+      aOutMessage = NS_LITERAL_CSTRING("ClearKey was disabled");
       return MediaKeySystemStatus::Cdm_disabled;
     }
-    return EnsureMinCDMVersion(mps, aKeySystem, aMinCdmVersion);
+    return EnsureMinCDMVersion(mps, aKeySystem, aMinCdmVersion, aOutMessage);
   }
 
 #ifdef XP_WIN
   if ((aKeySystem.EqualsLiteral("com.adobe.access") ||
        aKeySystem.EqualsLiteral("com.adobe.primetime"))) {
     // Win Vista and later only.
     if (!IsVistaOrLater()) {
+      aOutMessage = NS_LITERAL_CSTRING("Minimum Windows version not met for Adobe EME");
       return MediaKeySystemStatus::Cdm_not_supported;
     }
     if (!Preferences::GetBool("media.gmp-eme-adobe.enabled", false)) {
+      aOutMessage = NS_LITERAL_CSTRING("Adobe EME disabled");
       return MediaKeySystemStatus::Cdm_disabled;
     }
-    if (!MP4Decoder::CanCreateH264Decoder() ||
-        !MP4Decoder::CanCreateAACDecoder() ||
-        !EMEVoucherFileExists()) {
+    if (!EMEVoucherFileExists()) {
       // The system doesn't have the codecs that Adobe EME relies
       // on installed, or doesn't have a voucher for the plugin-container.
       // Adobe EME isn't going to work, so don't advertise that it will.
+      aOutMessage = NS_LITERAL_CSTRING("Plugin-container voucher not present");
       return MediaKeySystemStatus::Cdm_not_supported;
     }
-    return EnsureMinCDMVersion(mps, aKeySystem, aMinCdmVersion);
+    return EnsureMinCDMVersion(mps, aKeySystem, aMinCdmVersion, aOutMessage);
   }
 #endif
 
   return MediaKeySystemStatus::Cdm_not_supported;
 }
 
 static bool
 IsPlayableWithGMP(mozIGeckoMediaPluginService* aGMPS,
--- a/dom/media/eme/MediaKeySystemAccess.h
+++ b/dom/media/eme/MediaKeySystemAccess.h
@@ -39,18 +39,21 @@ public:
   nsPIDOMWindow* GetParentObject() const;
 
   virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
 
   void GetKeySystem(nsString& aRetVal) const;
 
   already_AddRefed<Promise> CreateMediaKeys(ErrorResult& aRv);
 
+
+
   static MediaKeySystemStatus GetKeySystemStatus(const nsAString& aKeySystem,
-                                                 int32_t aMinCdmVersion);
+                                                 int32_t aMinCdmVersion,
+                                                 nsACString& aOutExceptionMessage);
 
   static bool IsSupported(const nsAString& aKeySystem,
                           const Sequence<MediaKeySystemOptions>& aOptions);
 
   static void NotifyObservers(nsIDOMWindow* aWindow,
                               const nsAString& aKeySystem,
                               MediaKeySystemStatus aStatus);
 
--- a/dom/media/eme/MediaKeySystemAccessManager.cpp
+++ b/dom/media/eme/MediaKeySystemAccessManager.cpp
@@ -100,17 +100,18 @@ MediaKeySystemAccessManager::Request(Det
     // Invalid keySystem string, or unsupported keySystem. Send notification
     // to chrome to show a failure notice.
     MediaKeySystemAccess::NotifyObservers(mWindow, aKeySystem, MediaKeySystemStatus::Cdm_not_supported);
     aPromise->MaybeReject(NS_ERROR_DOM_NOT_SUPPORTED_ERR,
                           NS_LITERAL_CSTRING("Key system string is invalid, or key system is unsupported"));
     return;
   }
 
-  MediaKeySystemStatus status = MediaKeySystemAccess::GetKeySystemStatus(keySystem, minCdmVersion);
+  nsAutoCString message;
+  MediaKeySystemStatus status = MediaKeySystemAccess::GetKeySystemStatus(keySystem, minCdmVersion, message);
   if ((status == MediaKeySystemStatus::Cdm_not_installed ||
        status == MediaKeySystemStatus::Cdm_insufficient_version) &&
       keySystem.EqualsLiteral("com.adobe.primetime")) {
     // These are cases which could be resolved by downloading a new(er) CDM.
     // When we send the status to chrome, chrome's GMPProvider will attempt to
     // download or update the CDM. In AwaitInstall() we add listeners to wait
     // for the update to complete, and we'll call this function again with
     // aType==Subsequent once the download has completed and the GMPService