Merge "WifiManager getBssidBlocklist API" into main
diff --git a/framework/java/android/net/wifi/rtt/ResponderLocation.java b/framework/java/android/net/wifi/rtt/ResponderLocation.java
index 42cc52d..c77160c 100644
--- a/framework/java/android/net/wifi/rtt/ResponderLocation.java
+++ b/framework/java/android/net/wifi/rtt/ResponderLocation.java
@@ -671,9 +671,9 @@
 
         long zHeightUncertainty =
                 subelementZFields[SUBELEMENT_Z_HEIGHT_ABOVE_FLOOR_UNCERTAINTY_INDEX];
-        if (zHeightUncertainty > 0 && zHeightUncertainty < Z_MAX_HEIGHT_UNCERTAINTY_FACTOR) {
-            mHeightAboveFloorUncertaintyMeters =
-                    Math.pow(2, Z_FLOOR_HEIGHT_FRACTION_BITS - zHeightUncertainty - 1);
+        if (zHeightUncertainty >= 0 && zHeightUncertainty < Z_MAX_HEIGHT_UNCERTAINTY_FACTOR) {
+            mHeightAboveFloorUncertaintyMeters = zHeightUncertainty == 0
+                    ? 0 : Math.pow(2, Z_FLOOR_HEIGHT_FRACTION_BITS - zHeightUncertainty - 1);
         } else {
             return false;
         }
diff --git a/framework/tests/src/android/net/wifi/rtt/ResponderLocationTest.java b/framework/tests/src/android/net/wifi/rtt/ResponderLocationTest.java
index f9f25ab..5d257c9 100644
--- a/framework/tests/src/android/net/wifi/rtt/ResponderLocationTest.java
+++ b/framework/tests/src/android/net/wifi/rtt/ResponderLocationTest.java
@@ -16,6 +16,10 @@
 
 package android.net.wifi.rtt;
 
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+
 import android.location.Address;
 import android.location.Location;
 import android.net.MacAddress;
@@ -23,10 +27,6 @@
 import android.util.SparseArray;
 import android.webkit.MimeTypeMap;
 
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertTrue;
-
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.JUnit4;
@@ -87,6 +87,17 @@
             (byte) 0x0e, // STA Height Uncertainty
     };
 
+    private static final byte[] sTestZHeightSEUncertaintyUnset = {
+            (byte) 0x04, // Subelement Z
+            (byte) 6, // Length always 6
+            (byte) 0x00, // LSB STA Floor Info (2 bytes)
+            (byte) 0x01, // MSB
+            (byte) 0xcd, // LSB Height(m) (3 bytes)
+            (byte) 0x2c,
+            (byte) 0x00, // MSB Height(m)
+            (byte) 0x00, // STA Height Uncertainty
+    };
+
     private static final byte[] sTestUsageSE1 = {
             (byte) 0x06, // Subelement Usage Rights
             (byte) 1, // Length 1 (with no retention limit)
@@ -403,6 +414,32 @@
     }
 
     /**
+     * Test for a valid Z (Height) subelement with unset uncertainty following an LCI subelement.
+     */
+    @Test
+    public void testLciValidZBufferSEAfterLciWithUnsetUncertainty() {
+        byte[] testBufferTmp = concatenateArrays(sTestLciIeHeader, sTestLciSE);
+        byte[] testBuffer = concatenateArrays(testBufferTmp, sTestZHeightSEUncertaintyUnset);
+        ResponderLocation responderLocation =
+                new ResponderLocation(testBuffer, sTestLcrBufferHeader);
+
+        boolean isValid = responderLocation.isValid();
+        boolean isZValid = responderLocation.isZaxisSubelementValid();
+        boolean isLciValid = responderLocation.isLciSubelementValid();
+        double staFloorNumber = responderLocation.getFloorNumber();
+        double staHeightAboveFloorMeters = responderLocation.getHeightAboveFloorMeters();
+        double staHeightAboveFloorUncertaintyMeters =
+                responderLocation.getHeightAboveFloorUncertaintyMeters();
+
+        assertTrue(isValid);
+        assertTrue(isZValid);
+        assertTrue(isLciValid);
+        assertEquals(4.0, staFloorNumber);
+        assertEquals(2.8, staHeightAboveFloorMeters, HEIGHT_TOLERANCE_METERS);
+        assertEquals(0.0, staHeightAboveFloorUncertaintyMeters);
+    }
+
+    /**
      * Test for a valid Usage Policy that is unrestrictive
      */
     @Test
diff --git a/service/ServiceWifiResources/res/values-mcc310-mnc150/config.xml b/service/ServiceWifiResources/res/values-mcc310-mnc150/config.xml
new file mode 100644
index 0000000..39eaadb
--- /dev/null
+++ b/service/ServiceWifiResources/res/values-mcc310-mnc150/config.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2023 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string-array translatable="false" name="config_wifiOobPseudonymEnabled_carrier_overrides">
+        <item><xliff:g id="carrier_id_prefix">:::1779:::</xliff:g>true</item>
+    </string-array>
+
+    <!-- Carrier specific override for the URL of entitlement server retrieving OOB pseudonym. -->
+    <string-array translatable="false" name="config_wifiOobPseudonymEntitlementServerUrl_carrier_overrides">
+        <item><xliff:g id="carrier_id_prefix">:::1779:::</xliff:g>https://sentitlement2.mobile.att.net/WFC</item>
+    </string-array>
+</resources>
diff --git a/service/ServiceWifiResources/res/values-mcc313-mnc100/config.xml b/service/ServiceWifiResources/res/values-mcc313-mnc100/config.xml
new file mode 100644
index 0000000..83b0368
--- /dev/null
+++ b/service/ServiceWifiResources/res/values-mcc313-mnc100/config.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2023 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string-array translatable="false" name="config_wifiOobPseudonymEnabled_carrier_overrides">
+        <item><xliff:g id="carrier_id_prefix">:::2119:::</xliff:g>true</item>
+    </string-array>
+
+    <!-- Carrier specific override for the URL of entitlement server retrieving OOB pseudonym. -->
+    <string-array translatable="false" name="config_wifiOobPseudonymEntitlementServerUrl_carrier_overrides">
+        <item><xliff:g id="carrier_id_prefix">:::2119:::</xliff:g>https://sentitlement2.mobile.att.net/WFC</item>
+    </string-array>
+</resources>
diff --git a/service/ServiceWifiResources/res/values-mcc313-mnc130 b/service/ServiceWifiResources/res/values-mcc313-mnc130
new file mode 120000
index 0000000..2d21ee5
--- /dev/null
+++ b/service/ServiceWifiResources/res/values-mcc313-mnc130
@@ -0,0 +1 @@
+values-mcc313-mnc100
\ No newline at end of file
diff --git a/service/ServiceWifiResources/res/values-zu/strings.xml b/service/ServiceWifiResources/res/values-zu/strings.xml
index d8e04f0..5820703 100644
--- a/service/ServiceWifiResources/res/values-zu/strings.xml
+++ b/service/ServiceWifiResources/res/values-zu/strings.xml
@@ -64,11 +64,11 @@
     <string name="dlg_ok" msgid="254496739491689405">"KULUNGILE"</string>
     <string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"Ayikwazi ukuxhumeka ku-<xliff:g id="SSID">%1$s</xliff:g>"</string>
     <string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"Thepha ukuze ushintshe izilungiselelo zobumfihlo uphinde uzame futhi"</string>
-    <string name="wifi_disable_mac_randomization_dialog_title" msgid="2054540994993681606">"Shintsha isilungiselelo sobumfihlo?"</string>
+    <string name="wifi_disable_mac_randomization_dialog_title" msgid="2054540994993681606">"Shintsha isethingi yobumfihlo?"</string>
     <string name="wifi_disable_mac_randomization_dialog_message" msgid="8874064864332248988">"Ukuze uxhume, i-<xliff:g id="SSID">%1$s</xliff:g> idinga ukusebenzisa ikheli lakho ledivayisi ye-MAC, inkomba ehlukile. Okwamanje, izilungiselelo zemfihlo yakho ngale nethiwekhi zisebenzisa inkomba engahleliwe. \n\nLokhu kungavumela indawo yedivayisi yakho ukuthi ilandelelwe amadivayisi aseduze."</string>
