Files
android/libwvdrmengine/tools/metrics_dump/src/parse_metrics.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

118 lines
3.7 KiB
C++

// Copyright 2020 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 "parse_metrics.h"
#include <algorithm>
#include <map>
#include <regex>
#include <string>
#include <utility>
#include <vector>
namespace metrics_dump {
using std::string;
using std::vector;
void to_lower(string& lower) {
std::transform(lower.begin(), lower.end(), lower.begin(), ::tolower);
}
void parse_metrics(const string& line, MediaMetrics* metrics) {
string regex_delimiters;
bool is_r_metrics = is_q_metrics(line) == false;
int properties_index = 0;
if (is_r_metrics) {
// Format of mediadrm metrics (R and forward):
// index: {key, (timestamp), (package, pid, uid), (properties, ...)}
// properties in this format: (key=value, key=value, ...)
// key(component) and packagename may contain '.'
// timestamp contains ':' (month-day h:m:s.n)
// Note: we want to preserve spaces within a metric field
regex_delimiters = "[^()|,|^{}]+";
properties_index = kPropertiesR;
} else {
// Format of mediadrm metrics before R release:
// index: [version:component:session:uid:package:package_version:
// pid:finalized:timestamp:item_count:properties:]
// properties in this format: :key=value:key=value:...:
regex_delimiters = "[^:|^[\\]|\\s]+";
properties_index = kPropertiesQ;
}
std::regex delimiters(regex_delimiters);
auto tokens_begin =
std::sregex_iterator(line.begin(), line.end(), delimiters);
auto tokens_end = std::sregex_iterator();
vector<string> tokens;
vector<string> properties;
int count = 0;
for (std::sregex_iterator itr = tokens_begin; itr != tokens_end; ++itr) {
std::smatch match = *itr;
string token = match.str();
// timestamp contains space, so we do not want to filter
// all spaces; here we filter out token that contains just spaces
if (token.find_first_not_of(' ') != string::npos) {
if (count < properties_index) {
tokens.push_back(token);
count++;
} else {
// trim leading spaces in token
size_t first_non_space = token.find_first_not_of(' ');
string trimmed_token = token.substr(first_non_space);
properties.push_back(trimmed_token);
}
}
}
string component, package;
if (is_r_metrics) {
component = tokens[kComponentR];
package = tokens[kPackageR];
to_lower(component);
to_lower(package);
metrics->component = component;
metrics->package = package;
metrics->pid = tokens[kPidR];
metrics->timestamp = tokens[kTimestampR];
metrics->uid = tokens[kUidR];
// the following fields are not used by the tool
metrics->index = tokens[kIndexR];
} else {
component = tokens[kComponentQ];
package = tokens[kPackageQ];
to_lower(component);
to_lower(package);
metrics->component = component;
metrics->package = package;
metrics->timestamp = tokens[kTimestampQ];
metrics->uid = tokens[kUidQ];
metrics->pid = tokens[kPidQ];
// the following fields are not used by the tool
metrics->finalized = tokens[kFinalizedQ];
metrics->index = tokens[kIndexQ];
metrics->item_count = tokens[kItemCountQ];
metrics->package_version = tokens[kPackageVersionQ];
metrics->session = tokens[kSessionQ];
metrics->version = tokens[kVersionQ];
}
for (auto property : properties) {
size_t equal_pos = property.find_first_of('=');
string key = property.substr(0, equal_pos);
string value = property.substr(equal_pos + 1);
metrics->properties.push_back(std::pair<string, string>(key, value));
}
}
} // namespace metrics_dump