libmediadrm: refactor bundle dependency

Bundle dependency now lives in DrmMetricsConsumer,
which is part of the new libmediadrmmetrics_consumer.

Bug: 134787536
Test: DrmMetrics_test
Change-Id: I09b0981b6f97668c2572fb28d0e98de72068376b
diff --git a/drm/libmediadrm/Android.bp b/drm/libmediadrm/Android.bp
index 34a2f69..4c411be 100644
--- a/drm/libmediadrm/Android.bp
+++ b/drm/libmediadrm/Android.bp
@@ -95,8 +95,6 @@
         "android.hardware.drm@1.0",
         "android.hardware.drm@1.1",
         "android.hardware.drm@1.2",
-        "libbinder",
-        "libhidlbase",
         "liblog",
         "libmediametrics",
         "libprotobuf-cpp-lite",
@@ -134,8 +132,6 @@
         "android.hardware.drm@1.1",
         "android.hardware.drm@1.2",
         "libbase",
-        "libbinder",
-        "libhidlbase",
         "liblog",
         "libmediametrics",
         "libprotobuf-cpp-full",
@@ -149,3 +145,25 @@
     ],
 }
 
+cc_library_shared {
+    name: "libmediadrmmetrics_consumer",
+    srcs: [
+        "DrmMetricsConsumer.cpp",
+    ],
+
+    include_dirs: [
+        "frameworks/av/media/libmedia/include"
+    ],
+
+    shared_libs: [
+        "android.hardware.drm@1.0",
+        "android.hardware.drm@1.1",
+        "android.hardware.drm@1.2",
+        "libbinder",
+        "libhidlbase",
+        "liblog",
+        "libmediadrm",
+        "libmediadrmmetrics_full",
+        "libutils",
+    ],
+}
diff --git a/drm/libmediadrm/DrmHal.cpp b/drm/libmediadrm/DrmHal.cpp
index f3028d8..757ccda 100644
--- a/drm/libmediadrm/DrmHal.cpp
+++ b/drm/libmediadrm/DrmHal.cpp
@@ -38,6 +38,7 @@
 #include <mediadrm/DrmHal.h>
 #include <mediadrm/DrmSessionClientInterface.h>
 #include <mediadrm/DrmSessionManager.h>
+#include <mediadrm/IDrmMetricsConsumer.h>
 
 #include <vector>
 
@@ -1362,11 +1363,11 @@
     return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
 }
 
