Merge "Ensure access to mobile network configs is restricted." into main
diff --git a/Android.bp b/Android.bp
index 4b90e06..78e6afb 100644
--- a/Android.bp
+++ b/Android.bp
@@ -45,7 +45,7 @@
         "modules-utils-os",
         "nist-sip",
         "service-entitlement",
-        "android.permission.flags-aconfig-java",
+        "android.permission.flags-aconfig-java-export",
         "satellite-s2storage-ro",
         "s2-geometry-library-java",
         "dropbox_flags_lib",
@@ -101,3 +101,4 @@
     name: "TeleService-platform-compat-config",
     src: ":TeleService",
 }
+
diff --git a/res/layout/radio_info.xml b/res/layout/radio_info.xml
index 1e5e91b..f18eda0 100644
--- a/res/layout/radio_info.xml
+++ b/res/layout/radio_info.xml
@@ -257,6 +257,16 @@
                 android:layout_height="wrap_content"
                 android:text="@string/mock_carrier_roaming_satellite_string"/>
 
+        <!-- ESOS -->
+        <Button android:id="@+id/esos_questionnaire"
+                android:textSize="14sp"
+                android:layout_marginTop="8dip"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:textAllCaps="false"
+                android:text="@string/esos_satellite_string"
+        />
+
         <!-- VoLTE provisioned -->
         <Switch android:id="@+id/volte_provisioned_switch"
                 android:textSize="14sp"
diff --git a/res/values-af/strings.xml b/res/values-af/strings.xml
index 8ba0a99..7fce427 100644
--- a/res/values-af/strings.xml
+++ b/res/values-af/strings.xml
@@ -845,6 +845,7 @@
     <string name="radio_info_radio_power" msgid="8805595022160471587">"Mobieleradiokrag"</string>
     <string name="simulate_out_of_service_string" msgid="7787925611727597193">"Simuleer is nie beskikbaar nie (Slegs ontfoutingbou)"</string>
     <string name="mock_carrier_roaming_satellite_string" msgid="4796300252858292593">"Satellietmodus van skyndiensverskaffer (net ontfoutingsbou)"</string>
+    <string name="esos_satellite_string" msgid="7274794226125968657">"Toets regte satelliet-eSOS-modus (net ontfoutingsbou)"</string>
     <string name="radioInfo_menu_viewADN" msgid="4533179730908559846">"Bekyk SIM-adresboek"</string>
     <string name="radioInfo_menu_viewFDN" msgid="1847236480527032061">"Kyk na vaste skakelnommers"</string>
     <string name="radioInfo_menu_viewSDN" msgid="2613431584522392842">"Bekyk skakeldiensnommers"</string>
diff --git a/res/values-am/strings.xml b/res/values-am/strings.xml
index 3846362..32dda83 100644
--- a/res/values-am/strings.xml
+++ b/res/values-am/strings.xml
@@ -845,6 +845,8 @@
     <string name="radio_info_radio_power" msgid="8805595022160471587">"የሞባይል ሬዲዮ ኃይል"</string>
     <string name="simulate_out_of_service_string" msgid="7787925611727597193">"ከአገልግሎት ውጭን አስመስል (የስህተት ማረሚያ ግንብ ብቻ)"</string>
     <string name="mock_carrier_roaming_satellite_string" msgid="4796300252858292593">"Mock Carrier Satellite Mode (የስህተት ማረሚያ ግንባታ ብቻ)"</string>
+    <!-- no translation found for esos_satellite_string (7274794226125968657) -->
+    <skip />
     <string name="radioInfo_menu_viewADN" msgid="4533179730908559846">"የሲም አድራሻ ደብተር አሳይ"</string>
     <string name="radioInfo_menu_viewFDN" msgid="1847236480527032061">"በቋሚነት የሚደወልባቸው ቁጥሮች"</string>
     <string name="radioInfo_menu_viewSDN" msgid="2613431584522392842">"የአገልግሎት መደወያ ቁጥሮችን ተመልከት"</string>
diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml
index 862be88..d2df67e 100644
--- a/res/values-ar/strings.xml
+++ b/res/values-ar/strings.xml
@@ -845,6 +845,8 @@
     <string name="radio_info_radio_power" msgid="8805595022160471587">"طاقة اللاسلكي للجوّال"</string>
     <string name="simulate_out_of_service_string" msgid="7787925611727597193">"محاكاة الخطأ \"خارج الخدمة\" (الإصدار المخصص لتصحيح الأخطاء فقط)"</string>
     <string name="mock_carrier_roaming_satellite_string" msgid="4796300252858292593">"وضع القمر الصناعي التجريبي لمشغّل شبكة الجوّال (إصدار مخصّص لتصحيح الأخطاء فقط)"</string>
+    <!-- no translation found for esos_satellite_string (7274794226125968657) -->
+    <skip />
     <string name="radioInfo_menu_viewADN" msgid="4533179730908559846">"‏عرض دفتر عناوين SIM"</string>
     <string name="radioInfo_menu_viewFDN" msgid="1847236480527032061">"عرض أرقام الطلب الثابت"</string>
     <string name="radioInfo_menu_viewSDN" msgid="2613431584522392842">"عرض أرقام طلب الخدمة"</string>
diff --git a/res/values-as/strings.xml b/res/values-as/strings.xml
index bc2eee1..57af0b1 100644
--- a/res/values-as/strings.xml
+++ b/res/values-as/strings.xml
@@ -845,6 +845,7 @@
     <string name="radio_info_radio_power" msgid="8805595022160471587">"ম’বাইলৰ ৰেডিঅ’ পাৱাৰ"</string>
     <string name="simulate_out_of_service_string" msgid="7787925611727597193">"সেৱাত নাই ছিমুলে’ট কৰক (কেৱল ডিবাগ বিল্ড)"</string>
     <string name="mock_carrier_roaming_satellite_string" msgid="4796300252858292593">"নকল বাহক উপগ্ৰহ ম’ড (কেৱল ডিবাগ বিল্ড)"</string>
+    <string name="esos_satellite_string" msgid="7274794226125968657">"বাস্তৱিক উপগ্ৰহৰ eSOS ম’ড পৰীক্ষা কৰক (কেৱল ডিবাগ বিল্ড)"</string>
     <string name="radioInfo_menu_viewADN" msgid="4533179730908559846">"ছিম ঠিকনা সূচী চাওক"</string>
     <string name="radioInfo_menu_viewFDN" msgid="1847236480527032061">"ফিক্সড্ ডায়েলিং নম্বৰসমূহ চাওক"</string>
     <string name="radioInfo_menu_viewSDN" msgid="2613431584522392842">"সেৱা ডায়েলিং নম্বৰসমূহ চাওক"</string>
diff --git a/res/values-az/strings.xml b/res/values-az/strings.xml
index f443d39..9277e9b 100644
--- a/res/values-az/strings.xml
+++ b/res/values-az/strings.xml
@@ -845,6 +845,7 @@
     <string name="radio_info_radio_power" msgid="8805595022160471587">"Mobil Radio Enerjisi"</string>
     <string name="simulate_out_of_service_string" msgid="7787925611727597193">"\"Xidmətdənkənar\" Simulyasiyası (yalnız Debaq Versiyası)"</string>
     <string name="mock_carrier_roaming_satellite_string" msgid="4796300252858292593">"Sınaq Daşıyıcı Peyk Rejimi (yalnız sazlama versiyası)"</string>
+    <string name="esos_satellite_string" msgid="7274794226125968657">"Real peyk eSOS rejimini sınaqdan keçirin (yalnız sazlama versiyası)"</string>
     <string name="radioInfo_menu_viewADN" msgid="4533179730908559846">"SIM Ünvan Kitabçasına Baxın"</string>
     <string name="radioInfo_menu_viewFDN" msgid="1847236480527032061">"Sabit Yığım Nömrələrinə Baxın"</string>
     <string name="radioInfo_menu_viewSDN" msgid="2613431584522392842">"Xidmət Yığım Nömrələrinə Baxın"</string>
diff --git a/res/values-b+sr+Latn/strings.xml b/res/values-b+sr+Latn/strings.xml
index 06f6a0a..8bb9e1c 100644
--- a/res/values-b+sr+Latn/strings.xml
+++ b/res/values-b+sr+Latn/strings.xml
@@ -845,6 +845,8 @@
     <string name="radio_info_radio_power" msgid="8805595022160471587">"Napajanje za radio na mobilnim uređajima"</string>
     <string name="simulate_out_of_service_string" msgid="7787925611727597193">"Simulacija ne funkcioniše (samo verzija sa otklonjenim greškama)"</string>
     <string name="mock_carrier_roaming_satellite_string" msgid="4796300252858292593">"Lažni režim mobilnog operatera za slanje preko satelita (samo verzija za otklanjanje grešaka)"</string>
+    <!-- no translation found for esos_satellite_string (7274794226125968657) -->
+    <skip />
     <string name="radioInfo_menu_viewADN" msgid="4533179730908559846">"Prikaži adresar SIM-a"</string>
     <string name="radioInfo_menu_viewFDN" msgid="1847236480527032061">"Prikaži brojeve za fiksno biranje"</string>
     <string name="radioInfo_menu_viewSDN" msgid="2613431584522392842">"Prikaži brojeve za servisno biranje"</string>
diff --git a/res/values-be/strings.xml b/res/values-be/strings.xml
index 76c6676..b772e13 100644
--- a/res/values-be/strings.xml
+++ b/res/values-be/strings.xml
@@ -845,6 +845,7 @@
     <string name="radio_info_radio_power" msgid="8805595022160471587">"Магутнасць радыёсігналу"</string>
     <string name="simulate_out_of_service_string" msgid="7787925611727597193">"Мадэляванне знаходжання па-за сеткай (толькі ў зборцы для адладкі)"</string>
     <string name="mock_carrier_roaming_satellite_string" msgid="4796300252858292593">"Імітацыя рэжыму спадарожніка з SIM-картай ад аператара (толькі ў зборцы для адладкі)"</string>
+    <string name="esos_satellite_string" msgid="7274794226125968657">"Тэсціраванне рэальнага рэжыму спадарожнікавага падключэння eSOS (толькі ў зборцы для адладкі)"</string>
     <string name="radioInfo_menu_viewADN" msgid="4533179730908559846">"Праглядзець адрасную кнігу на SIM-карце"</string>
     <string name="radioInfo_menu_viewFDN" msgid="1847236480527032061">"Прагляд фіксаваных нумароў"</string>
     <string name="radioInfo_menu_viewSDN" msgid="2613431584522392842">"Паглядзець сэрвісныя нумары"</string>
diff --git a/res/values-bg/strings.xml b/res/values-bg/strings.xml
index 6266c3b..9481a0b 100644
--- a/res/values-bg/strings.xml
+++ b/res/values-bg/strings.xml
@@ -845,6 +845,8 @@
     <string name="radio_info_radio_power" msgid="8805595022160471587">"Мощност на мобилното радио"</string>
     <string name="simulate_out_of_service_string" msgid="7787925611727597193">"Симулиране на липса на услуга (само в компилацията за отстраняване на грешки)"</string>
     <string name="mock_carrier_roaming_satellite_string" msgid="4796300252858292593">"Симулиран сателитен режим от оператора (само в компилацията за отстраняване на грешки)"</string>
+    <!-- no translation found for esos_satellite_string (7274794226125968657) -->
+    <skip />
     <string name="radioInfo_menu_viewADN" msgid="4533179730908559846">"Преглед на указателя на SIM картата"</string>
     <string name="radioInfo_menu_viewFDN" msgid="1847236480527032061">"Преглед на номера за фиксирано набиране"</string>
     <string name="radioInfo_menu_viewSDN" msgid="2613431584522392842">"Преглед на номера за набиране на услуги"</string>
diff --git a/res/values-bn/strings.xml b/res/values-bn/strings.xml
index d562b95..616e313 100644
--- a/res/values-bn/strings.xml
+++ b/res/values-bn/strings.xml
@@ -845,6 +845,8 @@
     <string name="radio_info_radio_power" msgid="8805595022160471587">"মোবাইল রেডিওর গুণমান"</string>
     <string name="simulate_out_of_service_string" msgid="7787925611727597193">"আউট-অফ-সার্ভিস সিমুলেট করা (শুধুমাত্র ডিবাগ বিল্ডের জন্য)"</string>
     <string name="mock_carrier_roaming_satellite_string" msgid="4796300252858292593">"নকল পরিষেবা প্রদানকারী উপগ্রহ মোড (শুধুমাত্র ডিবাগ বিল্ড)"</string>
+    <!-- no translation found for esos_satellite_string (7274794226125968657) -->
+    <skip />
     <string name="radioInfo_menu_viewADN" msgid="4533179730908559846">"সিম অ্যাড্রেস বুক দেখুন"</string>
     <string name="radioInfo_menu_viewFDN" msgid="1847236480527032061">"স্থায়ী ডায়াল নম্বরগুলি দেখুন"</string>
     <string name="radioInfo_menu_viewSDN" msgid="2613431584522392842">"সার্ভিস ডায়াল নম্বরগুলি দেখুন"</string>
diff --git a/res/values-bs/strings.xml b/res/values-bs/strings.xml
index 2cbbcc8..cccbaec 100644
--- a/res/values-bs/strings.xml
+++ b/res/values-bs/strings.xml
@@ -845,6 +845,7 @@
     <string name="radio_info_radio_power" msgid="8805595022160471587">"Snaga mobilnog radija"</string>
     <string name="simulate_out_of_service_string" msgid="7787925611727597193">"Simulacija ne radi (samo verzija za otklanjanje grešaka)"</string>
     <string name="mock_carrier_roaming_satellite_string" msgid="4796300252858292593">"Lažni način rada operatera za slanje putem satelita (samo verzija za otklanjanje grešaka)"</string>
+    <string name="esos_satellite_string" msgid="7274794226125968657">"Testiraj stvarni način rada satelitskog eSOS-a (samo verzija za otklanjanje grešaka)"</string>
     <string name="radioInfo_menu_viewADN" msgid="4533179730908559846">"Prikaži SIM adresar"</string>
     <string name="radioInfo_menu_viewFDN" msgid="1847236480527032061">"Prikaži brojeve fiksnog biranja"</string>
     <string name="radioInfo_menu_viewSDN" msgid="2613431584522392842">"Prikaži brojeve biranja usluga"</string>
diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml
index 3bfa70b..8a5dcca 100644
--- a/res/values-ca/strings.xml
+++ b/res/values-ca/strings.xml
@@ -845,6 +845,7 @@
     <string name="radio_info_radio_power" msgid="8805595022160471587">"Potència del senyal mòbil"</string>
     <string name="simulate_out_of_service_string" msgid="7787925611727597193">"Simula que està fora de servei (només per a la compilació de depuració)"</string>
     <string name="mock_carrier_roaming_satellite_string" msgid="4796300252858292593">"Mode de satèl·lit d\'un operador de telefonia mòbil simulat (només per a la compilació de depuració)"</string>
+    <string name="esos_satellite_string" msgid="7274794226125968657">"Provar el mode eSOS de satèl·lit real (només per a la compilació de depuració)"</string>
     <string name="radioInfo_menu_viewADN" msgid="4533179730908559846">"Mostra la llibreta d\'adreces de la SIM"</string>
     <string name="radioInfo_menu_viewFDN" msgid="1847236480527032061">"Mostra els números de marcatge fix"</string>
     <string name="radioInfo_menu_viewSDN" msgid="2613431584522392842">"Mostra els números de marcatge de serveis"</string>
diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml
index 552567d..2ce9f7f 100644
--- a/res/values-cs/strings.xml
+++ b/res/values-cs/strings.xml
@@ -845,6 +845,8 @@
     <string name="radio_info_radio_power" msgid="8805595022160471587">"Výkon mobilního přijímače"</string>
     <string name="simulate_out_of_service_string" msgid="7787925611727597193">"Simulovat provoz mimo službu (pouze ladicí sestavení)"</string>
     <string name="mock_carrier_roaming_satellite_string" msgid="4796300252858292593">"Simulace satelitního režimu operátora (pouze ladicí sestavení)"</string>
+    <!-- no translation found for esos_satellite_string (7274794226125968657) -->
+    <skip />
     <string name="radioInfo_menu_viewADN" msgid="4533179730908559846">"Zobrazit adresář SIM karty"</string>
     <string name="radioInfo_menu_viewFDN" msgid="1847236480527032061">"Zobrazit povolená telefonní čísla"</string>
     <string name="radioInfo_menu_viewSDN" msgid="2613431584522392842">"Zobrazit čísla volání služeb"</string>
diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml
index e099858..866250c 100644
--- a/res/values-da/strings.xml
+++ b/res/values-da/strings.xml
@@ -845,6 +845,7 @@
     <string name="radio_info_radio_power" msgid="8805595022160471587">"Mobilsendestyrke"</string>
     <string name="simulate_out_of_service_string" msgid="7787925611727597193">"Simulering af enhed, der er ude af drift (kun i fejlretningsbuild)"</string>
     <string name="mock_carrier_roaming_satellite_string" msgid="4796300252858292593">"Test af satellittilstand via mobilselskab (kun fejlretningsbuild)"</string>
+    <string name="esos_satellite_string" msgid="7274794226125968657">"Test af virkelig eSOS-satellittilstand (kun fejlretningsbuild)"</string>
     <string name="radioInfo_menu_viewADN" msgid="4533179730908559846">"Vis adressebog på SIM-kortet"</string>
     <string name="radioInfo_menu_viewFDN" msgid="1847236480527032061">"Vis numre til begrænset opkald"</string>
     <string name="radioInfo_menu_viewSDN" msgid="2613431584522392842">"Vis tjenestens faste opkaldsnumre"</string>
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index 06da7f9..1cd26ba 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -845,6 +845,7 @@
     <string name="radio_info_radio_power" msgid="8805595022160471587">"Mobilfunkstärke"</string>
     <string name="simulate_out_of_service_string" msgid="7787925611727597193">"„Außer Betrieb“ simulieren (nur Debug-Build)"</string>
     <string name="mock_carrier_roaming_satellite_string" msgid="4796300252858292593">"Vom Mobilfunkanbieter simulierter Satellitenmodus (nur Debug-Build)"</string>
+    <string name="esos_satellite_string" msgid="7274794226125968657">"eSOS-Modus mit echtem Satelliten testen (nur Debug-Build)"</string>
     <string name="radioInfo_menu_viewADN" msgid="4533179730908559846">"SIM-Adressbuch anzeigen"</string>
     <string name="radioInfo_menu_viewFDN" msgid="1847236480527032061">"Rufnummernbeschränkung ansehen"</string>
     <string name="radioInfo_menu_viewSDN" msgid="2613431584522392842">"Servicerufnummern anzeigen"</string>
diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml
index 324fc41..d2e0b91 100644
--- a/res/values-el/strings.xml
+++ b/res/values-el/strings.xml
@@ -845,6 +845,8 @@
     <string name="radio_info_radio_power" msgid="8805595022160471587">"Ισχύς πομπού κινητής τηλεφωνίας"</string>
     <string name="simulate_out_of_service_string" msgid="7787925611727597193">"Η προσομοίωση δεν λειτουργεί (μόνο έκδοση εντοπισμού σφαλμάτων)"</string>
     <string name="mock_carrier_roaming_satellite_string" msgid="4796300252858292593">"Εικονική λειτουργία δορυφόρου εταιρείας κινητής τηλεφωνίας (μόνο έκδοση εντοπισμού σφαλμάτων)"</string>
+    <!-- no translation found for esos_satellite_string (7274794226125968657) -->
+    <skip />
     <string name="radioInfo_menu_viewADN" msgid="4533179730908559846">"Προβολή βιβλίου διευθύνσεων κάρτας SIM"</string>
     <string name="radioInfo_menu_viewFDN" msgid="1847236480527032061">"Προβολή προκαθορισμένων αριθμών κλήσης"</string>
     <string name="radioInfo_menu_viewSDN" msgid="2613431584522392842">"Προβολή αριθμών κλήσης υπηρεσίας"</string>
diff --git a/res/values-en-rAU/strings.xml b/res/values-en-rAU/strings.xml
index 2a602c2..a411ae6 100644
--- a/res/values-en-rAU/strings.xml
+++ b/res/values-en-rAU/strings.xml
@@ -845,6 +845,7 @@
     <string name="radio_info_radio_power" msgid="8805595022160471587">"Mobile radio power"</string>
     <string name="simulate_out_of_service_string" msgid="7787925611727597193">"Simulate out of service (debug build only)"</string>
     <string name="mock_carrier_roaming_satellite_string" msgid="4796300252858292593">"Mock operator satellite mode (debug build only)"</string>
+    <string name="esos_satellite_string" msgid="7274794226125968657">"Test real satellite eSOS mode (debug build only)"</string>
     <string name="radioInfo_menu_viewADN" msgid="4533179730908559846">"View SIM address book"</string>
     <string name="radioInfo_menu_viewFDN" msgid="1847236480527032061">"View fixed dialling numbers"</string>
     <string name="radioInfo_menu_viewSDN" msgid="2613431584522392842">"View service dialling numbers"</string>
diff --git a/res/values-en-rCA/strings.xml b/res/values-en-rCA/strings.xml
index 5fb42ff..c27292d 100644
--- a/res/values-en-rCA/strings.xml
+++ b/res/values-en-rCA/strings.xml
@@ -845,6 +845,7 @@
     <string name="radio_info_radio_power" msgid="8805595022160471587">"Mobile Radio Power"</string>
     <string name="simulate_out_of_service_string" msgid="7787925611727597193">"Simulate Out of Service (Debug Build only)"</string>
     <string name="mock_carrier_roaming_satellite_string" msgid="4796300252858292593">"Mock Carrier Satellite Mode (Debug Build only)"</string>
+    <string name="esos_satellite_string" msgid="7274794226125968657">"Test real satellite eSOS mode (Debug Build only)"</string>
     <string name="radioInfo_menu_viewADN" msgid="4533179730908559846">"View SIM Address Book"</string>
     <string name="radioInfo_menu_viewFDN" msgid="1847236480527032061">"View Fixed Dialing Numbers"</string>
     <string name="radioInfo_menu_viewSDN" msgid="2613431584522392842">"View Service Dialing Numbers"</string>
diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml
index 2a602c2..a411ae6 100644
--- a/res/values-en-rGB/strings.xml
+++ b/res/values-en-rGB/strings.xml
@@ -845,6 +845,7 @@
     <string name="radio_info_radio_power" msgid="8805595022160471587">"Mobile radio power"</string>
     <string name="simulate_out_of_service_string" msgid="7787925611727597193">"Simulate out of service (debug build only)"</string>
     <string name="mock_carrier_roaming_satellite_string" msgid="4796300252858292593">"Mock operator satellite mode (debug build only)"</string>
+    <string name="esos_satellite_string" msgid="7274794226125968657">"Test real satellite eSOS mode (debug build only)"</string>
     <string name="radioInfo_menu_viewADN" msgid="4533179730908559846">"View SIM address book"</string>
     <string name="radioInfo_menu_viewFDN" msgid="1847236480527032061">"View fixed dialling numbers"</string>
     <string name="radioInfo_menu_viewSDN" msgid="2613431584522392842">"View service dialling numbers"</string>
diff --git a/res/values-en-rIN/strings.xml b/res/values-en-rIN/strings.xml
index 2a602c2..a411ae6 100644
--- a/res/values-en-rIN/strings.xml
+++ b/res/values-en-rIN/strings.xml
@@ -845,6 +845,7 @@
     <string name="radio_info_radio_power" msgid="8805595022160471587">"Mobile radio power"</string>
     <string name="simulate_out_of_service_string" msgid="7787925611727597193">"Simulate out of service (debug build only)"</string>
     <string name="mock_carrier_roaming_satellite_string" msgid="4796300252858292593">"Mock operator satellite mode (debug build only)"</string>
+    <string name="esos_satellite_string" msgid="7274794226125968657">"Test real satellite eSOS mode (debug build only)"</string>
     <string name="radioInfo_menu_viewADN" msgid="4533179730908559846">"View SIM address book"</string>
     <string name="radioInfo_menu_viewFDN" msgid="1847236480527032061">"View fixed dialling numbers"</string>
     <string name="radioInfo_menu_viewSDN" msgid="2613431584522392842">"View service dialling numbers"</string>
diff --git a/res/values-en-rXC/strings.xml b/res/values-en-rXC/strings.xml
index 9af3f97..2f6fcfa 100644
--- a/res/values-en-rXC/strings.xml
+++ b/res/values-en-rXC/strings.xml
@@ -845,6 +845,7 @@
     <string name="radio_info_radio_power" msgid="8805595022160471587">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‎‎‏‏‎‎‏‏‏‏‎‎‎‎‏‎‎‎‎‎‎‏‎‎‏‏‎‎‎‎‏‏‏‏‎‏‎‎‏‎‏‎‏‎‎‏‏‎‎‎‏‎‎‎‏‏‎Mobile Radio Power‎‏‎‎‏‎"</string>
     <string name="simulate_out_of_service_string" msgid="7787925611727597193">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‎‎‎‎‏‎‏‎‎‎‏‎‎‎‏‎‏‎‎‎‏‎‏‎‎‏‏‏‎‏‎‎‎‎‎‏‏‎‎‎‎‏‎‏‎‏‏‏‎‏‎‎‎‏‎‎‏‎Simulate Out of Service (Debug Build only)‎‏‎‎‏‎"</string>
     <string name="mock_carrier_roaming_satellite_string" msgid="4796300252858292593">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‏‏‏‏‏‏‎‎‎‎‏‎‏‎‎‎‏‏‏‏‏‏‏‎‎‎‎‏‏‎‏‎‏‎‏‏‎‎‎‎‎‏‏‏‏‎‏‏‏‏‎‎‎‎‎‏‏‎‎‏‎‏‏‏‎‎‎‏‎Mock Carrier Satellite Mode (Debug Build only)‎‏‎‎‏‎"</string>
+    <string name="esos_satellite_string" msgid="7274794226125968657">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‏‏‏‏‎‏‎‏‎‏‎‎‎‎‏‎‏‏‎‎‏‏‏‎‎‎‎‏‏‏‏‎‎‏‎‎‏‏‎‏‎‎‎‏‎‏‎‏‎‎‎‏‎‎‎‏‎Test real satellite eSOS mode (Debug Build only)‎‏‎‎‏‎"</string>
     <string name="radioInfo_menu_viewADN" msgid="4533179730908559846">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‎‏‏‏‎‏‎‎‏‎‎‎‏‎‏‏‎‏‏‏‏‎‎‏‎‏‎‎‎‏‎‏‏‏‏‎‎‏‏‏‎‎‎‏‏‏‎‎‏‏‏‏‎‎‏‏‎‎View SIM Address Book‎‏‎‎‏‎"</string>
     <string name="radioInfo_menu_viewFDN" msgid="1847236480527032061">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‏‏‏‎‏‏‏‎‎‏‏‎‏‎‎‎‏‎‏‎‏‏‎‎‏‏‏‏‎‎‏‎‏‎‏‎‏‏‏‏‎‏‏‏‏‏‎‏‎‎‏‏‎‏‏‏‏‎‏‏‏‏‏‏‎‏‎View Fixed Dialing Numbers‎‏‎‎‏‎"</string>
     <string name="radioInfo_menu_viewSDN" msgid="2613431584522392842">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‏‏‏‏‎‏‎‎‏‎‎‎‏‎‎‎‏‎‎‏‏‎‎‎‏‏‎‎‎‏‎‏‏‎‏‏‏‏‏‏‎‎‎‎‎‏‏‏‏‏‎‎‏‎‏‎‏‎‏‎‎‎‎‏‎‏‎‎View Service Dialing Numbers‎‏‎‎‏‎"</string>
diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml
index 77865c2..6923c98 100644
--- a/res/values-es-rUS/strings.xml
+++ b/res/values-es-rUS/strings.xml
@@ -845,6 +845,7 @@
     <string name="radio_info_radio_power" msgid="8805595022160471587">"Potencia de la señal móvil"</string>
     <string name="simulate_out_of_service_string" msgid="7787925611727597193">"Simular fuera de servicio (solo para la compilación de depuración)"</string>
     <string name="mock_carrier_roaming_satellite_string" msgid="4796300252858292593">"Modo Satélite del operador de prueba (solo en la compilación de depuración)"</string>
+    <string name="esos_satellite_string" msgid="7274794226125968657">"Prueba el modo eSOS de satélite real (solo en la compilación de depuración)"</string>
     <string name="radioInfo_menu_viewADN" msgid="4533179730908559846">"Ver libreta de direcciones de SIM"</string>
     <string name="radioInfo_menu_viewFDN" msgid="1847236480527032061">"Ver números de marcación fija"</string>
     <string name="radioInfo_menu_viewSDN" msgid="2613431584522392842">"Ver números de marcación de servicio"</string>
diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml
index 1fbc5f2..fa7a08c 100644
--- a/res/values-es/strings.xml
+++ b/res/values-es/strings.xml
@@ -845,6 +845,8 @@
     <string name="radio_info_radio_power" msgid="8805595022160471587">"Potencia de la señal móvil"</string>
     <string name="simulate_out_of_service_string" msgid="7787925611727597193">"Simular fuera del servicio (solo versión de depuración)"</string>
     <string name="mock_carrier_roaming_satellite_string" msgid="4796300252858292593">"Simulación del modo Satélite de operador (solo versión de depuración)"</string>
+    <!-- no translation found for esos_satellite_string (7274794226125968657) -->
+    <skip />
     <string name="radioInfo_menu_viewADN" msgid="4533179730908559846">"Ver libreta de direcciones de tarjeta SIM"</string>
     <string name="radioInfo_menu_viewFDN" msgid="1847236480527032061">"Ver números de marcación fija"</string>
     <string name="radioInfo_menu_viewSDN" msgid="2613431584522392842">"Ver números de marcación de servicio"</string>
diff --git a/res/values-et/strings.xml b/res/values-et/strings.xml
index 6b3c1c1..beeed08 100644
--- a/res/values-et/strings.xml
+++ b/res/values-et/strings.xml
@@ -845,6 +845,8 @@
     <string name="radio_info_radio_power" msgid="8805595022160471587">"Mobiiliraadio toide"</string>
     <string name="simulate_out_of_service_string" msgid="7787925611727597193">"Simuleerimine ei tööta (ainult silumisjärgus)"</string>
     <string name="mock_carrier_roaming_satellite_string" msgid="4796300252858292593">"Simuleeritud operaatori satelliidirežiim (ainult silumisjärgus)"</string>
+    <!-- no translation found for esos_satellite_string (7274794226125968657) -->
+    <skip />
     <string name="radioInfo_menu_viewADN" msgid="4533179730908559846">"Kuva SIM-i aadressiraamat"</string>
     <string name="radioInfo_menu_viewFDN" msgid="1847236480527032061">"Kuva fikseeritud valimisnumbrid"</string>
     <string name="radioInfo_menu_viewSDN" msgid="2613431584522392842">"Kuva teenuse valimise numbrid"</string>
diff --git a/res/values-eu/strings.xml b/res/values-eu/strings.xml
index 82627d7..f655bdd 100644
--- a/res/values-eu/strings.xml
+++ b/res/values-eu/strings.xml
@@ -305,7 +305,7 @@
     <string name="keywords_carrier_settings_euicc" msgid="8540160967922063745">"operadorea, esim, esim txartela, sim, sim txartela, euicc, euicc txartela, aldatu operadoreak, aldatu operadorez, aldatu operadorea, gehitu operadorea, gehitu operadoreak"</string>
     <string name="carrier_settings_euicc_summary" msgid="2027941166597330117">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>: <xliff:g id="PHONE_NUMBER">%2$s</xliff:g>"</string>
     <string name="mobile_data_settings_title" msgid="7228249980933944101">"Datu-konexioa"</string>
-    <string name="mobile_data_settings_summary" msgid="5012570152029118471">"Atzitu datuak datu-konexioaren bidez"</string>
+    <string name="mobile_data_settings_summary" msgid="5012570152029118471">"Atzitu datuak sare mugikorraren bidez"</string>
     <string name="data_usage_disable_mobile" msgid="5669109209055988308">"Datu-konexioa desaktibatu nahi duzu?"</string>
     <string name="sim_selection_required_pref" msgid="6985901872978341314">"Hautatu egin behar da"</string>
     <string name="sim_change_data_title" msgid="9142726786345906606">"Datuetarako SIMa aldatu nahi duzu?"</string>
@@ -845,6 +845,8 @@
     <string name="radio_info_radio_power" msgid="8805595022160471587">"Sare mugikor bidezko irratiaren indarra"</string>
     <string name="simulate_out_of_service_string" msgid="7787925611727597193">"Simulatu gailua ez dabilela (arazketa-konpilazioa soilik)"</string>
     <string name="mock_carrier_roaming_satellite_string" msgid="4796300252858292593">"Simulatu operadorearen satelite modua (arazketa-konpilazioa soilik)"</string>
+    <!-- no translation found for esos_satellite_string (7274794226125968657) -->
+    <skip />
     <string name="radioInfo_menu_viewADN" msgid="4533179730908559846">"Ikusi SIMeko kontaktuak"</string>
     <string name="radioInfo_menu_viewFDN" msgid="1847236480527032061">"Ikusi markatze finkoko zenbakiak"</string>
     <string name="radioInfo_menu_viewSDN" msgid="2613431584522392842">"Ikusi zerbitzuaren markatze-zenbakiak"</string>
diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml
index 268b082..88309e9 100644
--- a/res/values-fa/strings.xml
+++ b/res/values-fa/strings.xml
@@ -845,6 +845,8 @@
     <string name="radio_info_radio_power" msgid="8805595022160471587">"توان رادیوی تلفن همراه"</string>
     <string name="simulate_out_of_service_string" msgid="7787925611727597193">"شبیه‌سازی از کار افتادن (فقط ساخت اشکال‌زدایی)"</string>
     <string name="mock_carrier_roaming_satellite_string" msgid="4796300252858292593">"حالت ماهواره‌ای شرکت مخابراتی ساختگی (فقط ساخت اشکال‌زدایی)"</string>
+    <!-- no translation found for esos_satellite_string (7274794226125968657) -->
+    <skip />
     <string name="radioInfo_menu_viewADN" msgid="4533179730908559846">"مشاهده دفترچه نشانی سیم‌کارت"</string>
     <string name="radioInfo_menu_viewFDN" msgid="1847236480527032061">"مشاهده شماره‌های شماره‌گیری ثابت"</string>
     <string name="radioInfo_menu_viewSDN" msgid="2613431584522392842">"مشاهده شماره‌های شماره‌گیری سرویس"</string>
diff --git a/res/values-fi/strings.xml b/res/values-fi/strings.xml
index 9d375dd..388daa9 100644
--- a/res/values-fi/strings.xml
+++ b/res/values-fi/strings.xml
@@ -845,6 +845,8 @@
     <string name="radio_info_radio_power" msgid="8805595022160471587">"Mobiiliradion voimakkuus"</string>
     <string name="simulate_out_of_service_string" msgid="7787925611727597193">"Epäkunnossa-simulaatio (vain virheenkorjauksen koontiversio)"</string>
     <string name="mock_carrier_roaming_satellite_string" msgid="4796300252858292593">"Operaattorin satelliittitilaesimerkki (vain virheenkorjauksen koontiversio)"</string>
+    <!-- no translation found for esos_satellite_string (7274794226125968657) -->
+    <skip />
     <string name="radioInfo_menu_viewADN" msgid="4533179730908559846">"Näytä SIM-kortin osoitekirja"</string>
     <string name="radioInfo_menu_viewFDN" msgid="1847236480527032061">"Näytä sallitut numerot"</string>
     <string name="radioInfo_menu_viewSDN" msgid="2613431584522392842">"Näytä sallitut palvelunumerot"</string>
diff --git a/res/values-fr-rCA/strings.xml b/res/values-fr-rCA/strings.xml
index 1bcb73d..a1dc0ed 100644
--- a/res/values-fr-rCA/strings.xml
+++ b/res/values-fr-rCA/strings.xml
@@ -845,6 +845,8 @@
     <string name="radio_info_radio_power" msgid="8805595022160471587">"Alimentation de radio cellulaire"</string>
     <string name="simulate_out_of_service_string" msgid="7787925611727597193">"Simulation de l\'appareil hors service (version de débogage uniquement)"</string>
     <string name="mock_carrier_roaming_satellite_string" msgid="4796300252858292593">"Mode Satellite de l\'opérateur simulé (version de débogage uniquement)"</string>
+    <!-- no translation found for esos_satellite_string (7274794226125968657) -->
+    <skip />
     <string name="radioInfo_menu_viewADN" msgid="4533179730908559846">"Afficher le carnet d\'adresses de la carte SIM"</string>
     <string name="radioInfo_menu_viewFDN" msgid="1847236480527032061">"Afficher les numéros d\'appel fixes"</string>
     <string name="radioInfo_menu_viewSDN" msgid="2613431584522392842">"Afficher les numéros de service"</string>
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index 1475f81..3c1400c 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -845,6 +845,8 @@
     <string name="radio_info_radio_power" msgid="8805595022160471587">"Alimentation radio mobile"</string>
     <string name="simulate_out_of_service_string" msgid="7787925611727597193">"Simuler une panne (version de débogage uniquement)"</string>
     <string name="mock_carrier_roaming_satellite_string" msgid="4796300252858292593">"Simuler le mode Satellite de l\'opérateur (version de débogage uniquement)"</string>
+    <!-- no translation found for esos_satellite_string (7274794226125968657) -->
+    <skip />
     <string name="radioInfo_menu_viewADN" msgid="4533179730908559846">"Afficher le carnet d\'adresses de la carte SIM"</string>
     <string name="radioInfo_menu_viewFDN" msgid="1847236480527032061">"Afficher les numéros autorisés"</string>
     <string name="radioInfo_menu_viewSDN" msgid="2613431584522392842">"Afficher les numéros de service"</string>
diff --git a/res/values-gl/strings.xml b/res/values-gl/strings.xml
index a6a69dc..1a57822 100644
--- a/res/values-gl/strings.xml
+++ b/res/values-gl/strings.xml
@@ -845,6 +845,7 @@
     <string name="radio_info_radio_power" msgid="8805595022160471587">"Alimentación da radio móbil"</string>
     <string name="simulate_out_of_service_string" msgid="7787925611727597193">"Simular Fóra de servizo (só compilación de depuración)"</string>
     <string name="mock_carrier_roaming_satellite_string" msgid="4796300252858292593">"Simular o modo Satélite do operador (só compilación de depuración)"</string>
+    <string name="esos_satellite_string" msgid="7274794226125968657">"Probar o modo real eSOS por satélite (só compilación de depuración)"</string>
     <string name="radioInfo_menu_viewADN" msgid="4533179730908559846">"Ver axenda de enderezos da SIM"</string>
     <string name="radioInfo_menu_viewFDN" msgid="1847236480527032061">"Ver números de marcación fixa"</string>
     <string name="radioInfo_menu_viewSDN" msgid="2613431584522392842">"Ver números de marcación de servizo"</string>
