Merge "Clean up flag data_only_service_allow_emergency_call_only" into main
diff --git a/res/layout/radio_info.xml b/res/layout/radio_info.xml
index ab7307c..ac1f3f3 100644
--- a/res/layout/radio_info.xml
+++ b/res/layout/radio_info.xml
@@ -212,7 +212,9 @@
 
         <!-- Mock signal strength -->
         <LinearLayout style="@style/RadioInfo_entry_layout">
-            <TextView android:text="@string/radio_info_signal_strength_label" style="@style/info_label" />
+            <TextView android:id="@+id/signal_strength_label"
+                android:text="@string/radio_info_signal_strength_label"
+                style="@style/info_label" />
             <Spinner android:id="@+id/signalStrength"
                  android:layout_width="match_parent"
                  android:layout_height="wrap_content"/>
@@ -220,7 +222,9 @@
 
        <!-- Mock data network type -->
        <LinearLayout style="@style/RadioInfo_entry_layout">
-            <TextView android:text="@string/radio_info_data_network_type_label" style="@style/info_label" />
+            <TextView android:id="@+id/data_network_type_label"
+                android:text="@string/radio_info_data_network_type_label"
+                style="@style/info_label" />
             <Spinner android:id="@+id/dataNetworkType"
                  android:layout_width="match_parent"
                  android:layout_height="wrap_content"/>
diff --git a/res/values-gu/strings.xml b/res/values-gu/strings.xml
index dac357e..60b9b24 100644
--- a/res/values-gu/strings.xml
+++ b/res/values-gu/strings.xml
@@ -25,13 +25,13 @@
     <string name="private_num" msgid="4487990167889159992">"ખાનગી નંબર"</string>
     <string name="payphone" msgid="7936735771836716941">"પેફોન"</string>
     <string name="onHold" msgid="6132725550015899006">"હોલ્ડ પર"</string>
-    <string name="carrier_mmi_msg_title" msgid="6050165242447507034">"<xliff:g id="MMICARRIER">%s</xliff:g> સંદેશ"</string>
-    <string name="default_carrier_mmi_msg_title" msgid="7754317179938537213">"કૅરિઅરનો સંદેશ"</string>
+    <string name="carrier_mmi_msg_title" msgid="6050165242447507034">"<xliff:g id="MMICARRIER">%s</xliff:g> મેસેજ"</string>
+    <string name="default_carrier_mmi_msg_title" msgid="7754317179938537213">"કૅરિઅર મેસેજ"</string>
     <string name="mmiStarted" msgid="9212975136944568623">"MMI કોડ પ્રારંભ કર્યો"</string>
     <string name="ussdRunning" msgid="1163586813106772717">"USSD કોડ ચાલે છે…"</string>
     <string name="mmiCancelled" msgid="5339191899200678272">"MMI કોડ રદ કર્યો"</string>
     <string name="cancel" msgid="8984206397635155197">"રદ કરો"</string>
-    <string name="enter_input" msgid="6193628663039958990">"USSD સંદેશ <xliff:g id="MIN_LEN">%1$d</xliff:g> અને <xliff:g id="MAX_LEN">%2$d</xliff:g> વર્ણ વચ્ચેનો હોવો આવશ્યક છે. કૃપા કરીને ફરી પ્રયાસ કરો."</string>
+    <string name="enter_input" msgid="6193628663039958990">"USSD મેસેજ <xliff:g id="MIN_LEN">%1$d</xliff:g> અને <xliff:g id="MAX_LEN">%2$d</xliff:g> અક્ષરો વચ્ચે હોવો આવશ્યક છે. કૃપા કરીને ફરી પ્રયાસ કરો."</string>
     <string name="manageConferenceLabel" msgid="8415044818156353233">"કોન્ફરન્સ કૉલ સંચાલિત કરો"</string>
     <string name="ok" msgid="7818974223666140165">"ઓકે"</string>
     <string name="audio_mode_speaker" msgid="243689733219312360">"સ્પીકર્સ"</string>
@@ -173,7 +173,7 @@
     <string name="vm_change_pin_error_mismatch" msgid="5364847280026257331">"જૂનો PIN મેળ ખાતો નથી."</string>
     <string name="vm_change_pin_error_invalid" msgid="5230002671175580674">"નવો PIN અમાન્ય અક્ષરો ધરાવે છે."</string>
     <string name="vm_change_pin_error_system_error" msgid="9116483527909681791">"PIN બદલવામાં અસમર્થ"</string>
-    <string name="vvm_unsupported_message_format" msgid="4206402558577739713">"અસમર્થિત સંદેશ પ્રકાર, સાંભળવા માટે <xliff:g id="NUMBER">%s</xliff:g> પર કૉલ કરો."</string>
+    <string name="vvm_unsupported_message_format" msgid="4206402558577739713">"અનસપોર્ટેડ મેસેજ પ્રકાર, સાંભળવા માટે <xliff:g id="NUMBER">%s</xliff:g> પર કૉલ કરો."</string>
     <string name="network_settings_title" msgid="7560807107123171541">"મોબાઇલ નેટવર્ક"</string>
     <string name="label_available" msgid="1316084116670821258">"ઉપલબ્ધ નેટવર્ક્સ"</string>
     <string name="load_networks_progress" msgid="4051433047717401683">"શોધી રહ્યું છે..."</string>
@@ -548,7 +548,7 @@
     <string name="incall_error_out_of_service_wfc_2g_user" msgid="8218768986365299663">"મોબાઇલ નેટવર્ક ઉપલબ્ધ નથી.\n\nકોઈ કૉલ કરવા માટે, વાયરલેસ નેટવર્કથી કનેક્ટ કરો.\n\nઆ ડિવાઇસ પર 2G સેવા બંધ છે, જે તમારી કનેક્ટિવિટીને અસર કરી શકે છે. સેટિંગમાં જાઓ અને આ સેવાને ચાલુ રાખવા માટે \'2Gને મંજૂરી આપો\' ચાલુ કરો."</string>
     <string name="incall_error_no_phone_number_supplied" msgid="8680831089508851894">"કૉલ કરવા માટે, માન્ય નંબર દાખલ કરો."</string>
     <string name="incall_error_call_failed" msgid="393508653582682539">"કૉલ નિષ્ફળ થયો."</string>
-    <string name="incall_error_cannot_add_call" msgid="5425764862628655443">"આ સમયે કૉલ ઉમેરી શકાતો નથી. તમે એક સંદેશ મોકલીને સંપર્ક કરવાનો પ્રયાસ કરી શકો છો."</string>
+    <string name="incall_error_cannot_add_call" msgid="5425764862628655443">"આ સમયે કૉલ ઉમેરી શકાતો નથી. તમે એક મેસેજ મોકલીને સંપર્ક કરવાનો પ્રયાસ કરી શકો છો."</string>
     <string name="incall_error_supp_service_unknown" msgid="8751177117194592623">"સેવા સમર્થિત નથી"</string>
     <string name="incall_error_supp_service_switch" msgid="5272822448189448479">"કૉલ્સ સ્વિચ કરી શકાતા નથી."</string>
     <string name="incall_error_supp_service_resume" msgid="1276861499306817035">"કૉલ ફરી શરૂ કરી શકતા નથી."</string>
@@ -601,8 +601,8 @@
     <string name="hac_mode_title" msgid="4127986689621125468">"સાંભળવામાં સહાયતા"</string>
     <string name="hac_mode_summary" msgid="7774989500136009881">"સાંભળવામાં સહાયતા સુસંગતતા ચાલુ કરો"</string>
     <string name="rtt_mode_title" msgid="3075948111362818043">"રિઅલ-ટાઇમ ટેક્સ્ટ(RTT) કૉલ"</string>
-    <string name="rtt_mode_summary" msgid="8631541375609989562">"વૉઇસ કૉલ અંતર્ગત સંદેશ મોકલવાની મંજૂરી આપો"</string>
-    <string name="rtt_mode_more_information" msgid="587500128658756318">"RTT બહેરા, સાંભળવા અને બોલવામાં મુશ્કેલી પડતી હોય અથવા વૉઇસ કરતાં પણ વધુ કંઈકની જરૂર હોય એવા કૉલરની સહાય કરે છે.&lt;br&gt; &lt;a href=<xliff:g id="URL">http://support.google.com/mobile?p=telephony_rtt</xliff:g>&gt;વધુ જાણો&lt;/a&gt;\n       &lt;br&gt;&lt;br&gt; - RTT કૉલને સંદેશ ટ્રાન્સક્રિપ્ટ તરીકે સાચવવામાં આવે છે\n       &lt;br&gt; - RTT વીડિઓ કૉલ માટે ઉપલબ્ધ નથી"</string>
+    <string name="rtt_mode_summary" msgid="8631541375609989562">"વૉઇસ કૉલ અંતર્ગત મેસેજ મોકલવાની મંજૂરી આપો"</string>
+    <string name="rtt_mode_more_information" msgid="587500128658756318">"RTT બહેરા, સાંભળવા અને બોલવામાં મુશ્કેલી પડતી હોય અથવા વૉઇસ કરતાં પણ વધુ કંઈકની જરૂર હોય એવા કૉલરની સહાય કરે છે.&lt;br&gt; &lt;a href=<xliff:g id="URL">http://support.google.com/mobile?p=telephony_rtt</xliff:g>&gt;વધુ જાણો&lt;/a&gt;\n       &lt;br&gt;&lt;br&gt; - RTT કૉલને મેસેજ ટ્રાન્સક્રિપ્ટ તરીકે સાચવવામાં આવે છે\n       &lt;br&gt; - RTT વીડિયો કૉલ માટે ઉપલબ્ધ નથી"</string>
     <string name="no_rtt_when_roaming" msgid="5268008247378355389">"નોંધ: રોમિંગ વખતે RTT ઉપલબ્ધ નથી"</string>
   <string-array name="tty_mode_entries">
     <item msgid="3238070884803849303">"TTY બંધ"</item>
@@ -616,8 +616,8 @@
     <item msgid="2271798469250155310">"સામાન્ય"</item>
     <item msgid="6044210222666533564">"લાંબુ"</item>
   </string-array>
