Merge "Remove WPS metrics" into rvc-dev
diff --git a/libs/WifiTrackerLib/Android.bp b/libs/WifiTrackerLib/Android.bp
index 412f182..5355d00 100644
--- a/libs/WifiTrackerLib/Android.bp
+++ b/libs/WifiTrackerLib/Android.bp
@@ -3,6 +3,7 @@
     srcs: ["src/**/*.java"],
     static_libs: [
         "androidx.preference_preference",
+        "SettingsLibHelpUtils",
     ],
 
     min_sdk_version: "21",
diff --git a/libs/WifiTrackerLib/res/values-af/strings.xml b/libs/WifiTrackerLib/res/values-af/strings.xml
index b426051..84cedbd 100644
--- a/libs/WifiTrackerLib/res/values-af/strings.xml
+++ b/libs/WifiTrackerLib/res/values-af/strings.xml
@@ -46,5 +46,12 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"Voltooi tans aanmelding …"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"Kon nie aanmelding voltooi nie. Tik om weer te probeer."</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"Aanmelding is voltooi. Koppel tans …"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"Hierdie netwerk ontvang \'n unieke ID wat gebruik kan word om toestelligging na te spoor.\n"<annotation id="url">"Kom meer te wete"</annotation></string>
+    <!-- no translation found for imsi_protection_warning (3207104049473134195) -->
+    <skip />
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"Baie stadig"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"Stadig"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"OK"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"Middelmatig"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"Vinnig"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"Baie vinnig"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values-am/strings.xml b/libs/WifiTrackerLib/res/values-am/strings.xml
index 52fbdf1..c2572e0 100644
--- a/libs/WifiTrackerLib/res/values-am/strings.xml
+++ b/libs/WifiTrackerLib/res/values-am/strings.xml
@@ -46,5 +46,12 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"መመዝገብን በማጠናቀቅ ላይ…"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"ምዝገባን ማጠናቀቅ አልተቻለም። እንደገና ለመሞከር መታ ያድርጉ።"</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"ምዝገባ ተጠናቋል። በማገናኘት ላይ…"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"ይህ አውታረ መረብ የመሣሪያ አካባቢን ለመከታተል ሥራ ላይ ሊውል የሚችል ልዩ መታወቂያ ተቀብሏል።\n"<annotation id="url">"የበለጠ ለመረዳት"</annotation></string>
+    <!-- no translation found for imsi_protection_warning (3207104049473134195) -->
+    <skip />
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"በጣም ቀርፋፋ"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"አዘግይ"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"እሺ"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"መካከለኛ"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"ፈጣን"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"እጅግ በጣም ፈጣን"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values-ar/strings.xml b/libs/WifiTrackerLib/res/values-ar/strings.xml
index 7fdda62..369d697 100644
--- a/libs/WifiTrackerLib/res/values-ar/strings.xml
+++ b/libs/WifiTrackerLib/res/values-ar/strings.xml
@@ -46,5 +46,12 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"جارٍ إكمال الاشتراك…"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"تعذّر إكمال الاشتراك. انقر لإعادة المحاولة."</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"اكتمل الاشتراك. جارٍ الاتصال…"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"تتلقّى هذه الشبكة معرّفًا فريدًا يمكن استخدامه لتتبُّع الموقع الجغرافي للجهاز.\n"<annotation id="url">"مزيد من المعلومات"</annotation></string>
+    <!-- no translation found for imsi_protection_warning (3207104049473134195) -->
+    <skip />
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"بطيئة جدًا"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"بطيئة"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"حسنًا"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"متوسطة"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"سريعة"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"سريعة جدًا"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values-as/strings.xml b/libs/WifiTrackerLib/res/values-as/strings.xml
index 18cb039..588e228 100644
--- a/libs/WifiTrackerLib/res/values-as/strings.xml
+++ b/libs/WifiTrackerLib/res/values-as/strings.xml
@@ -46,5 +46,12 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"ছাইন আপ সম্পূৰ্ণ কৰি থকা হৈছে…"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"ছাইন আপ সম্পূৰ্ণ কৰিব পৰা নগ’ল। পুনৰ চেষ্টা কৰিবলৈ টিপক।"</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"ছাইন আপ সম্পূৰ্ণ হৈছে। সংযোগ কৰি থকা হৈছে…"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"এই নেটৱৰ্কটোৱে এটা অদ্বৈত আইডি পায়, যিটো ডিভাইচৰ অৱস্থান ট্ৰেক কৰিবলৈ ব্যৱহাৰ কৰিব পৰা যায়।\n"<annotation id="url">"অধিক জানক"</annotation></string>
+    <!-- no translation found for imsi_protection_warning (3207104049473134195) -->
+    <skip />
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"অতি লেহেম"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"লেহেমীয়া"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"ঠিক"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"মধ্যমীয়া"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"দ্ৰুত"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"অতি দ্ৰুত"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values-az/strings.xml b/libs/WifiTrackerLib/res/values-az/strings.xml
index be3d8d5..54be676 100644
--- a/libs/WifiTrackerLib/res/values-az/strings.xml
+++ b/libs/WifiTrackerLib/res/values-az/strings.xml
@@ -46,5 +46,12 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"Qeydiyyat tamamlanır…"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"Qeydiyyat tamamlanmadı. Yenidən cəhd etmək üçün toxunun."</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"Qeydiyyat tamamlandı. Qoşulur…"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"Bu şəbəkə cihaz məkanını izləmək üçün istifadə edilə biləcək unikal ID qəbul edir.\n"<annotation id="url">"Ətraflı məlumat"</annotation></string>
+    <!-- no translation found for imsi_protection_warning (3207104049473134195) -->
+    <skip />
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"Çox Yavaş"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"Yavaş"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"OK"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"Orta"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"Sürətli"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"Çox Sürətli"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values-b+sr+Latn/strings.xml b/libs/WifiTrackerLib/res/values-b+sr+Latn/strings.xml
index 546bb19..312627c 100644
--- a/libs/WifiTrackerLib/res/values-b+sr+Latn/strings.xml
+++ b/libs/WifiTrackerLib/res/values-b+sr+Latn/strings.xml
@@ -46,5 +46,12 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"Registracija se dovršava…"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"Dovršavanje registracije nije uspelo. Dodirnite da biste probali ponovo."</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"Registracija je dovršena. Povezuje se…"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"Ova mreža zahteva jedinstveni ID koji može da se koristi za praćenje lokacije uređaja.\n"<annotation id="url">"Saznajte više"</annotation></string>
+    <!-- no translation found for imsi_protection_warning (3207104049473134195) -->
+    <skip />
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"Veoma spora"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"Spora"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"Potvrdi"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"Srednja"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"Brza"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"Veoma brza"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values-be/strings.xml b/libs/WifiTrackerLib/res/values-be/strings.xml
index adda3a8..424f9df 100644
--- a/libs/WifiTrackerLib/res/values-be/strings.xml
+++ b/libs/WifiTrackerLib/res/values-be/strings.xml
@@ -46,5 +46,12 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"Рэгістрацыя завяршаецца…"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"Не ўдалося выканаць рэгістрацыю. Дакраніцеся, каб паўтарыць спробу."</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"Рэгістрацыя завершана. Ідзе падключэнне…"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"Гэта сетка атрымлівае ўнікальны ідэнтыфікатар, які можа выкарыстоўвацца для адсочвання месцазнаходжання прылады.\n"<annotation id="url">"Даведацца больш"</annotation></string>
+    <!-- no translation found for imsi_protection_warning (3207104049473134195) -->
+    <skip />
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"Вельмі павольная"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"Павольная"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"ОК"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"Сярэдняя"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"Хуткая"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"Вельмі хуткая"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values-bg/strings.xml b/libs/WifiTrackerLib/res/values-bg/strings.xml
index 9b6e2d7..0b5c908 100644
--- a/libs/WifiTrackerLib/res/values-bg/strings.xml
+++ b/libs/WifiTrackerLib/res/values-bg/strings.xml
@@ -46,5 +46,12 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"Регистрацията се завършва…"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"Регистрацията не можа да бъде завършена. Докоснете, за да опитате отново."</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"Регистрацията е завършена. Установява се връзка…"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"Тази мрежа получава уникален идентификатор, който може да се използва за проследяване на местоположението на устройството.\n"<annotation id="url">"Научете повече"</annotation></string>
+    <!-- no translation found for imsi_protection_warning (3207104049473134195) -->
+    <skip />
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"Много бавна"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"Бавна"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"ОK"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"Средна"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"Бърза"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"Много бърза"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values-bn/strings.xml b/libs/WifiTrackerLib/res/values-bn/strings.xml
index 94a6b2c..8b38266 100644
--- a/libs/WifiTrackerLib/res/values-bn/strings.xml
+++ b/libs/WifiTrackerLib/res/values-bn/strings.xml
@@ -46,5 +46,12 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"সাইন-আপ করা হচ্ছে…"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"সাইন-আপ করা যায়নি। আবার চেষ্টা করতে ট্যাপ করুন।"</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"সাইন-আপ করা হয়ে গেছে। কানেক্ট করা হচ্ছে…"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"এই নেটওয়ার্ক একটি অনন্য আইডি পায় যেটি ব্যবহার করে ডিভাইস লোকেশন ট্র্যাক করা যায়।\n"<annotation id="url">"আরও জানুন"</annotation></string>
+    <!-- no translation found for imsi_protection_warning (3207104049473134195) -->
+    <skip />
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"খুব ধীরে"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"ধীরে"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"ঠিক আছে"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"মাঝারি"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"দ্রুত"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"খুব দ্রুত"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values-bs/strings.xml b/libs/WifiTrackerLib/res/values-bs/strings.xml
index 5e3d540..0b48daa 100644
--- a/libs/WifiTrackerLib/res/values-bs/strings.xml
+++ b/libs/WifiTrackerLib/res/values-bs/strings.xml
@@ -38,7 +38,7 @@
     <string name="private_dns_broken" msgid="2212227512243587416">"Nije moguće pristupiti privatnom DNS serveru"</string>
     <string name="wifi_connected_no_internet" msgid="7273909077465731259">"Nema internetske veze"</string>
     <string name="wifi_security_none" msgid="6680263031386719053">"Ništa"</string>
-    <string name="wifi_passpoint_expired" msgid="3257021415099577815">"Istekao"</string>
+    <string name="wifi_passpoint_expired" msgid="3257021415099577815">"Isteklo"</string>
     <string name="tap_to_sign_up" msgid="2409214576606918295">"Dodirnite za registraciju"</string>
     <string name="tap_to_renew_subscription_and_connect" msgid="375976298920840105">"Dodirnite da obnovite pretplatu i povežete se"</string>
     <string name="osu_opening_provider" msgid="5633521771769175139">"Otvaranje <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
@@ -46,5 +46,12 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"Završavanje registracije…"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"Registraciju nije moguće izvršiti. Dodirnite da pokušate ponovo."</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"Registracija je završena. Povezivanje…"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"Ova mreža prima jedinstveni ID koji se može koristiti za praćenje lokacije uređaja.\n"<annotation id="url">"Saznajte više"</annotation></string>
+    <!-- no translation found for imsi_protection_warning (3207104049473134195) -->
+    <skip />
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"Veoma sporo"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"Sporo"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"Uredu"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"Srednja brzina"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"Brzo"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"Veoma brzo"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values-ca/strings.xml b/libs/WifiTrackerLib/res/values-ca/strings.xml
index 92dfe52..7c5478e 100644
--- a/libs/WifiTrackerLib/res/values-ca/strings.xml
+++ b/libs/WifiTrackerLib/res/values-ca/strings.xml
@@ -38,7 +38,7 @@
     <string name="private_dns_broken" msgid="2212227512243587416">"No es pot accedir al servidor DNS privat"</string>
     <string name="wifi_connected_no_internet" msgid="7273909077465731259">"Sense connexió a Internet"</string>
     <string name="wifi_security_none" msgid="6680263031386719053">"Cap"</string>
-    <string name="wifi_passpoint_expired" msgid="3257021415099577815">"Caducat"</string>
+    <string name="wifi_passpoint_expired" msgid="3257021415099577815">"Caducada"</string>
     <string name="tap_to_sign_up" msgid="2409214576606918295">"Toca per registrar-te"</string>
     <string name="tap_to_renew_subscription_and_connect" msgid="375976298920840105">"Toca per renovar la subscripció i connectar-te"</string>
     <string name="osu_opening_provider" msgid="5633521771769175139">"S\'està obrint <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
@@ -46,5 +46,12 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"S\'està completant el registre…"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"No s\'ha pogut completar el registre. Toca per tornar-ho a provar."</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"S\'ha completat el registre. S\'està connectant…"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"Aquesta xarxa rep un identificador únic que es pot utilitzar per fer el seguiment de la ubicació del dispositiu.\n"<annotation id="url">"Més informació"</annotation></string>
+    <!-- no translation found for imsi_protection_warning (3207104049473134195) -->
+    <skip />
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"Molt lenta"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"Lenta"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"Correcta"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"Mitjana"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"Ràpida"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"Molt ràpida"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values-cs/strings.xml b/libs/WifiTrackerLib/res/values-cs/strings.xml
index 488194a..db0dbb0 100644
--- a/libs/WifiTrackerLib/res/values-cs/strings.xml
+++ b/libs/WifiTrackerLib/res/values-cs/strings.xml
@@ -46,5 +46,12 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"Dokončování registrace…"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"Registraci se nepodařilo dokončit. Klepnutím opakujte akci."</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"Registrace byla dokončena. Připojování…"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"Tato síť dostane jedinečný identifikátor, pomocí kterého lze sledovat polohu zařízení.\n"<annotation id="url">"Další informace"</annotation></string>
+    <!-- no translation found for imsi_protection_warning (3207104049473134195) -->
+    <skip />
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"Velmi pomalá"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"Pomalá"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"OK"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"Střední"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"Rychlá"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"Velmi rychlá"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values-da/strings.xml b/libs/WifiTrackerLib/res/values-da/strings.xml
index 9657b91..8c9b5a0 100644
--- a/libs/WifiTrackerLib/res/values-da/strings.xml
+++ b/libs/WifiTrackerLib/res/values-da/strings.xml
@@ -46,5 +46,12 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"Fuldfører registrering…"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"Registreringen kunne ikke fuldføres. Tryk for at prøve igen."</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"Registreringen er fuldført. Opretter forbindelse…"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"Dette netværk kræver et unikt id, der kan bruges til at spore enhedens placering.\n"<annotation id="url">"Få flere oplysninger"</annotation></string>
+    <!-- no translation found for imsi_protection_warning (3207104049473134195) -->
+    <skip />
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"Meget langsom"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"Langsom"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"OK"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"Middel"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"Hurtig"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"Meget hurtig"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values-de/strings.xml b/libs/WifiTrackerLib/res/values-de/strings.xml
index afaaeec..eaf53f0 100644
--- a/libs/WifiTrackerLib/res/values-de/strings.xml
+++ b/libs/WifiTrackerLib/res/values-de/strings.xml
@@ -46,5 +46,12 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"Registrierung wird abgeschlossen…"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"Registrierung konnte nicht abgeschlossen werden. Tippe, um es noch einmal zu versuchen."</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"Registrierung abgeschlossen. Verbindung wird hergestellt…"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"Dieses Netz empfängt eine eindeutige ID, mit der der Gerätestandort erfasst werden kann.\n"<annotation id="url">"Weitere Informationen"</annotation></string>
+    <!-- no translation found for imsi_protection_warning (3207104049473134195) -->
+    <skip />
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"Sehr langsam"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"Langsam"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"Ok"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"Mittel"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"Schnell"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"Sehr schnell"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values-el/strings.xml b/libs/WifiTrackerLib/res/values-el/strings.xml
index 86bde63..498477c 100644
--- a/libs/WifiTrackerLib/res/values-el/strings.xml
+++ b/libs/WifiTrackerLib/res/values-el/strings.xml
@@ -46,5 +46,12 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"Ολοκλήρωση εγγραφής…"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"Δεν ήταν δυνατή η ολοκλήρωση της εγγραφής. Πατήστε για να δοκιμάσετε ξανά."</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"Η εγγραφή ολοκληρώθηκε. Σύνδεση…"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"Αυτό το δίκτυο λαμβάνει ένα μοναδικό αναγνωριστικό που μπορεί να χρησιμοποιηθεί για τον εντοπισμό της τοποθεσίας της συσκευής.\n"<annotation id="url">"Μάθετε περισσότερα"</annotation>"."</string>
+    <!-- no translation found for imsi_protection_warning (3207104049473134195) -->
+    <skip />
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"Πολύ αργή"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"Αργή"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"ΟΚ"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"Μέτρια"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"Γρήγορη"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"Πολύ γρήγορη"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values-en-rAU/strings.xml b/libs/WifiTrackerLib/res/values-en-rAU/strings.xml
index 58271df..4a36110 100644
--- a/libs/WifiTrackerLib/res/values-en-rAU/strings.xml
+++ b/libs/WifiTrackerLib/res/values-en-rAU/strings.xml
@@ -46,5 +46,12 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"Completing sign-up…"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"Couldn’t complete sign-up. Tap to try again."</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"Sign-up complete. Connecting…"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"This network receives a unique ID that can be used to track device location.\n"<annotation id="url">"Learn more"</annotation></string>
+    <!-- no translation found for imsi_protection_warning (3207104049473134195) -->
+    <skip />
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"Very slow"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"Slow"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"OK"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"Medium"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"Fast"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"Very fast"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values-en-rCA/strings.xml b/libs/WifiTrackerLib/res/values-en-rCA/strings.xml
index 58271df..4a36110 100644
--- a/libs/WifiTrackerLib/res/values-en-rCA/strings.xml
+++ b/libs/WifiTrackerLib/res/values-en-rCA/strings.xml
@@ -46,5 +46,12 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"Completing sign-up…"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"Couldn’t complete sign-up. Tap to try again."</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"Sign-up complete. Connecting…"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"This network receives a unique ID that can be used to track device location.\n"<annotation id="url">"Learn more"</annotation></string>
+    <!-- no translation found for imsi_protection_warning (3207104049473134195) -->
+    <skip />
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"Very slow"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"Slow"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"OK"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"Medium"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"Fast"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"Very fast"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values-en-rGB/strings.xml b/libs/WifiTrackerLib/res/values-en-rGB/strings.xml
index 58271df..4a36110 100644
--- a/libs/WifiTrackerLib/res/values-en-rGB/strings.xml
+++ b/libs/WifiTrackerLib/res/values-en-rGB/strings.xml
@@ -46,5 +46,12 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"Completing sign-up…"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"Couldn’t complete sign-up. Tap to try again."</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"Sign-up complete. Connecting…"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"This network receives a unique ID that can be used to track device location.\n"<annotation id="url">"Learn more"</annotation></string>
+    <!-- no translation found for imsi_protection_warning (3207104049473134195) -->
+    <skip />
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"Very slow"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"Slow"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"OK"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"Medium"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"Fast"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"Very fast"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values-en-rIN/strings.xml b/libs/WifiTrackerLib/res/values-en-rIN/strings.xml
index 58271df..4a36110 100644
--- a/libs/WifiTrackerLib/res/values-en-rIN/strings.xml
+++ b/libs/WifiTrackerLib/res/values-en-rIN/strings.xml
@@ -46,5 +46,12 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"Completing sign-up…"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"Couldn’t complete sign-up. Tap to try again."</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"Sign-up complete. Connecting…"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"This network receives a unique ID that can be used to track device location.\n"<annotation id="url">"Learn more"</annotation></string>
+    <!-- no translation found for imsi_protection_warning (3207104049473134195) -->
+    <skip />
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"Very slow"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"Slow"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"OK"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"Medium"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"Fast"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"Very fast"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values-en-rXC/strings.xml b/libs/WifiTrackerLib/res/values-en-rXC/strings.xml
index 0250fc4..087ad38 100644
--- a/libs/WifiTrackerLib/res/values-en-rXC/strings.xml
+++ b/libs/WifiTrackerLib/res/values-en-rXC/strings.xml
@@ -46,5 +46,11 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‏‏‏‏‎‎‎‎‏‎‏‎‏‎‏‎‎‎‏‎‎‎‎‏‎‎‎‏‎‎‏‏‏‎‏‎‎‎‎‎‎‎‏‏‎‎‏‏‎‎‏‎‏‏‎‏‏‏‎Completing sign-up…‎‏‎‎‏‎"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‏‏‏‎‏‎‎‎‏‎‏‎‏‏‎‎‏‏‎‏‏‎‎‎‏‎‎‏‎‏‎‎‏‎‎‎‎‏‎‏‏‏‏‏‎‎‏‏‏‏‏‎‎‎‏‏‏‎Couldn’t complete sign-up. Tap to try again.‎‏‎‎‏‎"</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‎‏‎‏‎‏‎‏‏‎‎‎‎‎‏‎‏‎‏‏‎‏‏‏‏‏‏‏‏‏‎‎‎‏‎‏‎‏‎‏‎‎‏‏‏‎‏‏‎‏‏‏‏‎‎‎‎‏‎Sign-up complete. Connecting…‎‏‎‎‏‎"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‎‎‎‏‎‏‏‎‎‎‎‏‏‎‎‏‏‏‏‎‏‎‎‎‎‏‏‏‎‎‏‏‎‎‎‏‎‎‎‏‎‎‏‎‎‎‏‏‏‏‎‎‏‎‏‏‎‏‎This network receives a unique ID that can be used to track device location.‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎"<annotation id="url">"‎‏‎‎‏‏‏‎Learn more‎‏‎‎‏‏‎"</annotation>"‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
+    <string name="imsi_protection_warning" msgid="3207104049473134195">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‎‎‏‎‎‎‎‎‎‏‏‏‏‎‏‏‎‎‎‎‏‎‎‏‎‎‎‎‎‏‏‎‏‎‏‎‎‏‎‎‎‎‎‎‎‏‏‏‏‎‎‏‏‏‎‎‏‏‎This network receives a unique ID that can be used to track device location. ‎‏‎‎‏‏‎"<annotation id="url">"‎‏‎‎‏‏‏‎Learn more‎‏‎‎‏‏‎"</annotation>"‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‏‎‏‎‏‎‏‎‎‎‎‏‎‎‎‏‎‏‎‏‏‎‏‏‏‎‏‎‎‏‎‏‏‏‏‎‎‏‏‎‎‎‏‏‏‎‏‎‏‏‎‎‎‏‎‏‏‎Very Slow‎‏‎‎‏‎"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‎‏‎‏‏‎‏‏‏‏‎‏‏‎‎‎‏‎‎‏‏‏‏‎‎‏‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‎‏‏‏‎‏‎‏‎‏‏‎‏‏‏‏‎Slow‎‏‎‎‏‎"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‏‏‏‏‎‏‏‎‏‏‎‏‏‏‏‏‏‏‏‎‏‏‎‎‏‎‎‏‏‏‎‎‎‎‎‏‏‏‎‏‏‏‎‏‏‏‏‎‏‏‏‎‏‎‎‎‎‎OK‎‏‎‎‏‎"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‎‎‎‎‎‏‎‎‏‎‎‏‎‏‏‏‎‏‏‏‎‏‎‎‏‏‎‎‏‏‎‏‎‎‏‎‏‎‏‏‎‏‎‎‎‏‎‏‎‏‎‎‏‏‏‎‎‏‎Medium‎‏‎‎‏‎"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‏‏‏‎‎‏‏‎‎‎‏‎‎‎‎‎‏‎‏‏‎‎‎‎‏‏‎‏‏‏‎‏‎‏‏‎‏‏‏‏‏‏‎‏‏‏‎‏‏‏‎‎‎‎‎‏‎‎Fast‎‏‎‎‏‎"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‎‎‎‏‎‎‏‎‏‎‏‏‏‎‎‎‏‏‎‏‎‏‏‏‏‎‏‏‏‏‏‎‏‏‎‎‎‏‏‏‎‏‏‏‏‏‏‏‏‏‎‎‎‎‏‎‏‎Very Fast‎‏‎‎‏‎"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values-es-rUS/strings.xml b/libs/WifiTrackerLib/res/values-es-rUS/strings.xml
index f030270..0fe060b 100644
--- a/libs/WifiTrackerLib/res/values-es-rUS/strings.xml
+++ b/libs/WifiTrackerLib/res/values-es-rUS/strings.xml
@@ -46,5 +46,12 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"Completando registro…"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"No se pudo completar el registro. Presiona para volver a intentarlo."</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"Se completó el registro. Conectando…"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"Esta red recibe un ID único con el que se puede realizar el seguimiento de la ubicación del dispositivo.\n"<annotation id="url">"Más información"</annotation></string>
+    <!-- no translation found for imsi_protection_warning (3207104049473134195) -->
+    <skip />
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"Muy lenta"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"Lenta"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"Aceptar"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"Media"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"Rápida"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"Muy rápida"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values-es/strings.xml b/libs/WifiTrackerLib/res/values-es/strings.xml
index 0cc1415..1687090 100644
--- a/libs/WifiTrackerLib/res/values-es/strings.xml
+++ b/libs/WifiTrackerLib/res/values-es/strings.xml
@@ -46,5 +46,12 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"Completando registro…"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"No se ha podido completar el registro. Toca para volver a intentarlo."</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"Se ha completado el registro. Conectando…"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"Esta red recibe un ID único con el que se puede rastrear la ubicación del dispositivo.\n"<annotation id="url">"Más información"</annotation></string>
+    <!-- no translation found for imsi_protection_warning (3207104049473134195) -->
+    <skip />
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"Muy lenta"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"Lenta"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"Aceptable"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"Media"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"Rápida"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"Muy rápida"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values-et/strings.xml b/libs/WifiTrackerLib/res/values-et/strings.xml
index bbc6aee..c8d762d 100644
--- a/libs/WifiTrackerLib/res/values-et/strings.xml
+++ b/libs/WifiTrackerLib/res/values-et/strings.xml
@@ -46,5 +46,12 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"Registreerimise lõpuleviimine …"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"Registreerimist ei saanud lõpule viia. Puudutage, et uuesti proovida."</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"Registreerimine on lõpule viidud. Ühendamine …"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"See võrk saab kordumatu ID, mida saab kasutada seadme asukoha jälgimiseks.\n"<annotation id="url">"Lisateave"</annotation></string>
+    <!-- no translation found for imsi_protection_warning (3207104049473134195) -->
+    <skip />
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"Väga aeglane"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"Aeglane"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"Hea"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"Keskmine"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"Kiire"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"Väga kiire"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values-eu/strings.xml b/libs/WifiTrackerLib/res/values-eu/strings.xml
index dd85cfe..ab9dc84 100644
--- a/libs/WifiTrackerLib/res/values-eu/strings.xml
+++ b/libs/WifiTrackerLib/res/values-eu/strings.xml
@@ -46,5 +46,12 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"Izena ematen…"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"Ezin izan da eman izena. Berriro saiatzeko, ukitu hau."</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"Eman da izena. Konektatzen…"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"Gailuaren kokapenaren jarraipena egiteko balio duen ID esklusibo bat jasotzen du sare honek.\n"<annotation id="url">"Lortu informazio gehiago"</annotation></string>
+    <!-- no translation found for imsi_protection_warning (3207104049473134195) -->
+    <skip />
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"Oso motela"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"Motela"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"Ados"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"Tartekoa"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"Bizkorra"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"Oso bizkorra"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values-fa/strings.xml b/libs/WifiTrackerLib/res/values-fa/strings.xml
index 97cc7a7..be14163 100644
--- a/libs/WifiTrackerLib/res/values-fa/strings.xml
+++ b/libs/WifiTrackerLib/res/values-fa/strings.xml
@@ -46,5 +46,12 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"درحال تکمیل ثبت‌نام…"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"ثبت‌نام تکمیل نشد. برای امتحان مجدد ضربه بزنید."</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"ثبت‌نام کامل شد. درحال اتصال…"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"این شبکه شناسه یکتایی دریافت می‌کند که می‌توان از آن برای ردیابی مکان دستگاه استفاده کرد.\n"<annotation id="url">"بیشتر بدانید"</annotation></string>
+    <!-- no translation found for imsi_protection_warning (3207104049473134195) -->
+    <skip />
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"بسیار آهسته"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"آهسته"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"تأیید"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"متوسط"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"سریع"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"خیلی سریع"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values-fi/strings.xml b/libs/WifiTrackerLib/res/values-fi/strings.xml
index 9efd7b1..aca4ff4 100644
--- a/libs/WifiTrackerLib/res/values-fi/strings.xml
+++ b/libs/WifiTrackerLib/res/values-fi/strings.xml
@@ -46,5 +46,12 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"Viimeistellään rekisteröitymistä…"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"Rekisteröityminen ei onnistunut. Yritä uudelleen napauttamalla."</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"Rekisteröityminen valmis. Yhdistetään…"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"Tälle verkolle lähetetään yksilöllinen tunnus, jolla voidaan seurata laitteen sijaintia.\n"<annotation id="url">"Lue lisää"</annotation></string>
+    <!-- no translation found for imsi_protection_warning (3207104049473134195) -->
+    <skip />
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"Hyvin hidas"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"Hidas"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"OK"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"Kohtuullinen"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"Nopea"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"Hyvin nopea"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values-fr-rCA/strings.xml b/libs/WifiTrackerLib/res/values-fr-rCA/strings.xml
index eac36cb..077b524 100644
--- a/libs/WifiTrackerLib/res/values-fr-rCA/strings.xml
+++ b/libs/WifiTrackerLib/res/values-fr-rCA/strings.xml
@@ -46,5 +46,12 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"Finalisation de l\'inscription en cours…"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"Impossible de terminer l\'inscription. Touchez pour réessayer."</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"Inscription terminée. Connexion en cours…"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"Ce réseau reçoit un identifiant unique qui peut être utilisé pour faire le suivi de la position de l\'appareil.\n"<annotation id="url">"En savoir plus"</annotation></string>
+    <!-- no translation found for imsi_protection_warning (3207104049473134195) -->
+    <skip />
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"Très lente"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"Lente"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"OK"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"Moyenne"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"Élevée"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"Très rapide"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values-fr/strings.xml b/libs/WifiTrackerLib/res/values-fr/strings.xml
index 82aea86..8131925 100644
--- a/libs/WifiTrackerLib/res/values-fr/strings.xml
+++ b/libs/WifiTrackerLib/res/values-fr/strings.xml
@@ -46,5 +46,12 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"Finalisation de l\'inscription…"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"Impossible de finaliser l\'inscription. Appuyez ici pour réessayer."</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"Inscription terminée. Connexion…"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"Ce réseau reçoit un identifiant unique qui peut être utilisé pour suivre la position de l\'appareil.\n"<annotation id="url">"Plus d\'infos"</annotation></string>
+    <!-- no translation found for imsi_protection_warning (3207104049473134195) -->
+    <skip />
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"Très lente"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"Lente"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"Correcte"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"Moyenne"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"Élevée"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"Très rapide"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values-gl/strings.xml b/libs/WifiTrackerLib/res/values-gl/strings.xml
index ea86e58..0816db5 100644
--- a/libs/WifiTrackerLib/res/values-gl/strings.xml
+++ b/libs/WifiTrackerLib/res/values-gl/strings.xml
@@ -46,5 +46,12 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"Completando rexistro…"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"Non se puido completar o rexistro. Toca para tentalo de novo."</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"Completouse o rexistro. Conectando…"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"Esta rede recibe un código exclusivo que se pode utilizar para realizar un seguimento da localización do dispositivo.\n"<annotation id="url">"Máis información"</annotation></string>
+    <!-- no translation found for imsi_protection_warning (3207104049473134195) -->
+    <skip />
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"Moi lenta"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"Lenta"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"Aceptar"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"Media"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"Rápida"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"Moi rápida"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values-gu/strings.xml b/libs/WifiTrackerLib/res/values-gu/strings.xml
index 5094a5c..a108ddc 100644
--- a/libs/WifiTrackerLib/res/values-gu/strings.xml
+++ b/libs/WifiTrackerLib/res/values-gu/strings.xml
@@ -46,5 +46,12 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"સાઇન અપ પૂર્ણ કરી રહ્યા છીએ…"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"સાઇન અપ પૂર્ણ કરી શકાયું નથી. ફરી પ્રયાસ કરવા માટે ટૅપ કરો."</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"સાઇન અપ પૂર્ણ. કનેક્ટ કરી રહ્યાં છીએ…"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"આ નેટવર્ક એક અજોડ ID મેળવે છે જેનો ઉપયોગ ડિવાઇસનું સ્થાન ટ્રૅક કરવા માટે થઈ શકે છે.\n"<annotation id="url">"વધુ જાણો"</annotation></string>
+    <!-- no translation found for imsi_protection_warning (3207104049473134195) -->
+    <skip />
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"ખૂબ જ ધીમી"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"ધીમી"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"ઓકે"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"મધ્યમ"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"ઝડપી"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"ખૂબ ઝડપી"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values-hi/strings.xml b/libs/WifiTrackerLib/res/values-hi/strings.xml
index 476f18a..5391688 100644
--- a/libs/WifiTrackerLib/res/values-hi/strings.xml
+++ b/libs/WifiTrackerLib/res/values-hi/strings.xml
@@ -46,5 +46,12 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"साइन अप किया जा रहा है…"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"साइन अप नहीं हो सका. फिर से कोशिश करने के लिए टैप करें."</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"साइन अप की प्रक्रिया पूरी हो गई. कनेक्ट हो रहा है…"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"इस नेटवर्क को एक विशेष आईडी दिया जाता है. इसका इस्तेमाल डिवाइस की जगह की जानकारी का पता लगाने के लिए किया जा सकता है.\n"<annotation id="url">"ज़्यादा जानें"</annotation></string>
+    <!-- no translation found for imsi_protection_warning (3207104049473134195) -->
+    <skip />
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"अत्‍यधिक धीमी"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"धीमी"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"ठीक है"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"मध्यम"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"तेज़"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"बहुत ज़्यादा तेज़"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values-hr/strings.xml b/libs/WifiTrackerLib/res/values-hr/strings.xml
index 10a0d82..0ad5388 100644
--- a/libs/WifiTrackerLib/res/values-hr/strings.xml
+++ b/libs/WifiTrackerLib/res/values-hr/strings.xml
@@ -46,5 +46,12 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"Dovršavanje registracije…"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"Registracija nije dovršena. Dodirnite za ponovni pokušaj."</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"Registracija je dovršena. Povezivanje…"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"Ta mreža prima jedinstveni ID koji se može koristiti za praćenje lokacije uređaja.\n"<annotation id="url">"Saznajte više"</annotation></string>
+    <!-- no translation found for imsi_protection_warning (3207104049473134195) -->
+    <skip />
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"Vrlo sporo"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"Sporo"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"U redu"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"Srednje"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"Brzo"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"Vrlo brzo"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values-hu/strings.xml b/libs/WifiTrackerLib/res/values-hu/strings.xml
index 86bfc65..6999741 100644
--- a/libs/WifiTrackerLib/res/values-hu/strings.xml
+++ b/libs/WifiTrackerLib/res/values-hu/strings.xml
@@ -46,5 +46,12 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"Regisztráció befejezése…"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"Nem sikerült a regisztráció befejezése. Koppintással újrapróbálkozhat."</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"A regisztráció befejeződött. Csatlakozás…"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"Ez a hálózat egyedi azonosítót kap, amely felhasználható az eszköz helyadatainak követésére.\n"<annotation id="url">"További információ."</annotation></string>
+    <!-- no translation found for imsi_protection_warning (3207104049473134195) -->
+    <skip />
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"Nagyon lassú"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"Lassú"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"Rendben"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"Közepes"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"Gyors"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"Nagyon gyors"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values-hy/strings.xml b/libs/WifiTrackerLib/res/values-hy/strings.xml
index 6d2c40c..a042dd9 100644
--- a/libs/WifiTrackerLib/res/values-hy/strings.xml
+++ b/libs/WifiTrackerLib/res/values-hy/strings.xml
@@ -46,5 +46,12 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"Գրանցումն ավարտվում է…"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"Չհաջողվեց ավարտել գրանցումը։ Հպեք՝ նորից փորձելու համար։"</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"Գրանցումն ավարտված է։ Միացում…"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"Այս ցանցը ստանում է եզակի ID, որի օգնությամբ հնարավոր է հետագծել սարքի տեղադրությունը։\n"<annotation id="url">"Իմանալ ավելին"</annotation></string>
+    <!-- no translation found for imsi_protection_warning (3207104049473134195) -->
+    <skip />
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"Շատ դանդաղ"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"Դանդաղ"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"Հաստատել"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"Միջին"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"Արագ"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"Շատ արագ"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values-in/strings.xml b/libs/WifiTrackerLib/res/values-in/strings.xml
index 9278842..1a17156 100644
--- a/libs/WifiTrackerLib/res/values-in/strings.xml
+++ b/libs/WifiTrackerLib/res/values-in/strings.xml
@@ -46,5 +46,12 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"Menyelesaikan pendaftaran…"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"Tidak dapat menyelesaikan pendaftaran. Ketuk untuk mencoba lagi."</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"Pendaftaran selesai. Menyambungkan…"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"Jaringan ini menerima ID unik yang dapat digunakan untuk melacak lokasi perangkat.\n"<annotation id="url">"Pelajari lebih lanjut"</annotation></string>
+    <!-- no translation found for imsi_protection_warning (3207104049473134195) -->
+    <skip />
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"Sangat Lambat"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"Lambat"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"Oke"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"Sedang"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"Cepat"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"Sangat Cepat"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values-is/strings.xml b/libs/WifiTrackerLib/res/values-is/strings.xml
index 6d294c1..1ef9e0c 100644
--- a/libs/WifiTrackerLib/res/values-is/strings.xml
+++ b/libs/WifiTrackerLib/res/values-is/strings.xml
@@ -38,7 +38,7 @@
     <string name="private_dns_broken" msgid="2212227512243587416">"Ekki næst í DNS-einkaþjón"</string>
     <string name="wifi_connected_no_internet" msgid="7273909077465731259">"Engin nettenging"</string>
     <string name="wifi_security_none" msgid="6680263031386719053">"Ekkert"</string>
