Snap for 7915200 from 84707ce57faf77f06029a844a600c6eb2f872c7c to mainline-ipsec-release

Change-Id: I8248f1ed953886ee55b9e4c4ff420ffd2203184a
diff --git a/OsuLogin/src/com/android/hotspot2/osulogin/OsuLoginActivity.java b/OsuLogin/src/com/android/hotspot2/osulogin/OsuLoginActivity.java
index 9797846..8450b7b 100644
--- a/OsuLogin/src/com/android/hotspot2/osulogin/OsuLoginActivity.java
+++ b/OsuLogin/src/com/android/hotspot2/osulogin/OsuLoginActivity.java
@@ -25,11 +25,13 @@
 import android.net.Network;
 import android.net.NetworkCapabilities;
 import android.net.NetworkRequest;
+import android.net.http.SslError;
 import android.net.wifi.WifiManager;
 import android.os.Bundle;
 import android.util.Log;
 import android.view.KeyEvent;
 import android.view.View;
+import android.webkit.SslErrorHandler;
 import android.webkit.WebChromeClient;
 import android.webkit.WebResourceError;
 import android.webkit.WebResourceRequest;
@@ -268,6 +270,7 @@
             if (request.getUrl().toString().startsWith("http://127.0.0.1")) {
                 mRedirectResponseReceived = true;
                 view.stopLoading();
+                Log.d(TAG, "Redirect received");
             }
 
             if (request.isForMainFrame()) {
@@ -277,5 +280,13 @@
                 Log.e(TAG, "onReceived Error for MainFrame: " + error.getErrorCode());
             }
         }
+
+        @Override
+        public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
+            Log.e(TAG, String.format("SSL error: %d, url: %s, certificate: %s",
+                    error.getPrimaryError(), error.getUrl(), error.getCertificate()));
+            mPageError = true;
+            handler.cancel();
+        }
     }
 }
diff --git a/framework/api/current.txt b/framework/api/current.txt
index c5d9c2f..e8db727 100644
--- a/framework/api/current.txt
+++ b/framework/api/current.txt
@@ -297,7 +297,7 @@
     method @Nullable public java.util.List<android.net.wifi.ScanResult.InformationElement> getInformationElements();
     method @Deprecated public int getIpAddress();
     method public int getLinkSpeed();
-    method @RequiresPermission(allOf={android.Manifest.permission.LOCAL_MAC_ADDRESS, android.Manifest.permission.ACCESS_FINE_LOCATION}) public String getMacAddress();
+    method public String getMacAddress();
     method public int getMaxSupportedRxLinkSpeedMbps();
     method public int getMaxSupportedTxLinkSpeedMbps();
     method public int getNetworkId();
@@ -343,7 +343,7 @@
 
   public class WifiManager {
     method @Deprecated public int addNetwork(android.net.wifi.WifiConfiguration);
-    method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.NETWORK_MANAGED_PROVISIONING}) public android.net.wifi.WifiManager.AddNetworkResult addNetworkPrivileged(@NonNull android.net.wifi.WifiConfiguration);
+    method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.NETWORK_MANAGED_PROVISIONING}, conditional=true) public android.net.wifi.WifiManager.AddNetworkResult addNetworkPrivileged(@NonNull android.net.wifi.WifiConfiguration);
     method @RequiresPermission(android.Manifest.permission.CHANGE_WIFI_STATE) public int addNetworkSuggestions(@NonNull java.util.List<android.net.wifi.WifiNetworkSuggestion>);
     method public void addOrUpdatePasspointConfiguration(android.net.wifi.hotspot2.PasspointConfiguration);
     method @RequiresPermission(allOf={android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.ACCESS_WIFI_STATE}) public void addSuggestionConnectionStatusListener(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.WifiManager.SuggestionConnectionStatusListener);
@@ -358,7 +358,7 @@
     method @Deprecated public boolean disableNetwork(int);
     method @Deprecated public boolean disconnect();
     method @Deprecated public boolean enableNetwork(int, boolean);
-    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_MANAGED_PROVISIONING, android.Manifest.permission.NETWORK_CARRIER_PROVISIONING}) public void flushPasspointAnqpCache();
+    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_MANAGED_PROVISIONING, android.Manifest.permission.NETWORK_CARRIER_PROVISIONING}, conditional=true) public void flushPasspointAnqpCache();
     method @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public java.util.List<android.net.wifi.WifiConfiguration> getCallerConfiguredNetworks();
     method @Deprecated @RequiresPermission(allOf={android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.ACCESS_WIFI_STATE}) public java.util.List<android.net.wifi.WifiConfiguration> getConfiguredNetworks();
     method @Deprecated public android.net.wifi.WifiInfo getConnectionInfo();
@@ -366,7 +366,7 @@
     method public int getMaxNumberOfNetworkSuggestionsPerApp();
     method @IntRange(from=0) public int getMaxSignalLevel();
     method @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public java.util.List<android.net.wifi.WifiNetworkSuggestion> getNetworkSuggestions();
-    method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public java.util.List<android.net.wifi.hotspot2.PasspointConfiguration> getPasspointConfigurations();
+    method @Deprecated public java.util.List<android.net.wifi.hotspot2.PasspointConfiguration> getPasspointConfigurations();
     method public java.util.List<android.net.wifi.ScanResult> getScanResults();
     method public int getWifiState();
     method public boolean is24GHzBandSupported();
@@ -408,7 +408,7 @@
     method @Deprecated public boolean removeNetwork(int);
     method @RequiresPermission(android.Manifest.permission.CHANGE_WIFI_STATE) public int removeNetworkSuggestions(@NonNull java.util.List<android.net.wifi.WifiNetworkSuggestion>);
     method @RequiresPermission(android.Manifest.permission.CHANGE_WIFI_STATE) public boolean removeNonCallerConfiguredNetworks();
-    method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_CARRIER_PROVISIONING}) public void removePasspointConfiguration(String);
+    method @Deprecated public void removePasspointConfiguration(String);
     method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public void removeSuggestionConnectionStatusListener(@NonNull android.net.wifi.WifiManager.SuggestionConnectionStatusListener);
     method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public void removeSuggestionUserApprovalStatusListener(@NonNull android.net.wifi.WifiManager.SuggestionUserApprovalStatusListener);
     method @Deprecated public boolean saveConfiguration();
diff --git a/framework/java/android/net/wifi/WifiInfo.java b/framework/java/android/net/wifi/WifiInfo.java
index 8b99294..ead4361 100644
--- a/framework/java/android/net/wifi/WifiInfo.java
+++ b/framework/java/android/net/wifi/WifiInfo.java
@@ -845,11 +845,10 @@
      * Returns the MAC address used for this connection.
      * @return MAC address of the connection or {@code "02:00:00:00:00:00"} if the caller has
      * insufficient permission.
