Added metrics history for WV CDM for Android.

[ Merge of http://go/wvgerrit/171271 ]

There is a need to maintain a short history of metrics from CDMs which
have been deleted.  This CL adds this ability to the Android version
of the WV CDM.  The history cannot yet be maintained for long, as the
WV CDM instance is destroyed if unused.

Further changes are required to the plugin to maintain the history
beyond the life-cycle of the CDM instance, and to properly format
its output.

Bug: 239462891
Bug: 270166158
Test: adb shell dumpsys android.hardware.drm.IDrmFactory/widevine -m
Test: atest GtsMediaTestCases
Change-Id: I81c0996602722a9795fc3951030d20bb39b5816b
This commit is contained in:
Alex Dale
2023-04-18 20:15:16 -07:00
parent 5ce29c42da
commit c42627a23e
7 changed files with 259 additions and 80 deletions

View File

@@ -9,8 +9,10 @@
#include "WVDrmFactory.h"
#include <cctype>
#include <algorithm>
#include <cctype>
#include <cinttypes>
#include <cstdio>
#include <android/binder_ibinder_platform.h>
#include <binder/IPCThreadState.h>
@@ -23,6 +25,7 @@
#include "WVUUID.h"
#include "android-base/properties.h"
#include "cutils/properties.h"
#include "string_conversions.h"
#include "wv_cdm_constants.h"
#include "wv_content_decryption_module.h"
#include "wv_metrics.h"
@@ -59,21 +62,44 @@ void FormatIndent(int fd, size_t indent) {
if (real_indent < indent) FormatIndent(fd, indent - real_indent);
}
void FormatWvCdmIdentifier(int fd, size_t parent_indent,
const wvcdm::CdmIdentifier& identifier) {
const size_t indent = parent_indent + 2;
// Spoid.
FormatIndent(fd, indent);
dprintf(fd, "spoid: \"%s\"\n", wvutil::b2a_hex(identifier.spoid).c_str());
// Origin.
FormatIndent(fd, indent);
dprintf(fd, "origin: \"%s\"\n", wvutil::b2a_hex(identifier.origin).c_str());
// App package name.
FormatIndent(fd, indent);
dprintf(fd, "app_package_name: \"%s\"\n",
identifier.app_package_name.c_str());
// Unique ID.
FormatIndent(fd, indent);
dprintf(fd, "unique_id: %" PRIu32 "\n", identifier.unique_id);
}
void FormatWvMetricsSnapshotItem(int fd, size_t parent_indent,
drm_metrics::WvCdmMetrics& metrics,
const wvcdm::WvMetricsSnapshot& snapshot,
size_t item_index) {
const size_t indent = parent_indent + 2;
// TODO(b/239462891): Provide identifier and timestamp for metrics.
// Serialized proto size.
// CDM identifier.
FormatIndent(fd, parent_indent); // First parameter uses indent + list tick.
dprintf(fd, "- serialized_proto_bytes: %zu # [%zu]\n",
metrics.ByteSizeLong(), item_index);
dprintf(fd, "- identifier: # [%zu]\n", item_index);
FormatWvCdmIdentifier(fd, indent, snapshot.cdm_id());
// Timestamp.
FormatIndent(fd, indent);
dprintf(fd, "timestamp: \"%s\"\n", snapshot.GetFormattedTimestamp().c_str());
// Serialized proto size.
FormatIndent(fd, indent);
dprintf(fd, "serialized_proto_bytes: %zu\n",
snapshot.metrics().ByteSizeLong());
// Engine metrics.
FormatIndent(fd, indent);
dprintf(fd, "cdm_metrics:\n");
std::stringstream ss;
wv_metrics::FormatWvCdmMetrics(metrics, indent, ss);
wv_metrics::FormatWvCdmMetrics(snapshot.metrics(), indent, ss);
PrintStream(fd, ss);
}
} // namespace
@@ -213,15 +239,15 @@ void WVDrmFactory::printCdmMetrics(int fd) {
android::sp<wvcdm::WvContentDecryptionModule> cdm(getCDM());
vector<drm_metrics::WvCdmMetrics> metrics;
bool full_list_returned = true;
std::vector<wvcdm::WvMetricsSnapshot> snapshots;
bool full_list_returned = false;
wvcdm::CdmResponseType result =
cdm->GetMetrics(&metrics, &full_list_returned);
cdm->GetAllCurrentMetricsSnapshots(&snapshots, &full_list_returned);
if (result != wvcdm::NO_ERROR) {
dprintf(fd, " live_metrics:\n");
dprintf(fd, " error_message: \"%s\"\n", result.ToString().c_str());
dprintf(fd, " error_code: %d\n", static_cast<int>(result.code()));
} else if (metrics.empty()) {
} else if (snapshots.empty()) {
// YAML does not support empty property values.
const char kNoMetricsMessage[] =
"Metrics not available, please retry while streaming a video.";
@@ -229,15 +255,15 @@ void WVDrmFactory::printCdmMetrics(int fd) {
} else {
dprintf(fd, " live_metrics: ");
if (full_list_returned) {
dprintf(fd, "# count = %zu\n", metrics.size());
dprintf(fd, "# count = %zu\n", snapshots.size());
} else {
const char kPartialListMessage[] =
"Some metrics are missing due to an internal error, "
"check logs for details.";
dprintf(fd, "# count = %zu, %s\n", metrics.size(), kPartialListMessage);
dprintf(fd, "# count = %zu, %s\n", snapshots.size(), kPartialListMessage);
}
for (size_t i = 0; i < metrics.size(); i++) {
FormatWvMetricsSnapshotItem(fd, 2, metrics[i], i);
for (size_t i = 0; i < snapshots.size(); i++) {
FormatWvMetricsSnapshotItem(fd, 2, snapshots[i], i);
}
}
// TODO(b/270166158): Print metrics history.