Adds a code when statsd sends intent to getData.

If the data receiver is experiencing delays, there may be a queue of
multiple intents to collect the same data. This timestamp makes it
easy in the receiver to de-dupe these requests to call getData.

Also, we update how StatsCompanionService gets the snapshot by
requesting data for all known apps. I notice that Keep seems to have
a uid active even when it appears uninstalled.

Bug: 77981668
Test: Flashed marlin-eng and manually verified.
Change-Id: I509e19383ec4a5da8746dd0c76ac71a948c6877d
diff --git a/cmds/statsd/src/StatsLogProcessor.cpp b/cmds/statsd/src/StatsLogProcessor.cpp
index f2443e8..d3aefed 100644
--- a/cmds/statsd/src/StatsLogProcessor.cpp
+++ b/cmds/statsd/src/StatsLogProcessor.cpp
@@ -485,6 +485,15 @@
     mStatsPullerManager.OnAlarmFired(timestampNs);
 }
 
+int64_t StatsLogProcessor::getLastReportTimeNs(const ConfigKey& key) {
+    auto it = mMetricsManagers.find(key);
+    if (it == mMetricsManagers.end()) {
+        return 0;
+    } else {
+        return it->second->getLastReportTimeNs();
+    }
+}
+
 }  // namespace statsd
 }  // namespace os
 }  // namespace android
diff --git a/cmds/statsd/src/StatsLogProcessor.h b/cmds/statsd/src/StatsLogProcessor.h
index 6efdf8c..b91b01d 100644
--- a/cmds/statsd/src/StatsLogProcessor.h
+++ b/cmds/statsd/src/StatsLogProcessor.h
@@ -75,6 +75,8 @@
 
     void informPullAlarmFired(const int64_t timestampNs);
 
+    int64_t getLastReportTimeNs(const ConfigKey& key);
+
 private:
     // For testing only.
     inline sp<AlarmMonitor> getAnomalyAlarmMonitor() const {
diff --git a/cmds/statsd/src/StatsService.cpp b/cmds/statsd/src/StatsService.cpp
index f7cc00c..e26806b 100644
--- a/cmds/statsd/src/StatsService.cpp
+++ b/cmds/statsd/src/StatsService.cpp
@@ -90,7 +90,7 @@
             VLOG("Statscompanion could not find a broadcast receiver for %s",
                  key.ToString().c_str());
         } else {
-            sc->sendDataBroadcast(receiver);
+            sc->sendDataBroadcast(receiver, mProcessor->getLastReportTimeNs(key));
         }
     }
     );
@@ -377,14 +377,15 @@
         print_cmd_help(out);
         return UNKNOWN_ERROR;
     }
-    auto receiver = mConfigManager->GetConfigReceiver(ConfigKey(uid, StrToInt64(name)));
+    ConfigKey key(uid, StrToInt64(name));
+    auto receiver = mConfigManager->GetConfigReceiver(key);
     sp<IStatsCompanionService> sc = getStatsCompanionService();
     if (sc == nullptr) {
         VLOG("Could not access statsCompanion");
     } else if (receiver == nullptr) {
         VLOG("Could not find receiver for %s, %s", args[1].c_str(), args[2].c_str())
     } else {
-        sc->sendDataBroadcast(receiver);
+        sc->sendDataBroadcast(receiver, mProcessor->getLastReportTimeNs(key));
         VLOG("StatsService::trigger broadcast succeeded to %s, %s", args[1].c_str(),
              args[2].c_str());
     }
diff --git a/core/java/android/os/IStatsCompanionService.aidl b/core/java/android/os/IStatsCompanionService.aidl
index 116262e..dde46cd 100644
--- a/core/java/android/os/IStatsCompanionService.aidl
+++ b/core/java/android/os/IStatsCompanionService.aidl
@@ -66,7 +66,7 @@
     StatsLogEventWrapper[] pullData(int pullCode);
 
     /** Send a broadcast to the specified PendingIntent's as IBinder that it should getData now. */
-    oneway void sendDataBroadcast(in IBinder intentSender);
+    oneway void sendDataBroadcast(in IBinder intentSender, long lastReportTimeNs);
 
     /**
      * Requests StatsCompanionService to send a broadcast using the given intentSender
diff --git a/services/core/java/com/android/server/stats/StatsCompanionService.java b/services/core/java/com/android/server/stats/StatsCompanionService.java
index 5f2ac4f..401f74c 100644
--- a/services/core/java/com/android/server/stats/StatsCompanionService.java
+++ b/services/core/java/com/android/server/stats/StatsCompanionService.java
@@ -107,6 +107,15 @@
 
     public static final int CODE_DATA_BROADCAST = 1;
     public static final int CODE_SUBSCRIBER_BROADCAST = 1;
+    /**
+     * The last report time is provided with each intent registered to
+     * StatsManager#setFetchReportsOperation. This allows easy de-duping in the receiver if
+     * statsd is requesting the client to retrieve the same statsd data. The last report time
+     * corresponds to the last_report_elapsed_nanos that will provided in the current
+     * ConfigMetricsReport, and this timestamp also corresponds to the
+     * current_report_elapsed_nanos of the most recently obtained ConfigMetricsReport.
+     */
+    public static final String EXTRA_LAST_REPORT_TIME = "android.app.extra.LAST_REPORT_TIME";
     public static final int DEATH_THRESHOLD = 10;
 
     private final Context mContext;
@@ -197,10 +206,11 @@
     }
 
     @Override
-    public void sendDataBroadcast(IBinder intentSenderBinder) {
+    public void sendDataBroadcast(IBinder intentSenderBinder, long lastReportTimeNs) {
         enforceCallingPermission();
         IntentSender intentSender = new IntentSender(intentSenderBinder);
         Intent intent = new Intent();
+        intent.putExtra(EXTRA_LAST_REPORT_TIME, lastReportTimeNs);
         try {
             intentSender.sendIntent(mContext, CODE_DATA_BROADCAST, intent, null, null);
         } catch (IntentSender.SendIntentException e) {
@@ -274,7 +284,7 @@
         // Add in all the apps for every user/profile.
         for (UserInfo profile : users) {
             List<PackageInfo> pi =
-                pm.getInstalledPackagesAsUser(PackageManager.MATCH_DISABLED_COMPONENTS, profile.id);
+                pm.getInstalledPackagesAsUser(PackageManager.MATCH_KNOWN_PACKAGES, profile.id);
             for (int j = 0; j < pi.size(); j++) {
                 if (pi.get(j).applicationInfo != null) {
                     uids.add(pi.get(j).applicationInfo.uid);