| 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" |
| 11 #include "media/base/cdm_config.h" |
| 11 #include "media/base/key_systems.h" | 12 #include "media/base/key_systems.h" |
| 12 #include "media/base/media_permission.h" | 13 #include "media/base/media_permission.h" |
| 13 #include "media/blink/webmediaplayer_util.h" | 14 #include "media/blink/webmediaplayer_util.h" |
| 14 #include "net/base/mime_util.h" | 15 #include "net/base/mime_util.h" |
| 15 #include "third_party/WebKit/public/platform/WebMediaKeySystemConfiguration.h" | 16 #include "third_party/WebKit/public/platform/WebMediaKeySystemConfiguration.h" |
| 16 #include "third_party/WebKit/public/platform/WebSecurityOrigin.h" | 17 #include "third_party/WebKit/public/platform/WebSecurityOrigin.h" |
| 17 #include "third_party/WebKit/public/platform/WebString.h" | 18 #include "third_party/WebKit/public/platform/WebString.h" |
| 18 #include "third_party/WebKit/public/platform/WebVector.h" | 19 #include "third_party/WebKit/public/platform/WebVector.h" |
| 19 #include "url/gurl.h" | 20 #include "url/gurl.h" |
| 20 | 21 |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 124 return EmeConfigRule::PERSISTENCE_REQUIRED; | 125 return EmeConfigRule::PERSISTENCE_REQUIRED; |
| 125 } | 126 } |
| 126 | 127 |
| 127 } // namespace | 128 } // namespace |
| 128 | 129 |
| 129 struct KeySystemConfigSelector::SelectionRequest { | 130 struct KeySystemConfigSelector::SelectionRequest { |
| 130 std::string key_system; | 131 std::string key_system; |
| 131 blink::WebVector<blink::WebMediaKeySystemConfiguration> | 132 blink::WebVector<blink::WebMediaKeySystemConfiguration> |
| 132 candidate_configurations; | 133 candidate_configurations; |
| 133 blink::WebSecurityOrigin security_origin; | 134 blink::WebSecurityOrigin security_origin; |
| 134 base::Callback<void(const blink::WebMediaKeySystemConfiguration&, bool)> | 135 base::Callback<void(const blink::WebMediaKeySystemConfiguration&, |
| 135 succeeded_cb; | 136 const CdmConfig&)> succeeded_cb; |
| 136 base::Callback<void(const blink::WebString&)> not_supported_cb; | 137 base::Callback<void(const blink::WebString&)> not_supported_cb; |
| 137 bool was_permission_requested = false; | 138 bool was_permission_requested = false; |
| 138 bool is_permission_granted = false; | 139 bool is_permission_granted = false; |
| 139 bool are_secure_codecs_supported = false; | 140 bool are_secure_codecs_supported = false; |
| 140 }; | 141 }; |
| 141 | 142 |
| 142 // Accumulates configuration rules to determine if a feature (additional | 143 // Accumulates configuration rules to determine if a feature (additional |
| 143 // configuration rule) can be added to an accumulated configuration. | 144 // configuration rule) can be added to an accumulated configuration. |
| 144 class KeySystemConfigSelector::ConfigState { | 145 class KeySystemConfigSelector::ConfigState { |
| 145 public: | 146 public: |
| 146 ConfigState(bool was_permission_requested, bool is_permission_granted) | 147 ConfigState(bool was_permission_requested, bool is_permission_granted) |
| 147 : was_permission_requested_(was_permission_requested), | 148 : was_permission_requested_(was_permission_requested), |
| 148 is_permission_granted_(is_permission_granted) {} | 149 is_permission_granted_(is_permission_granted) {} |
| 149 | 150 |
| 150 bool IsPermissionGranted() const { return is_permission_granted_; } | 151 bool IsPermissionGranted() const { return is_permission_granted_; } |
| 151 | 152 |
| 152 // Permission is possible if it has not been denied. | 153 // Permission is possible if it has not been denied. |
| 153 bool IsPermissionPossible() const { | 154 bool IsPermissionPossible() const { |
| 154 return is_permission_granted_ || !was_permission_requested_; | 155 return is_permission_granted_ || !was_permission_requested_; |
| 155 } | 156 } |
| 156 | 157 |
| 157 bool IsIdentifierRequired() const { return is_identifier_required_; } | 158 bool IsIdentifierRequired() const { return is_identifier_required_; } |
| 158 | 159 |
| 159 bool IsIdentifierRecommended() const { return is_identifier_recommended_; } | 160 bool IsIdentifierRecommended() const { return is_identifier_recommended_; } |
| 160 | 161 |
| 161 bool AreSecureCodecsRequired() const { | 162 bool AreHwSecureCodecsRequired() const { |
| 162 return are_secure_codecs_required_; | 163 return are_hw_secure_codecs_required_; |
| 163 } | 164 } |
| 164 | 165 |
| 165 // Checks whether a rule is compatible with all previously added rules. | 166 // Checks whether a rule is compatible with all previously added rules. |
| 166 bool IsRuleSupported(EmeConfigRule rule) const { | 167 bool IsRuleSupported(EmeConfigRule rule) const { |
| 167 switch (rule) { | 168 switch (rule) { |
| 168 case EmeConfigRule::NOT_SUPPORTED: | 169 case EmeConfigRule::NOT_SUPPORTED: |
| 169 return false; | 170 return false; |
| 170 case EmeConfigRule::IDENTIFIER_NOT_ALLOWED: | 171 case EmeConfigRule::IDENTIFIER_NOT_ALLOWED: |
| 171 return !is_identifier_required_; | 172 return !is_identifier_required_; |
| 172 case EmeConfigRule::IDENTIFIER_REQUIRED: | 173 case EmeConfigRule::IDENTIFIER_REQUIRED: |
| 173 // TODO(sandersd): Confirm if we should be refusing these rules when | 174 // TODO(sandersd): Confirm if we should be refusing these rules when |
| 174 // permission has been denied (as the spec currently says). | 175 // permission has been denied (as the spec currently says). |
| 175 return !is_identifier_not_allowed_ && IsPermissionPossible(); | 176 return !is_identifier_not_allowed_ && IsPermissionPossible(); |
| 176 case EmeConfigRule::IDENTIFIER_RECOMMENDED: | 177 case EmeConfigRule::IDENTIFIER_RECOMMENDED: |
| 177 return true; | 178 return true; |
| 178 case EmeConfigRule::PERSISTENCE_NOT_ALLOWED: | 179 case EmeConfigRule::PERSISTENCE_NOT_ALLOWED: |
| 179 return !is_persistence_required_; | 180 return !is_persistence_required_; |
| 180 case EmeConfigRule::PERSISTENCE_REQUIRED: | 181 case EmeConfigRule::PERSISTENCE_REQUIRED: |
| 181 return !is_persistence_not_allowed_; | 182 return !is_persistence_not_allowed_; |
| 182 case EmeConfigRule::IDENTIFIER_AND_PERSISTENCE_REQUIRED: | 183 case EmeConfigRule::IDENTIFIER_AND_PERSISTENCE_REQUIRED: |
| 183 return (!is_identifier_not_allowed_ && IsPermissionPossible() && | 184 return (!is_identifier_not_allowed_ && IsPermissionPossible() && |
| 184 !is_persistence_not_allowed_); | 185 !is_persistence_not_allowed_); |
| 185 case EmeConfigRule::SECURE_CODECS_NOT_ALLOWED: | 186 case EmeConfigRule::HW_SECURE_CODECS_NOT_ALLOWED: |
| 186 return !are_secure_codecs_required_; | 187 return !are_hw_secure_codecs_required_; |
| 187 case EmeConfigRule::SECURE_CODECS_REQUIRED: | 188 case EmeConfigRule::HW_SECURE_CODECS_REQUIRED: |
| 188 return !are_secure_codecs_not_allowed_; | 189 return !are_hw_secure_codecs_not_allowed_; |
| 189 case EmeConfigRule::SUPPORTED: | 190 case EmeConfigRule::SUPPORTED: |
| 190 return true; | 191 return true; |
| 191 } | 192 } |
| 192 NOTREACHED(); | 193 NOTREACHED(); |
| 193 return false; | 194 return false; |
| 194 } | 195 } |
| 195 | 196 |
| 196 // Add a rule to the accumulated configuration state. | 197 // Add a rule to the accumulated configuration state. |
| 197 void AddRule(EmeConfigRule rule) { | 198 void AddRule(EmeConfigRule rule) { |
| 198 DCHECK(IsRuleSupported(rule)); | 199 DCHECK(IsRuleSupported(rule)); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 212 case EmeConfigRule::PERSISTENCE_NOT_ALLOWED: | 213 case EmeConfigRule::PERSISTENCE_NOT_ALLOWED: |
| 213 is_persistence_not_allowed_ = true; | 214 is_persistence_not_allowed_ = true; |
| 214 return; | 215 return; |
| 215 case EmeConfigRule::PERSISTENCE_REQUIRED: | 216 case EmeConfigRule::PERSISTENCE_REQUIRED: |
| 216 is_persistence_required_ = true; | 217 is_persistence_required_ = true; |
| 217 return; | 218 return; |
| 218 case EmeConfigRule::IDENTIFIER_AND_PERSISTENCE_REQUIRED: | 219 case EmeConfigRule::IDENTIFIER_AND_PERSISTENCE_REQUIRED: |
| 219 is_identifier_required_ = true; | 220 is_identifier_required_ = true; |
| 220 is_persistence_required_ = true; | 221 is_persistence_required_ = true; |
| 221 return; | 222 return; |
| 222 case EmeConfigRule::SECURE_CODECS_NOT_ALLOWED: | 223 case EmeConfigRule::HW_SECURE_CODECS_NOT_ALLOWED: |
| 223 are_secure_codecs_not_allowed_ = true; | 224 are_hw_secure_codecs_not_allowed_ = true; |
| 224 return; | 225 return; |
| 225 case EmeConfigRule::SECURE_CODECS_REQUIRED: | 226 case EmeConfigRule::HW_SECURE_CODECS_REQUIRED: |
| 226 are_secure_codecs_required_ = true; | 227 are_hw_secure_codecs_required_ = true; |
| 227 return; | 228 return; |
| 228 case EmeConfigRule::SUPPORTED: | 229 case EmeConfigRule::SUPPORTED: |
| 229 return; | 230 return; |
| 230 } | 231 } |
| 231 NOTREACHED(); | 232 NOTREACHED(); |
| 232 } | 233 } |
| 233 | 234 |
| 234 private: | 235 private: |
| 235 // Whether permission to use a distinctive identifier was requested. If set, | 236 // Whether permission to use a distinctive identifier was requested. If set, |
| 236 // |is_permission_granted_| represents the final decision. | 237 // |is_permission_granted_| represents the final decision. |
| (...skipping 11 matching lines...) Expand all Loading... |
| 248 | 249 |
| 249 // Whether a rule has been added that recommends a distinctive identifier. | 250 // Whether a rule has been added that recommends a distinctive identifier. |
| 250 bool is_identifier_recommended_ = false; | 251 bool is_identifier_recommended_ = false; |
| 251 | 252 |
| 252 // Whether a rule has been added that requires or blocks persistent state. | 253 // Whether a rule has been added that requires or blocks persistent state. |
| 253 bool is_persistence_required_ = false; | 254 bool is_persistence_required_ = false; |
| 254 bool is_persistence_not_allowed_ = false; | 255 bool is_persistence_not_allowed_ = false; |
| 255 | 256 |
| 256 // Whether a rule has been added that requires or blocks hardware-secure | 257 // Whether a rule has been added that requires or blocks hardware-secure |
| 257 // codecs. | 258 // codecs. |
| 258 bool are_secure_codecs_required_ = false; | 259 bool are_hw_secure_codecs_required_ = false; |
| 259 bool are_secure_codecs_not_allowed_ = false; | 260 bool are_hw_secure_codecs_not_allowed_ = false; |
| 260 }; | 261 }; |
| 261 | 262 |
| 262 KeySystemConfigSelector::KeySystemConfigSelector( | 263 KeySystemConfigSelector::KeySystemConfigSelector( |
| 263 const KeySystems* key_systems, | 264 const KeySystems* key_systems, |
| 264 MediaPermission* media_permission) | 265 MediaPermission* media_permission) |
| 265 : key_systems_(key_systems), | 266 : key_systems_(key_systems), |
| 266 media_permission_(media_permission), | 267 media_permission_(media_permission), |
| 267 weak_factory_(this) { | 268 weak_factory_(this) { |
| 268 DCHECK(key_systems_); | 269 DCHECK(key_systems_); |
| 269 DCHECK(media_permission_); | 270 DCHECK(media_permission_); |
| (...skipping 396 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 666 // 17. Return accumulated configuration. | 667 // 17. Return accumulated configuration. |
| 667 return CONFIGURATION_SUPPORTED; | 668 return CONFIGURATION_SUPPORTED; |
| 668 } | 669 } |
| 669 | 670 |
| 670 void KeySystemConfigSelector::SelectConfig( | 671 void KeySystemConfigSelector::SelectConfig( |
| 671 const blink::WebString& key_system, | 672 const blink::WebString& key_system, |
| 672 const blink::WebVector<blink::WebMediaKeySystemConfiguration>& | 673 const blink::WebVector<blink::WebMediaKeySystemConfiguration>& |
| 673 candidate_configurations, | 674 candidate_configurations, |
| 674 const blink::WebSecurityOrigin& security_origin, | 675 const blink::WebSecurityOrigin& security_origin, |
| 675 bool are_secure_codecs_supported, | 676 bool are_secure_codecs_supported, |
| 676 base::Callback<void(const blink::WebMediaKeySystemConfiguration&, bool)> | 677 base::Callback<void(const blink::WebMediaKeySystemConfiguration&, |
| 677 succeeded_cb, | 678 const CdmConfig&)> succeeded_cb, |
| 678 base::Callback<void(const blink::WebString&)> not_supported_cb) { | 679 base::Callback<void(const blink::WebString&)> not_supported_cb) { |
| 679 // Continued from requestMediaKeySystemAccess(), step 7, from | 680 // Continued from requestMediaKeySystemAccess(), step 7, from |
| 680 // https://w3c.github.io/encrypted-media/#requestmediakeysystemaccess | 681 // https://w3c.github.io/encrypted-media/#requestmediakeysystemaccess |
| 681 // | 682 // |
| 682 // 7.1. If keySystem is not one of the Key Systems supported by the user | 683 // 7.1. If keySystem is not one of the Key Systems supported by the user |
| 683 // agent, reject promise with with a new DOMException whose name is | 684 // agent, reject promise with with a new DOMException whose name is |
| 684 // NotSupportedError. String comparison is case-sensitive. | 685 // NotSupportedError. String comparison is case-sensitive. |
| 685 if (!base::IsStringASCII(key_system)) { | 686 if (!base::IsStringASCII(key_system)) { |
| 686 not_supported_cb.Run("Only ASCII keySystems are supported"); | 687 not_supported_cb.Run("Only ASCII keySystems are supported"); |
| 687 return; | 688 return; |
| (...skipping 28 matching lines...) Expand all Loading... |
| 716 for (size_t i = 0; i < request->candidate_configurations.size(); i++) { | 717 for (size_t i = 0; i < request->candidate_configurations.size(); i++) { |
| 717 // 7.3.1. Let candidate configuration be the value. | 718 // 7.3.1. Let candidate configuration be the value. |
| 718 // 7.3.2. Let supported configuration be the result of executing the Get | 719 // 7.3.2. Let supported configuration be the result of executing the Get |
| 719 // Supported Configuration algorithm on implementation, candidate | 720 // Supported Configuration algorithm on implementation, candidate |
| 720 // configuration, and origin. | 721 // configuration, and origin. |
| 721 // 7.3.3. If supported configuration is not null, [initialize and return a | 722 // 7.3.3. If supported configuration is not null, [initialize and return a |
| 722 // new MediaKeySystemAccess object.] | 723 // new MediaKeySystemAccess object.] |
| 723 ConfigState config_state(request->was_permission_requested, | 724 ConfigState config_state(request->was_permission_requested, |
| 724 request->is_permission_granted); | 725 request->is_permission_granted); |
| 725 DCHECK(config_state.IsRuleSupported( | 726 DCHECK(config_state.IsRuleSupported( |
| 726 EmeConfigRule::SECURE_CODECS_NOT_ALLOWED)); | 727 EmeConfigRule::HW_SECURE_CODECS_NOT_ALLOWED)); |
| 727 if (!request->are_secure_codecs_supported) | 728 if (!request->are_secure_codecs_supported) |
| 728 config_state.AddRule(EmeConfigRule::SECURE_CODECS_NOT_ALLOWED); | 729 config_state.AddRule(EmeConfigRule::HW_SECURE_CODECS_NOT_ALLOWED); |
| 729 blink::WebMediaKeySystemConfiguration accumulated_configuration; | 730 blink::WebMediaKeySystemConfiguration accumulated_configuration; |
| 731 CdmConfig cdm_config; |
| 730 ConfigurationSupport support = GetSupportedConfiguration( | 732 ConfigurationSupport support = GetSupportedConfiguration( |
| 731 request->key_system, request->candidate_configurations[i], | 733 request->key_system, request->candidate_configurations[i], |
| 732 &config_state, &accumulated_configuration); | 734 &config_state, &accumulated_configuration); |
| 733 switch (support) { | 735 switch (support) { |
| 734 case CONFIGURATION_NOT_SUPPORTED: | 736 case CONFIGURATION_NOT_SUPPORTED: |
| 735 continue; | 737 continue; |
| 736 case CONFIGURATION_REQUIRES_PERMISSION: | 738 case CONFIGURATION_REQUIRES_PERMISSION: |
| 737 if (request->was_permission_requested) { | 739 if (request->was_permission_requested) { |
| 738 DVLOG(2) << "Rejecting requested configuration because " | 740 DVLOG(2) << "Rejecting requested configuration because " |
| 739 << "permission was denied."; | 741 << "permission was denied."; |
| 740 continue; | 742 continue; |
| 741 } | 743 } |
| 742 media_permission_->RequestPermission( | 744 media_permission_->RequestPermission( |
| 743 MediaPermission::PROTECTED_MEDIA_IDENTIFIER, | 745 MediaPermission::PROTECTED_MEDIA_IDENTIFIER, |
| 744 GURL(request->security_origin.toString()), | 746 GURL(request->security_origin.toString()), |
| 745 base::Bind(&KeySystemConfigSelector::OnPermissionResult, | 747 base::Bind(&KeySystemConfigSelector::OnPermissionResult, |
| 746 weak_factory_.GetWeakPtr(), base::Passed(&request))); | 748 weak_factory_.GetWeakPtr(), base::Passed(&request))); |
| 747 return; | 749 return; |
| 748 case CONFIGURATION_SUPPORTED: | 750 case CONFIGURATION_SUPPORTED: |
| 749 request->succeeded_cb.Run(accumulated_configuration, | 751 cdm_config.allow_distinctive_identifier = |
| 750 config_state.AreSecureCodecsRequired()); | 752 (accumulated_configuration.distinctiveIdentifier == |
| 753 blink::WebMediaKeySystemConfiguration::Requirement::Required); |
| 754 cdm_config.allow_persistent_state = |
| 755 (accumulated_configuration.persistentState == |
| 756 blink::WebMediaKeySystemConfiguration::Requirement::Required); |
| 757 cdm_config.use_hw_secure_codecs = |
| 758 config_state.AreHwSecureCodecsRequired(); |
| 759 request->succeeded_cb.Run(accumulated_configuration, cdm_config); |
| 751 return; | 760 return; |
| 752 } | 761 } |
| 753 } | 762 } |
| 754 | 763 |
| 755 // 7.4. Reject promise with a new DOMException whose name is | 764 // 7.4. Reject promise with a new DOMException whose name is |
| 756 // NotSupportedError. | 765 // NotSupportedError. |
| 757 request->not_supported_cb.Run( | 766 request->not_supported_cb.Run( |
| 758 "None of the requested configurations were supported."); | 767 "None of the requested configurations were supported."); |
| 759 } | 768 } |
| 760 | 769 |
| 761 void KeySystemConfigSelector::OnPermissionResult( | 770 void KeySystemConfigSelector::OnPermissionResult( |
| 762 scoped_ptr<SelectionRequest> request, | 771 scoped_ptr<SelectionRequest> request, |
| 763 bool is_permission_granted) { | 772 bool is_permission_granted) { |
| 764 request->was_permission_requested = true; | 773 request->was_permission_requested = true; |
| 765 request->is_permission_granted = is_permission_granted; | 774 request->is_permission_granted = is_permission_granted; |
| 766 SelectConfigInternal(request.Pass()); | 775 SelectConfigInternal(request.Pass()); |
| 767 } | 776 } |
| 768 | 777 |
| 769 } // namespace media | 778 } // namespace media |
| OLD | NEW |