Enable usage reporting

[ Merge from Widevine CDM repo of
  https://widevine-internal-review.googlesource.com/#/c/10171/ and
  https://widevine-internal-review.googlesource.com/#/c/10172/ ]

Updated license_protocol.proto from constituent protos in google3

These changes make use of OEMCrypto v9 changes to support usage reporting.
Usage reporting may be enabled for streaming (by means of secure stops) and
offline playback by a provider session token specified in the license.

Changes include periodically updating usage information for relevant
sessions and reporting and releasing usage information as needed.

The CDM has removed all references to Secure Stops. This change
updates the Android API implementation to comply.

b/11987015

Change-Id: Ibb6f2ced4ef20ee349ca1ae6412ce686b2b5d085
This commit is contained in:
Rahul Frias
2014-05-17 09:31:41 -07:00
parent d68e1f8307
commit e56e58fbf5
20 changed files with 1573 additions and 261 deletions

View File

@@ -155,7 +155,7 @@ bool CryptoSession::GetDeviceUniqueId(std::string* device_id) {
return false;
}
device_id->assign(reinterpret_cast<char *>(&id[0]), id_length);
device_id->assign(reinterpret_cast<char*>(&id[0]), id_length);
return true;
}
@@ -340,12 +340,11 @@ size_t CryptoSession::GetOffset(std::string message, std::string field) {
return pos;
}
CdmResponseType CryptoSession::LoadKeys(const std::string& message,
const std::string& signature,
const std::string& mac_key_iv,
const std::string& mac_key,
int num_keys,
const CryptoKey* key_array) {
CdmResponseType CryptoSession::LoadKeys(
const std::string& message, const std::string& signature,
const std::string& mac_key_iv, const std::string& mac_key,
const std::vector<CryptoKey>& keys,
const std::string& provider_session_token) {
LOGV("CryptoSession::LoadKeys: Lock");
AutoLock auto_lock(crypto_lock_);
@@ -358,10 +357,10 @@ CdmResponseType CryptoSession::LoadKeys(const std::string& message,
} else {
LOGV("CryptoSession::LoadKeys: enc_mac_key not set");
}
std::vector<OEMCrypto_KeyObject> load_key_array(num_keys);
for (int i = 0; i < num_keys; ++i) {
const CryptoKey* ki = &key_array[i];
OEMCrypto_KeyObject* ko = &load_key_array[i];
std::vector<OEMCrypto_KeyObject> load_keys(keys.size());
for (size_t i = 0; i < keys.size(); ++i) {
const CryptoKey* ki = &keys[i];
OEMCrypto_KeyObject* ko = &load_keys[i];
ko->key_id = msg + GetOffset(message, ki->key_id());
ko->key_id_length = ki->key_id().length();
ko->key_data_iv = msg + GetOffset(message, ki->key_data_iv());
@@ -377,11 +376,17 @@ CdmResponseType CryptoSession::LoadKeys(const std::string& message,
ko->key_control = NULL;
}
}
uint8_t* pst = NULL;
if (!provider_session_token.empty()) {
pst =
const_cast<uint8_t*>(msg) + GetOffset(message, provider_session_token);
}
LOGV("LoadKeys: id=%ld", (uint32_t)oec_session_id_);
OEMCryptoResult sts = OEMCrypto_LoadKeys(
oec_session_id_, msg, message.size(),
reinterpret_cast<const uint8_t*>(signature.data()), signature.size(),
enc_mac_key_iv, enc_mac_key, num_keys, &load_key_array[0], NULL, 0);
enc_mac_key_iv, enc_mac_key, keys.size(), &load_keys[0], pst,
provider_session_token.length());
if (OEMCrypto_SUCCESS == sts) {
return KEY_ADDED;
@@ -613,6 +618,84 @@ CdmResponseType CryptoSession::Decrypt(const CdmDecryptionParameters& params) {
}
}
CdmResponseType CryptoSession::UpdateUsageInformation() {
return (OEMCrypto_UpdateUsageTable() == OEMCrypto_SUCCESS) ? NO_ERROR
: UNKNOWN_ERROR;
}
CdmResponseType CryptoSession::GenerateUsageReport(
const std::string& provider_session_token, std::string* usage_report) {
LOGV("GenerateUsageReport: id=%ld", (uint32_t)oec_session_id_);
if (NULL == usage_report) {
LOGE("usage_report parameter is null");
return UNKNOWN_ERROR;
}
AutoLock auto_lock(crypto_lock_);
uint8_t* pst = reinterpret_cast<uint8_t*>(
const_cast<char*>(provider_session_token.data()));
OEMCryptoResult status =
OEMCrypto_DeactivateUsageEntry(pst, provider_session_token.length());
if (OEMCrypto_SUCCESS != status) {
LOGE("CryptoSession::GenerateUsageReport: Deactivate Usage Entry error=%ld",
status);
return UNKNOWN_ERROR;
}
size_t usage_length = 0;
status = OEMCrypto_ReportUsage(oec_session_id_, pst,
provider_session_token.length(), NULL,
&usage_length);
if (OEMCrypto_ERROR_SHORT_BUFFER != status) {
LOGE("CryptoSession::GenerateUsageReport: Report Usage error=%ld", status);
return UNKNOWN_ERROR;
}
usage_report->resize(usage_length);
OEMCrypto_PST_Report* report = reinterpret_cast<OEMCrypto_PST_Report*>(
const_cast<char*>(usage_report->data()));
status = OEMCrypto_ReportUsage(oec_session_id_, pst,
provider_session_token.length(), report,
&usage_length);
if (OEMCrypto_SUCCESS != status) {
LOGE("CryptoSession::GenerateUsageReport: Report Usage error=%ld", status);
return UNKNOWN_ERROR;
}
if (usage_length < usage_report->length()) {
usage_report->resize(usage_length);
}
return NO_ERROR;
}
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<const uint8_t*>(message.data());
const uint8_t* sig = reinterpret_cast<const uint8_t*>(signature.data());
const uint8_t* pst = msg + GetOffset(message, provider_session_token);
OEMCryptoResult status = OEMCrypto_DeleteUsageEntry(
oec_session_id_, pst, provider_session_token.length(), msg,
message.length(), sig, signature.length());
if (OEMCrypto_SUCCESS != status) {
LOGE("CryptoSession::ReleaseUsageInformation: Report Usage error=%ld",
status);
return UNKNOWN_ERROR;
}
return NO_ERROR;
}
bool CryptoSession::GenerateNonce(uint32_t* nonce) {
if (!nonce) {
LOGE("input parameter is null");