diff --git a/res/values-gu/strings.xml b/res/values-gu/strings.xml
index 8f7e9ac..170da4f 100644
--- a/res/values-gu/strings.xml
+++ b/res/values-gu/strings.xml
@@ -845,6 +845,8 @@
     <string name="radio_info_radio_power" msgid="8805595022160471587">"મોબાઇલ રેડિયો પાવર"</string>
     <string name="simulate_out_of_service_string" msgid="7787925611727597193">"\'સેવા ઉપલબ્ધ નથી\' મોડ સિમ્યુલેટ કરો (માત્ર ડિબગ બિલ્ડ માટે)"</string>
     <string name="mock_carrier_roaming_satellite_string" msgid="4796300252858292593">"મૉક કૅરિઅર સૅટલાઇટ મોડ (માત્ર ડિબગ બિલ્ડ માટે)"</string>
+    <!-- no translation found for esos_satellite_string (7274794226125968657) -->
+    <skip />
     <string name="radioInfo_menu_viewADN" msgid="4533179730908559846">"સિમમાં સરનામા પુસ્તિકા જુઓ"</string>
     <string name="radioInfo_menu_viewFDN" msgid="1847236480527032061">"ફિક્સ્ડ ડાયલિંગ નંબર જુઓ"</string>
     <string name="radioInfo_menu_viewSDN" msgid="2613431584522392842">"સર્વિસ ડાયલિંગ નંબર જુઓ"</string>
diff --git a/res/values-hi/strings.xml b/res/values-hi/strings.xml
index 9c91915..c57d82a 100644
--- a/res/values-hi/strings.xml
+++ b/res/values-hi/strings.xml
@@ -845,6 +845,7 @@
     <string name="radio_info_radio_power" msgid="8805595022160471587">"मोबाइल रेडियो पावर"</string>
     <string name="simulate_out_of_service_string" msgid="7787925611727597193">"सिम्युलेट किया गया डिवाइस काम नहीं कर रहा है (सिर्फ़ डीबग के लिए बिल्ड)"</string>
     <string name="mock_carrier_roaming_satellite_string" msgid="4796300252858292593">"मोबाइल और इंटरनेट सेवा देने वाली कंपनी के सैटलाइट मोड की मॉक टेस्टिंग करें (सिर्फ़ डीबग के लिए बिल्ड)"</string>
+    <string name="esos_satellite_string" msgid="7274794226125968657">"रीयल सैटलाइट इमरजेंसी एसओएस मोड को आज़माएं (सिर्फ़ डीबग के लिए बिल्ड)"</string>
     <string name="radioInfo_menu_viewADN" msgid="4533179730908559846">"सिम में संपर्कों के पते की सूची देखें"</string>
     <string name="radioInfo_menu_viewFDN" msgid="1847236480527032061">"फ़िक्स्ड डायलिंग नंबर देखें"</string>
     <string name="radioInfo_menu_viewSDN" msgid="2613431584522392842">"सेवा के डायलिंग नंबर देखें"</string>
diff --git a/res/values-hr/strings.xml b/res/values-hr/strings.xml
index cc35a21..5428368 100644
--- a/res/values-hr/strings.xml
+++ b/res/values-hr/strings.xml
@@ -845,6 +845,8 @@
     <string name="radio_info_radio_power" msgid="8805595022160471587">"Snaga mobilnog radija"</string>
     <string name="simulate_out_of_service_string" msgid="7787925611727597193">"Simulacija stanja \"izvan upotrebe\" (samo međuverzija programa za otklanjanje pogrešaka)"</string>
     <string name="mock_carrier_roaming_satellite_string" msgid="4796300252858292593">"Lažni način mobilnog operatera za slanje putem satelita (samo međuverzija programa za otklanjanje pogrešaka)"</string>
+    <!-- no translation found for esos_satellite_string (7274794226125968657) -->
+    <skip />
     <string name="radioInfo_menu_viewADN" msgid="4533179730908559846">"Prikaži imenik SIM-a"</string>
     <string name="radioInfo_menu_viewFDN" msgid="1847236480527032061">"Prikaži brojeve za fiksno biranje"</string>
     <string name="radioInfo_menu_viewSDN" msgid="2613431584522392842">"Prikaži brojeve za servisno biranje"</string>
diff --git a/res/values-hu/strings.xml b/res/values-hu/strings.xml
index 3b3dd9d..e90047f 100644
--- a/res/values-hu/strings.xml
+++ b/res/values-hu/strings.xml
@@ -845,6 +845,7 @@
     <string name="radio_info_radio_power" msgid="8805595022160471587">"Mobil rádióadó teljesítménye"</string>
     <string name="simulate_out_of_service_string" msgid="7787925611727597193">"Szolgáltatáskiesés szimulációja (csak hibaelhárító build)"</string>
     <string name="mock_carrier_roaming_satellite_string" msgid="4796300252858292593">"Szimulált szolgáltató – Műholdas mód (csak hibaelhárító build)"</string>
+    <string name="esos_satellite_string" msgid="7274794226125968657">"A valódi műholdas eSOS mód tesztelése (csak hibaelhárító build)"</string>
     <string name="radioInfo_menu_viewADN" msgid="4533179730908559846">"SIM-kártya telefonkönyvének megtekintése"</string>
     <string name="radioInfo_menu_viewFDN" msgid="1847236480527032061">"Fix hívószámok megtekintése"</string>
     <string name="radioInfo_menu_viewSDN" msgid="2613431584522392842">"Szolgáltatásszámok megtekintése"</string>
diff --git a/res/values-hy/strings.xml b/res/values-hy/strings.xml
index 3ae4ae9..ce2c782 100644
--- a/res/values-hy/strings.xml
+++ b/res/values-hy/strings.xml
@@ -845,6 +845,7 @@
     <string name="radio_info_radio_power" msgid="8805595022160471587">"Բջջային ռադիոազդանշանի հզորությունը"</string>
     <string name="simulate_out_of_service_string" msgid="7787925611727597193">"Սպասարկման գոտուց դուրս գտնվելու սիմուլյացիա (միայն վրիպազերծման կառուցում)"</string>
     <string name="mock_carrier_roaming_satellite_string" msgid="4796300252858292593">"Օպերատորի արբանյակի ռեժիմի սիմուլյացիա (միայն վրիպազերծման կառուցում)"</string>
+    <string name="esos_satellite_string" msgid="7274794226125968657">"Փորձարկել իրական արբանյակային eSOS ռեժիմը (միայն վրիպազերծման կառուցման մեջ)"</string>
     <string name="radioInfo_menu_viewADN" msgid="4533179730908559846">"Դիտել SIM քարտի հասցեագիրքը"</string>
     <string name="radioInfo_menu_viewFDN" msgid="1847236480527032061">"Տեսնել ամրակցված հեռախոսահամարները"</string>
     <string name="radioInfo_menu_viewSDN" msgid="2613431584522392842">"Տեսնել ծառայությունների հեռախոսահամարները"</string>
diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml
index adf7f52..a362736 100644
--- a/res/values-in/strings.xml
+++ b/res/values-in/strings.xml
@@ -845,6 +845,8 @@
     <string name="radio_info_radio_power" msgid="8805595022160471587">"Daya Radio Seluler"</string>
     <string name="simulate_out_of_service_string" msgid="7787925611727597193">"Simulasi Tidak dapat Digunakan (Khusus Build Debug)"</string>
     <string name="mock_carrier_roaming_satellite_string" msgid="4796300252858292593">"Mode Satelit Operator Tiruan (khusus Build Debug)."</string>
+    <!-- no translation found for esos_satellite_string (7274794226125968657) -->
+    <skip />
     <string name="radioInfo_menu_viewADN" msgid="4533179730908559846">"Lihat Buku Alamat SIM"</string>
     <string name="radioInfo_menu_viewFDN" msgid="1847236480527032061">"Lihat Panggilan Terbatas"</string>
     <string name="radioInfo_menu_viewSDN" msgid="2613431584522392842">"Lihat Nomor Panggilan Layanan"</string>
diff --git a/res/values-is/strings.xml b/res/values-is/strings.xml
index 6702a8a..4503890 100644
--- a/res/values-is/strings.xml
+++ b/res/values-is/strings.xml
@@ -845,6 +845,8 @@
     <string name="radio_info_radio_power" msgid="8805595022160471587">"Loftnetsstyrkur farsíma"</string>
     <string name="simulate_out_of_service_string" msgid="7787925611727597193">"Líkja eftir „Utan þjónustusvæðis“ (aðeins villuleitarsmíði)"</string>
     <string name="mock_carrier_roaming_satellite_string" msgid="4796300252858292593">"Eftirlíking af gervihnattarstillingu símafyrirtækis (aðeins villuleitarsmíði)"</string>
+    <!-- no translation found for esos_satellite_string (7274794226125968657) -->
+    <skip />
     <string name="radioInfo_menu_viewADN" msgid="4533179730908559846">"Skoða símaskrá SIM-korts"</string>
     <string name="radioInfo_menu_viewFDN" msgid="1847236480527032061">"Skoða læst númeraval"</string>
     <string name="radioInfo_menu_viewSDN" msgid="2613431584522392842">"Skoða þjónustunúmer"</string>
diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml
index 1574fcc..df9b582 100644
--- a/res/values-it/strings.xml
+++ b/res/values-it/strings.xml
@@ -845,6 +845,8 @@
     <string name="radio_info_radio_power" msgid="8805595022160471587">"Potenza del segnale radio mobile"</string>
     <string name="simulate_out_of_service_string" msgid="7787925611727597193">"Simulazione non disponibile (solo build di debug)"</string>
     <string name="mock_carrier_roaming_satellite_string" msgid="4796300252858292593">"Modalità satellite operatore fittizio (solo build di debug)"</string>
+    <!-- no translation found for esos_satellite_string (7274794226125968657) -->
+    <skip />
     <string name="radioInfo_menu_viewADN" msgid="4533179730908559846">"Visualizza rubrica SIM"</string>
     <string name="radioInfo_menu_viewFDN" msgid="1847236480527032061">"Visualizza numeri consentiti"</string>
     <string name="radioInfo_menu_viewSDN" msgid="2613431584522392842">"Visualizza numeri dell\'elenco dei numeri di servizio"</string>
diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml
index 4a51379..816d5cf 100644
--- a/res/values-iw/strings.xml
+++ b/res/values-iw/strings.xml
@@ -846,6 +846,8 @@
     <string name="radio_info_radio_power" msgid="8805595022160471587">"הפעלה של רדיו סלולרי"</string>
     <string name="simulate_out_of_service_string" msgid="7787925611727597193">"‏סימולציה של המצב \'לא בשירות\' (גרסת build לניפוי באגים בלבד)"</string>
     <string name="mock_carrier_roaming_satellite_string" msgid="4796300252858292593">"‏מצב שמדמה תקשורת לוויינית דרך ספק הסלולר (גרסת build לניפוי באגים בלבד)"</string>
+    <!-- no translation found for esos_satellite_string (7274794226125968657) -->
+    <skip />
     <string name="radioInfo_menu_viewADN" msgid="4533179730908559846">"‏הצגת פנקס כתובות של SIM"</string>
     <string name="radioInfo_menu_viewFDN" msgid="1847236480527032061">"הצגת מספרי חיוג קבועים"</string>
     <string name="radioInfo_menu_viewSDN" msgid="2613431584522392842">"מספרי חיוג לשירות"</string>
diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index 8b610b0..6ce1881 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -845,6 +845,8 @@
     <string name="radio_info_radio_power" msgid="8805595022160471587">"モバイル無線電力"</string>
     <string name="simulate_out_of_service_string" msgid="7787925611727597193">"圏外状態のシミュレート(デバッグビルドのみ)"</string>
     <string name="mock_carrier_roaming_satellite_string" msgid="4796300252858292593">"携帯通信会社の疑似航空写真モード(デバッグビルドのみ)"</string>
+    <!-- no translation found for esos_satellite_string (7274794226125968657) -->
+    <skip />
     <string name="radioInfo_menu_viewADN" msgid="4533179730908559846">"SIM のアドレス帳を表示"</string>
     <string name="radioInfo_menu_viewFDN" msgid="1847236480527032061">"発信番号制限を表示"</string>
     <string name="radioInfo_menu_viewSDN" msgid="2613431584522392842">"サービス電話番号を表示"</string>
diff --git a/res/values-ka/strings.xml b/res/values-ka/strings.xml
index 0463353..bd8c241 100644
--- a/res/values-ka/strings.xml
+++ b/res/values-ka/strings.xml
@@ -845,6 +845,7 @@
     <string name="radio_info_radio_power" msgid="8805595022160471587">"მობილური რადიოკავშირის ელკვება"</string>
     <string name="simulate_out_of_service_string" msgid="7787925611727597193">"სიმულაცია სერვისის გარეშე (მხოლოდ გამართვის აგება)"</string>
     <string name="mock_carrier_roaming_satellite_string" msgid="4796300252858292593">"სიმულაციური ოპერატორის სატელიტის რეჟიმი (მხოლოდ გამართვის აგება)"</string>
+    <string name="esos_satellite_string" msgid="7274794226125968657">"სატელიტური eSOS-ის რეალური რეჟიმის ტესტირება (მხოლოდ გამართვის მიზნით)"</string>
     <string name="radioInfo_menu_viewADN" msgid="4533179730908559846">"SIM-ის მისამართების წიგნის ნახვა"</string>
     <string name="radioInfo_menu_viewFDN" msgid="1847236480527032061">"დაშვებული ნომრების ნახვა"</string>
     <string name="radioInfo_menu_viewSDN" msgid="2613431584522392842">"სერვისის დარეკილი ნომრების ნახვა"</string>
diff --git a/res/values-kk/strings.xml b/res/values-kk/strings.xml
index d947868..9057472 100644
--- a/res/values-kk/strings.xml
+++ b/res/values-kk/strings.xml
@@ -845,6 +845,8 @@
     <string name="radio_info_radio_power" msgid="8805595022160471587">"Радиосигнал күші"</string>
     <string name="simulate_out_of_service_string" msgid="7787925611727597193">"\"Істен шыққан\" қызметін симуляциялау (түзету құрамасы ғана)"</string>
     <string name="mock_carrier_roaming_satellite_string" msgid="4796300252858292593">"Mock Carrier жер серігі режимі (тек түзету құрамасы)"</string>
+    <!-- no translation found for esos_satellite_string (7274794226125968657) -->
+    <skip />
     <string name="radioInfo_menu_viewADN" msgid="4533179730908559846">"SIM мекенжай кітапшасын көру"</string>
     <string name="radioInfo_menu_viewFDN" msgid="1847236480527032061">"Рұқсат нөмірлерді көру"</string>
     <string name="radioInfo_menu_viewSDN" msgid="2613431584522392842">"Қызметтік теру нөмірлерін көру"</string>
diff --git a/res/values-km/strings.xml b/res/values-km/strings.xml
index 368043d..fa81334 100644
--- a/res/values-km/strings.xml
+++ b/res/values-km/strings.xml
@@ -845,6 +845,7 @@
     <string name="radio_info_radio_power" msgid="8805595022160471587">"ថាមពល​វិទ្យុ​ទូរសព្ទ​ចល័ត"</string>
     <string name="simulate_out_of_service_string" msgid="7787925611727597193">"ត្រាប់តាម​ពេលគ្មានសេវា (កំណែបង្កើតសម្រាប់ជួសជុលតែប៉ុណ្ណោះ)"</string>
     <string name="mock_carrier_roaming_satellite_string" msgid="4796300252858292593">"មុខងារ​ផ្កាយរណប​ក្រុមហ៊ុន​សេវាទូរសព្ទ​សាកល្បង (កំណែបង្កើត​សម្រាប់​ជួសជុល​តែប៉ុណ្ណោះ)"</string>
+    <string name="esos_satellite_string" msgid="7274794226125968657">"មុខងារ​ធ្វើតេស្ត eSOS ផ្កាយរណប​ជាក់ស្ដែង (កំណែបង្កើត​សម្រាប់​ជួសជុល​តែប៉ុណ្ណោះ)"</string>
     <string name="radioInfo_menu_viewADN" msgid="4533179730908559846">"មើលសៀវភៅអាសយដ្ឋានក្នុងស៊ីមកាត"</string>
     <string name="radioInfo_menu_viewFDN" msgid="1847236480527032061">"មើល​លេខ​ហៅ​ថេរ"</string>
     <string name="radioInfo_menu_viewSDN" msgid="2613431584522392842">"មើល​លេខ​ហៅ​សេវាកម្ម"</string>
diff --git a/res/values-kn/strings.xml b/res/values-kn/strings.xml
index bb89410..b5ef249 100644
--- a/res/values-kn/strings.xml
+++ b/res/values-kn/strings.xml
@@ -845,6 +845,7 @@
     <string name="radio_info_radio_power" msgid="8805595022160471587">"ಮೊಬೈಲ್ ರೇಡಿಯೋ ಪವರ್"</string>
     <string name="simulate_out_of_service_string" msgid="7787925611727597193">"ಸೇವೆಯಲ್ಲಿಲ್ಲದಿರುವುದನ್ನು ಸಿಮ್ಯುಲೇಟ್‌ ಮಾಡುವುದು (ಡೀಬಗ್ ಬಿಲ್ಡ್ ಮಾತ್ರ)"</string>
     <string name="mock_carrier_roaming_satellite_string" msgid="4796300252858292593">"Mock Carrier ಉಪಗ್ರಹ ಮೋಡ್ (ಡೀಬಗ್ ಬಿಲ್ಡ್ ಮಾತ್ರ)"</string>
+    <string name="esos_satellite_string" msgid="7274794226125968657">"ನೈಜ ಸ್ಯಾಟಲೈಟ್ eSOS ಮೋಡ್ ಅನ್ನು ಪರೀಕ್ಷಿಸಿ (ಡೀಬಗ್ ಬಿಲ್ಡ್ ಮಾತ್ರ)"</string>
     <string name="radioInfo_menu_viewADN" msgid="4533179730908559846">"ಸಿಮ್ ವಿಳಾಸ ಪುಸ್ತಕವನ್ನು ವೀಕ್ಷಿಸಿ"</string>
     <string name="radioInfo_menu_viewFDN" msgid="1847236480527032061">"ಸ್ಥಿರ ಡಯಲಿಂಗ್ ಸಂಖ್ಯೆಗಳನ್ನು ವೀಕ್ಷಿಸಿ"</string>
     <string name="radioInfo_menu_viewSDN" msgid="2613431584522392842">"ಸೇವಾ ಡಯಲಿಂಗ್ ಸಂಖ್ಯೆಗಳನ್ನು ವೀಕ್ಷಿಸಿ"</string>
diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml
index 73f4226..8d4ba68 100644
--- a/res/values-ko/strings.xml
+++ b/res/values-ko/strings.xml
@@ -845,6 +845,8 @@
     <string name="radio_info_radio_power" msgid="8805595022160471587">"모바일 무선 전력"</string>
     <string name="simulate_out_of_service_string" msgid="7787925611727597193">"\'서비스 지역 벗어남\' 시뮬레이션(디버그 빌드만 해당)"</string>
     <string name="mock_carrier_roaming_satellite_string" msgid="4796300252858292593">"모의 이동통신사 위성 모드(디버그 빌드만 해당)"</string>
+    <!-- no translation found for esos_satellite_string (7274794226125968657) -->
+    <skip />
     <string name="radioInfo_menu_viewADN" msgid="4533179730908559846">"SIM 주소록 보기"</string>
     <string name="radioInfo_menu_viewFDN" msgid="1847236480527032061">"발신 허용 번호 보기"</string>
     <string name="radioInfo_menu_viewSDN" msgid="2613431584522392842">"SDN(Service Dialing Numbers) 보기"</string>
diff --git a/res/values-ky/strings.xml b/res/values-ky/strings.xml
index daad4bb..c71fc2d 100644
--- a/res/values-ky/strings.xml
+++ b/res/values-ky/strings.xml
@@ -845,6 +845,8 @@
     <string name="radio_info_radio_power" msgid="8805595022160471587">"Мобилдик радионун кубаты"</string>
     <string name="simulate_out_of_service_string" msgid="7787925611727597193">"Тейлөө аймагынын сыртында режимин иштетүү (Мүчүлүштүктөрдү оңдоо үчүн гана)"</string>
     <string name="mock_carrier_roaming_satellite_string" msgid="4796300252858292593">"Симуляцияланган байланыш операторунун спутниги (Мүчүлүштүктөрдү оңдоо үчүн гана)"</string>
+    <!-- no translation found for esos_satellite_string (7274794226125968657) -->
+    <skip />
     <string name="radioInfo_menu_viewADN" msgid="4533179730908559846">"SIM картадагы дарек китепчесин көрүү"</string>
     <string name="radioInfo_menu_viewFDN" msgid="1847236480527032061">"Туруктуу терүү номерлерин көрүү"</string>
     <string name="radioInfo_menu_viewSDN" msgid="2613431584522392842">"Кызматтык терүү номерлерин көрүү"</string>
diff --git a/res/values-lo/strings.xml b/res/values-lo/strings.xml
index eb5ca0a..805cf29 100644
--- a/res/values-lo/strings.xml
+++ b/res/values-lo/strings.xml
@@ -845,6 +845,8 @@
     <string name="radio_info_radio_power" msgid="8805595022160471587">"ພະລັງງານວິທະຍຸມືຖື"</string>
     <string name="simulate_out_of_service_string" msgid="7787925611727597193">"ຈໍາລອງເຫດການບໍ່ພ້ອມໃຫ້ບໍລິການ (ສໍາລັບ Build ດີບັກເທົ່ານັ້ນ)"</string>
     <string name="mock_carrier_roaming_satellite_string" msgid="4796300252858292593">"ຈຳລອງໂໝດດາວທຽມຂອງຜູ້ໃຫ້ບໍລິການ (ສຳລັບ Build ດີບັກເທົ່ານັ້ນ)"</string>
+    <!-- no translation found for esos_satellite_string (7274794226125968657) -->
+    <skip />
     <string name="radioInfo_menu_viewADN" msgid="4533179730908559846">"ເບິ່ງສະໝຸດທີ່ຢູ່ໃນຊິມ"</string>
     <string name="radioInfo_menu_viewFDN" msgid="1847236480527032061">"ເບິ່ງໝາຍເລກໂທອອກທີ່ກຳນົດ"</string>
     <string name="radioInfo_menu_viewSDN" msgid="2613431584522392842">"ເບິ່ງໝາຍເລກບໍລິການໂທອອກ"</string>
diff --git a/res/values-lt/strings.xml b/res/values-lt/strings.xml
index ba3667d..64ed0ef 100644
--- a/res/values-lt/strings.xml
+++ b/res/values-lt/strings.xml
@@ -845,6 +845,7 @@
     <string name="radio_info_radio_power" msgid="8805595022160471587">"Mobiliojo ryšio radijo signalas"</string>
     <string name="simulate_out_of_service_string" msgid="7787925611727597193">"Modeliavimas neteikiamas (tik derinimo versija)"</string>
     <string name="mock_carrier_roaming_satellite_string" msgid="4796300252858292593">"Netikras operatoriaus satelito režimas (tik derinimo versija)"</string>
+    <string name="esos_satellite_string" msgid="7274794226125968657">"Išbandykite tikrą Pagalbos iškvietimo kritiniu atveju naudojant palydovinį ryšį režimą (tik derinimo versija)"</string>
     <string name="radioInfo_menu_viewADN" msgid="4533179730908559846">"Žiūrėti SIM kortelės adresų knygą"</string>
     <string name="radioInfo_menu_viewFDN" msgid="1847236480527032061">"Žiūrėti fiksuotojo rinkimo numerius"</string>
     <string name="radioInfo_menu_viewSDN" msgid="2613431584522392842">"Žiūrėti paslaugos renkamus numerius"</string>
diff --git a/res/values-lv/strings.xml b/res/values-lv/strings.xml
index 74873ca..956a703 100644
--- a/res/values-lv/strings.xml
+++ b/res/values-lv/strings.xml
@@ -845,6 +845,8 @@
     <string name="radio_info_radio_power" msgid="8805595022160471587">"Mobilā tālruņa radio signāla stiprums"</string>
     <string name="simulate_out_of_service_string" msgid="7787925611727597193">"Simulācijas ierīce nedarbojas (tikai būvējuma atkļūdošana)"</string>
     <string name="mock_carrier_roaming_satellite_string" msgid="4796300252858292593">"Mobilo sakaru operatora satelīta režīma imitēšana (tikai būvējuma atkļūdošana)"</string>
+    <!-- no translation found for esos_satellite_string (7274794226125968657) -->
+    <skip />
     <string name="radioInfo_menu_viewADN" msgid="4533179730908559846">"Skatīt SIM adrešu grāmatu"</string>
     <string name="radioInfo_menu_viewFDN" msgid="1847236480527032061">"Skatīt ierobežotā zvanu saraksta numurus"</string>
     <string name="radioInfo_menu_viewSDN" msgid="2613431584522392842">"Pakalpojuma iezvanes numuru skatīšana"</string>
diff --git a/res/values-mk/strings.xml b/res/values-mk/strings.xml
index ca6d7d5..86c5688 100644
--- a/res/values-mk/strings.xml
+++ b/res/values-mk/strings.xml
@@ -845,6 +845,7 @@
     <string name="radio_info_radio_power" msgid="8805595022160471587">"Радио-напојување на мобилен"</string>
     <string name="simulate_out_of_service_string" msgid="7787925611727597193">"Симулирање „Надвор од употреба“ (само за верзиите за отстранување грешки)"</string>
     <string name="mock_carrier_roaming_satellite_string" msgid="4796300252858292593">"Симулација на режим на сателит за оператор (само за верзиите за отстранување грешки)"</string>
+    <string name="esos_satellite_string" msgid="7274794226125968657">"Тестирајте го реалниот режим на eSOS (само во верзијата за отстранување грешки)"</string>
     <string name="radioInfo_menu_viewADN" msgid="4533179730908559846">"Прикажи именик на SIM-картичката"</string>
     <string name="radioInfo_menu_viewFDN" msgid="1847236480527032061">"Прикажи броеви со ограничено бирање"</string>
     <string name="radioInfo_menu_viewSDN" msgid="2613431584522392842">"Прикажи броеви за бирање служби"</string>
diff --git a/res/values-ml/strings.xml b/res/values-ml/strings.xml
index 98c45de..e5e09f1 100644
--- a/res/values-ml/strings.xml
+++ b/res/values-ml/strings.xml
@@ -535,7 +535,7 @@
     <string name="notification_voicemail_no_vm_number" msgid="3423686009815186750">"വോയ്‌സ്‌മെയിൽ നമ്പർ അജ്ഞാതമാണ്"</string>
     <string name="notification_network_selection_title" msgid="255595526707809121">"സേവനമില്ല"</string>
     <string name="notification_network_selection_text" msgid="553288408722427659">"തിരഞ്ഞെടുത്ത നെറ്റ്‌വർക്ക് (<xliff:g id="OPERATOR_NAME">%s</xliff:g>) ലഭ്യമല്ല"</string>
-    <string name="incall_error_power_off" product="watch" msgid="7191184639454113633">"ഒരു കോൾ വിളിക്കാൻ മൊബൈൽ നെറ്റ്‌വർക്ക് ഓണാക്കുകയോ ഫ്ലൈറ്റ് മോഡ് അല്ലെങ്കിൽ ബാറ്ററി ലാഭിക്കൽ മോഡ് ഓഫാക്കുകയോ ചെയ്യുക."</string>
+    <string name="incall_error_power_off" product="watch" msgid="7191184639454113633">"ഒരു കോൾ വിളിക്കാൻ മൊബൈൽ നെറ്റ്‌വർക്ക് ഓണാക്കുകയോ ഫ്ലൈറ്റ് മോഡ് അല്ലെങ്കിൽ ബാറ്ററി സേവർ മോഡ് ഓഫാക്കുകയോ ചെയ്യുക."</string>
     <string name="incall_error_power_off" product="default" msgid="8131672264311208673">"ഒരു കോൾ വിളിക്കാൻ വിമാന മോഡ് ഓഫാക്കുക."</string>
     <string name="incall_error_power_off_wfc" msgid="9125661184694727052">"ഒരു കോൾ വിളിക്കാൻ വിമാന മോഡ് ഓഫാക്കുക അല്ലെങ്കിൽ വയർലെസ്സ് നെറ്റ്‌വർക്കിലേക്ക് കണക്റ്റുചെയ്യുക."</string>
     <string name="incall_error_power_off_thermal" product="default" msgid="8695809601655300168"><b>"ഫോൺ വളരെയധികം ചൂടായിരിക്കുന്നു"</b>\n\n"ഈ കോൾ പൂർത്തിയാക്കാനാകില്ല. ഫോൺ തണുക്കുമ്പോൾ വീണ്ടും ശ്രമിക്കുക.\n\nഎമർജൻസി കോളുകൾ നിങ്ങൾക്ക് ഇപ്പോഴും ചെയ്യാവുന്നതാണ്."</string>
@@ -845,6 +845,7 @@
     <string name="radio_info_radio_power" msgid="8805595022160471587">"മൊബൈൽ റേഡിയോ പവർ"</string>
     <string name="simulate_out_of_service_string" msgid="7787925611727597193">"സേവനം ലഭ്യമല്ലെന്ന് അനുകരിക്കുക (ഡീബഗ് ബിൽഡ് മാത്രം)"</string>
     <string name="mock_carrier_roaming_satellite_string" msgid="4796300252858292593">"Mock സേവനദാതാവ് ഉപഗ്രഹ മോഡ് (ഡീബഗ് ബിൽഡ് മാത്രം)"</string>
+    <string name="esos_satellite_string" msgid="7274794226125968657">"യഥാർത്ഥ സാറ്റലൈറ്റ് eSOS മോഡ് പരീക്ഷിക്കുക (ഡീബഗ് ബിൽഡ് മാത്രം)"</string>
     <string name="radioInfo_menu_viewADN" msgid="4533179730908559846">"സിം വിലാസ പുസ്‌തകം കാണുക"</string>
     <string name="radioInfo_menu_viewFDN" msgid="1847236480527032061">"സ്ഥിര ഡയലിംഗ് നമ്പറുകൾ കാണുക"</string>
     <string name="radioInfo_menu_viewSDN" msgid="2613431584522392842">"സർവീസ് ഡയലിംഗ് നമ്പറുകൾ കാണുക"</string>
diff --git a/res/values-mn/strings.xml b/res/values-mn/strings.xml
index c15fa11..c42e0de 100644
--- a/res/values-mn/strings.xml
+++ b/res/values-mn/strings.xml
@@ -56,7 +56,7 @@
     <string name="requesting_unlock" msgid="930512210309437741">"Сүлжээг тайлах хүсэлтийг илгээж байна…"</string>
     <string name="unlock_failed" msgid="7103543844840661366">"Сүлжээг тайлах хүсэлт амжилтгүй боллоо."</string>
     <string name="unlock_success" msgid="32681089371067565">"Сүлжээг амжилттай тайллаа."</string>
-    <string name="mobile_network_settings_not_available" msgid="8678168497517090039">"Энэ хэрэглэгч мобайл сүлжээний тохиргоог ашиглах боломжгүй"</string>
+    <string name="mobile_network_settings_not_available" msgid="8678168497517090039">"Энэ хэрэглэгч хөдөлгөөнт холбооны сүлжээний тохиргоог ашиглах боломжгүй"</string>
     <string name="labelGSMMore" msgid="7354182269461281543">"GSM дуудлагын тохиргоо"</string>
     <string name="labelGsmMore_with_label" msgid="3206015314393246224">"GSM дуудлагын тохиргоо (<xliff:g id="SUBSCRIPTIONLABEL">%s</xliff:g>)"</string>
     <string name="labelCDMAMore" msgid="7937441382611224632">"CDMA дуудлагын тохиргоо"</string>
@@ -173,7 +173,7 @@
     <string name="vm_change_pin_error_invalid" msgid="5230002671175580674">"Шинэ ПИН-д буруу тэмдэгт агуулагдаж байна."</string>
     <string name="vm_change_pin_error_system_error" msgid="9116483527909681791">"ПИН-г өөрчлөх боломжгүй"</string>
     <string name="vvm_unsupported_message_format" msgid="4206402558577739713">"Дэмжигдээгүй мессежийн төрөл, сонсохын тулд <xliff:g id="NUMBER">%s</xliff:g> руу залгана уу."</string>
-    <string name="network_settings_title" msgid="7560807107123171541">"Мобайл сүлжээ"</string>
+    <string name="network_settings_title" msgid="7560807107123171541">"Хөдөлгөөнт холбооны сүлжээ"</string>
     <string name="label_available" msgid="1316084116670821258">"Боломжтой сүлжээнүүд"</string>
     <string name="load_networks_progress" msgid="4051433047717401683">"Хайж байна..."</string>
     <string name="empty_networks_list" msgid="9216418268008582342">"Сүлжээ олдсонгүй."</string>
@@ -305,7 +305,7 @@
     <string name="keywords_carrier_settings_euicc" msgid="8540160967922063745">"үүрэн холбооны компани, esim, sim, euicc, үүрэн холбооны компани сэлгэх, үүрэн холбооны компани нэмэх"</string>
     <string name="carrier_settings_euicc_summary" msgid="2027941166597330117">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g> — <xliff:g id="PHONE_NUMBER">%2$s</xliff:g>"</string>
     <string name="mobile_data_settings_title" msgid="7228249980933944101">"Мобайл дата"</string>
-    <string name="mobile_data_settings_summary" msgid="5012570152029118471">"Мобайл сүлжээг ашиглан датанд хандах"</string>
+    <string name="mobile_data_settings_summary" msgid="5012570152029118471">"Хөдөлгөөнт холбооны сүлжээг ашиглан датанд хандах"</string>
     <string name="data_usage_disable_mobile" msgid="5669109209055988308">"Мобайл датаг унтраах уу?"</string>
     <string name="sim_selection_required_pref" msgid="6985901872978341314">"Сонгох шаардлагатай"</string>
     <string name="sim_change_data_title" msgid="9142726786345906606">"Дата SIM солих уу?"</string>
@@ -535,16 +535,16 @@
     <string name="notification_voicemail_no_vm_number" msgid="3423686009815186750">"Дуут шуудангийн дугаар тодорхойгүй"</string>
     <string name="notification_network_selection_title" msgid="255595526707809121">"Үйлчилгээ байхгүй"</string>
     <string name="notification_network_selection_text" msgid="553288408722427659">"Сонгосон <xliff:g id="OPERATOR_NAME">%s</xliff:g> сүлжээг ашиглах боломжгүй"</string>
-    <string name="incall_error_power_off" product="watch" msgid="7191184639454113633">"Дуудлага хийхийн тулд мобайл сүлжээг асаах, нислэгийн горим буюу батарей хэмнэх горимыг идэвхгүй болгоно уу."</string>
+    <string name="incall_error_power_off" product="watch" msgid="7191184639454113633">"Дуудлага хийхийн тулд хөдөлгөөнт холбооны сүлжээг асаах, нислэгийн горим буюу батарей хэмнэх горимыг идэвхгүй болгоно уу."</string>
     <string name="incall_error_power_off" product="default" msgid="8131672264311208673">"Дуудлага хийхийн тулд онгоцны горимыг унтраа."</string>
     <string name="incall_error_power_off_wfc" msgid="9125661184694727052">"Дуудлага хийхийн тулд онгоцны горимыг унтраа эсвэл утасгүй интернетэд холбогдоно уу."</string>
     <string name="incall_error_power_off_thermal" product="default" msgid="8695809601655300168"><b>"Утас хэт халуун байна"</b>\n\n"Энэ дуудлагыг гүйцээх боломжгүй. Та утсаа хөрсөн үед дахин оролдоно уу.\n\nТа яаралтай дуудлага хийх боломжтой хэвээр байна."</string>
     <string name="incall_error_ecm_emergency_only" msgid="5622379058883722080">"Яаралтай түргэн тусламжийн бус дуудлага хийхийн тулд яаралтай түргэн тусламжийн callback горимоос гарна уу."</string>
     <string name="incall_error_emergency_only" msgid="8786127461027964653">"Сүлжээнд бүртгэгдээгүй."</string>
     <string name="incall_error_out_of_service" msgid="1927265196942672791">"Мобайль сүлжээ байхгүй."</string>
-    <string name="incall_error_out_of_service_2g" msgid="904434080740846116">"Мобайл сүлжээ боломжгүй байна.\n\nДуудлага хийхийн тулд утасгүй сүлжээнд холбогдоно уу.\n\n2G-г энэ төхөөрөмж дээр идэвхгүй болгосон бөгөөд энэ нь таны холболтод нөлөөлж байж магадгүй. Үргэлжлүүлэхийн тулд Тохиргоо руу очоод, 2G-г зөвшөөрөхийг идэвхжүүлнэ үү."</string>
-    <string name="incall_error_out_of_service_wfc" msgid="4497663185857190885">"Мобайл сүлжээнд холбогдох боломжгүй байна. Дуудлага хийхийн тулд утасгүй интернетэд холбогдоно уу."</string>
-    <string name="incall_error_out_of_service_wfc_2g_user" msgid="8218768986365299663">"Мобайл сүлжээ боломжгүй байна.\n\nДуудлага хийхийн тулд утасгүй сүлжээнд холбогдоно уу.\n\n2G-г энэ төхөөрөмж дээр идэвхгүй болгосон бөгөөд энэ нь таны холболтод нөлөөлж байж магадгүй. Үргэлжлүүлэхийн тулд Тохиргоо руу очоод, 2G-г зөвшөөрөхийг идэвхжүүлнэ үү."</string>
+    <string name="incall_error_out_of_service_2g" msgid="904434080740846116">"Хөдөлгөөнт холбооны сүлжээ боломжгүй байна.\n\nДуудлага хийхийн тулд утасгүй сүлжээнд холбогдоно уу.\n\n2G-г энэ төхөөрөмж дээр идэвхгүй болгосон бөгөөд энэ нь таны холболтод нөлөөлж байж магадгүй. Үргэлжлүүлэхийн тулд Тохиргоо руу очоод, 2G-г зөвшөөрөхийг идэвхжүүлнэ үү."</string>
+    <string name="incall_error_out_of_service_wfc" msgid="4497663185857190885">"Хөдөлгөөнт холбооны сүлжээнд холбогдох боломжгүй байна. Дуудлага хийхийн тулд утасгүй интернетэд холбогдоно уу."</string>
+    <string name="incall_error_out_of_service_wfc_2g_user" msgid="8218768986365299663">"Хөдөлгөөнт холбооны сүлжээ боломжгүй байна.\n\nДуудлага хийхийн тулд утасгүй сүлжээнд холбогдоно уу.\n\n2G-г энэ төхөөрөмж дээр идэвхгүй болгосон бөгөөд энэ нь таны холболтод нөлөөлж байж магадгүй. Үргэлжлүүлэхийн тулд Тохиргоо руу очоод, 2G-г зөвшөөрөхийг идэвхжүүлнэ үү."</string>
     <string name="incall_error_no_phone_number_supplied" msgid="8680831089508851894">"Дуудлага хийхийн тулд хүчин төгөлдөр дугаар оруулна уу."</string>
     <string name="incall_error_call_failed" msgid="393508653582682539">"Дуудлага амжилтгүй болсон."</string>
     <string name="incall_error_cannot_add_call" msgid="5425764862628655443">"Дуудлагыг энэ удаад нэмэх боломжгүй. Та мессеж илгээн холбоо тогтоохыг оролдох боломжтой."</string>
@@ -717,7 +717,7 @@
     <string name="clh_card_title_call_ended_txt" msgid="5977978317527299698">"Дуудлага дууссан"</string>
     <string name="clh_callFailed_powerOff_txt" msgid="8279934912560765361">"Нислэгийн горим асаалттай"</string>
     <string name="clh_callFailed_simError_txt" msgid="5128538525762326413">"SIM картад хандах боломжгүй"</string>
