Merge "Use EUI64 IPv6 link-local address generation when randomizing MAC" into rvc-dev
diff --git a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/SavedNetworkTracker.java b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/SavedNetworkTracker.java
index c6b5454..df931f8 100644
--- a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/SavedNetworkTracker.java
+++ b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/SavedNetworkTracker.java
@@ -143,7 +143,6 @@
     @WorkerThread
     @Override
     protected void handleScanResultsAvailableAction(@Nullable Intent intent) {
-        //TODO(b/70983952): Add PasspointWifiEntry and update their scans here.
         checkNotNull(intent, "Intent cannot be null!");
         conditionallyUpdateScanResults(intent.getBooleanExtra(WifiManager.EXTRA_RESULTS_UPDATED,
                 true /* defaultValue */));
@@ -158,7 +157,7 @@
 
         final WifiConfiguration config =
                 (WifiConfiguration) intent.getExtra(WifiManager.EXTRA_WIFI_CONFIGURATION);
-        if (config != null) {
+        if (config != null && !config.isPasspoint()) {
             updateStandardWifiEntryConfig(
                     config, (Integer) intent.getExtra(WifiManager.EXTRA_CHANGE_REASON));
         } else {
diff --git a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/WifiPickerTracker.java b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/WifiPickerTracker.java
index 734779a..170dd4e 100644
--- a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/WifiPickerTracker.java
+++ b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/WifiPickerTracker.java
@@ -218,7 +218,6 @@
     @WorkerThread
     @Override
     protected void handleConfiguredNetworksChangedAction(@NonNull Intent intent) {
-        // TODO(b/70983952): Handle Passpoint configurations here
         checkNotNull(intent, "Intent cannot be null!");
 
         final WifiConfiguration config =
diff --git a/service/Android.bp b/service/Android.bp
index e721f8c..d7c16df 100644
--- a/service/Android.bp
+++ b/service/Android.bp
@@ -62,7 +62,7 @@
         // need pre-jarjar symbols so that wifi-service can reference the original class names at
         // compile time
         "framework-wifi-pre-jarjar",
-        "framework-statsd-stubs-module_libs_api",
+        "framework-statsd.stubs.module_lib",
         "unsupportedappusage",
     ],
 
diff --git a/service/java/com/android/server/wifi/WifiConnectivityManager.java b/service/java/com/android/server/wifi/WifiConnectivityManager.java
index ad5a8f2..2ce0bc0 100644
--- a/service/java/com/android/server/wifi/WifiConnectivityManager.java
+++ b/service/java/com/android/server/wifi/WifiConnectivityManager.java
@@ -1847,6 +1847,7 @@
         if (!mWifiEnabled) return;
         localLog("forceConnectivityScan in request of " + workSource);
 
+        clearConnectionAttemptTimeStamps();
         mWaitForFullBandScanResults = true;
         startForcedSingleScan(true, workSource);
     }
diff --git a/service/java/com/android/server/wifi/WifiHealthMonitor.java b/service/java/com/android/server/wifi/WifiHealthMonitor.java
index 27167dc..8ab3a74 100644
--- a/service/java/com/android/server/wifi/WifiHealthMonitor.java
+++ b/service/java/com/android/server/wifi/WifiHealthMonitor.java
@@ -326,6 +326,15 @@
         pw.println("WifiHealthMonitor - Log End ----");
     }
 
+    /**
+     * Get current wifi mainline module long version code
+     * @Return a non-zero value if version code is available, 0 otherwise.
+     */
+    public long getWifiStackVersion() {
+        WifiSoftwareBuildInfo currentBuild = getWifiSystemInfoStats().getCurrSoftwareBuildInfo();
+        return (currentBuild == null) ? 0 : currentBuild.getWifiStackVersion();
+    }
+
     private synchronized void dailyDetectionHandler() {
         logd("Run daily detection");
         // Clear daily detection result
@@ -533,12 +542,12 @@
             return null;
         }
         PackageManager packageManager = mContext.getPackageManager();
-        int wifiStackVersion = 0;
+        long wifiStackVersion = 0;
         try {
             wifiStackVersion = packageManager.getPackageInfo(
-                    WIFI_APK_PACKAGE_NAME, PackageManager.MATCH_APEX).versionCode;
+                    WIFI_APK_PACKAGE_NAME, PackageManager.MATCH_APEX).getLongVersionCode();
         } catch (PackageManager.NameNotFoundException e) {
-            Log.e(TAG, " hit PackageManager nameNotFoundException");
+            Log.e(TAG, " Hit PackageManager exception", e);
         }
         String osBuildVersion = replaceNullByEmptyString(Build.DISPLAY);
         if (mWifiNative == null) {
@@ -629,10 +638,10 @@
      */
     final class WifiSoftwareBuildInfo {
         private String mOsBuildVersion;
-        private int mWifiStackVersion;
+        private long mWifiStackVersion;
         private String mWifiDriverVersion;
         private String mWifiFirmwareVersion;
-        WifiSoftwareBuildInfo(@NonNull String osBuildVersion, int wifiStackVersion,
+        WifiSoftwareBuildInfo(@NonNull String osBuildVersion, long wifiStackVersion,
                 @NonNull String wifiDriverVersion, @NonNull String wifiFirmwareVersion) {
             mOsBuildVersion = osBuildVersion;
             mWifiStackVersion = wifiStackVersion;
@@ -648,7 +657,7 @@
         String getOsBuildVersion() {
             return mOsBuildVersion;
         }
-        int getWifiStackVersion() {
+        long getWifiStackVersion() {
             return mWifiStackVersion;
         }
         String getWifiDriverVersion() {
@@ -842,7 +851,7 @@
                 @NonNull SoftwareBuildInfo softwareBuildInfo) {
             String osBuildVersion = softwareBuildInfo.hasOsBuildVersion()
                     ? softwareBuildInfo.getOsBuildVersion() : "NA";
-            int stackVersion = softwareBuildInfo.hasWifiStackVersion()
+            long stackVersion = softwareBuildInfo.hasWifiStackVersion()
                     ? softwareBuildInfo.getWifiStackVersion() : 0;
             String driverVersion = softwareBuildInfo.hasWifiDriverVersion()
                     ? softwareBuildInfo.getWifiDriverVersion() : "NA";
diff --git a/service/java/com/android/server/wifi/WifiMetrics.java b/service/java/com/android/server/wifi/WifiMetrics.java
index dbd5325..e23779e 100644
--- a/service/java/com/android/server/wifi/WifiMetrics.java
+++ b/service/java/com/android/server/wifi/WifiMetrics.java
@@ -4359,8 +4359,9 @@
             initialPartialScanStats.failedScanChannelCountHistogram =
                     mInitPartialScanFailureHistogram.toProto();
             mWifiLogProto.initPartialScanStats = initialPartialScanStats;
-
             mWifiLogProto.carrierWifiMetrics = mCarrierWifiMetrics.toProto();
+            mWifiLogProto.mainlineModuleVersion = mWifiHealthMonitor.getWifiStackVersion();
+
         }
     }
 
diff --git a/service/java/com/android/server/wifi/WifiShellCommand.java b/service/java/com/android/server/wifi/WifiShellCommand.java
index 842493c..41933ab 100644
--- a/service/java/com/android/server/wifi/WifiShellCommand.java
+++ b/service/java/com/android/server/wifi/WifiShellCommand.java
@@ -372,10 +372,10 @@
                     if (ApConfigUtil.isWpa3SaeSupported(mContext)) {
                         pw.println("wifi_softap_wpa3_sae_supported");
                     }
-                    break;
+                    return 0;
                 case "settings-reset":
                     mWifiService.factoryReset(SHELL_PACKAGE_NAME);
-                    break;
+                    return 0;
                 case "list-scan-results":
                     List<ScanResult> scanResults =
                             mWifiService.getScanResults(SHELL_PACKAGE_NAME, null);
@@ -385,10 +385,10 @@
                         ScanResultUtil.dumpScanResults(pw, scanResults,
                                 SystemClock.elapsedRealtime());
                     }
-                    break;
+                    return 0;
                 case "start-scan":
                     mWifiService.startScan(SHELL_PACKAGE_NAME, null);
-                    break;
+                    return 0;
                 case "list-networks":
                     ParceledListSlice<WifiConfiguration> networks =
                             mWifiService.getConfiguredNetworks(SHELL_PACKAGE_NAME, null);
@@ -414,7 +414,7 @@
                                     securityType));
                         }
                     }