+     *
+     * Requires {@code android.Manifest.permission#LOCAL_MAC_ADDRESS} and
+     * {@link android.Manifest.permission#ACCESS_FINE_LOCATION}.
      */
-    @RequiresPermission(allOf = {
-            Manifest.permission.LOCAL_MAC_ADDRESS,
-            Manifest.permission.ACCESS_FINE_LOCATION
-    })
     public String getMacAddress() {
         return mMacAddress;
     }
diff --git a/framework/java/android/net/wifi/WifiManager.java b/framework/java/android/net/wifi/WifiManager.java
index da17f56..0a31915 100644
--- a/framework/java/android/net/wifi/WifiManager.java
+++ b/framework/java/android/net/wifi/WifiManager.java
@@ -1714,7 +1714,7 @@
             android.Manifest.permission.NETWORK_STACK,
             android.Manifest.permission.NETWORK_SETUP_WIZARD,
             android.Manifest.permission.NETWORK_MANAGED_PROVISIONING
-    })
+            }, conditional = true)
     @NonNull
     public AddNetworkResult addNetworkPrivileged(@NonNull WifiConfiguration config) {
         if (config == null) throw new IllegalArgumentException("config cannot be null");
@@ -2336,12 +2336,11 @@
      * @throws IllegalArgumentException if no configuration is associated with the given FQDN or
      *                                  Passpoint is not enabled on the device.
      * @deprecated This will be non-functional in a future release.
+     * <br>
+     * Requires {@code android.Manifest.permission.NETWORK_SETTINGS} or
+     * {@code android.Manifest.permission.NETWORK_CARRIER_PROVISIONING}.
      */
     @Deprecated
-    @RequiresPermission(anyOf = {
-            android.Manifest.permission.NETWORK_SETTINGS,
-            android.Manifest.permission.NETWORK_CARRIER_PROVISIONING
-    })
     public void removePasspointConfiguration(String fqdn) {
         try {
             if (!mService.removePasspointConfiguration(fqdn, mContext.getOpPackageName())) {
@@ -2359,12 +2358,11 @@
      *
      * @return A list of {@link PasspointConfiguration} added by the caller
      * @deprecated This will be non-functional in a future release.
+     * <br>
+     * Requires {@code android.Manifest.permission.NETWORK_SETTINGS} or
+     * {@code android.Manifest.permission.NETWORK_SETUP_WIZARD}.
      */
     @Deprecated
-    @RequiresPermission(anyOf = {
-            android.Manifest.permission.NETWORK_SETTINGS,
-            android.Manifest.permission.NETWORK_SETUP_WIZARD
-    })
     public List<PasspointConfiguration> getPasspointConfigurations() {
         try {
             return mService.getPasspointConfigurations(mContext.getOpPackageName());
@@ -8062,7 +8060,7 @@
             android.Manifest.permission.NETWORK_SETTINGS,
             android.Manifest.permission.NETWORK_MANAGED_PROVISIONING,
             android.Manifest.permission.NETWORK_CARRIER_PROVISIONING
-            })
+            }, conditional = true)
     public void flushPasspointAnqpCache() {
         try {
             mService.flushPasspointAnqpCache(mContext.getOpPackageName());
diff --git a/service/java/com/android/server/wifi/ActiveModeWarden.java b/service/java/com/android/server/wifi/ActiveModeWarden.java
index b2e1ef5..b882eb2 100644
--- a/service/java/com/android/server/wifi/ActiveModeWarden.java
+++ b/service/java/com/android/server/wifi/ActiveModeWarden.java
@@ -1016,6 +1016,12 @@
         }
     }
 
+    private void stopSecondaryClientModeManagers() {
+        stopAllClientModeManagersInRole(ROLE_CLIENT_LOCAL_ONLY);
+        stopAllClientModeManagersInRole(ROLE_CLIENT_SECONDARY_TRANSIENT);
+        stopAllClientModeManagersInRole(ROLE_CLIENT_SECONDARY_LONG_LIVED);
+    }
+
     /**
      * Method to switch all client mode manager mode of operation (from ScanOnly To Connect &
      * vice-versa) based on the toggle state.
@@ -1762,6 +1768,14 @@
         private void handleStaToggleChangeInEnabledState(WorkSource requestorWs) {
             if (shouldEnableSta()) {
                 if (hasAnyClientModeManager()) {
+                    if (!mSettingsStore.isWifiToggleEnabled()) {
+                        // Wifi is turned off, so we should stop all the secondary CMMs which are
+                        // currently all for connectivity purpose. It's important to stops the
+                        // secondary CMMs before switch state of the primary CMM so features using
+                        // those secondary CMMs knows to abort properly, and won't react in strange
+                        // ways to the primary switching to scan only mode later.
+                        stopSecondaryClientModeManagers();
+                    }
                     switchAllPrimaryOrScanOnlyClientModeManagers();
                 } else {
                     startPrimaryOrScanOnlyClientModeManager(requestorWs);
diff --git a/service/java/com/android/server/wifi/ClientModeImpl.java b/service/java/com/android/server/wifi/ClientModeImpl.java
index ee5923c..1baca3b 100644
--- a/service/java/com/android/server/wifi/ClientModeImpl.java
+++ b/service/java/com/android/server/wifi/ClientModeImpl.java
@@ -4882,7 +4882,7 @@
             if (mVcnManager == null && SdkLevel.isAtLeastS()) {
                 mVcnManager = mContext.getSystemService(VcnManager.class);
             }
-            if (mVcnManager != null) {
+            if (mVcnManager != null && mVcnPolicyChangeListener == null) {
                 mVcnPolicyChangeListener = new WifiVcnNetworkPolicyChangeListener();
                 mVcnManager.addVcnNetworkPolicyChangeListener(new HandlerExecutor(getHandler()),
                         mVcnPolicyChangeListener);
@@ -5154,7 +5154,7 @@
                             mWifiNative.removeNetworkCachedData(mLastNetworkId);
                             // remove network so that supplicant's PMKSA cache is cleared
                             mWifiNative.removeAllNetworks(mInterfaceName);
-                            if (isPrimary()) {
+                            if (isPrimary() && !mWifiCarrierInfoManager.isSimReady(mLastSubId)) {
                                 mSimRequiredNotifier.showSimRequiredNotification(
                                         config, mLastSimBasedConnectionCarrierName);
                             }
diff --git a/service/java/com/android/server/wifi/HalDeviceManager.java b/service/java/com/android/server/wifi/HalDeviceManager.java
index 638d661..b664c1f 100644
--- a/service/java/com/android/server/wifi/HalDeviceManager.java
+++ b/service/java/com/android/server/wifi/HalDeviceManager.java
@@ -1012,7 +1012,7 @@
                                 @Override
                                 public void onChipReconfigureFailure(WifiStatus status)
                                         throws RemoteException {
-                                    Log.d(TAG, "onChipReconfigureFailure: status=" + statusString(
+                                    Log.e(TAG, "onChipReconfigureFailure: status=" + statusString(
                                             status));
                                 }
 
@@ -1675,7 +1675,13 @@
             if (bestIfaceCreationProposal != null) {
                 IWifiIface iface = executeChipReconfiguration(bestIfaceCreationProposal,
                         createIfaceType);
-                if (iface != null) {
+                if (iface == null) {
+                    // If the chip reconfiguration failed, we'll need to clean up internal state.
+                    Log.e(TAG, "Teardown Wifi internal state");
+                    mWifi = null;
+                    mIsReady = false;
+                    teardownInternal();
+                } else {
                     InterfaceCacheEntry cacheEntry = new InterfaceCacheEntry();
 
                     cacheEntry.chip = bestIfaceCreationProposal.chipInfo.chip;
@@ -1698,7 +1704,7 @@
             }
         }
 
-        Log.d(TAG, "createIfaceIfPossible: Failed to create iface for ifaceType=" + createIfaceType
+        Log.e(TAG, "createIfaceIfPossible: Failed to create iface for ifaceType=" + createIfaceType
                 + ", requestorWs=" + requestorWs);
         return null;
     }
diff --git a/service/java/com/android/server/wifi/ImsiPrivacyProtectionExemptionStoreData.java b/service/java/com/android/server/wifi/ImsiPrivacyProtectionExemptionStoreData.java
index 582bee4..93e61d6 100644
--- a/service/java/com/android/server/wifi/ImsiPrivacyProtectionExemptionStoreData.java
+++ b/service/java/com/android/server/wifi/ImsiPrivacyProtectionExemptionStoreData.java
@@ -27,6 +27,7 @@
 import org.xmlpull.v1.XmlSerializer;
 
 import java.io.IOException;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
 /**
@@ -82,6 +83,7 @@
             throws XmlPullParserException, IOException {
         // Ignore empty reads.
         if (in == null) {
+            mDataSource.fromDeserialized(Collections.emptyMap());
             return;
         }
         mDataSource.fromDeserialized(parseCarrierImsiProtectionExemptionMap(in, outerTagDepth,
diff --git a/service/java/com/android/server/wifi/WifiBlocklistMonitor.java b/service/java/com/android/server/wifi/WifiBlocklistMonitor.java
index b53f648..7a389eb 100644
--- a/service/java/com/android/server/wifi/WifiBlocklistMonitor.java
+++ b/service/java/com/android/server/wifi/WifiBlocklistMonitor.java
@@ -1069,7 +1069,9 @@
 
         // Clear out all the disable reason counters.
         status.clearDisableReasonCounter();
-        config.status = WifiConfiguration.Status.ENABLED;
+        if (config.status == WifiConfiguration.Status.DISABLED) {
+            config.status = WifiConfiguration.Status.ENABLED;
+        }
     }
 
     /**
diff --git a/service/java/com/android/server/wifi/WifiCarrierInfoManager.java b/service/java/com/android/server/wifi/WifiCarrierInfoManager.java
index 3d01ee6..f17dc72 100644
--- a/service/java/com/android/server/wifi/WifiCarrierInfoManager.java
+++ b/service/java/com/android/server/wifi/WifiCarrierInfoManager.java
@@ -17,7 +17,6 @@
 package com.android.server.wifi;
 
 import static android.Manifest.permission.NETWORK_SETTINGS;
-import static android.telephony.TelephonyManager.DATA_ENABLED_REASON_USER;
 
 import android.annotation.IntDef;
 import android.annotation.NonNull;
@@ -262,15 +261,13 @@
 
         @Override
         public void onDataEnabledChanged(boolean enabled, int reason) {
-            if (reason == DATA_ENABLED_REASON_USER) {
-                Log.d(TAG, "Mobile data change by user to "
-                        + (enabled ? "enabled" : "disabled") + " for subId: " + mSubscriptionId);
-                mUserDataEnabled.put(mSubscriptionId, enabled);
-                if (!enabled) {
-                    for (OnCarrierOffloadDisabledListener listener :
-                            mOnCarrierOffloadDisabledListeners) {
-                        listener.onCarrierOffloadDisabled(mSubscriptionId, true);
-                    }
+            Log.d(TAG, "Mobile data change by reason " + reason + " to "
+                    + (enabled ? "enabled" : "disabled") + " for subId: " + mSubscriptionId);
+            mUserDataEnabled.put(mSubscriptionId, enabled);
+            if (!enabled) {
+                for (OnCarrierOffloadDisabledListener listener :
+                        mOnCarrierOffloadDisabledListeners) {
+                    listener.onCarrierOffloadDisabled(mSubscriptionId, true);
                 }
             }
         }
diff --git a/service/java/com/android/server/wifi/WifiConfigurationUtil.java b/service/java/com/android/server/wifi/WifiConfigurationUtil.java
index 6478ba2..5419298 100644
--- a/service/java/com/android/server/wifi/WifiConfigurationUtil.java
+++ b/service/java/com/android/server/wifi/WifiConfigurationUtil.java
@@ -1153,7 +1153,14 @@
      */
     public static int addSecurityTypeToNetworkId(
             int netId, @WifiConfiguration.SecurityType int securityType) {
-        if (netId == INVALID_NETWORK_ID || SdkLevel.isAtLeastS()) {
+        // Do not add Passpoint security types since R WifiTrackerLib will map both R1/R2 and R3 to
+        // EAP, which means one of the configs will clobber the other when WifiTrackerLib caches
+        // them by SSID + security type. This may cause a mismatch between a WifiInfo with an
+        // R1/R2-encoded networkId and a cached WifiConfiguration with an R3-encoded networkId,
+        // resulting in a connected Passpoint network not showing in the Wifi picker.
+        if (netId == INVALID_NETWORK_ID || SdkLevel.isAtLeastS()
+                || securityType == WifiConfiguration.SECURITY_TYPE_PASSPOINT_R1_R2
+                || securityType == WifiConfiguration.SECURITY_TYPE_PASSPOINT_R3) {
             return netId;
         }
         return removeSecurityTypeFromNetworkId(netId)
diff --git a/service/java/com/android/server/wifi/WifiConnectivityManager.java b/service/java/com/android/server/wifi/WifiConnectivityManager.java
index 4dd1467..892f692 100644
--- a/service/java/com/android/server/wifi/WifiConnectivityManager.java
+++ b/service/java/com/android/server/wifi/WifiConnectivityManager.java
@@ -2068,7 +2068,10 @@
                 + " wifiState=" + stateToString(mWifiState)
                 + " scanImmediately=" + scanImmediately
                 + " wifiEnabled=" + mWifiEnabled
-                + " mAutoJoinEnabled=" + mAutoJoinEnabled);
+                + " mAutoJoinEnabled=" + mAutoJoinEnabled
+                + " mAutoJoinEnabledExternal=" + mAutoJoinEnabledExternal
+                + " mSpecificNetworkRequestInProgress=" + mSpecificNetworkRequestInProgress
+                + " mTrustedConnectionAllowed=" + mTrustedConnectionAllowed);
 
         if (!mWifiEnabled || !mAutoJoinEnabled) {
             return;
diff --git a/service/java/com/android/server/wifi/WifiNetworkSelector.java b/service/java/com/android/server/wifi/WifiNetworkSelector.java
index 9f81038..df50568 100644
--- a/service/java/com/android/server/wifi/WifiNetworkSelector.java
+++ b/service/java/com/android/server/wifi/WifiNetworkSelector.java
@@ -978,6 +978,22 @@
                 mScanRequestProxy.isWpa2EnterpriseOnlyNetworkInRange(config.SSID),
                 mScanRequestProxy.isWpa3EnterpriseOnlyNetworkInRange(config.SSID),
                 true);
+        // When using WPA3 (SAE), all passwords in all lengths are strings, but when using WPA2,
+        // there is a distinction between 8-63 octets that go through BDKDF2 function, and
+        // 64-octets that are assumed to be the output of it. BDKDF2 is not applicable to SAE
+        // and to prevent interop issues with APs when 64-octet Hex PSK is configured, update
+        // the configuration to use WPA2 only.
+        WifiConfiguration configWithPassword = mWifiConfigManager
+                .getConfiguredNetworkWithPassword(config.networkId);
+        if (configWithPassword.isSecurityType(WifiConfiguration.SECURITY_TYPE_PSK)
+                && configWithPassword.isSecurityType(WifiConfiguration.SECURITY_TYPE_SAE)
+                && !configWithPassword.preSharedKey.startsWith("\"")
+                && configWithPassword.preSharedKey.length() == 64
+                && configWithPassword.preSharedKey.matches(String.format("[0-9A-Fa-f]{%d}", 64))) {
+            localLog("Remove SAE type for " + configWithPassword.SSID + " with 64-octet Hex PSK.");
+            scanResultParamsList
+                    .removeIf(p -> p.isSecurityType(WifiConfiguration.SECURITY_TYPE_SAE));
+        }
     }
 
     /**
diff --git a/service/java/com/android/server/wifi/WifiServiceImpl.java b/service/java/com/android/server/wifi/WifiServiceImpl.java
index f1f9d79..13c96fe 100644
--- a/service/java/com/android/server/wifi/WifiServiceImpl.java
+++ b/service/java/com/android/server/wifi/WifiServiceImpl.java
@@ -486,13 +486,11 @@
 
     private void resetCarrierNetworks(@ClientModeImpl.ResetSimReason int resetReason) {
         Log.d(TAG, "resetting carrier networks since SIM was changed");
-        if (resetReason == RESET_SIM_REASON_SIM_INSERTED
-                || resetReason == RESET_SIM_REASON_DEFAULT_DATA_SIM_CHANGED) {
+        if (resetReason == RESET_SIM_REASON_SIM_INSERTED) {
             // clear all SIM related notifications since some action was taken to address
             // "missing" SIM issue
             mSimRequiredNotifier.dismissSimRequiredNotification();
-        }
-        if (resetReason != RESET_SIM_REASON_SIM_INSERTED) {
+        } else {
             mWifiConfigManager.resetSimNetworks();
             mWifiNetworkSuggestionsManager.resetSimNetworkSuggestions();
             mPasspointManager.resetSimPasspointNetwork();
@@ -503,7 +501,7 @@
         for (ClientModeManager cmm : mActiveModeWarden.getClientModeManagers()) {
             cmm.resetSimAuthNetworks(resetReason);
         }
-        mWifiNetworkSuggestionsManager.resetCarrierPrivilegedApps();
+        mWifiThreadRunner.post(mWifiNetworkSuggestionsManager::resetCarrierPrivilegedApps);
         if (resetReason == RESET_SIM_REASON_SIM_INSERTED) {
             // clear the blocklists in case any SIM based network were disabled due to the SIM
             // not being available.
@@ -511,7 +509,7 @@
             mWifiConnectivityManager.forceConnectivityScan(ClientModeImpl.WIFI_WORK_SOURCE);
         } else {
             // Remove all ephemeral carrier networks keep subscriptionId update with SIM changes
-            mWifiConfigManager.removeEphemeralCarrierNetworks();
+            mWifiThreadRunner.post(mWifiConfigManager::removeEphemeralCarrierNetworks);
         }
     }
 
diff --git a/service/java/com/android/server/wifi/p2p/WifiP2pNative.java b/service/java/com/android/server/wifi/p2p/WifiP2pNative.java
index f26d532..1c66aea 100644
--- a/service/java/com/android/server/wifi/p2p/WifiP2pNative.java
+++ b/service/java/com/android/server/wifi/p2p/WifiP2pNative.java
@@ -314,16 +314,6 @@
     }
 
     /**
-     * Set WPS device name.
-     *
-     * @param name String to be set.
-     * @return true if request is sent successfully, false otherwise.
-     */
-    public boolean setP2pDeviceName(String name) {
-        return mSupplicantP2pIfaceHal.setWpsDeviceName(name);
-    }
-
-    /**
      * Set WPS device type.
      *
      * @param type Type specified as a string. Used format: <categ>-<OUI>-<subcateg>
diff --git a/service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java b/service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java
index 62f8feb..f1604dd 100644
--- a/service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java
+++ b/service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java
@@ -420,6 +420,31 @@
         }
     }
 
+    private void updateWorkSourceByUid(int uid, boolean active) {
+        if (uid == -1) return;
+        if (active == mActiveClients.containsKey(uid)) return;
+        Log.d(TAG, "Update WorkSource UID=" + uid + " active=" + active);
+
+        if (!active) mActiveClients.remove(uid);
+        // The worksource is based on UID, just find the first one.
+        DeathHandlerData dhd = mDeathDataByBinder.values().stream()
+                .filter(d -> d.mUid == uid)
+                .findAny()
+                .orElse(null);
+        if (active && null == dhd) {
+            Log.w(TAG, "No WorkSource for UID " + uid);
+            return;
+        }
+
+        if (null != dhd) {
+            mActiveClients.put(uid, dhd.mWorkSource);
+        }
+        // If p2p is off, the first one activates P2P will merge all worksources.
+        // If p2p is already on, send ENABLE_P2P to merge the new worksource.
+        if (mP2pStateMachine.isP2pDisabled()) return;
+        mP2pStateMachine.sendMessage(ENABLE_P2P);
+    }
+
     /**
      * Handles client connections
      */
@@ -504,7 +529,8 @@
     }
 
     private class DeathHandlerData {
-        DeathHandlerData(DeathRecipient dr, Messenger m, WorkSource ws) {
+        DeathHandlerData(int uid, DeathRecipient dr, Messenger m, WorkSource ws) {
+            mUid = uid;
             mDeathRecipient = dr;
             mMessenger = m;
             mWorkSource = ws;
@@ -516,12 +542,14 @@
                     + ", worksource=" + mWorkSource;
         }
 
+        final int mUid;
         final DeathRecipient mDeathRecipient;
         final Messenger mMessenger;
         final WorkSource mWorkSource;
     }
     private Object mLock = new Object();
     private final Map<IBinder, DeathHandlerData> mDeathDataByBinder = new ConcurrentHashMap<>();
+    private final Map<Integer, WorkSource> mActiveClients = new ConcurrentHashMap<>();
 
     public WifiP2pServiceImpl(Context context, WifiInjector wifiInjector) {
         mContext = context;
@@ -686,16 +714,12 @@
                     : new WorkSource(Binder.getCallingUid());
             try {
                 binder.linkToDeath(dr, 0);
-                mDeathDataByBinder.put(binder, new DeathHandlerData(dr, messenger, ws));
+                mDeathDataByBinder.put(binder, new DeathHandlerData(
+                        Binder.getCallingUid(), dr, messenger, ws));
             } catch (RemoteException e) {
                 Log.e(TAG, "Error on linkToDeath: e=" + e);
                 // fall-through here - won't clean up
             }
-            // If p2p is already on, send ENABLE_P2P to merge the new worksource.
-            // If p2p is off, the first one activates P2P will merge all worksources.
-            if (!mP2pStateMachine.isP2pDisabled()) {
-                mP2pStateMachine.sendMessage(ENABLE_P2P);
-            }
             return messenger;
         }
     }
