Automated import from //branches/donutburger/...@140679,140679
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index 76c74df..d492b6a 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -292,7 +292,7 @@
      * {@hide}
      */
     public abstract long getPhoneOnTime(long batteryRealtime, int which);
-    
+
     /**
      * Returns the time in milliseconds that wifi has been on while the device was
      * running on battery.
@@ -300,7 +300,15 @@
      * {@hide}
      */
     public abstract long getWifiOnTime(long batteryRealtime, int which);
-    
+
+    /**
+     * Returns the time in milliseconds that wifi has been on and the driver has
+     * been in the running state while the device was running on battery.
+     *
+     * {@hide}
+     */
+    public abstract long getWifiRunningTime(long batteryRealtime, int which);
+
     /**
      * Returns the time in milliseconds that bluetooth has been on while the device was
      * running on battery.
@@ -535,6 +543,7 @@
         final long screenOnTime = getScreenOnTime(batteryRealtime, which);
         final long phoneOnTime = getPhoneOnTime(batteryRealtime, which);
         final long wifiOnTime = getWifiOnTime(batteryRealtime, which);
+        final long wifiRunningTime = getWifiRunningTime(batteryRealtime, which);
         final long bluetoothOnTime = getBluetoothOnTime(batteryRealtime, which);
        
         StringBuilder sb = new StringBuilder(128);
@@ -549,7 +558,8 @@
         
         // Dump misc stats
         dumpLine(pw, 0 /* uid */, category, MISC_DATA,
-                screenOnTime / 1000, phoneOnTime / 1000, wifiOnTime / 1000, bluetoothOnTime / 1000);
+                screenOnTime / 1000, phoneOnTime / 1000, wifiOnTime / 1000,
+                wifiRunningTime / 1000, bluetoothOnTime / 1000);
         
         if (which == STATS_UNPLUGGED) {
             dumpLine(pw, 0 /* uid */, category, BATTERY_DATA, getUnpluggedStartLevel(), 
@@ -667,7 +677,7 @@
         final long rawUptime = SystemClock.uptimeMillis() * 1000;
         final long rawRealtime = SystemClock.elapsedRealtime() * 1000;
         final long batteryUptime = getBatteryUptime(rawUptime);
-        final long batteryRealtime = getBatteryUptime(rawRealtime);
+        final long batteryRealtime = getBatteryRealtime(rawRealtime);
 
         final long whichBatteryUptime = computeBatteryUptime(rawUptime, which);
         final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which);
@@ -692,6 +702,7 @@
         
         final long screenOnTime = getScreenOnTime(batteryRealtime, which);
         final long phoneOnTime = getPhoneOnTime(batteryRealtime, which);
+        final long wifiRunningTime = getWifiRunningTime(batteryRealtime, which);
         final long wifiOnTime = getWifiOnTime(batteryRealtime, which);
         final long bluetoothOnTime = getBluetoothOnTime(batteryRealtime, which);
         pw.println(prefix
@@ -701,6 +712,8 @@
                 + "(" + formatRatioLocked(phoneOnTime, whichBatteryRealtime)
                 + "), time with wifi on: " + formatTimeMs(wifiOnTime / 1000)
                 + "(" + formatRatioLocked(wifiOnTime, whichBatteryRealtime)
+                + "), time with wifi running: " + formatTimeMs(wifiRunningTime / 1000)
+                + "(" + formatRatioLocked(wifiRunningTime, whichBatteryRealtime)
                 + "), time with bluetooth on: " + formatTimeMs(bluetoothOnTime / 1000)
                 + "(" + formatRatioLocked(bluetoothOnTime, whichBatteryRealtime)+ ")");
         
diff --git a/core/java/com/android/internal/app/IBatteryStats.aidl b/core/java/com/android/internal/app/IBatteryStats.aidl
index d259756..e0de421 100644
--- a/core/java/com/android/internal/app/IBatteryStats.aidl
+++ b/core/java/com/android/internal/app/IBatteryStats.aidl
@@ -32,6 +32,8 @@
     void notePhoneOff();
     void noteWifiOn();
     void noteWifiOff();
+    void noteWifiRunning();
+    void noteWifiStopped();
     void noteBluetoothOn();
     void noteBluetoothOff();
     void noteFullWifiLockAcquired(int uid);
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index b3ae0d6..38335b5 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -47,7 +47,7 @@
     private static final int MAGIC = 0xBA757475; // 'BATSTATS' 
 
     // Current on-disk Parcel version
-    private static final int VERSION = 27;
+    private static final int VERSION = 28;
 
     private final File mFile;
     private final File mBackupFile;
@@ -94,6 +94,9 @@
     
     boolean mWifiOn;
     Timer mWifiOnTimer;
+
+    boolean mWifiRunning;
+    Timer mWifiRunningTimer;
     
     boolean mBluetoothOn;
     Timer mBluetoothOnTimer;
@@ -497,6 +500,20 @@
         }
     }
     
