summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIrfan Sheriff <isheriff@google.com>2010-10-14 17:01:27 -0700
committerIrfan Sheriff <isheriff@google.com>2010-10-20 12:04:21 -0700
commit4f5f7c968339a83b6af98ac8893a1ac33c7aa7bc (patch)
tree1bf9e2f1548ba3db07defb52d38d11ca784fd2ca
parent92f987a07a0b2d03a769a8b5fc57fe97a7bd7541 (diff)
downloadframeworks_base-4f5f7c968339a83b6af98ac8893a1ac33c7aa7bc.zip
frameworks_base-4f5f7c968339a83b6af98ac8893a1ac33c7aa7bc.tar.gz
frameworks_base-4f5f7c968339a83b6af98ac8893a1ac33c7aa7bc.tar.bz2
Fix wake and scan behavior
- Add wakelock for driver start/stop to ensure a wifilock acquisition kick starts driver. Also cleaned up state machine driver start/stop behavior. - Add periodic scans when driver is started to ensure wifi reconnections when wifilock exists or when user chooses never to sleep - some minor clean up Change-Id: I844eb70491d5aa2f8c8933b3d8dd01ba237ee534
-rw-r--r--core/java/android/provider/Settings.java8
-rw-r--r--services/java/com/android/server/WifiService.java38
-rw-r--r--wifi/java/android/net/wifi/WifiStateMachine.java50
3 files changed, 64 insertions, 32 deletions
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 56babdd..17d4aa4 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -3297,6 +3297,14 @@ public final class Settings {
public static final String WIFI_IDLE_MS = "wifi_idle_ms";
/**
+ * The interval in milliseconds to issue scans when the driver is
+ * started. This is necessary to allow wifi to connect to an
+ * access point when the driver is suspended.
+ * @hide
+ */
+ public static final String WIFI_SCAN_INTERVAL_MS = "wifi_scan_interval_ms";
+
+ /**
* The interval in milliseconds at which to check packet counts on the
* mobile data interface when screen is on, to detect possible data
* connection problems.
diff --git a/services/java/com/android/server/WifiService.java b/services/java/com/android/server/WifiService.java
index 55b7c9e..1241a7e 100644
--- a/services/java/com/android/server/WifiService.java
+++ b/services/java/com/android/server/WifiService.java
@@ -88,8 +88,10 @@ public class WifiService extends IWifiManager.Stub {
private AlarmManager mAlarmManager;
private PendingIntent mIdleIntent;
+ private PendingIntent mScanIntent;
private BluetoothA2dp mBluetoothA2dp;
private static final int IDLE_REQUEST = 0;
+ private static final int SCAN_REQUEST = 0;
private boolean mScreenOff;
private boolean mDeviceIdle;
private int mPluggedType;
@@ -121,7 +123,13 @@ public class WifiService extends IWifiManager.Stub {
* being enabled but not active exceeds the battery drain caused by
* re-establishing a connection to the mobile data network.
*/
- private static final long DEFAULT_IDLE_MILLIS = 15 * 60 * 1000; /* 15 minutes */
+ private static final long DEFAULT_IDLE_MS = 15 * 60 * 1000; /* 15 minutes */
+
+ /**
+ * See {@link Settings.Secure#WIFI_SCAN_INTERVAL_MS}. This is the default value if a
+ * Settings.Secure value is not present.
+ */
+ private static final long DEFAULT_SCAN_INTERVAL_MS = 60 * 1000; /* 1 minute */
/**
* Number of allowed radio frequency channels in various regulatory domains.
@@ -132,6 +140,9 @@ public class WifiService extends IWifiManager.Stub {
private static final String ACTION_DEVICE_IDLE =
"com.android.server.WifiManager.action.DEVICE_IDLE";
+ private static final String ACTION_START_SCAN =
+ "com.android.server.WifiManager.action.START_SCAN";
+
private boolean mIsReceiverRegistered = false;
@@ -202,6 +213,9 @@ public class WifiService extends IWifiManager.Stub {
Intent idleIntent = new Intent(ACTION_DEVICE_IDLE, null);
mIdleIntent = PendingIntent.getBroadcast(mContext, IDLE_REQUEST, idleIntent, 0);
+ Intent scanIntent = new Intent(ACTION_START_SCAN, null);
+ mScanIntent = PendingIntent.getBroadcast(mContext, SCAN_REQUEST, scanIntent, 0);
+
HandlerThread wifiThread = new HandlerThread("WifiService");
wifiThread.start();
@@ -824,7 +838,7 @@ public class WifiService extends IWifiManager.Stub {
long idleMillis =
Settings.Secure.getLong(mContext.getContentResolver(),
- Settings.Secure.WIFI_IDLE_MS, DEFAULT_IDLE_MILLIS);
+ Settings.Secure.WIFI_IDLE_MS, DEFAULT_IDLE_MS);
int stayAwakeConditions =
Settings.System.getInt(mContext.getContentResolver(),
Settings.System.STAY_ON_WHILE_PLUGGED_IN, 0);
@@ -837,6 +851,7 @@ public class WifiService extends IWifiManager.Stub {
// because of any locks so clear that tracking immediately.
reportStartWorkSource();
mWifiStateMachine.enableRssiPolling(true);
+ updateWifiState();
} else if (action.equals(Intent.ACTION_SCREEN_OFF)) {
Slog.d(TAG, "ACTION_SCREEN_OFF");
mScreenOff = true;
@@ -866,12 +881,11 @@ public class WifiService extends IWifiManager.Stub {
mAlarmManager.set(AlarmManager.RTC_WAKEUP, triggerTime, mIdleIntent);
}
}
- /* we can return now -- there's nothing to do until we get the idle intent back */
- return;
} else if (action.equals(ACTION_DEVICE_IDLE)) {
Slog.d(TAG, "got ACTION_DEVICE_IDLE");
mDeviceIdle = true;
reportStartWorkSource();
+ updateWifiState();
} else if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
/*
* Set a timer to put Wi-Fi to sleep, but only if the screen is off
@@ -886,19 +900,15 @@ public class WifiService extends IWifiManager.Stub {
long triggerTime = System.currentTimeMillis() + idleMillis;
Slog.d(TAG, "setting ACTION_DEVICE_IDLE timer for " + idleMillis + "ms");
mAlarmManager.set(AlarmManager.RTC_WAKEUP, triggerTime, mIdleIntent);
- mPluggedType = pluggedType;
- return;
}
mPluggedType = pluggedType;
} else if (action.equals(BluetoothA2dp.ACTION_PLAYING_STATE_CHANGED)) {
int state = intent.getIntExtra(BluetoothProfile.EXTRA_STATE,
BluetoothA2dp.STATE_NOT_PLAYING);
mWifiStateMachine.setBluetoothScanMode(state == BluetoothA2dp.STATE_PLAYING);
- } else {
- return;
+ } else if (action.equals(ACTION_START_SCAN)) {
+ mWifiStateMachine.startScan(true);
}
-
- updateWifiState();
}
/**
@@ -967,6 +977,10 @@ public class WifiService extends IWifiManager.Stub {
strongestLockMode = WifiManager.WIFI_MODE_FULL;
}
+ /* Scan interval when driver is started */
+ long scanMs = Settings.Secure.getLong(mContext.getContentResolver(),
+ Settings.Secure.WIFI_SCAN_INTERVAL_MS, DEFAULT_SCAN_INTERVAL_MS);
+
/* Disable tethering when airplane mode is enabled */
if (airplaneMode) {
mWifiStateMachine.setWifiApEnabled(null, false);
@@ -979,9 +993,12 @@ public class WifiService extends IWifiManager.Stub {
mWifiStateMachine.setScanOnlyMode(
strongestLockMode == WifiManager.WIFI_MODE_SCAN_ONLY);
mWifiStateMachine.setDriverStart(true);
+ mAlarmManager.setRepeating(AlarmManager.RTC_WAKEUP,
+ System.currentTimeMillis() + scanMs, scanMs, mScanIntent);
} else {
mWifiStateMachine.requestCmWakeLock();
mWifiStateMachine.setDriverStart(false);
+ mAlarmManager.cancel(mScanIntent);
}
} else {
mWifiStateMachine.setWifiEnabled(false);
@@ -994,6 +1011,7 @@ public class WifiService extends IWifiManager.Stub {
intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
intentFilter.addAction(Intent.ACTION_BATTERY_CHANGED);
intentFilter.addAction(ACTION_DEVICE_IDLE);
+ intentFilter.addAction(ACTION_START_SCAN);
intentFilter.addAction(BluetoothA2dp.ACTION_PLAYING_STATE_CHANGED);
mContext.registerReceiver(mReceiver, intentFilter);
}
diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java
index 3a9d272..f2fdbad 100644
--- a/wifi/java/android/net/wifi/WifiStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiStateMachine.java
@@ -132,8 +132,8 @@ public class WifiStateMachine extends HierarchicalStateMachine {
private LinkProperties mLinkProperties;
- // Held during driver load and unload
- private static PowerManager.WakeLock sWakeLock;
+ // Wakelock held during wifi start/stop and driver load/unload
+ private PowerManager.WakeLock mWakeLock;
private Context mContext;
@@ -469,7 +469,7 @@ public class WifiStateMachine extends HierarchicalStateMachine {
};
PowerManager powerManager = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
- sWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
+ mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
addState(mDefaultState);
addState(mInitialState, mDefaultState);
@@ -624,11 +624,11 @@ public class WifiStateMachine extends HierarchicalStateMachine {
* TODO: doc
*/
public void setDriverStart(boolean enable) {
- if (enable) {
- sendMessage(CMD_START_DRIVER);
- } else {
- sendMessage(CMD_STOP_DRIVER);
- }
+ if (enable) {
+ sendMessage(CMD_START_DRIVER);
+ } else {
+ sendMessage(CMD_STOP_DRIVER);
+ }
}
/**
@@ -951,6 +951,7 @@ public class WifiStateMachine extends HierarchicalStateMachine {
mReportedRunning = false;
}
}
+ mWakeLock.setWorkSource(newSource);
} catch (RemoteException ignore) {
}
}
@@ -1678,7 +1679,7 @@ public class WifiStateMachine extends HierarchicalStateMachine {
*/
new Thread(new Runnable() {
public void run() {
- sWakeLock.acquire();
+ mWakeLock.acquire();
//enabling state
switch(message.arg1) {
case WIFI_STATE_ENABLING:
@@ -1704,7 +1705,7 @@ public class WifiStateMachine extends HierarchicalStateMachine {
}
sendMessage(CMD_LOAD_DRIVER_FAILURE);
}
- sWakeLock.release();
+ mWakeLock.release();
}
}).start();
}
@@ -1802,7 +1803,7 @@ public class WifiStateMachine extends HierarchicalStateMachine {
new Thread(new Runnable() {
public void run() {
if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
- sWakeLock.acquire();
+ mWakeLock.acquire();
if(WifiNative.unloadDriver()) {
Log.d(TAG, "Driver unload successful");
sendMessage(CMD_UNLOAD_DRIVER_SUCCESS);
@@ -1832,7 +1833,7 @@ public class WifiStateMachine extends HierarchicalStateMachine {
break;
}
}
- sWakeLock.release();
+ mWakeLock.release();
}
}).start();
}
@@ -1936,7 +1937,7 @@ public class WifiStateMachine extends HierarchicalStateMachine {
checkIsBluetoothPlaying();
sendSupplicantConnectionChangedBroadcast(true);
- transitionTo(mDriverSupReadyState);
+ transitionTo(mDriverStartedState);
break;
case SUP_DISCONNECTION_EVENT:
Log.e(TAG, "Failed to setup control channel, restart supplicant");
@@ -2004,11 +2005,6 @@ public class WifiStateMachine extends HierarchicalStateMachine {
transitionTo(mDriverLoadedState);
sendMessageAtFrontOfQueue(CMD_START_SUPPLICANT); /* restart */
break;
- case CMD_START_DRIVER:
- EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
- WifiNative.startDriverCommand();
- transitionTo(mDriverStartingState);
- break;
case SCAN_RESULTS_EVENT:
setScanResults(WifiNative.scanResultsCommand());
sendScanResultsAvailableBroadcast();
@@ -2185,12 +2181,11 @@ public class WifiStateMachine extends HierarchicalStateMachine {
mNumAllowedChannels = message.arg1;
WifiNative.setNumAllowedChannelsCommand(message.arg1);
break;
- case CMD_START_DRIVER:
- /* Ignore another driver start */
- break;
case CMD_STOP_DRIVER:
+ mWakeLock.acquire();
WifiNative.stopDriverCommand();
transitionTo(mDriverStoppingState);
+ mWakeLock.release();
break;
case CMD_REQUEST_CM_WAKELOCK:
if (mCm == null) {
@@ -2266,7 +2261,18 @@ public class WifiStateMachine extends HierarchicalStateMachine {
@Override
public boolean processMessage(Message message) {
if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
- return NOT_HANDLED;
+ switch (message.what) {
+ case CMD_START_DRIVER:
+ mWakeLock.acquire();
+ WifiNative.startDriverCommand();
+ transitionTo(mDriverStartingState);
+ mWakeLock.release();
+ break;
+ default:
+ return NOT_HANDLED;
+ }
+ EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
+ return HANDLED;
}
}