[automerger skipped] DO NOT MERGE Grant carrier privileges if package has carrier config access. am: 213aba7e18 am: 42ad104329 -s ours am: b64e63b2e7 -s ours am: 54e8348939 -s ours am: 8e20cf2cc6 -s ours am: 4deb808247 -s ours am: d2851521e3 -s ours am: 431db290e1 -s ours am: 02f9786911 -s ours am: 52aeeae4ed -s ours

am skip reason: subject contains skip directive

Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/services/Telephony/+/20315707

Change-Id: Ice4ab86698f2a8d99a54ca5e3d60e9d5c6112ecb
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/res/values-bs/strings.xml b/res/values-bs/strings.xml
index c8b5ae4..22c5af4 100644
--- a/res/values-bs/strings.xml
+++ b/res/values-bs/strings.xml
@@ -928,7 +928,7 @@
     <string name="notification_channel_sip_account" msgid="1261816025156179637">"Zastarjeli SIP računi"</string>
     <string name="send_from_work_profile_title" msgid="7044759579507604732">"Nije moguće poslati poruku iz lične aplikacije"</string>
     <string name="send_from_work_profile_description" msgid="2174402508727161974">"Vaša organizacija vam dozvoljava da šaljete poruke samo iz poslovnih aplikacija"</string>
-    <string name="send_from_work_profile_cancel" msgid="177746511030381711">"Odustani"</string>
-    <string name="send_from_work_profile_action_str" msgid="6892775562934243337">"Prelazak na poslovni profil"</string>
+    <string name="send_from_work_profile_cancel" msgid="177746511030381711">"Otkaži"</string>
+    <string name="send_from_work_profile_action_str" msgid="6892775562934243337">"Pređite na radni profil"</string>
     <string name="install_messages_on_work_profile_action_str" msgid="3773440996395152903">"Instalirajte poslovnu aplikaciju za razmjenu poruka"</string>
 </resources>
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index cf22b1b..722b227 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -594,7 +594,7 @@
     <string name="importToFDNfromContacts" msgid="5068664870738407341">"Aus Kontakten importieren"</string>
     <string name="singleContactImportedMsg" msgid="3619804066300998934">"Kontakt wird importiert."</string>
     <string name="failedToImportSingleContactMsg" msgid="228095510489830266">"Fehler beim Importieren des Kontakts"</string>
-    <string name="hac_mode_title" msgid="4127986689621125468">"Hörhilfen"</string>
+    <string name="hac_mode_title" msgid="4127986689621125468">"Hörgeräte"</string>
     <string name="hac_mode_summary" msgid="7774989500136009881">"Hörhilfekompatibilität aktivieren"</string>
     <string name="rtt_mode_title" msgid="3075948111362818043">"RTT-Anruf"</string>
     <string name="rtt_mode_summary" msgid="8631541375609989562">"Nachrichten in Sprachanrufen erlauben"</string>
diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml
index f69788a..ee17505 100644
--- a/res/values-es/strings.xml
+++ b/res/values-es/strings.xml
@@ -187,9 +187,9 @@
     <string name="manual_mode_disallowed_summary" msgid="3970048592179890197">"No disponible cuando se ha conectado con %1$s"</string>
     <string name="network_select_title" msgid="4117305053881611988">"Red"</string>
     <string name="register_automatically" msgid="3907580547590554834">"Registro automático..."</string>
-    <string name="preferred_network_mode_title" msgid="5253395265169539830">"Tipo de red preferida"</string>
+    <string name="preferred_network_mode_title" msgid="5253395265169539830">"Tipo de red preferido"</string>
     <string name="preferred_network_mode_summary" msgid="3787989000044330064">"Cambiar el modo operativo de la red"</string>
-    <string name="preferred_network_mode_dialogtitle" msgid="2781447433514459696">"Tipo de red preferida"</string>
+    <string name="preferred_network_mode_dialogtitle" msgid="2781447433514459696">"Tipo de red preferido"</string>
     <string name="forbidden_network" msgid="5081729819561333023">"(prohibida)"</string>
     <string name="choose_network_title" msgid="5335832663422653082">"Elegir red"</string>
     <string name="network_disconnected" msgid="8844141106841160825">"Desconectado"</string>
diff --git a/res/values-eu/strings.xml b/res/values-eu/strings.xml
index f317d50..3b64c20 100644
--- a/res/values-eu/strings.xml
+++ b/res/values-eu/strings.xml
@@ -96,10 +96,10 @@
     <string name="sum_loading_settings" msgid="434063780286688775">"Ezarpenak kargatzen…"</string>
     <string name="sum_hide_caller_id" msgid="131100328602371933">"Ezkutatu zenbakia irteerako deietan"</string>
     <string name="sum_show_caller_id" msgid="3571854755324664591">"Erakutsi zenbakia irteerako deietan"</string>
-    <string name="sum_default_caller_id" msgid="1767070797135682959">"Erabili operadorearen ezarpen lehenetsiak, egiten ditudan deietan nire zenbakia erakusteko"</string>
+    <string name="sum_default_caller_id" msgid="1767070797135682959">"Erabili operadorearen ezarpen lehenetsiak, irteerako deietan nire zenbakia erakusteko"</string>
     <string name="labelCW" msgid="8449327023861428622">"Deiak zain"</string>
-    <string name="sum_cw_enabled" msgid="3977308526187139996">"Deiak abian dauden bitartean, eman jasotzen ditudan deien berri"</string>
-    <string name="sum_cw_disabled" msgid="3658094589461768637">"Deiak abian dauden bitartean, eman jasotzen ditudan deien berri"</string>
+    <string name="sum_cw_enabled" msgid="3977308526187139996">"Deiak abian dauden bitartean, eman sarrerako deien berri"</string>
+    <string name="sum_cw_disabled" msgid="3658094589461768637">"Deiak abian dauden bitartean, eman sarrerako deien berri"</string>
     <string name="call_forwarding_settings" msgid="8937130467468257671">"Dei-desbideratzearen ezarpenak"</string>
     <string name="call_forwarding_settings_with_label" msgid="2345432813399564272">"Deiak desbideratzeko ezarpenak (<xliff:g id="SUBSCRIPTIONLABEL">%s</xliff:g>)"</string>
     <string name="labelCF" msgid="3578719437928476078">"Dei-desbideratzea"</string>
@@ -126,7 +126,7 @@
     <string name="disable_cfnrc_forbidden" msgid="775348748084726890">"Operadoreak ez du dei-desbideratzeak desgaitzea onartzen telefonoa eskuragarri ez dagoen bitartean."</string>
     <string name="registration_cf_forbidden" msgid="4386482610771190420">"Operadoreak ez du onartzen dei-desbideratzea."</string>
     <string name="cdma_call_waiting" msgid="4565070960879673216">"Deia zain uzteko aukera aktibatu nahi duzu?"</string>
-    <string name="enable_cdma_call_waiting_setting" msgid="5906811747921744307">"Dei batean zaudenean, jakinarazpen bat jasoko duzu deiak jasotzen badituzu"</string>
+    <string name="enable_cdma_call_waiting_setting" msgid="5906811747921744307">"Dei batean zaudenean, jakinarazpen bat jasoko duzu sarrerako deiak jasotzen badituzu"</string>
     <string name="enable_cdma_cw" msgid="811047045863422232">"Aktibatu"</string>
     <string name="disable_cdma_cw" msgid="7119290446496301734">"Utzi"</string>
     <string name="cdma_call_waiting_in_ims_on" msgid="6390979414188659218">"IMS zerbitzupean CDMA deiak zain uzteko aukera aktibatuta dago"</string>
@@ -157,8 +157,8 @@
     <item msgid="9150034130629852635">"Erakutsi zenbakia"</item>
   </string-array>
     <string name="vm_changed" msgid="4739599044379692505">"Erantzungailuaren zenbakia aldatu da."</string>
-    <string name="vm_change_failed" msgid="7877733929455763566">"Ezin izan da erantzungailuaren zenbakia aldatu.\nArazoak bere horretan badirau, jarri harremanetan operadorearekin."</string>
-    <string name="fw_change_failed" msgid="9179241823460192148">"Ezin izan da desbideratze-zenbakia aldatu.\nArazoak bere horretan jarraitzen badu, jarri harremanetan operadorearekin."</string>
+    <string name="vm_change_failed" msgid="7877733929455763566">"Ezin izan da erantzungailuaren zenbakia aldatu.\nArazoak bere horretan badirau, jarri operadorearekin harremanetan."</string>
+    <string name="fw_change_failed" msgid="9179241823460192148">"Ezin izan da desbideratze-zenbakia aldatu.\nArazoak bere horretan jarraitzen badu, jarri operadorearekin harremanetan."</string>
     <string name="fw_get_in_vm_failed" msgid="2432678237218183844">"Ezin izan dira desbideratze-zenbakiaren ezarpenak eskuratu eta gorde.\nHala ere, hornitzaile berrira aldatu nahi duzu?"</string>
     <string name="no_change" msgid="3737264882821031892">"Ez da aldaketarik egin."</string>
     <string name="sum_voicemail_choose_provider" msgid="6750824719081403773">"Aukeratu erantzungailu-zerbitzua"</string>
@@ -769,8 +769,8 @@
     <string name="sum_call_barring_enabled" msgid="5184331188926370824">"Aktibatuta"</string>
     <string name="sum_call_barring_disabled" msgid="5699448000600153096">"Desaktibatuta"</string>
     <string name="call_barring_baoc" msgid="7400892586336429326">"Egindako guztiak"</string>
-    <string name="call_barring_baoc_enabled" msgid="3131509193386668182">"Egindako dei guztiak blokeatzeko aukera desgaitu nahi duzu?"</string>
-    <string name="call_barring_baoc_disabled" msgid="8534224684091141509">"Egindako dei guztiak blokeatu nahi dituzu?"</string>
+    <string name="call_barring_baoc_enabled" msgid="3131509193386668182">"Irteerako dei guztiak blokeatzeko aukera desgaitu nahi duzu?"</string>
+    <string name="call_barring_baoc_disabled" msgid="8534224684091141509">"Irteerako dei guztiak blokeatu nahi dituzu?"</string>
     <string name="call_barring_baoic" msgid="8668125428666851665">"Nazioartean egindakoak"</string>
     <string name="call_barring_baoic_enabled" msgid="1203758092657630123">"Nazioartean egindako deiak blokeatzeko aukera desgaitu nahi duzu?"</string>
     <string name="call_barring_baoic_disabled" msgid="5656889339002997449">"Nazioartean egindako deiak blokeatu nahi dituzu?"</string>
@@ -778,8 +778,8 @@
     <string name="call_barring_baoicr_enabled" msgid="1615324165512798478">"Nazioarteko ibiltaritzan egindako deiak blokeatzeko aukera desgaitu nahi duzu?"</string>
     <string name="call_barring_baoicr_disabled" msgid="172010175248142831">"Nazioarteko ibiltaritzan egindako deiak blokeatu nahi dituzu?"</string>
     <string name="call_barring_baic" msgid="7941393541678658566">"Jasotako guztiak"</string>
-    <string name="call_barring_baic_enabled" msgid="4357332358020337470">"Jasotako dei guztiak blokeatzeko aukera desgaitu nahi duzu?"</string>
-    <string name="call_barring_baic_disabled" msgid="2355945245938240958">"Jasotako dei guztiak blokeatu nahi dituzu?"</string>
+    <string name="call_barring_baic_enabled" msgid="4357332358020337470">"Sarrerako dei guztiak blokeatzeko aukera desgaitu nahi duzu?"</string>
+    <string name="call_barring_baic_disabled" msgid="2355945245938240958">"Sarrerako dei guztiak blokeatu nahi dituzu?"</string>
     <string name="call_barring_baicr" msgid="8712249337313034226">"Nazioarteko ibiltaritzan jasotakoak"</string>
     <string name="call_barring_baicr_enabled" msgid="64774270234828175">"Nazioarteko ibiltaritzan jasotako dei guztiak blokeatzeko aukera desgaitu nahi duzu?"</string>
     <string name="call_barring_baicr_disabled" msgid="3488129262744027262">"Nazioarteko ibiltaritzan jasotako deiak blokeatu nahi dituzu?"</string>
@@ -804,8 +804,8 @@
     <string name="supp_service_notification_call_waiting" msgid="4577403881609445324">"Deia zain dago."</string>
     <string name="supp_service_clir_suppression_rejected" msgid="6105737020194776121">"Sareak zenbakia blokeatzeko aukera baztertu du."</string>
     <string name="supp_service_closed_user_group_call" msgid="2811636666505250689">"Erabiltzaile talde itxi baten deia."</string>
-    <string name="supp_service_incoming_calls_barred" msgid="2034627421274447674">"Debekatu da deiak jasotzea."</string>
-    <string name="supp_service_outgoing_calls_barred" msgid="5205725332394087112">"Debekatu da deiak egitea."</string>
+    <string name="supp_service_incoming_calls_barred" msgid="2034627421274447674">"Debekatu dira sarrerako deiak."</string>
+    <string name="supp_service_outgoing_calls_barred" msgid="5205725332394087112">"Debekatu dira irteerako deiak."</string>
     <string name="supp_service_call_forwarding_active" msgid="7910162960395132464">"Aktibatu da dei-desbideratzea."</string>
     <string name="supp_service_additional_call_forwarded" msgid="8772753260008398632">"Desbideratu da jasotako beste deia."</string>
     <string name="supp_service_additional_ect_connected" msgid="8525934162945220237">"Transferitu da deia."</string>
@@ -817,8 +817,8 @@
     <string name="supp_service_conference_call" msgid="4004193534408317148">"Konferentzia-deian sartzen."</string>
     <string name="supp_service_held_call_released" msgid="2847835124639112410">"Askatu da zain utzitako deia."</string>
     <string name="callFailed_otasp_provisioning_in_process" msgid="3345666183602879326">"Ezin da egin deia, une honetan gailua hornitzen ari delako."</string>
-    <string name="callFailed_already_dialing" msgid="7250591188960691086">"Ezin da egin deia, beste dei bat abian delako."</string>
-    <string name="callFailed_already_ringing" msgid="2376603543544289303">"Ezin da egin deia, oraindik erantzun ez diozun dei bat jasotzen ari zarelako. Beste dei bat egin aurretik, erantzun deiari edo bazter ezazu."</string>
+    <string name="callFailed_already_dialing" msgid="7250591188960691086">"Ezin da egin deia, irteerako beste dei bat abian delako."</string>
+    <string name="callFailed_already_ringing" msgid="2376603543544289303">"Ezin da egin deia, oraindik erantzun ez diozun sarrerako dei bat baitago. Beste dei bat egin aurretik, erantzun sarrerako deiari edo bazter ezazu."</string>
     <string name="callFailed_calling_disabled" msgid="5010992739401206283">"Ezin da egin deia, deiak egiteko aukera desgaitu egin delako sistemaren ro.telephony.disable-call propietatea erabilita."</string>
     <string name="callFailed_too_many_calls" msgid="2761754044990799580">"Ezin da egin deia, dagoeneko bi dei daudelako abian. Beste dei bat egin aurretik, eten deietako bat edo bateratu deiak konferentzia-dei bakarrean."</string>
     <string name="supp_service_over_ut_precautions" msgid="2145018231396701311">"<xliff:g id="SUPP_SERVICE">%s</xliff:g> erabiltzeko, ziurtatu datu-konexioa aktibatuta dagoela. Sare mugikorren ezarpenetan alda dezakezu aukera hau."</string>
diff --git a/res/values-kn/strings.xml b/res/values-kn/strings.xml
index 4e2da8a..dc25d7c 100644
--- a/res/values-kn/strings.xml
+++ b/res/values-kn/strings.xml
@@ -924,7 +924,7 @@
     <string name="carrier_provisioning" msgid="2668065041869578376">"ವಾಹಕ ಪೂರೈಕೆಯ ಮಾಹಿತಿ"</string>
     <string name="trigger_carrier_provisioning" msgid="1301829588620638234">"ಟ್ರಿಗರ್‌ ವಾಹಕ ಪೂರೈಕೆ"</string>
     <string name="call_quality_notification_bluetooth_details" msgid="8348950331707346711">"ನಿಮ್ಮ ಬ್ಲೂಟೂತ್ ಸಿಗ್ನಲ್ ದುರ್ಬಲವಾಗಿದೆ. ಸ್ಪೀಕರ್‌ಫೋನ್‌ಗೆ ಬದಲಾಯಿಸಲು ಪ್ರಯತ್ನಿಸಿ."</string>
-    <string name="call_quality_notification_name" msgid="3476828289553948830">"ಕರೆ ಗುಣಮಟ್ಟದ ಅಧಿಸೂಚನೆ"</string>
+    <string name="call_quality_notification_name" msgid="3476828289553948830">"ಕರೆ ಗುಣಮಟ್ಟದ ನೋಟಿಫಿಕೇಶನ್"</string>
     <string name="notification_channel_sip_account" msgid="1261816025156179637">"ತಡೆಹಿಡಿಯಲಾಗಿರುವ SIP ಖಾತೆಗಳು"</string>
     <string name="send_from_work_profile_title" msgid="7044759579507604732">"ವೈಯಕ್ತಿಕ ಆ್ಯಪ್‌ನಿಂದ ಸಂದೇಶವನ್ನು ಕಳುಹಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
     <string name="send_from_work_profile_description" msgid="2174402508727161974">"ನಿಮ್ಮ ಸಂಸ್ಥೆಯು ಕೆಲಸಕ್ಕೆ ಸಂಬಂಧಿಸಿದ ಆ್ಯಪ್‌ಗಳಿಂದ ಮಾತ್ರ ಸಂದೇಶಗಳನ್ನು ಕಳುಹಿಸಲು ನಿಮಗೆ ಅನುಮತಿಸುತ್ತದೆ"</string>
diff --git a/res/values-ky/strings.xml b/res/values-ky/strings.xml
index 861f066..9272c31 100644
--- a/res/values-ky/strings.xml
+++ b/res/values-ky/strings.xml
@@ -476,7 +476,7 @@
     <string name="delete_fdn_contact" msgid="7027405651994507077">"Туруктуу терүү номерин жок кылуу"</string>
     <string name="deleting_fdn_contact" msgid="6872320570844460428">"Туруктуу терүү номери жок кылынууда…"</string>
     <string name="fdn_contact_deleted" msgid="1680714996763848838">"Туруктуу терүү номери өчүрүлдү."</string>
