Merge "Remove hostapd.conf before starting Tethering am: dc24ed7ffb am: 5ab7f53cbd am: 26c98abafc" into oc-mr1-dev-plus-aosp
diff --git a/service/java/com/android/server/wifi/WifiConnectivityManager.java b/service/java/com/android/server/wifi/WifiConnectivityManager.java
index 7e730c8..6bfce74 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.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 @@
                 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 a3054c9..9e12446 100644
--- a/service/java/com/android/server/wifi/WifiStateMachine.java
+++ b/service/java/com/android/server/wifi/WifiStateMachine.java
@@ -1321,7 +1321,7 @@
 
     /**
      * 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 @@
             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 @@
                 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 @@
                             // 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 @@
         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 @@
      * 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 6420fac..5fb7007 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.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 @@
         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 @@
         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 @@
         mWifiConnectivityManager.handleScreenStateChanged(true);
 
         verify(mWifiStateMachine, atLeastOnce()).startConnectToNetwork(
-                CANDIDATE_NETWORK_ID, CANDIDATE_BSSID);
+                CANDIDATE_NETWORK_ID, Process.WIFI_UID, CANDIDATE_BSSID);
     }
 
     /**
@@ -373,7 +376,7 @@
         mWifiConnectivityManager.handleScreenStateChanged(true);
 
         verify(mWifiStateMachine, atLeastOnce()).startConnectToNetwork(
-                CANDIDATE_NETWORK_ID, CANDIDATE_BSSID);
+                CANDIDATE_NETWORK_ID, Process.WIFI_UID, CANDIDATE_BSSID);
     }
 
     /**
@@ -400,7 +403,7 @@
         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 @@
 
         // 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 @@
 
         // 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 @@
 
         // 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 @@
 
         // 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 @@
 
         // 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 @@
         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 @@
                 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 @@
         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 @@
         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 @@
         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 @@
                 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 5b0f596..ecb4c95 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.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.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 @@
             (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 @@
                 mAlarmManager.getAlarmManager());
 
         when(context.getSystemService(Context.CONNECTIVITY_SERVICE)).thenReturn(
-                mock(ConnectivityManager.class));
+                mConnectivityManager);
 
         when(context.getOpPackageName()).thenReturn(OP_PACKAGE_NAME);
 
@@ -318,6 +324,7 @@
     HandlerThread mP2pThread;
     HandlerThread mSyncThread;
     AsyncChannel  mWsmAsyncChannel;
+    AsyncChannel  mNetworkFactoryChannel;
     TestAlarmManager mAlarmManager;
     MockWifiMonitor mWifiMonitor;
     TestLooper mLooper;
@@ -326,6 +333,7 @@
     FrameworkFacade mFrameworkFacade;
     IpManager.Callback mIpManagerCallback;
     PhoneStateListener mPhoneStateListener;
+    NetworkRequest mDefaultNetworkRequest;
 
     final ArgumentCaptor<SoftApManager.Listener> mSoftApManagerListenerCaptor =
                     ArgumentCaptor.forClass(SoftApManager.Listener.class);
@@ -361,6 +369,7 @@
     @Mock Clock mClock;
     @Mock ScanDetailCache mScanDetailCache;
     @Mock BaseWifiDiagnostics mWifiDiagnostics;
+    @Mock ConnectivityManager mConnectivityManager;
 
     public WifiStateMachineTest() throws Exception {
     }
@@ -449,15 +458,11 @@
             }
         }).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 @@
                 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 @@
             }
         };
 
-        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 @@
         mSyncThread = null;
         mWsmAsyncChannel = null;
         mWsm = null;
+        mNetworkFactoryChannel = null;
     }
 
     @Test
@@ -1043,22 +1084,81 @@
                 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 @@
         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();