diff --git a/cmds/statsd/src/StatsLogProcessor.cpp b/cmds/statsd/src/StatsLogProcessor.cpp index 4d279481dc765..daafe9c0390df 100644 --- a/cmds/statsd/src/StatsLogProcessor.cpp +++ b/cmds/statsd/src/StatsLogProcessor.cpp @@ -382,10 +382,13 @@ void StatsLogProcessor::onConfigMetricsReportLocked(const ConfigKey& key, it->second->onDumpReport(dumpTimeStampNs, include_current_partial_bucket, &str_set, proto); - // Fill in UidMap. - uint64_t uidMapToken = proto->start(FIELD_TYPE_MESSAGE | FIELD_ID_UID_MAP); - mUidMap->appendUidMap(dumpTimeStampNs, key, &str_set, proto); - proto->end(uidMapToken); + // Fill in UidMap if there is at least one metric to report. + // This skips the uid map if it's an empty config. + if (it->second->getNumMetrics() > 0) { + uint64_t uidMapToken = proto->start(FIELD_TYPE_MESSAGE | FIELD_ID_UID_MAP); + mUidMap->appendUidMap(dumpTimeStampNs, key, &str_set, proto); + proto->end(uidMapToken); + } // Fill in the timestamps. proto->write(FIELD_TYPE_INT64 | FIELD_ID_LAST_REPORT_ELAPSED_NANOS, diff --git a/cmds/statsd/src/metrics/MetricsManager.h b/cmds/statsd/src/metrics/MetricsManager.h index 4f39df9e7ad2c..456da982bd9bc 100644 --- a/cmds/statsd/src/metrics/MetricsManager.h +++ b/cmds/statsd/src/metrics/MetricsManager.h @@ -89,6 +89,10 @@ public: return mLastReportWallClockNs; }; + inline size_t getNumMetrics() const { + return mAllMetricProducers.size(); + } + virtual void dropData(const int64_t dropTimeNs); virtual void onDumpReport(const int64_t dumpTimeNs, diff --git a/cmds/statsd/tests/StatsLogProcessor_test.cpp b/cmds/statsd/tests/StatsLogProcessor_test.cpp index de6e6e542c604..3395aa639aabf 100644 --- a/cmds/statsd/tests/StatsLogProcessor_test.cpp +++ b/cmds/statsd/tests/StatsLogProcessor_test.cpp @@ -24,6 +24,8 @@ #include #include +#include "tests/statsd_test_util.h" + #include using namespace android; @@ -123,6 +125,21 @@ TEST(StatsLogProcessorTest, TestDropWhenByteSizeTooLarge) { EXPECT_EQ(0, broadcastCount); } +StatsdConfig MakeConfig(bool includeMetric) { + StatsdConfig config; + config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root. + + if (includeMetric) { + auto appCrashMatcher = CreateProcessCrashAtomMatcher(); + *config.add_atom_matcher() = appCrashMatcher; + auto countMetric = config.add_count_metric(); + countMetric->set_id(StringToId("AppCrashes")); + countMetric->set_what(appCrashMatcher.id()); + countMetric->set_bucket(FIVE_MINUTES); + } + return config; +} + TEST(StatsLogProcessorTest, TestUidMapHasSnapshot) { // Setup simple config key corresponding to empty config. sp m = new UidMap(); @@ -133,8 +150,7 @@ TEST(StatsLogProcessorTest, TestUidMapHasSnapshot) { StatsLogProcessor p(m, anomalyAlarmMonitor, subscriberAlarmMonitor, 0, [&broadcastCount](const ConfigKey& key) { broadcastCount++; return true;}); ConfigKey key(3, 4); - StatsdConfig config; - config.add_allowed_log_source("AID_ROOT"); + StatsdConfig config = MakeConfig(true); p.OnConfigUpdated(0, key, config); // Expect to get no metrics, but snapshot specified above in uidmap. @@ -149,6 +165,29 @@ TEST(StatsLogProcessorTest, TestUidMapHasSnapshot) { EXPECT_EQ(2, uidmap.snapshots(0).package_info_size()); } +TEST(StatsLogProcessorTest, TestEmptyConfigHasNoUidMap) { + // Setup simple config key corresponding to empty config. + sp m = new UidMap(); + m->updateMap(1, {1, 2}, {1, 2}, {String16("p1"), String16("p2")}); + sp anomalyAlarmMonitor; + sp subscriberAlarmMonitor; + int broadcastCount = 0; + StatsLogProcessor p(m, anomalyAlarmMonitor, subscriberAlarmMonitor, 0, + [&broadcastCount](const ConfigKey& key) { broadcastCount++; return true;}); + ConfigKey key(3, 4); + StatsdConfig config = MakeConfig(false); + p.OnConfigUpdated(0, key, config); + + // Expect to get no metrics, but snapshot specified above in uidmap. + vector bytes; + p.onDumpReport(key, 1, false, true, ADB_DUMP, &bytes); + + ConfigMetricsReportList output; + output.ParseFromArray(bytes.data(), bytes.size()); + EXPECT_TRUE(output.reports_size() > 0); + EXPECT_FALSE(output.reports(0).has_uid_map()); +} + TEST(StatsLogProcessorTest, TestReportIncludesSubConfig) { // Setup simple config key corresponding to empty config. sp m = new UidMap();