diff options
Diffstat (limited to 'wifi')
-rw-r--r-- | wifi/java/android/net/wifi/SupplicantState.java | 44 | ||||
-rw-r--r-- | wifi/java/android/net/wifi/SupplicantStateTracker.java | 22 | ||||
-rw-r--r-- | wifi/java/android/net/wifi/WifiInfo.java | 2 | ||||
-rw-r--r-- | wifi/java/android/net/wifi/WifiManager.java | 7 | ||||
-rw-r--r-- | wifi/java/android/net/wifi/WifiMonitor.java | 11 | ||||
-rw-r--r-- | wifi/java/android/net/wifi/WifiNative.java | 4 | ||||
-rw-r--r-- | wifi/java/android/net/wifi/WifiStateMachine.java | 86 |
7 files changed, 126 insertions, 50 deletions
diff --git a/wifi/java/android/net/wifi/SupplicantState.java b/wifi/java/android/net/wifi/SupplicantState.java index 6b79210..91e685f 100644 --- a/wifi/java/android/net/wifi/SupplicantState.java +++ b/wifi/java/android/net/wifi/SupplicantState.java @@ -39,6 +39,15 @@ public enum SupplicantState implements Parcelable { DISCONNECTED, /** + * Interface is disabled + * <p/> + * This state is entered if the network interface is disabled. + * wpa_supplicant refuses any new operations that would + * use the radio until the interface has been enabled. + */ + INTERFACE_DISABLED, + + /** * Inactive state (wpa_supplicant disabled). * <p/> * This state is entered if there are no enabled networks in the @@ -57,6 +66,15 @@ public enum SupplicantState implements Parcelable { SCANNING, /** + * Trying to authenticate with a BSS/SSID + * <p/> + * This state is entered when wpa_supplicant has found a suitable BSS + * to authenticate with and the driver is configured to try to + * authenticate with this BSS. + */ + AUTHENTICATING, + + /** * Trying to associate with a BSS/SSID. * <p/> * This state is entered when wpa_supplicant has found a suitable BSS @@ -152,8 +170,33 @@ public enum SupplicantState implements Parcelable { return state != UNINITIALIZED && state != INVALID; } + + /* Supplicant associating or authenticating is considered a handshake state */ + static boolean isHandshakeState(SupplicantState state) { + switch(state) { + case AUTHENTICATING: + case ASSOCIATING: + case ASSOCIATED: + case FOUR_WAY_HANDSHAKE: + case GROUP_HANDSHAKE: + return true; + case COMPLETED: + case DISCONNECTED: + case INTERFACE_DISABLED: + case INACTIVE: + case SCANNING: + case DORMANT: + case UNINITIALIZED: + case INVALID: + return false; + default: + throw new IllegalArgumentException("Unknown supplicant state"); + } + } + static boolean isConnecting(SupplicantState state) { switch(state) { + case AUTHENTICATING: case ASSOCIATING: case ASSOCIATED: case FOUR_WAY_HANDSHAKE: @@ -161,6 +204,7 @@ public enum SupplicantState implements Parcelable { case COMPLETED: return true; case DISCONNECTED: + case INTERFACE_DISABLED: case INACTIVE: case SCANNING: case DORMANT: diff --git a/wifi/java/android/net/wifi/SupplicantStateTracker.java b/wifi/java/android/net/wifi/SupplicantStateTracker.java index 9ae26da..0c4f9f6 100644 --- a/wifi/java/android/net/wifi/SupplicantStateTracker.java +++ b/wifi/java/android/net/wifi/SupplicantStateTracker.java @@ -98,12 +98,16 @@ class SupplicantStateTracker extends StateMachine { if (DBG) Log.d(TAG, "Supplicant state: " + supState.toString() + "\n"); switch (supState) { - case DISCONNECTED: + case DISCONNECTED: transitionTo(mDisconnectState); break; + case INTERFACE_DISABLED: + //we should have received a disconnection already, do nothing + break; case SCANNING: transitionTo(mScanState); break; + case AUTHENTICATING: case ASSOCIATING: case ASSOCIATED: case FOUR_WAY_HANDSHAKE: @@ -250,10 +254,7 @@ class SupplicantStateTracker extends StateMachine { case WifiStateMachine.SUPPLICANT_STATE_CHANGE_EVENT: StateChangeResult stateChangeResult = (StateChangeResult) message.obj; SupplicantState state = stateChangeResult.state; - if (state == SupplicantState.ASSOCIATING || - state == SupplicantState.ASSOCIATED || - state == SupplicantState.FOUR_WAY_HANDSHAKE || - state == SupplicantState.GROUP_HANDSHAKE) { + if (SupplicantState.isHandshakeState(state)) { if (mLoopDetectIndex > state.ordinal()) { mLoopDetectCount++; } @@ -296,12 +297,11 @@ class SupplicantStateTracker extends StateMachine { StateChangeResult stateChangeResult = (StateChangeResult) message.obj; SupplicantState state = stateChangeResult.state; sendSupplicantStateChangedBroadcast(state, mAuthFailureInSupplicantBroadcast); - /* Ignore a re-auth in completed state */ - if (state == SupplicantState.ASSOCIATING || - state == SupplicantState.ASSOCIATED || - state == SupplicantState.FOUR_WAY_HANDSHAKE || - state == SupplicantState.GROUP_HANDSHAKE || - state == SupplicantState.COMPLETED) { + /* Ignore any connecting state in completed state. Group re-keying + * events and other auth events that do not affect connectivity are + * ignored + */ + if (SupplicantState.isConnecting(state)) { break; } transitionOnSupplicantStateChange(stateChangeResult); diff --git a/wifi/java/android/net/wifi/WifiInfo.java b/wifi/java/android/net/wifi/WifiInfo.java index f60ae48..e3661bf 100644 --- a/wifi/java/android/net/wifi/WifiInfo.java +++ b/wifi/java/android/net/wifi/WifiInfo.java @@ -41,8 +41,10 @@ public class WifiInfo implements Parcelable { static { stateMap.put(SupplicantState.DISCONNECTED, DetailedState.DISCONNECTED); + stateMap.put(SupplicantState.INTERFACE_DISABLED, DetailedState.DISCONNECTED); stateMap.put(SupplicantState.INACTIVE, DetailedState.IDLE); stateMap.put(SupplicantState.SCANNING, DetailedState.SCANNING); + stateMap.put(SupplicantState.AUTHENTICATING, DetailedState.CONNECTING); stateMap.put(SupplicantState.ASSOCIATING, DetailedState.CONNECTING); stateMap.put(SupplicantState.ASSOCIATED, DetailedState.CONNECTING); stateMap.put(SupplicantState.FOUR_WAY_HANDSHAKE, DetailedState.AUTHENTICATING); diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 949e80f..9d1bdd4 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -1194,16 +1194,19 @@ public class WifiManager { * Acquiring a WifiLock will keep the radio on until the lock is released. Multiple * applications may hold WifiLocks, and the radio will only be allowed to turn off when no * WifiLocks are held in any application. - * + * <p> * Before using a WifiLock, consider carefully if your application requires Wi-Fi access, or * could function over a mobile network, if available. A program that needs to download large * files should hold a WifiLock to ensure that the download will complete, but a program whose * network usage is occasional or low-bandwidth should not hold a WifiLock to avoid adversely * affecting battery life. - * + * <p> * Note that WifiLocks cannot override the user-level "Wi-Fi Enabled" setting, nor Airplane * Mode. They simply keep the radio from turning off when Wi-Fi is already on but the device * is idle. + * <p> + * Any application using a WifiLock must request the {@code android.permission.WAKE_LOCK} + * permission in an {@code <uses-permission>} element of the application's manifest. */ public class WifiLock { private String mTag; diff --git a/wifi/java/android/net/wifi/WifiMonitor.java b/wifi/java/android/net/wifi/WifiMonitor.java index ce38261..4a45825 100644 --- a/wifi/java/android/net/wifi/WifiMonitor.java +++ b/wifi/java/android/net/wifi/WifiMonitor.java @@ -17,7 +17,6 @@ package android.net.wifi; import android.util.Log; -import android.util.Config; import android.net.NetworkInfo; import java.util.regex.Pattern; @@ -182,7 +181,7 @@ public class WifiMonitor { String eventStr = WifiNative.waitForEvent(); // Skip logging the common but mostly uninteresting scan-results event - if (Config.LOGD && eventStr.indexOf(scanResultsEvent) == -1) { + if (false && eventStr.indexOf(scanResultsEvent) == -1) { Log.v(TAG, "Event [" + eventStr + "]"); } if (!eventStr.startsWith(eventPrefix)) { @@ -200,7 +199,7 @@ public class WifiMonitor { if (nameEnd != -1) eventName = eventName.substring(0, nameEnd); if (eventName.length() == 0) { - if (Config.LOGD) Log.i(TAG, "Received wpa_supplicant event with empty event name"); + if (false) Log.i(TAG, "Received wpa_supplicant event with empty event name"); continue; } /* @@ -251,7 +250,7 @@ public class WifiMonitor { * stopped the supplicant, simply exit the monitor thread */ if (eventData.startsWith(monitorSocketClosed)) { - if (Config.LOGD) { + if (false) { Log.d(TAG, "Monitor socket is closed, exiting thread"); } break; @@ -263,7 +262,7 @@ public class WifiMonitor { */ if (eventData.startsWith(wpaRecvError)) { if (++mRecvErrors > MAX_RECV_ERRORS) { - if (Config.LOGD) { + if (false) { Log.d(TAG, "too many recv errors, closing connection"); } } else { @@ -398,7 +397,7 @@ public class WifiMonitor { if (newState == NetworkInfo.DetailedState.CONNECTED) { Matcher match = mConnectedEventPattern.matcher(data); if (!match.find()) { - if (Config.LOGD) Log.d(TAG, "Could not find BSSID in CONNECTED event string"); + if (false) Log.d(TAG, "Could not find BSSID in CONNECTED event string"); } else { BSSID = match.group(1); try { diff --git a/wifi/java/android/net/wifi/WifiNative.java b/wifi/java/android/net/wifi/WifiNative.java index 909605dc..6e13d0f 100644 --- a/wifi/java/android/net/wifi/WifiNative.java +++ b/wifi/java/android/net/wifi/WifiNative.java @@ -171,5 +171,7 @@ public class WifiNative { */ public native static String waitForEvent(); - public native static void enableBackgroundScan(boolean enable); + public native static void enableBackgroundScanCommand(boolean enable); + + public native static void setScanIntervalCommand(int scanInterval); } diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java index e03680f..bd6da64 100644 --- a/wifi/java/android/net/wifi/WifiStateMachine.java +++ b/wifi/java/android/net/wifi/WifiStateMachine.java @@ -351,10 +351,20 @@ public class WifiStateMachine extends StateMachine { private int mPowerMode = POWER_MODE_AUTO; /** - * See {@link Settings.Secure#WIFI_SCAN_INTERVAL_MS}. This is the default value if a - * Settings.Secure value is not present. + * Default framework scan interval in milliseconds. This is used in the scenario in which + * wifi chipset does not support background scanning to set up a + * periodic wake up scan so that the device can connect to a new access + * point on the move. {@link Settings.Secure#WIFI_FRAMEWORK_SCAN_INTERVAL_MS} can + * override this. */ - private static final long DEFAULT_SCAN_INTERVAL_MS = 60 * 1000; /* 1 minute */ + private final int mDefaultFrameworkScanIntervalMs; + + /** + * Default supplicant scan interval in milliseconds. + * {@link Settings.Secure#WIFI_SUPPLICANT_SCAN_INTERVAL_MS} can override this. + */ + private final int mDefaultSupplicantScanIntervalMs; + private static final int MIN_RSSI = -200; private static final int MAX_RSSI = 256; @@ -488,6 +498,12 @@ public class WifiStateMachine extends StateMachine { Intent scanIntent = new Intent(ACTION_START_SCAN, null); mScanIntent = PendingIntent.getBroadcast(mContext, SCAN_REQUEST, scanIntent, 0); + mDefaultFrameworkScanIntervalMs = mContext.getResources().getInteger( + com.android.internal.R.integer.config_wifi_framework_scan_interval); + + mDefaultSupplicantScanIntervalMs = mContext.getResources().getInteger( + com.android.internal.R.integer.config_wifi_supplicant_scan_interval); + mContext.registerReceiver( new BroadcastReceiver() { @Override @@ -847,7 +863,7 @@ public class WifiStateMachine extends StateMachine { sendMessage(obtainMessage(CMD_ENABLE_RSSI_POLL, enabled ? 1 : 0, 0)); } - public void enableBackgroundScan(boolean enabled) { + public void enableBackgroundScanCommand(boolean enabled) { sendMessage(obtainMessage(CMD_ENABLE_BACKGROUND_SCAN, enabled ? 1 : 0, 0)); } @@ -2096,6 +2112,11 @@ public class WifiStateMachine extends StateMachine { mIsScanMode = false; /* Wifi is available as long as we have a connection to supplicant */ mNetworkInfo.setIsAvailable(true); + /* Set scan interval */ + long supplicantScanIntervalMs = Settings.Secure.getLong(mContext.getContentResolver(), + Settings.Secure.WIFI_SUPPLICANT_SCAN_INTERVAL_MS, + mDefaultSupplicantScanIntervalMs); + WifiNative.setScanIntervalCommand((int)supplicantScanIntervalMs / 1000); } @Override public boolean processMessage(Message message) { @@ -2104,17 +2125,6 @@ public class WifiStateMachine extends StateMachine { boolean eventLoggingEnabled = true; switch(message.what) { case CMD_STOP_SUPPLICANT: /* Supplicant stopped by user */ - Log.d(TAG, "stopping supplicant"); - if (!WifiNative.stopSupplicant()) { - Log.e(TAG, "Failed to stop supplicant, issue kill"); - WifiNative.killSupplicant(); - } - mNetworkInfo.setIsAvailable(false); - handleNetworkDisconnect(); - setWifiState(WIFI_STATE_DISABLING); - sendSupplicantConnectionChangedBroadcast(false); - mSupplicantStateTracker.sendMessage(CMD_RESET_SUPPLICANT_STATE); - mWpsStateMachine.sendMessage(CMD_RESET_WPS_STATE); transitionTo(mSupplicantStoppingState); break; case SUP_DISCONNECTION_EVENT: /* Supplicant connection lost */ @@ -2215,6 +2225,17 @@ public class WifiStateMachine extends StateMachine { public void enter() { if (DBG) Log.d(TAG, getName() + "\n"); EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName()); + Log.d(TAG, "stopping supplicant"); + if (!WifiNative.stopSupplicant()) { + Log.e(TAG, "Failed to stop supplicant, issue kill"); + WifiNative.killSupplicant(); + } + mNetworkInfo.setIsAvailable(false); + handleNetworkDisconnect(); + setWifiState(WIFI_STATE_DISABLING); + sendSupplicantConnectionChangedBroadcast(false); + mSupplicantStateTracker.sendMessage(CMD_RESET_SUPPLICANT_STATE); + mWpsStateMachine.sendMessage(CMD_RESET_WPS_STATE); } @Override public boolean processMessage(Message message) { @@ -2869,17 +2890,21 @@ public class WifiStateMachine extends StateMachine { class DisconnectedState extends State { private boolean mAlarmEnabled = false; - private long mScanIntervalMs; + /* This is set from the overlay config file or from a secure setting. + * A value of 0 disables scanning in the framework. + */ + private long mFrameworkScanIntervalMs; private void setScanAlarm(boolean enabled) { if (enabled == mAlarmEnabled) return; if (enabled) { - mAlarmManager.setRepeating(AlarmManager.RTC_WAKEUP, - System.currentTimeMillis() + mScanIntervalMs, - mScanIntervalMs, - mScanIntent); - - mAlarmEnabled = true; + if (mFrameworkScanIntervalMs > 0) { + mAlarmManager.setRepeating(AlarmManager.RTC_WAKEUP, + System.currentTimeMillis() + mFrameworkScanIntervalMs, + mFrameworkScanIntervalMs, + mScanIntent); + mAlarmEnabled = true; + } } else { mAlarmManager.cancel(mScanIntent); mAlarmEnabled = false; @@ -2891,8 +2916,9 @@ public class WifiStateMachine extends StateMachine { if (DBG) Log.d(TAG, getName() + "\n"); EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName()); - mScanIntervalMs = Settings.Secure.getLong(mContext.getContentResolver(), - Settings.Secure.WIFI_SCAN_INTERVAL_MS, DEFAULT_SCAN_INTERVAL_MS); + mFrameworkScanIntervalMs = Settings.Secure.getLong(mContext.getContentResolver(), + Settings.Secure.WIFI_FRAMEWORK_SCAN_INTERVAL_MS, + mDefaultFrameworkScanIntervalMs); /* * We initiate background scanning if it is enabled, otherwise we * initiate an infrequent scan that wakes up the device to ensure @@ -2906,7 +2932,7 @@ public class WifiStateMachine extends StateMachine { * cleared */ if (!mScanResultIsPending) { - WifiNative.enableBackgroundScan(true); + WifiNative.enableBackgroundScanCommand(true); } } else { setScanAlarm(true); @@ -2928,10 +2954,10 @@ public class WifiStateMachine extends StateMachine { case CMD_ENABLE_BACKGROUND_SCAN: mEnableBackgroundScan = (message.arg1 == 1); if (mEnableBackgroundScan) { - WifiNative.enableBackgroundScan(true); + WifiNative.enableBackgroundScanCommand(true); setScanAlarm(false); } else { - WifiNative.enableBackgroundScan(false); + WifiNative.enableBackgroundScanCommand(false); setScanAlarm(true); } break; @@ -2946,14 +2972,14 @@ public class WifiStateMachine extends StateMachine { case CMD_START_SCAN: /* Disable background scan temporarily during a regular scan */ if (mEnableBackgroundScan) { - WifiNative.enableBackgroundScan(false); + WifiNative.enableBackgroundScanCommand(false); } /* Handled in parent state */ return NOT_HANDLED; case SCAN_RESULTS_EVENT: /* Re-enable background scan when a pending scan result is received */ if (mEnableBackgroundScan && mScanResultIsPending) { - WifiNative.enableBackgroundScan(true); + WifiNative.enableBackgroundScanCommand(true); } /* Handled in parent state */ return NOT_HANDLED; @@ -2968,7 +2994,7 @@ public class WifiStateMachine extends StateMachine { public void exit() { /* No need for a background scan upon exit from a disconnected state */ if (mEnableBackgroundScan) { - WifiNative.enableBackgroundScan(false); + WifiNative.enableBackgroundScanCommand(false); } setScanAlarm(false); } |