-status_t DrmHal::getMetrics(PersistableBundle* metrics) {
-    if (metrics == nullptr) {
+status_t DrmHal::getMetrics(const sp<IDrmMetricsConsumer> &consumer) {
+    if (consumer == nullptr) {
         return UNEXPECTED_NULL;
     }
-    mMetrics.Export(metrics);
+    consumer->consumeFrameworkMetrics(mMetrics);
 
     // Append vendor metrics if they are supported.
     if (mPluginV1_1 != NULL) {
@@ -1393,11 +1394,7 @@
                     if (status != Status::OK) {
                       ALOGV("Error getting plugin metrics: %d", status);
                     } else {
-                        PersistableBundle pluginBundle;
-                        if (MediaDrmMetrics::HidlMetricsToBundle(
-                                pluginMetrics, &pluginBundle) == OK) {
-                            metrics->putPersistableBundle(String16(vendor), pluginBundle);
-                        }
+                      consumer->consumeHidlMetrics(vendor, pluginMetrics);
                     }
                     err = toStatusT(status);
                 });
diff --git a/drm/libmediadrm/DrmMetrics.cpp b/drm/libmediadrm/DrmMetrics.cpp
index 3080802..996fd19 100644
--- a/drm/libmediadrm/DrmMetrics.cpp
+++ b/drm/libmediadrm/DrmMetrics.cpp
@@ -29,143 +29,12 @@
 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_2::KeyStatusType;
 using ::android::hardware::drm::V1_1::DrmMetricGroup;
-using ::android::os::PersistableBundle;
 
 namespace {
 
-template <typename T> std::string GetAttributeName(T type);
-
-template <> std::string GetAttributeName<KeyStatusType>(KeyStatusType type) {
-    static const char *type_names[] = {"USABLE", "EXPIRED",
-                                       "OUTPUT_NOT_ALLOWED", "STATUS_PENDING",
-                                       "INTERNAL_ERROR"};
-    if (((size_t)type) > arraysize(type_names)) {
-        return "UNKNOWN_TYPE";
-    }
-    return type_names[(size_t)type];
-}
-
-template <> std::string GetAttributeName<EventType>(EventType type) {
-    static const char *type_names[] = {"PROVISION_REQUIRED", "KEY_NEEDED",
-                                       "KEY_EXPIRED", "VENDOR_DEFINED",
-                                       "SESSION_RECLAIMED"};
-    if (((size_t)type) > arraysize(type_names)) {
-        return "UNKNOWN_TYPE";
-    }
-    return type_names[(size_t)type];
-}
-
-template <typename T>
-void ExportCounterMetric(const android::CounterMetric<T> &counter,
-                         PersistableBundle *metrics) {
-    if (!metrics) {
-        ALOGE("metrics was unexpectedly null.");
-        return;
-    }
-    std::string success_count_name = counter.metric_name() + ".ok.count";
-    std::string error_count_name = counter.metric_name() + ".error.count";
-    std::vector<int64_t> status_values;
-    counter.ExportValues(
-        [&](const android::status_t status, const int64_t value) {
-            if (status == android::OK) {
-                metrics->putLong(android::String16(success_count_name.c_str()),
-                                 value);
-            } else {
-                int64_t total_errors(0);
-                metrics->getLong(android::String16(error_count_name.c_str()),
-                                 &total_errors);
-                metrics->putLong(android::String16(error_count_name.c_str()),
-                                 total_errors + value);
-                status_values.push_back(status);
-            }
-        });
-    if (!status_values.empty()) {
-        std::string error_list_name = counter.metric_name() + ".error.list";
-        metrics->putLongVector(android::String16(error_list_name.c_str()),
-                               status_values);
-    }
-}
-
-template <typename T>
-void ExportCounterMetricWithAttributeNames(
-    const android::CounterMetric<T> &counter, PersistableBundle *metrics) {
-    if (!metrics) {
-        ALOGE("metrics was unexpectedly null.");
-        return;
-    }
-    counter.ExportValues([&](const T &attribute, const int64_t value) {
-        std::string name = counter.metric_name() + "." +
-                           GetAttributeName(attribute) + ".count";
-        metrics->putLong(android::String16(name.c_str()), value);
-    });
-}
-
-template <typename T>
-void ExportEventMetric(const android::EventMetric<T> &event,
-                       PersistableBundle *metrics) {
-    if (!metrics) {
-        ALOGE("metrics was unexpectedly null.");
-        return;
-    }
-    std::string success_count_name = event.metric_name() + ".ok.count";
-    std::string error_count_name = event.metric_name() + ".error.count";
-    std::string timing_name = event.metric_name() + ".ok.average_time_micros";
-    std::vector<int64_t> status_values;
-    event.ExportValues([&](const android::status_t &status,
-                           const android::EventStatistics &value) {
-        if (status == android::OK) {
-            metrics->putLong(android::String16(success_count_name.c_str()),
-                             value.count);
-            metrics->putLong(android::String16(timing_name.c_str()),
-                             value.mean);
-        } else {
-            int64_t total_errors(0);
-            metrics->getLong(android::String16(error_count_name.c_str()),
-                             &total_errors);
-            metrics->putLong(android::String16(error_count_name.c_str()),
-                             total_errors + value.count);
-            status_values.push_back(status);
-        }
-    });
-    if (!status_values.empty()) {
-        std::string error_list_name = event.metric_name() + ".error.list";
-        metrics->putLongVector(android::String16(error_list_name.c_str()),
-                               status_values);
-    }
-}
-
-void ExportSessionLifespans(
-    const std::map<std::string, std::pair<int64_t, int64_t>> &mSessionLifespans,
-    PersistableBundle *metrics) {
-    if (!metrics) {
-        ALOGE("metrics was unexpectedly null.");
-        return;
-    }
-
-    if (mSessionLifespans.empty()) {
-        return;
-    }
-
-    PersistableBundle startTimesBundle;
-    PersistableBundle endTimesBundle;
-    for (auto it = mSessionLifespans.begin(); it != mSessionLifespans.end();
-         it++) {
-        String16 key(it->first.c_str(), it->first.size());
-        startTimesBundle.putLong(key, it->second.first);
-        endTimesBundle.putLong(key, it->second.second);
-    }
-    metrics->putPersistableBundle(
-        android::String16("drm.mediadrm.session_start_times_ms"),
-        startTimesBundle);
-    metrics->putPersistableBundle(
-        android::String16("drm.mediadrm.session_end_times_ms"), endTimesBundle);
-}
-
 std::string ToHexString(const android::Vector<uint8_t> &sessionId) {
     std::ostringstream out;
     out << std::hex << std::setfill('0');
@@ -175,31 +44,6 @@
     return out.str();
 }
 
-template <typename CT>
-void SetValue(const String16 &name, DrmMetricGroup::ValueType type,
-              const CT &value, PersistableBundle *bundle) {
-    switch (type) {
-    case DrmMetricGroup::ValueType::INT64_TYPE:
-        bundle->putLong(name, value.int64Value);
-        break;
-    case DrmMetricGroup::ValueType::DOUBLE_TYPE:
-        bundle->putDouble(name, value.doubleValue);
-        break;
-    case DrmMetricGroup::ValueType::STRING_TYPE:
-        bundle->putString(name, String16(value.stringValue.c_str()));
-        break;
-    default:
-        ALOGE("Unexpected value type: %hhu", type);
-    }
-}
-
-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 {
@@ -237,23 +81,6 @@
     }
 }
 
-void MediaDrmMetrics::Export(PersistableBundle *metrics) {
-    if (!metrics) {
-        ALOGE("metrics was unexpectedly null.");
-        return;
-    }
-    ExportCounterMetric(mOpenSessionCounter, metrics);
-    ExportCounterMetric(mCloseSessionCounter, metrics);
-    ExportEventMetric(mGetKeyRequestTimeUs, metrics);
-    ExportEventMetric(mProvideKeyResponseTimeUs, metrics);
-    ExportCounterMetric(mGetProvisionRequestCounter, metrics);
-    ExportCounterMetric(mProvideProvisionResponseCounter, metrics);
-    ExportCounterMetricWithAttributeNames(mKeyStatusChangeCounter, metrics);
-    ExportCounterMetricWithAttributeNames(mEventCounter, metrics);
-    ExportCounterMetric(mGetDeviceUniqueIdCounter, metrics);
-    ExportSessionLifespans(mSessionLifespans, metrics);
-}
-
 status_t MediaDrmMetrics::GetSerializedMetrics(std::string *serializedMetrics) {
 
     if (!serializedMetrics) {
@@ -361,62 +188,14 @@
     return OK;
 }
 
+std::map<std::string, std::pair<int64_t, int64_t>> MediaDrmMetrics::GetSessionLifespans() const {
+  return mSessionLifespans;
+}
+
 int64_t MediaDrmMetrics::GetCurrentTimeMs() {
     struct timeval tv;
     gettimeofday(&tv, NULL);
     return ((int64_t)tv.tv_sec * 1000) + ((int64_t)tv.tv_usec / 1000);
 }
 
-status_t MediaDrmMetrics::HidlMetricsToBundle(
-    const hidl_vec<DrmMetricGroup> &hidlMetricGroups,
-    PersistableBundle *bundleMetricGroups) {
-    if (bundleMetricGroups == nullptr) {
-        return UNEXPECTED_NULL;
-    }
-    if (hidlMetricGroups.size() == 0) {
-        return OK;
-    }
-
-    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) {
-                SetValue(String16(value.componentName.c_str()), value.type,
-                         value, &bundleMetric);
-            }
-            // Set metric attributes.
-            PersistableBundle bundleMetricAttributes;
-            for (const auto &attribute : hidlMetric.attributes) {
-                SetValue(String16(attribute.name.c_str()), attribute.type,
-                         attribute, &bundleMetricAttributes);
-            }
-            // 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(metricName,
-                                                   repeatedMetrics);
-        }
-        // Add the bundle metric group to the collection of groups.
-        bundleMetricGroups->putPersistableBundle(MakeIndexString(groupIndex++),
-                                                 bundleMetricGroup);
-    }
-
-    return OK;
-}
-
 } // namespace android
