Bug 1174566 - More helpful MediaKeySystemAccess error messages. r=edwin
authorChris Pearce <cpearce@mozilla.com>
Fri, 26 Jun 2015 15:16:52 -0700
changeset 250352 fd6fb494c3493aa9c6e09eebd8e3aeaff4c49532
parent 250351 18039b7d024d89f7d136940dcb14682e777c8c9c
child 250353 3bec99cdf27ae761a8a2744f198625b51b79610b
push id61529
push usercpearce@mozilla.com
push dateFri, 26 Jun 2015 22:16:54 +0000
treeherdermozilla-inbound@fd6fb494c349 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersedwin
bugs1174566
milestone41.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 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