-    <string name="pin2_invalid" msgid="2313954262684494442">"БНТ жаңырган жок, анткени туура эмес PIN-код киргизилди."</string>
+    <string name="pin2_invalid" msgid="2313954262684494442">"БНТ жаңырган жок, анткени туура эмес PIN код киргизилди."</string>
     <string name="fdn_invalid_number" msgid="9067189814657840439">"Уруксат берилген номер жаңырган жок, себеби жазылган номердин саны <xliff:g id="FDN_NUMBER_LIMIT_LENGTH">%d</xliff:g> ашпашы керек."</string>
     <string name="pin2_or_fdn_invalid" msgid="7542639487955868181">"БНТ жаңырган жок. PIN2 туура эмес, же телефон номуру жараксыз."</string>
     <string name="fdn_failed" msgid="216592346853420250">"БНТ иши кыйрады."</string>
@@ -490,9 +490,9 @@
     <string name="oldPinLabel" msgid="8618515202411987721">"Эски PIN"</string>
     <string name="newPinLabel" msgid="3585899083055354732">"Жаңы PIN"</string>
     <string name="confirmPinLabel" msgid="7783531218662473778">"Жаңы PIN\'ди ырастаңыз"</string>
-    <string name="badPin" msgid="4549286285015892321">"Сиз киргизген эски PIN-кодуңуз туура эмес. Кайра аракеттениңиз."</string>
+    <string name="badPin" msgid="4549286285015892321">"Сиз киргизген эски PIN кодуңуз туура эмес. Кайра аракеттениңиз."</string>
     <string name="mismatchPin" msgid="1467254768290323845">"Сиз терген PIN\'дер дал келишпейт. Кайра аракеттениңиз."</string>
-    <string name="invalidPin" msgid="7363723429414001979">"Узундугу 4төн 8ге чейинки сандан турган PIN-кодду териңиз."</string>
+    <string name="invalidPin" msgid="7363723429414001979">"Узундугу 4төн 8ге чейинки сандан турган PIN кодду териңиз."</string>
     <string name="disable_sim_pin" msgid="3112303905548613752">"SIM PIN тазалоо"</string>
     <string name="enable_sim_pin" msgid="445461050748318980">"SIM PIN орнотуу"</string>
     <string name="enable_in_progress" msgid="4135305985717272592">"PIN орнотулууда…"</string>
diff --git a/res/values-mk/strings.xml b/res/values-mk/strings.xml
index b636122..f9215ad 100644
--- a/res/values-mk/strings.xml
+++ b/res/values-mk/strings.xml
@@ -75,7 +75,7 @@
     <string name="phone_accounts_configure_account_settings" msgid="6622119715253196586">"Конфигурирајте ги поставките на сметка"</string>
     <string name="phone_accounts_all_calling_accounts" msgid="1609600743500618823">"Сите сметки за повици"</string>
     <string name="phone_accounts_all_calling_accounts_summary" msgid="2214134955430107240">"Изберете кои сметки може да повикуваат"</string>
-    <string name="wifi_calling" msgid="3650509202851355742">"Повик преку Wi-Fi"</string>
+    <string name="wifi_calling" msgid="3650509202851355742">"Повици преку Wi-Fi"</string>
     <string name="connection_service_default_label" msgid="7332739049855715584">"Вградена услуга на поврзување"</string>
     <string name="voicemail" msgid="7697769412804195032">"Говорна пошта"</string>
     <string name="voicemail_settings_with_label" msgid="4228431668214894138">"Говорна пошта (<xliff:g id="SUBSCRIPTIONLABEL">%s</xliff:g>)"</string>
@@ -297,7 +297,7 @@
     <string name="limited_sim_function_notification_message" msgid="5338638075496721160">"Повиците и услугите за интернет на <xliff:g id="CARRIER_NAME">%1$s</xliff:g> може да се блокирани со друга SIM-картичка."</string>
     <string name="sip_accounts_removed_notification_title" msgid="3528076957535736095">"Најдени и отстранети се неподдржани сметки на SIP"</string>
     <string name="sip_accounts_removed_notification_message" msgid="1916856744869791592">"Платформата Android веќе не поддржува повикување преку SIP.\nВашите постојни сметки на SIP <xliff:g id="REMOVED_SIP_ACCOUNTS">%s</xliff:g> се отстранети.\nПотврдете ја вашата стандардна поставка за повикување."</string>
-    <string name="sip_accounts_removed_notification_action" msgid="3772778402370555562">"Одете во „Поставки“"</string>
+    <string name="sip_accounts_removed_notification_action" msgid="3772778402370555562">"Отворете „Поставки“"</string>
     <string name="data_usage_title" msgid="8438592133893837464">"Потрошен интернет од апликации"</string>
     <string name="data_usage_template" msgid="6287906680674061783">"<xliff:g id="ID_1">%1$s</xliff:g> потрошен мобилен интернет во периодот <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="advanced_options_title" msgid="9208195294513520934">"Напредни"</string>
@@ -310,7 +310,7 @@
     <string name="sim_selection_required_pref" msgid="6985901872978341314">"Треба да се избере"</string>
     <string name="sim_change_data_title" msgid="9142726786345906606">"Да се промени SIM за интернет?"</string>
     <string name="sim_change_data_message" msgid="3567358694255933280">"Да се користи <xliff:g id="NEW_SIM">%1$s</xliff:g> наместо <xliff:g id="OLD_SIM">%2$s</xliff:g> за мобилен интернет?"</string>
-    <string name="wifi_calling_settings_title" msgid="5800018845662016507">"Повик преку Wi-Fi"</string>
+    <string name="wifi_calling_settings_title" msgid="5800018845662016507">"Повици преку Wi-Fi"</string>
     <string name="video_calling_settings_title" msgid="342829454913266078">"Видеоповикување преку оператор"</string>
     <string name="gsm_umts_options" msgid="4968446771519376808">"Опции за GSM/UMTS"</string>
     <string name="cdma_options" msgid="3669592472226145665">"Опции на CDMA"</string>
@@ -598,7 +598,7 @@
     <string name="hac_mode_summary" msgid="7774989500136009881">"Вклучи компатибилност на слушни помагала"</string>
     <string name="rtt_mode_title" msgid="3075948111362818043">"Повик со „Текст во реално време“ (RTT)"</string>
     <string name="rtt_mode_summary" msgid="8631541375609989562">"Дозволете пораки во текот на гласовен повик"</string>
-    <string name="rtt_mode_more_information" msgid="587500128658756318">"Функцијата RTT им помага на повикувачи коишто се глуви, слабо слушаат, имаат говорна мана или пак, им е потребно многу повеќе од глас.&lt;br&gt; &lt;a href=<xliff:g id="URL">http://support.google.com/mobile?p=telephony_rtt</xliff:g>&gt;Дознајте повеќе&lt;/a&gt;\n       &lt;br&gt;&lt;br&gt; - Повиците со RTT се зачувуваат како препис на порака\n       &lt;br&gt; - Функцијата RTT не е достапна за видеоповици"</string>
+    <string name="rtt_mode_more_information" msgid="587500128658756318">"RTT им помага на корисниците коишто се глуви, наглуви, имаат попреченост во говорот или пак, не им е доволен само глас.&lt;br&gt; &lt;a href=<xliff:g id="URL">http://support.google.com/mobile?p=telephony_rtt</xliff:g>&gt;Дознајте повеќе&lt;/a&gt;\n       &lt;br&gt;&lt;br&gt; - RTT-повиците се зачувуваат како транскрипции на пораки\n       &lt;br&gt; - Функцијата RTT не е достапна за видеоповици"</string>
     <string name="no_rtt_when_roaming" msgid="5268008247378355389">"Напомена: RTT не е достапна во роаминг"</string>
   <string-array name="tty_mode_entries">
     <item msgid="3238070884803849303">"TTY исклучени"</item>
diff --git a/res/values-ne/strings.xml b/res/values-ne/strings.xml
index 9630be6..3ee9043 100644
--- a/res/values-ne/strings.xml
+++ b/res/values-ne/strings.xml
@@ -927,7 +927,7 @@
     <string name="call_quality_notification_name" msgid="3476828289553948830">"कलको गुणस्तरसम्बन्धी सूचना"</string>
     <string name="notification_channel_sip_account" msgid="1261816025156179637">"चल्तीबाट हटाइएका SIP खाताहरू"</string>
     <string name="send_from_work_profile_title" msgid="7044759579507604732">"व्यक्तिगत एपमार्फत म्यासेज पठाउन मिल्दैन"</string>
-    <string name="send_from_work_profile_description" msgid="2174402508727161974">"तपाईंको सङ्गठनले तपाईंलाई केवल कामसम्बन्धी एपहरूमार्फत म्यासेज पठाउने अनुमति दिन्छ"</string>
+    <string name="send_from_work_profile_description" msgid="2174402508727161974">"तपाईंको सङ्गठनले तपाईंलाई केवल कामसम्बन्धी एपहरूमार्फत म्यासेज पठाउने अनुमति दिएको छ"</string>
     <string name="send_from_work_profile_cancel" msgid="177746511030381711">"रद्द गर्नुहोस्"</string>
     <string name="send_from_work_profile_action_str" msgid="6892775562934243337">"कार्य प्रोफाइल प्रयोग गर्नुहोस्"</string>
     <string name="install_messages_on_work_profile_action_str" msgid="3773440996395152903">"कामसम्बन्धी म्यासेजिङ एप इन्स्टल गर्नुहोस्"</string>
diff --git a/res/values-te/strings.xml b/res/values-te/strings.xml
index da06712..39f5ce3 100644
--- a/res/values-te/strings.xml
+++ b/res/values-te/strings.xml
@@ -320,7 +320,7 @@
     <string name="throttle_rate" msgid="7641913901133634905">"డేటా రేట్ విధానం"</string>
     <string name="throttle_help" msgid="2624535757028809735">"మరింత తెలుసుకోండి"</string>
     <string name="throttle_status_subtext" msgid="1110276415078236687">"గరిష్ఠ వ్యవధి అయిన <xliff:g id="USED_2">%3$s</xliff:g>లో <xliff:g id="USED_0">%1$s</xliff:g> (<xliff:g id="USED_1">%2$d</xliff:g>٪)\nతర్వాతి వ్యవధి <xliff:g id="USED_3">%4$d</xliff:g> రోజుల్లో (<xliff:g id="USED_4">%5$s</xliff:g>) ప్రారంభమవుతుంది"</string>
-    <string name="throttle_data_usage_subtext" msgid="3185429653996709840">"గరిష్టంగా <xliff:g id="USED_2">%3$s</xliff:g>లో <xliff:g id="USED_0">%1$s</xliff:g> (<xliff:g id="USED_1">%2$d</xliff:g>٪)"</string>
+    <string name="throttle_data_usage_subtext" msgid="3185429653996709840">"గరిష్ఠంగా <xliff:g id="USED_2">%3$s</xliff:g>లో <xliff:g id="USED_0">%1$s</xliff:g> (<xliff:g id="USED_1">%2$d</xliff:g>٪)"</string>
     <string name="throttle_data_rate_reduced_subtext" msgid="8369839346277847725">"<xliff:g id="USED_0">%1$s</xliff:g> గరిష్ట పరిమితి మించిపోయింది\nడేటా రేట్ <xliff:g id="USED_1">%2$d</xliff:g> Kb/sకి తగ్గించబడింది"</string>
     <string name="throttle_time_frame_subtext" msgid="6462089615392402127">"సైకిల్‌లో <xliff:g id="USED_0">%1$d</xliff:g>٪ గడిచిపోయింది\nతదుపరి వ్యవధి <xliff:g id="USED_1">%2$d</xliff:g> రోజుల్లో (<xliff:g id="USED_2">%3$s</xliff:g>) ప్రారంభమవుతుంది"</string>
     <string name="throttle_rate_subtext" msgid="7221971817325779535">"డేటా వినియోగ పరిమితి మించిపోయినప్పుడు డేటా రేట్ <xliff:g id="USED">%1$d</xliff:g> Kb/sకి తగ్గించబడుతుంది"</string>
@@ -617,7 +617,7 @@
     <string name="ota_title_activate" msgid="4049645324841263423">"మీ ఫోన్‌ను యాక్టివేట్ చేయండి"</string>
     <string name="ota_touch_activate" msgid="838764494319694754">"మీ ఫోన్ సేవను సక్రియం చేయడానికి ప్రత్యేక కాల్ చేయాల్సి ఉంటుంది. \n\n“యాక్టివేట్ చేయండి” నొక్కిన తర్వాత, మీ ఫోన్‌ను సక్రియం చేయడానికి అందించబడే సూచనలను వినండి."</string>
     <string name="ota_hfa_activation_title" msgid="3300556778212729671">"సక్రియం చేస్తోంది..."</string>
-    <string name="ota_hfa_activation_dialog_message" msgid="7921718445773342996">"ఫోన్ మీ మొబైల్ డేటా సేవను సక్రియం చేస్తోంది.\n\nదీనికి గరిష్టంగా 5 నిమిషాలు పట్టవచ్చు."</string>
+    <string name="ota_hfa_activation_dialog_message" msgid="7921718445773342996">"ఫోన్ మీ మొబైల్ డేటా సేవను సక్రియం చేస్తోంది.\n\nదీనికి గరిష్ఠంగా 5 నిమిషాలు పట్టవచ్చు."</string>
     <string name="ota_skip_activation_dialog_title" msgid="7666611236789203797">"సక్రియం చేయడాన్ని దాటవేయాలా?"</string>
     <string name="ota_skip_activation_dialog_message" msgid="6691722887019708713">"మీరు సక్రియం చేయడాన్ని దాటవేస్తే, కాల్స్‌ చేయలేరు లేదా మొబైల్ డేటా నెట్‌వర్క్‌లకు కనెక్ట్ చేయలేరు (మీరు Wi-Fi నెట్‌వర్క్‌లకు కనెక్ట్ చేయగలిగినప్పటికీ). మీరు మీ ఫోన్‌ను సక్రియం చేసేవరకు, దాన్ని ప్రారంభించే ప్రతిసారీ సక్రియం చేయమని మిమ్మల్ని అడుగుతుంది."</string>
     <string name="ota_skip_activation_dialog_skip_label" msgid="5908029466817825633">"స్కిప్ చేయండి"</string>
@@ -628,7 +628,7 @@
     <string name="ota_speaker" msgid="1086766980329820528">"స్పీకర్"</string>
     <string name="ota_progress" msgid="8837259285255700132">"మీ ఫోన్ ప్రోగ్రామ్ చేయబడుతోంది…"</string>
     <string name="ota_failure" msgid="5674217489921481576">"మీ ఫోన్‌ను ప్రోగ్రామ్ చేయడం సాధ్యపడలేదు"</string>
-    <string name="ota_successful" msgid="1106825981548107774">"మీ ఫోన్ ఇప్పుడు సక్రియం అయ్యింది. సేవ ప్రారంభం కావడానికి గరిష్టంగా 15 నిమిషాలు పట్టవచ్చు."</string>
+    <string name="ota_successful" msgid="1106825981548107774">"మీ ఫోన్ ఇప్పుడు సక్రియం అయ్యింది. సేవ ప్రారంభం కావడానికి గరిష్ఠంగా 15 నిమిషాలు పట్టవచ్చు."</string>
     <string name="ota_unsuccessful" msgid="8531037653803955754">"మీ ఫోన్ సక్రియం చేయబడలేదు. \nమీరు మెరుగైన కవరేజీ గల ప్రాంతాన్ని (కిటికీ దగ్గర లేదా వెలుపల) కనుగొనాల్సి ఉంటుంది. \n\nమళ్లీ ట్రై చేయండి లేదా మరిన్ని ఎంపికల కోసం కస్టమర్ సేవకు కాల్ చేయండి."</string>
     <string name="ota_spc_failure" msgid="904092035241370080">"అత్యధిక SPC వైఫల్యాలు"</string>
     <string name="ota_call_end" msgid="8657746378290737034">"వెనుకకు"</string>
diff --git a/src/com/android/phone/CarrierConfigLoader.java b/src/com/android/phone/CarrierConfigLoader.java
index fa85f27..bc42a93 100644
--- a/src/com/android/phone/CarrierConfigLoader.java
+++ b/src/com/android/phone/CarrierConfigLoader.java
@@ -39,6 +39,7 @@
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.Message;
+import android.os.PermissionEnforcer;
 import android.os.PersistableBundle;
 import android.os.Process;
 import android.os.RemoteException;
