diff options
Diffstat (limited to 'wifi/java/android')
-rw-r--r-- | wifi/java/android/net/wifi/IWifiManager.aidl | 10 | ||||
-rw-r--r-- | wifi/java/android/net/wifi/SupplicantState.java | 20 | ||||
-rw-r--r-- | wifi/java/android/net/wifi/WifiConfigStore.java | 12 | ||||
-rw-r--r-- | wifi/java/android/net/wifi/WifiManager.java | 67 | ||||
-rw-r--r-- | wifi/java/android/net/wifi/WifiNative.java | 2 | ||||
-rw-r--r-- | wifi/java/android/net/wifi/WifiStateMachine.java | 150 | ||||
-rw-r--r-- | wifi/java/android/net/wifi/WpsStateMachine.java | 4 |
7 files changed, 192 insertions, 73 deletions
diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl index 7a9276d..1d115b1 100644 --- a/wifi/java/android/net/wifi/IWifiManager.aidl +++ b/wifi/java/android/net/wifi/IWifiManager.aidl @@ -103,16 +103,6 @@ interface IWifiManager void clearBlacklist(); - void connectNetworkWithConfig(in WifiConfiguration wifiConfig); - - void connectNetworkWithId(int networkId); - - void saveNetwork(in WifiConfiguration wifiConfig); - - void forgetNetwork(int networkId); - - WpsResult startWps(in WpsConfiguration config); - Messenger getMessenger(); } diff --git a/wifi/java/android/net/wifi/SupplicantState.java b/wifi/java/android/net/wifi/SupplicantState.java index 169b2d6..6b79210 100644 --- a/wifi/java/android/net/wifi/SupplicantState.java +++ b/wifi/java/android/net/wifi/SupplicantState.java @@ -152,6 +152,26 @@ public enum SupplicantState implements Parcelable { return state != UNINITIALIZED && state != INVALID; } + static boolean isConnecting(SupplicantState state) { + switch(state) { + case ASSOCIATING: + case ASSOCIATED: + case FOUR_WAY_HANDSHAKE: + case GROUP_HANDSHAKE: + case COMPLETED: + return true; + case DISCONNECTED: + case INACTIVE: + case SCANNING: + case DORMANT: + case UNINITIALIZED: + case INVALID: + return false; + default: + throw new IllegalArgumentException("Unknown supplicant state"); + } + } + /** Implement the Parcelable interface {@hide} */ public int describeContents() { return 0; diff --git a/wifi/java/android/net/wifi/WifiConfigStore.java b/wifi/java/android/net/wifi/WifiConfigStore.java index d411715..f6317f5 100644 --- a/wifi/java/android/net/wifi/WifiConfigStore.java +++ b/wifi/java/android/net/wifi/WifiConfigStore.java @@ -686,13 +686,15 @@ class WifiConfigStore { } else if (key.equals(IP_ASSIGNMENT_KEY)) { ipAssignment = IpAssignment.valueOf(in.readUTF()); } else if (key.equals(LINK_ADDRESS_KEY)) { - LinkAddress linkAddr = new LinkAddress(InetAddress.getByName( - in.readUTF()), in.readInt()); + LinkAddress linkAddr = new LinkAddress( + NetworkUtils.numericToInetAddress(in.readUTF()), in.readInt()); linkProperties.addLinkAddress(linkAddr); } else if (key.equals(GATEWAY_KEY)) { - linkProperties.addGateway(InetAddress.getByName(in.readUTF())); + linkProperties.addGateway( + NetworkUtils.numericToInetAddress(in.readUTF())); } else if (key.equals(DNS_KEY)) { - linkProperties.addDns(InetAddress.getByName(in.readUTF())); + linkProperties.addDns( + NetworkUtils.numericToInetAddress(in.readUTF())); } else if (key.equals(PROXY_SETTINGS_KEY)) { proxySettings = ProxySettings.valueOf(in.readUTF()); } else if (key.equals(PROXY_HOST_KEY)) { @@ -706,7 +708,7 @@ class WifiConfigStore { } else { Log.e(TAG, "Ignore unknown key " + key + "while reading"); } - } catch (UnknownHostException e) { + } catch (IllegalArgumentException e) { Log.e(TAG, "Ignore invalid address while reading" + e); } } while (true); diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 0807a24..5238899 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -18,6 +18,7 @@ package android.net.wifi; import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; +import android.content.Context; import android.net.DhcpInfo; import android.os.Binder; import android.os.IBinder; @@ -26,6 +27,8 @@ import android.os.RemoteException; import android.os.WorkSource; import android.os.Messenger; +import com.android.internal.util.AsyncChannel; + import java.util.List; /** @@ -447,6 +450,9 @@ public class WifiManager { /* Number of currently active WifiLocks and MulticastLocks */ private int mActiveLockCount; + /* For communication with WifiService */ + private AsyncChannel mAsyncChannel = new AsyncChannel(); + /** * Create a new WifiManager instance. * Applications will almost always want to use @@ -1032,6 +1038,37 @@ public class WifiManager { } /* TODO: deprecate synchronous API and open up the following API */ + + /* Commands to WifiService */ + /** @hide */ + public static final int CMD_CONNECT_NETWORK = 1; + /** @hide */ + public static final int CMD_FORGET_NETWORK = 2; + /** @hide */ + public static final int CMD_SAVE_NETWORK = 3; + /** @hide */ + public static final int CMD_START_WPS = 4; + + /* Events from WifiService */ + /** @hide */ + public static final int CMD_WPS_COMPLETED = 11; + + /* For system use only */ + /** @hide */ + public static final int CMD_ENABLE_TRAFFIC_STATS_POLL = 21; + /** @hide */ + public static final int CMD_TRAFFIC_STATS_POLL = 22; + + /** + * Initiate an asynchronous channel connection setup + * @param srcContext is the context of the source + * @param srcHandler is the handler on which the source receives messages + * @hide + */ + public void asyncConnect(Context srcContext, Handler srcHandler) { + mAsyncChannel.connect(srcContext, srcHandler, getMessenger()); + } + /** * Connect to a network with the given configuration. The network also * gets added to the supplicant configuration. @@ -1048,9 +1085,7 @@ public class WifiManager { if (config == null) { return; } - try { - mService.connectNetworkWithConfig(config); - } catch (RemoteException e) { } + mAsyncChannel.sendMessage(CMD_CONNECT_NETWORK, config); } /** @@ -1067,9 +1102,7 @@ public class WifiManager { if (networkId < 0) { return; } - try { - mService.connectNetworkWithId(networkId); - } catch (RemoteException e) { } + mAsyncChannel.sendMessage(CMD_CONNECT_NETWORK, networkId); } /** @@ -1091,9 +1124,8 @@ public class WifiManager { if (config == null) { return; } - try { - mService.saveNetwork(config); - } catch (RemoteException e) { } + + mAsyncChannel.sendMessage(CMD_SAVE_NETWORK, config); } /** @@ -1110,25 +1142,22 @@ public class WifiManager { if (netId < 0) { return; } - try { - mService.forgetNetwork(netId); - } catch (RemoteException e) { } + + mAsyncChannel.sendMessage(CMD_FORGET_NETWORK, netId); } /** * Start Wi-fi Protected Setup * * @param config WPS configuration - * @return WpsResult containing pin and status * @hide - * TODO: with use of AsyncChannel, return value should go away */ - public WpsResult startWps(WpsConfiguration config) { - try { - return mService.startWps(config); - } catch (RemoteException e) { - return new WpsResult(WpsResult.Status.FAILURE); + public void startWps(WpsConfiguration config) { + if (config == null) { + return; } + + mAsyncChannel.sendMessage(CMD_START_WPS, config); } /** diff --git a/wifi/java/android/net/wifi/WifiNative.java b/wifi/java/android/net/wifi/WifiNative.java index 39676b0..909605dc 100644 --- a/wifi/java/android/net/wifi/WifiNative.java +++ b/wifi/java/android/net/wifi/WifiNative.java @@ -170,4 +170,6 @@ public class WifiNative { * @return the event string sent by the supplicant. */ public native static String waitForEvent(); + + public native static void enableBackgroundScan(boolean enable); } diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java index fc42ab8..589d88c 100644 --- a/wifi/java/android/net/wifi/WifiStateMachine.java +++ b/wifi/java/android/net/wifi/WifiStateMachine.java @@ -59,6 +59,7 @@ import android.os.Binder; import android.os.IBinder; import android.os.INetworkManagementService; import android.os.Message; +import android.os.Messenger; import android.os.PowerManager; import android.os.Process; import android.os.RemoteException; @@ -112,9 +113,11 @@ public class WifiStateMachine extends HierarchicalStateMachine { private String mLastBssid; private int mLastNetworkId; private boolean mEnableRssiPolling = false; + private boolean mEnableBackgroundScan = false; private int mRssiPollToken = 0; private int mReconnectCount = 0; private boolean mIsScanMode = false; + private boolean mScanResultIsPending = false; private boolean mBluetoothConnectionActive = false; @@ -300,6 +303,8 @@ public class WifiStateMachine extends HierarchicalStateMachine { static final int CMD_START_WPS = 89; /* Set the frequency band */ static final int CMD_SET_FREQUENCY_BAND = 90; + /* Enable background scan for configured networks */ + static final int CMD_ENABLE_BACKGROUND_SCAN = 91; /* Commands from/to the SupplicantStateTracker */ /* Reset the supplicant state tracker */ @@ -339,6 +344,9 @@ public class WifiStateMachine extends HierarchicalStateMachine { */ private static final long DEFAULT_SCAN_INTERVAL_MS = 60 * 1000; /* 1 minute */ + private static final int MIN_RSSI = -200; + private static final int MAX_RSSI = 256; + /* Default parent state */ private HierarchicalState mDefaultState = new DefaultState(); /* Temporary initial state */ @@ -801,28 +809,20 @@ public class WifiStateMachine extends HierarchicalStateMachine { sendMessage(obtainMessage(CMD_FORGET_NETWORK, netId, 0)); } - public WpsResult startWps(AsyncChannel channel, WpsConfiguration config) { - WpsResult result; - switch (config.setup) { - case PIN_FROM_DEVICE: - case PBC: - case PIN_FROM_ACCESS_POINT: - //TODO: will go away with AsyncChannel use from settings - Message resultMsg = channel.sendMessageSynchronously(CMD_START_WPS, config); - result = (WpsResult) resultMsg.obj; - resultMsg.recycle(); - break; - default: - result = new WpsResult(Status.FAILURE); - break; - } - return result; + public void startWps(Messenger replyTo, WpsConfiguration config) { + Message msg = obtainMessage(CMD_START_WPS, config); + msg.replyTo = replyTo; + sendMessage(msg); } public void enableRssiPolling(boolean enabled) { sendMessage(obtainMessage(CMD_ENABLE_RSSI_POLL, enabled ? 1 : 0, 0)); } + public void enableBackgroundScan(boolean enabled) { + sendMessage(obtainMessage(CMD_ENABLE_BACKGROUND_SCAN, enabled ? 1 : 0, 0)); + } + public void enableAllNetworks() { sendMessage(CMD_ENABLE_ALL_NETWORKS); } @@ -999,7 +999,8 @@ public class WifiStateMachine extends HierarchicalStateMachine { ifcg = service.getInterfaceConfig(intf); if (ifcg != null) { /* IP/netmask: 192.168.43.1/255.255.255.0 */ - ifcg.addr = new LinkAddress(InetAddress.getByName("192.168.43.1"), 24); + ifcg.addr = new LinkAddress(NetworkUtils.numericToInetAddress( + "192.168.43.1"), 24); ifcg.interfaceFlags = "[up]"; service.setInterfaceConfig(intf, ifcg); @@ -1241,7 +1242,7 @@ public class WifiStateMachine extends HierarchicalStateMachine { */ private void fetchRssiAndLinkSpeedNative() { int newRssi = WifiNative.getRssiCommand(); - if (newRssi != -1 && -200 < newRssi && newRssi < 256) { // screen out invalid values + if (newRssi != -1 && MIN_RSSI < newRssi && newRssi < MAX_RSSI) { // screen out invalid values /* some implementations avoid negative values by adding 256 * so we need to adjust for that here. */ @@ -1266,7 +1267,7 @@ public class WifiStateMachine extends HierarchicalStateMachine { } mLastSignalLevel = newSignalLevel; } else { - mWifiInfo.setRssi(-200); + mWifiInfo.setRssi(MIN_RSSI); } int newLinkSpeed = WifiNative.getLinkSpeedCommand(); if (newLinkSpeed != -1) { @@ -1388,15 +1389,17 @@ public class WifiStateMachine extends HierarchicalStateMachine { /* Disable interface */ NetworkUtils.disableInterface(mInterfaceName); - /* send event to CM & network change broadcast */ - setNetworkDetailedState(DetailedState.DISCONNECTED); - sendNetworkStateChangeBroadcast(mLastBssid); - /* Reset data structures */ mWifiInfo.setInetAddress(null); mWifiInfo.setBSSID(null); mWifiInfo.setSSID(null); mWifiInfo.setNetworkId(-1); + mWifiInfo.setRssi(MIN_RSSI); + mWifiInfo.setLinkSpeed(-1); + + /* send event to CM & network change broadcast */ + setNetworkDetailedState(DetailedState.DISCONNECTED); + sendNetworkStateChangeBroadcast(mLastBssid); /* Clear network properties */ mLinkProperties.clear(); @@ -1538,6 +1541,9 @@ public class WifiStateMachine extends HierarchicalStateMachine { case CMD_ENABLE_RSSI_POLL: mEnableRssiPolling = (message.arg1 == 1); break; + case CMD_ENABLE_BACKGROUND_SCAN: + mEnableBackgroundScan = (message.arg1 == 1); + break; /* Discard */ case CMD_LOAD_DRIVER: case CMD_UNLOAD_DRIVER: @@ -1577,7 +1583,7 @@ public class WifiStateMachine extends HierarchicalStateMachine { break; case CMD_START_WPS: /* Return failure when the state machine cannot handle WPS initiation*/ - mReplyChannel.replyToMessage(message, message.what, + mReplyChannel.replyToMessage(message, WifiManager.CMD_WPS_COMPLETED, new WpsResult(Status.FAILURE)); break; default: @@ -1973,6 +1979,7 @@ public class WifiStateMachine extends HierarchicalStateMachine { eventLoggingEnabled = false; setScanResults(WifiNative.scanResultsCommand()); sendScanResultsAvailableBroadcast(); + mScanResultIsPending = false; break; case CMD_PING_SUPPLICANT: boolean ok = WifiNative.pingCommand(); @@ -2180,6 +2187,7 @@ public class WifiStateMachine extends HierarchicalStateMachine { case CMD_START_SCAN: eventLoggingEnabled = false; WifiNative.scanCommand(message.arg1 == SCAN_ACTIVE); + mScanResultIsPending = true; break; case CMD_SET_HIGH_PERF_MODE: setHighPerfModeEnabledNative(message.arg1 == 1); @@ -2360,7 +2368,10 @@ public class WifiStateMachine extends HierarchicalStateMachine { // 50023 supplicant_state_changed (custom|1|5) EventLog.writeEvent(EVENTLOG_SUPPLICANT_STATE_CHANGED, state.ordinal()); mWifiInfo.setSupplicantState(state); - mWifiInfo.setNetworkId(stateChangeResult.networkId); + // Network id is only valid when we start connecting + if (SupplicantState.isConnecting(state)) { + mWifiInfo.setNetworkId(stateChangeResult.networkId); + } if (state == SupplicantState.ASSOCIATING) { /* BSSID is valid only in ASSOCIATING state */ mWifiInfo.setBSSID(stateChangeResult.BSSID); @@ -2681,8 +2692,8 @@ public class WifiStateMachine extends HierarchicalStateMachine { * back to CONNECT_MODE. */ WifiNative.setScanResultHandlingCommand(SCAN_ONLY_MODE); - WifiNative.scanCommand(message.arg1 == SCAN_ACTIVE); - break; + /* Have the parent state handle the rest */ + return NOT_HANDLED; /* Ignore connection to same network */ case CMD_CONNECT_NETWORK: int netId = message.arg1; @@ -2738,6 +2749,15 @@ public class WifiStateMachine extends HierarchicalStateMachine { } return HANDLED; } + @Override + public void exit() { + /* If a scan result is pending in connected state, the supplicant + * is in SCAN_ONLY_MODE. Restore CONNECT_MODE on exit + */ + if (mScanResultIsPending) { + WifiNative.setScanResultHandlingCommand(CONNECT_MODE); + } + } } class DisconnectingState extends HierarchicalState { @@ -2771,21 +2791,49 @@ public class WifiStateMachine extends HierarchicalStateMachine { } class DisconnectedState extends HierarchicalState { + private boolean mAlarmEnabled = false; + private long mScanIntervalMs; + + private void setScanAlarm(boolean enabled) { + if (enabled == mAlarmEnabled) return; + if (enabled) { + mAlarmManager.setRepeating(AlarmManager.RTC_WAKEUP, + System.currentTimeMillis() + mScanIntervalMs, + mScanIntervalMs, + mScanIntent); + + mAlarmEnabled = true; + } else { + mAlarmManager.cancel(mScanIntent); + mAlarmEnabled = false; + } + } + @Override public void enter() { if (DBG) Log.d(TAG, getName() + "\n"); EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName()); - /** - * In a disconnected state, an infrequent scan that wakes - * up the device is needed to ensure a user connects to - * an access point on the move - */ - long scanMs = Settings.Secure.getLong(mContext.getContentResolver(), + mScanIntervalMs = Settings.Secure.getLong(mContext.getContentResolver(), Settings.Secure.WIFI_SCAN_INTERVAL_MS, DEFAULT_SCAN_INTERVAL_MS); - - mAlarmManager.setRepeating(AlarmManager.RTC_WAKEUP, - System.currentTimeMillis() + scanMs, scanMs, mScanIntent); + /* + * We initiate background scanning if it is enabled, otherwise we + * initiate an infrequent scan that wakes up the device to ensure + * a user connects to an access point on the move + */ + if (mEnableBackgroundScan) { + /* If a regular scan result is pending, do not initiate background + * scan until the scan results are returned. This is needed because + * initiating a background scan will cancel the regular scan and + * scan results will not be returned until background scanning is + * cleared + */ + if (!mScanResultIsPending) { + WifiNative.enableBackgroundScan(true); + } + } else { + setScanAlarm(true); + } } @Override public boolean processMessage(Message message) { @@ -2800,6 +2848,16 @@ public class WifiStateMachine extends HierarchicalStateMachine { transitionTo(mScanModeState); } break; + case CMD_ENABLE_BACKGROUND_SCAN: + mEnableBackgroundScan = (message.arg1 == 1); + if (mEnableBackgroundScan) { + WifiNative.enableBackgroundScan(true); + setScanAlarm(false); + } else { + WifiNative.enableBackgroundScan(false); + setScanAlarm(true); + } + break; /* Ignore network disconnect */ case NETWORK_DISCONNECTION_EVENT: break; @@ -2808,6 +2866,20 @@ public class WifiStateMachine extends HierarchicalStateMachine { setNetworkDetailedState(WifiInfo.getDetailedStateOf(stateChangeResult.state)); /* DriverStartedState does the rest of the handling */ return NOT_HANDLED; + case CMD_START_SCAN: + /* Disable background scan temporarily during a regular scan */ + if (mEnableBackgroundScan) { + WifiNative.enableBackgroundScan(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); + } + /* Handled in parent state */ + return NOT_HANDLED; default: return NOT_HANDLED; } @@ -2817,7 +2889,11 @@ public class WifiStateMachine extends HierarchicalStateMachine { @Override public void exit() { - mAlarmManager.cancel(mScanIntent); + /* No need for a background scan upon exit from a disconnected state */ + if (mEnableBackgroundScan) { + WifiNative.enableBackgroundScan(false); + } + setScanAlarm(false); } } diff --git a/wifi/java/android/net/wifi/WpsStateMachine.java b/wifi/java/android/net/wifi/WpsStateMachine.java index 92f9f57..32d77a1 100644 --- a/wifi/java/android/net/wifi/WpsStateMachine.java +++ b/wifi/java/android/net/wifi/WpsStateMachine.java @@ -110,7 +110,7 @@ class WpsStateMachine extends HierarchicalStateMachine { Log.e(TAG, "Invalid setup for WPS"); break; } - mReplyChannel.replyToMessage(message, message.what, result); + mReplyChannel.replyToMessage(message, WifiManager.CMD_WPS_COMPLETED, result); if (result.status == Status.SUCCESS) { transitionTo(mActiveState); } else { @@ -172,7 +172,7 @@ class WpsStateMachine extends HierarchicalStateMachine { break; case WifiStateMachine.CMD_START_WPS: /* Ignore request and send an in progress message */ - mReplyChannel.replyToMessage(message, message.what, + mReplyChannel.replyToMessage(message, WifiManager.CMD_WPS_COMPLETED, new WpsResult(Status.IN_PROGRESS)); break; default: |