-    <string name="wifi_passpoint_expired" msgid="3257021415099577815">"Útrunninn"</string>
+    <string name="wifi_passpoint_expired" msgid="3257021415099577815">"Útrunnin"</string>
     <string name="tap_to_sign_up" msgid="2409214576606918295">"Ýttu til að skrá þig"</string>
     <string name="tap_to_renew_subscription_and_connect" msgid="375976298920840105">"Ýttu til að endurnýja áskrift og tengjast"</string>
     <string name="osu_opening_provider" msgid="5633521771769175139">"Opnar <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
@@ -46,5 +46,12 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"Gengur frá skráningu…"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"Ekki tókst að ljúka við skráningu. Ýttu til að reyna aftur."</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"Skráningu lokið. Tengist…"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"Þetta net fær einkvæmt auðkenni sem hægt er að nota til að rekja staðsetningu tækisins.\n"<annotation id="url">"Frekari upplýsingar"</annotation></string>
+    <!-- no translation found for imsi_protection_warning (3207104049473134195) -->
+    <skip />
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"Mjög hægt"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"Hægt"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"Í lagi"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"Miðlungshratt"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"Hratt"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"Mjög hratt"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values-it/strings.xml b/libs/WifiTrackerLib/res/values-it/strings.xml
index 62264a9..78bc4c7 100644
--- a/libs/WifiTrackerLib/res/values-it/strings.xml
+++ b/libs/WifiTrackerLib/res/values-it/strings.xml
@@ -38,7 +38,7 @@
     <string name="private_dns_broken" msgid="2212227512243587416">"Non è possibile accedere al server DNS privato"</string>
     <string name="wifi_connected_no_internet" msgid="7273909077465731259">"Internet assente"</string>
     <string name="wifi_security_none" msgid="6680263031386719053">"Nessuna"</string>
-    <string name="wifi_passpoint_expired" msgid="3257021415099577815">"Scaduto"</string>
+    <string name="wifi_passpoint_expired" msgid="3257021415099577815">"Scaduta"</string>
     <string name="tap_to_sign_up" msgid="2409214576606918295">"Tocca per registrarti"</string>
     <string name="tap_to_renew_subscription_and_connect" msgid="375976298920840105">"Tocca per rinnovare l\'abbonamento e connetterti"</string>
     <string name="osu_opening_provider" msgid="5633521771769175139">"Apertura di <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
@@ -46,5 +46,12 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"Completamento della registrazione…"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"Impossibile completare la registrazione. Tocca per riprovare."</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"Registrazione completata. Connessione…"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"Questa rete riceve un ID univoco che può essere utilizzato per tracciare la posizione del dispositivo.\n"<annotation id="url">"Ulteriori informazioni"</annotation></string>
+    <!-- no translation found for imsi_protection_warning (3207104049473134195) -->
+    <skip />
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"Molto lenta"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"Lenta"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"OK"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"Media"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"Veloce"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"Molto veloce"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values-iw/strings.xml b/libs/WifiTrackerLib/res/values-iw/strings.xml
index a9a1917..63c3605 100644
--- a/libs/WifiTrackerLib/res/values-iw/strings.xml
+++ b/libs/WifiTrackerLib/res/values-iw/strings.xml
@@ -46,5 +46,12 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"מתבצעת השלמה של ההרשמה…"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"לא ניתן היה להשלים את ההרשמה. יש להקיש כדי לנסות שוב."</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"תהליך ההרשמה הסתיים. בתהליך התחברות…"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"הרשת הזו מקבלת מזהה ייחודי שיכול לשמש למעקב אחר מיקום המכשיר.\n"<annotation id="url">"למידע נוסף"</annotation></string>
+    <!-- no translation found for imsi_protection_warning (3207104049473134195) -->
+    <skip />
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"איטית מאוד"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"איטית"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"אישור"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"בינונית"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"מהירה"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"מהירה מאוד"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values-ja/strings.xml b/libs/WifiTrackerLib/res/values-ja/strings.xml
index e1232db..1b3c2ca 100644
--- a/libs/WifiTrackerLib/res/values-ja/strings.xml
+++ b/libs/WifiTrackerLib/res/values-ja/strings.xml
@@ -46,5 +46,12 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"登録を完了しています…"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"登録を完了できませんでした。タップしてもう一度お試しください。"</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"登録が完了しました。接続しています…"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"このネットワークは一意の ID を受信します。この ID を使ってデバイスの位置情報が追跡される可能性があります。\n"<annotation id="url">"詳細"</annotation></string>
+    <!-- no translation found for imsi_protection_warning (3207104049473134195) -->
+    <skip />
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"とても遅い"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"遅い"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"OK"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"普通"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"速い"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"非常に速い"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values-ka/strings.xml b/libs/WifiTrackerLib/res/values-ka/strings.xml
index e7d010b..759935b 100644
--- a/libs/WifiTrackerLib/res/values-ka/strings.xml
+++ b/libs/WifiTrackerLib/res/values-ka/strings.xml
@@ -17,7 +17,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="summary_separator" msgid="6533720408587140819">" / "</string>
-    <string name="auto_connect_disable" msgid="1078319396240632542">"ავტომატური დაკავშირება გამორთულია"</string>
+    <string name="auto_connect_disable" msgid="1078319396240632542">"ავტოდაკავშირება გამორთულია"</string>
     <string name="saved_network" msgid="6241977554502802914">"შენახული <xliff:g id="NAME">%1$s</xliff:g>-ის მიერ"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="3089980800841926268">"ავტომატურად დაკავშირება ვერ ხერხდება"</string>
     <string name="wifi_no_internet" msgid="4461212237521310895">"ინტერნეტ-კავშირი არ არის"</string>
@@ -46,5 +46,12 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"მიმდინარეობს რეგისტრაციის დასრულება…"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"რეგისტრაციის დასრულება ვერ მოხერხდა. შეეხეთ ხელახლა საცდელად."</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"რეგისტრაცია დასრულდა. მიმდინარეობს დაკავშირება…"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"ეს ქსელი მიიღებს უნიკალურ ID-ს, რომლის მეშვეობითაც შესაძლებელია მოწყობილობის მდებარეობის აღნუსხვა.\n"<annotation id="url">"შეიტყვეთ მეტი"</annotation></string>
+    <!-- no translation found for imsi_protection_warning (3207104049473134195) -->
+    <skip />
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"ძალიან ნელი"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"ნელი"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"კარგი"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"საშუალო"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"სწრაფი"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"ძალიან სწრაფი"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values-kk/strings.xml b/libs/WifiTrackerLib/res/values-kk/strings.xml
index eaec09d..f2c0f1e 100644
--- a/libs/WifiTrackerLib/res/values-kk/strings.xml
+++ b/libs/WifiTrackerLib/res/values-kk/strings.xml
@@ -46,5 +46,12 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"Тіркелу аяқталуда…"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"Тіркелу аяқталмады. Әрекетті қайталау үшін түртіңіз."</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"Тіркелу аяқталды. Байланыс орнатылуда…"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"Бұл желіге бірегей идентификатор беріледі, оның көмегімен құрылғының орналасқан жері қадағаланады.\n"<annotation id="url">"Толығырақ"</annotation></string>
+    <!-- no translation found for imsi_protection_warning (3207104049473134195) -->
+    <skip />
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"Өте баяу"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"Баяу"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"Жарайды"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"Орташа"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"Жылдам"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"Өте жылдам"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values-km/strings.xml b/libs/WifiTrackerLib/res/values-km/strings.xml
index 1c0791c..3ae2418 100644
--- a/libs/WifiTrackerLib/res/values-km/strings.xml
+++ b/libs/WifiTrackerLib/res/values-km/strings.xml
@@ -38,7 +38,7 @@
     <string name="private_dns_broken" msgid="2212227512243587416">"មិនអាច​ចូលប្រើ​ម៉ាស៊ីនមេ DNS ឯកជន​បានទេ"</string>
     <string name="wifi_connected_no_internet" msgid="7273909077465731259">"គ្មាន​អ៊ីនធឺណិតទេ"</string>
     <string name="wifi_security_none" msgid="6680263031386719053">"គ្មាន"</string>
-    <string name="wifi_passpoint_expired" msgid="3257021415099577815">"ផុតកំណត់"</string>
+    <string name="wifi_passpoint_expired" msgid="3257021415099577815">"បានផុតកំណត់"</string>
     <string name="tap_to_sign_up" msgid="2409214576606918295">"ចុច​ដើម្បី​ចុះឈ្មោះ"</string>
     <string name="tap_to_renew_subscription_and_connect" msgid="375976298920840105">"ចុច ដើម្បី​បន្តការ​ជាវជាថ្មី និង​ភ្ជាប់"</string>
     <string name="osu_opening_provider" msgid="5633521771769175139">"កំពុង​បើក <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
@@ -46,5 +46,12 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"កំពុង​បញ្ចប់​ការចុះឈ្មោះ…"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"មិនអាច​បញ្ចប់​ការចុះឈ្មោះ​បានទេ។ សូមចុច ដើម្បី​ព្យាយាម​ម្ដង​ទៀត។"</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"ការចុះ​ឈ្មោះ​បានបញ្ចប់។ កំពុងភ្ជាប់…"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"បណ្ដាញនេះ​ទទួលបាន​លេខសម្គាល់​ពិសេស ដែល​អាចប្រើ​ដើម្បី​តាមដាន​ទីតាំង​ឧបករណ៍។\n"<annotation id="url">"ស្វែងយល់​បន្ថែម"</annotation></string>
+    <!-- no translation found for imsi_protection_warning (3207104049473134195) -->
+    <skip />
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"យឺតណាស់"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"យឺត"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"យល់ព្រម"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"មធ្យម"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"លឿន"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"លឿន​ខ្លាំង"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values-kn/strings.xml b/libs/WifiTrackerLib/res/values-kn/strings.xml
index 2972dc0..7b58269 100644
--- a/libs/WifiTrackerLib/res/values-kn/strings.xml
+++ b/libs/WifiTrackerLib/res/values-kn/strings.xml
@@ -46,5 +46,12 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"ಸೈನ್-ಅಪ್ ಪೂರ್ಣಗೊಳಿಸಲಾಗುತ್ತಿದೆ…"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"ಸೈನ್-ಅಪ್ ಪೂರ್ಣಗೊಳಿಸಲು ಸಾಧ್ಯವಾಗುತ್ತಿಲ್ಲ. ಮತ್ತೊಮ್ಮೆ ಪ್ರಯತ್ನಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"ಸೈನ್-ಅಪ್ ಪೂರ್ಣಗೊಂಡಿದೆ. ಕನೆಕ್ಟ್ ಆಗುತ್ತಿದೆ…"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"ಸಾಧನದ ಸ್ಥಳವನ್ನು ಟ್ರ್ಯಾಕ್ ಮಾಡಲು ಬಳಸಬಹುದಾದ ಅನನ್ಯ ಐಡಿ ಒಂದನ್ನು ಈ ನೆಟ್‌ವರ್ಕ್ ಸ್ವೀಕರಿಸುತ್ತದೆ.\n"<annotation id="url">"ಇನ್ನಷ್ಟು ತಿಳಿಯಿರಿ"</annotation></string>
+    <!-- no translation found for imsi_protection_warning (3207104049473134195) -->
+    <skip />
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"ತುಂಬಾ ನಿಧಾನವಾಗಿದೆ"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"ನಿಧಾನ"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"ಸರಿ"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"ಮಧ್ಯಮ"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"ವೇಗ"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"ತುಂಬಾ ವೇಗವಾಗಿದೆ"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values-ko/strings.xml b/libs/WifiTrackerLib/res/values-ko/strings.xml
index 5347e12..7a1e600 100644
--- a/libs/WifiTrackerLib/res/values-ko/strings.xml
+++ b/libs/WifiTrackerLib/res/values-ko/strings.xml
@@ -46,5 +46,12 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"가입 완료 중…"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"가입을 완료할 수 없습니다. 다시 시도하려면 탭하세요."</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"가입이 완료되었습니다. 연결 중…"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"이 네트워크는 기기 위치 추적에 사용될 수 있는 고유 ID를 수신합니다.\n"<annotation id="url">"자세히 알아보기"</annotation></string>
+    <!-- no translation found for imsi_protection_warning (3207104049473134195) -->
+    <skip />
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"매우 느림"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"느림"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"보통"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"보통"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"빠름"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"매우 빠름"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values-ky/strings.xml b/libs/WifiTrackerLib/res/values-ky/strings.xml
index 04b3547..5a49dd2 100644
--- a/libs/WifiTrackerLib/res/values-ky/strings.xml
+++ b/libs/WifiTrackerLib/res/values-ky/strings.xml
@@ -38,7 +38,7 @@
     <string name="private_dns_broken" msgid="2212227512243587416">"Жеке DNS сервери жеткиликсиз"</string>
     <string name="wifi_connected_no_internet" msgid="7273909077465731259">"Интернет жок"</string>
     <string name="wifi_security_none" msgid="6680263031386719053">"Жок"</string>
-    <string name="wifi_passpoint_expired" msgid="3257021415099577815">"Мөөнөтү бүткөн"</string>
+    <string name="wifi_passpoint_expired" msgid="3257021415099577815">"Эскирип калган"</string>
     <string name="tap_to_sign_up" msgid="2409214576606918295">"Катталуу үчүн таптап коюңуз"</string>
     <string name="tap_to_renew_subscription_and_connect" msgid="375976298920840105">"Жазылууну жаңыртып, туташуу үчүн таптап коюңуз"</string>
     <string name="osu_opening_provider" msgid="5633521771769175139">"<xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g> ачылууда"</string>
@@ -46,5 +46,12 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"Катталуу аяктоодо…"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"Катталуу аягына чыккан жок. Кайра аракет кылуу үчүн таптап коюңуз."</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"Катталуу аягына чыкты. Туташууда…"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"Бул тармактарга өзгөчө идентификатор берилип, анын жардамы менен түзмөктүн жайгашкан жерин аныктоого болот.\n"<annotation id="url">"Кеңири маалымат"</annotation></string>
+    <!-- no translation found for imsi_protection_warning (3207104049473134195) -->
+    <skip />
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"Өтө жай"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"Жай"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"Жарайт"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"Орто"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"Ылдам"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"Абдан ылдам"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values-lo/strings.xml b/libs/WifiTrackerLib/res/values-lo/strings.xml
index c28ecf9..c4124aa 100644
--- a/libs/WifiTrackerLib/res/values-lo/strings.xml
+++ b/libs/WifiTrackerLib/res/values-lo/strings.xml
@@ -46,5 +46,12 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"ກຳລັງສຳເລັດການສະໝັກ…"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"ບໍ່ສາມາດສຳເລັດການສະໝັກໄດ້. ແຕະເພື່ອລອງໃໝ່."</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"ສະໝັກສຳເລັດແລ້ວ. ກຳລັງເຊື່ອມຕໍ່…"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"ເຄືອຂ່າຍນີ້ຈະໄດ້ຮັບ unique ID ທີ່ສາມາດໃຊ້ເພື່ອຕິດຕາມສະຖານທີ່ອຸປະກອນໄດ້.\n"<annotation id="url">"ສຶກສາເພີ່ມເຕີມ"</annotation></string>
+    <!-- no translation found for imsi_protection_warning (3207104049473134195) -->
+    <skip />
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"ຊ້າຫຼາຍ"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"ຊ້າ"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"ຕົກລົງ"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"ປານກາງ"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"ໄວ"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"ໄວຫຼາຍ"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values-lt/strings.xml b/libs/WifiTrackerLib/res/values-lt/strings.xml
index 51a8525..013c4a2 100644
--- a/libs/WifiTrackerLib/res/values-lt/strings.xml
+++ b/libs/WifiTrackerLib/res/values-lt/strings.xml
@@ -46,5 +46,12 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"Baigiamas prisiregistravimas…"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"Nepavyko užbaigti prisiregistravimo. Jei norite bandyti dar kartą, palieskite."</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"Prisiregistravimas baigtas. Prijungiama…"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"Šis tinklas gauna unikalų ID, kurį galima naudoti įrenginio vietovei stebėti.\n"<annotation id="url">"Sužinokite daugiau"</annotation></string>
+    <!-- no translation found for imsi_protection_warning (3207104049473134195) -->
+    <skip />
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"Labai lėtas"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"Lėtas"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"Gerai"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"Vidutinis"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"Greitas"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"Labai greitas"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values-lv/strings.xml b/libs/WifiTrackerLib/res/values-lv/strings.xml
index f89491e..02149a1 100644
--- a/libs/WifiTrackerLib/res/values-lv/strings.xml
+++ b/libs/WifiTrackerLib/res/values-lv/strings.xml
@@ -46,5 +46,12 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"Notiek reģistrācijas pabeigšana…"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"Nevarēja pabeigt reģistrāciju. Pieskarieties, lai mēģinātu vēlreiz."</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"Reģistrācija ir pabeigta. Notiek savienojuma izveide…"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"Šis tīkls saņem unikālo ID, ko var izmantot, lai izsekotu ierīces atrašanās vietu.\n"<annotation id="url">"Uzzināt vairāk"</annotation></string>
+    <!-- no translation found for imsi_protection_warning (3207104049473134195) -->
+    <skip />
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"Ļoti lēns"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"Lēns"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"Labi"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"Vidējs"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"Ātrs"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"Ļoti ātrs"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values-mk/strings.xml b/libs/WifiTrackerLib/res/values-mk/strings.xml
index d694bb6..30caa1e 100644
--- a/libs/WifiTrackerLib/res/values-mk/strings.xml
+++ b/libs/WifiTrackerLib/res/values-mk/strings.xml
@@ -46,5 +46,12 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"Се завршува регистрацијата…"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"Не можеше да се заврши регистрацијата. Допрете за да се обидете повторно."</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"Регистрацијата е завршена. Се поврзува…"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"Мрежава добива уникатен ID што може да се користи за следење на локацијата на уредот.\n"<annotation id="url">"Дознајте повеќе"</annotation></string>
+    <!-- no translation found for imsi_protection_warning (3207104049473134195) -->
+    <skip />
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"Многу бавна"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"Бавна"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"Во ред"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"Средна"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"Брза"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"Многу брза"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values-ml/strings.xml b/libs/WifiTrackerLib/res/values-ml/strings.xml
index 5f8b640..93ff297 100644
--- a/libs/WifiTrackerLib/res/values-ml/strings.xml
+++ b/libs/WifiTrackerLib/res/values-ml/strings.xml
@@ -46,5 +46,12 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"സൈൻ അപ്പ് പൂർത്തിയാക്കുന്നു…"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"സൈൻ അപ്പ് പൂർത്തിയാക്കാനായില്ല. വീണ്ടും ശ്രമിക്കാൻ ടാപ്പ് ചെയ്യുക."</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"സൈൻ അപ്പ് പൂർത്തിയായി. കണക്റ്റ് ചെയ്യുന്നു…"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"ഉപകരണ ലൊക്കേഷൻ ട്രാക്ക് ചെയ്യാൻ ഉപയോഗിക്കാവുന്ന തനത് ഐഡി ഈ നെറ്റ്‌വർക്കിന് ലഭിക്കും.\n"<annotation id="url">"കൂടുതലറിയുക"</annotation></string>
+    <!-- no translation found for imsi_protection_warning (3207104049473134195) -->
+    <skip />
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"വളരെ കുറഞ്ഞ വേഗത്തിൽ"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"കുറഞ്ഞ വേഗത്തിൽ"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"ശരി"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"ഇടത്തരം"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"വേഗത്തിൽ"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"അതിവേഗം"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values-mn/strings.xml b/libs/WifiTrackerLib/res/values-mn/strings.xml
index b149125..35bd092 100644
--- a/libs/WifiTrackerLib/res/values-mn/strings.xml
+++ b/libs/WifiTrackerLib/res/values-mn/strings.xml
@@ -46,5 +46,12 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"Бүртгэлийг дуусгаж байна…"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"Бүртгэлийг дуусгаж чадсангүй. Дахин оролдохын тулд товшино уу."</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"Бүртгэлийг дуусгалаа. Холбогдож байна…"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"Энэ сүлжээ нь төхөөрөмжийн байршлыг тандахад ашиглах боломжтой цор ганц дугаарыг хүлээн авдаг.\n"<annotation id="url">"Нэмэлт мэдээлэл авах"</annotation></string>
+    <!-- no translation found for imsi_protection_warning (3207104049473134195) -->
+    <skip />
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"Маш удаан"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"Удаан"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"ЗА"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"Дунд"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"Хурдан"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"Маш хурдан"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values-mr/strings.xml b/libs/WifiTrackerLib/res/values-mr/strings.xml
index a569334..9260947 100644
--- a/libs/WifiTrackerLib/res/values-mr/strings.xml
+++ b/libs/WifiTrackerLib/res/values-mr/strings.xml
@@ -46,5 +46,12 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"साइन-अप पूर्ण होत आहे…"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"साइन-अप पूर्ण करता आले नाही. पुन्हा प्रयत्न करण्यासाठी टॅप करा."</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"साइन-अप पूर्ण झाले आहे. कनेक्ट करत आहे…"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"हे नेटवर्क डिव्हाइसचे स्थान ट्रॅक करण्यासाठी वापरता येणारा युनिक आयडी मिळवते.\n"<annotation id="url">"अधिक जाणून घ्या"</annotation></string>
+    <!-- no translation found for imsi_protection_warning (3207104049473134195) -->
+    <skip />
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"खूप हळू"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"हळू"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"ठीक आहे"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"मध्‍यम"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"जलद"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"खूप जलद"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values-ms/strings.xml b/libs/WifiTrackerLib/res/values-ms/strings.xml
index 0cfd1e2..f94ec0d 100644
--- a/libs/WifiTrackerLib/res/values-ms/strings.xml
+++ b/libs/WifiTrackerLib/res/values-ms/strings.xml
@@ -46,5 +46,12 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"Menyelesaikan pendaftaran…"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"Tidak dapat menyelesaikan pendaftaran. Ketik untuk mencuba lagi."</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"Pendaftaran selesai. Menyambung…"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"Rangkaian ini menerima ID unik yang boleh digunakan untuk menjejaki lokasi peranti.\n"<annotation id="url">"Ketahui lebih lanjut"</annotation></string>
+    <!-- no translation found for imsi_protection_warning (3207104049473134195) -->
+    <skip />
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"Sangat Perlahan"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"Perlahan"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"OK"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"Sederhana"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"Laju"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"Sangat Laju"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values-my/strings.xml b/libs/WifiTrackerLib/res/values-my/strings.xml
index 930dd27..4beca48 100644
--- a/libs/WifiTrackerLib/res/values-my/strings.xml
+++ b/libs/WifiTrackerLib/res/values-my/strings.xml
@@ -46,5 +46,12 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"အကောင့်ဖွင့်ခြင်း အပြီးသတ်နေသည်…"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"အကောင့်ဖွင့်ခြင်း အပြီးသတ်၍ မရပါ။ ထပ်စမ်းကြည့်ရန် တို့ပါ။"</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"အကောင့်ဖွင့်ပြီးပါပြီ။ ချိတ်ဆက်နေသည်…"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"ဤကွန်ရက်က စက်တည်နေရာကို ခြေရာခံရန် အသုံးပြုနိုင်သည့် သီးသန့် ID ကို ရရှိပါသည်။\n"<annotation id="url">"ပိုမိုလေ့လာရန်"</annotation></string>
+    <!-- no translation found for imsi_protection_warning (3207104049473134195) -->
+    <skip />
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"အလွန်နှေး"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"နှေး"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"OK"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"အတော်အသင့်"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"မြန်"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"အလွန်မြန်"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values-nb/strings.xml b/libs/WifiTrackerLib/res/values-nb/strings.xml
index b987fe2..a696fa9 100644
--- a/libs/WifiTrackerLib/res/values-nb/strings.xml
+++ b/libs/WifiTrackerLib/res/values-nb/strings.xml
@@ -46,5 +46,12 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"Fullfører registreringen …"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"Kunne ikke fullføre registreringen. Trykk for å prøve på nytt."</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"Registreringen er fullført. Kobler til …"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"Dette nettverket mottar en unik ID som kan brukes til å spore enhetsposisjonen.\n"<annotation id="url">"Finn ut mer"</annotation></string>
+    <!-- no translation found for imsi_protection_warning (3207104049473134195) -->
+    <skip />
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"Veldig treg"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"Treg"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"Ok"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"Middels"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"Rask"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"Veldig rask"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values-ne/strings.xml b/libs/WifiTrackerLib/res/values-ne/strings.xml
index 9cffaf2..35f7f7a 100644
--- a/libs/WifiTrackerLib/res/values-ne/strings.xml
+++ b/libs/WifiTrackerLib/res/values-ne/strings.xml
@@ -46,5 +46,12 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"साइन अप गर्ने कार्य सम्पन्न गर्दै…"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"साइन अप गर्ने कार्य सम्पन्न गर्न सकिएन। फेरि प्रयास गर्न ट्याप गर्नुहोस्।"</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"साइन अप गर्ने कार्य सम्पन्न भयो। जोड्दै…"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"यो नेटवर्कले यन्त्रको स्थान पत्ता लगाउन प्रयोग गर्न सकिने एउटा अद्वित्तीय ID प्राप्त गर्छ।\n"<annotation id="url">"थप जान्नुहोस्"</annotation></string>
+    <!-- no translation found for imsi_protection_warning (3207104049473134195) -->
+    <skip />
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"धेरै ढिलो"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"बिस्तारै"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"ठिक छ"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"मध्यम"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"छिटो"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"धेरै छिटो"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values-nl/strings.xml b/libs/WifiTrackerLib/res/values-nl/strings.xml
index fa11f23..c83a0e1 100644
--- a/libs/WifiTrackerLib/res/values-nl/strings.xml
+++ b/libs/WifiTrackerLib/res/values-nl/strings.xml
@@ -46,5 +46,12 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"Aanmelding voltooien…"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"Kan aanmelding niet voltooien. Tik om het opnieuw te proberen."</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"Aanmelding voltooid. Verbinden…"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"Dit netwerk ontvangt een unieke ID die kan worden gebruikt om de apparaatlocatie bij te houden.\n"<annotation id="url">"Meer informatie"</annotation></string>
+    <!-- no translation found for imsi_protection_warning (3207104049473134195) -->
+    <skip />
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"Zeer langzaam"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"Langzaam"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"Redelijk"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"Gemiddeld"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"Snel"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"Zeer snel"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values-or/strings.xml b/libs/WifiTrackerLib/res/values-or/strings.xml
index 858eb06..7ba1d8e 100644
--- a/libs/WifiTrackerLib/res/values-or/strings.xml
+++ b/libs/WifiTrackerLib/res/values-or/strings.xml
@@ -46,5 +46,12 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"ସାଇନ୍ ଅପ୍ ଶେଷ ହେଉଛି…"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"ସାଇନ୍ ଅପ୍ ଶେଷ ହୋଇପାରିଲା ନାହିଁ। ପୁଣି ଚେଷ୍ଟା କରିବାକୁ ଟାପ୍ କରନ୍ତୁ।"</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"ସାଇନ୍ ଅପ୍ ଶେଷ ହୋଇଛି। ସଂଯୋଗ କରୁଛି…"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"ଡିଭାଇସର ଲୋକେସନ୍ ଟ୍ରାକ୍ କରିବାକୁ ବ୍ୟବହାର କରାଯାଇପାରୁଥିବା ଏକ ସ୍ୱତନ୍ତ୍ର ID ଏହି ନେଟୱାର୍କ ପାଇଥାଏ।\n"<annotation id="url">"ଅଧିକ ଜାଣନ୍ତୁ"</annotation></string>
+    <!-- no translation found for imsi_protection_warning (3207104049473134195) -->
+    <skip />
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"ବହୁତ ମନ୍ଥର"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"କମ୍‌ ବେଗ"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"ଠିକ୍‌ ଅଛି"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"ମଧ୍ୟମ"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"ଦ୍ରୁତ"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"ଅତି ଦ୍ରୁତ"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values-pa/strings.xml b/libs/WifiTrackerLib/res/values-pa/strings.xml
index 8d61fe6..0d7c827 100644
--- a/libs/WifiTrackerLib/res/values-pa/strings.xml
+++ b/libs/WifiTrackerLib/res/values-pa/strings.xml
@@ -46,5 +46,12 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"ਸਾਈਨ-ਅੱਪ ਮੁਕੰਮਲ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ…"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"ਸਾਈਨ-ਅੱਪ ਮੁਕੰਮਲ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਿਆ। ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ।"</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"ਸਾਈਨ-ਅੱਪ ਮੁਕੰਮਲ ਹੋਇਆ। ਕਨੈਕਟ ਹੋ ਰਿਹਾ ਹੈ…"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"ਇਹ ਨੈੱਟਵਰਕ ਇੱਕ ਵਿਲੱਖਣ ਆਈਡੀ ਪ੍ਰਾਪਤ ਕਰਦਾ ਹੈ ਜਿਸ ਨੂੰ ਡੀਵਾਈਸ ਦੇ ਟਿਕਾਣੇ ਨੂੰ ਟਰੈਕ ਕਰਨ ਲਈ ਵਰਤਿਆ ਦਾ ਸਕਦਾ ਹੈ।\n"<annotation id="url">"ਹੋਰ ਜਾਣੋ"</annotation></string>
+    <!-- no translation found for imsi_protection_warning (3207104049473134195) -->
+    <skip />
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"ਬਹੁਤ ਹੌਲੀ"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"ਹੌਲੀ"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"ਠੀਕ ਹੈ"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"ਔਸਤ"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"ਤੇਜ਼"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"ਬਹੁਤ ਤੇਜ਼"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values-pl/strings.xml b/libs/WifiTrackerLib/res/values-pl/strings.xml
index e2b7b20..8827201 100644
--- a/libs/WifiTrackerLib/res/values-pl/strings.xml
+++ b/libs/WifiTrackerLib/res/values-pl/strings.xml
@@ -46,5 +46,12 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"Kończę rejestrować…"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"Nie udało się dokończyć rejestracji. Kliknij, by spróbować ponownie."</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"Rejestracja zakończona. Łączę…"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"Ta sieć wymaga unikalnego identyfikatora, którego można użyć do śledzenia lokalizacji urządzenia.\n"<annotation id="url">"Więcej informacji"</annotation></string>
+    <!-- no translation found for imsi_protection_warning (3207104049473134195) -->
+    <skip />
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"Bardzo wolna"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"Wolna"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"OK"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"Średnia"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"Szybka"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"Bardzo szybka"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values-pt-rBR/strings.xml b/libs/WifiTrackerLib/res/values-pt-rBR/strings.xml
index 657ba2e..9c3a188 100644
--- a/libs/WifiTrackerLib/res/values-pt-rBR/strings.xml
+++ b/libs/WifiTrackerLib/res/values-pt-rBR/strings.xml
@@ -46,5 +46,12 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"Concluindo inscrição…"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"Não foi possível concluir a inscrição. Toque para tentar novamente."</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"Inscrição concluída. Conectando…"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"Essa rede recebe um código exclusivo que pode ser usado para rastrear a localização do dispositivo.\n"<annotation id="url">"Saiba mais"</annotation></string>
+    <!-- no translation found for imsi_protection_warning (3207104049473134195) -->
+    <skip />
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"Muito lenta"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"Lenta"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"Ok"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"Média"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"Rápida"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"Muito rápida"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values-pt-rPT/strings.xml b/libs/WifiTrackerLib/res/values-pt-rPT/strings.xml
index a117a8f..baa3e07 100644
--- a/libs/WifiTrackerLib/res/values-pt-rPT/strings.xml
+++ b/libs/WifiTrackerLib/res/values-pt-rPT/strings.xml
@@ -38,7 +38,7 @@
     <string name="private_dns_broken" msgid="2212227512243587416">"Não é possível aceder ao servidor DNS."</string>
     <string name="wifi_connected_no_internet" msgid="7273909077465731259">"Sem Internet"</string>
     <string name="wifi_security_none" msgid="6680263031386719053">"Nenhuma"</string>
-    <string name="wifi_passpoint_expired" msgid="3257021415099577815">"Expirado"</string>
+    <string name="wifi_passpoint_expired" msgid="3257021415099577815">"Expirada"</string>
     <string name="tap_to_sign_up" msgid="2409214576606918295">"Toque para se inscrever."</string>
     <string name="tap_to_renew_subscription_and_connect" msgid="375976298920840105">"Toque para renovar a subscrição e estabelecer ligação."</string>
     <string name="osu_opening_provider" msgid="5633521771769175139">"A abrir <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>…"</string>