-    <string name="network_info_message" msgid="7599413947016532355">"નેટવર્ક સંદેશ"</string>
-    <string name="network_error_message" msgid="4271579424089326618">"ભૂલ સંદેશ"</string>
+    <string name="network_info_message" msgid="7599413947016532355">"નેટવર્ક મેસેજ"</string>
+    <string name="network_error_message" msgid="4271579424089326618">"ભૂલ મેસેજ"</string>
     <string name="ota_title_activate" msgid="4049645324841263423">"તમારા ફોનને સક્રિય કરો"</string>
     <string name="ota_touch_activate" msgid="838764494319694754">"તમારી ફોન સેવાને સક્રિય કરવા માટે એક વિશિષ્ટ કૉલની જરૂર છે. \n\n\"સક્રિય કરો\" દબાવ્યાં પછી, તમારા ફોનને સક્રિય કરવા માટે પ્રદાન કરવામાં આવેલ સૂચનાઓને અનુસરો."</string>
     <string name="ota_hfa_activation_title" msgid="3300556778212729671">"સક્રિય કરી રહ્યું છે…"</string>
@@ -680,7 +680,7 @@
     <string name="accessibility_settings_activity_title" msgid="7883415189273700298">"ઍક્સેસિબિલિટી"</string>
     <string name="status_hint_label_incoming_wifi_call" msgid="2606052595898044071">"આમના તરફથી Wi-Fi કૉલ"</string>
     <string name="status_hint_label_wifi_call" msgid="942993035689809853">"Wi-Fi કૉલ"</string>
-    <string name="message_decode_error" msgid="1061856591500290887">"સંદેશ ડીકોડિંગ કરતી વખતે ભૂલ આવી હતી."</string>
+    <string name="message_decode_error" msgid="1061856591500290887">"મેસેજ ડિકોડિંગ કરતી વખતે ભૂલ આવી હતી."</string>
     <string name="callFailed_cdma_activation" msgid="5392057031552253550">"એક SIM કાર્ડ એ તમારી સેવા સક્રિય કરી છે અને તમારા ફોનની રોમિંગ ક્ષમતાઓને અપડેટ કરી છે."</string>
     <string name="callFailed_cdma_call_limit" msgid="1074219746093031412">"અહીં ઘણા બધા સક્રિય કૉલ્સ છે. કૃપા કરીને એક નવો કૉલ કરવા પહેલાં અસ્તિત્વમાંના કૉલ્સને સમાપ્ત કરો અથવા મર્જ કરો."</string>
     <string name="callFailed_imei_not_accepted" msgid="7257903653685147251">"કનેક્ટ કરવામાં અસમર્થ, કૃપા કરીને એક માન્ય SIM કાર્ડ દાખલ કરો."</string>
@@ -899,7 +899,7 @@
     <string name="radio_info_signal_strength_label" msgid="5545444702102543260">"સિગ્નલની પ્રબળતા:"</string>
     <string name="radio_info_call_status_label" msgid="7693575431923095487">"વૉઇસ કૉલનું સ્ટેટસ:"</string>
     <string name="radio_info_ppp_sent_label" msgid="6542208429356199695">"ડેટા મોકલ્યો:"</string>
-    <string name="radio_info_message_waiting_label" msgid="1886549432566952078">"સંદેશ ઉપલબ્ધ છે:"</string>
+    <string name="radio_info_message_waiting_label" msgid="1886549432566952078">"મેસેજ ઉપલબ્ધ છે:"</string>
     <string name="radio_info_phone_number_label" msgid="2533852539562512203">"ફોન નંબર:"</string>
     <string name="radio_info_voice_network_type_label" msgid="2395347336419593265">"વૉઇસ નેટવર્ક પ્રકાર:"</string>
     <string name="radio_info_data_network_type_label" msgid="8886597029237501929">"ડેટા નેટવર્કનો પ્રકાર:"</string>
diff --git a/src/com/android/phone/CarrierConfigLoader.java b/src/com/android/phone/CarrierConfigLoader.java
index 7f720c2..46f20f5 100644
--- a/src/com/android/phone/CarrierConfigLoader.java
+++ b/src/com/android/phone/CarrierConfigLoader.java
@@ -1497,10 +1497,8 @@
         if (!SubscriptionManager.isValidPhoneId(phoneId)) {
             final String msg =
                     "Ignore invalid phoneId: " + phoneId + " for subId: " + subscriptionId;
-            if (mFeatureFlags.addAnomalyWhenNotifyConfigChangedWithInvalidPhone()) {
-                AnomalyReporter.reportAnomaly(
-                        UUID.fromString(UUID_NOTIFY_CONFIG_CHANGED_WITH_INVALID_PHONE), msg);
-            }
+            AnomalyReporter.reportAnomaly(
+                    UUID.fromString(UUID_NOTIFY_CONFIG_CHANGED_WITH_INVALID_PHONE), msg);
             logd(msg);
             throw new IllegalArgumentException(msg);
         }
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index f337704..e48a57a 100644
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -8159,31 +8159,15 @@
     @Override
     public void uploadCallComposerPicture(int subscriptionId, String callingPackage,
             String contentType, ParcelFileDescriptor fd, ResultReceiver callback) {
-        if (com.android.internal.telephony.flags.Flags.supportPhoneUidCheckForMultiuser()) {
-            enforceCallingPackage(callingPackage, Binder.getCallingUid(),
-                    "Invalid package:" + callingPackage);
-        } else {
-            try {
-                if (!Objects.equals(mApp.getPackageManager().getPackageUid(callingPackage, 0),
-                        Binder.getCallingUid())) {
-                    throw new SecurityException("Invalid package:" + callingPackage);
-                }
-            } catch (PackageManager.NameNotFoundException e) {
-                throw new SecurityException("Invalid package:" + callingPackage);
-            }
-        }
-
+        enforceCallingPackage(callingPackage, Binder.getCallingUid(),
+                "Invalid package:" + callingPackage);
         enforceTelephonyFeatureWithException(callingPackage,
                 PackageManager.FEATURE_TELEPHONY_CALLING, "uploadCallComposerPicture");
 
         RoleManager rm = mApp.getSystemService(RoleManager.class);
         List<String> dialerRoleHolders;
-        if (com.android.internal.telephony.flags.Flags.supportPhoneUidCheckForMultiuser()) {
-            dialerRoleHolders = rm.getRoleHoldersAsUser(RoleManager.ROLE_DIALER,
-                    UserHandle.of(ActivityManager.getCurrentUser()));
-        } else {
-            dialerRoleHolders = rm.getRoleHolders(RoleManager.ROLE_DIALER);
-        }
+        dialerRoleHolders = rm.getRoleHoldersAsUser(RoleManager.ROLE_DIALER,
+                UserHandle.of(ActivityManager.getCurrentUser()));
         if (!dialerRoleHolders.contains(callingPackage)) {
             throw new SecurityException("App must be the dialer role holder to"
                     + " upload a call composer pic");
@@ -14377,4 +14361,37 @@
             Binder.restoreCallingIdentity(identity);
         }
     }
+
+    /**
+     * 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
+     * config_satellite_carrier_roaming_esos_provisioned_class.
+     * These values are set before sending an intent to broadcast there are any change to list of
+     * subscriber informations.
+     *
+     * @param name the name is one of the following that constitute an intent.
+     * Component package name, or component class name.
+     * @return {@code true} if the setting is successful, {@code false} otherwise.
+     */
+    @Override
+    public boolean setSatelliteSubscriberIdListChangedIntentComponent(String name) {
+        if (!mFeatureFlags.carrierRoamingNbIotNtn()) {
+            Log.d(LOG_TAG, "setSatelliteSubscriberIdListChangedIntentComponent:"
+                    + " carrierRoamingNbIotNtn is disabled");
+            return false;
+        }
+        Log.d(LOG_TAG, "setSatelliteSubscriberIdListChangedIntentComponent");
+        TelephonyPermissions.enforceShellOnly(
+                Binder.getCallingUid(), "setSatelliteSubscriberIdListChangedIntentComponent");
+        TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
+                SubscriptionManager.INVALID_SUBSCRIPTION_ID,
+                "setSatelliteSubscriberIdListChangedIntentComponent");
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            return mSatelliteController.setSatelliteSubscriberIdListChangedIntentComponent(name);
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
 }
diff --git a/src/com/android/phone/TelephonyShellCommand.java b/src/com/android/phone/TelephonyShellCommand.java
index 7a424cb..08b041b 100644
--- a/src/com/android/phone/TelephonyShellCommand.java
+++ b/src/com/android/phone/TelephonyShellCommand.java
@@ -209,6 +209,8 @@
             "set-should-send-datagram-to-modem-in-demo-mode";
     private static final String SET_IS_SATELLITE_COMMUNICATION_ALLOWED_FOR_CURRENT_LOCATION_CACHE =
             "set-is-satellite-communication-allowed-for-current-location-cache";
+    private static final String SET_SATELLITE_SUBSCRIBERID_LIST_CHANGED_INTENT_COMPONENT =
+            "set-satellite-subscriberid-list-changed-intent-component";
 
     private static final String DOMAIN_SELECTION_SUBCOMMAND = "domainselection";
     private static final String DOMAIN_SELECTION_SET_SERVICE_OVERRIDE = "set-dss-override";
@@ -422,6 +424,8 @@
                 return handleSetOemEnabledSatelliteProvisionStatus();
             case SET_IS_SATELLITE_COMMUNICATION_ALLOWED_FOR_CURRENT_LOCATION_CACHE:
                 return handleSetIsSatelliteCommunicationAllowedForCurrentLocationCache();
+            case SET_SATELLITE_SUBSCRIBERID_LIST_CHANGED_INTENT_COMPONENT:
+                return handleSetSatelliteSubscriberIdListChangedIntentComponent();
             default: {
                 return handleDefaultCommands(cmd);
             }
@@ -3766,6 +3770,54 @@
         return 0;
     }
 