@@ -730,9 +754,10 @@
                 return;
             }
 
-            mP2pStateMachine.sendMessage(REMOVE_CLIENT_INFO, 0, 0, binder);
             binder.unlinkToDeath(dhd.mDeathRecipient, 0);
             mDeathDataByBinder.remove(binder);
+            updateWorkSourceByUid(Binder.getCallingUid(), false);
+            mP2pStateMachine.sendMessage(REMOVE_CLIENT_INFO, 0, 0, binder);
 
             // clean-up if there are no more clients registered
             // TODO: what does the ClientModeImpl client do? It isn't tracked through here!
@@ -1082,12 +1107,51 @@
 
         private WorkSource createMergedRequestorWs() {
             WorkSource requestorWs = new WorkSource();
-            for (DeathHandlerData deathHandlerData : mDeathDataByBinder.values()) {
-                requestorWs.add(deathHandlerData.mWorkSource);
+            for (WorkSource ws: mActiveClients.values()) {
+                requestorWs.add(ws);
             }
+            logd("Requestor WorkSource: " + requestorWs);
             return requestorWs;
         }
 
+        private boolean needsActiveP2p(int cmd) {
+            if (cmd < Protocol.BASE_WIFI_P2P_MANAGER) return false;
+            if (cmd >= Protocol.BASE_WIFI_P2P_SERVICE) return false;
+            switch (cmd) {
+                case WifiP2pManager.UPDATE_CHANNEL_INFO:
+                case WifiP2pManager.SET_WFD_INFO:
+                // If P2P is not active, these commands do not take effect actually.
+                case WifiP2pManager.STOP_DISCOVERY:
+                case WifiP2pManager.STOP_LISTEN:
+                case WifiP2pManager.CANCEL_CONNECT:
+                case WifiP2pManager.REMOVE_GROUP:
+                case WifiP2pManager.REMOVE_LOCAL_SERVICE:
+                case WifiP2pManager.CLEAR_LOCAL_SERVICES:
+                case WifiP2pManager.REMOVE_SERVICE_REQUEST:
+                case WifiP2pManager.CLEAR_SERVICE_REQUESTS:
+                // These commands return wifi service p2p information which
+                // does not need active P2P.
+                case WifiP2pManager.REQUEST_P2P_STATE:
+                case WifiP2pManager.REQUEST_DISCOVERY_STATE:
+                case WifiP2pManager.REQUEST_NETWORK_INFO:
+                case WifiP2pManager.REQUEST_CONNECTION_INFO:
+                case WifiP2pManager.REQUEST_GROUP_INFO:
+                case WifiP2pManager.REQUEST_DEVICE_INFO:
+                case WifiP2pManager.REQUEST_PEERS:
+                // These commands could be cached and executed on activating P2P.
+                case WifiP2pManager.SET_DEVICE_NAME:
+                    return false;
+            }
+            return true;
+        }
+
+        @Override
+        protected void onPreHandleMessage(Message msg) {
+            if (needsActiveP2p(msg.what)) {
+                updateWorkSourceByUid(msg.sendingUid, true);
+            }
+        }
+
         class DefaultState extends State {
             @Override
             public boolean processMessage(Message message) {
@@ -1132,8 +1196,12 @@
                                 WifiP2pManager.BUSY);
                         break;
                     case WifiP2pManager.STOP_DISCOVERY:
-                        replyToMessage(message, WifiP2pManager.STOP_DISCOVERY_FAILED,
-                                WifiP2pManager.BUSY);
+                        if (mIsWifiEnabled) {
+                            replyToMessage(message, WifiP2pManager.STOP_DISCOVERY_SUCCEEDED);
+                        } else {
+                            replyToMessage(message, WifiP2pManager.STOP_DISCOVERY_FAILED,
+                                    WifiP2pManager.BUSY);
+                        }
                         break;
                     case WifiP2pManager.DISCOVER_SERVICES:
                         replyToMessage(message, WifiP2pManager.DISCOVER_SERVICES_FAILED,
@@ -1145,7 +1213,7 @@
                         break;
                     case WifiP2pManager.CANCEL_CONNECT:
                         replyToMessage(message, WifiP2pManager.CANCEL_CONNECT_FAILED,
-                                WifiP2pManager.BUSY);
+                                 WifiP2pManager.BUSY);
                         break;
                     case WifiP2pManager.CREATE_GROUP:
                         replyToMessage(message, WifiP2pManager.CREATE_GROUP_FAILED,
@@ -1155,6 +1223,11 @@
                         replyToMessage(message, WifiP2pManager.REMOVE_GROUP_FAILED,
                                 WifiP2pManager.BUSY);
                         break;
+                    case WifiP2pManager.STOP_LISTEN:
+                        if (mIsWifiEnabled) {
+                            replyToMessage(message, WifiP2pManager.STOP_LISTEN_SUCCEEDED);
+                        }
+                        break;
                     case WifiP2pManager.ADD_LOCAL_SERVICE:
                         replyToMessage(message, WifiP2pManager.ADD_LOCAL_SERVICE_FAILED,
                                 WifiP2pManager.BUSY);
@@ -1182,9 +1255,31 @@
                                 WifiP2pManager.BUSY);
                         break;
                     case WifiP2pManager.SET_DEVICE_NAME:
-                        replyToMessage(message, WifiP2pManager.SET_DEVICE_NAME_FAILED,
-                                WifiP2pManager.BUSY);
+                    {
+                        if (!mIsWifiEnabled) {
+                            replyToMessage(message, WifiP2pManager.SET_DEVICE_NAME_FAILED,
+                                    WifiP2pManager.BUSY);
+                            break;
+                        }
+                        if (!checkNetworkSettingsOrNetworkStackOrOverrideWifiConfigPermission(
+                                message.sendingUid)) {
+                            loge("Permission violation - none of NETWORK_SETTING, NETWORK_STACK,"
+                                    + " or OVERRIDE_WIFI_CONFIG permission, uid = "
+                                    + message.sendingUid);
+                            replyToMessage(message, WifiP2pManager.SET_DEVICE_NAME_FAILED,
+                                    WifiP2pManager.ERROR);
+                            break;
+                        }
+                        WifiP2pDevice d = (WifiP2pDevice) message.obj;
+                        if (d != null && setAndPersistDeviceName(d.deviceName)) {
+                            if (mVerboseLoggingEnabled) logd("set device name " + d.deviceName);
+                            replyToMessage(message, WifiP2pManager.SET_DEVICE_NAME_SUCCEEDED);
+                        } else {
+                            replyToMessage(message, WifiP2pManager.SET_DEVICE_NAME_FAILED,
+                                    WifiP2pManager.ERROR);
+                        }
                         break;
+                    }
                     case WifiP2pManager.DELETE_PERSISTENT_GROUP:
                         replyToMessage(message, WifiP2pManager.DELETE_PERSISTENT_GROUP_FAILED,
                                 WifiP2pManager.BUSY);
@@ -1293,7 +1388,6 @@
                     case WifiP2pMonitor.P2P_PROV_DISC_FAILURE_EVENT:
                     case SET_MIRACAST_MODE:
                     case WifiP2pManager.START_LISTEN:
-                    case WifiP2pManager.STOP_LISTEN:
                     case WifiP2pManager.SET_CHANNEL:
                     case ENABLE_P2P:
                         // Enable is lazy and has no response
@@ -1533,6 +1627,7 @@
             public void enter() {
                 if (mVerboseLoggingEnabled) logd(getName());
                 mInterfaceName = null; // reset iface name on disable.
+                mActiveClients.clear();
                 clearP2pInternalDataIfNecessary();
             }
 
@@ -1596,10 +1691,7 @@
                     default:
                         // only handle commands from clients and only commands
                         // which require P2P to be active.
-                        if (message.what < Protocol.BASE_WIFI_P2P_MANAGER
-                                || Protocol.BASE_WIFI_P2P_SERVICE <= message.what
-                                || message.what == WifiP2pManager.UPDATE_CHANNEL_INFO
-                                || message.what == WifiP2pManager.SET_WFD_INFO) {
+                        if (!needsActiveP2p(message.what)) {
                             return NOT_HANDLED;
                         }
                         // If P2P is not ready, it might be disabled due
@@ -1678,27 +1770,6 @@
                             Log.e(TAG, "Failed to replace requestorWs");
                         }
                         break;
-                    case WifiP2pManager.SET_DEVICE_NAME:
-                    {
-                        if (!checkNetworkSettingsOrNetworkStackOrOverrideWifiConfigPermission(
-                                message.sendingUid)) {
-                            loge("Permission violation - none of NETWORK_SETTING, NETWORK_STACK,"
-                                    + " or OVERRIDE_WIFI_CONFIG permission, uid = "
-                                    + message.sendingUid);
-                            replyToMessage(message, WifiP2pManager.SET_DEVICE_NAME_FAILED,
-                                    WifiP2pManager.ERROR);
-                            break;
-                        }
-                        WifiP2pDevice d = (WifiP2pDevice) message.obj;
-                        if (d != null && setAndPersistDeviceName(d.deviceName)) {
-                            if (mVerboseLoggingEnabled) logd("set device name " + d.deviceName);
-                            replyToMessage(message, WifiP2pManager.SET_DEVICE_NAME_SUCCEEDED);
-                        } else {
-                            replyToMessage(message, WifiP2pManager.SET_DEVICE_NAME_FAILED,
-                                    WifiP2pManager.ERROR);
-                        }
-                        break;
-                    }
                     case WifiP2pManager.SET_WFD_INFO:
                     {
                         WifiP2pWfdInfo d = (WifiP2pWfdInfo) message.obj;
@@ -4021,14 +4092,15 @@
         private boolean setAndPersistDeviceName(String devName) {
             if (TextUtils.isEmpty(devName)) return false;
 
-            if (!mWifiNative.setDeviceName(devName)) {
-                loge("Failed to set device name " + devName);
-                return false;
+            if (mInterfaceName != null) {
+                if (!mWifiNative.setDeviceName(devName)
+                        || !mWifiNative.setP2pSsidPostfix("-" + devName)) {
+                    loge("Failed to set device name " + devName);
+                    return false;
+                }
             }
 
             mThisDevice.deviceName = devName;
-            mWifiNative.setP2pSsidPostfix("-" + mThisDevice.deviceName);
-
             mSettingsConfigStore.put(WIFI_P2P_DEVICE_NAME, devName);
             sendThisDeviceChangedBroadcast();
             return true;
@@ -4068,7 +4140,7 @@
             mThisDevice.primaryDeviceType = mContext.getResources().getString(
                     R.string.config_wifi_p2p_device_type);
 
-            mWifiNative.setP2pDeviceName(mThisDevice.deviceName);
+            mWifiNative.setDeviceName(mThisDevice.deviceName);
             // DIRECT-XY-DEVICENAME (XY is randomly generated)
             mWifiNative.setP2pSsidPostfix("-" + mThisDevice.deviceName);
             mWifiNative.setP2pDeviceType(mThisDevice.primaryDeviceType);
diff --git a/service/tests/wifitests/src/com/android/server/wifi/ActiveModeWardenTest.java b/service/tests/wifitests/src/com/android/server/wifi/ActiveModeWardenTest.java
index d694d8a..f4742ba 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/ActiveModeWardenTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/ActiveModeWardenTest.java
@@ -42,6 +42,7 @@
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.doThrow;
 import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.inOrder;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.mockingDetails;
 import static org.mockito.Mockito.never;
@@ -91,6 +92,7 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.ArgumentCaptor;
+import org.mockito.InOrder;
 import org.mockito.Mock;
 import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
@@ -700,6 +702,52 @@
     }
 
     /**
+     * Test that wifi toggle switching the primary to scan only mode will also remove the additional
+     * CMMs.
+     */
+    @Test
+    public void testSwitchFromConnectModeToScanOnlyModeRemovesAdditionalCMMs() throws Exception {
+        // Ensure that we can create more client ifaces.
+        when(mWifiNative.isItPossibleToCreateStaIface(any())).thenReturn(true);
+        when(mResources.getBoolean(
+                R.bool.config_wifiMultiStaNetworkSwitchingMakeBeforeBreakEnabled))
+                .thenReturn(true);
+        assertTrue(mActiveModeWarden.canRequestMoreClientModeManagersInRole(
+                TEST_WORKSOURCE, ROLE_CLIENT_SECONDARY_TRANSIENT));
+
+        // request for an additional CMM
+        ConcreteClientModeManager additionalClientModeManager =
+                mock(ConcreteClientModeManager.class);
+        ExternalClientModeManagerRequestListener externalRequestListener = mock(
+                ExternalClientModeManagerRequestListener.class);
+        Listener<ConcreteClientModeManager> additionalClientListener =
+                requestAdditionalClientModeManager(ROLE_CLIENT_SECONDARY_TRANSIENT,
+                        additionalClientModeManager, externalRequestListener, TEST_SSID_2,
+                        TEST_BSSID_2);
+
+        // Verify that there exists both a primary and a secondary transient CMM
+        List<ClientModeManager> currentCMMs = mActiveModeWarden.getClientModeManagers();
+        assertEquals(2, currentCMMs.size());
+        assertTrue(currentCMMs.stream().anyMatch(cmm -> cmm.getRole() == ROLE_CLIENT_PRIMARY));
+        assertTrue(currentCMMs.stream().anyMatch(
+                cmm -> cmm.getRole() == ROLE_CLIENT_SECONDARY_TRANSIENT));
+
+        InOrder inOrder = inOrder(additionalClientModeManager, mClientModeManager);
+        // disable wifi and switch primary CMM to scan only mode
+        when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(true);
+        when(mSettingsStore.isAirplaneModeOn()).thenReturn(false);
+        when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(true);
+        when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false);
+        mActiveModeWarden.wifiToggled(TEST_WORKSOURCE);
+        mLooper.dispatchAll();
+
+        // Verify that we first stop the additional CMM and then switch the primary to scan only
+        // mode
+        inOrder.verify(additionalClientModeManager).stop();
+        inOrder.verify(mClientModeManager).setRole(ROLE_CLIENT_SCAN_ONLY, INTERNAL_REQUESTOR_WS);
+    }
+
+    /**
      * Reentering EnabledState should be a NOP.
      */
     @Test
diff --git a/service/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java b/service/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java
index 36d6e0f..4cd40c5 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java
@@ -1183,6 +1183,7 @@
         verify(mWifiNative, times(2)).removeAllNetworks(WIFI_IFACE_NAME);
         verify(mWifiMetrics).logStaEvent(anyString(), eq(StaEvent.TYPE_FRAMEWORK_DISCONNECT),
                 eq(StaEvent.DISCONNECT_RESET_SIM_NETWORKS));
+        verify(mSimRequiredNotifier, never()).showSimRequiredNotification(any(), anyString());
     }
 
     /**
@@ -6342,7 +6343,7 @@
             });
 
         // Verify VCN policy listener is registered
-        verify(vcnManager, atLeastOnce()).addVcnNetworkPolicyChangeListener(any(),
+        verify(vcnManager).addVcnNetworkPolicyChangeListener(any(),
                 policyChangeListenerCaptor.capture());
         assertNotNull(policyChangeListenerCaptor.getValue());
 
diff --git a/service/tests/wifitests/src/com/android/server/wifi/ImsiPrivacyProtectionExemptionStoreDataTest.java b/service/tests/wifitests/src/com/android/server/wifi/ImsiPrivacyProtectionExemptionStoreDataTest.java
index 0e764d3..185aa82 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/ImsiPrivacyProtectionExemptionStoreDataTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/ImsiPrivacyProtectionExemptionStoreDataTest.java
@@ -16,6 +16,7 @@
 package com.android.server.wifi;
 
 import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
@@ -92,6 +93,14 @@
         Map<Integer, Boolean> imsiPrivacyProtectionExemptionMap = new HashMap<>();
         assertSerializeDeserialize(imsiPrivacyProtectionExemptionMap);
     }
+
+    @Test
+    public void testDeserializeNullData() throws Exception {
+        mImsiPrivacyProtectionExemptionStoreData.deserializeData(null, 0,
+                WifiConfigStore.ENCRYPT_CREDENTIALS_CONFIG_STORE_DATA_VERSION, null);
+        verify(mDataSource).fromDeserialized(any());
+    }
+
     private Map<Integer, Boolean> assertSerializeDeserialize(
             Map<Integer, Boolean> mImsiPrivacyProtectionExemptionMap) throws Exception {
         // Setup the data to serialize.
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiBlocklistMonitorTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiBlocklistMonitorTest.java
index 9245aa3..a0f4a8a 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiBlocklistMonitorTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiBlocklistMonitorTest.java
@@ -1014,6 +1014,40 @@
     }
 
     /**
+     * Verifies the update of the current network's status using
+     * {@link WifiConfigManager#updateNetworkSelectionStatus(int, int)}.
+     */
+    @Test
+    public void testNetworkSelectionStatusCurrent() {
+        WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork();
+        openNetwork.status = WifiConfiguration.Status.CURRENT;
+        // First set it to enabled.
+        verifyUpdateNetworkSelectionStatus(
+                openNetwork, NetworkSelectionStatus.DISABLED_NONE, 0);
+
+        // Now set it to temporarily disabled. The threshold for association rejection is 5, so
+        // disable it 5 times to actually mark it temporarily disabled.
+        int assocRejectReason = NetworkSelectionStatus.DISABLED_ASSOCIATION_REJECTION;
+        int assocRejectThreshold =
+                mWifiBlocklistMonitor.getNetworkSelectionDisableThreshold(assocRejectReason);
+        for (int i = 1; i <= assocRejectThreshold; i++) {
+            verifyUpdateNetworkSelectionStatus(openNetwork, assocRejectReason, i);
+        }
+        assertEquals(NetworkSelectionStatus.DISABLED_ASSOCIATION_REJECTION,
+                openNetwork.getNetworkSelectionStatus().getNetworkSelectionDisableReason());
+        // Now set it to permanently disabled.
+        verifyUpdateNetworkSelectionStatus(
+                openNetwork, NetworkSelectionStatus.DISABLED_BY_WIFI_MANAGER, 0);
+        assertEquals(NetworkSelectionStatus.DISABLED_BY_WIFI_MANAGER,
+                openNetwork.getNetworkSelectionStatus().getNetworkSelectionDisableReason());
+        // Now set it back to enabled.
+        verifyUpdateNetworkSelectionStatus(
+                openNetwork, NetworkSelectionStatus.DISABLED_NONE, 0);
+        assertEquals(NetworkSelectionStatus.DISABLED_NONE,
+                openNetwork.getNetworkSelectionStatus().getNetworkSelectionDisableReason());
+    }
+
+    /**
      * Verifies the update of network status using
      * {@link WifiBlocklistMonitor#updateNetworkSelectionStatus(int, int)}.
      */
@@ -1081,6 +1115,7 @@
                 .thenReturn(TEST_ELAPSED_UPDATE_NETWORK_SELECTION_TIME_MILLIS);
         NetworkSelectionStatus currentStatus = config.getNetworkSelectionStatus();
         int currentDisableReason = currentStatus.getNetworkSelectionDisableReason();
+        boolean isCurrent = config.status == WifiConfiguration.Status.CURRENT;
 
         // First set the status to the provided reason.
         mWifiBlocklistMonitor.updateNetworkSelectionStatus(config, reason);
@@ -1098,7 +1133,11 @@
             assertEquals(
                     NetworkSelectionStatus.INVALID_NETWORK_SELECTION_DISABLE_TIMESTAMP,
                     retrievedDisableTime);
-            assertEquals(WifiConfiguration.Status.ENABLED, config.status);
+            if (isCurrent) {
+                assertEquals(WifiConfiguration.Status.CURRENT, config.status);
+            } else {
+                assertEquals(WifiConfiguration.Status.ENABLED, config.status);
+            }
         } else if (mWifiBlocklistMonitor.getNetworkSelectionDisableTimeoutMillis(reason)
                 != DisableReasonInfo.PERMANENT_DISABLE_TIMEOUT) {
             // For temporarily disabled networks, we need to ensure that the current status remains
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiCarrierInfoManagerTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiCarrierInfoManagerTest.java
index a2b8c5f..e0aec3b 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiCarrierInfoManagerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiCarrierInfoManagerTest.java
@@ -17,6 +17,8 @@
 package com.android.server.wifi;
 
 import static android.telephony.CarrierConfigManager.KEY_CARRIER_CONFIG_APPLIED_BOOL;
+import static android.telephony.TelephonyManager.DATA_ENABLED_REASON_CARRIER;
+import static android.telephony.TelephonyManager.DATA_ENABLED_REASON_THERMAL;
 import static android.telephony.TelephonyManager.DATA_ENABLED_REASON_USER;
 
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
@@ -1954,7 +1956,7 @@
         verify(mDataTelephonyManager).registerTelephonyCallback(any(), listenerCaptor.capture());
 
         // Verify result will change with state changes
-        listenerCaptor.getValue().onDataEnabledChanged(false, DATA_ENABLED_REASON_USER);
+        listenerCaptor.getValue().onDataEnabledChanged(false, DATA_ENABLED_REASON_THERMAL);
         assertFalse(mWifiCarrierInfoManager.isCarrierNetworkOffloadEnabled(DATA_SUBID, true));
 
         listenerCaptor.getValue().onDataEnabledChanged(true, DATA_ENABLED_REASON_USER);
@@ -2188,7 +2190,7 @@
         mWifiCarrierInfoManager.setCarrierNetworkOffloadEnabled(DATA_SUBID, true, false);
         verify(mOnCarrierOffloadDisabledListener).onCarrierOffloadDisabled(DATA_SUBID, true);
 
-        captor.getValue().onDataEnabledChanged(false, DATA_ENABLED_REASON_USER);
+        captor.getValue().onDataEnabledChanged(false, DATA_ENABLED_REASON_CARRIER);
         verify(mOnCarrierOffloadDisabledListener, times(2))
                 .onCarrierOffloadDisabled(DATA_SUBID, true);
     }
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java
index 75f2144..29c6d2b 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java
@@ -2008,8 +2008,7 @@
             ScanDetail scanDetail =
                     createScanDetailForNetwork(
                             openNetwork, String.format("%s%02x", testBssidPrefix, scanDetailNum));
-            assertNotNull(
-                    mWifiConfigManager.getSavedNetworkForScanDetailAndCache(scanDetail));
+            mWifiConfigManager.updateScanDetailForNetwork(openNetwork.networkId, scanDetail);
 
             // The size of scan detail cache should keep growing until it hits
             // |SCAN_CACHE_ENTRIES_MAX_SIZE|.
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiConfigurationUtilTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiConfigurationUtilTest.java
index 640a884..a715422 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiConfigurationUtilTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiConfigurationUtilTest.java
@@ -1320,7 +1320,7 @@
      */
     @Test
     public void testAddAndRemoveSecurityTypeForNetworkId() {
-        List<Integer> securityList = Arrays.asList(
+        List<Integer> securityListNoPasspoint = Arrays.asList(
                 WifiConfiguration.SECURITY_TYPE_OPEN,
                 WifiConfiguration.SECURITY_TYPE_WEP,
                 WifiConfiguration.SECURITY_TYPE_PSK,
@@ -1331,11 +1331,18 @@
                 WifiConfiguration.SECURITY_TYPE_WAPI_PSK,
                 WifiConfiguration.SECURITY_TYPE_WAPI_CERT,
                 WifiConfiguration.SECURITY_TYPE_EAP_WPA3_ENTERPRISE,
-                WifiConfiguration.SECURITY_TYPE_OSEN,
+                WifiConfiguration.SECURITY_TYPE_OSEN
+        );
+
+        List<Integer> securityListPasspoint = Arrays.asList(
                 WifiConfiguration.SECURITY_TYPE_PASSPOINT_R1_R2,
                 WifiConfiguration.SECURITY_TYPE_PASSPOINT_R3
         );
 
+        List<Integer> securityList = new ArrayList<>();
+        securityList.addAll(securityListPasspoint);
+        securityList.addAll(securityListNoPasspoint);
+
         final int netId = 1;
         if (!SdkLevel.isAtLeastS()) {
             // INVALID_NET_ID should remain the same from either adding or removing
@@ -1357,11 +1364,17 @@
                                         WifiConfigurationUtil.addSecurityTypeToNetworkId(
                                                 netId, securityType))));
             }
