| 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 |