Merge "Using current location to check satellite allowed state before enabling satellite" into main
diff --git a/res/values/config.xml b/res/values/config.xml
index 61e01b0..847c4c5 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -157,6 +157,8 @@
     <string name="mobile_network_settings_package" translatable="false">com.android.settings</string>
     <!-- Class name for the mobile network settings activity [DO NOT TRANSLATE] -->
     <string name="mobile_network_settings_class" translatable="false">com.android.settings.Settings$MobileNetworkActivity</string>
+    <!-- Class name for the SIMs settings activity [DO NOT TRANSLATE] -->
+    <string name="sims_settings_class" translatable="false">com.android.settings.Settings$MobileNetworkListActivity</string>
 
     <!-- CDMA activation goes through HFA -->
     <!-- DEPRECATED: Use CarrierConfigManager#KEY_USE_HFA_FOR_PROVISIONING_BOOL -->
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index e77d652..9f9c615 100644
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -7427,8 +7427,11 @@
     public boolean isTetheringApnRequiredForSubscriber(int subId) {
         enforceModifyPermission();
 
-        enforceTelephonyFeatureWithException(getCurrentPackageName(),
-                PackageManager.FEATURE_TELEPHONY_DATA, "isTetheringApnRequiredForSubscriber");
+        if (!mApp.getResources().getBoolean(
+                    com.android.internal.R.bool.config_force_phone_globals_creation)) {
+            enforceTelephonyFeatureWithException(getCurrentPackageName(),
+                    PackageManager.FEATURE_TELEPHONY_DATA, "isTetheringApnRequiredForSubscriber");
+        }
 
         final long identity = Binder.clearCallingIdentity();
         final Phone phone = getPhone(subId);
@@ -8721,8 +8724,11 @@
     public void requestModemActivityInfo(ResultReceiver result) {
         enforceModifyPermission();
 
-        enforceTelephonyFeatureWithException(getCurrentPackageName(),
-                PackageManager.FEATURE_TELEPHONY, "requestModemActivityInfo");
+        if (!mApp.getResources().getBoolean(
+                    com.android.internal.R.bool.config_force_phone_globals_creation)) {
+            enforceTelephonyFeatureWithException(getCurrentPackageName(),
+                    PackageManager.FEATURE_TELEPHONY, "requestModemActivityInfo");
+        }
 
         WorkSource workSource = getWorkSource(Binder.getCallingUid());
 
diff --git a/src/com/android/phone/settings/RadioInfo.java b/src/com/android/phone/settings/RadioInfo.java
index dcd6971..f00ef51 100644
--- a/src/com/android/phone/settings/RadioInfo.java
+++ b/src/com/android/phone/settings/RadioInfo.java
@@ -1948,7 +1948,7 @@
     private static final int SATELLITE_CHANNEL = 8665;
     private final OnCheckedChangeListener mForceSatelliteChannelOnChangeListener =
             (buttonView, isChecked) -> {
-                if (SubscriptionManager.isValidSubscriptionId(mSubId)) {
+                if (!SubscriptionManager.isValidSubscriptionId(mSubId)) {
                     loge("Force satellite channel invalid subId " + mSubId);
                     return;
                 }
diff --git a/src/com/android/phone/settings/SuppServicesUiUtil.java b/src/com/android/phone/settings/SuppServicesUiUtil.java
index 4f1a79f..785d66a 100644
--- a/src/com/android/phone/settings/SuppServicesUiUtil.java
+++ b/src/com/android/phone/settings/SuppServicesUiUtil.java
@@ -70,7 +70,7 @@
                         Intent intent = new Intent(Intent.ACTION_MAIN);
                         ComponentName mobileNetworkSettingsComponent = new ComponentName(
                                 context.getString(R.string.mobile_network_settings_package),
-                                context.getString(R.string.mobile_network_settings_class));
+                                context.getString(R.string.sims_settings_class));
                         intent.setComponent(mobileNetworkSettingsComponent);
                         context.startActivity(intent);
                     }
diff --git a/src/com/android/services/telephony/TelephonyConnectionService.java b/src/com/android/services/telephony/TelephonyConnectionService.java
index 3a52406..7467e74 100644
--- a/src/com/android/services/telephony/TelephonyConnectionService.java
+++ b/src/com/android/services/telephony/TelephonyConnectionService.java
@@ -18,6 +18,8 @@
 
 import static android.telephony.CarrierConfigManager.KEY_USE_ONLY_DIALED_SIM_ECC_LIST_BOOL;
 import static android.telephony.DomainSelectionService.SELECTOR_TYPE_CALLING;
+import static android.telephony.ServiceState.STATE_EMERGENCY_ONLY;
+import static android.telephony.ServiceState.STATE_IN_SERVICE;
 import static android.telephony.TelephonyManager.HAL_SERVICE_VOICE;
 
 import static com.android.internal.telephony.PhoneConstants.PHONE_TYPE_GSM;
@@ -1156,7 +1158,7 @@
             // so they will only need the special emergency call setup when the phone is out of
             // service.
             if (phone == null || phone.getServiceState().getState()
-                    != ServiceState.STATE_IN_SERVICE) {
+                    != STATE_IN_SERVICE) {
                 String convertedNumber = mPhoneNumberUtilsProxy.convertToEmergencyNumber(this,
                         number);
                 if (!TextUtils.equals(convertedNumber, number)) {
@@ -1297,7 +1299,7 @@
                         return phone.getState() == PhoneConstants.State.OFFHOOK
                                 // Do not wait for voice in service on opportunistic SIMs.
                                 || subInfo != null && subInfo.isOpportunistic()
-                                || (serviceState == ServiceState.STATE_IN_SERVICE
+                                || (serviceState == STATE_IN_SERVICE
                                 && !needToTurnOffSatellite);
                     }
                 }
@@ -1638,8 +1640,8 @@
 
         if (!isEmergencyNumber) {
             switch (state) {
-                case ServiceState.STATE_IN_SERVICE:
-                case ServiceState.STATE_EMERGENCY_ONLY:
+                case STATE_IN_SERVICE:
+                case STATE_EMERGENCY_ONLY:
                     break;
                 case ServiceState.STATE_OUT_OF_SERVICE:
                     if (phone.isUtEnabled() && number.endsWith("#")) {
@@ -2137,7 +2139,7 @@
 
         return imsPhone != null
                 && (imsPhone.isVoiceOverCellularImsEnabled() || imsPhone.isWifiCallingEnabled())
-                && (imsPhone.getServiceState().getState() == ServiceState.STATE_IN_SERVICE);
+                && (imsPhone.getServiceState().getState() == STATE_IN_SERVICE);
     }
 
     private boolean isRadioOn() {
@@ -3069,7 +3071,7 @@
         }
 
         ServiceState ss = phone.getServiceStateTracker().getServiceState();
-        if (ss.getState() != ServiceState.STATE_IN_SERVICE) return false;
+        if (ss.getState() != STATE_IN_SERVICE) return false;
 
         NetworkRegistrationInfo regState = ss.getNetworkRegistrationInfo(
                 NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
@@ -4143,7 +4145,7 @@
     @VisibleForTesting
     public boolean isAvailableForEmergencyCalls(Phone phone,
             @EmergencyNumber.EmergencyCallRouting int routing) {
-        if (isCallDisallowedDueToSatellite(phone)) {
+        if (isCallDisallowedDueToSatellite(phone) && isTerrestrialNetworkAvailable()) {
             // Phone is connected to satellite due to which it is not preferred for emergency call.
             return false;
         }
@@ -4157,7 +4159,7 @@
         }
 
         // In service phones are always appropriate for emergency calls.
-        if (ServiceState.STATE_IN_SERVICE == phone.getServiceState().getState()) {
+        if (STATE_IN_SERVICE == phone.getServiceState().getState()) {
             return true;
         }
 
@@ -4168,6 +4170,23 @@
                 && phone.getServiceState().isEmergencyOnly());
     }
 
+    private boolean isTerrestrialNetworkAvailable() {
+        for (Phone phone : mPhoneFactoryProxy.getPhones()) {
+            ServiceState serviceState = phone.getServiceState();
+            if (serviceState != null) {
+                int state = serviceState.getState();
+                if ((state == STATE_IN_SERVICE || state == STATE_EMERGENCY_ONLY
+                        || serviceState.isEmergencyOnly())
+                        && !serviceState.isUsingNonTerrestrialNetwork()) {
+                    Log.d(this, "isTerrestrialNetworkAvailable true");
+                    return true;
+                }
+            }
+        }
+        Log.d(this, "isTerrestrialNetworkAvailable false");
+        return false;
+    }
+
     /**
      * Determines if the connection should allow mute.
      *
@@ -4362,7 +4381,7 @@
                                                 context.getString(
                                                     R.string.mobile_network_settings_package),
                                                 context.getString(
-                                                    R.string.mobile_network_settings_class));
+                                                    R.string.sims_settings_class));
                                     intent.setComponent(mobileNetworkSettingsComponent);
                                     context.startActivity(intent);
                                 }
diff --git a/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java b/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java
index 6990e29..6eb9416 100644
--- a/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java
+++ b/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java
@@ -3888,6 +3888,7 @@
         ss.setEmergencyOnly(true);
         ss.setState(ServiceState.STATE_EMERGENCY_ONLY);
         when(mockPhone.getServiceState()).thenReturn(ss);
+        when(mPhoneFactoryProxy.getPhones()).thenReturn(new Phone[] {mockPhone});
 
         assertFalse(mTestConnectionService.isAvailableForEmergencyCalls(mockPhone,
                 EmergencyNumber.EMERGENCY_CALL_ROUTING_EMERGENCY));
@@ -3911,6 +3912,79 @@
         ss.setState(ServiceState.STATE_EMERGENCY_ONLY);
         when(mockPhone.getServiceState()).thenReturn(ss);
 
+        when(mPhoneFactoryProxy.getPhones()).thenReturn(new Phone[] {mockPhone});
+
+        assertTrue(mTestConnectionService.isAvailableForEmergencyCalls(mockPhone,
+                EmergencyNumber.EMERGENCY_CALL_ROUTING_EMERGENCY));
+        assertFalse(mTestConnectionService.isAvailableForEmergencyCalls(mockPhone,
+                EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL));
+        assertTrue(mTestConnectionService.isAvailableForEmergencyCalls(mockPhone,
+                EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN));
+    }
+
+    @Test
+    public void testIsAvailableForEmergencyCallsUsingNTN_CellularAvailable() {
+        mSetFlagsRule.enableFlags(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG);
+
+        // Call is not supported while using satellite
+        when(mSatelliteController.isInSatelliteModeForCarrierRoaming(any())).thenReturn(true);
+        when(mSatelliteController.getCapabilitiesForCarrierRoamingSatelliteMode(any()))
+                .thenReturn(List.of(NetworkRegistrationInfo.SERVICE_TYPE_DATA));
+
+        Phone mockPhone = Mockito.mock(Phone.class);
+        ServiceState ss = new ServiceState();
+        ss.setEmergencyOnly(true);
+        ss.setState(ServiceState.STATE_EMERGENCY_ONLY);
+        when(mockPhone.getServiceState()).thenReturn(ss);
+
+        // Phone2 is in limited service
+        Phone mockPhone2 = Mockito.mock(Phone.class);
+        ServiceState ss2 = new ServiceState();
+        ss2.setEmergencyOnly(true);
+        ss2.setState(ServiceState.STATE_EMERGENCY_ONLY);
+        when(mockPhone2.getServiceState()).thenReturn(ss2);
+
+        Phone[] phones = {mockPhone, mockPhone2};
+        when(mPhoneFactoryProxy.getPhones()).thenReturn(phones);
+
+        assertFalse(mTestConnectionService.isAvailableForEmergencyCalls(mockPhone,
+                EmergencyNumber.EMERGENCY_CALL_ROUTING_EMERGENCY));
+        assertFalse(mTestConnectionService.isAvailableForEmergencyCalls(mockPhone,
+                EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL));
+        assertFalse(mTestConnectionService.isAvailableForEmergencyCalls(mockPhone,
+                EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN));
+    }
+
+    @Test
+    public void testIsAvailableForEmergencyCallsUsingNTN_CellularNotAvailable() {
+        mSetFlagsRule.enableFlags(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG);
+
+        // Call is not supported while using satellite
+        when(mSatelliteController.isInSatelliteModeForCarrierRoaming(any())).thenReturn(true);
+        when(mSatelliteController.getCapabilitiesForCarrierRoamingSatelliteMode(any()))
+                .thenReturn(List.of(NetworkRegistrationInfo.SERVICE_TYPE_DATA));
+
+        NetworkRegistrationInfo nri = new NetworkRegistrationInfo.Builder()
+                .setIsNonTerrestrialNetwork(true)
+                .setAvailableServices(List.of(NetworkRegistrationInfo.SERVICE_TYPE_DATA))
+                .build();
+        Phone mockPhone = Mockito.mock(Phone.class);
+        ServiceState ss = new ServiceState();
+        ss.addNetworkRegistrationInfo(nri);
+        ss.setEmergencyOnly(true);
+        ss.setState(ServiceState.STATE_EMERGENCY_ONLY);
+        when(mockPhone.getServiceState()).thenReturn(ss);
+
+        // Phone2 is out of service
+        Phone mockPhone2 = Mockito.mock(Phone.class);
+        ServiceState ss2 = new ServiceState();
+        ss2.setEmergencyOnly(false);
+        ss2.setState(ServiceState.STATE_OUT_OF_SERVICE);
+        when(mockPhone2.getServiceState()).thenReturn(ss2);
+
+        Phone[] phones = {mockPhone, mockPhone2};
+        when(mPhoneFactoryProxy.getPhones()).thenReturn(phones);
+
         assertTrue(mTestConnectionService.isAvailableForEmergencyCalls(mockPhone,
                 EmergencyNumber.EMERGENCY_CALL_ROUTING_EMERGENCY));
         assertFalse(mTestConnectionService.isAvailableForEmergencyCalls(mockPhone,