Loading drm/libmediadrm/DrmHal.cpp +38 −6 Original line number Diff line number Diff line Loading @@ -54,6 +54,14 @@ using ::android::hardware::Void; using ::android::hidl::manager::V1_0::IServiceManager; using ::android::sp; namespace { // This constant corresponds to the PROPERTY_DEVICE_UNIQUE_ID constant // in the MediaDrm API. constexpr char kPropertyDeviceUniqueId[] = "deviceUniqueId"; } namespace android { #define INIT_CHECK() {if (mInitCheck != OK) return mInitCheck;} Loading Loading @@ -320,6 +328,7 @@ status_t DrmHal::setListener(const sp<IDrmClient>& listener) Return<void> DrmHal::sendEvent(EventType hEventType, const hidl_vec<uint8_t>& sessionId, const hidl_vec<uint8_t>& data) { mMetrics.mEventCounter.Increment(hEventType); mEventLock.lock(); sp<IDrmClient> listener = mListener; Loading Loading @@ -410,12 +419,21 @@ Return<void> DrmHal::sendKeysChange(const hidl_vec<uint8_t>& sessionId, break; } obj.writeInt32(type); mMetrics.mKeyStatusChangeCounter.Increment(keyStatus.type); } obj.writeInt32(hasNewUsableKey); Mutex::Autolock lock(mNotifyLock); listener->notify(DrmPlugin::kDrmPluginEventKeysChange, 0, &obj); } else { // There's no listener. But we still want to count the key change // events. size_t nKeys = keyStatusList.size(); for (size_t i = 0; i < nKeys; i++) { mMetrics.mKeyStatusChangeCounter.Increment(keyStatusList[i].type); } } return Void(); } Loading Loading @@ -539,8 +557,11 @@ status_t DrmHal::closeSession(Vector<uint8_t> const &sessionId) { } } reportMetrics(); return toStatusT(status); status_t response = toStatusT(status); mMetrics.mCloseSessionCounter.Increment(response); return response; } mMetrics.mCloseSessionCounter.Increment(DEAD_OBJECT); return DEAD_OBJECT; } Loading Loading @@ -646,6 +667,8 @@ status_t DrmHal::getKeyRequest(Vector<uint8_t> const &sessionId, status_t DrmHal::provideKeyResponse(Vector<uint8_t> const &sessionId, Vector<uint8_t> const &response, Vector<uint8_t> &keySetId) { Mutex::Autolock autoLock(mLock); EventTimer<status_t> keyResponseTimer(&mMetrics.mProvideKeyResponseTiming); INIT_CHECK(); DrmSessionManager::Instance()->useSession(sessionId); Loading @@ -661,8 +684,9 @@ status_t DrmHal::provideKeyResponse(Vector<uint8_t> const &sessionId, err = toStatusT(status); } ); return hResult.isOk() ? err : DEAD_OBJECT; err = hResult.isOk() ? err : DEAD_OBJECT; keyResponseTimer.SetAttribute(err); return err; } status_t DrmHal::removeKeys(Vector<uint8_t> const &keySetId) { Loading Loading @@ -726,7 +750,9 @@ status_t DrmHal::getProvisionRequest(String8 const &certType, } ); return hResult.isOk() ? err : DEAD_OBJECT; err = hResult.isOk() ? err : DEAD_OBJECT; mMetrics.mGetProvisionRequestCounter.Increment(err); return err; } status_t DrmHal::provideProvisionResponse(Vector<uint8_t> const &response, Loading @@ -747,7 +773,9 @@ status_t DrmHal::provideProvisionResponse(Vector<uint8_t> const &response, } ); return hResult.isOk() ? err : DEAD_OBJECT; err = hResult.isOk() ? err : DEAD_OBJECT; mMetrics.mProvideProvisionResponseCounter.Increment(err); return err; } status_t DrmHal::getSecureStops(List<Vector<uint8_t>> &secureStops) { Loading Loading @@ -969,7 +997,11 @@ status_t DrmHal::getPropertyByteArrayInternal(String8 const &name, Vector<uint8_ } ); return hResult.isOk() ? err : DEAD_OBJECT; err = hResult.isOk() ? err : DEAD_OBJECT; if (name == kPropertyDeviceUniqueId) { mMetrics.mGetDeviceUniqueIdCounter.Increment(err); } return err; } status_t DrmHal::setPropertyString(String8 const &name, String8 const &value ) const { Loading drm/libmediadrm/DrmMetrics.cpp +77 −2 Original line number Diff line number Diff line Loading @@ -14,13 +14,46 @@ * limitations under the License. */ #include <android-base/macros.h> #include <media/DrmMetrics.h> using ::android::hardware::drm::V1_0::EventType; using ::android::hardware::drm::V1_0::KeyStatusType; 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, android::MediaAnalyticsItem* item) { if (!item) { ALOGE("item was unexpectedly null."); return; } std::string success_count_name = counter.metric_name() + "/ok/count"; std::string error_count_name = counter.metric_name() + "/error/count"; counter.ExportValues( Loading @@ -37,12 +70,32 @@ void ExportCounterMetric(const android::CounterMetric<T>& counter, }); } template<typename T> void ExportCounterMetricWithAttributeNames( const android::CounterMetric<T>& counter, android::MediaAnalyticsItem* item) { if (!item) { ALOGE("item was unexpectedly null."); return; } counter.ExportValues( [&] (const T& attribute, const int64_t value) { std::string name = counter.metric_name() + "/" + GetAttributeName(attribute) + "/count"; item->setInt64(name.c_str(), value); }); } template<typename T> void ExportEventMetric(const android::EventMetric<T>& event, android::MediaAnalyticsItem* item) { if (!item) { ALOGE("item 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() + "/average_time_micros"; std::string timing_name = event.metric_name() + "/ok/average_time_micros"; event.ExportValues( [&] (const android::status_t& status, const android::EventStatistics& value) { Loading @@ -66,12 +119,34 @@ namespace android { MediaDrmMetrics::MediaDrmMetrics() : mOpenSessionCounter("/drm/mediadrm/open_session", "status"), mGetKeyRequestTiming("/drm/mediadrm/get_key_request", "status") { mCloseSessionCounter("/drm/mediadrm/close_session", "status"), mGetKeyRequestTiming("/drm/mediadrm/get_key_request", "status"), mProvideKeyResponseTiming("/drm/mediadrm/provide_key_response", "status"), mGetProvisionRequestCounter( "/drm/mediadrm/get_provision_request", "status"), mProvideProvisionResponseCounter( "/drm/mediadrm/provide_provision_response", "status"), mKeyStatusChangeCounter( "/drm/mediadrm/key_status_change", "key_status_type"), mEventCounter("/drm/mediadrm/event", "event_type"), mGetDeviceUniqueIdCounter( "/drm/mediadrm/get_device_unique_id", "status") { } void MediaDrmMetrics::Export(MediaAnalyticsItem* item) { if (!item) { ALOGE("item was unexpectedly null."); return; } ExportCounterMetric(mOpenSessionCounter, item); ExportCounterMetric(mCloseSessionCounter, item); ExportEventMetric(mGetKeyRequestTiming, item); ExportEventMetric(mProvideKeyResponseTiming, item); ExportCounterMetric(mGetProvisionRequestCounter, item); ExportCounterMetric(mProvideProvisionResponseCounter, item); ExportCounterMetricWithAttributeNames(mKeyStatusChangeCounter, item); ExportCounterMetricWithAttributeNames(mEventCounter, item); ExportCounterMetric(mGetDeviceUniqueIdCounter, item); } } // namespace android drm/libmediadrm/tests/Android.bp +17 −0 Original line number Diff line number Diff line Loading @@ -11,6 +11,23 @@ cc_test { ], } cc_test { name: "DrmMetrics_test", srcs: ["DrmMetrics_test.cpp"], shared_libs: [ "android.hardware.drm@1.0", "liblog", "libmediadrm", "libmediametrics", "libutils", ], include_dirs: ["frameworks/av/include/media"], cflags: [ "-Werror", "-Wall", ], } cc_test { name: "EventMetric_test", srcs: ["EventMetric_test.cpp"], Loading drm/libmediadrm/tests/DrmMetrics_test.cpp 0 → 100644 +191 −0 Original line number Diff line number Diff line /* * Copyright 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. */ #include <gtest/gtest.h> #include "DrmMetrics.h" using ::android::hardware::drm::V1_0::EventType; using ::android::hardware::drm::V1_0::KeyStatusType; namespace android { /** * Unit tests for the MediaDrmMetrics class. */ class MediaDrmMetricsTest : public ::testing::Test { }; TEST_F(MediaDrmMetricsTest, EmptySuccess) { MediaDrmMetrics metrics; MediaAnalyticsItem item; metrics.Export(&item); EXPECT_EQ(0, item.count()); } TEST_F(MediaDrmMetricsTest, AllValuesSuccessCounts) { MediaDrmMetrics metrics; metrics.mOpenSessionCounter.Increment(OK); metrics.mCloseSessionCounter.Increment(OK); { EventTimer<status_t> get_key_request_timer(&metrics.mGetKeyRequestTiming); EventTimer<status_t> provide_key_response_timer( &metrics.mProvideKeyResponseTiming); get_key_request_timer.SetAttribute(OK); provide_key_response_timer.SetAttribute(OK); } metrics.mGetProvisionRequestCounter.Increment(OK); metrics.mProvideProvisionResponseCounter.Increment(OK); metrics.mGetDeviceUniqueIdCounter.Increment(OK); metrics.mKeyStatusChangeCounter.Increment(KeyStatusType::USABLE); metrics.mEventCounter.Increment(EventType::PROVISION_REQUIRED); MediaAnalyticsItem item; metrics.Export(&item); EXPECT_EQ(11, item.count()); // Verify the list of pairs of int64 metrics. std::vector<std::pair<std::string, int64_t>> expected_values = { { "/drm/mediadrm/open_session/ok/count", 1 }, { "/drm/mediadrm/close_session/ok/count", 1 }, { "/drm/mediadrm/get_key_request/ok/count", 1 }, { "/drm/mediadrm/provide_key_response/ok/count", 1 }, { "/drm/mediadrm/get_provision_request/ok/count", 1 }, { "/drm/mediadrm/provide_provision_response/ok/count", 1 }, { "/drm/mediadrm/key_status_change/USABLE/count", 1 }, { "/drm/mediadrm/event/PROVISION_REQUIRED/count", 1 }, { "/drm/mediadrm/get_device_unique_id/ok/count", 1 }}; for (const auto& expected_pair : expected_values) { int64_t value = -1; EXPECT_TRUE(item.getInt64(expected_pair.first.c_str(), &value)) << "Failed to get " << expected_pair.first; EXPECT_EQ(expected_pair.second, value) << "Unexpected value for " << expected_pair.first; } // Validate timing values exist. int64_t value = -1; EXPECT_TRUE( item.getInt64("/drm/mediadrm/get_key_request/ok/average_time_micros", &value)); EXPECT_GE(value, 0); value = -1; EXPECT_TRUE( item.getInt64("/drm/mediadrm/provide_key_response/ok/average_time_micros", &value)); EXPECT_GE(value, 0); } TEST_F(MediaDrmMetricsTest, AllValuesFull) { MediaDrmMetrics metrics; metrics.mOpenSessionCounter.Increment(OK); metrics.mOpenSessionCounter.Increment(UNEXPECTED_NULL); metrics.mCloseSessionCounter.Increment(OK); metrics.mCloseSessionCounter.Increment(UNEXPECTED_NULL); for (status_t s : {OK, UNEXPECTED_NULL}) { { EventTimer<status_t> get_key_request_timer(&metrics.mGetKeyRequestTiming); EventTimer<status_t> provide_key_response_timer( &metrics.mProvideKeyResponseTiming); get_key_request_timer.SetAttribute(s); provide_key_response_timer.SetAttribute(s); } } metrics.mGetProvisionRequestCounter.Increment(OK); metrics.mGetProvisionRequestCounter.Increment(UNEXPECTED_NULL); metrics.mProvideProvisionResponseCounter.Increment(OK); metrics.mProvideProvisionResponseCounter.Increment(UNEXPECTED_NULL); metrics.mGetDeviceUniqueIdCounter.Increment(OK); metrics.mGetDeviceUniqueIdCounter.Increment(UNEXPECTED_NULL); metrics.mKeyStatusChangeCounter.Increment(KeyStatusType::USABLE); metrics.mKeyStatusChangeCounter.Increment(KeyStatusType::EXPIRED); metrics.mKeyStatusChangeCounter.Increment(KeyStatusType::OUTPUTNOTALLOWED); metrics.mKeyStatusChangeCounter.Increment(KeyStatusType::STATUSPENDING); metrics.mKeyStatusChangeCounter.Increment(KeyStatusType::INTERNALERROR); metrics.mEventCounter.Increment(EventType::PROVISION_REQUIRED); metrics.mEventCounter.Increment(EventType::KEY_NEEDED); metrics.mEventCounter.Increment(EventType::KEY_EXPIRED); metrics.mEventCounter.Increment(EventType::VENDOR_DEFINED); metrics.mEventCounter.Increment(EventType::SESSION_RECLAIMED); MediaAnalyticsItem item; metrics.Export(&item); EXPECT_EQ(26, item.count()); // Verify the list of pairs of int64 metrics. std::vector<std::pair<std::string, int64_t>> expected_values = { { "/drm/mediadrm/open_session/ok/count", 1 }, { "/drm/mediadrm/close_session/ok/count", 1 }, { "/drm/mediadrm/get_key_request/ok/count", 1 }, { "/drm/mediadrm/provide_key_response/ok/count", 1 }, { "/drm/mediadrm/get_provision_request/ok/count", 1 }, { "/drm/mediadrm/provide_provision_response/ok/count", 1 }, { "/drm/mediadrm/get_device_unique_id/ok/count", 1 }, { "/drm/mediadrm/open_session/error/count", 1 }, { "/drm/mediadrm/close_session/error/count", 1 }, { "/drm/mediadrm/get_key_request/error/count", 1 }, { "/drm/mediadrm/provide_key_response/error/count", 1 }, { "/drm/mediadrm/get_provision_request/error/count", 1 }, { "/drm/mediadrm/provide_provision_response/error/count", 1 }, { "/drm/mediadrm/get_device_unique_id/error/count", 1 }, { "/drm/mediadrm/key_status_change/USABLE/count", 1 }, { "/drm/mediadrm/key_status_change/EXPIRED/count", 1 }, { "/drm/mediadrm/key_status_change/OUTPUT_NOT_ALLOWED/count", 1 }, { "/drm/mediadrm/key_status_change/STATUS_PENDING/count", 1 }, { "/drm/mediadrm/key_status_change/INTERNAL_ERROR/count", 1 }, { "/drm/mediadrm/event/PROVISION_REQUIRED/count", 1 }, { "/drm/mediadrm/event/KEY_NEEDED/count", 1 }, { "/drm/mediadrm/event/KEY_EXPIRED/count", 1 }, { "/drm/mediadrm/event/VENDOR_DEFINED/count", 1 }, { "/drm/mediadrm/event/SESSION_RECLAIMED/count", 1 }}; for (const auto& expected_pair : expected_values) { int64_t value = -1; EXPECT_TRUE(item.getInt64(expected_pair.first.c_str(), &value)) << "Failed to get " << expected_pair.first; EXPECT_EQ(expected_pair.second, value) << "Unexpected value for " << expected_pair.first; } // Validate timing values exist. int64_t value = -1; std::string name = metrics.mGetKeyRequestTiming.metric_name() + "/ok/average_time_micros"; EXPECT_TRUE(item.getInt64(name.c_str(), &value)); EXPECT_GE(value, 0); value = -1; name = metrics.mProvideKeyResponseTiming.metric_name() + "/ok/average_time_micros"; EXPECT_TRUE(item.getInt64(name.c_str(), &value)); EXPECT_GE(value, 0); } } // namespace android media/libmedia/include/media/DrmHal.h +2 −1 Original line number Diff line number Diff line Loading @@ -181,7 +181,8 @@ private: sp<IDrmPlugin> mPlugin; sp<drm::V1_1::IDrmPlugin> mPluginV1_1; MediaDrmMetrics mMetrics; // Mutable to allow modification within GetPropertyByteArray. mutable MediaDrmMetrics mMetrics; Vector<Vector<uint8_t>> mOpenSessions; void closeOpenSessions(); Loading Loading
drm/libmediadrm/DrmHal.cpp +38 −6 Original line number Diff line number Diff line Loading @@ -54,6 +54,14 @@ using ::android::hardware::Void; using ::android::hidl::manager::V1_0::IServiceManager; using ::android::sp; namespace { // This constant corresponds to the PROPERTY_DEVICE_UNIQUE_ID constant // in the MediaDrm API. constexpr char kPropertyDeviceUniqueId[] = "deviceUniqueId"; } namespace android { #define INIT_CHECK() {if (mInitCheck != OK) return mInitCheck;} Loading Loading @@ -320,6 +328,7 @@ status_t DrmHal::setListener(const sp<IDrmClient>& listener) Return<void> DrmHal::sendEvent(EventType hEventType, const hidl_vec<uint8_t>& sessionId, const hidl_vec<uint8_t>& data) { mMetrics.mEventCounter.Increment(hEventType); mEventLock.lock(); sp<IDrmClient> listener = mListener; Loading Loading @@ -410,12 +419,21 @@ Return<void> DrmHal::sendKeysChange(const hidl_vec<uint8_t>& sessionId, break; } obj.writeInt32(type); mMetrics.mKeyStatusChangeCounter.Increment(keyStatus.type); } obj.writeInt32(hasNewUsableKey); Mutex::Autolock lock(mNotifyLock); listener->notify(DrmPlugin::kDrmPluginEventKeysChange, 0, &obj); } else { // There's no listener. But we still want to count the key change // events. size_t nKeys = keyStatusList.size(); for (size_t i = 0; i < nKeys; i++) { mMetrics.mKeyStatusChangeCounter.Increment(keyStatusList[i].type); } } return Void(); } Loading Loading @@ -539,8 +557,11 @@ status_t DrmHal::closeSession(Vector<uint8_t> const &sessionId) { } } reportMetrics(); return toStatusT(status); status_t response = toStatusT(status); mMetrics.mCloseSessionCounter.Increment(response); return response; } mMetrics.mCloseSessionCounter.Increment(DEAD_OBJECT); return DEAD_OBJECT; } Loading Loading @@ -646,6 +667,8 @@ status_t DrmHal::getKeyRequest(Vector<uint8_t> const &sessionId, status_t DrmHal::provideKeyResponse(Vector<uint8_t> const &sessionId, Vector<uint8_t> const &response, Vector<uint8_t> &keySetId) { Mutex::Autolock autoLock(mLock); EventTimer<status_t> keyResponseTimer(&mMetrics.mProvideKeyResponseTiming); INIT_CHECK(); DrmSessionManager::Instance()->useSession(sessionId); Loading @@ -661,8 +684,9 @@ status_t DrmHal::provideKeyResponse(Vector<uint8_t> const &sessionId, err = toStatusT(status); } ); return hResult.isOk() ? err : DEAD_OBJECT; err = hResult.isOk() ? err : DEAD_OBJECT; keyResponseTimer.SetAttribute(err); return err; } status_t DrmHal::removeKeys(Vector<uint8_t> const &keySetId) { Loading Loading @@ -726,7 +750,9 @@ status_t DrmHal::getProvisionRequest(String8 const &certType, } ); return hResult.isOk() ? err : DEAD_OBJECT; err = hResult.isOk() ? err : DEAD_OBJECT; mMetrics.mGetProvisionRequestCounter.Increment(err); return err; } status_t DrmHal::provideProvisionResponse(Vector<uint8_t> const &response, Loading @@ -747,7 +773,9 @@ status_t DrmHal::provideProvisionResponse(Vector<uint8_t> const &response, } ); return hResult.isOk() ? err : DEAD_OBJECT; err = hResult.isOk() ? err : DEAD_OBJECT; mMetrics.mProvideProvisionResponseCounter.Increment(err); return err; } status_t DrmHal::getSecureStops(List<Vector<uint8_t>> &secureStops) { Loading Loading @@ -969,7 +997,11 @@ status_t DrmHal::getPropertyByteArrayInternal(String8 const &name, Vector<uint8_ } ); return hResult.isOk() ? err : DEAD_OBJECT; err = hResult.isOk() ? err : DEAD_OBJECT; if (name == kPropertyDeviceUniqueId) { mMetrics.mGetDeviceUniqueIdCounter.Increment(err); } return err; } status_t DrmHal::setPropertyString(String8 const &name, String8 const &value ) const { Loading
drm/libmediadrm/DrmMetrics.cpp +77 −2 Original line number Diff line number Diff line Loading @@ -14,13 +14,46 @@ * limitations under the License. */ #include <android-base/macros.h> #include <media/DrmMetrics.h> using ::android::hardware::drm::V1_0::EventType; using ::android::hardware::drm::V1_0::KeyStatusType; 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, android::MediaAnalyticsItem* item) { if (!item) { ALOGE("item was unexpectedly null."); return; } std::string success_count_name = counter.metric_name() + "/ok/count"; std::string error_count_name = counter.metric_name() + "/error/count"; counter.ExportValues( Loading @@ -37,12 +70,32 @@ void ExportCounterMetric(const android::CounterMetric<T>& counter, }); } template<typename T> void ExportCounterMetricWithAttributeNames( const android::CounterMetric<T>& counter, android::MediaAnalyticsItem* item) { if (!item) { ALOGE("item was unexpectedly null."); return; } counter.ExportValues( [&] (const T& attribute, const int64_t value) { std::string name = counter.metric_name() + "/" + GetAttributeName(attribute) + "/count"; item->setInt64(name.c_str(), value); }); } template<typename T> void ExportEventMetric(const android::EventMetric<T>& event, android::MediaAnalyticsItem* item) { if (!item) { ALOGE("item 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() + "/average_time_micros"; std::string timing_name = event.metric_name() + "/ok/average_time_micros"; event.ExportValues( [&] (const android::status_t& status, const android::EventStatistics& value) { Loading @@ -66,12 +119,34 @@ namespace android { MediaDrmMetrics::MediaDrmMetrics() : mOpenSessionCounter("/drm/mediadrm/open_session", "status"), mGetKeyRequestTiming("/drm/mediadrm/get_key_request", "status") { mCloseSessionCounter("/drm/mediadrm/close_session", "status"), mGetKeyRequestTiming("/drm/mediadrm/get_key_request", "status"), mProvideKeyResponseTiming("/drm/mediadrm/provide_key_response", "status"), mGetProvisionRequestCounter( "/drm/mediadrm/get_provision_request", "status"), mProvideProvisionResponseCounter( "/drm/mediadrm/provide_provision_response", "status"), mKeyStatusChangeCounter( "/drm/mediadrm/key_status_change", "key_status_type"), mEventCounter("/drm/mediadrm/event", "event_type"), mGetDeviceUniqueIdCounter( "/drm/mediadrm/get_device_unique_id", "status") { } void MediaDrmMetrics::Export(MediaAnalyticsItem* item) { if (!item) { ALOGE("item was unexpectedly null."); return; } ExportCounterMetric(mOpenSessionCounter, item); ExportCounterMetric(mCloseSessionCounter, item); ExportEventMetric(mGetKeyRequestTiming, item); ExportEventMetric(mProvideKeyResponseTiming, item); ExportCounterMetric(mGetProvisionRequestCounter, item); ExportCounterMetric(mProvideProvisionResponseCounter, item); ExportCounterMetricWithAttributeNames(mKeyStatusChangeCounter, item); ExportCounterMetricWithAttributeNames(mEventCounter, item); ExportCounterMetric(mGetDeviceUniqueIdCounter, item); } } // namespace android
drm/libmediadrm/tests/Android.bp +17 −0 Original line number Diff line number Diff line Loading @@ -11,6 +11,23 @@ cc_test { ], } cc_test { name: "DrmMetrics_test", srcs: ["DrmMetrics_test.cpp"], shared_libs: [ "android.hardware.drm@1.0", "liblog", "libmediadrm", "libmediametrics", "libutils", ], include_dirs: ["frameworks/av/include/media"], cflags: [ "-Werror", "-Wall", ], } cc_test { name: "EventMetric_test", srcs: ["EventMetric_test.cpp"], Loading
drm/libmediadrm/tests/DrmMetrics_test.cpp 0 → 100644 +191 −0 Original line number Diff line number Diff line /* * Copyright 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. */ #include <gtest/gtest.h> #include "DrmMetrics.h" using ::android::hardware::drm::V1_0::EventType; using ::android::hardware::drm::V1_0::KeyStatusType; namespace android { /** * Unit tests for the MediaDrmMetrics class. */ class MediaDrmMetricsTest : public ::testing::Test { }; TEST_F(MediaDrmMetricsTest, EmptySuccess) { MediaDrmMetrics metrics; MediaAnalyticsItem item; metrics.Export(&item); EXPECT_EQ(0, item.count()); } TEST_F(MediaDrmMetricsTest, AllValuesSuccessCounts) { MediaDrmMetrics metrics; metrics.mOpenSessionCounter.Increment(OK); metrics.mCloseSessionCounter.Increment(OK); { EventTimer<status_t> get_key_request_timer(&metrics.mGetKeyRequestTiming); EventTimer<status_t> provide_key_response_timer( &metrics.mProvideKeyResponseTiming); get_key_request_timer.SetAttribute(OK); provide_key_response_timer.SetAttribute(OK); } metrics.mGetProvisionRequestCounter.Increment(OK); metrics.mProvideProvisionResponseCounter.Increment(OK); metrics.mGetDeviceUniqueIdCounter.Increment(OK); metrics.mKeyStatusChangeCounter.Increment(KeyStatusType::USABLE); metrics.mEventCounter.Increment(EventType::PROVISION_REQUIRED); MediaAnalyticsItem item; metrics.Export(&item); EXPECT_EQ(11, item.count()); // Verify the list of pairs of int64 metrics. std::vector<std::pair<std::string, int64_t>> expected_values = { { "/drm/mediadrm/open_session/ok/count", 1 }, { "/drm/mediadrm/close_session/ok/count", 1 }, { "/drm/mediadrm/get_key_request/ok/count", 1 }, { "/drm/mediadrm/provide_key_response/ok/count", 1 }, { "/drm/mediadrm/get_provision_request/ok/count", 1 }, { "/drm/mediadrm/provide_provision_response/ok/count", 1 }, { "/drm/mediadrm/key_status_change/USABLE/count", 1 }, { "/drm/mediadrm/event/PROVISION_REQUIRED/count", 1 }, { "/drm/mediadrm/get_device_unique_id/ok/count", 1 }}; for (const auto& expected_pair : expected_values) { int64_t value = -1; EXPECT_TRUE(item.getInt64(expected_pair.first.c_str(), &value)) << "Failed to get " << expected_pair.first; EXPECT_EQ(expected_pair.second, value) << "Unexpected value for " << expected_pair.first; } // Validate timing values exist. int64_t value = -1; EXPECT_TRUE( item.getInt64("/drm/mediadrm/get_key_request/ok/average_time_micros", &value)); EXPECT_GE(value, 0); value = -1; EXPECT_TRUE( item.getInt64("/drm/mediadrm/provide_key_response/ok/average_time_micros", &value)); EXPECT_GE(value, 0); } TEST_F(MediaDrmMetricsTest, AllValuesFull) { MediaDrmMetrics metrics; metrics.mOpenSessionCounter.Increment(OK); metrics.mOpenSessionCounter.Increment(UNEXPECTED_NULL); metrics.mCloseSessionCounter.Increment(OK); metrics.mCloseSessionCounter.Increment(UNEXPECTED_NULL); for (status_t s : {OK, UNEXPECTED_NULL}) { { EventTimer<status_t> get_key_request_timer(&metrics.mGetKeyRequestTiming); EventTimer<status_t> provide_key_response_timer( &metrics.mProvideKeyResponseTiming); get_key_request_timer.SetAttribute(s); provide_key_response_timer.SetAttribute(s); } } metrics.mGetProvisionRequestCounter.Increment(OK); metrics.mGetProvisionRequestCounter.Increment(UNEXPECTED_NULL); metrics.mProvideProvisionResponseCounter.Increment(OK); metrics.mProvideProvisionResponseCounter.Increment(UNEXPECTED_NULL); metrics.mGetDeviceUniqueIdCounter.Increment(OK); metrics.mGetDeviceUniqueIdCounter.Increment(UNEXPECTED_NULL); metrics.mKeyStatusChangeCounter.Increment(KeyStatusType::USABLE); metrics.mKeyStatusChangeCounter.Increment(KeyStatusType::EXPIRED); metrics.mKeyStatusChangeCounter.Increment(KeyStatusType::OUTPUTNOTALLOWED); metrics.mKeyStatusChangeCounter.Increment(KeyStatusType::STATUSPENDING); metrics.mKeyStatusChangeCounter.Increment(KeyStatusType::INTERNALERROR); metrics.mEventCounter.Increment(EventType::PROVISION_REQUIRED); metrics.mEventCounter.Increment(EventType::KEY_NEEDED); metrics.mEventCounter.Increment(EventType::KEY_EXPIRED); metrics.mEventCounter.Increment(EventType::VENDOR_DEFINED); metrics.mEventCounter.Increment(EventType::SESSION_RECLAIMED); MediaAnalyticsItem item; metrics.Export(&item); EXPECT_EQ(26, item.count()); // Verify the list of pairs of int64 metrics. std::vector<std::pair<std::string, int64_t>> expected_values = { { "/drm/mediadrm/open_session/ok/count", 1 }, { "/drm/mediadrm/close_session/ok/count", 1 }, { "/drm/mediadrm/get_key_request/ok/count", 1 }, { "/drm/mediadrm/provide_key_response/ok/count", 1 }, { "/drm/mediadrm/get_provision_request/ok/count", 1 }, { "/drm/mediadrm/provide_provision_response/ok/count", 1 }, { "/drm/mediadrm/get_device_unique_id/ok/count", 1 }, { "/drm/mediadrm/open_session/error/count", 1 }, { "/drm/mediadrm/close_session/error/count", 1 }, { "/drm/mediadrm/get_key_request/error/count", 1 }, { "/drm/mediadrm/provide_key_response/error/count", 1 }, { "/drm/mediadrm/get_provision_request/error/count", 1 }, { "/drm/mediadrm/provide_provision_response/error/count", 1 }, { "/drm/mediadrm/get_device_unique_id/error/count", 1 }, { "/drm/mediadrm/key_status_change/USABLE/count", 1 }, { "/drm/mediadrm/key_status_change/EXPIRED/count", 1 }, { "/drm/mediadrm/key_status_change/OUTPUT_NOT_ALLOWED/count", 1 }, { "/drm/mediadrm/key_status_change/STATUS_PENDING/count", 1 }, { "/drm/mediadrm/key_status_change/INTERNAL_ERROR/count", 1 }, { "/drm/mediadrm/event/PROVISION_REQUIRED/count", 1 }, { "/drm/mediadrm/event/KEY_NEEDED/count", 1 }, { "/drm/mediadrm/event/KEY_EXPIRED/count", 1 }, { "/drm/mediadrm/event/VENDOR_DEFINED/count", 1 }, { "/drm/mediadrm/event/SESSION_RECLAIMED/count", 1 }}; for (const auto& expected_pair : expected_values) { int64_t value = -1; EXPECT_TRUE(item.getInt64(expected_pair.first.c_str(), &value)) << "Failed to get " << expected_pair.first; EXPECT_EQ(expected_pair.second, value) << "Unexpected value for " << expected_pair.first; } // Validate timing values exist. int64_t value = -1; std::string name = metrics.mGetKeyRequestTiming.metric_name() + "/ok/average_time_micros"; EXPECT_TRUE(item.getInt64(name.c_str(), &value)); EXPECT_GE(value, 0); value = -1; name = metrics.mProvideKeyResponseTiming.metric_name() + "/ok/average_time_micros"; EXPECT_TRUE(item.getInt64(name.c_str(), &value)); EXPECT_GE(value, 0); } } // namespace android
media/libmedia/include/media/DrmHal.h +2 −1 Original line number Diff line number Diff line Loading @@ -181,7 +181,8 @@ private: sp<IDrmPlugin> mPlugin; sp<drm::V1_1::IDrmPlugin> mPluginV1_1; MediaDrmMetrics mMetrics; // Mutable to allow modification within GetPropertyByteArray. mutable MediaDrmMetrics mMetrics; Vector<Vector<uint8_t>> mOpenSessions; void closeOpenSessions(); Loading