diff options
Diffstat (limited to 'chromium/third_party/blink/renderer/platform/media/key_system_config_selector_unittest.cc')
-rw-r--r-- | chromium/third_party/blink/renderer/platform/media/key_system_config_selector_unittest.cc | 1849 |
1 files changed, 1849 insertions, 0 deletions
diff --git a/chromium/third_party/blink/renderer/platform/media/key_system_config_selector_unittest.cc b/chromium/third_party/blink/renderer/platform/media/key_system_config_selector_unittest.cc new file mode 100644 index 00000000000..0b8394f14a7 --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/media/key_system_config_selector_unittest.cc @@ -0,0 +1,1849 @@ +// Copyright 2015 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. + +#include "third_party/blink/public/platform/media/key_system_config_selector.h" + +#include <string> +#include <vector> + +#include "base/bind.h" +#include "base/strings/pattern.h" +#include "build/build_config.h" +#include "media/base/cdm_config.h" +#include "media/base/eme_constants.h" +#include "media/base/key_systems.h" +#include "media/base/media_permission.h" +#include "media/base/mime_util.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/platform/web_content_settings_client.h" +#include "third_party/blink/public/platform/web_encrypted_media_types.h" +#include "third_party/blink/public/platform/web_media_key_system_configuration.h" +#include "third_party/blink/public/platform/web_string.h" + +namespace blink { +namespace { + +using ::media::EmeConfigRule; +using ::media::EmeFeatureSupport; +using ::media::EmeInitDataType; +using ::media::EmeMediaType; +using ::media::EmeSessionTypeSupport; +using MediaKeysRequirement = WebMediaKeySystemConfiguration::Requirement; +using EncryptionScheme = WebMediaKeySystemMediaCapability::EncryptionScheme; + +// Key system strings. Clear Key support is hardcoded in KeySystemConfigSelector +// so kClearKeyKeySystem is the real key system string. The rest key system +// strings are for testing purpose only. +const char kClearKeyKeySystem[] = "org.w3.clearkey"; +const char kSupportedKeySystem[] = "keysystem.test.supported"; +const char kUnsupportedKeySystem[] = "keysystem.test.unsupported"; + +// Robustness strings for kSupportedKeySystem. +const char kSupportedRobustness[] = "supported"; +const char kRecommendIdentifierRobustness[] = "recommend_identifier"; +const char kRequireIdentifierRobustness[] = "require_identifier"; +const char kDisallowHwSecureCodecRobustness[] = "disallow_hw_secure_codec"; +const char kRequireHwSecureCodecRobustness[] = "require_hw_secure_codec"; +const char kRequireIdentifierAndHwSecureCodecRobustness[] = + "require_identifier_and_hw_secure_codec"; +const char kRequireIdentifierPersistenceAndHwSecureCodecRobustness[] = + "require_identifier_persistence_and_hw_secure_codec"; +const char kUnsupportedRobustness[] = "unsupported"; + +// Test container mime types. Supported types are prefixed with audio/video so +// that the test can perform EmeMediaType check. +const char kSupportedVideoContainer[] = "video/supported"; +const char kSupportedAudioContainer[] = "audio/supported"; +const char kUnsupportedContainer[] = "video/unsupported"; +const char kInvalidContainer[] = "video/invalid"; + +// The codec strings. Supported types are prefixed with audio/video so +// that the test can perform EmeMediaType check. +// TODO(sandersd): Extended codec variants (requires proprietary codec support). +// TODO(xhwang): Platform Opus is not available on all Android versions, where +// some encrypted Opus related tests may fail. See +// MediaCodecUtil::IsOpusDecoderAvailable() for more details. +const char kSupportedAudioCodec[] = "audio_codec"; +const char kSupportedVideoCodec[] = "video_codec"; +const char kUnsupportedCodec[] = "unsupported_codec"; +const char kInvalidCodec[] = "foo"; +const char kRequireHwSecureCodec[] = "require_hw_secure_codec"; +const char kDisallowHwSecureCodec[] = "disallow_hw_secure_codec"; +const char kExtendedVideoCodec[] = "video_extended_codec.extended"; +const char kExtendedVideoCodecStripped[] = "video_extended_codec"; +// A special codec that is supported by the key systems, but is not supported +// in IsSupportedMediaType() when |use_aes_decryptor| is true. +const char kUnsupportedByAesDecryptorCodec[] = "unsupported_by_aes_decryptor"; + +// Encryption schemes. For testing 'cenc' is supported, while 'cbcs' is not. +// Note that WebMediaKeySystemMediaCapability defaults to kNotSpecified, +// which is treated as 'cenc' by KeySystemConfigSelector. +constexpr EncryptionScheme kSupportedEncryptionScheme = EncryptionScheme::kCenc; +constexpr EncryptionScheme kDisallowHwSecureCodecEncryptionScheme = + EncryptionScheme::kCbcs; + +media::EncryptionScheme ConvertEncryptionScheme( + EncryptionScheme encryption_scheme) { + switch (encryption_scheme) { + case EncryptionScheme::kNotSpecified: + case EncryptionScheme::kCenc: + return media::EncryptionScheme::kCenc; + case EncryptionScheme::kCbcs: + case EncryptionScheme::kCbcs_1_9: + return media::EncryptionScheme::kCbcs; + case EncryptionScheme::kUnrecognized: + // Not used in these tests. + break; + } + + NOTREACHED(); + return media::EncryptionScheme::kUnencrypted; +} + +WebString MakeCodecs(const std::string& a, const std::string& b) { + return WebString::FromUTF8(a + "," + b); +} + +WebString GetSupportedVideoCodecs() { + return MakeCodecs(kSupportedVideoCodec, kSupportedVideoCodec); +} + +WebString GetSubsetSupportedVideoCodecs() { + return MakeCodecs(kSupportedVideoCodec, kUnsupportedCodec); +} + +WebString GetSubsetInvalidVideoCodecs() { + return MakeCodecs(kSupportedVideoCodec, kInvalidCodec); +} + +bool IsValidContainerMimeType(const std::string& container_mime_type) { + return container_mime_type != kInvalidContainer; +} + +bool IsValidCodec(const std::string& codec) { + return codec != kInvalidCodec; +} + +// Returns whether |type| is compatible with |media_type|. +bool IsCompatibleWithEmeMediaType(EmeMediaType media_type, + const std::string& type) { + if (media_type == EmeMediaType::AUDIO && base::MatchPattern(type, "video*")) + return false; + + if (media_type == EmeMediaType::VIDEO && base::MatchPattern(type, "audio*")) + return false; + + return true; +} + +// Pretend that we support all |container_mime_type| and |codecs| except for +// those explicitly marked as invalid. +bool IsSupportedMediaType(const std::string& container_mime_type, + const std::string& codecs, + bool use_aes_decryptor) { + if (container_mime_type == kInvalidContainer) + return false; + + std::vector<std::string> codec_vector; + media::SplitCodecs(codecs, &codec_vector); + for (const std::string& codec : codec_vector) { + DCHECK_NE(codec, kExtendedVideoCodecStripped) + << "codecs passed into this function should not be stripped"; + + if (codec == kInvalidCodec) + return false; + + if (use_aes_decryptor && codec == kUnsupportedByAesDecryptorCodec) + return false; + } + + return true; +} + +// The IDL for MediaKeySystemConfiguration specifies some defaults, so +// create a config object that mimics what would be created if an empty +// dictionary was passed in. +WebMediaKeySystemConfiguration EmptyConfiguration() { + // http://w3c.github.io/encrypted-media/#mediakeysystemconfiguration-dictionary + // If this member (sessionTypes) is not present when the dictionary + // is passed to requestMediaKeySystemAccess(), the dictionary will + // be treated as if this member is set to [ "temporary" ]. + std::vector<WebEncryptedMediaSessionType> session_types; + session_types.push_back(WebEncryptedMediaSessionType::kTemporary); + + WebMediaKeySystemConfiguration config; + config.label = ""; + config.session_types = session_types; + return config; +} + +// EME spec requires that at least one of |video_capabilities| and +// |audio_capabilities| be specified. Add a single valid audio capability +// to the EmptyConfiguration(). +WebMediaKeySystemConfiguration UsableConfiguration() { + // Blink code parses the contentType into mimeType and codecs, so mimic + // that here. + std::vector<WebMediaKeySystemMediaCapability> audio_capabilities(1); + audio_capabilities[0].mime_type = kSupportedAudioContainer; + audio_capabilities[0].codecs = kSupportedAudioCodec; + + auto config = EmptyConfiguration(); + config.audio_capabilities = audio_capabilities; + return config; +} + +class FakeKeySystems : public media::KeySystems { + public: + ~FakeKeySystems() override = default; + + void UpdateIfNeeded() override { ++update_count; } + + bool IsSupportedKeySystem(const std::string& key_system) const override { + // Based on EME spec, Clear Key key system is always supported. + return key_system == kSupportedKeySystem || + key_system == kClearKeyKeySystem; + } + + bool CanUseAesDecryptor(const std::string& key_system) const override { + return key_system == kClearKeyKeySystem; + } + + // TODO(sandersd): Move implementation into KeySystemConfigSelector? + bool IsSupportedInitDataType(const std::string& key_system, + EmeInitDataType init_data_type) const override { + switch (init_data_type) { + case EmeInitDataType::UNKNOWN: + return false; + case EmeInitDataType::WEBM: + return init_data_type_webm_supported_; + case EmeInitDataType::CENC: + return init_data_type_cenc_supported_; + case EmeInitDataType::KEYIDS: + return init_data_type_keyids_supported_; + } + NOTREACHED(); + return false; + } + + EmeConfigRule GetEncryptionSchemeConfigRule( + const std::string& key_system, + media::EncryptionScheme encryption_scheme) const override { + if (encryption_scheme == + ConvertEncryptionScheme(kSupportedEncryptionScheme)) { + return EmeConfigRule::SUPPORTED; + } + + if (encryption_scheme == + ConvertEncryptionScheme(kDisallowHwSecureCodecEncryptionScheme)) { + return EmeConfigRule::HW_SECURE_CODECS_NOT_ALLOWED; + } + + return EmeConfigRule::NOT_SUPPORTED; + } + + EmeConfigRule GetContentTypeConfigRule( + const std::string& key_system, + EmeMediaType media_type, + const std::string& container_mime_type, + const std::vector<std::string>& codecs) const override { + DCHECK(IsValidContainerMimeType(container_mime_type)) + << "Invalid container mime type should not be passed in"; + if (container_mime_type == kUnsupportedContainer || + !IsCompatibleWithEmeMediaType(media_type, container_mime_type)) { + return EmeConfigRule::NOT_SUPPORTED; + } + + bool hw_secure_codec_required_ = false; + bool hw_secure_codec_not_allowed_ = false; + + for (const std::string& codec : codecs) { + DCHECK(IsValidCodec(codec)) << "Invalid codec should not be passed in"; + + if (codec == kUnsupportedCodec || + !IsCompatibleWithEmeMediaType(media_type, codec)) { + return EmeConfigRule::NOT_SUPPORTED; + } else if (codec == kRequireHwSecureCodec) { + hw_secure_codec_required_ = true; + } else if (codec == kDisallowHwSecureCodec) { + hw_secure_codec_not_allowed_ = true; + } + } + + if (hw_secure_codec_required_) { + if (hw_secure_codec_not_allowed_) + return EmeConfigRule::NOT_SUPPORTED; + else + return EmeConfigRule::HW_SECURE_CODECS_REQUIRED; + } + + if (hw_secure_codec_not_allowed_) + return EmeConfigRule::HW_SECURE_CODECS_NOT_ALLOWED; + + return EmeConfigRule::SUPPORTED; + } + + EmeConfigRule GetRobustnessConfigRule( + const std::string& key_system, + EmeMediaType media_type, + const std::string& requested_robustness, + const bool* hw_secure_requirement) const override { + // TODO(crbug.com/1204284): Remove the `hw_secure_requirement` parameter. + // This only exists as a temporary solution until a larger refactoring is + // done. We are only testing the explicit thing it is fixing here. + if (hw_secure_requirement && *hw_secure_requirement && + distinctive_identifier == EmeFeatureSupport::NOT_SUPPORTED) { + return EmeConfigRule::NOT_SUPPORTED; + } + if (requested_robustness.empty()) + return EmeConfigRule::SUPPORTED; + if (requested_robustness == kSupportedRobustness) + return EmeConfigRule::SUPPORTED; + if (requested_robustness == kRequireIdentifierRobustness) + return EmeConfigRule::IDENTIFIER_REQUIRED; + if (requested_robustness == kRecommendIdentifierRobustness) + return EmeConfigRule::IDENTIFIER_RECOMMENDED; + if (requested_robustness == kDisallowHwSecureCodecRobustness) + return EmeConfigRule::HW_SECURE_CODECS_NOT_ALLOWED; + if (requested_robustness == kRequireHwSecureCodecRobustness) + return EmeConfigRule::HW_SECURE_CODECS_REQUIRED; + if (requested_robustness == kRequireIdentifierAndHwSecureCodecRobustness) + return EmeConfigRule::IDENTIFIER_AND_HW_SECURE_CODECS_REQUIRED; + if (requested_robustness == + kRequireIdentifierPersistenceAndHwSecureCodecRobustness) { + return EmeConfigRule:: + IDENTIFIER_PERSISTENCE_AND_HW_SECURE_CODECS_REQUIRED; + } + if (requested_robustness == kUnsupportedRobustness) + return EmeConfigRule::NOT_SUPPORTED; + + NOTREACHED(); + return EmeConfigRule::NOT_SUPPORTED; + } + + EmeSessionTypeSupport GetPersistentLicenseSessionSupport( + const std::string& key_system) const override { + return persistent_license; + } + + EmeFeatureSupport GetPersistentStateSupport( + const std::string& key_system) const override { + return persistent_state; + } + + EmeFeatureSupport GetDistinctiveIdentifierSupport( + const std::string& key_system) const override { + return distinctive_identifier; + } + + bool init_data_type_webm_supported_ = false; + bool init_data_type_cenc_supported_ = false; + bool init_data_type_keyids_supported_ = false; + + // INVALID so that they must be set in any test that needs them. + EmeSessionTypeSupport persistent_license = EmeSessionTypeSupport::INVALID; + + // Every test implicitly requires these, so they must be set. They are set to + // values that are likely to cause tests to fail if they are accidentally + // depended on. Test cases explicitly depending on them should set them, as + // the default values may be changed. + EmeFeatureSupport persistent_state = EmeFeatureSupport::NOT_SUPPORTED; + EmeFeatureSupport distinctive_identifier = EmeFeatureSupport::REQUESTABLE; + + int update_count = 0; +}; + +class FakeMediaPermission : public media::MediaPermission { + public: + // MediaPermission implementation. + void HasPermission(Type type, + PermissionStatusCB permission_status_cb) override { + std::move(permission_status_cb).Run(is_granted); + } + + void RequestPermission(Type type, + PermissionStatusCB permission_status_cb) override { + requests++; + std::move(permission_status_cb).Run(is_granted); + } + + bool IsEncryptedMediaEnabled() override { return is_encrypted_media_enabled; } + + int requests = 0; + bool is_granted = false; + bool is_encrypted_media_enabled = true; +}; + +class FakeWebLocalFrameDelegate + : public KeySystemConfigSelector::WebLocalFrameDelegate { + public: + FakeWebLocalFrameDelegate() + : KeySystemConfigSelector::WebLocalFrameDelegate(nullptr) {} + bool IsCrossOriginToMainFrame() override { return is_cross_origin_; } + bool AllowStorageAccessSync( + WebContentSettingsClient::StorageType storage_type) override { + if (storage_type == WebContentSettingsClient::StorageType::kLocalStorage) { + return local_storage_allowed_; + } + return true; + } + + bool is_cross_origin_ = false; + bool local_storage_allowed_ = true; +}; + +} // namespace + +class KeySystemConfigSelectorTest : public testing::Test { + public: + KeySystemConfigSelectorTest() + : key_systems_(std::make_unique<FakeKeySystems>()), + media_permission_(std::make_unique<FakeMediaPermission>()), + web_frame_delegate_(std::make_unique<FakeWebLocalFrameDelegate>()) {} + KeySystemConfigSelectorTest(const KeySystemConfigSelectorTest&) = delete; + KeySystemConfigSelectorTest& operator=(const KeySystemConfigSelectorTest&) = + delete; + + void SelectConfig() { + media_permission_->requests = 0; + succeeded_count_ = 0; + not_supported_count_ = 0; + KeySystemConfigSelector key_system_config_selector( + key_systems_.get(), media_permission_.get(), + std::move(web_frame_delegate_)); + // Replace the delegate with a new one to handle tests that call this + // method multiple times. This is safe because they don't use the delegate + // in testing. + web_frame_delegate_ = std::make_unique<FakeWebLocalFrameDelegate>(); + + key_system_config_selector.SetIsSupportedMediaTypeCBForTesting( + base::BindRepeating(&IsSupportedMediaType)); + + key_system_config_selector.SelectConfig( + key_system_, configs_, + base::BindOnce(&KeySystemConfigSelectorTest::OnConfigSelected, + base::Unretained(this))); + } + + void SelectConfigReturnsConfig() { + SelectConfig(); + EXPECT_EQ(0, media_permission_->requests); + EXPECT_EQ(1, succeeded_count_); + EXPECT_EQ(0, not_supported_count_); + ASSERT_NE(succeeded_count_, 0); + } + + void SelectConfigReturnsError() { + SelectConfig(); + EXPECT_EQ(0, media_permission_->requests); + EXPECT_EQ(0, succeeded_count_); + EXPECT_EQ(1, not_supported_count_); + ASSERT_NE(not_supported_count_, 0); + } + + void SelectConfigRequestsPermissionAndReturnsConfig() { + SelectConfig(); + EXPECT_EQ(1, media_permission_->requests); + EXPECT_EQ(1, succeeded_count_); + EXPECT_EQ(0, not_supported_count_); + ASSERT_NE(media_permission_->requests, 0); + ASSERT_NE(succeeded_count_, 0); + } + + void SelectConfigRequestsPermissionAndReturnsError() { + SelectConfig(); + EXPECT_EQ(1, media_permission_->requests); + EXPECT_EQ(0, succeeded_count_); + EXPECT_EQ(1, not_supported_count_); + ASSERT_NE(media_permission_->requests, 0); + ASSERT_NE(not_supported_count_, 0); + } + + void OnConfigSelected(KeySystemConfigSelector::Status status, + WebMediaKeySystemConfiguration* config, + media::CdmConfig* cdm_config) { + if (status == KeySystemConfigSelector::Status::kSupported) { + succeeded_count_++; + config_ = *config; + cdm_config_ = *cdm_config; + } else { + not_supported_count_++; + } + } + + std::unique_ptr<FakeKeySystems> key_systems_; + std::unique_ptr<FakeMediaPermission> media_permission_; + std::unique_ptr<FakeWebLocalFrameDelegate> web_frame_delegate_; + + // Held values for the call to SelectConfig(). + WebString key_system_ = WebString::FromUTF8(kSupportedKeySystem); + std::vector<WebMediaKeySystemConfiguration> configs_; + + // Holds the selected configuration and CdmConfig. + WebMediaKeySystemConfiguration config_; + media::CdmConfig cdm_config_; + + int succeeded_count_; + int not_supported_count_; +}; + +// --- Basics --- + +TEST_F(KeySystemConfigSelectorTest, NoConfigs) { + SelectConfigReturnsError(); +} + +TEST_F(KeySystemConfigSelectorTest, DefaultConfig) { + auto config = EmptyConfiguration(); + + // label = ""; + ASSERT_EQ("", config.label); + + // initDataTypes = []; + ASSERT_EQ(0u, config.init_data_types.size()); + + // audioCapabilities = []; + ASSERT_EQ(0u, config.audio_capabilities.size()); + + // videoCapabilities = []; + ASSERT_EQ(0u, config.video_capabilities.size()); + + // distinctiveIdentifier = "optional"; + ASSERT_EQ(MediaKeysRequirement::kOptional, config.distinctive_identifier); + + // persistentState = "optional"; + ASSERT_EQ(MediaKeysRequirement::kOptional, config.persistent_state); + + // If this member is not present when the dictionary is passed to + // requestMediaKeySystemAccess(), the dictionary will be treated as + // if this member is set to [ "temporary" ]. + ASSERT_EQ(1u, config.session_types.size()); + ASSERT_EQ(WebEncryptedMediaSessionType::kTemporary, config.session_types[0]); +} + +TEST_F(KeySystemConfigSelectorTest, EmptyConfig) { + // EME spec requires that at least one of |video_capabilities| and + // |audio_capabilities| be specified. + configs_.push_back(EmptyConfiguration()); + SelectConfigReturnsError(); +} + +// Most of the tests below assume that the the usable config is valid. +// Tests that touch |video_capabilities| and/or |audio_capabilities| can +// modify the empty config. + +TEST_F(KeySystemConfigSelectorTest, UsableConfig) { + configs_.push_back(UsableConfiguration()); + + SelectConfigReturnsConfig(); + + EXPECT_EQ("", config_.label); + EXPECT_TRUE(config_.init_data_types.empty()); + EXPECT_EQ(1u, config_.audio_capabilities.size()); + EXPECT_TRUE(config_.video_capabilities.empty()); + EXPECT_EQ(MediaKeysRequirement::kNotAllowed, config_.distinctive_identifier); + EXPECT_EQ(MediaKeysRequirement::kNotAllowed, config_.persistent_state); + ASSERT_EQ(1u, config_.session_types.size()); + EXPECT_EQ(WebEncryptedMediaSessionType::kTemporary, config_.session_types[0]); + + EXPECT_FALSE(cdm_config_.allow_distinctive_identifier); + EXPECT_FALSE(cdm_config_.allow_persistent_state); + EXPECT_FALSE(cdm_config_.use_hw_secure_codecs); +} + +// KeySystemConfigSelector should make sure it uses up-to-date KeySystems. +TEST_F(KeySystemConfigSelectorTest, UpdateKeySystems) { + configs_.push_back(UsableConfiguration()); + + ASSERT_EQ(key_systems_->update_count, 0); + SelectConfig(); + EXPECT_EQ(key_systems_->update_count, 1); + SelectConfig(); + EXPECT_EQ(key_systems_->update_count, 2); +} + +TEST_F(KeySystemConfigSelectorTest, Label) { + auto config = UsableConfiguration(); + config.label = "foo"; + configs_.push_back(config); + + SelectConfigReturnsConfig(); + EXPECT_EQ("foo", config_.label); +} + +// --- keySystem --- +// Empty is not tested because the empty check is in Blink. + +TEST_F(KeySystemConfigSelectorTest, KeySystem_NonAscii) { + key_system_ = "\xde\xad\xbe\xef"; + configs_.push_back(UsableConfiguration()); + SelectConfigReturnsError(); +} + +TEST_F(KeySystemConfigSelectorTest, KeySystem_Unsupported) { + key_system_ = kUnsupportedKeySystem; + configs_.push_back(UsableConfiguration()); + SelectConfigReturnsError(); +} + +TEST_F(KeySystemConfigSelectorTest, KeySystem_ClearKey) { + key_system_ = kClearKeyKeySystem; + configs_.push_back(UsableConfiguration()); + SelectConfigReturnsConfig(); +} + +// --- Disable EncryptedMedia --- + +TEST_F(KeySystemConfigSelectorTest, EncryptedMediaDisabled_ClearKey) { + media_permission_->is_encrypted_media_enabled = false; + + // Clear Key key system is always supported. + key_system_ = kClearKeyKeySystem; + configs_.push_back(UsableConfiguration()); + SelectConfigReturnsConfig(); +} + +TEST_F(KeySystemConfigSelectorTest, EncryptedMediaDisabled_Supported) { + media_permission_->is_encrypted_media_enabled = false; + + // Other key systems are not supported. + key_system_ = kSupportedKeySystem; + configs_.push_back(UsableConfiguration()); + SelectConfigReturnsError(); +} + +// --- initDataTypes --- + +TEST_F(KeySystemConfigSelectorTest, InitDataTypes_Empty) { + auto config = UsableConfiguration(); + configs_.push_back(config); + + SelectConfigReturnsConfig(); +} + +TEST_F(KeySystemConfigSelectorTest, InitDataTypes_NoneSupported) { + key_systems_->init_data_type_webm_supported_ = true; + + std::vector<EmeInitDataType> init_data_types; + init_data_types.push_back(EmeInitDataType::UNKNOWN); + init_data_types.push_back(EmeInitDataType::CENC); + + auto config = UsableConfiguration(); + config.init_data_types = init_data_types; + configs_.push_back(config); + + SelectConfigReturnsError(); +} + +TEST_F(KeySystemConfigSelectorTest, InitDataTypes_SubsetSupported) { + key_systems_->init_data_type_webm_supported_ = true; + + std::vector<EmeInitDataType> init_data_types; + init_data_types.push_back(EmeInitDataType::UNKNOWN); + init_data_types.push_back(EmeInitDataType::CENC); + init_data_types.push_back(EmeInitDataType::WEBM); + + auto config = UsableConfiguration(); + config.init_data_types = init_data_types; + configs_.push_back(config); + + SelectConfigReturnsConfig(); + ASSERT_EQ(1u, config_.init_data_types.size()); + EXPECT_EQ(EmeInitDataType::WEBM, config_.init_data_types[0]); +} + +// --- distinctiveIdentifier --- + +TEST_F(KeySystemConfigSelectorTest, DistinctiveIdentifier_Default) { + key_systems_->distinctive_identifier = EmeFeatureSupport::REQUESTABLE; + + auto config = UsableConfiguration(); + config.distinctive_identifier = MediaKeysRequirement::kOptional; + configs_.push_back(config); + + SelectConfigReturnsConfig(); + EXPECT_EQ(MediaKeysRequirement::kNotAllowed, config_.distinctive_identifier); + EXPECT_FALSE(cdm_config_.allow_distinctive_identifier); +} + +TEST_F(KeySystemConfigSelectorTest, DistinctiveIdentifier_Forced) { + media_permission_->is_granted = true; + key_systems_->distinctive_identifier = EmeFeatureSupport::ALWAYS_ENABLED; + + auto config = UsableConfiguration(); + config.distinctive_identifier = MediaKeysRequirement::kOptional; + configs_.push_back(config); + + SelectConfigRequestsPermissionAndReturnsConfig(); + EXPECT_EQ(MediaKeysRequirement::kRequired, config_.distinctive_identifier); + EXPECT_TRUE(cdm_config_.allow_distinctive_identifier); +} + +TEST_F(KeySystemConfigSelectorTest, DistinctiveIdentifier_Blocked) { + key_systems_->distinctive_identifier = EmeFeatureSupport::NOT_SUPPORTED; + + auto config = UsableConfiguration(); + config.distinctive_identifier = MediaKeysRequirement::kRequired; + configs_.push_back(config); + + SelectConfigReturnsError(); +} + +TEST_F(KeySystemConfigSelectorTest, DistinctiveIdentifier_RequestsPermission) { + media_permission_->is_granted = true; + key_systems_->distinctive_identifier = EmeFeatureSupport::REQUESTABLE; + + auto config = UsableConfiguration(); + config.distinctive_identifier = MediaKeysRequirement::kRequired; + configs_.push_back(config); + + SelectConfigRequestsPermissionAndReturnsConfig(); + EXPECT_EQ(MediaKeysRequirement::kRequired, config_.distinctive_identifier); + EXPECT_TRUE(cdm_config_.allow_distinctive_identifier); +} + +TEST_F(KeySystemConfigSelectorTest, DistinctiveIdentifier_RespectsPermission) { + media_permission_->is_granted = false; + key_systems_->distinctive_identifier = EmeFeatureSupport::REQUESTABLE; + + auto config = UsableConfiguration(); + config.distinctive_identifier = MediaKeysRequirement::kRequired; + configs_.push_back(config); + + SelectConfigRequestsPermissionAndReturnsError(); +} + +TEST_F(KeySystemConfigSelectorTest, DistinctiveIdentifier_DefaultCrossOrigin) { + key_systems_->distinctive_identifier = EmeFeatureSupport::REQUESTABLE; + web_frame_delegate_->is_cross_origin_ = true; + + auto config = UsableConfiguration(); + config.distinctive_identifier = MediaKeysRequirement::kOptional; + configs_.push_back(config); + + SelectConfigReturnsConfig(); + EXPECT_EQ(MediaKeysRequirement::kNotAllowed, config_.distinctive_identifier); + EXPECT_FALSE(cdm_config_.allow_distinctive_identifier); +} + +TEST_F(KeySystemConfigSelectorTest, + DistinctiveIdentifier_ForcedBlockedByCrossOrigin) { + media_permission_->is_granted = true; + key_systems_->distinctive_identifier = EmeFeatureSupport::ALWAYS_ENABLED; + web_frame_delegate_->is_cross_origin_ = true; + + auto config = UsableConfiguration(); + config.distinctive_identifier = MediaKeysRequirement::kOptional; + configs_.push_back(config); + +#if defined(OS_ANDROID) + SelectConfigRequestsPermissionAndReturnsConfig(); + EXPECT_EQ(MediaKeysRequirement::kRequired, config_.distinctive_identifier); + EXPECT_TRUE(cdm_config_.allow_distinctive_identifier); +#else + SelectConfigReturnsError(); +#endif // defined(OS_ANDROID) +} + +TEST_F(KeySystemConfigSelectorTest, + DistinctiveIdentifier_RequestsPermissionBlockedByCrossOrigin) { + media_permission_->is_granted = true; + key_systems_->distinctive_identifier = EmeFeatureSupport::REQUESTABLE; + web_frame_delegate_->is_cross_origin_ = true; + + auto config = UsableConfiguration(); + config.distinctive_identifier = MediaKeysRequirement::kRequired; + configs_.push_back(config); + +#if defined(OS_ANDROID) + SelectConfigRequestsPermissionAndReturnsConfig(); + EXPECT_EQ(MediaKeysRequirement::kRequired, config_.distinctive_identifier); + EXPECT_TRUE(cdm_config_.allow_distinctive_identifier); +#else + SelectConfigReturnsError(); +#endif // defined(OS_ANDROID) +} + +// --- persistentState --- + +TEST_F(KeySystemConfigSelectorTest, PersistentState_Default) { + key_systems_->persistent_state = EmeFeatureSupport::REQUESTABLE; + + auto config = UsableConfiguration(); + config.persistent_state = MediaKeysRequirement::kOptional; + configs_.push_back(config); + + SelectConfigReturnsConfig(); + EXPECT_EQ(MediaKeysRequirement::kNotAllowed, config_.persistent_state); + EXPECT_FALSE(cdm_config_.allow_persistent_state); +} + +TEST_F(KeySystemConfigSelectorTest, PersistentState_Forced) { + key_systems_->persistent_state = EmeFeatureSupport::ALWAYS_ENABLED; + + auto config = UsableConfiguration(); + config.persistent_state = MediaKeysRequirement::kOptional; + configs_.push_back(config); + + SelectConfigReturnsConfig(); + EXPECT_EQ(MediaKeysRequirement::kRequired, config_.persistent_state); + EXPECT_TRUE(cdm_config_.allow_persistent_state); +} + +TEST_F(KeySystemConfigSelectorTest, PersistentState_Required) { + key_systems_->persistent_state = EmeFeatureSupport::REQUESTABLE; + + auto config = UsableConfiguration(); + config.persistent_state = MediaKeysRequirement::kRequired; + configs_.push_back(config); + + SelectConfigReturnsConfig(); + EXPECT_EQ(MediaKeysRequirement::kRequired, config_.persistent_state); + EXPECT_TRUE(cdm_config_.allow_persistent_state); +} + +TEST_F(KeySystemConfigSelectorTest, PersistentState_Blocked) { + key_systems_->persistent_state = EmeFeatureSupport::ALWAYS_ENABLED; + + auto config = UsableConfiguration(); + config.persistent_state = MediaKeysRequirement::kNotAllowed; + configs_.push_back(config); + + SelectConfigReturnsError(); +} + +TEST_F(KeySystemConfigSelectorTest, PersistentState_BlockedByContentSettings) { + key_systems_->persistent_state = EmeFeatureSupport::ALWAYS_ENABLED; + + auto config = UsableConfiguration(); + config.persistent_state = MediaKeysRequirement::kRequired; + configs_.push_back(config); + + web_frame_delegate_->local_storage_allowed_ = false; + SelectConfigReturnsError(); +} + +TEST_F(KeySystemConfigSelectorTest, + PersistentState_ForcedBlockedByContentSettings) { + key_systems_->persistent_state = EmeFeatureSupport::ALWAYS_ENABLED; + + auto config = UsableConfiguration(); + config.persistent_state = MediaKeysRequirement::kOptional; + configs_.push_back(config); + + web_frame_delegate_->local_storage_allowed_ = false; + SelectConfigReturnsError(); +} + +TEST_F(KeySystemConfigSelectorTest, + PersistentState_RequiredBlockedByContentSettings) { + key_systems_->persistent_state = EmeFeatureSupport::REQUESTABLE; + + auto config = UsableConfiguration(); + config.persistent_state = MediaKeysRequirement::kRequired; + configs_.push_back(config); + + web_frame_delegate_->local_storage_allowed_ = false; + SelectConfigReturnsError(); +} + +// --- sessionTypes --- + +TEST_F(KeySystemConfigSelectorTest, SessionTypes_Empty) { + auto config = UsableConfiguration(); + + // Usable configuration has [ "temporary" ]. + std::vector<WebEncryptedMediaSessionType> session_types; + config.session_types = session_types; + + configs_.push_back(config); + + SelectConfigReturnsConfig(); + EXPECT_TRUE(config_.session_types.empty()); +} + +TEST_F(KeySystemConfigSelectorTest, SessionTypes_SubsetSupported) { + // Allow persistent state, as it would be required to be successful. + key_systems_->persistent_state = EmeFeatureSupport::REQUESTABLE; + key_systems_->persistent_license = EmeSessionTypeSupport::NOT_SUPPORTED; + + std::vector<WebEncryptedMediaSessionType> session_types; + session_types.push_back(WebEncryptedMediaSessionType::kTemporary); + session_types.push_back(WebEncryptedMediaSessionType::kPersistentLicense); + + auto config = UsableConfiguration(); + config.session_types = session_types; + configs_.push_back(config); + + SelectConfigReturnsError(); +} + +TEST_F(KeySystemConfigSelectorTest, SessionTypes_AllSupported) { + // Allow persistent state, and expect it to be required. + key_systems_->persistent_state = EmeFeatureSupport::REQUESTABLE; + key_systems_->persistent_license = EmeSessionTypeSupport::SUPPORTED; + + std::vector<WebEncryptedMediaSessionType> session_types; + session_types.push_back(WebEncryptedMediaSessionType::kTemporary); + session_types.push_back(WebEncryptedMediaSessionType::kPersistentLicense); + + auto config = UsableConfiguration(); + config.persistent_state = MediaKeysRequirement::kOptional; + config.session_types = session_types; + configs_.push_back(config); + + SelectConfigReturnsConfig(); + EXPECT_EQ(MediaKeysRequirement::kRequired, config_.persistent_state); + ASSERT_EQ(2u, config_.session_types.size()); + EXPECT_EQ(WebEncryptedMediaSessionType::kTemporary, config_.session_types[0]); + EXPECT_EQ(WebEncryptedMediaSessionType::kPersistentLicense, + config_.session_types[1]); +} + +TEST_F(KeySystemConfigSelectorTest, SessionTypes_PermissionCanBeRequired) { + media_permission_->is_granted = true; + key_systems_->distinctive_identifier = EmeFeatureSupport::REQUESTABLE; + key_systems_->persistent_state = EmeFeatureSupport::REQUESTABLE; + key_systems_->persistent_license = + EmeSessionTypeSupport::SUPPORTED_WITH_IDENTIFIER; + + std::vector<WebEncryptedMediaSessionType> session_types; + session_types.push_back(WebEncryptedMediaSessionType::kPersistentLicense); + + auto config = UsableConfiguration(); + config.distinctive_identifier = MediaKeysRequirement::kOptional; + config.persistent_state = MediaKeysRequirement::kOptional; + config.session_types = session_types; + configs_.push_back(config); + + SelectConfigRequestsPermissionAndReturnsConfig(); + EXPECT_EQ(MediaKeysRequirement::kRequired, config_.distinctive_identifier); +} + +// --- videoCapabilities --- + +TEST_F(KeySystemConfigSelectorTest, VideoCapabilities_Empty) { + auto config = UsableConfiguration(); + configs_.push_back(config); + + SelectConfigReturnsConfig(); +} + +TEST_F(KeySystemConfigSelectorTest, VideoCapabilities_ExtendedCodec) { + std::vector<WebMediaKeySystemMediaCapability> video_capabilities(1); + video_capabilities[0].content_type = "a"; + video_capabilities[0].mime_type = kSupportedVideoContainer; + video_capabilities[0].codecs = kExtendedVideoCodec; + + auto config = EmptyConfiguration(); + config.video_capabilities = video_capabilities; + configs_.push_back(config); + + SelectConfigReturnsConfig(); +} + +TEST_F(KeySystemConfigSelectorTest, VideoCapabilities_InvalidContainer) { + std::vector<WebMediaKeySystemMediaCapability> video_capabilities(1); + video_capabilities[0].content_type = "a"; + video_capabilities[0].mime_type = kInvalidContainer; + video_capabilities[0].codecs = kSupportedVideoCodec; + + auto config = EmptyConfiguration(); + config.video_capabilities = video_capabilities; + configs_.push_back(config); + + SelectConfigReturnsError(); +} + +TEST_F(KeySystemConfigSelectorTest, VideoCapabilities_UnsupportedContainer) { + std::vector<WebMediaKeySystemMediaCapability> video_capabilities(1); + video_capabilities[0].content_type = "a"; + video_capabilities[0].mime_type = kUnsupportedContainer; + video_capabilities[0].codecs = kSupportedVideoCodec; + + auto config = EmptyConfiguration(); + config.video_capabilities = video_capabilities; + configs_.push_back(config); + + SelectConfigReturnsError(); +} + +TEST_F(KeySystemConfigSelectorTest, VideoCapabilities_IncompatibleContainer) { + std::vector<WebMediaKeySystemMediaCapability> video_capabilities(1); + video_capabilities[0].content_type = "a"; + video_capabilities[0].mime_type = kSupportedAudioContainer; + video_capabilities[0].codecs = kSupportedVideoCodec; + + auto config = EmptyConfiguration(); + config.video_capabilities = video_capabilities; + configs_.push_back(config); + + SelectConfigReturnsError(); +} + +TEST_F(KeySystemConfigSelectorTest, VideoCapabilities_InvalidCodec) { + std::vector<WebMediaKeySystemMediaCapability> video_capabilities(1); + video_capabilities[0].content_type = "a"; + video_capabilities[0].mime_type = kSupportedVideoContainer; + video_capabilities[0].codecs = kInvalidCodec; + + auto config = EmptyConfiguration(); + config.video_capabilities = video_capabilities; + configs_.push_back(config); + + SelectConfigReturnsError(); +} + +TEST_F(KeySystemConfigSelectorTest, VideoCapabilities_UnsupportedCodec) { + std::vector<WebMediaKeySystemMediaCapability> video_capabilities(1); + video_capabilities[0].content_type = "a"; + video_capabilities[0].mime_type = kInvalidContainer; + video_capabilities[0].codecs = kUnsupportedCodec; + + auto config = EmptyConfiguration(); + config.video_capabilities = video_capabilities; + configs_.push_back(config); + + SelectConfigReturnsError(); +} + +TEST_F(KeySystemConfigSelectorTest, VideoCapabilities_IncompatibleCodec) { + std::vector<WebMediaKeySystemMediaCapability> video_capabilities(1); + video_capabilities[0].content_type = "a"; + video_capabilities[0].mime_type = kSupportedVideoContainer; + video_capabilities[0].codecs = kSupportedAudioCodec; + + auto config = EmptyConfiguration(); + config.video_capabilities = video_capabilities; + configs_.push_back(config); + + SelectConfigReturnsError(); +} + +TEST_F(KeySystemConfigSelectorTest, + VideoCapabilities_UnsupportedByAesDecryptorCodec_ClearKey) { + key_system_ = kClearKeyKeySystem; + + std::vector<WebMediaKeySystemMediaCapability> video_capabilities(1); + video_capabilities[0].content_type = "a"; + video_capabilities[0].mime_type = kSupportedVideoContainer; + video_capabilities[0].codecs = kUnsupportedByAesDecryptorCodec; + + auto config = EmptyConfiguration(); + config.video_capabilities = video_capabilities; + configs_.push_back(config); + + SelectConfigReturnsError(); +} + +TEST_F(KeySystemConfigSelectorTest, + VideoCapabilities_UnsupportedByAesDecryptorCodec) { + std::vector<WebMediaKeySystemMediaCapability> video_capabilities(1); + video_capabilities[0].content_type = "a"; + video_capabilities[0].mime_type = kSupportedVideoContainer; + video_capabilities[0].codecs = kUnsupportedByAesDecryptorCodec; + + auto config = EmptyConfiguration(); + config.video_capabilities = video_capabilities; + configs_.push_back(config); + + SelectConfigReturnsConfig(); + ASSERT_EQ(1u, config_.video_capabilities.size()); +} + +TEST_F(KeySystemConfigSelectorTest, VideoCapabilities_SubsetSupported) { + std::vector<WebMediaKeySystemMediaCapability> video_capabilities(2); + video_capabilities[0].content_type = "a"; + video_capabilities[0].mime_type = kInvalidContainer; + video_capabilities[1].content_type = "b"; + video_capabilities[1].mime_type = kSupportedVideoContainer; + video_capabilities[1].codecs = kSupportedVideoCodec; + + auto config = EmptyConfiguration(); + config.video_capabilities = video_capabilities; + configs_.push_back(config); + + SelectConfigReturnsConfig(); + ASSERT_EQ(1u, config_.video_capabilities.size()); + EXPECT_EQ("b", config_.video_capabilities[0].content_type); + EXPECT_EQ(kSupportedVideoContainer, config_.video_capabilities[0].mime_type); +} + +TEST_F(KeySystemConfigSelectorTest, VideoCapabilities_AllSupported) { + std::vector<WebMediaKeySystemMediaCapability> video_capabilities(2); + video_capabilities[0].content_type = "a"; + video_capabilities[0].mime_type = kSupportedVideoContainer; + video_capabilities[0].codecs = GetSupportedVideoCodecs(); + video_capabilities[1].content_type = "b"; + video_capabilities[1].mime_type = kSupportedVideoContainer; + video_capabilities[1].codecs = GetSupportedVideoCodecs(); + + auto config = EmptyConfiguration(); + config.video_capabilities = video_capabilities; + configs_.push_back(config); + + SelectConfigReturnsConfig(); + ASSERT_EQ(2u, config_.video_capabilities.size()); + EXPECT_EQ("a", config_.video_capabilities[0].content_type); + EXPECT_EQ("b", config_.video_capabilities[1].content_type); +} + +// --- videoCapabilities Codecs --- + +TEST_F(KeySystemConfigSelectorTest, VideoCapabilities_Codecs_SubsetInvalid) { + std::vector<WebMediaKeySystemMediaCapability> video_capabilities(1); + video_capabilities[0].content_type = "a"; + video_capabilities[0].mime_type = kSupportedVideoContainer; + video_capabilities[0].codecs = GetSubsetInvalidVideoCodecs(); + + auto config = EmptyConfiguration(); + config.video_capabilities = video_capabilities; + configs_.push_back(config); + + SelectConfigReturnsError(); +} + +TEST_F(KeySystemConfigSelectorTest, VideoCapabilities_Codecs_SubsetSupported) { + std::vector<WebMediaKeySystemMediaCapability> video_capabilities(1); + video_capabilities[0].content_type = "a"; + video_capabilities[0].mime_type = kSupportedVideoContainer; + video_capabilities[0].codecs = GetSubsetSupportedVideoCodecs(); + + auto config = EmptyConfiguration(); + config.video_capabilities = video_capabilities; + configs_.push_back(config); + + SelectConfigReturnsError(); +} + +TEST_F(KeySystemConfigSelectorTest, VideoCapabilities_Codecs_AllSupported) { + std::vector<WebMediaKeySystemMediaCapability> video_capabilities(1); + video_capabilities[0].content_type = "a"; + video_capabilities[0].mime_type = kSupportedVideoContainer; + video_capabilities[0].codecs = GetSupportedVideoCodecs(); + + auto config = EmptyConfiguration(); + config.video_capabilities = video_capabilities; + configs_.push_back(config); + + SelectConfigReturnsConfig(); + ASSERT_EQ(1u, config_.video_capabilities.size()); + EXPECT_EQ(GetSupportedVideoCodecs(), config_.video_capabilities[0].codecs); +} + +TEST_F(KeySystemConfigSelectorTest, VideoCapabilities_Missing_Codecs) { + std::vector<WebMediaKeySystemMediaCapability> video_capabilities(1); + video_capabilities[0].content_type = "a"; + video_capabilities[0].mime_type = kSupportedVideoContainer; + + auto config = EmptyConfiguration(); + config.video_capabilities = video_capabilities; + configs_.push_back(config); + + SelectConfigReturnsError(); +} + +// --- videoCapabilities Robustness --- + +TEST_F(KeySystemConfigSelectorTest, VideoCapabilities_Robustness_Empty) { + std::vector<WebMediaKeySystemMediaCapability> video_capabilities(1); + video_capabilities[0].content_type = "a"; + video_capabilities[0].mime_type = kSupportedVideoContainer; + video_capabilities[0].codecs = kSupportedVideoCodec; + ASSERT_TRUE(video_capabilities[0].robustness.IsEmpty()); + + auto config = EmptyConfiguration(); + config.video_capabilities = video_capabilities; + configs_.push_back(config); + + SelectConfigReturnsConfig(); + ASSERT_EQ(1u, config_.video_capabilities.size()); + EXPECT_TRUE(config_.video_capabilities[0].robustness.IsEmpty()); +} + +TEST_F(KeySystemConfigSelectorTest, VideoCapabilities_Robustness_Supported) { + std::vector<WebMediaKeySystemMediaCapability> video_capabilities(1); + video_capabilities[0].content_type = "a"; + video_capabilities[0].mime_type = kSupportedVideoContainer; + video_capabilities[0].codecs = kSupportedVideoCodec; + video_capabilities[0].robustness = kSupportedRobustness; + + auto config = EmptyConfiguration(); + config.video_capabilities = video_capabilities; + configs_.push_back(config); + + SelectConfigReturnsConfig(); + ASSERT_EQ(1u, config_.video_capabilities.size()); + EXPECT_EQ(kSupportedRobustness, config_.video_capabilities[0].robustness); +} + +TEST_F(KeySystemConfigSelectorTest, VideoCapabilities_Robustness_Unsupported) { + std::vector<WebMediaKeySystemMediaCapability> video_capabilities(1); + video_capabilities[0].content_type = "a"; + video_capabilities[0].mime_type = kSupportedVideoContainer; + video_capabilities[0].codecs = kSupportedVideoCodec; + video_capabilities[0].robustness = kUnsupportedRobustness; + + auto config = EmptyConfiguration(); + config.video_capabilities = video_capabilities; + configs_.push_back(config); + + SelectConfigReturnsError(); +} + +TEST_F(KeySystemConfigSelectorTest, + VideoCapabilities_Robustness_PermissionCanBeRequired) { + media_permission_->is_granted = true; + key_systems_->distinctive_identifier = EmeFeatureSupport::REQUESTABLE; + + std::vector<WebMediaKeySystemMediaCapability> video_capabilities(1); + video_capabilities[0].content_type = "a"; + video_capabilities[0].mime_type = kSupportedVideoContainer; + video_capabilities[0].codecs = kSupportedVideoCodec; + video_capabilities[0].robustness = kRequireIdentifierRobustness; + + auto config = EmptyConfiguration(); + config.video_capabilities = video_capabilities; + configs_.push_back(config); + + SelectConfigRequestsPermissionAndReturnsConfig(); + EXPECT_EQ(MediaKeysRequirement::kRequired, config_.distinctive_identifier); +} + +TEST_F(KeySystemConfigSelectorTest, + VideoCapabilities_Robustness_PermissionCanBeRecommended) { + media_permission_->is_granted = false; + key_systems_->distinctive_identifier = EmeFeatureSupport::REQUESTABLE; + + std::vector<WebMediaKeySystemMediaCapability> video_capabilities(1); + video_capabilities[0].content_type = "a"; + video_capabilities[0].mime_type = kSupportedVideoContainer; + video_capabilities[0].codecs = kSupportedVideoCodec; + video_capabilities[0].robustness = kRecommendIdentifierRobustness; + + auto config = EmptyConfiguration(); + config.video_capabilities = video_capabilities; + configs_.push_back(config); + + SelectConfigRequestsPermissionAndReturnsConfig(); + EXPECT_EQ(MediaKeysRequirement::kNotAllowed, config_.distinctive_identifier); +} + +TEST_F(KeySystemConfigSelectorTest, + VideoCapabilities_Robustness_PermissionCanBeRecommendedAndGranted) { + media_permission_->is_granted = true; + key_systems_->distinctive_identifier = EmeFeatureSupport::REQUESTABLE; + + std::vector<WebMediaKeySystemMediaCapability> video_capabilities(1); + video_capabilities[0].content_type = "a"; + video_capabilities[0].mime_type = kSupportedVideoContainer; + video_capabilities[0].codecs = kSupportedVideoCodec; + video_capabilities[0].robustness = kRecommendIdentifierRobustness; + + auto config = EmptyConfiguration(); + config.video_capabilities = video_capabilities; + configs_.push_back(config); + + SelectConfigRequestsPermissionAndReturnsConfig(); + EXPECT_EQ(MediaKeysRequirement::kRequired, config_.distinctive_identifier); +} + +TEST_F(KeySystemConfigSelectorTest, + VideoCapabilities_Robustness_NoPermissionRecommendedCrossOrigin) { + key_systems_->distinctive_identifier = EmeFeatureSupport::REQUESTABLE; + web_frame_delegate_->is_cross_origin_ = true; + + std::vector<WebMediaKeySystemMediaCapability> video_capabilities(1); + video_capabilities[0].content_type = "a"; + video_capabilities[0].mime_type = kSupportedVideoContainer; + video_capabilities[0].codecs = kSupportedVideoCodec; + video_capabilities[0].robustness = kRecommendIdentifierRobustness; + + auto config = EmptyConfiguration(); + config.video_capabilities = video_capabilities; + configs_.push_back(config); + +#if defined(OS_ANDROID) + SelectConfigRequestsPermissionAndReturnsConfig(); +#else + SelectConfigReturnsConfig(); +#endif // defined(OS_ANDROID) + EXPECT_EQ(MediaKeysRequirement::kNotAllowed, config_.distinctive_identifier); + ASSERT_EQ(1u, config_.video_capabilities.size()); +} + +TEST_F(KeySystemConfigSelectorTest, + VideoCapabilities_EncryptionScheme_Supported) { + std::vector<WebMediaKeySystemMediaCapability> video_capabilities(1); + video_capabilities[0].content_type = "a"; + video_capabilities[0].mime_type = kSupportedVideoContainer; + video_capabilities[0].codecs = kSupportedVideoCodec; + video_capabilities[0].encryption_scheme = kSupportedEncryptionScheme; + + WebMediaKeySystemConfiguration config = EmptyConfiguration(); + config.video_capabilities = video_capabilities; + configs_.push_back(config); + + SelectConfigReturnsConfig(); + ASSERT_EQ(1u, config_.video_capabilities.size()); + EXPECT_EQ(kSupportedEncryptionScheme, + config_.video_capabilities[0].encryption_scheme); +} + +TEST_F(KeySystemConfigSelectorTest, + VideoCapabilities_EncryptionScheme_DisallowHwSecureCodec) { + std::vector<WebMediaKeySystemMediaCapability> video_capabilities(1); + video_capabilities[0].content_type = "a"; + video_capabilities[0].mime_type = kSupportedVideoContainer; + video_capabilities[0].codecs = kSupportedVideoCodec; + video_capabilities[0].encryption_scheme = + kDisallowHwSecureCodecEncryptionScheme; + + WebMediaKeySystemConfiguration config = EmptyConfiguration(); + config.video_capabilities = video_capabilities; + configs_.push_back(config); + + SelectConfigReturnsConfig(); + ASSERT_EQ(1u, config_.video_capabilities.size()); + EXPECT_EQ(kDisallowHwSecureCodecEncryptionScheme, + config_.video_capabilities[0].encryption_scheme); +} + +// --- HW Secure Codecs and Robustness --- + +TEST_F(KeySystemConfigSelectorTest, HwSecureCodec_RequireHwSecureCodec) { + std::vector<WebMediaKeySystemMediaCapability> video_capabilities(1); + video_capabilities[0].content_type = "a"; + video_capabilities[0].mime_type = kSupportedVideoContainer; + video_capabilities[0].codecs = kRequireHwSecureCodec; + + auto config = EmptyConfiguration(); + config.video_capabilities = video_capabilities; + configs_.push_back(config); + + SelectConfigReturnsConfig(); + EXPECT_TRUE(cdm_config_.use_hw_secure_codecs); +} + +TEST_F(KeySystemConfigSelectorTest, HwSecureCodec_DisallowHwSecureCodec) { + std::vector<WebMediaKeySystemMediaCapability> video_capabilities(1); + video_capabilities[0].content_type = "a"; + video_capabilities[0].mime_type = kSupportedVideoContainer; + video_capabilities[0].codecs = kDisallowHwSecureCodec; + + auto config = EmptyConfiguration(); + config.video_capabilities = video_capabilities; + configs_.push_back(config); + + SelectConfigReturnsConfig(); + EXPECT_FALSE(cdm_config_.use_hw_secure_codecs); +} + +TEST_F(KeySystemConfigSelectorTest, + HwSecureCodec_IncompatibleCodecAndRobustness) { + std::vector<WebMediaKeySystemMediaCapability> video_capabilities(1); + video_capabilities[0].content_type = "a"; + video_capabilities[0].mime_type = kSupportedVideoContainer; + video_capabilities[0].codecs = kDisallowHwSecureCodec; + video_capabilities[0].robustness = kRequireHwSecureCodecRobustness; + + auto config = EmptyConfiguration(); + config.video_capabilities = video_capabilities; + configs_.push_back(config); + + SelectConfigReturnsError(); +} + +TEST_F(KeySystemConfigSelectorTest, HwSecureCodec_CompatibleCodecs) { + std::vector<WebMediaKeySystemMediaCapability> video_capabilities(1); + video_capabilities[0].content_type = "a"; + video_capabilities[0].mime_type = kSupportedVideoContainer; + video_capabilities[0].codecs = + MakeCodecs(kRequireHwSecureCodec, kSupportedVideoCodec); + + auto config = EmptyConfiguration(); + config.video_capabilities = video_capabilities; + configs_.push_back(config); + + SelectConfigReturnsConfig(); + EXPECT_TRUE(cdm_config_.use_hw_secure_codecs); +} + +TEST_F(KeySystemConfigSelectorTest, HwSecureCodec_IncompatibleCodecs) { + std::vector<WebMediaKeySystemMediaCapability> video_capabilities(1); + video_capabilities[0].content_type = "a"; + video_capabilities[0].mime_type = kSupportedVideoContainer; + video_capabilities[0].codecs = + MakeCodecs(kRequireHwSecureCodec, kDisallowHwSecureCodec); + + auto config = EmptyConfiguration(); + config.video_capabilities = video_capabilities; + configs_.push_back(config); + + SelectConfigReturnsError(); +} + +TEST_F(KeySystemConfigSelectorTest, HwSecureCodec_CompatibleCapabilityCodec) { + std::vector<WebMediaKeySystemMediaCapability> video_capabilities(2); + video_capabilities[0].content_type = "require_hw_secure_codec"; + video_capabilities[0].mime_type = kSupportedVideoContainer; + video_capabilities[0].codecs = kRequireHwSecureCodec; + video_capabilities[1].content_type = "supported_video_codec"; + video_capabilities[1].mime_type = kSupportedVideoContainer; + video_capabilities[1].codecs = kSupportedVideoCodec; + + auto config = EmptyConfiguration(); + config.video_capabilities = video_capabilities; + configs_.push_back(config); + + SelectConfigReturnsConfig(); + ASSERT_EQ(2u, config_.video_capabilities.size()); + EXPECT_TRUE(cdm_config_.use_hw_secure_codecs); +} + +TEST_F(KeySystemConfigSelectorTest, HwSecureCodec_RequireAndDisallow) { + std::vector<WebMediaKeySystemMediaCapability> video_capabilities(2); + video_capabilities[0].content_type = "require_hw_secure_codec"; + video_capabilities[0].mime_type = kSupportedVideoContainer; + video_capabilities[0].codecs = kRequireHwSecureCodec; + video_capabilities[1].content_type = "disallow_hw_secure_codec"; + video_capabilities[1].mime_type = kSupportedVideoContainer; + video_capabilities[1].codecs = kDisallowHwSecureCodec; + + auto config = EmptyConfiguration(); + config.video_capabilities = video_capabilities; + configs_.push_back(config); + + SelectConfigReturnsConfig(); + ASSERT_EQ(1u, config_.video_capabilities.size()); + EXPECT_EQ("require_hw_secure_codec", + config_.video_capabilities[0].content_type); + EXPECT_TRUE(cdm_config_.use_hw_secure_codecs); +} + +TEST_F(KeySystemConfigSelectorTest, HwSecureCodec_DisallowAndRequire) { + std::vector<WebMediaKeySystemMediaCapability> video_capabilities(2); + video_capabilities[0].content_type = "disallow_hw_secure_codec"; + video_capabilities[0].mime_type = kSupportedVideoContainer; + video_capabilities[0].codecs = kDisallowHwSecureCodec; + video_capabilities[1].content_type = "require_hw_secure_codec"; + video_capabilities[1].mime_type = kSupportedVideoContainer; + video_capabilities[1].codecs = kRequireHwSecureCodec; + + auto config = EmptyConfiguration(); + config.video_capabilities = video_capabilities; + configs_.push_back(config); + + SelectConfigReturnsConfig(); + ASSERT_EQ(1u, config_.video_capabilities.size()); + EXPECT_EQ("disallow_hw_secure_codec", + config_.video_capabilities[0].content_type); + EXPECT_FALSE(cdm_config_.use_hw_secure_codecs); +} + +TEST_F(KeySystemConfigSelectorTest, HwSecureCodec_IncompatibleCapabilities) { + std::vector<WebMediaKeySystemMediaCapability> video_capabilities(2); + video_capabilities[0].content_type = "require_hw_secure_codec"; + video_capabilities[0].mime_type = kSupportedVideoContainer; + video_capabilities[0].codecs = kSupportedVideoCodec; + video_capabilities[0].robustness = kRequireHwSecureCodecRobustness; + video_capabilities[1].content_type = "disallow_hw_secure_codec"; + video_capabilities[1].mime_type = kSupportedVideoContainer; + video_capabilities[1].codecs = kDisallowHwSecureCodec; + video_capabilities[1].robustness = kUnsupportedRobustness; + + auto config = EmptyConfiguration(); + config.video_capabilities = video_capabilities; + configs_.push_back(config); + + SelectConfigReturnsConfig(); + ASSERT_EQ(1u, config_.video_capabilities.size()); + EXPECT_EQ("require_hw_secure_codec", + config_.video_capabilities[0].content_type); + EXPECT_TRUE(cdm_config_.use_hw_secure_codecs); +} + +TEST_F(KeySystemConfigSelectorTest, + HwSecureCodec_UnsupportedCapabilityNotAffectingRules) { + std::vector<WebMediaKeySystemMediaCapability> video_capabilities(2); + video_capabilities[0].content_type = "unsupported_robustness"; + video_capabilities[0].mime_type = kSupportedVideoContainer; + video_capabilities[0].codecs = kDisallowHwSecureCodec; + video_capabilities[0].robustness = kUnsupportedRobustness; + video_capabilities[1].content_type = "require_hw_secure_codec"; + video_capabilities[1].mime_type = kSupportedVideoContainer; + video_capabilities[1].codecs = kRequireHwSecureCodec; + video_capabilities[1].robustness = kRequireHwSecureCodecRobustness; + + auto config = EmptyConfiguration(); + config.video_capabilities = video_capabilities; + configs_.push_back(config); + + SelectConfigReturnsConfig(); + ASSERT_EQ(1u, config_.video_capabilities.size()); + EXPECT_EQ("require_hw_secure_codec", + config_.video_capabilities[0].content_type); + EXPECT_TRUE(cdm_config_.use_hw_secure_codecs); +} + +TEST_F(KeySystemConfigSelectorTest, HwSecureCodec_EncryptionScheme_Supported) { + std::vector<WebMediaKeySystemMediaCapability> video_capabilities(1); + video_capabilities[0].content_type = "a"; + video_capabilities[0].mime_type = kSupportedVideoContainer; + video_capabilities[0].codecs = kRequireHwSecureCodec; + video_capabilities[0].encryption_scheme = kSupportedEncryptionScheme; + + WebMediaKeySystemConfiguration config = EmptyConfiguration(); + config.video_capabilities = video_capabilities; + configs_.push_back(config); + + SelectConfigReturnsConfig(); + ASSERT_EQ(1u, config_.video_capabilities.size()); + EXPECT_EQ(kSupportedEncryptionScheme, + config_.video_capabilities[0].encryption_scheme); + EXPECT_TRUE(cdm_config_.use_hw_secure_codecs); +} + +TEST_F(KeySystemConfigSelectorTest, + HwSecureCodec_EncryptionScheme_DisallowHwSecureCodec) { + std::vector<WebMediaKeySystemMediaCapability> video_capabilities(1); + video_capabilities[0].content_type = "a"; + video_capabilities[0].mime_type = kSupportedVideoContainer; + video_capabilities[0].codecs = kRequireHwSecureCodec; + video_capabilities[0].encryption_scheme = + kDisallowHwSecureCodecEncryptionScheme; + + WebMediaKeySystemConfiguration config = EmptyConfiguration(); + config.video_capabilities = video_capabilities; + configs_.push_back(config); + + SelectConfigReturnsError(); +} + +// --- Identifier and HW Secure Robustness --- + +TEST_F(KeySystemConfigSelectorTest, + IdentifierAndHwSecureCodec_IncompatibleCodecAndRobustness) { + media_permission_->is_granted = true; + key_systems_->distinctive_identifier = EmeFeatureSupport::REQUESTABLE; + + std::vector<WebMediaKeySystemMediaCapability> video_capabilities(1); + video_capabilities[0].content_type = "a"; + video_capabilities[0].mime_type = kSupportedVideoContainer; + video_capabilities[0].codecs = kDisallowHwSecureCodec; + video_capabilities[0].robustness = + kRequireIdentifierAndHwSecureCodecRobustness; + + auto config = EmptyConfiguration(); + config.video_capabilities = video_capabilities; + configs_.push_back(config); + + SelectConfigReturnsError(); +} + +TEST_F(KeySystemConfigSelectorTest, + IdentifierAndHwSecureCodec_IncompatibleCapabilities) { + media_permission_->is_granted = true; + key_systems_->distinctive_identifier = EmeFeatureSupport::REQUESTABLE; + + std::vector<WebMediaKeySystemMediaCapability> video_capabilities(2); + video_capabilities[0].content_type = "require_hw_secure_codec"; + video_capabilities[0].mime_type = kSupportedVideoContainer; + video_capabilities[0].codecs = kSupportedVideoCodec; + video_capabilities[0].robustness = + kRequireIdentifierAndHwSecureCodecRobustness; + video_capabilities[1].content_type = "disallow_hw_secure_codec"; + video_capabilities[1].mime_type = kSupportedVideoContainer; + video_capabilities[1].codecs = kDisallowHwSecureCodec; + video_capabilities[1].robustness = kUnsupportedRobustness; + + auto config = EmptyConfiguration(); + config.video_capabilities = video_capabilities; + configs_.push_back(config); + + SelectConfigRequestsPermissionAndReturnsConfig(); + EXPECT_EQ(MediaKeysRequirement::kRequired, config_.distinctive_identifier); + ASSERT_EQ(1u, config_.video_capabilities.size()); + EXPECT_EQ("require_hw_secure_codec", + config_.video_capabilities[0].content_type); + EXPECT_TRUE(cdm_config_.use_hw_secure_codecs); +} + +TEST_F(KeySystemConfigSelectorTest, + IdentifierAndHwSecureCodec_UnsupportedCapabilityNotAffectingRules) { + media_permission_->is_granted = true; + key_systems_->distinctive_identifier = EmeFeatureSupport::REQUESTABLE; + + std::vector<WebMediaKeySystemMediaCapability> video_capabilities(2); + video_capabilities[0].content_type = "unsupported_robustness"; + video_capabilities[0].mime_type = kSupportedVideoContainer; + video_capabilities[0].codecs = kDisallowHwSecureCodec; + video_capabilities[0].robustness = kUnsupportedRobustness; + video_capabilities[1].content_type = "require_hw_secure_codec"; + video_capabilities[1].mime_type = kSupportedVideoContainer; + video_capabilities[1].codecs = kRequireHwSecureCodec; + video_capabilities[1].robustness = + kRequireIdentifierAndHwSecureCodecRobustness; + + auto config = EmptyConfiguration(); + config.video_capabilities = video_capabilities; + configs_.push_back(config); + + SelectConfigRequestsPermissionAndReturnsConfig(); + EXPECT_EQ(MediaKeysRequirement::kRequired, config_.distinctive_identifier); + ASSERT_EQ(1u, config_.video_capabilities.size()); + EXPECT_EQ("require_hw_secure_codec", + config_.video_capabilities[0].content_type); + EXPECT_TRUE(cdm_config_.use_hw_secure_codecs); +} + +TEST_F(KeySystemConfigSelectorTest, + HwSecureCodecAndIdentifier_IdentifierAndHwSecureCodecsDisjoint) { + media_permission_->is_granted = false; + key_systems_->distinctive_identifier = EmeFeatureSupport::NOT_SUPPORTED; + + std::vector<WebMediaKeySystemMediaCapability> video_capabilities(2); + video_capabilities[0].content_type = "require_hw_secure_codec"; + video_capabilities[0].mime_type = kSupportedVideoContainer; + video_capabilities[0].codecs = kRequireHwSecureCodec; + video_capabilities[0].robustness = ""; + + auto config = EmptyConfiguration(); + config.video_capabilities = video_capabilities; + configs_.push_back(config); + + SelectConfigReturnsError(); +} + +// --- Identifier, Persistence and HW Secure Robustness --- + +TEST_F(KeySystemConfigSelectorTest, + IdentifierPersistenceAndHwSecureCodec_Supported) { + media_permission_->is_granted = true; + key_systems_->persistent_state = EmeFeatureSupport::REQUESTABLE; + key_systems_->distinctive_identifier = EmeFeatureSupport::REQUESTABLE; + + std::vector<WebMediaKeySystemMediaCapability> video_capabilities(1); + video_capabilities[0].content_type = "require_hw_secure_codec"; + video_capabilities[0].mime_type = kSupportedVideoContainer; + video_capabilities[0].codecs = kSupportedVideoCodec; + video_capabilities[0].robustness = + kRequireIdentifierPersistenceAndHwSecureCodecRobustness; + + auto config = EmptyConfiguration(); + config.video_capabilities = video_capabilities; + configs_.push_back(config); + + SelectConfigRequestsPermissionAndReturnsConfig(); + EXPECT_EQ(MediaKeysRequirement::kRequired, config_.distinctive_identifier); + EXPECT_EQ(MediaKeysRequirement::kRequired, config_.persistent_state); + ASSERT_EQ(1u, config_.video_capabilities.size()); + EXPECT_EQ("require_hw_secure_codec", + config_.video_capabilities[0].content_type); + EXPECT_TRUE(cdm_config_.use_hw_secure_codecs); +} + +TEST_F(KeySystemConfigSelectorTest, + IdentifierPersistenceAndHwSecureCodec_NotSupported) { + media_permission_->is_granted = true; + key_systems_->persistent_state = EmeFeatureSupport::NOT_SUPPORTED; + key_systems_->distinctive_identifier = EmeFeatureSupport::REQUESTABLE; + + std::vector<WebMediaKeySystemMediaCapability> video_capabilities(1); + video_capabilities[0].content_type = "require_hw_secure_codec"; + video_capabilities[0].mime_type = kSupportedVideoContainer; + video_capabilities[0].codecs = kSupportedVideoCodec; + video_capabilities[0].robustness = + kRequireIdentifierPersistenceAndHwSecureCodecRobustness; + + auto config = EmptyConfiguration(); + config.video_capabilities = video_capabilities; + configs_.push_back(config); + + SelectConfigReturnsError(); +} + +// --- audioCapabilities --- +// These are handled by the same code as |videoCapabilities|, so only minimal +// additional testing is done. + +TEST_F(KeySystemConfigSelectorTest, AudioCapabilities_SubsetSupported) { + std::vector<WebMediaKeySystemMediaCapability> audio_capabilities(2); + audio_capabilities[0].content_type = "a"; + audio_capabilities[0].mime_type = kInvalidContainer; + audio_capabilities[1].content_type = "b"; + audio_capabilities[1].mime_type = kSupportedAudioContainer; + audio_capabilities[1].codecs = kSupportedAudioCodec; + + auto config = EmptyConfiguration(); + config.audio_capabilities = audio_capabilities; + configs_.push_back(config); + + SelectConfigReturnsConfig(); + ASSERT_EQ(1u, config_.audio_capabilities.size()); + EXPECT_EQ("b", config_.audio_capabilities[0].content_type); + EXPECT_EQ(kSupportedAudioContainer, config_.audio_capabilities[0].mime_type); +} + +// --- audioCapabilities and videoCapabilities --- + +TEST_F(KeySystemConfigSelectorTest, AudioAndVideoCapabilities_AllSupported) { + std::vector<WebMediaKeySystemMediaCapability> audio_capabilities(1); + audio_capabilities[0].content_type = "a"; + audio_capabilities[0].mime_type = kSupportedAudioContainer; + audio_capabilities[0].codecs = kSupportedAudioCodec; + + std::vector<WebMediaKeySystemMediaCapability> video_capabilities(1); + video_capabilities[0].content_type = "b"; + video_capabilities[0].mime_type = kSupportedVideoContainer; + video_capabilities[0].codecs = kSupportedVideoCodec; + + auto config = EmptyConfiguration(); + config.audio_capabilities = audio_capabilities; + config.video_capabilities = video_capabilities; + configs_.push_back(config); + + SelectConfigReturnsConfig(); + ASSERT_EQ(1u, config_.audio_capabilities.size()); + ASSERT_EQ(1u, config_.video_capabilities.size()); +} + +TEST_F(KeySystemConfigSelectorTest, + AudioAndVideoCapabilities_AudioUnsupported) { + std::vector<WebMediaKeySystemMediaCapability> audio_capabilities(1); + audio_capabilities[0].content_type = "a"; + audio_capabilities[0].mime_type = kUnsupportedContainer; + audio_capabilities[0].codecs = kSupportedAudioCodec; + + std::vector<WebMediaKeySystemMediaCapability> video_capabilities(1); + video_capabilities[0].content_type = "b"; + video_capabilities[0].mime_type = kSupportedVideoContainer; + video_capabilities[0].codecs = kSupportedVideoCodec; + + auto config = EmptyConfiguration(); + config.audio_capabilities = audio_capabilities; + config.video_capabilities = video_capabilities; + configs_.push_back(config); + + SelectConfigReturnsError(); +} + +TEST_F(KeySystemConfigSelectorTest, + AudioAndVideoCapabilities_VideoUnsupported) { + std::vector<WebMediaKeySystemMediaCapability> audio_capabilities(1); + audio_capabilities[0].content_type = "a"; + audio_capabilities[0].mime_type = kSupportedAudioContainer; + audio_capabilities[0].codecs = kSupportedAudioCodec; + + std::vector<WebMediaKeySystemMediaCapability> video_capabilities(1); + video_capabilities[0].content_type = "b"; + video_capabilities[0].mime_type = kSupportedVideoContainer; + video_capabilities[0].codecs = kUnsupportedCodec; + + auto config = EmptyConfiguration(); + config.audio_capabilities = audio_capabilities; + config.video_capabilities = video_capabilities; + configs_.push_back(config); + + SelectConfigReturnsError(); +} + +// Only "a2" and "v2" are supported types. +TEST_F(KeySystemConfigSelectorTest, AudioAndVideoCapabilities_SubsetSupported) { + std::vector<WebMediaKeySystemMediaCapability> audio_capabilities(3); + audio_capabilities[0].content_type = "a1"; + audio_capabilities[0].mime_type = kUnsupportedContainer; + audio_capabilities[0].codecs = kSupportedAudioCodec; + audio_capabilities[1].content_type = "a2"; + audio_capabilities[1].mime_type = kSupportedAudioContainer; + audio_capabilities[1].codecs = kSupportedAudioCodec; + audio_capabilities[2].content_type = "a3"; + audio_capabilities[2].mime_type = kSupportedAudioContainer; + audio_capabilities[2].codecs = kUnsupportedCodec; + + std::vector<WebMediaKeySystemMediaCapability> video_capabilities(2); + video_capabilities[0].content_type = "v1"; + video_capabilities[0].mime_type = kSupportedVideoContainer; + video_capabilities[0].codecs = kUnsupportedCodec; + video_capabilities[1].content_type = "v2"; + video_capabilities[1].mime_type = kSupportedVideoContainer; + video_capabilities[1].codecs = kSupportedVideoCodec; + + auto config = EmptyConfiguration(); + config.audio_capabilities = audio_capabilities; + config.video_capabilities = video_capabilities; + configs_.push_back(config); + + SelectConfigReturnsConfig(); + ASSERT_EQ(1u, config_.audio_capabilities.size()); + EXPECT_EQ("a2", config_.audio_capabilities[0].content_type); + ASSERT_EQ(1u, config_.video_capabilities.size()); + EXPECT_EQ("v2", config_.video_capabilities[0].content_type); +} + +// --- Multiple configurations --- + +TEST_F(KeySystemConfigSelectorTest, Configurations_AllSupported) { + auto config = UsableConfiguration(); + config.label = "a"; + configs_.push_back(config); + config.label = "b"; + configs_.push_back(config); + + SelectConfigReturnsConfig(); + ASSERT_EQ("a", config_.label); +} + +TEST_F(KeySystemConfigSelectorTest, Configurations_SubsetSupported) { + auto config1 = UsableConfiguration(); + config1.label = "a"; + std::vector<EmeInitDataType> init_data_types; + init_data_types.push_back(EmeInitDataType::UNKNOWN); + config1.init_data_types = init_data_types; + configs_.push_back(config1); + + auto config2 = UsableConfiguration(); + config2.label = "b"; + configs_.push_back(config2); + + SelectConfigReturnsConfig(); + ASSERT_EQ("b", config_.label); +} + +TEST_F(KeySystemConfigSelectorTest, + Configurations_FirstRequiresPermission_Allowed) { + media_permission_->is_granted = true; + key_systems_->distinctive_identifier = EmeFeatureSupport::REQUESTABLE; + + auto config1 = UsableConfiguration(); + config1.label = "a"; + config1.distinctive_identifier = MediaKeysRequirement::kRequired; + configs_.push_back(config1); + + auto config2 = UsableConfiguration(); + config2.label = "b"; + configs_.push_back(config2); + + SelectConfigRequestsPermissionAndReturnsConfig(); + ASSERT_EQ("a", config_.label); +} + +TEST_F(KeySystemConfigSelectorTest, + Configurations_FirstRequiresPermission_Rejected) { + media_permission_->is_granted = false; + key_systems_->distinctive_identifier = EmeFeatureSupport::REQUESTABLE; + + auto config1 = UsableConfiguration(); + config1.label = "a"; + config1.distinctive_identifier = MediaKeysRequirement::kRequired; + configs_.push_back(config1); + + auto config2 = UsableConfiguration(); + config2.label = "b"; + configs_.push_back(config2); + + SelectConfigRequestsPermissionAndReturnsConfig(); + ASSERT_EQ("b", config_.label); +} + +} // namespace blink |