diff --git a/drm/libmediadrm/DrmMetricsConsumer.cpp b/drm/libmediadrm/DrmMetricsConsumer.cpp
new file mode 100644
index 0000000..b47b4ff
--- /dev/null
+++ b/drm/libmediadrm/DrmMetricsConsumer.cpp
@@ -0,0 +1,270 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#define LOG_TAG "DrmMetricsConsumer"
+
+#include <android-base/macros.h>
+#include <mediadrm/DrmMetricsConsumer.h>
+#include <mediadrm/DrmMetrics.h>
+#include <utils/String8.h>
+#include <utils/String16.h>
+
+using ::android::String16;
+using ::android::String8;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::drm::V1_0::EventType;
+using ::android::hardware::drm::V1_2::KeyStatusType;
+using ::android::hardware::drm::V1_1::DrmMetricGroup;
+using ::android::os::PersistableBundle;
+
+namespace {
+
+template <typename T> std::string GetAttributeName(T type);
+
+template <> std::string GetAttributeName<KeyStatusType>(KeyStatusType type) {
+    static const char *type_names[] = {"USABLE", "EXPIRED",
+                                       "OUTPUT_NOT_ALLOWED", "STATUS_PENDING",
+                                       "INTERNAL_ERROR"};
+    if (((size_t)type) > arraysize(type_names)) {
+        return "UNKNOWN_TYPE";
+    }
+    return type_names[(size_t)type];
+}
+
+template <> std::string GetAttributeName<EventType>(EventType type) {
+    static const char *type_names[] = {"PROVISION_REQUIRED", "KEY_NEEDED",
+                                       "KEY_EXPIRED", "VENDOR_DEFINED",
+                                       "SESSION_RECLAIMED"};
+    if (((size_t)type) > arraysize(type_names)) {
+        return "UNKNOWN_TYPE";
+    }
+    return type_names[(size_t)type];
+}
+
+template <typename T>
+void ExportCounterMetric(const android::CounterMetric<T> &counter,
+                         PersistableBundle *metrics) {
+    if (!metrics) {
+        ALOGE("metrics was unexpectedly null.");
+        return;
+    }
+    std::string success_count_name = counter.metric_name() + ".ok.count";
+    std::string error_count_name = counter.metric_name() + ".error.count";
+    std::vector<int64_t> status_values;
+    counter.ExportValues(
+        [&](const android::status_t status, const int64_t value) {
+            if (status == android::OK) {
+                metrics->putLong(android::String16(success_count_name.c_str()),
+                                 value);
+            } else {
+                int64_t total_errors(0);
+                metrics->getLong(android::String16(error_count_name.c_str()),
+                                 &total_errors);
+                metrics->putLong(android::String16(error_count_name.c_str()),
+                                 total_errors + value);
+                status_values.push_back(status);
+            }
+        });
+    if (!status_values.empty()) {
+        std::string error_list_name = counter.metric_name() + ".error.list";
+        metrics->putLongVector(android::String16(error_list_name.c_str()),
+                               status_values);
+    }
+}
+
+template <typename T>
+void ExportCounterMetricWithAttributeNames(
+    const android::CounterMetric<T> &counter, PersistableBundle *metrics) {
+    if (!metrics) {
+        ALOGE("metrics was unexpectedly null.");
+        return;
+    }
+    counter.ExportValues([&](const T &attribute, const int64_t value) {
+        std::string name = counter.metric_name() + "." +
+                           GetAttributeName(attribute) + ".count";
+        metrics->putLong(android::String16(name.c_str()), value);
+    });
+}
+
+template <typename T>
+void ExportEventMetric(const android::EventMetric<T> &event,
+                       PersistableBundle *metrics) {
+    if (!metrics) {
+        ALOGE("metrics was unexpectedly null.");
+        return;
+    }
+    std::string success_count_name = event.metric_name() + ".ok.count";
+    std::string error_count_name = event.metric_name() + ".error.count";
+    std::string timing_name = event.metric_name() + ".ok.average_time_micros";
+    std::vector<int64_t> status_values;
+    event.ExportValues([&](const android::status_t &status,
+                           const android::EventStatistics &value) {
+        if (status == android::OK) {
+            metrics->putLong(android::String16(success_count_name.c_str()),
+                             value.count);
+            metrics->putLong(android::String16(timing_name.c_str()),
+                             value.mean);
+        } else {
+            int64_t total_errors(0);
+            metrics->getLong(android::String16(error_count_name.c_str()),
+                             &total_errors);
+            metrics->putLong(android::String16(error_count_name.c_str()),
+                             total_errors + value.count);
+            status_values.push_back(status);
+        }
+    });
+    if (!status_values.empty()) {
+        std::string error_list_name = event.metric_name() + ".error.list";
+        metrics->putLongVector(android::String16(error_list_name.c_str()),
+                               status_values);
+    }
+}
+
+void ExportSessionLifespans(
+    const std::map<std::string, std::pair<int64_t, int64_t>> &sessionLifespans,
+    PersistableBundle *metrics) {
+    if (!metrics) {
+        ALOGE("metrics was unexpectedly null.");
+        return;
+    }
+
+    if (sessionLifespans.empty()) {
+        return;
+    }
+
+    PersistableBundle startTimesBundle;
+    PersistableBundle endTimesBundle;
+    for (auto it = sessionLifespans.begin(); it != sessionLifespans.end();
+         it++) {
+        String16 key(it->first.c_str(), it->first.size());
+        startTimesBundle.putLong(key, it->second.first);
+        endTimesBundle.putLong(key, it->second.second);
+    }
+    metrics->putPersistableBundle(
+        android::String16("drm.mediadrm.session_start_times_ms"),
+        startTimesBundle);
+    metrics->putPersistableBundle(
+        android::String16("drm.mediadrm.session_end_times_ms"), endTimesBundle);
+}
+
+template <typename CT>
+void SetValue(const String16 &name, DrmMetricGroup::ValueType type,
+              const CT &value, PersistableBundle *bundle) {
+    switch (type) {
+    case DrmMetricGroup::ValueType::INT64_TYPE:
+        bundle->putLong(name, value.int64Value);
+        break;
+    case DrmMetricGroup::ValueType::DOUBLE_TYPE:
+        bundle->putDouble(name, value.doubleValue);
+        break;
+    case DrmMetricGroup::ValueType::STRING_TYPE:
+        bundle->putString(name, String16(value.stringValue.c_str()));
+        break;
+    default:
+        ALOGE("Unexpected value type: %hhu", type);
+    }
+}
+
+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 {
+
+status_t DrmMetricsConsumer::consumeFrameworkMetrics(const MediaDrmMetrics &metrics) {
+    ExportCounterMetric(metrics.mOpenSessionCounter, mBundle);
+    ExportCounterMetric(metrics.mCloseSessionCounter, mBundle);
+    ExportEventMetric(metrics.mGetKeyRequestTimeUs, mBundle);
+    ExportEventMetric(metrics.mProvideKeyResponseTimeUs, mBundle);
+    ExportCounterMetric(metrics.mGetProvisionRequestCounter, mBundle);
+    ExportCounterMetric(metrics.mProvideProvisionResponseCounter, mBundle);
+    ExportCounterMetricWithAttributeNames(metrics.mKeyStatusChangeCounter, mBundle);
+    ExportCounterMetricWithAttributeNames(metrics.mEventCounter, mBundle);
+    ExportCounterMetric(metrics.mGetDeviceUniqueIdCounter, mBundle);
+    ExportSessionLifespans(metrics.GetSessionLifespans(), mBundle);
+    return android::OK;
+}
+
+status_t DrmMetricsConsumer::consumeHidlMetrics(
+        const String8 &vendor,
+        const hidl_vec<DrmMetricGroup> &pluginMetrics) {
+    PersistableBundle pluginBundle;
+    if (DrmMetricsConsumer::HidlMetricsToBundle(
+            pluginMetrics, &pluginBundle) == OK) {
+        mBundle->putPersistableBundle(String16(vendor), pluginBundle);
+    }
+    return android::OK;
+}
+
+status_t DrmMetricsConsumer::HidlMetricsToBundle(
+    const hidl_vec<DrmMetricGroup> &hidlMetricGroups,
+    PersistableBundle *bundleMetricGroups) {
+    if (bundleMetricGroups == nullptr) {
+        return UNEXPECTED_NULL;
+    }
+    if (hidlMetricGroups.size() == 0) {
+        return OK;
+    }
+
+    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) {
+                SetValue(String16(value.componentName.c_str()), value.type,
+                         value, &bundleMetric);
+            }
+            // Set metric attributes.
+            PersistableBundle bundleMetricAttributes;
+            for (const auto &attribute : hidlMetric.attributes) {
+                SetValue(String16(attribute.name.c_str()), attribute.type,
+                         attribute, &bundleMetricAttributes);
+            }
+            // 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(metricName,
+                                                   repeatedMetrics);
+        }
+        // Add the bundle metric group to the collection of groups.
+        bundleMetricGroups->putPersistableBundle(MakeIndexString(groupIndex++),
+                                                 bundleMetricGroup);
+    }
+
+    return OK;
+}
+
+} // namespace android
+
diff --git a/drm/libmediadrm/include/mediadrm/BundleDrmMetricsConsumer.h b/drm/libmediadrm/include/mediadrm/BundleDrmMetricsConsumer.h
deleted file mode 100644
index 1bcb352..0000000
--- a/drm/libmediadrm/include/mediadrm/BundleDrmMetricsConsumer.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <binder/PersistableBundle.h>
-#include <mediadrm/IDrmMetricsConsumer.h>
-#include <utils/Errors.h>
-
-#ifndef ANDROID_BUNDLEMETRICSCONSUMER_H_
-
-#define ANDROID_BUNDLEMETRICSCONSUMER_H_
-
-namespace android {
-
-/**
- * IDrmMetricsConsumer which saves IDrm/ICrypto metrics into a PersistableBundle.
- *
- * Example usage:
- *
- *   PersistableBundle bundle;
- *   BundleDrmMetricsConsumer consumer(&bundle);
- *   drm->exportMetrics(&consumer);
- *   crypto->exportMetrics(&consumer);
- *   // bundle now contains metrics from drm/crypto.
- *
- */
-struct BundleDrmMetricsConsumer : public IDrmMetricsConsumer {
-    BundleDrmMetricsConsumer(os::PersistableBundle*) {}
-
-    status_t consumeFrameworkMetrics(const MediaDrmMetrics &) override {
-        return OK;
-    }
-
-    status_t consumeHidlMetrics(
-            const String8 &/*vendor*/,
-            const hidl_vec<DrmMetricGroup> &/*pluginMetrics*/) override {
-        return OK;
-    }
-
-private:
-    DISALLOW_EVIL_CONSTRUCTORS(BundleDrmMetricsConsumer);
-};
-
-}  // namespace android
-
-#endif // ANDROID_BUNDLEMETRICSCONSUMER_H_
diff --git a/drm/libmediadrm/include/mediadrm/DrmHal.h b/drm/libmediadrm/include/mediadrm/DrmHal.h
index f261d89..6818dd7 100644
--- a/drm/libmediadrm/include/mediadrm/DrmHal.h
+++ b/drm/libmediadrm/include/mediadrm/DrmHal.h
@@ -30,6 +30,7 @@
 #include <mediadrm/DrmSessionManager.h>
 #include <mediadrm/IDrm.h>
 #include <mediadrm/IDrmClient.h>
