Snap for 7802582 from 4b7830e6ee8ae66d3396ed6b94a74613c5a3beb9 to mainline-art-release

Change-Id: I31a499e47eb5a81b7b162181919123e15c3db91e
diff --git a/framework/java/android/net/wifi/hotspot2/pps/UpdateParameter.java b/framework/java/android/net/wifi/hotspot2/pps/UpdateParameter.java
index 4a8aa36..8a2bfa4 100644
--- a/framework/java/android/net/wifi/hotspot2/pps/UpdateParameter.java
+++ b/framework/java/android/net/wifi/hotspot2/pps/UpdateParameter.java
@@ -52,7 +52,7 @@
      * Valid string for UpdateMethod.
      */
     public static final String UPDATE_METHOD_OMADM = "OMA-DM-ClientInitiated";
-    public static final String UPDATE_METHOD_SSP = "SSP-ClientInitiated";
+    public static final String UPDATE_METHOD_SPP = "SPP-ClientInitiated";
 
     /**
      * Valid string for Restriction.
@@ -308,7 +308,7 @@
         }
 
         if (!TextUtils.equals(mUpdateMethod, UPDATE_METHOD_OMADM)
-                && !TextUtils.equals(mUpdateMethod, UPDATE_METHOD_SSP)) {
+                && !TextUtils.equals(mUpdateMethod, UPDATE_METHOD_SPP)) {
             Log.d(TAG, "Unknown update method: " + mUpdateMethod);
             return false;
         }
diff --git a/framework/tests/assets/pps/PerProviderSubscription.xml b/framework/tests/assets/pps/PerProviderSubscription.xml
index a4c78ac..e910d3e 100644
--- a/framework/tests/assets/pps/PerProviderSubscription.xml
+++ b/framework/tests/assets/pps/PerProviderSubscription.xml
@@ -368,7 +368,7 @@
         </Node>
         <Node>
           <NodeName>UpdateMethod</NodeName>
-          <Value>SSP-ClientInitiated</Value>
+          <Value>SPP-ClientInitiated</Value>
         </Node>
         <Node>
           <NodeName>Restriction</NodeName>
diff --git a/framework/tests/src/android/net/wifi/hotspot2/PasspointTestUtils.java b/framework/tests/src/android/net/wifi/hotspot2/PasspointTestUtils.java
index 5830a1e..7125b17 100644
--- a/framework/tests/src/android/net/wifi/hotspot2/PasspointTestUtils.java
+++ b/framework/tests/src/android/net/wifi/hotspot2/PasspointTestUtils.java
@@ -116,7 +116,7 @@
     private static UpdateParameter createSubscriptionUpdate() {
         UpdateParameter subUpdate = new UpdateParameter();
         subUpdate.setUpdateIntervalInMinutes(9021);
-        subUpdate.setUpdateMethod(UpdateParameter.UPDATE_METHOD_SSP);
+        subUpdate.setUpdateMethod(UpdateParameter.UPDATE_METHOD_SPP);
         subUpdate.setRestriction(UpdateParameter.UPDATE_RESTRICTION_ROAMING_PARTNER);
         subUpdate.setServerUri("subscription.update.com");
         subUpdate.setUsername("subUsername");
diff --git a/framework/tests/src/android/net/wifi/hotspot2/omadm/PpsMoParserTest.java b/framework/tests/src/android/net/wifi/hotspot2/omadm/PpsMoParserTest.java
index 266899c..afa89d9 100644
--- a/framework/tests/src/android/net/wifi/hotspot2/omadm/PpsMoParserTest.java
+++ b/framework/tests/src/android/net/wifi/hotspot2/omadm/PpsMoParserTest.java
@@ -104,7 +104,7 @@
         // Subscription update.
         UpdateParameter subscriptionUpdate = new UpdateParameter();
         subscriptionUpdate.setUpdateIntervalInMinutes(120);
-        subscriptionUpdate.setUpdateMethod(UpdateParameter.UPDATE_METHOD_SSP);
+        subscriptionUpdate.setUpdateMethod(UpdateParameter.UPDATE_METHOD_SPP);
         subscriptionUpdate.setRestriction(UpdateParameter.UPDATE_RESTRICTION_ROAMING_PARTNER);
         subscriptionUpdate.setServerUri("subscription.update.com");
         subscriptionUpdate.setUsername("subscriptionUser");
diff --git a/service/ServiceWifiResources/res/values-as/strings.xml b/service/ServiceWifiResources/res/values-as/strings.xml
index dc6e1d6..97a2884 100644
--- a/service/ServiceWifiResources/res/values-as/strings.xml
+++ b/service/ServiceWifiResources/res/values-as/strings.xml
@@ -63,7 +63,7 @@
     <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"ফ\'নটো <xliff:g id="DEVICE_NAME">%1$s</xliff:g> লৈ সংযোগ হ\'লে ৱাই-ফাইৰ পৰা কিছু সময়ৰ বাবে সংযোগ স্বীকাৰ বিচ্ছিন্ন হ\'ব"</string>
     <string name="dlg_ok" msgid="254496739491689405">"ঠিক আছে"</string>
     <string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"<xliff:g id="SSID">%1$s</xliff:g>ৰ সৈতে সংযোগ কৰিব নোৱাৰি"</string>
-    <string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"গোপনীয়তাৰ ছেটিংসমূহ সলনি কৰিবলৈ আৰু পুনৰ চেষ্টা কৰিবলৈ টিপক"</string>
+    <string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"গোপনীয়তাৰ ছেটিং সলনি কৰিবলৈ আৰু পুনৰ চেষ্টা কৰিবলৈ টিপক"</string>
     <string name="wifi_disable_mac_randomization_dialog_title" msgid="2054540994993681606">"গোপনীয়তাৰ ছেটিংটো সলনি কৰিবনে?"</string>
     <string name="wifi_disable_mac_randomization_dialog_message" msgid="8874064864332248988">"সংযোগ কৰিবলৈ <xliff:g id="SSID">%1$s</xliff:g>এ আপোনাৰ ডিভাইচৰ MAC ঠিকনাটো, এটা সুকীয়া চিনাক্তকাৰী ব্যৱহাৰ কৰিব লাগে। বৰ্তমান, এই নেটৱৰ্কটোৰ বাবে আপোনাৰ গোপনীয়তাৰ ছেটিঙে এটা যাদৃচ্ছিক চিনাক্তকাৰী ব্যৱহাৰ কৰে। \n\nএই সালসলনিয়ে নিকটৱৰ্তী ডিভাইচসমূহক আপোনাৰ ডিভাইচটোৰ অৱস্থান ট্ৰেক কৰাৰ অনুমতি দিব পাৰে।"</string>
     <string name="wifi_disable_mac_randomization_dialog_confirm_text" msgid="6954419863076751626">"ছেটিংটো সলনি কৰক"</string>
diff --git a/service/ServiceWifiResources/res/values-da/strings.xml b/service/ServiceWifiResources/res/values-da/strings.xml
index c823271..58f854a 100644
--- a/service/ServiceWifiResources/res/values-da/strings.xml
+++ b/service/ServiceWifiResources/res/values-da/strings.xml
@@ -32,11 +32,11 @@
     <string name="wifi_suggestion_action_allow_app" msgid="7757859972144671588">"Tillad"</string>
     <string name="wifi_suggestion_action_disallow_app" msgid="4565857699629860726">"Nej tak"</string>
     <string name="wifi_suggestion_imsi_privacy_title" msgid="8969261812845304079">"Opret forbindelse til <xliff:g id="CARRIERNAME">%s</xliff:g>-Wi-Fi"</string>
-    <string name="wifi_suggestion_imsi_privacy_content" msgid="4266931269306079184">"Disse netværk kræver et SIM-id, der kan bruges til at spore enhedens placering"</string>
+    <string name="wifi_suggestion_imsi_privacy_content" msgid="4266931269306079184">"Disse netværk kræver et SIM-id, der kan bruges til at spore enhedens lokation"</string>
     <string name="wifi_suggestion_action_allow_imsi_privacy_exemption_carrier" msgid="3888538126440442636">"Opret forbindelse"</string>
     <string name="wifi_suggestion_action_disallow_imsi_privacy_exemption_carrier" msgid="3225397664735676024">"Opret ikke forbindelse"</string>
     <string name="wifi_suggestion_imsi_privacy_exemption_confirmation_title" msgid="4407415300707014525">"Vil du bekræfte forbindelsen?"</string>
-    <string name="wifi_suggestion_imsi_privacy_exemption_confirmation_content" msgid="9211241189147807136">"Hvis du opretter forbindelse, kan Wi-Fi-netværk fra <xliff:g id="CARRIERNAME">%s</xliff:g> få adgang til eller dele et unikt id, der er knyttet til dit SIM-kort. Derved kan din enheds placering muligvis spores."</string>
+    <string name="wifi_suggestion_imsi_privacy_exemption_confirmation_content" msgid="9211241189147807136">"Hvis du opretter forbindelse, kan Wi-Fi-netværk fra <xliff:g id="CARRIERNAME">%s</xliff:g> få adgang til eller dele et unikt id, der er knyttet til dit SIM-kort. Derved kan din enheds lokation muligvis spores."</string>
     <string name="wifi_suggestion_action_allow_imsi_privacy_exemption_confirmation" msgid="2168947026413431603">"Opret forbindelse"</string>
     <string name="wifi_suggestion_action_disallow_imsi_privacy_exemption_confirmation" msgid="5156881939985876066">"Opret ikke forbindelse"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="3868826648004934540">"Wi‑Fi aktiveres automatisk"</string>
@@ -65,7 +65,7 @@
     <string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"Der kan ikke oprettes forbindelse til <xliff:g id="SSID">%1$s</xliff:g>"</string>
     <string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"Tryk for at ændre privatlivsindstillingerne, og prøv igen"</string>
     <string name="wifi_disable_mac_randomization_dialog_title" msgid="2054540994993681606">"Vil du ændre privatlivsindstillingen?"</string>
-    <string name="wifi_disable_mac_randomization_dialog_message" msgid="8874064864332248988">"<xliff:g id="SSID">%1$s</xliff:g> skal bruge din enheds MAC-adresse (som er et unikt id), for at oprette forbindelse. I øjeblikket bruges et tilfældigt id i henhold til dine privatlivsindstillinger for dette netværk. \n\nDenne ændring kan gøre det muligt for enheder i nærheden spore din enheds placering."</string>
+    <string name="wifi_disable_mac_randomization_dialog_message" msgid="8874064864332248988">"<xliff:g id="SSID">%1$s</xliff:g> skal bruge din enheds MAC-adresse (som er et unikt id), for at oprette forbindelse. I øjeblikket bruges et tilfældigt id i henhold til dine privatlivsindstillinger for dette netværk. \n\nDenne ændring kan gøre det muligt for enheder i nærheden spore din enheds lokation."</string>
     <string name="wifi_disable_mac_randomization_dialog_confirm_text" msgid="6954419863076751626">"Skift indstilling"</string>
     <string name="wifi_disable_mac_randomization_dialog_success" msgid="5849155828154391387">"Indstillingen blev opdateret. Prøv at oprette forbindelse igen."</string>
     <string name="wifi_disable_mac_randomization_dialog_failure" msgid="2894643619143813096">"Privatlivsindstillingen kan ikke ændres"</string>
diff --git a/service/ServiceWifiResources/res/values-in/strings.xml b/service/ServiceWifiResources/res/values-in/strings.xml
index e3c3a83..08d689c 100644
--- a/service/ServiceWifiResources/res/values-in/strings.xml
+++ b/service/ServiceWifiResources/res/values-in/strings.xml
@@ -37,17 +37,17 @@
     <string name="wifi_suggestion_action_disallow_imsi_privacy_exemption_carrier" msgid="3225397664735676024">"Jangan hubungkan"</string>
     <string name="wifi_suggestion_imsi_privacy_exemption_confirmation_title" msgid="4407415300707014525">"Konfirmasi koneksi?"</string>
     <string name="wifi_suggestion_imsi_privacy_exemption_confirmation_content" msgid="9211241189147807136">"Jika Anda menghubungkan, jaringan Wi-Fi <xliff:g id="CARRIERNAME">%s</xliff:g> mungkin mengakses atau membagikan ID unik terkait dengan SIM Anda. Ini memungkinkan lokasi perangkat Anda untuk dilacak."</string>
-    <string name="wifi_suggestion_action_allow_imsi_privacy_exemption_confirmation" msgid="2168947026413431603">"Ikuti"</string>
+    <string name="wifi_suggestion_action_allow_imsi_privacy_exemption_confirmation" msgid="2168947026413431603">"Hubungkan"</string>
     <string name="wifi_suggestion_action_disallow_imsi_privacy_exemption_confirmation" msgid="5156881939985876066">"Jangan hubungkan"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="3868826648004934540">"Wi‑Fi akan aktif otomatis"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="5705886295837387430">"Saat berada di dekat jaringan berkualitas tinggi yang tersimpan"</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="6209706680391785825">"Jangan aktifkan kembali"</string>
     <string name="wifi_wakeup_enabled_title" msgid="5043486751612595850">"Wi‑Fi diaktifkan otomatis"</string>
     <string name="wifi_wakeup_enabled_content" msgid="3911262526267025882">"Anda berada di dekat jaringan yang tersimpan: <xliff:g id="NETWORK_SSID">%1$s</xliff:g>"</string>
-    <string name="wifi_watchdog_network_disabled" msgid="5769226742956006362">"Tidak dapat tersambung ke Wi-Fi"</string>
+    <string name="wifi_watchdog_network_disabled" msgid="5769226742956006362">"Tidak dapat terhubung ke Wi-Fi"</string>
     <string name="wifi_watchdog_network_disabled_detailed" msgid="1725243835135539125">" memiliki koneksi internet yang buruk."</string>
     <string name="wifi_connect_alert_title" msgid="2368200646665663612">"Izinkan hubungan?"</string>
-    <string name="wifi_connect_alert_message" msgid="7226456300982080746">"Aplikasi %1$s ingin tersambung ke Jaringan Wifi %2$s"</string>
+    <string name="wifi_connect_alert_message" msgid="7226456300982080746">"Aplikasi %1$s ingin terhubung ke Jaringan Wifi %2$s"</string>
     <string name="wifi_connect_default_application" msgid="8917703737222707062">"Aplikasi"</string>
     <string name="accept" msgid="8346431649376483879">"Terima"</string>
     <string name="decline" msgid="4172251727603762084">"Tolak"</string>
@@ -58,9 +58,9 @@
     <string name="wifi_p2p_to_message" msgid="3809923305696994787">"Kepada:"</string>
     <string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"Ketik PIN yang diminta:"</string>
     <string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"PIN:"</string>
-    <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"Sambungan tablet akan diputuskan dari Wi-Fi untuk sementara saat tersambung dengan <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+    <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"Sambungan tablet akan diputuskan dari Wi-Fi untuk sementara saat terhubung dengan <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
     <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"Perangkat Android TV akan memutuskan hubungan sementara dari Wi-Fi saat terhubung ke <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
-    <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"Ponsel akan terputus sementara dari Wi-Fi saat tersambung ke <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+    <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"Ponsel akan terputus sementara dari Wi-Fi saat terhubung ke <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
     <string name="dlg_ok" msgid="254496739491689405">"Oke"</string>
     <string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"Tidak dapat terhubung ke <xliff:g id="SSID">%1$s</xliff:g>"</string>
     <string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"Ketuk untuk mengubah setelan privasi dan coba lagi"</string>
@@ -79,6 +79,6 @@
     <string name="wifi_eap_error_message_code_32766" msgid="2335996367705677670">"<xliff:g id="SSID">%1$s</xliff:g> : Error autentikasi EAP 32766"</string>
     <string name="wifi_softap_auto_shutdown_timeout_expired_title" msgid="4896534374569504484">"Hotspot dinonaktifkan"</string>
     <string name="wifi_softap_auto_shutdown_timeout_expired_summary" msgid="7975476698140267728">"Tidak ada perangkat yang terhubung. Ketuk untuk mengubah."</string>
-    <string name="wifi_sim_required_title" msgid="2262227800991155459">"Wi-Fi tidak tersambung"</string>
+    <string name="wifi_sim_required_title" msgid="2262227800991155459">"Wi-Fi tidak terhubung"</string>
     <string name="wifi_sim_required_message" msgid="284812212346125745">"Untuk terhubung ke <xliff:g id="SSID">%1$s</xliff:g>, masukkan SIM <xliff:g id="CARRIER_NAME">%2$s</xliff:g>"</string>
 </resources>
diff --git a/service/ServiceWifiResources/res/values-mcc310-mnc004-da/strings.xml b/service/ServiceWifiResources/res/values-mcc310-mnc004-da/strings.xml
index 42d9cf6..8972969 100644
--- a/service/ServiceWifiResources/res/values-mcc310-mnc004-da/strings.xml
+++ b/service/ServiceWifiResources/res/values-mcc310-mnc004-da/strings.xml
@@ -22,5 +22,5 @@
     <string name="wifi_eap_error_message_code_32763" msgid="8051026304965697200">"<xliff:g id="SSID">%1$s</xliff:g> : Du har allerede oprettet forbindelse til Verizon Wi-Fi Access."</string>
     <string name="wifi_eap_error_message_code_32764" msgid="7311904315070770780">"<xliff:g id="SSID">%1$s</xliff:g> : Du kan ikke oprette forbindelse til Verizon Wi-Fi Access. Ring til os på telefonnummer 800-922-0204."</string>
     <string name="wifi_eap_error_message_code_32765" msgid="576968115890091383">"<xliff:g id="SSID">%1$s</xliff:g> : Der er et problem med din Verizon Wi-Fi Access-konto. Ring til os på telefonnummer 800-922-0204."</string>
-    <string name="wifi_eap_error_message_code_32766" msgid="895346637290649533">"<xliff:g id="SSID">%1$s</xliff:g> : Verizon Wi-Fi Access er ikke tilgængeligt i dit område. Prøv igen senere eller fra en anden placering."</string>
+    <string name="wifi_eap_error_message_code_32766" msgid="895346637290649533">"<xliff:g id="SSID">%1$s</xliff:g> : Verizon Wi-Fi Access er ikke tilgængeligt i dit område. Prøv igen senere eller fra en anden lokation."</string>
 </resources>
diff --git a/service/ServiceWifiResources/res/values-mcc310-mnc004-kk/strings.xml b/service/ServiceWifiResources/res/values-mcc310-mnc004-kk/strings.xml
index 0847cdf..6044ecc 100644
--- a/service/ServiceWifiResources/res/values-mcc310-mnc004-kk/strings.xml
+++ b/service/ServiceWifiResources/res/values-mcc310-mnc004-kk/strings.xml
@@ -18,9 +18,9 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="wifi_eap_error_message_code_32760" msgid="5711364720754353427">"<xliff:g id="SSID">%1$s</xliff:g> : Verizon Wi-Fi Access қызметіне Verizon қызмет көрсету аясынан тыс жерден қосыла алмайсыз."</string>
     <string name="wifi_eap_error_message_code_32761" msgid="7871615432524623339">"<xliff:g id="SSID">%1$s</xliff:g> : Verizon Wi-Fi Access қызметіне жазылған жоқсыз. Бізге 800-922-0204 нөмірі арқылы хабарласыңыз."</string>
-    <string name="wifi_eap_error_message_code_32762" msgid="2994908156286205343">"<xliff:g id="SSID">%1$s</xliff:g> : Verizon Wi-Fi Access есептік жазбасына қатысты мәселе шықты. Бізге 800-922-0204 нөмірі арқылы хабарласыңыз."</string>
+    <string name="wifi_eap_error_message_code_32762" msgid="2994908156286205343">"<xliff:g id="SSID">%1$s</xliff:g> : Verizon Wi-Fi Access аккаунтына қатысты мәселе шықты. Бізге 800-922-0204 нөмірі арқылы хабарласыңыз."</string>
     <string name="wifi_eap_error_message_code_32763" msgid="8051026304965697200">"<xliff:g id="SSID">%1$s</xliff:g> : Verizon Wi-Fi Access қызметіне әлдеқашан қосылғансыз."</string>
     <string name="wifi_eap_error_message_code_32764" msgid="7311904315070770780">"<xliff:g id="SSID">%1$s</xliff:g> : Verizon Wi-Fi Access қызметіне қосылу кезінде мәселе шықты. Бізге 800-922-0204 нөмірі арқылы хабарласыңыз."</string>
-    <string name="wifi_eap_error_message_code_32765" msgid="576968115890091383">"<xliff:g id="SSID">%1$s</xliff:g> : Verizon Wi-Fi Access есептік жазбасына қатысты мәселе шықты. Бізге 800-922-0204 нөмірі арқылы хабарласыңыз."</string>
+    <string name="wifi_eap_error_message_code_32765" msgid="576968115890091383">"<xliff:g id="SSID">%1$s</xliff:g> : Verizon Wi-Fi Access аккаунтына қатысты мәселе шықты. Бізге 800-922-0204 нөмірі арқылы хабарласыңыз."</string>
     <string name="wifi_eap_error_message_code_32766" msgid="895346637290649533">"<xliff:g id="SSID">%1$s</xliff:g> : Verizon Wi-Fi Access қазіргі орналасқан жеріңізде жұмыс істемейді. Әрекетті кейінірек немесе басқа жерден қайталап көріңіз."</string>
 </resources>
diff --git a/service/ServiceWifiResources/res/values-mcc311-mnc480-da/strings.xml b/service/ServiceWifiResources/res/values-mcc311-mnc480-da/strings.xml
index 18a2e82..d7180f4 100644
--- a/service/ServiceWifiResources/res/values-mcc311-mnc480-da/strings.xml
+++ b/service/ServiceWifiResources/res/values-mcc311-mnc480-da/strings.xml
@@ -22,5 +22,5 @@
     <string name="wifi_eap_error_message_code_32763" msgid="2668371888408710653">"<xliff:g id="SSID">%1$s</xliff:g> : Du har allerede oprettet forbindelse til Verizon Wi-Fi Access."</string>
     <string name="wifi_eap_error_message_code_32764" msgid="4857239018269450670">"<xliff:g id="SSID">%1$s</xliff:g> : Du kan ikke oprette forbindelse til Verizon Wi-Fi Access. Ring til os på telefonnummer 800-922-0204."</string>
     <string name="wifi_eap_error_message_code_32765" msgid="3223606535554861258">"<xliff:g id="SSID">%1$s</xliff:g> : Der er et problem med din Verizon Wi-Fi Access-konto. Ring til os på telefonnummer 800-922-0204."</string>
-    <string name="wifi_eap_error_message_code_32766" msgid="2703925241673900110">"<xliff:g id="SSID">%1$s</xliff:g> : Verizon Wi-Fi Access er ikke tilgængeligt i dit område. Prøv igen senere eller fra en anden placering."</string>
+    <string name="wifi_eap_error_message_code_32766" msgid="2703925241673900110">"<xliff:g id="SSID">%1$s</xliff:g> : Verizon Wi-Fi Access er ikke tilgængeligt i dit område. Prøv igen senere eller fra en anden lokation."</string>
 </resources>
diff --git a/service/ServiceWifiResources/res/values-mcc311-mnc480-kk/strings.xml b/service/ServiceWifiResources/res/values-mcc311-mnc480-kk/strings.xml
index 6e59481..f31d062 100644
--- a/service/ServiceWifiResources/res/values-mcc311-mnc480-kk/strings.xml
+++ b/service/ServiceWifiResources/res/values-mcc311-mnc480-kk/strings.xml
@@ -18,9 +18,9 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="wifi_eap_error_message_code_32760" msgid="1073938428568671170">"<xliff:g id="SSID">%1$s</xliff:g> : Verizon Wi-Fi Access қызметіне Verizon қызмет көрсету аясынан тыс жерден қосыла алмайсыз."</string>
     <string name="wifi_eap_error_message_code_32761" msgid="5240496654119200117">"<xliff:g id="SSID">%1$s</xliff:g> : Verizon Wi-Fi Access қызметіне жазылған жоқсыз. Бізге 800-922-0204 нөмірі арқылы хабарласыңыз."</string>
-    <string name="wifi_eap_error_message_code_32762" msgid="1380081181230313771">"<xliff:g id="SSID">%1$s</xliff:g> : Verizon Wi-Fi Access есептік жазбасына қатысты мәселе шықты. Бізге 800-922-0204 нөмірі арқылы хабарласыңыз."</string>
+    <string name="wifi_eap_error_message_code_32762" msgid="1380081181230313771">"<xliff:g id="SSID">%1$s</xliff:g> : Verizon Wi-Fi Access аккаунтына қатысты мәселе шықты. Бізге 800-922-0204 нөмірі арқылы хабарласыңыз."</string>
     <string name="wifi_eap_error_message_code_32763" msgid="2668371888408710653">"<xliff:g id="SSID">%1$s</xliff:g> : Verizon Wi-Fi Access қызметіне әлдеқашан қосылғансыз."</string>
     <string name="wifi_eap_error_message_code_32764" msgid="4857239018269450670">"<xliff:g id="SSID">%1$s</xliff:g> : Verizon Wi-Fi Access қызметіне қосылу кезінде мәселе шықты. Бізге 800-922-0204 нөмірі арқылы хабарласыңыз."</string>
-    <string name="wifi_eap_error_message_code_32765" msgid="3223606535554861258">"<xliff:g id="SSID">%1$s</xliff:g> : Verizon Wi-Fi Access есептік жазбасына қатысты мәселе шықты. Бізге 800-922-0204 нөмірі арқылы хабарласыңыз."</string>
+    <string name="wifi_eap_error_message_code_32765" msgid="3223606535554861258">"<xliff:g id="SSID">%1$s</xliff:g> : Verizon Wi-Fi Access аккаунтына қатысты мәселе шықты. Бізге 800-922-0204 нөмірі арқылы хабарласыңыз."</string>
     <string name="wifi_eap_error_message_code_32766" msgid="2703925241673900110">"<xliff:g id="SSID">%1$s</xliff:g> : Verizon Wi-Fi Access қазіргі орналасқан жеріңізде жұмыс істемейді. Әрекетті кейінірек немесе басқа жерден қайталап көріңіз."</string>
 </resources>
diff --git a/service/java/com/android/server/wifi/ActiveModeWarden.java b/service/java/com/android/server/wifi/ActiveModeWarden.java
index 1686d70..b2e1ef5 100644
--- a/service/java/com/android/server/wifi/ActiveModeWarden.java
+++ b/service/java/com/android/server/wifi/ActiveModeWarden.java
@@ -1935,6 +1935,13 @@
                         requestInfo.listener.onAnswer(cmmForSameBssid);
                         return;
                     }
+                    // The CMM having BSSID conflict is exactly the one being requested.
+                    // Simply return the CMM in this case. The requestor will be responsible to
+                    // make sure it does not trigger the connection again when already connected.
+                    if (cmmForSameBssid.getRole() == requestInfo.clientRole) {
+                        requestInfo.listener.onAnswer(cmmForSameBssid);
+                        return;
+                    }
                     // Existing secondary CMM connected to the same ssid/bssid.
                     if (!canRequestMoreClientModeManagersInRole(
                             requestInfo.requestorWs, requestInfo.clientRole)) {
diff --git a/service/java/com/android/server/wifi/ClientModeImpl.java b/service/java/com/android/server/wifi/ClientModeImpl.java
index a3ee4df..fcbc408 100644
--- a/service/java/com/android/server/wifi/ClientModeImpl.java
+++ b/service/java/com/android/server/wifi/ClientModeImpl.java
@@ -1405,8 +1405,8 @@
      * mark network agent as disconnected and stop the ip client.
      */
     public void handleIfaceDestroyed() {
-        mWifiThreadRunner.post(() -> handleNetworkDisconnect(false,
-                WifiStatsLog.WIFI_DISCONNECT_REPORTED__FAILURE_CODE__IFACE_DESTROYED));
+        handleNetworkDisconnect(false,
+                WifiStatsLog.WIFI_DISCONNECT_REPORTED__FAILURE_CODE__IFACE_DESTROYED);
     }
 
     /** Stop this ClientModeImpl. Do not interact with ClientModeImpl after it has been stopped. */