@@ -46,5 +46,12 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"A concluir a inscrição…"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"Não foi possível concluir a inscrição. Toque para tentar novamente."</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"Inscrição concluída. A estabelecer ligação…"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"Esta rede recebe um ID exclusivo que pode ser utilizado para monitorizar a localização do dispositivo.\n"<annotation id="url">"Saber mais"</annotation></string>
+    <!-- no translation found for imsi_protection_warning (3207104049473134195) -->
+    <skip />
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"Muito lenta"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"Lenta"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"OK"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"Média"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"Rápida"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"Muito rápida"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values-pt/strings.xml b/libs/WifiTrackerLib/res/values-pt/strings.xml
index 657ba2e..9c3a188 100644
--- a/libs/WifiTrackerLib/res/values-pt/strings.xml
+++ b/libs/WifiTrackerLib/res/values-pt/strings.xml
@@ -46,5 +46,12 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"Concluindo inscrição…"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"Não foi possível concluir a inscrição. Toque para tentar novamente."</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"Inscrição concluída. Conectando…"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"Essa rede recebe um código exclusivo que pode ser usado para rastrear a localização do dispositivo.\n"<annotation id="url">"Saiba mais"</annotation></string>
+    <!-- no translation found for imsi_protection_warning (3207104049473134195) -->
+    <skip />
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"Muito lenta"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"Lenta"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"Ok"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"Média"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"Rápida"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"Muito rápida"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values-ro/strings.xml b/libs/WifiTrackerLib/res/values-ro/strings.xml
index 39630e8..6d2f9d5 100644
--- a/libs/WifiTrackerLib/res/values-ro/strings.xml
+++ b/libs/WifiTrackerLib/res/values-ro/strings.xml
@@ -46,5 +46,12 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"Se finalizează înscrierea…"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"Nu s-a putut finaliza înscrierea. Atingeți pentru a încerca din nou."</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"Înscrierea a fost finalizată. Se conectează…"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"Această rețea primește un ID unic care se poate folosi pentru a urmări locația dispozitivului.\n"<annotation id="url">"Aflați mai multe"</annotation></string>
+    <!-- no translation found for imsi_protection_warning (3207104049473134195) -->
+    <skip />
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"Foarte lentă"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"Lentă"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"Bine"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"Medie"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"Rapidă"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"Foarte rapidă"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values-ru/strings.xml b/libs/WifiTrackerLib/res/values-ru/strings.xml
index dc08428..e6b42c1 100644
--- a/libs/WifiTrackerLib/res/values-ru/strings.xml
+++ b/libs/WifiTrackerLib/res/values-ru/strings.xml
@@ -46,5 +46,12 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"Завершение регистрации…"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"Не удалось завершить регистрацию. Нажмите, чтобы повторить попытку."</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"Регистрация завершена. Подключение…"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"Эта сеть получит доступ к уникальному идентификатору, с помощью которого можно отслеживать местоположение устройства.\n"<annotation id="url">"Подробнее…"</annotation></string>
+    <!-- no translation found for imsi_protection_warning (3207104049473134195) -->
+    <skip />
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"Очень медленная"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"Медленная"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"ОК"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"Средняя"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"Быстрая"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"Очень быстрая"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values-si/strings.xml b/libs/WifiTrackerLib/res/values-si/strings.xml
index a2937df..04d5877 100644
--- a/libs/WifiTrackerLib/res/values-si/strings.xml
+++ b/libs/WifiTrackerLib/res/values-si/strings.xml
@@ -46,5 +46,12 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"ලියාපදිංචිය සම්පූර්ණ කරමින්…"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"ලියාපදිංචිය සම්පූර්ණ කළ නොහැකි විය. නැවත උත්සාහ කිරීමට තට්ටු කරන්න."</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"ලියාපදිංචිය සම්පූර්ණයි. සබැඳෙමින්…"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"මෙම ජාලය උපාංග ස්ථානය නිරීක්ෂණය කිරීමට භාවිත කළ හැකි අනන්‍ය ID එකක් ලැබේ.\n"<annotation id="url">"තව දැන ගන්න"</annotation></string>
+    <!-- no translation found for imsi_protection_warning (3207104049473134195) -->
+    <skip />
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"ඉතා මන්දගාමී"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"මන්දගාමී"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"හරි"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"මධ්‍යම"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"වේගවත්"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"ඉතා වේගවත්"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values-sk/strings.xml b/libs/WifiTrackerLib/res/values-sk/strings.xml
index 0b527f2..539798b 100644
--- a/libs/WifiTrackerLib/res/values-sk/strings.xml
+++ b/libs/WifiTrackerLib/res/values-sk/strings.xml
@@ -46,5 +46,12 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"Dokončuje sa registrácia…"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"Registráciu sa nepodarilo dokončiť. Klepnutím to skúste znova."</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"Registrácia je dokončená. Pripája sa…"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"Táto sieť prijíma jedinečný identifikátor, pomocou ktorého je možné sledovať polohu zariadenia.\n"<annotation id="url">"Ďalšie informácie"</annotation></string>
+    <!-- no translation found for imsi_protection_warning (3207104049473134195) -->
+    <skip />
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"Veľmi pomalá"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"Pomalá"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"OK"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"Stredná"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"Rýchla"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"Veľmi rýchla"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values-sl/strings.xml b/libs/WifiTrackerLib/res/values-sl/strings.xml
index fce1afd..7de0131 100644
--- a/libs/WifiTrackerLib/res/values-sl/strings.xml
+++ b/libs/WifiTrackerLib/res/values-sl/strings.xml
@@ -46,5 +46,12 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"Dokončevanje registracije …"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"Registracije ni bilo mogoče dokončati. Če želite poskusiti znova, se dotaknite."</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"Registracija je končana. Povezovanje …"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"To omrežje prejme enolični ID, s katerim je mogoče spremljati lokacijo naprave.\n"<annotation id="url">"Več o tem"</annotation></string>
+    <!-- no translation found for imsi_protection_warning (3207104049473134195) -->
+    <skip />
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"Zelo počasna"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"Počasna"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"V redu"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"Srednje hitra"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"Hitra"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"Zelo hitra"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values-sq/strings.xml b/libs/WifiTrackerLib/res/values-sq/strings.xml
index f74ad93..6c5c292 100644
--- a/libs/WifiTrackerLib/res/values-sq/strings.xml
+++ b/libs/WifiTrackerLib/res/values-sq/strings.xml
@@ -46,5 +46,12 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"Po përfundon regjistrimin…"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"Regjistrimi nuk mund të përfundonte. Trokit për të provuar përsëri."</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"Regjistrimi përfundoi. Po lidhet…"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"Ky rrjet merr një ID unike që mund të përdoret për të monitoruar vendndodhjen e pajisjes.\n"<annotation id="url">"Mëso më shumë"</annotation></string>
+    <!-- no translation found for imsi_protection_warning (3207104049473134195) -->
+    <skip />
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"Shumë e ulët"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"E ngadaltë"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"Në rregull"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"Mesatare"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"E shpejtë"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"Shumë e shpejtë"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values-sr/strings.xml b/libs/WifiTrackerLib/res/values-sr/strings.xml
index 7cdad28..e26558e 100644
--- a/libs/WifiTrackerLib/res/values-sr/strings.xml
+++ b/libs/WifiTrackerLib/res/values-sr/strings.xml
@@ -46,5 +46,12 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"Регистрација се довршава…"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"Довршавање регистрације није успело. Додирните да бисте пробали поново."</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"Регистрација је довршена. Повезује се…"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"Ова мрежа захтева јединствени ИД који може да се користи за праћење локације уређаја.\n"<annotation id="url">"Сазнајте више"</annotation></string>
+    <!-- no translation found for imsi_protection_warning (3207104049473134195) -->
+    <skip />
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"Веома спора"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"Спора"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"Потврди"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"Средња"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"Брза"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"Веома брза"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values-sv/strings.xml b/libs/WifiTrackerLib/res/values-sv/strings.xml
index 8556393..e4d41b5 100644
--- a/libs/WifiTrackerLib/res/values-sv/strings.xml
+++ b/libs/WifiTrackerLib/res/values-sv/strings.xml
@@ -46,5 +46,12 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"Registreringen slutförs …"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"Det gick inte att slutföra registreringen. Tryck för att försöka igen."</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"Registrering har slutförts. Ansluter …"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"Detta nätverk får ett unikt id som kan användas till att spåra enhetens plats.\n"<annotation id="url">"Läs mer"</annotation></string>
+    <!-- no translation found for imsi_protection_warning (3207104049473134195) -->
+    <skip />
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"Mycket långsam"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"Långsam"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"Okej"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"Medelsnabb"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"Snabb"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"Mycket snabb"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values-sw/strings.xml b/libs/WifiTrackerLib/res/values-sw/strings.xml
index 6fd97c9..44f70e3 100644
--- a/libs/WifiTrackerLib/res/values-sw/strings.xml
+++ b/libs/WifiTrackerLib/res/values-sw/strings.xml
@@ -17,7 +17,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="summary_separator" msgid="6533720408587140819">" / "</string>
-    <string name="auto_connect_disable" msgid="1078319396240632542">"Kipengele cha kuunganisha kiotomatiki kimezimwa"</string>
+    <string name="auto_connect_disable" msgid="1078319396240632542">"Kuunganisha kiotomatiki kumezimwa"</string>
     <string name="saved_network" msgid="6241977554502802914">"Ilihifadhiwa na <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="3089980800841926268">"Haiwezi kuunganisha kiotomatiki"</string>
     <string name="wifi_no_internet" msgid="4461212237521310895">"Hakuna muunganisho wa intaneti"</string>
@@ -46,5 +46,12 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"Inakamilisha usajili…"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"Imeshindwa kukamilisha usajili. Gusa ili ujaribu tena."</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"Imekamilisha usajili. Inaunganisha…"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"Mtandao huu hupokea kitambulisho cha kipekee kinachoweza kutumika kufuatilia mahali kifaa kilipo.\n"<annotation id="url">"Pata maelezo zaidi"</annotation></string>
+    <!-- no translation found for imsi_protection_warning (3207104049473134195) -->
+    <skip />
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"Polepole Sana"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"Polepole"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"Sawa"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"Wastani"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"Haraka"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"Haraka Sana"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values-ta/strings.xml b/libs/WifiTrackerLib/res/values-ta/strings.xml
index 05efc62..8b59825 100644
--- a/libs/WifiTrackerLib/res/values-ta/strings.xml
+++ b/libs/WifiTrackerLib/res/values-ta/strings.xml
@@ -46,5 +46,12 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"பதிவு செய்தல் நிறைவடைகிறது…"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"பதிவு செய்தலை நிறைவுசெய்ய முடியவில்லை. மீண்டும் முயல தட்டவும்."</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"பதிவு செய்தல் நிறைவடைந்தது. இணைக்கிறது…"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"இந்த நெட்வொர்க் ஒரு தனிப்பட்ட ஐடியைப் பெறும், சாதன இருப்பிடத்தை டிராக் செய்ய இதைப் பயன்படுத்தலாம்.\n"<annotation id="url">"மேலும் அறிக"</annotation></string>
+    <!-- no translation found for imsi_protection_warning (3207104049473134195) -->
+    <skip />
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"மிகவும் வேகம் குறைவானது"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"வேகம் குறைவு"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"சரி"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"நடுத்தரம்"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"வேகம்"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"மிகவும் வேகமானது"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values-te/strings.xml b/libs/WifiTrackerLib/res/values-te/strings.xml
index 4d8c9e7..c3cd6a3 100644
--- a/libs/WifiTrackerLib/res/values-te/strings.xml
+++ b/libs/WifiTrackerLib/res/values-te/strings.xml
@@ -46,5 +46,12 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"సైన్ అప్ పూర్తవుతోంది…"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"సైన్ అప్‌ను పూర్తి చేయడం సాధ్యపడలేదు. మళ్ళీ ప్రయత్నించడానికి ట్యాప్ చేయండి."</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"సైన్ అప్ పూర్తయింది. కనెక్ట్ చేయబడుతోంది…"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"పరికర లొకేషన్‌ను ట్రాక్ చేయడానికి ఉపయోగపడే యూనిక్ IDని ఈ నెట్‌వర్క్ అందుకుంటుంది.\n"<annotation id="url">"మరింత తెలుసుకోండి"</annotation></string>
+    <!-- no translation found for imsi_protection_warning (3207104049473134195) -->
+    <skip />
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"చాలా నెమ్మది"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"నెమ్మది"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"సరే"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"మధ్యస్థం"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"వేగవంతం"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"చాలా వేగవంతం"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values-th/strings.xml b/libs/WifiTrackerLib/res/values-th/strings.xml
index e9d280b..f67df18 100644
--- a/libs/WifiTrackerLib/res/values-th/strings.xml
+++ b/libs/WifiTrackerLib/res/values-th/strings.xml
@@ -46,5 +46,12 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"กำลังลงชื่อสมัครใช้ให้เสร็จสิ้น…"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"ลงชื่อสมัครใช้ไม่สำเร็จ แตะเพื่อลองอีกครั้ง"</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"การลงชื่อสมัครใช้เสร็จสมบูรณ์ กำลังเชื่อมต่อ…"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"เครือข่ายนี้ได้รับรหัสที่ไม่ซ้ำกันซึ่งใช้ติดตามตำแหน่งอุปกรณ์ได้\n"<annotation id="url">"ดูข้อมูลเพิ่มเติม"</annotation></string>
+    <!-- no translation found for imsi_protection_warning (3207104049473134195) -->
+    <skip />
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"ช้ามาก"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"ช้า"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"ตกลง"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"ปานกลาง"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"เร็ว"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"เร็วมาก"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values-tl/strings.xml b/libs/WifiTrackerLib/res/values-tl/strings.xml
index e185727..6bc9982 100644
--- a/libs/WifiTrackerLib/res/values-tl/strings.xml
+++ b/libs/WifiTrackerLib/res/values-tl/strings.xml
@@ -46,5 +46,12 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"Kinukumpleto ang pag-sign up…"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"Hindi makumpleto ang pag-sign up. I-tap para subukan ulit."</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"Kumpleto na ang pag-sign up. Kumokonekta…"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"Nakakatanggap ang network na ito ng natatanging ID na magagamit para sumubaybay ng lokasyon ng device.\n"<annotation id="url">"Matuto pa"</annotation></string>
+    <!-- no translation found for imsi_protection_warning (3207104049473134195) -->
+    <skip />
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"Napakabagal"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"Mabagal"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"OK"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"Katamtaman"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"Mabilis"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"Napakabilis"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values-tr/strings.xml b/libs/WifiTrackerLib/res/values-tr/strings.xml
index 0bb41cf..7218bb6 100644
--- a/libs/WifiTrackerLib/res/values-tr/strings.xml
+++ b/libs/WifiTrackerLib/res/values-tr/strings.xml
@@ -46,5 +46,12 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"Kayıt işlemi tamamlanıyor…"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"Kayıt işlemi tamamlanamadı. Tekrar denemek için dokunun."</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"Kayıt tamamlandı. Bağlanıyor…"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"Bu ağ, cihaz konumunu izlemek için kullanılabilecek benzersiz bir kimlik alır.\n"<annotation id="url">"Daha fazla bilgi"</annotation></string>
+    <!-- no translation found for imsi_protection_warning (3207104049473134195) -->
+    <skip />
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"Çok Yavaş"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"Yavaş"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"Tamam"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"Orta"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"Hızlı"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"Çok Hızlı"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values-uk/strings.xml b/libs/WifiTrackerLib/res/values-uk/strings.xml
index 48ed628..d8df718 100644
--- a/libs/WifiTrackerLib/res/values-uk/strings.xml
+++ b/libs/WifiTrackerLib/res/values-uk/strings.xml
@@ -46,5 +46,12 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"Завершення реєстрації…"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"Не вдалося завершити реєстрацію. Торкніться, щоб повторити спробу."</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"Реєстрацію завершено. Підключення…"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"Ця мережа має унікальний ідентифікатор, за допомогою якого можна відстежувати місцезнаходження пристрою.\n"<annotation id="url">"Докладніше"</annotation></string>
+    <!-- no translation found for imsi_protection_warning (3207104049473134195) -->
+    <skip />
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"Дуже повільна"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"Повільна"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"ОК"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"Середня"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"Швидка"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"Дуже швидка"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values-ur/strings.xml b/libs/WifiTrackerLib/res/values-ur/strings.xml
index 3abcbdb..aaad801 100644
--- a/libs/WifiTrackerLib/res/values-ur/strings.xml
+++ b/libs/WifiTrackerLib/res/values-ur/strings.xml
@@ -46,5 +46,12 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"سائن اپ مکمل ہو رہا ہے…"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"سائن اپ مکمل نہیں ہو سکا۔ دوبارہ کوشش کرنے کے لیے تھپتھپائیں۔"</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"سائن اپ مکمل ہو گیا۔ منسلک ہو رہا ہے…"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"‏اس نیٹ ورک کو ایک منفرد ID موصول ہوتی ہے جو آلہ کے مقام کو ٹریک کرنے کیلئے استعمال ہوسکتی ہے۔\n"<annotation id="url">"مزید جانیں"</annotation></string>
+    <!-- no translation found for imsi_protection_warning (3207104049473134195) -->
+    <skip />
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"بہت سست"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"سست"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"ٹھیک ہے"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"متوسط"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"تیز"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"بہت تیز"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values-uz/strings.xml b/libs/WifiTrackerLib/res/values-uz/strings.xml
index c19bf53..bd188d7 100644
--- a/libs/WifiTrackerLib/res/values-uz/strings.xml
+++ b/libs/WifiTrackerLib/res/values-uz/strings.xml
@@ -46,5 +46,12 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"Registratsiya tamomlanmoqda…"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"Registratsiya tamomlanmadi. Qayta urinish uchun tegining."</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"Registratsiya qilindi. Ulanmoqda…"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"Bu tarmoqqa qurilma joylashuvini aniqlash imkonini beruvchi maxsus identifikator beriladi.\n"<annotation id="url">"Batafsil"</annotation></string>
+    <!-- no translation found for imsi_protection_warning (3207104049473134195) -->
+    <skip />
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"Juda sekin"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"Sekin"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"OK"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"O‘rtacha"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"Tez"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"Juda tez"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values-vi/strings.xml b/libs/WifiTrackerLib/res/values-vi/strings.xml
index e9e049a..d0b9fe9 100644
--- a/libs/WifiTrackerLib/res/values-vi/strings.xml
+++ b/libs/WifiTrackerLib/res/values-vi/strings.xml
@@ -46,5 +46,12 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"Đang hoàn tất việc đăng ký…"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"Không thể hoàn tất việc đăng ký. Hãy nhấn để thử lại."</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"Đã đăng ký xong. Đang kết nối…"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"Mạng này nhận được một mã nhận dạng có thể dùng để theo dõi vị trí thiết bị.\n"<annotation id="url">"Tìm hiểu thêm"</annotation></string>
+    <!-- no translation found for imsi_protection_warning (3207104049473134195) -->
+    <skip />
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"Rất chậm"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"Chậm"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"Khá tốt"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"Trung bình"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"Nhanh"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"Rất nhanh"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values-zh-rCN/strings.xml b/libs/WifiTrackerLib/res/values-zh-rCN/strings.xml
index 5f26a48..1a30722 100644
--- a/libs/WifiTrackerLib/res/values-zh-rCN/strings.xml
+++ b/libs/WifiTrackerLib/res/values-zh-rCN/strings.xml
@@ -46,5 +46,12 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"正在完成注册…"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"无法完成注册。点按即可重试。"</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"注册完毕。正在连接…"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"此网络会接收可用于追踪设备位置的唯一 ID。\n"<annotation id="url">"了解详情"</annotation></string>
+    <!-- no translation found for imsi_protection_warning (3207104049473134195) -->
+    <skip />
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"很慢"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"慢"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"良好"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"适中"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"快"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"很快"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values-zh-rHK/strings.xml b/libs/WifiTrackerLib/res/values-zh-rHK/strings.xml
index 36e3d35..51ff1e2 100644
--- a/libs/WifiTrackerLib/res/values-zh-rHK/strings.xml
+++ b/libs/WifiTrackerLib/res/values-zh-rHK/strings.xml
@@ -46,5 +46,12 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"正在完成申請…"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"無法完成申請。輕按即可重試。"</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"已完成申請。連接中…"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"此網絡會收到可用於追蹤裝置位置的獨特 ID。\n"<annotation id="url">"瞭解詳情"</annotation></string>
+    <!-- no translation found for imsi_protection_warning (3207104049473134195) -->
+    <skip />
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"非常慢"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"慢"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"良好"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"適中"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"快"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"非常快"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values-zh-rTW/strings.xml b/libs/WifiTrackerLib/res/values-zh-rTW/strings.xml
index 8cd9a49..0527b99 100644
--- a/libs/WifiTrackerLib/res/values-zh-rTW/strings.xml
+++ b/libs/WifiTrackerLib/res/values-zh-rTW/strings.xml
@@ -46,5 +46,12 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"正在完成註冊程序…"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"無法完成註冊程序。輕觸即可重試。"</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"註冊完成。連線中…"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"這個網路會收到可用來追蹤裝置位置的唯一識別碼。\n"<annotation id="url">"瞭解詳情"</annotation></string>
+    <!-- no translation found for imsi_protection_warning (3207104049473134195) -->
+    <skip />
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"非常慢"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"慢"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"確定"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"適中"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"快"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"非常快"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values-zu/strings.xml b/libs/WifiTrackerLib/res/values-zu/strings.xml
index 821c2e7..cf5c4c2 100644
--- a/libs/WifiTrackerLib/res/values-zu/strings.xml
+++ b/libs/WifiTrackerLib/res/values-zu/strings.xml
@@ -46,5 +46,12 @@
     <string name="osu_completing_sign_up" msgid="7188493241442946231">"Iqedela ukubhalisa…"</string>
     <string name="osu_sign_up_failed" msgid="2725057866968590279">"Ayikwazanga ukuqedelela ukubhalisa. Thepha ukuze uzame futhi."</string>
     <string name="osu_sign_up_complete" msgid="7013805426618985953">"Ukubhalisa kuqediwe. Iyaxhuma…"</string>
-    <string name="imsi_protection_warning" msgid="3771878632537231149">"Le nethiwekhi ithola i-ID ehlukile engasetshenziselwa ukulandelela indawo yedivayisi.\n"<annotation id="url">"Funda kabanzi"</annotation></string>
+    <!-- no translation found for imsi_protection_warning (3207104049473134195) -->
+    <skip />
+    <string name="speed_label_very_slow" msgid="2401582671941367179">"Phansi kakhulu"</string>
+    <string name="speed_label_slow" msgid="8410385703344502127">"Phansi"</string>
+    <string name="speed_label_okay" msgid="3741857805086997968">"KULUNGILE"</string>
+    <string name="speed_label_medium" msgid="3175703848952862009">"Okumaphakathi"</string>
+    <string name="speed_label_fast" msgid="8344116097613544322">"Sheshayo"</string>
+    <string name="speed_label_very_fast" msgid="1595806641512447877">"Kushesha kakhulu"</string>
 </resources>
diff --git a/libs/WifiTrackerLib/res/values/strings.xml b/libs/WifiTrackerLib/res/values/strings.xml
index 690ff24..c238f66 100644
--- a/libs/WifiTrackerLib/res/values/strings.xml
+++ b/libs/WifiTrackerLib/res/values/strings.xml
@@ -170,5 +170,26 @@
     <string name="osu_sign_up_complete">Sign-up complete. Connecting\u2026</string>
 
     <!-- IMSI protection warning for non-protection network [CHAR LIMIT=NONE] -->
-    <string name="imsi_protection_warning">This network receives a unique ID that can be used to track device location.\n<annotation id="url">Learn more</annotation></string>
+    <string name="imsi_protection_warning">This network receives a unique ID that can be used to track device location. <annotation id="url">Learn more</annotation></string>
+
+    <!-- Help URL, IMSI protection [DO NOT TRANSLATE] -->
+    <string name="help_url_imsi_protection" translatable="false"></string>
+
+    <!-- Speed label for very slow network speed -->
+    <string name="speed_label_very_slow">Very Slow</string>
+
+    <!-- Speed label for slow network speed -->
+    <string name="speed_label_slow">Slow</string>
+
+    <!-- Speed label for okay network speed -->
+    <string name="speed_label_okay">OK</string>
+
+    <!-- Speed label for medium network speed -->
+    <string name="speed_label_medium">Medium</string>
+
+    <!-- Speed label for fast network speed -->
+    <string name="speed_label_fast">Fast</string>
+
+    <!-- Speed label for very fast network speed -->
+    <string name="speed_label_very_fast">Very Fast</string>
 </resources>
diff --git a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/OsuWifiEntry.java b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/OsuWifiEntry.java
index b3b99e0..55709d1 100644
--- a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/OsuWifiEntry.java
+++ b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/OsuWifiEntry.java
@@ -130,6 +130,11 @@
     }
 
     @Override
+    public boolean isSuggestion() {
+        return false;
+    }
+
+    @Override
     public boolean isSubscription() {
         return false;
     }
diff --git a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/PasspointNetworkDetailsTracker.java b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/PasspointNetworkDetailsTracker.java
index 22d200f..21a25ec 100644
--- a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/PasspointNetworkDetailsTracker.java
+++ b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/PasspointNetworkDetailsTracker.java
@@ -45,6 +45,7 @@
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
+import java.util.Optional;
 
 /**
  * Implementation of NetworkDetailsTracker that tracks a single PasspointWifiEntry.
@@ -68,17 +69,32 @@
         super(lifecycle, context, wifiManager, connectivityManager, networkScoreManager,
                 mainHandler, workerHandler, clock, maxScanAgeMillis, scanIntervalMillis, TAG);
 
-        PasspointConfiguration passpointConfig = mWifiManager.getPasspointConfigurations().stream()
-                .filter(config -> TextUtils.equals(
-                        uniqueIdToPasspointWifiEntryKey(config.getUniqueId()), key))
-                .findAny().get();
+        Optional<PasspointConfiguration> optionalPasspointConfig =
+                mWifiManager.getPasspointConfigurations()
+                        .stream()
+                        .filter(passpointConfig -> TextUtils.equals(key,
+                                uniqueIdToPasspointWifiEntryKey(passpointConfig.getUniqueId())))
+                        .findAny();
+        if (optionalPasspointConfig.isPresent()) {
+            mChosenEntry = new PasspointWifiEntry(mContext, mMainHandler,
+                    optionalPasspointConfig.get(), mWifiManager, false /* forSavedNetworksPage */);
+        } else {
+            Optional<WifiConfiguration> optionalWifiConfig =
+                    mWifiManager.getPrivilegedConfiguredNetworks()
+                            .stream()
+                            .filter(wifiConfig -> wifiConfig.isPasspoint()
+                                    && TextUtils.equals(key,
+                                            uniqueIdToPasspointWifiEntryKey(wifiConfig.getKey())))
+                            .findAny();
+            if (optionalWifiConfig.isPresent()) {
+                mChosenEntry = new PasspointWifiEntry(mContext, mMainHandler,
+                        optionalWifiConfig.get(), mWifiManager, false /* forSavedNetworksPage */);
+            } else {
+                throw new IllegalArgumentException(
+                        "Cannot find config for given PasspointWifiEntry key!");
+            }
+        }
 
-        checkNotNull(passpointConfig,
-                "Cannot find PasspointConfiguration with matching unique identifier: "
-                        + passpointConfig.getUniqueId());
-
-        mChosenEntry = new PasspointWifiEntry(mContext, mMainHandler, passpointConfig,
-                mWifiManager, false /* forSavedNetworksPage */);
         cacheNewScanResults();
         conditionallyUpdateScanResults(true /* lastScanSucceeded */);
         conditionallyUpdateConfig();
diff --git a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/PasspointWifiEntry.java b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/PasspointWifiEntry.java
index e7ed153..9b923fa 100644
--- a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/PasspointWifiEntry.java
+++ b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/PasspointWifiEntry.java
@@ -20,14 +20,19 @@
 
 import static androidx.core.util.Preconditions.checkNotNull;
 
+import static com.android.wifitrackerlib.Utils.getAppLabel;
+import static com.android.wifitrackerlib.Utils.getAppLabelForWifiConfiguration;
 import static com.android.wifitrackerlib.Utils.getAutoConnectDescription;
 import static com.android.wifitrackerlib.Utils.getBestScanResultByLevel;
+import static com.android.wifitrackerlib.Utils.getCarrierNameForSubId;
 import static com.android.wifitrackerlib.Utils.getCurrentNetworkCapabilitiesInformation;
 import static com.android.wifitrackerlib.Utils.getDisconnectedStateDescription;
+import static com.android.wifitrackerlib.Utils.getImsiProtectionDescription;
 import static com.android.wifitrackerlib.Utils.getMeteredDescription;
 import static com.android.wifitrackerlib.Utils.getNetworkDetailedState;
 import static com.android.wifitrackerlib.Utils.getSecurityTypeFromWifiConfiguration;
 import static com.android.wifitrackerlib.Utils.getSpeedDescription;
+import static com.android.wifitrackerlib.Utils.getSubIdForConfig;
 import static com.android.wifitrackerlib.Utils.getVerboseLoggingDescription;
 
 import android.content.Context;
@@ -66,11 +71,13 @@
     private final List<ScanResult> mCurrentRoamingScanResults = new ArrayList<>();
 
     @NonNull private final String mKey;
+    @NonNull private String mFqdn;
     @NonNull private String mFriendlyName;
     @NonNull private final Context mContext;
-    @NonNull private PasspointConfiguration mPasspointConfig;
+    @Nullable
+    private PasspointConfiguration mPasspointConfig;
     @Nullable private WifiConfiguration mWifiConfig;
-    private @Security int mSecurity;
+    private @Security int mSecurity = SECURITY_EAP;
     private boolean mIsRoaming = false;
 
     private int mLevel = WIFI_LEVEL_UNREACHABLE;
@@ -81,7 +88,7 @@
     // For PasspointWifiEntry#getMeteredChoice() to return correct value right after
     // PasspointWifiEntry#setMeteredChoice(int meteredChoice), cache
     // PasspointConfiguration#getMeteredOverride() in this variable.
-    private int mMeteredOverride;
+    private int mMeteredOverride = METERED_CHOICE_AUTO;
 
     /**
      * Create a PasspointWifiEntry with the associated PasspointConfiguration
@@ -97,13 +104,36 @@
         mContext = context;
         mPasspointConfig = passpointConfig;
         mKey = uniqueIdToPasspointWifiEntryKey(passpointConfig.getUniqueId());
+        mFqdn = passpointConfig.getHomeSp().getFqdn();
         mFriendlyName = passpointConfig.getHomeSp().getFriendlyName();
-        mSecurity = SECURITY_NONE; //TODO: Should this always be Enterprise?
         mSubscriptionExpirationTimeInMillis =
                 passpointConfig.getSubscriptionExpirationTimeMillis();
         mMeteredOverride = mPasspointConfig.getMeteredOverride();
     }
 
+    /**
+     * Create a PasspointWifiEntry with the associated WifiConfiguration for use with network
+     * suggestions, since WifiManager#getAllMatchingWifiConfigs() does not provide a corresponding
+     * PasspointConfiguration.
+     */
+    PasspointWifiEntry(@NonNull Context context, @NonNull Handler callbackHandler,
+            @NonNull WifiConfiguration wifiConfig,
+            @NonNull WifiManager wifiManager,
+            boolean forSavedNetworksPage) throws IllegalArgumentException {
+        super(callbackHandler, wifiManager, forSavedNetworksPage);
+
+        checkNotNull(wifiConfig, "Cannot construct with null PasspointConfiguration!");
+        if (!wifiConfig.isPasspoint()) {
+            throw new IllegalArgumentException("Given WifiConfiguration is not for Passpoint!");
+        }
+
+        mContext = context;
+        mWifiConfig = wifiConfig;
+        mKey = uniqueIdToPasspointWifiEntryKey(wifiConfig.getKey());
+        mFqdn = wifiConfig.FQDN;
+        mFriendlyName = mWifiConfig.providerFriendlyName;
+    }
+
     @Override
     public String getKey() {
         return mKey;
@@ -134,7 +164,15 @@
                 if (concise) {
                     sj.add(mContext.getString(R.string.wifi_disconnected));
                 } else if (!mForSavedNetworksPage) {
-                    sj.add(mContext.getString(R.string.wifi_remembered));
+                    if (mWifiConfig != null && mWifiConfig.fromWifiNetworkSuggestion) {
+                        String carrierName = getCarrierNameForSubId(mContext,
+                                getSubIdForConfig(mContext, mWifiConfig));
+                        sj.add(mContext.getString(R.string.available_via_app, carrierName != null
+                                ? carrierName
+                                : getAppLabelForWifiConfiguration(mContext, mWifiConfig)));
+                    } else {
+                        sj.add(mContext.getString(R.string.wifi_remembered));
+                    }
                 }
             } else {
                 sj.add(disconnectDescription);
@@ -168,6 +206,17 @@
 
     private String getConnectStateDescription() {
         if (getConnectedState() == CONNECTED_STATE_CONNECTED) {
+            // For network suggestions
+            final String suggestionOrSpecifierPackageName = mWifiInfo != null
+                    ? mWifiInfo.getRequestingPackageName() : null;
+            if (!TextUtils.isEmpty(suggestionOrSpecifierPackageName)) {
+                String carrierName = mWifiConfig != null
+                        ? getCarrierNameForSubId(mContext, getSubIdForConfig(mContext, mWifiConfig))
+                        : null;
+                return mContext.getString(R.string.connected_via_app, carrierName != null
+                        ? carrierName
+                        : getAppLabel(mContext, suggestionOrSpecifierPackageName));
+            }
             String networkCapabilitiesinformation =
                     getCurrentNetworkCapabilitiesInformation(mContext, mNetworkCapabilities);
             if (!TextUtils.isEmpty(networkCapabilitiesinformation)) {
@@ -179,6 +228,12 @@
     }
 
     @Override
+    public CharSequence getSecondSummary() {
+        return getConnectedState() == CONNECTED_STATE_CONNECTED
+                ? getImsiProtectionDescription(mContext, mWifiConfig) : "";
+    }
+
+    @Override
     public int getLevel() {
         return mLevel;
     }
@@ -213,8 +268,14 @@
     }
 
     @Override
+    public boolean isSuggestion() {
+        // TODO(b/70983952): Fill this method in when passpoint suggestions are in
+        return mWifiConfig != null && mWifiConfig.fromWifiNetworkSuggestion;
+    }
+
+    @Override
     public boolean isSubscription() {
-        return true;
+        return mPasspointConfig != null;
     }
 
     @Override
@@ -262,11 +323,15 @@
 
     @Override
     public boolean canForget() {
-        return true;
+        return mPasspointConfig != null;
     }
 
     @Override
     public void forget(@Nullable ForgetCallback callback) {
+        if (!canForget()) {
+            return;
+        }
+
         mForgetCallback = callback;
         mWifiManager.removePasspointConfiguration(mPasspointConfig.getHomeSp().getFqdn());
         new ForgetActionListener().onSuccess();
@@ -320,11 +385,15 @@
 
     @Override
     public boolean canSetMeteredChoice() {
-        return true;
+        return mPasspointConfig != null;
     }
 
     @Override
     public void setMeteredChoice(int meteredChoice) {
+        if (!canSetMeteredChoice()) {
+            return;
+        }
+
         switch (meteredChoice) {
             case METERED_CHOICE_AUTO:
                 mMeteredOverride = WifiConfiguration.METERED_OVERRIDE_NONE;
@@ -345,18 +414,26 @@
 
     @Override
     public boolean canSetPrivacy() {
-        return true;
+        return mPasspointConfig != null;
     }
 
     @Override
     @Privacy
     public int getPrivacy() {
+        if (mPasspointConfig == null) {
+            return PRIVACY_RANDOMIZED_MAC;
+        }
+
         return mPasspointConfig.isMacRandomizationEnabled()
                 ? PRIVACY_RANDOMIZED_MAC : PRIVACY_DEVICE_MAC;
     }
 
     @Override
     public void setPrivacy(int privacy) {
+        if (!canSetPrivacy()) {
+            return;
+        }
+
         mWifiManager.setMacRandomizationSettingPasspointEnabled(
                 mPasspointConfig.getHomeSp().getFqdn(),
                 privacy == PRIVACY_DEVICE_MAC ? false : true);
@@ -364,6 +441,11 @@
 
     @Override
     public boolean isAutoJoinEnabled() {
+        // Suggestion network; use WifiConfig instead
+        if (mPasspointConfig == null && mWifiConfig != null) {
+            return mWifiConfig.allowAutojoin;
+        }
+
         return mPasspointConfig.isAutojoinEnabled();
     }
 
@@ -374,6 +456,11 @@
 
     @Override
     public void setAutoJoinEnabled(boolean enabled) {
+        if (mPasspointConfig == null && mWifiConfig != null) {
+            mWifiManager.allowAutojoin(mWifiConfig.networkId, enabled);
+            return;
+        }
+
         mWifiManager.allowAutojoinPasspoint(mPasspointConfig.getHomeSp().getFqdn(), enabled);
     }
 
@@ -394,12 +481,14 @@
     }
 
     @WorkerThread
-    void updatePasspointConfig(@NonNull PasspointConfiguration passpointConfig) {
+    void updatePasspointConfig(@Nullable PasspointConfiguration passpointConfig) {
         mPasspointConfig = passpointConfig;
-        mFriendlyName = passpointConfig.getHomeSp().getFriendlyName();
-        mSubscriptionExpirationTimeInMillis =
-                passpointConfig.getSubscriptionExpirationTimeMillis();
-        mMeteredOverride = mPasspointConfig.getMeteredOverride();
+        if (mPasspointConfig != null) {
+            mFriendlyName = passpointConfig.getHomeSp().getFriendlyName();
+            mSubscriptionExpirationTimeInMillis =
+                    passpointConfig.getSubscriptionExpirationTimeMillis();
+            mMeteredOverride = passpointConfig.getMeteredOverride();
+        }
         notifyOnUpdated();
     }
 
@@ -450,8 +539,8 @@
             return false;
         }
 
-        return TextUtils.equals(
-                wifiInfo.getPasspointFqdn(), mPasspointConfig.getHomeSp().getFqdn());
+        // Match with FQDN until WifiInfo supports returning the passpoint uniqueID
+        return TextUtils.equals(wifiInfo.getPasspointFqdn(), mFqdn);
     }
 
     @NonNull
@@ -465,4 +554,9 @@
         // TODO(b/70983952): Fill this method in.
         return "";
     }
+
+    @Override
+    String getNetworkSelectionDescription() {
+        return Utils.getNetworkSelectionDescription(mWifiConfig);
+    }
 }
diff --git a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/StandardNetworkDetailsTracker.java b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/StandardNetworkDetailsTracker.java
index 65560d6..f97ae64 100644
--- a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/StandardNetworkDetailsTracker.java
+++ b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/StandardNetworkDetailsTracker.java
@@ -175,19 +175,17 @@
     }
 
     /**
-     * Updates the tracked entry's WifiConfiguration from getConfiguredNetworks(), or sets it to
-     * null if it does not exist.
+     * Updates the tracked entry's WifiConfiguration from getPrivilegedConfiguredNetworks(), or sets
+     * it to null if it does not exist.
      */
     private void conditionallyUpdateConfig() {
-        WifiConfiguration config = mWifiManager.getConfiguredNetworks().stream()
-                .filter(savedConfig -> TextUtils.equals(
-                        wifiConfigToStandardWifiEntryKey(savedConfig), mChosenEntry.getKey()))
-                .findAny().orElse(mWifiManager.getPrivilegedConfiguredNetworks().stream()
-                        .filter(suggestedConfig -> TextUtils.equals(
-                                wifiConfigToStandardWifiEntryKey(suggestedConfig),
+        WifiConfiguration updatedConfig = mWifiManager.getPrivilegedConfiguredNetworks().stream()
+                .filter(cachedConfig -> !cachedConfig.isPasspoint()
+                        && TextUtils.equals(
+                                wifiConfigToStandardWifiEntryKey(cachedConfig),
                                 mChosenEntry.getKey()))
-                        .findAny().orElse(null));
-        mChosenEntry.updateConfig(config);
+                .findAny().orElse(null);
+        mChosenEntry.updateConfig(updatedConfig);
     }
 
     /**
diff --git a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/StandardWifiEntry.java b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/StandardWifiEntry.java
index f6c3a2b..4a1be50 100644
--- a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/StandardWifiEntry.java
+++ b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/StandardWifiEntry.java
@@ -16,6 +16,10 @@
 
 package com.android.wifitrackerlib;
 
+import static android.net.wifi.WifiConfiguration.NetworkSelectionStatus.DISABLED_AUTHENTICATION_FAILURE;
+import static android.net.wifi.WifiConfiguration.NetworkSelectionStatus.DISABLED_AUTHENTICATION_NO_CREDENTIALS;
+import static android.net.wifi.WifiConfiguration.NetworkSelectionStatus.DISABLED_BY_WRONG_PASSWORD;
+import static android.net.wifi.WifiConfiguration.NetworkSelectionStatus.NETWORK_SELECTION_ENABLED;
 import static android.net.wifi.WifiInfo.sanitizeSsid;
 
 import static androidx.core.util.Preconditions.checkNotNull;
@@ -28,6 +32,7 @@
 import static com.android.wifitrackerlib.Utils.getCarrierNameForSubId;
 import static com.android.wifitrackerlib.Utils.getCurrentNetworkCapabilitiesInformation;
 import static com.android.wifitrackerlib.Utils.getDisconnectedStateDescription;
+import static com.android.wifitrackerlib.Utils.getImsiProtectionDescription;
 import static com.android.wifitrackerlib.Utils.getMeteredDescription;
 import static com.android.wifitrackerlib.Utils.getNetworkDetailedState;
 import static com.android.wifitrackerlib.Utils.getSecurityTypeFromWifiConfiguration;
@@ -43,6 +48,7 @@
 import android.net.NetworkScorerAppData;
 import android.net.wifi.ScanResult;
 import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiConfiguration.NetworkSelectionStatus;
 import android.net.wifi.WifiInfo;
 import android.net.wifi.WifiManager;
 import android.os.Handler;
@@ -199,7 +205,7 @@
                     sj.add(mContext.getString(R.string.wifi_disconnected));
                 } else if (!mForSavedNetworksPage) {
                     // Summary for unconnected suggested network
-                    if (mWifiConfig != null && mWifiConfig.fromWifiNetworkSuggestion) {
+                    if (isSuggestion()) {
                         String carrierName = getCarrierNameForSubId(mContext,
                                 getSubIdForConfig(mContext, mWifiConfig));
                         sj.add(mContext.getString(R.string.available_via_app, carrierName != null
@@ -241,7 +247,7 @@
 
     private String getConnectStateDescription() {
         if (getConnectedState() == CONNECTED_STATE_CONNECTED) {
-            if (!isSaved()) {
+            if (!isSaved() && !isSuggestion()) {
                 // Special case for connected + ephemeral networks.
                 if (!TextUtils.isEmpty(mRecommendationServiceLabel)) {
                     return String.format(mContext.getString(R.string.connected_via_network_scorer),
@@ -273,6 +279,12 @@
     }
 
     @Override
+    public CharSequence getSecondSummary() {
+        return getConnectedState() == CONNECTED_STATE_CONNECTED
+                ? getImsiProtectionDescription(mContext, getWifiConfiguration()) : "";
+    }
+
+    @Override
     public int getLevel() {
         return mLevel;
     }
@@ -311,7 +323,12 @@
 
     @Override
     public boolean isSaved() {
-        return mWifiConfig != null;
+        return mWifiConfig != null && !mWifiConfig.isEphemeral();
+    }
+
+    @Override
+    public boolean isSuggestion() {
+        return mWifiConfig != null && mWifiConfig.fromWifiNetworkSuggestion;
     }
 
     @Override
@@ -321,10 +338,10 @@
 
     @Override
     public WifiConfiguration getWifiConfiguration() {
-        if (mWifiConfig != null && !mWifiConfig.fromWifiNetworkSuggestion) {
-            return mWifiConfig;
+        if (!isSaved()) {
+            return null;
         }
-        return null;
+        return mWifiConfig;
     }
 
     @Override
@@ -344,7 +361,11 @@
         // We should flag this network to auto-open captive portal since this method represents
         // the user manually connecting to a network (i.e. not auto-join).
         mShouldAutoOpenCaptivePortal = true;
-        if (mWifiConfig == null) {
+
+        if (isSaved() || isSuggestion()) {
+            // Saved/suggested network
+            mWifiManager.connect(mWifiConfig.networkId, new ConnectActionListener());
+        } else {
             // Unsaved network
             if (mSecurity == SECURITY_NONE
                     || mSecurity == SECURITY_OWE) {
@@ -368,9 +389,6 @@
                                     ConnectCallback.CONNECT_STATUS_FAILURE_NO_CONFIG));
                 }
             }
-        } else {
-            // Saved network
-            mWifiManager.connect(mWifiConfig.networkId, new ConnectActionListener());
         }
     }
 
@@ -525,7 +543,7 @@
 
     @Override
     public boolean canSetPrivacy() {
-        return getWifiConfiguration() != null;
+        return isSaved();
     }
 
     @Override
@@ -552,7 +570,7 @@
 
     @Override
     public boolean isAutoJoinEnabled() {
-        if (!isSaved()) {
+        if (mWifiConfig == null) {
             return false;
         }
 
@@ -561,11 +579,15 @@
 
     @Override
     public boolean canSetAutoJoinEnabled() {
-        return isSaved();
+        return isSaved() || isSuggestion();
     }
 
     @Override
     public void setAutoJoinEnabled(boolean enabled) {
+        if (!canSetAutoJoinEnabled()) {
+            return;
+        }
+
         mWifiManager.allowAutojoin(mWifiConfig.networkId, enabled);
     }
 
@@ -624,6 +646,34 @@
         return false;
     }
 
+    @Override
+    public boolean shouldEditBeforeConnect() {
+        WifiConfiguration wifiConfig = getWifiConfiguration();
+        if (wifiConfig == null) {
+            return false;
+        }
+
+        // The secured Wi-Fi entry is never connected.
+        if (getSecurity() != SECURITY_NONE && getSecurity() != SECURITY_OWE
+                && !wifiConfig.getNetworkSelectionStatus().hasEverConnected()) {
+            return true;
+        }
+
+        // The network is disabled because of one of the authentication problems.
+        NetworkSelectionStatus networkSelectionStatus = wifiConfig.getNetworkSelectionStatus();
+        if (networkSelectionStatus.getNetworkSelectionStatus() != NETWORK_SELECTION_ENABLED) {
+            if (networkSelectionStatus.getDisableReasonCounter(DISABLED_AUTHENTICATION_FAILURE) > 0
+                    || networkSelectionStatus.getDisableReasonCounter(
+                    DISABLED_BY_WRONG_PASSWORD) > 0
+                    || networkSelectionStatus.getDisableReasonCounter(
+                    DISABLED_AUTHENTICATION_NO_CREDENTIALS) > 0) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
     @WorkerThread
     void updateScanResultInfo(@Nullable List<ScanResult> scanResults)
             throws IllegalArgumentException {
@@ -746,10 +796,6 @@
         }
 
         if (mWifiConfig != null) {
-            if (mWifiConfig.fromWifiNetworkSuggestion) {
-                // Match network suggestions with SSID since the net id is prone to change.
-                return TextUtils.equals(mSsid, sanitizeSsid(wifiInfo.getSSID()));
-            }
             if (mWifiConfig.networkId == wifiInfo.getNetworkId()) {
                 return true;
             }
@@ -839,4 +885,9 @@
         description.append("}");
         return description.toString();
     }
+
+    @Override
+    String getNetworkSelectionDescription() {
+        return Utils.getNetworkSelectionDescription(getWifiConfiguration());
+    }
 }
diff --git a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/Utils.java b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/Utils.java
index 382fe02..00a8dcf 100644
--- a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/Utils.java
+++ b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/Utils.java
@@ -41,6 +41,7 @@
 import android.net.NetworkInfo.DetailedState;
 import android.net.wifi.ScanResult;
 import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiConfiguration.NetworkSelectionStatus;
 import android.os.PersistableBundle;
 import android.os.RemoteException;
 import android.os.UserHandle;
@@ -48,11 +49,19 @@
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
+import android.text.Annotation;
+import android.text.SpannableString;
+import android.text.SpannableStringBuilder;
 import android.text.TextUtils;
+import android.text.format.DateUtils;
+import android.text.style.ClickableSpan;
+import android.view.View;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
+import com.android.settingslib.HelpUtils;
+
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
@@ -436,9 +445,47 @@
             sj.add(scanResultsDescription);
         }
 
+        final String networkSelectionDescription = wifiEntry.getNetworkSelectionDescription();
+        if (!TextUtils.isEmpty(networkSelectionDescription)) {
+            sj.add(networkSelectionDescription);
+        }
+
         return sj.toString();
     }
 
+    static String getNetworkSelectionDescription(WifiConfiguration wifiConfig) {
+        if (wifiConfig == null) {
+            return "";
+        }
+
+        StringBuilder description = new StringBuilder();
+        NetworkSelectionStatus networkSelectionStatus = wifiConfig.getNetworkSelectionStatus();
+
+        if (networkSelectionStatus.getNetworkSelectionStatus() != NETWORK_SELECTION_ENABLED) {
+            description.append(" (" + networkSelectionStatus.getNetworkStatusString());
+            if (networkSelectionStatus.getDisableTime() > 0) {
+                long now = System.currentTimeMillis();
+                long elapsedSeconds = (now - networkSelectionStatus.getDisableTime()) / 1000;
+                description.append(" " + DateUtils.formatElapsedTime(elapsedSeconds));
+            }
+            description.append(")");
+        }
+
+        int maxNetworkSelectionDisableReason =
+                NetworkSelectionStatus.getMaxNetworkSelectionDisableReason();
+        for (int reason = 0; reason <= maxNetworkSelectionDisableReason; reason++) {
+            int disableReasonCounter = networkSelectionStatus.getDisableReasonCounter(reason);
+            if (disableReasonCounter == 0) {
+                continue;
+            }
+            description.append(" ")
+                    .append(NetworkSelectionStatus.getNetworkSelectionDisableReasonString(reason))
+                    .append("=")
+                    .append(disableReasonCounter);
+        }
+        return description.toString();
+    }
+
     static String getCurrentNetworkCapabilitiesInformation(Context context,
             NetworkCapabilities networkCapabilities) {
         if (context == null || networkCapabilities == null) {
@@ -566,4 +613,46 @@
         return (bundle.getInt(CarrierConfigManager.IMSI_KEY_AVAILABILITY_INT)
                 & TelephonyManager.KEY_TYPE_WLAN) != 0;
     }
+
+    static CharSequence getImsiProtectionDescription(Context context,
+            @Nullable WifiConfiguration wifiConfig) {
+        if (context == null || wifiConfig == null || !isSimCredential(wifiConfig)) {
+            return "";
+        }
+
+        int subId = getSubIdForConfig(context, wifiConfig);
+        if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID
+                || isImsiPrivacyProtectionProvided(context, subId)) {
+            return "";
+        }
+
+        // IMSI protection is not provided, return warning message.
+        return linkifyAnnotation(context, context.getText(R.string.imsi_protection_warning), "url",
+                context.getString(R.string.help_url_imsi_protection));
+    }
+
+    /** Find the annotation of specified id in rawText and linkify it with helpUriString. */
+    static CharSequence linkifyAnnotation(Context context, CharSequence rawText, String id,
+            String helpUriString) {
+        SpannableString spannableText = new SpannableString(rawText);
+        Annotation[] annotations = spannableText.getSpans(0, spannableText.length(),
+                Annotation.class);
+
+        for (Annotation annotation : annotations) {
+            if (TextUtils.equals(annotation.getValue(), id)) {
+                SpannableStringBuilder builder = new SpannableStringBuilder(spannableText);
+                ClickableSpan link = new ClickableSpan() {
+                    @Override
+                    public void onClick(View view) {
+                        view.startActivityForResult(HelpUtils.getHelpIntent(context, helpUriString,
+                                view.getClass().getName()), 0);
+                    }
+                };
+                builder.setSpan(link, spannableText.getSpanStart(annotation),
+                        spannableText.getSpanEnd(annotation), spannableText.getSpanFlags(link));
+                return builder;
+            }
+        }
+        return rawText;
+    }
 }
diff --git a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/WifiEntry.java b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/WifiEntry.java
index afe8b5f..fb43d4b 100644
--- a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/WifiEntry.java
+++ b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/WifiEntry.java
@@ -165,14 +165,14 @@
     public static final int MAX_FREQ_5GHZ = 5900;
 
     /**
-     * Min bound on the 6.0 GHz (802.11ad/ay) WLAN channels.
+     * Min bound on the 6.0 GHz (802.11ax) WLAN channels.
      */
-    public static final int MIN_FREQ_6GHZ = 5700;
+    public static final int MIN_FREQ_6GHZ = 5925;
 
     /**
-     * Max bound on the 6.0 GHz (802.11ad/ay) WLAN channels.
+     * Max bound on the 6.0 GHz (802.11ax) WLAN channels.
      */
-    public static final int MAX_FREQ_6GHZ = 7100;
+    public static final int MAX_FREQ_6GHZ = 7125;
 
     /**
      * Max ScanResult information displayed of Wi-Fi Verbose Logging.
@@ -246,6 +246,11 @@
         return getSummary(true /* concise */);
     }
 
