Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(528)

Side by Side Diff: media/blink/key_system_config_selector.cc

Issue 1052273004: Extract requestMediaKeySystemAccess() algorithm. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Class vs struct forward declarations. Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « media/blink/key_system_config_selector.h ('k') | media/blink/media_blink.gyp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "webencryptedmediaclient_impl.h" 5 #include "key_system_config_selector.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/metrics/histogram.h"
10 #include "base/strings/string_util.h" 9 #include "base/strings/string_util.h"
11 #include "base/strings/utf_string_conversions.h" 10 #include "base/strings/utf_string_conversions.h"
12 #include "media/base/key_systems.h" 11 #include "media/base/key_systems.h"
13 #include "media/base/media_permission.h" 12 #include "media/base/media_permission.h"
14 #include "media/blink/webcontentdecryptionmodule_impl.h"
15 #include "media/blink/webcontentdecryptionmoduleaccess_impl.h"
16 #include "media/blink/webmediaplayer_util.h" 13 #include "media/blink/webmediaplayer_util.h"
17 #include "net/base/mime_util.h" 14 #include "net/base/mime_util.h"
18 #include "third_party/WebKit/public/platform/WebEncryptedMediaRequest.h"
19 #include "third_party/WebKit/public/platform/WebMediaKeySystemConfiguration.h" 15 #include "third_party/WebKit/public/platform/WebMediaKeySystemConfiguration.h"
16 #include "third_party/WebKit/public/platform/WebSecurityOrigin.h"
20 #include "third_party/WebKit/public/platform/WebString.h" 17 #include "third_party/WebKit/public/platform/WebString.h"
21 #include "third_party/WebKit/public/platform/WebVector.h" 18 #include "third_party/WebKit/public/platform/WebVector.h"
19 #include "url/gurl.h"
22 20
23 namespace media { 21 namespace media {
24 22
25 // These names are used by UMA. 23 namespace {
26 const char kKeySystemSupportUMAPrefix[] =
27 "Media.EME.RequestMediaKeySystemAccess.";
28 24
29 enum ConfigurationSupport { 25 static EmeFeatureRequirement ConvertRequirement(
30 CONFIGURATION_NOT_SUPPORTED, 26 blink::WebMediaKeySystemConfiguration::Requirement requirement) {
31 CONFIGURATION_REQUIRES_PERMISSION, 27 switch (requirement) {
32 CONFIGURATION_SUPPORTED, 28 case blink::WebMediaKeySystemConfiguration::Requirement::Required:
29 return EME_FEATURE_REQUIRED;
30 case blink::WebMediaKeySystemConfiguration::Requirement::Optional:
31 return EME_FEATURE_OPTIONAL;
32 case blink::WebMediaKeySystemConfiguration::Requirement::NotAllowed:
33 return EME_FEATURE_NOT_ALLOWED;
34 }
35
36 NOTREACHED();
37 return EME_FEATURE_NOT_ALLOWED;
38 }
39
40 } // namespace
41
42 struct KeySystemConfigSelector::SelectionRequest {
43 std::string key_system;
44 blink::WebVector<blink::WebMediaKeySystemConfiguration>
45 candidate_configurations;
46 blink::WebSecurityOrigin security_origin;
47 base::Callback<void(const blink::WebMediaKeySystemConfiguration&)>
48 succeeded_cb;
49 base::Callback<void(const blink::WebString&)> not_supported_cb;
50 bool was_permission_requested = false;
51 bool is_permission_granted = false;
33 }; 52 };
34 53
35 // Accumulates configuration rules to determine if a feature (additional 54 // Accumulates configuration rules to determine if a feature (additional
36 // configuration rule) can be added to an accumulated configuration. 55 // configuration rule) can be added to an accumulated configuration.
37 class ConfigState { 56 class KeySystemConfigSelector::ConfigState {
38 public: 57 public:
39 ConfigState(bool was_permission_requested, bool is_permission_granted) 58 ConfigState(bool was_permission_requested, bool is_permission_granted)
40 : was_permission_requested_(was_permission_requested), 59 : was_permission_requested_(was_permission_requested),
41 is_permission_granted_(is_permission_granted) { 60 is_permission_granted_(is_permission_granted) {}
42 }
43 61
44 bool IsPermissionGranted() const { 62 bool IsPermissionGranted() const { return is_permission_granted_; }
45 return is_permission_granted_;
46 }
47 63
48 // Permission is possible if it has not been denied. 64 // Permission is possible if it has not been denied.
49 bool IsPermissionPossible() const { 65 bool IsPermissionPossible() const {
50 return is_permission_granted_ || !was_permission_requested_; 66 return is_permission_granted_ || !was_permission_requested_;
51 } 67 }
52 68
53 bool IsIdentifierRequired() const { 69 bool IsIdentifierRequired() const { return is_identifier_required_; }
54 return is_identifier_required_;
55 }
56 70
57 bool IsIdentifierRecommended() const { 71 bool IsIdentifierRecommended() const { return is_identifier_recommended_; }
58 return is_identifier_recommended_;
59 }
60 72
61 // Checks whether a rule is compatible with all previously added rules. 73 // Checks whether a rule is compatible with all previously added rules.
62 bool IsRuleSupported(EmeConfigRule rule) const { 74 bool IsRuleSupported(EmeConfigRule rule) const {
63 switch (rule) { 75 switch (rule) {
64 case EmeConfigRule::NOT_SUPPORTED: 76 case EmeConfigRule::NOT_SUPPORTED:
65 return false; 77 return false;
66 case EmeConfigRule::IDENTIFIER_NOT_ALLOWED: 78 case EmeConfigRule::IDENTIFIER_NOT_ALLOWED:
67 return !is_identifier_required_; 79 return !is_identifier_required_;
68 case EmeConfigRule::IDENTIFIER_REQUIRED: 80 case EmeConfigRule::IDENTIFIER_REQUIRED:
69 // TODO(sandersd): Confirm if we should be refusing these rules when 81 // TODO(sandersd): Confirm if we should be refusing these rules when
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
128 // identifier. 140 // identifier.
129 bool is_identifier_required_ = false; 141 bool is_identifier_required_ = false;
130 bool is_identifier_not_allowed_ = false; 142 bool is_identifier_not_allowed_ = false;
131 143
132 // Whether a rule has been added that recommends a distinctive identifier. 144 // Whether a rule has been added that recommends a distinctive identifier.
133 bool is_identifier_recommended_ = false; 145 bool is_identifier_recommended_ = false;
134 146
135 // Whether a rule has been added that requires or blocks persistent state. 147 // Whether a rule has been added that requires or blocks persistent state.
136 bool is_persistence_required_ = false; 148 bool is_persistence_required_ = false;
137 bool is_persistence_not_allowed_ = false; 149 bool is_persistence_not_allowed_ = false;
150
151 DISALLOW_COPY_AND_ASSIGN(ConfigState);
138 }; 152 };
139 153
140 static bool IsSupportedContentType( 154 KeySystemConfigSelector::KeySystemConfigSelector(
141 const KeySystems& key_systems, 155 const KeySystems* key_systems,
156 MediaPermission* media_permission)
157 : key_systems_(key_systems),
158 media_permission_(media_permission),
159 weak_factory_(this) {
160 DCHECK(key_systems_);
161 DCHECK(media_permission_);
162 }
163
164 KeySystemConfigSelector::~KeySystemConfigSelector() {
165 }
166
167 bool KeySystemConfigSelector::IsSupportedContentType(
142 const std::string& key_system, 168 const std::string& key_system,
143 EmeMediaType media_type, 169 EmeMediaType media_type,
144 const std::string& container_mime_type, 170 const std::string& container_mime_type,
145 const std::string& codecs) { 171 const std::string& codecs) {
146 // TODO(sandersd): Move contentType parsing from Blink to here so that invalid 172 // TODO(sandersd): Move contentType parsing from Blink to here so that invalid
147 // parameters can be rejected. http://crbug.com/417561 173 // parameters can be rejected. http://crbug.com/417561
148 std::string container_lower = base::StringToLowerASCII(container_mime_type); 174 std::string container_lower = base::StringToLowerASCII(container_mime_type);
149 175
150 // Check that |container_mime_type| and |codecs| are supported by the CDM. 176 // Check that |container_mime_type| and |codecs| are supported by the CDM.
151 // This check does not handle extended codecs, so extended codec information 177 // This check does not handle extended codecs, so extended codec information
152 // is stripped. 178 // is stripped.
153 std::vector<std::string> codec_vector; 179 std::vector<std::string> codec_vector;
154 net::ParseCodecString(codecs, &codec_vector, true); 180 net::ParseCodecString(codecs, &codec_vector, true);
155 if (!key_systems.IsSupportedCodecCombination( 181 if (!key_systems_->IsSupportedCodecCombination(
156 key_system, media_type, container_lower, codec_vector)) { 182 key_system, media_type, container_lower, codec_vector)) {
157 return false; 183 return false;
158 } 184 }
159 185
160 // Check that |container_mime_type| is supported by Chrome. This can only 186 // Check that |container_mime_type| is supported by Chrome. This can only
161 // happen if the CDM declares support for a container that Chrome does not. 187 // happen if the CDM declares support for a container that Chrome does not.
162 if (!net::IsSupportedMediaMimeType(container_lower)) { 188 if (!net::IsSupportedMediaMimeType(container_lower)) {
163 NOTREACHED(); 189 NOTREACHED();
164 return false; 190 return false;
165 } 191 }
166 192
167 // Check that |codecs| are supported by Chrome. This is done primarily to 193 // Check that |codecs| are supported by Chrome. This is done primarily to
168 // validate extended codecs, but it also ensures that the CDM cannot support 194 // validate extended codecs, but it also ensures that the CDM cannot support
169 // codecs that Chrome does not (which could complicate the robustness 195 // codecs that Chrome does not (which could complicate the robustness
170 // algorithm). 196 // algorithm).
171 if (codec_vector.empty()) 197 if (codec_vector.empty())
172 return true; 198 return true;
173 codec_vector.clear(); 199 codec_vector.clear();
174 net::ParseCodecString(codecs, &codec_vector, false); 200 net::ParseCodecString(codecs, &codec_vector, false);
175 return (net::IsSupportedStrictMediaMimeType(container_lower, codec_vector) == 201 return (net::IsSupportedStrictMediaMimeType(container_lower, codec_vector) ==
176 net::IsSupported); 202 net::IsSupported);
177 } 203 }
178 204
179 static bool GetSupportedCapabilities( 205 bool KeySystemConfigSelector::GetSupportedCapabilities(
180 const KeySystems& key_systems,
181 const std::string& key_system, 206 const std::string& key_system,
182 EmeMediaType media_type, 207 EmeMediaType media_type,
183 const blink::WebVector<blink::WebMediaKeySystemMediaCapability>& 208 const blink::WebVector<blink::WebMediaKeySystemMediaCapability>&
184 requested_media_capabilities, 209 requested_media_capabilities,
185 ConfigState* config_state, 210 KeySystemConfigSelector::ConfigState* config_state,
186 std::vector<blink::WebMediaKeySystemMediaCapability>* 211 std::vector<blink::WebMediaKeySystemMediaCapability>*
187 supported_media_capabilities) { 212 supported_media_capabilities) {
188 // From 213 // From
189 // https://w3c.github.io/encrypted-media/#get-supported-capabilities-for-media -type 214 // https://w3c.github.io/encrypted-media/#get-supported-capabilities-for-media -type
190 // 1. Let local accumulated capabilities be a local copy of partial 215 // 1. Let local accumulated capabilities be a local copy of partial
191 // configuration. 216 // configuration.
192 // (Skipped as we directly update |config_state|. This is safe because we 217 // (Skipped as we directly update |config_state|. This is safe because we
193 // only do so when at least one requested media capability is supported.) 218 // only do so when at least one requested media capability is supported.)
194 // 2. Let supported media capabilities be empty. 219 // 2. Let supported media capabilities be empty.
195 DCHECK_EQ(supported_media_capabilities->size(), 0ul); 220 DCHECK_EQ(supported_media_capabilities->size(), 0ul);
196 // 3. For each value in requested media capabilities: 221 // 3. For each value in requested media capabilities:
197 for (size_t i = 0; i < requested_media_capabilities.size(); i++) { 222 for (size_t i = 0; i < requested_media_capabilities.size(); i++) {
198 // 3.1. Let contentType be the value's contentType member. 223 // 3.1. Let contentType be the value's contentType member.
199 // 3.2. Let robustness be the value's robustness member. 224 // 3.2. Let robustness be the value's robustness member.
200 const blink::WebMediaKeySystemMediaCapability& capability = 225 const blink::WebMediaKeySystemMediaCapability& capability =
201 requested_media_capabilities[i]; 226 requested_media_capabilities[i];
202 // 3.3. If contentType is the empty string, return null. 227 // 3.3. If contentType is the empty string, return null.
203 if (capability.mimeType.isEmpty()) { 228 if (capability.mimeType.isEmpty()) {
204 DVLOG(2) << "Rejecting requested configuration because " 229 DVLOG(2) << "Rejecting requested configuration because "
205 << "a capability contentType was empty."; 230 << "a capability contentType was empty.";
206 return false; 231 return false;
207 } 232 }
208 // 3.4-3.11. (Implemented by IsSupportedContentType().) 233 // 3.4-3.11. (Implemented by IsSupportedContentType().)
209 if (!base::IsStringASCII(capability.mimeType) || 234 if (!base::IsStringASCII(capability.mimeType) ||
210 !base::IsStringASCII(capability.codecs) || 235 !base::IsStringASCII(capability.codecs) ||
211 !IsSupportedContentType(key_systems, key_system, media_type, 236 !IsSupportedContentType(key_system, media_type,
212 base::UTF16ToASCII(capability.mimeType), 237 base::UTF16ToASCII(capability.mimeType),
213 base::UTF16ToASCII(capability.codecs))) { 238 base::UTF16ToASCII(capability.codecs))) {
214 continue; 239 continue;
215 } 240 }
216 // 3.12. If robustness is not the empty string, run the following steps: 241 // 3.12. If robustness is not the empty string, run the following steps:
217 if (!capability.robustness.isEmpty()) { 242 if (!capability.robustness.isEmpty()) {
218 // 3.12.1. If robustness is an unrecognized value or not supported by 243 // 3.12.1. If robustness is an unrecognized value or not supported by
219 // implementation, continue to the next iteration. String 244 // implementation, continue to the next iteration. String
220 // comparison is case-sensitive. 245 // comparison is case-sensitive.
221 if (!base::IsStringASCII(capability.robustness)) 246 if (!base::IsStringASCII(capability.robustness))
222 continue; 247 continue;
223 EmeConfigRule robustness_rule = key_systems.GetRobustnessConfigRule( 248 EmeConfigRule robustness_rule = key_systems_->GetRobustnessConfigRule(
224 key_system, media_type, base::UTF16ToASCII(capability.robustness)); 249 key_system, media_type, base::UTF16ToASCII(capability.robustness));
225 if (!config_state->IsRuleSupported(robustness_rule)) 250 if (!config_state->IsRuleSupported(robustness_rule))
226 continue; 251 continue;
227 config_state->AddRule(robustness_rule); 252 config_state->AddRule(robustness_rule);
228 // 3.12.2. Add robustness to configuration. 253 // 3.12.2. Add robustness to configuration.
229 // (It's already added, we use capability as configuration.) 254 // (It's already added, we use capability as configuration.)
230 } 255 }
231 // 3.13. If the user agent and implementation do not support playback of 256 // 3.13. If the user agent and implementation do not support playback of
232 // encrypted media data as specified by configuration, including all 257 // encrypted media data as specified by configuration, including all
233 // media types, in combination with local accumulated capabilities, 258 // media types, in combination with local accumulated capabilities,
234 // continue to the next iteration. 259 // continue to the next iteration.
235 // (This is handled when adding rules to |config_state|.) 260 // (This is handled when adding rules to |config_state|.)
236 // 3.14. Add configuration to supported media capabilities. 261 // 3.14. Add configuration to supported media capabilities.
237 supported_media_capabilities->push_back(capability); 262 supported_media_capabilities->push_back(capability);
238 // 3.15. Add configuration to local accumulated capabilities. 263 // 3.15. Add configuration to local accumulated capabilities.
239 // (Skipped as we directly update |config_state|.) 264 // (Skipped as we directly update |config_state|.)
240 } 265 }
241 // 4. If supported media capabilities is empty, return null. 266 // 4. If supported media capabilities is empty, return null.
242 if (supported_media_capabilities->empty()) { 267 if (supported_media_capabilities->empty()) {
243 DVLOG(2) << "Rejecting requested configuration because " 268 DVLOG(2) << "Rejecting requested configuration because "
244 << "no capabilities were supported."; 269 << "no capabilities were supported.";
245 return false; 270 return false;
246 } 271 }
247 // 5. Return media type capabilities. 272 // 5. Return media type capabilities.
248 return true; 273 return true;
249 } 274 }
250 275
251 static EmeFeatureRequirement ConvertRequirement( 276 KeySystemConfigSelector::ConfigurationSupport
252 blink::WebMediaKeySystemConfiguration::Requirement requirement) { 277 KeySystemConfigSelector::GetSupportedConfiguration(
253 switch (requirement) {
254 case blink::WebMediaKeySystemConfiguration::Requirement::Required:
255 return EME_FEATURE_REQUIRED;
256 case blink::WebMediaKeySystemConfiguration::Requirement::Optional:
257 return EME_FEATURE_OPTIONAL;
258 case blink::WebMediaKeySystemConfiguration::Requirement::NotAllowed:
259 return EME_FEATURE_NOT_ALLOWED;
260 }
261
262 NOTREACHED();
263 return EME_FEATURE_NOT_ALLOWED;
264 }
265
266 static ConfigurationSupport GetSupportedConfiguration(
267 const KeySystems& key_systems,
268 const std::string& key_system, 278 const std::string& key_system,
269 const blink::WebMediaKeySystemConfiguration& candidate, 279 const blink::WebMediaKeySystemConfiguration& candidate,
270 bool was_permission_requested, 280 ConfigState* config_state,
271 bool is_permission_granted,
272 blink::WebMediaKeySystemConfiguration* accumulated_configuration) { 281 blink::WebMediaKeySystemConfiguration* accumulated_configuration) {
273 ConfigState config_state(was_permission_requested, is_permission_granted);
274
275 // From https://w3c.github.io/encrypted-media/#get-supported-configuration 282 // From https://w3c.github.io/encrypted-media/#get-supported-configuration
276 // 1. Let accumulated configuration be empty. (Done by caller.) 283 // 1. Let accumulated configuration be empty. (Done by caller.)
277 // 2. If the initDataTypes member is present in candidate configuration, run 284 // 2. If the initDataTypes member is present in candidate configuration, run
278 // the following steps: 285 // the following steps:
279 if (candidate.hasInitDataTypes) { 286 if (candidate.hasInitDataTypes) {
280 // 2.1. Let supported types be empty. 287 // 2.1. Let supported types be empty.
281 std::vector<blink::WebEncryptedMediaInitDataType> supported_types; 288 std::vector<blink::WebEncryptedMediaInitDataType> supported_types;
282 289
283 // 2.2. For each value in candidate configuration's initDataTypes member: 290 // 2.2. For each value in candidate configuration's initDataTypes member:
284 for (size_t i = 0; i < candidate.initDataTypes.size(); i++) { 291 for (size_t i = 0; i < candidate.initDataTypes.size(); i++) {
285 // 2.2.1. Let initDataType be the value. 292 // 2.2.1. Let initDataType be the value.
286 blink::WebEncryptedMediaInitDataType init_data_type = 293 blink::WebEncryptedMediaInitDataType init_data_type =
287 candidate.initDataTypes[i]; 294 candidate.initDataTypes[i];
288 // 2.2.2. If the implementation supports generating requests based on 295 // 2.2.2. If the implementation supports generating requests based on
289 // initDataType, add initDataType to supported types. String 296 // initDataType, add initDataType to supported types. String
290 // comparison is case-sensitive. The empty string is never 297 // comparison is case-sensitive. The empty string is never
291 // supported. 298 // supported.
292 if (init_data_type == blink::WebEncryptedMediaInitDataType::Unknown) 299 if (key_systems_->IsSupportedInitDataType(
293 continue;
294 if (key_systems.IsSupportedInitDataType(
295 key_system, ConvertToEmeInitDataType(init_data_type))) { 300 key_system, ConvertToEmeInitDataType(init_data_type))) {
296 supported_types.push_back(init_data_type); 301 supported_types.push_back(init_data_type);
297 } 302 }
298 } 303 }
299 304
300 // 2.3. If supported types is empty, return null. 305 // 2.3. If supported types is empty, return null.
301 if (supported_types.empty()) { 306 if (supported_types.empty()) {
302 DVLOG(2) << "Rejecting requested configuration because " 307 DVLOG(2) << "Rejecting requested configuration because "
303 << "no initDataType values were supported."; 308 << "no initDataType values were supported.";
304 return CONFIGURATION_NOT_SUPPORTED; 309 return CONFIGURATION_NOT_SUPPORTED;
305 } 310 }
306 311
307 // 2.4. Add supported types to accumulated configuration. 312 // 2.4. Add supported types to accumulated configuration.
308 accumulated_configuration->initDataTypes = supported_types; 313 accumulated_configuration->initDataTypes = supported_types;
309 } 314 }
310 315
311 // 3. Follow the steps for the value of candidate configuration's 316 // 3. Follow the steps for the value of candidate configuration's
312 // distinctiveIdentifier member from the following list: 317 // distinctiveIdentifier member from the following list:
313 // - "required": If the implementation does not support a persistent 318 // - "required": If the implementation does not support a persistent
314 // Distinctive Identifier in combination with accumulated 319 // Distinctive Identifier in combination with accumulated
315 // configuration, return null. 320 // configuration, return null.
316 // - "optional": Continue. 321 // - "optional": Continue.
317 // - "not-allowed": If the implementation requires a Distinctive 322 // - "not-allowed": If the implementation requires a Distinctive
318 // Identifier in combination with accumulated configuration, return 323 // Identifier in combination with accumulated configuration, return
319 // null. 324 // null.
320 // We also reject OPTIONAL when distinctive identifiers are ALWAYS_ENABLED and 325 // We also reject OPTIONAL when distinctive identifiers are ALWAYS_ENABLED and
321 // permission has already been denied. This would happen anyway at step 11. 326 // permission has already been denied. This would happen anyway at step 11.
322 EmeConfigRule di_rule = key_systems.GetDistinctiveIdentifierConfigRule( 327 EmeConfigRule di_rule = key_systems_->GetDistinctiveIdentifierConfigRule(
323 key_system, ConvertRequirement(candidate.distinctiveIdentifier)); 328 key_system, ConvertRequirement(candidate.distinctiveIdentifier));
324 if (!config_state.IsRuleSupported(di_rule)) { 329 if (!config_state->IsRuleSupported(di_rule)) {
325 DVLOG(2) << "Rejecting requested configuration because " 330 DVLOG(2) << "Rejecting requested configuration because "
326 << "the distinctiveIdentifier requirement was not supported."; 331 << "the distinctiveIdentifier requirement was not supported.";
327 return CONFIGURATION_NOT_SUPPORTED; 332 return CONFIGURATION_NOT_SUPPORTED;
328 } 333 }
329 config_state.AddRule(di_rule); 334 config_state->AddRule(di_rule);
330 335
331 // 4. Add the value of the candidate configuration's distinctiveIdentifier 336 // 4. Add the value of the candidate configuration's distinctiveIdentifier
332 // member to accumulated configuration. 337 // member to accumulated configuration.
333 accumulated_configuration->distinctiveIdentifier = 338 accumulated_configuration->distinctiveIdentifier =
334 candidate.distinctiveIdentifier; 339 candidate.distinctiveIdentifier;
335 340
336 // 5. Follow the steps for the value of candidate configuration's 341 // 5. Follow the steps for the value of candidate configuration's
337 // persistentState member from the following list: 342 // persistentState member from the following list:
338 // - "required": If the implementation does not support persisting state 343 // - "required": If the implementation does not support persisting state
339 // in combination with accumulated configuration, return null. 344 // in combination with accumulated configuration, return null.
340 // - "optional": Continue. 345 // - "optional": Continue.
341 // - "not-allowed": If the implementation requires persisting state in 346 // - "not-allowed": If the implementation requires persisting state in
342 // combination with accumulated configuration, return null. 347 // combination with accumulated configuration, return null.
343 EmeConfigRule ps_rule = key_systems.GetPersistentStateConfigRule( 348 EmeConfigRule ps_rule = key_systems_->GetPersistentStateConfigRule(
344 key_system, ConvertRequirement(candidate.persistentState)); 349 key_system, ConvertRequirement(candidate.persistentState));
345 if (!config_state.IsRuleSupported(ps_rule)) { 350 if (!config_state->IsRuleSupported(ps_rule)) {
346 DVLOG(2) << "Rejecting requested configuration because " 351 DVLOG(2) << "Rejecting requested configuration because "
347 << "the persistentState requirement was not supported."; 352 << "the persistentState requirement was not supported.";
348 return CONFIGURATION_NOT_SUPPORTED; 353 return CONFIGURATION_NOT_SUPPORTED;
349 } 354 }
350 config_state.AddRule(ps_rule); 355 config_state->AddRule(ps_rule);
351 356
352 // 6. Add the value of the candidate configuration's persistentState 357 // 6. Add the value of the candidate configuration's persistentState
353 // member to accumulated configuration. 358 // member to accumulated configuration.
354 accumulated_configuration->persistentState = candidate.persistentState; 359 accumulated_configuration->persistentState = candidate.persistentState;
355 360
356 // 7. Follow the steps for the first matching condition from the following 361 // 7. Follow the steps for the first matching condition from the following
357 // list: 362 // list:
358 // - If the sessionTypes member is present in candidate configuration, 363 // - If the sessionTypes member is present in candidate configuration,
359 // let session types be candidate configuration's sessionTypes member. 364 // let session types be candidate configuration's sessionTypes member.
360 // - Otherwise, let session types be [ "temporary" ]. 365 // - Otherwise, let session types be [ "temporary" ].
(...skipping 23 matching lines...) Expand all
384 switch (session_type) { 389 switch (session_type) {
385 case blink::WebEncryptedMediaSessionType::Unknown: 390 case blink::WebEncryptedMediaSessionType::Unknown:
386 DVLOG(2) << "Rejecting requested configuration because " 391 DVLOG(2) << "Rejecting requested configuration because "
387 << "a required session type was not recognized."; 392 << "a required session type was not recognized.";
388 return CONFIGURATION_NOT_SUPPORTED; 393 return CONFIGURATION_NOT_SUPPORTED;
389 case blink::WebEncryptedMediaSessionType::Temporary: 394 case blink::WebEncryptedMediaSessionType::Temporary:
390 session_type_rule = EmeConfigRule::SUPPORTED; 395 session_type_rule = EmeConfigRule::SUPPORTED;
391 break; 396 break;
392 case blink::WebEncryptedMediaSessionType::PersistentLicense: 397 case blink::WebEncryptedMediaSessionType::PersistentLicense:
393 session_type_rule = 398 session_type_rule =
394 key_systems.GetPersistentLicenseSessionConfigRule(key_system); 399 key_systems_->GetPersistentLicenseSessionConfigRule(key_system);
395 break; 400 break;
396 case blink::WebEncryptedMediaSessionType::PersistentReleaseMessage: 401 case blink::WebEncryptedMediaSessionType::PersistentReleaseMessage:
397 session_type_rule = 402 session_type_rule =
398 key_systems.GetPersistentReleaseMessageSessionConfigRule( 403 key_systems_->GetPersistentReleaseMessageSessionConfigRule(
399 key_system); 404 key_system);
400 break; 405 break;
401 } 406 }
402 if (!config_state.IsRuleSupported(session_type_rule)) { 407 if (!config_state->IsRuleSupported(session_type_rule)) {
403 DVLOG(2) << "Rejecting requested configuration because " 408 DVLOG(2) << "Rejecting requested configuration because "
404 << "a required session type was not supported."; 409 << "a required session type was not supported.";
405 return CONFIGURATION_NOT_SUPPORTED; 410 return CONFIGURATION_NOT_SUPPORTED;
406 } 411 }
407 config_state.AddRule(session_type_rule); 412 config_state->AddRule(session_type_rule);
408 } 413 }
409 414
410 // 9. Add session types to accumulated configuration. 415 // 9. Add session types to accumulated configuration.
411 accumulated_configuration->sessionTypes = session_types; 416 accumulated_configuration->sessionTypes = session_types;
412 417
413 // 10. If the videoCapabilities member is present in candidate configuration: 418 // 10. If the videoCapabilities member is present in candidate configuration:
414 if (candidate.hasVideoCapabilities) { 419 if (candidate.hasVideoCapabilities) {
415 // 10.1. Let video capabilities be the result of executing the Get Supported 420 // 10.1. Let video capabilities be the result of executing the Get Supported
416 // Capabilities for Media Type algorithm on Video, candidate 421 // Capabilities for Media Type algorithm on Video, candidate
417 // configuration's videoCapabilities member, and accumulated 422 // configuration's videoCapabilities member, and accumulated
418 // configuration. 423 // configuration.
419 // 10.2. If video capabilities is null, return null. 424 // 10.2. If video capabilities is null, return null.
420 std::vector<blink::WebMediaKeySystemMediaCapability> video_capabilities; 425 std::vector<blink::WebMediaKeySystemMediaCapability> video_capabilities;
421 if (!GetSupportedCapabilities(key_systems, key_system, EmeMediaType::VIDEO, 426 if (!GetSupportedCapabilities(key_system, EmeMediaType::VIDEO,
422 candidate.videoCapabilities, 427 candidate.videoCapabilities, config_state,
423 &config_state, &video_capabilities)) { 428 &video_capabilities)) {
424 return CONFIGURATION_NOT_SUPPORTED; 429 return CONFIGURATION_NOT_SUPPORTED;
425 } 430 }
426 431
427 // 10.3. Add video capabilities to accumulated configuration. 432 // 10.3. Add video capabilities to accumulated configuration.
428 accumulated_configuration->videoCapabilities = video_capabilities; 433 accumulated_configuration->videoCapabilities = video_capabilities;
429 } 434 }
430 435
431 // 11. If the audioCapabilities member is present in candidate configuration: 436 // 11. If the audioCapabilities member is present in candidate configuration:
432 if (candidate.hasAudioCapabilities) { 437 if (candidate.hasAudioCapabilities) {
433 // 11.1. Let audio capabilities be the result of executing the Get Supported 438 // 11.1. Let audio capabilities be the result of executing the Get Supported
434 // Capabilities for Media Type algorithm on Audio, candidate 439 // Capabilities for Media Type algorithm on Audio, candidate
435 // configuration's audioCapabilities member, and accumulated 440 // configuration's audioCapabilities member, and accumulated
436 // configuration. 441 // configuration.
437 // 11.2. If audio capabilities is null, return null. 442 // 11.2. If audio capabilities is null, return null.
438 std::vector<blink::WebMediaKeySystemMediaCapability> audio_capabilities; 443 std::vector<blink::WebMediaKeySystemMediaCapability> audio_capabilities;
439 if (!GetSupportedCapabilities(key_systems, key_system, EmeMediaType::AUDIO, 444 if (!GetSupportedCapabilities(key_system, EmeMediaType::AUDIO,
440 candidate.audioCapabilities, 445 candidate.audioCapabilities, config_state,
441 &config_state, &audio_capabilities)) { 446 &audio_capabilities)) {
442 return CONFIGURATION_NOT_SUPPORTED; 447 return CONFIGURATION_NOT_SUPPORTED;
443 } 448 }
444 449
445 // 11.3. Add audio capabilities to accumulated configuration. 450 // 11.3. Add audio capabilities to accumulated configuration.
446 accumulated_configuration->audioCapabilities = audio_capabilities; 451 accumulated_configuration->audioCapabilities = audio_capabilities;
447 } 452 }
448 453
449 // 12. If accumulated configuration's distinctiveIdentifier value is 454 // 12. If accumulated configuration's distinctiveIdentifier value is
450 // "optional", follow the steps for the first matching condition from the 455 // "optional", follow the steps for the first matching condition from the
451 // following list: 456 // following list:
452 // - If the implementation requires a Distinctive Identifier for any of 457 // - If the implementation requires a Distinctive Identifier for any of
453 // the combinations in accumulated configuration, change accumulated 458 // the combinations in accumulated configuration, change accumulated
454 // configuration's distinctiveIdentifier value to "required". 459 // configuration's distinctiveIdentifier value to "required".
455 // - Otherwise, change accumulated configuration's distinctiveIdentifier 460 // - Otherwise, change accumulated configuration's distinctiveIdentifier
456 // value to "not-allowed". 461 // value to "not-allowed".
457 if (accumulated_configuration->distinctiveIdentifier == 462 if (accumulated_configuration->distinctiveIdentifier ==
458 blink::WebMediaKeySystemConfiguration::Requirement::Optional) { 463 blink::WebMediaKeySystemConfiguration::Requirement::Optional) {
459 EmeConfigRule not_allowed_rule = 464 EmeConfigRule not_allowed_rule =
460 key_systems.GetDistinctiveIdentifierConfigRule( 465 key_systems_->GetDistinctiveIdentifierConfigRule(
461 key_system, EME_FEATURE_NOT_ALLOWED); 466 key_system, EME_FEATURE_NOT_ALLOWED);
462 EmeConfigRule required_rule = 467 EmeConfigRule required_rule =
463 key_systems.GetDistinctiveIdentifierConfigRule( 468 key_systems_->GetDistinctiveIdentifierConfigRule(key_system,
464 key_system, EME_FEATURE_REQUIRED); 469 EME_FEATURE_REQUIRED);
465 bool not_allowed_supported = config_state.IsRuleSupported(not_allowed_rule); 470 bool not_allowed_supported =
466 bool required_supported = config_state.IsRuleSupported(required_rule); 471 config_state->IsRuleSupported(not_allowed_rule);
472 bool required_supported = config_state->IsRuleSupported(required_rule);
467 // If a distinctive identifier is recommend and that is a possible outcome, 473 // If a distinctive identifier is recommend and that is a possible outcome,
468 // prefer that. 474 // prefer that.
469 if (required_supported && 475 if (required_supported && config_state->IsIdentifierRecommended() &&
470 config_state.IsIdentifierRecommended() && 476 config_state->IsPermissionPossible()) {
471 config_state.IsPermissionPossible()) {
472 not_allowed_supported = false; 477 not_allowed_supported = false;
473 } 478 }
474 if (not_allowed_supported) { 479 if (not_allowed_supported) {
475 accumulated_configuration->distinctiveIdentifier = 480 accumulated_configuration->distinctiveIdentifier =
476 blink::WebMediaKeySystemConfiguration::Requirement::NotAllowed; 481 blink::WebMediaKeySystemConfiguration::Requirement::NotAllowed;
477 config_state.AddRule(not_allowed_rule); 482 config_state->AddRule(not_allowed_rule);
478 } else if (required_supported) { 483 } else if (required_supported) {
479 accumulated_configuration->distinctiveIdentifier = 484 accumulated_configuration->distinctiveIdentifier =
480 blink::WebMediaKeySystemConfiguration::Requirement::Required; 485 blink::WebMediaKeySystemConfiguration::Requirement::Required;
481 config_state.AddRule(required_rule); 486 config_state->AddRule(required_rule);
482 } else { 487 } else {
483 // We should not have passed step 3. 488 // We should not have passed step 3.
484 NOTREACHED(); 489 NOTREACHED();
485 return CONFIGURATION_NOT_SUPPORTED; 490 return CONFIGURATION_NOT_SUPPORTED;
486 } 491 }
487 } 492 }
488 493
489 // 13. If accumulated configuration's persistentState value is "optional", 494 // 13. If accumulated configuration's persistentState value is "optional",
490 // follow the steps for the first matching condition from the following 495 // follow the steps for the first matching condition from the following
491 // list: 496 // list:
492 // - If the implementation requires persisting state for any of the 497 // - If the implementation requires persisting state for any of the
493 // combinations in accumulated configuration, change accumulated 498 // combinations in accumulated configuration, change accumulated
494 // configuration's persistentState value to "required". 499 // configuration's persistentState value to "required".
495 // - Otherwise, change accumulated configuration's persistentState value 500 // - Otherwise, change accumulated configuration's persistentState value
496 // to "not-allowed". 501 // to "not-allowed".
497 if (accumulated_configuration->persistentState == 502 if (accumulated_configuration->persistentState ==
498 blink::WebMediaKeySystemConfiguration::Requirement::Optional) { 503 blink::WebMediaKeySystemConfiguration::Requirement::Optional) {
499 EmeConfigRule not_allowed_rule = 504 EmeConfigRule not_allowed_rule = key_systems_->GetPersistentStateConfigRule(
500 key_systems.GetPersistentStateConfigRule( 505 key_system, EME_FEATURE_NOT_ALLOWED);
501 key_system, EME_FEATURE_NOT_ALLOWED); 506 EmeConfigRule required_rule = key_systems_->GetPersistentStateConfigRule(
502 EmeConfigRule required_rule = 507 key_system, EME_FEATURE_REQUIRED);
503 key_systems.GetPersistentStateConfigRule(
504 key_system, EME_FEATURE_REQUIRED);
505 // |distinctiveIdentifier| should not be affected after it is decided. 508 // |distinctiveIdentifier| should not be affected after it is decided.
506 DCHECK(not_allowed_rule == EmeConfigRule::NOT_SUPPORTED || 509 DCHECK(not_allowed_rule == EmeConfigRule::NOT_SUPPORTED ||
507 not_allowed_rule == EmeConfigRule::PERSISTENCE_NOT_ALLOWED); 510 not_allowed_rule == EmeConfigRule::PERSISTENCE_NOT_ALLOWED);
508 DCHECK(required_rule == EmeConfigRule::NOT_SUPPORTED || 511 DCHECK(required_rule == EmeConfigRule::NOT_SUPPORTED ||
509 required_rule == EmeConfigRule::PERSISTENCE_REQUIRED); 512 required_rule == EmeConfigRule::PERSISTENCE_REQUIRED);
510 bool not_allowed_supported = 513 bool not_allowed_supported =
511 config_state.IsRuleSupported(not_allowed_rule); 514 config_state->IsRuleSupported(not_allowed_rule);
512 bool required_supported = 515 bool required_supported = config_state->IsRuleSupported(required_rule);
513 config_state.IsRuleSupported(required_rule);
514 if (not_allowed_supported) { 516 if (not_allowed_supported) {
515 accumulated_configuration->persistentState = 517 accumulated_configuration->persistentState =
516 blink::WebMediaKeySystemConfiguration::Requirement::NotAllowed; 518 blink::WebMediaKeySystemConfiguration::Requirement::NotAllowed;
517 config_state.AddRule(not_allowed_rule); 519 config_state->AddRule(not_allowed_rule);
518 } else if (required_supported) { 520 } else if (required_supported) {
519 accumulated_configuration->persistentState = 521 accumulated_configuration->persistentState =
520 blink::WebMediaKeySystemConfiguration::Requirement::Required; 522 blink::WebMediaKeySystemConfiguration::Requirement::Required;
521 config_state.AddRule(required_rule); 523 config_state->AddRule(required_rule);
522 } else { 524 } else {
523 // We should not have passed step 5. 525 // We should not have passed step 5.
524 NOTREACHED(); 526 NOTREACHED();
525 return CONFIGURATION_NOT_SUPPORTED; 527 return CONFIGURATION_NOT_SUPPORTED;
526 } 528 }
527 } 529 }
528 530
529 // 14. If implementation in the configuration specified by the combination of 531 // 14. If implementation in the configuration specified by the combination of
530 // the values in accumulated configuration is not supported or not allowed 532 // the values in accumulated configuration is not supported or not allowed
531 // in the origin, return null. 533 // in the origin, return null.
532 // 15. If accumulated configuration's distinctiveIdentifier value is 534 // 15. If accumulated configuration's distinctiveIdentifier value is
533 // "required", [prompt the user for consent]. 535 // "required", [prompt the user for consent].
534 if (accumulated_configuration->distinctiveIdentifier == 536 if (accumulated_configuration->distinctiveIdentifier ==
535 blink::WebMediaKeySystemConfiguration::Requirement::Required) { 537 blink::WebMediaKeySystemConfiguration::Requirement::Required) {
536 // The caller is responsible for resolving what to do if permission is 538 // The caller is responsible for resolving what to do if permission is
537 // required but has been denied (it should treat it as NOT_SUPPORTED). 539 // required but has been denied (it should treat it as NOT_SUPPORTED).
538 if (!config_state.IsPermissionGranted()) 540 if (!config_state->IsPermissionGranted())
539 return CONFIGURATION_REQUIRES_PERMISSION; 541 return CONFIGURATION_REQUIRES_PERMISSION;
540 } 542 }
541 543
542 // 16. If the label member is present in candidate configuration, add the 544 // 16. If the label member is present in candidate configuration, add the
543 // value of the candidate configuration's label member to accumulated 545 // value of the candidate configuration's label member to accumulated
544 // configuration. 546 // configuration.
545 accumulated_configuration->label = candidate.label; 547 accumulated_configuration->label = candidate.label;
546 548
547 // 17. Return accumulated configuration. 549 // 17. Return accumulated configuration.
548 return CONFIGURATION_SUPPORTED; 550 return CONFIGURATION_SUPPORTED;
549 } 551 }
550 552
551 // Report usage of key system to UMA. There are 2 different counts logged: 553 void KeySystemConfigSelector::SelectConfig(
552 // 1. The key system is requested. 554 const blink::WebString& key_system,
553 // 2. The requested key system and options are supported. 555 const blink::WebVector<blink::WebMediaKeySystemConfiguration>&
554 // Each stat is only reported once per renderer frame per key system. 556 candidate_configurations,
555 // Note that WebEncryptedMediaClientImpl is only created once by each 557 const blink::WebSecurityOrigin& security_origin,
556 // renderer frame. 558 base::Callback<void(const blink::WebMediaKeySystemConfiguration&)>
557 class WebEncryptedMediaClientImpl::Reporter { 559 succeeded_cb,
558 public: 560 base::Callback<void(const blink::WebString&)> not_supported_cb) {
559 enum KeySystemSupportStatus {
560 KEY_SYSTEM_REQUESTED = 0,
561 KEY_SYSTEM_SUPPORTED = 1,
562 KEY_SYSTEM_SUPPORT_STATUS_COUNT
563 };
564
565 explicit Reporter(const std::string& key_system_for_uma)
566 : uma_name_(kKeySystemSupportUMAPrefix + key_system_for_uma),
567 is_request_reported_(false),
568 is_support_reported_(false) {}
569 ~Reporter() {}
570
571 void ReportRequested() {
572 if (is_request_reported_)
573 return;
574 Report(KEY_SYSTEM_REQUESTED);
575 is_request_reported_ = true;
576 }
577
578 void ReportSupported() {
579 DCHECK(is_request_reported_);
580 if (is_support_reported_)
581 return;
582 Report(KEY_SYSTEM_SUPPORTED);
583 is_support_reported_ = true;
584 }
585
586 private:
587 void Report(KeySystemSupportStatus status) {
588 // Not using UMA_HISTOGRAM_ENUMERATION directly because UMA_* macros
589 // require the names to be constant throughout the process' lifetime.
590 base::LinearHistogram::FactoryGet(
591 uma_name_, 1, KEY_SYSTEM_SUPPORT_STATUS_COUNT,
592 KEY_SYSTEM_SUPPORT_STATUS_COUNT + 1,
593 base::Histogram::kUmaTargetedHistogramFlag)->Add(status);
594 }
595
596 const std::string uma_name_;
597 bool is_request_reported_;
598 bool is_support_reported_;
599 };
600
601 WebEncryptedMediaClientImpl::WebEncryptedMediaClientImpl(
602 CdmFactory* cdm_factory,
603 MediaPermission* media_permission)
604 : key_systems_(KeySystems::GetInstance()),
605 cdm_factory_(cdm_factory),
606 media_permission_(media_permission),
607 weak_factory_(this) {
608 DCHECK(media_permission);
609 }
610
611 WebEncryptedMediaClientImpl::~WebEncryptedMediaClientImpl() {
612 }
613
614 void WebEncryptedMediaClientImpl::requestMediaKeySystemAccess(
615 blink::WebEncryptedMediaRequest request) {
616 // TODO(jrummell): This should be asynchronous, ideally not on the main
617 // thread.
618
619 // Continued from requestMediaKeySystemAccess(), step 7, from 561 // Continued from requestMediaKeySystemAccess(), step 7, from
620 // https://w3c.github.io/encrypted-media/#requestmediakeysystemaccess 562 // https://w3c.github.io/encrypted-media/#requestmediakeysystemaccess
621 // 563 //
622 // 7.1. If keySystem is not one of the Key Systems supported by the user 564 // 7.1. If keySystem is not one of the Key Systems supported by the user
623 // agent, reject promise with with a new DOMException whose name is 565 // agent, reject promise with with a new DOMException whose name is
624 // NotSupportedError. String comparison is case-sensitive. 566 // NotSupportedError. String comparison is case-sensitive.
625 if (!base::IsStringASCII(request.keySystem())) { 567 if (!base::IsStringASCII(key_system)) {
626 request.requestNotSupported("Only ASCII keySystems are supported"); 568 not_supported_cb.Run("Only ASCII keySystems are supported");
627 return; 569 return;
628 } 570 }
629 571
630 // Report this request to the UMA. 572 std::string key_system_ascii = base::UTF16ToASCII(key_system);
631 std::string key_system = base::UTF16ToASCII(request.keySystem()); 573 if (!key_systems_->IsSupportedKeySystem(key_system_ascii)) {
632 GetReporter(key_system)->ReportRequested(); 574 not_supported_cb.Run("Unsupported keySystem");
633
634 if (!key_systems_.IsSupportedKeySystem(key_system)) {
635 request.requestNotSupported("Unsupported keySystem");
636 return; 575 return;
637 } 576 }
638 577
639 // 7.2-7.4. Implemented by SelectSupportedConfiguration(). 578 // 7.2-7.4. Implemented by OnSelectConfig().
640 SelectSupportedConfiguration(request, false, false); 579 // TODO(sandersd): This should be async, ideally not on the main thread.
580 scoped_ptr<SelectionRequest> request(new SelectionRequest());
581 request->key_system = key_system_ascii;
582 request->candidate_configurations = candidate_configurations;
583 request->security_origin = security_origin;
584 request->succeeded_cb = succeeded_cb;
585 request->not_supported_cb = not_supported_cb;
586 SelectConfigInternal(request.Pass());
641 } 587 }
642 588
643 void WebEncryptedMediaClientImpl::SelectSupportedConfiguration( 589 void KeySystemConfigSelector::SelectConfigInternal(
644 blink::WebEncryptedMediaRequest request, 590 scoped_ptr<SelectionRequest> request) {
645 bool was_permission_requested,
646 bool is_permission_granted) {
647 // Continued from requestMediaKeySystemAccess(), step 7.1, from 591 // Continued from requestMediaKeySystemAccess(), step 7.1, from
648 // https://w3c.github.io/encrypted-media/#requestmediakeysystemaccess 592 // https://w3c.github.io/encrypted-media/#requestmediakeysystemaccess
649 // 593 //
650 // 7.2. Let implementation be the implementation of keySystem. 594 // 7.2. Let implementation be the implementation of keySystem.
651 std::string key_system = base::UTF16ToASCII(request.keySystem()); 595 // (|key_systems_| fills this role.)
652
653 // 7.3. For each value in supportedConfigurations: 596 // 7.3. For each value in supportedConfigurations:
654 const blink::WebVector<blink::WebMediaKeySystemConfiguration>& 597 for (size_t i = 0; i < request->candidate_configurations.size(); i++) {
655 configurations = request.supportedConfigurations();
656 for (size_t i = 0; i < configurations.size(); i++) {
657 // 7.3.1. Let candidate configuration be the value. 598 // 7.3.1. Let candidate configuration be the value.
658 const blink::WebMediaKeySystemConfiguration& candidate_configuration =
659 configurations[i];
660 // 7.3.2. Let supported configuration be the result of executing the Get 599 // 7.3.2. Let supported configuration be the result of executing the Get
661 // Supported Configuration algorithm on implementation, candidate 600 // Supported Configuration algorithm on implementation, candidate
662 // configuration, and origin. 601 // configuration, and origin.
663 // 7.3.3. If supported configuration is not null, [initialize and return a 602 // 7.3.3. If supported configuration is not null, [initialize and return a
664 // new MediaKeySystemAccess object.] 603 // new MediaKeySystemAccess object.]
604 ConfigState config_state(request->was_permission_requested,
605 request->is_permission_granted);
665 blink::WebMediaKeySystemConfiguration accumulated_configuration; 606 blink::WebMediaKeySystemConfiguration accumulated_configuration;
666 ConfigurationSupport supported = GetSupportedConfiguration( 607 ConfigurationSupport support = GetSupportedConfiguration(
667 key_systems_, key_system, candidate_configuration, 608 request->key_system, request->candidate_configurations[i],
668 was_permission_requested, is_permission_granted, 609 &config_state, &accumulated_configuration);
669 &accumulated_configuration); 610 switch (support) {
670 switch (supported) {
671 case CONFIGURATION_NOT_SUPPORTED: 611 case CONFIGURATION_NOT_SUPPORTED:
672 continue; 612 continue;
673 case CONFIGURATION_REQUIRES_PERMISSION: 613 case CONFIGURATION_REQUIRES_PERMISSION:
674 if (was_permission_requested) { 614 if (request->was_permission_requested) {
675 DVLOG(2) << "Rejecting requested configuration because " 615 DVLOG(2) << "Rejecting requested configuration because "
676 << "permission was denied."; 616 << "permission was denied.";
677 continue; 617 continue;
678 } 618 }
679 media_permission_->RequestPermission( 619 media_permission_->RequestPermission(
680 MediaPermission::PROTECTED_MEDIA_IDENTIFIER, 620 MediaPermission::PROTECTED_MEDIA_IDENTIFIER,
681 GURL(request.securityOrigin().toString()), 621 GURL(request->security_origin.toString()),
682 // Try again with |was_permission_requested| true and 622 base::Bind(&KeySystemConfigSelector::OnPermissionResult,
683 // |is_permission_granted| the value of the permission. 623 weak_factory_.GetWeakPtr(), base::Passed(&request)));
684 base::Bind(
685 &WebEncryptedMediaClientImpl::SelectSupportedConfiguration,
686 weak_factory_.GetWeakPtr(), request, true));
687 return; 624 return;
688 case CONFIGURATION_SUPPORTED: 625 case CONFIGURATION_SUPPORTED:
689 // Report that this request succeeded to the UMA. 626 request->succeeded_cb.Run(accumulated_configuration);
690 GetReporter(key_system)->ReportSupported();
691 request.requestSucceeded(WebContentDecryptionModuleAccessImpl::Create(
692 request.keySystem(), accumulated_configuration,
693 request.securityOrigin(), weak_factory_.GetWeakPtr()));
694 return; 627 return;
695 } 628 }
696 } 629 }
697 630
698 // 7.4. Reject promise with a new DOMException whose name is 631 // 7.4. Reject promise with a new DOMException whose name is
699 // NotSupportedError. 632 // NotSupportedError.
700 request.requestNotSupported( 633 request->not_supported_cb.Run(
701 "None of the requested configurations were supported."); 634 "None of the requested configurations were supported.");
702 } 635 }
703 636
704 void WebEncryptedMediaClientImpl::CreateCdm( 637 void KeySystemConfigSelector::OnPermissionResult(
705 const blink::WebString& key_system, 638 scoped_ptr<SelectionRequest> request,
706 bool allow_distinctive_identifier, 639 bool is_permission_granted) {
707 bool allow_persistent_state, 640 request->was_permission_requested = true;
708 const blink::WebSecurityOrigin& security_origin, 641 request->is_permission_granted = is_permission_granted;
709 blink::WebContentDecryptionModuleResult result) { 642 SelectConfigInternal(request.Pass());
710 WebContentDecryptionModuleImpl::Create(
711 cdm_factory_, key_system, allow_distinctive_identifier,
712 allow_persistent_state, security_origin, result);
713 }
714
715 // Lazily create Reporters.
716 WebEncryptedMediaClientImpl::Reporter* WebEncryptedMediaClientImpl::GetReporter(
717 const std::string& key_system) {
718 std::string uma_name = GetKeySystemNameForUMA(key_system);
719 Reporter* reporter = reporters_.get(uma_name);
720 if (reporter != nullptr)
721 return reporter;
722
723 // Reporter not found, so create one.
724 auto result =
725 reporters_.add(uma_name, make_scoped_ptr(new Reporter(uma_name)));
726 DCHECK(result.second);
727 return result.first->second;
728 } 643 }
729 644
730 } // namespace media 645 } // namespace media
OLDNEW
« no previous file with comments | « media/blink/key_system_config_selector.h ('k') | media/blink/media_blink.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698