Add some wifi tracking to battery stats.

Now track supplicant state and wifi signal strength.
Output looks like this:

         +12m45s235ms (1) 095 +wifi_full_lock +wifi_running wifi_signal_strength=3 wifi_suppl=scanning
         +12m46s095ms (1) 095 -wifi_full_lock wifi_suppl=associated
         +12m46s469ms (2) 095 wifi_suppl=completed +proc=u0a74:"com.google.android.videos"
         +12m52s103ms (1) 095 +wifi_full_lock wifi_suppl=disconn

Also modify history dump so that when we hit a RESET or START
command, we clear our previous history data, so the next event
will include new data.  This means if you are scanning through
the output, you must at this point clear any binary stats you
have like "running" or "wake_lock" or else you will continue to
think they are on until whatever point later they get turned on
and then back off.

And a small bug fix in proc stats that would cause the system
process to crash.

Change-Id: Ibec416a1ef786d428bd0d1d86e6e3296c41f7648
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 1ccaa0f3..02e4b3f 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -24,6 +24,7 @@
 import android.content.Context;
 import android.net.ConnectivityManager;
 import android.net.NetworkStats;
+import android.net.wifi.WifiManager;
 import android.os.BadParcelableException;
 import android.os.BatteryManager;
 import android.os.BatteryStats;
@@ -88,7 +89,7 @@
     private static final int MAGIC = 0xBA757475; // 'BATSTATS'
 
     // Current on-disk Parcel version
-    private static final int VERSION = 106 + (USE_OLD_HISTORY ? 1000 : 0);
+    private static final int VERSION = 107 + (USE_OLD_HISTORY ? 1000 : 0);
 
     // Maximum number of items we will record in the history.
     private static final int MAX_HISTORY_ITEMS = 2000;
@@ -284,6 +285,13 @@
     int mWifiState = -1;
     final StopwatchTimer[] mWifiStateTimer = new StopwatchTimer[NUM_WIFI_STATES];
 
+    int mWifiSupplState = -1;
+    final StopwatchTimer[] mWifiSupplStateTimer = new StopwatchTimer[NUM_WIFI_SUPPL_STATES];
+
+    int mWifiSignalStrengthBin = -1;
+    final StopwatchTimer[] mWifiSignalStrengthsTimer =
+            new StopwatchTimer[NUM_WIFI_SIGNAL_STRENGTH_BINS];
+
     boolean mBluetoothOn;
     StopwatchTimer mBluetoothOnTimer;
 
@@ -2086,7 +2094,9 @@
             if (mHistoryLastWritten.batteryLevel == cur.batteryLevel &&
                     (dataSize >= MAX_MAX_HISTORY_BUFFER
                             || ((mHistoryLastWritten.states^cur.states)
-                                    & HistoryItem.MOST_INTERESTING_STATES) == 0)) {
+                                    & HistoryItem.MOST_INTERESTING_STATES) == 0
+                            || ((mHistoryLastWritten.states2^cur.states2)
+                                    & HistoryItem.MOST_INTERESTING_STATES2) == 0)) {
                 return;
             }
 
@@ -2863,7 +2873,7 @@
         }
     }
 
-    void stopAllSignalStrengthTimersLocked(int except) {
+    void stopAllPhoneSignalStrengthTimersLocked(int except) {
         final long elapsedRealtime = SystemClock.elapsedRealtime();
         for (int i = 0; i < SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
             if (i == except) {
@@ -2959,13 +2969,13 @@
                 if (!mPhoneSignalStrengthsTimer[strengthBin].isRunningLocked()) {
                     mPhoneSignalStrengthsTimer[strengthBin].startRunningLocked(elapsedRealtime);
                 }
-                mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_SIGNAL_STRENGTH_MASK)
-                        | (strengthBin << HistoryItem.STATE_SIGNAL_STRENGTH_SHIFT);
+                mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_PHONE_SIGNAL_STRENGTH_MASK)
+                        | (strengthBin << HistoryItem.STATE_PHONE_SIGNAL_STRENGTH_SHIFT);
                 if (DEBUG_HISTORY) Slog.v(TAG, "Signal strength " + strengthBin + " to: "
                         + Integer.toHexString(mHistoryCur.states));
                 newHistory = true;
             } else {
-                stopAllSignalStrengthTimersLocked(-1);
+                stopAllPhoneSignalStrengthTimersLocked(-1);
             }
             mPhoneSignalStrengthBin = strengthBin;
         }
