Snap for 8712302 from da647bd309dfea36069d4340d1df252867c51529 to tm-frc-neuralnetworks-release

Change-Id: Ia8e87eacff6906a24e8257fab5c3b0eb5f75f0f1
diff --git a/WifiDialog/src/com/android/wifi/dialog/WifiDialogActivity.java b/WifiDialog/src/com/android/wifi/dialog/WifiDialogActivity.java
index 62497d9..5fa0177 100644
--- a/WifiDialog/src/com/android/wifi/dialog/WifiDialogActivity.java
+++ b/WifiDialog/src/com/android/wifi/dialog/WifiDialogActivity.java
@@ -34,9 +34,11 @@
 import android.os.Bundle;
 import android.os.Process;
 import android.os.Vibrator;
+import android.text.Editable;
 import android.text.SpannableString;
 import android.text.Spanned;
 import android.text.TextUtils;
+import android.text.TextWatcher;
 import android.text.method.LinkMovementMethod;
 import android.text.style.URLSpan;
 import android.util.ArraySet;
@@ -564,6 +566,31 @@
                     getWifiManager().replyToP2pInvitationReceivedDialog(dialogId, false, null);
                 })
                 .create();
+        if (pinEditText != null) {
+            dialog.setOnShowListener(dialogShow -> {
+                dialog.getButton(Dialog.BUTTON_POSITIVE).setEnabled(false);
+            });
+            pinEditText.addTextChangedListener(new TextWatcher() {
+                @Override
+                public void onTextChanged(CharSequence s, int start, int before, int count) {
+                    // No-op.
+                }
+
+                @Override
+                public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+                    // No-op.
+                }
+
+                @Override
+                public void afterTextChanged(Editable s) {
+                    if (s.length() == 4 || s.length() == 8) {
+                        dialog.getButton(Dialog.BUTTON_POSITIVE).setEnabled(true);
+                    } else {
+                        dialog.getButton(Dialog.BUTTON_POSITIVE).setEnabled(false);
+                    }
+                }
+            });
+        }
         if ((getResources().getConfiguration().uiMode & Configuration.UI_MODE_TYPE_APPLIANCE)
                 == Configuration.UI_MODE_TYPE_APPLIANCE) {
             // For appliance devices, add a key listener which accepts.
diff --git a/apex/apex_manifest.json b/apex/apex_manifest.json
index b5d8dd5..1708bbe 100644
--- a/apex/apex_manifest.json
+++ b/apex/apex_manifest.json
@@ -1,5 +1,5 @@
 {
   "name": "com.android.wifi",
-  "version": 330090000
+  "version": 339990000
 }
 
diff --git a/service/ServiceWifiResources/res/layout/wifi_p2p_dialog.xml b/service/ServiceWifiResources/res/layout/wifi_p2p_dialog.xml
index 86dcbfa..8579493 100644
--- a/service/ServiceWifiResources/res/layout/wifi_p2p_dialog.xml
+++ b/service/ServiceWifiResources/res/layout/wifi_p2p_dialog.xml
@@ -19,7 +19,7 @@
     android:layout_height="wrap_content">
 
     <LinearLayout
-        android:layout_width="wrap_content"
+        android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:orientation="vertical">
 
@@ -34,13 +34,10 @@
                 style="@style/wifi_item">
                 <TextView
                     android:text="@string/wifi_p2p_enter_pin_message"
-                    style="@style/wifi_item_label" />
+                    style="@style/wifi_p2p_dialog_enter_pin_message" />
 
                 <EditText android:id="@+id/wifi_p2p_wps_pin"
-                        android:singleLine="true"
-                        android:maxLines="8"
-                        android:inputType="number"
-                        style="@style/wifi_item_content" />
+                        style="@style/wifi_p2p_dialog_pin_input" />
             </LinearLayout>
         </LinearLayout>
     </LinearLayout>
diff --git a/service/ServiceWifiResources/res/layout/wifi_p2p_dialog_row.xml b/service/ServiceWifiResources/res/layout/wifi_p2p_dialog_row.xml
index 2c88b10..ca9bbb2 100644
--- a/service/ServiceWifiResources/res/layout/wifi_p2p_dialog_row.xml
+++ b/service/ServiceWifiResources/res/layout/wifi_p2p_dialog_row.xml
@@ -17,12 +17,10 @@
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     style="@style/wifi_item">
     <TextView
-            style="@style/wifi_item_label"
-            android:id="@+id/name" />
+            android:id="@+id/name"
+            style="@style/wifi_p2p_dialog_row_label"/>
 
     <TextView
             android:id="@+id/value"
-            style="@style/wifi_item_content"
-            android:textStyle="bold"
-            android:textAlignment="viewStart" />
+            style="@style/wifi_p2p_dialog_row_content"/>
 </LinearLayout>
diff --git a/service/ServiceWifiResources/res/values/overlayable.xml b/service/ServiceWifiResources/res/values/overlayable.xml
index 2b43cdf..2d6d08d 100644
--- a/service/ServiceWifiResources/res/values/overlayable.xml
+++ b/service/ServiceWifiResources/res/values/overlayable.xml
@@ -328,6 +328,10 @@
           <item type="style" name="wifi_item_content" />
           <item type="style" name="wifi_section" />
           <item type="style" name="wifi_p2p_invitation_received_dialog" />
+          <item type="style" name="wifi_p2p_dialog_row_label" />
+          <item type="style" name="wifi_p2p_dialog_row_content" />
+          <item type="style" name="wifi_p2p_dialog_enter_pin_message" />
+          <item type="style" name="wifi_p2p_dialog_pin_input" />
           <!-- Params from styles.xml that can be overlayed -->
 
           <!-- Params from drawable/ that can be overlayed -->
diff --git a/service/ServiceWifiResources/res/values/styles.xml b/service/ServiceWifiResources/res/values/styles.xml
index a4cc4d6..872616d 100644
--- a/service/ServiceWifiResources/res/values/styles.xml
+++ b/service/ServiceWifiResources/res/values/styles.xml
@@ -16,7 +16,7 @@
 <resources>
     <!-- Wifi dialog styles -->
     <style name="wifi_item">
-        <item name="android:layout_width">200dip</item>
+        <item name="android:layout_width">match_parent</item>
         <item name="android:layout_height">wrap_content</item>
         <item name="android:layout_marginTop">8dip</item>
         <item name="android:layout_marginStart">16dip</item>
@@ -44,4 +44,19 @@
     </style>
 
     <style name="wifi_p2p_invitation_received_dialog" />
+
+    <style name="wifi_p2p_dialog_row_label" parent="@style/wifi_item_label" />
+
+    <style name="wifi_p2p_dialog_row_content" parent="@style/wifi_item_content">
+        <item name="android:textStyle">bold</item>
+        <item name="android:textAlignment">viewStart</item>
+    </style>
+
+    <style name="wifi_p2p_dialog_enter_pin_message" parent="@style/wifi_item_label" />
+
+    <style name="wifi_p2p_dialog_pin_input" parent="@style/wifi_item_content">
+        <item name="android:singleLine">true</item>
+        <item name="android:maxLength">8</item>
+        <item name="android:inputType">number</item>
+    </style>
 </resources>
diff --git a/service/java/com/android/server/wifi/AvailableNetworkNotifier.java b/service/java/com/android/server/wifi/AvailableNetworkNotifier.java
index c16c12b..81aa467 100644
--- a/service/java/com/android/server/wifi/AvailableNetworkNotifier.java
+++ b/service/java/com/android/server/wifi/AvailableNetworkNotifier.java
@@ -214,7 +214,8 @@
             new BroadcastReceiver() {
                 @Override
                 public void onReceive(Context context, Intent intent) {
-                    if (!mTag.equals(intent.getStringExtra(AVAILABLE_NETWORK_NOTIFIER_TAG))) {
+                    if (!TextUtils.equals(mTag,
+                            intent.getStringExtra(AVAILABLE_NETWORK_NOTIFIER_TAG))) {
                         return;
                     }
                     switch (intent.getAction()) {
diff --git a/service/java/com/android/server/wifi/ClientModeImpl.java b/service/java/com/android/server/wifi/ClientModeImpl.java
index f010db6..92cc9ff 100644
--- a/service/java/com/android/server/wifi/ClientModeImpl.java
+++ b/service/java/com/android/server/wifi/ClientModeImpl.java
@@ -857,6 +857,7 @@
                 mNotificationManager,
                 mWifiInjector.getWifiDialogManager(),
                 isTrustOnFirstUseSupported(),
+                mWifiGlobals.isInsecureEnterpriseConfigurationAllowed(),
                 mInsecureEapNetworkHandlerCallbacksImpl,
                 mInterfaceName,
                 getHandler());
@@ -931,7 +932,7 @@
     private static boolean isValidBssid(String bssidStr) {
         try {
             MacAddress bssid = MacAddress.fromString(bssidStr);
-            return !bssid.equals(WifiManager.ALL_ZEROS_MAC_ADDRESS);
+            return !Objects.equals(bssid, WifiManager.ALL_ZEROS_MAC_ADDRESS);
         } catch (IllegalArgumentException e) {
             return false;
         }
@@ -1310,7 +1311,7 @@
             logi("connectToUserSelectNetwork already connecting/connected=" + netId);
         } else {
             mWifiConnectivityManager.prepareForForcedConnection(netId);
-            if (uid == Process.SYSTEM_UID) {
+            if (UserHandle.getAppId(uid) == Process.SYSTEM_UID) {
                 mWifiMetrics.setNominatorForNetwork(netId,
                         WifiMetricsProto.ConnectionEvent.NOMINATOR_MANUAL);
             }
@@ -3353,10 +3354,6 @@
             }
             log("DHCP failure count=" + count);
         }
-        reportConnectionAttemptEnd(
-                WifiMetrics.ConnectionEvent.FAILURE_DHCP,
-                WifiMetricsProto.ConnectionEvent.HLF_DHCP,
-                WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN);
         synchronized (mDhcpResultsParcelableLock) {
             mDhcpResultsParcelable = new DhcpResultsParcelable();
         }
@@ -3500,7 +3497,7 @@
                 String ip = tokens[0];
                 String mac = tokens[3];
 
-                if (ipAddress.equals(ip)) {
+                if (TextUtils.equals(ipAddress, ip)) {
                     macAddress = mac;
                     break;
                 }
@@ -3566,7 +3563,7 @@
                 : mWifiConfigManager.getRandomizedMacAndUpdateIfNeeded(config);
         if (!WifiConfiguration.isValidMacAddressForRandomization(newMac)) {
             Log.wtf(getTag(), "Config generated an invalid MAC address");
-        } else if (newMac.equals(currentMac)) {
+        } else if (Objects.equals(newMac, currentMac)) {
             Log.d(getTag(), "No changes in MAC address");
         } else {
             mWifiMetrics.logStaEvent(mInterfaceName, StaEvent.TYPE_MAC_CHANGE, config);
@@ -3844,9 +3841,9 @@
             @Override
             public void onReceive(Context context, Intent intent) {
                 String action = intent.getAction();
-                if (action.equals(Intent.ACTION_SCREEN_ON)) {
+                if (TextUtils.equals(action, Intent.ACTION_SCREEN_ON)) {
                     sendMessage(CMD_SCREEN_STATE_CHANGED, 1);
-                } else if (action.equals(Intent.ACTION_SCREEN_OFF)) {
+                } else if (TextUtils.equals(action, Intent.ACTION_SCREEN_OFF)) {
                     sendMessage(CMD_SCREEN_STATE_CHANGED, 0);
                 }
             }
@@ -4400,7 +4397,7 @@
             builder.removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
         }
 
-        if (!mWifiInfo.getSSID().equals(WifiManager.UNKNOWN_SSID)) {
+        if (!WifiManager.UNKNOWN_SSID.equals(mWifiInfo.getSSID())) {
             builder.setSsid(mWifiInfo.getSSID());
         }
 
@@ -4901,11 +4898,15 @@
                             String decoratedPseudonym = mWifiCarrierInfoManager
                                     .decoratePseudonymWith3GppRealm(config,
                                             anonymousIdentity);
-                            if (decoratedPseudonym != null) {
+                            if (decoratedPseudonym != null
+                                    && !decoratedPseudonym.equals(anonymousIdentity)) {
                                 anonymousIdentity = decoratedPseudonym;
                                 // propagate to the supplicant to avoid using
                                 // the original anonymous identity for firmware
                                 // roaming.
+                                if (mVerboseLoggingEnabled) {
+                                    log("Update decorated pseudonym: " + anonymousIdentity);
+                                }
                                 mWifiNative.setEapAnonymousIdentity(mInterfaceName,
                                         anonymousIdentity);
                             }
@@ -5174,7 +5175,8 @@
                 case WifiMonitor.AUTHENTICATION_FAILURE_EVENT: {
                     AuthenticationFailureEventInfo authenticationFailureEventInfo =
                             (AuthenticationFailureEventInfo) message.obj;
-                    if (!authenticationFailureEventInfo.ssid.equals(getConnectingSsidInternal())) {
+                    if (!TextUtils.equals(authenticationFailureEventInfo.ssid,
+                            getConnectingSsidInternal())) {
                         logw("Authentication failure event received on not target network");
                         break;
                     }
@@ -5534,6 +5536,9 @@
                             (mLastBssid == null) ? mTargetBssid : mLastBssid,
                             WifiLastResortWatchdog.FAILURE_CODE_DHCP,
                             isConnected());
+                    handleNetworkDisconnect(false,
+                            WifiStatsLog.WIFI_DISCONNECT_REPORTED__FAILURE_CODE__UNSPECIFIED);
+                    transitionTo(mDisconnectedState); // End of connection attempt.
                     break;
                 }
                 case CMD_IP_REACHABILITY_LOST: {
@@ -5865,10 +5870,6 @@
             switch(message.what) {
                 case WifiMonitor.NETWORK_DISCONNECTION_EVENT: {
                     DisconnectEventInfo eventInfo = (DisconnectEventInfo) message.obj;
-                    reportConnectionAttemptEnd(
-                            WifiMetrics.ConnectionEvent.FAILURE_NETWORK_DISCONNECTION,
-                            WifiMetricsProto.ConnectionEvent.HLF_NONE,
-                            WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN);
                     mWifiLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded(
                             getConnectingSsidInternal(),
                             !isValidBssid(eventInfo.bssid)
diff --git a/service/java/com/android/server/wifi/ConfigurationMap.java b/service/java/com/android/server/wifi/ConfigurationMap.java
index 4219a90..85206d9 100644
--- a/service/java/com/android/server/wifi/ConfigurationMap.java
+++ b/service/java/com/android/server/wifi/ConfigurationMap.java
@@ -19,6 +19,7 @@
 import android.net.wifi.ScanResult;
 import android.net.wifi.WifiConfiguration;
 import android.os.UserHandle;
+import android.text.TextUtils;
 
 import androidx.annotation.NonNull;
 
@@ -128,7 +129,7 @@
             return null;
         }
         for (WifiConfiguration config : mPerIDForCurrentUser.values()) {
-            if (config.getProfileKey().equals(key)) {
+            if (TextUtils.equals(config.getProfileKey(), key)) {
                 return config;
             }
         }
diff --git a/service/java/com/android/server/wifi/ConnectionFailureNotifier.java b/service/java/com/android/server/wifi/ConnectionFailureNotifier.java
index e86c056..9131144 100644
--- a/service/java/com/android/server/wifi/ConnectionFailureNotifier.java
+++ b/service/java/com/android/server/wifi/ConnectionFailureNotifier.java
@@ -26,6 +26,7 @@
 import android.net.wifi.WifiContext;
 import android.os.Handler;
 import android.os.Process;
+import android.text.TextUtils;
 import android.util.Log;
 
 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
@@ -72,7 +73,7 @@
                     @Override
                     public void onReceive(Context context, Intent intent) {
                         String action = intent.getAction();
-                        if (action.equals(ConnectionFailureNotificationBuilder
+                        if (TextUtils.equals(action, ConnectionFailureNotificationBuilder
                                 .ACTION_SHOW_SET_RANDOMIZATION_DETAILS)) {
                             int networkId = intent.getIntExtra(
                                     ConnectionFailureNotificationBuilder
@@ -113,8 +114,8 @@
         // Make sure the networkId is still pointing to the correct WifiConfiguration since
         // there might be a large time gap between when the notification shows and when
         // it's tapped.
-        if (config == null || ssidAndSecurityType == null
-                || !ssidAndSecurityType.equals(config.getSsidAndSecurityTypeString())) {
+        if (config == null || !TextUtils.equals(ssidAndSecurityType,
+                config.getSsidAndSecurityTypeString())) {
             String message = res.getString(
                     R.string.wifi_disable_mac_randomization_dialog_network_not_found);
             mFrameworkFacade.showToast(mContext, message);
diff --git a/service/java/com/android/server/wifi/DppManager.java b/service/java/com/android/server/wifi/DppManager.java
index c29fd53..359e1ad 100644
--- a/service/java/com/android/server/wifi/DppManager.java
+++ b/service/java/com/android/server/wifi/DppManager.java
@@ -652,7 +652,7 @@
 
                 if (newWifiConfiguration.isSecurityType(WifiConfiguration.SECURITY_TYPE_DPP)
                         && existingWifiConfig != null && existingWifiConfig.isDppConfigurator()
-                        && existingWifiConfig.SSID.equals(newWifiConfiguration.SSID)
+                        && TextUtils.equals(existingWifiConfig.SSID, newWifiConfiguration.SSID)
                         && existingWifiConfig.isSecurityType(WifiConfiguration.SECURITY_TYPE_DPP)) {
                     if (newWifiConfiguration.getDppConnector().length > 0
                             && newWifiConfiguration.getDppCSignKey().length > 0
@@ -894,7 +894,7 @@
         boolean isNetworkInScanCache = false;
         boolean channelMatch = false;
         for (ScanResult scanResult : mScanRequestProxy.getScanResults()) {
-            if (!ssid.equals(scanResult.SSID)) {
+            if (!TextUtils.equals(ssid, scanResult.SSID)) {
                 continue;
             }
             isNetworkInScanCache = true;
diff --git a/service/java/com/android/server/wifi/ExternalPnoScanRequestManager.java b/service/java/com/android/server/wifi/ExternalPnoScanRequestManager.java
index a4464d3..94dd70d 100644
--- a/service/java/com/android/server/wifi/ExternalPnoScanRequestManager.java
+++ b/service/java/com/android/server/wifi/ExternalPnoScanRequestManager.java
@@ -54,6 +54,7 @@
     private final Handler mHandler;
     private int mCurrentRequestOnPnoNetworkFoundCount = 0;
     private Context mContext;
+    private boolean mVerboseLoggingEnabled = false;
 
     /**
      * Creates a ExternalPnoScanRequestManager.
@@ -82,6 +83,13 @@
     }
 
     /**
+     * Enables verbose logging.
+     */
+    public void enableVerboseLogging(boolean enabled) {
+        mVerboseLoggingEnabled = enabled;
+    }
+
+    /**
      * Sets the request. This will fail if there's already a request set.
      */
     public boolean setRequest(int uid, @NonNull String packageName, @NonNull IBinder binder,
@@ -91,7 +99,8 @@
             try {
                 callback.onRegisterFailed(REGISTER_PNO_CALLBACK_RESOURCE_BUSY);
             } catch (RemoteException e) {
-                Log.e(TAG, e.getMessage());
+                Log.e(TAG, "RemoteException failed to trigger onRegisterFailed for callback="
+                        + callback);
             }
             return false;
         }
@@ -106,17 +115,12 @@
         try {
             request.mCallback.onRegisterSuccess();
         } catch (RemoteException e) {
-            Log.e(TAG, e.getMessage());
+            Log.e(TAG, "Failed to register request due to remote exception:" + e.getMessage());
             return false;
         }
-        if (mCurrentRequest != null) {
-            // overriding the existing request from the same caller.
-            try {
-                mCurrentRequest.mCallback.onRemoved(REMOVE_PNO_CALLBACK_UNREGISTERED);
-            } catch (RemoteException e) {
-                Log.e(TAG, e.getMessage());
-            }
-            removeCurrentRequest();
+        removeCurrentRequest();
+        if (mVerboseLoggingEnabled) {
+            Log.i(TAG, "Successfully set external PNO scan request:" + request);
         }
         mCurrentRequest = request;
         return true;
@@ -126,8 +130,11 @@
         if (mCurrentRequest != null) {
             try {
                 mCurrentRequest.mBinder.unlinkToDeath(this, 0);
+                if (mVerboseLoggingEnabled) {
+                    Log.i(TAG, "mBinder.unlinkToDeath on request:" + mCurrentRequest);
+                }
             } catch (NoSuchElementException e) {
-                Log.e(TAG, e.getMessage());
+                Log.e(TAG, "Encountered remote exception in unlinkToDeath=" + e.getMessage());
             }
         }
         mCurrentRequest = null;
@@ -146,7 +153,7 @@
         try {
             mCurrentRequest.mCallback.onRemoved(REMOVE_PNO_CALLBACK_UNREGISTERED);
         } catch (RemoteException e) {
-            Log.e(TAG, e.getMessage());
+            Log.e(TAG, "Encountered remote exception in onRemoved=" + e.getMessage());
         }
         removeCurrentRequest();
         return true;
@@ -173,12 +180,16 @@
         }
 
         // requested PNO SSIDs found. Send results and then remove request.
+        if (mVerboseLoggingEnabled) {
+            Log.i(TAG, "On network found for request:" + mCurrentRequest);
+        }
+        sendScanResultAvailableBroadcastToPackage(mCurrentRequest.mPackageName);
         try {
-            sendScanResultAvailableBroadcastToPackage(mCurrentRequest.mPackageName);
             mCurrentRequest.mCallback.onScanResultsAvailable(requestedResults);
             mCurrentRequest.mCallback.onRemoved(REMOVE_PNO_CALLBACK_RESULTS_DELIVERED);
         } catch (RemoteException e) {
-            Log.e(TAG, e.getMessage());
+            Log.e(TAG, "Failed to send PNO results via callback due to remote exception="
+                    + e.getMessage());
         }
         removeCurrentRequest();
     }
@@ -188,6 +199,9 @@
         intent.putExtra(WifiManager.EXTRA_RESULTS_UPDATED, true);
         intent.setPackage(packageName);
         mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
+        if (mVerboseLoggingEnabled) {
+            Log.i(TAG, "Successfully sent out targeted broadcast for:" + mCurrentRequest);
+        }
     }
 
     /**
diff --git a/service/java/com/android/server/wifi/HalDeviceManager.java b/service/java/com/android/server/wifi/HalDeviceManager.java
index fa71055..c8ce15c 100644
--- a/service/java/com/android/server/wifi/HalDeviceManager.java
+++ b/service/java/com/android/server/wifi/HalDeviceManager.java
@@ -2247,6 +2247,7 @@
             StringBuilder sb = new StringBuilder();
             sb.append("{chipInfo=").append(chipInfo).append(", chipModeId=").append(chipModeId)
                     .append(", interfacesToBeRemovedFirst=").append(interfacesToBeRemovedFirst)
+                    .append(", interfacesToBeDowngraded=").append(interfacesToBeDowngraded)
                     .append(")");
             return sb.toString();
         }
@@ -2369,7 +2370,8 @@
      * Note: both proposals are 'acceptable' bases on priority criteria.
      *
      * Criteria:
-     * - Proposal is better if it means removing fewer high priority interfaces
+     * - Proposal is better if it means removing fewer high priority interfaces, or downgrades the
+     *   fewest interfaces.
      */
     private boolean compareIfaceCreationData(IfaceCreationData val1, IfaceCreationData val2) {
         if (VDBG) Log.d(TAG, "compareIfaceCreationData: val1=" + val1 + ", val2=" + val2);
@@ -2415,6 +2417,14 @@
             }
         }
 
+        int val1NumIFacesToBeDowngraded = val1.interfacesToBeDowngraded != null
+                ? val1.interfacesToBeDowngraded.size() : 0;
+        int val2NumIFacesToBeDowngraded = val2.interfacesToBeDowngraded != null
+                ? val2.interfacesToBeDowngraded.size() : 0;
+        if (val1NumIFacesToBeDowngraded != val2NumIFacesToBeDowngraded) {
+            return val1NumIFacesToBeDowngraded < val2NumIFacesToBeDowngraded;
+        }
+
         // arbitrary - flip a coin
         if (VDBG) Log.d(TAG, "proposals identical - flip a coin");
         return false;
diff --git a/service/java/com/android/server/wifi/IMSIParameter.java b/service/java/com/android/server/wifi/IMSIParameter.java
index 4991bb9..c2b49f8 100644
--- a/service/java/com/android/server/wifi/IMSIParameter.java
+++ b/service/java/com/android/server/wifi/IMSIParameter.java
@@ -97,7 +97,7 @@
             return mImsi.regionMatches(false, 0, fullIMSI, 0, mImsi.length());
         } else {
             // Exact matching.
-            return mImsi.equals(fullIMSI);
+            return TextUtils.equals(mImsi, fullIMSI);
         }
     }
 
diff --git a/service/java/com/android/server/wifi/InsecureEapNetworkHandler.java b/service/java/com/android/server/wifi/InsecureEapNetworkHandler.java
index 56dc36f..225d01c 100644
--- a/service/java/com/android/server/wifi/InsecureEapNetworkHandler.java
+++ b/service/java/com/android/server/wifi/InsecureEapNetworkHandler.java
@@ -66,6 +66,7 @@
     private final WifiNotificationManager mNotificationManager;
     private final WifiDialogManager mWifiDialogManager;
     private final boolean mIsTrustOnFirstUseSupported;
+    private final boolean mIsInsecureEnterpriseConfigurationAllowed;
     private final InsecureEapNetworkHandlerCallbacks mCallbacks;
     private final String mInterfaceName;
     private final Handler mHandler;
@@ -93,11 +94,11 @@
             // This is an onGoing notification, dismiss it once an action is sent.
             dismissDialogAndNotification();
             Log.d(TAG, "Received CertNotification: ssid=" + ssid + ", action=" + action);
-            if (action.equals(ACTION_CERT_NOTIF_TAP)) {
+            if (TextUtils.equals(action, ACTION_CERT_NOTIF_TAP)) {
                 askForUserApprovalForCaCertificate();
-            } else if (action.equals(ACTION_CERT_NOTIF_ACCEPT)) {
+            } else if (TextUtils.equals(action, ACTION_CERT_NOTIF_ACCEPT)) {
                 handleAccept(ssid);
-            } else if (action.equals(ACTION_CERT_NOTIF_REJECT)) {
+            } else if (TextUtils.equals(action, ACTION_CERT_NOTIF_REJECT)) {
                 handleReject(ssid);
             }
         }
@@ -110,6 +111,7 @@
             @NonNull WifiNotificationManager notificationManager,
             @NonNull WifiDialogManager wifiDialogManager,
             boolean isTrustOnFirstUseSupported,
+            boolean isInsecureEnterpriseConfigurationAllowed,
             @NonNull InsecureEapNetworkHandlerCallbacks callbacks,
             @NonNull String interfaceName,
             @NonNull Handler handler) {
@@ -120,6 +122,7 @@
         mNotificationManager = notificationManager;
         mWifiDialogManager = wifiDialogManager;
         mIsTrustOnFirstUseSupported = isTrustOnFirstUseSupported;
+        mIsInsecureEnterpriseConfigurationAllowed = isInsecureEnterpriseConfigurationAllowed;
         mCallbacks = callbacks;
         mInterfaceName = interfaceName;
         mHandler = handler;
@@ -143,18 +146,24 @@
         if (!entConfig.isEapMethodServerCertUsed()) return;
         if (entConfig.hasCaCertificate()) return;
 
-        // For TOFU supported devices, return if TOFU is not enabled.
-        if (mIsTrustOnFirstUseSupported && !entConfig.isTrustOnFirstUseEnabled()) {
-            return;
-        }
-        // For TOFU non-supported devices, return if this is approved before.
-        if (!mIsTrustOnFirstUseSupported && entConfig.isUserApproveNoCaCert()) {
-            return;
+        clearConnection();
+
+        Log.d(TAG, "prepareConnection: isTofuSupported=" + mIsTrustOnFirstUseSupported
+                + ", isInsecureEapNetworkAllowed=" + mIsInsecureEnterpriseConfigurationAllowed
+                + ", isTofuEnabled=" + entConfig.isTrustOnFirstUseEnabled()
+                + ", isUserApprovedNoCaCert=" + entConfig.isUserApproveNoCaCert());
+        // If TOFU is not supported or insecure EAP network is allowed without TOFU enabled,
+        // return to skip the dialog if this network is approved before.
+        if (entConfig.isUserApproveNoCaCert()) {
+            if (!mIsTrustOnFirstUseSupported) return;
+            if (mIsInsecureEnterpriseConfigurationAllowed
+                    && !entConfig.isTrustOnFirstUseEnabled()) {
+                return;
+            }
         }
 
-        clearConnection();
-        registerCertificateNotificationReceiver();
         mCurConfig = config;
+        registerCertificateNotificationReceiver();
         // Remove cached PMK in the framework and supplicant to avoid
         // skipping the EAP flow.
         clearNativeData();
@@ -183,7 +192,7 @@
                 + " current config=" + mCurConfig);
         if (TextUtils.isEmpty(ssid)) return false;
         if (null == mCurConfig) return false;
-        if (!ssid.equals(mCurConfig.SSID)) return false;
+        if (!TextUtils.equals(ssid, mCurConfig.SSID)) return false;
         if (null == cert) return false;
         if (depth < 0) return false;
         // 0 is the tail, i.e. the server cert.
@@ -217,13 +226,18 @@
     /**
      * Ask for the user approval if necessary.
      *
-     * For T and an EAP network without a CA certificate.
-     * - if TOFU is not enabled or no pending CA cert, disconnect it.
-     * - if TOFU is enabled and CA cert is pending
+     * For TOFU is supported and an EAP network without a CA certificate.
+     * - if insecure EAP networks are not allowed
+     *    - if TOFU is not enabled, disconnect it.
+     *    - if no pending CA cert, disconnect it.
+     *    - if no server cert, disconnect it.
+     * - if insecure EAP networks are allowed and TOFU is not enabled
+     *    - follow no TOFU support flow.
+     * - if TOFU is enabled, CA cert is pending, and server cert is pending
      *     - gate the connecitvity event here
      *     - if this request is from a user, launch a dialog to get the user approval.
      *     - if this request is from auto-connect, launch a notification.
-     * For preT release, the confirmation flow is similar. Instead of installing CA
+     * If TOFU is not supported, the confirmation flow is similar. Instead of installing CA
      * cert from the server, just mark this network is approved by the user.
      *
      * @param isUserSelected indicates that this connection is triggered by a user.
@@ -236,20 +250,25 @@
         if (!entConfig.isEapMethodServerCertUsed()) return false;
         if (entConfig.hasCaCertificate()) return false;
 
-        // If Trust On First Use is supported, Root CA cert is mandatory
-        // for an Enterprise network which needs Root CA cert.
-        if (!mIsTrustOnFirstUseSupported) {
-            if (mCurConfig.enterpriseConfig.isUserApproveNoCaCert()) {
-                return false;
+        // If Trust On First Use is supported and insecure enterprise configuration
+        // is not allowed, TOFU must be used for an Enterprise network without certs.
+        if (mIsTrustOnFirstUseSupported && !mIsInsecureEnterpriseConfigurationAllowed
+                && !mCurConfig.enterpriseConfig.isTrustOnFirstUseEnabled()) {
+            Log.d(TAG, "Trust On First Use is not enabled.");
+            handleError(mCurConfig.SSID);
+            return true;
+        }
+
+        if (useTrustOnFirstUse()) {
+            if (null == mPendingCaCert) {
+                Log.d(TAG, "No valid CA cert for TLS-based connection.");
+                handleError(mCurConfig.SSID);
+                return true;
+            } else if (null == mPendingServerCert) {
+                Log.d(TAG, "No valid Server cert for TLS-based connection.");
+                handleError(mCurConfig.SSID);
+                return true;
             }
-        } else if (null == mPendingCaCert) {
-            Log.d(TAG, "No valid CA cert for TLS-based connection.");
-            handleError(mCurConfig.SSID);
-            return true;
-        } else if (null == mPendingServerCert) {
-            Log.d(TAG, "No valid Server cert for TLS-based connection.");
-            handleError(mCurConfig.SSID);
-            return true;
         }
 
         Log.d(TAG, "startUserApprovalIfNecessaryForInsecureEapNetwork: mIsUserSelected="
@@ -263,14 +282,18 @@
         return true;
     }
 
+    private boolean useTrustOnFirstUse() {
+        return mIsTrustOnFirstUseSupported
+                && mCurConfig.enterpriseConfig.isTrustOnFirstUseEnabled();
+    }
+
     private void registerCertificateNotificationReceiver() {
         if (mIsCertNotificationReceiverRegistered) return;
 
         IntentFilter filter = new IntentFilter();
-        if (mIsTrustOnFirstUseSupported) {
+        if (useTrustOnFirstUse()) {
             filter.addAction(ACTION_CERT_NOTIF_TAP);
-        }
-        if (!mIsTrustOnFirstUseSupported) {
+        } else {
             filter.addAction(ACTION_CERT_NOTIF_ACCEPT);
             filter.addAction(ACTION_CERT_NOTIF_REJECT);
         }
@@ -289,7 +312,7 @@
     void handleAccept(@NonNull String ssid) {
         if (!isConnectionValid(ssid)) return;
 
-        if (!mIsTrustOnFirstUseSupported) {
+        if (!useTrustOnFirstUse()) {
             mWifiConfigManager.setUserApproveNoCaCert(mCurConfig.networkId, true);
         } else {
             if (null == mPendingCaCert || null == mPendingServerCert) {
@@ -333,7 +356,7 @@
 
     private void askForUserApprovalForCaCertificate() {
         if (mCurConfig == null || TextUtils.isEmpty(mCurConfig.SSID)) return;
-        if (mIsTrustOnFirstUseSupported) {
+        if (useTrustOnFirstUse()) {
             if (null == mPendingCaCert || null == mPendingServerCert) {
                 Log.e(TAG, "Cannot launch a dialog for TOFU without "
                         + "a valid pending CA certificate.");
@@ -342,13 +365,13 @@
         }
         dismissDialogAndNotification();
 
-        String title = mIsTrustOnFirstUseSupported
+        String title = useTrustOnFirstUse()
                 ? mContext.getString(R.string.wifi_ca_cert_dialog_title)
                 : mContext.getString(R.string.wifi_ca_cert_dialog_preT_title);
-        String positiveButtonText = mIsTrustOnFirstUseSupported
+        String positiveButtonText = useTrustOnFirstUse()
                 ? mContext.getString(R.string.wifi_ca_cert_dialog_continue_text)
                 : mContext.getString(R.string.wifi_ca_cert_dialog_preT_continue_text);
-        String negativeButtonText = mIsTrustOnFirstUseSupported
+        String negativeButtonText = useTrustOnFirstUse()
                 ? mContext.getString(R.string.wifi_ca_cert_dialog_abort_text)
                 : mContext.getString(R.string.wifi_ca_cert_dialog_preT_abort_text);
 
@@ -356,7 +379,7 @@
         String messageUrl = null;
         int messageUrlStart = 0;
         int messageUrlEnd = 0;
-        if (mIsTrustOnFirstUseSupported) {
+        if (useTrustOnFirstUse()) {
             String signature = NativeUtil.hexStringFromByteArray(
                     mPendingCaCert.getSignature());
             StringBuilder contentBuilder = new StringBuilder()
@@ -438,14 +461,14 @@
 
     private void notifyUserForCaCertificate() {
         if (mCurConfig == null) return;
-        if (mIsTrustOnFirstUseSupported) {
+        if (useTrustOnFirstUse()) {
             if (null == mPendingCaCert) return;
             if (null == mPendingServerCert) return;
         }
         dismissDialogAndNotification();
 
         PendingIntent tapPendingIntent;
-        if (mIsTrustOnFirstUseSupported) {
+        if (useTrustOnFirstUse()) {
             tapPendingIntent = genCaCertNotifIntent(ACTION_CERT_NOTIF_TAP, mCurConfig.SSID);
         } else {
             Intent openLinkIntent = new Intent(Intent.ACTION_VIEW)
@@ -455,10 +478,10 @@
                     PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
         }
 
-        String title = mIsTrustOnFirstUseSupported
+        String title = useTrustOnFirstUse()
                 ? mContext.getString(R.string.wifi_ca_cert_notification_title)
                 : mContext.getString(R.string.wifi_ca_cert_notification_preT_title);
-        String content = mIsTrustOnFirstUseSupported
+        String content = useTrustOnFirstUse()
                 ? mContext.getString(R.string.wifi_ca_cert_notification_message, mCurConfig.SSID)
                 : mContext.getString(R.string.wifi_ca_cert_notification_preT_message,
                         mCurConfig.SSID);
@@ -475,7 +498,7 @@
                             android.R.color.system_notification_accent_color));
         // On a device which does not support Trust On First Use,
         // a user can accept or reject this network via the notification.
-        if (!mIsTrustOnFirstUseSupported) {
+        if (!useTrustOnFirstUse()) {
             Notification.Action acceptAction = new Notification.Action.Builder(
                     null /* icon */,
                     mContext.getString(R.string.wifi_ca_cert_dialog_preT_continue_text),
@@ -533,7 +556,7 @@
             return false;
         }
 
-        if (!ssid.equals(mCurConfig.SSID)) {
+        if (!TextUtils.equals(ssid, mCurConfig.SSID)) {
             Log.w(TAG, "Target SSID " + mCurConfig.SSID
                     + " is different from TOFU returned SSID" + ssid);
             return false;
diff --git a/service/java/com/android/server/wifi/NetworkListStoreData.java b/service/java/com/android/server/wifi/NetworkListStoreData.java
index 7f5f5de..d9d53fa 100644
--- a/service/java/com/android/server/wifi/NetworkListStoreData.java
+++ b/service/java/com/android/server/wifi/NetworkListStoreData.java
@@ -25,6 +25,7 @@
 import android.net.wifi.WifiConfiguration.NetworkSelectionStatus;
 import android.net.wifi.WifiEnterpriseConfig;
 import android.os.Process;
+import android.text.TextUtils;
 import android.util.Log;
 import android.util.Pair;
 
@@ -296,7 +297,7 @@
         }
 
         String configKeyCalculated = configuration.getKey();
-        if (!configKeyParsed.equals(configKeyCalculated)) {
+        if (!TextUtils.equals(configKeyParsed, configKeyCalculated)) {
             // configKey is not part of the SDK. So, we can't expect this to be the same
             // across OEM's. Just log a warning & continue.
             Log.w(TAG, "Configuration key does not match. Retrieved: " + configKeyParsed
@@ -310,7 +311,7 @@
             configuration.creatorUid = Process.SYSTEM_UID;
             configuration.creatorName =
                     mContext.getPackageManager().getNameForUid(Process.SYSTEM_UID);
-        } else if (!creatorName.equals(configuration.creatorName)) {
+        } else if (!TextUtils.equals(creatorName, configuration.creatorName)) {
             Log.w(TAG, "Invalid creatorName for saved network " + configuration.getKey()
                     + ", creatorUid=" + configuration.creatorUid
                     + ", creatorName=" + configuration.creatorName);
diff --git a/service/java/com/android/server/wifi/PmkCacheManager.java b/service/java/com/android/server/wifi/PmkCacheManager.java
index a28a978..3e17283 100644
--- a/service/java/com/android/server/wifi/PmkCacheManager.java
+++ b/service/java/com/android/server/wifi/PmkCacheManager.java
@@ -80,7 +80,7 @@
             mPmkCacheEntries.put(networkId, pmkDataList);
         } else {
             PmkCacheStoreData existStoreData = pmkDataList.stream()
-                    .filter(storeData -> storeData.equals(newStoreData))
+                    .filter(storeData -> Objects.equals(storeData, newStoreData))
                     .findAny()
                     .orElse(null);
             if (null != existStoreData) {
@@ -128,7 +128,7 @@
         List<PmkCacheStoreData> pmkDataList = mPmkCacheEntries.get(networkId);
         if (null == pmkDataList) return false;
 
-        pmkDataList.removeIf(pmkData -> !curMacAddress.equals(pmkData.macAddress));
+        pmkDataList.removeIf(pmkData -> !Objects.equals(curMacAddress, pmkData.macAddress));
 
         if (pmkDataList.size() == 0) {
             remove(networkId);
@@ -239,8 +239,8 @@
             if (!(o instanceof PmkCacheStoreData)) return false;
             PmkCacheStoreData storeData = (PmkCacheStoreData) o;
             return expirationTimeInSec == storeData.expirationTimeInSec
-                    && macAddress.equals(storeData.macAddress)
-                    && data.equals(storeData.data);
+                    && Objects.equals(macAddress, storeData.macAddress)
+                    && Objects.equals(data, storeData.data);
         }
 
         @Override
diff --git a/service/java/com/android/server/wifi/SarManager.java b/service/java/com/android/server/wifi/SarManager.java
index 38a89b0..da7ec96 100644
--- a/service/java/com/android/server/wifi/SarManager.java
+++ b/service/java/com/android/server/wifi/SarManager.java
@@ -34,6 +34,7 @@
 import android.os.PowerManager;
 import android.telephony.PhoneStateListener;
 import android.telephony.TelephonyManager;
+import android.text.TextUtils;
 import android.util.Log;
 
 import com.android.modules.utils.HandlerExecutor;
@@ -246,9 +247,9 @@
                     @Override
                     public void onReceive(Context context, Intent intent) {
                         String action = intent.getAction();
-                        if (action.equals(Intent.ACTION_SCREEN_ON)) {
+                        if (TextUtils.equals(action, Intent.ACTION_SCREEN_ON)) {
                             handleScreenStateChanged(true);
-                        } else if (action.equals(Intent.ACTION_SCREEN_OFF)) {
+                        } else if (TextUtils.equals(action, Intent.ACTION_SCREEN_OFF)) {
                             handleScreenStateChanged(false);
                         }
                     }
diff --git a/service/java/com/android/server/wifi/ScanRequestProxy.java b/service/java/com/android/server/wifi/ScanRequestProxy.java
index 9a0b694..3e4d8be 100644
--- a/service/java/com/android/server/wifi/ScanRequestProxy.java
+++ b/service/java/com/android/server/wifi/ScanRequestProxy.java
@@ -34,6 +34,7 @@
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.os.WorkSource;
+import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.Log;
 import android.util.Pair;
@@ -372,7 +373,7 @@
             return false;
         }
         for (String name : exceptionList) {
-            if (packageName.equals(name)) {
+            if (TextUtils.equals(packageName, name)) {
                 return true;
             }
         }
@@ -599,7 +600,7 @@
     /** Indicate whether there are WPA2 personal only networks. */
     public boolean isWpa2PersonalOnlyNetworkInRange(String ssid) {
         return mLastScanResultsMap.values().stream().anyMatch(r ->
-                ssid.equals(r.getWifiSsid().toString())
+                TextUtils.equals(ssid, r.getWifiSsid().toString())
                 && ScanResultUtil.isScanResultForPskNetwork(r)
                 && !ScanResultUtil.isScanResultForSaeNetwork(r));
     }
@@ -607,7 +608,7 @@
     /** Indicate whether there are WPA3 only networks. */
     public boolean isWpa3PersonalOnlyNetworkInRange(String ssid) {
         return mLastScanResultsMap.values().stream().anyMatch(r ->
-                ssid.equals(r.getWifiSsid().toString())
+                TextUtils.equals(ssid, r.getWifiSsid().toString())
                 && ScanResultUtil.isScanResultForSaeNetwork(r)
                 && !ScanResultUtil.isScanResultForPskNetwork(r));
     }
@@ -615,14 +616,14 @@
     /** Indicate whether there are WPA2/WPA3 transition mode networks. */
     public boolean isWpa2Wpa3PersonalTransitionNetworkInRange(String ssid) {
         return mLastScanResultsMap.values().stream().anyMatch(r ->
-                ssid.equals(ScanResultUtil.createQuotedSsid(r.SSID))
+                TextUtils.equals(ssid, ScanResultUtil.createQuotedSsid(r.SSID))
                 && ScanResultUtil.isScanResultForPskSaeTransitionNetwork(r));
     }
 
     /** Indicate whether there are OPEN only networks. */
     public boolean isOpenOnlyNetworkInRange(String ssid) {
         return mLastScanResultsMap.values().stream().anyMatch(r ->
-                ssid.equals(r.getWifiSsid().toString())
+                TextUtils.equals(ssid, r.getWifiSsid().toString())
                 && ScanResultUtil.isScanResultForOpenNetwork(r)
                 && !ScanResultUtil.isScanResultForOweNetwork(r));
     }
@@ -630,7 +631,7 @@
     /** Indicate whether there are OWE only networks. */
     public boolean isOweOnlyNetworkInRange(String ssid) {
         return mLastScanResultsMap.values().stream().anyMatch(r ->
-                ssid.equals(r.getWifiSsid().toString())
+                TextUtils.equals(ssid, r.getWifiSsid().toString())
                 && ScanResultUtil.isScanResultForOweNetwork(r)
                 && !ScanResultUtil.isScanResultForOweTransitionNetwork(r));
     }
@@ -638,7 +639,7 @@
     /** Indicate whether there are WPA2 Enterprise only networks. */
     public boolean isWpa2EnterpriseOnlyNetworkInRange(String ssid) {
         return mLastScanResultsMap.values().stream().anyMatch(r ->
-                ssid.equals(r.getWifiSsid().toString())
+                TextUtils.equals(ssid, r.getWifiSsid().toString())
                 && ScanResultUtil.isScanResultForEapNetwork(r)
                 && !ScanResultUtil.isScanResultForWpa3EnterpriseTransitionNetwork(r)
                 && !ScanResultUtil.isScanResultForWpa3EnterpriseOnlyNetwork(r));
@@ -647,7 +648,7 @@
     /** Indicate whether there are WPA3 Enterprise only networks. */
     public boolean isWpa3EnterpriseOnlyNetworkInRange(String ssid) {
         return mLastScanResultsMap.values().stream().anyMatch(r ->
-                ssid.equals(r.getWifiSsid().toString())
+                TextUtils.equals(ssid, r.getWifiSsid().toString())
                 && ScanResultUtil.isScanResultForWpa3EnterpriseOnlyNetwork(r)
                 && !ScanResultUtil.isScanResultForWpa3EnterpriseTransitionNetwork(r)
                 && !ScanResultUtil.isScanResultForEapNetwork(r));
diff --git a/service/java/com/android/server/wifi/ScoringParams.java b/service/java/com/android/server/wifi/ScoringParams.java
index d3e8fad..0f42f16 100644
--- a/service/java/com/android/server/wifi/ScoringParams.java
+++ b/service/java/com/android/server/wifi/ScoringParams.java
@@ -20,6 +20,7 @@
 import android.content.Context;
 import android.net.wifi.ScanResult;
 import android.net.wifi.WifiInfo;
+import android.text.TextUtils;
 import android.util.Log;
 
 import com.android.internal.annotations.VisibleForTesting;
@@ -319,7 +320,7 @@
      */
     @VisibleForTesting
     public boolean update(String kvList) {
-        if (kvList == null || "".equals(kvList)) {
+        if (TextUtils.isEmpty(kvList)) {
             return true;
         }
         if (!("," + kvList).matches(COMMA_KEY_VAL_STAR)) {
diff --git a/service/java/com/android/server/wifi/SupplicantStaIfaceHalHidlImpl.java b/service/java/com/android/server/wifi/SupplicantStaIfaceHalHidlImpl.java
index 7bbc6aa..a1aeb9e 100644
--- a/service/java/com/android/server/wifi/SupplicantStaIfaceHalHidlImpl.java
+++ b/service/java/com/android/server/wifi/SupplicantStaIfaceHalHidlImpl.java
@@ -497,7 +497,8 @@
             }
             Mutable<ISupplicantIface> supplicantIface = new Mutable<>();
             for (ISupplicant.IfaceInfo ifaceInfo : supplicantIfaces) {
-                if (ifaceInfo.type == IfaceType.STA && ifaceName.equals(ifaceInfo.name)) {
+                if (ifaceInfo.type == IfaceType.STA
+                        && TextUtils.equals(ifaceName, ifaceInfo.name)) {
                     try {
                         mISupplicant.getInterface(ifaceInfo,
                                 (SupplicantStatus status, ISupplicantIface iface) -> {
diff --git a/service/java/com/android/server/wifi/WifiCarrierInfoManager.java b/service/java/com/android/server/wifi/WifiCarrierInfoManager.java
index 54880b7..f1ea3c7 100644
--- a/service/java/com/android/server/wifi/WifiCarrierInfoManager.java
+++ b/service/java/com/android/server/wifi/WifiCarrierInfoManager.java
@@ -637,7 +637,7 @@
             return false;
         }
         for (String curSsid : macRandDisabledSsids) {
-            if (sanitizedSsid.equals(curSsid)) {
+            if (TextUtils.equals(sanitizedSsid, curSsid)) {
                 return true;
             }
         }
diff --git a/service/java/com/android/server/wifi/WifiConfigManager.java b/service/java/com/android/server/wifi/WifiConfigManager.java
index fe14f83..f5729dc 100644
--- a/service/java/com/android/server/wifi/WifiConfigManager.java
+++ b/service/java/com/android/server/wifi/WifiConfigManager.java
@@ -162,6 +162,15 @@
          * @param choiceKey The network profile key of the user connect choice that was removed.
          */
         default void onConnectChoiceRemoved(String choiceKey){ }
+
+        /**
+         * Invoke when security params changed, especially when NetworkTransitionDisable event
+         * received
+         * @param oldConfig The original WifiConfiguration
+         * @param securityParams the updated securityParams
+         */
+        default void onSecurityParamsUpdate(@NonNull WifiConfiguration oldConfig,
+                List<SecurityParams> securityParams) { }
     }
     /**
      * Max size of scan details to cache in {@link #mScanDetailCaches}.
@@ -3866,8 +3875,7 @@
      * @param indicationBit transition disable indication bits.
      * @return true if the network was found, false otherwise.
      */
-    public boolean updateNetworkTransitionDisable(
-            int networkId,
+    public boolean updateNetworkTransitionDisable(int networkId,
             @WifiMonitor.TransitionDisableIndication int indicationBit) {
         localLog("updateNetworkTransitionDisable: network ID=" + networkId
                 + " indication: " + indicationBit);
@@ -3876,21 +3884,33 @@
             Log.e(TAG, "Cannot find network for " + networkId);
             return false;
         }
+        WifiConfiguration copy = new WifiConfiguration(config);
+        boolean changed = false;
         if (0 != (indicationBit & WifiMonitor.TDI_USE_WPA3_PERSONAL)
                 && config.isSecurityType(WifiConfiguration.SECURITY_TYPE_SAE)) {
             config.setSecurityParamsEnabled(WifiConfiguration.SECURITY_TYPE_PSK, false);
+            changed = true;
         }
         if (0 != (indicationBit & WifiMonitor.TDI_USE_SAE_PK)) {
             config.enableSaePkOnlyMode(true);
+            changed = true;
         }
         if (0 != (indicationBit & WifiMonitor.TDI_USE_WPA3_ENTERPRISE)
                 && config.isSecurityType(WifiConfiguration.SECURITY_TYPE_EAP_WPA3_ENTERPRISE)) {
             config.setSecurityParamsEnabled(WifiConfiguration.SECURITY_TYPE_EAP, false);
+            changed = true;
         }
         if (0 != (indicationBit & WifiMonitor.TDI_USE_ENHANCED_OPEN)
                 && config.isSecurityType(WifiConfiguration.SECURITY_TYPE_OWE)) {
             config.setSecurityParamsEnabled(WifiConfiguration.SECURITY_TYPE_OPEN, false);
+            changed = true;
         }
+        if (changed) {
+            for (OnNetworkUpdateListener listener : mListeners) {
+                listener.onSecurityParamsUpdate(copy, config.getSecurityParamsList());
+            }
+        }
+
         return true;
     }
 
@@ -4116,14 +4136,13 @@
      * This method updates Trust On First Use flag according to
      * Trust On First Use support and No-Ca-Cert Approval.
      */
-    public void updateTrustOnFirstUseFlag(
-            boolean isTrustOnFirstUseSupported) {
+    public void updateTrustOnFirstUseFlag(boolean enableTrustOnFirstUse) {
         getInternalConfiguredNetworks().stream()
                 .filter(config -> config.isEnterprise())
                 .filter(config -> config.enterpriseConfig.isEapMethodServerCertUsed())
                 .filter(config -> !config.enterpriseConfig.hasCaCertificate())
                 .forEach(config ->
-                        config.enterpriseConfig.enableTrustOnFirstUse(isTrustOnFirstUseSupported));
+                        config.enterpriseConfig.enableTrustOnFirstUse(enableTrustOnFirstUse));
     }
 
     /**
diff --git a/service/java/com/android/server/wifi/WifiCountryCode.java b/service/java/com/android/server/wifi/WifiCountryCode.java
index d93cade..3381557 100644
--- a/service/java/com/android/server/wifi/WifiCountryCode.java
+++ b/service/java/com/android/server/wifi/WifiCountryCode.java
@@ -79,6 +79,7 @@
     private String mTelephonyCountryCode = null;
     private String mOverrideCountryCode = null;
     private String mDriverCountryCode = null;
+    private String mLastActiveDriverCountryCode = null;
     private long mDriverCountryCodeUpdatedTimestamp = 0;
     private String mTelephonyCountryTimestamp = null;
     private String mAllCmmReadyTimestamp = null;
@@ -154,7 +155,7 @@
     private class CountryChangeListenerInternal implements ChangeListener {
         @Override
         public void onDriverCountryCodeChanged(String country) {
-            if (TextUtils.equals(country, mDriverCountryCode)) {
+            if (TextUtils.equals(country, mLastActiveDriverCountryCode)) {
                 return;
             }
             Log.i(TAG, "Receive onDriverCountryCodeChanged " + country);
@@ -168,7 +169,12 @@
         @Override
         public void onSetCountryCodeSucceeded(String country) {
             Log.i(TAG, "Receive onSetCountryCodeSucceeded " + country);
-            if (!isDriverSupportedRegChangedEvent()) {
+            // The country code callback might not be triggered even if the driver supports reg
+            // changed event when the maintained country code in the driver is same as set one.
+            // So notify the country code changed event to listener when the set one is same as
+            // last active one.
+            if (!isDriverSupportedRegChangedEvent()
+                    || TextUtils.equals(country, mLastActiveDriverCountryCode)) {
                 mWifiNative.countryCodeChanged(country);
                 handleCountryCodeChanged(country);
             }
@@ -600,6 +606,9 @@
         if (!TextUtils.equals(mDriverCountryCode, country)) {
             mDriverCountryCodeUpdatedTimestamp = System.currentTimeMillis();
             mDriverCountryCode = country;
+            if (country !=  null) {
+                mLastActiveDriverCountryCode = country;
+            }
             notifyListener(country);
         }
     }
diff --git a/service/java/com/android/server/wifi/WifiGlobals.java b/service/java/com/android/server/wifi/WifiGlobals.java
index d66368e..85cc4b6 100644
--- a/service/java/com/android/server/wifi/WifiGlobals.java
+++ b/service/java/com/android/server/wifi/WifiGlobals.java
@@ -66,6 +66,8 @@
     private final boolean mSaveFactoryMacToConfigStoreEnabled;
     private final int mWifiLowConnectedScoreThresholdToTriggerScanForMbb;
     private final int mWifiLowConnectedScoreScanPeriodSeconds;
+    // This is read from the overlay, cache it after boot up.
+    private final boolean mWifiAllowInsecureEnterpriseConfiguration;
 
     // This is set by WifiManager#setVerboseLoggingEnabled(int).
     private boolean mIsShowKeyVerboseLoggingModeEnabled = false;
@@ -96,6 +98,8 @@
                 R.integer.config_wifiLowConnectedScoreThresholdToTriggerScanForMbb);
         mWifiLowConnectedScoreScanPeriodSeconds = mContext.getResources().getInteger(
                 R.integer.config_wifiLowConnectedScoreScanPeriodSeconds);
+        mWifiAllowInsecureEnterpriseConfiguration = mContext.getResources().getBoolean(
+                R.bool.config_wifiAllowInsecureEnterpriseConfigurationsForSettingsAndSUW);
     }
 
     /** Get the interval between RSSI polls, in milliseconds. */
@@ -253,6 +257,11 @@
         return mWifiLowConnectedScoreScanPeriodSeconds;
     }
 
+    /** Get whether or not insecure enterprise configuration is allowed. */
+    public boolean isInsecureEnterpriseConfigurationAllowed() {
+        return mWifiAllowInsecureEnterpriseConfiguration;
+    }
+
     /** Dump method for debugging */
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         pw.println("Dump of WifiGlobals");
@@ -274,5 +283,7 @@
                 + mWifiLowConnectedScoreScanPeriodSeconds);
         pw.println("mIsUsingExternalScorer="
                 + mIsUsingExternalScorer);
+        pw.println("mWifiAllowInsecureEnterpriseConfiguratio"
+                + mWifiAllowInsecureEnterpriseConfiguration);
     }
 }
diff --git a/service/java/com/android/server/wifi/WifiInjector.java b/service/java/com/android/server/wifi/WifiInjector.java
index 85d30c6..9bcdbf2 100644
--- a/service/java/com/android/server/wifi/WifiInjector.java
+++ b/service/java/com/android/server/wifi/WifiInjector.java
@@ -589,6 +589,7 @@
         }
         mWifiPermissionsUtil.enableVerboseLogging(verboseEnabled);
         mWifiDialogManager.enableVerboseLogging(verboseEnabled);
+        mExternalPnoScanRequestManager.enableVerboseLogging(verboseEnabled);
     }
 
     public UserManager getUserManager() {
diff --git a/service/java/com/android/server/wifi/WifiKeyStore.java b/service/java/com/android/server/wifi/WifiKeyStore.java
index 703949a..503001e 100644
--- a/service/java/com/android/server/wifi/WifiKeyStore.java
+++ b/service/java/com/android/server/wifi/WifiKeyStore.java
@@ -140,7 +140,7 @@
             }
         }
         // If alias changed, remove the old one.
-        if (!alias.equals(existingAlias)) {
+        if (!TextUtils.equals(alias, existingAlias)) {
             if (existingConfig != null && existingConfig.isAppInstalledDeviceKeyAndCert()) {
                 // Remove old private keys.
                 removeEntryFromKeyStore(existingAlias);
@@ -404,7 +404,7 @@
         // support for both RSA and ECDSA, and for STAs it mandates ECDSA and optionally
         // RSA. In order to be compatible with all WPA3-Enterprise 192-bit deployments,
         // we are supporting both types here.
-        if (sigAlgOid.equals("1.2.840.113549.1.1.12")) {
+        if (TextUtils.equals(sigAlgOid, "1.2.840.113549.1.1.12")) {
             // sha384WithRSAEncryption
             if (x509Certificate.getPublicKey() instanceof RSAPublicKey) {
                 final RSAPublicKey rsaPublicKey = (RSAPublicKey) x509Certificate.getPublicKey();
@@ -418,7 +418,7 @@
                     }
                 }
             }
-        } else if (sigAlgOid.equals("1.2.840.10045.4.3.3")) {
+        } else if (TextUtils.equals(sigAlgOid, "1.2.840.10045.4.3.3")) {
             // ecdsa-with-SHA384
             if (x509Certificate.getPublicKey() instanceof ECPublicKey) {
                 final ECPublicKey ecPublicKey = (ECPublicKey) x509Certificate.getPublicKey();
diff --git a/service/java/com/android/server/wifi/WifiLockManager.java b/service/java/com/android/server/wifi/WifiLockManager.java
index b7b5ca6..4e9cd9d 100644
--- a/service/java/com/android/server/wifi/WifiLockManager.java
+++ b/service/java/com/android/server/wifi/WifiLockManager.java
@@ -31,6 +31,7 @@
 import android.os.RemoteException;
 import android.os.WorkSource;
 import android.os.WorkSource.WorkChain;
+import android.text.TextUtils;
 import android.util.Log;
 import android.util.Pair;
 import android.util.SparseArray;
@@ -110,9 +111,9 @@
                     @Override
                     public void onReceive(Context context, Intent intent) {
                         String action = intent.getAction();
-                        if (action.equals(Intent.ACTION_SCREEN_ON)) {
+                        if (TextUtils.equals(action, Intent.ACTION_SCREEN_ON)) {
                             handleScreenStateChanged(true);
-                        } else if (action.equals(Intent.ACTION_SCREEN_OFF)) {
+                        } else if (TextUtils.equals(action, Intent.ACTION_SCREEN_OFF)) {
                             handleScreenStateChanged(false);
                         }
                     }
diff --git a/service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java b/service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java
index 2b59658..5e27d34 100644
--- a/service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java
+++ b/service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java
@@ -39,6 +39,7 @@
 import android.net.wifi.ISuggestionConnectionStatusListener;
 import android.net.wifi.ISuggestionUserApprovalStatusListener;
 import android.net.wifi.ScanResult;
+import android.net.wifi.SecurityParams;
 import android.net.wifi.WifiConfiguration;
 import android.net.wifi.WifiContext;
 import android.net.wifi.WifiEnterpriseConfig;
@@ -172,14 +173,22 @@
 
     private class OnNetworkUpdateListener implements
             WifiConfigManager.OnNetworkUpdateListener {
+
         @Override
         public void onConnectChoiceSet(@NonNull List<WifiConfiguration> networks,
                 String choiceKey, int rssi) {
-            onUserConnectChoiceSet(networks, choiceKey, rssi);
+            onUserConnectChoiceSetForSuggestion(networks, choiceKey, rssi);
         }
+
         @Override
         public void onConnectChoiceRemoved(String choiceKey) {
-            onUserConnectChoiceRemove(choiceKey);
+            onUserConnectChoiceRemoveForSuggestion(choiceKey);
+        }
+
+        @Override
+        public void onSecurityParamsUpdate(WifiConfiguration configuration,
+                List<SecurityParams> securityParams) {
+            onSecurityParamsUpdateForSuggestion(configuration, securityParams);
         }
     }
 
@@ -727,7 +736,7 @@
     }
 
     private void removeFromScanResultMatchInfoMapAndRemoveRelatedScoreCard(
-            @NonNull ExtendedWifiNetworkSuggestion extNetworkSuggestion) {
+            @NonNull ExtendedWifiNetworkSuggestion extNetworkSuggestion, boolean removeScoreCard) {
         ScanResultMatchInfo scanResultMatchInfo =
                 ScanResultMatchInfo.fromWifiConfiguration(
                         extNetworkSuggestion.wns.wifiConfiguration);
@@ -750,7 +759,9 @@
             if (extNetworkSuggestionsForScanResultMatchInfo.isEmpty()) {
                 mActiveScanResultMatchInfoWithBssid.remove(lookupPair);
                 if (!mActiveScanResultMatchInfoWithNoBssid.containsKey(scanResultMatchInfo)) {
-                    removeNetworkFromScoreCard(extNetworkSuggestion.wns.wifiConfiguration);
+                    if (removeScoreCard) {
+                        removeNetworkFromScoreCard(extNetworkSuggestion.wns.wifiConfiguration);
+                    }
                     mLruConnectionTracker.removeNetwork(
                             extNetworkSuggestion.wns.wifiConfiguration);
                 }
@@ -768,7 +779,9 @@
             // Remove the set from map if empty.
             if (extNetworkSuggestionsForScanResultMatchInfo.isEmpty()) {
                 mActiveScanResultMatchInfoWithNoBssid.remove(scanResultMatchInfo);
-                removeNetworkFromScoreCard(extNetworkSuggestion.wns.wifiConfiguration);
+                if (removeScoreCard) {
+                    removeNetworkFromScoreCard(extNetworkSuggestion.wns.wifiConfiguration);
+                }
                 mLruConnectionTracker.removeNetwork(
                         extNetworkSuggestion.wns.wifiConfiguration);
             }
@@ -1315,7 +1328,7 @@
             if (ewns.wns.wifiConfiguration.isEnterprise()) {
                 mWifiKeyStore.removeKeys(ewns.wns.wifiConfiguration.enterpriseConfig);
             }
-            removeFromScanResultMatchInfoMapAndRemoveRelatedScoreCard(ewns);
+            removeFromScanResultMatchInfoMapAndRemoveRelatedScoreCard(ewns, true);
             mWifiConfigManager.removeConnectChoiceFromAllNetworks(ewns
                     .createInternalWifiConfiguration(mWifiCarrierInfoManager)
                     .getProfileKey());
@@ -2644,8 +2657,8 @@
         return extendedWifiNetworkSuggestion.wns.wifiConfiguration.isOpenNetwork();
     }
 
-    private void onUserConnectChoiceSet(Collection<WifiConfiguration> networks, String choiceKey,
-            int rssi) {
+    private void onUserConnectChoiceSetForSuggestion(Collection<WifiConfiguration> networks,
+            String choiceKey, int rssi) {
         Set<String> networkKeys = networks.stream()
                 .filter(config -> config.fromWifiNetworkSuggestion)
                 .map(WifiConfiguration::getProfileKey)
@@ -2667,7 +2680,7 @@
         saveToStore();
     }
 
-    private void onUserConnectChoiceRemove(String choiceKey) {
+    private void onUserConnectChoiceRemoveForSuggestion(String choiceKey) {
         mActiveNetworkSuggestionsPerApp.values().stream()
                 .flatMap(e -> e.extNetworkSuggestions.values().stream())
                 .filter(ewns -> TextUtils.equals(ewns.connectChoice, choiceKey))
@@ -2743,4 +2756,22 @@
     private int getLingerDelayMs() {
         return SystemProperties.getInt(LINGER_DELAY_PROPERTY, DEFAULT_LINGER_DELAY_MS);
     }
+
+    private void onSecurityParamsUpdateForSuggestion(WifiConfiguration config,
+            List<SecurityParams> securityParams) {
+        Set<ExtendedWifiNetworkSuggestion> matchingExtendedWifiNetworkSuggestions =
+                        getNetworkSuggestionsForWifiConfiguration(config, config.BSSID);
+        if (matchingExtendedWifiNetworkSuggestions.isEmpty()) {
+            if (mVerboseLoggingEnabled) {
+                Log.w(TAG, "onSecurityParamsUpdateForSuggestion: no network matches: " + config);
+            }
+            return;
+        }
+        for (ExtendedWifiNetworkSuggestion ewns : matchingExtendedWifiNetworkSuggestions) {
+            removeFromScanResultMatchInfoMapAndRemoveRelatedScoreCard(ewns, false);
+            ewns.wns.wifiConfiguration.setSecurityParams(securityParams);
+            addToScanResultMatchInfoMap(ewns);
+        }
+        saveToStore();
+    }
 }
diff --git a/service/java/com/android/server/wifi/WifiServiceImpl.java b/service/java/com/android/server/wifi/WifiServiceImpl.java
index a1f34c2..04c3780 100644
--- a/service/java/com/android/server/wifi/WifiServiceImpl.java
+++ b/service/java/com/android/server/wifi/WifiServiceImpl.java
@@ -527,7 +527,9 @@
             if (!mWifiConfigManager.loadFromStore()) {
                 Log.e(TAG, "Failed to load from config store");
             }
-            mWifiConfigManager.updateTrustOnFirstUseFlag(isTrustOnFirstUseSupported());
+            if (!mWifiGlobals.isInsecureEnterpriseConfigurationAllowed()) {
+                mWifiConfigManager.updateTrustOnFirstUseFlag(isTrustOnFirstUseSupported());
+            }
             mWifiConfigManager.incrementNumRebootsSinceLastUse();
             // config store is read, check if verbose logging is enabled.
             enableVerboseLoggingInternal(
@@ -734,7 +736,7 @@
                         @Override
                         public void onReceive(Context context, Intent intent) {
                             String action = intent.getAction();
-                            if (action.equals(Intent.ACTION_USER_REMOVED)) {
+                            if (Intent.ACTION_USER_REMOVED.equals(action)) {
                                 UserHandle userHandle =
                                         intent.getParcelableExtra(Intent.EXTRA_USER);
                                 if (userHandle == null) {
@@ -744,8 +746,8 @@
                                 }
                                 mWifiConfigManager
                                         .removeNetworksForUser(userHandle.getIdentifier());
-                            } else if (action.equals(
-                                    BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED)) {
+                            } else if (BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED
+                                    .equals(action)) {
                                 int state = intent.getIntExtra(
                                         BluetoothAdapter.EXTRA_CONNECTION_STATE,
                                         BluetoothAdapter.STATE_DISCONNECTED);
@@ -756,7 +758,7 @@
                                         mActiveModeWarden.getClientModeManagers()) {
                                     cmm.onBluetoothConnectionStateChanged();
                                 }
-                            } else if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
+                            } else if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(action)) {
                                 int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,
                                         BluetoothAdapter.STATE_OFF);
                                 boolean isEnabled = state != BluetoothAdapter.STATE_OFF;
@@ -765,10 +767,10 @@
                                         mActiveModeWarden.getClientModeManagers()) {
                                     cmm.onBluetoothConnectionStateChanged();
                                 }
-                            } else if (action.equals(
-                                    PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED)) {
+                            } else if (PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED
+                                    .equals(action)) {
                                 handleIdleModeChanged();
-                            } else if (action.equals(Intent.ACTION_SHUTDOWN)) {
+                            } else if (Intent.ACTION_SHUTDOWN.equals(action)) {
                                 handleShutDown();
                             }
                         }
@@ -1485,6 +1487,35 @@
         mWifiThreadRunner.post(() -> mCoexManager.unregisterRemoteCoexCallback(callback));
     }
 
+    private Runnable mRecoverSoftApStateIfNeeded = new Runnable() {
+        @Override
+        public void run() {
+            mTetheredSoftApTracker.setFailedWhileEnabling();
+        }
+    };
+
+    private boolean checkSetEnablingIfAllowed() {
+        Boolean resultSetEnablingIfAllowed = mWifiThreadRunner.call(() -> {
+            if (mWifiThreadRunner.hasCallbacks(mRecoverSoftApStateIfNeeded)) {
+                Log.i(TAG, "An error happened, state is recovering, reject more requests");
+                return false;
+            }
+            return mTetheredSoftApTracker.setEnablingIfAllowed();
+        }, null);
+
+        if (resultSetEnablingIfAllowed == null) {
+            Log.i(TAG, "Timeout happened ! Recover SAP state if needed");
+            mWifiThreadRunner.removeCallbacks(mRecoverSoftApStateIfNeeded);
+            mWifiThreadRunner.post(mRecoverSoftApStateIfNeeded);
+            return false;
+        }
+
+        if (!resultSetEnablingIfAllowed) {
+            mLog.err("Tethering is already active or in recovering.").flush();
+        }
+        return resultSetEnablingIfAllowed;
+    }
+
     /**
      * see {@link android.net.wifi.WifiManager#startSoftAp(WifiConfiguration)}
      * @param wifiConfig SSID, security and channel details as part of WifiConfiguration
@@ -1508,8 +1539,8 @@
             }
         }
 
-        if (!mTetheredSoftApTracker.setEnablingIfAllowed()) {
-            mLog.err("Tethering is already active.").flush();
+        // TODO: b/233363886, handle timeout in general way.
+        if (!checkSetEnablingIfAllowed()) {
             return false;
         }
 
@@ -1553,9 +1584,8 @@
 
         mLog.info("startTetheredHotspot uid=%").c(callingUid).flush();
 
-        if (!mWifiThreadRunner.call(
-                () -> mTetheredSoftApTracker.setEnablingIfAllowed(), false)) {
-            mLog.err("Tethering is already active.").flush();
+        // TODO: b/233363886, handle timeout in general way.
+        if (!checkSetEnablingIfAllowed()) {
             return false;
         }
 
@@ -2017,8 +2047,7 @@
                         sendHotspotStartedMessageToAllLOHSRequestInfoEntriesLocked();
                         break;
                     case WifiManager.IFACE_IP_MODE_TETHERED:
-                        if (mLohsInterfaceName != null
-                                && mLohsInterfaceName.equals(ifaceName)) {
+                        if (TextUtils.equals(mLohsInterfaceName, ifaceName)) {
                             /* This shouldn't happen except in a race, but if it does, tear down
                              * the LOHS and let tethering win.
                              *
@@ -2040,7 +2069,7 @@
                             sendHotspotFailedMessageToAllLOHSRequestInfoEntriesLocked(
                                     LocalOnlyHotspotCallback.ERROR_GENERIC);
                             stopSoftApInternal(WifiManager.IFACE_IP_MODE_UNSPECIFIED);
-                        } else if (ifaceName.equals(mLohsInterfaceName)) {
+                        } else if (TextUtils.equals(mLohsInterfaceName, ifaceName)) {
                             mLohsInterfaceName = null;
                             mLohsInterfaceMode = mode;
                             sendHotspotFailedMessageToAllLOHSRequestInfoEntriesLocked(
@@ -3359,7 +3388,7 @@
 
         // if we're being called from the SYSTEM_UID then allow usage of the AttributionSource to
         // reassign the WifiConfiguration to another app (reassignment == creatorUid)
-        if (SdkLevel.isAtLeastS() && uidToUse == Process.SYSTEM_UID) {
+        if (SdkLevel.isAtLeastS() && UserHandle.getAppId(uidToUse) == Process.SYSTEM_UID) {
             if (extras == null) {
                 throw new SecurityException("extras bundle is null");
             }
@@ -3490,8 +3519,7 @@
 
         if (config.isEnterprise() && config.enterpriseConfig.isEapMethodServerCertUsed()
                 && !config.enterpriseConfig.isMandatoryParameterSetForServerCertValidation()) {
-            if (!(mContext.getResources().getBoolean(
-                    R.bool.config_wifiAllowInsecureEnterpriseConfigurationsForSettingsAndSUW)
+            if (!(mWifiGlobals.isInsecureEnterpriseConfigurationAllowed()
                     && isSettingsOrSuw(Binder.getCallingPid(), Binder.getCallingUid()))) {
                 Log.e(TAG, "Enterprise network configuration is missing either a Root CA "
                         + "or a domain name");
@@ -4510,7 +4538,7 @@
                     String ip = tokens[0];
                     String mac = tokens[3];
 
-                    if (remoteIpAddress.equals(ip)) {
+                    if (TextUtils.equals(remoteIpAddress, ip)) {
                         macAddress = mac;
                         break;
                     }
diff --git a/service/java/com/android/server/wifi/WifiShellCommand.java b/service/java/com/android/server/wifi/WifiShellCommand.java
index 8d4ece7..367979f 100644
--- a/service/java/com/android/server/wifi/WifiShellCommand.java
+++ b/service/java/com/android/server/wifi/WifiShellCommand.java
@@ -416,7 +416,7 @@
     @Override
     public int onCommand(String cmd) {
         // Treat no command as help command.
-        if (cmd == null || cmd.equals("")) {
+        if (TextUtils.isEmpty(cmd)) {
             cmd = "help";
         }
         // Explicit exclusion from root permission
diff --git a/service/java/com/android/server/wifi/WifiThreadRunner.java b/service/java/com/android/server/wifi/WifiThreadRunner.java
index 64ec5b2..1009d94 100644
--- a/service/java/com/android/server/wifi/WifiThreadRunner.java
+++ b/service/java/com/android/server/wifi/WifiThreadRunner.java
@@ -181,6 +181,16 @@
         mHandler.removeCallbacks(r);
     }
 
+    /**
+     * Check if there are any pending posts of messages with callback r in the message queue.
+     *
+     * @param r The Runnable that will be used to query.
+     * @return true if exists, otherwise false.
+     */
+    public final boolean hasCallbacks(@NonNull Runnable r) {
+        return mHandler.hasCallbacks(r);
+    }
+
     // Note: @hide methods copied from android.os.Handler
     /**
      * Runs the specified task synchronously.
diff --git a/service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java b/service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java
index 5527ec9..c417758 100644
--- a/service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java
+++ b/service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java
@@ -767,8 +767,8 @@
         String packageNameToUse = packageName;
 
         // if we're being called from the SYSTEM_UID then allow usage of the AttributionSource to
-        // reassign the WifiConfiguration to another app (reassignment == creatorUid)
-        if (SdkLevel.isAtLeastS() && callerUid == Process.SYSTEM_UID) {
+        // locate the original caller.
+        if (SdkLevel.isAtLeastS() && UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
             if (extras == null) {
                 throw new SecurityException("extras bundle is null");
             }
@@ -4445,6 +4445,9 @@
             Log.i(TAG, "sending p2p tether request broadcast to "
                     + tetheringServicePackage);
 
+            final String[] receiverPermissionsForTetheringRequest = {
+                    android.Manifest.permission.TETHER_PRIVILEGED
+            };
             Intent intent = new Intent(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
             intent.setPackage(tetheringServicePackage);
             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
@@ -4454,7 +4457,7 @@
 
             Context context = mContext.createContextAsUser(UserHandle.ALL, 0);
             context.sendBroadcastWithMultiplePermissions(
-                    intent, RECEIVER_PERMISSIONS_FOR_BROADCAST);
+                    intent, receiverPermissionsForTetheringRequest);
             return true;
         }
 
@@ -5946,7 +5949,7 @@
             if (clientInfo != null) {
                 return clientInfo.mPackageName;
             }
-            if (uid == Process.SYSTEM_UID) return mContext.getOpPackageName();
+            if (UserHandle.getAppId(uid) == Process.SYSTEM_UID) return mContext.getOpPackageName();
             return null;
         }
 
@@ -5961,7 +5964,7 @@
             if (clientInfo != null) {
                 return clientInfo.mFeatureId;
             }
-            if (uid == Process.SYSTEM_UID) return mContext.getAttributionTag();
+            if (UserHandle.getAppId(uid) == Process.SYSTEM_UID) return mContext.getAttributionTag();
             return null;
         }
 
diff --git a/service/java/com/android/server/wifi/util/IpConfigStore.java b/service/java/com/android/server/wifi/util/IpConfigStore.java
index e12f75f..2a719c4 100644
--- a/service/java/com/android/server/wifi/util/IpConfigStore.java
+++ b/service/java/com/android/server/wifi/util/IpConfigStore.java
@@ -112,14 +112,14 @@
                 do {
                     key = in.readUTF();
                     try {
-                        if (key.equals(ID_KEY)) {
+                        if (ID_KEY.equals(key)) {
                             if (version < 3) {
                                 int id = in.readInt();
                                 uniqueToken = String.valueOf(id);
                             } else {
                                 uniqueToken = in.readUTF();
                             }
-                        } else if (key.equals(IP_ASSIGNMENT_KEY)) {
+                        } else if (IP_ASSIGNMENT_KEY.equals(key)) {
                             ipAssignment = IpAssignment.valueOf(in.readUTF());
                         } else if (key.equals(LINK_ADDRESS_KEY)) {
                             LinkAddress linkAddr = new LinkAddress(
@@ -127,7 +127,7 @@
                             if (linkAddr.getAddress() instanceof Inet4Address) {
                                 staticIPBuilder.setIpAddress(linkAddr);
                             }
-                        } else if (key.equals(GATEWAY_KEY)) {
+                        } else if (GATEWAY_KEY.equals(key)) {
                             LinkAddress dest = null;
                             InetAddress gateway = null;
                             if (version == 1) {
@@ -155,19 +155,19 @@
                                     loge("Non-IPv4 default or duplicate route: " + route);
                                 }
                             }
-                        } else if (key.equals(DNS_KEY)) {
+                        } else if (DNS_KEY.equals(key)) {
                             dnsServerAddresses.add(InetAddresses.parseNumericAddress(in.readUTF()));
-                        } else if (key.equals(PROXY_SETTINGS_KEY)) {
+                        } else if (PROXY_SETTINGS_KEY.equals(key)) {
                             proxySettings = ProxySettings.valueOf(in.readUTF());
-                        } else if (key.equals(PROXY_HOST_KEY)) {
+                        } else if (PROXY_HOST_KEY.equals(key)) {
                             proxyHost = in.readUTF();
-                        } else if (key.equals(PROXY_PORT_KEY)) {
+                        } else if (PROXY_PORT_KEY.equals(key)) {
                             proxyPort = in.readInt();
-                        } else if (key.equals(PROXY_PAC_FILE)) {
+                        } else if (PROXY_PAC_FILE.equals(key)) {
                             pacFileUrl = in.readUTF();
-                        } else if (key.equals(EXCLUSION_LIST_KEY)) {
+                        } else if (EXCLUSION_LIST_KEY.equals(key)) {
                             exclusionList = in.readUTF();
-                        } else if (key.equals(EOS)) {
+                        } else if (EOS.equals(key)) {
                             break;
                         } else {
                             loge("Ignore unknown key " + key + "while reading");
diff --git a/service/java/com/android/server/wifi/util/WifiPermissionsUtil.java b/service/java/com/android/server/wifi/util/WifiPermissionsUtil.java
index 8228bba..4c0c7ef 100644
--- a/service/java/com/android/server/wifi/util/WifiPermissionsUtil.java
+++ b/service/java/com/android/server/wifi/util/WifiPermissionsUtil.java
@@ -1069,6 +1069,11 @@
             return false;
         }
         String[] packages = mContext.getPackageManager().getPackagesForUid(uid);
+        if (packages == null) {
+            Log.w(TAG, "isProfileOwnerOfOrganizationOwnedDevice(): could not find packages for uid="
+                    + uid);
+            return false;
+        }
         for (String packageName : packages) {
             if (devicePolicyManager.isProfileOwnerApp(packageName)) return true;
         }
@@ -1152,7 +1157,7 @@
      * @return true if the given UID belongs to the given user.
      */
     public boolean doesUidBelongToUser(int uid, int userId) {
-        if (uid == android.os.Process.SYSTEM_UID
+        if (UserHandle.getAppId(uid) == android.os.Process.SYSTEM_UID
                 // UIDs with the NETWORK_SETTINGS permission are always allowed since they are
                 // acting on behalf of the user.
                 || checkNetworkSettingsPermission(uid)) {
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 f410a54..ca8f5b0 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java
@@ -2205,12 +2205,16 @@
         verify(mWifiLastResortWatchdog, times(2)).noteConnectionFailureAndTriggerIfNeeded(
                 eq(TEST_SSID), eq(TEST_BSSID_STR),
                 eq(WifiLastResortWatchdog.FAILURE_CODE_DHCP), anyBoolean());
-        verify(mWifiBlocklistMonitor, times(2)).handleBssidConnectionFailure(eq(TEST_BSSID_STR),
+        verify(mWifiBlocklistMonitor).handleBssidConnectionFailure(eq(TEST_BSSID_STR),
                 eq(mTestConfig), eq(WifiBlocklistMonitor.REASON_DHCP_FAILURE), anyInt());
         verify(mWifiBlocklistMonitor, never()).handleDhcpProvisioningSuccess(
                 TEST_BSSID_STR, TEST_SSID);
         verify(mWifiBlocklistMonitor, never()).handleNetworkValidationSuccess(
                 TEST_BSSID_STR, TEST_SSID);
+        DisconnectEventInfo disconnectEventInfo =
+                new DisconnectEventInfo(mConnectedNetwork.SSID, TEST_BSSID_STR, 3, true);
+        mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, disconnectEventInfo);
+        mLooper.dispatchAll();
     }
 
     /**
@@ -4302,17 +4306,17 @@
                 .setCandidate(getGoogleGuestScanDetail(TEST_RSSI, TEST_BSSID_STR, sFreq)
                         .getScanResult());
         testDhcpFailure();
-        verify(mWifiDiagnostics, atLeastOnce()).reportConnectionEvent(
+        verify(mWifiDiagnostics).reportConnectionEvent(
                 eq(WifiDiagnostics.CONNECTION_EVENT_FAILED), any());
-        verify(mWifiConnectivityManager, atLeastOnce()).handleConnectionAttemptEnded(
+        verify(mWifiConnectivityManager).handleConnectionAttemptEnded(
                 mClientModeManager,
                 WifiMetrics.ConnectionEvent.FAILURE_DHCP,
                 WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN, TEST_BSSID_STR,
                 mTestConfig);
-        verify(mWifiNetworkFactory, atLeastOnce()).handleConnectionAttemptEnded(
+        verify(mWifiNetworkFactory).handleConnectionAttemptEnded(
                 eq(WifiMetrics.ConnectionEvent.FAILURE_DHCP), any(WifiConfiguration.class),
                 eq(TEST_BSSID_STR));
-        verify(mWifiNetworkSuggestionsManager, atLeastOnce()).handleConnectionAttemptEnded(
+        verify(mWifiNetworkSuggestionsManager).handleConnectionAttemptEnded(
                 eq(WifiMetrics.ConnectionEvent.FAILURE_DHCP), any(WifiConfiguration.class),
                 any(String.class));
         verify(mWifiMetrics, never())
diff --git a/service/tests/wifitests/src/com/android/server/wifi/ExternalPnoScanRequestManagerTest.java b/service/tests/wifitests/src/com/android/server/wifi/ExternalPnoScanRequestManagerTest.java
index d5e9730..8574809 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/ExternalPnoScanRequestManagerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/ExternalPnoScanRequestManagerTest.java
@@ -96,8 +96,7 @@
 
     @Test
     public void testSetRequest_success() throws RemoteException {
-        IPnoScanResultsCallback anotherCallback = mock(IPnoScanResultsCallback.class);
-        InOrder inOrder = inOrder(mCallback, anotherCallback, mIBinder);
+        InOrder inOrder = inOrder(mCallback, mIBinder);
 
         // initial register should be successful
         assertTrue(mExternalPnoScanRequestManager.setRequest(TEST_UID, TEST_PACKAGE, mIBinder,
@@ -107,15 +106,13 @@
 
         // Another register with same uid should override the existing one.
         assertTrue(mExternalPnoScanRequestManager.setRequest(TEST_UID, TEST_PACKAGE, mIBinder,
-                anotherCallback, TEST_WIFI_SSIDS, TEST_FREQUENCIES_2));
-        inOrder.verify(anotherCallback).onRegisterSuccess();
-        // Verify the original callback has been removed
-        inOrder.verify(mCallback).onRemoved(anyInt());
+                mCallback, TEST_WIFI_SSIDS, TEST_FREQUENCIES_2));
+        inOrder.verify(mCallback).onRegisterSuccess();
 
         // Another register with different uid should fail with REGISTER_PNO_CALLBACK_RESOURCE_BUSY
         assertFalse(mExternalPnoScanRequestManager.setRequest(TEST_UID + 1, TEST_PACKAGE,
-                mIBinder, anotherCallback, TEST_WIFI_SSIDS, TEST_FREQUENCIES));
-        inOrder.verify(anotherCallback).onRegisterFailed(REGISTER_PNO_CALLBACK_RESOURCE_BUSY);
+                mIBinder, mCallback, TEST_WIFI_SSIDS, TEST_FREQUENCIES));
+        inOrder.verify(mCallback).onRegisterFailed(REGISTER_PNO_CALLBACK_RESOURCE_BUSY);
 
 
         assertEquals(EXPECTED_SSIDS_SET, mExternalPnoScanRequestManager.getExternalPnoScanSsids());
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 061bad1..f87cd1f 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/HalDeviceManagerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/HalDeviceManagerTest.java
@@ -3264,16 +3264,68 @@
     }
 
     /**
-     * Validate creation of AP Bridge interface from blank start-up in chip V1.6
+     * Validate creation of AP Bridge interface from blank start-up in TestChipV6
      */
     @Test
-    public void testCreateApBridgeInterfaceNoInitModeTestChipV16() throws Exception {
+    public void testCreateApBridgeInterfaceNoInitModeTestChipV6() throws Exception {
         TestChipV6 testChip = new TestChipV6();
         setupWifiChipV15(testChip);
         runCreateSingleXxxInterfaceNoInitMode(testChip, HDM_CREATE_IFACE_AP_BRIDGE, "wlan0",
                 TestChipV6.CHIP_MODE_ID);
     }
 
+    /**
+     * Validate creation of STA will not downgrade an AP Bridge interface in TestChipV6, since it
+     * can support STA and AP Bridge concurrently.
+     */
+    @Test
+    public void testCreateStaDoesNotDowngradeApBridgeInterfaceTestChipV6() throws Exception {
+        mIsBridgedSoftApSupported = true;
+        mIsStaWithBridgedSoftApConcurrencySupported = false;
+        TestChipV6 chipMock = new TestChipV6();
+        setupWifiChipV15(chipMock);
+        chipMock.initialize();
+        mInOrder = inOrder(mServiceManagerMock, mWifiMock, mWifiMockV15, chipMock.chip,
+                mWifiChipV15, mManagerStatusListenerMock);
+        executeAndValidateInitializationSequence();
+        executeAndValidateStartupSequence();
+
+        InterfaceDestroyedListener idl = mock(
+                InterfaceDestroyedListener.class);
+
+        // Create the bridged AP
+        ArrayList<String> bridgedApInstances = new ArrayList<>();
+        bridgedApInstances.add("instance0");
+        bridgedApInstances.add("instance1");
+        chipMock.bridgedApInstancesByName.put("wlan0", bridgedApInstances);
+        IWifiIface iface = validateInterfaceSequence(chipMock,
+                false, // chipModeValid
+                -1000, // chipModeId (only used if chipModeValid is true)
+                HDM_CREATE_IFACE_AP_BRIDGE,
+                "wlan0",
+                TestChipV6.CHIP_MODE_ID,
+                null, // tearDownList
+                idl, // destroyedListener
+                TEST_WORKSOURCE_0 // requestorWs
+        );
+        collector.checkThat("interface was null", iface, IsNull.notNullValue());
+
+        when(mSoftApManager.getBridgedApDowngradeIfaceInstanceForRemoval()).thenReturn("instance1");
+        // Should be able to create a STA without downgrading the bridged AP
+        iface = validateInterfaceSequence(chipMock,
+                true, // chipModeValid
+                TestChipV6.CHIP_MODE_ID,
+                HDM_CREATE_IFACE_STA,
+                "wlan3",
+                TestChipV6.CHIP_MODE_ID,
+                null, // tearDownList
+                idl, // destroyedListener
+                TEST_WORKSOURCE_0 // requestorWs
+        );
+        collector.checkThat("interface was null", iface, IsNull.notNullValue());
+        assertEquals(2, bridgedApInstances.size());
+    }
+
     private IWifiIface setupDbsSupportTest(ChipMockBase testChip, int onlyChipMode,
             ImmutableList<ArrayList<Integer>> radioCombinationMatrix) throws Exception {
         WifiRadioCombinationMatrix matrix = new WifiRadioCombinationMatrix();
diff --git a/service/tests/wifitests/src/com/android/server/wifi/InsecureEapNetworkHandlerTest.java b/service/tests/wifitests/src/com/android/server/wifi/InsecureEapNetworkHandlerTest.java
index 546e322..aed3753 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/InsecureEapNetworkHandlerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/InsecureEapNetworkHandlerTest.java
@@ -326,6 +326,12 @@
 
     private void setupTest(WifiConfiguration config,
             boolean isAtLeastT, boolean isTrustOnFirstUseSupported) {
+        setupTest(config, isAtLeastT, isTrustOnFirstUseSupported, false);
+    }
+
+    private void setupTest(WifiConfiguration config,
+            boolean isAtLeastT, boolean isTrustOnFirstUseSupported,
+            boolean isInsecureEnterpriseConfigurationAllowed) {
         mInsecureEapNetworkHandler = new InsecureEapNetworkHandler(
                 mContext,
                 mWifiConfigManager,
@@ -333,19 +339,23 @@
                 mFrameworkFacade,
                 mWifiNotificationManager,
                 mWifiDialogManager, isTrustOnFirstUseSupported,
+                isInsecureEnterpriseConfigurationAllowed,
                 mCallbacks,
                 WIFI_IFACE_NAME,
                 mHandler);
 
         mInsecureEapNetworkHandler.prepareConnection(config);
 
-        if (isAtLeastT && isTrustOnFirstUseSupported) {
+        if (isTrustOnFirstUseSupported && config.enterpriseConfig.isTrustOnFirstUseEnabled()) {
             verify(mContext, atLeastOnce()).registerReceiver(
                     mBroadcastReceiverCaptor.capture(),
                     argThat(f -> f.hasAction(InsecureEapNetworkHandler.ACTION_CERT_NOTIF_TAP)),
                     eq(null),
                     eq(mHandler));
-        } else {
+        } else if ((isTrustOnFirstUseSupported
+                && !config.enterpriseConfig.isTrustOnFirstUseEnabled()
+                && isInsecureEnterpriseConfigurationAllowed)
+                || !isTrustOnFirstUseSupported) {
             verify(mContext, atLeastOnce()).registerReceiver(
                     mBroadcastReceiverCaptor.capture(),
                     argThat(f -> f.hasAction(InsecureEapNetworkHandler.ACTION_CERT_NOTIF_ACCEPT)
@@ -420,6 +430,75 @@
                 isUserSelected, needUserApproval, FakeKeys.CA_CERT0, FakeKeys.CA_CERT0);
     }
 
+    /**
+     * Verify that the connection should be terminated.
+     * - TOFU is supported.
+     * - Insecure EAP network is not allowed.
+     * - No cert is received.
+     */
+    @Test
+    public void verifyOnErrorWithoutCert() throws Exception {
+        assumeTrue(SdkLevel.isAtLeastT());
+        boolean isAtLeastT = true, isTrustOnFirstUseSupported = true, isUserSelected = true;
+        boolean needUserApproval = true;
+
+        WifiConfiguration config = prepareWifiConfiguration(isAtLeastT);
+        setupTest(config, isAtLeastT, isTrustOnFirstUseSupported);
+
+        assertEquals(needUserApproval,
+                mInsecureEapNetworkHandler.startUserApprovalIfNecessary(isUserSelected));
+        verify(mCallbacks).onError(eq(config.SSID));
+    }
+
+    /**
+     * Verify that the connection should be terminated.
+     * - TOFU is supported.
+     * - Insecure EAP network is not allowed.
+     * - TOFU is not enabled
+     */
+    @Test
+    public void verifyOnErrorWithTofuDisabledWhenInsecureEapNetworkIsNotAllowed()
+            throws Exception {
+        assumeTrue(SdkLevel.isAtLeastT());
+        boolean isAtLeastT = true, isTrustOnFirstUseSupported = true, isUserSelected = true;
+        boolean needUserApproval = true;
+
+        WifiConfiguration config = prepareWifiConfiguration(isAtLeastT);
+        config.enterpriseConfig.enableTrustOnFirstUse(false);
+        setupTest(config, isAtLeastT, isTrustOnFirstUseSupported);
+
+        mInsecureEapNetworkHandler.setPendingCertificate(config.SSID, 0, FakeKeys.CA_CERT0);
+
+        assertEquals(needUserApproval,
+                mInsecureEapNetworkHandler.startUserApprovalIfNecessary(isUserSelected));
+        verify(mCallbacks).onError(eq(config.SSID));
+    }
+
+    /**
+     * Verify that no error occurs in insecure network handling flow.
+     * - TOFU is supported.
+     * - Insecure EAP network is allowed.
+     * - TOFU is not enabled
+     */
+    @Test
+    public void verifyNoErrorWithTofuDisabledWhenInsecureEapNetworkIsAllowed()
+            throws Exception {
+        assumeTrue(SdkLevel.isAtLeastT());
+        boolean isAtLeastT = true, isTrustOnFirstUseSupported = true, isUserSelected = true;
+        boolean needUserApproval = true, isInsecureEnterpriseConfigurationAllowed = true;
+
+        WifiConfiguration config = prepareWifiConfiguration(isAtLeastT);
+        config.enterpriseConfig.enableTrustOnFirstUse(false);
+        setupTest(config, isAtLeastT, isTrustOnFirstUseSupported,
+                isInsecureEnterpriseConfigurationAllowed);
+
+        mInsecureEapNetworkHandler.setPendingCertificate(config.SSID, 0, FakeKeys.CA_CERT0);
+
+        assertEquals(needUserApproval,
+                mInsecureEapNetworkHandler.startUserApprovalIfNecessary(isUserSelected));
+        verify(mCallbacks, never()).onError(any());
+    }
+
     private void verifyTrustOnFirstUseFlowWithDefaultCerts(WifiConfiguration config,
             int action, boolean isTrustOnFirstUseSupported, boolean isUserSelected,
             boolean needUserApproval) throws Exception {
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 4f5ac81..8d0a9f6 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java
@@ -6766,6 +6766,7 @@
         int disabledType = testNetwork.getDefaultSecurityParams().getSecurityType();
         NetworkUpdateResult result = verifyAddNetworkToWifiConfigManager(testNetwork);
         int networkId = result.getNetworkId();
+        mWifiConfigManager.addOnNetworkUpdateListener(mListener);
 
         WifiConfiguration configBefore = mWifiConfigManager.getConfiguredNetwork(networkId);
         assertTrue(configBefore.getSecurityParams(disabledType).isEnabled());
@@ -6774,6 +6775,7 @@
 
         WifiConfiguration configAfter = mWifiConfigManager.getConfiguredNetwork(networkId);
         assertFalse(configAfter.getSecurityParams(disabledType).isEnabled());
+        verify(mListener).onSecurityParamsUpdate(any(), eq(configAfter.getSecurityParamsList()));
     }
 
     /**
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiCountryCodeTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiCountryCodeTest.java
index 1b7fe5b..e981df3 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiCountryCodeTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiCountryCodeTest.java
@@ -523,6 +523,33 @@
     }
 
     @Test
+    public void testNotifyExternalListenerWhenOverlayisTrueButCountryCodeSameAsLastActiveOne()
+            throws Exception {
+        mDriverSupportedNl80211RegChangedEvent = true;
+        createWifiCountryCode();
+        // External caller register the listener
+        mWifiCountryCode.registerListener(mExternalChangeListener);
+        // Supplicant started.
+        mModeChangeCallbackCaptor.getValue().onActiveModeManagerAdded(mClientModeManager);
+        // Wifi get L2 connected.
+        mClientModeImplListenerCaptor.getValue().onConnectionStart(mClientModeManager);
+        verify(mClientModeManager).setCountryCode(mDefaultCountryCode);
+        assertEquals(mDefaultCountryCode, mWifiCountryCode.getCurrentDriverCountryCode());
+        verify(mExternalChangeListener).onDriverCountryCodeChanged(mDefaultCountryCode);
+        // First time it should not trigger since last active country code is null.
+        verify(mWifiNative, never()).countryCodeChanged(any());
+        // Remove and add client mode manager again.
+        mModeChangeCallbackCaptor.getValue().onActiveModeManagerRemoved(mClientModeManager);
+        assertNull(mWifiCountryCode.getCurrentDriverCountryCode());
+        mModeChangeCallbackCaptor.getValue().onActiveModeManagerAdded(mClientModeManager);
+        verify(mClientModeManager, times(2)).setCountryCode(mDefaultCountryCode);
+        // Second time it would notify the wificond since it is same as last active country code
+        verify(mWifiNative).countryCodeChanged(mDefaultCountryCode);
+        assertEquals(mDefaultCountryCode, mWifiCountryCode.getCurrentDriverCountryCode());
+        verify(mExternalChangeListener, times(2)).onDriverCountryCodeChanged(mDefaultCountryCode);
+    }
+
+    @Test
     public void testSetTelephonyCountryCodeAndUpdateWithEmptyCCReturnFalseWhenDefaultSIMCCExist()
             throws Exception {
         when(mTelephonyManager.getNetworkCountryIso()).thenReturn(mTelephonyCountryCode);
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 a1afe2b..6ac3632 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiNetworkSuggestionsManagerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiNetworkSuggestionsManagerTest.java
@@ -5232,4 +5232,49 @@
                 mWifiNetworkSuggestionsManager.add(List.of(networkSuggestion), TEST_UID_1,
                 TEST_PACKAGE_1, TEST_FEATURE));
     }
+
+    @Test
+    public void testOnNetworkConnectionSuccessWithMatchAndNetworkTransitionDisable()
+            throws Exception {
+        assertTrue(mWifiNetworkSuggestionsManager.registerSuggestionConnectionStatusListener(
+                mConnectionStatusListener, TEST_PACKAGE_1, TEST_UID_1));
+        WifiNetworkSuggestion networkSuggestion = createWifiNetworkSuggestion(
+                WifiConfigurationTestUtil.createPskNetwork(), null, true, false, true, true,
+                DEFAULT_PRIORITY_GROUP);
+        List<WifiNetworkSuggestion> networkSuggestionList =
+                new ArrayList<WifiNetworkSuggestion>() {{
+                    add(networkSuggestion);
+                }};
+        assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS,
+                mWifiNetworkSuggestionsManager.add(networkSuggestionList, TEST_UID_1,
+                        TEST_PACKAGE_1, TEST_FEATURE));
+        mWifiNetworkSuggestionsManager.setHasUserApprovedForApp(true, TEST_UID_1, TEST_PACKAGE_1);
+
+        // Simulate connecting to the network.
+        WifiConfiguration connectNetwork =
+                new WifiConfiguration(networkSuggestion.wifiConfiguration);
+        connectNetwork.fromWifiNetworkSuggestion = true;
+        connectNetwork.shared = false;
+        connectNetwork.ephemeral = true;
+        connectNetwork.creatorName = TEST_PACKAGE_1;
+        connectNetwork.creatorUid = TEST_UID_1;
+        WifiConfiguration updated = new WifiConfiguration(connectNetwork);
+        updated.setSecurityParamsEnabled(WifiConfiguration.SECURITY_TYPE_PSK, false);
+
+        // Update to handle Network Transition Disable
+        mNetworkListenerCaptor.getValue().onSecurityParamsUpdate(connectNetwork,
+                updated.getSecurityParamsList());
+        mWifiNetworkSuggestionsManager.handleConnectionAttemptEnded(
+                WifiMetrics.ConnectionEvent.FAILURE_NONE, updated, TEST_BSSID);
+
+        verify(mWifiMetrics).incrementNetworkSuggestionApiNumConnectSuccess();
+
+        // Verify that the correct broadcast was sent out.
+        mInorder.verify(mWifiPermissionsUtil).enforceCanAccessScanResults(eq(TEST_PACKAGE_1),
+                eq(TEST_FEATURE), eq(TEST_UID_1), nullable(String.class));
+        validatePostConnectionBroadcastSent(TEST_PACKAGE_1, networkSuggestion);
+
+        // Verify no more broadcast were sent out.
+        mInorder.verifyNoMoreInteractions();
+    }
 }
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 79ad100..019e689 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java
@@ -9155,9 +9155,7 @@
                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
 
         // First set flag to not allow
-        when(mResources.getBoolean(
-                R.bool.config_wifiAllowInsecureEnterpriseConfigurationsForSettingsAndSUW))
-                .thenReturn(false);
+        when(mWifiGlobals.isInsecureEnterpriseConfigurationAllowed()).thenReturn(false);
         when(mWifiConfigManager.addOrUpdateNetwork(any(),  anyInt(), any(), eq(false))).thenReturn(
                 new NetworkUpdateResult(0));
 
@@ -9174,9 +9172,7 @@
         verify(mWifiConfigManager, never()).addOrUpdateNetwork(any(),  anyInt(), any(), eq(false));
 
         // Set flag to allow
-        when(mResources.getBoolean(
-                R.bool.config_wifiAllowInsecureEnterpriseConfigurationsForSettingsAndSUW))
-                .thenReturn(true);
+        when(mWifiGlobals.isInsecureEnterpriseConfigurationAllowed()).thenReturn(true);
 
         // Verify operation succeeds
         mLooper.startAutoDispatch();
@@ -9196,9 +9192,7 @@
     @Test
     public void testAddInsecureEnterpirseNetworkWithNoNetworkSettingsPerm() throws Exception {
         // First set flag to not allow
-        when(mResources.getBoolean(
-                R.bool.config_wifiAllowInsecureEnterpriseConfigurationsForSettingsAndSUW))
-                .thenReturn(false);
+        when(mWifiGlobals.isInsecureEnterpriseConfigurationAllowed()).thenReturn(false);
 
         // Create an insecure Enterprise network
         WifiConfiguration config = WifiConfigurationTestUtil.createEapNetwork();
@@ -9213,9 +9207,7 @@
         verify(mWifiConfigManager, never()).addOrUpdateNetwork(any(),  anyInt(), any(), eq(false));
 
         // Set flag to allow
-        when(mResources.getBoolean(
-                R.bool.config_wifiAllowInsecureEnterpriseConfigurationsForSettingsAndSUW))
-                .thenReturn(true);
+        when(mWifiGlobals.isInsecureEnterpriseConfigurationAllowed()).thenReturn(true);
 
         // Verify operation still fails
         mLooper.startAutoDispatch();
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 bbb301c..b2e844b 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
@@ -6528,4 +6528,27 @@
         sendSimpleMsg(null, WifiP2pServiceImpl.PEER_CONNECTION_USER_REJECT);
         verify(mWifiNative).p2pReject(eq(mTestWifiP2pDevice.deviceAddress));
     }
+
+    /**
+     * Verify the tethering request is sent with TETHER_PRIVILEGED permission.
+     */
+    @Test
+    public void testTetheringRequestWithTetherPrivilegedPermission() throws Exception {
+        mockEnterGroupCreatedState();
+
+        String[] permission_gold = new String[] {
+                android.Manifest.permission.TETHER_PRIVILEGED};
+        ArgumentCaptor<String []> permissionCaptor = ArgumentCaptor.forClass(String[].class);
+        // 2 connection changed event:
+        // * Enter Enabled state
+        // * Tethering request.
+        verify(mContext, times(2)).sendBroadcastWithMultiplePermissions(
+                argThat(new WifiP2pServiceImplTest
+                       .P2pConnectionChangedIntentMatcherForNetworkState(IDLE)),
+                permissionCaptor.capture());
+        String[] permission = permissionCaptor.getAllValues().get(1);
+        Arrays.sort(permission);
+        Arrays.sort(permission_gold);
+        assertEquals(permission_gold, permission);
+    }
 }
diff --git a/service/tests/wifitests/src/com/android/server/wifi/util/WifiPermissionsUtilTest.java b/service/tests/wifitests/src/com/android/server/wifi/util/WifiPermissionsUtilTest.java
index 0e1d9b1..33bedd4 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/util/WifiPermissionsUtilTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/util/WifiPermissionsUtilTest.java
@@ -1059,9 +1059,18 @@
         when(mDevicePolicyManager.isProfileOwnerApp(TEST_PACKAGE_NAME)).thenReturn(false);
         assertFalse(wifiPermissionsUtil.isProfileOwnerOfOrganizationOwnedDevice(
                 MANAGED_PROFILE_UID));
+        when(mDevicePolicyManager.isProfileOwnerApp(TEST_PACKAGE_NAME)).thenReturn(true);
+
+        // Package does not exist for uid.
+        when(mMockContext.getPackageManager().getPackagesForUid(MANAGED_PROFILE_UID))
+                .thenReturn(null);
+        assertFalse(wifiPermissionsUtil.isProfileOwnerOfOrganizationOwnedDevice(
+                MANAGED_PROFILE_UID));
+        when(mMockContext.getPackageManager().getPackagesForUid(MANAGED_PROFILE_UID))
+                .thenReturn(packageNames);
 
         // DevicePolicyManager does not exist.
-        when(mMockContext.getSystemService(Context.DEVICE_POLICY_SERVICE))
+        when(mMockContext.getSystemService(DevicePolicyManager.class))
                 .thenReturn(null);
         assertFalse(wifiPermissionsUtil.isProfileOwnerOfOrganizationOwnedDevice(
                 MANAGED_PROFILE_UID));