diff options
author | Irfan Sheriff <isheriff@google.com> | 2010-12-23 09:17:39 -0800 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2010-12-23 09:17:39 -0800 |
commit | 68b9f6f90a8e659a3e40a010f8ad46382f0deeb8 (patch) | |
tree | 291def2ece924767cfe15de53d167b3bdb1f8b4c | |
parent | d486375c148b54be209468d83311b981ef3258cc (diff) | |
parent | b45e726bf5df9650e8a67a7c05bf2f41f414c07d (diff) | |
download | frameworks_base-68b9f6f90a8e659a3e40a010f8ad46382f0deeb8.zip frameworks_base-68b9f6f90a8e659a3e40a010f8ad46382f0deeb8.tar.gz frameworks_base-68b9f6f90a8e659a3e40a010f8ad46382f0deeb8.tar.bz2 |
Merge "Fix wifi broadcasts"
3 files changed, 136 insertions, 39 deletions
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/unit/WifiClientTest.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/unit/WifiClientTest.java index e0a3ee6..e22b018 100644 --- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/unit/WifiClientTest.java +++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/unit/WifiClientTest.java @@ -18,14 +18,17 @@ package com.android.connectivitymanagertest.unit; import android.content.BroadcastReceiver; import android.content.Intent; +import android.content.IntentFilter; import android.content.Context; import android.app.Instrumentation; import android.os.Handler; import android.os.Message; +import android.net.NetworkInfo; import android.net.wifi.WifiManager; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiConfiguration.KeyMgmt; import android.net.wifi.WifiConfiguration.Status; +import android.net.wifi.SupplicantState; import android.test.suitebuilder.annotation.LargeTest; import android.test.AndroidTestCase; @@ -45,10 +48,62 @@ public class WifiClientTest extends AndroidTestCase { //10s delay for turning on wifi private static final int DELAY = 10000; + private WifiStateListener mWifiStateListener; + int mWifiState; + int mDisableBroadcastCounter = 0; + int mEnableBroadcastCounter = 0; + NetworkInfo mNetworkInfo; + boolean mSupplicantConnection; + SupplicantState mSupplicantState; + + private class WifiStateListener extends BroadcastReceiver { + @Override + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) { + mWifiState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, + WifiManager.WIFI_STATE_UNKNOWN); + switch (mWifiState) { + case WifiManager.WIFI_STATE_DISABLING: + if (mDisableBroadcastCounter == 0) mDisableBroadcastCounter++; + break; + case WifiManager.WIFI_STATE_DISABLED: + if (mDisableBroadcastCounter == 1) mDisableBroadcastCounter++; + break; + case WifiManager.WIFI_STATE_ENABLING: + if (mEnableBroadcastCounter == 0) mEnableBroadcastCounter++; + break; + case WifiManager.WIFI_STATE_ENABLED: + if (mEnableBroadcastCounter == 1) mEnableBroadcastCounter++; + break; + } + } else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) { + mNetworkInfo = (NetworkInfo) + intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO); + } else if (action.equals(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION)) { + mSupplicantState = (SupplicantState) + intent.getParcelableExtra(WifiManager.EXTRA_NEW_STATE); + } else if (action.equals(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION)) { + mSupplicantConnection = + intent.getBooleanExtra(WifiManager.EXTRA_SUPPLICANT_CONNECTED, false); + } + } + } @Override protected void setUp() throws Exception { super.setUp(); + + // register a connectivity receiver for CONNECTIVITY_ACTION; + + mWifiStateListener = new WifiStateListener(); + IntentFilter mIntentFilter = new IntentFilter(); + mIntentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION); + mIntentFilter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION); + mIntentFilter.addAction(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION); + mIntentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); + getContext().registerReceiver(mWifiStateListener, mIntentFilter); + mWifiManager = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE); mWifiManager.setWifiEnabled(true); assertNotNull(mWifiManager); @@ -183,4 +238,37 @@ public class WifiClientTest extends AndroidTestCase { assertTrue(ret); mWifiManager.saveConfiguration(); } + + // Test case 5: test wifi state change broadcasts + @LargeTest + public void testWifiBroadcasts() { + + /* Initialize */ + mWifiManager.setWifiEnabled(false); + sleepAfterWifiEnable(); + mDisableBroadcastCounter = 0; + mEnableBroadcastCounter = 0; + mSupplicantConnection = false; + mNetworkInfo = null; + mSupplicantState = null; + + /* Enable wifi */ + mWifiManager.setWifiEnabled(true); + sleepAfterWifiEnable(); + assertTrue(mEnableBroadcastCounter == 2); + assertTrue(mSupplicantConnection == true); + assertTrue(mNetworkInfo.isConnected()); + assertTrue(mSupplicantState == SupplicantState.COMPLETED); + + + /* Disable wifi */ + mWifiManager.setWifiEnabled(false); + sleepAfterWifiEnable(); + assertTrue(mDisableBroadcastCounter == 2); + assertTrue(mSupplicantConnection == false); + assertTrue(!mNetworkInfo.isConnected()); + assertTrue(mSupplicantState != SupplicantState.COMPLETED); + + } + } diff --git a/wifi/java/android/net/wifi/SupplicantStateTracker.java b/wifi/java/android/net/wifi/SupplicantStateTracker.java index f823314..08e4606 100644 --- a/wifi/java/android/net/wifi/SupplicantStateTracker.java +++ b/wifi/java/android/net/wifi/SupplicantStateTracker.java @@ -79,11 +79,6 @@ class SupplicantStateTracker extends HierarchicalStateMachine { start(); } - public void resetSupplicantState() { - transitionTo(mUninitializedState); - } - - private void transitionOnSupplicantStateChange(StateChangeResult stateChangeResult) { SupplicantState supState = (SupplicantState) stateChangeResult.state; @@ -121,11 +116,11 @@ class SupplicantStateTracker extends HierarchicalStateMachine { } } - private void sendSupplicantStateChangedBroadcast(StateChangeResult sc, boolean failedAuth) { + private void sendSupplicantStateChangedBroadcast(SupplicantState state, boolean failedAuth) { Intent intent = new Intent(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION); intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | Intent.FLAG_RECEIVER_REPLACE_PENDING); - intent.putExtra(WifiManager.EXTRA_NEW_STATE, (Parcelable)sc.state); + intent.putExtra(WifiManager.EXTRA_NEW_STATE, (Parcelable) state); if (failedAuth) { intent.putExtra( WifiManager.EXTRA_SUPPLICANT_ERROR, @@ -153,11 +148,14 @@ class SupplicantStateTracker extends HierarchicalStateMachine { break; case WifiStateMachine.SUPPLICANT_STATE_CHANGE_EVENT: StateChangeResult stateChangeResult = (StateChangeResult) message.obj; - sendSupplicantStateChangedBroadcast(stateChangeResult, - mAuthFailureInSupplicantBroadcast); + SupplicantState state = stateChangeResult.state; + sendSupplicantStateChangedBroadcast(state, mAuthFailureInSupplicantBroadcast); mAuthFailureInSupplicantBroadcast = false; transitionOnSupplicantStateChange(stateChangeResult); break; + case WifiStateMachine.CMD_RESET_SUPPLICANT_STATE: + transitionTo(mUninitializedState); + break; default: Log.e(TAG, "Ignoring " + message); break; @@ -166,6 +164,14 @@ class SupplicantStateTracker extends HierarchicalStateMachine { } } + /* + * This indicates that the supplicant state as seen + * by the framework is not initialized yet. We are + * in this state right after establishing a control + * channel connection before any supplicant events + * or after we have lost the control channel + * connection to the supplicant + */ class UninitializedState extends HierarchicalState { @Override public void enter() { @@ -239,7 +245,7 @@ class SupplicantStateTracker extends HierarchicalStateMachine { switch (message.what) { case WifiStateMachine.SUPPLICANT_STATE_CHANGE_EVENT: StateChangeResult stateChangeResult = (StateChangeResult) message.obj; - SupplicantState state = (SupplicantState) stateChangeResult.state; + SupplicantState state = stateChangeResult.state; if (state == SupplicantState.ASSOCIATING || state == SupplicantState.ASSOCIATED || state == SupplicantState.FOUR_WAY_HANDSHAKE || @@ -253,7 +259,7 @@ class SupplicantStateTracker extends HierarchicalStateMachine { WifiConfigStore.disableNetwork(stateChangeResult.networkId); } mLoopDetectIndex = state.ordinal(); - sendSupplicantStateChangedBroadcast(stateChangeResult, + sendSupplicantStateChangedBroadcast(state, mAuthFailureInSupplicantBroadcast); } else { //Have the DefaultState handle the transition @@ -280,9 +286,8 @@ class SupplicantStateTracker extends HierarchicalStateMachine { switch(message.what) { case WifiStateMachine.SUPPLICANT_STATE_CHANGE_EVENT: StateChangeResult stateChangeResult = (StateChangeResult) message.obj; - SupplicantState state = (SupplicantState) stateChangeResult.state; - sendSupplicantStateChangedBroadcast(stateChangeResult, - mAuthFailureInSupplicantBroadcast); + SupplicantState state = stateChangeResult.state; + sendSupplicantStateChangedBroadcast(state, mAuthFailureInSupplicantBroadcast); /* Ignore a re-auth in completed state */ if (state == SupplicantState.ASSOCIATING || state == SupplicantState.ASSOCIATED || @@ -293,6 +298,10 @@ class SupplicantStateTracker extends HierarchicalStateMachine { } transitionOnSupplicantStateChange(stateChangeResult); break; + case WifiStateMachine.CMD_RESET_SUPPLICANT_STATE: + sendSupplicantStateChangedBroadcast(SupplicantState.DISCONNECTED, false); + transitionTo(mUninitializedState); + break; default: return NOT_HANDLED; } diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java index 17a35c4..909ad43 100644 --- a/wifi/java/android/net/wifi/WifiStateMachine.java +++ b/wifi/java/android/net/wifi/WifiStateMachine.java @@ -326,13 +326,16 @@ public class WifiStateMachine extends HierarchicalStateMachine { /* Set the frequency band */ static final int CMD_SET_FREQUENCY_BAND = 90; - /* Commands from the SupplicantStateTracker */ + /* Commands from/to the SupplicantStateTracker */ /* Indicates whether a wifi network is available for connection */ - static final int CMD_SET_NETWORK_AVAILABLE = 111; + static final int CMD_SET_NETWORK_AVAILABLE = 111; + /* Reset the supplicant state tracker */ + static final int CMD_RESET_SUPPLICANT_STATE = 112; + /* Commands/events reported by WpsStateMachine */ /* Indicates the completion of WPS activity */ - static final int WPS_COMPLETED_EVENT = 121; + static final int WPS_COMPLETED_EVENT = 121; private static final int CONNECT_MODE = 1; private static final int SCAN_ONLY_MODE = 2; @@ -1453,20 +1456,17 @@ public class WifiStateMachine extends HierarchicalStateMachine { ********************************************************/ /** - * A structure for supplying information about a supplicant state - * change in the STATE_CHANGE event message that comes from the - * WifiMonitor - * thread. + * Stores supplicant state change information passed from WifiMonitor */ static class StateChangeResult { - StateChangeResult(int networkId, String BSSID, Object state) { + StateChangeResult(int networkId, String BSSID, SupplicantState state) { this.state = state; this.BSSID = BSSID; this.networkId = networkId; } int networkId; String BSSID; - Object state; + SupplicantState state; } /** @@ -1505,11 +1505,9 @@ public class WifiStateMachine extends HierarchicalStateMachine { */ void notifyNetworkStateChange(DetailedState newState, String BSSID, int networkId) { if (newState == NetworkInfo.DetailedState.CONNECTED) { - sendMessage(obtainMessage(NETWORK_CONNECTION_EVENT, - new StateChangeResult(networkId, BSSID, newState))); + sendMessage(obtainMessage(NETWORK_CONNECTION_EVENT, networkId, 0, BSSID)); } else { - sendMessage(obtainMessage(NETWORK_DISCONNECTION_EVENT, - new StateChangeResult(networkId, BSSID, newState))); + sendMessage(obtainMessage(NETWORK_DISCONNECTION_EVENT, networkId, 0, BSSID)); } } @@ -1755,7 +1753,6 @@ public class WifiStateMachine extends HierarchicalStateMachine { if(WifiNative.startSupplicant()) { Log.d(TAG, "Supplicant start successful"); mWifiMonitor.startMonitoring(); - setWifiState(WIFI_STATE_ENABLED); transitionTo(mSupplicantStartingState); } else { Log.e(TAG, "Failed to start supplicant!"); @@ -1914,8 +1911,11 @@ public class WifiStateMachine extends HierarchicalStateMachine { switch(message.what) { case SUP_CONNECTION_EVENT: Log.d(TAG, "Supplicant connection established"); + setWifiState(WIFI_STATE_ENABLED); mSupplicantRestartCount = 0; - mSupplicantStateTracker.resetSupplicantState(); + /* Reset the supplicant state to indicate the supplicant + * state is not known at this time */ + mSupplicantStateTracker.sendMessage(CMD_RESET_SUPPLICANT_STATE); /* Initialize data structures */ mLastBssid = null; mLastNetworkId = -1; @@ -1944,7 +1944,7 @@ public class WifiStateMachine extends HierarchicalStateMachine { Log.e(TAG, "Failed " + mSupplicantRestartCount + " times to start supplicant, unload driver"); transitionTo(mDriverLoadedState); - sendMessage(CMD_UNLOAD_DRIVER); + sendMessage(obtainMessage(CMD_UNLOAD_DRIVER, WIFI_STATE_UNKNOWN, 0)); } break; case CMD_LOAD_DRIVER: @@ -1995,8 +1995,9 @@ public class WifiStateMachine extends HierarchicalStateMachine { WifiNative.killSupplicant(); } handleNetworkDisconnect(); + setWifiState(WIFI_STATE_DISABLING); sendSupplicantConnectionChangedBroadcast(false); - mSupplicantStateTracker.resetSupplicantState(); + mSupplicantStateTracker.sendMessage(CMD_RESET_SUPPLICANT_STATE); transitionTo(mSupplicantStoppingState); break; case SUP_DISCONNECTION_EVENT: /* Supplicant connection lost */ @@ -2006,7 +2007,7 @@ public class WifiStateMachine extends HierarchicalStateMachine { WifiNative.closeSupplicantConnection(); handleNetworkDisconnect(); sendSupplicantConnectionChangedBroadcast(false); - mSupplicantStateTracker.resetSupplicantState(); + mSupplicantStateTracker.sendMessage(CMD_RESET_SUPPLICANT_STATE); transitionTo(mDriverLoadedState); sendMessageDelayed(CMD_START_SUPPLICANT, SUPPLICANT_RESTART_INTERVAL_MSECS); break; @@ -2380,7 +2381,7 @@ public class WifiStateMachine extends HierarchicalStateMachine { break; case SUPPLICANT_STATE_CHANGE_EVENT: stateChangeResult = (StateChangeResult) message.obj; - SupplicantState state = (SupplicantState) stateChangeResult.state; + SupplicantState state = stateChangeResult.state; // Supplicant state change // [31-13] Reserved for future use // [8 - 0] Supplicant state (as defined in SupplicantState.java) @@ -2445,13 +2446,13 @@ public class WifiStateMachine extends HierarchicalStateMachine { return NOT_HANDLED; case NETWORK_CONNECTION_EVENT: Log.d(TAG,"Network connection established"); - stateChangeResult = (StateChangeResult) message.obj; + mLastNetworkId = message.arg1; + mLastBssid = (String) message.obj; //TODO: make supplicant modification to push this in events mWifiInfo.setSSID(fetchSSID()); - mWifiInfo.setBSSID(mLastBssid = stateChangeResult.BSSID); - mWifiInfo.setNetworkId(stateChangeResult.networkId); - mLastNetworkId = stateChangeResult.networkId; + mWifiInfo.setBSSID(mLastBssid); + mWifiInfo.setNetworkId(mLastNetworkId); /* send event to CM & network change broadcast */ setNetworkDetailedState(DetailedState.OBTAINING_IPADDR); sendNetworkStateChangeBroadcast(mLastBssid); @@ -2825,8 +2826,7 @@ public class WifiStateMachine extends HierarchicalStateMachine { break; case SUPPLICANT_STATE_CHANGE_EVENT: StateChangeResult stateChangeResult = (StateChangeResult) message.obj; - SupplicantState state = (SupplicantState) stateChangeResult.state; - setNetworkDetailedState(WifiInfo.getDetailedStateOf(state)); + setNetworkDetailedState(WifiInfo.getDetailedStateOf(stateChangeResult.state)); /* DriverStartedState does the rest of the handling */ return NOT_HANDLED; default: |