Revise a few metrics and add unit tests.

This is a merge of Widevine cl 39040.

A few of the metrics were not implemented, or implemented incorrectly in
O MR1. This cleans them up

Bug: 64001676

Test: Re-ran unit tests and added some additional tests. GPlay Movies check.

Change-Id: I1e8bcc36fecd76e72d853306075bc46d82f45161
This commit is contained in:
Adam Stone
2018-01-23 17:43:35 -08:00
parent 7bbe8e3bf1
commit 795cf8a624
12 changed files with 320 additions and 89 deletions

View File

@@ -75,7 +75,6 @@ class CryptoSession {
explicit CryptoSession(metrics::CryptoMetrics* crypto_metrics);
virtual ~CryptoSession();
virtual bool GetClientToken(std::string* client_token);
virtual bool GetProvisioningToken(std::string* client_token);
virtual CdmClientTokenType GetPreProvisionTokenType() {
return pre_provision_token_type_;
@@ -227,6 +226,7 @@ class CryptoSession {
bool GetTokenFromOemCert(std::string* token);
static bool ExtractSystemIdFromOemCert(const std::string& oem_cert,
uint32_t* system_id);
bool GetSystemIdInternal(uint32_t* system_id);
bool GenerateSignature(const std::string& message, std::string* signature);
bool GenerateRsaSignature(const std::string& message, std::string* signature);
@@ -273,6 +273,7 @@ class CryptoSession {
metrics::CryptoMetrics* metrics_;
metrics::TimerMetric life_span_;
uint32_t system_id_;
bool open_;
CdmClientTokenType pre_provision_token_type_;

View File

@@ -318,6 +318,7 @@ enum CdmResponseType {
RELEASE_ALL_USAGE_INFO_ERROR_7 = 276,
LICENSE_REQUEST_INVALID_SUBLICENSE = 277,
CERT_PROVISIONING_EMPTY_SERVICE_CERTIFICATE = 278,
LOAD_SYSTEM_ID_ERROR = 279,
};
enum CdmKeyStatus {

View File

@@ -480,17 +480,16 @@ CdmResponseType CdmEngine::QueryStatus(SecurityLevel security_level,
std::string* query_response) {
LOGI("CdmEngine::QueryStatus");
CryptoSession crypto_session(metrics_.GetCryptoMetrics());
if (security_level == kLevel3) {
CdmResponseType status;
M_TIME(
status = crypto_session.Open(
kLevel3),
metrics_.GetCryptoMetrics(),
crypto_session_open_,
status,
kLevel3);
if (NO_ERROR != status) return INVALID_QUERY_STATUS;
}
CdmResponseType status;
M_TIME(
status = crypto_session.Open(
security_level),
metrics_.GetCryptoMetrics(),
crypto_session_open_,
status,
security_level);
if (status != NO_ERROR)
return INVALID_QUERY_STATUS;
if (!query_response) {
LOGE("CdmEngine::QueryStatus: no query response destination");

View File

@@ -23,6 +23,7 @@
#include "wv_cdm_constants.h"
namespace {
// Encode unsigned integer into a big endian formatted string
std::string EncodeUint32(unsigned int u) {
std::string s;
@@ -32,6 +33,7 @@ std::string EncodeUint32(unsigned int u) {
s.append(1, (u >> 0) & 0xFF);
return s;
}
size_t GetOffset(std::string message, std::string field) {
size_t pos = message.find(field);
if (pos == std::string::npos) {
@@ -40,6 +42,7 @@ size_t GetOffset(std::string message, std::string field) {
}
return pos;
}
void GenerateMacContext(const std::string& input_context,
std::string* deriv_context) {
if (!deriv_context) {
@@ -677,6 +680,7 @@ class SubLicenseKeySession : public KeySession {
CryptoSession::CryptoSession(metrics::CryptoMetrics* metrics)
: metrics_(metrics),
system_id_(-1),
open_(false),
update_usage_table_after_close_session_(false),
is_destination_buffer_type_valid_(false),
@@ -700,9 +704,11 @@ CryptoSession::~CryptoSession() {
}
bool CryptoSession::GetProvisioningMethod(CdmClientTokenType* token_type) {
OEMCrypto_ProvisioningMethod method;
OEMCrypto_ProvisioningMethod method =
OEMCrypto_GetProvisioningMethod(requested_security_level_);
metrics_->oemcrypto_provisioning_method_.Record(method);
CdmClientTokenType type;
switch (method = OEMCrypto_GetProvisioningMethod(requested_security_level_)) {
switch (method) {
case OEMCrypto_OEMCertificate:
type = kClientTokenOemCert;
break;
@@ -714,7 +720,8 @@ bool CryptoSession::GetProvisioningMethod(CdmClientTokenType* token_type) {
break;
case OEMCrypto_ProvisioningError:
default:
LOGE("OEMCrypto_GetProvisioningMethod failed", method);
LOGE("OEMCrypto_GetProvisioningMethod failed. %d", method);
metrics_->oemcrypto_provisioning_method_.SetError(method);
return false;
}
*token_type = type;
@@ -805,13 +812,14 @@ bool CryptoSession::GetTokenFromOemCert(std::string* token) {
size_t buf_size = temp_buffer.size();
uint8_t* buf = reinterpret_cast<uint8_t*>(&temp_buffer[0]);
status = OEMCrypto_GetOEMPublicCertificate(oec_session_id_, buf, &buf_size);
metrics_->oemcrypto_get_oem_public_certificate_.Increment(status);
if (OEMCrypto_SUCCESS == status) {
temp_buffer.resize(buf_size);
oem_token_.assign(temp_buffer);
token->assign(temp_buffer);
return true;
}
if (OEMCrypto_ERROR_SHORT_BUFFER && !retrying) {
if (status == OEMCrypto_ERROR_SHORT_BUFFER && !retrying) {
temp_buffer.resize(buf_size);
retrying = true;
continue;
@@ -821,42 +829,28 @@ bool CryptoSession::GetTokenFromOemCert(std::string* token) {
}
}
bool CryptoSession::GetClientToken(std::string* token) {
if (!token) {
LOGE("CryptoSession::GetClientToken : No token passed to method.");
return false;
}
LOGV("CryptoSession::GetClientToken: Lock");
AutoLock auto_lock(crypto_lock_);
if (!initialized_) {
return false;
}
// Only keybox is used for client token. All other cases use DRM Cert.
if (pre_provision_token_type_ != kClientTokenKeybox) {
return false;
}
return GetTokenFromKeybox(token);
}
bool CryptoSession::GetProvisioningToken(std::string* token) {
if (!token) {
LOGE("CryptoSession::GetProvisioningToken : No token passed to method.");
metrics_->crypto_session_get_token_.Increment(false);
return false;
}
LOGV("CryptoSession::GetProvisioningToken: Lock");
AutoLock auto_lock(crypto_lock_);
if (!initialized_) {
metrics_->crypto_session_get_token_.Increment(false);
return false;
}
bool result = false;
if (pre_provision_token_type_ == kClientTokenKeybox) {
return GetTokenFromKeybox(token);
result = GetTokenFromKeybox(token);
} else if (pre_provision_token_type_ == kClientTokenOemCert) {
return GetTokenFromOemCert(token);
} else {
return false;
result = GetTokenFromOemCert(token);
}
metrics_->crypto_session_get_token_.Increment(result);
return result;
}
CdmSecurityLevel CryptoSession::GetSecurityLevel() {
@@ -977,7 +971,19 @@ bool CryptoSession::GetSystemId(uint32_t* system_id) {
LOGV("CryptoSession::GetSystemId: Lock");
AutoLock auto_lock(crypto_lock_);
if (!initialized_) {
if (!initialized_ || !open_) {
return false;
}
*system_id = system_id_;
return true;
}
// This method gets the system id from the keybox key data.
// This method assumes that OEMCrypto has been initialized and that
// the caller has acquired the crypto_lock_ before making this call.
bool CryptoSession::GetSystemIdInternal(uint32_t* system_id) {
if (!system_id) {
LOGE("CryptoSession::GetSystemIdInternal: No system_id passed to method.");
return false;
}
@@ -991,8 +997,8 @@ bool CryptoSession::GetSystemId(uint32_t* system_id) {
metrics_, oemcrypto_get_key_data_, sts, metrics::Pow2Bucket(buf_size));
if (OEMCrypto_SUCCESS != sts) {
LOGE("CryptoSession::GetSystemId: OEMCrypto_GetKeyData failed with %d",
sts);
LOGE("CryptoSession::GetSystemIdInternal: "
"OEMCrypto_GetKeyData failed with %d", sts);
return false;
}
@@ -1010,9 +1016,13 @@ bool CryptoSession::GetSystemId(uint32_t* system_id) {
} else {
return false;
}
} else if (pre_provision_token_type_ == kClientTokenDrmCert) {
// TODO(blueeyes): Support loading the system id from a pre-provisioned
// Drm certificate.
return true;
} else {
LOGE("CryptoSession::GetSystemId: Unsupported pre-provision token type %d",
pre_provision_token_type_);
LOGE("CryptoSession::GetSystemIdInternal: "
"Unsupported pre-provision token type %d", pre_provision_token_type_);
return false;
}
}
@@ -1023,7 +1033,8 @@ bool CryptoSession::ExtractSystemIdFromOemCert(const std::string& oem_cert,
const boringssl_ptr<STACK_OF(X509), DeleteX509Stack> x509_stack(
sk_X509_new_null());
if (x509_stack.get() == NULL) {
LOGE("CryptoSession::GetSystemId: Unable to allocate X509 Stack.");
LOGE("CryptoSession::ExtractSystemIdFromOemCert: "
"Unable to allocate X509 Stack.");
return false;
}
@@ -1031,7 +1042,8 @@ bool CryptoSession::ExtractSystemIdFromOemCert(const std::string& oem_cert,
CBS_init(&pkcs7, reinterpret_cast<const uint8_t*>(oem_cert.data()),
oem_cert.size());
if (!PKCS7_get_certificates(x509_stack.get(), &pkcs7)) {
LOGE("CryptoSession::GetSystemId: Error getting certificate chain.");
LOGE("CryptoSession::ExtractSystemIdFromOemCert: "
"Error getting certificate chain.");
return false;
}
@@ -1039,14 +1051,16 @@ bool CryptoSession::ExtractSystemIdFromOemCert(const std::string& oem_cert,
// Get the Widevine intermediate cert from the stack
if (sk_X509_num(certs) != 2) {
LOGE("CryptoSession::GetSystemId: Expected 2 certificates in chain, got %d",
LOGE("CryptoSession::ExtractSystemIdFromOemCert: "
"Expected 2 certificates in chain, got %d",
sk_X509_num(certs));
return false;
}
X509* const intermediate_cert = sk_X509_value(certs, 1);
if (!intermediate_cert) {
LOGE("CryptoSession::GetSystemId: Unable to get intermediate cert.");
LOGE("CryptoSession::ExtractSystemIdFromOemCert: "
"Unable to get intermediate cert.");
return false;
}
@@ -1055,16 +1069,15 @@ bool CryptoSession::ExtractSystemIdFromOemCert(const std::string& oem_cert,
for (int i = 0; i < extension_count; ++i) {
X509_EXTENSION* const extension = X509_get_ext(intermediate_cert, i);
if (!extension) {
LOGE("CryptoSession::GetSystemId: Unable to get cert extension %d", i);
LOGE("CryptoSession::ExtractSystemIdFromOemCert: "
"Unable to get cert extension %d", i);
continue;
}
ASN1_OBJECT* const extension_object = X509_EXTENSION_get_object(extension);
if (!extension_object) {
LOGE(
"CryptoSession::GetSystemId: Unable to get object of cert "
"extension %d",
i);
LOGE("CryptoSession::ExtractSystemIdFromOemCert: "
"Unable to get object of cert extension %d", i);
continue;
}
@@ -1078,35 +1091,31 @@ bool CryptoSession::ExtractSystemIdFromOemCert(const std::string& oem_cert,
ASN1_OCTET_STRING* const octet_str = X509_EXTENSION_get_data(extension);
if (!octet_str) {
LOGE(
"CryptoSession::GetSystemId: Unable to get data of Widevine System "
"ID extension.");
LOGE("CryptoSession::ExtractSystemIdFromOemCert: "
"Unable to get data of Widevine System ID extension.");
return false;
}
const unsigned char* data = octet_str->data;
if (!data) {
LOGE(
"CryptoSession::GetSystemId: Null data in Widevine System ID "
"extension.");
LOGE("CryptoSession::ExtractSystemIdFromOemCert: "
"Null data in Widevine System ID extension.");
return false;
}
ASN1_INTEGER* const asn1_integer =
d2i_ASN1_INTEGER(NULL, &data, octet_str->length);
if (!asn1_integer) {
LOGE(
"CryptoSession::GetSystemId: Unable to decode data in Widevine "
"System ID extension.");
LOGE("CryptoSession::ExtractSystemIdFromOemCert: "
"Unable to decode data in Widevine System ID extension.");
return false;
}
const long system_id_long = ASN1_INTEGER_get(asn1_integer);
ASN1_INTEGER_free(asn1_integer);
if (system_id_long == -1) {
LOGE(
"CryptoSession::GetSystemId: Unable to decode ASN integer in "
"Widevine System ID extension.");
LOGE("CryptoSession::ExtractSystemIdFromOemCert: "
"Unable to decode ASN integer in Widevine System ID extension.");
return false;
}
@@ -1114,7 +1123,8 @@ bool CryptoSession::ExtractSystemIdFromOemCert(const std::string& oem_cert,
return true;
}
LOGE("CryptoSession::GetSystemId: Widevine System ID extension not found.");
LOGE("CryptoSession::ExtractSystemIdFromOemCert: "
"Widevine System ID extension not found.");
return false;
}
@@ -1191,13 +1201,25 @@ CdmResponseType CryptoSession::Open(SecurityLevel requested_security_level) {
session_count_, (int)initialized_);
return UNKNOWN_ERROR;
}
// Get System ID and save it.
if (GetSystemIdInternal(&system_id_)) {
metrics_->crypto_session_system_id_.Record(system_id_);
} else {
LOGE("CryptoSession::Open: Failed to fetch system id.");
metrics_->crypto_session_system_id_.SetError(LOAD_SYSTEM_ID_ERROR);
return LOAD_SYSTEM_ID_ERROR;
}
OEMCryptoResult random_sts = OEMCrypto_GetRandom(
reinterpret_cast<uint8_t*>(&request_id_base_), sizeof(request_id_base_));
metrics_->oemcrypto_get_random_.Increment(random_sts);
++request_id_index_;
CdmUsageSupportType usage_support_type;
if (GetUsageSupportType(&usage_support_type) == NO_ERROR) {
CdmResponseType result = GetUsageSupportType(&usage_support_type);
if (result == NO_ERROR) {
metrics_->oemcrypto_usage_table_support_.Record(usage_support_type);
if (usage_support_type == kUsageEntrySupport) {
CdmSecurityLevel security_level = GetSecurityLevel();
if (security_level == kSecurityLevelL1 ||
@@ -1224,6 +1246,8 @@ CdmResponseType CryptoSession::Open(SecurityLevel requested_security_level) {
usage_table_header_ = *header;
}
}
} else {
metrics_->oemcrypto_usage_table_support_.SetError(result);
}
// TODO(gmorgan, jfore): resolve handling of usage records in sublicenses
@@ -1361,6 +1385,7 @@ bool CryptoSession::LoadCertificatePrivateKey(std::string& wrapped_key) {
uint8_t* buf = reinterpret_cast<uint8_t*>(&temp_buffer[0]);
OEMCryptoResult sts =
OEMCrypto_GetOEMPublicCertificate(oec_session_id_, buf, &buf_size);
metrics_->oemcrypto_get_oem_public_certificate_.Increment(sts);
LOGV("LoadDeviceRSAKey: id=%ld", (uint32_t)oec_session_id_);
M_TIME(
@@ -2032,10 +2057,15 @@ bool CryptoSession::RewrapDeviceRSAKey30(const std::string& message,
// Gets wrapped_rsa_key_length by passing NULL as uint8_t* wrapped_rsa_key
// and 0 as wrapped_rsa_key_length.
size_t wrapped_private_key_length = 0;
OEMCryptoResult status = OEMCrypto_RewrapDeviceRSAKey30(
oec_session_id_, msg_nonce, msg_wrapping_key, wrapping_key.size(),
msg_private_key, private_key.size(), msg_iv, NULL,
&wrapped_private_key_length);
OEMCryptoResult status;
M_TIME(
status = OEMCrypto_RewrapDeviceRSAKey30(
oec_session_id_, msg_nonce, msg_wrapping_key, wrapping_key.size(),
msg_private_key, private_key.size(), msg_iv, NULL,
&wrapped_private_key_length),
metrics_,
oemcrypto_rewrap_device_rsa_key_30_,
status);
if (status != OEMCrypto_ERROR_SHORT_BUFFER) {
LOGE("OEMCrypto_RewrapDeviceRSAKey30 failed getting wrapped key length");
@@ -2043,11 +2073,15 @@ bool CryptoSession::RewrapDeviceRSAKey30(const std::string& message,
}
wrapped_private_key->resize(wrapped_private_key_length);
status = OEMCrypto_RewrapDeviceRSAKey30(
oec_session_id_, msg_nonce, msg_wrapping_key, wrapping_key.size(),
msg_private_key, private_key.size(), msg_iv,
reinterpret_cast<uint8_t*>(&(*wrapped_private_key)[0]),
&wrapped_private_key_length);
M_TIME(
status = OEMCrypto_RewrapDeviceRSAKey30(
oec_session_id_, msg_nonce, msg_wrapping_key, wrapping_key.size(),
msg_private_key, private_key.size(), msg_iv,
reinterpret_cast<uint8_t*>(&(*wrapped_private_key)[0]),
&wrapped_private_key_length),
metrics_,
oemcrypto_rewrap_device_rsa_key_30_,
status);
wrapped_private_key->resize(wrapped_private_key_length);

View File

@@ -5,7 +5,11 @@
#include <gtest/gtest.h>
#include "crypto_session.h"
#include "log.h"
#include "metrics_collections.h"
#include "metrics.pb.h"
#include "scoped_ptr.h"
#include "wv_cdm_types.h"
namespace {
@@ -245,4 +249,188 @@ TEST(CryptoSessionTest, CanExtractSystemIdFromOemCertificate) {
ASSERT_EQ(kOemCertSystemId, system_id);
}
class CryptoSessionMetricsTest : public testing::Test {
protected:
void MakeMetricMap(
const drm_metrics::MetricsGroup& metric_group,
std::map<std::string, drm_metrics::MetricsGroup::Metric>* metric_map) {
std::transform(metric_group.metric().begin(),
metric_group.metric().end(),
std::inserter(*metric_map, metric_map->end()),
CryptoSessionMetricsTest::MakeMetricPair);
}
bool FindMetric(
const std::map<std::string,
drm_metrics::MetricsGroup::Metric>& metric_map,
const std::string& metric_name,
drm_metrics::MetricsGroup::Metric* metric) {
std::map<std::string,
drm_metrics::MetricsGroup::Metric>::const_iterator it =
metric_map.find(metric_name);
if (it == metric_map.end()) {
return false;
}
*metric = it->second;
return true;
}
private:
static std::pair<std::string, drm_metrics::MetricsGroup::Metric>
MakeMetricPair(const drm_metrics::MetricsGroup::Metric& metric) {
LOGV("Metric: %s", metric.name().c_str());
return std::make_pair(metric.name(), metric);
}
};
TEST_F(CryptoSessionMetricsTest, OpenSessionValidMetrics) {
metrics::CryptoMetrics crypto_metrics;
CryptoSession session(&crypto_metrics);
session.Open(wvcdm::kLevelDefault);
drm_metrics::MetricsGroup actual_metrics;
crypto_metrics.Serialize(&actual_metrics);
// TODO(blueeyes): If we an convert to use full proto rather than proto lite,
// convert these tests to use Message-based convenience functions.
std::map<std::string, drm_metrics::MetricsGroup::Metric> metric_map;
MakeMetricMap(actual_metrics, &metric_map);
// Validate common metrics regardless of provisioning type.
drm_metrics::MetricsGroup::Metric metric;
EXPECT_TRUE(FindMetric(
metric_map,
"/drm/widevine/oemcrypto/initialize/time/count{oemcrypto_error:0}",
&metric));
EXPECT_EQ(metric.value().int_value(), 1);
EXPECT_TRUE(FindMetric(
metric_map,
"/drm/widevine/oemcrypto/initialize/time/mean{oemcrypto_error:0}",
&metric));
EXPECT_TRUE(metric.value().has_double_value());
CdmUsageSupportType usage_type;
ASSERT_EQ(NO_ERROR, session.GetUsageSupportType(&usage_type));
EXPECT_TRUE(FindMetric(
metric_map,
"/drm/widevine/oemcrypto/usage_table_support",
&metric));
EXPECT_EQ(metric.value().int_value(), usage_type);
// Validate metrics that differ based on provisioning type.
CdmClientTokenType token_type = session.GetPreProvisionTokenType();
if (token_type == kClientTokenKeybox) {
EXPECT_TRUE(FindMetric(
metric_map, "/drm/widevine/crypto_session/system_id", &metric));
EXPECT_EQ(metric.value().int_value(), 4121);
EXPECT_TRUE(FindMetric(
metric_map,
"/drm/widevine/oemcrypto/provisioning_method",
&metric));
EXPECT_EQ(metric.value().int_value(), OEMCrypto_Keybox);
EXPECT_TRUE(FindMetric(
metric_map,
"/drm/widevine/oemcrypto/get_key_data/time/count"
"{oemcrypto_error:0&length:64}",
&metric));
EXPECT_GE(metric.value().int_value(), 1);
EXPECT_TRUE(FindMetric(
metric_map,
"/drm/widevine/oemcrypto/get_key_data/time/mean"
"{oemcrypto_error:0&length:64}",
&metric));
EXPECT_TRUE(metric.value().has_double_value());
} else if (token_type == kClientTokenOemCert) {
EXPECT_TRUE(FindMetric(
metric_map, "/drm/widevine/crypto_session/system_id", &metric));
EXPECT_EQ(metric.value().int_value(), 7346);
EXPECT_TRUE(FindMetric(
metric_map,
"/drm/widevine/oemcrypto/provisioning_method",
&metric));
EXPECT_EQ(metric.value().int_value(), OEMCrypto_OEMCertificate);
EXPECT_TRUE(FindMetric(
metric_map,
"/drm/widevine/oemcrypto/get_oem_public_certificate/count"
"{oemcrypto_error:0}",
&metric));
EXPECT_EQ(metric.value().int_value(), 1);
} else if (token_type == kClientTokenDrmCert) {
// TODO(blueeyes): Add support for getting the system id from a
// pre-installed DRM certificate..
} else {
FAIL() << "Unexpected token type: " << token_type;
}
}
TEST_F(CryptoSessionMetricsTest, GetProvisioningTokenValidMetrics) {
metrics::CryptoMetrics crypto_metrics;
CryptoSession session(&crypto_metrics);
ASSERT_EQ(NO_ERROR, session.Open(wvcdm::kLevelDefault));
CdmClientTokenType token_type = session.GetPreProvisionTokenType();
LOGI("token_type: %d", token_type);
// DRM Certificate provisioning method does not support a provisioning
// token. Otherwise, we should be able to fetch the token.
std::string token;
if (token_type != kClientTokenDrmCert) {
ASSERT_TRUE(session.GetProvisioningToken(&token));
}
drm_metrics::MetricsGroup actual_metrics;
crypto_metrics.Serialize(&actual_metrics);
std::map<std::string, drm_metrics::MetricsGroup::Metric> metric_map;
MakeMetricMap(actual_metrics, &metric_map);
drm_metrics::MetricsGroup::Metric metric;
if (token_type == kClientTokenKeybox) {
// TODO(blueeyes): Add more metrics verifications.
ASSERT_TRUE(FindMetric(
metric_map, "/drm/widevine/crypto_session/get_token/count{success:1}",
&metric));
EXPECT_EQ(metric.value().int_value(), 1);
EXPECT_TRUE(FindMetric(
metric_map, "/drm/widevine/crypto_session/system_id",
&metric));
EXPECT_EQ(metric.value().int_value(), 4121);
EXPECT_TRUE(FindMetric(
metric_map,
"/drm/widevine/oemcrypto/get_key_data/time/count"
"{oemcrypto_error:0&length:64}",
&metric));
EXPECT_GE(metric.value().int_value(), 1);
} else if (token_type == kClientTokenOemCert) {
// TODO(blueeyes): Add more metrics verifications.
ASSERT_TRUE(FindMetric(
metric_map, "/drm/widevine/crypto_session/get_token/count{success:1}",
&metric));
EXPECT_EQ(metric.value().int_value(), 1);
EXPECT_TRUE(FindMetric(
metric_map, "/drm/widevine/crypto_session/system_id",
&metric));
EXPECT_EQ(metric.value().int_value(), 7346);
EXPECT_TRUE(FindMetric(
metric_map,
"/drm/widevine/oemcrypto/get_oem_public_certificate/count"
"{oemcrypto_error:0}",
&metric));
EXPECT_EQ(metric.value().int_value(), 1);
} else {
ASSERT_FALSE(FindMetric(
metric_map, "/drm/widevine/crypto_session/get_token/count{success:1}",
&metric));
}
}
} // namespace wvcdm

View File

@@ -568,6 +568,12 @@ void PrintTo(const enum CdmResponseType& value, ::std::ostream* os) {
case LICENSE_REQUEST_INVALID_SUBLICENSE:
*os << "LICENSE_REQUEST_INVALID_SUBLICENSE";
break;
case CERT_PROVISIONING_EMPTY_SERVICE_CERTIFICATE:
*os << "CERT_PROVISIONING_EMPTY_SERVICE_CERTIFICATE";
break;
case LOAD_SYSTEM_ID_ERROR:
*os << "LOAD_SYSTEM_ID_ERROR";
break;
default:
*os << "Unknown CdmResponseType";
break;

View File

@@ -128,7 +128,6 @@ class CryptoMetrics {
CounterMetric<OEMCryptoResult> oemcrypto_get_oem_public_certificate_;
CounterMetric<OEMCryptoResult> oemcrypto_get_random_;
EventMetric<OEMCryptoResult> oemcrypto_initialize_;
EventMetric<OEMCryptoResult> oemcrypto_install_keybox_;
ValueMetric<bool> oemcrypto_is_anti_rollback_hw_present_;
ValueMetric<bool> oemcrypto_is_keybox_valid_;
EventMetric<OEMCryptoResult> oemcrypto_load_device_rsa_key_;
@@ -143,9 +142,8 @@ class CryptoMetrics {
EventMetric<OEMCryptoResult> oemcrypto_rewrap_device_rsa_key_30_;
ValueMetric<uint16_t> oemcrypto_security_patch_level_;
EventMetric<OEMCryptoResult> oemcrypto_select_key_;
ValueMetric<bool> oemcrypto_supports_usage_table_;
ValueMetric<CdmUsageSupportType> oemcrypto_usage_table_support_;
CounterMetric<OEMCryptoResult> oemcrypto_update_usage_table_;
EventMetric<OEMCryptoResult> oemcrypto_wrap_keybox_;
};
// This class contains session-scoped metrics. All properties and

View File

@@ -189,9 +189,6 @@ CryptoMetrics::CryptoMetrics() :
oemcrypto_initialize_(
"/drm/widevine/oemcrypto/initialize/time",
"oemcrypto_error"),
oemcrypto_install_keybox_(
"/drm/widevine/oemcrypto/install_keybox/time",
"oemcrypto_error"),
oemcrypto_is_anti_rollback_hw_present_(
"/drm/widevine/oemcrypto/is_anti_rollback_hw_present"),
oemcrypto_is_keybox_valid_(
@@ -227,13 +224,10 @@ CryptoMetrics::CryptoMetrics() :
oemcrypto_select_key_(
"/drm/widevine/oemcrypto/select_key/time",
"oemcrypto_error"),
oemcrypto_supports_usage_table_(
"/drm/widevine/oemcrypto/supports_usage_table"),
oemcrypto_usage_table_support_(
"/drm/widevine/oemcrypto/usage_table_support"),
oemcrypto_update_usage_table_(
"/drm/widevine/oemcrypto/update_usage_table",
"oemcrypto_error"),
oemcrypto_wrap_keybox_(
"/drm/widevine/oemcrypto/wrap_keybox/time",
"oemcrypto_error") {
}
@@ -280,7 +274,6 @@ void CryptoMetrics::Serialize(MetricsGroup* metrics) {
oemcrypto_get_oem_public_certificate_.Serialize(&serializer);
oemcrypto_get_random_.Serialize(&serializer);
oemcrypto_initialize_.Serialize(&serializer);
oemcrypto_install_keybox_.Serialize(&serializer);
oemcrypto_is_anti_rollback_hw_present_.Serialize(&serializer);
oemcrypto_is_keybox_valid_.Serialize(&serializer);
oemcrypto_load_device_rsa_key_.Serialize(&serializer);
@@ -295,9 +288,8 @@ void CryptoMetrics::Serialize(MetricsGroup* metrics) {
oemcrypto_rewrap_device_rsa_key_30_.Serialize(&serializer);
oemcrypto_security_patch_level_.Serialize(&serializer);
oemcrypto_select_key_.Serialize(&serializer);
oemcrypto_supports_usage_table_.Serialize(&serializer);
oemcrypto_usage_table_support_.Serialize(&serializer);
oemcrypto_update_usage_table_.Serialize(&serializer);
oemcrypto_wrap_keybox_.Serialize(&serializer);
}
SessionMetrics::SessionMetrics() :

View File

@@ -110,6 +110,14 @@ void Serialize<OEMCryptoInitializationMode>(
serializer->SetInt32(metric_name, value);
}
template<>
void Serialize<CdmUsageSupportType>(
MetricSerializer* serializer,
const std::string& metric_name,
const CdmUsageSupportType& value) {
serializer->SetInt32(metric_name, value);
}
} // namespace impl
} // namespace metrics
} // namespace wvcdm

View File

@@ -259,10 +259,11 @@ enum {
kReleaseAllUsageInfoError7 = ERROR_DRM_VENDOR_MIN + 268,
kLicenseRequestInvalidSublicense = ERROR_DRM_VENDOR_MIN + 269,
kCertProvisioningEmptyServiceCertificate = ERROR_DRM_VENDOR_MIN + 270,
kLoadSystemIdError = ERROR_DRM_VENDOR_MIN + 271,
// This should always follow the last error code.
// The offset value should be updated each time a new error code is added.
kErrorWVDrmMaxErrorUsed = ERROR_DRM_VENDOR_MIN + 270,
kErrorWVDrmMaxErrorUsed = ERROR_DRM_VENDOR_MIN + 271,
// Used by crypto test mode
kErrorTestMode = ERROR_DRM_VENDOR_MAX,

View File

@@ -499,6 +499,8 @@ static android::status_t mapCdmResponseType(wvcdm::CdmResponseType res) {
return kLicenseRequestInvalidSublicense;
case wvcdm::CERT_PROVISIONING_EMPTY_SERVICE_CERTIFICATE:
return kCertProvisioningEmptyServiceCertificate;
case wvcdm::LOAD_SYSTEM_ID_ERROR:
return kLoadSystemIdError;
}
// Return here instead of as a default case so that the compiler will warn

View File

@@ -286,6 +286,7 @@ static Status mapCdmResponseType(wvcdm::CdmResponseType res) {
case wvcdm::PARSE_RESPONSE_ERROR_2:
case wvcdm::PARSE_RESPONSE_ERROR_3:
case wvcdm::PARSE_RESPONSE_ERROR_4:
case wvcdm::LOAD_SYSTEM_ID_ERROR:
ALOGW("Returns UNKNOWN error for legacy status: %d", res);
return Status::ERROR_DRM_UNKNOWN;