@@ -695,6 +696,7 @@
      */
     @VisibleForTesting
     /* package */ CarrierConfigLoader(@NonNull Context context, @NonNull Looper looper) {
+        super(PermissionEnforcer.fromContext(context));
         mContext = context;
         mPlatformCarrierConfigPackage =
                 mContext.getString(R.string.platform_carrier_config_package);
@@ -1408,11 +1410,11 @@
         return configSubset;
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_PHONE_STATE)
     @Override
     public void overrideConfig(int subscriptionId, @Nullable PersistableBundle overrides,
             boolean persistent) {
-        mContext.enforceCallingOrSelfPermission(
-                android.Manifest.permission.MODIFY_PHONE_STATE, null);
+        overrideConfig_enforcePermission();
         int phoneId = SubscriptionManager.getPhoneId(subscriptionId);
         if (!SubscriptionManager.isValidPhoneId(phoneId)) {
             logd("Ignore invalid phoneId: " + phoneId + " for subId: " + subscriptionId);
@@ -1478,10 +1480,10 @@
         updateConfigForPhoneId(phoneId);
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_PHONE_STATE)
     @Override
     public void updateConfigForPhoneId(int phoneId, @NonNull String simState) {
-        mContext.enforceCallingOrSelfPermission(
-                android.Manifest.permission.MODIFY_PHONE_STATE, null);
+        updateConfigForPhoneId_enforcePermission();
         logdWithLocalLog("Update config for phoneId: " + phoneId + " simState: " + simState);
         if (!SubscriptionManager.isValidPhoneId(phoneId)) {
             throw new IllegalArgumentException("Invalid phoneId: " + phoneId);
@@ -1502,12 +1504,11 @@
         }
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
     @Override
     @NonNull
     public String getDefaultCarrierServicePackageName() {
-        mContext.enforceCallingOrSelfPermission(
-                android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
-                "getDefaultCarrierServicePackageName");
+        getDefaultCarrierServicePackageName_enforcePermission();
         return mPlatformCarrierConfigPackage;
     }
 
diff --git a/src/com/android/phone/IccNetworkDepersonalizationPanel.java b/src/com/android/phone/IccNetworkDepersonalizationPanel.java
index a4ec8a4..7099476 100644
--- a/src/com/android/phone/IccNetworkDepersonalizationPanel.java
+++ b/src/com/android/phone/IccNetworkDepersonalizationPanel.java
@@ -112,7 +112,7 @@
     }
 
     public static void dialogDismiss(int phoneId) {
-        if (phoneId >= sShowingDialog.length) {
+        if (phoneId >= sShowingDialog.length || !SubscriptionManager.isValidPhoneId(phoneId)) {
             Log.e(TAG, "[IccNetworkDepersonalizationPanel] - dismiss; invalid phoneId " + phoneId);
             return;
         }
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index 0107b1c..3c7ee80 100644
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -296,8 +296,6 @@
     private static final int EVENT_GET_ALLOWED_NETWORK_TYPES_BITMASK_DONE = 22;
     private static final int CMD_SEND_ENVELOPE = 25;
     private static final int EVENT_SEND_ENVELOPE_DONE = 26;
-    private static final int CMD_INVOKE_OEM_RIL_REQUEST_RAW = 27;
-    private static final int EVENT_INVOKE_OEM_RIL_REQUEST_RAW_DONE = 28;
     private static final int CMD_TRANSMIT_APDU_BASIC_CHANNEL = 29;
     private static final int EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE = 30;
     private static final int CMD_EXCHANGE_SIM_IO = 31;
@@ -1154,19 +1152,6 @@
                     handleNullReturnEvent(msg, "setAllowedNetworkTypesForReason");
                     break;
 
-                case CMD_INVOKE_OEM_RIL_REQUEST_RAW:
-                    request = (MainThreadRequest)msg.obj;
-                    onCompleted = obtainMessage(EVENT_INVOKE_OEM_RIL_REQUEST_RAW_DONE, request);
-                    defaultPhone.invokeOemRilRequestRaw((byte[]) request.argument, onCompleted);
-                    break;
-
-                case EVENT_INVOKE_OEM_RIL_REQUEST_RAW_DONE:
-                    ar = (AsyncResult)msg.obj;
-                    request = (MainThreadRequest)ar.userObj;
-                    request.result = ar;
-                    notifyRequester(request);
-                    break;
-
                 case CMD_SET_VOICEMAIL_NUMBER:
                     request = (MainThreadRequest) msg.obj;
                     onCompleted = obtainMessage(EVENT_SET_VOICEMAIL_NUMBER_DONE, request);
@@ -7518,39 +7503,6 @@
     }
 
     @Override
-    @Deprecated
-    public int invokeOemRilRequestRaw(byte[] oemReq, byte[] oemResp) {
-        enforceModifyPermission();
-
-        int returnValue = 0;
-        try {
-            AsyncResult result = (AsyncResult) sendRequest(CMD_INVOKE_OEM_RIL_REQUEST_RAW, oemReq);
-            if(result.exception == null) {
-                if (result.result != null) {
-                    byte[] responseData = (byte[])(result.result);
-                    if(responseData.length > oemResp.length) {
-                        Log.w(LOG_TAG, "Buffer to copy response too small: Response length is " +
-                                responseData.length +  "bytes. Buffer Size is " +
-                                oemResp.length + "bytes.");
-                    }
-                    System.arraycopy(responseData, 0, oemResp, 0, responseData.length);
-                    returnValue = responseData.length;
-                }
-            } else {
-                CommandException ex = (CommandException) result.exception;
-                returnValue = ex.getCommandError().ordinal();
-                if(returnValue > 0) returnValue *= -1;
-            }
-        } catch (RuntimeException e) {
-            Log.w(LOG_TAG, "sendOemRilRequestRaw: Runtime Exception");
-            returnValue = (CommandException.Error.GENERIC_FAILURE.ordinal());
-            if(returnValue > 0) returnValue *= -1;
-        }
-
-        return returnValue;
-    }
-
-    @Override
     public int getRadioAccessFamily(int phoneId, String callingPackage) {
         int raf = RadioAccessFamily.RAF_UNKNOWN;
         Phone phone = PhoneFactory.getPhone(phoneId);
diff --git a/src/com/android/phone/PhoneUtils.java b/src/com/android/phone/PhoneUtils.java
index 4826d2b..0c8a9c7 100644
--- a/src/com/android/phone/PhoneUtils.java
+++ b/src/com/android/phone/PhoneUtils.java
@@ -703,8 +703,12 @@
     }
 
     public static PhoneAccountHandle makePstnPhoneAccountHandle(Phone phone) {
-        return makePstnPhoneAccountHandleWithPrefix(phone, "",
-                false, phone.getUserHandle());
+        if (phone == null) {
+            return null;
+        } else {
+            return makePstnPhoneAccountHandleWithPrefix(phone, "",
+                    false, phone.getUserHandle());
+        }
     }
 
     public static PhoneAccountHandle makePstnPhoneAccountHandleWithPrefix(
diff --git a/src/com/android/phone/settings/RadioInfo.java b/src/com/android/phone/settings/RadioInfo.java
index 124badf..6d2ddf3 100644
--- a/src/com/android/phone/settings/RadioInfo.java
+++ b/src/com/android/phone/settings/RadioInfo.java
@@ -44,6 +44,7 @@
 import android.os.Message;
 import android.os.PersistableBundle;
 import android.os.SystemProperties;
+import android.os.UserManager;
 import android.telephony.AccessNetworkConstants;
 import android.telephony.CarrierConfigManager;
 import android.telephony.CellIdentityCdma;
@@ -482,6 +483,15 @@
             return;
         }
 
+        UserManager userManager =
+                (UserManager) getApplicationContext().getSystemService(Context.USER_SERVICE);
+        if (userManager != null
+                && userManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS)) {
+            Log.w(TAG, "User is restricted from configuring mobile networks.");
+            finish();
+            return;
+        }
+
         setContentView(R.layout.radio_info);
 
         log("Started onCreate");
@@ -835,7 +845,9 @@
     @Override
     protected void onDestroy() {
         super.onDestroy();
-        mQueuedWork.shutdown();
+        if (mQueuedWork != null) {
+            mQueuedWork.shutdown();
+        }
     }
 
     // returns array of string labels for each phone index. The array index is equal to the phone
diff --git a/src/com/android/phone/slice/PremiumNetworkEntitlementResponse.java b/src/com/android/phone/slice/PremiumNetworkEntitlementResponse.java
index ba44581..6b7e945 100644
--- a/src/com/android/phone/slice/PremiumNetworkEntitlementResponse.java
+++ b/src/com/android/phone/slice/PremiumNetworkEntitlementResponse.java
@@ -25,19 +25,19 @@
  *
  * The relationship between entitlement status (left column) and provision status (top row)
  * is defined in the table below:
- * +--------------+-----------------+-------------------+-------------------+---------------+
- * |              | Not Provisioned |    Provisioned    |   Not Available   |  In Progress  |
- * +--------------+-----------------+-------------------+-------------------+---------------+
- * |   Disabled   |   Check failed  |    Check failed   |    Check failed   |  Check failed |
- * +--------------+-----------------+-------------------+-------------------+---------------+
- * |    Enabled   |  Carrier error  |  Display webview  |  Display webview  | Carrier error |
- * +--------------+-----------------+-------------------+-------------------+---------------+
- * | Incompatible |   Check failed  |    Check failed   |    Check failed   |  Check failed |
- * +--------------+-----------------+-------------------+-------------------+---------------+
- * | Provisioning |  Carrier error  |   Carrier error   |    In Progress    |  In Progress  |
- * +--------------+-----------------+-------------------+-------------------+---------------+
- * |   Included   |  Carrier error  | Already purchased | Already purchased | Carrier error |
- * +--------------+-----------------+-------------------+-------------------+---------------+
+ * +--------------+-----------------+-------------------+-------------------+-----------------+
+ * |              | Not Provisioned |    Provisioned    |   Not Available   |   In Progress   |
+ * +--------------+-----------------+-------------------+-------------------+-----------------+
+ * |   Disabled   |   Check failed  |    Check failed   |    Check failed   |   Check failed  |
+ * +--------------+-----------------+-------------------+-------------------+-----------------+
+ * |    Enabled   | Display webview | Already purchased | Already purchased |   In progress   |
+ * +--------------+-----------------+-------------------+-------------------+-----------------+
+ * | Incompatible |   Check failed  |    Check failed   |    Check failed   |   Check failed  |
+ * +--------------+-----------------+-------------------+-------------------+-----------------+
+ * | Provisioning |  Carrier error  |   Carrier error   |    In progress    |   In progress   |
+ * +--------------+-----------------+-------------------+-------------------+-----------------+
+ * |   Included   |  Carrier error  | Already purchased | Already purchased |  Carrier error  |
+ * +--------------+-----------------+-------------------+-------------------+-----------------+
  */
 public class PremiumNetworkEntitlementResponse {
     public static final int PREMIUM_NETWORK_ENTITLEMENT_STATUS_DISABLED = 0;
@@ -74,11 +74,16 @@
     @NonNull public String mServiceFlowUserData;
 
     /**
-     * @return {@code true} if the premium network is provisioned and {@code false} otherwise.
+     * @return {@code true} if the premium network is already purchased and {@code false} otherwise.
      */
-    public boolean isProvisioned() {
-        return !isInvalidResponse()
-                && mEntitlementStatus == PREMIUM_NETWORK_ENTITLEMENT_STATUS_INCLUDED;
+    public boolean isAlreadyPurchased() {
+        switch (mEntitlementStatus) {
+            case PREMIUM_NETWORK_ENTITLEMENT_STATUS_ENABLED:
+            case PREMIUM_NETWORK_ENTITLEMENT_STATUS_INCLUDED:
+                return mProvisionStatus == PREMIUM_NETWORK_PROVISION_STATUS_PROVISIONED
+                        || mProvisionStatus == PREMIUM_NETWORK_PROVISION_STATUS_NOT_AVAILABLE;
+        }
+        return false;
     }
 
     /**
@@ -86,8 +91,14 @@
      *         {@code false} otherwise.
      */
     public boolean isProvisioningInProgress() {
-        return !isInvalidResponse()
-                && mEntitlementStatus == PREMIUM_NETWORK_ENTITLEMENT_STATUS_PROVISIONING;
+        switch (mEntitlementStatus) {
+            case PREMIUM_NETWORK_ENTITLEMENT_STATUS_ENABLED:
+                return mProvisionStatus == PREMIUM_NETWORK_PROVISION_STATUS_IN_PROGRESS;
+            case PREMIUM_NETWORK_ENTITLEMENT_STATUS_PROVISIONING:
+                return mProvisionStatus == PREMIUM_NETWORK_PROVISION_STATUS_IN_PROGRESS
+                        || mProvisionStatus == PREMIUM_NETWORK_PROVISION_STATUS_NOT_AVAILABLE;
+        }
+        return false;
     }
 
     /**
@@ -108,7 +119,6 @@
      */
     public boolean isInvalidResponse() {
         switch (mEntitlementStatus) {
-            case PREMIUM_NETWORK_ENTITLEMENT_STATUS_ENABLED:
             case PREMIUM_NETWORK_ENTITLEMENT_STATUS_INCLUDED:
                 return mProvisionStatus == PREMIUM_NETWORK_PROVISION_STATUS_NOT_PROVISIONED
                         || mProvisionStatus == PREMIUM_NETWORK_PROVISION_STATUS_IN_PROGRESS;
diff --git a/src/com/android/phone/slice/SlicePurchaseController.java b/src/com/android/phone/slice/SlicePurchaseController.java
index b1abe56..95b47a3 100644
--- a/src/com/android/phone/slice/SlicePurchaseController.java
+++ b/src/com/android/phone/slice/SlicePurchaseController.java
@@ -92,12 +92,10 @@
     public static final int FAILURE_CODE_UNKNOWN = 0;
     /** Performance boost purchase failed because the carrier URL is unavailable. */
     public static final int FAILURE_CODE_CARRIER_URL_UNAVAILABLE = 1;
-    /** Performance boost purchase failed because the server is unreachable. */
-    public static final int FAILURE_CODE_SERVER_UNREACHABLE = 2;
     /** Performance boost purchase failed because user authentication failed. */
-    public static final int FAILURE_CODE_AUTHENTICATION_FAILED = 3;
+    public static final int FAILURE_CODE_AUTHENTICATION_FAILED = 2;
     /** Performance boost purchase failed because the payment failed. */
-    public static final int FAILURE_CODE_PAYMENT_FAILED = 4;
+    public static final int FAILURE_CODE_PAYMENT_FAILED = 3;
 
     /**
      * Failure codes that the carrier website can return when a premium capability purchase fails.
@@ -106,7 +104,6 @@
     @IntDef(prefix = { "FAILURE_CODE_" }, value = {
             FAILURE_CODE_UNKNOWN,
             FAILURE_CODE_CARRIER_URL_UNAVAILABLE,
-            FAILURE_CODE_SERVER_UNREACHABLE,
             FAILURE_CODE_AUTHENTICATION_FAILED,
             FAILURE_CODE_PAYMENT_FAILED})
     public @interface FailureCode {}
@@ -455,7 +452,7 @@
         mIsSlicingUpsellEnabled = DeviceConfig.getBoolean(
                 DeviceConfig.NAMESPACE_TELEPHONY, KEY_ENABLE_SLICING_UPSELL, false);
         DeviceConfig.addOnPropertiesChangedListener(
-                DeviceConfig.NAMESPACE_TELEPHONY, this::post,
+                DeviceConfig.NAMESPACE_TELEPHONY, Runnable::run,
                 properties -> {
                     if (TextUtils.equals(DeviceConfig.NAMESPACE_TELEPHONY,
                             properties.getNamespace())) {
@@ -690,6 +687,17 @@
 
     private void onStartSlicePurchaseApplication(
             @TelephonyManager.PremiumCapability int capability) {
+        updateNotificationCounts();
+        if (mMonthlyCount >= getCarrierConfigs().getInt(
+                CarrierConfigManager.KEY_PREMIUM_CAPABILITY_MAXIMUM_MONTHLY_NOTIFICATION_COUNT_INT)
+                || mDailyCount >= getCarrierConfigs().getInt(
+                CarrierConfigManager.KEY_PREMIUM_CAPABILITY_MAXIMUM_DAILY_NOTIFICATION_COUNT_INT)) {
+            logd("Reached maximum number of performance boost notifications.");
+            handlePurchaseResult(capability,
+                    TelephonyManager.PURCHASE_PREMIUM_CAPABILITY_RESULT_THROTTLED, false);
+            return;
+        }
+
         final PremiumNetworkEntitlementApi premiumNetworkEntitlementApi =
                 getPremiumNetworkEntitlementApi();
         PremiumNetworkEntitlementResponse premiumNetworkEntitlementResponse =
@@ -711,8 +719,8 @@
             return;
         }
 
-        if (premiumNetworkEntitlementResponse.isProvisioned()) {
-            logd("Entitlement Check: Already provisioned.");
+        if (premiumNetworkEntitlementResponse.isAlreadyPurchased()) {
+            logd("Entitlement Check: Already purchased/provisioned.");
             handlePurchaseResult(capability,
                     PURCHASE_PREMIUM_CAPABILITY_RESULT_ALREADY_PURCHASED, true);
             return;
@@ -734,17 +742,6 @@
             return;
         }
 
-        updateNotificationCounts();
-        if (mMonthlyCount >= getCarrierConfigs().getInt(
-                CarrierConfigManager.KEY_PREMIUM_CAPABILITY_MAXIMUM_MONTHLY_NOTIFICATION_COUNT_INT)
-                || mDailyCount >= getCarrierConfigs().getInt(
-                CarrierConfigManager.KEY_PREMIUM_CAPABILITY_MAXIMUM_DAILY_NOTIFICATION_COUNT_INT)) {
-            logd("Reached maximum number of performance boost notifications.");
-            handlePurchaseResult(capability,
-                    TelephonyManager.PURCHASE_PREMIUM_CAPABILITY_RESULT_THROTTLED, false);
-            return;
-        }
-
         // Start timeout for purchase completion.
         long timeout = getCarrierConfigs().getLong(CarrierConfigManager
                 .KEY_PREMIUM_CAPABILITY_NOTIFICATION_DISPLAY_TIMEOUT_MILLIS_LONG);
@@ -1094,7 +1091,6 @@
         switch (failureCode) {
             case FAILURE_CODE_UNKNOWN: return "UNKNOWN";
             case FAILURE_CODE_CARRIER_URL_UNAVAILABLE: return "CARRIER_URL_UNAVAILABLE";
-            case FAILURE_CODE_SERVER_UNREACHABLE: return "SERVER_UNREACHABLE";
             case FAILURE_CODE_AUTHENTICATION_FAILED: return "AUTHENTICATION_FAILED";
             case FAILURE_CODE_PAYMENT_FAILED: return "PAYMENT_FAILED";
             default:
diff --git a/src/com/android/services/telephony/TelephonyConnectionService.java b/src/com/android/services/telephony/TelephonyConnectionService.java
index bf7ce00..3c4e2c3 100644
--- a/src/com/android/services/telephony/TelephonyConnectionService.java
+++ b/src/com/android/services/telephony/TelephonyConnectionService.java
@@ -2249,8 +2249,7 @@
                                         .setVideoState(videoState)
                                         .setIntentExtras(extras)
                                         .setRttTextStream(mNormalCallConnection.getRttTextStream())
-                                        .setIsWpsCall(NormalCallDomainSelectionConnection
-                                                .isWpsCall(number))
+                                        .setIsWpsCall(PhoneNumberUtils.isWpsCallNumber(number))
                                         .build(),
                                 mNormalCallConnection::registerForCallEvents);
 
@@ -2311,7 +2310,7 @@
         // Check and select same domain as ongoing call on the same subscription (if exists)
         int activeCallDomain = getActiveCallDomain(phone.getSubId());
         if (activeCallDomain != NetworkRegistrationInfo.DOMAIN_UNKNOWN
-                && !NormalCallDomainSelectionConnection.isWpsCall(number)) {
+                && !PhoneNumberUtils.isWpsCallNumber(number)) {
             Log.d(LOG_TAG, "Selecting same domain as ongoing call on same subId");
             mNormalCallConnection = connection;
             handleOutgoingCallConnectionByCallDomainSelection(
diff --git a/src/com/android/services/telephony/domainselection/NormalCallDomainSelector.java b/src/com/android/services/telephony/domainselection/NormalCallDomainSelector.java
index f176d90..70ad38e 100644
--- a/src/com/android/services/telephony/domainselection/NormalCallDomainSelector.java
+++ b/src/com/android/services/telephony/domainselection/NormalCallDomainSelector.java
@@ -28,13 +28,12 @@
 import android.telephony.DisconnectCause;
 import android.telephony.DomainSelectionService.SelectionAttributes;
 import android.telephony.NetworkRegistrationInfo;
+import android.telephony.PhoneNumberUtils;
 import android.telephony.ServiceState;
 import android.telephony.SubscriptionManager;
 import android.telephony.TransportSelectorCallback;
 import android.telephony.ims.ImsReasonInfo;
 
-import com.android.internal.telephony.domainselection.NormalCallDomainSelectionConnection;
-
 /**
  * Implements domain selector for outgoing non-emergency calls.
  */
@@ -375,9 +374,7 @@
         // Handle voice call.
         if (mImsStateTracker.isImsVoiceCapable()) {
             logd("IMS is voice capable");
-            // TODO(b/266175810) Remove this dependency.
-            if (NormalCallDomainSelectionConnection
-                    .isWpsCall(mSelectionAttributes.getNumber())) {
+            if (PhoneNumberUtils.isWpsCallNumber(mSelectionAttributes.getNumber())) {
                 handleWpsCall();
             } else {
                 notifyPsSelected();
diff --git a/testapps/GbaTestApp/Android.bp b/testapps/GbaTestApp/Android.bp
index 76e02a0..72f7cc4 100644
--- a/testapps/GbaTestApp/Android.bp
+++ b/testapps/GbaTestApp/Android.bp
@@ -22,7 +22,6 @@
     static_libs: [
         "androidx.appcompat_appcompat",
 	"androidx-constraintlayout_constraintlayout",
-	"ub-uiautomator",
     ],
     srcs: ["src/**/*.java"],
     javacflags: ["-parameters"],
diff --git a/testapps/TestSatelliteApp/Android.bp b/testapps/TestSatelliteApp/Android.bp
new file mode 100644
index 0000000..fd3c424
--- /dev/null
+++ b/testapps/TestSatelliteApp/Android.bp
@@ -0,0 +1,17 @@
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+android_app {
+    name: "SatelliteTestApp",
+    system_ext_specific: true,
+    platform_apis: true,
+    manifest: "AndroidManifest.xml",
+    srcs: [
+        "src/**/*.java",
+        "src/**/I*.aidl",
+    ],
+    owner: "google",
+    privileged: true,
+    certificate: "platform",
+}
diff --git a/testapps/TestSatelliteApp/AndroidManifest.xml b/testapps/TestSatelliteApp/AndroidManifest.xml
new file mode 100644
index 0000000..278d102
--- /dev/null
+++ b/testapps/TestSatelliteApp/AndroidManifest.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2023 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.phone.testapps.satellitetestapp">
+    <uses-permission android:name="android.permission.BIND_SATELLITE_SERVICE"/>
+    <uses-permission android:name="android.permission.SATELLITE_COMMUNICATION"/>
+    <application android:label="SatelliteTestApp">
+        <activity android:name=".SatelliteTestApp"
+             android:label="SatelliteTestApp"
+             android:exported="true">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+                <category android:name="android.intent.category.DEFAULT"/>
+                <category android:name="android.intent.category.LAUNCHER"/>
+            </intent-filter>
+        </activity>
+
+        <service android:name=".TestSatelliteService"
+             android:directBootAware="true"
+             android:persistent="true"
+             android:permission="android.permission.BIND_SATELLITE_SERVICE"
+             android:exported="true">
+            <intent-filter>
+                <action android:name="android.telephony.satellite.SatelliteService"/>
+            </intent-filter>
+        </service>
+
+        <activity android:name=".SatelliteControl" />
+        <activity android:name=".SatelliteTransmissionUpdates" />
+        <activity android:name=".Datagram" />
+        <activity android:name=".Provisioning" />
+        <activity android:name=".SatelliteModemState" />
+    </application>
+</manifest>
diff --git a/testapps/TestSatelliteApp/res/layout/activity_Datagram.xml b/testapps/TestSatelliteApp/res/layout/activity_Datagram.xml
new file mode 100644
index 0000000..5cfe7d9
--- /dev/null
+++ b/testapps/TestSatelliteApp/res/layout/activity_Datagram.xml
@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2023 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:orientation="vertical"
+    android:gravity="center"
+    android:paddingLeft="4dp">
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="vertical" >
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content" android:layout_weight="0"
+            android:textColor="@android:color/holo_blue_dark"
+            android:textSize="20dp"
+            android:text="Datagram APIs"/>
+        <Button
+            android:id="@+id/pollPendingSatelliteDatagrams"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingRight="4dp"
+            android:text="@string/pollPendingSatelliteDatagrams"/>
+        <Button
+            android:id="@+id/multiplePollPendingSatelliteDatagrams"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingRight="4dp"
+            android:text="@string/multiplePollPendingSatelliteDatagrams"/>
+        <Button
+            android:id="@+id/sendSatelliteDatagram"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingRight="4dp"
+            android:text="@string/sendSatelliteDatagram"/>
+        <Button
+            android:id="@+id/multipleSendSatelliteDatagram"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingRight="4dp"
+            android:text="@string/multipleSendSatelliteDatagram"/>
+        <Button
+            android:id="@+id/multipleSendReceiveSatelliteDatagram"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingRight="4dp"
+            android:text="@string/multipleSendReceiveSatelliteDatagram"/>
+        <Button
+            android:id="@+id/registerForSatelliteDatagram"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingRight="4dp"
+            android:text="@string/registerForSatelliteDatagram"/>
+        <Button
+            android:id="@+id/unregisterForSatelliteDatagram"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingRight="4dp"
+            android:text="@string/unregisterForSatelliteDatagram"/>
+        <Button
+            android:id="@+id/Back"
+            android:onClick="Back"
+            android:textColor="@android:color/holo_blue_dark"
+            android:layout_marginTop="100dp"
+            android:layout_gravity="center"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:paddingRight="4dp"
+            android:text="@string/Back"/>
+        <TextView
+            android:id="@+id/text_id"
+            android:layout_width="300dp"
+            android:layout_height="200dp"
+            android:capitalize="characters"
+            android:textColor="@android:color/holo_blue_light"
+            android:layout_centerVertical="true"
+            android:textSize="15dp" />
+    </LinearLayout>
+</LinearLayout>
diff --git a/testapps/TestSatelliteApp/res/layout/activity_Provisioning.xml b/testapps/TestSatelliteApp/res/layout/activity_Provisioning.xml
new file mode 100644
index 0000000..c62aebf
--- /dev/null
+++ b/testapps/TestSatelliteApp/res/layout/activity_Provisioning.xml
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2023 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:orientation="vertical"
+    android:gravity="center"
+    android:paddingLeft="4dp">
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="vertical" >
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content" android:layout_weight="0"
+            android:textColor="@android:color/holo_blue_dark"
+            android:textSize="20dp"
+            android:text="Provisioning APIs"/>
+        <Button
+            android:id="@+id/provisionSatelliteService"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingRight="4dp"
+            android:text="@string/provisionSatelliteService"/>
+        <Button
+            android:id="@+id/deprovisionSatelliteService"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingRight="4dp"
+            android:text="@string/deprovisionSatelliteService"/>
+        <Button
+            android:id="@+id/requestIsSatelliteProvisioned"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingRight="4dp"
+            android:text="@string/requestIsSatelliteProvisioned"/>
+         <Button
+            android:id="@+id/registerForSatelliteProvisionStateChanged"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingRight="4dp"
+            android:text="@string/registerForSatelliteProvisionStateChanged"/>
+        <Button
+            android:id="@+id/unregisterForSatelliteProvisionStateChanged"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingRight="4dp"
+            android:text="@string/unregisterForSatelliteProvisionStateChanged"/>
+        <Button
+            android:id="@+id/Back"
+            android:onClick="Back"
+            android:textColor="@android:color/holo_blue_dark"
+            android:layout_marginTop="100dp"
+            android:layout_gravity="center"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:paddingRight="4dp"
+            android:text="@string/Back"/>
+        <TextView
+            android:id="@+id/text_id"
+            android:layout_width="300dp"
+            android:layout_height="200dp"
+            android:capitalize="characters"
+            android:textColor="@android:color/holo_blue_light"
+            android:layout_centerVertical="true"
+            android:textSize="15dp" />
+    </LinearLayout>
+</LinearLayout>
diff --git a/testapps/TestSatelliteApp/res/layout/activity_SatelliteControl.xml b/testapps/TestSatelliteApp/res/layout/activity_SatelliteControl.xml
new file mode 100644
index 0000000..1484ba7
--- /dev/null
+++ b/testapps/TestSatelliteApp/res/layout/activity_SatelliteControl.xml
@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2023 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:orientation="vertical"
+    android:gravity="center"
+    android:paddingLeft="4dp">
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="vertical" >
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content" android:layout_weight="0"
+            android:textColor="@android:color/holo_blue_dark"
+            android:textSize="20dp"
+            android:text="Satellite Control APIs"/>
+        <Button
+            android:id="@+id/requestSatelliteEnabled"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingRight="4dp"
+            android:text="@string/requestSatelliteEnabled"/>
+         <Button
+            android:id="@+id/requestIsSatelliteEnabled"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingRight="4dp"
+            android:text="@string/requestIsSatelliteEnabled"/>
+         <Button
+            android:id="@+id/requestIsDemoModeEnabled"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingRight="4dp"
+            android:text="@string/requestIsDemoModeEnabled"/>
+          <Button
+            android:id="@+id/requestIsSatelliteSupported"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingRight="4dp"
+            android:text="@string/requestIsSatelliteSupported"/>
+         <Button
+            android:id="@+id/requestSatelliteCapabilities"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingRight="4dp"
+            android:text="@string/requestSatelliteCapabilities"/>
+         <Button
+            android:id="@+id/requestIsSatelliteCommunicationAllowedForCurrentLocation"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingRight="4dp"
+            android:text="@string/requestIsSatelliteCommunicationAllowedForCurrentLocation"/>
+          <Button
+            android:id="@+id/requestTimeForNextSatelliteVisibility"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingRight="4dp"
+            android:text="@string/requestTimeForNextSatelliteVisibility"/>
+         <Button
+            android:id="@+id/Back"
+            android:onClick="Back"
+            android:textColor="@android:color/holo_blue_dark"
+            android:layout_marginTop="100dp"
+            android:layout_gravity="center"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:paddingRight="4dp"
+            android:text="@string/Back"/>
+         <TextView
+            android:id="@+id/text_id"
+            android:layout_width="300dp"
+            android:layout_height="200dp"
+            android:capitalize="characters"
+            android:textColor="@android:color/holo_blue_light"
+            android:layout_centerVertical="true"
+            android:textSize="15dp" />
+    </LinearLayout>
+</LinearLayout>
diff --git a/testapps/TestSatelliteApp/res/layout/activity_SatelliteModemState.xml b/testapps/TestSatelliteApp/res/layout/activity_SatelliteModemState.xml
new file mode 100644
index 0000000..5e70ef3
--- /dev/null
+++ b/testapps/TestSatelliteApp/res/layout/activity_SatelliteModemState.xml
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2023 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:orientation="vertical"
+    android:gravity="center"
+    android:paddingLeft="4dp">
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="vertical" >
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content" android:layout_weight="0"
+            android:textColor="@android:color/holo_blue_dark"
+            android:textSize="20dp"
+            android:text="SatelliteModemState APIs"/>
+        <Button
+            android:id="@+id/registerForSatelliteModemStateChanged"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingRight="4dp"
+            android:text="@string/registerForSatelliteModemStateChanged"/>
+        <Button
+            android:id="@+id/unregisterForSatelliteModemStateChanged"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingRight="4dp"
+            android:text="@string/unregisterForSatelliteModemStateChanged"/>
+        <Button
+            android:id="@+id/Back"
+            android:onClick="Back"
+            android:textColor="@android:color/holo_blue_dark"
+            android:layout_marginTop="100dp"
+            android:layout_gravity="center"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:paddingRight="4dp"
+            android:text="@string/Back"/>
+         <TextView
+            android:id="@+id/text_id"
+            android:layout_width="300dp"
+            android:layout_height="200dp"
+            android:capitalize="characters"
+            android:textColor="@android:color/holo_blue_light"
+            android:layout_centerVertical="true"
+            android:textSize="15dp" />
+    </LinearLayout>
+</LinearLayout>
+
diff --git a/testapps/TestSatelliteApp/res/layout/activity_SatelliteTestApp.xml b/testapps/TestSatelliteApp/res/layout/activity_SatelliteTestApp.xml
new file mode 100644
index 0000000..f9a0809
--- /dev/null
+++ b/testapps/TestSatelliteApp/res/layout/activity_SatelliteTestApp.xml
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2023 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:orientation="vertical"
+    android:paddingLeft="4dp">
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="vertical" >
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content" android:layout_weight="0"
+            android:textColor="@android:color/holo_blue_dark"
+            android:textSize="20dp"
+            android:text="Available Satellite APIs"/>
+        <Button
+            android:id="@+id/SatelliteControl"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingRight="4dp"
+            android:text="@string/SatelliteControl"/>
+        <Button
+            android:id="@+id/SatelliteTransmissionUpdates"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingRight="4dp"
+            android:text="@string/SatelliteTransmissionUpdates"/>
+        <Button
+            android:id="@+id/Datagram"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingRight="4dp"
+            android:text="@string/Datagram"/>
+        <Button
+            android:id="@+id/Provisioning"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingRight="4dp"
+            android:text="@string/Provisioning"/>
+        <Button
+            android:id="@+id/SatelliteModemState"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingRight="4dp"
+            android:text="@string/SatelliteModemState"/>
+    </LinearLayout>
+</LinearLayout>
diff --git a/testapps/TestSatelliteApp/res/layout/activity_SatelliteTransmissionUpdates.xml b/testapps/TestSatelliteApp/res/layout/activity_SatelliteTransmissionUpdates.xml
new file mode 100644
index 0000000..4eb3851
--- /dev/null
+++ b/testapps/TestSatelliteApp/res/layout/activity_SatelliteTransmissionUpdates.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2023 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:orientation="vertical"
+    android:gravity="center"
+    android:paddingLeft="4dp">
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="vertical" >
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content" android:layout_weight="0"
+            android:textColor="@android:color/holo_blue_dark"
+            android:textSize="20dp"
+            android:text="SatelliteTransmissionUpdates APIs"/>
+        <Button
+            android:id="@+id/startSatelliteTransmissionUpdates"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingRight="4dp"
+            android:text="@string/startSatelliteTransmissionUpdates"/>
+        <Button
+            android:id="@+id/stopSatelliteTransmissionUpdates"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingRight="4dp"
+            android:text="@string/stopSatelliteTransmissionUpdates"/>
+        <Button
+            android:id="@+id/Back"
+            android:onClick="Back"
+            android:textColor="@android:color/holo_blue_dark"
+            android:layout_marginTop="100dp"
+            android:layout_gravity="center"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:paddingRight="4dp"
+            android:text="@string/Back"/>
+         <TextView
+            android:id="@+id/text_id"
+            android:layout_width="300dp"
+            android:layout_height="200dp"
+            android:capitalize="characters"
+            android:textColor="@android:color/holo_blue_light"
+            android:layout_centerVertical="true"
+            android:textSize="15dp" />
+    </LinearLayout>
+</LinearLayout>
diff --git a/testapps/TestSatelliteApp/res/values/donottranslate_strings.xml b/testapps/TestSatelliteApp/res/values/donottranslate_strings.xml
new file mode 100644
index 0000000..bd6f389
--- /dev/null
+++ b/testapps/TestSatelliteApp/res/values/donottranslate_strings.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2023 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+
+<resources>
+    <string name="SatelliteControl">SatelliteControl APIs</string>
+    <string name="SatelliteTransmissionUpdates">SatelliteTransmissionUpdates APIs</string>
+    <string name="Datagram">Datagram APIs</string>
+    <string name="Provisioning">Provisioning APIs</string>
+    <string name="SatelliteModemState">SatelliteModemState APIs</string>
+
+    <string name="requestSatelliteEnabled">requestSatelliteEnabled</string>
+    <string name="requestIsSatelliteEnabled">requestIsSatelliteEnabled</string>
+    <string name="requestIsDemoModeEnabled">requestIsDemoModeEnabled</string>
+    <string name="requestIsSatelliteSupported">requestIsSatelliteSupported</string>
+    <string name="requestSatelliteCapabilities">requestSatelliteCapabilities</string>
+    <string name="requestIsSatelliteCommunicationAllowedForCurrentLocation">requestIsSatelliteCommunicationAllowedForCurrentLocation</string>
+    <string name="requestTimeForNextSatelliteVisibility">requestTimeForNextSatelliteVisibility</string>
+
+    <string name="startSatelliteTransmissionUpdates">startSatelliteTransmissionUpdates</string>
+    <string name="stopSatelliteTransmissionUpdates">stopSatelliteTransmissionUpdates</string>
+
+    <string name="pollPendingSatelliteDatagrams">pollPendingSatelliteDatagrams</string>
+    <string name="multiplePollPendingSatelliteDatagrams">multiplePollPendingSatelliteDatagrams</string>
+    <string name="sendSatelliteDatagram">sendSatelliteDatagram</string>
+    <string name="multipleSendSatelliteDatagram">multipleSendSatelliteDatagram</string>
+    <string name="multipleSendReceiveSatelliteDatagram">multipleSendReceiveSatelliteDatagram</string>
+    <string name="registerForSatelliteDatagram">registerForSatelliteDatagram</string>
+    <string name="unregisterForSatelliteDatagram">unregisterForSatelliteDatagram</string>
+
+    <string name="provisionSatelliteService">provisionSatelliteService</string>
+    <string name="deprovisionSatelliteService">deprovisionSatelliteService</string>
+    <string name="requestIsSatelliteProvisioned">requestIsSatelliteProvisioned</string>
+    <string name="registerForSatelliteProvisionStateChanged">registerForSatelliteProvisionStateChanged</string>
+    <string name="unregisterForSatelliteProvisionStateChanged">unregisterForSatelliteProvisionStateChanged</string>
+
+    <string name="registerForSatelliteModemStateChanged">registerForSatelliteModemStateChanged</string>
+    <string name="unregisterForSatelliteModemStateChanged">unregisterForSatelliteModemStateChanged</string>
+
+    <string name="Back">Back</string>
+</resources>
diff --git a/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/Datagram.java b/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/Datagram.java
new file mode 100644
index 0000000..1391c47
--- /dev/null
+++ b/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/Datagram.java
@@ -0,0 +1,240 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.phone.testapps.satellitetestapp;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.telephony.satellite.SatelliteDatagram;
+import android.telephony.satellite.SatelliteDatagramCallback;
+import android.telephony.satellite.SatelliteManager;
+import android.util.Log;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.TextView;
+
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
+import java.util.function.Consumer;
+
+/**
+ * Activity related to Datagram APIs.
+ */
+public class Datagram extends Activity {
+
+    private static final String TAG = "Datagram";
+
+    private SatelliteManager mSatelliteManager;
+    private SatelliteDatagramCallbackTestApp mCallback;
+    private android.telephony.satellite.stub.SatelliteDatagram mReceivedDatagram;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        mSatelliteManager = getSystemService(SatelliteManager.class);
+        mCallback = new SatelliteDatagramCallbackTestApp();
+
+        mReceivedDatagram = new android.telephony.satellite.stub.SatelliteDatagram();
+
+        setContentView(R.layout.activity_Datagram);
+        findViewById(R.id.pollPendingSatelliteDatagrams)
+                .setOnClickListener(this::pollPendingSatelliteDatagramsApp);
+        findViewById(R.id.multiplePollPendingSatelliteDatagrams)
+                .setOnClickListener(this::multiplePollPendingSatelliteDatagramsApp);
+        findViewById(R.id.sendSatelliteDatagram)
+                .setOnClickListener(this::sendSatelliteDatagramApp);
+        findViewById(R.id.multipleSendSatelliteDatagram)
+                .setOnClickListener(this::multipleSendSatelliteDatagramApp);
+        findViewById(R.id.multipleSendReceiveSatelliteDatagram)
+                .setOnClickListener(this::multipleSendReceiveSatelliteDatagramApp);
+        findViewById(R.id.registerForSatelliteDatagram)
+                .setOnClickListener(this::registerForSatelliteDatagramApp);
+        findViewById(R.id.unregisterForSatelliteDatagram)
+                .setOnClickListener(this::unregisterForSatelliteDatagramApp);
+        findViewById(R.id.Back).setOnClickListener(new OnClickListener() {
+            @Override
+            public void onClick(View view) {
+                startActivity(new Intent(Datagram.this, SatelliteTestApp.class));
+            }
+        });
+    }
+
+    protected static class SatelliteDatagramCallbackTestApp implements SatelliteDatagramCallback {
+        @Override
+        public void onSatelliteDatagramReceived(long datagramId, SatelliteDatagram datagram,
+                int pendingCount, Consumer<Void> callback) {
+            Log.d(TAG, "onSatelliteDatagramReceived in SatelliteTestApp: datagramId =" + datagramId
+                    + ", datagram =" + datagram + ", pendingCount=" + pendingCount);
+        }
+    }
+
+    private void pollPendingSatelliteDatagramsApp(View view) {
+        SatelliteTestApp.getTestSatelliteService().sendOnPendingDatagrams();
+        SatelliteTestApp.getTestSatelliteService().sendOnSatelliteDatagramReceived(
+                    mReceivedDatagram, 0);
+        LinkedBlockingQueue<Integer> resultListener = new LinkedBlockingQueue<>(1);
+        mSatelliteManager.pollPendingSatelliteDatagrams(Runnable::run, resultListener::offer);
+        try {
+            Integer value = resultListener.poll(1000, TimeUnit.MILLISECONDS);
+            TextView textView = findViewById(R.id.text_id);
+            if (value == 0) {
+                textView.setText("pollPendingSatelliteDatagrams is Successful");
+            } else {
+                textView.setText("Status for pollPendingSatelliteDatagrams : "
+                        + SatelliteErrorUtils.mapError(value));
+            }
+        } catch (InterruptedException e) {
+            Log.e(TAG, "exception caught =" + e);
+        }
+    }
+
+    private void multiplePollPendingSatelliteDatagramsApp(View view) {
+        SatelliteTestApp.getTestSatelliteService().sendOnPendingDatagrams();
+        SatelliteTestApp.getTestSatelliteService().sendOnSatelliteDatagramReceived(
+                    mReceivedDatagram, 4);
+        LinkedBlockingQueue<Integer> resultListener = new LinkedBlockingQueue<>(1);
+        mSatelliteManager.pollPendingSatelliteDatagrams(Runnable::run, resultListener::offer);
+        SatelliteTestApp.getTestSatelliteService().sendOnSatelliteDatagramReceived(
+                    mReceivedDatagram, 3);
+        mSatelliteManager.pollPendingSatelliteDatagrams(Runnable::run, resultListener::offer);
+        SatelliteTestApp.getTestSatelliteService().sendOnSatelliteDatagramReceived(
+                    mReceivedDatagram, 2);
+        mSatelliteManager.pollPendingSatelliteDatagrams(Runnable::run, resultListener::offer);
+        SatelliteTestApp.getTestSatelliteService().sendOnSatelliteDatagramReceived(
+                    mReceivedDatagram, 1);
+        mSatelliteManager.pollPendingSatelliteDatagrams(Runnable::run, resultListener::offer);
+        SatelliteTestApp.getTestSatelliteService().sendOnSatelliteDatagramReceived(
+                    mReceivedDatagram, 0);
+        mSatelliteManager.pollPendingSatelliteDatagrams(Runnable::run, resultListener::offer);
+        try {
+            Integer value = resultListener.poll(1000, TimeUnit.MILLISECONDS);
+            TextView textView = findViewById(R.id.text_id);
+            if (value == 0) {
+                textView.setText("multiplePollPendingSatelliteDatagrams is Successful");
+            } else {
+                textView.setText("Status for multiplePollPendingSatelliteDatagrams : "
+                        + SatelliteErrorUtils.mapError(value));
+            }
+        } catch (InterruptedException e) {
+            Log.e(TAG, "exception caught =" + e);
+        }
+    }
+
+    private void sendSatelliteDatagramApp(View view) {
+        LinkedBlockingQueue<Integer> resultListener = new LinkedBlockingQueue<>(1);
+        String mText = "This is a test datagram message";
+        SatelliteDatagram datagram = new SatelliteDatagram(mText.getBytes());
+        mSatelliteManager.sendSatelliteDatagram(SatelliteManager.DATAGRAM_TYPE_SOS_MESSAGE,
+                datagram, true, Runnable::run, resultListener::offer);
+        try {
+            Integer value = resultListener.poll(1000, TimeUnit.MILLISECONDS);
+            TextView textView = findViewById(R.id.text_id);
+            if (value == 0) {
+                textView.setText("sendSatelliteDatagram is Successful");
+            } else {
+                textView.setText("Status for sendSatelliteDatagram : "
+                        + SatelliteErrorUtils.mapError(value));
+            }
+        } catch (InterruptedException e) {
+            Log.e(TAG, "exception caught =" + e);
+        }
+    }
+
+    private void multipleSendSatelliteDatagramApp(View view) {
+        LinkedBlockingQueue<Integer> resultListener = new LinkedBlockingQueue<>(1);
+        String mText = "This is a test datagram message";
+        SatelliteDatagram datagram = new SatelliteDatagram(mText.getBytes());
+        mSatelliteManager.sendSatelliteDatagram(SatelliteManager.DATAGRAM_TYPE_SOS_MESSAGE,
+                datagram, true, Runnable::run, resultListener::offer);
+        mSatelliteManager.sendSatelliteDatagram(SatelliteManager.DATAGRAM_TYPE_SOS_MESSAGE,
+                datagram, true, Runnable::run, resultListener::offer);
+        mSatelliteManager.sendSatelliteDatagram(SatelliteManager.DATAGRAM_TYPE_SOS_MESSAGE,
+                datagram, true, Runnable::run, resultListener::offer);
+        mSatelliteManager.sendSatelliteDatagram(SatelliteManager.DATAGRAM_TYPE_SOS_MESSAGE,
+                datagram, true, Runnable::run, resultListener::offer);
+        mSatelliteManager.sendSatelliteDatagram(SatelliteManager.DATAGRAM_TYPE_SOS_MESSAGE,
+                datagram, true, Runnable::run, resultListener::offer);
+        try {
+            Integer value = resultListener.poll(1000, TimeUnit.MILLISECONDS);
+            TextView textView = findViewById(R.id.text_id);
+            if (value == 0) {
+                textView.setText("multipleSendSatelliteDatagram is Successful");
+            } else {
+                textView.setText("Status for multipleSendSatelliteDatagram : "
+                        + SatelliteErrorUtils.mapError(value));
+            }
+        } catch (InterruptedException e) {
+            Log.e(TAG, "exception caught =" + e);
+        }
+    }
+
+    private void multipleSendReceiveSatelliteDatagramApp(View view) {
+        LinkedBlockingQueue<Integer> resultListener = new LinkedBlockingQueue<>(1);
+        String mText = "This is a test datagram message";
+        SatelliteDatagram datagram = new SatelliteDatagram(mText.getBytes());
+        mSatelliteManager.sendSatelliteDatagram(SatelliteManager.DATAGRAM_TYPE_SOS_MESSAGE,
+                datagram, true, Runnable::run, resultListener::offer);
+        SatelliteTestApp.getTestSatelliteService().sendOnSatelliteDatagramReceived(
+                    mReceivedDatagram, 4);
+        mSatelliteManager.pollPendingSatelliteDatagrams(Runnable::run, resultListener::offer);
+        mSatelliteManager.sendSatelliteDatagram(SatelliteManager.DATAGRAM_TYPE_SOS_MESSAGE,
+                datagram, true, Runnable::run, resultListener::offer);
+        SatelliteTestApp.getTestSatelliteService().sendOnSatelliteDatagramReceived(
+                    mReceivedDatagram, 3);
+        mSatelliteManager.sendSatelliteDatagram(SatelliteManager.DATAGRAM_TYPE_SOS_MESSAGE,
+                datagram, true, Runnable::run, resultListener::offer);
+        SatelliteTestApp.getTestSatelliteService().sendOnSatelliteDatagramReceived(
+                    mReceivedDatagram, 2);
+        mSatelliteManager.sendSatelliteDatagram(SatelliteManager.DATAGRAM_TYPE_SOS_MESSAGE,
+                datagram, true, Runnable::run, resultListener::offer);
+        SatelliteTestApp.getTestSatelliteService().sendOnSatelliteDatagramReceived(
+                    mReceivedDatagram, 1);
+        mSatelliteManager.sendSatelliteDatagram(SatelliteManager.DATAGRAM_TYPE_SOS_MESSAGE,
+                datagram, true, Runnable::run, resultListener::offer);
+        SatelliteTestApp.getTestSatelliteService().sendOnSatelliteDatagramReceived(
+                    mReceivedDatagram, 0);
+        try {
+            Integer value = resultListener.poll(1000, TimeUnit.MILLISECONDS);
+            TextView textView = findViewById(R.id.text_id);
+            if (value == 0) {
+                textView.setText("multipleSendReceiveSatelliteDatagram is Successful");
+            } else {
+                textView.setText("Status for multipleSendReceiveSatelliteDatagram : "
+                        + SatelliteErrorUtils.mapError(value));
+            }
+        } catch (InterruptedException e) {
+            Log.e(TAG, "exception caught =" + e);
+        }
+    }
+
+    private void registerForSatelliteDatagramApp(View view) {
+        int result = mSatelliteManager.registerForSatelliteDatagram(Runnable::run, mCallback);
+        TextView textView = findViewById(R.id.text_id);
+        if (result == 0) {
+            textView.setText("registerForSatelliteDatagram is successful");
+        } else {
+            textView.setText("Status for registerForSatelliteDatagram : "
+                    + SatelliteErrorUtils.mapError(result));
+        }
+    }
+
+    private void unregisterForSatelliteDatagramApp(View view) {
+        mSatelliteManager.unregisterForSatelliteDatagram(mCallback);
+        TextView textView = findViewById(R.id.text_id);
+        textView.setText("unregisterForSatelliteDatagram is successful");
+    }
+}
diff --git a/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/ILocalSatelliteListener.aidl b/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/ILocalSatelliteListener.aidl
new file mode 100644
index 0000000..2c320c8
--- /dev/null
+++ b/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/ILocalSatelliteListener.aidl
@@ -0,0 +1,67 @@
+
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.phone.testapps.satellitetestapp;
+
+import android.telephony.satellite.stub.SatelliteDatagram;
+
+/**
+ * {@hide}
+ */
+oneway interface ILocalSatelliteListener {
+    /**
+     * Indicates that the remote service - SatelliteModemInterface - has successfully connected to
+     * the TestSatelliteService.
+     */
+    void onRemoteServiceConnected();
+
+    /**
+     * Indicates that TestSatelliteService has just received the request
+     * startSendingSatellitePointingInfo from Telephony.
+     */
+    void onStartSendingSatellitePointingInfo();
+
+    /**
+     * Indicates that TestSatelliteService has just received the request
+     * stopSendingSatellitePointingInfo from Telephony.
+     */
+    void onStopSendingSatellitePointingInfo();
+
+    /**
+     * Indicates that TestSatelliteService has just received the request
+     * pollPendingSatelliteDatagrams from Telephony.
+     */
+    void onPollPendingSatelliteDatagrams();
+
+    /**
+     * Indicates that TestSatelliteService has just received the request
+     * sendSatelliteDatagram from Telephony.
+     */
+    void onSendSatelliteDatagram(in SatelliteDatagram datagram, in boolean isEmergency);
+
+    /**
+     * Indicates that TestSatelliteService has just received the request
+     * requestSatelliteListeningEnabled from Telephony.
+     */
+    void onSatelliteListeningEnabled(in boolean enabled);
+
+    /**
+     * Indicates that TestSatelliteService has just received the request
+     * enableCellularModemWhileSatelliteModeIsOn from Telephony.
+     */
+    void onEnableCellularModemWhileSatelliteModeIsOn(in boolean enable);
+}
diff --git a/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/Provisioning.java b/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/Provisioning.java
new file mode 100644
index 0000000..b403b2c
--- /dev/null
+++ b/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/Provisioning.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.phone.testapps.satellitetestapp;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.CancellationSignal;
+import android.os.OutcomeReceiver;
+import android.telephony.satellite.SatelliteManager;
+import android.telephony.satellite.SatelliteProvisionStateCallback;
+import android.util.Log;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.TextView;
+
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
+
+/**
+ * Activity related to Provisioning APIs.
+ */
+public class Provisioning extends Activity {
+
+    private static final String TAG = "Provisioning";
+
+    private SatelliteManager mSatelliteManager;
+    private SatelliteProvisionStateCallbackTestApp mCallback;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        mSatelliteManager = getSystemService(SatelliteManager.class);
+        mCallback = new SatelliteProvisionStateCallbackTestApp();
+
+        setContentView(R.layout.activity_Provisioning);
+        findViewById(R.id.provisionSatelliteService)
+                .setOnClickListener(this::provisionSatelliteServiceApp);
+        findViewById(R.id.deprovisionSatelliteService)
+                .setOnClickListener(this::deprovisionSatelliteServiceApp);
+        findViewById(R.id.requestIsSatelliteProvisioned)
+                .setOnClickListener(this::requestIsSatelliteProvisionedApp);
+        findViewById(R.id.registerForSatelliteProvisionStateChanged)
+                .setOnClickListener(this::registerForSatelliteProvisionStateChangedApp);
+        findViewById(R.id.unregisterForSatelliteProvisionStateChanged)
+                .setOnClickListener(this::unregisterForSatelliteProvisionStateChangedApp);
+        findViewById(R.id.Back).setOnClickListener(new OnClickListener() {
+            @Override
+            public void onClick(View view) {
+                startActivity(new Intent(Provisioning.this, SatelliteTestApp.class));
+            }
+        });
+    }
+
+    protected static class SatelliteProvisionStateCallbackTestApp implements
+            SatelliteProvisionStateCallback {
+        @Override
+        public void onSatelliteProvisionStateChanged(boolean provisioned) {
+            Log.d(TAG, "onSatelliteProvisionStateChanged in SatelliteTestApp: provisioned="
+                    + provisioned);
+        }
+    }
+
+    private void provisionSatelliteServiceApp(View view) {
+        CancellationSignal cancellationSignal = new CancellationSignal();
+        LinkedBlockingQueue<Integer> error = new LinkedBlockingQueue<>(1);
+        String mText = "This is test provision data.";
+        byte[] testProvisionData = mText.getBytes();
+        mSatelliteManager.provisionSatelliteService("SATELLITE_TOKEN", testProvisionData,
+                cancellationSignal, Runnable::run, error::offer);
+        try {
+            Integer value = error.poll(1000, TimeUnit.MILLISECONDS);
+            TextView textView = findViewById(R.id.text_id);
+            textView.setText("Status for provisionSatelliteService : "
+                    + SatelliteErrorUtils.mapError(value));
+        } catch (InterruptedException e) {
+            Log.e(TAG, "exception caught =" + e);
+        }
+    }
+
+    private void deprovisionSatelliteServiceApp(View view) {
+        LinkedBlockingQueue<Integer> error = new LinkedBlockingQueue<>(1);
+        mSatelliteManager.deprovisionSatelliteService("SATELLITE_TOKEN", Runnable::run,
+                error::offer);
+        try {
+            Integer value = error.poll(1000, TimeUnit.MILLISECONDS);
+            TextView textView = findViewById(R.id.text_id);
+            textView.setText("Status for deprovisionSatelliteService : "
+                    + SatelliteErrorUtils.mapError(value));
+        } catch (InterruptedException e) {
+            Log.e(TAG, "exception caught =" + e);
+        }
+    }
+
+    private void requestIsSatelliteProvisionedApp(View view) {
+        final AtomicReference<Boolean> enabled = new AtomicReference<>();
+        final AtomicReference<Integer> errorCode = new AtomicReference<>();
+        OutcomeReceiver<Boolean, SatelliteManager.SatelliteException> mReceiver =
+                new OutcomeReceiver<>() {
+            @Override
+            public void onResult(Boolean result) {
+                enabled.set(result);
+                TextView textView = findViewById(R.id.text_id);
+                textView.setText("Status for requestIsSatelliteProvisioned result: "
+                        + enabled.get());
+            }
+
+            @Override
+            public void onError(SatelliteManager.SatelliteException exception) {
+                errorCode.set(exception.getErrorCode());
+                TextView textView = findViewById(R.id.text_id);
+                textView.setText("Status for requestIsSatelliteProvisioned error : "
+                        + SatelliteErrorUtils.mapError(errorCode.get()));
+            }
+        };
+        mSatelliteManager.requestIsSatelliteProvisioned(Runnable::run, mReceiver);
+    }
+
+    private void registerForSatelliteProvisionStateChangedApp(View view) {
+        int result = mSatelliteManager.registerForSatelliteProvisionStateChanged(Runnable::run,
+                mCallback);
+        TextView textView = findViewById(R.id.text_id);
+        textView.setText("Status for registerForSatelliteProvisionStateChanged : "
+                + SatelliteErrorUtils.mapError(result));
+    }
+
+    private void unregisterForSatelliteProvisionStateChangedApp(View view) {
+        mSatelliteManager.unregisterForSatelliteProvisionStateChanged(mCallback);
+        TextView textView = findViewById(R.id.text_id);
+        textView.setText("unregisterForSatelliteProvisionStateChanged is successful");
+    }
+}
diff --git a/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/SatelliteControl.java b/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/SatelliteControl.java
new file mode 100644
index 0000000..9cfbc6a
--- /dev/null
+++ b/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/SatelliteControl.java
@@ -0,0 +1,251 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.phone.testapps.satellitetestapp;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.OutcomeReceiver;
+import android.telephony.satellite.SatelliteCapabilities;
+import android.telephony.satellite.SatelliteManager;
+import android.util.Log;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.TextView;
+
+import java.time.Duration;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
+
+/**
+ * Activity related to SatelliteControl APIs for satellite.
+ */
+public class SatelliteControl extends Activity {
+
+    private static final String TAG = "SatelliteControl";
+
+    private SatelliteManager mSatelliteManager;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        mSatelliteManager = getSystemService(SatelliteManager.class);
+
+        setContentView(R.layout.activity_SatelliteControl);
+        findViewById(R.id.requestSatelliteEnabled)
+                .setOnClickListener(this::requestSatelliteEnabledApp);
+        findViewById(R.id.requestIsSatelliteEnabled)
+                .setOnClickListener(this::requestIsSatelliteEnabledApp);
+        findViewById(R.id.requestIsDemoModeEnabled)
+                .setOnClickListener(this::requestIsDemoModeEnabledApp);
+        findViewById(R.id.requestIsSatelliteSupported)
+                .setOnClickListener(this::requestIsSatelliteSupportedApp);
+        findViewById(R.id.requestSatelliteCapabilities)
+                .setOnClickListener(this::requestSatelliteCapabilitiesApp);
+        findViewById(R.id.requestIsSatelliteCommunicationAllowedForCurrentLocation)
+                .setOnClickListener(
+                this::requestIsSatelliteCommunicationAllowedForCurrentLocationApp);
+        findViewById(R.id.requestTimeForNextSatelliteVisibility)
+                .setOnClickListener(this::requestTimeForNextSatelliteVisibilityApp);
+        findViewById(R.id.Back).setOnClickListener(new OnClickListener() {
+            @Override
+            public void onClick(View view) {
+                startActivity(new Intent(SatelliteControl.this, SatelliteTestApp.class));
+            }
+        });
+    }
+
+    private void requestSatelliteEnabledApp(View view) {
+        LinkedBlockingQueue<Integer> error = new LinkedBlockingQueue<>(1);
+        mSatelliteManager.requestSatelliteEnabled(true, true, Runnable::run, error::offer);
+        try {
+            Integer value = error.poll(1000, TimeUnit.MILLISECONDS);
+            TextView textView = findViewById(R.id.text_id);
+            if (value == 0) {
+                textView.setText("requestSatelliteEnabled is successful");
+            } else {
+                textView.setText("Status for requestSatelliteEnabled: "
+                        + SatelliteErrorUtils.mapError(value));
+            }
+        } catch (InterruptedException e) {
+            Log.e(TAG, "exception caught =" + e);
+        }
+    }
+
+    private void requestIsSatelliteEnabledApp(View view) {
+        final AtomicReference<Boolean> enabled = new AtomicReference<>();
+        final AtomicReference<Integer> errorCode = new AtomicReference<>();
+        OutcomeReceiver<Boolean, SatelliteManager.SatelliteException> receiver =
+                new OutcomeReceiver<>() {
+            @Override
+            public void onResult(Boolean result) {
+                enabled.set(result);
+                TextView textView = findViewById(R.id.text_id);
+                if (enabled.get()) {
+                    textView.setText("requestIsSatelliteEnabled is true");
+                } else {
+                    textView.setText("Status for requestIsSatelliteEnabled result : "
+                            + enabled.get());
+                }
+            }
+
+            @Override
+            public void onError(SatelliteManager.SatelliteException exception) {
+                errorCode.set(exception.getErrorCode());
+                TextView textView = findViewById(R.id.text_id);
+                textView.setText("Status for requestIsSatelliteEnabled error : "
+                        + SatelliteErrorUtils.mapError(errorCode.get()));
+            }
+        };
+        mSatelliteManager.requestIsSatelliteEnabled(Runnable::run, receiver);
+    }
+
+    private void requestIsDemoModeEnabledApp(View view) {
+        final AtomicReference<Boolean> enabled = new AtomicReference<>();
+        final AtomicReference<Integer> errorCode = new AtomicReference<>();
+        OutcomeReceiver<Boolean, SatelliteManager.SatelliteException> receiver =
+                new OutcomeReceiver<>() {
+            @Override
+            public void onResult(Boolean result) {
+                enabled.set(result);
+                TextView textView = findViewById(R.id.text_id);
+                if (enabled.get()) {
+                    textView.setText("requestIsDemoModeEnabled is true");
+                } else {
+                    textView.setText("Status for requestIsDemoModeEnabled result : "
+                            + enabled.get());
+                }
+            }
+
+            @Override
+            public void onError(SatelliteManager.SatelliteException exception) {
+                errorCode.set(exception.getErrorCode());
+                TextView textView = findViewById(R.id.text_id);
+                textView.setText("Status for requestIsDemoModeEnabled error : "
+                        + SatelliteErrorUtils.mapError(errorCode.get()));
+            }
+        };
+        mSatelliteManager.requestIsDemoModeEnabled(Runnable::run, receiver);
+    }
+
+    private void requestIsSatelliteSupportedApp(View view) {
+        final AtomicReference<Boolean> enabled = new AtomicReference<>();
+        final AtomicReference<Integer> errorCode = new AtomicReference<>();
+        OutcomeReceiver<Boolean, SatelliteManager.SatelliteException> receiver =
+                new OutcomeReceiver<>() {
+            @Override
+            public void onResult(Boolean result) {
+                enabled.set(result);
+                TextView textView = findViewById(R.id.text_id);
+                if (enabled.get()) {
+                    textView.setText("requestIsSatelliteSupported is true");
+                } else {
+                    textView.setText("Status for requestIsSatelliteSupported result : "
+                            + enabled.get());
+                }
+            }
+
+            @Override
+            public void onError(SatelliteManager.SatelliteException exception) {
+                errorCode.set(exception.getErrorCode());
+                TextView textView = findViewById(R.id.text_id);
+                textView.setText("Status for requestIsSatelliteSupported error : "
+                        + SatelliteErrorUtils.mapError(errorCode.get()));
+            }
+        };
+        mSatelliteManager.requestIsSatelliteSupported(Runnable::run, receiver);
+    }
+
+    private void requestSatelliteCapabilitiesApp(View view) {
+        final AtomicReference<SatelliteCapabilities> capabilities = new AtomicReference<>();
+        final AtomicReference<Integer> errorCode = new AtomicReference<>();
+        OutcomeReceiver<SatelliteCapabilities, SatelliteManager.SatelliteException> receiver =
+                new OutcomeReceiver<>() {
+            @Override
+            public void onResult(SatelliteCapabilities result) {
+                capabilities.set(result);
+                TextView textView = findViewById(R.id.text_id);
+                textView.setText("Status for requestSatelliteCapabilities result: "
+                        + capabilities.get());
+            }
+
+            @Override
+            public void onError(SatelliteManager.SatelliteException exception) {
+                errorCode.set(exception.getErrorCode());
+                TextView textView = findViewById(R.id.text_id);
+                textView.setText("Status for requestSatelliteCapabilities error : "
+                        + SatelliteErrorUtils.mapError(errorCode.get()));
+            }
+        };
+        mSatelliteManager.requestSatelliteCapabilities(Runnable::run, receiver);
+    }
+
+    private void requestIsSatelliteCommunicationAllowedForCurrentLocationApp(View view) {
+        final AtomicReference<Boolean> enabled = new AtomicReference<>();
+        final AtomicReference<Integer> errorCode = new AtomicReference<>();
+        String display = "requestIsSatelliteCommunicationAllowedForCurrentLocation";
+        OutcomeReceiver<Boolean, SatelliteManager.SatelliteException> receiver =
+                new OutcomeReceiver<>() {
+            @Override
+            public void onResult(Boolean result) {
+                enabled.set(result);
+                TextView textView = findViewById(R.id.text_id);
+                if (enabled.get()) {
+                    textView.setText(display + "is true");
+                } else {
+                    textView.setText("Status for" + display + "result: " + enabled.get());
+                }
+
+            }
+
+            @Override
+            public void onError(SatelliteManager.SatelliteException exception) {
+                errorCode.set(exception.getErrorCode());
+                TextView textView = findViewById(R.id.text_id);
+                textView.setText("Status for"  + display + "error: "
+                        + SatelliteErrorUtils.mapError(errorCode.get()));
+            }
+        };
+        mSatelliteManager.requestIsSatelliteCommunicationAllowedForCurrentLocation(Runnable::run,
+                receiver);
+    }
+
+    private void requestTimeForNextSatelliteVisibilityApp(View view) {
+        final AtomicReference<Duration> nextVisibilityDuration = new AtomicReference<>();
+        final AtomicReference<Integer> errorCode = new AtomicReference<>();
+        OutcomeReceiver<Duration, SatelliteManager.SatelliteException> receiver =
+                new OutcomeReceiver<>() {
+            @Override
+            public void onResult(Duration result) {
+                nextVisibilityDuration.set(result);
+                TextView textView = findViewById(R.id.text_id);
+                textView.setText("Status for requestTimeForNextSatelliteVisibility result : "
+                        + result.getSeconds());
+            }
+
+            @Override
+            public void onError(SatelliteManager.SatelliteException exception) {
+                errorCode.set(exception.getErrorCode());
+                TextView textView = findViewById(R.id.text_id);
+                textView.setText("Status for requestTimeForNextSatelliteVisibility error : "
+                        + SatelliteErrorUtils.mapError(errorCode.get()));
+            }
+        };
+        mSatelliteManager.requestTimeForNextSatelliteVisibility(Runnable::run, receiver);
+    }
+}
diff --git a/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/SatelliteErrorUtils.java b/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/SatelliteErrorUtils.java
new file mode 100644
index 0000000..a52d3ba
--- /dev/null
+++ b/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/SatelliteErrorUtils.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.phone.testapps.satellitetestapp;
+
+import android.telephony.satellite.stub.SatelliteError;
+import android.util.Log;
+
+/**
+ * Utils class for satellite error to display as string in SatelliteTestApp UI.
+ */
+public class SatelliteErrorUtils {
+    private static final String TAG = "SatelliteErrorUtils";
+
+   /**
+     * @param error int from the satellite manager.
+     * @return The converted SatelliteError for the testapp, result of the operation.
+     */
+    public static String mapError(int error) {
+        switch (error) {
+            case SatelliteError.ERROR_NONE:
+                return "SATELLITE_ERROR_NONE";
+            case SatelliteError.SATELLITE_ERROR:
+                return "SATELLITE_ERROR";
+            case SatelliteError.SERVER_ERROR:
+                return "SATELLITE_SERVER_ERROR";
+            case SatelliteError.SERVICE_ERROR:
+                return "SATELLITE_SERVICE_ERROR";
+            case SatelliteError.MODEM_ERROR:
+                return "SATELLITE_MODEM_ERROR";
+            case SatelliteError.NETWORK_ERROR:
+                return "SATELLITE_NETWORK_ERROR";
+            case SatelliteError.INVALID_TELEPHONY_STATE:
+                return "SATELLITE_INVALID_TELEPHONY_STATE";
+            case SatelliteError.INVALID_MODEM_STATE:
+                return "SATELLITE_INVALID_MODEM_STATE";
+            case SatelliteError.INVALID_ARGUMENTS:
+                return "SATELLITE_INVALID_ARGUMENTS";
+            case SatelliteError.REQUEST_FAILED:
+                return "SATELLITE_REQUEST_FAILED";
+            case SatelliteError.RADIO_NOT_AVAILABLE:
+                return "SATELLITE_RADIO_NOT_AVAILABLE";
+            case SatelliteError.REQUEST_NOT_SUPPORTED:
+                return "SATELLITE_REQUEST_NOT_SUPPORTED";
+            case SatelliteError.NO_RESOURCES:
+                return "SATELLITE_NO_RESOURCES";
+            case SatelliteError.SERVICE_NOT_PROVISIONED:
+                return "SATELLITE_SERVICE_NOT_PROVISIONED";
+            case SatelliteError.SERVICE_PROVISION_IN_PROGRESS:
+                return "SATELLITE_SERVICE_PROVISION_IN_PROGRESS";
+            case SatelliteError.REQUEST_ABORTED:
+                return "SATELLITE_REQUEST_ABORTED";
+            case SatelliteError.SATELLITE_ACCESS_BARRED:
+                return "SATELLITE_ACCESS_BARRED";
+            case SatelliteError.NETWORK_TIMEOUT:
+                return "SATELLITE_NETWORK_TIMEOUT";
+            case SatelliteError.SATELLITE_NOT_REACHABLE:
+                return "SATELLITE_NOT_REACHABLE";
+            case SatelliteError.NOT_AUTHORIZED:
+                return "SATELLITE_NOT_AUTHORIZED";
+        }
+        Log.d(TAG, "Received invalid satellite service error: " + error);
+        return "SATELLITE_SERVICE_ERROR";
+    }
+}
diff --git a/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/SatelliteModemState.java b/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/SatelliteModemState.java
new file mode 100644
index 0000000..aa0d5b0
--- /dev/null
+++ b/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/SatelliteModemState.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.phone.testapps.satellitetestapp;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.telephony.satellite.SatelliteManager;
+import android.telephony.satellite.SatelliteStateCallback;
+import android.util.Log;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.TextView;
+
+/**
+ * Activity related to SatelliteModemState APIs.
+ */
+public class SatelliteModemState extends Activity {
+
+    private static final String TAG = "SatelliteModemState";
+
+    private SatelliteManager mSatelliteManager;
+    private SatelliteStateCallbackTestApp mCallback;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        mSatelliteManager = getSystemService(SatelliteManager.class);
+        mCallback = new SatelliteStateCallbackTestApp();
+
+        setContentView(R.layout.activity_SatelliteModemState);
+        findViewById(R.id.registerForSatelliteModemStateChanged)
+                .setOnClickListener(this::registerForSatelliteModemStateChangedApp);
+        findViewById(R.id.unregisterForSatelliteModemStateChanged)
+                .setOnClickListener(this::unregisterForSatelliteModemStateChangedApp);
+        findViewById(R.id.Back).setOnClickListener(new OnClickListener() {
+            @Override
+            public void onClick(View view) {
+                startActivity(new Intent(SatelliteModemState.this, SatelliteTestApp.class));
+            }
+        });
+    }
+
+    protected static class SatelliteStateCallbackTestApp implements SatelliteStateCallback {
+        @Override
+        public void onSatelliteModemStateChanged(int state) {
+            Log.d(TAG, "onSatelliteModemStateChanged in SatelliteTestApp: state=" + state);
+        }
+    }
+
+    private void registerForSatelliteModemStateChangedApp(View view) {
+        int result = mSatelliteManager.registerForSatelliteModemStateChanged(Runnable::run,
+                mCallback);
+        TextView textView = findViewById(R.id.text_id);
+        if (result == 0) {
+            textView.setText("registerForSatelliteModemStateChanged is successful");
+        } else {
+            textView.setText("Status for registerForSatelliteModemStateChanged : "
+                    + SatelliteErrorUtils.mapError(result));
+        }
+    }
+
+    private void unregisterForSatelliteModemStateChangedApp(View view) {
+        mSatelliteManager.unregisterForSatelliteModemStateChanged(mCallback);
+        TextView textView = findViewById(R.id.text_id);
+        textView.setText("unregisterForSatelliteModemStateChanged is successful");
+    }
+}
+
diff --git a/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/SatelliteTestApp.java b/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/SatelliteTestApp.java
new file mode 100644
index 0000000..ed5b75e
--- /dev/null
+++ b/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/SatelliteTestApp.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.phone.testapps.satellitetestapp;
+
+import android.app.Activity;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.telephony.satellite.stub.SatelliteDatagram;
+import android.util.Log;
+import android.view.View;
+import android.view.View.OnClickListener;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * SatelliteTestApp main activity to navigate to other APIs related to satellite.
+ */
+public class SatelliteTestApp extends Activity {
+
+    private static final String TAG = "SatelliteTestApp";
+    private static TestSatelliteService sSatelliteService;
+    private final Object mSendDatagramLock = new Object();
+
+    private TestSatelliteServiceConnection mSatelliteServiceConn;
+    private List<SatelliteDatagram> mSentSatelliteDatagrams = new ArrayList<>();
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        if (mSatelliteServiceConn == null) {
+            mSatelliteServiceConn = new TestSatelliteServiceConnection();
+            getBaseContext().bindService(new Intent(getBaseContext(),
+                    TestSatelliteService.class), mSatelliteServiceConn, Context.BIND_AUTO_CREATE);
+        }
+
+        setContentView(R.layout.activity_SatelliteTestApp);
+        findViewById(R.id.SatelliteControl).setOnClickListener(new OnClickListener() {
+            @Override
+            public void onClick(View view) {
+                Intent intent = new Intent(SatelliteTestApp.this, SatelliteControl.class);
+                startActivity(intent);
+            }
+        });
+        findViewById(R.id.SatelliteTransmissionUpdates).setOnClickListener(new OnClickListener() {
+            @Override
+            public void onClick(View view) {
+                Intent intent = new Intent(SatelliteTestApp.this,
+                        SatelliteTransmissionUpdates.class);
+                startActivity(intent);
+            }
+        });
+        findViewById(R.id.Datagram).setOnClickListener(new OnClickListener() {
+            @Override
+            public void onClick(View view) {
+                Intent intent = new Intent(SatelliteTestApp.this, Datagram.class);
+                startActivity(intent);
+            }
+        });
+        findViewById(R.id.Provisioning).setOnClickListener(new OnClickListener() {
+            @Override
+            public void onClick(View view) {
+                Intent intent = new Intent(SatelliteTestApp.this, Provisioning.class);
+                startActivity(intent);
+            }
+        });
+        findViewById(R.id.SatelliteModemState).setOnClickListener(new OnClickListener() {
+            @Override
+            public void onClick(View view) {
+                Intent intent = new Intent(SatelliteTestApp.this, SatelliteModemState.class);
+                startActivity(intent);
+            }
+        });
+    }
+
+    private final ILocalSatelliteListener mSatelliteListener =
+            new ILocalSatelliteListener.Stub() {
+                @Override
+                public void onRemoteServiceConnected() {
+                    Log.d(TAG, "onRemoteServiceConnected");
+                }
+
+                @Override
+                public void onStartSendingSatellitePointingInfo() {
+                    Log.d(TAG, "onStartSendingSatellitePointingInfo");
+                }
+
+                @Override
+                public void onStopSendingSatellitePointingInfo() {
+                    Log.d(TAG, "onStopSendingSatellitePointingInfo");
+                }
+
+                @Override
+                public void onPollPendingSatelliteDatagrams() {
+                    Log.d(TAG, "onPollPendingSatelliteDatagrams");
+                }
+
+                @Override
+                public void onSendSatelliteDatagram(
+                        SatelliteDatagram datagram, boolean isEmergency) {
+                    Log.d(TAG, "onSendSatelliteDatagram");
+                    synchronized (mSendDatagramLock) {
+                        mSentSatelliteDatagrams.add(datagram);
+                    }
+                }
+
+                @Override
+                public void onSatelliteListeningEnabled(boolean enable) {
+                    Log.d(TAG, "onSatelliteListeningEnabled");
+                }
+
+                @Override
+                public void onEnableCellularModemWhileSatelliteModeIsOn(boolean enable) {
+                    Log.d(TAG, "onEnableCellularModemWhileSatelliteModeIsOn");
+                }
+            };
+
+    private class TestSatelliteServiceConnection implements ServiceConnection {
+        @Override
+        public void onServiceConnected(ComponentName name, IBinder service) {
+            Log.d(TAG, "onServiceConnected in SatelliteTestApp");
+            sSatelliteService = ((TestSatelliteService.LocalBinder) service).getService();
+            sSatelliteService.setLocalSatelliteListener(mSatelliteListener);
+        }
+
+        @Override
+        public void onServiceDisconnected(ComponentName name) {
+            Log.d(TAG, "onServiceDisconnected in SatelliteTestApp");
+            sSatelliteService = null;
+        }
+    }
+
+    public static TestSatelliteService getTestSatelliteService() {
+        return sSatelliteService;
+    }
+}
diff --git a/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/SatelliteTransmissionUpdates.java b/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/SatelliteTransmissionUpdates.java
new file mode 100644
index 0000000..368f519
--- /dev/null
+++ b/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/SatelliteTransmissionUpdates.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.phone.testapps.satellitetestapp;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.telephony.satellite.PointingInfo;
+import android.telephony.satellite.SatelliteManager;
+import android.telephony.satellite.SatelliteTransmissionUpdateCallback;
+import android.util.Log;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.TextView;
+
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Activity related to SatelliteTransmissionUpdates APIs.
+ */
+public class SatelliteTransmissionUpdates extends Activity {
+
+    private static final String TAG = "SatelliteTransmissionUpdates";
+
+    private SatelliteManager mSatelliteManager;
+    private SatelliteTransmissionUpdateCallbackTestApp mCallback;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        mSatelliteManager = getSystemService(SatelliteManager.class);
+        mCallback = new SatelliteTransmissionUpdateCallbackTestApp();
+
+        setContentView(R.layout.activity_SatelliteTransmissionUpdates);
+        findViewById(R.id.startSatelliteTransmissionUpdates)
+                .setOnClickListener(this::startSatelliteTransmissionUpdatesApp);
+        findViewById(R.id.stopSatelliteTransmissionUpdates)
+                .setOnClickListener(this::stopSatelliteTransmissionUpdatesApp);
+        findViewById(R.id.Back).setOnClickListener(new OnClickListener() {
+            @Override
+            public void onClick(View view) {
+                startActivity(new Intent(SatelliteTransmissionUpdates.this,
+                        SatelliteTestApp.class));
+            }
+        });
+    }
+
+    protected static class SatelliteTransmissionUpdateCallbackTestApp implements
+            SatelliteTransmissionUpdateCallback {
+        @Override
+        public void onSatellitePositionChanged(PointingInfo pointingInfo) {
+            Log.d(TAG, "onSatellitePositionChanged in TestApp: pointingInfo =" + pointingInfo);
+        }
+
+        @Override
+        public void onSendDatagramStateChanged(int state, int sendPendingCount, int errorCode) {
+            Log.d(TAG, "onSendDatagramStateChanged in TestApp: state =" + state
+                    + ", sendPendingCount =" + sendPendingCount + ", errorCode=" + errorCode);
+        }
+
+        @Override
+        public void onReceiveDatagramStateChanged(
+                int state, int receivePendingCount, int errorCode) {
+            Log.d(TAG, "onReceiveDatagramStateChanged in TestApp: state=" + state + ", "
+                    + "receivePendingCount=" + receivePendingCount + ", errorCode=" + errorCode);
+        }
+    }
+
+    private void startSatelliteTransmissionUpdatesApp(View view) {
+        LinkedBlockingQueue<Integer> error = new LinkedBlockingQueue<>(1);
+        mSatelliteManager.startSatelliteTransmissionUpdates(Runnable::run, error::offer, mCallback);
+        try {
+            Integer value = error.poll(1000, TimeUnit.MILLISECONDS);
+            TextView textView = findViewById(R.id.text_id);
+            if (value == 0) {
+                textView.setText("startSatelliteTransmissionUpdates is Successful");
+            } else {
+                textView.setText("Status for startSatelliteTransmissionUpdates : "
+                        + SatelliteErrorUtils.mapError(value));
+            }
+        } catch (InterruptedException e) {
+            Log.e(TAG, "exception caught =" + e);
+        }
+    }
+
+    private void stopSatelliteTransmissionUpdatesApp(View view) {
+        LinkedBlockingQueue<Integer> error = new LinkedBlockingQueue<>(1);
+        mSatelliteManager.stopSatelliteTransmissionUpdates(mCallback, Runnable::run, error::offer);
+        try {
+            Integer value = error.poll(1000, TimeUnit.MILLISECONDS);
+            TextView textView = findViewById(R.id.text_id);
+            if (value == 0) {
+                textView.setText("stopSatelliteTransmissionUpdates is Successful");
+            } else {
+                textView.setText("Status for stopSatelliteTransmissionUpdates : "
+                        + SatelliteErrorUtils.mapError(value));
+            }
+        } catch (InterruptedException e) {
+            Log.e(TAG, "exception caught =" + e);
+        }
+    }
+}
diff --git a/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/TestSatelliteService.java b/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/TestSatelliteService.java
new file mode 100644
index 0000000..5c7f4a2
--- /dev/null
+++ b/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/TestSatelliteService.java
@@ -0,0 +1,542 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.phone.testapps.satellitetestapp;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.Intent;
+import android.os.Binder;
+import android.os.IBinder;
+import android.telephony.satellite.AntennaDirection;
+import android.telephony.satellite.AntennaPosition;
+import android.telephony.satellite.SatelliteManager;
+import android.telephony.satellite.stub.ISatelliteCapabilitiesConsumer;
+import android.telephony.satellite.stub.ISatelliteListener;
+import android.telephony.satellite.stub.NTRadioTechnology;
+import android.telephony.satellite.stub.PointingInfo;
+import android.telephony.satellite.stub.SatelliteCapabilities;
+import android.telephony.satellite.stub.SatelliteDatagram;
+import android.telephony.satellite.stub.SatelliteError;
+import android.telephony.satellite.stub.SatelliteImplBase;
+import android.telephony.satellite.stub.SatelliteModemState;
+import android.telephony.satellite.stub.SatelliteService;
+import android.util.Log;
+
+import com.android.internal.telephony.IBooleanConsumer;
+import com.android.internal.telephony.IIntegerConsumer;
+import com.android.internal.util.FunctionalUtils;
+import com.android.telephony.Rlog;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.Executor;
+
+/**
+ * Test service for Satellite to verify end to end flow via testapp.
+ */
+public class TestSatelliteService extends SatelliteImplBase {
+    private static final String TAG = "TestSatelliteService";
+
+    // Hardcoded values below
+    private static final int SATELLITE_ALWAYS_VISIBLE = 0;
+    /** SatelliteCapabilities constant indicating that the radio technology is proprietary. */
+    private static final int[] SUPPORTED_RADIO_TECHNOLOGIES =
+            new int[]{NTRadioTechnology.PROPRIETARY};
+    /** SatelliteCapabilities constant indicating that pointing to satellite is required. */
+    private static final boolean POINTING_TO_SATELLITE_REQUIRED = true;
+    /** SatelliteCapabilities constant indicating the maximum number of characters per datagram. */
+    private static final int MAX_BYTES_PER_DATAGRAM = 339;
+    /** SatelliteCapabilities constant keys which are used to fill mAntennaPositionMap. */
+    private static final int[] ANTENNA_POSITION_KEYS = new int[]{
+            SatelliteManager.DISPLAY_MODE_OPENED, SatelliteManager.DISPLAY_MODE_CLOSED};
+    /** SatelliteCapabilities constant values which are used to fill mAntennaPositionMap. */
+    private static final AntennaPosition[] ANTENNA_POSITION_VALUES = new AntennaPosition[] {
+            new AntennaPosition(new AntennaDirection(1, 1, 1),
+                    SatelliteManager.DEVICE_HOLD_POSITION_PORTRAIT),
+            new AntennaPosition(new AntennaDirection(2, 2, 2),
+                    SatelliteManager.DEVICE_HOLD_POSITION_LANDSCAPE_LEFT)
+    };
+
+    @NonNull
+    private final Map<IBinder, ISatelliteListener> mRemoteListeners = new HashMap<>();
+    @Nullable private ILocalSatelliteListener mLocalListener;
+    private final LocalBinder mBinder = new LocalBinder();
+    @SatelliteError
+    private int mErrorCode = SatelliteError.ERROR_NONE;
+
+    // For local access of this Service.
+    class LocalBinder extends Binder {
+        TestSatelliteService getService() {
+            return TestSatelliteService.this;
+        }
+    }
+
+    private boolean mIsCommunicationAllowedInLocation;
+    private boolean mIsEnabled;
+    private boolean mIsProvisioned;
+    private boolean mIsSupported;
+    private int mModemState;
+    private boolean mIsCellularModemEnabledMode;
+
+    /**
+     * Create TestSatelliteService using the Executor specified for methods being called from
+     * the framework.
+     *
+     * @param executor The executor for the framework to use when executing satellite methods.
+     */
+    public TestSatelliteService(@NonNull Executor executor) {
+        super(executor);
+        mIsCommunicationAllowedInLocation = true;
+        mIsEnabled = false;
+        mIsProvisioned = false;
+        mIsSupported = true;
+        mModemState = SatelliteModemState.SATELLITE_MODEM_STATE_OFF;
+        mIsCellularModemEnabledMode = false;
+    }
+
+    /**
+     * Zero-argument constructor to prevent service binding exception.
+     */
+    public TestSatelliteService() {
+        this(Runnable::run);
+    }
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        if (SatelliteService.SERVICE_INTERFACE.equals(intent.getAction())) {
+            logd("Remote service bound");
+            return getBinder();
+        }
+        logd("Local service bound");
+        return mBinder;
+    }
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+        logd("onCreate");
+    }
+
+    @Override
+    public void onDestroy() {
+        super.onDestroy();
+        logd("onDestroy");
+    }
+
+    @Override
+    public void setSatelliteListener(@NonNull ISatelliteListener listener) {
+        logd("setSatelliteListener");
+        mRemoteListeners.put(listener.asBinder(), listener);
+        notifyRemoteServiceConnected();
+    }
+
+    @Override
+    public void requestSatelliteListeningEnabled(boolean enabled, int timeout,
+            @NonNull IIntegerConsumer errorCallback) {
+        logd("requestSatelliteListeningEnabled: mErrorCode=" + mErrorCode);
+
+        if (mLocalListener != null) {
+            runWithExecutor(() -> mLocalListener.onSatelliteListeningEnabled(enabled));
+        } else {
+            loge("requestSatelliteListeningEnabled: mLocalListener is null");
+        }
+
+        if (!verifySatelliteModemState(errorCallback)) {
+            return;
+        }
+        if (mErrorCode != SatelliteError.ERROR_NONE) {
+            runWithExecutor(() -> errorCallback.accept(mErrorCode));
+            return;
+        }
+
+        if (enabled) {
+            updateSatelliteModemState(SatelliteModemState.SATELLITE_MODEM_STATE_LISTENING);
+        } else {
+            updateSatelliteModemState(SatelliteModemState.SATELLITE_MODEM_STATE_IDLE);
+        }
+        runWithExecutor(() -> errorCallback.accept(SatelliteError.ERROR_NONE));
+    }
+
+    @Override
+    public void requestSatelliteEnabled(boolean enableSatellite, boolean enableDemoMode,
+            @NonNull IIntegerConsumer errorCallback) {
+        logd("requestSatelliteEnabled: mErrorCode=" + mErrorCode + " enable = " + enableSatellite
+                + "mIsCellularModemEnabledMode = " + mIsCellularModemEnabledMode);
+        if (mErrorCode != SatelliteError.ERROR_NONE) {
+            runWithExecutor(() -> errorCallback.accept(mErrorCode));
+            return;
+        }
+
+        if (enableSatellite) {
+            enableSatellite(errorCallback);
+        } else {
+            mIsCellularModemEnabledMode = false;
+            disableSatellite(errorCallback);
+        }
+    }
+
+    @Override
+    public void enableCellularModemWhileSatelliteModeIsOn(boolean enable,
+             @NonNull IIntegerConsumer errorCallback) {
+        logd("enableCellularModemWhileSatelliteModeIsOn :" + enable + " error Code = " + mErrorCode
+                    + "mIsCellularModemEnabledMode = " + mIsCellularModemEnabledMode
+                    + " mIsEnabled = " + mIsEnabled);
+        if (mLocalListener != null) {
+            runWithExecutor(() -> mLocalListener
+                    .onEnableCellularModemWhileSatelliteModeIsOn(enable));
+        } else {
+            loge("requestSatelliteListeningEnabled: mLocalListener is null");
+        }
+        if (mIsEnabled) {
+            if (enable) {
+                mIsCellularModemEnabledMode = true;
+                disableSatellite(errorCallback);
+            } else {
+                mIsCellularModemEnabledMode = false;
+                enableSatellite(errorCallback);
+            }
+        } else {
+            final int finalError = SatelliteError.INVALID_MODEM_STATE;
+            runWithExecutor(() -> errorCallback.accept(finalError));
+        }
+
+    }
+    private void enableSatellite(@NonNull IIntegerConsumer errorCallback) {
+        mIsEnabled = true;
+        updateSatelliteModemState(SatelliteModemState.SATELLITE_MODEM_STATE_IDLE);
+        runWithExecutor(() -> errorCallback.accept(SatelliteError.ERROR_NONE));
+    }
+
+    private void disableSatellite(@NonNull IIntegerConsumer errorCallback) {
+        mIsEnabled = false;
+        updateSatelliteModemState(SatelliteModemState.SATELLITE_MODEM_STATE_OFF);
+        runWithExecutor(() -> errorCallback.accept(SatelliteError.ERROR_NONE));
+    }
+
+    @Override
+    public void requestIsSatelliteEnabled(@NonNull IIntegerConsumer errorCallback,
+            @NonNull IBooleanConsumer callback) {
+        logd("requestIsSatelliteEnabled: mErrorCode=" + mErrorCode);
+        if (mErrorCode != SatelliteError.ERROR_NONE) {
+            runWithExecutor(() -> errorCallback.accept(mErrorCode));
+            return;
+        }
+        runWithExecutor(() -> callback.accept(mIsEnabled));
+    }
+
+    @Override
+    public void requestIsSatelliteSupported(@NonNull IIntegerConsumer errorCallback,
+            @NonNull IBooleanConsumer callback) {
+        logd("requestIsSatelliteSupported");
+        if (mErrorCode != SatelliteError.ERROR_NONE) {
+            runWithExecutor(() -> errorCallback.accept(mErrorCode));
+            return;
+        }
+        runWithExecutor(() -> callback.accept(mIsSupported));
+    }
+
+    @Override
+    public void requestSatelliteCapabilities(@NonNull IIntegerConsumer errorCallback,
+            @NonNull ISatelliteCapabilitiesConsumer callback) {
+        logd("requestSatelliteCapabilities: mErrorCode=" + mErrorCode);
+        if (mErrorCode != SatelliteError.ERROR_NONE) {
+            runWithExecutor(() -> errorCallback.accept(mErrorCode));
+            return;
+        }
+
+        SatelliteCapabilities capabilities = new SatelliteCapabilities();
+        capabilities.supportedRadioTechnologies = SUPPORTED_RADIO_TECHNOLOGIES;
+        capabilities.isPointingRequired = POINTING_TO_SATELLITE_REQUIRED;
+        capabilities.maxBytesPerOutgoingDatagram = MAX_BYTES_PER_DATAGRAM;
+        capabilities.antennaPositionKeys = ANTENNA_POSITION_KEYS;
+        capabilities.antennaPositionValues = ANTENNA_POSITION_VALUES;
+        runWithExecutor(() -> callback.accept(capabilities));
+    }
+
+    @Override
+    public void startSendingSatellitePointingInfo(@NonNull IIntegerConsumer errorCallback) {
+        logd("startSendingSatellitePointingInfo: mErrorCode=" + mErrorCode);
+        if (!verifySatelliteModemState(errorCallback)) {
+            if (mLocalListener != null) {
+                runWithExecutor(() -> mLocalListener.onStartSendingSatellitePointingInfo());
+            } else {
+                loge("startSendingSatellitePointingInfo: mLocalListener is null");
+            }
+            return;
+        }
+
+        if (mErrorCode != SatelliteError.ERROR_NONE) {
+            runWithExecutor(() -> errorCallback.accept(mErrorCode));
+        } else {
+            runWithExecutor(() -> errorCallback.accept(SatelliteError.ERROR_NONE));
+        }
+
+        if (mLocalListener != null) {
+            runWithExecutor(() -> mLocalListener.onStartSendingSatellitePointingInfo());
+        } else {
+            loge("startSendingSatellitePointingInfo: mLocalListener is null");
+        }
+    }
+
+    @Override
+    public void stopSendingSatellitePointingInfo(@NonNull IIntegerConsumer errorCallback) {
+        logd("stopSendingSatellitePointingInfo: mErrorCode=" + mErrorCode);
+        if (mErrorCode != SatelliteError.ERROR_NONE) {
+            runWithExecutor(() -> errorCallback.accept(mErrorCode));
+        } else {
+            runWithExecutor(() -> errorCallback.accept(SatelliteError.ERROR_NONE));
+        }
+
+        if (mLocalListener != null) {
+            runWithExecutor(() -> mLocalListener.onStopSendingSatellitePointingInfo());
+        } else {
+            loge("stopSendingSatellitePointingInfo: mLocalListener is null");
+        }
+    }
+
+    @Override
+    public void provisionSatelliteService(@NonNull String token, @NonNull byte[] provisionData,
+            @NonNull IIntegerConsumer errorCallback) {
+        logd("provisionSatelliteService: mErrorCode=" + mErrorCode);
+        if (mErrorCode != SatelliteError.ERROR_NONE) {
+            runWithExecutor(() -> errorCallback.accept(mErrorCode));
+            return;
+        }
+        runWithExecutor(() -> errorCallback.accept(SatelliteError.ERROR_NONE));
+        updateSatelliteProvisionState(true);
+    }
+
+    @Override
+    public void deprovisionSatelliteService(@NonNull String token,
+            @NonNull IIntegerConsumer errorCallback) {
+        logd("deprovisionSatelliteService: mErrorCode=" + mErrorCode);
+        if (mErrorCode != SatelliteError.ERROR_NONE) {
+            runWithExecutor(() -> errorCallback.accept(mErrorCode));
+            return;
+        }
+        runWithExecutor(() -> errorCallback.accept(SatelliteError.ERROR_NONE));
+        updateSatelliteProvisionState(false);
+    }
+
+    @Override
+    public void requestIsSatelliteProvisioned(@NonNull IIntegerConsumer errorCallback,
+            @NonNull IBooleanConsumer callback) {
+        logd("requestIsSatelliteProvisioned: mErrorCode=" + mErrorCode);
+        if (mErrorCode != SatelliteError.ERROR_NONE) {
+            runWithExecutor(() -> errorCallback.accept(mErrorCode));
+            return;
+        }
+        runWithExecutor(() -> callback.accept(mIsProvisioned));
+    }
+
+    @Override
+    public void pollPendingSatelliteDatagrams(@NonNull IIntegerConsumer errorCallback) {
+        logd("pollPendingSatelliteDatagrams: mErrorCode=" + mErrorCode);
+        if (mErrorCode != SatelliteError.ERROR_NONE) {
+            runWithExecutor(() -> errorCallback.accept(mErrorCode));
+        } else {
+            runWithExecutor(() -> errorCallback.accept(SatelliteError.ERROR_NONE));
+        }
+
+        if (mLocalListener != null) {
+            runWithExecutor(() -> mLocalListener.onPollPendingSatelliteDatagrams());
+        } else {
+            loge("pollPendingSatelliteDatagrams: mLocalListener is null");
+        }
+    }
+
+    @Override
+    public void sendSatelliteDatagram(@NonNull SatelliteDatagram datagram, boolean isEmergency,
+            @NonNull IIntegerConsumer errorCallback) {
+        logd("sendSatelliteDatagram: mErrorCode=" + mErrorCode);
+        if (mErrorCode != SatelliteError.ERROR_NONE) {
+            runWithExecutor(() -> errorCallback.accept(mErrorCode));
+        } else {
+            runWithExecutor(() -> errorCallback.accept(SatelliteError.ERROR_NONE));
+        }
+
+        if (mLocalListener != null) {
+            runWithExecutor(() -> mLocalListener.onSendSatelliteDatagram(datagram, isEmergency));
+        } else {
+            loge("sendSatelliteDatagram: mLocalListener is null");
+        }
+    }
+
+    @Override
+    public void requestSatelliteModemState(@NonNull IIntegerConsumer errorCallback,
+            @NonNull IIntegerConsumer callback) {
+        logd("requestSatelliteModemState: mErrorCode=" + mErrorCode);
+        if (mErrorCode != SatelliteError.ERROR_NONE) {
+            runWithExecutor(() -> errorCallback.accept(mErrorCode));
+            return;
+        }
+        runWithExecutor(() -> callback.accept(mModemState));
+    }
+
+    @Override
+    public void requestIsSatelliteCommunicationAllowedForCurrentLocation(
+            @NonNull IIntegerConsumer errorCallback, @NonNull IBooleanConsumer callback) {
+        logd("requestIsSatelliteCommunicationAllowedForCurrentLocation: mErrorCode=" + mErrorCode);
+        if (mErrorCode != SatelliteError.ERROR_NONE) {
+            runWithExecutor(() -> errorCallback.accept(mErrorCode));
+            return;
+        }
+
+        if (mIsCommunicationAllowedInLocation) {
+            runWithExecutor(() -> callback.accept(true));
+        } else {
+            runWithExecutor(() -> callback.accept(false));
+        }
+    }
+
+    @Override
+    public void requestTimeForNextSatelliteVisibility(@NonNull IIntegerConsumer errorCallback,
+            @NonNull IIntegerConsumer callback) {
+        logd("requestTimeForNextSatelliteVisibility: mErrorCode=" + mErrorCode);
+        if (mErrorCode != SatelliteError.ERROR_NONE) {
+            runWithExecutor(() -> errorCallback.accept(mErrorCode));
+            return;
+        }
+        runWithExecutor(() -> callback.accept(SATELLITE_ALWAYS_VISIBLE));
+    }
+
+    public void setLocalSatelliteListener(@NonNull ILocalSatelliteListener listener) {
+        logd("setLocalSatelliteListener: listener=" + listener);
+        mLocalListener = listener;
+    }
+
+    public void setErrorCode(@SatelliteError int errorCode) {
+        logd("setErrorCode: errorCode=" + errorCode);
+        mErrorCode = errorCode;
+    }
+
+    public void setSatelliteSupport(boolean supported) {
+        logd("setSatelliteSupport: supported=" + supported);
+        mIsSupported = supported;
+    }
+
+    public void sendOnSatelliteDatagramReceived(SatelliteDatagram datagram, int pendingCount) {
+        logd("sendOnSatelliteDatagramReceived");
+        mRemoteListeners.values().forEach(listener -> runWithExecutor(() ->
+                listener.onSatelliteDatagramReceived(datagram, pendingCount)));
+    }
+
+    public void sendOnPendingDatagrams() {
+        logd("sendOnPendingDatagrams");
+        mRemoteListeners.values().forEach(listener -> runWithExecutor(() ->
+                listener.onPendingDatagrams()));
+    }
+
+    public void sendOnSatellitePositionChanged(PointingInfo pointingInfo) {
+        logd("sendOnSatellitePositionChanged");
+        mRemoteListeners.values().forEach(listener -> runWithExecutor(() ->
+                listener.onSatellitePositionChanged(pointingInfo)));
+    }
+
+    /**
+     * Helper method to verify that the satellite modem is properly configured to receive
+     * requests.
+     *
+     * @param errorCallback The callback to notify of any errors preventing satellite requests.
+     * @return {@code true} if the satellite modem is configured to receive requests and
+     * {@code false} if it is not.
+     */
+    private boolean verifySatelliteModemState(@NonNull IIntegerConsumer errorCallback) {
+        if (!mIsSupported) {
+            runWithExecutor(() -> errorCallback.accept(SatelliteError.REQUEST_NOT_SUPPORTED));
+            return false;
+        }
+        if (!mIsProvisioned) {
+            runWithExecutor(() -> errorCallback.accept(SatelliteError.SERVICE_NOT_PROVISIONED));
+            return false;
+        }
+        if (!mIsEnabled) {
+            runWithExecutor(() -> errorCallback.accept(SatelliteError.INVALID_MODEM_STATE));
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Update the satellite modem state and notify listeners if it changed.
+     *
+     * @param modemState The {@link SatelliteModemState} to update.
+     */
+    private void updateSatelliteModemState(int modemState) {
+        if (modemState == mModemState) {
+            return;
+        }
+        if (mIsCellularModemEnabledMode
+                && modemState == SatelliteModemState.SATELLITE_MODEM_STATE_OFF) {
+            logd("Not updating the Modem state to Off as it is in CellularModemEnabledMode");
+            return;
+        }
+        mRemoteListeners.values().forEach(listener -> runWithExecutor(() ->
+                listener.onSatelliteModemStateChanged(modemState)));
+        mModemState = modemState;
+    }
+
+    /**
+     * Update the satellite provision state and notify listeners if it changed.
+     *
+     * @param isProvisioned {@code true} if the satellite is currently provisioned and
+     *                      {@code false} if it is not.
+     */
+    private void updateSatelliteProvisionState(boolean isProvisioned) {
+        logd("updateSatelliteProvisionState: isProvisioned=" + isProvisioned
+                + ", mIsProvisioned=" + mIsProvisioned);
+        if (isProvisioned == mIsProvisioned) {
+            return;
+        }
+        mIsProvisioned = isProvisioned;
+        logd("updateSatelliteProvisionState: mRemoteListeners.size=" + mRemoteListeners.size());
+        mRemoteListeners.values().forEach(listener -> runWithExecutor(() ->
+                listener.onSatelliteProvisionStateChanged(mIsProvisioned)));
+    }
+
+    /**
+     * Execute the given runnable using the executor that this service was created with.
+     *
+     * @param r A runnable that can throw an exception.
+     */
+    private void runWithExecutor(@NonNull FunctionalUtils.ThrowingRunnable r) {
+        mExecutor.execute(() -> Binder.withCleanCallingIdentity(r));
+    }
+
+    private void notifyRemoteServiceConnected() {
+        logd("notifyRemoteServiceConnected");
+        runWithExecutor(() -> mLocalListener.onRemoteServiceConnected());
+    }
+
+    /**
+     * Log the message to the radio buffer with {@code DEBUG} priority.
+     *
+     * @param log The message to log.
+     */
+    private static void logd(@NonNull String log) {
+        Rlog.d(TAG, log);
+    }
+
+    /**
+     * Log with error attribute
+     *
+     * @param s is string log
+     */
+    protected void loge(@NonNull String s) {
+        Log.e(TAG, s);
+    }
+}
diff --git a/tests/Android.bp b/tests/Android.bp
index 08cac05..1f15b9b 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -38,6 +38,7 @@
     instrumentation_for: "TeleService",
 
     static_libs: [
+        "frameworks-base-testutils",
         "androidx.test.core",
         "androidx.test.espresso.core",
         "androidx.test.ext.junit",
diff --git a/tests/src/com/android/phone/CarrierConfigLoaderTest.java b/tests/src/com/android/phone/CarrierConfigLoaderTest.java
index b6f8ed8..bd2e4f7 100644
--- a/tests/src/com/android/phone/CarrierConfigLoaderTest.java
+++ b/tests/src/com/android/phone/CarrierConfigLoaderTest.java
@@ -40,8 +40,10 @@
 import android.os.Build;
 import android.os.Handler;
 import android.os.HandlerThread;
+import android.os.PermissionEnforcer;
 import android.os.PersistableBundle;
 import android.os.UserHandle;
+import android.os.test.FakePermissionEnforcer;
 import android.service.carrier.CarrierIdentifier;
 import android.telephony.CarrierConfigManager;
 import android.telephony.SubscriptionManager;
@@ -97,10 +99,17 @@
     private HandlerThread mHandlerThread;
     private TestableLooper mTestableLooper;
 
+    // The AIDL stub will use PermissionEnforcer to check permission from the caller.
+    private FakePermissionEnforcer mFakePermissionEnforcer = new FakePermissionEnforcer();
+
     @Before
     public void setUp() throws Exception {
         super.setUp();
         MockitoAnnotations.initMocks(this);
+        doReturn(Context.PERMISSION_ENFORCER_SERVICE).when(mContext).getSystemServiceName(
+                eq(PermissionEnforcer.class));
+        doReturn(mFakePermissionEnforcer).when(mContext).getSystemService(
+                eq(Context.PERMISSION_ENFORCER_SERVICE));
         replaceInstance(SubscriptionManagerService.class, "sInstance", null,
                 mSubscriptionManagerService);
 
@@ -142,6 +151,9 @@
     @After
     public void tearDown() throws Exception {
         mContext.revokeAllPermissions();
+        mFakePermissionEnforcer.revoke(android.Manifest.permission.DUMP);
+        mFakePermissionEnforcer.revoke(android.Manifest.permission.MODIFY_PHONE_STATE);
+        mFakePermissionEnforcer.revoke(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE);
         mTestableLooper.destroy();
         mHandlerThread.quit();
         super.tearDown();
@@ -164,7 +176,7 @@
      */
     @Test
     public void testUpdateConfigForPhoneId_invalidPhoneId() throws Exception {
-        mContext.grantPermission(STUB_PERMISSION_ENABLE_ALL);
+        mFakePermissionEnforcer.grant(android.Manifest.permission.MODIFY_PHONE_STATE);
 
         assertThrows(IllegalArgumentException.class,
                 () -> mCarrierConfigLoader.updateConfigForPhoneId(
@@ -182,7 +194,7 @@
         if (!SubscriptionManager.isValidPhoneId(SubscriptionManager.getPhoneId(DEFAULT_SUB_ID))) {
             return;
         }
-        mContext.grantPermission(STUB_PERMISSION_ENABLE_ALL);
+        mFakePermissionEnforcer.grant(android.Manifest.permission.MODIFY_PHONE_STATE);
         doNothing().when(mContext).sendBroadcastAsUser(any(Intent.class), any(UserHandle.class));
 
         // Prepare a cached config to fetch from xml
@@ -215,7 +227,7 @@
         if (!SubscriptionManager.isValidPhoneId(SubscriptionManager.getPhoneId(DEFAULT_SUB_ID))) {
             return;
         }
-        mContext.grantPermission(STUB_PERMISSION_ENABLE_ALL);
+        mFakePermissionEnforcer.grant(android.Manifest.permission.MODIFY_PHONE_STATE);
 
         // Prepare to make sure we can save the config into the XML file which used as cache
         doReturn(PLATFORM_CARRIER_CONFIG_PACKAGE).when(mTelephonyManager)
@@ -252,7 +264,7 @@
      */
     @Test
     public void testOverrideConfig_invalidSubId() throws Exception {
-        mContext.grantPermission(STUB_PERMISSION_ENABLE_ALL);
+        mFakePermissionEnforcer.grant(android.Manifest.permission.MODIFY_PHONE_STATE);
 
         assertThrows(IllegalArgumentException.class, () -> mCarrierConfigLoader.overrideConfig(
                 SubscriptionManager.INVALID_SUBSCRIPTION_ID, new PersistableBundle(), false));
@@ -267,7 +279,7 @@
         if (!SubscriptionManager.isValidPhoneId(SubscriptionManager.getPhoneId(DEFAULT_SUB_ID))) {
             return;
         }
-        mContext.grantPermission(STUB_PERMISSION_ENABLE_ALL);
+        mFakePermissionEnforcer.grant(android.Manifest.permission.MODIFY_PHONE_STATE);
 
         mCarrierConfigLoader.overrideConfig(DEFAULT_SUB_ID, null /*overrides*/,
                 false/*persistent*/);
@@ -288,7 +300,7 @@
         if (!SubscriptionManager.isValidPhoneId(SubscriptionManager.getPhoneId(DEFAULT_SUB_ID))) {
             return;
         }
-        mContext.grantPermission(STUB_PERMISSION_ENABLE_ALL);
+        mFakePermissionEnforcer.grant(android.Manifest.permission.MODIFY_PHONE_STATE);
 
         PersistableBundle config = getTestConfig();
         mCarrierConfigLoader.overrideConfig(DEFAULT_SUB_ID, config /*overrides*/,
@@ -308,7 +320,7 @@
      */
     @Test
     public void testNotifyConfigChangedForSubId_invalidSubId() throws Exception {
-        mContext.grantPermission(STUB_PERMISSION_ENABLE_ALL);
+        mFakePermissionEnforcer.grant(STUB_PERMISSION_ENABLE_ALL);
 
         assertThrows(IllegalArgumentException.class,
                 () -> mCarrierConfigLoader.notifyConfigChangedForSubId(
@@ -346,7 +358,7 @@
      */
     @Test
     public void testGetDefaultCarrierServicePackageName_withPermission() {
-        mContext.grantPermission(STUB_PERMISSION_ENABLE_ALL);
+        mFakePermissionEnforcer.grant(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE);
 
         assertThat(mCarrierConfigLoader.getDefaultCarrierServicePackageName())
                 .isEqualTo(PLATFORM_CARRIER_CONFIG_PACKAGE);
@@ -417,7 +429,7 @@
     @Test
     public void testMultiSimConfigChanged() throws Exception {
         replaceInstance(TelephonyManager.class, "sInstance", null, mTelephonyManager);
-        mContext.grantPermission(STUB_PERMISSION_ENABLE_ALL);
+        mFakePermissionEnforcer.grant(android.Manifest.permission.MODIFY_PHONE_STATE);
 
         // Changed from 1 to 2.
         doReturn(2).when(mTelephonyManager).getActiveModemCount();
diff --git a/tests/src/com/android/phone/slice/SlicePurchaseControllerTest.java b/tests/src/com/android/phone/slice/SlicePurchaseControllerTest.java
index b2a4a9f..e9a2e90 100644
--- a/tests/src/com/android/phone/slice/SlicePurchaseControllerTest.java
+++ b/tests/src/com/android/phone/slice/SlicePurchaseControllerTest.java
@@ -578,7 +578,7 @@
         intent.putExtra(SlicePurchaseController.EXTRA_PREMIUM_CAPABILITY,
                 TelephonyManager.PREMIUM_CAPABILITY_PRIORITIZE_LATENCY);
         intent.putExtra(SlicePurchaseController.EXTRA_FAILURE_CODE,
-                SlicePurchaseController.FAILURE_CODE_SERVER_UNREACHABLE);
+                SlicePurchaseController.FAILURE_CODE_CARRIER_URL_UNAVAILABLE);
         mContext.getBroadcastReceiver().onReceive(mContext, intent);
         mTestableLooper.processAllMessages();
         assertEquals(TelephonyManager.PURCHASE_PREMIUM_CAPABILITY_RESULT_CARRIER_ERROR, mResult);
@@ -726,7 +726,7 @@
         mEntitlementResponse.mEntitlementStatus =
                 PremiumNetworkEntitlementResponse.PREMIUM_NETWORK_ENTITLEMENT_STATUS_ENABLED;
         mEntitlementResponse.mProvisionStatus =
-                PremiumNetworkEntitlementResponse.PREMIUM_NETWORK_PROVISION_STATUS_PROVISIONED;
+                PremiumNetworkEntitlementResponse.PREMIUM_NETWORK_PROVISION_STATUS_NOT_PROVISIONED;
 
         // send purchase request
         mSlicePurchaseController.purchasePremiumCapability(