-    <string name="wifi_disable_mac_randomization_dialog_confirm_text" msgid="6954419863076751626">"Shintsha isilungiselelo"</string>
-    <string name="wifi_disable_mac_randomization_dialog_success" msgid="5849155828154391387">"Isilungiselelo sibuyekeziwe. Zama ukuxhuma futhi."</string>
-    <string name="wifi_disable_mac_randomization_dialog_failure" msgid="2894643619143813096">"Ayikwazi ukushintsha isilungiselelo sobumfihlo"</string>
+    <string name="wifi_disable_mac_randomization_dialog_confirm_text" msgid="6954419863076751626">"Shintsha isethingi"</string>
+    <string name="wifi_disable_mac_randomization_dialog_success" msgid="5849155828154391387">"Isethingi sibuyekeziwe. Zama ukuxhuma futhi."</string>
+    <string name="wifi_disable_mac_randomization_dialog_failure" msgid="2894643619143813096">"Ayikwazi ukushintsha isethingi yobumfihlo"</string>
     <string name="wifi_disable_mac_randomization_dialog_network_not_found" msgid="7359256966900782004">"Inethiwekhi ayitholiwe"</string>
     <string name="wifi_eap_error_message_code_32756" msgid="2620877003804313434">"<xliff:g id="SSID">%1$s</xliff:g> : Iphutha lokugunyaza le-EAP 32756"</string>
     <!-- no translation found for wifi_eap_error_message_code_32756_carrier_overrides:0 (9114567205305206743) -->
diff --git a/service/ServiceWifiResources/res/values/config.xml b/service/ServiceWifiResources/res/values/config.xml
index 0e57ea8..ab73f3a 100644
--- a/service/ServiceWifiResources/res/values/config.xml
+++ b/service/ServiceWifiResources/res/values/config.xml
@@ -1316,6 +1316,9 @@
     <!-- Boolean indicating whether the device supports d2d allowed control when infra STA is disabled  -->
     <bool translatable="false" name ="config_wifiD2dAllowedControlSupportedWhenInfraStaDisabled">false</bool>
 
