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 "media/blink/key_system_config_selector.h" | 5 #include "media/blink/key_system_config_selector.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 122 requirement == EmeFeatureRequirement::Optional) { | 122 requirement == EmeFeatureRequirement::Optional) { |
| 123 return EmeConfigRule::SUPPORTED; | 123 return EmeConfigRule::SUPPORTED; |
| 124 } | 124 } |
| 125 if (support == EmeFeatureSupport::NOT_SUPPORTED || | 125 if (support == EmeFeatureSupport::NOT_SUPPORTED || |
| 126 requirement == EmeFeatureRequirement::NotAllowed) { | 126 requirement == EmeFeatureRequirement::NotAllowed) { |
| 127 return EmeConfigRule::PERSISTENCE_NOT_ALLOWED; | 127 return EmeConfigRule::PERSISTENCE_NOT_ALLOWED; |
| 128 } | 128 } |
| 129 return EmeConfigRule::PERSISTENCE_REQUIRED; | 129 return EmeConfigRule::PERSISTENCE_REQUIRED; |
| 130 } | 130 } |
| 131 | 131 |
| 132 static bool IsPersistentSessionType( | |
| 133 blink::WebEncryptedMediaSessionType sessionType) { | |
| 134 switch (sessionType) { | |
| 135 case blink::WebEncryptedMediaSessionType::Temporary: | |
| 136 return false; | |
| 137 case blink::WebEncryptedMediaSessionType::PersistentLicense: | |
| 138 return true; | |
| 139 case blink::WebEncryptedMediaSessionType::PersistentReleaseMessage: | |
| 140 return true; | |
| 141 case blink::WebEncryptedMediaSessionType::Unknown: | |
| 142 break; | |
| 143 } | |
| 144 | |
| 145 NOTREACHED(); | |
| 146 return false; | |
| 147 } | |
| 148 | |
| 132 } // namespace | 149 } // namespace |
| 133 | 150 |
| 134 struct KeySystemConfigSelector::SelectionRequest { | 151 struct KeySystemConfigSelector::SelectionRequest { |
| 135 std::string key_system; | 152 std::string key_system; |
| 136 blink::WebVector<blink::WebMediaKeySystemConfiguration> | 153 blink::WebVector<blink::WebMediaKeySystemConfiguration> |
| 137 candidate_configurations; | 154 candidate_configurations; |
| 138 blink::WebSecurityOrigin security_origin; | 155 blink::WebSecurityOrigin security_origin; |
| 139 base::Callback<void(const blink::WebMediaKeySystemConfiguration&, | 156 base::Callback<void(const blink::WebMediaKeySystemConfiguration&, |
| 140 const CdmConfig&)> succeeded_cb; | 157 const CdmConfig&)> succeeded_cb; |
| 141 base::Callback<void(const blink::WebString&)> not_supported_cb; | 158 base::Callback<void(const blink::WebString&)> not_supported_cb; |
| (...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 427 // 5. Return media type capabilities. | 444 // 5. Return media type capabilities. |
| 428 return true; | 445 return true; |
| 429 } | 446 } |
| 430 | 447 |
| 431 KeySystemConfigSelector::ConfigurationSupport | 448 KeySystemConfigSelector::ConfigurationSupport |
| 432 KeySystemConfigSelector::GetSupportedConfiguration( | 449 KeySystemConfigSelector::GetSupportedConfiguration( |
| 433 const std::string& key_system, | 450 const std::string& key_system, |
| 434 const blink::WebMediaKeySystemConfiguration& candidate, | 451 const blink::WebMediaKeySystemConfiguration& candidate, |
| 435 ConfigState* config_state, | 452 ConfigState* config_state, |
| 436 blink::WebMediaKeySystemConfiguration* accumulated_configuration) { | 453 blink::WebMediaKeySystemConfiguration* accumulated_configuration) { |
| 437 // From https://w3c.github.io/encrypted-media/#get-supported-configuration | 454 // From |
| 438 // 1. Let accumulated configuration be empty. (Done by caller.) | 455 // http://w3c.github.io/encrypted-media/#get-supported-configuration-and-conse nt |
| 439 // 2. If the initDataTypes member is present in candidate configuration, run | 456 // 1. Let accumulated configuration be a new MediaKeySystemConfiguration |
| 440 // the following steps: | 457 // dictionary. (Done by caller.) |
| 441 if (candidate.hasInitDataTypes) { | 458 // 2. Set the label member of accumulated configuration to equal the label |
| 442 // 2.1. Let supported types be empty. | 459 // member of candidate configuration. |
| 460 accumulated_configuration->label = candidate.label; | |
| 461 | |
| 462 // 3. If the initDataTypes member of candidate configuration is non-empty, | |
| 463 // run the following steps: | |
| 464 if (!candidate.initDataTypes.isEmpty()) { | |
| 465 // 3.1. Let supported types be an empty sequence of DOMStrings. | |
| 443 std::vector<blink::WebEncryptedMediaInitDataType> supported_types; | 466 std::vector<blink::WebEncryptedMediaInitDataType> supported_types; |
| 444 | 467 |
| 445 // 2.2. For each value in candidate configuration's initDataTypes member: | 468 // 3.2. For each value in candidate configuration's initDataTypes member: |
| 446 for (size_t i = 0; i < candidate.initDataTypes.size(); i++) { | 469 for (size_t i = 0; i < candidate.initDataTypes.size(); i++) { |
| 447 // 2.2.1. Let initDataType be the value. | 470 // 3.2.1. Let initDataType be the value. |
| 448 blink::WebEncryptedMediaInitDataType init_data_type = | 471 blink::WebEncryptedMediaInitDataType init_data_type = |
| 449 candidate.initDataTypes[i]; | 472 candidate.initDataTypes[i]; |
| 450 // 2.2.2. If the implementation supports generating requests based on | 473 |
| 474 // 3.2.2. If the implementation supports generating requests based on | |
| 451 // initDataType, add initDataType to supported types. String | 475 // initDataType, add initDataType to supported types. String |
| 452 // comparison is case-sensitive. The empty string is never | 476 // comparison is case-sensitive. The empty string is never |
| 453 // supported. | 477 // supported. |
| 454 if (key_systems_->IsSupportedInitDataType( | 478 if (key_systems_->IsSupportedInitDataType( |
| 455 key_system, ConvertToEmeInitDataType(init_data_type))) { | 479 key_system, ConvertToEmeInitDataType(init_data_type))) { |
| 456 supported_types.push_back(init_data_type); | 480 supported_types.push_back(init_data_type); |
| 457 } | 481 } |
| 458 } | 482 } |
| 459 | 483 |
| 460 // 2.3. If supported types is empty, return null. | 484 // 3.3. If supported types is empty, return null. |
| 461 if (supported_types.empty()) { | 485 if (supported_types.empty()) { |
| 462 DVLOG(2) << "Rejecting requested configuration because " | 486 DVLOG(2) << "Rejecting requested configuration because " |
| 463 << "no initDataType values were supported."; | 487 << "no initDataType values were supported."; |
| 464 return CONFIGURATION_NOT_SUPPORTED; | 488 return CONFIGURATION_NOT_SUPPORTED; |
| 465 } | 489 } |
| 466 | 490 |
| 467 // 2.4. Add supported types to accumulated configuration. | 491 // 3.4. Set the initDataTypes member of accumulated configuration to |
| 492 // supported types. | |
| 468 accumulated_configuration->initDataTypes = supported_types; | 493 accumulated_configuration->initDataTypes = supported_types; |
| 469 } | 494 } |
| 470 | 495 |
| 471 // 3. Follow the steps for the value of candidate configuration's | 496 // 4. Let distinctive identifier requirement be the value of candidate |
| 472 // distinctiveIdentifier member from the following list: | 497 // configuration's distinctiveIdentifier member. |
| 473 // - "required": If the implementation does not support a persistent | 498 EmeFeatureRequirement distinctiveIdentifier = candidate.distinctiveIdentifier; |
| 474 // Distinctive Identifier in combination with accumulated | 499 |
| 475 // configuration, return null. | 500 // 5. If distinctive identifier requirement is "optional" and Distinctive |
| 476 // - "optional": Continue. | 501 // Identifiers are not allowed according to restrictions, set distinctive |
| 477 // - "not-allowed": If the implementation requires a Distinctive | 502 // identifier requirement to "not-allowed". |
| 478 // Identifier in combination with accumulated configuration, return | 503 EmeFeatureSupport distinctiveIdentifierSupport = |
|
sandersd (OOO until July 31)
2016/09/16 23:02:10
Nit: variable name does not match Chromium style.
jrummell
2016/09/17 00:15:05
Done.
| |
| 479 // null. | 504 key_systems_->GetDistinctiveIdentifierSupport(key_system); |
| 505 if (distinctiveIdentifier == EmeFeatureRequirement::Optional) { | |
| 506 if (distinctiveIdentifierSupport == EmeFeatureSupport::INVALID || | |
| 507 distinctiveIdentifierSupport == EmeFeatureSupport::NOT_SUPPORTED) { | |
| 508 distinctiveIdentifier = EmeFeatureRequirement::NotAllowed; | |
| 509 } | |
| 510 } | |
| 511 | |
| 512 // 6. Follow the steps for distinctive identifier requirement from the | |
| 513 // following list: | |
| 514 // - "required": If the implementation does not support use of | |
| 515 // Distinctive Identifier(s) in combination with accumulated | |
| 516 // configuration and restrictions, return NotSupported. | |
| 517 // - "optional": Continue with the following steps. | |
| 518 // - "not-allowed": If the implementation requires use Distinctive | |
| 519 // Identifier(s) or Distinctive Permanent Identifier(s) in | |
| 520 // combination with accumulated configuration and restrictions, | |
| 521 // return NotSupported. | |
| 480 // We also reject OPTIONAL when distinctive identifiers are ALWAYS_ENABLED and | 522 // We also reject OPTIONAL when distinctive identifiers are ALWAYS_ENABLED and |
| 481 // permission has already been denied. This would happen anyway at step 11. | 523 // permission has already been denied. This would happen anyway later. |
| 482 EmeConfigRule di_rule = GetDistinctiveIdentifierConfigRule( | 524 EmeConfigRule di_rule = GetDistinctiveIdentifierConfigRule( |
| 483 key_systems_->GetDistinctiveIdentifierSupport(key_system), | 525 distinctiveIdentifierSupport, distinctiveIdentifier); |
| 484 candidate.distinctiveIdentifier); | |
| 485 if (!config_state->IsRuleSupported(di_rule)) { | 526 if (!config_state->IsRuleSupported(di_rule)) { |
| 486 DVLOG(2) << "Rejecting requested configuration because " | 527 DVLOG(2) << "Rejecting requested configuration because " |
| 487 << "the distinctiveIdentifier requirement was not supported."; | 528 << "the distinctiveIdentifier requirement was not supported."; |
| 488 return CONFIGURATION_NOT_SUPPORTED; | 529 return CONFIGURATION_NOT_SUPPORTED; |
| 489 } | 530 } |
| 490 config_state->AddRule(di_rule); | 531 config_state->AddRule(di_rule); |
| 491 | 532 |
| 492 // 4. Add the value of the candidate configuration's distinctiveIdentifier | 533 // 7. Set the distinctiveIdentifier member of accumulated configuration to |
| 493 // member to accumulated configuration. | 534 // equal distinctive identifier requirement. |
| 494 accumulated_configuration->distinctiveIdentifier = | 535 accumulated_configuration->distinctiveIdentifier = distinctiveIdentifier; |
| 495 candidate.distinctiveIdentifier; | |
| 496 | 536 |
| 497 // 5. Follow the steps for the value of candidate configuration's | 537 // 8. Let persistent state requirement be equal to the value of candidate |
| 498 // persistentState member from the following list: | 538 // configuration's persistentState member. |
| 499 // - "required": If the implementation does not support persisting state | 539 EmeFeatureRequirement persistentState = candidate.persistentState; |
|
sandersd (OOO until July 31)
2016/09/16 23:02:10
Nit: variable name does not match Chromium style.
jrummell
2016/09/17 00:15:05
Done.
| |
| 500 // in combination with accumulated configuration, return null. | 540 |
| 501 // - "optional": Continue. | 541 // 9. If persistent state requirement is "optional" and persisting state is |
| 502 // - "not-allowed": If the implementation requires persisting state in | 542 // not allowed according to restrictions, set persistent state requirement |
| 503 // combination with accumulated configuration, return null. | 543 // to "not-allowed". |
| 504 EmeConfigRule ps_rule = GetPersistentStateConfigRule( | 544 EmeFeatureSupport persistentStateSupport = |
|
sandersd (OOO until July 31)
2016/09/16 23:02:10
Nit: variable name does not match Chromium style.
jrummell
2016/09/17 00:15:05
Done.
| |
| 505 key_systems_->GetPersistentStateSupport(key_system), | 545 key_systems_->GetPersistentStateSupport(key_system); |
| 506 candidate.persistentState); | 546 if (persistentState == EmeFeatureRequirement::Optional) { |
| 547 if (persistentStateSupport == EmeFeatureSupport::INVALID || | |
| 548 persistentStateSupport == EmeFeatureSupport::NOT_SUPPORTED) { | |
| 549 persistentState = EmeFeatureRequirement::NotAllowed; | |
| 550 } | |
| 551 } | |
| 552 | |
| 553 // 10. Follow the steps for persistent state requirement from the following | |
| 554 // list: | |
| 555 // - "required": If the implementation does not support persisting | |
| 556 // state in combination with accumulated configuration and | |
| 557 // restrictions, return NotSupported. | |
| 558 // - "optional": Continue with the following steps. | |
| 559 // - "not-allowed": If the implementation requires persisting state in | |
| 560 // combination with accumulated configuration and restrictions, | |
| 561 // return NotSupported. | |
| 562 EmeConfigRule ps_rule = | |
| 563 GetPersistentStateConfigRule(persistentStateSupport, persistentState); | |
| 507 if (!config_state->IsRuleSupported(ps_rule)) { | 564 if (!config_state->IsRuleSupported(ps_rule)) { |
| 508 DVLOG(2) << "Rejecting requested configuration because " | 565 DVLOG(2) << "Rejecting requested configuration because " |
| 509 << "the persistentState requirement was not supported."; | 566 << "the persistentState requirement was not supported."; |
| 510 return CONFIGURATION_NOT_SUPPORTED; | 567 return CONFIGURATION_NOT_SUPPORTED; |
| 511 } | 568 } |
| 512 config_state->AddRule(ps_rule); | 569 config_state->AddRule(ps_rule); |
| 513 | 570 |
| 514 // 6. Add the value of the candidate configuration's persistentState | 571 // 11. Set the persistentState member of accumulated configuration to equal |
| 515 // member to accumulated configuration. | 572 // the value of persistent state requirement. |
| 516 accumulated_configuration->persistentState = candidate.persistentState; | 573 accumulated_configuration->persistentState = persistentState; |
| 517 | 574 |
| 518 // 7. Follow the steps for the first matching condition from the following | 575 // 12. Follow the steps for the first matching condition from the following |
| 519 // list: | 576 // list: |
| 520 // - If the sessionTypes member is present in candidate configuration, | 577 // - If the sessionTypes member is present in candidate configuration, |
| 521 // let session types be candidate configuration's sessionTypes member. | 578 // let session types be candidate configuration's sessionTypes member. |
| 522 // - Otherwise, let session types be [ "temporary" ]. | 579 // - Otherwise, let session types be [ "temporary" ]. |
| 523 blink::WebVector<blink::WebEncryptedMediaSessionType> session_types; | 580 blink::WebVector<blink::WebEncryptedMediaSessionType> session_types; |
| 524 if (candidate.hasSessionTypes) { | 581 if (candidate.hasSessionTypes) { |
| 525 session_types = candidate.sessionTypes; | 582 session_types = candidate.sessionTypes; |
| 526 } else { | 583 } else { |
| 527 std::vector<blink::WebEncryptedMediaSessionType> temporary(1); | 584 std::vector<blink::WebEncryptedMediaSessionType> temporary(1); |
| 528 temporary[0] = blink::WebEncryptedMediaSessionType::Temporary; | 585 temporary[0] = blink::WebEncryptedMediaSessionType::Temporary; |
| 529 session_types = temporary; | 586 session_types = temporary; |
| 530 } | 587 } |
| 531 | 588 |
| 532 // 8. For each value in session types: | 589 // 13. For each value in session types: |
| 533 for (size_t i = 0; i < session_types.size(); i++) { | 590 for (size_t i = 0; i < session_types.size(); i++) { |
| 534 // 8.1. Let session type be the value. | 591 // 13.1. Let session type be the value. |
| 535 blink::WebEncryptedMediaSessionType session_type = session_types[i]; | 592 blink::WebEncryptedMediaSessionType session_type = session_types[i]; |
| 536 // 8.2. If the implementation does not support session type in combination | 593 |
| 537 // with accumulated configuration, return null. | 594 // 13.2. If accumulated configuration's persistentState value is |
| 538 // 8.3. If session type is "persistent-license" or | 595 // "not-allowed" and the Is persistent session type? algorithm |
| 539 // "persistent-release-message", follow the steps for accumulated | 596 // returns true for session type return NotSupported. |
| 540 // configuration's persistentState value from the following list: | 597 if (accumulated_configuration->persistentState == |
| 541 // - "required": Continue. | 598 EmeFeatureRequirement::NotAllowed && |
| 542 // - "optional": Change accumulated configuration's persistentState | 599 IsPersistentSessionType(session_type)) { |
| 543 // value to "required". | 600 DVLOG(2) << "Rejecting requested configuration because persistent " |
| 544 // - "not-allowed": Return null. | 601 "sessions are not allowed."; |
| 602 return CONFIGURATION_NOT_SUPPORTED; | |
| 603 } | |
| 604 | |
| 605 // 13.3. If the implementation does not support session type in combination | |
| 606 // with accumulated configuration and restrictions for other reasons, | |
| 607 // return NotSupported. | |
| 545 EmeConfigRule session_type_rule = EmeConfigRule::NOT_SUPPORTED; | 608 EmeConfigRule session_type_rule = EmeConfigRule::NOT_SUPPORTED; |
| 546 switch (session_type) { | 609 switch (session_type) { |
| 547 case blink::WebEncryptedMediaSessionType::Unknown: | 610 case blink::WebEncryptedMediaSessionType::Unknown: |
| 548 DVLOG(2) << "Rejecting requested configuration because " | 611 DVLOG(2) << "Rejecting requested configuration because " |
| 549 << "a required session type was not recognized."; | 612 << "a required session type was not recognized."; |
| 550 return CONFIGURATION_NOT_SUPPORTED; | 613 return CONFIGURATION_NOT_SUPPORTED; |
| 551 case blink::WebEncryptedMediaSessionType::Temporary: | 614 case blink::WebEncryptedMediaSessionType::Temporary: |
| 552 session_type_rule = EmeConfigRule::SUPPORTED; | 615 session_type_rule = EmeConfigRule::SUPPORTED; |
| 553 break; | 616 break; |
| 554 case blink::WebEncryptedMediaSessionType::PersistentLicense: | 617 case blink::WebEncryptedMediaSessionType::PersistentLicense: |
| 555 session_type_rule = GetSessionTypeConfigRule( | 618 session_type_rule = GetSessionTypeConfigRule( |
| 556 key_systems_->GetPersistentLicenseSessionSupport(key_system)); | 619 key_systems_->GetPersistentLicenseSessionSupport(key_system)); |
| 557 break; | 620 break; |
| 558 case blink::WebEncryptedMediaSessionType::PersistentReleaseMessage: | 621 case blink::WebEncryptedMediaSessionType::PersistentReleaseMessage: |
| 559 session_type_rule = GetSessionTypeConfigRule( | 622 session_type_rule = GetSessionTypeConfigRule( |
| 560 key_systems_->GetPersistentReleaseMessageSessionSupport( | 623 key_systems_->GetPersistentReleaseMessageSessionSupport( |
| 561 key_system)); | 624 key_system)); |
| 562 break; | 625 break; |
| 563 } | 626 } |
| 627 | |
| 564 if (!config_state->IsRuleSupported(session_type_rule)) { | 628 if (!config_state->IsRuleSupported(session_type_rule)) { |
| 565 DVLOG(2) << "Rejecting requested configuration because " | 629 DVLOG(2) << "Rejecting requested configuration because " |
| 566 << "a required session type was not supported."; | 630 << "a required session type was not supported."; |
| 567 return CONFIGURATION_NOT_SUPPORTED; | 631 return CONFIGURATION_NOT_SUPPORTED; |
| 568 } | 632 } |
| 569 config_state->AddRule(session_type_rule); | 633 config_state->AddRule(session_type_rule); |
| 634 | |
| 635 // 13.4. If accumulated configuration's persistentState value is "optional" | |
| 636 // and the result of running the Is persistent session type? | |
| 637 // algorithm on session type is true, change accumulated | |
| 638 // configuration's persistentState value to "required". | |
| 639 if (accumulated_configuration->persistentState == | |
| 640 EmeFeatureRequirement::Optional && | |
| 641 IsPersistentSessionType(session_type)) { | |
| 642 accumulated_configuration->persistentState = | |
| 643 EmeFeatureRequirement::Required; | |
| 644 } | |
| 570 } | 645 } |
| 571 | 646 |
| 572 // 9. Add session types to accumulated configuration. | 647 // 14. Set the sessionTypes member of accumulated configuration to |
| 648 // session types. | |
| 573 accumulated_configuration->sessionTypes = session_types; | 649 accumulated_configuration->sessionTypes = session_types; |
| 574 | 650 |
| 575 // 10. If the videoCapabilities member is present in candidate configuration: | 651 // 15. If the videoCapabilities and audioCapabilities members in candidate |
| 576 if (candidate.hasVideoCapabilities) { | 652 // configuration are both empty, return NotSupported. |
| 577 // 10.1. Let video capabilities be the result of executing the Get Supported | 653 // TODO(jrummell): Enforce this once the deprecation warning is removed. |
| 578 // Capabilities for Media Type algorithm on Video, candidate | 654 // See http://crbug.com/616233. |
| 579 // configuration's videoCapabilities member, and accumulated | 655 |
| 580 // configuration. | 656 // 16. If the videoCapabilities member in candidate configuration is |
| 581 // 10.2. If video capabilities is null, return null. | 657 // non-empty: |
| 582 std::vector<blink::WebMediaKeySystemMediaCapability> video_capabilities; | 658 std::vector<blink::WebMediaKeySystemMediaCapability> video_capabilities; |
| 659 if (!candidate.videoCapabilities.isEmpty()) { | |
| 660 // 16.1. Let video capabilities be the result of executing the Get | |
| 661 // Supported Capabilities for Audio/Video Type algorithm on Video, | |
| 662 // candidate configuration's videoCapabilities member, accumulated | |
| 663 // configuration, and restrictions. | |
| 664 // 16.2. If video capabilities is null, return NotSupported. | |
| 583 if (!GetSupportedCapabilities(key_system, EmeMediaType::VIDEO, | 665 if (!GetSupportedCapabilities(key_system, EmeMediaType::VIDEO, |
| 584 candidate.videoCapabilities, config_state, | 666 candidate.videoCapabilities, config_state, |
| 585 &video_capabilities)) { | 667 &video_capabilities)) { |
| 586 return CONFIGURATION_NOT_SUPPORTED; | 668 return CONFIGURATION_NOT_SUPPORTED; |
| 587 } | 669 } |
| 588 | 670 |
| 589 // 10.3. Add video capabilities to accumulated configuration. | 671 // 16.3. Set the videoCapabilities member of accumulated configuration |
| 590 accumulated_configuration->hasVideoCapabilities = true; | 672 // to video capabilities. |
| 673 accumulated_configuration->videoCapabilities = video_capabilities; | |
| 674 } else { | |
| 675 // Otherwise set the videoCapabilities member of accumulated configuration | |
| 676 // to an empty sequence. | |
| 591 accumulated_configuration->videoCapabilities = video_capabilities; | 677 accumulated_configuration->videoCapabilities = video_capabilities; |
| 592 } | 678 } |
| 593 | 679 |
| 594 // 11. If the audioCapabilities member is present in candidate configuration: | 680 // 17. If the audioCapabilities member in candidate configuration is |
| 595 if (candidate.hasAudioCapabilities) { | 681 // non-empty: |
| 596 // 11.1. Let audio capabilities be the result of executing the Get Supported | 682 std::vector<blink::WebMediaKeySystemMediaCapability> audio_capabilities; |
| 597 // Capabilities for Media Type algorithm on Audio, candidate | 683 if (!candidate.audioCapabilities.isEmpty()) { |
| 598 // configuration's audioCapabilities member, and accumulated | 684 // 17.1. Let audio capabilities be the result of executing the Get |
| 599 // configuration. | 685 // Supported Capabilities for Audio/Video Type algorithm on Audio, |
| 600 // 11.2. If audio capabilities is null, return null. | 686 // candidate configuration's audioCapabilities member, accumulated |
| 601 std::vector<blink::WebMediaKeySystemMediaCapability> audio_capabilities; | 687 // configuration, and restrictions. |
| 688 // 17.2. If audio capabilities is null, return NotSupported. | |
| 602 if (!GetSupportedCapabilities(key_system, EmeMediaType::AUDIO, | 689 if (!GetSupportedCapabilities(key_system, EmeMediaType::AUDIO, |
| 603 candidate.audioCapabilities, config_state, | 690 candidate.audioCapabilities, config_state, |
| 604 &audio_capabilities)) { | 691 &audio_capabilities)) { |
| 605 return CONFIGURATION_NOT_SUPPORTED; | 692 return CONFIGURATION_NOT_SUPPORTED; |
| 606 } | 693 } |
| 607 | 694 |
| 608 // 11.3. Add audio capabilities to accumulated configuration. | 695 // 17.3. Set the audioCapabilities member of accumulated configuration |
| 609 accumulated_configuration->hasAudioCapabilities = true; | 696 // to audio capabilities. |
| 697 accumulated_configuration->audioCapabilities = audio_capabilities; | |
| 698 } else { | |
| 699 // Otherwise set the audioCapabilities member of accumulated configuration | |
| 700 // to an empty sequence. | |
| 610 accumulated_configuration->audioCapabilities = audio_capabilities; | 701 accumulated_configuration->audioCapabilities = audio_capabilities; |
| 611 } | 702 } |
| 612 | 703 |
| 613 // 12. If accumulated configuration's distinctiveIdentifier value is | 704 // 18. If accumulated configuration's distinctiveIdentifier value is |
| 614 // "optional", follow the steps for the first matching condition from the | 705 // "optional", follow the steps for the first matching condition |
| 615 // following list: | 706 // from the following list: |
| 616 // - If the implementation requires a Distinctive Identifier for any of | 707 // - If the implementation requires use Distinctive Identifier(s) or |
| 617 // the combinations in accumulated configuration, change accumulated | 708 // Distinctive Permanent Identifier(s) for any of the combinations |
| 618 // configuration's distinctiveIdentifier value to "required". | 709 // in accumulated configuration, change accumulated configuration's |
| 619 // - Otherwise, change accumulated configuration's distinctiveIdentifier | 710 // distinctiveIdentifier value to "required". |
| 620 // value to "not-allowed". | 711 // - Otherwise, change accumulated configuration's |
| 712 // distinctiveIdentifier value to "not-allowed". | |
| 621 if (accumulated_configuration->distinctiveIdentifier == | 713 if (accumulated_configuration->distinctiveIdentifier == |
| 622 blink::WebMediaKeySystemConfiguration::Requirement::Optional) { | 714 EmeFeatureRequirement::Optional) { |
| 623 EmeConfigRule not_allowed_rule = GetDistinctiveIdentifierConfigRule( | 715 EmeConfigRule not_allowed_rule = GetDistinctiveIdentifierConfigRule( |
| 624 key_systems_->GetDistinctiveIdentifierSupport(key_system), | 716 key_systems_->GetDistinctiveIdentifierSupport(key_system), |
| 625 EmeFeatureRequirement::NotAllowed); | 717 EmeFeatureRequirement::NotAllowed); |
| 626 EmeConfigRule required_rule = GetDistinctiveIdentifierConfigRule( | 718 EmeConfigRule required_rule = GetDistinctiveIdentifierConfigRule( |
| 627 key_systems_->GetDistinctiveIdentifierSupport(key_system), | 719 key_systems_->GetDistinctiveIdentifierSupport(key_system), |
| 628 EmeFeatureRequirement::Required); | 720 EmeFeatureRequirement::Required); |
| 629 bool not_allowed_supported = | 721 bool not_allowed_supported = |
| 630 config_state->IsRuleSupported(not_allowed_rule); | 722 config_state->IsRuleSupported(not_allowed_rule); |
| 631 bool required_supported = config_state->IsRuleSupported(required_rule); | 723 bool required_supported = config_state->IsRuleSupported(required_rule); |
| 632 // If a distinctive identifier is recommend and that is a possible outcome, | 724 // If a distinctive identifier is recommend and that is a possible outcome, |
| 633 // prefer that. | 725 // prefer that. |
| 634 if (required_supported && config_state->IsIdentifierRecommended() && | 726 if (required_supported && config_state->IsIdentifierRecommended() && |
| 635 config_state->IsPermissionPossible()) { | 727 config_state->IsPermissionPossible()) { |
| 636 not_allowed_supported = false; | 728 not_allowed_supported = false; |
| 637 } | 729 } |
| 638 if (not_allowed_supported) { | 730 if (not_allowed_supported) { |
| 639 accumulated_configuration->distinctiveIdentifier = | 731 accumulated_configuration->distinctiveIdentifier = |
| 640 blink::WebMediaKeySystemConfiguration::Requirement::NotAllowed; | 732 EmeFeatureRequirement::NotAllowed; |
| 641 config_state->AddRule(not_allowed_rule); | 733 config_state->AddRule(not_allowed_rule); |
| 642 } else if (required_supported) { | 734 } else if (required_supported) { |
| 643 accumulated_configuration->distinctiveIdentifier = | 735 accumulated_configuration->distinctiveIdentifier = |
| 644 blink::WebMediaKeySystemConfiguration::Requirement::Required; | 736 EmeFeatureRequirement::Required; |
| 645 config_state->AddRule(required_rule); | 737 config_state->AddRule(required_rule); |
| 646 } else { | 738 } else { |
| 647 // We should not have passed step 3. | 739 // We should not have passed step 6. |
| 648 NOTREACHED(); | 740 NOTREACHED(); |
| 649 return CONFIGURATION_NOT_SUPPORTED; | 741 return CONFIGURATION_NOT_SUPPORTED; |
| 650 } | 742 } |
| 651 } | 743 } |
| 652 | 744 |
| 653 // 13. If accumulated configuration's persistentState value is "optional", | 745 // 19. If accumulated configuration's persistentState value is "optional", |
| 654 // follow the steps for the first matching condition from the following | 746 // follow the steps for the first matching condition from the following |
| 655 // list: | 747 // list: |
| 656 // - If the implementation requires persisting state for any of the | 748 // - If the implementation requires persisting state for any of the |
| 657 // combinations in accumulated configuration, change accumulated | 749 // combinations in accumulated configuration, change accumulated |
| 658 // configuration's persistentState value to "required". | 750 // configuration's persistentState value to "required". |
| 659 // - Otherwise, change accumulated configuration's persistentState value | 751 // - Otherwise, change accumulated configuration's persistentState |
| 660 // to "not-allowed". | 752 // value to "not-allowed". |
| 661 if (accumulated_configuration->persistentState == | 753 if (accumulated_configuration->persistentState == |
| 662 blink::WebMediaKeySystemConfiguration::Requirement::Optional) { | 754 EmeFeatureRequirement::Optional) { |
| 663 EmeConfigRule not_allowed_rule = GetPersistentStateConfigRule( | 755 EmeConfigRule not_allowed_rule = GetPersistentStateConfigRule( |
| 664 key_systems_->GetPersistentStateSupport(key_system), | 756 key_systems_->GetPersistentStateSupport(key_system), |
| 665 EmeFeatureRequirement::NotAllowed); | 757 EmeFeatureRequirement::NotAllowed); |
| 666 EmeConfigRule required_rule = GetPersistentStateConfigRule( | 758 EmeConfigRule required_rule = GetPersistentStateConfigRule( |
| 667 key_systems_->GetPersistentStateSupport(key_system), | 759 key_systems_->GetPersistentStateSupport(key_system), |
| 668 EmeFeatureRequirement::Required); | 760 EmeFeatureRequirement::Required); |
| 669 // |distinctiveIdentifier| should not be affected after it is decided. | 761 // |distinctiveIdentifier| should not be affected after it is decided. |
| 670 DCHECK(not_allowed_rule == EmeConfigRule::NOT_SUPPORTED || | 762 DCHECK(not_allowed_rule == EmeConfigRule::NOT_SUPPORTED || |
| 671 not_allowed_rule == EmeConfigRule::PERSISTENCE_NOT_ALLOWED); | 763 not_allowed_rule == EmeConfigRule::PERSISTENCE_NOT_ALLOWED); |
| 672 DCHECK(required_rule == EmeConfigRule::NOT_SUPPORTED || | 764 DCHECK(required_rule == EmeConfigRule::NOT_SUPPORTED || |
| 673 required_rule == EmeConfigRule::PERSISTENCE_REQUIRED); | 765 required_rule == EmeConfigRule::PERSISTENCE_REQUIRED); |
| 674 bool not_allowed_supported = | 766 bool not_allowed_supported = |
| 675 config_state->IsRuleSupported(not_allowed_rule); | 767 config_state->IsRuleSupported(not_allowed_rule); |
| 676 bool required_supported = config_state->IsRuleSupported(required_rule); | 768 bool required_supported = config_state->IsRuleSupported(required_rule); |
| 677 if (not_allowed_supported) { | 769 if (not_allowed_supported) { |
| 678 accumulated_configuration->persistentState = | 770 accumulated_configuration->persistentState = |
| 679 blink::WebMediaKeySystemConfiguration::Requirement::NotAllowed; | 771 EmeFeatureRequirement::NotAllowed; |
| 680 config_state->AddRule(not_allowed_rule); | 772 config_state->AddRule(not_allowed_rule); |
| 681 } else if (required_supported) { | 773 } else if (required_supported) { |
| 682 accumulated_configuration->persistentState = | 774 accumulated_configuration->persistentState = |
| 683 blink::WebMediaKeySystemConfiguration::Requirement::Required; | 775 EmeFeatureRequirement::Required; |
| 684 config_state->AddRule(required_rule); | 776 config_state->AddRule(required_rule); |
| 685 } else { | 777 } else { |
| 686 // We should not have passed step 5. | 778 // We should not have passed step 5. |
| 687 NOTREACHED(); | 779 NOTREACHED(); |
| 688 return CONFIGURATION_NOT_SUPPORTED; | 780 return CONFIGURATION_NOT_SUPPORTED; |
| 689 } | 781 } |
| 690 } | 782 } |
| 691 | 783 |
| 692 // 14. If implementation in the configuration specified by the combination of | 784 // 20. If implementation in the configuration specified by the combination of |
| 693 // the values in accumulated configuration is not supported or not allowed | 785 // the values in accumulated configuration is not supported or not allowed |
| 694 // in the origin, return null. | 786 // in the origin, return NotSupported. |
| 695 // 15. If accumulated configuration's distinctiveIdentifier value is | 787 // TODO(jrummell): can we check that the CDM can't be loaded by the origin? |
| 696 // "required", [prompt the user for consent]. | 788 |
| 789 // 21. If accumulated configuration's distinctiveIdentifier value is | |
| 790 // "required" and the Distinctive Identifier(s) associated with | |
| 791 // accumulated configuration are not unique per origin and profile | |
| 792 // and clearable: | |
| 793 // 21.1. Update restrictions to reflect that all configurations described | |
| 794 // by accumulated configuration do not have user consent. | |
| 795 // 21.2. Return ConsentDenied and restrictions. | |
| 796 // (Not required as data is unique per origin and clearable.) | |
| 797 | |
| 798 // 22. Let consent status and updated restrictions be the result of running | |
| 799 // the Get Consent Status algorithm on accumulated configuration, | |
| 800 // restrictions and origin and follow the steps for the value of consent | |
| 801 // status from the following list: | |
| 802 // - "ConsentDenied": Return ConsentDenied and updated restrictions. | |
| 803 // - "InformUser": Inform the user that accumulated configuration is | |
| 804 // in use in the origin including, specifically, the information | |
| 805 // that Distinctive Identifier(s) and/or Distinctive Permanent | |
| 806 // Identifier(s) as appropriate will be used if the | |
| 807 // distinctiveIdentifier member of accumulated configuration is | |
| 808 // "required". Continue to the next step. | |
| 809 // - "Allowed": Continue to the next step. | |
| 810 // Accumulated configuration's distinctiveIdentifier should be "required" or | |
| 811 // "notallowed"" due to step 18. If it is "required", prompt the user for | |
| 812 // consent unless it has already been granted. | |
| 697 if (accumulated_configuration->distinctiveIdentifier == | 813 if (accumulated_configuration->distinctiveIdentifier == |
| 698 blink::WebMediaKeySystemConfiguration::Requirement::Required) { | 814 EmeFeatureRequirement::Required) { |
| 699 // The caller is responsible for resolving what to do if permission is | 815 // The caller is responsible for resolving what to do if permission is |
| 700 // required but has been denied (it should treat it as NOT_SUPPORTED). | 816 // required but has been denied (it should treat it as NOT_SUPPORTED). |
| 701 if (!config_state->IsPermissionGranted()) | 817 if (!config_state->IsPermissionGranted()) |
| 702 return CONFIGURATION_REQUIRES_PERMISSION; | 818 return CONFIGURATION_REQUIRES_PERMISSION; |
| 703 } | 819 } |
| 704 | 820 |
| 705 // 16. If the label member is present in candidate configuration, add the | 821 // 23. Return accumulated configuration. |
| 706 // value of the candidate configuration's label member to accumulated | |
| 707 // configuration. | |
| 708 accumulated_configuration->label = candidate.label; | |
| 709 | |
| 710 // 17. Return accumulated configuration. | |
| 711 return CONFIGURATION_SUPPORTED; | 822 return CONFIGURATION_SUPPORTED; |
| 712 } | 823 } |
| 713 | 824 |
| 714 void KeySystemConfigSelector::SelectConfig( | 825 void KeySystemConfigSelector::SelectConfig( |
| 715 const blink::WebString& key_system, | 826 const blink::WebString& key_system, |
| 716 const blink::WebVector<blink::WebMediaKeySystemConfiguration>& | 827 const blink::WebVector<blink::WebMediaKeySystemConfiguration>& |
| 717 candidate_configurations, | 828 candidate_configurations, |
| 718 const blink::WebSecurityOrigin& security_origin, | 829 const blink::WebSecurityOrigin& security_origin, |
| 719 bool are_secure_codecs_supported, | 830 bool are_secure_codecs_supported, |
| 720 base::Callback<void(const blink::WebMediaKeySystemConfiguration&, | 831 base::Callback<void(const blink::WebMediaKeySystemConfiguration&, |
| 721 const CdmConfig&)> succeeded_cb, | 832 const CdmConfig&)> succeeded_cb, |
| 722 base::Callback<void(const blink::WebString&)> not_supported_cb) { | 833 base::Callback<void(const blink::WebString&)> not_supported_cb) { |
| 723 // Continued from requestMediaKeySystemAccess(), step 7, from | 834 // Continued from requestMediaKeySystemAccess(), step 6, from |
| 724 // https://w3c.github.io/encrypted-media/#requestmediakeysystemaccess | 835 // https://w3c.github.io/encrypted-media/#requestmediakeysystemaccess |
| 725 // | 836 // |
| 726 // 7.1. If keySystem is not one of the Key Systems supported by the user | 837 // 6.1 If keySystem is not one of the Key Systems supported by the user |
| 727 // agent, reject promise with with a new DOMException whose name is | 838 // agent, reject promise with a NotSupportedError. String comparison |
| 728 // NotSupportedError. String comparison is case-sensitive. | 839 // is case-sensitive. |
| 729 if (!base::IsStringASCII(key_system)) { | 840 if (!base::IsStringASCII(key_system)) { |
| 730 not_supported_cb.Run("Only ASCII keySystems are supported"); | 841 not_supported_cb.Run("Only ASCII keySystems are supported"); |
| 731 return; | 842 return; |
| 732 } | 843 } |
| 733 | 844 |
| 734 std::string key_system_ascii = | 845 std::string key_system_ascii = |
| 735 base::UTF16ToASCII(base::StringPiece16(key_system)); | 846 base::UTF16ToASCII(base::StringPiece16(key_system)); |
| 736 if (!key_systems_->IsSupportedKeySystem(key_system_ascii)) { | 847 if (!key_systems_->IsSupportedKeySystem(key_system_ascii)) { |
| 737 not_supported_cb.Run("Unsupported keySystem"); | 848 not_supported_cb.Run("Unsupported keySystem"); |
| 738 return; | 849 return; |
| 739 } | 850 } |
| 740 | 851 |
| 741 // 7.2-7.4. Implemented by OnSelectConfig(). | 852 // 6.2-6.4. Implemented by OnSelectConfig(). |
| 742 // TODO(sandersd): This should be async, ideally not on the main thread. | 853 // TODO(sandersd): This should be async, ideally not on the main thread. |
| 743 std::unique_ptr<SelectionRequest> request(new SelectionRequest()); | 854 std::unique_ptr<SelectionRequest> request(new SelectionRequest()); |
| 744 request->key_system = key_system_ascii; | 855 request->key_system = key_system_ascii; |
| 745 request->candidate_configurations = candidate_configurations; | 856 request->candidate_configurations = candidate_configurations; |
| 746 request->security_origin = security_origin; | 857 request->security_origin = security_origin; |
| 747 request->are_secure_codecs_supported = are_secure_codecs_supported; | 858 request->are_secure_codecs_supported = are_secure_codecs_supported; |
| 748 request->succeeded_cb = succeeded_cb; | 859 request->succeeded_cb = succeeded_cb; |
| 749 request->not_supported_cb = not_supported_cb; | 860 request->not_supported_cb = not_supported_cb; |
| 750 SelectConfigInternal(std::move(request)); | 861 SelectConfigInternal(std::move(request)); |
| 751 } | 862 } |
| 752 | 863 |
| 753 void KeySystemConfigSelector::SelectConfigInternal( | 864 void KeySystemConfigSelector::SelectConfigInternal( |
| 754 std::unique_ptr<SelectionRequest> request) { | 865 std::unique_ptr<SelectionRequest> request) { |
| 755 // Continued from requestMediaKeySystemAccess(), step 7.1, from | 866 // Continued from requestMediaKeySystemAccess(), step 6, from |
| 756 // https://w3c.github.io/encrypted-media/#requestmediakeysystemaccess | 867 // https://w3c.github.io/encrypted-media/#requestmediakeysystemaccess |
| 757 // | 868 // |
| 758 // 7.2. Let implementation be the implementation of keySystem. | 869 // 6.2. Let implementation be the implementation of keySystem. |
| 759 // (|key_systems_| fills this role.) | 870 // (|key_systems_| fills this role.) |
| 760 // 7.3. For each value in supportedConfigurations: | 871 // 6.3. For each value in supportedConfigurations: |
| 761 for (size_t i = 0; i < request->candidate_configurations.size(); i++) { | 872 for (size_t i = 0; i < request->candidate_configurations.size(); i++) { |
| 762 // 7.3.1. Let candidate configuration be the value. | 873 // 6.3.1. Let candidate configuration be the value. |
| 763 // 7.3.2. Let supported configuration be the result of executing the Get | 874 // 6.3.2. Let supported configuration be the result of executing the Get |
| 764 // Supported Configuration algorithm on implementation, candidate | 875 // Supported Configuration algorithm on implementation, candidate |
| 765 // configuration, and origin. | 876 // configuration, and origin. |
| 766 // 7.3.3. If supported configuration is not null, [initialize and return a | 877 // 6.3.3. If supported configuration is not NotSupported, [initialize |
| 767 // new MediaKeySystemAccess object.] | 878 // and return a new MediaKeySystemAccess object.] |
| 768 ConfigState config_state(request->was_permission_requested, | 879 ConfigState config_state(request->was_permission_requested, |
| 769 request->is_permission_granted); | 880 request->is_permission_granted); |
| 770 DCHECK(config_state.IsRuleSupported( | 881 DCHECK(config_state.IsRuleSupported( |
| 771 EmeConfigRule::HW_SECURE_CODECS_NOT_ALLOWED)); | 882 EmeConfigRule::HW_SECURE_CODECS_NOT_ALLOWED)); |
| 772 if (!request->are_secure_codecs_supported) | 883 if (!request->are_secure_codecs_supported) |
| 773 config_state.AddRule(EmeConfigRule::HW_SECURE_CODECS_NOT_ALLOWED); | 884 config_state.AddRule(EmeConfigRule::HW_SECURE_CODECS_NOT_ALLOWED); |
| 774 blink::WebMediaKeySystemConfiguration accumulated_configuration; | 885 blink::WebMediaKeySystemConfiguration accumulated_configuration; |
| 775 CdmConfig cdm_config; | 886 CdmConfig cdm_config; |
| 776 ConfigurationSupport support = GetSupportedConfiguration( | 887 ConfigurationSupport support = GetSupportedConfiguration( |
| 777 request->key_system, request->candidate_configurations[i], | 888 request->key_system, request->candidate_configurations[i], |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 792 blink::WebStringToGURL(request->security_origin.toString())); | 903 blink::WebStringToGURL(request->security_origin.toString())); |
| 793 media_permission_->RequestPermission( | 904 media_permission_->RequestPermission( |
| 794 MediaPermission::PROTECTED_MEDIA_IDENTIFIER, security_origin, | 905 MediaPermission::PROTECTED_MEDIA_IDENTIFIER, security_origin, |
| 795 base::Bind(&KeySystemConfigSelector::OnPermissionResult, | 906 base::Bind(&KeySystemConfigSelector::OnPermissionResult, |
| 796 weak_factory_.GetWeakPtr(), base::Passed(&request))); | 907 weak_factory_.GetWeakPtr(), base::Passed(&request))); |
| 797 } | 908 } |
| 798 return; | 909 return; |
| 799 case CONFIGURATION_SUPPORTED: | 910 case CONFIGURATION_SUPPORTED: |
| 800 cdm_config.allow_distinctive_identifier = | 911 cdm_config.allow_distinctive_identifier = |
| 801 (accumulated_configuration.distinctiveIdentifier == | 912 (accumulated_configuration.distinctiveIdentifier == |
| 802 blink::WebMediaKeySystemConfiguration::Requirement::Required); | 913 EmeFeatureRequirement::Required); |
| 803 cdm_config.allow_persistent_state = | 914 cdm_config.allow_persistent_state = |
| 804 (accumulated_configuration.persistentState == | 915 (accumulated_configuration.persistentState == |
| 805 blink::WebMediaKeySystemConfiguration::Requirement::Required); | 916 EmeFeatureRequirement::Required); |
| 806 cdm_config.use_hw_secure_codecs = | 917 cdm_config.use_hw_secure_codecs = |
| 807 config_state.AreHwSecureCodecsRequired(); | 918 config_state.AreHwSecureCodecsRequired(); |
| 808 request->succeeded_cb.Run(accumulated_configuration, cdm_config); | 919 request->succeeded_cb.Run(accumulated_configuration, cdm_config); |
| 809 return; | 920 return; |
| 810 } | 921 } |
| 811 } | 922 } |
| 812 | 923 |
| 813 // 7.4. Reject promise with a new DOMException whose name is | 924 // 6.4. Reject promise with a NotSupportedError. |
| 814 // NotSupportedError. | |
| 815 request->not_supported_cb.Run( | 925 request->not_supported_cb.Run( |
| 816 "None of the requested configurations were supported."); | 926 "None of the requested configurations were supported."); |
| 817 } | 927 } |
| 818 | 928 |
| 819 void KeySystemConfigSelector::OnPermissionResult( | 929 void KeySystemConfigSelector::OnPermissionResult( |
| 820 std::unique_ptr<SelectionRequest> request, | 930 std::unique_ptr<SelectionRequest> request, |
| 821 bool is_permission_granted) { | 931 bool is_permission_granted) { |
| 822 request->was_permission_requested = true; | 932 request->was_permission_requested = true; |
| 823 request->is_permission_granted = is_permission_granted; | 933 request->is_permission_granted = is_permission_granted; |
| 824 SelectConfigInternal(std::move(request)); | 934 SelectConfigInternal(std::move(request)); |
| 825 } | 935 } |
| 826 | 936 |
| 827 } // namespace media | 937 } // namespace media |
| OLD | NEW |