-            // A unique net id should be created for each security type added
-            assertEquals(securityList.size(), securityList.stream()
+            // A unique net id should be created for each non-passpoint security type added
+            assertEquals(securityListNoPasspoint.size(), securityListNoPasspoint.stream()
                     .map(security -> addSecurityTypeToNetworkId(netId, security))
                     .distinct()
                     .count());
+
+            // Passpoint should keep its security type for R WifiTrackerLib
+            for (@WifiConfiguration.SecurityType int securityType : securityListPasspoint) {
+                assertEquals(netId, WifiConfigurationUtil.addSecurityTypeToNetworkId(
+                                netId, securityType));
+            }
         } else {
             // Add should do nothing for SDK level S and above.
             for (@WifiConfiguration.SecurityType int securityType : securityList) {
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiNetworkSelectorTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiNetworkSelectorTest.java
index 05afcf5..30930cd 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiNetworkSelectorTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiNetworkSelectorTest.java
@@ -1771,10 +1771,13 @@
         List<ScanDetail> scanDetails = scanDetailsAndConfigs.getScanDetails();
         WifiConfiguration[] configs = scanDetailsAndConfigs.getWifiConfigs();
         WifiConfiguration existingConfig = WifiConfigurationTestUtil.createPasspointNetwork();
+        existingConfig.networkId = configs[0].networkId;
         existingConfig.SSID = ssids[1];
         // Matched wifiConfig is an passpoint network with SSID from last scan.
         when(mWifiConfigManager.getConfiguredNetwork(configs[0].networkId))
                 .thenReturn(existingConfig);
+        when(mWifiConfigManager.getConfiguredNetworkWithPassword(configs[0].networkId))
+                .thenReturn(existingConfig);
         mWifiNetworkSelector.registerNetworkNominator(
                 new PlaceholderNominator(0, PLACEHOLDER_NOMINATOR_ID_2));
         List<WifiCandidates.Candidate> candidates = mWifiNetworkSelector.getCandidatesFromScan(
@@ -2537,4 +2540,41 @@
                     network.getNetworkSelectionStatus().getCandidateSecurityParams());
         }
     }
