MediaMetrics: Add device-based actions for Bluetooth
Log summary group statistics by device.
Test: adb shell dumpsys media.metrics
Bug: 149850236
Change-Id: I31fef89fa020de175e59784049ef4741914f3a2c
diff --git a/services/mediametrics/MediaMetricsService.cpp b/services/mediametrics/MediaMetricsService.cpp
index 4b84bea..3b3dc3e 100644
--- a/services/mediametrics/MediaMetricsService.cpp
+++ b/services/mediametrics/MediaMetricsService.cpp
@@ -78,6 +78,74 @@
}
}
+/* static */
+std::pair<std::string, int64_t>
+MediaMetricsService::getSanitizedPackageNameAndVersionCode(uid_t uid) {
+ // Meyer's singleton, initialized on first access.
+ // mUidInfo is locked internally.
+ static mediautils::UidInfo uidInfo;
+
+ // get info.
+ mediautils::UidInfo::Info info = uidInfo.getInfo(uid);
+ if (useUidForPackage(info.package, info.installer)) {
+ return { std::to_string(uid), /* versionCode */ 0 };
+ } else {
+ return { info.package, info.versionCode };
+ }
+}
+
+/* static */
+std::string MediaMetricsService::tokenizer(std::string::const_iterator& it,
+ const std::string::const_iterator& end, const char *reserved) {
+ // consume leading white space
+ for (; it != end && std::isspace(*it); ++it);
+ if (it == end) return {};
+
+ auto start = it;
+ // parse until we hit a reserved keyword or space
+ if (strchr(reserved, *it)) return {start, ++it};
+ for (;;) {
+ ++it;
+ if (it == end || std::isspace(*it) || strchr(reserved, *it)) return {start, it};
+ }
+}
+
+/* static */
+std::vector<std::pair<std::string, std::string>>
+MediaMetricsService::getDeviceAddressPairs(const std::string& devices) {
+ std::vector<std::pair<std::string, std::string>> result;
+
+ // Currently, the device format is EXACTLY
+ // (device1, addr1)|(device2, addr2)|...
+
+ static constexpr char delim[] = "()|,";
+ for (auto it = devices.begin(); ; ) {
+ auto token = tokenizer(it, devices.end(), delim);
+ if (token != "(") return result;
+
+ auto device = tokenizer(it, devices.end(), delim);
+ if (device.empty() || !std::isalnum(device[0])) return result;
+
+ token = tokenizer(it, devices.end(), delim);
+ if (token != ",") return result;
+
+ // special handling here for empty addresses
+ auto address = tokenizer(it, devices.end(), delim);
+ if (address.empty() || !std::isalnum(device[0])) return result;
+ if (address == ")") { // no address, just the ")"
+ address.clear();
+ } else {
+ token = tokenizer(it, devices.end(), delim);
+ if (token != ")") return result;
+ }
+
+ result.emplace_back(std::move(device), std::move(address));
+
+ token = tokenizer(it, devices.end(), delim);
+ if (token != "|") return result; // this includes end of string detection
+ }
+}
+
MediaMetricsService::MediaMetricsService()
: mMaxRecords(kMaxRecords),
mMaxRecordAgeNs(kMaxRecordAgeNs),
@@ -136,16 +204,10 @@
// Overwrite package name and version if the caller was untrusted or empty
if (!isTrusted || item->getPkgName().empty()) {
const uid_t uid = item->getUid();
- mediautils::UidInfo::Info info = mUidInfo.getInfo(uid);
- if (useUidForPackage(info.package, info.installer)) {
- // remove uid information of unknown installed packages.
- // TODO: perhaps this can be done just before uploading to Westworld.
- item->setPkgName(std::to_string(uid));
- item->setPkgVersionCode(0);
- } else {
- item->setPkgName(info.package);
- item->setPkgVersionCode(info.versionCode);
- }
+ const auto [ pkgName, version ] =
+ MediaMetricsService::getSanitizedPackageNameAndVersionCode(uid);
+ item->setPkgName(pkgName);
+ item->setPkgVersionCode(version);
}
ALOGV("%s: isTrusted:%d given uid %d; sanitized uid: %d sanitized pkg: %s "