+    <!-- Boolean indicating whether the device supports WEP allowed control or not  -->
+    <bool translatable="false" name ="config_wifiWepAllowedControlSupported">true</bool>
+
     <!-- Array describing MAC OUI list to block TWT session setup request. If the primary station is
          connected to an AP with a MAC address OUI (https://standards-oui.ieee.org/oui/oui.txt)
          matching with any of entries in this blocked list, WifiManager#setupTwtSession() will fail
@@ -1330,4 +1333,13 @@
 
     <!-- Wi-Fi chip supports single link MLO SoftAp instances in the bridged mode -->
     <bool translatable="false" name="config_wifiSoftApSingleLinkMloInBridgedModeSupported">false</bool>
+
+    <!-- Boolean indicating whether Target Wake Time (TWT) feature is supported or not. This flag
+         overrides the device's TWT capability if set to false. If the device supports TWT and this
+         overlay parameter is set to false, the application cannot set up a TWT session. Also, the
+         API WifiManager#getTwtCapabilities returns TWT unsupported even if the device is capable
+         of setting up TWT session.
+    -->
+    <bool translatable="false" name="config_wifiTwtSupported">true</bool>
+
 </resources>
diff --git a/service/ServiceWifiResources/res/values/overlayable.xml b/service/ServiceWifiResources/res/values/overlayable.xml
index 421299d..e736668 100644
--- a/service/ServiceWifiResources/res/values/overlayable.xml
+++ b/service/ServiceWifiResources/res/values/overlayable.xml
@@ -343,6 +343,8 @@
           <item type="bool" name="config_wifiD2dAllowedControlSupportedWhenInfraStaDisabled" />
           <item type="array" name="config_wifiTwtBlockedOuiList" />
           <item type="bool" name="config_wifiSoftApSingleLinkMloInBridgedModeSupported" />
+          <item type="bool" name="config_wifiTwtSupported" />
+          <item type="bool" name="config_wifiWepAllowedControlSupported" />
 
           <!-- Params from config.xml that can be overlayed -->
 
diff --git a/service/java/com/android/server/wifi/ActiveModeWarden.java b/service/java/com/android/server/wifi/ActiveModeWarden.java
index 45bf103..fc6392c 100644
--- a/service/java/com/android/server/wifi/ActiveModeWarden.java
+++ b/service/java/com/android/server/wifi/ActiveModeWarden.java
@@ -411,18 +411,17 @@
 
         wifiNative.registerStatusListener(isReady -> {
             if (!isReady && !mIsShuttingdown) {
-                mHandler.post(() -> {
-                    Log.e(TAG, "One of the native daemons died. Triggering recovery");
-                    wifiDiagnostics.triggerBugReportDataCapture(
-                            WifiDiagnostics.REPORT_REASON_WIFINATIVE_FAILURE);
+                Log.e(TAG, "One of the native daemons died. Triggering recovery");
+                mWifiInjector.getWifiConfigManager().writeDataToStorage();
+                wifiDiagnostics.triggerBugReportDataCapture(
+                        WifiDiagnostics.REPORT_REASON_WIFINATIVE_FAILURE);
 
-                    // immediately trigger SelfRecovery if we receive a notice about an
-                    // underlying daemon failure
-                    // Note: SelfRecovery has a circular dependency with ActiveModeWarden and is
-                    // instantiated after ActiveModeWarden, so use WifiInjector to get the instance
-                    // instead of directly passing in SelfRecovery in the constructor.
+                // immediately trigger SelfRecovery if we receive a notice about an
+                // underlying daemon failure
+                // Note: SelfRecovery has a circular dependency with ActiveModeWarden and is
+                // instantiated after ActiveModeWarden, so use WifiInjector to get the instance
+                // instead of directly passing in SelfRecovery in the constructor.
                     mWifiInjector.getSelfRecovery().trigger(SelfRecovery.REASON_WIFINATIVE_FAILURE);
-                });
             }
         });
 
diff --git a/service/java/com/android/server/wifi/ClientModeImpl.java b/service/java/com/android/server/wifi/ClientModeImpl.java
index c331d55..913ac9b 100644
--- a/service/java/com/android/server/wifi/ClientModeImpl.java
+++ b/service/java/com/android/server/wifi/ClientModeImpl.java
@@ -2794,6 +2794,9 @@
          * set Tx link speed only if it is valid
          */
         if (newTxLinkSpeed > 0) {
+            if (newTxLinkSpeed != mWifiInfo.getTxLinkSpeedMbps() && SdkLevel.isAtLeastV()) {
+                updateNetworkCapabilities = true;
+            }
             mWifiInfo.setLinkSpeed(newTxLinkSpeed);
             mWifiInfo.setTxLinkSpeedMbps(newTxLinkSpeed);
         }
@@ -2801,6 +2804,9 @@
          * set Rx link speed only if it is valid
          */
         if (newRxLinkSpeed > 0) {
+            if (newRxLinkSpeed != mWifiInfo.getRxLinkSpeedMbps() && SdkLevel.isAtLeastV()) {
+                updateNetworkCapabilities = true;
+            }
             mWifiInfo.setRxLinkSpeedMbps(newRxLinkSpeed);
         }
         if (newFrequency > 0) {
diff --git a/service/java/com/android/server/wifi/DeviceConfigFacade.java b/service/java/com/android/server/wifi/DeviceConfigFacade.java
index 6116aae..ec5c4bf 100644
--- a/service/java/com/android/server/wifi/DeviceConfigFacade.java
+++ b/service/java/com/android/server/wifi/DeviceConfigFacade.java
@@ -220,6 +220,7 @@
     private boolean mSoftwarePnoEnabled;
     private boolean mIncludePasspointSsidsInPnoScans;
     private boolean mHandleRssiOrganicKernelFailuresEnabled;
+    private Set<String> mDisabledAutoBugreports = Collections.EMPTY_SET;
 
     private final Handler mWifiHandler;
 
@@ -421,6 +422,24 @@
                 "include_passpoint_ssids_in_pno_scans", true);
         mHandleRssiOrganicKernelFailuresEnabled = DeviceConfig.getBoolean(NAMESPACE,
                 "handle_rssi_organic_kernel_failures_enabled", true);
+        mDisabledAutoBugreports = getDisabledAutoBugreports();
+    }
+
+    private Set<String> getDisabledAutoBugreports() {
+        String rawList = DeviceConfig.getString(NAMESPACE,
+                "disabled_auto_bugreport_title_and_description", null);
+        if (rawList == null || rawList.isEmpty()) {
+            return Collections.EMPTY_SET;
+        }
+        Set<String> result = new ArraySet<>();
+        String[] list = rawList.split(",");
+        for (String cur : list) {
+            if (cur.length() == 0) {
+                continue;
+            }
+            result.add(cur);
+        }
+        return Collections.unmodifiableSet(result);
     }
 
     private Set<String> getUnmodifiableSetQuoted(String key) {
@@ -923,8 +942,7 @@
      * @return A Set of String to indicate disabled auto-bugreports trigger points.
      */
     public Set<String> getDisabledAutoBugreportTitleAndDetails() {
-        // TODO: b/336376991
-        return Collections.EMPTY_SET;
+        return mDisabledAutoBugreports;
     }
 
     public FeatureFlags getFeatureFlags() {
diff --git a/service/java/com/android/server/wifi/HalDeviceManager.java b/service/java/com/android/server/wifi/HalDeviceManager.java
index b5ff88a..99f929c 100644
--- a/service/java/com/android/server/wifi/HalDeviceManager.java
+++ b/service/java/com/android/server/wifi/HalDeviceManager.java
@@ -1114,7 +1114,6 @@
         dispatchRttControllerLifecycleOnDestroyed();
         mRttControllerLifecycleCallbacks.clear();
         mWifiP2pIfaces.clear();
-        mWifiInjector.getWifiConfigManager().writeDataToStorage();
     }
 
     private class WifiDeathRecipient implements WifiHal.DeathRecipient {
diff --git a/service/java/com/android/server/wifi/SoftApManager.java b/service/java/com/android/server/wifi/SoftApManager.java
index 619be54..a0ceb41 100644
--- a/service/java/com/android/server/wifi/SoftApManager.java
+++ b/service/java/com/android/server/wifi/SoftApManager.java
@@ -1873,11 +1873,6 @@
 
             @Override
             public void exitImpl() {
-                // Update state to WIFI_AP_STATE_DISABLED now in case the destroyed listeners
-                // trigger a call to WifiManager#startTetheredHotspot again (e.g. for downstream
-                // prefix conflict).
-                updateApState(WifiManager.WIFI_AP_STATE_DISABLED,
-                        WifiManager.WIFI_AP_STATE_DISABLING, 0);
                 if (!mIfaceIsDestroyed) {
                     stopSoftAp();
                 }
@@ -1916,6 +1911,9 @@
                         mSpecifiedModeConfiguration.getTargetMode(),
                         mDefaultShutdownTimeoutMillis,
                         isBridgeRequired());
+                updateApState(WifiManager.WIFI_AP_STATE_DISABLED,
+                        WifiManager.WIFI_AP_STATE_DISABLING, 0);
+
                 mSarManager.setSapWifiState(WifiManager.WIFI_AP_STATE_DISABLED);
 
                 mApInterfaceName = null;
diff --git a/service/java/com/android/server/wifi/TwtManager.java b/service/java/com/android/server/wifi/TwtManager.java
index 077cd15..2d1333f 100644
--- a/service/java/com/android/server/wifi/TwtManager.java
+++ b/service/java/com/android/server/wifi/TwtManager.java
@@ -97,12 +97,12 @@
     private final AlarmManager mAlarmManager;
     private final Handler mHandler;
     ArraySet<Integer> mBlockedOuiSet = new ArraySet<>();
-
     private final WifiNative mWifiNative;
     private final WifiNativeTwtEvents mWifiNativeTwtEvents;
     private final AlarmManager.OnAlarmListener mTimeoutListener = () -> {
         startGarbageCollector();
     };
+    private final WifiInjector mWifiInjector;
 
     /**
      * Whenever primary clientModeManager identified by the interface name gets disconnected, reset
@@ -121,6 +121,7 @@
     TwtManager(@NonNull WifiInjector wifiInjector, @NonNull ClientModeImplMonitor cmiMonitor,
             @NonNull WifiNative wifiNative, @NonNull Handler handler, @NonNull Clock clock,
             int maxSessions, int startOffset) {
+        mWifiInjector = wifiInjector;
         mAlarmManager = wifiInjector.getAlarmManager();
         mHandler = handler;
         mClock = clock;
@@ -483,7 +484,7 @@
     public void getTwtCapabilities(@Nullable String interfaceName,
             @NonNull ITwtCapabilitiesListener listener) {
         try {
-            if (interfaceName == null) {
+            if (interfaceName == null || !isTwtSupported()) {
                 listener.onResult(getDefaultTwtCapabilities());
                 return;
             }
@@ -506,6 +507,11 @@
      */
     public void setupTwtSession(@Nullable String interfaceName, @NonNull TwtRequest twtRequest,
             @NonNull ITwtCallback iTwtCallback, int callingUid, @NonNull String bssid) {
+        if (!isTwtSupported() || !isTwtCapable(interfaceName)) {
+            notifyFailure(iTwtCallback, CallbackType.SETUP,
+                    TwtSessionCallback.TWT_ERROR_CODE_NOT_SUPPORTED);
+            return;
+        }
         if (isOuiBlockListed(bssid)) {
             notifyFailure(iTwtCallback, CallbackType.SETUP,
                     TwtSessionCallback.TWT_ERROR_CODE_AP_OUI_BLOCKLISTED);
@@ -527,6 +533,18 @@
         }
     }
 
+    private boolean isTwtSupported() {
+        return mWifiInjector.getContext().getResources().getBoolean(
+                R.bool.config_wifiTwtSupported);
+    }
+
+    private boolean isTwtCapable(String interfaceName) {
+        if (interfaceName == null) return false;
+        Bundle twtCapabilities = mWifiNative.getTwtCapabilities(interfaceName);
+        if (twtCapabilities == null) return false;
+        return twtCapabilities.getBoolean(WifiManager.TWT_CAPABILITIES_KEY_BOOLEAN_TWT_REQUESTER);
+    }
+
     private boolean isOuiBlockListed(@NonNull String bssid) {
         if (mBlockedOuiSet.isEmpty()) return false;
         byte[] macBytes = MacAddress.fromString(bssid).toByteArray();
diff --git a/service/java/com/android/server/wifi/WifiDeviceStateChangeManager.java b/service/java/com/android/server/wifi/WifiDeviceStateChangeManager.java
index 5fa82fe..74df0a5 100644
--- a/service/java/com/android/server/wifi/WifiDeviceStateChangeManager.java
+++ b/service/java/com/android/server/wifi/WifiDeviceStateChangeManager.java
@@ -66,16 +66,15 @@
                     @Override
                     public void onReceive(Context context, Intent intent) {
                         String action = intent.getAction();
-                        if (TextUtils.equals(action, Intent.ACTION_SCREEN_ON)) {
-                            handleScreenStateChanged(true);
-                        } else if (TextUtils.equals(action, Intent.ACTION_SCREEN_OFF)) {
-                            handleScreenStateChanged(false);
+                        if (TextUtils.equals(action, Intent.ACTION_SCREEN_ON)
+                                || TextUtils.equals(action, Intent.ACTION_SCREEN_OFF)) {
+                            mHandler.post(() ->
+                                    handleScreenStateChanged(TextUtils.equals(action,
+                                            Intent.ACTION_SCREEN_ON)));
                         }
                     }
                 },
-                filter,
-                null,
-                mHandler);
+                filter);
         handleScreenStateChanged(mPowerManager.isInteractive());
         mIsWifiServiceStarted = true;
     }
