summaryrefslogtreecommitdiffstats
path: root/media/blink
diff options
context:
space:
mode:
authorsandersd <sandersd@chromium.org>2015-01-09 17:44:28 -0800
committerCommit bot <commit-bot@chromium.org>2015-01-10 01:45:20 +0000
commit44e7f83d24f351dcbf7d398c6e3786378244fee7 (patch)
tree74923792876516b6a345c254780d95f9da07ec5c /media/blink
parenteebec0cf6a652c29bc5bd58f90671633e7e62d67 (diff)
downloadchromium_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.cc205
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