OLD | NEW |
---|---|
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 "key_system_config_selector.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/strings/string_util.h" | 9 #include "base/strings/string_util.h" |
10 #include "base/strings/utf_string_conversions.h" | 10 #include "base/strings/utf_string_conversions.h" |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
170 return !is_identifier_not_allowed_ && IsPermissionPossible(); | 170 return !is_identifier_not_allowed_ && IsPermissionPossible(); |
171 case EmeConfigRule::IDENTIFIER_RECOMMENDED: | 171 case EmeConfigRule::IDENTIFIER_RECOMMENDED: |
172 return true; | 172 return true; |
173 case EmeConfigRule::PERSISTENCE_NOT_ALLOWED: | 173 case EmeConfigRule::PERSISTENCE_NOT_ALLOWED: |
174 return !is_persistence_required_; | 174 return !is_persistence_required_; |
175 case EmeConfigRule::PERSISTENCE_REQUIRED: | 175 case EmeConfigRule::PERSISTENCE_REQUIRED: |
176 return !is_persistence_not_allowed_; | 176 return !is_persistence_not_allowed_; |
177 case EmeConfigRule::IDENTIFIER_AND_PERSISTENCE_REQUIRED: | 177 case EmeConfigRule::IDENTIFIER_AND_PERSISTENCE_REQUIRED: |
178 return (!is_identifier_not_allowed_ && IsPermissionPossible() && | 178 return (!is_identifier_not_allowed_ && IsPermissionPossible() && |
179 !is_persistence_not_allowed_); | 179 !is_persistence_not_allowed_); |
180 #if defined(OS_ANDROID) | |
181 case EmeConfigRule::SECURE_CODECS_NOT_ALLOWED: | |
182 return !are_secure_codecs_required_; | |
183 case EmeConfigRule::SECURE_CODECS_REQUIRED: | |
184 return !are_secure_codecs_not_allowed_; | |
185 #endif // defined(OS_ANDROID) | |
180 case EmeConfigRule::SUPPORTED: | 186 case EmeConfigRule::SUPPORTED: |
181 return true; | 187 return true; |
182 } | 188 } |
183 NOTREACHED(); | 189 NOTREACHED(); |
184 return false; | 190 return false; |
185 } | 191 } |
186 | 192 |
187 // Add a rule to the accumulated configuration state. | 193 // Add a rule to the accumulated configuration state. |
188 void AddRule(EmeConfigRule rule) { | 194 void AddRule(EmeConfigRule rule) { |
189 DCHECK(IsRuleSupported(rule)); | 195 DCHECK(IsRuleSupported(rule)); |
(...skipping 13 matching lines...) Expand all Loading... | |
203 case EmeConfigRule::PERSISTENCE_NOT_ALLOWED: | 209 case EmeConfigRule::PERSISTENCE_NOT_ALLOWED: |
204 is_persistence_not_allowed_ = true; | 210 is_persistence_not_allowed_ = true; |
205 return; | 211 return; |
206 case EmeConfigRule::PERSISTENCE_REQUIRED: | 212 case EmeConfigRule::PERSISTENCE_REQUIRED: |
207 is_persistence_required_ = true; | 213 is_persistence_required_ = true; |
208 return; | 214 return; |
209 case EmeConfigRule::IDENTIFIER_AND_PERSISTENCE_REQUIRED: | 215 case EmeConfigRule::IDENTIFIER_AND_PERSISTENCE_REQUIRED: |
210 is_identifier_required_ = true; | 216 is_identifier_required_ = true; |
211 is_persistence_required_ = true; | 217 is_persistence_required_ = true; |
212 return; | 218 return; |
219 #if defined(OS_ANDROID) | |
220 case EmeConfigRule::SECURE_CODECS_NOT_ALLOWED: | |
221 are_secure_codecs_not_allowed_ = true; | |
222 return; | |
223 case EmeConfigRule::SECURE_CODECS_REQUIRED: | |
224 are_secure_codecs_required_ = true; | |
225 return; | |
226 #endif // defined(OS_ANDROID) | |
213 case EmeConfigRule::SUPPORTED: | 227 case EmeConfigRule::SUPPORTED: |
214 return; | 228 return; |
215 } | 229 } |
216 NOTREACHED(); | 230 NOTREACHED(); |
217 } | 231 } |
218 | 232 |
219 private: | 233 private: |
220 // Whether permission to use a distinctive identifier was requested. If set, | 234 // Whether permission to use a distinctive identifier was requested. If set, |
221 // |is_permission_granted_| represents the final decision. | 235 // |is_permission_granted_| represents the final decision. |
222 const bool was_permission_requested_; | 236 // (Not changed by adding rules.) |
237 bool was_permission_requested_; | |
223 | 238 |
224 // Whether permission to use a distinctive identifier has been granted. | 239 // Whether permission to use a distinctive identifier has been granted. |
225 const bool is_permission_granted_; | 240 // (Not changed by adding rules.) |
241 bool is_permission_granted_; | |
226 | 242 |
227 // Whether a rule has been added that requires or blocks a distinctive | 243 // Whether a rule has been added that requires or blocks a distinctive |
228 // identifier. | 244 // identifier. |
229 bool is_identifier_required_ = false; | 245 bool is_identifier_required_ = false; |
230 bool is_identifier_not_allowed_ = false; | 246 bool is_identifier_not_allowed_ = false; |
231 | 247 |
232 // Whether a rule has been added that recommends a distinctive identifier. | 248 // Whether a rule has been added that recommends a distinctive identifier. |
233 bool is_identifier_recommended_ = false; | 249 bool is_identifier_recommended_ = false; |
234 | 250 |
235 // Whether a rule has been added that requires or blocks persistent state. | 251 // Whether a rule has been added that requires or blocks persistent state. |
236 bool is_persistence_required_ = false; | 252 bool is_persistence_required_ = false; |
237 bool is_persistence_not_allowed_ = false; | 253 bool is_persistence_not_allowed_ = false; |
238 | 254 |
239 DISALLOW_COPY_AND_ASSIGN(ConfigState); | 255 #if defined(OS_ANDROID) |
256 // Whether a rule has been added that requires or blocks secure codecs. | |
257 bool are_secure_codecs_required_ = false; | |
258 bool are_secure_codecs_not_allowed_ = false; | |
259 #endif // defined(OS_ANDROID) | |
240 }; | 260 }; |
241 | 261 |
242 KeySystemConfigSelector::KeySystemConfigSelector( | 262 KeySystemConfigSelector::KeySystemConfigSelector( |
243 const KeySystems* key_systems, | 263 const KeySystems* key_systems, |
244 MediaPermission* media_permission) | 264 MediaPermission* media_permission) |
245 : key_systems_(key_systems), | 265 : key_systems_(key_systems), |
246 media_permission_(media_permission), | 266 media_permission_(media_permission), |
247 weak_factory_(this) { | 267 weak_factory_(this) { |
248 DCHECK(key_systems_); | 268 DCHECK(key_systems_); |
249 DCHECK(media_permission_); | 269 DCHECK(media_permission_); |
250 } | 270 } |
251 | 271 |
252 KeySystemConfigSelector::~KeySystemConfigSelector() { | 272 KeySystemConfigSelector::~KeySystemConfigSelector() { |
253 } | 273 } |
254 | 274 |
255 bool KeySystemConfigSelector::IsSupportedContentType( | 275 bool KeySystemConfigSelector::IsSupportedContentType( |
256 const std::string& key_system, | 276 const std::string& key_system, |
257 EmeMediaType media_type, | 277 EmeMediaType media_type, |
258 const std::string& container_mime_type, | 278 const std::string& container_mime_type, |
259 const std::string& codecs) { | 279 const std::string& codecs, |
280 KeySystemConfigSelector::ConfigState* config_state) { | |
260 // TODO(sandersd): Move contentType parsing from Blink to here so that invalid | 281 // TODO(sandersd): Move contentType parsing from Blink to here so that invalid |
261 // parameters can be rejected. http://crbug.com/417561 | 282 // parameters can be rejected. http://crbug.com/417561 |
262 std::string container_lower = base::StringToLowerASCII(container_mime_type); | 283 std::string container_lower = base::StringToLowerASCII(container_mime_type); |
263 | 284 |
264 // Check that |container_mime_type| and |codecs| are supported by the CDM. | 285 // Check that |container_mime_type| is supported by Chrome. |
265 // This check does not handle extended codecs, so extended codec information | 286 if (!net::IsSupportedMediaMimeType(container_lower)) |
266 // is stripped. | |
267 std::vector<std::string> codec_vector; | |
268 net::ParseCodecString(codecs, &codec_vector, true); | |
269 if (!key_systems_->IsSupportedCodecCombination( | |
270 key_system, media_type, container_lower, codec_vector)) { | |
271 return false; | 287 return false; |
272 } | |
273 | |
274 // Check that |container_mime_type| is supported by Chrome. This can only | |
275 // happen if the CDM declares support for a container that Chrome does not. | |
276 if (!net::IsSupportedMediaMimeType(container_lower)) { | |
277 NOTREACHED(); | |
278 return false; | |
279 } | |
280 | 288 |
281 // Check that |codecs| are supported by Chrome. This is done primarily to | 289 // Check that |codecs| are supported by Chrome. This is done primarily to |
282 // validate extended codecs, but it also ensures that the CDM cannot support | 290 // validate extended codecs, but it also ensures that the CDM cannot support |
283 // codecs that Chrome does not (which could complicate the robustness | 291 // codecs that Chrome does not (which could complicate the robustness |
284 // algorithm). | 292 // algorithm). |
285 if (codec_vector.empty()) | 293 std::vector<std::string> codec_vector; |
286 return true; | |
287 codec_vector.clear(); | |
288 net::ParseCodecString(codecs, &codec_vector, false); | 294 net::ParseCodecString(codecs, &codec_vector, false); |
289 return (net::IsSupportedStrictMediaMimeType(container_lower, codec_vector) == | 295 if (!codec_vector.empty() && |
290 net::IsSupported); | 296 (net::IsSupportedStrictMediaMimeType(container_lower, codec_vector) != |
297 net::IsSupported)) { | |
298 return false; | |
299 } | |
300 | |
301 // Check that |container_mime_type| and |codecs| are supported by the CDM. | |
302 // This check does not handle extended codecs, so extended codec information | |
303 // is stripped. | |
ddorwin
2015/05/01 20:39:12
Validation of the correctness of such strings was
sandersd (OOO until July 31)
2015/05/01 21:57:01
Done.
| |
304 std::vector<std::string> stripped_codec_vector; | |
305 net::ParseCodecString(codecs, &stripped_codec_vector, true); | |
306 EmeConfigRule codecs_rule = key_systems_->GetContentTypeConfigRule( | |
307 key_system, media_type, container_lower, stripped_codec_vector); | |
308 if (!config_state->IsRuleSupported(codecs_rule)) | |
309 return false; | |
310 config_state->AddRule(codecs_rule); | |
ddorwin
2015/05/01 20:39:12
nit: empty line
sandersd (OOO until July 31)
2015/05/01 21:57:02
Done.
| |
311 return true; | |
291 } | 312 } |
292 | 313 |
293 bool KeySystemConfigSelector::GetSupportedCapabilities( | 314 bool KeySystemConfigSelector::GetSupportedCapabilities( |
294 const std::string& key_system, | 315 const std::string& key_system, |
295 EmeMediaType media_type, | 316 EmeMediaType media_type, |
296 const blink::WebVector<blink::WebMediaKeySystemMediaCapability>& | 317 const blink::WebVector<blink::WebMediaKeySystemMediaCapability>& |
297 requested_media_capabilities, | 318 requested_media_capabilities, |
298 KeySystemConfigSelector::ConfigState* config_state, | 319 KeySystemConfigSelector::ConfigState* config_state, |
299 std::vector<blink::WebMediaKeySystemMediaCapability>* | 320 std::vector<blink::WebMediaKeySystemMediaCapability>* |
300 supported_media_capabilities) { | 321 supported_media_capabilities) { |
(...skipping 10 matching lines...) Expand all Loading... | |
311 // 3.1. Let contentType be the value's contentType member. | 332 // 3.1. Let contentType be the value's contentType member. |
312 // 3.2. Let robustness be the value's robustness member. | 333 // 3.2. Let robustness be the value's robustness member. |
313 const blink::WebMediaKeySystemMediaCapability& capability = | 334 const blink::WebMediaKeySystemMediaCapability& capability = |
314 requested_media_capabilities[i]; | 335 requested_media_capabilities[i]; |
315 // 3.3. If contentType is the empty string, return null. | 336 // 3.3. If contentType is the empty string, return null. |
316 if (capability.mimeType.isEmpty()) { | 337 if (capability.mimeType.isEmpty()) { |
317 DVLOG(2) << "Rejecting requested configuration because " | 338 DVLOG(2) << "Rejecting requested configuration because " |
318 << "a capability contentType was empty."; | 339 << "a capability contentType was empty."; |
319 return false; | 340 return false; |
320 } | 341 } |
342 | |
321 // 3.4-3.11. (Implemented by IsSupportedContentType().) | 343 // 3.4-3.11. (Implemented by IsSupportedContentType().) |
344 ConfigState proposed_config_state = *config_state; | |
322 if (!base::IsStringASCII(capability.mimeType) || | 345 if (!base::IsStringASCII(capability.mimeType) || |
323 !base::IsStringASCII(capability.codecs) || | 346 !base::IsStringASCII(capability.codecs) || |
324 !IsSupportedContentType(key_system, media_type, | 347 !IsSupportedContentType(key_system, media_type, |
325 base::UTF16ToASCII(capability.mimeType), | 348 base::UTF16ToASCII(capability.mimeType), |
326 base::UTF16ToASCII(capability.codecs))) { | 349 base::UTF16ToASCII(capability.codecs), |
350 &proposed_config_state)) { | |
327 continue; | 351 continue; |
328 } | 352 } |
329 // 3.12. If robustness is not the empty string, run the following steps: | 353 // 3.12. If robustness is not the empty string, run the following steps: |
330 if (!capability.robustness.isEmpty()) { | 354 if (!capability.robustness.isEmpty()) { |
331 // 3.12.1. If robustness is an unrecognized value or not supported by | 355 // 3.12.1. If robustness is an unrecognized value or not supported by |
332 // implementation, continue to the next iteration. String | 356 // implementation, continue to the next iteration. String |
333 // comparison is case-sensitive. | 357 // comparison is case-sensitive. |
334 if (!base::IsStringASCII(capability.robustness)) | 358 if (!base::IsStringASCII(capability.robustness)) |
335 continue; | 359 continue; |
336 EmeConfigRule robustness_rule = key_systems_->GetRobustnessConfigRule( | 360 EmeConfigRule robustness_rule = key_systems_->GetRobustnessConfigRule( |
337 key_system, media_type, base::UTF16ToASCII(capability.robustness)); | 361 key_system, media_type, base::UTF16ToASCII(capability.robustness)); |
338 if (!config_state->IsRuleSupported(robustness_rule)) | 362 if (!proposed_config_state.IsRuleSupported(robustness_rule)) |
339 continue; | 363 continue; |
340 config_state->AddRule(robustness_rule); | 364 proposed_config_state.AddRule(robustness_rule); |
341 // 3.12.2. Add robustness to configuration. | 365 // 3.12.2. Add robustness to configuration. |
342 // (It's already added, we use capability as configuration.) | 366 // (It's already added, we use capability as configuration.) |
343 } | 367 } |
344 // 3.13. If the user agent and implementation do not support playback of | 368 // 3.13. If the user agent and implementation do not support playback of |
345 // encrypted media data as specified by configuration, including all | 369 // encrypted media data as specified by configuration, including all |
346 // media types, in combination with local accumulated capabilities, | 370 // media types, in combination with local accumulated capabilities, |
347 // continue to the next iteration. | 371 // continue to the next iteration. |
348 // (This is handled when adding rules to |config_state|.) | 372 // (This is handled when adding rules to |proposed_config_state|.) |
349 // 3.14. Add configuration to supported media capabilities. | 373 // 3.14. Add configuration to supported media capabilities. |
350 supported_media_capabilities->push_back(capability); | 374 supported_media_capabilities->push_back(capability); |
351 // 3.15. Add configuration to local accumulated capabilities. | 375 // 3.15. Add configuration to local accumulated capabilities. |
352 // (Skipped as we directly update |config_state|.) | 376 *config_state = proposed_config_state; |
353 } | 377 } |
354 // 4. If supported media capabilities is empty, return null. | 378 // 4. If supported media capabilities is empty, return null. |
355 if (supported_media_capabilities->empty()) { | 379 if (supported_media_capabilities->empty()) { |
356 DVLOG(2) << "Rejecting requested configuration because " | 380 DVLOG(2) << "Rejecting requested configuration because " |
357 << "no capabilities were supported."; | 381 << "no capabilities were supported."; |
358 return false; | 382 return false; |
359 } | 383 } |
360 // 5. Return media type capabilities. | 384 // 5. Return media type capabilities. |
361 return true; | 385 return true; |
362 } | 386 } |
363 | 387 |
364 KeySystemConfigSelector::ConfigurationSupport | 388 KeySystemConfigSelector::ConfigurationSupport |
365 KeySystemConfigSelector::GetSupportedConfiguration( | 389 KeySystemConfigSelector::GetSupportedConfiguration( |
366 const std::string& key_system, | 390 const std::string& key_system, |
367 const blink::WebMediaKeySystemConfiguration& candidate, | 391 const blink::WebMediaKeySystemConfiguration& candidate, |
368 ConfigState* config_state, | 392 ConfigState* config_state, |
369 blink::WebMediaKeySystemConfiguration* accumulated_configuration) { | 393 blink::WebMediaKeySystemConfiguration* accumulated_configuration) { |
394 // TODO(sandersd): Set state of SECURE_CODECS from renderer pref. | |
370 // From https://w3c.github.io/encrypted-media/#get-supported-configuration | 395 // From https://w3c.github.io/encrypted-media/#get-supported-configuration |
371 // 1. Let accumulated configuration be empty. (Done by caller.) | 396 // 1. Let accumulated configuration be empty. (Done by caller.) |
372 // 2. If the initDataTypes member is present in candidate configuration, run | 397 // 2. If the initDataTypes member is present in candidate configuration, run |
373 // the following steps: | 398 // the following steps: |
374 if (candidate.hasInitDataTypes) { | 399 if (candidate.hasInitDataTypes) { |
375 // 2.1. Let supported types be empty. | 400 // 2.1. Let supported types be empty. |
376 std::vector<blink::WebEncryptedMediaInitDataType> supported_types; | 401 std::vector<blink::WebEncryptedMediaInitDataType> supported_types; |
377 | 402 |
378 // 2.2. For each value in candidate configuration's initDataTypes member: | 403 // 2.2. For each value in candidate configuration's initDataTypes member: |
379 for (size_t i = 0; i < candidate.initDataTypes.size(); i++) { | 404 for (size_t i = 0; i < candidate.initDataTypes.size(); i++) { |
(...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
728 | 753 |
729 void KeySystemConfigSelector::OnPermissionResult( | 754 void KeySystemConfigSelector::OnPermissionResult( |
730 scoped_ptr<SelectionRequest> request, | 755 scoped_ptr<SelectionRequest> request, |
731 bool is_permission_granted) { | 756 bool is_permission_granted) { |
732 request->was_permission_requested = true; | 757 request->was_permission_requested = true; |
733 request->is_permission_granted = is_permission_granted; | 758 request->is_permission_granted = is_permission_granted; |
734 SelectConfigInternal(request.Pass()); | 759 SelectConfigInternal(request.Pass()); |
735 } | 760 } |
736 | 761 |
737 } // namespace media | 762 } // namespace media |
OLD | NEW |