+#include <mediadrm/IDrmMetricsConsumer.h>
 #include <utils/threads.h>
 
 namespace drm = ::android::hardware::drm;
@@ -136,7 +137,7 @@
     virtual status_t setPropertyString(String8 const &name, String8 const &value ) const;
     virtual status_t setPropertyByteArray(String8 const &name,
                                           Vector<uint8_t> const &value ) const;
-    virtual status_t getMetrics(os::PersistableBundle *metrics);
+    virtual status_t getMetrics(const sp<IDrmMetricsConsumer> &consumer);
 
     virtual status_t setCipherAlgorithm(Vector<uint8_t> const &sessionId,
                                         String8 const &algorithm);
diff --git a/drm/libmediadrm/include/mediadrm/DrmMetrics.h b/drm/libmediadrm/include/mediadrm/DrmMetrics.h
index 833ffa4..100b8f7 100644
--- a/drm/libmediadrm/include/mediadrm/DrmMetrics.h
+++ b/drm/libmediadrm/include/mediadrm/DrmMetrics.h
@@ -75,55 +75,14 @@
   void SetAppUid(uid_t appUid) { mAppUid = appUid; }
   uid_t GetAppUid() const { return mAppUid; }
 
-  // Export the metrics to a PersistableBundle.
-  void Export(os::PersistableBundle* metricsBundle);
-
   // Get the serialized metrics. Metrics are formatted as a serialized
   // DrmFrameworkMetrics proto. If there is a failure serializing the metrics,
   // this returns an error. The parameter |serlializedMetrics| is owned by the
   // caller and must not be null.
   status_t GetSerializedMetrics(std::string* serializedMetrics);
 