diff --git a/service/java/com/android/server/wifi/WifiGlobals.java b/service/java/com/android/server/wifi/WifiGlobals.java
index 098c3c7..6aa2d27 100644
--- a/service/java/com/android/server/wifi/WifiGlobals.java
+++ b/service/java/com/android/server/wifi/WifiGlobals.java
@@ -86,6 +86,7 @@
     private boolean mIsBackgroundScanSupported;
     private boolean mIsSwPnoEnabled;
     private boolean mIsWepDeprecated;
+    private boolean mWepAllowedControlSupported;
     private final boolean mIsWpaPersonalDeprecated;
     private final Map<String, List<String>> mCountryCodeToAfcServers;
     private final long mWifiConfigMaxDisableDurationMs;
@@ -166,6 +167,8 @@
                 .getBoolean(R.bool.config_wifiSwPnoEnabled);
         mIsWepDeprecated = mContext.getResources()
                 .getBoolean(R.bool.config_wifiWepDeprecated);
+        mWepAllowedControlSupported = mContext.getResources()
+                .getBoolean(R.bool.config_wifiWepAllowedControlSupported);
         mIsWpaPersonalDeprecated = mContext.getResources()
                 .getBoolean(R.bool.config_wifiWpaPersonalDeprecated);
         mIsAfcSupportedOnDevice = mContext.getResources().getBoolean(R.bool.config_wifiAfcSupported)
