diff options
-rw-r--r-- | android_webview/renderer/aw_key_systems.cc | 6 | ||||
-rw-r--r-- | chrome/renderer/media/chrome_key_systems.cc | 6 | ||||
-rw-r--r-- | chromecast/renderer/key_systems_cast.cc | 30 | ||||
-rw-r--r-- | components/cdm/renderer/android_key_systems.cc | 83 | ||||
-rw-r--r-- | components/cdm/renderer/android_key_systems.h | 7 | ||||
-rw-r--r-- | components/cdm/renderer/widevine_key_systems.cc | 6 | ||||
-rw-r--r-- | components/cdm/renderer/widevine_key_systems.h | 3 | ||||
-rw-r--r-- | media/base/eme_constants.h | 9 | ||||
-rw-r--r-- | media/base/key_system_info.cc | 11 | ||||
-rw-r--r-- | media/base/key_system_info.h | 24 | ||||
-rw-r--r-- | media/base/key_systems.cc | 40 | ||||
-rw-r--r-- | media/base/key_systems.h | 7 | ||||
-rw-r--r-- | media/base/key_systems_unittest.cc | 10 | ||||
-rw-r--r-- | media/blink/key_system_config_selector.cc | 84 | ||||
-rw-r--r-- | media/blink/key_system_config_selector.h | 3 | ||||
-rw-r--r-- | media/blink/key_system_config_selector_unittest.cc | 9 |
16 files changed, 195 insertions, 143 deletions
diff --git a/android_webview/renderer/aw_key_systems.cc b/android_webview/renderer/aw_key_systems.cc index 29e50ce..cc3059e 100644 --- a/android_webview/renderer/aw_key_systems.cc +++ b/android_webview/renderer/aw_key_systems.cc @@ -9,11 +9,7 @@ namespace android_webview { void AwAddKeySystems( std::vector<media::KeySystemInfo>* key_systems_info) { - // TODO(sandersd): Non-compositing support depends on the - // use_video_overlay_for_embedded_encrypted_video pref, which may differ per - // WebContents. For now, err on the side of registering support. - // http://crbug.com/467779 - cdm::AddAndroidWidevine(key_systems_info, true); + cdm::AddAndroidWidevine(key_systems_info); cdm::AddAndroidPlatformKeySystems(key_systems_info); } diff --git a/chrome/renderer/media/chrome_key_systems.cc b/chrome/renderer/media/chrome_key_systems.cc index 7f4c8362..c1db59a 100644 --- a/chrome/renderer/media/chrome_key_systems.cc +++ b/chrome/renderer/media/chrome_key_systems.cc @@ -225,10 +225,6 @@ void AddChromeKeySystems(std::vector<KeySystemInfo>* key_systems_info) { #endif // defined(ENABLE_PEPPER_CDMS) #if defined(OS_ANDROID) - // TODO(sandersd): Non-compositing support depends on the - // use_video_overlay_for_embedded_encrypted_video pref, which may differ per - // WebContents. For now, Chromium does not support them. - // http://crbug.com/467779 - cdm::AddAndroidWidevine(key_systems_info, false); + cdm::AddAndroidWidevine(key_systems_info); #endif // defined(OS_ANDROID) } diff --git a/chromecast/renderer/key_systems_cast.cc b/chromecast/renderer/key_systems_cast.cc index c9cae76..bede018 100644 --- a/chromecast/renderer/key_systems_cast.cc +++ b/chromecast/renderer/key_systems_cast.cc @@ -14,6 +14,10 @@ #include "widevine_cdm_version.h" // In SHARED_INTERMEDIATE_DIR. +using ::media::EmeFeatureSupport; +using ::media::EmeRobustness; +using ::media::EmeSessionTypeSupport; + namespace chromecast { namespace shell { @@ -40,24 +44,28 @@ void AddKeySystemWithCodecs( void AddChromecastKeySystems( std::vector<::media::KeySystemInfo>* key_systems_info) { #if defined(WIDEVINE_CDM_AVAILABLE) + ::media::SupportedCodecs codecs = + ::media::EME_CODEC_MP4_AAC | ::media::EME_CODEC_MP4_AVC1; AddWidevineWithCodecs( - cdm::WIDEVINE, ::media::EME_CODEC_MP4_AAC | ::media::EME_CODEC_MP4_AVC1, - ::media::EmeRobustness::HW_SECURE_ALL, // Max audio robustness. - ::media::EmeRobustness::HW_SECURE_ALL, // Max video robustness. - ::media::EmeSessionTypeSupport::NOT_SUPPORTED, // persistent-license. - ::media::EmeSessionTypeSupport:: - NOT_SUPPORTED, // persistent-release-message. + cdm::WIDEVINE, + codecs, // Regular codecs. +#if defined(OS_ANDROID) + codecs, // Hardware-secure codecs. +#endif // defined(OS_ANDROID) + EmeRobustness::HW_SECURE_ALL, // Max audio robustness. + EmeRobustness::HW_SECURE_ALL, // Max video robustness. + EmeSessionTypeSupport::NOT_SUPPORTED, // persistent-license. + EmeSessionTypeSupport::NOT_SUPPORTED, // persistent-release-message. // Note: On Chromecast, all CDMs may have persistent state. - ::media::EmeFeatureSupport::ALWAYS_ENABLED, // Persistent state. - ::media::EmeFeatureSupport::ALWAYS_ENABLED, // Distinctive - // identifier. + EmeFeatureSupport::ALWAYS_ENABLED, // Persistent state. + EmeFeatureSupport::ALWAYS_ENABLED, // Distinctive identifier. key_systems_info); -#endif +#endif // defined(WIDEVINE_CDM_AVAILABLE) #if defined(PLAYREADY_CDM_AVAILABLE) AddKeySystemWithCodecs(media::kChromecastPlayreadyKeySystem, key_systems_info); -#endif +#endif // defined(PLAYREADY_CDM_AVAILABLE) } } // namespace shell diff --git a/components/cdm/renderer/android_key_systems.cc b/components/cdm/renderer/android_key_systems.cc index 28b45eb..b9521d3 100644 --- a/components/cdm/renderer/android_key_systems.cc +++ b/components/cdm/renderer/android_key_systems.cc @@ -17,7 +17,9 @@ #include "widevine_cdm_version.h" // In SHARED_INTERMEDIATE_DIR. +using media::EmeFeatureSupport; using media::EmeRobustness; +using media::EmeSessionTypeSupport; using media::KeySystemInfo; using media::SupportedCodecs; @@ -39,60 +41,50 @@ static SupportedKeySystemResponse QueryKeySystemSupport( return response; } -void AddAndroidWidevine(std::vector<KeySystemInfo>* concrete_key_systems, - bool is_non_compositing_supported) { +void AddAndroidWidevine(std::vector<KeySystemInfo>* concrete_key_systems) { SupportedKeySystemResponse response = QueryKeySystemSupport( kWidevineKeySystem); - // When creating the WIDEVINE key system, BrowserCdmFactoryAndroid configures - // the CDM's security level based on a pref. Therefore the supported - // codec/robustenss combinations depend on that pref, represented by - // |bool is_non_compositing_supported|. - // TODO(sandersd): For unprefixed, set the security level based on the - // requested robustness instead of the flag. http://crbug.com/467779 - // We should also stop using the term "non_compositing." - SupportedCodecs codecs = response.compositing_codecs; - EmeRobustness max_audio_robustness = EmeRobustness::SW_SECURE_CRYPTO; - EmeRobustness max_video_robustness = EmeRobustness::SW_SECURE_CRYPTO; - if (is_non_compositing_supported) { - codecs = response.non_compositing_codecs; - max_audio_robustness = EmeRobustness::HW_SECURE_CRYPTO; - max_video_robustness = EmeRobustness::HW_SECURE_ALL; - } - - // We are using MediaDrm API on Android and we cannot guarantee that API - // doesn't use persistent storage on the device. Therefore always set - // persistent state to EmeFeatureSupport::ALWAYS_ENABLED to err on the - // safe side. + // Since we do not control the implementation of the MediaDrm API on Android, + // we assume that it can and will make use of persistence even though no + // persistence-based features are supported. - if (codecs != media::EME_CODEC_NONE) { + if (response.compositing_codecs != media::EME_CODEC_NONE) { AddWidevineWithCodecs( - WIDEVINE, codecs, max_audio_robustness, max_video_robustness, - media::EmeSessionTypeSupport::NOT_SUPPORTED, // persistent-license. - media::EmeSessionTypeSupport:: - NOT_SUPPORTED, // persistent-release-message. - media::EmeFeatureSupport::ALWAYS_ENABLED, // Persistent state. - media::EmeFeatureSupport::ALWAYS_ENABLED, // Distinctive - // identifier. + WIDEVINE, + response.compositing_codecs, // Regular codecs. + response.non_compositing_codecs, // Hardware-secure codecs. + EmeRobustness::HW_SECURE_CRYPTO, // Max audio robustness. + EmeRobustness::HW_SECURE_ALL, // Max video robustness. + EmeSessionTypeSupport::NOT_SUPPORTED, // persistent-license. + EmeSessionTypeSupport::NOT_SUPPORTED, // persistent-release-message. + EmeFeatureSupport::ALWAYS_ENABLED, // Persistent state. + EmeFeatureSupport::ALWAYS_ENABLED, // Distinctive identifier. concrete_key_systems); + } else { + // It doesn't make sense to support secure codecs but not regular codecs. + DCHECK(response.non_compositing_codecs == media::EME_CODEC_NONE); } // For compatibility with the prefixed API, register a separate L1 key system. - // When creating the WIDEVINE_HR_NON_COMPOSITING key system, - // BrowserCdmFactoryAndroid does not configure the CDM's security level (that - // is, leaves it as L1); therefore only secure codecs are supported. - // TODO(ddorwin): Remove with unprefixed. http://crbug.com/249976 - if (response.non_compositing_codecs != media::EME_CODEC_NONE) { + // This key systems acts as though only hardware-secure codecs are available. + // We only register support for codecs with both regular and hardware-secure + // variants so that we can be sure they will work regardless of the renderer + // preference. + SupportedCodecs secure_codecs = + response.compositing_codecs & response.non_compositing_codecs; + if (secure_codecs != media::EME_CODEC_NONE) { + // Note: The prefixed API only consults the regular codecs field. AddWidevineWithCodecs( - WIDEVINE_HR_NON_COMPOSITING, response.non_compositing_codecs, - EmeRobustness::HW_SECURE_CRYPTO, // Max audio robustness. - EmeRobustness::HW_SECURE_ALL, // Max video robustness. - media::EmeSessionTypeSupport::NOT_SUPPORTED, // persistent-license. - media::EmeSessionTypeSupport:: - NOT_SUPPORTED, // persistent-release-message. - media::EmeFeatureSupport::ALWAYS_ENABLED, // Persistent state. - media::EmeFeatureSupport::ALWAYS_ENABLED, // Distinctive - // identifier. + WIDEVINE_HR_NON_COMPOSITING, + secure_codecs, // Regular codecs. + media::EME_CODEC_NONE, // Hardware-secure codecs. + EmeRobustness::HW_SECURE_CRYPTO, // Max audio robustness. + EmeRobustness::HW_SECURE_ALL, // Max video robustness. + EmeSessionTypeSupport::NOT_SUPPORTED, // persistent-license. + EmeSessionTypeSupport::NOT_SUPPORTED, // persistent-release-message. + EmeFeatureSupport::ALWAYS_ENABLED, // Persistent state. + EmeFeatureSupport::ALWAYS_ENABLED, // Distinctive identifier. concrete_key_systems); } } @@ -121,7 +113,8 @@ void AddAndroidPlatformKeySystems( #endif // defined(USE_PROPRIETARY_CODECS) info.max_audio_robustness = EmeRobustness::EMPTY; info.max_video_robustness = EmeRobustness::EMPTY; - // Assume the worst case (from a user point of view). + // Assume that platform key systems support no features but can and will + // make use of persistence and identifiers. info.persistent_license_support = media::EmeSessionTypeSupport::NOT_SUPPORTED; info.persistent_release_message_support = diff --git a/components/cdm/renderer/android_key_systems.h b/components/cdm/renderer/android_key_systems.h index b27f57c..fb962b1 100644 --- a/components/cdm/renderer/android_key_systems.h +++ b/components/cdm/renderer/android_key_systems.h @@ -12,12 +12,7 @@ namespace cdm { void AddAndroidWidevine( - std::vector<media::KeySystemInfo>* concrete_key_systems, - // TODO(sandersd): Non-compositing support depends on the - // use_video_overlay_for_embedded_encrypted_video pref, which may differ per - // WebContents, meaning this cannot be a global setting for the renderer - // process. Handle this per WebContents instead. http://crbug.com/467779 - bool is_non_compositing_supported); + std::vector<media::KeySystemInfo>* concrete_key_systems); // Add platform-supported key systems which are not explicitly handled // by Chrome. diff --git a/components/cdm/renderer/widevine_key_systems.cc b/components/cdm/renderer/widevine_key_systems.cc index c1412c3..3998066 100644 --- a/components/cdm/renderer/widevine_key_systems.cc +++ b/components/cdm/renderer/widevine_key_systems.cc @@ -29,6 +29,9 @@ static std::string GetDirectParentName(std::string name) { void AddWidevineWithCodecs( WidevineCdmType widevine_cdm_type, SupportedCodecs supported_codecs, +#if defined(OS_ANDROID) + SupportedCodecs supported_secure_codecs, +#endif // defined(OS_ANDROID) media::EmeRobustness max_audio_robustness, media::EmeRobustness max_video_robustness, media::EmeSessionTypeSupport persistent_license_support, @@ -57,6 +60,9 @@ void AddWidevineWithCodecs( // there are no codecs supported in that container. Fix this when we support // initDataType. info.supported_codecs = supported_codecs; +#if defined(OS_ANDROID) + info.supported_secure_codecs = supported_secure_codecs; +#endif // defined(OS_ANDROID) // Here we assume that support for a container imples support for the // associated initialization data type. KeySystems handles validating diff --git a/components/cdm/renderer/widevine_key_systems.h b/components/cdm/renderer/widevine_key_systems.h index dc05bb8..125e297 100644 --- a/components/cdm/renderer/widevine_key_systems.h +++ b/components/cdm/renderer/widevine_key_systems.h @@ -22,6 +22,9 @@ enum WidevineCdmType { void AddWidevineWithCodecs( WidevineCdmType widevine_cdm_type, media::SupportedCodecs supported_codecs, +#if defined(OS_ANDROID) + media::SupportedCodecs supported_secure_codecs, +#endif // defined(OS_ANDROID) media::EmeRobustness max_audio_robustness, media::EmeRobustness max_video_robustness, media::EmeSessionTypeSupport persistent_license_support, diff --git a/media/base/eme_constants.h b/media/base/eme_constants.h index 0b24670..6d6399d 100644 --- a/media/base/eme_constants.h +++ b/media/base/eme_constants.h @@ -129,6 +129,15 @@ enum class EmeConfigRule { // The configuration option is supported if both a distinctive identifier and // persistent state are available. IDENTIFIER_AND_PERSISTENCE_REQUIRED, +#if defined(OS_ANDROID) + // The configuration option is supported if no hardware-secure codecs are used + // (as they would be for video if secure surfaces are enabled). + SECURE_CODECS_NOT_ALLOWED, + // The configuration option is supported if only hardware-secure codecs are + // used. This implies that secure surfaces (hole-punching) are required for + // video. + SECURE_CODECS_REQUIRED, +#endif // defined(OS_ANDROID) // The configuration option is supported without conditions. SUPPORTED, }; diff --git a/media/base/key_system_info.cc b/media/base/key_system_info.cc index 8eec5b1..f36104a 100644 --- a/media/base/key_system_info.cc +++ b/media/base/key_system_info.cc @@ -6,16 +6,7 @@ namespace media { -KeySystemInfo::KeySystemInfo() - : supported_init_data_types(kInitDataTypeMaskNone), - supported_codecs(EME_CODEC_NONE), - max_audio_robustness(EmeRobustness::INVALID), - max_video_robustness(EmeRobustness::INVALID), - persistent_license_support(EmeSessionTypeSupport::INVALID), - persistent_release_message_support(EmeSessionTypeSupport::INVALID), - persistent_state_support(EmeFeatureSupport::INVALID), - distinctive_identifier_support(EmeFeatureSupport::INVALID), - use_aes_decryptor(false) { +KeySystemInfo::KeySystemInfo() { } KeySystemInfo::~KeySystemInfo() { diff --git a/media/base/key_system_info.h b/media/base/key_system_info.h index 4c60552..d349452 100644 --- a/media/base/key_system_info.h +++ b/media/base/key_system_info.h @@ -7,6 +7,7 @@ #include <string> +#include "build/build_config.h" #include "media/base/eme_constants.h" #include "media/base/media_export.h" @@ -35,14 +36,19 @@ struct MEDIA_EXPORT KeySystemInfo { std::string key_system; - InitDataTypeMask supported_init_data_types; - SupportedCodecs supported_codecs; - EmeRobustness max_audio_robustness; - EmeRobustness max_video_robustness; - EmeSessionTypeSupport persistent_license_support; - EmeSessionTypeSupport persistent_release_message_support; - EmeFeatureSupport persistent_state_support; - EmeFeatureSupport distinctive_identifier_support; + InitDataTypeMask supported_init_data_types = kInitDataTypeMaskNone; + SupportedCodecs supported_codecs = EME_CODEC_NONE; +#if defined(OS_ANDROID) + SupportedCodecs supported_secure_codecs = EME_CODEC_NONE; +#endif // defined(OS_ANDROID) + EmeRobustness max_audio_robustness = EmeRobustness::INVALID; + EmeRobustness max_video_robustness = EmeRobustness::INVALID; + EmeSessionTypeSupport persistent_license_support = + EmeSessionTypeSupport::INVALID; + EmeSessionTypeSupport persistent_release_message_support = + EmeSessionTypeSupport::INVALID; + EmeFeatureSupport persistent_state_support = EmeFeatureSupport::INVALID; + EmeFeatureSupport distinctive_identifier_support = EmeFeatureSupport::INVALID; // A hierarchical parent for |key_system|. This value can be used to check // supported types but cannot be used to instantiate a MediaKeys object. @@ -50,7 +56,7 @@ struct MEDIA_EXPORT KeySystemInfo { std::string parent_key_system; // The following indicate how the corresponding CDM should be instantiated. - bool use_aes_decryptor; + bool use_aes_decryptor = false; #if defined(ENABLE_PEPPER_CDMS) std::string pepper_type; #endif diff --git a/media/base/key_systems.cc b/media/base/key_systems.cc index dae0b18..17c4210 100644 --- a/media/base/key_systems.cc +++ b/media/base/key_systems.cc @@ -202,7 +202,7 @@ class KeySystemsImpl : public KeySystems { bool IsSupportedInitDataType(const std::string& key_system, EmeInitDataType init_data_type) const override; - bool IsSupportedCodecCombination( + EmeConfigRule GetContentTypeConfigRule( const std::string& key_system, EmeMediaType media_type, const std::string& container_mime_type, @@ -665,7 +665,7 @@ bool KeySystemsImpl::IsSupportedKeySystem(const std::string& key_system) const { return concrete_key_system_map_.count(key_system) != 0; } -bool KeySystemsImpl::IsSupportedCodecCombination( +EmeConfigRule KeySystemsImpl::GetContentTypeConfigRule( const std::string& key_system, EmeMediaType media_type, const std::string& container_mime_type, @@ -677,12 +677,12 @@ bool KeySystemsImpl::IsSupportedCodecCombination( switch (media_type) { case EmeMediaType::AUDIO: if (!StartsWithASCII(container_mime_type, "audio/", true)) - return false; + return EmeConfigRule::NOT_SUPPORTED; media_type_codec_mask = audio_codec_mask_; break; case EmeMediaType::VIDEO: if (!StartsWithASCII(container_mime_type, "video/", true)) - return false; + return EmeConfigRule::NOT_SUPPORTED; media_type_codec_mask = video_codec_mask_; break; } @@ -692,26 +692,43 @@ bool KeySystemsImpl::IsSupportedCodecCombination( concrete_key_system_map_.find(key_system); if (key_system_iter == concrete_key_system_map_.end()) { NOTREACHED(); - return false; + return EmeConfigRule::NOT_SUPPORTED; } SupportedCodecs key_system_codec_mask = key_system_iter->second.supported_codecs; +#if defined(OS_ANDROID) + SupportedCodecs key_system_secure_codec_mask = + key_system_iter->second.supported_secure_codecs; +#endif // defined(OS_ANDROID) + // Check that the container is supported by the key system. (This check is // necessary because |codecs| may be empty.) SupportedCodecs container_codec_mask = GetCodecMaskForContainer(container_mime_type) & media_type_codec_mask; if ((key_system_codec_mask & container_codec_mask) == 0) - return false; + return EmeConfigRule::NOT_SUPPORTED; // Check that the codecs are supported by the key system and container. + EmeConfigRule support = EmeConfigRule::SUPPORTED; for (size_t i = 0; i < codecs.size(); i++) { SupportedCodecs codec = GetCodecForString(codecs[i]); if ((codec & key_system_codec_mask & container_codec_mask) == 0) - return false; + return EmeConfigRule::NOT_SUPPORTED; +#if defined(OS_ANDROID) + // Check whether the codec supports a hardware-secure mode; if not, indicate + // that hardware-secure codecs are not available for all listed codecs. + // Because the check for regular codec support is early-exit, we don't have + // to consider codecs that are only supported in hardware-secure mode. We + // could do so, and make use of SECURE_CODECS_REQUIRED, if it turns out that + // hardware-secure-only codecs actually exist and are useful. + if ((codec & key_system_secure_codec_mask) == 0) + support = EmeConfigRule::SECURE_CODECS_NOT_ALLOWED; +#endif // defined(OS_ANDROID) + } - return true; + return support; } EmeConfigRule KeySystemsImpl::GetRobustnessConfigRule( @@ -754,8 +771,8 @@ EmeConfigRule KeySystemsImpl::GetRobustnessConfigRule( return EmeConfigRule::NOT_SUPPORTED; } -#if defined(OS_CHROMEOS) if (key_system == kWidevineKeySystem) { +#if defined(OS_CHROMEOS) // Hardware security requires remote attestation. if (robustness >= EmeRobustness::HW_SECURE_CRYPTO) return EmeConfigRule::IDENTIFIER_REQUIRED; @@ -768,8 +785,11 @@ EmeConfigRule KeySystemsImpl::GetRobustnessConfigRule( max_robustness == EmeRobustness::HW_SECURE_ALL) { return EmeConfigRule::IDENTIFIER_RECOMMENDED; } - } +#elif defined(OS_ANDROID) + if (robustness > EmeRobustness::SW_SECURE_CRYPTO) + return EmeConfigRule::SECURE_CODECS_REQUIRED; #endif // defined(OS_CHROMEOS) + } return EmeConfigRule::SUPPORTED; } diff --git a/media/base/key_systems.h b/media/base/key_systems.h index 064e2cf..ade5d65 100644 --- a/media/base/key_systems.h +++ b/media/base/key_systems.h @@ -34,10 +34,9 @@ class MEDIA_EXPORT KeySystems { const std::string& key_system, EmeInitDataType init_data_type) const = 0; - // Returns whether the list of codecs are supported together by |key_system|. - // TODO(sandersd): Return a rule instead of a bool so that codec selection can - // affect other configuration options (namely robustness). - virtual bool IsSupportedCodecCombination( + // Returns the configuration rule for supporting a container and list of + // codecs. + virtual EmeConfigRule GetContentTypeConfigRule( const std::string& key_system, EmeMediaType media_type, const std::string& container_mime_type, diff --git a/media/base/key_systems_unittest.cc b/media/base/key_systems_unittest.cc index 611c2b6..1a29488 100644 --- a/media/base/key_systems_unittest.cc +++ b/media/base/key_systems_unittest.cc @@ -77,16 +77,18 @@ static bool IsSupportedKeySystemWithMediaMimeType( const std::string& mime_type, const std::vector<std::string>& codecs, const std::string& key_system) { - return KeySystems::GetInstance()->IsSupportedCodecCombination( - key_system, EmeMediaType::VIDEO, mime_type, codecs); + return (KeySystems::GetInstance()->GetContentTypeConfigRule( + key_system, EmeMediaType::VIDEO, mime_type, codecs) != + EmeConfigRule::NOT_SUPPORTED); } static bool IsSupportedKeySystemWithAudioMimeType( const std::string& mime_type, const std::vector<std::string>& codecs, const std::string& key_system) { - return KeySystems::GetInstance()->IsSupportedCodecCombination( - key_system, EmeMediaType::AUDIO, mime_type, codecs); + return (KeySystems::GetInstance()->GetContentTypeConfigRule( + key_system, EmeMediaType::AUDIO, mime_type, codecs) != + EmeConfigRule::NOT_SUPPORTED); } // Adds test container and codec masks. diff --git a/media/blink/key_system_config_selector.cc b/media/blink/key_system_config_selector.cc index 67a13e2..324a28f6 100644 --- a/media/blink/key_system_config_selector.cc +++ b/media/blink/key_system_config_selector.cc @@ -177,6 +177,12 @@ class KeySystemConfigSelector::ConfigState { case EmeConfigRule::IDENTIFIER_AND_PERSISTENCE_REQUIRED: return (!is_identifier_not_allowed_ && IsPermissionPossible() && !is_persistence_not_allowed_); +#if defined(OS_ANDROID) + case EmeConfigRule::SECURE_CODECS_NOT_ALLOWED: + return !are_secure_codecs_required_; + case EmeConfigRule::SECURE_CODECS_REQUIRED: + return !are_secure_codecs_not_allowed_; +#endif // defined(OS_ANDROID) case EmeConfigRule::SUPPORTED: return true; } @@ -210,6 +216,14 @@ class KeySystemConfigSelector::ConfigState { is_identifier_required_ = true; is_persistence_required_ = true; return; +#if defined(OS_ANDROID) + case EmeConfigRule::SECURE_CODECS_NOT_ALLOWED: + are_secure_codecs_not_allowed_ = true; + return; + case EmeConfigRule::SECURE_CODECS_REQUIRED: + are_secure_codecs_required_ = true; + return; +#endif // defined(OS_ANDROID) case EmeConfigRule::SUPPORTED: return; } @@ -219,10 +233,12 @@ class KeySystemConfigSelector::ConfigState { private: // Whether permission to use a distinctive identifier was requested. If set, // |is_permission_granted_| represents the final decision. - const bool was_permission_requested_; + // (Not changed by adding rules.) + bool was_permission_requested_; // Whether permission to use a distinctive identifier has been granted. - const bool is_permission_granted_; + // (Not changed by adding rules.) + bool is_permission_granted_; // Whether a rule has been added that requires or blocks a distinctive // identifier. @@ -236,7 +252,11 @@ class KeySystemConfigSelector::ConfigState { bool is_persistence_required_ = false; bool is_persistence_not_allowed_ = false; - DISALLOW_COPY_AND_ASSIGN(ConfigState); +#if defined(OS_ANDROID) + // Whether a rule has been added that requires or blocks secure codecs. + bool are_secure_codecs_required_ = false; + bool are_secure_codecs_not_allowed_ = false; +#endif // defined(OS_ANDROID) }; KeySystemConfigSelector::KeySystemConfigSelector( @@ -256,38 +276,40 @@ bool KeySystemConfigSelector::IsSupportedContentType( const std::string& key_system, EmeMediaType media_type, const std::string& container_mime_type, - const std::string& codecs) { + const std::string& codecs, + KeySystemConfigSelector::ConfigState* config_state) { // TODO(sandersd): Move contentType parsing from Blink to here so that invalid // parameters can be rejected. http://crbug.com/417561 std::string container_lower = base::StringToLowerASCII(container_mime_type); - // Check that |container_mime_type| and |codecs| are supported by the CDM. - // This check does not handle extended codecs, so extended codec information - // is stripped. - std::vector<std::string> codec_vector; - net::ParseCodecString(codecs, &codec_vector, true); - if (!key_systems_->IsSupportedCodecCombination( - key_system, media_type, container_lower, codec_vector)) { - return false; - } - - // Check that |container_mime_type| is supported by Chrome. This can only - // happen if the CDM declares support for a container that Chrome does not. - if (!net::IsSupportedMediaMimeType(container_lower)) { - NOTREACHED(); + // Check that |container_mime_type| is supported by Chrome. + if (!net::IsSupportedMediaMimeType(container_lower)) return false; - } // Check that |codecs| are supported by Chrome. This is done primarily to // validate extended codecs, but it also ensures that the CDM cannot support // codecs that Chrome does not (which could complicate the robustness // algorithm). - if (codec_vector.empty()) - return true; - codec_vector.clear(); + std::vector<std::string> codec_vector; net::ParseCodecString(codecs, &codec_vector, false); - return (net::IsSupportedStrictMediaMimeType(container_lower, codec_vector) == - net::IsSupported); + if (!codec_vector.empty() && + (net::IsSupportedStrictMediaMimeType(container_lower, codec_vector) != + net::IsSupported)) { + return false; + } + + // Check that |container_mime_type| and |codecs| are supported by the CDM. + // This check does not handle extended codecs, so extended codec information + // is stripped (extended codec information was checked above). + std::vector<std::string> stripped_codec_vector; + net::ParseCodecString(codecs, &stripped_codec_vector, true); + EmeConfigRule codecs_rule = key_systems_->GetContentTypeConfigRule( + key_system, media_type, container_lower, stripped_codec_vector); + if (!config_state->IsRuleSupported(codecs_rule)) + return false; + config_state->AddRule(codecs_rule); + + return true; } bool KeySystemConfigSelector::GetSupportedCapabilities( @@ -318,12 +340,15 @@ bool KeySystemConfigSelector::GetSupportedCapabilities( << "a capability contentType was empty."; return false; } + // 3.4-3.11. (Implemented by IsSupportedContentType().) + ConfigState proposed_config_state = *config_state; if (!base::IsStringASCII(capability.mimeType) || !base::IsStringASCII(capability.codecs) || !IsSupportedContentType(key_system, media_type, base::UTF16ToASCII(capability.mimeType), - base::UTF16ToASCII(capability.codecs))) { + base::UTF16ToASCII(capability.codecs), + &proposed_config_state)) { continue; } // 3.12. If robustness is not the empty string, run the following steps: @@ -335,9 +360,9 @@ bool KeySystemConfigSelector::GetSupportedCapabilities( continue; EmeConfigRule robustness_rule = key_systems_->GetRobustnessConfigRule( key_system, media_type, base::UTF16ToASCII(capability.robustness)); - if (!config_state->IsRuleSupported(robustness_rule)) + if (!proposed_config_state.IsRuleSupported(robustness_rule)) continue; - config_state->AddRule(robustness_rule); + proposed_config_state.AddRule(robustness_rule); // 3.12.2. Add robustness to configuration. // (It's already added, we use capability as configuration.) } @@ -345,11 +370,11 @@ bool KeySystemConfigSelector::GetSupportedCapabilities( // encrypted media data as specified by configuration, including all // media types, in combination with local accumulated capabilities, // continue to the next iteration. - // (This is handled when adding rules to |config_state|.) + // (This is handled when adding rules to |proposed_config_state|.) // 3.14. Add configuration to supported media capabilities. supported_media_capabilities->push_back(capability); // 3.15. Add configuration to local accumulated capabilities. - // (Skipped as we directly update |config_state|.) + *config_state = proposed_config_state; } // 4. If supported media capabilities is empty, return null. if (supported_media_capabilities->empty()) { @@ -367,6 +392,7 @@ KeySystemConfigSelector::GetSupportedConfiguration( const blink::WebMediaKeySystemConfiguration& candidate, ConfigState* config_state, blink::WebMediaKeySystemConfiguration* accumulated_configuration) { + // TODO(sandersd): Set state of SECURE_CODECS from renderer pref. // From https://w3c.github.io/encrypted-media/#get-supported-configuration // 1. Let accumulated configuration be empty. (Done by caller.) // 2. If the initDataTypes member is present in candidate configuration, run diff --git a/media/blink/key_system_config_selector.h b/media/blink/key_system_config_selector.h index 47a9fee..86eec7e 100644 --- a/media/blink/key_system_config_selector.h +++ b/media/blink/key_system_config_selector.h @@ -78,7 +78,8 @@ class MEDIA_EXPORT KeySystemConfigSelector { bool IsSupportedContentType(const std::string& key_system, EmeMediaType media_type, const std::string& container_mime_type, - const std::string& codecs); + const std::string& codecs, + ConfigState* config_state); const KeySystems* key_systems_; MediaPermission* media_permission_; diff --git a/media/blink/key_system_config_selector_unittest.cc b/media/blink/key_system_config_selector_unittest.cc index 762db78..1e2d1e8 100644 --- a/media/blink/key_system_config_selector_unittest.cc +++ b/media/blink/key_system_config_selector_unittest.cc @@ -69,20 +69,21 @@ class FakeKeySystems : public KeySystems { return false; } - bool IsSupportedCodecCombination( + // TODO(sandersd): Secure codec simulation. + EmeConfigRule GetContentTypeConfigRule( const std::string& key_system, EmeMediaType media_type, const std::string& container_mime_type, const std::vector<std::string>& codecs) const override { if (container_mime_type == kUnsupportedContainer) - return false; + return EmeConfigRule::NOT_SUPPORTED; DCHECK_EQ(kSupportedContainer, container_mime_type); for (const std::string& codec : codecs) { if (codec == kUnsupportedCodec) - return false; + return EmeConfigRule::NOT_SUPPORTED; DCHECK_EQ(kSupportedCodec, codec); } - return true; + return EmeConfigRule::SUPPORTED; } EmeConfigRule GetRobustnessConfigRule( |