AI 143266: am: CL 143124 Fix bug #1731826, in which auto-connect to remembered networks does not
take place.
This has the same underlying cause as bug #1739874, so this fixes that
bug as well. The problem was that if the supplicant was in the DORMANT
state at the time a scan-only Wi-Fi lock was released, the command to
stop the Wi-Fi driver would never be issued. This had two main results:
first, the driver would stay awake when the screen was blank and it was
supposed to be sleeping, leading to excessive battery drain, and second,
when the screen was turned back on, there would be no DRIVER-STARTED
event generated (because the driver was already running). The
DRIVER-STARTED event is the trigger for the framework to issue a
RECONNECT command to the supplicant to cause it leave the DORMANT state
and look for available remembered networks.
To assist in tracking down this problem, and any such problems in the
future, I added four counters to keep track of how many times full and
scan-only Wi-Fi locks are acquired and released. The counter values
are output in the dump() method of WifiService. While doing this, I
noticed that because of missing "break" statements, the battery stats
that keep track of how much time Wi-Fi locks are held were including
the time for full locks in the time reported for scan-only locks.
Original author: ers
Merged from: //branches/cupcake/...
Automated import of CL 143266
diff --git a/services/java/com/android/server/WifiService.java b/services/java/com/android/server/WifiService.java
index 6323e2f..8e1d053 100644
--- a/services/java/com/android/server/WifiService.java
+++ b/services/java/com/android/server/WifiService.java
@@ -89,6 +89,11 @@
private int mPluggedType;
private final LockList mLocks = new LockList();
+ // some wifi lock statistics
+ private int mFullLocksAcquired;
+ private int mFullLocksReleased;
+ private int mScanLocksAcquired;
+ private int mScanLocksReleased;
private final IBatteryStats mBatteryStats;
@@ -1731,6 +1736,11 @@
}
}
pw.println();
+ pw.println("Locks acquired: " + mFullLocksAcquired + " full, " +
+ mScanLocksAcquired + " scan");
+ pw.println("Locks released: " + mFullLocksReleased + " full, " +
+ mScanLocksReleased + " scan");
+ pw.println();
pw.println("Locks held:");
mLocks.dump(pw);
}
@@ -1852,8 +1862,14 @@
long ident = Binder.clearCallingIdentity();
try {
switch(wifiLock.mLockMode) {
- case (WifiManager.WIFI_MODE_FULL): mBatteryStats.noteFullWifiLockAcquired(uid);
- case (WifiManager.WIFI_MODE_SCAN_ONLY): mBatteryStats.noteScanWifiLockAcquired(uid);
+ case WifiManager.WIFI_MODE_FULL:
+ ++mFullLocksAcquired;
+ mBatteryStats.noteFullWifiLockAcquired(uid);
+ break;
+ case WifiManager.WIFI_MODE_SCAN_ONLY:
+ ++mScanLocksAcquired;
+ mBatteryStats.noteScanWifiLockAcquired(uid);
+ break;
}
} catch (RemoteException e) {
} finally {
@@ -1882,8 +1898,14 @@
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);
+ case WifiManager.WIFI_MODE_FULL:
+ ++mFullLocksReleased;
+ mBatteryStats.noteFullWifiLockReleased(uid);
+ break;
+ case WifiManager.WIFI_MODE_SCAN_ONLY:
+ ++mScanLocksReleased;
+ mBatteryStats.noteScanWifiLockReleased(uid);
+ break;
}
} catch (RemoteException e) {
} finally {
diff --git a/wifi/java/android/net/wifi/WifiStateTracker.java b/wifi/java/android/net/wifi/WifiStateTracker.java
index f7a9677..6ea35f5 100644
--- a/wifi/java/android/net/wifi/WifiStateTracker.java
+++ b/wifi/java/android/net/wifi/WifiStateTracker.java
@@ -245,6 +245,13 @@
private static final int RUN_STATE_RUNNING = 2;
private static final int RUN_STATE_STOPPING = 3;
private static final int RUN_STATE_STOPPED = 4;
+
+ private static final String mRunStateNames[] = {
+ "Starting",
+ "Running",
+ "Stopping",
+ "Stopped"
+ };
private int mRunState;
private final IBatteryStats mBatteryStats;
@@ -836,7 +843,14 @@
newDetailedState = DetailedState.FAILED;
}
handleDisconnectedState(newDetailedState);
- if (mRunState == RUN_STATE_RUNNING && !mIsScanOnly) {
+ /**
+ * If we were associated with a network (networkId != -1),
+ * assume we reached this state because of a failed attempt
+ * to acquire an IP address, and attempt another connection
+ * and IP address acquisition in RECONNECT_DELAY_MSECS
+ * milliseconds.
+ */
+ if (mRunState == RUN_STATE_RUNNING && !mIsScanOnly && networkId != -1) {
sendEmptyMessageDelayed(EVENT_DEFERRED_RECONNECT, RECONNECT_DELAY_MSECS);
} else if (mRunState == RUN_STATE_STOPPING) {
synchronized (this) {
@@ -1376,13 +1390,24 @@
}
}
+ /**
+ * We want to stop the driver, but if we're connected to a network,
+ * we first want to disconnect, so that the supplicant is always in
+ * a known state (DISCONNECTED) when the driver is stopped.
+ * @return {@code true} if the operation succeeds, which means that the
+ * disconnect or stop command was initiated.
+ */
public synchronized boolean disconnectAndStop() {
if (mRunState != RUN_STATE_STOPPING && mRunState != RUN_STATE_STOPPED) {
// Take down any open network notifications
setNotificationVisible(false, 0, false, 0);
mRunState = RUN_STATE_STOPPING;
- return WifiNative.disconnectCommand();
+ if (mWifiInfo.getSupplicantState() == SupplicantState.DORMANT) {
+ return WifiNative.stopDriverCommand();
+ } else {
+ return WifiNative.disconnectCommand();
+ }
} else {
/*
* The "driver-stop" wake lock normally is released from the
@@ -1574,9 +1599,14 @@
@Override
public String toString() {
StringBuffer sb = new StringBuffer();
- sb.append("interface ").append(mInterfaceName).
- append(" runState=").append(mRunState).append(LS);
- sb.append(mWifiInfo).append(LS);
+ sb.append("interface ").append(mInterfaceName);
+ sb.append(" runState=");
+ if (mRunState >= 1 && mRunState <= mRunStateNames.length) {
+ sb.append(mRunStateNames[mRunState-1]);
+ } else {
+ sb.append(mRunState);
+ }
+ sb.append(LS).append(mWifiInfo).append(LS);
sb.append(mDhcpInfo).append(LS);
sb.append("haveIpAddress=").append(mHaveIPAddress).
append(", obtainingIpAddress=").append(mObtainingIPAddress).