@@ -383,7 +386,7 @@
      * @return boolean true if WEP networks are deprecated, false otherwise.
      */
     public boolean isWepDeprecated() {
-        return mIsWepDeprecated || !mIsWepAllowed.get();
+        return mIsWepDeprecated || (mWepAllowedControlSupported && !mIsWepAllowed.get());
     }
 
     /**
@@ -753,6 +756,7 @@
         pw.println("mIsWepDeprecated=" + mIsWepDeprecated);
         pw.println("mIsWpaPersonalDeprecated=" + mIsWpaPersonalDeprecated);
         pw.println("mIsWepAllowed=" + mIsWepAllowed.get());
+        pw.println("mWepAllowedControlSupported=" + mWepAllowedControlSupported);
         pw.println("mDisableFirmwareRoamingInIdleMode=" + mDisableFirmwareRoamingInIdleMode);
         pw.println("mRepeatedNudFailuresThreshold=" + mRepeatedNudFailuresThreshold);
         pw.println("mRepeatedNudFailuresWindowMs=" + mRepeatedNudFailuresWindowMs);
diff --git a/service/java/com/android/server/wifi/WifiNative.java b/service/java/com/android/server/wifi/WifiNative.java
index 1ae14b3..9ec97ee 100644
--- a/service/java/com/android/server/wifi/WifiNative.java
+++ b/service/java/com/android/server/wifi/WifiNative.java
@@ -932,11 +932,11 @@
     private class VendorHalDeathHandlerInternal implements VendorHalDeathEventHandler {
         @Override
         public void onDeath() {
-            synchronized (mLock) {
+            mHandler.post(() -> {
                 Log.i(TAG, "Vendor HAL died. Cleaning up internal state.");
                 onNativeDaemonDeath();
                 mWifiMetrics.incrementNumHalCrashes();
-            }
+            });
         }
     }
 
@@ -947,11 +947,9 @@
         @Override
         public void run() {
             mHandler.post(() -> {
-                synchronized (mLock) {
-                    Log.i(TAG, "wificond died. Cleaning up internal state.");
-                    onNativeDaemonDeath();
-                    mWifiMetrics.incrementNumWificondCrashes();
-                }
+                Log.i(TAG, "wificond died. Cleaning up internal state.");
+                onNativeDaemonDeath();
+                mWifiMetrics.incrementNumWificondCrashes();
             });
         }
     }
@@ -963,11 +961,9 @@
         @Override
         public void onDeath() {
             mHandler.post(() -> {
-                synchronized (mLock) {
-                    Log.i(TAG, "wpa_supplicant died. Cleaning up internal state.");
-                    onNativeDaemonDeath();
-                    mWifiMetrics.incrementNumSupplicantCrashes();
-                }
+                Log.i(TAG, "wpa_supplicant died. Cleaning up internal state.");
+                onNativeDaemonDeath();
+                mWifiMetrics.incrementNumSupplicantCrashes();
             });
         }
     }
@@ -978,11 +974,11 @@
     private class HostapdDeathHandlerInternal implements HostapdDeathEventHandler {
         @Override
         public void onDeath() {
-            synchronized (mLock) {
+            mHandler.post(() -> {
                 Log.i(TAG, "hostapd died. Cleaning up internal state.");
                 onNativeDaemonDeath();
                 mWifiMetrics.incrementNumHostapdCrashes();
-            }
+            });
         }
     }
 
diff --git a/service/java/com/android/server/wifi/WifiNetworkFactory.java b/service/java/com/android/server/wifi/WifiNetworkFactory.java
index 9d471a6..dc58ee4 100644
--- a/service/java/com/android/server/wifi/WifiNetworkFactory.java
+++ b/service/java/com/android/server/wifi/WifiNetworkFactory.java
@@ -1439,12 +1439,8 @@
             mConnectedSpecificNetworkRequestSpecifier = mActiveSpecificNetworkRequestSpecifier;
             mConnectedUids.clear();
         }
-        if (mActiveSpecificNetworkRequest.getRequestorUid() == 0) {
-            // For shell test call from root
-            mConnectedUids.add(Process.SYSTEM_UID);
-        } else {
-            mConnectedUids.add(mActiveSpecificNetworkRequest.getRequestorUid());
-        }
+
+        mConnectedUids.add(mActiveSpecificNetworkRequest.getRequestorUid());
         mActiveSpecificNetworkRequest = null;
         mActiveSpecificNetworkRequestSpecifier = null;
         mSkipUserDialogue = false;
diff --git a/service/java/com/android/server/wifi/WifiNetworkSelector.java b/service/java/com/android/server/wifi/WifiNetworkSelector.java
index 358593d..12598a5 100644
--- a/service/java/com/android/server/wifi/WifiNetworkSelector.java
+++ b/service/java/com/android/server/wifi/WifiNetworkSelector.java
@@ -1104,6 +1104,11 @@
                 || isNetworkSelectionNeeded(cmmStates);
         final String userConnectChoiceKey;
         if (!networkSelectionNeeded) {
+            if (!isAssociatedNetworkSelectionEnabled()) {
+                // Skip network selection based on connect choice because associated network
+                // selection is disabled.
+                return null;
+            }
             userConnectChoiceKey = getConnectChoiceKey(cmmStates);
             if (userConnectChoiceKey == null) {
                 return null;
@@ -1437,6 +1442,7 @@
                 .getConfiguredNetworkWithPassword(config.networkId);
         if (configWithPassword.isSecurityType(WifiConfiguration.SECURITY_TYPE_PSK)
                 && configWithPassword.isSecurityType(WifiConfiguration.SECURITY_TYPE_SAE)
+                && configWithPassword.preSharedKey != null
                 && !configWithPassword.preSharedKey.startsWith("\"")
                 && configWithPassword.preSharedKey.length() == 64
                 && configWithPassword.preSharedKey.matches("[0-9A-Fa-f]{64}")) {
diff --git a/service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java b/service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java
index 5aa7c2b..ec18b6b 100644
--- a/service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java
+++ b/service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java
@@ -379,7 +379,8 @@
             config.shared = false;
             config.allowAutojoin = isAutojoinEnabled;
             if (config.enterpriseConfig
-                    != null && config.enterpriseConfig.isAuthenticationSimBased()) {
+                    != null && config.enterpriseConfig.isAuthenticationSimBased()
+                    && anonymousIdentity != null) {
                 config.enterpriseConfig.setAnonymousIdentity(anonymousIdentity);
             }
             config.getNetworkSelectionStatus().setConnectChoice(connectChoice);
diff --git a/service/java/com/android/server/wifi/WifiServiceImpl.java b/service/java/com/android/server/wifi/WifiServiceImpl.java
index 6eb95e9..1796e4b 100644
--- a/service/java/com/android/server/wifi/WifiServiceImpl.java
+++ b/service/java/com/android/server/wifi/WifiServiceImpl.java
@@ -6697,7 +6697,10 @@
     public void connect(WifiConfiguration config, int netId, @Nullable IActionListener callback,
             @NonNull String packageName, Bundle extras) {
         int uid = getMockableCallingUid();
-        if (!isPrivileged(Binder.getCallingPid(), uid)) {
+        if (!isPrivileged(Binder.getCallingPid(), uid)
+                // TODO(b/343881335): Longer term, we need a specific permission
+                // for NFC.
+                && UserHandle.getAppId(uid) != Process.NFC_UID) {
             throw new SecurityException(TAG + ": Permission denied");
         }
         if (packageName == null) {
diff --git a/service/java/com/android/server/wifi/WifiShellCommand.java b/service/java/com/android/server/wifi/WifiShellCommand.java
index a01f72b..a8ae7cc 100644
--- a/service/java/com/android/server/wifi/WifiShellCommand.java
+++ b/service/java/com/android/server/wifi/WifiShellCommand.java
@@ -553,8 +553,10 @@
                 case "network-suggestions-set-user-approved": {
                     String packageName = getNextArgRequired();
                     boolean approved = getNextArgRequiredTrueOrFalse("yes", "no");
-                    mWifiNetworkSuggestionsManager.setHasUserApprovedForApp(approved,
-                            Binder.getCallingUid(), packageName);
+                    mWifiThreadRunner.post(() -> mWifiNetworkSuggestionsManager
+                            .setHasUserApprovedForApp(approved,
+                                    Binder.getCallingUid(), packageName),
+                            "shell#setHasUserApprovedForApp");
                     return 0;
                 }
                 case "network-suggestions-has-user-approved": {
@@ -1220,7 +1222,10 @@
                     ConnectivityManager.NetworkCallback networkCallback =
                             new ConnectivityManager.NetworkCallback();
                     pw.println("Adding request: " + networkRequest);
-                    mConnectivityManager.requestNetwork(networkRequest, networkCallback);
+                    mWifiThreadRunner.post(() -> mConnectivityManager
+                                    .requestNetwork(networkRequest, networkCallback),
+                            "shell#add-request");
+
                     sActiveRequests.put(ssid, Pair.create(networkRequest, networkCallback));
                     return 0;
                 }
@@ -1233,7 +1238,10 @@
                         return -1;
                     }
                     pw.println("Removing request: " + nrAndNc.first);
-                    mConnectivityManager.unregisterNetworkCallback(nrAndNc.second);
+                    mWifiThreadRunner.post(() -> mConnectivityManager
+                                    .unregisterNetworkCallback(nrAndNc.second),
+                            "shell#remove-request")
+                    ;
                     return 0;
                 }
                 case "remove-all-requests":
diff --git a/service/java/com/android/server/wifi/hotspot2/PasspointProvider.java b/service/java/com/android/server/wifi/hotspot2/PasspointProvider.java
index de0be19..d000db5 100644
--- a/service/java/com/android/server/wifi/hotspot2/PasspointProvider.java
+++ b/service/java/com/android/server/wifi/hotspot2/PasspointProvider.java
@@ -351,7 +351,8 @@
 
         // Install the client private key & certificate.
         if (mConfig.getCredential().getClientPrivateKey() != null
-                && mConfig.getCredential().getClientCertificateChain() != null) {
+                && mConfig.getCredential().getClientCertificateChain() != null
+                && mConfig.getCredential().getCertCredential() != null) {
             String keyName = ALIAS_HS_TYPE + mProviderId;
             PrivateKey clientKey = mConfig.getCredential().getClientPrivateKey();
             X509Certificate clientCert = getClientCertificate(
diff --git a/service/java/com/android/server/wifi/hotspot2/PasspointProvisioner.java b/service/java/com/android/server/wifi/hotspot2/PasspointProvisioner.java
index 646349f..08be762 100644
--- a/service/java/com/android/server/wifi/hotspot2/PasspointProvisioner.java
+++ b/service/java/com/android/server/wifi/hotspot2/PasspointProvisioner.java
@@ -77,7 +77,7 @@
     private static final int PROVISIONING_FAILURE = 1;
 
     // TLS version to be used for HTTPS connection with OSU server
-    private static final String TLS_VERSION = "TLSv1";
+    private static final String TLS_VERSION = "TLS";
 
     private final Context mContext;
     private final ProvisioningStateMachine mProvisioningStateMachine;
diff --git a/service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java b/service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java
index 6989411..e004bc4 100644
--- a/service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java
+++ b/service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java
@@ -1519,7 +1519,7 @@
                         }
                         if (wifistate == WifiManager.WIFI_STATE_ENABLED
                                 || wifistate == WifiManager.WIFI_STATE_DISABLING) {
-                            checkAndSendP2pStateChangedBroadcast();
+                            getHandler().post(() -> checkAndSendP2pStateChangedBroadcast());
                         }
                     }
                 }, new IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION));
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 c0fbf6b..78f28fb 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/ActiveModeWardenTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/ActiveModeWardenTest.java
@@ -189,6 +189,7 @@
     @Mock LastCallerInfoManager mLastCallerInfoManager;
     @Mock WifiGlobals mWifiGlobals;
     @Mock WifiConnectivityManager mWifiConnectivityManager;
+    @Mock WifiConfigManager mWifiConfigManager;
 
     Listener<ConcreteClientModeManager> mClientListener;
     Listener<SoftApManager> mSoftApListener;
@@ -222,6 +223,7 @@
         when(mWifiInjector.getUserManager()).thenReturn(mUserManager);
         when(mWifiInjector.getWifiHandlerLocalLog()).thenReturn(mLocalLog);
         when(mWifiInjector.getWifiConnectivityManager()).thenReturn(mWifiConnectivityManager);
+        when(mWifiInjector.getWifiConfigManager()).thenReturn(mWifiConfigManager);
         when(mClientModeManager.getRole()).thenReturn(ROLE_CLIENT_PRIMARY);
         when(mClientModeManager.getInterfaceName()).thenReturn(WIFI_IFACE_NAME);
         when(mContext.getResources()).thenReturn(mResources);
@@ -1178,6 +1180,7 @@
         verify(mWifiDiagnostics).triggerBugReportDataCapture(
                 WifiDiagnostics.REPORT_REASON_WIFINATIVE_FAILURE);
         verify(mSelfRecovery).trigger(eq(SelfRecovery.REASON_WIFINATIVE_FAILURE));
+        verify(mWifiConfigManager).writeDataToStorage();
     }
 
     /**
@@ -1191,6 +1194,7 @@
         verify(mWifiDiagnostics, never()).triggerBugReportDataCapture(
                 WifiDiagnostics.REPORT_REASON_WIFINATIVE_FAILURE);
         verify(mSelfRecovery, never()).trigger(eq(SelfRecovery.REASON_WIFINATIVE_FAILURE));
+        verify(mWifiConfigManager, never()).writeDataToStorage();
     }
 
     /**
@@ -1203,6 +1207,7 @@
         verify(mWifiDiagnostics, never()).triggerBugReportDataCapture(
                 WifiDiagnostics.REPORT_REASON_WIFINATIVE_FAILURE);
         verify(mSelfRecovery, never()).trigger(eq(SelfRecovery.REASON_WIFINATIVE_FAILURE));
+        verify(mWifiConfigManager, never()).writeDataToStorage();
     }
 
     /**
diff --git a/service/tests/wifitests/src/com/android/server/wifi/DeviceConfigFacadeTest.java b/service/tests/wifitests/src/com/android/server/wifi/DeviceConfigFacadeTest.java
index 9353e6a..04536b8 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/DeviceConfigFacadeTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/DeviceConfigFacadeTest.java
@@ -19,6 +19,7 @@
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.*;
 
 import android.app.test.MockAnswerUtil.AnswerWithArguments;
@@ -234,6 +235,8 @@
         assertEquals(false, mDeviceConfigFacade.isAdjustPollRssiIntervalEnabled());
         assertEquals(true, mDeviceConfigFacade.includePasspointSsidsInPnoScans());
         assertEquals(true, mDeviceConfigFacade.isHandleRssiOrganicKernelFailuresEnabled());
+        assertEquals(Collections.EMPTY_SET,
+                mDeviceConfigFacade.getDisabledAutoBugreportTitleAndDetails());
     }
 
     /**
@@ -376,6 +379,9 @@
                 anyBoolean())).thenReturn(true);
         when(DeviceConfig.getBoolean(anyString(), eq("handle_rssi_organic_kernel_failures_enabled"),
                 anyBoolean())).thenReturn(true);
+        when(DeviceConfig.getString(anyString(),
+                eq("disabled_auto_bugreport_title_and_description"), any()))
+                .thenReturn("TITLE_1DETAIL_1,TITLE_2DETAIL_2");
         mOnPropertiesChangedListenerCaptor.getValue().onPropertiesChanged(null);
 
         // Verifying fields are updated to the new values
@@ -449,6 +455,11 @@
         assertEquals(true, mDeviceConfigFacade.isAdjustPollRssiIntervalEnabled());
         assertEquals(true, mDeviceConfigFacade.includePasspointSsidsInPnoScans());
         assertEquals(true, mDeviceConfigFacade.isHandleRssiOrganicKernelFailuresEnabled());
+        Set<String> disabledAutoBugreports =
+                mDeviceConfigFacade.getDisabledAutoBugreportTitleAndDetails();
+        assertEquals(2, disabledAutoBugreports.size());
+        assertTrue(disabledAutoBugreports.contains("TITLE_1DETAIL_1"));
+        assertTrue(disabledAutoBugreports.contains("TITLE_2DETAIL_2"));
 
         when(DeviceConfig.getBoolean(anyString(), eq("oob_pseudonym_enabled"),
                 anyBoolean())).thenReturn(false);
diff --git a/service/tests/wifitests/src/com/android/server/wifi/HalDeviceManagerTest.java b/service/tests/wifitests/src/com/android/server/wifi/HalDeviceManagerTest.java
index 67293df..36e54b0 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/HalDeviceManagerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/HalDeviceManagerTest.java
@@ -138,7 +138,6 @@
     @Mock private WorkSourceHelper mWorkSourceHelper1;
     @Mock private WorkSourceHelper mWorkSourceHelper2;
     @Mock private DeviceConfigFacade mDeviceConfigFacade;
-    @Mock private WifiConfigManager mWifiConfigManager;
     @Mock private FeatureFlags mFeatureFlags;
     private TestLooper mTestLooper;
     private Handler mHandler;
@@ -176,7 +175,6 @@
         mHandler = new Handler(mTestLooper.getLooper());
 
         when(mWifiInjector.getInterfaceConflictManager()).thenReturn(mInterfaceConflictManager);
-        when(mWifiInjector.getWifiConfigManager()).thenReturn(mWifiConfigManager);
         when(mInterfaceConflictManager.needsUserApprovalToDelete(anyInt(), any(), anyInt(), any()))
                 .thenReturn(false);
         when(mWifiInjector.makeWsHelper(TEST_WORKSOURCE_0)).thenReturn(mWorkSourceHelper0);
@@ -250,7 +248,6 @@
         // verify: onStop called
         mInOrder.verify(mWifiMock).stop();
         mInOrder.verify(mManagerStatusListenerMock).onStatusChanged();
-        verify(mWifiConfigManager).writeDataToStorage();
 
         verifyNoMoreInteractions(mManagerStatusListenerMock);
     }
@@ -303,7 +300,6 @@
 
         // verify: getting onStop
         mInOrder.verify(mManagerStatusListenerMock).onStatusChanged();
-        verify(mWifiConfigManager).writeDataToStorage();
 
         // act: start
         collector.checkThat(mDut.start(), equalTo(true));
diff --git a/service/tests/wifitests/src/com/android/server/wifi/TwtManagerTest.java b/service/tests/wifitests/src/com/android/server/wifi/TwtManagerTest.java
index 6bcc9c5..79db9d4 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/TwtManagerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/TwtManagerTest.java
@@ -118,11 +118,20 @@
                 {TEST_BLOCKED_OUI_4, TEST_BLOCKED_OUI_3, TEST_BLOCKED_OUI_2, TEST_BLOCKED_OUI_1};
         when(mResources.getIntArray(R.array.config_wifiTwtBlockedOuiList)).thenReturn(
                 blockedOuiList);
+        when(mResources.getBoolean(R.bool.config_wifiTwtSupported)).thenReturn(true);
         mTwtManager = new TwtManager(mWifiInjector, mCmiMonitor, mWifiNative, mHandler, mClock,
                 WifiTwtSession.MAX_TWT_SESSIONS, TWT_CALLBACKS_ID_START_OFFSET);
         verify(mCmiMonitor).registerListener(mCmiListenerCaptor.capture());
         mTwtManager.registerWifiNativeTwtEvents();
         verify(mWifiNative).registerTwtCallbacks(mWifiNativeTwtEventsArgumentCaptor.capture());
+        when(mWifiNative.getTwtCapabilities(eq(WIFI_IFACE_NAME))).thenReturn(
+                getMockTwtCapabilities());
+    }
+
+    private void disableTwtSupport() {
+        when(mResources.getBoolean(R.bool.config_wifiTwtSupported)).thenReturn(false);
+        mTwtManager = new TwtManager(mWifiInjector, mCmiMonitor, mWifiNative, mHandler, mClock,
+                WifiTwtSession.MAX_TWT_SESSIONS, TWT_CALLBACKS_ID_START_OFFSET);
     }
 
     private Bundle getDefaultTwtCapabilities() {
@@ -199,6 +208,11 @@
         mTwtManager.getTwtCapabilities(WIFI_IFACE_NAME, iTwtCapabilitiesListener);
         inorder.verify(iTwtCapabilitiesListener).onResult(
                 argThat(argument -> isBundleContentEqual(mockTwtCapabilities, argument)));
+        // Disable overlay and test
+        disableTwtSupport();
+        mTwtManager.getTwtCapabilities(WIFI_IFACE_NAME, iTwtCapabilitiesListener);
+        inorder.verify(iTwtCapabilitiesListener).onResult(
+                argThat(argument -> isBundleContentEqual(defaultTwtCapabilities, argument)));
     }
 
     @Test
@@ -227,7 +241,7 @@
         mTwtManager.setupTwtSession(null, twtRequest, iTwtCallback, Binder.getCallingUid(),
                 TEST_BSSID);
         inOrderCallback.verify(iTwtCallback).onFailure(
-                TwtSessionCallback.TWT_ERROR_CODE_NOT_AVAILABLE);
+                TwtSessionCallback.TWT_ERROR_CODE_NOT_SUPPORTED);
         // Test when wifiNative.setupTwtSession return false
         when(mWifiNative.setupTwtSession(eq(1), eq(WIFI_IFACE_NAME), eq(twtRequest))).thenReturn(
                 false);
@@ -248,6 +262,28 @@
         inOrderBinder.verify(mAppBinder).linkToDeath(any(IBinder.DeathRecipient.class), anyInt());
         inOrderAlarm.verify(mAlarmManager).set(eq(AlarmManager.ELAPSED_REALTIME), anyLong(),
                 anyString(), any(AlarmManager.OnAlarmListener.class), eq(mHandler));
+        // Enable overlay, disable TWT capability, and test
+        when(mWifiNative.getTwtCapabilities(eq(WIFI_IFACE_NAME))).thenReturn(
+                getDefaultTwtCapabilities());
+        mTwtManager.setupTwtSession(WIFI_IFACE_NAME, twtRequest, iTwtCallback,
+                Binder.getCallingUid(), TEST_BSSID);
+        inOrderCallback.verify(iTwtCallback).onFailure(
+                TwtSessionCallback.TWT_ERROR_CODE_NOT_SUPPORTED);
+        // Disable overlay, enable TWT capability, and test
+        when(mWifiNative.getTwtCapabilities(eq(WIFI_IFACE_NAME))).thenReturn(
+                getMockTwtCapabilities());
+        disableTwtSupport();
+        mTwtManager.setupTwtSession(WIFI_IFACE_NAME, twtRequest, iTwtCallback,
+                Binder.getCallingUid(), TEST_BSSID);
+        inOrderCallback.verify(iTwtCallback).onFailure(
+                TwtSessionCallback.TWT_ERROR_CODE_NOT_SUPPORTED);
+        // Disable overlay, disable TWT capability, and test
+        when(mWifiNative.getTwtCapabilities(eq(WIFI_IFACE_NAME))).thenReturn(
+                getDefaultTwtCapabilities());
+        mTwtManager.setupTwtSession(WIFI_IFACE_NAME, twtRequest, iTwtCallback,
+                Binder.getCallingUid(), TEST_BSSID);
+        inOrderCallback.verify(iTwtCallback).onFailure(
+                TwtSessionCallback.TWT_ERROR_CODE_NOT_SUPPORTED);
     }
 
     @Test
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiDeviceStateChangeManagerTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiDeviceStateChangeManagerTest.java
index ed4910a..95eac5f 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiDeviceStateChangeManagerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiDeviceStateChangeManagerTest.java
@@ -74,7 +74,7 @@
         verify(mStateChangeCallback, never()).onScreenStateChanged(anyBoolean());
         mWifiDeviceStateChangeManager.handleBootCompleted();
         verify(mContext, atLeastOnce())
-                .registerReceiver(mBroadcastReceiverCaptor.capture(), any(), any(), any());
+                .registerReceiver(mBroadcastReceiverCaptor.capture(), any());
         verify(mStateChangeCallback).onScreenStateChanged(true);
         reset(mStateChangeCallback);
         setScreenState(true);
@@ -91,7 +91,7 @@
     public void testRegisterAfterBootCompleted() {
         mWifiDeviceStateChangeManager.handleBootCompleted();
         verify(mContext, atLeastOnce())
-                .registerReceiver(mBroadcastReceiverCaptor.capture(), any(), any(), any());
+                .registerReceiver(mBroadcastReceiverCaptor.capture(), any());
         mWifiDeviceStateChangeManager.registerStateChangeCallback(mStateChangeCallback);
         // Register after boot completed should immediately get a callback
         verify(mStateChangeCallback).onScreenStateChanged(true);
@@ -102,5 +102,6 @@
         assertNotNull(broadcastReceiver);
         Intent intent = new Intent(screenOn ? ACTION_SCREEN_ON : ACTION_SCREEN_OFF);
         broadcastReceiver.onReceive(mContext, intent);
+        mLooper.dispatchAll();
     }
 }
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiGlobalsTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiGlobalsTest.java
index 3a29bbf..9e48383 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiGlobalsTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiGlobalsTest.java
@@ -277,6 +277,8 @@
 
     @Test
     public void testSetWepAllowedWhenWepIsNotDeprecated() {
+        mResources.setBoolean(R.bool.config_wifiWepAllowedControlSupported, true);
+        mWifiGlobals = new WifiGlobals(mContext);
         assertTrue(mWifiGlobals.isWepSupported());
         // Default is not allow
         assertFalse(mWifiGlobals.isWepAllowed());
@@ -288,6 +290,15 @@
         mWifiGlobals.setWepAllowed(false);
         assertTrue(mWifiGlobals.isWepDeprecated());
         assertFalse(mWifiGlobals.isWepAllowed());
+
+        // Test WEP allowed control is NOT supported.
+        mResources.setBoolean(R.bool.config_wifiWepAllowedControlSupported, false);
+        mWifiGlobals = new WifiGlobals(mContext);
+        // Default is not allow, but don't care it since control is not supported.
+        assertFalse(mWifiGlobals.isWepAllowed());
+        // But we won't consider WEP is allowed since control is NOT supported.
+        // So WEP should be NOT deprecated since config_wifiWepDeprecated is false.
+        assertFalse(mWifiGlobals.isWepDeprecated());
     }
 
 
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiNativeInterfaceManagementTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiNativeInterfaceManagementTest.java
index 99d46b3..0fcc471 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiNativeInterfaceManagementTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiNativeInterfaceManagementTest.java
@@ -929,6 +929,7 @@
         // Trigger vendor HAL death
 
         mWifiVendorHalDeathHandlerCaptor.getValue().onDeath();
+        mLooper.dispatchAll();
 
         mInOrder.verify(mWifiMetrics).incrementNumHalCrashes();
 
@@ -976,6 +977,7 @@
 
         // Trigger vendor HAL death
         mHostapdDeathHandlerCaptor.getValue().onDeath();
+        mLooper.dispatchAll();
 
         mInOrder.verify(mWifiMetrics).incrementNumHostapdCrashes();
 
@@ -1005,6 +1007,7 @@
 
         // Trigger vendor HAL death
         mHostapdDeathHandlerCaptor.getValue().onDeath();
+        mLooper.dispatchAll();
 
         mInOrder.verify(mWifiMetrics).incrementNumHostapdCrashes();
 
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 47b105f..d5e1023 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiNetworkSelectorTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiNetworkSelectorTest.java
@@ -2760,6 +2760,13 @@
                 false);
         // Candidate should not be null
         assertNotNull(candidates);
+
+        // disable associated network selection and verify no candidate is returned now
+        doReturn(false).when(mResource).getBoolean(
+                R.bool.config_wifi_framework_enable_associated_network_selection);
+        assertNull(mWifiNetworkSelector.getCandidatesFromScan(
+                scanDetails, blocklist, cmmStates, false, true, true, Collections.emptySet(),
+                false));
     }
 
     private void runNetworkSelectionWith(ScanDetailsAndWifiConfigs scanDetailsAndConfigs) {
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiNetworkSuggestionsManagerTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiNetworkSuggestionsManagerTest.java
index 00ac355..1cfa894 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiNetworkSuggestionsManagerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiNetworkSuggestionsManagerTest.java
@@ -34,6 +34,7 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assume.assumeFalse;
 import static org.junit.Assume.assumeTrue;
@@ -4974,6 +4975,7 @@
                 .thenReturn(true);
         WifiConfiguration eapSimConfig = WifiConfigurationTestUtil.createWpa2Wpa3EnterpriseNetwork(
                 WifiEnterpriseConfig.Eap.SIM, WifiEnterpriseConfig.Phase2.NONE);
+        eapSimConfig.enterpriseConfig.setAnonymousIdentity(TEST_ANONYMOUS_IDENTITY);
         WifiNetworkSuggestion networkSuggestion = createWifiNetworkSuggestion(
                 new WifiConfiguration(eapSimConfig), null, false, false, true, true,
                 DEFAULT_PRIORITY_GROUP);
@@ -4993,14 +4995,25 @@
         configuration.creatorUid = TEST_UID_1;
         configuration.enterpriseConfig.setAnonymousIdentity(TEST_ANONYMOUS_IDENTITY);
 
+        Set<ExtendedWifiNetworkSuggestion> matchedSuggestions = mWifiNetworkSuggestionsManager
+                .getNetworkSuggestionsForWifiConfiguration(configuration,
+                        TEST_BSSID);
+        for (ExtendedWifiNetworkSuggestion ewns : matchedSuggestions) {
+            assertNull(ewns.anonymousIdentity);
+            assertEquals(TEST_ANONYMOUS_IDENTITY,
+                    ewns.createInternalWifiConfiguration(mWifiCarrierInfoManager)
+                            .enterpriseConfig.getAnonymousIdentity());
+        }
+
         mWifiNetworkSuggestionsManager.setAnonymousIdentity(configuration);
 
-        Set<ExtendedWifiNetworkSuggestion> matchedSuggestions = mWifiNetworkSuggestionsManager
+        matchedSuggestions = mWifiNetworkSuggestionsManager
                 .getNetworkSuggestionsForWifiConfiguration(configuration,
                         TEST_BSSID);
         for (ExtendedWifiNetworkSuggestion ewns : matchedSuggestions) {
             assertEquals(TEST_ANONYMOUS_IDENTITY, ewns.anonymousIdentity);
         }
+
         // Reset SIM network suggestion, Anonymous Identity should gone.
         mWifiNetworkSuggestionsManager.resetSimNetworkSuggestions();
         matchedSuggestions = mWifiNetworkSuggestionsManager
@@ -5008,6 +5021,9 @@
                         TEST_BSSID);
         for (ExtendedWifiNetworkSuggestion ewns : matchedSuggestions) {
             assertEquals(null, ewns.anonymousIdentity);
+            assertEquals(TEST_ANONYMOUS_IDENTITY,
+                    ewns.createInternalWifiConfiguration(mWifiCarrierInfoManager)
+                            .enterpriseConfig.getAnonymousIdentity());
         }
         verify(mWifiConfigManager, times(3)).saveToStore();
     }
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 f41ab89..54398c8 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java
@@ -5454,6 +5454,34 @@
     }
 
     /**
+     * Verify that the CONNECT_NETWORK message received from NF is forwarded to
+     * ClientModeManager.
+     */
+    @Test
+    public void testConnectNetworkWithNfcUid() throws Exception {
+        final int origCallingUid = Binder.getCallingUid();
+        BinderUtil.setUid(Process.NFC_UID);
+        try {
+            when(mWifiConfigManager.addOrUpdateNetwork(any(), anyInt()))
+                    .thenReturn(new NetworkUpdateResult(TEST_NETWORK_ID));
+            WifiConfiguration config = new WifiConfiguration();
+            config.SSID = TEST_SSID;
+            when(mWifiConfigManager.getConfiguredNetwork(TEST_NETWORK_ID))
+                    .thenReturn(config);
+            mWifiServiceImpl.connect(config, TEST_NETWORK_ID, mock(IActionListener.class),
+                    TEST_PACKAGE_NAME, mExtras);
+            mLooper.dispatchAll();
+            verify(mWifiConfigManager).addOrUpdateNetwork(eq(config), anyInt());
+            verify(mConnectHelper).connectToNetwork(any(NetworkUpdateResult.class),
+                    any(ActionListenerWrapper.class), anyInt(), any(), any());
+            verify(mLastCallerInfoManager).put(eq(WifiManager.API_CONNECT_CONFIG), anyInt(),
+                    anyInt(), anyInt(), anyString(), eq(true));
+        } finally {
+            BinderUtil.setUid(origCallingUid);
+        }
+    }
+
+    /**
      * Verify the secondary internet CMM is stopped when explicit connection is initiated on the
      * primary.
      */
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiShellCommandTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiShellCommandTest.java
index ed4b8c9..9252aa8 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiShellCommandTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiShellCommandTest.java
@@ -58,8 +58,10 @@
 import android.net.wifi.WifiNetworkSuggestion;
 import android.net.wifi.WifiScanner;
 import android.os.Binder;
