/* static */
MediaKeySystemStatus
MediaKeySystemAccess::GetKeySystemStatus(const nsAString& aKeySystem,
                                         int32_t aMinCdmVersion)
{
  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)) {
    return MediaKeySystemStatus::Error;
  }

  if (aKeySystem.EqualsLiteral("org.w3.clearkey")) {
    if (!Preferences::GetBool("media.eme.clearkey.enabled", true)) {
      return MediaKeySystemStatus::Cdm_disabled;
    }
    if (!HaveGMPFor(mps,
                    NS_LITERAL_CSTRING("org.w3.clearkey"),
                    NS_LITERAL_CSTRING(GMP_API_DECRYPTOR))) {
      return MediaKeySystemStatus::Cdm_not_installed;
    }
    return EnsureMinCDMVersion(mps, aKeySystem, aMinCdmVersion);
  }

#ifdef XP_WIN
  if ((aKeySystem.EqualsLiteral("com.adobe.access") ||
       aKeySystem.EqualsLiteral("com.adobe.primetime"))) {
    // Win Vista and later only.
    if (!IsVistaOrLater()) {
      return MediaKeySystemStatus::Cdm_not_supported;
    }
    if (!Preferences::GetBool("media.gmp-eme-adobe.enabled", false)) {
      return MediaKeySystemStatus::Cdm_disabled;
    }
    if ((!WMFDecoderModule::HasH264() || !WMFDecoderModule::HasAAC()) ||
        !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.
      return MediaKeySystemStatus::Cdm_not_supported;
    }
    if (!HaveGMPFor(mps,
                    NS_ConvertUTF16toUTF8(aKeySystem),
                    NS_LITERAL_CSTRING(GMP_API_DECRYPTOR)) &&
        // XXX to be removed later in bug 1147692
        !HaveGMPFor(mps,
                    NS_ConvertUTF16toUTF8(aKeySystem),
                    NS_LITERAL_CSTRING(GMP_API_DECRYPTOR_COMPAT))) {
      return MediaKeySystemStatus::Cdm_not_installed;
    }
    return EnsureMinCDMVersion(mps, aKeySystem, aMinCdmVersion);
  }
#endif

  return MediaKeySystemStatus::Cdm_not_supported;
}
/* static */ bool
MediaKeySystemAccess::IsGMPPresentOnDisk(const nsAString& aKeySystem,
                                         const nsACString& aVersion,
                                         nsACString& aOutMessage)
{
  MOZ_ASSERT(NS_IsMainThread());

  if (XRE_GetProcessType() != GeckoProcessType_Default) {
    // We need to be able to access the filesystem, so call this in the
    // main process via ContentChild.
    ContentChild* contentChild = ContentChild::GetSingleton();
    if (NS_WARN_IF(!contentChild)) {
      return false;
    }

    nsCString message;
    bool result = false;
    bool ok = contentChild->SendIsGMPPresentOnDisk(nsString(aKeySystem), nsCString(aVersion),
                                                   &result, &message);
    aOutMessage = message;
    return ok && result;
  }

  bool isPresent = true;

#if XP_WIN
  if (aKeySystem.EqualsLiteral("com.adobe.primetime")) {
    if (!AdobePluginDLLExists(aVersion)) {
      NS_WARNING("Adobe EME plugin disappeared from disk!");
      aOutMessage = NS_LITERAL_CSTRING("Adobe DLL was expected to be on disk but was not");
      isPresent = false;
    }
    if (!AdobePluginVoucherExists(aVersion)) {
      NS_WARNING("Adobe EME voucher disappeared from disk!");
      aOutMessage = NS_LITERAL_CSTRING("Adobe plugin voucher was expected to be on disk but was not");
      isPresent = false;
    }

    if (!isPresent) {
      // 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");
    } else if (!EMEVoucherFileExists()) {
      // Gecko doesn't have a voucher file 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");
      isPresent = false;
    }
  }
#endif

  return isPresent;
}
/* static */
MediaKeySystemStatus
MediaKeySystemAccess::GetKeySystemStatus(const nsAString& aKeySystem,
                                         int32_t aMinCdmVersion,
                                         nsACString& aOutMessage,
                                         nsACString& aOutCdmVersion)
{
  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, aOutMessage, aOutCdmVersion);
  }

#ifdef PRIMETIME_EME_SUPPORTED
  if (aKeySystem.EqualsLiteral("com.adobe.primetime")) {
    if (!Preferences::GetBool("media.gmp-eme-adobe.enabled", false)) {
      aOutMessage = NS_LITERAL_CSTRING("Adobe EME disabled");
      return MediaKeySystemStatus::Cdm_disabled;
    }
#ifdef XP_WIN
    // Win Vista and later only.
    if (!IsVistaOrLater()) {
      aOutMessage = NS_LITERAL_CSTRING("Minimum Windows version not met for Adobe EME");
      return MediaKeySystemStatus::Cdm_not_supported;
    }
#endif
#ifdef XP_MACOSX
    if (!nsCocoaFeatures::OnLionOrLater()) {
      aOutMessage = NS_LITERAL_CSTRING("Minimum MacOSX version not met for Adobe EME");
      return MediaKeySystemStatus::Cdm_not_supported;
    }
#endif
    if (!EMEVoucherFileExists()) {
      // Gecko doesn't have a voucher file 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, aOutMessage, aOutCdmVersion);
  }
#endif

  return MediaKeySystemStatus::Cdm_not_supported;
}