-  // Converts the DRM plugin metrics to a PersistableBundle. All of the metrics
-  // found in |pluginMetrics| are added to the |metricsBundle| parameter.
-  // |pluginBundle| is owned by the caller and must not be null.
-  //
-  // Each item in the pluginMetrics vector is added as a new PersistableBundle. E.g.
-  // DrmMetricGroup {
-  //   metrics[0] {
-  //     name: "buf_copy"
-  //     attributes[0] {
-  //       name: "size"
-  //       type: INT64_TYPE
-  //       int64Value: 1024
-  //     }
-  //     values[0] {
-  //       componentName: "operation_count"
-  //       type: INT64_TYPE
-  //       int64Value: 75
-  //     }
-  //     values[1] {
-  //       component_name: "average_time_seconds"
-  //       type: DOUBLE_TYPE
-  //       doubleValue: 0.00000042
-  //     }
-  //   }
-  // }
-  //
-  // becomes
-  //
-  // metricsBundle {
-  //   "0": (PersistableBundle) {
-  //     "attributes" : (PersistableBundle) {
-  //       "size" : (int64) 1024
-  //     }
-  //     "operation_count" : (int64) 75
-  //     "average_time_seconds" : (double) 0.00000042
-  //   }
-  //
-  static status_t HidlMetricsToBundle(
-          const hardware::hidl_vec<hardware::drm::V1_1::DrmMetricGroup>& pluginMetrics,
-          os::PersistableBundle* metricsBundle);
+  // Get copy of session lifetimes.
+  std::map<std::string, std::pair<int64_t, int64_t>> GetSessionLifespans() const;
 
  protected:
   // This is visible for testing only.
