Merge "Check roaming network for Fast Re-Authentication"
diff --git a/service/java/com/android/server/wifi/SupplicantStaIfaceHal.java b/service/java/com/android/server/wifi/SupplicantStaIfaceHal.java
index e9c20db..703c798 100644
--- a/service/java/com/android/server/wifi/SupplicantStaIfaceHal.java
+++ b/service/java/com/android/server/wifi/SupplicantStaIfaceHal.java
@@ -69,6 +69,7 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
@@ -404,7 +405,22 @@
     public boolean connectToNetwork(@NonNull WifiConfiguration config) {
         logd("connectToNetwork " + config.configKey());
         if (WifiConfigurationUtil.isSameNetwork(config, mCurrentNetworkLocalConfig)) {
-            logd("Network is already saved, will not trigger remove and add operation.");
+            String networkSelectionBSSID = config.getNetworkSelectionStatus()
+                    .getNetworkSelectionBSSID();
+            String networkSelectionBSSIDCurrent =
+                    mCurrentNetworkLocalConfig.getNetworkSelectionStatus()
+                            .getNetworkSelectionBSSID();
+            if (Objects.equals(networkSelectionBSSID, networkSelectionBSSIDCurrent)) {
+                logd("Network is already saved, will not trigger remove and add operation.");
+            } else {
+                logd("Network is already saved, but need to update BSSID.");
+                if (!setCurrentNetworkBssid(
+                        config.getNetworkSelectionStatus().getNetworkSelectionBSSID())) {
+                    loge("Failed to set current network BSSID.");
+                    return false;
+                }
+                mCurrentNetworkLocalConfig = new WifiConfiguration(config);
+            }
         } else {
             mCurrentNetworkRemoteHandle = null;
             mCurrentNetworkLocalConfig = null;
diff --git a/service/java/com/android/server/wifi/WifiConfigurationUtil.java b/service/java/com/android/server/wifi/WifiConfigurationUtil.java
index c726f49..bbfde46 100644
--- a/service/java/com/android/server/wifi/WifiConfigurationUtil.java
+++ b/service/java/com/android/server/wifi/WifiConfigurationUtil.java
@@ -236,9 +236,10 @@
 
     /**
      * Check if the provided two networks are the same.
+     * Note: This does not check if network selection BSSID's are the same.
      *
-     * @param config      Configuration corresponding to a network.
-     * @param config1      Configuration corresponding to another network.
+     * @param config  Configuration corresponding to a network.
+     * @param config1 Configuration corresponding to another network.
      *
      * @return true if |config| and |config1| are the same network.
      *         false otherwise.
@@ -256,13 +257,6 @@
         if (!Objects.equals(config.SSID, config1.SSID)) {
             return false;
         }
-        String networkSelectionBSSID = config.getNetworkSelectionStatus()
-                .getNetworkSelectionBSSID();
-        String networkSelectionBSSID1 = config1.getNetworkSelectionStatus()
-                .getNetworkSelectionBSSID();
-        if (!Objects.equals(networkSelectionBSSID, networkSelectionBSSID1)) {
-            return false;
-        }
         if (WifiConfigurationUtil.hasCredentialChanged(config, config1)) {
             return false;
         }
diff --git a/tests/wifitests/src/com/android/server/wifi/SupplicantStaIfaceHalTest.java b/tests/wifitests/src/com/android/server/wifi/SupplicantStaIfaceHalTest.java
index 2deef52..6c7b252 100644
--- a/tests/wifitests/src/com/android/server/wifi/SupplicantStaIfaceHalTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/SupplicantStaIfaceHalTest.java
@@ -54,6 +54,7 @@
 import android.net.wifi.WifiSsid;
 import android.os.IHwBinder;
 import android.os.RemoteException;
+import android.text.TextUtils;
 import android.util.SparseArray;
 
 import com.android.server.wifi.hotspot2.AnqpEvent;
@@ -488,6 +489,28 @@
                 .addNetwork(any(ISupplicantStaIface.addNetworkCallback.class));
     }
 
+    @Test
+    public void connectToNetworkWithSameNetworkButDifferentBssidUpdatesNetworkFromSupplicant()
+            throws Exception {
+        executeAndValidateInitializationSequence();
+        WifiConfiguration config = executeAndValidateConnectSequence(SUPPLICANT_NETWORK_ID, false);
+        String testBssid = "11:22:33:44:55:66";
+        when(mSupplicantStaNetworkMock.setBssid(eq(testBssid))).thenReturn(true);
+
+        // Reset mocks for mISupplicantStaIfaceMock because we finished the first connection.
+        reset(mISupplicantStaIfaceMock);
+        setupMocksForConnectSequence(true /*haveExistingNetwork*/);
+        // Change the BSSID and connect to the same network.
+        assertFalse(TextUtils.equals(
+                testBssid, config.getNetworkSelectionStatus().getNetworkSelectionBSSID()));
+        config.getNetworkSelectionStatus().setNetworkSelectionBSSID(testBssid);
+        assertTrue(mDut.connectToNetwork(config));
+        verify(mSupplicantStaNetworkMock).setBssid(eq(testBssid));
+        verify(mISupplicantStaIfaceMock, never()).removeNetwork(anyInt());
+        verify(mISupplicantStaIfaceMock, never())
+                .addNetwork(any(ISupplicantStaIface.addNetworkCallback.class));
+    }
+
     /**
      * Tests connection to a specified network failure due to network add.
      */
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiConfigurationUtilTest.java b/tests/wifitests/src/com/android/server/wifi/WifiConfigurationUtilTest.java
index 506db91..2b3de3f 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiConfigurationUtilTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiConfigurationUtilTest.java
@@ -43,6 +43,8 @@
     static final int OTHER_USER_ID = 11;
     static final String TEST_SSID = "test_ssid";
     static final String TEST_SSID_1 = "test_ssid_1";
+    static final String TEST_BSSID = "aa:aa:11:22:cc:dd";
+    static final String TEST_BSSID_1 = "11:22:11:22:cc:dd";
     static final List<UserInfo> PROFILES = Arrays.asList(
             new UserInfo(CURRENT_USER_ID, "owner", 0),
             new UserInfo(CURRENT_USER_MANAGED_PROFILE_USER_ID, "managed profile", 0));
@@ -252,6 +254,19 @@
     }
 
     /**
+     * Verify that WifiConfigurationUtil.isSameNetwork returns true when two WifiConfiguration
+     * objects have the same parameters but different network selection BSSID's.
+     */
+    @Test
+    public void testIsSameNetworkReturnsTrueOnSameNetworkWithDifferentBSSID() {
+        WifiConfiguration network = WifiConfigurationTestUtil.createPskNetwork(TEST_SSID);
+        network.getNetworkSelectionStatus().setNetworkSelectionBSSID(TEST_BSSID);
+        WifiConfiguration network1 = WifiConfigurationTestUtil.createPskNetwork(TEST_SSID);
+        network1.getNetworkSelectionStatus().setNetworkSelectionBSSID(TEST_BSSID_1);
+        assertTrue(WifiConfigurationUtil.isSameNetwork(network, network1));
+    }
+
+    /**
      * Verify that WifiConfigurationUtil.isSameNetwork returns false when two WifiConfiguration
      * objects have the different SSIDs.
      */