static bool
CanDecryptAndDecode(mozIGeckoMediaPluginService* aGMPService,
                    const nsString& aKeySystem,
                    const nsString& aContentType,
                    CodecType aCodecType,
                    const KeySystemContainerSupport& aContainerSupport,
                    const nsTArray<GMPCodecString>& aCodecs,
                    DecoderDoctorDiagnostics* aDiagnostics)
{
  MOZ_ASSERT(aCodecType != Invalid);
  MOZ_ASSERT(HaveGMPFor(aGMPService,
                        NS_ConvertUTF16toUTF8(aKeySystem),
                        NS_LITERAL_CSTRING(GMP_API_DECRYPTOR)));
  for (const GMPCodecString& codec : aCodecs) {
    MOZ_ASSERT(!codec.IsEmpty());

    nsCString api = (aCodecType == Audio) ? NS_LITERAL_CSTRING(GMP_API_AUDIO_DECODER)
                                          : NS_LITERAL_CSTRING(GMP_API_VIDEO_DECODER);
    if (aContainerSupport.DecryptsAndDecodes(codec) &&
        HaveGMPFor(aGMPService,
                   NS_ConvertUTF16toUTF8(aKeySystem),
                   api,
                   codec)) {
      // GMP can decrypt-and-decode this codec.
      continue;
    }

    if (aContainerSupport.Decrypts(codec) &&
        NS_SUCCEEDED(MediaSource::IsTypeSupported(aContentType, aDiagnostics))) {
      // GMP can decrypt and is allowed to return compressed samples to
      // Gecko to decode, and Gecko has a decoder.
      continue;
    }

    // Neither the GMP nor Gecko can both decrypt and decode. We don't
    // support this codec.

#if defined(XP_WIN)
    // Widevine CDM doesn't include an AAC decoder. So if WMF can't
    // decode AAC, and a codec wasn't specified, be conservative
    // and reject the MediaKeys request, since our policy is to prevent
    //  the Adobe GMP's unencrypted AAC decoding path being used to
    // decode content decrypted by the Widevine CDM.
    if (codec == GMP_CODEC_AAC &&
        IsWidevineKeySystem(aKeySystem) &&
        !WMFDecoderModule::HasAAC()) {
      if (aDiagnostics) {
        aDiagnostics->SetKeySystemIssue(
          DecoderDoctorDiagnostics::eWidevineWithNoWMF);
      }
    }
#endif
    return false;
  }
  return true;
}
static bool
CanDecryptAndDecode(const nsString& aKeySystem,
                    const nsString& aContentType,
                    CodecType aCodecType,
                    const KeySystemContainerSupport& aContainerSupport,
                    const nsTArray<EMECodecString>& aCodecs,
                    DecoderDoctorDiagnostics* aDiagnostics)
{
  MOZ_ASSERT(aCodecType != Invalid);
  for (const EMECodecString& codec : aCodecs) {
    MOZ_ASSERT(!codec.IsEmpty());

    if (aContainerSupport.DecryptsAndDecodes(codec)) {
      // GMP can decrypt-and-decode this codec.
      continue;
    }

    if (aContainerSupport.Decrypts(codec) &&
        NS_SUCCEEDED(MediaSource::IsTypeSupported(aContentType, aDiagnostics))) {
      // GMP can decrypt and is allowed to return compressed samples to
      // Gecko to decode, and Gecko has a decoder.
      continue;
    }

    // Neither the GMP nor Gecko can both decrypt and decode. We don't
    // support this codec.

#if defined(XP_WIN)
    // Widevine CDM doesn't include an AAC decoder. So if WMF can't
    // decode AAC, and a codec wasn't specified, be conservative
    // and reject the MediaKeys request, since our policy is to prevent
    //  the Adobe GMP's unencrypted AAC decoding path being used to
    // decode content decrypted by the Widevine CDM.
    if (codec == EME_CODEC_AAC &&
        IsWidevineKeySystem(aKeySystem) &&
        !WMFDecoderModule::HasAAC()) {
      if (aDiagnostics) {
        aDiagnostics->SetKeySystemIssue(
          DecoderDoctorDiagnostics::eWidevineWithNoWMF);
      }
    }
#endif
    return false;
  }
  return true;
}