+    /** Returns the second summary, it's for additional information of the WifiEntry */
+    public CharSequence getSecondSummary() {
+        return "";
+    }
+
     /**
      * Returns the display summary.
      * @param concise Whether to show more information. e.g., verbose logging.
@@ -287,6 +292,11 @@
     public abstract boolean isSaved();
 
     /**
+     * Indicates whether or not an entry is for a saved configuration.
+     */
+    public abstract boolean isSuggestion();
+
+    /**
      * Indicates whether or not an entry is for a subscription.
      */
     public abstract boolean isSubscription();
@@ -418,6 +428,20 @@
     /** Returns the ScanResult information of a WifiEntry */
     abstract String getScanResultDescription();
 
+    /** Returns the network selection information of a WifiEntry */
+    String getNetworkSelectionDescription() {
+        return "";
+    }
+
+    /**
+     * In Wi-Fi picker, when users click a saved network, it will connect to the Wi-Fi network.
+     * However, for some special cases, Wi-Fi picker should show Wi-Fi editor UI for users to edit
+     * security or password before connecting. Or users will always get connection fail results.
+     */
+    public boolean shouldEditBeforeConnect() {
+        return false;
+    }
+
     /**
      * Sets the callback listener for WifiEntryCallback methods.
      * Subsequent calls will overwrite the previous listener.
@@ -729,6 +753,9 @@
         if (isSaved() && !other.isSaved()) return -1;
         if (!isSaved() && other.isSaved()) return 1;
 
+        if (isSuggestion() && !other.isSuggestion()) return -1;
+        if (!isSuggestion() && other.isSuggestion()) return 1;
+
         if (getLevel() > other.getLevel()) return -1;
         if (getLevel() < other.getLevel()) return 1;
 
@@ -749,6 +776,12 @@
                 .append(getTitle())
                 .append(",summary:")
                 .append(getSummary())
+                .append(",isSaved:")
+                .append(isSaved())
+                .append(",isSubscription:")
+                .append(isSubscription())
+                .append(",isSuggestion:")
+                .append(isSuggestion())
                 .append(",level:")
                 .append(getLevel())
                 .append(",security:")
diff --git a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/WifiPickerTracker.java b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/WifiPickerTracker.java
index c48ca73..6e74e2e 100644
--- a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/WifiPickerTracker.java
+++ b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/WifiPickerTracker.java
@@ -67,6 +67,7 @@
 import java.util.TreeSet;
 import java.util.function.Function;
 import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 /**
  * Wi-Fi tracker that provides all Wi-Fi related data to the Wi-Fi picker page.
@@ -107,6 +108,8 @@
     // Cache containing visible OsuWifiEntries. Must be accessed only by the worker thread.
     private final Map<String, OsuWifiEntry> mOsuWifiEntryCache = new HashMap<>();
 
+    private int mNumSavedNetworks;
+
     /**
      * Constructor for WifiPickerTracker.
      *
@@ -164,7 +167,7 @@
      */
     @AnyThread
     public int getNumSavedNetworks() {
-        return mWifiConfigCache.size();
+        return mNumSavedNetworks;
     }
 
     /**
@@ -178,10 +181,8 @@
     @WorkerThread
     @Override
     protected void handleOnStart() {
-        updateStandardWifiEntryConfigs(mWifiManager.getConfiguredNetworks());
-        updateSuggestedWifiEntryConfigs(mWifiManager.getPrivilegedConfiguredNetworks().stream()
-                .filter(config -> config.fromWifiNetworkSuggestion).collect(toList()));
-        updatePasspointWifiEntryConfigs(mWifiManager.getPasspointConfigurations());
+        updateWifiConfigurations(mWifiManager.getPrivilegedConfiguredNetworks());
+        updatePasspointConfigurations(mWifiManager.getPasspointConfigurations());
         mScanResultUpdater.update(mWifiManager.getScanResults());
         conditionallyUpdateScanResults(true /* lastScanSucceeded */);
         final WifiInfo wifiInfo = mWifiManager.getConnectionInfo();
@@ -218,16 +219,13 @@
 
         final WifiConfiguration config =
                 (WifiConfiguration) intent.getExtra(WifiManager.EXTRA_WIFI_CONFIGURATION);
-        if (config != null && !config.isEphemeral() && !config.isPasspoint()) {
-            updateStandardWifiEntryConfig(
+        if (config != null && !config.isPasspoint()) {
+            updateWifiConfiguration(
                     config, (Integer) intent.getExtra(WifiManager.EXTRA_CHANGE_REASON));
         } else {
-            updateStandardWifiEntryConfigs(mWifiManager.getConfiguredNetworks());
-            updateSuggestedWifiEntryConfigs(mWifiManager.getPrivilegedConfiguredNetworks().stream()
-                    .filter((privilegedConfig) -> privilegedConfig.fromWifiNetworkSuggestion)
-                    .collect(toList()));
+            updateWifiConfigurations(mWifiManager.getPrivilegedConfiguredNetworks());
         }
-        updatePasspointWifiEntryConfigs(mWifiManager.getPasspointConfigurations());
+        updatePasspointConfigurations(mWifiManager.getPasspointConfigurations());
         // Update scans since config changes may result in different entries being shown.
         final List<ScanResult> scanResults = mScanResultUpdater.getScanResults();
         updateStandardWifiEntryScans(scanResults);
@@ -433,7 +431,7 @@
                         wifiEntry.updateConfig(mSuggestedConfigCache.get(key));
                         wifiEntry.setUserShareable(false);
                     }
-                    return !wifiEntry.isSaved();
+                    return !wifiEntry.isSuggestion();
                 });
     }
 
@@ -444,6 +442,7 @@
         Set<String> seenKeys = new TreeSet<>();
         List<Pair<WifiConfiguration, Map<Integer, List<ScanResult>>>> matchingWifiConfigs =
                 mWifiManager.getAllMatchingWifiConfigs(scanResults);
+
         for (Pair<WifiConfiguration, Map<Integer, List<ScanResult>>> pair : matchingWifiConfigs) {
             final WifiConfiguration wifiConfig = pair.first;
             final List<ScanResult> homeScans =
@@ -452,16 +451,21 @@
                     pair.second.get(WifiManager.PASSPOINT_ROAMING_NETWORK);
             final String key = uniqueIdToPasspointWifiEntryKey(wifiConfig.getKey());
             seenKeys.add(key);
-            // Skip in case we don't have a Passpoint configuration for the returned unique key
-            if (!mPasspointConfigCache.containsKey(key)) {
-                continue;
-            }
 
             // Create PasspointWifiEntry if one doesn't exist for the seen key yet.
             if (!mPasspointWifiEntryCache.containsKey(key)) {
-                mPasspointWifiEntryCache.put(key, new PasspointWifiEntry(mContext,
-                        mMainHandler, mPasspointConfigCache.get(key), mWifiManager,
-                        false /* forSavedNetworksPage */));
+                if (wifiConfig.fromWifiNetworkSuggestion) {
+                    mPasspointWifiEntryCache.put(key, new PasspointWifiEntry(mContext,
+                            mMainHandler, wifiConfig, mWifiManager,
+                            false /* forSavedNetworksPage */));
+                } else if (mPasspointConfigCache.containsKey(key)) {
+                    mPasspointWifiEntryCache.put(key, new PasspointWifiEntry(mContext,
+                            mMainHandler, mPasspointConfigCache.get(key), mWifiManager,
+                            false /* forSavedNetworksPage */));
+                } else {
+                    // Failed to find PasspointConfig for a provisioned Passpoint network
+                    continue;
+                }
             }
             mPasspointWifiEntryCache.get(key).updateScanResultInfo(wifiConfig,
                     homeScans, roamingScans);
@@ -533,66 +537,87 @@
     }
 
     /**
-     * Updates a single WifiConfiguration for the corresponding StandardWifiEntry if it exists.
+     * Updates the WifiConfiguration caches for a single saved/ephemeral/suggested network and
+     * updates the corresponding WifiEntry with the new config.
      *
      * @param config WifiConfiguration to update
      * @param changeReason WifiManager.CHANGE_REASON_ADDED, WifiManager.CHANGE_REASON_REMOVED, or
      *                     WifiManager.CHANGE_REASON_CONFIG_CHANGE
      */
     @WorkerThread
