MediaMetrics: Accept elided second argument in string pair
(device, address) string pairs used to have an optional second argument
that was empty.
Before: (d1, )|(d2, a2)
we now permit elision of the second argument entirely, so that
can now be written as
After: d1|(d2, a2)
Note: the prior string continues to be accepted.
Flag: EXEMPT bugfix
Test: atest mediametrics_tests
Test: play ringtone with BT buds and check mediametrics dumpsys
Bug: 376948941
Change-Id: I41fd2f6acf1ea42cc5e683835790769148988b7d
diff --git a/services/mediametrics/StringUtils.cpp b/services/mediametrics/StringUtils.cpp
index 5766f1c..3b2db85 100644
--- a/services/mediametrics/StringUtils.cpp
+++ b/services/mediametrics/StringUtils.cpp
@@ -80,33 +80,40 @@
{
std::vector<std::pair<std::string, std::string>> result;
- // Currently, the device format is EXACTLY
- // (device1, addr1)|(device2, addr2)|...
+ // Currently, the device format is
+ //
+ // devices = device_addr OR device_addr|devices
+ // device_addr = device OR (device, addr)
+ //
+ // EXAMPLE:
+ // device1|(device2, addr2)|...
static constexpr char delim[] = "()|,";
for (auto it = devices.begin(); ; ) {
- auto token = tokenizer(it, devices.end(), delim);
- if (token != "(") return result;
+ std::string address;
+ std::string device = tokenizer(it, devices.end(), delim);
+ if (device.empty()) return result;
+ if (device == "(") { // it is a pair otherwise we consider it a device
+ device = tokenizer(it, devices.end(), delim); // get actual device
+ auto token = tokenizer(it, devices.end(), delim);
+ if (token != ",") return result; // malformed, must have a comma
- 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;
+ // special handling here for empty addresses
+ address = tokenizer(it, devices.end(), delim);
+ if (address.empty()) return result;
+ if (address == ")") { // no address, just the ")"
+ address.clear();
+ } else {
+ token = tokenizer(it, devices.end(), delim);
+ if (token != ")") return result;
+ }
}
+ // misaligned token, device must start alphanumeric.
+ if (!std::isalnum(device[0])) return result;
result.emplace_back(std::move(device), std::move(address));
- token = tokenizer(it, devices.end(), delim);
+ auto token = tokenizer(it, devices.end(), delim);
if (token != "|") return result; // this includes end of string detection
}
}
diff --git a/services/mediametrics/tests/mediametrics_tests.cpp b/services/mediametrics/tests/mediametrics_tests.cpp
index a7684f4..f3933a7 100644
--- a/services/mediametrics/tests/mediametrics_tests.cpp
+++ b/services/mediametrics/tests/mediametrics_tests.cpp
@@ -963,6 +963,31 @@
ASSERT_EQ("B", devaddr[0].second);
ASSERT_EQ("C", devaddr[1].first);
ASSERT_EQ("D2", devaddr[1].second);
+
+ devaddr = android::mediametrics::stringutils::getDeviceAddressPairs(
+ " Z ");
+ ASSERT_EQ((size_t)1, devaddr.size());
+ ASSERT_EQ("Z", devaddr[0].first);
+
+ devaddr = android::mediametrics::stringutils::getDeviceAddressPairs(
+ " A | B|C ");
+ ASSERT_EQ((size_t)3, devaddr.size());
+ ASSERT_EQ("A", devaddr[0].first);
+ ASSERT_EQ("", devaddr[0].second);
+ ASSERT_EQ("B", devaddr[1].first);
+ ASSERT_EQ("", devaddr[1].second);
+ ASSERT_EQ("C", devaddr[2].first);
+ ASSERT_EQ("", devaddr[2].second);
+
+ devaddr = android::mediametrics::stringutils::getDeviceAddressPairs(
+ " A | (B1, 10) |C ");
+ ASSERT_EQ((size_t)3, devaddr.size());
+ ASSERT_EQ("A", devaddr[0].first);
+ ASSERT_EQ("", devaddr[0].second);
+ ASSERT_EQ("B1", devaddr[1].first);
+ ASSERT_EQ("10", devaddr[1].second);
+ ASSERT_EQ("C", devaddr[2].first);
+ ASSERT_EQ("", devaddr[2].second);
}
TEST(mediametrics_tests, timed_action) {