-                    break;
+                    return 0;
                 case "connect-network": {
                     CountDownLatch countDownLatch = new CountDownLatch(1);
                     IActionListener.Stub actionListener = new IActionListener.Stub() {
@@ -436,7 +436,7 @@
                     // wait for status.
                     countDownLatch.await(500, TimeUnit.MILLISECONDS);
                     setAutoJoin(pw, config.SSID, config.allowAutojoin);
-                    break;
+                    return 0;
                 }
                 case "add-network": {
                     CountDownLatch countDownLatch = new CountDownLatch(1);
@@ -459,7 +459,7 @@
                     // wait for status.
                     countDownLatch.await(500, TimeUnit.MILLISECONDS);
                     setAutoJoin(pw, config.SSID, config.allowAutojoin);
-                    break;
+                    return 0;
                 }
                 case "forget-network": {
                     String networkId = getNextArgRequired();
@@ -482,21 +482,21 @@
                             actionListener.hashCode());
                     // wait for status.
                     countDownLatch.await(500, TimeUnit.MILLISECONDS);
-                    break;
+                    return 0;
                 }
                 case "status":
                     printStatus(pw);
-                    break;
+                    return 0;
                 case "set-verbose-logging": {
                     boolean enabled = getNextArgRequiredTrueOrFalse("enabled", "disabled");
                     mWifiService.enableVerboseLogging(enabled ? 1 : 0);
-                    break;
+                    return 0;
                 }
                 case "add-suggestion": {
                     WifiNetworkSuggestion suggestion = buildSuggestion(pw);
                     mWifiService.addNetworkSuggestions(
                             Arrays.asList(suggestion), SHELL_PACKAGE_NAME, null);
-                    break;
+                    return 0;
                 }
                 case "remove-suggestion": {
                     String ssid = getNextArgRequired();
@@ -512,12 +512,12 @@
                     }
                     mWifiService.removeNetworkSuggestions(
                             Arrays.asList(suggestion), SHELL_PACKAGE_NAME);