-    private void updateStandardWifiEntryConfig(@NonNull WifiConfiguration config,
+    private void updateWifiConfiguration(@NonNull WifiConfiguration config,
             int changeReason) {
         checkNotNull(config, "Config should not be null!");
 
         final String key = wifiConfigToStandardWifiEntryKey(config);
-        final StandardWifiEntry entry = mStandardWifiEntryCache.get(key);
-
-        if (entry != null) {
+        StandardWifiEntry updatedEntry;
+        WifiConfiguration updatedConfig;
+        if (config.fromWifiNetworkSuggestion) {
+            if (changeReason == WifiManager.CHANGE_REASON_REMOVED) {
+                mSuggestedConfigCache.remove(key);
+            } else { // CHANGE_REASON_ADDED || CHANGE_REASON_CONFIG_CHANGE
+                mSuggestedConfigCache.put(key, config);
+            }
+            updatedConfig = mSuggestedConfigCache.get(key);
+            updatedEntry = mSuggestedWifiEntryCache.get(key);
+        } else {
             if (changeReason == WifiManager.CHANGE_REASON_REMOVED) {
                 mWifiConfigCache.remove(key);
             } else { // CHANGE_REASON_ADDED || CHANGE_REASON_CONFIG_CHANGE
                 mWifiConfigCache.put(key, config);
             }
-            entry.updateConfig(mWifiConfigCache.get(key));
+            updatedConfig = mWifiConfigCache.get(key);
+            updatedEntry = mStandardWifiEntryCache.get(key);
+            mNumSavedNetworks = (int) mWifiConfigCache.values().stream()
+                    .filter(cachedConfig ->
+                            !cachedConfig.isEphemeral() && !cachedConfig.isPasspoint()).count();
+        }
+
+        if (updatedEntry != null) {
+            updatedEntry.updateConfig(updatedConfig);
         }
     }
 
     /**
-     * Updates all saved WifiConfigurations for the corresponding StandardWifiEntries if they exist.
+     * Updates the WifiConfiguration caches for saved/ephemeral/suggested networks and updates the
+     * corresponding WifiEntries with the new configs.
      *
-     * @param configs List of saved WifiConfigurations
+     * @param configs List of all saved/ephemeral/suggested WifiConfigurations
      */
     @WorkerThread
-    private void updateStandardWifiEntryConfigs(@NonNull List<WifiConfiguration> configs) {
+    private void updateWifiConfigurations(@NonNull List<WifiConfiguration> configs) {
         checkNotNull(configs, "Config list should not be null!");
         mWifiConfigCache.clear();
-        mWifiConfigCache.putAll(configs.stream().collect(Collectors.toMap(
-                StandardWifiEntry::wifiConfigToStandardWifiEntryKey,
-                Function.identity())));
+        mSuggestedConfigCache.clear();
+        for (WifiConfiguration config : configs) {
+            if (config.fromWifiNetworkSuggestion) {
+                mSuggestedConfigCache.put(wifiConfigToStandardWifiEntryKey(config), config);
+            } else {
+                mWifiConfigCache.put(wifiConfigToStandardWifiEntryKey(config), config);
+            }
+        }
+        mNumSavedNetworks = (int) mWifiConfigCache.values().stream()
+                .filter(cachedConfig ->
+                    !cachedConfig.isEphemeral() && !cachedConfig.isPasspoint()).count();
 
         // Iterate through current entries and update each entry's config
         mStandardWifiEntryCache.entrySet().forEach((entry) -> {
             final StandardWifiEntry wifiEntry = entry.getValue();
             final String key = wifiEntry.getKey();
-            wifiEntry.updateConfig(mWifiConfigCache.get(key));
+            final WifiConfiguration config = mWifiConfigCache.get(key);
+            if (config != null && config.isPasspoint()) {
+                return;
+            }
+            wifiEntry.updateConfig(config);
         });
-    }
 
-    @WorkerThread
-    private void updateSuggestedWifiEntryConfigs(@NonNull List<WifiConfiguration> configs) {
-        checkNotNull(configs, "Config list should not be null!");
-        mSuggestedConfigCache.clear();
-        mSuggestedConfigCache.putAll(configs.stream().collect(Collectors.toMap(
-                StandardWifiEntry::wifiConfigToStandardWifiEntryKey,
-                Function.identity())));
-
-        // Iterate through current entries and update each entry's config
+        // Iterate through current suggestion entries and update each entry's config
         mSuggestedWifiEntryCache.entrySet().removeIf((entry) -> {
             final StandardWifiEntry wifiEntry = entry.getValue();
             final String key = wifiEntry.getKey();
-            final WifiConfiguration cachedConfig = mSuggestedConfigCache.get(key);
-            if (cachedConfig != null) {
-                wifiEntry.updateConfig(cachedConfig);
+            final WifiConfiguration config = mSuggestedConfigCache.get(key);
+            if (config != null && !config.isPasspoint()) {
+                wifiEntry.updateConfig(config);
                 return false;
             } else {
                 return true;
@@ -601,7 +626,7 @@
     }
 
     @WorkerThread
-    private void updatePasspointWifiEntryConfigs(@NonNull List<PasspointConfiguration> configs) {
+    private void updatePasspointConfigurations(@NonNull List<PasspointConfiguration> configs) {
         checkNotNull(configs, "Config list should not be null!");
         mPasspointConfigCache.clear();
         mPasspointConfigCache.putAll(configs.stream().collect(
@@ -613,13 +638,8 @@
         mPasspointWifiEntryCache.entrySet().removeIf((entry) -> {
             final PasspointWifiEntry wifiEntry = entry.getValue();
             final String key = wifiEntry.getKey();
-            final PasspointConfiguration cachedConfig = mPasspointConfigCache.get(key);
-            if (cachedConfig != null) {
-                wifiEntry.updatePasspointConfig(cachedConfig);
-                return false;
-            } else {
-                return true;
-            }
+            wifiEntry.updatePasspointConfig(mPasspointConfigCache.get(key));
+            return !wifiEntry.isSubscription() && !wifiEntry.isSuggestion();
         });
     }
 
@@ -691,11 +711,11 @@
             return;
         }
 
+        final int connectedNetId = wifiInfo.getNetworkId();
         mSuggestedConfigCache.values().stream()
                 .filter(config ->
-                        TextUtils.equals(config.SSID, wifiInfo.getSSID())
-                                && !mSuggestedWifiEntryCache.containsKey(
-                                        wifiConfigToStandardWifiEntryKey(config)))
+                    config.networkId == connectedNetId && !mSuggestedWifiEntryCache.containsKey(
+                        wifiConfigToStandardWifiEntryKey(config)))
                 .findAny().ifPresent(config -> {
                     final StandardWifiEntry connectedEntry =
                             new StandardWifiEntry(mContext, mMainHandler,
@@ -720,20 +740,24 @@
             return;
         }
 
-        // TODO(b/148556276): This logic will match the fqdn of the connected passpoint network to
-        // the first PasspointConfiguration found. This may or may not represent the actual
-        // connection, so we will need to use WifiInfo.getPasspointUniqueId() once it is ready to be
-        // a public API.
-        final String connectedFqdn = wifiInfo.getPasspointFqdn();
-        mPasspointConfigCache.values().stream()
-                .filter(config ->
-                        TextUtils.equals(config.getHomeSp().getFqdn(), connectedFqdn)
-                                && !mPasspointWifiEntryCache.containsKey(
-                                        uniqueIdToPasspointWifiEntryKey(config.getUniqueId())))
-                .findAny().ifPresent(config -> {
-                    final PasspointWifiEntry connectedEntry =
-                            new PasspointWifiEntry(mContext, mMainHandler, config, mWifiManager,
-                                    false /* forSavedNetworksPage */);
+        final int connectedNetId = wifiInfo.getNetworkId();
+        Stream.concat(mWifiConfigCache.values().stream(), mSuggestedConfigCache.values().stream())
+                .filter(wifiConfig ->
+                    wifiConfig.isPasspoint() && wifiConfig.networkId == connectedNetId
+                        && !mPasspointWifiEntryCache.containsKey(
+                                uniqueIdToPasspointWifiEntryKey(wifiConfig.getKey())))
+                .findAny().ifPresent(wifiConfig -> {
+                    PasspointConfiguration passpointConfig = mPasspointConfigCache.get(
+                            uniqueIdToPasspointWifiEntryKey(wifiConfig.getKey()));
+                    PasspointWifiEntry connectedEntry;
+                    if (passpointConfig != null) {
+                        connectedEntry = new PasspointWifiEntry(mContext, mMainHandler,
+                                passpointConfig, mWifiManager, false /* forSavedNetworksPage */);
+                    } else {
+                        // Suggested PasspointWifiEntry without a corresponding Passpoint config
+                        connectedEntry = new PasspointWifiEntry(mContext, mMainHandler,
+                                wifiConfig, mWifiManager, false /* forSavedNetworksPage */);
+                    }
                     connectedEntry.updateConnectionInfo(wifiInfo, networkInfo);
                     mPasspointWifiEntryCache.put(connectedEntry.getKey(), connectedEntry);
                 });
diff --git a/libs/WifiTrackerLib/tests/Android.bp b/libs/WifiTrackerLib/tests/Android.bp
index 0abd401..a9c51e7 100644
--- a/libs/WifiTrackerLib/tests/Android.bp
+++ b/libs/WifiTrackerLib/tests/Android.bp
@@ -22,6 +22,7 @@
         "mockito-target-minus-junit4",
         "truth-prebuilt",
         "WifiTrackerLib",
+        "Robolectric_all-target",
     ],
 
     libs: [
diff --git a/libs/WifiTrackerLib/tests/src/com/android/wifitrackerlib/StandardWifiEntryTest.java b/libs/WifiTrackerLib/tests/src/com/android/wifitrackerlib/StandardWifiEntryTest.java
index e7d1260..63b096e 100644
--- a/libs/WifiTrackerLib/tests/src/com/android/wifitrackerlib/StandardWifiEntryTest.java
+++ b/libs/WifiTrackerLib/tests/src/com/android/wifitrackerlib/StandardWifiEntryTest.java
@@ -16,6 +16,12 @@
 
 package com.android.wifitrackerlib;
 
+import static android.net.wifi.WifiConfiguration.NetworkSelectionStatus.DISABLED_AUTHENTICATION_FAILURE;
+import static android.net.wifi.WifiConfiguration.NetworkSelectionStatus.DISABLED_AUTHENTICATION_NO_CREDENTIALS;
+import static android.net.wifi.WifiConfiguration.NetworkSelectionStatus.DISABLED_BY_WRONG_PASSWORD;
+import static android.net.wifi.WifiConfiguration.NetworkSelectionStatus.NETWORK_SELECTION_PERMANENTLY_DISABLED;
+import static android.net.wifi.WifiConfiguration.NetworkSelectionStatus.NETWORK_SELECTION_TEMPORARY_DISABLED;
+
 import static com.android.wifitrackerlib.StandardWifiEntry.ssidAndSecurityToStandardWifiEntryKey;
 import static com.android.wifitrackerlib.StandardWifiEntry.wifiConfigToStandardWifiEntryKey;
 import static com.android.wifitrackerlib.TestUtils.buildScanResult;
@@ -23,6 +29,7 @@
 import static com.android.wifitrackerlib.WifiEntry.CONNECTED_STATE_DISCONNECTED;
 import static com.android.wifitrackerlib.WifiEntry.SECURITY_EAP;
 import static com.android.wifitrackerlib.WifiEntry.SECURITY_NONE;
+import static com.android.wifitrackerlib.WifiEntry.SECURITY_OWE;
 import static com.android.wifitrackerlib.WifiEntry.SECURITY_PSK;
 import static com.android.wifitrackerlib.WifiEntry.SECURITY_WEP;
 import static com.android.wifitrackerlib.WifiEntry.WIFI_LEVEL_UNREACHABLE;
@@ -31,6 +38,7 @@
 
 import static org.junit.Assert.fail;
 import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.eq;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
@@ -48,6 +56,7 @@
 import android.net.NetworkScoreManager;
 import android.net.wifi.ScanResult;
 import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiConfiguration.NetworkSelectionStatus;
 import android.net.wifi.WifiInfo;
 import android.net.wifi.WifiManager;
 import android.os.Handler;
@@ -664,4 +673,98 @@
 
         verify(mMockConnectivityManager, times(1)).startCaptivePortalApp(any());
     }
+
+    @Test
+    public void testShouldEditBeforeConnect_nullWifiConfig_returnFalse() {
+        StandardWifiEntry entry = new StandardWifiEntry(mMockContext, mTestHandler,
+                ssidAndSecurityToStandardWifiEntryKey("ssid", SECURITY_EAP),
+                mMockWifiManager, false /* forSavedNetworksPage */);
+
+        assertThat(entry.shouldEditBeforeConnect()).isFalse();
+    }
+
+    @Test
+    public void testShouldEditBeforeConnect_openNetwork_returnFalse() {
+        // Test open networks.
+        WifiConfiguration wifiConfig = new WifiConfiguration();
+        wifiConfig.SSID = "\"ssid\"";
+        wifiConfig.setSecurityParams(WifiConfiguration.SECURITY_TYPE_OPEN);
+        StandardWifiEntry entry = new StandardWifiEntry(mMockContext, mTestHandler,
+                ssidAndSecurityToStandardWifiEntryKey("ssid", SECURITY_NONE),
+                wifiConfig, mMockWifiManager, false /* forSavedNetworksPage */);
+
+        assertThat(entry.shouldEditBeforeConnect()).isFalse();
+
+        // Test enhanced open networks.
+        wifiConfig.setSecurityParams(WifiConfiguration.SECURITY_TYPE_OWE);
+        entry = new StandardWifiEntry(mMockContext, mTestHandler,
+                ssidAndSecurityToStandardWifiEntryKey("ssid", SECURITY_OWE),
+                wifiConfig, mMockWifiManager, false /* forSavedNetworksPage */);
+
+        assertThat(entry.shouldEditBeforeConnect()).isFalse();
+    }
+
+    @Test
+    public void testShouldEditBeforeConnect_securedNetwork_returnTrueIfNeverConnected() {
+        // Test never connected.
+        WifiConfiguration wifiConfig = spy(new WifiConfiguration());
+        wifiConfig.SSID = "\"ssid\"";
+        wifiConfig.setSecurityParams(WifiConfiguration.SECURITY_TYPE_PSK);
+        StandardWifiEntry entry = new StandardWifiEntry(mMockContext, mTestHandler,
+                ssidAndSecurityToStandardWifiEntryKey("ssid", SECURITY_PSK),
+                wifiConfig, mMockWifiManager, false /* forSavedNetworksPage */);
+        NetworkSelectionStatus networkSelectionStatus =
+                spy(new NetworkSelectionStatus.Builder().build());
+        doReturn(networkSelectionStatus).when(wifiConfig).getNetworkSelectionStatus();
+
+        assertThat(entry.shouldEditBeforeConnect()).isTrue();
+
+        // Test ever connected.
+        doReturn(true).when(networkSelectionStatus).hasEverConnected();
+
+        assertThat(entry.shouldEditBeforeConnect()).isFalse();
+    }
+
+    @Test
+    public void testShouldEditBeforeConnect_authenticationFailure_returnTrue() {
+        // Test DISABLED_AUTHENTICATION_FAILURE.
+        WifiConfiguration wifiConfig = spy(new WifiConfiguration());
+        wifiConfig.SSID = "\"ssid\"";
+        wifiConfig.setSecurityParams(WifiConfiguration.SECURITY_TYPE_PSK);
+        StandardWifiEntry entry = new StandardWifiEntry(mMockContext, mTestHandler,
+                ssidAndSecurityToStandardWifiEntryKey("ssid", SECURITY_PSK),
+                wifiConfig, mMockWifiManager, false /* forSavedNetworksPage */);
+        NetworkSelectionStatus.Builder statusBuilder = new NetworkSelectionStatus.Builder();
+        NetworkSelectionStatus networkSelectionStatus = spy(statusBuilder.setNetworkSelectionStatus(
+                NETWORK_SELECTION_TEMPORARY_DISABLED)
+                .setNetworkSelectionDisableReason(
+                DISABLED_AUTHENTICATION_FAILURE)
+                .build());
+        doReturn(1).when(networkSelectionStatus).getDisableReasonCounter(
+                DISABLED_AUTHENTICATION_FAILURE);
+        doReturn(true).when(networkSelectionStatus).hasEverConnected();
+        doReturn(networkSelectionStatus).when(wifiConfig).getNetworkSelectionStatus();
+
+        assertThat(entry.shouldEditBeforeConnect()).isTrue();
+
+        // Test DISABLED_BY_WRONG_PASSWORD.
+        networkSelectionStatus = spy(statusBuilder.setNetworkSelectionStatus(
+                NETWORK_SELECTION_PERMANENTLY_DISABLED)
+                .setNetworkSelectionDisableReason(DISABLED_BY_WRONG_PASSWORD)
+                .build());
+        doReturn(1).when(networkSelectionStatus).getDisableReasonCounter(
+                DISABLED_BY_WRONG_PASSWORD);
+
+        assertThat(entry.shouldEditBeforeConnect()).isTrue();
+
+        // Test DISABLED_AUTHENTICATION_NO_CREDENTIALS.
+        networkSelectionStatus = spy(statusBuilder.setNetworkSelectionStatus(
+                NETWORK_SELECTION_PERMANENTLY_DISABLED)
+                .setNetworkSelectionDisableReason(DISABLED_AUTHENTICATION_NO_CREDENTIALS)
+                .build());
+        doReturn(1).when(networkSelectionStatus).getDisableReasonCounter(
+                DISABLED_AUTHENTICATION_NO_CREDENTIALS);
+
+        assertThat(entry.shouldEditBeforeConnect()).isTrue();
+    }
 }
diff --git a/libs/WifiTrackerLib/tests/src/com/android/wifitrackerlib/UtilsTest.java b/libs/WifiTrackerLib/tests/src/com/android/wifitrackerlib/UtilsTest.java
index 7ed2d1a..0ee26da 100644
--- a/libs/WifiTrackerLib/tests/src/com/android/wifitrackerlib/UtilsTest.java
+++ b/libs/WifiTrackerLib/tests/src/com/android/wifitrackerlib/UtilsTest.java
@@ -23,19 +23,23 @@
 import static com.android.wifitrackerlib.Utils.getAutoConnectDescription;
 import static com.android.wifitrackerlib.Utils.getBestScanResultByLevel;
 import static com.android.wifitrackerlib.Utils.getCarrierNameForSubId;
+import static com.android.wifitrackerlib.Utils.getImsiProtectionDescription;
 import static com.android.wifitrackerlib.Utils.getMeteredDescription;
+import static com.android.wifitrackerlib.Utils.getNetworkSelectionDescription;
 import static com.android.wifitrackerlib.Utils.getSubIdForConfig;
 import static com.android.wifitrackerlib.Utils.isImsiPrivacyProtectionProvided;
 import static com.android.wifitrackerlib.Utils.isSimPresent;
+import static com.android.wifitrackerlib.Utils.linkifyAnnotation;
 import static com.android.wifitrackerlib.Utils.mapScanResultsToKey;
 import static com.android.wifitrackerlib.WifiEntry.SECURITY_NONE;
 import static com.android.wifitrackerlib.WifiEntry.SECURITY_PSK;
 
 import static com.google.common.truth.Truth.assertThat;
 
-
 import static org.junit.Assert.*;
+import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.when;
 
 import android.content.Context;
@@ -46,6 +50,8 @@
 import android.net.NetworkScoreManager;
 import android.net.wifi.ScanResult;
 import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiConfiguration.NetworkSelectionStatus;
+import android.net.wifi.WifiEnterpriseConfig;
 import android.net.wifi.WifiInfo;
 import android.net.wifi.WifiManager;
 import android.os.Handler;
@@ -55,18 +61,27 @@
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
+import android.text.Annotation;
+import android.text.SpannableString;
+import android.text.SpannableStringBuilder;
+import android.text.Spanned;
+import android.text.style.ClickableSpan;
+
+import com.android.wifitrackerlib.shadow.ShadowSystem;
 
 import org.junit.Before;
 import org.junit.Ignore;
 import org.junit.Test;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
 
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
 
+@Config(shadows = {ShadowSystem.class})
 public class UtilsTest {
     private static final String LABEL_AUTO_CONNECTION_DISABLED = "Auto-Connection disabled";
     private static final String LABEL_METERED = "Metered";
@@ -361,6 +376,72 @@
         assertEquals(TEST_SUB_ID, getSubIdForConfig(mMockContext, config));
     }
 
+    @Test
+    public void testGetImsiProtectionDescription_isSimCredentialFalse_returnEmptyString() {
+        final WifiConfiguration wificonfig = new WifiConfiguration();
+
+        assertEquals(getImsiProtectionDescription(mMockContext, wificonfig), "");
+    }
+
+    @Test
+    public void testGetImsiProtectionDescription_noValidSubId_returnEmptyString() {
+        final WifiConfiguration mockWifiConfig = mock(WifiConfiguration.class);
+        final WifiEnterpriseConfig mockWifiEnterpriseConfig = mock(WifiEnterpriseConfig.class);
+        when(mockWifiEnterpriseConfig.isAuthenticationSimBased()).thenReturn(true);
+        mockWifiConfig.enterpriseConfig = mockWifiEnterpriseConfig;
+
+        assertEquals(getImsiProtectionDescription(mMockContext, mockWifiConfig), "");
+    }
+
+    @Test
+    public void testLinkifyAnnotation_noAnnotation_returnOriginalText() {
+        final CharSequence testText = "test text";
+
+        final CharSequence output = linkifyAnnotation(mMockContext, testText, "id", "url");
+
+        final SpannableString outputSpannableString = new SpannableString(output);
+        assertEquals(output, testText);
+        assertEquals(outputSpannableString.getSpans(0, outputSpannableString.length(),
+                ClickableSpan.class).length, 0);
+    }
+
+    @Test
+    public void testLinkifyAnnotation_annotation_returnTextWithClickableSpan() {
+        final String annotationId = "id";
+        final CharSequence testText = "test text ";
+        final CharSequence testLink = "link";
+        final CharSequence expectedText = "test text link";
+        final SpannableStringBuilder builder = new SpannableStringBuilder(testText);
+        builder.append(testLink, new Annotation("key", annotationId),
+                Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+
+        final CharSequence output = linkifyAnnotation(mMockContext, builder, annotationId, "url");
+
+        final SpannableString outputSpannableString = new SpannableString(output);
+        assertEquals(output.toString(), expectedText.toString());
+        assertEquals(outputSpannableString.getSpans(0, outputSpannableString.length(),
+                ClickableSpan.class).length, 1);
+    }
+
+    @Test
+    public void testGetNetworkSelectionDescription_disabledWrongPassword_showsWrongPasswordLabel() {
+        String expected = " (NETWORK_SELECTION_TEMPORARY_DISABLED 1:02:03) "
+                + "NETWORK_SELECTION_DISABLED_BY_WRONG_PASSWORD=2";
+        WifiConfiguration wifiConfig = spy(new WifiConfiguration());
+        NetworkSelectionStatus.Builder statusBuilder = new NetworkSelectionStatus.Builder();
+        NetworkSelectionStatus networkSelectionStatus = spy(statusBuilder.setNetworkSelectionStatus(
+                NetworkSelectionStatus.NETWORK_SELECTION_TEMPORARY_DISABLED)
+                .setNetworkSelectionDisableReason(NetworkSelectionStatus.DISABLED_BY_WRONG_PASSWORD)
+                .build());
+        doReturn(2).when(networkSelectionStatus).getDisableReasonCounter(
+                NetworkSelectionStatus.DISABLED_BY_WRONG_PASSWORD);
+        long now = System.currentTimeMillis();
+        // Network selection disable time is 1:02:03 ago.
+        doReturn(now - (60 * 60 + 2 * 60 + 3) * 1000).when(networkSelectionStatus).getDisableTime();
+        when(wifiConfig.getNetworkSelectionStatus()).thenReturn(networkSelectionStatus);
+
+        assertThat(getNetworkSelectionDescription(wifiConfig)).isEqualTo(expected);
+    }
 
     private StandardWifiEntry getStandardWifiEntry(WifiConfiguration config) {
         final WifiManager mockWifiManager = mock(WifiManager.class);
diff --git a/libs/WifiTrackerLib/tests/src/com/android/wifitrackerlib/shadows/ShadowSystem.java b/libs/WifiTrackerLib/tests/src/com/android/wifitrackerlib/shadows/ShadowSystem.java
new file mode 100644
index 0000000..1ef4958
--- /dev/null
+++ b/libs/WifiTrackerLib/tests/src/com/android/wifitrackerlib/shadows/ShadowSystem.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wifitrackerlib.shadow;
+
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+
+/**
+ * A shadow object of {@link System}.
+ */
+@Implements(System.class)
+public class ShadowSystem {
+    /**
+     * Implements {@link System#currentTimeMillis}.
+     *
+     * @return a fixed time milli throughout tests.
+     */
+    @Implementation
+    public static long currentTimeMillis() {
+        // It's 2100/01/02 00:00:00.
+        return 4102531200000L;
+    }
+}
diff --git a/service/java/com/android/server/wifi/ActiveModeWarden.java b/service/java/com/android/server/wifi/ActiveModeWarden.java
index 457b687..0333458 100644
--- a/service/java/com/android/server/wifi/ActiveModeWarden.java
+++ b/service/java/com/android/server/wifi/ActiveModeWarden.java
@@ -79,6 +79,7 @@
 
     private boolean mCanRequestMoreClientModeManagers = false;
     private boolean mCanRequestMoreSoftApManagers = false;
+    private boolean mIsShuttingdown = false;
 
     /**
      * Called from WifiServiceImpl to register a callback for notifications from SoftApManager
@@ -122,7 +123,7 @@
         mWifiController = new WifiController();
 
         wifiNative.registerStatusListener(isReady -> {
-            if (!isReady) {
+            if (!isReady && !mIsShuttingdown) {
                 mHandler.post(() -> {
                     Log.e(TAG, "One of the native daemons died. Triggering recovery");
                     wifiDiagnostics.captureBugReportData(
@@ -149,6 +150,15 @@
     }
 
     /**
+     * Notify that device is shutting down
+     * Keep it simple and don't add collection access codes
+     * to avoid concurrentModificationException when it is directly called from a different thread
+     */
+    public void notifyShuttingDown() {
+        mIsShuttingdown = true;
+    }
+
+    /**
      * @return Returns whether we can create more client mode managers or not.
      */
     public boolean canRequestMoreClientModeManagers() {
diff --git a/service/java/com/android/server/wifi/AvailableNetworkNotifier.java b/service/java/com/android/server/wifi/AvailableNetworkNotifier.java
index 1ec6fba..7243193 100644
--- a/service/java/com/android/server/wifi/AvailableNetworkNotifier.java
+++ b/service/java/com/android/server/wifi/AvailableNetworkNotifier.java
@@ -438,7 +438,7 @@
             mWifiMetrics.setNominatorForNetwork(result.netId, mNominatorId);
             ConnectActionListener connectActionListener = new ConnectActionListener();
             mClientModeImpl.connect(null, result.netId, new Binder(), connectActionListener,
-                    connectActionListener.hashCode(), Process.WIFI_UID);
+                    connectActionListener.hashCode(), Process.SYSTEM_UID);
             addNetworkToBlacklist(mRecommendedNetwork.SSID);
         }
 
diff --git a/service/java/com/android/server/wifi/ClientModeImpl.java b/service/java/com/android/server/wifi/ClientModeImpl.java
index 00e02df..7314bb8 100644
--- a/service/java/com/android/server/wifi/ClientModeImpl.java
+++ b/service/java/com/android/server/wifi/ClientModeImpl.java
@@ -67,6 +67,7 @@
 import android.net.shared.Layer2Information;
 import android.net.shared.ProvisioningConfiguration;
 import android.net.shared.ProvisioningConfiguration.ScanResultInfo;
+import android.net.util.MacAddressUtils;
 import android.net.util.NetUtils;
 import android.net.wifi.IActionListener;
 import android.net.wifi.INetworkRequestMatchCallback;
@@ -1195,6 +1196,7 @@
         mWifiHealthMonitor.enableVerboseLogging(mVerboseLoggingEnabled);
         mWifiInjector.getThroughputPredictor().enableVerboseLogging(mVerboseLoggingEnabled);
         mWifiDataStall.enableVerboseLogging(mVerboseLoggingEnabled);
+        mWifiConnectivityManager.enableVerboseLogging(mVerboseLoggingEnabled);
     }
 
     /**
@@ -2692,9 +2694,14 @@
         if (mIpClient != null) {
             Pair<String, String> p = mWifiScoreCard.getL2KeyAndGroupHint(mWifiInfo);
             if (!p.equals(mLastL2KeyAndGroupHint)) {
+                final MacAddress lastBssid = getCurrentBssid();
                 final Layer2Information l2Information = new Layer2Information(
-                        p.first, p.second,
-                        mLastBssid != null ? MacAddress.fromString(mLastBssid) : null);
+                        p.first, p.second, lastBssid);
+                // Update current BSSID on IpClient side whenever l2Key and groupHint
+                // pair changes (i.e. the initial connection establishment or L2 roaming
+                // happened). If we have COMPLETED the roaming to a different BSSID, start
+                // doing DNAv4/DNAv6 -style probing for on-link neighbors of interest (e.g.
+                // routers/DNS servers/default gateway).
                 if (mIpClient.updateLayer2Information(l2Information)) {
                     mLastL2KeyAndGroupHint = p;
                 } else {
@@ -2978,6 +2985,31 @@
         handleConnectionAttemptEndForDiagnostics(level2FailureCode);
     }
 
+    /* If this connection attempt fails after 802.1x stage, clear intermediate cached data. */
+    void clearNetworkCachedDataIfNeeded(WifiConfiguration config, int reason) {
+        if (config == null) return;
+
+        switch(reason) {
+            case 14: // MICHAEL_MIC_FAILURE
+            case 15: // 4WAY_HANDSHAKE_TIMEOUT
+            case 16: // GROUP_KEY_UPDATE_TIMEOUT
+            case 17: // IE_IN_4WAY_DIFFERS
+            case 18: // GROUP_CIPHER_NOT_VALID
+            case 19: // PAIRWISE_CIPHER_NOT_VALID
+            case 20: // AKMP_NOT_VALID
+            case 23: // IEEE_802_1X_AUTH_FAILED
+            case 24: // CIPHER_SUITE_REJECTED
+            case 29: // BAD_CIPHER_OR_AKM
+            case 45: // PEERKEY_MISMATCH
+            case 49: // INVALID_PMKID
+                mWifiNative.removeNetworkCachedData(config.networkId);
+                break;
+            default:
+                logi("Keep PMK cache for network disconnection reason " + reason);
+                break;
+        }
+    }
+
     /**
      * Returns the sufficient RSSI for the frequency that this network is last seen on.
      */
@@ -3240,6 +3272,9 @@
             mWifiMetrics.logStaEvent(StaEvent.TYPE_MAC_CHANGE, config);
             boolean setMacSuccess =
                     mWifiNative.setMacAddress(mInterfaceName, newMac);
+            if (setMacSuccess) {
+                mWifiNative.removeNetworkCachedDataIfNeeded(config.networkId, newMac);
+            }
             Log.d(TAG, "ConnectedMacRandomization SSID(" + config.getPrintableSsid()
                     + "). setMacAddress(" + newMac.toString() + ") from "
                     + currentMacString + " = " + setMacSuccess);
@@ -3258,6 +3293,7 @@
         String currentMacStr = mWifiNative.getMacAddress(mInterfaceName);
         if (!TextUtils.equals(currentMacStr, factoryMac.toString())) {
             if (mWifiNative.setMacAddress(mInterfaceName, factoryMac)) {
+                mWifiNative.removeNetworkCachedDataIfNeeded(config.networkId, factoryMac);
                 mWifiMetrics.logStaEvent(StaEvent.TYPE_MAC_CHANGE, config);
             } else {
                 Log.e(TAG, "Failed to set MAC address to " + "'" + factoryMac.toString() + "'");
@@ -3549,6 +3585,7 @@
         mLastSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
         mLastSimBasedConnectionCarrierName = null;
         mLastSignalLevel = -1;
+        mWifiNative.setMacAddress(mInterfaceName, MacAddressUtils.createRandomUnicastAddress());
         mWifiInfo.setMacAddress(mWifiNative.getMacAddress(mInterfaceName));
         // TODO: b/79504296 This broadcast has been deprecated and should be removed
         sendSupplicantConnectionChangedBroadcast(true);
@@ -3675,6 +3712,16 @@
         return mLastBssid;
     }
 
+    MacAddress getCurrentBssid() {
+        MacAddress bssid = null;
+        try {
+            bssid = (mLastBssid != null) ? MacAddress.fromString(mLastBssid) : null;
+        } catch (IllegalArgumentException e) {
+            Log.e(TAG, "Invalid BSSID format: " + mLastBssid);
+        }
+        return bssid;
+    }
+
     void connectToNetwork(WifiConfiguration config) {
         if ((config != null) && mWifiNative.connectToNetwork(mInterfaceName, config)) {
             mWifiInjector.getWifiLastResortWatchdog().noteStartConnectTime();
@@ -3892,23 +3939,7 @@
                         transitionTo(mDisconnectedState);
                     }
 
-                    // If we have COMPLETED a connection to a BSSID, start doing
-                    // DNAv4/DNAv6 -style probing for on-link neighbors of
-                    // interest (e.g. routers); harmless if none are configured.
                     if (state == SupplicantState.COMPLETED) {
-                        if (mIpClient != null) {
-                            MacAddress lastBssid = null;
-                            try {
-                                lastBssid = (mLastBssid != null)
-                                        ? MacAddress.fromString(mLastBssid) : null;
-                            } catch (IllegalArgumentException e) {
-                                Log.e(TAG, "Invalid BSSID format: " + mLastBssid);
-                            }
-                            final Layer2Information info = new Layer2Information(
-                                    mLastL2KeyAndGroupHint.first, mLastL2KeyAndGroupHint.second,
-                                    lastBssid);
-                            mIpClient.updateLayer2Information(info);
-                        }
                         mWifiScoreReport.noteIpCheck();
                     }
                     break;
@@ -4211,6 +4242,7 @@
                     // idempotent commands are executed twice (stopping Dhcp, enabling the SPS mode
                     // at the chip etc...
                     if (mVerboseLoggingEnabled) log("ConnectModeState: Network connection lost ");
+                    clearNetworkCachedDataIfNeeded(getTargetWifiConfiguration(), message.arg2);
                     handleNetworkDisconnect();
                     transitionTo(mDisconnectedState);
                     break;
@@ -5240,6 +5272,7 @@
                                 + " BSSID=" + bssid
                                 + " target=" + target);
                     }
+                    clearNetworkCachedDataIfNeeded(getTargetWifiConfiguration(), message.arg2);
                     if (bssid != null && bssid.equals(mTargetBssid)) {
                         handleNetworkDisconnect();
                         transitionTo(mDisconnectedState);
@@ -5395,6 +5428,7 @@
                         mWifiDiagnostics.captureBugReportData(
                                 WifiDiagnostics.REPORT_REASON_UNEXPECTED_DISCONNECT);
                     }
+
                     boolean localGen = message.arg1 == 1;
                     if (!localGen) { // ignore disconnects initiated by wpa_supplicant.
                         mWifiScoreCard.noteNonlocalDisconnect(message.arg2);
@@ -5598,6 +5632,7 @@
                                         getTargetSsid(), bssid,
                                         WifiLastResortWatchdog.FAILURE_CODE_AUTHENTICATION);
                     }
+                    clearNetworkCachedDataIfNeeded(getTargetWifiConfiguration(), message.arg2);
                     break;
                 case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT:
                     StateChangeResult stateChangeResult = (StateChangeResult) message.obj;
@@ -6377,6 +6412,14 @@
                     + " isFilsConnection=" + isFilsConnection);
         }
 
+        final MacAddress currentBssid = getCurrentBssid();
+        final String l2Key = mLastL2KeyAndGroupHint != null
+                ? mLastL2KeyAndGroupHint.first : null;
+        final String groupHint = mLastL2KeyAndGroupHint != null
+                ? mLastL2KeyAndGroupHint.second : null;
+        final Layer2Information layer2Info = new Layer2Information(l2Key, groupHint,
+                currentBssid);
+
         if (isFilsConnection) {
             stopIpClient();
             if (isUsingStaticIp) {
@@ -6390,6 +6433,7 @@
                     .withPreconnection()
                     .withApfCapabilities(
                     mWifiNative.getApfCapabilities(mInterfaceName))
+                    .withLayer2Information(layer2Info)
                     .build();
             mIpClient.startProvisioning(prov);
         } else {
@@ -6454,6 +6498,7 @@
                     .withNetwork(getCurrentNetwork())
                     .withDisplayName(config.SSID)
                     .withScanResultInfo(scanResultInfo)
+                    .withLayer2Information(layer2Info)
                     .build();
             } else {
                 StaticIpConfiguration staticIpConfig = config.getStaticIpConfiguration();
@@ -6462,6 +6507,7 @@
                         .withApfCapabilities(mWifiNative.getApfCapabilities(mInterfaceName))
                         .withNetwork(getCurrentNetwork())
                         .withDisplayName(config.SSID)
+                        .withLayer2Information(layer2Info)
                         .build();
             }
             mIpClient.startProvisioning(prov);
diff --git a/service/java/com/android/server/wifi/HalDeviceManager.java b/service/java/com/android/server/wifi/HalDeviceManager.java
index e47a33e..783c91a 100644
--- a/service/java/com/android/server/wifi/HalDeviceManager.java
+++ b/service/java/com/android/server/wifi/HalDeviceManager.java
@@ -2087,15 +2087,20 @@
     private void dispatchAllDestroyedListeners() {
         if (VDBG) Log.d(TAG, "dispatchAllDestroyedListeners");
 
+        List<InterfaceDestroyedListenerProxy> triggerList = new ArrayList<>();
         synchronized (mLock) {
             for (InterfaceCacheEntry cacheEntry: mInterfaceInfoCache.values()) {
                 for (InterfaceDestroyedListenerProxy listener : cacheEntry.destroyedListeners) {
-                    listener.trigger();
+                    triggerList.add(listener);
                 }
                 cacheEntry.destroyedListeners.clear(); // for insurance
             }
             mInterfaceInfoCache.clear();
         }
+
+        for (InterfaceDestroyedListenerProxy listener : triggerList) {
+            listener.trigger();
+        }
     }
 
     private abstract class ListenerProxy<LISTENER>  {
diff --git a/service/java/com/android/server/wifi/HostapdHal.java b/service/java/com/android/server/wifi/HostapdHal.java
index 418fde6..6ef0a7f 100644
--- a/service/java/com/android/server/wifi/HostapdHal.java
+++ b/service/java/com/android/server/wifi/HostapdHal.java
@@ -584,9 +584,12 @@
                     case WifiManager.SAP_CLIENT_BLOCK_REASON_CODE_NO_MORE_STAS:
                         disconnectReason = Ieee80211ReasonCode.WLAN_REASON_DISASSOC_AP_BUSY;
                         break;
-                    default:
+                    case WifiManager.SAP_CLIENT_DISCONNECT_REASON_CODE_UNSPECIFIED:
                         disconnectReason = Ieee80211ReasonCode.WLAN_REASON_UNSPECIFIED;
                         break;
+                    default:
+                        throw new IllegalArgumentException(
+                                "Unknown disconnect reason code:" + reasonCode);
                 }
                 android.hardware.wifi.hostapd.V1_2.HostapdStatus status =
                         iHostapdV1_2.forceClientDisconnect(ifaceName,
diff --git a/service/java/com/android/server/wifi/SavedNetworkNominator.java b/service/java/com/android/server/wifi/SavedNetworkNominator.java
index 2d91881..a303909 100644
--- a/service/java/com/android/server/wifi/SavedNetworkNominator.java
+++ b/service/java/com/android/server/wifi/SavedNetworkNominator.java
@@ -97,7 +97,6 @@
 
             // One ScanResult can be associated with more than one network, hence we calculate all
             // the scores and use the highest one as the ScanResult's score.
-            // TODO(b/112196799): this has side effects, rather not do that in a nominator
             WifiConfiguration network =
                     mWifiConfigManager.getConfiguredNetworkForScanDetailAndCache(scanDetail);
 
@@ -117,20 +116,21 @@
 
             // Ignore networks that the user has disallowed auto-join for.
             if (!network.allowAutojoin) {
+                localLog("Ignoring auto join disabled SSID: " + network.SSID);
                 continue;
             }
 
             WifiConfiguration.NetworkSelectionStatus status =
                     network.getNetworkSelectionStatus();
-            // TODO (b/112196799): another side effect
             status.setSeenInLastQualifiedNetworkSelection(true);
 
             if (mWifiConfigManager.isNetworkTemporarilyDisabledByUser(network.SSID)) {
-                mLocalLog.log("Ignoring user disabled SSID: " + network.SSID);
+                localLog("Ignoring user disabled SSID: " + network.SSID);
                 continue;
             }
 
             if (!status.isNetworkEnabled()) {
+                localLog("Ignoring network selection disabled SSID: " + network.SSID);
                 continue;
             }
             if (network.BSSID != null &&  !network.BSSID.equals("any")
@@ -143,6 +143,7 @@
                 continue;
             }
             if (isNetworkSimBasedCredential(network) && !isSimBasedNetworkAbleToAutoJoin(network)) {
+                localLog("Ignoring SIM auto join disabled SSID: " + network.SSID);
                 continue;
             }
 
diff --git a/service/java/com/android/server/wifi/SoftApManager.java b/service/java/com/android/server/wifi/SoftApManager.java
index 44bbc73..3bf12ca 100644
--- a/service/java/com/android/server/wifi/SoftApManager.java
+++ b/service/java/com/android/server/wifi/SoftApManager.java
@@ -16,6 +16,8 @@
 
 package com.android.server.wifi;
 
+import static android.net.wifi.WifiManager.SAP_CLIENT_DISCONNECT_REASON_CODE_UNSPECIFIED;
+
 import static com.android.server.wifi.util.ApConfigUtil.ERROR_GENERIC;
 import static com.android.server.wifi.util.ApConfigUtil.ERROR_NO_CHANNEL;
 import static com.android.server.wifi.util.ApConfigUtil.ERROR_UNSUPPORTED_CONFIGURATION;
@@ -433,9 +435,21 @@
     }
 
     /**
+     * Disconnect all connected clients on active softap interface(s).
+     * This is usually done just before stopSoftAp().
+     */
+    private void disconnectAllClients() {
+        for (WifiClient client : mConnectedClients) {
+            mWifiNative.forceClientDisconnect(mApInterfaceName, client.getMacAddress(),
+                    SAP_CLIENT_DISCONNECT_REASON_CODE_UNSPECIFIED);
+        }
+    }
+
+    /**
      * Teardown soft AP and teardown the interface.
      */
     private void stopSoftAp() {
+        disconnectAllClients();
         mWifiDiagnostics.stopLogging(mApInterfaceName);
         mWifiNative.teardownInterface(mApInterfaceName);
         Log.d(TAG, "Soft AP is stopped");
diff --git a/service/java/com/android/server/wifi/SupplicantStaIfaceCallbackImpl.java b/service/java/com/android/server/wifi/SupplicantStaIfaceCallbackImpl.java
index 2d78514..92ba43b 100644
--- a/service/java/com/android/server/wifi/SupplicantStaIfaceCallbackImpl.java
+++ b/service/java/com/android/server/wifi/SupplicantStaIfaceCallbackImpl.java
@@ -258,28 +258,35 @@
     public void onAssociationRejected(byte[/* 6 */] bssid, int statusCode, boolean timedOut) {
         synchronized (mLock) {
             mStaIfaceHal.logCallback("onAssociationRejected");
+            boolean isWrongPwd = false;
             WifiConfiguration curConfiguration =
                     mStaIfaceHal.getCurrentNetworkLocalConfig(mIfaceName);
 
-            if (curConfiguration != null && !timedOut) {
-                Log.d(TAG, "flush PMK cache due to association rejection for config id "
-                        + curConfiguration.networkId + ".");
-                mStaIfaceHal.removePmkCacheEntry(curConfiguration.networkId);
+            if (curConfiguration != null) {
+                if (!timedOut) {
+                    Log.d(TAG, "flush PMK cache due to association rejection for config id "
+                            + curConfiguration.networkId + ".");
+                    mStaIfaceHal.removePmkCacheEntry(curConfiguration.networkId);
+                }
+                // Special handling for WPA3-Personal networks. If the password is
+                // incorrect, the AP will send association rejection, with status code 1
+                // (unspecified failure). In SAE networks, the password authentication
+                // is not related to the 4-way handshake. In this case, we will send an
+                // authentication failure event up.
+                if (statusCode == StatusCode.UNSPECIFIED_FAILURE
+                        && WifiConfigurationUtil.isConfigForSaeNetwork(curConfiguration)) {
+                    mStaIfaceHal.logCallback("SAE incorrect password");
+                    isWrongPwd = true;
+                } else if (statusCode == StatusCode.CHALLENGE_FAIL
+                        && WifiConfigurationUtil.isConfigForWepNetwork(curConfiguration)) {
+                    mStaIfaceHal.logCallback("WEP incorrect password");
+                    isWrongPwd = true;
+                }
             }
 
-            if (statusCode == StatusCode.UNSPECIFIED_FAILURE) {
-                if (curConfiguration != null
-                        && curConfiguration.allowedKeyManagement
-                                .get(WifiConfiguration.KeyMgmt.SAE)) {
-                    // Special handling for WPA3-Personal networks. If the password is
-                    // incorrect, the AP will send association rejection, with status code 1
-                    // (unspecified failure). In SAE networks, the password authentication
-                    // is not related to the 4-way handshake. In this case, we will send an
-                    // authentication failure event up.
-                    mStaIfaceHal.logCallback("SAE incorrect password");
-                    mWifiMonitor.broadcastAuthenticationFailureEvent(
-                            mIfaceName, WifiManager.ERROR_AUTH_FAILURE_WRONG_PSWD, -1);
-                }
+            if (isWrongPwd) {
+                mWifiMonitor.broadcastAuthenticationFailureEvent(
+                        mIfaceName, WifiManager.ERROR_AUTH_FAILURE_WRONG_PSWD, -1);
             }
             mWifiMonitor
                     .broadcastAssociationRejectionEvent(
diff --git a/service/java/com/android/server/wifi/SupplicantStaIfaceCallbackV1_3Impl.java b/service/java/com/android/server/wifi/SupplicantStaIfaceCallbackV1_3Impl.java
index 463881b..cac84b5 100644
--- a/service/java/com/android/server/wifi/SupplicantStaIfaceCallbackV1_3Impl.java
+++ b/service/java/com/android/server/wifi/SupplicantStaIfaceCallbackV1_3Impl.java
@@ -19,6 +19,7 @@
 import android.hardware.wifi.supplicant.V1_0.ISupplicantStaIfaceCallback;
 import android.hardware.wifi.supplicant.V1_3.ISupplicantStaIfaceCallback.BssTmData;
 import android.net.wifi.SupplicantState;
+import android.net.wifi.WifiConfiguration;
 import android.net.wifi.WifiManager;
 import android.net.wifi.WifiSsid;
 import android.util.Log;
@@ -192,10 +193,19 @@
 
     @Override
     public void onPmkCacheAdded(long expirationTimeInSec, ArrayList<Byte> serializedEntry) {
-        int curNetworkId = mStaIfaceHal.getCurrentNetworkId(mIfaceName);
-        mStaIfaceHal.addPmkCacheEntry(curNetworkId, expirationTimeInSec, serializedEntry);
+        WifiConfiguration curConfig = mStaIfaceHal.getCurrentNetworkLocalConfig(mIfaceName);
+
+        if (curConfig == null) return;
+
+        if (WifiConfigurationUtil.isConfigForPskNetwork(curConfig)) return;
+
+        mStaIfaceHal.addPmkCacheEntry(mIfaceName,
+                curConfig.networkId, expirationTimeInSec, serializedEntry);
         mStaIfaceHal.logCallback(
-                "onPmkCacheAdded: update pmk cache for config id " + curNetworkId);
+                "onPmkCacheAdded: update pmk cache for config id "
+                + curConfig.networkId
+                + " on "
+                + mIfaceName);
     }
 
     @Override
diff --git a/service/java/com/android/server/wifi/SupplicantStaIfaceHal.java b/service/java/com/android/server/wifi/SupplicantStaIfaceHal.java
index 9d8f4ee..657b081 100644
--- a/service/java/com/android/server/wifi/SupplicantStaIfaceHal.java
+++ b/service/java/com/android/server/wifi/SupplicantStaIfaceHal.java
@@ -43,6 +43,7 @@
 import android.hardware.wifi.supplicant.V1_3.WpaDriverCapabilitiesMask;
 import android.hidl.manager.V1_0.IServiceManager;
 import android.hidl.manager.V1_0.IServiceNotification;
+import android.net.MacAddress;
 import android.net.wifi.ScanResult;
 import android.net.wifi.WifiAnnotations.WifiStandard;
 import android.net.wifi.WifiConfiguration;
@@ -170,10 +171,12 @@
     static class PmkCacheStoreData {
         public long expirationTimeInSec;
         public ArrayList<Byte> data;
+        public MacAddress macAddress;
 
-        PmkCacheStoreData(long timeInSec, ArrayList<Byte> serializedData) {
+        PmkCacheStoreData(long timeInSec, ArrayList<Byte> serializedData, MacAddress macAddress) {
             expirationTimeInSec = timeInSec;
             data = serializedData;
+            this.macAddress = macAddress;
         }
     }
 
@@ -987,6 +990,7 @@
 
             PmkCacheStoreData pmkData = mPmkCacheEntries.get(config.networkId);
             if (pmkData != null
+                    && !WifiConfigurationUtil.isConfigForPskNetwork(config)
                     && pmkData.expirationTimeInSec > mClock.getElapsedSinceBootMillis() / 1000) {
                 logi("Set PMK cache for config id " + config.networkId);
                 if (networkHandle.setPmkCache(pmkData.data)) {
@@ -1052,6 +1056,24 @@
     }
 
     /**
+     * Clear HAL cached data if MAC address is changed.
+     *
+     * @param networkId network id of the network to be checked.
+     * @param curMacAddress current MAC address
+     */
+    public void removeNetworkCachedDataIfNeeded(int networkId, MacAddress curMacAddress) {
+        synchronized (mLock) {
+            PmkCacheStoreData pmkData = mPmkCacheEntries.get(networkId);
+
+            if (pmkData == null) return;
+
+            if (curMacAddress.equals(pmkData.macAddress)) return;
+
+            removeNetworkCachedData(networkId);
+        }
+    }
+
+    /**
      * Remove all networks from supplicant
      *
      * @param ifaceName Name of the interface.
@@ -2635,10 +2657,21 @@
     }
 
     protected void addPmkCacheEntry(
+            String ifaceName,
             int networkId, long expirationTimeInSec, ArrayList<Byte> serializedEntry) {
-        mPmkCacheEntries.put(networkId,
-                new PmkCacheStoreData(expirationTimeInSec, serializedEntry));
-        updatePmkCacheExpiration();
+        String macAddressStr = getMacAddress(ifaceName);
+        if (macAddressStr == null) {
+            Log.w(TAG, "Omit PMK cache due to no valid MAC address on " + ifaceName);
+            return;
+        }
+        try {
+            MacAddress macAddress = MacAddress.fromString(macAddressStr);
+            mPmkCacheEntries.put(networkId,
+                    new PmkCacheStoreData(expirationTimeInSec, serializedEntry, macAddress));
+            updatePmkCacheExpiration();
+        } catch (IllegalArgumentException ex) {
+            Log.w(TAG, "Invalid MAC address string " + macAddressStr);
+        }
     }
 
     protected void removePmkCacheEntry(int networkId) {
diff --git a/service/java/com/android/server/wifi/SupplicantStaNetworkHal.java b/service/java/com/android/server/wifi/SupplicantStaNetworkHal.java
index 8571109..0507a88 100644
--- a/service/java/com/android/server/wifi/SupplicantStaNetworkHal.java
+++ b/service/java/com/android/server/wifi/SupplicantStaNetworkHal.java
@@ -884,7 +884,7 @@
                     break;
                 case WifiConfiguration.GroupCipher.GCMP_256:
                     mask |= android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork
-                                .GroupCipherMask.GCMP_256;
+                            .GroupCipherMask.GCMP_256;
                     break;
                 case WifiConfiguration.GroupCipher.SMS4:
                     mask |= android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork
@@ -1126,8 +1126,8 @@
                 mask, ISupplicantStaNetwork.GroupCipherMask.CCMP, bitset,
                 WifiConfiguration.GroupCipher.CCMP);
         mask = supplicantMaskValueToWifiConfigurationBitSet(mask,
-                android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork.GroupCipherMask
-                        .GCMP_256, bitset, WifiConfiguration.GroupCipher.GCMP_256);
+                android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork
+                        .GroupCipherMask.GCMP_256, bitset, WifiConfiguration.GroupCipher.GCMP_256);
         mask = supplicantMaskValueToWifiConfigurationBitSet(
                 mask, ISupplicantStaNetwork.GroupCipherMask.GTK_NOT_USED, bitset,
                 WifiConfiguration.GroupCipher.GTK_NOT_USED);
@@ -1432,6 +1432,9 @@
                      * Requires HAL v1.2 or higher */
                     status = iSupplicantStaNetworkV12.setGroupCipher_1_2(groupCipherMask);
                 } else {
+                    // Clear GCMP_256 group cipher which is not supported before v1.2
+                    groupCipherMask &= ~android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork
+                            .GroupCipherMask.GCMP_256;
                     status = mISupplicantStaNetwork.setGroupCipher(
                             groupCipherMask);
                 }
@@ -1516,6 +1519,9 @@
                      * Requires HAL v1.2 or higher */
                     status = iSupplicantStaNetworkV12.setPairwiseCipher_1_2(pairwiseCipherMask);
                 } else {
+                    // Clear GCMP_256 pairwise cipher which is not supported before v1.2
+                    pairwiseCipherMask &= ~android.hardware.wifi.supplicant.V1_2
+                            .ISupplicantStaNetwork.PairwiseCipherMask.GCMP_256;
                     status =
                             mISupplicantStaNetwork.setPairwiseCipher(pairwiseCipherMask);
                 }
@@ -1546,7 +1552,6 @@
                 } else {
                     return false;
                 }
-
             } catch (RemoteException e) {
                 handleRemoteException(e, methodStr);
                 return false;
diff --git a/service/java/com/android/server/wifi/WifiConfigManager.java b/service/java/com/android/server/wifi/WifiConfigManager.java
index 90c7f42..209044a 100644
--- a/service/java/com/android/server/wifi/WifiConfigManager.java
+++ b/service/java/com/android/server/wifi/WifiConfigManager.java
@@ -52,6 +52,7 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.server.wifi.hotspot2.PasspointManager;
+import com.android.server.wifi.proto.nano.WifiMetricsProto.UserActionEvent;
 import com.android.server.wifi.util.LruConnectionTracker;
 import com.android.server.wifi.util.MissingCounterTimerLockList;
 import com.android.server.wifi.util.WifiPermissionsUtil;
@@ -1183,6 +1184,25 @@
         return newInternalConfig;
     }
 
+    private void logUserActionEvents(WifiConfiguration before, WifiConfiguration after) {
+        // Logs changes in meteredOverride.
+        if (before.meteredOverride != after.meteredOverride) {
+            mWifiInjector.getWifiMetrics().logUserActionEvent(
+                    WifiMetrics.convertMeteredOverrideEnumToUserActionEventType(
+                            after.meteredOverride),
+                    after.networkId);
+        }
+
+        // Logs changes in macRandomizationSetting.
+        if (before.macRandomizationSetting != after.macRandomizationSetting) {
+            mWifiInjector.getWifiMetrics().logUserActionEvent(
+                    after.macRandomizationSetting == WifiConfiguration.RANDOMIZATION_NONE
+                            ? UserActionEvent.EVENT_CONFIGURE_MAC_RANDOMIZATION_OFF
+                            : UserActionEvent.EVENT_CONFIGURE_MAC_RANDOMIZATION_ON,
+                    after.networkId);
+        }
+    }
+
     /**
      * Add a network or update a network configuration to our database.
      * If the supplied networkId is INVALID_NETWORK_ID, we create a new empty
@@ -1228,6 +1248,10 @@
                         + config.getKey());
                 return new NetworkUpdateResult(WifiConfiguration.INVALID_NETWORK_ID);
             }
+            if (mWifiPermissionsUtil.checkNetworkSettingsPermission(uid)
+                    && !config.isPasspoint()) {
+                logUserActionEvents(existingInternalConfig, config);
+            }
             newInternalConfig =
                     updateExistingInternalWifiConfigurationFromExternal(
                             existingInternalConfig, config, uid, packageName);
@@ -2665,12 +2689,13 @@
      * @param network Input can be SSID or FQDN. And caller must ensure that the SSID passed thru
      *                this API matched the WifiConfiguration.SSID rules, and thus be surrounded by
      *                quotes.
+     *        uid     UID of the calling process.
      */
-    public void userTemporarilyDisabledNetwork(String network) {
+    public void userTemporarilyDisabledNetwork(String network, int uid) {
         mUserTemporarilyDisabledList.add(network, USER_DISCONNECT_NETWORK_BLOCK_EXPIRY_MS);
-        Log.d(TAG, "Temporarily disable network: " + network + " num="
+        Log.d(TAG, "Temporarily disable network: " + network + " uid=" + uid + " num="
                 + mUserTemporarilyDisabledList.size());
-        removeUserChoiceFromDisabledNetwork(network);
+        removeUserChoiceFromDisabledNetwork(network, uid);
     }
 
     /**
@@ -2684,9 +2709,13 @@
     }
 
     private void removeUserChoiceFromDisabledNetwork(
-            @NonNull String network) {
+            @NonNull String network, int uid) {
         for (WifiConfiguration config : getInternalConfiguredNetworks()) {
             if (TextUtils.equals(config.SSID, network) || TextUtils.equals(config.FQDN, network)) {
+                if (mWifiPermissionsUtil.checkNetworkSettingsPermission(uid)) {
+                    mWifiInjector.getWifiMetrics().logUserActionEvent(
+                            UserActionEvent.EVENT_DISCONNECT_WIFI, config.networkId);
+                }
                 removeConnectChoiceFromAllNetworks(config.getKey());
             }
         }
diff --git a/service/java/com/android/server/wifi/WifiConnectivityManager.java b/service/java/com/android/server/wifi/WifiConnectivityManager.java
index 7178a0a..9148e3a 100644
--- a/service/java/com/android/server/wifi/WifiConnectivityManager.java
+++ b/service/java/com/android/server/wifi/WifiConnectivityManager.java
@@ -165,6 +165,7 @@
     private WifiScoreCard mWifiScoreCard;
 
     private boolean mDbg = false;
+    private boolean mVerboseLoggingEnabled = false;
     private boolean mWifiEnabled = false;
     private boolean mAutoJoinEnabled = false; // disabled by default, enabled by external triggers
     private boolean mRunning = false;
@@ -219,6 +220,14 @@
     // be retrieved in bugreport.
     private void localLog(String log) {
         mLocalLog.log(log);
+        if (mVerboseLoggingEnabled) Log.v(TAG, log);
+    }
+
+    /**
+     * Enable verbose logging for WifiConnectivityManager.
+     */
+    public void enableVerboseLogging(boolean verbose) {
+        mVerboseLoggingEnabled = verbose;
     }
 
     // A periodic/PNO scan will be rescheduled up to MAX_SCAN_RESTART_ALLOWED times
diff --git a/service/java/com/android/server/wifi/WifiMetrics.java b/service/java/com/android/server/wifi/WifiMetrics.java
index 736b6c8..4c0627a 100644
--- a/service/java/com/android/server/wifi/WifiMetrics.java
+++ b/service/java/com/android/server/wifi/WifiMetrics.java
@@ -16,6 +16,8 @@
 
 package com.android.server.wifi;
 
+import static android.net.wifi.WifiConfiguration.MeteredOverride;
+
 import static java.lang.StrictMath.toIntExact;
 
 import android.content.Context;
@@ -77,6 +79,7 @@
 import com.android.server.wifi.proto.nano.WifiMetricsProto.SoftApConnectedClientsEvent;
 import com.android.server.wifi.proto.nano.WifiMetricsProto.StaEvent;
 import com.android.server.wifi.proto.nano.WifiMetricsProto.StaEvent.ConfigInfo;
+import com.android.server.wifi.proto.nano.WifiMetricsProto.TargetNetworkInfo;
 import com.android.server.wifi.proto.nano.WifiMetricsProto.UserActionEvent;
 import com.android.server.wifi.proto.nano.WifiMetricsProto.WifiIsUnusableEvent;
 import com.android.server.wifi.proto.nano.WifiMetricsProto.WifiLinkLayerUsageStats;
@@ -732,6 +735,14 @@
         private UserActionEvent mUserActionEvent;
         private long mWallClockTimeMs = 0; // wall clock time for debugging only
 
+        UserActionEventWithTime(int eventType, TargetNetworkInfo targetNetworkInfo) {
+            mUserActionEvent = new UserActionEvent();
+            mUserActionEvent.eventType = eventType;
+            mUserActionEvent.startTimeMillis = mClock.getElapsedSinceBootMillis();
+            mWallClockTimeMs = mClock.getWallClockMillis();
+            mUserActionEvent.targetNetworkInfo = targetNetworkInfo;
+        }
+
         UserActionEventWithTime(int eventType, int targetNetId) {
             mUserActionEvent = new UserActionEvent();
             mUserActionEvent.eventType = eventType;
@@ -740,8 +751,7 @@
             if (targetNetId >= 0) {
                 WifiConfiguration config = mWifiConfigManager.getConfiguredNetwork(targetNetId);
                 if (config != null) {
-                    WifiMetricsProto.TargetNetworkInfo networkInfo =
-                            new WifiMetricsProto.TargetNetworkInfo();
+                    TargetNetworkInfo networkInfo = new TargetNetworkInfo();
                     networkInfo.isEphemeral = config.isEphemeral();
                     networkInfo.isPasspoint = config.isPasspoint();
                     mUserActionEvent.targetNetworkInfo = networkInfo;
@@ -768,6 +778,9 @@
                 case UserActionEvent.EVENT_CONFIGURE_METERED_STATUS_UNMETERED:
                     eventType = "EVENT_CONFIGURE_METERED_STATUS_UNMETERED";
                     break;
+                case UserActionEvent.EVENT_CONFIGURE_METERED_STATUS_AUTO:
+                    eventType = "EVENT_CONFIGURE_METERED_STATUS_AUTO";
+                    break;
                 case UserActionEvent.EVENT_CONFIGURE_MAC_RANDOMIZATION_ON:
                     eventType = "EVENT_CONFIGURE_MAC_RANDOMIZATION_ON";
                     break;
@@ -792,7 +805,7 @@
             }
             sb.append(" eventType=").append(eventType);
             sb.append(" startTimeMillis=").append(mUserActionEvent.startTimeMillis);
-            WifiMetricsProto.TargetNetworkInfo networkInfo = mUserActionEvent.targetNetworkInfo;
+            TargetNetworkInfo networkInfo = mUserActionEvent.targetNetworkInfo;
             if (networkInfo != null) {
                 sb.append(" isEphemeral=").append(networkInfo.isEphemeral);
                 sb.append(" isPasspoint=").append(networkInfo.isPasspoint);
@@ -1657,6 +1670,24 @@
     }
 
     /**
+     * Developer options toggle value for verbose logging.
+     */
+    public void setVerboseLoggingEnabled(boolean enabled) {
+        synchronized (mLock) {
+            mWifiLogProto.isVerboseLoggingEnabled = enabled;
+        }
+    }
+
+    /**
+     * Developer options toggle value for enhanced MAC randomization.
+     */
+    public void setEnhancedMacRandomizationForceEnabled(boolean enabled) {
+        synchronized (mLock) {
+            mWifiLogProto.isEnhancedMacRandomizationForceEnabled = enabled;
+        }
+    }
+
+    /**
      * Increment Non Empty Scan Results count
      */
     public void incrementNonEmptyScanResultCount() {
@@ -3020,6 +3051,10 @@
                 pw.println("mWifiLogProto.isLocationEnabled=" + mWifiLogProto.isLocationEnabled);
                 pw.println("mWifiLogProto.isScanningAlwaysEnabled="
                         + mWifiLogProto.isScanningAlwaysEnabled);
+                pw.println("mWifiLogProto.isVerboseLoggingEnabled="
+                        + mWifiLogProto.isVerboseLoggingEnabled);
+                pw.println("mWifiLogProto.isEnhancedMacRandomizationForceEnabled="
+                        + mWifiLogProto.isEnhancedMacRandomizationForceEnabled);
                 pw.println("mWifiLogProto.numNetworksAddedByUser="
                         + mWifiLogProto.numNetworksAddedByUser);
                 pw.println("mWifiLogProto.numNetworksAddedByApps="
@@ -5025,6 +5060,25 @@
     }
 
     /**
+     * Converts MeteredOverride enum to UserActionEvent type.
+     * @param value
+     */
+    public static int convertMeteredOverrideEnumToUserActionEventType(@MeteredOverride int value) {
+        int result = UserActionEvent.EVENT_UNKNOWN;
+        switch(value) {
+            case WifiConfiguration.METERED_OVERRIDE_NONE:
+                result = UserActionEvent.EVENT_CONFIGURE_METERED_STATUS_AUTO;
+                break;
+            case WifiConfiguration.METERED_OVERRIDE_METERED:
+                result = UserActionEvent.EVENT_CONFIGURE_METERED_STATUS_METERED;
+                break;
+            case WifiConfiguration.METERED_OVERRIDE_NOT_METERED:
+                result = UserActionEvent.EVENT_CONFIGURE_METERED_STATUS_UNMETERED;
+                break;
+        }
+        return result;
+    }
+    /**
      * Logs a UserActionEvent without a target network.
      * @param eventType the type of user action (one of WifiMetricsProto.UserActionEvent.EventType)
      */
@@ -5047,6 +5101,24 @@
     }
 
     /**
+     * Logs a UserActionEvent, directly specifying the target network's properties.
+     * @param eventType the type of user action (one of WifiMetricsProto.UserActionEvent.EventType)
+     * @param isEphemeral true if the target network is ephemeral.
+     * @param isPasspoint true if the target network is passpoint.
+     */
+    public void logUserActionEvent(int eventType, boolean isEphemeral, boolean isPasspoint) {
+        synchronized (mLock) {
+            TargetNetworkInfo networkInfo = new TargetNetworkInfo();
+            networkInfo.isEphemeral = isEphemeral;
+            networkInfo.isPasspoint = isPasspoint;
+            mUserActionEventList.add(new UserActionEventWithTime(eventType, networkInfo));
+            if (mUserActionEventList.size() > MAX_USER_ACTION_EVENTS) {
+                mUserActionEventList.remove();
+            }
+        }
+    }
+
+    /**
      * Update the difference between the last two WifiLinkLayerStats for WifiIsUnusableEvent
      */
     public void updateWifiIsUnusableLinkLayerStats(long txSuccessDelta, long txRetriesDelta,
diff --git a/service/java/com/android/server/wifi/WifiNative.java b/service/java/com/android/server/wifi/WifiNative.java
index 08abafa..d0f2753 100644
--- a/service/java/com/android/server/wifi/WifiNative.java
+++ b/service/java/com/android/server/wifi/WifiNative.java
@@ -2416,6 +2416,15 @@
         mSupplicantStaIfaceHal.removeNetworkCachedData(networkId);
     }
 
+    /** Clear HAL cached data for |networkId| if MAC address is changed.
+     *
+     * @param networkId network id of the network to be checked.
+     * @param curMacAddress current MAC address
+     */
+    public void removeNetworkCachedDataIfNeeded(int networkId, MacAddress curMacAddress) {
+        mSupplicantStaIfaceHal.removeNetworkCachedDataIfNeeded(networkId, curMacAddress);
+    }
+
     /*
      * DPP
      */
diff --git a/service/java/com/android/server/wifi/WifiNetworkFactory.java b/service/java/com/android/server/wifi/WifiNetworkFactory.java
index 26e6023..52fc0e5 100644
--- a/service/java/com/android/server/wifi/WifiNetworkFactory.java
+++ b/service/java/com/android/server/wifi/WifiNetworkFactory.java
@@ -790,7 +790,9 @@
                 new WifiConfiguration(mActiveSpecificNetworkRequestSpecifier.wifiConfiguration);
         networkToConnect.SSID = network.SSID;
         // Set the WifiConfiguration.BSSID field to prevent roaming.
-        networkToConnect.BSSID = findBestBssidFromActiveMatchedScanResultsForNetwork(network);
+        networkToConnect.BSSID =
+                findBestBssidFromActiveMatchedScanResultsForNetwork(
+                        ScanResultMatchInfo.fromWifiConfiguration(networkToConnect));
         networkToConnect.ephemeral = true;
         // Mark it user private to avoid conflicting with any saved networks the user might have.
         // TODO (b/142035508): Use a more generic mechanism to fix this.
@@ -1246,14 +1248,14 @@
     // i) The latest scan results were empty.
     // ii) The latest scan result did not contain any BSSID for the SSID user chose.
     private @Nullable String findBestBssidFromActiveMatchedScanResultsForNetwork(
-            @NonNull WifiConfiguration network) {
+            @NonNull ScanResultMatchInfo scanResultMatchInfo) {
         if (mActiveSpecificNetworkRequestSpecifier == null
                 || mActiveMatchedScanResults == null) return null;
         ScanResult selectedScanResult = mActiveMatchedScanResults
                 .stream()
                 .filter(scanResult -> Objects.equals(
                         ScanResultMatchInfo.fromScanResult(scanResult),
-                        ScanResultMatchInfo.fromWifiConfiguration(network)))
+                        scanResultMatchInfo))
                 .max(Comparator.comparing(scanResult -> scanResult.level))
                 .orElse(null);
         if (selectedScanResult == null) { // Should never happen.
diff --git a/service/java/com/android/server/wifi/WifiNetworkSelector.java b/service/java/com/android/server/wifi/WifiNetworkSelector.java
index 2054428..da583df 100644
--- a/service/java/com/android/server/wifi/WifiNetworkSelector.java
+++ b/service/java/com/android/server/wifi/WifiNetworkSelector.java
@@ -1047,7 +1047,7 @@
 
     private static boolean isFromCarrierOrPrivilegedApp(WifiConfiguration config) {
         if (config.fromWifiNetworkSuggestion
-                && config.carrierId == TelephonyManager.UNKNOWN_CARRIER_ID) {
+                && config.carrierId != TelephonyManager.UNKNOWN_CARRIER_ID) {
             // Privileged carrier suggestion
             return true;
         }
diff --git a/service/java/com/android/server/wifi/WifiScoreReport.java b/service/java/com/android/server/wifi/WifiScoreReport.java
index 5561a91..fa0ba6a 100644
--- a/service/java/com/android/server/wifi/WifiScoreReport.java
+++ b/service/java/com/android/server/wifi/WifiScoreReport.java
@@ -617,6 +617,7 @@
      * Stop the registered Wi-Fi connected network scorer.
      */
     public void stopConnectedNetworkScorer() {
+        mNetworkAgent = null;
         if (mWifiConnectedNetworkScorerHolder == null) {
             return;
         }
diff --git a/service/java/com/android/server/wifi/WifiServiceImpl.java b/service/java/com/android/server/wifi/WifiServiceImpl.java
index 6e33904..73fb306 100644
--- a/service/java/com/android/server/wifi/WifiServiceImpl.java
+++ b/service/java/com/android/server/wifi/WifiServiceImpl.java
@@ -112,7 +112,7 @@
 import com.android.internal.util.AsyncChannel;
 import com.android.server.wifi.hotspot2.PasspointManager;
 import com.android.server.wifi.hotspot2.PasspointProvider;
-import com.android.server.wifi.proto.nano.WifiMetricsProto;
+import com.android.server.wifi.proto.nano.WifiMetricsProto.UserActionEvent;
 import com.android.server.wifi.util.ApConfigUtil;
 import com.android.server.wifi.util.ExternalCallbackTracker;
 import com.android.server.wifi.util.RssiUtil;
@@ -571,11 +571,17 @@
     }
 
     private void handleShutDown() {
-        // There is no explicit disconnection event in clientModeImpl during shutdown.
-        // Call resetConnectionState() so that connection duration is calculated correctly
-        // before memory store write triggered by mMemoryStoreImpl.stop().
-        mWifiScoreCard.resetConnectionState();
-        mMemoryStoreImpl.stop();
+        // Direct call to notify ActiveModeWarden as soon as possible with the assumption that
+        // 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.resetConnectionState();
+            mMemoryStoreImpl.stop();
+        });
     }
 
     private boolean checkNetworkSettingsPermission(int pid, int uid) {
@@ -735,10 +741,10 @@
     private boolean isTargetSdkLessThanQOrPrivileged(String packageName, int pid, int uid) {
         return mWifiPermissionsUtil.isTargetSdkLessThan(packageName, Build.VERSION_CODES.Q, uid)
                 || isPrivileged(pid, uid)
-                // DO/PO apps should be able to add/modify saved networks.
                 || isDeviceOrProfileOwner(uid, packageName)
-                // TODO: Remove this system app bypass once Q is released.
-                || isSystem(packageName, uid);
+                || isSystem(packageName, uid)
+                // TODO(b/140540984): Remove this bypass.
+                || mWifiPermissionsUtil.checkSystemAlertWindowPermission(uid, packageName);
     }
 
     /**
@@ -749,9 +755,7 @@
     private boolean isTargetSdkLessThanROrPrivileged(String packageName, int pid, int uid) {
         return mWifiPermissionsUtil.isTargetSdkLessThan(packageName, Build.VERSION_CODES.R, uid)
                 || isPrivileged(pid, uid)
-                // DO/PO apps should be able to add/modify saved networks.
                 || isDeviceOrProfileOwner(uid, packageName)
-                // TODO: Remove this system app bypass once R is released.
                 || isSystem(packageName, uid);
     }
 
@@ -798,6 +802,10 @@
         } finally {
             Binder.restoreCallingIdentity(ident);
         }
+        if (mWifiPermissionsUtil.checkNetworkSettingsPermission(Binder.getCallingUid())) {
+            mWifiMetrics.logUserActionEvent(enable ? UserActionEvent.EVENT_TOGGLE_WIFI_ON
+                    : UserActionEvent.EVENT_TOGGLE_WIFI_OFF);
+        }
         mWifiMetrics.incrementNumWifiToggles(isPrivileged, enable);
         mActiveModeWarden.wifiToggled();
         return true;
@@ -2552,7 +2560,16 @@
             }
             // even for Suggestion, modify the current ephemeral configuration so that
             // existing configuration auto-connection is updated correctly
-            mWifiConfigManager.allowAutojoin(netId, choice);
+            if (choice != config.allowAutojoin) {
+                mWifiConfigManager.allowAutojoin(netId, choice);
+                // do not log this metrics for passpoint networks again here since it's already
+                // logged in PasspointManager.
+                if (!config.isPasspoint()) {
+                    mWifiMetrics.logUserActionEvent(choice
+                            ? UserActionEvent.EVENT_CONFIGURE_AUTO_CONNECT_ON
+                            : UserActionEvent.EVENT_CONFIGURE_AUTO_CONNECT_OFF, netId);
+                }
+            }
         });
     }
 
@@ -3051,7 +3068,8 @@
             return;
         }
         mLog.info("disableEphemeralNetwork uid=%").c(Binder.getCallingUid()).flush();
-        mWifiThreadRunner.post(() -> mWifiConfigManager.userTemporarilyDisabledNetwork(network));
+        mWifiThreadRunner.post(() -> mWifiConfigManager.userTemporarilyDisabledNetwork(network,
+                Binder.getCallingUid()));
     }
 
     private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@@ -3172,6 +3190,20 @@
                 args);
     }
 
+    private void updateWifiMetrics() {
+        mWifiThreadRunner.run(() -> {
+            mWifiMetrics.updateSavedNetworks(
+                    mWifiConfigManager.getSavedNetworks(Process.WIFI_UID));
+            mPasspointManager.updateMetrics();
+        });
+        boolean isEnhancedMacRandEnabled = mFrameworkFacade.getIntegerSetting(mContext,
+                WifiConfigManager.ENHANCED_MAC_RANDOMIZATION_FEATURE_FORCE_ENABLE_FLAG, 0) == 1
+                ? true : false;
+        mWifiMetrics.setEnhancedMacRandomizationForceEnabled(isEnhancedMacRandEnabled);
+        mWifiMetrics.setIsScanningAlwaysEnabled(isScanAlwaysAvailable());
+        mWifiMetrics.setVerboseLoggingEnabled(mVerboseLoggingEnabled);
+    }
+
     @Override
     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
@@ -3183,11 +3215,7 @@
         }
         if (args != null && args.length > 0 && WifiMetrics.PROTO_DUMP_ARG.equals(args[0])) {
             // WifiMetrics proto bytes were requested. Dump only these.
-            mWifiThreadRunner.run(() -> {
-                mWifiMetrics.updateSavedNetworks(
-                        mWifiConfigManager.getSavedNetworks(Process.WIFI_UID));
-                mPasspointManager.updateMetrics();
-            });
+            updateWifiMetrics();
             mWifiMetrics.dump(fd, pw, args);
         } else if (args != null && args.length > 0 && IpClientUtil.DUMP_ARG.equals(args[0])) {
             // IpClient dump was requested. Pass it along and take no further action.
@@ -3230,12 +3258,10 @@
                     wifiScoreCard.getNetworkListBase64(true), "");
             pw.println("WifiScoreCard:");
             pw.println(networkListBase64);
-            mWifiThreadRunner.run(() -> {
-                mWifiMetrics.updateSavedNetworks(
-                        mWifiConfigManager.getSavedNetworks(Process.WIFI_UID));
-                mPasspointManager.updateMetrics();
-            });
+
+            updateWifiMetrics();
             mWifiMetrics.dump(fd, pw, args);
+
             pw.println();
             mWifiThreadRunner.run(() -> mWifiNetworkSuggestionsManager.dump(fd, pw, args));
             pw.println();
@@ -4062,12 +4088,15 @@
     @Override
     public void connect(WifiConfiguration config, int netId, IBinder binder,
             @Nullable IActionListener callback, int callbackIdentifier) {
-        if (!isPrivileged(Binder.getCallingPid(), Binder.getCallingUid())) {
+        int uid = Binder.getCallingUid();
+        if (!isPrivileged(Binder.getCallingPid(), uid)) {
             throw new SecurityException(TAG + ": Permission denied");
         }
-        mLog.info("connect uid=%").c(Binder.getCallingUid()).flush();
-        mClientModeImpl.connect(
-                config, netId, binder, callback, callbackIdentifier, Binder.getCallingUid());
+        mLog.info("connect uid=%").c(uid).flush();
+        mClientModeImpl.connect(config, netId, binder, callback, callbackIdentifier, uid);
+        if (mWifiPermissionsUtil.checkNetworkSettingsPermission(uid)) {
+            mWifiMetrics.logUserActionEvent(UserActionEvent.EVENT_MANUAL_CONNECT, netId);
+        }
     }
 
     /**
@@ -4099,8 +4128,7 @@
         if (mWifiPermissionsUtil.checkNetworkSettingsPermission(uid)) {
             // It's important to log this metric before the actual forget executes because
             // the netId becomes invalid after the forget operation.
-            mWifiMetrics.logUserActionEvent(WifiMetricsProto.UserActionEvent.EVENT_FORGET_WIFI,
-                    netId);
+            mWifiMetrics.logUserActionEvent(UserActionEvent.EVENT_FORGET_WIFI, netId);
         }
         mClientModeImpl.forget(netId, binder, callback, callbackIdentifier, uid);
     }
diff --git a/service/java/com/android/server/wifi/aware/WifiAwareStateManager.java b/service/java/com/android/server/wifi/aware/WifiAwareStateManager.java
index 2c4d836..f7a6032 100644
--- a/service/java/com/android/server/wifi/aware/WifiAwareStateManager.java
+++ b/service/java/com/android/server/wifi/aware/WifiAwareStateManager.java
@@ -3103,8 +3103,8 @@
             SparseArray<WifiAwareDiscoverySessionState> sessions = mClients.valueAt(
                     i).getSessions();
             for (int j = 0; j < sessions.size(); ++j) {
-                mAwareMetrics.recordDiscoverySessionDuration(sessions.valueAt(i).getCreationTime(),
-                        sessions.valueAt(i).isPublishSession());
+                mAwareMetrics.recordDiscoverySessionDuration(sessions.valueAt(j).getCreationTime(),
+                        sessions.valueAt(j).isPublishSession());
             }
         }
         mAwareMetrics.recordDisableAware();
diff --git a/service/java/com/android/server/wifi/hotspot2/PasspointManager.java b/service/java/com/android/server/wifi/hotspot2/PasspointManager.java
index b60ef3f..7ccca06 100644
--- a/service/java/com/android/server/wifi/hotspot2/PasspointManager.java
+++ b/service/java/com/android/server/wifi/hotspot2/PasspointManager.java
@@ -65,6 +65,7 @@
 import com.android.server.wifi.hotspot2.anqp.Constants;
 import com.android.server.wifi.hotspot2.anqp.HSOsuProvidersElement;
 import com.android.server.wifi.hotspot2.anqp.OsuProviderInfo;
+import com.android.server.wifi.proto.nano.WifiMetricsProto.UserActionEvent;
 import com.android.server.wifi.util.InformationElementUtil;
 
 import java.io.IOException;
@@ -628,7 +629,12 @@
                 Log.e(TAG, "Config doesn't exist");
                 return false;
             }
-            provider.setAutojoinEnabled(enableAutojoin);
+            if (provider.setAutojoinEnabled(enableAutojoin)) {
+                mWifiMetrics.logUserActionEvent(enableAutojoin
+                                ? UserActionEvent.EVENT_CONFIGURE_AUTO_CONNECT_ON
+                                : UserActionEvent.EVENT_CONFIGURE_AUTO_CONNECT_OFF,
+                        provider.isFromSuggestion(), true);
+            }
             mWifiConfigManager.saveToStore(true);
             return true;
         }
@@ -639,7 +645,12 @@
         // FQDN provided, loop through all profiles with matching FQDN
         for (PasspointProvider provider : passpointProviders) {
             if (TextUtils.equals(provider.getConfig().getHomeSp().getFqdn(), fqdn)) {
-                provider.setAutojoinEnabled(enableAutojoin);
+                if (provider.setAutojoinEnabled(enableAutojoin)) {
+                    mWifiMetrics.logUserActionEvent(enableAutojoin
+                                    ? UserActionEvent.EVENT_CONFIGURE_AUTO_CONNECT_ON
+                                    : UserActionEvent.EVENT_CONFIGURE_AUTO_CONNECT_OFF,
+                            provider.isFromSuggestion(), true);
+                }
                 found = true;
             }
         }
@@ -664,6 +675,10 @@
             if (TextUtils.equals(provider.getConfig().getHomeSp().getFqdn(), fqdn)) {
                 boolean settingChanged = provider.setMacRandomizationEnabled(enable);
                 if (settingChanged) {
+                    mWifiMetrics.logUserActionEvent(enable
+                                    ? UserActionEvent.EVENT_CONFIGURE_MAC_RANDOMIZATION_ON
+                                    : UserActionEvent.EVENT_CONFIGURE_MAC_RANDOMIZATION_OFF,
+                            provider.isFromSuggestion(), true);
                     mWifiConfigManager.removePasspointConfiguredNetwork(
                             provider.getWifiConfig().getKey());
                 }
@@ -689,7 +704,12 @@
         // Loop through all profiles with matching FQDN
         for (PasspointProvider provider : passpointProviders) {
             if (TextUtils.equals(provider.getConfig().getHomeSp().getFqdn(), fqdn)) {
-                provider.setMeteredOverride(meteredOverride);
+                if (provider.setMeteredOverride(meteredOverride)) {
+                    mWifiMetrics.logUserActionEvent(
+                            WifiMetrics.convertMeteredOverrideEnumToUserActionEventType(
+                                    meteredOverride),
+                            provider.isFromSuggestion(), true);
+                }
                 found = true;
             }
         }
diff --git a/service/java/com/android/server/wifi/hotspot2/PasspointNetworkNominateHelper.java b/service/java/com/android/server/wifi/hotspot2/PasspointNetworkNominateHelper.java
index 22ce2f0..0a5da1f 100644
--- a/service/java/com/android/server/wifi/hotspot2/PasspointNetworkNominateHelper.java
+++ b/service/java/com/android/server/wifi/hotspot2/PasspointNetworkNominateHelper.java
@@ -204,13 +204,9 @@
         // Add or update with the newly created WifiConfiguration to WifiConfigManager.
         // NOTE: if existingNetwork != null, this update is a no-op in most cases if the SSID is the
         // same (since we update the cached config in PasspointManager#addOrUpdateProvider().
-        NetworkUpdateResult result;
-        if (config.fromWifiNetworkSuggestion) {
-            result = mWifiConfigManager.addOrUpdateNetwork(
-                    config, config.creatorUid, config.creatorName);
-        } else {
-            result = mWifiConfigManager.addOrUpdateNetwork(config, Process.WIFI_UID);
-        }
+        NetworkUpdateResult result = mWifiConfigManager.addOrUpdateNetwork(
+                config, config.creatorUid, config.creatorName);
+
         if (!result.isSuccess()) {
             mLocalLog.log("Failed to add passpoint network");
             return existingNetwork;
diff --git a/service/java/com/android/server/wifi/hotspot2/PasspointProvider.java b/service/java/com/android/server/wifi/hotspot2/PasspointProvider.java
index 006b8ea..9174534 100644
--- a/service/java/com/android/server/wifi/hotspot2/PasspointProvider.java
+++ b/service/java/com/android/server/wifi/hotspot2/PasspointProvider.java
@@ -212,9 +212,13 @@
 
     /**
      * Enable/disable the auto-join configuration of the corresponding passpoint configuration.
+     *
+     * @return true if the setting has changed
      */
-    public void setAutojoinEnabled(boolean autoJoinEnabled) {
+    public boolean setAutojoinEnabled(boolean autoJoinEnabled) {
+        boolean changed = mConfig.isAutojoinEnabled() != autoJoinEnabled;
         mConfig.setAutojoinEnabled(autoJoinEnabled);
+        return changed;
     }
 
     public boolean isAutojoinEnabled() {
@@ -241,9 +245,13 @@
 
     /**
      * Get the metered override for this passpoint profile.
+     *
+     * @return true if the setting has changed
      */
-    public void setMeteredOverride(@MeteredOverride int meteredOverride) {
+    public boolean setMeteredOverride(@MeteredOverride int meteredOverride) {
+        boolean changed = mConfig.getMeteredOverride() != meteredOverride;
         mConfig.setMeteredOverride(meteredOverride);
+        return changed;
     }
 
     /**
diff --git a/service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java b/service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java
index 00c58aa..b65ac64 100644
--- a/service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java
+++ b/service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java
@@ -858,9 +858,6 @@
                 // Register for interface availability from HalDeviceManager
                 mWifiNative.registerInterfaceAvailableListener((boolean isAvailable) -> {
                     mIsHalInterfaceAvailable = isAvailable;
-                    if (isAvailable) {
-                        checkAndReEnableP2p();
-                    }
                     checkAndSendP2pStateChangedBroadcast();
                 }, getHandler());
 
@@ -1390,7 +1387,9 @@
                             break;
                         }
                         mInterfaceName = mWifiNative.setupInterface((String ifaceName) -> {
+                            mIsHalInterfaceAvailable = false;
                             sendMessage(DISABLE_P2P);
+                            checkAndSendP2pStateChangedBroadcast();
                         }, getHandler());
                         if (mInterfaceName == null) {
                             Log.e(TAG, "Failed to setup interface for P2P");
diff --git a/service/proto/src/metrics.proto b/service/proto/src/metrics.proto
index 0202ac1..d2e769d 100644
--- a/service/proto/src/metrics.proto
+++ b/service/proto/src/metrics.proto
@@ -688,6 +688,12 @@
 
   // List of user initiated actions
   repeated UserActionEvent user_action_events = 192;
+
+  // Does the user have wifi verbose logging enabled.
+  optional bool is_verbose_logging_enabled = 193;
+
+  // Does the user have enhanced MAC randomization forced to on.
+  optional bool is_enhanced_mac_randomization_force_enabled = 194;
 }
 
 // Information that gets logged for every WiFi connection.
@@ -3076,6 +3082,8 @@
     EVENT_TOGGLE_WIFI_OFF = 10;
     // User manually connects to a network
     EVENT_MANUAL_CONNECT = 11;
+    // User changes the metered setting to "detect automatically"
+    EVENT_CONFIGURE_METERED_STATUS_AUTO = 12;
   }
 
   // The type of user action
diff --git a/service/res/values-ne/strings.xml b/service/res/values-ne/strings.xml
index 92cd32b..52cc79d 100644
--- a/service/res/values-ne/strings.xml
+++ b/service/res/values-ne/strings.xml
@@ -47,8 +47,8 @@
     <string name="wifi_watchdog_network_disabled" msgid="688248897654073438">"वाइ-फाइसँग जडान गर्न सकेन"</string>
     <string name="wifi_watchdog_network_disabled_detailed" msgid="2946200607682633112">" खराब इन्टरनेट जडान रहेको छ।"</string>
     <string name="wifi_connect_alert_title" msgid="6144470472092017636">"जडान अनुमति दिने हो?"</string>
-    <string name="wifi_connect_alert_message" msgid="3123801378559831220">"अनुप्रयोग %1$s Wifi सञ्जाल %2$s मा जडान गर्न चाहन्छ"</string>
-    <string name="wifi_connect_default_application" msgid="6164721692891325243">"एउटा अनुप्रयोग"</string>
+    <string name="wifi_connect_alert_message" msgid="3123801378559831220">"एप %1$s Wifi सञ्जाल %2$s मा जडान गर्न चाहन्छ"</string>
+    <string name="wifi_connect_default_application" msgid="6164721692891325243">"एउटा एप"</string>
     <string name="accept" msgid="5931271886782610829">"स्वीकार्नुहोस्"</string>
     <string name="decline" msgid="6874256900873707640">"अस्वीकार गर्नुहोस्"</string>
     <string name="ok" msgid="4215387532539340948">"ठिक छ"</string>
diff --git a/tests/wifitests/src/com/android/server/wifi/ActiveModeWardenTest.java b/tests/wifitests/src/com/android/server/wifi/ActiveModeWardenTest.java
index 701ffb3..db7b4e2 100644
--- a/tests/wifitests/src/com/android/server/wifi/ActiveModeWardenTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/ActiveModeWardenTest.java
@@ -821,10 +821,11 @@
     }
 
     /**
-     * Trigger recovery and a bug report if we see a native failure.
+     * Trigger recovery and a bug report if we see a native failure
+     * while the device is not shutting down
      */
     @Test
-    public void handleWifiNativeFailure() throws Exception {
+    public void handleWifiNativeFailureDeviceNotShuttingDown() throws Exception {
         mWifiNativeStatusListener.onStatusChanged(false);
         mLooper.dispatchAll();
         verify(mWifiDiagnostics).captureBugReportData(
@@ -833,6 +834,19 @@
     }
 
     /**
+     * Verify the device shutting down doesn't trigger recovery or bug report.
+     */
+    @Test
+    public void handleWifiNativeFailureDeviceShuttingDown() throws Exception {
+        mActiveModeWarden.notifyShuttingDown();
+        mWifiNativeStatusListener.onStatusChanged(false);
+        mLooper.dispatchAll();
+        verify(mWifiDiagnostics, never()).captureBugReportData(
+                WifiDiagnostics.REPORT_REASON_WIFINATIVE_FAILURE);
+        verify(mSelfRecovery, never()).trigger(eq(SelfRecovery.REASON_WIFINATIVE_FAILURE));
+    }
+
+    /**
      * Verify an onStatusChanged callback with "true" does not trigger recovery.
      */
     @Test
diff --git a/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java b/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java
index 2923315..8f36770 100644
--- a/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java
@@ -2646,7 +2646,7 @@
      * 3. macRandomizationSetting of the WifiConfiguration is RANDOMIZATION_PERSISTENT and
      * 4. randomized MAC for the network to connect to is different from the current MAC.
      *
-     * Then the current MAC does not change when CMD_START_CONNECT executes.
+     * The factory MAC address is used for the connection.
      */
     @Test
     public void testConnectedMacRandomizationNotSupported() throws Exception {
@@ -2657,11 +2657,7 @@
         assertEquals(WifiManager.WIFI_STATE_ENABLED, mCmi.syncGetWifiState());
 
         connect();
-        verify(mWifiNative, never()).setMacAddress(WIFI_IFACE_NAME, TEST_LOCAL_MAC_ADDRESS);
-        verify(mWifiMetrics, never())
-                .logStaEvent(eq(StaEvent.TYPE_MAC_CHANGE), any(WifiConfiguration.class));
         assertEquals(TEST_GLOBAL_MAC_ADDRESS.toString(), mCmi.getWifiInfo().getMacAddress());
-
     }
 
     /**
@@ -2746,9 +2742,8 @@
      * Verifies that when
      * 1. connected MAC randomization is on and
      * 2. macRandomizationSetting of the WifiConfiguration is RANDOMIZATION_NONE and
-     * 3. current MAC is the factory MAC.
      *
-     * Then MAC change should not occur when CMD_START_CONNECT executes.
+     * Then the factory MAC should be used to connect to the network.
      * @throws Exception
      */
     @Test
@@ -2765,9 +2760,6 @@
         mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, sBSSID);
         mLooper.dispatchAll();
 
-        verify(mWifiNative, never()).setMacAddress(WIFI_IFACE_NAME, TEST_GLOBAL_MAC_ADDRESS);
-        verify(mWifiMetrics, never())
-                .logStaEvent(eq(StaEvent.TYPE_MAC_CHANGE), any(WifiConfiguration.class));
         assertEquals(TEST_GLOBAL_MAC_ADDRESS.toString(), mCmi.getWifiInfo().getMacAddress());
     }
 
@@ -2812,7 +2804,8 @@
         mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, sBSSID);
         mLooper.dispatchAll();
 
-        verify(mWifiNative, never()).setMacAddress(eq(WIFI_IFACE_NAME), any(MacAddress.class));
+        // setMacAddress is invoked once when ClientModeImpl starts to prevent leak of factory MAC.
+        verify(mWifiNative).setMacAddress(eq(WIFI_IFACE_NAME), any(MacAddress.class));
     }
 
     /**
@@ -3828,7 +3821,7 @@
         initializeCmi();
         initializeAndAddNetworkAndVerifySuccess();
         when(mWifiNative.getFactoryMacAddress(WIFI_IFACE_NAME)).thenReturn(null);
-        assertEquals(TEST_GLOBAL_MAC_ADDRESS.toString(), mCmi.getFactoryMacAddress());
+        mCmi.getFactoryMacAddress();
         verify(mWifiNative).getFactoryMacAddress(anyString());
         verify(mWifiNative, times(2)).getMacAddress(WIFI_IFACE_NAME);
     }
@@ -3845,6 +3838,21 @@
     }
 
     /**
+     * Verify the MAC address is being randomized at start to prevent leaking the factory MAC.
+     */
+    @Test
+    public void testRandomizeMacAddressOnStart() throws Exception {
+        ArgumentCaptor<MacAddress> macAddressCaptor = ArgumentCaptor.forClass(MacAddress.class);
+        loadComponentsInStaMode();
+        verify(mWifiNative).setMacAddress(anyString(), macAddressCaptor.capture());
+        MacAddress currentMac = macAddressCaptor.getValue();
+
+        assertNotEquals("The currently programmed MAC address should be different from the factory "
+                + "MAC address after ClientModeImpl starts",
+                mCmi.getFactoryMacAddress(), currentMac.toString());
+    }
+
+    /**
      * Verify bugreport will be taken when get IP_REACHABILITY_LOST
      */
     @Test
@@ -4989,4 +4997,81 @@
 
         verifyNoMoreInteractions(mNetworkAgentHandler);
     }
+
+    /*
+     * Verify that network cached data is cleared correctly in
+     * disconnected state.
+     */
+    @Test
+    public void testNetworkCachedDataIsClearedCorrectlyInDisconnectedState() throws Exception {
+        // Setup CONNECT_MODE & a WifiConfiguration
+        initializeAndAddNetworkAndVerifySuccess();
+        mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, sBSSID);
+        mLooper.dispatchAll();
+
+        // got UNSPECIFIED during this connection attempt
+        mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, 0, 1, sBSSID);
+        mLooper.dispatchAll();
+
+        assertEquals("DisconnectedState", getCurrentState().getName());
+        verify(mWifiNative, never()).removeNetworkCachedData(anyInt());
+
+        // got 4WAY_HANDSHAKE_TIMEOUT during this connection attempt
+        mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, 0, 15, sBSSID);
+        mLooper.dispatchAll();
+
+        assertEquals("DisconnectedState", getCurrentState().getName());
+        verify(mWifiNative).removeNetworkCachedData(FRAMEWORK_NETWORK_ID);
+    }
+
+    /*
+     * Verify that network cached data is cleared correctly in
+     * disconnected state.
+     */
+    @Test
+    public void testNetworkCachedDataIsClearedCorrectlyInObtainingIpState() throws Exception {
+        initializeAndAddNetworkAndVerifySuccess();
+
+        verify(mWifiNative).removeAllNetworks(WIFI_IFACE_NAME);
+
+        IActionListener connectActionListener = mock(IActionListener.class);
+        mCmi.connect(null, 0, mock(Binder.class), connectActionListener, 0, Binder.getCallingUid());
+        mLooper.dispatchAll();
+        verify(connectActionListener).onSuccess();
+
+        verify(mWifiConfigManager).enableNetwork(eq(0), eq(true), anyInt(), any());
+
+        mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 0, 0, sBSSID);
+        mLooper.dispatchAll();
+
+        mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0,
+                new StateChangeResult(0, sWifiSsid, sBSSID, SupplicantState.COMPLETED));
+        mLooper.dispatchAll();
+
+        assertEquals("ObtainingIpState", getCurrentState().getName());
+
+        // got 4WAY_HANDSHAKE_TIMEOUT during this connection attempt
+        mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, 0, 15, sBSSID);
+        mLooper.dispatchAll();
+
+        verify(mWifiNative).removeNetworkCachedData(FRAMEWORK_NETWORK_ID);
+    }
+
+    /*
+     * Verify that network cached data is NOT cleared in ConnectedState.
+     */
+    @Test
+    public void testNetworkCachedDataIsClearedIf4WayHandshakeFailure() throws Exception {
+        when(mWifiScoreCard.detectAbnormalDisconnection())
+                .thenReturn(WifiHealthMonitor.REASON_SHORT_CONNECTION_NONLOCAL);
+        InOrder inOrderWifiLockManager = inOrder(mWifiLockManager);
+        connect();
+        inOrderWifiLockManager.verify(mWifiLockManager).updateWifiClientConnected(true);
+
+        // got 4WAY_HANDSHAKE_TIMEOUT
+        mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, 0, 15, sBSSID);
+        mLooper.dispatchAll();
+        verify(mWifiNative, never()).removeNetworkCachedData(anyInt());
+    }
+
 }
diff --git a/tests/wifitests/src/com/android/server/wifi/HostapdHalTest.java b/tests/wifitests/src/com/android/server/wifi/HostapdHalTest.java
index 9db553f..52a28ea 100644
--- a/tests/wifitests/src/com/android/server/wifi/HostapdHalTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/HostapdHalTest.java
@@ -34,6 +34,7 @@
 import android.net.MacAddress;
 import android.net.wifi.SoftApConfiguration;
 import android.net.wifi.SoftApConfiguration.Builder;
+import android.net.wifi.WifiManager;
 import android.net.wifi.nl80211.WifiNl80211Manager;
 import android.os.Handler;
 import android.os.IHwBinder;
@@ -820,10 +821,28 @@
         when(mIHostapdMockV12.forceClientDisconnect(any(), any(), anyShort()))
                 .thenReturn(mStatusSuccess12);
 
-        assertTrue(mHostapdHal.forceClientDisconnect(IFACE_NAME, test_client, 0));
+        assertTrue(mHostapdHal.forceClientDisconnect(IFACE_NAME, test_client,
+                WifiManager.SAP_CLIENT_BLOCK_REASON_CODE_BLOCKED_BY_USER));
         verify(mIHostapdMockV12).forceClientDisconnect(any(), any(), anyShort());
     }
 
+    @Test
+    public void testForceClientDisconnectFailureDueToInvalidArg() throws Exception {
+        executeAndValidateInitializationSequence();
+        when(mServiceManagerMock.getTransport(anyString(), anyString()))
+                .thenReturn(IServiceManager.Transport.HWBINDER);
+        MacAddress test_client = MacAddress.fromString("da:a1:19:0:0:0");
+        mIHostapdMockV12 = mock(android.hardware.wifi.hostapd.V1_2.IHostapd.class);
+        when(mIHostapdMockV12.forceClientDisconnect(any(), any(), anyShort()))
+                .thenReturn(mStatusSuccess12);
+
+        try {
+            mHostapdHal.forceClientDisconnect(IFACE_NAME, test_client, -1);
+            fail();
+        } catch (IllegalArgumentException e) {
+        }
+    }
+
     /**
      * Verifies the failure handling in forceClientDisconnect.
      */
@@ -837,7 +856,8 @@
         when(mIHostapdMockV12.forceClientDisconnect(any(), any(), anyShort()))
                 .thenReturn(mStatusFailure12);
 
-        assertFalse(mHostapdHal.forceClientDisconnect(IFACE_NAME, test_client, 0));
+        assertFalse(mHostapdHal.forceClientDisconnect(IFACE_NAME, test_client,
+                WifiManager.SAP_CLIENT_BLOCK_REASON_CODE_BLOCKED_BY_USER));
         verify(mIHostapdMockV12).forceClientDisconnect(any(), any(), anyShort());
     }
 
diff --git a/tests/wifitests/src/com/android/server/wifi/OpenNetworkNotifierTest.java b/tests/wifitests/src/com/android/server/wifi/OpenNetworkNotifierTest.java
index f1eeb38..6dae6f5 100644
--- a/tests/wifitests/src/com/android/server/wifi/OpenNetworkNotifierTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/OpenNetworkNotifierTest.java
@@ -495,7 +495,7 @@
     public void actionConnectToNetwork_notificationNotShowing_doesNothing() {
         mBroadcastReceiver.onReceive(mContext, createIntent(ACTION_CONNECT_TO_NETWORK));
         verify(mClientModeImpl, never()).connect(any(), anyInt(), any(Binder.class),
-                any(IActionListener.class), anyInt(), eq(Process.WIFI_UID));
+                any(IActionListener.class), anyInt(), eq(Process.SYSTEM_UID));
     }
 
     /**
@@ -516,7 +516,7 @@
         mBroadcastReceiver.onReceive(mContext, createIntent(ACTION_CONNECT_TO_NETWORK));
 
         verify(mClientModeImpl).connect(eq(null), eq(TEST_NETWORK_ID), any(Binder.class),
-                any(IActionListener.class), anyInt(), eq(Process.WIFI_UID));
+                any(IActionListener.class), anyInt(), eq(Process.SYSTEM_UID));
         // Connecting Notification
         verify(mNotificationBuilder).createNetworkConnectingNotification(OPEN_NET_NOTIFIER_TAG,
                 mDummyNetwork);
@@ -697,7 +697,7 @@
         ArgumentCaptor<IActionListener> connectListenerCaptor =
                 ArgumentCaptor.forClass(IActionListener.class);
         verify(mClientModeImpl).connect(eq(null), eq(TEST_NETWORK_ID), any(Binder.class),
-                connectListenerCaptor.capture(), anyInt(), eq(Process.WIFI_UID));
+                connectListenerCaptor.capture(), anyInt(), eq(Process.SYSTEM_UID));
         IActionListener connectListener = connectListenerCaptor.getValue();
 
         // Connecting Notification
diff --git a/tests/wifitests/src/com/android/server/wifi/SoftApManagerTest.java b/tests/wifitests/src/com/android/server/wifi/SoftApManagerTest.java
index a7e21c9..ca7bc62 100644
--- a/tests/wifitests/src/com/android/server/wifi/SoftApManagerTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/SoftApManagerTest.java
@@ -23,6 +23,7 @@
 import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_MODE;
 import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_STATE;
 import static android.net.wifi.WifiManager.IFACE_IP_MODE_LOCAL_ONLY;
+import static android.net.wifi.WifiManager.SAP_CLIENT_DISCONNECT_REASON_CODE_UNSPECIFIED;
 import static android.net.wifi.WifiManager.WIFI_AP_STATE_DISABLED;
 import static android.net.wifi.WifiManager.WIFI_AP_STATE_DISABLING;
 import static android.net.wifi.WifiManager.WIFI_AP_STATE_ENABLED;
@@ -1106,6 +1107,34 @@
     }
 
     @Test
+    public void stopDisconnectsConnectedClients() throws Exception {
+        InOrder order = inOrder(mCallback, mWifiMetrics);
+        SoftApModeConfiguration apConfig =
+                new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null,
+                        mTestSoftApCapability);
+        startSoftApAndVerifyEnabled(apConfig);
+
+        order.verify(mCallback).onConnectedClientsChanged(new ArrayList<>());
+
+        mSoftApListenerCaptor.getValue().onConnectedClientsChanged(
+                TEST_NATIVE_CLIENT, true);
+        mLooper.dispatchAll();
+
+        order.verify(mCallback).onConnectedClientsChanged(
+                Mockito.argThat((List<WifiClient> clients) ->
+                        clients.contains(TEST_CONNECTED_CLIENT))
+        );
+        verify(mWifiMetrics).addSoftApNumAssociatedStationsChangedEvent(
+                1, apConfig.getTargetMode());
+
+        mSoftApManager.stop();
+        mLooper.dispatchAll();
+
+        verify(mWifiNative).forceClientDisconnect(TEST_INTERFACE_NAME, TEST_MAC_ADDRESS,
+                SAP_CLIENT_DISCONNECT_REASON_CODE_UNSPECIFIED);
+    }
+
+    @Test
     public void handlesInvalidConnectedClients() throws Exception {
         SoftApModeConfiguration apConfig =
                 new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null,
diff --git a/tests/wifitests/src/com/android/server/wifi/SupplicantStaIfaceHalTest.java b/tests/wifitests/src/com/android/server/wifi/SupplicantStaIfaceHalTest.java
index ad2eac8..95f88bb 100644
--- a/tests/wifitests/src/com/android/server/wifi/SupplicantStaIfaceHalTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/SupplicantStaIfaceHalTest.java
@@ -52,6 +52,7 @@
 
 import android.annotation.NonNull;
 import android.app.test.MockAnswerUtil;
+import android.app.test.MockAnswerUtil.AnswerWithArguments;
 import android.content.Context;
 import android.hardware.wifi.V1_0.WifiChannelWidthInMhz;
 import android.hardware.wifi.supplicant.V1_0.ISupplicant;
@@ -69,6 +70,7 @@
 import android.hardware.wifi.supplicant.V1_3.WifiTechnology;
 import android.hidl.manager.V1_0.IServiceManager;
 import android.hidl.manager.V1_0.IServiceNotification;
+import android.net.MacAddress;
 import android.net.wifi.ScanResult;
 import android.net.wifi.SupplicantState;
 import android.net.wifi.WifiConfiguration;
@@ -126,6 +128,8 @@
     private static final int ICON_FILE_SIZE = 72;
     private static final String HS20_URL = "http://blahblah";
     private static final long PMK_CACHE_EXPIRATION_IN_SEC = 1024;
+    private static final byte[] CONNECTED_MAC_ADDRESS_BYTES =
+            {0x00, 0x01, 0x02, 0x03, 0x04, 0x05};
 
     private @Mock IServiceManager mServiceManagerMock;
     private @Mock ISupplicant mISupplicantMock;
@@ -251,6 +255,13 @@
                 any(IServiceNotification.Stub.class))).thenReturn(true);
         when(mISupplicantMock.linkToDeath(any(IHwBinder.DeathRecipient.class),
                 anyLong())).thenReturn(true);
+        doAnswer(new AnswerWithArguments() {
+            public void answer(ISupplicantStaIface.getMacAddressCallback cb) {
+                cb.onValues(mStatusSuccess, CONNECTED_MAC_ADDRESS_BYTES);
+            }
+        })
+        .when(mISupplicantStaIfaceMock)
+                .getMacAddress(any(ISupplicantStaIface.getMacAddressCallback.class));
         mHandler = spy(new Handler(mLooper.getLooper()));
         mDut = new SupplicantStaIfaceHalSpy();
     }
@@ -1063,12 +1074,12 @@
      * Tests the handling of incorrect network passwords for WPA3-Personal networks
      */
     @Test
-    public void testAuthRejectionPassword() throws Exception {
+    public void testWpa3AuthRejectionPassword() throws Exception {
         executeAndValidateInitializationSequence();
         assertNotNull(mISupplicantStaIfaceCallback);
 
         executeAndValidateConnectSequenceWithKeyMgmt(SUPPLICANT_NETWORK_ID, false,
-                WifiConfiguration.KeyMgmt.SAE);
+                WifiConfiguration.KeyMgmt.SAE, null);
 
         int statusCode = ISupplicantStaIfaceCallback.StatusCode.UNSPECIFIED_FAILURE;
 
@@ -1081,6 +1092,27 @@
     }
 
     /**
+     * Tests the handling of incorrect network passwords for WEP networks.
+     */
+    @Test
+    public void testWepAuthRejectionPassword() throws Exception {
+        executeAndValidateInitializationSequence();
+        assertNotNull(mISupplicantStaIfaceCallback);
+
+        executeAndValidateConnectSequenceWithKeyMgmt(SUPPLICANT_NETWORK_ID, false,
+                WifiConfiguration.KeyMgmt.NONE, "97CA326539");
+
+        int statusCode = ISupplicantStaIfaceCallback.StatusCode.CHALLENGE_FAIL;
+
+        mISupplicantStaIfaceCallback.onAssociationRejected(
+                NativeUtil.macAddressToByteArray(BSSID), statusCode, false);
+        verify(mWifiMonitor).broadcastAuthenticationFailureEvent(eq(WLAN0_IFACE_NAME),
+                eq(WifiManager.ERROR_AUTH_FAILURE_WRONG_PSWD), eq(-1));
+        verify(mWifiMonitor).broadcastAssociationRejectionEvent(
+                eq(WLAN0_IFACE_NAME), eq(statusCode), eq(false), eq(BSSID));
+    }
+
+    /**
      * Tests the handling of incorrect network passwords, edge case.
      *
      * If the network is removed during 4-way handshake, do not call it a password mismatch.
@@ -1736,9 +1768,10 @@
         long testStartSeconds = PMK_CACHE_EXPIRATION_IN_SEC / 2;
         WifiConfiguration config = new WifiConfiguration();
         config.networkId = testFrameworkNetworkId;
-        config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
+        config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP);
         PmkCacheStoreData pmkCacheData =
-                new PmkCacheStoreData(PMK_CACHE_EXPIRATION_IN_SEC, new ArrayList<Byte>());
+                new PmkCacheStoreData(PMK_CACHE_EXPIRATION_IN_SEC, new ArrayList<Byte>(),
+                        MacAddress.fromBytes(CONNECTED_MAC_ADDRESS_BYTES));
         mDut.mPmkCacheEntries.put(testFrameworkNetworkId, pmkCacheData);
         when(mClock.getElapsedSinceBootMillis()).thenReturn(testStartSeconds * 1000L);
 
@@ -1770,7 +1803,38 @@
         long testStartSeconds = PMK_CACHE_EXPIRATION_IN_SEC / 2;
         WifiConfiguration config = new WifiConfiguration();
         config.networkId = testFrameworkNetworkId;
+        config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP);
+        when(mClock.getElapsedSinceBootMillis()).thenReturn(testStartSeconds * 1000L);
+
+        setupMocksForHalV1_3();
+        setupMocksForPmkCache();
+        setupMocksForConnectSequence(false);
+        executeAndValidateInitializationSequenceV1_3();
+        assertTrue(mDut.connectToNetwork(WLAN0_IFACE_NAME, config));
+
+        verify(mSupplicantStaNetworkMock, never()).setPmkCache(any(ArrayList.class));
+        verify(mISupplicantStaIfaceCallbackV13, never()).onPmkCacheAdded(
+                anyLong(), any(ArrayList.class));
+        verify(mHandler, never()).postDelayed(
+                /* private listener */ any(),
+                eq(SupplicantStaIfaceHal.PMK_CACHE_EXPIRATION_ALARM_TAG),
+                anyLong());
+    }
+
+    /**
+     * Test adding PMK cache entry returns faliure if this is a psk network.
+     */
+    @Test
+    public void testAddPmkEntryIsOmittedWithPskNetwork() throws Exception {
+        int testFrameworkNetworkId = 9;
+        long testStartSeconds = PMK_CACHE_EXPIRATION_IN_SEC / 2;
+        WifiConfiguration config = new WifiConfiguration();
+        config.networkId = testFrameworkNetworkId;
         config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
+        PmkCacheStoreData pmkCacheData =
+                new PmkCacheStoreData(PMK_CACHE_EXPIRATION_IN_SEC, new ArrayList<Byte>(),
+                        MacAddress.fromBytes(CONNECTED_MAC_ADDRESS_BYTES));
+        mDut.mPmkCacheEntries.put(testFrameworkNetworkId, pmkCacheData);
         when(mClock.getElapsedSinceBootMillis()).thenReturn(testStartSeconds * 1000L);
 
         setupMocksForHalV1_3();
@@ -1797,9 +1861,10 @@
         long testStartSeconds = PMK_CACHE_EXPIRATION_IN_SEC / 2;
         WifiConfiguration config = new WifiConfiguration();
         config.networkId = testFrameworkNetworkId;
-        config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
+        config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP);
         PmkCacheStoreData pmkCacheData =
-                new PmkCacheStoreData(PMK_CACHE_EXPIRATION_IN_SEC, new ArrayList<Byte>());
+                new PmkCacheStoreData(PMK_CACHE_EXPIRATION_IN_SEC, new ArrayList<Byte>(),
+                        MacAddress.fromBytes(CONNECTED_MAC_ADDRESS_BYTES));
         mDut.mPmkCacheEntries.put(testFrameworkNetworkId, pmkCacheData);
         when(mClock.getElapsedSinceBootMillis()).thenReturn(testStartSeconds * 1000L);
 
@@ -1824,9 +1889,10 @@
         long testStartSeconds = PMK_CACHE_EXPIRATION_IN_SEC / 2;
         WifiConfiguration config = new WifiConfiguration();
         config.networkId = testFrameworkNetworkId;
-        config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
+        config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP);
         PmkCacheStoreData pmkCacheData =
-                new PmkCacheStoreData(PMK_CACHE_EXPIRATION_IN_SEC, new ArrayList<Byte>());
+                new PmkCacheStoreData(PMK_CACHE_EXPIRATION_IN_SEC, new ArrayList<Byte>(),
+                        MacAddress.fromBytes(CONNECTED_MAC_ADDRESS_BYTES));
         mDut.mPmkCacheEntries.put(testFrameworkNetworkId, pmkCacheData);
         when(mClock.getElapsedSinceBootMillis()).thenReturn(testStartSeconds * 1000L);
 
@@ -1845,6 +1911,40 @@
     }
 
     /**
+     * Tests the PMK cache is removed and not set if MAC address is changed.
+     */
+    @Test
+    public void testRemovePmkEntryOnMacAddressChanged() throws Exception {
+        int testFrameworkNetworkId = 9;
+        long testStartSeconds = PMK_CACHE_EXPIRATION_IN_SEC / 2;
+        WifiConfiguration config = new WifiConfiguration();
+        config.networkId = testFrameworkNetworkId;
+        config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP);
+        // Assume we have a PMK cache with a different MAC address.
+        final byte[] previouisConnectedMacAddressBytes =
+                {0x00, 0x01, 0x02, 0x03, 0x04, 0x09};
+        PmkCacheStoreData pmkCacheData =
+                new PmkCacheStoreData(PMK_CACHE_EXPIRATION_IN_SEC, new ArrayList<Byte>(),
+                        MacAddress.fromBytes(previouisConnectedMacAddressBytes));
+        mDut.mPmkCacheEntries.put(testFrameworkNetworkId, pmkCacheData);
+        when(mClock.getElapsedSinceBootMillis()).thenReturn(testStartSeconds * 1000L);
+
+        setupMocksForHalV1_3();
+        setupMocksForPmkCache();
+        setupMocksForConnectSequence(false);
+
+        // When MAC is not changed, PMK cache should NOT be removed.
+        mDut.removeNetworkCachedDataIfNeeded(testFrameworkNetworkId,
+                MacAddress.fromBytes(previouisConnectedMacAddressBytes));
+        assertEquals(pmkCacheData, mDut.mPmkCacheEntries.get(testFrameworkNetworkId));
+
+        // When MAC is changed, PMK cache should be removed.
+        mDut.removeNetworkCachedDataIfNeeded(testFrameworkNetworkId,
+                MacAddress.fromBytes(CONNECTED_MAC_ADDRESS_BYTES));
+        assertNull(mDut.mPmkCacheEntries.get(testFrameworkNetworkId));
+    }
+
+    /**
      * Test getConnectionCapabilities
      * Should fail if running HAL lower than V1_3
      */
