Snap for 7890423 from b6c93683db to tm-release
Change-Id: I17fc4d046ec719d04dc6a7ffa0beac3965a40d03
This commit is contained in:
@@ -319,6 +319,10 @@ typedef OEMCryptoResult (*L1_LoadProvisioning_t)(
|
||||
size_t signature_length, uint8_t* wrapped_private_key,
|
||||
size_t* wrapped_private_key_length);
|
||||
typedef uint32_t (*L1_MinorAPIVersion_t)();
|
||||
typedef OEMCryptoResult (*L1_OPK_SerializationVersion_t)(uint32_t* ree_major,
|
||||
uint32_t* ree_minor,
|
||||
uint32_t* tee_major,
|
||||
uint32_t* tee_minor);
|
||||
typedef OEMCryptoResult (*L1_GenerateOTARequest_t)(OEMCrypto_SESSION session,
|
||||
uint8_t* buffer,
|
||||
size_t* buffer_length,
|
||||
@@ -411,6 +415,7 @@ struct FunctionPointers {
|
||||
L1_MaximumUsageTableHeaderSize_t MaximumUsageTableHeaderSize;
|
||||
L1_LoadProvisioning_t LoadProvisioning;
|
||||
L1_MinorAPIVersion_t MinorAPIVersion;
|
||||
L1_OPK_SerializationVersion_t OPK_SerializationVersion;
|
||||
|
||||
L1_LoadKeys_V8_t LoadKeys_V8;
|
||||
L1_GenerateRSASignature_V8_t GenerateRSASignature_V8;
|
||||
@@ -961,6 +966,7 @@ class Adapter {
|
||||
LOOKUP_ALL(16, MaximumUsageTableHeaderSize, OEMCrypto_MaximumUsageTableHeaderSize);
|
||||
LOOKUP_ALL(16, LoadProvisioning, OEMCrypto_LoadProvisioning);
|
||||
LOOKUP_ALL(16, MinorAPIVersion, OEMCrypto_MinorAPIVersion);
|
||||
LOOKUP_ALL(16, OPK_SerializationVersion, OEMCrypto_OPK_SerializationVersion);
|
||||
LOOKUP_ALL(16, GenerateOTARequest, OEMCrypto_GenerateOTARequest);
|
||||
LOOKUP_ALL(16, ProcessOTAKeybox, OEMCrypto_ProcessOTAKeybox);
|
||||
// clang-format on
|
||||
@@ -2873,6 +2879,18 @@ extern "C" OEMCryptoResult OEMCrypto_FreeSecureBuffer(
|
||||
return pair.fcn->FreeSecureBuffer(pair.session, output_descriptor, secure_fd);
|
||||
}
|
||||
|
||||
extern "C" OEMCryptoResult OEMCrypto_OPK_SerializationVersion(
|
||||
uint32_t* ree_major, uint32_t* ree_minor, uint32_t* tee_major,
|
||||
uint32_t* tee_minor) {
|
||||
if (!gAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||
const FunctionPointers* fcn = gAdapter->GetFunctionPointers(kLevelDefault);
|
||||
if (!fcn || fcn->OPK_SerializationVersion == nullptr) {
|
||||
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
return fcn->OPK_SerializationVersion(ree_major, ree_minor, tee_major,
|
||||
tee_minor);
|
||||
}
|
||||
|
||||
extern "C" OEMCryptoResult OEMCrypto_GenerateOTARequest(
|
||||
OEMCrypto_SESSION session, uint8_t* buffer, size_t* buffer_length,
|
||||
uint32_t use_test_key) {
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <chrono>
|
||||
#include <mutex>
|
||||
|
||||
#ifdef _WIN32
|
||||
@@ -108,40 +109,6 @@ void ShowServerCertificate(const SSL* ssl) {
|
||||
}
|
||||
#endif
|
||||
|
||||
// Wait for a socket to be ready for reading or writing.
|
||||
// Establishing a connection counts as "ready for write".
|
||||
// Returns false on select error or timeout.
|
||||
// Returns true when the socket is ready.
|
||||
bool SocketWait(int fd, bool for_read, int timeout_in_ms) {
|
||||
fd_set fds;
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(fd, &fds);
|
||||
|
||||
struct timeval tv;
|
||||
tv.tv_sec = timeout_in_ms / 1000;
|
||||
tv.tv_usec = (timeout_in_ms % 1000) * 1000;
|
||||
|
||||
fd_set* read_fds = nullptr;
|
||||
fd_set* write_fds = nullptr;
|
||||
if (for_read) {
|
||||
read_fds = &fds;
|
||||
} else {
|
||||
write_fds = &fds;
|
||||
}
|
||||
|
||||
int ret = select(fd + 1, read_fds, write_fds, nullptr, &tv);
|
||||
if (ret == 0) {
|
||||
LOGE("socket timed out");
|
||||
return false;
|
||||
} else if (ret == -1) {
|
||||
LOGE("select failed, errno = %d", errno);
|
||||
return false;
|
||||
}
|
||||
|
||||
// socket ready.
|
||||
return true;
|
||||
}
|
||||
|
||||
int GetError() {
|
||||
#ifdef _WIN32
|
||||
return WSAGetLastError();
|
||||
@@ -228,6 +195,8 @@ HttpSocket::HttpSocket(const std::string& url)
|
||||
: socket_fd_(-1), ssl_(nullptr), ssl_ctx_(nullptr) {
|
||||
valid_url_ = ParseUrl(url, &scheme_, &secure_connect_, &domain_name_, &port_,
|
||||
&resource_path_);
|
||||
create_time_ =
|
||||
std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
|
||||
InitSslLibrary();
|
||||
}
|
||||
|
||||
@@ -252,6 +221,16 @@ void HttpSocket::CloseSocket() {
|
||||
}
|
||||
}
|
||||
|
||||
bool HttpSocket::ConnectAndLogErrors(int timeout_in_ms) {
|
||||
std::time_t start =
|
||||
std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
|
||||
bool result = Connect(timeout_in_ms);
|
||||
std::time_t finish =
|
||||
std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
|
||||
if (!result) LogTime("socket connect error", start, finish);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool HttpSocket::Connect(int timeout_in_ms) {
|
||||
if (!valid_url_) {
|
||||
LOGE("URL is invalid");
|
||||
@@ -355,7 +334,7 @@ bool HttpSocket::Connect(int timeout_in_ms) {
|
||||
return false;
|
||||
} else {
|
||||
// in progress. block until timeout expired or connection established.
|
||||
if (!SocketWait(socket_fd_, /* for_read */ false, timeout_in_ms)) {
|
||||
if (!Wait(/* for_read */ false, timeout_in_ms)) {
|
||||
LOGE("cannot connect to %s", domain_name_.c_str());
|
||||
CloseSocket();
|
||||
return false;
|
||||
@@ -399,7 +378,7 @@ bool HttpSocket::Connect(int timeout_in_ms) {
|
||||
return false;
|
||||
}
|
||||
const bool for_read = (ssl_err == SSL_ERROR_WANT_READ);
|
||||
if (!SocketWait(socket_fd_, for_read, timeout_in_ms)) {
|
||||
if (!Wait(for_read, timeout_in_ms)) {
|
||||
LOGE("Cannot connect securely to %s", domain_name_.c_str());
|
||||
CloseSocket();
|
||||
return false;
|
||||
@@ -414,6 +393,16 @@ bool HttpSocket::Connect(int timeout_in_ms) {
|
||||
// Returns -1 for error, number of bytes read for success.
|
||||
// The timeout here only applies to the span between packets of data, for the
|
||||
// sake of simplicity.
|
||||
int HttpSocket::ReadAndLogErrors(char* data, int len, int timeout_in_ms) {
|
||||
std::time_t start =
|
||||
std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
|
||||
int result = Read(data, len, timeout_in_ms);
|
||||
std::time_t finish =
|
||||
std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
|
||||
if (result < 0) LogTime("read error", start, finish);
|
||||
return result;
|
||||
}
|
||||
|
||||
int HttpSocket::Read(char* data, int len, int timeout_in_ms) {
|
||||
int total_read = 0;
|
||||
int to_read = len;
|
||||
@@ -423,8 +412,9 @@ int HttpSocket::Read(char* data, int len, int timeout_in_ms) {
|
||||
return -1;
|
||||
}
|
||||
while (to_read > 0) {
|
||||
if (!SocketWait(socket_fd_, /* for_read */ true, timeout_in_ms)) {
|
||||
LOGE("unable to read from %s", domain_name_.c_str());
|
||||
if (!Wait(/* for_read */ true, timeout_in_ms)) {
|
||||
LOGE("unable to read from %s. len=%d, to_read=%d", domain_name_.c_str(),
|
||||
len, to_read);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -480,6 +470,17 @@ int HttpSocket::Read(char* data, int len, int timeout_in_ms) {
|
||||
// Returns -1 for error, number of bytes written for success.
|
||||
// The timeout here only applies to the span between packets of data, for the
|
||||
// sake of simplicity.
|
||||
int HttpSocket::WriteAndLogErrors(const char* data, int len,
|
||||
int timeout_in_ms) {
|
||||
std::time_t start =
|
||||
std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
|
||||
int result = Write(data, len, timeout_in_ms);
|
||||
std::time_t finish =
|
||||
std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
|
||||
if (result < 0) LogTime("write error", start, finish);
|
||||
return result;
|
||||
}
|
||||
|
||||
int HttpSocket::Write(const char* data, int len, int timeout_in_ms) {
|
||||
int total_sent = 0;
|
||||
int to_send = len;
|
||||
@@ -502,7 +503,7 @@ int HttpSocket::Write(const char* data, int len, int timeout_in_ms) {
|
||||
total_sent += sent;
|
||||
} else if (sent == 0) {
|
||||
// We filled up the pipe. Wait for room to write.
|
||||
if (!SocketWait(socket_fd_, /* for_read */ false, timeout_in_ms)) {
|
||||
if (!Wait(/* for_read */ false, timeout_in_ms)) {
|
||||
LOGE("unable to write to %s", domain_name_.c_str());
|
||||
return -1;
|
||||
}
|
||||
@@ -515,4 +516,50 @@ int HttpSocket::Write(const char* data, int len, int timeout_in_ms) {
|
||||
return total_sent;
|
||||
}
|
||||
|
||||
bool HttpSocket::Wait(bool for_read, int timeout_in_ms) {
|
||||
fd_set fds;
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(socket_fd_, &fds);
|
||||
|
||||
struct timeval tv;
|
||||
tv.tv_sec = timeout_in_ms / 1000;
|
||||
tv.tv_usec = (timeout_in_ms % 1000) * 1000;
|
||||
|
||||
fd_set* read_fds = nullptr;
|
||||
fd_set* write_fds = nullptr;
|
||||
if (for_read) {
|
||||
read_fds = &fds;
|
||||
} else {
|
||||
write_fds = &fds;
|
||||
}
|
||||
|
||||
const std::time_t start =
|
||||
std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
|
||||
int ret = select(socket_fd_ + 1, read_fds, write_fds, nullptr, &tv);
|
||||
const std::time_t finish =
|
||||
std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
|
||||
if (ret == 0) {
|
||||
LogTime("socket select timeout", start, finish);
|
||||
// TODO(b/186031735): Remove this when the bug is fixed.
|
||||
LOGE("Timeout = %0.3f. Consider adding a comment to http://b/186031735",
|
||||
0.001 * timeout_in_ms);
|
||||
return false;
|
||||
} else if (ret == -1) {
|
||||
LOGE("select failed, errno = %d", errno);
|
||||
return false;
|
||||
}
|
||||
|
||||
// socket ready.
|
||||
return true;
|
||||
}
|
||||
|
||||
void HttpSocket::LogTime(const char* note, const std::time_t& start,
|
||||
const std::time_t& finish) {
|
||||
std::string start_string = std::string(std::ctime(&start));
|
||||
start_string.pop_back(); // Remove new line character.
|
||||
LOGE("%s: start = %s = create + %0.3f, end = start + %0.3f", note,
|
||||
start_string.c_str(), difftime(start, create_time_),
|
||||
difftime(finish, start));
|
||||
}
|
||||
|
||||
} // namespace wvcdm
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <ctime>
|
||||
#include <string>
|
||||
|
||||
#include <gtest/gtest_prod.h>
|
||||
@@ -23,7 +24,7 @@ class HttpSocket {
|
||||
explicit HttpSocket(const std::string& url);
|
||||
~HttpSocket();
|
||||
|
||||
bool Connect(int timeout_in_ms);
|
||||
bool ConnectAndLogErrors(int timeout_in_ms);
|
||||
void CloseSocket();
|
||||
|
||||
const std::string& scheme() const { return scheme_; }
|
||||
@@ -32,13 +33,25 @@ class HttpSocket {
|
||||
int port() const { return atoi(port_.c_str()); }
|
||||
const std::string& resource_path() const { return resource_path_; }
|
||||
|
||||
int Read(char* data, int len, int timeout_in_ms);
|
||||
int Write(const char* data, int len, int timeout_in_ms);
|
||||
int ReadAndLogErrors(char* data, int len, int timeout_in_ms);
|
||||
int WriteAndLogErrors(const char* data, int len, int timeout_in_ms);
|
||||
|
||||
private:
|
||||
static bool ParseUrl(const std::string& url, std::string* scheme,
|
||||
bool* secure_connect, std::string* domain_name,
|
||||
std::string* port, std::string* path);
|
||||
// The following three functions do the work without logging errors.
|
||||
bool Connect(int timeout_in_ms);
|
||||
int Read(char* data, int len, int timeout_in_ms);
|
||||
int Write(const char* data, int len, int timeout_in_ms);
|
||||
// Log times with a note as an error.
|
||||
void LogTime(const char* note, const std::time_t& start,
|
||||
const std::time_t& finish);
|
||||
// Wait for a socket to be ready for reading or writing.
|
||||
// Establishing a connection counts as "ready for write".
|
||||
// Returns false on select error or timeout.
|
||||
// Returns true when the socket is ready.
|
||||
bool Wait(bool for_read, int timeout_in_ms);
|
||||
FRIEND_TEST(HttpSocketTest, ParseUrlTest);
|
||||
|
||||
std::string scheme_;
|
||||
@@ -52,6 +65,10 @@ class HttpSocket {
|
||||
SSL* ssl_;
|
||||
SSL_CTX* ssl_ctx_;
|
||||
|
||||
// When the socket was created. Logged on error to help debug flaky
|
||||
// tests. e.g. b/186031735
|
||||
std::time_t create_time_;
|
||||
|
||||
CORE_DISALLOW_COPY_AND_ASSIGN(HttpSocket);
|
||||
};
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ class HttpSocketTest : public testing::Test {
|
||||
bool Connect(const std::string& server_url) {
|
||||
socket_.reset(new HttpSocket(server_url));
|
||||
|
||||
if (socket_->Connect(kTimeout)) {
|
||||
if (socket_->ConnectAndLogErrors(kTimeout)) {
|
||||
LOGD("connected to %s", socket_->domain_name().c_str());
|
||||
return true;
|
||||
} else {
|
||||
@@ -73,7 +73,7 @@ class HttpSocketTest : public testing::Test {
|
||||
|
||||
// append data
|
||||
request.append(data);
|
||||
socket_->Write(request.c_str(), request.size(), kTimeout);
|
||||
socket_->WriteAndLogErrors(request.c_str(), request.size(), kTimeout);
|
||||
|
||||
LOGD("request: %s", request.c_str());
|
||||
return true;
|
||||
@@ -81,7 +81,7 @@ class HttpSocketTest : public testing::Test {
|
||||
|
||||
bool GetResponse(std::string* response) {
|
||||
char buffer[kHttpBufferSize];
|
||||
int bytes = socket_->Read(buffer, sizeof(buffer), kTimeout);
|
||||
int bytes = socket_->ReadAndLogErrors(buffer, sizeof(buffer), kTimeout);
|
||||
if (bytes < 0) {
|
||||
LOGE("read error, errno = %d", errno);
|
||||
return false;
|
||||
|
||||
@@ -87,7 +87,7 @@ UrlRequest::~UrlRequest() {}
|
||||
void UrlRequest::Reconnect() {
|
||||
for (uint32_t i = 0; i < kMaxConnectAttempts && !is_connected_; ++i) {
|
||||
socket_.CloseSocket();
|
||||
if (socket_.Connect(kConnectTimeoutMs)) {
|
||||
if (socket_.ConnectAndLogErrors(kConnectTimeoutMs)) {
|
||||
is_connected_ = true;
|
||||
} else {
|
||||
LOGE("Failed to connect: url = %s, port = %d, attempt = %u",
|
||||
@@ -104,8 +104,8 @@ bool UrlRequest::GetResponse(std::string* message) {
|
||||
// non-blocking mode.
|
||||
while (true) {
|
||||
char read_buffer[kReadBufferSize];
|
||||
const int bytes =
|
||||
socket_.Read(read_buffer, sizeof(read_buffer), kReadTimeoutMs);
|
||||
const int bytes = socket_.ReadAndLogErrors(read_buffer, sizeof(read_buffer),
|
||||
kReadTimeoutMs);
|
||||
if (bytes > 0) {
|
||||
response.append(read_buffer, bytes);
|
||||
} else if (bytes < 0) {
|
||||
@@ -203,8 +203,8 @@ bool UrlRequest::PostRequestWithPath(const std::string& path,
|
||||
|
||||
request.append(data);
|
||||
|
||||
const int ret =
|
||||
socket_.Write(request.c_str(), request.size(), kWriteTimeoutMs);
|
||||
const int ret = socket_.WriteAndLogErrors(request.c_str(), request.size(),
|
||||
kWriteTimeoutMs);
|
||||
LOGV("HTTP request: (%zu): %s", request.size(), b2a_hex(request).c_str());
|
||||
return ret != -1;
|
||||
}
|
||||
|
||||
@@ -1,21 +1,18 @@
|
||||
// Copyright 2018 Google Inc. All Rights Reserved.
|
||||
// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine License
|
||||
// Agreement.
|
||||
//
|
||||
// This file contains the declarations for the EventMetric class and related
|
||||
// types.
|
||||
#ifndef WVCDM_METRICS_ATTRIBUTE_HANDLER_H_
|
||||
#define WVCDM_METRICS_ATTRIBUTE_HANDLER_H_
|
||||
#include <string>
|
||||
|
||||
#include "OEMCryptoCENC.h"
|
||||
#include "field_tuples.h"
|
||||
#include "log.h"
|
||||
#include "pow2bucket.h"
|
||||
#include "value_metric.h"
|
||||
#include "wv_cdm_types.h"
|
||||
#include "wv_metrics.pb.h"
|
||||
|
||||
namespace wvcdm {
|
||||
namespace metrics {
|
||||
|
||||
// This method is used to set the value of a single proto field.
|
||||
// Specializations handle setting each value.
|
||||
template <int I, typename F>
|
||||
@@ -47,7 +44,6 @@ class AttributeHandler {
|
||||
return serialized_attributes;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace metrics
|
||||
} // namespace wvcdm
|
||||
#endif // WVCDM_METRICS_ATTRIBUTE_HANDLER_H_
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
// Copyright 2017 Google Inc. All Rights Reserved.
|
||||
// Copyright 2017 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine License
|
||||
// Agreement.
|
||||
//
|
||||
// This file contains the declarations for the Metric class and related
|
||||
// types.
|
||||
#ifndef WVCDM_METRICS_COUNTER_METRIC_H_
|
||||
#define WVCDM_METRICS_COUNTER_METRIC_H_
|
||||
|
||||
#include <cstdarg>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "attribute_handler.h"
|
||||
#include "field_tuples.h"
|
||||
#include "wv_metrics.pb.h"
|
||||
|
||||
namespace wvcdm {
|
||||
namespace metrics {
|
||||
|
||||
class CounterMetricTest;
|
||||
|
||||
// This base class provides the common defintion used by all templated
|
||||
@@ -37,7 +37,7 @@ class BaseCounterMetric {
|
||||
// Increment will look for an existing instance of the field names and
|
||||
// add the new value to the existing value. If the instance does not exist,
|
||||
// this method will create it.
|
||||
void Increment(const std::string &counter_key, int64_t value);
|
||||
void Increment(const std::string& counter_key, int64_t value);
|
||||
|
||||
private:
|
||||
friend class CounterMetricTest;
|
||||
@@ -99,14 +99,13 @@ class CounterMetric : public BaseCounterMetric {
|
||||
void Increment(int64_t value, F1 field1 = util::Unused(),
|
||||
F2 field2 = util::Unused(), F3 field3 = util::Unused(),
|
||||
F4 field4 = util::Unused()) {
|
||||
std::string key =
|
||||
attribute_handler_.GetSerializedAttributes(field1, field2,
|
||||
field3, field4);
|
||||
std::string key = attribute_handler_.GetSerializedAttributes(
|
||||
field1, field2, field3, field4);
|
||||
BaseCounterMetric::Increment(key, value);
|
||||
}
|
||||
|
||||
void ToProto(::google::protobuf::RepeatedPtrField<drm_metrics::CounterMetric>
|
||||
*counters) const;
|
||||
void ToProto(::google::protobuf::RepeatedPtrField<drm_metrics::CounterMetric>*
|
||||
counters) const;
|
||||
|
||||
private:
|
||||
friend class CounterMetricTest;
|
||||
@@ -120,13 +119,12 @@ class CounterMetric : public BaseCounterMetric {
|
||||
template <>
|
||||
inline void CounterMetric<0, util::Unused, 0, util::Unused, 0, util::Unused, 0,
|
||||
util::Unused>::
|
||||
ToProto(::google::protobuf::RepeatedPtrField<drm_metrics::CounterMetric>
|
||||
*counters) const {
|
||||
|
||||
ToProto(::google::protobuf::RepeatedPtrField<drm_metrics::CounterMetric>*
|
||||
counters) const {
|
||||
const std::map<std::string, int64_t>* values = GetValues();
|
||||
for (std::map<std::string, int64_t>::const_iterator it = values->begin();
|
||||
it != values->end(); it++) {
|
||||
drm_metrics::CounterMetric *new_counter = counters->Add();
|
||||
drm_metrics::CounterMetric* new_counter = counters->Add();
|
||||
new_counter->set_count(it->second);
|
||||
}
|
||||
}
|
||||
@@ -134,20 +132,18 @@ inline void CounterMetric<0, util::Unused, 0, util::Unused, 0, util::Unused, 0,
|
||||
template <int I1, typename F1, int I2, typename F2, int I3, typename F3, int I4,
|
||||
typename F4>
|
||||
inline void CounterMetric<I1, F1, I2, F2, I3, F3, I4, F4>::ToProto(
|
||||
::google::protobuf::RepeatedPtrField<drm_metrics::CounterMetric>
|
||||
*counters) const {
|
||||
::google::protobuf::RepeatedPtrField<drm_metrics::CounterMetric>* counters)
|
||||
const {
|
||||
const std::map<std::string, int64_t>* values = GetValues();
|
||||
for (std::map<std::string, int64_t>::const_iterator it = values->begin();
|
||||
it != values->end(); it++) {
|
||||
drm_metrics::CounterMetric *new_counter = counters->Add();
|
||||
drm_metrics::CounterMetric* new_counter = counters->Add();
|
||||
if (!new_counter->mutable_attributes()->ParseFromString(it->first)) {
|
||||
LOGE("Failed to parse the attributes from a string.");
|
||||
}
|
||||
new_counter->set_count(it->second);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace metrics
|
||||
} // namespace wvcdm
|
||||
|
||||
#endif // WVCDM_METRICS_COUNTER_METRIC_H_
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
// Copyright 2017 Google Inc. All Rights Reserved.
|
||||
// Copyright 2017 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine License
|
||||
// Agreement.
|
||||
//
|
||||
// This file contains the definition of a Distribution class which computes
|
||||
// the distribution values of a series of samples.
|
||||
@@ -10,7 +12,6 @@
|
||||
|
||||
namespace wvcdm {
|
||||
namespace metrics {
|
||||
|
||||
// The Distribution class holds statistics about a series of values that the
|
||||
// client provides via the Record method. A caller will call Record once for
|
||||
// each of the values in a series. The Distribution instance will calculate the
|
||||
@@ -46,8 +47,6 @@ class Distribution {
|
||||
float mean_;
|
||||
double sum_squared_deviation_;
|
||||
};
|
||||
|
||||
} // namespace metrics
|
||||
} // namespace wvcdm
|
||||
|
||||
#endif // WVCDM_METRICS_DISTRIBUTION_H_
|
||||
|
||||
@@ -1,26 +1,24 @@
|
||||
// Copyright 2017 Google Inc. All Rights Reserved.
|
||||
// Copyright 2017 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine License
|
||||
// Agreement.
|
||||
//
|
||||
// This file contains the declarations for the EventMetric class and related
|
||||
// types.
|
||||
#ifndef WVCDM_METRICS_EVENT_METRIC_H_
|
||||
#define WVCDM_METRICS_EVENT_METRIC_H_
|
||||
|
||||
#include <cstdarg>
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "OEMCryptoCENC.h"
|
||||
#include "attribute_handler.h"
|
||||
#include "distribution.h"
|
||||
#include "field_tuples.h"
|
||||
#include "log.h"
|
||||
#include "pow2bucket.h"
|
||||
#include "wv_metrics.pb.h"
|
||||
|
||||
namespace wvcdm {
|
||||
namespace metrics {
|
||||
|
||||
class EventMetricTest;
|
||||
|
||||
// This base class provides the common defintion used by all templated
|
||||
@@ -36,12 +34,12 @@ class BaseEventMetric {
|
||||
// Record will look for an existing instance of the Distribution identified
|
||||
// by the distribution_key string and update it. If the instance does
|
||||
// not exist, this will create it.
|
||||
void Record(const std::string &distribution_key, double value);
|
||||
void Record(const std::string& distribution_key, double value);
|
||||
|
||||
// value_map_ contains a mapping from the string key (attribute name/values)
|
||||
// to the distribution instance which holds the metric information
|
||||
// (min, max, sum, etc.).
|
||||
std::map<std::string, Distribution *> value_map_;
|
||||
std::map<std::string, Distribution*> value_map_;
|
||||
|
||||
private:
|
||||
friend class EventMetricTest;
|
||||
@@ -90,34 +88,33 @@ template <int I1 = 0, typename F1 = util::Unused, int I2 = 0,
|
||||
class EventMetric : public BaseEventMetric {
|
||||
public:
|
||||
// Create an EventMetric instance with no attribute breakdowns.
|
||||
explicit EventMetric() : BaseEventMetric(){}
|
||||
explicit EventMetric() : BaseEventMetric() {}
|
||||
|
||||
// Record will update the statistics of the EventMetric broken down by the
|
||||
// given field values.
|
||||
void Record(double value, F1 field1 = util::Unused(),
|
||||
F2 field2 = util::Unused(), F3 field3 = util::Unused(),
|
||||
F4 field4 = util::Unused()) {
|
||||
std::string key =
|
||||
attribute_handler_.GetSerializedAttributes(field1, field2,
|
||||
field3, field4);
|
||||
std::string key = attribute_handler_.GetSerializedAttributes(
|
||||
field1, field2, field3, field4);
|
||||
BaseEventMetric::Record(key, value);
|
||||
}
|
||||
|
||||
const std::map<std::string, Distribution *>* GetDistributions() const {
|
||||
const std::map<std::string, Distribution*>* GetDistributions() const {
|
||||
return &value_map_;
|
||||
};
|
||||
|
||||
void ToProto(
|
||||
::google::protobuf::RepeatedPtrField<drm_metrics::DistributionMetric>
|
||||
*distributions_proto) const;
|
||||
::google::protobuf::RepeatedPtrField<drm_metrics::DistributionMetric>*
|
||||
distributions_proto) const;
|
||||
|
||||
private:
|
||||
friend class EventMetricTest;
|
||||
AttributeHandler<I1, F1, I2, F2, I3, F3, I4, F4> attribute_handler_;
|
||||
|
||||
inline void SetDistributionValues(
|
||||
const Distribution &distribution,
|
||||
drm_metrics::DistributionMetric *metric_proto) const {
|
||||
const Distribution& distribution,
|
||||
drm_metrics::DistributionMetric* metric_proto) const {
|
||||
metric_proto->set_mean(distribution.Mean());
|
||||
metric_proto->set_operation_count(distribution.Count());
|
||||
if (distribution.Count() > 1) {
|
||||
@@ -138,13 +135,14 @@ template <>
|
||||
inline void EventMetric<0, util::Unused, 0, util::Unused, 0, util::Unused, 0,
|
||||
util::Unused>::
|
||||
ToProto(
|
||||
::google::protobuf::RepeatedPtrField<drm_metrics::DistributionMetric>
|
||||
*distributions_proto) const {
|
||||
const std::map<std::string, Distribution *>* distributions
|
||||
= GetDistributions();
|
||||
for (std::map<std::string, Distribution *>::const_iterator it =
|
||||
distributions->begin(); it != distributions->end(); it++) {
|
||||
drm_metrics::DistributionMetric *new_metric = distributions_proto->Add();
|
||||
::google::protobuf::RepeatedPtrField<drm_metrics::DistributionMetric>*
|
||||
distributions_proto) const {
|
||||
const std::map<std::string, Distribution*>* distributions =
|
||||
GetDistributions();
|
||||
for (std::map<std::string, Distribution*>::const_iterator it =
|
||||
distributions->begin();
|
||||
it != distributions->end(); it++) {
|
||||
drm_metrics::DistributionMetric* new_metric = distributions_proto->Add();
|
||||
SetDistributionValues(*it->second, new_metric);
|
||||
}
|
||||
}
|
||||
@@ -152,21 +150,20 @@ inline void EventMetric<0, util::Unused, 0, util::Unused, 0, util::Unused, 0,
|
||||
template <int I1, typename F1, int I2, typename F2, int I3, typename F3, int I4,
|
||||
typename F4>
|
||||
inline void EventMetric<I1, F1, I2, F2, I3, F3, I4, F4>::ToProto(
|
||||
::google::protobuf::RepeatedPtrField<drm_metrics::DistributionMetric>
|
||||
*distributions_proto) const {
|
||||
const std::map<std::string, Distribution *>* distributions
|
||||
= GetDistributions();
|
||||
for (std::map<std::string, Distribution *>::const_iterator it =
|
||||
distributions->begin(); it != distributions->end(); it++) {
|
||||
drm_metrics::DistributionMetric *new_metric = distributions_proto->Add();
|
||||
::google::protobuf::RepeatedPtrField<drm_metrics::DistributionMetric>*
|
||||
distributions_proto) const {
|
||||
const std::map<std::string, Distribution*>* distributions =
|
||||
GetDistributions();
|
||||
for (std::map<std::string, Distribution*>::const_iterator it =
|
||||
distributions->begin();
|
||||
it != distributions->end(); it++) {
|
||||
drm_metrics::DistributionMetric* new_metric = distributions_proto->Add();
|
||||
if (!new_metric->mutable_attributes()->ParseFromString(it->first)) {
|
||||
LOGE("Failed to parse the attributes from a string.");
|
||||
}
|
||||
SetDistributionValues(*it->second, new_metric);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace metrics
|
||||
} // namespace wvcdm
|
||||
|
||||
#endif // WVCDM_METRICS_EVENT_METRIC_H_
|
||||
|
||||
@@ -1,17 +1,16 @@
|
||||
// Copyright 2017 Google Inc. All Rights Reserved.
|
||||
// Copyright 2017 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine License
|
||||
// Agreement.
|
||||
//
|
||||
// This file contains the helper classes and methods for using field tuples
|
||||
// used by metrics classes to record variations of a single metric.
|
||||
#ifndef WVCDM_METRICS_FIELD_TUPLES_H_
|
||||
#define WVCDM_METRICS_FIELD_TUPLES_H_
|
||||
|
||||
#include <ostream>
|
||||
#include <sstream>
|
||||
|
||||
namespace wvcdm {
|
||||
namespace metrics {
|
||||
namespace util {
|
||||
|
||||
// TODO(blueeyes): Change to use C++ 11 support for variadic template args.
|
||||
// The C++ 03 pattern is no longer needed since we require C++11. b/68766426.
|
||||
|
||||
@@ -23,9 +22,7 @@ struct Unused {
|
||||
return out;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace util
|
||||
} // namespace metrics
|
||||
} // namespace wvcdm
|
||||
|
||||
#endif // WVCDM_METRICS_FIELD_TUPLES_H_
|
||||
|
||||
@@ -1,15 +1,18 @@
|
||||
// Copyright 2016 Google Inc. All Rights Reserved.
|
||||
// Copyright 2016 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine License
|
||||
// Agreement.
|
||||
//
|
||||
// This file contains definitions for metrics being collected throughout the
|
||||
// CDM.
|
||||
|
||||
#ifndef WVCDM_METRICS_METRICS_GROUP_H_
|
||||
#define WVCDM_METRICS_METRICS_GROUP_H_
|
||||
|
||||
#ifndef WVCDM_METRICS_METRICS_COLLECTIONS_H_
|
||||
#define WVCDM_METRICS_METRICS_COLLECTIONS_H_
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <mutex>
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "OEMCryptoCENC.h"
|
||||
#include "counter_metric.h"
|
||||
@@ -58,9 +61,7 @@
|
||||
|
||||
namespace wvcdm {
|
||||
namespace metrics {
|
||||
|
||||
namespace {
|
||||
|
||||
// Short name definitions to ease AttributeHandler definitions.
|
||||
// Internal namespace to help simplify declarations.
|
||||
const int kErrorCodeFieldNumber =
|
||||
@@ -73,8 +74,7 @@ const int kCdmSecurityLevelFieldNumber =
|
||||
::drm_metrics::Attributes::kCdmSecurityLevelFieldNumber;
|
||||
const int kSecurityLevelFieldNumber =
|
||||
::drm_metrics::Attributes::kSecurityLevelFieldNumber;
|
||||
const int kLengthFieldNumber =
|
||||
::drm_metrics::Attributes::kLengthFieldNumber;
|
||||
const int kLengthFieldNumber = ::drm_metrics::Attributes::kLengthFieldNumber;
|
||||
const int kEncryptAlgorithmFieldNumber =
|
||||
::drm_metrics::Attributes::kEncryptionAlgorithmFieldNumber;
|
||||
const int kSigningAlgorithmFieldNumber =
|
||||
@@ -89,8 +89,7 @@ const int kKeyRequestTypeFieldNumber =
|
||||
::drm_metrics::Attributes::kKeyRequestTypeFieldNumber;
|
||||
const int kLicenseTypeFieldNumber =
|
||||
::drm_metrics::Attributes::kLicenseTypeFieldNumber;
|
||||
|
||||
} // anonymous namespace
|
||||
} // namespace
|
||||
|
||||
// The maximum number of completed sessions that can be stored. More than this
|
||||
// will cause some metrics to be discarded.
|
||||
@@ -125,8 +124,8 @@ typedef enum OEMCryptoInitializationMode {
|
||||
// This class contains metrics for Crypto Session and OEM Crypto.
|
||||
class CryptoMetrics {
|
||||
public:
|
||||
void Serialize(drm_metrics::WvCdmMetrics::CryptoMetrics *crypto_metrics)
|
||||
const;
|
||||
void Serialize(
|
||||
drm_metrics::WvCdmMetrics::CryptoMetrics* crypto_metrics) const;
|
||||
|
||||
/* CRYPTO SESSION */
|
||||
// TODO(blueeyes): Convert this to crypto_session_default_security_level_.
|
||||
@@ -293,7 +292,7 @@ class CryptoMetrics {
|
||||
oemcrypto_load_provisioning_;
|
||||
ValueMetric<uint32_t> oemcrypto_minor_api_version_;
|
||||
ValueMetric<uint32_t> oemcrypto_maximum_usage_table_header_size_;
|
||||
};
|
||||
}; // class CryptoMetrics
|
||||
|
||||
// This class contains session-scoped metrics. All properties and
|
||||
// statistics related to operations within a single session are
|
||||
@@ -304,12 +303,12 @@ class SessionMetrics {
|
||||
|
||||
// Sets the session id of the metrics group. This allows the session
|
||||
// id to be captured and reported as part of the collection of metrics.
|
||||
void SetSessionId(const CdmSessionId &session_id) {
|
||||
void SetSessionId(const CdmSessionId& session_id) {
|
||||
session_id_ = session_id;
|
||||
}
|
||||
|
||||
// Returns the session id or an empty session id if it has not been set.
|
||||
const CdmSessionId &GetSessionId() const { return session_id_; }
|
||||
const CdmSessionId& GetSessionId() const { return session_id_; }
|
||||
|
||||
// Marks the metrics object as completed and ready for serialization.
|
||||
void SetCompleted() { completed_ = true; }
|
||||
@@ -320,16 +319,16 @@ class SessionMetrics {
|
||||
|
||||
// Returns a pointer to the crypto metrics belonging to the engine instance.
|
||||
// This instance retains ownership of the object.
|
||||
CryptoMetrics *GetCryptoMetrics() { return &crypto_metrics_; }
|
||||
CryptoMetrics* GetCryptoMetrics() { return &crypto_metrics_; }
|
||||
|
||||
// Metrics collected at the session level.
|
||||
ValueMetric<double> cdm_session_life_span_; // Milliseconds.
|
||||
EventMetric<kErrorCodeFieldNumber, CdmResponseType> cdm_session_renew_key_;
|
||||
CounterMetric<kErrorCodeFieldNumber, CdmResponseType,
|
||||
kErrorDetailFieldNumber, int32_t>
|
||||
CounterMetric<kErrorCodeFieldNumber, CdmResponseType, kErrorDetailFieldNumber,
|
||||
int32_t>
|
||||
cdm_session_restore_offline_session_;
|
||||
CounterMetric<kErrorCodeFieldNumber, CdmResponseType,
|
||||
kErrorDetailFieldNumber, int32_t>
|
||||
CounterMetric<kErrorCodeFieldNumber, CdmResponseType, kErrorDetailFieldNumber,
|
||||
int32_t>
|
||||
cdm_session_restore_usage_session_;
|
||||
|
||||
EventMetric<kKeyRequestTypeFieldNumber, CdmKeyRequestType>
|
||||
@@ -342,16 +341,16 @@ class SessionMetrics {
|
||||
|
||||
// Serialize the session metrics to the provided |metric_group|.
|
||||
// |metric_group| is owned by the caller and must not be null.
|
||||
void Serialize(drm_metrics::WvCdmMetrics::SessionMetrics *session_metrics)
|
||||
const;
|
||||
void Serialize(
|
||||
drm_metrics::WvCdmMetrics::SessionMetrics* session_metrics) const;
|
||||
|
||||
private:
|
||||
void SerializeSessionMetrics(
|
||||
drm_metrics::WvCdmMetrics::SessionMetrics *session_metrics) const;
|
||||
drm_metrics::WvCdmMetrics::SessionMetrics* session_metrics) const;
|
||||
CdmSessionId session_id_;
|
||||
bool completed_;
|
||||
CryptoMetrics crypto_metrics_;
|
||||
};
|
||||
}; // class SessionMetrics
|
||||
|
||||
// This class contains metrics for the OEMCrypto Dynamic Adapter. They are
|
||||
// separated from other metrics because they need to be encapsulated in a
|
||||
@@ -375,8 +374,8 @@ class OemCryptoDynamicAdapterMetrics {
|
||||
|
||||
// Serialize the session metrics to the provided |metric_group|.
|
||||
// |metric_group| is owned by the caller and must not be null.
|
||||
void Serialize(drm_metrics::WvCdmMetrics::EngineMetrics *engine_metrics)
|
||||
const;
|
||||
void Serialize(
|
||||
drm_metrics::WvCdmMetrics::EngineMetrics* engine_metrics) const;
|
||||
|
||||
// Clears the existing metric values.
|
||||
void Clear();
|
||||
@@ -390,14 +389,14 @@ class OemCryptoDynamicAdapterMetrics {
|
||||
previous_oemcrypto_initialization_failure_;
|
||||
ValueMetric<uint32_t> oemcrypto_l1_api_version_;
|
||||
ValueMetric<uint32_t> oemcrypto_l1_min_api_version_;
|
||||
};
|
||||
}; // class OemCryptoDynamicAdapterMetrics
|
||||
|
||||
// This will fetch the singleton instance for dynamic adapter metrics.
|
||||
// This method is safe only if we use C++ 11. In C++ 11, static function-local
|
||||
// initialization is guaranteed to be threadsafe. We return the reference to
|
||||
// avoid non-guaranteed destructor order problems. Effectively, the destructor
|
||||
// is never run for the created instance.
|
||||
OemCryptoDynamicAdapterMetrics &GetDynamicAdapterMetricsInstance();
|
||||
OemCryptoDynamicAdapterMetrics& GetDynamicAdapterMetricsInstance();
|
||||
|
||||
// This class contains engine-scoped metrics. All properties and
|
||||
// statistics related to operations within the engine, but outside
|
||||
@@ -428,18 +427,19 @@ class EngineMetrics {
|
||||
// Returns a pointer to the crypto metrics belonging to the engine instance.
|
||||
// The CryptoMetrics instance is still owned by this object and will exist
|
||||
// until this object is deleted.
|
||||
CryptoMetrics *GetCryptoMetrics() { return &crypto_metrics_; }
|
||||
CryptoMetrics* GetCryptoMetrics() { return &crypto_metrics_; }
|
||||
|
||||
// Serialize engine and session metrics into a serialized WvCdmMetrics
|
||||
// instance and output that instance to the provided |engine_metrics|.
|
||||
// |engine_metrics| is owned by the caller and must NOT be null.
|
||||
void Serialize(drm_metrics::WvCdmMetrics *engine_metrics) const;
|
||||
void Serialize(drm_metrics::WvCdmMetrics* engine_metrics) const;
|
||||
|
||||
void SetAppPackageName(const std::string &app_package_name);
|
||||
void SetAppPackageName(const std::string& app_package_name);
|
||||
|
||||
// Metrics recorded at the engine level.
|
||||
EventMetric<kErrorCodeFieldNumber, CdmResponseType,
|
||||
kLicenseTypeFieldNumber, CdmLicenseType> cdm_engine_add_key_;
|
||||
EventMetric<kErrorCodeFieldNumber, CdmResponseType, kLicenseTypeFieldNumber,
|
||||
CdmLicenseType>
|
||||
cdm_engine_add_key_;
|
||||
ValueMetric<std::string> cdm_engine_cdm_version_;
|
||||
CounterMetric<kErrorCodeFieldNumber, CdmResponseType>
|
||||
cdm_engine_close_session_;
|
||||
@@ -449,15 +449,15 @@ class EngineMetrics {
|
||||
cdm_engine_decrypt_;
|
||||
CounterMetric<kErrorCodeBoolFieldNumber, bool>
|
||||
cdm_engine_find_session_for_key_;
|
||||
EventMetric<kErrorCodeFieldNumber, CdmResponseType,
|
||||
kLicenseTypeFieldNumber, CdmLicenseType>
|
||||
EventMetric<kErrorCodeFieldNumber, CdmResponseType, kLicenseTypeFieldNumber,
|
||||
CdmLicenseType>
|
||||
cdm_engine_generate_key_request_;
|
||||
EventMetric<kErrorCodeFieldNumber, CdmResponseType>
|
||||
cdm_engine_get_provisioning_request_;
|
||||
CounterMetric<kErrorCodeFieldNumber, CdmResponseType>
|
||||
cdm_engine_get_secure_stop_ids_;
|
||||
EventMetric<kErrorCodeFieldNumber, CdmResponseType,
|
||||
kErrorDetailFieldNumber, int32_t>
|
||||
EventMetric<kErrorCodeFieldNumber, CdmResponseType, kErrorDetailFieldNumber,
|
||||
int32_t>
|
||||
cdm_engine_get_usage_info_;
|
||||
EventMetric<kErrorCodeFieldNumber, CdmResponseType>
|
||||
cdm_engine_handle_provisioning_response_;
|
||||
@@ -493,10 +493,8 @@ class EngineMetrics {
|
||||
std::string app_package_name_;
|
||||
|
||||
void SerializeEngineMetrics(
|
||||
drm_metrics::WvCdmMetrics::EngineMetrics *engine_metrics) const;
|
||||
};
|
||||
|
||||
drm_metrics::WvCdmMetrics::EngineMetrics* engine_metrics) const;
|
||||
}; // class EngineMetrics
|
||||
} // namespace metrics
|
||||
} // namespace wvcdm
|
||||
|
||||
#endif // WVCDM_METRICS_METRICS_GROUP_H_
|
||||
#endif // WVCDM_METRICS_METRICS_COLLECTIONS_H_
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
// Copyright 2018 Google Inc. All Rights Reserved.
|
||||
// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine License
|
||||
// Agreement.
|
||||
//
|
||||
// This file contains the declaration of the Pow2Bucket class which
|
||||
// is a convenient way to bucketize sampled values into powers of 2.
|
||||
#ifndef WVCDM_METRICS_POW2BUCKET_H_
|
||||
#define WVCDM_METRICS_POW2BUCKET_H_
|
||||
|
||||
namespace wvcdm {
|
||||
namespace metrics {
|
||||
|
||||
// This class converts the size_t value into the highest power of two
|
||||
// below the value. E.g. for 7, the value is 4. For 11, the value is 8.
|
||||
// This class is intended to simplify the use of EventMetric Fields that may
|
||||
@@ -17,12 +17,12 @@ class Pow2Bucket {
|
||||
public:
|
||||
explicit Pow2Bucket(size_t value) : value_(GetLowerBucket(value)) {}
|
||||
|
||||
Pow2Bucket(const Pow2Bucket &value) : value_(value.value_) {}
|
||||
Pow2Bucket(const Pow2Bucket& value) : value_(value.value_) {}
|
||||
|
||||
size_t value() const { return value_; }
|
||||
|
||||
// Support for converting to string.
|
||||
friend std::ostream &operator<<(std::ostream &os, const Pow2Bucket &log) {
|
||||
friend std::ostream& operator<<(std::ostream& os, const Pow2Bucket& log) {
|
||||
return os << log.value_;
|
||||
}
|
||||
|
||||
@@ -43,8 +43,6 @@ class Pow2Bucket {
|
||||
|
||||
size_t value_;
|
||||
};
|
||||
|
||||
} // namespace metrics
|
||||
} // namespace wvcdm
|
||||
|
||||
#endif // WVCDM_METRICS_POW2BUCKET_H_
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
// Copyright 2017 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine License
|
||||
// Agreement.
|
||||
#ifndef WVCDM_METRICS_TIMER_METRIC_H_
|
||||
#define WVCDM_METRICS_TIMER_METRIC_H_
|
||||
|
||||
#include <chrono>
|
||||
|
||||
namespace wvcdm {
|
||||
namespace metrics {
|
||||
|
||||
class TimerMetric {
|
||||
public:
|
||||
// Constructs a new TimerMetric.
|
||||
@@ -28,7 +29,6 @@ class TimerMetric {
|
||||
std::chrono::time_point<std::chrono::steady_clock> start_;
|
||||
bool is_started_;
|
||||
};
|
||||
|
||||
} // namespace metrics
|
||||
} // namespace wvcdm
|
||||
#endif
|
||||
#endif // WVCDM_METRICS_TIMER_METRIC_H_
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
// Copyright 2017 Google Inc. All Rights Reserved.
|
||||
// Copyright 2017 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine License
|
||||
// Agreement.
|
||||
//
|
||||
// This file contains the declarations for the Metric class and related
|
||||
// types.
|
||||
#ifndef WVCDM_METRICS_VALUE_METRIC_H_
|
||||
#define WVCDM_METRICS_VALUE_METRIC_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
|
||||
@@ -13,14 +15,11 @@
|
||||
|
||||
namespace wvcdm {
|
||||
namespace metrics {
|
||||
|
||||
// Internal namespace for helper methods.
|
||||
namespace impl {
|
||||
|
||||
// Helper function for setting a value in the proto.
|
||||
template <typename T>
|
||||
void SetValue(drm_metrics::ValueMetric *value_proto, const T &value);
|
||||
|
||||
void SetValue(drm_metrics::ValueMetric* value_proto, const T& value);
|
||||
} // namespace impl
|
||||
|
||||
// The ValueMetric class supports storing a single, overwritable value or an
|
||||
@@ -46,7 +45,7 @@ class ValueMetric {
|
||||
: error_code_(0), has_error_(false), has_value_(false) {}
|
||||
|
||||
// Record the value of the metric.
|
||||
void Record(const T &value) {
|
||||
void Record(const T& value) {
|
||||
std::unique_lock<std::mutex> lock(internal_lock_);
|
||||
value_ = value;
|
||||
has_value_ = true;
|
||||
@@ -65,7 +64,7 @@ class ValueMetric {
|
||||
std::unique_lock<std::mutex> lock(internal_lock_);
|
||||
return has_value_;
|
||||
}
|
||||
const T &GetValue() const {
|
||||
const T& GetValue() const {
|
||||
std::unique_lock<std::mutex> lock(internal_lock_);
|
||||
return value_;
|
||||
}
|
||||
@@ -88,14 +87,14 @@ class ValueMetric {
|
||||
|
||||
// Returns a new ValueMetric proto containing the metric value or the
|
||||
// error code. If neither the error or value are set, it returns nullptr.
|
||||
drm_metrics::ValueMetric *ToProto() const {
|
||||
drm_metrics::ValueMetric* ToProto() const {
|
||||
std::unique_lock<std::mutex> lock(internal_lock_);
|
||||
if (has_error_) {
|
||||
drm_metrics::ValueMetric *value_proto = new drm_metrics::ValueMetric;
|
||||
drm_metrics::ValueMetric* value_proto = new drm_metrics::ValueMetric;
|
||||
value_proto->set_error_code(error_code_);
|
||||
return value_proto;
|
||||
} else if (has_value_) {
|
||||
drm_metrics::ValueMetric *value_proto = new drm_metrics::ValueMetric;
|
||||
drm_metrics::ValueMetric* value_proto = new drm_metrics::ValueMetric;
|
||||
impl::SetValue(value_proto, value_);
|
||||
return value_proto;
|
||||
}
|
||||
@@ -118,9 +117,7 @@ class ValueMetric {
|
||||
* in const methods.
|
||||
*/
|
||||
mutable std::mutex internal_lock_;
|
||||
};
|
||||
|
||||
}; // class ValueMetric
|
||||
} // namespace metrics
|
||||
} // namespace wvcdm
|
||||
|
||||
#endif // WVCDM_METRICS_VALUE_METRIC_H_
|
||||
|
||||
@@ -1,113 +1,113 @@
|
||||
// Copyright 2018 Google Inc. All Rights Reserved.
|
||||
// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine License
|
||||
// Agreement.
|
||||
//
|
||||
// This file contains implementations for the AttributeHandler.
|
||||
|
||||
#include "attribute_handler.h"
|
||||
|
||||
#include "OEMCryptoCENC.h"
|
||||
#include "field_tuples.h"
|
||||
#include "pow2bucket.h"
|
||||
#include "wv_cdm_types.h"
|
||||
|
||||
namespace wvcdm {
|
||||
namespace metrics {
|
||||
|
||||
//
|
||||
// Specializations for setting attribute fields.
|
||||
//
|
||||
template <>
|
||||
void SetAttributeField<drm_metrics::Attributes::kErrorCodeFieldNumber,
|
||||
CdmResponseType>(const CdmResponseType &cdm_error,
|
||||
drm_metrics::Attributes *attributes) {
|
||||
CdmResponseType>(const CdmResponseType& cdm_error,
|
||||
drm_metrics::Attributes* attributes) {
|
||||
attributes->set_error_code(cdm_error);
|
||||
}
|
||||
|
||||
template <>
|
||||
void SetAttributeField<drm_metrics::Attributes::kCdmSecurityLevelFieldNumber,
|
||||
CdmSecurityLevel>(
|
||||
const CdmSecurityLevel &cdm_security_level,
|
||||
drm_metrics::Attributes *attributes) {
|
||||
const CdmSecurityLevel& cdm_security_level,
|
||||
drm_metrics::Attributes* attributes) {
|
||||
attributes->set_cdm_security_level(cdm_security_level);
|
||||
}
|
||||
|
||||
template <>
|
||||
void SetAttributeField<drm_metrics::Attributes::kSecurityLevelFieldNumber,
|
||||
SecurityLevel>(const SecurityLevel &security_level,
|
||||
drm_metrics::Attributes *attributes) {
|
||||
SecurityLevel>(const SecurityLevel& security_level,
|
||||
drm_metrics::Attributes* attributes) {
|
||||
attributes->set_security_level(security_level);
|
||||
}
|
||||
|
||||
template <>
|
||||
void SetAttributeField<drm_metrics::Attributes::kErrorCodeBoolFieldNumber,
|
||||
bool>(const bool &cdm_error,
|
||||
drm_metrics::Attributes *attributes) {
|
||||
bool>(const bool& cdm_error,
|
||||
drm_metrics::Attributes* attributes) {
|
||||
attributes->set_error_code_bool(cdm_error);
|
||||
}
|
||||
|
||||
template <>
|
||||
void SetAttributeField<drm_metrics::Attributes::kOemCryptoResultFieldNumber,
|
||||
OEMCryptoResult>(
|
||||
const OEMCryptoResult &oem_crypto_result,
|
||||
drm_metrics::Attributes *attributes) {
|
||||
const OEMCryptoResult& oem_crypto_result,
|
||||
drm_metrics::Attributes* attributes) {
|
||||
attributes->set_oem_crypto_result(oem_crypto_result);
|
||||
}
|
||||
|
||||
template <>
|
||||
void SetAttributeField<drm_metrics::Attributes::kLengthFieldNumber, Pow2Bucket>(
|
||||
const Pow2Bucket &pow2, drm_metrics::Attributes *attributes) {
|
||||
const Pow2Bucket& pow2, drm_metrics::Attributes* attributes) {
|
||||
attributes->set_length(pow2.value());
|
||||
}
|
||||
|
||||
template <>
|
||||
void SetAttributeField<drm_metrics::Attributes::kEncryptionAlgorithmFieldNumber,
|
||||
CdmEncryptionAlgorithm>(
|
||||
const CdmEncryptionAlgorithm &encryption_algorithm,
|
||||
drm_metrics::Attributes *attributes) {
|
||||
const CdmEncryptionAlgorithm& encryption_algorithm,
|
||||
drm_metrics::Attributes* attributes) {
|
||||
attributes->set_encryption_algorithm(encryption_algorithm);
|
||||
}
|
||||
|
||||
template <>
|
||||
void SetAttributeField<drm_metrics::Attributes::kSigningAlgorithmFieldNumber,
|
||||
CdmSigningAlgorithm>(
|
||||
const CdmSigningAlgorithm &signing_algorithm,
|
||||
drm_metrics::Attributes *attributes) {
|
||||
const CdmSigningAlgorithm& signing_algorithm,
|
||||
drm_metrics::Attributes* attributes) {
|
||||
attributes->set_signing_algorithm(signing_algorithm);
|
||||
}
|
||||
|
||||
template <>
|
||||
void SetAttributeField<drm_metrics::Attributes::kKeyRequestTypeFieldNumber,
|
||||
CdmKeyRequestType>(
|
||||
const CdmKeyRequestType &key_request_type,
|
||||
drm_metrics::Attributes *attributes) {
|
||||
const CdmKeyRequestType& key_request_type,
|
||||
drm_metrics::Attributes* attributes) {
|
||||
attributes->set_key_request_type(key_request_type);
|
||||
}
|
||||
|
||||
template <>
|
||||
void SetAttributeField<drm_metrics::Attributes::kLicenseTypeFieldNumber,
|
||||
CdmLicenseType>(
|
||||
const CdmLicenseType &license_type,
|
||||
drm_metrics::Attributes *attributes) {
|
||||
CdmLicenseType>(const CdmLicenseType& license_type,
|
||||
drm_metrics::Attributes* attributes) {
|
||||
attributes->set_license_type(license_type);
|
||||
}
|
||||
|
||||
template <>
|
||||
void SetAttributeField<drm_metrics::Attributes::kErrorDetailFieldNumber,
|
||||
int32_t>(
|
||||
const int32_t &error_detail,
|
||||
drm_metrics::Attributes *attributes) {
|
||||
int32_t>(const int32_t& error_detail,
|
||||
drm_metrics::Attributes* attributes) {
|
||||
attributes->set_error_detail(error_detail);
|
||||
}
|
||||
|
||||
template <>
|
||||
void SetAttributeField<0, util::Unused>(const util::Unused &,
|
||||
drm_metrics::Attributes *) {
|
||||
void SetAttributeField<0, util::Unused>(const util::Unused&,
|
||||
drm_metrics::Attributes*) {
|
||||
// Intentionally empty.
|
||||
}
|
||||
|
||||
// Specializations only used by tests.
|
||||
template <>
|
||||
void SetAttributeField<drm_metrics::Attributes::kErrorCodeFieldNumber, int>(
|
||||
const int &cdm_error, drm_metrics::Attributes *attributes) {
|
||||
const int& cdm_error, drm_metrics::Attributes* attributes) {
|
||||
attributes->set_error_code(cdm_error);
|
||||
}
|
||||
|
||||
} // namespace metrics
|
||||
} // namespace wvcdm
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
// Copyright 2017 Google Inc. All Rights Reserved.
|
||||
// Copyright 2017 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine License
|
||||
// Agreement.
|
||||
//
|
||||
// This file contains implementations for the BaseCounterMetric, the base class
|
||||
// for CounterMetric.
|
||||
|
||||
#include "counter_metric.h"
|
||||
|
||||
#include "wv_metrics.pb.h"
|
||||
|
||||
namespace wvcdm {
|
||||
namespace metrics {
|
||||
|
||||
void BaseCounterMetric::Increment(const std::string &counter_key,
|
||||
void BaseCounterMetric::Increment(const std::string& counter_key,
|
||||
int64_t value) {
|
||||
std::unique_lock<std::mutex> lock(internal_lock_);
|
||||
|
||||
@@ -20,6 +19,5 @@ void BaseCounterMetric::Increment(const std::string &counter_key,
|
||||
value_map_[counter_key] = value_map_[counter_key] + value;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace metrics
|
||||
} // namespace wvcdm
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
// Copyright 2017 Google Inc. All Rights Reserved.
|
||||
// Copyright 2017 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine License
|
||||
// Agreement.
|
||||
//
|
||||
// This file contains the definitions for the Distribution class members.
|
||||
|
||||
@@ -8,7 +10,6 @@
|
||||
|
||||
namespace wvcdm {
|
||||
namespace metrics {
|
||||
|
||||
Distribution::Distribution()
|
||||
: count_(0ULL),
|
||||
min_(FLT_MAX),
|
||||
@@ -26,6 +27,5 @@ void Distribution::Record(float value) {
|
||||
min_ = min_ < value ? min_ : value;
|
||||
max_ = max_ > value ? max_ : value;
|
||||
}
|
||||
|
||||
} // namespace metrics
|
||||
} // namespace wvcdm
|
||||
|
||||
@@ -1,28 +1,23 @@
|
||||
// Copyright 2017 Google Inc. All Rights Reserved.
|
||||
// Copyright 2017 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine License
|
||||
// Agreement.
|
||||
//
|
||||
// This file contains implementations for the BaseEventMetric.
|
||||
|
||||
#include "event_metric.h"
|
||||
|
||||
using ::google::protobuf::RepeatedPtrField;
|
||||
|
||||
namespace wvcdm {
|
||||
namespace metrics {
|
||||
|
||||
BaseEventMetric::~BaseEventMetric() {
|
||||
std::unique_lock<std::mutex> lock(internal_lock_);
|
||||
|
||||
for (std::map<std::string, Distribution *>::iterator it = value_map_.begin();
|
||||
for (std::map<std::string, Distribution*>::iterator it = value_map_.begin();
|
||||
it != value_map_.end(); it++) {
|
||||
delete it->second;
|
||||
}
|
||||
}
|
||||
|
||||
void BaseEventMetric::Record(const std::string &key, double value) {
|
||||
void BaseEventMetric::Record(const std::string& key, double value) {
|
||||
std::unique_lock<std::mutex> lock(internal_lock_);
|
||||
|
||||
Distribution *distribution;
|
||||
|
||||
Distribution* distribution;
|
||||
if (value_map_.find(key) == value_map_.end()) {
|
||||
distribution = new Distribution();
|
||||
value_map_[key] = distribution;
|
||||
@@ -32,6 +27,5 @@ void BaseEventMetric::Record(const std::string &key, double value) {
|
||||
|
||||
distribution->Record(value);
|
||||
}
|
||||
|
||||
} // namespace metrics
|
||||
} // namespace wvcdm
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// Copyright 2016 Google Inc. All Rights Reserved.
|
||||
|
||||
// Copyright 2016 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine License
|
||||
// Agreement.
|
||||
#include "metrics_collections.h"
|
||||
|
||||
#include <algorithm>
|
||||
@@ -7,32 +8,28 @@
|
||||
#include "log.h"
|
||||
#include "wv_metrics.pb.h"
|
||||
|
||||
namespace wvcdm {
|
||||
namespace metrics {
|
||||
using ::drm_metrics::Attributes;
|
||||
using ::drm_metrics::WvCdmMetrics;
|
||||
using ::google::protobuf::RepeatedPtrField;
|
||||
using ::wvcdm::metrics::EventMetric;
|
||||
|
||||
namespace {
|
||||
|
||||
// Helper struct for comparing session ids.
|
||||
struct CompareSessionIds {
|
||||
const std::string &target_;
|
||||
const std::string& target_;
|
||||
|
||||
CompareSessionIds(const wvcdm::CdmSessionId &target) : target_(target){};
|
||||
CompareSessionIds(const wvcdm::CdmSessionId& target) : target_(target){};
|
||||
|
||||
bool operator()(const std::shared_ptr<wvcdm::metrics::SessionMetrics> metrics)
|
||||
const {
|
||||
bool operator()(
|
||||
const std::shared_ptr<wvcdm::metrics::SessionMetrics> metrics) const {
|
||||
return metrics->GetSessionId() == target_;
|
||||
}
|
||||
};
|
||||
} // namespace
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
namespace wvcdm {
|
||||
namespace metrics {
|
||||
|
||||
void CryptoMetrics::Serialize(WvCdmMetrics::CryptoMetrics *crypto_metrics)
|
||||
const {
|
||||
void CryptoMetrics::Serialize(
|
||||
WvCdmMetrics::CryptoMetrics* crypto_metrics) const {
|
||||
/* CRYPTO SESSION */
|
||||
crypto_metrics->set_allocated_crypto_session_security_level(
|
||||
crypto_session_security_level_.ToProto());
|
||||
@@ -182,8 +179,7 @@ void CryptoMetrics::Serialize(WvCdmMetrics::CryptoMetrics *crypto_metrics)
|
||||
crypto_metrics->mutable_oemcrypto_create_new_usage_entry());
|
||||
oemcrypto_load_usage_entry_.ToProto(
|
||||
crypto_metrics->mutable_oemcrypto_load_usage_entry());
|
||||
oemcrypto_move_entry_.ToProto(
|
||||
crypto_metrics->mutable_oemcrypto_move_entry());
|
||||
oemcrypto_move_entry_.ToProto(crypto_metrics->mutable_oemcrypto_move_entry());
|
||||
oemcrypto_create_old_usage_entry_.ToProto(
|
||||
crypto_metrics->mutable_oemcrypto_create_old_usage_entry());
|
||||
oemcrypto_copy_old_usage_entry_.ToProto(
|
||||
@@ -217,14 +213,14 @@ void CryptoMetrics::Serialize(WvCdmMetrics::CryptoMetrics *crypto_metrics)
|
||||
|
||||
SessionMetrics::SessionMetrics() : session_id_(""), completed_(false) {}
|
||||
|
||||
void SessionMetrics::Serialize(WvCdmMetrics::SessionMetrics *session_metrics)
|
||||
const {
|
||||
void SessionMetrics::Serialize(
|
||||
WvCdmMetrics::SessionMetrics* session_metrics) const {
|
||||
SerializeSessionMetrics(session_metrics);
|
||||
crypto_metrics_.Serialize(session_metrics->mutable_crypto_metrics());
|
||||
}
|
||||
|
||||
void SessionMetrics::SerializeSessionMetrics(
|
||||
WvCdmMetrics::SessionMetrics *session_metrics) const {
|
||||
WvCdmMetrics::SessionMetrics* session_metrics) const {
|
||||
// If the session id was set, add it to the metrics. It's possible that
|
||||
// it's not set in some circumstances such as when provisioning is needed.
|
||||
if (!session_id_.empty()) {
|
||||
@@ -287,15 +283,15 @@ void OemCryptoDynamicAdapterMetrics::SetL1MinApiVersion(uint32_t version) {
|
||||
}
|
||||
|
||||
void OemCryptoDynamicAdapterMetrics::Serialize(
|
||||
WvCdmMetrics::EngineMetrics *engine_metrics) const {
|
||||
WvCdmMetrics::EngineMetrics* engine_metrics) const {
|
||||
std::unique_lock<std::mutex> lock(adapter_lock_);
|
||||
|
||||
engine_metrics->set_allocated_level3_oemcrypto_initialization_error(
|
||||
level3_oemcrypto_initialization_error_.ToProto());
|
||||
oemcrypto_initialization_mode_.ToProto());
|
||||
engine_metrics->set_allocated_oemcrypto_initialization_mode(
|
||||
oemcrypto_initialization_mode_.ToProto());
|
||||
engine_metrics->set_allocated_previous_oemcrypto_initialization_failure(
|
||||
previous_oemcrypto_initialization_failure_.ToProto());
|
||||
oemcrypto_initialization_mode_.ToProto());
|
||||
engine_metrics->set_allocated_oemcrypto_l1_api_version(
|
||||
oemcrypto_l1_api_version_.ToProto());
|
||||
engine_metrics->set_allocated_oemcrypto_l1_min_api_version(
|
||||
@@ -314,22 +310,20 @@ void OemCryptoDynamicAdapterMetrics::Clear() {
|
||||
|
||||
// This method returns a reference. This means that the destructor is never
|
||||
// executed for the returned object.
|
||||
OemCryptoDynamicAdapterMetrics &GetDynamicAdapterMetricsInstance() {
|
||||
OemCryptoDynamicAdapterMetrics& GetDynamicAdapterMetricsInstance() {
|
||||
// This is safe in C++ 11 since the initialization is guaranteed to run
|
||||
// only once regardless of multi-threaded access.
|
||||
static OemCryptoDynamicAdapterMetrics *adapter_metrics =
|
||||
static OemCryptoDynamicAdapterMetrics* adapter_metrics =
|
||||
new OemCryptoDynamicAdapterMetrics();
|
||||
return *adapter_metrics;
|
||||
}
|
||||
|
||||
EngineMetrics::EngineMetrics() {
|
||||
life_span_internal_.Start();
|
||||
}
|
||||
EngineMetrics::EngineMetrics() { life_span_internal_.Start(); }
|
||||
|
||||
EngineMetrics::~EngineMetrics() {
|
||||
std::unique_lock<std::mutex> lock(session_metrics_lock_);
|
||||
if (!active_session_metrics_list_.empty()
|
||||
|| !completed_session_metrics_list_.empty()) {
|
||||
if (!active_session_metrics_list_.empty() ||
|
||||
!completed_session_metrics_list_.empty()) {
|
||||
LOGV("Session counts: active = %zu, completed = %zu.",
|
||||
active_session_metrics_list_.size(),
|
||||
completed_session_metrics_list_.size());
|
||||
@@ -358,19 +352,17 @@ void EngineMetrics::RemoveSession(wvcdm::CdmSessionId session_id) {
|
||||
|
||||
void EngineMetrics::ConsolidateSessions() {
|
||||
auto completed_filter =
|
||||
[] (const std::shared_ptr<SessionMetrics>& session_metrics) {
|
||||
[](const std::shared_ptr<SessionMetrics>& session_metrics) {
|
||||
return session_metrics->IsCompleted();
|
||||
};
|
||||
|
||||
std::unique_lock<std::mutex> lock(session_metrics_lock_);
|
||||
std::copy_if(active_session_metrics_list_.begin(),
|
||||
active_session_metrics_list_.end(),
|
||||
std::back_inserter(completed_session_metrics_list_),
|
||||
completed_filter);
|
||||
std::copy_if(
|
||||
active_session_metrics_list_.begin(), active_session_metrics_list_.end(),
|
||||
std::back_inserter(completed_session_metrics_list_), completed_filter);
|
||||
active_session_metrics_list_.erase(
|
||||
std::remove_if(active_session_metrics_list_.begin(),
|
||||
active_session_metrics_list_.end(),
|
||||
completed_filter),
|
||||
active_session_metrics_list_.end(), completed_filter),
|
||||
active_session_metrics_list_.end());
|
||||
|
||||
// TODO(b/118664842): Add support to merge older metrics into one
|
||||
@@ -384,12 +376,12 @@ void EngineMetrics::ConsolidateSessions() {
|
||||
}
|
||||
}
|
||||
|
||||
void EngineMetrics::Serialize(WvCdmMetrics *wv_metrics) const {
|
||||
void EngineMetrics::Serialize(WvCdmMetrics* wv_metrics) const {
|
||||
std::unique_lock<std::mutex> lock(session_metrics_lock_);
|
||||
WvCdmMetrics::EngineMetrics *engine_metrics =
|
||||
WvCdmMetrics::EngineMetrics* engine_metrics =
|
||||
wv_metrics->mutable_engine_metrics();
|
||||
// Serialize the most recent metrics from the OemCyrpto dynamic adapter.
|
||||
OemCryptoDynamicAdapterMetrics &adapter_metrics =
|
||||
OemCryptoDynamicAdapterMetrics& adapter_metrics =
|
||||
GetDynamicAdapterMetricsInstance();
|
||||
adapter_metrics.Serialize(engine_metrics);
|
||||
if (!app_package_name_.empty()) {
|
||||
@@ -408,12 +400,12 @@ void EngineMetrics::Serialize(WvCdmMetrics *wv_metrics) const {
|
||||
}
|
||||
}
|
||||
|
||||
void EngineMetrics::SetAppPackageName(const std::string &app_package_name) {
|
||||
void EngineMetrics::SetAppPackageName(const std::string& app_package_name) {
|
||||
app_package_name_ = app_package_name;
|
||||
}
|
||||
|
||||
void EngineMetrics::SerializeEngineMetrics(
|
||||
WvCdmMetrics::EngineMetrics *engine_metrics) const {
|
||||
WvCdmMetrics::EngineMetrics* engine_metrics) const {
|
||||
// Set the engine lifespan at the time of serialization.
|
||||
engine_metrics->mutable_cdm_engine_life_span_ms()->set_int_value(
|
||||
life_span_internal_.AsMs());
|
||||
@@ -463,6 +455,5 @@ void EngineMetrics::SerializeEngineMetrics(
|
||||
|
||||
crypto_metrics_.Serialize(engine_metrics->mutable_crypto_metrics());
|
||||
}
|
||||
|
||||
} // namespace metrics
|
||||
} // namespace wvcdm
|
||||
|
||||
@@ -1,24 +1,23 @@
|
||||
// Copyright 2017 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine License
|
||||
// Agreement.
|
||||
#include "timer_metric.h"
|
||||
|
||||
namespace wvcdm {
|
||||
namespace metrics {
|
||||
|
||||
void TimerMetric::Start() {
|
||||
start_ = clock_.now();
|
||||
is_started_ = true;
|
||||
}
|
||||
|
||||
void TimerMetric::Clear() {
|
||||
is_started_ = false;
|
||||
}
|
||||
void TimerMetric::Clear() { is_started_ = false; }
|
||||
|
||||
double TimerMetric::AsMs() const {
|
||||
return (clock_.now() - start_) / std::chrono::milliseconds(1);
|
||||
return (clock_.now() - start_) / std::chrono::milliseconds(1);
|
||||
}
|
||||
|
||||
double TimerMetric::AsUs() const {
|
||||
return (clock_.now() - start_) / std::chrono::microseconds(1);
|
||||
return (clock_.now() - start_) / std::chrono::microseconds(1);
|
||||
}
|
||||
|
||||
} // namespace metrics
|
||||
} // namespace wvcdm
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
// Copyright 2017 Google Inc. All Rights Reserved.
|
||||
// Copyright 2017 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine License
|
||||
// Agreement.
|
||||
//
|
||||
// This file contains the specializations for helper methods for the
|
||||
// ValueMetric class.
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string>
|
||||
|
||||
#include "value_metric.h"
|
||||
|
||||
#include "OEMCryptoCENC.h"
|
||||
@@ -14,102 +12,96 @@
|
||||
|
||||
namespace wvcdm {
|
||||
namespace metrics {
|
||||
|
||||
namespace impl{
|
||||
|
||||
namespace impl {
|
||||
template <>
|
||||
void SetValue<int>(drm_metrics::ValueMetric *value_proto,
|
||||
const int &value) {
|
||||
void SetValue<int>(drm_metrics::ValueMetric* value_proto, const int& value) {
|
||||
value_proto->set_int_value(value);
|
||||
}
|
||||
|
||||
template <>
|
||||
void SetValue<long>(drm_metrics::ValueMetric *value_proto,
|
||||
const long &value) {
|
||||
void SetValue<long>(drm_metrics::ValueMetric* value_proto, const long& value) {
|
||||
value_proto->set_int_value(value);
|
||||
}
|
||||
|
||||
template <>
|
||||
void SetValue<long long>(drm_metrics::ValueMetric *value_proto,
|
||||
const long long &value) {
|
||||
void SetValue<long long>(drm_metrics::ValueMetric* value_proto,
|
||||
const long long& value) {
|
||||
value_proto->set_int_value(value);
|
||||
}
|
||||
|
||||
template <>
|
||||
void SetValue<unsigned int>(drm_metrics::ValueMetric *value_proto,
|
||||
const unsigned int &value) {
|
||||
void SetValue<unsigned int>(drm_metrics::ValueMetric* value_proto,
|
||||
const unsigned int& value) {
|
||||
value_proto->set_int_value((int64_t)value);
|
||||
}
|
||||
|
||||
template <>
|
||||
void SetValue<unsigned short>(drm_metrics::ValueMetric *value_proto,
|
||||
const unsigned short &value) {
|
||||
void SetValue<unsigned short>(drm_metrics::ValueMetric* value_proto,
|
||||
const unsigned short& value) {
|
||||
value_proto->set_int_value((int64_t)value);
|
||||
}
|
||||
|
||||
template <>
|
||||
void SetValue<unsigned long>(drm_metrics::ValueMetric *value_proto,
|
||||
const unsigned long &value) {
|
||||
void SetValue<unsigned long>(drm_metrics::ValueMetric* value_proto,
|
||||
const unsigned long& value) {
|
||||
value_proto->set_int_value((int64_t)value);
|
||||
}
|
||||
|
||||
template <>
|
||||
void SetValue<unsigned long long>(drm_metrics::ValueMetric *value_proto,
|
||||
const unsigned long long &value) {
|
||||
void SetValue<unsigned long long>(drm_metrics::ValueMetric* value_proto,
|
||||
const unsigned long long& value) {
|
||||
value_proto->set_int_value((int64_t)value);
|
||||
}
|
||||
|
||||
template <>
|
||||
void SetValue<bool>(drm_metrics::ValueMetric *value_proto,
|
||||
const bool &value) {
|
||||
void SetValue<bool>(drm_metrics::ValueMetric* value_proto, const bool& value) {
|
||||
value_proto->set_int_value(value);
|
||||
}
|
||||
|
||||
template <>
|
||||
void SetValue<OEMCrypto_HDCP_Capability>(
|
||||
drm_metrics::ValueMetric *value_proto,
|
||||
const OEMCrypto_HDCP_Capability &value) {
|
||||
drm_metrics::ValueMetric* value_proto,
|
||||
const OEMCrypto_HDCP_Capability& value) {
|
||||
value_proto->set_int_value(value);
|
||||
}
|
||||
|
||||
template <>
|
||||
void SetValue<OEMCrypto_ProvisioningMethod>(
|
||||
drm_metrics::ValueMetric *value_proto,
|
||||
const OEMCrypto_ProvisioningMethod &value) {
|
||||
drm_metrics::ValueMetric* value_proto,
|
||||
const OEMCrypto_ProvisioningMethod& value) {
|
||||
value_proto->set_int_value(value);
|
||||
}
|
||||
|
||||
template <>
|
||||
void SetValue<OEMCryptoInitializationMode>(
|
||||
drm_metrics::ValueMetric *value_proto,
|
||||
const OEMCryptoInitializationMode &value) {
|
||||
drm_metrics::ValueMetric* value_proto,
|
||||
const OEMCryptoInitializationMode& value) {
|
||||
value_proto->set_int_value(value);
|
||||
}
|
||||
|
||||
template <>
|
||||
void SetValue<CdmSecurityLevel>(drm_metrics::ValueMetric *value_proto,
|
||||
const CdmSecurityLevel &value) {
|
||||
void SetValue<CdmSecurityLevel>(drm_metrics::ValueMetric* value_proto,
|
||||
const CdmSecurityLevel& value) {
|
||||
value_proto->set_int_value(value);
|
||||
}
|
||||
|
||||
template <>
|
||||
void SetValue<CdmUsageSupportType>(drm_metrics::ValueMetric *value_proto,
|
||||
const CdmUsageSupportType &value) {
|
||||
void SetValue<CdmUsageSupportType>(drm_metrics::ValueMetric* value_proto,
|
||||
const CdmUsageSupportType& value) {
|
||||
value_proto->set_int_value(value);
|
||||
}
|
||||
|
||||
template <>
|
||||
void SetValue<double>(drm_metrics::ValueMetric *value_proto,
|
||||
const double &value) {
|
||||
void SetValue<double>(drm_metrics::ValueMetric* value_proto,
|
||||
const double& value) {
|
||||
value_proto->set_double_value(value);
|
||||
}
|
||||
|
||||
template <>
|
||||
void SetValue<std::string>(drm_metrics::ValueMetric *value_proto,
|
||||
const std::string &value) {
|
||||
void SetValue<std::string>(drm_metrics::ValueMetric* value_proto,
|
||||
const std::string& value) {
|
||||
value_proto->set_string_value(value);
|
||||
}
|
||||
|
||||
} // namespace impl
|
||||
} // namespace metrics
|
||||
} // namespace wvcdm
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
// Copyright 2017 Google Inc. All Rights Reserved.
|
||||
// Copyright 2017 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine License
|
||||
// Agreement.
|
||||
//
|
||||
// This file contains a proto definition for serialization of metrics data.
|
||||
//
|
||||
@@ -15,10 +17,7 @@ option optimize_for = LITE_RUNTIME;
|
||||
// want to count all of the operations with a give error code.
|
||||
message Attributes {
|
||||
// Reserved for compatibility with logging proto.
|
||||
// TODO(blueeyes): The reserved keyword is not supported in the older version
|
||||
// of protoc in the CE CDM third_party directory. Uncomment the reserved
|
||||
// line when we upgrade. b/67016366.
|
||||
// reserved 8, 10 to 13;
|
||||
reserved 8, 10 to 13;
|
||||
|
||||
// The error code. See CdmResponseType in wv_cdm_types.h
|
||||
optional int32 error_code = 1;
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
// Copyright 2017 Google Inc. All Rights Reserved.
|
||||
// Copyright 2017 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine License
|
||||
// Agreement.
|
||||
//
|
||||
// Unit tests for CounterMetric
|
||||
|
||||
#include "counter_metric.h"
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "string_conversions.h"
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
using drm_metrics::TestMetrics;
|
||||
using testing::IsNull;
|
||||
using testing::NotNull;
|
||||
#include "pow2bucket.h"
|
||||
#include "string_conversions.h"
|
||||
#include "wv_cdm_types.h"
|
||||
|
||||
namespace wvcdm {
|
||||
namespace metrics {
|
||||
using drm_metrics::TestMetrics;
|
||||
|
||||
TEST(CounterMetricTest, NoFieldsEmpty) {
|
||||
wvcdm::metrics::CounterMetric<> metric;
|
||||
@@ -43,7 +43,8 @@ TEST(CounterMetricTest, NoFieldsSuccess) {
|
||||
|
||||
TEST(CounterMetricTest, OneFieldSuccess) {
|
||||
wvcdm::metrics::CounterMetric<drm_metrics::Attributes::kErrorCodeFieldNumber,
|
||||
int> metric;
|
||||
int>
|
||||
metric;
|
||||
metric.Increment(7);
|
||||
metric.Increment(10, 7);
|
||||
metric.Increment(13);
|
||||
@@ -61,7 +62,8 @@ TEST(CounterMetricTest, OneFieldSuccess) {
|
||||
|
||||
TEST(CounterMetricTest, TwoFieldsSuccess) {
|
||||
CounterMetric<drm_metrics::Attributes::kErrorCodeFieldNumber, int,
|
||||
drm_metrics::Attributes::kLengthFieldNumber, Pow2Bucket> metric;
|
||||
drm_metrics::Attributes::kLengthFieldNumber, Pow2Bucket>
|
||||
metric;
|
||||
|
||||
metric.Increment(7, Pow2Bucket(23)); // Increment by one.
|
||||
metric.Increment(2, 7, Pow2Bucket(33));
|
||||
@@ -93,7 +95,7 @@ TEST(CounterMetricTest, ThreeFieldsSuccess) {
|
||||
CounterMetric<drm_metrics::Attributes::kErrorCodeFieldNumber, int,
|
||||
drm_metrics::Attributes::kLengthFieldNumber, Pow2Bucket,
|
||||
drm_metrics::Attributes::kErrorCodeBoolFieldNumber, bool>
|
||||
metric;
|
||||
metric;
|
||||
metric.Increment(7, Pow2Bucket(13), true);
|
||||
|
||||
TestMetrics metric_proto;
|
||||
@@ -110,7 +112,8 @@ TEST(CounterMetricTest, FourFieldsSuccess) {
|
||||
drm_metrics::Attributes::kLengthFieldNumber, Pow2Bucket,
|
||||
drm_metrics::Attributes::kErrorCodeBoolFieldNumber, bool,
|
||||
drm_metrics::Attributes::kSecurityLevelFieldNumber,
|
||||
SecurityLevel> metric;
|
||||
SecurityLevel>
|
||||
metric;
|
||||
metric.Increment(10LL, 7, Pow2Bucket(13), true, kLevel3);
|
||||
|
||||
TestMetrics metric_proto;
|
||||
@@ -123,6 +126,5 @@ TEST(CounterMetricTest, FourFieldsSuccess) {
|
||||
EXPECT_EQ(kLevel3,
|
||||
metric_proto.test_counters(0).attributes().security_level());
|
||||
}
|
||||
|
||||
} // namespace metrics
|
||||
} // namespace wvcdm
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
// Copyright 2017 Google Inc. All Rights Reserved.
|
||||
// Copyright 2017 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine License
|
||||
// Agreement.
|
||||
//
|
||||
// Unit tests for Distribution.
|
||||
|
||||
#include <float.h>
|
||||
|
||||
#include "distribution.h"
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include <float.h>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
namespace wvcdm {
|
||||
namespace metrics {
|
||||
|
||||
TEST(DistributionTest, NoValuesRecorded) {
|
||||
Distribution distribution;
|
||||
EXPECT_EQ(FLT_MAX, distribution.Min());
|
||||
@@ -41,7 +42,5 @@ TEST(DistributionTest, MultipleValuesRecorded) {
|
||||
EXPECT_EQ(3u, distribution.Count());
|
||||
EXPECT_NEAR(16.6667, distribution.Variance(), 0.0001);
|
||||
}
|
||||
|
||||
} // namespace metrics
|
||||
} // namespace wvcdm
|
||||
|
||||
|
||||
@@ -1,19 +1,18 @@
|
||||
// Copyright 2017 Google Inc. All Rights Reserved.
|
||||
// Copyright 2017 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine License
|
||||
// Agreement.
|
||||
//
|
||||
// Unit tests for EventMetric
|
||||
|
||||
#include "event_metric.h"
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "string_conversions.h"
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
using drm_metrics::TestMetrics;
|
||||
using testing::IsNull;
|
||||
using testing::NotNull;
|
||||
#include "string_conversions.h"
|
||||
#include "wv_cdm_types.h"
|
||||
|
||||
namespace wvcdm {
|
||||
namespace metrics {
|
||||
using drm_metrics::TestMetrics;
|
||||
|
||||
class EventMetricTest : public ::testing::Test {
|
||||
public:
|
||||
@@ -71,7 +70,8 @@ TEST_F(EventMetricTest, OneFieldSuccess) {
|
||||
|
||||
TEST_F(EventMetricTest, TwoFieldsSuccess) {
|
||||
EventMetric<drm_metrics::Attributes::kErrorCodeFieldNumber, int,
|
||||
drm_metrics::Attributes::kLengthFieldNumber, Pow2Bucket> metric;
|
||||
drm_metrics::Attributes::kLengthFieldNumber, Pow2Bucket>
|
||||
metric;
|
||||
|
||||
metric.Record(1, 7, Pow2Bucket(23));
|
||||
metric.Record(2, 7, Pow2Bucket(33));
|
||||
@@ -114,7 +114,8 @@ TEST_F(EventMetricTest, TwoFieldsSuccess) {
|
||||
TEST_F(EventMetricTest, ThreeFieldsSuccess) {
|
||||
EventMetric<drm_metrics::Attributes::kErrorCodeFieldNumber, int,
|
||||
drm_metrics::Attributes::kLengthFieldNumber, Pow2Bucket,
|
||||
drm_metrics::Attributes::kErrorCodeBoolFieldNumber, bool> metric;
|
||||
drm_metrics::Attributes::kErrorCodeBoolFieldNumber, bool>
|
||||
metric;
|
||||
metric.Record(10LL, 7, Pow2Bucket(13), false);
|
||||
metric.Record(11LL, 8, Pow2Bucket(17), true);
|
||||
|
||||
@@ -127,14 +128,16 @@ TEST_F(EventMetricTest, ThreeFieldsSuccess) {
|
||||
EXPECT_FALSE(metric_proto.test_distributions(0).has_variance());
|
||||
EXPECT_EQ(7, metric_proto.test_distributions(0).attributes().error_code());
|
||||
EXPECT_EQ(8u, metric_proto.test_distributions(0).attributes().length());
|
||||
EXPECT_FALSE(metric_proto.test_distributions(0).attributes().error_code_bool());
|
||||
EXPECT_FALSE(
|
||||
metric_proto.test_distributions(0).attributes().error_code_bool());
|
||||
|
||||
EXPECT_EQ(1u, metric_proto.test_distributions(1).operation_count());
|
||||
EXPECT_EQ(11LL, metric_proto.test_distributions(1).mean());
|
||||
EXPECT_FALSE(metric_proto.test_distributions(1).has_variance());
|
||||
EXPECT_EQ(8, metric_proto.test_distributions(1).attributes().error_code());
|
||||
EXPECT_EQ(16u, metric_proto.test_distributions(1).attributes().length());
|
||||
EXPECT_TRUE(metric_proto.test_distributions(1).attributes().error_code_bool());
|
||||
EXPECT_TRUE(
|
||||
metric_proto.test_distributions(1).attributes().error_code_bool());
|
||||
}
|
||||
|
||||
TEST_F(EventMetricTest, FourFieldsSuccess) {
|
||||
@@ -142,7 +145,8 @@ TEST_F(EventMetricTest, FourFieldsSuccess) {
|
||||
drm_metrics::Attributes::kLengthFieldNumber, Pow2Bucket,
|
||||
drm_metrics::Attributes::kErrorCodeBoolFieldNumber, bool,
|
||||
drm_metrics::Attributes::kCdmSecurityLevelFieldNumber,
|
||||
CdmSecurityLevel> metric;
|
||||
CdmSecurityLevel>
|
||||
metric;
|
||||
|
||||
metric.Record(10LL, 7, Pow2Bucket(13), true, kSecurityLevelL3);
|
||||
|
||||
@@ -155,7 +159,8 @@ TEST_F(EventMetricTest, FourFieldsSuccess) {
|
||||
EXPECT_FALSE(metric_proto.test_distributions(0).has_variance());
|
||||
EXPECT_EQ(7, metric_proto.test_distributions(0).attributes().error_code());
|
||||
EXPECT_EQ(8u, metric_proto.test_distributions(0).attributes().length());
|
||||
EXPECT_TRUE(metric_proto.test_distributions(0).attributes().error_code_bool());
|
||||
EXPECT_TRUE(
|
||||
metric_proto.test_distributions(0).attributes().error_code_bool());
|
||||
EXPECT_EQ(
|
||||
3u, metric_proto.test_distributions(0).attributes().cdm_security_level());
|
||||
}
|
||||
@@ -185,6 +190,5 @@ TEST_F(EventMetricTest, Pow2BucketTest) {
|
||||
value << Pow2Bucket(0x7FFFFFFF);
|
||||
EXPECT_EQ("1073741824", value.str());
|
||||
}
|
||||
|
||||
} // namespace metrics
|
||||
} // namespace wvcdm
|
||||
|
||||
@@ -1,29 +1,24 @@
|
||||
// Copyright 2017 Google Inc. All Rights Reserved.
|
||||
// Copyright 2017 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine License
|
||||
// Agreement.
|
||||
//
|
||||
// Unit tests for the metrics collections,
|
||||
// EngineMetrics, SessionMetrics and CrytpoMetrics.
|
||||
|
||||
#include "metrics_collections.h"
|
||||
|
||||
#include <sstream>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "google/protobuf/text_format.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "log.h"
|
||||
#include "wv_cdm_types.h"
|
||||
#include "wv_metrics.pb.h"
|
||||
|
||||
using drm_metrics::MetricsGroup;
|
||||
using google::protobuf::TextFormat;
|
||||
|
||||
namespace wvcdm {
|
||||
namespace metrics {
|
||||
using drm_metrics::MetricsGroup;
|
||||
|
||||
// TODO(blueeyes): Improve this implementation by supporting full message
|
||||
// API In CDM. That allows us to use MessageDifferencer.
|
||||
class EngineMetricsTest : public ::testing::Test {
|
||||
};
|
||||
class EngineMetricsTest : public ::testing::Test {};
|
||||
|
||||
TEST_F(EngineMetricsTest, AllEngineMetrics) {
|
||||
EngineMetrics engine_metrics;
|
||||
@@ -45,7 +40,8 @@ TEST_F(EngineMetricsTest, AllEngineMetrics) {
|
||||
engine_metrics.cdm_engine_release_usage_info_.Record(1.0, NO_ERROR);
|
||||
engine_metrics.cdm_engine_remove_keys_.Record(1.0, NO_ERROR);
|
||||
engine_metrics.cdm_engine_restore_key_.Record(1.0, NO_ERROR);
|
||||
engine_metrics.cdm_engine_unprovision_.Record(1.0, NO_ERROR, kSecurityLevelL1);
|
||||
engine_metrics.cdm_engine_unprovision_.Record(1.0, NO_ERROR,
|
||||
kSecurityLevelL1);
|
||||
|
||||
drm_metrics::MetricsGroup actual_metrics;
|
||||
engine_metrics.Serialize(&actual_metrics, true, false);
|
||||
@@ -73,10 +69,9 @@ TEST_F(EngineMetricsTest, EngineAndCryptoMetrics) {
|
||||
engine_metrics.cdm_engine_close_session_.Record(1.0, NO_ERROR);
|
||||
CryptoMetrics* crypto_metrics = engine_metrics.GetCryptoMetrics();
|
||||
|
||||
crypto_metrics->crypto_session_generic_decrypt_
|
||||
.Record(2.0, NO_ERROR, Pow2Bucket(1025), kEncryptionAlgorithmAesCbc128);
|
||||
crypto_metrics->crypto_session_get_device_unique_id_
|
||||
.Record(4.0, false);
|
||||
crypto_metrics->crypto_session_generic_decrypt_.Record(
|
||||
2.0, NO_ERROR, Pow2Bucket(1025), kEncryptionAlgorithmAesCbc128);
|
||||
crypto_metrics->crypto_session_get_device_unique_id_.Record(4.0, false);
|
||||
|
||||
drm_metrics::MetricsGroup actual_metrics;
|
||||
engine_metrics.Serialize(&actual_metrics, true, false);
|
||||
@@ -124,8 +119,8 @@ TEST_F(EngineMetricsTest, EngineMetricsWithCompletedSessions) {
|
||||
SessionMetrics* session_metrics_2 = engine_metrics.AddSession();
|
||||
session_metrics_2->SetSessionId("session_id_2");
|
||||
// Record a CryptoMetrics metric in the session.
|
||||
session_metrics_2->GetCryptoMetrics()->crypto_session_generic_decrypt_
|
||||
.Record(2.0, NO_ERROR, Pow2Bucket(1025), kEncryptionAlgorithmAesCbc128);
|
||||
session_metrics_2->GetCryptoMetrics()->crypto_session_generic_decrypt_.Record(
|
||||
2.0, NO_ERROR, Pow2Bucket(1025), kEncryptionAlgorithmAesCbc128);
|
||||
session_metrics_2->SetSessionId("session_id_2");
|
||||
// Mark only session 2 as completed.
|
||||
session_metrics_2->SetCompleted();
|
||||
@@ -144,9 +139,10 @@ TEST_F(EngineMetricsTest, EngineMetricsWithCompletedSessions) {
|
||||
// Spot check some metrics.
|
||||
EXPECT_EQ("/drm/widevine/cdm_engine/add_key/time/count{error:2}",
|
||||
actual_metrics.metric(0).name());
|
||||
EXPECT_EQ("/drm/widevine/crypto_session/load_certificate_private_key"
|
||||
"/time/count{success:1}",
|
||||
actual_metrics.metric(2).name());
|
||||
EXPECT_EQ(
|
||||
"/drm/widevine/crypto_session/load_certificate_private_key"
|
||||
"/time/count{success:1}",
|
||||
actual_metrics.metric(2).name());
|
||||
EXPECT_EQ("/drm/widevine/cdm_session/session_id",
|
||||
actual_metrics.metric_sub_group(0).metric(0).name());
|
||||
EXPECT_EQ(
|
||||
@@ -241,8 +237,7 @@ TEST_F(EngineMetricsTest, EngineMetricsRemoveSessions) {
|
||||
ASSERT_EQ(0, actual_metrics.metric_sub_group_size());
|
||||
}
|
||||
|
||||
class SessionMetricsTest : public ::testing::Test {
|
||||
};
|
||||
class SessionMetricsTest : public ::testing::Test {};
|
||||
|
||||
TEST_F(SessionMetricsTest, AllSessionMetrics) {
|
||||
SessionMetrics session_metrics;
|
||||
@@ -254,8 +249,8 @@ TEST_F(SessionMetricsTest, AllSessionMetrics) {
|
||||
session_metrics.cdm_session_restore_usage_session_.Record(1.0, NO_ERROR);
|
||||
|
||||
// Record a CryptoMetrics metric in the session.
|
||||
session_metrics.GetCryptoMetrics()->crypto_session_generic_decrypt_
|
||||
.Record(2.0, NO_ERROR, Pow2Bucket(1025), kEncryptionAlgorithmAesCbc128);
|
||||
session_metrics.GetCryptoMetrics()->crypto_session_generic_decrypt_.Record(
|
||||
2.0, NO_ERROR, Pow2Bucket(1025), kEncryptionAlgorithmAesCbc128);
|
||||
|
||||
MetricsGroup actual_metrics;
|
||||
session_metrics.Serialize(&actual_metrics);
|
||||
@@ -271,9 +266,10 @@ TEST_F(SessionMetricsTest, AllSessionMetrics) {
|
||||
EXPECT_EQ("/drm/widevine/cdm_session/renew_key/time/mean{error:0}",
|
||||
actual_metrics.metric(4).name());
|
||||
EXPECT_EQ(1.0, actual_metrics.metric(4).value().double_value());
|
||||
EXPECT_EQ("/drm/widevine/crypto_session/generic_decrypt/time/count"
|
||||
"{error:0&length:1024&encryption_algorithm:1}",
|
||||
actual_metrics.metric(9).name());
|
||||
EXPECT_EQ(
|
||||
"/drm/widevine/crypto_session/generic_decrypt/time/count"
|
||||
"{error:0&length:1024&encryption_algorithm:1}",
|
||||
actual_metrics.metric(9).name());
|
||||
}
|
||||
|
||||
TEST_F(SessionMetricsTest, EmptySessionMetrics) {
|
||||
@@ -290,134 +286,126 @@ TEST_F(SessionMetricsTest, EmptySessionMetrics) {
|
||||
EXPECT_EQ(0, actual_metrics.metric_sub_group_size());
|
||||
}
|
||||
|
||||
class CryptoMetricsTest : public ::testing::Test {
|
||||
};
|
||||
class CryptoMetricsTest : public ::testing::Test {};
|
||||
|
||||
TEST_F(CryptoMetricsTest, AllCryptoMetrics) {
|
||||
CryptoMetrics crypto_metrics;
|
||||
|
||||
// Crypto session metrics.
|
||||
crypto_metrics.crypto_session_delete_all_usage_reports_
|
||||
.Record(1.0, NO_ERROR);
|
||||
crypto_metrics.crypto_session_delete_multiple_usage_information_
|
||||
.Record(1.0, NO_ERROR);
|
||||
crypto_metrics.crypto_session_generic_decrypt_
|
||||
.Record(2.0, NO_ERROR, Pow2Bucket(1025), kEncryptionAlgorithmAesCbc128);
|
||||
crypto_metrics.crypto_session_generic_encrypt_
|
||||
.Record(2.0, NO_ERROR, Pow2Bucket(1025), kEncryptionAlgorithmAesCbc128);
|
||||
crypto_metrics.crypto_session_generic_sign_
|
||||
.Record(2.0, NO_ERROR, Pow2Bucket(1025), kSigningAlgorithmHmacSha256);
|
||||
crypto_metrics.crypto_session_generic_verify_
|
||||
.Record(2.0, NO_ERROR, Pow2Bucket(1025), kSigningAlgorithmHmacSha256);
|
||||
crypto_metrics.crypto_session_delete_all_usage_reports_.Record(1.0, NO_ERROR);
|
||||
crypto_metrics.crypto_session_delete_multiple_usage_information_.Record(
|
||||
1.0, NO_ERROR);
|
||||
crypto_metrics.crypto_session_generic_decrypt_.Record(
|
||||
2.0, NO_ERROR, Pow2Bucket(1025), kEncryptionAlgorithmAesCbc128);
|
||||
crypto_metrics.crypto_session_generic_encrypt_.Record(
|
||||
2.0, NO_ERROR, Pow2Bucket(1025), kEncryptionAlgorithmAesCbc128);
|
||||
crypto_metrics.crypto_session_generic_sign_.Record(
|
||||
2.0, NO_ERROR, Pow2Bucket(1025), kSigningAlgorithmHmacSha256);
|
||||
crypto_metrics.crypto_session_generic_verify_.Record(
|
||||
2.0, NO_ERROR, Pow2Bucket(1025), kSigningAlgorithmHmacSha256);
|
||||
crypto_metrics.crypto_session_get_device_unique_id_.Record(1.0, true);
|
||||
crypto_metrics.crypto_session_get_security_level_
|
||||
.Record(1.0, kSecurityLevelL1);
|
||||
crypto_metrics.crypto_session_get_security_level_.Record(1.0,
|
||||
kSecurityLevelL1);
|
||||
crypto_metrics.crypto_session_get_system_id_.Record(1.0, true, 1234);
|
||||
crypto_metrics.crypto_session_get_token_.Record(1.0, true);
|
||||
crypto_metrics.crypto_session_life_span_.Record(1.0);
|
||||
crypto_metrics.crypto_session_load_certificate_private_key_
|
||||
.Record(1.0, true);
|
||||
crypto_metrics.crypto_session_load_certificate_private_key_.Record(1.0, true);
|
||||
crypto_metrics.crypto_session_open_.Record(1.0, NO_ERROR, kLevelDefault);
|
||||
crypto_metrics.crypto_session_update_usage_information_
|
||||
.Record(1.0, NO_ERROR);
|
||||
crypto_metrics.crypto_session_update_usage_information_.Record(1.0, NO_ERROR);
|
||||
crypto_metrics.crypto_session_usage_information_support_.Record(1.0, true);
|
||||
|
||||
// Oem crypto metrics.
|
||||
crypto_metrics.oemcrypto_api_version_.Record(1.0, 123, kLevelDefault);
|
||||
crypto_metrics.oemcrypto_close_session_
|
||||
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_copy_buffer_
|
||||
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED,
|
||||
kLevelDefault, Pow2Bucket(1025));
|
||||
crypto_metrics.oemcrypto_deactivate_usage_entry_
|
||||
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_decrypt_cenc_
|
||||
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED, Pow2Bucket(1025));
|
||||
crypto_metrics.oemcrypto_delete_usage_entry_
|
||||
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_delete_usage_table_
|
||||
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_derive_keys_from_session_key_
|
||||
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_force_delete_usage_entry_
|
||||
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_generate_derived_keys_
|
||||
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_generate_nonce_
|
||||
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_generate_rsa_signature_
|
||||
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED, Pow2Bucket(1025));
|
||||
crypto_metrics.oemcrypto_generate_signature_
|
||||
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED, Pow2Bucket(1025));
|
||||
crypto_metrics.oemcrypto_generic_decrypt_
|
||||
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED, Pow2Bucket(1025));
|
||||
crypto_metrics.oemcrypto_generic_encrypt_
|
||||
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED, Pow2Bucket(1025));
|
||||
crypto_metrics.oemcrypto_generic_sign_
|
||||
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED, Pow2Bucket(1025));
|
||||
crypto_metrics.oemcrypto_generic_verify_
|
||||
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED, Pow2Bucket(1025));
|
||||
crypto_metrics.oemcrypto_get_device_id_
|
||||
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED, kLevelDefault);
|
||||
crypto_metrics.oemcrypto_get_hdcp_capability_
|
||||
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED, kLevelDefault);
|
||||
crypto_metrics.oemcrypto_get_key_data_
|
||||
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED,
|
||||
Pow2Bucket(1025), kLevelDefault);
|
||||
crypto_metrics.oemcrypto_get_max_number_of_sessions_
|
||||
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED, kLevelDefault);
|
||||
crypto_metrics.oemcrypto_get_number_of_open_sessions_
|
||||
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED, kLevelDefault);
|
||||
crypto_metrics.oemcrypto_get_oem_public_certificate_
|
||||
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_close_session_.Record(1.0,
|
||||
OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_copy_buffer_.Record(1.0, OEMCrypto_ERROR_INIT_FAILED,
|
||||
kLevelDefault, Pow2Bucket(1025));
|
||||
crypto_metrics.oemcrypto_deactivate_usage_entry_.Record(
|
||||
1.0, OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_decrypt_cenc_.Record(
|
||||
1.0, OEMCrypto_ERROR_INIT_FAILED, Pow2Bucket(1025));
|
||||
crypto_metrics.oemcrypto_delete_usage_entry_.Record(
|
||||
1.0, OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_delete_usage_table_.Record(
|
||||
1.0, OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_derive_keys_from_session_key_.Record(
|
||||
1.0, OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_force_delete_usage_entry_.Record(
|
||||
1.0, OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_generate_derived_keys_.Record(
|
||||
1.0, OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_generate_nonce_.Record(1.0,
|
||||
OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_generate_rsa_signature_.Record(
|
||||
1.0, OEMCrypto_ERROR_INIT_FAILED, Pow2Bucket(1025));
|
||||
crypto_metrics.oemcrypto_generate_signature_.Record(
|
||||
1.0, OEMCrypto_ERROR_INIT_FAILED, Pow2Bucket(1025));
|
||||
crypto_metrics.oemcrypto_generic_decrypt_.Record(
|
||||
1.0, OEMCrypto_ERROR_INIT_FAILED, Pow2Bucket(1025));
|
||||
crypto_metrics.oemcrypto_generic_encrypt_.Record(
|
||||
1.0, OEMCrypto_ERROR_INIT_FAILED, Pow2Bucket(1025));
|
||||
crypto_metrics.oemcrypto_generic_sign_.Record(
|
||||
1.0, OEMCrypto_ERROR_INIT_FAILED, Pow2Bucket(1025));
|
||||
crypto_metrics.oemcrypto_generic_verify_.Record(
|
||||
1.0, OEMCrypto_ERROR_INIT_FAILED, Pow2Bucket(1025));
|
||||
crypto_metrics.oemcrypto_get_device_id_.Record(
|
||||
1.0, OEMCrypto_ERROR_INIT_FAILED, kLevelDefault);
|
||||
crypto_metrics.oemcrypto_get_hdcp_capability_.Record(
|
||||
1.0, OEMCrypto_ERROR_INIT_FAILED, kLevelDefault);
|
||||
crypto_metrics.oemcrypto_get_key_data_.Record(
|
||||
1.0, OEMCrypto_ERROR_INIT_FAILED, Pow2Bucket(1025), kLevelDefault);
|
||||
crypto_metrics.oemcrypto_get_max_number_of_sessions_.Record(
|
||||
1.0, OEMCrypto_ERROR_INIT_FAILED, kLevelDefault);
|
||||
crypto_metrics.oemcrypto_get_number_of_open_sessions_.Record(
|
||||
1.0, OEMCrypto_ERROR_INIT_FAILED, kLevelDefault);
|
||||
crypto_metrics.oemcrypto_get_oem_public_certificate_.Record(
|
||||
1.0, OEMCrypto_ERROR_INIT_FAILED);
|
||||
|
||||
crypto_metrics.oemcrypto_get_provisioning_method_
|
||||
.Record(1.0, OEMCrypto_Keybox, kLevelDefault);
|
||||
crypto_metrics.oemcrypto_get_provisioning_method_.Record(
|
||||
1.0, OEMCrypto_Keybox, kLevelDefault);
|
||||
|
||||
crypto_metrics.oemcrypto_get_random_
|
||||
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED, Pow2Bucket(1025));
|
||||
crypto_metrics.oemcrypto_initialize_
|
||||
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_install_keybox_
|
||||
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED, kLevelDefault);
|
||||
crypto_metrics.oemcrypto_is_anti_rollback_hw_present_
|
||||
.Record(1.0, true, kLevelDefault);
|
||||
crypto_metrics.oemcrypto_get_random_.Record(1.0, OEMCrypto_ERROR_INIT_FAILED,
|
||||
Pow2Bucket(1025));
|
||||
crypto_metrics.oemcrypto_initialize_.Record(1.0, OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_install_keybox_.Record(
|
||||
1.0, OEMCrypto_ERROR_INIT_FAILED, kLevelDefault);
|
||||
crypto_metrics.oemcrypto_is_anti_rollback_hw_present_.Record(1.0, true,
|
||||
kLevelDefault);
|
||||
|
||||
crypto_metrics.oemcrypto_is_keybox_valid_
|
||||
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED, kLevelDefault);
|
||||
crypto_metrics.oemcrypto_load_device_rsa_key_
|
||||
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_is_keybox_valid_.Record(
|
||||
1.0, OEMCrypto_ERROR_INIT_FAILED, kLevelDefault);
|
||||
crypto_metrics.oemcrypto_load_device_rsa_key_.Record(
|
||||
1.0, OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_load_keys_.Record(1.0, OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_load_test_keybox_
|
||||
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_load_test_rsa_key_
|
||||
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_open_session_
|
||||
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED, kLevelDefault);
|
||||
crypto_metrics.oemcrypto_refresh_keys_
|
||||
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_report_usage_
|
||||
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_rewrap_device_rsa_key_
|
||||
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_rewrap_device_rsa_key_30_
|
||||
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_security_level_
|
||||
.Record(1.0, kSecurityLevelL2, kLevelDefault);
|
||||
crypto_metrics.oemcrypto_security_patch_level_
|
||||
.Record(1.0, 123, kLevelDefault);
|
||||
crypto_metrics.oemcrypto_select_key_
|
||||
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_supports_usage_table_
|
||||
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED, kLevelDefault);
|
||||
crypto_metrics.oemcrypto_update_usage_table_
|
||||
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_wrap_keybox_
|
||||
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_load_test_keybox_.Record(
|
||||
1.0, OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_load_test_rsa_key_.Record(
|
||||
1.0, OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_open_session_.Record(
|
||||
1.0, OEMCrypto_ERROR_INIT_FAILED, kLevelDefault);
|
||||
crypto_metrics.oemcrypto_refresh_keys_.Record(1.0,
|
||||
OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_report_usage_.Record(1.0,
|
||||
OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_rewrap_device_rsa_key_.Record(
|
||||
1.0, OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_rewrap_device_rsa_key_30_.Record(
|
||||
1.0, OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_security_level_.Record(1.0, kSecurityLevelL2,
|
||||
kLevelDefault);
|
||||
crypto_metrics.oemcrypto_security_patch_level_.Record(1.0, 123,
|
||||
kLevelDefault);
|
||||
crypto_metrics.oemcrypto_select_key_.Record(1.0, OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_supports_usage_table_.Record(
|
||||
1.0, OEMCrypto_ERROR_INIT_FAILED, kLevelDefault);
|
||||
crypto_metrics.oemcrypto_update_usage_table_.Record(
|
||||
1.0, OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_wrap_keybox_.Record(1.0,
|
||||
OEMCrypto_ERROR_INIT_FAILED);
|
||||
|
||||
// Internal OEMCrypto Metrics
|
||||
crypto_metrics.oemcrypto_initialization_mode_
|
||||
.Record(1.0, OEMCrypto_INITIALIZED_FORCING_L3);
|
||||
crypto_metrics.oemcrypto_initialization_mode_.Record(
|
||||
1.0, OEMCrypto_INITIALIZED_FORCING_L3);
|
||||
crypto_metrics.oemcrypto_l1_api_version_.Record(1.0, 12, 123);
|
||||
|
||||
MetricsGroup actual_metrics;
|
||||
@@ -440,6 +428,5 @@ TEST_F(CryptoMetricsTest, AllCryptoMetrics) {
|
||||
// No subgroups should exist.
|
||||
EXPECT_EQ(0, actual_metrics.metric_sub_group_size());
|
||||
}
|
||||
|
||||
} // namespace metrics
|
||||
} // namespace wvcdm
|
||||
|
||||
@@ -1,35 +1,31 @@
|
||||
// Copyright 2017 Google Inc. All Rights Reserved.
|
||||
// Copyright 2017 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine License
|
||||
// Agreement.
|
||||
//
|
||||
// Unit tests for the metrics collections,
|
||||
// EngineMetrics, SessionMetrics and CryptoMetrics.
|
||||
|
||||
#include "metrics_collections.h"
|
||||
|
||||
#include <sstream>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "device_files.h"
|
||||
#include "gmock/gmock.h"
|
||||
#include "google/protobuf/text_format.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "log.h"
|
||||
#include "string_conversions.h"
|
||||
#include "wv_cdm_types.h"
|
||||
#include "wv_metrics.pb.h"
|
||||
|
||||
namespace wvcdm {
|
||||
namespace metrics {
|
||||
using drm_metrics::WvCdmMetrics;
|
||||
|
||||
namespace {
|
||||
const char kSessionId1[] = "session_id_1";
|
||||
const char kSessionId2[] = "session_id_2";
|
||||
} // anonymous namespace
|
||||
|
||||
namespace wvcdm {
|
||||
namespace metrics {
|
||||
} // namespace
|
||||
|
||||
// TODO(blueeyes): Improve this implementation by supporting full message
|
||||
// API In CDM. That allows us to use MessageDifferencer.
|
||||
class EngineMetricsTest : public ::testing::Test {
|
||||
};
|
||||
class EngineMetricsTest : public ::testing::Test {};
|
||||
|
||||
TEST_F(EngineMetricsTest, AllEngineMetrics) {
|
||||
EngineMetrics engine_metrics;
|
||||
@@ -78,16 +74,16 @@ TEST_F(EngineMetricsTest, AllEngineMetrics) {
|
||||
EXPECT_GT(actual.engine_metrics().cdm_engine_decrypt_time_us_size(), 0);
|
||||
EXPECT_GT(actual.engine_metrics().cdm_engine_find_session_for_key_size(), 0);
|
||||
EXPECT_GT(
|
||||
actual.engine_metrics()
|
||||
.cdm_engine_generate_key_request_time_us_size(), 0);
|
||||
EXPECT_GT(
|
||||
actual.engine_metrics()
|
||||
.cdm_engine_get_provisioning_request_time_us_size(), 0);
|
||||
actual.engine_metrics().cdm_engine_generate_key_request_time_us_size(),
|
||||
0);
|
||||
EXPECT_GT(actual.engine_metrics()
|
||||
.cdm_engine_get_provisioning_request_time_us_size(),
|
||||
0);
|
||||
EXPECT_GT(actual.engine_metrics().cdm_engine_get_usage_info_time_us_size(),
|
||||
0);
|
||||
EXPECT_GT(
|
||||
actual.engine_metrics()
|
||||
.cdm_engine_handle_provisioning_response_time_us_size(), 0);
|
||||
EXPECT_GT(actual.engine_metrics()
|
||||
.cdm_engine_handle_provisioning_response_time_us_size(),
|
||||
0);
|
||||
EXPECT_GT(actual.engine_metrics().cdm_engine_open_key_set_session_size(), 0);
|
||||
EXPECT_GT(actual.engine_metrics().cdm_engine_open_session_size(), 0);
|
||||
EXPECT_GT(actual.engine_metrics().cdm_engine_query_key_status_time_us_size(),
|
||||
@@ -105,9 +101,9 @@ TEST_F(EngineMetricsTest, AllEngineMetrics) {
|
||||
actual.engine_metrics().app_package_name().string_value());
|
||||
EXPECT_EQ("test cdm version",
|
||||
actual.engine_metrics().cdm_engine_cdm_version().string_value());
|
||||
EXPECT_EQ(100,
|
||||
actual.engine_metrics()
|
||||
.cdm_engine_creation_time_millis().int_value());
|
||||
EXPECT_EQ(
|
||||
100,
|
||||
actual.engine_metrics().cdm_engine_creation_time_millis().int_value());
|
||||
}
|
||||
|
||||
TEST_F(EngineMetricsTest, EngineAndCryptoMetrics) {
|
||||
@@ -120,8 +116,8 @@ TEST_F(EngineMetricsTest, EngineAndCryptoMetrics) {
|
||||
CryptoMetrics* crypto_metrics = engine_metrics.GetCryptoMetrics();
|
||||
|
||||
crypto_metrics->crypto_session_get_device_unique_id_.Increment(NO_ERROR);
|
||||
crypto_metrics->crypto_session_generic_decrypt_
|
||||
.Record(2.0, NO_ERROR, Pow2Bucket(1025), kEncryptionAlgorithmAesCbc128);
|
||||
crypto_metrics->crypto_session_generic_decrypt_.Record(
|
||||
2.0, NO_ERROR, Pow2Bucket(1025), kEncryptionAlgorithmAesCbc128);
|
||||
|
||||
WvCdmMetrics actual_metrics;
|
||||
engine_metrics.Serialize(&actual_metrics);
|
||||
@@ -133,29 +129,38 @@ TEST_F(EngineMetricsTest, EngineAndCryptoMetrics) {
|
||||
ASSERT_EQ(1,
|
||||
actual_metrics.engine_metrics().cdm_engine_add_key_time_us_size());
|
||||
EXPECT_EQ(2, actual_metrics.engine_metrics()
|
||||
.cdm_engine_add_key_time_us(0)
|
||||
.attributes().error_code());
|
||||
ASSERT_EQ(1,
|
||||
actual_metrics.engine_metrics().cdm_engine_close_session_size());
|
||||
.cdm_engine_add_key_time_us(0)
|
||||
.attributes()
|
||||
.error_code());
|
||||
ASSERT_EQ(1, actual_metrics.engine_metrics().cdm_engine_close_session_size());
|
||||
EXPECT_EQ(UNKNOWN_ERROR, actual_metrics.engine_metrics()
|
||||
.cdm_engine_close_session(0)
|
||||
.attributes().error_code());
|
||||
ASSERT_EQ(1, actual_metrics.engine_metrics().crypto_metrics()
|
||||
.crypto_session_get_device_unique_id_size());
|
||||
EXPECT_EQ(1, actual_metrics.engine_metrics().crypto_metrics()
|
||||
.crypto_session_get_device_unique_id(0)
|
||||
.count());
|
||||
EXPECT_EQ(NO_ERROR, actual_metrics.engine_metrics().crypto_metrics()
|
||||
.crypto_session_get_device_unique_id(0)
|
||||
.attributes().error_code());
|
||||
ASSERT_EQ(1, actual_metrics.engine_metrics().crypto_metrics()
|
||||
.crypto_session_generic_decrypt_time_us_size());
|
||||
EXPECT_EQ(2.0, actual_metrics.engine_metrics().crypto_metrics()
|
||||
.crypto_session_generic_decrypt_time_us(0)
|
||||
.mean());
|
||||
EXPECT_EQ(NO_ERROR, actual_metrics.engine_metrics().crypto_metrics()
|
||||
.crypto_session_generic_decrypt_time_us(0)
|
||||
.attributes().error_code());
|
||||
.cdm_engine_close_session(0)
|
||||
.attributes()
|
||||
.error_code());
|
||||
ASSERT_EQ(1, actual_metrics.engine_metrics()
|
||||
.crypto_metrics()
|
||||
.crypto_session_get_device_unique_id_size());
|
||||
EXPECT_EQ(1, actual_metrics.engine_metrics()
|
||||
.crypto_metrics()
|
||||
.crypto_session_get_device_unique_id(0)
|
||||
.count());
|
||||
EXPECT_EQ(NO_ERROR, actual_metrics.engine_metrics()
|
||||
.crypto_metrics()
|
||||
.crypto_session_get_device_unique_id(0)
|
||||
.attributes()
|
||||
.error_code());
|
||||
ASSERT_EQ(1, actual_metrics.engine_metrics()
|
||||
.crypto_metrics()
|
||||
.crypto_session_generic_decrypt_time_us_size());
|
||||
EXPECT_EQ(2.0, actual_metrics.engine_metrics()
|
||||
.crypto_metrics()
|
||||
.crypto_session_generic_decrypt_time_us(0)
|
||||
.mean());
|
||||
EXPECT_EQ(NO_ERROR, actual_metrics.engine_metrics()
|
||||
.crypto_metrics()
|
||||
.crypto_session_generic_decrypt_time_us(0)
|
||||
.attributes()
|
||||
.error_code());
|
||||
}
|
||||
|
||||
TEST_F(EngineMetricsTest, EmptyEngineMetrics) {
|
||||
@@ -186,8 +191,8 @@ TEST_F(EngineMetricsTest, EngineMetricsWithSessions) {
|
||||
engine_metrics.AddSession();
|
||||
session_metrics_2->SetSessionId(kSessionId2);
|
||||
// Record a CryptoMetrics metric in the session.
|
||||
session_metrics_2->GetCryptoMetrics()->crypto_session_generic_decrypt_
|
||||
.Record(2.0, NO_ERROR, Pow2Bucket(1025), kEncryptionAlgorithmAesCbc128);
|
||||
session_metrics_2->GetCryptoMetrics()->crypto_session_generic_decrypt_.Record(
|
||||
2.0, NO_ERROR, Pow2Bucket(1025), kEncryptionAlgorithmAesCbc128);
|
||||
|
||||
WvCdmMetrics actual_metrics;
|
||||
engine_metrics.Serialize(&actual_metrics);
|
||||
@@ -201,7 +206,8 @@ TEST_F(EngineMetricsTest, EngineMetricsWithSessions) {
|
||||
actual_metrics.session_metrics(0).session_id().string_value());
|
||||
EXPECT_EQ(kSessionId2,
|
||||
actual_metrics.session_metrics(1).session_id().string_value());
|
||||
EXPECT_EQ(1, actual_metrics.session_metrics(1).crypto_metrics()
|
||||
EXPECT_EQ(1, actual_metrics.session_metrics(1)
|
||||
.crypto_metrics()
|
||||
.crypto_session_generic_decrypt_time_us_size());
|
||||
}
|
||||
|
||||
@@ -259,8 +265,7 @@ TEST_F(EngineMetricsTest, EngineMetricsConsolidateSessionsNoSessions) {
|
||||
ASSERT_EQ(0, actual_metrics.session_metrics_size());
|
||||
}
|
||||
|
||||
class SessionMetricsTest : public ::testing::Test {
|
||||
};
|
||||
class SessionMetricsTest : public ::testing::Test {};
|
||||
|
||||
TEST_F(SessionMetricsTest, AllSessionMetrics) {
|
||||
SessionMetrics session_metrics;
|
||||
@@ -275,12 +280,13 @@ TEST_F(SessionMetricsTest, AllSessionMetrics) {
|
||||
2.0, kKeyRequestTypeInitial);
|
||||
session_metrics.oemcrypto_build_info_.Record("test build info");
|
||||
session_metrics.license_sdk_version_.Record("test license sdk version");
|
||||
session_metrics.license_service_version_.Record("test license service version");
|
||||
session_metrics.license_service_version_.Record(
|
||||
"test license service version");
|
||||
session_metrics.drm_certificate_key_type_.Record(1);
|
||||
|
||||
// Record a CryptoMetrics metric in the session.
|
||||
session_metrics.GetCryptoMetrics()->crypto_session_generic_decrypt_
|
||||
.Record(2.0, NO_ERROR, Pow2Bucket(1025), kEncryptionAlgorithmAesCbc128);
|
||||
session_metrics.GetCryptoMetrics()->crypto_session_generic_decrypt_.Record(
|
||||
2.0, NO_ERROR, Pow2Bucket(1025), kEncryptionAlgorithmAesCbc128);
|
||||
|
||||
WvCdmMetrics::SessionMetrics actual;
|
||||
session_metrics.Serialize(&actual);
|
||||
@@ -315,32 +321,30 @@ TEST_F(SessionMetricsTest, EmptySessionMetrics) {
|
||||
EXPECT_EQ(0, actual_metrics.cdm_session_restore_usage_session_size());
|
||||
}
|
||||
|
||||
class CryptoMetricsTest : public ::testing::Test {
|
||||
};
|
||||
class CryptoMetricsTest : public ::testing::Test {};
|
||||
|
||||
TEST_F(CryptoMetricsTest, AllCryptoMetrics) {
|
||||
CryptoMetrics crypto_metrics;
|
||||
|
||||
// Crypto session metrics.
|
||||
crypto_metrics.crypto_session_delete_all_usage_reports_.Increment(NO_ERROR);
|
||||
crypto_metrics.crypto_session_delete_multiple_usage_information_
|
||||
.Increment(NO_ERROR);
|
||||
crypto_metrics.crypto_session_generic_decrypt_
|
||||
.Record(2.0, NO_ERROR, Pow2Bucket(1025), kEncryptionAlgorithmAesCbc128);
|
||||
crypto_metrics.crypto_session_generic_encrypt_
|
||||
.Record(2.0, NO_ERROR, Pow2Bucket(1025), kEncryptionAlgorithmAesCbc128);
|
||||
crypto_metrics.crypto_session_generic_sign_
|
||||
.Record(2.0, NO_ERROR, Pow2Bucket(1025), kSigningAlgorithmHmacSha256);
|
||||
crypto_metrics.crypto_session_generic_verify_
|
||||
.Record(2.0, NO_ERROR, Pow2Bucket(1025), kSigningAlgorithmHmacSha256);
|
||||
crypto_metrics.crypto_session_delete_multiple_usage_information_.Increment(
|
||||
NO_ERROR);
|
||||
crypto_metrics.crypto_session_generic_decrypt_.Record(
|
||||
2.0, NO_ERROR, Pow2Bucket(1025), kEncryptionAlgorithmAesCbc128);
|
||||
crypto_metrics.crypto_session_generic_encrypt_.Record(
|
||||
2.0, NO_ERROR, Pow2Bucket(1025), kEncryptionAlgorithmAesCbc128);
|
||||
crypto_metrics.crypto_session_generic_sign_.Record(
|
||||
2.0, NO_ERROR, Pow2Bucket(1025), kSigningAlgorithmHmacSha256);
|
||||
crypto_metrics.crypto_session_generic_verify_.Record(
|
||||
2.0, NO_ERROR, Pow2Bucket(1025), kSigningAlgorithmHmacSha256);
|
||||
crypto_metrics.crypto_session_get_device_unique_id_.Increment(NO_ERROR);
|
||||
crypto_metrics.crypto_session_get_token_.Increment(NO_ERROR);
|
||||
crypto_metrics.crypto_session_life_span_.Record(1.0);
|
||||
crypto_metrics.crypto_session_load_certificate_private_key_
|
||||
.Record(1.0, NO_ERROR);
|
||||
crypto_metrics.crypto_session_load_certificate_private_key_.Record(1.0,
|
||||
NO_ERROR);
|
||||
crypto_metrics.crypto_session_open_.Record(1.0, NO_ERROR, kLevelDefault);
|
||||
crypto_metrics.crypto_session_update_usage_information_
|
||||
.Record(1.0, NO_ERROR);
|
||||
crypto_metrics.crypto_session_update_usage_information_.Record(1.0, NO_ERROR);
|
||||
crypto_metrics.crypto_session_usage_information_support_.Record(true);
|
||||
crypto_metrics.crypto_session_security_level_.Record(kSecurityLevelL2);
|
||||
|
||||
@@ -359,87 +363,83 @@ TEST_F(CryptoMetricsTest, AllCryptoMetrics) {
|
||||
|
||||
// Oem crypto metrics.
|
||||
crypto_metrics.oemcrypto_api_version_.Record(123);
|
||||
crypto_metrics.oemcrypto_close_session_
|
||||
.Increment(OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_copy_buffer_
|
||||
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED, Pow2Bucket(1025));
|
||||
crypto_metrics.oemcrypto_deactivate_usage_entry_
|
||||
.Increment(OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_decrypt_cenc_
|
||||
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED, Pow2Bucket(1025));
|
||||
crypto_metrics.oemcrypto_delete_usage_entry_
|
||||
.Increment(OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_delete_usage_table_
|
||||
.Increment(OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_derive_keys_from_session_key_
|
||||
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_force_delete_usage_entry_
|
||||
.Increment(OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_generate_derived_keys_
|
||||
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_generate_nonce_
|
||||
.Increment(OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_generate_rsa_signature_
|
||||
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED, Pow2Bucket(1025));
|
||||
crypto_metrics.oemcrypto_generate_signature_
|
||||
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED, Pow2Bucket(1025));
|
||||
crypto_metrics.oemcrypto_generic_decrypt_
|
||||
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED, Pow2Bucket(1025));
|
||||
crypto_metrics.oemcrypto_generic_encrypt_
|
||||
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED, Pow2Bucket(1025));
|
||||
crypto_metrics.oemcrypto_generic_sign_
|
||||
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED, Pow2Bucket(1025));
|
||||
crypto_metrics.oemcrypto_generic_verify_
|
||||
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED, Pow2Bucket(1025));
|
||||
crypto_metrics.oemcrypto_get_device_id_
|
||||
.Increment(OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_get_key_data_
|
||||
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED, Pow2Bucket(1025));
|
||||
crypto_metrics.oemcrypto_close_session_.Increment(
|
||||
OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_copy_buffer_.Record(1.0, OEMCrypto_ERROR_INIT_FAILED,
|
||||
Pow2Bucket(1025));
|
||||
crypto_metrics.oemcrypto_deactivate_usage_entry_.Increment(
|
||||
OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_decrypt_cenc_.Record(
|
||||
1.0, OEMCrypto_ERROR_INIT_FAILED, Pow2Bucket(1025));
|
||||
crypto_metrics.oemcrypto_delete_usage_entry_.Increment(
|
||||
OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_delete_usage_table_.Increment(
|
||||
OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_derive_keys_from_session_key_.Record(
|
||||
1.0, OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_force_delete_usage_entry_.Increment(
|
||||
OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_generate_derived_keys_.Record(
|
||||
1.0, OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_generate_nonce_.Increment(
|
||||
OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_generate_rsa_signature_.Record(
|
||||
1.0, OEMCrypto_ERROR_INIT_FAILED, Pow2Bucket(1025));
|
||||
crypto_metrics.oemcrypto_generate_signature_.Record(
|
||||
1.0, OEMCrypto_ERROR_INIT_FAILED, Pow2Bucket(1025));
|
||||
crypto_metrics.oemcrypto_generic_decrypt_.Record(
|
||||
1.0, OEMCrypto_ERROR_INIT_FAILED, Pow2Bucket(1025));
|
||||
crypto_metrics.oemcrypto_generic_encrypt_.Record(
|
||||
1.0, OEMCrypto_ERROR_INIT_FAILED, Pow2Bucket(1025));
|
||||
crypto_metrics.oemcrypto_generic_sign_.Record(
|
||||
1.0, OEMCrypto_ERROR_INIT_FAILED, Pow2Bucket(1025));
|
||||
crypto_metrics.oemcrypto_generic_verify_.Record(
|
||||
1.0, OEMCrypto_ERROR_INIT_FAILED, Pow2Bucket(1025));
|
||||
crypto_metrics.oemcrypto_get_device_id_.Increment(
|
||||
OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_get_key_data_.Record(
|
||||
1.0, OEMCrypto_ERROR_INIT_FAILED, Pow2Bucket(1025));
|
||||
crypto_metrics.oemcrypto_max_number_of_sessions_.Record(7);
|
||||
crypto_metrics.oemcrypto_number_of_open_sessions_.Record(5);
|
||||
crypto_metrics.oemcrypto_get_oem_public_certificate_
|
||||
.Increment(OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_get_oem_public_certificate_.Increment(
|
||||
OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_provisioning_method_.Record(OEMCrypto_Keybox);
|
||||
crypto_metrics.oemcrypto_get_random_
|
||||
.Increment(OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_initialize_
|
||||
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_get_random_.Increment(OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_initialize_.Record(1.0, OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_is_anti_rollback_hw_present_.Record(true);
|
||||
crypto_metrics.oemcrypto_is_keybox_valid_.Record(true);
|
||||
crypto_metrics.oemcrypto_load_device_drm_key_.Record(
|
||||
1.0, OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_load_keys_.Record(1.0, OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_refresh_keys_
|
||||
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_refresh_keys_.Record(1.0,
|
||||
OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_report_usage_.Increment(OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_rewrap_device_rsa_key_
|
||||
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_rewrap_device_rsa_key_30_
|
||||
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_rewrap_device_rsa_key_.Record(
|
||||
1.0, OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_rewrap_device_rsa_key_30_.Record(
|
||||
1.0, OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_security_patch_level_.Record(123);
|
||||
crypto_metrics.oemcrypto_select_key_
|
||||
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_update_usage_table_
|
||||
.Increment(OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_create_usage_table_header_
|
||||
.Increment(OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_load_usage_table_header_
|
||||
.Increment(OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_shrink_usage_table_header_
|
||||
.Increment(OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_create_new_usage_entry_
|
||||
.Increment(OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_load_usage_entry_
|
||||
.Increment(OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_move_entry_
|
||||
.Increment(OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_create_old_usage_entry_
|
||||
.Increment(OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_copy_old_usage_entry_
|
||||
.Increment(OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_select_key_.Record(1.0, OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_update_usage_table_.Increment(
|
||||
OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_create_usage_table_header_.Increment(
|
||||
OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_load_usage_table_header_.Increment(
|
||||
OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_shrink_usage_table_header_.Increment(
|
||||
OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_create_new_usage_entry_.Increment(
|
||||
OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_load_usage_entry_.Increment(
|
||||
OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_move_entry_.Increment(OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_create_old_usage_entry_.Increment(
|
||||
OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_copy_old_usage_entry_.Increment(
|
||||
OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_set_sandbox_.Record("sandbox");
|
||||
crypto_metrics.oemcrypto_set_decrypt_hash_
|
||||
.Increment(OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_set_decrypt_hash_.Increment(
|
||||
OEMCrypto_ERROR_INIT_FAILED);
|
||||
crypto_metrics.oemcrypto_resource_rating_tier_.Record(123);
|
||||
crypto_metrics.oemcrypto_minor_api_version_.Record(234);
|
||||
crypto_metrics.oemcrypto_maximum_usage_table_header_size_.Record(321);
|
||||
@@ -535,6 +535,5 @@ TEST_F(CryptoMetricsTest, AllCryptoMetrics) {
|
||||
EXPECT_EQ(321,
|
||||
actual.oemcrypto_maximum_usage_table_header_size().int_value());
|
||||
}
|
||||
|
||||
} // namespace metrics
|
||||
} // namespace wvcdm
|
||||
|
||||
@@ -1,19 +1,17 @@
|
||||
// Copyright 2017 Google Inc. All Rights Reserved.
|
||||
// Copyright 2017 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine License
|
||||
// Agreement.
|
||||
//
|
||||
// Unit tests for ValueMetric.
|
||||
#include "value_metric.h"
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "value_metric.h"
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "wv_metrics.pb.h"
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
namespace wvcdm {
|
||||
namespace metrics {
|
||||
|
||||
TEST(ValueMetricTest, StringValue) {
|
||||
ValueMetric<std::string> metric;
|
||||
metric.Record("foo");
|
||||
@@ -59,6 +57,5 @@ TEST(ValueMetricTest, SetError) {
|
||||
ASSERT_EQ(7, metric_proto->error_code());
|
||||
ASSERT_FALSE(metric_proto->has_int_value());
|
||||
}
|
||||
|
||||
} // namespace metrics
|
||||
} // namespace wvcdm
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
# OEMCRYPTO Fuzzing
|
||||
|
||||
Refer to [Setting up Clusterfuzz](build_clusterfuzz.md) if you are interested
|
||||
in setting up a local instance of cluster fuzz to run fuzzing on your own
|
||||
OEMCrypto implementations on linux.
|
||||
|
||||
## Objective
|
||||
|
||||
* Run fuzzing on OEMCrypto public APIs on linux using google supported
|
||||
@@ -76,13 +80,31 @@
|
||||
$ export PATH_TO_CDM_DIR=..
|
||||
$ gyp --format=ninja --depth=$(pwd) oemcrypto/oemcrypto_unittests.gyp
|
||||
$ ninja -C out/Default/
|
||||
$ ./out/Default/oemcrypto_unittests --generate_corpus
|
||||
$ mkdir oemcrypto/test/fuzz_tests/corpus/<fuzzername>_seed_corpus
|
||||
# Generate corpus by excluding buffer overflow tests.
|
||||
$ ./out/Default/oemcrypto_unittests --generate_corpus \
|
||||
--gtest_filter=-"*Huge*"
|
||||
```
|
||||
|
||||
* To avoid uploading huge binary files to git repository, the corpus files
|
||||
will be saved in fuzzername_seed_corpus.zip format in blockbuster project's
|
||||
oemcrypto_fuzzing_corpus GCS bucket using gsutil. If you need permissions
|
||||
for blockbuster project, contact widevine-engprod@google.com.
|
||||
* There can be lot of duplicate corpus files that are generated from unit
|
||||
tests. We can minimize the corpus files to only a subset of files that
|
||||
cover unique paths within the API when run using fuzzer. Run following
|
||||
command to minimize corpus.
|
||||
|
||||
```shell
|
||||
$ cd /path/to/cdm/repo
|
||||
# build fuzzer binaries
|
||||
$ ./oemcrypto/test/fuzz_tests/build_oemcrypto_fuzztests
|
||||
$ mkdir /tmp/minimized_corpus
|
||||
# minimize corpus
|
||||
$ ./out/Default/<fuzz_target_binary> -merge=1 /tmp/minimized_corpus \
|
||||
<FULL_CORPUS_DIR>
|
||||
```
|
||||
|
||||
* To avoid uploading huge binary files to git repository, the minimized corpus
|
||||
files will be saved in fuzzername_seed_corpus.zip format in blockbuster
|
||||
project's oemcrypto_fuzzing_corpus GCS bucket using gsutil. If you need
|
||||
permissions for blockbuster project, contact widevine-engprod@google.com.
|
||||
|
||||
```shell
|
||||
$ gsutil cp gs://oemcrypto_fuzzing_corpus/<fuzzername_seed_corpus.zip> \
|
||||
@@ -106,7 +128,7 @@
|
||||
|
||||
* Build and test fuzz scripts locally using following commands. The build
|
||||
script builds fuzz binaries for both oemcrypto reference implementation
|
||||
as well as odkitee implementation.
|
||||
as well as opk implementation.
|
||||
|
||||
```shell
|
||||
$ cd PATH_TO_CDM_DIR
|
||||
|
||||
174
libwvdrmengine/oemcrypto/test/fuzz_tests/build_clusterfuzz.md
Normal file
174
libwvdrmengine/oemcrypto/test/fuzz_tests/build_clusterfuzz.md
Normal file
@@ -0,0 +1,174 @@
|
||||
# OEMCRYPTO Fuzzing - Build clustefuzz and run fuzzing
|
||||
|
||||
## Objective
|
||||
|
||||
* Run fuzzing on OEMCrypto public APIs on linux by building open sourced
|
||||
clusterfuzz source code in order to find security vulnerabilities.
|
||||
|
||||
[Clusterfuzz][1]
|
||||
|
||||
* Partners who implement OEMCrypto can follow these instructions to build
|
||||
clusterfuzz, the fuzzing framework and run fuzzing using fuzzer scripts
|
||||
provided by the Widevine team at Google.
|
||||
|
||||
## Glossary
|
||||
|
||||
* Fuzzing - Fuzzing is a methodology where random, interesting, unexpected
|
||||
inputs are fed to APIs in order to crash those, thereby catching any
|
||||
security vulnerabilities with the code.
|
||||
|
||||
* Fuzzing engines - [libfuzzer][4], afl, honggfuzz are the actual fuzzing
|
||||
engines that get the coverage information from API, use that to generate
|
||||
more interesting inputs which can be passed to fuzzer.
|
||||
|
||||
* Seed corpus - Fuzzing engine trying to generate interesting inputs from an
|
||||
empty file is not efficient. Seed corpus is the initial input that a fuzzer
|
||||
can accept and call the API with that. Fuzzing engine can then mutate this
|
||||
seed corpus to generate more inputs to fuzzer.
|
||||
|
||||
* Clusterfuzz - ClusterFuzz is a scalable fuzzing infrastructure that finds
|
||||
security and stability issues in software. Google uses ClusterFuzz to fuzz
|
||||
all Google products. Clusterfuzz provides us with the capability, tools to
|
||||
upload fuzz binaries and make use of the fuzzing engines to run fuzzing,
|
||||
find crashes and organizes the information. Clusterfuzz framework is open
|
||||
sourced, the source code can be downloaded and framework can be built
|
||||
locally or by using google cloud.
|
||||
|
||||
* Fuzzing output - Fuzzing is used to pass random inputs to API in order to
|
||||
ensure that API is crash resistant. We are not testing functionality via
|
||||
fuzzing. Fuzz scripts run continuously until they find a crash with the API
|
||||
under test.
|
||||
|
||||
## Building fuzz scripts
|
||||
|
||||
This section outlines the steps to build fuzz binaries that can be run
|
||||
continuously using clusterfuzz.
|
||||
|
||||
> **Note:** All the directories mentioned below are relative to cdm repository
|
||||
> root directory.
|
||||
|
||||
1. Fuzz scripts for OEMCrypto APIs are provided by the Widevine team at Google
|
||||
located under `oemcrypto/test/fuzz_tests` directory.
|
||||
|
||||
> **Note:** Prerequisites to run the following step are [here][10]. We also need
|
||||
> to install ninja.
|
||||
|
||||
2. Build a static library of your OEMCrypto implementation.
|
||||
* Compile and link your OEMCrypto implementation source with
|
||||
`-fsanitize=address,fuzzer` flag as per these [instructions][9] when
|
||||
building a static library.
|
||||
|
||||
* Run `./oemcrypto/test/fuzz_tests/build_partner_oemcrypto_fuzztests
|
||||
<oemcrypto_static_library_path>` script from cdm repository root
|
||||
directory.
|
||||
|
||||
* This will generate fuzz binaries under the `out/Default` directory.
|
||||
|
||||
|
||||
|
||||
> **Note:** Alternatively, you can use your own build systems, for which you
|
||||
> will need to define your own build files with the OEMCrypto fuzz source files
|
||||
> included. You can find the the fuzz source files in
|
||||
> `oemcrypto/test/fuzz_tests/partner_oemcrypto_fuzztests.gyp` and
|
||||
> `oemcrypto/test/fuzz_tests/partner_oemcrypto_fuzztests.gypi`.
|
||||
|
||||
3. Seed corpus for each fuzz script can be found under
|
||||
`oemcrypto/test/fuzz_tests/corpus` directory. Some fuzzers are simple and do
|
||||
not have seed corpus associated with them.
|
||||
|
||||
4. Create a zip file `oemcrypto_fuzzers_yyyymmddhhmmss.zip` with fuzz binaries
|
||||
and respective seed corpus zip files. Structure of a sample zip file with
|
||||
fuzzer binaries and seed corpus would look like following:
|
||||
|
||||
```
|
||||
* fuzzerA
|
||||
* fuzzerA_seed_corpus.zip
|
||||
* fuzzerB
|
||||
* fuzzerB_seed_corpus.zip
|
||||
* fuzzerC (fuzzerC doesn't have seed corpus associated with it)
|
||||
```
|
||||
|
||||
## Building clusterfuzz
|
||||
|
||||
* OEMCrypto implementation can be fuzzed by building clusterfuzz code which is
|
||||
open sourced and using it to run fuzzing. Use a Linux VM to build
|
||||
clusterfuzz.
|
||||
|
||||
> **Note:** You may see some issues with python modules missing, please install
|
||||
> those modules if you see errors. If you have multiple versions of python on
|
||||
> the VM, then use `python<version> -m pipenv shell` when you are at [this][3]
|
||||
> step.
|
||||
|
||||
* Follow these [instructions][2] in order to download clusterfuzz repository,
|
||||
build it locally or create a continuous fuzz infrastructure setup using
|
||||
google cloud.
|
||||
|
||||
## Running fuzzers on local clusterfuzz instance
|
||||
|
||||
* If you prefer to run fuzzing on a local machine instead of having a
|
||||
production setup using google cloud, then follow these [instructions][6] to
|
||||
add a job to the local clusterfuzz instance.
|
||||
|
||||
> **Note:** Job name should have a fuzzing engine and sanitizer as part of it. A
|
||||
> libfuzzer and asan jobs should have libfuzzer_asan in the job name.
|
||||
|
||||
* Create a job e:g:`libfuzzer_asan_oemcrypto` and upload previously created
|
||||
`oemcrypto_fuzzers_yyyymmddhhmmss.zip` as a custom build. Future uploads of
|
||||
zip file should have a name greater than current name. Following the above
|
||||
naming standard will ensure zip file names are always in ascending order.
|
||||
|
||||
* Once the job is added and clusterfuzz bot is running, fuzzing should be up
|
||||
and running. Results can be monitored as mentioned [here][6].
|
||||
|
||||
* On a local clusterfuzz instance, only one fuzzer is being fuzzed at a time.
|
||||
|
||||
> **Note:** Fuzzing is time consuming. Finding issues as well as clusterfuzz
|
||||
> regressing and fixing the issues can take time. We need fuzzing to run at
|
||||
> least for a couple of weeks to have good coverage.
|
||||
|
||||
## Finding fuzz crashes
|
||||
|
||||
Once the clusterfuzz finds an issue, it logs crash information such as the
|
||||
build, test case and stack trace for the crash.
|
||||
|
||||
* Test cases tab should show the fuzz crash and test case that caused the
|
||||
crash. Run `./fuzz_binary <test_case>` in order to debug the crash locally.
|
||||
|
||||
More information about different types of logs is as below:
|
||||
|
||||
* [Bot logs][7] will show information related to fuzzing, number of crashes
|
||||
that a particular fuzzer finds, number of new crashes, number of known
|
||||
crashes etc.
|
||||
|
||||
* [Local GCS][8] in your clusterfuzz checkout folder will store the fuzz
|
||||
binaries that are being fuzzed, seed corpus etc.
|
||||
|
||||
* `local_gcs/test-fuzz-logs-bucket` will store information related to fuzz
|
||||
crashes if any were found by the fuzzing engine. It will store crash
|
||||
information categorized by fuzzer and by each day. It will also store test
|
||||
case that caused the crash.
|
||||
|
||||
* `/path/to/my-bot/clusterfuzz/log.txt` will have any log information from
|
||||
fuzzer script and OEMCrypto implementation.
|
||||
|
||||
## Fixing issues
|
||||
|
||||
* Once you are able to debug using the crash test case, apply fix to the
|
||||
implementation, create `oemcrypto_fuzzers_yyyymmddhhmmss.zip` with latest
|
||||
fuzz binaries.
|
||||
|
||||
* Upload the latest fuzz binary to the fuzz job that was created earlier.
|
||||
Fuzzer will recognize the fix and mark the crash as fixed in test cases tab
|
||||
once the regression finishes. You do not need to update crashes as fixed,
|
||||
clusterfuzz will do that.
|
||||
|
||||
[1]: https://google.github.io/clusterfuzz/
|
||||
[2]: https://google.github.io/clusterfuzz/getting-started/
|
||||
[3]: https://google.github.io/clusterfuzz/getting-started/prerequisites/#loading-pipenv
|
||||
[4]: https://llvm.org/docs/LibFuzzer.html
|
||||
[5]: https://google.github.io/clusterfuzz/setting-up-fuzzing/libfuzzer-and-afl/
|
||||
[6]: https://google.github.io/clusterfuzz/setting-up-fuzzing/libfuzzer-and-afl/#checking-results
|
||||
[7]: https://google.github.io/clusterfuzz/getting-started/local-instance/#viewing-logs
|
||||
[8]: https://google.github.io/clusterfuzz/getting-started/local-instance/#local-google-cloud-storage
|
||||
[9]: https://google.github.io/clusterfuzz/setting-up-fuzzing/libfuzzer-and-afl/#libfuzzer
|
||||
[10]: https://google.github.io/clusterfuzz/setting-up-fuzzing/libfuzzer-and-afl/#prerequisites
|
||||
@@ -10,10 +10,10 @@ export PYTHONPATH="$PYTHONPATH:$PATH_TO_CDM_DIR/third_party"
|
||||
python3 $PATH_TO_CDM_DIR/third_party/gyp/__init__.py --format=ninja \
|
||||
--depth=$(pwd) oemcrypto/test/fuzz_tests/oemcrypto_fuzztests.gyp
|
||||
ninja -C out/Default
|
||||
# oemcrypto_odkitee_fuzztests.gypi has flags to instrument all the gyp targets
|
||||
# oemcrypto_opk_fuzztests.gypi has flags to instrument all the gyp targets
|
||||
# with fuzzer flags.
|
||||
python3 $PATH_TO_CDM_DIR/third_party/gyp/__init__.py --format=ninja \
|
||||
--depth=$(pwd) \
|
||||
--include=oemcrypto/test/fuzz_tests/oemcrypto_odkitee_fuzztests.gypi \
|
||||
oemcrypto/test/fuzz_tests/oemcrypto_odkitee_fuzztests.gyp
|
||||
--include=oemcrypto/test/fuzz_tests/oemcrypto_opk_fuzztests.gypi \
|
||||
oemcrypto/test/fuzz_tests/oemcrypto_opk_fuzztests.gyp
|
||||
ninja -C out/Default
|
||||
15
libwvdrmengine/oemcrypto/test/fuzz_tests/build_partner_oemcrypto_fuzztests
Executable file
15
libwvdrmengine/oemcrypto/test/fuzz_tests/build_partner_oemcrypto_fuzztests
Executable file
@@ -0,0 +1,15 @@
|
||||
#!/bin/bash
|
||||
set -ex
|
||||
|
||||
# For use by partners to generate fuzz binaries for their OEMCrypto
|
||||
# implementation on linux.
|
||||
|
||||
export CXX=clang++
|
||||
export CC=clang
|
||||
export GYP_DEFINES="$GYP_DEFINES clang=1 oemcrypto_static_library=$1"
|
||||
export PATH_TO_CDM_DIR=.
|
||||
export PYTHONPATH="$PYTHONPATH:$PATH_TO_CDM_DIR/third_party"
|
||||
|
||||
python3 $PATH_TO_CDM_DIR/third_party/gyp/__init__.py --format=ninja \
|
||||
--depth=$(pwd) oemcrypto/test/fuzz_tests/partner_oemcrypto_fuzztests.gyp
|
||||
ninja -C out/Default
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user