+    public void noteWifiRunningLocked() {
+        if (!mWifiRunning) {
+            mWifiRunning = true;
+            mWifiRunningTimer.startRunningLocked(this);
+        }
+    }
+
+    public void noteWifiStoppedLocked() {
+        if (mWifiRunning) {
+            mWifiRunning = false;
+            mWifiRunningTimer.stopRunningLocked(this);
+        }
+    }
+
     public void noteBluetoothOnLocked() {
         if (!mBluetoothOn) {
             mBluetoothOn = true;
@@ -551,6 +568,10 @@
         return mWifiOnTimer.getTotalTime(batteryRealtime, which);
     }
     
+    @Override public long getWifiRunningTime(long batteryRealtime, int which) {
+        return mWifiRunningTimer.getTotalTime(batteryRealtime, which);
+    }
+
     @Override public long getBluetoothOnTime(long batteryRealtime, int which) {
         return mBluetoothOnTimer.getTotalTime(batteryRealtime, which);
     }
@@ -1597,7 +1618,8 @@
         mScreenOnTimer = new Timer(-1, null, mUnpluggables);
         mPhoneOnTimer = new Timer(-2, null, mUnpluggables);
         mWifiOnTimer = new Timer(-3, null, mUnpluggables);
-        mBluetoothOnTimer = new Timer(-4, null, mUnpluggables);
+        mWifiRunningTimer = new Timer(-4, null, mUnpluggables);
+        mBluetoothOnTimer = new Timer(-5, null, mUnpluggables);
         mOnBattery = mOnBatteryInternal = false;
         mTrackBatteryPastUptime = 0;
         mTrackBatteryPastRealtime = 0;
@@ -1935,6 +1957,8 @@
         mPhoneOnTimer.readSummaryFromParcelLocked(in);
         mWifiOn = false;
         mWifiOnTimer.readSummaryFromParcelLocked(in);
+        mWifiRunning = false;
+        mWifiRunningTimer.readSummaryFromParcelLocked(in);
         mBluetoothOn = false;
         mBluetoothOnTimer.readSummaryFromParcelLocked(in);
 
@@ -2038,6 +2062,7 @@
         mScreenOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
         mPhoneOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
         mWifiOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
+        mWifiRunningTimer.writeSummaryFromParcelLocked(out, NOWREAL);
         mBluetoothOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
 
         final int NU = mUidStats.size();
@@ -2163,6 +2188,8 @@
         mPhoneOnTimer = new Timer(-2, null, mUnpluggables, in);
         mWifiOn = false;
         mWifiOnTimer = new Timer(-2, null, mUnpluggables, in);
+        mWifiRunning = false;
+        mWifiRunningTimer = new Timer(-2, null, mUnpluggables, in);
         mBluetoothOn = false;
         mBluetoothOnTimer = new Timer(-2, null, mUnpluggables, in);
         mUptime = in.readLong();
@@ -2217,6 +2244,7 @@
         mScreenOnTimer.writeToParcel(out, batteryRealtime);
         mPhoneOnTimer.writeToParcel(out, batteryRealtime);
         mWifiOnTimer.writeToParcel(out, batteryRealtime);
+        mWifiRunningTimer.writeToParcel(out, batteryRealtime);
         mBluetoothOnTimer.writeToParcel(out, batteryRealtime);
         out.writeLong(mUptime);
         out.writeLong(mUptimeStart);
@@ -2264,6 +2292,8 @@
             mPhoneOnTimer.logState();
             Log.i(TAG, "*** Wifi timer:");
             mWifiOnTimer.logState();
+            Log.i(TAG, "*** WifiRunning timer:");
+            mWifiRunningTimer.logState();
             Log.i(TAG, "*** Bluetooth timer:");
             mBluetoothOnTimer.logState();
         }
diff --git a/services/java/com/android/server/WifiService.java b/services/java/com/android/server/WifiService.java
index ddf92e2..6323e2f 100644
--- a/services/java/com/android/server/WifiService.java
+++ b/services/java/com/android/server/WifiService.java
@@ -50,7 +50,6 @@
 import android.os.RemoteException;
 import android.provider.Settings;
 import android.util.Log;
-import android.telephony.TelephonyManager;
 import android.text.TextUtils;
 
 import java.util.ArrayList;
@@ -64,7 +63,6 @@
 import java.io.PrintWriter;
 
 import com.android.internal.app.IBatteryStats;
