OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "key_system_config_selector.h" | 5 #include "key_system_config_selector.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "base/strings/string_util.h" | 9 #include "base/strings/string_util.h" |
10 #include "base/strings/utf_string_conversions.h" | 10 #include "base/strings/utf_string_conversions.h" |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
170 return !is_identifier_not_allowed_ && IsPermissionPossible(); | 170 return !is_identifier_not_allowed_ && IsPermissionPossible(); |
171 case EmeConfigRule::IDENTIFIER_RECOMMENDED: | 171 case EmeConfigRule::IDENTIFIER_RECOMMENDED: |
172 return true; | 172 return true; |
173 case EmeConfigRule::PERSISTENCE_NOT_ALLOWED: | 173 case EmeConfigRule::PERSISTENCE_NOT_ALLOWED: |
174 return !is_persistence_required_; | 174 return !is_persistence_required_; |
175 case EmeConfigRule::PERSISTENCE_REQUIRED: | 175 case EmeConfigRule::PERSISTENCE_REQUIRED: |
176 return !is_persistence_not_allowed_; | 176 return !is_persistence_not_allowed_; |
177 case EmeConfigRule::IDENTIFIER_AND_PERSISTENCE_REQUIRED: | 177 case EmeConfigRule::IDENTIFIER_AND_PERSISTENCE_REQUIRED: |
178 return (!is_identifier_not_allowed_ && IsPermissionPossible() && | 178 return (!is_identifier_not_allowed_ && IsPermissionPossible() && |
179 !is_persistence_not_allowed_); | 179 !is_persistence_not_allowed_); |
| 180 #if defined(OS_ANDROID) |
| 181 case EmeConfigRule::SECURE_CODECS_NOT_ALLOWED: |
| 182 return !are_secure_codecs_required_; |
| 183 case EmeConfigRule::SECURE_CODECS_REQUIRED: |
| 184 return !are_secure_codecs_not_allowed_; |
| 185 #endif // defined(OS_ANDROID) |
180 case EmeConfigRule::SUPPORTED: | 186 case EmeConfigRule::SUPPORTED: |
181 return true; | 187 return true; |
182 } | 188 } |
183 NOTREACHED(); | 189 NOTREACHED(); |
184 return false; | 190 return false; |
185 } | 191 } |
186 | 192 |
187 // Add a rule to the accumulated configuration state. | 193 // Add a rule to the accumulated configuration state. |
188 void AddRule(EmeConfigRule rule) { | 194 void AddRule(EmeConfigRule rule) { |
189 DCHECK(IsRuleSupported(rule)); | 195 DCHECK(IsRuleSupported(rule)); |
(...skipping 13 matching lines...) Expand all Loading... |
203 case EmeConfigRule::PERSISTENCE_NOT_ALLOWED: | 209 case EmeConfigRule::PERSISTENCE_NOT_ALLOWED: |
204 is_persistence_not_allowed_ = true; | 210 is_persistence_not_allowed_ = true; |
205 return; | 211 return; |
206 case EmeConfigRule::PERSISTENCE_REQUIRED: | 212 case EmeConfigRule::PERSISTENCE_REQUIRED: |
207 is_persistence_required_ = true; | 213 is_persistence_required_ = true; |
208 return; | 214 return; |
209 case EmeConfigRule::IDENTIFIER_AND_PERSISTENCE_REQUIRED: | 215 case EmeConfigRule::IDENTIFIER_AND_PERSISTENCE_REQUIRED: |
210 is_identifier_required_ = true; | 216 is_identifier_required_ = true; |
211 is_persistence_required_ = true; | 217 is_persistence_required_ = true; |
212 return; | 218 return; |
| 219 #if defined(OS_ANDROID) |
| 220 case EmeConfigRule::SECURE_CODECS_NOT_ALLOWED: |
| 221 are_secure_codecs_not_allowed_ = true; |
| 222 return; |
| 223 case EmeConfigRule::SECURE_CODECS_REQUIRED: |
| 224 are_secure_codecs_required_ = true; |
| 225 return; |
| 226 #endif // defined(OS_ANDROID) |
213 case EmeConfigRule::SUPPORTED: | 227 case EmeConfigRule::SUPPORTED: |
214 return; | 228 return; |
215 } | 229 } |
216 NOTREACHED(); | 230 NOTREACHED(); |
217 } | 231 } |
218 | 232 |
219 private: | 233 private: |
220 // Whether permission to use a distinctive identifier was requested. If set, | 234 // Whether permission to use a distinctive identifier was requested. If set, |
221 // |is_permission_granted_| represents the final decision. | 235 // |is_permission_granted_| represents the final decision. |
222 const bool was_permission_requested_; | 236 // (Not changed by adding rules.) |
| 237 bool was_permission_requested_; |
223 | 238 |
224 // Whether permission to use a distinctive identifier has been granted. | 239 // Whether permission to use a distinctive identifier has been granted. |
225 const bool is_permission_granted_; | 240 // (Not changed by adding rules.) |
| 241 bool is_permission_granted_; |
226 | 242 |
227 // Whether a rule has been added that requires or blocks a distinctive | 243 // Whether a rule has been added that requires or blocks a distinctive |
228 // identifier. | 244 // identifier. |
229 bool is_identifier_required_ = false; | 245 bool is_identifier_required_ = false; |
230 bool is_identifier_not_allowed_ = false; | 246 bool is_identifier_not_allowed_ = false; |
231 | 247 |
232 // Whether a rule has been added that recommends a distinctive identifier. | 248 // Whether a rule has been added that recommends a distinctive identifier. |
233 bool is_identifier_recommended_ = false; | 249 bool is_identifier_recommended_ = false; |
234 | 250 |
235 // Whether a rule has been added that requires or blocks persistent state. | 251 // Whether a rule has been added that requires or blocks persistent state. |
236 bool is_persistence_required_ = false; | 252 bool is_persistence_required_ = false; |
237 bool is_persistence_not_allowed_ = false; | 253 bool is_persistence_not_allowed_ = false; |
238 | 254 |
239 DISALLOW_COPY_AND_ASSIGN(ConfigState); | 255 #if defined(OS_ANDROID) |
| 256 // Whether a rule has been added that requires or blocks secure codecs. |
| 257 bool are_secure_codecs_required_ = false; |
| 258 bool are_secure_codecs_not_allowed_ = false; |
| 259 #endif // defined(OS_ANDROID) |
240 }; | 260 }; |
241 | 261 |
242 KeySystemConfigSelector::KeySystemConfigSelector( | 262 KeySystemConfigSelector::KeySystemConfigSelector( |
243 const KeySystems* key_systems, | 263 const KeySystems* key_systems, |
244 MediaPermission* media_permission) | 264 MediaPermission* media_permission) |
245 : key_systems_(key_systems), | 265 : key_systems_(key_systems), |
246 media_permission_(media_permission), | 266 media_permission_(media_permission), |
247 weak_factory_(this) { | 267 weak_factory_(this) { |
248 DCHECK(key_systems_); | 268 DCHECK(key_systems_); |
249 DCHECK(media_permission_); | 269 DCHECK(media_permission_); |
250 } | 270 } |
251 | 271 |
252 KeySystemConfigSelector::~KeySystemConfigSelector() { | 272 KeySystemConfigSelector::~KeySystemConfigSelector() { |
253 } | 273 } |
254 | 274 |
255 bool KeySystemConfigSelector::IsSupportedContentType( | 275 bool KeySystemConfigSelector::IsSupportedContentType( |
256 const std::string& key_system, | 276 const std::string& key_system, |
257 EmeMediaType media_type, | 277 EmeMediaType media_type, |
258 const std::string& container_mime_type, | 278 const std::string& container_mime_type, |
259 const std::string& codecs) { | 279 const std::string& codecs, |
| 280 KeySystemConfigSelector::ConfigState* config_state) { |
260 // TODO(sandersd): Move contentType parsing from Blink to here so that invalid | 281 // TODO(sandersd): Move contentType parsing from Blink to here so that invalid |
261 // parameters can be rejected. http://crbug.com/417561 | 282 // parameters can be rejected. http://crbug.com/417561 |
262 std::string container_lower = base::StringToLowerASCII(container_mime_type); | 283 std::string container_lower = base::StringToLowerASCII(container_mime_type); |
263 | 284 |
264 // Check that |container_mime_type| and |codecs| are supported by the CDM. | 285 // Check that |container_mime_type| is supported by Chrome. |
265 // This check does not handle extended codecs, so extended codec information | 286 if (!net::IsSupportedMediaMimeType(container_lower)) |
266 // is stripped. | |
267 std::vector<std::string> codec_vector; | |
268 net::ParseCodecString(codecs, &codec_vector, true); | |
269 if (!key_systems_->IsSupportedCodecCombination( | |
270 key_system, media_type, container_lower, codec_vector)) { | |
271 return false; | 287 return false; |
272 } | |
273 | |
274 // Check that |container_mime_type| is supported by Chrome. This can only | |
275 // happen if the CDM declares support for a container that Chrome does not. | |
276 if (!net::IsSupportedMediaMimeType(container_lower)) { | |
277 NOTREACHED(); | |
278 return false; | |
279 } | |
280 | 288 |
281 // Check that |codecs| are supported by Chrome. This is done primarily to | 289 // Check that |codecs| are supported by Chrome. This is done primarily to |
282 // validate extended codecs, but it also ensures that the CDM cannot support | 290 // validate extended codecs, but it also ensures that the CDM cannot support |
283 // codecs that Chrome does not (which could complicate the robustness | 291 // codecs that Chrome does not (which could complicate the robustness |
284 // algorithm). | 292 // algorithm). |
285 if (codec_vector.empty()) | 293 std::vector<std::string> codec_vector; |
286 return true; | |
287 codec_vector.clear(); | |
288 net::ParseCodecString(codecs, &codec_vector, false); | 294 net::ParseCodecString(codecs, &codec_vector, false); |
289 return (net::IsSupportedStrictMediaMimeType(container_lower, codec_vector) == | 295 if (!codec_vector.empty() && |
290 net::IsSupported); | 296 (net::IsSupportedStrictMediaMimeType(container_lower, codec_vector) != |
| 297 net::IsSupported)) { |
| 298 return false; |
| 299 } |
| 300 |
| 301 // Check that |container_mime_type| and |codecs| are supported by the CDM. |
| 302 // This check does not handle extended codecs, so extended codec information |
| 303 // is stripped (extended codec information was checked above). |
| 304 std::vector<std::string> stripped_codec_vector; |
| 305 net::ParseCodecString(codecs, &stripped_codec_vector, true); |
| 306 EmeConfigRule codecs_rule = key_systems_->GetContentTypeConfigRule( |
| 307 key_system, media_type, container_lower, stripped_codec_vector); |
| 308 if (!config_state->IsRuleSupported(codecs_rule)) |
| 309 return false; |
| 310 config_state->AddRule(codecs_rule); |
| 311 |
| 312 return true; |
291 } | 313 } |
292 | 314 |
293 bool KeySystemConfigSelector::GetSupportedCapabilities( | 315 bool KeySystemConfigSelector::GetSupportedCapabilities( |
294 const std::string& key_system, | 316 const std::string& key_system, |
295 EmeMediaType media_type, | 317 EmeMediaType media_type, |
296 const blink::WebVector<blink::WebMediaKeySystemMediaCapability>& | 318 const blink::WebVector<blink::WebMediaKeySystemMediaCapability>& |
297 requested_media_capabilities, | 319 requested_media_capabilities, |
298 KeySystemConfigSelector::ConfigState* config_state, | 320 KeySystemConfigSelector::ConfigState* config_state, |
299 std::vector<blink::WebMediaKeySystemMediaCapability>* | 321 std::vector<blink::WebMediaKeySystemMediaCapability>* |
300 supported_media_capabilities) { | 322 supported_media_capabilities) { |
(...skipping 10 matching lines...) Expand all Loading... |
311 // 3.1. Let contentType be the value's contentType member. | 333 // 3.1. Let contentType be the value's contentType member. |
312 // 3.2. Let robustness be the value's robustness member. | 334 // 3.2. Let robustness be the value's robustness member. |
313 const blink::WebMediaKeySystemMediaCapability& capability = | 335 const blink::WebMediaKeySystemMediaCapability& capability = |
314 requested_media_capabilities[i]; | 336 requested_media_capabilities[i]; |
315 // 3.3. If contentType is the empty string, return null. | 337 // 3.3. If contentType is the empty string, return null. |
316 if (capability.mimeType.isEmpty()) { | 338 if (capability.mimeType.isEmpty()) { |
317 DVLOG(2) << "Rejecting requested configuration because " | 339 DVLOG(2) << "Rejecting requested configuration because " |
318 << "a capability contentType was empty."; | 340 << "a capability contentType was empty."; |
319 return false; | 341 return false; |
320 } | 342 } |
| 343 |
321 // 3.4-3.11. (Implemented by IsSupportedContentType().) | 344 // 3.4-3.11. (Implemented by IsSupportedContentType().) |
| 345 ConfigState proposed_config_state = *config_state; |
322 if (!base::IsStringASCII(capability.mimeType) || | 346 if (!base::IsStringASCII(capability.mimeType) || |
323 !base::IsStringASCII(capability.codecs) || | 347 !base::IsStringASCII(capability.codecs) || |
324 !IsSupportedContentType(key_system, media_type, | 348 !IsSupportedContentType(key_system, media_type, |
325 base::UTF16ToASCII(capability.mimeType), | 349 base::UTF16ToASCII(capability.mimeType), |
326 base::UTF16ToASCII(capability.codecs))) { | 350 base::UTF16ToASCII(capability.codecs), |
| 351 &proposed_config_state)) { |
327 continue; | 352 continue; |
328 } | 353 } |
329 // 3.12. If robustness is not the empty string, run the following steps: | 354 // 3.12. If robustness is not the empty string, run the following steps: |
330 if (!capability.robustness.isEmpty()) { | 355 if (!capability.robustness.isEmpty()) { |
331 // 3.12.1. If robustness is an unrecognized value or not supported by | 356 // 3.12.1. If robustness is an unrecognized value or not supported by |
332 // implementation, continue to the next iteration. String | 357 // implementation, continue to the next iteration. String |
333 // comparison is case-sensitive. | 358 // comparison is case-sensitive. |
334 if (!base::IsStringASCII(capability.robustness)) | 359 if (!base::IsStringASCII(capability.robustness)) |
335 continue; | 360 continue; |
336 EmeConfigRule robustness_rule = key_systems_->GetRobustnessConfigRule( | 361 EmeConfigRule robustness_rule = key_systems_->GetRobustnessConfigRule( |
337 key_system, media_type, base::UTF16ToASCII(capability.robustness)); | 362 key_system, media_type, base::UTF16ToASCII(capability.robustness)); |
338 if (!config_state->IsRuleSupported(robustness_rule)) | 363 if (!proposed_config_state.IsRuleSupported(robustness_rule)) |
339 continue; | 364 continue; |
340 config_state->AddRule(robustness_rule); | 365 proposed_config_state.AddRule(robustness_rule); |
341 // 3.12.2. Add robustness to configuration. | 366 // 3.12.2. Add robustness to configuration. |
342 // (It's already added, we use capability as configuration.) | 367 // (It's already added, we use capability as configuration.) |
343 } | 368 } |
344 // 3.13. If the user agent and implementation do not support playback of | 369 // 3.13. If the user agent and implementation do not support playback of |
345 // encrypted media data as specified by configuration, including all | 370 // encrypted media data as specified by configuration, including all |
346 // media types, in combination with local accumulated capabilities, | 371 // media types, in combination with local accumulated capabilities, |
347 // continue to the next iteration. | 372 // continue to the next iteration. |
348 // (This is handled when adding rules to |config_state|.) | 373 // (This is handled when adding rules to |proposed_config_state|.) |
349 // 3.14. Add configuration to supported media capabilities. | 374 // 3.14. Add configuration to supported media capabilities. |
350 supported_media_capabilities->push_back(capability); | 375 supported_media_capabilities->push_back(capability); |
351 // 3.15. Add configuration to local accumulated capabilities. | 376 // 3.15. Add configuration to local accumulated capabilities. |
352 // (Skipped as we directly update |config_state|.) | 377 *config_state = proposed_config_state; |
353 } | 378 } |
354 // 4. If supported media capabilities is empty, return null. | 379 // 4. If supported media capabilities is empty, return null. |
355 if (supported_media_capabilities->empty()) { | 380 if (supported_media_capabilities->empty()) { |
356 DVLOG(2) << "Rejecting requested configuration because " | 381 DVLOG(2) << "Rejecting requested configuration because " |
357 << "no capabilities were supported."; | 382 << "no capabilities were supported."; |
358 return false; | 383 return false; |
359 } | 384 } |
360 // 5. Return media type capabilities. | 385 // 5. Return media type capabilities. |
361 return true; | 386 return true; |
362 } | 387 } |
363 | 388 |
364 KeySystemConfigSelector::ConfigurationSupport | 389 KeySystemConfigSelector::ConfigurationSupport |
365 KeySystemConfigSelector::GetSupportedConfiguration( | 390 KeySystemConfigSelector::GetSupportedConfiguration( |
366 const std::string& key_system, | 391 const std::string& key_system, |
367 const blink::WebMediaKeySystemConfiguration& candidate, | 392 const blink::WebMediaKeySystemConfiguration& candidate, |
368 ConfigState* config_state, | 393 ConfigState* config_state, |
369 blink::WebMediaKeySystemConfiguration* accumulated_configuration) { | 394 blink::WebMediaKeySystemConfiguration* accumulated_configuration) { |
| 395 // TODO(sandersd): Set state of SECURE_CODECS from renderer pref. |
370 // From https://w3c.github.io/encrypted-media/#get-supported-configuration | 396 // From https://w3c.github.io/encrypted-media/#get-supported-configuration |
371 // 1. Let accumulated configuration be empty. (Done by caller.) | 397 // 1. Let accumulated configuration be empty. (Done by caller.) |
372 // 2. If the initDataTypes member is present in candidate configuration, run | 398 // 2. If the initDataTypes member is present in candidate configuration, run |
373 // the following steps: | 399 // the following steps: |
374 if (candidate.hasInitDataTypes) { | 400 if (candidate.hasInitDataTypes) { |
375 // 2.1. Let supported types be empty. | 401 // 2.1. Let supported types be empty. |
376 std::vector<blink::WebEncryptedMediaInitDataType> supported_types; | 402 std::vector<blink::WebEncryptedMediaInitDataType> supported_types; |
377 | 403 |
378 // 2.2. For each value in candidate configuration's initDataTypes member: | 404 // 2.2. For each value in candidate configuration's initDataTypes member: |
379 for (size_t i = 0; i < candidate.initDataTypes.size(); i++) { | 405 for (size_t i = 0; i < candidate.initDataTypes.size(); i++) { |
(...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
728 | 754 |
729 void KeySystemConfigSelector::OnPermissionResult( | 755 void KeySystemConfigSelector::OnPermissionResult( |
730 scoped_ptr<SelectionRequest> request, | 756 scoped_ptr<SelectionRequest> request, |
731 bool is_permission_granted) { | 757 bool is_permission_granted) { |
732 request->was_permission_requested = true; | 758 request->was_permission_requested = true; |
733 request->is_permission_granted = is_permission_granted; | 759 request->is_permission_granted = is_permission_granted; |
734 SelectConfigInternal(request.Pass()); | 760 SelectConfigInternal(request.Pass()); |
735 } | 761 } |
736 | 762 |
737 } // namespace media | 763 } // namespace media |
OLD | NEW |