diff options
author | Lorenzo Colitti <lorenzo@google.com> | 2017-09-28 14:46:29 +0900 |
---|---|---|
committer | Roshan Pius <rpius@google.com> | 2017-10-04 08:20:26 -0700 |
commit | 9686c96d8d0c0bc21ca069e244e2570c169724e1 (patch) | |
tree | 9d73516faedacc4bbf9e46d3d275d9498585447b | |
parent | 9d7cf1434fc63dec2d63d5a9c7330c2fa37aefc5 (diff) |
Allow connecting with no requests if we're already connected.
Currently, we drop all connection start attempts if we do not
have any NetworkRequests that we can fulfil. This can happen if
the default network has a score that's higher than our score
filter. The reason for this is that we don't want to connect a
new network if we're not already connected: if we did,
ConnectivityService would immediately request that the network be
torn down.
However, it does make sense to connect if we are already
connected, because that means that we ourselves are the
highest-scoring network - otherwise, ConnectivityService would
have torn us down. So, when deciding whether to process a
connection request, allow it if mNetworkAgent is non-null, even
if there are no NetworkRequests that we can fulfil.
In order to do this, move the check from startConnectToNetwork to
the code that processes CMD_START_CONNECT, because it's not safe
to access mNetworkAgent except from the handler thread. Moving
the check also seems more correct in general, because
the return value of hasConnectionRequests() could change between
when startConnectToNetwork is called and when the resulting
CMD_START_CONNECT is processed.
The connect requests are only allowed from the settings/sysui. We don't
allow any non-privileged apps to be able to override the user's decision
to stay connected to a network with no internet access (which causes the
mNetworkAgent.releaseNetworkFor()).
Bug: 65262556
Test: Unit tests for START_CONNECT handling for 4 scenarios:
a) START_CONNECT with the default network request.
b) START_CONNECT with no network request.
c) START_CONNECT with no network request, but already connected
d) START_CONNECT with no network request, but already connected, but
from non-privileged app.
Test: Settings can connect to a new network when wifi has a score of 100
Change-Id: Iad582b5109a81f238f335eaac3e7264c5da6e9b1
4 files changed, 216 insertions, 46 deletions
diff --git a/service/java/com/android/server/wifi/WifiConnectivityManager.java b/service/java/com/android/server/wifi/WifiConnectivityManager.java index 7e730c838..6bfce74db 100644 --- a/service/java/com/android/server/wifi/WifiConnectivityManager.java +++ b/service/java/com/android/server/wifi/WifiConnectivityManager.java @@ -30,6 +30,7 @@ import android.net.wifi.WifiScanner.PnoSettings; import android.net.wifi.WifiScanner.ScanSettings; import android.os.Handler; import android.os.Looper; +import android.os.Process; import android.util.LocalLog; import android.util.Log; @@ -741,7 +742,7 @@ public class WifiConnectivityManager { localLog("connectToNetwork: Connect to " + targetAssociationId + " from " + currentAssociationId); } - mStateMachine.startConnectToNetwork(candidate.networkId, targetBssid); + mStateMachine.startConnectToNetwork(candidate.networkId, Process.WIFI_UID, targetBssid); } } diff --git a/service/java/com/android/server/wifi/WifiStateMachine.java b/service/java/com/android/server/wifi/WifiStateMachine.java index a3054c92b..9e124463d 100644 --- a/service/java/com/android/server/wifi/WifiStateMachine.java +++ b/service/java/com/android/server/wifi/WifiStateMachine.java @@ -1321,7 +1321,7 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss /** * Initiates connection to a network specified by the user/app. This method checks if the - * requesting app holds the WIFI_CONFIG_OVERRIDE permission. + * requesting app holds the NETWORK_SETTINGS permission. * * @param netId Id network to initiate connection. * @param uid UID of the app requesting the connection. @@ -1350,7 +1350,7 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss logi("connectToUserSelectNetwork already connecting/connected=" + netId); } else { mWifiConnectivityManager.prepareForForcedConnection(netId); - startConnectToNetwork(netId, SUPPLICANT_BSSID_ANY); + startConnectToNetwork(netId, uid, SUPPLICANT_BSSID_ANY); } return true; } @@ -5178,7 +5178,23 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss case CMD_START_CONNECT: /* connect command coming from auto-join */ netId = message.arg1; + int uid = message.arg2; bssid = (String) message.obj; + + synchronized (mWifiReqCountLock) { + if (!hasConnectionRequests()) { + if (mNetworkAgent == null) { + loge("CMD_START_CONNECT but no requests and not connected," + + " bailing"); + break; + } else if (!mWifiPermissionsUtil.checkNetworkSettingsPermission(uid)) { + loge("CMD_START_CONNECT but no requests and connected, but app " + + "does not have sufficient permissions, bailing"); + break; + } + } + } + config = mWifiConfigManager.getConfiguredNetworkWithPassword(netId); logd("CMD_START_CONNECT sup state " + mSupplicantStateTracker.getSupplicantStateName() @@ -5278,7 +5294,7 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss // start a new connection with the updated credentials. logi("SAVE_NETWORK credential changed for config=" + config.configKey() + ", Reconnecting."); - startConnectToNetwork(netId, SUPPLICANT_BSSID_ANY); + startConnectToNetwork(netId, message.sendingUid, SUPPLICANT_BSSID_ANY); } else { if (result.hasProxyChanged()) { log("Reconfiguring proxy on connection"); @@ -6121,7 +6137,7 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss WifiConfiguration config = getCurrentWifiConfiguration(); if (shouldEvaluateWhetherToSendExplicitlySelected(config)) { boolean prompt = - mWifiPermissionsUtil.checkConfigOverridePermission(config.lastConnectUid); + mWifiPermissionsUtil.checkNetworkSettingsPermission(config.lastConnectUid); if (mVerboseLoggingEnabled) { log("Network selected by UID " + config.lastConnectUid + " prompt=" + prompt); } @@ -7097,14 +7113,11 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss * Automatically connect to the network specified * * @param networkId ID of the network to connect to + * @param uid UID of the app triggering the connection. * @param bssid BSSID of the network */ - public void startConnectToNetwork(int networkId, String bssid) { - synchronized (mWifiReqCountLock) { - if (hasConnectionRequests()) { - sendMessage(CMD_START_CONNECT, networkId, 0, bssid); - } - } + public void startConnectToNetwork(int networkId, int uid, String bssid) { + sendMessage(CMD_START_CONNECT, networkId, uid, bssid); } /** diff --git a/tests/wifitests/src/com/android/server/wifi/WifiConnectivityManagerTest.java b/tests/wifitests/src/com/android/server/wifi/WifiConnectivityManagerTest.java index 6420fac88..5fb700720 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiConnectivityManagerTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiConnectivityManagerTest.java @@ -41,6 +41,7 @@ import android.net.wifi.WifiScanner.ScanData; import android.net.wifi.WifiScanner.ScanListener; import android.net.wifi.WifiScanner.ScanSettings; import android.net.wifi.WifiSsid; +import android.os.Process; import android.os.SystemClock; import android.os.WorkSource; import android.os.test.TestLooper; @@ -314,7 +315,8 @@ public class WifiConnectivityManagerTest { mWifiConnectivityManager.handleConnectionStateChanged( WifiConnectivityManager.WIFI_STATE_DISCONNECTED); - verify(mWifiStateMachine).startConnectToNetwork(CANDIDATE_NETWORK_ID, CANDIDATE_BSSID); + verify(mWifiStateMachine).startConnectToNetwork( + CANDIDATE_NETWORK_ID, Process.WIFI_UID, CANDIDATE_BSSID); } /** @@ -333,7 +335,8 @@ public class WifiConnectivityManagerTest { mWifiConnectivityManager.handleConnectionStateChanged( WifiConnectivityManager.WIFI_STATE_CONNECTED); - verify(mWifiStateMachine).startConnectToNetwork(CANDIDATE_NETWORK_ID, CANDIDATE_BSSID); + verify(mWifiStateMachine).startConnectToNetwork( + CANDIDATE_NETWORK_ID, Process.WIFI_UID, CANDIDATE_BSSID); } /** @@ -353,7 +356,7 @@ public class WifiConnectivityManagerTest { mWifiConnectivityManager.handleScreenStateChanged(true); verify(mWifiStateMachine, atLeastOnce()).startConnectToNetwork( - CANDIDATE_NETWORK_ID, CANDIDATE_BSSID); + CANDIDATE_NETWORK_ID, Process.WIFI_UID, CANDIDATE_BSSID); } /** @@ -373,7 +376,7 @@ public class WifiConnectivityManagerTest { mWifiConnectivityManager.handleScreenStateChanged(true); verify(mWifiStateMachine, atLeastOnce()).startConnectToNetwork( - CANDIDATE_NETWORK_ID, CANDIDATE_BSSID); + CANDIDATE_NETWORK_ID, Process.WIFI_UID, CANDIDATE_BSSID); } /** @@ -400,7 +403,7 @@ public class WifiConnectivityManagerTest { mWifiConnectivityManager.handleScreenStateChanged(true); verify(mWifiStateMachine, times(0)).startConnectToNetwork( - CANDIDATE_NETWORK_ID, CANDIDATE_BSSID); + CANDIDATE_NETWORK_ID, Process.WIFI_UID, CANDIDATE_BSSID); } /** @@ -438,7 +441,7 @@ public class WifiConnectivityManagerTest { // Verify that we attempt to connect upto the rate. verify(mWifiStateMachine, times(numAttempts)).startConnectToNetwork( - CANDIDATE_NETWORK_ID, CANDIDATE_BSSID); + CANDIDATE_NETWORK_ID, Process.WIFI_UID, CANDIDATE_BSSID); } /** @@ -479,7 +482,7 @@ public class WifiConnectivityManagerTest { // Verify that all the connection attempts went through verify(mWifiStateMachine, times(numAttempts)).startConnectToNetwork( - CANDIDATE_NETWORK_ID, CANDIDATE_BSSID); + CANDIDATE_NETWORK_ID, Process.WIFI_UID, CANDIDATE_BSSID); } /** @@ -523,7 +526,7 @@ public class WifiConnectivityManagerTest { // Verify that all the connection attempts went through verify(mWifiStateMachine, times(numAttempts)).startConnectToNetwork( - CANDIDATE_NETWORK_ID, CANDIDATE_BSSID); + CANDIDATE_NETWORK_ID, Process.WIFI_UID, CANDIDATE_BSSID); } /** @@ -1152,7 +1155,8 @@ public class WifiConnectivityManagerTest { // Verify that WCM receives the scan results and initiates a connection // to the network. - verify(mWifiStateMachine).startConnectToNetwork(CANDIDATE_NETWORK_ID, CANDIDATE_BSSID); + verify(mWifiStateMachine).startConnectToNetwork( + CANDIDATE_NETWORK_ID, Process.WIFI_UID, CANDIDATE_BSSID); } /** @@ -1178,7 +1182,7 @@ public class WifiConnectivityManagerTest { // No roaming because no full band scan results. verify(mWifiStateMachine, times(0)).startConnectToNetwork( - CANDIDATE_NETWORK_ID, CANDIDATE_BSSID); + CANDIDATE_NETWORK_ID, Process.WIFI_UID, CANDIDATE_BSSID); // Set up as full band scan results. when(mScanData.isAllChannelsScanned()).thenReturn(true); @@ -1188,7 +1192,8 @@ public class WifiConnectivityManagerTest { mWifiConnectivityManager.forceConnectivityScan(); // Roaming attempt because full band scan results are available. - verify(mWifiStateMachine).startConnectToNetwork(CANDIDATE_NETWORK_ID, CANDIDATE_BSSID); + verify(mWifiStateMachine).startConnectToNetwork( + CANDIDATE_NETWORK_ID, Process.WIFI_UID, CANDIDATE_BSSID); } /** @@ -1441,7 +1446,7 @@ public class WifiConnectivityManagerTest { WifiConnectivityManager.WIFI_STATE_DISCONNECTED); verify(mWifiStateMachine).startConnectToNetwork( - CANDIDATE_NETWORK_ID, WifiStateMachine.SUPPLICANT_BSSID_ANY); + CANDIDATE_NETWORK_ID, Process.WIFI_UID, WifiStateMachine.SUPPLICANT_BSSID_ANY); } /* @@ -1477,7 +1482,8 @@ public class WifiConnectivityManagerTest { mWifiConnectivityManager.handleConnectionStateChanged( WifiConnectivityManager.WIFI_STATE_DISCONNECTED); - verify(mWifiStateMachine).startConnectToNetwork(CANDIDATE_NETWORK_ID, CANDIDATE_BSSID); + verify(mWifiStateMachine).startConnectToNetwork( + CANDIDATE_NETWORK_ID, Process.WIFI_UID, CANDIDATE_BSSID); } /* @@ -1497,7 +1503,8 @@ public class WifiConnectivityManagerTest { mWifiConnectivityManager.handleConnectionStateChanged( WifiConnectivityManager.WIFI_STATE_DISCONNECTED); - verify(mWifiStateMachine).startConnectToNetwork(CANDIDATE_NETWORK_ID, CANDIDATE_BSSID); + verify(mWifiStateMachine).startConnectToNetwork( + CANDIDATE_NETWORK_ID, Process.WIFI_UID, CANDIDATE_BSSID); } /* @@ -1529,7 +1536,8 @@ public class WifiConnectivityManagerTest { mWifiConnectivityManager.handleConnectionStateChanged( WifiConnectivityManager.WIFI_STATE_DISCONNECTED); - verify(mWifiStateMachine).startConnectToNetwork(CANDIDATE_NETWORK_ID, CANDIDATE_BSSID); + verify(mWifiStateMachine).startConnectToNetwork( + CANDIDATE_NETWORK_ID, Process.WIFI_UID, CANDIDATE_BSSID); } /** @@ -1619,7 +1627,7 @@ public class WifiConnectivityManagerTest { WifiConnectivityManager.WIFI_STATE_DISCONNECTED); verify(mWifiStateMachine, times(0)).startConnectToNetwork( - CANDIDATE_NETWORK_ID, CANDIDATE_BSSID); + CANDIDATE_NETWORK_ID, Process.WIFI_UID, CANDIDATE_BSSID); } /* diff --git a/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java b/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java index 5b0f59685..ecb4c959c 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java @@ -47,6 +47,9 @@ import android.hardware.wifi.supplicant.V1_0.ISupplicantStaIfaceCallback; import android.net.ConnectivityManager; import android.net.DhcpResults; import android.net.LinkProperties; +import android.net.NetworkCapabilities; +import android.net.NetworkFactory; +import android.net.NetworkRequest; import android.net.dhcp.DhcpClient; import android.net.ip.IpManager; import android.net.wifi.IApInterface; @@ -123,6 +126,7 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.CountDownLatch; +import java.util.function.Consumer; /** * Unit tests for {@link com.android.server.wifi.WifiStateMachine}. @@ -137,9 +141,11 @@ public class WifiStateMachineTest { (ActivityManager.isLowRamDeviceStatic() ? WifiStateMachine.NUM_LOG_RECS_VERBOSE_LOW_MEMORY : WifiStateMachine.NUM_LOG_RECS_VERBOSE); - private static final int FRAMEWORK_NETWORK_ID = 7; + private static final int FRAMEWORK_NETWORK_ID = 0; private static final int TEST_RSSI = -54; private static final int TEST_NETWORK_ID = 54; + private static final int TEST_VALID_NETWORK_SCORE = 54; + private static final int TEST_OUTSCORED_NETWORK_SCORE = 100; private static final int WPS_SUPPLICANT_NETWORK_ID = 5; private static final int WPS_FRAMEWORK_NETWORK_ID = 10; private static final String DEFAULT_TEST_SSID = "\"GoogleGuest\""; @@ -230,7 +236,7 @@ public class WifiStateMachineTest { mAlarmManager.getAlarmManager()); when(context.getSystemService(Context.CONNECTIVITY_SERVICE)).thenReturn( - mock(ConnectivityManager.class)); + mConnectivityManager); when(context.getOpPackageName()).thenReturn(OP_PACKAGE_NAME); @@ -318,6 +324,7 @@ public class WifiStateMachineTest { HandlerThread mP2pThread; HandlerThread mSyncThread; AsyncChannel mWsmAsyncChannel; + AsyncChannel mNetworkFactoryChannel; TestAlarmManager mAlarmManager; MockWifiMonitor mWifiMonitor; TestLooper mLooper; @@ -326,6 +333,7 @@ public class WifiStateMachineTest { FrameworkFacade mFrameworkFacade; IpManager.Callback mIpManagerCallback; PhoneStateListener mPhoneStateListener; + NetworkRequest mDefaultNetworkRequest; final ArgumentCaptor<SoftApManager.Listener> mSoftApManagerListenerCaptor = ArgumentCaptor.forClass(SoftApManager.Listener.class); @@ -361,6 +369,7 @@ public class WifiStateMachineTest { @Mock Clock mClock; @Mock ScanDetailCache mScanDetailCache; @Mock BaseWifiDiagnostics mWifiDiagnostics; + @Mock ConnectivityManager mConnectivityManager; public WifiStateMachineTest() throws Exception { } @@ -449,15 +458,11 @@ public class WifiStateMachineTest { } }).when(mTelephonyManager).listen(any(PhoneStateListener.class), anyInt()); + when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(true); initializeWsm(); } - private void initializeWsm() throws Exception { - mWsm = new WifiStateMachine(mContext, mFrameworkFacade, mLooper.getLooper(), - mUserManager, mWifiInjector, mBackupManagerProxy, mCountryCode, mWifiNative, - mWrongPasswordNotifier); - mWsmThread = getWsmHandlerThread(mWsm); - + private void registerAsyncChannel(Consumer<AsyncChannel> consumer, Messenger messenger) { final AsyncChannel channel = new AsyncChannel(); Handler handler = new Handler(mLooper.getLooper()) { @Override @@ -465,7 +470,7 @@ public class WifiStateMachineTest { switch (msg.what) { case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED: if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) { - mWsmAsyncChannel = channel; + consumer.accept(channel); } else { Log.d(TAG, "Failed to connect Command channel " + this); } @@ -477,15 +482,50 @@ public class WifiStateMachineTest { } }; - channel.connect(mContext, handler, mWsm.getMessenger()); + channel.connect(mContext, handler, messenger); mLooper.dispatchAll(); - /* Now channel is supposed to be connected */ + } + + private void initializeWsm() throws Exception { + mWsm = new WifiStateMachine(mContext, mFrameworkFacade, mLooper.getLooper(), + mUserManager, mWifiInjector, mBackupManagerProxy, mCountryCode, mWifiNative, + mWrongPasswordNotifier); + mWsmThread = getWsmHandlerThread(mWsm); + + registerAsyncChannel((x) -> { + mWsmAsyncChannel = x; + }, mWsm.getMessenger()); mBinderToken = Binder.clearCallingIdentity(); /* Send the BOOT_COMPLETED message to setup some WSM state. */ mWsm.sendMessage(WifiStateMachine.CMD_BOOT_COMPLETED); mLooper.dispatchAll(); + + /* Simulate the initial NetworkRequest sent in by ConnectivityService. */ + ArgumentCaptor<Messenger> captor = ArgumentCaptor.forClass(Messenger.class); + verify(mConnectivityManager, atLeast(2)).registerNetworkFactory( + captor.capture(), anyString()); + Messenger networkFactoryMessenger = captor.getAllValues().get(0); + registerAsyncChannel((x) -> { + mNetworkFactoryChannel = x; + }, networkFactoryMessenger); + + mDefaultNetworkRequest = new NetworkRequest.Builder() + .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) + .build(); + sendDefaultNetworkRequest(TEST_VALID_NETWORK_SCORE); + } + + /** + * Helper function to resend the cached network request (id == 0) with the specified score. + * Note: If you need to add a separate network request, don't use the builder to create one + * since the new request object will again default to id == 0. + */ + private void sendDefaultNetworkRequest(int score) { + mNetworkFactoryChannel.sendMessage( + NetworkFactory.CMD_REQUEST_NETWORK, score, 0, mDefaultNetworkRequest); + mLooper.dispatchAll(); } @After @@ -501,6 +541,7 @@ public class WifiStateMachineTest { mSyncThread = null; mWsmAsyncChannel = null; mWsm = null; + mNetworkFactoryChannel = null; } @Test @@ -1043,22 +1084,81 @@ public class WifiStateMachineTest { hiddenNetworkSet); } - @Test - public void connect() throws Exception { - initializeAndAddNetworkAndVerifySuccess(); - when(mWifiConfigManager.enableNetwork(eq(0), eq(true), anyInt())).thenReturn(true); - when(mWifiConfigManager.checkAndUpdateLastConnectUid(eq(0), anyInt())).thenReturn(true); + private void setupAndStartConnectSequence(WifiConfiguration config) throws Exception { + when(mWifiConfigManager.enableNetwork(eq(config.networkId), eq(true), anyInt())) + .thenReturn(true); + when(mWifiConfigManager.checkAndUpdateLastConnectUid(eq(config.networkId), anyInt())) + .thenReturn(true); + when(mWifiConfigManager.getConfiguredNetwork(eq(config.networkId))) + .thenReturn(config); + when(mWifiConfigManager.getConfiguredNetworkWithPassword(eq(config.networkId))) + .thenReturn(config); mWsm.setOperationalMode(WifiStateMachine.CONNECT_MODE); mLooper.dispatchAll(); verify(mWifiNative).removeAllNetworks(); mLooper.startAutoDispatch(); - assertTrue(mWsm.syncEnableNetwork(mWsmAsyncChannel, 0, true)); + assertTrue(mWsm.syncEnableNetwork(mWsmAsyncChannel, config.networkId, true)); mLooper.stopAutoDispatch(); + } - verify(mWifiConfigManager).enableNetwork(eq(0), eq(true), anyInt()); - verify(mWifiConnectivityManager).setUserConnectChoice(eq(0)); + private void validateSuccessfulConnectSequence(WifiConfiguration config) { + verify(mWifiConfigManager).enableNetwork(eq(config.networkId), eq(true), anyInt()); + verify(mWifiConnectivityManager).setUserConnectChoice(eq(config.networkId)); + verify(mWifiConnectivityManager).prepareForForcedConnection(eq(config.networkId)); + verify(mWifiConfigManager).getConfiguredNetworkWithPassword(eq(config.networkId)); + verify(mWifiNative).connectToNetwork(eq(config)); + } + + private void validateFailureConnectSequence(WifiConfiguration config) { + verify(mWifiConfigManager).enableNetwork(eq(config.networkId), eq(true), anyInt()); + verify(mWifiConnectivityManager).setUserConnectChoice(eq(config.networkId)); + verify(mWifiConnectivityManager).prepareForForcedConnection(eq(config.networkId)); + verify(mWifiConfigManager, never()).getConfiguredNetworkWithPassword(eq(config.networkId)); + verify(mWifiNative, never()).connectToNetwork(eq(config)); + } + + /** + * Tests the network connection initiation sequence with the default network request pending + * from WifiNetworkFactory. + * This simulates the connect sequence using the public + * {@link WifiManager#enableNetwork(int, boolean)} and ensures that we invoke + * {@link WifiNative#connectToNetwork(WifiConfiguration)}. + */ + @Test + public void triggerConnect() throws Exception { + loadComponentsInStaMode(); + WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork(); + config.networkId = FRAMEWORK_NETWORK_ID; + setupAndStartConnectSequence(config); + validateSuccessfulConnectSequence(config); + } + + /** + * Tests the network connection initiation sequence with no network request pending from + * from WifiNetworkFactory. + * This simulates the connect sequence using the public + * {@link WifiManager#enableNetwork(int, boolean)} and ensures that we don't invoke + * {@link WifiNative#connectToNetwork(WifiConfiguration)}. + */ + @Test + public void triggerConnectWithNoNetworkRequest() throws Exception { + loadComponentsInStaMode(); + // Change the network score to remove the network request. + sendDefaultNetworkRequest(TEST_OUTSCORED_NETWORK_SCORE); + WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork(); + config.networkId = FRAMEWORK_NETWORK_ID; + setupAndStartConnectSequence(config); + validateFailureConnectSequence(config); + } + + /** + * Tests the entire successful network connection flow. + */ + @Test + public void connect() throws Exception { + triggerConnect(); when(mWifiConfigManager.getScanDetailCacheForNetwork(FRAMEWORK_NETWORK_ID)) .thenReturn(mScanDetailCache); @@ -1094,6 +1194,54 @@ public class WifiStateMachineTest { assertEquals("ConnectedState", getCurrentState().getName()); } + /** + * Tests the network connection initiation sequence with no network request pending from + * from WifiNetworkFactory when we're already connected to a different network. + * This simulates the connect sequence using the public + * {@link WifiManager#enableNetwork(int, boolean)} and ensures that we invoke + * {@link WifiNative#connectToNetwork(WifiConfiguration)}. + */ + @Test + public void triggerConnectWithNoNetworkRequestAndAlreadyConnected() throws Exception { + // Simulate the first connection. + connect(); + + // Change the network score to remove the network request. + sendDefaultNetworkRequest(TEST_OUTSCORED_NETWORK_SCORE); + + WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork(); + config.networkId = FRAMEWORK_NETWORK_ID + 1; + setupAndStartConnectSequence(config); + validateSuccessfulConnectSequence(config); + verify(mWifiPermissionsUtil, times(2)).checkNetworkSettingsPermission(anyInt()); + } + + /** + * Tests the network connection initiation sequence from a non-privileged app with no network + * request pending from from WifiNetworkFactory when we're already connected to a different + * network. + * This simulates the connect sequence using the public + * {@link WifiManager#enableNetwork(int, boolean)} and ensures that we don't invoke + * {@link WifiNative#connectToNetwork(WifiConfiguration)}. + */ + @Test + public void triggerConnectWithNoNetworkRequestAndAlreadyConnectedButNonPrivilegedApp() + throws Exception { + // Simulate the first connection. + connect(); + + // Change the network score to remove the network request. + sendDefaultNetworkRequest(TEST_OUTSCORED_NETWORK_SCORE); + + when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(false); + + WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork(); + config.networkId = FRAMEWORK_NETWORK_ID + 1; + setupAndStartConnectSequence(config); + validateFailureConnectSequence(config); + verify(mWifiPermissionsUtil, times(2)).checkNetworkSettingsPermission(anyInt()); + } + @Test public void connectWithNoEnablePermission() throws Exception { initializeAndAddNetworkAndVerifySuccess(); |