+    private int handleSetSatelliteSubscriberIdListChangedIntentComponent() {
+        final String cmd = SET_SATELLITE_SUBSCRIBERID_LIST_CHANGED_INTENT_COMPONENT;
+        PrintWriter errPw = getErrPrintWriter();
+        String opt;
+        String name;
+
+        if ((opt = getNextArg()) == null) {
+            errPw.println("adb shell cmd phone " + cmd + ": Invalid Argument");
+            return -1;
+        } else {
+            switch (opt) {
+                case "-p": {
+                    name = opt + "/" + "android.telephony.cts";
+                    break;
+                }
+                case "-c": {
+                    name = opt + "/" + "android.telephony.cts.SatelliteReceiver";
+                    break;
+                }
+                case "-r": {
+                    name = "reset";
+                    break;
+                }
+                default:
+                    errPw.println("adb shell cmd phone " + cmd + ": Invalid Argument");
+                    return -1;
+            }
+        }
+
+        Log.d(LOG_TAG, "handleSetSatelliteSubscriberIdListChangedIntentComponent("
+                + name + ")");
+
+        try {
+            boolean result = mInterface.setSatelliteSubscriberIdListChangedIntentComponent(name);
+            if (VDBG) {
+                Log.v(LOG_TAG, "handleSetSatelliteSubscriberIdListChangedIntentComponent "
+                        + "returns: " + result);
+            }
+            getOutPrintWriter().println(result);
+        } catch (RemoteException e) {
+            Log.w(LOG_TAG, "handleSetSatelliteSubscriberIdListChangedIntentComponent("
+                    + name + "), error = " + e.getMessage());
+            errPw.println("Exception: " + e.getMessage());
+            return -1;
+        }
+        return 0;
+    }
+
     /**
      * Sample inputStr = "US,UK,CA;2,1,3"
      * Sample output: {[US,2], [UK,1], [CA,3]}
diff --git a/src/com/android/phone/satellite/accesscontrol/SatelliteAccessController.java b/src/com/android/phone/satellite/accesscontrol/SatelliteAccessController.java
index 2a64caa..ce77a92 100644
--- a/src/com/android/phone/satellite/accesscontrol/SatelliteAccessController.java
+++ b/src/com/android/phone/satellite/accesscontrol/SatelliteAccessController.java
@@ -19,7 +19,9 @@
 import static android.telephony.satellite.SatelliteManager.KEY_SATELLITE_COMMUNICATION_ALLOWED;
 import static android.telephony.satellite.SatelliteManager.KEY_SATELLITE_PROVISIONED;
 import static android.telephony.satellite.SatelliteManager.KEY_SATELLITE_SUPPORTED;
+import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_LOCATION_DISABLED;
 import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_LOCATION_NOT_AVAILABLE;
+import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_NOT_SUPPORTED;
 import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED;
 import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_SUCCESS;
 
@@ -964,7 +966,8 @@
         return true;
     }
 
-    private void handleIsSatelliteSupportedResult(int resultCode, Bundle resultData) {
+    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
+    protected void handleIsSatelliteSupportedResult(int resultCode, Bundle resultData) {
         plogd("handleIsSatelliteSupportedResult: resultCode=" + resultCode);
         synchronized (mLock) {
             if (resultCode == SATELLITE_RESULT_SUCCESS) {
@@ -975,7 +978,8 @@
                         Bundle bundle = new Bundle();
                         bundle.putBoolean(SatelliteManager.KEY_SATELLITE_COMMUNICATION_ALLOWED,
                                 false);
-                        sendSatelliteAllowResultToReceivers(resultCode, bundle, false);
+                        sendSatelliteAllowResultToReceivers(SATELLITE_RESULT_NOT_SUPPORTED, bundle,
+                                false);
                     } else {
                         plogd("Satellite is supported");
                         List<String> networkCountryIsoList =
@@ -1031,6 +1035,7 @@
 
     private void sendSatelliteAllowResultToReceivers(int resultCode, Bundle resultData,
             boolean allowed) {
+        plogd("sendSatelliteAllowResultToReceivers : resultCode is " + resultCode);
         if (resultCode == SATELLITE_RESULT_SUCCESS) {
             updateCurrentSatelliteAllowedState(allowed);
         }
@@ -1183,7 +1188,8 @@
                 plogv("location query is not allowed");
                 Bundle bundle = new Bundle();
                 bundle.putBoolean(KEY_SATELLITE_COMMUNICATION_ALLOWED, false);
-                sendSatelliteAllowResultToReceivers(SATELLITE_RESULT_SUCCESS, bundle, false);
+                sendSatelliteAllowResultToReceivers(
+                        SATELLITE_RESULT_LOCATION_DISABLED, bundle, false);
             }
         }
     }
diff --git a/src/com/android/phone/settings/RadioInfo.java b/src/com/android/phone/settings/RadioInfo.java
index 70986a5..dcd6971 100644
--- a/src/com/android/phone/settings/RadioInfo.java
+++ b/src/com/android/phone/settings/RadioInfo.java
@@ -20,8 +20,8 @@
 
 import static java.util.concurrent.TimeUnit.MILLISECONDS;
 
+import android.annotation.NonNull;
 import android.content.ComponentName;
-import android.content.Context;
 import android.content.DialogInterface;
 import android.content.Intent;
 import android.content.pm.ComponentInfo;
@@ -29,7 +29,6 @@
 import android.content.pm.ResolveInfo;
 import android.content.res.Resources;
 import android.graphics.Typeface;
-import android.hardware.radio.modem.ImeiInfo;
 import android.net.ConnectivityManager;
 import android.net.Network;
 import android.net.NetworkCapabilities;
@@ -41,6 +40,7 @@
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.HandlerExecutor;
+import android.os.HandlerThread;
 import android.os.Message;
 import android.os.PersistableBundle;
 import android.os.SystemProperties;
@@ -110,21 +110,24 @@
 import com.android.internal.telephony.PhoneFactory;
 import com.android.internal.telephony.RILConstants;
 import com.android.internal.telephony.euicc.EuiccConnector;
-import com.android.internal.telephony.util.TelephonyUtils;
 import com.android.phone.R;
 
 import java.io.IOException;
 import java.net.HttpURLConnection;
 import java.net.URL;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
+import java.util.Locale;
 import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.LinkedBlockingDeque;
 import java.util.concurrent.ThreadPoolExecutor;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
+import java.util.concurrent.atomic.AtomicBoolean;
 
 /**
  * Radio Information Class
@@ -249,7 +252,6 @@
 
     private static final int EVENT_QUERY_SMSC_DONE = 1005;
     private static final int EVENT_UPDATE_SMSC_DONE = 1006;
-    private static final int EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED = 1007;
     private static final int EVENT_UPDATE_NR_STATS = 1008;
 
     private static final int MENU_ITEM_VIEW_ADN            = 1;
@@ -346,6 +348,8 @@
     private boolean mMwiValue = false;
     private boolean mCfiValue = false;
 
+    private boolean mSystemUser = true;
+
     private final PersistableBundle[] mCarrierSatelliteOriginalBundle = new PersistableBundle[2];
     private final PersistableBundle[] mOriginalSystemChannels = new PersistableBundle[2];
     private List<CellInfo> mCellInfoResult = null;
@@ -356,11 +360,17 @@
 
     private int mPreferredNetworkTypeResult;
     private int mCellInfoRefreshRateIndex;
-    private int mSelectedPhoneIndex;
+    private int mPhoneId = SubscriptionManager.INVALID_PHONE_INDEX;
+
+    private int mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
 
     private String mActionEsos;
     private String mActionEsosDemo;
 
+    private TelephonyDisplayInfo mDisplayInfo;
+
+    private List<PhysicalChannelConfig> mPhysicalChannelConfigs = new ArrayList<>();
+
     private final NetworkRequest mDefaultNetworkRequest = new NetworkRequest.Builder()
             .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
             .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
@@ -387,6 +397,7 @@
             TelephonyCallback.CellInfoListener,
             TelephonyCallback.SignalStrengthsListener,
             TelephonyCallback.ServiceStateListener,
+            TelephonyCallback.PhysicalChannelConfigListener,
             TelephonyCallback.DisplayInfoListener {
 
         @Override
@@ -451,16 +462,23 @@
 
         @Override
         public void onDisplayInfoChanged(TelephonyDisplayInfo displayInfo) {
+            mDisplayInfo = displayInfo;
             updateNetworkType();
         }
+
+        @Override
+        public void onPhysicalChannelConfigChanged(@NonNull List<PhysicalChannelConfig> configs) {
+            updatePhysicalChannelConfiguration(configs);
+        }
     }
 
     private void updatePhysicalChannelConfiguration(List<PhysicalChannelConfig> configs) {
+        mPhysicalChannelConfigs = configs;
         StringBuilder sb = new StringBuilder();
         String div = "";
         sb.append("{");
-        if (configs != null) {
-            for (PhysicalChannelConfig c : configs) {
+        if (mPhysicalChannelConfigs != null) {
+            for (PhysicalChannelConfig c : mPhysicalChannelConfigs) {
                 sb.append(div).append(c);
                 div = ",";
             }
@@ -479,24 +497,21 @@
         mPreferredNetworkType.setSelection(mPreferredNetworkTypeResult, true);
     }
 
-    private void updatePhoneIndex(int phoneIndex, int subId) {
+    private void updatePhoneIndex() {
         // unregister listeners on the old subId
         unregisterPhoneStateListener();
-        mTelephonyManager.setCellInfoListRate(sCellInfoListRateDisabled, mPhone.getSubId());
-
-        if (phoneIndex == SubscriptionManager.INVALID_PHONE_INDEX) {
-            log("Invalid phone index " + phoneIndex + ", subscription ID " + subId);
-            return;
-        }
+        mTelephonyManager.setCellInfoListRate(sCellInfoListRateDisabled, mSubId);
 
         // update the subId
-        mTelephonyManager = mTelephonyManager.createForSubscriptionId(subId);
+        mTelephonyManager = mTelephonyManager.createForSubscriptionId(mSubId);
 
         // update the phoneId
-        mPhone = PhoneFactory.getPhone(phoneIndex);
-        mImsManager = new ImsManager(mPhone.getContext());
+        if (mSystemUser) {
+            mPhone = PhoneFactory.getPhone(mPhoneId);
+        }
+        mImsManager = new ImsManager(this);
         try {
-            mProvisioningManager = ProvisioningManager.createForSubscriptionId(subId);
+            mProvisioningManager = ProvisioningManager.createForSubscriptionId(mSubId);
         } catch (IllegalArgumentException e) {
             log("updatePhoneIndex : IllegalArgumentException " + e.getMessage());
             mProvisioningManager = null;
@@ -525,13 +540,6 @@
                         mSmsc.setText("update error");
                     }
                     break;
-                case EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED:
-                    ar = (AsyncResult) msg.obj;
-                    if (ar.exception != null) {
-                        mPhyChanConfig.setText(("update error"));
-                    }
-                    updatePhysicalChannelConfiguration((List<PhysicalChannelConfig>) ar.result);
-                    break;
                 case EVENT_UPDATE_NR_STATS:
                     log("got EVENT_UPDATE_NR_STATS");
                     updateNrStats();
@@ -547,16 +555,9 @@
     @Override
     public void onCreate(Bundle icicle) {
         super.onCreate(icicle);
-        try {
-            PhoneFactory.getDefaultPhone();
-        } catch (Exception e) {
-            loge("Do nothing due to getDefaultPhone " + e);
-            finish();
-            return;
-        }
-
-        UserManager userManager =
-                (UserManager) getApplicationContext().getSystemService(Context.USER_SERVICE);
+        mSystemUser = android.os.Process.myUserHandle().isSystem();
+        log("onCreate: mSystemUser=" + mSystemUser);
+        UserManager userManager = getSystemService(UserManager.class);
         if (userManager != null
                 && userManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS)) {
             Log.w(TAG, "User is restricted from configuring mobile networks.");
@@ -565,9 +566,6 @@
         }
 
         setContentView(R.layout.radio_info);
-
-        log("Started onCreate");
-
         Resources r = getResources();
         mActionEsos =
             r.getString(
@@ -579,16 +577,20 @@
                     com.android.internal.R.string.config_satellite_demo_mode_sos_intent_action);
 
         mQueuedWork = new ThreadPoolExecutor(1, 1, RUNNABLE_TIMEOUT_MS, TimeUnit.MICROSECONDS,
-                new LinkedBlockingDeque<Runnable>());
-        mConnectivityManager = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
-        mPhone = getPhone(SubscriptionManager.getDefaultSubscriptionId());
-        mTelephonyManager = ((TelephonyManager) getSystemService(TELEPHONY_SERVICE))
-                .createForSubscriptionId(mPhone.getSubId());
+                new LinkedBlockingDeque<>());
+        mConnectivityManager = getSystemService(ConnectivityManager.class);
+        if (mSystemUser) {
+            mPhone = getPhone(SubscriptionManager.getDefaultSubscriptionId());
+        }
+        mSubId = SubscriptionManager.getDefaultSubscriptionId();
+        mPhoneId = SubscriptionManager.getPhoneId(mSubId);
+        mTelephonyManager = getSystemService(TelephonyManager.class)
+                .createForSubscriptionId(mSubId);
         mEuiccManager = getSystemService(EuiccManager.class);
 
-        mImsManager = new ImsManager(mPhone.getContext());
+        mImsManager = new ImsManager(this);
         try {
-            mProvisioningManager = ProvisioningManager.createForSubscriptionId(mPhone.getSubId());
+            mProvisioningManager = ProvisioningManager.createForSubscriptionId(mSubId);
         } catch (IllegalArgumentException e) {
             log("onCreate : IllegalArgumentException " + e.getMessage());
             mProvisioningManager = null;
@@ -647,8 +649,10 @@
         mPreferredNetworkType.setAdapter(mPreferredNetworkTypeAdapter);
 
         mMockSignalStrength = (Spinner) findViewById(R.id.signalStrength);
-        if (!TelephonyUtils.IS_DEBUGGABLE) {
+        if (!Build.isDebuggable() || !mSystemUser) {
             mMockSignalStrength.setVisibility(View.GONE);
+            findViewById(R.id.signalStrength).setVisibility(View.GONE);
+            findViewById(R.id.signal_strength_label).setVisibility(View.GONE);
         } else {
             ArrayAdapter<Integer> mSignalStrengthAdapter = new ArrayAdapter<>(this,
                     android.R.layout.simple_spinner_item, SIGNAL_STRENGTH_LEVEL);
@@ -658,8 +662,10 @@
         }
 
         mMockDataNetworkType = (Spinner) findViewById(R.id.dataNetworkType);
-        if (!TelephonyUtils.IS_DEBUGGABLE) {
+        if (!Build.isDebuggable() || !mSystemUser) {
             mMockDataNetworkType.setVisibility(View.GONE);
+            findViewById(R.id.dataNetworkType).setVisibility(View.GONE);
+            findViewById(R.id.data_network_type_label).setVisibility(View.GONE);
         } else {
             ArrayAdapter<String> mNetworkTypeAdapter = new ArrayAdapter<>(this,
                     android.R.layout.simple_spinner_item, Arrays.stream(MOCK_DATA_NETWORK_TYPE)
@@ -686,7 +692,7 @@
         mImsWfcProvisionedSwitch = (Switch) findViewById(R.id.wfc_provisioned_switch);
         mEabProvisionedSwitch = (Switch) findViewById(R.id.eab_provisioned_switch);
 
-        if (!isImsSupportedOnDevice(mPhone.getContext())) {
+        if (!isImsSupportedOnDevice()) {
             mImsVolteProvisionedSwitch.setVisibility(View.GONE);
             mImsVtProvisionedSwitch.setVisibility(View.GONE);
             mImsWfcProvisionedSwitch.setVisibility(View.GONE);
@@ -723,13 +729,13 @@
         mRadioPowerOnSwitch = (Switch) findViewById(R.id.radio_power);
 
         mSimulateOutOfServiceSwitch = (Switch) findViewById(R.id.simulate_out_of_service);
-        if (!TelephonyUtils.IS_DEBUGGABLE) {
+        if (!Build.isDebuggable()) {
             mSimulateOutOfServiceSwitch.setVisibility(View.GONE);
         }
 
         mMockSatellite = (Switch) findViewById(R.id.mock_carrier_roaming_satellite);
         mEnforceSatelliteChannel = (Switch) findViewById(R.id.enforce_satellite_channel);
-        if (!TelephonyUtils.IS_DEBUGGABLE) {
+        if (!Build.isDebuggable()) {
             mMockSatellite.setVisibility(View.GONE);
             mEnforceSatelliteChannel.setVisibility(View.GONE);
         }
@@ -744,6 +750,12 @@
         mUpdateSmscButton.setOnClickListener(mUpdateSmscButtonHandler);
         mRefreshSmscButton = (Button) findViewById(R.id.refresh_smsc);
         mRefreshSmscButton.setOnClickListener(mRefreshSmscButtonHandler);
+        if (!mSystemUser) {
+            mSmsc.setVisibility(View.GONE);
+            mUpdateSmscButton.setVisibility(View.GONE);
+            mRefreshSmscButton.setVisibility(View.GONE);
+            findViewById(R.id.smsc_label).setVisibility(View.GONE);
+        }
         mCarrierProvisioningButton = (Button) findViewById(R.id.carrier_provisioning);
         if (!TextUtils.isEmpty(getCarrierProvisioningAppString())) {
             mCarrierProvisioningButton.setOnClickListener(mCarrierProvisioningButtonHandler);
@@ -764,13 +776,13 @@
         mEsosDemoButton  = (Button) findViewById(R.id.demo_esos_questionnaire);
         mSatelliteEnableNonEmergencyModeButton = (Button) findViewById(
                 R.id.satellite_enable_non_emergency_mode);
-        CarrierConfigManager cm = mPhone.getContext().getSystemService(CarrierConfigManager.class);
-        if (!cm.getConfigForSubId(mPhone.getSubId(),
+        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 (!TelephonyUtils.IS_DEBUGGABLE) {
+        if (!Build.isDebuggable()) {
             if (!TextUtils.isEmpty(mActionEsos)) {
                 mEsosButton.setVisibility(View.GONE);
             }
@@ -779,16 +791,13 @@
             }
             mSatelliteEnableNonEmergencyModeButton.setVisibility(View.GONE);
         } else {
-            mEsosButton.setOnClickListener(v ->
-                    mPhone.getContext().startActivity(
-                        new Intent(mActionEsos)
-                        .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK))
+            mEsosButton.setOnClickListener(v -> startActivity(
+                    new Intent(mActionEsos).addFlags(
+                            Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK))
             );
-            mEsosDemoButton.setOnClickListener(v ->
-                    mPhone.getContext().startActivity(
-                            new Intent(mActionEsosDemo)
-                                    .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
-                                            | Intent.FLAG_ACTIVITY_CLEAR_TASK))
+            mEsosDemoButton.setOnClickListener(v -> startActivity(
+                    new Intent(mActionEsosDemo).addFlags(
+                            Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK))
             );
             mSatelliteEnableNonEmergencyModeButton.setOnClickListener(v ->
                     enableSatelliteNonEmergencyMode());
@@ -805,7 +814,6 @@
 
         mCellInfoRefreshRateIndex = 0; //disabled
         mPreferredNetworkTypeResult = PREFERRED_NETWORK_LABELS.length - 1; //Unknown
-        mSelectedPhoneIndex = mPhone.getPhoneId();
 
         new Thread(() -> {
             int networkType = (int) mTelephonyManager.getPreferredNetworkTypeBitmask();
@@ -859,7 +867,7 @@
         mCellInfoRefreshRateSpinner.setSelection(mCellInfoRefreshRateIndex);
         // Request cell information update from RIL.
         mTelephonyManager.setCellInfoListRate(CELL_INFO_REFRESH_RATES[mCellInfoRefreshRateIndex],
-                mPhone.getSubId());
+                mSubId);
 
         //set selection before registering to prevent update
         mPreferredNetworkType.setSelection(mPreferredNetworkTypeResult, true);
@@ -872,23 +880,23 @@
         }).start();
 
         // mock signal strength
-        mMockSignalStrength.setSelection(mSelectedSignalStrengthIndex[mPhone.getPhoneId()]);
+        mMockSignalStrength.setSelection(mSelectedSignalStrengthIndex[mPhoneId]);
         mMockSignalStrength.setOnItemSelectedListener(mOnMockSignalStrengthSelectedListener);
 
         // mock data network type
-        mMockDataNetworkType.setSelection(mSelectedMockDataNetworkTypeIndex[mPhone.getPhoneId()]);
+        mMockDataNetworkType.setSelection(mSelectedMockDataNetworkTypeIndex[mPhoneId]);
         mMockDataNetworkType.setOnItemSelectedListener(mOnMockDataNetworkTypeSelectedListener);
 
         // set phone index
-        mSelectPhoneIndex.setSelection(mSelectedPhoneIndex, true);
+        mSelectPhoneIndex.setSelection(mPhoneId, true);
         mSelectPhoneIndex.setOnItemSelectedListener(mSelectPhoneIndexHandler);
 
         mRadioPowerOnSwitch.setOnCheckedChangeListener(mRadioPowerOnChangeListener);
-        mSimulateOutOfServiceSwitch.setChecked(mSimulateOos[mPhone.getPhoneId()]);
+        mSimulateOutOfServiceSwitch.setChecked(mSimulateOos[mPhoneId]);
         mSimulateOutOfServiceSwitch.setOnCheckedChangeListener(mSimulateOosOnChangeListener);
-        mMockSatellite.setChecked(mCarrierSatelliteOriginalBundle[mPhone.getPhoneId()] != null);
+        mMockSatellite.setChecked(mCarrierSatelliteOriginalBundle[mPhoneId] != null);
         mMockSatellite.setOnCheckedChangeListener(mMockSatelliteListener);
-        updateSatelliteChannelDisplay(mPhone.getPhoneId());
+        updateSatelliteChannelDisplay(mPhoneId);
         mEnforceSatelliteChannel.setOnCheckedChangeListener(mForceSatelliteChannelOnChangeListener);
         mImsVolteProvisionedSwitch.setOnCheckedChangeListener(mImsVolteCheckedChangeListener);
         mImsVtProvisionedSwitch.setOnCheckedChangeListener(mImsVtCheckedChangeListener);
@@ -902,9 +910,6 @@
 
         unregisterPhoneStateListener();
         registerPhoneStateListener();
-        mPhone.registerForPhysicalChannelConfig(mHandler,
-            EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED, null);
-
         mConnectivityManager.registerNetworkCallback(
                 mDefaultNetworkRequest, mNetworkCallback, mHandler);
 
@@ -918,7 +923,7 @@
         log("onPause: unregister phone & data intents");
 
         mTelephonyManager.unregisterTelephonyCallback(mTelephonyCallback);
-        mTelephonyManager.setCellInfoListRate(sCellInfoListRateDisabled, mPhone.getSubId());
+        mTelephonyManager.setCellInfoListRate(sCellInfoListRateDisabled, mSubId);
         mConnectivityManager.unregisterNetworkCallback(mNetworkCallback);
 
     }
@@ -939,7 +944,8 @@
         mPreferredNetworkTypeResult = b.getInt("mPreferredNetworkTypeResult",
                 PREFERRED_NETWORK_LABELS.length - 1);
 
-        mSelectedPhoneIndex = b.getInt("mSelectedPhoneIndex", 0);
+        mPhoneId = b.getInt("mSelectedPhoneIndex", 0);
+        mSubId = SubscriptionManager.getSubscriptionId(mPhoneId);
 
         mCellInfoRefreshRateIndex = b.getInt("mCellInfoRefreshRateIndex", 0);
     }
@@ -952,7 +958,7 @@
         outState.putString("mHttpClientTestResult", mHttpClientTestResult);
 
         outState.putInt("mPreferredNetworkTypeResult", mPreferredNetworkTypeResult);
-        outState.putInt("mSelectedPhoneIndex", mSelectedPhoneIndex);
+        outState.putInt("mSelectedPhoneIndex", mPhoneId);
         outState.putInt("mCellInfoRefreshRateIndex", mCellInfoRefreshRateIndex);
 
     }
@@ -966,7 +972,7 @@
                 R.string.radioInfo_menu_viewFDN).setOnMenuItemClickListener(mViewFDNCallback);
         menu.add(1, MENU_ITEM_VIEW_SDN, 0,
                 R.string.radioInfo_menu_viewSDN).setOnMenuItemClickListener(mViewSDNCallback);
-        if (isImsSupportedOnDevice(mPhone.getContext())) {
+        if (isImsSupportedOnDevice()) {
             menu.add(1, MENU_ITEM_GET_IMS_STATUS,
                     0, R.string.radioInfo_menu_getIMS).setOnMenuItemClickListener(mGetImsStatus);
         }
@@ -1011,21 +1017,23 @@
 
     private void clearOverride() {
         for (int phoneId = 0; phoneId < sPhoneIndexLabels.length; phoneId++) {
-            mPhone = PhoneFactory.getPhone(phoneId);
-            if (mSimulateOos[mPhone.getPhoneId()])  {
+            if (mSystemUser) {
+                mPhone = PhoneFactory.getPhone(phoneId);
+            }
+            if (mSimulateOos[mPhoneId])  {
                 mSimulateOosOnChangeListener.onCheckedChanged(mSimulateOutOfServiceSwitch, false);
             }
-            if (mOriginalSystemChannels[mPhone.getPhoneId()] != null) {
+            if (mOriginalSystemChannels[mPhoneId] != null) {
                 mForceSatelliteChannelOnChangeListener
                         .onCheckedChanged(mEnforceSatelliteChannel, false);
             }
-            if (mCarrierSatelliteOriginalBundle[mPhone.getPhoneId()] != null) {
+            if (mCarrierSatelliteOriginalBundle[mPhoneId] != null) {
                 mMockSatelliteListener.onCheckedChanged(mMockSatellite, false);
             }
-            if (mSelectedSignalStrengthIndex[mPhone.getPhoneId()] > 0) {
+            if (mSelectedSignalStrengthIndex[mPhoneId] > 0) {
                 mOnMockSignalStrengthSelectedListener.onItemSelected(null, null, 0/*pos*/, 0);
             }