+import android.os.Handler;
 import android.os.PatternMatcher;
 import android.os.Process;
+import android.os.test.TestLooper;
 
 import androidx.test.filters.SmallTest;
 
@@ -101,16 +103,17 @@
     @Mock WifiCarrierInfoManager mWifiCarrierInfoManager;
     @Mock WifiNetworkFactory mWifiNetworkFactory;
     @Mock WifiGlobals mWifiGlobals;
-    @Mock WifiThreadRunner mWifiThreadRunner;
     @Mock ScanRequestProxy mScanRequestProxy;
     @Mock WifiDiagnostics mWifiDiagnostics;
     @Mock DeviceConfigFacade mDeviceConfig;
     @Mock WifiScanner mWifiScanner;
     WifiShellCommand mWifiShellCommand;
+    TestLooper mLooper;
 
     @Before
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
+        mLooper = new TestLooper();
 
         when(mWifiInjector.getActiveModeWarden()).thenReturn(mActiveModeWarden);
         when(mActiveModeWarden.getPrimaryClientModeManager()).thenReturn(mPrimaryClientModeManager);
@@ -135,7 +138,7 @@
         when(mScanRequestProxy.getScanResults()).thenReturn(new ArrayList<>());
 
         mWifiShellCommand = new WifiShellCommand(mWifiInjector, mWifiService, mContext,
-                mWifiGlobals, mWifiThreadRunner);
+                mWifiGlobals, new WifiThreadRunner(new Handler(mLooper.getLooper())));
 
         // by default emulate shell uid.
         BinderUtil.setUid(Process.SHELL_UID);
