[automerger skipped] Merge 24Q4 (ab/12406339) into aosp-main-future am: bb3d978113 -s ours
am skip reason: Merged-In Ic8c973caac761882481a6b2be319f41497012095 with SHA-1 be3fa44813 is already in history
Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/services/Telephony/+/30285533
Change-Id: Id03ae03d6b6686dd70c6d5845c83e8f255c658fa
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/assets/CarrierRestrictionOperatorDetails.json b/assets/CarrierRestrictionOperatorDetails.json
index a088f94..b3c8976 100644
--- a/assets/CarrierRestrictionOperatorDetails.json
+++ b/assets/CarrierRestrictionOperatorDetails.json
@@ -2,9 +2,13 @@
"_comment": "Operator should register with its application package name, carrierId and all the corresponding SHA256IDs",
"_comment": "Example format :: << \"packageName\" : {\"carrierId\":[<int>], \"callerSHA256Ids\":[<SHAID1>, <SHAID2>]} >>",
"com.vzw.hss.myverizon":{"carrierIds":[1839],"callerSHA256Ids":["AE23A03436DF07B0CD70FE881CDA2EC1D21215D7B7B0CC68E67B67F5DF89526A"]},
+ "com.verizon.mips.services":{"carrierIds":[1839],"callerSHA256Ids":["FF82050BF6BED1F152AC1A12DC83CACBAD401775161882872C6665FC5E15C8F2"]},
"com.google.android.apps.tycho":{"carrierIds":[1989],"callerSHA256Ids":["B9CFCE1C47A6AC713442718F15EF55B00B3A6D1A6D48CB46249FA8EB51465350","4C36AF4A5BDAD97C1F3D8B283416D244496C2AC5EAFE8226079EF6F676FD1859"]},
"com.comcast.mobile.mxs":{"carrierIds": [2032,2532,2556],"callerSHA256Ids":["914C26403B57D2D482359FC235CC825AD00D52B0121C18EF2B2B9D4DDA4B8996"]},
"com.xfinity.digitalhome": {"carrierIds": [2032,2532,2556],"callerSHA256Ids":["31b4c17315c2269040d535f7b6a79cf4d11517c664d9de8f1ddf4f8a785aad47"]},
"com.xfinity.digitalhome.debug":{"carrierIds": [2032,2532,2556],"callerSHA256Ids":["c9133e8168f97573c8c567f46777dff74ade0c015ecf2c5e91be3e4e76ddcae2"]},
- "com.xfinity.dh.xm.app": {"carrierIds": [2032,2532,2556],"callerSHA256Ids":["c9133e8168f97573c8c567f46777dff74ade0c015ecf2c5e91be3e4e76ddcae2"]}
+ "com.xfinity.dh.xm.app": {"carrierIds": [2032,2532,2556],"callerSHA256Ids":["c9133e8168f97573c8c567f46777dff74ade0c015ecf2c5e91be3e4e76ddcae2"]},
+ "com.tmobile.tmte": {"carrierIds": [1],"callerSHA256Ids":["3D:1A:4B:EF:6E:E7:AF:7D:34:D1:20:E7:B1:AA:C0:DD:24:55:85:DE:62:37:CF:10:0F:68:33:3A:FA:CF:F5:62"]},
+ "com.tmobile.tuesdays": {"carrierIds": [1],"callerSHA256Ids":["3D:1A:4B:EF:6E:E7:AF:7D:34:D1:20:E7:B1:AA:C0:DD:24:55:85:DE:62:37:CF:10:0F:68:33:3A:FA:CF:F5:62","92:B5:F8:11:7F:BD:9B:D5:73:8F:F1:68:A4:FA:12:CB:E2:84:BE:83:4E:DE:1A:7B:B4:4D:D8:45:5B:A1:59:20"]},
+ "com.tmobile.pr.mytmobile": {"carrierIds": [1],"callerSHA256Ids":["92:B5:F8:11:7F:BD:9B:D5:73:8F:F1:68:A4:FA:12:CB:E2:84:BE:83:4E:DE:1A:7B:B4:4D:D8:45:5B:A1:59:20"]}
}
\ No newline at end of file
diff --git a/res/values-bs/strings.xml b/res/values-bs/strings.xml
index 226ab18..f553698 100644
--- a/res/values-bs/strings.xml
+++ b/res/values-bs/strings.xml
@@ -284,33 +284,33 @@
<string name="data_enable_summary" msgid="696860063456536557">"Dozvoli korištenje podataka"</string>
<string name="dialog_alert_title" msgid="5260471806940268478">"Pažnja"</string>
<string name="roaming" msgid="1576180772877858949">"Roming"</string>
- <string name="roaming_enable" msgid="6853685214521494819">"Povezivanje na usluge prijenosa podataka u romingu"</string>
- <string name="roaming_disable" msgid="8856224638624592681">"Povezivanje na usluge prijenosa podataka u romingu"</string>
+ <string name="roaming_enable" msgid="6853685214521494819">"Povezivanje na usluge prenosa podataka u romingu"</string>
+ <string name="roaming_disable" msgid="8856224638624592681">"Povezivanje na usluge prenosa podataka u romingu"</string>
<string name="roaming_reenable_message" msgid="1951802463885727915">"Roming podataka je isključen. Dodirnite da ga uključite."</string>
<string name="roaming_enabled_message" msgid="9022249120750897">"Mogu nastati troškovi za roming. Dodirnite da izmijenite."</string>
- <string name="roaming_notification_title" msgid="3590348480688047320">"Veza za prijenos podataka na mobilnoj mreži je izgubljena"</string>
+ <string name="roaming_notification_title" msgid="3590348480688047320">"Veza za prenos podataka na mobilnoj mreži je izgubljena"</string>
<string name="roaming_on_notification_title" msgid="7451473196411559173">"Roming podataka je uključen"</string>
<string name="roaming_warning" msgid="7855681468067171971">"Može dovesti do značajnih troškova."</string>
<string name="roaming_check_price_warning" msgid="8212484083990570215">"Raspitajte se kod svog mobilnog operatera za cijene."</string>
<string name="roaming_alert_title" msgid="5689615818220960940">"Dozvoliti roming podataka?"</string>
<string name="limited_sim_function_notification_title" msgid="612715399099846281">"Ograničena funkcionalnost SIM-a"</string>
- <string name="limited_sim_function_with_phone_num_notification_message" msgid="5928988883403677610">"Pozivi i usluge prijenosa podataka operatera <xliff:g id="CARRIER_NAME">%1$s</xliff:g> mogu biti blokirane kada koristite broj <xliff:g id="PHONE_NUMBER">%2$s</xliff:g>."</string>
- <string name="limited_sim_function_notification_message" msgid="5338638075496721160">"Pozivi i usluge prijenosa pod. op. <xliff:g id="CARRIER_NAME">%1$s</xliff:g> mogu biti blok. kada koristite drugi SIM."</string>
+ <string name="limited_sim_function_with_phone_num_notification_message" msgid="5928988883403677610">"Pozivi i usluge prenosa podataka operatera <xliff:g id="CARRIER_NAME">%1$s</xliff:g> mogu biti blokirane kada koristite broj <xliff:g id="PHONE_NUMBER">%2$s</xliff:g>."</string>
+ <string name="limited_sim_function_notification_message" msgid="5338638075496721160">"Pozivi i usluge prenosa pod. op. <xliff:g id="CARRIER_NAME">%1$s</xliff:g> mogu biti blok. kada koristite drugi SIM."</string>
<string name="sip_accounts_removed_notification_title" msgid="3528076957535736095">"Zastarjeli SIP računi su pronađeni i uklonjeni"</string>
<string name="sip_accounts_removed_notification_message" msgid="1916856744869791592">"Android platforma više ne podržva SIP pozivanje.\nVaši postojeći SIP računi <xliff:g id="REMOVED_SIP_ACCOUNTS">%s</xliff:g> su uklonjeni.\nPotvrdite zadanu postavku računa za pozivanje."</string>
<string name="sip_accounts_removed_notification_action" msgid="3772778402370555562">"Idi u postavke"</string>
<string name="data_usage_title" msgid="8438592133893837464">"Prijenos podataka u aplikaciji"</string>
- <string name="data_usage_template" msgid="6287906680674061783">"Iskorišteno je <xliff:g id="ID_1">%1$s</xliff:g> prijenosa podataka u periodu <xliff:g id="ID_2">%2$s</xliff:g>"</string>
+ <string name="data_usage_template" msgid="6287906680674061783">"Iskorišteno je <xliff:g id="ID_1">%1$s</xliff:g> prenosa podataka u periodu <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="advanced_options_title" msgid="9208195294513520934">"Napredno"</string>
<string name="carrier_settings_euicc" msgid="1190237227261337749">"Operater"</string>
<string name="keywords_carrier_settings_euicc" msgid="8540160967922063745">"mobilni operater, esim, sim, euicc, promijeni mobilnog operatera, dodaj mobilnog operatera"</string>
<string name="carrier_settings_euicc_summary" msgid="2027941166597330117">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g> — <xliff:g id="PHONE_NUMBER">%2$s</xliff:g>"</string>
<string name="mobile_data_settings_title" msgid="7228249980933944101">"Prijenos podataka na mobilnoj mreži"</string>
- <string name="mobile_data_settings_summary" msgid="5012570152029118471">"Pristup prijenosu podataka mobilnom mrežom"</string>
+ <string name="mobile_data_settings_summary" msgid="5012570152029118471">"Pristup prenosu podataka mobilnom mrežom"</string>
<string name="data_usage_disable_mobile" msgid="5669109209055988308">"Isključiti prijenos podataka na mobilnoj mreži?"</string>
<string name="sim_selection_required_pref" msgid="6985901872978341314">"Potreban izbor"</string>
- <string name="sim_change_data_title" msgid="9142726786345906606">"Promijeniti SIM za prijenos podataka?"</string>
- <string name="sim_change_data_message" msgid="3567358694255933280">"Koristiti SIM karticu <xliff:g id="NEW_SIM">%1$s</xliff:g> umjesto SIM kartice <xliff:g id="OLD_SIM">%2$s</xliff:g> za prijenos podataka na mobilnoj mreži?"</string>
+ <string name="sim_change_data_title" msgid="9142726786345906606">"Promijeniti SIM za prenos podataka?"</string>
+ <string name="sim_change_data_message" msgid="3567358694255933280">"Koristiti SIM karticu <xliff:g id="NEW_SIM">%1$s</xliff:g> umjesto SIM kartice <xliff:g id="OLD_SIM">%2$s</xliff:g> za prenos podataka na mobilnoj mreži?"</string>
<string name="wifi_calling_settings_title" msgid="5800018845662016507">"Pozivanje putem WiFi-ja"</string>
<string name="video_calling_settings_title" msgid="342829454913266078">"Video pozivi putem operatera"</string>
<string name="gsm_umts_options" msgid="4968446771519376808">"GSM/UMTS opcije"</string>
@@ -318,13 +318,13 @@
<string name="throttle_data_usage" msgid="1944145350660420711">"Korištenje podataka"</string>
<string name="throttle_current_usage" msgid="7483859109708658613">"Iskorišteni podaci u trenutnom periodu"</string>
<string name="throttle_time_frame" msgid="1813452485948918791">"Period korištenja podataka"</string>
- <string name="throttle_rate" msgid="7641913901133634905">"Pravila o brzini prijenosa podataka"</string>
+ <string name="throttle_rate" msgid="7641913901133634905">"Pravila o brzini prenosa podataka"</string>
<string name="throttle_help" msgid="2624535757028809735">"Saznajte više"</string>
<string name="throttle_status_subtext" msgid="1110276415078236687">"<xliff:g id="USED_0">%1$s</xliff:g> (<xliff:g id="USED_1">%2$d</xliff:g> ٪) od <xliff:g id="USED_2">%3$s</xliff:g> maksimuma perioda\nSljedeći period počinje za <xliff:g id="USED_3">%4$d</xliff:g> dan(a) (<xliff:g id="USED_4">%5$s</xliff:g>)"</string>
<string name="throttle_data_usage_subtext" msgid="3185429653996709840">"<xliff:g id="USED_0">%1$s</xliff:g> (<xliff:g id="USED_1">%2$d</xliff:g> ٪) od <xliff:g id="USED_2">%3$s</xliff:g> maksimuma perioda"</string>
- <string name="throttle_data_rate_reduced_subtext" msgid="8369839346277847725">"<xliff:g id="USED_0">%1$s</xliff:g> ograničenje je prekoračeno \nBrzina prijenosa podataka je smanjena na <xliff:g id="USED_1">%2$d</xliff:g> Kb/s"</string>
+ <string name="throttle_data_rate_reduced_subtext" msgid="8369839346277847725">"<xliff:g id="USED_0">%1$s</xliff:g> ograničenje je prekoračeno \nBrzina prenosa podataka je smanjena na <xliff:g id="USED_1">%2$d</xliff:g> Kb/s"</string>
<string name="throttle_time_frame_subtext" msgid="6462089615392402127">"Proteklo je <xliff:g id="USED_0">%1$d</xliff:g> ٪ ciklusa\nSljedeći period počinje za <xliff:g id="USED_1">%2$d</xliff:g> dan(a) (<xliff:g id="USED_2">%3$s</xliff:g>)"</string>
- <string name="throttle_rate_subtext" msgid="7221971817325779535">"Brzina prijenosa podataka se smanjuje na <xliff:g id="USED">%1$d</xliff:g> Kb/s ako se prekorači ograničenje korištenja podataka"</string>
+ <string name="throttle_rate_subtext" msgid="7221971817325779535">"Brzina prenosa podataka se smanjuje na <xliff:g id="USED">%1$d</xliff:g> Kb/s ako se prekorači ograničenje korištenja podataka"</string>
<string name="throttle_help_subtext" msgid="2817114897095534807">"Više informacija o pravilima korištenja podataka mobilne mreže vašeg operatera"</string>
<string name="cell_broadcast_sms" msgid="4053449797289031063">"SMS info servisa"</string>
<string name="enable_disable_cell_bc_sms" msgid="4759958924031721350">"SMS info servisa"</string>
@@ -553,7 +553,7 @@
<string name="incall_error_supp_service_switch" msgid="5272822448189448479">"Nije moguće prebacivati pozive."</string>
<string name="incall_error_supp_service_resume" msgid="1276861499306817035">"Nije moguće nastaviti poziv."</string>
<string name="incall_error_supp_service_separate" msgid="8932660028965274353">"Nije moguće odvojiti poziv."</string>
- <string name="incall_error_supp_service_transfer" msgid="8211925891867334323">"Prijenos nije moguć."</string>
+ <string name="incall_error_supp_service_transfer" msgid="8211925891867334323">"Prenos nije moguć."</string>
<string name="incall_error_supp_service_conference" msgid="27578082433544702">"Nije moguće spajati pozive."</string>
<string name="incall_error_supp_service_reject" msgid="3044363092441655912">"Nije moguće odbiti poziv."</string>
<string name="incall_error_supp_service_hangup" msgid="836524952243836735">"Nije moguće uputiti poziv(e)."</string>
@@ -621,7 +621,7 @@
<string name="ota_title_activate" msgid="4049645324841263423">"Aktivirajte svoj telefon"</string>
<string name="ota_touch_activate" msgid="838764494319694754">"Za aktiviranje telefonske usluge potrebno je uputiti poseban poziv. \n\nNakon što pritisnete „Aktiviraj“, poslušajte uputstva za aktiviranje telefona."</string>
<string name="ota_hfa_activation_title" msgid="3300556778212729671">"Aktivacija u toku..."</string>
- <string name="ota_hfa_activation_dialog_message" msgid="7921718445773342996">"Telefon aktivira uslugu prijenosa mobilnih podataka.\n\nTo može potrajati do 5 minuta."</string>
+ <string name="ota_hfa_activation_dialog_message" msgid="7921718445773342996">"Telefon aktivira uslugu prenosa mobilnih podataka.\n\nTo može potrajati do 5 minuta."</string>
<string name="ota_skip_activation_dialog_title" msgid="7666611236789203797">"Preskočiti aktivaciju?"</string>
<string name="ota_skip_activation_dialog_message" msgid="6691722887019708713">"Ako preskočite aktivaciju, nećete moći upućivati pozive niti se povezati na mobilne podatkovne mreže (iako se možete povezati s WiFi mrežama). Dok ne aktivirate telefon, prikazivat će se upit za aktivaciju svaki put kada upalite telefon."</string>
<string name="ota_skip_activation_dialog_skip_label" msgid="5908029466817825633">"Preskoči"</string>
@@ -642,7 +642,7 @@
<string name="phone_entered_ecm_text" msgid="8431238297843035842">"Aktiviran način rada za hitni povratni poziv"</string>
<string name="phone_in_ecm_notification_title" msgid="6825016389926367946">"Način rada za hitni povratni poziv"</string>
<string name="phone_in_ecm_call_notification_text" msgid="653972232922670335">"Podatkovna veza je onemogućena"</string>
- <string name="phone_in_ecm_notification_complete_time" msgid="7341624337163082759">"Nema veze za prijenos podataka do <xliff:g id="COMPLETETIME">%s</xliff:g>"</string>
+ <string name="phone_in_ecm_notification_complete_time" msgid="7341624337163082759">"Nema veze za prenos podataka do <xliff:g id="COMPLETETIME">%s</xliff:g>"</string>
<!-- format error in translation for alert_dialog_exit_ecm (7661603870224398025) -->
<!-- format error in translation for alert_dialog_not_avaialble_in_ecm (8717711120099503279) -->
<string name="alert_dialog_in_ecm_call" msgid="1207545603149771978">"Odabrana radnja nije dostupna tokom hitnog poziva."</string>
@@ -707,10 +707,10 @@
<string name="mobile_data_status_roaming_with_plan_subtext" msgid="2576177169108123095">"Trenutno u romingu, plan za podatke je aktivan"</string>
<string name="mobile_data_status_no_plan_subtext" msgid="170331026419263657">"Nema preostalih mobilnih podataka"</string>
<string name="mobile_data_activate_prepaid" msgid="4276738964416795596">"Nema preostalih mobilnih podataka"</string>
- <string name="mobile_data_activate_prepaid_summary" msgid="6846085278531605925">"Dodajte podatke za prijenos na mobilnoj mreži putem operatera <xliff:g id="PROVIDER_NAME">%s</xliff:g>"</string>
+ <string name="mobile_data_activate_prepaid_summary" msgid="6846085278531605925">"Dodajte podatke za prenos na mobilnoj mreži putem operatera <xliff:g id="PROVIDER_NAME">%s</xliff:g>"</string>
<string name="mobile_data_activate_roaming_plan" msgid="922290995866269366">"Nema plana za roming"</string>
<string name="mobile_data_activate_roaming_plan_summary" msgid="5379228493306235969">"Dodajte plan za roming pomoću pružaoca usluga <xliff:g id="PROVIDER_NAME">%s</xliff:g>"</string>
- <string name="mobile_data_activate_footer" msgid="7895874069807204548">"Možete dodati podatke za prijenos na mobilnoj mreži ili plan za roming pomoću operatera, <xliff:g id="PROVIDER_NAME">%s</xliff:g>."</string>
+ <string name="mobile_data_activate_footer" msgid="7895874069807204548">"Možete dodati podatke za prenos na mobilnoj mreži ili plan za roming pomoću operatera, <xliff:g id="PROVIDER_NAME">%s</xliff:g>."</string>
<string name="mobile_data_activate_diag_title" msgid="5401741936224757312">"Dodati podatke?"</string>
<string name="mobile_data_activate_diag_message" msgid="3527260988020415441">"Možda ćete morati dodati podatke preko pružaoca usluga <xliff:g id="PROVIDER_NAME">%s</xliff:g>"</string>
<string name="mobile_data_activate_button" msgid="1139792516354374612">"DODAJTE PODATKE"</string>
@@ -830,8 +830,8 @@
<string name="supp_service_over_ut_precautions_dual_sim" msgid="5166866975550910474">"Za korištenje usluge <xliff:g id="SUPP_SERVICE">%1$s</xliff:g>, provjerite je li za SIM <xliff:g id="SIM_NUMBER">%2$d</xliff:g> uključen prijenos podataka na mobilnoj mreži. Ovo možete promijeniti u postavkama mobilne mreže."</string>
<string name="supp_service_over_ut_precautions_roaming_dual_sim" msgid="6627654855191817965">"Za korištenje usluge <xliff:g id="SUPP_SERVICE">%1$s</xliff:g>, provjerite jesu li za SIM <xliff:g id="SIM_NUMBER">%2$d</xliff:g> uključeni prijenos podataka na mobilnoj mreži i roming podataka. Ovo možete promijeniti u postavkama mobilne mreže."</string>
<string name="supp_service_over_ut_precautions_dialog_dismiss" msgid="5934541487903081652">"Odbaci"</string>
- <string name="radio_info_data_connection_enable" msgid="6183729739783252840">"Omogućite vezu za prijenos podataka"</string>
- <string name="radio_info_data_connection_disable" msgid="6404751291511368706">"Onemogući vezu za prijenos podataka"</string>
+ <string name="radio_info_data_connection_enable" msgid="6183729739783252840">"Omogućite vezu za prenos podataka"</string>
+ <string name="radio_info_data_connection_disable" msgid="6404751291511368706">"Onemogući vezu za prenos podataka"</string>
<string name="volte_provisioned_switch_string" msgid="4812874990480336178">"VoLTE omogućen"</string>
<string name="vt_provisioned_switch_string" msgid="8295542122512195979">"Video pozivi su omogućeni"</string>
<string name="wfc_provisioned_switch_string" msgid="3835004640321078988">"WiFi poziv obezbijeđen"</string>
@@ -882,7 +882,7 @@
<string name="radioInfo_lac" msgid="3892986460272607013">"LAC"</string>
<string name="radioInfo_cid" msgid="1423185536264406705">"CID"</string>
<string name="radio_info_subid" msgid="6839966868621703203">"Trenutni pomoćni ID:"</string>
- <string name="radio_info_dds" msgid="1122593144425697126">"Pomoćni ID za zadani SIM za prijenos podataka:"</string>
+ <string name="radio_info_dds" msgid="1122593144425697126">"Pomoćni ID za zadani SIM za prenos podataka:"</string>
<string name="radio_info_dl_kbps" msgid="2382922659525318726">"DL propusnost (kbps):"</string>
<string name="radio_info_ul_kbps" msgid="2102225400904799036">"UL propusnost (kbps):"</string>
<string name="radio_info_phy_chan_config" msgid="608045501232211303">"Konfiguracije fizičkih kanala:"</string>
@@ -902,7 +902,7 @@
<string name="radio_info_message_waiting_label" msgid="1886549432566952078">"Poruka na čekanju:"</string>
<string name="radio_info_phone_number_label" msgid="2533852539562512203">"Broj telefona:"</string>
<string name="radio_info_voice_network_type_label" msgid="2395347336419593265">"Vrsta glasovne mreže:"</string>
- <string name="radio_info_data_network_type_label" msgid="8886597029237501929">"Vrsta mreže za prijenos podataka:"</string>
+ <string name="radio_info_data_network_type_label" msgid="8886597029237501929">"Vrsta mreže za prenos podataka:"</string>
<string name="radio_info_override_network_type_label" msgid="4176280017221092005">"Zaobilaženje vrste mreže:"</string>
<string name="radio_info_voice_raw_registration_state_label" msgid="2822988327145825128">"Stanje registracije sirovog glasa:"</string>
<string name="radio_info_data_raw_registration_state_label" msgid="2895895513822604539">"Stanje registracije sirovih podataka:"</string>
diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml
index f4c5593..c6e4796 100644
--- a/res/values-ca/strings.xml
+++ b/res/values-ca/strings.xml
@@ -680,7 +680,7 @@
<string name="accessibility_settings_activity_title" msgid="7883415189273700298">"Accessibilitat"</string>
<string name="status_hint_label_incoming_wifi_call" msgid="2606052595898044071">"Trucada per Wi-Fi de"</string>
<string name="status_hint_label_wifi_call" msgid="942993035689809853">"Trucada per Wi-Fi"</string>
- <string name="message_decode_error" msgid="1061856591500290887">"S\'ha produït un error en descodificar el missatge."</string>
+ <string name="message_decode_error" msgid="1061856591500290887">"Hi ha hagut un error en descodificar el missatge."</string>
<string name="callFailed_cdma_activation" msgid="5392057031552253550">"Una targeta SIM ha activat el servei, i s\'ha actualitzat la funció d\'itinerància del telèfon."</string>
<string name="callFailed_cdma_call_limit" msgid="1074219746093031412">"Hi ha massa trucades actives. Finalitza\'n alguna o combina-les abans de fer-ne una de nova."</string>
<string name="callFailed_imei_not_accepted" msgid="7257903653685147251">"No es pot establir la connexió. Insereix una targeta SIM vàlida."</string>
diff --git a/res/values-eu/strings.xml b/res/values-eu/strings.xml
index 452df67..1bd3ed4 100644
--- a/res/values-eu/strings.xml
+++ b/res/values-eu/strings.xml
@@ -297,7 +297,7 @@
<string name="limited_sim_function_with_phone_num_notification_message" msgid="5928988883403677610">"Baliteke <xliff:g id="CARRIER_NAME">%1$s</xliff:g> bidezko deiak eta datu-zerbitzuak blokeatuta egotea <xliff:g id="PHONE_NUMBER">%2$s</xliff:g> telefono-zenbakia erabiltzean."</string>
<string name="limited_sim_function_notification_message" msgid="5338638075496721160">"Baliteke <xliff:g id="CARRIER_NAME">%1$s</xliff:g> bidezko deiak eta datu-zerbitzuak blokeatuta egotea beste SIM txartel bat erabiltzean."</string>
<string name="sip_accounts_removed_notification_title" msgid="3528076957535736095">"SIP-eko kontu zaharkituak aurkitu eta kendu dira"</string>
- <string name="sip_accounts_removed_notification_message" msgid="1916856744869791592">"SIP bidezko deiak jadanik ez dira bateragarriak Android-en plataformarekin.\nZeneuzkan SIP-eko kontuak (<xliff:g id="REMOVED_SIP_ACCOUNTS">%s</xliff:g>) kendu egin dira.\nBerretsi deietarako ezarri duzun kontu lehenetsia."</string>
+ <string name="sip_accounts_removed_notification_message" msgid="1916856744869791592">"SIP bidezko deiak jadanik ez dira onartzen Android-en plataforman.\nZeneuzkan SIP-eko kontuak (<xliff:g id="REMOVED_SIP_ACCOUNTS">%s</xliff:g>) kendu egin dira.\nBerretsi deietarako ezarri duzun kontu lehenetsia."</string>
<string name="sip_accounts_removed_notification_action" msgid="3772778402370555562">"Joan ezarpenetara"</string>
<string name="data_usage_title" msgid="8438592133893837464">"Aplikazioak erabilitako datuak"</string>
<string name="data_usage_template" msgid="6287906680674061783">"Datuen <xliff:g id="ID_1">%1$s</xliff:g> erabili dira data hauen artean: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
diff --git a/res/values-fr-rCA/strings.xml b/res/values-fr-rCA/strings.xml
index b62728f..ff32473 100644
--- a/res/values-fr-rCA/strings.xml
+++ b/res/values-fr-rCA/strings.xml
@@ -582,7 +582,7 @@
<string name="description_concat_format" msgid="2014471565101724088">"%1$s, %2$s"</string>
<string name="dialerKeyboardHintText" msgid="1115266533703764049">"Utilisez le clavier pour composer un numéro."</string>
<string name="onscreenHoldText" msgid="4025348842151665191">"Attente"</string>
- <string name="onscreenEndCallText" msgid="6138725377654842757">"Terminé"</string>
+ <string name="onscreenEndCallText" msgid="6138725377654842757">"Terminer"</string>
<string name="onscreenShowDialpadText" msgid="658465753816164079">"Clavier numérique"</string>
<string name="onscreenMuteText" msgid="5470306116733843621">"Couper le son"</string>
<string name="onscreenAddCallText" msgid="9075675082903611677">"Autre appel"</string>
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index f20960c..22a69bb 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -582,7 +582,7 @@
<string name="description_concat_format" msgid="2014471565101724088">"%1$s, %2$s"</string>
<string name="dialerKeyboardHintText" msgid="1115266533703764049">"Utilisez le clavier pour composer un numéro."</string>
<string name="onscreenHoldText" msgid="4025348842151665191">"En attente"</string>
- <string name="onscreenEndCallText" msgid="6138725377654842757">"Raccrocher"</string>
+ <string name="onscreenEndCallText" msgid="6138725377654842757">"Terminer"</string>
<string name="onscreenShowDialpadText" msgid="658465753816164079">"Clavier"</string>
<string name="onscreenMuteText" msgid="5470306116733843621">"Silencieux"</string>
<string name="onscreenAddCallText" msgid="9075675082903611677">"Autre appel"</string>
diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml
index efb22b1..af0b7f1 100644
--- a/res/values-in/strings.xml
+++ b/res/values-in/strings.xml
@@ -193,7 +193,7 @@
<string name="preferred_network_mode_dialogtitle" msgid="2781447433514459696">"Preferensi jenis jaringan"</string>
<string name="forbidden_network" msgid="5081729819561333023">"(terlarang)"</string>
<string name="choose_network_title" msgid="5335832663422653082">"Pilih jaringan"</string>
- <string name="network_disconnected" msgid="8844141106841160825">"Terputus"</string>
+ <string name="network_disconnected" msgid="8844141106841160825">"Tidak terhubung"</string>
<string name="network_connected" msgid="2760235679963580224">"Terhubung"</string>
<string name="network_connecting" msgid="160901383582774987">"Menghubungkan..."</string>
<string name="network_could_not_connect" msgid="6547460848093727998">"Tidak dapat terhubung"</string>
@@ -869,7 +869,7 @@
<string name="radioInfo_phone_idle" msgid="2191653783170757819">"Tidak ada aktivitas"</string>
<string name="radioInfo_phone_ringing" msgid="8100354169567413370">"Berdering"</string>
<string name="radioInfo_phone_offhook" msgid="7564601639749936170">"Panggilan sedang Berlangsung"</string>
- <string name="radioInfo_data_disconnected" msgid="8085447971880814541">"Terputus"</string>
+ <string name="radioInfo_data_disconnected" msgid="8085447971880814541">"Tidak terhubung"</string>
<string name="radioInfo_data_connecting" msgid="925092271092152472">"Menghubungkan"</string>
<string name="radioInfo_data_connected" msgid="7637335645634239508">"Terhubung"</string>
<string name="radioInfo_data_suspended" msgid="8695262782642002785">"Ditangguhkan"</string>
diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index ddbec3a..8cb4d1d 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -184,7 +184,7 @@
<string name="connect_later" msgid="1950138106010005425">"現在このネットワークに接続できません。しばらくしてからもう一度お試しください。"</string>
<string name="registration_done" msgid="5337407023566953292">"ネットワークに登録されました。"</string>
<string name="already_auto" msgid="8607068290733079336">"すでに自動選択が適用されています。"</string>
- <string name="select_automatically" msgid="779750291257872651">"ネットワークを自動的に選択"</string>
+ <string name="select_automatically" msgid="779750291257872651">"ネットワークを自動的に選択する"</string>
<string name="manual_mode_disallowed_summary" msgid="3970048592179890197">"%1$s に接続中はご利用いただけません"</string>
<string name="network_select_title" msgid="4117305053881611988">"ネットワーク"</string>
<string name="register_automatically" msgid="3907580547590554834">"自動登録..."</string>
diff --git a/res/values-ky/strings.xml b/res/values-ky/strings.xml
index 4e74022..a7054f9 100644
--- a/res/values-ky/strings.xml
+++ b/res/values-ky/strings.xml
@@ -539,7 +539,7 @@
<string name="incall_error_power_off" product="watch" msgid="7191184639454113633">"Мобилдик тармакты күйгүзүңүз, чалуу үчүн \"Учакта\" режимин же \"Батареяны үнөмдөө\" режимин өчүрүңүз."</string>
<string name="incall_error_power_off" product="default" msgid="8131672264311208673">"Чалуу үчүн учак режимин өчүрүңүз."</string>
<string name="incall_error_power_off_wfc" msgid="9125661184694727052">"Чалуу үчүн учак режимин өчүрүңүз же зымсыз тармакка туташыңыз."</string>
- <string name="incall_error_power_off_thermal" product="default" msgid="8695809601655300168"><b>"Телефон ысып кетти"</b>\n\n"Бул чалуу аяктабай жатат. Телефон муздагандан кийин кайра аракет кылыңыз.\n\nШашылыш чалууларды аткара берсеңиз болот."</string>
+ <string name="incall_error_power_off_thermal" product="default" msgid="8695809601655300168"><b>"Телефон ысып кетти"</b>\n\n"Бул чалуу аяктабай жатат. Телефон муздагандан кийин кайталап көрүңүз.\n\nШашылыш чалууларды аткара берсеңиз болот."</string>
<string name="incall_error_ecm_emergency_only" msgid="5622379058883722080">"Кадимки шартта чалуу үчүн шашылыш кайра чалуу режиминен чыгыңыз."</string>
<string name="incall_error_emergency_only" msgid="8786127461027964653">"Тармакта катталган эмес."</string>
<string name="incall_error_out_of_service" msgid="1927265196942672791">"Мобилдик тармак жок."</string>
diff --git a/src/com/android/phone/CarrierConfigLoader.java b/src/com/android/phone/CarrierConfigLoader.java
index c6c26b0..3a908d2 100644
--- a/src/com/android/phone/CarrierConfigLoader.java
+++ b/src/com/android/phone/CarrierConfigLoader.java
@@ -23,6 +23,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.app.ActivityManager;
import android.app.AppOpsManager;
import android.app.compat.CompatChanges;
import android.content.BroadcastReceiver;
@@ -899,8 +900,11 @@
mServiceConnection[phoneId] = serviceConnection;
}
try {
- if (mContext.bindService(carrierService, serviceConnection,
- Context.BIND_AUTO_CREATE)) {
+ if (mFeatureFlags.supportCarrierServicesForHsum()
+ ? mContext.bindServiceAsUser(carrierService, serviceConnection,
+ Context.BIND_AUTO_CREATE, UserHandle.of(ActivityManager.getCurrentUser()))
+ : mContext.bindService(carrierService, serviceConnection,
+ Context.BIND_AUTO_CREATE)) {
if (eventId == EVENT_CONNECTED_TO_DEFAULT_FOR_NO_SIM_CONFIG) {
mServiceBoundForNoSimConfig[phoneId] = true;
} else {
@@ -1261,7 +1265,10 @@
@Nullable
private String getPackageVersion(@NonNull String packageName) {
try {
- PackageInfo info = mContext.getPackageManager().getPackageInfo(packageName, 0);
+ PackageInfo info = mFeatureFlags.supportCarrierServicesForHsum()
+ ? mContext.getPackageManager().getPackageInfoAsUser(packageName, 0,
+ ActivityManager.getCurrentUser())
+ : mContext.getPackageManager().getPackageInfo(packageName, 0);
return Long.toString(info.getLongVersionCode());
} catch (PackageManager.NameNotFoundException e) {
return null;
diff --git a/src/com/android/phone/EmergencyCallbackModeExitDialog.java b/src/com/android/phone/EmergencyCallbackModeExitDialog.java
index 6901789..6918d48 100644
--- a/src/com/android/phone/EmergencyCallbackModeExitDialog.java
+++ b/src/com/android/phone/EmergencyCallbackModeExitDialog.java
@@ -252,7 +252,8 @@
if (DomainSelectionResolver.getInstance()
.isDomainSelectionSupported()) {
EmergencyStateTracker.getInstance()
- .exitEmergencyCallbackMode();
+ .exitEmergencyCallbackMode(
+ TelephonyManager.STOP_REASON_USER_ACTION);
} else {
mPhone.exitEmergencyCallbackMode();
}
diff --git a/src/com/android/phone/NotificationMgr.java b/src/com/android/phone/NotificationMgr.java
index 3c7b321..4fb96a2 100644
--- a/src/com/android/phone/NotificationMgr.java
+++ b/src/com/android/phone/NotificationMgr.java
@@ -878,7 +878,9 @@
+ (isManualSelection ? selectedNetworkOperatorName : ""));
}
- if (isManualSelection) {
+ if (isManualSelection
+ && isSubscriptionVisibleToUser(
+ mSubscriptionManager.getActiveSubscriptionInfo(subId))) {
mSelectedNetworkOperatorName.put(subId, selectedNetworkOperatorName);
shouldShowNotification(serviceState, subId);
} else {
@@ -934,7 +936,9 @@
+ (isManualSelection ? selectedNetworkOperatorName : ""));
}
- if (isManualSelection) {
+ if (isManualSelection
+ && isSubscriptionVisibleToUser(
+ mSubscriptionManager.getActiveSubscriptionInfo(subId))) {
mSelectedNetworkOperatorName.put(subId, selectedNetworkOperatorName);
shouldShowNotification(serviceState, subId);
} else {
@@ -949,6 +953,12 @@
}
}
+ // TODO(b/261916533) This should be handled by SubscriptionManager#isSubscriptionVisible(),
+ // but that method doesn't support system callers, so here we are.
+ private boolean isSubscriptionVisibleToUser(SubscriptionInfo subInfo) {
+ return subInfo != null && (!subInfo.isOpportunistic() || subInfo.getGroupUuid() == null);
+ }
+
private void dismissNetworkSelectionNotification(int subId) {
if (mSelectedUnavailableNotify.get(subId, false)) {
cancelNetworkSelection(subId);
diff --git a/src/com/android/phone/PhoneGlobals.java b/src/com/android/phone/PhoneGlobals.java
index 0433a33..dcddf2b 100644
--- a/src/com/android/phone/PhoneGlobals.java
+++ b/src/com/android/phone/PhoneGlobals.java
@@ -44,6 +44,7 @@
import android.telecom.TelecomManager;
import android.telephony.AnomalyReporter;
import android.telephony.CarrierConfigManager;
+import android.telephony.NetworkRegistrationInfo;
import android.telephony.ServiceState;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
@@ -373,12 +374,16 @@
break;
case EVENT_DATA_ROAMING_DISCONNECTED:
+ Log.d(LOG_TAG, "EVENT_DATA_ROAMING_DISCONNECTED");
if (SubscriptionManagerService.getInstance()
.isEsimBootStrapProvisioningActiveForSubId(msg.arg1)) {
Log.i(LOG_TAG,
"skip notification/warnings during esim bootstrap activation");
+ } else if (skipDataRoamingDisconnectedNotificationInSatelliteMode((msg.arg1))) {
+ Log.i(LOG_TAG, "skip data roaming disconnected notification when device is "
+ + "connected to satellite network that does not support data.");
} else {
- notificationMgr.showDataRoamingNotification(msg.arg1, false);
+ notificationMgr.showDataRoamingNotification((msg.arg1), false);
}
break;
@@ -566,7 +571,8 @@
// Initialize EmergencyStateTracker if domain selection is supported
boolean isSuplDdsSwitchRequiredForEmergencyCall = getResources()
.getBoolean(R.bool.config_gnss_supl_requires_default_data_for_emergency);
- EmergencyStateTracker.make(this, isSuplDdsSwitchRequiredForEmergencyCall);
+ EmergencyStateTracker.make(this, isSuplDdsSwitchRequiredForEmergencyCall,
+ mFeatureFlags);
DynamicRoutingController.getInstance().initialize(this);
}
@@ -1495,4 +1501,32 @@
}
pw.println("------- End PhoneGlobals -------");
}
+
+ private boolean skipDataRoamingDisconnectedNotificationInSatelliteMode(int subId) {
+ SatelliteController satelliteController = SatelliteController.getInstance();
+ if (satelliteController.isSatelliteEnabledOrBeingEnabled()) {
+ Log.d(LOG_TAG, "skipDataRoamingDisconnected - skip notification as "
+ + "satellite is enabled or being enabled");
+ return true;
+ }
+
+ int phoneId = SubscriptionManager.getPhoneId(subId);
+ Phone phone = PhoneFactory.getPhone(phoneId);
+ ServiceState serviceState = phone.getServiceState();
+ if (serviceState != null && serviceState.isUsingNonTerrestrialNetwork()) {
+ Log.d(LOG_TAG, "skipDataRoamingDisconnected - isUsingNtn");
+ List<Integer> capabilities =
+ satelliteController.getCapabilitiesForCarrierRoamingSatelliteMode(phone);
+ if (!capabilities.contains(NetworkRegistrationInfo.SERVICE_TYPE_DATA)) {
+ // Skip data roaming disconnected notification as device is connected to
+ // non-terrestrial network that does not support data.
+ Log.d(LOG_TAG, "skipDataRoamingDisconnected - skip notification as "
+ + "NTN does not support data");
+ return true;
+ }
+ }
+
+ Log.d(LOG_TAG, "skipDataRoamingDisconnected - do not skip notification.");
+ return false;
+ }
}
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index a997f01..440c39d 100644
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -158,6 +158,7 @@
import android.telephony.satellite.ISatelliteCapabilitiesCallback;
import android.telephony.satellite.ISatelliteCommunicationAllowedStateCallback;
import android.telephony.satellite.ISatelliteDatagramCallback;
+import android.telephony.satellite.ISatelliteDisallowedReasonsCallback;
import android.telephony.satellite.ISatelliteModemStateCallback;
import android.telephony.satellite.ISatelliteProvisionStateCallback;
import android.telephony.satellite.ISatelliteSupportedStateCallback;
@@ -442,6 +443,9 @@
private PackageManager mPackageManager;
private final int mVendorApiLevel;
+ @Nullable
+ private ComponentName mTestEuiccUiComponent;
+
/** User Activity */
private final AtomicBoolean mNotifyUserActivity;
private static final int USER_ACTIVITY_NOTIFICATION_DELAY = 200;
@@ -475,7 +479,7 @@
public static final String RESET_NETWORK_ERASE_MODEM_CONFIG_ENABLED =
"reset_network_erase_modem_config_enabled";
- private static final int SET_NETWORK_SELECTION_MODE_AUTOMATIC_TIMEOUT_MS = 2000; // 2 seconds
+ private static final int BLOCKING_REQUEST_DEFAULT_TIMEOUT_MS = 2000; // 2 seconds
private static final int MODEM_ACTIVITY_TIME_OFFSET_CORRECTION_MS = 50;
@@ -3676,9 +3680,6 @@
return null;
}
- enforceTelephonyFeatureWithException(callingPackage,
- PackageManager.FEATURE_TELEPHONY_GSM, "getImeiForSlot");
-
final long identity = Binder.clearCallingIdentity();
try {
return phone.getImei();
@@ -3695,9 +3696,6 @@
throw new SecurityException("Caller does not have permission");
}
- enforceTelephonyFeatureWithException(callingPackage,
- PackageManager.FEATURE_TELEPHONY_GSM, "getPrimaryImei");
-
final long identity = Binder.clearCallingIdentity();
try {
for (Phone phone : PhoneFactory.getPhones()) {
@@ -3713,9 +3711,6 @@
@Override
public String getTypeAllocationCodeForSlot(int slotIndex) {
- enforceTelephonyFeatureWithException(getCurrentPackageName(),
- PackageManager.FEATURE_TELEPHONY_GSM, "getTypeAllocationCodeForSlot");
-
Phone phone = PhoneFactory.getPhone(slotIndex);
String tac = null;
if (phone != null) {
@@ -4233,8 +4228,12 @@
final long identity = Binder.clearCallingIdentity();
try {
- Boolean success = (Boolean) sendRequest(CMD_SET_VOICEMAIL_NUMBER,
- new Pair<String, String>(alphaTag, number), new Integer(subId));
+ Boolean success = (Boolean) sendRequest(
+ CMD_SET_VOICEMAIL_NUMBER,
+ new Pair<String, String>(alphaTag, number),
+ new Integer(subId),
+ BLOCKING_REQUEST_DEFAULT_TIMEOUT_MS);
+ if (success == null) return false; // most likely due to a timeout
return success;
} finally {
Binder.restoreCallingIdentity(identity);
@@ -6642,6 +6641,8 @@
* Sets the ImsService Package Name that Telephony will bind to.
*
* @param slotIndex the slot ID that the ImsService should bind for.
+ * @param userId the user ID that the ImsService should bind for or {@link UserHandle#USER_NULL}
+ * if there is no preference.
* @param isCarrierService true if the ImsService is the carrier override, false if the
* ImsService is the device default ImsService.
* @param featureTypes An integer array of feature types associated with a packageName.
@@ -6649,7 +6650,7 @@
* with.
* @return true if setting the ImsService to bind to succeeded, false if it did not.
*/
- public boolean setBoundImsServiceOverride(int slotIndex, boolean isCarrierService,
+ public boolean setBoundImsServiceOverride(int slotIndex, int userId, boolean isCarrierService,
int[] featureTypes, String packageName) {
TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "setBoundImsServiceOverride");
TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
@@ -6661,12 +6662,8 @@
// may happen if the device does not support IMS.
return false;
}
- Map<Integer, String> featureConfig = new HashMap<>();
- for (int featureType : featureTypes) {
- featureConfig.put(featureType, packageName);
- }
- return mImsResolver.overrideImsServiceConfiguration(slotIndex, isCarrierService,
- featureConfig);
+ return mImsResolver.overrideImsServiceConfiguration(packageName, slotIndex, userId,
+ isCarrierService, featureTypes);
} finally {
Binder.restoreCallingIdentity(identity);
}
@@ -6804,7 +6801,7 @@
}
if (DBG) log("setNetworkSelectionModeAutomatic: subId " + subId);
sendRequest(CMD_SET_NETWORK_SELECTION_MODE_AUTOMATIC, null, subId,
- SET_NETWORK_SELECTION_MODE_AUTOMATIC_TIMEOUT_MS);
+ BLOCKING_REQUEST_DEFAULT_TIMEOUT_MS);
} finally {
Binder.restoreCallingIdentity(identity);
}
@@ -11702,10 +11699,10 @@
@Override
public boolean setBoundGbaServiceOverride(int subId, String packageName) {
enforceModifyPermission();
-
+ int userId = ActivityManager.getCurrentUser();
final long identity = Binder.clearCallingIdentity();
try {
- return getGbaManager(subId).overrideServicePackage(packageName);
+ return getGbaManager(subId).overrideServicePackage(packageName, userId);
} finally {
Binder.restoreCallingIdentity(identity);
}
@@ -13202,40 +13199,58 @@
public void requestSatelliteEnabled(boolean enableSatellite, boolean enableDemoMode,
boolean isEmergency, @NonNull IIntegerConsumer callback) {
enforceSatelliteCommunicationPermission("requestSatelliteEnabled");
- if (enableSatellite) {
- ResultReceiver resultReceiver = new ResultReceiver(mMainThreadHandler) {
- @Override
- protected void onReceiveResult(int resultCode, Bundle resultData) {
- Log.d(LOG_TAG, "Satellite access restriction resultCode=" + resultCode
- + ", resultData=" + resultData);
- boolean isAllowed = false;
- Consumer<Integer> result = FunctionalUtils.ignoreRemoteException(
- callback::accept);
- if (resultCode == SATELLITE_RESULT_SUCCESS) {
- if (resultData != null
- && resultData.containsKey(KEY_SATELLITE_COMMUNICATION_ALLOWED)) {
- isAllowed = resultData.getBoolean(KEY_SATELLITE_COMMUNICATION_ALLOWED);
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ if (enableSatellite) {
+ String caller = "PIM:requestSatelliteEnabled";
+ ResultReceiver resultReceiver = new ResultReceiver(mMainThreadHandler) {
+ @Override
+ protected void onReceiveResult(int resultCode, Bundle resultData) {
+ Log.d(LOG_TAG, "Satellite access restriction resultCode=" + resultCode
+ + ", resultData=" + resultData);
+ mSatelliteController.decrementResultReceiverCount(caller);
+
+ boolean isAllowed = false;
+ Consumer<Integer> result = FunctionalUtils.ignoreRemoteException(
+ callback::accept);
+ if (resultCode == SATELLITE_RESULT_SUCCESS) {
+ if (resultData != null
+ && resultData.containsKey(
+ KEY_SATELLITE_COMMUNICATION_ALLOWED)) {
+ isAllowed = resultData.getBoolean(
+ KEY_SATELLITE_COMMUNICATION_ALLOWED);
+ } else {
+ loge("KEY_SATELLITE_COMMUNICATION_ALLOWED does not exist.");
+ }
} else {
- loge("KEY_SATELLITE_COMMUNICATION_ALLOWED does not exist.");
+ result.accept(resultCode);
+ return;
}
- } else {
- result.accept(resultCode);
- return;
+ if (isAllowed) {
+ if (mFeatureFlags.carrierRoamingNbIotNtn()
+ && !mSatelliteAccessController.getSatelliteDisallowedReasons()
+ .isEmpty()) {
+ result.accept(SATELLITE_RESULT_ACCESS_BARRED);
+ } else {
+ mSatelliteController.requestSatelliteEnabled(
+ enableSatellite, enableDemoMode, isEmergency, callback);
+ }
+ } else {
+ result.accept(SATELLITE_RESULT_ACCESS_BARRED);
+ }
}
- if (isAllowed) {
- mSatelliteController.requestSatelliteEnabled(
- enableSatellite, enableDemoMode, isEmergency, callback);
- } else {
- result.accept(SATELLITE_RESULT_ACCESS_BARRED);
- }
- }
- };
- mSatelliteAccessController.requestIsCommunicationAllowedForCurrentLocation(
- resultReceiver, true);
- } else {
- // No need to check if satellite is allowed at current location when disabling satellite
- mSatelliteController.requestSatelliteEnabled(
- enableSatellite, enableDemoMode, isEmergency, callback);
+ };
+ mSatelliteAccessController.requestIsCommunicationAllowedForCurrentLocation(
+ resultReceiver, true);
+ mSatelliteController.incrementResultReceiverCount(caller);
+ } else {
+ // No need to check if satellite is allowed at current location when disabling
+ // satellite
+ mSatelliteController.requestSatelliteEnabled(
+ enableSatellite, enableDemoMode, isEmergency, callback);
+ }
+ } finally {
+ Binder.restoreCallingIdentity(identity);
}
}
@@ -13250,7 +13265,12 @@
@Override
public void requestIsSatelliteEnabled(@NonNull ResultReceiver result) {
enforceSatelliteCommunicationPermission("requestIsSatelliteEnabled");
- mSatelliteController.requestIsSatelliteEnabled(result);
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ mSatelliteController.requestIsSatelliteEnabled(result);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
}
/**
@@ -13264,7 +13284,12 @@
@Override
public void requestIsDemoModeEnabled(@NonNull ResultReceiver result) {
enforceSatelliteCommunicationPermission("requestIsDemoModeEnabled");
- mSatelliteController.requestIsDemoModeEnabled(result);
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ mSatelliteController.requestIsDemoModeEnabled(result);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
}
/**
@@ -13278,7 +13303,12 @@
@Override
public void requestIsEmergencyModeEnabled(@NonNull ResultReceiver result) {
enforceSatelliteCommunicationPermission("requestIsEmergencyModeEnabled");
- mSatelliteController.requestIsEmergencyModeEnabled(result);
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ mSatelliteController.requestIsEmergencyModeEnabled(result);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
}
/**
@@ -13286,10 +13316,18 @@
*
* @param result The result receiver that returns whether the satellite service is supported on
* the device if the request is successful or an error code if the request failed.
+ *
+ * @throws SecurityException if the caller doesn't have the required permission.
*/
@Override
public void requestIsSatelliteSupported(@NonNull ResultReceiver result) {
- mSatelliteController.requestIsSatelliteSupported(result);
+ enforceSatelliteCommunicationPermission("requestIsSatelliteSupported");
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ mSatelliteController.requestIsSatelliteSupported(result);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
}
/**
@@ -13303,7 +13341,12 @@
@Override
public void requestSatelliteCapabilities(@NonNull ResultReceiver result) {
enforceSatelliteCommunicationPermission("requestSatelliteCapabilities");
- mSatelliteController.requestSatelliteCapabilities(result);
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ mSatelliteController.requestSatelliteCapabilities(result);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
}
/**
@@ -13321,7 +13364,12 @@
@NonNull IIntegerConsumer resultCallback,
@NonNull ISatelliteTransmissionUpdateCallback callback) {
enforceSatelliteCommunicationPermission("startSatelliteTransmissionUpdates");
- mSatelliteController.startSatelliteTransmissionUpdates(resultCallback, callback);
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ mSatelliteController.startSatelliteTransmissionUpdates(resultCallback, callback);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
}
/**
@@ -13339,7 +13387,12 @@
@NonNull IIntegerConsumer resultCallback,
@NonNull ISatelliteTransmissionUpdateCallback callback) {
enforceSatelliteCommunicationPermission("stopSatelliteTransmissionUpdates");
- mSatelliteController.stopSatelliteTransmissionUpdates(resultCallback, callback);
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ mSatelliteController.stopSatelliteTransmissionUpdates(resultCallback, callback);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
}
/**
@@ -13361,8 +13414,13 @@
@NonNull String token, @NonNull byte[] provisionData,
@NonNull IIntegerConsumer callback) {
enforceSatelliteCommunicationPermission("provisionSatelliteService");
- return mSatelliteController.provisionSatelliteService(token, provisionData,
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ return mSatelliteController.provisionSatelliteService(token, provisionData,
callback);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
}
/**
@@ -13380,7 +13438,12 @@
public void deprovisionSatelliteService(
@NonNull String token, @NonNull IIntegerConsumer callback) {
enforceSatelliteCommunicationPermission("deprovisionSatelliteService");
- mSatelliteController.deprovisionSatelliteService(token, callback);
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ mSatelliteController.deprovisionSatelliteService(token, callback);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
}
/**
@@ -13396,7 +13459,12 @@
@SatelliteManager.SatelliteResult public int registerForSatelliteProvisionStateChanged(
@NonNull ISatelliteProvisionStateCallback callback) {
enforceSatelliteCommunicationPermission("registerForSatelliteProvisionStateChanged");
- return mSatelliteController.registerForSatelliteProvisionStateChanged(callback);
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ return mSatelliteController.registerForSatelliteProvisionStateChanged(callback);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
}
/**
@@ -13412,7 +13480,12 @@
public void unregisterForSatelliteProvisionStateChanged(
@NonNull ISatelliteProvisionStateCallback callback) {
enforceSatelliteCommunicationPermission("unregisterForSatelliteProvisionStateChanged");
- mSatelliteController.unregisterForSatelliteProvisionStateChanged(callback);
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ mSatelliteController.unregisterForSatelliteProvisionStateChanged(callback);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
}
/**
@@ -13427,7 +13500,12 @@
@Override
public void requestIsSatelliteProvisioned(@NonNull ResultReceiver result) {
enforceSatelliteCommunicationPermission("requestIsSatelliteProvisioned");
- mSatelliteController.requestIsSatelliteProvisioned(result);
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ mSatelliteController.requestIsSatelliteProvisioned(result);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
}
/**
@@ -13443,7 +13521,12 @@
@SatelliteManager.SatelliteResult public int registerForSatelliteModemStateChanged(
@NonNull ISatelliteModemStateCallback callback) {
enforceSatelliteCommunicationPermission("registerForSatelliteModemStateChanged");
- return mSatelliteController.registerForSatelliteModemStateChanged(callback);
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ return mSatelliteController.registerForSatelliteModemStateChanged(callback);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
}
/**
@@ -13458,7 +13541,12 @@
@Override
public void unregisterForModemStateChanged(@NonNull ISatelliteModemStateCallback callback) {
enforceSatelliteCommunicationPermission("unregisterForModemStateChanged");
- mSatelliteController.unregisterForModemStateChanged(callback);
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ mSatelliteController.unregisterForModemStateChanged(callback);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
}
/**
@@ -13474,7 +13562,12 @@
@SatelliteManager.SatelliteResult public int registerForIncomingDatagram(
@NonNull ISatelliteDatagramCallback callback) {
enforceSatelliteCommunicationPermission("registerForIncomingDatagram");
- return mSatelliteController.registerForIncomingDatagram(callback);
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ return mSatelliteController.registerForIncomingDatagram(callback);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
}
/**
@@ -13489,7 +13582,12 @@
@Override
public void unregisterForIncomingDatagram(@NonNull ISatelliteDatagramCallback callback) {
enforceSatelliteCommunicationPermission("unregisterForIncomingDatagram");
- mSatelliteController.unregisterForIncomingDatagram(callback);
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ mSatelliteController.unregisterForIncomingDatagram(callback);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
}
/**
@@ -13505,7 +13603,12 @@
*/
public void pollPendingDatagrams(IIntegerConsumer callback) {
enforceSatelliteCommunicationPermission("pollPendingDatagrams");
- mSatelliteController.pollPendingDatagrams(callback);
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ mSatelliteController.pollPendingDatagrams(callback);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
}
/**
@@ -13530,8 +13633,71 @@
@NonNull SatelliteDatagram datagram, boolean needFullScreenPointingUI,
@NonNull IIntegerConsumer callback) {
enforceSatelliteCommunicationPermission("sendDatagram");
- mSatelliteController.sendDatagram(datagramType, datagram, needFullScreenPointingUI,
- callback);
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ mSatelliteController.sendDatagram(datagramType, datagram, needFullScreenPointingUI,
+ callback);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
+ /**
+ * Returns integer array of disallowed reasons of satellite.
+ *
+ * @return Integer array of disallowed reasons of satellite.
+ *
+ * @throws SecurityException if the caller doesn't have the required permission.
+ */
+ @NonNull public int[] getSatelliteDisallowedReasons() {
+ enforceSatelliteCommunicationPermission("getSatelliteDisallowedReasons");
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ return mSatelliteAccessController.getSatelliteDisallowedReasons()
+ .stream().mapToInt(Integer::intValue).toArray();
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
+ /**
+ * Registers for disallowed reasons change event from satellite service.
+ *
+ * @param callback The callback to handle disallowed reasons changed event.
+ *
+ * @throws SecurityException if the caller doesn't have the required permission.
+ */
+ @Override
+ public void registerForSatelliteDisallowedReasonsChanged(
+ @NonNull ISatelliteDisallowedReasonsCallback callback) {
+ enforceSatelliteCommunicationPermission("registerForSatelliteDisallowedReasonsChanged");
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ mSatelliteAccessController.registerForSatelliteDisallowedReasonsChanged(callback);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
+ /**
+ * Unregisters for disallowed reasons change event from satellite service.
+ * If callback was not registered before, the request will be ignored.
+ *
+ * @param callback The callback to handle disallowed reasons changed event.
+ * {@link #registerForSatelliteDisallowedReasonsChanged(
+ * ISatelliteDisallowedReasonsCallback)}.
+ * @throws SecurityException if the caller doesn't have the required permission.
+ */
+ @Override
+ public void unregisterForSatelliteDisallowedReasonsChanged(
+ @NonNull ISatelliteDisallowedReasonsCallback callback) {
+ enforceSatelliteCommunicationPermission("unregisterForSatelliteDisallowedReasonsChanged");
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ mSatelliteAccessController.unregisterForSatelliteDisallowedReasonsChanged(callback);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
}
/**
@@ -13549,7 +13715,36 @@
public void requestIsCommunicationAllowedForCurrentLocation(int subId,
@NonNull ResultReceiver result) {
enforceSatelliteCommunicationPermission("requestIsCommunicationAllowedForCurrentLocation");
- mSatelliteAccessController.requestIsCommunicationAllowedForCurrentLocation(result, false);
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ mSatelliteAccessController.requestIsCommunicationAllowedForCurrentLocation(result,
+ false);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
+ /**
+ * Request to get satellite access configuration for the current location.
+ *
+ * @param result The result receiver that returns the satellite access configuration
+ * for the current location if the request is successful or an error code
+ * if the request failed.
+ *
+ * @throws SecurityException if the caller doesn't have the required permission.
+ */
+ @Override
+ public void requestSatelliteAccessConfigurationForCurrentLocation(
+ @NonNull ResultReceiver result) {
+ enforceSatelliteCommunicationPermission(
+ "requestSatelliteAccessConfigurationForCurrentLocation");
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ mSatelliteAccessController
+ .requestSatelliteAccessConfigurationForCurrentLocation(result);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
}
/**
@@ -13563,22 +13758,32 @@
@Override
public void requestTimeForNextSatelliteVisibility(@NonNull ResultReceiver result) {
enforceSatelliteCommunicationPermission("requestTimeForNextSatelliteVisibility");
- mSatelliteController.requestTimeForNextSatelliteVisibility(result);
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ mSatelliteController.requestTimeForNextSatelliteVisibility(result);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
}
/**
- * Inform that Device is aligned to satellite for demo mode.
+ * Inform whether the device is aligned with the satellite in both real and demo mode.
*
- * @param isAligned {@code true} Device is aligned with the satellite for demo mode
- * {@code false} Device fails to align with the satellite for demo mode.
+ * @param isAligned {@code true} Device is aligned with the satellite.
+ * {@code false} Device fails to align with the satellite.
*
* @throws SecurityException if the caller doesn't have required permission.
*/
@RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
public void setDeviceAlignedWithSatellite(@NonNull boolean isAligned) {
- enforceSatelliteCommunicationPermission("informDeviceAlignedToSatellite");
- mSatelliteController.setDeviceAlignedWithSatellite(isAligned);
+ enforceSatelliteCommunicationPermission("setDeviceAlignedWithSatellite");
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ mSatelliteController.setDeviceAlignedWithSatellite(isAligned);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
}
/**
@@ -13772,7 +13977,12 @@
@SatelliteManager.SatelliteResult public int registerForSatelliteSupportedStateChanged(
@NonNull ISatelliteSupportedStateCallback callback) {
enforceSatelliteCommunicationPermission("registerForSatelliteSupportedStateChanged");
- return mSatelliteController.registerForSatelliteSupportedStateChanged(callback);
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ return mSatelliteController.registerForSatelliteSupportedStateChanged(callback);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
}
/**
@@ -13788,7 +13998,12 @@
public void unregisterForSatelliteSupportedStateChanged(
@NonNull ISatelliteSupportedStateCallback callback) {
enforceSatelliteCommunicationPermission("unregisterForSatelliteSupportedStateChanged");
- mSatelliteController.unregisterForSatelliteSupportedStateChanged(callback);
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ mSatelliteController.unregisterForSatelliteSupportedStateChanged(callback);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
}
/**
@@ -13809,8 +14024,13 @@
TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
SubscriptionManager.INVALID_SUBSCRIPTION_ID,
"setSatelliteServicePackageName");
- return mSatelliteController.setSatelliteServicePackageName(servicePackageName,
- provisioned);
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ return mSatelliteController.setSatelliteServicePackageName(servicePackageName,
+ provisioned);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
}
/**
@@ -13827,7 +14047,12 @@
TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
SubscriptionManager.INVALID_SUBSCRIPTION_ID,
"setSatelliteGatewayServicePackageName");
- return mSatelliteController.setSatelliteGatewayServicePackageName(servicePackageName);
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ return mSatelliteController.setSatelliteGatewayServicePackageName(servicePackageName);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
}
/**
@@ -13846,8 +14071,13 @@
Binder.getCallingUid(), "setSatellitePointingUiClassName");
TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
SubscriptionManager.INVALID_SUBSCRIPTION_ID,
- "setSatelliteGatewayServicePackageName");
- return mSatelliteController.setSatellitePointingUiClassName(packageName, className);
+ "setSatellitePointingUiClassName");
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ return mSatelliteController.setSatellitePointingUiClassName(packageName, className);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
}
/**
@@ -13865,7 +14095,33 @@
TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
SubscriptionManager.INVALID_SUBSCRIPTION_ID,
"setSatelliteListeningTimeoutDuration");
- return mSatelliteController.setSatelliteListeningTimeoutDuration(timeoutMillis);
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ return mSatelliteController.setSatelliteListeningTimeoutDuration(timeoutMillis);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
+ /**
+ * This API can be used by only CTS to control ingoring cellular service state event.
+ *
+ * @param enabled Whether to enable boolean config.
+ * @return {@code true} if the value is set successfully, {@code false} otherwise.
+ */
+ public boolean setSatelliteIgnoreCellularServiceState(boolean enabled) {
+ Log.d(LOG_TAG, "setSatelliteIgnoreCellularServiceState - " + enabled);
+ TelephonyPermissions.enforceShellOnly(
+ Binder.getCallingUid(), "setSatelliteIgnoreCellularServiceState");
+ TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
+ SubscriptionManager.INVALID_SUBSCRIPTION_ID,
+ "setSatelliteIgnoreCellularServiceState");
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ return mSatelliteController.setSatelliteIgnoreCellularServiceState(enabled);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
}
/**
@@ -13884,8 +14140,13 @@
TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
SubscriptionManager.INVALID_SUBSCRIPTION_ID,
"setDatagramControllerTimeoutDuration");
- return mSatelliteController.setDatagramControllerTimeoutDuration(
- reset, timeoutType, timeoutMillis);
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ return mSatelliteController.setDatagramControllerTimeoutDuration(
+ reset, timeoutType, timeoutMillis);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
}
/**
@@ -13904,7 +14165,13 @@
TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
SubscriptionManager.INVALID_SUBSCRIPTION_ID,
"ssetDatagramControllerBooleanConfig");
- return mSatelliteController.setDatagramControllerBooleanConfig(reset, booleanType, enable);
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ return mSatelliteController.setDatagramControllerBooleanConfig(reset, booleanType,
+ enable);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
}
@@ -13924,8 +14191,13 @@
TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
SubscriptionManager.INVALID_SUBSCRIPTION_ID,
"setSatelliteControllerTimeoutDuration");
- return mSatelliteController.setSatelliteControllerTimeoutDuration(
- reset, timeoutType, timeoutMillis);
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ return mSatelliteController.setSatelliteControllerTimeoutDuration(
+ reset, timeoutType, timeoutMillis);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
}
/**
@@ -13948,8 +14220,13 @@
TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
SubscriptionManager.INVALID_SUBSCRIPTION_ID,
"setEmergencyCallToSatelliteHandoverType");
- return mSatelliteController.setEmergencyCallToSatelliteHandoverType(
- handoverType, delaySeconds);
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ return mSatelliteController.setEmergencyCallToSatelliteHandoverType(
+ handoverType, delaySeconds);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
}
/**
@@ -13968,7 +14245,12 @@
TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
SubscriptionManager.INVALID_SUBSCRIPTION_ID,
"setOemEnabledSatelliteProvisionStatus");
- return mSatelliteController.setOemEnabledSatelliteProvisionStatus(reset, isProvisioned);
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ return mSatelliteController.setOemEnabledSatelliteProvisionStatus(reset, isProvisioned);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
}
/**
@@ -13985,14 +14267,18 @@
+ ", locationCountryCodeTimestampNanos" + locationCountryCodeTimestampNanos
+ ", reset=" + reset + ", cachedNetworkCountryCodes="
+ String.join(", ", cachedNetworkCountryCodes.keySet()));
- TelephonyPermissions.enforceShellOnly(
- Binder.getCallingUid(), "setCachedLocationCountryCode");
+ TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "setCountryCodes");
TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
- SubscriptionManager.INVALID_SUBSCRIPTION_ID,
- "setCachedLocationCountryCode");
- return TelephonyCountryDetector.getInstance(getDefaultPhone().getContext(), mFeatureFlags)
- .setCountryCodes(reset, currentNetworkCountryCodes, cachedNetworkCountryCodes,
- locationCountryCode, locationCountryCodeTimestampNanos);
+ SubscriptionManager.INVALID_SUBSCRIPTION_ID, "setCountryCodes");
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ return TelephonyCountryDetector.getInstance(getDefaultPhone().getContext(),
+ mFeatureFlags).setCountryCodes(reset, currentNetworkCountryCodes,
+ cachedNetworkCountryCodes, locationCountryCode,
+ locationCountryCodeTimestampNanos);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
}
/**
@@ -14016,8 +14302,13 @@
TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
SubscriptionManager.INVALID_SUBSCRIPTION_ID,
"setSatelliteAccessControlOverlayConfigs");
- return mSatelliteAccessController.setSatelliteAccessControlOverlayConfigs(reset, isAllowed,
- s2CellFile, locationFreshDurationNanos, satelliteCountryCodes);
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ return mSatelliteAccessController.setSatelliteAccessControlOverlayConfigs(reset,
+ isAllowed, s2CellFile, locationFreshDurationNanos, satelliteCountryCodes);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
}
/**
@@ -14042,8 +14333,13 @@
TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
SubscriptionManager.INVALID_SUBSCRIPTION_ID,
"setShouldSendDatagramToModemInDemoMode");
- return mSatelliteController.setShouldSendDatagramToModemInDemoMode(
- shouldSendToModemInDemoMode);
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ return mSatelliteController.setShouldSendDatagramToModemInDemoMode(
+ shouldSendToModemInDemoMode);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
}
/**
@@ -14068,8 +14364,13 @@
TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
SubscriptionManager.INVALID_SUBSCRIPTION_ID,
"setIsSatelliteCommunicationAllowedForCurrentLocationCache");
- return mSatelliteAccessController.setIsSatelliteCommunicationAllowedForCurrentLocationCache(
- state);
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ return mSatelliteAccessController
+ .setIsSatelliteCommunicationAllowedForCurrentLocationCache(state);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
}
/**
@@ -14430,6 +14731,44 @@
}
/**
+ * Deliver the list of deprovisioned satellite subscriber ids.
+ *
+ * @param list List of deprovisioned satellite subscriber ids.
+ * @param result The result receiver that returns whether deliver success or fail.
+ *
+ * @throws SecurityException if the caller doesn't have the required permission.
+ */
+ @Override
+ public void deprovisionSatellite(@NonNull List<SatelliteSubscriberInfo> list,
+ @NonNull ResultReceiver result) {
+ enforceSatelliteCommunicationPermission("deprovisionSatellite");
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ mSatelliteController.deprovisionSatellite(list, result);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
+
+ /**
+ * Inform whether application supports NTN SMS in satellite mode.
+ *
+ * This method is used by default messaging application to inform framework whether it supports
+ * NTN SMS or not.
+ *
+ * @param ntnSmsSupported {@code true} If application supports NTN SMS, else {@code false}.
+ *
+ * @throws SecurityException if the caller doesn't have required permission.
+ */
+ @Override
+ public void setNtnSmsSupported(boolean ntnSmsSupported) {
+ enforceSatelliteCommunicationPermission("setNtnSmsSupported");
+ enforceSendSmsPermission();
+ mSatelliteController.setNtnSmsSupportedByMessagesApp(ntnSmsSupported);
+ }
+
+ /**
* This API can be used by only CTS to override the cached value for the device overlay config
* value :
* config_satellite_gateway_service_package and
@@ -14461,4 +14800,49 @@
Binder.restoreCallingIdentity(identity);
}
}
+
+ /**
+ * This API can be used by only CTS to override the Euicc UI component.
+ *
+ * @param componentName ui component to be launched for testing. {@code null} to reset.
+ *
+ * @hide
+ */
+ @Override
+ public void setTestEuiccUiComponent(@Nullable ComponentName componentName) {
+ enforceModifyPermission();
+ log("setTestEuiccUiComponent: " + componentName);
+ mTestEuiccUiComponent = componentName;
+ }
+
+ /**
+ * This API can be used by only CTS to retrieve the Euicc UI component.
+ *
+ * @return Euicc UI component. {@code null} if not available.
+ * @hide
+ */
+ @Override
+ @Nullable
+ public ComponentName getTestEuiccUiComponent() {
+ enforceReadPrivilegedPermission("getTestEuiccUiComponent");
+ return mTestEuiccUiComponent;
+ }
+
+ /**
+ * This API can be used only for test purpose to override the carrier roaming Ntn eligibility
+ *
+ * @param state to update Ntn Eligibility.
+ * @param resetRequired to reset the overridden flag in satellite controller.
+ * @return {@code true} if the shell command is successful, {@code false} otherwise.
+ */
+ public boolean overrideCarrierRoamingNtnEligibilityChanged(boolean state,
+ boolean resetRequired) {
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ return mSatelliteAccessController.overrideCarrierRoamingNtnEligibilityChanged(state,
+ resetRequired);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
}
diff --git a/src/com/android/phone/TelephonyShellCommand.java b/src/com/android/phone/TelephonyShellCommand.java
index bfc93e0..5ea1304 100644
--- a/src/com/android/phone/TelephonyShellCommand.java
+++ b/src/com/android/phone/TelephonyShellCommand.java
@@ -56,12 +56,12 @@
import com.android.internal.telephony.ITelephony;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneFactory;
+import com.android.internal.telephony.TelephonyPermissions;
import com.android.internal.telephony.d2d.Communicator;
import com.android.internal.telephony.emergency.EmergencyNumberTracker;
import com.android.internal.telephony.util.TelephonyUtils;
import com.android.modules.utils.BasicShellCommandHandler;
import com.android.phone.callcomposer.CallComposerPictureManager;
-import com.android.phone.euicc.EuiccUiDispatcherActivity;
import com.android.phone.utils.CarrierAllowListInfo;
import java.io.IOException;
@@ -131,9 +131,6 @@
private static final String CC_SET_VALUES_FROM_XML = "set-values-from-xml";
private static final String CC_CLEAR_VALUES = "clear-values";
- private static final String EUICC_SUBCOMMAND = "euicc";
- private static final String EUICC_SET_UI_COMPONENT = "set-euicc-uicomponent";
-
private static final String GBA_SUBCOMMAND = "gba";
private static final String GBA_SET_SERVICE = "set-service";
private static final String GBA_GET_SERVICE = "get-service";
@@ -190,6 +187,8 @@
"set-satellite-gateway-service-package-name";
private static final String SET_SATELLITE_LISTENING_TIMEOUT_DURATION =
"set-satellite-listening-timeout-duration";
+ private static final String SET_SATELLITE_IGNORE_CELLULAR_SERVICE_STATE =
+ "set-satellite-ignore-cellular-service-state";
private static final String SET_SATELLITE_POINTING_UI_CLASS_NAME =
"set-satellite-pointing-ui-class-name";
private static final String SET_DATAGRAM_CONTROLLER_TIMEOUT_DURATION =
@@ -213,6 +212,9 @@
private static final String SET_SATELLITE_SUBSCRIBERID_LIST_CHANGED_INTENT_COMPONENT =
"set-satellite-subscriberid-list-changed-intent-component";
+ private static final String SET_SATELLITE_ACCESS_RESTRICTION_CHECKING_RESULT =
+ "set-satellite-access-restriction-checking-result";
+
private static final String DOMAIN_SELECTION_SUBCOMMAND = "domainselection";
private static final String DOMAIN_SELECTION_SET_SERVICE_OVERRIDE = "set-dss-override";
private static final String DOMAIN_SELECTION_CLEAR_SERVICE_OVERRIDE = "clear-dss-override";
@@ -358,8 +360,6 @@
return handleDataTestModeCommand();
case END_BLOCK_SUPPRESSION:
return handleEndBlockSuppressionCommand();
- case EUICC_SUBCOMMAND:
- return handleEuiccCommand();
case GBA_SUBCOMMAND:
return handleGbaCommand();
case D2D_SUBCOMMAND:
@@ -405,6 +405,8 @@
return handleSetSatelliteGatewayServicePackageNameCommand();
case SET_SATELLITE_LISTENING_TIMEOUT_DURATION:
return handleSetSatelliteListeningTimeoutDuration();
+ case SET_SATELLITE_IGNORE_CELLULAR_SERVICE_STATE:
+ return handleSetSatelliteIgnoreCellularServiceState();
case SET_SATELLITE_POINTING_UI_CLASS_NAME:
return handleSetSatellitePointingUiClassNameCommand();
case SET_DATAGRAM_CONTROLLER_TIMEOUT_DURATION:
@@ -427,6 +429,8 @@
return handleSetIsSatelliteCommunicationAllowedForCurrentLocationCache();
case SET_SATELLITE_SUBSCRIBERID_LIST_CHANGED_INTENT_COMPONENT:
return handleSetSatelliteSubscriberIdListChangedIntentComponent();
+ case SET_SATELLITE_ACCESS_RESTRICTION_CHECKING_RESULT:
+ return handleOverrideCarrierRoamingNtnEligibilityChanged();
default: {
return handleDefaultCommands(cmd);
}
@@ -522,11 +526,14 @@
private void onHelpIms() {
PrintWriter pw = getOutPrintWriter();
pw.println("IMS Commands:");
- pw.println(" ims set-ims-service [-s SLOT_ID] (-c | -d | -f) PACKAGE_NAME");
+ pw.println(" ims set-ims-service [-s SLOT_ID] [-u USER_ID] (-c | -d | -f) PACKAGE_NAME");
pw.println(" Sets the ImsService defined in PACKAGE_NAME to to be the bound");
pw.println(" ImsService. Options are:");
pw.println(" -s: the slot ID that the ImsService should be bound for. If no option");
pw.println(" is specified, it will choose the default voice SIM slot.");
+ pw.println(" -u: the user ID that the ImsService should be bound on. If no option");
+ pw.println(" is specified, the SYSTEM user ID will be preferred followed by the");
+ pw.println(" current user ID if they are different");
pw.println(" -c: Override the ImsService defined in the carrier configuration.");
pw.println(" -d: Override the ImsService defined in the device overlay.");
pw.println(" -f: Set the feature that this override if for, if no option is");
@@ -691,15 +698,6 @@
pw.println(" is specified, it will choose the default voice SIM slot.");
}
- private void onHelpEuicc() {
- PrintWriter pw = getOutPrintWriter();
- pw.println("Euicc Commands:");
- pw.println(" euicc set-euicc-uicomponent COMPONENT_NAME PACKAGE_NAME");
- pw.println(" Sets the Euicc Ui-Component which handles EuiccService Actions.");
- pw.println(" COMPONENT_NAME: The component name which handles UI Actions.");
- pw.println(" PACKAGE_NAME: THe package name in which ui component belongs.");
- }
-
private void onHelpGba() {
PrintWriter pw = getOutPrintWriter();
pw.println("Gba Commands:");
@@ -1358,12 +1356,22 @@
private int handleImsSetServiceCommand() {
PrintWriter errPw = getErrPrintWriter();
int slotId = getDefaultSlot();
+ int userId = UserHandle.USER_NULL; // By default, set no userId constraint
Boolean isCarrierService = null;
List<Integer> featuresList = new ArrayList<>();
String opt;
while ((opt = getNextOption()) != null) {
switch (opt) {
+ case "-u": {
+ try {
+ userId = Integer.parseInt(getNextArgRequired());
+ } catch (NumberFormatException e) {
+ errPw.println("ims set-ims-service requires an integer as a USER_ID");
+ return -1;
+ }
+ break;
+ }
case "-s": {
try {
slotId = Integer.parseInt(getNextArgRequired());
@@ -1419,17 +1427,17 @@
for (int i = 0; i < featuresList.size(); i++) {
featureArray[i] = featuresList.get(i);
}
- boolean result = mInterface.setBoundImsServiceOverride(slotId, isCarrierService,
+ boolean result = mInterface.setBoundImsServiceOverride(slotId, userId, isCarrierService,
featureArray, packageName);
if (VDBG) {
- Log.v(LOG_TAG, "ims set-ims-service -s " + slotId + " "
+ Log.v(LOG_TAG, "ims set-ims-service -s " + slotId + " -u " + userId + " "
+ (isCarrierService ? "-c " : "-d ")
+ "-f " + featuresList + " "
+ packageName + ", result=" + result);
}
getOutPrintWriter().println(result);
} catch (RemoteException e) {
- Log.w(LOG_TAG, "ims set-ims-service -s " + slotId + " "
+ Log.w(LOG_TAG, "ims set-ims-service -s " + slotId + " -u " + userId + " "
+ (isCarrierService ? "-c " : "-d ")
+ "-f " + featuresList + " "
+ packageName + ", error" + e.getMessage());
@@ -1686,9 +1694,7 @@
}
private boolean checkShellUid() {
- // adb can run as root or as shell, depending on whether the device is rooted.
- return UserHandle.isSameApp(Binder.getCallingUid(), Process.SHELL_UID)
- || UserHandle.isSameApp(Binder.getCallingUid(), Process.ROOT_UID);
+ return TelephonyPermissions.isRootOrShell(Binder.getCallingUid());
}
private int handleCcCommand() {
@@ -2219,35 +2225,6 @@
return 0;
}
- private int handleEuiccCommand() {
- String arg = getNextArg();
- if (arg == null) {
- onHelpEuicc();
- return 0;
- }
-
- switch (arg) {
- case EUICC_SET_UI_COMPONENT: {
- return handleEuiccServiceCommand();
- }
- }
- return -1;
- }
-
- private int handleEuiccServiceCommand() {
- String uiComponent = getNextArg();
- String packageName = getNextArg();
- if (packageName == null || uiComponent == null) {
- return -1;
- }
- EuiccUiDispatcherActivity.setTestEuiccUiComponent(packageName, uiComponent);
- if (VDBG) {
- Log.v(LOG_TAG, "euicc set-euicc-uicomponent " + uiComponent +" "
- + packageName);
- }
- return 0;
- }
-
private int handleRestartModemCommand() {
// Verify that the user is allowed to run the command. Only allowed in rooted device in a
// non user build.
@@ -3400,6 +3377,37 @@
return 0;
}
+ private int handleSetSatelliteIgnoreCellularServiceState() {
+ PrintWriter errPw = getErrPrintWriter();
+ boolean enabled = false;
+
+ String opt;
+ while ((opt = getNextOption()) != null) {
+ switch (opt) {
+ case "-d": {
+ enabled = Boolean.parseBoolean(getNextArgRequired());
+ break;
+ }
+ }
+ }
+ Log.d(LOG_TAG, "handleSetSatelliteIgnoreCellularServiceState: enabled =" + enabled);
+
+ try {
+ boolean result = mInterface.setSatelliteIgnoreCellularServiceState(enabled);
+ if (VDBG) {
+ Log.v(LOG_TAG, "handleSetSatelliteIgnoreCellularServiceState " + enabled
+ + ", result = " + result);
+ }
+ getOutPrintWriter().println(result);
+ } catch (RemoteException e) {
+ Log.w(LOG_TAG, "handleSetSatelliteIgnoreCellularServiceState: " + enabled
+ + ", error = " + e.getMessage());
+ errPw.println("Exception: " + e.getMessage());
+ return -1;
+ }
+ return 0;
+ }
+
private int handleSetDatagramControllerTimeoutDuration() {
PrintWriter errPw = getErrPrintWriter();
boolean reset = false;
@@ -3726,7 +3734,6 @@
PrintWriter errPw = getErrPrintWriter();
String opt;
String state;
-
if ((opt = getNextArg()) == null) {
errPw.println(
"adb shell cmd phone set-is-satellite-communication-allowed-for-current"
@@ -3739,6 +3746,10 @@
state = "cache_allowed";
break;
}
+ case "-na": {
+ state = "cache_not_allowed";
+ break;
+ }
case "-n": {
state = "cache_clear_and_not_allowed";
break;
@@ -4077,4 +4088,48 @@
}
return jSonString;
}
+
+ /**
+ * This method override the check for carrier roaming Ntn eligibility.
+ * <ul>
+ * <li> `adb shell cmd phone set-satellite-access-restriction-checking-result true` will set
+ * override eligibility to true.</li>
+ * <li> `adb shell cmd phone set-satellite-access-restriction-checking-result false` will
+ * override eligibility to false.</li>
+ * <li> `adb shell cmd phone set-satellite-access-restriction-checking-result` will reset the
+ * override data set through adb command.</li>
+ * </ul>
+ *
+ * @return {@code true} is command executed successfully otherwise {@code false}.
+ */
+ private int handleOverrideCarrierRoamingNtnEligibilityChanged() {
+ PrintWriter errPw = getErrPrintWriter();
+ String opt;
+ boolean state = false;
+ boolean isRestRequired = false;
+ try {
+ if ((opt = getNextArg()) == null) {
+ isRestRequired = true;
+ } else {
+ if ("true".equalsIgnoreCase(opt)) {
+ state = true;
+ }
+ }
+ boolean result = mInterface.overrideCarrierRoamingNtnEligibilityChanged(state,
+ isRestRequired);
+ if (VDBG) {
+ Log.v(LOG_TAG, "handleSetSatelliteAccessRestrictionCheckingResult "
+ + "returns: "
+ + result);
+ }
+ getOutPrintWriter().println(result);
+ } catch (RemoteException e) {
+ Log.w(LOG_TAG, "handleSetSatelliteAccessRestrictionCheckingResult("
+ + state + "), error = " + e.getMessage());
+ errPw.println("Exception: " + e.getMessage());
+ return -1;
+ }
+ Log.d(LOG_TAG, "handleSetSatelliteAccessRestrictionCheckingResult(" + state + ")");
+ return 0;
+ }
}
diff --git a/src/com/android/phone/euicc/EuiccUiDispatcherActivity.java b/src/com/android/phone/euicc/EuiccUiDispatcherActivity.java
index a75f26f..9632329 100644
--- a/src/com/android/phone/euicc/EuiccUiDispatcherActivity.java
+++ b/src/com/android/phone/euicc/EuiccUiDispatcherActivity.java
@@ -28,8 +28,8 @@
import android.os.UserHandle;
import android.permission.LegacyPermissionManager;
import android.service.euicc.EuiccService;
+import android.telephony.TelephonyManager;
import android.telephony.euicc.EuiccManager;
-import android.text.TextUtils;
import android.util.Log;
import com.android.internal.annotations.VisibleForTesting;
@@ -59,8 +59,6 @@
private LegacyPermissionManager mPermissionManager;
private boolean mGrantPermissionDone = false;
private ThreadPoolExecutor mExecutor;
- // Used for CTS EuiccManager action verification
- private static ComponentName mTestEuiccUiComponentName;
@Override
public void onCreate(Bundle savedInstanceState) {
@@ -97,18 +95,6 @@
}
}
- /**
- * This API used to set the Test EuiccUiComponent for CTS
- * @param packageName package which handles the intent
- * @param componentName ui component to be launched for testing
- */
- public static void setTestEuiccUiComponent(String packageName, String componentName) {
- mTestEuiccUiComponentName = null;
- if (!TextUtils.isEmpty(packageName) && !TextUtils.isEmpty(componentName)) {
- mTestEuiccUiComponentName = new ComponentName(packageName, componentName);
- }
- }
-
@VisibleForTesting
@Nullable
Intent resolveEuiccUiIntent() {
@@ -124,10 +110,11 @@
return null;
}
- if (mTestEuiccUiComponentName != null) {
- Log.i(TAG, "Test mode");
- euiccUiIntent.setComponent(mTestEuiccUiComponentName);
- mTestEuiccUiComponentName = null;
+ ComponentName testEuiccUiComponent = ((TelephonyManager)
+ getSystemService(Context.TELEPHONY_SERVICE)).getTestEuiccUiComponent();
+ if (testEuiccUiComponent != null) {
+ Log.i(TAG, "Test mode: " + testEuiccUiComponent);
+ euiccUiIntent.setComponent(testEuiccUiComponent);
return euiccUiIntent;
}
diff --git a/src/com/android/phone/satellite/accesscontrol/S2RangeSatelliteOnDeviceAccessController.java b/src/com/android/phone/satellite/accesscontrol/S2RangeSatelliteOnDeviceAccessController.java
index 4490460..845ff18 100644
--- a/src/com/android/phone/satellite/accesscontrol/S2RangeSatelliteOnDeviceAccessController.java
+++ b/src/com/android/phone/satellite/accesscontrol/S2RangeSatelliteOnDeviceAccessController.java
@@ -16,10 +16,12 @@
package com.android.phone.satellite.accesscontrol;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.telephony.Rlog;
-import com.android.storage.s2.S2LevelRange;
+import com.android.internal.telephony.flags.FeatureFlags;
import com.android.telephony.sats2range.read.SatS2RangeFileReader;
+import com.android.telephony.sats2range.read.SuffixTableRange;
import com.google.common.geometry.S2CellId;
import com.google.common.geometry.S2LatLng;
@@ -36,31 +38,42 @@
private static final String TAG = "S2RangeSatelliteOnDeviceAccessController";
private static final boolean DBG = false;
- @NonNull private final SatS2RangeFileReader mSatS2RangeFileReader;
+ @NonNull
+ private final SatS2RangeFileReader mSatS2RangeFileReader;
private final int mS2Level;
+ /** Feature flags to control behavior and errors. */
+ @NonNull
+ private final FeatureFlags mFeatureFlags;
+
private S2RangeSatelliteOnDeviceAccessController(
- @NonNull SatS2RangeFileReader satS2RangeFileReader, int s2Level) {
+ @NonNull SatS2RangeFileReader satS2RangeFileReader,
+ int s2Level,
+ @NonNull FeatureFlags featureFlags) {
mSatS2RangeFileReader = Objects.requireNonNull(satS2RangeFileReader);
mS2Level = s2Level;
+ mFeatureFlags = featureFlags;
}
/**
* Returns a new {@link S2RangeSatelliteOnDeviceAccessController} using the specified data file.
*
* @param file The input file that contains the S2-range-based access restriction information.
- * @throws IOException in the event of a problem while reading the underlying file.
+ * @throws IOException in the event of a problem while reading the underlying file.
* @throws IllegalArgumentException if either the S2 level defined by
- * {@code config_oem_enabled_satellite_s2cell_level} or the satellite access allow defined by
- * {@code config_oem_enabled_satellite_access_allow} does not match the values included in the
- * header of the input file.
+ * {@code config_oem_enabled_satellite_s2cell_level} or the
+ * satellite access allow defined by
+ * {@code config_oem_enabled_satellite_access_allow} does not
+ * match the values included in the
+ * header of the input file.
*/
public static S2RangeSatelliteOnDeviceAccessController create(
- @NonNull File file) throws IOException, IllegalArgumentException {
+ @NonNull File file, FeatureFlags featureFlags)
+ throws IOException, IllegalArgumentException {
SatS2RangeFileReader reader = SatS2RangeFileReader.open(file);
int s2Level = reader.getS2Level();
- return new S2RangeSatelliteOnDeviceAccessController(reader, s2Level);
+ return new S2RangeSatelliteOnDeviceAccessController(reader, s2Level, featureFlags);
}
public static LocationToken createLocationTokenForLatLng(
@@ -84,7 +97,7 @@
}
private boolean isSatCommunicationAllowedAtLocation(long s2CellId) throws IOException {
- S2LevelRange entry = mSatS2RangeFileReader.findEntryByCellId(s2CellId);
+ SuffixTableRange entry = mSatS2RangeFileReader.findEntryByCellId(s2CellId);
if (mSatS2RangeFileReader.isAllowedList()) {
// The file contains an allowed list of S2 cells. Thus, satellite is allowed if an
// entry is found
@@ -158,4 +171,25 @@
return Objects.hash(mS2CellId);
}
}
+
+ @Override
+ @Nullable
+ public Integer getRegionalConfigIdForLocation(@NonNull LocationToken locationToken)
+ throws IOException {
+ if (!mFeatureFlags.carrierRoamingNbIotNtn()) {
+ logd("getAccessControlConfigIdForLocation: carrierRoamingNbIotNtn is disabled");
+ return null;
+ }
+
+ if (locationToken instanceof LocationTokenImpl locationTokenImpl) {
+ return getRegionalConfigIdForLocation(locationTokenImpl.getS2CellId());
+ } else {
+ throw new IllegalArgumentException("Unknown locationToken=" + locationToken);
+ }
+ }
+
+ private Integer getRegionalConfigIdForLocation(long s2CellId) throws IOException {
+ SuffixTableRange entry = mSatS2RangeFileReader.findEntryByCellId(s2CellId);
+ return (entry == null) ? null : entry.getEntryValue();
+ }
}
diff --git a/src/com/android/phone/satellite/accesscontrol/SatelliteAccessController.java b/src/com/android/phone/satellite/accesscontrol/SatelliteAccessController.java
index 7b244a1..5f60291 100644
--- a/src/com/android/phone/satellite/accesscontrol/SatelliteAccessController.java
+++ b/src/com/android/phone/satellite/accesscontrol/SatelliteAccessController.java
@@ -16,9 +16,16 @@
package com.android.phone.satellite.accesscontrol;
+import static android.telephony.satellite.SatelliteManager.KEY_SATELLITE_ACCESS_CONFIGURATION;
import static android.telephony.satellite.SatelliteManager.KEY_SATELLITE_COMMUNICATION_ALLOWED;
import static android.telephony.satellite.SatelliteManager.KEY_SATELLITE_PROVISIONED;
import static android.telephony.satellite.SatelliteManager.KEY_SATELLITE_SUPPORTED;
+import static android.telephony.satellite.SatelliteManager.SATELLITE_DISALLOWED_REASON_NOT_SUPPORTED;
+import static android.telephony.satellite.SatelliteManager.SATELLITE_DISALLOWED_REASON_NOT_PROVISIONED;
+import static android.telephony.satellite.SatelliteManager.SATELLITE_DISALLOWED_REASON_NOT_IN_ALLOWED_REGION;
+import static android.telephony.satellite.SatelliteManager.SATELLITE_DISALLOWED_REASON_UNSUPPORTED_DEFAULT_MSG_APP;
+import static android.telephony.satellite.SatelliteManager.SATELLITE_DISALLOWED_REASON_LOCATION_DISABLED;
+import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_INVALID_TELEPHONY_STATE;
import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_LOCATION_DISABLED;
import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_LOCATION_NOT_AVAILABLE;
import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_NOT_SUPPORTED;
@@ -34,7 +41,11 @@
import android.annotation.ArrayRes;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.app.Notification;
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
import android.content.BroadcastReceiver;
+import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
@@ -56,16 +67,20 @@
import android.os.ResultReceiver;
import android.os.SystemClock;
import android.os.SystemProperties;
+import android.os.UserHandle;
import android.provider.DeviceConfig;
import android.telecom.TelecomManager;
import android.telephony.AnomalyReporter;
import android.telephony.DropBoxManagerLoggerBackend;
+import android.telephony.NetworkRegistrationInfo;
import android.telephony.PersistentLogger;
import android.telephony.Rlog;
import android.telephony.SubscriptionManager;
import android.telephony.satellite.ISatelliteCommunicationAllowedStateCallback;
+import android.telephony.satellite.ISatelliteDisallowedReasonsCallback;
import android.telephony.satellite.ISatelliteProvisionStateCallback;
import android.telephony.satellite.ISatelliteSupportedStateCallback;
+import android.telephony.satellite.SatelliteAccessConfiguration;
import android.telephony.satellite.SatelliteManager;
import android.telephony.satellite.SatelliteSubscriberProvisionStatus;
import android.text.TextUtils;
@@ -76,6 +91,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneFactory;
+import com.android.internal.telephony.SmsApplication;
import com.android.internal.telephony.TelephonyCountryDetector;
import com.android.internal.telephony.flags.FeatureFlags;
import com.android.internal.telephony.satellite.SatelliteConfig;
@@ -97,11 +113,13 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
+import java.util.Objects;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
@@ -145,6 +163,60 @@
protected static final int EVENT_COUNTRY_CODE_CHANGED = 5;
protected static final int EVENT_LOCATION_SETTINGS_ENABLED = 6;
+ public static final int DEFAULT_REGIONAL_SATELLITE_CONFIG_ID = 0;
+ public static final int UNKNOWN_REGIONAL_SATELLITE_CONFIG_ID = -1;
+
+
+ private static final String KEY_AVAILABLE_NOTIFICATION_SHOWN = "available_notification_shown";
+ private static final String KEY_UNAVAILABLE_NOTIFICATION_SHOWN =
+ "unavailable_notification_shown";
+ private static final String NOTIFICATION_TAG = "SatelliteAccessController";
+ private static final int NOTIFICATION_ID = 1;
+ private static final String NOTIFICATION_CHANNEL = "satelliteChannel";
+ private static final String NOTIFICATION_CHANNEL_ID = "satellite";
+ private static final int SATELLITE_DISALLOWED_REASON_NONE = -1;
+ private static final List<Integer> DISALLOWED_REASONS_TO_BE_RESET =
+ Arrays.asList(SATELLITE_DISALLOWED_REASON_NOT_IN_ALLOWED_REGION,
+ SATELLITE_DISALLOWED_REASON_LOCATION_DISABLED);
+
+ private static final HashMap<Integer, Pair<Integer, Integer>>
+ SATELLITE_SOS_UNAVAILABLE_REASONS = new HashMap<>(Map.of(
+ SATELLITE_DISALLOWED_REASON_NOT_SUPPORTED, new Pair<>(
+ R.string.satellite_sos_not_supported_notification_title,
+ R.string.satellite_sos_not_supported_notification_summary),
+ SATELLITE_DISALLOWED_REASON_NOT_PROVISIONED, new Pair<>(
+ R.string.satellite_sos_not_provisioned_notification_title,
+ R.string.satellite_sos_not_provisioned_notification_summary),
+ SATELLITE_DISALLOWED_REASON_NOT_IN_ALLOWED_REGION, new Pair<>(
+ R.string.satellite_sos_not_in_allowed_region_notification_title,
+ R.string.satellite_sos_not_in_allowed_region_notification_summary),
+ SATELLITE_DISALLOWED_REASON_UNSUPPORTED_DEFAULT_MSG_APP, new Pair<>(
+ R.string.satellite_sos_unsupported_default_sms_app_notification_title,
+ R.string.satellite_sos_unsupported_default_sms_app_notification_summary),
+ SATELLITE_DISALLOWED_REASON_LOCATION_DISABLED, new Pair<>(
+ R.string.satellite_sos_location_disabled_notification_title,
+ R.string.satellite_sos_location_disabled_notification_summary)
+ ));
+
+ private static final HashMap<Integer, Pair<Integer, Integer>>
+ SATELLITE_MESSAGING_UNAVAILABLE_REASONS = new HashMap<>(Map.of(
+ SATELLITE_DISALLOWED_REASON_NOT_SUPPORTED, new Pair<>(
+ R.string.satellite_messaging_not_supported_notification_title,
+ R.string.satellite_messaging_not_supported_notification_summary),
+ SATELLITE_DISALLOWED_REASON_NOT_PROVISIONED, new Pair<>(
+ R.string.satellite_messaging_not_provisioned_notification_title,
+ R.string.satellite_messaging_not_provisioned_notification_summary),
+ SATELLITE_DISALLOWED_REASON_NOT_IN_ALLOWED_REGION, new Pair<>(
+ R.string.satellite_messaging_not_in_allowed_region_notification_title,
+ R.string.satellite_messaging_not_in_allowed_region_notification_summary),
+ SATELLITE_DISALLOWED_REASON_UNSUPPORTED_DEFAULT_MSG_APP, new Pair<>(
+ R.string.satellite_messaging_unsupported_default_sms_app_notification_title,
+ R.string.satellite_messaging_unsupported_default_sms_app_notification_summary),
+ SATELLITE_DISALLOWED_REASON_LOCATION_DISABLED, new Pair<>(
+ R.string.satellite_messaging_location_disabled_notification_title,
+ R.string.satellite_messaging_location_disabled_notification_summary)
+ ));
+
private static SatelliteAccessController sInstance;
/** Feature flags to control behavior and errors. */
@@ -194,11 +266,11 @@
private long mOverriddenLocationFreshDurationNanos;
@GuardedBy("mLock")
@NonNull
- private final Map<SatelliteOnDeviceAccessController.LocationToken, Boolean>
+ private final Map<SatelliteOnDeviceAccessController.LocationToken, Integer>
mCachedAccessRestrictionMap = new LinkedHashMap<>() {
@Override
protected boolean removeEldestEntry(
- Entry<SatelliteOnDeviceAccessController.LocationToken, Boolean> eldest) {
+ Entry<SatelliteOnDeviceAccessController.LocationToken, Integer> eldest) {
return size() > MAX_CACHE_SIZE;
}
};
@@ -209,6 +281,17 @@
@GuardedBy("mLock")
@Nullable
private Location mFreshLastKnownLocation = null;
+ @GuardedBy("mLock")
+ @Nullable
+ protected Integer mRegionalConfigId = null;
+ @GuardedBy("mLock")
+ @Nullable
+ protected Integer mNewRegionalConfigId = null;
+
+ /** Key: Config ID; Value: SatelliteAccessConfiguration */
+ @NonNull
+ private HashMap<Integer, SatelliteAccessConfiguration> mSatelliteAccessConfigMap =
+ new HashMap<>();
/** These are used for CTS test */
private Path mCtsSatS2FilePath = null;
@@ -259,9 +342,13 @@
*/
private final ConcurrentHashMap<IBinder, ISatelliteCommunicationAllowedStateCallback>
mSatelliteCommunicationAllowedStateChangedListeners = new ConcurrentHashMap<>();
- private final Object mSatelliteCommunicationAllowStateLock = new Object();
+ protected final Object mSatelliteCommunicationAllowStateLock = new Object();
@GuardedBy("mSatelliteCommunicationAllowStateLock")
- private boolean mCurrentSatelliteAllowedState = false;
+ protected boolean mCurrentSatelliteAllowedState = false;
+
+ private final ConcurrentHashMap<IBinder, ISatelliteDisallowedReasonsCallback>
+ mSatelliteDisallowedReasonsChangedListeners = new ConcurrentHashMap<>();
+ private final Object mSatelliteDisallowedReasonsLock = new Object();
protected static final long ALLOWED_STATE_CACHE_VALID_DURATION_NANOS =
TimeUnit.HOURS.toNanos(4);
@@ -273,6 +360,13 @@
private long mOnDeviceLookupStartTimeMillis;
private long mTotalCheckingStartTimeMillis;
+ private final boolean mNotifySatelliteAvailabilityEnabled;
+ private Notification mSatelliteAvailableNotification;
+ // Key: SatelliteManager#SatelliteDisallowedReason; Value: Notification
+ private final Map<Integer, Notification> mSatelliteUnAvailableNotifications = new HashMap<>();
+ private NotificationManager mNotificationManager;
+ private final List<Integer> mSatelliteDisallowedReasons = new ArrayList<>();
+
protected BroadcastReceiver mLocationModeChangedBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
@@ -345,6 +439,9 @@
handleIsSatelliteSupportedResult(resultCode, resultData);
}
};
+ mSatelliteController.incrementResultReceiverCount(
+ "SAC:mInternalSatelliteSupportedResultReceiver");
+
mInternalSatelliteProvisionedResultReceiver = new ResultReceiver(this) {
@Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
@@ -353,19 +450,38 @@
};
mConfigUpdaterMetricsStats = ConfigUpdaterMetricsStats.getOrCreateInstance();
+ mNotifySatelliteAvailabilityEnabled =
+ context.getResources().getBoolean(
+ R.bool.config_satellite_should_notify_availability);
mInternalSatelliteSupportedStateCallback = new ISatelliteSupportedStateCallback.Stub() {
@Override
public void onSatelliteSupportedStateChanged(boolean isSupported) {
logd("onSatelliteSupportedStateChanged: isSupported=" + isSupported);
if (isSupported) {
+ final String caller = "SAC:onSatelliteSupportedStateChanged";
requestIsCommunicationAllowedForCurrentLocation(
new ResultReceiver(null) {
@Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
+ mSatelliteController.decrementResultReceiverCount(caller);
// do nothing
}
}, false);
+ mSatelliteController.incrementResultReceiverCount(caller);
+ if (mSatelliteDisallowedReasons.contains(
+ Integer.valueOf(SATELLITE_DISALLOWED_REASON_NOT_SUPPORTED))) {
+ mSatelliteDisallowedReasons.remove(
+ Integer.valueOf(SATELLITE_DISALLOWED_REASON_NOT_SUPPORTED));
+ handleEventDisallowedReasonsChanged();
+ }
+ } else {
+ if (!mSatelliteDisallowedReasons.contains(
+ Integer.valueOf(SATELLITE_DISALLOWED_REASON_NOT_SUPPORTED))) {
+ mSatelliteDisallowedReasons.add(
+ Integer.valueOf(SATELLITE_DISALLOWED_REASON_NOT_SUPPORTED));
+ handleEventDisallowedReasonsChanged();
+ }
}
}
};
@@ -377,13 +493,29 @@
public void onSatelliteProvisionStateChanged(boolean isProvisioned) {
logd("onSatelliteProvisionStateChanged: isProvisioned=" + isProvisioned);
if (isProvisioned) {
+ final String caller = "SAC:onSatelliteProvisionStateChanged";
requestIsCommunicationAllowedForCurrentLocation(
new ResultReceiver(null) {
@Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
+ mSatelliteController.decrementResultReceiverCount(caller);
// do nothing
}
}, false);
+ mSatelliteController.incrementResultReceiverCount(caller);
+ if (mSatelliteDisallowedReasons.contains(
+ SATELLITE_DISALLOWED_REASON_NOT_PROVISIONED)) {
+ mSatelliteDisallowedReasons.remove(
+ Integer.valueOf(SATELLITE_DISALLOWED_REASON_NOT_PROVISIONED));
+ handleEventDisallowedReasonsChanged();
+ }
+ } else {
+ if (!mSatelliteDisallowedReasons.contains(
+ SATELLITE_DISALLOWED_REASON_NOT_PROVISIONED)) {
+ mSatelliteDisallowedReasons.add(
+ SATELLITE_DISALLOWED_REASON_NOT_PROVISIONED);
+ handleEventDisallowedReasonsChanged();
+ }
}
}
@@ -399,7 +531,9 @@
// Init the SatelliteOnDeviceAccessController so that the S2 level can be cached
initSatelliteOnDeviceAccessController();
+ initializeSatelliteSystemNotification(context);
registerLocationModeChangedBroadcastReceiver(context);
+ registerDefaultSmsAppChangedBroadcastReceiver(context);
}
private void updateCurrentSatelliteAllowedState(boolean isAllowed) {
@@ -411,6 +545,13 @@
mCurrentSatelliteAllowedState = isAllowed;
notifySatelliteCommunicationAllowedStateChanged(isAllowed);
mControllerMetricsStats.reportAllowedStateChanged();
+ if (!isAllowed) {
+ synchronized (mLock) {
+ plogd("updateCurrentSatelliteAllowedState : set mNewRegionalConfigId null");
+ mNewRegionalConfigId = null;
+ }
+ }
+ updateRegionalConfigId();
}
}
}
@@ -479,7 +620,69 @@
}
mAccessControllerMetricsStats.setTriggeringEvent(TRIGGERING_EVENT_EXTERNAL_REQUEST);
sendRequestAsync(CMD_IS_SATELLITE_COMMUNICATION_ALLOWED,
- new Pair<>(mSatelliteController.getSatellitePhone().getSubId(), result));
+ new Pair<>(mSatelliteController.getSelectedSatelliteSubId(), result));
+ mSatelliteController.incrementResultReceiverCount(
+ "SAC:requestIsCommunicationAllowedForCurrentLocation");
+ }
+
+ /**
+ * Request to get satellite access configuration for the current location.
+ *
+ * @param result The result receiver that returns satellite access configuration
+ * for the current location if the request is successful or an error code
+ * if the request failed.
+ */
+ public void requestSatelliteAccessConfigurationForCurrentLocation(
+ @NonNull ResultReceiver result) {
+ if (!mFeatureFlags.carrierRoamingNbIotNtn()) {
+ plogd("carrierRoamingNbIotNtnFlag is disabled");
+ result.send(SATELLITE_RESULT_REQUEST_NOT_SUPPORTED, null);
+ return;
+ }
+ plogd("requestSatelliteAccessConfigurationForCurrentLocation");
+ ResultReceiver internalResultReceiver = new ResultReceiver(this) {
+ @Override
+ protected void onReceiveResult(int resultCode, Bundle resultData) {
+ plogd("requestSatelliteAccessConfigurationForCurrentLocation: resultCode="
+ + resultCode + ", resultData=" + resultData);
+ boolean isSatelliteCommunicationAllowed = false;
+ if (resultCode == SATELLITE_RESULT_SUCCESS) {
+ if (resultData.containsKey(KEY_SATELLITE_COMMUNICATION_ALLOWED)) {
+ isSatelliteCommunicationAllowed =
+ resultData.getBoolean(KEY_SATELLITE_COMMUNICATION_ALLOWED);
+ } else {
+ loge("KEY_SATELLITE_COMMUNICATION_ALLOWED does not exist.");
+ result.send(SATELLITE_RESULT_INVALID_TELEPHONY_STATE, null);
+ return;
+ }
+ } else {
+ loge("resultCode is not SATELLITE_RESULT_SUCCESS.");
+ result.send(resultCode, null);
+ return;
+ }
+
+ SatelliteAccessConfiguration satelliteAccessConfig = null;
+ synchronized (mLock) {
+ if (isSatelliteCommunicationAllowed && isRegionalConfigIdValid(
+ mRegionalConfigId)) {
+ plogd("requestSatelliteAccessConfigurationForCurrentLocation : "
+ + "mRegionalConfigId is " + mRegionalConfigId);
+ satelliteAccessConfig =
+ mSatelliteAccessConfigMap.get(mRegionalConfigId);
+ }
+ }
+ plogd("requestSatelliteAccessConfigurationForCurrentLocation : "
+ + "satelliteAccessConfig is " + satelliteAccessConfig);
+ Bundle bundle = new Bundle();
+ bundle.putParcelable(KEY_SATELLITE_ACCESS_CONFIGURATION, satelliteAccessConfig);
+ result.send(resultCode, bundle);
+ }
+ };
+ requestIsCommunicationAllowedForCurrentLocation(internalResultReceiver, false);
+ }
+
+ private boolean isRegionalConfigIdValid(@Nullable Integer configId) {
+ return (configId != null && configId >= 0);
}
/**
@@ -611,7 +814,7 @@
private boolean isS2CellFileValid(@NonNull File s2CellFile) {
try {
SatelliteOnDeviceAccessController satelliteOnDeviceAccessController =
- SatelliteOnDeviceAccessController.create(s2CellFile);
+ SatelliteOnDeviceAccessController.create(s2CellFile, mFeatureFlags);
int s2Level = satelliteOnDeviceAccessController.getS2Level();
if (s2Level < MIN_S2_LEVEL || s2Level > MAX_S2_LEVEL) {
ploge("isS2CellFileValid: invalid s2 level = " + s2Level);
@@ -946,6 +1149,18 @@
}
}
+ private void registerDefaultSmsAppChangedBroadcastReceiver(Context context) {
+ if (!mFeatureFlags.oemEnabledSatelliteFlag()) {
+ plogd("registerDefaultSmsAppChangedBroadcastReceiver: Flag "
+ + "oemEnabledSatellite is disabled");
+ return;
+ }
+ IntentFilter intentFilter = new IntentFilter();
+ intentFilter.addAction(Intent.ACTION_PACKAGE_CHANGED);
+ intentFilter.addDataScheme("package");
+ context.registerReceiver(mDefaultSmsAppChangedBroadcastReceiver, intentFilter);
+ }
+
private void registerLocationModeChangedBroadcastReceiver(Context context) {
if (!mFeatureFlags.oemEnabledSatelliteFlag()) {
plogd("registerLocationModeChangedBroadcastReceiver: Flag "
@@ -1002,8 +1217,8 @@
if (isRegionDisallowed(networkCountryIsoList)) {
Bundle bundle = new Bundle();
bundle.putBoolean(KEY_SATELLITE_COMMUNICATION_ALLOWED, false);
- mAccessControllerMetricsStats.setAccessControlType(
- SatelliteConstants.ACCESS_CONTROL_TYPE_NETWORK_COUNTRY_CODE)
+ mAccessControllerMetricsStats.setAccessControlType(SatelliteConstants
+ .ACCESS_CONTROL_TYPE_NETWORK_COUNTRY_CODE)
.setCountryCodes(networkCountryIsoList);
sendSatelliteAllowResultToReceivers(SATELLITE_RESULT_SUCCESS, bundle,
false);
@@ -1049,7 +1264,7 @@
}
private void sendSatelliteAllowResultToReceivers(int resultCode, Bundle resultData,
- boolean allowed) {
+ boolean allowed) {
plogd("sendSatelliteAllowResultToReceivers : resultCode is " + resultCode);
if (resultCode == SATELLITE_RESULT_SUCCESS) {
updateCurrentSatelliteAllowedState(allowed);
@@ -1057,18 +1272,103 @@
synchronized (mLock) {
for (ResultReceiver resultReceiver : mSatelliteAllowResultReceivers) {
resultReceiver.send(resultCode, resultData);
+ mSatelliteController.decrementResultReceiverCount(
+ "SAC:requestIsCommunicationAllowedForCurrentLocation");
}
mSatelliteAllowResultReceivers.clear();
}
if (!shouldRetryValidatingPossibleChangeInAllowedRegion(resultCode)) {
setIsSatelliteAllowedRegionPossiblyChanged(false);
}
+ Integer disallowedReason = getDisallowedReason(resultCode, allowed);
+ boolean isChanged = false;
+ if (disallowedReason != SATELLITE_DISALLOWED_REASON_NONE) {
+ if (!mSatelliteDisallowedReasons.contains(disallowedReason)) {
+ isChanged = true;
+ }
+ } else {
+ if (mSatelliteDisallowedReasons.contains(
+ SATELLITE_DISALLOWED_REASON_NOT_IN_ALLOWED_REGION)
+ || mSatelliteDisallowedReasons.contains(
+ SATELLITE_DISALLOWED_REASON_LOCATION_DISABLED)) {
+ isChanged = true;
+ }
+ }
+ mSatelliteDisallowedReasons.removeAll(DISALLOWED_REASONS_TO_BE_RESET);
+ if (disallowedReason != SATELLITE_DISALLOWED_REASON_NONE) {
+ mSatelliteDisallowedReasons.add(disallowedReason);
+ }
+ if (isChanged) {
+ handleEventDisallowedReasonsChanged();
+ }
synchronized (mIsAllowedCheckBeforeEnablingSatelliteLock) {
mIsAllowedCheckBeforeEnablingSatellite = false;
}
reportMetrics(resultCode, allowed);
}
+ private int getDisallowedReason(int resultCode, boolean allowed) {
+ if (resultCode == SATELLITE_RESULT_SUCCESS) {
+ if (!allowed) {
+ return SATELLITE_DISALLOWED_REASON_NOT_IN_ALLOWED_REGION;
+ }
+ } else if (resultCode == SATELLITE_RESULT_LOCATION_DISABLED) {
+ return SATELLITE_DISALLOWED_REASON_LOCATION_DISABLED;
+ }
+ return SATELLITE_DISALLOWED_REASON_NONE;
+ }
+
+ private void handleEventDisallowedReasonsChanged() {
+ logd("mSatelliteDisallowedReasons:"
+ + String.join(", ", mSatelliteDisallowedReasons.toString()));
+ notifySatelliteDisallowedReasonsChanged();
+ if (mNotifySatelliteAvailabilityEnabled) {
+ showSatelliteSystemNotification();
+ }
+ }
+
+ private void showSatelliteSystemNotification() {
+ if (mSatelliteDisallowedReasons.isEmpty()) {
+ if (!hasAlreadyNotified(KEY_AVAILABLE_NOTIFICATION_SHOWN, 0)) {
+ mNotificationManager.notifyAsUser(
+ NOTIFICATION_TAG,
+ NOTIFICATION_ID,
+ mSatelliteAvailableNotification,
+ UserHandle.ALL
+ );
+ markAsNotified(KEY_AVAILABLE_NOTIFICATION_SHOWN, 0);
+ }
+ } else {
+ for (Integer reason : mSatelliteDisallowedReasons) {
+ if (!hasAlreadyNotified(KEY_UNAVAILABLE_NOTIFICATION_SHOWN, reason)) {
+ mNotificationManager.notifyAsUser(
+ NOTIFICATION_TAG,
+ NOTIFICATION_ID,
+ mSatelliteUnAvailableNotifications.get(reason),
+ UserHandle.ALL
+ );
+ markAsNotified(KEY_UNAVAILABLE_NOTIFICATION_SHOWN, reason);
+ break;
+ }
+ }
+ }
+ }
+
+ private boolean hasAlreadyNotified(String key, int reason) {
+ Set<String> reasons = mSharedPreferences.getStringSet(key, new HashSet<>());
+ return reasons.contains(String.valueOf(reason));
+ }
+
+ private void markAsNotified(String key, int reason) {
+ Set<String> reasons = mSharedPreferences.getStringSet(key, new HashSet<>());
+ if (!reasons.contains(String.valueOf(reason))) {
+ reasons.add(String.valueOf(reason));
+ SharedPreferences.Editor editor = mSharedPreferences.edit();
+ editor.putStringSet(key, reasons);
+ editor.apply();
+ }
+ }
+
/**
* Telephony-internal logic to verify if satellite access is restricted at the current
* location.
@@ -1132,6 +1432,122 @@
};
}
+ private void initializeSatelliteSystemNotification(@NonNull Context context) {
+ final NotificationChannel notificationChannel = new NotificationChannel(
+ NOTIFICATION_CHANNEL_ID,
+ NOTIFICATION_CHANNEL,
+ NotificationManager.IMPORTANCE_DEFAULT
+ );
+ notificationChannel.setSound(null, null);
+ mNotificationManager = context.getSystemService(NotificationManager.class);
+ mNotificationManager.createNotificationChannel(notificationChannel);
+
+ createAvailableNotifications(context);
+ createUnavailableNotifications(context);
+ }
+
+ private Notification createNotification(@NonNull Context context,
+ String title,
+ String content) {
+ Notification.Builder notificationBuilder = new Notification.Builder(context)
+ .setContentTitle(title)
+ .setContentText(content)
+ .setSmallIcon(R.drawable.ic_android_satellite_24px)
+ .setChannelId(NOTIFICATION_CHANNEL_ID)
+ .setAutoCancel(true)
+ .setColor(context.getColor(
+ com.android.internal.R.color.system_notification_accent_color))
+ .setVisibility(Notification.VISIBILITY_PUBLIC);
+
+ return notificationBuilder.build();
+ }
+
+ private void createAvailableNotifications(Context context) {
+ int subId = mSatelliteController.getSelectedSatelliteSubId();
+ int titleId;
+ int summaryId;
+
+ if (mSatelliteController.isSatelliteServiceSupportedByCarrier(
+ subId, NetworkRegistrationInfo.SERVICE_TYPE_SMS)) {
+ titleId = R.string.satellite_messaging_available_notification_title;
+ summaryId = R.string.satellite_messaging_available_notification_summary;
+ } else {
+ titleId = R.string.satellite_sos_available_notification_title;
+ summaryId = R.string.satellite_sos_available_notification_summary;
+ }
+
+ mSatelliteAvailableNotification = createNotification(
+ context,
+ context.getResources().getString(titleId),
+ context.getResources().getString(summaryId));
+ }
+
+ private void createUnavailableNotifications(Context context) {
+ int subId = mSatelliteController.getSelectedSatelliteSubId();
+
+ HashMap<Integer, Pair<Integer, Integer>> unavailableReasons;
+ if (mSatelliteController.isSatelliteServiceSupportedByCarrier(
+ subId, NetworkRegistrationInfo.SERVICE_TYPE_SMS)) {
+ unavailableReasons = SATELLITE_MESSAGING_UNAVAILABLE_REASONS;
+ } else {
+ unavailableReasons = SATELLITE_SOS_UNAVAILABLE_REASONS;
+ }
+
+ for (int reason : unavailableReasons.keySet()) {
+ Pair<Integer, Integer> notificationString =
+ unavailableReasons.getOrDefault(reason, null);
+ if (notificationString != null) {
+ mSatelliteUnAvailableNotifications.put(reason,
+ createNotification(
+ context,
+ context.getResources().getString(notificationString.first),
+ context.getResources().getString(notificationString.second)));
+ }
+ }
+ }
+
+ private final BroadcastReceiver mDefaultSmsAppChangedBroadcastReceiver =
+ new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (intent.getAction()
+ .equals(Intent.ACTION_PACKAGE_CHANGED)) {
+ boolean isDefaultMsgAppSupported = false;
+ ComponentName componentName =
+ SmsApplication.getDefaultSmsApplicationAsUser(
+ context, true, context.getUser());
+ logd("Current default SMS app:" + componentName);
+ if (componentName != null) {
+ String packageName = componentName.getPackageName();
+ List<String> supportedMsgApps =
+ mSatelliteController.getSatelliteSupportedMsgApps(
+ mSatelliteController.getSelectedSatelliteSubId());
+ if (supportedMsgApps.contains(packageName)) {
+ isDefaultMsgAppSupported = true;
+ }
+ } else {
+ logd("No default SMS app");
+ }
+
+ if (isDefaultMsgAppSupported) {
+ if (mSatelliteDisallowedReasons.contains(Integer.valueOf(
+ SATELLITE_DISALLOWED_REASON_UNSUPPORTED_DEFAULT_MSG_APP))) {
+ mSatelliteDisallowedReasons.remove(Integer.valueOf(
+ SATELLITE_DISALLOWED_REASON_UNSUPPORTED_DEFAULT_MSG_APP));
+ handleEventDisallowedReasonsChanged();
+ }
+ } else {
+ if (!mSatelliteDisallowedReasons.contains(Integer.valueOf(
+ SATELLITE_DISALLOWED_REASON_UNSUPPORTED_DEFAULT_MSG_APP))) {
+ mSatelliteDisallowedReasons.add(Integer.valueOf(
+ SATELLITE_DISALLOWED_REASON_UNSUPPORTED_DEFAULT_MSG_APP));
+ handleEventDisallowedReasonsChanged();
+ }
+ }
+ }
+ }
+ };
+
private void handleSatelliteAllowedRegionPossiblyChanged(int handleEvent) {
if (!mFeatureFlags.oemEnabledSatelliteFlag()) {
ploge("handleSatelliteAllowedRegionPossiblyChanged: "
@@ -1242,14 +1658,6 @@
private void executeLocationQuery() {
plogd("executeLocationQuery");
- synchronized (mPossibleChangeInSatelliteAllowedRegionLock) {
- if (isSatelliteAllowedRegionPossiblyChanged()) {
- mLastLocationQueryForPossibleChangeInAllowedRegionTimeNanos =
- getElapsedRealtimeNanos();
- plogd("mLastLocationQueryForPossibleChangeInAllowedRegionTimeNanos is set "
- + mLastLocationQueryForPossibleChangeInAllowedRegionTimeNanos);
- }
- }
synchronized (mLock) {
mFreshLastKnownLocation = getFreshLastKnownLocation();
checkSatelliteAccessRestrictionUsingOnDeviceData();
@@ -1321,6 +1729,16 @@
+ "Request for current location was already sent to LocationManager");
return;
}
+
+ synchronized (mPossibleChangeInSatelliteAllowedRegionLock) {
+ if (isSatelliteAllowedRegionPossiblyChanged()) {
+ mLastLocationQueryForPossibleChangeInAllowedRegionTimeNanos =
+ getElapsedRealtimeNanos();
+ plogd("mLastLocationQueryForPossibleChangeInAllowedRegionTimeNanos is set "
+ + mLastLocationQueryForPossibleChangeInAllowedRegionTimeNanos);
+ }
+ }
+
mLocationRequestCancellationSignal = new CancellationSignal();
mLocationQueryStartTimeMillis = System.currentTimeMillis();
mLocationManager.getCurrentLocation(LocationManager.FUSED_PROVIDER,
@@ -1372,7 +1790,7 @@
}
}
- private void checkSatelliteAccessRestrictionForLocation(@NonNull Location location) {
+ protected void checkSatelliteAccessRestrictionForLocation(@NonNull Location location) {
synchronized (mLock) {
try {
SatelliteOnDeviceAccessController.LocationToken locationToken =
@@ -1380,8 +1798,11 @@
location.getLatitude(),
location.getLongitude(), mS2Level);
boolean satelliteAllowed;
+
if (mCachedAccessRestrictionMap.containsKey(locationToken)) {
- satelliteAllowed = mCachedAccessRestrictionMap.get(locationToken);
+ mNewRegionalConfigId = mCachedAccessRestrictionMap.get(locationToken);
+ satelliteAllowed = (mNewRegionalConfigId != null);
+ plogd("mNewRegionalConfigId is " + mNewRegionalConfigId);
} else {
if (!initSatelliteOnDeviceAccessController()) {
ploge("Failed to init SatelliteOnDeviceAccessController");
@@ -1391,9 +1812,23 @@
false);
return;
}
- satelliteAllowed = mSatelliteOnDeviceAccessController
- .isSatCommunicationAllowedAtLocation(locationToken);
- updateCachedAccessRestrictionMap(locationToken, satelliteAllowed);
+
+ if (mFeatureFlags.carrierRoamingNbIotNtn()) {
+ synchronized (mLock) {
+ mNewRegionalConfigId = mSatelliteOnDeviceAccessController
+ .getRegionalConfigIdForLocation(locationToken);
+ plogd("mNewRegionalConfigId is " + mNewRegionalConfigId);
+ satelliteAllowed = (mNewRegionalConfigId != null);
+ }
+ } else {
+ plogd("checkSatelliteAccessRestrictionForLocation: "
+ + "carrierRoamingNbIotNtn is disabled");
+ satelliteAllowed = mSatelliteOnDeviceAccessController
+ .isSatCommunicationAllowedAtLocation(locationToken);
+ mNewRegionalConfigId =
+ satelliteAllowed ? UNKNOWN_REGIONAL_SATELLITE_CONFIG_ID : null;
+ }
+ updateCachedAccessRestrictionMap(locationToken, mNewRegionalConfigId);
}
mAccessControllerMetricsStats.setOnDeviceLookupTime(mOnDeviceLookupStartTimeMillis);
Bundle bundle = new Bundle();
@@ -1422,11 +1857,23 @@
}
}
+ private void updateRegionalConfigId() {
+ synchronized (mLock) {
+ plogd("mNewRegionalConfigId: updatedValue = " + mNewRegionalConfigId
+ + " | mRegionalConfigId: beforeValue = " + mRegionalConfigId);
+ if (!Objects.equals(mRegionalConfigId, mNewRegionalConfigId)) {
+ mRegionalConfigId = mNewRegionalConfigId;
+ notifyRegionalSatelliteConfigurationChanged(
+ mSatelliteAccessConfigMap.get(mRegionalConfigId));
+ }
+ }
+ }
+
private void updateCachedAccessRestrictionMap(
@NonNull SatelliteOnDeviceAccessController.LocationToken locationToken,
- boolean satelliteAllowed) {
+ Integer regionalConfigId) {
synchronized (mLock) {
- mCachedAccessRestrictionMap.put(locationToken, satelliteAllowed);
+ mCachedAccessRestrictionMap.put(locationToken, regionalConfigId);
}
}
@@ -1580,7 +2027,8 @@
try {
mSatelliteOnDeviceAccessController =
- SatelliteOnDeviceAccessController.create(getSatelliteS2CellFile());
+ SatelliteOnDeviceAccessController.create(
+ getSatelliteS2CellFile(), mFeatureFlags);
restartKeepOnDeviceAccessControllerResourcesTimer();
mS2Level = mSatelliteOnDeviceAccessController.getS2Level();
plogd("mS2Level=" + mS2Level);
@@ -1864,6 +2312,14 @@
logd("registerForCommunicationAllowedStateChanged: "
+ "mCurrentSatelliteAllowedState " + mCurrentSatelliteAllowedState);
}
+ synchronized (mLock) {
+ SatelliteAccessConfiguration satelliteAccessConfig =
+ mSatelliteAccessConfigMap.get(mRegionalConfigId);
+ callback.onSatelliteAccessConfigurationChanged(satelliteAccessConfig);
+ logd("registerForCommunicationAllowedStateChanged: satelliteAccessConfig: "
+ + satelliteAccessConfig + " of mRegionalConfigId: "
+ + mRegionalConfigId);
+ }
} catch (RemoteException ex) {
ploge("registerForCommunicationAllowedStateChanged: RemoteException ex=" + ex);
}
@@ -1894,6 +2350,74 @@
}
/**
+ * Returns integer array of disallowed reasons of satellite.
+ *
+ * @return Integer array of disallowed reasons of satellite.
+ *
+ */
+ @NonNull public List<Integer> getSatelliteDisallowedReasons() {
+ if (!mFeatureFlags.carrierRoamingNbIotNtn()) {
+ plogd("getSatelliteDisallowedReasons: carrierRoamingNbIotNtn is disabled");
+ return new ArrayList<>();
+ }
+
+ synchronized (mSatelliteDisallowedReasonsLock) {
+ return mSatelliteDisallowedReasons;
+ }
+ }
+
+ /**
+ * Registers for disallowed reasons change event from satellite service.
+ *
+ * @param callback The callback to handle disallowed reasons changed event.
+ *
+ */
+ public void registerForSatelliteDisallowedReasonsChanged(
+ @NonNull ISatelliteDisallowedReasonsCallback callback) {
+ if (!mFeatureFlags.carrierRoamingNbIotNtn()) {
+ plogd("registerForSatelliteDisallowedReasonsChanged: carrierRoamingNbIotNtn is "
+ + "disabled");
+ return;
+ }
+
+ mSatelliteDisallowedReasonsChangedListeners.put(callback.asBinder(), callback);
+
+ this.post(() -> {
+ try {
+ synchronized (mSatelliteDisallowedReasonsLock) {
+ callback.onSatelliteDisallowedReasonsChanged(
+ mSatelliteDisallowedReasons.stream()
+ .mapToInt(Integer::intValue)
+ .toArray());
+ logd("registerForSatelliteDisallowedReasonsChanged: "
+ + "mSatelliteDisallowedReasons " + mSatelliteDisallowedReasons.size());
+ }
+ } catch (RemoteException ex) {
+ ploge("registerForSatelliteDisallowedReasonsChanged: RemoteException ex=" + ex);
+ }
+ });
+ }
+
+ /**
+ * Unregisters for disallowed reasons change event from satellite service.
+ * If callback was not registered before, the request will be ignored.
+ *
+ * @param callback The callback that was passed to
+ * {@link #registerForSatelliteDisallowedReasonsChanged(
+ * ISatelliteDisallowedReasonsCallback)}.
+ */
+ public void unregisterForSatelliteDisallowedReasonsChanged(
+ @NonNull ISatelliteDisallowedReasonsCallback callback) {
+ if (!mFeatureFlags.carrierRoamingNbIotNtn()) {
+ plogd("unregisterForSatelliteDisallowedReasonsChanged: "
+ + "carrierRoamingNbIotNtn is disabled");
+ return;
+ }
+
+ mSatelliteDisallowedReasonsChangedListeners.remove(callback.asBinder());
+ }
+
+ /**
* This API can be used by only CTS to set the cache whether satellite communication is allowed.
*
* @param state a state indicates whether satellite access allowed state should be cached and
@@ -1920,6 +2444,10 @@
mLatestSatelliteCommunicationAllowedSetTime = getElapsedRealtimeNanos();
mLatestSatelliteCommunicationAllowed = true;
mCurrentSatelliteAllowedState = true;
+ } else if ("cache_not_allowed".equalsIgnoreCase(state)) {
+ mLatestSatelliteCommunicationAllowedSetTime = getElapsedRealtimeNanos();
+ mLatestSatelliteCommunicationAllowed = false;
+ mCurrentSatelliteAllowedState = false;
} else if ("cache_clear_and_not_allowed".equalsIgnoreCase(state)) {
mLatestSatelliteCommunicationAllowedSetTime = 0;
mLatestSatelliteCommunicationAllowed = false;
@@ -1955,6 +2483,45 @@
});
}
+ private void notifySatelliteDisallowedReasonsChanged() {
+ plogd("notifySatelliteDisallowedReasonsChanged");
+
+ List<ISatelliteDisallowedReasonsCallback> deadCallersList = new ArrayList<>();
+ mSatelliteDisallowedReasonsChangedListeners.values().forEach(listener -> {
+ try {
+ listener.onSatelliteDisallowedReasonsChanged(
+ mSatelliteDisallowedReasons.stream()
+ .mapToInt(Integer::intValue)
+ .toArray());
+ } catch (RemoteException e) {
+ plogd("notifySatelliteDisallowedReasonsChanged RemoteException: " + e);
+ deadCallersList.add(listener);
+ }
+ });
+ deadCallersList.forEach(listener -> {
+ mSatelliteDisallowedReasonsChangedListeners.remove(listener.asBinder());
+ });
+ }
+
+ protected void notifyRegionalSatelliteConfigurationChanged(
+ @Nullable SatelliteAccessConfiguration satelliteAccessConfig) {
+ plogd("notifyRegionalSatelliteConfigurationChanged : satelliteAccessConfig is "
+ + satelliteAccessConfig);
+
+ List<ISatelliteCommunicationAllowedStateCallback> deadCallersList = new ArrayList<>();
+ mSatelliteCommunicationAllowedStateChangedListeners.values().forEach(listener -> {
+ try {
+ listener.onSatelliteAccessConfigurationChanged(satelliteAccessConfig);
+ } catch (RemoteException e) {
+ plogd("handleEventNtnSignalStrengthChanged RemoteException: " + e);
+ deadCallersList.add(listener);
+ }
+ });
+ deadCallersList.forEach(listener -> {
+ mSatelliteCommunicationAllowedStateChangedListeners.remove(listener.asBinder());
+ });
+ }
+
private void reportMetrics(int resultCode, boolean allowed) {
if (resultCode == SATELLITE_RESULT_SUCCESS) {
mControllerMetricsStats.reportAllowedSatelliteAccessCount(allowed);
@@ -2016,6 +2583,32 @@
}
}
+ /**
+ * This API can be used only for test purpose to override the carrier roaming Ntn eligibility
+ *
+ * @param state to update Ntn Eligibility.
+ * @param resetRequired to reset the overridden flag in satellite controller.
+ * @return {@code true} if the shell command is successful, {@code false} otherwise.
+ */
+ public boolean overrideCarrierRoamingNtnEligibilityChanged(boolean state,
+ boolean resetRequired) {
+ if (!mFeatureFlags.carrierRoamingNbIotNtn()) {
+ logd("overrideCarrierRoamingNtnEligibilityChanged: "
+ + "carrierRoamingNbIotNtn is disabled");
+ return false;
+ }
+
+ if (!isMockModemAllowed()) {
+ logd("overrideCarrierRoamingNtnEligibilityChanged: "
+ + "mock modem not allowed.");
+ return false;
+ }
+
+ logd("calling overrideCarrierRoamingNtnEligibilityChanged");
+ return mSatelliteController.overrideCarrierRoamingNtnEligibilityChanged(state,
+ resetRequired);
+ }
+
private void plogv(@NonNull String log) {
Rlog.v(TAG, log);
if (mPersistentLogger != null) {
diff --git a/src/com/android/phone/satellite/accesscontrol/SatelliteOnDeviceAccessController.java b/src/com/android/phone/satellite/accesscontrol/SatelliteOnDeviceAccessController.java
index 520699f..2d7cf96 100644
--- a/src/com/android/phone/satellite/accesscontrol/SatelliteOnDeviceAccessController.java
+++ b/src/com/android/phone/satellite/accesscontrol/SatelliteOnDeviceAccessController.java
@@ -16,6 +16,9 @@
package com.android.phone.satellite.accesscontrol;
import android.annotation.NonNull;
+import android.annotation.Nullable;
+
+import com.android.internal.telephony.flags.FeatureFlags;
import java.io.Closeable;
import java.io.File;
@@ -34,13 +37,15 @@
* but at the cost of some memory, or close it immediately after a single use.
*
* @param file The input file that contains the location-based access restriction information.
- * @throws IOException in the unlikely event of errors when reading underlying file(s)
+ * @throws IOException in the unlikely event of errors when reading underlying
+ * file(s)
* @throws IllegalArgumentException if the input file format does not match the format defined
- * by the device overlay configs.
+ * by the device overlay configs.
*/
public static SatelliteOnDeviceAccessController create(
- @NonNull File file) throws IOException, IllegalArgumentException {
- return S2RangeSatelliteOnDeviceAccessController.create(file);
+ @NonNull File file, @NonNull FeatureFlags featureFlags)
+ throws IOException, IllegalArgumentException {
+ return S2RangeSatelliteOnDeviceAccessController.create(file, featureFlags);
}
/**
@@ -83,4 +88,14 @@
/** This will print out the location information */
public abstract String toPiiString();
}
+
+ /**
+ * Returns an unsigned integer if a regional access control config ID is found for the current
+ * location, {@code null} otherwise.
+ *
+ * @throws IOException in the unlikely event of errors when reading the underlying file
+ */
+ @Nullable
+ public abstract Integer getRegionalConfigIdForLocation(LocationToken locationToken)
+ throws IOException;
}
diff --git a/src/com/android/phone/settings/RadioInfo.java b/src/com/android/phone/settings/RadioInfo.java
index 24d680c..4d98d92 100644
--- a/src/com/android/phone/settings/RadioInfo.java
+++ b/src/com/android/phone/settings/RadioInfo.java
@@ -85,7 +85,6 @@
import android.telephony.ims.ProvisioningManager;
import android.telephony.ims.feature.MmTelFeature;
import android.telephony.ims.stub.ImsRegistrationImplBase;
-import android.telephony.satellite.EnableRequestAttributes;
import android.telephony.satellite.SatelliteManager;
import android.text.TextUtils;
import android.util.Log;
@@ -368,7 +367,7 @@
private String mActionEsos;
private String mActionEsosDemo;
-
+ private Intent mNonEsosIntent;
private TelephonyDisplayInfo mDisplayInfo;
private List<PhysicalChannelConfig> mPhysicalChannelConfigs = new ArrayList<>();
@@ -786,33 +785,33 @@
mEsosDemoButton = (Button) findViewById(R.id.demo_esos_questionnaire);
mSatelliteEnableNonEmergencyModeButton = (Button) findViewById(
R.id.satellite_enable_non_emergency_mode);
- CarrierConfigManager cm = getSystemService(CarrierConfigManager.class);
- if (!cm.getConfigForSubId(mSubId,
- CarrierConfigManager.KEY_SATELLITE_ATTACH_SUPPORTED_BOOL)
- .getBoolean(CarrierConfigManager.KEY_SATELLITE_ATTACH_SUPPORTED_BOOL)) {
- mSatelliteEnableNonEmergencyModeButton.setVisibility(View.GONE);
- }
- if (!Build.isDebuggable()) {
- if (!TextUtils.isEmpty(mActionEsos)) {
- mEsosButton.setVisibility(View.GONE);
- }
- if (!TextUtils.isEmpty(mActionEsosDemo)) {
- mEsosDemoButton.setVisibility(View.GONE);
- }
- mSatelliteEnableNonEmergencyModeButton.setVisibility(View.GONE);
+
+ if (shouldHideButton(mActionEsos)) {
+ mEsosButton.setVisibility(View.GONE);
} else {
mEsosButton.setOnClickListener(v -> startActivityAsUser(
new Intent(mActionEsos).addFlags(
Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK),
UserHandle.CURRENT)
);
+ }
+ if (shouldHideButton(mActionEsosDemo)) {
+ mEsosDemoButton.setVisibility(View.GONE);
+ } else {
mEsosDemoButton.setOnClickListener(v -> startActivityAsUser(
new Intent(mActionEsosDemo).addFlags(
Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK),
UserHandle.CURRENT)
);
- mSatelliteEnableNonEmergencyModeButton.setOnClickListener(v ->
- enableSatelliteNonEmergencyMode());
+ }
+ if (shouldHideNonEmergencyMode()) {
+ mSatelliteEnableNonEmergencyModeButton.setVisibility(View.GONE);
+ } else {
+ mSatelliteEnableNonEmergencyModeButton.setOnClickListener(v -> {
+ if (mNonEsosIntent != null) {
+ sendBroadcast(mNonEsosIntent);
+ }
+ });
}
mOemInfoButton = (Button) findViewById(R.id.oem_info);
@@ -836,6 +835,21 @@
restoreFromBundle(icicle);
}
+ boolean shouldHideButton(String action) {
+ if (!Build.isDebuggable()) {
+ return true;
+ }
+ if (TextUtils.isEmpty(action)) {
+ return true;
+ }
+ PackageManager pm = getPackageManager();
+ Intent intent = new Intent(action);
+ if (pm.resolveActivity(intent, 0) == null) {
+ return true;
+ }
+ return false;
+ }
+
@Override
public Intent getParentActivityIntent() {
Intent parentActivity = super.getParentActivityIntent();
@@ -1411,7 +1425,9 @@
}
private void updateNetworkType() {
- if (SubscriptionManager.isValidPhoneId(mPhoneId)) {
+ SubscriptionManager mSm = getSystemService(SubscriptionManager.class);
+ if (SubscriptionManager.isValidPhoneId(mPhoneId)
+ && mSm.isActiveSubscriptionId(mSubId)) {
mDataNetwork.setText(ServiceState.rilRadioTechnologyToString(
mTelephonyManager.getServiceStateForSlot(mPhoneId)
.getRilDataRadioTechnology()));
@@ -2138,27 +2154,68 @@
}
};
- /**
- * Enable modem satellite for non-emergency mode.
- */
- private void enableSatelliteNonEmergencyMode() {
- SatelliteManager sm = getSystemService(SatelliteManager.class);
+ private boolean shouldHideNonEmergencyMode() {
+ if (!Build.isDebuggable()) {
+ return true;
+ }
+ String action = SatelliteManager.ACTION_SATELLITE_START_NON_EMERGENCY_SESSION;
+ if (TextUtils.isEmpty(action)) {
+ return true;
+ }
+ if (mNonEsosIntent != null) {
+ mNonEsosIntent = null;
+ }
CarrierConfigManager cm = getSystemService(CarrierConfigManager.class);
- if (sm == null || cm == null) {
- loge("enableSatelliteNonEmergencyMode: sm or cm is null");
- return;
+ if (cm == null) {
+ loge("shouldHideNonEmergencyMode: cm is null");
+ return true;
}
- if (!cm.getConfigForSubId(mSubId,
- CarrierConfigManager.KEY_SATELLITE_ATTACH_SUPPORTED_BOOL)
- .getBoolean(CarrierConfigManager.KEY_SATELLITE_ATTACH_SUPPORTED_BOOL)) {
- loge("enableSatelliteNonEmergencyMode: KEY_SATELLITE_ATTACH_SUPPORTED_BOOL is false");
- return;
+ PersistableBundle bundle = cm.getConfigForSubId(mSubId,
+ CarrierConfigManager.KEY_SATELLITE_ATTACH_SUPPORTED_BOOL,
+ CarrierConfigManager.KEY_SATELLITE_ESOS_SUPPORTED_BOOL);
+ if (!bundle.getBoolean(
+ CarrierConfigManager.KEY_SATELLITE_ESOS_SUPPORTED_BOOL, false)) {
+ log("shouldHideNonEmergencyMode: esos_supported false");
+ return true;
}
- log("enableSatelliteNonEmergencyMode: requestEnabled");
- sm.requestEnabled(new EnableRequestAttributes.Builder(true)
- .setDemoMode(false).setEmergencyMode(false).build(),
- Runnable::run, res -> log("enableSatelliteNonEmergencyMode: " + res)
- );
+ if (!bundle.getBoolean(
+ CarrierConfigManager.KEY_SATELLITE_ATTACH_SUPPORTED_BOOL, false)) {
+ log("shouldHideNonEmergencyMode: attach_supported false");
+ return true;
+ }
+
+ String packageName = getStringFromOverlayConfig(
+ com.android.internal.R.string.config_satellite_gateway_service_package);
+
+ String className = getStringFromOverlayConfig(com.android.internal.R.string
+ .config_satellite_carrier_roaming_non_emergency_session_class);
+ if (packageName == null || className == null
+ || packageName.isEmpty() || className.isEmpty()) {
+ Log.d(TAG, "shouldHideNonEmergencyMode:"
+ + " packageName or className is null or empty.");
+ return true;
+ }
+ PackageManager pm = getPackageManager();
+ Intent intent = new Intent(action);
+ intent.setComponent(new ComponentName(packageName, className));
+ if (pm.queryBroadcastReceivers(intent, 0).isEmpty()) {
+ Log.d(TAG, "shouldHideNonEmergencyMode: Broadcast receiver not found for intent: "
+ + intent);
+ return true;
+ }
+ mNonEsosIntent = intent;
+ return false;
+ }
+
+ private String getStringFromOverlayConfig(int resourceId) {
+ String name;
+ try {
+ name = getResources().getString(resourceId);
+ } catch (Resources.NotFoundException ex) {
+ loge("getStringFromOverlayConfig: ex=" + ex);
+ name = null;
+ }
+ return name;
}
private boolean isImsVolteProvisioned() {
diff --git a/src/com/android/services/telephony/DisconnectCauseUtil.java b/src/com/android/services/telephony/DisconnectCauseUtil.java
index 48786dc..e753e20 100644
--- a/src/com/android/services/telephony/DisconnectCauseUtil.java
+++ b/src/com/android/services/telephony/DisconnectCauseUtil.java
@@ -1046,7 +1046,7 @@
}
private static Integer getSatelliteErrorString() {
- if (SatelliteController.getInstance().isSatelliteEnabled()) {
+ if (SatelliteController.getInstance().isSatelliteEnabledOrBeingEnabled()) {
return R.string.incall_error_satellite_enabled;
}
return R.string.incall_error_carrier_roaming_satellite_mode;
diff --git a/src/com/android/services/telephony/ImsConference.java b/src/com/android/services/telephony/ImsConference.java
index 7f0c800..af1ddb6 100644
--- a/src/com/android/services/telephony/ImsConference.java
+++ b/src/com/android/services/telephony/ImsConference.java
@@ -430,9 +430,9 @@
super(phoneAccountHandle);
- mTelecomAccountRegistry = telecomAccountRegistry;
- mFeatureFlagProxy = featureFlagProxy;
- mCarrierConfig = carrierConfig;
+ mTelecomAccountRegistry = Objects.requireNonNull(telecomAccountRegistry);
+ mFeatureFlagProxy = Objects.requireNonNull(featureFlagProxy);
+ mCarrierConfig = Objects.requireNonNull(carrierConfig);
// Specify the connection time of the conference to be the connection time of the original
// connection.
diff --git a/src/com/android/services/telephony/ImsConferenceController.java b/src/com/android/services/telephony/ImsConferenceController.java
index fa2151b..ca3bcfe 100644
--- a/src/com/android/services/telephony/ImsConferenceController.java
+++ b/src/com/android/services/telephony/ImsConferenceController.java
@@ -142,9 +142,9 @@
public ImsConferenceController(TelecomAccountRegistry telecomAccountRegistry,
TelephonyConnectionServiceProxy connectionService,
ImsConference.FeatureFlagProxy featureFlagProxy) {
- mConnectionService = connectionService;
- mTelecomAccountRegistry = telecomAccountRegistry;
- mFeatureFlagProxy = featureFlagProxy;
+ mConnectionService = Objects.requireNonNull(connectionService);
+ mTelecomAccountRegistry = Objects.requireNonNull(telecomAccountRegistry);
+ mFeatureFlagProxy = Objects.requireNonNull(featureFlagProxy);
}
void addConference(ImsConference conference) {
diff --git a/src/com/android/services/telephony/TelecomAccountRegistry.java b/src/com/android/services/telephony/TelecomAccountRegistry.java
index c39d121..8956266 100644
--- a/src/com/android/services/telephony/TelecomAccountRegistry.java
+++ b/src/com/android/services/telephony/TelecomAccountRegistry.java
@@ -70,6 +70,7 @@
import com.android.internal.telephony.flags.Flags;
import com.android.internal.telephony.subscription.SubscriptionManagerService;
import com.android.phone.PhoneGlobals;
+import com.android.phone.PhoneInterfaceManager;
import com.android.phone.PhoneUtils;
import com.android.phone.R;
import com.android.telephony.Rlog;
@@ -434,7 +435,7 @@
boolean isVideoEnabledByPlatform = ImsManager.getInstance(mPhone.getContext(),
mPhone.getPhoneId()).isVtEnabledByPlatform();
- if (!mIsPrimaryUser) {
+ if (!mDoesUserSupportVideoCalling) {
Log.i(this, "Disabling video calling for secondary user.");
mIsVideoCapable = false;
isVideoEnabledByPlatform = false;
@@ -651,8 +652,8 @@
// Check if IMS video pause is supported.
PersistableBundle b =
PhoneGlobals.getInstance().getCarrierConfigForSubId(mPhone.getSubId());
- return b != null &&
- b.getBoolean(CarrierConfigManager.KEY_SUPPORT_PAUSE_IMS_VIDEO_CALLS_BOOL);
+ if (b == null) return false;
+ return b.getBoolean(CarrierConfigManager.KEY_SUPPORT_PAUSE_IMS_VIDEO_CALLS_BOOL);
}
/**
@@ -697,8 +698,8 @@
private boolean isCarrierInstantLetteringSupported() {
PersistableBundle b =
PhoneGlobals.getInstance().getCarrierConfigForSubId(mPhone.getSubId());
- return b != null &&
- b.getBoolean(CarrierConfigManager.KEY_CARRIER_INSTANT_LETTERING_AVAILABLE_BOOL);
+ if (b == null) return false;
+ return b.getBoolean(CarrierConfigManager.KEY_CARRIER_INSTANT_LETTERING_AVAILABLE_BOOL);
}
/**
@@ -709,8 +710,8 @@
private boolean isCarrierAdhocConferenceCallSupported() {
PersistableBundle b =
PhoneGlobals.getInstance().getCarrierConfigForSubId(mPhone.getSubId());
- return b != null &&
- b.getBoolean(CarrierConfigManager.KEY_SUPPORT_ADHOC_CONFERENCE_CALLS_BOOL);
+ if (b == null) return false;
+ return b.getBoolean(CarrierConfigManager.KEY_SUPPORT_ADHOC_CONFERENCE_CALLS_BOOL);
}
@@ -722,8 +723,8 @@
private boolean isCarrierMergeCallSupported() {
PersistableBundle b =
PhoneGlobals.getInstance().getCarrierConfigForSubId(mPhone.getSubId());
- return b != null &&
- b.getBoolean(CarrierConfigManager.KEY_SUPPORT_CONFERENCE_CALL_BOOL);
+ if (b == null) return false;
+ return b.getBoolean(CarrierConfigManager.KEY_SUPPORT_CONFERENCE_CALL_BOOL);
}
/**
@@ -734,6 +735,7 @@
private boolean isCarrierMergeImsCallSupported() {
PersistableBundle b =
PhoneGlobals.getInstance().getCarrierConfigForSubId(mPhone.getSubId());
+ if (b == null) return false;
return b.getBoolean(CarrierConfigManager.KEY_SUPPORT_IMS_CONFERENCE_CALL_BOOL);
}
@@ -745,8 +747,8 @@
private boolean isCarrierEmergencyVideoCallsAllowed() {
PersistableBundle b =
PhoneGlobals.getInstance().getCarrierConfigForSubId(mPhone.getSubId());
- return b != null &&
- b.getBoolean(CarrierConfigManager.KEY_ALLOW_EMERGENCY_VIDEO_CALLS_BOOL);
+ if (b == null) return false;
+ return b.getBoolean(CarrierConfigManager.KEY_ALLOW_EMERGENCY_VIDEO_CALLS_BOOL);
}
/**
@@ -757,8 +759,8 @@
private boolean isCarrierVideoConferencingSupported() {
PersistableBundle b =
PhoneGlobals.getInstance().getCarrierConfigForSubId(mPhone.getSubId());
- return b != null &&
- b.getBoolean(CarrierConfigManager.KEY_SUPPORT_VIDEO_CONFERENCE_CALL_BOOL);
+ if (b == null) return false;
+ return b.getBoolean(CarrierConfigManager.KEY_SUPPORT_VIDEO_CONFERENCE_CALL_BOOL);
}
/**
@@ -771,7 +773,8 @@
private boolean isCarrierMergeOfWifiCallsAllowedWhenVoWifiOff() {
PersistableBundle b =
PhoneGlobals.getInstance().getCarrierConfigForSubId(mPhone.getSubId());
- return b != null && b.getBoolean(
+ if (b == null) return false;
+ return b.getBoolean(
CarrierConfigManager.KEY_ALLOW_MERGE_WIFI_CALLS_WHEN_VOWIFI_OFF_BOOL);
}
@@ -784,6 +787,7 @@
private boolean isCarrierManageImsConferenceCallSupported() {
PersistableBundle b =
PhoneGlobals.getInstance().getCarrierConfigForSubId(mPhone.getSubId());
+ if (b == null) return false;
return b.getBoolean(CarrierConfigManager.KEY_SUPPORT_MANAGE_IMS_CONFERENCE_CALL_BOOL);
}
@@ -796,6 +800,7 @@
private boolean isCarrierUsingSimCallManager() {
PersistableBundle b =
PhoneGlobals.getInstance().getCarrierConfigForSubId(mPhone.getSubId());
+ if (b == null) return false;
return !TextUtils.isEmpty(
b.getString(CarrierConfigManager.KEY_DEFAULT_SIM_CALL_MANAGER_STRING));
}
@@ -810,6 +815,7 @@
private boolean isCarrierShowPreciseFailedCause() {
PersistableBundle b =
PhoneGlobals.getInstance().getCarrierConfigForSubId(mPhone.getSubId());
+ if (b == null) return false;
return b.getBoolean(CarrierConfigManager.KEY_SHOW_PRECISE_FAILED_CAUSE_BOOL);
}
@@ -822,6 +828,7 @@
private boolean isCarrierUseCallRecordingTone() {
PersistableBundle b =
PhoneGlobals.getInstance().getCarrierConfigForSubId(mPhone.getSubId());
+ if (b == null) return false;
return b.getBoolean(CarrierConfigManager.KEY_PLAY_CALL_RECORDING_TONE_BOOL);
}
@@ -831,6 +838,7 @@
private boolean isCarrierAllowRttWhenRoaming() {
PersistableBundle b =
PhoneGlobals.getInstance().getCarrierConfigForSubId(mPhone.getSubId());
+ if (b == null) return false;
return b.getBoolean(CarrierConfigManager.KEY_RTT_SUPPORTED_WHILE_ROAMING_BOOL);
}
@@ -843,6 +851,7 @@
private Bundle getPhoneAccountExtras() {
PersistableBundle b =
PhoneGlobals.getInstance().getCarrierConfigForSubId(mPhone.getSubId());
+ if (b == null) return new Bundle();
int instantLetteringMaxLength = b.getInt(
CarrierConfigManager.KEY_CARRIER_INSTANT_LETTERING_LENGTH_LIMIT_INT);
@@ -1054,8 +1063,10 @@
boolean hasVoiceAvailability = isImsVoiceAvailable();
- boolean isRttSupported = PhoneGlobals.getInstance().phoneMgr
- .isRttEnabled(mPhone.getSubId());
+ PhoneInterfaceManager phoneMgr = PhoneGlobals.getInstance()
+ .phoneMgr;
+ boolean isRttSupported = (phoneMgr != null) ?
+ phoneMgr.isRttEnabled(mPhone.getSubId()) : false;
boolean isRoaming = mTelephonyManager.isNetworkRoaming(mPhone.getSubId());
boolean isOnWfc = mPhone.getImsRegistrationTech()
@@ -1214,7 +1225,7 @@
Log.i(this, "TelecomAccountRegistry: User changed, re-registering phone accounts.");
UserHandle currentUser = intent.getParcelableExtra(Intent.EXTRA_USER);
- mIsPrimaryUser = currentUser == null ? true : currentUser.isSystem();
+ mDoesUserSupportVideoCalling = currentUser == null ? true : currentUser.isSystem();
// Any time the user changes, re-register the accounts.
tearDownAccounts();
@@ -1287,7 +1298,8 @@
private int mSubscriptionListenerState = LISTENER_STATE_UNREGISTERED;
private int mServiceState = ServiceState.STATE_POWER_OFF;
private int mActiveDataSubscriptionId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
- private boolean mIsPrimaryUser = UserHandle.of(ActivityManager.getCurrentUser()).isSystem();
+ private boolean mDoesUserSupportVideoCalling =
+ UserHandle.of(ActivityManager.getCurrentUser()).isSystem();
private ExponentialBackoff mRegisterSubscriptionListenerBackoff;
private ExponentialBackoff mTelecomReadyBackoff;
private final HandlerThread mHandlerThread = new HandlerThread("TelecomAccountRegistry");
diff --git a/src/com/android/services/telephony/TelephonyConnectionService.java b/src/com/android/services/telephony/TelephonyConnectionService.java
index 3280c04..c69880d 100644
--- a/src/com/android/services/telephony/TelephonyConnectionService.java
+++ b/src/com/android/services/telephony/TelephonyConnectionService.java
@@ -1185,8 +1185,7 @@
boolean needToTurnOnRadio = (isEmergencyNumber && (!isRadioOn() || isAirplaneModeOn))
|| (isRadioPowerDownOnBluetooth() && !isPhoneWifiCallingEnabled);
- if (mSatelliteController.isSatelliteEnabled()
- || mSatelliteController.isSatelliteBeingEnabled()) {
+ if (mSatelliteController.isSatelliteEnabledOrBeingEnabled()) {
Log.d(this, "onCreateOutgoingConnection, "
+ " needToTurnOnRadio=" + needToTurnOnRadio
+ " needToTurnOffSatellite=" + needToTurnOffSatellite
@@ -1203,20 +1202,17 @@
}
}
- boolean forNormalRoutingEmergencyCall = false;
if (mDomainSelectionResolver.isDomainSelectionSupported()) {
- if (isEmergencyNumber) {
- // Normal routing emergency number shall be handled by normal call domain selector.
- int routing = getEmergencyCallRouting(phone, number, needToTurnOnRadio);
- if (routing != EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL) {
- final Connection resultConnection =
- placeEmergencyConnection(phone,
- request, numberToDial, isTestEmergencyNumber,
- handle, needToTurnOnRadio, routing);
- if (resultConnection != null) return resultConnection;
- }
- forNormalRoutingEmergencyCall = true;
- Log.d(this, "onCreateOutgoingConnection, forNormalRoutingEmergencyCall");
+ // Normal routing emergency number shall be handled by normal call domain selector.
+ int routing = (isEmergencyNumber)
+ ? getEmergencyCallRouting(phone, number, needToTurnOnRadio)
+ : EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN;
+ if (isEmergencyNumber && routing != EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL) {
+ final Connection resultConnection =
+ placeEmergencyConnection(phone,
+ request, numberToDial, isTestEmergencyNumber,
+ handle, needToTurnOnRadio, routing);
+ if (resultConnection != null) return resultConnection;
}
}
@@ -1287,8 +1283,7 @@
// reporting the OUT_OF_SERVICE state.
return phone.getState() == PhoneConstants.State.OFFHOOK
|| (phone.getServiceStateTracker().isRadioOn()
- && (!mSatelliteController.isSatelliteEnabled()
- && !mSatelliteController.isSatelliteBeingEnabled()));
+ && !mSatelliteController.isSatelliteEnabledOrBeingEnabled());
} else {
SubscriptionInfoInternal subInfo = SubscriptionManagerService
.getInstance().getSubscriptionInfoInternal(phone.getSubId());
@@ -1305,7 +1300,7 @@
}
}
}, isEmergencyNumber && !isTestEmergencyNumber, phone, isTestEmergencyNumber,
- timeoutToOnTimeoutCallback, forNormalRoutingEmergencyCall);
+ timeoutToOnTimeoutCallback);
// Return the still unconnected GsmConnection and wait for the Radios to boot before
// connecting it to the underlying Phone.
return resultConnection;
@@ -2152,8 +2147,7 @@
}
private boolean shouldExitSatelliteModeForEmergencyCall(boolean isEmergencyNumber) {
- if (!mSatelliteController.isSatelliteEnabled()
- && !mSatelliteController.isSatelliteBeingEnabled()) {
+ if (!mSatelliteController.isSatelliteEnabledOrBeingEnabled()) {
return false;
}
@@ -2167,16 +2161,12 @@
return true;
} else { // satellite is for emergency
if (mFeatureFlags.carrierRoamingNbIotNtn()) {
- Phone satellitePhone = mSatelliteController.getSatellitePhone();
- if (satellitePhone == null) {
- loge("satellite is/being enabled, but satellitePhone is null");
- return false;
- }
+ int subId = mSatelliteController.getSelectedSatelliteSubId();
SubscriptionInfoInternal info = SubscriptionManagerService.getInstance()
- .getSubscriptionInfoInternal(satellitePhone.getSubId());
+ .getSubscriptionInfoInternal(subId);
if (info == null) {
loge("satellite is/being enabled, but satellite sub "
- + satellitePhone.getSubId() + " is null");
+ + subId + " is null");
return false;
}
@@ -4827,8 +4817,12 @@
mSatelliteSOSMessageRecommender = new SatelliteSOSMessageRecommender(phone.getContext(),
phone.getContext().getMainLooper());
}
+
+ String number = connection.getAddress().getSchemeSpecificPart();
+ final boolean isTestEmergencyNumber = isEmergencyNumberTestNumber(number);
+
connection.addTelephonyConnectionListener(mEmergencyConnectionSatelliteListener);
- mSatelliteSOSMessageRecommender.onEmergencyCallStarted(connection);
+ mSatelliteSOSMessageRecommender.onEmergencyCallStarted(connection, isTestEmergencyNumber);
mSatelliteSOSMessageRecommender.onEmergencyCallConnectionStateChanged(
connection.getTelecomCallId(), connection.STATE_DIALING);
}
diff --git a/src/com/android/services/telephony/domainselection/NormalCallDomainSelector.java b/src/com/android/services/telephony/domainselection/NormalCallDomainSelector.java
index 37813e3..a7ed708 100644
--- a/src/com/android/services/telephony/domainselection/NormalCallDomainSelector.java
+++ b/src/com/android/services/telephony/domainselection/NormalCallDomainSelector.java
@@ -140,7 +140,10 @@
if (subId == getSubId()) {
logd("NormalCallDomainSelection triggered. Sub-id:" + subId);
- sendEmptyMessageDelayed(MSG_WAIT_FOR_IMS_STATE_TIMEOUT, WAIT_FOR_IMS_STATE_TIMEOUT_MS);
+ if (!mReselectDomain) {
+ sendEmptyMessageDelayed(MSG_WAIT_FOR_IMS_STATE_TIMEOUT,
+ WAIT_FOR_IMS_STATE_TIMEOUT_MS);
+ }
post(() -> selectDomain());
} else {
mSelectorState = SelectorState.INACTIVE;
diff --git a/testapps/TestSatelliteApp/AndroidManifest.xml b/testapps/TestSatelliteApp/AndroidManifest.xml
index eaddf95..a1f22fa 100644
--- a/testapps/TestSatelliteApp/AndroidManifest.xml
+++ b/testapps/TestSatelliteApp/AndroidManifest.xml
@@ -20,6 +20,7 @@
<uses-permission android:name="android.permission.BIND_SATELLITE_SERVICE"/>
<uses-permission android:name="android.permission.SATELLITE_COMMUNICATION"/>
<uses-permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE"/>
+ <uses-permission android:name="android.permission.SEND_SMS"/>
<application android:label="SatelliteTestApp">
<activity android:name=".SatelliteTestApp"
android:label="SatelliteTestApp"
diff --git a/testapps/TestSatelliteApp/res/layout/activity_Datagram.xml b/testapps/TestSatelliteApp/res/layout/activity_Datagram.xml
index 9e53f41..ba61328 100644
--- a/testapps/TestSatelliteApp/res/layout/activity_Datagram.xml
+++ b/testapps/TestSatelliteApp/res/layout/activity_Datagram.xml
@@ -15,12 +15,14 @@
~ limitations under the License
-->
-<LinearLayout
+<ScrollView
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:paddingTop="10dp"
+ android:paddingBottom="10dp"
android:paddingLeft="4dp">
<LinearLayout
@@ -125,4 +127,4 @@
android:textColor="@android:color/holo_blue_light"
android:textSize="15dp" />
</LinearLayout>
-</LinearLayout>
+</ScrollView>
diff --git a/testapps/TestSatelliteApp/res/layout/activity_MultipleSendReceive.xml b/testapps/TestSatelliteApp/res/layout/activity_MultipleSendReceive.xml
index 3632ecb..c81eb3b 100644
--- a/testapps/TestSatelliteApp/res/layout/activity_MultipleSendReceive.xml
+++ b/testapps/TestSatelliteApp/res/layout/activity_MultipleSendReceive.xml
@@ -15,12 +15,14 @@
~ limitations under the License
-->
-<LinearLayout
+<ScrollView
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:paddingTop="10dp"
+ android:paddingBottom="10dp"
android:paddingLeft="4dp">
<LinearLayout
@@ -95,4 +97,4 @@
android:layout_centerVertical="true"
android:textSize="15dp" />
</LinearLayout>
-</LinearLayout>
+</ScrollView>
diff --git a/testapps/TestSatelliteApp/res/layout/activity_NbIotSatellite.xml b/testapps/TestSatelliteApp/res/layout/activity_NbIotSatellite.xml
index c33522e..fef4292 100644
--- a/testapps/TestSatelliteApp/res/layout/activity_NbIotSatellite.xml
+++ b/testapps/TestSatelliteApp/res/layout/activity_NbIotSatellite.xml
@@ -15,79 +15,86 @@
~ limitations under the License
-->
-<LinearLayout
+<ScrollView
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:paddingStart="4dp"
- android:paddingEnd="4dp">
+ android:paddingTop="10dp"
+ android:paddingBottom="10dp"
+ android:paddingLeft="4dp">
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="0dp"
- android:layout_weight="0"
- android:textColor="@android:color/holo_blue_dark"
- android:textSize="20sp"
- android:text="@string/NbIotSatellite"/>
- <Button
- android:id="@+id/testRegisterForSupportedStateChanged"
+ <LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:paddingStart="4dp"
- android:paddingEnd="4dp"
- android:text="@string/testRegisterForSupportedStateChanged"/>
- <Button
- android:id="@+id/testUnregisterForSupportedStateChanged"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:paddingStart="4dp"
- android:paddingEnd="4dp"
- android:text="@string/testUnregisterForSupportedStateChanged"/>
- <Button
- android:id="@+id/testRequestIsSupported"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:paddingStart="4dp"
- android:paddingEnd="4dp"
- android:text="@string/testRequestIsSupported"/>
- <Button
- android:id="@+id/reportSatelliteSupportedFromModem"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:paddingStart="4dp"
- android:paddingEnd="4dp"
- android:text="@string/reportSatelliteSupportedFromModem"/>
- <Button
- android:id="@+id/reportSatelliteNotSupportedFromModem"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:paddingStart="4dp"
- android:paddingEnd="4dp"
- android:text="@string/reportSatelliteNotSupportedFromModem"/>
- <Button
- android:id="@+id/showCurrentSatelliteSupportedStated"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:paddingStart="4dp"
- android:paddingEnd="4dp"
- android:text="@string/showCurrentSatelliteSupportedStated"/>
- <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:paddingStart="4dp"
- android:paddingEnd="4dp"
- android:text="@string/Back"/>
- <TextView
- android:id="@+id/text_id"
- android:layout_width="300dp"
- android:layout_height="200dp"
- android:textColor="@android:color/holo_blue_light"
- android:textSize="15sp" />
-</LinearLayout>
+ android:orientation="vertical">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="0dp"
+ android:layout_weight="0"
+ android:textColor="@android:color/holo_blue_dark"
+ android:textSize="20sp"
+ android:text="@string/NbIotSatellite"/>
+ <Button
+ android:id="@+id/testRegisterForSupportedStateChanged"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingStart="4dp"
+ android:paddingEnd="4dp"
+ android:text="@string/testRegisterForSupportedStateChanged"/>
+ <Button
+ android:id="@+id/testUnregisterForSupportedStateChanged"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingStart="4dp"
+ android:paddingEnd="4dp"
+ android:text="@string/testUnregisterForSupportedStateChanged"/>
+ <Button
+ android:id="@+id/testRequestIsSupported"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingStart="4dp"
+ android:paddingEnd="4dp"
+ android:text="@string/testRequestIsSupported"/>
+ <Button
+ android:id="@+id/reportSatelliteSupportedFromModem"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingStart="4dp"
+ android:paddingEnd="4dp"
+ android:text="@string/reportSatelliteSupportedFromModem"/>
+ <Button
+ android:id="@+id/reportSatelliteNotSupportedFromModem"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingStart="4dp"
+ android:paddingEnd="4dp"
+ android:text="@string/reportSatelliteNotSupportedFromModem"/>
+ <Button
+ android:id="@+id/showCurrentSatelliteSupportedStated"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingStart="4dp"
+ android:paddingEnd="4dp"
+ android:text="@string/showCurrentSatelliteSupportedStated"/>
+ <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:paddingStart="4dp"
+ android:paddingEnd="4dp"
+ android:text="@string/Back"/>
+ <TextView
+ android:id="@+id/text_id"
+ android:layout_width="300dp"
+ android:layout_height="200dp"
+ android:textColor="@android:color/holo_blue_light"
+ android:textSize="15sp" />
+ </LinearLayout>
+</ScrollView>
diff --git a/testapps/TestSatelliteApp/res/layout/activity_Provisioning.xml b/testapps/TestSatelliteApp/res/layout/activity_Provisioning.xml
index da5105d..afcc706 100644
--- a/testapps/TestSatelliteApp/res/layout/activity_Provisioning.xml
+++ b/testapps/TestSatelliteApp/res/layout/activity_Provisioning.xml
@@ -15,12 +15,14 @@
~ limitations under the License
-->
-<LinearLayout
+<ScrollView
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:paddingTop="10dp"
+ android:paddingBottom="10dp"
android:paddingLeft="4dp">
<LinearLayout
@@ -90,4 +92,4 @@
android:layout_centerVertical="true"
android:textSize="15dp" />
</LinearLayout>
-</LinearLayout>
+</ScrollView>
diff --git a/testapps/TestSatelliteApp/res/layout/activity_SatelliteControl.xml b/testapps/TestSatelliteApp/res/layout/activity_SatelliteControl.xml
index 151f6ca..23f6ee9 100644
--- a/testapps/TestSatelliteApp/res/layout/activity_SatelliteControl.xml
+++ b/testapps/TestSatelliteApp/res/layout/activity_SatelliteControl.xml
@@ -21,7 +21,8 @@
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center"
- android:paddingTop="100dp"
+ android:paddingTop="10dp"
+ android:paddingBottom="10dp"
android:paddingLeft="4dp">
<LinearLayout
@@ -37,11 +38,17 @@
android:textSize="20dp"
android:text="Satellite Control APIs"/>
<Button
- android:id="@+id/enableSatellite"
+ android:id="@+id/enableSatelliteDemoMode"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingRight="4dp"
- android:text="@string/enableSatellite"/>
+ android:text="@string/enableSatelliteDemoMode"/>
+ <Button
+ android:id="@+id/enableSatelliteRealMode"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingRight="4dp"
+ android:text="@string/enableSatelliteRealMode"/>
<Button
android:id="@+id/disableSatellite"
android:layout_width="match_parent"
@@ -138,6 +145,12 @@
android:layout_height="wrap_content"
android:paddingRight="4dp"
android:text="@string/provisionSatellite"/>
+ <Button
+ android:id="@+id/deprovisionSatellite"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingRight="4dp"
+ android:text="@string/deprovisionSatellite"/>
<Button
android:id="@+id/Back"
android:onClick="Back"
diff --git a/testapps/TestSatelliteApp/res/layout/activity_SatelliteTestApp.xml b/testapps/TestSatelliteApp/res/layout/activity_SatelliteTestApp.xml
index 8fdc01f..26b45e3 100644
--- a/testapps/TestSatelliteApp/res/layout/activity_SatelliteTestApp.xml
+++ b/testapps/TestSatelliteApp/res/layout/activity_SatelliteTestApp.xml
@@ -15,12 +15,14 @@
~ limitations under the License
-->
-<LinearLayout
+<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
- android:paddingTop="100dp"
+ android:gravity="center"
+ android:paddingTop="10dp"
+ android:paddingBottom="10dp"
android:paddingLeft="4dp">
<LinearLayout
@@ -80,4 +82,4 @@
android:paddingEnd="4dp"
android:text="@string/TestSatelliteWrapper"/>
</LinearLayout>
-</LinearLayout>
+</ScrollView>
diff --git a/testapps/TestSatelliteApp/res/layout/activity_SendReceive.xml b/testapps/TestSatelliteApp/res/layout/activity_SendReceive.xml
index 6490e5d..4ac3483 100644
--- a/testapps/TestSatelliteApp/res/layout/activity_SendReceive.xml
+++ b/testapps/TestSatelliteApp/res/layout/activity_SendReceive.xml
@@ -15,12 +15,14 @@
~ limitations under the License
-->
-<LinearLayout
+<ScrollView
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:paddingTop="10dp"
+ android:paddingBottom="10dp"
android:paddingLeft="4dp">
<LinearLayout
@@ -94,4 +96,4 @@
android:layout_centerVertical="true"
android:textSize="15dp" />
</LinearLayout>
-</LinearLayout>
+</ScrollView>
diff --git a/testapps/TestSatelliteApp/res/layout/activity_TestSatelliteWrapper.xml b/testapps/TestSatelliteApp/res/layout/activity_TestSatelliteWrapper.xml
index 39a4bd6..d046f03 100644
--- a/testapps/TestSatelliteApp/res/layout/activity_TestSatelliteWrapper.xml
+++ b/testapps/TestSatelliteApp/res/layout/activity_TestSatelliteWrapper.xml
@@ -14,10 +14,16 @@
~ See the License for the specific language governing permissions and
~ limitations under the License
-->
+
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
- android:layout_height="match_parent">
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:gravity="center"
+ android:paddingTop="10dp"
+ android:paddingBottom="10dp"
+ android:paddingLeft="4dp">
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
@@ -167,6 +173,37 @@
android:layout_height="wrap_content"
android:paddingRight="4dp"
android:text="@string/unregisterForModemStateChanged"/>
+ <Button
+ android:id="@+id/requestSatelliteSubscriberProvisionStatusWrapper"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingRight="4dp"
+ android:text="@string/requestSatelliteSubscriberProvisionStatus"/>
+ <Button
+ android:id="@+id/provisionSatelliteWrapper"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingRight="4dp"
+ android:text="@string/provisionSatellite"/>
+ <Button
+ android:id="@+id/deprovisionSatelliteWrapper"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingRight="4dp"
+ android:text="@string/deprovisionSatellite"/>
+ <Button
+ android:id="@+id/setNtnSmsSupportedTrue"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingRight="4dp"
+ android:text="@string/setNtnSmsSupportedTrue"/>
+ <Button
+ android:id="@+id/setNtnSmsSupportedFalse"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingRight="4dp"
+ android:text="@string/setNtnSmsSupportedFalse"/>
+
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -203,5 +240,4 @@
android:layout_centerVertical="true"
android:textSize="8dp" />
</LinearLayout>
-
-</ScrollView>
\ No newline at end of file
+</ScrollView>
diff --git a/testapps/TestSatelliteApp/res/values/donottranslate_strings.xml b/testapps/TestSatelliteApp/res/values/donottranslate_strings.xml
index 728576a..4b5ea5b 100644
--- a/testapps/TestSatelliteApp/res/values/donottranslate_strings.xml
+++ b/testapps/TestSatelliteApp/res/values/donottranslate_strings.xml
@@ -23,7 +23,8 @@
<string name="SendReceive">Send and Receive datagrams</string>
<string name="NbIotSatellite">NB IoT Satellite modem interface test</string>
- <string name="enableSatellite">enableSatellite</string>
+ <string name="enableSatelliteRealMode">enableSatellite Real Mode</string>
+ <string name="enableSatelliteDemoMode">enableSatellite Demo Mode</string>
<string name="disableSatellite">disableSatellite</string>
<string name="requestIsSatelliteEnabled">requestIsSatelliteEnabled</string>
<string name="requestIsDemoModeEnabled">requestIsDemoModeEnabled</string>
@@ -95,6 +96,10 @@
<string name="requestSatelliteSubscriberProvisionStatus">requestSatelliteSubscriberProvisionStatus</string>
<string name="provisionSatellite">provisionSatellite</string>
+ <string name="deprovisionSatellite">deprovisionSatellite</string>
+ <string name="setNtnSmsSupportedTrue">setNtnSmsSupportedTrue</string>
+ <string name="setNtnSmsSupportedFalse">setNtnSmsSupportedFalse</string>
+
<string name="Back">Back</string>
<string name="ClearLog">Clear Log</string>
diff --git a/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/Provisioning.java b/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/Provisioning.java
index 15c8fd8..08984be 100644
--- a/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/Provisioning.java
+++ b/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/Provisioning.java
@@ -24,12 +24,14 @@
import android.os.OutcomeReceiver;
import android.telephony.satellite.SatelliteManager;
import android.telephony.satellite.SatelliteProvisionStateCallback;
+import android.telephony.satellite.SatelliteSubscriberProvisionStatus;
import android.telephony.satellite.stub.SatelliteResult;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.TextView;
+import java.util.List;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
@@ -82,6 +84,12 @@
Log.d(TAG, "onSatelliteProvisionStateChanged in SatelliteTestApp: provisioned="
+ mProvisioned);
}
+
+ @Override
+ public void onSatelliteSubscriptionProvisionStateChanged(
+ List<SatelliteSubscriberProvisionStatus> list) {
+ Log.d(TAG, "onSatelliteSubscriptionProvisionStateChanged in SatelliteTestApp" + list);
+ }
}
private void provisionServiceApp(View view) {
diff --git a/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/SatelliteControl.java b/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/SatelliteControl.java
index 379fc74..484a6d1 100644
--- a/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/SatelliteControl.java
+++ b/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/SatelliteControl.java
@@ -35,6 +35,7 @@
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
+import android.util.Log;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
@@ -44,7 +45,7 @@
*/
public class SatelliteControl extends Activity {
- private static final long TIMEOUT = 3000;
+ private static final long TIMEOUT = TimeUnit.SECONDS.toMillis(3);
private SatelliteManager mSatelliteManager;
private SubscriptionManager mSubscriptionManager;
@@ -58,8 +59,10 @@
mSubscriptionManager = getSystemService(SubscriptionManager.class);
setContentView(R.layout.activity_SatelliteControl);
- findViewById(R.id.enableSatellite)
- .setOnClickListener(this::enableSatelliteApp);
+ findViewById(R.id.enableSatelliteDemoMode)
+ .setOnClickListener(v -> enableSatelliteApp(/* isDemoMode */ true));
+ findViewById(R.id.enableSatelliteRealMode)
+ .setOnClickListener(v -> enableSatelliteApp(/* isDemoMode */ false));
findViewById(R.id.disableSatellite)
.setOnClickListener(this::disableSatelliteApp);
findViewById(R.id.requestIsSatelliteEnabled)
@@ -92,6 +95,8 @@
.setOnClickListener(this::requestSatelliteSubscriberProvisionStatusApp);
findViewById(R.id.provisionSatellite)
.setOnClickListener(this::provisionSatelliteApp);
+ findViewById(R.id.deprovisionSatellite)
+ .setOnClickListener(this::deprovisionSatelliteApp);
findViewById(R.id.Back).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
@@ -100,24 +105,32 @@
});
}
- private void enableSatelliteApp(View view) {
+ private void enableSatelliteApp(boolean isDemoMode) {
LinkedBlockingQueue<Integer> error = new LinkedBlockingQueue<>(1);
mSatelliteManager.requestEnabled(
- new EnableRequestAttributes.Builder(true).setDemoMode(true).setEmergencyMode(true)
+ new EnableRequestAttributes.Builder(true)
+ .setDemoMode(isDemoMode)
+ .setEmergencyMode(true)
.build(), Runnable::run, error::offer);
TextView textView = findViewById(R.id.text_id);
+ Log.d("SatelliteTestApp", "enableSatelliteApp: isDemoMode=" + isDemoMode);
try {
Integer value = error.poll(TIMEOUT, TimeUnit.MILLISECONDS);
if (value == null) {
textView.setText("Timed out to enable the satellite");
+ Log.d("SatelliteTestApp", "Timed out to enable the satellite");
} else if (value != SatelliteResult.SATELLITE_RESULT_SUCCESS) {
textView.setText("Failed to enable the satellite, error ="
+ SatelliteErrorUtils.mapError(value));
+ Log.d("SatelliteTestApp", "Failed to enable the satellite, error ="
+ + SatelliteErrorUtils.mapError(value));
} else {
textView.setText("Successfully enabled the satellite");
+ Log.d("SatelliteTestApp", "Successfully enabled the satellite");
}
} catch (InterruptedException e) {
textView.setText("Enable SatelliteService exception caught =" + e);
+ Log.d("SatelliteTestApp", "Enable SatelliteService exception caught =" + e);
}
}
@@ -456,4 +469,36 @@
}
mSatelliteManager.provisionSatellite(list, Runnable::run, receiver);
}
+
+ private void deprovisionSatelliteApp(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("deprovisionSatellite is true");
+ } else {
+ textView.setText("Status for deprovisionSatellite 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 deprovisionSatellite error : "
+ + SatelliteErrorUtils.mapError(errorCode.get()));
+ }
+ };
+ List<SatelliteSubscriberInfo> list = new ArrayList<>();
+ for (SatelliteSubscriberProvisionStatus status : mSatelliteSubscriberProvisionStatuses) {
+ list.add(status.getSatelliteSubscriberInfo());
+ }
+ mSatelliteManager.deprovisionSatellite(list, Runnable::run, receiver);
+ }
}
diff --git a/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/SatelliteTestApp.java b/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/SatelliteTestApp.java
index 7c4ae00..cb56e87 100644
--- a/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/SatelliteTestApp.java
+++ b/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/SatelliteTestApp.java
@@ -16,11 +16,13 @@
package com.android.phone.testapps.satellitetestapp;
+import android.Manifest;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
+import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.IBinder;
import android.telephony.satellite.stub.SatelliteDatagram;
@@ -42,6 +44,7 @@
private TestSatelliteServiceConnection mSatelliteServiceConn;
private List<SatelliteDatagram> mSentSatelliteDatagrams = new ArrayList<>();
+ private static final int REQUEST_CODE_SEND_SMS = 1;
@Override
public void onCreate(Bundle savedInstanceState) {
@@ -105,6 +108,16 @@
});
}
+ @Override
+ protected void onResume() {
+ super.onResume();
+ if (checkSelfPermission(Manifest.permission.SEND_SMS)
+ != PackageManager.PERMISSION_GRANTED) {
+ requestPermissions(new String[]{Manifest.permission.SEND_SMS}, REQUEST_CODE_SEND_SMS);
+ }
+ }
+
+
private final ILocalSatelliteListener mSatelliteListener =
new ILocalSatelliteListener.Stub() {
@Override
diff --git a/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/SendReceive.java b/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/SendReceive.java
index ede2377..bc60c9b 100644
--- a/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/SendReceive.java
+++ b/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/SendReceive.java
@@ -290,7 +290,7 @@
satellitePositionTextView.setText("startSatelliteTransmissionUpdates exception caught ="
+ e);
}
- //Device is aligned with the satellite for demo mode
+ //Device is aligned with the satellite
mSatelliteManager.setDeviceAlignedWithSatellite(true);
}
}
diff --git a/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/TestSatelliteService.java b/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/TestSatelliteService.java
index 9c75a84..225fba0 100644
--- a/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/TestSatelliteService.java
+++ b/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/TestSatelliteService.java
@@ -60,7 +60,7 @@
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};
+ new int[]{NTRadioTechnology.NB_IOT_NTN};
/** 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. */
@@ -208,14 +208,14 @@
private void enableSatellite(@NonNull IIntegerConsumer errorCallback) {
mIsEnabled = true;
- updateSatelliteModemState(SatelliteModemState.SATELLITE_MODEM_STATE_IDLE);
runWithExecutor(() -> errorCallback.accept(SatelliteResult.SATELLITE_RESULT_SUCCESS));
+ updateSatelliteModemState(SatelliteModemState.SATELLITE_MODEM_STATE_IN_SERVICE);
}
private void disableSatellite(@NonNull IIntegerConsumer errorCallback) {
mIsEnabled = false;
- updateSatelliteModemState(SatelliteModemState.SATELLITE_MODEM_STATE_OFF);
runWithExecutor(() -> errorCallback.accept(SatelliteResult.SATELLITE_RESULT_SUCCESS));
+ updateSatelliteModemState(SatelliteModemState.SATELLITE_MODEM_STATE_OFF);
}
@Override
@@ -494,6 +494,7 @@
* @param modemState The {@link SatelliteModemState} to update.
*/
private void updateSatelliteModemState(int modemState) {
+ logd("updateSatelliteModemState: new modemState=" + modemState);
if (modemState == mModemState) {
return;
}
diff --git a/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/TestSatelliteWrapper.java b/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/TestSatelliteWrapper.java
index d8e6e7c..7d5e9af 100644
--- a/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/TestSatelliteWrapper.java
+++ b/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/TestSatelliteWrapper.java
@@ -30,6 +30,8 @@
import android.telephony.satellite.wrapper.SatelliteCommunicationAllowedStateCallbackWrapper;
import android.telephony.satellite.wrapper.SatelliteManagerWrapper;
import android.telephony.satellite.wrapper.SatelliteModemStateCallbackWrapper2;
+import android.telephony.satellite.wrapper.SatelliteSubscriberInfoWrapper;
+import android.telephony.satellite.wrapper.SatelliteSubscriberProvisionStatusWrapper;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
@@ -62,6 +64,8 @@
private SatelliteCapabilitiesCallbackWrapper mSatelliteCapabilitiesCallback;
private SubscriptionManager mSubscriptionManager;
private int mSubId;
+ private List<SatelliteSubscriberProvisionStatusWrapper> mSatelliteSubscriberProvisionStatuses =
+ new ArrayList<>();
private ListView mLogListView;
@@ -117,6 +121,17 @@
.setOnClickListener(this::registerForModemStateChanged);
findViewById(R.id.unregisterForModemStateChanged)
.setOnClickListener(this::unregisterForModemStateChanged);
+ findViewById(R.id.requestSatelliteSubscriberProvisionStatusWrapper)
+ .setOnClickListener(this::requestSatelliteSubscriberProvisionStatus);
+ findViewById(R.id.provisionSatelliteWrapper)
+ .setOnClickListener(this::provisionSatellite);
+ findViewById(R.id.deprovisionSatelliteWrapper)
+ .setOnClickListener(this::deprovisionSatellite);
+ findViewById(R.id.setNtnSmsSupportedTrue)
+ .setOnClickListener(this::setNtnSmsSupportedTrue);
+ findViewById(R.id.setNtnSmsSupportedFalse)
+ .setOnClickListener(this::setNtnSmsSupportedFalse);
+
findViewById(R.id.Back).setOnClickListener(new OnClickListener() {
@Override
@@ -389,7 +404,137 @@
}
}
+ private void requestSatelliteSubscriberProvisionStatus(View view) {
+ addLogMessage("requestSatelliteSubscriberProvisionStatus");
+ logd("requestSatelliteSubscriberProvisionStatus");
+ if (mSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+ addLogMessage("requestSatelliteSubscriberProvisionStatus: Subscription ID is invalid");
+ logd("requestSatelliteSubscriberProvisionStatus: Subscription ID is invalid");
+ return;
+ }
+
+ OutcomeReceiver<List<SatelliteSubscriberProvisionStatusWrapper>,
+ SatelliteManagerWrapper.SatelliteExceptionWrapper> receiver =
+ new OutcomeReceiver<>() {
+ @Override
+ public void onResult(List<SatelliteSubscriberProvisionStatusWrapper> result) {
+ mSatelliteSubscriberProvisionStatuses = result;
+ logd("requestSatelliteSubscriberProvisionStatus: onResult=" + result);
+ addLogMessage(
+ "requestSatelliteSubscriberProvisionStatus: onResult=" + result);
+ }
+
+ @Override
+ public void onError(
+ SatelliteManagerWrapper.SatelliteExceptionWrapper exception) {
+ if (exception != null) {
+ String onError = "requestSatelliteSubscriberProvisionStatus exception: "
+ + translateResultCodeToString(exception.getErrorCode());
+ logd(onError);
+ addLogMessage(onError);
+ }
+ }
+ };
+
+ try {
+ mSatelliteManagerWrapper.requestSatelliteSubscriberProvisionStatus(mExecutor, receiver);
+ } catch (SecurityException | IllegalArgumentException ex) {
+ String errorMessage = "requestSatelliteSubscriberProvisionStatus: " + ex.getMessage();
+ logd(errorMessage);
+ addLogMessage(errorMessage);
+ }
+ }
+
+ private void provisionSatellite(View view) {
+ addLogMessage("provisionSatellite");
+ logd("provisionSatellite");
+
+ if (mSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+ addLogMessage("provisionSatellite: Subscription ID is invalid");
+ logd("provisionSatellite: Subscription ID is invalid");
+ return;
+ }
+
+ OutcomeReceiver<Boolean,
+ SatelliteManagerWrapper.SatelliteExceptionWrapper> receiver =
+ new OutcomeReceiver<>() {
+ @Override
+ public void onResult(Boolean result) {
+ logd("provisionSatellite: onResult=" + result);
+ addLogMessage("provisionSatellite: onResult=" + result);
+ }
+
+ @Override
+ public void onError(
+ SatelliteManagerWrapper.SatelliteExceptionWrapper exception) {
+ if (exception != null) {
+ String onError = "provisionSatellite exception: "
+ + translateResultCodeToString(exception.getErrorCode());
+ logd(onError);
+ addLogMessage(onError);
+ }
+ }
+ };
+
+ List<SatelliteSubscriberInfoWrapper> list = new ArrayList<>();
+ for (SatelliteSubscriberProvisionStatusWrapper status :
+ mSatelliteSubscriberProvisionStatuses) {
+ list.add(status.getSatelliteSubscriberInfo());
+ }
+ try {
+ mSatelliteManagerWrapper.provisionSatellite(list, mExecutor, receiver);
+ } catch (SecurityException | IllegalArgumentException ex) {
+ String errorMessage = "provisionSatellite: " + ex.getMessage();
+ logd(errorMessage);
+ addLogMessage(errorMessage);
+ }
+ }
+
+ private void deprovisionSatellite(View view) {
+ addLogMessage("deprovisionSatellite");
+ logd("deprovisionSatellite");
+
+ if (mSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+ addLogMessage("deprovisionSatellite: Subscription ID is invalid");
+ logd("deprovisionSatellite: Subscription ID is invalid");
+ return;
+ }
+
+ OutcomeReceiver<Boolean,
+ SatelliteManagerWrapper.SatelliteExceptionWrapper> receiver =
+ new OutcomeReceiver<>() {
+ @Override
+ public void onResult(Boolean result) {
+ logd("deprovisionSatellite: onResult=" + result);
+ addLogMessage("deprovisionSatellite: onResult=" + result);
+ }
+
+ @Override
+ public void onError(
+ SatelliteManagerWrapper.SatelliteExceptionWrapper exception) {
+ if (exception != null) {
+ String onError = "deprovisionSatellite exception: "
+ + translateResultCodeToString(exception.getErrorCode());
+ logd(onError);
+ addLogMessage(onError);
+ }
+ }
+ };
+
+ List<SatelliteSubscriberInfoWrapper> list = new ArrayList<>();
+ for (SatelliteSubscriberProvisionStatusWrapper status :
+ mSatelliteSubscriberProvisionStatuses) {
+ list.add(status.getSatelliteSubscriberInfo());
+ }
+ try {
+ mSatelliteManagerWrapper.deprovisionSatellite(list, mExecutor, receiver);
+ } catch (SecurityException | IllegalArgumentException ex) {
+ String errorMessage = "deprovisionSatellite: " + ex.getMessage();
+ logd(errorMessage);
+ addLogMessage(errorMessage);
+ }
+ }
public class NtnSignalStrengthCallback implements NtnSignalStrengthCallbackWrapper {
@Override
@@ -659,6 +804,31 @@
}
}
+ private void setNtnSmsSupportedTrue(View view) {
+ setNtnSmsSupported(true);
+ }
+
+ private void setNtnSmsSupportedFalse(View view) {
+ setNtnSmsSupported(false);
+ }
+
+ private void setNtnSmsSupported(boolean ntnSmsSupported) {
+ String msg = "setNtnSmsSupported:" + ntnSmsSupported;
+ addLogMessage(msg);
+ logd(msg);
+
+ try {
+ mSatelliteManagerWrapper.setNtnSmsSupported(ntnSmsSupported);
+ msg = "setNtnSmsSupported=" + ntnSmsSupported + " is successful";
+ logd(msg);
+ addLogMessage(msg);
+ } catch (SecurityException | IllegalStateException ex) {
+ msg = "setNtnSmsSupported=" + ntnSmsSupported + " failed. " + ex.getMessage();
+ logd(msg);
+ addLogMessage(msg);
+ }
+ }
+
private int getActiveSubId() {
int subId;
List<SubscriptionInfo> subscriptionInfoList =
diff --git a/tests/src/com/android/TelephonyTestBase.java b/tests/src/com/android/TelephonyTestBase.java
index d72d85e..3e74eb7 100644
--- a/tests/src/com/android/TelephonyTestBase.java
+++ b/tests/src/com/android/TelephonyTestBase.java
@@ -16,21 +16,38 @@
package com.android;
+import static org.junit.Assert.assertNotNull;
import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.doCallRealMethod;
+import static org.mockito.Mockito.doReturn;
+import android.content.ContextWrapper;
+import android.content.res.Resources;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
+import androidx.test.InstrumentationRegistry;
+
+import com.android.internal.telephony.GsmCdmaPhone;
+import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneConfigurationManager;
+import com.android.internal.telephony.PhoneFactory;
+import com.android.internal.telephony.data.DataConfigManager;
+import com.android.internal.telephony.data.DataNetworkController;
+import com.android.phone.PhoneGlobals;
+import com.android.phone.PhoneInterfaceManager;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
+import org.mockito.Mock;
+import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import java.lang.reflect.Field;
+import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
@@ -39,31 +56,50 @@
import java.util.concurrent.TimeUnit;
/**
- * Helper class to load Mockito Resources into a test.
+ * Helper class to load Mockito Resources into Telephony unit tests.
*/
public class TelephonyTestBase {
@Rule public final MockitoRule mocks = MockitoJUnit.rule();
protected TestContext mContext;
+ @Mock protected PhoneGlobals mPhoneGlobals;
+ @Mock protected GsmCdmaPhone mPhone;
+ @Mock protected DataNetworkController mDataNetworkController;
private final HashMap<InstanceKey, Object> mOldInstances = new HashMap<>();
private final LinkedList<InstanceKey> mInstanceKeys = new LinkedList<>();
@Before
public void setUp() throws Exception {
- mContext = spy(new TestContext());
- // Set up the looper if it does not exist on the test thread.
if (Looper.myLooper() == null) {
Looper.prepare();
- // Wait until the looper is not null anymore
- for(int i = 0; i < 5; i++) {
- if (Looper.myLooper() != null) {
- break;
- }
- Looper.prepare();
- Thread.sleep(100);
- }
}
+
+ doCallRealMethod().when(mPhoneGlobals).getBaseContext();
+ doCallRealMethod().when(mPhoneGlobals).getResources();
+ doCallRealMethod().when(mPhone).getServiceState();
+
+ mContext = spy(new TestContext());
+ doReturn(mContext).when(mPhone).getContext();
+ replaceInstance(ContextWrapper.class, "mBase", mPhoneGlobals, mContext);
+
+ Resources resources = InstrumentationRegistry.getTargetContext().getResources();
+ assertNotNull(resources);
+ doReturn(resources).when(mContext).getResources();
+
+ replaceInstance(Handler.class, "mLooper", mPhone, Looper.myLooper());
+ replaceInstance(PhoneFactory.class, "sMadeDefaults", null, true);
+ replaceInstance(PhoneFactory.class, "sPhone", null, mPhone);
+ replaceInstance(PhoneFactory.class, "sPhones", null, new Phone[] {mPhone});
+ replaceInstance(PhoneGlobals.class, "sMe", null, mPhoneGlobals);
+
+ doReturn(mDataNetworkController).when(mPhone).getDataNetworkController();
+ doReturn(Collections.emptyList()).when(mDataNetworkController)
+ .getInternetDataDisallowedReasons();
+ doReturn(Mockito.mock(DataConfigManager.class)).when(mDataNetworkController)
+ .getDataConfigManager();
+
+ mPhoneGlobals.phoneMgr = Mockito.mock(PhoneInterfaceManager.class);
}
@After
diff --git a/tests/src/com/android/TestContext.java b/tests/src/com/android/TestContext.java
index e464ad5..a684ef5 100644
--- a/tests/src/com/android/TestContext.java
+++ b/tests/src/com/android/TestContext.java
@@ -103,6 +103,11 @@
}
@Override
+ public String getOpPackageName() {
+ return getPackageName();
+ }
+
+ @Override
public String getAttributionTag() {
return "";
}
@@ -212,6 +217,11 @@
}
@Override
+ public Looper getMainLooper() {
+ return Looper.getMainLooper();
+ }
+
+ @Override
public Handler getMainThreadHandler() {
return new Handler(Looper.getMainLooper());
}
diff --git a/tests/src/com/android/phone/CarrierConfigLoaderTest.java b/tests/src/com/android/phone/CarrierConfigLoaderTest.java
index bda2313..5190b21 100644
--- a/tests/src/com/android/phone/CarrierConfigLoaderTest.java
+++ b/tests/src/com/android/phone/CarrierConfigLoaderTest.java
@@ -41,7 +41,6 @@
import android.content.res.Resources;
import android.os.Build;
import android.os.Handler;
-import android.os.HandlerThread;
import android.os.PermissionEnforcer;
import android.os.PersistableBundle;
import android.os.UserHandle;
@@ -51,10 +50,10 @@
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.telephony.TelephonyRegistryManager;
+import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import androidx.test.InstrumentationRegistry;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.android.TelephonyTestBase;
import com.android.internal.telephony.IccCardConstants;
@@ -72,7 +71,6 @@
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -81,7 +79,8 @@
/**
* Unit Test for CarrierConfigLoader.
*/
-@RunWith(AndroidJUnit4.class)
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
public class CarrierConfigLoaderTest extends TelephonyTestBase {
@Rule
public TestRule compatChangeRule = new PlatformCompatChangeRule();
@@ -108,7 +107,6 @@
private TelephonyManager mTelephonyManager;
private CarrierConfigLoader mCarrierConfigLoader;
private Handler mHandler;
- private HandlerThread mHandlerThread;
private TestableLooper mTestableLooper;
// The AIDL stub will use PermissionEnforcer to check permission from the caller.
@@ -117,7 +115,6 @@
@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(
@@ -151,10 +148,7 @@
when(mContext.getSystemService(TelephonyRegistryManager.class)).thenReturn(
mTelephonyRegistryManager);
- mHandlerThread = new HandlerThread("CarrierConfigLoaderTest");
- mHandlerThread.start();
-
- mTestableLooper = new TestableLooper(mHandlerThread.getLooper());
+ mTestableLooper = TestableLooper.get(this);
mCarrierConfigLoader = new CarrierConfigLoader(mContext, mTestableLooper.getLooper(),
mFeatureFlags);
mHandler = mCarrierConfigLoader.getHandler();
@@ -169,8 +163,6 @@
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();
}
diff --git a/tests/src/com/android/phone/ImsStateCallbackControllerTest.java b/tests/src/com/android/phone/ImsStateCallbackControllerTest.java
index 0e902a8..5521ac0 100644
--- a/tests/src/com/android/phone/ImsStateCallbackControllerTest.java
+++ b/tests/src/com/android/phone/ImsStateCallbackControllerTest.java
@@ -46,7 +46,6 @@
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
-import android.os.Looper;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyRegistryManager;
import android.testing.TestableLooper;
@@ -70,7 +69,6 @@
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
@@ -110,7 +108,6 @@
@Captor ArgumentCaptor<FeatureConnector.Listener<ImsManager>> mMmTelConnectorListenerSlot1;
@Captor ArgumentCaptor<FeatureConnector.Listener<RcsFeatureManager>> mRcsConnectorListenerSlot0;
@Captor ArgumentCaptor<FeatureConnector.Listener<RcsFeatureManager>> mRcsConnectorListenerSlot1;
- @Mock private PhoneGlobals mPhone;
@Mock ImsStateCallbackController.PhoneFactoryProxy mPhoneFactoryProxy;
@Mock Phone mPhoneSlot0;
@Mock Phone mPhoneSlot1;
@@ -134,16 +131,16 @@
@Before
public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
+ super.setUp();
- when(mPhone.getMainExecutor()).thenReturn(mExecutor);
- when(mPhone.getSystemServiceName(eq(SubscriptionManager.class)))
+ when(mPhoneGlobals.getMainExecutor()).thenReturn(mExecutor);
+ when(mPhoneGlobals.getSystemServiceName(eq(SubscriptionManager.class)))
.thenReturn(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
- when(mPhone.getSystemService(eq(Context.TELEPHONY_SUBSCRIPTION_SERVICE)))
+ when(mPhoneGlobals.getSystemService(eq(Context.TELEPHONY_SUBSCRIPTION_SERVICE)))
.thenReturn(mSubscriptionManager);
- when(mPhone.getSystemServiceName(eq(TelephonyRegistryManager.class)))
+ when(mPhoneGlobals.getSystemServiceName(eq(TelephonyRegistryManager.class)))
.thenReturn(Context.TELEPHONY_REGISTRY_SERVICE);
- when(mPhone.getSystemService(eq(Context.TELEPHONY_REGISTRY_SERVICE)))
+ when(mPhoneGlobals.getSystemService(eq(Context.TELEPHONY_REGISTRY_SERVICE)))
.thenReturn(mTelephonyRegistryManager);
when(mPhoneFactoryProxy.getPhone(eq(0))).thenReturn(mPhoneSlot0);
when(mPhoneFactoryProxy.getPhone(eq(1))).thenReturn(mPhoneSlot1);
@@ -937,9 +934,6 @@
}
private void createController(int slotCount) throws Exception {
- if (Looper.myLooper() == null) {
- Looper.prepare();
- }
makeFakeActiveSubIds(slotCount);
when(mMmTelFeatureFactory
@@ -956,7 +950,7 @@
.thenReturn(mRcsFeatureConnectorSlot1);
mImsStateCallbackController =
- new ImsStateCallbackController(mPhone, mHandlerThread.getLooper(),
+ new ImsStateCallbackController(mPhoneGlobals, mHandlerThread.getLooper(),
slotCount, mMmTelFeatureFactory, mRcsFeatureFactory, mImsResolver,
mFeatureFlags);
diff --git a/tests/src/com/android/phone/LocationAccessPolicyTest.java b/tests/src/com/android/phone/LocationAccessPolicyTest.java
index 58e7fbd..551c2cb 100644
--- a/tests/src/com/android/phone/LocationAccessPolicyTest.java
+++ b/tests/src/com/android/phone/LocationAccessPolicyTest.java
@@ -225,6 +225,8 @@
try {
when(mPackageManager.getApplicationInfo(anyString(), anyInt()))
.thenReturn(fakeAppInfo);
+ when(mPackageManager.getApplicationInfoAsUser(anyString(), anyInt(),
+ any(UserHandle.class))).thenReturn(fakeAppInfo);
} catch (Exception e) {
// this is a formality
}
diff --git a/tests/src/com/android/phone/NotificationMgrTest.java b/tests/src/com/android/phone/NotificationMgrTest.java
index 98c6a4a..0c1f8a3 100644
--- a/tests/src/com/android/phone/NotificationMgrTest.java
+++ b/tests/src/com/android/phone/NotificationMgrTest.java
@@ -59,6 +59,7 @@
import android.content.pm.ApplicationInfo;
import android.content.res.Resources;
import android.os.Build;
+import android.os.ParcelUuid;
import android.os.PersistableBundle;
import android.os.SystemClock;
import android.os.UserHandle;
@@ -76,11 +77,8 @@
import com.android.TelephonyTestBase;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneConstants;
-import com.android.internal.telephony.PhoneFactory;
import com.android.internal.telephony.ServiceStateTracker;
import com.android.internal.telephony.SignalStrengthController;
-import com.android.internal.telephony.data.DataConfigManager;
-import com.android.internal.telephony.data.DataNetworkController;
import com.android.internal.telephony.data.DataSettingsManager;
import com.android.internal.telephony.util.NotificationChannelController;
@@ -89,9 +87,7 @@
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import java.util.Collections;
import java.util.concurrent.TimeUnit;
/**
@@ -110,13 +106,12 @@
private static final String MOBILE_NETWORK_SELECTION_CLASS = ".testClass";
private static final String CARRIER_NAME = "CoolCarrier";
- @Mock PhoneGlobals mApp;
+ PhoneGlobals mApp; // mPhoneGlobals alias
@Mock StatusBarManager mStatusBarManager;
@Mock UserManager mUserManager;
@Mock SubscriptionManager mSubscriptionManager;
@Mock TelecomManager mTelecomManager;
@Mock TelephonyManager mTelephonyManager;
- @Mock Phone mPhone;
@Mock SharedPreferences mSharedPreferences;
@Mock NotificationManager mNotificationManager;
@Mock SubscriptionInfo mSubscriptionInfo;
@@ -125,20 +120,16 @@
@Mock ServiceStateTracker mServiceStateTracker;
@Mock ServiceState mServiceState;
@Mock CarrierConfigManager mCarrierConfigManager;
- @Mock DataNetworkController mDataNetworkController;
@Mock DataSettingsManager mDataSettingsManager;
- @Mock DataConfigManager mDataConfigManager;
@Mock SignalStrengthController mSignalStrengthController;
- private Phone[] mPhones;
private NotificationMgr mNotificationMgr;
private TestableLooper mTestableLooper;
@Before
public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
- mPhones = new Phone[]{mPhone};
- replaceInstance(PhoneFactory.class, "sPhones", null, mPhones);
+ super.setUp();
+ mApp = mPhoneGlobals;
when(mPhone.getPhoneType()).thenReturn(PhoneConstants.PHONE_TYPE_GSM);
when(mPhone.getContext()).thenReturn(mMockedContext);
when(mMockedContext.getResources()).thenReturn(mResources);
@@ -151,10 +142,6 @@
when(mPhone.getServiceStateTracker()).thenReturn(mServiceStateTracker);
mServiceStateTracker.mSS = mServiceState;
when(mPhone.getSignalStrengthController()).thenReturn(mSignalStrengthController);
- when(mPhone.getDataNetworkController()).thenReturn(mDataNetworkController);
- when(mDataNetworkController.getInternetDataDisallowedReasons()).thenReturn(
- Collections.emptyList());
- when(mDataNetworkController.getDataConfigManager()).thenReturn(mDataConfigManager);
when(mPhone.getDataSettingsManager()).thenReturn(mDataSettingsManager);
when(mDataSettingsManager.isDataEnabledForReason(anyInt())).thenReturn(true);
when(mApp.getSharedPreferences(anyString(), anyInt())).thenReturn(mSharedPreferences);
@@ -409,6 +396,35 @@
}
@Test
+ public void testUpdateNetworkSelection_opportunisticSubscription_notificationNotSent()
+ throws Exception {
+ prepareResourcesForNetworkSelection();
+ when(mSubscriptionManager.getActiveSubscriptionInfo(eq(TEST_SUB_ID))).thenReturn(
+ mSubscriptionInfo);
+
+ when(mTelephonyManager.isManualNetworkSelectionAllowed()).thenReturn(true);
+ PersistableBundle config = new PersistableBundle();
+ config.putBoolean(CarrierConfigManager.KEY_OPERATOR_SELECTION_EXPAND_BOOL, true);
+ config.putBoolean(CarrierConfigManager.KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL, false);
+ config.putBoolean(CarrierConfigManager.KEY_CSP_ENABLED_BOOL, false);
+ config.putBoolean(CarrierConfigManager.KEY_WORLD_PHONE_BOOL, true);
+ when(mCarrierConfigManager.getConfigForSubId(TEST_SUB_ID)).thenReturn(config);
+
+ when(mSubscriptionInfo.isOpportunistic()).thenReturn(true);
+ when(mSubscriptionInfo.getGroupUuid()).thenReturn(
+ ParcelUuid.fromString("5be5c5f3-3412-452e-86a0-6f18558ae8c8"));
+
+ mNotificationMgr.updateNetworkSelection(ServiceState.STATE_OUT_OF_SERVICE, TEST_SUB_ID);
+ try {
+ Thread.sleep(10000);
+ } catch (InterruptedException ignored) {
+ }
+ mNotificationMgr.updateNetworkSelection(ServiceState.STATE_OUT_OF_SERVICE, TEST_SUB_ID);
+
+ verify(mNotificationManager, never()).notify(any(), anyInt(), any());
+ }
+
+ @Test
public void testUpdateNetworkSelection_worldMode_userSetLTE_notificationNotSent() {
prepareResourcesForNetworkSelection();
@@ -632,6 +648,8 @@
when(mApp.getString(R.string.mobile_network_settings_class)).thenReturn(
MOBILE_NETWORK_SELECTION_CLASS);
when(mSubscriptionManager.isActiveSubId(anyInt())).thenReturn(true);
+ when(mSubscriptionManager.getActiveSubscriptionInfo(eq(TEST_SUB_ID))).thenReturn(
+ mSubscriptionInfo);
}
private void moveTimeForward(long seconds) {
diff --git a/tests/src/com/android/phone/PhoneInterfaceManagerTest.java b/tests/src/com/android/phone/PhoneInterfaceManagerTest.java
index 7464ba2..ef6a02a 100644
--- a/tests/src/com/android/phone/PhoneInterfaceManagerTest.java
+++ b/tests/src/com/android/phone/PhoneInterfaceManagerTest.java
@@ -20,7 +20,6 @@
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
@@ -45,11 +44,14 @@
import android.os.UserHandle;
import android.permission.flags.Flags;
import android.platform.test.flag.junit.SetFlagsRule;
+import android.preference.PreferenceManager;
import android.telephony.RadioAccessFamily;
import android.telephony.TelephonyManager;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
import androidx.test.annotation.UiThreadTest;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.platform.app.InstrumentationRegistry;
import com.android.TelephonyTestBase;
import com.android.internal.telephony.IIntegerConsumer;
@@ -57,6 +59,7 @@
import com.android.internal.telephony.RILConstants;
import com.android.internal.telephony.flags.FeatureFlags;
import com.android.internal.telephony.subscription.SubscriptionManagerService;
+import com.android.phone.satellite.accesscontrol.SatelliteAccessController;
import libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges;
@@ -66,6 +69,7 @@
import org.junit.rules.TestRule;
import org.junit.runner.RunWith;
import org.mockito.Mock;
+import org.mockito.Mockito;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
@@ -75,20 +79,19 @@
/**
* Unit Test for PhoneInterfaceManager.
*/
-@RunWith(AndroidJUnit4.class)
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
public class PhoneInterfaceManagerTest extends TelephonyTestBase {
@Rule
public TestRule compatChangeRule = new PlatformCompatChangeRule();
private PhoneInterfaceManager mPhoneInterfaceManager;
private SharedPreferences mSharedPreferences;
- private IIntegerConsumer mIIntegerConsumer;
+ @Mock private IIntegerConsumer mIIntegerConsumer;
private static final String sDebugPackageName =
PhoneInterfaceManagerTest.class.getPackageName();
@Mock
- PhoneGlobals mPhoneGlobals;
- @Mock
Phone mPhone;
@Mock
FeatureFlags mFeatureFlags;
@@ -108,6 +111,18 @@
super.setUp();
doReturn(sDebugPackageName).when(mPhoneGlobals).getOpPackageName();
+ replaceInstance(SatelliteAccessController.class, "sInstance", null,
+ Mockito.mock(SatelliteAccessController.class));
+
+ mSharedPreferences = PreferenceManager.getDefaultSharedPreferences(
+ InstrumentationRegistry.getInstrumentation().getTargetContext());
+ doReturn(mSharedPreferences).when(mPhoneGlobals)
+ .getSharedPreferences(anyString(), anyInt());
+ mSharedPreferences.edit().remove(Phone.PREF_NULL_CIPHER_AND_INTEGRITY_ENABLED).commit();
+ mSharedPreferences.edit().remove(Phone.PREF_NULL_CIPHER_NOTIFICATIONS_ENABLED).commit();
+
+ // Trigger sInstance restore in tearDown, after PhoneInterfaceManager.init.
+ replaceInstance(PhoneInterfaceManager.class, "sInstance", null, null);
// Note that PhoneInterfaceManager is a singleton. Calling init gives us a handle to the
// global singleton, but the context that is passed in is unused if the phone app is already
// alive on a test devices. You must use the spy to mock behavior. Mocks stemming from the
@@ -119,10 +134,6 @@
doReturn(mSubscriptionManagerService).when(mPhoneInterfaceManager)
.getSubscriptionManagerService();
TelephonyManager.setupISubForTest(mSubscriptionManagerService);
- mSharedPreferences = mPhoneInterfaceManager.getSharedPreferences();
- mSharedPreferences.edit().remove(Phone.PREF_NULL_CIPHER_AND_INTEGRITY_ENABLED).commit();
- mSharedPreferences.edit().remove(Phone.PREF_NULL_CIPHER_NOTIFICATIONS_ENABLED).commit();
- mIIntegerConsumer = mock(IIntegerConsumer.class);
// In order not to affect the existing implementation, define a telephony features
// and disabled enforce_telephony_feature_mapping_for_public_apis feature flag
@@ -130,7 +141,9 @@
doReturn(false).when(mFeatureFlags).enforceTelephonyFeatureMappingForPublicApis();
doReturn(true).when(mFeatureFlags).hsumPackageManager();
mPhoneInterfaceManager.setPackageManager(mPackageManager);
+ doReturn(mPackageManager).when(mPhoneGlobals).getPackageManager();
doReturn(true).when(mPackageManager).hasSystemFeature(anyString());
+ doReturn(new String[]{sDebugPackageName}).when(mPackageManager).getPackagesForUid(anyInt());
mPhoneInterfaceManager.setAppOpsManager(mAppOps);
}
@@ -491,15 +504,11 @@
mPhoneInterfaceManager.setFeatureFlags(mFeatureFlags);
doNothing().when(mPhoneInterfaceManager).enforceModifyPermission();
- try {
- // FEATURE_TELEPHONY_CALLING
- mPhoneInterfaceManager.handlePinMmiForSubscriber(1, "123456789");
+ // FEATURE_TELEPHONY_CALLING
+ mPhoneInterfaceManager.getVoiceActivationState(1, "com.test.package");
- // FEATURE_TELEPHONY_RADIO_ACCESS
- mPhoneInterfaceManager.toggleRadioOnOffForSubscriber(1);
- } catch (Exception e) {
- fail("Not expect exception " + e.getMessage());
- }
+ // FEATURE_TELEPHONY_RADIO_ACCESS
+ mPhoneInterfaceManager.toggleRadioOnOffForSubscriber(1);
}
@Test
diff --git a/tests/src/com/android/phone/PhoneUtilsTest.java b/tests/src/com/android/phone/PhoneUtilsTest.java
index 3d7815c..2d3d065 100644
--- a/tests/src/com/android/phone/PhoneUtilsTest.java
+++ b/tests/src/com/android/phone/PhoneUtilsTest.java
@@ -30,15 +30,11 @@
import androidx.test.runner.AndroidJUnit4;
import com.android.TelephonyTestBase;
-import com.android.internal.telephony.GsmCdmaPhone;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneFactory;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
@RunWith(AndroidJUnit4.class)
public class PhoneUtilsTest extends TelephonyTestBase {
@@ -46,8 +42,6 @@
private SubscriptionManager mMockSubscriptionManager;
@Mock
private SubscriptionInfo mMockSubscriptionInfo;
- @Mock
- private GsmCdmaPhone mMockPhone;
private final int mPhoneAccountHandleIdInteger = 123;
private final String mPhoneAccountHandleIdString = "123";
@@ -58,12 +52,10 @@
@Before
public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
+ super.setUp();
when(mMockSubscriptionManager.getActiveSubscriptionInfo(
eq(mPhoneAccountHandleIdInteger))).thenReturn(mMockSubscriptionInfo);
- when(mMockPhone.getSubId()).thenReturn(mPhoneAccountHandleIdInteger);
- Phone[] mPhones = new Phone[] {mMockPhone};
- replaceInstance(PhoneFactory.class, "sPhones", null, mPhones);
+ when(mPhone.getSubId()).thenReturn(mPhoneAccountHandleIdInteger);
}
@Test
@@ -74,7 +66,7 @@
@Test
public void testGetPhoneForPhoneAccountHandle() throws Exception {
- assertEquals(mMockPhone, PhoneUtils.getPhoneForPhoneAccountHandle(
+ assertEquals(mPhone, PhoneUtils.getPhoneForPhoneAccountHandle(
mPhoneAccountHandleTest));
}
diff --git a/tests/src/com/android/phone/euicc/EuiccUiDispatcherActivityTest.java b/tests/src/com/android/phone/euicc/EuiccUiDispatcherActivityTest.java
index 817220c..1bd118a 100644
--- a/tests/src/com/android/phone/euicc/EuiccUiDispatcherActivityTest.java
+++ b/tests/src/com/android/phone/euicc/EuiccUiDispatcherActivityTest.java
@@ -24,6 +24,7 @@
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.service.euicc.EuiccService;
+import android.telephony.TelephonyManager;
import android.telephony.euicc.EuiccManager;
import androidx.test.InstrumentationRegistry;
@@ -50,6 +51,7 @@
@Mock private Context mMockContext;
@Mock private EuiccManager mMockEuiccManager;
+ @Mock private TelephonyManager mTelephonyManager;
private ActivityInfo mActivityInfo = ACTIVITY_INFO;
private Intent mIntent = MANAGE_INTENT;
private EuiccUiDispatcherActivity mActivity;
@@ -59,6 +61,8 @@
MockitoAnnotations.initMocks(this);
when(mMockEuiccManager.isEnabled()).thenReturn(true);
when(mMockContext.getSystemService(Context.EUICC_SERVICE)).thenReturn(mMockEuiccManager);
+ when(mMockContext.getSystemService(Context.TELEPHONY_SERVICE))
+ .thenReturn(mTelephonyManager);
InstrumentationRegistry.getInstrumentation().runOnMainSync(
new Runnable() {
@Override
diff --git a/tests/src/com/android/phone/satellite/accesscontrol/S2RangeSatelliteOnDeviceAccessControllerTest.java b/tests/src/com/android/phone/satellite/accesscontrol/S2RangeSatelliteOnDeviceAccessControllerTest.java
index 16a256d..27f3ef7 100644
--- a/tests/src/com/android/phone/satellite/accesscontrol/S2RangeSatelliteOnDeviceAccessControllerTest.java
+++ b/tests/src/com/android/phone/satellite/accesscontrol/S2RangeSatelliteOnDeviceAccessControllerTest.java
@@ -16,13 +16,21 @@
package com.android.phone.satellite.accesscontrol;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
+import static org.mockito.Mockito.doReturn;
+
+import android.annotation.Nullable;
import androidx.test.ext.junit.runners.AndroidJUnit4;
-import com.android.storage.s2.S2LevelRange;
+import com.android.internal.telephony.flags.FeatureFlags;
import com.android.telephony.sats2range.read.SatS2RangeFileFormat;
+import com.android.telephony.sats2range.read.SuffixTableRange;
import com.android.telephony.sats2range.utils.TestUtils;
import com.android.telephony.sats2range.write.SatS2RangeFileWriter;
@@ -33,6 +41,7 @@
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import java.io.File;
@@ -44,6 +53,9 @@
public class S2RangeSatelliteOnDeviceAccessControllerTest {
private File mFile;
+ @Mock
+ private FeatureFlags mMockFeatureFlags;
+
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
@@ -60,18 +72,42 @@
@Test
public void testSatelliteAccessControl_AllowedList() throws Exception {
- testSatelliteAccessControl(true);
+ testSatelliteAccessControl(true, null);
}
@Test
public void testSatelliteAccessControl_DisallowedList() throws Exception {
- testSatelliteAccessControl(false);
+ testSatelliteAccessControl(false, null);
}
- private void testSatelliteAccessControl(boolean isAllowedList) throws Exception {
+ @Test
+ public void testSatelliteAccessControl_AllowedList_validEntryValue() throws Exception {
+ testSatelliteAccessControl(true, 1);
+ }
+
+ @Test
+ public void testSatelliteAccessControl_DisallowedList_validEntryValue() {
+ assertThrows(IllegalArgumentException.class,
+ () -> testSatelliteAccessControl(false, 1));
+ }
+
+ private void testSatelliteAccessControl(boolean isAllowedList, @Nullable Integer entryValue)
+ throws Exception {
+ final int defaultEntryValue = -1;
+
+ if (!isAllowedList && entryValue != null) {
+ throw new IllegalArgumentException(
+ "isAllowedList must be true when entryValue is present.");
+ }
+
+ List<Integer> expectedConfigIds = List.of(1, 1, 3);
SatS2RangeFileFormat fileFormat = null;
try {
- fileFormat = createSatS2File(mFile, isAllowedList);
+ if (entryValue == null) {
+ fileFormat = createSatS2File(mFile, isAllowedList);
+ } else {
+ fileFormat = createSatS2FileWithEntryValue(mFile, isAllowedList, expectedConfigIds);
+ }
} catch (Exception ex) {
fail("Got unexpected exception in createSatS2File, ex=" + ex);
}
@@ -79,8 +115,12 @@
// Validate the output block file
SatelliteOnDeviceAccessController accessController = null;
try {
- accessController = SatelliteOnDeviceAccessController.create(mFile);
+ accessController = SatelliteOnDeviceAccessController.create(mFile, mMockFeatureFlags);
int s2Level = accessController.getS2Level();
+ if (entryValue == null) {
+ expectedConfigIds = List.of(defaultEntryValue, defaultEntryValue,
+ defaultEntryValue);
+ }
// Verify an edge cell of range 1 not in the output file
S2CellId s2CellId = new S2CellId(TestUtils.createCellId(fileFormat, 1, 1000, 999));
@@ -88,9 +128,18 @@
SatelliteOnDeviceAccessController.LocationToken locationToken =
SatelliteOnDeviceAccessController.createLocationTokenForLatLng(
s2LatLng.latDegrees(), s2LatLng.lngDegrees(), s2Level);
+
+ // Verify if the return value is null, when the carrierRoamingNbIotNtn is disabled.
+ doReturn(false).when(mMockFeatureFlags).carrierRoamingNbIotNtn();
+ assertNull(accessController.getRegionalConfigIdForLocation(locationToken));
+
+ doReturn(true).when(mMockFeatureFlags).carrierRoamingNbIotNtn();
boolean isAllowed = accessController.isSatCommunicationAllowedAtLocation(locationToken);
assertTrue(isAllowed != isAllowedList);
+ Integer configId = accessController.getRegionalConfigIdForLocation(locationToken);
+ assertNull(configId);
+
// Verify cells in range1 present in the output file
for (int suffix = 1000; suffix < 2000; suffix++) {
s2CellId = new S2CellId(TestUtils.createCellId(fileFormat, 1, 1000, suffix));
@@ -98,9 +147,13 @@
// Lookup using location token
locationToken = SatelliteOnDeviceAccessController.createLocationTokenForLatLng(
- s2LatLng.latDegrees(), s2LatLng.lngDegrees(), s2Level);
+ s2LatLng.latDegrees(), s2LatLng.lngDegrees(), s2Level);
isAllowed = accessController.isSatCommunicationAllowedAtLocation(locationToken);
assertTrue(isAllowed == isAllowedList);
+
+ configId = accessController.getRegionalConfigIdForLocation(locationToken);
+ assertNotNull(configId);
+ assertEquals((int) expectedConfigIds.get(0), (int) configId);
}
// Verify the middle cell not in the output file
@@ -111,6 +164,10 @@
isAllowed = accessController.isSatCommunicationAllowedAtLocation(locationToken);
assertTrue(isAllowed != isAllowedList);
+ configId = accessController.getRegionalConfigIdForLocation(locationToken);
+ assertNull(configId);
+
+
// Verify cells in range2 present in the output file
for (int suffix = 2001; suffix < 3000; suffix++) {
s2CellId = new S2CellId(TestUtils.createCellId(fileFormat, 1, 1000, suffix));
@@ -119,6 +176,10 @@
s2LatLng.latDegrees(), s2LatLng.lngDegrees(), s2Level);
isAllowed = accessController.isSatCommunicationAllowedAtLocation(locationToken);
assertTrue(isAllowed == isAllowedList);
+
+ configId = accessController.getRegionalConfigIdForLocation(locationToken);
+ assertNotNull(configId);
+ assertEquals((int) expectedConfigIds.get(1), (int) configId);
}
// Verify an edge cell of range 2 not in the output file
@@ -129,6 +190,9 @@
isAllowed = accessController.isSatCommunicationAllowedAtLocation(locationToken);
assertTrue(isAllowed != isAllowedList);
+ configId = accessController.getRegionalConfigIdForLocation(locationToken);
+ assertNull(configId);
+
// Verify an edge cell of range 3 not in the output file
s2CellId = new S2CellId(TestUtils.createCellId(fileFormat, 1, 1001, 999));
s2LatLng = s2CellId.toLatLng();
@@ -137,6 +201,9 @@
isAllowed = accessController.isSatCommunicationAllowedAtLocation(locationToken);
assertTrue(isAllowed != isAllowedList);
+ configId = accessController.getRegionalConfigIdForLocation(locationToken);
+ assertNull(configId);
+
// Verify cells in range1 present in the output file
for (int suffix = 1000; suffix < 2000; suffix++) {
s2CellId = new S2CellId(TestUtils.createCellId(fileFormat, 1, 1001, suffix));
@@ -145,6 +212,10 @@
s2LatLng.latDegrees(), s2LatLng.lngDegrees(), s2Level);
isAllowed = accessController.isSatCommunicationAllowedAtLocation(locationToken);
assertTrue(isAllowed == isAllowedList);
+
+ configId = accessController.getRegionalConfigIdForLocation(locationToken);
+ assertNotNull(configId);
+ assertEquals((int) expectedConfigIds.get(2), (int) configId);
}
// Verify an edge cell of range 3 not in the output file
@@ -154,6 +225,10 @@
s2LatLng.latDegrees(), s2LatLng.lngDegrees(), s2Level);
isAllowed = accessController.isSatCommunicationAllowedAtLocation(locationToken);
assertTrue(isAllowed != isAllowedList);
+
+ configId = accessController.getRegionalConfigIdForLocation(locationToken);
+ assertNull(configId);
+
} catch (Exception ex) {
fail("Unexpected exception when validating the output ex=" + ex);
} finally {
@@ -163,27 +238,61 @@
}
}
- private SatS2RangeFileFormat createSatS2File(
- File file, boolean isAllowedList) throws Exception {
+ private SatS2RangeFileFormat createSatS2File(File file, boolean isAllowedList)
+ throws Exception {
SatS2RangeFileFormat fileFormat;
- S2LevelRange range1, range2, range3;
+ SuffixTableRange range1, range2, range3;
try (SatS2RangeFileWriter satS2RangeFileWriter = SatS2RangeFileWriter.open(
file, TestUtils.createS2RangeFileFormat(isAllowedList))) {
fileFormat = satS2RangeFileWriter.getFileFormat();
// Two ranges that share a prefix.
- range1 = new S2LevelRange(
+ range1 = new SuffixTableRange(
TestUtils.createCellId(fileFormat, 1, 1000, 1000),
TestUtils.createCellId(fileFormat, 1, 1000, 2000));
- range2 = new S2LevelRange(
+ range2 = new SuffixTableRange(
TestUtils.createCellId(fileFormat, 1, 1000, 2001),
TestUtils.createCellId(fileFormat, 1, 1000, 3000));
// This range has a different prefix, so will be in a different suffix table.
- range3 = new S2LevelRange(
+ range3 = new SuffixTableRange(
TestUtils.createCellId(fileFormat, 1, 1001, 1000),
TestUtils.createCellId(fileFormat, 1, 1001, 2000));
- List<S2LevelRange> ranges = new ArrayList<>();
+ List<SuffixTableRange> ranges = new ArrayList<>();
+ ranges.add(range1);
+ ranges.add(range2);
+ ranges.add(range3);
+ satS2RangeFileWriter.createSortedSuffixBlocks(ranges.iterator());
+ }
+ assertTrue(file.length() > 0);
+ return fileFormat;
+ }
+
+ private SatS2RangeFileFormat createSatS2FileWithEntryValue(
+ File file, boolean isAllowedList, List<Integer> entryValues) throws Exception {
+
+ SatS2RangeFileFormat fileFormat;
+ SuffixTableRange range1, range2, range3;
+ try (SatS2RangeFileWriter satS2RangeFileWriter = SatS2RangeFileWriter.open(
+ file, TestUtils.createS2RangeFileFormat(isAllowedList, 4, 1))) {
+ fileFormat = satS2RangeFileWriter.getFileFormat();
+
+ // Two ranges that share a prefix.
+ range1 = new SuffixTableRange(
+ TestUtils.createCellId(fileFormat, 1, 1000, 1000),
+ TestUtils.createCellId(fileFormat, 1, 1000, 2000),
+ entryValues.get(0));
+ range2 = new SuffixTableRange(
+ TestUtils.createCellId(fileFormat, 1, 1000, 2001),
+ TestUtils.createCellId(fileFormat, 1, 1000, 3000),
+ entryValues.get(1));
+ // This range has a different prefix, so will be in a different suffix table.
+ range3 = new SuffixTableRange(
+ TestUtils.createCellId(fileFormat, 1, 1001, 1000),
+ TestUtils.createCellId(fileFormat, 1, 1001, 2000),
+ entryValues.get(2));
+
+ List<SuffixTableRange> ranges = new ArrayList<>();
ranges.add(range1);
ranges.add(range2);
ranges.add(range3);
diff --git a/tests/src/com/android/phone/satellite/accesscontrol/SatelliteAccessControllerTest.java b/tests/src/com/android/phone/satellite/accesscontrol/SatelliteAccessControllerTest.java
index 55f72fc..5c18cc5 100644
--- a/tests/src/com/android/phone/satellite/accesscontrol/SatelliteAccessControllerTest.java
+++ b/tests/src/com/android/phone/satellite/accesscontrol/SatelliteAccessControllerTest.java
@@ -17,6 +17,8 @@
package com.android.phone.satellite.accesscontrol;
import static android.location.LocationManager.MODE_CHANGED_ACTION;
+import static android.telephony.SubscriptionManager.DEFAULT_SUBSCRIPTION_ID;
+import static android.telephony.satellite.SatelliteManager.KEY_SATELLITE_ACCESS_CONFIGURATION;
import static android.telephony.satellite.SatelliteManager.KEY_SATELLITE_COMMUNICATION_ALLOWED;
import static android.telephony.satellite.SatelliteManager.KEY_SATELLITE_PROVISIONED;
import static android.telephony.satellite.SatelliteManager.KEY_SATELLITE_SUPPORTED;
@@ -29,13 +31,17 @@
import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_SUCCESS;
import static com.android.phone.satellite.accesscontrol.SatelliteAccessController.ALLOWED_STATE_CACHE_VALID_DURATION_NANOS;
-import static com.android.phone.satellite.accesscontrol.SatelliteAccessController.EVENT_COUNTRY_CODE_CHANGED;
import static com.android.phone.satellite.accesscontrol.SatelliteAccessController.CMD_IS_SATELLITE_COMMUNICATION_ALLOWED;
import static com.android.phone.satellite.accesscontrol.SatelliteAccessController.DEFAULT_DELAY_MINUTES_BEFORE_VALIDATING_POSSIBLE_CHANGE_IN_ALLOWED_REGION;
+import static com.android.phone.satellite.accesscontrol.SatelliteAccessController.DEFAULT_MAX_RETRY_COUNT_FOR_VALIDATING_POSSIBLE_CHANGE_IN_ALLOWED_REGION;
+import static com.android.phone.satellite.accesscontrol.SatelliteAccessController.DEFAULT_REGIONAL_SATELLITE_CONFIG_ID;
+import static com.android.phone.satellite.accesscontrol.SatelliteAccessController.DEFAULT_S2_LEVEL;
import static com.android.phone.satellite.accesscontrol.SatelliteAccessController.DEFAULT_THROTTLE_INTERVAL_FOR_LOCATION_QUERY_MINUTES;
import static com.android.phone.satellite.accesscontrol.SatelliteAccessController.EVENT_CONFIG_DATA_UPDATED;
+import static com.android.phone.satellite.accesscontrol.SatelliteAccessController.EVENT_COUNTRY_CODE_CHANGED;
+import static com.android.phone.satellite.accesscontrol.SatelliteAccessController.EVENT_WAIT_FOR_CURRENT_LOCATION_TIMEOUT;
import static com.android.phone.satellite.accesscontrol.SatelliteAccessController.GOOGLE_US_SAN_SAT_S2_FILE_NAME;
-import static com.android.phone.satellite.accesscontrol.SatelliteAccessController.DEFAULT_MAX_RETRY_COUNT_FOR_VALIDATING_POSSIBLE_CHANGE_IN_ALLOWED_REGION;
+import static com.android.phone.satellite.accesscontrol.SatelliteAccessController.UNKNOWN_REGIONAL_SATELLITE_CONFIG_ID;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -49,6 +55,7 @@
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doNothing;
@@ -61,26 +68,38 @@
import static org.mockito.Mockito.when;
import android.annotation.Nullable;
+import android.app.NotificationManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
import android.content.res.Resources;
import android.location.Location;
import android.location.LocationManager;
import android.location.LocationRequest;
import android.os.AsyncResult;
+import android.os.Build;
import android.os.Bundle;
import android.os.CancellationSignal;
import android.os.DropBoxManager;
import android.os.Handler;
import android.os.HandlerThread;
+import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
+import android.os.Parcel;
import android.os.ResultReceiver;
+import android.os.UserHandle;
import android.telecom.TelecomManager;
import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
+import android.telephony.satellite.ISatelliteCommunicationAllowedStateCallback;
+import android.telephony.satellite.SatelliteAccessConfiguration;
+import android.telephony.satellite.SatelliteInfo;
import android.telephony.satellite.SatelliteManager;
import android.testing.TestableLooper;
import android.util.Log;
@@ -115,6 +134,7 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executor;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
@@ -179,14 +199,30 @@
@Mock
private SharedPreferences.Editor mMockSharedPreferencesEditor;
@Mock
- private Map<SatelliteOnDeviceAccessController.LocationToken, Boolean>
+ private Map<SatelliteOnDeviceAccessController.LocationToken, Integer>
mMockCachedAccessRestrictionMap;
@Mock
+ HashMap<Integer, SatelliteAccessConfiguration> mMockSatelliteAccessConfigMap;
+
+ @Mock
private Intent mMockLocationIntent;
@Mock
private Set<ResultReceiver> mMockSatelliteAllowResultReceivers;
@Mock
- private ResultReceiver mMockSatelliteSupportedResultReceiver;
+ private TelephonyManager mMockTelephonyManager;
+ @Mock
+ private PackageManager mMockPackageManager;
+ @Mock
+ private List<ResolveInfo> mMockResolveInfoList;
+ @Mock
+ private NotificationManager mMockNotificationManager;
+ @Mock
+ private ApplicationInfo mMockApplicationInfo;
+ @Mock
+ private ResultReceiver mMockResultReceiver;
+ @Mock
+ private ConcurrentHashMap<IBinder, ISatelliteCommunicationAllowedStateCallback>
+ mSatelliteCommunicationAllowedStateCallbackMap;
private Looper mLooper;
private TestableLooper mTestableLooper;
@@ -221,6 +257,8 @@
private ArgumentCaptor<Integer> mResultCodeIntCaptor;
@Captor
private ArgumentCaptor<Bundle> mResultDataBundleCaptor;
+ @Captor
+ private ArgumentCaptor<ISatelliteCommunicationAllowedStateCallback> mAllowedStateCallbackCaptor;
private boolean mQueriedSatelliteAllowed = false;
private int mQueriedSatelliteAllowedResultCode = SATELLITE_RESULT_SUCCESS;
@@ -284,6 +322,7 @@
mMockCountryDetector);
when(mMockSatelliteController.getSatellitePhone()).thenReturn(mMockPhone);
when(mMockPhone.getSubId()).thenReturn(SubscriptionManager.getDefaultSubscriptionId());
+
when(mMockContext.getResources()).thenReturn(mMockResources);
when(mMockResources.getStringArray(
com.android.internal.R.array.config_oem_enabled_satellite_country_codes))
@@ -318,8 +357,9 @@
when(mMockLocation0.getLongitude()).thenReturn(0.0);
when(mMockLocation1.getLatitude()).thenReturn(1.0);
when(mMockLocation1.getLongitude()).thenReturn(1.0);
- when(mMockSatelliteOnDeviceAccessController.isSatCommunicationAllowedAtLocation(
- any(SatelliteOnDeviceAccessController.LocationToken.class))).thenReturn(true);
+ when(mMockSatelliteOnDeviceAccessController.getRegionalConfigIdForLocation(
+ any(SatelliteOnDeviceAccessController.LocationToken.class)))
+ .thenReturn(DEFAULT_REGIONAL_SATELLITE_CONFIG_ID);
when(mMockContext.getSharedPreferences(anyString(), anyInt())).thenReturn(
mMockSharedPreferences);
@@ -338,7 +378,24 @@
when(mMockFeatureFlags.satellitePersistentLogging()).thenReturn(true);
when(mMockFeatureFlags.geofenceEnhancementForBetterUx()).thenReturn(true);
when(mMockFeatureFlags.oemEnabledSatelliteFlag()).thenReturn(true);
+ when(mMockFeatureFlags.carrierRoamingNbIotNtn()).thenReturn(true);
+ when(mMockContext.getSystemService(Context.TELEPHONY_SERVICE))
+ .thenReturn(mMockTelephonyManager);
+ when(mMockTelephonyManager.isSmsCapable()).thenReturn(true);
+ when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager);
+ mMockResolveInfoList = new ArrayList<>();
+ when(mMockPackageManager.queryBroadcastReceiversAsUser(any(Intent.class), anyInt(), any(
+ UserHandle.class)))
+ .thenReturn(mMockResolveInfoList);
+ when(mMockContext.getSystemServiceName(
+ NotificationManager.class)).thenReturn(Context.NOTIFICATION_SERVICE);
+ when(mMockContext.getSystemService(Context.NOTIFICATION_SERVICE))
+ .thenReturn(mMockNotificationManager);
+ when(mMockContext.getApplicationInfo()).thenReturn(mMockApplicationInfo);
+ mMockApplicationInfo.targetSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE;
+ when(mMockPackageManager.getApplicationInfo(anyString(), anyInt()))
+ .thenReturn(mMockApplicationInfo);
mSatelliteAccessControllerUT = new TestSatelliteAccessController(mMockContext,
mMockFeatureFlags, mLooper, mMockLocationManager, mMockTelecomManager,
mMockSatelliteOnDeviceAccessController, mMockSatS2File);
@@ -369,6 +426,49 @@
}
@Test
+ public void testOnCurrentLocationNotAvailable() throws Exception {
+ // Verify the cache is used when the location is null and the cache is valid and true.
+ mSatelliteAccessControllerUT.elapsedRealtimeNanos =
+ ALLOWED_STATE_CACHE_VALID_DURATION_NANOS - 1;
+ mSatelliteAccessControllerUT
+ .setIsSatelliteCommunicationAllowedForCurrentLocationCache("cache_allowed");
+ mSatelliteAccessControllerUT.setLocationRequestCancellationSignalAsNull(false);
+
+ sendCurrentLocationTimeoutEvent();
+ assertTrue(mSatelliteAccessControllerUT.isCurrentSatelliteAllowedState());
+
+ // Verify the cache is used when the location is null and the cache is valid and false.
+ mSatelliteAccessControllerUT
+ .setIsSatelliteCommunicationAllowedForCurrentLocationCache("cache_not_allowed");
+ mSatelliteAccessControllerUT.setLocationRequestCancellationSignalAsNull(false);
+
+ sendCurrentLocationTimeoutEvent();
+ assertFalse(mSatelliteAccessControllerUT.isCurrentSatelliteAllowedState());
+
+ // Verify the result code is SATELLITE_RESULT_LOCATION_NOT_AVAILABLE
+ // and allowedState is false when the location is null and the cache is expired
+ mSatelliteAccessControllerUT.elapsedRealtimeNanos =
+ ALLOWED_STATE_CACHE_VALID_DURATION_NANOS + 1;
+ Iterator<ResultReceiver> mockResultReceiverIterator = mock(Iterator.class);
+ doReturn(mockResultReceiverIterator).when(mMockSatelliteAllowResultReceivers).iterator();
+ doReturn(true, false).when(mockResultReceiverIterator).hasNext();
+ doNothing().when(mMockSatelliteAllowResultReceivers).clear();
+ doReturn(mMockResultReceiver).when(mockResultReceiverIterator).next();
+ replaceInstance(SatelliteAccessController.class, "mSatelliteAllowResultReceivers",
+ mSatelliteAccessControllerUT, mMockSatelliteAllowResultReceivers);
+ mSatelliteAccessControllerUT.setIsSatelliteCommunicationAllowedForCurrentLocationCache(
+ "cache_clear_and_not_allowed");
+ mSatelliteAccessControllerUT.setLocationRequestCancellationSignalAsNull(false);
+
+ sendCurrentLocationTimeoutEvent();
+ verify(mMockResultReceiver)
+ .send(mResultCodeIntCaptor.capture(), any());
+ assertEquals(Integer.valueOf(SATELLITE_RESULT_LOCATION_NOT_AVAILABLE),
+ mResultCodeIntCaptor.getValue());
+ assertFalse(mSatelliteAccessControllerUT.isCurrentSatelliteAllowedState());
+ }
+
+ @Test
public void testIsSatelliteAccessAllowedForLocation() {
when(mMockFeatureFlags.oemEnabledSatelliteFlag()).thenReturn(true);
@@ -398,7 +498,7 @@
assertFalse(mSatelliteAccessControllerUT
.isSatelliteAccessAllowedForLocation(List.of(TEST_SATELLITE_COUNTRY_CODE_US)));
assertFalse(mSatelliteAccessControllerUT.isSatelliteAccessAllowedForLocation(
- List.of(TEST_SATELLITE_COUNTRY_CODE_US, TEST_SATELLITE_COUNTRY_CODE_KR)));
+ List.of(TEST_SATELLITE_COUNTRY_CODE_US, TEST_SATELLITE_COUNTRY_CODE_KR)));
assertTrue(mSatelliteAccessControllerUT
.isSatelliteAccessAllowedForLocation(List.of(TEST_SATELLITE_COUNTRY_CODE_KR)));
@@ -433,6 +533,314 @@
.isSatelliteAccessAllowedForLocation(List.of(TEST_SATELLITE_COUNTRY_CODE_US)));
}
+
+ private void setSatelliteCommunicationAllowed() throws Exception {
+ when(mMockContext.getResources()).thenReturn(mMockResources);
+ when(mMockResources.getBoolean(
+ com.android.internal.R.bool.config_oem_enabled_satellite_access_allow))
+ .thenReturn(TEST_SATELLITE_ALLOW);
+ setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_RESULT_SUCCESS);
+ setUpResponseForRequestIsSatelliteProvisioned(true, SATELLITE_RESULT_SUCCESS);
+ doReturn(true).when(mMockLocationManager).isLocationEnabled();
+ when(mMockSatelliteOnDeviceAccessController.getRegionalConfigIdForLocation(
+ any(SatelliteOnDeviceAccessController.LocationToken.class)))
+ .thenReturn(DEFAULT_REGIONAL_SATELLITE_CONFIG_ID);
+ replaceInstance(SatelliteAccessController.class, "mCachedAccessRestrictionMap",
+ mSatelliteAccessControllerUT, mMockCachedAccessRestrictionMap);
+ doReturn(true).when(mMockCachedAccessRestrictionMap).containsKey(any());
+ doReturn(DEFAULT_REGIONAL_SATELLITE_CONFIG_ID)
+ .when(mMockCachedAccessRestrictionMap).get(any());
+ }
+
+ @Test
+ public void testRequestSatelliteAccessConfigurationForCurrentLocation() throws Exception {
+ // setup result receiver and satellite access configuration data
+ ResultReceiver mockResultReceiver = mock(ResultReceiver.class);
+ ArgumentCaptor<Integer> resultCodeCaptor = ArgumentCaptor.forClass(Integer.class);
+ ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
+ SatelliteAccessConfiguration satelliteAccessConfig = getSatelliteAccessConfiguration();
+
+ // setup satellite communication allwed state as true
+ setSatelliteCommunicationAllowed();
+
+ // setup map data of location and configId.
+ replaceInstance(SatelliteAccessController.class, "mSatelliteAccessConfigMap",
+ mSatelliteAccessControllerUT, mMockSatelliteAccessConfigMap);
+ doReturn(satelliteAccessConfig).when(mMockSatelliteAccessConfigMap).get(anyInt());
+ doReturn(null).when(mMockSatelliteAccessConfigMap).get(eq(null));
+ doReturn(null).when(mMockSatelliteAccessConfigMap)
+ .get(eq(UNKNOWN_REGIONAL_SATELLITE_CONFIG_ID));
+
+ // setup callback
+ ISatelliteCommunicationAllowedStateCallback mockSatelliteAllowedStateCallback = mock(
+ ISatelliteCommunicationAllowedStateCallback.class);
+ ArgumentCaptor<SatelliteAccessConfiguration> satelliteAccessConfigurationCaptor =
+ ArgumentCaptor.forClass(SatelliteAccessConfiguration.class);
+
+ when(mSatelliteCommunicationAllowedStateCallbackMap.values())
+ .thenReturn(List.of(mockSatelliteAllowedStateCallback));
+ replaceInstance(SatelliteAccessController.class,
+ "mSatelliteCommunicationAllowedStateChangedListeners", mSatelliteAccessControllerUT,
+ mSatelliteCommunicationAllowedStateCallbackMap);
+
+ // Test when the featureFlags.carrierRoamingNbIotNtn() is false
+ doReturn(false).when(mMockFeatureFlags).carrierRoamingNbIotNtn();
+
+ clearInvocations(mockResultReceiver);
+ mSatelliteAccessControllerUT
+ .requestSatelliteAccessConfigurationForCurrentLocation(mockResultReceiver);
+ mTestableLooper.processAllMessages();
+ verify(mockResultReceiver, times(1)).send(resultCodeCaptor.capture(),
+ bundleCaptor.capture());
+ assertEquals(SATELLITE_RESULT_REQUEST_NOT_SUPPORTED, (int) resultCodeCaptor.getValue());
+ assertNull(bundleCaptor.getValue());
+ verify(mockSatelliteAllowedStateCallback, never())
+ .onSatelliteAccessConfigurationChanged(any());
+
+ doReturn(true).when(mMockFeatureFlags).carrierRoamingNbIotNtn();
+
+ // satellite communication allowed state is enabled and
+ // regional config id is DEFAULT_REGIONAL_SATELLITE_CONFIG_ID.
+ clearInvocations(mockResultReceiver);
+ clearInvocations(mockSatelliteAllowedStateCallback);
+ mSatelliteAccessControllerUT
+ .requestSatelliteAccessConfigurationForCurrentLocation(mockResultReceiver);
+ mTestableLooper.processAllMessages();
+ verify(mockResultReceiver, times(1)).send(resultCodeCaptor.capture(),
+ bundleCaptor.capture());
+ assertEquals(SatelliteManager.SATELLITE_RESULT_SUCCESS, (int) resultCodeCaptor.getValue());
+ assertTrue(bundleCaptor.getValue().containsKey(KEY_SATELLITE_ACCESS_CONFIGURATION));
+ assertSame(bundleCaptor.getValue().getParcelable(KEY_SATELLITE_ACCESS_CONFIGURATION,
+ SatelliteAccessConfiguration.class), satelliteAccessConfig);
+ verify(mockSatelliteAllowedStateCallback, times(1))
+ .onSatelliteAccessConfigurationChanged(
+ satelliteAccessConfigurationCaptor.capture());
+ assertEquals(satelliteAccessConfigurationCaptor.getValue(), satelliteAccessConfig);
+
+ // satellite communication allowed state is disabled and
+ // regional config id is null.
+ clearInvocations(mockResultReceiver);
+ clearInvocations(mockSatelliteAllowedStateCallback);
+ when(mMockCachedAccessRestrictionMap.get(any())).thenReturn(null);
+ mSatelliteAccessControllerUT
+ .requestSatelliteAccessConfigurationForCurrentLocation(mockResultReceiver);
+ mTestableLooper.processAllMessages();
+
+ verify(mockResultReceiver, times(1)).send(resultCodeCaptor.capture(),
+ bundleCaptor.capture());
+ assertEquals(SATELLITE_RESULT_SUCCESS, (int) resultCodeCaptor.getValue());
+ assertTrue(bundleCaptor.getValue().containsKey(KEY_SATELLITE_ACCESS_CONFIGURATION));
+ assertNull(bundleCaptor.getValue().getParcelable(KEY_SATELLITE_ACCESS_CONFIGURATION,
+ SatelliteAccessConfiguration.class));
+ verify(mockSatelliteAllowedStateCallback, times(1))
+ .onSatelliteAccessConfigurationChanged(
+ satelliteAccessConfigurationCaptor.capture());
+ assertNull(satelliteAccessConfigurationCaptor.getValue());
+ }
+
+ private SatelliteAccessConfiguration getSatelliteAccessConfiguration() {
+ Parcel satelliteAccessconfigParcel = Parcel.obtain();
+
+ List<SatelliteInfo> satelliteInfoList = new ArrayList<>();
+ satelliteInfoList.add(mock(SatelliteInfo.class));
+ satelliteAccessconfigParcel.writeTypedList(satelliteInfoList);
+
+ List<Integer> tagIds = new ArrayList<>(List.of(1, 2));
+ satelliteAccessconfigParcel.writeList(tagIds);
+
+ return new SatelliteAccessConfiguration(satelliteAccessconfigParcel);
+ }
+
+ @Test
+ public void testRegisterForCommunicationAllowedStateChanged() throws Exception {
+ ISatelliteCommunicationAllowedStateCallback mockSatelliteAllowedStateCallback = mock(
+ ISatelliteCommunicationAllowedStateCallback.class);
+ doReturn(true).when(mSatelliteCommunicationAllowedStateCallbackMap)
+ .put(any(IBinder.class), any(ISatelliteCommunicationAllowedStateCallback.class));
+ replaceInstance(SatelliteAccessController.class,
+ "mSatelliteCommunicationAllowedStateChangedListeners", mSatelliteAccessControllerUT,
+ mSatelliteCommunicationAllowedStateCallbackMap);
+
+ doReturn(false).when(mMockFeatureFlags).oemEnabledSatelliteFlag();
+ int result = mSatelliteAccessControllerUT.registerForCommunicationAllowedStateChanged(
+ DEFAULT_SUBSCRIPTION_ID, mockSatelliteAllowedStateCallback);
+ mTestableLooper.processAllMessages();
+ assertEquals(SATELLITE_RESULT_REQUEST_NOT_SUPPORTED, result);
+ verify(mockSatelliteAllowedStateCallback, never())
+ .onSatelliteCommunicationAllowedStateChanged(anyBoolean());
+ verify(mockSatelliteAllowedStateCallback, never())
+ .onSatelliteAccessConfigurationChanged(any(SatelliteAccessConfiguration.class));
+
+ doReturn(true).when(mMockFeatureFlags).oemEnabledSatelliteFlag();
+ result = mSatelliteAccessControllerUT.registerForCommunicationAllowedStateChanged(
+ DEFAULT_SUBSCRIPTION_ID, mockSatelliteAllowedStateCallback);
+ mTestableLooper.processAllMessages();
+ assertEquals(SATELLITE_RESULT_SUCCESS, result);
+ verify(mockSatelliteAllowedStateCallback, times(1))
+ .onSatelliteCommunicationAllowedStateChanged(anyBoolean());
+ verify(mockSatelliteAllowedStateCallback, times(1))
+ .onSatelliteAccessConfigurationChanged(
+ nullable(SatelliteAccessConfiguration.class));
+ }
+
+ @Test
+ public void testNotifyRegionalSatelliteConfigurationChanged() throws Exception {
+ // setup test
+ ISatelliteCommunicationAllowedStateCallback mockSatelliteAllowedStateCallback = mock(
+ ISatelliteCommunicationAllowedStateCallback.class);
+ ArgumentCaptor<SatelliteAccessConfiguration> satelliteAccessConfigurationCaptor =
+ ArgumentCaptor.forClass(SatelliteAccessConfiguration.class);
+
+ when(mSatelliteCommunicationAllowedStateCallbackMap.values())
+ .thenReturn(List.of(mockSatelliteAllowedStateCallback));
+ replaceInstance(SatelliteAccessController.class,
+ "mSatelliteCommunicationAllowedStateChangedListeners", mSatelliteAccessControllerUT,
+ mSatelliteCommunicationAllowedStateCallbackMap);
+
+ // register callback
+ mSatelliteAccessControllerUT.registerForCommunicationAllowedStateChanged(
+ DEFAULT_SUBSCRIPTION_ID, mockSatelliteAllowedStateCallback);
+
+ // verify if the callback is
+ // the same instance from onmSatelliteCommunicationAllowedStateCallbackMap
+ verify(mSatelliteCommunicationAllowedStateCallbackMap).put(any(),
+ mAllowedStateCallbackCaptor.capture());
+ assertSame(mockSatelliteAllowedStateCallback, mAllowedStateCallbackCaptor.getValue());
+
+ // create SatelliteAccessConfiguration data for this test
+ SatelliteAccessConfiguration satelliteAccessConfig = getSatelliteAccessConfiguration();
+
+ // trigger notifyRegionalSatelliteConfigurationChanged
+ mSatelliteAccessControllerUT
+ .notifyRegionalSatelliteConfigurationChanged(satelliteAccessConfig);
+
+ // verify if the satelliteAccessConfig is the same instance with the captured one.
+ verify(mockSatelliteAllowedStateCallback).onSatelliteAccessConfigurationChanged(
+ satelliteAccessConfigurationCaptor.capture());
+ assertSame(satelliteAccessConfig, satelliteAccessConfigurationCaptor.getValue());
+ }
+
+ @Test
+ public void testCheckSatelliteAccessRestrictionForLocation() throws Exception {
+ // Setup
+ logd("testCheckSatelliteAccessRestrictionForLocation : setup");
+ ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
+ ArgumentCaptor<Integer> regionalConfigIdCaptor = ArgumentCaptor.forClass(Integer.class);
+ replaceInstance(SatelliteAccessController.class, "mS2Level",
+ mSatelliteAccessControllerUT, DEFAULT_S2_LEVEL);
+ Iterator<ResultReceiver> mockResultReceiverIterator = mock(Iterator.class);
+ mSatelliteAccessControllerUT.setRegionalConfigId(null);
+
+ doReturn(mockResultReceiverIterator).when(mMockSatelliteAllowResultReceivers).iterator();
+ doReturn(true, false).when(mockResultReceiverIterator).hasNext();
+ doNothing().when(mMockSatelliteAllowResultReceivers).clear();
+ doReturn(mMockResultReceiver).when(mockResultReceiverIterator).next();
+ replaceInstance(SatelliteAccessController.class, "mSatelliteAllowResultReceivers",
+ mSatelliteAccessControllerUT, mMockSatelliteAllowResultReceivers);
+ replaceInstance(SatelliteAccessController.class, "mCachedAccessRestrictionMap",
+ mSatelliteAccessControllerUT, mMockCachedAccessRestrictionMap);
+
+ // when mMockCachedAccessRestrictionMap is hit and has DEFAULT_REGIONAL_SATELLITE_CONFIG_ID,
+ // verify belows
+ // - the bundle data of KEY_SATELLITE_COMMUNICATION_ALLOWED is true
+ // - the newRegionalConfigId is the same as DEFAULT_REGIONAL_SATELLITE_CONFIG_ID
+ // - the regionalConfigId is the same as DEFAULT_REGIONAL_SATELLITE_CONFIG_ID
+ logd("testCheckSatelliteAccessRestrictionForLocation : case 1");
+ clearInvocations(mMockSatelliteOnDeviceAccessController);
+ clearInvocations(mMockCachedAccessRestrictionMap);
+
+ doReturn(true).when(mMockCachedAccessRestrictionMap)
+ .containsKey(any(SatelliteOnDeviceAccessController.LocationToken.class));
+ doReturn(DEFAULT_REGIONAL_SATELLITE_CONFIG_ID).when(mMockCachedAccessRestrictionMap)
+ .get(any(SatelliteOnDeviceAccessController.LocationToken.class));
+
+ mSatelliteAccessControllerUT.checkSatelliteAccessRestrictionForLocation(mMockLocation0);
+ verify(mMockResultReceiver, times(1))
+ .send(mResultCodeIntCaptor.capture(), bundleCaptor.capture());
+ verify(mMockSatelliteOnDeviceAccessController, never()).getRegionalConfigIdForLocation(
+ any(SatelliteOnDeviceAccessController.LocationToken.class));
+ assertEquals(Integer.valueOf(SATELLITE_RESULT_SUCCESS), mResultCodeIntCaptor.getValue());
+ assertTrue(bundleCaptor.getValue().getBoolean(KEY_SATELLITE_COMMUNICATION_ALLOWED));
+ assertEquals(Integer.valueOf(DEFAULT_REGIONAL_SATELLITE_CONFIG_ID),
+ mSatelliteAccessControllerUT.getNewRegionalConfigId());
+ assertEquals(Integer.valueOf(DEFAULT_REGIONAL_SATELLITE_CONFIG_ID),
+ mSatelliteAccessControllerUT.getRegionalConfigId());
+
+ // when mMockCachedAccessRestrictionMap is not hit and regionalConfigId is null
+ // verify belows
+ // - the bundle data of KEY_SATELLITE_COMMUNICATION_ALLOWED is false
+ // - the regionalConfigId is null
+ logd("testCheckSatelliteAccessRestrictionForLocation : case 2");
+ clearInvocations(mMockCachedAccessRestrictionMap);
+ doReturn(false).when(mMockCachedAccessRestrictionMap)
+ .containsKey(any(SatelliteOnDeviceAccessController.LocationToken.class));
+ doReturn(true, false).when(mockResultReceiverIterator).hasNext();
+ when(mMockSatelliteOnDeviceAccessController.getRegionalConfigIdForLocation(
+ any(SatelliteOnDeviceAccessController.LocationToken.class)))
+ .thenReturn(null);
+
+ mSatelliteAccessControllerUT.checkSatelliteAccessRestrictionForLocation(mMockLocation0);
+ verify(mMockResultReceiver, times(2))
+ .send(mResultCodeIntCaptor.capture(), bundleCaptor.capture());
+ assertEquals(Integer.valueOf(SATELLITE_RESULT_SUCCESS), mResultCodeIntCaptor.getValue());
+ assertFalse(bundleCaptor.getValue().getBoolean(KEY_SATELLITE_COMMUNICATION_ALLOWED));
+ verify(mMockCachedAccessRestrictionMap, times(1))
+ .put(any(), regionalConfigIdCaptor.capture());
+ assertNull(regionalConfigIdCaptor.getValue());
+ assertNull(mSatelliteAccessControllerUT.getNewRegionalConfigId());
+ assertNull(mSatelliteAccessControllerUT.getRegionalConfigId());
+
+ // when mMockCachedAccessRestrictionMap is not hit and
+ // regionalConfigId is DEFAULT_REGIONAL_SATELLITE_CONFIG_ID
+ // verify belows
+ // - the bundle data of KEY_SATELLITE_COMMUNICATION_ALLOWED is true
+ // - the regionalConfigId is DEFAULT_REGIONAL_SATELLITE_CONFIG_ID
+ logd("testCheckSatelliteAccessRestrictionForLocation : case 3");
+ clearInvocations(mMockCachedAccessRestrictionMap);
+ when(mMockSatelliteOnDeviceAccessController.getRegionalConfigIdForLocation(
+ any(SatelliteOnDeviceAccessController.LocationToken.class)))
+ .thenReturn(DEFAULT_REGIONAL_SATELLITE_CONFIG_ID);
+ doReturn(true, false).when(mockResultReceiverIterator).hasNext();
+
+ mSatelliteAccessControllerUT.checkSatelliteAccessRestrictionForLocation(mMockLocation0);
+ verify(mMockResultReceiver, times(3))
+ .send(mResultCodeIntCaptor.capture(), bundleCaptor.capture());
+ assertEquals(Integer.valueOf(SATELLITE_RESULT_SUCCESS), mResultCodeIntCaptor.getValue());
+ assertTrue(bundleCaptor.getValue().getBoolean(KEY_SATELLITE_COMMUNICATION_ALLOWED));
+ verify(mMockCachedAccessRestrictionMap, times(1))
+ .put(any(), regionalConfigIdCaptor.capture());
+
+ assertEquals(Integer.valueOf(DEFAULT_REGIONAL_SATELLITE_CONFIG_ID),
+ regionalConfigIdCaptor.getValue());
+ assertEquals(Integer.valueOf(DEFAULT_REGIONAL_SATELLITE_CONFIG_ID),
+ mSatelliteAccessControllerUT.getNewRegionalConfigId());
+ assertEquals(Integer.valueOf(DEFAULT_REGIONAL_SATELLITE_CONFIG_ID),
+ mSatelliteAccessControllerUT.getRegionalConfigId());
+
+
+ // when mMockCachedAccessRestrictionMap is not hit and regionalConfigId is null
+ // verify belows
+ // - the bundle data of KEY_SATELLITE_COMMUNICATION_ALLOWED is false
+ // - the regionalConfigId is null
+ logd("testCheckSatelliteAccessRestrictionForLocation : case 4");
+ clearInvocations(mMockCachedAccessRestrictionMap);
+ when(mMockSatelliteOnDeviceAccessController.getRegionalConfigIdForLocation(
+ any(SatelliteOnDeviceAccessController.LocationToken.class)))
+ .thenReturn(null);
+ doReturn(true, false).when(mockResultReceiverIterator).hasNext();
+
+ mSatelliteAccessControllerUT.checkSatelliteAccessRestrictionForLocation(mMockLocation0);
+ verify(mMockResultReceiver, times(4))
+ .send(mResultCodeIntCaptor.capture(), bundleCaptor.capture());
+ assertEquals(Integer.valueOf(SATELLITE_RESULT_SUCCESS), mResultCodeIntCaptor.getValue());
+ assertFalse(bundleCaptor.getValue().getBoolean(KEY_SATELLITE_COMMUNICATION_ALLOWED));
+ verify(mMockCachedAccessRestrictionMap, times(1))
+ .put(any(), regionalConfigIdCaptor.capture());
+ assertNull(regionalConfigIdCaptor.getValue());
+ assertNull(mSatelliteAccessControllerUT.getNewRegionalConfigId());
+ assertNull(mSatelliteAccessControllerUT.getRegionalConfigId());
+ }
+
@Test
public void testIsRegionDisallowed() throws Exception {
// setup to make the return value of mQueriedSatelliteAllowed 'true'
@@ -444,12 +852,14 @@
setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_RESULT_SUCCESS);
setUpResponseForRequestIsSatelliteProvisioned(true, SATELLITE_RESULT_SUCCESS);
doReturn(true).when(mMockLocationManager).isLocationEnabled();
- when(mMockSatelliteOnDeviceAccessController.isSatCommunicationAllowedAtLocation(
- any(SatelliteOnDeviceAccessController.LocationToken.class))).thenReturn(true);
+ when(mMockSatelliteOnDeviceAccessController.getRegionalConfigIdForLocation(
+ any(SatelliteOnDeviceAccessController.LocationToken.class)))
+ .thenReturn(DEFAULT_REGIONAL_SATELLITE_CONFIG_ID);
replaceInstance(SatelliteAccessController.class, "mCachedAccessRestrictionMap",
mSatelliteAccessControllerUT, mMockCachedAccessRestrictionMap);
doReturn(true).when(mMockCachedAccessRestrictionMap).containsKey(any());
- doReturn(true).when(mMockCachedAccessRestrictionMap).get(any());
+ doReturn(DEFAULT_REGIONAL_SATELLITE_CONFIG_ID)
+ .when(mMockCachedAccessRestrictionMap).get(any());
// get allowed country codes EMPTY from resources
when(mMockResources.getStringArray(
@@ -681,7 +1091,7 @@
mTestableLooper.processAllMessages();
assertTrue(
mSatelliteAccessControllerUT.isKeepOnDeviceAccessControllerResourcesTimerStarted());
- verify(mMockSatelliteOnDeviceAccessController).isSatCommunicationAllowedAtLocation(
+ verify(mMockSatelliteOnDeviceAccessController).getRegionalConfigIdForLocation(
any(SatelliteOnDeviceAccessController.LocationToken.class));
assertTrue(waitForRequestIsSatelliteAllowedForCurrentLocationResult(
mSatelliteAllowedSemaphore, 1));
@@ -726,7 +1136,7 @@
sendLocationRequestResult(mMockLocation0);
assertFalse(mSatelliteAccessControllerUT.isWaitForCurrentLocationTimerStarted());
// The LocationToken should be already in the cache
- verify(mMockSatelliteOnDeviceAccessController, never()).isSatCommunicationAllowedAtLocation(
+ verify(mMockSatelliteOnDeviceAccessController, never()).getRegionalConfigIdForLocation(
any(SatelliteOnDeviceAccessController.LocationToken.class));
assertTrue(waitForRequestIsSatelliteAllowedForCurrentLocationResult(
mSatelliteAllowedSemaphore, 1));
@@ -758,7 +1168,7 @@
mSatelliteAccessControllerUT.getWaitForCurrentLocationTimeoutMillis());
mTestableLooper.processAllMessages();
assertFalse(mSatelliteAccessControllerUT.isWaitForCurrentLocationTimerStarted());
- verify(mMockSatelliteOnDeviceAccessController, never()).isSatCommunicationAllowedAtLocation(
+ verify(mMockSatelliteOnDeviceAccessController, never()).getRegionalConfigIdForLocation(
any(SatelliteOnDeviceAccessController.LocationToken.class));
assertTrue(waitForRequestIsSatelliteAllowedForCurrentLocationResult(
mSatelliteAllowedSemaphore, 1));
@@ -784,7 +1194,7 @@
verify(mMockLocationManager, never()).getCurrentLocation(anyString(),
any(LocationRequest.class), any(CancellationSignal.class), any(Executor.class),
any(Consumer.class));
- verify(mMockSatelliteOnDeviceAccessController, never()).isSatCommunicationAllowedAtLocation(
+ verify(mMockSatelliteOnDeviceAccessController, never()).getRegionalConfigIdForLocation(
any(SatelliteOnDeviceAccessController.LocationToken.class));
assertTrue(waitForRequestIsSatelliteAllowedForCurrentLocationResult(
mSatelliteAllowedSemaphore, 1));
@@ -793,6 +1203,91 @@
}
@Test
+ public void testLocationQueryThrottleTimeUpdate() {
+ long firstMccChangedTime = 1;
+ long lastKnownLocationElapsedRealtime =
+ firstMccChangedTime + TEST_LOCATION_QUERY_THROTTLE_INTERVAL_NANOS;
+
+ // OEM-enabled satellite is supported
+ when(mMockFeatureFlags.oemEnabledSatelliteFlag()).thenReturn(true);
+
+ verify(mMockCountryDetector).registerForCountryCodeChanged(
+ mCountryDetectorHandlerCaptor.capture(), mCountryDetectorIntCaptor.capture(),
+ mCountryDetectorObjCaptor.capture());
+
+ assertSame(mCountryDetectorHandlerCaptor.getValue(), mSatelliteAccessControllerUT);
+ assertSame(mCountryDetectorIntCaptor.getValue(), EVENT_COUNTRY_CODE_CHANGED);
+ assertNull(mCountryDetectorObjCaptor.getValue());
+
+ // Setup to invoke GPS query
+ clearInvocations(mMockSatelliteOnDeviceAccessController);
+ setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_RESULT_SUCCESS);
+ setUpResponseForRequestIsSatelliteProvisioned(true, SATELLITE_RESULT_SUCCESS);
+ doReturn(true).when(mMockLocationManager).isLocationEnabled();
+ when(mMockLocationManager.getLastKnownLocation(LocationManager.FUSED_PROVIDER))
+ .thenReturn(null);
+ when(mMockLocationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER))
+ .thenReturn(null);
+
+ // When mcc changed first, so queried a location with GPS,
+ // verify if the mLastLocationQueryForPossibleChangeInAllowedRegionTimeNanos
+ // is the same with firstMccChangedTime.
+ // verify mMockLocationManager.getCurrentLocation() is invoked
+ // verify time(mLastLocationQueryForPossibleChangeInAllowedRegionTimeNanos) is
+ // firstMccChangedTime
+ clearInvocations(mMockLocationManager);
+ mSatelliteAccessControllerUT.elapsedRealtimeNanos = firstMccChangedTime;
+ sendCommandValidateCountryCodeChangeEvent(mMockContext);
+ verify(mMockLocationManager, times(1))
+ .getCurrentLocation(any(), any(), any(), any(), any());
+ assertEquals(firstMccChangedTime, mSatelliteAccessControllerUT
+ .mLastLocationQueryForPossibleChangeInAllowedRegionTimeNanos);
+
+ // set current time less than throttle_interval
+ // verify mMockLocationManager.getCurrentLocation() is not invoked
+ // verify time(mLastLocationQueryForPossibleChangeInAllowedRegionTimeNanos) is not updated
+ clearInvocations(mMockLocationManager);
+ doReturn(lastKnownLocationElapsedRealtime).when(mMockLocation1).getElapsedRealtimeNanos();
+ mSatelliteAccessControllerUT.elapsedRealtimeNanos =
+ (firstMccChangedTime + TEST_LOCATION_QUERY_THROTTLE_INTERVAL_NANOS - 1);
+ sendCommandValidateCountryCodeChangeEvent(mMockContext);
+ verify(mMockLocationManager, never())
+ .getCurrentLocation(any(), any(), any(), any(), any());
+ assertEquals(firstMccChangedTime, mSatelliteAccessControllerUT
+ .mLastLocationQueryForPossibleChangeInAllowedRegionTimeNanos);
+
+ // Test the scenario when last know location is fresh and
+ // current time is greater than the location query throttle interval
+ // verify mMockLocationManager.getCurrentLocation() is not invoked
+ // verify time(mLastLocationQueryForPossibleChangeInAllowedRegionTimeNanos) is not updated
+ clearInvocations(mMockLocationManager);
+ doReturn(lastKnownLocationElapsedRealtime).when(mMockLocation1).getElapsedRealtimeNanos();
+ mSatelliteAccessControllerUT.elapsedRealtimeNanos =
+ (lastKnownLocationElapsedRealtime + TEST_LOCATION_FRESH_DURATION_NANOS - 1);
+ sendCommandValidateCountryCodeChangeEvent(mMockContext);
+ verify(mMockLocationManager, never())
+ .getCurrentLocation(any(), any(), any(), any(), any());
+ assertEquals(firstMccChangedTime, mSatelliteAccessControllerUT
+ .mLastLocationQueryForPossibleChangeInAllowedRegionTimeNanos);
+
+ // Test the scenario when last know location is not fresh and
+ // current time is greater than the location query throttle interval
+ // verify mMockLocationManager.getCurrentLocation() is invoked
+ // verify time(mLastLocationQueryForPossibleChangeInAllowedRegionTimeNanos) is updated
+ clearInvocations(mMockLocationManager);
+ mSatelliteAccessControllerUT.setLocationRequestCancellationSignalAsNull(true);
+ mSatelliteAccessControllerUT.elapsedRealtimeNanos =
+ (lastKnownLocationElapsedRealtime + TEST_LOCATION_FRESH_DURATION_NANOS + 1);
+ sendCommandValidateCountryCodeChangeEvent(mMockContext);
+ verify(mMockLocationManager, times(1))
+ .getCurrentLocation(any(), any(), any(), any(), any());
+ assertEquals(lastKnownLocationElapsedRealtime + TEST_LOCATION_FRESH_DURATION_NANOS + 1,
+ mSatelliteAccessControllerUT
+ .mLastLocationQueryForPossibleChangeInAllowedRegionTimeNanos);
+ }
+
+
+ @Test
public void testAllowLocationQueryForSatelliteAllowedCheck() {
mSatelliteAccessControllerUT.mLatestSatelliteCommunicationAllowedSetTime = 1;
@@ -849,7 +1344,7 @@
assertNull(mCountryDetectorObjCaptor.getValue());
// Normal case that invokes
- // mMockSatelliteOnDeviceAccessController.isSatCommunicationAllowedAtLocation
+ // mMockSatelliteOnDeviceAccessController.getRegionalConfigIdForLocation
clearInvocations(mMockSatelliteOnDeviceAccessController);
setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_RESULT_SUCCESS);
setUpResponseForRequestIsSatelliteProvisioned(true, SATELLITE_RESULT_SUCCESS);
@@ -857,14 +1352,14 @@
mSatelliteAccessControllerUT.elapsedRealtimeNanos = TEST_LOCATION_FRESH_DURATION_NANOS;
sendCommandValidateCountryCodeChangeEvent(mMockContext);
verify(mMockSatelliteOnDeviceAccessController,
- times(1)).isSatCommunicationAllowedAtLocation(
+ times(1)).getRegionalConfigIdForLocation(
any(SatelliteOnDeviceAccessController.LocationToken.class));
// Case that isCommunicationAllowedCacheValid is true
clearInvocations(mMockSatelliteOnDeviceAccessController);
mSatelliteAccessControllerUT.elapsedRealtimeNanos = TEST_LOCATION_FRESH_DURATION_NANOS + 1;
sendCommandValidateCountryCodeChangeEvent(mMockContext);
- verify(mMockSatelliteOnDeviceAccessController, never()).isSatCommunicationAllowedAtLocation(
+ verify(mMockSatelliteOnDeviceAccessController, never()).getRegionalConfigIdForLocation(
any(SatelliteOnDeviceAccessController.LocationToken.class));
// Case that mLatestCacheEnforcedValidateTimeNanos is over
@@ -881,11 +1376,11 @@
when(mMockLocation0.getLongitude()).thenReturn(2.0);
when(mMockLocation1.getLatitude()).thenReturn(3.0);
when(mMockLocation1.getLongitude()).thenReturn(3.0);
- when(mMockSatelliteOnDeviceAccessController.isSatCommunicationAllowedAtLocation(
- any(SatelliteOnDeviceAccessController.LocationToken.class))).thenReturn(false);
+ when(mMockSatelliteOnDeviceAccessController.getRegionalConfigIdForLocation(
+ any(SatelliteOnDeviceAccessController.LocationToken.class))).thenReturn(null);
sendCommandValidateCountryCodeChangeEvent(mMockContext);
verify(mMockSatelliteOnDeviceAccessController,
- times(1)).isSatCommunicationAllowedAtLocation(
+ times(1)).getRegionalConfigIdForLocation(
any(SatelliteOnDeviceAccessController.LocationToken.class));
}
@@ -1005,19 +1500,18 @@
.thenReturn(TEST_SATELLITE_ALLOW);
setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_RESULT_SUCCESS);
setUpResponseForRequestIsSatelliteProvisioned(true, SATELLITE_RESULT_SUCCESS);
- when(mMockSatelliteOnDeviceAccessController.isSatCommunicationAllowedAtLocation(
- any(SatelliteOnDeviceAccessController.LocationToken.class))).thenReturn(true);
+ when(mMockSatelliteOnDeviceAccessController.getRegionalConfigIdForLocation(
+ any(SatelliteOnDeviceAccessController.LocationToken.class)))
+ .thenReturn(DEFAULT_REGIONAL_SATELLITE_CONFIG_ID);
replaceInstance(SatelliteAccessController.class, "mCachedAccessRestrictionMap",
mSatelliteAccessControllerUT, mMockCachedAccessRestrictionMap);
doReturn(false).when(mMockCachedAccessRestrictionMap).containsKey(any());
mSatelliteAccessControllerUT.elapsedRealtimeNanos = TEST_LOCATION_FRESH_DURATION_NANOS + 1;
// Captor and Verify if the mockReceiver and mocContext is registered well
- verify(mMockContext).registerReceiver(mLocationBroadcastReceiverCaptor.capture(),
+ verify(mMockContext, times(2))
+ .registerReceiver(mLocationBroadcastReceiverCaptor.capture(),
mIntentFilterCaptor.capture());
- assertSame(mSatelliteAccessControllerUT.getLocationBroadcastReceiver(),
- mLocationBroadcastReceiverCaptor.getValue());
- assertSame(MODE_CHANGED_ACTION, mIntentFilterCaptor.getValue().getAction(0));
// When the intent action is not MODE_CHANGED_ACTION,
// verify if the location manager never invoke isLocationEnabled()
@@ -1056,7 +1550,7 @@
// In emergency case,
// verify if the location manager get FUSED provider and ignore location settings
doReturn(true).when(mMockTelecomManager).isInEmergencyCall();
- mSatelliteAccessControllerUT.setLocationRequestCancellationSignalAsNull();
+ mSatelliteAccessControllerUT.setLocationRequestCancellationSignalAsNull(true);
mSatelliteAccessControllerUT.elapsedRealtimeNanos = TEST_LOCATION_FRESH_DURATION_NANOS + 1;
mSatelliteAccessControllerUT.checkSatelliteAccessRestrictionUsingGPS();
@@ -1074,7 +1568,7 @@
doReturn(false).when(mMockPhone2).isInEcm();
doReturn(false).when(mMockSatelliteController).isInEmergencyMode();
doReturn(true).when(mMockLocationManager).isLocationEnabled();
- mSatelliteAccessControllerUT.setLocationRequestCancellationSignalAsNull();
+ mSatelliteAccessControllerUT.setLocationRequestCancellationSignalAsNull(true);
mSatelliteAccessControllerUT.checkSatelliteAccessRestrictionUsingGPS();
verify(mMockLocationManager, times(1))
@@ -1087,10 +1581,10 @@
@Test
public void testHandleIsSatelliteSupportedResult() throws Exception {
// Setup for this test case
- Iterator<ResultReceiver> mockIterator = mock(Iterator.class);
- doReturn(mockIterator).when(mMockSatelliteAllowResultReceivers).iterator();
- doReturn(true, false).when(mockIterator).hasNext();
- doReturn(mMockSatelliteSupportedResultReceiver).when(mockIterator).next();
+ Iterator<ResultReceiver> mockResultReceiverIterator = mock(Iterator.class);
+ doReturn(mockResultReceiverIterator).when(mMockSatelliteAllowResultReceivers).iterator();
+ doReturn(true, false).when(mockResultReceiverIterator).hasNext();
+ doReturn(mMockResultReceiver).when(mockResultReceiverIterator).next();
replaceInstance(SatelliteAccessController.class, "mSatelliteAllowResultReceivers",
mSatelliteAccessControllerUT, mMockSatelliteAllowResultReceivers);
@@ -1099,10 +1593,10 @@
// case that resultCode is not SATELLITE_RESULT_SUCCESS
int resultCode = SATELLITE_RESULT_ERROR;
Bundle bundle = new Bundle();
- doReturn(true, false).when(mockIterator).hasNext();
- clearInvocations(mMockSatelliteSupportedResultReceiver);
+ doReturn(true, false).when(mockResultReceiverIterator).hasNext();
+ clearInvocations(mMockResultReceiver);
mSatelliteAccessControllerUT.handleIsSatelliteSupportedResult(resultCode, bundle);
- verify(mMockSatelliteSupportedResultReceiver)
+ verify(mMockResultReceiver)
.send(mResultCodeIntCaptor.capture(), any());
assertEquals(Integer.valueOf(SATELLITE_RESULT_ERROR), mResultCodeIntCaptor.getValue());
@@ -1110,20 +1604,19 @@
// verify that the resultCode is delivered as it were
resultCode = SATELLITE_RESULT_SUCCESS;
bundle.putBoolean(KEY_SATELLITE_PROVISIONED, false);
- doReturn(true, false).when(mockIterator).hasNext();
- clearInvocations(mMockSatelliteSupportedResultReceiver);
+ doReturn(true, false).when(mockResultReceiverIterator).hasNext();
+ clearInvocations(mMockResultReceiver);
mSatelliteAccessControllerUT.handleIsSatelliteSupportedResult(resultCode, bundle);
- verify(mMockSatelliteSupportedResultReceiver)
- .send(mResultCodeIntCaptor.capture(), any());
+ verify(mMockResultReceiver).send(mResultCodeIntCaptor.capture(), any());
assertEquals(Integer.valueOf(SATELLITE_RESULT_SUCCESS), mResultCodeIntCaptor.getValue());
// case KEY_SATELLITE_SUPPORTED is false
// verify SATELLITE_RESULT_NOT_SUPPORTED is captured
bundle.putBoolean(KEY_SATELLITE_SUPPORTED, false);
- doReturn(true, false).when(mockIterator).hasNext();
- clearInvocations(mMockSatelliteSupportedResultReceiver);
+ doReturn(true, false).when(mockResultReceiverIterator).hasNext();
+ clearInvocations(mMockResultReceiver);
mSatelliteAccessControllerUT.handleIsSatelliteSupportedResult(resultCode, bundle);
- verify(mMockSatelliteSupportedResultReceiver)
+ verify(mMockResultReceiver)
.send(mResultCodeIntCaptor.capture(), mResultDataBundleCaptor.capture());
assertEquals(Integer.valueOf(SATELLITE_RESULT_NOT_SUPPORTED),
mResultCodeIntCaptor.getValue());
@@ -1135,10 +1628,10 @@
bundle.putBoolean(KEY_SATELLITE_SUPPORTED, true);
when(mMockCountryDetector.getCurrentNetworkCountryIso())
.thenReturn(List.of(TEST_SATELLITE_COUNTRY_CODE_KR));
- doReturn(true, false).when(mockIterator).hasNext();
- clearInvocations(mMockSatelliteSupportedResultReceiver);
+ doReturn(true, false).when(mockResultReceiverIterator).hasNext();
+ clearInvocations(mMockResultReceiver);
mSatelliteAccessControllerUT.handleIsSatelliteSupportedResult(resultCode, bundle);
- verify(mMockSatelliteSupportedResultReceiver)
+ verify(mMockResultReceiver)
.send(mResultCodeIntCaptor.capture(), mResultDataBundleCaptor.capture());
assertEquals(Integer.valueOf(SATELLITE_RESULT_SUCCESS),
mResultCodeIntCaptor.getValue());
@@ -1150,10 +1643,10 @@
when(mMockCountryDetector.getCurrentNetworkCountryIso())
.thenReturn(List.of(TEST_SATELLITE_COUNTRY_CODE_US));
doReturn(false).when(mMockLocationManager).isLocationEnabled();
- doReturn(true, false).when(mockIterator).hasNext();
- clearInvocations(mMockSatelliteSupportedResultReceiver);
+ doReturn(true, false).when(mockResultReceiverIterator).hasNext();
+ clearInvocations(mMockResultReceiver);
mSatelliteAccessControllerUT.handleIsSatelliteSupportedResult(resultCode, bundle);
- verify(mMockSatelliteSupportedResultReceiver)
+ verify(mMockResultReceiver)
.send(mResultCodeIntCaptor.capture(), mResultDataBundleCaptor.capture());
assertEquals(Integer.valueOf(SATELLITE_RESULT_LOCATION_DISABLED),
mResultCodeIntCaptor.getValue());
@@ -1173,7 +1666,7 @@
doReturn(false).when(mMockPhone2).isInEcm();
doReturn(false).when(mMockSatelliteController).isInEmergencyMode();
doReturn(true).when(mMockLocationManager).isLocationEnabled();
- mSatelliteAccessControllerUT.setLocationRequestCancellationSignalAsNull();
+ mSatelliteAccessControllerUT.setLocationRequestCancellationSignalAsNull(true);
mSatelliteAccessControllerUT.elapsedRealtimeNanos = TEST_LOCATION_FRESH_DURATION_NANOS + 1;
// Invoking requestIsCommunicationAllowedForCurrentLocation(resultReceiver, "false");
@@ -1200,7 +1693,7 @@
private void sendSatelliteCommunicationAllowedEvent() {
Pair<Integer, ResultReceiver> requestPair =
- new Pair<>(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID,
+ new Pair<>(DEFAULT_SUBSCRIPTION_ID,
mSatelliteAccessControllerUT.getResultReceiverCurrentLocation());
Message msg = mSatelliteAccessControllerUT.obtainMessage(
CMD_IS_SATELLITE_COMMUNICATION_ALLOWED);
@@ -1217,6 +1710,13 @@
mTestableLooper.processAllMessages();
}
+ private void sendCurrentLocationTimeoutEvent() {
+ Message msg = mSatelliteAccessControllerUT
+ .obtainMessage(EVENT_WAIT_FOR_CURRENT_LOCATION_TIMEOUT);
+ msg.sendToTarget();
+ mTestableLooper.processAllMessages();
+ }
+
private void sendCommandValidateCountryCodeChangeEvent(Context context) {
Message msg = mSatelliteAccessControllerUT.obtainMessage(EVENT_COUNTRY_CODE_CHANGED);
msg.obj = new AsyncResult(context, SATELLITE_RESULT_SUCCESS, null);
@@ -1382,9 +1882,35 @@
return mLocationModeChangedBroadcastReceiver;
}
- public void setLocationRequestCancellationSignalAsNull() {
+ public void setLocationRequestCancellationSignalAsNull(boolean isNull) {
synchronized (mLock) {
- mLocationRequestCancellationSignal = null;
+ mLocationRequestCancellationSignal = isNull ? null : new CancellationSignal();
+ }
+ }
+
+ public boolean isCurrentSatelliteAllowedState() {
+ synchronized (mSatelliteCommunicationAllowStateLock) {
+ return mCurrentSatelliteAllowedState;
+ }
+ }
+
+ @Nullable
+ public Integer getRegionalConfigId() {
+ synchronized (mLock) {
+ return mRegionalConfigId;
+ }
+ }
+
+ @Nullable
+ public Integer getNewRegionalConfigId() {
+ synchronized (mLock) {
+ return mNewRegionalConfigId;
+ }
+ }
+
+ public void setRegionalConfigId(@Nullable Integer regionalConfigId) {
+ synchronized (mLock) {
+ mRegionalConfigId = regionalConfigId;
}
}
}
diff --git a/tests/src/com/android/phone/satellite/entitlement/SatelliteEntitlementControllerTest.java b/tests/src/com/android/phone/satellite/entitlement/SatelliteEntitlementControllerTest.java
index e663519..9f8a733 100644
--- a/tests/src/com/android/phone/satellite/entitlement/SatelliteEntitlementControllerTest.java
+++ b/tests/src/com/android/phone/satellite/entitlement/SatelliteEntitlementControllerTest.java
@@ -20,6 +20,7 @@
import static com.android.phone.satellite.entitlement.SatelliteEntitlementResult.SATELLITE_ENTITLEMENT_STATUS_DISABLED;
import static com.android.phone.satellite.entitlement.SatelliteEntitlementResult.SATELLITE_ENTITLEMENT_STATUS_ENABLED;
+import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
@@ -46,21 +47,22 @@
import android.net.NetworkCapabilities;
import android.net.wifi.WifiInfo;
import android.os.Handler;
-import android.os.HandlerThread;
import android.os.Looper;
-import android.os.Message;
import android.os.PersistableBundle;
import android.telephony.CarrierConfigManager;
import android.telephony.TelephonyManager;
+import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.util.Log;
import android.util.Pair;
import androidx.annotation.NonNull;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.android.TelephonyTestBase;
import com.android.internal.telephony.ExponentialBackoff;
+import com.android.internal.telephony.PhoneFactory;
+import com.android.internal.telephony.metrics.MetricsCollector;
+import com.android.internal.telephony.metrics.PersistAtomsStorage;
import com.android.internal.telephony.satellite.SatelliteController;
import com.android.internal.telephony.subscription.SubscriptionManagerService;
import com.android.libraries.entitlement.ServiceEntitlementException;
@@ -70,7 +72,7 @@
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
@@ -83,7 +85,8 @@
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
-@RunWith(AndroidJUnit4.class)
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper
public class SatelliteEntitlementControllerTest extends TelephonyTestBase {
private static final String TAG = "SatelliteEntitlementControllerTest";
private static final int SUB_ID = 0;
@@ -97,13 +100,12 @@
private static final int CMD_RETRY_QUERY_ENTITLEMENT = 2;
private static final int CMD_SIM_REFRESH = 3;
private static final int MAX_RETRY_COUNT = 5;
- @Mock
- CarrierConfigManager mCarrierConfigManager;
- @Mock
- ConnectivityManager mConnectivityManager;
+ @Mock CarrierConfigManager mCarrierConfigManager;
+ @Mock ConnectivityManager mConnectivityManager;
@Mock Network mNetwork;
@Mock TelephonyManager mTelephonyManager;
@Mock SubscriptionManagerService mMockSubscriptionManagerService;
+ @Mock private MetricsCollector mMetricsCollector;
@Mock SatelliteEntitlementApi mSatelliteEntitlementApi;
@Mock SatelliteEntitlementResult mSatelliteEntitlementResult;
@Mock SatelliteController mSatelliteController;
@@ -113,23 +115,19 @@
private TestableLooper mTestableLooper;
private List<Pair<Executor, CarrierConfigManager.CarrierConfigChangeListener>>
mCarrierConfigChangedListenerList = new ArrayList<>();
+
@Before
public void setUp() throws Exception {
super.setUp();
- MockitoAnnotations.initMocks(this);
replaceInstance(SubscriptionManagerService.class, "sInstance", null,
mMockSubscriptionManagerService);
replaceInstance(SatelliteController.class, "sInstance", null, mSatelliteController);
+ replaceInstance(PhoneFactory.class, "sMetricsCollector", null, mMetricsCollector);
+ doReturn(Mockito.mock(PersistAtomsStorage.class)).when(mMetricsCollector).getAtomsStorage();
- HandlerThread handlerThread = new HandlerThread("SatelliteEntitlementController");
- handlerThread.start();
- mHandler = new Handler(handlerThread.getLooper()) {
- @Override
- public void handleMessage(Message msg) {
- }
- };
- mTestableLooper = new TestableLooper(mHandler.getLooper());
+ mTestableLooper = TestableLooper.get(this);
+ mHandler = new Handler(mTestableLooper.getLooper());
doReturn(Context.TELEPHONY_SERVICE).when(mContext).getSystemServiceName(
TelephonyManager.class);
doReturn(mTelephonyManager).when(mContext).getSystemService(Context.TELEPHONY_SERVICE);
@@ -160,9 +158,8 @@
Context.CONNECTIVITY_SERVICE);
doReturn(mNetwork).when(mConnectivityManager).getActiveNetwork();
doReturn(ACTIVE_SUB_ID).when(mMockSubscriptionManagerService).getActiveSubIdList(true);
- mSatelliteEntitlementController = new TestSatelliteEntitlementController(mContext,
- mHandler.getLooper(), mSatelliteEntitlementApi);
- mSatelliteEntitlementController = spy(mSatelliteEntitlementController);
+ mSatelliteEntitlementController = spy(new TestSatelliteEntitlementController(mContext,
+ mTestableLooper.getLooper(), mSatelliteEntitlementApi));
doReturn(mSatelliteEntitlementResult).when(
mSatelliteEntitlementApi).checkEntitlementStatus();
}
@@ -174,7 +171,6 @@
@Test
public void testShouldStartQueryEntitlement() throws Exception {
- logd("testShouldStartQueryEntitlement");
doReturn(ACTIVE_SUB_ID).when(mMockSubscriptionManagerService).getActiveSubIdList(true);
// Verify don't start the query when KEY_SATELLITE_ENTITLEMENT_SUPPORTED_BOOL is false.
@@ -249,7 +245,6 @@
@Test
public void testCheckSatelliteEntitlementStatus() throws Exception {
- logd("testCheckSatelliteEntitlementStatus");
setIsQueryAvailableTrue();
// Verify don't call the checkSatelliteEntitlementStatus when getActiveSubIdList is empty.
doReturn(new int[]{}).when(mMockSubscriptionManagerService).getActiveSubIdList(true);
@@ -340,7 +335,6 @@
@Test
public void testCheckSatelliteEntitlementStatusWhenInternetConnected() throws Exception {
- logd("testCheckSatelliteEntitlementStatusWhenInternetConnected");
ConnectivityManager.NetworkCallback networkCallback =
(ConnectivityManager.NetworkCallback) getValue("mNetworkCallback");
Network mockNetwork = mock(Network.class);
@@ -362,7 +356,6 @@
@Test
public void testCheckSatelliteEntitlementStatusWhenCarrierConfigChanged() throws Exception {
- logd("testCheckSatelliteEntitlementStatusWhenCarrierConfigChanged");
// Verify the called the checkSatelliteEntitlementStatus when CarrierConfigChanged
// occurred and Internet is connected.
setInternetConnected(true);
@@ -379,7 +372,6 @@
@Test
public void testCheckWhenStartCmdIsReceivedDuringRetry() throws Exception {
- logd("testCheckWhenStartCmdIsReceivedDuringRetry");
// Verify that start cmd is ignored and retry is performed up to 5 times when start cmd
// occurs during retries.
setIsQueryAvailableTrue();
@@ -393,47 +385,47 @@
verify(mSatelliteEntitlementApi, times(1)).checkEntitlementStatus();
// Verify that the retry count is 0 after receiving a 503 with retry-after header in
// response.
- assertTrue(retryCountPerSub.getOrDefault(SUB_ID, 0) == 0);
+ assertEquals(0, retryCountPerSub.getOrDefault(SUB_ID, 0).longValue());
// Verify that the retry count is 1 for the second query when receiving a 503 with
// retry-after header in response.
mTestableLooper.moveTimeForward(TimeUnit.SECONDS.toMillis(1));
mTestableLooper.processAllMessages();
verify(mSatelliteEntitlementApi, times(2)).checkEntitlementStatus();
- assertTrue(retryCountPerSub.get(SUB_ID) == 1);
+ assertEquals(1, retryCountPerSub.get(SUB_ID).longValue());
// Verify that the retry count is 2 for the third query when receiving a 503 with
// retry-after header in response.
mTestableLooper.moveTimeForward(TimeUnit.SECONDS.toMillis(1));
mTestableLooper.processAllMessages();
verify(mSatelliteEntitlementApi, times(3)).checkEntitlementStatus();
- assertTrue(retryCountPerSub.get(SUB_ID) == 2);
+ assertEquals(2, retryCountPerSub.get(SUB_ID).longValue());
// Verify that start CMD is ignored during retries.
sendMessage(CMD_START_QUERY_ENTITLEMENT, SUB_ID);
mTestableLooper.processAllMessages();
verify(mSatelliteEntitlementApi, times(3)).checkEntitlementStatus();
- assertTrue(retryCountPerSub.get(SUB_ID) == 2);
+ assertEquals(2, retryCountPerSub.get(SUB_ID).longValue());
// Verify that the retry count is 3 for the forth query when receiving a 503 with
// retry-after header in response.
mTestableLooper.moveTimeForward(TimeUnit.SECONDS.toMillis(1));
mTestableLooper.processAllMessages();
verify(mSatelliteEntitlementApi, times(4)).checkEntitlementStatus();
- assertTrue(retryCountPerSub.get(SUB_ID) == 3);
+ assertEquals(3, retryCountPerSub.get(SUB_ID).longValue());
// Verify that the retry count is 4 for the fifth query when receiving a 503 with
// retry-after header in response.
mTestableLooper.moveTimeForward(TimeUnit.SECONDS.toMillis(1));
mTestableLooper.processAllMessages();
verify(mSatelliteEntitlementApi, times(5)).checkEntitlementStatus();
- assertTrue(retryCountPerSub.get(SUB_ID) == 4);
+ assertEquals(4, retryCountPerSub.get(SUB_ID).longValue());
// Verify that start CMD is ignored during retries.
sendMessage(CMD_START_QUERY_ENTITLEMENT, SUB_ID);
mTestableLooper.processAllMessages();
verify(mSatelliteEntitlementApi, times(5)).checkEntitlementStatus();
- assertTrue(retryCountPerSub.get(SUB_ID) == 4);
+ assertEquals(4, retryCountPerSub.get(SUB_ID).longValue());
// Verify that the retry count is 5 for the sixth query when receiving a 503 with
// retry-after header in response.
@@ -463,7 +455,6 @@
@Test
public void testCheckAfterInternetConnectionChangedDuringRetry() throws Exception {
- logd("testCheckAfterInternetConnectionChangedDuringRetry");
// Verify that the retry count is maintained even when internet connection is lost and
// connected during retries, and that up to 5 retries are performed.
setIsQueryAvailableTrue();
@@ -477,48 +468,48 @@
verify(mSatelliteEntitlementApi, times(1)).checkEntitlementStatus();
// Verify that the retry count is 0 after receiving a 503 with retry-after header in
// response.
- assertTrue(retryCountPerSub.getOrDefault(SUB_ID, 0) == 0);
+ assertEquals(0, retryCountPerSub.getOrDefault(SUB_ID, 0).longValue());
// Verify that the retry count is 1 for the second query when receiving a 503 with
// retry-after header in response.
mTestableLooper.moveTimeForward(TimeUnit.SECONDS.toMillis(1));
mTestableLooper.processAllMessages();
verify(mSatelliteEntitlementApi, times(2)).checkEntitlementStatus();
- assertTrue(retryCountPerSub.get(SUB_ID) == 1);
+ assertEquals(1, retryCountPerSub.get(SUB_ID).longValue());
// Verify that no query is executed and the retry count does not increase when internet
// connection is lost during the second retry.
setInternetConnected(false);
- mTestableLooper.moveTimeForward(TimeUnit.SECONDS.toMillis(1));
+ mTestableLooper.moveTimeForward(TimeUnit.SECONDS.toMillis(2));
mTestableLooper.processAllMessages();
verify(mSatelliteEntitlementApi, times(2)).checkEntitlementStatus();
- assertTrue(retryCountPerSub.get(SUB_ID) == 1);
+ assertEquals(1, retryCountPerSub.get(SUB_ID).longValue());
// Verify that the query is started when internet connection is restored and that the
// retry count does not increase.
setInternetConnected(true);
- logd("internet connected again");
+ Log.d(TAG, "internet connected again");
sendMessage(CMD_START_QUERY_ENTITLEMENT, SUB_ID);
mTestableLooper.processAllMessages();
verify(mSatelliteEntitlementApi, times(3)).checkEntitlementStatus();
- assertTrue(retryCountPerSub.get(SUB_ID) == 1);
+ assertEquals(1, retryCountPerSub.get(SUB_ID).longValue());
// Verify that the retry count is increases after received a 503 with retry-after header
// in response.
mTestableLooper.moveTimeForward(TimeUnit.SECONDS.toMillis(1));
mTestableLooper.processAllMessages();
verify(mSatelliteEntitlementApi, times(4)).checkEntitlementStatus();
- assertTrue(retryCountPerSub.get(SUB_ID) == 2);
+ assertEquals(2, retryCountPerSub.get(SUB_ID).longValue());
mTestableLooper.moveTimeForward(TimeUnit.SECONDS.toMillis(1));
mTestableLooper.processAllMessages();
verify(mSatelliteEntitlementApi, times(5)).checkEntitlementStatus();
- assertTrue(retryCountPerSub.get(SUB_ID) == 3);
+ assertEquals(3, retryCountPerSub.get(SUB_ID).longValue());
mTestableLooper.moveTimeForward(TimeUnit.SECONDS.toMillis(1));
mTestableLooper.processAllMessages();
verify(mSatelliteEntitlementApi, times(6)).checkEntitlementStatus();
- assertTrue(retryCountPerSub.get(SUB_ID) == 4);
+ assertEquals(4, retryCountPerSub.get(SUB_ID).longValue());
mTestableLooper.moveTimeForward(TimeUnit.SECONDS.toMillis(1));
mTestableLooper.processAllMessages();
@@ -546,7 +537,6 @@
@Test
public void testStartQueryEntitlementStatus_error500() throws Exception {
- logd("testStartQueryEntitlementStatus_error500");
setIsQueryAvailableTrue();
Map<Integer, Integer> retryCountPerSub =
(Map<Integer, Integer>) getValue("mRetryCountPerSub");
@@ -562,7 +552,6 @@
@Test
public void testStartQueryEntitlementStatus_error503_retrySuccess() throws Exception {
- logd("testStartQueryEntitlementStatus_error503_retrySuccess");
setIsQueryAvailableTrue();
set503RetryAfterResponse();
Map<Integer, Integer> retryCountPerSub =
@@ -590,7 +579,6 @@
@Test
public void testStartQueryEntitlementStatus_otherError_retrySuccess() throws Exception {
- logd("testStartQueryEntitlementStatus_otherError_retrySuccess");
setIsQueryAvailableTrue();
Map<Integer, Integer> retryCountPerSub =
(Map<Integer, Integer>) getValue("mRetryCountPerSub");
@@ -615,7 +603,7 @@
sendMessage(CMD_RETRY_QUERY_ENTITLEMENT, SUB_ID);
mTestableLooper.processAllMessages();
verify(mSatelliteEntitlementApi, times(2)).checkEntitlementStatus();
- assertTrue(retryCountPerSub.get(SUB_ID) == 1);
+ assertEquals(1, retryCountPerSub.get(SUB_ID).longValue());
// Verify don't call the onSatelliteEntitlementStatusUpdated.
verify(mSatelliteController, never()).onSatelliteEntitlementStatusUpdated(anyInt(),
anyBoolean(), anyList(), anyList(), any());
@@ -630,14 +618,13 @@
sendMessage(CMD_RETRY_QUERY_ENTITLEMENT, SUB_ID);
mTestableLooper.processAllMessages();
verify(mSatelliteEntitlementApi, times(3)).checkEntitlementStatus();
- assertTrue(retryCountPerSub.get(SUB_ID) == 1);
+ assertEquals(1, retryCountPerSub.get(SUB_ID).longValue());
verify(mSatelliteController).onSatelliteEntitlementStatusUpdated(eq(SUB_ID), eq(true),
eq(PLMN_ALLOWED_LIST), eq(PLMN_BARRED_LIST), any());
}
@Test
public void testSatelliteEntitlementSupportedChangedFromSupportToNotSupport() throws Exception {
- logd("testSatelliteEntitlementSupportedChangedFromSupportToNotSupport");
setIsQueryAvailableTrue();
// KEY_SATELLITE_ENTITLEMENT_SUPPORTED_BOOL changed from Support(entitlement status
@@ -692,7 +679,6 @@
@Test
public void testStartQueryEntitlementStatus_refreshStatus() throws Exception {
- logd("testStartQueryEntitlementStatus_refreshStatus");
setIsQueryAvailableTrue();
mCarrierConfigBundle.putInt(
CarrierConfigManager.KEY_SATELLITE_ENTITLEMENT_STATUS_REFRESH_DAYS_INT, 1);
@@ -722,7 +708,6 @@
@Test
public void testStartQueryEntitlementStatus_internetDisconnectedAndConnectedAgain()
throws Exception {
- logd("testStartQueryEntitlementStatus_internetDisconnectedAndConnectedAgain");
setIsQueryAvailableTrue();
// Verify the query does not start if there is no internet connection.
@@ -750,7 +735,6 @@
@Test
public void testStartQueryEntitlementStatus_error503_error500() throws Exception {
- logd("testStartQueryEntitlementStatus_error503_error500");
setIsQueryAvailableTrue();
set503RetryAfterResponse();
@@ -775,7 +759,6 @@
@Test
public void testStartQueryEntitlementStatus_error503_otherError() throws Exception {
- logd("testStartQueryEntitlementStatus_error503_otherError");
setIsQueryAvailableTrue();
set503RetryAfterResponse();
@@ -813,7 +796,6 @@
@Test
public void testStartQueryEntitlementStatus_AfterSimRefresh() throws Exception {
- logd("testStartQueryEntitlementStatus_AfterSimRefresh");
setIsQueryAvailableTrue();
// Verify the first query complete.
@@ -952,12 +934,8 @@
@Override
public SatelliteEntitlementApi getSatelliteEntitlementApi(int subId) {
- logd("getSatelliteEntitlementApi");
+ Log.d(TAG, "getSatelliteEntitlementApi");
return mInjectSatelliteEntitlementApi;
}
}
-
- private static void logd(String log) {
- Log.d(TAG, log);
- }
}
diff --git a/tests/src/com/android/services/telephony/DisconnectCauseUtilTest.java b/tests/src/com/android/services/telephony/DisconnectCauseUtilTest.java
index 71a23e6..fe6d6f7 100644
--- a/tests/src/com/android/services/telephony/DisconnectCauseUtilTest.java
+++ b/tests/src/com/android/services/telephony/DisconnectCauseUtilTest.java
@@ -22,7 +22,6 @@
import static junit.framework.Assert.assertNotNull;
import static junit.framework.TestCase.assertEquals;
-import static org.mockito.Mockito.mock;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertTrue;
@@ -38,15 +37,11 @@
import com.android.TelephonyTestBase;
import com.android.internal.telephony.CallFailCause;
-import com.android.internal.telephony.GsmCdmaPhone;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneFactory;
import com.android.phone.R;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.mockito.Mock;
import java.util.Locale;
@@ -57,13 +52,6 @@
public static final int PHONE_ID = 123;
public static final String EMPTY_STRING = "";
- // dynamic
- private Context mContext;
-
- //Mocks
- @Mock
- private GsmCdmaPhone mMockPhone;
-
private final FlagsAdapter mFeatureFlags = new FlagsAdapter(){
@Override
public boolean doNotOverridePreciseLabel() {
@@ -74,11 +62,6 @@
@Before
public void setUp() throws Exception {
super.setUp();
- // objects that call static getInstance()
- mMockPhone = mock(GsmCdmaPhone.class);
- mContext = InstrumentationRegistry.getTargetContext();
- // set mocks
- setSinglePhone();
}
/**
@@ -253,11 +236,6 @@
return config;
}
- private void setSinglePhone() throws Exception {
- Phone[] mPhones = new Phone[]{mMockPhone};
- replaceInstance(PhoneFactory.class, "sPhones", null, mPhones);
- }
-
private Resources getResourcesForLocale(Context context, Locale locale) {
Configuration config = new Configuration();
config.setToDefaults();
@@ -268,7 +246,7 @@
private void safeAssertLabel(Integer resourceId,
android.telecom.DisconnectCause disconnectCause) {
- Resources r = getResourcesForLocale(mContext, Locale.US);
+ Resources r = getResourcesForLocale(InstrumentationRegistry.getTargetContext(), Locale.US);
if (resourceId == null || r == null) {
return;
}
diff --git a/tests/src/com/android/services/telephony/ImsConferenceControllerTest.java b/tests/src/com/android/services/telephony/ImsConferenceControllerTest.java
index b1572f1..eacb001 100644
--- a/tests/src/com/android/services/telephony/ImsConferenceControllerTest.java
+++ b/tests/src/com/android/services/telephony/ImsConferenceControllerTest.java
@@ -25,21 +25,27 @@
import static org.mockito.Mockito.when;
import android.content.ComponentName;
-import android.os.Looper;
+import android.content.pm.PackageManager;
import android.telecom.PhoneAccountHandle;
import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+import com.android.TelephonyTestBase;
+
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
+import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
/**
* Tests the functionality in ImsConferenceController.java
*/
-
-public class ImsConferenceControllerTest {
+@RunWith(AndroidJUnit4.class)
+public class ImsConferenceControllerTest extends TelephonyTestBase {
+ @Mock
+ PackageManager mPackageManager;
@Mock
private TelephonyConnectionServiceProxy mMockTelephonyConnectionServiceProxy;
@@ -64,11 +70,14 @@
@Before
public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
- if (Looper.myLooper() == null) {
- Looper.prepare();
- }
- mTelecomAccountRegistry = TelecomAccountRegistry.getInstance(null);
+ super.setUp();
+
+ when(mContext.getPackageManager()).thenReturn(mPackageManager);
+ when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)).thenReturn(true);
+ when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY_CALLING))
+ .thenReturn(true);
+
+ mTelecomAccountRegistry = TelecomAccountRegistry.getInstance(mContext);
mTestTelephonyConnectionA = new TestTelephonyConnection();
mTestTelephonyConnectionB = new TestTelephonyConnection();
@@ -79,6 +88,11 @@
mMockTelephonyConnectionServiceProxy, () -> false);
}
+ @After
+ public void tearDown() throws Exception {
+ super.tearDown();
+ }
+
/**
* Behavior: add telephony connections B and A to conference controller,
* set status for connections, remove one call
diff --git a/tests/src/com/android/services/telephony/ImsConferenceTest.java b/tests/src/com/android/services/telephony/ImsConferenceTest.java
index ca16bc7..b6cb11a 100644
--- a/tests/src/com/android/services/telephony/ImsConferenceTest.java
+++ b/tests/src/com/android/services/telephony/ImsConferenceTest.java
@@ -124,6 +124,30 @@
}
/**
+ * Verifies that the default address presentation of an ImsConference is
+ * {@link TelecomManager#PRESENTATION_UNKNOWN}
+ */
+ @Test
+ @SmallTest
+ public void testDefaultNumberPresentationIsValid() {
+ when(mMockTelecomAccountRegistry.isUsingSimCallManager(any(PhoneAccountHandle.class)))
+ .thenReturn(false);
+ mConferenceHost.setConnectionProperties(Connection.PROPERTY_ASSISTED_DIALING
+ | Connection.PROPERTY_WIFI);
+ Bundle extras = new Bundle();
+ extras.putInt(TelecomManager.EXTRA_CALL_NETWORK_TYPE, TelephonyManager.NETWORK_TYPE_IWLAN);
+ mConferenceHost.putTelephonyExtras(extras);
+ mConferenceHost.setStatusHints(new StatusHints("WIFIs", null, null));
+
+ ImsConference imsConference = new ImsConference(mMockTelecomAccountRegistry,
+ mMockTelephonyConnectionServiceProxy, mConferenceHost,
+ null /* phoneAccountHandle */, () -> true /* featureFlagProxy */,
+ new ImsConference.CarrierConfiguration.Builder().build());
+
+ assertEquals(TelecomManager.PRESENTATION_UNKNOWN, imsConference.getAddressPresentation());
+ }
+
+ /**
* Verifies that an ImsConference will inform listeners when the "fullness" of the conference
* changes as participants come and go.
*/
diff --git a/tests/src/com/android/services/telephony/TelecomAccountRegistryTest.java b/tests/src/com/android/services/telephony/TelecomAccountRegistryTest.java
index fc544b0..d0fc69d 100644
--- a/tests/src/com/android/services/telephony/TelecomAccountRegistryTest.java
+++ b/tests/src/com/android/services/telephony/TelecomAccountRegistryTest.java
@@ -50,9 +50,8 @@
import com.android.TelephonyTestBase;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneConstants;
-import com.android.internal.telephony.PhoneFactory;
+import com.android.internal.telephony.SimultaneousCallingTracker;
import com.android.internal.telephony.flags.Flags;
-import com.android.phone.PhoneGlobals;
import com.android.phone.PhoneInterfaceManager;
import com.android.phone.R;
@@ -63,7 +62,7 @@
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.Mockito;
@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper(setAsMainLooper = true)
@@ -83,7 +82,6 @@
@Mock ImsManager mImsManager;
@Mock SubscriptionManager mSubscriptionManager;
@Mock ContentProvider mContentProvider;
- @Mock PhoneGlobals mPhoneGlobals;
@Mock Phone mPhone;
@Mock Resources mResources;
@Mock Drawable mDrawable;
@@ -96,18 +94,13 @@
private BroadcastReceiver mUserSwitchedAndConfigChangedReceiver;
private BroadcastReceiver mLocaleChangedBroadcastReceiver;
private ContentResolver mContentResolver;
- private Phone[] mPhones;
private TestableLooper mTestableLooper;
@Before
public void setUp() throws Exception {
super.setUp();
mSetFlagsRule.disableFlags(Flags.FLAG_DELAY_PHONE_ACCOUNT_REGISTRATION);
- MockitoAnnotations.initMocks(this);
- mPhones = new Phone[]{mPhone};
- replaceInstance(PhoneFactory.class, "sPhones", null, mPhones);
- replaceInstance(PhoneGlobals.class, "sMe", null, mPhoneGlobals);
replaceInstance(PhoneInterfaceManager.class, "sInstance", null, mPhoneInterfaceManager);
when(mPhone.getPhoneType()).thenReturn(PhoneConstants.PHONE_TYPE_GSM);
when(mPhone.getContext()).thenReturn(mMockedContext);
@@ -182,6 +175,9 @@
broadcastReceiverArgumentCaptor.getAllValues().get(0);
mLocaleChangedBroadcastReceiver = broadcastReceiverArgumentCaptor.getAllValues().get(1);
+ replaceInstance(SimultaneousCallingTracker.class, "sInstance", null,
+ Mockito.mock(SimultaneousCallingTracker.class));
+
mTestableLooper.processAllMessages();
}
diff --git a/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java b/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java
index 463e9ae..6a10d75 100644
--- a/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java
+++ b/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java
@@ -61,7 +61,6 @@
import android.os.AsyncResult;
import android.os.Bundle;
import android.os.Handler;
-import android.os.Looper;
import android.platform.test.flag.junit.SetFlagsRule;
import android.telecom.Conference;
import android.telecom.Conferenceable;
@@ -283,7 +282,7 @@
@Before
public void setUp() throws Exception {
super.setUp();
- doReturn(Looper.getMainLooper()).when(mContext).getMainLooper();
+
mTestConnectionService = new TestTelephonyConnectionService(mContext);
mTestConnectionService.setFeatureFlags(mFeatureFlags);
mTestConnectionService.setPhoneFactoryProxy(mPhoneFactoryProxy);
@@ -314,7 +313,8 @@
mTestConnectionService, mEmergencyStateTracker);
replaceInstance(TelephonyConnectionService.class, "mSatelliteSOSMessageRecommender",
mTestConnectionService, mSatelliteSOSMessageRecommender);
- doNothing().when(mSatelliteSOSMessageRecommender).onEmergencyCallStarted(any());
+ doNothing().when(mSatelliteSOSMessageRecommender).onEmergencyCallStarted(any(),
+ anyBoolean());
doNothing().when(mSatelliteSOSMessageRecommender).onEmergencyCallConnectionStateChanged(
anyString(), anyInt());
doReturn(CompletableFuture.completedFuture(NOT_DISCONNECTED))
@@ -1308,7 +1308,7 @@
ArgumentCaptor<RadioOnStateListener.Callback> callback =
ArgumentCaptor.forClass(RadioOnStateListener.Callback.class);
verify(mRadioOnHelper).triggerRadioOnAndListen(callback.capture(), eq(true),
- eq(testPhone), eq(false), eq(0), eq(false));
+ eq(testPhone), eq(false), eq(0));
assertFalse(callback.getValue()
.isOkToCall(testPhone, ServiceState.STATE_OUT_OF_SERVICE, false));
@@ -1336,7 +1336,7 @@
ArgumentCaptor<RadioOnStateListener.Callback> callback =
ArgumentCaptor.forClass(RadioOnStateListener.Callback.class);
verify(mRadioOnHelper).triggerRadioOnAndListen(callback.capture(), eq(true),
- eq(testPhone), eq(false), eq(0), eq(false));
+ eq(testPhone), eq(false), eq(0));
assertFalse(callback.getValue()
.isOkToCall(testPhone, ServiceState.STATE_OUT_OF_SERVICE, false));
@@ -1353,7 +1353,7 @@
// This shouldn't happen
fail();
}
- verify(mSatelliteSOSMessageRecommender).onEmergencyCallStarted(any());
+ verify(mSatelliteSOSMessageRecommender).onEmergencyCallStarted(any(), anyBoolean());
}
/**
@@ -1439,7 +1439,7 @@
@Test
@SmallTest
public void testCreateOutgoingEmergencyConnection_exitingSatellite_placeCall() {
- when(mSatelliteController.isSatelliteEnabled()).thenReturn(true);
+ when(mSatelliteController.isSatelliteEnabledOrBeingEnabled()).thenReturn(true);
doReturn(true).when(mMockResources).getBoolean(anyInt());
doReturn(true).when(mTelephonyManagerProxy).isCurrentEmergencyNumber(
anyString());
@@ -1448,14 +1448,14 @@
ArgumentCaptor<RadioOnStateListener.Callback> callback =
ArgumentCaptor.forClass(RadioOnStateListener.Callback.class);
verify(mRadioOnHelper).triggerRadioOnAndListen(callback.capture(), eq(true),
- eq(testPhone), eq(false), eq(0), eq(false));
+ eq(testPhone), eq(false), eq(0));
assertFalse(callback.getValue()
.isOkToCall(testPhone, ServiceState.STATE_OUT_OF_SERVICE, false));
when(mSST.isRadioOn()).thenReturn(true);
assertFalse(callback.getValue()
.isOkToCall(testPhone, ServiceState.STATE_OUT_OF_SERVICE, false));
- when(mSatelliteController.isSatelliteEnabled()).thenReturn(false);
+ when(mSatelliteController.isSatelliteEnabledOrBeingEnabled()).thenReturn(false);
assertTrue(callback.getValue()
.isOkToCall(testPhone, ServiceState.STATE_OUT_OF_SERVICE, false));
@@ -1468,7 +1468,7 @@
// This shouldn't happen
fail();
}
- verify(mSatelliteSOSMessageRecommender).onEmergencyCallStarted(any());
+ verify(mSatelliteSOSMessageRecommender).onEmergencyCallStarted(any(), anyBoolean());
}
/**
@@ -1480,7 +1480,7 @@
public void testCreateOutgoingEmergencyConnection_exitingSatellite_EmergencySatellite()
throws Exception {
doReturn(true).when(mFeatureFlags).carrierRoamingNbIotNtn();
- doReturn(true).when(mSatelliteController).isSatelliteEnabled();
+ doReturn(true).when(mSatelliteController).isSatelliteEnabledOrBeingEnabled();
// Set config_turn_off_oem_enabled_satellite_during_emergency_call as false
doReturn(true).when(mTelephonyManagerProxy).isCurrentEmergencyNumber(anyString());
@@ -1499,7 +1499,7 @@
@SmallTest
public void testCreateOutgoingEmergencyConnection_exitingSatellite_OEM() throws Exception {
doReturn(true).when(mFeatureFlags).carrierRoamingNbIotNtn();
- doReturn(true).when(mSatelliteController).isSatelliteEnabled();
+ doReturn(true).when(mSatelliteController).isSatelliteEnabledOrBeingEnabled();
// Set config_turn_off_oem_enabled_satellite_during_emergency_call as false
doReturn(false).when(mMockResources).getBoolean(anyInt());
@@ -1508,9 +1508,7 @@
// Satellite is for emergency
doReturn(true).when(mSatelliteController).getRequestIsEmergency();
- Phone phone = mock(Phone.class);
- doReturn(1).when(phone).getSubId();
- doReturn(phone).when(mSatelliteController).getSatellitePhone();
+ doReturn(1).when(mSatelliteController).getSelectedSatelliteSubId();
SubscriptionManagerService isub = mock(SubscriptionManagerService.class);
replaceInstance(SubscriptionManagerService.class, "sInstance", null, isub);
SubscriptionInfoInternal info = mock(SubscriptionInfoInternal.class);
@@ -1538,7 +1536,7 @@
@SmallTest
public void testCreateOutgoingEmergencyConnection_exitingSatellite_Carrier() throws Exception {
doReturn(true).when(mFeatureFlags).carrierRoamingNbIotNtn();
- doReturn(true).when(mSatelliteController).isSatelliteEnabled();
+ doReturn(true).when(mSatelliteController).isSatelliteEnabledOrBeingEnabled();
// Set config_turn_off_oem_enabled_satellite_during_emergency_call as false
doReturn(false).when(mMockResources).getBoolean(anyInt());
@@ -1547,9 +1545,7 @@
// Satellite is for emergency
doReturn(true).when(mSatelliteController).getRequestIsEmergency();
- Phone phone = mock(Phone.class);
- doReturn(1).when(phone).getSubId();
- doReturn(phone).when(mSatelliteController).getSatellitePhone();
+ doReturn(1).when(mSatelliteController).getSelectedSatelliteSubId();
SubscriptionManagerService isub = mock(SubscriptionManagerService.class);
replaceInstance(SubscriptionManagerService.class, "sInstance", null, isub);
SubscriptionInfoInternal info = mock(SubscriptionInfoInternal.class);
@@ -1603,7 +1599,7 @@
PHONE_ACCOUNT_HANDLE_1, connectionRequest);
verify(mRadioOnHelper).triggerRadioOnAndListen(any(), eq(false),
- eq(testPhone0), eq(false), eq(0), eq(false));
+ eq(testPhone0), eq(false), eq(0));
}
/**
@@ -1637,7 +1633,7 @@
PHONE_ACCOUNT_HANDLE_1, connectionRequest);
verify(mRadioOnHelper).triggerRadioOnAndListen(any(), eq(false),
- eq(testPhone0), eq(false), eq(0), eq(false));
+ eq(testPhone0), eq(false), eq(0));
}
/**
@@ -1670,7 +1666,7 @@
PHONE_ACCOUNT_HANDLE_1, connectionRequest);
verify(mRadioOnHelper, times(0)).triggerRadioOnAndListen(any(),
- eq(true), eq(testPhone0), eq(false), eq(0), eq(false));
+ eq(true), eq(testPhone0), eq(false), eq(0));
}
/**
@@ -2291,7 +2287,8 @@
.getDomainSelectionConnection(eq(mPhone0), eq(SELECTOR_TYPE_CALLING), eq(true));
verify(mEmergencyStateTracker)
.startEmergencyCall(eq(mPhone0), connectionCaptor.capture(), eq(false));
- verify(mSatelliteSOSMessageRecommender, times(2)).onEmergencyCallStarted(any());
+ verify(mSatelliteSOSMessageRecommender, times(2)).onEmergencyCallStarted(any(),
+ anyBoolean());
verify(mEmergencyCallDomainSelectionConnection).createEmergencyConnection(any(), any());
android.telecom.Connection tc = connectionCaptor.getValue();
@@ -2330,7 +2327,8 @@
.getDomainSelectionConnection(eq(mPhone0), eq(SELECTOR_TYPE_CALLING), eq(true));
verify(mEmergencyStateTracker)
.startEmergencyCall(eq(mPhone0), connectionCaptor.capture(), eq(false));
- verify(mSatelliteSOSMessageRecommender, times(2)).onEmergencyCallStarted(any());
+ verify(mSatelliteSOSMessageRecommender, times(2)).onEmergencyCallStarted(any(),
+ anyBoolean());
verify(mEmergencyCallDomainSelectionConnection).createEmergencyConnection(any(), any());
android.telecom.Connection tc = connectionCaptor.getValue();
@@ -2374,7 +2372,8 @@
.getDomainSelectionConnection(eq(mPhone0), eq(SELECTOR_TYPE_CALLING), eq(true));
verify(mEmergencyStateTracker)
.startEmergencyCall(eq(mPhone0), connectionCaptor.capture(), eq(false));
- verify(mSatelliteSOSMessageRecommender, times(2)).onEmergencyCallStarted(any());
+ verify(mSatelliteSOSMessageRecommender, times(2)).onEmergencyCallStarted(any(),
+ anyBoolean());
verify(mEmergencyCallDomainSelectionConnection).createEmergencyConnection(any(), any());
android.telecom.Connection tc = connectionCaptor.getValue();
@@ -2522,7 +2521,8 @@
listener.onDisconnect(0);
- verify(mSatelliteSOSMessageRecommender, times(2)).onEmergencyCallStarted(any());
+ verify(mSatelliteSOSMessageRecommender, times(2)).onEmergencyCallStarted(any(),
+ anyBoolean());
ArgumentCaptor<DialArgs> argsCaptor = ArgumentCaptor.forClass(DialArgs.class);
@@ -2628,7 +2628,7 @@
verify(mDomainSelectionResolver)
.getDomainSelectionConnection(eq(mPhone0), eq(SELECTOR_TYPE_CALLING), eq(false));
verify(mNormalCallDomainSelectionConnection).createNormalConnection(any(), any());
- verify(mSatelliteSOSMessageRecommender).onEmergencyCallStarted(any());
+ verify(mSatelliteSOSMessageRecommender).onEmergencyCallStarted(any(), anyBoolean());
ArgumentCaptor<DialArgs> argsCaptor = ArgumentCaptor.forClass(DialArgs.class);
@@ -2725,7 +2725,8 @@
.getDomainSelectionConnection(eq(mPhone0), eq(SELECTOR_TYPE_CALLING), eq(true));
verify(mEmergencyStateTracker)
.startEmergencyCall(eq(mPhone0), connectionCaptor.capture(), eq(false));
- verify(mSatelliteSOSMessageRecommender, times(2)).onEmergencyCallStarted(any());
+ verify(mSatelliteSOSMessageRecommender, times(2)).onEmergencyCallStarted(any(),
+ anyBoolean());
verify(mEmergencyCallDomainSelectionConnection).createEmergencyConnection(any(), any());
android.telecom.Connection tc = connectionCaptor.getValue();
@@ -2796,7 +2797,7 @@
verify(mDomainSelectionResolver)
.getDomainSelectionConnection(eq(mPhone0), eq(SELECTOR_TYPE_CALLING), eq(false));
verify(mNormalCallDomainSelectionConnection).createNormalConnection(any(), any());
- verify(mSatelliteSOSMessageRecommender).onEmergencyCallStarted(any());
+ verify(mSatelliteSOSMessageRecommender).onEmergencyCallStarted(any(), anyBoolean());
ArgumentCaptor<DialArgs> argsCaptor = ArgumentCaptor.forClass(DialArgs.class);
@@ -2818,7 +2819,7 @@
ArgumentCaptor<RadioOnStateListener.Callback> callback =
ArgumentCaptor.forClass(RadioOnStateListener.Callback.class);
verify(mRadioOnHelper).triggerRadioOnAndListen(callback.capture(), eq(true),
- eq(testPhone), eq(false), eq(TIMEOUT_TO_DYNAMIC_ROUTING_MS), eq(true));
+ eq(testPhone), eq(false), eq(TIMEOUT_TO_DYNAMIC_ROUTING_MS));
ServiceState ss = new ServiceState();
ss.setState(ServiceState.STATE_OUT_OF_SERVICE);
@@ -2857,7 +2858,7 @@
ArgumentCaptor<RadioOnStateListener.Callback> callback =
ArgumentCaptor.forClass(RadioOnStateListener.Callback.class);
verify(mRadioOnHelper).triggerRadioOnAndListen(callback.capture(), eq(true),
- eq(testPhone), eq(false), eq(TIMEOUT_TO_DYNAMIC_ROUTING_MS), eq(true));
+ eq(testPhone), eq(false), eq(TIMEOUT_TO_DYNAMIC_ROUTING_MS));
ServiceState ss = new ServiceState();
ss.setState(ServiceState.STATE_OUT_OF_SERVICE);
@@ -2882,7 +2883,7 @@
ArgumentCaptor<RadioOnStateListener.Callback> callback =
ArgumentCaptor.forClass(RadioOnStateListener.Callback.class);
verify(mRadioOnHelper).triggerRadioOnAndListen(callback.capture(), eq(true),
- eq(testPhone), eq(false), eq(TIMEOUT_TO_DYNAMIC_ROUTING_MS), eq(true));
+ eq(testPhone), eq(false), eq(TIMEOUT_TO_DYNAMIC_ROUTING_MS));
ServiceState ss = new ServiceState();
ss.setState(ServiceState.STATE_IN_SERVICE);
@@ -2918,7 +2919,7 @@
ArgumentCaptor<RadioOnStateListener.Callback> callback =
ArgumentCaptor.forClass(RadioOnStateListener.Callback.class);
verify(mRadioOnHelper).triggerRadioOnAndListen(callback.capture(), eq(true),
- eq(testPhone), eq(false), eq(TIMEOUT_TO_DYNAMIC_ROUTING_MS), eq(true));
+ eq(testPhone), eq(false), eq(TIMEOUT_TO_DYNAMIC_ROUTING_MS));
ServiceState ss = new ServiceState();
ss.setState(ServiceState.STATE_IN_SERVICE);
@@ -2955,7 +2956,7 @@
ArgumentCaptor<RadioOnStateListener.Callback> callback =
ArgumentCaptor.forClass(RadioOnStateListener.Callback.class);
verify(mRadioOnHelper).triggerRadioOnAndListen(callback.capture(), eq(true),
- eq(testPhone), eq(false), eq(TIMEOUT_TO_DYNAMIC_ROUTING_MS), eq(true));
+ eq(testPhone), eq(false), eq(TIMEOUT_TO_DYNAMIC_ROUTING_MS));
ServiceState ss = new ServiceState();
ss.setState(ServiceState.STATE_IN_SERVICE);
@@ -2992,7 +2993,7 @@
ArgumentCaptor<RadioOnStateListener.Callback> callback =
ArgumentCaptor.forClass(RadioOnStateListener.Callback.class);
verify(mRadioOnHelper).triggerRadioOnAndListen(callback.capture(), eq(true),
- eq(testPhone), eq(false), eq(TIMEOUT_TO_DYNAMIC_ROUTING_MS), eq(true));
+ eq(testPhone), eq(false), eq(TIMEOUT_TO_DYNAMIC_ROUTING_MS));
mConnection.setDisconnected(null);
@@ -3029,7 +3030,7 @@
.getDomainSelectionConnection(eq(mPhone0), eq(SELECTOR_TYPE_CALLING), eq(true));
verify(mEmergencyStateTracker)
.startEmergencyCall(eq(mPhone0), connectionCaptor.capture(), eq(false));
- verify(mSatelliteSOSMessageRecommender).onEmergencyCallStarted(any());
+ verify(mSatelliteSOSMessageRecommender).onEmergencyCallStarted(any(), anyBoolean());
verify(mEmergencyCallDomainSelectionConnection).createEmergencyConnection(any(), any());
android.telecom.Connection tc = connectionCaptor.getValue();
@@ -3082,7 +3083,7 @@
.getDomainSelectionConnection(eq(mPhone0), eq(SELECTOR_TYPE_CALLING), eq(true));
verify(mEmergencyStateTracker)
.startEmergencyCall(eq(mPhone0), connectionCaptor.capture(), eq(false));
- verify(mSatelliteSOSMessageRecommender).onEmergencyCallStarted(any());
+ verify(mSatelliteSOSMessageRecommender).onEmergencyCallStarted(any(), anyBoolean());
verify(mEmergencyCallDomainSelectionConnection).createEmergencyConnection(any(), any());
android.telecom.Connection tc = connectionCaptor.getValue();
@@ -3417,7 +3418,7 @@
verify(mEmergencyStateTracker)
.startEmergencyCall(eq(mPhone0), connectionCaptor.capture(), eq(false));
- verify(mSatelliteSOSMessageRecommender).onEmergencyCallStarted(any());
+ verify(mSatelliteSOSMessageRecommender).onEmergencyCallStarted(any(), anyBoolean());
android.telecom.Connection tc = connectionCaptor.getValue();
@@ -3493,7 +3494,8 @@
.getDomainSelectionConnection(eq(mPhone0), eq(SELECTOR_TYPE_CALLING), eq(true));
verify(mEmergencyStateTracker)
.startEmergencyCall(eq(mPhone0), connectionCaptor.capture(), eq(false));
- verify(mSatelliteSOSMessageRecommender, times(2)).onEmergencyCallStarted(any());
+ verify(mSatelliteSOSMessageRecommender, times(2)).onEmergencyCallStarted(any(),
+ anyBoolean());
verify(mEmergencyCallDomainSelectionConnection).createEmergencyConnection(any(), any());
verify(mPhone0).dial(anyString(), any(), any());
@@ -3703,7 +3705,8 @@
verify(mDomainSelectionResolver)
.getDomainSelectionConnection(eq(mPhone0), eq(SELECTOR_TYPE_CALLING), eq(false));
verify(mNormalCallDomainSelectionConnection).createNormalConnection(any(), any());
- verify(mSatelliteSOSMessageRecommender, never()).onEmergencyCallStarted(any());
+ verify(mSatelliteSOSMessageRecommender, never()).onEmergencyCallStarted(any(),
+ anyBoolean());
ArgumentCaptor<DialArgs> argsCaptor = ArgumentCaptor.forClass(DialArgs.class);
@@ -3728,7 +3731,8 @@
verify(mDomainSelectionResolver)
.getDomainSelectionConnection(eq(mPhone0), eq(SELECTOR_TYPE_CALLING), eq(false));
verify(mNormalCallDomainSelectionConnection).createNormalConnection(any(), any());
- verify(mSatelliteSOSMessageRecommender, never()).onEmergencyCallStarted(any());
+ verify(mSatelliteSOSMessageRecommender, never()).onEmergencyCallStarted(any(),
+ anyBoolean());
ArgumentCaptor<DialArgs> argsCaptor = ArgumentCaptor.forClass(DialArgs.class);
@@ -3744,7 +3748,7 @@
@Test
public void testNormalCallSatelliteEnabled() {
setupForCallTest();
- doReturn(true).when(mSatelliteController).isSatelliteEnabled();
+ doReturn(true).when(mSatelliteController).isSatelliteEnabledOrBeingEnabled();
mConnection = mTestConnectionService.onCreateOutgoingConnection(PHONE_ACCOUNT_HANDLE_1,
createConnectionRequest(PHONE_ACCOUNT_HANDLE_1, "1234", TELECOM_CALL_ID1));
@@ -3757,7 +3761,7 @@
@Test
public void testEmergencyCallSatelliteEnabled_blockEmergencyCall() {
setupForCallTest();
- doReturn(true).when(mSatelliteController).isSatelliteEnabled();
+ doReturn(true).when(mSatelliteController).isSatelliteEnabledOrBeingEnabled();
doReturn(false).when(mMockResources).getBoolean(anyInt());
doReturn(true).when(mTelephonyManagerProxy).isCurrentEmergencyNumber(
anyString());
diff --git a/tests/src/com/android/services/telephony/TelephonyManagerTest.java b/tests/src/com/android/services/telephony/TelephonyManagerTest.java
index 20c062f..efb7375 100644
--- a/tests/src/com/android/services/telephony/TelephonyManagerTest.java
+++ b/tests/src/com/android/services/telephony/TelephonyManagerTest.java
@@ -15,10 +15,12 @@
*/
package com.android.services.telephony;
-import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail;
import static org.junit.Assume.assumeFalse;
+import static org.junit.Assert.assertThrows;
import static org.junit.Assume.assumeTrue;
+import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.anyInt;
@@ -34,7 +36,9 @@
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.PackageManager;
+import android.os.OutcomeReceiver;
import android.os.RemoteException;
+import android.platform.test.annotations.RequiresFlagsEnabled;
import android.telecom.PhoneAccountHandle;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
@@ -43,9 +47,10 @@
import androidx.test.runner.AndroidJUnit4;
-import com.android.internal.telephony.ITelephony;
import com.android.internal.telephony.IPhoneSubInfo;
+import com.android.internal.telephony.ITelephony;
import com.android.internal.telephony.PhoneConstants;
+import com.android.internal.telephony.flags.Flags;
import org.junit.After;
import org.junit.Before;
@@ -53,13 +58,16 @@
import org.junit.runner.RunWith;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
/** Unit tests for {@link TelephonyManager}. */
@RunWith(AndroidJUnit4.class)
@@ -131,6 +139,55 @@
}
@Test
+ @RequiresFlagsEnabled(Flags.FLAG_SUPPORT_ISIM_RECORD)
+ public void testGetImsPcscfAddresses() throws Exception {
+ assumeTrue(hasFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, true));
+ List<String> pcscfs = Arrays.asList(new String[] { "1.1.1.1 ", " 2.2.2.2"});
+ when(mMockIPhoneSubInfo.getImsPcscfAddresses(anyInt(), anyString()))
+ .thenReturn(pcscfs);
+
+ List<String> actualResult = mTelephonyManager.getImsPcscfAddresses();
+
+ assertTrue(pcscfs.equals(actualResult));
+ }
+
+ @Test
+ @RequiresFlagsEnabled(Flags.FLAG_SUPPORT_ISIM_RECORD)
+ public void testGetImsPcscfAddresses_ReturnEmptyListWhenNotAvailable() throws Exception {
+ assumeTrue(hasFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, true));
+ List<String> pcscfs = new ArrayList<>();
+ when(mMockIPhoneSubInfo.getImsPcscfAddresses(anyInt(), anyString()))
+ .thenReturn(pcscfs);
+
+ List<String> actualResult = mTelephonyManager.getImsPcscfAddresses();
+
+ assertTrue(pcscfs.equals(actualResult));
+ }
+
+ @Test
+ @RequiresFlagsEnabled(Flags.FLAG_SUPPORT_ISIM_RECORD)
+ public void testGetImsPcscfAddresses_ReturnEmptyListForInvalidSubId() throws Exception {
+ assumeTrue(hasFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, true));
+ List<String> pcscfs = new ArrayList<>();
+ when(mMockIPhoneSubInfo.getImsPcscfAddresses(anyInt(), anyString()))
+ .thenThrow(new IllegalArgumentException("Invalid subscription"));
+
+ List<String> actualResult = mTelephonyManager.getImsPcscfAddresses();
+
+ assertTrue(pcscfs.equals(actualResult));
+ }
+
+ @Test
+ @RequiresFlagsEnabled(Flags.FLAG_SUPPORT_ISIM_RECORD)
+ public void testGetImsPcscfAddresses_ThrowRuntimeException() throws Exception {
+ assumeTrue(hasFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, true));
+ when(mMockIPhoneSubInfo.getImsPcscfAddresses(anyInt(), anyString()))
+ .thenThrow(new IllegalStateException("ISIM is not loaded"));
+
+ assertThrows(RuntimeException.class, () -> mTelephonyManager.getImsPcscfAddresses());
+ }
+
+ @Test
public void testFilterEmergencyNumbersByCategories() throws Exception {
Map<Integer, List<EmergencyNumber>> emergencyNumberLists = new HashMap<>();
List<EmergencyNumber> emergencyNumberList = new ArrayList<>();
@@ -260,6 +317,70 @@
assertEquals(null, mTelephonyManager.getSimServiceTable(PhoneConstants.APPTYPE_RUIM));
}
+ @Test
+ @RequiresFlagsEnabled(Flags.FLAG_SUPPORT_ISIM_RECORD)
+ public void testGetSimServiceTableFromIsimAsByteArrayType() throws Exception {
+ assumeTrue(hasFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, true));
+ String simServiceTable = "34FA754E8390BD02";
+ Executor executor = Executors.newSingleThreadExecutor();
+ TestOutcomeReceiver<byte[], Exception> receiver = new TestOutcomeReceiver<>();
+ when(mMockIPhoneSubInfo.getIsimIst(anyInt())).thenReturn(simServiceTable);
+
+ mTelephonyManager.getSimServiceTable(
+ PhoneConstants.APPTYPE_ISIM, executor, receiver);
+
+ byte[] actualResult = receiver.getResult();
+ assertArrayEquals(hexStringToBytes(simServiceTable), actualResult);
+ }
+
+ @Test
+ @RequiresFlagsEnabled(Flags.FLAG_SUPPORT_ISIM_RECORD)
+ public void testGetSimServiceTableFromUsimAsByteArrayType() throws Exception {
+ assumeTrue(hasFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, true));
+ String simServiceTable = "34FA754E8390BD02";
+ Executor executor = Executors.newSingleThreadExecutor();
+ TestOutcomeReceiver<byte[], Exception> receiver = new TestOutcomeReceiver<>();
+ when(mMockIPhoneSubInfo.getSimServiceTable(anyInt(), anyInt()))
+ .thenReturn(simServiceTable);
+
+ mTelephonyManager.getSimServiceTable(
+ PhoneConstants.APPTYPE_USIM, executor, receiver);
+
+ byte[] actualResult = receiver.getResult();
+ assertArrayEquals(hexStringToBytes(simServiceTable), actualResult);
+ }
+
+ @Test
+ @RequiresFlagsEnabled(Flags.FLAG_SUPPORT_ISIM_RECORD)
+ public void testGetSimServiceTable_ReturnEmptyArrayWhenNotAvailable() throws Exception {
+ assumeTrue(hasFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, true));
+ Executor executor = Executors.newSingleThreadExecutor();
+ TestOutcomeReceiver<byte[], Exception> receiver = new TestOutcomeReceiver<>();
+ when(mMockIPhoneSubInfo.getSimServiceTable(anyInt(), anyInt())).thenReturn(null);
+
+ mTelephonyManager.getSimServiceTable(
+ PhoneConstants.APPTYPE_RUIM, executor, receiver);
+
+ byte[] actualResult = receiver.getResult();
+ assertArrayEquals(new byte[0], actualResult);
+ }
+
+ @Test
+ @RequiresFlagsEnabled(Flags.FLAG_SUPPORT_ISIM_RECORD)
+ public void testGetSimServiceTable_CallbackErrorIfExceptionIsThrown() throws Exception {
+ assumeTrue(hasFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, true));
+ Executor executor = Executors.newSingleThreadExecutor();
+ TestOutcomeReceiver<byte[], Exception> receiver = new TestOutcomeReceiver<>();
+ when(mMockIPhoneSubInfo.getIsimIst(anyInt()))
+ .thenThrow(new IllegalStateException("ISIM is not loaded"));
+
+ mTelephonyManager.getSimServiceTable(
+ PhoneConstants.APPTYPE_ISIM, executor, receiver);
+
+ Exception error = receiver.getError();
+ assertTrue(error instanceof IllegalStateException);
+ }
+
private boolean hasFeature(String feature, boolean status) {
doReturn(status)
.when(mPackageManager).hasSystemFeature(
@@ -295,4 +416,58 @@
});
}
+
+ private static class TestOutcomeReceiver<R, E extends Throwable>
+ implements OutcomeReceiver<R, E> {
+ final int mTimeoutSeconds = 3;
+ CountDownLatch mLatch = new CountDownLatch(1);
+ AtomicReference<R> mResult = new AtomicReference<>();
+ AtomicReference<E> mError = new AtomicReference<>();
+
+ public R getResult() throws InterruptedException {
+ assertTrue(mLatch.await(mTimeoutSeconds, TimeUnit.SECONDS));
+ assertNotNull(mResult.get());
+ return mResult.get();
+ }
+
+ public E getError() throws InterruptedException {
+ assertTrue(mLatch.await(mTimeoutSeconds, TimeUnit.SECONDS));
+ assertNotNull(mError.get());
+ return mError.get();
+ }
+
+ @Override
+ public void onResult(R result) {
+ mResult.set(result);
+ mLatch.countDown();
+ }
+
+ @Override
+ public void onError(E error) {
+ mError.set(error);
+ mLatch.countDown();
+ }
+ }
+
+ private static byte[] hexStringToBytes(String s) {
+ byte[] ret;
+ if (s == null) return null;
+ int sz = s.length();
+ ret = new byte[sz / 2];
+
+ for (int i = 0; i < sz; i += 2) {
+ ret[i / 2] = (byte) ((hexCharToInt(s.charAt(i)) << 4)
+ | hexCharToInt(s.charAt(i + 1)));
+ }
+
+ return ret;
+ }
+
+ private static int hexCharToInt(char c) {
+ if (c >= '0' && c <= '9') return (c - '0');
+ if (c >= 'A' && c <= 'F') return (c - 'A' + 10);
+ if (c >= 'a' && c <= 'f') return (c - 'a' + 10);
+
+ throw new RuntimeException("invalid hex char '" + c + "'");
+ }
}
\ No newline at end of file
diff --git a/tests/src/com/android/services/telephony/TestTelephonyConnection.java b/tests/src/com/android/services/telephony/TestTelephonyConnection.java
index d91435c..9f1a0ec 100644
--- a/tests/src/com/android/services/telephony/TestTelephonyConnection.java
+++ b/tests/src/com/android/services/telephony/TestTelephonyConnection.java
@@ -16,27 +16,31 @@
package com.android.services.telephony;
-import android.content.AttributionSource;
-import android.content.ContentResolver;
-import android.os.Process;
-import android.os.UserHandle;
-import android.telephony.TelephonyManager;
-
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.notNull;
import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
+import android.content.AttributionSource;
import android.content.Context;
+import android.content.pm.ApplicationInfo;
import android.content.res.Resources;
+import android.os.Build;
import android.os.Bundle;
import android.os.PersistableBundle;
+import android.os.Process;
+import android.os.UserHandle;
+import android.provider.Settings;
import android.telecom.PhoneAccountHandle;
import android.telecom.VideoProfile;
import android.telephony.CarrierConfigManager;
+import android.telephony.TelephonyManager;
+import android.test.mock.MockContentProvider;
+import android.test.mock.MockContentResolver;
import com.android.ims.ImsCall;
import com.android.internal.telephony.Call;
@@ -70,9 +74,6 @@
Context mMockContext;
@Mock
- ContentResolver mMockContentResolver;
-
- @Mock
Resources mMockResources;
@Mock
@@ -96,6 +97,7 @@
@Mock
CarrierConfigManager mCarrierConfigManager;
+ private MockContentResolver mMockContentResolver;
private boolean mIsImsConnection;
private boolean mIsImsExternalConnection;
private boolean mIsConferenceSupported = true;
@@ -136,6 +138,14 @@
mMockContext = mock(Context.class);
mMockTelephonyManager = mock(TelephonyManager.class);
mOriginalConnection = mMockRadioConnection;
+
+ ApplicationInfo applicationInfo = new ApplicationInfo();
+ applicationInfo.targetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT;
+ doReturn(applicationInfo).when(mMockContext).getApplicationInfo();
+ mMockContentResolver = new MockContentResolver(mMockContext);
+ mMockContentResolver.addProvider(Settings.AUTHORITY,
+ new EmptyContentProvider(mMockContext));
+
// Set up mMockRadioConnection and mMockPhone to contain an active call
when(mMockRadioConnection.getState()).thenReturn(Call.State.ACTIVE);
when(mOriginalConnection.getState()).thenReturn(Call.State.ACTIVE);
@@ -159,8 +169,7 @@
when(mMockContext.getSystemService(Context.TELEPHONY_SERVICE))
.thenReturn(mMockTelephonyManager);
when(mMockContext.getAttributionSource()).thenReturn(attributionSource);
- when(mMockContentResolver.getUserId()).thenReturn(UserHandle.USER_CURRENT);
- when(mMockContentResolver.getAttributionSource()).thenReturn(attributionSource);
+ when(mMockContext.getUserId()).thenReturn(UserHandle.USER_CURRENT);
when(mMockResources.getBoolean(anyInt())).thenReturn(false);
when(mMockPhone.getDefaultPhone()).thenReturn(mMockPhone);
when(mMockPhone.getPhoneType()).thenReturn(PhoneConstants.PHONE_TYPE_IMS);
@@ -320,4 +329,15 @@
public void setMockImsPhoneConnection(ImsPhoneConnection connection) {
mImsPhoneConnection = connection;
}
+
+ static class EmptyContentProvider extends MockContentProvider {
+ EmptyContentProvider(Context context) {
+ super(context);
+ }
+
+ @Override
+ public Bundle call(String method, String request, Bundle args) {
+ return new Bundle();
+ }
+ }
}
diff --git a/tests/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelectorTest.java b/tests/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelectorTest.java
index 8a83ab0..51493d3 100644
--- a/tests/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelectorTest.java
+++ b/tests/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelectorTest.java
@@ -127,6 +127,7 @@
import android.testing.TestableLooper;
import android.util.Log;
import android.util.SparseArray;
+import android.view.Display;
import androidx.test.filters.SmallTest;
@@ -230,6 +231,11 @@
public Resources getResources() {
return mResources;
}
+
+ @Override
+ public int getDisplayId() {
+ return Display.DEFAULT_DISPLAY;
+ }
};
if (Looper.myLooper() == null) {
diff --git a/tests/src/com/android/services/telephony/domainselection/NormalCallDomainSelectorTest.java b/tests/src/com/android/services/telephony/domainselection/NormalCallDomainSelectorTest.java
index 49411bd..7acc7d6 100644
--- a/tests/src/com/android/services/telephony/domainselection/NormalCallDomainSelectorTest.java
+++ b/tests/src/com/android/services/telephony/domainselection/NormalCallDomainSelectorTest.java
@@ -743,6 +743,27 @@
mNormalCallDomainSelector.getSelectorState());
}
+ @Test
+ public void testReselectDomainNoTimeoutMessage() {
+ final TestTransportSelectorCallback transportSelectorCallback =
+ new TestTransportSelectorCallback(mNormalCallDomainSelector);
+
+ DomainSelectionService.SelectionAttributes attributes =
+ new DomainSelectionService.SelectionAttributes.Builder(
+ SLOT_ID, SUB_ID_1, SELECTOR_TYPE_CALLING)
+ .setAddress(TEST_URI)
+ .setCallId(TEST_CALLID)
+ .setEmergency(false)
+ .setVideoCall(false)
+ .setExitedFromAirplaneMode(false)
+ .build();
+
+ mNormalCallDomainSelector.selectDomain(null, transportSelectorCallback);
+ mNormalCallDomainSelector.reselectDomain(attributes);
+ assertFalse(mNormalCallDomainSelector.hasMessages(
+ NormalCallDomainSelector.MSG_WAIT_FOR_IMS_STATE_TIMEOUT));
+ }
+
static class TestTransportSelectorCallback implements TransportSelectorCallback,
WwanSelectorCallback {
public boolean mCreated;
diff --git a/tests/src/com/android/services/telephony/rcs/RcsFeatureControllerTest.java b/tests/src/com/android/services/telephony/rcs/RcsFeatureControllerTest.java
index 07c9fd0..649d3dd 100644
--- a/tests/src/com/android/services/telephony/rcs/RcsFeatureControllerTest.java
+++ b/tests/src/com/android/services/telephony/rcs/RcsFeatureControllerTest.java
@@ -45,6 +45,7 @@
import com.android.ims.FeatureConnector;
import com.android.ims.RcsFeatureManager;
import com.android.internal.telephony.imsphone.ImsRegistrationCallbackHelper;
+import com.android.phone.ImsStateCallbackController;
import org.junit.After;
import org.junit.Before;
@@ -84,6 +85,9 @@
@Before
public void setUp() throws Exception {
super.setUp();
+
+ replaceInstance(ImsStateCallbackController.class, "sInstance", null,
+ mock(ImsStateCallbackController.class));
}
@After
diff --git a/tests/src/com/android/services/telephony/rcs/SipTransportControllerTest.java b/tests/src/com/android/services/telephony/rcs/SipTransportControllerTest.java
index 42a45f4..df7a37e 100644
--- a/tests/src/com/android/services/telephony/rcs/SipTransportControllerTest.java
+++ b/tests/src/com/android/services/telephony/rcs/SipTransportControllerTest.java
@@ -147,12 +147,16 @@
@After
public void tearDown() throws Exception {
- super.tearDown();
- boolean isShutdown = mExecutorService == null || mExecutorService.isShutdown();
- if (!isShutdown) {
+ var monitor = RcsProvisioningMonitor.getInstance();
+ if (monitor != null) {
+ monitor.overrideImsFeatureValidation(TEST_SUB_ID, null);
+ }
+
+ if (mExecutorService != null && !mExecutorService.isShutdown()) {
mExecutorService.shutdownNow();
}
- RcsProvisioningMonitor.getInstance().overrideImsFeatureValidation(TEST_SUB_ID, null);
+
+ super.tearDown();
}
@SmallTest
diff --git a/tests/src/com/android/services/telephony/rcs/TelephonyRcsServiceTest.java b/tests/src/com/android/services/telephony/rcs/TelephonyRcsServiceTest.java
index 4cabf95..34ed5c6 100644
--- a/tests/src/com/android/services/telephony/rcs/TelephonyRcsServiceTest.java
+++ b/tests/src/com/android/services/telephony/rcs/TelephonyRcsServiceTest.java
@@ -20,6 +20,7 @@
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
@@ -40,6 +41,7 @@
import com.android.ims.RcsFeatureManager;
import com.android.internal.telephony.ISub;
import com.android.internal.telephony.flags.FeatureFlags;
+import com.android.phone.ImsStateCallbackController;
import org.junit.After;
import org.junit.Before;
@@ -103,6 +105,9 @@
eq(1), anyInt());
doReturn(true).when(mResourceProxy).getDeviceUceEnabled(any());
+ replaceInstance(ImsStateCallbackController.class, "sInstance", null,
+ mock(ImsStateCallbackController.class));
+
replaceInstance(TelephonyManager.class, "sInstance", null, mTelephonyManager);
doReturn(2).when(mTelephonyManager).getActiveModemCount();
}
diff --git a/utils/satellite/s2storage/src/readonly/java/com/android/telephony/sats2range/read/HeaderBlock.java b/utils/satellite/s2storage/src/readonly/java/com/android/telephony/sats2range/read/HeaderBlock.java
index 9895d1a..9592e1e 100644
--- a/utils/satellite/s2storage/src/readonly/java/com/android/telephony/sats2range/read/HeaderBlock.java
+++ b/utils/satellite/s2storage/src/readonly/java/com/android/telephony/sats2range/read/HeaderBlock.java
@@ -40,10 +40,26 @@
int suffixBitCount = blockData.getUnsignedByte(offset++);
int suffixRecordBitCount = blockData.getUnsignedByte(offset++);
int suffixTableBlockIdOffset = blockData.getUnsignedByte(offset++);
- boolean isAllowedList = (blockData.getUnsignedByte(offset) == TRUE);
- mFileFormat = new SatS2RangeFileFormat(
- dataS2Level, prefixBitCount, suffixBitCount, suffixTableBlockIdOffset,
- suffixRecordBitCount, isAllowedList);
+ boolean isAllowedList = (blockData.getUnsignedByte(offset++) == TRUE);
+
+
+ // Check if the block is in the original format or the enhanced format.
+ // If the offset is equal to the block data size, this block is in the original format.
+ // If the offset is less than the block data size, this block is an enhanced block, which
+ // has additional fields:
+ // - the size of an entry value in bytes
+ // - version number of header block
+ if (offset < blockData.getSize()) {
+ int entryValueSizeInBytes = blockData.getUnsignedByte(offset++);
+ int versionNumber = blockData.getInt(offset);
+ mFileFormat = new SatS2RangeFileFormat(
+ dataS2Level, prefixBitCount, suffixBitCount, suffixTableBlockIdOffset,
+ suffixRecordBitCount, isAllowedList, entryValueSizeInBytes, versionNumber);
+ } else {
+ mFileFormat = new SatS2RangeFileFormat(
+ dataS2Level, prefixBitCount, suffixBitCount, suffixTableBlockIdOffset,
+ suffixRecordBitCount, isAllowedList);
+ }
}
/** Creates a {@link HeaderBlock} from low-level block data from a block file. */
diff --git a/utils/satellite/s2storage/src/readonly/java/com/android/telephony/sats2range/read/PopulatedSuffixTableBlock.java b/utils/satellite/s2storage/src/readonly/java/com/android/telephony/sats2range/read/PopulatedSuffixTableBlock.java
index 9aa56b2..8cb9d1d 100644
--- a/utils/satellite/s2storage/src/readonly/java/com/android/telephony/sats2range/read/PopulatedSuffixTableBlock.java
+++ b/utils/satellite/s2storage/src/readonly/java/com/android/telephony/sats2range/read/PopulatedSuffixTableBlock.java
@@ -20,7 +20,6 @@
import static com.android.storage.s2.S2Support.cellIdToString;
import static com.android.storage.util.Conditions.checkStateInRange;
-import com.android.storage.s2.S2LevelRange;
import com.android.storage.table.packed.read.IntValueTypedPackedTable;
import com.android.storage.table.reader.IntValueTable;
@@ -59,7 +58,8 @@
SatS2RangeFileFormat fileFormat, IntValueTypedPackedTable packedTable) {
mFileFormat = Objects.requireNonNull(fileFormat);
mPackedTable = Objects.requireNonNull(packedTable);
- mSuffixTableSharedData = SuffixTableSharedData.fromBytes(packedTable.getSharedData());
+ mSuffixTableSharedData = SuffixTableSharedData.fromTypedData(
+ packedTable.getSharedDataAsTyped(), fileFormat);
// Obtain the prefix. All cellIds in this table will share the same prefix except for end
// range values (which are exclusive so can be for mPrefix + 1 with a suffix value of 0).
@@ -141,7 +141,7 @@
private final IntValueTable.TableEntry mSuffixTableEntry;
- private S2LevelRange mSuffixTableRange;
+ private SuffixTableRange mSuffixTableRange;
Entry(IntValueTable.TableEntry suffixTableEntry) {
mSuffixTableEntry = Objects.requireNonNull(suffixTableEntry);
@@ -154,7 +154,7 @@
/** Returns the data for this entry. */
@Override
- public S2LevelRange getSuffixTableRange() {
+ public SuffixTableRange getSuffixTableRange() {
// Creating SuffixTableRange is relatively expensive so it is created lazily and
// memoized.
if (mSuffixTableRange == null) {
@@ -190,7 +190,8 @@
endCellIdSuffix = 0;
}
long endCellId = mFileFormat.createCellId(endCellPrefixValue, endCellIdSuffix);
- mSuffixTableRange = new S2LevelRange(startCellId, endCellId);
+ int entryValue = getEntryValue();
+ mSuffixTableRange = new SuffixTableRange(startCellId, endCellId, entryValue);
}
return mSuffixTableRange;
}
@@ -218,5 +219,9 @@
+ "mSuffixTableEntry=" + mSuffixTableEntry
+ '}';
}
+
+ private int getEntryValue() {
+ return mSuffixTableSharedData.getEntryValue(mSuffixTableEntry.getIndex());
+ }
}
}
diff --git a/utils/satellite/s2storage/src/readonly/java/com/android/telephony/sats2range/read/SatS2RangeFileFormat.java b/utils/satellite/s2storage/src/readonly/java/com/android/telephony/sats2range/read/SatS2RangeFileFormat.java
index 39507aa..a335766 100644
--- a/utils/satellite/s2storage/src/readonly/java/com/android/telephony/sats2range/read/SatS2RangeFileFormat.java
+++ b/utils/satellite/s2storage/src/readonly/java/com/android/telephony/sats2range/read/SatS2RangeFileFormat.java
@@ -53,6 +53,10 @@
/** The format version of the satellite S2 data file, read and written. */
public static final int VERSION = 1;
+ private static final int DEFAULT_ENTRY_VALUE_SIZE_IN_BYTES = 0;
+ private static final int DEFAULT_VERSION_NUMBER = 0;
+ private static final int MAX_ENTRY_BYTE_COUNT = 4;
+
private final int mDataS2Level;
private final int mPrefixBitCount;
@@ -87,11 +91,28 @@
private final boolean mIsAllowedList;
/**
+ * Entry value size in bytes
+ */
+ private final int mEntryValueSizeInBytes;
+
+ /**
+ * Version number
+ */
+ private final int mVersionNumber;
+
+ public SatS2RangeFileFormat(int s2Level, int prefixBitCount, int suffixBitCount,
+ int suffixTableBlockIdOffset, int tableEntryBitCount, boolean isAllowedList) {
+ this(s2Level, prefixBitCount, suffixBitCount, suffixTableBlockIdOffset, tableEntryBitCount,
+ isAllowedList, DEFAULT_ENTRY_VALUE_SIZE_IN_BYTES, DEFAULT_VERSION_NUMBER);
+ }
+
+ /**
* Creates a new file format. This constructor validates the values against various hard-coded
* constraints and will throw an {@link IllegalArgumentException} if they are not satisfied.
*/
public SatS2RangeFileFormat(int s2Level, int prefixBitCount, int suffixBitCount,
- int suffixTableBlockIdOffset, int tableEntryBitCount, boolean isAllowedList) {
+ int suffixTableBlockIdOffset, int tableEntryBitCount, boolean isAllowedList,
+ int entryValueSizeInBytes, int versionNumber) {
Conditions.checkArgInRange("s2Level", s2Level, 0, MAX_S2_LEVEL);
@@ -180,6 +201,12 @@
mSuffixTableBlockIdOffset = suffixTableBlockIdOffset;
mIsAllowedList = isAllowedList;
+
+ Conditions.checkArgInRange("entryValueSizeInBytes", entryValueSizeInBytes, 0,
+ MAX_ENTRY_BYTE_COUNT);
+ mEntryValueSizeInBytes = entryValueSizeInBytes;
+
+ mVersionNumber = versionNumber;
}
/** Returns the S2 level of all geo data stored in the file. */
@@ -345,6 +372,18 @@
+ "}";
}
+ /**
+ * Returns the length of entry value in Bytes.
+ * @return the length of entry value
+ */
+ public int getEntryValueSizeInBytes() {
+ return mEntryValueSizeInBytes;
+ }
+
+ public int getVersionNumber() {
+ return mVersionNumber;
+ }
+
@Override
public String toString() {
return "SatS2RangeFileFormat{"
@@ -359,6 +398,8 @@
+ ", mSuffixTableBlockIdOffset=" + mSuffixTableBlockIdOffset
+ ", mUnusedCellIdBitCount=" + mUnusedCellIdBitCount
+ ", mIsAllowedList=" + mIsAllowedList
+ + ", mEntryValueSizeInBytes=" + mEntryValueSizeInBytes
+ + ", mVersionNumber=" + mVersionNumber
+ '}';
}
@@ -381,7 +422,9 @@
&& mTableEntryMaxRangeLengthValue == that.mTableEntryMaxRangeLengthValue
&& mSuffixTableBlockIdOffset == that.mSuffixTableBlockIdOffset
&& mIsAllowedList == that.mIsAllowedList
- && mUnusedCellIdBitCount == that.mUnusedCellIdBitCount;
+ && mUnusedCellIdBitCount == that.mUnusedCellIdBitCount
+ && mEntryValueSizeInBytes == that.mEntryValueSizeInBytes
+ && mVersionNumber == that.mVersionNumber;
}
@Override
@@ -389,7 +432,7 @@
return Objects.hash(mDataS2Level, mPrefixBitCount, mMaxPrefixValue, mSuffixBitCount,
mMaxSuffixValue, mTableEntryBitCount, mTableEntryRangeLengthBitCount,
mTableEntryMaxRangeLengthValue, mSuffixTableBlockIdOffset, mIsAllowedList,
- mUnusedCellIdBitCount);
+ mUnusedCellIdBitCount, mEntryValueSizeInBytes, mVersionNumber);
}
private void checkS2Level(String name, long cellId) {
diff --git a/utils/satellite/s2storage/src/readonly/java/com/android/telephony/sats2range/read/SatS2RangeFileReader.java b/utils/satellite/s2storage/src/readonly/java/com/android/telephony/sats2range/read/SatS2RangeFileReader.java
index ecfa0a9..2c6c4af 100644
--- a/utils/satellite/s2storage/src/readonly/java/com/android/telephony/sats2range/read/SatS2RangeFileReader.java
+++ b/utils/satellite/s2storage/src/readonly/java/com/android/telephony/sats2range/read/SatS2RangeFileReader.java
@@ -19,7 +19,6 @@
import com.android.storage.block.read.Block;
import com.android.storage.block.read.BlockFileReader;
import com.android.storage.block.read.BlockInfo;
-import com.android.storage.s2.S2LevelRange;
import com.android.storage.s2.S2Support;
import com.android.storage.util.Conditions;
import com.android.storage.util.Visitor;
@@ -144,11 +143,11 @@
}
/**
- * Finds an {@link S2LevelRange} associated with a range covering {@code cellId}.
+ * Finds an {@link SuffixTableRange} associated with a range covering {@code cellId}.
* Returns {@code null} if no range exists. Throws {@link IllegalArgumentException} if
* {@code cellId} is not the correct S2 level for the file. See {@link #getS2Level()}.
*/
- public S2LevelRange findEntryByCellId(long cellId) throws IOException {
+ public SuffixTableRange findEntryByCellId(long cellId) throws IOException {
checkNotClosed();
int dataS2Level = mFileFormat.getS2Level();
int searchS2Level = S2Support.getS2Level(cellId);
diff --git a/utils/satellite/s2storage/src/readonly/java/com/android/telephony/sats2range/read/SuffixTableBlock.java b/utils/satellite/s2storage/src/readonly/java/com/android/telephony/sats2range/read/SuffixTableBlock.java
index 90ddd89..ffd28d5 100644
--- a/utils/satellite/s2storage/src/readonly/java/com/android/telephony/sats2range/read/SuffixTableBlock.java
+++ b/utils/satellite/s2storage/src/readonly/java/com/android/telephony/sats2range/read/SuffixTableBlock.java
@@ -20,7 +20,6 @@
import static com.android.storage.s2.S2Support.getS2Level;
import com.android.storage.block.read.BlockData;
-import com.android.storage.s2.S2LevelRange;
import com.android.storage.table.packed.read.IntValueTypedPackedTable;
import com.android.storage.util.BitwiseUtils;
import com.android.storage.util.Visitor;
@@ -180,6 +179,6 @@
public abstract int getIndex();
/** Returns the data for this entry. */
- public abstract S2LevelRange getSuffixTableRange();
+ public abstract SuffixTableRange getSuffixTableRange();
}
}
diff --git a/utils/satellite/s2storage/src/readonly/java/com/android/telephony/sats2range/read/SuffixTableRange.java b/utils/satellite/s2storage/src/readonly/java/com/android/telephony/sats2range/read/SuffixTableRange.java
new file mode 100644
index 0000000..8c1466f
--- /dev/null
+++ b/utils/satellite/s2storage/src/readonly/java/com/android/telephony/sats2range/read/SuffixTableRange.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.telephony.sats2range.read;
+
+import static com.android.storage.s2.S2Support.cellIdToString;
+
+import com.android.storage.s2.S2LevelRange;
+
+import java.util.Objects;
+
+public final class SuffixTableRange extends S2LevelRange {
+ private static final int DEFAULT_ENTRY_VALUE = -1;
+ private final int mEntryValue;
+
+ // For backward compatibility
+ public SuffixTableRange(long startCellId, long endCellId) {
+ this(startCellId, endCellId, DEFAULT_ENTRY_VALUE);
+ }
+
+ public SuffixTableRange(long startCellId, long endCellId, int entryValue) {
+ super(startCellId, endCellId);
+ mEntryValue = entryValue;
+ }
+
+ /** Returns the entry value associated with this range. */
+ public int getEntryValue() {
+ return mEntryValue;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+
+ if (super.equals(o)) {
+ int entryValue = ((SuffixTableRange) o).mEntryValue;
+ return mEntryValue == entryValue;
+ } else {
+ return false;
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mStartCellId, mEndCellId, mEntryValue);
+ }
+
+ @Override
+ public String toString() {
+ return "SuffixTableRange{"
+ + "mS2Level=" + mS2Level
+ + ", mStartCellId=" + cellIdToString(mStartCellId)
+ + ", mEndCellId=" + cellIdToString(mEndCellId)
+ + ", mEntryValue=" + mEntryValue
+ + '}';
+ }
+}
diff --git a/utils/satellite/s2storage/src/readonly/java/com/android/telephony/sats2range/read/SuffixTableSharedData.java b/utils/satellite/s2storage/src/readonly/java/com/android/telephony/sats2range/read/SuffixTableSharedData.java
index 2221b2c..14cb92f 100644
--- a/utils/satellite/s2storage/src/readonly/java/com/android/telephony/sats2range/read/SuffixTableSharedData.java
+++ b/utils/satellite/s2storage/src/readonly/java/com/android/telephony/sats2range/read/SuffixTableSharedData.java
@@ -16,11 +16,13 @@
package com.android.telephony.sats2range.read;
+import com.android.storage.block.read.TypedData;
import com.android.storage.io.read.TypedInputStream;
import com.android.storage.table.reader.Table;
import java.io.ByteArrayInputStream;
import java.io.IOException;
+import java.util.List;
import java.util.Objects;
/**
@@ -28,14 +30,98 @@
* entries in the table and is required when interpreting the table's block data.
*/
public final class SuffixTableSharedData {
-
+ public static final int INVALID_ENTRY_VALUE = -1;
private final int mTablePrefix;
+ private final int mEntryValueSizeInBytes;
+ private final int mNumberOfEntryValues;
+ private final int mHeaderByteOffsetToRead;
+ private List<Integer> mEntryValuesToWrite = List.of(); // This is used for write path
+ private final TypedData mSharedDataToRead; // This is used for read path
/**
* Creates a {@link SuffixTableSharedData}. See also {@link #fromBytes(byte[])}.
*/
public SuffixTableSharedData(int tablePrefix) {
mTablePrefix = tablePrefix;
+ mEntryValueSizeInBytes = 0;
+ mNumberOfEntryValues = 0;
+ mHeaderByteOffsetToRead = 0;
+ mSharedDataToRead = null;
+ }
+
+ /**
+ * This constructor is used for write path
+ */
+ public SuffixTableSharedData(int tablePrefix, List<Integer> entryValues,
+ SatS2RangeFileFormat fileFormat) {
+ mSharedDataToRead = null;
+ mTablePrefix = tablePrefix;
+ mNumberOfEntryValues = entryValues.size();
+ mEntryValuesToWrite = entryValues;
+ mEntryValueSizeInBytes = fileFormat.getEntryValueSizeInBytes();
+ mHeaderByteOffsetToRead = 0;
+ }
+
+ /**
+ * This constructor is used for read path
+ */
+ public SuffixTableSharedData(TypedData sharedDataToRead, SatS2RangeFileFormat fileFormat) {
+ mSharedDataToRead = Objects.requireNonNull(sharedDataToRead);
+ int offset = 0;
+ // extract prefix value
+ mTablePrefix = mSharedDataToRead.getInt(offset);
+ offset += Integer.BYTES;
+
+ // If the size of shared data is greater than the offset, extract the number of entry
+ // values.
+ if ((offset + Integer.BYTES) < mSharedDataToRead.getSize()) {
+ mNumberOfEntryValues = mSharedDataToRead.getInt(offset);
+ mHeaderByteOffsetToRead = offset + Integer.BYTES;
+ mEntryValueSizeInBytes = fileFormat.getEntryValueSizeInBytes();
+ } else {
+ mNumberOfEntryValues = 0;
+ mHeaderByteOffsetToRead = offset;
+ mEntryValueSizeInBytes = 0;
+ }
+ }
+
+ /**
+ * This is used for read path
+ */
+ public static SuffixTableSharedData fromTypedData(TypedData sharedData,
+ SatS2RangeFileFormat fileFormat) {
+ return new SuffixTableSharedData(sharedData, fileFormat);
+ }
+
+ /**
+ * Reads the entry value at a specific position in the byte buffer and returns it.
+ *
+ * @param entryIndex The index of entry to be read.
+ * @return entry value (integer) read from the byte buffer.
+ */
+ public int getEntryValue(int entryIndex) {
+ if (mSharedDataToRead == null || entryIndex < 0 || mNumberOfEntryValues == 0) {
+ return INVALID_ENTRY_VALUE;
+ }
+
+ if (mNumberOfEntryValues == 1) {
+ entryIndex = 0;
+ }
+
+ int offset;
+ if (entryIndex < mNumberOfEntryValues) {
+ // offset = table prefix(4) + entry value count(4) + size of entry * entry index
+ offset = mHeaderByteOffsetToRead + (mEntryValueSizeInBytes * entryIndex);
+ } else {
+ return INVALID_ENTRY_VALUE;
+ }
+
+ return getValueInternal(mSharedDataToRead, mEntryValueSizeInBytes, offset);
+ }
+
+ // Entry lists to be written to a byte buffer.
+ public List<Integer> getEntryValuesToWrite() {
+ return mEntryValuesToWrite;
}
/**
@@ -46,6 +132,20 @@
return mTablePrefix;
}
+ /**
+ * Returns the number of entry values.
+ */
+ public int getNumberOfEntryValues() {
+ return mNumberOfEntryValues;
+ }
+
+ /**
+ * Returns the size of entry value in Bytes.
+ */
+ public int getEntryValueSizeInBytes() {
+ return mEntryValueSizeInBytes;
+ }
+
@Override
public boolean equals(Object o) {
if (this == o) {
@@ -55,18 +155,22 @@
return false;
}
SuffixTableSharedData that = (SuffixTableSharedData) o;
- return mTablePrefix == that.mTablePrefix;
+ return mTablePrefix == that.mTablePrefix
+ && mNumberOfEntryValues == that.mNumberOfEntryValues
+ && mEntryValuesToWrite.equals(that.mEntryValuesToWrite);
}
@Override
public int hashCode() {
- return Objects.hash(mTablePrefix);
+ return Objects.hash(mTablePrefix, mNumberOfEntryValues, mEntryValuesToWrite);
}
@Override
public String toString() {
return "SuffixTableSharedData{"
+ "mTablePrefix=" + mTablePrefix
+ + "mNumberOfEntries=" + mNumberOfEntryValues
+ + "mEntryValuesToWrite=" + mEntryValuesToWrite
+ '}';
}
@@ -82,4 +186,21 @@
throw new RuntimeException(e);
}
}
+
+ private int getValueInternal(TypedData buffer, int valueSizeBytes, int byteOffset) {
+ if (byteOffset < 0) {
+ throw new IllegalArgumentException(
+ "byteOffset=" + byteOffset + " must not be negative");
+ }
+
+ // High bytes read first.
+ int value = 0;
+ int bytesRead = 0;
+ while (bytesRead++ < valueSizeBytes) {
+ value <<= Byte.SIZE;
+ value |= buffer.getUnsignedByte(byteOffset++);
+ }
+
+ return value;
+ }
}
diff --git a/utils/satellite/s2storage/src/test/java/com/android/telephony/sats2range/SatS2RangeFileFormatTest.java b/utils/satellite/s2storage/src/test/java/com/android/telephony/sats2range/SatS2RangeFileFormatTest.java
index 80ef467..65da1e4 100644
--- a/utils/satellite/s2storage/src/test/java/com/android/telephony/sats2range/SatS2RangeFileFormatTest.java
+++ b/utils/satellite/s2storage/src/test/java/com/android/telephony/sats2range/SatS2RangeFileFormatTest.java
@@ -67,10 +67,12 @@
int suffixBitCount = 16;
int suffixTableBlockIdOffset = 5;
int suffixTableEntryBitCount = 24;
+ int suffixTableEntryValueSizeInBytes = 4;
+ int versionNumber = 2;
boolean isAllowedList = false;
SatS2RangeFileFormat satS2RangeFileFormat = new SatS2RangeFileFormat(s2Level,
prefixBitCount, suffixBitCount, suffixTableBlockIdOffset, suffixTableEntryBitCount,
- isAllowedList);
+ isAllowedList, suffixTableEntryValueSizeInBytes, versionNumber);
assertEquals(2, satS2RangeFileFormat.calculateRangeLength(
cellId(s2Level, 0, 0), cellId(s2Level, 0, 2)));
@@ -92,9 +94,11 @@
int suffixTableBlockIdOffset = 5;
int suffixTableEntryBitCount = 24;
boolean isAllowedList = true;
+ int suffixTableEntryValueSizeInBytes = 4;
+ int versionNumber = 2;
SatS2RangeFileFormat satS2RangeFileFormat = new SatS2RangeFileFormat(s2Level,
prefixBitCount, suffixBitCount, suffixTableBlockIdOffset, suffixTableEntryBitCount,
- isAllowedList);
+ isAllowedList, suffixTableEntryValueSizeInBytes, versionNumber);
// Too many bits for prefixValue
assertThrows(IllegalArgumentException.class,
@@ -127,9 +131,11 @@
int suffixTableBlockIdOffset = 5;
int suffixTableEntryBitCount = 24;
boolean isAllowedList = true;
+ int suffixTableEntryValueSizeInBytes = 4;
+ int versionNumber = 2;
SatS2RangeFileFormat satS2RangeFileFormat = new SatS2RangeFileFormat(s2Level,
prefixBitCount, suffixBitCount, suffixTableBlockIdOffset, suffixTableEntryBitCount,
- isAllowedList);
+ isAllowedList, suffixTableEntryValueSizeInBytes, versionNumber);
assertEquals(0, satS2RangeFileFormat.extractFaceIdFromPrefix(0b00000000000));
assertEquals(5, satS2RangeFileFormat.extractFaceIdFromPrefix(0b10100000000));
@@ -147,9 +153,11 @@
int suffixTableBlockIdOffset = 5;
int suffixTableEntryBitCount = 24;
boolean isAllowedList = true;
+ int suffixTableEntryValueSizeInBytes = 4;
+ int versionNumber = 2;
SatS2RangeFileFormat satS2RangeFileFormat = new SatS2RangeFileFormat(s2Level,
prefixBitCount, suffixBitCount, suffixTableBlockIdOffset, suffixTableEntryBitCount,
- isAllowedList);
+ isAllowedList, suffixTableEntryValueSizeInBytes, versionNumber);
// Too many bits for rangeLength
assertThrows(IllegalArgumentException.class,
@@ -161,6 +169,33 @@
assertTrue(satS2RangeFileFormat.isAllowedList());
}
+ @Test
+ public void extractEntryValueByteCount() {
+ int s2Level = 12;
+ int prefixBitCount = 11;
+ int suffixBitCount = 16;
+ int suffixTableBlockIdOffset = 5;
+ int suffixTableEntryBitCount = 24;
+ boolean isAllowedList = true;
+ final int[] suffixTableEntryValueSizeInBytes = {5};
+ int versionNumber = 1;
+
+ // Table entry byte count exceeds BYTE range.
+ assertThrows(IllegalArgumentException.class,
+ () -> new SatS2RangeFileFormat(s2Level, prefixBitCount, suffixBitCount,
+ suffixTableBlockIdOffset, suffixTableEntryBitCount, isAllowedList,
+ suffixTableEntryValueSizeInBytes[0], versionNumber));
+
+ suffixTableEntryValueSizeInBytes[0] = 1;
+ SatS2RangeFileFormat satS2RangeFileFormat = new SatS2RangeFileFormat(s2Level,
+ prefixBitCount, suffixBitCount, suffixTableBlockIdOffset, suffixTableEntryBitCount,
+ isAllowedList, suffixTableEntryValueSizeInBytes[0], versionNumber);
+
+ assertEquals(suffixTableEntryValueSizeInBytes[0],
+ satS2RangeFileFormat.getEntryValueSizeInBytes());
+ assertEquals(versionNumber, satS2RangeFileFormat.getVersionNumber());
+ }
+
private static int maxValForBits(int bits) {
return intPow2(bits) - 1;
}
diff --git a/utils/satellite/s2storage/src/test/java/com/android/telephony/sats2range/SatS2RangeFileReaderTest.java b/utils/satellite/s2storage/src/test/java/com/android/telephony/sats2range/SatS2RangeFileReaderTest.java
index bbfaef7..6de40e1 100644
--- a/utils/satellite/s2storage/src/test/java/com/android/telephony/sats2range/SatS2RangeFileReaderTest.java
+++ b/utils/satellite/s2storage/src/test/java/com/android/telephony/sats2range/SatS2RangeFileReaderTest.java
@@ -17,10 +17,11 @@
package com.android.telephony.sats2range;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
-import com.android.storage.s2.S2LevelRange;
import com.android.telephony.sats2range.read.SatS2RangeFileFormat;
import com.android.telephony.sats2range.read.SatS2RangeFileReader;
+import com.android.telephony.sats2range.read.SuffixTableRange;
import com.android.telephony.sats2range.utils.TestUtils;
import com.android.telephony.sats2range.write.SatS2RangeFileWriter;
@@ -38,24 +39,24 @@
SatS2RangeFileFormat fileFormat;
boolean isAllowedList = true;
- S2LevelRange expectedRange1, expectedRange2, expectedRange3;
+ SuffixTableRange expectedRange1, expectedRange2, expectedRange3;
try (SatS2RangeFileWriter satS2RangeFileWriter = SatS2RangeFileWriter.open(
file, TestUtils.createS2RangeFileFormat(isAllowedList))) {
fileFormat = satS2RangeFileWriter.getFileFormat();
// Two ranges that share a prefix.
- expectedRange1 = new S2LevelRange(
+ expectedRange1 = new SuffixTableRange(
TestUtils.createCellId(fileFormat, 1, 1000, 1000),
TestUtils.createCellId(fileFormat, 1, 1000, 2000));
- expectedRange2 = new S2LevelRange(
+ expectedRange2 = new SuffixTableRange(
TestUtils.createCellId(fileFormat, 1, 1000, 2000),
TestUtils.createCellId(fileFormat, 1, 1000, 3000));
// This range has a different prefix, so will be in a different suffix table.
- expectedRange3 = new S2LevelRange(
+ expectedRange3 = new SuffixTableRange(
TestUtils.createCellId(fileFormat, 1, 1001, 1000),
TestUtils.createCellId(fileFormat, 1, 1001, 2000));
- List<S2LevelRange> ranges = new ArrayList<>();
+ List<SuffixTableRange> ranges = new ArrayList<>();
ranges.add(expectedRange1);
ranges.add(expectedRange2);
ranges.add(expectedRange3);
@@ -65,17 +66,80 @@
try (SatS2RangeFileReader satS2RangeFileReader = SatS2RangeFileReader.open(file)) {
assertEquals(isAllowedList, satS2RangeFileReader.isAllowedList());
- S2LevelRange range1 = satS2RangeFileReader.findEntryByCellId(
+ SuffixTableRange range1 = satS2RangeFileReader.findEntryByCellId(
TestUtils.createCellId(fileFormat, 1, 1000, 1500));
assertEquals(expectedRange1, range1);
- S2LevelRange range2 = satS2RangeFileReader.findEntryByCellId(
+ SuffixTableRange range2 = satS2RangeFileReader.findEntryByCellId(
TestUtils.createCellId(fileFormat, 1, 1000, 2500));
assertEquals(expectedRange2, range2);
- S2LevelRange range3 = satS2RangeFileReader.findEntryByCellId(
+ SuffixTableRange range3 = satS2RangeFileReader.findEntryByCellId(
TestUtils.createCellId(fileFormat, 1, 1001, 1500));
assertEquals(expectedRange3, range3);
}
}
+
+ @Test
+ public void findEntryByCellIdWithEntryValue() throws IOException {
+ final boolean isAllowedList = true;
+ final int entryValueSizeInBytes = 4;
+ final int versionNumber = 0;
+ final int entryValue1 = 1;
+ final int entryValue2 = 2;
+ final int entryValue3 = 3;
+
+ File file = File.createTempFile("test", ".dat");
+ SatS2RangeFileFormat fileFormat;
+
+ SuffixTableRange expectedRange1, expectedRange2, expectedRange3;
+ try (SatS2RangeFileWriter satS2RangeFileWriter = SatS2RangeFileWriter.open(file,
+ TestUtils.createS2RangeFileFormat(isAllowedList, entryValueSizeInBytes,
+ versionNumber))) {
+ fileFormat = satS2RangeFileWriter.getFileFormat();
+
+ // Two ranges that share a prefix.
+ expectedRange1 = new SuffixTableRange(
+ TestUtils.createCellId(fileFormat, 1, 1000, 1000),
+ TestUtils.createCellId(fileFormat, 1, 1000, 2000),
+ entryValue1);
+ expectedRange2 = new SuffixTableRange(
+ TestUtils.createCellId(fileFormat, 1, 1000, 2000),
+ TestUtils.createCellId(fileFormat, 1, 1000, 3000),
+ entryValue2);
+ // This range has a different prefix, so will be in a different suffix table.
+ expectedRange3 = new SuffixTableRange(
+ TestUtils.createCellId(fileFormat, 1, 1001, 1000),
+ TestUtils.createCellId(fileFormat, 1, 1001, 2000),
+ entryValue3);
+
+ List<SuffixTableRange> ranges = new ArrayList<>();
+ ranges.add(expectedRange1);
+ ranges.add(expectedRange2);
+ ranges.add(expectedRange3);
+ satS2RangeFileWriter.createSortedSuffixBlocks(ranges.iterator());
+ }
+
+ try (SatS2RangeFileReader satS2RangeFileReader = SatS2RangeFileReader.open(file)) {
+ assertEquals(isAllowedList, satS2RangeFileReader.isAllowedList());
+
+ SuffixTableRange range1 = satS2RangeFileReader.findEntryByCellId(
+ TestUtils.createCellId(fileFormat, 1, 1000, 1500));
+ assertNotNull(range1);
+ assertEquals(expectedRange1, range1);
+ assertEquals(entryValue1, range1.getEntryValue());
+
+ SuffixTableRange range2 = satS2RangeFileReader.findEntryByCellId(
+ TestUtils.createCellId(fileFormat, 1, 1000, 2500));
+ assertNotNull(range2);
+ assertEquals(expectedRange2, range2);
+ assertEquals(entryValue2, range2.getEntryValue());
+
+ SuffixTableRange range3 = satS2RangeFileReader.findEntryByCellId(
+ TestUtils.createCellId(fileFormat, 1, 1001, 1500));
+ assertNotNull(range3);
+ assertEquals(expectedRange3, range3);
+ assertEquals(entryValue3, range3.getEntryValue());
+ }
+ }
}
diff --git a/utils/satellite/s2storage/src/test/java/com/android/telephony/sats2range/SuffixTableBlockTest.java b/utils/satellite/s2storage/src/test/java/com/android/telephony/sats2range/SuffixTableBlockTest.java
index 04b915b..7b9ce4a 100644
--- a/utils/satellite/s2storage/src/test/java/com/android/telephony/sats2range/SuffixTableBlockTest.java
+++ b/utils/satellite/s2storage/src/test/java/com/android/telephony/sats2range/SuffixTableBlockTest.java
@@ -24,9 +24,9 @@
import static org.mockito.ArgumentMatchers.argThat;
import com.android.storage.block.write.BlockWriter;
-import com.android.storage.s2.S2LevelRange;
import com.android.telephony.sats2range.read.SatS2RangeFileFormat;
import com.android.telephony.sats2range.read.SuffixTableBlock;
+import com.android.telephony.sats2range.read.SuffixTableRange;
import com.android.telephony.sats2range.read.SuffixTableSharedData;
import com.android.telephony.sats2range.utils.TestUtils;
import com.android.telephony.sats2range.write.SuffixTableWriter;
@@ -78,12 +78,14 @@
long invalidEndCellId = fileFormat.createCellId(tablePrefixValue + 1, maxSuffixValue);
long validEndCellId = fileFormat.createCellId(tablePrefixValue, maxSuffixValue);
{
- S2LevelRange badStartCellId = new S2LevelRange(invalidStartCellId, validEndCellId);
+ SuffixTableRange badStartCellId = new SuffixTableRange(invalidStartCellId,
+ validEndCellId);
assertThrows(IllegalArgumentException.class,
() -> suffixTableWriter.addRange(badStartCellId));
}
{
- S2LevelRange badEndCellId = new S2LevelRange(validStartCellId, invalidEndCellId);
+ SuffixTableRange badEndCellId = new SuffixTableRange(validStartCellId,
+ invalidEndCellId);
assertThrows(IllegalArgumentException.class,
() -> suffixTableWriter.addRange(badEndCellId));
}
@@ -101,13 +103,13 @@
SuffixTableWriter suffixTableWriter =
SuffixTableWriter.createPopulated(fileFormat, suffixTableSharedData);
- S2LevelRange suffixTableRange1 = new S2LevelRange(
+ SuffixTableRange suffixTableRange1 = new SuffixTableRange(
fileFormat.createCellId(tablePrefixValue, 1000),
fileFormat.createCellId(tablePrefixValue, 1001));
suffixTableWriter.addRange(suffixTableRange1);
// It's fine to add a range that starts adjacent to the last one.
- S2LevelRange suffixTableRange2 = new S2LevelRange(
+ SuffixTableRange suffixTableRange2 = new SuffixTableRange(
fileFormat.createCellId(tablePrefixValue, 1001),
fileFormat.createCellId(tablePrefixValue, 1002));
suffixTableWriter.addRange(suffixTableRange2);
@@ -117,7 +119,7 @@
() -> suffixTableWriter.addRange(suffixTableRange2));
// Try similar checks at the top end of the table.
- S2LevelRange suffixTableRange3 = new S2LevelRange(
+ SuffixTableRange suffixTableRange3 = new SuffixTableRange(
fileFormat.createCellId(tablePrefixValue, maxSuffixValue - 1),
fileFormat.createCellId(tablePrefixValue, maxSuffixValue));
suffixTableWriter.addRange(suffixTableRange3);
@@ -131,7 +133,7 @@
() -> suffixTableWriter.addRange(suffixTableRange3));
// Now "complete" the table: there can be no entry after this one.
- S2LevelRange suffixTableRange4 = new S2LevelRange(
+ SuffixTableRange suffixTableRange4 = new SuffixTableRange(
fileFormat.createCellId(tablePrefixValue, maxSuffixValue),
fileFormat.createCellId(tablePrefixValue + 1, 0));
suffixTableWriter.addRange(suffixTableRange4);
@@ -180,23 +182,23 @@
long entry1StartCellId = fileFormat.createCellId(tablePrefix, 1000);
long entry1EndCellId = fileFormat.createCellId(tablePrefix, 2000);
- S2LevelRange entry1 = new S2LevelRange(entry1StartCellId, entry1EndCellId);
+ SuffixTableRange entry1 = new SuffixTableRange(entry1StartCellId, entry1EndCellId);
suffixTableWriter.addRange(entry1);
long entry2StartCellId = fileFormat.createCellId(tablePrefix, 2000);
long entry2EndCellId = fileFormat.createCellId(tablePrefix, 3000);
- S2LevelRange entry2 = new S2LevelRange(entry2StartCellId, entry2EndCellId);
+ SuffixTableRange entry2 = new SuffixTableRange(entry2StartCellId, entry2EndCellId);
suffixTableWriter.addRange(entry2);
// There is a deliberate gap here between entry2 and entry3.
long entry3StartCellId = fileFormat.createCellId(tablePrefix, 4000);
long entry3EndCellId = fileFormat.createCellId(tablePrefix, 5000);
- S2LevelRange entry3 = new S2LevelRange(entry3StartCellId, entry3EndCellId);
+ SuffixTableRange entry3 = new SuffixTableRange(entry3StartCellId, entry3EndCellId);
suffixTableWriter.addRange(entry3);
long entry4StartCellId = fileFormat.createCellId(tablePrefix, maxSuffix - 999);
long entry4EndCellId = fileFormat.createCellId(tablePrefix + 1, 0);
- S2LevelRange entry4 = new S2LevelRange(entry4StartCellId, entry4EndCellId);
+ SuffixTableRange entry4 = new SuffixTableRange(entry4StartCellId, entry4EndCellId);
suffixTableWriter.addRange(entry4);
BlockWriter.ReadBack blockReadback = suffixTableWriter.close();
@@ -251,7 +253,7 @@
SuffixTableWriter.createPopulated(fileFormat, suffixTableSharedData);
long entry1StartCellId = fileFormat.createCellId(tablePrefix, 1000);
long entry1EndCellId = fileFormat.createCellId(tablePrefix, 2000);
- S2LevelRange entry1 = new S2LevelRange(entry1StartCellId, entry1EndCellId);
+ SuffixTableRange entry1 = new SuffixTableRange(entry1StartCellId, entry1EndCellId);
suffixTableWriter.addRange(entry1);
BlockWriter.ReadBack blockReadback = suffixTableWriter.close();
@@ -276,12 +278,12 @@
SuffixTableWriter suffixTableWriter =
SuffixTableWriter.createPopulated(fileFormat, sharedData);
- S2LevelRange entry1 = new S2LevelRange(
+ SuffixTableRange entry1 = new SuffixTableRange(
fileFormat.createCellId(tablePrefix, 1001),
fileFormat.createCellId(tablePrefix, 1101));
suffixTableWriter.addRange(entry1);
- S2LevelRange entry2 = new S2LevelRange(
+ SuffixTableRange entry2 = new SuffixTableRange(
fileFormat.createCellId(tablePrefix, 2001),
fileFormat.createCellId(tablePrefix, 2101));
suffixTableWriter.addRange(entry2);
@@ -302,7 +304,7 @@
inOrder.verify(mockVisitor).end();
}
- private S2LevelRange findEntryByCellId(SatS2RangeFileFormat fileFormat,
+ private SuffixTableRange findEntryByCellId(SatS2RangeFileFormat fileFormat,
SuffixTableBlock suffixTableBlock, int prefix, int suffix) {
long cellId = fileFormat.createCellId(prefix, suffix);
SuffixTableBlock.Entry entry = suffixTableBlock.findEntryByCellId(cellId);
diff --git a/utils/satellite/s2storage/src/test/java/com/android/telephony/sats2range/SuffixTableExtraInfoTest.java b/utils/satellite/s2storage/src/test/java/com/android/telephony/sats2range/SuffixTableExtraInfoTest.java
index f992ae7..f978bd5 100644
--- a/utils/satellite/s2storage/src/test/java/com/android/telephony/sats2range/SuffixTableExtraInfoTest.java
+++ b/utils/satellite/s2storage/src/test/java/com/android/telephony/sats2range/SuffixTableExtraInfoTest.java
@@ -20,9 +20,9 @@
import com.android.storage.block.read.BlockInfo;
import com.android.storage.block.write.BlockWriter;
-import com.android.storage.s2.S2LevelRange;
import com.android.telephony.sats2range.read.SatS2RangeFileFormat;
import com.android.telephony.sats2range.read.SuffixTableExtraInfo;
+import com.android.telephony.sats2range.read.SuffixTableRange;
import com.android.telephony.sats2range.read.SuffixTableSharedData;
import com.android.telephony.sats2range.utils.TestUtils;
import com.android.telephony.sats2range.write.SuffixTableWriter;
@@ -54,13 +54,13 @@
SuffixTableWriter.createPopulated(fileFormat, suffixTableSharedData);
int tablePrefix = suffixTableSharedData.getTablePrefix();
- S2LevelRange range1 = new S2LevelRange(
+ SuffixTableRange range1 = new SuffixTableRange(
fileFormat.createCellId(tablePrefix, 1000),
fileFormat.createCellId(tablePrefix, 1001));
- S2LevelRange range2 = new S2LevelRange(
+ SuffixTableRange range2 = new SuffixTableRange(
fileFormat.createCellId(tablePrefix, 1002),
fileFormat.createCellId(tablePrefix, 1003));
- S2LevelRange range3 = new S2LevelRange(
+ SuffixTableRange range3 = new SuffixTableRange(
fileFormat.createCellId(tablePrefix, 1004),
fileFormat.createCellId(tablePrefix, 1005));
diff --git a/utils/satellite/s2storage/src/test/java/com/android/telephony/sats2range/SuffixTableSharedDataTest.java b/utils/satellite/s2storage/src/test/java/com/android/telephony/sats2range/SuffixTableSharedDataTest.java
index 2baefa9..ee21626 100644
--- a/utils/satellite/s2storage/src/test/java/com/android/telephony/sats2range/SuffixTableSharedDataTest.java
+++ b/utils/satellite/s2storage/src/test/java/com/android/telephony/sats2range/SuffixTableSharedDataTest.java
@@ -18,11 +18,18 @@
import static org.junit.Assert.assertEquals;
+import com.android.storage.block.read.BlockData;
+import com.android.telephony.sats2range.read.SatS2RangeFileFormat;
import com.android.telephony.sats2range.read.SuffixTableSharedData;
import com.android.telephony.sats2range.write.SuffixTableSharedDataWriter;
import org.junit.Test;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
/** Tests for {@link SuffixTableSharedData} and {@link SuffixTableSharedDataWriter}. */
public class SuffixTableSharedDataTest {
@Test
@@ -33,5 +40,106 @@
assertEquals(sharedData, SuffixTableSharedData.fromBytes(bytes));
}
-}
+ @Test
+ public void testSuffixTableSharedDataWithEntryValues() {
+ int prefix = 321;
+ int entryValueSizeInBytes = 1;
+ List<Integer> entryValues = new ArrayList<>(Arrays.asList(0x01, 0x7F, 0xFF));
+ int versionNumber = 1;
+
+ // Verify whether fromTypedData returns correct SuffixTableSharedData when entryByte is 1
+ verifySharedData(prefix, entryValueSizeInBytes, entryValues.size(), entryValues,
+ versionNumber);
+
+ // Verify when entryValueSizeInBytes is 2
+ entryValueSizeInBytes = 2;
+ entryValues = new ArrayList<>(Arrays.asList(0x001, 0x5FFF, 0xAFFF, 0xFFFF));
+ verifySharedData(prefix, entryValueSizeInBytes, entryValues.size(), entryValues,
+ versionNumber);
+
+ // Verify when entryValueSizeInBytes is 3
+ entryValueSizeInBytes = 3;
+ entryValues = new ArrayList<>(
+ Arrays.asList(0x000001, 0x4FFFFF, 0x8FFFFF, 0xBFFFFF, 0xFFFFFF));
+ verifySharedData(prefix, entryValueSizeInBytes, entryValues.size(), entryValues,
+ versionNumber);
+
+ // Verify when entryValueSizeInBytes is 4, max int value is 0x7FFFFFFF.
+ // ConfigID is supported up to 0x7FFFFFFF for now.
+ entryValueSizeInBytes = 4;
+ entryValues = new ArrayList<>(
+ Arrays.asList(0x00000001, 0x2FFFFFFF, 0x3FFFFFFF, 0x4FFFFFFF, 0x5FFFFFFF,
+ 0x6FFFFFFF, 0x7FFFFFFF));
+ verifySharedData(prefix, entryValueSizeInBytes, entryValues.size(), entryValues,
+ versionNumber);
+
+ // Verify when every entry has same value.
+ entryValues = new ArrayList<>(
+ Arrays.asList(0x3FFFFFFF, 0x3FFFFFFF, 0x3FFFFFFF, 0x3FFFFFFF, 0x3FFFFFFF,
+ 0x3FFFFFFF, 0x3FFFFFFF));
+ verifySharedData(prefix, entryValueSizeInBytes, entryValues.size(), entryValues,
+ versionNumber);
+
+ // Verify when entry is empty
+ // entryValueSizeInBytes is set as 4, but there is no entry list
+ entryValues = new ArrayList<>(List.of());
+ verifySharedData(prefix, entryValueSizeInBytes, entryValues.size(), entryValues,
+ versionNumber);
+ // entryValueSizeInBytes is 0, no entry list
+ entryValueSizeInBytes = 0;
+ verifySharedData(prefix, entryValueSizeInBytes, entryValues.size(), entryValues,
+ versionNumber);
+ }
+
+ private BlockData createBlockedDataFromByteBuffer(int prefix,
+ List<Integer> entryValues, SatS2RangeFileFormat fileFormat) {
+ SuffixTableSharedData sharedDataToWrite = new SuffixTableSharedData(prefix, entryValues,
+ fileFormat);
+ ByteBuffer byteBuffer = ByteBuffer.wrap(
+ SuffixTableSharedDataWriter.toBytes(sharedDataToWrite));
+ return new BlockData(byteBuffer.asReadOnlyBuffer());
+ }
+
+ private void verifySharedData(int expectedTablePrefix, int expectedEntryValueSizeInBytes,
+ int expectedNumberOfEntryValues, List<Integer> expectedEntryValues, int versionNumber) {
+ SatS2RangeFileFormat fileFormat = createSatS2RangeFileFormat(expectedEntryValueSizeInBytes,
+ versionNumber);
+ BlockData blockData = createBlockedDataFromByteBuffer(
+ expectedTablePrefix, expectedEntryValues, fileFormat);
+ SuffixTableSharedData sharedData = SuffixTableSharedData.fromTypedData(blockData,
+ fileFormat);
+
+ assertEquals(expectedTablePrefix, sharedData.getTablePrefix());
+ if (!expectedEntryValues.isEmpty()) {
+ assertEquals(expectedEntryValueSizeInBytes, sharedData.getEntryValueSizeInBytes());
+ } else {
+ assertEquals(0, sharedData.getEntryValueSizeInBytes());
+ }
+
+ // If every entry has same value, block data contains only 1 entry info
+ if (expectedEntryValues.stream().distinct().count() == 1) {
+ assertEquals(3 * Integer.BYTES, blockData.getSize());
+ // Verify whether the entry value count has been set to 1.
+ assertEquals(1, sharedData.getNumberOfEntryValues());
+ } else {
+ assertEquals(expectedNumberOfEntryValues, sharedData.getNumberOfEntryValues());
+ }
+ for (int i = 0; i < expectedNumberOfEntryValues; i++) {
+ assertEquals((int) expectedEntryValues.get(i), sharedData.getEntryValue(i));
+ }
+ }
+
+ private SatS2RangeFileFormat createSatS2RangeFileFormat(int entryByteCount, int versionNumber) {
+ int s2Level = 12;
+ int prefixBitCount = 11;
+ int suffixBitCount = 16;
+ int suffixTableBlockIdOffset = 5;
+ int suffixTableEntryBitCount = 24;
+ boolean isAllowedList = true;
+
+ return new SatS2RangeFileFormat(s2Level,
+ prefixBitCount, suffixBitCount, suffixTableBlockIdOffset, suffixTableEntryBitCount,
+ isAllowedList, entryByteCount, versionNumber);
+ }
+}
diff --git a/utils/satellite/s2storage/src/testutils/java/com/android/telephony/sats2range/testutils/TestUtils.java b/utils/satellite/s2storage/src/testutils/java/com/android/telephony/sats2range/testutils/TestUtils.java
index 3dfc720..ca0b754 100644
--- a/utils/satellite/s2storage/src/testutils/java/com/android/telephony/sats2range/testutils/TestUtils.java
+++ b/utils/satellite/s2storage/src/testutils/java/com/android/telephony/sats2range/testutils/TestUtils.java
@@ -38,6 +38,14 @@
/** Returns a valid {@link SatS2RangeFileFormat}. */
public static SatS2RangeFileFormat createS2RangeFileFormat(boolean isAllowedList) {
+ return createS2RangeFileFormat(isAllowedList,
+ /* entryValueSizeInBytes */0,
+ /* versionNumber */0);
+ }
+
+ /** Returns a valid {@link SatS2RangeFileFormat}. */
+ public static SatS2RangeFileFormat createS2RangeFileFormat(boolean isAllowedList,
+ int entryValueSizeInBytes, int versionNumber) {
int dataS2Level = TEST_S2_LEVEL;
int faceIdBits = 3;
int bitCountPerLevel = 2;
@@ -48,7 +56,8 @@
int suffixTableEntryBitCount = 4 * Byte.SIZE;
int suffixTableBlockIdOffset = 5;
return new SatS2RangeFileFormat(dataS2Level, prefixBitCount, suffixBitCount,
- suffixTableBlockIdOffset, suffixTableEntryBitCount, isAllowedList);
+ suffixTableBlockIdOffset, suffixTableEntryBitCount, isAllowedList,
+ entryValueSizeInBytes, versionNumber);
}
/** Create an S2 cell ID */
diff --git a/utils/satellite/s2storage/src/write/java/com/android/telephony/sats2range/write/HeaderBlockWriter.java b/utils/satellite/s2storage/src/write/java/com/android/telephony/sats2range/write/HeaderBlockWriter.java
index d4e9310..0435922 100644
--- a/utils/satellite/s2storage/src/write/java/com/android/telephony/sats2range/write/HeaderBlockWriter.java
+++ b/utils/satellite/s2storage/src/write/java/com/android/telephony/sats2range/write/HeaderBlockWriter.java
@@ -63,6 +63,8 @@
tos.writeUnsignedByte(mFileFormat.getSuffixTableBlockIdOffset());
tos.writeUnsignedByte(mFileFormat.isAllowedList()
? HeaderBlock.TRUE : HeaderBlock.FALSE);
+ tos.writeUnsignedByte(mFileFormat.getEntryValueSizeInBytes());
+ tos.writeInt(mFileFormat.getVersionNumber());
}
FileChannel fileChannel = FileChannel.open(mFile.toPath(), StandardOpenOption.READ);
diff --git a/utils/satellite/s2storage/src/write/java/com/android/telephony/sats2range/write/SatS2RangeFileWriter.java b/utils/satellite/s2storage/src/write/java/com/android/telephony/sats2range/write/SatS2RangeFileWriter.java
index 9b3c20e..375707a 100644
--- a/utils/satellite/s2storage/src/write/java/com/android/telephony/sats2range/write/SatS2RangeFileWriter.java
+++ b/utils/satellite/s2storage/src/write/java/com/android/telephony/sats2range/write/SatS2RangeFileWriter.java
@@ -19,9 +19,9 @@
import com.android.storage.block.write.BlockFileWriter;
import com.android.storage.block.write.BlockWriter;
import com.android.storage.block.write.EmptyBlockWriter;
-import com.android.storage.s2.S2LevelRange;
import com.android.storage.s2.S2Support;
import com.android.telephony.sats2range.read.SatS2RangeFileFormat;
+import com.android.telephony.sats2range.read.SuffixTableRange;
import com.android.telephony.sats2range.read.SuffixTableSharedData;
import java.io.File;
@@ -64,8 +64,8 @@
* needed to fit them into suffix blocks. The ranges must be of the expected S2 level
* and ordered by cell ID.
*/
- public void createSortedSuffixBlocks(Iterator<S2LevelRange> ranges) throws IOException {
- PushBackIterator<S2LevelRange> pushBackIterator = new PushBackIterator<>(ranges);
+ public void createSortedSuffixBlocks(Iterator<SuffixTableRange> ranges) throws IOException {
+ PushBackIterator<SuffixTableRange> pushBackIterator = new PushBackIterator<>(ranges);
// For each prefix value, collect all the ranges that match.
for (int currentPrefix = 0;
@@ -74,7 +74,7 @@
// Step 1:
// populate samePrefixRanges, which holds ranges that have a prefix of currentPrefix.
- List<S2LevelRange> samePrefixRanges =
+ List<SuffixTableRange> samePrefixRanges =
collectSamePrefixRanges(pushBackIterator, currentPrefix);
// Step 2: Write samePrefixRanges to a suffix table.
@@ -88,11 +88,11 @@
}
}
- private List<S2LevelRange> collectSamePrefixRanges(
- PushBackIterator<S2LevelRange> pushBackIterator, int currentPrefix) {
- List<S2LevelRange> samePrefixRanges = new ArrayList<>();
+ private List<SuffixTableRange> collectSamePrefixRanges(
+ PushBackIterator<SuffixTableRange> pushBackIterator, int currentPrefix) {
+ List<SuffixTableRange> samePrefixRanges = new ArrayList<>();
while (pushBackIterator.hasNext()) {
- S2LevelRange currentRange = pushBackIterator.next();
+ SuffixTableRange currentRange = pushBackIterator.next();
long startCellId = currentRange.getStartCellId();
if (mFileFormat.getS2Level() != S2Support.getS2Level(startCellId)) {
@@ -123,17 +123,18 @@
// Create a range for the current prefix.
{
long newEndCellId = mFileFormat.createCellId(startCellPrefix + 1, 0);
- S2LevelRange satS2Range = new S2LevelRange(startCellId, newEndCellId);
+ SuffixTableRange satS2Range = new SuffixTableRange(startCellId, newEndCellId);
samePrefixRanges.add(satS2Range);
}
- Deque<S2LevelRange> otherRanges = new ArrayDeque<>();
+ Deque<SuffixTableRange> otherRanges = new ArrayDeque<>();
// Intermediate prefixes.
startCellPrefix = startCellPrefix + 1;
while (startCellPrefix != endCellPrefixValue) {
long newStartCellId = mFileFormat.createCellId(startCellPrefix, 0);
long newEndCellId = mFileFormat.createCellId(startCellPrefix + 1, 0);
- S2LevelRange satS2Range = new S2LevelRange(newStartCellId, newEndCellId);
+ SuffixTableRange satS2Range = new SuffixTableRange(newStartCellId,
+ newEndCellId);
otherRanges.add(satS2Range);
startCellPrefix++;
}
@@ -142,7 +143,8 @@
{
long newStartCellId = mFileFormat.createCellId(endCellPrefixValue, 0);
if (newStartCellId != endCellId) {
- S2LevelRange satS2Range = new S2LevelRange(newStartCellId, endCellId);
+ SuffixTableRange satS2Range = new SuffixTableRange(newStartCellId,
+ endCellId);
otherRanges.add(satS2Range);
}
}
@@ -160,41 +162,22 @@
}
private BlockWriter writeSamePrefixRanges(
- int currentPrefix, List<S2LevelRange> samePrefixRanges) throws IOException {
+ int currentPrefix, List<SuffixTableRange> samePrefixRanges) throws IOException {
BlockWriter blockWriter;
if (samePrefixRanges.size() == 0) {
// Add an empty block.
blockWriter = SuffixTableWriter.createEmptyBlockWriter();
} else {
+ List<SuffixTableRange> suffixTableRanges = convertSamePrefixRangesToSuffixTableRanges(
+ samePrefixRanges);
+ List<Integer> entryValues = getEntryValues(suffixTableRanges);
// Create a suffix table block.
- SuffixTableSharedData sharedData = new SuffixTableSharedData(currentPrefix);
+ SuffixTableSharedData sharedData = new SuffixTableSharedData(currentPrefix, entryValues,
+ mFileFormat);
SuffixTableWriter suffixTableWriter =
SuffixTableWriter.createPopulated(mFileFormat, sharedData);
- S2LevelRange lastRange = null;
- for (S2LevelRange currentRange : samePrefixRanges) {
- // Validate ranges don't overlap.
- if (lastRange != null) {
- if (lastRange.overlaps(currentRange)) {
- throw new IllegalStateException("lastRange=" + lastRange + " overlaps"
- + " currentRange=" + currentRange);
- }
- }
- lastRange = currentRange;
-
- // Split the range so it fits.
- final int maxRangeLength = mFileFormat.getTableEntryMaxRangeLengthValue();
- long startCellId = currentRange.getStartCellId();
- long endCellId = currentRange.getEndCellId();
- int rangeLength = mFileFormat.calculateRangeLength(startCellId, endCellId);
- while (rangeLength > maxRangeLength) {
- long newEndCellId = S2Support.offsetCellId(startCellId, maxRangeLength);
- S2LevelRange suffixTableRange = new S2LevelRange(startCellId, newEndCellId);
- suffixTableWriter.addRange(suffixTableRange);
- startCellId = newEndCellId;
- rangeLength = mFileFormat.calculateRangeLength(startCellId, endCellId);
- }
- S2LevelRange suffixTableRange = new S2LevelRange(startCellId, endCellId);
- suffixTableWriter.addRange(suffixTableRange);
+ for (SuffixTableRange range : suffixTableRanges) {
+ suffixTableWriter.addRange(range);
}
blockWriter = suffixTableWriter;
}
@@ -234,4 +217,48 @@
public SatS2RangeFileFormat getFileFormat() {
return mFileFormat;
}
+
+ private List<SuffixTableRange> convertSamePrefixRangesToSuffixTableRanges(
+ List<SuffixTableRange> samePrefixRanges) {
+ List<SuffixTableRange> suffixTableRanges = new ArrayList<>();
+ SuffixTableRange lastRange = null;
+ for (SuffixTableRange currentRange : samePrefixRanges) {
+ // Validate ranges don't overlap.
+ if (lastRange != null) {
+ if (lastRange.overlaps(currentRange)) {
+ throw new IllegalStateException("lastRange=" + lastRange + " overlaps"
+ + " currentRange=" + currentRange);
+ }
+ }
+ lastRange = currentRange;
+ int entryValue = currentRange.getEntryValue();
+
+ // Split the range so it fits.
+ final int maxRangeLength = mFileFormat.getTableEntryMaxRangeLengthValue();
+ long startCellId = currentRange.getStartCellId();
+ long endCellId = currentRange.getEndCellId();
+ int rangeLength = mFileFormat.calculateRangeLength(startCellId, endCellId);
+ while (rangeLength > maxRangeLength) {
+ long newEndCellId = S2Support.offsetCellId(startCellId, maxRangeLength);
+ SuffixTableRange suffixTableRange =
+ new SuffixTableRange(startCellId, newEndCellId, entryValue);
+ suffixTableRanges.add(suffixTableRange);
+ startCellId = newEndCellId;
+ rangeLength = mFileFormat.calculateRangeLength(startCellId, endCellId);
+ }
+ SuffixTableRange suffixTableRange =
+ new SuffixTableRange(startCellId, endCellId, entryValue);
+ suffixTableRanges.add(suffixTableRange);
+ }
+ return suffixTableRanges;
+ }
+
+ private List<Integer> getEntryValues(List<SuffixTableRange> suffixTableRanges) {
+ List<Integer> entryValues = new ArrayList<>();
+ for (SuffixTableRange suffixTableRange : suffixTableRanges) {
+ entryValues.add(suffixTableRange.getEntryValue());
+ }
+ return entryValues;
+ }
+
}
diff --git a/utils/satellite/s2storage/src/write/java/com/android/telephony/sats2range/write/SuffixTableSharedDataWriter.java b/utils/satellite/s2storage/src/write/java/com/android/telephony/sats2range/write/SuffixTableSharedDataWriter.java
index 5499148..a739e5e 100644
--- a/utils/satellite/s2storage/src/write/java/com/android/telephony/sats2range/write/SuffixTableSharedDataWriter.java
+++ b/utils/satellite/s2storage/src/write/java/com/android/telephony/sats2range/write/SuffixTableSharedDataWriter.java
@@ -21,21 +21,37 @@
import java.io.ByteArrayOutputStream;
import java.io.IOException;
+import java.util.List;
/**
* Converts a {@link SuffixTableSharedData} to a byte[] for writing.
* See also {@link SuffixTableSharedData#fromBytes(byte[])}.
*/
public final class SuffixTableSharedDataWriter {
-
+ private static final int BUFFER_SIZE = (int) Math.pow(2, 20);
private SuffixTableSharedDataWriter() {
}
/** Returns the byte[] for the supplied {@link SuffixTableSharedData} */
public static byte[] toBytes(SuffixTableSharedData suffixTableSharedData) {
+ int entryValueSizeInBytes = suffixTableSharedData.getEntryValueSizeInBytes();
+ List<Integer> entryValues = suffixTableSharedData.getEntryValuesToWrite();
+ // If every entry has same value, compress to save memory
+ int numberOfEntryValues =
+ entryValues.stream().distinct().count() == 1 ? 1 : entryValues.size();
+
try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
- TypedOutputStream tos = new TypedOutputStream(baos)) {
+ TypedOutputStream tos = new TypedOutputStream(baos, BUFFER_SIZE)) {
tos.writeInt(suffixTableSharedData.getTablePrefix());
+
+ if (entryValueSizeInBytes > 0 && !entryValues.isEmpty()) {
+ tos.writeInt(numberOfEntryValues);
+ for (int i = 0; i < numberOfEntryValues; i++) {
+ // ConfigId is supported up to 0x7FFFFFFF
+ tos.writeVarByteValue(entryValueSizeInBytes, entryValues.get(i));
+ }
+ }
+
tos.flush();
return baos.toByteArray();
} catch (IOException e) {
diff --git a/utils/satellite/s2storage/src/write/java/com/android/telephony/sats2range/write/SuffixTableWriter.java b/utils/satellite/s2storage/src/write/java/com/android/telephony/sats2range/write/SuffixTableWriter.java
index dc265d5..31b35eb 100644
--- a/utils/satellite/s2storage/src/write/java/com/android/telephony/sats2range/write/SuffixTableWriter.java
+++ b/utils/satellite/s2storage/src/write/java/com/android/telephony/sats2range/write/SuffixTableWriter.java
@@ -22,11 +22,11 @@
import com.android.storage.block.write.BlockWriter;
import com.android.storage.block.write.EmptyBlockWriter;
import com.android.storage.io.write.TypedOutputStream;
-import com.android.storage.s2.S2LevelRange;
import com.android.storage.s2.S2Support;
import com.android.storage.table.packed.write.PackedTableWriter;
import com.android.telephony.sats2range.read.SatS2RangeFileFormat;
import com.android.telephony.sats2range.read.SuffixTableExtraInfo;
+import com.android.telephony.sats2range.read.SuffixTableRange;
import com.android.telephony.sats2range.read.SuffixTableSharedData;
import java.io.ByteArrayOutputStream;
@@ -42,7 +42,7 @@
* To write empty tables use {@link #createEmptyBlockWriter()}.
* To write populated tables use {@link
* #createPopulated(SatS2RangeFileFormat, SuffixTableSharedData)} and add entries with
- * {@link #addRange(S2LevelRange)}
+ * {@link #addRange(SuffixTableRange)}
*/
public final class SuffixTableWriter implements BlockWriter {
@@ -54,7 +54,7 @@
private final File mFile;
- private S2LevelRange mLastRangeAdded;
+ private SuffixTableRange mLastRangeAdded;
private SuffixTableWriter(SatS2RangeFileFormat fileFormat, SuffixTableSharedData sharedData)
throws IOException {
@@ -90,7 +90,7 @@
* called at least once. See {@link SuffixTableWriter#createEmptyBlockWriter()} for empty
* tables.
*/
- public void addRange(S2LevelRange suffixTableRange) throws IOException {
+ public void addRange(SuffixTableRange suffixTableRange) throws IOException {
checkIsOpen();
long rangeStartCellId = suffixTableRange.getStartCellId();
diff --git a/utils/satellite/tools/src/main/java/com/android/telephony/tools/sats2/CreateTestSatS2File.java b/utils/satellite/tools/src/main/java/com/android/telephony/tools/sats2/CreateTestSatS2File.java
index f9a9347..41ce416 100644
--- a/utils/satellite/tools/src/main/java/com/android/telephony/tools/sats2/CreateTestSatS2File.java
+++ b/utils/satellite/tools/src/main/java/com/android/telephony/tools/sats2/CreateTestSatS2File.java
@@ -16,8 +16,8 @@
package com.android.telephony.tools.sats2;
-import com.android.storage.s2.S2LevelRange;
import com.android.telephony.sats2range.read.SatS2RangeFileFormat;
+import com.android.telephony.sats2range.read.SuffixTableRange;
import com.android.telephony.sats2range.write.SatS2RangeFileWriter;
import java.io.File;
@@ -42,18 +42,18 @@
try (SatS2RangeFileWriter satS2RangeFileWriter =
SatS2RangeFileWriter.open(file, fileFormat)) {
// Two ranges that share a prefix.
- S2LevelRange range1 = new S2LevelRange(
+ SuffixTableRange range1 = new SuffixTableRange(
fileFormat.createCellId(0b100_11111111, 1000),
fileFormat.createCellId(0b100_11111111, 2000));
- S2LevelRange range2 = new S2LevelRange(
+ SuffixTableRange range2 = new SuffixTableRange(
fileFormat.createCellId(0b100_11111111, 2000),
fileFormat.createCellId(0b100_11111111, 3000));
// This range has a different face, so a different prefix, and will be in a different
// suffix table.
- S2LevelRange range3 = new S2LevelRange(
+ SuffixTableRange range3 = new SuffixTableRange(
fileFormat.createCellId(0b101_11111111, 1000),
fileFormat.createCellId(0b101_11111111, 2000));
- List<S2LevelRange> allRanges = listOf(range1, range2, range3);
+ List<SuffixTableRange> allRanges = listOf(range1, range2, range3);
satS2RangeFileWriter.createSortedSuffixBlocks(allRanges.iterator());
}
}
diff --git a/utils/satellite/tools/src/main/java/com/android/telephony/tools/sats2/SatS2FileCreator.java b/utils/satellite/tools/src/main/java/com/android/telephony/tools/sats2/SatS2FileCreator.java
index dd7d8c0..1ed9680 100644
--- a/utils/satellite/tools/src/main/java/com/android/telephony/tools/sats2/SatS2FileCreator.java
+++ b/utils/satellite/tools/src/main/java/com/android/telephony/tools/sats2/SatS2FileCreator.java
@@ -16,9 +16,9 @@
package com.android.telephony.tools.sats2;
-import com.android.storage.s2.S2LevelRange;
import com.android.telephony.sats2range.read.SatS2RangeFileFormat;
import com.android.telephony.sats2range.read.SatS2RangeFileReader;
+import com.android.telephony.sats2range.read.SuffixTableRange;
import com.android.telephony.sats2range.write.SatS2RangeFileWriter;
import com.google.common.base.Stopwatch;
@@ -73,15 +73,15 @@
FileFormats.getFileFormatForLevel(s2Level, isAllowedList);
try (SatS2RangeFileWriter satS2RangeFileWriter =
SatS2RangeFileWriter.open(new File(outputFile), fileFormat)) {
- Iterator<S2LevelRange> s2LevelRangeIterator = satS2Ranges
+ Iterator<SuffixTableRange> suffixTableRangeIterator = satS2Ranges
.stream()
- .map(x -> new S2LevelRange(x.rangeStart.id(), x.rangeEnd.id()))
+ .map(x -> new SuffixTableRange(x.rangeStart.id(), x.rangeEnd.id()))
.iterator();
/*
* Group the sorted ranges into contiguous suffix blocks. Big ranges might get split as
* needed to fit them into suffix blocks.
*/
- satS2RangeFileWriter.createSortedSuffixBlocks(s2LevelRangeIterator);
+ satS2RangeFileWriter.createSortedSuffixBlocks(suffixTableRangeIterator);
}
// Validate the output block file