Statsd: pull once per event time

If a pull happens at the same event time, we should reuse the existing
data, regardless of whether or not the cool down has been met. For
example, if an app upgrade happens at time t, and two metrics need to
pull atom a, if metric one pulls at time t, but metric two initiates the
pull at time t+2, we should still reuse the pull from time t since that
is when the app upgrade happened.

Bug: 156294650
Test: atest statsd_test

Change-Id: I4efc49545093f6683bf6dd89ed68c5dfa5b44d8f
diff --git a/cmds/statsd/src/external/StatsPullerManager.cpp b/cmds/statsd/src/external/StatsPullerManager.cpp
index 1a52eb9..8a9ec74 100644
--- a/cmds/statsd/src/external/StatsPullerManager.cpp
+++ b/cmds/statsd/src/external/StatsPullerManager.cpp
@@ -91,20 +91,21 @@
       mPullAtomCallbackDeathRecipient(AIBinder_DeathRecipient_new(pullAtomCallbackDied)) {
 }
 
-bool StatsPullerManager::Pull(int tagId, const ConfigKey& configKey,
+bool StatsPullerManager::Pull(int tagId, const ConfigKey& configKey, const int64_t eventTimeNs,
                               vector<shared_ptr<LogEvent>>* data, bool useUids) {
     std::lock_guard<std::mutex> _l(mLock);
-    return PullLocked(tagId, configKey, data, useUids);
+    return PullLocked(tagId, configKey, eventTimeNs, data, useUids);
 }
 
-bool StatsPullerManager::Pull(int tagId, const vector<int32_t>& uids,
+bool StatsPullerManager::Pull(int tagId, const vector<int32_t>& uids, const int64_t eventTimeNs,
                               vector<std::shared_ptr<LogEvent>>* data, bool useUids) {
     std::lock_guard<std::mutex> _l(mLock);
-    return PullLocked(tagId, uids, data, useUids);
+    return PullLocked(tagId, uids, eventTimeNs, data, useUids);
 }
 
 bool StatsPullerManager::PullLocked(int tagId, const ConfigKey& configKey,
-                                    vector<shared_ptr<LogEvent>>* data, bool useUids) {
+                                    const int64_t eventTimeNs, vector<shared_ptr<LogEvent>>* data,
+                                    bool useUids) {
     vector<int32_t> uids;
     if (useUids) {
         auto uidProviderIt = mPullUidProviders.find(configKey);
@@ -123,18 +124,19 @@
         }
         uids = pullUidProvider->getPullAtomUids(tagId);
     }
-    return PullLocked(tagId, uids, data, useUids);
+    return PullLocked(tagId, uids, eventTimeNs, data, useUids);
 }
 
 bool StatsPullerManager::PullLocked(int tagId, const vector<int32_t>& uids,
-                                    vector<shared_ptr<LogEvent>>* data, bool useUids) {
+                                    const int64_t eventTimeNs, vector<shared_ptr<LogEvent>>* data,
+                                    bool useUids) {
     VLOG("Initiating pulling %d", tagId);
     if (useUids) {
         for (int32_t uid : uids) {
             PullerKey key = {.atomTag = tagId, .uid = uid};
             auto pullerIt = kAllPullAtomInfo.find(key);
             if (pullerIt != kAllPullAtomInfo.end()) {
-                bool ret = pullerIt->second->Pull(data);
+                bool ret = pullerIt->second->Pull(eventTimeNs, data);
                 VLOG("pulled %zu items", data->size());
                 if (!ret) {
                     StatsdStats::getInstance().notePullFailed(tagId);
@@ -149,7 +151,7 @@
         PullerKey key = {.atomTag = tagId, .uid = -1};
         auto pullerIt = kAllPullAtomInfo.find(key);
         if (pullerIt != kAllPullAtomInfo.end()) {
-            bool ret = pullerIt->second->Pull(data);
+            bool ret = pullerIt->second->Pull(eventTimeNs, data);
             VLOG("pulled %zu items", data->size());
             if (!ret) {
                 StatsdStats::getInstance().notePullFailed(tagId);
@@ -290,7 +292,8 @@
     }
     for (const auto& pullInfo : needToPull) {
         vector<shared_ptr<LogEvent>> data;
-        bool pullSuccess = PullLocked(pullInfo.first->atomTag, pullInfo.first->configKey, &data);
+        bool pullSuccess = PullLocked(pullInfo.first->atomTag, pullInfo.first->configKey,
+                                      elapsedTimeNs, &data);
         if (!pullSuccess) {
             VLOG("pull failed at %lld, will try again later", (long long)elapsedTimeNs);
         }