Merge "Prepare LooperStats to be collected as a Westworld gauge matric"
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index 4738749..786e76c 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -2272,6 +2272,14 @@
     optional int64 exception_count = 2;
 }
 
+/**
+ * Pulls the statistics of message dispatching on HandlerThreads.
+ *
+ * Looper stats will be reset every time the data is pulled. It means it can only be pulled by one
+ * config on the device.
+ *
+ * Next tag: 11
+ */
 message LooperStats {
     // Currently not collected and always set to 0.
     optional int32 uid = 1 [(is_uid) = true];
@@ -2315,8 +2323,11 @@
     // Total CPU usage of all processed message.
     // Average can be computed using recorded_total_cpu_micros /
     // recorded_message_count. Total can be computed using
-    // recorded_total_cpu_micros / recorded_message_count * call_count.
+    // recorded_total_cpu_micros / recorded_message_count * message_count.
     optional int64 recorded_total_cpu_micros = 9;
+
+    // True if the screen was interactive PowerManager#isInteractive at the end of the call.
+    optional bool screen_interactive = 10;
 }
 
 /**
diff --git a/cmds/statsd/src/external/StatsPullerManager.cpp b/cmds/statsd/src/external/StatsPullerManager.cpp
index 1cd1330..745ff74 100644
--- a/cmds/statsd/src/external/StatsPullerManager.cpp
+++ b/cmds/statsd/src/external/StatsPullerManager.cpp
@@ -190,7 +190,7 @@
         // looper_stats
         {android::util::LOOPER_STATS,
          {{5, 6, 7, 8, 9},
-          {2, 3, 4},
+          {2, 3, 4, 10},
           1 * NS_PER_SEC,
           new StatsCompanionServicePuller(android::util::LOOPER_STATS)}},
         // Disk Stats
diff --git a/core/java/com/android/internal/os/LooperStats.java b/core/java/com/android/internal/os/LooperStats.java
index 02a8b22..0650d0af 100644
--- a/core/java/com/android/internal/os/LooperStats.java
+++ b/core/java/com/android/internal/os/LooperStats.java
@@ -106,6 +106,7 @@
         synchronized (entry) {
             entry.exceptionCount++;
         }
+
         recycleSession(session);
     }
 
@@ -116,29 +117,29 @@
 
     /** Returns an array of {@link ExportedEntry entries} with the aggregated statistics. */
     public List<ExportedEntry> getEntries() {
-        final ArrayList<ExportedEntry> entries;
+        final ArrayList<ExportedEntry> exportedEntries;
         synchronized (mLock) {
             final int size = mEntries.size();
-            entries = new ArrayList<>(size);
+            exportedEntries = new ArrayList<>(size);
             for (int i = 0; i < size; i++) {
                 Entry entry = mEntries.valueAt(i);
                 synchronized (entry) {
-                    entries.add(new ExportedEntry(entry));
+                    exportedEntries.add(new ExportedEntry(entry));
                 }
             }
         }
         // Add the overflow and collision entries only if they have any data.
-        if (mOverflowEntry.messageCount > 0 || mOverflowEntry.exceptionCount > 0) {
-            synchronized (mOverflowEntry) {
-                entries.add(new ExportedEntry(mOverflowEntry));
+        maybeAddSpecialEntry(exportedEntries, mOverflowEntry);
+        maybeAddSpecialEntry(exportedEntries, mHashCollisionEntry);
+        return exportedEntries;
+    }
+
+    private void maybeAddSpecialEntry(List<ExportedEntry> exportedEntries, Entry specialEntry) {
+        synchronized (specialEntry) {
+            if (specialEntry.messageCount > 0 || specialEntry.exceptionCount > 0) {
+                exportedEntries.add(new ExportedEntry(specialEntry));
             }
         }
-        if (mHashCollisionEntry.messageCount > 0 || mHashCollisionEntry.exceptionCount > 0) {
-            synchronized (mHashCollisionEntry) {
-                entries.add(new ExportedEntry(mHashCollisionEntry));
-            }
-        }
-        return entries;
     }
 
     /** Removes all collected data. */
diff --git a/core/tests/coretests/src/com/android/internal/os/LooperStatsTest.java b/core/tests/coretests/src/com/android/internal/os/LooperStatsTest.java
index 0eb3d06..565a3ec 100644
--- a/core/tests/coretests/src/com/android/internal/os/LooperStatsTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/LooperStatsTest.java
@@ -342,6 +342,20 @@
         assertThat(looperStats.getEntries().get(0).messageCount).isEqualTo(2);
     }
 
+    @Test
+    public void testReset() {
+        TestableLooperStats looperStats = new TestableLooperStats(1, 1);
+
+        Object token1 = looperStats.messageDispatchStarting();
+        looperStats.messageDispatched(token1, mHandlerFirst.obtainMessage(1000));
+        Object token2 = looperStats.messageDispatchStarting();
+        looperStats.messageDispatched(token2, mHandlerFirst.obtainMessage(2000));
+        looperStats.reset();
+
+        List<LooperStats.ExportedEntry> entries = looperStats.getEntries();
+        assertThat(entries).hasSize(0);
+    }
+
     private static void assertThrows(Class<? extends Exception> exceptionClass, Runnable r) {
         try {
             r.run();
diff --git a/services/core/java/com/android/server/stats/StatsCompanionService.java b/services/core/java/com/android/server/stats/StatsCompanionService.java
index 2091899..a4d42a1 100644
--- a/services/core/java/com/android/server/stats/StatsCompanionService.java
+++ b/services/core/java/com/android/server/stats/StatsCompanionService.java
@@ -976,10 +976,11 @@
         }
 
         List<LooperStats.ExportedEntry> entries = looperStats.getEntries();
+        looperStats.reset();
         long elapsedNanos = SystemClock.elapsedRealtimeNanos();
         for (LooperStats.ExportedEntry entry : entries) {
-            StatsLogEventWrapper e = new StatsLogEventWrapper(elapsedNanos, tagId, 9 /* fields */);
-            e.writeLong(0); // uid collection not implemented yet
+            StatsLogEventWrapper e = new StatsLogEventWrapper(elapsedNanos, tagId, 10 /* fields */);
+            e.writeInt(1000); // uid collection not implemented yet
             e.writeString(entry.handlerClassName);
             e.writeString(entry.threadName);
             e.writeString(entry.messageName);
@@ -988,6 +989,7 @@
             e.writeLong(entry.recordedMessageCount);
             e.writeLong(entry.totalLatencyMicros);
             e.writeLong(entry.cpuUsageMicros);
+            e.writeBoolean(entry.isInteractive);
             pulledData.add(e);
         }
     }