wifi: bug fix of network selection when autoConnect == false

Ensure current network has the correct throughput prediction value even when autoConnect is disabled.

Test: atest com.android.server.wifi
Test: manual test to ensre the current network is still selected when
autoConnect is disabled.
Bug: 167409983

Change-Id: I9e6059ee057d0f17c1cdf7cafd98dceafaef7eb5
Merged-In: I9e6059ee057d0f17c1cdf7cafd98dceafaef7eb5
diff --git a/service/java/com/android/server/wifi/WifiNetworkSelector.java b/service/java/com/android/server/wifi/WifiNetworkSelector.java
index 50078b6..fbbcb31 100644
--- a/service/java/com/android/server/wifi/WifiNetworkSelector.java
+++ b/service/java/com/android/server/wifi/WifiNetworkSelector.java
@@ -462,6 +462,17 @@
         return validScanDetails;
     }
 
+    private ScanDetail findScanDetailForBssid(List<ScanDetail> scanDetails,
+            String currentBssid) {
+        for (ScanDetail scanDetail : scanDetails) {
+            ScanResult scanResult = scanDetail.getScanResult();
+            if (scanResult.BSSID.equals(currentBssid)) {
+                return scanDetail;
+            }
+        }
+        return null;
+    }
+
     private boolean isEnhancedOpenSupported() {
         if (mIsEnhancedOpenSupportedInitialized) {
             return mIsEnhancedOpenSupported;
@@ -790,6 +801,8 @@
             WifiCandidates.Key key = new WifiCandidates.Key(
                     ScanResultMatchInfo.fromWifiConfiguration(currentNetwork),
                     bssid, currentNetwork.networkId);
+            ScanDetail scanDetail = findScanDetailForBssid(mFilteredNetworks, currentBssid);
+            int predictedTputMbps = (scanDetail == null) ? 0 : predictThroughput(scanDetail);
             wifiCandidates.add(key, currentNetwork,
                     NetworkNominator.NOMINATOR_ID_CURRENT,
                     wifiInfo.getRssi(),
@@ -797,7 +810,7 @@
                     calculateLastSelectionWeight(currentNetwork.networkId),
                     WifiConfiguration.isMetered(currentNetwork, wifiInfo),
                     isFromCarrierOrPrivilegedApp(currentNetwork),
-                    0 /* Mbps */);
+                    predictedTputMbps);
         }
         for (NetworkNominator registeredNominator : mNominators) {
             localLog("About to run " + registeredNominator.getName() + " :");
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiNetworkSelectorTest.java b/tests/wifitests/src/com/android/server/wifi/WifiNetworkSelectorTest.java
index 0bd14a4..1507e9c 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiNetworkSelectorTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiNetworkSelectorTest.java
@@ -741,6 +741,56 @@
     }
 
     /**
+     * Wifi network selector stays with current network if current network is not nominated
+     * but has the higher score
+     */
+    @Test
+    public void includeCurrentNetworkWhenCurrentNetworkNotNominated() {
+        String[] ssids = {"\"test1\"", "\"test2\""};
+        String[] bssids = {"6c:f3:7f:ae:8c:f3", "6c:f3:7f:ae:8c:f4"};
+        int[] freqs = {2437, 5120};
+        String[] caps = {"[WPA2-EAP-CCMP][ESS]", "[WPA2-PSK][ESS]"};
+        int[] levels = {mThresholdMinimumRssi2G + 10, mThresholdMinimumRssi2G + 20};
+        int[] securities = {SECURITY_EAP, SECURITY_PSK};
+        // VHT cap IE
+        byte[] iesBytes = {(byte) 0x92, (byte) 0x01, (byte) 0x80, (byte) 0x33, (byte) 0xaa,
+                (byte) 0xff, (byte) 0x00, (byte) 0x00, (byte) 0xaa, (byte) 0xff, (byte) 0x00,
+                (byte) 0x00};
+        byte[][] iesByteStream = {iesBytes, iesBytes};
+        // Make a network selection to connect to test1.
+        ScanDetailsAndWifiConfigs scanDetailsAndConfigs =
+                WifiNetworkSelectorTestUtil.setupScanDetailsAndConfigStore(ssids, bssids,
+                        freqs, caps, levels, securities, mWifiConfigManager, mClock, iesByteStream);
+        List<ScanDetail> scanDetails = scanDetailsAndConfigs.getScanDetails();
+        assertEquals(2, scanDetails.size());
+        HashSet<String> blocklist = new HashSet<String>();
+        List<WifiCandidates.Candidate> candidates = mWifiNetworkSelector.getCandidatesFromScan(
+                scanDetails, blocklist, mWifiInfo, false, true, false);
+        WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(candidates);
+
+        when(mWifiInfo.getSupplicantState()).thenReturn(SupplicantState.COMPLETED);
+        when(mWifiInfo.getNetworkId()).thenReturn(0); // 0 is current network
+        when(mWifiInfo.getBSSID()).thenReturn(bssids[0]);
+        when(mWifiInfo.is24GHz()).thenReturn(true);
+        when(mWifiInfo.getScore()).thenReturn(ConnectedScore.WIFI_TRANSITION_SCORE);
+        when(mWifiInfo.is5GHz()).thenReturn(false);
+        when(mWifiInfo.getFrequency()).thenReturn(2400);
+        when(mWifiInfo.getRssi()).thenReturn(levels[0]);
+        when(mClock.getElapsedSinceBootMillis()).thenReturn(SystemClock.elapsedRealtime()
+                + WifiNetworkSelector.MINIMUM_NETWORK_SELECTION_INTERVAL_MS + 2000);
+
+        when(mThroughputPredictor.predictThroughput(any(), anyInt(), anyInt(), anyInt(),
+                anyInt(), anyInt(), anyInt(), anyInt(), anyBoolean())).thenReturn(100);
+        // Force to return 2nd network in the network nominator
+        mDummyNominator.setNetworkIndexToReturn(1);
+
+        candidates = mWifiNetworkSelector.getCandidatesFromScan(
+                scanDetails, blocklist, mWifiInfo, true, false, false);
+        assertEquals(2, candidates.size());
+        assertEquals(100, candidates.get(0).getPredictedThroughputMbps());
+    }
+
+    /**
      * If two qualified networks, test1 and test2, are in range when the user selects test2 over
      * test1, WifiNetworkSelector will override the NetworkSelector's choice to connect to test1
      * with test2.