@@ -312,6 +315,7 @@
         mWifiShellCommand.exec(
                 new Binder(), new FileDescriptor(), new FileDescriptor(), new FileDescriptor(),
                 new String[]{"network-suggestions-set-user-approved", TEST_PACKAGE, "yes"});
+        mLooper.dispatchAll();
         verify(mWifiNetworkSuggestionsManager, never()).setHasUserApprovedForApp(
                 anyBoolean(), anyInt(), anyString());
         assertFalse(mWifiShellCommand.getErrPrintWriter().toString().isEmpty());
@@ -321,12 +325,14 @@
         mWifiShellCommand.exec(
                 new Binder(), new FileDescriptor(), new FileDescriptor(), new FileDescriptor(),
                 new String[]{"network-suggestions-set-user-approved", TEST_PACKAGE, "yes"});
+        mLooper.dispatchAll();
         verify(mWifiNetworkSuggestionsManager).setHasUserApprovedForApp(
                 eq(true), anyInt(), eq(TEST_PACKAGE));
 
         mWifiShellCommand.exec(
                 new Binder(), new FileDescriptor(), new FileDescriptor(), new FileDescriptor(),
                 new String[]{"network-suggestions-set-user-approved", TEST_PACKAGE, "no"});
+        mLooper.dispatchAll();
         verify(mWifiNetworkSuggestionsManager).setHasUserApprovedForApp(
                 eq(false), anyInt(), eq(TEST_PACKAGE));
     }