@@ -2366,7 +2466,7 @@
     private WifiConfiguration executeAndValidateConnectSequence(
             final int newFrameworkNetworkId, final boolean haveExistingNetwork) throws Exception {
         return executeAndValidateConnectSequenceWithKeyMgmt(newFrameworkNetworkId,
-                haveExistingNetwork, WifiConfiguration.KeyMgmt.WPA_PSK);
+                haveExistingNetwork, WifiConfiguration.KeyMgmt.WPA_PSK, null);
     }
 
     /**
@@ -2374,16 +2474,19 @@
      *
      * @param newFrameworkNetworkId Framework Network Id of the new network to connect.
      * @param haveExistingNetwork Removes the existing network.
-     * @param keyMgmt Key management of the new network
+     * @param keyMgmt Key management of the new network.
+     * @param wepKey if configurations are for a WEP network else null.
      * @return the WifiConfiguration object of the new network to connect.
      */
     private WifiConfiguration executeAndValidateConnectSequenceWithKeyMgmt(
             final int newFrameworkNetworkId, final boolean haveExistingNetwork,
-            int keyMgmt) throws Exception {
+            int keyMgmt, String wepKey) throws Exception {
         setupMocksForConnectSequence(haveExistingNetwork);
         WifiConfiguration config = new WifiConfiguration();
         config.networkId = newFrameworkNetworkId;
         config.allowedKeyManagement.set(keyMgmt);
+        config.wepKeys[0] = wepKey;
+        config.wepTxKeyIndex = 0;
         assertTrue(mDut.connectToNetwork(WLAN0_IFACE_NAME, config));
         validateConnectSequence(haveExistingNetwork, 1);
         return config;
diff --git a/tests/wifitests/src/com/android/server/wifi/SupplicantStaNetworkHalTest.java b/tests/wifitests/src/com/android/server/wifi/SupplicantStaNetworkHalTest.java
index 0e1c980..49ae7a7 100644
--- a/tests/wifitests/src/com/android/server/wifi/SupplicantStaNetworkHalTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/SupplicantStaNetworkHalTest.java
@@ -196,6 +196,14 @@
     public void testPskPassphraseNetworkWifiConfigurationSaveLoad() throws Exception {
         WifiConfiguration config = WifiConfigurationTestUtil.createPskNetwork();
         config.requirePmf = true;
+
+        // Set the new defaults
+        config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.GCMP_256);
+        config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
+        config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.GCMP_256);
+        config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
+        config.allowedGroupManagementCiphers
+                .set(WifiConfiguration.GroupMgmtCipher.BIP_GMAC_256);
         testWifiConfigurationSaveLoad(config);
         verify(mISupplicantStaNetworkMock).setPskPassphrase(anyString());
         verify(mISupplicantStaNetworkMock)
