[TimeStats] Add callback for global stats

Now that the new statsd api is completed, we can implement the puller
logic in TimeStats instead of in statsd's code.

Bug: 119885568
Test: adb shell cmd stats pull-source 10062
Change-Id: Ic90ec5ddc082160bd7e784becf8bf3c3a99ef971
diff --git a/services/surfaceflinger/TimeStats/TimeStats.h b/services/surfaceflinger/TimeStats/TimeStats.h
index 65e5cf4..94c24ea 100644
--- a/services/surfaceflinger/TimeStats/TimeStats.h
+++ b/services/surfaceflinger/TimeStats/TimeStats.h
@@ -16,7 +16,11 @@
 
 #pragma once
 
+#include <binder/IServiceManager.h>
 #include <hardware/hwcomposer_defs.h>
+#include <stats_event.h>
+#include <stats_pull_atom_callback.h>
+#include <statslog.h>
 #include <timestatsproto/TimeStatsHelper.h>
 #include <timestatsproto/TimeStatsProtoHeader.h>
 #include <ui/FenceTime.h>
@@ -37,6 +41,10 @@
 public:
     virtual ~TimeStats() = default;
 
+    // Called once boot has been finished to perform additional capabilities,
+    // e.g. registration to statsd.
+    virtual void onBootFinished() = 0;
+
     virtual void parseArgs(bool asProto, const Vector<String16>& args, std::string& result) = 0;
     virtual bool isEnabled() = 0;
     virtual std::string miniDump() = 0;
@@ -131,6 +139,40 @@
 public:
     TimeStats();
 
+    // Delegate to the statsd service and associated APIs.
+    // Production code may use this class directly, whereas unit test may define
+    // a subclass for ease of testing.
+    class StatsEventDelegate {
+    public:
+        virtual ~StatsEventDelegate() = default;
+        virtual struct stats_event* addStatsEventToPullData(pulled_stats_event_list* data) {
+            return add_stats_event_to_pull_data(data);
+        }
+        virtual void registerStatsPullAtomCallback(int32_t atom_tag,
+                                                   stats_pull_atom_callback_t callback,
+                                                   pull_atom_metadata* metadata, void* cookie) {
+            return register_stats_pull_atom_callback(atom_tag, callback, metadata, cookie);
+        }
+
+        // Check if the statsd daemon exists, as otherwise callback registration
+        // will silently fail.
+        virtual bool checkStatsService();
+
+        virtual void statsEventSetAtomId(struct stats_event* event, int32_t atom_id) {
+            return stats_event_set_atom_id(event, atom_id);
+        }
+
+        virtual void statsEventWriteInt64(struct stats_event* event, int64_t field) {
+            return stats_event_write_int64(event, field);
+        }
+
+        virtual void statsEventBuild(struct stats_event* event) { return stats_event_build(event); }
+    };
+    // For testing only for injecting custom dependencies.
+    TimeStats(std::unique_ptr<StatsEventDelegate> statsDelegate);
+
+    void onBootFinished() override;
+
     void parseArgs(bool asProto, const Vector<String16>& args, std::string& result) override;
     bool isEnabled() override;
     std::string miniDump() override;
@@ -167,14 +209,19 @@
     static const size_t MAX_NUM_TIME_RECORDS = 64;
 
 private:
+    static bool pullGlobalAtomCallback(int32_t atom_tag, pulled_stats_event_list* data,
+                                       const void* cookie);
     bool recordReadyLocked(int32_t layerId, TimeRecord* timeRecord);
     void flushAvailableRecordsToStatsLocked(int32_t layerId);
     void flushPowerTimeLocked();
     void flushAvailableGlobalRecordsToStatsLocked();
+    void registerToStatsdIfNeededLocked();
 
     void enable();
     void disable();
-    void clear();
+    void clearAll();
+    void clearGlobalLocked();
+    void clearLayersLocked();
     void dump(bool asProto, std::optional<uint32_t> maxLayers, std::string& result);
 
     std::atomic<bool> mEnabled = false;
@@ -187,6 +234,10 @@
 
     static const size_t MAX_NUM_LAYER_RECORDS = 200;
     static const size_t MAX_NUM_LAYER_STATS = 200;
+    // Default is true, so that registration doesn't happen until the device has
+    // been booted.
+    bool mRegisteredCallback = true;
+    std::unique_ptr<StatsEventDelegate> mStatsDelegate = std::make_unique<StatsEventDelegate>();
 };
 
 } // namespace impl