From 826e390ad6ae039f0f881085b7cc0085c488d14b Mon Sep 17 00:00:00 2001 From: Rahul Frias Date: Mon, 13 Feb 2017 13:56:30 -0800 Subject: [PATCH] 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 --- .../cdm/core/include/device_files.h | 7 +- .../cdm/core/src/crypto_session.cpp | 234 ++++++++---------- libwvdrmengine/cdm/core/src/device_files.cpp | 83 ++++++- 3 files changed, 193 insertions(+), 131 deletions(-) diff --git a/libwvdrmengine/cdm/core/include/device_files.h b/libwvdrmengine/cdm/core/include/device_files.h index 89d6b41f..b0fa5ced 100644 --- a/libwvdrmengine/cdm/core/include/device_files.h +++ b/libwvdrmengine/cdm/core/include/device_files.h @@ -139,10 +139,15 @@ class DeviceFiles { virtual bool ListUsageInfoFiles(std::vector* usage_file_names); virtual bool RetrieveUsageInfo(const std::string& usage_info_file_name, std::vector* 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 virtual bool StoreUsageInfo(const std::string& usage_info_file_name, const std::vector& 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, const CdmHlsMethod method, diff --git a/libwvdrmengine/cdm/core/src/crypto_session.cpp b/libwvdrmengine/cdm/core/src/crypto_session.cpp index 0b630b8c..b105cf5b 100644 --- a/libwvdrmengine/cdm/core/src/crypto_session.cpp +++ b/libwvdrmengine/cdm/core/src/crypto_session.cpp @@ -430,28 +430,25 @@ CdmResponseType CryptoSession::Open(SecurityLevel requested_security_level) { void CryptoSession::Close() { LOGV("CloseSession: id=%ld open=%s", (uint32_t)oec_session_id_, open_ ? "true" : "false"); - AutoLock auto_lock(crypto_lock_); - if (!open_) return; OEMCryptoResult close_sts; - M_TIME( - close_sts = OEMCrypto_CloseSession( - oec_session_id_), - metrics_, - oemcrypto_close_session_, - close_sts); - if (OEMCrypto_SUCCESS == close_sts) { - open_ = false; - if (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); - } + bool update_usage_table = false; + { + AutoLock auto_lock(crypto_lock_); + if (!open_) return; + + M_TIME( + close_sts = OEMCrypto_CloseSession( + oec_session_id_), + metrics_, + oemcrypto_close_session_, + close_sts); + if (OEMCrypto_SUCCESS == close_sts) + open_ = false; + update_usage_table = update_usage_table_after_close_session_; + } + if (close_sts == OEMCrypto_SUCCESS && update_usage_table) { + UpdateUsageInformation(); } } @@ -623,27 +620,25 @@ CdmResponseType CryptoSession::LoadKeys( metrics_, oemcrypto_load_keys_, sts); + CdmResponseType result = KEY_ADDED; if (OEMCrypto_SUCCESS == sts) { - if (!provider_session_token.empty()) { + if (!provider_session_token.empty()) update_usage_table_after_close_session_ = true; - M_TIME( - sts = OEMCrypto_UpdateUsageTable(), - metrics_, - oemcrypto_update_usage_table_, - sts); - if (sts != OEMCrypto_SUCCESS) { - LOGW("CryptoSession::LoadKeys: OEMCrypto_UpdateUsageTable error=%ld", - sts); - } - } - return KEY_ADDED; + result = KEY_ADDED; } else if (OEMCrypto_ERROR_TOO_MANY_KEYS == sts) { LOGE("CryptoSession::LoadKeys: OEMCrypto_LoadKeys error=%d", sts); - return INSUFFICIENT_CRYPTO_RESOURCES; + result = INSUFFICIENT_CRYPTO_RESOURCES; } else { 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) { @@ -1053,6 +1048,13 @@ CdmResponseType CryptoSession::UpdateUsageInformation() { AutoLock auto_lock(crypto_lock_); 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; M_TIME( status = OEMCrypto_UpdateUsageTable(), @@ -1207,40 +1209,34 @@ CdmResponseType CryptoSession::ReleaseUsageInformation( const std::string& message, const std::string& signature, const std::string& provider_session_token) { LOGV("ReleaseUsageInformation: id=%ld", (uint32_t)oec_session_id_); - AutoLock auto_lock(crypto_lock_); - const uint8_t* msg = reinterpret_cast(message.data()); - const uint8_t* sig = reinterpret_cast(signature.data()); - const uint8_t* pst = msg + GetOffset(message, provider_session_token); + { + AutoLock auto_lock(crypto_lock_); + const uint8_t* msg = reinterpret_cast(message.data()); + const uint8_t* sig = reinterpret_cast(signature.data()); + const uint8_t* pst = msg + GetOffset(message, provider_session_token); - OEMCryptoResult status; - M_TIME( - status = OEMCrypto_DeleteUsageEntry( - oec_session_id_, - pst, - provider_session_token.length(), - msg, - message.length(), - sig, - signature.length()), - metrics_, - oemcrypto_delete_usage_entry_, - status); + OEMCryptoResult status; + M_TIME( + status = OEMCrypto_DeleteUsageEntry( + oec_session_id_, + pst, + provider_session_token.length(), + msg, + message.length(), + sig, + signature.length()), + metrics_, + oemcrypto_delete_usage_entry_, + status); - if (OEMCrypto_SUCCESS != status) { - LOGE("CryptoSession::ReleaseUsageInformation: Report Usage error=%ld", - status); - 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); + if (OEMCrypto_SUCCESS != status) { + LOGE("CryptoSession::ReleaseUsageInformation: Report Usage error=%ld", + status); + return UNKNOWN_ERROR; + } } + UpdateUsageInformation(); return NO_ERROR; } @@ -1249,28 +1245,22 @@ CdmResponseType CryptoSession::DeleteUsageInformation( CdmResponseType response = NO_ERROR; LOGV("CryptoSession::DeleteUsageInformation"); OEMCryptoResult status; - M_TIME( - status = OEMCrypto_ForceDeleteUsageEntry( - reinterpret_cast(provider_session_token.c_str()), - provider_session_token.length()), - metrics_, - oemcrypto_force_delete_usage_entry_, - status); - if (OEMCrypto_SUCCESS != status) { - LOGE("CryptoSession::DeleteUsageInformation: Delete Usage Table error =%ld", - status); - 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; + { + AutoLock auto_lock(crypto_lock_); + M_TIME( + status = OEMCrypto_ForceDeleteUsageEntry( + reinterpret_cast(provider_session_token.c_str()), + provider_session_token.length()), + metrics_, + oemcrypto_force_delete_usage_entry_, + status); + if (OEMCrypto_SUCCESS != status) { + LOGE("CryptoSession::DeleteUsageInformation: Delete Usage Table error " + "= %ld", status); + response = UNKNOWN_ERROR; + } } + UpdateUsageInformation(); return response; } @@ -1278,58 +1268,46 @@ CdmResponseType CryptoSession::DeleteMultipleUsageInformation( const std::vector& provider_session_tokens) { LOGV("CryptoSession::DeleteMultipleUsageInformation"); CdmResponseType response = NO_ERROR; - for (size_t i=0; i < provider_session_tokens.size(); ++i) { - OEMCryptoResult status; - M_TIME( - status = OEMCrypto_ForceDeleteUsageEntry( - reinterpret_cast(provider_session_tokens[i].c_str()), - provider_session_tokens[i].length()), - metrics_, - oemcrypto_force_delete_usage_entry_, - status); - if (OEMCrypto_SUCCESS != status) { - LOGW("CryptoSession::DeleteMultipleUsageInformation: " - "Delete Usage Table error =%ld", status); - response = UNKNOWN_ERROR; + { + AutoLock auto_lock(crypto_lock_); + for (size_t i=0; i < provider_session_tokens.size(); ++i) { + OEMCryptoResult status; + M_TIME( + status = OEMCrypto_ForceDeleteUsageEntry( + reinterpret_cast( + provider_session_tokens[i].c_str()), + provider_session_tokens[i].length()), + metrics_, + oemcrypto_force_delete_usage_entry_, + status); + if (OEMCrypto_SUCCESS != status) { + LOGW("CryptoSession::DeleteMultipleUsageInformation: " + "Delete Usage Table error =%ld", status); + 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; } CdmResponseType CryptoSession::DeleteAllUsageReports() { LOGV("DeleteAllUsageReports"); OEMCryptoResult status; - M_TIME( - status = OEMCrypto_DeleteOldUsageTable(), - metrics_, - oemcrypto_delete_usage_table_, - status); - if (OEMCrypto_SUCCESS != status) { - LOGE("CryptoSession::DeleteAllUsageReports: Delete Usage Table error =%ld", - status); + { + AutoLock auto_lock(crypto_lock_); + M_TIME( + status = OEMCrypto_DeleteOldUsageTable(), + metrics_, + oemcrypto_delete_usage_table_, + status); + if (OEMCrypto_SUCCESS != status) { + LOGE("CryptoSession::DeleteAllUsageReports: Delete Usage Table error " + "=%ld", status); + } } - M_TIME( - status = OEMCrypto_UpdateUsageTable(), - metrics_, - oemcrypto_update_usage_table_, - status); - if (status != OEMCrypto_SUCCESS) { - LOGE("CryptoSession::DeletaAllUsageReports: update table error=%ld", - status); - return UNKNOWN_ERROR; - } + UpdateUsageInformation(); return NO_ERROR; } @@ -1879,7 +1857,7 @@ CdmResponseType CryptoSession::CreateUsageTableHeader( } if (result != OEMCrypto_SUCCESS) { - LOGE("CreateUsageTableHeader; usage table header creation failed: %d", + LOGE("CreateUsageTableHeader: usage table header creation failed: %d", result); return CREATE_USAGE_TABLE_ERROR; } diff --git a/libwvdrmengine/cdm/core/src/device_files.cpp b/libwvdrmengine/cdm/core/src/device_files.cpp index 5b9f92ac..28fd0222 100644 --- a/libwvdrmengine/cdm/core/src/device_files.cpp +++ b/libwvdrmengine/cdm/core/src/device_files.cpp @@ -51,7 +51,7 @@ const char kUsageInfoFileNamePrefix[] = "usage"; const char kUsageInfoFileNameExt[] = ".bin"; const char kLicenseFileNameExt[] = ".lic"; const char kEmptyFileName[] = ""; -const char kUsageTableFileName[] = "usagetable.bin"; +const char kUsageTableFileName[] = "usgtable.bin"; const char kWildcard[] = "*"; 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); } +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, std::vector* usage_data) { - if (!initialized_) { LOGW("DeviceFiles::RetrieveUsageInfo: not initialized"); 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; if (!RetrieveHashedFile(usage_info_file_name, &file)) { return false; @@ -649,6 +695,39 @@ bool DeviceFiles::RetrieveUsageInfo(const std::string& usage_info_file_name, 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; }