Add arguments to Widevine lshal debug hook.
Add options to dump Widevine Cdm properties, Widevine Cdm metrics, or both. The valid arguments are Cdm Metrics (m|M) or Cdm Properties (p|P). If no arguments are provided, both Cdm properties and Cdm metrics will be displayed. Test: adb shell lshal debug [drm service] [m/p] adb shell lshal debug android.hardware.drm@1.3::IDrmFactory/widevine Bug: 154027349 Change-Id: I95c10dd7d4274226936295c73be4eb1612c2ef6a
This commit is contained in:
@@ -202,6 +202,7 @@ include $(CLEAR_VARS)
|
|||||||
LOCAL_SRC_FILES := \
|
LOCAL_SRC_FILES := \
|
||||||
src/WVCDMSingleton.cpp \
|
src/WVCDMSingleton.cpp \
|
||||||
src/WVUUID.cpp \
|
src/WVUUID.cpp \
|
||||||
|
src_hidl/wv_metrics.cpp \
|
||||||
src_hidl/WVCreatePluginFactories.cpp \
|
src_hidl/WVCreatePluginFactories.cpp \
|
||||||
src_hidl/WVCryptoFactory.cpp \
|
src_hidl/WVCryptoFactory.cpp \
|
||||||
src_hidl/WVDrmFactory.cpp \
|
src_hidl/WVDrmFactory.cpp \
|
||||||
|
|||||||
@@ -149,6 +149,13 @@ class WvContentDecryptionModule : public android::RefBase, public TimerHandler {
|
|||||||
virtual CdmResponseType GetMetrics(const CdmIdentifier& identifier,
|
virtual CdmResponseType GetMetrics(const CdmIdentifier& identifier,
|
||||||
drm_metrics::WvCdmMetrics* metrics);
|
drm_metrics::WvCdmMetrics* metrics);
|
||||||
|
|
||||||
|
// Fill the metrics parameter with the metrics data for all the CdmEngine
|
||||||
|
// associated with the given CdmIdentifiers. If there are no CdmEngine
|
||||||
|
// instances, this will return an error.
|
||||||
|
virtual CdmResponseType GetMetrics(
|
||||||
|
std::vector<drm_metrics::WvCdmMetrics>* metrics,
|
||||||
|
bool* full_list_returned);
|
||||||
|
|
||||||
// Closes the CdmEngine and sessions associated with the given CdmIdentifier.
|
// Closes the CdmEngine and sessions associated with the given CdmIdentifier.
|
||||||
virtual CdmResponseType CloseCdm(const CdmIdentifier& identifier);
|
virtual CdmResponseType CloseCdm(const CdmIdentifier& identifier);
|
||||||
|
|
||||||
|
|||||||
@@ -378,6 +378,32 @@ bool WvContentDecryptionModule::IsValidServiceCertificate(
|
|||||||
return cert.has_certificate();
|
return cert.has_certificate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CdmResponseType WvContentDecryptionModule::GetMetrics(
|
||||||
|
std::vector<drm_metrics::WvCdmMetrics>* metrics, bool* full_list_returned) {
|
||||||
|
if (!metrics || !full_list_returned) {
|
||||||
|
return PARAMETER_NULL;
|
||||||
|
}
|
||||||
|
for (auto& key_value_pair : cdms_) {
|
||||||
|
drm_metrics::WvCdmMetrics metric;
|
||||||
|
CdmResponseType status = GetMetrics(key_value_pair.first, &metric);
|
||||||
|
if (status == NO_ERROR) {
|
||||||
|
metrics->push_back(metric);
|
||||||
|
} else {
|
||||||
|
LOGD("GetMetrics call failed: cdm identifier=%u, error=%d",
|
||||||
|
key_value_pair.first.unique_id, status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// With no streaming activities, cdms_ size would be zero,
|
||||||
|
// treat it as a non full list in that case.
|
||||||
|
*full_list_returned = !cdms_.empty() && metrics->size() == cdms_.size();
|
||||||
|
|
||||||
|
// We only return error if no metrics is returned when cdms_ is not empty.
|
||||||
|
// - metrics && cdms_ sizes can both be zero, returns NO_ERROR
|
||||||
|
// - metrics size <= cdms_, returns NO_ERROR
|
||||||
|
// - metrics is empty, but cdms_ is not, returns UNKNOWN_ERROR
|
||||||
|
return (metrics->empty() && !cdms_.empty()) ? UNKNOWN_ERROR : NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
CdmResponseType WvContentDecryptionModule::GetMetrics(
|
CdmResponseType WvContentDecryptionModule::GetMetrics(
|
||||||
const CdmIdentifier& identifier, drm_metrics::WvCdmMetrics* metrics) {
|
const CdmIdentifier& identifier, drm_metrics::WvCdmMetrics* metrics) {
|
||||||
if (!metrics) {
|
if (!metrics) {
|
||||||
|
|||||||
@@ -24,19 +24,16 @@ struct WVDrmFactory : public IDrmFactory {
|
|||||||
WVDrmFactory() {}
|
WVDrmFactory() {}
|
||||||
virtual ~WVDrmFactory() {}
|
virtual ~WVDrmFactory() {}
|
||||||
|
|
||||||
Return<bool> isCryptoSchemeSupported(const hidl_array<uint8_t, 16>& uuid)
|
Return<bool> isCryptoSchemeSupported(
|
||||||
override;
|
const hidl_array<uint8_t, 16>& uuid) override;
|
||||||
|
|
||||||
Return<bool> isCryptoSchemeSupported_1_2(const hidl_array<uint8_t, 16>& uuid,
|
Return<bool> isCryptoSchemeSupported_1_2(const hidl_array<uint8_t, 16>& uuid,
|
||||||
const hidl_string& mimeType,
|
const hidl_string& mimeType,
|
||||||
SecurityLevel level)
|
SecurityLevel level) override;
|
||||||
override;
|
|
||||||
|
|
||||||
Return<bool> isContentTypeSupported(const hidl_string &mimeType)
|
Return<bool> isContentTypeSupported(const hidl_string& mimeType) override;
|
||||||
override;
|
|
||||||
|
|
||||||
Return<void> createPlugin(
|
Return<void> createPlugin(const hidl_array<uint8_t, 16>& uuid,
|
||||||
const hidl_array<uint8_t, 16>& uuid,
|
|
||||||
const hidl_string& appPackageName,
|
const hidl_string& appPackageName,
|
||||||
createPlugin_cb _hidl_cb) override;
|
createPlugin_cb _hidl_cb) override;
|
||||||
|
|
||||||
@@ -54,6 +51,7 @@ struct WVDrmFactory : public IDrmFactory {
|
|||||||
static bool isBlankAppPackageNameAllowed();
|
static bool isBlankAppPackageNameAllowed();
|
||||||
static int32_t firstApiLevel();
|
static int32_t firstApiLevel();
|
||||||
static std::string stringToHex(const std::string& input);
|
static std::string stringToHex(const std::string& input);
|
||||||
|
static void printCdmMetrics(FILE* out);
|
||||||
static void printCdmProperties(FILE* out);
|
static void printCdmProperties(FILE* out);
|
||||||
|
|
||||||
friend class WVDrmFactoryTestPeer;
|
friend class WVDrmFactoryTestPeer;
|
||||||
|
|||||||
14
libwvdrmengine/include_hidl/wv_metrics.h
Normal file
14
libwvdrmengine/include_hidl/wv_metrics.h
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
// Copyright 2020 Google LLC. All Rights Reserved. This file and proprietary
|
||||||
|
// source code may only be used and distributed under the Widevine Master
|
||||||
|
// License Agreement.
|
||||||
|
//
|
||||||
|
// Format widevine protobuf metrics
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "metrics.pb.h"
|
||||||
|
|
||||||
|
namespace wv_metrics {
|
||||||
|
void FormatWvCdmMetrics(const drm_metrics::WvCdmMetrics& metrics,
|
||||||
|
std::string& result);
|
||||||
|
}
|
||||||
@@ -19,6 +19,7 @@
|
|||||||
#include "cutils/properties.h"
|
#include "cutils/properties.h"
|
||||||
#include "wv_cdm_constants.h"
|
#include "wv_cdm_constants.h"
|
||||||
#include "wv_content_decryption_module.h"
|
#include "wv_content_decryption_module.h"
|
||||||
|
#include "wv_metrics.h"
|
||||||
|
|
||||||
namespace wvdrm {
|
namespace wvdrm {
|
||||||
namespace hardware {
|
namespace hardware {
|
||||||
@@ -148,6 +149,39 @@ std::string WVDrmFactory::stringToHex(const std::string& input) {
|
|||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WVDrmFactory::printCdmMetrics(FILE* out) {
|
||||||
|
fprintf(out, "\n**** Widevine Cdm Metrics ****\n");
|
||||||
|
|
||||||
|
// Verify that the version of the library that we linked against is
|
||||||
|
// compatible with the version of the headers we compiled against.
|
||||||
|
GOOGLE_PROTOBUF_VERIFY_VERSION;
|
||||||
|
|
||||||
|
sp<wvcdm::WvContentDecryptionModule> cdm(getCDM());
|
||||||
|
|
||||||
|
std::vector<drm_metrics::WvCdmMetrics> metrics;
|
||||||
|
bool full_list_returned = true;
|
||||||
|
wvcdm::CdmResponseType result =
|
||||||
|
cdm->GetMetrics(&metrics, &full_list_returned);
|
||||||
|
if (metrics.empty()) {
|
||||||
|
fprintf(out,
|
||||||
|
"Metrics not available, please retry while streaming a video\n");
|
||||||
|
} else if (!full_list_returned) {
|
||||||
|
fprintf(out,
|
||||||
|
"Not all metrics are returned due to some GetMetric error, "
|
||||||
|
"please check logcat for possible GetMetric errors.\n");
|
||||||
|
}
|
||||||
|
if (result == wvcdm::NO_ERROR) {
|
||||||
|
for (auto& metric : metrics) {
|
||||||
|
fprintf(out, "*** Metric size=%zu\n", metric.DebugString().size());
|
||||||
|
std::string formatted;
|
||||||
|
wv_metrics::FormatWvCdmMetrics(metric, formatted);
|
||||||
|
fprintf(out, "%s\n", formatted.c_str());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fprintf(out, "GetMetrics failed, error=%d\n", result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void WVDrmFactory::printCdmProperties(FILE* out) {
|
void WVDrmFactory::printCdmProperties(FILE* out) {
|
||||||
fprintf(out, "\n**** Widevine CDM properties ****\n");
|
fprintf(out, "\n**** Widevine CDM properties ****\n");
|
||||||
|
|
||||||
@@ -155,7 +189,7 @@ void WVDrmFactory::printCdmProperties(FILE* out) {
|
|||||||
|
|
||||||
const bool isLevel1 =
|
const bool isLevel1 =
|
||||||
cdm->IsSecurityLevelSupported(wvcdm::CdmSecurityLevel::kSecurityLevelL1);
|
cdm->IsSecurityLevelSupported(wvcdm::CdmSecurityLevel::kSecurityLevelL1);
|
||||||
fprintf(out, "current security level: [%s]\n", isLevel1 ? "L1" : "L3");
|
fprintf(out, "default security level: [%s]\n", isLevel1 ? "L1" : "L3");
|
||||||
|
|
||||||
std::map<std::string, std::string> cdmProperties = {
|
std::map<std::string, std::string> cdmProperties = {
|
||||||
{"version- Widevine CDM:", wvcdm::QUERY_KEY_WVCDM_VERSION},
|
{"version- Widevine CDM:", wvcdm::QUERY_KEY_WVCDM_VERSION},
|
||||||
@@ -165,7 +199,7 @@ void WVDrmFactory::printCdmProperties(FILE* out) {
|
|||||||
{"version(minor)- OEM Crypto API:",
|
{"version(minor)- OEM Crypto API:",
|
||||||
wvcdm::QUERY_KEY_OEMCRYPTO_API_MINOR_VERSION},
|
wvcdm::QUERY_KEY_OEMCRYPTO_API_MINOR_VERSION},
|
||||||
{"id- device:", wvcdm::QUERY_KEY_DEVICE_ID},
|
{"id- device:", wvcdm::QUERY_KEY_DEVICE_ID},
|
||||||
{"id- systen:", wvcdm::QUERY_KEY_SYSTEM_ID},
|
{"id- system:", wvcdm::QUERY_KEY_SYSTEM_ID},
|
||||||
{"renewal server url:", wvcdm::QUERY_KEY_RENEWAL_SERVER_URL},
|
{"renewal server url:", wvcdm::QUERY_KEY_RENEWAL_SERVER_URL},
|
||||||
{"hdcp level- max:", wvcdm::QUERY_KEY_MAX_HDCP_LEVEL},
|
{"hdcp level- max:", wvcdm::QUERY_KEY_MAX_HDCP_LEVEL},
|
||||||
{"hdcp level- current:", wvcdm::QUERY_KEY_CURRENT_HDCP_LEVEL},
|
{"hdcp level- current:", wvcdm::QUERY_KEY_CURRENT_HDCP_LEVEL},
|
||||||
@@ -192,14 +226,40 @@ void WVDrmFactory::printCdmProperties(FILE* out) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Return<void> WVDrmFactory::debug(const hidl_handle& fd,
|
Return<void> WVDrmFactory::debug(const hidl_handle& fd,
|
||||||
const hidl_vec<hidl_string>& /*args*/) {
|
const hidl_vec<hidl_string>& args) {
|
||||||
if (fd.getNativeHandle() == nullptr || fd->numFds < 1) {
|
if (fd.getNativeHandle() == nullptr || fd->numFds < 1) {
|
||||||
ALOGE("%s: missing fd for writing", __FUNCTION__);
|
ALOGE("%s: missing fd for writing", __FUNCTION__);
|
||||||
return Void();
|
return Void();
|
||||||
}
|
}
|
||||||
|
|
||||||
FILE* out = fdopen(dup(fd->data[0]), "w");
|
FILE* out = fdopen(dup(fd->data[0]), "w");
|
||||||
printCdmProperties(out);
|
fprintf(out, "\nDefault to print all info if no arguments are used.\n");
|
||||||
|
fprintf(out, "Optional arguments are:\n");
|
||||||
|
fprintf(out, "\tm:cdm metrics | p:cdm properties\n");
|
||||||
|
fprintf(out,
|
||||||
|
"Usage: adb shell lshal debug "
|
||||||
|
"android.hardware.drm@1.3::IDrmFactory/widevine [m|p]\n");
|
||||||
|
|
||||||
|
bool dumpCdmProperties, dumpCdmMetrics = false;
|
||||||
|
if (args.size() == 0) {
|
||||||
|
// default to print all info if no arguments are given
|
||||||
|
dumpCdmProperties = dumpCdmMetrics = true;
|
||||||
|
} else {
|
||||||
|
for (auto& str : args) {
|
||||||
|
fprintf(out, "args: %s\n", str.c_str());
|
||||||
|
std::string option = str.c_str();
|
||||||
|
if (option.find('m') != std::string::npos ||
|
||||||
|
option.find('M') != std::string::npos) {
|
||||||
|
dumpCdmMetrics = true;
|
||||||
|
}
|
||||||
|
if (option.find('p') != std::string::npos ||
|
||||||
|
option.find('P') != std::string::npos) {
|
||||||
|
dumpCdmProperties = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (dumpCdmMetrics) printCdmMetrics(out);
|
||||||
|
if (dumpCdmProperties) printCdmProperties(out);
|
||||||
fclose(out);
|
fclose(out);
|
||||||
|
|
||||||
return Void();
|
return Void();
|
||||||
|
|||||||
448
libwvdrmengine/src_hidl/wv_metrics.cpp
Normal file
448
libwvdrmengine/src_hidl/wv_metrics.cpp
Normal file
@@ -0,0 +1,448 @@
|
|||||||
|
// Copyright 2020 Google LLC. All Rights Reserved. This file and proprietary
|
||||||
|
// source code may only be used and distributed under the Widevine Master
|
||||||
|
// License Agreement.
|
||||||
|
//
|
||||||
|
// Format widevine protobuf metrics
|
||||||
|
|
||||||
|
#include "wv_metrics.h"
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
|
#include <memory>
|
||||||
|
#include <sstream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "OEMCryptoCENC.h"
|
||||||
|
#include "wv_cdm_types.h"
|
||||||
|
|
||||||
|
using namespace drm_metrics;
|
||||||
|
using std::string;
|
||||||
|
using std::to_string;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
const string kIndentPerLine = " ";
|
||||||
|
|
||||||
|
string FormatCdmErrorTranslation(int error_code) {
|
||||||
|
std::stringstream os;
|
||||||
|
os << static_cast<wvcdm::CdmResponseType>(error_code);
|
||||||
|
return " " + os.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
string FormatOEMCryptoResult(int oemcrypto_result) {
|
||||||
|
std::stringstream os;
|
||||||
|
os << static_cast<OEMCryptoResult>(oemcrypto_result);
|
||||||
|
return " " + os.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
string FormatOEMCryptoInitializeMode(const ValueMetric& vm) {
|
||||||
|
std::map<int, string> translations = {
|
||||||
|
{0, "USING_IN_APP"},
|
||||||
|
{1, "FORCING_L3"},
|
||||||
|
{2, "USING_L3_NO_L1_LIBRARY_PATH"},
|
||||||
|
{3, "USING_L3_L1_OPEN_FAILED"},
|
||||||
|
{4, "USING_L3_L1_LOAD_FAILED"},
|
||||||
|
{5, "USING_L3_COULD_NOT_INITIALIZE_L1"},
|
||||||
|
{6, "USING_L3_WRONG_L1_VERSION"},
|
||||||
|
{7, "USING_L1_WITH_KEYBOX"},
|
||||||
|
{8, "USING_L1_WITH_CERTIFICATE"},
|
||||||
|
{9, "USING_L1_CERTIFICATE_MIX"},
|
||||||
|
{10, "USING_L3_BAD_KEYBOX"},
|
||||||
|
{11, "USING_L3_COULD_NOT_OPEN_FACTORY_KEYBOX"},
|
||||||
|
{12, "USING_L3_COULD_NOT_INSTALL_KEYBOX"},
|
||||||
|
{13, "USING_L1_INSTALLED_KEYBOX"},
|
||||||
|
{14, "USING_L3_INVALID_L1"},
|
||||||
|
{15, "USING_L1_WITH_PROVISIONING_3_0"},
|
||||||
|
{16, "L3_INITIALIZATION_GENERAL_FAILED"},
|
||||||
|
{17, "L3_INITIALIZATION_RNG_FAILED"},
|
||||||
|
{18, "L3_INITIALIZATION_SAVE_DEVICE_KEYS_FAILED"},
|
||||||
|
{19, "L3_INITIALIZATION_READ_DEVICE_KEYS_FAILED"},
|
||||||
|
{20, "L3_INITIALIZATION_VERIFY_DEVIE_KEYS_FAILED"}};
|
||||||
|
return translations[vm.int_value()];
|
||||||
|
}
|
||||||
|
|
||||||
|
string FormatOEMCryptoHdcpCapability(const ValueMetric& vm) {
|
||||||
|
std::map<int, string> translations = {
|
||||||
|
{0, "HDCP_NONE"}, {1, "HDCP_V1"}, {2, "HDCP_V2"},
|
||||||
|
{3, "HDCP_V2_1"}, {4, "HDCP_V2_2"}, {5, "HDCP_V2_3"},
|
||||||
|
{0xff, "NO_DIGITAL_OUTPUT"}};
|
||||||
|
return translations[vm.int_value()];
|
||||||
|
}
|
||||||
|
|
||||||
|
string FormatOEMCryptoProvisioningMethod(const ValueMetric& vm) {
|
||||||
|
std::map<int, string> translations = {{0, "PROVISIONING_ERROR"},
|
||||||
|
{1, "DRM_CERTIFICATE"},
|
||||||
|
{2, "KEYBOX"},
|
||||||
|
{3, "OEM_CERTIFICATE"}};
|
||||||
|
return translations[vm.int_value()];
|
||||||
|
}
|
||||||
|
|
||||||
|
string FormatAttributes(const Attributes& attributes) {
|
||||||
|
string result;
|
||||||
|
if (attributes.has_error_code()) {
|
||||||
|
result.append("error_code:");
|
||||||
|
result.append(to_string(attributes.error_code()));
|
||||||
|
result.append(FormatCdmErrorTranslation(attributes.error_code()));
|
||||||
|
}
|
||||||
|
if (attributes.has_error_code_bool()) {
|
||||||
|
if (result.size()) result.append(",");
|
||||||
|
result.append("success:");
|
||||||
|
result.append(attributes.error_code_bool() ? "true" : "false");
|
||||||
|
}
|
||||||
|
if (attributes.has_cdm_security_level()) {
|
||||||
|
if (result.size()) result.append(",");
|
||||||
|
result.append("cdm_security_level:");
|
||||||
|
result.append(to_string(attributes.cdm_security_level()));
|
||||||
|
}
|
||||||
|
if (attributes.has_security_level()) {
|
||||||
|
if (result.size()) result.append(",");
|
||||||
|
result.append("security_level:");
|
||||||
|
result.append(to_string(attributes.security_level()));
|
||||||
|
}
|
||||||
|
if (attributes.has_length()) {
|
||||||
|
if (result.size()) result.append(",");
|
||||||
|
result.append("length:");
|
||||||
|
result.append(to_string(attributes.length()));
|
||||||
|
}
|
||||||
|
if (attributes.has_encryption_algorithm()) {
|
||||||
|
if (result.size()) result.append(",");
|
||||||
|
result.append("encryption_algorithm:");
|
||||||
|
result.append(to_string(attributes.encryption_algorithm()));
|
||||||
|
}
|
||||||
|
if (attributes.has_signing_algorithm()) {
|
||||||
|
if (result.size()) result.append(",");
|
||||||
|
result.append("signing_algorithm:");
|
||||||
|
result.append(to_string(attributes.signing_algorithm()));
|
||||||
|
}
|
||||||
|
if (attributes.has_oem_crypto_result()) {
|
||||||
|
if (result.size()) result.append(",");
|
||||||
|
result.append("oemcrypto_result:");
|
||||||
|
result.append(to_string(attributes.oem_crypto_result()));
|
||||||
|
result.append(FormatOEMCryptoResult(attributes.oem_crypto_result()));
|
||||||
|
}
|
||||||
|
if (attributes.has_key_status_type()) {
|
||||||
|
if (result.size()) result.append(",");
|
||||||
|
result.append("key_status_type:");
|
||||||
|
result.append(to_string(attributes.key_status_type()));
|
||||||
|
}
|
||||||
|
if (attributes.has_event_type()) {
|
||||||
|
if (result.size()) result.append(",");
|
||||||
|
result.append("event_type:");
|
||||||
|
result.append(to_string(attributes.event_type()));
|
||||||
|
}
|
||||||
|
if (attributes.has_key_request_type()) {
|
||||||
|
if (result.size()) result.append(",");
|
||||||
|
result.append("key_request_type:");
|
||||||
|
result.append(to_string(attributes.key_request_type()));
|
||||||
|
}
|
||||||
|
if (attributes.has_license_type()) {
|
||||||
|
if (result.size()) result.append(",");
|
||||||
|
result.append("license_type:");
|
||||||
|
result.append(to_string(attributes.license_type()));
|
||||||
|
}
|
||||||
|
if (result.size()) {
|
||||||
|
return string(" {") + result + "}";
|
||||||
|
} else {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
string FormatCounterMetric(const CounterMetric& cm) {
|
||||||
|
string result;
|
||||||
|
if (cm.has_count()) {
|
||||||
|
result = string("count=") + to_string(cm.count());
|
||||||
|
if (cm.has_attributes()) {
|
||||||
|
result.append(FormatAttributes(cm.attributes()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
string FormatDistributionMetric(const DistributionMetric& dm) {
|
||||||
|
string result;
|
||||||
|
if (dm.has_min()) {
|
||||||
|
std::ostringstream buffer;
|
||||||
|
buffer << dm.min();
|
||||||
|
result = string("min=") + buffer.str();
|
||||||
|
}
|
||||||
|
if (dm.has_max()) {
|
||||||
|
std::ostringstream buffer;
|
||||||
|
buffer << dm.max();
|
||||||
|
if (result.size()) result.append(" ");
|
||||||
|
result += string("max=") + buffer.str();
|
||||||
|
}
|
||||||
|
if (dm.has_mean()) {
|
||||||
|
std::ostringstream buffer;
|
||||||
|
buffer << dm.mean();
|
||||||
|
if (result.size()) result.append(" ");
|
||||||
|
result += string("mean=") + buffer.str();
|
||||||
|
}
|
||||||
|
if (dm.has_variance()) {
|
||||||
|
std::ostringstream buffer;
|
||||||
|
buffer << dm.variance();
|
||||||
|
if (result.size()) result.append(" ");
|
||||||
|
result += string("variance=") + buffer.str();
|
||||||
|
}
|
||||||
|
if (dm.has_operation_count()) {
|
||||||
|
if (result.size()) result.append(" ");
|
||||||
|
result += string("count=") + to_string(dm.operation_count());
|
||||||
|
}
|
||||||
|
if (dm.has_attributes()) {
|
||||||
|
result.append(FormatAttributes(dm.attributes()));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
string FormatValueMetric(const ValueMetric& vm) {
|
||||||
|
string result;
|
||||||
|
if (vm.has_error_code()) {
|
||||||
|
result.append("error(" + to_string(vm.error_code()));
|
||||||
|
result.append(FormatCdmErrorTranslation(vm.error_code()));
|
||||||
|
result.append(")");
|
||||||
|
}
|
||||||
|
if (vm.has_int_value()) {
|
||||||
|
result.append(to_string(vm.int_value()));
|
||||||
|
}
|
||||||
|
if (vm.has_double_value()) {
|
||||||
|
std::ostringstream buffer;
|
||||||
|
buffer << vm.double_value();
|
||||||
|
result.append(buffer.str());
|
||||||
|
}
|
||||||
|
if (vm.has_string_value()) {
|
||||||
|
result.append("\"");
|
||||||
|
result.append(vm.string_value());
|
||||||
|
result.append("\"");
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define FORMAT_REPEATED_DISTRIBUTION(NAME, INDENT) \
|
||||||
|
if (metrics.NAME##_size() == 1) { \
|
||||||
|
result.append(INDENT + #NAME + ": "); \
|
||||||
|
result.append(FormatDistributionMetric(metrics.NAME(0)) + "\n"); \
|
||||||
|
} else { \
|
||||||
|
for (int i = 0; i < metrics.NAME##_size(); i++) { \
|
||||||
|
result.append(INDENT + #NAME "[" + to_string(i) + "]: "); \
|
||||||
|
result.append(FormatDistributionMetric(metrics.NAME(i)) + "\n"); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define FORMAT_REPEATED_COUNTER(NAME, INDENT) \
|
||||||
|
if (metrics.NAME##_size() == 1) { \
|
||||||
|
result.append(INDENT + #NAME ": "); \
|
||||||
|
result.append(FormatCounterMetric(metrics.NAME(0)) + "\n"); \
|
||||||
|
} else { \
|
||||||
|
for (int i = 0; i < metrics.NAME##_size(); i++) { \
|
||||||
|
result.append(INDENT + #NAME "[" + to_string(i) + "]: "); \
|
||||||
|
result.append(FormatCounterMetric(metrics.NAME(i)) + "\n"); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define FORMAT_OPTIONAL_VALUE(NAME, INDENT) \
|
||||||
|
if (metrics.has_##NAME()) { \
|
||||||
|
result.append(INDENT + #NAME ": " + FormatValueMetric(metrics.NAME()) + \
|
||||||
|
"\n"); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define FORMAT_OPTIONAL_INITIALIZATION_MODE(NAME, INDENT) \
|
||||||
|
if (metrics.has_##NAME()) { \
|
||||||
|
result.append(INDENT + #NAME ": "); \
|
||||||
|
result.append(FormatOEMCryptoInitializeMode(metrics.NAME()) + "\n"); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define FORMAT_OPTIONAL_HDCP_CAPABILITY(NAME, INDENT) \
|
||||||
|
if (metrics.has_##NAME()) { \
|
||||||
|
result.append(INDENT + #NAME ": "); \
|
||||||
|
result.append(FormatOEMCryptoHdcpCapability(metrics.NAME()) + "\n"); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define FORMAT_OPTIONAL_PROVISIONING_METHOD(NAME, INDENT) \
|
||||||
|
if (metrics.has_##NAME()) { \
|
||||||
|
result.append(INDENT + #NAME ": "); \
|
||||||
|
result.append(FormatOEMCryptoProvisioningMethod(metrics.NAME()) + "\n"); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define FORMAT_OPTIONAL_CRYPTO_METRICS(NAME, INDENT) \
|
||||||
|
if (metrics.has_##NAME()) { \
|
||||||
|
FormatCryptoMetrics(metrics.NAME(), INDENT + kIndentPerLine, result); \
|
||||||
|
}
|
||||||
|
|
||||||
|
void FormatCryptoMetrics(const WvCdmMetrics_CryptoMetrics metrics,
|
||||||
|
const string& indent, string& result) {
|
||||||
|
// Crypto Session Metrics.
|
||||||
|
FORMAT_OPTIONAL_VALUE(crypto_session_security_level, indent);
|
||||||
|
FORMAT_REPEATED_COUNTER(crypto_session_delete_all_usage_reports, indent);
|
||||||
|
FORMAT_REPEATED_COUNTER(crypto_session_delete_multiple_usage_information,
|
||||||
|
indent);
|
||||||
|
FORMAT_REPEATED_DISTRIBUTION(crypto_session_generic_decrypt_time_us, indent);
|
||||||
|
FORMAT_REPEATED_DISTRIBUTION(crypto_session_generic_encrypt_time_us, indent);
|
||||||
|
FORMAT_REPEATED_DISTRIBUTION(crypto_session_generic_sign_time_us, indent);
|
||||||
|
FORMAT_REPEATED_DISTRIBUTION(crypto_session_generic_verify_time_us, indent);
|
||||||
|
FORMAT_REPEATED_COUNTER(crypto_session_get_device_unique_id, indent);
|
||||||
|
FORMAT_REPEATED_COUNTER(crypto_session_get_token, indent);
|
||||||
|
FORMAT_OPTIONAL_VALUE(crypto_session_life_span, indent);
|
||||||
|
FORMAT_REPEATED_DISTRIBUTION(
|
||||||
|
crypto_session_load_certificate_private_key_time_us, indent);
|
||||||
|
FORMAT_REPEATED_DISTRIBUTION(crypto_session_open_time_us, indent);
|
||||||
|
FORMAT_OPTIONAL_VALUE(crypto_session_system_id, indent);
|
||||||
|
FORMAT_REPEATED_DISTRIBUTION(crypto_session_update_usage_information_time_us,
|
||||||
|
indent);
|
||||||
|
FORMAT_OPTIONAL_VALUE(crypto_session_usage_information_support, indent);
|
||||||
|
|
||||||
|
// Usage Table Metrics
|
||||||
|
FORMAT_OPTIONAL_VALUE(usage_table_header_initial_size, indent);
|
||||||
|
FORMAT_REPEATED_COUNTER(usage_table_header_add_entry, indent);
|
||||||
|
FORMAT_REPEATED_COUNTER(usage_table_header_delete_entry, indent);
|
||||||
|
FORMAT_REPEATED_DISTRIBUTION(usage_table_header_update_entry_time_us, indent);
|
||||||
|
FORMAT_REPEATED_COUNTER(usage_table_header_load_entry, indent);
|
||||||
|
|
||||||
|
// Usage Table LRU Metrics
|
||||||
|
FORMAT_OPTIONAL_VALUE(usage_table_header_lru_usage_info_count, indent);
|
||||||
|
FORMAT_OPTIONAL_VALUE(usage_table_header_lru_offline_license_count, indent);
|
||||||
|
FORMAT_OPTIONAL_VALUE(usage_table_header_lru_evicted_entry_staleness_s,
|
||||||
|
indent);
|
||||||
|
|
||||||
|
// |usage_table_header_lru_evicted_entry_type| refers to the enumeration
|
||||||
|
// CdmUsageEntryStorageType in wv_cdm_types.h.
|
||||||
|
FORMAT_OPTIONAL_VALUE(usage_table_header_lru_evicted_entry_type, indent);
|
||||||
|
|
||||||
|
// OemCrypto metrics.
|
||||||
|
FORMAT_OPTIONAL_VALUE(oemcrypto_api_version, indent);
|
||||||
|
FORMAT_REPEATED_COUNTER(oemcrypto_close_session, indent);
|
||||||
|
FORMAT_REPEATED_DISTRIBUTION(oemcrypto_copy_buffer_time_us, indent);
|
||||||
|
FORMAT_OPTIONAL_HDCP_CAPABILITY(oemcrypto_current_hdcp_capability, indent);
|
||||||
|
FORMAT_REPEATED_COUNTER(oemcrypto_deactivate_usage_entry, indent);
|
||||||
|
FORMAT_REPEATED_DISTRIBUTION(oemcrypto_decrypt_cenc_time_us, indent);
|
||||||
|
FORMAT_REPEATED_COUNTER(oemcrypto_delete_usage_entry, indent);
|
||||||
|
FORMAT_REPEATED_COUNTER(oemcrypto_delete_usage_table, indent);
|
||||||
|
FORMAT_REPEATED_DISTRIBUTION(oemcrypto_derive_keys_from_session_key_time_us,
|
||||||
|
indent);
|
||||||
|
FORMAT_REPEATED_COUNTER(oemcrypto_force_delete_usage_entry, indent);
|
||||||
|
FORMAT_REPEATED_DISTRIBUTION(oemcrypto_generate_derived_keys_time_us, indent);
|
||||||
|
FORMAT_REPEATED_COUNTER(oemcrypto_generate_nonce, indent);
|
||||||
|
FORMAT_REPEATED_DISTRIBUTION(oemcrypto_generate_rsa_signature_time_us,
|
||||||
|
indent);
|
||||||
|
FORMAT_REPEATED_DISTRIBUTION(oemcrypto_generate_signature_time_us, indent);
|
||||||
|
FORMAT_REPEATED_DISTRIBUTION(oemcrypto_generic_decrypt_time_us, indent);
|
||||||
|
FORMAT_REPEATED_DISTRIBUTION(oemcrypto_generic_encrypt_time_us, indent);
|
||||||
|
FORMAT_REPEATED_DISTRIBUTION(oemcrypto_generic_sign_time_us, indent);
|
||||||
|
FORMAT_REPEATED_DISTRIBUTION(oemcrypto_generic_verify_time_us, indent);
|
||||||
|
FORMAT_REPEATED_COUNTER(oemcrypto_get_device_id, indent);
|
||||||
|
FORMAT_REPEATED_DISTRIBUTION(oemcrypto_get_key_data_time_us, indent);
|
||||||
|
FORMAT_REPEATED_COUNTER(oemcrypto_get_oem_public_certificate, indent);
|
||||||
|
FORMAT_REPEATED_COUNTER(oemcrypto_get_random, indent);
|
||||||
|
FORMAT_REPEATED_DISTRIBUTION(oemcrypto_initialize_time_us, indent);
|
||||||
|
FORMAT_OPTIONAL_VALUE(oemcrypto_is_anti_rollback_hw_present, indent);
|
||||||
|
FORMAT_OPTIONAL_VALUE(oemcrypto_is_keybox_valid, indent);
|
||||||
|
FORMAT_REPEATED_DISTRIBUTION(oemcrypto_load_device_rsa_key_time_us, indent);
|
||||||
|
FORMAT_REPEATED_DISTRIBUTION(oemcrypto_load_entitled_keys_time_us, indent);
|
||||||
|
FORMAT_REPEATED_DISTRIBUTION(oemcrypto_load_keys_time_us, indent);
|
||||||
|
FORMAT_OPTIONAL_HDCP_CAPABILITY(oemcrypto_max_hdcp_capability, indent);
|
||||||
|
FORMAT_OPTIONAL_VALUE(oemcrypto_max_number_of_sessions, indent);
|
||||||
|
FORMAT_OPTIONAL_VALUE(oemcrypto_number_of_open_sessions, indent);
|
||||||
|
FORMAT_OPTIONAL_PROVISIONING_METHOD(oemcrypto_provisioning_method, indent);
|
||||||
|
FORMAT_REPEATED_DISTRIBUTION(oemcrypto_refresh_keys_time_us, indent);
|
||||||
|
FORMAT_REPEATED_COUNTER(oemcrypto_report_usage, indent);
|
||||||
|
FORMAT_REPEATED_DISTRIBUTION(oemcrypto_rewrap_device_rsa_key_time_us, indent);
|
||||||
|
FORMAT_REPEATED_DISTRIBUTION(oemcrypto_rewrap_device_rsa_key_30_time_us,
|
||||||
|
indent);
|
||||||
|
FORMAT_OPTIONAL_VALUE(oemcrypto_security_patch_level, indent);
|
||||||
|
FORMAT_REPEATED_DISTRIBUTION(oemcrypto_select_key_time_us, indent);
|
||||||
|
FORMAT_OPTIONAL_VALUE(oemcrypto_usage_table_support, indent);
|
||||||
|
FORMAT_REPEATED_COUNTER(oemcrypto_update_usage_table, indent);
|
||||||
|
FORMAT_REPEATED_COUNTER(oemcrypto_update_usage_entry, indent);
|
||||||
|
FORMAT_REPEATED_COUNTER(oemcrypto_create_usage_table_header, indent);
|
||||||
|
FORMAT_REPEATED_COUNTER(oemcrypto_load_usage_table_header, indent);
|
||||||
|
FORMAT_REPEATED_COUNTER(oemcrypto_shrink_usage_table_header, indent);
|
||||||
|
FORMAT_REPEATED_COUNTER(oemcrypto_create_new_usage_entry, indent);
|
||||||
|
FORMAT_REPEATED_COUNTER(oemcrypto_load_usage_entry, indent);
|
||||||
|
FORMAT_REPEATED_COUNTER(oemcrypto_move_entry, indent);
|
||||||
|
FORMAT_REPEATED_COUNTER(oemcrypto_create_old_usage_entry, indent);
|
||||||
|
FORMAT_REPEATED_COUNTER(oemcrypto_copy_old_usage_entry, indent);
|
||||||
|
FORMAT_OPTIONAL_VALUE(oemcrypto_set_sandbox, indent);
|
||||||
|
FORMAT_REPEATED_COUNTER(oemcrypto_set_decrypt_hash, indent);
|
||||||
|
FORMAT_OPTIONAL_VALUE(oemcrypto_resource_rating_tier, indent);
|
||||||
|
|
||||||
|
// Oemcrypto V16 metrics below
|
||||||
|
FORMAT_REPEATED_DISTRIBUTION(oemcrypto_prep_and_sign_license_request_time_us,
|
||||||
|
indent);
|
||||||
|
FORMAT_REPEATED_DISTRIBUTION(oemcrypto_prep_and_sign_renewal_request_time_us,
|
||||||
|
indent);
|
||||||
|
FORMAT_REPEATED_DISTRIBUTION(
|
||||||
|
oemcrypto_prep_and_sign_provisioning_request_time_us, indent);
|
||||||
|
FORMAT_REPEATED_DISTRIBUTION(oemcrypto_load_license_time_us, indent);
|
||||||
|
FORMAT_REPEATED_DISTRIBUTION(oemcrypto_load_renewal_time_us, indent);
|
||||||
|
FORMAT_REPEATED_DISTRIBUTION(oemcrypto_load_provisioning_time_us, indent);
|
||||||
|
FORMAT_OPTIONAL_VALUE(oemcrypto_minor_api_version, indent);
|
||||||
|
FORMAT_OPTIONAL_VALUE(oemcrypto_maximum_usage_table_header_size, indent);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FormatSessionMetrics(const WvCdmMetrics_SessionMetrics& metrics,
|
||||||
|
const string& indent, string& result) {
|
||||||
|
FORMAT_OPTIONAL_VALUE(session_id, indent);
|
||||||
|
FORMAT_OPTIONAL_CRYPTO_METRICS(crypto_metrics, indent);
|
||||||
|
FORMAT_OPTIONAL_VALUE(cdm_session_life_span_ms, indent);
|
||||||
|
FORMAT_REPEATED_DISTRIBUTION(cdm_session_renew_key_time_us, indent);
|
||||||
|
FORMAT_REPEATED_COUNTER(cdm_session_restore_offline_session, indent);
|
||||||
|
FORMAT_REPEATED_COUNTER(cdm_session_restore_usage_session, indent);
|
||||||
|
FORMAT_REPEATED_DISTRIBUTION(cdm_session_license_request_latency_ms, indent);
|
||||||
|
FORMAT_OPTIONAL_VALUE(oemcrypto_build_info, indent);
|
||||||
|
FORMAT_OPTIONAL_VALUE(license_sdk_version, indent);
|
||||||
|
FORMAT_OPTIONAL_VALUE(license_service_version, indent);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FormatEngineMetrics(const WvCdmMetrics_EngineMetrics& metrics,
|
||||||
|
const string& indent, string& result) {
|
||||||
|
FORMAT_OPTIONAL_CRYPTO_METRICS(crypto_metrics, indent);
|
||||||
|
|
||||||
|
// OEMCrypto Initialize Metrics.
|
||||||
|
FORMAT_OPTIONAL_INITIALIZATION_MODE(oemcrypto_initialization_mode, indent);
|
||||||
|
FORMAT_OPTIONAL_VALUE(oemcrypto_l1_api_version, indent);
|
||||||
|
FORMAT_OPTIONAL_VALUE(oemcrypto_l1_min_api_version, indent);
|
||||||
|
FORMAT_OPTIONAL_VALUE(level3_oemcrypto_initialization_error, indent);
|
||||||
|
FORMAT_OPTIONAL_VALUE(previous_oemcrypto_initialization_failure, indent);
|
||||||
|
|
||||||
|
// CdmEngine Metrics.
|
||||||
|
FORMAT_OPTIONAL_VALUE(app_package_name, indent);
|
||||||
|
FORMAT_REPEATED_DISTRIBUTION(cdm_engine_add_key_time_us, indent);
|
||||||
|
FORMAT_OPTIONAL_VALUE(cdm_engine_cdm_version, indent);
|
||||||
|
FORMAT_REPEATED_COUNTER(cdm_engine_close_session, indent);
|
||||||
|
FORMAT_OPTIONAL_VALUE(cdm_engine_creation_time_millis, indent);
|
||||||
|
FORMAT_REPEATED_DISTRIBUTION(cdm_engine_decrypt_time_us, indent);
|
||||||
|
FORMAT_REPEATED_COUNTER(cdm_engine_find_session_for_key, indent);
|
||||||
|
FORMAT_REPEATED_DISTRIBUTION(cdm_engine_generate_key_request_time_us, indent);
|
||||||
|
FORMAT_REPEATED_DISTRIBUTION(cdm_engine_get_provisioning_request_time_us,
|
||||||
|
indent);
|
||||||
|
FORMAT_REPEATED_COUNTER(cdm_engine_get_secure_stop_ids, indent);
|
||||||
|
FORMAT_REPEATED_DISTRIBUTION(cdm_engine_get_usage_info_time_us, indent);
|
||||||
|
FORMAT_REPEATED_DISTRIBUTION(cdm_engine_handle_provisioning_response_time_us,
|
||||||
|
indent);
|
||||||
|
FORMAT_OPTIONAL_VALUE(cdm_engine_life_span_ms, indent);
|
||||||
|
FORMAT_REPEATED_COUNTER(cdm_engine_open_key_set_session, indent);
|
||||||
|
FORMAT_REPEATED_COUNTER(cdm_engine_open_session, indent);
|
||||||
|
FORMAT_REPEATED_DISTRIBUTION(cdm_engine_query_key_status_time_us, indent);
|
||||||
|
FORMAT_REPEATED_COUNTER(cdm_engine_release_all_usage_info, indent);
|
||||||
|
FORMAT_REPEATED_COUNTER(cdm_engine_release_usage_info, indent);
|
||||||
|
FORMAT_REPEATED_COUNTER(cdm_engine_remove_all_usage_info, indent);
|
||||||
|
FORMAT_REPEATED_COUNTER(cdm_engine_remove_keys, indent);
|
||||||
|
FORMAT_REPEATED_COUNTER(cdm_engine_remove_usage_info, indent);
|
||||||
|
FORMAT_REPEATED_DISTRIBUTION(cdm_engine_restore_key_time_us, indent);
|
||||||
|
FORMAT_REPEATED_COUNTER(cdm_engine_unprovision, indent);
|
||||||
|
}
|
||||||
|
} // anonymous namespace
|
||||||
|
|
||||||
|
namespace wv_metrics {
|
||||||
|
void FormatWvCdmMetrics(const WvCdmMetrics& metrics, string& result) {
|
||||||
|
string indent = kIndentPerLine;
|
||||||
|
string next_indent = indent + kIndentPerLine;
|
||||||
|
|
||||||
|
result.append("engine_metrics\n");
|
||||||
|
if (metrics.has_engine_metrics()) {
|
||||||
|
FormatEngineMetrics(metrics.engine_metrics(), indent, result);
|
||||||
|
}
|
||||||
|
result.append("session_metrics\n");
|
||||||
|
for (int i = 0; i < metrics.session_metrics_size(); i++) {
|
||||||
|
result.append(indent + "session[" + to_string(i) + "]\n");
|
||||||
|
FormatSessionMetrics(metrics.session_metrics(i), next_indent, result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // namespace wv_metrics
|
||||||
Reference in New Issue
Block a user