+
+    /**
+     * Verify that PSK type is selected for a transition network
+     * when only 64-octet Hex PSK is set.
+     */
+    @Test
+    public void testPskWithPskOnlyForPskSaeTransitionNetworks() {
+        when(mClientModeManager.getSupportedFeatures()).thenReturn(WIFI_FEATURE_WPA3_SAE);
+        when(mWifiGlobals.isWpa3SaeUpgradeEnabled()).thenReturn(true);
+        when(mWifiGlobals.isWpa3SaeUpgradeOffloadEnabled()).thenReturn(true);
+
+        when(mScanRequestProxy.isWpa2PersonalOnlyNetworkInRange(eq(TEST_AUTO_UPGRADE_SSID)))
+                .thenReturn(true);
+        ScanDetailsAndWifiConfigs scanDetailsAndConfigs = setupAutoUpgradeNetworks(
+                WifiConfigurationTestUtil.createPskSaeNetwork(TEST_AUTO_UPGRADE_SSID),
+                new String[] {"[RSN-PSK+SAE-CCMP][ESS]", "[WPA2-PSK][ESS]"});
+        List<ScanDetail> scanDetails = scanDetailsAndConfigs.getScanDetails();
+        WifiConfiguration[] savedConfigs = scanDetailsAndConfigs.getWifiConfigs();
+        WifiConfiguration networkSelectorChoice = savedConfigs[0];
+        networkSelectorChoice.preSharedKey =
+                "1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF";
+
+        List<WifiCandidates.Candidate> candidates = mWifiNetworkSelector.getCandidatesFromScan(
+                scanDetails, new HashSet<>(),
+                Arrays.asList(new ClientModeManagerState(TEST_IFACE_NAME, false, true, mWifiInfo)),
+                false, true, true);
+        assertEquals(2, candidates.size());
+
+        // Verify that PSK network is still selected if offload is not supported
+        // and no PSK network is shown.
+        when(mScanRequestProxy.isWpa2PersonalOnlyNetworkInRange(eq(networkSelectorChoice.SSID)))
+                .thenReturn(false);
+        WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(candidates);
+        WifiConfigurationTestUtil.assertConfigurationEqual(networkSelectorChoice, candidate);
+        assertTrue(networkSelectorChoice.getNetworkSelectionStatus().getCandidateSecurityParams()
+                .isSecurityType(WifiConfiguration.SECURITY_TYPE_PSK));
+    }
 }
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiNetworkSelectorTestUtil.java b/service/tests/wifitests/src/com/android/server/wifi/WifiNetworkSelectorTestUtil.java
index f134ee5..464cc90 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiNetworkSelectorTestUtil.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiNetworkSelectorTestUtil.java
@@ -328,6 +328,17 @@
                         return null;
                     }
                 });
