Fixes the transformation of metrics.

This changes slightly the way metrics are converted from the HIDL
interface to the MediaDrm interface. This provides a cleaner
representation for querying metrics.

Bug: 73724453
Test: New and existing unit tests. Updated and existing GTS. Google Play
manual.

Change-Id: I9be170784a19ca3e89add53cea1cdfcaad6d65eb
diff --git a/drm/libmediadrm/DrmMetrics.cpp b/drm/libmediadrm/DrmMetrics.cpp
index fce1717..4fed707 100644
--- a/drm/libmediadrm/DrmMetrics.cpp
+++ b/drm/libmediadrm/DrmMetrics.cpp
@@ -29,6 +29,7 @@
 using ::android::String16;
 using ::android::String8;
 using ::android::drm_metrics::DrmFrameworkMetrics;
+using ::android::hardware::hidl_string;
 using ::android::hardware::hidl_vec;
 using ::android::hardware::drm::V1_0::EventType;
 using ::android::hardware::drm::V1_0::KeyStatusType;
@@ -192,6 +193,13 @@
     }
 }
 
+inline String16 MakeIndexString(unsigned int index) {
+  std::string str("[");
+  str.append(std::to_string(index));
+  str.append("]");
+  return String16(str.c_str());
+}
+
 } // namespace
 
 namespace android {
@@ -370,9 +378,11 @@
     }
 
     int groupIndex = 0;
+    std::map<String16, int> indexMap;
     for (const auto &hidlMetricGroup : hidlMetricGroups) {
         PersistableBundle bundleMetricGroup;
         for (const auto &hidlMetric : hidlMetricGroup.metrics) {
+            String16 metricName(hidlMetric.name.c_str());
             PersistableBundle bundleMetric;
             // Add metric component values.
             for (const auto &value : hidlMetric.values) {
@@ -388,14 +398,22 @@
             // Add attributes to the bundle metric.
             bundleMetric.putPersistableBundle(String16("attributes"),
                                               bundleMetricAttributes);
+            // Add one layer of indirection, allowing for repeated metric names.
+            PersistableBundle repeatedMetrics;
+            bundleMetricGroup.getPersistableBundle(metricName,
+                                                   &repeatedMetrics);
+            int index = indexMap[metricName];
+            repeatedMetrics.putPersistableBundle(MakeIndexString(index),
+                                                 bundleMetric);
+            indexMap[metricName] = ++index;
+
             // Add the bundle metric to the group of metrics.
-            bundleMetricGroup.putPersistableBundle(
-                String16(hidlMetric.name.c_str()), bundleMetric);
+            bundleMetricGroup.putPersistableBundle(metricName,
+                                                   repeatedMetrics);
         }
         // Add the bundle metric group to the collection of groups.
-        bundleMetricGroups->putPersistableBundle(
-            String16(std::to_string(groupIndex).c_str()), bundleMetricGroup);
-        groupIndex++;
+        bundleMetricGroups->putPersistableBundle(MakeIndexString(groupIndex++),
+                                                 bundleMetricGroup);
     }
 
     return OK;
diff --git a/drm/libmediadrm/tests/DrmMetrics_test.cpp b/drm/libmediadrm/tests/DrmMetrics_test.cpp
index 1a20342..64aa9d0 100644
--- a/drm/libmediadrm/tests/DrmMetrics_test.cpp
+++ b/drm/libmediadrm/tests/DrmMetrics_test.cpp
@@ -429,7 +429,8 @@
   DrmMetricGroup hidlMetricGroup =
       { { {
               "open_session_ok",
-              { { "status", DrmMetricGroup::ValueType::INT64_TYPE, (int64_t) Status::OK, 0.0, "" } },
+              { { "status", DrmMetricGroup::ValueType::INT64_TYPE,
+                  (int64_t) Status::OK, 0.0, "" } },
               { { "count", DrmMetricGroup::ValueType::INT64_TYPE, 3, 0.0, "" } }
           },
           {
@@ -444,25 +445,28 @@
                                                      &bundleMetricGroups));
   ASSERT_EQ(1U, bundleMetricGroups.size());
   PersistableBundle bundleMetricGroup;
-  ASSERT_TRUE(bundleMetricGroups.getPersistableBundle(String16("0"), &bundleMetricGroup));
+  ASSERT_TRUE(bundleMetricGroups.getPersistableBundle(String16("[0]"), &bundleMetricGroup));
   ASSERT_EQ(2U, bundleMetricGroup.size());
 
   // Verify each metric.
   PersistableBundle metric;
   ASSERT_TRUE(bundleMetricGroup.getPersistableBundle(String16("open_session_ok"), &metric));
+  PersistableBundle metricInstance;
+  ASSERT_TRUE(metric.getPersistableBundle(String16("[0]"), &metricInstance));
   int64_t value = 0;
-  ASSERT_TRUE(metric.getLong(String16("count"), &value));
+  ASSERT_TRUE(metricInstance.getLong(String16("count"), &value));
   ASSERT_EQ(3, value);
   PersistableBundle attributeBundle;
-  ASSERT_TRUE(metric.getPersistableBundle(String16("attributes"), &attributeBundle));
+  ASSERT_TRUE(metricInstance.getPersistableBundle(String16("attributes"), &attributeBundle));
   ASSERT_TRUE(attributeBundle.getLong(String16("status"), &value));
   ASSERT_EQ((int64_t) Status::OK, value);
 
   ASSERT_TRUE(bundleMetricGroup.getPersistableBundle(String16("close_session_not_opened"),
                                                      &metric));
-  ASSERT_TRUE(metric.getLong(String16("count"), &value));
+  ASSERT_TRUE(metric.getPersistableBundle(String16("[0]"), &metricInstance));
+  ASSERT_TRUE(metricInstance.getLong(String16("count"), &value));
   ASSERT_EQ(7, value);
-  ASSERT_TRUE(metric.getPersistableBundle(String16("attributes"), &attributeBundle));
+  ASSERT_TRUE(metricInstance.getPersistableBundle(String16("attributes"), &attributeBundle));
   value = 0;
   ASSERT_TRUE(attributeBundle.getLong(String16("status"), &value));
   ASSERT_EQ((int64_t) Status::ERROR_DRM_SESSION_NOT_OPENED, value);