Work on issue #16629489: Google (Play?) Services eating through battery

There is a bug in how we deal with name overflows combined with resetting
the battery stats data.  If we do a reset while a wakelock is being
actively held that has been put into the overflow bucket, then we can
end up reducing the number of known wake locks in the list so when after
that it is released we try to release it under its real name rather than
the overflow name.

This means we need to keep track of which wake locks have been placed
in the overflow bucket while they are actively being used, so we can be
sure to properly handle it as part of that bucket until it is eventually
released.

This makes things...  somewhat more complicated.  So now we have a class
to take care of all these details, and also use it for other places where
we have the same overflow semantics sync and job stats.

Also fix potential deadlock -- BatteryStatsHelper needs to call on to
ConnectivityManager to find out of there is telepohny, however we use
that class when doing a dump while the battery stats lock is held.  To
fix this, we check the connectivity state up in the battery stats service
before acquiring the lock and propagate that information through to the
dump code.

Change-Id: Ib452206af5c36f4b0f03cc94d2845d36613d1ba5
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index 7d086e1..be46bc7 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -1843,13 +1843,21 @@
         }
         pw.println();
     }
-    
+
+    /**
+     * Temporary for settings.
+     */
+    public final void dumpCheckinLocked(Context context, PrintWriter pw, int which, int reqUid) {
+        dumpCheckinLocked(context, pw, which, reqUid, BatteryStatsHelper.checkWifiOnly(context));
+    }
+
     /**
      * Checkin server version of dump to produce more compact, computer-readable log.
      * 
      * NOTE: all times are expressed in 'ms'.
      */
-    public final void dumpCheckinLocked(Context context, PrintWriter pw, int which, int reqUid) {
+    public final void dumpCheckinLocked(Context context, PrintWriter pw, int which, int reqUid,
+            boolean wifiOnly) {
         final long rawUptime = SystemClock.uptimeMillis() * 1000;
         final long rawRealtime = SystemClock.elapsedRealtime() * 1000;
         final long batteryUptime = getBatteryUptime(rawUptime);
@@ -2046,7 +2054,7 @@
             }
         }
         
-        BatteryStatsHelper helper = new BatteryStatsHelper(context, false);
+        BatteryStatsHelper helper = new BatteryStatsHelper(context, false, wifiOnly);
         helper.create(this);
         helper.refreshStats(which, UserHandle.USER_ALL);
         List<BatterySipper> sippers = helper.getUsageList();
@@ -2315,9 +2323,17 @@
         printer.print(BatteryStatsHelper.makemAh(power));
     }
 
+    /**
+     * Temporary for settings.
+     */
+    public final void dumpLocked(Context context, PrintWriter pw, String prefix, int which,
+            int reqUid) {
+        dumpLocked(context, pw, prefix, which, reqUid, BatteryStatsHelper.checkWifiOnly(context));
+    }
+
     @SuppressWarnings("unused")
     public final void dumpLocked(Context context, PrintWriter pw, String prefix, final int which,
-            int reqUid) {
+            int reqUid, boolean wifiOnly) {
         final long rawUptime = SystemClock.uptimeMillis() * 1000;
         final long rawRealtime = SystemClock.elapsedRealtime() * 1000;
         final long batteryUptime = getBatteryUptime(rawUptime);
@@ -2746,7 +2762,7 @@
             pw.println();
         }
 
-        BatteryStatsHelper helper = new BatteryStatsHelper(context, false);
+        BatteryStatsHelper helper = new BatteryStatsHelper(context, false, wifiOnly);
         helper.create(this);
         helper.refreshStats(which, UserHandle.USER_ALL);
         List<BatterySipper> sippers = helper.getUsageList();
@@ -3723,6 +3739,7 @@
     public static final int DUMP_HISTORY_ONLY = 1<<2;
     public static final int DUMP_INCLUDE_HISTORY = 1<<3;
     public static final int DUMP_VERBOSE = 1<<4;
+    public static final int DUMP_DEVICE_WIFI_ONLY = 1<<5;
 
     private void dumpHistoryLocked(PrintWriter pw, int flags, long histStart, boolean checkin) {
         final HistoryPrinter hprinter = new HistoryPrinter();
@@ -3918,12 +3935,14 @@
             pw.println("Statistics since last charge:");
             pw.println("  System starts: " + getStartCount()
                     + ", currently on battery: " + getIsOnBattery());
-            dumpLocked(context, pw, "", STATS_SINCE_CHARGED, reqUid);
+            dumpLocked(context, pw, "", STATS_SINCE_CHARGED, reqUid,
+                    (flags&DUMP_DEVICE_WIFI_ONLY) != 0);
             pw.println();
         }
         if (!filtering || (flags&DUMP_UNPLUGGED_ONLY) != 0) {
             pw.println("Statistics since last unplugged:");
-            dumpLocked(context, pw, "", STATS_SINCE_UNPLUGGED, reqUid);
+            dumpLocked(context, pw, "", STATS_SINCE_UNPLUGGED, reqUid,
+                    (flags&DUMP_DEVICE_WIFI_ONLY) != 0);
         }
     }
     
@@ -4013,10 +4032,12 @@
                 dumpLine(pw, 0 /* uid */, "i" /* category */, CHARGE_TIME_REMAIN_DATA,
                         (Object[])lineArgs);
             }
-            dumpCheckinLocked(context, pw, STATS_SINCE_CHARGED, -1);
+            dumpCheckinLocked(context, pw, STATS_SINCE_CHARGED, -1,
+                    (flags&DUMP_DEVICE_WIFI_ONLY) != 0);
         }
         if (!filtering || (flags&DUMP_UNPLUGGED_ONLY) != 0) {
-            dumpCheckinLocked(context, pw, STATS_SINCE_UNPLUGGED, -1);
+            dumpCheckinLocked(context, pw, STATS_SINCE_UNPLUGGED, -1,
+                    (flags&DUMP_DEVICE_WIFI_ONLY) != 0);
         }
     }
 }