OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/base/key_systems.h" | 5 #include "media/base/key_systems.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "base/containers/hash_tables.h" | 9 #include "base/containers/hash_tables.h" |
10 #include "base/lazy_instance.h" | 10 #include "base/lazy_instance.h" |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
69 {"vp8.0", EME_CODEC_WEBM_VP8}, | 69 {"vp8.0", EME_CODEC_WEBM_VP8}, |
70 {"vp9", EME_CODEC_WEBM_VP9}, | 70 {"vp9", EME_CODEC_WEBM_VP9}, |
71 {"vp9.0", EME_CODEC_WEBM_VP9}, | 71 {"vp9.0", EME_CODEC_WEBM_VP9}, |
72 #if defined(USE_PROPRIETARY_CODECS) | 72 #if defined(USE_PROPRIETARY_CODECS) |
73 {"mp4a", EME_CODEC_MP4_AAC}, | 73 {"mp4a", EME_CODEC_MP4_AAC}, |
74 {"avc1", EME_CODEC_MP4_AVC1}, | 74 {"avc1", EME_CODEC_MP4_AVC1}, |
75 {"avc3", EME_CODEC_MP4_AVC1} | 75 {"avc3", EME_CODEC_MP4_AVC1} |
76 #endif // defined(USE_PROPRIETARY_CODECS) | 76 #endif // defined(USE_PROPRIETARY_CODECS) |
77 }; | 77 }; |
78 | 78 |
| 79 static EmeConfigRule ConvertSessionTypeSupport( |
| 80 EmeSessionTypeSupport support) { |
| 81 switch (support) { |
| 82 case EME_SESSION_TYPE_INVALID: |
| 83 NOTREACHED(); |
| 84 return EmeConfigRule::NOT_SUPPORTED; |
| 85 case EME_SESSION_TYPE_NOT_SUPPORTED: |
| 86 return EmeConfigRule::NOT_SUPPORTED; |
| 87 case EME_SESSION_TYPE_SUPPORTED_WITH_IDENTIFIER: |
| 88 return EmeConfigRule::IDENTIFIER_REQUIRED; |
| 89 case EME_SESSION_TYPE_SUPPORTED: |
| 90 return EmeConfigRule::SUPPORTED; |
| 91 } |
| 92 NOTREACHED(); |
| 93 return EmeConfigRule::NOT_SUPPORTED; |
| 94 } |
| 95 |
| 96 static EmeRobustness ConvertRobustness(const std::string& robustness) { |
| 97 if (robustness.empty()) |
| 98 return EmeRobustness::EMPTY; |
| 99 if (robustness == "SW_SECURE_CRYPTO") |
| 100 return EmeRobustness::SW_SECURE_CRYPTO; |
| 101 if (robustness == "SW_SECURE_DECODE") |
| 102 return EmeRobustness::SW_SECURE_DECODE; |
| 103 if (robustness == "HW_SECURE_CRYPTO") |
| 104 return EmeRobustness::HW_SECURE_CRYPTO; |
| 105 if (robustness == "HW_SECURE_DECODE") |
| 106 return EmeRobustness::HW_SECURE_DECODE; |
| 107 if (robustness == "HW_SECURE_ALL") |
| 108 return EmeRobustness::HW_SECURE_ALL; |
| 109 return EmeRobustness::INVALID; |
| 110 } |
| 111 |
79 static void AddClearKey(std::vector<KeySystemInfo>* concrete_key_systems) { | 112 static void AddClearKey(std::vector<KeySystemInfo>* concrete_key_systems) { |
80 KeySystemInfo info; | 113 KeySystemInfo info; |
81 info.key_system = kClearKeyKeySystem; | 114 info.key_system = kClearKeyKeySystem; |
82 | 115 |
83 // On Android, Vorbis, VP8, AAC and AVC1 are supported in MediaCodec: | 116 // On Android, Vorbis, VP8, AAC and AVC1 are supported in MediaCodec: |
84 // http://developer.android.com/guide/appendix/media-formats.html | 117 // http://developer.android.com/guide/appendix/media-formats.html |
85 // VP9 support is device dependent. | 118 // VP9 support is device dependent. |
86 | 119 |
87 info.supported_init_data_types = | 120 info.supported_init_data_types = |
88 EME_INIT_DATA_TYPE_WEBM | EME_INIT_DATA_TYPE_KEYIDS; | 121 EME_INIT_DATA_TYPE_WEBM | EME_INIT_DATA_TYPE_KEYIDS; |
89 info.supported_codecs = EME_CODEC_WEBM_ALL; | 122 info.supported_codecs = EME_CODEC_WEBM_ALL; |
90 | 123 |
91 #if defined(OS_ANDROID) | 124 #if defined(OS_ANDROID) |
92 // Temporarily disable VP9 support for Android. | 125 // Temporarily disable VP9 support for Android. |
93 // TODO(xhwang): Use mime_util.h to query VP9 support on Android. | 126 // TODO(xhwang): Use mime_util.h to query VP9 support on Android. |
94 info.supported_codecs &= ~EME_CODEC_WEBM_VP9; | 127 info.supported_codecs &= ~EME_CODEC_WEBM_VP9; |
95 | 128 |
96 // Opus is not supported on Android yet. http://crbug.com/318436. | 129 // Opus is not supported on Android yet. http://crbug.com/318436. |
97 // TODO(sandersd): Check for platform support to set this bit. | 130 // TODO(sandersd): Check for platform support to set this bit. |
98 info.supported_codecs &= ~EME_CODEC_WEBM_OPUS; | 131 info.supported_codecs &= ~EME_CODEC_WEBM_OPUS; |
99 #endif // defined(OS_ANDROID) | 132 #endif // defined(OS_ANDROID) |
100 | 133 |
101 #if defined(USE_PROPRIETARY_CODECS) | 134 #if defined(USE_PROPRIETARY_CODECS) |
102 info.supported_init_data_types |= EME_INIT_DATA_TYPE_CENC; | 135 info.supported_init_data_types |= EME_INIT_DATA_TYPE_CENC; |
103 info.supported_codecs |= EME_CODEC_MP4_ALL; | 136 info.supported_codecs |= EME_CODEC_MP4_ALL; |
104 #endif // defined(USE_PROPRIETARY_CODECS) | 137 #endif // defined(USE_PROPRIETARY_CODECS) |
105 | 138 |
| 139 info.max_audio_robustness = EmeRobustness::EMPTY; |
| 140 info.max_video_robustness = EmeRobustness::EMPTY; |
106 info.persistent_license_support = EME_SESSION_TYPE_NOT_SUPPORTED; | 141 info.persistent_license_support = EME_SESSION_TYPE_NOT_SUPPORTED; |
107 info.persistent_release_message_support = EME_SESSION_TYPE_NOT_SUPPORTED; | 142 info.persistent_release_message_support = EME_SESSION_TYPE_NOT_SUPPORTED; |
108 info.persistent_state_support = EME_FEATURE_NOT_SUPPORTED; | 143 info.persistent_state_support = EME_FEATURE_NOT_SUPPORTED; |
109 info.distinctive_identifier_support = EME_FEATURE_NOT_SUPPORTED; | 144 info.distinctive_identifier_support = EME_FEATURE_NOT_SUPPORTED; |
110 | 145 |
111 info.use_aes_decryptor = true; | 146 info.use_aes_decryptor = true; |
112 | 147 |
113 concrete_key_systems->push_back(info); | 148 concrete_key_systems->push_back(info); |
114 } | 149 } |
115 | 150 |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
184 bool is_prefixed); | 219 bool is_prefixed); |
185 | 220 |
186 std::string GetKeySystemNameForUMA(const std::string& key_system) const; | 221 std::string GetKeySystemNameForUMA(const std::string& key_system) const; |
187 | 222 |
188 bool UseAesDecryptor(const std::string& concrete_key_system); | 223 bool UseAesDecryptor(const std::string& concrete_key_system); |
189 | 224 |
190 #if defined(ENABLE_PEPPER_CDMS) | 225 #if defined(ENABLE_PEPPER_CDMS) |
191 std::string GetPepperType(const std::string& concrete_key_system); | 226 std::string GetPepperType(const std::string& concrete_key_system); |
192 #endif | 227 #endif |
193 | 228 |
194 bool IsPersistentLicenseSessionSupported( | 229 EmeConfigRule GetRobustnessConfigRule( |
195 const std::string& key_system, | 230 const std::string& key_system, |
196 bool is_permission_granted); | 231 EmeMediaType media_type, |
| 232 const std::string& requested_robustness); |
197 | 233 |
198 bool IsPersistentReleaseMessageSessionSupported( | 234 EmeConfigRule GetPersistentLicenseSessionConfigRule( |
| 235 const std::string& key_system); |
| 236 |
| 237 EmeConfigRule GetPersistentReleaseMessageSessionConfigRule( |
| 238 const std::string& key_system); |
| 239 |
| 240 EmeConfigRule GetPersistentStateConfigRule( |
199 const std::string& key_system, | 241 const std::string& key_system, |
200 bool is_permission_granted); | 242 EmeFeatureRequirement requirement); |
201 | 243 |
202 bool IsPersistentStateRequirementSupported( | 244 EmeConfigRule GetDistinctiveIdentifierConfigRule( |
203 const std::string& key_system, | 245 const std::string& key_system, |
204 EmeFeatureRequirement requirement, | 246 EmeFeatureRequirement requirement); |
205 bool is_permission_granted); | |
206 | |
207 bool IsDistinctiveIdentifierRequirementSupported( | |
208 const std::string& key_system, | |
209 EmeFeatureRequirement requirement, | |
210 bool is_permission_granted); | |
211 | 247 |
212 void AddContainerMask(const std::string& container, uint32 mask); | 248 void AddContainerMask(const std::string& container, uint32 mask); |
213 void AddCodecMask(const std::string& codec, uint32 mask); | 249 void AddCodecMask(const std::string& codec, uint32 mask); |
214 | 250 |
215 private: | 251 private: |
216 void InitializeUMAInfo(); | 252 void InitializeUMAInfo(); |
217 | 253 |
218 void UpdateSupportedKeySystems(); | 254 void UpdateSupportedKeySystems(); |
219 | 255 |
220 void AddConcreteSupportedKeySystems( | 256 void AddConcreteSupportedKeySystems( |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
387 } | 423 } |
388 | 424 |
389 void KeySystems::AddConcreteSupportedKeySystems( | 425 void KeySystems::AddConcreteSupportedKeySystems( |
390 const std::vector<KeySystemInfo>& concrete_key_systems) { | 426 const std::vector<KeySystemInfo>& concrete_key_systems) { |
391 DCHECK(thread_checker_.CalledOnValidThread()); | 427 DCHECK(thread_checker_.CalledOnValidThread()); |
392 DCHECK(concrete_key_system_map_.empty()); | 428 DCHECK(concrete_key_system_map_.empty()); |
393 DCHECK(parent_key_system_map_.empty()); | 429 DCHECK(parent_key_system_map_.empty()); |
394 | 430 |
395 for (const KeySystemInfo& info : concrete_key_systems) { | 431 for (const KeySystemInfo& info : concrete_key_systems) { |
396 DCHECK(!info.key_system.empty()); | 432 DCHECK(!info.key_system.empty()); |
397 DCHECK_NE(info.persistent_license_support, EME_SESSION_TYPE_INVALID); | 433 DCHECK(info.max_audio_robustness != EmeRobustness::INVALID); |
398 DCHECK_NE(info.persistent_release_message_support, | 434 DCHECK(info.max_video_robustness != EmeRobustness::INVALID); |
399 EME_SESSION_TYPE_INVALID); | 435 DCHECK(info.persistent_license_support != EME_SESSION_TYPE_INVALID); |
400 // TODO(sandersd): Add REQUESTABLE and REQUESTABLE_WITH_PERMISSION for | 436 DCHECK(info.persistent_release_message_support != EME_SESSION_TYPE_INVALID); |
401 // persistent_state_support once we can block access per-CDM-instance | 437 DCHECK(info.persistent_state_support != EME_FEATURE_INVALID); |
402 // (http://crbug.com/457482). | 438 DCHECK(info.distinctive_identifier_support != EME_FEATURE_INVALID); |
403 DCHECK(info.persistent_state_support == EME_FEATURE_NOT_SUPPORTED || | 439 |
404 info.persistent_state_support == EME_FEATURE_ALWAYS_ENABLED); | 440 // Supporting persistent state is a prerequsite for supporting persistent |
405 // TODO(sandersd): Allow REQUESTABLE_WITH_PERMISSION for all key systems on | 441 // sessions. |
406 // all platforms once we have proper enforcement (http://crbug.com/457482). | 442 if (info.persistent_state_support == EME_FEATURE_NOT_SUPPORTED) { |
407 // On Chrome OS, an ID will not be used without permission, but we cannot | 443 DCHECK(info.persistent_license_support == EME_SESSION_TYPE_NOT_SUPPORTED); |
408 // currently prevent the CDM from requesting the permission again when no | 444 DCHECK(info.persistent_release_message_support == |
409 // there was no initial prompt. Thus, we block "not-allowed" below. | 445 EME_SESSION_TYPE_NOT_SUPPORTED); |
410 #if defined(OS_CHROMEOS) | 446 } |
411 DCHECK(info.distinctive_identifier_support == EME_FEATURE_NOT_SUPPORTED || | 447 else if (info.persistent_state_support == |
412 (info.distinctive_identifier_support == | 448 EME_FEATURE_REQUESTABLE_WITH_IDENTIFIER) { |
413 EME_FEATURE_REQUESTABLE_WITH_PERMISSION && | 449 // Must be either NOT_SUPPORTED or SUPPORTED_WITH_IDENTIFIER. |
414 info.key_system == kWidevineKeySystem) || | 450 DCHECK(info.persistent_license_support != EME_SESSION_TYPE_SUPPORTED); |
415 info.distinctive_identifier_support == EME_FEATURE_ALWAYS_ENABLED); | 451 DCHECK(info.persistent_release_message_support != |
416 #else | 452 EME_SESSION_TYPE_SUPPORTED); |
417 DCHECK(info.distinctive_identifier_support == EME_FEATURE_NOT_SUPPORTED || | 453 } |
418 info.distinctive_identifier_support == EME_FEATURE_ALWAYS_ENABLED); | 454 |
| 455 // persistent-release-message sessions are not currently supported. |
| 456 // http://crbug.com/448888 |
| 457 DCHECK(info.persistent_release_message_support == |
| 458 EME_SESSION_TYPE_NOT_SUPPORTED); |
| 459 |
| 460 // Because an optional persistent state value is resolved after an optional |
| 461 // distinctive identifier, persistent state requiring a distinctive |
| 462 // identifier may not resolve correctly. |
| 463 DCHECK(info.persistent_state_support != |
| 464 EME_FEATURE_REQUESTABLE_WITH_IDENTIFIER); |
| 465 |
| 466 // If supported, distinctive identifiers always require permission. |
| 467 DCHECK(info.distinctive_identifier_support != EME_FEATURE_REQUESTABLE); |
| 468 |
| 469 // If distinctive identifiers are not supported, then no other features can |
| 470 // require them. |
| 471 if (info.distinctive_identifier_support == EME_FEATURE_NOT_SUPPORTED) { |
| 472 DCHECK(info.persistent_license_support != |
| 473 EME_SESSION_TYPE_SUPPORTED_WITH_IDENTIFIER); |
| 474 DCHECK(info.persistent_release_message_support != |
| 475 EME_SESSION_TYPE_SUPPORTED_WITH_IDENTIFIER); |
| 476 } |
| 477 |
| 478 // Distinctive identifiers and persistent state can only be reliably blocked |
| 479 // (and therefore be safely configurable) for Pepper-hosted key systems. For |
| 480 // other platforms, only non-configurable values are valid. |
| 481 bool can_block = false; |
| 482 #if defined(ENABLE_PEPPER_CDMS) |
| 483 DCHECK_EQ(info.use_aes_decryptor, info.pepper_type.empty()); |
| 484 can_block = !info.pepper_type.empty(); |
419 #endif | 485 #endif |
420 if (info.persistent_state_support == EME_FEATURE_NOT_SUPPORTED) { | 486 if (!can_block) { |
421 DCHECK_EQ(info.persistent_license_support, | 487 DCHECK(info.distinctive_identifier_support == EME_FEATURE_NOT_SUPPORTED || |
422 EME_SESSION_TYPE_NOT_SUPPORTED); | 488 info.distinctive_identifier_support == EME_FEATURE_ALWAYS_ENABLED); |
423 DCHECK_EQ(info.persistent_release_message_support, | 489 DCHECK(info.persistent_state_support == EME_FEATURE_NOT_SUPPORTED || |
424 EME_SESSION_TYPE_NOT_SUPPORTED); | 490 info.persistent_state_support == EME_FEATURE_ALWAYS_ENABLED); |
425 } | 491 } |
| 492 |
426 DCHECK(!IsSupportedKeySystem(info.key_system)) | 493 DCHECK(!IsSupportedKeySystem(info.key_system)) |
427 << "Key system '" << info.key_system << "' already registered"; | 494 << "Key system '" << info.key_system << "' already registered"; |
428 DCHECK(!parent_key_system_map_.count(info.key_system)) | 495 DCHECK(!parent_key_system_map_.count(info.key_system)) |
429 << "'" << info.key_system << "' is already registered as a parent"; | 496 << "'" << info.key_system << "' is already registered as a parent"; |
430 #if defined(ENABLE_PEPPER_CDMS) | |
431 DCHECK_EQ(info.use_aes_decryptor, info.pepper_type.empty()); | |
432 #endif | |
433 | |
434 concrete_key_system_map_[info.key_system] = info; | 497 concrete_key_system_map_[info.key_system] = info; |
435 | |
436 if (!info.parent_key_system.empty()) { | 498 if (!info.parent_key_system.empty()) { |
437 DCHECK(!IsConcreteSupportedKeySystem(info.parent_key_system)) | 499 DCHECK(!IsConcreteSupportedKeySystem(info.parent_key_system)) |
438 << "Parent '" << info.parent_key_system << "' " | 500 << "Parent '" << info.parent_key_system << "' " |
439 << "already registered concrete"; | 501 << "already registered concrete"; |
440 DCHECK(!parent_key_system_map_.count(info.parent_key_system)) | 502 DCHECK(!parent_key_system_map_.count(info.parent_key_system)) |
441 << "Parent '" << info.parent_key_system << "' already registered"; | 503 << "Parent '" << info.parent_key_system << "' already registered"; |
442 parent_key_system_map_[info.parent_key_system] = info.key_system; | 504 parent_key_system_map_[info.parent_key_system] = info.key_system; |
443 } | 505 } |
444 } | 506 } |
445 } | 507 } |
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
613 DLOG(FATAL) << concrete_key_system << " is not a known concrete system"; | 675 DLOG(FATAL) << concrete_key_system << " is not a known concrete system"; |
614 return std::string(); | 676 return std::string(); |
615 } | 677 } |
616 | 678 |
617 const std::string& type = key_system_iter->second.pepper_type; | 679 const std::string& type = key_system_iter->second.pepper_type; |
618 DLOG_IF(FATAL, type.empty()) << concrete_key_system << " is not Pepper-based"; | 680 DLOG_IF(FATAL, type.empty()) << concrete_key_system << " is not Pepper-based"; |
619 return type; | 681 return type; |
620 } | 682 } |
621 #endif | 683 #endif |
622 | 684 |
623 bool KeySystems::IsPersistentLicenseSessionSupported( | 685 EmeConfigRule KeySystems::GetRobustnessConfigRule( |
624 const std::string& key_system, | 686 const std::string& key_system, |
625 bool is_permission_granted) { | 687 EmeMediaType media_type, |
| 688 const std::string& requested_robustness) { |
| 689 DCHECK(thread_checker_.CalledOnValidThread()); |
| 690 |
| 691 EmeRobustness robustness = ConvertRobustness(requested_robustness); |
| 692 if (robustness == EmeRobustness::INVALID) |
| 693 return EmeConfigRule::NOT_SUPPORTED; |
| 694 if (robustness == EmeRobustness::EMPTY) |
| 695 return EmeConfigRule::SUPPORTED; |
| 696 |
| 697 KeySystemInfoMap::const_iterator key_system_iter = |
| 698 concrete_key_system_map_.find(key_system); |
| 699 if (key_system_iter == concrete_key_system_map_.end()) { |
| 700 NOTREACHED(); |
| 701 return EmeConfigRule::NOT_SUPPORTED; |
| 702 } |
| 703 |
| 704 EmeRobustness max_robustness = EmeRobustness::INVALID; |
| 705 switch (media_type) { |
| 706 case EmeMediaType::AUDIO: |
| 707 max_robustness = key_system_iter->second.max_audio_robustness; |
| 708 break; |
| 709 case EmeMediaType::VIDEO: |
| 710 max_robustness = key_system_iter->second.max_video_robustness; |
| 711 break; |
| 712 } |
| 713 |
| 714 // We can compare robustness levels whenever they are not HW_SECURE_CRYPTO |
| 715 // and SW_SECURE_DECODE in some order. If they are exactly those two then the |
| 716 // robustness requirement is not supported. |
| 717 if ((max_robustness == EmeRobustness::HW_SECURE_CRYPTO && |
| 718 robustness == EmeRobustness::SW_SECURE_DECODE) || |
| 719 (max_robustness == EmeRobustness::SW_SECURE_DECODE && |
| 720 robustness == EmeRobustness::HW_SECURE_CRYPTO) || |
| 721 robustness > max_robustness) { |
| 722 return EmeConfigRule::NOT_SUPPORTED; |
| 723 } |
| 724 |
| 725 #if defined(OS_CHROMEOS) |
| 726 if (key_system == kWidevineKeySystem) { |
| 727 // Hardware security requires remote attestation. |
| 728 if (robustness >= EmeRobustness::HW_SECURE_CRYPTO) |
| 729 return EmeConfigRule::IDENTIFIER_REQUIRED; |
| 730 |
| 731 // For video, recommend remote attestation if HW_SECURE_ALL is available, |
| 732 // because it enables hardware accelerated decoding. |
| 733 // TODO(sandersd): Only do this when hardware accelerated decoding is |
| 734 // available for the requested codecs. |
| 735 if (media_type == EmeMediaType::VIDEO && |
| 736 max_robustness == EmeRobustness::HW_SECURE_ALL) { |
| 737 return EmeConfigRule::IDENTIFIER_RECOMMENDED; |
| 738 } |
| 739 } |
| 740 #endif // defined(OS_CHROMEOS) |
| 741 |
| 742 return EmeConfigRule::SUPPORTED; |
| 743 } |
| 744 |
| 745 EmeConfigRule KeySystems::GetPersistentLicenseSessionConfigRule( |
| 746 const std::string& key_system) { |
626 DCHECK(thread_checker_.CalledOnValidThread()); | 747 DCHECK(thread_checker_.CalledOnValidThread()); |
627 | 748 |
628 KeySystemInfoMap::const_iterator key_system_iter = | 749 KeySystemInfoMap::const_iterator key_system_iter = |
629 concrete_key_system_map_.find(key_system); | 750 concrete_key_system_map_.find(key_system); |
630 if (key_system_iter == concrete_key_system_map_.end()) { | 751 if (key_system_iter == concrete_key_system_map_.end()) { |
631 NOTREACHED(); | 752 NOTREACHED(); |
632 return false; | 753 return EmeConfigRule::NOT_SUPPORTED; |
633 } | 754 } |
634 | 755 return ConvertSessionTypeSupport( |
635 switch (key_system_iter->second.persistent_license_support) { | 756 key_system_iter->second.persistent_license_support); |
636 case EME_SESSION_TYPE_INVALID: | |
637 NOTREACHED(); | |
638 return false; | |
639 case EME_SESSION_TYPE_NOT_SUPPORTED: | |
640 return false; | |
641 case EME_SESSION_TYPE_SUPPORTED_WITH_PERMISSION: | |
642 return is_permission_granted; | |
643 case EME_SESSION_TYPE_SUPPORTED: | |
644 return true; | |
645 } | |
646 | |
647 NOTREACHED(); | |
648 return false; | |
649 } | 757 } |
650 | 758 |
651 bool KeySystems::IsPersistentReleaseMessageSessionSupported( | 759 EmeConfigRule KeySystems::GetPersistentReleaseMessageSessionConfigRule( |
652 const std::string& key_system, | 760 const std::string& key_system) { |
653 bool is_permission_granted) { | |
654 DCHECK(thread_checker_.CalledOnValidThread()); | 761 DCHECK(thread_checker_.CalledOnValidThread()); |
655 | 762 |
656 KeySystemInfoMap::const_iterator key_system_iter = | 763 KeySystemInfoMap::const_iterator key_system_iter = |
657 concrete_key_system_map_.find(key_system); | 764 concrete_key_system_map_.find(key_system); |
658 if (key_system_iter == concrete_key_system_map_.end()) { | 765 if (key_system_iter == concrete_key_system_map_.end()) { |
659 NOTREACHED(); | 766 NOTREACHED(); |
660 return false; | 767 return EmeConfigRule::NOT_SUPPORTED; |
661 } | 768 } |
662 | 769 return ConvertSessionTypeSupport( |
663 switch (key_system_iter->second.persistent_release_message_support) { | 770 key_system_iter->second.persistent_release_message_support); |
664 case EME_SESSION_TYPE_INVALID: | |
665 NOTREACHED(); | |
666 return false; | |
667 case EME_SESSION_TYPE_NOT_SUPPORTED: | |
668 return false; | |
669 case EME_SESSION_TYPE_SUPPORTED_WITH_PERMISSION: | |
670 return is_permission_granted; | |
671 case EME_SESSION_TYPE_SUPPORTED: | |
672 return true; | |
673 } | |
674 | |
675 NOTREACHED(); | |
676 return false; | |
677 } | 771 } |
678 | 772 |
679 bool KeySystems::IsPersistentStateRequirementSupported( | 773 EmeConfigRule KeySystems::GetPersistentStateConfigRule( |
680 const std::string& key_system, | 774 const std::string& key_system, |
681 EmeFeatureRequirement requirement, | 775 EmeFeatureRequirement requirement) { |
682 bool is_permission_granted) { | |
683 DCHECK(thread_checker_.CalledOnValidThread()); | 776 DCHECK(thread_checker_.CalledOnValidThread()); |
684 | 777 |
685 KeySystemInfoMap::const_iterator key_system_iter = | 778 KeySystemInfoMap::const_iterator key_system_iter = |
686 concrete_key_system_map_.find(key_system); | 779 concrete_key_system_map_.find(key_system); |
687 if (key_system_iter == concrete_key_system_map_.end()) { | 780 if (key_system_iter == concrete_key_system_map_.end()) { |
688 NOTREACHED(); | 781 NOTREACHED(); |
689 return false; | 782 return EmeConfigRule::NOT_SUPPORTED; |
690 } | 783 } |
691 | 784 |
692 switch (key_system_iter->second.persistent_state_support) { | 785 // For NOT_ALLOWED and REQUIRED, the result is as expected. For OPTIONAL, we |
693 case EME_FEATURE_INVALID: | 786 // return the least restrictive of the two rules; this guarantees that if |
694 NOTREACHED(); | 787 // OPTIONAL is accepted, then it can always be resolved to some value. (In |
695 return false; | 788 // fact OPTIONAL is always accepted, because the least restrictive rule is |
696 case EME_FEATURE_NOT_SUPPORTED: | 789 // always SUPPORTED.) |
697 return requirement != EME_FEATURE_REQUIRED; | 790 // |
698 case EME_FEATURE_REQUESTABLE_WITH_PERMISSION: | 791 // Note that even if permission is not required for persistent state, it may |
699 return (requirement != EME_FEATURE_REQUIRED) || is_permission_granted; | 792 // be required for specific persistent session types. |
700 case EME_FEATURE_REQUESTABLE: | 793 // |
701 return true; | 794 // NOT_ALLOWED OPTIONAL REQUIRED |
702 case EME_FEATURE_ALWAYS_ENABLED: | 795 // NOT_SUPPORTED SUPPORTED SUPPORTED NOT_SUPPORTED |
703 // Persistent state does not require user permission, but the session | 796 // REQUESTABLE_WITH_IDENTIFIER SUPPORTED SUPPORTED IDENTIFIER_REQ |
704 // types that use it might. | 797 // REQUESTABLE SUPPORTED SUPPORTED SUPPORTED |
705 return requirement != EME_FEATURE_NOT_ALLOWED; | 798 // ALWAYS_ENABLED NOT_SUPPORTED SUPPORTED SUPPORTED |
| 799 EmeFeatureSupport support = key_system_iter->second.persistent_state_support; |
| 800 if (support == EME_FEATURE_NOT_SUPPORTED && |
| 801 requirement == EME_FEATURE_REQUIRED) { |
| 802 return EmeConfigRule::NOT_SUPPORTED; |
706 } | 803 } |
707 | 804 if (support == EME_FEATURE_ALWAYS_ENABLED && |
708 NOTREACHED(); | 805 requirement == EME_FEATURE_NOT_ALLOWED) { |
709 return false; | 806 return EmeConfigRule::NOT_SUPPORTED; |
| 807 } |
| 808 if (support == EME_FEATURE_REQUESTABLE_WITH_IDENTIFIER && |
| 809 requirement == EME_FEATURE_REQUIRED) { |
| 810 return EmeConfigRule::IDENTIFIER_REQUIRED; |
| 811 } |
| 812 return EmeConfigRule::SUPPORTED; |
710 } | 813 } |
711 | 814 |
712 bool KeySystems::IsDistinctiveIdentifierRequirementSupported( | 815 EmeConfigRule KeySystems::GetDistinctiveIdentifierConfigRule( |
713 const std::string& key_system, | 816 const std::string& key_system, |
714 EmeFeatureRequirement requirement, | 817 EmeFeatureRequirement requirement) { |
715 bool is_permission_granted) { | |
716 DCHECK(thread_checker_.CalledOnValidThread()); | 818 DCHECK(thread_checker_.CalledOnValidThread()); |
717 | 819 |
718 KeySystemInfoMap::const_iterator key_system_iter = | 820 KeySystemInfoMap::const_iterator key_system_iter = |
719 concrete_key_system_map_.find(key_system); | 821 concrete_key_system_map_.find(key_system); |
720 if (key_system_iter == concrete_key_system_map_.end()) { | 822 if (key_system_iter == concrete_key_system_map_.end()) { |
721 NOTREACHED(); | 823 NOTREACHED(); |
722 return false; | 824 return EmeConfigRule::NOT_SUPPORTED; |
723 } | 825 } |
724 | 826 |
725 switch (key_system_iter->second.distinctive_identifier_support) { | 827 // Permission is required for REQUIRED, but not for NOT_ALLOWED. For OPTIONAL, |
726 case EME_FEATURE_INVALID: | 828 // we return the least restrictive of the two rules; this guarantees that if |
727 NOTREACHED(); | 829 // OPTIONAL is accepted, then it can always be resolved to some value. |
728 return false; | 830 // |
729 case EME_FEATURE_NOT_SUPPORTED: | 831 // NOT_ALLOWED OPTIONAL REQUIRED |
730 return requirement != EME_FEATURE_REQUIRED; | 832 // NOT_SUPPORTED SUPPORTED SUPPORTED NOT_SUPPORTED |
731 case EME_FEATURE_REQUESTABLE_WITH_PERMISSION: | 833 // REQUESTABLE_WITH_IDENTIFIER SUPPORTED SUPPORTED IDENTIFIER_REQ |
732 // TODO(sandersd): Remove this hack once crbug.com/457482 and | 834 // ALWAYS_ENABLED NOT_SUPPORTED IDENTIFIER_REQ IDENTIFIER_REQ |
733 // crbug.com/460616 are addressed. | 835 EmeFeatureSupport support = |
734 // We cannot currently enforce "not-allowed", so don't allow it. | 836 key_system_iter->second.distinctive_identifier_support; |
735 // Note: Removing this check will expose crbug.com/460616. | 837 DCHECK(support != EME_FEATURE_REQUESTABLE); |
736 if (requirement == EME_FEATURE_NOT_ALLOWED) | 838 if (support == EME_FEATURE_NOT_SUPPORTED && |
737 return false; | 839 requirement == EME_FEATURE_REQUIRED) { |
738 return (requirement != EME_FEATURE_REQUIRED) || is_permission_granted; | 840 return EmeConfigRule::NOT_SUPPORTED; |
739 case EME_FEATURE_REQUESTABLE: | |
740 NOTREACHED(); | |
741 return true; | |
742 case EME_FEATURE_ALWAYS_ENABLED: | |
743 // Distinctive identifiers always require user permission. | |
744 return (requirement != EME_FEATURE_NOT_ALLOWED) && is_permission_granted; | |
745 } | 841 } |
746 | 842 if (support == EME_FEATURE_ALWAYS_ENABLED && |
747 NOTREACHED(); | 843 requirement == EME_FEATURE_NOT_ALLOWED) { |
748 return false; | 844 return EmeConfigRule::NOT_SUPPORTED; |
| 845 } |
| 846 if (support == EME_FEATURE_ALWAYS_ENABLED || |
| 847 requirement == EME_FEATURE_REQUIRED) { |
| 848 return EmeConfigRule::IDENTIFIER_REQUIRED; |
| 849 } |
| 850 return EmeConfigRule::SUPPORTED; |
749 } | 851 } |
750 | 852 |
751 void KeySystems::AddContainerMask(const std::string& container, uint32 mask) { | 853 void KeySystems::AddContainerMask(const std::string& container, uint32 mask) { |
752 DCHECK(thread_checker_.CalledOnValidThread()); | 854 DCHECK(thread_checker_.CalledOnValidThread()); |
753 DCHECK(!container_to_codec_mask_map_.count(container)); | 855 DCHECK(!container_to_codec_mask_map_.count(container)); |
754 container_to_codec_mask_map_[container] = static_cast<EmeCodec>(mask); | 856 container_to_codec_mask_map_[container] = static_cast<EmeCodec>(mask); |
755 } | 857 } |
756 | 858 |
757 void KeySystems::AddCodecMask(const std::string& codec, uint32 mask) { | 859 void KeySystems::AddCodecMask(const std::string& codec, uint32 mask) { |
758 DCHECK(thread_checker_.CalledOnValidThread()); | 860 DCHECK(thread_checker_.CalledOnValidThread()); |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
843 bool CanUseAesDecryptor(const std::string& concrete_key_system) { | 945 bool CanUseAesDecryptor(const std::string& concrete_key_system) { |
844 return KeySystems::GetInstance().UseAesDecryptor(concrete_key_system); | 946 return KeySystems::GetInstance().UseAesDecryptor(concrete_key_system); |
845 } | 947 } |
846 | 948 |
847 #if defined(ENABLE_PEPPER_CDMS) | 949 #if defined(ENABLE_PEPPER_CDMS) |
848 std::string GetPepperType(const std::string& concrete_key_system) { | 950 std::string GetPepperType(const std::string& concrete_key_system) { |
849 return KeySystems::GetInstance().GetPepperType(concrete_key_system); | 951 return KeySystems::GetInstance().GetPepperType(concrete_key_system); |
850 } | 952 } |
851 #endif | 953 #endif |
852 | 954 |
853 bool IsPersistentLicenseSessionSupported( | 955 EmeConfigRule GetRobustnessConfigRule( |
854 const std::string& key_system, | 956 const std::string& key_system, |
855 bool is_permission_granted) { | 957 EmeMediaType media_type, |
856 return KeySystems::GetInstance().IsPersistentLicenseSessionSupported( | 958 const std::string& robustness) { |
857 key_system, is_permission_granted); | 959 return KeySystems::GetInstance().GetRobustnessConfigRule( |
| 960 key_system, media_type, robustness); |
858 } | 961 } |
859 | 962 |
860 bool IsPersistentReleaseMessageSessionSupported( | 963 EmeConfigRule GetPersistentLicenseSessionConfigRule( |
861 const std::string& key_system, | 964 const std::string& key_system) { |
862 bool is_permission_granted) { | 965 return KeySystems::GetInstance().GetPersistentLicenseSessionConfigRule( |
863 return KeySystems::GetInstance().IsPersistentReleaseMessageSessionSupported( | 966 key_system); |
864 key_system, is_permission_granted); | |
865 } | 967 } |
866 | 968 |
867 bool IsPersistentStateRequirementSupported( | 969 EmeConfigRule GetPersistentReleaseMessageSessionConfigRule( |
868 const std::string& key_system, | 970 const std::string& key_system) { |
869 EmeFeatureRequirement requirement, | 971 return KeySystems::GetInstance().GetPersistentReleaseMessageSessionConfigRule( |
870 bool is_permission_granted) { | 972 key_system); |
871 return KeySystems::GetInstance().IsPersistentStateRequirementSupported( | |
872 key_system, requirement, is_permission_granted); | |
873 } | 973 } |
874 | 974 |
875 bool IsDistinctiveIdentifierRequirementSupported( | 975 EmeConfigRule GetPersistentStateConfigRule( |
876 const std::string& key_system, | 976 const std::string& key_system, |
877 EmeFeatureRequirement requirement, | 977 EmeFeatureRequirement requirement) { |
878 bool is_permission_granted) { | 978 return KeySystems::GetInstance().GetPersistentStateConfigRule( |
879 return KeySystems::GetInstance().IsDistinctiveIdentifierRequirementSupported( | 979 key_system, requirement); |
880 key_system, requirement, is_permission_granted); | 980 } |
| 981 |
| 982 EmeConfigRule GetDistinctiveIdentifierConfigRule( |
| 983 const std::string& key_system, |
| 984 EmeFeatureRequirement requirement) { |
| 985 return KeySystems::GetInstance().GetDistinctiveIdentifierConfigRule( |
| 986 key_system, requirement); |
881 } | 987 } |
882 | 988 |
883 // These two functions are for testing purpose only. The declaration in the | 989 // These two functions are for testing purpose only. The declaration in the |
884 // header file is guarded by "#if defined(UNIT_TEST)" so that they can be used | 990 // header file is guarded by "#if defined(UNIT_TEST)" so that they can be used |
885 // by tests but not non-test code. However, this .cc file is compiled as part of | 991 // by tests but not non-test code. However, this .cc file is compiled as part of |
886 // "media" where "UNIT_TEST" is not defined. So we need to specify | 992 // "media" where "UNIT_TEST" is not defined. So we need to specify |
887 // "MEDIA_EXPORT" here again so that they are visible to tests. | 993 // "MEDIA_EXPORT" here again so that they are visible to tests. |
888 | 994 |
889 MEDIA_EXPORT void AddContainerMask(const std::string& container, uint32 mask) { | 995 MEDIA_EXPORT void AddContainerMask(const std::string& container, uint32 mask) { |
890 KeySystems::GetInstance().AddContainerMask(container, mask); | 996 KeySystems::GetInstance().AddContainerMask(container, mask); |
891 } | 997 } |
892 | 998 |
893 MEDIA_EXPORT void AddCodecMask(const std::string& codec, uint32 mask) { | 999 MEDIA_EXPORT void AddCodecMask(const std::string& codec, uint32 mask) { |
894 KeySystems::GetInstance().AddCodecMask(codec, mask); | 1000 KeySystems::GetInstance().AddCodecMask(codec, mask); |
895 } | 1001 } |
896 | 1002 |
897 } // namespace media | 1003 } // namespace media |
OLD | NEW |