Use MetricsReporter in the CHRE daemon

This CL replaces manual metrics logging in the CHRE
daemon with MetricsReporter.

Bug: 298459533
Test: m chre
Test: Set flag flag_metrics_reporter_in_the_daemon = true
Test: Set event queue snapshot trigger interval to 10s
Test: Add unsigned preloaded nanoapp to list of preloaded
Test:     nanoapps
Test: Manually trigger onPalOpenFailure with event queue
Test:     snapshot collection
Test: statsd reports all metrics received
Change-Id: Ieb69abcc041e13c3ee002f1bbcc380c5d4798cfd
diff --git a/host/common/daemon_base.cc b/host/common/daemon_base.cc
index 48737f0..b7681cb 100644
--- a/host/common/daemon_base.cc
+++ b/host/common/daemon_base.cc
@@ -14,6 +14,9 @@
  * limitations under the License.
  */
 
+// TODO(b/298459533): metrics_reporter_in_the_daemon ramp up -> remove old
+// code
+
 #include <signal.h>
 #include <cstdlib>
 #include <fstream>
@@ -25,12 +28,9 @@
 #include "chre_host/napp_header.h"
 
 #ifdef CHRE_DAEMON_METRIC_ENABLED
+#include <android_chre_flags.h>
 #include <chre_atoms_log.h>
 #include <system/chre/core/chre_metrics.pb.h>
-
-using ::aidl::android::frameworks::stats::IStats;
-using ::aidl::android::frameworks::stats::VendorAtom;
-using ::aidl::android::frameworks::stats::VendorAtomValue;
 #endif  // CHRE_DAEMON_METRIC_ENABLED
 
 // Aliased for consistency with the way these symbols are referenced in