@@ -3205,6 +3205,8 @@
         mWifiNative.setSupplicantLogLevel(mVerboseLoggingEnabled);
 
         // Initialize data structures
+        mTargetBssid = SUPPLICANT_BSSID_ANY;
+        mTargetNetworkId = WifiConfiguration.INVALID_NETWORK_ID;
         mLastBssid = null;
         mLastNetworkId = WifiConfiguration.INVALID_NETWORK_ID;
         mLastSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
@@ -3271,6 +3273,8 @@
             // Block to make sure IpClient has really shut down, lest cleanup
             // race with, say, bringup code over in tethering.
             mIpClientCallbacks.awaitShutdown();
+            mIpClientCallbacks = null;
+            mIpClient = null;
         }
         deregisterForWifiMonitorEvents(); // uses mInterfaceName, must call before nulling out
         // TODO: b/79504296 This broadcast has been deprecated and should be removed
@@ -3285,7 +3289,8 @@
             WifiConfiguration config = getConnectedWifiConfigurationInternal();
             boolean shouldSetUserConnectChoice = config != null
                     && isRecentlySelectedByTheUser(config)
-                    && config.getNetworkSelectionStatus().hasEverConnected()
+                    && (config.getNetworkSelectionStatus().hasEverConnected()
+                    || config.isEphemeral())
                     && mWifiPermissionsUtil.checkNetworkSettingsPermission(config.lastConnectUid);
             mWifiConfigManager.updateNetworkAfterConnect(mLastNetworkId,
                     shouldSetUserConnectChoice, mWifiInfo.getRssi());
