Consolidate update usage table calls

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

In OEMCrypto version 13, usage information is updated by calls to
OEMCrypto_UpdateUsageEntry. In previous versions calls were made to
OEMCrypto_UpdateUsageTable instead. Both need to be supported as the
OEMCrypto version may vary by device.

This consolidates calls to OEMCrypto_UpdateUsageTable so that they
can be disabled if OEMCrypto version >= 13. No functional changes other
than disabling by OEMCrypto version were introduced in this section.

Helper routines have been added to device files as well.

b/34327459

Test: Verified by unit, integration tests on angler

Change-Id: If5d4bbbe7589e7cc1094999ba21f727eb6c92c3b
This commit is contained in:
Rahul Frias
2017-02-13 13:56:30 -08:00
parent 0db3a137e9
commit 826e390ad6
3 changed files with 193 additions and 131 deletions

View File

@@ -139,10 +139,15 @@ class DeviceFiles {
virtual bool ListUsageInfoFiles(std::vector<std::string>* usage_file_names); virtual bool ListUsageInfoFiles(std::vector<std::string>* usage_file_names);
virtual bool RetrieveUsageInfo(const std::string& usage_info_file_name, virtual bool RetrieveUsageInfo(const std::string& usage_info_file_name,
std::vector<CdmUsageData>* usage_data); std::vector<CdmUsageData>* usage_data);
virtual bool RetrieveUsageInfo(const std::string& usage_info_file_name,
const std::string& provider_session_token,
CdmUsageData* usage_data);
// This method overwrites rather than appends data to the usage file // This method overwrites rather than appends data to the usage file
virtual bool StoreUsageInfo(const std::string& usage_info_file_name, virtual bool StoreUsageInfo(const std::string& usage_info_file_name,
const std::vector<CdmUsageData>& usage_data); const std::vector<CdmUsageData>& usage_data);
virtual bool UpdateUsageInfo(const std::string& usage_info_file_name,
const std::string& provider_session_token,
const CdmUsageData& usage_data);
virtual bool StoreHlsAttributes(const std::string& key_set_id, virtual bool StoreHlsAttributes(const std::string& key_set_id,
const CdmHlsMethod method, const CdmHlsMethod method,

View File

@@ -430,28 +430,25 @@ CdmResponseType CryptoSession::Open(SecurityLevel requested_security_level) {
void CryptoSession::Close() { void CryptoSession::Close() {
LOGV("CloseSession: id=%ld open=%s", (uint32_t)oec_session_id_, LOGV("CloseSession: id=%ld open=%s", (uint32_t)oec_session_id_,
open_ ? "true" : "false"); open_ ? "true" : "false");
OEMCryptoResult close_sts;
bool update_usage_table = false;
{
AutoLock auto_lock(crypto_lock_); AutoLock auto_lock(crypto_lock_);
if (!open_) return; if (!open_) return;
OEMCryptoResult close_sts;
M_TIME( M_TIME(
close_sts = OEMCrypto_CloseSession( close_sts = OEMCrypto_CloseSession(
oec_session_id_), oec_session_id_),
metrics_, metrics_,
oemcrypto_close_session_, oemcrypto_close_session_,
close_sts); close_sts);
if (OEMCrypto_SUCCESS == close_sts) { if (OEMCrypto_SUCCESS == close_sts)
open_ = false; open_ = false;
if (update_usage_table_after_close_session_) { update_usage_table = update_usage_table_after_close_session_;
OEMCryptoResult update_sts;
M_TIME(
update_sts = OEMCrypto_UpdateUsageTable(),
metrics_,
oemcrypto_update_usage_table_,
update_sts);
if ( update_sts != OEMCrypto_SUCCESS)
LOGW("CryptoSession::Close: OEMCrypto_UpdateUsageTable error=%ld", update_sts);
} }
if (close_sts == OEMCrypto_SUCCESS && update_usage_table) {
UpdateUsageInformation();
} }
} }
@@ -623,27 +620,25 @@ CdmResponseType CryptoSession::LoadKeys(
metrics_, metrics_,
oemcrypto_load_keys_, oemcrypto_load_keys_,
sts); sts);
CdmResponseType result = KEY_ADDED;
if (OEMCrypto_SUCCESS == sts) { if (OEMCrypto_SUCCESS == sts) {
if (!provider_session_token.empty()) { if (!provider_session_token.empty())
update_usage_table_after_close_session_ = true; update_usage_table_after_close_session_ = true;
M_TIME( result = KEY_ADDED;
sts = OEMCrypto_UpdateUsageTable(),
metrics_,
oemcrypto_update_usage_table_,
sts);
if (sts != OEMCrypto_SUCCESS) {
LOGW("CryptoSession::LoadKeys: OEMCrypto_UpdateUsageTable error=%ld",
sts);
}
}
return KEY_ADDED;
} else if (OEMCrypto_ERROR_TOO_MANY_KEYS == sts) { } else if (OEMCrypto_ERROR_TOO_MANY_KEYS == sts) {
LOGE("CryptoSession::LoadKeys: OEMCrypto_LoadKeys error=%d", sts); LOGE("CryptoSession::LoadKeys: OEMCrypto_LoadKeys error=%d", sts);
return INSUFFICIENT_CRYPTO_RESOURCES; result = INSUFFICIENT_CRYPTO_RESOURCES;
} else { } else {
LOGE("CryptoSession::LoadKeys: OEMCrypto_LoadKeys error=%d", sts); LOGE("CryptoSession::LoadKeys: OEMCrypto_LoadKeys error=%d", sts);
return LOAD_KEY_ERROR; result = LOAD_KEY_ERROR;
} }
// Leaving critical section
crypto_lock_.Release();
if (!provider_session_token.empty())
UpdateUsageInformation();
return result;
} }
bool CryptoSession::LoadCertificatePrivateKey(std::string& wrapped_key) { bool CryptoSession::LoadCertificatePrivateKey(std::string& wrapped_key) {
@@ -1053,6 +1048,13 @@ CdmResponseType CryptoSession::UpdateUsageInformation() {
AutoLock auto_lock(crypto_lock_); AutoLock auto_lock(crypto_lock_);
if (!initialized_) return UNKNOWN_ERROR; if (!initialized_) return UNKNOWN_ERROR;
CdmUsageSupportType usage_support_type;
if (GetUsageSupportType(&usage_support_type) == NO_ERROR &&
usage_support_type == kUsageEntrySupport) {
LOGV("UpdateUsageInformation: deprecated for OEMCrypto v13+");
return NO_ERROR;
}
OEMCryptoResult status; OEMCryptoResult status;
M_TIME( M_TIME(
status = OEMCrypto_UpdateUsageTable(), status = OEMCrypto_UpdateUsageTable(),
@@ -1207,6 +1209,7 @@ CdmResponseType CryptoSession::ReleaseUsageInformation(
const std::string& message, const std::string& signature, const std::string& message, const std::string& signature,
const std::string& provider_session_token) { const std::string& provider_session_token) {
LOGV("ReleaseUsageInformation: id=%ld", (uint32_t)oec_session_id_); LOGV("ReleaseUsageInformation: id=%ld", (uint32_t)oec_session_id_);
{
AutoLock auto_lock(crypto_lock_); AutoLock auto_lock(crypto_lock_);
const uint8_t* msg = reinterpret_cast<const uint8_t*>(message.data()); const uint8_t* msg = reinterpret_cast<const uint8_t*>(message.data());
const uint8_t* sig = reinterpret_cast<const uint8_t*>(signature.data()); const uint8_t* sig = reinterpret_cast<const uint8_t*>(signature.data());
@@ -1231,16 +1234,9 @@ CdmResponseType CryptoSession::ReleaseUsageInformation(
status); status);
return UNKNOWN_ERROR; return UNKNOWN_ERROR;
} }
M_TIME(
status = OEMCrypto_UpdateUsageTable(),
metrics_,
oemcrypto_update_usage_table_,
status);
if (status != OEMCrypto_SUCCESS) {
LOGW("CryptoSession::ReleaseUsageInformation: update table error=%ld",
status);
} }
UpdateUsageInformation();
return NO_ERROR; return NO_ERROR;
} }
@@ -1249,6 +1245,8 @@ CdmResponseType CryptoSession::DeleteUsageInformation(
CdmResponseType response = NO_ERROR; CdmResponseType response = NO_ERROR;
LOGV("CryptoSession::DeleteUsageInformation"); LOGV("CryptoSession::DeleteUsageInformation");
OEMCryptoResult status; OEMCryptoResult status;
{
AutoLock auto_lock(crypto_lock_);
M_TIME( M_TIME(
status = OEMCrypto_ForceDeleteUsageEntry( status = OEMCrypto_ForceDeleteUsageEntry(
reinterpret_cast<const uint8_t*>(provider_session_token.c_str()), reinterpret_cast<const uint8_t*>(provider_session_token.c_str()),
@@ -1257,20 +1255,12 @@ CdmResponseType CryptoSession::DeleteUsageInformation(
oemcrypto_force_delete_usage_entry_, oemcrypto_force_delete_usage_entry_,
status); status);
if (OEMCrypto_SUCCESS != status) { if (OEMCrypto_SUCCESS != status) {
LOGE("CryptoSession::DeleteUsageInformation: Delete Usage Table error =%ld", LOGE("CryptoSession::DeleteUsageInformation: Delete Usage Table error "
status); "= %ld", status);
response = UNKNOWN_ERROR; response = UNKNOWN_ERROR;
} }
M_TIME(
status = OEMCrypto_UpdateUsageTable(),
metrics_,
oemcrypto_update_usage_table_,
status);
if (status != OEMCrypto_SUCCESS) {
LOGE("CryptoSession::DeleteUsageInformation: update table error=%ld",
status);
response = UNKNOWN_ERROR;
} }
UpdateUsageInformation();
return response; return response;
} }
@@ -1278,11 +1268,14 @@ CdmResponseType CryptoSession::DeleteMultipleUsageInformation(
const std::vector<std::string>& provider_session_tokens) { const std::vector<std::string>& provider_session_tokens) {
LOGV("CryptoSession::DeleteMultipleUsageInformation"); LOGV("CryptoSession::DeleteMultipleUsageInformation");
CdmResponseType response = NO_ERROR; CdmResponseType response = NO_ERROR;
{
AutoLock auto_lock(crypto_lock_);
for (size_t i=0; i < provider_session_tokens.size(); ++i) { for (size_t i=0; i < provider_session_tokens.size(); ++i) {
OEMCryptoResult status; OEMCryptoResult status;
M_TIME( M_TIME(
status = OEMCrypto_ForceDeleteUsageEntry( status = OEMCrypto_ForceDeleteUsageEntry(
reinterpret_cast<const uint8_t*>(provider_session_tokens[i].c_str()), reinterpret_cast<const uint8_t*>(
provider_session_tokens[i].c_str()),
provider_session_tokens[i].length()), provider_session_tokens[i].length()),
metrics_, metrics_,
oemcrypto_force_delete_usage_entry_, oemcrypto_force_delete_usage_entry_,
@@ -1293,43 +1286,28 @@ CdmResponseType CryptoSession::DeleteMultipleUsageInformation(
response = UNKNOWN_ERROR; response = UNKNOWN_ERROR;
} }
} }
OEMCryptoResult status;
M_TIME(
status = OEMCrypto_UpdateUsageTable(),
metrics_,
oemcrypto_update_usage_table_,
status);
if (status != OEMCrypto_SUCCESS) {
LOGE("CryptoSession::DeleteMultipleUsageInformation: update table error=%ld",
status);
response = UNKNOWN_ERROR;
} }
UpdateUsageInformation();
return response; return response;
} }
CdmResponseType CryptoSession::DeleteAllUsageReports() { CdmResponseType CryptoSession::DeleteAllUsageReports() {
LOGV("DeleteAllUsageReports"); LOGV("DeleteAllUsageReports");
OEMCryptoResult status; OEMCryptoResult status;
{
AutoLock auto_lock(crypto_lock_);
M_TIME( M_TIME(
status = OEMCrypto_DeleteOldUsageTable(), status = OEMCrypto_DeleteOldUsageTable(),
metrics_, metrics_,
oemcrypto_delete_usage_table_, oemcrypto_delete_usage_table_,
status); status);
if (OEMCrypto_SUCCESS != status) { if (OEMCrypto_SUCCESS != status) {
LOGE("CryptoSession::DeleteAllUsageReports: Delete Usage Table error =%ld", LOGE("CryptoSession::DeleteAllUsageReports: Delete Usage Table error "
status); "=%ld", status);
}
} }
M_TIME( UpdateUsageInformation();
status = OEMCrypto_UpdateUsageTable(),
metrics_,
oemcrypto_update_usage_table_,
status);
if (status != OEMCrypto_SUCCESS) {
LOGE("CryptoSession::DeletaAllUsageReports: update table error=%ld",
status);
return UNKNOWN_ERROR;
}
return NO_ERROR; return NO_ERROR;
} }
@@ -1879,7 +1857,7 @@ CdmResponseType CryptoSession::CreateUsageTableHeader(
} }
if (result != OEMCrypto_SUCCESS) { if (result != OEMCrypto_SUCCESS) {
LOGE("CreateUsageTableHeader; usage table header creation failed: %d", LOGE("CreateUsageTableHeader: usage table header creation failed: %d",
result); result);
return CREATE_USAGE_TABLE_ERROR; return CREATE_USAGE_TABLE_ERROR;
} }

View File

@@ -51,7 +51,7 @@ const char kUsageInfoFileNamePrefix[] = "usage";
const char kUsageInfoFileNameExt[] = ".bin"; const char kUsageInfoFileNameExt[] = ".bin";
const char kLicenseFileNameExt[] = ".lic"; const char kLicenseFileNameExt[] = ".lic";
const char kEmptyFileName[] = ""; const char kEmptyFileName[] = "";
const char kUsageTableFileName[] = "usagetable.bin"; const char kUsageTableFileName[] = "usgtable.bin";
const char kWildcard[] = "*"; const char kWildcard[] = "*";
bool Hash(const std::string& data, std::string* hash) { bool Hash(const std::string& data, std::string* hash) {
@@ -623,14 +623,60 @@ bool DeviceFiles::StoreUsageInfo(const std::string& usage_info_file_name,
return StoreFileWithHash(usage_info_file_name, serialized_file); return StoreFileWithHash(usage_info_file_name, serialized_file);
} }
bool DeviceFiles::UpdateUsageInfo(const std::string& usage_info_file_name,
const std::string& provider_session_token,
const CdmUsageData& usage_data) {
if (!initialized_) {
LOGW("DeviceFiles::UpdateUsageInfo: not initialized");
return false;
}
video_widevine_client::sdk::File file;
if (!FileExists(usage_info_file_name)) {
LOGW("DeviceFiles::UpdateUsageInfo: Usage file does not exist");
return false;
}
if (!RetrieveHashedFile(usage_info_file_name, &file)) {
LOGW("DeviceFiles::UpdateUsageInfo: Unable to parse file");
return false;
}
int index = 0;
for (; index < file.usage_info().sessions_size(); ++index) {
if (file.usage_info().sessions(index).token() == provider_session_token) {
UsageInfo* usage_info = file.mutable_usage_info();
UsageInfo_ProviderSession* provider_session =
usage_info->mutable_sessions(index);
provider_session->set_license_request(usage_data.license_request);
provider_session->set_license(usage_data.license);
provider_session->set_key_set_id(usage_data.key_set_id);
provider_session->set_usage_entry(usage_data.usage_entry);
provider_session->set_usage_entry_number(usage_data.usage_entry_number);
std::string serialized_file;
file.SerializeToString(&serialized_file);
return StoreFileWithHash(usage_info_file_name, serialized_file);
}
}
return false;
}
bool DeviceFiles::RetrieveUsageInfo(const std::string& usage_info_file_name, bool DeviceFiles::RetrieveUsageInfo(const std::string& usage_info_file_name,
std::vector<CdmUsageData>* usage_data) { std::vector<CdmUsageData>* usage_data) {
if (!initialized_) { if (!initialized_) {
LOGW("DeviceFiles::RetrieveUsageInfo: not initialized"); LOGW("DeviceFiles::RetrieveUsageInfo: not initialized");
return false; return false;
} }
if (!FileExists(usage_info_file_name) ||
GetFileSize(usage_info_file_name) == 0) {
usage_data->resize(0);
return true;
}
video_widevine_client::sdk::File file; video_widevine_client::sdk::File file;
if (!RetrieveHashedFile(usage_info_file_name, &file)) { if (!RetrieveHashedFile(usage_info_file_name, &file)) {
return false; return false;
@@ -649,6 +695,39 @@ bool DeviceFiles::RetrieveUsageInfo(const std::string& usage_info_file_name,
file.usage_info().sessions(i).usage_entry_number(); file.usage_info().sessions(i).usage_entry_number();
} }
return true;
}
bool DeviceFiles::RetrieveUsageInfo(const std::string& usage_info_file_name,
const std::string& provider_session_token,
CdmUsageData* usage_data) {
if (!initialized_) {
LOGW("DeviceFiles::RetrieveUsageInfo: not initialized");
return false;
}
video_widevine_client::sdk::File file;
if (!RetrieveHashedFile(usage_info_file_name, &file)) {
return false;
}
int index = 0;
for (; index < file.usage_info().sessions_size(); ++index) {
if (file.usage_info().sessions(index).token() == provider_session_token) {
usage_data->provider_session_token =
file.usage_info().sessions(index).token();
usage_data->license_request =
file.usage_info().sessions(index).license_request();
usage_data->license = file.usage_info().sessions(index).license();
usage_data->key_set_id = file.usage_info().sessions(index).key_set_id();
usage_data->usage_entry = file.usage_info().sessions(index).usage_entry();
usage_data->usage_entry_number =
file.usage_info().sessions(index).usage_entry_number();
return true;
}
}
return false; return false;
} }