@@ -40,6 +40,17 @@
 namespace android {
 namespace chre {
 
+#ifdef CHRE_DAEMON_METRIC_ENABLED
+using ::aidl::android::frameworks::stats::IStats;
+using ::aidl::android::frameworks::stats::VendorAtom;
+using ::aidl::android::frameworks::stats::VendorAtomValue;
+
+using ::android::chre::Atoms::CHRE_EVENT_QUEUE_SNAPSHOT_REPORTED;
+using ::android::chre::Atoms::CHRE_PAL_OPEN_FAILED;
+using ::android::chre::Atoms::ChrePalOpenFailed;
+using ::android::chre::flags::metrics_reporter_in_the_daemon;
+#endif  // CHRE_DAEMON_METRIC_ENABLED
+
 namespace {
 
 void signalHandler(void *ctx) {
@@ -153,46 +164,66 @@
   const std::vector<int8_t> &encodedMetric = metricMsg->encoded_metric;
 
   switch (metricMsg->id) {
-    case Atoms::CHRE_PAL_OPEN_FAILED: {
+    case CHRE_PAL_OPEN_FAILED: {
       metrics::ChrePalOpenFailed metric;
       if (!metric.ParseFromArray(encodedMetric.data(), encodedMetric.size())) {
         LOGE("Failed to parse metric data");
       } else {
-        std::vector<VendorAtomValue> values(2);
-        values[0].set<VendorAtomValue::intValue>(metric.pal());
-        values[1].set<VendorAtomValue::intValue>(metric.type());
-        const VendorAtom atom{
-            .atomId = Atoms::CHRE_PAL_OPEN_FAILED,
-            .values{std::move(values)},
-        };
-        reportMetric(atom);
+        if (metrics_reporter_in_the_daemon()) {
+          ChrePalOpenFailed::ChrePalType pal =
+              static_cast<ChrePalOpenFailed::ChrePalType>(metric.pal());
+          ChrePalOpenFailed::Type type =
+              static_cast<ChrePalOpenFailed::Type>(metric.type());
+          if (!mMetricsReporter.logPalOpenFailed(pal, type)) {
+            LOGE("Could not log the PAL open failed metric");
+          }
+        } else {
+          std::vector<VendorAtomValue> values(2);
+          values[0].set<VendorAtomValue::intValue>(metric.pal());
+          values[1].set<VendorAtomValue::intValue>(metric.type());
+          const VendorAtom atom{
+              .atomId = Atoms::CHRE_PAL_OPEN_FAILED,
+              .values{std::move(values)},
+          };
+          reportMetric(atom);
+        }
       }
       break;
     }
-    case Atoms::CHRE_EVENT_QUEUE_SNAPSHOT_REPORTED: {
+    case CHRE_EVENT_QUEUE_SNAPSHOT_REPORTED: {
       metrics::ChreEventQueueSnapshotReported metric;
       if (!metric.ParseFromArray(encodedMetric.data(), encodedMetric.size())) {
         LOGE("Failed to parse metric data");
       } else {
-        std::vector<VendorAtomValue> values(6);
-        values[0].set<VendorAtomValue::intValue>(
-            metric.snapshot_chre_get_time_ms());
-        values[1].set<VendorAtomValue::intValue>(metric.max_event_queue_size());
-        values[2].set<VendorAtomValue::intValue>(
-            metric.mean_event_queue_size());
-        values[3].set<VendorAtomValue::intValue>(metric.num_dropped_events());
-        // Last two values are not currently populated and will be implemented
-        // later. To avoid confusion of the interpretation, we use UINT32_MAX
-        // as a placeholder value.
-        values[4].set<VendorAtomValue::intValue>(
-            UINT32_MAX);  // max_queue_delay_us
-        values[5].set<VendorAtomValue::intValue>(
-            UINT32_MAX);  // mean_queue_delay_us
-        const VendorAtom atom{
-            .atomId = Atoms::CHRE_EVENT_QUEUE_SNAPSHOT_REPORTED,
-            .values{std::move(values)},
-        };
-        reportMetric(atom);
+        if (metrics_reporter_in_the_daemon()) {
+          if (!mMetricsReporter.logEventQueueSnapshotReported(
+                  metric.snapshot_chre_get_time_ms(),
+                  metric.max_event_queue_size(), metric.mean_event_queue_size(),
+                  metric.num_dropped_events())) {
+            LOGE("Could not log the event queue snapshot metric");
+          }
+        } else {
+          std::vector<VendorAtomValue> values(6);
+          values[0].set<VendorAtomValue::intValue>(
+              metric.snapshot_chre_get_time_ms());
+          values[1].set<VendorAtomValue::intValue>(
+              metric.max_event_queue_size());
+          values[2].set<VendorAtomValue::intValue>(
+              metric.mean_event_queue_size());
+          values[3].set<VendorAtomValue::intValue>(metric.num_dropped_events());
+          // Last two values are not currently populated and will be implemented
+          // later. To avoid confusion of the interpretation, we use UINT32_MAX
+          // as a placeholder value.
+          values[4].set<VendorAtomValue::intValue>(
+              UINT32_MAX);  // max_queue_delay_us
+          values[5].set<VendorAtomValue::intValue>(
+              UINT32_MAX);  // mean_queue_delay_us
+          const VendorAtom atom{
+              .atomId = Atoms::CHRE_EVENT_QUEUE_SNAPSHOT_REPORTED,
+              .values{std::move(values)},
+          };
+          reportMetric(atom);
+        }
       }
       break;
     }
diff --git a/host/common/fbs_daemon_base.cc b/host/common/fbs_daemon_base.cc
index 94f0770..fa0803c 100644
--- a/host/common/fbs_daemon_base.cc
+++ b/host/common/fbs_daemon_base.cc
@@ -14,6 +14,9 @@
  * limitations under the License.
  */
 
+// TODO(b/298459533): metrics_reporter_in_the_daemon ramp up -> remove old
+// code
+
 #include <cstdlib>
 #include <fstream>
 
@@ -26,11 +29,8 @@
 #ifdef CHRE_DAEMON_METRIC_ENABLED
 #include <aidl/android/frameworks/stats/IStats.h>
 #include <android/binder_manager.h>
+#include <android_chre_flags.h>
 #include <chre_atoms_log.h>
-
-using ::aidl::android::frameworks::stats::IStats;
-using ::aidl::android::frameworks::stats::VendorAtom;
-using ::aidl::android::frameworks::stats::VendorAtomValue;
 #endif  // CHRE_DAEMON_METRIC_ENABLED
 
 // Aliased for consistency with the way these symbols are referenced in
@@ -40,6 +40,14 @@
 namespace android {
 namespace chre {
 
+#ifdef CHRE_DAEMON_METRIC_ENABLED
+using ::aidl::android::frameworks::stats::IStats;
+using ::aidl::android::frameworks::stats::VendorAtom;
+using ::aidl::android::frameworks::stats::VendorAtomValue;
+using ::android::chre::Atoms::ChreHalNanoappLoadFailed;
+using ::android::chre::flags::metrics_reporter_in_the_daemon;
+#endif  // CHRE_DAEMON_METRIC_ENABLED
+
 bool FbsDaemonBase::sendNanoappLoad(uint64_t appId, uint32_t appVersion,
                                     uint32_t appTargetApiVersion,
                                     const std::string &appBinaryName,
@@ -176,18 +184,27 @@
              mPreloadedNanoappPendingTransactions.front().transactionId);
 
 #ifdef CHRE_DAEMON_METRIC_ENABLED
-        std::vector<VendorAtomValue> values(3);
-        values[0].set<VendorAtomValue::longValue>(
-            mPreloadedNanoappPendingTransactions.front().nanoappId);
-        values[1].set<VendorAtomValue::intValue>(
-            Atoms::ChreHalNanoappLoadFailed::TYPE_PRELOADED);
-        values[2].set<VendorAtomValue::intValue>(
-            Atoms::ChreHalNanoappLoadFailed::REASON_ERROR_GENERIC);
-        const VendorAtom atom{
-            .atomId = Atoms::CHRE_HAL_NANOAPP_LOAD_FAILED,
-            .values{std::move(values)},
-        };
-        reportMetric(atom);
+        if (metrics_reporter_in_the_daemon()) {
+          if (!mMetricsReporter.logNanoappLoadFailed(
+                  mPreloadedNanoappPendingTransactions.front().nanoappId,
+                  ChreHalNanoappLoadFailed::TYPE_PRELOADED,
+                  ChreHalNanoappLoadFailed::REASON_ERROR_GENERIC)) {
+            LOGE("Could not log the nanoapp load failed metric");
+          }
+        } else {
+          std::vector<VendorAtomValue> values(3);
+          values[0].set<VendorAtomValue::longValue>(
+              mPreloadedNanoappPendingTransactions.front().nanoappId);
+          values[1].set<VendorAtomValue::intValue>(
+              Atoms::ChreHalNanoappLoadFailed::TYPE_PRELOADED);
+          values[2].set<VendorAtomValue::intValue>(
+              Atoms::ChreHalNanoappLoadFailed::REASON_ERROR_GENERIC);
+          const VendorAtom atom{
+              .atomId = Atoms::CHRE_HAL_NANOAPP_LOAD_FAILED,
+              .values{std::move(values)},
+          };
+          reportMetric(atom);
+        }
 #endif  // CHRE_DAEMON_METRIC_ENABLED
       }
       mPreloadedNanoappPendingTransactions.pop();
diff --git a/host/common/include/chre_host/daemon_base.h b/host/common/include/chre_host/daemon_base.h
index c0c6e73..453a866 100644
--- a/host/common/include/chre_host/daemon_base.h
+++ b/host/common/include/chre_host/daemon_base.h
@@ -25,10 +25,14 @@
  * implement.
  */
 
+// TODO(b/298459533): metrics_reporter_in_the_daemon ramp up -> remove old
+// code
+
 #include <atomic>
 #include <csignal>
 #include <cstdint>
 #include <map>
+#include <mutex>
 #include <queue>
 #include <string>
 #include <thread>
@@ -40,6 +44,8 @@
 #ifdef CHRE_DAEMON_METRIC_ENABLED
 #include <aidl/android/frameworks/stats/IStats.h>
 #include <android/binder_manager.h>
+
+#include "chre_host/metrics_reporter.h"
 #endif  // CHRE_DAEMON_METRIC_ENABLED
 
 namespace android {
@@ -230,16 +236,15 @@
 #ifdef CHRE_LOG_ATOM_EXTENSION_ENABLED
   /**
    * Handles additional metrics that aren't logged by the common CHRE code.
-   *
    */
   virtual void handleVendorMetricLog(
       const ::chre::fbs::MetricLogT *metric_msg) = 0;
 #endif  // CHRE_LOG_ATOM_EXTENSION_ENABLED
 
   /**
-   * Create and report CHRE vendor atom and send it to stats_client
+   * Create and report CHRE vendor atom and send it to stats_client.
    *
-   * @param atom the vendor atom to be reported
+   * @param atom the vendor atom to be reported.
    */
   void reportMetric(const aidl::android::frameworks::stats::VendorAtom &atom);
 #endif  // CHRE_DAEMON_METRIC_ENABLED
@@ -263,6 +268,10 @@
   //! Server used to communicate with daemon clients
   SocketServer mServer;
 
+#ifdef CHRE_DAEMON_METRIC_ENABLED
+  android::chre::MetricsReporter mMetricsReporter;
+#endif  // CHRE_DAEMON_METRIC_ENABLED
+
  private:
   LogMessageParser mLogger;