Infrastructure changes to support big usage tables

[ Merge of http://go/wvgerrit/23161 ]

The usage table redesign will require storing usage table headers
and usage entries in non-secure persistent store. This information
will be signed by the TEE to prevent against modification. New
Storage and retrieval methods have been added for usage table headers,
while usage entries will be stored alongside (offline) licenses and
(secure stops/)usage info.

b/34327459

Test: All unittests, including newly introduced ones other than some
oemcrypto, request_license_test passed. Those tests failed with or without
this CL.

Change-Id: I9b8d6210e33774b0803f8af1711b2d593d467aec
This commit is contained in:
Rahul Frias
2017-01-23 23:09:04 -08:00
parent 65a2c240de
commit 4069e72102
6 changed files with 498 additions and 74 deletions

View File

@@ -28,6 +28,19 @@ class DeviceFiles {
kLicenseStateUnknown,
} LicenseState;
typedef enum {
kStorageLicense, // persistent license
kStorageUsageInfo, // secure stop
} UsageEntryStorage;
struct UsageEntryInfo {
UsageEntryStorage storage_type;
std::string key_set_id; // used when storage_type is kStorageLicense
std::string
provider_session_token; // used when storage_type is kStorageUsageInfo
std::string app_id; // used when storage_type is kStorageUsageInfo
};
DeviceFiles(FileSystem*);
virtual ~DeviceFiles();
@@ -54,14 +67,16 @@ class DeviceFiles {
int64_t playback_start_time,
int64_t last_playback_time,
int64_t grace_period_end_time,
const CdmAppParameterMap& app_parameters);
const CdmAppParameterMap& app_parameters,
const std::string& usage_entry);
virtual bool RetrieveLicense(
const std::string& key_set_id, LicenseState* state,
CdmInitData* pssh_data, CdmKeyMessage* key_request,
CdmKeyResponse* key_response, CdmKeyMessage* key_renewal_request,
CdmKeyResponse* key_renewal_response, std::string* release_server_url,
int64_t* playback_start_time, int64_t* last_playback_time,
int64_t* grace_period_end_time, CdmAppParameterMap* app_parameters);
int64_t* grace_period_end_time, CdmAppParameterMap* app_parameters,
std::string* usage_entry);
virtual bool DeleteLicense(const std::string& key_set_id);
virtual bool DeleteAllFiles();
virtual bool DeleteAllLicenses();
@@ -73,7 +88,8 @@ class DeviceFiles {
const CdmKeyMessage& key_request,
const CdmKeyResponse& key_response,
const std::string& app_id,
const std::string& key_set_id);
const std::string& key_set_id,
const std::string& usage_entry);
virtual bool DeleteUsageInfo(const std::string& app_id,
const std::string& provider_session_token);
// Delete usage information from the file system. Puts a list of all the
@@ -91,13 +107,15 @@ class DeviceFiles {
virtual bool RetrieveUsageInfo(const std::string& app_id,
const std::string& provider_session_token,
CdmKeyMessage* license_request,
CdmKeyResponse* license_response);
CdmKeyResponse* license_response,
std::string* usage_entry);
// Retrieve the usage info entry specified by |key_set_id|.
// Returns false if the entry could not be found.
virtual bool RetrieveUsageInfoByKeySetId(const std::string& app_id,
const std::string& key_set_id,
CdmKeyMessage* license_request,
CdmKeyResponse* license_response);
CdmKeyResponse* license_response,
std::string* usage_entry);
virtual bool StoreHlsAttributes(const std::string& key_set_id,
const CdmHlsMethod method,
@@ -106,6 +124,15 @@ class DeviceFiles {
CdmHlsMethod* method,
std::vector<uint8_t>* media_segment_iv);
virtual bool DeleteHlsAttributes(const std::string& key_set_id);
virtual bool StoreUsageTableInfo(
const std::string& usage_table_header,
const std::vector<UsageEntryInfo>& usage_entry_info);
virtual bool RetrieveUsageTableInfo(
std::string* usage_table_header,
std::vector<UsageEntryInfo>* usage_entry_info);
private:
// Helpers that wrap the File interface and automatically handle hashing, as
// well as adding the device files base path to to the file name.
@@ -123,6 +150,7 @@ class DeviceFiles {
static std::string GetHlsAttributesFileNameExtension();
static std::string GetLicenseFileNameExtension();
static std::string GetUsageInfoFileName(const std::string& app_id);
static std::string GetUsageTableFileName();
static std::string GetFileNameSafeHash(const std::string& input);
#if defined(UNIT_TEST)
@@ -144,6 +172,8 @@ class DeviceFiles {
FRIEND_TEST(DeviceFilesUsageInfoTest, DeleteAll);
FRIEND_TEST(DeviceFilesUsageInfoTest, Read);
FRIEND_TEST(DeviceFilesUsageInfoTest, Store);
FRIEND_TEST(DeviceFilesUsageTableTest, Read);
FRIEND_TEST(DeviceFilesUsageTableTest, Store);
FRIEND_TEST(WvCdmRequestLicenseTest, UnprovisionTest);
FRIEND_TEST(WvCdmRequestLicenseTest, ForceL3Test);
FRIEND_TEST(WvCdmRequestLicenseTest, UsageInfoRetryTest);

View File

@@ -854,8 +854,9 @@ CdmResponseType CdmEngine::GetUsageInfo(const std::string& app_id,
CdmKeyMessage license_request;
CdmKeyResponse license_response;
std::string usage_entry;
if (!handle.RetrieveUsageInfo(app_id, ssid, &license_request,
&license_response)) {
&license_response, &usage_entry)) {
usage_property_set_->set_security_level(kLevel3);
usage_property_set_->set_app_id(app_id);
usage_session_.reset(new CdmSession(file_system_));
@@ -869,7 +870,7 @@ CdmResponseType CdmEngine::GetUsageInfo(const std::string& app_id,
return GET_USAGE_INFO_ERROR_2;
}
if (!handle.RetrieveUsageInfo(app_id, ssid, &license_request,
&license_response)) {
&license_response, &usage_entry)) {
// No entry found for that ssid.
return USAGE_INFO_NOT_FOUND;
}
@@ -1084,8 +1085,9 @@ CdmResponseType CdmEngine::LoadUsageSession(const CdmKeySetId& key_set_id,
CdmKeyMessage key_message;
CdmKeyResponse key_response;
std::string usage_entry;
if (!handle.RetrieveUsageInfoByKeySetId(app_id, key_set_id, &key_message,
&key_response)) {
&key_response, &usage_entry)) {
LOGE("CdmEngine::LoadUsageSession: unable to find usage information");
return LOAD_USAGE_INFO_MISSING;
}

View File

@@ -146,13 +146,14 @@ CdmResponseType CdmSession::RestoreOfflineSession(
int64_t playback_start_time;
int64_t last_playback_time;
int64_t grace_period_end_time;
std::string usage_entry;
if (!file_handle_->RetrieveLicense(
key_set_id, &license_state, &offline_init_data_, &key_request_,
&key_response_, &offline_key_renewal_request_,
&offline_key_renewal_response_, &offline_release_server_url_,
&playback_start_time, &last_playback_time, &grace_period_end_time,
&app_parameters_)) {
&app_parameters_, &usage_entry)) {
LOGE("CdmSession::Init failed to retrieve license. key set id = %s",
key_set_id.c_str());
return GET_LICENSE_ERROR;
@@ -573,8 +574,10 @@ CdmResponseType CdmSession::StoreLicense() {
std::string app_id;
GetApplicationId(&app_id);
std::string usage_entry;
if (!file_handle_->StoreUsageInfo(provider_session_token, key_request_,
key_response_, app_id, key_set_id_)) {
key_response_, app_id, key_set_id_,
usage_entry)) {
LOGE("CdmSession::StoreLicense: Unable to store usage info");
return STORE_USAGE_INFO_ERROR;
}
@@ -582,12 +585,13 @@ CdmResponseType CdmSession::StoreLicense() {
}
bool CdmSession::StoreLicense(DeviceFiles::LicenseState state) {
std::string usage_entry;
return file_handle_->StoreLicense(
key_set_id_, state, offline_init_data_, key_request_, key_response_,
offline_key_renewal_request_, offline_key_renewal_response_,
offline_release_server_url_, policy_engine_->GetPlaybackStartTime(),
policy_engine_->GetLastPlaybackTime(),
policy_engine_->GetGracePeriodEndTime(), app_parameters_);
policy_engine_->GetGracePeriodEndTime(), app_parameters_, usage_entry);
}
CdmResponseType CdmSession::ReleaseCrypto() {

View File

@@ -34,6 +34,12 @@ using video_widevine_client::sdk::License_LicenseState_RELEASING;
using video_widevine_client::sdk::NameValue;
using video_widevine_client::sdk::UsageInfo;
using video_widevine_client::sdk::UsageInfo_ProviderSession;
using video_widevine_client::sdk::UsageTableInfo;
using video_widevine_client::sdk::UsageTableInfo_UsageEntryInfo;
using video_widevine_client::sdk::
UsageTableInfo_UsageEntryInfo_UsageEntryStorage_LICENSE;
using video_widevine_client::sdk::
UsageTableInfo_UsageEntryInfo_UsageEntryStorage_USAGE_INFO;
namespace {
@@ -43,6 +49,7 @@ const char kUsageInfoFileNamePrefix[] = "usage";
const char kUsageInfoFileNameExt[] = ".bin";
const char kLicenseFileNameExt[] = ".lic";
const char kEmptyFileName[] = "";
const char kUsageTableFileName[] = "usagetable.bin";
const char kWildcard[] = "*";
bool Hash(const std::string& data, std::string* hash) {
@@ -169,7 +176,8 @@ bool DeviceFiles::StoreLicense(
const CdmKeyResponse& license_renewal,
const std::string& release_server_url, int64_t playback_start_time,
int64_t last_playback_time, int64_t grace_period_end_time,
const CdmAppParameterMap& app_parameters) {
const CdmAppParameterMap& app_parameters,
const std::string& usage_entry) {
if (!initialized_) {
LOGW("DeviceFiles::StoreLicense: not initialized");
return false;
@@ -210,6 +218,7 @@ bool DeviceFiles::StoreLicense(
app_params->set_name(iter->first);
app_params->set_value(iter->second);
}
license->set_usage_entry(usage_entry);
std::string serialized_file;
file.SerializeToString(&serialized_file);
@@ -224,7 +233,7 @@ bool DeviceFiles::RetrieveLicense(
CdmKeyMessage* license_renewal_request, CdmKeyResponse* license_renewal,
std::string* release_server_url, int64_t* playback_start_time,
int64_t* last_playback_time, int64_t* grace_period_end_time,
CdmAppParameterMap* app_parameters) {
CdmAppParameterMap* app_parameters, std::string* usage_entry) {
if (!initialized_) {
LOGW("DeviceFiles::RetrieveLicense: not initialized");
return false;
@@ -278,6 +287,7 @@ bool DeviceFiles::RetrieveLicense(
(*app_parameters)[license.app_parameters(i).name()] =
license.app_parameters(i).value();
}
*usage_entry = license.usage_entry();
return true;
}
@@ -340,7 +350,8 @@ bool DeviceFiles::StoreUsageInfo(const std::string& provider_session_token,
const CdmKeyMessage& key_request,
const CdmKeyResponse& key_response,
const std::string& app_id,
const std::string& key_set_id) {
const std::string& key_set_id,
const std::string& usage_entry) {
if (!initialized_) {
LOGW("DeviceFiles::StoreUsageInfo: not initialized");
return false;
@@ -366,6 +377,7 @@ bool DeviceFiles::StoreUsageInfo(const std::string& provider_session_token,
provider_session->set_license_request(key_request.data(), key_request.size());
provider_session->set_license(key_response.data(), key_response.size());
provider_session->set_key_set_id(key_set_id.data(), key_set_id.size());
provider_session->set_usage_entry(usage_entry);
std::string serialized_file;
file.SerializeToString(&serialized_file);
@@ -479,7 +491,8 @@ bool DeviceFiles::RetrieveUsageInfo(
bool DeviceFiles::RetrieveUsageInfo(const std::string& app_id,
const std::string& provider_session_token,
CdmKeyMessage* license_request,
CdmKeyResponse* license_response) {
CdmKeyResponse* license_response,
std::string* usage_entry) {
if (!initialized_) {
LOGW("DeviceFiles::RetrieveUsageInfo: not initialized");
return false;
@@ -496,6 +509,7 @@ bool DeviceFiles::RetrieveUsageInfo(const std::string& app_id,
if (file.usage_info().sessions(index).token() == provider_session_token) {
*license_request = file.usage_info().sessions(index).license_request();
*license_response = file.usage_info().sessions(index).license();
*usage_entry = file.usage_info().sessions(index).usage_entry();
return true;
}
}
@@ -507,7 +521,8 @@ bool DeviceFiles::RetrieveUsageInfoByKeySetId(
const std::string& app_id,
const std::string& key_set_id,
CdmKeyMessage* license_request,
CdmKeyResponse* license_response) {
CdmKeyResponse* license_response,
std::string* usage_entry) {
if (!initialized_) {
LOGW("DeviceFiles::RetrieveUsageInfoByKeySetId: not initialized");
return false;
@@ -524,6 +539,7 @@ bool DeviceFiles::RetrieveUsageInfoByKeySetId(
if (file.usage_info().sessions(index).key_set_id() == key_set_id) {
*license_request = file.usage_info().sessions(index).license_request();
*license_response = file.usage_info().sessions(index).license();
*usage_entry = file.usage_info().sessions(index).usage_entry();
return true;
}
}
@@ -628,6 +644,118 @@ bool DeviceFiles::DeleteHlsAttributes(const std::string& key_set_id) {
return RemoveFile(key_set_id + kHlsAttributesFileNameExt);
}
bool DeviceFiles::StoreUsageTableInfo(
const std::string& usage_table_header,
const std::vector<DeviceFiles::UsageEntryInfo>& usage_entry_info) {
if (!initialized_) {
LOGW("DeviceFiles::StoreUsageTableHeader: not initialized");
return false;
}
// Fill in file information
video_widevine_client::sdk::File file;
file.set_type(video_widevine_client::sdk::File::USAGE_TABLE_INFO);
file.set_version(video_widevine_client::sdk::File::VERSION_1);
UsageTableInfo* usage_table_info = file.mutable_usage_table_info();
usage_table_info->set_usage_table_header(usage_table_header);
for (size_t i = 0; i < usage_entry_info.size(); ++i) {
UsageTableInfo_UsageEntryInfo* info =
usage_table_info->add_usage_entry_info();
switch (usage_entry_info[i].storage_type) {
case kStorageLicense:
info->set_storage(
UsageTableInfo_UsageEntryInfo_UsageEntryStorage_LICENSE);
info->set_key_set_id(usage_entry_info[i].key_set_id);
break;
case kStorageUsageInfo:
info->set_storage(
UsageTableInfo_UsageEntryInfo_UsageEntryStorage_USAGE_INFO);
info->set_provider_session_token(
usage_entry_info[i].provider_session_token);
info->set_app_id(usage_entry_info[i].app_id);
break;
default:
LOGW("DeviceFiles::StoreUsageTableHeader: unknown storage type: %d",
usage_entry_info[i].storage_type);
return false;
}
}
std::string serialized_file;
file.SerializeToString(&serialized_file);
return StoreFileWithHash(GetUsageTableFileName(), serialized_file);
}
bool DeviceFiles::RetrieveUsageTableInfo(
std::string* usage_table_header,
std::vector<DeviceFiles::UsageEntryInfo>* usage_entry_info) {
if (!initialized_) {
LOGW("DeviceFiles::RetrieveUsageTableInfo: not initialized");
return false;
}
if (usage_table_header == NULL) {
LOGW(
"DeviceFiles::RetrieveUsageTableInfo: usage_table_header not provided");
return false;
}
if (usage_entry_info == NULL) {
LOGW("DeviceFiles::RetrieveUsageTableInfo: usage_entry_info not provided");
return false;
}
video_widevine_client::sdk::File file;
if (!RetrieveHashedFile(GetUsageTableFileName(), &file)) {
return false;
}
if (file.type() != video_widevine_client::sdk::File::USAGE_TABLE_INFO) {
LOGW("DeviceFiles::RetrieveUsageTableInfo: Incorrect file type");
return false;
}
if (file.version() != video_widevine_client::sdk::File::VERSION_1) {
LOGW("DeviceFiles::RetrieveUsageTableInfo: Incorrect file version");
return false;
}
if (!file.has_usage_table_info()) {
LOGW("DeviceFiles::RetrieveUsageTableInfo: Usage table info not present");
return false;
}
const UsageTableInfo& usage_table_info = file.usage_table_info();
*usage_table_header = usage_table_info.usage_table_header();
usage_entry_info->resize(usage_table_info.usage_entry_info_size());
for (int i = 0; i < usage_table_info.usage_entry_info_size(); ++i) {
const UsageTableInfo_UsageEntryInfo& info =
usage_table_info.usage_entry_info(i);
switch (info.storage()) {
case UsageTableInfo_UsageEntryInfo_UsageEntryStorage_LICENSE:
(*usage_entry_info)[i].storage_type = kStorageLicense;
(*usage_entry_info)[i].key_set_id = info.key_set_id();
break;
case UsageTableInfo_UsageEntryInfo_UsageEntryStorage_USAGE_INFO:
(*usage_entry_info)[i].storage_type = kStorageUsageInfo;
(*usage_entry_info)[i].provider_session_token =
info.provider_session_token();
(*usage_entry_info)[i].app_id = info.app_id();
break;
default:
LOGW("DeviceFiles::RetrieveUsageTableInfo: Unknown storage type: %d",
info.storage());
return false;
}
}
return true;
}
bool DeviceFiles::StoreFileWithHash(const std::string& name,
const std::string& serialized_file) {
// calculate SHA hash
@@ -796,6 +924,10 @@ std::string DeviceFiles::GetCertificateFileName() {
return kCertificateFileName;
}
std::string DeviceFiles::GetUsageTableFileName() {
return kUsageTableFileName;
}
std::string DeviceFiles::GetHlsAttributesFileNameExtension() {
return kHlsAttributesFileNameExt;
}

View File

@@ -43,6 +43,7 @@ message License {
// contains the playback_start_time we should use as an override. This is
// ignored if there is no grace period.
optional int64 grace_period_end_time = 11 [default = 0];
optional bytes usage_entry = 12;
}
message UsageInfo {
@@ -51,13 +52,14 @@ message UsageInfo {
optional bytes license_request = 2;
optional bytes license = 3;
optional bytes key_set_id = 4;
optional bytes usage_entry = 5;
}
repeated ProviderSession sessions = 1;
}
message HlsAttributes {
enum Method {
enum Method {
AES_128 = 1;
SAMPLE_AES = 2;
}
@@ -65,12 +67,30 @@ message HlsAttributes {
optional bytes media_segment_iv = 2;
}
message UsageTableInfo {
message UsageEntryInfo {
enum UsageEntryStorage {
LICENSE = 1;
USAGE_INFO = 2;
}
optional UsageEntryStorage storage = 1;
optional bytes key_set_id = 2; // used if storage is LICENSE
optional bytes provider_session_token = 3; // used if storage is USAGE_INFO
optional bytes app_id = 4; // used if storage is USAGE_INFO
}
optional bytes usage_table_header = 1;
repeated UsageEntryInfo usage_entry_info = 2;
}
message File {
enum FileType {
DEVICE_CERTIFICATE = 1;
LICENSE = 2;
USAGE_INFO = 3;
HLS_ATTRIBUTES = 4;
USAGE_TABLE_INFO = 5;
}
enum FileVersion {
@@ -83,6 +103,7 @@ message File {
optional License license = 4;
optional UsageInfo usage_info = 5;
optional HlsAttributes hls_attributes = 6;
optional UsageTableInfo usage_table_info = 7;
}
message HashedFile {

View File

@@ -22,6 +22,9 @@ const uint32_t kLicenseRequestLen = 300;
const uint32_t kLicenseLen = 500;
const uint32_t kProviderSessionTokenLen = 128;
const uint32_t kKeySetIdLen = 20;
const uint32_t kUsageEntryLen = 50;
const std::string kEmptyString;
// Structurally valid test certificate.
// The data elements in this module are used to test the storage and
@@ -120,6 +123,7 @@ struct LicenseInfo {
int64_t last_playback_time;
int64_t grace_period_end_time;
std::string app_parameters;
std::string usage_entry;
std::string file_data;
};
@@ -226,9 +230,9 @@ LicenseInfo license_test_data[] = {
"0112001A16200342120A106B63746C0000000000ECDCBE0000000020DBDF"
"A68F051A20182F029E35047A3841FA176C74E5B387350E8D58DEA6878FF0"
"BEA6CABACA1C2C"),
"https://test.google.com/license/GetCencLicense", 0x0, 0x0, 0x0, "",
"https://test.google.com/license/GetCencLicense", 0x0, 0x0, 0x0, "", "",
a2bs_hex(
"0AAA150802100122A3150801121408011210303132333435363738394142434445461"
"0AAC150802100122A5150801121408011210303132333435363738394142434445461"
"A9D0E080112950C0AD70B080112EF090AB002080212103E560EC5335E346F591BC4D0"
"7A7D507618A5D3A68F05228E023082010A0282010100A947904B8DBD55FB685FDB302"
"5574517CCCC74EE4FEAF6629D5179A52FF85CE7409528EFFA0E5DFC3DE9A34BA5F08B"
@@ -307,8 +311,8 @@ LicenseInfo license_test_data[] = {
"106B63746C0000000000ECDCBE0000000020DBDFA68F051A20182F029E35047A3841F"
"A176C74E5B387350E8D58DEA6878FF0BEA6CABACA1C2C3A2E68747470733A2F2F7465"
"73742E676F6F676C652E636F6D2F6C6963656E73652F47657443656E634C6963656E7"
"365400048005800122066F4FFF1CB2C0F978149A9402F3E4FF8D49B19635E646A0678"
"71AA08E7A8FDC3")},
"3654000480058006200122039CB77169260F923E5D4BA5BBF6A7611117483253F2869"
"9DF3D9D14C3718E309")},
// license 1
{"ksidC8EAA2579A282EB0", DeviceFiles::kLicenseStateReleasing,
@@ -409,7 +413,10 @@ LicenseInfo license_test_data[] = {
"https://test.google.com/license/GetCencLicense", 0x12345678, 0x12348765,
0x0, "Name1 Value1",
a2bs_hex(
"0AC3150802100122BC150802121408011210303132333435363738394142434445461"
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2021"
"22232425262728292a2b2c2d2e2f"),
a2bs_hex(
"0AF5150802100122EE150802121408011210303132333435363738394142434445461"
"A9D0E080112950C0AD70B080112EF090AB002080212103E560EC5335E346F591BC4D0"
"7A7D507618A5D3A68F05228E023082010A0282010100A947904B8DBD55FB685FDB302"
"5574517CCCC74EE4FEAF6629D5179A52FF85CE7409528EFFA0E5DFC3DE9A34BA5F08B"
@@ -488,8 +495,10 @@ LicenseInfo license_test_data[] = {
"106B63746C00000000CA3A6A75000000002083E5A68F051A20BDA6A56F7CBFD094219"
"8F87C23A34AA5CBD64AFEB134277774CCF8E789D815DD3A2E68747470733A2F2F7465"
"73742E676F6F676C652E636F6D2F6C6963656E73652F47657443656E634C6963656E7"
"36540F8ACD1910148E58ED29101520F0A054E616D6531120656616C75653158001220"
"9C0315FC1812C6A0E5936E36D04ECE2FA56AF4AB544ECDF3C9135D54B4A26167")},
"36540F8ACD1910148E58ED29101520F0A054E616D6531120656616C75653158006230"
"000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F20212"
"2232425262728292A2B2C2D2E2F1220312487214ACA5A9AF5ED9D45F209DC77E03CA1"
"DBFFDF86C44A35A1351CE968B9")},
// license 2
{"ksidE8C37662C88DC673", DeviceFiles::kLicenseStateReleasing,
@@ -590,7 +599,10 @@ LicenseInfo license_test_data[] = {
"https://test.google.com/license/GetCencLicense", 0x0123456789abcdef,
0x123456789abfedc, 0x0, "Name1 Value1 Name2 Param2",
a2bs_hex(
"0AE9150802100122E2150802121408011210303132333435363738394142434445461"
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2021"
"22232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f"),
a2bs_hex(
"0AAB160802100122A4160802121408011210303132333435363738394142434445461"
"A9D0E080112950C0AD70B080112EF090AB002080212103E560EC5335E346F591BC4D0"
"7A7D507618A5D3A68F05228E023082010A0282010100A947904B8DBD55FB685FDB302"
"5574517CCCC74EE4FEAF6629D5179A52FF85CE7409528EFFA0E5DFC3DE9A34BA5F08B"
@@ -671,8 +683,9 @@ LicenseInfo license_test_data[] = {
"73742E676F6F676C652E636F6D2F6C6963656E73652F47657443656E634C6963656E7"
"36540EF9BAFCDF8ACD1910148DCFDAFCDF8ACD1910152150A054E616D6531120C5661"
"6C756531204E616D653252160A0C4E616D653220506172616D321206506172616D325"
"8001220616E6AC4AF6EB4F7147E98CF7302425E2390B293BBC01F9F8E89B49F653EA3"
"45")}};
"8006240000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E"
"1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F122"
"07CEAAE401B81E635808AC830A0F3F43308A38FAB16069E542F994B6EC1325280")}};
// Sample license data and related data for storage and use for offline
// playback. The license data and URLs in this test are not real.
@@ -777,7 +790,10 @@ LicenseInfo license_update_test_data[] = {
"https://test.google.com/license/GetCencLicense", 0x0123456789abcdef,
0x123456789abfedc, 0x0, "Name1 Value1 Name2 Value2 Name3 Value3",
a2bs_hex(
"0ABA150802100122B3150801121408011210303132333435363738394142434445461"
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2021"
"22232425262728292a2b2c2d2e2f"),
a2bs_hex(
"0AEC150802100122E5150801121408011210303132333435363738394142434445461"
"A9D0E080112950C0AD70B080112EF090AB002080212103E560EC5335E346F591BC4D0"
"7A7D5076189EDFB68F05228E023082010A0282010100CC1715C81AD3F6F279C686F82"
"6E6D7C8961EB13318367D06B4061BBC57E3C616A226A10F042CAD54D44C6484C725CD"
@@ -856,14 +872,16 @@ LicenseInfo license_update_test_data[] = {
"106B63746C0000000071FEF30B0000000020F4DFB68F051A2000351030900858FCFD6"
"977B67803ADFD1280AA661E6B0BD30B08B2C4673551293A2E68747470733A2F2F7465"
"73742E676F6F676C652E636F6D2F6C6963656E73652F47657443656E634C6963656E7"
"36540EF9BAFCDF8ACD1910148DCFDAFCDF8ACD191015800122051F15CDA5B9414919D"
"B67769A781CC4F43138D314DAFFCBFBD620E53167E4AF2")},
"36540EF9BAFCDF8ACD1910148DCFDAFCDF8ACD1910158006230000102030405060708"
"090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2"
"B2C2D2E2F1220A33C179B7718632337DFDC32D3711FD543336EBE838979DFDEB3A168"
"BC9AFB27")},
// license being released. all fields are identical except for license
// state and hashed file data
{"", DeviceFiles::kLicenseStateReleasing, "", "", "", "", "", "", 0, 0, 0,
"",
"", "",
a2bs_hex(
"0ABA150802100122B3150802121408011210303132333435363738394142434445461"
"0AEC150802100122E5150802121408011210303132333435363738394142434445461"
"A9D0E080112950C0AD70B080112EF090AB002080212103E560EC5335E346F591BC4D0"
"7A7D5076189EDFB68F05228E023082010A0282010100CC1715C81AD3F6F279C686F82"
"6E6D7C8961EB13318367D06B4061BBC57E3C616A226A10F042CAD54D44C6484C725CD"
@@ -942,8 +960,10 @@ LicenseInfo license_update_test_data[] = {
"106B63746C0000000071FEF30B0000000020F4DFB68F051A2000351030900858FCFD6"
"977B67803ADFD1280AA661E6B0BD30B08B2C4673551293A2E68747470733A2F2F7465"
"73742E676F6F676C652E636F6D2F6C6963656E73652F47657443656E634C6963656E7"
"36540EF9BAFCDF8ACD1910148DCFDAFCDF8ACD191015800122093FDE0D42BC60D3932"
"02E0D5A49775E08093BF01560EF72C298321E921716E24")}};
"36540EF9BAFCDF8ACD1910148DCFDAFCDF8ACD1910158006230000102030405060708"
"090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2"
"B2C2D2E2F1220394BA01DFB519C1A7311115F8B2A0AC3141F981FFEA09FCD48A8EFA3"
"A045AAE6")}};
// Application parameters were added to the License message. This data
// is used to verify that a License saved without application parameters can
@@ -1045,7 +1065,7 @@ LicenseInfo license_app_parameters_backwards_compatibility_test_data = {
"0112001A16200342120A106B63746C0000000000ECDCBE0000000020DBDF"
"A68F051A20182F029E35047A3841FA176C74E5B387350E8D58DEA6878FF0"
"BEA6CABACA1C2C"),
"https://test.google.com/license/GetCencLicense", 0x0, 0x0, 0x0, "",
"https://test.google.com/license/GetCencLicense", 0x0, 0x0, 0x0, "", "",
a2bs_hex(
"0AA8150802100122A1150801121408011210303132333435363738394142434445461"
"A9D0E080112950C0AD70B080112EF090AB002080212103E560EC5335E346F591BC4D0"
@@ -1133,14 +1153,14 @@ struct UsageInfo {
std::string provider_session_token;
std::string license_request;
std::string license;
std::string usage_entry;
std::string file_data;
};
UsageInfo kUsageInfoTestData[] = {
{"", "", "", // 0 usage info records
a2bs_hex(
"0A06080210012A00122095053501C5FA405B7EF01DA94685C6B20CB36493"
"A9CF1653B720E2BEA3B77929")},
{"", "", "", "", // 0 usage info records
a2bs_hex("0A06080210012A00122095053501C5FA405B7EF01DA94685C6B20CB36493"
"A9CF1653B720E2BEA3B77929")},
{// 1 usage info record
a2bs_hex(
"924B035FBDA56AE5EF0ED05A08DE7AECC8ABE1835E0C4A548F7803937F4C3B4520EB7"
@@ -1173,6 +1193,9 @@ UsageInfo kUsageInfoTestData[] = {
"E103904BBE4C031A6483858FBAD74DACD01711F7B882749FFFBA0DB6C7D7109D82989"
"C7D4DB5A0F1E7506AC24C89CECAF231EFF99F96AD76E57DABDD3C2DFBA7BAA869A771"
"F561B165987E552824B0C914E708E425C3"),
a2bs_hex(
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2021"
"22232425262728292a2b2c2d2e2f"),
a2bs_hex(
"0AB307080210012AAC070AA9070A8001924B035FBDA56AE5EF0ED05A08DE7AECC8ABE"
"1835E0C4A548F7803937F4C3B4520EB7F3334FFCDFA00DE56408F09D5019FCE87072D"
@@ -1235,6 +1258,9 @@ UsageInfo kUsageInfoTestData[] = {
"9D4D0AA2B358990F244BA76C8E40791D29A0C63C9EF620B97FDFFA9B671E5A65AFCC1"
"C94CAACE0443E9D91F14028935BEA3988831BEBBFD3EB7C3A5AC9605B3534712A0912"
"4345ACB09665E357E58946871BC140D365"),
a2bs_hex(
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2021"
"22232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f"),
a2bs_hex(
"0ADF0E080210012AD80E0AA9070A8001924B035FBDA56AE5EF0ED05A08DE7AECC8ABE"
"1835E0C4A548F7803937F4C3B4520EB7F3334FFCDFA00DE56408F09D5019FCE87072D"
@@ -1324,6 +1350,9 @@ UsageInfo kUsageInfoTestData[] = {
"0FF37DF85BE23D58C17379FEC08DC0648236A107AE66178EEBF78F05F3B898424FA02"
"668B51F838AFA90D367B5CB425372D8CC3790BEA8AFB8795251FA09340D85A7F0B003"
"134C838F08BB1054D18404C3F69130700E"),
a2bs_hex(
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2021"
"22232425262728292a2b2c2d2e2f"),
a2bs_hex(
"0A8B16080210012A84160AA9070A8001924B035FBDA56AE5EF0ED05A08DE7AECC8ABE"
"1835E0C4A548F7803937F4C3B4520EB7F3334FFCDFA00DE56408F09D5019FCE87072D"
@@ -1433,6 +1462,93 @@ HlsAttributesInfo kHlsAttributesTestData[] = {
"41"),
}};
// Usage Table and Entry Test Data
// Note: Make sure the number of entries in kUsageEntriesTestData and
// kUsageTableInfoTestData are equal.
DeviceFiles::UsageEntryInfo kUsageEntriesTestData[] = {
// usage entry 0
{
DeviceFiles::kStorageLicense, "ksid0", "", "",
},
// usage entry 1
{
DeviceFiles::kStorageLicense, "ksid1", "", "",
},
// usage entry 2
{
DeviceFiles::kStorageUsageInfo, "", "provider_session_token_2",
"app_id_2",
},
// usage entry 3
{
DeviceFiles::kStorageUsageInfo, "", "provider_session_token_3",
"app_id_3",
},
// usage entry 4
{
DeviceFiles::kStorageLicense, "ksid4", "", "",
},
// usage entry 5
{
DeviceFiles::kStorageUsageInfo, "", "provider_session_token_5",
"app_id_5",
},
};
struct UsageTableTestInfo {
std::string usage_table_header;
std::string file_data;
};
UsageTableTestInfo kUsageTableInfoTestData[] = {
// usage table 0
{a2bs_hex("5574517CCC"),
a2bs_hex("0A18080510013A120A055574517CCC1209080112056B73696430122018268E3F"
"384F28D04BEE00304089C000463C22E987532855390915FD02C36B5C")},
// usage table 1
{a2bs_hex("CA870203010001288001"),
a2bs_hex("0A28080510013A220A0ACA8702030100012880011209080112056B7369643012"
"09080112056B7369643112202D3638164ADC3B4276734A8EDE96C40BFE14DDB2"
"8013337A3A1A9DFC09F34923")},
// usage table 2
{a2bs_hex("7A7D507618A5D3A68F05228E023082010A028201"),
a2bs_hex("0A5A080510013A540A147A7D507618A5D3A68F05228E023082010A0282011209"
"080112056B736964301209080112056B73696431122608021A1870726F766964"
"65725F73657373696F6E5F746F6B656E5F3222086170705F69645F321220CB07"
"CA08A1E76C61A5F45067176B960A9DB40D169025AF245CF1AFC66C979F47")},
// usage table 3
{a2bs_hex("E83A4902772DAFD2740B7748E9C3B1752D6F12859CED07E82969B4EC"),
a2bs_hex("0A8B01080510013A84010A1CE83A4902772DAFD2740B7748E9C3B1752D6F1285"
"9CED07E82969B4EC1209080112056B736964301209080112056B736964311226"
"08021A1870726F76696465725F73657373696F6E5F746F6B656E5F3222086170"
"705F69645F32122608021A1870726F76696465725F73657373696F6E5F746F6B"
"656E5F3322086170705F69645F331220C4157F80E81C923A9F0885CE6B928D15"
"7E1648384C3E44F04A966815EB09B260")},
// usage table 4
{a2bs_hex("CA870203010001288001300112800250D1F8B1ECF849B60FF93E37C4DEEF"
"52F1CCFC047EF42300131F9C4758F4"),
a2bs_hex("0AA701080510013AA0010A2DCA870203010001288001300112800250D1F8B1EC"
"F849B60FF93E37C4DEEF52F1CCFC047EF42300131F9C4758F41209080112056B"
"736964301209080112056B73696431122608021A1870726F76696465725F7365"
"7373696F6E5F746F6B656E5F3222086170705F69645F32122608021A1870726F"
"76696465725F73657373696F6E5F746F6B656E5F3322086170705F69645F3312"
"09080112056B7369643412203F75C53693E7A3DC9BA5BF3E23D7EFCF3C05687A"
"A6082E3AB78F563525981999")},
// usage table 5
{a2bs_hex("EC83A4902772DAFD2740B7748E9C3B1752D6F12859CED07E8882969B433E"
"C29AC6FDBE79230B0FAED5D94CF6B829A420BBE3270323941776EE60DD6B"),
a2bs_hex("0ADE01080510013AD7010A3CEC83A4902772DAFD2740B7748E9C3B1752D6F128"
"59CED07E8882969B433EC29AC6FDBE79230B0FAED5D94CF6B829A420BBE32703"
"23941776EE60DD6B1209080112056B736964301209080112056B736964311226"
"08021A1870726F76696465725F73657373696F6E5F746F6B656E5F3222086170"
"705F69645F32122608021A1870726F76696465725F73657373696F6E5F746F6B"
"656E5F3322086170705F69645F331209080112056B73696434122608021A1870"
"726F76696465725F73657373696F6E5F746F6B656E5F3522086170705F69645F"
"3512203B35BD5C615BBA79008A7A1DA29AFA69F5CD529DFDE794A0544E423B72"
"1CB8E8")},
};
class MockFile : public File {
public:
MockFile() : File(NULL) {}
@@ -1488,10 +1604,18 @@ class DeviceFilesTest : public ::testing::Test {
}
size_t GetLicenseDataSize(LicenseInfo& data) {
CdmAppParameterMap app_parameters = GetAppParameters(data.app_parameters);
size_t app_parameters_len = 0;
CdmAppParameterMap::const_iterator itr = app_parameters.begin();
for (itr = app_parameters.begin(); itr != app_parameters.end(); ++itr) {
app_parameters_len += itr->first.length();
app_parameters_len += itr->second.length();
}
return sizeof(DeviceFiles::LicenseState) + data.pssh_data.size() +
data.key_request.size() + data.key_response.size() +
data.key_renewal_request.size() + data.key_renewal_response.size() +
data.key_release_url.size() + 3 * sizeof(int64_t);
data.key_release_url.size() + 3 * sizeof(int64_t) +
app_parameters_len + data.usage_entry.size();
}
CdmAppParameterMap GetAppParameters(std::string str) {
@@ -1533,12 +1657,30 @@ class DeviceFilesHlsAttributesTest
: public DeviceFilesTest,
public ::testing::WithParamInterface<HlsAttributesInfo*> {};
class DeviceFilesUsageTableTest : public DeviceFilesTest,
public ::testing::WithParamInterface<int> {};
MATCHER(IsCreateFileFlagSet, "") { return FileSystem::kCreate & arg; }
MATCHER_P(IsStrEq, str, "") {
// Estimating the length of data. We can have gmock provide length
// as well as pointer to data but that will introduce a dependency on tr1
return memcmp(arg, str.c_str(), str.size()) == 0;
}
MATCHER_P(ContainsAllElementsInVector, str_vector, "") {
// Estimating the length of data. We can have gmock provide length
// as well as pointer to data but that will introduce a dependency on tr1
size_t str_length = 0;
for (size_t i = 0; i < str_vector.size(); ++i) {
str_length += str_vector[i].size();
}
std::string data(arg, str_length + kProtobufEstimatedOverhead);
bool all_entries_found = true;
for (size_t i = 0; i < str_vector.size(); ++i) {
if (data.find(str_vector[i]) == std::string::npos)
all_entries_found = false;
}
return all_entries_found;
}
MATCHER_P2(Contains, str1, size, "") {
// Estimating the length of data. We can have gmock provide length
// as well as pointer to data but that will introduce a dependency on tr1
@@ -1562,30 +1704,19 @@ MATCHER_P4(Contains, str1, str2, str3, size, "") {
data.find(str2) != std::string::npos &&
data.find(str3) != std::string::npos);
}
MATCHER_P5(Contains, str1, str2, str3, str4, size, "") {
MATCHER_P6(Contains, str1, str2, str3, str4, str5, size, "") {
// Estimating the length of data. We can have gmock provide length
// as well as pointer to data but that will introduce a dependency on tr1
std::string data(arg, size + str1.size() + str2.size() + str3.size() +
str4.size() + kProtobufEstimatedOverhead);
return (data.find(str1) != std::string::npos &&
data.find(str2) != std::string::npos &&
data.find(str3) != std::string::npos &&
data.find(str4) != std::string::npos);
}
MATCHER_P6(Contains, str1, str2, str3, str4, str5, str6, "") {
// Estimating the length of data. We can have gmock provide length
// as well as pointer to data but that will introduce a dependency on tr1
std::string data(arg, str1.size() + str2.size() + str3.size() + str4.size() +
str5.size() + str6.size() +
str4.size() + str5.size() +
kProtobufEstimatedOverhead);
return (data.find(str1) != std::string::npos &&
data.find(str2) != std::string::npos &&
data.find(str3) != std::string::npos &&
data.find(str4) != std::string::npos &&
data.find(str5) != std::string::npos &&
data.find(str6) != std::string::npos);
data.find(str5) != std::string::npos);
}
MATCHER_P7(Contains, str1, str2, str3, str4, str5, str6, map7, "") {
MATCHER_P8(Contains, str1, str2, str3, str4, str5, str6, map7, str8, "") {
// Estimating the length of data. We can have gmock provide length
// as well as pointer to data but that will introduce a dependency on tr1
size_t map7_len = 0;
@@ -1595,7 +1726,7 @@ MATCHER_P7(Contains, str1, str2, str3, str4, str5, str6, map7, "") {
map7_len += itr->second.length();
}
std::string data(arg, str1.size() + str2.size() + str3.size() + str4.size() +
str5.size() + str6.size() + map7_len +
str5.size() + str6.size() + map7_len + str8.size() +
kProtobufEstimatedOverhead);
bool map7_entries_present = true;
for (itr = map7.begin(); itr != map7.end(); ++itr) {
@@ -1608,7 +1739,8 @@ MATCHER_P7(Contains, str1, str2, str3, str4, str5, str6, map7, "") {
data.find(str3) != std::string::npos &&
data.find(str4) != std::string::npos &&
data.find(str5) != std::string::npos &&
data.find(str6) != std::string::npos && map7_entries_present);
data.find(str6) != std::string::npos && map7_entries_present &&
data.find(str8) != std::string::npos);
}
TEST_F(DeviceCertificateStoreTest, StoreCertificate) {
@@ -1731,7 +1863,8 @@ TEST_P(DeviceFilesStoreTest, StoreLicense) {
license_test_data[license_num].key_renewal_request,
license_test_data[license_num].key_renewal_response,
license_test_data[license_num].key_release_url,
app_parameters),
app_parameters,
license_test_data[license_num].usage_entry),
Gt(GetLicenseDataSize(license_test_data[license_num]))))
.WillOnce(ReturnArg<1>());
EXPECT_CALL(file, Close()).Times(1);
@@ -1750,7 +1883,8 @@ TEST_P(DeviceFilesStoreTest, StoreLicense) {
license_test_data[license_num].key_release_url,
license_test_data[license_num].playback_start_time,
license_test_data[license_num].last_playback_time,
license_test_data[license_num].grace_period_end_time, app_parameters));
license_test_data[license_num].grace_period_end_time, app_parameters,
license_test_data[license_num].usage_entry));
}
INSTANTIATE_TEST_CASE_P(StoreLicense, DeviceFilesStoreTest, ::testing::Bool());
@@ -1776,7 +1910,8 @@ TEST_F(DeviceFilesTest, StoreLicenses) {
license_test_data[i].key_renewal_request,
license_test_data[i].key_renewal_response,
license_test_data[i].key_release_url,
app_parameters),
app_parameters,
license_test_data[i].usage_entry),
Gt(GetLicenseDataSize(license_test_data[i]))))
.WillOnce(ReturnArg<1>());
}
@@ -1798,7 +1933,8 @@ TEST_F(DeviceFilesTest, StoreLicenses) {
license_test_data[i].key_release_url,
license_test_data[i].playback_start_time,
license_test_data[i].last_playback_time,
license_test_data[i].grace_period_end_time, app_parameters));
license_test_data[i].grace_period_end_time, app_parameters,
license_test_data[i].usage_entry));
}
}
@@ -1839,6 +1975,7 @@ TEST_F(DeviceFilesTest, RetrieveLicenses) {
int64_t grace_period_end_time;
std::string release_server_url;
CdmAppParameterMap app_parameters;
std::string usage_entry;
for (size_t i = 0; i < kNumberOfLicenses; i++) {
DeviceFiles::LicenseState license_state;
@@ -1846,7 +1983,8 @@ TEST_F(DeviceFilesTest, RetrieveLicenses) {
license_test_data[i].key_set_id, &license_state, &pssh_data,
&key_request, &key_response, &key_renewal_request,
&key_renewal_response, &release_server_url, &playback_start_time,
&last_playback_time, &grace_period_end_time, &app_parameters));
&last_playback_time, &grace_period_end_time, &app_parameters,
&usage_entry));
EXPECT_EQ(license_test_data[i].license_state, license_state);
EXPECT_EQ(license_test_data[i].pssh_data, pssh_data);
EXPECT_EQ(license_test_data[i].key_request, key_request);
@@ -1857,6 +1995,7 @@ TEST_F(DeviceFilesTest, RetrieveLicenses) {
EXPECT_EQ(license_test_data[i].last_playback_time, last_playback_time);
EXPECT_EQ(license_test_data[i].grace_period_end_time,
grace_period_end_time);
EXPECT_EQ(license_test_data[i].usage_entry, usage_entry);
std::map<std::string, std::string>::iterator itr;
for (itr = app_parameters.begin(); itr != app_parameters.end(); ++itr) {
@@ -1904,12 +2043,13 @@ TEST_F(DeviceFilesTest, AppParametersBackwardCompatibility) {
int64_t grace_period_end_time;
std::string release_server_url;
CdmAppParameterMap app_parameters;
std::string usage_entry;
EXPECT_TRUE(device_files.RetrieveLicense(
test_data->key_set_id, &license_state, &pssh_data, &key_request,
&key_response, &key_renewal_request, &key_renewal_response,
&release_server_url, &playback_start_time, &last_playback_time,
&grace_period_end_time, &app_parameters));
&grace_period_end_time, &app_parameters, &usage_entry));
EXPECT_EQ(test_data->license_state, license_state);
EXPECT_EQ(test_data->pssh_data, pssh_data);
EXPECT_EQ(test_data->key_request, key_request);
@@ -1920,6 +2060,7 @@ TEST_F(DeviceFilesTest, AppParametersBackwardCompatibility) {
EXPECT_EQ(test_data->last_playback_time, last_playback_time);
EXPECT_EQ(test_data->grace_period_end_time, grace_period_end_time);
EXPECT_EQ(0u, app_parameters.size());
EXPECT_EQ(test_data->usage_entry, usage_entry);
}
TEST_F(DeviceFilesTest, UpdateLicenseState) {
@@ -1955,7 +2096,8 @@ TEST_F(DeviceFilesTest, UpdateLicenseState) {
license_update_test_data[0].playback_start_time,
license_update_test_data[0].last_playback_time,
license_update_test_data[0].grace_period_end_time,
GetAppParameters(license_test_data[0].app_parameters)));
GetAppParameters(license_test_data[0].app_parameters),
license_update_test_data[0].usage_entry));
EXPECT_TRUE(device_files.StoreLicense(
license_update_test_data[0].key_set_id,
@@ -1969,7 +2111,8 @@ TEST_F(DeviceFilesTest, UpdateLicenseState) {
license_update_test_data[0].playback_start_time,
license_update_test_data[0].last_playback_time,
license_update_test_data[0].grace_period_end_time,
GetAppParameters(license_test_data[0].app_parameters)));
GetAppParameters(license_test_data[0].app_parameters),
license_update_test_data[0].usage_entry));
}
TEST_F(DeviceFilesTest, DeleteLicense) {
@@ -2009,12 +2152,13 @@ TEST_F(DeviceFilesTest, DeleteLicense) {
std::string release_server_url;
int64_t playback_start_time, last_playback_time, grace_period_end_time;
CdmAppParameterMap app_parameters;
std::string usage_entry;
EXPECT_TRUE(device_files.RetrieveLicense(
license_test_data[0].key_set_id, &license_state, &pssh_data, &key_request,
&key_response, &key_renewal_request, &key_renewal_response,
&release_server_url, &playback_start_time, &last_playback_time,
&grace_period_end_time, &app_parameters));
&grace_period_end_time, &app_parameters, &usage_entry));
EXPECT_EQ(license_test_data[0].license_state, license_state);
EXPECT_EQ(license_test_data[0].pssh_data, pssh_data);
EXPECT_EQ(license_test_data[0].key_request, key_request);
@@ -2031,6 +2175,7 @@ TEST_F(DeviceFilesTest, DeleteLicense) {
EXPECT_NE(license_test_data[0].app_parameters.find(itr->second),
std::string::npos);
}
EXPECT_EQ(license_test_data[0].usage_entry, usage_entry);
EXPECT_TRUE(device_files.DeleteLicense(license_test_data[0].key_set_id));
EXPECT_FALSE(device_files.LicenseExists(license_test_data[0].key_set_id));
@@ -2112,6 +2257,7 @@ TEST_P(DeviceFilesUsageInfoTest, Store) {
std::string license_request(GenerateRandomData(kLicenseRequestLen));
std::string license(GenerateRandomData(kLicenseLen));
std::string key_set_id(GenerateRandomData(kKeySetIdLen));
std::string usage_entry(GenerateRandomData(kUsageEntryLen));
std::string path =
device_base_path_ + DeviceFiles::GetUsageInfoFileName(app_id);
@@ -2140,19 +2286,17 @@ TEST_P(DeviceFilesUsageInfoTest, Store) {
EXPECT_CALL(file, Close());
}
EXPECT_CALL(file,
Write(Contains(pst, license_request, license, key_set_id,
data.size()),
Gt(pst.size() + license_request.size() + license.size() +
key_set_id.size())))
EXPECT_CALL(file, Write(Contains(pst, license_request, license, key_set_id,
usage_entry, data.size()),
Gt(pst.size() + license_request.size() +
license.size() + key_set_id.size())))
.WillOnce(ReturnArg<1>());
DeviceFiles device_files(&file_system);
EXPECT_TRUE(device_files.Init(kSecurityLevelL1));
ASSERT_TRUE(
device_files.StoreUsageInfo(pst, license_request, license, app_id,
key_set_id));
ASSERT_TRUE(device_files.StoreUsageInfo(pst, license_request, license, app_id,
key_set_id, usage_entry));
}
TEST_P(DeviceFilesUsageInfoTest, Delete) {
@@ -2323,4 +2467,95 @@ INSTANTIATE_TEST_CASE_P(HlsAttributes, DeviceFilesHlsAttributesTest,
::testing::Range(&kHlsAttributesTestData[0],
&kHlsAttributesTestData[2]));
TEST_P(DeviceFilesUsageTableTest, Store) {
MockFileSystem file_system;
MockFile file;
int index = GetParam();
size_t entry_data_length = 0;
std::vector<std::string> entry_data;
std::vector<DeviceFiles::UsageEntryInfo> usage_entry_info;
usage_entry_info.resize(index + 1);
for (int i = 0; i <= index; ++i) {
usage_entry_info[i] = kUsageEntriesTestData[i];
if (kUsageEntriesTestData[i].storage_type == DeviceFiles::kStorageLicense) {
entry_data.push_back(kUsageEntriesTestData[i].key_set_id);
entry_data_length += kUsageEntriesTestData[i].key_set_id.size();
} else {
entry_data.push_back(kUsageEntriesTestData[i].provider_session_token);
entry_data.push_back(kUsageEntriesTestData[i].app_id);
entry_data_length +=
kUsageEntriesTestData[i].provider_session_token.size() +
kUsageEntriesTestData[i].app_id.size();
}
}
entry_data.push_back(kUsageTableInfoTestData[index].usage_table_header);
entry_data_length += kUsageTableInfoTestData[index].usage_table_header.size();
std::string path = device_base_path_ + DeviceFiles::GetUsageTableFileName();
EXPECT_CALL(file_system, Exists(StrEq(path))).WillRepeatedly(Return(true));
EXPECT_CALL(file_system, Open(StrEq(path), _)).WillOnce(Return(&file));
EXPECT_CALL(file, Write(ContainsAllElementsInVector(entry_data),
Gt(entry_data_length)))
.WillOnce(ReturnArg<1>());
EXPECT_CALL(file, Read(_, _)).Times(0);
EXPECT_CALL(file, Close()).Times(1);
DeviceFiles device_files(&file_system);
EXPECT_TRUE(device_files.Init(kSecurityLevelL1));
ASSERT_TRUE(device_files.StoreUsageTableInfo(
kUsageTableInfoTestData[index].usage_table_header, usage_entry_info));
}
TEST_P(DeviceFilesUsageTableTest, Read) {
MockFileSystem file_system;
MockFile file;
int index = GetParam();
std::string path = device_base_path_ + DeviceFiles::GetUsageTableFileName();
const std::string& file_data = kUsageTableInfoTestData[index].file_data;
EXPECT_CALL(file_system, Exists(StrEq(path))).WillRepeatedly(Return(true));
EXPECT_CALL(file_system, FileSize(StrEq(path)))
.WillRepeatedly(Return(file_data.size()));
EXPECT_CALL(file_system, Open(StrEq(path), _)).WillOnce(Return(&file));
EXPECT_CALL(file, Read(NotNull(), Eq(file_data.size())))
.WillOnce(DoAll(SetArrayArgument<0>(file_data.begin(), file_data.end()),
Return(file_data.size())));
EXPECT_CALL(file, Close()).Times(1);
EXPECT_CALL(file, Write(_, _)).Times(0);
DeviceFiles device_files(&file_system);
EXPECT_TRUE(device_files.Init(kSecurityLevelL1));
std::vector<DeviceFiles::UsageEntryInfo> usage_entry_info;
std::string usage_table_header;
ASSERT_TRUE(device_files.RetrieveUsageTableInfo(&usage_table_header,
&usage_entry_info));
EXPECT_EQ(kUsageTableInfoTestData[index].usage_table_header,
usage_table_header);
EXPECT_EQ(index + 1, usage_entry_info.size());
for (int i = 0; i <= index; ++i) {
EXPECT_EQ(kUsageEntriesTestData[i].storage_type,
usage_entry_info[i].storage_type);
if (usage_entry_info[i].storage_type == DeviceFiles::kStorageLicense) {
EXPECT_EQ(kUsageEntriesTestData[i].key_set_id,
usage_entry_info[i].key_set_id);
EXPECT_EQ(kEmptyString, usage_entry_info[i].provider_session_token);
EXPECT_EQ(kEmptyString, usage_entry_info[i].app_id);
} else {
EXPECT_EQ(kEmptyString, usage_entry_info[i].key_set_id);
EXPECT_EQ(kUsageEntriesTestData[i].provider_session_token,
usage_entry_info[i].provider_session_token);
EXPECT_EQ(kUsageEntriesTestData[i].app_id, usage_entry_info[i].app_id);
}
}
}
INSTANTIATE_TEST_CASE_P(UsageInfo, DeviceFilesUsageTableTest,
::testing::Range(0, 6));
} // namespace wvcdm