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