Save metadata to Disk

Bug: 148280505
Test: bit statsd_test:*
Change-Id: Ib9c6b9b4f22e7380717b480c7ae4a37bb3364619
diff --git a/cmds/statsd/src/StatsLogProcessor.cpp b/cmds/statsd/src/StatsLogProcessor.cpp
index 69b9fc7..45cb07b 100644
--- a/cmds/statsd/src/StatsLogProcessor.cpp
+++ b/cmds/statsd/src/StatsLogProcessor.cpp
@@ -79,6 +79,7 @@
 #define NS_PER_HOUR 3600 * NS_PER_SEC
 
 #define STATS_ACTIVE_METRIC_DIR "/data/misc/stats-active-metric"
+#define STATS_METADATA_DIR "/data/misc/stats-metadata"
 
 // Cool down period for writing data to disk to avoid overwriting files.
 #define WRITE_DATA_COOL_DOWN_SEC 5
@@ -851,6 +852,56 @@
     proto.flush(fd.get());
 }
 
+void StatsLogProcessor::SaveMetadataToDisk(int64_t currentWallClockTimeNs,
+                                           int64_t systemElapsedTimeNs) {
+    std::lock_guard<std::mutex> lock(mMetricsMutex);
+    // Do not write to disk if we already have in the last few seconds.
+    if (static_cast<unsigned long long> (systemElapsedTimeNs) <
+            mLastMetadataWriteNs + WRITE_DATA_COOL_DOWN_SEC * NS_PER_SEC) {
+        ALOGI("Statsd skipping writing metadata to disk. Already wrote data in last %d seconds",
+                WRITE_DATA_COOL_DOWN_SEC);
+        return;
+    }
+    mLastMetadataWriteNs = systemElapsedTimeNs;
+
+    metadata::StatsMetadataList metadataList;
+    WriteMetadataToProtoLocked(
+            currentWallClockTimeNs, systemElapsedTimeNs, &metadataList);
+
+    string file_name = StringPrintf("%s/metadata", STATS_METADATA_DIR);
+    StorageManager::deleteFile(file_name.c_str());
+
+    if (metadataList.stats_metadata_size() == 0) {
+        // Skip the write if we have nothing to write.
+        return;
+    }
+
+    std::string data;
+    metadataList.SerializeToString(&data);
+    StorageManager::writeFile(file_name.c_str(), data.c_str(), data.size());
+}
+
+void StatsLogProcessor::WriteMetadataToProto(int64_t currentWallClockTimeNs,
+                                             int64_t systemElapsedTimeNs,
+                                             metadata::StatsMetadataList* metadataList) {
+    std::lock_guard<std::mutex> lock(mMetricsMutex);
+    WriteMetadataToProtoLocked(currentWallClockTimeNs, systemElapsedTimeNs, metadataList);
+}
+
+void StatsLogProcessor::WriteMetadataToProtoLocked(int64_t currentWallClockTimeNs,
+                                                   int64_t systemElapsedTimeNs,
+                                                   metadata::StatsMetadataList* metadataList) {
+    for (const auto& pair : mMetricsManagers) {
+        const sp<MetricsManager>& metricsManager = pair.second;
+        metadata::StatsMetadata* statsMetadata = metadataList->add_stats_metadata();
+        bool metadataWritten = metricsManager->writeMetadataToProto(currentWallClockTimeNs,
+                systemElapsedTimeNs, statsMetadata);
+        if (!metadataWritten) {
+            metadataList->mutable_stats_metadata()->RemoveLast();
+        }
+    }
+}
+
 void StatsLogProcessor::WriteActiveConfigsToProtoOutputStream(
         int64_t currentTimeNs, const DumpReportReason reason, ProtoOutputStream* proto) {
     std::lock_guard<std::mutex> lock(mMetricsMutex);