Chromium Code Reviews| 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 |