Loading drm/libmediadrm/Android.bp +9 −7 Original line number Diff line number Diff line Loading @@ -65,6 +65,7 @@ cc_library_shared { "liblog", "libmediametrics", "libprotobuf-cpp-lite", "libstagefright_foundation", "libutils", ], cflags: [ Loading Loading @@ -97,6 +98,7 @@ cc_library_shared { "liblog", "libmediametrics", "libprotobuf-cpp-full", "libstagefright_foundation", "libutils", ], cflags: [ Loading drm/libmediadrm/DrmHal.cpp +30 −16 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ #include <media/drm/DrmAPI.h> #include <media/stagefright/foundation/ADebug.h> #include <media/stagefright/foundation/AString.h> #include <media/stagefright/foundation/base64.h> #include <media/stagefright/foundation/hexdump.h> #include <media/stagefright/MediaErrors.h> #include <mediadrm/DrmHal.h> Loading Loading @@ -63,8 +64,26 @@ namespace { // This constant corresponds to the PROPERTY_DEVICE_UNIQUE_ID constant // in the MediaDrm API. constexpr char kPropertyDeviceUniqueId[] = "deviceUniqueId"; constexpr char kEqualsSign[] = "="; template<typename T> std::string toBase64StringNoPad(const T* data, size_t size) { if (size == 0) { return ""; } CHECK(sizeof(data[0] == 1)); android::AString outputString; encodeBase64(data, size, &outputString); // Remove trailing equals padding if it exists. while (outputString.size() > 0 && outputString.endsWith(kEqualsSign)) { outputString.erase(outputString.size() - 1, 1); } return std::string(outputString.c_str(), outputString.size()); } } // anonymous namespace namespace android { Loading Loading @@ -101,15 +120,6 @@ static hidl_string toHidlString(const String8& string) { return hidl_string(string.string()); } std::string toHexString(const std::string& str) { std::ostringstream out; out << std::hex << std::setfill('0'); for (size_t i = 0; i < str.size(); i++) { out << std::setw(2) << (int)(str[i]); } return out.str(); } static DrmPlugin::SecurityLevel toSecurityLevel(SecurityLevel level) { switch(level) { case SecurityLevel::SW_SECURE_CRYPTO: Loading Loading @@ -340,6 +350,7 @@ Vector<sp<IDrmFactory>> DrmHal::makeDrmFactories() { sp<IDrmPlugin> DrmHal::makeDrmPlugin(const sp<IDrmFactory>& factory, const uint8_t uuid[16], const String8& appPackageName) { mAppPackageName = appPackageName; mMetrics.SetAppPackageName(appPackageName); sp<IDrmPlugin> plugin; Loading Loading @@ -1353,9 +1364,10 @@ void DrmHal::reportFrameworkMetrics() const if (result != OK) { ALOGE("Failed to serialize framework metrics: %d", result); } serializedMetrics = toHexString(serializedMetrics); if (!serializedMetrics.empty()) { item.setCString("serialized_metrics", serializedMetrics.c_str()); std::string b64EncodedMetrics = toBase64StringNoPad(serializedMetrics.data(), serializedMetrics.size()); if (!b64EncodedMetrics.empty()) { item.setCString("serialized_metrics", b64EncodedMetrics.c_str()); } if (!item.selfrecord()) { ALOGE("Failed to self record framework metrics"); Loading @@ -1364,14 +1376,16 @@ void DrmHal::reportFrameworkMetrics() const void DrmHal::reportPluginMetrics() const { Vector<uint8_t> metrics; Vector<uint8_t> metricsVector; String8 vendor; String8 description; if (getPropertyStringInternal(String8("vendor"), vendor) == OK && getPropertyStringInternal(String8("description"), description) == OK && getPropertyByteArrayInternal(String8("metrics"), metrics) == OK) { status_t res = android::reportDrmPluginMetrics( metrics, vendor, description); getPropertyByteArrayInternal(String8("metrics"), metricsVector) == OK) { std::string metricsString = toBase64StringNoPad(metricsVector.array(), metricsVector.size()); status_t res = android::reportDrmPluginMetrics(metricsString, vendor, description, mAppPackageName); if (res != OK) { ALOGE("Metrics were retrieved but could not be reported: %d", res); } Loading drm/libmediadrm/PluginMetricsReporting.cpp +17 −67 Original line number Diff line number Diff line Loading @@ -16,80 +16,35 @@ //#define LOG_NDEBUG 0 #define LOG_TAG "PluginMetricsReporting" #include <utils/Log.h> #include <inttypes.h> #include <media/PluginMetricsReporting.h> #include <inttypes.h> #include <media/MediaAnalyticsItem.h> #include <utils/Log.h> #include "protos/metrics.pb.h" namespace android { namespace { using android::drm_metrics::MetricsGroup; using android::drm_metrics::MetricsGroup_Metric; using android::drm_metrics::MetricsGroup_Metric_MetricValue; constexpr char kSerializedMetricsField[] = "serialized_metrics"; const char* const kParentAttribute = "/parent/external"; status_t reportMetricsGroup(const MetricsGroup& metricsGroup, const String8& batchName, const int64_t* parentId) { MediaAnalyticsItem analyticsItem(batchName.c_str()); status_t reportVendorMetrics(const std::string& metrics, const String8& name, const String8& appPackageName) { MediaAnalyticsItem analyticsItem(name.c_str()); analyticsItem.generateSessionID(); int64_t sessionId = analyticsItem.getSessionID(); if (parentId != NULL) { analyticsItem.setInt64(kParentAttribute, *parentId); } // Report the package name. if (metricsGroup.has_app_package_name()) { std::string app_package_name(metricsGroup.app_package_name().c_str(), metricsGroup.app_package_name().size()); std::string app_package_name(appPackageName.c_str(), appPackageName.size()); analyticsItem.setPkgName(app_package_name); } for (int i = 0; i < metricsGroup.metric_size(); ++i) { const MetricsGroup_Metric& metric = metricsGroup.metric(i); if (!metric.has_name()) { ALOGE("Metric with no name."); return BAD_VALUE; } if (!metric.has_value()) { ALOGE("Metric with no value."); return BAD_VALUE; } const MetricsGroup_Metric_MetricValue& value = metric.value(); if (value.has_int_value()) { analyticsItem.setInt64(metric.name().c_str(), value.int_value()); } else if (value.has_double_value()) { analyticsItem.setDouble(metric.name().c_str(), value.double_value()); } else if (value.has_string_value()) { analyticsItem.setCString(metric.name().c_str(), value.string_value().c_str()); } else { ALOGE("Metric Value with no actual value."); return BAD_VALUE; } if (metrics.size() > 0) { analyticsItem.setCString(kSerializedMetricsField, metrics.c_str()); } if (!analyticsItem.selfrecord()) { ALOGE("selfrecord() returned false. sessioId %" PRId64, sessionId); } for (int i = 0; i < metricsGroup.metric_sub_group_size(); ++i) { const MetricsGroup& subGroup = metricsGroup.metric_sub_group(i); status_t res = reportMetricsGroup(subGroup, batchName, &sessionId); if (res != OK) { return res; } ALOGE("selfrecord() returned false. sessioId %" PRId64, analyticsItem.getSessionID()); } return OK; Loading @@ -111,21 +66,16 @@ String8 sanitize(const String8& input) { } // namespace status_t reportDrmPluginMetrics(const Vector<uint8_t>& serializedMetrics, status_t reportDrmPluginMetrics(const std::string& b64EncodedMetrics, const String8& vendor, const String8& description) { MetricsGroup root_metrics_group; if (!root_metrics_group.ParseFromArray(serializedMetrics.array(), serializedMetrics.size())) { ALOGE("Failure to parse."); return BAD_VALUE; } const String8& description, const String8& appPackageName) { String8 name = String8::format("drm.vendor.%s.%s", sanitize(vendor).c_str(), sanitize(description).c_str()); return reportMetricsGroup(root_metrics_group, name, NULL); return reportVendorMetrics(b64EncodedMetrics, name, appPackageName); } } // namespace android drm/libmediadrm/protos/metrics.proto +7 −34 Original line number Diff line number Diff line Loading @@ -18,33 +18,6 @@ syntax = "proto2"; package android.drm_metrics; // The MetricsGroup is a collection of metric name/value pair instances // that can be serialized and provided to a caller. message MetricsGroup { message Metric { message MetricValue { // Exactly one of the following values must be set. optional int64 int_value = 1; optional double double_value = 2; optional string string_value = 3; } // The name of the metric. Must be valid UTF-8. Required. optional string name = 1; // The value of the metric. Required. optional MetricValue value = 2; } // The list of name/value pairs of metrics. repeated Metric metric = 1; // Allow multiple sub groups of metrics. repeated MetricsGroup metric_sub_group = 2; // Name of the application package associated with the metrics. optional string app_package_name = 3; } // This message contains the specific metrics captured by DrmMetrics. It is // used for serializing and logging metrics. Loading Loading @@ -72,7 +45,7 @@ message DrmFrameworkMetrics { // The Counter message is used to store a count value with an associated // Attribute. message Counter { optional int64 count = 1; optional uint64 count = 1; // Represents the attributes associated with this counter instance. optional Attributes attributes = 2; } Loading @@ -80,11 +53,11 @@ message DrmFrameworkMetrics { // The DistributionMetric is meant to capture the moments of a normally // distributed (or approximately normal) value. message DistributionMetric { optional double min = 1; optional double max = 2; optional double mean = 3; optional float min = 1; optional float max = 2; optional float mean = 3; optional double variance = 4; optional double operation_count = 5; optional uint64 operation_count = 5; // Represents the attributes assocated with this distribution metric // instance. Loading @@ -93,9 +66,9 @@ message DrmFrameworkMetrics { message SessionLifetime { // Start time of the session in milliseconds since epoch. optional int64 start_time_ms = 1; optional uint64 start_time_ms = 1; // End time of the session in milliseconds since epoch. optional int64 end_time_ms = 2; optional uint64 end_time_ms = 2; } // The count of open session operations. Each instance has a specific error Loading media/libmedia/include/media/DrmHal.h +1 −0 Original line number Diff line number Diff line Loading @@ -182,6 +182,7 @@ private: const Vector<sp<IDrmFactory>> mFactories; sp<IDrmPlugin> mPlugin; sp<drm::V1_1::IDrmPlugin> mPluginV1_1; String8 mAppPackageName; // Mutable to allow modification within GetPropertyByteArray. mutable MediaDrmMetrics mMetrics; Loading Loading
drm/libmediadrm/Android.bp +9 −7 Original line number Diff line number Diff line Loading @@ -65,6 +65,7 @@ cc_library_shared { "liblog", "libmediametrics", "libprotobuf-cpp-lite", "libstagefright_foundation", "libutils", ], cflags: [ Loading Loading @@ -97,6 +98,7 @@ cc_library_shared { "liblog", "libmediametrics", "libprotobuf-cpp-full", "libstagefright_foundation", "libutils", ], cflags: [ Loading
drm/libmediadrm/DrmHal.cpp +30 −16 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ #include <media/drm/DrmAPI.h> #include <media/stagefright/foundation/ADebug.h> #include <media/stagefright/foundation/AString.h> #include <media/stagefright/foundation/base64.h> #include <media/stagefright/foundation/hexdump.h> #include <media/stagefright/MediaErrors.h> #include <mediadrm/DrmHal.h> Loading Loading @@ -63,8 +64,26 @@ namespace { // This constant corresponds to the PROPERTY_DEVICE_UNIQUE_ID constant // in the MediaDrm API. constexpr char kPropertyDeviceUniqueId[] = "deviceUniqueId"; constexpr char kEqualsSign[] = "="; template<typename T> std::string toBase64StringNoPad(const T* data, size_t size) { if (size == 0) { return ""; } CHECK(sizeof(data[0] == 1)); android::AString outputString; encodeBase64(data, size, &outputString); // Remove trailing equals padding if it exists. while (outputString.size() > 0 && outputString.endsWith(kEqualsSign)) { outputString.erase(outputString.size() - 1, 1); } return std::string(outputString.c_str(), outputString.size()); } } // anonymous namespace namespace android { Loading Loading @@ -101,15 +120,6 @@ static hidl_string toHidlString(const String8& string) { return hidl_string(string.string()); } std::string toHexString(const std::string& str) { std::ostringstream out; out << std::hex << std::setfill('0'); for (size_t i = 0; i < str.size(); i++) { out << std::setw(2) << (int)(str[i]); } return out.str(); } static DrmPlugin::SecurityLevel toSecurityLevel(SecurityLevel level) { switch(level) { case SecurityLevel::SW_SECURE_CRYPTO: Loading Loading @@ -340,6 +350,7 @@ Vector<sp<IDrmFactory>> DrmHal::makeDrmFactories() { sp<IDrmPlugin> DrmHal::makeDrmPlugin(const sp<IDrmFactory>& factory, const uint8_t uuid[16], const String8& appPackageName) { mAppPackageName = appPackageName; mMetrics.SetAppPackageName(appPackageName); sp<IDrmPlugin> plugin; Loading Loading @@ -1353,9 +1364,10 @@ void DrmHal::reportFrameworkMetrics() const if (result != OK) { ALOGE("Failed to serialize framework metrics: %d", result); } serializedMetrics = toHexString(serializedMetrics); if (!serializedMetrics.empty()) { item.setCString("serialized_metrics", serializedMetrics.c_str()); std::string b64EncodedMetrics = toBase64StringNoPad(serializedMetrics.data(), serializedMetrics.size()); if (!b64EncodedMetrics.empty()) { item.setCString("serialized_metrics", b64EncodedMetrics.c_str()); } if (!item.selfrecord()) { ALOGE("Failed to self record framework metrics"); Loading @@ -1364,14 +1376,16 @@ void DrmHal::reportFrameworkMetrics() const void DrmHal::reportPluginMetrics() const { Vector<uint8_t> metrics; Vector<uint8_t> metricsVector; String8 vendor; String8 description; if (getPropertyStringInternal(String8("vendor"), vendor) == OK && getPropertyStringInternal(String8("description"), description) == OK && getPropertyByteArrayInternal(String8("metrics"), metrics) == OK) { status_t res = android::reportDrmPluginMetrics( metrics, vendor, description); getPropertyByteArrayInternal(String8("metrics"), metricsVector) == OK) { std::string metricsString = toBase64StringNoPad(metricsVector.array(), metricsVector.size()); status_t res = android::reportDrmPluginMetrics(metricsString, vendor, description, mAppPackageName); if (res != OK) { ALOGE("Metrics were retrieved but could not be reported: %d", res); } Loading
drm/libmediadrm/PluginMetricsReporting.cpp +17 −67 Original line number Diff line number Diff line Loading @@ -16,80 +16,35 @@ //#define LOG_NDEBUG 0 #define LOG_TAG "PluginMetricsReporting" #include <utils/Log.h> #include <inttypes.h> #include <media/PluginMetricsReporting.h> #include <inttypes.h> #include <media/MediaAnalyticsItem.h> #include <utils/Log.h> #include "protos/metrics.pb.h" namespace android { namespace { using android::drm_metrics::MetricsGroup; using android::drm_metrics::MetricsGroup_Metric; using android::drm_metrics::MetricsGroup_Metric_MetricValue; constexpr char kSerializedMetricsField[] = "serialized_metrics"; const char* const kParentAttribute = "/parent/external"; status_t reportMetricsGroup(const MetricsGroup& metricsGroup, const String8& batchName, const int64_t* parentId) { MediaAnalyticsItem analyticsItem(batchName.c_str()); status_t reportVendorMetrics(const std::string& metrics, const String8& name, const String8& appPackageName) { MediaAnalyticsItem analyticsItem(name.c_str()); analyticsItem.generateSessionID(); int64_t sessionId = analyticsItem.getSessionID(); if (parentId != NULL) { analyticsItem.setInt64(kParentAttribute, *parentId); } // Report the package name. if (metricsGroup.has_app_package_name()) { std::string app_package_name(metricsGroup.app_package_name().c_str(), metricsGroup.app_package_name().size()); std::string app_package_name(appPackageName.c_str(), appPackageName.size()); analyticsItem.setPkgName(app_package_name); } for (int i = 0; i < metricsGroup.metric_size(); ++i) { const MetricsGroup_Metric& metric = metricsGroup.metric(i); if (!metric.has_name()) { ALOGE("Metric with no name."); return BAD_VALUE; } if (!metric.has_value()) { ALOGE("Metric with no value."); return BAD_VALUE; } const MetricsGroup_Metric_MetricValue& value = metric.value(); if (value.has_int_value()) { analyticsItem.setInt64(metric.name().c_str(), value.int_value()); } else if (value.has_double_value()) { analyticsItem.setDouble(metric.name().c_str(), value.double_value()); } else if (value.has_string_value()) { analyticsItem.setCString(metric.name().c_str(), value.string_value().c_str()); } else { ALOGE("Metric Value with no actual value."); return BAD_VALUE; } if (metrics.size() > 0) { analyticsItem.setCString(kSerializedMetricsField, metrics.c_str()); } if (!analyticsItem.selfrecord()) { ALOGE("selfrecord() returned false. sessioId %" PRId64, sessionId); } for (int i = 0; i < metricsGroup.metric_sub_group_size(); ++i) { const MetricsGroup& subGroup = metricsGroup.metric_sub_group(i); status_t res = reportMetricsGroup(subGroup, batchName, &sessionId); if (res != OK) { return res; } ALOGE("selfrecord() returned false. sessioId %" PRId64, analyticsItem.getSessionID()); } return OK; Loading @@ -111,21 +66,16 @@ String8 sanitize(const String8& input) { } // namespace status_t reportDrmPluginMetrics(const Vector<uint8_t>& serializedMetrics, status_t reportDrmPluginMetrics(const std::string& b64EncodedMetrics, const String8& vendor, const String8& description) { MetricsGroup root_metrics_group; if (!root_metrics_group.ParseFromArray(serializedMetrics.array(), serializedMetrics.size())) { ALOGE("Failure to parse."); return BAD_VALUE; } const String8& description, const String8& appPackageName) { String8 name = String8::format("drm.vendor.%s.%s", sanitize(vendor).c_str(), sanitize(description).c_str()); return reportMetricsGroup(root_metrics_group, name, NULL); return reportVendorMetrics(b64EncodedMetrics, name, appPackageName); } } // namespace android
drm/libmediadrm/protos/metrics.proto +7 −34 Original line number Diff line number Diff line Loading @@ -18,33 +18,6 @@ syntax = "proto2"; package android.drm_metrics; // The MetricsGroup is a collection of metric name/value pair instances // that can be serialized and provided to a caller. message MetricsGroup { message Metric { message MetricValue { // Exactly one of the following values must be set. optional int64 int_value = 1; optional double double_value = 2; optional string string_value = 3; } // The name of the metric. Must be valid UTF-8. Required. optional string name = 1; // The value of the metric. Required. optional MetricValue value = 2; } // The list of name/value pairs of metrics. repeated Metric metric = 1; // Allow multiple sub groups of metrics. repeated MetricsGroup metric_sub_group = 2; // Name of the application package associated with the metrics. optional string app_package_name = 3; } // This message contains the specific metrics captured by DrmMetrics. It is // used for serializing and logging metrics. Loading Loading @@ -72,7 +45,7 @@ message DrmFrameworkMetrics { // The Counter message is used to store a count value with an associated // Attribute. message Counter { optional int64 count = 1; optional uint64 count = 1; // Represents the attributes associated with this counter instance. optional Attributes attributes = 2; } Loading @@ -80,11 +53,11 @@ message DrmFrameworkMetrics { // The DistributionMetric is meant to capture the moments of a normally // distributed (or approximately normal) value. message DistributionMetric { optional double min = 1; optional double max = 2; optional double mean = 3; optional float min = 1; optional float max = 2; optional float mean = 3; optional double variance = 4; optional double operation_count = 5; optional uint64 operation_count = 5; // Represents the attributes assocated with this distribution metric // instance. Loading @@ -93,9 +66,9 @@ message DrmFrameworkMetrics { message SessionLifetime { // Start time of the session in milliseconds since epoch. optional int64 start_time_ms = 1; optional uint64 start_time_ms = 1; // End time of the session in milliseconds since epoch. optional int64 end_time_ms = 2; optional uint64 end_time_ms = 2; } // The count of open session operations. Each instance has a specific error Loading
media/libmedia/include/media/DrmHal.h +1 −0 Original line number Diff line number Diff line Loading @@ -182,6 +182,7 @@ private: const Vector<sp<IDrmFactory>> mFactories; sp<IDrmPlugin> mPlugin; sp<drm::V1_1::IDrmPlugin> mPluginV1_1; String8 mAppPackageName; // Mutable to allow modification within GetPropertyByteArray. mutable MediaDrmMetrics mMetrics; Loading