-import com.android.internal.os.BatteryStatsImpl;
 import com.android.server.am.BatteryStatsService;
 
 /**
@@ -1874,24 +1872,26 @@
     }
 
     private boolean releaseWifiLockLocked(IBinder lock) {
-        boolean result;
+        boolean hadLock;
         
         WifiLock wifiLock = mLocks.removeLock(lock);
-        result = (wifiLock != null);
-        
-        int uid = Binder.getCallingUid();
-        long ident = Binder.clearCallingIdentity();
-        try {
-            switch(wifiLock.mLockMode) {
-            case (WifiManager.WIFI_MODE_FULL): mBatteryStats.noteFullWifiLockReleased(uid);
-            case (WifiManager.WIFI_MODE_SCAN_ONLY): mBatteryStats.noteScanWifiLockReleased(uid);
+        hadLock = (wifiLock != null);
+
+        if (hadLock) {
+            int uid = Binder.getCallingUid();
+            long ident = Binder.clearCallingIdentity();
+            try {
+                switch(wifiLock.mLockMode) {
+                    case (WifiManager.WIFI_MODE_FULL): mBatteryStats.noteFullWifiLockReleased(uid);
+                    case (WifiManager.WIFI_MODE_SCAN_ONLY): mBatteryStats.noteScanWifiLockReleased(uid);
+                }
+            } catch (RemoteException e) {
+            } finally {
+                Binder.restoreCallingIdentity(ident);
             }
-        } catch (RemoteException e) {
-        } finally {
-            Binder.restoreCallingIdentity(ident);
         }
         
         updateWifiState();
-        return result;
+        return hadLock;
     }
 }
diff --git a/services/java/com/android/server/am/BatteryStatsService.java b/services/java/com/android/server/am/BatteryStatsService.java
index cc9a0af..ee89c09 100644
--- a/services/java/com/android/server/am/BatteryStatsService.java
+++ b/services/java/com/android/server/am/BatteryStatsService.java
@@ -162,7 +162,21 @@
             mStats.noteWifiOffLocked();
         }
     }
-    
+
+    public void noteWifiRunning() {
+        enforceCallingPermission();
+        synchronized (mStats) {
+            mStats.noteWifiRunningLocked();
+        }
+    }
+
+    public void noteWifiStopped() {
+        enforceCallingPermission();
+        synchronized (mStats) {
+            mStats.noteWifiStoppedLocked();
+        }
+    }
+
     public void noteBluetoothOn() {
         enforceCallingPermission();
         synchronized (mStats) {
diff --git a/wifi/java/android/net/wifi/WifiStateTracker.java b/wifi/java/android/net/wifi/WifiStateTracker.java
index 452a8fa..f7a9677 100644
--- a/wifi/java/android/net/wifi/WifiStateTracker.java
+++ b/wifi/java/android/net/wifi/WifiStateTracker.java
@@ -30,6 +30,8 @@
 import android.os.HandlerThread;
 import android.os.SystemProperties;
 import android.os.Looper;
+import android.os.RemoteException;
+import android.os.ServiceManager;
 import android.provider.Settings;
 import android.text.TextUtils;
 import android.util.EventLog;
@@ -43,6 +45,7 @@
 import android.content.Intent;
 import android.content.Context;
 import android.database.ContentObserver;
+import com.android.internal.app.IBatteryStats;
 
 import java.util.List;
 import java.util.ArrayList;
@@ -244,12 +247,12 @@
     private static final int RUN_STATE_STOPPED  = 4;
     private int mRunState;
 
+    private final IBatteryStats mBatteryStats;
+
     private boolean mIsScanOnly;
 
     private BluetoothA2dp mBluetoothA2dp;
 
-    private boolean mBluetoothScanMode;
-    
     private String mInterfaceName;
     private static String LS = System.getProperty("line.separator");
 
@@ -316,6 +319,8 @@
             "dhcp." + mInterfaceName + ".dns1",
             "dhcp." + mInterfaceName + ".dns2"
         };
+        mBatteryStats = IBatteryStats.Stub.asInterface(ServiceManager.getService("batteryinfo"));
+
     }
 
     /**
@@ -501,7 +506,7 @@
      * Send the tracker a notification that the Wi-Fi driver has been stopped.
      */
     void notifyDriverStopped() {
-       mRunState = RUN_STATE_STOPPED;
+        mRunState = RUN_STATE_STOPPED;
 
         // Send a driver stopped message to our handler
         Message.obtain(this, EVENT_DRIVER_STATE_CHANGED, 0, 0).sendToTarget();
@@ -530,6 +535,17 @@
         return mRunState == RUN_STATE_STOPPED || mRunState == RUN_STATE_STOPPING;
     }
 
+    private void noteRunState() {
+        try {
+            if (mRunState == RUN_STATE_RUNNING) {
+                mBatteryStats.noteWifiRunning();
+            } else if (mRunState == RUN_STATE_STOPPED) {
+                mBatteryStats.noteWifiStopped();
+            }
+        } catch (RemoteException ignore) {
+        }
+    }
+
     /**
      * Set the number of allowed radio frequency channels from the system
      * setting value, if any.
@@ -654,6 +670,7 @@
         switch (msg.what) {
             case EVENT_SUPPLICANT_CONNECTION:
                 mRunState = RUN_STATE_RUNNING;
+                noteRunState();
                 checkUseStaticIp();
                 /*
                  * DHCP requests are blocking, so run them in a separate thread.
@@ -721,6 +738,8 @@
                 break;
 
             case EVENT_SUPPLICANT_DISCONNECT:
+                mRunState = RUN_STATE_STOPPED;
+                noteRunState();
                 int wifiState = mWM.getWifiState();
                 boolean died = wifiState != WifiManager.WIFI_STATE_DISABLED &&
                         wifiState != WifiManager.WIFI_STATE_DISABLING;
@@ -1079,6 +1098,7 @@
                         }
                     }
                 }
+                noteRunState();
                 break;
 
             case EVENT_PASSWORD_KEY_MAY_BE_INCORRECT: