Loading media/libmediametrics/include/media/MediaMetricsItem.h +2 −2 Original line number Original line Diff line number Diff line Loading @@ -208,11 +208,11 @@ static inline constexpr const char *BUNDLE_PROPERTY_COUNT = "_propertyCount"; template<size_t N> template<size_t N> static inline bool startsWith(const std::string &s, const char (&comp)[N]) { static inline bool startsWith(const std::string &s, const char (&comp)[N]) { return !strncmp(s.c_str(), comp, N - 1); return !strncmp(s.c_str(), comp, N - 1); // last char is null termination } } static inline bool startsWith(const std::string& s, const std::string& comp) { static inline bool startsWith(const std::string& s, const std::string& comp) { return !strncmp(s.c_str(), comp.c_str(), comp.size() - 1); return !strncmp(s.c_str(), comp.c_str(), comp.size()); } } /** /** Loading services/mediametrics/AnalyticsState.h +8 −5 Original line number Original line Diff line number Diff line Loading @@ -84,8 +84,11 @@ public: * delivered. * delivered. * * * \param lines the maximum number of lines in the string returned. * \param lines the maximum number of lines in the string returned. * \param sinceNs the nanoseconds since Unix epoch to start dump (0 shows all) * \param prefix the desired key prefix to match (nullptr shows all) */ */ std::pair<std::string, int32_t> dump(int32_t lines = INT32_MAX) const { std::pair<std::string, int32_t> dump( int32_t lines = INT32_MAX, int64_t sinceNs = 0, const char *prefix = nullptr) const { std::stringstream ss; std::stringstream ss; int32_t ll = lines; int32_t ll = lines; Loading @@ -94,8 +97,8 @@ public: --ll; --ll; } } if (ll > 0) { if (ll > 0) { auto [s, l] = mTransactionLog.dump(ll); auto [s, l] = mTransactionLog.dump(ll, sinceNs, prefix); ss << s; ss << std::move(s); ll -= l; ll -= l; } } if (ll > 0) { if (ll > 0) { Loading @@ -103,8 +106,8 @@ public: --ll; --ll; } } if (ll > 0) { if (ll > 0) { auto [s, l] = mTimeMachine.dump(ll); auto [s, l] = mTimeMachine.dump(ll, sinceNs, prefix); ss << s; ss << std::move(s); ll -= l; ll -= l; } } return { ss.str(), lines - ll }; return { ss.str(), lines - ll }; Loading services/mediametrics/AudioAnalytics.cpp +6 −5 Original line number Original line Diff line number Diff line Loading @@ -107,14 +107,15 @@ status_t AudioAnalytics::submit( return NO_ERROR; return NO_ERROR; } } std::pair<std::string, int32_t> AudioAnalytics::dump(int32_t lines) const std::pair<std::string, int32_t> AudioAnalytics::dump( int32_t lines, int64_t sinceNs, const char *prefix) const { { std::stringstream ss; std::stringstream ss; int32_t ll = lines; int32_t ll = lines; if (ll > 0) { if (ll > 0) { auto [s, l] = mAnalyticsState->dump(ll); auto [s, l] = mAnalyticsState->dump(ll, sinceNs, prefix); ss << s; ss << std::move(s); ll -= l; ll -= l; } } if (ll > 0) { if (ll > 0) { Loading @@ -122,8 +123,8 @@ std::pair<std::string, int32_t> AudioAnalytics::dump(int32_t lines) const --ll; --ll; } } if (ll > 0) { if (ll > 0) { auto [s, l] = mPreviousAnalyticsState->dump(ll); auto [s, l] = mPreviousAnalyticsState->dump(ll, sinceNs, prefix); ss << s; ss << std::move(s); ll -= l; ll -= l; } } return { ss.str(), lines - ll }; return { ss.str(), lines - ll }; Loading services/mediametrics/AudioAnalytics.h +10 −1 Original line number Original line Diff line number Diff line Loading @@ -60,8 +60,17 @@ public: * delivered. * delivered. * * * \param lines the maximum number of lines in the string returned. * \param lines the maximum number of lines in the string returned. * \param sinceNs the nanoseconds since Unix epoch to start dump (0 shows all) * \param prefix the desired key prefix to match (nullptr shows all) */ */ std::pair<std::string, int32_t> dump(int32_t lines = INT32_MAX) const; std::pair<std::string, int32_t> dump( int32_t lines = INT32_MAX, int64_t sinceNs = 0, const char *prefix = nullptr) const; void clear() { // underlying state is locked. mPreviousAnalyticsState->clear(); mAnalyticsState->clear(); } private: private: Loading services/mediametrics/MediaMetricsService.cpp +79 −98 Original line number Original line Diff line number Diff line Loading @@ -207,69 +207,66 @@ status_t MediaMetricsService::dump(int fd, const Vector<String16>& args) return NO_ERROR; return NO_ERROR; } } static const String16 allOption("--all"); static const String16 clearOption("--clear"); static const String16 heapOption("--heap"); static const String16 heapOption("--heap"); static const String16 helpOption("--help"); static const String16 prefixOption("--prefix"); static const String16 sinceOption("--since"); static const String16 unreachableOption("--unreachable"); static const String16 unreachableOption("--unreachable"); bool heap = false; bool unreachable = false; const String16 protoOption("--proto"); bool all = false; const String16 clearOption("--clear"); bool clear = false; bool clear = false; const String16 sinceOption("--since"); bool heap = false; nsecs_t ts_since = 0; bool unreachable = false; const String16 helpOption("--help"); int64_t sinceNs = 0; const String16 onlyOption("--only"); std::string prefix; std::string only; const int n = args.size(); const size_t n = args.size(); for (int i = 0; i < n; i++) { for (size_t i = 0; i < n; i++) { if (args[i] == clearOption) { if (args[i] == allOption) { all = true; } else if (args[i] == clearOption) { clear = true; clear = true; } else if (args[i] == heapOption) { } else if (args[i] == heapOption) { heap = true; heap = true; } else if (args[i] == protoOption) { } else if (args[i] == helpOption) { i++; // TODO: consider function area dumping. // dumpsys media.metrics audiotrack,codec // or dumpsys media.metrics audiotrack codec result.append("Recognized parameters:\n"); result.append("--all show all records\n"); result.append("--clear clear out saved records\n"); result.append("--heap show heap usage (top 100)\n"); result.append("--help display help\n"); result.append("--prefix X process records for component X\n"); result.append("--since X X < 0: records from -X seconds in the past\n"); result.append(" X = 0: ignore\n"); result.append(" X > 0: records from X seconds since Unix epoch\n"); result.append("--unreachable show unreachable memory (leaks)\n"); write(fd, result.string(), result.size()); return NO_ERROR; } else if (args[i] == prefixOption) { ++i; if (i < n) { if (i < n) { // ignore prefix = String8(args[i]).string(); } else { result.append("missing value for -proto\n\n"); } } } else if (args[i] == sinceOption) { } else if (args[i] == sinceOption) { i++; ++i; if (i < n) { if (i < n) { String8 value(args[i]); String8 value(args[i]); char *endp; char *endp; const char *p = value.string(); const char *p = value.string(); ts_since = strtoll(p, &endp, 10); long long sec = strtoll(p, &endp, 10); if (endp == p || *endp != '\0') { if (endp == p || *endp != '\0' || sec == 0) { ts_since = 0; sinceNs = 0; } } else if (sec < 0) { sinceNs = systemTime(SYSTEM_TIME_REALTIME) + sec * NANOS_PER_SECOND; } else { } else { ts_since = 0; sinceNs = sec * NANOS_PER_SECOND; } } // command line is milliseconds; internal units are nano-seconds ts_since *= NANOS_PER_MILLISECOND; } else if (args[i] == onlyOption) { i++; if (i < n) { String8 value(args[i]); only = value.string(); } } } else if (args[i] == helpOption) { // TODO: consider function area dumping. // dumpsys media.metrics audiotrack,codec // or dumpsys media.metrics audiotrack codec result.append("Recognized parameters:\n"); result.append("--heap heap usage (top 100)\n"); result.append("--help this help message\n"); result.append("--proto # dump using protocol #"); result.append("--clear clears out saved records\n"); result.append("--only X process records for component X\n"); result.append("--since X include records since X\n"); result.append(" (X is milliseconds since the UNIX epoch)\n"); result.append("--unreachable unreachable memory (leaks)\n"); write(fd, result.string(), result.size()); return NO_ERROR; } else if (args[i] == unreachableOption) { } else if (args[i] == unreachableOption) { unreachable = true; unreachable = true; } } Loading @@ -278,23 +275,25 @@ status_t MediaMetricsService::dump(int fd, const Vector<String16>& args) { { std::lock_guard _l(mLock); std::lock_guard _l(mLock); result.appendFormat("Dump of the %s process:\n", kServiceName); dumpHeaders_l(result, ts_since); dumpRecent_l(result, ts_since, only.c_str()); if (clear) { if (clear) { mItemsDiscarded += mItems.size(); mItemsDiscarded += mItems.size(); mItems.clear(); mItems.clear(); // shall we clear the summary data too? mAudioAnalytics.clear(); } } else { result.appendFormat("Dump of the %s process:\n", kServiceName); const char *prefixptr = prefix.size() > 0 ? prefix.c_str() : nullptr; dumpHeaders_l(result, sinceNs, prefixptr); dumpQueue_l(result, sinceNs, prefixptr); // TODO: maybe consider a better way of dumping audio analytics info. // TODO: maybe consider a better way of dumping audio analytics info. constexpr int32_t linesToDump = 1000; const int32_t linesToDump = all ? INT32_MAX : 1000; auto [ dumpString, lines ] = mAudioAnalytics.dump(linesToDump); auto [ dumpString, lines ] = mAudioAnalytics.dump(linesToDump, sinceNs, prefixptr); result.append(dumpString.c_str()); result.append(dumpString.c_str()); if (lines == linesToDump) { if (lines == linesToDump) { result.append("-- some lines may be truncated --\n"); result.append("-- some lines may be truncated --\n"); } } } } } write(fd, result.string(), result.size()); write(fd, result.string(), result.size()); // Check heap and unreachable memory outside of lock. // Check heap and unreachable memory outside of lock. Loading @@ -313,7 +312,7 @@ status_t MediaMetricsService::dump(int fd, const Vector<String16>& args) } } // dump headers // dump headers void MediaMetricsService::dumpHeaders_l(String8 &result, nsecs_t ts_since) void MediaMetricsService::dumpHeaders_l(String8 &result, int64_t sinceNs, const char* prefix) { { if (mediametrics::Item::isEnabled()) { if (mediametrics::Item::isEnabled()) { result.append("Metrics gathering: enabled\n"); result.append("Metrics gathering: enabled\n"); Loading @@ -327,56 +326,38 @@ void MediaMetricsService::dumpHeaders_l(String8 &result, nsecs_t ts_since) "Records Discarded: %lld (by Count: %lld by Expiration: %lld)\n", "Records Discarded: %lld (by Count: %lld by Expiration: %lld)\n", (long long)mItemsDiscarded, (long long)mItemsDiscardedCount, (long long)mItemsDiscarded, (long long)mItemsDiscardedCount, (long long)mItemsDiscardedExpire); (long long)mItemsDiscardedExpire); if (ts_since != 0) { if (prefix != nullptr) { result.appendFormat("Restricting to prefix %s", prefix); } if (sinceNs != 0) { result.appendFormat( result.appendFormat( "Emitting Queue entries more recent than: %lld\n", "Emitting Queue entries more recent than: %lld\n", (long long)ts_since); (long long)sinceNs); } } } } void MediaMetricsService::dumpRecent_l( // TODO: should prefix be a set<string>? String8 &result, nsecs_t ts_since, const char * only) void MediaMetricsService::dumpQueue_l(String8 &result, int64_t sinceNs, const char* prefix) { { if (only != nullptr && *only == '\0') { if (mItems.empty()) { only = nullptr; result.append("empty\n"); } return; result.append("\nFinalized Metrics (oldest first):\n"); dumpQueue_l(result, ts_since, only); // show who is connected and injecting records? // talk about # records fed to the 'readers' // talk about # records we discarded, perhaps "discarded w/o reading" too } void MediaMetricsService::dumpQueue_l(String8 &result) { dumpQueue_l(result, (nsecs_t) 0, nullptr /* only */); } } void MediaMetricsService::dumpQueue_l( String8 &result, nsecs_t ts_since, const char * only) { int slot = 0; int slot = 0; for (const auto &item : mItems) { // TODO: consider std::lower_bound() on mItems if (mItems.empty()) { if (item->getTimestamp() < sinceNs) { // sinceNs == 0 means all items shown result.append("empty\n"); } else { for (const auto &item : mItems) { nsecs_t when = item->getTimestamp(); if (when < ts_since) { continue; continue; } } // TODO: Only should be a set<string> if (prefix != nullptr && !startsWith(item->getKey(), prefix)) { if (only != nullptr && item->getKey() /* std::string */ != only) { ALOGV("%s: omit '%s', it's not '%s'", ALOGV("%s: omit '%s', it's not '%s'", __func__, item->getKey().c_str(), only); __func__, item->getKey().c_str(), prefix); continue; continue; } } result.appendFormat("%5d: %s\n", result.appendFormat("%5d: %s\n", slot, item->toString().c_str()); slot, item->toString().c_str()); slot++; slot++; } } } } } // // // Our Cheap in-core, non-persistent records management. // Our Cheap in-core, non-persistent records management. Loading Loading
media/libmediametrics/include/media/MediaMetricsItem.h +2 −2 Original line number Original line Diff line number Diff line Loading @@ -208,11 +208,11 @@ static inline constexpr const char *BUNDLE_PROPERTY_COUNT = "_propertyCount"; template<size_t N> template<size_t N> static inline bool startsWith(const std::string &s, const char (&comp)[N]) { static inline bool startsWith(const std::string &s, const char (&comp)[N]) { return !strncmp(s.c_str(), comp, N - 1); return !strncmp(s.c_str(), comp, N - 1); // last char is null termination } } static inline bool startsWith(const std::string& s, const std::string& comp) { static inline bool startsWith(const std::string& s, const std::string& comp) { return !strncmp(s.c_str(), comp.c_str(), comp.size() - 1); return !strncmp(s.c_str(), comp.c_str(), comp.size()); } } /** /** Loading
services/mediametrics/AnalyticsState.h +8 −5 Original line number Original line Diff line number Diff line Loading @@ -84,8 +84,11 @@ public: * delivered. * delivered. * * * \param lines the maximum number of lines in the string returned. * \param lines the maximum number of lines in the string returned. * \param sinceNs the nanoseconds since Unix epoch to start dump (0 shows all) * \param prefix the desired key prefix to match (nullptr shows all) */ */ std::pair<std::string, int32_t> dump(int32_t lines = INT32_MAX) const { std::pair<std::string, int32_t> dump( int32_t lines = INT32_MAX, int64_t sinceNs = 0, const char *prefix = nullptr) const { std::stringstream ss; std::stringstream ss; int32_t ll = lines; int32_t ll = lines; Loading @@ -94,8 +97,8 @@ public: --ll; --ll; } } if (ll > 0) { if (ll > 0) { auto [s, l] = mTransactionLog.dump(ll); auto [s, l] = mTransactionLog.dump(ll, sinceNs, prefix); ss << s; ss << std::move(s); ll -= l; ll -= l; } } if (ll > 0) { if (ll > 0) { Loading @@ -103,8 +106,8 @@ public: --ll; --ll; } } if (ll > 0) { if (ll > 0) { auto [s, l] = mTimeMachine.dump(ll); auto [s, l] = mTimeMachine.dump(ll, sinceNs, prefix); ss << s; ss << std::move(s); ll -= l; ll -= l; } } return { ss.str(), lines - ll }; return { ss.str(), lines - ll }; Loading
services/mediametrics/AudioAnalytics.cpp +6 −5 Original line number Original line Diff line number Diff line Loading @@ -107,14 +107,15 @@ status_t AudioAnalytics::submit( return NO_ERROR; return NO_ERROR; } } std::pair<std::string, int32_t> AudioAnalytics::dump(int32_t lines) const std::pair<std::string, int32_t> AudioAnalytics::dump( int32_t lines, int64_t sinceNs, const char *prefix) const { { std::stringstream ss; std::stringstream ss; int32_t ll = lines; int32_t ll = lines; if (ll > 0) { if (ll > 0) { auto [s, l] = mAnalyticsState->dump(ll); auto [s, l] = mAnalyticsState->dump(ll, sinceNs, prefix); ss << s; ss << std::move(s); ll -= l; ll -= l; } } if (ll > 0) { if (ll > 0) { Loading @@ -122,8 +123,8 @@ std::pair<std::string, int32_t> AudioAnalytics::dump(int32_t lines) const --ll; --ll; } } if (ll > 0) { if (ll > 0) { auto [s, l] = mPreviousAnalyticsState->dump(ll); auto [s, l] = mPreviousAnalyticsState->dump(ll, sinceNs, prefix); ss << s; ss << std::move(s); ll -= l; ll -= l; } } return { ss.str(), lines - ll }; return { ss.str(), lines - ll }; Loading
services/mediametrics/AudioAnalytics.h +10 −1 Original line number Original line Diff line number Diff line Loading @@ -60,8 +60,17 @@ public: * delivered. * delivered. * * * \param lines the maximum number of lines in the string returned. * \param lines the maximum number of lines in the string returned. * \param sinceNs the nanoseconds since Unix epoch to start dump (0 shows all) * \param prefix the desired key prefix to match (nullptr shows all) */ */ std::pair<std::string, int32_t> dump(int32_t lines = INT32_MAX) const; std::pair<std::string, int32_t> dump( int32_t lines = INT32_MAX, int64_t sinceNs = 0, const char *prefix = nullptr) const; void clear() { // underlying state is locked. mPreviousAnalyticsState->clear(); mAnalyticsState->clear(); } private: private: Loading
services/mediametrics/MediaMetricsService.cpp +79 −98 Original line number Original line Diff line number Diff line Loading @@ -207,69 +207,66 @@ status_t MediaMetricsService::dump(int fd, const Vector<String16>& args) return NO_ERROR; return NO_ERROR; } } static const String16 allOption("--all"); static const String16 clearOption("--clear"); static const String16 heapOption("--heap"); static const String16 heapOption("--heap"); static const String16 helpOption("--help"); static const String16 prefixOption("--prefix"); static const String16 sinceOption("--since"); static const String16 unreachableOption("--unreachable"); static const String16 unreachableOption("--unreachable"); bool heap = false; bool unreachable = false; const String16 protoOption("--proto"); bool all = false; const String16 clearOption("--clear"); bool clear = false; bool clear = false; const String16 sinceOption("--since"); bool heap = false; nsecs_t ts_since = 0; bool unreachable = false; const String16 helpOption("--help"); int64_t sinceNs = 0; const String16 onlyOption("--only"); std::string prefix; std::string only; const int n = args.size(); const size_t n = args.size(); for (int i = 0; i < n; i++) { for (size_t i = 0; i < n; i++) { if (args[i] == clearOption) { if (args[i] == allOption) { all = true; } else if (args[i] == clearOption) { clear = true; clear = true; } else if (args[i] == heapOption) { } else if (args[i] == heapOption) { heap = true; heap = true; } else if (args[i] == protoOption) { } else if (args[i] == helpOption) { i++; // TODO: consider function area dumping. // dumpsys media.metrics audiotrack,codec // or dumpsys media.metrics audiotrack codec result.append("Recognized parameters:\n"); result.append("--all show all records\n"); result.append("--clear clear out saved records\n"); result.append("--heap show heap usage (top 100)\n"); result.append("--help display help\n"); result.append("--prefix X process records for component X\n"); result.append("--since X X < 0: records from -X seconds in the past\n"); result.append(" X = 0: ignore\n"); result.append(" X > 0: records from X seconds since Unix epoch\n"); result.append("--unreachable show unreachable memory (leaks)\n"); write(fd, result.string(), result.size()); return NO_ERROR; } else if (args[i] == prefixOption) { ++i; if (i < n) { if (i < n) { // ignore prefix = String8(args[i]).string(); } else { result.append("missing value for -proto\n\n"); } } } else if (args[i] == sinceOption) { } else if (args[i] == sinceOption) { i++; ++i; if (i < n) { if (i < n) { String8 value(args[i]); String8 value(args[i]); char *endp; char *endp; const char *p = value.string(); const char *p = value.string(); ts_since = strtoll(p, &endp, 10); long long sec = strtoll(p, &endp, 10); if (endp == p || *endp != '\0') { if (endp == p || *endp != '\0' || sec == 0) { ts_since = 0; sinceNs = 0; } } else if (sec < 0) { sinceNs = systemTime(SYSTEM_TIME_REALTIME) + sec * NANOS_PER_SECOND; } else { } else { ts_since = 0; sinceNs = sec * NANOS_PER_SECOND; } } // command line is milliseconds; internal units are nano-seconds ts_since *= NANOS_PER_MILLISECOND; } else if (args[i] == onlyOption) { i++; if (i < n) { String8 value(args[i]); only = value.string(); } } } else if (args[i] == helpOption) { // TODO: consider function area dumping. // dumpsys media.metrics audiotrack,codec // or dumpsys media.metrics audiotrack codec result.append("Recognized parameters:\n"); result.append("--heap heap usage (top 100)\n"); result.append("--help this help message\n"); result.append("--proto # dump using protocol #"); result.append("--clear clears out saved records\n"); result.append("--only X process records for component X\n"); result.append("--since X include records since X\n"); result.append(" (X is milliseconds since the UNIX epoch)\n"); result.append("--unreachable unreachable memory (leaks)\n"); write(fd, result.string(), result.size()); return NO_ERROR; } else if (args[i] == unreachableOption) { } else if (args[i] == unreachableOption) { unreachable = true; unreachable = true; } } Loading @@ -278,23 +275,25 @@ status_t MediaMetricsService::dump(int fd, const Vector<String16>& args) { { std::lock_guard _l(mLock); std::lock_guard _l(mLock); result.appendFormat("Dump of the %s process:\n", kServiceName); dumpHeaders_l(result, ts_since); dumpRecent_l(result, ts_since, only.c_str()); if (clear) { if (clear) { mItemsDiscarded += mItems.size(); mItemsDiscarded += mItems.size(); mItems.clear(); mItems.clear(); // shall we clear the summary data too? mAudioAnalytics.clear(); } } else { result.appendFormat("Dump of the %s process:\n", kServiceName); const char *prefixptr = prefix.size() > 0 ? prefix.c_str() : nullptr; dumpHeaders_l(result, sinceNs, prefixptr); dumpQueue_l(result, sinceNs, prefixptr); // TODO: maybe consider a better way of dumping audio analytics info. // TODO: maybe consider a better way of dumping audio analytics info. constexpr int32_t linesToDump = 1000; const int32_t linesToDump = all ? INT32_MAX : 1000; auto [ dumpString, lines ] = mAudioAnalytics.dump(linesToDump); auto [ dumpString, lines ] = mAudioAnalytics.dump(linesToDump, sinceNs, prefixptr); result.append(dumpString.c_str()); result.append(dumpString.c_str()); if (lines == linesToDump) { if (lines == linesToDump) { result.append("-- some lines may be truncated --\n"); result.append("-- some lines may be truncated --\n"); } } } } } write(fd, result.string(), result.size()); write(fd, result.string(), result.size()); // Check heap and unreachable memory outside of lock. // Check heap and unreachable memory outside of lock. Loading @@ -313,7 +312,7 @@ status_t MediaMetricsService::dump(int fd, const Vector<String16>& args) } } // dump headers // dump headers void MediaMetricsService::dumpHeaders_l(String8 &result, nsecs_t ts_since) void MediaMetricsService::dumpHeaders_l(String8 &result, int64_t sinceNs, const char* prefix) { { if (mediametrics::Item::isEnabled()) { if (mediametrics::Item::isEnabled()) { result.append("Metrics gathering: enabled\n"); result.append("Metrics gathering: enabled\n"); Loading @@ -327,56 +326,38 @@ void MediaMetricsService::dumpHeaders_l(String8 &result, nsecs_t ts_since) "Records Discarded: %lld (by Count: %lld by Expiration: %lld)\n", "Records Discarded: %lld (by Count: %lld by Expiration: %lld)\n", (long long)mItemsDiscarded, (long long)mItemsDiscardedCount, (long long)mItemsDiscarded, (long long)mItemsDiscardedCount, (long long)mItemsDiscardedExpire); (long long)mItemsDiscardedExpire); if (ts_since != 0) { if (prefix != nullptr) { result.appendFormat("Restricting to prefix %s", prefix); } if (sinceNs != 0) { result.appendFormat( result.appendFormat( "Emitting Queue entries more recent than: %lld\n", "Emitting Queue entries more recent than: %lld\n", (long long)ts_since); (long long)sinceNs); } } } } void MediaMetricsService::dumpRecent_l( // TODO: should prefix be a set<string>? String8 &result, nsecs_t ts_since, const char * only) void MediaMetricsService::dumpQueue_l(String8 &result, int64_t sinceNs, const char* prefix) { { if (only != nullptr && *only == '\0') { if (mItems.empty()) { only = nullptr; result.append("empty\n"); } return; result.append("\nFinalized Metrics (oldest first):\n"); dumpQueue_l(result, ts_since, only); // show who is connected and injecting records? // talk about # records fed to the 'readers' // talk about # records we discarded, perhaps "discarded w/o reading" too } void MediaMetricsService::dumpQueue_l(String8 &result) { dumpQueue_l(result, (nsecs_t) 0, nullptr /* only */); } } void MediaMetricsService::dumpQueue_l( String8 &result, nsecs_t ts_since, const char * only) { int slot = 0; int slot = 0; for (const auto &item : mItems) { // TODO: consider std::lower_bound() on mItems if (mItems.empty()) { if (item->getTimestamp() < sinceNs) { // sinceNs == 0 means all items shown result.append("empty\n"); } else { for (const auto &item : mItems) { nsecs_t when = item->getTimestamp(); if (when < ts_since) { continue; continue; } } // TODO: Only should be a set<string> if (prefix != nullptr && !startsWith(item->getKey(), prefix)) { if (only != nullptr && item->getKey() /* std::string */ != only) { ALOGV("%s: omit '%s', it's not '%s'", ALOGV("%s: omit '%s', it's not '%s'", __func__, item->getKey().c_str(), only); __func__, item->getKey().c_str(), prefix); continue; continue; } } result.appendFormat("%5d: %s\n", result.appendFormat("%5d: %s\n", slot, item->toString().c_str()); slot, item->toString().c_str()); slot++; slot++; } } } } } // // // Our Cheap in-core, non-persistent records management. // Our Cheap in-core, non-persistent records management. Loading