Loading services/mediametrics/MediaMetricsService.cpp +3 −1 Original line number Diff line number Diff line Loading @@ -113,6 +113,7 @@ status_t MediaMetricsService::submitInternal(mediametrics::Item *item, bool rele case AID_MEDIA_CODEC: case AID_MEDIA_EX: case AID_MEDIA_DRM: // case AID_SHELL: // DEBUG ONLY - used for mediametrics_tests to add new keys case AID_SYSTEM: // trusted source, only override default values isTrusted = true; Loading Loading @@ -145,9 +146,10 @@ status_t MediaMetricsService::submitInternal(mediametrics::Item *item, bool rele } } ALOGV("%s: given uid %d; sanitized uid: %d sanitized pkg: %s " ALOGV("%s: isTrusted:%d given uid %d; sanitized uid: %d sanitized pkg: %s " "sanitized pkg version: %lld", __func__, (int)isTrusted, uid_given, item->getUid(), item->getPkgName().c_str(), (long long)item->getPkgVersionCode()); Loading services/mediametrics/TimeMachine.h +19 −0 Original line number Diff line number Diff line Loading @@ -124,12 +124,23 @@ private: T&& e, int64_t time = 0) { if (time == 0) time = systemTime(SYSTEM_TIME_BOOTTIME); mLastModificationTime = time; if (mPropertyMap.size() >= kKeyMaxProperties && !mPropertyMap.count(property)) { ALOGV("%s: too many properties, rejecting %s", __func__, property.c_str()); return; } auto& timeSequence = mPropertyMap[property]; Elem el{std::forward<T>(e)}; if (timeSequence.empty() // no elements || property.back() == AMEDIAMETRICS_PROP_SUFFIX_CHAR_DUPLICATES_ALLOWED || timeSequence.rbegin()->second != el) { // value changed timeSequence.emplace(time, std::move(el)); if (timeSequence.size() > kTimeSequenceMaxElements) { ALOGV("%s: restricting maximum elements (discarding oldest) for %s", __func__, property.c_str()); timeSequence.erase(timeSequence.begin()); } } } Loading Loading @@ -188,6 +199,8 @@ private: using History = std::map<std::string /* key */, std::shared_ptr<KeyHistory>>; static inline constexpr size_t kTimeSequenceMaxElements = 100; static inline constexpr size_t kKeyMaxProperties = 100; static inline constexpr size_t kKeyLowWaterMark = 500; static inline constexpr size_t kKeyHighWaterMark = 1000; Loading Loading @@ -239,6 +252,9 @@ public: const int64_t time = item->getTimestamp(); const std::string &key = item->getKey(); ALOGV("%s(%zu, %zu): key: %s isTrusted:%d size:%zu", __func__, mKeyLowWaterMark, mKeyHighWaterMark, key.c_str(), (int)isTrusted, item->count()); std::shared_ptr<KeyHistory> keyHistory; { std::vector<std::any> garbage; Loading Loading @@ -446,6 +462,9 @@ private: /** * Garbage collects if the TimeMachine size exceeds the high water mark. * * This GC operation limits the number of keys stored (not the size of properties * stored in each key). * * \param garbage a type-erased vector of elements to be destroyed * outside of lock. Move large items to be destroyed here. * Loading services/mediametrics/TransactionLog.h +1 −1 Original line number Diff line number Diff line Loading @@ -264,7 +264,7 @@ private: return ret; } const size_t mLowWaterMark = kLogItemsHighWater; const size_t mLowWaterMark = kLogItemsLowWater; const size_t mHighWaterMark = kLogItemsHighWater; mutable std::mutex mLock; Loading services/mediametrics/tests/mediametrics_tests.cpp +18 −0 Original line number Diff line number Diff line Loading @@ -846,3 +846,21 @@ TEST(mediametrics_tests, audio_analytics_dump) { ASSERT_EQ(ll, (int32_t) countNewlines(s.c_str())); } } #if 0 // Stress test code for garbage collection, you need to enable AID_SHELL as trusted to run // in MediaMetricsService.cpp. // // TODO: Make a dedicated stress test. // TEST(mediametrics_tests, gc_same_key) { // random keys ignored when empty for (int i = 0; i < 10000000; ++i) { std::unique_ptr<mediametrics::Item> test_key(mediametrics::Item::create("audio.zzz.123")); test_key->set("event#", "hello"); test_key->set("value", (int)10); test_key->selfrecord(); } //mediaMetrics->dump(fileno(stdout), {} /* args */); } #endif Loading
services/mediametrics/MediaMetricsService.cpp +3 −1 Original line number Diff line number Diff line Loading @@ -113,6 +113,7 @@ status_t MediaMetricsService::submitInternal(mediametrics::Item *item, bool rele case AID_MEDIA_CODEC: case AID_MEDIA_EX: case AID_MEDIA_DRM: // case AID_SHELL: // DEBUG ONLY - used for mediametrics_tests to add new keys case AID_SYSTEM: // trusted source, only override default values isTrusted = true; Loading Loading @@ -145,9 +146,10 @@ status_t MediaMetricsService::submitInternal(mediametrics::Item *item, bool rele } } ALOGV("%s: given uid %d; sanitized uid: %d sanitized pkg: %s " ALOGV("%s: isTrusted:%d given uid %d; sanitized uid: %d sanitized pkg: %s " "sanitized pkg version: %lld", __func__, (int)isTrusted, uid_given, item->getUid(), item->getPkgName().c_str(), (long long)item->getPkgVersionCode()); Loading
services/mediametrics/TimeMachine.h +19 −0 Original line number Diff line number Diff line Loading @@ -124,12 +124,23 @@ private: T&& e, int64_t time = 0) { if (time == 0) time = systemTime(SYSTEM_TIME_BOOTTIME); mLastModificationTime = time; if (mPropertyMap.size() >= kKeyMaxProperties && !mPropertyMap.count(property)) { ALOGV("%s: too many properties, rejecting %s", __func__, property.c_str()); return; } auto& timeSequence = mPropertyMap[property]; Elem el{std::forward<T>(e)}; if (timeSequence.empty() // no elements || property.back() == AMEDIAMETRICS_PROP_SUFFIX_CHAR_DUPLICATES_ALLOWED || timeSequence.rbegin()->second != el) { // value changed timeSequence.emplace(time, std::move(el)); if (timeSequence.size() > kTimeSequenceMaxElements) { ALOGV("%s: restricting maximum elements (discarding oldest) for %s", __func__, property.c_str()); timeSequence.erase(timeSequence.begin()); } } } Loading Loading @@ -188,6 +199,8 @@ private: using History = std::map<std::string /* key */, std::shared_ptr<KeyHistory>>; static inline constexpr size_t kTimeSequenceMaxElements = 100; static inline constexpr size_t kKeyMaxProperties = 100; static inline constexpr size_t kKeyLowWaterMark = 500; static inline constexpr size_t kKeyHighWaterMark = 1000; Loading Loading @@ -239,6 +252,9 @@ public: const int64_t time = item->getTimestamp(); const std::string &key = item->getKey(); ALOGV("%s(%zu, %zu): key: %s isTrusted:%d size:%zu", __func__, mKeyLowWaterMark, mKeyHighWaterMark, key.c_str(), (int)isTrusted, item->count()); std::shared_ptr<KeyHistory> keyHistory; { std::vector<std::any> garbage; Loading Loading @@ -446,6 +462,9 @@ private: /** * Garbage collects if the TimeMachine size exceeds the high water mark. * * This GC operation limits the number of keys stored (not the size of properties * stored in each key). * * \param garbage a type-erased vector of elements to be destroyed * outside of lock. Move large items to be destroyed here. * Loading
services/mediametrics/TransactionLog.h +1 −1 Original line number Diff line number Diff line Loading @@ -264,7 +264,7 @@ private: return ret; } const size_t mLowWaterMark = kLogItemsHighWater; const size_t mLowWaterMark = kLogItemsLowWater; const size_t mHighWaterMark = kLogItemsHighWater; mutable std::mutex mLock; Loading
services/mediametrics/tests/mediametrics_tests.cpp +18 −0 Original line number Diff line number Diff line Loading @@ -846,3 +846,21 @@ TEST(mediametrics_tests, audio_analytics_dump) { ASSERT_EQ(ll, (int32_t) countNewlines(s.c_str())); } } #if 0 // Stress test code for garbage collection, you need to enable AID_SHELL as trusted to run // in MediaMetricsService.cpp. // // TODO: Make a dedicated stress test. // TEST(mediametrics_tests, gc_same_key) { // random keys ignored when empty for (int i = 0; i < 10000000; ++i) { std::unique_ptr<mediametrics::Item> test_key(mediametrics::Item::create("audio.zzz.123")); test_key->set("event#", "hello"); test_key->set("value", (int)10); test_key->selfrecord(); } //mediaMetrics->dump(fileno(stdout), {} /* args */); } #endif