-                    break;
+                    return 0;
                 }
                 case "remove-all-suggestions":
                     mWifiService.removeNetworkSuggestions(
                             Collections.emptyList(), SHELL_PACKAGE_NAME);
-                    break;
+                    return 0;
                 case "list-suggestions": {
                     List<WifiNetworkSuggestion> suggestions =
                             mWifiService.getNetworkSuggestions(SHELL_PACKAGE_NAME);
@@ -548,7 +548,7 @@
                                     securityType));
                         }
                     }
-                    break;
+                    return 0;
                 }
                 case "add-request": {
                     NetworkRequest networkRequest = buildNetworkRequest(pw);
@@ -558,7 +558,7 @@
                     mConnectivityManager.requestNetwork(networkRequest, networkCallback);
                     String ssid = getAllArgs()[1];
                     sActiveRequests.put(ssid, Pair.create(networkRequest, networkCallback));
-                    break;
+                    return 0;
                 }
                 case "remove-request": {
                     String ssid = getNextArgRequired();
@@ -570,7 +570,7 @@
                     }
                     pw.println("Removing request: " + nrAndNc.first);
                     mConnectivityManager.unregisterNetworkCallback(nrAndNc.second);
-                    break;
+                    return 0;
                 }
                 case "remove-all-requests":
                     if (sActiveRequests.isEmpty()) {
@@ -583,7 +583,7 @@
                         mConnectivityManager.unregisterNetworkCallback(nrAndNc.second);
                     }
                     sActiveRequests.clear();
-                    break;
+                    return 0;
                 case "list-requests":
                     if (sActiveRequests.isEmpty()) {
                         pw.println("No active requests");
@@ -596,7 +596,7 @@
                                     entry.getKey(), entry.getValue().first));
                         }
                     }
-                    break;
+                    return 0;
                 case "network-requests-set-user-approved": {
                     String packageName = getNextArgRequired();
                     boolean approved = getNextArgRequiredTrueOrFalse("yes", "no");
@@ -667,11 +667,12 @@
             }
         } catch (IllegalArgumentException e) {
             pw.println("Invalid args for " + cmd + ": " + e);
+            return -1;
         } catch (Exception e) {
             pw.println("Exception while executing WifiShellCommand: ");
             e.printStackTrace(pw);
+            return -1;
         }
-        return -1;
     }
 
     private boolean getNextArgRequiredTrueOrFalse(String trueString, String falseString)
