Files
android/libwvdrmengine/tools/metrics_dump/src/metrics_dump.cpp
Edwin Wong d5d0652d4f Build metrics_dump tool in Android.
Replace Makefile with Android.bp.
Remove duplication of protos in proto directory.

Since we are now building the metrics_dump tool
under Android, use frameworks metrics.proto
directly. Also, reference cdm's wv_metrics.proto
from the cdm directory instead of creating a
subset in proto directory.

bug: 161783052
bug: 170607430

Test: build
  m -j128 metrics_dump
Test: metrics_dump [bugreport from adt-3-r.zip]
Test: metrics_dump [bugreport from sabrina-q.gz]
Test: metrics_dump --widevine [adb shell dumpsys media.metrics output]
Change-Id: I82c7e723453ac2a6335cb2bb732a376d535b9ea3
2020-11-03 10:19:32 -08:00

197 lines
6.0 KiB
C++

// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
// source code may only be used and distributed under the Widevine License
// Agreement.
//
// Format metric output from |adb shell dumpsys media.metrics|
#include <fstream>
#include <iostream>
#include <sstream>
#include <string>
#include "base64decode.h"
#include "mediadrm_metrics.h"
#include "parse_metrics.h"
#include "wv_metrics.h"
namespace metrics_dump {
using namespace base64;
using namespace wv_metrics;
using std::cerr;
using std::cout;
using std::endl;
using std::string;
using std::vector;
string selected_one;
std::vector<string> excluded_ones;
// Look for metrics pattern
// q-metrics:
// [:item:item:]
// r-metrics:
// {item, (item), (item)}
//
// @return true if metrics is formatted prior to R release
bool is_q_metrics(const string &line) {
int left_brackets = std::count(line.begin(), line.end(), '[');
int right_brackets = std::count(line.begin(), line.end(), ']');
return (left_brackets == 1 && right_brackets == 1 &&
line.find('(') == string::npos && line.find(')') == string::npos);
}
// Process one line of metrics
void process_one_metric(const string &line) {
std::istringstream fields(line);
MediaMetrics metrics;
parse_metrics(line, &metrics);
// handle specific package and component selection
if (selected_one.size() && metrics.package != selected_one &&
metrics.component != selected_one) {
return;
}
if (std::find(excluded_ones.begin(), excluded_ones.end(), metrics.package) !=
excluded_ones.end()) {
return;
}
if (std::find(excluded_ones.begin(), excluded_ones.end(),
metrics.component) != excluded_ones.end()) {
return;
}
cout << "===================================================================="
"============="
<< endl;
if (is_q_metrics(line)) {
char timebuf[128];
time_t time_s = stoll(metrics.timestamp) / 1000000000LL;
strftime(timebuf, sizeof(timebuf), "%a %b %e %H:%M:%S", localtime(&time_s));
cout << timebuf << " timestamp: " << time_s << endl << endl;
} else {
cout << metrics.timestamp << endl << endl;
}
cout << " "
<< "APK PACKAGE -> METRICS COMPONENT" << endl;
cout << " " << metrics.package << " -> " << metrics.component << endl;
cout << "\tuid:" << metrics.uid << " pid:" << metrics.pid << endl;
for (auto property : metrics.properties) {
string key = property.first;
string value = property.second;
if (key == "serialized_metrics") {
string decoded = Base64::Decode(value);
if (metrics.component == "drm.vendor.google.widevinecdm") {
drm_metrics::WvCdmMetrics wv_metrics;
if (!wv_metrics.ParseFromString(decoded)) {
cerr << "failed to parse proto string" << endl;
} else {
string result;
FormatWvCdmMetrics(wv_metrics, result);
cout << endl << result << endl;
}
} else {
android::drm_metrics::DrmFrameworkMetrics fw_metrics;
if (!fw_metrics.ParseFromString(decoded)) {
cerr << "failed to parse proto string" << endl;
} else {
string result;
mediadrm_metrics::FormatDrmFrameworkMetrics(fw_metrics, result);
cout << endl << result << endl;
}
}
} else {
cout << " " << key << ": " << value << endl;
}
}
}
void process_metrics(std::istream &instream) {
string line;
while (std::getline(instream, line)) {
if (line.find("serialized_metrics") != string::npos) {
process_one_metric(line);
}
}
}
} // namespace metrics_dump
using std::cerr;
using std::endl;
using std::string;
void usage() {
cerr << "usage: metrics_dump [options] [<bugreport>]" << endl;
cerr << endl;
cerr << "Displays the drm metrics that are generated by" << endl;
cerr << "adb shell dumpsys media.metrics. Input may be from a file" << endl;
cerr << "such as a bugreport, or from stdin." << endl;
cerr << endl;
cerr << "options:" << endl;
cerr << " --no-gms" << endl;
cerr << " ignore metrics from package com.google.android.gms" << endl;
cerr << " which are generated frequently by droidguard" << endl;
cerr << " --widevine" << endl;
cerr << " show only widevine metrics, "
"component=drm.vendor.Google.WidevineCDM"
<< endl;
cerr << " --mediadrm" << endl;
cerr << " show only framework drm metrics, component=mediadrm" << endl;
cerr << " --exclude <package>|<component>" << endl;
cerr << " ignore metrics from the specified package or component"
<< endl;
cerr << " --select <package>|<component>" << endl;
cerr << " only show metrics from the specified package or component"
<< endl;
exit(-1);
}
int main(int argc, char **argv) {
// 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;
int i = 1;
while (i < argc) {
string arg = argv[i];
if (arg == "--help") {
usage();
} else if (arg == "--no-gms") {
metrics_dump::excluded_ones.push_back("com.google.android.gms");
} else if (arg == "--widevine") {
metrics_dump::selected_one = "drm.vendor.google.widevinecdm";
} else if (arg == "--mediadrm") {
metrics_dump::selected_one = "mediadrm";
} else if (i == argc - 1) {
std::ifstream bugfile(argv[i]);
if (bugfile.is_open()) {
metrics_dump::process_metrics(bugfile);
bugfile.close();
} else {
cerr << "unable to open input file " << argv[i] << endl;
}
break;
} else {
// args with a parameter
if (arg == "--exclude") {
string lowercase_argv = argv[++i];
metrics_dump::to_lower(lowercase_argv);
metrics_dump::excluded_ones.push_back(lowercase_argv);
} else if (arg == "--select") {
metrics_dump::selected_one = argv[++i];
metrics_dump::to_lower(metrics_dump::selected_one);
} else {
usage();
}
}
i++;
}
if (i == argc) {
metrics_dump::process_metrics(std::cin);
}
return 0;
}