Commit f6750f79 authored by Xiaohan Wang's avatar Xiaohan Wang Committed by Commit Bot

media: Add supported session types in CdmInfo

This is more consistent with how other capabilities are passed along.

Bug: 848532
Test: No new functionality
Change-Id: Ib0ec5f979c9d183950fcaa6424729a027c5e5ef5
Reviewed-on: https://chromium-review.googlesource.com/1109739Reviewed-by: default avatarFrank Liberato <liberato@chromium.org>
Reviewed-by: default avatarAlex Moshchuk <alexmos@chromium.org>
Reviewed-by: default avatarLei Zhang <thestig@chromium.org>
Commit-Queue: Xiaohan Wang <xhwang@chromium.org>
Cr-Commit-Position: refs/heads/master@{#569412}
parent 4bd33d22
......@@ -327,14 +327,22 @@ void RegisterWidevineCdmWithChrome(
VLOG(1) << "Register Widevine CDM with Chrome";
// Temporary session is always supported.
base::flat_set<media::CdmSessionType> supported_session_types = {
media::CdmSessionType::TEMPORARY_SESSION};
if (supports_persistent_license) {
supported_session_types.insert(
media::CdmSessionType::PERSISTENT_LICENSE_SESSION);
}
const base::FilePath cdm_path =
GetPlatformDirectory(cdm_install_dir)
.AppendASCII(base::GetNativeLibraryName(kWidevineCdmLibraryName));
CdmRegistry::GetInstance()->RegisterCdm(content::CdmInfo(
kWidevineCdmDisplayName, kWidevineCdmGuid, cdm_version, cdm_path,
kWidevineCdmFileSystemId, supported_video_codecs,
supports_persistent_license, supported_encryption_schemes,
kWidevineKeySystem, false));
kWidevineCdmFileSystemId, supported_video_codecs, supported_session_types,
supported_encryption_schemes, kWidevineKeySystem, false));
}
} // namespace
......
......@@ -541,10 +541,18 @@ void ChromeContentClient::AddContentDecryptionModules(
const base::Version version(WIDEVINE_CDM_VERSION_STRING);
DCHECK(version.IsValid());
// Temporary session is always supported.
base::flat_set<media::CdmSessionType> supported_session_types = {
media::CdmSessionType::TEMPORARY_SESSION};
if (supports_persistent_license) {
supported_session_types.insert(
media::CdmSessionType::PERSISTENT_LICENSE_SESSION);
}
cdms->push_back(content::CdmInfo(
kWidevineCdmDisplayName, kWidevineCdmGuid, version, cdm_path,
kWidevineCdmFileSystemId, video_codecs_supported,
supports_persistent_license, encryption_modes_supported,
supported_session_types, encryption_modes_supported,
kWidevineKeySystem, false));
}
#endif // defined(WIDEVINE_CDM_AVAILABLE_NOT_COMPONENT)
......@@ -562,8 +570,6 @@ void ChromeContentClient::AddContentDecryptionModules(
// A variant of ECK key system that has a different GUID.
const char kExternalClearKeyDifferentGuidTestKeySystem[] =
"org.chromium.externalclearkey.differentguid";
// ECK implementation supports persistent licenses.
constexpr bool supports_persistent_license = true;
// Register kExternalClearKeyDifferentGuidTestKeySystem first separately.
// Otherwise, it'll be treated as a sub-key-system of normal
......@@ -572,7 +578,9 @@ void ChromeContentClient::AddContentDecryptionModules(
cdms->push_back(content::CdmInfo(
media::kClearKeyCdmDisplayName, media::kClearKeyCdmDifferentGuid,
base::Version("0.1.0.0"), clear_key_cdm_path,
media::kClearKeyCdmFileSystemId, {}, supports_persistent_license,
media::kClearKeyCdmFileSystemId, {},
{media::CdmSessionType::TEMPORARY_SESSION,
media::CdmSessionType::PERSISTENT_LICENSE_SESSION},
{media::EncryptionMode::kCenc, media::EncryptionMode::kCbcs},
kExternalClearKeyDifferentGuidTestKeySystem, false));
......@@ -580,7 +588,9 @@ void ChromeContentClient::AddContentDecryptionModules(
cdms->push_back(content::CdmInfo(
media::kClearKeyCdmDisplayName, media::kClearKeyCdmGuid,
base::Version("0.1.0.0"), clear_key_cdm_path,
media::kClearKeyCdmFileSystemId, {}, supports_persistent_license,
media::kClearKeyCdmFileSystemId, {},
{media::CdmSessionType::TEMPORARY_SESSION,
media::CdmSessionType::PERSISTENT_LICENSE_SESSION},
{media::EncryptionMode::kCenc, media::EncryptionMode::kCbcs},
kExternalClearKeyKeySystem, true));
}
......
......@@ -21,6 +21,12 @@
namespace content {
namespace {
using VideoCodec = media::VideoCodec;
using EncryptionMode = media::EncryptionMode;
using CdmSessionType = media::CdmSessionType;
const char kTestCdmName[] = "Test CDM";
const char kAlternateCdmName[] = "Alternate CDM";
const char kTestCdmGuid[] = "62FE9C4B-384E-48FD-B28A-9F6F248BC8CC";
......@@ -30,6 +36,28 @@ const char kVersion2[] = "1.1.1.2";
const char kTestKeySystem[] = "com.example.somesystem";
const char kTestFileSystemId[] = "file_system_id";
// Helper function to compare a STL container to an initializer_list.
template <typename Container, typename T>
bool StlEquals(const Container a, std::initializer_list<T> b) {
return a == Container(b);
}
#define EXPECT_STL_EQ(a, ...) \
do { \
EXPECT_TRUE(StlEquals(a, {__VA_ARGS__})); \
} while (false)
#define EXPECT_VIDEO_CODECS(...) \
EXPECT_STL_EQ(cdm.supported_video_codecs, __VA_ARGS__)
#define EXPECT_ENCRYPTION_SCHEMES(...) \
EXPECT_STL_EQ(cdm.supported_encryption_schemes, __VA_ARGS__)
#define EXPECT_SESSION_TYPES(...) \
EXPECT_STL_EQ(cdm.supported_session_types, __VA_ARGS__)
} // namespace
// For simplicity and to make failures easier to diagnose, this test uses
// std::string instead of base::FilePath and std::vector<std::string>.
class CdmRegistryImplTest : public testing::Test {
......@@ -38,19 +66,21 @@ class CdmRegistryImplTest : public testing::Test {
~CdmRegistryImplTest() override {}
protected:
void Register(const std::string& name,
const std::string& version,
const std::string& path,
const std::vector<media::VideoCodec>& supported_video_codecs,
bool supports_persistent_license,
const base::flat_set<media::EncryptionMode>& supported_modes,
std::string supported_key_system,
bool supports_sub_key_systems = false) {
cdm_registry_.RegisterCdm(CdmInfo(
name, kTestCdmGuid, base::Version(version),
base::FilePath::FromUTF8Unsafe(path), kTestFileSystemId,
supported_video_codecs, supports_persistent_license, supported_modes,
supported_key_system, supports_sub_key_systems));
void Register(
const std::string& name,
const std::string& version,
const std::string& path,
const std::vector<VideoCodec>& supported_video_codecs,
const base::flat_set<CdmSessionType>& supported_session_types,
const base::flat_set<EncryptionMode>& supported_encryption_schemes,
std::string supported_key_system,
bool supports_sub_key_systems = false) {
cdm_registry_.RegisterCdm(
CdmInfo(name, kTestCdmGuid, base::Version(version),
base::FilePath::FromUTF8Unsafe(path), kTestFileSystemId,
supported_video_codecs, supported_session_types,
supported_encryption_schemes, supported_key_system,
supports_sub_key_systems));
}
bool IsRegistered(const std::string& name, const std::string& version) {
......@@ -76,8 +106,10 @@ class CdmRegistryImplTest : public testing::Test {
TEST_F(CdmRegistryImplTest, Register) {
Register(kTestCdmName, kVersion1, kTestPath,
{media::kCodecVP8, media::kCodecVP9}, true,
{media::EncryptionMode::kCenc}, kTestKeySystem, true);
{media::kCodecVP8, media::kCodecVP9},
{CdmSessionType::TEMPORARY_SESSION,
CdmSessionType::PERSISTENT_LICENSE_SESSION},
{EncryptionMode::kCenc}, kTestKeySystem, true);
std::vector<CdmInfo> cdms = cdm_registry_.GetAllRegisteredCdms();
ASSERT_EQ(1u, cdms.size());
CdmInfo cdm = cdms[0];
......@@ -85,42 +117,45 @@ TEST_F(CdmRegistryImplTest, Register) {
EXPECT_EQ(kVersion1, cdm.version.GetString());
EXPECT_EQ(kTestPath, cdm.path.MaybeAsASCII());
EXPECT_EQ(kTestFileSystemId, cdm.file_system_id);
EXPECT_EQ(2u, cdm.supported_video_codecs.size());
EXPECT_EQ(media::kCodecVP8, cdm.supported_video_codecs[0]);
EXPECT_EQ(media::kCodecVP9, cdm.supported_video_codecs[1]);
EXPECT_TRUE(cdm.supports_persistent_license);
EXPECT_EQ(1u, cdm.supported_encryption_schemes.size());
EXPECT_EQ(
1u, cdm.supported_encryption_schemes.count(media::EncryptionMode::kCenc));
EXPECT_VIDEO_CODECS(VideoCodec::kCodecVP8, VideoCodec::kCodecVP9);
EXPECT_SESSION_TYPES(CdmSessionType::TEMPORARY_SESSION,
CdmSessionType::PERSISTENT_LICENSE_SESSION);
EXPECT_ENCRYPTION_SCHEMES(EncryptionMode::kCenc);
EXPECT_EQ(kTestKeySystem, cdm.supported_key_system);
EXPECT_TRUE(cdm.supports_sub_key_systems);
}
TEST_F(CdmRegistryImplTest, ReRegister) {
Register(kTestCdmName, kVersion1, "/bb/cc", {}, false,
{media::EncryptionMode::kCenc}, kTestKeySystem);
Register(kTestCdmName, kVersion1, "/bb/cc", {},
{CdmSessionType::TEMPORARY_SESSION}, {EncryptionMode::kCenc},
kTestKeySystem);
EXPECT_TRUE(IsRegistered(kTestCdmName, kVersion1));
// Now register same key system with different values.
Register(kTestCdmName, kVersion1, kTestPath, {}, false,
{media::EncryptionMode::kCenc}, kTestKeySystem);
Register(kTestCdmName, kVersion1, kTestPath, {},
{CdmSessionType::TEMPORARY_SESSION}, {EncryptionMode::kCenc},
kTestKeySystem);
EXPECT_TRUE(IsRegistered(kTestCdmName, kVersion1));
}
TEST_F(CdmRegistryImplTest, MultipleVersions) {
Register(kTestCdmName, kVersion1, kTestPath, {}, false,
{media::EncryptionMode::kCenc}, kTestKeySystem);
Register(kTestCdmName, kVersion2, "/bb/cc", {}, false,
{media::EncryptionMode::kCenc}, kTestKeySystem);
Register(kTestCdmName, kVersion1, kTestPath, {},
{CdmSessionType::TEMPORARY_SESSION}, {EncryptionMode::kCenc},
kTestKeySystem);
Register(kTestCdmName, kVersion2, "/bb/cc", {},
{CdmSessionType::TEMPORARY_SESSION}, {EncryptionMode::kCenc},
kTestKeySystem);
EXPECT_TRUE(IsRegistered(kTestCdmName, kVersion1));
EXPECT_TRUE(IsRegistered(kTestCdmName, kVersion2));
}
TEST_F(CdmRegistryImplTest, NewVersionInsertedLast) {
Register(kTestCdmName, kVersion1, kTestPath, {}, false,
{media::EncryptionMode::kCenc}, kTestKeySystem);
Register(kTestCdmName, kVersion2, "/bb/cc", {}, false,
{media::EncryptionMode::kCenc}, kTestKeySystem);
Register(kTestCdmName, kVersion1, kTestPath, {},
{CdmSessionType::TEMPORARY_SESSION}, {EncryptionMode::kCenc},
kTestKeySystem);
Register(kTestCdmName, kVersion2, "/bb/cc", {},
{CdmSessionType::TEMPORARY_SESSION}, {EncryptionMode::kCenc},
kTestKeySystem);
const std::vector<std::string> versions = GetVersions(kTestCdmGuid);
EXPECT_EQ(2u, versions.size());
......@@ -129,27 +164,25 @@ TEST_F(CdmRegistryImplTest, NewVersionInsertedLast) {
}
TEST_F(CdmRegistryImplTest, DifferentNames) {
Register(kTestCdmName, kVersion1, kTestPath, {}, false,
{media::EncryptionMode::kCenc}, kTestKeySystem);
Register(kAlternateCdmName, kVersion1, kTestPath, {}, false,
{media::EncryptionMode::kCbcs}, kTestKeySystem);
Register(kTestCdmName, kVersion1, kTestPath, {},
{CdmSessionType::TEMPORARY_SESSION}, {EncryptionMode::kCenc},
kTestKeySystem);
Register(kAlternateCdmName, kVersion1, kTestPath, {},
{CdmSessionType::TEMPORARY_SESSION}, {EncryptionMode::kCbcs},
kTestKeySystem);
EXPECT_TRUE(IsRegistered(kTestCdmName, kVersion1));
EXPECT_TRUE(IsRegistered(kAlternateCdmName, kVersion1));
}
TEST_F(CdmRegistryImplTest, SupportedEncryptionSchemes) {
Register(kTestCdmName, kVersion1, kTestPath, {}, false,
{media::EncryptionMode::kCenc, media::EncryptionMode::kCbcs},
kTestKeySystem);
Register(kTestCdmName, kVersion1, kTestPath, {},
{CdmSessionType::TEMPORARY_SESSION},
{EncryptionMode::kCenc, EncryptionMode::kCbcs}, kTestKeySystem);
std::vector<CdmInfo> cdms = cdm_registry_.GetAllRegisteredCdms();
ASSERT_EQ(1u, cdms.size());
const CdmInfo& cdm = cdms[0];
EXPECT_EQ(2u, cdm.supported_encryption_schemes.size());
EXPECT_EQ(
1u, cdm.supported_encryption_schemes.count(media::EncryptionMode::kCenc));
EXPECT_EQ(
1u, cdm.supported_encryption_schemes.count(media::EncryptionMode::kCbcs));
EXPECT_ENCRYPTION_SCHEMES(EncryptionMode::kCenc, EncryptionMode::kCbcs);
}
} // namespace content
......@@ -56,6 +56,11 @@ std::vector<media::VideoCodec> GetEnabledHardwareSecureCodecsFromCommandLine() {
return result;
}
template <typename T>
std::vector<T> SetToVector(const base::flat_set<T>& s) {
return std::vector<T>(s.begin(), s.end());
}
} // namespace
// static
......@@ -102,10 +107,9 @@ void KeySystemSupportImpl::IsKeySystemSupported(
// Supported codecs and encryption schemes.
auto capability = media::mojom::KeySystemCapability::New();
const auto& schemes = cdm_info->supported_encryption_schemes;
capability->video_codecs = cdm_info->supported_video_codecs;
capability->encryption_schemes =
std::vector<media::EncryptionMode>(schemes.begin(), schemes.end());
SetToVector(cdm_info->supported_encryption_schemes);
if (base::FeatureList::IsEnabled(media::kHardwareSecureDecryption)) {
capability->hw_secure_video_codecs =
......@@ -116,14 +120,7 @@ void KeySystemSupportImpl::IsKeySystemSupported(
NOTIMPLEMENTED();
}
// Temporary session is always supported.
// TODO(xhwang): Populate this from CdmInfo.
capability->session_types.push_back(media::CdmSessionType::TEMPORARY_SESSION);
if (cdm_info->supports_persistent_license) {
capability->session_types.push_back(
media::CdmSessionType::PERSISTENT_LICENSE_SESSION);
}
capability->session_types = SetToVector(cdm_info->supported_session_types);
std::move(callback).Run(true, std::move(capability));
}
......
......@@ -60,20 +60,21 @@ class KeySystemSupportTest : public testing::Test {
KeySystemSupportImpl::Create(mojo::MakeRequest(&key_system_support_));
}
// Registers |key_system| with |supported_video_codecs| and
// |supports_persistent_license|. All other values for CdmInfo have some
// default value as they're not returned by IsKeySystemSupported().
void Register(const std::string& key_system,
const std::vector<media::VideoCodec>& supported_video_codecs,
bool supports_persistent_license,
const base::flat_set<media::EncryptionMode>& supported_modes) {
// Registers |key_system| with supported capabilities. All other values for
// CdmInfo have some default value as they're not returned by
// IsKeySystemSupported().
void Register(
const std::string& key_system,
const std::vector<VideoCodec>& supported_video_codecs,
const base::flat_set<CdmSessionType>& supported_session_types,
const base::flat_set<EncryptionMode>& supported_encryption_schemes) {
DVLOG(1) << __func__;
CdmRegistry::GetInstance()->RegisterCdm(
CdmInfo(key_system, kTestCdmGuid, base::Version(kVersion),
base::FilePath::FromUTF8Unsafe(kTestPath), kTestFileSystemId,
supported_video_codecs, supports_persistent_license,
supported_modes, key_system, false));
supported_video_codecs, supported_session_types,
supported_encryption_schemes, key_system, false));
}
// Determines if |key_system| is registered. If it is, updates |codecs_|
......@@ -103,7 +104,9 @@ TEST_F(KeySystemSupportTest, NoKeySystems) {
}
TEST_F(KeySystemSupportTest, OneKeySystem) {
Register("KeySystem2", {VideoCodec::kCodecVP8}, true,
Register("KeySystem2", {VideoCodec::kCodecVP8},
{CdmSessionType::TEMPORARY_SESSION,
CdmSessionType::PERSISTENT_LICENSE_SESSION},
{EncryptionMode::kCenc, EncryptionMode::kCbcs});
EXPECT_TRUE(IsSupported("KeySystem2"));
......@@ -114,11 +117,12 @@ TEST_F(KeySystemSupportTest, OneKeySystem) {
}
TEST_F(KeySystemSupportTest, MultipleKeySystems) {
Register("KeySystem3",
{media::VideoCodec::kCodecVP8, media::VideoCodec::kCodecVP9}, true,
{media::EncryptionMode::kCenc});
Register("KeySystem4", {media::VideoCodec::kCodecVP9}, false,
{media::EncryptionMode::kCbcs});
Register("KeySystem3", {VideoCodec::kCodecVP8, VideoCodec::kCodecVP9},
{CdmSessionType::TEMPORARY_SESSION,
CdmSessionType::PERSISTENT_LICENSE_SESSION},
{EncryptionMode::kCenc});
Register("KeySystem4", {VideoCodec::kCodecVP9},
{CdmSessionType::TEMPORARY_SESSION}, {EncryptionMode::kCbcs});
EXPECT_TRUE(IsSupported("KeySystem3"));
EXPECT_VIDEO_CODECS(VideoCodec::kCodecVP8, VideoCodec::kCodecVP9);
......@@ -133,8 +137,10 @@ TEST_F(KeySystemSupportTest, MultipleKeySystems) {
}
TEST_F(KeySystemSupportTest, MissingKeySystem) {
Register("KeySystem5", {media::VideoCodec::kCodecVP8}, true,
{media::EncryptionMode::kCenc});
Register("KeySystem5", {VideoCodec::kCodecVP8},
{CdmSessionType::TEMPORARY_SESSION,
CdmSessionType::PERSISTENT_LICENSE_SESSION},
{EncryptionMode::kCenc});
EXPECT_FALSE(IsSupported("KeySystem6"));
EXPECT_FALSE(capability_);
......
......@@ -16,7 +16,7 @@ CdmInfo::CdmInfo(
const base::FilePath& path,
const std::string& file_system_id,
const std::vector<media::VideoCodec>& supported_video_codecs,
bool supports_persistent_license,
const base::flat_set<media::CdmSessionType>& supported_session_types,
const base::flat_set<media::EncryptionMode>& supported_encryption_schemes,
const std::string& supported_key_system,
bool supports_sub_key_systems)
......@@ -26,7 +26,7 @@ CdmInfo::CdmInfo(
path(path),
file_system_id(file_system_id),
supported_video_codecs(supported_video_codecs),
supports_persistent_license(supports_persistent_license),
supported_session_types(supported_session_types),
supported_encryption_schemes(supported_encryption_schemes),
supported_key_system(supported_key_system),
supports_sub_key_systems(supports_sub_key_systems) {
......
......@@ -12,6 +12,7 @@
#include "base/files/file_path.h"
#include "base/version.h"
#include "content/common/content_export.h"
#include "media/base/content_decryption_module.h"
// TODO(crbug.com/825041): Move EncryptionMode out of decrypt_config and
// rename it to EncryptionScheme.
#include "media/base/decrypt_config.h"
......@@ -28,7 +29,7 @@ struct CONTENT_EXPORT CdmInfo {
const base::FilePath& path,
const std::string& file_system_id,
const std::vector<media::VideoCodec>& supported_video_codecs,
bool supports_persistent_license,
const base::flat_set<media::CdmSessionType>& supported_session_types,
const base::flat_set<media::EncryptionMode>& supported_encryption_schemes,
const std::string& supported_key_system,
bool supports_sub_key_systems);
......@@ -60,11 +61,10 @@ struct CONTENT_EXPORT CdmInfo {
// TODO(crbug.com/796725) Find a way to include profiles and levels.
std::vector<media::VideoCodec> supported_video_codecs;
// Whether this CDM supports persistent licenses.
bool supports_persistent_license;
// List of session types supported by the CDM.
base::flat_set<media::CdmSessionType> supported_session_types;
// List of encryption schemes supported by the CDM (e.g. cenc). This is the
// set of encryption schemes that the CDM supports.
// List of encryption schemes supported by the CDM (e.g. cenc).
base::flat_set<media::EncryptionMode> supported_encryption_schemes;
// The key system supported by this CDM.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment