diff options
author | sandersd <sandersd@chromium.org> | 2015-05-05 18:50:57 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-05-06 01:52:17 +0000 |
commit | a6bf8b52a70dafe95e8e2d8827f5e1283ec1bf56 (patch) | |
tree | 24fd280efc30617bbdb4802a082dce2ea3a99d8e /media | |
parent | d5538fccee51a36e074196b5f5b846a787559600 (diff) | |
download | chromium_src-a6bf8b52a70dafe95e8e2d8827f5e1283ec1bf56.zip chromium_src-a6bf8b52a70dafe95e8e2d8827f5e1283ec1bf56.tar.gz chromium_src-a6bf8b52a70dafe95e8e2d8827f5e1283ec1bf56.tar.bz2 |
Support Android secure codecs in requestMediaKeySystemAccess().
This adds the bits necessary to determine if a configuration requires hardware-secure codecs. It does not add the logic to actually enable secure surfaces based on the requirement, that decision is still based on the renderer preference.
BUG=467779
Review URL: https://codereview.chromium.org/1106263004
Cr-Commit-Position: refs/heads/master@{#328464}
Diffstat (limited to 'media')
-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 |
9 files changed, 126 insertions, 71 deletions
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( |