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");
AutoLock auto_lock(crypto_lock_);
if (!open_) return;
OEMCryptoResult close_sts; OEMCryptoResult close_sts;
M_TIME( bool update_usage_table = false;
close_sts = OEMCrypto_CloseSession( {
oec_session_id_), AutoLock auto_lock(crypto_lock_);
metrics_, if (!open_) return;
oemcrypto_close_session_,
close_sts); M_TIME(
if (OEMCrypto_SUCCESS == close_sts) { close_sts = OEMCrypto_CloseSession(
open_ = false; oec_session_id_),
if (update_usage_table_after_close_session_) { metrics_,
OEMCryptoResult update_sts; oemcrypto_close_session_,
M_TIME( close_sts);
update_sts = OEMCrypto_UpdateUsageTable(), if (OEMCrypto_SUCCESS == close_sts)
metrics_, open_ = false;
oemcrypto_update_usage_table_, update_usage_table = update_usage_table_after_close_session_;
update_sts); }
if ( update_sts != OEMCrypto_SUCCESS) if (close_sts == OEMCrypto_SUCCESS && update_usage_table) {
LOGW("CryptoSession::Close: OEMCrypto_UpdateUsageTable error=%ld", update_sts); 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,40 +1209,34 @@ 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_); {
const uint8_t* msg = reinterpret_cast<const uint8_t*>(message.data()); AutoLock auto_lock(crypto_lock_);
const uint8_t* sig = reinterpret_cast<const uint8_t*>(signature.data()); const uint8_t* msg = reinterpret_cast<const uint8_t*>(message.data());
const uint8_t* pst = msg + GetOffset(message, provider_session_token); const uint8_t* sig = reinterpret_cast<const uint8_t*>(signature.data());
const uint8_t* pst = msg + GetOffset(message, provider_session_token);
OEMCryptoResult status; OEMCryptoResult status;
M_TIME( M_TIME(
status = OEMCrypto_DeleteUsageEntry( status = OEMCrypto_DeleteUsageEntry(
oec_session_id_, oec_session_id_,
pst, pst,
provider_session_token.length(), provider_session_token.length(),
msg, msg,
message.length(), message.length(),
sig, sig,
signature.length()), signature.length()),
metrics_, metrics_,
oemcrypto_delete_usage_entry_, oemcrypto_delete_usage_entry_,
status); status);
if (OEMCrypto_SUCCESS != status) { if (OEMCrypto_SUCCESS != status) {
LOGE("CryptoSession::ReleaseUsageInformation: Report Usage error=%ld", LOGE("CryptoSession::ReleaseUsageInformation: Report Usage error=%ld",
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,28 +1245,22 @@ CdmResponseType CryptoSession::DeleteUsageInformation(
CdmResponseType response = NO_ERROR; CdmResponseType response = NO_ERROR;
LOGV("CryptoSession::DeleteUsageInformation"); LOGV("CryptoSession::DeleteUsageInformation");
OEMCryptoResult status; OEMCryptoResult status;
M_TIME( {
status = OEMCrypto_ForceDeleteUsageEntry( AutoLock auto_lock(crypto_lock_);
reinterpret_cast<const uint8_t*>(provider_session_token.c_str()), M_TIME(
provider_session_token.length()), status = OEMCrypto_ForceDeleteUsageEntry(
metrics_, reinterpret_cast<const uint8_t*>(provider_session_token.c_str()),
oemcrypto_force_delete_usage_entry_, provider_session_token.length()),
status); metrics_,
if (OEMCrypto_SUCCESS != status) { oemcrypto_force_delete_usage_entry_,
LOGE("CryptoSession::DeleteUsageInformation: Delete Usage Table error =%ld", status);
status); if (OEMCrypto_SUCCESS != status) {
response = UNKNOWN_ERROR; LOGE("CryptoSession::DeleteUsageInformation: Delete Usage Table error "
} "= %ld", status);
M_TIME( response = UNKNOWN_ERROR;
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,58 +1268,46 @@ 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;
for (size_t i=0; i < provider_session_tokens.size(); ++i) { {
OEMCryptoResult status; AutoLock auto_lock(crypto_lock_);
M_TIME( for (size_t i=0; i < provider_session_tokens.size(); ++i) {
status = OEMCrypto_ForceDeleteUsageEntry( OEMCryptoResult status;
reinterpret_cast<const uint8_t*>(provider_session_tokens[i].c_str()), M_TIME(
provider_session_tokens[i].length()), status = OEMCrypto_ForceDeleteUsageEntry(
metrics_, reinterpret_cast<const uint8_t*>(
oemcrypto_force_delete_usage_entry_, provider_session_tokens[i].c_str()),
status); provider_session_tokens[i].length()),
if (OEMCrypto_SUCCESS != status) { metrics_,
LOGW("CryptoSession::DeleteMultipleUsageInformation: " oemcrypto_force_delete_usage_entry_,
"Delete Usage Table error =%ld", status); status);
response = UNKNOWN_ERROR; if (OEMCrypto_SUCCESS != status) {
LOGW("CryptoSession::DeleteMultipleUsageInformation: "
"Delete Usage Table error =%ld", status);
response = UNKNOWN_ERROR;
}
} }
} }
OEMCryptoResult status; UpdateUsageInformation();
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;
}
return response; return response;
} }
CdmResponseType CryptoSession::DeleteAllUsageReports() { CdmResponseType CryptoSession::DeleteAllUsageReports() {
LOGV("DeleteAllUsageReports"); LOGV("DeleteAllUsageReports");
OEMCryptoResult status; OEMCryptoResult status;
M_TIME( {
status = OEMCrypto_DeleteOldUsageTable(), AutoLock auto_lock(crypto_lock_);
metrics_, M_TIME(
oemcrypto_delete_usage_table_, status = OEMCrypto_DeleteOldUsageTable(),
status); metrics_,
if (OEMCrypto_SUCCESS != status) { oemcrypto_delete_usage_table_,
LOGE("CryptoSession::DeleteAllUsageReports: Delete Usage Table error =%ld", status);
status); if (OEMCrypto_SUCCESS != status) {
LOGE("CryptoSession::DeleteAllUsageReports: Delete Usage Table error "
"=%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;
} }