@@ -203,6 +211,10 @@
         verify(mISupplicantStaNetworkMock, never()).setPsk(any(byte[].class));
         verify(mISupplicantStaNetworkMock, never())
                 .getPsk(any(ISupplicantStaNetwork.getPskCallback.class));
+        verify(mISupplicantStaNetworkMock)
+                .setPairwiseCipher(ISupplicantStaNetwork.PairwiseCipherMask.CCMP);
+        verify(mISupplicantStaNetworkMock)
+                .setGroupCipher(ISupplicantStaNetwork.GroupCipherMask.CCMP);
     }
 
     /**
@@ -948,6 +960,12 @@
     }
 
     private void testWifiConfigurationSaveLoad(WifiConfiguration config) {
+        if (mSupplicantNetwork.getSupplicantStaNetworkForV1_2Mockable() == null) {
+            // Clear unsupported settings in HAL v1.0
+            config.allowedPairwiseCiphers.clear(WifiConfiguration.PairwiseCipher.GCMP_256);
+            config.allowedGroupCiphers.clear(WifiConfiguration.GroupCipher.GCMP_256);
+        }
+        // Save the configuration using the default supplicant network HAL v1.0
         assertTrue(mSupplicantNetwork.saveWifiConfiguration(config));
         WifiConfiguration loadConfig = new WifiConfiguration();
         Map<String, String> networkExtras = new HashMap<>();
@@ -1039,6 +1057,38 @@
     }
 
     /**
+     * Tests the saving/loading of WifiConfiguration to wpa_supplicant with psk passphrase for
+     * HAL v1.2 or higher
+     */
+    @Test
+    public void testPskPassphraseNetworkWifiConfigurationSaveLoad1_2OrHigher() throws Exception {
+        createSupplicantStaNetwork(SupplicantStaNetworkVersion.V1_2);
+        WifiConfiguration config = WifiConfigurationTestUtil.createPskNetwork();
+        config.requirePmf = true;
+
+        // Set the new defaults
+        config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.GCMP_256);
+        config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
+        config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.GCMP_256);
+        config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
+        testWifiConfigurationSaveLoad(config);
+        verify(mISupplicantStaNetworkMock).setPskPassphrase(anyString());
+        verify(mISupplicantStaNetworkMock)
+                .getPskPassphrase(any(ISupplicantStaNetwork.getPskPassphraseCallback.class));
+        verify(mISupplicantStaNetworkMock, never()).setPsk(any(byte[].class));
+        verify(mISupplicantStaNetworkMock, never())
+                .getPsk(any(ISupplicantStaNetwork.getPskCallback.class));
+        verify(mISupplicantStaNetworkV12)
+                .setPairwiseCipher_1_2(ISupplicantStaNetwork.PairwiseCipherMask.CCMP
+                        | android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork
+                        .PairwiseCipherMask.GCMP_256);
+        verify(mISupplicantStaNetworkV12)
+                .setGroupCipher_1_2(ISupplicantStaNetwork.GroupCipherMask.CCMP
+                        | android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork
+                        .GroupCipherMask.GCMP_256);
+    }
+
+    /**
      * Sets up the HIDL interface mock with all the setters/getter values.
      * Note: This only sets up the mock to return success on all methods.
      */
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java b/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java
index 8e199ec..f1ebd98 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java
@@ -51,6 +51,7 @@
 
 import com.android.dx.mockito.inline.extended.ExtendedMockito;
 import com.android.server.wifi.WifiScoreCard.PerNetwork;
+import com.android.server.wifi.proto.nano.WifiMetricsProto.UserActionEvent;
 import com.android.server.wifi.util.LruConnectionTracker;
 import com.android.server.wifi.util.WifiPermissionsUtil;
 import com.android.server.wifi.util.WifiPermissionsWrapper;
@@ -142,6 +143,7 @@
     @Mock private WifiNetworkSuggestionsManager mWifiNetworkSuggestionsManager;
     @Mock private WifiScoreCard mWifiScoreCard;
     @Mock private PerNetwork mPerNetwork;
+    @Mock private WifiMetrics mWifiMetrics;
     private LruConnectionTracker mLruConnectionTracker;
 
     private MockResources mResources;
@@ -222,6 +224,7 @@
         when(mWifiInjector.getWifiLastResortWatchdog().shouldIgnoreSsidUpdate())
                 .thenReturn(false);
         when(mWifiInjector.getMacAddressUtil()).thenReturn(mMacAddressUtil);
+        when(mWifiInjector.getWifiMetrics()).thenReturn(mWifiMetrics);
         when(mMacAddressUtil.calculatePersistentMac(any(), any())).thenReturn(TEST_RANDOMIZED_MAC);
         when(mWifiScoreCard.lookupNetwork(any())).thenReturn(mPerNetwork);
 
@@ -634,6 +637,8 @@
         networks.add(openNetwork);
 
         verifyAddNetworkToWifiConfigManager(openNetwork);
+        // Verify user action event is not logged when the network is added
+        verify(mWifiMetrics, never()).logUserActionEvent(anyInt(), anyBoolean(), anyBoolean());
         verify(mWcmListener).onNetworkAdded(wifiConfigCaptor.capture());
         assertEquals(openNetwork.networkId, wifiConfigCaptor.getValue().networkId);
         reset(mWcmListener);
@@ -642,6 +647,8 @@
         openNetwork.macRandomizationSetting = WifiConfiguration.RANDOMIZATION_NONE;
         NetworkUpdateResult networkUpdateResult = updateNetworkToWifiConfigManager(openNetwork);
         assertNotEquals(WifiConfiguration.INVALID_NETWORK_ID, networkUpdateResult.getNetworkId());
+        verify(mWifiMetrics).logUserActionEvent(
+                UserActionEvent.EVENT_CONFIGURE_MAC_RANDOMIZATION_OFF, openNetwork.networkId);
 
         List<WifiConfiguration> retrievedNetworks =
                 mWifiConfigManager.getConfiguredNetworksWithPasswords();
@@ -4460,7 +4467,7 @@
                 retrievedSavedNetwork.getNetworkSelectionStatus().getConnectChoice());
 
         // Disable the passpoint network & ensure the user choice is now removed from saved network.
-        mWifiConfigManager.userTemporarilyDisabledNetwork(passpointNetwork.FQDN);
+        mWifiConfigManager.userTemporarilyDisabledNetwork(passpointNetwork.FQDN, TEST_UPDATE_UID);
 
         retrievedSavedNetwork = mWifiConfigManager.getConfiguredNetwork(savedNetwork.networkId);
         assertNull(retrievedSavedNetwork.getNetworkSelectionStatus().getConnectChoice());
@@ -4468,6 +4475,7 @@
 
     @Test
     public void  testUserEnableDisabledNetwork() {
+        when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(true);
         WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork();
         List<WifiConfiguration> networks = new ArrayList<>();
         networks.add(openNetwork);
@@ -4477,10 +4485,12 @@
         WifiConfigurationTestUtil.assertConfigurationsEqualForConfigManagerAddOrUpdate(
                 networks, retrievedNetworks);
 
-        mWifiConfigManager.userTemporarilyDisabledNetwork(openNetwork.SSID);
+        mWifiConfigManager.userTemporarilyDisabledNetwork(openNetwork.SSID, TEST_UPDATE_UID);
         assertTrue(mWifiConfigManager.isNetworkTemporarilyDisabledByUser(openNetwork.SSID));
         mWifiConfigManager.userEnabledNetwork(retrievedNetworks.get(0).networkId);
         assertFalse(mWifiConfigManager.isNetworkTemporarilyDisabledByUser(openNetwork.SSID));
+        verify(mWifiMetrics).logUserActionEvent(eq(UserActionEvent.EVENT_DISCONNECT_WIFI),
+                anyInt());
     }
 
     @Test
@@ -4488,7 +4498,7 @@
         WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork();
         List<WifiConfiguration> networks = new ArrayList<>();
         networks.add(openNetwork);
-        mWifiConfigManager.userTemporarilyDisabledNetwork(openNetwork.SSID);
+        mWifiConfigManager.userTemporarilyDisabledNetwork(openNetwork.SSID, TEST_UPDATE_UID);
         assertTrue(mWifiConfigManager.isNetworkTemporarilyDisabledByUser(openNetwork.SSID));
 
         verifyAddNetworkToWifiConfigManager(openNetwork);
@@ -4504,7 +4514,7 @@
         WifiConfiguration passpointNetwork = WifiConfigurationTestUtil.createPasspointNetwork();
         List<WifiConfiguration> networks = new ArrayList<>();
         networks.add(passpointNetwork);
-        mWifiConfigManager.userTemporarilyDisabledNetwork(passpointNetwork.FQDN);
+        mWifiConfigManager.userTemporarilyDisabledNetwork(passpointNetwork.FQDN, TEST_UPDATE_UID);
         assertTrue(mWifiConfigManager.isNetworkTemporarilyDisabledByUser(passpointNetwork.FQDN));
         // Add new passpoint network will enable the network.
         NetworkUpdateResult result = addNetworkToWifiConfigManager(passpointNetwork);
@@ -4517,7 +4527,7 @@
                 networks, retrievedNetworks);
         assertFalse(mWifiConfigManager.isNetworkTemporarilyDisabledByUser(passpointNetwork.FQDN));
 
-        mWifiConfigManager.userTemporarilyDisabledNetwork(passpointNetwork.FQDN);
+        mWifiConfigManager.userTemporarilyDisabledNetwork(passpointNetwork.FQDN, TEST_UPDATE_UID);
         assertTrue(mWifiConfigManager.isNetworkTemporarilyDisabledByUser(passpointNetwork.FQDN));
         // Update a existing passpoint network will not enable network.
         result = addNetworkToWifiConfigManager(passpointNetwork);
@@ -4532,7 +4542,7 @@
         long currentTimeMs = disableTimeMs;
         when(mClock.getWallClockMillis()).thenReturn(currentTimeMs);
         String network = config.isPasspoint() ? config.FQDN : config.SSID;
-        mWifiConfigManager.userTemporarilyDisabledNetwork(network);
+        mWifiConfigManager.userTemporarilyDisabledNetwork(network, TEST_UPDATE_UID);
         // Before timer is triggered, timer will not expiry will enable network.
         currentTimeMs = disableTimeMs
                 + WifiConfigManager.USER_DISCONNECT_NETWORK_BLOCK_EXPIRY_MS + 1;
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java b/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java
index 653d8d9..d374dc9 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java
@@ -316,6 +316,8 @@
             - NUM_NETWORKS_ADDED_BY_USER;
     private static final boolean TEST_VAL_IS_LOCATION_ENABLED = true;
     private static final boolean IS_SCANNING_ALWAYS_ENABLED = true;