-            if (mSelectedMockDataNetworkTypeIndex[mPhone.getPhoneId()] > 0) {
+            if (mSelectedMockDataNetworkTypeIndex[mPhoneId] > 0) {
                 mOnMockDataNetworkTypeSelectedListener.onItemSelected(null, null, 0/*pos*/, 0);
             }
         }
@@ -1044,7 +1052,6 @@
 
     private void unregisterPhoneStateListener() {
         mTelephonyManager.unregisterTelephonyCallback(mTelephonyCallback);
-        mPhone.unregisterForPhysicalChannelConfig(mHandler);
 
         // clear all fields so they are blank until the next listener event occurs
         mOperatorName.setText("");
@@ -1067,6 +1074,8 @@
         mGsmState.setText("");
         mRoamingState.setText("");
         mPhyChanConfig.setText("");
+        mDownlinkKbps.setText("");
+        mUplinkKbps.setText("");
     }
 
     // register mTelephonyCallback for relevant fields using the current TelephonyManager
@@ -1297,7 +1306,7 @@
     }
 
     private void updateSubscriptionIds() {
-        mSubscriptionId.setText(Integer.toString(mPhone.getSubId()));
+        mSubscriptionId.setText(String.format(Locale.ROOT, "%d", mSubId));
         mDds.setText(Integer.toString(SubscriptionManager.getDefaultDataSubscriptionId()));
     }
 