diff --git a/service/proto/src/metrics.proto b/service/proto/src/metrics.proto
index eaea734..349543d 100644
--- a/service/proto/src/metrics.proto
+++ b/service/proto/src/metrics.proto
@@ -712,6 +712,9 @@
 
   // Metrics about carrier wifi network.
   optional CarrierWifiMetrics carrier_wifi_metrics = 200;
+
+  // Long version code of wifi mainline module, 0 means not available.
+  optional int64 mainline_module_version = 201;
 }
 
 // Information that gets logged for every WiFi connection.
diff --git a/service/proto/src/scorecard.proto b/service/proto/src/scorecard.proto
index ad5822c..d351c56 100644
--- a/service/proto/src/scorecard.proto
+++ b/service/proto/src/scorecard.proto
@@ -146,7 +146,7 @@
   // Android OS build version
   optional string os_build_version = 1;
   // WiFi stack APK version, 0 means not available.
-  optional int32 wifi_stack_version = 2;
+  optional int64 wifi_stack_version = 2;
   // WiFi driver version
   optional string wifi_driver_version = 3;
   // WiFi firmware version
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiConnectivityManagerTest.java b/tests/wifitests/src/com/android/server/wifi/WifiConnectivityManagerTest.java
index 7bf21fb..ba1c4f9 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiConnectivityManagerTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiConnectivityManagerTest.java
@@ -607,6 +607,50 @@
     }
 
     /**
+     * Multiple back to back connection attempts after a force connectivity scan should not be rate
+     * limited.
+     *
+     * Expected behavior: WifiConnectivityManager calls ClientModeImpl.startConnectToNetwork()
+     * with the expected candidate network ID and BSSID for only the expected number of times within
+     * the given interval.
+     */
+    @Test
+    public void connectionAttemptNotRateLimitedWhenScreenOffForceConnectivityScan() {
+        int maxAttemptRate = WifiConnectivityManager.MAX_CONNECTION_ATTEMPTS_RATE;
+        int timeInterval = WifiConnectivityManager.MAX_CONNECTION_ATTEMPTS_TIME_INTERVAL_MS;
+        int numAttempts = 0;
+        int connectionAttemptIntervals = timeInterval / maxAttemptRate;
+
+        mWifiConnectivityManager.handleScreenStateChanged(false);
+
+        // First attempt the max rate number of connections within the rate interval.
+        long currentTimeStamp = 0;
+        for (int attempt = 0; attempt < maxAttemptRate; attempt++) {
+            currentTimeStamp += connectionAttemptIntervals;
+            when(mClock.getElapsedSinceBootMillis()).thenReturn(currentTimeStamp);
+            // Set WiFi to disconnected state to trigger PNO scan
+            mWifiConnectivityManager.handleConnectionStateChanged(
+                    WifiConnectivityManager.WIFI_STATE_DISCONNECTED);
+            numAttempts++;
+        }
+
+        mWifiConnectivityManager.forceConnectivityScan(new WorkSource());
+
+        for (int attempt = 0; attempt < maxAttemptRate; attempt++) {
+            currentTimeStamp += connectionAttemptIntervals;
+            when(mClock.getElapsedSinceBootMillis()).thenReturn(currentTimeStamp);
+            // Set WiFi to disconnected state to trigger PNO scan
+            mWifiConnectivityManager.handleConnectionStateChanged(
+                    WifiConnectivityManager.WIFI_STATE_DISCONNECTED);
+            numAttempts++;
+        }
+
+        // Verify that all the connection attempts went through
+        verify(mClientModeImpl, times(numAttempts)).startConnectToNetwork(
+                CANDIDATE_NETWORK_ID, Process.WIFI_UID, CANDIDATE_BSSID);
+    }
+
+    /**
      * Multiple back to back connection attempts after a user selection should not be rate limited.
      *
      * Expected behavior: WifiConnectivityManager calls ClientModeImpl.startConnectToNetwork()
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiHealthMonitorTest.java b/tests/wifitests/src/com/android/server/wifi/WifiHealthMonitorTest.java
index 4e0b5b7..264fe90 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiHealthMonitorTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiHealthMonitorTest.java
@@ -110,6 +110,7 @@
     private WifiConfiguration mWifiConfig;
     private String mDriverVersion;
     private String mFirmwareVersion;
+    private static final long MODULE_VERSION = 1L;
     private TestAlarmManager mAlarmManager;
     private TestLooper mLooper = new TestLooper();
     private List<WifiConfiguration> mConfiguredNetworks;
@@ -152,7 +153,7 @@
 
         mDriverVersion = "build 1.1";
         mFirmwareVersion = "HW 1.1";
-        mPackageInfo.versionCode = 1;
+        when(mPackageInfo.getLongVersionCode()).thenReturn(MODULE_VERSION);
         when(mContext.getPackageName()).thenReturn("WifiAPK");
         when(mPackageManager.getPackageInfo(anyString(), anyInt())).thenReturn(mPackageInfo);
         when(mContext.getPackageManager()).thenReturn(mPackageManager);
@@ -310,6 +311,7 @@
         // trigger extractCurrentSoftwareBuildInfo() call to update currSoftwareBuildInfo
         mWifiHealthMonitor.installMemoryStoreSetUpDetectionAlarm(mMemoryStore);
         mWifiHealthMonitor.setWifiEnabled(true);
+        assertEquals(0, mWifiHealthMonitor.getWifiStackVersion());
         millisecondsPass(5000);
         mWifiScanner.startScan(mScanSettings, mScanListener);
         mAlarmManager.dispatch(WifiHealthMonitor.POST_BOOT_DETECTION_TIMER_TAG);
@@ -365,6 +367,7 @@
                 .getWifiFirmwareVersion());
         assertEquals(mFirmwareVersion, wifiSystemInfoStats.getPrevSoftwareBuildInfo()
                 .getWifiFirmwareVersion());
+        assertEquals(MODULE_VERSION, mWifiHealthMonitor.getWifiStackVersion());
 
         // Check write
         String writtenHex = hexStringFromByteArray(mBlobs.get(mKeys.size() - 1));
@@ -395,8 +398,7 @@
         SystemInfoStats systemInfoStats = SystemInfoStats.parseFrom(serialized);
         WifiSoftwareBuildInfo currSoftwareBuildInfoFromMemory = wifiSystemInfoStats
                 .fromSoftwareBuildInfo(systemInfoStats.getCurrSoftwareBuildInfo());
-        assertEquals(mPackageInfo.versionCode,
-                currSoftwareBuildInfoFromMemory.getWifiStackVersion());
+        assertEquals(MODULE_VERSION, currSoftwareBuildInfoFromMemory.getWifiStackVersion());
         assertEquals(mDriverVersion, currSoftwareBuildInfoFromMemory.getWifiDriverVersion());
         assertEquals(mFirmwareVersion, currSoftwareBuildInfoFromMemory.getWifiFirmwareVersion());
         assertEquals(Build.DISPLAY, currSoftwareBuildInfoFromMemory.getOsBuildVersion());
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java b/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java
index fcaee05..ca5ae26 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java
@@ -441,6 +441,7 @@
     private static final int NUM_NETWORK_SUFFICIENT_RECENT_STATS_ONLY = 4;
     private static final int NUM_NETWORK_SUFFICIENT_RECENT_PREV_STATS = 5;
     private static final int NUM_BSSID_SELECTION_DIFFERENT_BETWEEN_FRAMEWORK_FIRMWARE = 3;
+    private static final long WIFI_MAINLINE_MODULE_VERSION = 123456L;
 
     /** Number of notifications per "Connect to Network" notification type. */
     private static final int[] NUM_CONNECT_TO_NETWORK_NOTIFICATIONS = {0, 10, 20, 30, 40};
@@ -1010,6 +1011,7 @@
         metrics.numNetworkSufficientRecentStatsOnly = NUM_NETWORK_SUFFICIENT_RECENT_STATS_ONLY;
         metrics.numNetworkSufficientRecentPrevStats = NUM_NETWORK_SUFFICIENT_RECENT_PREV_STATS;
         when(mWifiHealthMonitor.buildProto()).thenReturn(metrics);
+        when(mWifiHealthMonitor.getWifiStackVersion()).thenReturn(WIFI_MAINLINE_MODULE_VERSION);
     }
 
     private void addSoftApEventsToMetrics() {
@@ -1412,6 +1414,7 @@
                 mDecodedProto.numConnectRequestWithFilsAkm);
         assertEquals(NUM_L2_CONNECTION_THROUGH_FILS_AUTHENTICATION,
                 mDecodedProto.numL2ConnectionThroughFilsAuthentication);
+        assertEquals(WIFI_MAINLINE_MODULE_VERSION, mDecodedProto.mainlineModuleVersion);
 
     }