e911 call should go on same SIM as ongoing VoLTE call.
- In DSDA devices, e911 call should go on the same PhoneAccountHandle
of ongoing call, as long as ongoing call is on Wifi or cellular.
- If the ongoing call is over cross-SIM calling, e911 call will be made
in the other Phone object at TelephonyConnectionService#getPhoneForAccount().
Test: Manual testing:
confirm e911 call goes on same sub as existing VoLTE/WiFi call .
confirm e911 call goes on different sub as existing cross-SIM call.
New UTs in CallsManagerTest
Bug: 274537723
Change-Id: I40cc213d050c74ad88054b37a8a844ab3bbf948e
diff --git a/src/com/android/server/telecom/CallsManager.java b/src/com/android/server/telecom/CallsManager.java
index f36ba1b..250db1d 100644
--- a/src/com/android/server/telecom/CallsManager.java
+++ b/src/com/android/server/telecom/CallsManager.java
@@ -3178,7 +3178,10 @@
isEmergency);
// Only one SIM PhoneAccount can be active at one time for DSDS. Only that SIM PhoneAccount
// should be available if a call is already active on the SIM account.
- if (!isDsdaCallingPossible()) {
+ // Similarly, the emergency call should be attempted over the same PhoneAccount as the
+ // ongoing call. However, if the ongoing call is over cross-SIM registration, then the
+ // emergency call will be attempted over a different Phone object at a later stage.
+ if (isEmergency || !isDsdaCallingPossible()) {
List<PhoneAccountHandle> simAccounts =
mPhoneAccountRegistrar.getSimPhoneAccountsOfCurrentUser();
PhoneAccountHandle ongoingCallAccount = null;
diff --git a/tests/src/com/android/server/telecom/tests/CallsManagerTest.java b/tests/src/com/android/server/telecom/tests/CallsManagerTest.java
index c467671..6b9982c 100644
--- a/tests/src/com/android/server/telecom/tests/CallsManagerTest.java
+++ b/tests/src/com/android/server/telecom/tests/CallsManagerTest.java
@@ -70,6 +70,7 @@
import android.telecom.CallException;
import android.telecom.VideoProfile;
import android.telephony.CarrierConfigManager;
+import android.telephony.PhoneCapability;
import android.telephony.TelephonyManager;
import android.test.suitebuilder.annotation.MediumTest;
import android.test.suitebuilder.annotation.SmallTest;
@@ -240,6 +241,7 @@
@Mock private AnomalyReporterAdapter mAnomalyReporterAdapter;
@Mock private Ringer.AccessibilityManagerAdapter mAccessibilityManagerAdapter;
@Mock private BlockedNumbersAdapter mBlockedNumbersAdapter;
+ @Mock private PhoneCapability mPhoneCapability;
private CallsManager mCallsManager;
@@ -331,6 +333,26 @@
assertEquals(0, mCallsManager.constructPossiblePhoneAccounts(null, null, false, false).size());
}
+ private Call constructOngoingCall(String callId, PhoneAccountHandle phoneAccountHandle) {
+ Call ongoingCall = new Call(
+ callId,
+ mContext,
+ mCallsManager,
+ mLock,
+ null /* ConnectionServiceRepository */,
+ mPhoneNumberUtilsAdapter,
+ TEST_ADDRESS,
+ null /* GatewayInfo */,
+ null /* connectionManagerPhoneAccountHandle */,
+ phoneAccountHandle,
+ Call.CALL_DIRECTION_INCOMING,
+ false /* shouldAttachToExistingConnection*/,
+ false /* isConference */,
+ mClockProxy,
+ mToastFactory);
+ ongoingCall.setState(CallState.ACTIVE, "just cuz");
+ return ongoingCall;
+ }
/**
* Verify behavior for multisim devices where we want to ensure that the active sim is used for
* placing a new call.
@@ -341,23 +363,7 @@
public void testConstructPossiblePhoneAccountsMultiSimActive() throws Exception {
setupMsimAccounts();
- Call ongoingCall = new Call(
- "1", /* callId */
- mContext,
- mCallsManager,
- mLock,
- null /* ConnectionServiceRepository */,
- mPhoneNumberUtilsAdapter,
- TEST_ADDRESS,
- null /* GatewayInfo */,
- null /* connectionManagerPhoneAccountHandle */,
- SIM_2_HANDLE,
- Call.CALL_DIRECTION_INCOMING,
- false /* shouldAttachToExistingConnection*/,
- false /* isConference */,
- mClockProxy,
- mToastFactory);
- ongoingCall.setState(CallState.ACTIVE, "just cuz");
+ Call ongoingCall = constructOngoingCall("1", SIM_2_HANDLE);
mCallsManager.addCall(ongoingCall);
List<PhoneAccountHandle> phoneAccountHandles = mCallsManager.constructPossiblePhoneAccounts(
@@ -380,6 +386,47 @@
assertEquals(2, phoneAccountHandles.size());
}
+ /**
+ * For DSDA-enabled multisim devices with an ongoing call, verify that both SIMs'
+ * PhoneAccountHandles are constructed while placing a new call.
+ * @throws Exception
+ */
+ @MediumTest
+ @Test
+ public void testConstructPossiblePhoneAccountsMultiSimActive_dsdaCallingPossible() throws
+ Exception {
+ setupMsimAccounts();
+ setMaxActiveVoiceSubscriptions(2);
+
+ Call ongoingCall = constructOngoingCall("1", SIM_2_HANDLE);
+ mCallsManager.addCall(ongoingCall);
+
+ List<PhoneAccountHandle> phoneAccountHandles = mCallsManager.constructPossiblePhoneAccounts(
+ TEST_ADDRESS, null, false, false);
+ assertEquals(2, phoneAccountHandles.size());
+ }
+
+ /**
+ * For DSDA-enabled multisim devices with an ongoing call, verify that only the active SIMs'
+ * PhoneAccountHandle is constructed while placing an emergency call.
+ * @throws Exception
+ */
+ @MediumTest
+ @Test
+ public void testConstructPossiblePhoneAccountsMultiSimActive_dsdaCallingPossible_emergencyCall()
+ throws Exception {
+ setupMsimAccounts();
+ setMaxActiveVoiceSubscriptions(2);
+
+ Call ongoingCall = constructOngoingCall("1", SIM_2_HANDLE);
+ mCallsManager.addCall(ongoingCall);
+
+ List<PhoneAccountHandle> phoneAccountHandles = mCallsManager.constructPossiblePhoneAccounts(
+ TEST_ADDRESS, null, false, true /* isEmergency */);
+ assertEquals(1, phoneAccountHandles.size());
+ assertEquals(SIM_2_HANDLE, phoneAccountHandles.get(0));
+ }
+
private void setupCallerInfoLookupHelper() {
doAnswer(invocation -> {
Uri handle = invocation.getArgument(0);
@@ -2862,4 +2909,10 @@
when(mPhoneAccountRegistrar.getSimPhoneAccountsOfCurrentUser()).thenReturn(
new ArrayList<>(Arrays.asList(SIM_1_HANDLE, SIM_2_HANDLE)));
}
+
+ private void setMaxActiveVoiceSubscriptions(int num) {
+ TelephonyManager mockTelephonyManager = mComponentContextFixture.getTelephonyManager();
+ when(mockTelephonyManager.getPhoneCapability()).thenReturn(mPhoneCapability);
+ when(mPhoneCapability.getMaxActiveVoiceSubscriptions()).thenReturn(num);
+ }
}