diff --git a/chrome/renderer/media/chrome_key_systems.cc b/chrome/renderer/media/chrome_key_systems.cc index 537faefe4b2714..c0cf00b5da0585 100644 --- a/chrome/renderer/media/chrome_key_systems.cc +++ b/chrome/renderer/media/chrome_key_systems.cc @@ -243,7 +243,7 @@ static void AddWidevine( using Robustness = cdm::WidevineKeySystemProperties::Robustness; concrete_key_systems->emplace_back(new cdm::WidevineKeySystemProperties( - supported_codecs, + supported_encryption_schemes, supported_codecs, #if defined(OS_CHROMEOS) Robustness::HW_SECURE_ALL, // Maximum audio robustness. Robustness::HW_SECURE_ALL, // Maximum video robustness. diff --git a/chrome/renderer/media/chrome_key_systems_provider_unittest.cc b/chrome/renderer/media/chrome_key_systems_provider_unittest.cc index eac8034316c401..71eb3d90992851 100644 --- a/chrome/renderer/media/chrome_key_systems_provider_unittest.cc +++ b/chrome/renderer/media/chrome_key_systems_provider_unittest.cc @@ -27,6 +27,10 @@ class TestKeySystemProperties : public media::KeySystemProperties { media::EmeInitDataType init_data_type) const override { return false; } + bool IsEncryptionSchemeSupported( + media::EncryptionMode encryption_scheme) const override { + return false; + } media::SupportedCodecs GetSupportedCodecs() const override { return media::EME_CODEC_NONE; } diff --git a/components/cdm/renderer/android_key_systems.cc b/components/cdm/renderer/android_key_systems.cc index 183a3f5fb71ec1..6eaa2ba963d56a 100644 --- a/components/cdm/renderer/android_key_systems.cc +++ b/components/cdm/renderer/android_key_systems.cc @@ -57,6 +57,11 @@ class AndroidPlatformKeySystemProperties : public KeySystemProperties { return false; } + bool IsEncryptionSchemeSupported( + media::EncryptionMode encryption_scheme) const override { + return encryption_scheme == media::EncryptionMode::kCenc; + } + SupportedCodecs GetSupportedCodecs() const override { return supported_codecs_; } @@ -122,7 +127,14 @@ void AddAndroidWidevine( if (response.non_secure_codecs != media::EME_CODEC_NONE) { DVLOG(3) << __func__ << " Widevine supported."; + + // TODO(crbug.com/813845): Determine 'cbcs' support, which may vary by + // Android version. + base::flat_set supported_encryption_schemes = { + media::EncryptionMode::kCenc}; + concrete_key_systems->emplace_back(new WidevineKeySystemProperties( + supported_encryption_schemes, // Encryption schemes. response.non_secure_codecs, // Regular codecs. response.secure_codecs, // Hardware-secure codecs. Robustness::HW_SECURE_CRYPTO, // Max audio robustness. diff --git a/components/cdm/renderer/external_clear_key_key_system_properties.cc b/components/cdm/renderer/external_clear_key_key_system_properties.cc index 726daa135621e8..828d628acebc1d 100644 --- a/components/cdm/renderer/external_clear_key_key_system_properties.cc +++ b/components/cdm/renderer/external_clear_key_key_system_properties.cc @@ -34,6 +34,19 @@ bool ExternalClearKeyProperties::IsSupportedInitDataType( return false; } +bool ExternalClearKeyProperties::IsEncryptionSchemeSupported( + media::EncryptionMode encryption_scheme) const { + switch (encryption_scheme) { + case media::EncryptionMode::kCenc: + case media::EncryptionMode::kCbcs: + return true; + case media::EncryptionMode::kUnencrypted: + break; + } + NOTREACHED(); + return false; +} + media::SupportedCodecs ExternalClearKeyProperties::GetSupportedCodecs() const { return media::EME_CODEC_MP4_ALL | media::EME_CODEC_WEBM_ALL; } diff --git a/components/cdm/renderer/external_clear_key_key_system_properties.h b/components/cdm/renderer/external_clear_key_key_system_properties.h index f08967a61d7612..224f22d4f6e37d 100644 --- a/components/cdm/renderer/external_clear_key_key_system_properties.h +++ b/components/cdm/renderer/external_clear_key_key_system_properties.h @@ -22,6 +22,8 @@ class ExternalClearKeyProperties : public media::KeySystemProperties { std::string GetKeySystemName() const override; bool IsSupportedInitDataType( media::EmeInitDataType init_data_type) const override; + bool IsEncryptionSchemeSupported( + media::EncryptionMode encryption_scheme) const override; media::SupportedCodecs GetSupportedCodecs() const override; media::EmeConfigRule GetRobustnessConfigRule( media::EmeMediaType media_type, diff --git a/components/cdm/renderer/widevine_key_system_properties.cc b/components/cdm/renderer/widevine_key_system_properties.cc index b47bfc7ec08c95..60f4bb07d9c04a 100644 --- a/components/cdm/renderer/widevine_key_system_properties.cc +++ b/components/cdm/renderer/widevine_key_system_properties.cc @@ -38,6 +38,7 @@ Robustness ConvertRobustness(const std::string& robustness) { } // namespace WidevineKeySystemProperties::WidevineKeySystemProperties( + base::flat_set supported_encryption_schemes, media::SupportedCodecs supported_codecs, #if defined(OS_ANDROID) media::SupportedCodecs supported_secure_codecs, @@ -48,7 +49,8 @@ WidevineKeySystemProperties::WidevineKeySystemProperties( media::EmeSessionTypeSupport persistent_release_message_support, media::EmeFeatureSupport persistent_state_support, media::EmeFeatureSupport distinctive_identifier_support) - : supported_codecs_(supported_codecs), + : supported_encryption_schemes_(std::move(supported_encryption_schemes)), + supported_codecs_(supported_codecs), #if defined(OS_ANDROID) supported_secure_codecs_(supported_secure_codecs), #endif // defined(OS_ANDROID) @@ -60,6 +62,8 @@ WidevineKeySystemProperties::WidevineKeySystemProperties( distinctive_identifier_support_(distinctive_identifier_support) { } +WidevineKeySystemProperties::~WidevineKeySystemProperties() = default; + std::string WidevineKeySystemProperties::GetKeySystemName() const { return kWidevineKeySystem; } @@ -77,6 +81,11 @@ bool WidevineKeySystemProperties::IsSupportedInitDataType( return false; } +bool WidevineKeySystemProperties::IsEncryptionSchemeSupported( + media::EncryptionMode encryption_scheme) const { + return supported_encryption_schemes_.count(encryption_scheme) != 0; +} + SupportedCodecs WidevineKeySystemProperties::GetSupportedCodecs() const { return supported_codecs_; } diff --git a/components/cdm/renderer/widevine_key_system_properties.h b/components/cdm/renderer/widevine_key_system_properties.h index 3567cbdae0da1c..05b88a659d0816 100644 --- a/components/cdm/renderer/widevine_key_system_properties.h +++ b/components/cdm/renderer/widevine_key_system_properties.h @@ -5,6 +5,10 @@ #ifndef COMPONENTS_CDM_RENDERER_WIDEVINE_KEY_SYSTEM_PROPERTIES_H_ #define COMPONENTS_CDM_RENDERER_WIDEVINE_KEY_SYSTEM_PROPERTIES_H_ +#include +#include + +#include "base/containers/flat_set.h" #include "build/build_config.h" #include "media/base/key_system_properties.h" @@ -26,6 +30,7 @@ class WidevineKeySystemProperties : public media::KeySystemProperties { }; WidevineKeySystemProperties( + base::flat_set supported_encryption_schemes, media::SupportedCodecs supported_codecs, #if defined(OS_ANDROID) media::SupportedCodecs supported_secure_codecs, @@ -36,10 +41,13 @@ class WidevineKeySystemProperties : public media::KeySystemProperties { media::EmeSessionTypeSupport persistent_release_message_support, media::EmeFeatureSupport persistent_state_support, media::EmeFeatureSupport distinctive_identifier_support); + ~WidevineKeySystemProperties() override; std::string GetKeySystemName() const override; bool IsSupportedInitDataType( media::EmeInitDataType init_data_type) const override; + bool IsEncryptionSchemeSupported( + media::EncryptionMode encryption_scheme) const override; media::SupportedCodecs GetSupportedCodecs() const override; #if defined(OS_ANDROID) @@ -57,6 +65,7 @@ class WidevineKeySystemProperties : public media::KeySystemProperties { media::EmeFeatureSupport GetDistinctiveIdentifierSupport() const override; private: + const base::flat_set supported_encryption_schemes_; const media::SupportedCodecs supported_codecs_; #if defined(OS_ANDROID) const media::SupportedCodecs supported_secure_codecs_; diff --git a/media/base/key_system_properties.h b/media/base/key_system_properties.h index 16d089159b3ab5..33d2d52de3d679 100644 --- a/media/base/key_system_properties.h +++ b/media/base/key_system_properties.h @@ -8,6 +8,7 @@ #include #include "build/build_config.h" +#include "media/base/decrypt_config.h" #include "media/base/eme_constants.h" #include "media/base/media_export.h" @@ -25,6 +26,10 @@ class MEDIA_EXPORT KeySystemProperties { virtual bool IsSupportedInitDataType( EmeInitDataType init_data_type) const = 0; + // Returns whether |encryption_scheme| is supported by this key system. + virtual bool IsEncryptionSchemeSupported( + EncryptionMode encryption_scheme) const = 0; + // Returns the codecs supported by this key system. virtual SupportedCodecs GetSupportedCodecs() const = 0; diff --git a/media/base/key_systems.cc b/media/base/key_systems.cc index f676d61f59202c..a51a28df388bc7 100644 --- a/media/base/key_systems.cc +++ b/media/base/key_systems.cc @@ -102,6 +102,19 @@ class ClearKeyProperties : public KeySystemProperties { init_data_type == EmeInitDataType::KEYIDS; } + bool IsEncryptionSchemeSupported( + EncryptionMode encryption_scheme) const override { + switch (encryption_scheme) { + case EncryptionMode::kCenc: + case EncryptionMode::kCbcs: + return true; + case EncryptionMode::kUnencrypted: + break; + } + NOTREACHED(); + return false; + } + SupportedCodecs GetSupportedCodecs() const override { // On Android, Vorbis, VP8, AAC and AVC1 are supported in MediaCodec: // http://developer.android.com/guide/appendix/media-formats.html @@ -201,6 +214,10 @@ class KeySystemsImpl : public KeySystems { bool IsSupportedInitDataType(const std::string& key_system, EmeInitDataType init_data_type) const override; + bool IsEncryptionSchemeSupported( + const std::string& key_system, + EncryptionMode encryption_scheme) const override; + EmeConfigRule GetContentTypeConfigRule( const std::string& key_system, EmeMediaType media_type, @@ -483,6 +500,21 @@ bool KeySystemsImpl::IsSupportedInitDataType( return key_system_iter->second->IsSupportedInitDataType(init_data_type); } +bool KeySystemsImpl::IsEncryptionSchemeSupported( + const std::string& key_system, + EncryptionMode encryption_scheme) const { + DCHECK(thread_checker_.CalledOnValidThread()); + + KeySystemPropertiesMap::const_iterator key_system_iter = + key_system_properties_map_.find(key_system); + if (key_system_iter == key_system_properties_map_.end()) { + NOTREACHED(); + return false; + } + return key_system_iter->second->IsEncryptionSchemeSupported( + encryption_scheme); +} + std::string KeySystemsImpl::GetKeySystemNameForUMA( const std::string& key_system) const { DCHECK(thread_checker_.CalledOnValidThread()); diff --git a/media/base/key_systems.h b/media/base/key_systems.h index 6d885336a81ca7..a99e45b2c98efd 100644 --- a/media/base/key_systems.h +++ b/media/base/key_systems.h @@ -10,6 +10,7 @@ #include #include +#include "media/base/decrypt_config.h" #include "media/base/eme_constants.h" #include "media/base/media_export.h" #include "media/media_buildflags.h" @@ -35,6 +36,11 @@ class MEDIA_EXPORT KeySystems { const std::string& key_system, EmeInitDataType init_data_type) const = 0; + // Returns whether |encryption_scheme| is supported by |key_system|. + virtual bool IsEncryptionSchemeSupported( + const std::string& key_system, + EncryptionMode encryption_scheme) const = 0; + // Returns the configuration rule for supporting a container and list of // codecs. virtual EmeConfigRule GetContentTypeConfigRule( diff --git a/media/base/key_systems_unittest.cc b/media/base/key_systems_unittest.cc index a291c82f7a4c0b..19aaa27790689e 100644 --- a/media/base/key_systems_unittest.cc +++ b/media/base/key_systems_unittest.cc @@ -13,6 +13,7 @@ #include #include "base/logging.h" +#include "media/base/decrypt_config.h" #include "media/base/eme_constants.h" #include "media/base/key_systems.h" #include "media/base/media.h" @@ -84,6 +85,12 @@ class AesKeySystemProperties : public TestKeySystemPropertiesBase { std::string GetKeySystemName() const override { return name_; } + bool IsEncryptionSchemeSupported( + EncryptionMode encryption_scheme) const override { + return encryption_scheme == EncryptionMode::kUnencrypted || + encryption_scheme == EncryptionMode::kCenc; + } + EmeSessionTypeSupport GetPersistentLicenseSessionSupport() const override { return EmeSessionTypeSupport::NOT_SUPPORTED; } @@ -106,6 +113,11 @@ class ExternalKeySystemProperties : public TestKeySystemPropertiesBase { public: std::string GetKeySystemName() const override { return kExternal; } + bool IsEncryptionSchemeSupported( + EncryptionMode encryption_scheme) const override { + return encryption_scheme != EncryptionMode::kUnencrypted; + } + #if defined(OS_ANDROID) // We have hw-secure FOO_VIDEO codec support. SupportedCodecs GetSupportedSecureCodecs() const override { @@ -140,6 +152,12 @@ class ExternalKeySystemProperties : public TestKeySystemPropertiesBase { } }; +static bool IsEncryptionSchemeSupported(const std::string& key_system, + EncryptionMode encryption_scheme) { + return KeySystems::GetInstance()->IsEncryptionSchemeSupported( + key_system, encryption_scheme); +} + static EmeConfigRule GetVideoContentTypeConfigRule( const std::string& mime_type, const std::vector& codecs, @@ -570,6 +588,14 @@ TEST_F(KeySystemsTest, kAudioFoo, vorbis_codec(), kUsesAes)); } +TEST_F(KeySystemsTest, + IsSupportedKeySystem_UsesAesDecryptor_EncryptionSchemes) { + EXPECT_TRUE( + IsEncryptionSchemeSupported(kUsesAes, EncryptionMode::kUnencrypted)); + EXPECT_TRUE(IsEncryptionSchemeSupported(kUsesAes, EncryptionMode::kCenc)); + EXPECT_FALSE(IsEncryptionSchemeSupported(kUsesAes, EncryptionMode::kCbcs)); +} + // // Non-AesDecryptor-based key system. // @@ -692,6 +718,17 @@ TEST_F( kAudioFoo, vorbis_codec(), kExternal)); } +TEST_F(KeySystemsTest, + IsSupportedKeySystem_ExternalDecryptor_EncryptionSchemes) { + if (!CanRunExternalKeySystemTests()) + return; + + EXPECT_FALSE( + IsEncryptionSchemeSupported(kExternal, EncryptionMode::kUnencrypted)); + EXPECT_TRUE(IsEncryptionSchemeSupported(kExternal, EncryptionMode::kCenc)); + EXPECT_TRUE(IsEncryptionSchemeSupported(kExternal, EncryptionMode::kCbcs)); +} + TEST_F(KeySystemsTest, KeySystemNameForUMA) { EXPECT_EQ("ClearKey", GetKeySystemNameForUMA(kClearKey)); EXPECT_EQ("Widevine", GetKeySystemNameForUMA(kWidevineKeySystem)); diff --git a/media/blink/key_system_config_selector_unittest.cc b/media/blink/key_system_config_selector_unittest.cc index f1dbf56b825c25..25d2be09bf93f4 100644 --- a/media/blink/key_system_config_selector_unittest.cc +++ b/media/blink/key_system_config_selector_unittest.cc @@ -103,6 +103,14 @@ class FakeKeySystems : public KeySystems { return false; } + bool IsEncryptionSchemeSupported( + const std::string& key_system, + EncryptionMode encryption_scheme) const override { + // TODO(crbug.com/658026): Implement this once value passed from blink. + NOTREACHED(); + return false; + } + // TODO(sandersd): Secure codec simulation. EmeConfigRule GetContentTypeConfigRule( const std::string& key_system,