diff options
author | sandersd <sandersd@chromium.org> | 2015-01-09 17:44:28 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-01-10 01:45:20 +0000 |
commit | 44e7f83d24f351dcbf7d398c6e3786378244fee7 (patch) | |
tree | 74923792876516b6a345c254780d95f9da07ec5c /media/blink | |
parent | eebec0cf6a652c29bc5bd58f90671633e7e62d67 (diff) | |
download | chromium_src-44e7f83d24f351dcbf7d398c6e3786378244fee7.zip chromium_src-44e7f83d24f351dcbf7d398c6e3786378244fee7.tar.gz chromium_src-44e7f83d24f351dcbf7d398c6e3786378244fee7.tar.bz2 |
Implement checks in requestMediaKeySystemAccess().
BUG=429781
Review URL: https://codereview.chromium.org/840453002
Cr-Commit-Position: refs/heads/master@{#310934}
Diffstat (limited to 'media/blink')
-rw-r--r-- | media/blink/webencryptedmediaclient_impl.cc | 205 |
1 files changed, 157 insertions, 48 deletions
diff --git a/media/blink/webencryptedmediaclient_impl.cc b/media/blink/webencryptedmediaclient_impl.cc index 09cb0e5..af7b7f4 100644 --- a/media/blink/webencryptedmediaclient_impl.cc +++ b/media/blink/webencryptedmediaclient_impl.cc @@ -5,6 +5,10 @@ #include "webencryptedmediaclient_impl.h" #include "base/logging.h" +#include "base/strings/string_util.h" +#include "base/strings/utf_string_conversions.h" +#include "media/base/key_systems.h" +#include "net/base/mime_util.h" #include "third_party/WebKit/public/platform/WebEncryptedMediaRequest.h" #include "third_party/WebKit/public/platform/WebMediaKeySystemConfiguration.h" #include "third_party/WebKit/public/platform/WebString.h" @@ -13,10 +17,116 @@ namespace media { -static bool IsKeySystemSupportedWithInitDataType( - const blink::WebString& keySystem, - const blink::WebString& initDataType) { - DCHECK(!keySystem.isEmpty()); +static bool IsSupportedContentType( + const std::string& key_system, + const std::string& mime_type, + const std::string& codecs) { + // Per RFC 6838, "Both top-level type and subtype names are case-insensitive." + // TODO(sandersd): Check that |container| matches the capability: + // - audioCapabilitys: audio/mp4 or audio/webm. + // - videoCapabilitys: video/mp4 or video/webm. + // http://crbug.com/429781. + std::string container = base::StringToLowerASCII(mime_type); + + // TODO(sandersd): Strict checking for codecs. http://crbug.com/374751. + bool strip_codec_suffixes = !net::IsStrictMediaMimeType(container); + std::vector<std::string> codec_vector; + net::ParseCodecString(codecs, &codec_vector, strip_codec_suffixes); + return IsSupportedKeySystemWithMediaMimeType(container, codec_vector, + key_system); +} + +static bool GetSupportedConfiguration( + const std::string& key_system, + const blink::WebMediaKeySystemConfiguration& candidate, + const blink::WebSecurityOrigin& security_origin, + blink::WebMediaKeySystemConfiguration* accumulated_configuration) { + if (!candidate.initDataTypes.isEmpty()) { + std::vector<blink::WebString> init_data_types; + + for (size_t i = 0; i < candidate.initDataTypes.size(); i++) { + const blink::WebString& init_data_type = candidate.initDataTypes[i]; + if (init_data_type.isEmpty()) + return false; + if (base::IsStringASCII(init_data_type) && + IsSupportedKeySystemWithInitDataType( + key_system, base::UTF16ToASCII(init_data_type))) { + init_data_types.push_back(init_data_type); + } + } + + if (init_data_types.empty()) + return false; + + accumulated_configuration->initDataTypes = init_data_types; + } + + // TODO(sandersd): Implement distinctiveIdentifier and persistentState checks. + if (candidate.distinctiveIdentifier != + blink::WebMediaKeySystemConfiguration::Requirement::Optional || + candidate.persistentState != + blink::WebMediaKeySystemConfiguration::Requirement::Optional) { + return false; + } + + if (!candidate.audioCapabilities.isEmpty()) { + std::vector<blink::WebMediaKeySystemMediaCapability> audio_capabilities; + + for (size_t i = 0; i < candidate.audioCapabilities.size(); i++) { + const blink::WebMediaKeySystemMediaCapability& capabilities = + candidate.audioCapabilities[i]; + if (capabilities.mimeType.isEmpty()) + return false; + if (!base::IsStringASCII(capabilities.mimeType) || + !base::IsStringASCII(capabilities.codecs) || + !IsSupportedContentType( + key_system, base::UTF16ToASCII(capabilities.mimeType), + base::UTF16ToASCII(capabilities.codecs))) { + continue; + } + // TODO(sandersd): Support robustness. + if (!capabilities.robustness.isEmpty()) + continue; + audio_capabilities.push_back(capabilities); + } + + if (audio_capabilities.empty()) + return false; + + accumulated_configuration->audioCapabilities = audio_capabilities; + } + + if (!candidate.videoCapabilities.isEmpty()) { + std::vector<blink::WebMediaKeySystemMediaCapability> video_capabilities; + + for (size_t i = 0; i < candidate.videoCapabilities.size(); i++) { + const blink::WebMediaKeySystemMediaCapability& capabilities = + candidate.videoCapabilities[i]; + if (capabilities.mimeType.isEmpty()) + return false; + if (!base::IsStringASCII(capabilities.mimeType) || + !base::IsStringASCII(capabilities.codecs) || + !IsSupportedContentType( + key_system, base::UTF16ToASCII(capabilities.mimeType), + base::UTF16ToASCII(capabilities.codecs))) { + continue; + } + // TODO(sandersd): Support robustness. + if (!capabilities.robustness.isEmpty()) + continue; + video_capabilities.push_back(capabilities); + } + + if (video_capabilities.empty()) + return false; + + accumulated_configuration->videoCapabilities = video_capabilities; + } + + // TODO(sandersd): Prompt for distinctive identifiers and/or persistent state + // if required. Make sure that future checks are silent. + // http://crbug.com/446263. + return true; } @@ -32,60 +142,59 @@ void WebEncryptedMediaClientImpl::requestMediaKeySystemAccess( blink::WebEncryptedMediaRequest request) { // TODO(jrummell): This should be asynchronous. - // Continued from requestMediaKeySystemAccess(), step 5, from - // https://dvcs.w3.org/hg/html-media/raw-file/default/encrypted-media/encrypted-media.html#requestmediakeysystemaccess + // Continued from requestMediaKeySystemAccess(), step 7, from + // https://w3c.github.io/encrypted-media/#requestmediakeysystemaccess // - // 5.1 If keySystem is not supported or not allowed in the origin of the - // calling context's Document, return a promise rejected with a new - // DOMException whose name is NotSupportedError. - // (Handled by Chromium.) - - // 5.2 If supportedConfigurations was not provided, resolve the promise - // with a new MediaKeySystemAccess object, execute the following steps: - size_t number_configs = request.supportedConfigurations().size(); - if (!number_configs) { - // 5.2.1 Let access be a new MediaKeySystemAccess object, and initialize - // it as follows: - // 5.2.1.1 Set the keySystem attribute to keySystem. - // 5.2.2 Resolve promise with access and abort these steps. + // 7.1 If keySystem is not one of the Key Systems supported by the user + // agent, reject promise with with a new DOMException whose name is + // NotSupportedError. String comparison is case-sensitive. + if (!base::IsStringASCII(request.keySystem())) { + request.requestNotSupported("Only ASCII keySystems are supported"); + return; + } + + std::string key_system = base::UTF16ToASCII(request.keySystem()); + if (!IsConcreteSupportedKeySystem(key_system)) { + request.requestNotSupported("Unsupported keySystem"); + return; + } + + // 7.2 Let implementation be the implementation of keySystem. + // 7.3 Follow the steps for the first matching condition from the following + // list: + // - If supportedConfigurations was not provided, run the Is Key System + // Supported? algorithm and if successful, resolve promise with access + // and abort these steps. + // TODO(sandersd): Remove pending the resolution of + // https://github.com/w3c/encrypted-media/issues/1. + const blink::WebVector<blink::WebMediaKeySystemConfiguration>& + configurations = request.supportedConfigurations(); + if (configurations.isEmpty()) { request.requestSucceeded(WebContentDecryptionModuleAccessImpl::Create( request.keySystem(), request.securityOrigin(), cdm_factory_.get())); return; } - // 5.3 For each element of supportedConfigurations: - // 5.3.1 Let combination be the element. - // 5.3.2 For each dictionary member in combination: - for (size_t i = 0; i < number_configs; ++i) { - const auto& combination = request.supportedConfigurations()[i]; - // 5.3.2.1 If the member's value cannot be satisfied together in - // combination with the previous members, continue to the next - // iteration of the loop. - // 5.3.3 If keySystem is supported and allowed in the origin of the - // calling context's Document in the configuration specified by - // the combination of the values in combination, execute the - // following steps: - // FIXME: This test needs to be enhanced to use more values from - // combination. - for (size_t j = 0; j < combination.initDataTypes.size(); ++j) { - const auto& initDataType = combination.initDataTypes[j]; - if (IsKeySystemSupportedWithInitDataType(request.keySystem(), - initDataType)) { - // 5.3.3.1 Let access be a new MediaKeySystemAccess object, and - // initialize it as follows: - // 5.3.3.1.1 Set the keySystem attribute to keySystem. - // 5.3.3.2 Resolve promise with access and abort these steps. - request.requestSucceeded(WebContentDecryptionModuleAccessImpl::Create( - request.keySystem(), request.securityOrigin(), cdm_factory_.get())); - return; - } + // - Otherwise, for each value in supportedConfigurations, run the + // GetSuppored Configuration algorithm and if successful, resolve + // promise with access and abort these steps. + for (size_t i = 0; i < configurations.size(); i++) { + const blink::WebMediaKeySystemConfiguration& candidate = configurations[i]; + blink::WebMediaKeySystemConfiguration accumulated_configuration; + if (GetSupportedConfiguration(key_system, candidate, + request.securityOrigin(), + &accumulated_configuration)) { + // TODO(sandersd): Pass the accumulated configuration along. + // http://crbug.com/447059. + request.requestSucceeded(WebContentDecryptionModuleAccessImpl::Create( + request.keySystem(), request.securityOrigin(), cdm_factory_.get())); + return; } } - // 5.4 Reject promise with a new DOMException whose name is - // NotSupportedError. + // 7.4 Reject promise with a new DOMException whose name is NotSupportedError. request.requestNotSupported( - "There were no supported combinations in supportedConfigurations."); + "None of the requested configurations were supported."); } } // namespace media |