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