@@ -3065,7 +3075,7 @@
         if (!mWifiOn) {
             final long elapsedRealtime = SystemClock.elapsedRealtime();
             final long uptime = SystemClock.uptimeMillis();
-            mHistoryCur.states |= HistoryItem.STATE_WIFI_ON_FLAG;
+            mHistoryCur.states2 |= HistoryItem.STATE2_WIFI_ON_FLAG;
             if (DEBUG_HISTORY) Slog.v(TAG, "WIFI on to: "
                     + Integer.toHexString(mHistoryCur.states));
             addHistoryRecordLocked(elapsedRealtime, uptime);
@@ -3078,7 +3088,7 @@
         final long elapsedRealtime = SystemClock.elapsedRealtime();
         final long uptime = SystemClock.uptimeMillis();
         if (mWifiOn) {
-            mHistoryCur.states &= ~HistoryItem.STATE_WIFI_ON_FLAG;
+            mHistoryCur.states2 &= ~HistoryItem.STATE2_WIFI_ON_FLAG;
             if (DEBUG_HISTORY) Slog.v(TAG, "WIFI off to: "
                     + Integer.toHexString(mHistoryCur.states));
             addHistoryRecordLocked(elapsedRealtime, uptime);
@@ -3171,7 +3181,7 @@
         if (!mGlobalWifiRunning) {
             final long elapsedRealtime = SystemClock.elapsedRealtime();
             final long uptime = SystemClock.uptimeMillis();
-            mHistoryCur.states |= HistoryItem.STATE_WIFI_RUNNING_FLAG;
+            mHistoryCur.states2 |= HistoryItem.STATE2_WIFI_RUNNING_FLAG;
             if (DEBUG_HISTORY) Slog.v(TAG, "WIFI running to: "
                     + Integer.toHexString(mHistoryCur.states));
             addHistoryRecordLocked(elapsedRealtime, uptime);
@@ -3209,7 +3219,7 @@
         if (mGlobalWifiRunning) {
             final long elapsedRealtime = SystemClock.elapsedRealtime();
             final long uptime = SystemClock.uptimeMillis();
-            mHistoryCur.states &= ~HistoryItem.STATE_WIFI_RUNNING_FLAG;
+            mHistoryCur.states2 &= ~HistoryItem.STATE2_WIFI_RUNNING_FLAG;
             if (DEBUG_HISTORY) Slog.v(TAG, "WIFI stopped to: "
                     + Integer.toHexString(mHistoryCur.states));
             addHistoryRecordLocked(elapsedRealtime, uptime);
@@ -3237,6 +3247,64 @@
         }
     }
 
+    public void noteWifiSupplicantStateChangedLocked(int supplState, boolean failedAuth) {
+        if (DEBUG) Log.i(TAG, "WiFi suppl state -> " + supplState);
+        if (mWifiSupplState != supplState) {
+            final long elapsedRealtime = SystemClock.elapsedRealtime();
+            final long uptime = SystemClock.uptimeMillis();
+            if (mWifiSupplState >= 0) {
+                mWifiSupplStateTimer[mWifiSupplState].stopRunningLocked(elapsedRealtime);
+            }
+            mWifiSupplState = supplState;
+            mWifiSupplStateTimer[supplState].startRunningLocked(elapsedRealtime);
+            mHistoryCur.states2 =
+                    (mHistoryCur.states2&~HistoryItem.STATE2_WIFI_SUPPL_STATE_MASK)
+                    | (supplState << HistoryItem.STATE2_WIFI_SUPPL_STATE_SHIFT);
+            if (DEBUG_HISTORY) Slog.v(TAG, "Wifi suppl state " + supplState + " to: "
+                    + Integer.toHexString(mHistoryCur.states2));
+            addHistoryRecordLocked(elapsedRealtime, uptime);
+        }
+    }
+
+    void stopAllWifiSignalStrengthTimersLocked(int except) {
+        final long elapsedRealtime = SystemClock.elapsedRealtime();
+        for (int i = 0; i < NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
+            if (i == except) {
+                continue;
+            }
+            while (mWifiSignalStrengthsTimer[i].isRunningLocked()) {
+                mWifiSignalStrengthsTimer[i].stopRunningLocked(elapsedRealtime);
+            }
+        }
+    }
+
+    public void noteWifiRssiChangedLocked(int newRssi) {
+        int strengthBin = WifiManager.calculateSignalLevel(newRssi, NUM_WIFI_SIGNAL_STRENGTH_BINS);
+        if (DEBUG) Log.i(TAG, "WiFi rssi -> " + newRssi + " bin=" + strengthBin);
+        if (mWifiSignalStrengthBin != strengthBin) {
+            final long elapsedRealtime = SystemClock.elapsedRealtime();
+            final long uptime = SystemClock.uptimeMillis();
+            if (mWifiSignalStrengthBin >= 0) {
+                mWifiSignalStrengthsTimer[mWifiSignalStrengthBin].stopRunningLocked(
+                        elapsedRealtime);
+            }
+            if (strengthBin >= 0) {
+                if (!mWifiSignalStrengthsTimer[strengthBin].isRunningLocked()) {
+                    mWifiSignalStrengthsTimer[strengthBin].startRunningLocked(elapsedRealtime);
+                }
+                mHistoryCur.states2 =
+                        (mHistoryCur.states2&~HistoryItem.STATE2_WIFI_SIGNAL_STRENGTH_MASK)
+                        | (strengthBin << HistoryItem.STATE2_WIFI_SIGNAL_STRENGTH_SHIFT);
+                if (DEBUG_HISTORY) Slog.v(TAG, "Wifi signal strength " + strengthBin + " to: "
+                        + Integer.toHexString(mHistoryCur.states2));
+                addHistoryRecordLocked(elapsedRealtime, uptime);
+            } else {
+                stopAllWifiSignalStrengthTimersLocked(-1);
+            }
+            mWifiSignalStrengthBin = strengthBin;
+        }
+    }
+
     public void noteBluetoothOnLocked() {
         if (!mBluetoothOn) {
             final long elapsedRealtime = SystemClock.elapsedRealtime();
@@ -3580,6 +3648,26 @@
         return mWifiStateTimer[wifiState].getCountLocked(which);
     }
 
+    @Override public long getWifiSupplStateTime(int state,
+            long elapsedRealtimeUs, int which) {
+        return mWifiSupplStateTimer[state].getTotalTimeLocked(
+                elapsedRealtimeUs, which);
+    }
+
+    @Override public int getWifiSupplStateCount(int state, int which) {
+        return mWifiSupplStateTimer[state].getCountLocked(which);
+    }
+
+    @Override public long getWifiSignalStrengthTime(int strengthBin,
+            long elapsedRealtimeUs, int which) {
+        return mWifiSignalStrengthsTimer[strengthBin].getTotalTimeLocked(
+                elapsedRealtimeUs, which);
+    }
+
+    @Override public int getWifiSignalStrengthCount(int strengthBin, int which) {
+        return mWifiSignalStrengthsTimer[strengthBin].getCountLocked(which);
+    }
+
     @Override public long getBluetoothOnTime(long elapsedRealtimeUs, int which) {
         return mBluetoothOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
     }
@@ -5580,6 +5668,13 @@
         for (int i=0; i<NUM_WIFI_STATES; i++) {
             mWifiStateTimer[i] = new StopwatchTimer(null, -600-i, null, mOnBatteryTimeBase);
         }
+        for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
+            mWifiSupplStateTimer[i] = new StopwatchTimer(null, -700-i, null, mOnBatteryTimeBase);
+        }
+        for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
+            mWifiSignalStrengthsTimer[i] = new StopwatchTimer(null, -800-i, null,
+                    mOnBatteryTimeBase);
+        }
         mBluetoothOnTimer = new StopwatchTimer(null, -6, null, mOnBatteryTimeBase);
         for (int i=0; i< NUM_BLUETOOTH_STATES; i++) {
             mBluetoothStateTimer[i] = new StopwatchTimer(null, -500-i, null, mOnBatteryTimeBase);
@@ -5856,6 +5951,12 @@
         for (int i=0; i<NUM_WIFI_STATES; i++) {
             mWifiStateTimer[i].reset(false);
         }
+        for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
+            mWifiSupplStateTimer[i].reset(false);
+        }
+        for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
+            mWifiSignalStrengthsTimer[i].reset(false);
+        }
         mBluetoothOnTimer.reset(false);
         for (int i=0; i< NUM_BLUETOOTH_STATES; i++) {
             mBluetoothStateTimer[i].reset(false);
@@ -7012,6 +7113,12 @@
         for (int i=0; i<NUM_WIFI_STATES; i++) {
             mWifiStateTimer[i].readSummaryFromParcelLocked(in);
         }
+        for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
+            mWifiSupplStateTimer[i].readSummaryFromParcelLocked(in);
+        }
+        for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
+            mWifiSignalStrengthsTimer[i].readSummaryFromParcelLocked(in);
+        }
         mBluetoothOn = false;
         mBluetoothOnTimer.readSummaryFromParcelLocked(in);
         for (int i=0; i< NUM_BLUETOOTH_STATES; i++) {
@@ -7264,6 +7371,12 @@
         for (int i=0; i<NUM_WIFI_STATES; i++) {
             mWifiStateTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
         }
+        for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
+            mWifiSupplStateTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
+        }
+        for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
+            mWifiSignalStrengthsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
+        }
         mBluetoothOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
         for (int i=0; i< NUM_BLUETOOTH_STATES; i++) {
             mBluetoothStateTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
@@ -7536,6 +7649,14 @@
             mWifiStateTimer[i] = new StopwatchTimer(null, -600-i,
                     null, mOnBatteryTimeBase, in);
         }
