diff options
author | Irfan Sheriff <isheriff@google.com> | 2010-10-14 17:01:27 -0700 |
---|---|---|
committer | Irfan Sheriff <isheriff@google.com> | 2010-10-20 12:04:21 -0700 |
commit | 4f5f7c968339a83b6af98ac8893a1ac33c7aa7bc (patch) | |
tree | 1bf9e2f1548ba3db07defb52d38d11ca784fd2ca | |
parent | 92f987a07a0b2d03a769a8b5fc57fe97a7bd7541 (diff) | |
download | frameworks_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.java | 8 | ||||
-rw-r--r-- | services/java/com/android/server/WifiService.java | 38 | ||||
-rw-r--r-- | wifi/java/android/net/wifi/WifiStateMachine.java | 50 |
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; } } |