Add tracking of uid process states in battery stats.

We now keep track of how long each uid had processes in
various states: foreground, active, running.  This is based
on a collapse of the various activity manager process states
into these three bins.

You'll see these in a checkin like this:

8,10013,l,st,61504,61504,83109

Also fix issue #16021555: App showing up as on "top" even
when the screen is off.  This is "fixed" by just saying we
always report the current app at the top of the activity stack,
regardless of the state of the screen.

Change-Id: I1204904225101243eb00b43425d9806bffdd2ab9
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index 21d60c5..d0a6f08 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -115,6 +115,11 @@
     public static final int WIFI_BATCHED_SCAN = 11;
 
     /**
+     * A constant indicating a process state timer
+     */
+    public static final int PROCESS_STATE = 12;
+
+    /**
      * Include all of the data in the stats, including previously saved data.
      */
     public static final int STATS_SINCE_CHARGED = 0;
@@ -150,6 +155,7 @@
     private static final String SENSOR_DATA = "sr";
     private static final String VIBRATOR_DATA = "vib";
     private static final String FOREGROUND_DATA = "fg";
+    private static final String STATE_TIME_DATA = "st";
     private static final String WAKELOCK_DATA = "wl";
     private static final String KERNEL_WAKELOCK_DATA = "kwl";
     private static final String WAKEUP_REASON_DATA = "wr";
@@ -278,7 +284,7 @@
          *
          * @return a Map from Integer sensor ids to Uid.Sensor objects.
          */