diff --git a/drm/libmediadrm/include/mediadrm/DrmMetricsConsumer.h b/drm/libmediadrm/include/mediadrm/DrmMetricsConsumer.h
new file mode 100644
index 0000000..bbbf4b5
--- /dev/null
+++ b/drm/libmediadrm/include/mediadrm/DrmMetricsConsumer.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <binder/PersistableBundle.h>
+#include <mediadrm/IDrmMetricsConsumer.h>
+#include <utils/Errors.h>
+
+#ifndef ANDROID_METRICSCONSUMER_H_
+
+#define ANDROID_METRICSCONSUMER_H_
+
+namespace android {
+
+/**
+ * IDrmMetricsConsumer which saves IDrm/ICrypto metrics into a PersistableBundle.
+ *
+ * Example usage:
+ *
+ *   PersistableBundle bundle;
+ *   DrmMetricsConsumer consumer(&bundle);
+ *   drm->exportMetrics(&consumer);
+ *   crypto->exportMetrics(&consumer);
+ *   // bundle now contains metrics from drm/crypto.
+ *
+ */
+struct DrmMetricsConsumer : public IDrmMetricsConsumer {
+    DrmMetricsConsumer(os::PersistableBundle *bundle) : mBundle(bundle) {}
+
+    status_t consumeFrameworkMetrics(const MediaDrmMetrics &) override;
+
+    status_t consumeHidlMetrics(
+            const String8 &/*vendor*/,
+            const hidl_vec<DrmMetricGroup> &/*pluginMetrics*/) override;
+
+    // Converts the DRM plugin metrics to a PersistableBundle. All of the metrics
+    // found in |pluginMetrics| are added to the |metricsBundle| parameter.
+    // |pluginBundle| is owned by the caller and must not be null.
+    //
+    // Each item in the pluginMetrics vector is added as a new PersistableBundle. E.g.
+    // DrmMetricGroup {
+    //   metrics[0] {
+    //     name: "buf_copy"
+    //     attributes[0] {
+    //       name: "size"
+    //       type: INT64_TYPE
+    //       int64Value: 1024
+    //     }
+    //     values[0] {
+    //       componentName: "operation_count"
+    //       type: INT64_TYPE
+    //       int64Value: 75
+    //     }
+    //     values[1] {
+    //       component_name: "average_time_seconds"
+    //       type: DOUBLE_TYPE
+    //       doubleValue: 0.00000042
+    //     }
+    //   }
+    // }
+    //
+    // becomes
+    //
+    // metricsBundle {
+    //   "0": (PersistableBundle) {
+    //     "attributes" : (PersistableBundle) {
+    //       "size" : (int64) 1024
+    //     }
+    //     "operation_count" : (int64) 75
+    //     "average_time_seconds" : (double) 0.00000042
+    //   }
+    //
+    static status_t HidlMetricsToBundle(
+            const hardware::hidl_vec<hardware::drm::V1_1::DrmMetricGroup>& pluginMetrics,
+            os::PersistableBundle* metricsBundle);
+
+private:
+    os::PersistableBundle *mBundle;
+    DISALLOW_EVIL_CONSTRUCTORS(DrmMetricsConsumer);
+};
+
+}  // namespace android
+
+#endif // ANDROID_METRICSCONSUMER_H_
diff --git a/drm/libmediadrm/include/mediadrm/IDrm.h b/drm/libmediadrm/include/mediadrm/IDrm.h
index 4103d5d..48a7170 100644
--- a/drm/libmediadrm/include/mediadrm/IDrm.h
+++ b/drm/libmediadrm/include/mediadrm/IDrm.h
@@ -19,6 +19,7 @@
 #include <media/stagefright/foundation/ABase.h>
 #include <media/drm/DrmAPI.h>
 #include <mediadrm/IDrmClient.h>