@@ -1311,6 +1320,12 @@
 
 
     private void updateServiceState(ServiceState serviceState) {
+        if (!SubscriptionManager.isValidSubscriptionId(mSubId)) {
+            // When SIM is absent, we can't listen service state change from absent slot. Need
+            // explicitly get service state from the specific slot.
+            serviceState = mTelephonyManager.getServiceStateForSlot(mPhoneId);
+        }
+        log("Update service state " + serviceState);
         int state = serviceState.getState();
         Resources r = getResources();
         String display = r.getString(R.string.radioInfo_unknown);
@@ -1365,32 +1380,40 @@
         Resources r = getResources();
         String display = r.getString(R.string.radioInfo_unknown);
 
-        switch (state) {
-            case TelephonyManager.DATA_CONNECTED:
-                display = r.getString(R.string.radioInfo_data_connected);
-                break;
-            case TelephonyManager.DATA_CONNECTING:
-                display = r.getString(R.string.radioInfo_data_connecting);
-                break;
-            case TelephonyManager.DATA_DISCONNECTED:
-                display = r.getString(R.string.radioInfo_data_disconnected);
-                break;
-            case TelephonyManager.DATA_SUSPENDED:
-                display = r.getString(R.string.radioInfo_data_suspended);
-                break;
+        if (SubscriptionManager.isValidSubscriptionId(mSubId)) {
+            switch (state) {
+                case TelephonyManager.DATA_CONNECTED:
+                    display = r.getString(R.string.radioInfo_data_connected);
+                    break;
+                case TelephonyManager.DATA_CONNECTING:
+                    display = r.getString(R.string.radioInfo_data_connecting);
+                    break;
+                case TelephonyManager.DATA_DISCONNECTED:
+                    display = r.getString(R.string.radioInfo_data_disconnected);
+                    break;
+                case TelephonyManager.DATA_SUSPENDED:
+                    display = r.getString(R.string.radioInfo_data_suspended);
+                    break;
+            }
+        } else {
+            display = r.getString(R.string.radioInfo_data_disconnected);
         }
 
         mGprsState.setText(display);
     }
 
     private void updateNetworkType() {
-        if (mPhone != null) {
+        if (SubscriptionManager.isValidPhoneId(mPhoneId)) {
             mDataNetwork.setText(ServiceState.rilRadioTechnologyToString(
-                    mPhone.getServiceState().getRilDataRadioTechnology()));
+                    mTelephonyManager.getServiceStateForSlot(mPhoneId)
+                            .getRilDataRadioTechnology()));
             mVoiceNetwork.setText(ServiceState.rilRadioTechnologyToString(
-                    mPhone.getServiceState().getRilVoiceRadioTechnology()));
-            int overrideNetwork = mPhone.getDisplayInfoController().getTelephonyDisplayInfo()
-                    .getOverrideNetworkType();
+                    mTelephonyManager.getServiceStateForSlot(mPhoneId)
+                            .getRilVoiceRadioTechnology()));
+            int overrideNetwork = (mDisplayInfo != null
+                    && SubscriptionManager.isValidSubscriptionId(mSubId))
+                    ? mDisplayInfo.getOverrideNetworkType()
+                    : TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE;
             mOverrideNetwork.setText(
                     TelephonyDisplayInfo.overrideNetworkTypeToString(overrideNetwork));
         }
