Added actual (unpooled) partial wakelock times.

Previously, partial wakelock times reported the blame apportioned to the
app (i.e. the times were pooled). This CL adds another field to provide
the actual time the partial wakelock was held (unpooled, irrespective of
other app's wakelock usage). Full and window wakelocks also now have the
equivalent field, but it always returns -1 (like their max and current
durations), since none of those are currently tracked. Kernel wakelocks
are unchanged.

Test: cts-tradefed run cts-dev -m CtsDumpsysHostTestCases -t android.dumpsys.cts.BatteryStatsDumpsysTest
Bug: 18998184
Change-Id: Ic4cc8c3abba9afa60902d0c8e17e11abeef52a96
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index 235f24c..1eb0a8c 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -183,8 +183,10 @@
      *   - Wakelock data (wl) gets current and max times.
      * New in version 20:
      *   - Background timers and counters for: Sensor, BluetoothScan, WifiScan, Jobs, Syncs.
+     * New in version 21:
+     *   - Actual (not just apportioned) Wakelock time is also recorded.
      */
-    static final String CHECKIN_VERSION = "20";
+    static final String CHECKIN_VERSION = "21";
 
     /**
      * Old version, we hit 9 and ran out of room, need to remove.
@@ -194,7 +196,7 @@
     private static final long BYTES_PER_KB = 1024;
     private static final long BYTES_PER_MB = 1048576; // 1024^2
     private static final long BYTES_PER_GB = 1073741824; //1024^3
-    
+
     private static final String VERSION_DATA = "vers";
     private static final String UID_DATA = "uid";
     private static final String WAKEUP_ALARM_DATA = "wua";
@@ -205,6 +207,12 @@
     private static final String VIBRATOR_DATA = "vib";
     private static final String FOREGROUND_DATA = "fg";
     private static final String STATE_TIME_DATA = "st";
+    // wl line is:
+    // BATTERY_STATS_CHECKIN_VERSION, uid, which, "wl", name,
+    // full totalTime,    'f', count, current duration, max duration, total duration,
+    // partial totalTime, 'p', count, current duration, max duration, total duration,
+    // window totalTime,  'w', count, current duration, max duration, total duration
+    // [Currently, full and window wakelocks have durations current = max = total = -1]
     private static final String WAKELOCK_DATA = "wl";
     private static final String SYNC_DATA = "sy";
     private static final String JOB_DATA = "jb";
@@ -2659,6 +2667,12 @@
                     sb.append(" max=");
                     sb.append(maxDurationMs);
                 }
+                // Put actual time if it is available and different from totalTimeMillis.
+                final long totalDurMs = timer.getTotalDurationMsLocked(elapsedRealtimeUs/1000);
+                if (totalDurMs > totalTimeMillis) {
+                    sb.append(" actual=");
+                    sb.append(totalDurMs);
+                }
                 if (timer.isRunningLocked()) {
                     final long currentMs = timer.getCurrentDurationMsLocked(elapsedRealtimeUs/1000);
                     if (currentMs >= 0) {
@@ -2744,11 +2758,13 @@
         int count = 0;
         long max = -1;
         long current = -1;
+        long totalDuration = -1;
         if (timer != null) {
             totalTimeMicros = timer.getTotalTimeLocked(elapsedRealtimeUs, which);
-            count = timer.getCountLocked(which); 
+            count = timer.getCountLocked(which);
             current = timer.getCurrentDurationMsLocked(elapsedRealtimeUs/1000);
             max = timer.getMaxDurationMsLocked(elapsedRealtimeUs/1000);
+            totalDuration = timer.getTotalDurationMsLocked(elapsedRealtimeUs/1000);
         }
         sb.append(linePrefix);
         sb.append((totalTimeMicros + 500) / 1000); // microseconds to milliseconds with rounding
@@ -2759,9 +2775,16 @@
         sb.append(current);
         sb.append(',');
         sb.append(max);
+        // Partial, full, and window wakelocks are pooled, so totalDuration is meaningful (albeit
+        // not always tracked). Kernel wakelocks (which have name == null) have no notion of
+        // totalDuration independent of totalTimeMicros (since they are not pooled).
+        if (name != null) {
+            sb.append(',');
+            sb.append(totalDuration);
+        }
         return ",";
     }
-    
+
     private static final void dumpLineHeader(PrintWriter pw, int uid, String category,
                                              String type) {
         pw.print(BATTERY_STATS_CHECKIN_VERSION);