-    <string name="clh_incall_error_out_of_service_txt" msgid="2736010617446749869">"Мобайл сүлжээ байхгүй"</string>
+    <string name="clh_incall_error_out_of_service_txt" msgid="2736010617446749869">"Хөдөлгөөнт холбооны сүлжээ байхгүй"</string>
     <string name="clh_callFailed_satelliteEnabled_txt" msgid="1675517238240377396">"Хиймэл дагуулын горим асаалттай байна"</string>
     <string name="clh_callFailed_unassigned_number_txt" msgid="141967660286695682">"Таны залгахыг оролдож буй утасны дугаарт асуудал байна. Алдааны код 1."</string>
     <string name="clh_callFailed_no_route_to_destination_txt" msgid="4805015149822352308">"Дуудлагыг гүйцээж чадсангүй. Алдааны код 3."</string>
@@ -824,10 +824,10 @@
     <string name="callFailed_already_ringing" msgid="2376603543544289303">"Хариулаагүй ирсэн дуудлага байх үед дуудлага хийх боломжгүй. Шинэ дуудлага хийхийн өмнө ирсэн дуудлагад хариулах эсвэл татгалзана уу."</string>
     <string name="callFailed_calling_disabled" msgid="5010992739401206283">"ro.telephony.disable-call системийн өмчийг ашиглан дуудлагыг цуцалсан бол дуудлага хийх боломжгүй."</string>
     <string name="callFailed_too_many_calls" msgid="2761754044990799580">"Аль хэдийн хоёр дуудлага хийж байгаа тул дуудлага хийх боломжгүй байна. Шинэ дуудлага хийхийн өмнө аль нэг дуудлагыг салгах эсвэл тэдгээрийг хурал болгож нэгтгэнэ үү."</string>
-    <string name="supp_service_over_ut_precautions" msgid="2145018231396701311">"<xliff:g id="SUPP_SERVICE">%s</xliff:g>-г ашиглахын тулд мобайл датаг асаасан эсэхээ шалгана уу. Та үүнийг мобайл сүлжээний тохиргоонд өөрчлөх боломжтой."</string>
-    <string name="supp_service_over_ut_precautions_roaming" msgid="670342104569972327">"<xliff:g id="SUPP_SERVICE">%s</xliff:g>-г ашиглахын тулд мобайл дата болон дата роуминг асаасан эсэхээ шалгана уу. Та эдгээрийг мобайл сүлжээний тохиргоонд өөрчлөх боломжтой."</string>
-    <string name="supp_service_over_ut_precautions_dual_sim" msgid="5166866975550910474">"<xliff:g id="SUPP_SERVICE">%1$s</xliff:g>-г ашиглахын тулд SIM <xliff:g id="SIM_NUMBER">%2$d</xliff:g>-д мобайл датаг асаасан эсэхээ шалгана уу. Та үүнийг мобайл сүлжээний тохиргоонд өөрчлөх боломжтой."</string>
-    <string name="supp_service_over_ut_precautions_roaming_dual_sim" msgid="6627654855191817965">"<xliff:g id="SUPP_SERVICE">%1$s</xliff:g>-г ашиглахын тулд SIM <xliff:g id="SIM_NUMBER">%2$d</xliff:g>-д мобайл дата болон дата роуминг асаасан эсэхээ шалгана уу. Та эдгээрийг мобайл сүлжээний тохиргоонд өөрчлөх боломжтой."</string>
+    <string name="supp_service_over_ut_precautions" msgid="2145018231396701311">"<xliff:g id="SUPP_SERVICE">%s</xliff:g>-г ашиглахын тулд мобайл датаг асаасан эсэхээ шалгана уу. Та үүнийг хөдөлгөөнт холбооны сүлжээний тохиргоонд өөрчлөх боломжтой."</string>
+    <string name="supp_service_over_ut_precautions_roaming" msgid="670342104569972327">"<xliff:g id="SUPP_SERVICE">%s</xliff:g>-г ашиглахын тулд мобайл дата болон дата роуминг асаасан эсэхээ шалгана уу. Та эдгээрийг хөдөлгөөнт холбооны сүлжээний тохиргоонд өөрчлөх боломжтой."</string>
+    <string name="supp_service_over_ut_precautions_dual_sim" msgid="5166866975550910474">"<xliff:g id="SUPP_SERVICE">%1$s</xliff:g>-г ашиглахын тулд SIM <xliff:g id="SIM_NUMBER">%2$d</xliff:g>-д мобайл датаг асаасан эсэхээ шалгана уу. Та үүнийг хөдөлгөөнт холбооны сүлжээний тохиргоонд өөрчлөх боломжтой."</string>
+    <string name="supp_service_over_ut_precautions_roaming_dual_sim" msgid="6627654855191817965">"<xliff:g id="SUPP_SERVICE">%1$s</xliff:g>-г ашиглахын тулд SIM <xliff:g id="SIM_NUMBER">%2$d</xliff:g>-д мобайл дата болон дата роуминг асаасан эсэхээ шалгана уу. Та эдгээрийг хөдөлгөөнт холбооны сүлжээний тохиргоонд өөрчлөх боломжтой."</string>
     <string name="supp_service_over_ut_precautions_dialog_dismiss" msgid="5934541487903081652">"Үл хэрэгсэх"</string>
     <string name="radio_info_data_connection_enable" msgid="6183729739783252840">"Дата холболтыг идэвхжүүлэх"</string>
     <string name="radio_info_data_connection_disable" msgid="6404751291511368706">"Дата холболтыг идэвхгүй болгох"</string>
@@ -845,6 +845,8 @@
     <string name="radio_info_radio_power" msgid="8805595022160471587">"Мобайл радио цахилгаан"</string>
     <string name="simulate_out_of_service_string" msgid="7787925611727597193">"Үйлчилгээний хүрээнээс гарсан нөхцөл байдлыг загварчлах (зөвхөн дебагийн хийц)"</string>
     <string name="mock_carrier_roaming_satellite_string" msgid="4796300252858292593">"Оператор компанийн хуурамч хиймэл дагуулын горим (зөвхөн дебаг хийсэн хийц)"</string>
+    <!-- no translation found for esos_satellite_string (7274794226125968657) -->
+    <skip />
     <string name="radioInfo_menu_viewADN" msgid="4533179730908559846">"SIM хаягийн лавлахыг харах"</string>
     <string name="radioInfo_menu_viewFDN" msgid="1847236480527032061">"Залгахаар тохируулсан дугаарыг харах"</string>
     <string name="radioInfo_menu_viewSDN" msgid="2613431584522392842">"Үйлчилгээний залгах дугаарыг харах"</string>
diff --git a/res/values-mr/strings.xml b/res/values-mr/strings.xml
index 9ee54b0..5cf9d78 100644
--- a/res/values-mr/strings.xml
+++ b/res/values-mr/strings.xml
@@ -845,6 +845,7 @@
     <string name="radio_info_radio_power" msgid="8805595022160471587">"मोबाइल रेडिओ पॉवर"</string>
     <string name="simulate_out_of_service_string" msgid="7787925611727597193">"सेवा बंद आहे सिम्युलेट करा (फक्त डीबगचा बिल्‍ड)"</string>
     <string name="mock_carrier_roaming_satellite_string" msgid="4796300252858292593">"नमुना वाहकाचा उपग्रह मोड (फक्त डीबग बिल्ड)"</string>
+    <string name="esos_satellite_string" msgid="7274794226125968657">"प्रत्यक्ष सॅटेलाइट eSOS मोडची चाचणी करा (फक्त डीबग बिल्ड)"</string>
     <string name="radioInfo_menu_viewADN" msgid="4533179730908559846">"सिम ॲड्रेस बुक पहा"</string>
     <string name="radioInfo_menu_viewFDN" msgid="1847236480527032061">"निश्चित डायलिंग नंबर पहा"</string>
     <string name="radioInfo_menu_viewSDN" msgid="2613431584522392842">"सर्व्हिस डायलिंग नंबर पहा"</string>
diff --git a/res/values-ms/strings.xml b/res/values-ms/strings.xml
index f5d54f9..86de88e 100644
--- a/res/values-ms/strings.xml
+++ b/res/values-ms/strings.xml
@@ -845,6 +845,7 @@
     <string name="radio_info_radio_power" msgid="8805595022160471587">"Kuasa Radio Mudah Alih"</string>
     <string name="simulate_out_of_service_string" msgid="7787925611727597193">"Simulasi Rosak (Binaan Penyahpepijatan sahaja)"</string>
     <string name="mock_carrier_roaming_satellite_string" msgid="4796300252858292593">"Contoh Mod Satelit Pembawa (Binaan Penyahpepijatan sahaja)"</string>
+    <string name="esos_satellite_string" msgid="7274794226125968657">"Uji mod sSOS satelit sebenar (Binaan Penyahpepijatan sahaja)"</string>
     <string name="radioInfo_menu_viewADN" msgid="4533179730908559846">"Lihat Buku Alamat SIM"</string>
     <string name="radioInfo_menu_viewFDN" msgid="1847236480527032061">"Lihat Nombor Dailan Tetap"</string>
     <string name="radioInfo_menu_viewSDN" msgid="2613431584522392842">"Lihat Nombor Dailan Perkhidmatan"</string>
diff --git a/res/values-my/strings.xml b/res/values-my/strings.xml
index c327b54..4208775 100644
--- a/res/values-my/strings.xml
+++ b/res/values-my/strings.xml
@@ -845,6 +845,8 @@
     <string name="radio_info_radio_power" msgid="8805595022160471587">"မိုဘိုင်း ရေဒီယိုစွမ်းအား"</string>
     <string name="simulate_out_of_service_string" msgid="7787925611727597193">"အသွင်တူပြုလုပ်သောစက် အလုပ်မလုပ်ပါ (အမှားရှာပြင်ခြင်းသာလျှင်)"</string>
     <string name="mock_carrier_roaming_satellite_string" msgid="4796300252858292593">"Mock Carrier Satellite Mode (အမှားရှာပြင်ခြင်း အတွက်သာ)"</string>
+    <!-- no translation found for esos_satellite_string (7274794226125968657) -->
+    <skip />
     <string name="radioInfo_menu_viewADN" msgid="4533179730908559846">"SIM ထဲရှိ လိပ်စာ စာအုပ်ကိုကြည့်ပါ"</string>
     <string name="radioInfo_menu_viewFDN" msgid="1847236480527032061">"ခေါ်ဆိုရန် ကန့်သတ် နံပါတ်ကို ကြည့်မည်"</string>
     <string name="radioInfo_menu_viewSDN" msgid="2613431584522392842">"ခေါ်ဆိုသည့်ဝန်ဆောင်မှုနံပါတ်အားကြည့်မည်"</string>
diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml
index 6ca3099..30c7a9b 100644
--- a/res/values-nb/strings.xml
+++ b/res/values-nb/strings.xml
@@ -845,6 +845,8 @@
     <string name="radio_info_radio_power" msgid="8805595022160471587">"Strømforsyning for mobilradio"</string>
     <string name="simulate_out_of_service_string" msgid="7787925611727597193">"Ute av drift-simulering (bare for feilsøkingsversjoner)"</string>
     <string name="mock_carrier_roaming_satellite_string" msgid="4796300252858292593">"Satelittmodus for fiktiv operatør (feilsøkingsversjon)"</string>
+    <!-- no translation found for esos_satellite_string (7274794226125968657) -->
+    <skip />
     <string name="radioInfo_menu_viewADN" msgid="4533179730908559846">"Se adressebok for SIM-kort"</string>
     <string name="radioInfo_menu_viewFDN" msgid="1847236480527032061">"Vis forhåndsbestemte numre"</string>
     <string name="radioInfo_menu_viewSDN" msgid="2613431584522392842">"Vis tjenestenumre"</string>
diff --git a/res/values-ne/strings.xml b/res/values-ne/strings.xml
index d225c64..a74ec57 100644
--- a/res/values-ne/strings.xml
+++ b/res/values-ne/strings.xml
@@ -306,7 +306,7 @@
     <string name="carrier_settings_euicc_summary" msgid="2027941166597330117">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g> — <xliff:g id="PHONE_NUMBER">%2$s</xliff:g>"</string>
     <string name="mobile_data_settings_title" msgid="7228249980933944101">"मोबाइल डेटा"</string>
     <string name="mobile_data_settings_summary" msgid="5012570152029118471">"मोबाइल नेटवर्कको प्रयोग गरी डेटामाथि पहुँच गर्नुहोस्"</string>
-    <string name="data_usage_disable_mobile" msgid="5669109209055988308">"मोबाइल डेटा निष्क्रिय पार्ने हो?"</string>
+    <string name="data_usage_disable_mobile" msgid="5669109209055988308">"मोबाइल डेटा अफ गर्ने हो?"</string>
     <string name="sim_selection_required_pref" msgid="6985901872978341314">"चयन गर्न आवश्यक छ"</string>
     <string name="sim_change_data_title" msgid="9142726786345906606">"डेटा सिम परिवर्तन गर्ने हो?"</string>
     <string name="sim_change_data_message" msgid="3567358694255933280">"मोबाइल डेटाका लागि <xliff:g id="OLD_SIM">%2$s</xliff:g> को सट्टा <xliff:g id="NEW_SIM">%1$s</xliff:g> को प्रयोग गर्ने हो?"</string>
@@ -845,6 +845,7 @@
     <string name="radio_info_radio_power" msgid="8805595022160471587">"मोबाइल रेडियोको पावर"</string>
     <string name="simulate_out_of_service_string" msgid="7787925611727597193">"\"सेवा उपलब्ध छैन\" सिमुलेट गर्नुहोस् (डिबग बिल्डमा मात्र सिमुलेट गर्न मिल्छ)"</string>
     <string name="mock_carrier_roaming_satellite_string" msgid="4796300252858292593">"सेवा प्रदायकको स्याटेलाइट मोडको परीक्षण गर्नुहोस् (डिबग बिल्ड मात्र)"</string>
+    <string name="esos_satellite_string" msgid="7274794226125968657">"वास्तविक स्याटेलाइट eSOS मोड परीक्षण गर्नुहोस् (डिबग बिल्ड मात्र)"</string>
     <string name="radioInfo_menu_viewADN" msgid="4533179730908559846">"SIM को ठेगाना पुस्तिका हेर्नुहोस्"</string>
     <string name="radioInfo_menu_viewFDN" msgid="1847236480527032061">"स्थिर डायल गर्ने नम्बरहरू हेर्नुहोस्"</string>
     <string name="radioInfo_menu_viewSDN" msgid="2613431584522392842">"सेवामा डायल गर्ने नम्बरहरू हेर्नुहोस्"</string>
diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml
index 3384e1d..7ffa8f4 100644
--- a/res/values-nl/strings.xml
+++ b/res/values-nl/strings.xml
@@ -845,6 +845,8 @@
     <string name="radio_info_radio_power" msgid="8805595022160471587">"Mobiel radiovermogen"</string>
     <string name="simulate_out_of_service_string" msgid="7787925611727597193">"\'Niet in gebruik\' simuleren (alleen in foutopsporingsbuild)"</string>
     <string name="mock_carrier_roaming_satellite_string" msgid="4796300252858292593">"Satellietmodus voor testprovider (alleen in foutopsporingsbuild)"</string>
+    <!-- no translation found for esos_satellite_string (7274794226125968657) -->
+    <skip />
     <string name="radioInfo_menu_viewADN" msgid="4533179730908559846">"Adresboek op simkaart bekijken"</string>
     <string name="radioInfo_menu_viewFDN" msgid="1847236480527032061">"Vaste nummers bekijken"</string>
     <string name="radioInfo_menu_viewSDN" msgid="2613431584522392842">"Servicenummers bekijken"</string>
diff --git a/res/values-or/strings.xml b/res/values-or/strings.xml
index 178d06c..6158a39 100644
--- a/res/values-or/strings.xml
+++ b/res/values-or/strings.xml
@@ -845,6 +845,7 @@
     <string name="radio_info_radio_power" msgid="8805595022160471587">"ମୋବାଇଲ୍ ରେଡିଓ ପାୱାର୍"</string>
     <string name="simulate_out_of_service_string" msgid="7787925611727597193">"\"କାମ କରୁନାହିଁ\"ରେ ସିମୁଲେଟ କରନ୍ତୁ (କେବଳ ଡିବଗ ବିଲ୍ଡ)"</string>
     <string name="mock_carrier_roaming_satellite_string" msgid="4796300252858292593">"ମକ କେରିଅର ସେଟେଲାଇଟ ମୋଡ (କେବଳ ଡିବଗ ବିଲ୍ଡ)"</string>
+    <string name="esos_satellite_string" msgid="7274794226125968657">"ପ୍ରକୃତ ସେଟେଲାଇଟର eSOS ମୋଡ ପରୀକ୍ଷା କରନ୍ତୁ (କେବଳ ଡିବଗ ବିଲ୍ଡ)"</string>
     <string name="radioInfo_menu_viewADN" msgid="4533179730908559846">"ସିମ୍‌ରେ ଥିବା ଠିକଣା ପୁସ୍ତକ ଦେଖନ୍ତୁ"</string>
     <string name="radioInfo_menu_viewFDN" msgid="1847236480527032061">"ସ୍ଥାୟୀ ଡାଏଲିଂ ନମ୍ୱରଗୁଡ଼ିକୁ ଦେଖନ୍ତୁ"</string>
     <string name="radioInfo_menu_viewSDN" msgid="2613431584522392842">"ସର୍ଭିସ୍ ଡାଏଲିଂ ନମ୍ୱରଗୁଡ଼ିକ ଦେଖନ୍ତୁ"</string>
diff --git a/res/values-pa/strings.xml b/res/values-pa/strings.xml
index fb0d654..e46f5c7 100644
--- a/res/values-pa/strings.xml
+++ b/res/values-pa/strings.xml
@@ -845,6 +845,8 @@
     <string name="radio_info_radio_power" msgid="8805595022160471587">"ਮੋਬਾਈਲ ਰੇਡੀਓ ਪਾਵਰ"</string>
     <string name="simulate_out_of_service_string" msgid="7787925611727597193">"\'ਸੇਵਾ ਵਿੱਚ ਨਹੀਂ\' ਨੂੰ ਸਿਮੂਲੇਟ ਕਰੋ (ਸਿਰਫ਼ ਡੀਬੱਗ ਬਿਲਡ)"</string>
     <string name="mock_carrier_roaming_satellite_string" msgid="4796300252858292593">"ਮੌਕ ਕੈਰੀਅਰ ਉਪਗ੍ਰਹਿ ਮੋਡ (ਸਿਰਫ਼ ਡੀਬੱਗ ਬਿਲਡ)"</string>
+    <!-- no translation found for esos_satellite_string (7274794226125968657) -->
+    <skip />
     <string name="radioInfo_menu_viewADN" msgid="4533179730908559846">"ਸਿਮ ਦੀ ਪਤਾ ਬੁੱਕ ਦੇਖੋ"</string>
     <string name="radioInfo_menu_viewFDN" msgid="1847236480527032061">"ਫਿਕਸਡ ਡਾਇਲਿੰਗ ਨੰਬਰ ਦੇਖੋ"</string>
     <string name="radioInfo_menu_viewSDN" msgid="2613431584522392842">"ਸੇਵਾ ਡਾਇਲਿੰਗ ਨੰਬਰ ਦੇਖੋ"</string>
diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml
index 2067e08..b5b4721 100644
--- a/res/values-pl/strings.xml
+++ b/res/values-pl/strings.xml
@@ -845,6 +845,8 @@
     <string name="radio_info_radio_power" msgid="8805595022160471587">"Moc sygnału komórkowego"</string>
     <string name="simulate_out_of_service_string" msgid="7787925611727597193">"Symulowana przerwa w działaniu usługi (tylko w kompilacji do debugowania)"</string>
     <string name="mock_carrier_roaming_satellite_string" msgid="4796300252858292593">"Symulowany tryb satelitarny operatora (tylko kompilacja do debugowania)"</string>
+    <!-- no translation found for esos_satellite_string (7274794226125968657) -->
+    <skip />
     <string name="radioInfo_menu_viewADN" msgid="4533179730908559846">"Wyświetl książkę adresową z karty SIM"</string>
     <string name="radioInfo_menu_viewFDN" msgid="1847236480527032061">"Wyświetl ustalone numery"</string>
     <string name="radioInfo_menu_viewSDN" msgid="2613431584522392842">"Wyświetl numery usług"</string>
diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml
index 10aa84d..d0e893c 100644
--- a/res/values-pt-rPT/strings.xml
+++ b/res/values-pt-rPT/strings.xml
@@ -845,6 +845,8 @@
     <string name="radio_info_radio_power" msgid="8805595022160471587">"Potência do rádio móvel"</string>
     <string name="simulate_out_of_service_string" msgid="7787925611727597193">"Simule o modo fora de serviço (apenas na versão de depuração)"</string>
     <string name="mock_carrier_roaming_satellite_string" msgid="4796300252858292593">"Modo satélite da operadora fictícia (apenas na versão de depuração)"</string>
+    <!-- no translation found for esos_satellite_string (7274794226125968657) -->
+    <skip />
     <string name="radioInfo_menu_viewADN" msgid="4533179730908559846">"Ver livro de endereços do SIM"</string>
     <string name="radioInfo_menu_viewFDN" msgid="1847236480527032061">"Ver números autorizados"</string>
     <string name="radioInfo_menu_viewSDN" msgid="2613431584522392842">"Ver números de marcação de serviços"</string>
diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml
index 26d3c06..e59f195 100644
--- a/res/values-pt/strings.xml
+++ b/res/values-pt/strings.xml
@@ -845,6 +845,7 @@
     <string name="radio_info_radio_power" msgid="8805595022160471587">"Potência do rádio celular"</string>
     <string name="simulate_out_of_service_string" msgid="7787925611727597193">"Simular o modo fora de serviço (somente build de depuração)"</string>
     <string name="mock_carrier_roaming_satellite_string" msgid="4796300252858292593">"Simulação de modo satélite da operadora (somente build de depuração)"</string>
+    <string name="esos_satellite_string" msgid="7274794226125968657">"Testar o modo eSOS por satélite (somente build de depuração)"</string>
     <string name="radioInfo_menu_viewADN" msgid="4533179730908559846">"Ver o catálogo de endereços do chip"</string>
     <string name="radioInfo_menu_viewFDN" msgid="1847236480527032061">"Ver números de discagem fixa"</string>
     <string name="radioInfo_menu_viewSDN" msgid="2613431584522392842">"Ver números de discagem do serviço"</string>
diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml
index 39c3d0b..92531d2 100644
--- a/res/values-ro/strings.xml
+++ b/res/values-ro/strings.xml
@@ -845,6 +845,8 @@
     <string name="radio_info_radio_power" msgid="8805595022160471587">"Alimentare radio celular"</string>
     <string name="simulate_out_of_service_string" msgid="7787925611727597193">"Simulează modul în afara ariei de acoperire (numai în versiunea pentru remedierea erorilor)"</string>
     <string name="mock_carrier_roaming_satellite_string" msgid="4796300252858292593">"Mod Satelit al operatorului de testare (numai versiune pentru remedierea erorilor)"</string>
+    <!-- no translation found for esos_satellite_string (7274794226125968657) -->
+    <skip />
     <string name="radioInfo_menu_viewADN" msgid="4533179730908559846">"Afișează agenda de pe SIM"</string>
     <string name="radioInfo_menu_viewFDN" msgid="1847236480527032061">"Afișează numerele pentru apeluri restricționate"</string>
     <string name="radioInfo_menu_viewSDN" msgid="2613431584522392842">"Vezi numere de apelare de serviciu"</string>
diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml
index cd163bc..57d133e 100644
--- a/res/values-ru/strings.xml
+++ b/res/values-ru/strings.xml
@@ -306,7 +306,7 @@
     <string name="carrier_settings_euicc_summary" msgid="2027941166597330117">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g> – <xliff:g id="PHONE_NUMBER">%2$s</xliff:g>"</string>
     <string name="mobile_data_settings_title" msgid="7228249980933944101">"Мобильный интернет"</string>
     <string name="mobile_data_settings_summary" msgid="5012570152029118471">"Доступ к Интернету по мобильной сети"</string>
-    <string name="data_usage_disable_mobile" msgid="5669109209055988308">"Отключить мобильный Интернет?"</string>
+    <string name="data_usage_disable_mobile" msgid="5669109209055988308">"Отключить мобильный интернет?"</string>
     <string name="sim_selection_required_pref" msgid="6985901872978341314">"Выберите SIM-карту"</string>
     <string name="sim_change_data_title" msgid="9142726786345906606">"Смена SIM-карты"</string>
     <string name="sim_change_data_message" msgid="3567358694255933280">"Использовать для передачи данных по мобильной сети SIM-карту \"<xliff:g id="NEW_SIM">%1$s</xliff:g>\" (вместо \"<xliff:g id="OLD_SIM">%2$s</xliff:g>\")?"</string>
@@ -845,6 +845,7 @@
     <string name="radio_info_radio_power" msgid="8805595022160471587">"Мощность радиосигнала"</string>
     <string name="simulate_out_of_service_string" msgid="7787925611727597193">"Моделирование нахождения вне зоны обслуживания (только отладочная сборка)"</string>
     <string name="mock_carrier_roaming_satellite_string" msgid="4796300252858292593">"Режим спутниковой связи симуляции оператора (только отладочная сборка)"</string>
+    <string name="esos_satellite_string" msgid="7274794226125968657">"Проверка спутникового режима eSOS (только отладочная сборка)"</string>
     <string name="radioInfo_menu_viewADN" msgid="4533179730908559846">"Посмотреть адресную книгу на SIM-карте"</string>
     <string name="radioInfo_menu_viewFDN" msgid="1847236480527032061">"Список разрешенных номеров"</string>
     <string name="radioInfo_menu_viewSDN" msgid="2613431584522392842">"Посмотреть номера служебного набора"</string>
diff --git a/res/values-si/strings.xml b/res/values-si/strings.xml
index 06ac7f4..156abc0 100644
--- a/res/values-si/strings.xml
+++ b/res/values-si/strings.xml
@@ -845,6 +845,8 @@
     <string name="radio_info_radio_power" msgid="8805595022160471587">"ජංගම රේඩියෝ බලය"</string>
     <string name="simulate_out_of_service_string" msgid="7787925611727597193">"සේවයෙන් බැහැරව අනුකරණය කරන්න (නිදොස් තැනුම පමණි)"</string>
     <string name="mock_carrier_roaming_satellite_string" msgid="4796300252858292593">"ආදර්ශ වාහක චන්ද්‍රිකා ප්‍රකාරය (නිදොස් තැනීමට පමණි)"</string>
+    <!-- no translation found for esos_satellite_string (7274794226125968657) -->
+    <skip />
     <string name="radioInfo_menu_viewADN" msgid="4533179730908559846">"SIM ලිපින පොත බලන්න"</string>
     <string name="radioInfo_menu_viewFDN" msgid="1847236480527032061">"ස්ථාවර ඇමතුම් අංක පෙන්වන්න"</string>
     <string name="radioInfo_menu_viewSDN" msgid="2613431584522392842">"සේවා ඩයල් කිරීමේ අංක පෙන්වන්න"</string>
diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml
index 2385d5f..3427053 100644
--- a/res/values-sk/strings.xml
+++ b/res/values-sk/strings.xml
@@ -582,7 +582,7 @@
     <string name="dialerKeyboardHintText" msgid="1115266533703764049">"Číslo vytočíte pomocou klávesnice."</string>
     <string name="onscreenHoldText" msgid="4025348842151665191">"Podržať"</string>
     <string name="onscreenEndCallText" msgid="6138725377654842757">"Koniec"</string>
-    <string name="onscreenShowDialpadText" msgid="658465753816164079">"Číselná klávesnica"</string>
+    <string name="onscreenShowDialpadText" msgid="658465753816164079">"Číselník"</string>
     <string name="onscreenMuteText" msgid="5470306116733843621">"Ignorovať"</string>
     <string name="onscreenAddCallText" msgid="9075675082903611677">"Pridať hovor"</string>
     <string name="onscreenMergeCallsText" msgid="3692389519611225407">"Zlúčiť hovory"</string>
@@ -845,6 +845,8 @@
     <string name="radio_info_radio_power" msgid="8805595022160471587">"Sila signálu GSM"</string>
     <string name="simulate_out_of_service_string" msgid="7787925611727597193">"Simulácia nefungujúceho zariadenia (možné iba v ladiacej zostave)"</string>
     <string name="mock_carrier_roaming_satellite_string" msgid="4796300252858292593">"Simulácia satelitného režimu operátora (iba ladiaca zostava)"</string>
+    <!-- no translation found for esos_satellite_string (7274794226125968657) -->
+    <skip />
     <string name="radioInfo_menu_viewADN" msgid="4533179730908559846">"Zobraziť adresár SIM karty"</string>
     <string name="radioInfo_menu_viewFDN" msgid="1847236480527032061">"Zobraziť povolené čísla"</string>
     <string name="radioInfo_menu_viewSDN" msgid="2613431584522392842">"Zobraziť čísla volaní služieb"</string>
diff --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml
index 85fc9d1..55370a7 100644
--- a/res/values-sl/strings.xml
+++ b/res/values-sl/strings.xml
@@ -845,6 +845,8 @@
     <string name="radio_info_radio_power" msgid="8805595022160471587">"Moč radia mobilne naprave"</string>
     <string name="simulate_out_of_service_string" msgid="7787925611727597193">"Simulacija nedelovanja (samo za gradnjo za odpravljanje napak)"</string>
     <string name="mock_carrier_roaming_satellite_string" msgid="4796300252858292593">"Lažni satelitski način operaterja (samo gradnja za odpravljanje napak)"</string>
+    <!-- no translation found for esos_satellite_string (7274794226125968657) -->
+    <skip />
     <string name="radioInfo_menu_viewADN" msgid="4533179730908559846">"Prikaži imenik na kartici SIM"</string>
     <string name="radioInfo_menu_viewFDN" msgid="1847236480527032061">"Prikaži številke za zaporo odhodnih klicev"</string>
     <string name="radioInfo_menu_viewSDN" msgid="2613431584522392842">"Prikaži številke za klicanje storitev"</string>
diff --git a/res/values-sq/strings.xml b/res/values-sq/strings.xml
index b7c1e55..71220a1 100644
--- a/res/values-sq/strings.xml
+++ b/res/values-sq/strings.xml
@@ -845,6 +845,8 @@
     <string name="radio_info_radio_power" msgid="8805595022160471587">"Fuqia e radios së rrjetit celular"</string>
     <string name="simulate_out_of_service_string" msgid="7787925611727597193">"Simulo gjendjen jashtë shërbimit (vetëm versioni i korrigjimit)"</string>
     <string name="mock_carrier_roaming_satellite_string" msgid="4796300252858292593">"Simulo modalitetin e satelitit të operatorit celular (vetëm versioni i korrigjimit)"</string>
+    <!-- no translation found for esos_satellite_string (7274794226125968657) -->
+    <skip />
     <string name="radioInfo_menu_viewADN" msgid="4533179730908559846">"Shiko librin e adresave të kartës SIM"</string>
     <string name="radioInfo_menu_viewFDN" msgid="1847236480527032061">"Shiko numrat me telefonim të përzgjedhur"</string>
     <string name="radioInfo_menu_viewSDN" msgid="2613431584522392842">"Shiko numrat e telefonit të shërbimit"</string>
diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml
index 9bacab0..cec9a1d 100644
--- a/res/values-sr/strings.xml
+++ b/res/values-sr/strings.xml
@@ -845,6 +845,8 @@
     <string name="radio_info_radio_power" msgid="8805595022160471587">"Напајање за радио на мобилним уређајима"</string>
     <string name="simulate_out_of_service_string" msgid="7787925611727597193">"Симулација не функционише (само верзија са отклоњеним грешкама)"</string>
     <string name="mock_carrier_roaming_satellite_string" msgid="4796300252858292593">"Лажни режим мобилног оператера за слање преко сателита (само верзија за отклањање грешака)"</string>
+    <!-- no translation found for esos_satellite_string (7274794226125968657) -->
+    <skip />
     <string name="radioInfo_menu_viewADN" msgid="4533179730908559846">"Прикажи адресар SIM-а"</string>
     <string name="radioInfo_menu_viewFDN" msgid="1847236480527032061">"Прикажи бројеве за фиксно бирање"</string>
     <string name="radioInfo_menu_viewSDN" msgid="2613431584522392842">"Прикажи бројеве за сервисно бирање"</string>
diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml
index 0bae57a..3be1b7e 100644
--- a/res/values-sv/strings.xml
+++ b/res/values-sv/strings.xml
@@ -845,6 +845,7 @@
     <string name="radio_info_radio_power" msgid="8805595022160471587">"Strömförsörjning för mobilradio"</string>
     <string name="simulate_out_of_service_string" msgid="7787925611727597193">"Simulera ur funktion (endast felsökningsversion)"</string>
     <string name="mock_carrier_roaming_satellite_string" msgid="4796300252858292593">"Simulering av operatörssatellitläge (version endast för felsökning)"</string>
+    <string name="esos_satellite_string" msgid="7274794226125968657">"Testa verkligt eSOS-satellitläge (endast felsökningsversion)"</string>
     <string name="radioInfo_menu_viewADN" msgid="4533179730908559846">"Visa SIM-adressbok"</string>
     <string name="radioInfo_menu_viewFDN" msgid="1847236480527032061">"Visa Fasta nummer"</string>
     <string name="radioInfo_menu_viewSDN" msgid="2613431584522392842">"Visa tjänstenummer"</string>
diff --git a/res/values-sw/strings.xml b/res/values-sw/strings.xml
index 9d811b3..a060ce3 100644
--- a/res/values-sw/strings.xml
+++ b/res/values-sw/strings.xml
@@ -845,6 +845,8 @@
     <string name="radio_info_radio_power" msgid="8805595022160471587">"Nishati ya Redio ya Vifaa vya Mkononi"</string>
     <string name="simulate_out_of_service_string" msgid="7787925611727597193">"Kifaa cha Kuiga Hakifanyi Kazi (Muundo wa Utatuzi pekee)"</string>
     <string name="mock_carrier_roaming_satellite_string" msgid="4796300252858292593">"Hali ya Setilaiti ya Jaribio la Mtoa Huduma (Muundo wa Utatuzi pekee)"</string>
+    <!-- no translation found for esos_satellite_string (7274794226125968657) -->
+    <skip />
     <string name="radioInfo_menu_viewADN" msgid="4533179730908559846">"Angalia Kitabu cha Anwani katika SIM"</string>
     <string name="radioInfo_menu_viewFDN" msgid="1847236480527032061">"Ona Nambari za Simu Zilizobainishwa"</string>
     <string name="radioInfo_menu_viewSDN" msgid="2613431584522392842">"Angalia Nambari Zilizowekwa na Mtoa Huduma"</string>
diff --git a/res/values-ta/strings.xml b/res/values-ta/strings.xml
index 3bd1812..4f35095 100644
--- a/res/values-ta/strings.xml
+++ b/res/values-ta/strings.xml
@@ -845,6 +845,8 @@
     <string name="radio_info_radio_power" msgid="8805595022160471587">"மொபைல் ரேடியோ பவர்"</string>
     <string name="simulate_out_of_service_string" msgid="7787925611727597193">"சாதனம் \'வேலை செய்யவில்லை\' என்பதை சிமுலேட் செய்தல் (பிழைதிருத்தப் பதிப்பில் மட்டும்)"</string>
     <string name="mock_carrier_roaming_satellite_string" msgid="4796300252858292593">"Mock மொபைல் நிறுவன சாட்டிலைட் பயன்முறை (பிழைதிருத்த பதிப்பு மட்டும்)"</string>
+    <!-- no translation found for esos_satellite_string (7274794226125968657) -->
+    <skip />
     <string name="radioInfo_menu_viewADN" msgid="4533179730908559846">"சிம் முகவரிப் புத்தகத்தைக் காட்டு"</string>
     <string name="radioInfo_menu_viewFDN" msgid="1847236480527032061">"நிலையான அழைப்பு எண்களைக் காட்டு"</string>
     <string name="radioInfo_menu_viewSDN" msgid="2613431584522392842">"சேவை அழைப்பு எண்களைக் காட்டு"</string>
diff --git a/res/values-te/strings.xml b/res/values-te/strings.xml
index b271a86..cd033b4 100644
--- a/res/values-te/strings.xml
+++ b/res/values-te/strings.xml
@@ -845,6 +845,7 @@
     <string name="radio_info_radio_power" msgid="8805595022160471587">"మొబైల్ రేడియో పవర్"</string>
     <string name="simulate_out_of_service_string" msgid="7787925611727597193">"పరికరాన్ని సిమ్యులేట్ చేయడం అందుబాటులో లేదు (డీబగ్ బిల్డ్ మోడ్‌లో మాత్రమే)"</string>
     <string name="mock_carrier_roaming_satellite_string" msgid="4796300252858292593">"మాక్ క్యారియర్ శాటిలైట్ మోడ్ (డీబగ్ బిల్డ్ మోడ్‌లో మాత్రమే)"</string>
+    <string name="esos_satellite_string" msgid="7274794226125968657">"రియల్ శాటిలైట్ eSOS మోడ్‌ను టెస్ట్ చేయండి (డీబగ్ బిల్డ్ మోడ్‌లో మాత్రమే)"</string>
     <string name="radioInfo_menu_viewADN" msgid="4533179730908559846">"SIM అడ్రస్‌ పుస్తకాన్ని చూడండి"</string>
     <string name="radioInfo_menu_viewFDN" msgid="1847236480527032061">"ఫిక్స్‌డ్ డయలింగ్ నంబర్‌లను చూడండి"</string>
     <string name="radioInfo_menu_viewSDN" msgid="2613431584522392842">"సర్వీస్ డయలింగ్ నంబర్‌లను చూడండి"</string>
diff --git a/res/values-th/strings.xml b/res/values-th/strings.xml
index 1d3f89d..f4db199 100644
--- a/res/values-th/strings.xml
+++ b/res/values-th/strings.xml
@@ -845,6 +845,8 @@
     <string name="radio_info_radio_power" msgid="8805595022160471587">"กำลังส่งของวิทยุเครือข่ายมือถือ"</string>
     <string name="simulate_out_of_service_string" msgid="7787925611727597193">"จําลองความไม่พร้อมให้บริการ (บิลด์การแก้ไขข้อบกพร่องเท่านั้น)"</string>
     <string name="mock_carrier_roaming_satellite_string" msgid="4796300252858292593">"โหมดดาวเทียมของผู้ให้บริการจำลอง (บิลด์การแก้ไขข้อบกพร่องเท่านั้น)"</string>
+    <!-- no translation found for esos_satellite_string (7274794226125968657) -->
+    <skip />
     <string name="radioInfo_menu_viewADN" msgid="4533179730908559846">"ดูสมุดที่อยู่ของซิม"</string>
     <string name="radioInfo_menu_viewFDN" msgid="1847236480527032061">"ดูการจำกัดหมายเลขโทรออก"</string>
     <string name="radioInfo_menu_viewSDN" msgid="2613431584522392842">"ดูหมายเลขรับบริการโทรออก"</string>