diff --git a/service/java/com/android/server/wifi/ConcreteClientModeManager.java b/service/java/com/android/server/wifi/ConcreteClientModeManager.java
index 1e6d63d..d7b52c3 100644
--- a/service/java/com/android/server/wifi/ConcreteClientModeManager.java
+++ b/service/java/com/android/server/wifi/ConcreteClientModeManager.java
@@ -1062,8 +1062,12 @@
                             break;  // no change
                         }
                         if (!isUp) {
-                            if (mWifiGlobals.isConnectedMacRandomizationEnabled()
-                                    && getClientMode().isConnecting()) {
+                            // TODO(b/201584491) Figure out what to do with this block of code
+                            // handling iface down since most devices should have MAC randomization
+                            // enabled, which makes the "else" block essentially no-op. Also, the
+                            // "else" block would actually fully disable wifi which is not desirable
+                            // behavior because the firmware can recover the iface after it is down.
+                            if (mWifiGlobals.isConnectedMacRandomizationEnabled()) {
                                 return HANDLED; // For MAC randomization, ignore...
                             } else {
                                 // Handle the error case where our underlying interface went down if
diff --git a/service/java/com/android/server/wifi/ConfigurationMap.java b/service/java/com/android/server/wifi/ConfigurationMap.java
index 88c6956..4219a90 100644
--- a/service/java/com/android/server/wifi/ConfigurationMap.java
+++ b/service/java/com/android/server/wifi/ConfigurationMap.java
@@ -19,7 +19,10 @@
 import android.net.wifi.ScanResult;
 import android.net.wifi.WifiConfiguration;
 import android.os.UserHandle;
-import android.os.UserManager;
+
+import androidx.annotation.NonNull;
+
+import com.android.server.wifi.util.WifiPermissionsUtil;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -35,12 +38,12 @@
     private final Map<ScanResultMatchInfo, WifiConfiguration>
             mScanResultMatchInfoMapForCurrentUser = new HashMap<>();
 
-    private final UserManager mUserManager;
+    @NonNull private final WifiPermissionsUtil mWifiPermissionsUtil;
 
     private int mCurrentUserId = UserHandle.SYSTEM.getIdentifier();
 
-    ConfigurationMap(UserManager userManager) {
-        mUserManager = userManager;
+    ConfigurationMap(@NonNull WifiPermissionsUtil wifiPermissionsUtil) {
+        mWifiPermissionsUtil = wifiPermissionsUtil;
     }
 
     /** Dump internal state for debugging. */
@@ -55,10 +58,8 @@
     // RW methods:
     public WifiConfiguration put(WifiConfiguration config) {
         final WifiConfiguration current = mPerID.put(config.networkId, config);
-        final UserHandle currentUser = UserHandle.of(mCurrentUserId);
-        final UserHandle creatorUser = UserHandle.getUserHandleForUid(config.creatorUid);
-        if (config.shared || currentUser.equals(creatorUser)
-                || mUserManager.isSameProfileGroup(currentUser, creatorUser)) {
+        if (config.shared || mWifiPermissionsUtil
+                .doesUidBelongToCurrentUserOrDeviceOwner(config.creatorUid)) {
             mPerIDForCurrentUser.put(config.networkId, config);
             // TODO (b/142035508): Add a more generic fix. This cache should only hold saved
             // networks.
diff --git a/service/java/com/android/server/wifi/HalDeviceManager.java b/service/java/com/android/server/wifi/HalDeviceManager.java
index 8972880..638d661 100644
--- a/service/java/com/android/server/wifi/HalDeviceManager.java
+++ b/service/java/com/android/server/wifi/HalDeviceManager.java
@@ -256,9 +256,10 @@
      * @param destroyedListener Optional (nullable) listener to call when the allocated interface
      *                          is removed. Will only be registered and used if an interface is
      *                          created successfully.
-     * @param handler Handler on which to dispatch listener. Null implies the listener will be
-     *                invoked synchronously from the context of the client which triggered the
-     *                iface destruction.
+     * @param handler Handler on which to dispatch listener. Must be non Null if destroyedListener
+     *                is set. If the this handler is running on the same thread as the client which
+     *                triggered the iface destruction, the listener will be invoked synchronously
+     *                from that context of the client.
      * @param requestorWs Requestor worksource. This will be used to determine priority of this
      *                    interface using rules based on the requestor app's context.
      * @return A newly created interface - or null if the interface could not be created.
@@ -278,9 +279,10 @@
      * @param destroyedListener Optional (nullable) listener to call when the allocated interface
      *                          is removed. Will only be registered and used if an interface is
      *                          created successfully.
-     * @param handler Handler on which to dispatch listener. Null implies the listener will be
-     *                invoked synchronously from the context of the client which triggered the
-     *                iface destruction.
+     * @param handler Handler on which to dispatch listener. Must be non Null if destroyedListener
+     *                is set. If the handler is running on the same thread as the client which
+     *                triggered the iface destruction, the listener will be invoked synchronously
+     *                from that context of the client.
      * @param requestorWs Requestor worksource. This will be used to determine priority of this
      *                    interface using rules based on the requestor app's context.
      * @return A newly created interface - or null if the interface could not be created.
@@ -429,37 +431,6 @@
     }
 
     /**
-     * Register an InterfaceDestroyedListener to the specified iface - returns true on success
-     * and false on failure. This listener is in addition to the one registered when the interface
-     * was created - allowing non-creators to monitor interface status.
-     *
-     * @param destroyedListener Listener to call when the allocated interface is removed.
-     *                          Will only be registered and used if an interface is created
-     *                          successfully.
-     * @param handler Handler on which to dispatch listener. Null implies the listener will be
-     *                invoked synchronously from the context of the client which triggered the
-     *                iface destruction.
-     */
-    public boolean registerDestroyedListener(IWifiIface iface,
-            @NonNull InterfaceDestroyedListener destroyedListener,
-            @Nullable Handler handler) {
-        String name = getName(iface);
-        int type = getType(iface);
-        if (VDBG) Log.d(TAG, "registerDestroyedListener: iface(name)=" + name);
-
-        synchronized (mLock) {
-            InterfaceCacheEntry cacheEntry = mInterfaceInfoCache.get(Pair.create(name, type));
-            if (cacheEntry == null) {
-                Log.e(TAG, "registerDestroyedListener: no entry for iface(name)=" + name);
-                return false;
-            }
-
-            return cacheEntry.destroyedListeners.add(
-                    new InterfaceDestroyedListenerProxy(name, destroyedListener, handler));
-        }
-    }
-
-    /**
      * Register a callback object for RTT life-cycle events. The callback object registration
      * indicates that an RTT controller should be created whenever possible. The callback object
      * will be called with a new RTT controller whenever it is created (or at registration time
@@ -1624,6 +1595,11 @@
                     + ", requiredChipCapabilities=" + requiredChipCapabilities
                     + ", requestorWs=" + requestorWs);
         }
+        if (destroyedListener != null && handler == null) {
+            Log.wtf(TAG, "createIface: createIfaceType=" + createIfaceType
+                    + "with NonNull destroyedListener but Null handler");
+            return null;
+        }
 
         synchronized (mLock) {
             WifiChipInfo[] chipInfos = getAllChipInfo();
@@ -2482,9 +2458,25 @@
 
         void trigger() {
             if (mHandler != null) {
-                mHandler.post(() -> {
+                // TODO(b/199792691): The thread check is needed to preserve the existing
+                //  assumptions of synchronous execution of the "onDestroyed" callback as much as
+                //  possible. This is needed to prevent regressions caused by posting to the handler
+                //  thread changing the code execution order.
+                //  When all wifi services (ie. WifiAware, WifiP2p) get moved to the wifi handler
+                //  thread, remove this thread check and the Handler#post() and simply always
+                //  invoke the callback directly.
+                long currentTid = mWifiInjector.getCurrentThreadId();
+                long handlerTid = mHandler.getLooper().getThread().getId();
+                if (currentTid == handlerTid) {
+                    // Already running on the same handler thread. Trigger listener synchronously.
                     action();
-                });
+                } else {
+                    // Current thread is not the thread the listener should be invoked on.
+                    // Post action to the intended thread.
+                    mHandler.post(() -> {
+                        action();
+                    });
+                }
             } else {
                 action();
             }
@@ -2526,8 +2518,8 @@
             ListenerProxy<InterfaceDestroyedListener> {
         private final String mIfaceName;
         InterfaceDestroyedListenerProxy(@NonNull String ifaceName,
-                                        InterfaceDestroyedListener destroyedListener,
-                                        Handler handler) {
+                                        @NonNull InterfaceDestroyedListener destroyedListener,
+                                        @NonNull Handler handler) {
             super(destroyedListener, handler, "InterfaceDestroyedListenerProxy");
             mIfaceName = ifaceName;
         }
diff --git a/service/java/com/android/server/wifi/WifiConfigManager.java b/service/java/com/android/server/wifi/WifiConfigManager.java
index 1c87eb2..bbc09a1 100644
--- a/service/java/com/android/server/wifi/WifiConfigManager.java
+++ b/service/java/com/android/server/wifi/WifiConfigManager.java
@@ -383,7 +383,7 @@
         mWifiLastResortWatchdog = wifiLastResortWatchdog;
         mWifiScoreCard = wifiScoreCard;
 
-        mConfiguredNetworks = new ConfigurationMap(userManager);
+        mConfiguredNetworks = new ConfigurationMap(mWifiPermissionsUtil);
         mScanDetailCaches = new HashMap<>(16, 0.75f);
         mUserTemporarilyDisabledList =
                 new MissingCounterTimerLockList<>(SCAN_RESULT_MISSING_COUNT_THRESHOLD, mClock);
@@ -1402,7 +1402,7 @@
      */
     public NetworkUpdateResult addOrUpdateNetwork(WifiConfiguration config, int uid,
                                                   @Nullable String packageName) {
-        if (!mWifiPermissionsUtil.doesUidBelongToCurrentUser(uid)) {
+        if (!mWifiPermissionsUtil.doesUidBelongToCurrentUserOrDeviceOwner(uid)) {
             Log.e(TAG, "UID " + uid + " not visible to the current user");
             return new NetworkUpdateResult(WifiConfiguration.INVALID_NETWORK_ID);
         }
@@ -1584,7 +1584,7 @@
      * @return true if successful, false otherwise.
      */
     public boolean removeNetwork(int networkId, int uid, String packageName) {
-        if (!mWifiPermissionsUtil.doesUidBelongToCurrentUser(uid)) {
+        if (!mWifiPermissionsUtil.doesUidBelongToCurrentUserOrDeviceOwner(uid)) {
             Log.e(TAG, "UID " + uid + " not visible to the current user");
             return false;
         }
@@ -1902,7 +1902,7 @@
         if (mVerboseLoggingEnabled) {
             Log.v(TAG, "Enabling network " + networkId + " (disableOthers " + disableOthers + ")");
         }
-        if (!mWifiPermissionsUtil.doesUidBelongToCurrentUser(uid)) {
+        if (!mWifiPermissionsUtil.doesUidBelongToCurrentUserOrDeviceOwner(uid)) {
             Log.e(TAG, "UID " + uid + " not visible to the current user");
             return false;
         }
@@ -1940,7 +1940,7 @@
         if (mVerboseLoggingEnabled) {
             Log.v(TAG, "Disabling network " + networkId);
         }
-        if (!mWifiPermissionsUtil.doesUidBelongToCurrentUser(uid)) {
+        if (!mWifiPermissionsUtil.doesUidBelongToCurrentUserOrDeviceOwner(uid)) {
             Log.e(TAG, "UID " + uid + " not visible to the current user");
             return false;
         }
@@ -2008,7 +2008,7 @@
         if (mVerboseLoggingEnabled) {
             Log.v(TAG, "Update network last connect UID for " + networkId);
         }
-        if (!mWifiPermissionsUtil.doesUidBelongToCurrentUser(uid)) {
+        if (!mWifiPermissionsUtil.doesUidBelongToCurrentUserOrDeviceOwner(uid)) {
             Log.e(TAG, "UID " + uid + " not visible to the current user");
             return false;
         }
@@ -2971,7 +2971,7 @@
             saveToStore(true);
         }
         // Remove any private networks of the old user before switching the userId.
-        Set<Integer> removedNetworkIds = clearInternalDataForCurrentUser();
+        Set<Integer> removedNetworkIds = clearInternalDataForUser(mCurrentUserId);
         mConfiguredNetworks.setNewUser(userId);
         mCurrentUserId = userId;
 
@@ -3028,7 +3028,7 @@
         if (userId == mCurrentUserId
                 && mUserManager.isUserUnlockingOrUnlocked(UserHandle.of(mCurrentUserId))) {
             saveToStore(true);
-            clearInternalDataForCurrentUser();
+            clearInternalDataForUser(mCurrentUserId);
         }
     }
 
@@ -3059,13 +3059,13 @@
      * @return List of network ID's of all the private networks of the old user which will be
      * removed from memory.
      */
-    private Set<Integer> clearInternalDataForCurrentUser() {
-        localLog("clearInternalUserData: Clearing user internal data for " + mCurrentUserId);
+    private Set<Integer> clearInternalDataForUser(int user) {
+        localLog("clearInternalUserData: Clearing user internal data for " + user);
         Set<Integer> removedNetworkIds = new HashSet<>();
         // Remove any private networks of the old user before switching the userId.
         for (WifiConfiguration config : getConfiguredNetworks()) {
-            if ((!config.shared && !mWifiPermissionsUtil
-                    .doesUidBelongToCurrentUser(config.creatorUid))
+            if ((!config.shared
+                    && mWifiPermissionsUtil.doesUidBelongToUser(config.creatorUid, user))
                     || config.ephemeral) {
                 removedNetworkIds.add(config.networkId);
                 localLog("clearInternalUserData: removed config."
@@ -3343,8 +3343,8 @@
 
             // Migrate the legacy Passpoint configurations owned by the current user to
             // {@link PasspointManager}.
-            if (config.isLegacyPasspointConfig && !mWifiPermissionsUtil
-                    .doesUidBelongToCurrentUser(config.creatorUid)) {
+            if (config.isLegacyPasspointConfig && mWifiPermissionsUtil
+                    .doesUidBelongToUser(config.creatorUid, mCurrentUserId)) {
                 legacyPasspointNetId.add(config.networkId);
                 // Migrate the legacy Passpoint configuration and add it to PasspointManager.
                 if (!PasspointManager.addLegacyPasspointConfig(config)) {
@@ -3365,7 +3365,7 @@
             // write these private networks to the user specific store until the corresponding
             // user logs in.
             if (config.shared || !mWifiPermissionsUtil
-                    .doesUidBelongToCurrentUser(config.creatorUid)) {
+                    .doesUidBelongToUser(config.creatorUid, mCurrentUserId)) {
                 sharedConfigurations.add(config);
             } else {
                 userConfigurations.add(config);
diff --git a/service/java/com/android/server/wifi/WifiConnectivityManager.java b/service/java/com/android/server/wifi/WifiConnectivityManager.java
index e8507ce..7712693 100644
--- a/service/java/com/android/server/wifi/WifiConnectivityManager.java
+++ b/service/java/com/android/server/wifi/WifiConnectivityManager.java
@@ -457,7 +457,8 @@
                 mNetworkSelector.selectNetwork(secondaryCmmCandidates);
         // No oem paid/private selected, fallback to legacy flow (should never happen!).
         if (secondaryCmmCandidate == null
-                || secondaryCmmCandidate.getNetworkSelectionStatus().getCandidate() == null) {
+                || secondaryCmmCandidate.getNetworkSelectionStatus().getCandidate() == null
+                || (!secondaryCmmCandidate.oemPaid && !secondaryCmmCandidate.oemPrivate)) {
             localLog(listenerName + ": No secondary candidate");
             handleCandidatesFromScanResultsForPrimaryCmmUsingMbbIfAvailable(
                     listenerName,
@@ -468,20 +469,15 @@
         }
         String secondaryCmmCandidateBssid =
                 secondaryCmmCandidate.getNetworkSelectionStatus().getCandidate().BSSID;
-        WorkSource secondaryRequestorWs = null;
+
+        // At this point secondaryCmmCandidate must be either oemPaid, oemPrivate, or both.
         // OEM_PAID takes precedence over OEM_PRIVATE, so attribute to OEM_PAID requesting app.
-        if (secondaryCmmCandidate.oemPaid
-                && mActiveModeWarden.canRequestMoreClientModeManagersInRole(
-                mOemPaidConnectionRequestorWs, ROLE_CLIENT_SECONDARY_LONG_LIVED)) {
-            secondaryRequestorWs = mOemPaidConnectionRequestorWs;
-        } else if (secondaryCmmCandidate.oemPrivate
-                && mActiveModeWarden.canRequestMoreClientModeManagersInRole(
-                mOemPrivateConnectionRequestorWs, ROLE_CLIENT_SECONDARY_LONG_LIVED)) {
-            secondaryRequestorWs = mOemPrivateConnectionRequestorWs;
-        }
-        // Secondary STA not available, fallback to legacy flow.
+        WorkSource secondaryRequestorWs = secondaryCmmCandidate.oemPaid
+                ? mOemPaidConnectionRequestorWs : mOemPrivateConnectionRequestorWs;
+
         if (secondaryRequestorWs == null) {
-            localLog(listenerName + ": No secondary STA available");
+            localLog(listenerName + ": Requestor worksource is null in long live STA use-case,"
+                    + "  falling back to single client mode manager flow.");
             handleCandidatesFromScanResultsForPrimaryCmmUsingMbbIfAvailable(
                     listenerName,
                     Stream.concat(primaryCmmCandidates.stream(), secondaryCmmCandidates.stream())
@@ -489,6 +485,7 @@
                     handleScanResultsListener);
             return;
         }
+
         WifiConfiguration primaryCmmCandidate =
                 mNetworkSelector.selectNetwork(primaryCmmCandidates);
         // Request for a new client mode manager to spin up concurrent connection
@@ -2278,12 +2275,12 @@
      * @param bssid the failed network.
      * @param ssid identifies the failed network.
      */
-    public void handleConnectionAttemptEnded(@NonNull ActiveModeManager activeModeManager,
+    public void handleConnectionAttemptEnded(@NonNull ClientModeManager clientModeManager,
             int failureCode, @NonNull String bssid, @NonNull String ssid) {
         List<ClientModeManager> internetConnectivityCmms =
                 mActiveModeWarden.getInternetConnectivityClientModeManagers();
-        if (!(internetConnectivityCmms.contains(activeModeManager))) {
-            Log.w(TAG, "Ignoring call from non primary Mode Manager " + activeModeManager,
+        if (!internetConnectivityCmms.contains(clientModeManager)) {
+            Log.w(TAG, "Ignoring call from non primary Mode Manager " + clientModeManager,
                     new Throwable());
             return;
         }
@@ -2295,11 +2292,16 @@
             mOpenNetworkNotifier.handleWifiConnected(ssidUnquoted);
         } else {
             mOpenNetworkNotifier.handleConnectionFailure();
-            retryConnectionOnLatestCandidates(bssid, ssid);
+            // Only attempt to reconnect when connection on the primary CMM fails, since MBB
+            // CMM will be destroyed after the connection failure.
+            if (clientModeManager.getRole() == ROLE_CLIENT_PRIMARY) {
+                retryConnectionOnLatestCandidates(clientModeManager, bssid, ssid);
+            }
         }
     }
 
-    private void retryConnectionOnLatestCandidates(String bssid, String ssid) {
+    private void retryConnectionOnLatestCandidates(@NonNull ClientModeManager clientModeManager,
+            String bssid, String ssid) {
         try {
             if (mLatestCandidates == null || mLatestCandidates.size() == 0
                     || mClock.getElapsedSinceBootMillis() - mLatestCandidatesTimestampMs
@@ -2333,7 +2335,12 @@
                 mWifiBlocklistMonitor.blockBssidForDurationMs(bssid, ssid,
                         TEMP_BSSID_BLOCK_DURATION,
                         WifiBlocklistMonitor.REASON_FRAMEWORK_DISCONNECT_FAST_RECONNECT, 0);
-                connectToNetworkForPrimaryCmmUsingMbbIfAvailable(candidate);
+                triggerConnectToNetworkUsingCmm(clientModeManager, candidate,
+                        ClientModeImpl.SUPPLICANT_BSSID_ANY);
+                // since using primary manager to connect, stop any existing managers in the
+                // secondary transient role since they are no longer needed.
+                mActiveModeWarden.stopAllClientModeManagersInRole(
+                        ROLE_CLIENT_SECONDARY_TRANSIENT);
             }
         } catch (IllegalArgumentException e) {
             localLog("retryConnectionOnLatestCandidates: failed to create MacAddress from bssid="
diff --git a/service/java/com/android/server/wifi/WifiInjector.java b/service/java/com/android/server/wifi/WifiInjector.java
index 7a43efe..efbe219 100644
--- a/service/java/com/android/server/wifi/WifiInjector.java
+++ b/service/java/com/android/server/wifi/WifiInjector.java
@@ -411,6 +411,7 @@
         PasspointNetworkNominateHelper nominateHelper =
                 new PasspointNetworkNominateHelper(mPasspointManager, mWifiConfigManager,
                         mConnectivityLocalLog);
+        mPasspointManager.setPasspointNetworkNominateHelper(nominateHelper);
         mSavedNetworkNominator = new SavedNetworkNominator(
                 mWifiConfigManager, nominateHelper, mConnectivityLocalLog, mWifiCarrierInfoManager,
                 mWifiPermissionsUtil, mWifiNetworkSuggestionsManager);
@@ -610,6 +611,13 @@
         return mWifiHandlerThread;
     }
 
+    /**
+     * Wrapper method for getting the current native Java Thread ID of the current thread.
+     */
+    public long getCurrentThreadId() {
+        return Thread.currentThread().getId();
+    }
+
     public WifiTrafficPoller getWifiTrafficPoller() {
         return mWifiTrafficPoller;
     }
diff --git a/service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java b/service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java
index f5a1ebe..b4c9a3e 100644
--- a/service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java
+++ b/service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java
@@ -880,7 +880,7 @@
     public @WifiManager.NetworkSuggestionsStatusCode int add(
             List<WifiNetworkSuggestion> networkSuggestions, int uid, String packageName,
             @Nullable String featureId) {
-        if (!mWifiPermissionsUtil.doesUidBelongToCurrentUser(uid)) {
+        if (!mWifiPermissionsUtil.doesUidBelongToCurrentUserOrDeviceOwner(uid)) {
             Log.e(TAG, "UID " + uid + " not visible to the current user");
             return WifiManager.STATUS_NETWORK_SUGGESTIONS_ERROR_INTERNAL;
         }
@@ -1292,7 +1292,7 @@
      */
     public @WifiManager.NetworkSuggestionsStatusCode int remove(
             List<WifiNetworkSuggestion> networkSuggestions, int uid, String packageName) {
-        if (!mWifiPermissionsUtil.doesUidBelongToCurrentUser(uid)) {
+        if (!mWifiPermissionsUtil.doesUidBelongToCurrentUserOrDeviceOwner(uid)) {
             Log.e(TAG, "UID " + uid + " not visible to the current user");
             return WifiManager.STATUS_NETWORK_SUGGESTIONS_ERROR_INTERNAL;
         }
@@ -1359,7 +1359,7 @@
      */
     public @NonNull List<WifiNetworkSuggestion> get(@NonNull String packageName, int uid) {
         List<WifiNetworkSuggestion> networkSuggestionList = new ArrayList<>();
-        if (!mWifiPermissionsUtil.doesUidBelongToCurrentUser(uid)) {
+        if (!mWifiPermissionsUtil.doesUidBelongToCurrentUserOrDeviceOwner(uid)) {
             Log.e(TAG, "UID " + uid + " not visible to the current user");
             return networkSuggestionList;
         }
@@ -2206,7 +2206,7 @@
     public boolean registerSuggestionConnectionStatusListener(
             @NonNull ISuggestionConnectionStatusListener listener,
             String packageName, int uid) {
-        if (!mWifiPermissionsUtil.doesUidBelongToCurrentUser(uid)) {
+        if (!mWifiPermissionsUtil.doesUidBelongToCurrentUserOrDeviceOwner(uid)) {
             Log.e(TAG, "UID " + uid + " not visible to the current user");
             return false;
         }
@@ -2227,7 +2227,7 @@
      */
     public void unregisterSuggestionConnectionStatusListener(
             @NonNull ISuggestionConnectionStatusListener listener, String packageName, int uid) {
-        if (!mWifiPermissionsUtil.doesUidBelongToCurrentUser(uid)) {
+        if (!mWifiPermissionsUtil.doesUidBelongToCurrentUserOrDeviceOwner(uid)) {
             Log.e(TAG, "UID " + uid + " not visible to the current user");
             return;
         }
diff --git a/service/java/com/android/server/wifi/WifiServiceImpl.java b/service/java/com/android/server/wifi/WifiServiceImpl.java
index d252e2f..f1f9d79 100644
--- a/service/java/com/android/server/wifi/WifiServiceImpl.java
+++ b/service/java/com/android/server/wifi/WifiServiceImpl.java
@@ -105,6 +105,7 @@
 import android.os.Build;
 import android.os.Handler;
 import android.os.HandlerExecutor;
+import android.os.HandlerThread;
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.ParcelFileDescriptor;
@@ -274,6 +275,7 @@
     private final DppManager mDppManager;
     private final WifiApConfigStore mWifiApConfigStore;
     private final WifiThreadRunner mWifiThreadRunner;
+    private final HandlerThread mWifiHandlerThread;
     private final MemoryStoreImpl mMemoryStoreImpl;
     private final WifiScoreCard mWifiScoreCard;
     private final WifiHealthMonitor mWifiHealthMonitor;
@@ -347,6 +349,7 @@
         mWifiNetworkSuggestionsManager = mWifiInjector.getWifiNetworkSuggestionsManager();
         mDppManager = mWifiInjector.getDppManager();
         mWifiThreadRunner = mWifiInjector.getWifiThreadRunner();
+        mWifiHandlerThread = mWifiInjector.getWifiHandlerThread();
         mWifiConfigManager = mWifiInjector.getWifiConfigManager();
         mPasspointManager = mWifiInjector.getPasspointManager();
         mWifiScoreCard = mWifiInjector.getWifiScoreCard();
@@ -404,7 +407,9 @@
                             }
                         }
                     },
-                    new IntentFilter(TelephonyManager.ACTION_SIM_CARD_STATE_CHANGED));
+                    new IntentFilter(TelephonyManager.ACTION_SIM_CARD_STATE_CHANGED),
+                    null,
+                    new Handler(mWifiHandlerThread.getLooper()));
 
             mContext.registerReceiver(
                     new BroadcastReceiver() {
@@ -418,7 +423,9 @@
                             }
                         }
                     },
-                    new IntentFilter(TelephonyManager.ACTION_SIM_APPLICATION_STATE_CHANGED));
+                    new IntentFilter(TelephonyManager.ACTION_SIM_APPLICATION_STATE_CHANGED),
+                    null,
+                    new Handler(mWifiHandlerThread.getLooper()));
 
             mContext.registerReceiver(
                     new BroadcastReceiver() {
@@ -431,30 +438,39 @@
                                 Log.d(TAG, "resetting networks as default data SIM is changed");
                                 resetCarrierNetworks(RESET_SIM_REASON_DEFAULT_DATA_SIM_CHANGED);
                                 mLastSubId = subId;
-                                mWifiThreadRunner.post(() -> {
-                                    mWifiDataStall.resetPhoneStateListener();
-                                });
+                                mWifiDataStall.resetPhoneStateListener();
                             }
                         }
                     },
-                    new IntentFilter(TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED));
+                    new IntentFilter(TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED),
+                    null,
+                    new Handler(mWifiHandlerThread.getLooper()));
 
             mContext.registerReceiver(
                     new BroadcastReceiver() {
-                    @Override
-                    public void onReceive(Context context, Intent intent) {
-                        String countryCode = intent.getStringExtra(
-                                TelephonyManager.EXTRA_NETWORK_COUNTRY);
-                        Log.d(TAG, "Country code changed to :" + countryCode);
-                        mCountryCode.setTelephonyCountryCodeAndUpdate(countryCode);
-                    }}, new IntentFilter(TelephonyManager.ACTION_NETWORK_COUNTRY_CHANGED));
+                        @Override
+                        public void onReceive(Context context, Intent intent) {
+                            String countryCode = intent.getStringExtra(
+                                    TelephonyManager.EXTRA_NETWORK_COUNTRY);
+                            Log.d(TAG, "Country code changed to :" + countryCode);
+                            mCountryCode.setTelephonyCountryCodeAndUpdate(countryCode);
+                        }
+                    },
+                    new IntentFilter(TelephonyManager.ACTION_NETWORK_COUNTRY_CHANGED),
+                    null,
+                    new Handler(mWifiHandlerThread.getLooper()));
+
             mContext.registerReceiver(
                     new BroadcastReceiver() {
                         @Override
                         public void onReceive(Context context, Intent intent) {
                             Log.d(TAG, "locale changed");
                             resetNotificationManager();
-                        }}, new IntentFilter(Intent.ACTION_LOCALE_CHANGED));
+                        }
+                    },
+                    new IntentFilter(Intent.ACTION_LOCALE_CHANGED),
+                    null,
+                    new Handler(mWifiHandlerThread.getLooper()));
 
             // Adding optimizations of only receiving broadcasts when wifi is enabled
             // can result in race conditions when apps toggle wifi in the background
@@ -469,36 +485,34 @@
     }
 
     private void resetCarrierNetworks(@ClientModeImpl.ResetSimReason int resetReason) {
-        mWifiThreadRunner.post(() -> {
-            Log.d(TAG, "resetting carrier networks since SIM was changed");
-            if (resetReason == RESET_SIM_REASON_SIM_INSERTED
-                    || resetReason == RESET_SIM_REASON_DEFAULT_DATA_SIM_CHANGED) {
-                // clear all SIM related notifications since some action was taken to address
-                // "missing" SIM issue
-                mSimRequiredNotifier.dismissSimRequiredNotification();
-            }
-            if (resetReason != RESET_SIM_REASON_SIM_INSERTED) {
-                mWifiConfigManager.resetSimNetworks();
-                mWifiNetworkSuggestionsManager.resetSimNetworkSuggestions();
-                mPasspointManager.resetSimPasspointNetwork();
-                mWifiConfigManager.stopRestrictingAutoJoinToSubscriptionId();
-            }
+        Log.d(TAG, "resetting carrier networks since SIM was changed");
+        if (resetReason == RESET_SIM_REASON_SIM_INSERTED
+                || resetReason == RESET_SIM_REASON_DEFAULT_DATA_SIM_CHANGED) {
+            // clear all SIM related notifications since some action was taken to address
+            // "missing" SIM issue
+            mSimRequiredNotifier.dismissSimRequiredNotification();
+        }
+        if (resetReason != RESET_SIM_REASON_SIM_INSERTED) {
+            mWifiConfigManager.resetSimNetworks();
+            mWifiNetworkSuggestionsManager.resetSimNetworkSuggestions();
+            mPasspointManager.resetSimPasspointNetwork();
+            mWifiConfigManager.stopRestrictingAutoJoinToSubscriptionId();
+        }
 
-            // do additional handling if we are current connected to a sim auth network
-            for (ClientModeManager cmm : mActiveModeWarden.getClientModeManagers()) {
-                cmm.resetSimAuthNetworks(resetReason);
-            }
-            mWifiNetworkSuggestionsManager.resetCarrierPrivilegedApps();
-            if (resetReason == RESET_SIM_REASON_SIM_INSERTED) {
-                // clear the blocklists in case any SIM based network were disabled due to the SIM
-                // not being available.
-                mWifiConfigManager.enableTemporaryDisabledNetworks();
-                mWifiConnectivityManager.forceConnectivityScan(ClientModeImpl.WIFI_WORK_SOURCE);
-            } else {
-                // Remove all ephemeral carrier networks keep subscriptionId update with SIM changes
-                mWifiConfigManager.removeEphemeralCarrierNetworks();
-            }
-        });
+        // do additional handling if we are current connected to a sim auth network
+        for (ClientModeManager cmm : mActiveModeWarden.getClientModeManagers()) {
+            cmm.resetSimAuthNetworks(resetReason);
+        }
+        mWifiNetworkSuggestionsManager.resetCarrierPrivilegedApps();
+        if (resetReason == RESET_SIM_REASON_SIM_INSERTED) {
+            // clear the blocklists in case any SIM based network were disabled due to the SIM
+            // not being available.
+            mWifiConfigManager.enableTemporaryDisabledNetworks();
+            mWifiConnectivityManager.forceConnectivityScan(ClientModeImpl.WIFI_WORK_SOURCE);
+        } else {
+            // Remove all ephemeral carrier networks keep subscriptionId update with SIM changes
+            mWifiConfigManager.removeEphemeralCarrierNetworks();
+        }
     }
 
     public void handleBootCompleted() {
@@ -512,41 +526,53 @@
             intentFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
             intentFilter.addAction(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED);
             intentFilter.addAction(Intent.ACTION_SHUTDOWN);
-            mContext.registerReceiver(new BroadcastReceiver() {
-                @Override
-                public void onReceive(Context context, Intent intent) {
-                    String action = intent.getAction();
-                    if (action.equals(Intent.ACTION_USER_REMOVED)) {
-                        UserHandle userHandle = intent.getParcelableExtra(Intent.EXTRA_USER);
-                        if (userHandle == null) {
-                            Log.e(TAG, "User removed broadcast received with no user handle");
-                            return;
+            mContext.registerReceiver(
+                    new BroadcastReceiver() {
+                        @Override
+                        public void onReceive(Context context, Intent intent) {
+                            String action = intent.getAction();
+                            if (action.equals(Intent.ACTION_USER_REMOVED)) {
+                                UserHandle userHandle =
+                                        intent.getParcelableExtra(Intent.EXTRA_USER);
+                                if (userHandle == null) {
+                                    Log.e(TAG,
+                                            "User removed broadcast received with no user handle");
+                                    return;
+                                }
+                                mWifiConfigManager
+                                        .removeNetworksForUser(userHandle.getIdentifier());
+                            } else if (action.equals(
+                                    BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED)) {
+                                int state = intent.getIntExtra(
+                                        BluetoothAdapter.EXTRA_CONNECTION_STATE,
+                                        BluetoothAdapter.STATE_DISCONNECTED);
+                                boolean isConnected =
+                                        state != BluetoothAdapter.STATE_DISCONNECTED;
+                                mWifiGlobals.setBluetoothConnected(isConnected);
+                                for (ClientModeManager cmm :
+                                        mActiveModeWarden.getClientModeManagers()) {
+                                    cmm.onBluetoothConnectionStateChanged();
+                                }
+                            } else if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
+                                int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,
+                                        BluetoothAdapter.STATE_OFF);
+                                boolean isEnabled = state != BluetoothAdapter.STATE_OFF;
+                                mWifiGlobals.setBluetoothEnabled(isEnabled);
+                                for (ClientModeManager cmm :
+                                        mActiveModeWarden.getClientModeManagers()) {
+                                    cmm.onBluetoothConnectionStateChanged();
+                                }
+                            } else if (action.equals(
+                                    PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED)) {
+                                handleIdleModeChanged();
+                            } else if (action.equals(Intent.ACTION_SHUTDOWN)) {
+                                handleShutDown();
+                            }
                         }
-                        mWifiThreadRunner.post(() -> mWifiConfigManager
-                                .removeNetworksForUser(userHandle.getIdentifier()));
-                    } else if (action.equals(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED)) {
-                        int state = intent.getIntExtra(BluetoothAdapter.EXTRA_CONNECTION_STATE,
-                                BluetoothAdapter.STATE_DISCONNECTED);
-                        boolean isConnected = state != BluetoothAdapter.STATE_DISCONNECTED;
-                        mWifiGlobals.setBluetoothConnected(isConnected);
-                        for (ClientModeManager cmm : mActiveModeWarden.getClientModeManagers()) {
-                            cmm.onBluetoothConnectionStateChanged();
-                        }
-                    } else if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
-                        int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,
-                                BluetoothAdapter.STATE_OFF);
-                        boolean isEnabled = state != BluetoothAdapter.STATE_OFF;
-                        mWifiGlobals.setBluetoothEnabled(isEnabled);
-                        for (ClientModeManager cmm : mActiveModeWarden.getClientModeManagers()) {
-                            cmm.onBluetoothConnectionStateChanged();
-                        }
-                    } else if (action.equals(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED)) {
-                        handleIdleModeChanged();
-                    } else if (action.equals(Intent.ACTION_SHUTDOWN)) {
-                        handleShutDown();
-                    }
-                }
-            }, intentFilter);
+                    },
+                    intentFilter,
+                    null,
+                    new Handler(mWifiHandlerThread.getLooper()));
             mMemoryStoreImpl.start();
             mPasspointManager.initializeProvisioner(
                     mWifiInjector.getPasspointProvisionerHandlerThread().getLooper());
@@ -692,13 +718,12 @@
         // notifyShuttingDown() doesn't have codes that may cause concurrentModificationException,
         // e.g., access to a collection.
         mActiveModeWarden.notifyShuttingDown();
-        mWifiThreadRunner.post(()-> {
-            // There is no explicit disconnection event in clientModeImpl during shutdown.
-            // Call resetConnectionState() so that connection duration is calculated
-            // before memory store write triggered by mMemoryStoreImpl.stop().
-            mWifiScoreCard.resetAllConnectionStates();
-            mMemoryStoreImpl.stop();
-        });
+
+        // There is no explicit disconnection event in clientModeImpl during shutdown.
+        // Call resetConnectionState() so that connection duration is calculated
+        // before memory store write triggered by mMemoryStoreImpl.stop().
+        mWifiScoreCard.resetAllConnectionStates();
+        mMemoryStoreImpl.stop();
     }
 
     private boolean checkNetworkSettingsPermission(int pid, int uid) {
@@ -1180,7 +1205,8 @@
 
         mLog.info("startTetheredHotspot uid=%").c(Binder.getCallingUid()).flush();
 
-        if (!mTetheredSoftApTracker.setEnablingIfAllowed()) {
+        if (!mWifiThreadRunner.call(
+                () -> mTetheredSoftApTracker.setEnablingIfAllowed(), false)) {
             mLog.err("Tethering is already active.").flush();
             return false;
         }
@@ -2447,6 +2473,24 @@
             String featureId, boolean callerNetworksOnly) {
         enforceAccessPermission();
         int callingUid = Binder.getCallingUid();
+        // bypass shell: can get various pkg name
+        // also bypass if caller is only retrieving networks added by itself
+        if (callingUid != Process.SHELL_UID && callingUid != Process.ROOT_UID) {
+            mWifiPermissionsUtil.checkPackage(callingUid, packageName);
+            if (!callerNetworksOnly) {
+                long ident = Binder.clearCallingIdentity();
+                try {
+                    mWifiPermissionsUtil.enforceCanAccessScanResults(packageName, featureId,
+                            callingUid, null);
+                } catch (SecurityException e) {
+                    Log.w(TAG, "Permission violation - getConfiguredNetworks not allowed for uid="
+                            + callingUid + ", packageName=" + packageName + ", reason=" + e);
+                    return new ParceledListSlice<>(new ArrayList<>());
+                } finally {
+                    Binder.restoreCallingIdentity(ident);
+                }
+            }
+        }
         boolean isDeviceOrProfileOwner = isDeviceOrProfileOwner(callingUid, packageName);
         boolean isCarrierApp = mWifiInjector.makeTelephonyManager()
                 .checkCarrierPrivilegesForPackageAnyPhone(packageName)
@@ -2459,22 +2503,6 @@
                         "Not a DO, PO, carrier or privileged app");
             }
         }
-        // bypass shell: can get various pkg name
-        // also bypass if caller is only retrieving networks added by itself
-        if (callingUid != Process.SHELL_UID && callingUid != Process.ROOT_UID
-                && !callerNetworksOnly) {
-            long ident = Binder.clearCallingIdentity();
-            try {
-                mWifiPermissionsUtil.enforceCanAccessScanResults(packageName, featureId,
-                        callingUid, null);
-            } catch (SecurityException e) {
-                Log.w(TAG, "Permission violation - getConfiguredNetworks not allowed for uid="
-                        + callingUid + ", packageName=" + packageName + ", reason=" + e);
-                return new ParceledListSlice<>(new ArrayList<>());
-            } finally {
-                Binder.restoreCallingIdentity(ident);
-            }
-        }
         boolean isTargetSdkLessThanQOrPrivileged = isTargetSdkLessThanQOrPrivileged(
                 packageName, Binder.getCallingPid(), callingUid);
         if (!isTargetSdkLessThanQOrPrivileged && !isCarrierApp) {
@@ -3727,57 +3755,60 @@
         intentFilter.addAction(Intent.ACTION_PACKAGE_CHANGED);
         intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
         intentFilter.addDataScheme("package");
-        mContext.registerReceiver(new BroadcastReceiver() {
-            @Override
-            public void onReceive(Context context, Intent intent) {
-                int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
-                Uri uri = intent.getData();
-                if (uid == -1 || uri == null) {
-                    Log.e(TAG, "Uid or Uri is missing for action:" + intent.getAction());
-                    return;
-                }
-                String pkgName = uri.getSchemeSpecificPart();
-                PackageManager pm = context.getPackageManager();
-                PackageInfo packageInfo = null;
-                try {
-                    packageInfo = pm.getPackageInfo(pkgName, 0);
-                } catch (PackageManager.NameNotFoundException e) {
-                    Log.w(TAG, "Couldn't get PackageInfo for package:" + pkgName);
-                }
-                // If package is not removed or disabled, just ignore.
-                if (packageInfo != null
-                        && packageInfo.applicationInfo != null
-                        && packageInfo.applicationInfo.enabled) {
-                    return;
-                }
-                Log.d(TAG, "Remove settings for package:" + pkgName);
-                // Call the method in the main Wifi thread.
-                mWifiThreadRunner.post(() -> {
-                    removeAppStateInternal(uid, pkgName);
-                });
-            }
-        }, intentFilter);
+        mContext.registerReceiver(
+                new BroadcastReceiver() {
+                    @Override
+                    public void onReceive(Context context, Intent intent) {
+                        int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
+                        Uri uri = intent.getData();
+                        if (uid == -1 || uri == null) {
+                            Log.e(TAG, "Uid or Uri is missing for action:" + intent.getAction());
+                            return;
+                        }
+                        String pkgName = uri.getSchemeSpecificPart();
+                        PackageManager pm = context.getPackageManager();
+                        PackageInfo packageInfo = null;
+                        try {
+                            packageInfo = pm.getPackageInfo(pkgName, 0);
+                        } catch (PackageManager.NameNotFoundException e) {
+                            Log.w(TAG, "Couldn't get PackageInfo for package:" + pkgName);
+                        }
+                        // If package is not removed or disabled, just ignore.
+                        if (packageInfo != null
+                                && packageInfo.applicationInfo != null
+                                && packageInfo.applicationInfo.enabled) {
+                            return;
+                        }
+                        Log.d(TAG, "Remove settings for package:" + pkgName);
+                        removeAppStateInternal(uid, pkgName);
+                    }
+                },
+                intentFilter,
+                null,
+                new Handler(mWifiHandlerThread.getLooper()));
     }
 
     private void registerForCarrierConfigChange() {
         IntentFilter filter = new IntentFilter();
         filter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
-        mContext.registerReceiver(new BroadcastReceiver() {
-            @Override
-            public void onReceive(Context context, Intent intent) {
-                final int subId = SubscriptionManager.getActiveDataSubscriptionId();
-                // post operation to handler thread
-                mWifiThreadRunner.post(() -> {
-                    Log.d(TAG, "ACTION_CARRIER_CONFIG_CHANGED, active subId: " + subId);
-                    mTetheredSoftApTracker.updateSoftApCapabilityWhenCarrierConfigChanged(subId);
-                    mActiveModeWarden.updateSoftApCapability(
-                            mTetheredSoftApTracker.getSoftApCapability());
-                });
-            }
-        }, filter);
+        mContext.registerReceiver(
+                new BroadcastReceiver() {
+                    @Override
+                    public void onReceive(Context context, Intent intent) {
+                        final int subId = SubscriptionManager.getActiveDataSubscriptionId();
+                        Log.d(TAG, "ACTION_CARRIER_CONFIG_CHANGED, active subId: " + subId);
+                        mTetheredSoftApTracker
+                                .updateSoftApCapabilityWhenCarrierConfigChanged(subId);
+                        mActiveModeWarden.updateSoftApCapability(
+                                mTetheredSoftApTracker.getSoftApCapability());
+                    }
+                },
+                filter,
+                null,
+                new Handler(mWifiHandlerThread.getLooper()));
 
         WifiPhoneStateListener phoneStateListener = new WifiPhoneStateListener(
-                mWifiInjector.getWifiHandlerThread().getLooper());
+                mWifiHandlerThread.getLooper());
 
         mContext.getSystemService(TelephonyManager.class).listen(
                 phoneStateListener, PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE);
@@ -5067,6 +5098,7 @@
             throw new IllegalArgumentException("listener must not be null");
         }
         final int uid = Binder.getCallingUid();
+        mWifiPermissionsUtil.checkPackage(uid, packageName);
         enforceAccessPermission();
         enforceLocationPermission(packageName, featureId, uid);
         if (isVerboseLoggingEnabled()) {
@@ -5235,7 +5267,7 @@
         enforceAccessPermission();
         long callingIdentity = Binder.clearCallingIdentity();
         try {
-            if (!mWifiPermissionsUtil.doesUidBelongToCurrentUser(uid)) {
+            if (!mWifiPermissionsUtil.doesUidBelongToCurrentUserOrDeviceOwner(uid)) {
                 Log.e(TAG, "UID " + uid + " not visible to the current user");
                 throw new SecurityException("UID " + uid + " not visible to the current user");
             }
@@ -5261,7 +5293,7 @@
         int uid = Binder.getCallingUid();
         long callingIdentity = Binder.clearCallingIdentity();
         try {
-            if (!mWifiPermissionsUtil.doesUidBelongToCurrentUser(uid)) {
+            if (!mWifiPermissionsUtil.doesUidBelongToCurrentUserOrDeviceOwner(uid)) {
                 Log.e(TAG, "UID " + uid + " not visible to the current user");
                 throw new SecurityException("UID " + uid + " not visible to the current user");
             }
diff --git a/service/java/com/android/server/wifi/WifiVendorHal.java b/service/java/com/android/server/wifi/WifiVendorHal.java
index c48ae2b..81b881a 100644
--- a/service/java/com/android/server/wifi/WifiVendorHal.java
+++ b/service/java/com/android/server/wifi/WifiVendorHal.java
@@ -459,7 +459,7 @@
             @NonNull WorkSource requestorWs) {
         synchronized (sLock) {
             IWifiStaIface iface = mHalDeviceManager.createStaIface(
-                    new StaInterfaceDestroyedListenerInternal(destroyedListener), null,
+                    new StaInterfaceDestroyedListenerInternal(destroyedListener), mHalEventHandler,
                     requestorWs);
             if (iface == null) {
                 mLog.err("Failed to create STA iface").flush();
@@ -573,7 +573,7 @@
         synchronized (sLock) {
             IWifiApIface iface = mHalDeviceManager.createApIface(
                     getNecessaryCapabilitiesForSoftApMode(band),
-                    new ApInterfaceDestroyedListenerInternal(destroyedListener), null,
+                    new ApInterfaceDestroyedListenerInternal(destroyedListener), mHalEventHandler,
                     requestorWs, isBridged);
             if (iface == null) {
                 mLog.err("Failed to create AP iface").flush();
diff --git a/service/java/com/android/server/wifi/aware/WifiAwareStateManager.java b/service/java/com/android/server/wifi/aware/WifiAwareStateManager.java
index 3ef797e..afbeffa 100644
--- a/service/java/com/android/server/wifi/aware/WifiAwareStateManager.java
+++ b/service/java/com/android/server/wifi/aware/WifiAwareStateManager.java
@@ -122,7 +122,6 @@
     private static final int COMMAND_TYPE_ENABLE_USAGE = 108;
     private static final int COMMAND_TYPE_DISABLE_USAGE = 109;
     private static final int COMMAND_TYPE_GET_CAPABILITIES = 111;
-    private static final int COMMAND_TYPE_CREATE_ALL_DATA_PATH_INTERFACES = 112;
     private static final int COMMAND_TYPE_DELETE_ALL_DATA_PATH_INTERFACES = 113;
     private static final int COMMAND_TYPE_CREATE_DATA_PATH_INTERFACE = 114;
     private static final int COMMAND_TYPE_DELETE_DATA_PATH_INTERFACE = 115;
@@ -886,15 +885,6 @@
     }
 
     /**
-     * Create all Aware data path interfaces which are supported by the firmware capabilities.
-     */
-    public void createAllDataPathInterfaces() {
-        Message msg = mSm.obtainMessage(MESSAGE_TYPE_COMMAND);
-        msg.arg1 = COMMAND_TYPE_CREATE_ALL_DATA_PATH_INTERFACES;
-        mSm.sendMessage(msg);
-    }
-
-    /**
      * delete all Aware data path interfaces.
      */
     public void deleteAllDataPathInterfaces() {
@@ -1893,10 +1883,6 @@
                         waitForResponse = false;
                     }
                     break;
-                case COMMAND_TYPE_CREATE_ALL_DATA_PATH_INTERFACES:
-                    mDataPathMgr.createAllInterfaces();
-                    waitForResponse = false;
-                    break;
                 case COMMAND_TYPE_DELETE_ALL_DATA_PATH_INTERFACES:
                     mDataPathMgr.deleteAllInterfaces();
                     waitForResponse = false;
@@ -2178,11 +2164,6 @@
                             "processTimeout: GET_CAPABILITIES timed-out - strange, will try again"
                                     + " when next enabled!?");
                     break;
-                case COMMAND_TYPE_CREATE_ALL_DATA_PATH_INTERFACES:
-                    Log.wtf(TAG,
-                            "processTimeout: CREATE_ALL_DATA_PATH_INTERFACES - shouldn't be "
-                                    + "waiting!");
-                    break;
                 case COMMAND_TYPE_DELETE_ALL_DATA_PATH_INTERFACES:
                     Log.wtf(TAG,
                             "processTimeout: DELETE_ALL_DATA_PATH_INTERFACES - shouldn't be "
@@ -2773,7 +2754,7 @@
         if (completedCommand.arg1 == COMMAND_TYPE_CONNECT) {
             if (mCurrentAwareConfiguration == null) { // enabled (as opposed to re-configured)
                 queryCapabilities();
-                createAllDataPathInterfaces();
+                mDataPathMgr.createAllInterfaces();
             }
 
             Bundle data = completedCommand.getData();
@@ -3501,6 +3482,14 @@
     }
 
     /**
+     * Just a proxy to call {@link WifiAwareDataPathStateManager#createAllInterfaces()} for test.
+     */
+    @VisibleForTesting
+    public void createAllDataPathInterfaces() {
+        mDataPathMgr.createAllInterfaces();
+    }
+
+    /**
      * Dump the internal state of the class.
      */
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
diff --git a/service/java/com/android/server/wifi/coex/CoexManager.java b/service/java/com/android/server/wifi/coex/CoexManager.java
index 2bfcf13..fa4c45f 100644
--- a/service/java/com/android/server/wifi/coex/CoexManager.java
+++ b/service/java/com/android/server/wifi/coex/CoexManager.java
@@ -107,6 +107,10 @@
     private static final String TAG = "WifiCoexManager";
     private boolean mVerboseLoggingEnabled = false;
 
+    // Delay in millis before updating cell channels to empty in case of a temporary idle.
+    @VisibleForTesting
+    static final int CELL_CHANNEL_IDLE_DELAY_MILLIS = 2_000;
+
     @NonNull
     private final Context mContext;
     @NonNull
@@ -174,6 +178,12 @@
     /* package */ class CoexTelephonyCallback extends TelephonyCallback
             implements TelephonyCallback.PhysicalChannelConfigListener {
         private final int mSubId;
+        private boolean mIsEmpty = true;
+        private boolean mIsPendingEmpty = false;
+        private final Runnable mClearCellChannelsRunnable = () -> {
+            mIsPendingEmpty = false;
+            updateCellChannels(new ArrayList<>());
+        };
 
         private CoexTelephonyCallback(int subId) {
             super();
@@ -191,6 +201,25 @@
             for (PhysicalChannelConfig config : configs) {
                 cellChannels.add(new CoexUtils.CoexCellChannel(config, mSubId));
             }
+            // Delay updating an empty cell channel list in case this is a temporary idle to avoid
+            // recalculating the unsafe channels and sending them to the driver again.
+            if (configs.isEmpty()) {
+                if (!mIsEmpty && !mIsPendingEmpty) {
+                    mIsPendingEmpty = true;
+                    mCallbackHandler.postDelayed(
+                            mClearCellChannelsRunnable, CELL_CHANNEL_IDLE_DELAY_MILLIS);
+                }
+                return;
+            }
+            if (mIsPendingEmpty) {
+                mIsPendingEmpty = false;
+                mCallbackHandler.removeCallbacks(mClearCellChannelsRunnable);
+            }
+            updateCellChannels(cellChannels);
+        }
+
+        private void updateCellChannels(List<CoexUtils.CoexCellChannel> cellChannels) {
+            mIsEmpty = cellChannels.isEmpty();
             if (cellChannels.equals(mCellChannelsPerSubId.get(mSubId))) {
                 // No change to cell channels, so no need to recalculate
                 return;
diff --git a/service/java/com/android/server/wifi/hotspot2/PasspointManager.java b/service/java/com/android/server/wifi/hotspot2/PasspointManager.java
index 8d5a1d7..192b26b 100644
--- a/service/java/com/android/server/wifi/hotspot2/PasspointManager.java
+++ b/service/java/com/android/server/wifi/hotspot2/PasspointManager.java
@@ -128,6 +128,7 @@
     private final WifiConfigManager mWifiConfigManager;
     private final WifiMetrics mWifiMetrics;
     private final PasspointProvisioner mPasspointProvisioner;
+    private PasspointNetworkNominateHelper mPasspointNetworkNominateHelper;
     private final AppOpsManager mAppOps;
     private final WifiCarrierInfoManager mWifiCarrierInfoManager;
     private final MacAddressUtil mMacAddressUtil;
@@ -393,6 +394,14 @@
     }
 
     /**
+     * Sets the {@link PasspointNetworkNominateHelper} used by this PasspointManager.
+     */
+    public void setPasspointNetworkNominateHelper(
+            @Nullable PasspointNetworkNominateHelper nominateHelper) {
+        mPasspointNetworkNominateHelper = nominateHelper;
+    }
+
+    /**
      * Enable verbose logging
      * @param verbose enables verbose logging
      */
@@ -461,7 +470,7 @@
             Log.e(TAG, "Set isTrusted to false on a non suggestion passpoint is not allowed");
             return false;
         }
-        if (!mWifiPermissionsUtil.doesUidBelongToCurrentUser(uid)) {
+        if (!mWifiPermissionsUtil.doesUidBelongToCurrentUserOrDeviceOwner(uid)) {
             Log.e(TAG, "UID " + uid + " not visible to the current user");
             return false;
         }
@@ -555,6 +564,9 @@
             mWifiMetrics.incrementTotalNumberOfPasspointProfilesWithDecoratedIdentity();
         }
         mWifiMetrics.incrementNumPasspointProviderInstallSuccess();
+        if (mPasspointNetworkNominateHelper != null) {
+            mPasspointNetworkNominateHelper.refreshPasspointNetworkCandidates(isFromSuggestion);
+        }
         return true;
     }
 
@@ -565,7 +577,7 @@
                     + provider.getCreatorUid());
             return false;
         }
-        if (!mWifiPermissionsUtil.doesUidBelongToCurrentUser(callingUid)) {
+        if (!mWifiPermissionsUtil.doesUidBelongToCurrentUserOrDeviceOwner(callingUid)) {
             Log.e(TAG, "UID " + callingUid + " not visible to the current user");
             return false;
         }
diff --git a/service/java/com/android/server/wifi/hotspot2/PasspointNetworkNominateHelper.java b/service/java/com/android/server/wifi/hotspot2/PasspointNetworkNominateHelper.java
index a4d7e83..b8a6f85 100644
--- a/service/java/com/android/server/wifi/hotspot2/PasspointNetworkNominateHelper.java
+++ b/service/java/com/android/server/wifi/hotspot2/PasspointNetworkNominateHelper.java
@@ -43,9 +43,11 @@
  * Passpoint networks.
  */
 public class PasspointNetworkNominateHelper {
-    private final PasspointManager mPasspointManager;
-    private final WifiConfigManager mWifiConfigManager;
-    private final LocalLog mLocalLog;
+    @NonNull private final PasspointManager mPasspointManager;
+    @NonNull private final WifiConfigManager mWifiConfigManager;
+    @NonNull private final List<ScanDetail> mCachedScanDetails = new ArrayList<>();
+    @NonNull private LocalLog mLocalLog;
+
     /**
      * Contained information for a Passpoint network candidate.
      */
@@ -61,8 +63,8 @@
         ScanDetail mScanDetail;
     }
 
-    public PasspointNetworkNominateHelper(PasspointManager passpointManager,
-            WifiConfigManager wifiConfigManager, LocalLog localLog) {
+    public PasspointNetworkNominateHelper(@NonNull PasspointManager passpointManager,
+            @NonNull WifiConfigManager wifiConfigManager, @NonNull LocalLog localLog) {
         mPasspointManager = passpointManager;
         mWifiConfigManager = wifiConfigManager;
         mLocalLog = localLog;
@@ -95,11 +97,25 @@
             }
             filteredScanDetails.add(scanDetail);
         }
-
+        if (!filteredScanDetails.isEmpty()) {
+            mCachedScanDetails.clear();
+            mCachedScanDetails.addAll(filteredScanDetails);
+        }
         return findBestMatchScanDetailForProviders(filteredScanDetails, isFromSuggestion);
     }
 
     /**
+     * Refresh the best matched available Passpoint network candidates in WifiConfigManager for the
+     * last seen scanDetails. This should be used if new profiles have been added but scan results
+     * remain the same.
+     * @param isFromSuggestion True to indicate profile from suggestion, false for user saved.
+     */
+    public void refreshPasspointNetworkCandidates(boolean isFromSuggestion) {
+        // This method will add the provider wifi configs to WifiConfigManager
+        findBestMatchScanDetailForProviders(mCachedScanDetails, isFromSuggestion);
+    }
+
+    /**
      * Check if ANQP element inside that scanDetail indicate AP WAN port link status is down.
      *
      * @param scanDetail contains ANQP element to check.
@@ -126,8 +142,8 @@
     }
 
     /**
-     * Match available providers for each scan detail. Then for each available provider, find the
-     * best scan detail for it.
+     * Match available providers for each scan detail and add their configs to WifiConfigManager.
+     * Then for each available provider, find the best scan detail for it.
      * @param scanDetails all details for this scan.
      * @param isFromSuggestion True to indicate profile from suggestion, false for user saved.
      * @return List of pair of scanDetail and WifiConfig from matched available provider.
@@ -218,7 +234,7 @@
             return existingNetwork;
         }
         mWifiConfigManager.allowAutojoin(result.getNetworkId(), config.allowAutojoin);
-        mWifiConfigManager.enableNetwork(result.getNetworkId(), false, Process.WIFI_UID, null);
+        mWifiConfigManager.enableNetwork(result.getNetworkId(), false, config.creatorUid, null);
         mWifiConfigManager.setNetworkCandidateScanResult(result.getNetworkId(),
                 candidate.mScanDetail.getScanResult(), 0, null);
         mWifiConfigManager.updateScanDetailForNetwork(
diff --git a/service/java/com/android/server/wifi/hotspot2/omadm/DevDetailMo.java b/service/java/com/android/server/wifi/hotspot2/omadm/DevDetailMo.java
index 54ab547..5c872ad 100644
--- a/service/java/com/android/server/wifi/hotspot2/omadm/DevDetailMo.java
+++ b/service/java/com/android/server/wifi/hotspot2/omadm/DevDetailMo.java
@@ -50,7 +50,7 @@
 
     private static final String MO_NAME = "DevDetail";
 
-    private static final String TAG_EXT = "ext";
+    private static final String TAG_EXT = "Ext";
     private static final String TAG_ORG_WIFI = "org.wi-fi";
     private static final String TAG_WIFI = "Wi-Fi";
     private static final String TAG_EAP_METHOD_LIST = "EAPMethodList"; //Required field
diff --git a/service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java b/service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java
index 11b25ce..62f8feb 100644
--- a/service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java
+++ b/service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java
@@ -1190,12 +1190,16 @@
                                 WifiP2pManager.BUSY);
                         break;
                     case WifiP2pManager.SET_WFD_INFO:
+                        WifiP2pWfdInfo d = (WifiP2pWfdInfo) message.obj;
                         if (!getWfdPermission(message.sendingUid)) {
                             replyToMessage(message, WifiP2pManager.SET_WFD_INFO_FAILED,
                                     WifiP2pManager.ERROR);
+                        } else if (d != null) {
+                            mThisDevice.wfdInfo = d;
+                            replyToMessage(message, WifiP2pManager.SET_WFD_INFO_SUCCEEDED);
                         } else {
                             replyToMessage(message, WifiP2pManager.SET_WFD_INFO_FAILED,
-                                    WifiP2pManager.BUSY);
+                                    WifiP2pManager.ERROR);
                         }
                         break;
                     case WifiP2pManager.REQUEST_PEERS:
@@ -1594,7 +1598,8 @@
                         // which require P2P to be active.
                         if (message.what < Protocol.BASE_WIFI_P2P_MANAGER
                                 || Protocol.BASE_WIFI_P2P_SERVICE <= message.what
-                                || message.what == WifiP2pManager.UPDATE_CHANNEL_INFO) {
+                                || message.what == WifiP2pManager.UPDATE_CHANNEL_INFO
+                                || message.what == WifiP2pManager.SET_WFD_INFO) {
                             return NOT_HANDLED;
                         }
                         // If P2P is not ready, it might be disabled due
@@ -3751,11 +3756,7 @@
             }
             config.groupOwnerIntent = selectGroupOwnerIntentIfNecessary(config);
             boolean action;
-            if (triggerType == P2P_CONNECT_TRIGGER_GROUP_NEG_REQ) {
-                // If this is called from the GO negotiation path, the sender initiated
-                // a group negotiation.
-                action = FORM_GROUP;
-            } else if (triggerType == P2P_CONNECT_TRIGGER_INVITATION_REQ) {
+            if (triggerType == P2P_CONNECT_TRIGGER_INVITATION_REQ) {
                 // The group owner won't report it is a Group Owner always.
                 // If this is called from the invitation path, the sender should be in
                 // a group, and the target should be a group owner.
diff --git a/service/java/com/android/server/wifi/util/WifiPermissionsUtil.java b/service/java/com/android/server/wifi/util/WifiPermissionsUtil.java
index 5845f74..3072fd4 100644
--- a/service/java/com/android/server/wifi/util/WifiPermissionsUtil.java
+++ b/service/java/com/android/server/wifi/util/WifiPermissionsUtil.java
@@ -301,7 +301,8 @@
         }
         // If the User or profile is current, permission is granted
         // Otherwise, uid must have INTERACT_ACROSS_USERS_FULL permission.
-        boolean isCurrentProfile = isCurrentProfile(uid);
+        boolean isCurrentProfile = doesUidBelongToUser(
+                uid, mWifiPermissionsWrapper.getCurrentUser());
         if (!isCurrentProfile && !checkInteractAcrossUsersFull(uid)) {
             if (mVerboseLoggingEnabled) {
                 Log.v(TAG, "enforceCanAccessScanResults(pkg=" + pkgName + ", uid=" + uid + "): "
@@ -433,17 +434,6 @@
                 == PackageManager.PERMISSION_GRANTED;
     }
 
-    /**
-     * Returns true if the calling user is the current one or a profile of the
-     * current user.
-     */
-    private boolean isCurrentProfile(int uid) {
-        UserHandle currentUser = UserHandle.of(mWifiPermissionsWrapper.getCurrentUser());
-        UserHandle callingUser = UserHandle.getUserHandleForUid(uid);
-        return currentUser.equals(callingUser)
-                || mUserManager.isSameProfileGroup(currentUser, callingUser);
-    }
-
     private boolean noteAppOpAllowed(String op, String pkgName, @Nullable String featureId,
             int uid, @Nullable String message) {
         return mAppOps.noteOp(op, uid, pkgName, featureId, message) == AppOpsManager.MODE_ALLOWED;
@@ -728,14 +718,9 @@
      * @return true if the given UID belongs to the current foreground user,
      *         otherwise false.
      */
-    public boolean doesUidBelongToCurrentUser(int uid) {
-        if (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)) {
-            return true;
-        }
-        boolean isCurrentProfile = isCurrentProfile(uid);
+    public boolean doesUidBelongToCurrentUserOrDeviceOwner(int uid) {
+        boolean isCurrentProfile = doesUidBelongToUser(
+                uid, mWifiPermissionsWrapper.getCurrentUser());
         if (!isCurrentProfile) {
             // Fix for b/174749461
             EventLog.writeEvent(0x534e4554, "174749461", -1,
@@ -745,6 +730,31 @@
     }
 
     /**
+     * Checks if the given UID belongs to the given user ID. This is
+     * used to prevent apps running in other users from modifying network configurations belonging
+     * to the given user.
+     * <p>
+     * UIDs belonging to system internals (such as SystemUI) are always allowed,
+     * since they always run as {@link UserHandle#USER_SYSTEM}.
+     *
+     * @param uid uid to check
+     * @param userId user to check against
+     * @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
+                // UIDs with the NETWORK_SETTINGS permission are always allowed since they are
+                // acting on behalf of the user.
+                || checkNetworkSettingsPermission(uid)) {
+            return true;
+        }
+        UserHandle uidHandle = UserHandle.getUserHandleForUid(uid);
+        UserHandle userHandle = UserHandle.of(userId);
+        return uidHandle.equals(userHandle)
+                || mUserManager.isSameProfileGroup(uidHandle, userHandle);
+    }
+
+    /**
      * Sets the verbose logging level.
      */
     public void enableVerboseLogging(boolean enabled) {
diff --git a/service/tests/wifitests/src/com/android/server/wifi/ActiveModeWardenTest.java b/service/tests/wifitests/src/com/android/server/wifi/ActiveModeWardenTest.java
index 1b32b8d..d694d8a 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/ActiveModeWardenTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/ActiveModeWardenTest.java
@@ -2799,6 +2799,47 @@
         assertEquals(additionalClientModeManager, requestedClientModeManager.getValue());
     }
 
+    public void requestAdditionalClientModeManagerWhenAlreadyPresentSameBssid(
+            ClientConnectivityRole role) throws Exception {
+        ConcreteClientModeManager additionalClientModeManager =
+                mock(ConcreteClientModeManager.class);
+        ExternalClientModeManagerRequestListener externalRequestListener = mock(
+                ExternalClientModeManagerRequestListener.class);
+        requestAdditionalClientModeManager(role, additionalClientModeManager,
+                externalRequestListener, TEST_SSID_2, TEST_BSSID_2);
+
+        ArgumentCaptor<ClientModeManager> requestedClientModeManager =
+                ArgumentCaptor.forClass(ClientModeManager.class);
+        verify(externalRequestListener).onAnswer(requestedClientModeManager.capture());
+        assertEquals(additionalClientModeManager, requestedClientModeManager.getValue());
+
+        // set additional CMM connected to ssid2/bssid2
+        WifiConfiguration config2 = new WifiConfiguration();
+        config2.SSID = TEST_SSID_2;
+        when(additionalClientModeManager.getConnectedWifiConfiguration()).thenReturn(config2);
+        when(additionalClientModeManager.getConnectedBssid()).thenReturn(TEST_BSSID_2);
+
+        // request for the same SSID/BSSID and expect the existing CMM to get returned twice.
+        if (role == ROLE_CLIENT_LOCAL_ONLY) {
+            mActiveModeWarden.requestLocalOnlyClientModeManager(
+                    externalRequestListener, TEST_WORKSOURCE, TEST_SSID_2, TEST_BSSID_2);
+        } else if (role == ROLE_CLIENT_SECONDARY_LONG_LIVED) {
+            mActiveModeWarden.requestSecondaryLongLivedClientModeManager(
+                    externalRequestListener, TEST_WORKSOURCE, TEST_SSID_2, TEST_BSSID_2);
+        } else if (role == ROLE_CLIENT_SECONDARY_TRANSIENT) {
+            mActiveModeWarden.requestSecondaryTransientClientModeManager(
+                    externalRequestListener, TEST_WORKSOURCE, TEST_SSID_2, TEST_BSSID_2);
+        }
+        mLooper.dispatchAll();
+
+        // Don't make another client mode manager.
+        verify(mWifiInjector, times(1))
+                .makeClientModeManager(any(), any(), eq(role), anyBoolean());
+        // Returns the existing client mode manager.
+        verify(externalRequestListener, times(2)).onAnswer(requestedClientModeManager.capture());
+        assertEquals(additionalClientModeManager, requestedClientModeManager.getValue());
+    }
+
     private void requestAdditionalClientModeManagerWhenConnectingToPrimaryBssid(
             ClientConnectivityRole role) throws Exception {
         enterClientModeActiveState();
@@ -2900,6 +2941,18 @@
     }
 
     @Test
+    public void requestLocalOnlyClientModeManagerWhenAlreadyPresentSameBssid() throws Exception {
+        // Ensure that we can create more client ifaces.
+        when(mWifiNative.isItPossibleToCreateStaIface(any())).thenReturn(true);
+        when(mResources.getBoolean(R.bool.config_wifiMultiStaLocalOnlyConcurrencyEnabled))
+                .thenReturn(true);
+        assertTrue(mActiveModeWarden.canRequestMoreClientModeManagersInRole(
+                TEST_WORKSOURCE, ROLE_CLIENT_LOCAL_ONLY));
+
+        requestAdditionalClientModeManagerWhenAlreadyPresentSameBssid(ROLE_CLIENT_LOCAL_ONLY);
+    }
+
+    @Test
     public void requestLocalOnlyClientModeManagerWhenConnectingToPrimaryBssid() throws Exception {
         // Ensure that we can create more client ifaces.
         when(mWifiNative.isItPossibleToCreateStaIface(any())).thenReturn(true);
@@ -3002,6 +3055,20 @@
     }
 
     @Test
+    public void requestSecondaryLongLivedClientModeManagerWhenAlreadyPresentSameBssid()
+            throws Exception {
+        // Ensure that we can create more client ifaces.
+        when(mWifiNative.isItPossibleToCreateStaIface(any())).thenReturn(true);
+        when(mResources.getBoolean(R.bool.config_wifiMultiStaRestrictedConcurrencyEnabled))
+                .thenReturn(true);
+        assertTrue(mActiveModeWarden.canRequestMoreClientModeManagersInRole(
+                TEST_WORKSOURCE, ROLE_CLIENT_SECONDARY_LONG_LIVED));
+
+        requestAdditionalClientModeManagerWhenAlreadyPresentSameBssid(
+                ROLE_CLIENT_SECONDARY_LONG_LIVED);
+    }
+
+    @Test
     public void requestSecondaryLongLivedClientModeManagerWhenConnectingToPrimaryBssid()
             throws Exception {
         // Ensure that we can create more client ifaces.
@@ -3078,6 +3145,21 @@
     }
 
     @Test
+    public void requestSecondaryTransientClientModeManagerWhenAlreadyPresentSameBssid()
+            throws Exception {
+        // Ensure that we can create more client ifaces.
+        when(mWifiNative.isItPossibleToCreateStaIface(any())).thenReturn(true);
+        when(mResources.getBoolean(
+                R.bool.config_wifiMultiStaNetworkSwitchingMakeBeforeBreakEnabled))
+                .thenReturn(true);
+        assertTrue(mActiveModeWarden.canRequestMoreClientModeManagersInRole(
+                TEST_WORKSOURCE, ROLE_CLIENT_SECONDARY_TRANSIENT));
+
+        requestAdditionalClientModeManagerWhenAlreadyPresentSameBssid(
+                ROLE_CLIENT_SECONDARY_TRANSIENT);
+    }
+
+    @Test
     public void requestSecondaryTransientClientModeManagerWhenConnectingToPrimaryBssid()
             throws Exception {
         // Ensure that we can create more client ifaces.
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 6d913a1..36d6e0f 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java
@@ -4223,7 +4223,8 @@
     }
 
     /**
-     * Verify that we do not set the user connect choice after connecting to a newly added network.
+     * Verify that we do not set the user connect choice after connecting to a newly added saved
+     * network.
      */
     @Test
     public void testNoSetUserConnectChoiceOnFirstConnection() throws Exception {
@@ -4235,7 +4236,8 @@
     }
 
     /**
-     * Verify that on the second successful connection to a network we set the user connect choice.
+     * Verify that on the second successful connection to a saved network we set the user connect
+     * choice.
      */
     @Test
     public void testConnectionSetUserConnectChoiceOnSecondConnection() throws Exception {
@@ -4248,6 +4250,20 @@
     }
 
     /**
+     * Verify that on the first successful connection to an ephemeral network we set the user
+     * connect choice.
+     */
+    @Test
+    public void testConnectionSetUserConnectChoiceOnEphemeralConfig() throws Exception {
+        when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(true);
+        mConnectedNetwork.ephemeral = true;
+        connect();
+        verify(mWifiBlocklistMonitor).handleBssidConnectionSuccess(TEST_BSSID_STR, TEST_SSID);
+        verify(mWifiConfigManager).updateNetworkAfterConnect(eq(FRAMEWORK_NETWORK_ID), eq(true),
+                anyInt());
+    }
+
+    /**
      * Verify that we enable the network when we detect validated internet access.
      */
     @Test
diff --git a/service/tests/wifitests/src/com/android/server/wifi/ConcreteClientModeManagerTest.java b/service/tests/wifitests/src/com/android/server/wifi/ConcreteClientModeManagerTest.java
index 819750f..810889b 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/ConcreteClientModeManagerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/ConcreteClientModeManagerTest.java
@@ -596,7 +596,6 @@
         reset(mContext);
         setUpSystemServiceForContext();
         when(mWifiGlobals.isConnectedMacRandomizationEnabled()).thenReturn(true);
-        when(mClientModeImpl.isConnecting()).thenReturn(true);
         mInterfaceCallbackCaptor.getValue().onDown(TEST_INTERFACE_NAME);
         mLooper.dispatchAll();
         verify(mSelfRecovery, never()).trigger(SelfRecovery.REASON_STA_IFACE_DOWN);
diff --git a/service/tests/wifitests/src/com/android/server/wifi/ConfigurationMapTest.java b/service/tests/wifitests/src/com/android/server/wifi/ConfigurationMapTest.java
index 6dd864c..dc8f7f6 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/ConfigurationMapTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/ConfigurationMapTest.java
@@ -21,24 +21,28 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
-import static org.mockito.Mockito.*;
+import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.lenient;
+import static org.mockito.Mockito.when;
 
 import android.content.pm.UserInfo;
 import android.net.wifi.ScanResult;
 import android.net.wifi.WifiConfiguration;
 import android.net.wifi.WifiManager;
 import android.os.UserHandle;
-import android.os.UserManager;
 import android.util.SparseArray;
 
 import androidx.test.filters.SmallTest;
 
+import com.android.server.wifi.util.WifiPermissionsUtil;
+
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 import org.mockito.MockitoSession;
+import org.mockito.stubbing.Answer;
 
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -83,7 +87,7 @@
         USER_PROFILES.put(11, Arrays.asList(new UserInfo(11, "Bob", 0)));
     }
 
-    @Mock UserManager mUserManager;
+    @Mock WifiPermissionsUtil mWifiPermissionsUtil;
     @Mock WifiInjector mWifiInjector;
     @Mock ActiveModeWarden mActiveModeWarden;
     @Mock ClientModeManager mPrimaryClientModeManager;
@@ -111,16 +115,26 @@
         when(mWifiGlobals.isWpa3SaeUpgradeEnabled()).thenReturn(true);
         when(mWifiGlobals.isOweUpgradeEnabled()).thenReturn(true);
 
-        // by default, return false
-        when(mUserManager.isSameProfileGroup(any(), any())).thenReturn(false);
-        // return true for these 2 userids
-        when(mUserManager.isSameProfileGroup(UserHandle.SYSTEM,
-                UserHandle.of(SYSTEM_MANAGE_PROFILE_USER_ID)))
-                .thenReturn(true);
-        when(mUserManager.isSameProfileGroup(UserHandle.of(SYSTEM_MANAGE_PROFILE_USER_ID),
-                UserHandle.SYSTEM))
-                .thenReturn(true);
-        mConfigs = new ConfigurationMap(mUserManager);
+        when(mWifiPermissionsUtil.doesUidBelongToCurrentUserOrDeviceOwner(anyInt()))
+                .thenAnswer((Answer<Boolean>) invocation -> {
+                    Object[] args = invocation.getArguments();
+                    int userId = UserHandle.getUserId((int) args[0]);
+                    // Current userId matches input userId
+                    if (userId == mCurrentUserId) {
+                        return true;
+                    }
+                    // Current userId and input userId belong to the same profile group
+                    if (userId == UserHandle.USER_SYSTEM
+                            && mCurrentUserId == SYSTEM_MANAGE_PROFILE_USER_ID) {
+                        return true;
+                    }
+                    if (userId == SYSTEM_MANAGE_PROFILE_USER_ID
+                            && mCurrentUserId == UserHandle.USER_SYSTEM) {
+                        return true;
+                    }
+                    return false;
+                });
+        mConfigs = new ConfigurationMap(mWifiPermissionsUtil);
     }
 
     @After
@@ -170,10 +184,8 @@
         // user. Also, check that *ForAllUsers() methods can be used to access all network
         // configurations, irrespective of their visibility to the current user.
         for (WifiConfiguration config : configs) {
-            final UserHandle currentUser = UserHandle.of(mCurrentUserId);
-            final UserHandle creatorUser = UserHandle.getUserHandleForUid(config.creatorUid);
-            if (config.shared || currentUser.equals(creatorUser)
-                    || mUserManager.isSameProfileGroup(currentUser, creatorUser)) {
+            if (config.shared || mWifiPermissionsUtil
+                    .doesUidBelongToCurrentUserOrDeviceOwner(config.creatorUid)) {
                 configsForCurrentUser.add(config);
                 if (config.status != WifiConfiguration.Status.DISABLED) {
                     enabledConfigsForCurrentUser.add(config);
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 ba02e13..c7127ce 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/HalDeviceManagerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/HalDeviceManagerTest.java
@@ -24,6 +24,7 @@
 import static com.android.server.wifi.HalDeviceManager.START_HAL_RETRY_TIMES;
 
 import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertNull;
 
 import static org.hamcrest.Matchers.is;
 import static org.hamcrest.core.IsEqual.equalTo;
@@ -86,6 +87,7 @@
 import org.mockito.ArgumentCaptor;
 import org.mockito.InOrder;
 import org.mockito.Mock;
+import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
 
 import java.io.PrintWriter;
@@ -962,11 +964,100 @@
     }
 
     /**
+     * Verify that when the thread that caused an iface to get destroyed is not the thread the
+     * onDestroy callback is intended to be invoked on, then onDestroy is will get posted to the
+     * correct thread.
+     */
+    @Test
+    public void testOnDestroyedWithHandlerTriggeredOnDifferentThread() throws Exception {
+        long currentThreadId = 983757; // arbitrary current thread ID
+        when(mWifiInjector.getCurrentThreadId()).thenReturn(currentThreadId);
+        // RETURNS_DEEP_STUBS allows mocking nested method calls
+        Handler staIfaceOnDestroyedHandler = mock(Handler.class, Mockito.RETURNS_DEEP_STUBS);
+        // Configure the handler to be on a different thread as the current thread.
+        when(staIfaceOnDestroyedHandler.getLooper().getThread().getId())
+                .thenReturn(currentThreadId + 1);
+        InterfaceDestroyedListener staIdl = mock(InterfaceDestroyedListener.class);
+        ArgumentCaptor<Runnable> lambdaCaptor = ArgumentCaptor.forClass(Runnable.class);
+
+        // simulate adding a STA iface and then stopping wifi
+        simulateStartAndStopWifi(staIdl, staIfaceOnDestroyedHandler);
+
+        // Verify a runnable is posted because current thread is different than the intended thread
+        // for running "onDestroyed"
+        verify(staIfaceOnDestroyedHandler).post(lambdaCaptor.capture());
+
+        // Verify onDestroyed is only run after the posted runnable is dispatched
+        verify(staIdl, never()).onDestroyed("wlan0");
+        lambdaCaptor.getValue().run();
+        verify(staIdl).onDestroyed("wlan0");
+    }
+
+    /**
+     * Verify that when the thread that caused an iface to get destroyed is already the thread the
+     * onDestroy callback is intended to be invoked on, then onDestroy is invoked directly.
+     */
+    @Test
+    public void testOnDestroyedWithHandlerTriggeredOnSameThread() throws Exception {
+        long currentThreadId = 983757; // arbitrary current thread ID
+        when(mWifiInjector.getCurrentThreadId()).thenReturn(currentThreadId);
+        // RETURNS_DEEP_STUBS allows mocking nested method calls
+        Handler staIfaceOnDestroyedHandler = mock(Handler.class, Mockito.RETURNS_DEEP_STUBS);
+        // Configure the handler thread ID so it's the same as the current thread.
+        when(staIfaceOnDestroyedHandler.getLooper().getThread().getId())
+                .thenReturn(currentThreadId);
+        InterfaceDestroyedListener staIdl = mock(InterfaceDestroyedListener.class);
+
+        // simulate adding a STA iface and then stopping wifi
+        simulateStartAndStopWifi(staIdl, staIfaceOnDestroyedHandler);
+
+        // Verify a runnable is never posted
+        verify(staIfaceOnDestroyedHandler, never()).post(any());
+        // Verify onDestroyed is triggered directly
+        verify(staIdl).onDestroyed("wlan0");
+    }
+
+    private void simulateStartAndStopWifi(InterfaceDestroyedListener staIdl,
+            Handler staIfaceOnDestroyedHandler) throws Exception {
+        TestChipV1 chipMock = new TestChipV1();
+        chipMock.initialize();
+
+        mInOrder = inOrder(mServiceManagerMock, mWifiMock, mWifiMockV15, chipMock.chip,
+                mManagerStatusListenerMock);
+        executeAndValidateInitializationSequence();
+
+        // start Wi-Fi
+        assertTrue(mDut.start());
+
+        // Create STA Iface.
+        IWifiStaIface staIface = mock(IWifiStaIface.class);
+        doAnswer(new GetNameAnswer("wlan0")).when(staIface).getName(
+                any(IWifiIface.getNameCallback.class));
+        doAnswer(new GetTypeAnswer(IfaceType.STA)).when(staIface).getType(
+                any(IWifiIface.getTypeCallback.class));
+        doAnswer(new CreateXxxIfaceAnswer(chipMock, mStatusOk, staIface)).when(
+                chipMock.chip).createStaIface(any(IWifiChip.createStaIfaceCallback.class));
+        assertEquals(staIface, mDut.createStaIface(staIdl, staIfaceOnDestroyedHandler,
+                TEST_WORKSOURCE_0));
+
+        mInOrder.verify(chipMock.chip).configureChip(TestChipV1.STA_CHIP_MODE_ID);
+
+        // Stop Wi-Fi
+        mDut.stop();
+        mInOrder.verify(mWifiMock).stop();
+    }
+
+    /**
      * Validate creation of AP interface when in STA mode with a single STA iface created.
      * Expect a change in chip mode.
      */
     @Test
-    public void testCreateApWithStIfaceUpTestChipV1UsingNoHandlerListeners() throws Exception {
+    public void testCreateApWithStIfaceUpTestChipV1UsingHandlerListeners() throws Exception {
+        // Make the creation and InterfaceDestroyListener running on the same thread to verify the
+        // order in the real scenario.
+        when(mWifiInjector.getCurrentThreadId())
+                .thenReturn(mTestLooper.getLooper().getThread().getId());
+
         TestChipV1 chipMock = new TestChipV1();
         chipMock.initialize();
 
@@ -992,7 +1083,7 @@
                 any(IWifiIface.getTypeCallback.class));
         doAnswer(new CreateXxxIfaceAnswer(chipMock, mStatusOk, staIface)).when(
                 chipMock.chip).createStaIface(any(IWifiChip.createStaIfaceCallback.class));
-        assertEquals(staIface, mDut.createStaIface(staIdl, null, TEST_WORKSOURCE_0));
+        assertEquals(staIface, mDut.createStaIface(staIdl, mHandler, TEST_WORKSOURCE_0));
 
         mInOrder.verify(chipMock.chip).configureChip(TestChipV1.STA_CHIP_MODE_ID);
 
@@ -1005,8 +1096,7 @@
         doAnswer(new CreateXxxIfaceAnswer(chipMock, mStatusOk, apIface)).when(
                 chipMock.chip).createApIface(
                 any(IWifiChip.createApIfaceCallback.class));
-        assertEquals(apIface, mDut.createApIface(apIdl, null, TEST_WORKSOURCE_0, false));
-
+        assertEquals(apIface, mDut.createApIface(apIdl, mHandler, TEST_WORKSOURCE_0, false));
         mInOrder.verify(chipMock.chip).removeStaIface(getName(staIface));
         mInOrder.verify(staIdl).onDestroyed(getName(staIface));
         mInOrder.verify(chipMock.chip).configureChip(TestChipV1.AP_CHIP_MODE_ID);
@@ -1022,6 +1112,78 @@
     }
 
     /**
+     * Validate creation of interface with valid listener but Null handler will be failed.
+     */
+    @Test
+    public void testCreateIfaceTestChipV1UsingNullHandlerListeners() throws Exception {
+        TestChipV1 chipMock = new TestChipV1();
+        chipMock.initialize();
+
+        InterfaceDestroyedListener idl = mock(
+                InterfaceDestroyedListener.class);
+
+        mInOrder = inOrder(mServiceManagerMock, mWifiMock, mWifiMockV15, chipMock.chip,
+                mManagerStatusListenerMock, idl);
+        executeAndValidateInitializationSequence();
+
+        // Register listener & start Wi-Fi
+        mDut.registerStatusListener(mManagerStatusListenerMock, null);
+        assertTrue(mDut.start());
+        mInOrder.verify(mManagerStatusListenerMock).onStatusChanged();
+
+        // Create STA Iface will be failure because null handler.
+        IWifiStaIface staIface = mock(IWifiStaIface.class);
+        doAnswer(new GetNameAnswer("wlan0")).when(staIface).getName(
+                any(IWifiIface.getNameCallback.class));
+        doAnswer(new GetTypeAnswer(IfaceType.STA)).when(staIface).getType(
+                any(IWifiIface.getTypeCallback.class));
+        doAnswer(new CreateXxxIfaceAnswer(chipMock, mStatusOk, staIface)).when(
+                chipMock.chip).createStaIface(any(IWifiChip.createStaIfaceCallback.class));
+        assertNull(mDut.createStaIface(idl, null, TEST_WORKSOURCE_0));
+
+        // Create AP Iface will be failure because null handler.
+        IWifiApIface apIface = mock(IWifiApIface.class);
+        doAnswer(new GetNameAnswer("wlan0")).when(apIface).getName(
+                any(IWifiIface.getNameCallback.class));
+        doAnswer(new GetTypeAnswer(IfaceType.AP)).when(apIface).getType(
+                any(IWifiIface.getTypeCallback.class));
+        doAnswer(new CreateXxxIfaceAnswer(chipMock, mStatusOk, apIface)).when(
+                chipMock.chip).createApIface(
+                any(IWifiChip.createApIfaceCallback.class));
+        assertNull(mDut.createApIface(idl, null, TEST_WORKSOURCE_0, false));
+
+        // Create NAN Iface will be failure because null handler.
+        IWifiNanIface nanIface = mock(IWifiNanIface.class);
+        doAnswer(new GetNameAnswer("wlan0")).when(nanIface).getName(
+                any(IWifiIface.getNameCallback.class));
+        doAnswer(new GetTypeAnswer(IfaceType.NAN)).when(nanIface).getType(
+                any(IWifiIface.getTypeCallback.class));
+        doAnswer(new CreateXxxIfaceAnswer(chipMock, mStatusOk, nanIface)).when(
+                chipMock.chip).createNanIface(
+                any(IWifiChip.createNanIfaceCallback.class));
+        assertNull(mDut.createNanIface(idl, null, TEST_WORKSOURCE_0));
+
+        // Create P2P Iface will be failure because null handler.
+        IWifiP2pIface p2pIface = mock(IWifiP2pIface.class);
+        doAnswer(new GetNameAnswer("wlan0")).when(p2pIface).getName(
+                any(IWifiIface.getNameCallback.class));
+        doAnswer(new GetTypeAnswer(IfaceType.P2P)).when(p2pIface).getType(
+                any(IWifiIface.getTypeCallback.class));
+        doAnswer(new CreateXxxIfaceAnswer(chipMock, mStatusOk, p2pIface)).when(
+                chipMock.chip).createP2pIface(
+                any(IWifiChip.createP2pIfaceCallback.class));
+        assertNull(mDut.createP2pIface(idl, null, TEST_WORKSOURCE_0));
+
+        // Stop Wi-Fi
+        mDut.stop();
+
+        mInOrder.verify(mWifiMock).stop();
+        mInOrder.verify(mManagerStatusListenerMock).onStatusChanged();
+
+        verifyNoMoreInteractions(mManagerStatusListenerMock, idl);
+    }
+
+    /**
      * Validate creation of AP interface when in AP mode - but with no interface created. Expect
      * no change in chip mode.
      */
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 2411834..75f2144 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java
@@ -284,7 +284,8 @@
         when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(true);
         mockIsDeviceOwner(false);
         when(mWifiPermissionsUtil.isProfileOwner(anyInt(), any())).thenReturn(false);
-        when(mWifiPermissionsUtil.doesUidBelongToCurrentUser(anyInt())).thenReturn(true);
+        when(mWifiPermissionsUtil.doesUidBelongToCurrentUserOrDeviceOwner(anyInt()))
+                .thenReturn(true);
         when(mWifiLastResortWatchdog.shouldIgnoreSsidUpdate()).thenReturn(false);
         when(mMacAddressUtil.calculatePersistentMac(any(), any())).thenReturn(TEST_RANDOMIZED_MAC);
         when(mWifiScoreCard.lookupNetwork(any())).thenReturn(mPerNetwork);
@@ -3195,8 +3196,8 @@
         setupStoreDataForUserRead(user2Networks, new HashMap<>());
         // Now switch the user to user 2 and ensure that user 1's private network has been removed.
         when(mUserManager.isUserUnlockingOrUnlocked(UserHandle.of(user2))).thenReturn(true);
-        when(mWifiPermissionsUtil.doesUidBelongToCurrentUser(user1Network.creatorUid))
-                .thenReturn(false);
+        when(mWifiPermissionsUtil.doesUidBelongToUser(user1Network.creatorUid, user1))
+                .thenReturn(true);
         Set<Integer> removedNetworks = mWifiConfigManager.handleUserSwitch(user2);
         verify(mWifiConfigStore).switchUserStoresAndRead(any(List.class));
         assertTrue((removedNetworks.size() == 1) && (removedNetworks.contains(user1NetworkId)));
@@ -3375,8 +3376,10 @@
             }
         };
         setupStoreDataForUserRead(userNetworks, new HashMap<>());
-        when(mWifiPermissionsUtil.doesUidBelongToCurrentUser(user2Network.creatorUid))
-                .thenReturn(false);
+        when(mWifiPermissionsUtil.doesUidBelongToUser(user1Network.creatorUid, user1))
+                .thenReturn(true);
+        when(mWifiPermissionsUtil.doesUidBelongToUser(user2Network.creatorUid, user2))
+                .thenReturn(true);
         mWifiConfigManager.handleUserUnlock(user1);
         verify(mWifiConfigStore).switchUserStoresAndRead(any(List.class));
         // Capture the written data for the user 1 and ensure that it corresponds to what was
@@ -3391,10 +3394,6 @@
         // Now switch the user to user2 and ensure that user 2's private network has been moved to
         // the user store.
         when(mUserManager.isUserUnlockingOrUnlocked(UserHandle.of(user2))).thenReturn(true);
-        when(mWifiPermissionsUtil.doesUidBelongToCurrentUser(user1Network.creatorUid))
-                .thenReturn(true).thenReturn(false);
-        when(mWifiPermissionsUtil.doesUidBelongToCurrentUser(user2Network.creatorUid))
-                .thenReturn(false).thenReturn(true);
         mWifiConfigManager.handleUserSwitch(user2);
         // Set the expected network list before comparing. user1Network should be in shared data.
         // Note: In the real world, user1Network will no longer be visible now because it should
@@ -3459,8 +3458,8 @@
         // Unlock the owner of the legacy Passpoint configuration, verify it is removed from
         // the configured networks (migrated to PasspointManager).
         setupStoreDataForUserRead(new ArrayList<WifiConfiguration>(), new HashMap<>());
-        when(mWifiPermissionsUtil.doesUidBelongToCurrentUser(passpointConfig.creatorUid))
-                .thenReturn(false);
+        when(mWifiPermissionsUtil.doesUidBelongToUser(passpointConfig.creatorUid, user1))
+                .thenReturn(true);
         mWifiConfigManager.handleUserUnlock(user1);
         verify(mWifiConfigStore).switchUserStoresAndRead(any(List.class));
         Pair<List<WifiConfiguration>, List<WifiConfiguration>> writtenNetworkList =
@@ -3590,8 +3589,8 @@
 
         // Ensure that we have 2 networks in the database before the stop.
         assertEquals(2, mWifiConfigManager.getConfiguredNetworks().size());
-        when(mWifiPermissionsUtil.doesUidBelongToCurrentUser(user1Network.creatorUid))
-                .thenReturn(false);
+        when(mWifiPermissionsUtil.doesUidBelongToUser(user1Network.creatorUid, user1))
+                .thenReturn(true);
         mWifiConfigManager.handleUserStop(user1);
 
         // Ensure that we only have 1 shared network in the database after the stop.
@@ -3810,7 +3809,8 @@
         int creatorUid = UserHandle.getUid(user2, 674);
 
         when(mWifiPermissionsUtil.checkNetworkSettingsPermission(creatorUid)).thenReturn(false);
-        when(mWifiPermissionsUtil.doesUidBelongToCurrentUser(creatorUid)).thenReturn(false);
+        when(mWifiPermissionsUtil.doesUidBelongToCurrentUserOrDeviceOwner(creatorUid))
+                .thenReturn(false);
 
         // Create a network for user2 try adding it. This should be rejected.
         final WifiConfiguration user2Network = WifiConfigurationTestUtil.createPskNetwork();
@@ -6289,7 +6289,7 @@
 
         when(mWifiPermissionsUtil.checkNetworkSettingsPermission(TEST_OTHER_USER_UID))
                 .thenReturn(false);
-        when(mWifiPermissionsUtil.doesUidBelongToCurrentUser(TEST_OTHER_USER_UID))
+        when(mWifiPermissionsUtil.doesUidBelongToCurrentUserOrDeviceOwner(TEST_OTHER_USER_UID))
                 .thenReturn(false);
 
         NetworkUpdateResult result =
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiConnectivityManagerTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiConnectivityManagerTest.java
index d2acbae..0606093 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiConnectivityManagerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiConnectivityManagerTest.java
@@ -41,6 +41,7 @@
 import static org.mockito.Mockito.argThat;
 import static org.mockito.Mockito.atLeast;
 import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.clearInvocations;
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.eq;
@@ -867,31 +868,6 @@
     }
 
     @Test
-    public void secondaryLongLived_noSecondaryStaAvailable() {
-        setupMocksForSecondaryLongLivedTests();
-
-        // Set screen to on
-        setScreenState(true);
-
-        // OEM paid connection allowed.
-        mWifiConnectivityManager.setOemPaidConnectionAllowed(true, new WorkSource());
-
-        // STA + STA is supported, but not available.
-        when(mActiveModeWarden.canRequestMoreClientModeManagersInRole(
-                any(), eq(ROLE_CLIENT_SECONDARY_LONG_LIVED))).thenReturn(false);
-
-        // Set WiFi to disconnected state
-        mWifiConnectivityManager.handleConnectionStateChanged(
-                mPrimaryClientModeManager,
-                WifiConnectivityManager.WIFI_STATE_DISCONNECTED);
-
-        verify(mPrimaryClientModeManager).startConnectToNetwork(
-                CANDIDATE_NETWORK_ID, Process.WIFI_UID, "any");
-        verify(mActiveModeWarden, never()).requestSecondaryLongLivedClientModeManager(
-                any(), any(), any(), any());
-    }
-
-    @Test
     public void secondaryLongLived_secondaryStaRequestReturnsNull() {
         setupMocksForSecondaryLongLivedTests();
 
@@ -932,7 +908,7 @@
         // OEM paid connection allowed.
         mWifiConnectivityManager.setOemPaidConnectionAllowed(true, new WorkSource());
 
-        // STA + STA is supported, but secondary STA request returns null
+        // STA + STA is supported, but secondary STA request returns the primary
         doAnswer(new AnswerWithArguments() {
             public void answer(ExternalClientModeManagerRequestListener listener,
                     WorkSource requestorWs, String ssid, String bssid) {
@@ -981,6 +957,19 @@
                 CANDIDATE_NETWORK_ID, Process.WIFI_UID, "any");
         verify(mActiveModeWarden).requestSecondaryLongLivedClientModeManager(
                 any(), any(), any(), any());
+
+        // Simulate connection failing on the secondary
+        clearInvocations(mSecondaryClientModeManager, mPrimaryClientModeManager, mWifiNS);
+        mWifiConnectivityManager.handleConnectionAttemptEnded(
+                mSecondaryClientModeManager,
+                WifiMetrics.ConnectionEvent.FAILURE_ASSOCIATION_REJECTION, CANDIDATE_BSSID,
+                CANDIDATE_SSID);
+        // verify connection is never restarted when a connection on the secondary STA fails.
+        verify(mWifiNS, never()).selectNetwork(any());
+        verify(mSecondaryClientModeManager, never()).startConnectToNetwork(
+                anyInt(), anyInt(), any());
+        verify(mPrimaryClientModeManager, never()).startConnectToNetwork(
+                anyInt(), anyInt(), any());
     }
 
     @Test
@@ -1055,6 +1044,55 @@
     }
 
     /**
+     * Verify that when the secondary is already connecting to the selected secondary network,
+     * we only connect the primary STA.
+     */
+    @Test
+    public void secondaryLongLived_secondaryStaRequestSucceedsWhenSecondaryAlreadyConnecting() {
+        setupMocksForSecondaryLongLivedTests();
+
+        // 2 candidates - 1 oem paid, other regular.
+        // Mark the first candidate oem private only
+        when(mCandidate1.isOemPaid()).thenReturn(false);
+        when(mCandidate1.isOemPrivate()).thenReturn(true);
+        mCandidateWifiConfig1.oemPaid = false;
+        mCandidateWifiConfig1.oemPrivate = true;
+
+        // mock secondary STA to already connecting to the target OEM private network
+        when(mSecondaryClientModeManager.getConnectingWifiConfiguration()).thenReturn(
+                mCandidateWifiConfig1);
+
+        // Add the second regular candidate.
+        mCandidateList.add(mCandidate2);
+
+        // Set screen to on
+        setScreenState(true);
+
+        // OEM paid connection allowed.
+        mWifiConnectivityManager.setOemPrivateConnectionAllowed(true, new WorkSource());
+
+        // Network selection setup for primary.
+        when(mWifiNS.selectNetwork(argThat(
+                candidates -> (candidates != null && candidates.size() == 1
+                        // not oem paid or oem private.
+                        && !(candidates.get(0).isOemPaid() || candidates.get(0).isOemPrivate()))
+        ))).thenReturn(mCandidateWifiConfig2);
+
+        // Set WiFi to disconnected state
+        mWifiConnectivityManager.handleConnectionStateChanged(
+                mPrimaryClientModeManager,
+                WifiConnectivityManager.WIFI_STATE_DISCONNECTED);
+
+        // connection triggered on only on primary to CANDIDATE_NETWORK_ID_2.
+        verify(mPrimaryClientModeManager).startConnectToNetwork(
+                CANDIDATE_NETWORK_ID_2, Process.WIFI_UID, "any");
+        verify(mSecondaryClientModeManager, never()).startConnectToNetwork(
+                CANDIDATE_NETWORK_ID, Process.WIFI_UID, "any");
+        verify(mActiveModeWarden).requestSecondaryLongLivedClientModeManager(
+                any(), any(), eq(CANDIDATE_SSID), any());
+    }
+
+    /**
      *  Wifi enters disconnected state while screen is on.
      *
      * Expected behavior: WifiConnectivityManager calls
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 13c8077..000c100 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiNetworkSuggestionsManagerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiNetworkSuggestionsManagerTest.java
@@ -242,7 +242,8 @@
         when(mActivityManager.isLowRamDevice()).thenReturn(false);
         when(mActivityManager.getPackageImportance(any())).thenReturn(
                 IMPORTANCE_FOREGROUND_SERVICE);
-        when(mWifiPermissionsUtil.doesUidBelongToCurrentUser(anyInt())).thenReturn(true);
+        when(mWifiPermissionsUtil.doesUidBelongToCurrentUserOrDeviceOwner(anyInt()))
+                .thenReturn(true);
         when(mActiveModeWarden.getPrimaryClientModeManager()).thenReturn(mPrimaryClientModeManager);
         when(mPrimaryClientModeManager.getSupportedFeatures()).thenReturn(
                 WifiManager.WIFI_FEATURE_WPA3_SAE | WifiManager.WIFI_FEATURE_OWE);
@@ -1469,7 +1470,8 @@
                         TEST_PACKAGE_1));
         verify(mWifiConfigManager).removeSuggestionConfiguredNetwork(
                 argThat(new WifiConfigMatcher(networkSuggestion.wifiConfiguration)));
-        mInorder.verify(mWifiPermissionsUtil).doesUidBelongToCurrentUser(eq(TEST_UID_1));
+        mInorder.verify(mWifiPermissionsUtil)
+                .doesUidBelongToCurrentUserOrDeviceOwner(eq(TEST_UID_1));
 
         // Verify no more broadcast were sent out.
         mInorder.verifyNoMoreInteractions();
@@ -4686,7 +4688,8 @@
                 mWifiNetworkSuggestionsManager.add(Arrays.asList(networkSuggestion), TEST_UID_1,
                         TEST_PACKAGE_1, TEST_FEATURE));
         // When switch the user to background
-        when(mWifiPermissionsUtil.doesUidBelongToCurrentUser(TEST_UID_1)).thenReturn(false);
+        when(mWifiPermissionsUtil.doesUidBelongToCurrentUserOrDeviceOwner(TEST_UID_1))
+                .thenReturn(false);
         assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_ERROR_INTERNAL,
                 mWifiNetworkSuggestionsManager.add(Arrays.asList(networkSuggestion), TEST_UID_1,
                         TEST_PACKAGE_1, TEST_FEATURE));
@@ -4698,7 +4701,8 @@
                 mConnectionStatusListener, TEST_PACKAGE_1, TEST_UID_1));
 
         // When switch the user back to foreground
-        when(mWifiPermissionsUtil.doesUidBelongToCurrentUser(TEST_UID_1)).thenReturn(true);
+        when(mWifiPermissionsUtil.doesUidBelongToCurrentUserOrDeviceOwner(TEST_UID_1))
+                .thenReturn(true);
         assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS,
                 mWifiNetworkSuggestionsManager.add(Arrays.asList(networkSuggestion), TEST_UID_1,
                         TEST_PACKAGE_1, TEST_FEATURE));
@@ -4722,7 +4726,7 @@
         assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS,
                 mWifiNetworkSuggestionsManager.add(Arrays.asList(networkSuggestion), TEST_UID_1,
                         TEST_PACKAGE_1, TEST_FEATURE));
-        mInorder.verify(mWifiPermissionsUtil).doesUidBelongToCurrentUser(anyInt());
+        mInorder.verify(mWifiPermissionsUtil).doesUidBelongToCurrentUserOrDeviceOwner(anyInt());
         assertTrue(mWifiNetworkSuggestionsManager.hasUserApprovedForApp(TEST_PACKAGE_1));
 
         // Simulate connecting to the network.
@@ -4748,7 +4752,7 @@
                         TEST_PACKAGE_1));
         verify(mWifiConfigManager).removeSuggestionConfiguredNetwork(
                 argThat(new WifiConfigMatcher(connectNetwork)));
-        mInorder.verify(mWifiPermissionsUtil).doesUidBelongToCurrentUser(anyInt());
+        mInorder.verify(mWifiPermissionsUtil).doesUidBelongToCurrentUserOrDeviceOwner(anyInt());
 
         // 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 f8f7e65..6f0abe4 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java
@@ -500,7 +500,8 @@
         when(mActiveModeWarden.getClientModeManagersInRoles(
                 ROLE_CLIENT_LOCAL_ONLY, ROLE_CLIENT_SECONDARY_LONG_LIVED))
                 .thenReturn(Collections.emptyList());
-        when(mWifiPermissionsUtil.doesUidBelongToCurrentUser(anyInt())).thenReturn(true);
+        when(mWifiPermissionsUtil.doesUidBelongToCurrentUserOrDeviceOwner(anyInt()))
+                .thenReturn(true);
         when(mWifiInjector.getWifiCarrierInfoManager()).thenReturn(mWifiCarrierInfoManager);
         when(mWifiInjector.getOpenNetworkNotifier()).thenReturn(mOpenNetworkNotifier);
         when(mClientSoftApCallback.asBinder()).thenReturn(mAppBinder);
@@ -4980,7 +4981,9 @@
         mWifiServiceImpl.handleBootCompleted();
         mLooper.stopAutoDispatch();
         verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
-                (IntentFilter) argThat(new IdleModeIntentMatcher()));
+                (IntentFilter) argThat(new IdleModeIntentMatcher()),
+                isNull(),
+                any(Handler.class));
 
         // Tell the wifi service that the device became idle.
         when(mPowerManager.isDeviceIdleMode()).thenReturn(true);
@@ -5072,7 +5075,9 @@
                 argThat((IntentFilter filter) ->
                         filter.hasAction(Intent.ACTION_PACKAGE_FULLY_REMOVED)
                                 && filter.hasAction(Intent.ACTION_PACKAGE_REMOVED)
-                                && filter.hasAction(Intent.ACTION_PACKAGE_CHANGED)));
+                                && filter.hasAction(Intent.ACTION_PACKAGE_CHANGED)),
+                isNull(),
+                any(Handler.class));
         int uid = TEST_UID;
         String packageName = TEST_PACKAGE_NAME;
         doThrow(new PackageManager.NameNotFoundException()).when(mPackageManager)
@@ -5104,7 +5109,9 @@
                 argThat((IntentFilter filter) ->
                         filter.hasAction(Intent.ACTION_PACKAGE_FULLY_REMOVED)
                                 && filter.hasAction(Intent.ACTION_PACKAGE_REMOVED)
-                                && filter.hasAction(Intent.ACTION_PACKAGE_CHANGED)));
+                                && filter.hasAction(Intent.ACTION_PACKAGE_CHANGED)),
+                isNull(),
+                any(Handler.class));
         int uid = TEST_UID;
         String packageName = TEST_PACKAGE_NAME;
         // Send the broadcast
@@ -5134,7 +5141,9 @@
                 argThat((IntentFilter filter) ->
                         filter.hasAction(Intent.ACTION_PACKAGE_FULLY_REMOVED)
                                 && filter.hasAction(Intent.ACTION_PACKAGE_REMOVED)
-                                && filter.hasAction(Intent.ACTION_PACKAGE_CHANGED)));
+                                && filter.hasAction(Intent.ACTION_PACKAGE_CHANGED)),
+                isNull(),
+                any(Handler.class));
         int uid = TEST_UID;
         String packageName = TEST_PACKAGE_NAME;
         mPackageInfo.applicationInfo = mApplicationInfo;
@@ -5164,7 +5173,9 @@
         mLooper.dispatchAll();
         verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
                 argThat((IntentFilter filter) ->
-                        filter.hasAction(Intent.ACTION_PACKAGE_FULLY_REMOVED)));
+                        filter.hasAction(Intent.ACTION_PACKAGE_FULLY_REMOVED)),
+                isNull(),
+                any(Handler.class));
 
         String packageName = TEST_PACKAGE_NAME;
         // Send the broadcast
@@ -5187,7 +5198,9 @@
         mLooper.dispatchAll();
         verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
                 argThat((IntentFilter filter) ->
-                        filter.hasAction(Intent.ACTION_PACKAGE_FULLY_REMOVED)));
+                        filter.hasAction(Intent.ACTION_PACKAGE_FULLY_REMOVED)),
+                isNull(),
+                any(Handler.class));
 
         int uid = TEST_UID;
         // Send the broadcast
@@ -5214,7 +5227,9 @@
         mLooper.stopAutoDispatch();
         verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
                 argThat((IntentFilter filter) ->
-                        filter.hasAction(Intent.ACTION_USER_REMOVED)));
+                        filter.hasAction(Intent.ACTION_USER_REMOVED)),
+                isNull(),
+                any(Handler.class));
 
         UserHandle userHandle = UserHandle.of(TEST_USER_HANDLE);
         // Send the broadcast
@@ -5237,7 +5252,9 @@
         verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
                 argThat((IntentFilter filter) ->
                         filter.hasAction(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED)
-                                && filter.hasAction(BluetoothAdapter.ACTION_STATE_CHANGED)));
+                                && filter.hasAction(BluetoothAdapter.ACTION_STATE_CHANGED)),
+                isNull(),
+                any(Handler.class));
 
         {
             Intent intent = new Intent(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED);
@@ -5300,7 +5317,9 @@
         mLooper.stopAutoDispatch();
         verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
                 argThat((IntentFilter filter) ->
-                        filter.hasAction(Intent.ACTION_USER_REMOVED)));
+                        filter.hasAction(Intent.ACTION_USER_REMOVED)),
+                isNull(),
+                any(Handler.class));
 
         UserHandle userHandle = UserHandle.of(TEST_USER_HANDLE);
         // Send the broadcast with wrong action
@@ -5359,7 +5378,9 @@
         mLooper.dispatchAll();
         verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
                 (IntentFilter) argThat((IntentFilter filter) ->
-                        filter.hasAction(TelephonyManager.ACTION_SIM_CARD_STATE_CHANGED)));
+                        filter.hasAction(TelephonyManager.ACTION_SIM_CARD_STATE_CHANGED)),
+                isNull(),
+                any(Handler.class));
 
         int userHandle = TEST_USER_HANDLE;
         // Send the broadcast
@@ -5378,7 +5399,9 @@
         mLooper.dispatchAll();
         verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
                 (IntentFilter) argThat((IntentFilter filter) ->
-                        filter.hasAction(TelephonyManager.ACTION_SIM_CARD_STATE_CHANGED)));
+                        filter.hasAction(TelephonyManager.ACTION_SIM_CARD_STATE_CHANGED)),
+                isNull(),
+                any(Handler.class));
 
         int userHandle = TEST_USER_HANDLE;
         // Send the broadcast
@@ -5399,7 +5422,9 @@
         mLooper.dispatchAll();
         verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
                 argThat((IntentFilter filter) ->
-                        filter.hasAction(TelephonyManager.ACTION_SIM_CARD_STATE_CHANGED)));
+                        filter.hasAction(TelephonyManager.ACTION_SIM_CARD_STATE_CHANGED)),
+                isNull(),
+                any(Handler.class));
 
         Intent intent = new Intent(TelephonyManager.ACTION_SIM_CARD_STATE_CHANGED);
         intent.putExtra(TelephonyManager.EXTRA_SIM_STATE, TelephonyManager.SIM_STATE_ABSENT);
@@ -5425,7 +5450,9 @@
         mLooper.dispatchAll();
         verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
                 argThat((IntentFilter filter) ->
-                        filter.hasAction(TelephonyManager.ACTION_SIM_APPLICATION_STATE_CHANGED)));
+                        filter.hasAction(TelephonyManager.ACTION_SIM_APPLICATION_STATE_CHANGED)),
+                isNull(),
+                any(Handler.class));
 
         Intent intent = new Intent(TelephonyManager.ACTION_SIM_APPLICATION_STATE_CHANGED);
         intent.putExtra(TelephonyManager.EXTRA_SIM_STATE, TelephonyManager.SIM_STATE_LOADED);
@@ -5450,7 +5477,9 @@
         verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
                 argThat((IntentFilter filter) ->
                         filter.hasAction(
-                                TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED)));
+                                TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED)),
+                isNull(),
+                any(Handler.class));
 
         Intent intent = new Intent(TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED);
         intent.putExtra("subscription", 1);
@@ -7084,7 +7113,9 @@
         mLooper.dispatchAll();
         verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
                 argThat((IntentFilter filter) ->
-                        filter.hasAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED)));
+                        filter.hasAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED)),
+                isNull(),
+                any(Handler.class));
 
         // Send the broadcast
         Intent intent = new Intent(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
@@ -7105,7 +7136,9 @@
         mLooper.dispatchAll();
         verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
                 argThat((IntentFilter filter) ->
-                        filter.hasAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED)));
+                        filter.hasAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED)),
+                isNull(),
+                any(Handler.class));
         ArgumentCaptor<PhoneStateListener> phoneStateListenerCaptor =
                 ArgumentCaptor.forClass(PhoneStateListener.class);
         verify(mTelephonyManager).listen(phoneStateListenerCaptor.capture(),
@@ -7600,7 +7633,9 @@
         mLooper.dispatchAll();
         verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
                 argThat((IntentFilter filter) ->
-                        filter.hasAction(TelephonyManager.ACTION_NETWORK_COUNTRY_CHANGED)));
+                        filter.hasAction(TelephonyManager.ACTION_NETWORK_COUNTRY_CHANGED)),
+                isNull(),
+                any(Handler.class));
         sendCountryCodeChangedBroadcast("US");
         verify(mWifiCountryCode).setTelephonyCountryCodeAndUpdate(any());
     }
@@ -7629,7 +7664,8 @@
      */
     @Test(expected = SecurityException.class)
     public void testAddSuggestionUserApprovalStatusListenerFromBackgroundUser() {
-        when(mWifiPermissionsUtil.doesUidBelongToCurrentUser(anyInt())).thenReturn(false);
+        when(mWifiPermissionsUtil.doesUidBelongToCurrentUserOrDeviceOwner(anyInt()))
+                .thenReturn(false);
         mWifiServiceImpl.addSuggestionUserApprovalStatusListener(
                 mSuggestionUserApprovalStatusListener, TEST_PACKAGE_NAME);
     }
@@ -7639,7 +7675,8 @@
      */
     @Test(expected = SecurityException.class)
     public void testRemoveSuggestionUserApprovalStatusListenerFromBackgroundUser() {
-        when(mWifiPermissionsUtil.doesUidBelongToCurrentUser(anyInt())).thenReturn(false);
+        when(mWifiPermissionsUtil.doesUidBelongToCurrentUserOrDeviceOwner(anyInt()))
+                .thenReturn(false);
         mWifiServiceImpl.removeSuggestionUserApprovalStatusListener(
                 mSuggestionUserApprovalStatusListener, TEST_PACKAGE_NAME);
     }
@@ -7780,7 +7817,9 @@
         mLooper.dispatchAll();
         verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
                 argThat((IntentFilter filter) ->
-                        filter.hasAction(Intent.ACTION_LOCALE_CHANGED)));
+                        filter.hasAction(Intent.ACTION_LOCALE_CHANGED)),
+                isNull(),
+                any(Handler.class));
         verify(mWifiNotificationManager).createNotificationChannels();
         clearInvocations(mWifiNotificationManager);
 
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiVendorHalTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiVendorHalTest.java
index 6aa3c8c..a32f3d3 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiVendorHalTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiVendorHalTest.java
@@ -382,9 +382,9 @@
                 mLooper.dispatchAll();
             }
         }).when(mHalDeviceManager).stop();
-        when(mHalDeviceManager.createStaIface(any(), eq(null), any()))
+        when(mHalDeviceManager.createStaIface(any(), any(), any()))
                 .thenReturn(mIWifiStaIface);
-        when(mHalDeviceManager.createApIface(anyLong(), any(), eq(null), any(), anyBoolean()))
+        when(mHalDeviceManager.createApIface(anyLong(), any(), any(), any(), anyBoolean()))
                 .thenReturn(mIWifiApIface);
         when(mHalDeviceManager.removeIface(any())).thenReturn(true);
         when(mHalDeviceManager.getChip(any(IWifiIface.class)))
@@ -462,7 +462,7 @@
         assertTrue(mWifiVendorHal.isHalStarted());
 
         verify(mHalDeviceManager).start();
-        verify(mHalDeviceManager).createStaIface(any(), eq(null), any());
+        verify(mHalDeviceManager).createStaIface(any(), any(), any());
         verify(mHalDeviceManager).getChip(eq(mIWifiStaIface));
         verify(mHalDeviceManager).isReady();
         verify(mHalDeviceManager).isStarted();
@@ -470,7 +470,7 @@
         verify(mIWifiChip).registerEventCallback(any(IWifiChipEventCallback.class));
 
         verify(mHalDeviceManager, never()).createApIface(
-                anyLong(), any(), eq(null), any(), anyBoolean());
+                anyLong(), any(), any(), any(), anyBoolean());
     }
 
     /**
@@ -484,12 +484,12 @@
 
         verify(mHalDeviceManager).start();
         verify(mHalDeviceManager).createApIface(
-                anyLong(), any(), eq(null), any(), anyBoolean());
+                anyLong(), any(), any(), any(), anyBoolean());
         verify(mHalDeviceManager).getChip(eq(mIWifiApIface));
         verify(mHalDeviceManager).isReady();
         verify(mHalDeviceManager).isStarted();
 
-        verify(mHalDeviceManager, never()).createStaIface(any(), eq(null), any());
+        verify(mHalDeviceManager, never()).createStaIface(any(), any(), any());
     }
 
     /**
@@ -510,9 +510,9 @@
 
         verify(mHalDeviceManager).start();
 
-        verify(mHalDeviceManager, never()).createStaIface(any(), eq(null), any());
+        verify(mHalDeviceManager, never()).createStaIface(any(), any(), any());
         verify(mHalDeviceManager, never()).createApIface(
-                anyLong(), any(), eq(null), any(), anyBoolean());
+                anyLong(), any(), any(), any(), anyBoolean());
         verify(mHalDeviceManager, never()).getChip(any(IWifiIface.class));
         verify(mIWifiStaIface, never())
                 .registerEventCallback(any(IWifiStaIfaceEventCallback.class));
@@ -524,16 +524,16 @@
      */
     @Test
     public void testStartHalFailureInIfaceCreationInStaMode() throws Exception {
-        when(mHalDeviceManager.createStaIface(any(), eq(null), any())).thenReturn(null);
+        when(mHalDeviceManager.createStaIface(any(), any(), any())).thenReturn(null);
         assertFalse(mWifiVendorHal.startVendorHalSta());
         assertFalse(mWifiVendorHal.isHalStarted());
 
         verify(mHalDeviceManager).start();
-        verify(mHalDeviceManager).createStaIface(any(), eq(null), any());
+        verify(mHalDeviceManager).createStaIface(any(), any(), any());
         verify(mHalDeviceManager).stop();
 
         verify(mHalDeviceManager, never()).createApIface(
-                anyLong(), any(), eq(null), any(), anyBoolean());
+                anyLong(), any(), any(), any(), anyBoolean());
         verify(mHalDeviceManager, never()).getChip(any(IWifiIface.class));
         verify(mIWifiStaIface, never())
                 .registerEventCallback(any(IWifiStaIfaceEventCallback.class));
@@ -550,13 +550,13 @@
         assertFalse(mWifiVendorHal.isHalStarted());
 
         verify(mHalDeviceManager).start();
-        verify(mHalDeviceManager).createStaIface(any(), eq(null), any());
+        verify(mHalDeviceManager).createStaIface(any(), any(), any());
         verify(mHalDeviceManager).getChip(any(IWifiIface.class));
         verify(mHalDeviceManager).stop();
         verify(mIWifiStaIface).registerEventCallback(any(IWifiStaIfaceEventCallback.class));
 
         verify(mHalDeviceManager, never()).createApIface(
-                anyLong(), any(), eq(null), any(), anyBoolean());
+                anyLong(), any(), any(), any(), anyBoolean());
     }
 
     /**
@@ -571,13 +571,13 @@
         assertFalse(mWifiVendorHal.isHalStarted());
 
         verify(mHalDeviceManager).start();
-        verify(mHalDeviceManager).createStaIface(any(), eq(null), any());
+        verify(mHalDeviceManager).createStaIface(any(), any(), any());
         verify(mHalDeviceManager).stop();
         verify(mIWifiStaIface).registerEventCallback(any(IWifiStaIfaceEventCallback.class));
 
         verify(mHalDeviceManager, never()).getChip(any(IWifiIface.class));
         verify(mHalDeviceManager, never()).createApIface(
-                anyLong(), any(), eq(null), any(), anyBoolean());
+                anyLong(), any(), any(), any(), anyBoolean());
     }
 
     /**
@@ -592,14 +592,14 @@
         assertFalse(mWifiVendorHal.isHalStarted());
 
         verify(mHalDeviceManager).start();
-        verify(mHalDeviceManager).createStaIface(any(), eq(null), any());
+        verify(mHalDeviceManager).createStaIface(any(), any(), any());
         verify(mHalDeviceManager).getChip(any(IWifiIface.class));
         verify(mHalDeviceManager).stop();
         verify(mIWifiStaIface).registerEventCallback(any(IWifiStaIfaceEventCallback.class));
         verify(mIWifiChip).registerEventCallback(any(IWifiChipEventCallback.class));
 
         verify(mHalDeviceManager, never()).createApIface(
-                anyLong(), any(), eq(null), any(), anyBoolean());
+                anyLong(), any(), any(), any(), anyBoolean());
     }
 
     /**
@@ -608,16 +608,16 @@
      */
     @Test
     public void testStartHalFailureInApMode() throws Exception {
-        when(mHalDeviceManager.createApIface(anyLong(), any(), eq(null), any(), anyBoolean()))
+        when(mHalDeviceManager.createApIface(anyLong(), any(), any(), any(), anyBoolean()))
                 .thenReturn(null);
         assertFalse(mWifiVendorHal.startVendorHalAp());
         assertFalse(mWifiVendorHal.isHalStarted());
 
         verify(mHalDeviceManager).start();
-        verify(mHalDeviceManager).createApIface(anyLong(), any(), eq(null), any(), anyBoolean());
+        verify(mHalDeviceManager).createApIface(anyLong(), any(), any(), any(), anyBoolean());
         verify(mHalDeviceManager).stop();
 
-        verify(mHalDeviceManager, never()).createStaIface(any(), eq(null), any());
+        verify(mHalDeviceManager, never()).createStaIface(any(), any(), any());
         verify(mHalDeviceManager, never()).getChip(any(IWifiIface.class));
     }
 
@@ -635,13 +635,13 @@
 
         verify(mHalDeviceManager).start();
         verify(mHalDeviceManager).stop();
-        verify(mHalDeviceManager).createStaIface(any(), eq(null), any());
+        verify(mHalDeviceManager).createStaIface(any(), any(), any());
         verify(mHalDeviceManager).getChip(eq(mIWifiStaIface));
         verify(mHalDeviceManager, times(2)).isReady();
         verify(mHalDeviceManager, times(2)).isStarted();
 
         verify(mHalDeviceManager, never()).createApIface(
-                anyLong(), any(), eq(null), any(), anyBoolean());
+                anyLong(), any(), any(), any(), anyBoolean());
     }
 
     /**
@@ -659,12 +659,12 @@
         verify(mHalDeviceManager).start();
         verify(mHalDeviceManager).stop();
         verify(mHalDeviceManager).createApIface(
-                anyLong(), any(), eq(null), any(), anyBoolean());
+                anyLong(), any(), any(), any(), anyBoolean());
         verify(mHalDeviceManager).getChip(eq(mIWifiApIface));
         verify(mHalDeviceManager, times(2)).isReady();
         verify(mHalDeviceManager, times(2)).isStarted();
 
-        verify(mHalDeviceManager, never()).createStaIface(any(), eq(null), any());
+        verify(mHalDeviceManager, never()).createStaIface(any(), any(), any());
     }
 
     /**
@@ -682,7 +682,7 @@
 
         verify(mHalDeviceManager).start();
         verify(mHalDeviceManager).createStaIface(internalListenerCaptor.capture(),
-                eq(null), eq(TEST_WORKSOURCE));
+                any(), eq(TEST_WORKSOURCE));
         verify(mHalDeviceManager).getChip(eq(mIWifiStaIface));
         verify(mHalDeviceManager).isReady();
         verify(mHalDeviceManager).isStarted();
@@ -715,7 +715,7 @@
 
         verify(mHalDeviceManager).start();
         verify(mHalDeviceManager).createApIface(anyLong(),
-                internalListenerCaptor.capture(), eq(null), eq(TEST_WORKSOURCE), eq(false));
+                internalListenerCaptor.capture(), any(), eq(TEST_WORKSOURCE), eq(false));
         verify(mHalDeviceManager).getChip(eq(mIWifiApIface));
         verify(mHalDeviceManager).isReady();
         verify(mHalDeviceManager).isStarted();
@@ -3322,7 +3322,7 @@
 
         assertTrue(mWifiVendorHal.startVendorHal());
         assertNull(mWifiVendorHal.createStaIface(null, TEST_WORKSOURCE));
-        verify(mHalDeviceManager).createStaIface(any(), eq(null), eq(TEST_WORKSOURCE));
+        verify(mHalDeviceManager).createStaIface(any(), any(), eq(TEST_WORKSOURCE));
     }
 
     /**
@@ -3341,7 +3341,7 @@
         assertNull(mWifiVendorHal.createApIface(
                 null, TEST_WORKSOURCE, SoftApConfiguration.BAND_2GHZ, false));
         verify(mHalDeviceManager).createApIface(
-                anyLong(), any(), eq(null), eq(TEST_WORKSOURCE), eq(false));
+                anyLong(), any(), any(), eq(TEST_WORKSOURCE), eq(false));
     }
 
     /**
@@ -3351,7 +3351,7 @@
     public void testCreateRemoveStaIface() throws RemoteException {
         assertTrue(mWifiVendorHal.startVendorHal());
         String ifaceName = mWifiVendorHal.createStaIface(null, TEST_WORKSOURCE);
-        verify(mHalDeviceManager).createStaIface(any(), eq(null), eq(TEST_WORKSOURCE));
+        verify(mHalDeviceManager).createStaIface(any(), any(), eq(TEST_WORKSOURCE));
         assertEquals(TEST_IFACE_NAME, ifaceName);
         assertTrue(mWifiVendorHal.removeStaIface(ifaceName));
         verify(mHalDeviceManager).removeIface(eq(mIWifiStaIface));
@@ -3366,7 +3366,7 @@
         String ifaceName = mWifiVendorHal.createApIface(
                 null, TEST_WORKSOURCE, SoftApConfiguration.BAND_2GHZ, false);
         verify(mHalDeviceManager).createApIface(
-                anyLong(), any(), eq(null), eq(TEST_WORKSOURCE), eq(false));
+                anyLong(), any(), any(), eq(TEST_WORKSOURCE), eq(false));
         assertEquals(TEST_IFACE_NAME, ifaceName);
         assertTrue(mWifiVendorHal.removeApIface(ifaceName));
         verify(mHalDeviceManager).removeIface(eq(mIWifiApIface));
diff --git a/service/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareStateManagerTest.java b/service/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareStateManagerTest.java
index e4ddee8..1021a4d 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareStateManagerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareStateManagerTest.java
@@ -390,8 +390,8 @@
                 eq(false), eq(true), eq(true), eq(false), eq(false), eq(false));
         mDut.onConfigSuccessResponse(transactionId.getValue());
         mMockLooper.dispatchAll();
-        inOrder.verify(mockCallback).onConnectSuccess(clientId);
         inOrder.verify(mMockAwareDataPathStatemanager).createAllInterfaces();
+        inOrder.verify(mockCallback).onConnectSuccess(clientId);
 
         // (3) disconnect (disable Aware)
         mDut.disconnect(clientId);
diff --git a/service/tests/wifitests/src/com/android/server/wifi/coex/CoexManagerTest.java b/service/tests/wifitests/src/com/android/server/wifi/coex/CoexManagerTest.java
index 18ee415..837d254 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/coex/CoexManagerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/coex/CoexManagerTest.java
@@ -49,9 +49,9 @@
 import android.net.wifi.ICoexCallback;
 import android.os.Handler;
 import android.os.IBinder;
-import android.os.Looper;
 import android.os.PersistableBundle;
 import android.os.RemoteException;
+import android.os.test.TestLooper;
 import android.telephony.AccessNetworkConstants;
 import android.telephony.Annotation;
 import android.telephony.CarrierConfigManager;
@@ -103,6 +103,8 @@
     private static final String FILEPATH_LTE_27_HARMONIC = "assets/coex_lte_27_harmonic.xml";
     private static final String FILEPATH_LTE_7_INTERMOD = "assets/coex_lte_7_intermod.xml";
 
+    private TestLooper mTestLooper;
+
     @Mock private Context mMockContext;
     @Mock private Resources mMockResources;
     @Mock private WifiNative mMockWifiNative;
@@ -134,10 +136,10 @@
     }
 
     private CoexManager createCoexManager() {
-        Looper.prepare();
+        mTestLooper = new TestLooper();
         final CoexManager coexManager = new CoexManager(mMockContext, mMockWifiNative,
                 mMockDefaultTelephonyManager, mMockSubscriptionManager, mMockCarrierConfigManager,
-                new Handler(Looper.myLooper()));
+                new Handler(mTestLooper.getLooper()));
         coexManager.enableVerboseLogging(true);
         return coexManager;
     }
@@ -637,6 +639,8 @@
         );
 
         coexManager.resetMockCellChannels();
+        mTestLooper.moveTimeForward(CoexManager.CELL_CHANNEL_IDLE_DELAY_MILLIS);
+        mTestLooper.dispatchAll();
 
         // Real channels should be used when mock channels are reset.
         assertThat(coexManager.getCoexUnsafeChannels()).isEmpty();
@@ -853,6 +857,8 @@
         telephonyCallbackCaptor.getValue().onPhysicalChannelConfigChanged(Arrays.asList(
                 createMockPhysicalChannelConfig(NETWORK_TYPE_LTE, 41, 2399_900, 10_000, 0, 0)
         ));
+        mTestLooper.moveTimeForward(CoexManager.CELL_CHANNEL_IDLE_DELAY_MILLIS);
+        mTestLooper.dispatchAll();
         // Update physical channel configs back to the first channel
         telephonyCallbackCaptor.getValue().onPhysicalChannelConfigChanged(Arrays.asList(
                 createMockPhysicalChannelConfig(NETWORK_TYPE_LTE, 40, 2399_900, 10_000, 0, 0)
@@ -869,6 +875,108 @@
     }
 
     /**
+     * Verifies that calling onPhysicalChannelConfigChanged with empty cell channels will delay
+     * clearing the list.
+     */
+    @Test
+    public void testOnPhysicalChannelConfigChanged_emptyCellChannels_channelClearanceIsDelayed()
+            throws Exception {
+        when(mMockResources.getString(R.string.config_wifiCoexTableFilepath))
+                .thenReturn(createFileFromResource(FILEPATH_LTE_40_NEIGHBORING).getCanonicalPath());
+        final TelephonyManager telephonyManager = setUpSubIdMocks(0);
+        CoexManager coexManager = createCoexManager();
+        verify(mMockSubscriptionManager).addOnSubscriptionsChangedListener(
+                any(), mCoexSubscriptionsListenerCaptor.capture());
+        mCoexSubscriptionsListenerCaptor.getValue().onSubscriptionsChanged();
+        final ArgumentCaptor<CoexManager.CoexTelephonyCallback> telephonyCallbackCaptor =
+                ArgumentCaptor.forClass(CoexManager.CoexTelephonyCallback.class);
+        verify(telephonyManager).registerTelephonyCallback(any(Executor.class),
+                telephonyCallbackCaptor.capture());
+
+        // Update physical channel configs to populate the unsafe channel list
+        telephonyCallbackCaptor.getValue().onPhysicalChannelConfigChanged(Arrays.asList(
+                createMockPhysicalChannelConfig(NETWORK_TYPE_LTE, 40, 2399_900, 10_000, 0, 0)
+        ));
+        assertThat(coexManager.getCellChannels()).isNotEmpty();
+
+        // Update physical channel configs to clear unsafe channel list.
+        telephonyCallbackCaptor.getValue().onPhysicalChannelConfigChanged(new ArrayList<>());
+        // List should not be cleared yet since clearance delay isn't over
+        assertThat(coexManager.getCoexUnsafeChannels()).isNotEmpty();
+        // Simulate clearance delay
+        mTestLooper.moveTimeForward(CoexManager.CELL_CHANNEL_IDLE_DELAY_MILLIS);
+        mTestLooper.dispatchAll();
+        // Unsafe channels should now be cleared
+        assertThat(coexManager.getCoexUnsafeChannels()).isEmpty();
+
+        // Repopulate unsafe channels
+        telephonyCallbackCaptor.getValue().onPhysicalChannelConfigChanged(Arrays.asList(
+                createMockPhysicalChannelConfig(NETWORK_TYPE_LTE, 40, 2399_900, 10_000, 0, 0)
+        ));
+        assertThat(coexManager.getCellChannels()).isNotEmpty();
+
+        // Update physical channel configs to clear unsafe channel list.
+        telephonyCallbackCaptor.getValue().onPhysicalChannelConfigChanged(new ArrayList<>());
+        // Repopulate unsafe channels again before clearance delay is over
+        telephonyCallbackCaptor.getValue().onPhysicalChannelConfigChanged(Arrays.asList(
+                createMockPhysicalChannelConfig(NETWORK_TYPE_LTE, 40, 2399_900, 10_000, 0, 0)
+        ));
+        // Simulate clearance delay
+        mTestLooper.moveTimeForward(CoexManager.CELL_CHANNEL_IDLE_DELAY_MILLIS);
+        mTestLooper.dispatchAll();
+        // Unsafe channels should not be cleared since we got a physical channel config during delay
+        assertThat(coexManager.getCoexUnsafeChannels()).isNotEmpty();
+    }
+    /**
+     * Verifies that any pending channel clearances triggered by empty channel lists in
+     * onPhysicalChannelConfigChanged will be cancelled if a non-empty list is received.
+     */
+    @Test
+    public void testOnPhysicalChannelConfigChanged_nonEmptyCellChannels_cancelsChannelClearances()
+            throws Exception {
+        when(mMockResources.getString(R.string.config_wifiCoexTableFilepath))
+                .thenReturn(createFileFromResource(FILEPATH_LTE_40_NEIGHBORING).getCanonicalPath());
+        final TelephonyManager telephonyManager = setUpSubIdMocks(0);
+        CoexManager coexManager = createCoexManager();
+        verify(mMockSubscriptionManager).addOnSubscriptionsChangedListener(
+                any(), mCoexSubscriptionsListenerCaptor.capture());
+        mCoexSubscriptionsListenerCaptor.getValue().onSubscriptionsChanged();
+        final ArgumentCaptor<CoexManager.CoexTelephonyCallback> telephonyCallbackCaptor =
+                ArgumentCaptor.forClass(CoexManager.CoexTelephonyCallback.class);
+        verify(telephonyManager).registerTelephonyCallback(any(Executor.class),
+                telephonyCallbackCaptor.capture());
+        // Populate channel list
+        telephonyCallbackCaptor.getValue().onPhysicalChannelConfigChanged(Arrays.asList(
+                createMockPhysicalChannelConfig(NETWORK_TYPE_LTE, 40, 2399_900, 10_000, 0, 0)
+        ));
+        assertThat(coexManager.getCellChannels()).isNotEmpty();
+
+        // Schedule a channel clearance.
+        telephonyCallbackCaptor.getValue().onPhysicalChannelConfigChanged(new ArrayList<>());
+        // List should not be empty yet since delay isn't over
+        assertThat(coexManager.getCoexUnsafeChannels()).isNotEmpty();
+        // Populate channel list to cancel first channel clearance
+        telephonyCallbackCaptor.getValue().onPhysicalChannelConfigChanged(Arrays.asList(
+                createMockPhysicalChannelConfig(NETWORK_TYPE_LTE, 40, 2399_900, 10_000, 0, 0)
+        ));
+        // Schedule a second clearance to be done after the first clearance time
+        mTestLooper.moveTimeForward(CoexManager.CELL_CHANNEL_IDLE_DELAY_MILLIS / 2);
+        telephonyCallbackCaptor.getValue().onPhysicalChannelConfigChanged(new ArrayList<>());
+
+        // Simulate the first clearance time. List should be non-empty since this clearance was
+        // cancelled.
+        mTestLooper.moveTimeForward(CoexManager.CELL_CHANNEL_IDLE_DELAY_MILLIS / 2);
+        mTestLooper.dispatchAll();
+        assertThat(coexManager.getCoexUnsafeChannels()).isNotEmpty();
+
+        // Simulate the second clearance time. List should be empty since this clearance was
+        // not cancelled.
+        mTestLooper.moveTimeForward(CoexManager.CELL_CHANNEL_IDLE_DELAY_MILLIS / 2);
+        mTestLooper.dispatchAll();
+        assertThat(coexManager.getCoexUnsafeChannels()).isEmpty();
+    }
+
+    /**
      * Verify that multiple calls to setCoexUnsafeChannels with the same unsafe channels will only
      * update the driver the first time.
      */
diff --git a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointConfigUserStoreDataTest.java b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointConfigUserStoreDataTest.java
index 5d4c171..8ba2f36 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointConfigUserStoreDataTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointConfigUserStoreDataTest.java
@@ -115,7 +115,7 @@
         // Subscription update.
         UpdateParameter subscriptionUpdate = new UpdateParameter();
         subscriptionUpdate.setUpdateIntervalInMinutes(120);
-        subscriptionUpdate.setUpdateMethod(UpdateParameter.UPDATE_METHOD_SSP);
+        subscriptionUpdate.setUpdateMethod(UpdateParameter.UPDATE_METHOD_SPP);
         subscriptionUpdate.setRestriction(UpdateParameter.UPDATE_RESTRICTION_ROAMING_PARTNER);
         subscriptionUpdate.setServerUri("subscription.update.com");
         subscriptionUpdate.setUsername("subscriptionUser");
diff --git a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointManagerTest.java b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointManagerTest.java
index f80f785..463ec21 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointManagerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointManagerTest.java
@@ -38,6 +38,8 @@
 import static org.mockito.Mockito.anyInt;
 import static org.mockito.Mockito.anyLong;
 import static org.mockito.Mockito.anyMap;
+import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.eq;
 import static org.mockito.Mockito.lenient;
 import static org.mockito.Mockito.mock;
@@ -204,6 +206,7 @@
     @Mock OsuNetworkConnection mOsuNetworkConnection;
     @Mock OsuServerConnection mOsuServerConnection;
     @Mock PasspointProvisioner mPasspointProvisioner;
+    @Mock PasspointNetworkNominateHelper mPasspointNetworkNominateHelper;
     @Mock IProvisioningCallback mCallback;
     @Mock WfaKeyStore mWfaKeyStore;
     @Mock KeyStore mKeyStore;
@@ -253,7 +256,8 @@
         when(mContext.getSystemService(Context.APP_OPS_SERVICE)).thenReturn(mAppOpsManager);
         when(mWifiInjector.getWifiNetworkSuggestionsManager())
                 .thenReturn(mWifiNetworkSuggestionsManager);
-        when(mWifiPermissionsUtil.doesUidBelongToCurrentUser(anyInt())).thenReturn(true);
+        when(mWifiPermissionsUtil.doesUidBelongToCurrentUserOrDeviceOwner(anyInt()))
+                .thenReturn(true);
         mLooper = new TestLooper();
         mHandler = new Handler(mLooper.getLooper());
         mWifiCarrierInfoManager = new WifiCarrierInfoManager(mTelephonyManager,
@@ -265,6 +269,7 @@
                 mWifiKeyStore, mClock, mObjectFactory, mWifiConfigManager,
                 mWifiConfigStore, mWifiMetrics, mWifiCarrierInfoManager, mMacAddressUtil,
                 mWifiPermissionsUtil);
+        mManager.setPasspointNetworkNominateHelper(mPasspointNetworkNominateHelper);
         mManager.setUseInjectedPKIX(true);
         mManager.injectPKIXParameters(TEST_PKIX_PARAMETERS);
 
@@ -416,6 +421,8 @@
         when(provider.getPackageName()).thenReturn(packageName);
         assertTrue(mManager.addOrUpdateProvider(
                 config, TEST_CREATOR_UID, TEST_PACKAGE, isSuggestion, true));
+        verify(mPasspointNetworkNominateHelper, atLeastOnce())
+                .refreshPasspointNetworkCandidates(isSuggestion);
         return provider;
     }
 
@@ -571,7 +578,8 @@
      */
     @Test
     public void addProviderWithBackgroundUser() throws Exception {
-        when(mWifiPermissionsUtil.doesUidBelongToCurrentUser(anyInt())).thenReturn(false);
+        when(mWifiPermissionsUtil.doesUidBelongToCurrentUserOrDeviceOwner(anyInt()))
+                .thenReturn(false);
 
         PasspointConfiguration config = createTestConfigWithUserCredential(TEST_FQDN,
                 TEST_FRIENDLY_NAME);
@@ -2042,7 +2050,8 @@
         verify(mWifiMetrics).incrementNumPasspointProviderInstallation();
         verify(mWifiMetrics).incrementNumPasspointProviderInstallSuccess();
 
-        when(mWifiPermissionsUtil.doesUidBelongToCurrentUser(anyInt())).thenReturn(false);
+        when(mWifiPermissionsUtil.doesUidBelongToCurrentUserOrDeviceOwner(anyInt()))
+                .thenReturn(false);
         assertFalse(mManager.removeProvider(TEST_CREATOR_UID, false, null, TEST_FQDN));
     }
 
diff --git a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointNetworkNominateHelperTest.java b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointNetworkNominateHelperTest.java
index a029b19..0ca9691 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointNetworkNominateHelperTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointNetworkNominateHelperTest.java
@@ -91,7 +91,7 @@
     @Mock PasspointManager mPasspointManager;
     @Mock WifiConfigManager mWifiConfigManager;
     @Mock SubscriptionManager mSubscriptionManager;
-    LocalLog mLocalLog;
+    @Mock LocalLog mLocalLog;
     PasspointNetworkNominateHelper mNominateHelper;
 
     /**
@@ -161,9 +161,8 @@
         sTestProvider1 = generateProvider(TEST_CONFIG1);
         sTestProvider2 = generateProvider(TEST_CONFIG2);
 
-        mLocalLog = new LocalLog(512);
-        mNominateHelper = new PasspointNetworkNominateHelper(mPasspointManager, mWifiConfigManager,
-                mLocalLog);
+        mNominateHelper = new PasspointNetworkNominateHelper(
+                mPasspointManager, mWifiConfigManager, mLocalLog);
     }
 
     /**
@@ -237,7 +236,7 @@
         assertEquals("", addedConfig.getValue().enterpriseConfig.getAnonymousIdentity());
         assertTrue(addedConfig.getValue().isHomeProviderNetwork);
         verify(mWifiConfigManager).enableNetwork(
-                eq(TEST_NETWORK_ID), eq(false), anyInt(), any());
+                eq(TEST_NETWORK_ID), eq(false), eq(TEST_UID), any());
         verify(mWifiConfigManager).setNetworkCandidateScanResult(
                 eq(TEST_NETWORK_ID), any(ScanResult.class), anyInt(), any());
         verify(mWifiConfigManager).updateScanDetailForNetwork(
@@ -284,7 +283,7 @@
         assertEquals("", addedConfig.getValue().enterpriseConfig.getAnonymousIdentity());
         assertTrue(addedConfig.getValue().isHomeProviderNetwork);
         verify(mWifiConfigManager).enableNetwork(
-                eq(TEST_NETWORK_ID), eq(false), anyInt(), any());
+                eq(TEST_NETWORK_ID), eq(false), eq(TEST_UID), any());
         verify(mWifiConfigManager).setNetworkCandidateScanResult(
                 eq(TEST_NETWORK_ID), any(ScanResult.class), anyInt(), any());
         verify(mWifiConfigManager).updateScanDetailForNetwork(
@@ -325,7 +324,7 @@
         assertEquals("", addedConfig.getValue().enterpriseConfig.getAnonymousIdentity());
         assertFalse(addedConfig.getValue().isHomeProviderNetwork);
         verify(mWifiConfigManager).enableNetwork(
-                eq(TEST_NETWORK_ID), eq(false), anyInt(), any());
+                eq(TEST_NETWORK_ID), eq(false), eq(TEST_UID), any());
         verify(mWifiConfigManager).setNetworkCandidateScanResult(
                 eq(TEST_NETWORK_ID), any(ScanResult.class), anyInt(), any());
         verify(mWifiConfigManager).updateScanDetailForNetwork(
@@ -722,4 +721,41 @@
                 .getPasspointNetworkCandidates(scanDetails, false);
         assertEquals(1, candidates.size());
     }
+
+    @Test
+    public void testRefreshPasspointNetworkCandidatesUsesLastSeenScans() {
+        List<ScanDetail> scanDetails = Arrays.asList(generateScanDetail(TEST_SSID1, TEST_BSSID1));
+
+        // Setup matching providers for ScanDetail with TEST_SSID1.
+        List<Pair<PasspointProvider, PasspointMatch>> homeProvider = new ArrayList<>();
+        homeProvider.add(Pair.create(sTestProvider1, PasspointMatch.HomeProvider));
+
+        // No profiles have been added, so expect the first candidate matching to return nothing.
+        assertEquals(mNominateHelper.getPasspointNetworkCandidates(
+                scanDetails, false).size(), 0);
+
+        // Add a homeProvider for the scan detail passed in earlier
+        when(mPasspointManager.matchProvider(any(ScanResult.class))).thenReturn(homeProvider);
+        when(mWifiConfigManager.addOrUpdateNetwork(any(WifiConfiguration.class), anyInt(),
+                any())).thenReturn(new NetworkUpdateResult(TEST_NETWORK_ID));
+        when(mWifiConfigManager.getConfiguredNetwork(TEST_NETWORK_ID)).thenReturn(TEST_CONFIG1);
+
+        // Refreshing the network candidates with the old scans should now result in a match
+        mNominateHelper.refreshPasspointNetworkCandidates(false);
+        // Verify the content of the WifiConfiguration that was added to WifiConfigManager.
+        ArgumentCaptor<WifiConfiguration> addedConfig =
+                ArgumentCaptor.forClass(WifiConfiguration.class);
+        verify(mWifiConfigManager).addOrUpdateNetwork(addedConfig.capture(), anyInt(), any());
+        assertEquals(ScanResultUtil.createQuotedSSID(TEST_SSID1), addedConfig.getValue().SSID);
+        assertEquals(TEST_FQDN1, addedConfig.getValue().FQDN);
+        assertNotNull(addedConfig.getValue().enterpriseConfig);
+        assertEquals("", addedConfig.getValue().enterpriseConfig.getAnonymousIdentity());
+        assertTrue(addedConfig.getValue().isHomeProviderNetwork);
+        verify(mWifiConfigManager).enableNetwork(
+                eq(TEST_NETWORK_ID), eq(false), eq(TEST_UID), any());
+        verify(mWifiConfigManager).setNetworkCandidateScanResult(
+                eq(TEST_NETWORK_ID), any(ScanResult.class), anyInt(), any());
+        verify(mWifiConfigManager).updateScanDetailForNetwork(
+                eq(TEST_NETWORK_ID), any(ScanDetail.class));
+    }
 }
diff --git a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointXmlUtilsTest.java b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointXmlUtilsTest.java
index f6facb8..3ca9d57 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointXmlUtilsTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointXmlUtilsTest.java
@@ -17,7 +17,6 @@
 package com.android.server.wifi.hotspot2;
 
 import static org.junit.Assert.*;
-import static org.mockito.Mockito.*;
 
 import android.net.wifi.hotspot2.PasspointConfiguration;
 import android.net.wifi.hotspot2.pps.Credential;
@@ -82,7 +81,7 @@
         // Subscription update.
         UpdateParameter subscriptionUpdate = new UpdateParameter();
         subscriptionUpdate.setUpdateIntervalInMinutes(120);
-        subscriptionUpdate.setUpdateMethod(UpdateParameter.UPDATE_METHOD_SSP);
+        subscriptionUpdate.setUpdateMethod(UpdateParameter.UPDATE_METHOD_SPP);
         subscriptionUpdate.setRestriction(UpdateParameter.UPDATE_RESTRICTION_ROAMING_PARTNER);
         subscriptionUpdate.setServerUri("subscription.update.com");
         subscriptionUpdate.setUsername("subscriptionUser");
diff --git a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/omadm/DevDetailMoTest.java b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/omadm/DevDetailMoTest.java
index b1fbd37..3de4b4b 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/omadm/DevDetailMoTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/omadm/DevDetailMoTest.java
@@ -95,7 +95,7 @@
                         + "<RTProperties>"
                         + "<Type><DDFName>%s</DDFName></Type>"
                         + "</RTProperties>"
-                        + "<Node><NodeName>ext</NodeName>"
+                        + "<Node><NodeName>Ext</NodeName>"
                         + "<Node><NodeName>org.wi-fi</NodeName>"
                         + "<RTProperties>"
                         + "<Type><DDFName>%s</DDFName></Type>"
@@ -164,7 +164,7 @@
                         + "<RTProperties>"
                         + "<Type><DDFName>%s</DDFName></Type>"
                         + "</RTProperties>"
-                        + "<Node><NodeName>ext</NodeName>"
+                        + "<Node><NodeName>Ext</NodeName>"
                         + "<Node><NodeName>org.wi-fi</NodeName>"
                         + "<RTProperties>"
                         + "<Type><DDFName>%s</DDFName></Type>"
@@ -232,7 +232,7 @@
                         + "<RTProperties>"
                         + "<Type><DDFName>%s</DDFName></Type>"
                         + "</RTProperties>"
-                        + "<Node><NodeName>ext</NodeName>"
+                        + "<Node><NodeName>Ext</NodeName>"
                         + "<Node><NodeName>org.wi-fi</NodeName>"
                         + "<RTProperties>"
                         + "<Type><DDFName>%s</DDFName></Type>"
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 e0dfb4e..20eeea8 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
@@ -3285,25 +3285,6 @@
     }
 
     /**
-     * Verify WifiP2pManager.SET_WFD_INFO_FAILED is returned when p2p is disabled.
-     */
-    @Test
-    public void testSetWfdInfoFailureWhenP2pDisabled() throws Exception {
-        mTestThisDevice.wfdInfo = new WifiP2pWfdInfo();
-        when(mWifiInjector.getWifiPermissionsWrapper()).thenReturn(mWifiPermissionsWrapper);
-        when(mWifiPermissionsWrapper.getUidPermission(anyString(), anyInt()))
-                .thenReturn(PackageManager.PERMISSION_GRANTED);
-        sendSetWfdInfoMsg(mClientMessenger, mTestThisDevice.wfdInfo);
-        verify(mWifiInjector).getWifiPermissionsWrapper();
-        verify(mWifiPermissionsWrapper).getUidPermission(
-                eq(android.Manifest.permission.CONFIGURE_WIFI_DISPLAY), anyInt());
-        verify(mClientHandler).sendMessage(mMessageCaptor.capture());
-        Message message = mMessageCaptor.getValue();
-        assertEquals(WifiP2pManager.SET_WFD_INFO_FAILED, message.what);
-        assertEquals(WifiP2pManager.BUSY, message.arg1);
-    }
-
-    /**
      * Verify WifiP2pManager.SET_WFD_INFO_FAILED is returned when wfd permission denied
      * and p2p is disabled.
      */
@@ -4607,4 +4588,31 @@
         verify(mWifiNative, never()).setWfdEnable(anyBoolean());
         verify(mWifiNative, never()).setWfdDeviceInfo(anyString());
     }
+
+    /**
+     * Verify the WFD info is set if WFD info is set at P2pDisabledState.
+     */
+    @Test
+    public void testWfdInfoIsSetAtP2pEnabledWithPreSetWfdInfo() throws Exception {
+        mTestThisDevice.wfdInfo = new WifiP2pWfdInfo();
+        mTestThisDevice.wfdInfo.setEnabled(true);
+        when(mWifiInjector.getWifiPermissionsWrapper()).thenReturn(mWifiPermissionsWrapper);
+        when(mWifiPermissionsWrapper.getUidPermission(anyString(), anyInt()))
+                .thenReturn(PackageManager.PERMISSION_GRANTED);
+        when(mWifiNative.setWfdEnable(anyBoolean())).thenReturn(true);
+        when(mWifiNative.setWfdDeviceInfo(anyString())).thenReturn(true);
+        sendSetWfdInfoMsg(mClientMessenger, mTestThisDevice.wfdInfo);
+
+        // At disabled state, WFD info is stored in the service, but not set actually.
+        verify(mWifiNative, never()).setWfdEnable(anyBoolean());
+        verify(mWifiNative, never()).setWfdDeviceInfo(any());
+
+        // Move to enabled state
+        forceP2pEnabled(mClient1);
+        mTestThisDevice.status = mTestThisDevice.AVAILABLE;
+
+        // Restore data for resuming from idle shutdown.
+        verify(mWifiNative).setWfdEnable(eq(true));
+        verify(mWifiNative).setWfdDeviceInfo(eq(mTestThisDevice.wfdInfo.getDeviceInfoHex()));
+    }
 }
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 5da5582..6c6b7de 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
@@ -1372,8 +1372,9 @@
                         anyString(), anyInt());
         doAnswer(mReturnPermission).when(mMockPermissionsWrapper).getUidPermission(
                         anyString(), anyInt());
-        when(mMockUserManager.isSameProfileGroup(UserHandle.SYSTEM,
-                UserHandle.getUserHandleForUid(MANAGED_PROFILE_UID)))
+        when(mMockUserManager.isSameProfileGroup(
+                UserHandle.getUserHandleForUid(MANAGED_PROFILE_UID),
+                UserHandle.SYSTEM))
                 .thenReturn(true);
         when(mMockPermissionsWrapper.getCurrentUser()).thenReturn(mCurrentUser);
         when(mMockPermissionsWrapper.getUidPermission(mManifestStringCoarse, mUid))