-        public abstract Map<Integer, ? extends Sensor> getSensorStats();
+        public abstract SparseArray<? extends Sensor> getSensorStats();
 
         /**
          * Returns a mapping containing active process data.
@@ -328,6 +334,22 @@
         public abstract long getAudioTurnedOnTime(long elapsedRealtimeUs, int which);
         public abstract long getVideoTurnedOnTime(long elapsedRealtimeUs, int which);
         public abstract Timer getForegroundActivityTimer();
+
+        // Time this uid has any processes in foreground state.
+        public static final int PROCESS_STATE_FOREGROUND = 0;
+        // Time this uid has any process in active state (not cached).
+        public static final int PROCESS_STATE_ACTIVE = 1;
+        // Time this uid has any processes running at all.
+        public static final int PROCESS_STATE_RUNNING = 2;
+        // Total number of process states we track.
+        public static final int NUM_PROCESS_STATE = 3;
+
+        static final String[] PROCESS_STATE_NAMES = {
+            "Foreground", "Active", "Running"
+        };
+
+        public abstract long getProcessStateTime(int state, long elapsedRealtimeUs, int which);
+
         public abstract Timer getVibratorOnTimer();
 
         public static final int NUM_WIFI_BATCHED_SCAN_BINS = 5;
@@ -2082,22 +2104,20 @@
                     }
                 }
             }
-                
-            Map<Integer, ? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats();
-            if (sensors.size() > 0)  {
-                for (Map.Entry<Integer, ? extends BatteryStats.Uid.Sensor> ent
-                        : sensors.entrySet()) {
-                    Uid.Sensor se = ent.getValue();
-                    int sensorNumber = ent.getKey();
-                    Timer timer = se.getSensorTime();
-                    if (timer != null) {
-                        // Convert from microseconds to milliseconds with rounding
-                        long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
-                        int count = timer.getCountLocked(which);
-                        if (totalTime != 0) {
-                            dumpLine(pw, uid, category, SENSOR_DATA, sensorNumber, totalTime, count);
-                        }
-                    } 
+
+            SparseArray<? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats();
+            int NSE = sensors.size();
+            for (int ise=0; ise<NSE; ise++) {
+                Uid.Sensor se = sensors.valueAt(ise);
+                int sensorNumber = sensors.keyAt(ise);
+                Timer timer = se.getSensorTime();
+                if (timer != null) {
+                    // Convert from microseconds to milliseconds with rounding
+                    long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
+                    int count = timer.getCountLocked(which);
+                    if (totalTime != 0) {
+                        dumpLine(pw, uid, category, SENSOR_DATA, sensorNumber, totalTime, count);
+                    }
                 }
             }
 
@@ -2121,6 +2141,16 @@
                 }
             }
 
+            Object[] stateTimes = new Object[Uid.NUM_PROCESS_STATE];
+            long totalStateTime = 0;
+            for (int ips=0; ips<Uid.NUM_PROCESS_STATE; ips++) {
+                totalStateTime += u.getProcessStateTime(ips, rawRealtime, which);
+                stateTimes[ips] = (totalStateTime + 500) / 1000;
+            }
+            if (totalStateTime > 0) {
+                dumpLine(pw, uid, category, STATE_TIME_DATA, stateTimes);
+            }
+
             Map<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats();
             if (processStats.size() > 0) {
                 for (Map.Entry<String, ? extends BatteryStats.Uid.Proc> ent
@@ -2968,45 +2998,43 @@
                 }
             }
 
-            Map<Integer, ? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats();
-            if (sensors.size() > 0) {
-                for (Map.Entry<Integer, ? extends BatteryStats.Uid.Sensor> ent
-                    : sensors.entrySet()) {
-                    Uid.Sensor se = ent.getValue();
-                    int sensorNumber = ent.getKey();
-                    sb.setLength(0);
-                    sb.append(prefix);
-                    sb.append("    Sensor ");
-                    int handle = se.getHandle();
-                    if (handle == Uid.Sensor.GPS) {
-                        sb.append("GPS");
-                    } else {
-                        sb.append(handle);
-                    }
-                    sb.append(": ");
+            SparseArray<? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats();
+            int NSE = sensors.size();
+            for (int ise=0; ise<NSE; ise++) {
+                Uid.Sensor se = sensors.valueAt(ise);
+                int sensorNumber = sensors.keyAt(ise);
+                sb.setLength(0);
+                sb.append(prefix);
+                sb.append("    Sensor ");
+                int handle = se.getHandle();
+                if (handle == Uid.Sensor.GPS) {
+                    sb.append("GPS");
+                } else {
+                    sb.append(handle);
+                }
+                sb.append(": ");
 
-                    Timer timer = se.getSensorTime();
-                    if (timer != null) {
-                        // Convert from microseconds to milliseconds with rounding
-                        long totalTime = (timer.getTotalTimeLocked(
-                                rawRealtime, which) + 500) / 1000;
-                        int count = timer.getCountLocked(which);
-                        //timer.logState();
-                        if (totalTime != 0) {
-                            formatTimeMs(sb, totalTime);
-                            sb.append("realtime (");
-                            sb.append(count);
-                            sb.append(" times)");
-                        } else {
-                            sb.append("(not used)");
-                        }
+                Timer timer = se.getSensorTime();
+                if (timer != null) {
+                    // Convert from microseconds to milliseconds with rounding
+                    long totalTime = (timer.getTotalTimeLocked(
+                            rawRealtime, which) + 500) / 1000;
+                    int count = timer.getCountLocked(which);
+                    //timer.logState();
+                    if (totalTime != 0) {
+                        formatTimeMs(sb, totalTime);
+                        sb.append("realtime (");
+                        sb.append(count);
+                        sb.append(" times)");
                     } else {
                         sb.append("(not used)");
                     }
-
-                    pw.println(sb.toString());
-                    uidActivity = true;
+                } else {
+                    sb.append("(not used)");
                 }
+
+                pw.println(sb.toString());
+                uidActivity = true;
             }
 
             Timer vibTimer = u.getVibratorOnTimer();
@@ -3047,6 +3075,22 @@
                 }
             }
 
+            long totalStateTime = 0;
+            for (int ips=0; ips<Uid.NUM_PROCESS_STATE; ips++) {
+                long time = u.getProcessStateTime(ips, rawRealtime, which);
+                if (time > 0) {
+                    totalStateTime += time;
+                    sb.setLength(0);
+                    sb.append(prefix);
+                    sb.append("    ");
+                    sb.append(Uid.PROCESS_STATE_NAMES[ips]);
+                    sb.append(" for: ");
+                    formatTimeMs(sb, (totalStateTime + 500) / 1000);
+                    pw.println(sb.toString());
+                    uidActivity = true;
+                }
+            }
+
             Map<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats();
             if (processStats.size() > 0) {
                 for (Map.Entry<String, ? extends BatteryStats.Uid.Proc> ent