diff --git a/res/values-tl/strings.xml b/res/values-tl/strings.xml
index 61ca52c..c8e1b2c 100644
--- a/res/values-tl/strings.xml
+++ b/res/values-tl/strings.xml
@@ -845,6 +845,7 @@
     <string name="radio_info_radio_power" msgid="8805595022160471587">"Mobile Radio Power"</string>
     <string name="simulate_out_of_service_string" msgid="7787925611727597193">"Mag-simulate ng Hindi Gumagana (Build sa Pag-debug lang)"</string>
     <string name="mock_carrier_roaming_satellite_string" msgid="4796300252858292593">"Satellite Mode ng Mock Carrier (Debug Build lang)"</string>
+    <string name="esos_satellite_string" msgid="7274794226125968657">"Test real satellite eSOS mode (Build sa Pag-debug lang)"</string>
     <string name="radioInfo_menu_viewADN" msgid="4533179730908559846">"Tingnan ang Address Book ng SIM"</string>
     <string name="radioInfo_menu_viewFDN" msgid="1847236480527032061">"Tingnan ang Mga Fixed Dialing Number"</string>
     <string name="radioInfo_menu_viewSDN" msgid="2613431584522392842">"Tingnan ang Mga Service Dialing Number"</string>
diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml
index c7b55a5..0c3fbfc 100644
--- a/res/values-tr/strings.xml
+++ b/res/values-tr/strings.xml
@@ -845,6 +845,8 @@
     <string name="radio_info_radio_power" msgid="8805595022160471587">"Mobil Radyo Gücü"</string>
     <string name="simulate_out_of_service_string" msgid="7787925611727597193">"Hizmet Dışı Simülasyonu (Yalnızca Hata Ayıklama Derlemesi)"</string>
     <string name="mock_carrier_roaming_satellite_string" msgid="4796300252858292593">"Örnek operatör uydu modu (yalnızca hata ayıklama derlemesi)"</string>
+    <!-- no translation found for esos_satellite_string (7274794226125968657) -->
+    <skip />
     <string name="radioInfo_menu_viewADN" msgid="4533179730908559846">"SIM Adres Defterini Görüntüle"</string>
     <string name="radioInfo_menu_viewFDN" msgid="1847236480527032061">"Sabit Arama Numaralarını Görüntüle"</string>
     <string name="radioInfo_menu_viewSDN" msgid="2613431584522392842">"Hizmet Arama Numaralarını Görüntüle"</string>
diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml
index 1075ddf..c7a74e2 100644
--- a/res/values-uk/strings.xml
+++ b/res/values-uk/strings.xml
@@ -845,6 +845,7 @@
     <string name="radio_info_radio_power" msgid="8805595022160471587">"Потужність мобільного радіо"</string>
     <string name="simulate_out_of_service_string" msgid="7787925611727597193">"Імітація знаходження поза зоною обслуговування (лише складання для налагодження)"</string>
     <string name="mock_carrier_roaming_satellite_string" msgid="4796300252858292593">"Режим супутника оператора Mock (лише складання для налагодження)"</string>
+    <string name="esos_satellite_string" msgid="7274794226125968657">"Тестувати реальний режим супутникового сигналу SOS (лише складання для налагодження)"</string>
     <string name="radioInfo_menu_viewADN" msgid="4533179730908559846">"Переглянути адресну книгу SIM-карти"</string>
     <string name="radioInfo_menu_viewFDN" msgid="1847236480527032061">"Переглянути фіксовані номери"</string>
     <string name="radioInfo_menu_viewSDN" msgid="2613431584522392842">"Переглянути службові номери"</string>
diff --git a/res/values-ur/strings.xml b/res/values-ur/strings.xml
index bf5cd25..14965ab 100644
--- a/res/values-ur/strings.xml
+++ b/res/values-ur/strings.xml
@@ -845,6 +845,7 @@
     <string name="radio_info_radio_power" msgid="8805595022160471587">"موبائل ریڈیو پاور"</string>
     <string name="simulate_out_of_service_string" msgid="7787925611727597193">"\'سروس دستیاب نہیں ہے\' موڈ کو سمیولیٹ کریں (صرف ڈیبگ بلڈ کیلئے)"</string>
     <string name="mock_carrier_roaming_satellite_string" msgid="4796300252858292593">"موک کیریئر سیٹلائٹ موڈ (صرف ڈیبگ بلڈ)"</string>
+    <string name="esos_satellite_string" msgid="7274794226125968657">"‏اصل سیٹلائٹ eSOS وضع کی جانچ کریں (صرف ڈیبگ بلڈ)"</string>
     <string name="radioInfo_menu_viewADN" msgid="4533179730908559846">"‏SIM ایڈریس بک دیکھیں"</string>
     <string name="radioInfo_menu_viewFDN" msgid="1847236480527032061">"فکسڈ ڈائلنگ نمبرز دیکھیں"</string>
     <string name="radioInfo_menu_viewSDN" msgid="2613431584522392842">"سروس ڈائلنگ نمبرز دیکھیں"</string>
diff --git a/res/values-uz/strings.xml b/res/values-uz/strings.xml
index 858bfbc..f911475 100644
--- a/res/values-uz/strings.xml
+++ b/res/values-uz/strings.xml
@@ -845,6 +845,7 @@
     <string name="radio_info_radio_power" msgid="8805595022160471587">"Radio signal quvvati"</string>
     <string name="simulate_out_of_service_string" msgid="7787925611727597193">"Xizmatdan tashqari simulyatsiya (faqat nosozliklarni aniqlash dasturi uchun)"</string>
     <string name="mock_carrier_roaming_satellite_string" msgid="4796300252858292593">"Soxta operator sputnik rejimi (faqat debag nashrida)"</string>
+    <string name="esos_satellite_string" msgid="7274794226125968657">"Haqiqiy sputnik eSOS rejimini sinash (faqat debag nashrida)"</string>
     <string name="radioInfo_menu_viewADN" msgid="4533179730908559846">"SIM kartadagi abonentlar ro‘yxatini ochish"</string>
     <string name="radioInfo_menu_viewFDN" msgid="1847236480527032061">"Ruxsat etilgan raqamlar ro‘yxatini ochish"</string>
     <string name="radioInfo_menu_viewSDN" msgid="2613431584522392842">"Xizmatlarni terish raqamlarini ochish"</string>
diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml
index c2e9074..eb5a928 100644
--- a/res/values-vi/strings.xml
+++ b/res/values-vi/strings.xml
@@ -845,6 +845,8 @@
     <string name="radio_info_radio_power" msgid="8805595022160471587">"Cường độ của sóng di động"</string>
     <string name="simulate_out_of_service_string" msgid="7787925611727597193">"Mô phỏng thiết bị không hoạt động (chỉ dành cho bản gỡ lỗi)"</string>
     <string name="mock_carrier_roaming_satellite_string" msgid="4796300252858292593">"Mô phỏng chế độ vệ tinh của nhà mạng (chỉ dành cho Bản gỡ lỗi)"</string>
+    <!-- no translation found for esos_satellite_string (7274794226125968657) -->
+    <skip />
     <string name="radioInfo_menu_viewADN" msgid="4533179730908559846">"Xem sổ địa chỉ trên SIM"</string>
     <string name="radioInfo_menu_viewFDN" msgid="1847236480527032061">"Xem số gọi định sẵn"</string>
     <string name="radioInfo_menu_viewSDN" msgid="2613431584522392842">"Xem số quay số dịch vụ"</string>
diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
index 0e19c2f..6c8efbf 100644
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/strings.xml
@@ -845,6 +845,8 @@
     <string name="radio_info_radio_power" msgid="8805595022160471587">"移动无线装置电源"</string>
     <string name="simulate_out_of_service_string" msgid="7787925611727597193">"模拟服务终止(仅限调试 build)"</string>
     <string name="mock_carrier_roaming_satellite_string" msgid="4796300252858292593">"模拟运营商卫星模式(仅限调试 build)"</string>
+    <!-- no translation found for esos_satellite_string (7274794226125968657) -->
+    <skip />
     <string name="radioInfo_menu_viewADN" msgid="4533179730908559846">"查看 SIM 卡通讯录"</string>
     <string name="radioInfo_menu_viewFDN" msgid="1847236480527032061">"查看固定拨号号码"</string>
     <string name="radioInfo_menu_viewSDN" msgid="2613431584522392842">"查看服务拨号号码"</string>
diff --git a/res/values-zh-rHK/strings.xml b/res/values-zh-rHK/strings.xml
index 51cac5a..f679378 100644
--- a/res/values-zh-rHK/strings.xml
+++ b/res/values-zh-rHK/strings.xml
@@ -845,6 +845,8 @@
     <string name="radio_info_radio_power" msgid="8805595022160471587">"流動無線電的電源"</string>
     <string name="simulate_out_of_service_string" msgid="7787925611727597193">"模擬沒有服務 (僅限偵錯版本)"</string>
     <string name="mock_carrier_roaming_satellite_string" msgid="4796300252858292593">"模擬流動網絡供應商衛星模式 (僅限偵錯版本)"</string>
+    <!-- no translation found for esos_satellite_string (7274794226125968657) -->
+    <skip />
     <string name="radioInfo_menu_viewADN" msgid="4533179730908559846">"查看 SIM 卡通訊錄"</string>
     <string name="radioInfo_menu_viewFDN" msgid="1847236480527032061">"查看固定撥號"</string>
     <string name="radioInfo_menu_viewSDN" msgid="2613431584522392842">"查看服務撥號"</string>
diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml
index b4727d7..9b46329 100644
--- a/res/values-zh-rTW/strings.xml
+++ b/res/values-zh-rTW/strings.xml
@@ -845,6 +845,8 @@
     <string name="radio_info_radio_power" msgid="8805595022160471587">"行動無線電電源"</string>
     <string name="simulate_out_of_service_string" msgid="7787925611727597193">"模擬無法使用服務的情況 (僅限偵錯版本)"</string>
     <string name="mock_carrier_roaming_satellite_string" msgid="4796300252858292593">"模擬電信業者衛星模式 (僅限偵錯版本)"</string>
+    <!-- no translation found for esos_satellite_string (7274794226125968657) -->
+    <skip />
     <string name="radioInfo_menu_viewADN" msgid="4533179730908559846">"查看 SIM 通訊錄"</string>
     <string name="radioInfo_menu_viewFDN" msgid="1847236480527032061">"查看固定撥號"</string>
     <string name="radioInfo_menu_viewSDN" msgid="2613431584522392842">"查看服務撥號號碼"</string>
diff --git a/res/values-zu/strings.xml b/res/values-zu/strings.xml
index e648619..be41d8c 100644
--- a/res/values-zu/strings.xml
+++ b/res/values-zu/strings.xml
@@ -845,6 +845,8 @@
     <string name="radio_info_radio_power" msgid="8805595022160471587">"Amandla erediyo yeselula"</string>
     <string name="simulate_out_of_service_string" msgid="7787925611727597193">"Lingisa okuthi Ayikho Isevisi (Umakhiwo Wokususa Iphutha kuphela)"</string>
     <string name="mock_carrier_roaming_satellite_string" msgid="4796300252858292593">"Imodi Yesethelayithi Yenkampani Yenethiwekhi ye-Mock (Susa Iphutha Esakhiweni kuphela)"</string>
+    <!-- no translation found for esos_satellite_string (7274794226125968657) -->
+    <skip />
     <string name="radioInfo_menu_viewADN" msgid="4533179730908559846">"Buka incwadi yekheli le-SIM"</string>
     <string name="radioInfo_menu_viewFDN" msgid="1847236480527032061">"Buka Izinombolo Zokudayela Okungaguquki"</string>
     <string name="radioInfo_menu_viewSDN" msgid="2613431584522392842">"Buka Izinombolo Zokudayela Isevisi"</string>
diff --git a/res/values/config.xml b/res/values/config.xml
index a934398..cdef37e 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -358,8 +358,36 @@
         <item>us</item>
     </string-array>
 
+    <!-- Array of countries that GERAN is preferred than UTRAN and EUTRAN when SIM is absent.
+         Values should be ISO3166 country codes in lowercase. -->
+    <string-array name="config_countries_prefer_geran_when_sim_absent"
+            translatable="false">
+        <!-- b/335537430 -->
+        <item>cn</item>
+    </string-array>
+
+    <!-- Dynamic routing of emergency calls: trying normal routing if it's available.
+         Otherwise, emergency routing. -->
+    <!-- TODO (b/346398725: temporary code, cleanup) -->
+    <bool name="dynamic_routing_emergency_enabled">false</bool>
+
+    <!-- Array of countries that the dynamic routing is supported.
+         Values should be ISO3166 country codes in lowercase. -->
+    <string-array name="config_countries_dynamic_routing_emergency_enabled"
+            translatable="false">
+    </string-array>
+
+    <!-- Array of emergency numbers for dynamic routing.
+         Values are the tuples of Country ISO, MNC, and numbers. -->
+    <string-array name="config_dynamic_routing_emergency_numbers"
+            translatable="false">
+    </string-array>
+
     <!-- The component name(a flattened ComponentName string) for the telephony domain selection
          service. The device should fallback to the modem based domain selection architecture
          if this is not configured. -->
     <string name="config_domain_selection_service_component_name" translatable="false"></string>
+
+    <!-- Whether to turn off OEM-enabled satellite during emergency call -->
+    <bool name="config_turn_off_oem_enabled_satellite_during_emergency_call">false</bool>
 </resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index f2511d1..87e7095 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -2030,6 +2030,8 @@
 
     <!-- Title for simulating SIM capable of satellite. -->
     <string name="mock_carrier_roaming_satellite_string">Mock Carrier Satellite Mode (Debug Build only)</string>
+    <!-- Title for trigger real satellite eSOS. -->
+    <string name="esos_satellite_string">Test real satellite eSOS mode (Debug Build only)</string>
 
     <!-- Phone Info screen. Menu item label.  Used for diagnostic info screens, precise translation isn't needed -->
     <string name="radioInfo_menu_viewADN">View SIM Address Book</string>
diff --git a/src/com/android/phone/PhoneGlobals.java b/src/com/android/phone/PhoneGlobals.java
index 4e077e9..d0d92c6 100644
--- a/src/com/android/phone/PhoneGlobals.java
+++ b/src/com/android/phone/PhoneGlobals.java
@@ -84,6 +84,7 @@
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.phone.settings.SettingsConstants;
 import com.android.phone.vvm.CarrierVvmPackageInstalledReceiver;
+import com.android.services.telephony.domainselection.DynamicRoutingController;
 import com.android.services.telephony.rcs.TelephonyRcsService;
 
 import java.io.FileDescriptor;
@@ -518,7 +519,9 @@
 
         ContentResolver resolver = getContentResolver();
 
-        if (mFeatureFlags.enforceTelephonyFeatureMappingForPublicApis()) {
+        if (mFeatureFlags.enforceTelephonyFeatureMappingForPublicApis()
+                && !getResources().getBoolean(
+                    com.android.internal.R.bool.config_force_phone_globals_creation)) {
             if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
                 Log.v(LOG_TAG, "onCreate()... but not defined FEATURE_TELEPHONY");
                 return;
@@ -564,6 +567,7 @@
                 boolean isSuplDdsSwitchRequiredForEmergencyCall = getResources()
                         .getBoolean(R.bool.config_gnss_supl_requires_default_data_for_emergency);
                 EmergencyStateTracker.make(this, isSuplDdsSwitchRequiredForEmergencyCall);
+                DynamicRoutingController.getInstance().initialize(this);
             }
 
             // Only bring up ImsResolver if the device supports having an IMS stack.
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index d7eb4b8..dc4290d 100644
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -2731,6 +2731,10 @@
 
         // For async handler to identify request type
         private static final int SUPPLY_PIN_COMPLETE = 100;
+        private static final int SUPPLY_PIN_DELAYED  = 101;
+        private static final int SUPPLY_PIN_DELAYED_TIMER_IN_MILLIS = 10000;
+        private static final UUID SUPPLY_PIN_UUID = UUID.fromString(
+                "d3768135-4323-491d-a6c8-bda01fc89040");
 
         UnlockSim(int phoneId, IccCard simCard) {
             mPhoneId = phoneId;
@@ -2769,9 +2773,17 @@
                                         mResult = PhoneConstants.PIN_RESULT_SUCCESS;
                                     }
                                     mDone = true;
+                                    removeMessages(SUPPLY_PIN_DELAYED);
                                     UnlockSim.this.notifyAll();
                                 }
                                 break;
+                            case SUPPLY_PIN_DELAYED:
+                                if(!mDone) {
+                                    String logStr = "Delay in receiving SIM PIN response ";
+                                    if (DBG) log(logStr);
+                                    AnomalyReporter.reportAnomaly(SUPPLY_PIN_UUID, logStr);
+                                }
+                                break;
                         }
                     }
                 };
@@ -2810,6 +2822,8 @@
             while (!mDone) {
                 try {
                     Log.d(LOG_TAG, "wait for done");
+                    mHandler.sendEmptyMessageDelayed(SUPPLY_PIN_DELAYED,
+                            SUPPLY_PIN_DELAYED_TIMER_IN_MILLIS);
                     wait();
                 } catch (InterruptedException e) {
                     // Restore the interrupted status
@@ -3948,6 +3962,15 @@
         mApp.enforceCallingOrSelfPermission(permission.SATELLITE_COMMUNICATION, message);
     }
 
+    /**
+     * Make sure the caller has PACKAGE_USAGE_STATS permission.
+     * @param message - log message to print.
+     * @throws SecurityException if the caller does not have the required permission
+     */
+    private void enforcePackageUsageStatsPermission(String message) {
+        mApp.enforceCallingOrSelfPermission(permission.PACKAGE_USAGE_STATS, message);
+    }
+
     private String createTelUrl(String number) {
         if (TextUtils.isEmpty(number)) {
             return null;
@@ -9431,7 +9454,11 @@
                     + android.Manifest.permission.DUMP);
             return;
         }
-        DumpsysHandler.dump(mApp, fd, writer, args);
+        try {
+            DumpsysHandler.dump(mApp, fd, writer, args);
+        } catch (Exception e) {
+            writer.println("Failed to dump phone information: " + e);
+        }
     }
 
     @Override
@@ -13758,6 +13785,26 @@
     }
 
     /**
+     * This API can be used by only CTS to override the boolean configs used by the
+     * DatagramController module.
+     *
+     * @param enable Whether to enable or disable boolean config.
+     * @return {@code true} if the boolean config is set successfully, {@code false} otherwise.
+     */
+    public boolean setDatagramControllerBooleanConfig(
+            boolean reset, int booleanType, boolean enable) {
+        Log.d(LOG_TAG, "setDatagramControllerBooleanConfig: booleanType=" + booleanType
+                + ", reset=" + reset + ", enable=" + enable);
+        TelephonyPermissions.enforceShellOnly(
+                Binder.getCallingUid(), "setDatagramControllerBooleanConfig");
+        TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
+                SubscriptionManager.INVALID_SUBSCRIPTION_ID,
+                "ssetDatagramControllerBooleanConfig");
+        return mSatelliteController.setDatagramControllerBooleanConfig(reset, booleanType, enable);
+    }
+
+
+    /**
      * This API can be used by only CTS to override the timeout durations used by the
      * SatelliteController module.
      *
@@ -13896,6 +13943,32 @@
     }
 
     /**
+     * This API can be used by only CTS to set the cache whether satellite communication is allowed.
+     *
+     * @param state a state indicates whether satellite access allowed state should be cached and
+     * the allowed state.
+     * @return {@code true} if the setting is successful, {@code false} otherwise.
+     */
+    public boolean setIsSatelliteCommunicationAllowedForCurrentLocationCache(String state) {
+        if (!mFeatureFlags.oemEnabledSatelliteFlag()) {
+            Log.d(LOG_TAG, "setIsSatelliteCommunicationAllowedForCurrentLocationCache: "
+                    + "oemEnabledSatelliteFlag is disabled");
+            return false;
+        }
+
+        Log.d(LOG_TAG, "setIsSatelliteCommunicationAllowedForCurrentLocationCache: "
+                + "state=" + state);
+        TelephonyPermissions.enforceShellOnly(
+                Binder.getCallingUid(),
+                "setIsSatelliteCommunicationAllowedForCurrentLocationCache");
+        TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
+                SubscriptionManager.INVALID_SUBSCRIPTION_ID,
+                "setIsSatelliteCommunicationAllowedForCurrentLocationCache");
+        return mSatelliteAccessController.setIsSatelliteCommunicationAllowedForCurrentLocationCache(
+                state);
+    }
+
+    /**
      * Sets the service defined in ComponentName to be bound.
      *
      * This should only be used for testing.
@@ -14180,4 +14253,20 @@
         enforceSatelliteCommunicationPermission("unregisterForCommunicationAllowedStateChanged");
         mSatelliteAccessController.unregisterForCommunicationAllowedStateChanged(subId, callback);
     }
+
+    /**
+     * Request to get the {@link SatelliteSessionStats} of the satellite service.
+     *
+     * @param subId The subId of the subscription to the satellite session stats for.
+     * @param result The result receiver that returns the {@link SatelliteSessionStats}
+     *               if the request is successful or an error code if the request failed.
+     *
+     * @throws SecurityException if the caller doesn't have required permission.
+     */
+    @Override
+    public void requestSatelliteSessionStats(int subId, @NonNull ResultReceiver result) {
+        enforceModifyPermission();
+        enforcePackageUsageStatsPermission("requestSatelliteSessionStats");
+        mSatelliteController.requestSatelliteSessionStats(subId, result);
+    }
 }
diff --git a/src/com/android/phone/TelephonyShellCommand.java b/src/com/android/phone/TelephonyShellCommand.java
index 80304b2..6969275 100644
--- a/src/com/android/phone/TelephonyShellCommand.java
+++ b/src/com/android/phone/TelephonyShellCommand.java
@@ -193,6 +193,8 @@
             "set-satellite-pointing-ui-class-name";
     private static final String SET_DATAGRAM_CONTROLLER_TIMEOUT_DURATION =
             "set-datagram-controller-timeout-duration";
+    private static final String SET_DATAGRAM_CONTROLLER_BOOLEAN_CONFIG =
+            "set-datagram-controller-boolean-config";
 
     private static final String SET_SATELLITE_CONTROLLER_TIMEOUT_DURATION =
             "set-satellite-controller-timeout-duration";
@@ -205,6 +207,8 @@
             "set-oem-enabled-satellite-provision-status";
     private static final String SET_SHOULD_SEND_DATAGRAM_TO_MODEM_IN_DEMO_MODE =
             "set-should-send-datagram-to-modem-in-demo-mode";
+    private static final String SET_IS_SATELLITE_COMMUNICATION_ALLOWED_FOR_CURRENT_LOCATION_CACHE =
+            "set-is-satellite-communication-allowed-for-current-location-cache";
 
     private static final String DOMAIN_SELECTION_SUBCOMMAND = "domainselection";
     private static final String DOMAIN_SELECTION_SET_SERVICE_OVERRIDE = "set-dss-override";
@@ -402,6 +406,8 @@
                 return handleSetSatellitePointingUiClassNameCommand();
             case SET_DATAGRAM_CONTROLLER_TIMEOUT_DURATION:
                 return handleSetDatagramControllerTimeoutDuration();
+            case SET_DATAGRAM_CONTROLLER_BOOLEAN_CONFIG:
+                return handleSetDatagramControllerBooleanConfig();
             case SET_SATELLITE_CONTROLLER_TIMEOUT_DURATION:
                 return handleSetSatelliteControllerTimeoutDuration();
             case SET_EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE:
@@ -414,6 +420,8 @@
                 return handleSetCountryCodes();
             case SET_OEM_ENABLED_SATELLITE_PROVISION_STATUS:
                 return handleSetOemEnabledSatelliteProvisionStatus();
+            case SET_IS_SATELLITE_COMMUNICATION_ALLOWED_FOR_CURRENT_LOCATION_CACHE:
+                return handleSetIsSatelliteCommunicationAllowedForCurrentLocationCache();
             default: {
                 return handleDefaultCommands(cmd);
             }
@@ -3416,6 +3424,47 @@
         return 0;
     }
 
+    private int handleSetDatagramControllerBooleanConfig() {
+        PrintWriter errPw = getErrPrintWriter();
+        boolean reset = false;
+        int booleanType = 0;
+        boolean enable = false;
+
+        String opt;
+        while ((opt = getNextOption()) != null) {
+            switch (opt) {
+                case "-d": {
+                    enable = Boolean.parseBoolean(getNextArgRequired());
+                    break;
+                }
+                case "-r": {
+                    reset = true;
+                    break;
+                }
+                case "-t": {
+                    booleanType = Integer.parseInt(getNextArgRequired());
+                    break;
+                }
+            }
+        }
+        Log.d(LOG_TAG, "setDatagramControllerBooleanConfig: enable="
+                + enable + ", reset=" + reset + ", booleanType=" + booleanType);
+
+        try {
+            boolean result = mInterface.setDatagramControllerBooleanConfig(
+                    reset, booleanType, enable);
+            if (VDBG) {
+                Log.v(LOG_TAG, "setDatagramControllerBooleanConfig result = " + result);
+            }
+            getOutPrintWriter().println(result);
+        } catch (RemoteException e) {
+            Log.w(LOG_TAG, "setDatagramControllerBooleanConfig: error = " + e.getMessage());
+            errPw.println("Exception: " + e.getMessage());
+            return -1;
+        }
+        return 0;
+    }
+
     private int handleSetSatelliteControllerTimeoutDuration() {
         PrintWriter errPw = getErrPrintWriter();
         boolean reset = false;
@@ -3654,6 +3703,61 @@
         return 0;
     }
 
