| // Copyright 2013 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| // TODO(sandersd): Refactor to remove recomputed codec arrays, and generally |
| // shorten and improve coverage. |
| // - http://crbug.com/417444 |
| // - http://crbug.com/457438 |
| // TODO(sandersd): Add tests to cover codec vectors with empty items. |
| // http://crbug.com/417461 |
| |
| #include <string> |
| #include <vector> |
| |
| #include "base/check.h" |
| #include "base/notreached.h" |
| #include "build/build_config.h" |
| #include "media/base/audio_parameters.h" |
| #include "media/base/decrypt_config.h" |
| #include "media/base/eme_constants.h" |
| #include "media/base/key_systems.h" |
| #include "media/base/media.h" |
| #include "media/base/media_client.h" |
| #include "media/media_buildflags.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| #include "third_party/widevine/cdm/widevine_cdm_common.h" |
| |
| namespace media { |
| |
| namespace { |
| |
| // These are the (fake) key systems that are registered for these tests. |
| // kUsesAes uses the AesDecryptor like Clear Key. |
| // kExternal uses an external CDM, such as library CDM or Android platform CDM. |
| const char kUsesAes[] = "x-org.example.usesaes"; |
| const char kExternal[] = "x-com.example.external"; |
| |
| const char kClearKey[] = "org.w3.clearkey"; |
| const char kExternalClearKey[] = "org.chromium.externalclearkey"; |
| |
| const char kAudioWebM[] = "audio/webm"; |
| const char kVideoWebM[] = "video/webm"; |
| const char kAudioFoo[] = "audio/foo"; |
| const char kVideoFoo[] = "video/foo"; |
| |
| const char kRobustnessSupported[] = "supported"; |
| const char kRobustnessSecureCodecsRequired[] = "secure-codecs-required"; |
| const char kRobustnessNotSupported[] = "not-supported"; |
| |
| // Codecs only supported in FOO container. Pick some arbitrary bit fields as |
| // long as they are not in conflict with the real ones (static_asserted below). |
| // TODO(crbug.com/724362): Remove container type (FOO) from codec enums. |
| enum TestCodec : uint32_t { |
| TEST_CODEC_FOO_AUDIO = 1 << 25, |
| TEST_CODEC_FOO_AUDIO_ALL = TEST_CODEC_FOO_AUDIO, |
| TEST_CODEC_FOO_VIDEO = 1 << 26, |
| // Only supported by hardware secure codec in kExternal key system. |
| TEST_CODEC_FOO_SECURE_VIDEO = 1 << 27, |
| TEST_CODEC_FOO_VIDEO_ALL = TEST_CODEC_FOO_VIDEO | TEST_CODEC_FOO_SECURE_VIDEO, |
| TEST_CODEC_FOO_ALL = TEST_CODEC_FOO_AUDIO_ALL | TEST_CODEC_FOO_VIDEO_ALL |
| }; |
| |
| static_assert((TEST_CODEC_FOO_ALL & EME_CODEC_ALL) == EME_CODEC_NONE, |
| "test codec masks should only use invalid codec masks"); |
| |
| // Base class to provide default implementations. |
| class TestKeySystemPropertiesBase : public KeySystemProperties { |
| public: |
| bool IsSupportedInitDataType(EmeInitDataType init_data_type) const override { |
| return init_data_type == EmeInitDataType::WEBM; |
| } |
| |
| // Note: TEST_CODEC_FOO_SECURE_VIDEO is not supported by default. |
| SupportedCodecs GetSupportedCodecs() const override { |
| return EME_CODEC_WEBM_ALL | TEST_CODEC_FOO_AUDIO | TEST_CODEC_FOO_VIDEO; |
| } |
| |
| EmeConfigRule GetRobustnessConfigRule( |
| EmeMediaType media_type, |
| const std::string& requested_robustness, |
| const bool* /*hw_secure_requirement*/) const override { |
| return requested_robustness.empty() ? EmeConfigRule::SUPPORTED |
| : EmeConfigRule::NOT_SUPPORTED; |
| } |
| }; |
| |
| class AesKeySystemProperties : public TestKeySystemPropertiesBase { |
| public: |
| AesKeySystemProperties(const std::string& name) : name_(name) {} |
| |
| std::string GetKeySystemName() const override { return name_; } |
| |
| EmeConfigRule GetEncryptionSchemeConfigRule( |
| EncryptionScheme encryption_scheme) const override { |
| return (encryption_scheme == EncryptionScheme::kUnencrypted || |
| encryption_scheme == EncryptionScheme::kCenc) |
| ? EmeConfigRule::SUPPORTED |
| : EmeConfigRule::NOT_SUPPORTED; |
| } |
| |
| EmeSessionTypeSupport GetPersistentLicenseSessionSupport() const override { |
| return EmeSessionTypeSupport::NOT_SUPPORTED; |
| } |
| |
| EmeFeatureSupport GetPersistentStateSupport() const override { |
| return EmeFeatureSupport::NOT_SUPPORTED; |
| } |
| |
| EmeFeatureSupport GetDistinctiveIdentifierSupport() const override { |
| return EmeFeatureSupport::NOT_SUPPORTED; |
| } |
| |
| bool UseAesDecryptor() const override { return true; } |
| |
| private: |
| std::string name_; |
| }; |
| |
| class ExternalKeySystemProperties : public TestKeySystemPropertiesBase { |
| public: |
| std::string GetKeySystemName() const override { return kExternal; } |
| |
| // Pretend clear (unencrypted) and 'cenc' content are always supported. But |
| // 'cbcs' is not supported by hardware secure codecs. |
| EmeConfigRule GetEncryptionSchemeConfigRule( |
| EncryptionScheme encryption_scheme) const override { |
| switch (encryption_scheme) { |
| case media::EncryptionScheme::kUnencrypted: |
| case media::EncryptionScheme::kCenc: |
| return media::EmeConfigRule::SUPPORTED; |
| case media::EncryptionScheme::kCbcs: |
| return media::EmeConfigRule::HW_SECURE_CODECS_NOT_ALLOWED; |
| } |
| NOTREACHED(); |
| return media::EmeConfigRule::NOT_SUPPORTED; |
| } |
| |
| // We have hardware secure codec support for FOO_VIDEO and FOO_SECURE_VIDEO. |
| SupportedCodecs GetSupportedHwSecureCodecs() const override { |
| return TEST_CODEC_FOO_VIDEO | TEST_CODEC_FOO_SECURE_VIDEO; |
| } |
| |
| EmeConfigRule GetRobustnessConfigRule( |
| EmeMediaType media_type, |
| const std::string& requested_robustness, |
| const bool* /*hw_secure_requirement*/) const override { |
| if (requested_robustness == kRobustnessSupported) |
| return EmeConfigRule::SUPPORTED; |
| else if (requested_robustness == kRobustnessSecureCodecsRequired) |
| return EmeConfigRule::HW_SECURE_CODECS_REQUIRED; |
| else if (requested_robustness == kRobustnessNotSupported) |
| return EmeConfigRule::NOT_SUPPORTED; |
| else |
| NOTREACHED(); |
| return EmeConfigRule::NOT_SUPPORTED; |
| } |
| |
| EmeSessionTypeSupport GetPersistentLicenseSessionSupport() const override { |
| return EmeSessionTypeSupport::SUPPORTED; |
| } |
| |
| EmeFeatureSupport GetPersistentStateSupport() const override { |
| return EmeFeatureSupport::ALWAYS_ENABLED; |
| } |
| |
| EmeFeatureSupport GetDistinctiveIdentifierSupport() const override { |
| return EmeFeatureSupport::ALWAYS_ENABLED; |
| } |
| }; |
| |
| void ExpectEncryptionSchemeConfigRule(const std::string& key_system, |
| EncryptionScheme encryption_scheme, |
| EmeConfigRule expected_rule) { |
| EXPECT_EQ(expected_rule, |
| KeySystems::GetInstance()->GetEncryptionSchemeConfigRule( |
| key_system, encryption_scheme)); |
| } |
| |
| EmeConfigRule GetVideoContentTypeConfigRule( |
| const std::string& mime_type, |
| const std::vector<std::string>& codecs, |
| const std::string& key_system) { |
| return KeySystems::GetInstance()->GetContentTypeConfigRule( |
| key_system, EmeMediaType::VIDEO, mime_type, codecs); |
| } |
| |
| // Adapt IsSupportedKeySystemWithMediaMimeType() to the new API, |
| // IsSupportedCodecCombination(). |
| bool IsSupportedKeySystemWithMediaMimeType( |
| const std::string& mime_type, |
| const std::vector<std::string>& codecs, |
| const std::string& key_system) { |
| return (GetVideoContentTypeConfigRule(mime_type, codecs, key_system) != |
| EmeConfigRule::NOT_SUPPORTED); |
| } |
| |
| bool IsSupportedKeySystemWithAudioMimeType( |
| const std::string& mime_type, |
| const std::vector<std::string>& codecs, |
| const std::string& key_system) { |
| return (KeySystems::GetInstance()->GetContentTypeConfigRule( |
| key_system, EmeMediaType::AUDIO, mime_type, codecs) != |
| EmeConfigRule::NOT_SUPPORTED); |
| } |
| |
| bool IsSupportedKeySystem(const std::string& key_system) { |
| return KeySystems::GetInstance()->IsSupportedKeySystem(key_system); |
| } |
| |
| EmeConfigRule GetRobustnessConfigRule(const std::string& requested_robustness) { |
| return KeySystems::GetInstance()->GetRobustnessConfigRule( |
| kExternal, EmeMediaType::VIDEO, requested_robustness, nullptr); |
| } |
| |
| // Adds test container and codec masks. |
| // This function must be called after SetMediaClient() if a MediaClient will be |
| // provided. |
| // More details: AddXxxMask() will create KeySystems if it hasn't been created. |
| // During KeySystems's construction GetMediaClient() will be used to add key |
| // systems. In test code, the MediaClient is set by SetMediaClient(). |
| // Therefore, SetMediaClient() must be called before this function to make sure |
| // MediaClient in effect when constructing KeySystems. |
| void AddContainerAndCodecMasksForTest() { |
| // Since KeySystems is a singleton. Make sure we only add test container and |
| // codec masks once per process. |
| static bool is_test_masks_added = false; |
| |
| if (is_test_masks_added) |
| return; |
| |
| AddCodecMaskForTesting(EmeMediaType::AUDIO, "fooaudio", TEST_CODEC_FOO_AUDIO); |
| AddCodecMaskForTesting(EmeMediaType::VIDEO, "foovideo", TEST_CODEC_FOO_VIDEO); |
| AddCodecMaskForTesting(EmeMediaType::VIDEO, "securefoovideo", |
| TEST_CODEC_FOO_SECURE_VIDEO); |
| AddMimeTypeCodecMaskForTesting("audio/foo", TEST_CODEC_FOO_AUDIO_ALL); |
| AddMimeTypeCodecMaskForTesting("video/foo", TEST_CODEC_FOO_VIDEO_ALL); |
| |
| is_test_masks_added = true; |
| } |
| |
| bool CanRunExternalKeySystemTests() { |
| #if defined(OS_ANDROID) |
| if (HasPlatformDecoderSupport()) |
| return true; |
| |
| EXPECT_FALSE(IsSupportedKeySystem(kExternal)); |
| return false; |
| #else |
| return true; |
| #endif |
| } |
| |
| class TestMediaClient : public MediaClient { |
| public: |
| TestMediaClient(); |
| ~TestMediaClient() override; |
| |
| // MediaClient implementation. |
| bool IsKeySystemsUpdateNeeded() final; |
| void AddSupportedKeySystems(std::vector<std::unique_ptr<KeySystemProperties>>* |
| key_systems_properties) override; |
| bool IsSupportedAudioType(const media::AudioType& type) final; |
| bool IsSupportedVideoType(const media::VideoType& type) final; |
| bool IsSupportedBitstreamAudioCodec(AudioCodec codec) final; |
| |
| // Helper function to test the case where IsKeySystemsUpdateNeeded() is true |
| // after AddSupportedKeySystems() is called. |
| void SetKeySystemsUpdateNeeded(); |
| |
| // Helper function to disable "kExternal" key system support so that we can |
| // test the key system update case. |
| void DisableExternalKeySystemSupport(); |
| |
| absl::optional<::media::AudioRendererAlgorithmParameters> |
| GetAudioRendererAlgorithmParameters(AudioParameters audio_parameters) final; |
| |
| private: |
| bool is_update_needed_; |
| bool supports_external_key_system_; |
| }; |
| |
| TestMediaClient::TestMediaClient() |
| : is_update_needed_(true), supports_external_key_system_(true) {} |
| |
| TestMediaClient::~TestMediaClient() = default; |
| |
| bool TestMediaClient::IsKeySystemsUpdateNeeded() { |
| return is_update_needed_; |
| } |
| |
| void TestMediaClient::AddSupportedKeySystems( |
| std::vector<std::unique_ptr<KeySystemProperties>>* key_systems) { |
| DCHECK(is_update_needed_); |
| |
| key_systems->emplace_back(new AesKeySystemProperties(kUsesAes)); |
| |
| if (supports_external_key_system_) |
| key_systems->emplace_back(new ExternalKeySystemProperties()); |
| |
| is_update_needed_ = false; |
| } |
| |
| bool TestMediaClient::IsSupportedAudioType(const media::AudioType& type) { |
| return true; |
| } |
| |
| bool TestMediaClient::IsSupportedVideoType(const media::VideoType& type) { |
| return true; |
| } |
| |
| bool TestMediaClient::IsSupportedBitstreamAudioCodec(AudioCodec codec) { |
| return false; |
| } |
| |
| void TestMediaClient::SetKeySystemsUpdateNeeded() { |
| is_update_needed_ = true; |
| } |
| |
| void TestMediaClient::DisableExternalKeySystemSupport() { |
| supports_external_key_system_ = false; |
| } |
| |
| absl::optional<::media::AudioRendererAlgorithmParameters> |
| TestMediaClient::GetAudioRendererAlgorithmParameters( |
| AudioParameters audio_parameters) { |
| return absl::nullopt; |
| } |
| |
| } // namespace |
| |
| class KeySystemsTest : public testing::Test { |
| protected: |
| KeySystemsTest() { |
| vp8_codec_.push_back("vp8"); |
| |
| vp80_codec_.push_back("vp8.0"); |
| |
| vp9_codec_.push_back("vp9"); |
| |
| vp90_codec_.push_back("vp9.0"); |
| |
| vorbis_codec_.push_back("vorbis"); |
| |
| vp8_and_vorbis_codecs_.push_back("vp8"); |
| vp8_and_vorbis_codecs_.push_back("vorbis"); |
| |
| vp9_and_vorbis_codecs_.push_back("vp9"); |
| vp9_and_vorbis_codecs_.push_back("vorbis"); |
| |
| foovideo_codec_.push_back("foovideo"); |
| |
| securefoovideo_codec_.push_back("securefoovideo"); |
| |
| // KeySystems only do strict codec string comparison. Extended codecs are |
| // not supported. Note that in production KeySystemConfigSelector will strip |
| // codec extension before calling into KeySystems. |
| foovideo_extended_codec_.push_back("foovideo.4D400C"); |
| foovideo_dot_codec_.push_back("foovideo."); |
| |
| fooaudio_codec_.push_back("fooaudio"); |
| |
| foovideo_and_fooaudio_codecs_.push_back("foovideo"); |
| foovideo_and_fooaudio_codecs_.push_back("fooaudio"); |
| |
| unknown_codec_.push_back("unknown"); |
| |
| mixed_codecs_.push_back("vorbis"); |
| mixed_codecs_.push_back("foovideo"); |
| |
| SetMediaClient(&test_media_client_); |
| } |
| |
| void SetUp() override { AddContainerAndCodecMasksForTest(); } |
| |
| ~KeySystemsTest() override { |
| // Clear the use of |test_media_client_|, which was set in SetUp(). |
| // NOTE: This does not clear any cached KeySystemProperties in the global |
| // KeySystems instance. |
| SetMediaClient(nullptr); |
| } |
| |
| void UpdateClientKeySystems() { |
| test_media_client_.SetKeySystemsUpdateNeeded(); |
| test_media_client_.DisableExternalKeySystemSupport(); |
| } |
| |
| typedef std::vector<std::string> CodecVector; |
| |
| const CodecVector& no_codecs() const { return no_codecs_; } |
| |
| const CodecVector& vp8_codec() const { return vp8_codec_; } |
| const CodecVector& vp80_codec() const { return vp80_codec_; } |
| const CodecVector& vp9_codec() const { return vp9_codec_; } |
| const CodecVector& vp90_codec() const { return vp90_codec_; } |
| |
| const CodecVector& vorbis_codec() const { return vorbis_codec_; } |
| |
| const CodecVector& vp8_and_vorbis_codecs() const { |
| return vp8_and_vorbis_codecs_; |
| } |
| const CodecVector& vp9_and_vorbis_codecs() const { |
| return vp9_and_vorbis_codecs_; |
| } |
| |
| const CodecVector& foovideo_codec() const { return foovideo_codec_; } |
| const CodecVector& securefoovideo_codec() const { |
| return securefoovideo_codec_; |
| } |
| const CodecVector& foovideo_extended_codec() const { |
| return foovideo_extended_codec_; |
| } |
| const CodecVector& foovideo_dot_codec() const { return foovideo_dot_codec_; } |
| const CodecVector& fooaudio_codec() const { return fooaudio_codec_; } |
| const CodecVector& foovideo_and_fooaudio_codecs() const { |
| return foovideo_and_fooaudio_codecs_; |
| } |
| |
| const CodecVector& unknown_codec() const { return unknown_codec_; } |
| |
| const CodecVector& mixed_codecs() const { return mixed_codecs_; } |
| |
| private: |
| const CodecVector no_codecs_; |
| CodecVector vp8_codec_; |
| CodecVector vp80_codec_; |
| CodecVector vp9_codec_; |
| CodecVector vp90_codec_; |
| CodecVector vorbis_codec_; |
| CodecVector vp8_and_vorbis_codecs_; |
| CodecVector vp9_and_vorbis_codecs_; |
| |
| CodecVector foovideo_codec_; |
| CodecVector securefoovideo_codec_; |
| CodecVector foovideo_extended_codec_; |
| CodecVector foovideo_dot_codec_; |
| CodecVector fooaudio_codec_; |
| CodecVector foovideo_and_fooaudio_codecs_; |
| |
| CodecVector unknown_codec_; |
| |
| CodecVector mixed_codecs_; |
| |
| TestMediaClient test_media_client_; |
| }; |
| |
| TEST_F(KeySystemsTest, EmptyKeySystem) { |
| EXPECT_FALSE(IsSupportedKeySystem(std::string())); |
| EXPECT_EQ("Unknown", GetKeySystemNameForUMA(std::string())); |
| } |
| |
| // Clear Key is the only key system registered in content. |
| TEST_F(KeySystemsTest, ClearKey) { |
| EXPECT_TRUE(IsSupportedKeySystem(kClearKey)); |
| EXPECT_TRUE(IsSupportedKeySystemWithMediaMimeType(kVideoWebM, no_codecs(), |
| kClearKey)); |
| |
| EXPECT_EQ("ClearKey", GetKeySystemNameForUMA(kClearKey)); |
| } |
| |
| TEST_F(KeySystemsTest, ClearKeyWithInitDataType) { |
| EXPECT_TRUE(IsSupportedKeySystem(kClearKey)); |
| EXPECT_TRUE( |
| IsSupportedKeySystemWithInitDataType(kClearKey, EmeInitDataType::WEBM)); |
| EXPECT_TRUE( |
| IsSupportedKeySystemWithInitDataType(kClearKey, EmeInitDataType::KEYIDS)); |
| |
| // All other InitDataTypes are not supported. |
| EXPECT_FALSE(IsSupportedKeySystemWithInitDataType(kClearKey, |
| EmeInitDataType::UNKNOWN)); |
| } |
| |
| // The key system is not registered and therefore is unrecognized. |
| TEST_F(KeySystemsTest, Basic_UnrecognizedKeySystem) { |
| static const char* const kUnrecognized = "x-org.example.unrecognized"; |
| |
| EXPECT_FALSE(IsSupportedKeySystem(kUnrecognized)); |
| |
| EXPECT_EQ("Unknown", GetKeySystemNameForUMA(kUnrecognized)); |
| EXPECT_FALSE(CanUseAesDecryptor(kUnrecognized)); |
| } |
| |
| TEST_F(KeySystemsTest, Basic_UsesAesDecryptor) { |
| EXPECT_TRUE(IsSupportedKeySystem(kUsesAes)); |
| EXPECT_TRUE( |
| IsSupportedKeySystemWithMediaMimeType(kVideoWebM, no_codecs(), kUsesAes)); |
| |
| // No UMA value for this test key system. |
| EXPECT_EQ("Unknown", GetKeySystemNameForUMA(kUsesAes)); |
| |
| EXPECT_TRUE(CanUseAesDecryptor(kUsesAes)); |
| } |
| |
| TEST_F(KeySystemsTest, |
| IsSupportedKeySystemWithMediaMimeType_UsesAesDecryptor_TypesContainer1) { |
| // Valid video types. |
| EXPECT_TRUE( |
| IsSupportedKeySystemWithMediaMimeType(kVideoWebM, vp8_codec(), kUsesAes)); |
| EXPECT_TRUE(IsSupportedKeySystemWithMediaMimeType(kVideoWebM, vp80_codec(), |
| kUsesAes)); |
| EXPECT_TRUE( |
| IsSupportedKeySystemWithMediaMimeType(kVideoWebM, vp9_codec(), kUsesAes)); |
| EXPECT_TRUE(IsSupportedKeySystemWithMediaMimeType(kVideoWebM, vp90_codec(), |
| kUsesAes)); |
| |
| // Audio in a video container. |
| EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType( |
| kVideoWebM, vp8_and_vorbis_codecs(), kUsesAes)); |
| EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType( |
| kVideoWebM, vp9_and_vorbis_codecs(), kUsesAes)); |
| EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType(kVideoWebM, vorbis_codec(), |
| kUsesAes)); |
| |
| // Non-Webm codecs. |
| EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType( |
| kVideoWebM, foovideo_codec(), kUsesAes)); |
| EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType( |
| kVideoWebM, unknown_codec(), kUsesAes)); |
| EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType(kVideoWebM, mixed_codecs(), |
| kUsesAes)); |
| |
| // Valid audio types. |
| EXPECT_TRUE( |
| IsSupportedKeySystemWithAudioMimeType(kAudioWebM, no_codecs(), kUsesAes)); |
| EXPECT_TRUE(IsSupportedKeySystemWithAudioMimeType(kAudioWebM, vorbis_codec(), |
| kUsesAes)); |
| |
| // Non-audio codecs. |
| EXPECT_FALSE( |
| IsSupportedKeySystemWithMediaMimeType(kAudioWebM, vp8_codec(), kUsesAes)); |
| EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType( |
| kAudioWebM, vp8_and_vorbis_codecs(), kUsesAes)); |
| EXPECT_FALSE( |
| IsSupportedKeySystemWithMediaMimeType(kAudioWebM, vp9_codec(), kUsesAes)); |
| EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType( |
| kAudioWebM, vp9_and_vorbis_codecs(), kUsesAes)); |
| |
| // Non-Webm codec. |
| EXPECT_FALSE(IsSupportedKeySystemWithAudioMimeType( |
| kAudioWebM, fooaudio_codec(), kUsesAes)); |
| } |
| |
| TEST_F(KeySystemsTest, IsSupportedKeySystem_InvalidVariants) { |
| // Case sensitive. |
| EXPECT_FALSE(IsSupportedKeySystem("x-org.example.ClEaR")); |
| |
| // TLDs are not allowed. |
| EXPECT_FALSE(IsSupportedKeySystem("org.")); |
| EXPECT_FALSE(IsSupportedKeySystem("com")); |
| |
| // Extra period. |
| EXPECT_FALSE(IsSupportedKeySystem("x-org.example.clear.")); |
| |
| // Prefix. |
| EXPECT_FALSE(IsSupportedKeySystem("x-org.example.")); |
| EXPECT_FALSE(IsSupportedKeySystem("x-org.example")); |
| |
| // Incomplete. |
| EXPECT_FALSE(IsSupportedKeySystem("x-org.example.clea")); |
| |
| // Extra character. |
| EXPECT_FALSE(IsSupportedKeySystem("x-org.example.clearz")); |
| |
| // There are no child key systems for UsesAes. |
| EXPECT_FALSE(IsSupportedKeySystem("x-org.example.clear.foo")); |
| } |
| |
| TEST_F(KeySystemsTest, IsSupportedKeySystemWithMediaMimeType_NoType) { |
| EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType(std::string(), no_codecs(), |
| kUsesAes)); |
| |
| EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType(std::string(), no_codecs(), |
| "x-org.example.foo")); |
| EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType( |
| std::string(), no_codecs(), "x-org.example.clear.foo")); |
| } |
| |
| // Tests the second registered container type. |
| // TODO(ddorwin): Combined with TypesContainer1 in a future CL. |
| TEST_F(KeySystemsTest, |
| IsSupportedKeySystemWithMediaMimeType_UsesAesDecryptor_TypesContainer2) { |
| // Valid video types. |
| EXPECT_TRUE( |
| IsSupportedKeySystemWithMediaMimeType(kVideoFoo, no_codecs(), kUsesAes)); |
| EXPECT_TRUE(IsSupportedKeySystemWithMediaMimeType(kVideoFoo, foovideo_codec(), |
| kUsesAes)); |
| |
| // Audio in a video container. |
| EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType( |
| kVideoFoo, foovideo_and_fooaudio_codecs(), kUsesAes)); |
| EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType( |
| kVideoFoo, fooaudio_codec(), kUsesAes)); |
| |
| // Extended codecs. |
| EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType( |
| kVideoFoo, foovideo_extended_codec(), kUsesAes)); |
| |
| // Invalid codec format. |
| EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType( |
| kVideoFoo, foovideo_dot_codec(), kUsesAes)); |
| |
| // Non-container2 codec. |
| EXPECT_FALSE( |
| IsSupportedKeySystemWithMediaMimeType(kVideoFoo, vp8_codec(), kUsesAes)); |
| EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType(kVideoFoo, unknown_codec(), |
| kUsesAes)); |
| EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType(kVideoFoo, mixed_codecs(), |
| kUsesAes)); |
| |
| // Valid audio types. |
| EXPECT_TRUE( |
| IsSupportedKeySystemWithAudioMimeType(kAudioFoo, no_codecs(), kUsesAes)); |
| EXPECT_TRUE(IsSupportedKeySystemWithAudioMimeType(kAudioFoo, fooaudio_codec(), |
| kUsesAes)); |
| |
| // Non-audio codecs. |
| EXPECT_FALSE(IsSupportedKeySystemWithAudioMimeType( |
| kAudioFoo, foovideo_codec(), kUsesAes)); |
| EXPECT_FALSE(IsSupportedKeySystemWithAudioMimeType( |
| kAudioFoo, foovideo_and_fooaudio_codecs(), kUsesAes)); |
| |
| // Non-container2 codec. |
| EXPECT_FALSE(IsSupportedKeySystemWithAudioMimeType(kAudioFoo, vorbis_codec(), |
| kUsesAes)); |
| } |
| |
| TEST_F(KeySystemsTest, |
| IsSupportedKeySystem_UsesAesDecryptor_EncryptionSchemes) { |
| ExpectEncryptionSchemeConfigRule(kUsesAes, EncryptionScheme::kUnencrypted, |
| EmeConfigRule::SUPPORTED); |
| ExpectEncryptionSchemeConfigRule(kUsesAes, EncryptionScheme::kCenc, |
| EmeConfigRule::SUPPORTED); |
| ExpectEncryptionSchemeConfigRule(kUsesAes, EncryptionScheme::kCbcs, |
| EmeConfigRule::NOT_SUPPORTED); |
| } |
| |
| // |
| // Non-AesDecryptor-based key system. |
| // |
| |
| TEST_F(KeySystemsTest, Basic_ExternalDecryptor) { |
| if (!CanRunExternalKeySystemTests()) |
| return; |
| |
| EXPECT_TRUE(IsSupportedKeySystem(kExternal)); |
| EXPECT_TRUE(IsSupportedKeySystemWithMediaMimeType(kVideoWebM, no_codecs(), |
| kExternal)); |
| |
| EXPECT_FALSE(CanUseAesDecryptor(kExternal)); |
| } |
| |
| TEST_F( |
| KeySystemsTest, |
| IsSupportedKeySystemWithMediaMimeType_ExternalDecryptor_TypesContainer1) { |
| if (!CanRunExternalKeySystemTests()) |
| return; |
| |
| // Valid video types. |
| EXPECT_TRUE(IsSupportedKeySystemWithMediaMimeType(kVideoWebM, no_codecs(), |
| kExternal)); |
| EXPECT_TRUE(IsSupportedKeySystemWithMediaMimeType(kVideoWebM, vp8_codec(), |
| kExternal)); |
| EXPECT_TRUE(IsSupportedKeySystemWithMediaMimeType(kVideoWebM, vp80_codec(), |
| kExternal)); |
| EXPECT_TRUE(IsSupportedKeySystemWithMediaMimeType(kVideoWebM, vp9_codec(), |
| kExternal)); |
| EXPECT_TRUE(IsSupportedKeySystemWithMediaMimeType(kVideoWebM, vp90_codec(), |
| kExternal)); |
| |
| // Audio in a video container. |
| EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType( |
| kVideoWebM, vp8_and_vorbis_codecs(), kExternal)); |
| EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType( |
| kVideoWebM, vp9_and_vorbis_codecs(), kExternal)); |
| EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType(kVideoWebM, vorbis_codec(), |
| kExternal)); |
| |
| // Non-Webm codecs. |
| EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType( |
| kVideoWebM, foovideo_codec(), kExternal)); |
| EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType( |
| kVideoWebM, unknown_codec(), kExternal)); |
| EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType(kVideoWebM, mixed_codecs(), |
| kExternal)); |
| |
| // Valid audio types. |
| EXPECT_TRUE(IsSupportedKeySystemWithAudioMimeType(kAudioWebM, no_codecs(), |
| kExternal)); |
| EXPECT_TRUE(IsSupportedKeySystemWithAudioMimeType(kAudioWebM, vorbis_codec(), |
| kExternal)); |
| |
| // Non-audio codecs. |
| EXPECT_FALSE(IsSupportedKeySystemWithAudioMimeType(kAudioWebM, vp8_codec(), |
| kExternal)); |
| EXPECT_FALSE(IsSupportedKeySystemWithAudioMimeType( |
| kAudioWebM, vp8_and_vorbis_codecs(), kExternal)); |
| EXPECT_FALSE(IsSupportedKeySystemWithAudioMimeType(kAudioWebM, vp9_codec(), |
| kExternal)); |
| EXPECT_FALSE(IsSupportedKeySystemWithAudioMimeType( |
| kAudioWebM, vp9_and_vorbis_codecs(), kExternal)); |
| |
| // Non-Webm codec. |
| EXPECT_FALSE(IsSupportedKeySystemWithAudioMimeType( |
| kAudioWebM, fooaudio_codec(), kExternal)); |
| } |
| |
| TEST_F( |
| KeySystemsTest, |
| IsSupportedKeySystemWithMediaMimeType_ExternalDecryptor_TypesContainer2) { |
| if (!CanRunExternalKeySystemTests()) |
| return; |
| |
| // Valid video types. |
| EXPECT_TRUE( |
| IsSupportedKeySystemWithMediaMimeType(kVideoFoo, no_codecs(), kExternal)); |
| EXPECT_TRUE(IsSupportedKeySystemWithMediaMimeType(kVideoFoo, foovideo_codec(), |
| kExternal)); |
| |
| // Audio in a video container. |
| EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType( |
| kVideoFoo, foovideo_and_fooaudio_codecs(), kExternal)); |
| EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType( |
| kVideoFoo, fooaudio_codec(), kExternal)); |
| |
| // Extended codecs. |
| EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType( |
| kVideoFoo, foovideo_extended_codec(), kExternal)); |
| |
| // Invalid codec format. |
| EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType( |
| kVideoFoo, foovideo_dot_codec(), kExternal)); |
| |
| // Non-container2 codecs. |
| EXPECT_FALSE( |
| IsSupportedKeySystemWithMediaMimeType(kVideoFoo, vp8_codec(), kExternal)); |
| EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType(kVideoFoo, unknown_codec(), |
| kExternal)); |
| EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType(kVideoFoo, mixed_codecs(), |
| kExternal)); |
| |
| // Valid audio types. |
| EXPECT_TRUE( |
| IsSupportedKeySystemWithAudioMimeType(kAudioFoo, no_codecs(), kExternal)); |
| EXPECT_TRUE(IsSupportedKeySystemWithAudioMimeType(kAudioFoo, fooaudio_codec(), |
| kExternal)); |
| |
| // Non-audio codecs. |
| EXPECT_FALSE(IsSupportedKeySystemWithAudioMimeType( |
| kAudioFoo, foovideo_codec(), kExternal)); |
| EXPECT_FALSE(IsSupportedKeySystemWithAudioMimeType( |
| kAudioFoo, foovideo_and_fooaudio_codecs(), kExternal)); |
| |
| // Non-container2 codec. |
| EXPECT_FALSE(IsSupportedKeySystemWithAudioMimeType(kAudioFoo, vorbis_codec(), |
| kExternal)); |
| } |
| |
| TEST_F(KeySystemsTest, |
| IsSupportedKeySystem_ExternalDecryptor_EncryptionSchemes) { |
| if (!CanRunExternalKeySystemTests()) |
| return; |
| |
| ExpectEncryptionSchemeConfigRule(kExternal, EncryptionScheme::kUnencrypted, |
| EmeConfigRule::SUPPORTED); |
| ExpectEncryptionSchemeConfigRule(kExternal, EncryptionScheme::kCenc, |
| EmeConfigRule::SUPPORTED); |
| ExpectEncryptionSchemeConfigRule(kExternal, EncryptionScheme::kCbcs, |
| EmeConfigRule::HW_SECURE_CODECS_NOT_ALLOWED); |
| } |
| |
| TEST_F(KeySystemsTest, KeySystemNameForUMA) { |
| EXPECT_EQ("ClearKey", GetKeySystemNameForUMA(kClearKey)); |
| EXPECT_EQ("Widevine", GetKeySystemNameForUMA(kWidevineKeySystem)); |
| EXPECT_EQ("Unknown", GetKeySystemNameForUMA("Foo")); |
| |
| // External Clear Key never has a UMA name. |
| if (CanRunExternalKeySystemTests()) |
| EXPECT_EQ("Unknown", GetKeySystemNameForUMA(kExternalClearKey)); |
| } |
| |
| TEST_F(KeySystemsTest, KeySystemsUpdate) { |
| EXPECT_TRUE(IsSupportedKeySystem(kUsesAes)); |
| EXPECT_TRUE( |
| IsSupportedKeySystemWithMediaMimeType(kVideoWebM, no_codecs(), kUsesAes)); |
| |
| if (CanRunExternalKeySystemTests()) { |
| EXPECT_TRUE(IsSupportedKeySystem(kExternal)); |
| EXPECT_TRUE(IsSupportedKeySystemWithMediaMimeType(kVideoWebM, no_codecs(), |
| kExternal)); |
| } |
| |
| UpdateClientKeySystems(); |
| |
| EXPECT_TRUE(IsSupportedKeySystem(kUsesAes)); |
| EXPECT_TRUE( |
| IsSupportedKeySystemWithMediaMimeType(kVideoWebM, no_codecs(), kUsesAes)); |
| if (CanRunExternalKeySystemTests()) |
| EXPECT_FALSE(IsSupportedKeySystem(kExternal)); |
| } |
| |
| TEST_F(KeySystemsTest, GetContentTypeConfigRule) { |
| if (!CanRunExternalKeySystemTests()) |
| return; |
| |
| EXPECT_EQ(EmeConfigRule::SUPPORTED, |
| GetRobustnessConfigRule(kRobustnessSupported)); |
| EXPECT_EQ(EmeConfigRule::NOT_SUPPORTED, |
| GetRobustnessConfigRule(kRobustnessNotSupported)); |
| EXPECT_EQ(EmeConfigRule::HW_SECURE_CODECS_REQUIRED, |
| GetRobustnessConfigRule(kRobustnessSecureCodecsRequired)); |
| } |
| |
| TEST_F(KeySystemsTest, HardwareSecureCodecs) { |
| if (!CanRunExternalKeySystemTests()) |
| return; |
| |
| EXPECT_EQ(EmeConfigRule::HW_SECURE_CODECS_NOT_ALLOWED, |
| GetVideoContentTypeConfigRule(kVideoWebM, vp8_codec(), kUsesAes)); |
| EXPECT_EQ( |
| EmeConfigRule::HW_SECURE_CODECS_NOT_ALLOWED, |
| GetVideoContentTypeConfigRule(kVideoFoo, foovideo_codec(), kUsesAes)); |
| EXPECT_EQ(EmeConfigRule::NOT_SUPPORTED, |
| GetVideoContentTypeConfigRule(kVideoFoo, securefoovideo_codec(), |
| kUsesAes)); |
| |
| EXPECT_EQ(EmeConfigRule::HW_SECURE_CODECS_NOT_ALLOWED, |
| GetVideoContentTypeConfigRule(kVideoWebM, vp8_codec(), kExternal)); |
| EXPECT_EQ( |
| EmeConfigRule::SUPPORTED, |
| GetVideoContentTypeConfigRule(kVideoFoo, foovideo_codec(), kExternal)); |
| |
| EXPECT_EQ(EmeConfigRule::HW_SECURE_CODECS_REQUIRED, |
| GetVideoContentTypeConfigRule(kVideoFoo, securefoovideo_codec(), |
| kExternal)); |
| } |
| |
| } // namespace media |