+    private static final boolean IS_VERBOSE_LOGGING_ENABLED = true;
+    private static final boolean IS_ENHANCED_MAC_RANDOMIZATION_FORCE_ENABLED = true;
     private static final int NUM_EMPTY_SCAN_RESULTS = 19;
     private static final int NUM_NON_EMPTY_SCAN_RESULTS = 23;
     private static final int NUM_SCAN_UNKNOWN = 1;
@@ -672,6 +674,9 @@
 
         mWifiMetrics.setIsLocationEnabled(TEST_VAL_IS_LOCATION_ENABLED);
         mWifiMetrics.setIsScanningAlwaysEnabled(IS_SCANNING_ALWAYS_ENABLED);
+        mWifiMetrics.setVerboseLoggingEnabled(IS_VERBOSE_LOGGING_ENABLED);
+        mWifiMetrics.setEnhancedMacRandomizationForceEnabled(
+                IS_ENHANCED_MAC_RANDOMIZATION_FORCE_ENABLED);
 
         for (int i = 0; i < NUM_EMPTY_SCAN_RESULTS; i++) {
             mWifiMetrics.incrementEmptyScanResultCount();
@@ -1119,6 +1124,9 @@
                 TEST_VAL_IS_LOCATION_ENABLED, mDecodedProto.isLocationEnabled);
         assertEquals("mDecodedProto.isScanningAlwaysEnabled == IS_SCANNING_ALWAYS_ENABLED",
                 IS_SCANNING_ALWAYS_ENABLED, mDecodedProto.isScanningAlwaysEnabled);
+        assertEquals(IS_VERBOSE_LOGGING_ENABLED, mDecodedProto.isVerboseLoggingEnabled);
+        assertEquals(IS_ENHANCED_MAC_RANDOMIZATION_FORCE_ENABLED,
+                mDecodedProto.isEnhancedMacRandomizationForceEnabled);
         assertEquals("mDecodedProto.numEmptyScanResults == NUM_EMPTY_SCAN_RESULTS",
                 NUM_EMPTY_SCAN_RESULTS, mDecodedProto.numEmptyScanResults);
         assertEquals("mDecodedProto.numNonEmptyScanResults == NUM_NON_EMPTY_SCAN_RESULTS",
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiNetworkFactoryTest.java b/tests/wifitests/src/com/android/server/wifi/WifiNetworkFactoryTest.java
index b495b49..ff31eb2 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiNetworkFactoryTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiNetworkFactoryTest.java
@@ -1036,7 +1036,7 @@
 
         // Now trigger user selection to some network.
         WifiConfiguration selectedNetwork = WifiConfigurationTestUtil.createOpenNetwork();
-        networkRequestUserSelectionCallback.select(selectedNetwork);
+        sendUserSelectionSelect(networkRequestUserSelectionCallback, selectedNetwork);
         mLooper.dispatchAll();
 
         // Verify we did not attempt to trigger a connection or disable connectivity manager.
@@ -1060,7 +1060,7 @@
 
         // Now trigger user selection to some network.
         WifiConfiguration selectedNetwork = WifiConfigurationTestUtil.createOpenNetwork();
-        networkRequestUserSelectionCallback.select(selectedNetwork);
+        sendUserSelectionSelect(networkRequestUserSelectionCallback, selectedNetwork);
         mLooper.dispatchAll();
 
         // Verify we did not attempt to trigger a connection or disable connectivity manager.
@@ -1082,7 +1082,7 @@
         ScanResult matchingScanResult = mTestScanDatas[0].getResults()[0];
         mSelectedNetwork = WifiConfigurationTestUtil.createPskNetwork();
         mSelectedNetwork.SSID = "\"" + mTestScanDatas[0].getResults()[0].SSID + "\"";
-        networkRequestUserSelectionCallback.select(mSelectedNetwork);
+        sendUserSelectionSelect(networkRequestUserSelectionCallback, mSelectedNetwork);
         mLooper.dispatchAll();
 
         // Cancel periodic scans.
@@ -1140,7 +1140,7 @@
         // Now trigger user selection to one of the network.
         mSelectedNetwork = WifiConfigurationTestUtil.createPskNetwork();
         mSelectedNetwork.SSID = "\"" + mTestScanDatas[0].getResults()[0].SSID + "\"";
-        networkRequestUserSelectionCallback.select(mSelectedNetwork);
+        sendUserSelectionSelect(networkRequestUserSelectionCallback, mSelectedNetwork);
         mLooper.dispatchAll();
 
         // Verifier num of Approved access points.
@@ -1150,7 +1150,7 @@
         // Now trigger user selection to another network with different SSID.
         mSelectedNetwork = WifiConfigurationTestUtil.createPskNetwork();
         mSelectedNetwork.SSID = "\"" + mTestScanDatas[0].getResults()[numOfApPerSsid].SSID + "\"";
-        networkRequestUserSelectionCallback.select(mSelectedNetwork);
+        sendUserSelectionSelect(networkRequestUserSelectionCallback, mSelectedNetwork);
         mLooper.dispatchAll();
 
         // Verify triggered trim when user Approved Access Points exceed capacity.
@@ -1187,7 +1187,7 @@
                 .thenReturn(matchingSavedNetwork);
 
         // Now trigger user selection to one of the network.
-        networkRequestUserSelectionCallback.select(mSelectedNetwork);
+        sendUserSelectionSelect(networkRequestUserSelectionCallback, mSelectedNetwork);
         mLooper.dispatchAll();
 
         // Cancel periodic scans.
@@ -1240,7 +1240,7 @@
         INetworkRequestUserSelectionCallback networkRequestUserSelectionCallback =
                 mNetworkRequestUserSelectionCallback.getValue();
         assertNotNull(networkRequestUserSelectionCallback);
-        networkRequestUserSelectionCallback.select(mSelectedNetwork);
+        sendUserSelectionSelect(networkRequestUserSelectionCallback, mSelectedNetwork);
         mLooper.dispatchAll();
 
         // Verify WifiConfiguration params.
@@ -1291,7 +1291,7 @@
         INetworkRequestUserSelectionCallback networkRequestUserSelectionCallback =
                 mNetworkRequestUserSelectionCallback.getValue();
         assertNotNull(networkRequestUserSelectionCallback);
-        networkRequestUserSelectionCallback.select(mSelectedNetwork);
+        sendUserSelectionSelect(networkRequestUserSelectionCallback, mSelectedNetwork);
         mLooper.dispatchAll();
 
         // Verify WifiConfiguration params.
@@ -1734,7 +1734,7 @@
 
         // Ignore stale callbacks.
         WifiConfiguration selectedNetwork = WifiConfigurationTestUtil.createOpenNetwork();
-        networkRequestUserSelectionCallback.select(selectedNetwork);
+        sendUserSelectionSelect(networkRequestUserSelectionCallback, selectedNetwork);
         mLooper.dispatchAll();
 
         verify(mNetworkRequestMatchCallback).onAbort();
@@ -2713,7 +2713,7 @@
         // Now trigger user selection to one of the network.
         mSelectedNetwork = WifiConfigurationTestUtil.createPskNetwork();
         mSelectedNetwork.SSID = "\"" + targetSsid + "\"";
-        networkRequestUserSelectionCallback.select(mSelectedNetwork);
+        sendUserSelectionSelect(networkRequestUserSelectionCallback, mSelectedNetwork);
         mLooper.dispatchAll();
 
         // Cancel the periodic scan timer.
@@ -3055,4 +3055,12 @@
                 WifiConfigStore.ENCRYPT_CREDENTIALS_CONFIG_STORE_DATA_VERSION,
                 mock(WifiConfigStoreEncryptionUtil.class));
     }
+
+    private void sendUserSelectionSelect(INetworkRequestUserSelectionCallback callback,
+            WifiConfiguration selectedNetwork) throws RemoteException {
+        WifiConfiguration selectedNetworkinCb = new WifiConfiguration();
+        // only copy over the ssid
+        selectedNetworkinCb.SSID = selectedNetwork.SSID;
+        callback.select(selectedNetworkinCb);
+    }
 }
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiNetworkSelectorTest.java b/tests/wifitests/src/com/android/server/wifi/WifiNetworkSelectorTest.java
index 4f303d1..7c5ff1f 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiNetworkSelectorTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiNetworkSelectorTest.java
@@ -1438,6 +1438,42 @@
         assertEquals(ssids[0], candidate.SSID);
     }
 
+    @Test
+    public void testIsFromCarrierOrPrivilegedApp() {
+        String[] ssids = {"\"test1\"", "\"test2\""};
+        String[] bssids = {"6c:f3:7f:ae:8c:f3", "6c:f3:7f:ae:8c:f4"};
+        int[] freqs = {2437, 5180};
+        String[] caps = {"[WPA2-EAP-CCMP][ESS]", "[WPA2-EAP-CCMP][ESS]"};
+        int[] levels = {mThresholdMinimumRssi2G + 1, mThresholdMinimumRssi5G + 1};
+        int[] securities = {SECURITY_EAP, SECURITY_EAP};
+        HashSet<String> blacklist = new HashSet<>();
+        ScanDetailsAndWifiConfigs scanDetailsAndConfigs =
+                WifiNetworkSelectorTestUtil.setupScanDetailsAndConfigStore(ssids, bssids,
+                        freqs, caps, levels, securities, mWifiConfigManager, mClock);
+        List<ScanDetail> scanDetails = scanDetailsAndConfigs.getScanDetails();
+        WifiConfiguration[] configs = scanDetailsAndConfigs.getWifiConfigs();
+        // Mark one of the networks as carrier privileged.
+        configs[0].fromWifiNetworkSuggestion = true;
+        configs[0].carrierId = 5;
+        mWifiNetworkSelector.registerNetworkNominator(
+                new AllNetworkNominator(scanDetailsAndConfigs));
+        List<WifiCandidates.Candidate> candidates = mWifiNetworkSelector.getCandidatesFromScan(
+                scanDetails, blacklist, mWifiInfo, false, true, true);
+        // Expect one privileged and one regular candidate.
+        assertEquals(2, candidates.size());
+        boolean foundCarrierOrPrivilegedAppCandidate = false;
+        boolean foundNotCarrierOrPrivilegedAppCandidate = false;
+        for (WifiCandidates.Candidate candidate : candidates) {
+            if (candidate.isCarrierOrPrivileged()) {
+                foundCarrierOrPrivilegedAppCandidate = true;
+            } else {
+                foundNotCarrierOrPrivilegedAppCandidate = true;
+            }
+        }
+        assertTrue(foundCarrierOrPrivilegedAppCandidate);
+        assertTrue(foundNotCarrierOrPrivilegedAppCandidate);
+    }
+
     /**
      * Test that network which are not accepting new connections(MBO
      * association disallowed attribute in beacons/probe responses)
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiScoreReportTest.java b/tests/wifitests/src/com/android/server/wifi/WifiScoreReportTest.java
index 5fe8eaa..674ff8c 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiScoreReportTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiScoreReportTest.java
@@ -661,8 +661,12 @@
         mWifiScoreReport.setWifiConnectedNetworkScorer(mAppBinder, mWifiConnectedNetworkScorer);
         when(mNetwork.getNetId()).thenReturn(TEST_NETWORK_ID);
         mWifiScoreReport.startConnectedNetworkScorer(TEST_NETWORK_ID);
+        verify(mWifiConnectedNetworkScorer).onStart(TEST_SESSION_ID);
         mWifiScoreReport.stopConnectedNetworkScorer();
         verify(mWifiConnectedNetworkScorer).onStop(TEST_SESSION_ID);
+        // After the session stops, it should not start again (without a new NetworkAgent)
+        mWifiScoreReport.startConnectedNetworkScorer(TEST_NETWORK_ID);
+        verify(mWifiConnectedNetworkScorer).onStart(anyInt());
     }
 
     /**
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java b/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java
index a11fc6d..d91dffb 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java
@@ -152,7 +152,7 @@
 import com.android.server.wifi.WifiServiceImpl.LocalOnlyRequestorCallback;
 import com.android.server.wifi.hotspot2.PasspointManager;
 import com.android.server.wifi.hotspot2.PasspointProvisioningTestUtil;
-import com.android.server.wifi.proto.nano.WifiMetricsProto;
+import com.android.server.wifi.proto.nano.WifiMetricsProto.UserActionEvent;
 import com.android.server.wifi.util.ApConfigUtil;
 import com.android.server.wifi.util.WifiAsyncChannel;
 import com.android.server.wifi.util.WifiPermissionsUtil;
@@ -510,6 +510,9 @@
     public void testWifiMetricsDump() {
         mWifiServiceImpl.dump(new FileDescriptor(), new PrintWriter(new StringWriter()),
                 new String[]{mWifiMetrics.PROTO_DUMP_ARG});
+        verify(mWifiMetrics).setEnhancedMacRandomizationForceEnabled(anyBoolean());
+        verify(mWifiMetrics).setIsScanningAlwaysEnabled(anyBoolean());
+        verify(mWifiMetrics).setVerboseLoggingEnabled(anyBoolean());
         verify(mWifiMetrics)
                 .dump(any(FileDescriptor.class), any(PrintWriter.class), any(String[].class));
         verify(mClientModeImpl, never())
@@ -559,13 +562,16 @@
     public void testSetWifiEnabledMetricsPrivilegedApp() throws Exception {
         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
+        when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(true);
         when(mSettingsStore.handleWifiToggled(anyBoolean())).thenReturn(true);
         when(mSettingsStore.isAirplaneModeOn()).thenReturn(false);
 
         InOrder inorder = inOrder(mWifiMetrics);
         assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true));
         assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, false));
+        inorder.verify(mWifiMetrics).logUserActionEvent(UserActionEvent.EVENT_TOGGLE_WIFI_ON);
         inorder.verify(mWifiMetrics).incrementNumWifiToggles(eq(true), eq(true));
+        inorder.verify(mWifiMetrics).logUserActionEvent(UserActionEvent.EVENT_TOGGLE_WIFI_OFF);
         inorder.verify(mWifiMetrics).incrementNumWifiToggles(eq(true), eq(false));
     }
 
@@ -3538,11 +3544,13 @@
     public void testConnectNetworkWithPrivilegedPermission() throws Exception {
         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
             anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
+        when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(true);
         mWifiServiceImpl.connect(mock(WifiConfiguration.class), TEST_NETWORK_ID,
                 mock(Binder.class),
                 mock(IActionListener.class), 0);
         verify(mClientModeImpl).connect(any(WifiConfiguration.class), anyInt(),
                 any(Binder.class), any(IActionListener.class), anyInt(), anyInt());
+        verify(mWifiMetrics).logUserActionEvent(eq(UserActionEvent.EVENT_MANUAL_CONNECT), anyInt());
     }
 
     /**
@@ -3573,7 +3581,7 @@
 
         InOrder inOrder = inOrder(mClientModeImpl, mWifiMetrics);
         inOrder.verify(mWifiMetrics).logUserActionEvent(
-                WifiMetricsProto.UserActionEvent.EVENT_FORGET_WIFI, TEST_NETWORK_ID);
+                UserActionEvent.EVENT_FORGET_WIFI, TEST_NETWORK_ID);
         inOrder.verify(mClientModeImpl).forget(anyInt(), any(Binder.class),
                 any(IActionListener.class), anyInt(), anyInt());
     }
@@ -4253,6 +4261,30 @@
     }
 
     /**
+     * Verify that add or update networks is allowed for apps holding system alert permission.
+     */
+    @Test
+    public void testAddOrUpdateNetworkIsAllowedForAppsWithSystemAlertPermission() throws Exception {
+        doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
+                .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
+        when(mWifiConfigManager.addOrUpdateNetwork(any(),  anyInt(), any())).thenReturn(
+                new NetworkUpdateResult(0));
+
+        when(mWifiPermissionsUtil.checkSystemAlertWindowPermission(
+                Process.myUid(), TEST_PACKAGE_NAME)).thenReturn(true);
+
+        WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork();
+        mLooper.startAutoDispatch();
+        assertEquals(0, mWifiServiceImpl.addOrUpdateNetwork(config, TEST_PACKAGE_NAME));
+        mLooper.stopAutoDispatchAndIgnoreExceptions();
+
+        verifyCheckChangePermission(TEST_PACKAGE_NAME);
+        verify(mWifiPermissionsUtil).checkSystemAlertWindowPermission(anyInt(), anyString());
+        verify(mWifiConfigManager).addOrUpdateNetwork(any(),  anyInt(), any());
+        verify(mWifiMetrics).incrementNumAddOrUpdateNetworkCalls();
+    }
+
+    /**
      * Verify that add or update networks is allowed for DeviceOwner app.
      */
     @Test
@@ -4517,7 +4549,7 @@
                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
         mWifiServiceImpl.disableEphemeralNetwork(new String(), TEST_PACKAGE_NAME);
         mLooper.dispatchAll();
-        verify(mWifiConfigManager).userTemporarilyDisabledNetwork(anyString());
+        verify(mWifiConfigManager).userTemporarilyDisabledNetwork(anyString(), anyInt());
     }
 
     /**
@@ -4530,7 +4562,7 @@
                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_DENIED);
         mWifiServiceImpl.disableEphemeralNetwork(new String(), TEST_PACKAGE_NAME);
         mLooper.dispatchAll();
-        verify(mWifiConfigManager, never()).userTemporarilyDisabledNetwork(anyString());
+        verify(mWifiConfigManager, never()).userTemporarilyDisabledNetwork(anyString(), anyInt());
     }
 
     /**
@@ -5047,6 +5079,7 @@
     @Test
     public void testAllowAutojoinOnSuggestionNetwork() {
         WifiConfiguration config = new WifiConfiguration();
+        config.allowAutojoin = false;
         config.fromWifiNetworkSuggestion = true;
         when(mWifiConfigManager.getConfiguredNetwork(anyInt())).thenReturn(config);
         when(mWifiNetworkSuggestionsManager.allowNetworkSuggestionAutojoin(any(), anyBoolean()))
@@ -5056,11 +5089,14 @@
         verify(mWifiConfigManager).getConfiguredNetwork(0);
         verify(mWifiNetworkSuggestionsManager).allowNetworkSuggestionAutojoin(any(), anyBoolean());
         verify(mWifiConfigManager).allowAutojoin(anyInt(), anyBoolean());
+        verify(mWifiMetrics).logUserActionEvent(eq(UserActionEvent.EVENT_CONFIGURE_AUTO_CONNECT_ON),
+                anyInt());
     }
 
     @Test
     public void testAllowAutojoinOnSavedNetwork() {
         WifiConfiguration config = new WifiConfiguration();
+        config.allowAutojoin = false;
         config.fromWifiNetworkSuggestion = false;
         config.fromWifiNetworkSpecifier = false;
         when(mWifiConfigManager.getConfiguredNetwork(0)).thenReturn(config);
diff --git a/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointManagerTest.java b/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointManagerTest.java
index 861aa94..e75cefc 100644
--- a/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointManagerTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointManagerTest.java
@@ -108,6 +108,7 @@
 import com.android.server.wifi.hotspot2.anqp.HSOsuProvidersElement;
 import com.android.server.wifi.hotspot2.anqp.I18Name;
 import com.android.server.wifi.hotspot2.anqp.OsuProviderInfo;
+import com.android.server.wifi.proto.nano.WifiMetricsProto.UserActionEvent;
 import com.android.server.wifi.util.InformationElementUtil;
 import com.android.server.wifi.util.InformationElementUtil.RoamingConsortium;
 
@@ -678,7 +679,7 @@
         }
 
         verify(provider).uninstallCertsAndKeys();
-        verify(mWifiConfigManager, times(2)).removePasspointConfiguredNetwork(
+        verify(mWifiConfigManager, times(3)).removePasspointConfiguredNetwork(
                 provider.getWifiConfig().getKey());
         /**
          * 1 from |removeProvider| + 2 from |setAutojoinEnabled| + 2 from
@@ -723,6 +724,7 @@
      * @param provider a mock provider that is already added into the PasspointManager
      */
     private void verifyEnableAutojoin(PasspointProvider provider, boolean useFqdn) {
+        when(provider.setAutojoinEnabled(anyBoolean())).thenReturn(true);
         if (useFqdn) {
             assertTrue(mManager.enableAutojoin(null, provider.getConfig().getHomeSp().getFqdn(),
                     false));
@@ -743,6 +745,10 @@
                     mManager.enableAutojoin(provider.getConfig().getHomeSp().getFqdn() + "-XXXX",
                             null, true));
         }
+        verify(mWifiMetrics).logUserActionEvent(UserActionEvent.EVENT_CONFIGURE_AUTO_CONNECT_OFF,
+                false, true);
+        verify(mWifiMetrics).logUserActionEvent(UserActionEvent.EVENT_CONFIGURE_AUTO_CONNECT_ON,
+                false, true);
     }
 
     /**
@@ -750,26 +756,35 @@
      * @param provider a mock provider that is already added into the PasspointManager
      */
     private void verifyEnableMacRandomization(PasspointProvider provider) {
+        when(provider.setMacRandomizationEnabled(anyBoolean())).thenReturn(true);
         assertTrue(mManager.enableMacRandomization(provider.getConfig().getHomeSp().getFqdn(),
                 false));
         verify(provider).setMacRandomizationEnabled(false);
-        when(provider.setMacRandomizationEnabled(true)).thenReturn(true);
+        verify(mWifiMetrics).logUserActionEvent(
+                UserActionEvent.EVENT_CONFIGURE_MAC_RANDOMIZATION_OFF, false, true);
         assertTrue(mManager.enableMacRandomization(provider.getConfig().getHomeSp().getFqdn(),
                 true));
-        verify(mWifiConfigManager).removePasspointConfiguredNetwork(
+        verify(mWifiConfigManager, times(2)).removePasspointConfiguredNetwork(
                 provider.getWifiConfig().getKey());
+        verify(mWifiMetrics).logUserActionEvent(
+                UserActionEvent.EVENT_CONFIGURE_MAC_RANDOMIZATION_ON, false, true);
         verify(provider).setMacRandomizationEnabled(true);
         assertFalse(mManager.enableMacRandomization(provider.getConfig().getHomeSp().getFqdn()
                 + "-XXXX", false));
     }
 
     private void verifySetMeteredOverride(PasspointProvider provider) {
+        when(provider.setMeteredOverride(anyInt())).thenReturn(true);
         assertTrue(mManager.setMeteredOverride(provider.getConfig().getHomeSp().getFqdn(),
                 METERED_OVERRIDE_METERED));
         verify(provider).setMeteredOverride(METERED_OVERRIDE_METERED);
+        verify(mWifiMetrics).logUserActionEvent(
+                UserActionEvent.EVENT_CONFIGURE_METERED_STATUS_METERED, false, true);
         assertTrue(mManager.setMeteredOverride(provider.getConfig().getHomeSp().getFqdn(),
                 METERED_OVERRIDE_NOT_METERED));
         verify(provider).setMeteredOverride(METERED_OVERRIDE_NOT_METERED);
+        verify(mWifiMetrics).logUserActionEvent(
+                UserActionEvent.EVENT_CONFIGURE_METERED_STATUS_UNMETERED, false, true);
         assertFalse(mManager.setMeteredOverride(provider.getConfig().getHomeSp().getFqdn()
                 + "-XXXX", METERED_OVERRIDE_METERED));
     }
diff --git a/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointNetworkNominateHelperTest.java b/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointNetworkNominateHelperTest.java
index 493be0f..32fcb70 100644
--- a/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointNetworkNominateHelperTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointNetworkNominateHelperTest.java
@@ -219,8 +219,8 @@
         // for the second (TEST_SSID2);
         when(mPasspointManager.matchProvider(any(ScanResult.class))).thenReturn(homeProvider)
                 .thenReturn(null);
-        when(mWifiConfigManager.addOrUpdateNetwork(any(WifiConfiguration.class), anyInt()))
-                .thenReturn(new NetworkUpdateResult(TEST_NETWORK_ID));
+        when(mWifiConfigManager.addOrUpdateNetwork(any(WifiConfiguration.class), anyInt(),
+                any())).thenReturn(new NetworkUpdateResult(TEST_NETWORK_ID));
         when(mWifiConfigManager.getConfiguredNetwork(TEST_NETWORK_ID)).thenReturn(TEST_CONFIG1);
         List<Pair<ScanDetail, WifiConfiguration>> candidates = mNominateHelper
                 .getPasspointNetworkCandidates(scanDetails, false);
@@ -229,7 +229,7 @@
         // Verify the content of the WifiConfiguration that was added to WifiConfigManager.
         ArgumentCaptor<WifiConfiguration> addedConfig =
                 ArgumentCaptor.forClass(WifiConfiguration.class);
-        verify(mWifiConfigManager).addOrUpdateNetwork(addedConfig.capture(), anyInt());
+        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);
@@ -260,7 +260,7 @@
         // for the second (TEST_SSID2);
         when(mPasspointManager.matchProvider(any(ScanResult.class))).thenReturn(roamingProvider)
                 .thenReturn(null);
-        when(mWifiConfigManager.addOrUpdateNetwork(any(WifiConfiguration.class), anyInt()))
+        when(mWifiConfigManager.addOrUpdateNetwork(any(WifiConfiguration.class), anyInt(), any()))
                 .thenReturn(new NetworkUpdateResult(TEST_NETWORK_ID));
         when(mWifiConfigManager.getConfiguredNetwork(TEST_NETWORK_ID)).thenReturn(TEST_CONFIG1);
         List<Pair<ScanDetail, WifiConfiguration>> candidates = mNominateHelper
@@ -270,7 +270,7 @@
         // Verify the content of the WifiConfiguration that was added to WifiConfigManager.
         ArgumentCaptor<WifiConfiguration> addedConfig =
                 ArgumentCaptor.forClass(WifiConfiguration.class);
-        verify(mWifiConfigManager).addOrUpdateNetwork(addedConfig.capture(), anyInt());
+        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);
@@ -305,8 +305,8 @@
         // roamingProvider for the second (TEST_SSID2);
         when(mPasspointManager.matchProvider(any(ScanResult.class)))
                 .thenReturn(homeProvider).thenReturn(roamingProvider);
-        when(mWifiConfigManager.addOrUpdateNetwork(any(WifiConfiguration.class), anyInt()))
-                .thenReturn(new NetworkUpdateResult(TEST_NETWORK_ID))
+        when(mWifiConfigManager.addOrUpdateNetwork(any(WifiConfiguration.class), anyInt(),
+                any())).thenReturn(new NetworkUpdateResult(TEST_NETWORK_ID))
                 .thenReturn(new NetworkUpdateResult(TEST_NETWORK_ID + 1));
         when(mWifiConfigManager.getConfiguredNetwork(TEST_NETWORK_ID)).thenReturn(TEST_CONFIG1);
         when(mWifiConfigManager.getConfiguredNetwork(TEST_NETWORK_ID + 1))
@@ -316,7 +316,7 @@
         assertEquals(2, candidates.size());
 
         verify(mWifiConfigManager, times(2))
-                .addOrUpdateNetwork(any(), anyInt());
+                .addOrUpdateNetwork(any(), anyInt(), any());
     }
 
     /**
@@ -339,8 +339,8 @@
         // roamingProvider for the second (TEST_SSID2);
         when(mPasspointManager.matchProvider(any(ScanResult.class)))
                 .thenReturn(homeProvider).thenReturn(roamingProvider);
-        when(mWifiConfigManager.addOrUpdateNetwork(any(WifiConfiguration.class), anyInt()))
-                .thenReturn(new NetworkUpdateResult(TEST_NETWORK_ID + 1));
+        when(mWifiConfigManager.addOrUpdateNetwork(any(WifiConfiguration.class), anyInt(),
+                any())).thenReturn(new NetworkUpdateResult(TEST_NETWORK_ID + 1));
         when(mWifiConfigManager.getConfiguredNetwork(TEST_NETWORK_ID)).thenReturn(TEST_CONFIG1);
         when(mWifiConfigManager.getConfiguredNetwork(TEST_NETWORK_ID + 1))
                 .thenReturn(TEST_CONFIG2);
@@ -349,7 +349,7 @@
         assertEquals(1, candidates.size());
         assertEquals(TEST_FQDN2, candidates.get(0).second.FQDN);
 
-        verify(mWifiConfigManager).addOrUpdateNetwork(any(), anyInt());
+        verify(mWifiConfigManager).addOrUpdateNetwork(any(), anyInt(), any());
     }
 
     /**
@@ -373,8 +373,8 @@
         // roamingProvider for the second (TEST_SSID2);
         when(mPasspointManager.matchProvider(any(ScanResult.class)))
                 .thenReturn(homeProvider).thenReturn(roamingProvider);
-        when(mWifiConfigManager.addOrUpdateNetwork(any(WifiConfiguration.class), anyInt()))
-                .thenReturn(new NetworkUpdateResult(TEST_NETWORK_ID))
+        when(mWifiConfigManager.addOrUpdateNetwork(any(WifiConfiguration.class), anyInt(),
+                any())).thenReturn(new NetworkUpdateResult(TEST_NETWORK_ID))
                 .thenReturn(new NetworkUpdateResult(TEST_NETWORK_ID + 1));
         when(mWifiConfigManager.getConfiguredNetwork(TEST_NETWORK_ID)).thenReturn(TEST_CONFIG1);
         when(mWifiConfigManager.getConfiguredNetwork(TEST_NETWORK_ID + 1))
@@ -383,7 +383,7 @@
                 .getPasspointNetworkCandidates(scanDetails, false);
         assertEquals(0, candidates.size());
 
-        verify(mWifiConfigManager, never()).addOrUpdateNetwork(any(), anyInt());
+        verify(mWifiConfigManager, never()).addOrUpdateNetwork(any(), anyInt(), any());
     }
 
 
@@ -409,8 +409,8 @@
         // SIM is present
         when(mSubscriptionManager.getActiveSubscriptionInfoList())
                 .thenReturn(Arrays.asList(mock(SubscriptionInfo.class)));
-        when(mWifiConfigManager.addOrUpdateNetwork(any(WifiConfiguration.class), anyInt()))
-                .thenReturn(new NetworkUpdateResult(TEST_NETWORK_ID));
+        when(mWifiConfigManager.addOrUpdateNetwork(any(WifiConfiguration.class), anyInt(),
+                any())).thenReturn(new NetworkUpdateResult(TEST_NETWORK_ID));
         when(mWifiConfigManager.getConfiguredNetwork(TEST_NETWORK_ID)).thenReturn(config);
 
         List<Pair<ScanDetail, WifiConfiguration>> candidates = mNominateHelper
@@ -440,8 +440,8 @@
 
         // Match the current connected network to a home provider.
         when(mPasspointManager.matchProvider(any(ScanResult.class))).thenReturn(homeProvider);
-        when(mWifiConfigManager.addOrUpdateNetwork(any(WifiConfiguration.class), anyInt()))
-                .thenReturn(new NetworkUpdateResult(TEST_NETWORK_ID));
+        when(mWifiConfigManager.addOrUpdateNetwork(any(WifiConfiguration.class), anyInt(),
+                any())).thenReturn(new NetworkUpdateResult(TEST_NETWORK_ID));
         when(mWifiConfigManager.getConfiguredNetwork(TEST_NETWORK_ID)).thenReturn(currentNetwork);
 
         List<Pair<ScanDetail, WifiConfiguration>> candidates = mNominateHelper
@@ -495,7 +495,7 @@
         List<Pair<ScanDetail, WifiConfiguration>> candidates = mNominateHelper
                 .getPasspointNetworkCandidates(scanDetails, false);
         verify(mWifiConfigManager, never()).addOrUpdateNetwork(any(WifiConfiguration.class),
-                anyInt());
+                anyInt(), any());
         assertTrue(candidates.isEmpty());
     }
 
@@ -513,8 +513,8 @@
 
         // Return homeProvider for the first ScanDetail (TEST_SSID1).
         when(mPasspointManager.matchProvider(any(ScanResult.class))).thenReturn(homeProvider);
-        when(mWifiConfigManager.addOrUpdateNetwork(any(WifiConfiguration.class), anyInt()))
-                .thenReturn(new NetworkUpdateResult(TEST_NETWORK_ID));
+        when(mWifiConfigManager.addOrUpdateNetwork(any(WifiConfiguration.class), anyInt(),
+                any())).thenReturn(new NetworkUpdateResult(TEST_NETWORK_ID));
         when(mWifiConfigManager.getConfiguredNetwork(TEST_NETWORK_ID)).thenReturn(TEST_CONFIG1);
         when(mWifiConfigManager.isNetworkTemporarilyDisabledByUser(TEST_FQDN1))
                 .thenReturn(true);
@@ -535,8 +535,8 @@
         homeProvider.add(Pair.create(sTestProvider1, PasspointMatch.HomeProvider));
 
         when(mPasspointManager.matchProvider(any(ScanResult.class))).thenReturn(homeProvider);
-        when(mWifiConfigManager.addOrUpdateNetwork(any(WifiConfiguration.class), anyInt()))
-                .thenReturn(new NetworkUpdateResult(TEST_NETWORK_ID));
+        when(mWifiConfigManager.addOrUpdateNetwork(any(WifiConfiguration.class), anyInt(),
+                any())).thenReturn(new NetworkUpdateResult(TEST_NETWORK_ID));
         when(mWifiConfigManager.getConfiguredNetwork(TEST_NETWORK_ID)).thenReturn(TEST_CONFIG1);
         // Setup WAN metrics status is 'LINK_STATUS_DOWN'
         HSWanMetricsElement wm = mock(HSWanMetricsElement.class);
@@ -570,8 +570,8 @@
         // roamingProvider for the second (TEST_SSID2);
         when(mPasspointManager.matchProvider(any(ScanResult.class)))
                 .thenReturn(roamingProvider).thenReturn(homeProvider);
-        when(mWifiConfigManager.addOrUpdateNetwork(any(WifiConfiguration.class), anyInt()))
-                .thenReturn(new NetworkUpdateResult(TEST_NETWORK_ID));
+        when(mWifiConfigManager.addOrUpdateNetwork(any(WifiConfiguration.class), anyInt(),
+                any())).thenReturn(new NetworkUpdateResult(TEST_NETWORK_ID));
         when(mWifiConfigManager.getConfiguredNetwork(TEST_NETWORK_ID)).thenReturn(TEST_CONFIG1);
 
         List<Pair<ScanDetail, WifiConfiguration>> candidates = mNominateHelper
@@ -602,8 +602,8 @@
         // roamingProvider for the second (TEST_SSID2);
         when(mPasspointManager.matchProvider(any(ScanResult.class)))
                 .thenReturn(homeProvider).thenReturn(roamingProvider);
-        when(mWifiConfigManager.addOrUpdateNetwork(any(WifiConfiguration.class), anyInt()))
-                .thenReturn(new NetworkUpdateResult(TEST_NETWORK_ID))
+        when(mWifiConfigManager.addOrUpdateNetwork(any(WifiConfiguration.class), anyInt(),
+                any())).thenReturn(new NetworkUpdateResult(TEST_NETWORK_ID))
                 .thenReturn(new NetworkUpdateResult(TEST_NETWORK_ID2));
         when(mWifiConfigManager.getConfiguredNetwork(TEST_NETWORK_ID)).thenReturn(TEST_CONFIG1);
         when(mWifiConfigManager.getConfiguredNetwork(TEST_NETWORK_ID2)).thenReturn(TEST_CONFIG2);
@@ -639,10 +639,10 @@
         homeProviders.add(Pair.create(suggestionProvider, PasspointMatch.HomeProvider));
         when(mPasspointManager.matchProvider(any(ScanResult.class)))
                 .thenReturn(homeProviders);
-        when(mWifiConfigManager.addOrUpdateNetwork(any(WifiConfiguration.class), anyInt()))
-                .thenReturn(new NetworkUpdateResult(TEST_NETWORK_ID));
-        when(mWifiConfigManager.addOrUpdateNetwork(any(WifiConfiguration.class), anyInt(), any()))
-                .thenReturn(new NetworkUpdateResult(TEST_NETWORK_ID2));
+        when(mWifiConfigManager.addOrUpdateNetwork(eq(TEST_CONFIG1), anyInt(),
+                any())).thenReturn(new NetworkUpdateResult(TEST_NETWORK_ID));
+        when(mWifiConfigManager.addOrUpdateNetwork(eq(suggestionConfig), anyInt(),
+                any())).thenReturn(new NetworkUpdateResult(TEST_NETWORK_ID2));
         when(mWifiConfigManager.getConfiguredNetwork(TEST_NETWORK_ID)).thenReturn(TEST_CONFIG1);
         when(mWifiConfigManager.getConfiguredNetwork(TEST_NETWORK_ID2))
                 .thenReturn(suggestionConfig);
@@ -701,8 +701,8 @@
         // for the second (TEST_SSID2);
         when(mPasspointManager.matchProvider(any(ScanResult.class))).thenReturn(homeProvider)
                 .thenReturn(null);
-        when(mWifiConfigManager.addOrUpdateNetwork(any(WifiConfiguration.class), anyInt()))
-                .thenReturn(new NetworkUpdateResult(TEST_NETWORK_ID));
+        when(mWifiConfigManager.addOrUpdateNetwork(any(WifiConfiguration.class), anyInt(),
+                any())).thenReturn(new NetworkUpdateResult(TEST_NETWORK_ID));
         when(mWifiConfigManager.getConfiguredNetwork(TEST_NETWORK_ID)).thenReturn(TEST_CONFIG1);
         List<Pair<ScanDetail, WifiConfiguration>> candidates = mNominateHelper
                 .getPasspointNetworkCandidates(scanDetails, false);