+        when(wifiConfigManager.getConfiguredNetworkWithPassword(anyInt()))
+                .then(new AnswerWithArguments() {
+                    public WifiConfiguration answer(int netId) {
+                        for (WifiConfiguration config : configs) {
+                            if (netId == config.networkId) {
+                                return new WifiConfiguration(config);
+                            }
+                        }
+                        return null;
+                    }
+                });
         when(wifiConfigManager.getConfiguredNetwork(anyString()))
                 .then(new AnswerWithArguments() {
                     public WifiConfiguration answer(String configKey) {
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java
index 6f0abe4..4bdc302 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java
@@ -5488,7 +5488,7 @@
 
         verify(mWifiConfigManager).resetSimNetworks();
         verify(mWifiConfigManager).stopRestrictingAutoJoinToSubscriptionId();
-        verify(mSimRequiredNotifier).dismissSimRequiredNotification();
+        verify(mSimRequiredNotifier, never()).dismissSimRequiredNotification();
         verify(mWifiNetworkSuggestionsManager).resetCarrierPrivilegedApps();
         verify(mWifiConfigManager).removeEphemeralCarrierNetworks();
         verify(mWifiNetworkSuggestionsManager).resetSimNetworkSuggestions();
diff --git a/service/tests/wifitests/src/com/android/server/wifi/p2p/WifiP2pNativeTest.java b/service/tests/wifitests/src/com/android/server/wifi/p2p/WifiP2pNativeTest.java
index bd75d88..2999caa 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/p2p/WifiP2pNativeTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/p2p/WifiP2pNativeTest.java
@@ -168,16 +168,6 @@
     }
 
     /**
-     * Verifies that the device name can be set.
-     */
-    @Test
-    public void testSetP2pDeviceName() {
-        when(mSupplicantP2pIfaceHalMock.setWpsDeviceName(anyString())).thenReturn(true);
-        assertTrue(mWifiP2pNative.setP2pDeviceName(TEST_DEVICE_NAME));
-        verify(mSupplicantP2pIfaceHalMock).setWpsDeviceName(eq(TEST_DEVICE_NAME));
-    }
-
-    /**
      * Verifies that networks could be listed.
      */
     @Test
diff --git a/service/tests/wifitests/src/com/android/server/wifi/p2p/WifiP2pServiceImplTest.java b/service/tests/wifitests/src/com/android/server/wifi/p2p/WifiP2pServiceImplTest.java
index 20eeea8..d947fe4 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/p2p/WifiP2pServiceImplTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/p2p/WifiP2pServiceImplTest.java
@@ -674,7 +674,7 @@
     private void forceP2pEnabled(Binder clientBinder) throws Exception {
         simulateWifiStateChange(true);
         simulateLocationModeChange(true);
-        checkIsP2pInitWhenClientConnected(true, false, clientBinder,
+        checkIsP2pInitWhenClientConnected(true, clientBinder,
                 new WorkSource(clientBinder.getCallingUid(), TEST_PACKAGE_NAME));
         verify(mContext).sendBroadcastWithMultiplePermissions(
                 argThat(new WifiP2pServiceImplTest
@@ -694,13 +694,13 @@
      * @param clientBinder client binder to use for p2p channel init
      * @param expectedRequestorWs Expected merged requestorWs
      */
-    private void checkIsP2pInitWhenClientConnected(boolean expectInit, boolean expectReplace,
+    private void checkIsP2pInitWhenClientConnected(boolean expectInit,
             Binder clientBinder, WorkSource expectedRequestorWs)
             throws Exception {
         mWifiP2pServiceImpl.getMessenger(clientBinder, TEST_PACKAGE_NAME);
         if (expectInit) {
             // send a command to force P2P enabled.
-            sendSimpleMsg(mClientMessenger, WifiP2pManager.REQUEST_P2P_STATE);
+            sendSimpleMsg(mClientMessenger, WifiP2pManager.DISCOVER_PEERS);
         }
         mLooper.dispatchAll();
         reset(mClientHandler);
@@ -711,8 +711,6 @@
             // Verify timer is scheduled
             verify(mAlarmManager, times(2)).setExact(anyInt(), anyLong(),
                     eq(mWifiP2pServiceImpl.P2P_IDLE_SHUTDOWN_MESSAGE_TIMEOUT_TAG), any(), any());
-        } else if (expectReplace) {
-            verify(mWifiNative).replaceRequestorWs(expectedRequestorWs);
         } else {
             verify(mWifiNative, never()).setupInterface(any(), any(), any());
             verify(mNetdWrapper, never()).setInterfaceUp(anyString());
@@ -731,15 +729,13 @@
      * @param expectedRequestorWs Expected merged requestorWs
      */
     private void checkIsP2pTearDownWhenClientDisconnected(
-            boolean expectTearDown, boolean expectReplace,
+            boolean expectTearDown,
             Binder clientBinder, WorkSource expectedRequestorWs) throws Exception {
         mWifiP2pServiceImpl.close(clientBinder);
         mLooper.dispatchAll();
         if (expectTearDown) {
             verify(mWifiNative).teardownInterface();
             verify(mWifiMonitor).stopMonitoring(anyString());
-        } else if (expectReplace) {
-            verify(mWifiNative).replaceRequestorWs(expectedRequestorWs);
         } else {
             verify(mWifiNative, never()).teardownInterface();
             verify(mWifiMonitor, never()).stopMonitoring(anyString());
@@ -976,9 +972,9 @@
     @Test
     public void testP2pInitWhenClientConnectWithWifiEnabled() throws Exception {
         simulateWifiStateChange(true);
-        checkIsP2pInitWhenClientConnected(true, false, mClient1,
+        checkIsP2pInitWhenClientConnected(true, mClient1,
                 new WorkSource(mClient1.getCallingUid(), TEST_PACKAGE_NAME));
-        checkIsP2pTearDownWhenClientDisconnected(true, false, mClient1, null);
+        checkIsP2pTearDownWhenClientDisconnected(true, mClient1, null);
     }
 
     /**
@@ -989,9 +985,9 @@
     public void testP2pDoesntInitWhenClientConnectWithWifiDisabled()
             throws Exception {
         simulateWifiStateChange(false);
-        checkIsP2pInitWhenClientConnected(false, false, mClient1,
+        checkIsP2pInitWhenClientConnected(false, mClient1,
                 new WorkSource(mClient1.getCallingUid(), TEST_PACKAGE_NAME));
-        checkIsP2pTearDownWhenClientDisconnected(false, false, mClient1, null);
+        checkIsP2pTearDownWhenClientDisconnected(false, mClient1, null);
     }
 
     /**
@@ -1017,7 +1013,7 @@
         verify(mWifiMonitor, atLeastOnce()).registerHandler(anyString(), anyInt(), any());
 
         // Lazy initialization is done once receiving a command.
-        sendSimpleMsg(mClientMessenger, WifiP2pManager.REQUEST_P2P_STATE);
+        sendSimpleMsg(mClientMessenger, WifiP2pManager.DISCOVER_PEERS);
         verify(mWifiNative, times(2)).setupInterface(any(), any(), any());
         verify(mNetdWrapper, times(2)).setInterfaceUp(anyString());
     }
@@ -1030,13 +1026,14 @@
         forceP2pEnabled(mClient1);
         WorkSource expectedRequestorWs =
                 new WorkSource(mClient1.getCallingUid(), TEST_PACKAGE_NAME);
-        expectedRequestorWs.add(mClient2.getCallingUid(), TEST_PACKAGE_NAME);
-        // P2pInit check count should keep in once, same as one client connected case.
-        checkIsP2pInitWhenClientConnected(false, true, mClient2, expectedRequestorWs);
         reset(mWifiNative);
-        checkIsP2pTearDownWhenClientDisconnected(false, true, mClient2,
+        reset(mNetdWrapper);
+        reset(mWifiMonitor);
+        // P2pInit check count should keep in once, same as one client connected case.
+        checkIsP2pInitWhenClientConnected(false, mClient2, expectedRequestorWs);
+        checkIsP2pTearDownWhenClientDisconnected(false, mClient2,
                 new WorkSource(mClient1.getCallingUid(), TEST_PACKAGE_NAME));
-        checkIsP2pTearDownWhenClientDisconnected(true, false, mClient1, null);
+        checkIsP2pTearDownWhenClientDisconnected(true, mClient1, null);
     }
 
     /**
@@ -2971,6 +2968,7 @@
 
         mTestThisDevice.deviceName = "another-name";
         when(mWifiNative.setDeviceName(anyString())).thenReturn(true);
+        when(mWifiNative.setP2pSsidPostfix(anyString())).thenReturn(true);
         sendSetDeviceNameMsg(mClientMessenger, mTestThisDevice);
         verify(mWifiNative).setDeviceName(eq(mTestThisDevice.deviceName));
         verify(mWifiNative).setP2pSsidPostfix(eq("-" + mTestThisDevice.deviceName));
@@ -2991,6 +2989,8 @@
         forceP2pEnabled(mClient1);
         mTestThisDevice.status = mTestThisDevice.AVAILABLE;
 
+        // clear the one called on entering P2pEnabledState.
+        reset(mWifiNative);
         mTestThisDevice.deviceName = "";
         when(mWifiNative.setDeviceName(anyString())).thenReturn(true);
         sendSetDeviceNameMsg(mClientMessenger, mTestThisDevice);
@@ -3011,6 +3011,8 @@
         // Move to enabled state
         forceP2pEnabled(mClient1);
 
+        // clear the one called on entering P2pEnabledState.
+        reset(mWifiNative);
         when(mWifiNative.setDeviceName(anyString())).thenReturn(false);
         sendSetDeviceNameMsg(mClientMessenger, mTestThisDevice);
         verify(mWifiNative).setDeviceName(eq(mTestThisDevice.deviceName));
@@ -4491,7 +4493,7 @@
         // Verify timer is cannelled
         // Includes re-schedule 4 times:
         // 1. forceP2pEnabled(): enter InactiveState
-        // 2. forceP2pEnabled: REQUEST_P2P_STATE
+        // 2. forceP2pEnabled: DISCOVER_PEERS
         // 3. CONNECT
         // 4. leave InactiveState
         verify(mAlarmManager, times(4)).setExact(anyInt(), anyLong(),
@@ -4543,7 +4545,7 @@
         when(mWifiNative.setWfdDeviceInfo(anyString())).thenReturn(true);
 
         // send a command to resume P2P
-        sendSimpleMsg(mClientMessenger, WifiP2pManager.REQUEST_P2P_STATE);
+        sendSimpleMsg(mClientMessenger, WifiP2pManager.DISCOVER_PEERS);
 
         // Restore data for resuming from idle shutdown.
         verify(mWifiNative).setWfdEnable(eq(true));
@@ -4581,7 +4583,7 @@
         when(mWifiNative.setWfdDeviceInfo(anyString())).thenReturn(true);
 
         // send a command to resume P2P
-        sendSimpleMsg(mClientMessenger, WifiP2pManager.REQUEST_P2P_STATE);
+        sendSimpleMsg(mClientMessenger, WifiP2pManager.DISCOVER_PEERS);
         mLooper.dispatchAll();
 
         // In normal case, wfd info is cleared.