Merge "Fix crashes with partial telephony stack after boot" into main
diff --git a/src/com/android/phone/satellite/accesscontrol/SatelliteAccessController.java b/src/com/android/phone/satellite/accesscontrol/SatelliteAccessController.java
index ce77a92..de3811a 100644
--- a/src/com/android/phone/satellite/accesscontrol/SatelliteAccessController.java
+++ b/src/com/android/phone/satellite/accesscontrol/SatelliteAccessController.java
@@ -25,6 +25,10 @@
import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED;
import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_SUCCESS;
+import static com.android.internal.telephony.satellite.SatelliteConstants.TRIGGERING_EVENT_EXTERNAL_REQUEST;
+import static com.android.internal.telephony.satellite.SatelliteConstants.TRIGGERING_EVENT_LOCATION_SETTINGS_ENABLED;
+import static com.android.internal.telephony.satellite.SatelliteConstants.TRIGGERING_EVENT_MCC_CHANGED;
+import static com.android.internal.telephony.satellite.SatelliteConstants.TRIGGERING_EVENT_UNKNOWN;
import static com.android.internal.telephony.satellite.SatelliteController.SATELLITE_SHARED_PREF;
import android.annotation.ArrayRes;
@@ -402,6 +406,7 @@
+ mCurrentSatelliteAllowedState);
mCurrentSatelliteAllowedState = isAllowed;
notifySatelliteCommunicationAllowedStateChanged(isAllowed);
+ mControllerMetricsStats.reportAllowedStateChanged();
}
}
}
@@ -441,7 +446,7 @@
case EVENT_LOCATION_SETTINGS_ENABLED:
// Fall through
case EVENT_COUNTRY_CODE_CHANGED:
- handleSatelliteAllowedRegionPossiblyChanged();
+ handleSatelliteAllowedRegionPossiblyChanged(msg.what);
break;
default:
plogw("SatelliteAccessControllerHandler: unexpected message code: " + msg.what);
@@ -463,6 +468,7 @@
result.send(SATELLITE_RESULT_REQUEST_NOT_SUPPORTED, null);
return;
}
+ mAccessControllerMetricsStats.setTriggeringEvent(TRIGGERING_EVENT_EXTERNAL_REQUEST);
sendRequestAsync(CMD_IS_SATELLITE_COMMUNICATION_ALLOWED,
new Pair<>(mSatelliteController.getSatellitePhone().getSubId(), result));
}
@@ -1114,7 +1120,7 @@
};
}
- private void handleSatelliteAllowedRegionPossiblyChanged() {
+ private void handleSatelliteAllowedRegionPossiblyChanged(int handleEvent) {
if (!mFeatureFlags.oemEnabledSatelliteFlag()) {
ploge("handleSatelliteAllowedRegionPossiblyChanged: "
+ "The feature flag oemEnabledSatelliteFlag() is not enabled");
@@ -1125,6 +1131,13 @@
setIsSatelliteAllowedRegionPossiblyChanged(true);
requestIsCommunicationAllowedForCurrentLocation(
mHandlerForSatelliteAllowedResult);
+ int triggeringEvent = TRIGGERING_EVENT_UNKNOWN;
+ if (handleEvent == EVENT_LOCATION_SETTINGS_ENABLED) {
+ triggeringEvent = TRIGGERING_EVENT_LOCATION_SETTINGS_ENABLED;
+ } else if (handleEvent == EVENT_COUNTRY_CODE_CHANGED) {
+ triggeringEvent = TRIGGERING_EVENT_MCC_CHANGED;
+ }
+ mAccessControllerMetricsStats.setTriggeringEvent(triggeringEvent);
}
}
@@ -1324,6 +1337,7 @@
}
mAccessControllerMetricsStats.setAccessControlType(
SatelliteConstants.ACCESS_CONTROL_TYPE_CURRENT_LOCATION);
+ mControllerMetricsStats.reportLocationQuerySuccessful(true);
checkSatelliteAccessRestrictionForLocation(location);
} else {
plogd("current location is not available");
@@ -1338,6 +1352,7 @@
sendSatelliteAllowResultToReceivers(
SATELLITE_RESULT_LOCATION_NOT_AVAILABLE, bundle, false);
}
+ mControllerMetricsStats.reportLocationQuerySuccessful(false);
}
}
}
diff --git a/src/com/android/services/telephony/TelephonyConnectionService.java b/src/com/android/services/telephony/TelephonyConnectionService.java
index 3a52406..e44dcef 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.
*
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,