+    private int handleSetIsSatelliteCommunicationAllowedForCurrentLocationCache() {
+        PrintWriter errPw = getErrPrintWriter();
+        String opt;
+        String state;
+
+        if ((opt = getNextArg()) == null) {
+            errPw.println(
+                    "adb shell cmd phone set-is-satellite-communication-allowed-for-current"
+                            + "-location-cache :"
+                            + " Invalid Argument");
+            return -1;
+        } else {
+            switch (opt) {
+                case "-a": {
+                    state = "cache_allowed";
+                    break;
+                }
+                case "-n": {
+                    state = "cache_clear_and_not_allowed";
+                    break;
+                }
+                case "-c": {
+                    state = "clear_cache_only";
+                    break;
+                }
+                default:
+                    errPw.println(
+                            "adb shell cmd phone set-is-satellite-communication-allowed-for-current"
+                                    + "-location-cache :"
+                                    + " Invalid Argument");
+                    return -1;
+            }
+        }
+
+        Log.d(LOG_TAG, "handleSetIsSatelliteCommunicationAllowedForCurrentLocationCache("
+                + state + ")");
+
+        try {
+            boolean result = mInterface.setIsSatelliteCommunicationAllowedForCurrentLocationCache(
+                    state);
+            if (VDBG) {
+                Log.v(LOG_TAG, "setIsSatelliteCommunicationAllowedForCurrentLocationCache "
+                        + "returns: "
+                        + result);
+            }
+            getOutPrintWriter().println(result);
+        } catch (RemoteException e) {
+            Log.w(LOG_TAG, "setIsSatelliteCommunicationAllowedForCurrentLocationCache("
+                    + state + "), error = " + e.getMessage());
+            errPw.println("Exception: " + e.getMessage());
+            return -1;
+        }
+        return 0;
+    }
+
     /**
      * Sample inputStr = "US,UK,CA;2,1,3"
      * Sample output: {[US,2], [UK,1], [CA,3]}
diff --git a/src/com/android/phone/satellite/accesscontrol/SatelliteAccessController.java b/src/com/android/phone/satellite/accesscontrol/SatelliteAccessController.java
index ea72acd..b6003a8 100644
--- a/src/com/android/phone/satellite/accesscontrol/SatelliteAccessController.java
+++ b/src/com/android/phone/satellite/accesscontrol/SatelliteAccessController.java
@@ -17,6 +17,7 @@
 package com.android.phone.satellite.accesscontrol;
 
 import static android.telephony.satellite.SatelliteManager.KEY_SATELLITE_COMMUNICATION_ALLOWED;
+import static android.telephony.satellite.SatelliteManager.KEY_SATELLITE_PROVISIONED;
 import static android.telephony.satellite.SatelliteManager.KEY_SATELLITE_SUPPORTED;
 import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED;
 import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_SUCCESS;
@@ -48,12 +49,18 @@
 import android.provider.DeviceConfig;
 import android.telecom.TelecomManager;
 import android.telephony.AnomalyReporter;
+import android.telephony.DropBoxManagerLoggerBackend;
+import android.telephony.PersistentLogger;
 import android.telephony.Rlog;
+import android.telephony.SubscriptionManager;
 import android.telephony.satellite.ISatelliteCommunicationAllowedStateCallback;
+import android.telephony.satellite.ISatelliteProvisionStateCallback;
+import android.telephony.satellite.ISatelliteSupportedStateCallback;
 import android.telephony.satellite.SatelliteManager;
 import android.text.TextUtils;
 import android.util.Pair;
 
+import com.android.internal.R;
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.telephony.Phone;
@@ -61,7 +68,11 @@
 import com.android.internal.telephony.TelephonyCountryDetector;
 import com.android.internal.telephony.flags.FeatureFlags;
 import com.android.internal.telephony.satellite.SatelliteConfig;
+import com.android.internal.telephony.satellite.SatelliteConstants;
 import com.android.internal.telephony.satellite.SatelliteController;
+import com.android.internal.telephony.satellite.metrics.AccessControllerMetricsStats;
+import com.android.internal.telephony.satellite.metrics.ConfigUpdaterMetricsStats;
+import com.android.internal.telephony.satellite.metrics.ControllerMetricsStats;
 import com.android.internal.telephony.util.TelephonyUtils;
 import com.android.phone.PhoneGlobals;
 
@@ -72,6 +83,7 @@
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.StandardCopyOption;
+import java.time.Duration;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
@@ -138,8 +150,18 @@
     @NonNull
     private final SatelliteController mSatelliteController;
     @NonNull
+    private final ControllerMetricsStats mControllerMetricsStats;
+    @NonNull
+    private final AccessControllerMetricsStats mAccessControllerMetricsStats;
+    @NonNull
     private final ResultReceiver mInternalSatelliteSupportedResultReceiver;
     @NonNull
+    private final ResultReceiver mInternalSatelliteProvisionedResultReceiver;
+    @NonNull
+    private final ISatelliteSupportedStateCallback mInternalSatelliteSupportedStateCallback;
+    @NonNull
+    private final ISatelliteProvisionStateCallback mInternalSatelliteProvisionStateCallback;
+    @NonNull
     protected final Object mLock = new Object();
     @GuardedBy("mLock")
     @NonNull
@@ -189,7 +211,11 @@
             "config_updater_satellite_country_codes";
     private static final String CONFIG_UPDATER_SATELLITE_IS_ALLOW_ACCESS_CONTROL_KEY =
             "config_updater_satellite_is_allow_access_control";
+
     private SharedPreferences mSharedPreferences;
+    private final ConfigUpdaterMetricsStats mConfigUpdaterMetricsStats;
+    @Nullable
+    private PersistentLogger mPersistentLogger = null;
 
     /**
      * Map key: binder of the callback, value: callback to receive the satellite communication
@@ -201,6 +227,14 @@
     @GuardedBy("mSatelliteCommunicationAllowStateLock")
     private boolean mCurrentSatelliteAllowedState = false;
 
+    private static final long NANOS_IN_12_HOURS = Duration.ofHours(12).toNanos();
+    private boolean mLatestSatelliteCommunicationAllowed;
+    private long mLatestSatelliteCommunicationAllowedSetTime;
+
+    private long mLocationQueryStartTimeMillis;
+    private long mOnDeviceLookupStartTimeMillis;
+    private long mTotalCheckingStartTimeMillis;
+
     /**
      * Create a SatelliteAccessController instance.
      *
@@ -219,12 +253,18 @@
             @Nullable SatelliteOnDeviceAccessController satelliteOnDeviceAccessController,
             @Nullable File s2CellFile) {
         super(looper);
+        if (isSatellitePersistentLoggingEnabled(context, featureFlags)) {
+            mPersistentLogger = new PersistentLogger(
+                    DropBoxManagerLoggerBackend.getInstance(context));
+        }
         mFeatureFlags = featureFlags;
         mLocationManager = locationManager;
         mTelecomManager = telecomManager;
         mSatelliteOnDeviceAccessController = satelliteOnDeviceAccessController;
         mCountryDetector = TelephonyCountryDetector.getInstance(context);
         mSatelliteController = SatelliteController.getInstance();
+        mControllerMetricsStats = ControllerMetricsStats.getInstance();
+        mAccessControllerMetricsStats = AccessControllerMetricsStats.getInstance();
         initSharedPreferences(context);
         loadOverlayConfigs(context);
         // loadConfigUpdaterConfigs has to be called after loadOverlayConfigs
@@ -241,15 +281,62 @@
                 handleIsSatelliteSupportedResult(resultCode, resultData);
             }
         };
+        mInternalSatelliteProvisionedResultReceiver = new ResultReceiver(this) {
+            @Override
+            protected void onReceiveResult(int resultCode, Bundle resultData) {
+                handleIsSatelliteProvisionedResult(resultCode, resultData);
+            }
+        };
+
+        mConfigUpdaterMetricsStats = ConfigUpdaterMetricsStats.getOrCreateInstance();
+
+        mInternalSatelliteSupportedStateCallback = new ISatelliteSupportedStateCallback.Stub() {
+            @Override
+            public void onSatelliteSupportedStateChanged(boolean isSupported) {
+                logd("onSatelliteSupportedStateChanged: isSupported=" + isSupported);
+                if (isSupported) {
+                    requestIsCommunicationAllowedForCurrentLocation(
+                            SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, new ResultReceiver(null) {
+                                @Override
+                                protected void onReceiveResult(int resultCode, Bundle resultData) {
+                                    // do nothing
+                                }
+                            });
+                }
+            }
+        };
+        mSatelliteController.registerForSatelliteSupportedStateChanged(
+                SubscriptionManager.DEFAULT_SUBSCRIPTION_ID,
+                mInternalSatelliteSupportedStateCallback);
+
+        mInternalSatelliteProvisionStateCallback = new ISatelliteProvisionStateCallback.Stub() {
+            @Override
+            public void onSatelliteProvisionStateChanged(boolean isProvisioned) {
+                logd("onSatelliteProvisionStateChanged: isProvisioned=" + isProvisioned);
+                if (isProvisioned) {
+                    requestIsCommunicationAllowedForCurrentLocation(
+                            SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, new ResultReceiver(null) {
+                                @Override
+                                protected void onReceiveResult(int resultCode, Bundle resultData) {
+                                    // do nothing
+                                }
+                            });
+                }
+            }
+        };
+        mSatelliteController.registerForSatelliteProvisionStateChanged(
+                SubscriptionManager.DEFAULT_SUBSCRIPTION_ID,
+                mInternalSatelliteProvisionStateCallback);
+
         // Init the SatelliteOnDeviceAccessController so that the S2 level can be cached
         initSatelliteOnDeviceAccessController();
     }
 
     private void updateCurrentSatelliteAllowedState(boolean isAllowed) {
-        logd("updateCurrentSatelliteAllowedState");
+        plogd("updateCurrentSatelliteAllowedState");
         synchronized (mSatelliteCommunicationAllowStateLock) {
             if (isAllowed != mCurrentSatelliteAllowedState) {
-                logd("updatedValue = " + isAllowed + " | mCurrentSatelliteAllowedState = "
+                plogd("updatedValue = " + isAllowed + " | mCurrentSatelliteAllowedState = "
                         + mCurrentSatelliteAllowedState);
                 mCurrentSatelliteAllowedState = isAllowed;
                 notifySatelliteCommunicationAllowedStateChanged(isAllowed);
@@ -263,8 +350,10 @@
         if (sInstance == null) {
             HandlerThread handlerThread = new HandlerThread("SatelliteAccessController");
             handlerThread.start();
+            LocationManager lm = context.createAttributionContext("telephony")
+                    .getSystemService(LocationManager.class);
             sInstance = new SatelliteAccessController(context, featureFlags,
-                    handlerThread.getLooper(), context.getSystemService(LocationManager.class),
+                    handlerThread.getLooper(), lm,
                     context.getSystemService(TelecomManager.class), null, null);
         }
         return sInstance;
@@ -288,7 +377,7 @@
                 updateSatelliteConfigData((Context) ar.userObj);
                 break;
             default:
-                logw("SatelliteAccessControllerHandler: unexpected message code: " + msg.what);
+                plogw("SatelliteAccessControllerHandler: unexpected message code: " + msg.what);
                 break;
         }
     }
@@ -305,7 +394,7 @@
     public void requestIsCommunicationAllowedForCurrentLocation(int subId,
             @NonNull ResultReceiver result) {
         if (!mFeatureFlags.oemEnabledSatelliteFlag()) {
-            logd("oemEnabledSatelliteFlag is disabled");
+            plogd("oemEnabledSatelliteFlag is disabled");
             result.send(SATELLITE_RESULT_REQUEST_NOT_SUPPORTED, null);
             return;
         }
@@ -320,10 +409,10 @@
             @Nullable String s2CellFile, long locationFreshDurationNanos,
             @Nullable List<String> satelliteCountryCodes) {
         if (!isMockModemAllowed()) {
-            logd("setSatelliteAccessControllerOverlayConfigs: mock modem is not allowed");
+            plogd("setSatelliteAccessControllerOverlayConfigs: mock modem is not allowed");
             return false;
         }
-        logd("setSatelliteAccessControlOverlayConfigs: reset=" + reset
+        plogd("setSatelliteAccessControlOverlayConfigs: reset=" + reset
                 + ", isAllowed" + isAllowed + ", s2CellFile=" + s2CellFile
                 + ", locationFreshDurationNanos=" + locationFreshDurationNanos
                 + ", satelliteCountryCodes=" + ((satelliteCountryCodes != null)
@@ -338,7 +427,7 @@
                 if (!TextUtils.isEmpty(s2CellFile)) {
                     mOverriddenSatelliteS2CellFile = getTestSatelliteS2File(s2CellFile);
                     if (!mOverriddenSatelliteS2CellFile.exists()) {
-                        logd("The overriding file "
+                        plogd("The overriding file "
                                 + mOverriddenSatelliteS2CellFile.getAbsolutePath()
                                 + " does not exist");
                         mOverriddenSatelliteS2CellFile = null;
@@ -360,13 +449,13 @@
     }
 
     protected File getTestSatelliteS2File(String fileName) {
-        logd("getTestSatelliteS2File: fileName=" + fileName);
+        plogd("getTestSatelliteS2File: fileName=" + fileName);
         if (TextUtils.equals(fileName, GOOGLE_US_SAN_SAT_S2_FILE_NAME)) {
             mCtsSatS2FilePath = copyTestSatS2FileToPhoneDirectory(GOOGLE_US_SAN_SAT_S2_FILE_NAME);
             if (mCtsSatS2FilePath != null) {
                 return mCtsSatS2FilePath.toFile();
             } else {
-                loge("getTestSatelliteS2File: mCtsSatS2FilePath is null");
+                ploge("getTestSatelliteS2File: mCtsSatS2FilePath is null");
             }
         }
         return new File(fileName);
@@ -444,13 +533,13 @@
                     SatelliteOnDeviceAccessController.create(s2CellFile);
             int s2Level = satelliteOnDeviceAccessController.getS2Level();
             if (s2Level < MIN_S2_LEVEL || s2Level > MAX_S2_LEVEL) {
-                loge("isS2CellFileValid: invalid s2 level = " + s2Level);
+                ploge("isS2CellFileValid: invalid s2 level = " + s2Level);
                 satelliteOnDeviceAccessController.close();
                 return false;
             }
             satelliteOnDeviceAccessController.close();
         } catch (Exception ex) {
-            loge("isS2CellFileValid: Got exception in reading the file, ex=" + ex);
+            ploge("isS2CellFileValid: Got exception in reading the file, ex=" + ex);
             return false;
         }
         return true;
@@ -461,7 +550,7 @@
             try {
                 Files.delete(mCtsSatS2FilePath);
             } catch (IOException ex) {
-                loge("cleanUpCtsResources: ex=" + ex);
+                ploge("cleanUpCtsResources: ex=" + ex);
             }
         }
     }
@@ -481,7 +570,7 @@
         }
         for (String countryCode : countryCodes) {
             if (!TelephonyUtils.isValidCountryCode(countryCode)) {
-                loge("invalid country code : " + countryCode);
+                ploge("invalid country code : " + countryCode);
                 return false;
             }
         }
@@ -491,11 +580,11 @@
     private boolean updateSharedPreferencesCountryCodes(
             @NonNull Context context, @NonNull List<String> value) {
         if (mSharedPreferences == null) {
-            logd("updateSharedPreferencesCountryCodes: mSharedPreferences is null");
+            plogd("updateSharedPreferencesCountryCodes: mSharedPreferences is null");
             initSharedPreferences(context);
         }
         if (mSharedPreferences == null) {
-            loge("updateSharedPreferencesCountryCodes: mSharedPreferences is null");
+            ploge("updateSharedPreferencesCountryCodes: mSharedPreferences is null");
             return false;
         }
         try {
@@ -503,7 +592,7 @@
                     CONFIG_UPDATER_SATELLITE_COUNTRY_CODES_KEY, new HashSet<>(value)).apply();
             return true;
         } catch (Exception ex) {
-            loge("updateSharedPreferencesCountryCodes error : " + ex);
+            ploge("updateSharedPreferencesCountryCodes error : " + ex);
             return false;
         }
     }
@@ -511,11 +600,11 @@
     private boolean updateSharedPreferencesIsAllowAccessControl(
             @NonNull Context context, boolean value) {
         if (mSharedPreferences == null) {
-            logd("updateSharedPreferencesIsAllowAccessControl: mSharedPreferences is null");
+            plogd("updateSharedPreferencesIsAllowAccessControl: mSharedPreferences is null");
             initSharedPreferences(context);
         }
         if (mSharedPreferences == null) {
-            loge("updateSharedPreferencesIsAllowAccessControl: mSharedPreferences is null");
+            ploge("updateSharedPreferencesIsAllowAccessControl: mSharedPreferences is null");
             return false;
         }
         try {
@@ -524,7 +613,7 @@
                     value).apply();
             return true;
         } catch (Exception ex) {
-            loge("updateSharedPreferencesAllowRegion : " + ex);
+            ploge("updateSharedPreferencesIsAllowAccessControl error: " + ex);
             return false;
         }
     }
@@ -533,60 +622,76 @@
      * Update country codes and S2CellFile with the new data from ConfigUpdater
      */
     private void updateSatelliteConfigData(Context context) {
-        logd("updateSatelliteConfigData");
+        plogd("updateSatelliteConfigData");
 
         SatelliteConfig satelliteConfig = mSatelliteController.getSatelliteConfig();
         if (satelliteConfig == null) {
-            loge("satelliteConfig is null");
+            ploge("satelliteConfig is null");
+            mConfigUpdaterMetricsStats.reportOemAndCarrierConfigError(
+                    SatelliteConstants.CONFIG_UPDATE_RESULT_NO_SATELLITE_DATA);
             return;
         }
 
         List<String> satelliteCountryCodes = satelliteConfig.getDeviceSatelliteCountryCodes();
         if (!isValidCountryCodes(satelliteCountryCodes)) {
-            logd("country codes is invalid");
+            plogd("country codes is invalid");
+            mConfigUpdaterMetricsStats.reportOemConfigError(
+                    SatelliteConstants.CONFIG_UPDATE_RESULT_DEVICE_DATA_INVALID_COUNTRY_CODE);
             return;
         }
 
         Boolean isSatelliteDataForAllowedRegion = satelliteConfig.isSatelliteDataForAllowedRegion();
         if (isSatelliteDataForAllowedRegion == null) {
-            loge("Satellite allowed is not configured with country codes");
+            ploge("Satellite allowed is not configured with country codes");
+            mConfigUpdaterMetricsStats.reportOemConfigError(
+                    SatelliteConstants.CONFIG_UPDATE_RESULT_DEVICE_DATA_INVALID_S2_CELL_FILE);
             return;
         }
 
         File configUpdaterS2CellFile = satelliteConfig.getSatelliteS2CellFile(context);
         if (configUpdaterS2CellFile == null || !configUpdaterS2CellFile.exists()) {
-            logd("No S2 cell file configured or the file does not exist");
+            plogd("No S2 cell file configured or the file does not exist");
+            mConfigUpdaterMetricsStats.reportOemConfigError(
+                    SatelliteConstants.CONFIG_UPDATE_RESULT_DEVICE_DATA_INVALID_S2_CELL_FILE);
             return;
         }
 
         if (!isS2CellFileValid(configUpdaterS2CellFile)) {
-            loge("The configured S2 cell file is not valid");
+            ploge("The configured S2 cell file is not valid");
+            mConfigUpdaterMetricsStats.reportOemConfigError(
+                    SatelliteConstants.CONFIG_UPDATE_RESULT_DEVICE_DATA_INVALID_S2_CELL_FILE);
             return;
         }
 
         File localS2CellFile = copySatS2FileToLocalDirectory(configUpdaterS2CellFile);
         if (localS2CellFile == null || !localS2CellFile.exists()) {
-            loge("Fail to copy S2 cell file to local directory");
+            ploge("Fail to copy S2 cell file to local directory");
+            mConfigUpdaterMetricsStats.reportOemConfigError(
+                    SatelliteConstants.CONFIG_UPDATE_RESULT_IO_ERROR);
             return;
         }
 
         if (!updateSharedPreferencesCountryCodes(context, satelliteCountryCodes)) {
-            loge("Fail to copy country coeds into shared preferences");
+            ploge("Fail to copy country coeds into shared preferences");
             localS2CellFile.delete();
+            mConfigUpdaterMetricsStats.reportOemConfigError(
+                    SatelliteConstants.CONFIG_UPDATE_RESULT_IO_ERROR);
             return;
         }
 
         if (!updateSharedPreferencesIsAllowAccessControl(
                 context, isSatelliteDataForAllowedRegion.booleanValue())) {
-            loge("Fail to copy allow access control into shared preferences");
+            ploge("Fail to copy allow access control into shared preferences");
             localS2CellFile.delete();
+            mConfigUpdaterMetricsStats.reportOemConfigError(
+                    SatelliteConstants.CONFIG_UPDATE_RESULT_IO_ERROR);
             return;
         }
 
         mSatelliteS2CellFile = localS2CellFile;
         mSatelliteCountryCodes = satelliteCountryCodes;
         mIsSatelliteAllowAccessControl = satelliteConfig.isSatelliteDataForAllowedRegion();
-        logd("Use s2 cell file=" + mSatelliteS2CellFile.getAbsolutePath() + ", country codes="
+        plogd("Use s2 cell file=" + mSatelliteS2CellFile.getAbsolutePath() + ", country codes="
                 + String.join(",", mSatelliteCountryCodes)
                 + ", mIsSatelliteAllowAccessControl=" + mIsSatelliteAllowAccessControl
                 + " from ConfigUpdater");
@@ -596,9 +701,11 @@
 
         // Clean up cached data based on previous geofence data
         synchronized (mLock) {
-            logd("clear mCachedAccessRestrictionMap");
+            plogd("clear mCachedAccessRestrictionMap");
             mCachedAccessRestrictionMap.clear();
         }
+
+        mConfigUpdaterMetricsStats.reportConfigUpdateSuccess();
     }
 
     private void loadOverlayConfigs(@NonNull Context context) {
@@ -608,15 +715,17 @@
         mSatelliteS2CellFile = TextUtils.isEmpty(satelliteS2CellFileName)
                 ? null : new File(satelliteS2CellFileName);
         if (mSatelliteS2CellFile != null && !mSatelliteS2CellFile.exists()) {
-            loge("The satellite S2 cell file " + satelliteS2CellFileName + " does not exist");
+            ploge("The satellite S2 cell file " + satelliteS2CellFileName + " does not exist");
             mSatelliteS2CellFile = null;
         }
         mLocationFreshDurationNanos = getSatelliteLocationFreshDurationFromOverlayConfig(context);
+        mAccessControllerMetricsStats.setConfigDataSource(
+                SatelliteConstants.CONFIG_DATA_SOURCE_DEVICE_CONFIG);
     }
 
     private void loadConfigUpdaterConfigs() {
         if (mSharedPreferences == null) {
-            loge("loadConfigUpdaterConfigs : mSharedPreferences is null");
+            ploge("loadConfigUpdaterConfigs : mSharedPreferences is null");
             return;
         }
 
@@ -624,7 +733,7 @@
                 mSharedPreferences.getStringSet(CONFIG_UPDATER_SATELLITE_COUNTRY_CODES_KEY, null);
 
         if (countryCodes == null || countryCodes.isEmpty()) {
-            loge("config updater country codes are either null or empty");
+            ploge("config updater country codes are either null or empty");
             return;
         }
 
@@ -634,14 +743,16 @@
 
         File s2CellFile = getConfigUpdaterSatS2CellFileFromLocalDirectory();
         if (s2CellFile == null) {
-            loge("s2CellFile is null");
+            ploge("s2CellFile is null");
             return;
         }
 
-        logd("use config updater config data");
+        plogd("use config updater config data");
         mSatelliteS2CellFile = s2CellFile;
         mSatelliteCountryCodes = countryCodes.stream().collect(Collectors.toList());
         mIsSatelliteAllowAccessControl = isSatelliteAllowAccessControl;
+        mAccessControllerMetricsStats.setConfigDataSource(
+                SatelliteConstants.CONFIG_DATA_SOURCE_CONFIG_UPDATER);
     }
 
     private long getLocationFreshDurationNanos() {
@@ -687,46 +798,75 @@
         synchronized (mLock) {
             mSatelliteAllowResultReceivers.add(requestArguments.second);
             if (mSatelliteAllowResultReceivers.size() > 1) {
-                logd("requestIsCommunicationAllowedForCurrentLocation is already being "
+                plogd("requestIsCommunicationAllowedForCurrentLocation is already being "
                         + "processed");
                 return;
             }
+            mTotalCheckingStartTimeMillis = System.currentTimeMillis();
             mSatelliteController.requestIsSatelliteSupported(
                     requestArguments.first, mInternalSatelliteSupportedResultReceiver);
         }
     }
 
     private void handleWaitForCurrentLocationTimedOutEvent() {
-        logd("Timed out to wait for current location");
+        plogd("Timed out to wait for current location");
         synchronized (mLock) {
             if (mLocationRequestCancellationSignal != null) {
                 mLocationRequestCancellationSignal.cancel();
                 mLocationRequestCancellationSignal = null;
                 onCurrentLocationAvailable(null);
             } else {
-                loge("handleWaitForCurrentLocationTimedOutEvent: "
+                ploge("handleWaitForCurrentLocationTimedOutEvent: "
                         + "mLocationRequestCancellationSignal is null");
             }
         }
     }
 
     private void handleIsSatelliteSupportedResult(int resultCode, Bundle resultData) {
-        logd("handleIsSatelliteSupportedResult: resultCode=" + resultCode);
+        plogd("handleIsSatelliteSupportedResult: resultCode=" + resultCode);
         synchronized (mLock) {
             if (resultCode == SATELLITE_RESULT_SUCCESS) {
                 if (resultData.containsKey(KEY_SATELLITE_SUPPORTED)) {
                     boolean isSatelliteSupported = resultData.getBoolean(KEY_SATELLITE_SUPPORTED);
                     if (!isSatelliteSupported) {
-                        logd("Satellite is not supported");
+                        plogd("Satellite is not supported");
                         Bundle bundle = new Bundle();
                         bundle.putBoolean(SatelliteManager.KEY_SATELLITE_COMMUNICATION_ALLOWED,
                                 false);
                         sendSatelliteAllowResultToReceivers(resultCode, bundle, false);
                     } else {
-                        checkSatelliteAccessRestrictionForCurrentLocation();
+                        plogd("Satellite is supported");
+                        checkSatelliteAccessRestrictionUsingGPS();
                     }
                 } else {
-                    loge("KEY_SATELLITE_SUPPORTED does not exist.");
+                    ploge("KEY_SATELLITE_SUPPORTED does not exist.");
+                    sendSatelliteAllowResultToReceivers(resultCode, resultData, false);
+                }
+            } else {
+                sendSatelliteAllowResultToReceivers(resultCode, resultData, false);
+            }
+        }
+    }
+
+    private void handleIsSatelliteProvisionedResult(int resultCode, Bundle resultData) {
+        plogd("handleIsSatelliteProvisionedResult: resultCode=" + resultCode);
+        synchronized (mLock) {
+            if (resultCode == SATELLITE_RESULT_SUCCESS) {
+                if (resultData.containsKey(KEY_SATELLITE_PROVISIONED)) {
+                    boolean isSatelliteProvisioned =
+                            resultData.getBoolean(KEY_SATELLITE_PROVISIONED);
+                    if (!isSatelliteProvisioned) {
+                        plogd("Satellite is not provisioned");
+                        Bundle bundle = new Bundle();
+                        bundle.putBoolean(SatelliteManager.KEY_SATELLITE_COMMUNICATION_ALLOWED,
+                                false);
+                        sendSatelliteAllowResultToReceivers(resultCode, bundle, false);
+                    } else {
+                        plogd("Satellite is provisioned");
+                        checkSatelliteAccessRestrictionUsingGPS();
+                    }
+                } else {
+                    ploge("KEY_SATELLITE_PROVISIONED does not exist.");
                     sendSatelliteAllowResultToReceivers(resultCode, resultData, false);
                 }
             } else {
@@ -744,6 +884,7 @@
             }
             mSatelliteAllowResultReceivers.clear();
         }
+        reportMetrics(resultCode, allowed);
     }
 
     /**
@@ -753,12 +894,16 @@
         synchronized (mLock) {
             List<String> networkCountryIsoList = mCountryDetector.getCurrentNetworkCountryIso();
             if (!networkCountryIsoList.isEmpty()) {
-                logd("Use current network country codes=" + String.join(", ",
+                plogd("Use current network country codes=" + String.join(", ",
                         networkCountryIsoList));
 
                 boolean allowed = isSatelliteAccessAllowedForLocation(networkCountryIsoList);
                 Bundle bundle = new Bundle();
                 bundle.putBoolean(KEY_SATELLITE_COMMUNICATION_ALLOWED, allowed);
+                mAccessControllerMetricsStats
+                        .setAccessControlType(
+                                SatelliteConstants.ACCESS_CONTROL_TYPE_NETWORK_COUNTRY_CODE)
+                        .setCountryCodes(networkCountryIsoList);
                 sendSatelliteAllowResultToReceivers(SATELLITE_RESULT_SUCCESS, bundle, allowed);
             } else {
                 if (shouldUseOnDeviceAccessController()) {
@@ -774,6 +919,55 @@
     }
 
     /**
+     * Telephony-internal logic to verify if satellite access is restricted from the location query.
+     */
+    private void checkSatelliteAccessRestrictionUsingGPS() {
+        logv("checkSatelliteAccessRestrictionUsingGPS:");
+        if (isInEmergency()) {
+            executeLocationQuery();
+        } else {
+            if (mLocationManager.isLocationEnabled()) {
+                plogd("location query is allowed");
+                if (isCommunicationAllowedCacheValid()) {
+                    Bundle bundle = new Bundle();
+                    bundle.putBoolean(KEY_SATELLITE_COMMUNICATION_ALLOWED,
+                            mLatestSatelliteCommunicationAllowed);
+                    sendSatelliteAllowResultToReceivers(SATELLITE_RESULT_SUCCESS, bundle,
+                            mLatestSatelliteCommunicationAllowed);
+                } else {
+                    executeLocationQuery();
+                }
+            } else {
+                plogv("location query is not allowed");
+                Bundle bundle = new Bundle();
+                bundle.putBoolean(KEY_SATELLITE_COMMUNICATION_ALLOWED, false);
+                sendSatelliteAllowResultToReceivers(SATELLITE_RESULT_SUCCESS, bundle, false);
+            }
+        }
+    }
+
+    /* returns true,if the latest query was executed in 24Hr, or returns false. */
+    private boolean isCommunicationAllowedCacheValid() {
+        if (mLatestSatelliteCommunicationAllowedSetTime > 0) {
+            long currentTime = SystemClock.elapsedRealtimeNanos();
+            if ((currentTime - mLatestSatelliteCommunicationAllowedSetTime) <= NANOS_IN_12_HOURS) {
+                logv("isCommunicationAllowedCacheValid: cache is valid");
+                return true;
+            }
+        }
+        logv("isCommunicationAllowedCacheValid: cache is expired");
+        return false;
+    }
+
+    private void executeLocationQuery() {
+        plogv("executeLocationQuery");
+        synchronized (mLock) {
+            mFreshLastKnownLocation = getFreshLastKnownLocation();
+            checkSatelliteAccessRestrictionUsingOnDeviceData();
+        }
+    }
+
+    /**
      * This function synchronously checks if satellite is allowed at current location using cached
      * country codes.
      */
@@ -794,7 +988,9 @@
             // Use cached network country codes
             countryCodeList = networkCountryCodeInfoMap.keySet().stream().toList();
         }
-        logd("Use cached country codes=" + String.join(", ", countryCodeList));
+        plogd("Use cached country codes=" + String.join(", ", countryCodeList));
+        mAccessControllerMetricsStats.setAccessControlType(
+                SatelliteConstants.ACCESS_CONTROL_TYPE_CACHED_COUNTRY_CODE);
 
         boolean allowed = isSatelliteAccessAllowedForLocation(countryCodeList);
         Bundle bundle = new Bundle();
@@ -808,14 +1004,19 @@
      * from location service.
      */
     private void checkSatelliteAccessRestrictionUsingOnDeviceData() {
+        mOnDeviceLookupStartTimeMillis = System.currentTimeMillis();
         synchronized (mLock) {
-            logd("Use on-device data");
+            plogd("Use on-device data");
             if (mFreshLastKnownLocation != null) {
+                mAccessControllerMetricsStats.setAccessControlType(
+                        SatelliteConstants.ACCESS_CONTROL_TYPE_LAST_KNOWN_LOCATION);
                 checkSatelliteAccessRestrictionForLocation(mFreshLastKnownLocation);
                 mFreshLastKnownLocation = null;
             } else {
                 Location freshLastKnownLocation = getFreshLastKnownLocation();
                 if (freshLastKnownLocation != null) {
+                    mAccessControllerMetricsStats.setAccessControlType(
+                            SatelliteConstants.ACCESS_CONTROL_TYPE_LAST_KNOWN_LOCATION);
                     checkSatelliteAccessRestrictionForLocation(freshLastKnownLocation);
                 } else {
                     queryCurrentLocation();
@@ -827,10 +1028,11 @@
     private void queryCurrentLocation() {
         synchronized (mLock) {
             if (mLocationRequestCancellationSignal != null) {
-                logd("Request for current location was already sent to LocationManager");
+                plogd("Request for current location was already sent to LocationManager");
                 return;
             }
             mLocationRequestCancellationSignal = new CancellationSignal();
+            mLocationQueryStartTimeMillis = System.currentTimeMillis();
             mLocationManager.getCurrentLocation(LocationManager.GPS_PROVIDER,
                     new LocationRequest.Builder(0)
                             .setQuality(LocationRequest.QUALITY_HIGH_ACCURACY)
@@ -843,14 +1045,34 @@
     }
 
     private void onCurrentLocationAvailable(@Nullable Location location) {
-        logd("onCurrentLocationAvailable " + (location != null));
+        plogd("onCurrentLocationAvailable " + (location != null));
         synchronized (mLock) {
             stopWaitForCurrentLocationTimer();
             mLocationRequestCancellationSignal = null;
+            mAccessControllerMetricsStats.setLocationQueryTime(mLocationQueryStartTimeMillis);
+            Bundle bundle = new Bundle();
             if (location != null) {
+                if (location.isMock() && !isMockModemAllowed()) {
+                    logd("location is mock");
+                    bundle.putBoolean(KEY_SATELLITE_COMMUNICATION_ALLOWED, false);
+                    sendSatelliteAllowResultToReceivers(SATELLITE_RESULT_SUCCESS, bundle, false);
+                    return;
+                }
+                mAccessControllerMetricsStats.setAccessControlType(
+                        SatelliteConstants.ACCESS_CONTROL_TYPE_CURRENT_LOCATION);
                 checkSatelliteAccessRestrictionForLocation(location);
             } else {
-                checkSatelliteAccessRestrictionUsingCachedCountryCodes();
+                plogd("current location is not available");
+                if (isCommunicationAllowedCacheValid()) {
+                    plogd("onCurrentLocationAvailable: 24Hr cache is still valid, using it");
+                    bundle.putBoolean(KEY_SATELLITE_COMMUNICATION_ALLOWED,
+                            mLatestSatelliteCommunicationAllowed);
+                    sendSatelliteAllowResultToReceivers(SATELLITE_RESULT_SUCCESS, bundle,
+                            mLatestSatelliteCommunicationAllowed);
+                } else {
+                    bundle.putBoolean(KEY_SATELLITE_COMMUNICATION_ALLOWED, false);
+                    sendSatelliteAllowResultToReceivers(SATELLITE_RESULT_SUCCESS, bundle, false);
+                }
             }
         }
     }
@@ -867,23 +1089,39 @@
                     satelliteAllowed = mCachedAccessRestrictionMap.get(locationToken);
                 } else {
                     if (!initSatelliteOnDeviceAccessController()) {
-                        loge("Failed to init SatelliteOnDeviceAccessController");
-                        checkSatelliteAccessRestrictionUsingCachedCountryCodes();
+                        ploge("Failed to init SatelliteOnDeviceAccessController");
+                        Bundle bundle = new Bundle();
+                        bundle.putBoolean(KEY_SATELLITE_COMMUNICATION_ALLOWED, false);
+                        sendSatelliteAllowResultToReceivers(SATELLITE_RESULT_SUCCESS, bundle,
+                                false);
                         return;
                     }
                     satelliteAllowed = mSatelliteOnDeviceAccessController
                             .isSatCommunicationAllowedAtLocation(locationToken);
                     updateCachedAccessRestrictionMap(locationToken, satelliteAllowed);
                 }
+                mAccessControllerMetricsStats.setOnDeviceLookupTime(mOnDeviceLookupStartTimeMillis);
                 Bundle bundle = new Bundle();
                 bundle.putBoolean(KEY_SATELLITE_COMMUNICATION_ALLOWED, satelliteAllowed);
                 sendSatelliteAllowResultToReceivers(SATELLITE_RESULT_SUCCESS, bundle,
                         satelliteAllowed);
+                mLatestSatelliteCommunicationAllowed = satelliteAllowed;
+                mLatestSatelliteCommunicationAllowedSetTime = SystemClock.elapsedRealtimeNanos();
             } catch (Exception ex) {
-                loge("checkSatelliteAccessRestrictionForLocation: ex=" + ex);
+                ploge("checkSatelliteAccessRestrictionForLocation: ex=" + ex);
                 reportAnomaly(UUID_ON_DEVICE_LOOKUP_EXCEPTION,
                         "On-device satellite lookup exception");
-                checkSatelliteAccessRestrictionUsingCachedCountryCodes();
+                Bundle bundle = new Bundle();
+                if (isCommunicationAllowedCacheValid()) {
+                    bundle.putBoolean(KEY_SATELLITE_COMMUNICATION_ALLOWED,
+                            mLatestSatelliteCommunicationAllowed);
+                    plogd("checkSatelliteAccessRestrictionForLocation: 24Hr cache is still valid, "
+                            + "using it");
+                } else {
+                    bundle.putBoolean(KEY_SATELLITE_COMMUNICATION_ALLOWED, false);
+                }
+                sendSatelliteAllowResultToReceivers(SATELLITE_RESULT_SUCCESS, bundle,
+                        mLatestSatelliteCommunicationAllowed);
             }
         }
     }
@@ -997,7 +1235,12 @@
                 result = location;
             }
         }
-        return result;
+
+        if (result == null || isMockModemAllowed()) {
+            return result;
+        }
+
+        return result.isMock() ? null : result;
     }
 
     private void initSharedPreferences(@NonNull Context context) {
@@ -1005,7 +1248,7 @@
             mSharedPreferences =
                     context.getSharedPreferences(SATELLITE_SHARED_PREF, Context.MODE_PRIVATE);
         } catch (Exception e) {
-            loge("Cannot get default shared preferences: " + e);
+            ploge("Cannot get default shared preferences: " + e);
         }
     }
 
@@ -1031,9 +1274,9 @@
                         SatelliteOnDeviceAccessController.create(getSatelliteS2CellFile());
                 restartKeepOnDeviceAccessControllerResourcesTimer();
                 mS2Level = mSatelliteOnDeviceAccessController.getS2Level();
