Source release 18.5.0
This commit is contained in:
58
cdm/cdm.gyp
58
cdm/cdm.gyp
@@ -15,6 +15,7 @@
|
||||
'variables': {
|
||||
'has_dual_key%': 'false',
|
||||
'embedded_cert%': '',
|
||||
'support_embedded_cert_functions%': 'false',
|
||||
},
|
||||
'targets': [
|
||||
{
|
||||
@@ -23,12 +24,20 @@
|
||||
'type': 'static_library',
|
||||
'standalone_static_library': 1,
|
||||
'hard_dependency': 1,
|
||||
'includes': ['../third_party/protoc.gypi'],
|
||||
'includes': ['../third_party/disable_warnings.gypi'],
|
||||
'dependencies': [ '<(proto_gen_gyp_path):generate_license_protocol' ],
|
||||
'sources': [
|
||||
'../core/src/license_protocol.proto',
|
||||
'<(proto_cc_dir)/license_protocol.pb.cc'
|
||||
],
|
||||
'variables': {
|
||||
'proto_in_dir': '../core/src',
|
||||
'include_dirs': [
|
||||
'<(proto_cc_dir)',
|
||||
'<(DEPTH)/third_party/protobuf/src'
|
||||
],
|
||||
'direct_dependent_settings': {
|
||||
'include_dirs': [
|
||||
'<(proto_cc_dir)',
|
||||
'<(DEPTH)/third_party/protobuf/src'
|
||||
]
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -37,10 +46,20 @@
|
||||
'type': 'static_library',
|
||||
'standalone_static_library': 1,
|
||||
'hard_dependency': 1,
|
||||
'includes': ['../third_party/protoc.gypi'],
|
||||
'sources': ['../core/src/device_files.proto',],
|
||||
'variables': {
|
||||
'proto_in_dir': '../core/src',
|
||||
'includes': ['../third_party/disable_warnings.gypi'],
|
||||
'dependencies': [ '<(proto_gen_gyp_path):generate_device_files' ],
|
||||
'sources': [
|
||||
'<(proto_cc_dir)/device_files.pb.cc'
|
||||
],
|
||||
'include_dirs': [
|
||||
'<(proto_cc_dir)',
|
||||
'<(DEPTH)/third_party/protobuf/src'
|
||||
],
|
||||
'direct_dependent_settings': {
|
||||
'include_dirs': [
|
||||
'<(proto_cc_dir)',
|
||||
'<(DEPTH)/third_party/protobuf/src'
|
||||
]
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -49,10 +68,20 @@
|
||||
'type': 'static_library',
|
||||
'standalone_static_library': 1,
|
||||
'hard_dependency': 1,
|
||||
'includes': ['../third_party/protoc.gypi'],
|
||||
'sources': ['../metrics/src/wv_metrics.proto',],
|
||||
'variables': {
|
||||
'proto_in_dir': '../metrics/src',
|
||||
'includes': ['../third_party/disable_warnings.gypi'],
|
||||
'dependencies': [ '<(proto_gen_gyp_path):generate_metrics_proto' ],
|
||||
'sources': [
|
||||
'<(proto_cc_dir)/wv_metrics.pb.cc'
|
||||
],
|
||||
'include_dirs': [
|
||||
'<(proto_cc_dir)',
|
||||
'<(DEPTH)/third_party/protobuf/src'
|
||||
],
|
||||
'direct_dependent_settings': {
|
||||
'include_dirs': [
|
||||
'<(proto_cc_dir)',
|
||||
'<(DEPTH)/third_party/protobuf/src'
|
||||
]
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -178,6 +207,11 @@
|
||||
'../core/src/oemcrypto_ota_stubs.cpp',
|
||||
],
|
||||
}],
|
||||
['support_embedded_cert_functions=="false"', {
|
||||
'sources': [
|
||||
'../core/src/oemcrypto_embedded_cert_stubs.cpp',
|
||||
],
|
||||
}],
|
||||
],
|
||||
}, # widevine_cdm_core target
|
||||
{
|
||||
|
||||
@@ -126,8 +126,10 @@
|
||||
'../core/test/license_request.cpp',
|
||||
'../core/test/url_request.cpp',
|
||||
'../util/src/string_conversions.cpp',
|
||||
'../util/src/string_format.cpp',
|
||||
'../util/test/test_sleep.cpp',
|
||||
'src/log.cpp',
|
||||
'src/logger_global.cpp',
|
||||
'test/perf_test.cpp',
|
||||
'test/perf_test_dynamic.cpp',
|
||||
'test/test_host.cpp',
|
||||
@@ -136,6 +138,7 @@
|
||||
'include_dirs': [
|
||||
'../core/include',
|
||||
'../core/test',
|
||||
'../oemcrypto/include',
|
||||
'../util/include',
|
||||
'../util/test',
|
||||
'include',
|
||||
|
||||
@@ -11,7 +11,9 @@
|
||||
'../core/test/cdm_engine_metrics_decorator_unittest.cpp',
|
||||
'../core/test/cdm_session_unittest.cpp',
|
||||
'../core/test/cdm_usage_table_unittest.cpp',
|
||||
'../core/test/core_integration_test.cpp',
|
||||
'../core/test/config_test_env.cpp',
|
||||
'../core/test/core_integration_test.cpp',
|
||||
'../core/test/certificate_provisioning_unittest.cpp',
|
||||
'../core/test/crypto_session_unittest.cpp',
|
||||
'../core/test/device_files_unittest.cpp',
|
||||
|
||||
@@ -137,11 +137,16 @@ class CDM_EXPORT Cdm : public ITimerClient {
|
||||
// For ease of comparison, these values are kept in ascending order by version
|
||||
// number.
|
||||
enum HdcpVersion : int32_t {
|
||||
kHdcp1_x = 0,
|
||||
kHdcp2_0 = 1,
|
||||
kHdcp2_1 = 2,
|
||||
kHdcp2_2 = 3,
|
||||
kHdcp2_3 = 4,
|
||||
kHdcp1_x = 0, // Any 1.x version
|
||||
kHdcp1_0 = 100,
|
||||
kHdcp1_1 = 101,
|
||||
kHdcp1_2 = 102,
|
||||
kHdcp1_3 = 103,
|
||||
kHdcp1_4 = 104,
|
||||
kHdcp2_0 = 200,
|
||||
kHdcp2_1 = 201,
|
||||
kHdcp2_2 = 202,
|
||||
kHdcp2_3 = 203
|
||||
};
|
||||
|
||||
// Permissible usages for a key. Returned as a set of flags; multiple
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
# define CDM_VERSION_MAJOR 18
|
||||
#endif
|
||||
#ifndef CDM_VERSION_MINOR
|
||||
# define CDM_VERSION_MINOR 1
|
||||
# define CDM_VERSION_MINOR 5
|
||||
#endif
|
||||
#ifndef CDM_VERSION_PATCH
|
||||
# define CDM_VERSION_PATCH 0
|
||||
|
||||
@@ -193,5 +193,26 @@
|
||||
'protoc_bin%': '',
|
||||
'protobuf_lib_path%': '',
|
||||
'protoc_host_path%': '',
|
||||
|
||||
# Protobuf Generation and Build configurations:
|
||||
#
|
||||
# These options allow for different build steps to be specified for proto
|
||||
# cc file generation than the default step. This can be used to customize
|
||||
# cc file generation or add additional cc file processing steps before
|
||||
# proto cc files are built.
|
||||
#
|
||||
# The directory where proto cc files that will be compiled are located.
|
||||
'proto_cc_dir%': '<(SHARED_INTERMEDIATE_DIR)/protoc_out',
|
||||
|
||||
# The directory where proto cc files generated from proto files will be
|
||||
# located.
|
||||
'proto_gen_dir%': '<(SHARED_INTERMEDIATE_DIR)/protoc_out',
|
||||
|
||||
# Path to the GYP file that contains the proto cc file generation targets.
|
||||
# This file must provide the following targets:
|
||||
# - generate_license_protocol
|
||||
# - generate_device_files
|
||||
# - generate_metrics_proto
|
||||
'proto_gen_gyp_path%': '<(DEPTH)/third_party/generate_proto_cc.gyp',
|
||||
}, # variables
|
||||
}
|
||||
|
||||
@@ -36,11 +36,6 @@
|
||||
#include "cdm_version.h"
|
||||
#include "properties_ce.h"
|
||||
|
||||
#ifdef HAS_EMBEDDED_CERT
|
||||
extern uint8_t kDeviceCert[];
|
||||
extern size_t kDeviceCertSize;
|
||||
#endif
|
||||
|
||||
namespace widevine {
|
||||
|
||||
#ifdef HAS_EMBEDDED_CERT
|
||||
@@ -151,6 +146,8 @@ class ReadOnlyStorage final : public Cdm::IStorage {
|
||||
// TODO(b/148693106): Once we have resolved the bugs causing the CDM to
|
||||
// erroneously write to read-only files, change this to an error instead of
|
||||
// a silent failure.
|
||||
(void)name;
|
||||
(void)data;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -162,6 +159,7 @@ class ReadOnlyStorage final : public Cdm::IStorage {
|
||||
// TODO(b/148693106): Once we have resolved the bugs causing the CDM to
|
||||
// erroneously write to read-only files, change this to an error instead of
|
||||
// a silent failure.
|
||||
(void)name;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -576,7 +574,21 @@ Cdm::Status CdmImpl::getStatusForHdcpVersion(Cdm::HdcpVersion hdcp,
|
||||
result = ConvertHdcpLevel(query_value, &max_hdcp);
|
||||
if (result != kSuccess) return result;
|
||||
|
||||
*key_status = (hdcp <= max_hdcp ? Cdm::kUsable : Cdm::kOutputRestricted);
|
||||
if (hdcp == kHdcp1_x && max_hdcp == kHdcp1_x) {
|
||||
// Legacy case.
|
||||
*key_status = Cdm::kUsable;
|
||||
} else if (hdcp == kHdcp1_x &&
|
||||
(max_hdcp >= kHdcp1_0 && max_hdcp <= kHdcp1_4)) {
|
||||
// CDM app is using legacy 1.x value, but OEMCrypto is using newer
|
||||
// value. Assume usable.
|
||||
*key_status = Cdm::kUsable;
|
||||
} else if (max_hdcp == kHdcp1_x && (hdcp >= kHdcp1_0 && hdcp <= kHdcp1_4)) {
|
||||
// CDM app is using new 1.x value, but OEMCrypto is using legacy
|
||||
// value. Assume usable.
|
||||
*key_status = Cdm::kUsable;
|
||||
} else {
|
||||
*key_status = (hdcp <= max_hdcp ? Cdm::kUsable : Cdm::kOutputRestricted);
|
||||
}
|
||||
}
|
||||
return kSuccess;
|
||||
}
|
||||
@@ -1355,8 +1367,19 @@ CdmSigningAlgorithm CdmImpl::ConvertSigningAlgorithm(
|
||||
|
||||
Cdm::Status CdmImpl::ConvertHdcpLevel(const std::string& query_value,
|
||||
Cdm::HdcpVersion* result) {
|
||||
if (query_value == QUERY_VALUE_HDCP_V1) {
|
||||
if (query_value == QUERY_VALUE_HDCP_V1_X) {
|
||||
// Generic HDCP level
|
||||
*result = kHdcp1_x;
|
||||
} else if (query_value == QUERY_VALUE_HDCP_V1_0) {
|
||||
*result = kHdcp1_0;
|
||||
} else if (query_value == QUERY_VALUE_HDCP_V1_1) {
|
||||
*result = kHdcp1_1;
|
||||
} else if (query_value == QUERY_VALUE_HDCP_V1_2) {
|
||||
*result = kHdcp1_2;
|
||||
} else if (query_value == QUERY_VALUE_HDCP_V1_3) {
|
||||
*result = kHdcp1_3;
|
||||
} else if (query_value == QUERY_VALUE_HDCP_V1_4) {
|
||||
*result = kHdcp1_4;
|
||||
} else if (query_value == QUERY_VALUE_HDCP_V2_0) {
|
||||
*result = kHdcp2_0;
|
||||
} else if (query_value == QUERY_VALUE_HDCP_V2_1) {
|
||||
|
||||
@@ -34,10 +34,8 @@ namespace {
|
||||
constexpr char kGlobalDumpFileName[] = "dumped_global_filesystem.dat";
|
||||
constexpr char kPerOriginDumpFileName[] = "dumped_per_origin_filesystem.dat";
|
||||
|
||||
using StorageMap = TestHost::Storage::StorageMap;
|
||||
|
||||
// Load a TestHost file system from the real file system.
|
||||
bool ReloadFileSystem(const char* file_name, StorageMap* map) {
|
||||
bool ReloadFileSystem(const char* file_name, TestHost::Storage* store) {
|
||||
std::ifstream input(file_name);
|
||||
if (input.fail()) {
|
||||
// This is OK for first pass, but an error for later passes.
|
||||
@@ -46,7 +44,7 @@ bool ReloadFileSystem(const char* file_name, StorageMap* map) {
|
||||
}
|
||||
std::string dumped_file_system((std::istreambuf_iterator<char>(input)),
|
||||
std::istreambuf_iterator<char>());
|
||||
if (!wvcdm::RebootTest::ParseDump(dumped_file_system, map)) {
|
||||
if (!store->LoadFromString(dumped_file_system)) {
|
||||
LOGE("Could not parse %s", file_name);
|
||||
return false;
|
||||
}
|
||||
@@ -54,31 +52,26 @@ bool ReloadFileSystem(const char* file_name, StorageMap* map) {
|
||||
}
|
||||
|
||||
bool ReloadFileSystems() {
|
||||
StorageMap global_map;
|
||||
StorageMap per_origin_map;
|
||||
if (!ReloadFileSystem(kGlobalDumpFileName, &global_map) ||
|
||||
!ReloadFileSystem(kPerOriginDumpFileName, &per_origin_map)) {
|
||||
return false;
|
||||
}
|
||||
g_host->global_storage().ResetFiles(global_map);
|
||||
g_host->per_origin_storage().ResetFiles(per_origin_map);
|
||||
return true;
|
||||
return ReloadFileSystem(kGlobalDumpFileName, &g_host->global_storage()) &&
|
||||
ReloadFileSystem(kPerOriginDumpFileName,
|
||||
&g_host->per_origin_storage());
|
||||
}
|
||||
|
||||
// Dump a TestHost file system to the real file system. If the dump file
|
||||
// cannot be written, this raises an exception and crashes the program. Since
|
||||
// we usually build with exceptions turned off, what this means is that the test
|
||||
// executable will halt if the file cannot be written.
|
||||
void DumpFileSystem(const char* file_name, const StorageMap& map) {
|
||||
std::string dump = wvcdm::RebootTest::DumpData(map);
|
||||
void DumpFileSystem(const char* file_name, const TestHost::Storage& store) {
|
||||
std::string dump;
|
||||
(void)store.SaveToString(&dump);
|
||||
std::ofstream output(file_name);
|
||||
output << dump;
|
||||
output.close();
|
||||
}
|
||||
|
||||
void DumpFileSystems() {
|
||||
DumpFileSystem(kGlobalDumpFileName, g_host->global_storage().files());
|
||||
DumpFileSystem(kPerOriginDumpFileName, g_host->per_origin_storage().files());
|
||||
DumpFileSystem(kGlobalDumpFileName, g_host->global_storage());
|
||||
DumpFileSystem(kPerOriginDumpFileName, g_host->per_origin_storage());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -235,6 +235,15 @@ class CdmTest : public WvCdmTestBase, public Cdm::IEventListener {
|
||||
|
||||
protected:
|
||||
void SetUp() override {
|
||||
// TODO: b/305093063 - Remove when Drm Reprovisioning server is implemented.
|
||||
// Many of these tests call EnsureProvisioned which tries to provision the
|
||||
// test device using a provisioning server. Until support is added for Drm
|
||||
// Reprovisioning on the server, skip these tests to avoid test failures.
|
||||
if (wvoec::global_features.provisioning_method ==
|
||||
OEMCrypto_DrmReprovisioning) {
|
||||
GTEST_SKIP()
|
||||
<< "Skipping until Drm Reprovisioning server support is implemented.";
|
||||
}
|
||||
WvCdmTestBase::SetUp();
|
||||
|
||||
// Clear anything stored, load default device cert.
|
||||
@@ -1462,6 +1471,12 @@ TEST_F(CdmTest, GetExpiration) {
|
||||
TEST_P(CdmTestWithRemoveParam, Remove) {
|
||||
const bool intermediate_close = GetParam();
|
||||
|
||||
// TODO: b/305093063 - Remove when Drm Reprovisioning server is implemented.
|
||||
if (wvoec::global_features.provisioning_method ==
|
||||
OEMCrypto_DrmReprovisioning) {
|
||||
GTEST_SKIP()
|
||||
<< "Skipping until Drm Reprovisioning server support is implemented.";
|
||||
}
|
||||
EnsureProvisioned();
|
||||
std::string session_id;
|
||||
ASSERT_NO_FATAL_FAILURE(
|
||||
@@ -1916,27 +1931,22 @@ TEST_F(CdmTest, GetStatusForHdcpResolution) {
|
||||
// Unfortunately, since we cannot mock the HDCP state, we cannot validate
|
||||
// the validity of the values returned here, only that meaningful values are
|
||||
// returned.
|
||||
Cdm::KeyStatus key_status;
|
||||
const std::vector<Cdm::HdcpVersion> kSupportedHdcpVersions = {
|
||||
// Legacy 1.x version
|
||||
Cdm::kHdcp1_x,
|
||||
// v17 1.x versions
|
||||
Cdm::kHdcp1_0, Cdm::kHdcp1_1, Cdm::kHdcp1_2, Cdm::kHdcp1_3, Cdm::kHdcp1_4,
|
||||
// 2.x versions.
|
||||
Cdm::kHdcp2_0, Cdm::kHdcp2_1, Cdm::kHdcp2_2, Cdm::kHdcp2_3};
|
||||
|
||||
ASSERT_EQ(Cdm::kSuccess,
|
||||
cdm_->getStatusForHdcpVersion(Cdm::kHdcp1_x, &key_status));
|
||||
EXPECT_THAT(key_status, AnyOf(Cdm::kUsable, Cdm::kOutputRestricted));
|
||||
|
||||
ASSERT_EQ(Cdm::kSuccess,
|
||||
cdm_->getStatusForHdcpVersion(Cdm::kHdcp2_0, &key_status));
|
||||
EXPECT_THAT(key_status, AnyOf(Cdm::kUsable, Cdm::kOutputRestricted));
|
||||
|
||||
ASSERT_EQ(Cdm::kSuccess,
|
||||
cdm_->getStatusForHdcpVersion(Cdm::kHdcp2_1, &key_status));
|
||||
EXPECT_THAT(key_status, AnyOf(Cdm::kUsable, Cdm::kOutputRestricted));
|
||||
|
||||
ASSERT_EQ(Cdm::kSuccess,
|
||||
cdm_->getStatusForHdcpVersion(Cdm::kHdcp2_2, &key_status));
|
||||
EXPECT_THAT(key_status, AnyOf(Cdm::kUsable, Cdm::kOutputRestricted));
|
||||
|
||||
ASSERT_EQ(Cdm::kSuccess,
|
||||
cdm_->getStatusForHdcpVersion(Cdm::kHdcp2_3, &key_status));
|
||||
EXPECT_THAT(key_status, AnyOf(Cdm::kUsable, Cdm::kOutputRestricted));
|
||||
for (const auto version : kSupportedHdcpVersions) {
|
||||
Cdm::KeyStatus key_status;
|
||||
ASSERT_EQ(Cdm::kSuccess,
|
||||
cdm_->getStatusForHdcpVersion(version, &key_status))
|
||||
<< "HDCP version: " << static_cast<int>(version);
|
||||
EXPECT_THAT(key_status, AnyOf(Cdm::kUsable, Cdm::kOutputRestricted))
|
||||
<< "HDCP version: " << static_cast<int>(version);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(CdmTest, HandlesKeyRotationWithOnlyOneLicenseRequest) {
|
||||
@@ -2162,6 +2172,12 @@ TEST_F(CdmTest, GetMetrics) {
|
||||
}
|
||||
|
||||
TEST_P(CdmTestWithDecryptParam, DecryptToClearBuffer) {
|
||||
// TODO: b/305093063 - Remove when Drm Reprovisioning server is implemented.
|
||||
if (wvoec::global_features.provisioning_method ==
|
||||
OEMCrypto_DrmReprovisioning) {
|
||||
GTEST_SKIP()
|
||||
<< "Skipping until Drm Reprovisioning server support is implemented.";
|
||||
}
|
||||
EnsureProvisioned();
|
||||
DecryptParam param = GetParam();
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
#include "config_test_env.h"
|
||||
#include "license_request.h"
|
||||
#include "logger_global.h"
|
||||
#include "test_host.h"
|
||||
#include "url_request.h"
|
||||
|
||||
@@ -29,6 +30,7 @@
|
||||
#define WALL_NOW std::chrono::high_resolution_clock::now()
|
||||
|
||||
TestHost* g_host = nullptr;
|
||||
widevine::StderrLogger g_stderr_logger;
|
||||
|
||||
namespace widevine {
|
||||
|
||||
@@ -145,6 +147,8 @@ class EventListener : public Cdm::IEventListener {
|
||||
}
|
||||
void onKeyStatusesChange(const std::string& session_id,
|
||||
bool has_new_usable_key) override {}
|
||||
void onExpirationChange(const std::string& session_id,
|
||||
int64_t new_expiration) override {}
|
||||
void onRemoveComplete(const std::string& session_id) override {}
|
||||
|
||||
std::vector<MessageInfo> messages;
|
||||
@@ -182,6 +186,10 @@ class GlobalEnv : public testing::Environment {
|
||||
: init_func_(init_func), cert_(cert) {}
|
||||
|
||||
void SetUp() override {
|
||||
// Manually set the logger because `TestHost` makes logging calls before
|
||||
// the global logger is set in |init_func_|.
|
||||
g_logger = &g_stderr_logger;
|
||||
|
||||
g_host = new TestHost;
|
||||
if (!cert_.empty()) g_host->per_origin_storage().write("cert.bin", cert_);
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ constexpr char kInitName[] =
|
||||
"_ZN8widevine3Cdm10initializeENS0_16SecureOutputTypeEPNS0_8IStorageEPNS0_"
|
||||
"6IClockEPNS0_6ITimerEPNS0_7ILoggerENS0_8LogLevelE";
|
||||
constexpr char kCreateName[] =
|
||||
"_ZN8widevine3Cdm6createEPNS0_14IEventListenerEPNS0_8IStorageEb";
|
||||
"_ZN8widevine3Cdm6createEPNS0_14IEventListenerEPNS0_8IStorageEbb";
|
||||
|
||||
bool ReadFile(const std::string& path, std::string* output) {
|
||||
constexpr size_t kReadSize = 8 * 1024;
|
||||
|
||||
@@ -8,10 +8,12 @@
|
||||
#include <unordered_set>
|
||||
|
||||
#include "cdm_version.h"
|
||||
#include "device_files.pb.h"
|
||||
#include "file_store.h"
|
||||
#include "log.h"
|
||||
|
||||
using namespace widevine;
|
||||
using video_widevine_client::sdk::SavedStorage;
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -120,6 +122,20 @@ void TestHost::Storage::Reset() {
|
||||
files_.clear();
|
||||
}
|
||||
|
||||
bool TestHost::Storage::LoadFromString(const std::string& data) {
|
||||
SavedStorage proto;
|
||||
if (!proto.ParseFromString(data)) return false;
|
||||
Reset();
|
||||
files_.insert(proto.files().begin(), proto.files().end());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TestHost::Storage::SaveToString(std::string* data) const {
|
||||
SavedStorage proto;
|
||||
proto.mutable_files()->insert(files_.begin(), files_.end());
|
||||
return proto.SerializeToString(data);
|
||||
}
|
||||
|
||||
bool TestHost::Storage::read(const std::string& name, std::string* data) {
|
||||
StorageMap::iterator it = files_.find(name);
|
||||
bool ok = it != files_.end();
|
||||
|
||||
@@ -28,6 +28,10 @@ class TestHost : public widevine::Cdm::IClock,
|
||||
~Storage() override {}
|
||||
void Reset();
|
||||
|
||||
// Save and load the storage from a string buffer so it can be on disk.
|
||||
bool LoadFromString(const std::string& data);
|
||||
bool SaveToString(std::string* data) const;
|
||||
|
||||
// Reset the file system to contain the specified files.
|
||||
void ResetFiles(const StorageMap& files) { files_ = files; };
|
||||
const StorageMap& files() const { return files_; }
|
||||
|
||||
Reference in New Issue
Block a user