+        for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
+            mWifiSupplStateTimer[i] = new StopwatchTimer(null, -700-i,
+                    null, mOnBatteryTimeBase, in);
+        }
+        for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
+            mWifiSignalStrengthsTimer[i] = new StopwatchTimer(null, -800-i,
+                    null, mOnBatteryTimeBase, in);
+        }
         mBluetoothOn = false;
         mBluetoothOnTimer = new StopwatchTimer(null, -6, null, mOnBatteryTimeBase, in);
         for (int i=0; i< NUM_BLUETOOTH_STATES; i++) {
@@ -7667,6 +7788,12 @@
         for (int i=0; i<NUM_WIFI_STATES; i++) {
             mWifiStateTimer[i].writeToParcel(out, uSecRealtime);
         }
+        for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
+            mWifiSupplStateTimer[i].writeToParcel(out, uSecRealtime);
+        }
+        for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
+            mWifiSignalStrengthsTimer[i].writeToParcel(out, uSecRealtime);
+        }
         mBluetoothOnTimer.writeToParcel(out, uSecRealtime);
         for (int i=0; i< NUM_BLUETOOTH_STATES; i++) {
             mBluetoothStateTimer[i].writeToParcel(out, uSecRealtime);
@@ -7768,7 +7895,7 @@
             pr.println("*** Phone timer:");
             mPhoneOnTimer.logState(pr, "  ");
             for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
-                pr.println("*** Signal strength #" + i + ":");
+                pr.println("*** Phone signal strength #" + i + ":");
                 mPhoneSignalStrengthsTimer[i].logState(pr, "  ");
             }
             pr.println("*** Signal scanning :");
@@ -7790,6 +7917,14 @@
                 pr.println("*** Wifi state #" + i + ":");
                 mWifiStateTimer[i].logState(pr, "  ");
             }
+            for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
+                pr.println("*** Wifi suppl state #" + i + ":");
+                mWifiSupplStateTimer[i].logState(pr, "  ");
+            }
+            for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
+                pr.println("*** Wifi signal strength #" + i + ":");
+                mWifiSignalStrengthsTimer[i].logState(pr, "  ");
+            }
             pr.println("*** Bluetooth timer:");
             mBluetoothOnTimer.logState(pr, "  ");
             for (int i=0; i< NUM_BLUETOOTH_STATES; i++) {