-                logd("mS2Level=" + mS2Level);
+                plogd("mS2Level=" + mS2Level);
             } catch (Exception ex) {
-                loge("Got exception in creating an instance of SatelliteOnDeviceAccessController,"
+                ploge("Got exception in creating an instance of SatelliteOnDeviceAccessController,"
                         + " ex=" + ex + ", sat s2 file="
                         + getSatelliteS2CellFile().getAbsolutePath());
                 reportAnomaly(UUID_CREATE_ON_DEVICE_ACCESS_CONTROLLER_EXCEPTION,
@@ -1050,13 +1293,13 @@
 
     private void cleanupOnDeviceAccessControllerResources() {
         synchronized (mLock) {
-            logd("cleanupOnDeviceAccessControllerResources="
+            plogd("cleanupOnDeviceAccessControllerResources="
                     + (mSatelliteOnDeviceAccessController != null));
             if (mSatelliteOnDeviceAccessController != null) {
                 try {
                     mSatelliteOnDeviceAccessController.close();
                 } catch (Exception ex) {
-                    loge("cleanupOnDeviceAccessControllerResources: ex=" + ex);
+                    ploge("cleanupOnDeviceAccessControllerResources: ex=" + ex);
                 }
                 mSatelliteOnDeviceAccessController = null;
                 stopKeepOnDeviceAccessControllerResourcesTimer();
@@ -1163,7 +1406,7 @@
     private void startWaitForCurrentLocationTimer() {
         synchronized (mLock) {
             if (hasMessages(EVENT_WAIT_FOR_CURRENT_LOCATION_TIMEOUT)) {
-                logw("WaitForCurrentLocationTimer is already started");
+                plogw("WaitForCurrentLocationTimer is already started");
                 removeMessages(EVENT_WAIT_FOR_CURRENT_LOCATION_TIMEOUT);
             }
             sendEmptyMessageDelayed(EVENT_WAIT_FOR_CURRENT_LOCATION_TIMEOUT,
@@ -1180,7 +1423,7 @@
     private void restartKeepOnDeviceAccessControllerResourcesTimer() {
         synchronized (mLock) {
             if (hasMessages(EVENT_KEEP_ON_DEVICE_ACCESS_CONTROLLER_RESOURCES_TIMEOUT)) {
-                logd("KeepOnDeviceAccessControllerResourcesTimer is already started. "
+                plogd("KeepOnDeviceAccessControllerResourcesTimer is already started. "
                         + "Restarting it...");
                 removeMessages(EVENT_KEEP_ON_DEVICE_ACCESS_CONTROLLER_RESOURCES_TIMEOUT);
             }
@@ -1196,7 +1439,7 @@
     }
 
     private void reportAnomaly(@NonNull String uuid, @NonNull String log) {
-        loge(log);
+        ploge(log);
         AnomalyReporter.reportAnomaly(UUID.fromString(uuid), log);
     }
 
@@ -1229,7 +1472,7 @@
     public int registerForCommunicationAllowedStateChanged(int subId,
             @NonNull ISatelliteCommunicationAllowedStateCallback callback) {
         if (!mFeatureFlags.oemEnabledSatelliteFlag()) {
-            logd("registerForCommunicationAllowedStateChanged: oemEnabledSatelliteFlag is "
+            plogd("registerForCommunicationAllowedStateChanged: oemEnabledSatelliteFlag is "
                     + "disabled");
             return SatelliteManager.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED;
         }
@@ -1251,7 +1494,7 @@
     public void unregisterForCommunicationAllowedStateChanged(
             int subId, @NonNull ISatelliteCommunicationAllowedStateCallback callback) {
         if (!mFeatureFlags.oemEnabledSatelliteFlag()) {
-            logd("unregisterForCommunicationAllowedStateChanged: "
+            plogd("unregisterForCommunicationAllowedStateChanged: "
                     + "oemEnabledSatelliteFlag is disabled");
             return;
         }
@@ -1259,15 +1502,58 @@
         mSatelliteCommunicationAllowedStateChangedListeners.remove(callback.asBinder());
     }
 
+    /**
+     * This API can be used by only CTS to set the cache whether satellite communication is allowed.
+     *
+     * @param state a state indicates whether satellite access allowed state should be cached and
+     * the allowed state.
+     * @return {@code true} if the setting is successful, {@code false} otherwise.
+     */
+    public boolean setIsSatelliteCommunicationAllowedForCurrentLocationCache(String state) {
+        if (!mFeatureFlags.oemEnabledSatelliteFlag()) {
+            logd("setIsSatelliteCommunicationAllowedForCurrentLocationCache: "
+                    + "oemEnabledSatelliteFlag is disabled");
+            return false;
+        }
+
+        if (!isMockModemAllowed()) {
+            logd("setIsSatelliteCommunicationAllowedForCurrentLocationCache: "
+                    + "mock modem not allowed.");
+            return false;
+        }
+
+        logd("setIsSatelliteCommunicationAllowedForCurrentLocationCache: state=" + state);
+
+        synchronized (mSatelliteCommunicationAllowStateLock) {
+            if ("cache_allowed".equalsIgnoreCase(state)) {
+                mLatestSatelliteCommunicationAllowedSetTime = SystemClock.elapsedRealtimeNanos();
+                mLatestSatelliteCommunicationAllowed = true;
+                mCurrentSatelliteAllowedState = true;
+            } else if ("cache_clear_and_not_allowed".equalsIgnoreCase(state)) {
+                mLatestSatelliteCommunicationAllowedSetTime = 0;
+                mLatestSatelliteCommunicationAllowed = false;
+                mCurrentSatelliteAllowedState = false;
+            } else if ("clear_cache_only".equalsIgnoreCase(state)) {
+                mLatestSatelliteCommunicationAllowedSetTime = 0;
+                mLatestSatelliteCommunicationAllowed = false;
+            } else {
+                loge("setIsSatelliteCommunicationAllowedForCurrentLocationCache: invalid state="
+                        + state);
+                return false;
+            }
+        }
+        return true;
+    }
+
     private void notifySatelliteCommunicationAllowedStateChanged(boolean allowState) {
-        logd("notifySatelliteCommunicationAllowedStateChanged: allowState=" + allowState);
+        plogd("notifySatelliteCommunicationAllowedStateChanged: allowState=" + allowState);
 
         List<ISatelliteCommunicationAllowedStateCallback> deadCallersList = new ArrayList<>();
         mSatelliteCommunicationAllowedStateChangedListeners.values().forEach(listener -> {
             try {
                 listener.onSatelliteCommunicationAllowedStateChanged(allowState);
             } catch (RemoteException e) {
-                logd("handleEventNtnSignalStrengthChanged RemoteException: " + e);
+                plogd("handleEventNtnSignalStrengthChanged RemoteException: " + e);
                 deadCallersList.add(listener);
             }
         });
@@ -1276,6 +1562,25 @@
         });
     }
 
+    private void reportMetrics(int resultCode, boolean allowed) {
+        if (resultCode == SATELLITE_RESULT_SUCCESS) {
+            mControllerMetricsStats.reportAllowedSatelliteAccessCount(allowed);
+        } else {
+            mControllerMetricsStats.reportFailedSatelliteAccessCheckCount();
+        }
+
+        mAccessControllerMetricsStats
+                .setLocationQueryTime(mLocationQueryStartTimeMillis)
+                .setTotalCheckingTime(mTotalCheckingStartTimeMillis)
+                .setIsAllowed(allowed)
+                .setIsEmergency(isInEmergency())
+                .setResult(resultCode)
+                .reportAccessControllerMetrics();
+        mLocationQueryStartTimeMillis = 0;
+        mOnDeviceLookupStartTimeMillis = 0;
+        mTotalCheckingStartTimeMillis = 0;
+    }
+
     private static void logd(@NonNull String log) {
         Rlog.d(TAG, log);
     }
@@ -1287,4 +1592,49 @@
     private static void loge(@NonNull String log) {
         Rlog.e(TAG, log);
     }
+
+    private static void logv(@NonNull String log) {
+        Rlog.v(TAG, log);
+    }
+
+    private boolean isSatellitePersistentLoggingEnabled(
+            @NonNull Context context, @NonNull FeatureFlags featureFlags) {
+        if (featureFlags.satellitePersistentLogging()) {
+            return true;
+        }
+        try {
+            return context.getResources().getBoolean(
+                    R.bool.config_dropboxmanager_persistent_logging_enabled);
+        } catch (RuntimeException e) {
+            return false;
+        }
+    }
+
+    private void plogv(@NonNull String log) {
+        Rlog.v(TAG, log);
+        if (mPersistentLogger != null) {
+            mPersistentLogger.debug(TAG, log);
+        }
+    }
+
+    private void plogd(@NonNull String log) {
+        Rlog.d(TAG, log);
+        if (mPersistentLogger != null) {
+            mPersistentLogger.debug(TAG, log);
+        }
+    }
+
+    private void plogw(@NonNull String log) {
+        Rlog.w(TAG, log);
+        if (mPersistentLogger != null) {
+            mPersistentLogger.warn(TAG, log);
+        }
+    }
+
+    private void ploge(@NonNull String log) {
+        Rlog.e(TAG, log);
+        if (mPersistentLogger != null) {
+            mPersistentLogger.error(TAG, log);
+        }
+    }
 }
diff --git a/src/com/android/phone/satellite/entitlement/SatelliteEntitlementController.java b/src/com/android/phone/satellite/entitlement/SatelliteEntitlementController.java
index 8c2693b..307d1e6 100644
--- a/src/com/android/phone/satellite/entitlement/SatelliteEntitlementController.java
+++ b/src/com/android/phone/satellite/entitlement/SatelliteEntitlementController.java
@@ -16,8 +16,6 @@
 
 package com.android.phone.satellite.entitlement;
 
-import static com.android.phone.satellite.entitlement.SatelliteEntitlementResult.SATELLITE_ENTITLEMENT_STATUS_ENABLED;
-
 import static java.time.format.DateTimeFormatter.RFC_1123_DATE_TIME;
 import static java.time.temporal.ChronoUnit.SECONDS;
 
@@ -44,7 +42,9 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.telephony.ExponentialBackoff;
 import com.android.internal.telephony.flags.FeatureFlags;
+import com.android.internal.telephony.satellite.SatelliteConstants;
 import com.android.internal.telephony.satellite.SatelliteController;
+import com.android.internal.telephony.satellite.metrics.EntitlementMetricsStats;
 import com.android.internal.telephony.subscription.SubscriptionManagerService;
 import com.android.libraries.entitlement.ServiceEntitlementException;
 
@@ -67,6 +67,7 @@
     /** Message code used in handleMessage() */
     private static final int CMD_START_QUERY_ENTITLEMENT = 1;
     private static final int CMD_RETRY_QUERY_ENTITLEMENT = 2;
+    private static final int CMD_SIM_REFRESH = 3;
 
     /** Retry on next trigger event. */
     private static final int HTTP_RESPONSE_500 = 500;
@@ -109,6 +110,7 @@
     /** Map key : slotId, value : The last used subId. */
     @GuardedBy("mLock")
     private Map<Integer, Integer> mSubIdPerSlot = new HashMap<>();
+    @NonNull private final EntitlementMetricsStats mEntitlementMetricsStats;
 
     /**
      * Create the SatelliteEntitlementController singleton instance.
@@ -159,6 +161,8 @@
         IntentFilter intentFilter = new IntentFilter();
         intentFilter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);
         context.registerReceiver(mReceiver, intentFilter);
+        mEntitlementMetricsStats = EntitlementMetricsStats.getOrCreateInstance();
+        SatelliteController.getInstance().registerIccRefresh(this, CMD_SIM_REFRESH);
     }
 
     @Override
@@ -170,6 +174,9 @@
             case CMD_RETRY_QUERY_ENTITLEMENT:
                 handleCmdRetryQueryEntitlement(msg.arg1);
                 break;
+            case CMD_SIM_REFRESH:
+                handleSimRefresh();
+                break;
             default:
                 logd("do not used this message");
         }
@@ -225,6 +232,12 @@
         }
     }
 
+    private void handleSimRefresh() {
+        resetEntitlementQueryCounts(cmdToString(CMD_SIM_REFRESH));
+        sendMessageDelayed(obtainMessage(CMD_START_QUERY_ENTITLEMENT),
+                TimeUnit.SECONDS.toMillis(10));
+    }
+
     private boolean isInternetConnected() {
         Network activeNetwork = mConnectivityManager.getActiveNetwork();
         NetworkCapabilities networkCapabilities =
@@ -255,11 +268,15 @@
             try {
                 synchronized (mLock) {
                     mIsEntitlementInProgressPerSub.put(subId, true);
-                    mSatelliteEntitlementResultPerSub.put(subId, getSatelliteEntitlementApi(
-                            subId).checkEntitlementStatus());
+                    SatelliteEntitlementResult entitlementResult =  getSatelliteEntitlementApi(
+                            subId).checkEntitlementStatus();
+                    mSatelliteEntitlementResultPerSub.put(subId, entitlementResult);
+                    mEntitlementMetricsStats.reportSuccess(subId,
+                            getEntitlementStatus(entitlementResult), false);
                 }
             } catch (ServiceEntitlementException e) {
                 loge(e.toString());
+                mEntitlementMetricsStats.reportError(subId, e.getErrorCode(), false);
                 if (!isInternetConnected()) {
                     logd("StartQuery: disconnected. " + e);
                     synchronized (mLock) {
@@ -319,11 +336,15 @@
                 int currentRetryCount = getRetryCount(subId);
                 mRetryCountPerSub.put(subId, currentRetryCount + 1);
                 logd("[" + subId + "] retry cnt:" + getRetryCount(subId));
-                mSatelliteEntitlementResultPerSub.put(subId, getSatelliteEntitlementApi(
-                        subId).checkEntitlementStatus());
+                SatelliteEntitlementResult entitlementResult =  getSatelliteEntitlementApi(
+                        subId).checkEntitlementStatus();
+                mSatelliteEntitlementResultPerSub.put(subId, entitlementResult);
+                mEntitlementMetricsStats.reportSuccess(subId,
+                        getEntitlementStatus(entitlementResult), true);
             }
         } catch (ServiceEntitlementException e) {
             loge(e.toString());
+            mEntitlementMetricsStats.reportError(subId, e.getErrorCode(), true);
             if (!isRetryAvailable(subId)) {
                 logd("retryQuery: unavailable.");
                 queryCompleted(subId);
@@ -464,8 +485,8 @@
         sendMessageDelayed(message, TimeUnit.DAYS.toMillis(
                 getSatelliteEntitlementStatusRefreshDays(subId)));
         logd("queryCompleted: updateSatelliteEntitlementStatus");
-        updateSatelliteEntitlementStatus(subId,
-                entitlementResult.getEntitlementStatus() == SATELLITE_ENTITLEMENT_STATUS_ENABLED,
+        updateSatelliteEntitlementStatus(subId, entitlementResult.getEntitlementStatus() ==
+                        SatelliteEntitlementResult.SATELLITE_ENTITLEMENT_STATUS_ENABLED,
                 entitlementResult.getAllowedPLMNList(), entitlementResult.getBarredPLMNList());
     }
 
@@ -511,12 +532,13 @@
     private void resetSatelliteEntitlementRestrictedReason(int subId) {
         SatelliteEntitlementResult previousResult;
         SatelliteEntitlementResult enabledResult = new SatelliteEntitlementResult(
-                SATELLITE_ENTITLEMENT_STATUS_ENABLED, new ArrayList<>(), new ArrayList<>());
+                SatelliteEntitlementResult.SATELLITE_ENTITLEMENT_STATUS_ENABLED,
+                new ArrayList<>(), new ArrayList<>());
         synchronized (mLock) {
             previousResult = mSatelliteEntitlementResultPerSub.get(subId);
         }
         if (previousResult != null && previousResult.getEntitlementStatus()
-                != SATELLITE_ENTITLEMENT_STATUS_ENABLED) {
+                != SatelliteEntitlementResult.SATELLITE_ENTITLEMENT_STATUS_ENABLED) {
             logd("set enabled status for removing satellite entitlement restricted reason");
             synchronized (mLock) {
                 mSatelliteEntitlementResultPerSub.put(subId, enabledResult);
@@ -633,6 +655,31 @@
                 plmnAllowedList, plmnBarredList, null);
     }
 
+    private @SatelliteConstants.SatelliteEntitlementStatus int getEntitlementStatus(
+            SatelliteEntitlementResult entitlementResult) {
+        switch (entitlementResult.getEntitlementStatus()) {
+            case SatelliteEntitlementResult.SATELLITE_ENTITLEMENT_STATUS_DISABLED:
+                return SatelliteConstants.SATELLITE_ENTITLEMENT_STATUS_DISABLED;
+            case SatelliteEntitlementResult.SATELLITE_ENTITLEMENT_STATUS_ENABLED:
+                return SatelliteConstants.SATELLITE_ENTITLEMENT_STATUS_ENABLED;
+            case SatelliteEntitlementResult.SATELLITE_ENTITLEMENT_STATUS_INCOMPATIBLE:
+                return SatelliteConstants.SATELLITE_ENTITLEMENT_STATUS_INCOMPATIBLE;
+            case SatelliteEntitlementResult.SATELLITE_ENTITLEMENT_STATUS_PROVISIONING:
+                return SatelliteConstants.SATELLITE_ENTITLEMENT_STATUS_PROVISIONING;
+            default:
+                return SatelliteConstants.SATELLITE_ENTITLEMENT_STATUS_UNKNOWN;
+        }
+    }
+
+    private static String cmdToString(int cmd) {
+        switch (cmd) {
+            case CMD_SIM_REFRESH:
+                return "SIM_REFRESH";
+            default:
+                return "UNKNOWN(" + cmd + ")";
+        }
+    }
+
     private static void logd(String log) {
         Rlog.d(TAG, log);
     }
diff --git a/src/com/android/phone/settings/RadioInfo.java b/src/com/android/phone/settings/RadioInfo.java
index a153090..c59f92a 100644
--- a/src/com/android/phone/settings/RadioInfo.java
+++ b/src/com/android/phone/settings/RadioInfo.java
@@ -132,6 +132,9 @@
 
     private static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
 
+    private static final String ACTION_ESOS_TEST =
+            "com.google.android.apps.stargate.ACTION_ESOS_QUESTIONNAIRE";
+
     private static final String[] PREFERRED_NETWORK_LABELS = {
             "GSM/WCDMA preferred",
             "GSM only",
@@ -308,6 +311,7 @@
     private Button mOemInfoButton;
     private Button mCarrierProvisioningButton;
     private Button mTriggerCarrierProvisioningButton;
+    private Button mEsosButton;
     private Switch mImsVolteProvisionedSwitch;
     private Switch mImsVtProvisionedSwitch;
     private Switch mImsWfcProvisionedSwitch;
@@ -738,6 +742,17 @@
             mTriggerCarrierProvisioningButton.setEnabled(false);
         }
 
+        mEsosButton = (Button) findViewById(R.id.esos_questionnaire);
+        if (!TelephonyUtils.IS_DEBUGGABLE) {
+            mEsosButton.setVisibility(View.GONE);
+        } else {
+            mEsosButton.setOnClickListener(v ->
+                    mPhone.getContext().startActivity(
+                        new Intent(ACTION_ESOS_TEST)
+                        .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK))
+            );
+        }
+
         mOemInfoButton = (Button) findViewById(R.id.oem_info);
         mOemInfoButton.setOnClickListener(mOemInfoButtonHandler);
         PackageManager pm = getPackageManager();
@@ -1462,15 +1477,18 @@
         mQueuedWork.execute(new Runnable() {
             @Override
             public void run() {
-                if (!mEuiccManager.isEnabled()) {
-                    mEuiccInfoResult = "Not enabled";
-                }
-                try {
-                    mEuiccInfoResult = " { Available memory in bytes:"
-                            + mEuiccManager.getAvailableMemoryInBytes()
-                            + " }";
-                } catch (Exception e) {
-                    mEuiccInfoResult = e.getMessage();
+                if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY_EUICC)) {
+                    mEuiccInfoResult = "Euicc Feature is disabled";
+                } else if (mEuiccManager == null || !mEuiccManager.isEnabled()) {
+                    mEuiccInfoResult = "EuiccManager is not enabled";
+                } else {
+                    try {
+                        mEuiccInfoResult = " { Available memory in bytes:"
+                                + mEuiccManager.getAvailableMemoryInBytes()
+                                + " }";
+                    } catch (Exception e) {
+                        mEuiccInfoResult = e.getMessage();
+                    }
                 }
                 mHandler.post(setEuiccInfo);
             }
diff --git a/src/com/android/services/telephony/TelephonyConnection.java b/src/com/android/services/telephony/TelephonyConnection.java
index 5bfad6b..3dbae8e 100644
--- a/src/com/android/services/telephony/TelephonyConnection.java
+++ b/src/com/android/services/telephony/TelephonyConnection.java
@@ -962,6 +962,7 @@
             new ConcurrentHashMap<TelephonyConnectionListener, Boolean>(8, 0.9f, 1));
 
     private Integer mEmergencyServiceCategory = null;
+    private List<String> mEmergencyUrns = null;
 
     protected TelephonyConnection(com.android.internal.telephony.Connection originalConnection,
             String callId, int callDirection) {
@@ -2505,6 +2506,7 @@
                                     if (numberInfo != null) {
                                         mEmergencyServiceCategory =
                                                 numberInfo.getEmergencyServiceCategoryBitmask();
+                                        mEmergencyUrns = numberInfo.getEmergencyUrns();
                                     } else {
                                         Log.i(this, "mEmergencyServiceCategory no EmergencyNumber");
                                     }
@@ -2513,6 +2515,9 @@
                                         Log.i(this, "mEmergencyServiceCategory="
                                                 + mEmergencyServiceCategory);
                                     }
+                                    if (mEmergencyUrns != null) {
+                                        Log.i(this, "mEmergencyUrns=" + mEmergencyUrns);
+                                    }
                                 }
                             }
                         }
@@ -3930,4 +3935,21 @@
     public void setEmergencyServiceCategory(int eccCategory) {
         mEmergencyServiceCategory = eccCategory;
     }
+
+    /**
+     * @return a {@link List} of {@link String}s that are the emrgency URNs.
+     */
+    public @Nullable List<String> getEmergencyUrns() {
+        return mEmergencyUrns;
+    }
+
+    /**
+     * Set the emergency URNs.
+     *
+     * @param emergencyUrns The emergency URNs.
+     */
+    @VisibleForTesting
+    public void setEmergencyUrns(@Nullable List<String> emergencyUrns) {
+        mEmergencyUrns = emergencyUrns;
+    }
 }
diff --git a/src/com/android/services/telephony/TelephonyConnectionService.java b/src/com/android/services/telephony/TelephonyConnectionService.java
index 2a7a2f2..51c4fc7 100644
--- a/src/com/android/services/telephony/TelephonyConnectionService.java
+++ b/src/com/android/services/telephony/TelephonyConnectionService.java
@@ -34,6 +34,7 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.pm.PackageManager;
+import android.content.res.Resources;
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.ParcelUuid;
@@ -104,6 +105,7 @@
 import com.android.phone.R;
 import com.android.phone.callcomposer.CallComposerPictureManager;
 import com.android.phone.settings.SuppServicesUiUtil;
+import com.android.services.telephony.domainselection.DynamicRoutingController;
 
 import java.lang.ref.WeakReference;
 import java.util.ArrayList;
@@ -232,10 +234,12 @@
     public Pair<WeakReference<TelephonyConnection>, Queue<Phone>> mEmergencyRetryCache;
     private DeviceState mDeviceState = new DeviceState();
     private EmergencyStateTracker mEmergencyStateTracker;
+    private DynamicRoutingController mDynamicRoutingController;
     private SatelliteSOSMessageRecommender mSatelliteSOSMessageRecommender;
     private DomainSelectionResolver mDomainSelectionResolver;
     private EmergencyCallDomainSelectionConnection mEmergencyCallDomainSelectionConnection;
     private TelephonyConnection mEmergencyConnection;
+    private TelephonyConnection mAlternateEmergencyConnection;
     private TelephonyConnection mNormalRoutingEmergencyConnection;
     private Executor mDomainSelectionMainExecutor;
     private ImsManager mImsManager = null;
@@ -1164,13 +1168,31 @@
         boolean needToTurnOnRadio = (isEmergencyNumber && (!isRadioOn() || isAirplaneModeOn))
                 || (isRadioPowerDownOnBluetooth() && !isPhoneWifiCallingEnabled);
 
+        if (mSatelliteController.isSatelliteEnabled()) {
+            Log.d(this, "onCreateOutgoingConnection, "
+                    + " needToTurnOnRadio=" + needToTurnOnRadio
+                    + " needToTurnOffSatellite=" + needToTurnOffSatellite
+                    + " isEmergencyNumber=" + isEmergencyNumber);
+
+            if (!needToTurnOffSatellite) {
+                // Block outgoing call and do not turn off satellite
+                Log.d(this, "onCreateOutgoingConnection, "
+                        + "cannot make call in satellite mode.");
+                return Connection.createFailedConnection(
+                        mDisconnectCauseFactory.toTelecomDisconnectCause(
+                                android.telephony.DisconnectCause.SATELLITE_ENABLED,
+                                DISCONNECT_REASON_SATELLITE_ENABLED));
+            }
+        }
+
         if (mDomainSelectionResolver.isDomainSelectionSupported()) {
             // Normal routing emergency number shall be handled by normal call domain selctor.
-            if (isEmergencyNumber && !isNormalRouting(phone, number)) {
+            int routing = getEmergencyCallRouting(phone, number, needToTurnOnRadio);
+            if (isEmergencyNumber && routing != EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL) {
                 final Connection resultConnection =
                         placeEmergencyConnection(phone,
                                 request, numberToDial, isTestEmergencyNumber,
-                                handle, needToTurnOnRadio);
+                                handle, needToTurnOnRadio, routing);
                 if (resultConnection != null) return resultConnection;
             }
         }
@@ -1186,6 +1208,11 @@
 
             if (isEmergencyNumber) {
                 mIsEmergencyCallPending = true;
+                if (mDomainSelectionResolver.isDomainSelectionSupported()) {
+                    if (resultConnection instanceof TelephonyConnection) {
+                        setNormalRoutingEmergencyConnection((TelephonyConnection)resultConnection);
+                    }
+                }
             }
             int timeoutToOnTimeoutCallback = mDomainSelectionResolver.isDomainSelectionSupported()
                     ? TIMEOUT_TO_DYNAMIC_ROUTING_MS : 0;
@@ -1271,14 +1298,7 @@
             }
 
             if (!isEmergencyNumber) {
-                if (mSatelliteController.isSatelliteEnabled()) {
-                    Log.d(this, "onCreateOutgoingConnection, cannot make call in "
-                            + "satellite mode.");
-                    return Connection.createFailedConnection(
-                            mDisconnectCauseFactory.toTelecomDisconnectCause(
-                                    android.telephony.DisconnectCause.SATELLITE_ENABLED,
-                                    DISCONNECT_REASON_SATELLITE_ENABLED));
-                } else if (isCallDisallowedDueToSatellite(phone)
+                if (isCallDisallowedDueToSatellite(phone)
                         && (imsPhone == null || !imsPhone.canMakeWifiCall())) {
                     Log.d(this, "onCreateOutgoingConnection, cannot make call "
                             + "when device is connected to carrier roaming satellite network");
@@ -1321,6 +1341,12 @@
                 final Connection resultConnection = getTelephonyConnection(request, numberToDial,
                         true, handle, phone);
 
+                if (mDomainSelectionResolver.isDomainSelectionSupported()) {
+                    if (resultConnection instanceof TelephonyConnection) {
+                        setNormalRoutingEmergencyConnection((TelephonyConnection)resultConnection);
+                    }
+                }
+
                 CompletableFuture<Void> maybeHoldFuture =
                         checkAndHoldCallsOnOtherSubsForEmergencyCall(request,
                                 resultConnection, phone);
@@ -2102,11 +2128,20 @@
     }
 
     private boolean isSatelliteBlockingCall(boolean isEmergencyNumber) {
-        if (isEmergencyNumber) {
-            return mSatelliteController.isSatelliteEnabled();
-        } else {
-            return mSatelliteController.isDemoModeEnabled();
+        if (!mSatelliteController.isSatelliteEnabled()) {
+            return false;
         }
+
+        if (isEmergencyNumber) {
+            if (mSatelliteController.isDemoModeEnabled()) {
+                // If user makes emergency call in demo mode, end the satellite session
+                return true;
+            } else {
+                return getTurnOffOemEnabledSatelliteDuringEmergencyCall();
+            }
+        }
+
+        return false;
     }
 
     private Pair<WeakReference<TelephonyConnection>, Queue<Phone>> makeCachedConnectionPhonePair(
@@ -2182,7 +2217,7 @@
                 updatePhoneAccount(c, newPhoneToUse);
             }
             if (mDomainSelectionResolver.isDomainSelectionSupported()) {
-                onEmergencyRedial(c, newPhoneToUse);
+                onEmergencyRedial(c, newPhoneToUse, false);
                 return;
             }
             placeOutgoingConnection(c, newPhoneToUse, videoState, connExtras);
@@ -2279,11 +2314,21 @@
                         }
                     }
                     if (mDomainSelectionResolver.isDomainSelectionSupported()) {
-                        if (isNormalRouting(phone, number)) {
-                            /** Normal routing emergency number shall be handled
-                             * by normal call domain selctor.*/
+                        mIsEmergencyCallPending = false;
+                        if (connection == mNormalRoutingEmergencyConnection) {
+                            if (getEmergencyCallRouting(phone, number, false)
+                                    != EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL) {
+                                Log.i(this, "placeOutgoingConnection dynamic routing");
+                                // A normal routing number is dialed when airplane mode is enabled,
+                                // but normal service is not acquired.
+                                setNormalRoutingEmergencyConnection(null);
+                                mAlternateEmergencyConnection = connection;
+                                onEmergencyRedial(connection, phone, true);
+                                return;
+                            }
+                            /* Normal routing emergency number shall be handled
+                             * by normal call domain selector.*/
                             Log.i(this, "placeOutgoingConnection normal routing number");
-                            mNormalRoutingEmergencyConnection = connection;
                             mEmergencyStateTracker.startNormalRoutingEmergencyCall(
                                     phone, connection, result -> {
                                         Log.i(this, "placeOutgoingConnection normal routing number:"
@@ -2564,7 +2609,7 @@
     private Connection placeEmergencyConnection(
             final Phone phone, final ConnectionRequest request,
             final String numberToDial, final boolean isTestEmergencyNumber,
-            final Uri handle, final boolean needToTurnOnRadio) {
+            final Uri handle, final boolean needToTurnOnRadio, int routing) {
 
         final Connection resultConnection =
                 getTelephonyConnection(request, numberToDial, true, handle, phone);
@@ -2574,6 +2619,9 @@
 
             mIsEmergencyCallPending = true;
             mEmergencyConnection = (TelephonyConnection) resultConnection;
+            if (routing == EmergencyNumber.EMERGENCY_CALL_ROUTING_EMERGENCY) {
+                mAlternateEmergencyConnection = (TelephonyConnection) resultConnection;
+            }
             handleEmergencyCallStartedForSatelliteSOSMessageRecommender(mEmergencyConnection,
                     phone);
         }
@@ -2622,6 +2670,7 @@
                             mEmergencyStateTracker.getEmergencyRegistrationResult());
                 } else {
                     mEmergencyConnection = null;
+                    mAlternateEmergencyConnection = null;
                     String reason = "Couldn't setup emergency call";
                     if (result == android.telephony.DisconnectCause.POWER_OFF) {
                         reason = "Failed to turn on radio.";
@@ -2683,6 +2732,9 @@
             }
             Bundle extras = request.getExtras();
             extras.putInt(PhoneConstants.EXTRA_DIAL_DOMAIN, result);
+            if (resultConnection == mAlternateEmergencyConnection) {
+                extras.putBoolean(PhoneConstants.EXTRA_USE_EMERGENCY_ROUTING, true);
+            }
             CompletableFuture<Void> rejectFuture = checkAndRejectIncomingCall(phone, (ret) -> {
                 if (!ret) {
                     Log.i(this, "createEmergencyConnection reject incoming call failed");
@@ -2743,6 +2795,7 @@
             mEmergencyCallDomainSelectionConnection = null;
         }
         mIsEmergencyCallPending = false;
+        mAlternateEmergencyConnection = null;
         if (!isActive) {
             mEmergencyConnection = null;
         }
@@ -2782,13 +2835,15 @@
             int extraCode = reasonInfo.getExtraCode();
             if ((reasonCode == ImsReasonInfo.CODE_SIP_ALTERNATE_EMERGENCY_CALL)
                     || (reasonCode == ImsReasonInfo.CODE_LOCAL_CALL_CS_RETRY_REQUIRED
-                            && extraCode == ImsReasonInfo.EXTRA_CODE_CALL_RETRY_EMERGENCY)) {
+                            && extraCode == ImsReasonInfo.EXTRA_CODE_CALL_RETRY_EMERGENCY
+                            && mNormalRoutingEmergencyConnection != c)) {
                 // clear normal call domain selector
                 c.removeTelephonyConnectionListener(mNormalCallConnectionListener);
                 clearNormalCallDomainSelectionConnection();
                 mNormalCallConnection = null;
 
-                onEmergencyRedial(c, c.getPhone().getDefaultPhone());
+                mAlternateEmergencyConnection = c;
+                onEmergencyRedial(c, c.getPhone().getDefaultPhone(), false);
                 return true;
             }
         }
@@ -2866,6 +2921,23 @@
         return true;
     }
 
+    private int getEmergencyCallRouting(Phone phone, String number, boolean needToTurnOnRadio) {
+        // This method shall be called only if AOSP domain selection is enabled.
+        if (mDynamicRoutingController == null) {
+            mDynamicRoutingController = DynamicRoutingController.getInstance();
+        }
+        if (mDynamicRoutingController.isDynamicRoutingEnabled()) {
+            return mDynamicRoutingController.getEmergencyCallRouting(phone, number,
+                    isNormalRoutingNumber(phone, number),
+                    isEmergencyNumberAllowedOnDialedSim(phone, number),
+                    needToTurnOnRadio);
+        }
+
+        return isNormalRouting(phone, number)
+                ? EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL
+                : EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN;
+    }
+
     private boolean isNormalRouting(Phone phone, String number) {
         // Check isEmergencyNumberAllowedOnDialedSim(): some carriers do not want to handle
         // dial requests for numbers which are in the emergency number list on another SIM,
@@ -3020,6 +3092,17 @@
 
         final Bundle extras = new Bundle();
         extras.putInt(PhoneConstants.EXTRA_DIAL_DOMAIN, domain);
+        if (connection == mAlternateEmergencyConnection) {
+            extras.putBoolean(PhoneConstants.EXTRA_USE_EMERGENCY_ROUTING, true);
+            if (connection.getEmergencyServiceCategory() != null) {
+                extras.putInt(PhoneConstants.EXTRA_EMERGENCY_SERVICE_CATEGORY,
+                        connection.getEmergencyServiceCategory());
+            }
+            if (connection.getEmergencyUrns() != null) {
+                extras.putStringArrayList(PhoneConstants.EXTRA_EMERGENCY_URNS,
+                        new ArrayList<>(connection.getEmergencyUrns()));
+            }
+        }
 
         CompletableFuture<Void> future = checkAndRejectIncomingCall(phone, (ret) -> {
             if (!ret) {
@@ -3088,8 +3171,10 @@
     }
 
     @SuppressWarnings("FutureReturnValueIgnored")
-    private void onEmergencyRedial(final TelephonyConnection c, final Phone phone) {
-        Log.i(this, "onEmergencyRedial phoneId=" + phone.getPhoneId());
+    private void onEmergencyRedial(final TelephonyConnection c, final Phone phone,
+            boolean airplaneMode) {
+        Log.i(this, "onEmergencyRedial phoneId=" + phone.getPhoneId()
+                + ", ariplaneMode=" + airplaneMode);
 
         final String number = c.getAddress().getSchemeSpecificPart();
         final boolean isTestEmergencyNumber = isEmergencyNumberTestNumber(number);
@@ -3131,7 +3216,7 @@
                 DomainSelectionService.SelectionAttributes attr =
                         EmergencyCallDomainSelectionConnection.getSelectionAttributes(
                                 phone.getPhoneId(),
-                                phone.getSubId(), false,
+                                phone.getSubId(), airplaneMode,
                                 c.getTelecomCallId(),
                                 c.getAddress().getSchemeSpecificPart(), isTestEmergencyNumber,
                                 0, null, mEmergencyStateTracker.getEmergencyRegistrationResult());
@@ -3147,6 +3232,7 @@
                 }, mDomainSelectionMainExecutor);
             } else {
                 mEmergencyConnection = null;
+                mAlternateEmergencyConnection = null;
                 c.setTelephonyConnectionDisconnected(
                         mDisconnectCauseFactory.toTelecomDisconnectCause(result, "unknown error"));
                 c.close();
@@ -4683,4 +4769,15 @@
         // Call is disallowed while using satellite
         return true;
     }
+
+    private boolean getTurnOffOemEnabledSatelliteDuringEmergencyCall() {
+        boolean turnOffSatellite = false;
+        try {
+            turnOffSatellite = getApplicationContext().getResources().getBoolean(
+                    R.bool.config_turn_off_oem_enabled_satellite_during_emergency_call);
+        } catch (Resources.NotFoundException ex) {
+            Log.e(this, ex, "getTurnOffOemEnabledSatelliteDuringEmergencyCall: ex=" + ex);
+        }
+        return turnOffSatellite;
+    }
 }
diff --git a/src/com/android/services/telephony/domainselection/DynamicRoutingController.java b/src/com/android/services/telephony/domainselection/DynamicRoutingController.java
new file mode 100644
index 0000000..2690847
--- /dev/null
+++ b/src/com/android/services/telephony/domainselection/DynamicRoutingController.java
@@ -0,0 +1,389 @@
+/*
+ * Copyright (C) 2024 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.services.telephony.domainselection;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.res.Resources;
+import android.os.SystemProperties;
+import android.telephony.PhoneNumberUtils;
+import android.telephony.ServiceState;
+import android.telephony.TelephonyManager;
+import android.telephony.emergency.EmergencyNumber;
+import android.text.TextUtils;
+import android.util.ArrayMap;
+import android.util.Log;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.telephony.LocaleTracker;
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneConstants;
+import com.android.internal.telephony.PhoneFactory;
+import com.android.internal.telephony.ServiceStateTracker;
+import com.android.phone.R;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Manages dynamic routing of emergency numbers.
+ *
+ * Normal routing shall be tried if noraml service is available.
+ * Otherwise, emergency routing shall be tried.
+ */
+public class DynamicRoutingController {
+    private static final String TAG = "DynamicRoutingController";
+    private static final boolean DBG = (SystemProperties.getInt("ro.debuggable", 0) == 1);
+
+    private static final DynamicRoutingController sInstance =
+            new DynamicRoutingController();
+
+    /** PhoneFactory Dependencies for testing. */
+    @VisibleForTesting
+    public interface PhoneFactoryProxy {
+        Phone getPhone(int phoneId);
+    }
+
+    private static class PhoneFactoryProxyImpl implements PhoneFactoryProxy {
+        @Override
+        public Phone getPhone(int phoneId) {
+            return PhoneFactory.getPhone(phoneId);
+        }
+    }
+
+    private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (intent.getAction().equals(
+                    TelephonyManager.ACTION_NETWORK_COUNTRY_CHANGED)) {
+                int phoneId = intent.getIntExtra(PhoneConstants.PHONE_KEY, -1);
+                String countryIso = intent.getStringExtra(
+                        TelephonyManager.EXTRA_NETWORK_COUNTRY);
+                Log.i(TAG, "ACTION_NETWORK_COUNTRY_CHANGED phoneId: " + phoneId
+                        + " countryIso: " + countryIso);
+                if (TextUtils.isEmpty(countryIso)) {
+                    countryIso = getLastKnownCountryIso(phoneId);
+                    if (TextUtils.isEmpty(countryIso)) {
+                        return;
+                    }
+                }
+                String prevIso = mNetworkCountries.get(Integer.valueOf(phoneId));
+                if (!TextUtils.equals(prevIso, countryIso)) {
+                    mNetworkCountries.put(Integer.valueOf(phoneId), countryIso);
+                    updateDynamicEmergencyNumbers(phoneId);
+                }
+                mLastCountryIso = countryIso;
+            }
+        }
+    };
+
+    private String getLastKnownCountryIso(int phoneId) {
+        try {
+            Phone phone = mPhoneFactoryProxy.getPhone(phoneId);
+            if (phone == null) return "";
+
+            ServiceStateTracker sst = phone.getServiceStateTracker();
+            if (sst == null) return "";
+
+            LocaleTracker lt = sst.getLocaleTracker();
+            if (lt != null) {
+                String iso = lt.getLastKnownCountryIso();
+                Log.e(TAG, "getLastKnownCountryIso iso=" + iso);
+                return iso;
+            }
+        } catch (Exception e) {
+            Log.e(TAG, "getLastKnownCountryIso e=" + e);
+        }
+        return "";
+    }
+
+    private final PhoneFactoryProxy mPhoneFactoryProxy;
+    private final ArrayMap<Integer, String> mNetworkCountries = new ArrayMap<>();
+    private final ArrayMap<Integer, List<EmergencyNumber>> mEmergencyNumbers = new ArrayMap<>();
+
+    private String mLastCountryIso;
+    private boolean mEnabled;
+    private List<String> mCountriesEnabled = null;
+    private List<String> mDynamicNumbers = null;
+
+
+    /**
+     * Returns the singleton instance of DynamicRoutingController.
+     *
+     * @return A {@link DynamicRoutingController} instance.
+     */
+    public static DynamicRoutingController getInstance() {
+        return sInstance;
+    }
+
+    private DynamicRoutingController() {
+          this(new PhoneFactoryProxyImpl());
+    }
+
+    @VisibleForTesting
+    public DynamicRoutingController(PhoneFactoryProxy phoneFactoryProxy) {
+        mPhoneFactoryProxy = phoneFactoryProxy;
+    }
+
+    /**
+     * Initializes the instance.
+     *
+     * @param context The context of the application.
+     */
+    public void initialize(Context context) {
+        try {
+            mEnabled = context.getResources().getBoolean(R.bool.dynamic_routing_emergency_enabled);
+        } catch (Resources.NotFoundException nfe) {
+            Log.e(TAG, "init exception=" + nfe);
+        } catch (NullPointerException npe) {
+            Log.e(TAG, "init exception=" + npe);
+        }
+
+        mCountriesEnabled = readResourceConfiguration(context,
+                R.array.config_countries_dynamic_routing_emergency_enabled);
+
+        mDynamicNumbers = readResourceConfiguration(context,
+                R.array.config_dynamic_routing_emergency_numbers);
+
+        Log.i(TAG, "init enabled=" + mEnabled + ", countriesEnabled=" + mCountriesEnabled);
+
+        if (mEnabled) {
+            //register country change listener
+            IntentFilter filter = new IntentFilter(TelephonyManager.ACTION_NETWORK_COUNTRY_CHANGED);
+            context.registerReceiver(mIntentReceiver, filter);
+        }
+    }
+
+    private List<String> readResourceConfiguration(Context context, int id) {
+        Log.i(TAG, "readResourceConfiguration id=" + id);
+
+        List<String> resource = null;
+        try {
+            resource = Arrays.asList(context.getResources().getStringArray(id));
+        } catch (Resources.NotFoundException nfe) {
+            Log.e(TAG, "readResourceConfiguration exception=" + nfe);
+        } catch (NullPointerException npe) {
+            Log.e(TAG, "readResourceConfiguration exception=" + npe);
+        } finally {
+            if (resource == null) {
+                resource = new ArrayList<String>();
+            }
+        }
+        return resource;
+    }
+
+    /**
+     * Returns whether the dynamic routing feature is enabled.
+     */
+    public boolean isDynamicRoutingEnabled() {
+        Log.i(TAG, "isDynamicRoutingEnabled " + mEnabled);
+        return mEnabled;
+    }
+
+    /**
+     * Returns whether the dynamic routing is enabled with the given {@link Phone}.
+     * @param phone A {@link Phone} instance.
+     */
+    public boolean isDynamicRoutingEnabled(Phone phone) {
+        Log.i(TAG, "isDynamicRoutingEnabled");
+        if (phone == null) return false;
+        String iso = mNetworkCountries.get(Integer.valueOf(phone.getPhoneId()));
+        Log.i(TAG, "isDynamicRoutingEnabled phoneId=" + phone.getPhoneId() + ", iso=" + iso
+                + ", lastIso=" + mLastCountryIso);
+        if (TextUtils.isEmpty(iso)) {
+            iso = mLastCountryIso;
+        }
+        boolean ret = mEnabled && mCountriesEnabled.contains(iso);
+        Log.i(TAG, "isDynamicRoutingEnabled returns " + ret);
+        return ret;
+    }
+
+    /**
+     * Returns emergency call routing that to be used for the given number.
+     * @param phone A {@link Phone} instance.
+     * @param number The dialed number.
+     * @param isNormal Indicates whether it is normal routing number.
+     * @param isAllowed Indicates whether it is allowed emergency number.
+     * @param needToTurnOnRadio Indicates whether it needs to turn on radio power.
+     */
+    public int getEmergencyCallRouting(Phone phone, String number,
+            boolean isNormal, boolean isAllowed, boolean needToTurnOnRadio) {
+        Log.i(TAG, "getEmergencyCallRouting isNormal=" + isNormal + ", isAllowed=" + isAllowed
+                + ", needToTurnOnRadio=" + needToTurnOnRadio);
+        number = PhoneNumberUtils.stripSeparators(number);
+        boolean isDynamic = isDynamicNumber(phone, number);
+        if ((!isNormal && !isDynamic && isAllowed) || isFromNetworkOrSim(phone, number)) {
+            return EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN;
+        }
+        if (isDynamicRoutingEnabled(phone)) {
+            // If airplane mode is enabled, check the service state
+            // after turning on the radio power.
+            return (phone.getServiceState().getState() == ServiceState.STATE_IN_SERVICE
+                    || needToTurnOnRadio)
+                    ? EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL
+                    : EmergencyNumber.EMERGENCY_CALL_ROUTING_EMERGENCY;
+        }
+        return EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL;
+    }
+
+    private boolean isFromNetworkOrSim(Phone phone, String number) {
+        if (phone == null) return false;
+        Log.i(TAG, "isFromNetworkOrSim phoneId=" + phone.getPhoneId());
+        if (phone.getEmergencyNumberTracker() == null) return false;
+        for (EmergencyNumber num : phone.getEmergencyNumberTracker().getEmergencyNumbers(
+                number)) {
+            if (num.getNumber().equals(number)) {
+                if (num.isFromSources(EmergencyNumber.EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALING)
+                        || num.isFromSources(EmergencyNumber.EMERGENCY_NUMBER_SOURCE_SIM)) {
+                    Log.i(TAG, "isFromNetworkOrSim SIM or NETWORK emergency number");
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    private String getNetworkCountryIso(int phoneId) {
+        String iso = mNetworkCountries.get(Integer.valueOf(phoneId));
+        if (TextUtils.isEmpty(iso)) {
+            iso = mLastCountryIso;
+        }
+        return iso;
+    }
+
+    @VisibleForTesting
+    public boolean isDynamicNumber(Phone phone, String number) {
+        if (phone == null || phone.getEmergencyNumberTracker() == null
+                || TextUtils.isEmpty(number)
+                || mDynamicNumbers == null || mDynamicNumbers.isEmpty()) {
+            return false;
+        }
+
+        List<EmergencyNumber> emergencyNumbers =
+                mEmergencyNumbers.get(Integer.valueOf(phone.getPhoneId()));
+        if (emergencyNumbers == null) {
+            updateDynamicEmergencyNumbers(phone.getPhoneId());
+            emergencyNumbers =
+                    mEmergencyNumbers.get(Integer.valueOf(phone.getPhoneId()));
+        }
+        String iso = getNetworkCountryIso(phone.getPhoneId());
+        if (TextUtils.isEmpty(iso)
+                || emergencyNumbers == null || emergencyNumbers.isEmpty()) {
+            return false;
+        }
+
+        // Filter the list with the number.
+        List<EmergencyNumber> dynamicNumbers =
+                getDynamicEmergencyNumbers(emergencyNumbers, number);
+
+        // Compare the dynamicNumbers with the list of EmergencyNumber from EmergencyNumberTracker.
+        emergencyNumbers = phone.getEmergencyNumberTracker().getEmergencyNumbers(number);
+
+        if (dynamicNumbers == null || emergencyNumbers == null
+                || dynamicNumbers.isEmpty() || emergencyNumbers.isEmpty()) {
+            return false;
+        }
+
+        if (DBG) {
+            Log.i(TAG, "isDynamicNumber " + emergencyNumbers);
+        }
+
+        // Compare coutry ISO and MNC. MNC is optional.
+        for (EmergencyNumber dynamicNumber: dynamicNumbers) {
+            if (emergencyNumbers.stream().anyMatch(n ->
+                    TextUtils.equals(n.getCountryIso(), dynamicNumber.getCountryIso())
+                    && (TextUtils.equals(n.getMnc(), dynamicNumber.getMnc())
+                    || TextUtils.isEmpty(dynamicNumber.getMnc())))) {
+                Log.i(TAG, "isDynamicNumber found");
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /** Filter the list of {@link EmergencyNumber} with given number. */
+    private static List<EmergencyNumber> getDynamicEmergencyNumbers(
+            List<EmergencyNumber> emergencyNumbers, String number) {
+        List<EmergencyNumber> filteredNumbers = emergencyNumbers.stream()
+                .filter(num -> num.getNumber().equals(number))
+                .toList();
+
+        if (DBG) {
+            Log.i(TAG, "getDynamicEmergencyNumbers " + filteredNumbers);
+        }
+        return filteredNumbers;
+    }
+
+    /**
+     * Generates the lis of {@link EmergencyNumber} for the given phoneId
+     * based on the detected country from the resource configuration.
+     */
+    private void updateDynamicEmergencyNumbers(int phoneId) {
+        if (mDynamicNumbers == null || mDynamicNumbers.isEmpty()) {
+            // No resource configuration.
+            mEmergencyNumbers.put(Integer.valueOf(phoneId),
+                    new ArrayList<EmergencyNumber>());
+            return;
+        }
+
+        String iso = getNetworkCountryIso(phoneId);
+        if (TextUtils.isEmpty(iso)) {
+            // Update again later.
+            return;
+        }
+        List<EmergencyNumber> emergencyNumbers = new ArrayList<EmergencyNumber>();
+        for (String numberInfo : mDynamicNumbers) {
+            if (!TextUtils.isEmpty(numberInfo) && numberInfo.startsWith(iso)) {
+                emergencyNumbers.addAll(getEmergencyNumbers(numberInfo));
+            }
+        }
+        mEmergencyNumbers.put(Integer.valueOf(phoneId), emergencyNumbers);
+    }
+
+    /** Returns an {@link EmergencyNumber} instance from the resource configuration. */
+    private List<EmergencyNumber> getEmergencyNumbers(String numberInfo) {
+        ArrayList<EmergencyNumber> emergencyNumbers = new ArrayList<EmergencyNumber>();
+        if (TextUtils.isEmpty(numberInfo)) {
+            return emergencyNumbers;
+        }
+
+        String[] fields = numberInfo.split(",");
+        // Format: "iso,mnc,number1,number2,..."
+        if (fields == null || fields.length < 3
+                || TextUtils.isEmpty(fields[0])
+                || TextUtils.isEmpty(fields[2])) {
+            return emergencyNumbers;
+        }
+
+        for (int i = 2; i < fields.length; i++) {
+            if (TextUtils.isEmpty(fields[i])) {
+                continue;
+            }
+            emergencyNumbers.add(new EmergencyNumber(fields[i] /* number */,
+                fields[0] /* iso */, fields[1] /* mnc */,
+                EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED,
+                new ArrayList<String>(),
+                EmergencyNumber.EMERGENCY_NUMBER_SOURCE_DATABASE,
+                EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN));
+        }
+
+        return emergencyNumbers;
+    }
+}
diff --git a/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelector.java b/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelector.java
index 099def8..9f2e0a9 100644
--- a/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelector.java
+++ b/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelector.java
@@ -149,11 +149,15 @@
             ImsReasonInfo.CODE_LOCAL_NOT_REGISTERED,
             ImsReasonInfo.CODE_SIP_ALTERNATE_EMERGENCY_CALL);
 
+    private static List<Integer> sDisconnectCauseForTerminatation = List.of(
+            SERVICE_OPTION_NOT_AVAILABLE);
+
     private static final LocalLog sLocalLog = new LocalLog(LOG_SIZE);
 
     private static List<String> sSimReadyAllowList;
     private static List<String> sPreferSlotWithNormalServiceList;
     private static List<String> sPreferCsAfterCsfbFailure;
+    private static List<String> sPreferGeranWhenSimAbsent;
 
     /**
      * Network callback used to determine whether Wi-Fi is connected or not.
@@ -163,6 +167,9 @@
                 @Override
                 public void onAvailable(Network network) {
                     logi("onAvailable: " + network);
+                    if (network != null && !mWiFiNetworksAvailable.contains(network)) {
+                        mWiFiNetworksAvailable.add(network);
+                    }
                     mWiFiAvailable = true;
                     sendEmptyMessage(MSG_WIFI_AVAILABLE);
                 }
@@ -170,12 +177,20 @@
                 @Override
                 public void onLost(Network network) {
                     logi("onLost: " + network);
+                    if (network != null) {
+                        mWiFiNetworksAvailable.remove(network);
+                    }
+                    if (!mWiFiNetworksAvailable.isEmpty()) {
+                        logi("onLost: available networks=" + mWiFiNetworksAvailable);
+                        return;
+                    }
                     mWiFiAvailable = false;
                 }
 
                 @Override
                 public void onUnavailable() {
                     logi("onUnavailable");
+                    mWiFiNetworksAvailable.clear();
                     mWiFiAvailable = false;
                 }
             };
@@ -229,6 +244,7 @@
     private boolean mTryEsFallback;
     private boolean mIsWaitingForDataDisconnection;
     private boolean mSwitchRatPreferenceWithLocalNotRegistered;
+    private boolean mTerminateAfterCsFailure;
     private int mModemCount;
 
     /** Indicates whether this instance is deactivated. */
@@ -253,6 +269,7 @@
     private final PowerManager.WakeLock mPartialWakeLock;
     private final CrossSimRedialingController mCrossSimRedialingController;
     private final DataConnectionStateHelper mEpdnHelper;
+    private final List<Network> mWiFiNetworksAvailable = new ArrayList<>();
 
     /** Constructor. */
     public EmergencyCallDomainSelector(Context context, int slotId, int subId,
@@ -361,6 +378,8 @@
             return;
         }
 
+        checkAndSetTerminateAfterCsFailure(result);
+
         if (result.getRegState() != REGISTRATION_STATE_HOME
                 && result.getRegState() != REGISTRATION_STATE_ROAMING) {
             if (maybeRedialOnTheOtherSlotInNormalService(result)) {
@@ -401,7 +420,8 @@
         int domain = result.getDomain();
         if (domain == NetworkRegistrationInfo.DOMAIN_CS) return true;
         if ((domain & NetworkRegistrationInfo.DOMAIN_CS) > 0) {
-            return (!result.isEmcBearerSupported() || !result.isVopsSupported());
+            // b/341865236, check emcBearer only
+            return (!result.isEmcBearerSupported());
         }
         return false;
     }
@@ -437,6 +457,8 @@
             return;
         }
 
+        mTerminateAfterCsFailure = false;
+
         if (mTryCsWhenPsFails) {
             mTryCsWhenPsFails = false;
             // Initial state was CSFB available and dial PS failed.
@@ -629,6 +651,7 @@
         mImsRegistered = mImsStateTracker.isImsRegistered();
         logi("onImsRegistrationStateChanged " + mImsRegistered);
         selectDomain();
+        handleImsStateChange();
     }
 
     @Override
@@ -637,6 +660,14 @@
         mIsVoiceCapable = mImsStateTracker.isImsVoiceCapable();
         logi("onImsMmTelCapabilitiesChanged " + mIsVoiceCapable);
         selectDomain();
+        handleImsStateChange();
+    }
+
+    private void handleImsStateChange() {
+        if (!mVoWifiOverEmergencyPdn && !mDomainSelected
+                && (mMaxCellularTimerExpired || mNetworkScanTimerExpired)) {
+            maybeDialOverWlan();
+        }
     }
 
     private boolean isSimReady() {
@@ -785,6 +816,13 @@
         }
         logi("readResourceConfiguration preferCsAfterCsfbFailure="
                 + sPreferCsAfterCsfbFailure);
+
+        if (sPreferGeranWhenSimAbsent == null) {
+            sPreferGeranWhenSimAbsent = readResourceConfiguration(
+                    R.array.config_countries_prefer_geran_when_sim_absent);
+        }
+        logi("readResourceConfiguration preferGeranWhenSimAbsent="
+                + sPreferGeranWhenSimAbsent);
     }
 
     private List<String> readResourceConfiguration(int id) {
@@ -811,6 +849,7 @@
         sSimReadyAllowList = null;
         sPreferSlotWithNormalServiceList = null;
         sPreferCsAfterCsfbFailure = null;
+        sPreferGeranWhenSimAbsent = null;
     }
 
     private void selectDomain() {
@@ -883,6 +922,7 @@
             if (mPsNetworkType == EUTRAN) {
                 onWwanNetworkTypeSelected(mPsNetworkType);
             } else if (mCsNetworkType != UNKNOWN) {
+                checkAndSetTerminateAfterCsFailure(mLastRegResult);
                 onWwanNetworkTypeSelected(mCsNetworkType);
             } else {
                 requestScan(true);
@@ -1037,6 +1077,17 @@
                 + ", csPreferred=" + csPreferred + ", esFallback=" + tryEsFallback
                 + ", lastNetworkType=" + accessNetworkTypeToString(mLastNetworkType));
 
+        if (mLastRegResult != null
+                && sPreferGeranWhenSimAbsent.contains(mLastRegResult.getCountryIso())
+                && !isSimReady()) {
+            logi("getNextPreferredNetworks preferGeran");
+            preferredNetworks.add(GERAN);
+            preferredNetworks.add(UTRAN);
+            preferredNetworks.add(EUTRAN);
+            preferredNetworks.add(NGRAN);
+            return preferredNetworks;
+        }
+
         if (!csPreferred && (mLastNetworkType == UNKNOWN || tryEsFallback)) {
             // Generate the list per the domain preference.
 
@@ -1592,6 +1643,7 @@
             return;
         }
 
+        mWiFiNetworksAvailable.clear();
         ConnectivityManager cm = mContext.getSystemService(ConnectivityManager.class);
         if (cm != null) {
             logi("registerForConnectivityChanges");
@@ -1610,6 +1662,7 @@
             return;
         }
 
+        mWiFiNetworksAvailable.clear();
         ConnectivityManager cm = mContext.getSystemService(ConnectivityManager.class);
         if (cm != null) {
             logi("unregisterForConnectivityChanges");
@@ -1717,7 +1770,6 @@
                 break;
         }
 
-        // If CS call fails, retry always. Otherwise, check the reason code.
         ImsReasonInfo reasonInfo = mSelectionAttributes.getPsDisconnectCause();
         if (mRetryReasonCodes != null && reasonInfo != null) {
             if (!mRetryReasonCodes.contains(reasonInfo.getCode())) {
@@ -1725,6 +1777,13 @@
                 terminateSelection(DisconnectCause.NOT_VALID);
                 return true;
             }
+        } else if (reasonInfo == null
+                && sDisconnectCauseForTerminatation.contains(cause)
+                && mTerminateAfterCsFailure) {
+            // b/341055741
+            logi("maybeTerminateSelection terminate after CS failure");
+            terminateSelection(DisconnectCause.NOT_VALID);
+            return true;
         }
         return false;
     }
@@ -1925,6 +1984,27 @@
         return ret;
     }
 
+    private void checkAndSetTerminateAfterCsFailure(EmergencyRegistrationResult result) {
+        if (result == null) return;
+        String mcc = result.getMcc();
+        int accessNetwork = result.getAccessNetwork();
+        if (!TextUtils.isEmpty(mcc) && mcc.startsWith("00") // test network
+                && (accessNetwork == UTRAN || accessNetwork == GERAN)) {
+            // b/341055741
+            mTerminateAfterCsFailure = true;
+        }
+    }
+
+    @VisibleForTesting
+    public boolean isWiFiAvailable() {
+        return mWiFiAvailable;
+    }
+
+    @VisibleForTesting
+    public List<Network> getWiFiNetworksAvailable() {
+        return mWiFiNetworksAvailable;
+    }
+
     @Override
     protected void logi(String msg) {
         super.logi(msg);
diff --git a/src/com/android/services/telephony/domainselection/NormalCallDomainSelector.java b/src/com/android/services/telephony/domainselection/NormalCallDomainSelector.java
index 31a1cc2..8d49634 100644
--- a/src/com/android/services/telephony/domainselection/NormalCallDomainSelector.java
+++ b/src/com/android/services/telephony/domainselection/NormalCallDomainSelector.java
@@ -108,7 +108,7 @@
             mSelectorState = SelectorState.INACTIVE;
             loge("Subscription-ids doesn't match. This instance is associated with sub-id:"
                     + getSubId() + ", requested sub-id:" + subId);
-            // TODO: Throw anamoly here. This condition should never occur.
+            // TODO: Throw anomaly here. This condition should never occur.
         }
     }
 
@@ -314,6 +314,7 @@
     private synchronized void selectDomain() {
         if (mSelectorState != SelectorState.ACTIVE || mSelectionAttributes == null
                 || mTransportSelectorCallback == null) {
+            mSelectorState = SelectorState.INACTIVE;
             logd("Domain Selection is stopped.");
             return;
         }
@@ -429,7 +430,7 @@
     }
 
     @VisibleForTesting
-    public SelectorState getSelectorState() {
+    protected SelectorState getSelectorState() {
         return mSelectorState;
     }
 }
diff --git a/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/TestSatelliteService.java b/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/TestSatelliteService.java
index d79240e..b5b781c 100644
--- a/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/TestSatelliteService.java
+++ b/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/TestSatelliteService.java
@@ -36,6 +36,7 @@
 import android.telephony.satellite.stub.SatelliteModemState;
 import android.telephony.satellite.stub.SatelliteResult;
 import android.telephony.satellite.stub.SatelliteService;
+import android.telephony.satellite.stub.SystemSelectionSpecifier;
 import android.util.Log;
 
 import com.android.internal.util.FunctionalUtils;
@@ -434,6 +435,23 @@
         mIsRequestIsSatelliteEnabledForCarrier = true;
     }
 
+    @Override
+    public void updateSatelliteSubscription(@NonNull String iccId,
+            @NonNull IIntegerConsumer resultCallback) {
+        logd("updateSatelliteSubscription: iccId=" + iccId + " mErrorCode=" + mErrorCode);
+        runWithExecutor(() -> resultCallback.accept(mErrorCode));
+    }
+
+    @Override
+    public void updateSystemSelectionChannels(
+            @NonNull List<SystemSelectionSpecifier> systemSelectionSpecifiers,
+            @NonNull IIntegerConsumer resultCallback) {
+        logd(" updateSystemSelectionChannels: "
+                + "systemSelectionSpecifiers=" + systemSelectionSpecifiers
+                + " mErrorCode=" + mErrorCode);
+        runWithExecutor(() -> resultCallback.accept(mErrorCode));
+    }
+
     public void setLocalSatelliteListener(@NonNull ILocalSatelliteListener listener) {
         logd("setLocalSatelliteListener: listener=" + listener);
         mLocalListener = listener;
diff --git a/tests/src/com/android/phone/satellite/accesscontrol/SatelliteAccessControllerTest.java b/tests/src/com/android/phone/satellite/accesscontrol/SatelliteAccessControllerTest.java
index 8a29242..f34b4a7 100644
--- a/tests/src/com/android/phone/satellite/accesscontrol/SatelliteAccessControllerTest.java
+++ b/tests/src/com/android/phone/satellite/accesscontrol/SatelliteAccessControllerTest.java
@@ -55,6 +55,7 @@
 import android.os.AsyncResult;
 import android.os.Bundle;
 import android.os.CancellationSignal;
+import android.os.DropBoxManager;
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.Looper;
@@ -126,6 +127,8 @@
     @Mock
     private SatelliteModemInterface mMockSatelliteModemInterface;
     @Mock
+    private DropBoxManager mMockDropBoxManager;
+    @Mock
     private Context mMockContext;
     @Mock
     private Phone mMockPhone;
@@ -210,10 +213,14 @@
                 Context.LOCATION_SERVICE);
         when(mMockContext.getSystemServiceName(TelecomManager.class)).thenReturn(
                 Context.TELECOM_SERVICE);
+        when(mMockContext.getSystemServiceName(DropBoxManager.class)).thenReturn(
+                Context.DROPBOX_SERVICE);
         when(mMockContext.getSystemService(LocationManager.class)).thenReturn(
                 mMockLocationManager);
         when(mMockContext.getSystemService(TelecomManager.class)).thenReturn(
                 mMockTelecomManager);
+        when(mMockContext.getSystemService(DropBoxManager.class)).thenReturn(
+                mMockDropBoxManager);
         mPhones = new Phone[]{mMockPhone, mMockPhone2};
         replaceInstance(PhoneFactory.class, "sPhones", null, mPhones);
         replaceInstance(SatelliteController.class, "sInstance", null,
@@ -259,6 +266,8 @@
         doReturn(mMockSharedPreferencesEditor).when(mMockSharedPreferencesEditor)
                 .putStringSet(anyString(), any());
 
+        when(mMockFeatureFlags.satellitePersistentLogging()).thenReturn(true);
+
         mSatelliteAccessControllerUT = new TestSatelliteAccessController(mMockContext,
                 mMockFeatureFlags, mLooper, mMockLocationManager, mMockTelecomManager,
                 mMockSatelliteOnDeviceAccessController, mMockSatS2File);
@@ -323,21 +332,11 @@
                 mSatelliteAllowedSemaphore, 1));
         assertEquals(SATELLITE_RESULT_MODEM_ERROR, mQueriedSatelliteAllowedResultCode);
 
-        // Network country codes are available.
-        setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_RESULT_SUCCESS);
-        clearAllInvocations();
-        when(mMockCountryDetector.getCurrentNetworkCountryIso()).thenReturn(listOf("US", "CA"));
-        mSatelliteAccessControllerUT.requestIsCommunicationAllowedForCurrentLocation(
-                SUB_ID, mSatelliteAllowedReceiver);
-        mTestableLooper.processAllMessages();
-        assertTrue(waitForRequestIsSatelliteAllowedForCurrentLocationResult(
-                mSatelliteAllowedSemaphore, 1));
-        assertEquals(SATELLITE_RESULT_SUCCESS, mQueriedSatelliteAllowedResultCode);
-        assertTrue(mQueriedSatelliteAllowed);
-
         // Network country codes are not available. TelecomManager.isInEmergencyCall() returns true.
         // On-device access controller will be used. Last known location is available and fresh.
         clearAllInvocations();
+        setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_RESULT_SUCCESS);
+        setUpResponseForRequestIsSatelliteProvisioned(true, SATELLITE_RESULT_SUCCESS);
         when(mMockCountryDetector.getCurrentNetworkCountryIso()).thenReturn(EMPTY_STRING_LIST);
         when(mMockTelecomManager.isInEmergencyCall()).thenReturn(true);
         mSatelliteAccessControllerUT.elapsedRealtimeNanos = TEST_LOCATION_FRESH_DURATION_NANOS + 1;
@@ -423,12 +422,11 @@
         assertFalse(mSatelliteAccessControllerUT.isWaitForCurrentLocationTimerStarted());
         verify(mMockSatelliteOnDeviceAccessController, never()).isSatCommunicationAllowedAtLocation(
                 any(SatelliteOnDeviceAccessController.LocationToken.class));
-        verifyCountryDetectorApisCalled();
         assertTrue(waitForRequestIsSatelliteAllowedForCurrentLocationResult(
                 mSatelliteAllowedSemaphore, 1));
         assertEquals(SATELLITE_RESULT_SUCCESS,
                 mQueriedSatelliteAllowedResultCode);
-        assertFalse(mQueriedSatelliteAllowed);
+        assertTrue(mQueriedSatelliteAllowed);
 
         // Network country codes are not available. TelecomManager.isInEmergencyCall() returns
         // false. No phone is in ECM. Last known location is not fresh. Cached country codes should
@@ -451,43 +449,11 @@
                 any(Consumer.class));
         verify(mMockSatelliteOnDeviceAccessController, never()).isSatCommunicationAllowedAtLocation(
                 any(SatelliteOnDeviceAccessController.LocationToken.class));
-        verifyCountryDetectorApisCalled();
         assertTrue(waitForRequestIsSatelliteAllowedForCurrentLocationResult(
                 mSatelliteAllowedSemaphore, 1));
         assertEquals(SATELLITE_RESULT_SUCCESS, mQueriedSatelliteAllowedResultCode);
         assertFalse(mQueriedSatelliteAllowed);
 
-        // Network country codes are not available. TelecomManager.isInEmergencyCall() returns
-        // false. No phone is in ECM. Last known location is not fresh. Cached country codes should
-        // be used for verifying satellite allow. Cached country codes are available.
-        clearAllInvocations();
-        when(mMockCountryDetector.getCurrentNetworkCountryIso()).thenReturn(EMPTY_STRING_LIST);
-        when(mMockCountryDetector.getCachedLocationCountryIsoInfo())
-                .thenReturn(new Pair<>("US", 5L));
-        Map<String, Long> cachedNetworkCountryCodes = new HashMap<>();
-        cachedNetworkCountryCodes.put("UK", 1L);
-        cachedNetworkCountryCodes.put("US", 3L);
-        when(mMockCountryDetector.getCachedNetworkCountryIsoInfo())
-                .thenReturn(cachedNetworkCountryCodes);
-        when(mMockTelecomManager.isInEmergencyCall()).thenReturn(false);
-        when(mMockPhone.isInEcm()).thenReturn(false);
-        when(mMockPhone2.isInEcm()).thenReturn(false);
-        mSatelliteAccessControllerUT.elapsedRealtimeNanos = TEST_LOCATION_FRESH_DURATION_NANOS + 1;
-        when(mMockLocation0.getElapsedRealtimeNanos()).thenReturn(0L);
-        when(mMockLocation1.getElapsedRealtimeNanos()).thenReturn(0L);
-        mSatelliteAccessControllerUT.requestIsCommunicationAllowedForCurrentLocation(
-                SUB_ID, mSatelliteAllowedReceiver);
-        mTestableLooper.processAllMessages();
-        verify(mMockLocationManager, never()).getCurrentLocation(anyString(),
-                any(LocationRequest.class), any(CancellationSignal.class), any(Executor.class),
-                any(Consumer.class));
-        verify(mMockSatelliteOnDeviceAccessController, never()).isSatCommunicationAllowedAtLocation(
-                any(SatelliteOnDeviceAccessController.LocationToken.class));
-        verifyCountryDetectorApisCalled();
-        assertTrue(waitForRequestIsSatelliteAllowedForCurrentLocationResult(
-                mSatelliteAllowedSemaphore, 1));
-        assertEquals(SATELLITE_RESULT_SUCCESS, mQueriedSatelliteAllowedResultCode);
-        assertTrue(mQueriedSatelliteAllowed);
     }
 
     @Test
@@ -621,6 +587,23 @@
                 any(ResultReceiver.class));
     }
 
+    private void setUpResponseForRequestIsSatelliteProvisioned(
+            boolean isSatelliteProvisioned, @SatelliteManager.SatelliteResult int error) {
+        doAnswer(invocation -> {
+            ResultReceiver resultReceiver = invocation.getArgument(1);
+            if (error == SATELLITE_RESULT_SUCCESS) {
+                Bundle bundle = new Bundle();
+                bundle.putBoolean(SatelliteManager.KEY_SATELLITE_PROVISIONED,
+                        isSatelliteProvisioned);
+                resultReceiver.send(error, bundle);
+            } else {
+                resultReceiver.send(error, Bundle.EMPTY);
+            }
+            return null;
+        }).when(mMockSatelliteController).requestIsSatelliteProvisioned(anyInt(),
+                any(ResultReceiver.class));
+    }
+
     @SafeVarargs
     private static <E> List<E> listOf(E... values) {
         return Arrays.asList(values);
diff --git a/tests/src/com/android/phone/satellite/entitlement/SatelliteEntitlementControllerTest.java b/tests/src/com/android/phone/satellite/entitlement/SatelliteEntitlementControllerTest.java
index 4dcef2a..e663519 100644
--- a/tests/src/com/android/phone/satellite/entitlement/SatelliteEntitlementControllerTest.java
+++ b/tests/src/com/android/phone/satellite/entitlement/SatelliteEntitlementControllerTest.java
@@ -95,6 +95,7 @@
     private static final List<String> EMPTY_PLMN_LIST = new ArrayList<>();
     private static final int CMD_START_QUERY_ENTITLEMENT = 1;
     private static final int CMD_RETRY_QUERY_ENTITLEMENT = 2;
+    private static final int CMD_SIM_REFRESH = 3;
     private static final int MAX_RETRY_COUNT = 5;
     @Mock
     CarrierConfigManager mCarrierConfigManager;
@@ -810,6 +811,33 @@
                 eq(PLMN_ALLOWED_LIST), eq(PLMN_BARRED_LIST), any());
     }
 
+    @Test
+    public void testStartQueryEntitlementStatus_AfterSimRefresh() throws Exception {
+        logd("testStartQueryEntitlementStatus_AfterSimRefresh");
+        setIsQueryAvailableTrue();
+
+        // Verify the first query complete.
+        doReturn(mSatelliteEntitlementResult).when(
+                mSatelliteEntitlementApi).checkEntitlementStatus();
+        setSatelliteEntitlementResult(SATELLITE_ENTITLEMENT_STATUS_ENABLED, PLMN_ALLOWED_LIST,
+                PLMN_BARRED_LIST);
+        mSatelliteEntitlementController.handleCmdStartQueryEntitlement();
+
+        verify(mSatelliteEntitlementApi).checkEntitlementStatus();
+        verify(mSatelliteController).onSatelliteEntitlementStatusUpdated(anyInt(),
+                anyBoolean(), anyList(), anyList(), any());
+
+        // SIM_REFRESH event occurred before expired the query refresh timer, verify the start
+        // the query.
+        sendMessage(CMD_SIM_REFRESH, SUB_ID);
+        mTestableLooper.moveTimeForward(TimeUnit.MINUTES.toMillis(10));
+        mTestableLooper.processAllMessages();
+
+        verify(mSatelliteEntitlementApi, times(2)).checkEntitlementStatus();
+        verify(mSatelliteController, times(2)).onSatelliteEntitlementStatusUpdated(anyInt(),
+                anyBoolean(), anyList(), anyList(), any());
+    }
+
     private void triggerCarrierConfigChanged() {
         for (Pair<Executor, CarrierConfigManager.CarrierConfigChangeListener> pair
                 : mCarrierConfigChangedListenerList) {
diff --git a/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java b/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java
index 3470d4a..22ab787 100644
--- a/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java
+++ b/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java
@@ -56,6 +56,7 @@
 
 import android.content.ComponentName;
 import android.content.Context;
+import android.content.res.Resources;
 import android.net.Uri;
 import android.os.AsyncResult;
 import android.os.Bundle;
@@ -252,6 +253,7 @@
     @Mock ImsPhone mImsPhone;
     @Mock private SatelliteSOSMessageRecommender mSatelliteSOSMessageRecommender;
     @Mock private EmergencyStateTracker mEmergencyStateTracker;
+    @Mock private Resources mMockResources;
     private Phone mPhone0;
     private Phone mPhone1;
 
@@ -320,6 +322,8 @@
                 any(), anyInt(), anyBoolean());
         replaceInstance(TelephonyConnectionService.class,
                 "mSatelliteController", mTestConnectionService, mSatelliteController);
+        doReturn(mMockResources).when(mContext).getResources();
+
         mBinderStub = (IConnectionService.Stub) mTestConnectionService.onBind(null);
         mSetFlagsRule.disableFlags(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG);
         mSetFlagsRule.enableFlags(Flags.FLAG_DO_NOT_OVERRIDE_PRECISE_LABEL);
@@ -1431,6 +1435,9 @@
     @SmallTest
     public void testCreateOutgoingEmergencyConnection_exitingSatellite_placeCall() {
         when(mSatelliteController.isSatelliteEnabled()).thenReturn(true);
+        doReturn(true).when(mMockResources).getBoolean(anyInt());
+        doReturn(true).when(mTelephonyManagerProxy).isCurrentEmergencyNumber(
+                anyString());
         Phone testPhone = setupConnectionServiceInApm();
 
         ArgumentCaptor<RadioOnStateListener.Callback> callback =
@@ -2935,6 +2942,8 @@
                 dialArgs.intentExtras.getInt(PhoneConstants.EXTRA_DIAL_DOMAIN, -1));
         assertTrue(dialArgs.isEmergency);
         assertEquals(eccCategory, dialArgs.eccCategory);
+        assertTrue(dialArgs.intentExtras.getBoolean(
+                PhoneConstants.EXTRA_USE_EMERGENCY_ROUTING, false));
     }
 
     @Test
@@ -2986,6 +2995,8 @@
                 dialArgs.intentExtras.getInt(PhoneConstants.EXTRA_DIAL_DOMAIN, -1));
         assertTrue(dialArgs.isEmergency);
         assertEquals(eccCategory, dialArgs.eccCategory);
+        assertTrue(dialArgs.intentExtras.getBoolean(
+                PhoneConstants.EXTRA_USE_EMERGENCY_ROUTING, false));
     }
 
     @Test
@@ -3602,6 +3613,24 @@
     }
 
     @Test
+    public void testEmergencyCallSatelliteEnabled_blockEmergencyCall() {
+        setupForCallTest();
+        doReturn(true).when(mSatelliteController).isSatelliteEnabled();
+        doReturn(false).when(mMockResources).getBoolean(anyInt());
+        doReturn(true).when(mTelephonyManagerProxy).isCurrentEmergencyNumber(
+                anyString());
+
+        // Simulates an outgoing emergency call.
+        mConnection = mTestConnectionService.onCreateOutgoingConnection(PHONE_ACCOUNT_HANDLE_1,
+                createConnectionRequest(PHONE_ACCOUNT_HANDLE_1,
+                        TEST_EMERGENCY_NUMBER, TELECOM_CALL_ID1));
+        DisconnectCause disconnectCause = mConnection.getDisconnectCause();
+        assertEquals(android.telephony.DisconnectCause.SATELLITE_ENABLED,
+                disconnectCause.getTelephonyDisconnectCause());
+        assertEquals(DISCONNECT_REASON_SATELLITE_ENABLED, disconnectCause.getReason());
+    }
+
+    @Test
     public void testNormalCallUsingNonTerrestrialNetwork_enableFlag() throws Exception {
         mSetFlagsRule.enableFlags(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG);
 
diff --git a/tests/src/com/android/services/telephony/domainselection/DynamicRoutingControllerTest.java b/tests/src/com/android/services/telephony/domainselection/DynamicRoutingControllerTest.java
new file mode 100644
index 0000000..f15ae4a
--- /dev/null
+++ b/tests/src/com/android/services/telephony/domainselection/DynamicRoutingControllerTest.java
@@ -0,0 +1,227 @@
+/*
+ * Copyright (C) 2024 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.services.telephony.domainselection;
+
+import static junit.framework.Assert.assertNotNull;
+import static junit.framework.Assert.assertNull;
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.when;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.res.Resources;
+import android.os.Looper;
+import android.telephony.TelephonyManager;
+import android.telephony.emergency.EmergencyNumber;
+import android.text.TextUtils;
+
+import com.android.TestContext;
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneConstants;
+import com.android.internal.telephony.emergency.EmergencyNumberTracker;
+import com.android.phone.R;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.ArrayList;
+
+/**
+ * Unit tests for DynamicRoutingController
+ */
+public class DynamicRoutingControllerTest {
+    private static final String TAG = "DynamicRoutingControllerTest";
+
+    private static final int SLOT_0 = 0;
+    private static final int SLOT_1 = 1;
+
+    @Mock private Resources mResources;
+    @Mock private DynamicRoutingController.PhoneFactoryProxy mPhoneFactoryProxy;
+    @Mock private Phone mPhone0;
+    @Mock private Phone mPhone1;
+    @Mock private EmergencyNumberTracker mEmergencyNumberTracker;
+
+    private BroadcastReceiver mReceiver;
+    private IntentFilter mIntentFilter;
+
+    private Context mContext;
+    private DynamicRoutingController mDrc;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+        mContext = new TestContext() {
+            @Override
+            public String getOpPackageName() {
+                return "";
+            }
+
+            @Override
+            public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
+                mReceiver = receiver;
+                mIntentFilter = filter;
+                return null;
+            }
+
+            @Override
+            public Resources getResources() {
+                return mResources;
+            }
+        };
+
+        if (Looper.myLooper() == null) {
+            Looper.prepare();
+        }
+
+        when(mResources.getStringArray(anyInt())).thenReturn(null);
+        when(mPhoneFactoryProxy.getPhone(eq(SLOT_0))).thenReturn(mPhone0);
+        when(mPhoneFactoryProxy.getPhone(eq(SLOT_1))).thenReturn(mPhone1);
+        when(mPhone0.getPhoneId()).thenReturn(SLOT_0);
+        when(mPhone1.getPhoneId()).thenReturn(SLOT_1);
+        when(mPhone0.getEmergencyNumberTracker()).thenReturn(mEmergencyNumberTracker);
+        when(mPhone1.getEmergencyNumberTracker()).thenReturn(mEmergencyNumberTracker);
+        when(mEmergencyNumberTracker.getEmergencyNumbers(anyString()))
+                .thenReturn(new ArrayList<EmergencyNumber>());
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        mDrc = null;
+    }
+
+    @Test
+    public void testNotEnabledInitialize() throws Exception {
+        createController(false, null);
+
+        assertFalse(mDrc.isDynamicRoutingEnabled());
+
+        assertNull(mReceiver);
+        assertNull(mIntentFilter);
+    }
+
+    @Test
+    public void testEnabledInitialize() throws Exception {
+        createController(true, null);
+
+        assertTrue(mDrc.isDynamicRoutingEnabled());
+        assertFalse(mDrc.isDynamicRoutingEnabled(mPhone0));
+        assertFalse(mDrc.isDynamicRoutingEnabled(mPhone1));
+    }
+
+    @Test
+    public void testEnabledCountryChanged() throws Exception {
+        createController(true, "us");
+
+        sendNetworkCountryChanged(SLOT_0, "zz");
+        assertTrue(mDrc.isDynamicRoutingEnabled());
+        assertFalse(mDrc.isDynamicRoutingEnabled(mPhone0));
+        assertFalse(mDrc.isDynamicRoutingEnabled(mPhone1));
+
+        sendNetworkCountryChanged(SLOT_0, "us");
+        assertTrue(mDrc.isDynamicRoutingEnabled(mPhone0));
+        assertTrue(mDrc.isDynamicRoutingEnabled(mPhone1));
+    }
+
+    @Test
+    public void testDynamicRouting() throws Exception {
+        doReturn(new String[] {"us,,110,117,118,119", "zz,,200"})
+                .when(mResources).getStringArray(
+                eq(R.array.config_dynamic_routing_emergency_numbers));
+
+        createController(true, "us");
+
+        sendNetworkCountryChanged(SLOT_0, "us");
+
+        ArrayList<EmergencyNumber> nums = new ArrayList<EmergencyNumber>();
+        nums.add(getEmergencyNumber("us", "110", "92"));
+        when(mEmergencyNumberTracker.getEmergencyNumbers(eq("110"))).thenReturn(nums);
+
+        // Not included in the resource configuration.
+        nums = new ArrayList<EmergencyNumber>();
+        nums.add(getEmergencyNumber("us", "111", "92"));
+        when(mEmergencyNumberTracker.getEmergencyNumbers(eq("111"))).thenReturn(nums);
+
+        // Different country.
+        nums = new ArrayList<EmergencyNumber>();
+        nums.add(getEmergencyNumber("zz", "117", "92"));
+        when(mEmergencyNumberTracker.getEmergencyNumbers(eq("117"))).thenReturn(nums);
+
+        // No info in the EmergencyNumberTracker
+        nums = new ArrayList<EmergencyNumber>();
+        when(mEmergencyNumberTracker.getEmergencyNumbers(eq("118"))).thenReturn(nums);
+
+        nums = new ArrayList<EmergencyNumber>();
+        nums.add(getEmergencyNumber("us", "119", "92"));
+        when(mEmergencyNumberTracker.getEmergencyNumbers(eq("119"))).thenReturn(nums);
+
+        // Different country.
+        nums = new ArrayList<EmergencyNumber>();
+        nums.add(getEmergencyNumber("us", "200", "92"));
+        when(mEmergencyNumberTracker.getEmergencyNumbers(eq("200"))).thenReturn(nums);
+
+        assertTrue(mDrc.isDynamicNumber(mPhone0, "110"));
+        assertFalse(mDrc.isDynamicNumber(mPhone0, "111"));
+        assertFalse(mDrc.isDynamicNumber(mPhone0, "117"));
+        assertFalse(mDrc.isDynamicNumber(mPhone0, "118"));
+        assertTrue(mDrc.isDynamicNumber(mPhone0, "119"));
+        assertFalse(mDrc.isDynamicNumber(mPhone0, "200"));
+    }
+
+    private EmergencyNumber getEmergencyNumber(String iso, String number, String mnc) {
+        return new EmergencyNumber(number, iso, mnc,
+                EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED,
+                new ArrayList<String>(),
+                EmergencyNumber.EMERGENCY_NUMBER_SOURCE_MODEM_CONFIG,
+                EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN);
+    }
+
+    private void sendNetworkCountryChanged(int phoneId, String iso) {
+        Intent intent = new Intent(TelephonyManager.ACTION_NETWORK_COUNTRY_CHANGED);
+        intent.putExtra(PhoneConstants.PHONE_KEY, phoneId);
+        intent.putExtra(TelephonyManager.EXTRA_NETWORK_COUNTRY, iso);
+        mReceiver.onReceive(mContext, intent);
+    }
+
+    private void createController(boolean enabled, String iso) throws Exception {
+        doReturn(enabled).when(mResources).getBoolean(
+                eq(R.bool.dynamic_routing_emergency_enabled));
+        if (!TextUtils.isEmpty(iso)) {
+            doReturn(new String[] {iso}).when(mResources).getStringArray(
+                    eq(R.array.config_countries_dynamic_routing_emergency_enabled));
+        }
+
+        mDrc = new DynamicRoutingController(mPhoneFactoryProxy);
+        mDrc.initialize(mContext);
+
+        if (enabled) {
+            assertNotNull(mReceiver);
+            assertNotNull(mIntentFilter);
+            assertTrue(mIntentFilter.hasAction(TelephonyManager.ACTION_NETWORK_COUNTRY_CHANGED));
+        }
+    }
+}
diff --git a/tests/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelectorTest.java b/tests/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelectorTest.java
index 38c9677..d4ee933 100644
--- a/tests/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelectorTest.java
+++ b/tests/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelectorTest.java
@@ -92,6 +92,7 @@
 import android.content.Context;
 import android.content.res.Resources;
 import android.net.ConnectivityManager;
+import android.net.Network;
 import android.net.NetworkRequest;
 import android.net.Uri;
 import android.os.CancellationSignal;
@@ -129,6 +130,7 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.TestContext;
+import com.android.phone.R;
 
 import org.junit.After;
 import org.junit.Before;
@@ -1935,7 +1937,7 @@
         mResultConsumer.accept(regResult);
         processAllMessages();
 
-        verifyCsDialed();
+        verifyPsDialed();
     }
 
     @Test
@@ -3969,6 +3971,328 @@
         assertFalse(mDomainSelector.hasMessages(MSG_MAX_CELLULAR_TIMEOUT));
     }
 
+    @Test
+    public void testInvalidSubscriptionAdjustCsRatPreference() throws Exception {
+        doReturn(new String[] {"us"}).when(mResources).getStringArray(
+                eq(R.array.config_countries_prefer_geran_when_sim_absent));
+
+        createSelector(SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+        unsolBarringInfoChanged(false);
+
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(EUTRAN,
+                REGISTRATION_STATE_UNKNOWN, 0, false, true, 0, 0, "", "", "us");
+        // Invalid subscription id
+        SelectionAttributes attr = getSelectionAttributes(SLOT_0,
+                SubscriptionManager.INVALID_SUBSCRIPTION_ID, regResult);
+        mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+        processAllMessages();
+
+        bindImsServiceUnregistered();
+
+        verifyPsDialed();
+
+        mDomainSelector.reselectDomain(attr);
+        processAllMessages();
+
+        // Verify adjusted RAT preference
+        verifyScanPreferred(DomainSelectionService.SCAN_TYPE_NO_PREFERENCE, GERAN);
+    }
+
+    @Test
+    public void testSimNotReadyAdjustCsRatPreference() throws Exception {
+        doReturn(new String[] {"us"}).when(mResources).getStringArray(
+                eq(R.array.config_countries_prefer_geran_when_sim_absent));
+
+        createSelector(SLOT_0_SUB_ID);
+        unsolBarringInfoChanged(false);
+        // SIM state is not ready.
+        doReturn(TelephonyManager.SIM_STATE_PIN_REQUIRED)
+                .when(mTelephonyManager).getSimState(anyInt());
+
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(EUTRAN,
+                REGISTRATION_STATE_UNKNOWN, 0, false, true, 0, 0, "", "", "us");
+        SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+        mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+        processAllMessages();
+
+        bindImsServiceUnregistered();
+
+        verifyPsDialed();
+
+        mDomainSelector.reselectDomain(attr);
+        processAllMessages();
+
+        // Verify adjusted RAT preference
+        verifyScanPreferred(DomainSelectionService.SCAN_TYPE_NO_PREFERENCE, GERAN);
+    }
+
+    @Test
+    public void testNotAdjustCsRatPreferenceCountryNotIdentified() throws Exception {
+        doReturn(new String[] {"us"}).when(mResources).getStringArray(
+                eq(R.array.config_countries_prefer_geran_when_sim_absent));
+
+        createSelector(SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+        unsolBarringInfoChanged(false);
+
+        // Country is not identified
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(EUTRAN,
+                REGISTRATION_STATE_UNKNOWN, 0, false, true, 0, 0, "", "");
+        // Invalid subscription id
+        SelectionAttributes attr = getSelectionAttributes(SLOT_0,
+                SubscriptionManager.INVALID_SUBSCRIPTION_ID, regResult);
+        mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+        processAllMessages();
+
+        bindImsServiceUnregistered();
+
+        verifyPsDialed();
+
+        mDomainSelector.reselectDomain(attr);
+        processAllMessages();
+
+        // Verify not adjusted RAT preference
+        verifyScanPreferred(DomainSelectionService.SCAN_TYPE_NO_PREFERENCE, UTRAN);
+    }
+
+    @Test
+    public void testNotAdjustCsRatPreferenceValidSubscription() throws Exception {
+        doReturn(new String[] {"us"}).when(mResources).getStringArray(
+                eq(R.array.config_countries_prefer_geran_when_sim_absent));
+
+        createSelector(SLOT_0_SUB_ID);
+        unsolBarringInfoChanged(false);
+
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(EUTRAN,
+                REGISTRATION_STATE_UNKNOWN, 0, false, true, 0, 0, "", "", "us");
+        // Valid subscription id
+        SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+        mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+        processAllMessages();
+
+        bindImsServiceUnregistered();
+
+        verifyPsDialed();
+
+        mDomainSelector.reselectDomain(attr);
+        processAllMessages();
+
+        // Verify not adjusted RAT preference
+        verifyScanPreferred(DomainSelectionService.SCAN_TYPE_NO_PREFERENCE, UTRAN);
+    }
+
+    @Test
+    public void testNotTerminateSelectionAfterCsFailure() throws Exception {
+        mResultConsumer = null;
+        createSelector(SLOT_0_SUB_ID);
+        unsolBarringInfoChanged(false);
+
+        // mcc is identified but it doesn't start with 00.
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(
+                UTRAN, REGISTRATION_STATE_UNKNOWN, 0, false, false, 0, 0, "999", "");
+        SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+        mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+        processAllMessages();
+
+        bindImsServiceUnregistered();
+        processAllMessages();
+
+        verify(mWwanSelectorCallback, times(1)).onDomainSelected(eq(DOMAIN_CS), eq(false));
+
+        SelectionAttributes.Builder builder =
+                new SelectionAttributes.Builder(SLOT_0, SLOT_0_SUB_ID, SELECTOR_TYPE_CALLING)
+                .setAddress(TEST_URI)
+                .setCsDisconnectCause(SERVICE_OPTION_NOT_AVAILABLE)
+                .setEmergency(true)
+                .setEmergencyRegistrationResult(regResult);
+        attr = builder.build();
+        mDomainSelector.reselectDomain(attr);
+        processAllMessages();
+
+        // Verify reselection.
+        verify(mWwanSelectorCallback).onRequestEmergencyNetworkScan(
+                any(), anyInt(), anyBoolean(), any(), any());
+        verify(mTransportSelectorCallback, never())
+                .onSelectionTerminated(eq(DisconnectCause.NOT_VALID));
+    }
+
+    @Test
+    public void testTerminateSelectionAfterCsFailure() throws Exception {
+        mResultConsumer = null;
+        createSelector(SLOT_0_SUB_ID);
+        unsolBarringInfoChanged(false);
+
+        // mcc is identified and it starts with 00.
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(
+                UTRAN, REGISTRATION_STATE_UNKNOWN, 0, false, false, 0, 0, "003", "");
+        SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+        mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+        processAllMessages();
+
+        bindImsServiceUnregistered();
+        processAllMessages();
+
+        verify(mWwanSelectorCallback, times(1)).onDomainSelected(eq(DOMAIN_CS), eq(false));
+
+        SelectionAttributes.Builder builder =
+                new SelectionAttributes.Builder(SLOT_0, SLOT_0_SUB_ID, SELECTOR_TYPE_CALLING)
+                .setAddress(TEST_URI)
+                .setCsDisconnectCause(SERVICE_OPTION_NOT_AVAILABLE)
+                .setEmergency(true)
+                .setEmergencyRegistrationResult(regResult);
+        attr = builder.build();
+        mDomainSelector.reselectDomain(attr);
+        processAllMessages();
+
+        // Verify selection termination.
+        verify(mWwanSelectorCallback, never()).onRequestEmergencyNetworkScan(
+                any(), anyInt(), anyBoolean(), any(), any());
+        verify(mTransportSelectorCallback)
+                .onSelectionTerminated(eq(DisconnectCause.NOT_VALID));
+    }
+
+    @Test
+    public void testTerminateSelectionAfterCsFailureAfterScan() throws Exception {
+        mResultConsumer = null;
+        createSelector(SLOT_0_SUB_ID);
+        unsolBarringInfoChanged(false);
+
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(
+                UNKNOWN, REGISTRATION_STATE_UNKNOWN, 0, false, false, 0, 0, "", "");
+        SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+        mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+        processAllMessages();
+
+        bindImsServiceUnregistered();
+        processAllMessages();
+
+        verify(mTransportSelectorCallback, times(1)).onWwanSelected(any());
+        verify(mWwanSelectorCallback, times(1)).onRequestEmergencyNetworkScan(
+                any(), anyInt(), anyBoolean(), any(), any());
+        assertNotNull(mResultConsumer);
+
+        // mcc is not identified.
+        regResult = getEmergencyRegResult(UTRAN, REGISTRATION_STATE_UNKNOWN,
+                0, false, false, 0, 0, "", "");
+        mResultConsumer.accept(regResult);
+        processAllMessages();
+
+        verify(mWwanSelectorCallback, times(1)).onDomainSelected(eq(DOMAIN_CS), eq(false));
+
+        SelectionAttributes.Builder builder =
+                new SelectionAttributes.Builder(SLOT_0, SLOT_0_SUB_ID, SELECTOR_TYPE_CALLING)
+                .setAddress(TEST_URI)
+                .setCsDisconnectCause(SERVICE_OPTION_NOT_AVAILABLE)
+                .setEmergency(true)
+                .setEmergencyRegistrationResult(regResult);
+        attr = builder.build();
+        mResultConsumer = null;
+        mDomainSelector.reselectDomain(attr);
+        processAllMessages();
+
+        // Verify reselection.
+        verify(mWwanSelectorCallback, times(2)).onRequestEmergencyNetworkScan(
+                any(), anyInt(), anyBoolean(), any(), any());
+        assertNotNull(mResultConsumer);
+
+        // mcc is identified but it doesn't start with 00.
+        regResult = getEmergencyRegResult(UTRAN, REGISTRATION_STATE_UNKNOWN,
+                0, false, false, 0, 0, "999", "");
+        mResultConsumer.accept(regResult);
+        processAllMessages();
+
+        verify(mWwanSelectorCallback, times(2)).onDomainSelected(eq(DOMAIN_CS), eq(false));
+
+        mResultConsumer = null;
+        mDomainSelector.reselectDomain(attr);
+        processAllMessages();
+
+        // Verify reselection.
+        verify(mWwanSelectorCallback, times(3)).onRequestEmergencyNetworkScan(
+                any(), anyInt(), anyBoolean(), any(), any());
+        assertNotNull(mResultConsumer);
+
+        // mcc is identified and it starts with 00.
+        regResult = getEmergencyRegResult(UTRAN, REGISTRATION_STATE_UNKNOWN,
+                0, false, false, 0, 0, "003", "");
+        mResultConsumer.accept(regResult);
+        processAllMessages();
+
+        verify(mWwanSelectorCallback, times(3)).onDomainSelected(eq(DOMAIN_CS), eq(false));
+
+        mDomainSelector.reselectDomain(attr);
+        processAllMessages();
+
+        // Verify selection termination.
+        verify(mWwanSelectorCallback, times(3)).onRequestEmergencyNetworkScan(
+                any(), anyInt(), anyBoolean(), any(), any());
+        verify(mTransportSelectorCallback)
+                .onSelectionTerminated(eq(DisconnectCause.NOT_VALID));
+    }
+
+    @Test
+    public void testMultipleWiFiNetworksAvailable() throws Exception {
+        createSelector(SLOT_0_SUB_ID);
+        unsolBarringInfoChanged(false);
+
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(UNKNOWN,
+                REGISTRATION_STATE_UNKNOWN,
+                0, false, false, 0, 0, "", "");
+        SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+        mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+        processAllMessages();
+
+        bindImsServiceUnregistered();
+
+        verifyScanPsPreferred();
+
+        Network network1 = mock(Network.class);
+
+        // Wi-Fi is connected.
+        mNetworkCallback.onAvailable(network1);
+
+        assertTrue(mDomainSelector.isWiFiAvailable());
+        assertFalse(mDomainSelector.getWiFiNetworksAvailable().isEmpty());
+        assertTrue(mDomainSelector.getWiFiNetworksAvailable().contains(network1));
+
+        // Wi-Fi is lost.
+        mNetworkCallback.onLost(network1);
+
+        assertFalse(mDomainSelector.isWiFiAvailable());
+        assertTrue(mDomainSelector.getWiFiNetworksAvailable().isEmpty());
+
+        Network network2 = mock(Network.class);
+        Network network3 = mock(Network.class);
+
+        // Wi-Fi networks are connected.
+        mNetworkCallback.onAvailable(network2);
+
+        assertTrue(mDomainSelector.isWiFiAvailable());
+        assertFalse(mDomainSelector.getWiFiNetworksAvailable().isEmpty());
+        assertTrue(mDomainSelector.getWiFiNetworksAvailable().contains(network2));
+        assertFalse(mDomainSelector.getWiFiNetworksAvailable().contains(network3));
+
+        mNetworkCallback.onAvailable(network3);
+
+        assertTrue(mDomainSelector.isWiFiAvailable());
+        assertFalse(mDomainSelector.getWiFiNetworksAvailable().isEmpty());
+        assertTrue(mDomainSelector.getWiFiNetworksAvailable().contains(network2));
+        assertTrue(mDomainSelector.getWiFiNetworksAvailable().contains(network3));
+
+        // Wi-Fi network2 is lost.
+        mNetworkCallback.onLost(network2);
+
+        assertTrue(mDomainSelector.isWiFiAvailable());
+        assertFalse(mDomainSelector.getWiFiNetworksAvailable().isEmpty());
+        assertFalse(mDomainSelector.getWiFiNetworksAvailable().contains(network2));
+        assertTrue(mDomainSelector.getWiFiNetworksAvailable().contains(network3));
+
+        // Wi-Fi is unavailable.
+        mNetworkCallback.onUnavailable();
+
+        assertFalse(mDomainSelector.isWiFiAvailable());
+        assertTrue(mDomainSelector.getWiFiNetworksAvailable().isEmpty());
+    }
+
     private void setupForScanListTest(PersistableBundle bundle) throws Exception {
         setupForScanListTest(bundle, false);
     }
diff --git a/tests/src/com/android/services/telephony/domainselection/NormalCallDomainSelectorTest.java b/tests/src/com/android/services/telephony/domainselection/NormalCallDomainSelectorTest.java
index 6e438bf..309418e 100644
--- a/tests/src/com/android/services/telephony/domainselection/NormalCallDomainSelectorTest.java
+++ b/tests/src/com/android/services/telephony/domainselection/NormalCallDomainSelectorTest.java
@@ -48,6 +48,7 @@
 import android.telephony.ims.ImsManager;
 import android.telephony.ims.ImsMmTelManager;
 import android.telephony.ims.ImsReasonInfo;
+import android.testing.TestableLooper;
 import android.util.Log;
 
 import androidx.test.runner.AndroidJUnit4;
@@ -60,7 +61,6 @@
 import org.mockito.MockitoAnnotations;
 
 import java.util.List;
-import java.util.concurrent.Executors;
 import java.util.function.Consumer;
 
 /**
@@ -79,7 +79,7 @@
 
     private HandlerThread mHandlerThread;
     private NormalCallDomainSelector mNormalCallDomainSelector;
-
+    private TestableLooper mTestableLooper;
     @Mock private Context mMockContext;
     @Mock private CarrierConfigManager mMockCarrierConfigMgr;
     @Mock private ImsManager mMockImsManager;
@@ -124,6 +124,12 @@
 
         mNormalCallDomainSelector = new NormalCallDomainSelector(mMockContext, SLOT_ID, SUB_ID_1,
                 mHandlerThread.getLooper(), mMockImsStateTracker, mMockDestroyListener);
+
+        try {
+            setUpTestableLooper();
+        } catch (Exception e) {
+            fail(e.toString());
+        }
     }
 
     @After
@@ -131,6 +137,23 @@
         if (mHandlerThread != null) {
             mHandlerThread.quit();
         }
+
+        if (mTestableLooper != null) {
+            mTestableLooper.destroy();
+            mTestableLooper = null;
+        }
+    }
+
+    private void setUpTestableLooper() throws Exception {
+        mTestableLooper = new TestableLooper(mNormalCallDomainSelector.getLooper());
+    }
+
+    private void processAllMessages() {
+        Log.d(TAG, "processAllMessages - start");
+        while (!mTestableLooper.getLooper().getQueue().isIdle()) {
+            mTestableLooper.processAllMessages();
+        }
+        Log.d(TAG, "processAllMessages - end");
     }
 
     private void initialize(ServiceState serviceState, boolean isImsRegistered,
@@ -154,22 +177,22 @@
 
     @Test
     public void testInitialState() {
-        assertEquals(mNormalCallDomainSelector.getSelectorState(),
-                NormalCallDomainSelector.SelectorState.INACTIVE);
+        assertEquals(NormalCallDomainSelector.SelectorState.INACTIVE,
+                mNormalCallDomainSelector.getSelectorState());
     }
 
     @Test
     public void testDestroyedState() {
         mNormalCallDomainSelector.destroy();
 
-        assertEquals(mNormalCallDomainSelector.getSelectorState(),
-                NormalCallDomainSelector.SelectorState.DESTROYED);
+        assertEquals(NormalCallDomainSelector.SelectorState.DESTROYED,
+                mNormalCallDomainSelector.getSelectorState());
     }
 
     @Test
     public void testDestroyedDuringActiveState() {
-        MockTransportSelectorCallback transportSelectorCallback =
-                new MockTransportSelectorCallback(mNormalCallDomainSelector);
+        TestTransportSelectorCallback transportSelectorCallback =
+                new TestTransportSelectorCallback(mNormalCallDomainSelector);
 
         DomainSelectionService.SelectionAttributes attributes =
                 new DomainSelectionService.SelectionAttributes.Builder(
@@ -183,19 +206,19 @@
 
         mNormalCallDomainSelector.selectDomain(attributes, transportSelectorCallback);
 
-        assertEquals(mNormalCallDomainSelector.getSelectorState(),
-                NormalCallDomainSelector.SelectorState.ACTIVE);
+        assertEquals(NormalCallDomainSelector.SelectorState.ACTIVE,
+                mNormalCallDomainSelector.getSelectorState());
 
         mNormalCallDomainSelector.destroy();
 
-        assertEquals(mNormalCallDomainSelector.getSelectorState(),
-                NormalCallDomainSelector.SelectorState.DESTROYED);
+        assertEquals(NormalCallDomainSelector.SelectorState.DESTROYED,
+                mNormalCallDomainSelector.getSelectorState());
     }
 
     @Test
     public void testSelectDomainInputParams() {
-        MockTransportSelectorCallback transportSelectorCallback =
-                new MockTransportSelectorCallback(mNormalCallDomainSelector);
+        TestTransportSelectorCallback transportSelectorCallback =
+                new TestTransportSelectorCallback(mNormalCallDomainSelector);
 
         DomainSelectionService.SelectionAttributes attributes =
                 new DomainSelectionService.SelectionAttributes.Builder(
@@ -208,8 +231,8 @@
                         .build();
         mNormalCallDomainSelector.selectDomain(attributes, transportSelectorCallback);
 
-        assertEquals(mNormalCallDomainSelector.getSelectorState(),
-                NormalCallDomainSelector.SelectorState.ACTIVE);
+        assertEquals(NormalCallDomainSelector.SelectorState.ACTIVE,
+                mNormalCallDomainSelector.getSelectorState());
 
         // Case 1: null inputs
         try {
@@ -218,8 +241,8 @@
             fail("Invalid input params not handled." + e.getMessage());
         }
 
-        assertEquals(mNormalCallDomainSelector.getSelectorState(),
-                NormalCallDomainSelector.SelectorState.INACTIVE);
+        assertEquals(NormalCallDomainSelector.SelectorState.INACTIVE,
+                mNormalCallDomainSelector.getSelectorState());
 
         // Case 2: null TransportSelectorCallback
         try {
@@ -228,8 +251,8 @@
             fail("Invalid params (SelectionAttributes) not handled." + e.getMessage());
         }
 
-        assertEquals(mNormalCallDomainSelector.getSelectorState(),
-                NormalCallDomainSelector.SelectorState.INACTIVE);
+        assertEquals(NormalCallDomainSelector.SelectorState.INACTIVE,
+                mNormalCallDomainSelector.getSelectorState());
 
         // Case 3: null SelectionAttributes
         transportSelectorCallback.mSelectionTerminated = false;
@@ -239,11 +262,10 @@
             fail("Invalid params (SelectionAttributes) not handled." + e.getMessage());
         }
 
-        assertTrue(transportSelectorCallback
-                .verifyOnSelectionTerminated(DisconnectCause.OUTGOING_FAILURE));
-
-        assertEquals(mNormalCallDomainSelector.getSelectorState(),
-                NormalCallDomainSelector.SelectorState.DESTROYED);
+        assertTrue(transportSelectorCallback.mSelectionTerminated);
+        assertEquals(transportSelectorCallback.mCauseCode, DisconnectCause.OUTGOING_FAILURE);
+        assertEquals(NormalCallDomainSelector.SelectorState.DESTROYED,
+                mNormalCallDomainSelector.getSelectorState());
 
         // Case 4: Invalid Subscription-id
         attributes = new DomainSelectionService.SelectionAttributes.Builder(
@@ -260,11 +282,10 @@
             fail("Invalid params (SelectionAttributes) not handled." + e.getMessage());
         }
 
-        assertTrue(transportSelectorCallback
-                .verifyOnSelectionTerminated(DisconnectCause.OUTGOING_FAILURE));
-
-        assertEquals(mNormalCallDomainSelector.getSelectorState(),
-                NormalCallDomainSelector.SelectorState.DESTROYED);
+        assertTrue(transportSelectorCallback.mSelectionTerminated);
+        assertEquals(transportSelectorCallback.mCauseCode, DisconnectCause.OUTGOING_FAILURE);
+        assertEquals(NormalCallDomainSelector.SelectorState.DESTROYED,
+                mNormalCallDomainSelector.getSelectorState());
 
         // Case 5: Invalid SELECTOR_TYPE
         attributes =
@@ -282,11 +303,10 @@
             fail("Invalid params (SelectionAttributes) not handled." + e.getMessage());
         }
 
-        assertTrue(transportSelectorCallback
-                .verifyOnSelectionTerminated(DisconnectCause.OUTGOING_FAILURE));
-
-        assertEquals(mNormalCallDomainSelector.getSelectorState(),
-                NormalCallDomainSelector.SelectorState.DESTROYED);
+        assertTrue(transportSelectorCallback.mSelectionTerminated);
+        assertEquals(transportSelectorCallback.mCauseCode, DisconnectCause.OUTGOING_FAILURE);
+        assertEquals(NormalCallDomainSelector.SelectorState.DESTROYED,
+                mNormalCallDomainSelector.getSelectorState());
 
         // Case 6: Emergency Call
         attributes = new DomainSelectionService.SelectionAttributes.Builder(
@@ -303,44 +323,52 @@
             fail("Invalid params (SelectionAttributes) not handled." + e.getMessage());
         }
 
-        assertEquals(mNormalCallDomainSelector.getSelectorState(),
-                NormalCallDomainSelector.SelectorState.DESTROYED);
-
-        assertTrue(transportSelectorCallback
-                .verifyOnSelectionTerminated(DisconnectCause.OUTGOING_FAILURE));
+        assertTrue(transportSelectorCallback.mSelectionTerminated);
+        assertEquals(transportSelectorCallback.mCauseCode, DisconnectCause.OUTGOING_FAILURE);
+        assertEquals(NormalCallDomainSelector.SelectorState.DESTROYED,
+                mNormalCallDomainSelector.getSelectorState());
     }
 
     @Test
     public void testOutOfService() {
-        MockTransportSelectorCallback transportSelectorCallback =
-                new MockTransportSelectorCallback(mNormalCallDomainSelector);
-        DomainSelectionService.SelectionAttributes attributes =
-                new DomainSelectionService.SelectionAttributes.Builder(
-                        SLOT_ID, SUB_ID_1, SELECTOR_TYPE_CALLING)
-                        .setAddress(TEST_URI)
-                        .setCallId(TEST_CALLID)
-                        .setEmergency(false)
-                        .setVideoCall(true)
-                        .setExitedFromAirplaneMode(false)
-                        .build();
+        final TestTransportSelectorCallback transportSelectorCallback =
+                new TestTransportSelectorCallback(mNormalCallDomainSelector);
+        mNormalCallDomainSelector.post(() -> {
 
-        ServiceState serviceState = new ServiceState();
-        serviceState.setStateOutOfService();
-        initialize(serviceState, false, false, false, false);
+            DomainSelectionService.SelectionAttributes attributes =
+                    new DomainSelectionService.SelectionAttributes.Builder(
+                            SLOT_ID, SUB_ID_1, SELECTOR_TYPE_CALLING)
+                            .setAddress(TEST_URI)
+                            .setCallId(TEST_CALLID)
+                            .setEmergency(false)
+                            .setVideoCall(true)
+                            .setExitedFromAirplaneMode(false)
+                            .build();
 
-        mNormalCallDomainSelector.selectDomain(attributes, transportSelectorCallback);
+            ServiceState serviceState = new ServiceState();
+            serviceState.setStateOutOfService();
+            initialize(serviceState, false, false, false, false);
 
-        assertTrue(transportSelectorCallback
-                .verifyOnSelectionTerminated(DisconnectCause.OUT_OF_SERVICE));
+            mNormalCallDomainSelector.selectDomain(attributes, transportSelectorCallback);
+        });
 
-        assertEquals(mNormalCallDomainSelector.getSelectorState(),
-                NormalCallDomainSelector.SelectorState.DESTROYED);
+        processAllMessages();
+        assertTrue(transportSelectorCallback.mSelectionTerminated);
+        assertEquals(DisconnectCause.OUT_OF_SERVICE, transportSelectorCallback.mCauseCode);
+
+        assertEquals(NormalCallDomainSelector.SelectorState.DESTROYED,
+                mNormalCallDomainSelector.getSelectorState());
     }
 
     @Test
     public void testDomainSelection() {
-        MockTransportSelectorCallback transportSelectorCallback =
-                new MockTransportSelectorCallback(mNormalCallDomainSelector);
+        final TestTransportSelectorCallback transportSelectorCallback =
+                new TestTransportSelectorCallback(mNormalCallDomainSelector);
+
+        final ServiceState serviceState = new ServiceState();
+        serviceState.setState(ServiceState.STATE_IN_SERVICE);
+        initialize(serviceState, true, true, true, true);
+        transportSelectorCallback.reset();
         DomainSelectionService.SelectionAttributes attributes =
                 new DomainSelectionService.SelectionAttributes.Builder(
                         SLOT_ID, SUB_ID_1, SELECTOR_TYPE_CALLING)
@@ -352,34 +380,17 @@
                         .build();
 
         // Case 1: WLAN
-        ServiceState serviceState = new ServiceState();
-        serviceState.setState(ServiceState.STATE_IN_SERVICE);
-        initialize(serviceState, true, true, true, true);
-
         mNormalCallDomainSelector.selectDomain(attributes, transportSelectorCallback);
 
-        assertTrue(transportSelectorCallback.verifyOnWlanSelected());
-
-        assertEquals(mNormalCallDomainSelector.getSelectorState(),
-                NormalCallDomainSelector.SelectorState.INACTIVE);
+        processAllMessages();
+        assertTrue(transportSelectorCallback.mWlanSelected);
+        assertEquals(NormalCallDomainSelector.SelectorState.INACTIVE,
+                mNormalCallDomainSelector.getSelectorState());
 
         // Case 2: 5G
-        mNormalCallDomainSelector.selectDomain(attributes, transportSelectorCallback);
-
+        serviceState.setState(ServiceState.STATE_IN_SERVICE);
         initialize(serviceState, true, false, true, true);
-        mNormalCallDomainSelector.selectDomain(attributes, transportSelectorCallback);
-
-        assertTrue(transportSelectorCallback.verifyOnWwanSelected());
-
-        assertTrue(transportSelectorCallback
-                .verifyOnDomainSelected(NetworkRegistrationInfo.DOMAIN_PS));
-
-        assertEquals(mNormalCallDomainSelector.getSelectorState(),
-                NormalCallDomainSelector.SelectorState.INACTIVE);
-
-        // Case 3: PS -> CS redial
-        ImsReasonInfo imsReasonInfo = new ImsReasonInfo();
-        imsReasonInfo.mCode = ImsReasonInfo.CODE_LOCAL_CALL_CS_RETRY_REQUIRED;
+        transportSelectorCallback.reset();
         attributes = new DomainSelectionService.SelectionAttributes.Builder(
                 SLOT_ID, SUB_ID_1, SELECTOR_TYPE_CALLING)
                 .setAddress(TEST_URI)
@@ -387,54 +398,89 @@
                 .setEmergency(false)
                 .setVideoCall(false)
                 .setExitedFromAirplaneMode(false)
-                .setPsDisconnectCause(imsReasonInfo)
+                .build();
+
+        mNormalCallDomainSelector.selectDomain(attributes, transportSelectorCallback);
+
+        processAllMessages();
+        assertTrue(transportSelectorCallback.mWwanSelected);
+        assertEquals(NetworkRegistrationInfo.DOMAIN_PS, transportSelectorCallback.mSelectedDomain);
+        assertEquals(NormalCallDomainSelector.SelectorState.INACTIVE,
+                mNormalCallDomainSelector.getSelectorState());
+
+
+        // Case 3: PS -> CS redial
+        final ImsReasonInfo imsReasonInfoCsRetry = new ImsReasonInfo(
+                ImsReasonInfo.CODE_LOCAL_CALL_CS_RETRY_REQUIRED, 0, null);
+        transportSelectorCallback.reset();
+        attributes = new DomainSelectionService.SelectionAttributes.Builder(
+                SLOT_ID, SUB_ID_1, SELECTOR_TYPE_CALLING)
+                .setAddress(TEST_URI)
+                .setCallId(TEST_CALLID)
+                .setEmergency(false)
+                .setVideoCall(false)
+                .setExitedFromAirplaneMode(false)
+                .setPsDisconnectCause(imsReasonInfoCsRetry)
                 .build();
 
         mNormalCallDomainSelector.reselectDomain(attributes);
 
-        assertTrue(transportSelectorCallback
-                .verifyOnDomainSelected(NetworkRegistrationInfo.DOMAIN_CS));
-
-        assertEquals(mNormalCallDomainSelector.getSelectorState(),
-                NormalCallDomainSelector.SelectorState.INACTIVE);
+        processAllMessages();
+        assertEquals(transportSelectorCallback.mSelectedDomain, NetworkRegistrationInfo.DOMAIN_CS);
+        assertEquals(NormalCallDomainSelector.SelectorState.INACTIVE,
+                mNormalCallDomainSelector.getSelectorState());
 
         // Case 4: CS call
+        transportSelectorCallback.reset();
+        initialize(serviceState, false, false, false, false);
         NetworkRegistrationInfo nwRegistrationInfo = new NetworkRegistrationInfo(
                 NetworkRegistrationInfo.DOMAIN_CS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
                 NetworkRegistrationInfo.REGISTRATION_STATE_HOME,
                 AccessNetworkConstants.AccessNetworkType.UTRAN, 0, false,
                 null, null, null, false, 0, 0, 0);
         serviceState.addNetworkRegistrationInfo(nwRegistrationInfo);
+        attributes = new DomainSelectionService.SelectionAttributes.Builder(
+                SLOT_ID, SUB_ID_1, SELECTOR_TYPE_CALLING)
+                .setAddress(TEST_URI)
+                .setCallId(TEST_CALLID)
+                .setEmergency(false)
+                .setVideoCall(false)
+                .setExitedFromAirplaneMode(false)
+                .setPsDisconnectCause(imsReasonInfoCsRetry)
+                .build();
 
         mNormalCallDomainSelector.selectDomain(attributes, transportSelectorCallback);
 
-        initialize(serviceState, false, false, false, false);
-        mNormalCallDomainSelector.selectDomain(attributes, transportSelectorCallback);
-
-        assertTrue(transportSelectorCallback.verifyOnWwanSelected());
-
-        assertTrue(transportSelectorCallback
-                .verifyOnDomainSelected(NetworkRegistrationInfo.DOMAIN_CS));
-
-        assertEquals(mNormalCallDomainSelector.getSelectorState(),
-                NormalCallDomainSelector.SelectorState.INACTIVE);
+        processAllMessages();
+        assertEquals(transportSelectorCallback.mSelectedDomain, NetworkRegistrationInfo.DOMAIN_CS);
+        assertEquals(NormalCallDomainSelector.SelectorState.INACTIVE,
+                mNormalCallDomainSelector.getSelectorState());
 
         //Case 5: Backup calling
         serviceState.setStateOutOfService();
+        transportSelectorCallback.reset();
+        attributes = new DomainSelectionService.SelectionAttributes.Builder(
+                SLOT_ID, SUB_ID_1, SELECTOR_TYPE_CALLING)
+                .setAddress(TEST_URI)
+                .setCallId(TEST_CALLID)
+                .setEmergency(false)
+                .setVideoCall(false)
+                .setExitedFromAirplaneMode(false)
+                .setPsDisconnectCause(imsReasonInfoCsRetry)
+                .build();
         initialize(serviceState, true, true, true, true);
-
         mNormalCallDomainSelector.selectDomain(attributes, transportSelectorCallback);
 
-        assertTrue(transportSelectorCallback.verifyOnWlanSelected());
-
-        assertEquals(mNormalCallDomainSelector.getSelectorState(),
-                NormalCallDomainSelector.SelectorState.ACTIVE);
+        processAllMessages();
+        assertTrue(transportSelectorCallback.mWlanSelected);
+        assertEquals(NormalCallDomainSelector.SelectorState.INACTIVE,
+                mNormalCallDomainSelector.getSelectorState());
     }
 
     @Test
     public void testWPSCallDomainSelection() {
-        MockTransportSelectorCallback transportSelectorCallback =
-                new MockTransportSelectorCallback(mNormalCallDomainSelector);
+        TestTransportSelectorCallback transportSelectorCallback =
+                new TestTransportSelectorCallback(mNormalCallDomainSelector);
         DomainSelectionService.SelectionAttributes attributes =
                 new DomainSelectionService.SelectionAttributes.Builder(
                         SLOT_ID, SUB_ID_1, SELECTOR_TYPE_CALLING)
@@ -457,46 +503,43 @@
 
         mNormalCallDomainSelector.selectDomain(attributes, transportSelectorCallback);
 
-        assertTrue(transportSelectorCallback.verifyOnWwanSelected());
-
-        assertTrue(transportSelectorCallback
-                .verifyOnDomainSelected(NetworkRegistrationInfo.DOMAIN_CS));
-
-        assertEquals(mNormalCallDomainSelector.getSelectorState(),
-                NormalCallDomainSelector.SelectorState.INACTIVE);
+        processAllMessages();
+        assertTrue(transportSelectorCallback.mWwanSelected);
+        assertEquals(transportSelectorCallback.mSelectedDomain, NetworkRegistrationInfo.DOMAIN_CS);
+        assertEquals(NormalCallDomainSelector.SelectorState.INACTIVE,
+                mNormalCallDomainSelector.getSelectorState());
 
         //Case 2: WPS supported by IMS and WLAN registered
+        transportSelectorCallback.reset();
         config.putBoolean(CarrierConfigManager.KEY_SUPPORT_WPS_OVER_IMS_BOOL, true);
         serviceState.setState(ServiceState.STATE_IN_SERVICE);
         initialize(serviceState, true, true, true, true);
 
         mNormalCallDomainSelector.selectDomain(attributes, transportSelectorCallback);
 
-        assertTrue(transportSelectorCallback.verifyOnWlanSelected());
-
+        processAllMessages();
+        assertTrue(transportSelectorCallback.mWlanSelected);
         assertEquals(mNormalCallDomainSelector.getSelectorState(),
                 NormalCallDomainSelector.SelectorState.INACTIVE);
 
         //Case 2: WPS supported by IMS and LTE registered
+        transportSelectorCallback.reset();
         config.putBoolean(CarrierConfigManager.KEY_SUPPORT_WPS_OVER_IMS_BOOL, true);
         serviceState.setState(ServiceState.STATE_IN_SERVICE);
         initialize(serviceState, true, false, true, true);
 
         mNormalCallDomainSelector.selectDomain(attributes, transportSelectorCallback);
 
-        assertTrue(transportSelectorCallback.verifyOnWwanSelected());
-
-        assertTrue(transportSelectorCallback
-                .verifyOnDomainSelected(NetworkRegistrationInfo.DOMAIN_PS));
-
-        assertEquals(mNormalCallDomainSelector.getSelectorState(),
-                NormalCallDomainSelector.SelectorState.INACTIVE);
+        processAllMessages();
+        assertEquals(transportSelectorCallback.mSelectedDomain, NetworkRegistrationInfo.DOMAIN_PS);
+        assertEquals(NormalCallDomainSelector.SelectorState.INACTIVE,
+                mNormalCallDomainSelector.getSelectorState());
     }
 
     @Test
     public void testTtyCallDomainSelection() {
-        MockTransportSelectorCallback transportSelectorCallback =
-                new MockTransportSelectorCallback(mNormalCallDomainSelector);
+        TestTransportSelectorCallback transportSelectorCallback =
+                new TestTransportSelectorCallback(mNormalCallDomainSelector);
         DomainSelectionService.SelectionAttributes attributes =
                 new DomainSelectionService.SelectionAttributes.Builder(
                         SLOT_ID, SUB_ID_1, SELECTOR_TYPE_CALLING)
@@ -520,42 +563,34 @@
 
         mNormalCallDomainSelector.selectDomain(attributes, transportSelectorCallback);
 
-        assertTrue(transportSelectorCallback.verifyOnWwanSelected());
-
-        assertTrue(transportSelectorCallback
-                .verifyOnDomainSelected(NetworkRegistrationInfo.DOMAIN_CS));
-
-        assertEquals(mNormalCallDomainSelector.getSelectorState(),
-                NormalCallDomainSelector.SelectorState.INACTIVE);
+        processAllMessages();
+        assertTrue(transportSelectorCallback.mWwanSelected);
+        assertEquals(transportSelectorCallback.mSelectedDomain, NetworkRegistrationInfo.DOMAIN_CS);
+        assertEquals(NormalCallDomainSelector.SelectorState.INACTIVE,
+                mNormalCallDomainSelector.getSelectorState());
 
         //Case 2: TTY supported by IMS and TTY enabled
+        transportSelectorCallback.reset();
         config.putBoolean(CarrierConfigManager.KEY_CARRIER_VOLTE_TTY_SUPPORTED_BOOL, true);
         mNormalCallDomainSelector.selectDomain(attributes, transportSelectorCallback);
 
-        assertTrue(transportSelectorCallback.verifyOnWwanSelected());
-
-        assertTrue(transportSelectorCallback
-                .verifyOnDomainSelected(NetworkRegistrationInfo.DOMAIN_PS));
-
-        assertEquals(mNormalCallDomainSelector.getSelectorState(),
-                NormalCallDomainSelector.SelectorState.INACTIVE);
+        processAllMessages();
+        assertEquals(transportSelectorCallback.mSelectedDomain, NetworkRegistrationInfo.DOMAIN_PS);
+        assertEquals(NormalCallDomainSelector.SelectorState.INACTIVE,
+                mNormalCallDomainSelector.getSelectorState());
 
         //Case 3: TTY supported by IMS and TTY disabled
+        transportSelectorCallback.reset();
         doReturn(TelecomManager.TTY_MODE_OFF).when(mMockTelecomManager).getCurrentTtyMode();
         mNormalCallDomainSelector.selectDomain(attributes, transportSelectorCallback);
 
-        assertTrue(transportSelectorCallback.verifyOnWwanSelected());
-
-        assertTrue(transportSelectorCallback
-                .verifyOnDomainSelected(NetworkRegistrationInfo.DOMAIN_PS));
-
-        assertEquals(mNormalCallDomainSelector.getSelectorState(),
-                NormalCallDomainSelector.SelectorState.INACTIVE);
+        processAllMessages();
+        assertEquals(transportSelectorCallback.mSelectedDomain, NetworkRegistrationInfo.DOMAIN_PS);
+        assertEquals(NormalCallDomainSelector.SelectorState.INACTIVE,
+                mNormalCallDomainSelector.getSelectorState());
     }
 
-
-
-    static class MockTransportSelectorCallback implements TransportSelectorCallback,
+    static class TestTransportSelectorCallback implements TransportSelectorCallback,
             WwanSelectorCallback {
         public boolean mCreated;
         public boolean mWlanSelected;
@@ -566,8 +601,9 @@
         int mSelectedDomain;
         NormalCallDomainSelector mNormalCallDomainSelector;
 
-        MockTransportSelectorCallback(NormalCallDomainSelector normalCallDomainSelector) {
+        TestTransportSelectorCallback(NormalCallDomainSelector normalCallDomainSelector) {
             mNormalCallDomainSelector = normalCallDomainSelector;
+            mCauseCode = DisconnectCause.NOT_VALID;
         }
 
         @Override
@@ -575,50 +611,21 @@
             Log.d(TAG, "onCreated");
             mCreated = true;
 
-            assertEquals(mNormalCallDomainSelector.getSelectorState(),
-                    NormalCallDomainSelector.SelectorState.INACTIVE);
-
-            notifyAll();
-        }
-
-        public boolean verifyOnCreated() {
-            mCreated = false;
-            Log.d(TAG, "verifyOnCreated");
-            waitForCallback(mCreated);
-            return mCreated;
+            assertEquals(NormalCallDomainSelector.SelectorState.INACTIVE,
+                    mNormalCallDomainSelector.getSelectorState());
         }
 
         @Override
         public synchronized void onWlanSelected(boolean useEmergencyPdn) {
             Log.d(TAG, "onWlanSelected");
             mWlanSelected = true;
-
-            assertEquals(mNormalCallDomainSelector.getSelectorState(),
-                    NormalCallDomainSelector.SelectorState.INACTIVE);
-
-            notifyAll();
-        }
-
-        public boolean verifyOnWlanSelected() {
-            Log.d(TAG, "verifyOnWlanSelected");
-            waitForCallback(mWlanSelected);
-            return mWlanSelected;
         }
 
         @Override
         public void onWwanSelected(final Consumer<WwanSelectorCallback> consumer) {
+            Log.d(TAG, "onWwanSelected");
             mWwanSelected = true;
-            Executors.newSingleThreadExecutor().execute(() -> {
-                consumer.accept(this);
-            });
-
-            assertEquals(mNormalCallDomainSelector.getSelectorState(),
-                    NormalCallDomainSelector.SelectorState.INACTIVE);
-        }
-
-        public boolean verifyOnWwanSelected() {
-            waitForCallback(mWwanSelected);
-            return mWwanSelected;
+            consumer.accept(this);
         }
 
         @Override
@@ -627,31 +634,12 @@
             mCauseCode = cause;
             mSelectionTerminated = true;
 
-            assertEquals(mNormalCallDomainSelector.getSelectorState(),
-                    NormalCallDomainSelector.SelectorState.INACTIVE);
+            assertEquals(NormalCallDomainSelector.SelectorState.INACTIVE,
+                    mNormalCallDomainSelector.getSelectorState());
 
             notifyAll();
         }
 
-        public boolean verifyOnSelectionTerminated(int cause) {
-            Log.i(TAG, "verifyOnSelectionTerminated - called");
-            waitForCallback(mSelectionTerminated);
-            return (mSelectionTerminated && cause == mCauseCode);
-        }
-
-        private synchronized void waitForCallback(boolean condition) {
-            long now = System.currentTimeMillis();
-            long deadline = now + 1000;
-            try {
-                while (!condition && now < deadline) {
-                    wait(deadline - now);
-                    now = System.currentTimeMillis();
-                }
-            } catch (Exception e) {
-                Log.i(TAG, e.getMessage());
-            }
-        }
-
         @Override
         public void onRequestEmergencyNetworkScan(@NonNull List<Integer> preferredNetworks,
                 int scanType,
@@ -668,17 +656,19 @@
             mSelectedDomain = domain;
             mDomainSelected = true;
 
-            assertEquals(mNormalCallDomainSelector.getSelectorState(),
-                    NormalCallDomainSelector.SelectorState.INACTIVE);
+            assertEquals(NormalCallDomainSelector.SelectorState.INACTIVE,
+                    mNormalCallDomainSelector.getSelectorState());
 
             notifyAll();
         }
-
-        public boolean verifyOnDomainSelected(int domain) {
-            Log.i(TAG, "verifyOnDomainSelected - called");
+        public void reset() {
+            mCreated = false;
+            mWlanSelected = false;
+            mWwanSelected = false;
+            mSelectionTerminated = false;
             mDomainSelected = false;
-            waitForCallback(mDomainSelected);
-            return (domain == mSelectedDomain);
+            mCauseCode = DisconnectCause.NOT_VALID;
+            mSelectedDomain = NetworkRegistrationInfo.DOMAIN_UNKNOWN;
         }
     }
 }