+#include <mediadrm/IDrmMetricsConsumer.h>
 
 #ifndef ANDROID_IDRM_H_
 
@@ -107,7 +108,7 @@
     virtual status_t setPropertyByteArray(String8 const &name,
                                           Vector<uint8_t> const &value) const = 0;
 
-    virtual status_t getMetrics(os::PersistableBundle *metrics) = 0;
+    virtual status_t getMetrics(const sp<IDrmMetricsConsumer> &consumer) = 0;
 
     virtual status_t setCipherAlgorithm(Vector<uint8_t> const &sessionId,
                                         String8 const &algorithm) = 0;
diff --git a/drm/libmediadrm/include/mediadrm/IDrmMetricsConsumer.h b/drm/libmediadrm/include/mediadrm/IDrmMetricsConsumer.h
index efa61d8..aef35c3 100644
--- a/drm/libmediadrm/include/mediadrm/IDrmMetricsConsumer.h
+++ b/drm/libmediadrm/include/mediadrm/IDrmMetricsConsumer.h
@@ -55,8 +55,8 @@
  * ----------------------------------------
  *
  * For an example implementation of IDrmMetricsConsumer, please
- * see BundleDrmMetricsConsumer. BundleDrmMetricsConsumer consumes
- * IDrm/ICrypto metrics and saves the metrics to a PersistableBundle.
+ * see DrmMetricsConsumer. DrmMetricsConsumer consumes IDrm/ICrypto
+ * metrics and saves the metrics to a PersistableBundle.
  *
  */
 struct IDrmMetricsConsumer : public RefBase {
diff --git a/drm/libmediadrm/tests/Android.bp b/drm/libmediadrm/tests/Android.bp
index 2e39943..7471e05 100644
--- a/drm/libmediadrm/tests/Android.bp
+++ b/drm/libmediadrm/tests/Android.bp
@@ -24,6 +24,8 @@
       "libbinder",
       "libhidlbase",
       "liblog",
+      "libmediadrm",
+      "libmediadrmmetrics_consumer",
       "libmediadrmmetrics_full",
       "libmediametrics",
       "libprotobuf-cpp-full",
diff --git a/drm/libmediadrm/tests/DrmMetrics_test.cpp b/drm/libmediadrm/tests/DrmMetrics_test.cpp
index 5c8a1b0..f362d60 100644
--- a/drm/libmediadrm/tests/DrmMetrics_test.cpp
+++ b/drm/libmediadrm/tests/DrmMetrics_test.cpp
@@ -16,6 +16,7 @@
 
 #define LOG_TAG "DrmMetricsTest"
 #include "mediadrm/DrmMetrics.h"
+#include "mediadrm/DrmMetricsConsumer.h"
 
 #include <android/hardware/drm/1.0/types.h>
 #include <android/hardware/drm/1.1/types.h>
@@ -58,8 +59,9 @@
 TEST_F(MediaDrmMetricsTest, EmptySuccess) {
   MediaDrmMetrics metrics;
   PersistableBundle bundle;
+  DrmMetricsConsumer consumer(&bundle);
 
-  metrics.Export(&bundle);
+  consumer.consumeFrameworkMetrics(metrics);
   EXPECT_TRUE(bundle.empty());
 }
 
@@ -85,8 +87,9 @@
   metrics.mEventCounter.Increment(EventType::PROVISION_REQUIRED);
 
   PersistableBundle bundle;
+  DrmMetricsConsumer consumer(&bundle);
 
-  metrics.Export(&bundle);
+  consumer.consumeFrameworkMetrics(metrics);
   EXPECT_EQ(11U, bundle.size());
 
   // Verify the list of pairs of int64 metrics.
@@ -174,7 +177,8 @@
   metrics.SetSessionEnd(sessionId1);
 
   PersistableBundle bundle;
-  metrics.Export(&bundle);
+  DrmMetricsConsumer consumer(&bundle);
+  consumer.consumeFrameworkMetrics(metrics);
   EXPECT_EQ(35U, bundle.size());
 
   // Verify the list of pairs of int64 metrics.
@@ -421,7 +425,7 @@
   hidl_vec<DrmMetricGroup> hidlMetricGroups;
   PersistableBundle bundleMetricGroups;
 
-  ASSERT_EQ(OK, MediaDrmMetrics::HidlMetricsToBundle(hidlMetricGroups, &bundleMetricGroups));
+  ASSERT_EQ(OK, DrmMetricsConsumer::HidlMetricsToBundle(hidlMetricGroups, &bundleMetricGroups));
   ASSERT_EQ(0U, bundleMetricGroups.size());
 }
 
@@ -441,7 +445,7 @@
           } } };
 
   PersistableBundle bundleMetricGroups;
-  ASSERT_EQ(OK, MediaDrmMetrics::HidlMetricsToBundle(hidl_vec<DrmMetricGroup>({hidlMetricGroup}),
+  ASSERT_EQ(OK, DrmMetricsConsumer::HidlMetricsToBundle(hidl_vec<DrmMetricGroup>({hidlMetricGroup}),
                                                      &bundleMetricGroups));
   ASSERT_EQ(1U, bundleMetricGroups.size());
   PersistableBundle bundleMetricGroup;