@@ -1410,9 +1433,7 @@
 
     private void updateRawRegistrationState(ServiceState serviceState) {
         ServiceState ss = serviceState;
-        if (ss == null && mPhone != null) {
-            ss = mPhone.getServiceState();
-        }
+        ss = mTelephonyManager.getServiceStateForSlot(mPhoneId);
 
         mVoiceRawReg.setText(getRawRegistrationStateText(ss, NetworkRegistrationInfo.DOMAIN_CS,
                     AccessNetworkConstants.TRANSPORT_TYPE_WWAN));
@@ -1427,7 +1448,7 @@
                 & TelephonyManager.NETWORK_TYPE_BITMASK_NR) == 0) {
             return;
         }
-        ServiceState ss = (mPhone == null) ? null : mPhone.getServiceState();
+        ServiceState ss = mTelephonyManager.getServiceStateForSlot(mPhoneId);
         if (ss != null) {
             NetworkRegistrationInfo nri = ss.getNetworkRegistrationInfo(
                     NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
@@ -1467,21 +1488,18 @@
         String s;
         Resources r = getResources();
 
-        s = mPhone.getDeviceId();
-        if (s == null) {
-            s = r.getString(R.string.radioInfo_unknown);
-        }  else if (mPhone.getImeiType() == ImeiInfo.ImeiType.PRIMARY) {
-            s = s + " (" + r.getString(R.string.radioInfo_imei_primary) + ")";
-        }
+        s = mTelephonyManager.getImei(mPhoneId);
         mDeviceId.setText(s);
 
-        s = mPhone.getSubscriberId();
-        if (s == null) s = r.getString(R.string.radioInfo_unknown);
+        s = mTelephonyManager.getSubscriberId();
+        if (s == null || !SubscriptionManager.isValidSubscriptionId(mSubId)) {
+            s = r.getString(R.string.radioInfo_unknown);
+        }
 
         mSubscriberId.setText(s);
 
         SubscriptionManager subMgr = getSystemService(SubscriptionManager.class);
-        int subId = mPhone.getSubId();
+        int subId = mSubId;
         s = subMgr.getPhoneNumber(subId)
                 + " { CARRIER:"
                 + subMgr.getPhoneNumber(subId, SubscriptionManager.PHONE_NUMBER_SOURCE_CARRIER)
@@ -1592,9 +1610,8 @@
     }
 
     private void refreshSmsc() {
-        mQueuedWork.execute(new Runnable() {
-            public void run() {
-                //FIXME: Replace with a TelephonyManager call
+        mQueuedWork.execute(() -> {
+            if (mSystemUser) {
                 mPhone.getSmscAddress(mHandler.obtainMessage(EVENT_QUERY_SMSC_DONE));
             }
         });
@@ -1705,38 +1722,61 @@
 
     private MenuItem.OnMenuItemClickListener mGetImsStatus =
             new MenuItem.OnMenuItemClickListener() {
-        public boolean onMenuItemClick(MenuItem item) {
-            boolean isImsRegistered = mPhone.isImsRegistered();
-            boolean availableVolte = mPhone.isVoiceOverCellularImsEnabled();
-            boolean availableWfc = mPhone.isWifiCallingEnabled();
-            boolean availableVt = mPhone.isVideoEnabled();
-            boolean availableUt = mPhone.isUtEnabled();
+                public boolean onMenuItemClick(MenuItem item) {
+                    boolean isSimValid = SubscriptionManager.isValidSubscriptionId(mSubId);
+                    boolean isImsRegistered = isSimValid && mTelephonyManager.isImsRegistered();
+                    boolean availableVolte = isSimValid && mTelephonyManager.isVolteAvailable();
+                    boolean availableWfc = isSimValid && mTelephonyManager.isWifiCallingAvailable();
+                    boolean availableVt =
+                            isSimValid && mTelephonyManager.isVideoTelephonyAvailable();
+                    AtomicBoolean availableUt = new AtomicBoolean(false);
 
-            final String imsRegString = isImsRegistered
-                    ? getString(R.string.radio_info_ims_reg_status_registered)
-                    : getString(R.string.radio_info_ims_reg_status_not_registered);
+                    if (isSimValid) {
+                        ImsMmTelManager imsMmTelManager = mImsManager.getImsMmTelManager(mSubId);
+                        CountDownLatch latch = new CountDownLatch(1);
+                        try {
+                            HandlerThread handlerThread = new HandlerThread("RadioInfo");
+                            handlerThread.start();
+                            imsMmTelManager.isSupported(
+                                    MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_UT,
+                                    AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
+                                    handlerThread.getThreadExecutor(), (result) -> {
+                                        latch.countDown();
+                                        availableUt.set(result);
+                                    });
+                            latch.await(2, TimeUnit.SECONDS);
+                            handlerThread.quit();
+                        } catch (Exception e) {
+                            loge("Failed to get UT state.");
+                        }
+                    }
 
-            final String available = getString(R.string.radio_info_ims_feature_status_available);
-            final String unavailable = getString(
-                    R.string.radio_info_ims_feature_status_unavailable);
+                    final String imsRegString = isImsRegistered
+                            ? getString(R.string.radio_info_ims_reg_status_registered)
+                            : getString(R.string.radio_info_ims_reg_status_not_registered);
 
-            String imsStatus = getString(R.string.radio_info_ims_reg_status,
-                    imsRegString,
-                    availableVolte ? available : unavailable,
-                    availableWfc ? available : unavailable,
-                    availableVt ? available : unavailable,
-                    availableUt ? available : unavailable);
+                    final String available = getString(
+                            R.string.radio_info_ims_feature_status_available);
+                    final String unavailable = getString(
+                            R.string.radio_info_ims_feature_status_unavailable);
 
-            AlertDialog imsDialog = new AlertDialog.Builder(RadioInfo.this)
-                    .setMessage(imsStatus)
-                    .setTitle(getString(R.string.radio_info_ims_reg_status_title))
-                    .create();
+                    String imsStatus = getString(R.string.radio_info_ims_reg_status,
+                            imsRegString,
+                            availableVolte ? available : unavailable,
+                            availableWfc ? available : unavailable,
+                            availableVt ? available : unavailable,
+                            availableUt.get() ? available : unavailable);
 
-            imsDialog.show();
+                    AlertDialog imsDialog = new AlertDialog.Builder(RadioInfo.this)
+                            .setMessage(imsStatus)
+                            .setTitle(getString(R.string.radio_info_ims_reg_status_title))
+                            .create();
 
-            return true;
-        }
-    };
+                    imsDialog.show();
+
+                    return true;
+                }
+            };
 
     private MenuItem.OnMenuItemClickListener mToggleData =
             new MenuItem.OnMenuItemClickListener() {
@@ -1896,31 +1936,31 @@
         if (isChecked) {
             log("Send OOS override broadcast intent.");
             intent.putExtra("data_reg_state", 1);
-            mSimulateOos[mPhone.getPhoneId()] = true;
+            mSimulateOos[mPhoneId] = true;
         } else {
             log("Remove OOS override.");
             intent.putExtra("action", "reset");
-            mSimulateOos[mPhone.getPhoneId()] = false;
+            mSimulateOos[mPhoneId] = false;
         }
+        mPhone.getTelephonyTester().setServiceStateTestIntent(intent);
     };
 
     private static final int SATELLITE_CHANNEL = 8665;
     private final OnCheckedChangeListener mForceSatelliteChannelOnChangeListener =
             (buttonView, isChecked) -> {
-                if (mPhone == null || mPhone.getSubId() < 1) {
-                    loge("Force satellite channel mPhone.getSubId() < 1");
+                if (SubscriptionManager.isValidSubscriptionId(mSubId)) {
+                    loge("Force satellite channel invalid subId " + mSubId);
                     return;
                 }
-                CarrierConfigManager cm = mPhone.getContext()
-                        .getSystemService(CarrierConfigManager.class);
+                CarrierConfigManager cm = getSystemService(CarrierConfigManager.class);
                 if (cm == null) {
                     loge("Force satellite channel cm == null");
                     return;
                 }
-                TelephonyManager tm = mTelephonyManager.createForSubscriptionId(mPhone.getSubId());
+                TelephonyManager tm = mTelephonyManager.createForSubscriptionId(mSubId);
                 // To be used in thread in case mPhone changes.
-                int subId = mPhone.getSubId();
-                int phoneId = mPhone.getPhoneId();
+                int subId = mSubId;
+                int phoneId = mPhoneId;
                 if (isChecked) {
                     (new Thread(() -> {
                         // Override carrier config
@@ -2026,24 +2066,24 @@
 
     private final OnCheckedChangeListener mMockSatelliteListener =
             (buttonView, isChecked) -> {
-                if (mPhone != null) {
-                    CarrierConfigManager cm = mPhone.getContext()
-                            .getSystemService(CarrierConfigManager.class);
+                if (SubscriptionManager.isValidPhoneId(mPhoneId)) {
+                    CarrierConfigManager cm = getSystemService(CarrierConfigManager.class);
                     if (cm == null) return;
                     if (isChecked) {
-                        String operatorNumeric = mPhone.getOperatorNumeric();
+                        String operatorNumeric = mTelephonyManager
+                                .getNetworkOperatorForPhone(mPhoneId);
                         TelephonyManager tm;
-                        if (TextUtils.isEmpty(operatorNumeric) && (tm = mPhone.getContext()
-                                .getSystemService(TelephonyManager.class)) != null) {
-                            operatorNumeric = tm.getSimOperatorNumericForPhone(mPhone.getPhoneId());
+                        if (TextUtils.isEmpty(operatorNumeric)
+                                && (tm = getSystemService(TelephonyManager.class)) != null) {
+                            operatorNumeric = tm.getSimOperatorNumericForPhone(mPhoneId);
                         }
                         if (TextUtils.isEmpty(operatorNumeric)) {
                             loge("mMockSatelliteListener: Can't mock because no operator for phone "
-                                    + mPhone.getPhoneId());
+                                    + mPhoneId);
                             mMockSatellite.setChecked(false);
                             return;
                         }
-                        PersistableBundle originalBundle = cm.getConfigForSubId(mPhone.getSubId(),
+                        PersistableBundle originalBundle = cm.getConfigForSubId(mSubId,
                                 CarrierConfigManager.KEY_SATELLITE_ATTACH_SUPPORTED_BOOL,
                                 CarrierConfigManager.KEY_SATELLITE_ENTITLEMENT_SUPPORTED_BOOL,
                                 CarrierConfigManager
@@ -2055,28 +2095,30 @@
                         overrideBundle.putBoolean(CarrierConfigManager
                                 .KEY_SATELLITE_ENTITLEMENT_SUPPORTED_BOOL, false);
                         PersistableBundle capableProviderBundle = new PersistableBundle();
-                        capableProviderBundle.putIntArray(mPhone.getOperatorNumeric(), new int[]{
-                                // Currently satellite only supports below
-                                NetworkRegistrationInfo.SERVICE_TYPE_SMS,
-                                NetworkRegistrationInfo.SERVICE_TYPE_EMERGENCY
+                        capableProviderBundle.putIntArray(mTelephonyManager
+                                        .getNetworkOperatorForPhone(mPhoneId),
+                                new int[]{
+                                        // Currently satellite only supports below
+                                        NetworkRegistrationInfo.SERVICE_TYPE_SMS,
+                                        NetworkRegistrationInfo.SERVICE_TYPE_EMERGENCY
                         });
                         overrideBundle.putPersistableBundle(CarrierConfigManager
                                 .KEY_CARRIER_SUPPORTED_SATELLITE_SERVICES_PER_PROVIDER_BUNDLE,
                                 capableProviderBundle);
                         log("mMockSatelliteListener: new " + overrideBundle);
                         log("mMockSatelliteListener: old " + originalBundle);
-                        cm.overrideConfig(mPhone.getSubId(), overrideBundle, false);
-                        mCarrierSatelliteOriginalBundle[mPhone.getPhoneId()] = originalBundle;
+                        cm.overrideConfig(mSubId, overrideBundle, false);
+                        mCarrierSatelliteOriginalBundle[mPhoneId] = originalBundle;
                     } else {
                         try {
-                            cm.overrideConfig(mPhone.getSubId(),
-                                    mCarrierSatelliteOriginalBundle[mPhone.getPhoneId()], false);
-                            mCarrierSatelliteOriginalBundle[mPhone.getPhoneId()] = null;
+                            cm.overrideConfig(mSubId,
+                                    mCarrierSatelliteOriginalBundle[mPhoneId], false);
+                            mCarrierSatelliteOriginalBundle[mPhoneId] = null;
                             log("mMockSatelliteListener: Successfully cleared mock for phone "
-                                    + mPhone.getPhoneId());
+                                    + mPhoneId);
                         } catch (Exception e) {
                             loge("mMockSatelliteListener: Can't clear mock because invalid sub Id "
-                                    + mPhone.getSubId()
+                                    + mSubId
                                     + ", insert SIM and use adb shell cmd phone cc clear-values");
                             // Keep show toggle ON if the view is not destroyed. If destroyed, must
                             // use cmd to reset, because upon creation the view doesn't remember the
@@ -2091,13 +2133,13 @@
      * Enable modem satellite for non-emergency mode.
      */
     private void enableSatelliteNonEmergencyMode() {
-        SatelliteManager sm = mPhone.getContext().getSystemService(SatelliteManager.class);
-        CarrierConfigManager cm = mPhone.getContext().getSystemService(CarrierConfigManager.class);
+        SatelliteManager sm = getSystemService(SatelliteManager.class);
+        CarrierConfigManager cm = getSystemService(CarrierConfigManager.class);
         if (sm == null || cm == null) {
             loge("enableSatelliteNonEmergencyMode: sm or cm is null");
             return;
         }
-        if (!cm.getConfigForSubId(mPhone.getSubId(),
+        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");
@@ -2185,10 +2227,9 @@
     }
 
     private boolean isEabEnabledByPlatform() {
-        if (mPhone != null) {
-            CarrierConfigManager configManager = (CarrierConfigManager)
-                    mPhone.getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE);
-            PersistableBundle b = configManager.getConfigForSubId(mPhone.getSubId());
+        if (SubscriptionManager.isValidPhoneId(mPhoneId)) {
+            CarrierConfigManager configManager = getSystemService(CarrierConfigManager.class);
+            PersistableBundle b = configManager.getConfigForSubId(mSubId);
             if (b != null) {
                 return b.getBoolean(
                         CarrierConfigManager.KEY_USE_RCS_PRESENCE_BOOL, false) || b.getBoolean(
@@ -2200,7 +2241,7 @@
     }
 
     private void updateImsProvisionedState() {
-        if (!isImsSupportedOnDevice(mPhone.getContext())) {
+        if (!isImsSupportedOnDevice()) {
             return;
         }
 
@@ -2274,8 +2315,8 @@
     OnClickListener mUpdateSmscButtonHandler = new OnClickListener() {
         public void onClick(View v) {
             mUpdateSmscButton.setEnabled(false);
-            mQueuedWork.execute(new Runnable() {
-                public void run() {
+            mQueuedWork.execute(() -> {
+                if (mSystemUser) {
                     mPhone.setSmscAddress(mSmsc.getText().toString(),
                             mHandler.obtainMessage(EVENT_UPDATE_SMSC_DONE));
                 }
@@ -2283,11 +2324,7 @@
         }
     };
 
-    OnClickListener mRefreshSmscButtonHandler = new OnClickListener() {
-        public void onClick(View v) {
-            refreshSmsc();
-        }
-    };
+    OnClickListener mRefreshSmscButtonHandler = v -> refreshSmsc();
 
     OnClickListener mCarrierProvisioningButtonHandler = v -> {
         String carrierProvisioningApp = getCarrierProvisioningAppString();
@@ -2335,8 +2372,10 @@
 
                 public void onItemSelected(AdapterView<?> parent, View v, int pos, long id) {
                     log("mOnSignalStrengthSelectedListener: " + pos);
-                    mSelectedSignalStrengthIndex[mPhone.getPhoneId()] = pos;
-                    mPhone.getTelephonyTester().setSignalStrength(SIGNAL_STRENGTH_LEVEL[pos]);
+                    mSelectedSignalStrengthIndex[mPhoneId] = pos;
+                    if (mSystemUser) {
+                        mPhone.getTelephonyTester().setSignalStrength(SIGNAL_STRENGTH_LEVEL[pos]);
+                    }
                 }
 
                 public void onNothingSelected(AdapterView<?> parent) {}
@@ -2348,7 +2387,7 @@
 
                 public void onItemSelected(AdapterView<?> parent, View v, int pos, long id) {
                     log("mOnMockDataNetworkTypeSelectedListener: " + pos);
-                    mSelectedMockDataNetworkTypeIndex[mPhone.getPhoneId()] = pos;
+                    mSelectedMockDataNetworkTypeIndex[mPhoneId] = pos;
                     Intent intent = new Intent("com.android.internal.telephony.TestServiceState");
                     if (pos > 0) {
                         log("mOnMockDataNetworkTypeSelectedListener: Override RAT: "
@@ -2361,7 +2400,9 @@
                         intent.putExtra("action", "reset");
                     }
 
-                    mPhone.getTelephonyTester().setServiceStateTestIntent(intent);
+                    if (mSystemUser) {
+                        mPhone.getTelephonyTester().setServiceStateTestIntent(intent);
+                    }
                 }
 
                 public void onNothingSelected(AdapterView<?> parent) {}
@@ -2370,42 +2411,41 @@
     AdapterView.OnItemSelectedListener mSelectPhoneIndexHandler =
             new AdapterView.OnItemSelectedListener() {
 
-        public void onItemSelected(AdapterView parent, View v, int pos, long id) {
-            if (pos >= 0 && pos <= sPhoneIndexLabels.length - 1) {
-                // the array position is equal to the phone index
-                int phoneIndex = pos;
-                Phone[] phones = PhoneFactory.getPhones();
-                if (phones == null || phones.length <= phoneIndex) {
-                    return;
+                public void onItemSelected(AdapterView parent, View v, int pos, long id) {
+                    if (pos >= 0 && pos <= sPhoneIndexLabels.length - 1) {
+                        if (mTelephonyManager.getActiveModemCount() <= pos) {
+                            return;
+                        }
+
+                        mPhoneId = pos;
+                        mSubId = SubscriptionManager.getSubscriptionId(mPhoneId);
+                        log("Updated phone id to " + mPhoneId + ", sub id to " + mSubId);
+                        updatePhoneIndex();
+                    }
                 }
-                // getSubId says it takes a slotIndex, but it actually takes a phone index
-                mSelectedPhoneIndex = phoneIndex;
-                updatePhoneIndex(phoneIndex, SubscriptionManager.getSubscriptionId(phoneIndex));
-            }
-        }
 
-        public void onNothingSelected(AdapterView parent) {
-        }
-    };
+                public void onNothingSelected(AdapterView parent) {
+                }
+            };
 
-    AdapterView.OnItemSelectedListener mCellInfoRefreshRateHandler  =
+    AdapterView.OnItemSelectedListener mCellInfoRefreshRateHandler =
             new AdapterView.OnItemSelectedListener() {
 
-        public void onItemSelected(AdapterView parent, View v, int pos, long id) {
-            mCellInfoRefreshRateIndex = pos;
-            mTelephonyManager.setCellInfoListRate(CELL_INFO_REFRESH_RATES[pos], mPhone.getSubId());
-            updateAllCellInfo();
-        }
+                public void onItemSelected(AdapterView parent, View v, int pos, long id) {
+                    mCellInfoRefreshRateIndex = pos;
+                    mTelephonyManager.setCellInfoListRate(CELL_INFO_REFRESH_RATES[pos], mPhoneId);
+                    updateAllCellInfo();
+                }
 
-        public void onNothingSelected(AdapterView parent) {
-        }
-    };
+                public void onNothingSelected(AdapterView parent) {
+                }
+            };
 
     private String getCarrierProvisioningAppString() {
-        if (mPhone != null) {
+        if (SubscriptionManager.isValidPhoneId(mPhoneId)) {
             CarrierConfigManager configManager =
-                    mPhone.getContext().getSystemService(CarrierConfigManager.class);
-            PersistableBundle b = configManager.getConfigForSubId(mPhone.getSubId());
+                    getSystemService(CarrierConfigManager.class);
+            PersistableBundle b = configManager.getConfigForSubId(mSubId);
             if (b != null) {
                 return b.getString(
                         CarrierConfigManager.KEY_CARRIER_PROVISIONING_APP_STRING, "");
@@ -2512,18 +2552,17 @@
         sendBroadcast(intent);
     }
 
-    private boolean isImsSupportedOnDevice(Context context) {
-        return context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY_IMS);
+    private boolean isImsSupportedOnDevice() {
+        return getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY_IMS);
     }
 
     private void updateServiceEnabledByPlatform() {
-        int subId = mPhone.getSubId();
-        if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+        if (!SubscriptionManager.isValidSubscriptionId(mSubId)) {
             log("updateServiceEnabledByPlatform subscription ID is invalid");
             return;
         }
 
-        ImsMmTelManager imsMmTelManager = mImsManager.getImsMmTelManager(subId);
+        ImsMmTelManager imsMmTelManager = mImsManager.getImsMmTelManager(mSubId);
         try {
             imsMmTelManager.isSupported(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE,
                     AccessNetworkConstants.TRANSPORT_TYPE_WWAN, getMainExecutor(), (result) -> {
diff --git a/tests/src/com/android/phone/satellite/accesscontrol/SatelliteAccessControllerTest.java b/tests/src/com/android/phone/satellite/accesscontrol/SatelliteAccessControllerTest.java
index 8a2b4d6..9e5d9e7 100644
--- a/tests/src/com/android/phone/satellite/accesscontrol/SatelliteAccessControllerTest.java
+++ b/tests/src/com/android/phone/satellite/accesscontrol/SatelliteAccessControllerTest.java
@@ -18,8 +18,13 @@
 
 import static android.location.LocationManager.MODE_CHANGED_ACTION;
 import static android.telephony.satellite.SatelliteManager.KEY_SATELLITE_COMMUNICATION_ALLOWED;
+import static android.telephony.satellite.SatelliteManager.KEY_SATELLITE_PROVISIONED;
+import static android.telephony.satellite.SatelliteManager.KEY_SATELLITE_SUPPORTED;
+import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_ERROR;
+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_MODEM_ERROR;
+import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_NOT_SUPPORTED;
 import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED;
 import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_SUCCESS;
 
@@ -106,6 +111,7 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -177,6 +183,10 @@
             mMockCachedAccessRestrictionMap;
     @Mock
     private Intent mMockLocationIntent;
+    @Mock
+    private Set<ResultReceiver> mMockSatelliteAllowResultReceivers;
+    @Mock
+    private ResultReceiver mMockSatelliteSupportedResultReceiver;
 
     private Looper mLooper;
     private TestableLooper mTestableLooper;
@@ -207,6 +217,10 @@
     private ArgumentCaptor<LocationRequest> mLocationRequestCaptor;
     @Captor
     private ArgumentCaptor<String> mLocationProviderStringCaptor;
+    @Captor
+    private ArgumentCaptor<Integer> mResultCodeIntCaptor;
+    @Captor
+    private ArgumentCaptor<Bundle> mResultDataBundleCaptor;
 
     private boolean mQueriedSatelliteAllowed = false;
     private int mQueriedSatelliteAllowedResultCode = SATELLITE_RESULT_SUCCESS;
@@ -639,7 +653,7 @@
         mTestableLooper.processAllMessages();
         assertTrue(waitForRequestIsSatelliteAllowedForCurrentLocationResult(
                 mSatelliteAllowedSemaphore, 1));
-        assertEquals(SATELLITE_RESULT_SUCCESS, mQueriedSatelliteAllowedResultCode);
+        assertEquals(SATELLITE_RESULT_NOT_SUPPORTED, mQueriedSatelliteAllowedResultCode);
         assertFalse(mQueriedSatelliteAllowed);
 
         // Failed to query whether satellite is supported or not
@@ -763,6 +777,7 @@
         mSatelliteAccessControllerUT.elapsedRealtimeNanos = TEST_LOCATION_FRESH_DURATION_NANOS + 1;
         when(mMockLocation0.getElapsedRealtimeNanos()).thenReturn(0L);
         when(mMockLocation1.getElapsedRealtimeNanos()).thenReturn(0L);
+        doReturn(false).when(mMockLocationManager).isLocationEnabled();
         mSatelliteAccessControllerUT.requestIsCommunicationAllowedForCurrentLocation(
                 mSatelliteAllowedReceiver);
         mTestableLooper.processAllMessages();
@@ -773,7 +788,7 @@
                 any(SatelliteOnDeviceAccessController.LocationToken.class));
         assertTrue(waitForRequestIsSatelliteAllowedForCurrentLocationResult(
                 mSatelliteAllowedSemaphore, 1));
-        assertEquals(SATELLITE_RESULT_SUCCESS, mQueriedSatelliteAllowedResultCode);
+        assertEquals(SATELLITE_RESULT_LOCATION_DISABLED, mQueriedSatelliteAllowedResultCode);
         assertFalse(mQueriedSatelliteAllowed);
     }
 
@@ -1067,6 +1082,83 @@
         assertFalse(mLocationRequestCaptor.getValue().isLocationSettingsIgnored());
     }
 
+    @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();
+
+        replaceInstance(SatelliteAccessController.class, "mSatelliteAllowResultReceivers",
+                mSatelliteAccessControllerUT, mMockSatelliteAllowResultReceivers);
+        doNothing().when(mMockSatelliteAllowResultReceivers).clear();
+
+        // 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);
+        mSatelliteAccessControllerUT.handleIsSatelliteSupportedResult(resultCode, bundle);
+        verify(mMockSatelliteSupportedResultReceiver)
+                .send(mResultCodeIntCaptor.capture(), any());
+        assertEquals(Integer.valueOf(SATELLITE_RESULT_ERROR), mResultCodeIntCaptor.getValue());
+
+        // case no KEY_SATELLITE_SUPPORTED in the bundle data.
+        // 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);
+        mSatelliteAccessControllerUT.handleIsSatelliteSupportedResult(resultCode, bundle);
+        verify(mMockSatelliteSupportedResultReceiver)
+                .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);
+        mSatelliteAccessControllerUT.handleIsSatelliteSupportedResult(resultCode, bundle);
+        verify(mMockSatelliteSupportedResultReceiver)
+                .send(mResultCodeIntCaptor.capture(), mResultDataBundleCaptor.capture());
+        assertEquals(Integer.valueOf(SATELLITE_RESULT_NOT_SUPPORTED),
+                mResultCodeIntCaptor.getValue());
+        assertEquals(false,
+                mResultDataBundleCaptor.getValue().getBoolean(KEY_SATELLITE_COMMUNICATION_ALLOWED));
+
+        // case KEY_SATELLITE_SUPPORTED is success and region is not allowed
+        // verify SATELLITE_RESULT_SUCCESS is captured
+        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);
+        mSatelliteAccessControllerUT.handleIsSatelliteSupportedResult(resultCode, bundle);
+        verify(mMockSatelliteSupportedResultReceiver)
+                .send(mResultCodeIntCaptor.capture(), mResultDataBundleCaptor.capture());
+        assertEquals(Integer.valueOf(SATELLITE_RESULT_SUCCESS),
+                mResultCodeIntCaptor.getValue());
+        assertEquals(false,
+                mResultDataBundleCaptor.getValue().getBoolean(KEY_SATELLITE_COMMUNICATION_ALLOWED));
+
+        // case KEY_SATELLITE_SUPPORTED is success and locationManager is disabled
+        // verify SATELLITE_RESULT_LOCATION_DISABLED is captured
+        when(mMockCountryDetector.getCurrentNetworkCountryIso())
+                .thenReturn(List.of(TEST_SATELLITE_COUNTRY_CODE_US));
+        doReturn(false).when(mMockLocationManager).isLocationEnabled();
+        doReturn(true, false).when(mockIterator).hasNext();
+        clearInvocations(mMockSatelliteSupportedResultReceiver);
+        mSatelliteAccessControllerUT.handleIsSatelliteSupportedResult(resultCode, bundle);
+        verify(mMockSatelliteSupportedResultReceiver)
+                .send(mResultCodeIntCaptor.capture(), mResultDataBundleCaptor.capture());
+        assertEquals(Integer.valueOf(SATELLITE_RESULT_LOCATION_DISABLED),
+                mResultCodeIntCaptor.getValue());
+        assertEquals(false,
+                mResultDataBundleCaptor.getValue().getBoolean(KEY_SATELLITE_COMMUNICATION_ALLOWED));
+    }
+
     private void sendSatelliteCommunicationAllowedEvent() {
         Pair<Integer, ResultReceiver> requestPair =
                 new Pair<>(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID,
@@ -1150,7 +1242,7 @@
             ResultReceiver resultReceiver = invocation.getArgument(0);
             if (error == SATELLITE_RESULT_SUCCESS) {
                 Bundle bundle = new Bundle();
-                bundle.putBoolean(SatelliteManager.KEY_SATELLITE_PROVISIONED,
+                bundle.putBoolean(KEY_SATELLITE_PROVISIONED,
                         isSatelliteProvisioned);
                 resultReceiver.send(error, bundle);
             } else {