Statsd can dump data as proto to bugreport

* Creates an incident section for statsd data.
* Allows dump to output statsd data, in proto format.
* Hooks up two statsd outputs to bugreports:
  -statsd report data in proto format
  -statsd metadata (statsdstats) in text format

The incident section does not import stats_log.proto because that turns
out to be extremely difficult: stats_log.proto imports atoms.proto,
which imports more things and is enormous and causes all sorts of
problems. atoms.proto was purposefully never compiled in AOSP, so to
retain that feature, the incident section uses 'bytes' instead of an
actual message. Since this isn't ever read in AOSP (other than testing),
this should be fine.

Bug: 115678461
Test: take a bug report and confirm valid proto
Test: cts-tradefed run cts-dev -m CtsStatsdHostTestCases -t android.cts.statsd.atom.HostAtomTests#testDumpsysStats

Change-Id: I1c370af7678d1dc7440ce299ea5ea4da6d33832b
diff --git a/cmds/statsd/src/StatsLogProcessor.cpp b/cmds/statsd/src/StatsLogProcessor.cpp
index 12e2560..065f49e 100644
--- a/cmds/statsd/src/StatsLogProcessor.cpp
+++ b/cmds/statsd/src/StatsLogProcessor.cpp
@@ -276,22 +276,21 @@
  */
 void StatsLogProcessor::onDumpReport(const ConfigKey& key, const int64_t dumpTimeStampNs,
                                      const bool include_current_partial_bucket,
+                                     const bool erase_data,
                                      const DumpReportReason dumpReportReason,
-                                     vector<uint8_t>* outData) {
+                                     ProtoOutputStream* proto) {
     std::lock_guard<std::mutex> lock(mMetricsMutex);
 
-    ProtoOutputStream proto;
-
     // Start of ConfigKey.
-    uint64_t configKeyToken = proto.start(FIELD_TYPE_MESSAGE | FIELD_ID_CONFIG_KEY);
-    proto.write(FIELD_TYPE_INT32 | FIELD_ID_UID, key.GetUid());
-    proto.write(FIELD_TYPE_INT64 | FIELD_ID_ID, (long long)key.GetId());
-    proto.end(configKeyToken);
+    uint64_t configKeyToken = proto->start(FIELD_TYPE_MESSAGE | FIELD_ID_CONFIG_KEY);
+    proto->write(FIELD_TYPE_INT32 | FIELD_ID_UID, key.GetUid());
+    proto->write(FIELD_TYPE_INT64 | FIELD_ID_ID, (long long)key.GetId());
+    proto->end(configKeyToken);
     // End of ConfigKey.
 
     // Then, check stats-data directory to see there's any file containing
     // ConfigMetricsReport from previous shutdowns to concatenate to reports.
-    StorageManager::appendConfigMetricsReport(key, &proto);
+    StorageManager::appendConfigMetricsReport(key, proto);
 
     auto it = mMetricsManagers.find(key);
     if (it != mMetricsManagers.end()) {
@@ -301,14 +300,27 @@
 
         // Start of ConfigMetricsReport (reports).
         uint64_t reportsToken =
-                proto.start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_REPORTS);
+                proto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_REPORTS);
         onConfigMetricsReportLocked(key, dumpTimeStampNs, include_current_partial_bucket,
-                                    dumpReportReason, &proto);
-        proto.end(reportsToken);
+                                    erase_data, dumpReportReason, proto);
+        proto->end(reportsToken);
         // End of ConfigMetricsReport (reports).
     } else {
         ALOGW("Config source %s does not exist", key.ToString().c_str());
     }
+}
+
+/*
+ * onDumpReport dumps serialized ConfigMetricsReportList into outData.
+ */
+void StatsLogProcessor::onDumpReport(const ConfigKey& key, const int64_t dumpTimeStampNs,
+                                     const bool include_current_partial_bucket,
+                                     const bool erase_data,
+                                     const DumpReportReason dumpReportReason,
+                                     vector<uint8_t>* outData) {
+    ProtoOutputStream proto;
+    onDumpReport(key, dumpTimeStampNs, include_current_partial_bucket, erase_data,
+                 dumpReportReason, &proto);
 
     if (outData != nullptr) {
         outData->clear();
@@ -332,6 +344,7 @@
 void StatsLogProcessor::onConfigMetricsReportLocked(const ConfigKey& key,
                                                     const int64_t dumpTimeStampNs,
                                                     const bool include_current_partial_bucket,
+                                                    const bool erase_data,
                                                     const DumpReportReason dumpReportReason,
                                                     ProtoOutputStream* proto) {
     // We already checked whether key exists in mMetricsManagers in
@@ -348,7 +361,7 @@
     // First, fill in ConfigMetricsReport using current data on memory, which
     // starts from filling in StatsLogReport's.
     it->second->onDumpReport(dumpTimeStampNs, include_current_partial_bucket,
-                             &str_set, proto);
+                             erase_data, &str_set, proto);
 
     // Fill in UidMap if there is at least one metric to report.
     // This skips the uid map if it's an empty config.
@@ -479,7 +492,7 @@
     }
     ProtoOutputStream proto;
     onConfigMetricsReportLocked(key, timestampNs, true /* include_current_partial_bucket*/,
-                                dumpReportReason, &proto);
+                                true /* erase_data */, dumpReportReason, &proto);
     string file_name = StringPrintf("%s/%ld_%d_%lld", STATS_DATA_DIR,
          (long)getWallClockSec(), key.GetUid(), (long long)key.GetId());
     android::base::unique_fd fd(open(file_name.c_str(),