@@ -904,6 +910,7 @@
         mWifiShellCommand.exec(
                 new Binder(), new FileDescriptor(), new FileDescriptor(), new FileDescriptor(),
                 new String[]{"add-request", testSsid, "open"});
+        mLooper.dispatchAll();
         verify(mConnectivityManager).requestNetwork(eq(
                 new NetworkRequest.Builder()
                         .addTransportType(TRANSPORT_WIFI)
@@ -918,6 +925,7 @@
         mWifiShellCommand.exec(
                 new Binder(), new FileDescriptor(), new FileDescriptor(), new FileDescriptor(),
                 new String[]{"add-request", testSsid, "owe"});
+        mLooper.dispatchAll();
         verify(mConnectivityManager).requestNetwork(eq(
                 new NetworkRequest.Builder()
                         .addTransportType(TRANSPORT_WIFI)
@@ -933,6 +941,7 @@
         mWifiShellCommand.exec(
                 new Binder(), new FileDescriptor(), new FileDescriptor(), new FileDescriptor(),
                 new String[]{"add-request", testSsid, "wpa2", testPassphrase});
+        mLooper.dispatchAll();
         verify(mConnectivityManager).requestNetwork(eq(
                 new NetworkRequest.Builder()
                         .addTransportType(TRANSPORT_WIFI)
@@ -948,6 +957,7 @@
         mWifiShellCommand.exec(
                 new Binder(), new FileDescriptor(), new FileDescriptor(), new FileDescriptor(),
                 new String[]{"add-request", testSsid, "wpa3", testPassphrase});
+        mLooper.dispatchAll();
         verify(mConnectivityManager).requestNetwork(eq(
                 new NetworkRequest.Builder()
                         .addTransportType(TRANSPORT_WIFI)
@@ -963,6 +973,7 @@
         mWifiShellCommand.exec(
                 new Binder(), new FileDescriptor(), new FileDescriptor(), new FileDescriptor(),
                 new String[]{"add-request", testSsid, "open", "-b", testBssid});
+        mLooper.dispatchAll();
         verify(mConnectivityManager).requestNetwork(eq(
                 new NetworkRequest.Builder()
                         .addTransportType(TRANSPORT_WIFI)
@@ -978,6 +989,7 @@
         mWifiShellCommand.exec(
                 new Binder(), new FileDescriptor(), new FileDescriptor(), new FileDescriptor(),
                 new String[]{"add-request", "-g", testSsid, "open"});
+        mLooper.dispatchAll();
         verify(mConnectivityManager).requestNetwork(eq(
                 new NetworkRequest.Builder()
                         .addTransportType(TRANSPORT_WIFI)