1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License 15 */ 16 17 package com.android.services.telephony; 18 19 import static android.telecom.Connection.PROPERTY_WIFI; 20 import static android.telephony.DisconnectCause.EMERGENCY_PERM_FAILURE; 21 import static android.telephony.DisconnectCause.EMERGENCY_TEMP_FAILURE; 22 import static android.telephony.DisconnectCause.ERROR_UNSPECIFIED; 23 import static android.telephony.DisconnectCause.NOT_DISCONNECTED; 24 import static android.telephony.DomainSelectionService.SELECTOR_TYPE_CALLING; 25 import static android.telephony.NetworkRegistrationInfo.DOMAIN_CS; 26 import static android.telephony.NetworkRegistrationInfo.DOMAIN_PS; 27 import static android.telephony.emergency.EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_POLICE; 28 import static android.telephony.ims.ImsReasonInfo.CODE_SIP_ALTERNATE_EMERGENCY_CALL; 29 30 import static com.android.internal.telephony.RILConstants.GSM_PHONE; 31 import static com.android.services.telephony.TelephonyConnectionService.TIMEOUT_TO_DYNAMIC_ROUTING_MS; 32 33 import static junit.framework.Assert.assertEquals; 34 import static junit.framework.Assert.assertFalse; 35 import static junit.framework.Assert.assertNotNull; 36 import static junit.framework.Assert.assertNull; 37 import static junit.framework.Assert.assertTrue; 38 import static junit.framework.Assert.fail; 39 40 import static org.junit.Assert.assertThrows; 41 import static org.mockito.ArgumentMatchers.any; 42 import static org.mockito.ArgumentMatchers.anyBoolean; 43 import static org.mockito.ArgumentMatchers.anyInt; 44 import static org.mockito.ArgumentMatchers.anyString; 45 import static org.mockito.Matchers.eq; 46 import static org.mockito.Mockito.doAnswer; 47 import static org.mockito.Mockito.doNothing; 48 import static org.mockito.Mockito.doReturn; 49 import static org.mockito.Mockito.doThrow; 50 import static org.mockito.Mockito.mock; 51 import static org.mockito.Mockito.never; 52 import static org.mockito.Mockito.times; 53 import static org.mockito.Mockito.verify; 54 import static org.mockito.Mockito.verifyZeroInteractions; 55 import static org.mockito.Mockito.when; 56 57 import android.content.ComponentName; 58 import android.content.Context; 59 import android.content.res.Resources; 60 import android.net.Uri; 61 import android.os.AsyncResult; 62 import android.os.Bundle; 63 import android.os.Handler; 64 import android.platform.test.flag.junit.SetFlagsRule; 65 import android.telecom.Conference; 66 import android.telecom.Conferenceable; 67 import android.telecom.ConnectionRequest; 68 import android.telecom.DisconnectCause; 69 import android.telecom.PhoneAccount; 70 import android.telecom.PhoneAccountHandle; 71 import android.telecom.TelecomManager; 72 import android.telephony.AccessNetworkConstants; 73 import android.telephony.CarrierConfigManager; 74 import android.telephony.DataSpecificRegistrationInfo; 75 import android.telephony.DomainSelectionService; 76 import android.telephony.NetworkRegistrationInfo; 77 import android.telephony.RadioAccessFamily; 78 import android.telephony.ServiceState; 79 import android.telephony.SubscriptionManager; 80 import android.telephony.TelephonyManager; 81 import android.telephony.emergency.EmergencyNumber; 82 import android.telephony.ims.ImsReasonInfo; 83 import android.telephony.ims.stub.ImsRegistrationImplBase; 84 import android.util.ArrayMap; 85 86 import androidx.test.filters.SmallTest; 87 import androidx.test.runner.AndroidJUnit4; 88 89 import com.android.TelephonyTestBase; 90 import com.android.ims.ImsManager; 91 import com.android.internal.telecom.IConnectionService; 92 import com.android.internal.telephony.Call; 93 import com.android.internal.telephony.CallStateException; 94 import com.android.internal.telephony.Connection; 95 import com.android.internal.telephony.Phone; 96 import com.android.internal.telephony.PhoneConstants; 97 import com.android.internal.telephony.PhoneInternalInterface.DialArgs; 98 import com.android.internal.telephony.ServiceStateTracker; 99 import com.android.internal.telephony.data.PhoneSwitcher; 100 import com.android.internal.telephony.domainselection.DomainSelectionConnection; 101 import com.android.internal.telephony.domainselection.DomainSelectionResolver; 102 import com.android.internal.telephony.domainselection.EmergencyCallDomainSelectionConnection; 103 import com.android.internal.telephony.domainselection.NormalCallDomainSelectionConnection; 104 import com.android.internal.telephony.emergency.EmergencyNumberTracker; 105 import com.android.internal.telephony.emergency.EmergencyStateTracker; 106 import com.android.internal.telephony.emergency.RadioOnHelper; 107 import com.android.internal.telephony.emergency.RadioOnStateListener; 108 import com.android.internal.telephony.flags.FeatureFlags; 109 import com.android.internal.telephony.flags.Flags; 110 import com.android.internal.telephony.gsm.SuppServiceNotification; 111 import com.android.internal.telephony.imsphone.ImsPhone; 112 import com.android.internal.telephony.satellite.SatelliteController; 113 import com.android.internal.telephony.satellite.SatelliteSOSMessageRecommender; 114 import com.android.internal.telephony.subscription.SubscriptionInfoInternal; 115 import com.android.internal.telephony.subscription.SubscriptionManagerService; 116 117 import org.junit.After; 118 import org.junit.Before; 119 import org.junit.Rule; 120 import org.junit.Test; 121 import org.junit.runner.RunWith; 122 import org.mockito.ArgumentCaptor; 123 import org.mockito.Mock; 124 import org.mockito.Mockito; 125 126 import java.util.ArrayList; 127 import java.util.Arrays; 128 import java.util.Collection; 129 import java.util.Collections; 130 import java.util.HashMap; 131 import java.util.List; 132 import java.util.Map; 133 import java.util.concurrent.CompletableFuture; 134 import java.util.concurrent.Executor; 135 import java.util.function.Consumer; 136 137 /** 138 * Unit tests for TelephonyConnectionService. 139 */ 140 141 @RunWith(AndroidJUnit4.class) 142 public class TelephonyConnectionServiceTest extends TelephonyTestBase { 143 @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); 144 private static final String NORMAL_ROUTED_EMERGENCY_NUMBER = "110"; 145 private static final String EMERGENCY_ROUTED_EMERGENCY_NUMBER = "911"; 146 private static final EmergencyNumber MOCK_NORMAL_NUMBER = new EmergencyNumber( 147 NORMAL_ROUTED_EMERGENCY_NUMBER, 148 "US" /* country */, 149 null /* mcc */, 150 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED, 151 Collections.emptyList() /* categories */, 152 EmergencyNumber.EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALING, 153 EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL); 154 private static final EmergencyNumber MOCK_NORMAL_NUMBER_WITH_UNKNOWN_ROUTING = 155 new EmergencyNumber( 156 NORMAL_ROUTED_EMERGENCY_NUMBER, 157 "US" /* country */, 158 "455" /* mcc */, 159 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED, 160 Collections.emptyList() /* categories */, 161 EmergencyNumber.EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALING, 162 EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN); 163 private static final EmergencyNumber MOCK_EMERGENCY_NUMBER = new EmergencyNumber( 164 EMERGENCY_ROUTED_EMERGENCY_NUMBER, 165 "US" /* country */, 166 null /* mcc */, 167 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED, 168 Collections.emptyList() /* categories */, 169 EmergencyNumber.EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALING, 170 EmergencyNumber.EMERGENCY_CALL_ROUTING_EMERGENCY); 171 172 /** 173 * Unlike {@link TestTelephonyConnection}, a bare minimal {@link TelephonyConnection} impl 174 * that does not try to configure anything. 175 */ 176 public static class SimpleTelephonyConnection extends TelephonyConnection { 177 public boolean wasDisconnected = false; 178 public boolean wasUnheld = false; 179 public boolean wasHeld = false; 180 181 @Override cloneConnection()182 public TelephonyConnection cloneConnection() { 183 return null; 184 } 185 186 @Override hangup(int telephonyDisconnectCode)187 public void hangup(int telephonyDisconnectCode) { 188 wasDisconnected = true; 189 } 190 191 @Override onUnhold()192 public void onUnhold() { 193 wasUnheld = true; 194 } 195 196 @Override onHold()197 public void onHold() { 198 wasHeld = true; 199 } 200 } 201 202 public static class SimpleConference extends Conference { 203 public boolean wasUnheld = false; 204 SimpleConference(PhoneAccountHandle phoneAccountHandle)205 public SimpleConference(PhoneAccountHandle phoneAccountHandle) { 206 super(phoneAccountHandle); 207 } 208 209 @Override onUnhold()210 public void onUnhold() { 211 wasUnheld = true; 212 } 213 } 214 215 private static final long TIMEOUT_MS = 100; 216 private static final int SLOT_0_PHONE_ID = 0; 217 private static final int SLOT_1_PHONE_ID = 1; 218 219 private static final ComponentName TEST_COMPONENT_NAME = new ComponentName( 220 "com.android.phone.tests", TelephonyConnectionServiceTest.class.getName()); 221 private static final String TEST_ACCOUNT_ID1 = "0"; // subid 0 222 private static final String TEST_ACCOUNT_ID2 = "1"; // subid 1 223 private static final PhoneAccountHandle PHONE_ACCOUNT_HANDLE_1 = new PhoneAccountHandle( 224 TEST_COMPONENT_NAME, TEST_ACCOUNT_ID1); 225 private static final PhoneAccountHandle PHONE_ACCOUNT_HANDLE_2 = new PhoneAccountHandle( 226 TEST_COMPONENT_NAME, TEST_ACCOUNT_ID2); 227 private static final Uri TEST_ADDRESS = Uri.parse("tel:+16505551212"); 228 private static final String TELECOM_CALL_ID1 = "TC1"; 229 private static final String TEST_EMERGENCY_NUMBER = "911"; 230 private static final String DISCONNECT_REASON_SATELLITE_ENABLED = "SATELLITE_ENABLED"; 231 private static final String DISCONNECT_REASON_CARRIER_ROAMING_SATELLITE_MODE = 232 "CARRIER_ROAMING_SATELLITE_MODE"; 233 private android.telecom.Connection mConnection; 234 235 @Mock TelephonyConnectionService.TelephonyManagerProxy mTelephonyManagerProxy; 236 @Mock TelephonyConnectionService.SubscriptionManagerProxy mSubscriptionManagerProxy; 237 @Mock TelephonyConnectionService.PhoneFactoryProxy mPhoneFactoryProxy; 238 @Mock DeviceState mDeviceState; 239 @Mock TelephonyConnectionService.PhoneSwitcherProxy mPhoneSwitcherProxy; 240 @Mock TelephonyConnectionService.PhoneNumberUtilsProxy mPhoneNumberUtilsProxy; 241 @Mock TelephonyConnectionService.PhoneUtilsProxy mPhoneUtilsProxy; 242 @Mock TelephonyConnectionService.DisconnectCauseFactory mDisconnectCauseFactory; 243 @Mock SatelliteController mSatelliteController; 244 @Mock EmergencyNumberTracker mEmergencyNumberTracker; 245 @Mock PhoneSwitcher mPhoneSwitcher; 246 @Mock RadioOnHelper mRadioOnHelper; 247 @Mock ServiceStateTracker mSST; 248 @Mock Call mCall; 249 @Mock Call mCall2; 250 @Mock com.android.internal.telephony.Connection mInternalConnection; 251 @Mock com.android.internal.telephony.Connection mInternalConnection2; 252 @Mock DomainSelectionResolver mDomainSelectionResolver; 253 @Mock EmergencyCallDomainSelectionConnection mEmergencyCallDomainSelectionConnection; 254 @Mock NormalCallDomainSelectionConnection mNormalCallDomainSelectionConnection; 255 @Mock ImsPhone mImsPhone; 256 @Mock private SatelliteSOSMessageRecommender mSatelliteSOSMessageRecommender; 257 @Mock private EmergencyStateTracker mEmergencyStateTracker; 258 @Mock private Resources mMockResources; 259 @Mock private FeatureFlags mFeatureFlags; 260 private Phone mPhone0; 261 private Phone mPhone1; 262 263 private static class TestTelephonyConnectionService extends TelephonyConnectionService { 264 265 private final Context mContext; 266 TestTelephonyConnectionService(Context context)267 TestTelephonyConnectionService(Context context) { 268 mContext = context; 269 } 270 271 @Override onCreate()272 public void onCreate() { 273 // attach test context. 274 attachBaseContext(mContext); 275 super.onCreate(); 276 } 277 } 278 279 private TelephonyConnectionService mTestConnectionService; 280 private IConnectionService.Stub mBinderStub; 281 282 @Before setUp()283 public void setUp() throws Exception { 284 super.setUp(); 285 286 mTestConnectionService = new TestTelephonyConnectionService(mContext); 287 mTestConnectionService.setFeatureFlags(mFeatureFlags); 288 mTestConnectionService.setPhoneFactoryProxy(mPhoneFactoryProxy); 289 mTestConnectionService.setSubscriptionManagerProxy(mSubscriptionManagerProxy); 290 // Set configurations statically 291 doReturn(false).when(mDeviceState).shouldCheckSimStateBeforeOutgoingCall(any()); 292 mTestConnectionService.setPhoneSwitcherProxy(mPhoneSwitcherProxy); 293 doReturn(mPhoneSwitcher).when(mPhoneSwitcherProxy).getPhoneSwitcher(); 294 when(mPhoneNumberUtilsProxy.convertToEmergencyNumber(any(), anyString())) 295 .thenAnswer(invocation -> invocation.getArgument(1)); 296 mTestConnectionService.setPhoneNumberUtilsProxy(mPhoneNumberUtilsProxy); 297 mTestConnectionService.setPhoneUtilsProxy(mPhoneUtilsProxy); 298 mTestConnectionService.setDeviceState(mDeviceState); 299 mTestConnectionService.setRadioOnHelper(mRadioOnHelper); 300 doAnswer(invocation -> DisconnectCauseUtil.toTelecomDisconnectCause( 301 invocation.getArgument(0), invocation.getArgument(1))) 302 .when(mDisconnectCauseFactory).toTelecomDisconnectCause(anyInt(), any()); 303 doAnswer(invocation -> DisconnectCauseUtil.toTelecomDisconnectCause( 304 invocation.getArgument(0), invocation.getArgument(1), 305 (int) invocation.getArgument(2))) 306 .when(mDisconnectCauseFactory).toTelecomDisconnectCause(anyInt(), any(), anyInt()); 307 mTestConnectionService.setDisconnectCauseFactory(mDisconnectCauseFactory); 308 mTestConnectionService.onCreate(); 309 mTestConnectionService.setTelephonyManagerProxy(mTelephonyManagerProxy); 310 replaceInstance(TelephonyConnectionService.class, "mDomainSelectionResolver", 311 mTestConnectionService, mDomainSelectionResolver); 312 replaceInstance(TelephonyConnectionService.class, "mEmergencyStateTracker", 313 mTestConnectionService, mEmergencyStateTracker); 314 replaceInstance(TelephonyConnectionService.class, "mSatelliteSOSMessageRecommender", 315 mTestConnectionService, mSatelliteSOSMessageRecommender); 316 doNothing().when(mSatelliteSOSMessageRecommender).onEmergencyCallStarted(any(), 317 anyBoolean()); 318 doNothing().when(mSatelliteSOSMessageRecommender).onEmergencyCallConnectionStateChanged( 319 anyString(), anyInt()); 320 doReturn(CompletableFuture.completedFuture(NOT_DISCONNECTED)) 321 .when(mEmergencyStateTracker) 322 .startEmergencyCall(any(), any(), eq(false)); 323 replaceInstance(TelephonyConnectionService.class, 324 "mDomainSelectionMainExecutor", mTestConnectionService, getExecutor()); 325 doReturn(false).when(mDomainSelectionResolver).isDomainSelectionSupported(); 326 doReturn(null).when(mDomainSelectionResolver).getDomainSelectionConnection( 327 any(), anyInt(), anyBoolean()); 328 replaceInstance(TelephonyConnectionService.class, 329 "mSatelliteController", mTestConnectionService, mSatelliteController); 330 doReturn(mMockResources).when(mContext).getResources(); 331 332 mBinderStub = (IConnectionService.Stub) mTestConnectionService.onBind(null); 333 mSetFlagsRule.disableFlags(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG); 334 mSetFlagsRule.enableFlags(Flags.FLAG_DO_NOT_OVERRIDE_PRECISE_LABEL); 335 mSetFlagsRule.enableFlags(Flags.FLAG_CALL_EXTRA_FOR_NON_HOLD_SUPPORTED_CARRIERS); 336 } 337 338 @After tearDown()339 public void tearDown() throws Exception { 340 if (mTestConnectionService != null 341 && mTestConnectionService.getEmergencyConnection() != null) { 342 mTestConnectionService.onLocalHangup(mTestConnectionService.getEmergencyConnection()); 343 } 344 mTestConnectionService = null; 345 super.tearDown(); 346 } 347 348 /** 349 * Prerequisites: 350 * - MSIM Device, two slots with SIMs inserted 351 * - Slot 0 is IN_SERVICE, Slot 1 is OUT_OF_SERVICE (emergency calls only) 352 * - Slot 1 is in Emergency SMS Mode 353 * 354 * Result: getFirstPhoneForEmergencyCall returns the slot 1 phone 355 */ 356 @Test 357 @SmallTest testEmergencySmsModeSimEmergencyOnly()358 public void testEmergencySmsModeSimEmergencyOnly() { 359 Phone slot0Phone = makeTestPhone(SLOT_0_PHONE_ID, ServiceState.STATE_IN_SERVICE, 360 false /*isEmergencyOnly*/); 361 Phone slot1Phone = makeTestPhone(SLOT_1_PHONE_ID, ServiceState.STATE_OUT_OF_SERVICE, 362 true /*isEmergencyOnly*/); 363 setDefaultPhone(slot0Phone); 364 setupDeviceConfig(slot0Phone, slot1Phone, SLOT_0_PHONE_ID); 365 setEmergencySmsMode(slot1Phone, true); 366 367 Phone resultPhone = mTestConnectionService.getFirstPhoneForEmergencyCall(); 368 369 assertEquals(slot1Phone, resultPhone); 370 } 371 372 /** 373 * Prerequisites: 374 * - MSIM Device, two slots with SIMs inserted 375 * - Slot 0 is IN_SERVICE, Slot 1 is OUT_OF_SERVICE 376 * - Slot 1 is in Emergency SMS Mode 377 * 378 * Result: getFirstPhoneForEmergencyCall returns the slot 0 phone 379 */ 380 @Test 381 @SmallTest testEmergencySmsModeSimOutOfService()382 public void testEmergencySmsModeSimOutOfService() { 383 Phone slot0Phone = makeTestPhone(SLOT_0_PHONE_ID, ServiceState.STATE_IN_SERVICE, 384 false /*isEmergencyOnly*/); 385 Phone slot1Phone = makeTestPhone(SLOT_1_PHONE_ID, ServiceState.STATE_OUT_OF_SERVICE, 386 false /*isEmergencyOnly*/); 387 setDefaultPhone(slot0Phone); 388 setupDeviceConfig(slot0Phone, slot1Phone, SLOT_0_PHONE_ID); 389 setEmergencySmsMode(slot1Phone, true); 390 391 Phone resultPhone = mTestConnectionService.getFirstPhoneForEmergencyCall(); 392 393 assertEquals(slot0Phone, resultPhone); 394 } 395 396 /** 397 * Prerequisites: 398 * - MSIM Device, two slots with SIMs inserted 399 * - Users default Voice SIM choice is IN_SERVICE 400 * 401 * Result: getFirstPhoneForEmergencyCall returns the default Voice SIM choice. 402 */ 403 @Test 404 @SmallTest testDefaultVoiceSimInService()405 public void testDefaultVoiceSimInService() { 406 Phone slot0Phone = makeTestPhone(SLOT_0_PHONE_ID, ServiceState.STATE_IN_SERVICE, 407 false /*isEmergencyOnly*/); 408 Phone slot1Phone = makeTestPhone(SLOT_1_PHONE_ID, ServiceState.STATE_OUT_OF_SERVICE, 409 true /*isEmergencyOnly*/); 410 setDefaultPhone(slot0Phone); 411 setupDeviceConfig(slot0Phone, slot1Phone, SLOT_0_PHONE_ID); 412 413 Phone resultPhone = mTestConnectionService.getFirstPhoneForEmergencyCall(); 414 415 assertEquals(slot0Phone, resultPhone); 416 } 417 418 /** 419 * Prerequisites: 420 * - MSIM Device, two slots with SIMs inserted 421 * - Users default data SIM choice is OUT_OF_SERVICE (emergency calls only) 422 * 423 * Result: getFirstPhoneForEmergencyCall returns the default data SIM choice. 424 */ 425 @Test 426 @SmallTest testDefaultDataSimEmergencyOnly()427 public void testDefaultDataSimEmergencyOnly() { 428 Phone slot0Phone = makeTestPhone(SLOT_0_PHONE_ID, ServiceState.STATE_IN_SERVICE, 429 false /*isEmergencyOnly*/); 430 Phone slot1Phone = makeTestPhone(SLOT_1_PHONE_ID, ServiceState.STATE_OUT_OF_SERVICE, 431 true /*isEmergencyOnly*/); 432 setDefaultPhone(slot0Phone); 433 setupDeviceConfig(slot0Phone, slot1Phone, SubscriptionManager.INVALID_SUBSCRIPTION_ID); 434 setDefaultDataPhoneId(SLOT_1_PHONE_ID); 435 436 Phone resultPhone = mTestConnectionService.getFirstPhoneForEmergencyCall(); 437 438 assertEquals(slot1Phone, resultPhone); 439 } 440 441 /** 442 * Prerequisites: 443 * - MSIM Device, two slots with SIMs inserted 444 * - Users default data SIM choice is OUT_OF_SERVICE 445 * 446 * Result: getFirstPhoneForEmergencyCall does not return the default data SIM choice. 447 */ 448 @Test 449 @SmallTest testDefaultDataSimOutOfService()450 public void testDefaultDataSimOutOfService() { 451 Phone slot0Phone = makeTestPhone(SLOT_0_PHONE_ID, ServiceState.STATE_IN_SERVICE, 452 false /*isEmergencyOnly*/); 453 Phone slot1Phone = makeTestPhone(SLOT_1_PHONE_ID, ServiceState.STATE_OUT_OF_SERVICE, 454 false /*isEmergencyOnly*/); 455 setDefaultPhone(slot0Phone); 456 setupDeviceConfig(slot0Phone, slot1Phone, SubscriptionManager.INVALID_SUBSCRIPTION_ID); 457 setDefaultDataPhoneId(SLOT_1_PHONE_ID); 458 459 Phone resultPhone = mTestConnectionService.getFirstPhoneForEmergencyCall(); 460 461 assertEquals(slot0Phone, resultPhone); 462 } 463 464 /** 465 * Prerequisites: 466 * - MSIM Device, two slots with SIMs inserted 467 * - Slot 0 is OUT_OF_SERVICE, Slot 1 is OUT_OF_SERVICE (emergency calls only) 468 * 469 * Result: getFirstPhoneForEmergencyCall returns the slot 1 phone 470 */ 471 @Test 472 @SmallTest testSlot1EmergencyOnly()473 public void testSlot1EmergencyOnly() { 474 Phone slot0Phone = makeTestPhone(SLOT_0_PHONE_ID, ServiceState.STATE_OUT_OF_SERVICE, 475 false /*isEmergencyOnly*/); 476 Phone slot1Phone = makeTestPhone(SLOT_1_PHONE_ID, ServiceState.STATE_OUT_OF_SERVICE, 477 true /*isEmergencyOnly*/); 478 setDefaultPhone(slot0Phone); 479 setupDeviceConfig(slot0Phone, slot1Phone, SLOT_0_PHONE_ID); 480 481 Phone resultPhone = mTestConnectionService.getFirstPhoneForEmergencyCall(); 482 483 assertEquals(slot1Phone, resultPhone); 484 } 485 486 /** 487 * Prerequisites: 488 * - MSIM Device, two slots with SIMs inserted 489 * - Slot 0 is OUT_OF_SERVICE, Slot 1 is IN_SERVICE 490 * 491 * Result: getFirstPhoneForEmergencyCall returns the slot 1 phone 492 */ 493 @Test 494 @SmallTest testSlot1InService()495 public void testSlot1InService() { 496 Phone slot0Phone = makeTestPhone(SLOT_0_PHONE_ID, ServiceState.STATE_OUT_OF_SERVICE, 497 false /*isEmergencyOnly*/); 498 Phone slot1Phone = makeTestPhone(SLOT_1_PHONE_ID, ServiceState.STATE_IN_SERVICE, 499 false /*isEmergencyOnly*/); 500 setDefaultPhone(slot0Phone); 501 setupDeviceConfig(slot0Phone, slot1Phone, SLOT_0_PHONE_ID); 502 503 Phone resultPhone = mTestConnectionService.getFirstPhoneForEmergencyCall(); 504 505 assertEquals(slot1Phone, resultPhone); 506 } 507 508 /** 509 * Prerequisites: 510 * - MSIM Device, two slots with SIMs inserted 511 * - Slot 0 is PUK locked, Slot 1 is ready 512 * - Slot 0 is LTE capable, Slot 1 is GSM capable 513 * 514 * Result: getFirstPhoneForEmergencyCall returns the slot 1 phone. Although Slot 0 is more 515 * capable, it is locked, so use the other slot. 516 */ 517 @Test 518 @SmallTest testSlot0PukLocked()519 public void testSlot0PukLocked() { 520 Phone slot0Phone = makeTestPhone(SLOT_0_PHONE_ID, ServiceState.STATE_OUT_OF_SERVICE, 521 false /*isEmergencyOnly*/); 522 Phone slot1Phone = makeTestPhone(SLOT_1_PHONE_ID, ServiceState.STATE_OUT_OF_SERVICE, 523 false /*isEmergencyOnly*/); 524 setDefaultPhone(slot0Phone); 525 setupDeviceConfig(slot0Phone, slot1Phone, SLOT_0_PHONE_ID); 526 // Set Slot 0 to be PUK locked 527 setPhoneSlotState(SLOT_0_PHONE_ID, TelephonyManager.SIM_STATE_PUK_REQUIRED); 528 setPhoneSlotState(SLOT_1_PHONE_ID, TelephonyManager.SIM_STATE_READY); 529 // Make Slot 0 higher capability 530 setPhoneRadioAccessFamily(slot0Phone, RadioAccessFamily.RAF_LTE); 531 setPhoneRadioAccessFamily(slot1Phone, RadioAccessFamily.RAF_GSM); 532 533 Phone resultPhone = mTestConnectionService.getFirstPhoneForEmergencyCall(); 534 535 assertEquals(slot1Phone, resultPhone); 536 } 537 538 /** 539 * Prerequisites: 540 * - MSIM Device, two slots with SIMs inserted 541 * - Slot 0 is PIN locked, Slot 1 is ready 542 * - Slot 0 is LTE capable, Slot 1 is GSM capable 543 * 544 * Result: getFirstPhoneForEmergencyCall returns the slot 1 phone. Although Slot 0 is more 545 * capable, it is locked, so use the other slot. 546 */ 547 @Test 548 @SmallTest testSlot0PinLocked()549 public void testSlot0PinLocked() { 550 Phone slot0Phone = makeTestPhone(SLOT_0_PHONE_ID, ServiceState.STATE_OUT_OF_SERVICE, 551 false /*isEmergencyOnly*/); 552 Phone slot1Phone = makeTestPhone(SLOT_1_PHONE_ID, ServiceState.STATE_OUT_OF_SERVICE, 553 false /*isEmergencyOnly*/); 554 setDefaultPhone(slot0Phone); 555 setupDeviceConfig(slot0Phone, slot1Phone, SLOT_0_PHONE_ID); 556 // Set Slot 0 to be PUK locked 557 setPhoneSlotState(SLOT_0_PHONE_ID, TelephonyManager.SIM_STATE_PIN_REQUIRED); 558 setPhoneSlotState(SLOT_1_PHONE_ID, TelephonyManager.SIM_STATE_READY); 559 // Make Slot 0 higher capability 560 setPhoneRadioAccessFamily(slot0Phone, RadioAccessFamily.RAF_LTE); 561 setPhoneRadioAccessFamily(slot1Phone, RadioAccessFamily.RAF_GSM); 562 563 Phone resultPhone = mTestConnectionService.getFirstPhoneForEmergencyCall(); 564 565 assertEquals(slot1Phone, resultPhone); 566 } 567 568 /** 569 * Prerequisites: 570 * - MSIM Device, two slots with SIMs inserted 571 * - Slot 1 is PUK locked, Slot 0 is ready 572 * - Slot 1 is LTE capable, Slot 0 is GSM capable 573 * 574 * Result: getFirstPhoneForEmergencyCall returns the slot 0 phone. Although Slot 1 is more 575 * capable, it is locked, so use the other slot. 576 */ 577 @Test 578 @SmallTest testSlot1PukLocked()579 public void testSlot1PukLocked() { 580 Phone slot0Phone = makeTestPhone(SLOT_0_PHONE_ID, ServiceState.STATE_OUT_OF_SERVICE, 581 false /*isEmergencyOnly*/); 582 Phone slot1Phone = makeTestPhone(SLOT_1_PHONE_ID, ServiceState.STATE_OUT_OF_SERVICE, 583 false /*isEmergencyOnly*/); 584 setDefaultPhone(slot0Phone); 585 setupDeviceConfig(slot0Phone, slot1Phone, SLOT_0_PHONE_ID); 586 // Set Slot 1 to be PUK locked 587 setPhoneSlotState(SLOT_0_PHONE_ID, TelephonyManager.SIM_STATE_READY); 588 setPhoneSlotState(SLOT_1_PHONE_ID, TelephonyManager.SIM_STATE_PUK_REQUIRED); 589 // Make Slot 1 higher capability 590 setPhoneRadioAccessFamily(slot0Phone, RadioAccessFamily.RAF_GSM); 591 setPhoneRadioAccessFamily(slot1Phone, RadioAccessFamily.RAF_LTE); 592 593 Phone resultPhone = mTestConnectionService.getFirstPhoneForEmergencyCall(); 594 595 assertEquals(slot0Phone, resultPhone); 596 } 597 598 /** 599 * Prerequisites: 600 * - MSIM Device, two slots with SIMs inserted 601 * - Slot 1 is PIN locked, Slot 0 is ready 602 * - Slot 1 is LTE capable, Slot 0 is GSM capable 603 * 604 * Result: getFirstPhoneForEmergencyCall returns the slot 0 phone. Although Slot 1 is more 605 * capable, it is locked, so use the other slot. 606 */ 607 @Test 608 @SmallTest testSlot1PinLocked()609 public void testSlot1PinLocked() { 610 Phone slot0Phone = makeTestPhone(SLOT_0_PHONE_ID, ServiceState.STATE_OUT_OF_SERVICE, 611 false /*isEmergencyOnly*/); 612 Phone slot1Phone = makeTestPhone(SLOT_1_PHONE_ID, ServiceState.STATE_OUT_OF_SERVICE, 613 false /*isEmergencyOnly*/); 614 setDefaultPhone(slot0Phone); 615 setupDeviceConfig(slot0Phone, slot1Phone, SLOT_0_PHONE_ID); 616 // Set Slot 1 to be PUK locked 617 setPhoneSlotState(SLOT_0_PHONE_ID, TelephonyManager.SIM_STATE_READY); 618 setPhoneSlotState(SLOT_1_PHONE_ID, TelephonyManager.SIM_STATE_PIN_REQUIRED); 619 // Make Slot 1 higher capability 620 setPhoneRadioAccessFamily(slot0Phone, RadioAccessFamily.RAF_GSM); 621 setPhoneRadioAccessFamily(slot1Phone, RadioAccessFamily.RAF_LTE); 622 623 Phone resultPhone = mTestConnectionService.getFirstPhoneForEmergencyCall(); 624 625 assertEquals(slot0Phone, resultPhone); 626 } 627 628 /** 629 * Prerequisites: 630 * - MSIM Device, only slot 1 inserted and PUK locked 631 * - slot 1 has higher capabilities 632 * 633 * Result: getFirstPhoneForEmergencyCall returns the slot 1 phone because it is the only one 634 * with a SIM inserted (even if it is PUK locked) 635 */ 636 @Test 637 @SmallTest testSlot1PinLockedAndSlot0Absent()638 public void testSlot1PinLockedAndSlot0Absent() { 639 Phone slot0Phone = makeTestPhone(SLOT_0_PHONE_ID, ServiceState.STATE_OUT_OF_SERVICE, 640 false /*isEmergencyOnly*/); 641 Phone slot1Phone = makeTestPhone(SLOT_1_PHONE_ID, ServiceState.STATE_OUT_OF_SERVICE, 642 false /*isEmergencyOnly*/); 643 setDefaultPhone(slot0Phone); 644 setupDeviceConfig(slot0Phone, slot1Phone, SLOT_0_PHONE_ID); 645 setPhoneSlotState(SLOT_0_PHONE_ID, TelephonyManager.SIM_STATE_ABSENT); 646 setPhoneSlotState(SLOT_1_PHONE_ID, TelephonyManager.SIM_STATE_PIN_REQUIRED); 647 // Slot 1 has more capabilities 648 setPhoneRadioAccessFamily(slot0Phone, RadioAccessFamily.RAF_GSM); 649 setPhoneRadioAccessFamily(slot1Phone, RadioAccessFamily.RAF_LTE); 650 651 Phone resultPhone = mTestConnectionService.getFirstPhoneForEmergencyCall(); 652 653 assertEquals(slot1Phone, resultPhone); 654 } 655 656 /** 657 * Prerequisites: 658 * - MSIM Device, two slots with SIMs inserted 659 * - Slot 1 is LTE capable, Slot 0 is GSM capable 660 * 661 * Result: getFirstPhoneForEmergencyCall returns the slot 1 phone because it is more capable 662 */ 663 @Test 664 @SmallTest testSlot1HigherCapability()665 public void testSlot1HigherCapability() { 666 Phone slot0Phone = makeTestPhone(SLOT_0_PHONE_ID, ServiceState.STATE_OUT_OF_SERVICE, 667 false /*isEmergencyOnly*/); 668 Phone slot1Phone = makeTestPhone(SLOT_1_PHONE_ID, ServiceState.STATE_OUT_OF_SERVICE, 669 false /*isEmergencyOnly*/); 670 setDefaultPhone(slot0Phone); 671 setupDeviceConfig(slot0Phone, slot1Phone, SLOT_0_PHONE_ID); 672 setPhoneSlotState(SLOT_0_PHONE_ID, TelephonyManager.SIM_STATE_READY); 673 setPhoneSlotState(SLOT_1_PHONE_ID, TelephonyManager.SIM_STATE_READY); 674 // Make Slot 1 higher capability 675 setPhoneRadioAccessFamily(slot0Phone, RadioAccessFamily.RAF_GSM); 676 setPhoneRadioAccessFamily(slot1Phone, RadioAccessFamily.RAF_LTE); 677 678 Phone resultPhone = mTestConnectionService.getFirstPhoneForEmergencyCall(); 679 680 assertEquals(slot1Phone, resultPhone); 681 } 682 683 /** 684 * Prerequisites: 685 * - MSIM Device, two slots with SIMs inserted 686 * - Slot 1 is GSM/LTE capable, Slot 0 is GSM capable 687 * 688 * Result: getFirstPhoneForEmergencyCall returns the slot 1 phone because it has more 689 * capabilities. 690 */ 691 @Test 692 @SmallTest testSlot1MoreCapabilities()693 public void testSlot1MoreCapabilities() { 694 Phone slot0Phone = makeTestPhone(SLOT_0_PHONE_ID, ServiceState.STATE_OUT_OF_SERVICE, 695 false /*isEmergencyOnly*/); 696 Phone slot1Phone = makeTestPhone(SLOT_1_PHONE_ID, ServiceState.STATE_OUT_OF_SERVICE, 697 false /*isEmergencyOnly*/); 698 setDefaultPhone(slot0Phone); 699 setupDeviceConfig(slot0Phone, slot1Phone, SLOT_0_PHONE_ID); 700 setPhoneSlotState(SLOT_0_PHONE_ID, TelephonyManager.SIM_STATE_READY); 701 setPhoneSlotState(SLOT_1_PHONE_ID, TelephonyManager.SIM_STATE_READY); 702 // Make Slot 1 more capable 703 setPhoneRadioAccessFamily(slot0Phone, RadioAccessFamily.RAF_LTE); 704 setPhoneRadioAccessFamily(slot1Phone, 705 RadioAccessFamily.RAF_GSM | RadioAccessFamily.RAF_LTE); 706 707 Phone resultPhone = mTestConnectionService.getFirstPhoneForEmergencyCall(); 708 709 assertEquals(slot1Phone, resultPhone); 710 } 711 712 /** 713 * Prerequisites: 714 * - MSIM Device, two slots with SIMs inserted 715 * - Both SIMs PUK Locked 716 * - Slot 0 is LTE capable, Slot 1 is GSM capable 717 * 718 * Result: getFirstPhoneForEmergencyCall returns the slot 0 phone because it is more capable, 719 * ignoring that both SIMs are PUK locked. 720 */ 721 @Test 722 @SmallTest testSlot0MoreCapableBothPukLocked()723 public void testSlot0MoreCapableBothPukLocked() { 724 Phone slot0Phone = makeTestPhone(SLOT_0_PHONE_ID, ServiceState.STATE_OUT_OF_SERVICE, 725 false /*isEmergencyOnly*/); 726 Phone slot1Phone = makeTestPhone(SLOT_1_PHONE_ID, ServiceState.STATE_OUT_OF_SERVICE, 727 false /*isEmergencyOnly*/); 728 setDefaultPhone(slot0Phone); 729 setupDeviceConfig(slot0Phone, slot1Phone, SLOT_0_PHONE_ID); 730 setPhoneSlotState(SLOT_0_PHONE_ID, TelephonyManager.SIM_STATE_PUK_REQUIRED); 731 setPhoneSlotState(SLOT_1_PHONE_ID, TelephonyManager.SIM_STATE_PUK_REQUIRED); 732 // Make Slot 0 higher capability 733 setPhoneRadioAccessFamily(slot0Phone, RadioAccessFamily.RAF_LTE); 734 setPhoneRadioAccessFamily(slot1Phone, RadioAccessFamily.RAF_GSM); 735 736 Phone resultPhone = mTestConnectionService.getFirstPhoneForEmergencyCall(); 737 738 assertEquals(slot0Phone, resultPhone); 739 } 740 741 /** 742 * Prerequisites: 743 * - MSIM Device, two slots with SIMs inserted 744 * - Both SIMs have the same capability 745 * 746 * Result: getFirstPhoneForEmergencyCall returns the slot 0 phone because it is the first slot. 747 */ 748 @Test 749 @SmallTest testEqualCapabilityTwoSimsInserted()750 public void testEqualCapabilityTwoSimsInserted() { 751 Phone slot0Phone = makeTestPhone(SLOT_0_PHONE_ID, ServiceState.STATE_OUT_OF_SERVICE, 752 false /*isEmergencyOnly*/); 753 Phone slot1Phone = makeTestPhone(SLOT_1_PHONE_ID, ServiceState.STATE_OUT_OF_SERVICE, 754 false /*isEmergencyOnly*/); 755 setDefaultPhone(slot0Phone); 756 setupDeviceConfig(slot0Phone, slot1Phone, SLOT_0_PHONE_ID); 757 setPhoneSlotState(SLOT_0_PHONE_ID, TelephonyManager.SIM_STATE_READY); 758 setPhoneSlotState(SLOT_1_PHONE_ID, TelephonyManager.SIM_STATE_READY); 759 // Make Capability the same 760 setPhoneRadioAccessFamily(slot0Phone, RadioAccessFamily.RAF_LTE); 761 setPhoneRadioAccessFamily(slot1Phone, RadioAccessFamily.RAF_LTE); 762 763 Phone resultPhone = mTestConnectionService.getFirstPhoneForEmergencyCall(); 764 765 assertEquals(slot0Phone, resultPhone); 766 } 767 768 /** 769 * Prerequisites: 770 * - MSIM Device, only slot 0 inserted 771 * - Both SIMs have the same capability 772 * 773 * Result: getFirstPhoneForEmergencyCall returns the slot 0 phone because it is the only one 774 * with a SIM inserted 775 */ 776 @Test 777 @SmallTest testEqualCapabilitySim0Inserted()778 public void testEqualCapabilitySim0Inserted() { 779 Phone slot0Phone = makeTestPhone(SLOT_0_PHONE_ID, ServiceState.STATE_OUT_OF_SERVICE, 780 false /*isEmergencyOnly*/); 781 Phone slot1Phone = makeTestPhone(SLOT_1_PHONE_ID, ServiceState.STATE_OUT_OF_SERVICE, 782 false /*isEmergencyOnly*/); 783 setDefaultPhone(slot0Phone); 784 setupDeviceConfig(slot0Phone, slot1Phone, SLOT_0_PHONE_ID); 785 setPhoneSlotState(SLOT_0_PHONE_ID, TelephonyManager.SIM_STATE_READY); 786 setPhoneSlotState(SLOT_1_PHONE_ID, TelephonyManager.SIM_STATE_ABSENT); 787 // Make Capability the same 788 setPhoneRadioAccessFamily(slot0Phone, RadioAccessFamily.RAF_LTE); 789 setPhoneRadioAccessFamily(slot1Phone, RadioAccessFamily.RAF_LTE); 790 791 Phone resultPhone = mTestConnectionService.getFirstPhoneForEmergencyCall(); 792 793 assertEquals(slot0Phone, resultPhone); 794 } 795 796 /** 797 * Prerequisites: 798 * - MSIM Device, only slot 1 inserted 799 * - Both SIMs have the same capability 800 * 801 * Result: getFirstPhoneForEmergencyCall returns the slot 1 phone because it is the only one 802 * with a SIM inserted 803 */ 804 @Test 805 @SmallTest testEqualCapabilitySim1Inserted()806 public void testEqualCapabilitySim1Inserted() { 807 Phone slot0Phone = makeTestPhone(SLOT_0_PHONE_ID, ServiceState.STATE_OUT_OF_SERVICE, 808 false /*isEmergencyOnly*/); 809 Phone slot1Phone = makeTestPhone(SLOT_1_PHONE_ID, ServiceState.STATE_OUT_OF_SERVICE, 810 false /*isEmergencyOnly*/); 811 setDefaultPhone(slot0Phone); 812 setupDeviceConfig(slot0Phone, slot1Phone, SLOT_0_PHONE_ID); 813 setPhoneSlotState(SLOT_0_PHONE_ID, TelephonyManager.SIM_STATE_ABSENT); 814 setPhoneSlotState(SLOT_1_PHONE_ID, TelephonyManager.SIM_STATE_READY); 815 // Make Capability the same 816 setPhoneRadioAccessFamily(slot0Phone, RadioAccessFamily.RAF_LTE); 817 setPhoneRadioAccessFamily(slot1Phone, RadioAccessFamily.RAF_LTE); 818 819 Phone resultPhone = mTestConnectionService.getFirstPhoneForEmergencyCall(); 820 821 assertEquals(slot1Phone, resultPhone); 822 } 823 824 /** 825 * Prerequisites: 826 * - MSIM Device with one ESIM, only slot 1 inserted has PSIM inserted 827 * - Both phones have the same capability 828 * 829 * Result: getFirstPhoneForEmergencyCall returns the slot 1 phone because it is the only one 830 * with a SIM inserted 831 */ 832 @Test 833 @SmallTest testEqualCapabilitySim1Inserted_WithOneEsim()834 public void testEqualCapabilitySim1Inserted_WithOneEsim() { 835 Phone slot0Phone = makeTestPhone(SLOT_0_PHONE_ID, ServiceState.STATE_OUT_OF_SERVICE, 836 false /*isEmergencyOnly*/); 837 Phone slot1Phone = makeTestPhone(SLOT_1_PHONE_ID, ServiceState.STATE_OUT_OF_SERVICE, 838 false /*isEmergencyOnly*/); 839 setDefaultPhone(slot0Phone); 840 setupDeviceConfig(slot0Phone, slot1Phone, SLOT_0_PHONE_ID); 841 when(slot0Phone.getSubId()).thenReturn(SubscriptionManager.INVALID_SUBSCRIPTION_ID); 842 setPhoneSlotState(SLOT_0_PHONE_ID, TelephonyManager.SIM_STATE_READY); 843 setPhoneSlotState(SLOT_1_PHONE_ID, TelephonyManager.SIM_STATE_READY); 844 // Make Capability the same 845 setPhoneRadioAccessFamily(slot0Phone, RadioAccessFamily.RAF_LTE); 846 setPhoneRadioAccessFamily(slot1Phone, RadioAccessFamily.RAF_LTE); 847 848 Phone resultPhone = mTestConnectionService.getFirstPhoneForEmergencyCall(); 849 850 assertEquals(slot1Phone, resultPhone); 851 } 852 853 /** 854 * Prerequisites: 855 * - MSIM Device, no SIMs inserted 856 * - SIM 1 has the higher capability 857 * 858 * Result: getFirstPhoneForEmergencyCall returns the slot 1 phone, since it is a higher 859 * capability 860 */ 861 @Test 862 @SmallTest testSim1HigherCapabilityNoSimsInserted()863 public void testSim1HigherCapabilityNoSimsInserted() { 864 Phone slot0Phone = makeTestPhone(SLOT_0_PHONE_ID, ServiceState.STATE_OUT_OF_SERVICE, 865 false /*isEmergencyOnly*/); 866 Phone slot1Phone = makeTestPhone(SLOT_1_PHONE_ID, ServiceState.STATE_OUT_OF_SERVICE, 867 false /*isEmergencyOnly*/); 868 setDefaultPhone(slot0Phone); 869 setupDeviceConfig(slot0Phone, slot1Phone, SLOT_0_PHONE_ID); 870 setPhoneSlotState(SLOT_0_PHONE_ID, TelephonyManager.SIM_STATE_ABSENT); 871 setPhoneSlotState(SLOT_1_PHONE_ID, TelephonyManager.SIM_STATE_ABSENT); 872 // Make Capability the same 873 setPhoneRadioAccessFamily(slot0Phone, RadioAccessFamily.RAF_GSM); 874 setPhoneRadioAccessFamily(slot1Phone, RadioAccessFamily.RAF_LTE); 875 876 Phone resultPhone = mTestConnectionService.getFirstPhoneForEmergencyCall(); 877 878 assertEquals(slot1Phone, resultPhone); 879 } 880 881 /** 882 * Prerequisites: 883 * - MSIM Device, no SIMs inserted 884 * - Both SIMs have the same capability (Unknown) 885 * 886 * Result: getFirstPhoneForEmergencyCall returns the slot 0 phone, since it is the first slot. 887 */ 888 @Test 889 @SmallTest testEqualCapabilityNoSimsInserted()890 public void testEqualCapabilityNoSimsInserted() { 891 Phone slot0Phone = makeTestPhone(SLOT_0_PHONE_ID, ServiceState.STATE_OUT_OF_SERVICE, 892 false /*isEmergencyOnly*/); 893 Phone slot1Phone = makeTestPhone(SLOT_1_PHONE_ID, ServiceState.STATE_OUT_OF_SERVICE, 894 false /*isEmergencyOnly*/); 895 setDefaultPhone(slot0Phone); 896 setupDeviceConfig(slot0Phone, slot1Phone, SLOT_0_PHONE_ID); 897 setPhoneSlotState(SLOT_0_PHONE_ID, TelephonyManager.SIM_STATE_ABSENT); 898 setPhoneSlotState(SLOT_1_PHONE_ID, TelephonyManager.SIM_STATE_ABSENT); 899 // Make Capability the same 900 setPhoneRadioAccessFamily(slot0Phone, RadioAccessFamily.RAF_UNKNOWN); 901 setPhoneRadioAccessFamily(slot1Phone, RadioAccessFamily.RAF_UNKNOWN); 902 903 Phone resultPhone = mTestConnectionService.getFirstPhoneForEmergencyCall(); 904 905 assertEquals(slot0Phone, resultPhone); 906 } 907 908 /** 909 * Prerequisites: 910 * - MSIM Device, no SIMs inserted (one ESIM) 911 * - Both SIMs have the same capability (Unknown) 912 * 913 * Result: getFirstPhoneForEmergencyCall returns the slot 0 phone, since it is the first slot. 914 */ 915 @Test 916 @SmallTest testEqualCapabilityNoSimsInserted_WithOneESim()917 public void testEqualCapabilityNoSimsInserted_WithOneESim() { 918 Phone slot0Phone = makeTestPhone(SLOT_0_PHONE_ID, ServiceState.STATE_OUT_OF_SERVICE, 919 false /*isEmergencyOnly*/); 920 Phone slot1Phone = makeTestPhone(SLOT_1_PHONE_ID, ServiceState.STATE_OUT_OF_SERVICE, 921 false /*isEmergencyOnly*/); 922 setDefaultPhone(slot0Phone); 923 setupDeviceConfig(slot0Phone, slot1Phone, SLOT_0_PHONE_ID); 924 setPhoneSlotState(SLOT_0_PHONE_ID, TelephonyManager.SIM_STATE_ABSENT); 925 when(slot1Phone.getSubId()).thenReturn(SubscriptionManager.INVALID_SUBSCRIPTION_ID); 926 setPhoneSlotState(SLOT_1_PHONE_ID, TelephonyManager.SIM_STATE_READY); 927 // Make Capability the samesvim 928 setPhoneRadioAccessFamily(slot0Phone, RadioAccessFamily.RAF_UNKNOWN); 929 setPhoneRadioAccessFamily(slot1Phone, RadioAccessFamily.RAF_UNKNOWN); 930 931 Phone resultPhone = mTestConnectionService.getFirstPhoneForEmergencyCall(); 932 933 assertEquals(slot0Phone, resultPhone); 934 } 935 936 /** 937 * Prerequisites: 938 * - MSIM Device, both ESIMS (no profile activated) 939 * - Both phones have the same capability (Unknown) 940 * 941 * Result: getFirstPhoneForEmergencyCall returns the slot 0 phone, since it is the first slot. 942 */ 943 @Test 944 @SmallTest testEqualCapabilityNoSimsInserted_WithTwoESims()945 public void testEqualCapabilityNoSimsInserted_WithTwoESims() { 946 Phone slot0Phone = makeTestPhone(SLOT_0_PHONE_ID, ServiceState.STATE_OUT_OF_SERVICE, 947 false /*isEmergencyOnly*/); 948 Phone slot1Phone = makeTestPhone(SLOT_1_PHONE_ID, ServiceState.STATE_OUT_OF_SERVICE, 949 false /*isEmergencyOnly*/); 950 setDefaultPhone(slot0Phone); 951 setupDeviceConfig(slot0Phone, slot1Phone, SLOT_0_PHONE_ID); 952 when(slot0Phone.getSubId()).thenReturn(SubscriptionManager.INVALID_SUBSCRIPTION_ID); 953 setPhoneSlotState(SLOT_0_PHONE_ID, TelephonyManager.SIM_STATE_READY); 954 when(slot1Phone.getSubId()).thenReturn(SubscriptionManager.INVALID_SUBSCRIPTION_ID); 955 setPhoneSlotState(SLOT_1_PHONE_ID, TelephonyManager.SIM_STATE_READY); 956 // Make Capability the sames 957 setPhoneRadioAccessFamily(slot0Phone, RadioAccessFamily.RAF_UNKNOWN); 958 setPhoneRadioAccessFamily(slot1Phone, RadioAccessFamily.RAF_UNKNOWN); 959 960 Phone resultPhone = mTestConnectionService.getFirstPhoneForEmergencyCall(); 961 962 assertEquals(slot0Phone, resultPhone); 963 } 964 965 /** 966 * The modem has returned a temporary error when placing an emergency call on a phone with one 967 * SIM slot. 968 * 969 * Verify that dial is called on the same phone again when retryOutgoingOriginalConnection is 970 * called. 971 */ 972 @Test 973 @SmallTest testRetryOutgoingOriginalConnection_redialTempFailOneSlot()974 public void testRetryOutgoingOriginalConnection_redialTempFailOneSlot() { 975 TestTelephonyConnection c = new TestTelephonyConnection(); 976 Phone slot0Phone = c.getPhone(); 977 when(slot0Phone.getPhoneId()).thenReturn(SLOT_0_PHONE_ID); 978 List<Phone> phones = new ArrayList<>(1); 979 phones.add(slot0Phone); 980 setPhones(phones); 981 c.setAddress(TEST_ADDRESS, TelecomManager.PRESENTATION_ALLOWED); 982 983 mTestConnectionService.retryOutgoingOriginalConnection(c, 984 c.getPhone(), false /*isPermanentFailure*/); 985 986 // We never need to be notified in telecom that the PhoneAccount has changed, because it 987 // was redialed on the same slot 988 assertEquals(0, c.getNotifyPhoneAccountChangedCount()); 989 try { 990 verify(slot0Phone).dial(anyString(), any(), any()); 991 } catch (CallStateException e) { 992 // This shouldn't happen 993 fail(); 994 } 995 } 996 997 /** 998 * The modem has returned a permanent failure when placing an emergency call on a phone with one 999 * SIM slot. 1000 * 1001 * Verify that the connection is set to disconnected with an error disconnect cause and dial is 1002 * not called. 1003 */ 1004 @Test 1005 @SmallTest testRetryOutgoingOriginalConnection_redialPermFailOneSlot()1006 public void testRetryOutgoingOriginalConnection_redialPermFailOneSlot() { 1007 TestTelephonyConnection c = new TestTelephonyConnection(); 1008 Phone slot0Phone = c.getPhone(); 1009 when(slot0Phone.getPhoneId()).thenReturn(SLOT_0_PHONE_ID); 1010 List<Phone> phones = new ArrayList<>(1); 1011 phones.add(slot0Phone); 1012 setPhones(phones); 1013 c.setAddress(TEST_ADDRESS, TelecomManager.PRESENTATION_ALLOWED); 1014 1015 mTestConnectionService.retryOutgoingOriginalConnection(c, 1016 c.getPhone(), true /*isPermanentFailure*/); 1017 1018 // We never need to be notified in telecom that the PhoneAccount has changed, because it 1019 // was never redialed 1020 assertEquals(0, c.getNotifyPhoneAccountChangedCount()); 1021 try { 1022 verify(slot0Phone, never()).dial(anyString(), any(), any()); 1023 } catch (CallStateException e) { 1024 // This shouldn't happen 1025 fail(); 1026 } 1027 assertEquals(c.getState(), android.telecom.Connection.STATE_DISCONNECTED); 1028 assertEquals(c.getDisconnectCause().getCode(), DisconnectCause.ERROR); 1029 } 1030 1031 /** 1032 * The modem has returned a temporary failure when placing an emergency call on a phone with two 1033 * SIM slots. 1034 * 1035 * Verify that the emergency call is dialed on the other slot and telecom is notified of the new 1036 * PhoneAccount. 1037 */ 1038 @Test 1039 @SmallTest testRetryOutgoingOriginalConnection_redialTempFailTwoSlot()1040 public void testRetryOutgoingOriginalConnection_redialTempFailTwoSlot() { 1041 TestTelephonyConnection c = new TestTelephonyConnection(); 1042 Phone slot0Phone = c.getPhone(); 1043 when(slot0Phone.getPhoneId()).thenReturn(SLOT_0_PHONE_ID); 1044 Phone slot1Phone = makeTestPhone(SLOT_1_PHONE_ID, ServiceState.STATE_OUT_OF_SERVICE, 1045 false /*isEmergencyOnly*/); 1046 setPhonesDialConnection(slot1Phone, c.getOriginalConnection()); 1047 c.setAddress(TEST_ADDRESS, TelecomManager.PRESENTATION_ALLOWED); 1048 List<Phone> phones = new ArrayList<>(2); 1049 phones.add(slot0Phone); 1050 phones.add(slot1Phone); 1051 setPhones(phones); 1052 doReturn(PHONE_ACCOUNT_HANDLE_1).when(mPhoneUtilsProxy).makePstnPhoneAccountHandle( 1053 slot0Phone); 1054 doReturn(PHONE_ACCOUNT_HANDLE_2).when(mPhoneUtilsProxy).makePstnPhoneAccountHandle( 1055 slot1Phone); 1056 1057 mTestConnectionService.retryOutgoingOriginalConnection(c, 1058 c.getPhone(), false /*isPermanentFailure*/); 1059 1060 // The cache should still contain all of the Phones, since it was a temporary failure. 1061 assertEquals(2, mTestConnectionService.mEmergencyRetryCache.second.size()); 1062 // We need to be notified in Telecom that the PhoneAccount has changed, because it was 1063 // redialed on another slot 1064 assertEquals(1, c.getNotifyPhoneAccountChangedCount()); 1065 try { 1066 verify(slot1Phone).dial(anyString(), any(), any()); 1067 } catch (CallStateException e) { 1068 // This shouldn't happen 1069 fail(); 1070 } 1071 } 1072 1073 /** 1074 * The modem has returned a temporary failure when placing an emergency call on a phone with two 1075 * SIM slots. 1076 * 1077 * Verify that the emergency call is dialed on the other slot and telecom is notified of the new 1078 * PhoneAccount. 1079 */ 1080 @Test 1081 @SmallTest testRetryOutgoingOriginalConnection_redialPermFailTwoSlot()1082 public void testRetryOutgoingOriginalConnection_redialPermFailTwoSlot() { 1083 TestTelephonyConnection c = new TestTelephonyConnection(); 1084 Phone slot0Phone = c.getPhone(); 1085 when(slot0Phone.getPhoneId()).thenReturn(SLOT_0_PHONE_ID); 1086 Phone slot1Phone = makeTestPhone(SLOT_1_PHONE_ID, ServiceState.STATE_OUT_OF_SERVICE, 1087 false /*isEmergencyOnly*/); 1088 setPhonesDialConnection(slot1Phone, c.getOriginalConnection()); 1089 c.setAddress(TEST_ADDRESS, TelecomManager.PRESENTATION_ALLOWED); 1090 List<Phone> phones = new ArrayList<>(2); 1091 phones.add(slot0Phone); 1092 phones.add(slot1Phone); 1093 setPhones(phones); 1094 doReturn(PHONE_ACCOUNT_HANDLE_1).when(mPhoneUtilsProxy).makePstnPhoneAccountHandle( 1095 slot0Phone); 1096 doReturn(PHONE_ACCOUNT_HANDLE_2).when(mPhoneUtilsProxy).makePstnPhoneAccountHandle( 1097 slot1Phone); 1098 1099 mTestConnectionService.retryOutgoingOriginalConnection(c, 1100 c.getPhone(), true /*isPermanentFailure*/); 1101 1102 // The cache should only contain the slot1Phone. 1103 assertEquals(1, mTestConnectionService.mEmergencyRetryCache.second.size()); 1104 // We need to be notified in Telecom that the PhoneAccount has changed, because it was 1105 // redialed on another slot 1106 assertEquals(1, c.getNotifyPhoneAccountChangedCount()); 1107 try { 1108 verify(slot1Phone).dial(anyString(), any(), any()); 1109 } catch (CallStateException e) { 1110 // This shouldn't happen 1111 fail(); 1112 } 1113 } 1114 1115 /** 1116 * The modem has returned a temporary failure twice while placing an emergency call on a phone 1117 * with two SIM slots. 1118 * 1119 * Verify that the emergency call is dialed on slot 1 and then on slot 0 and telecom is 1120 * notified of this twice. 1121 */ 1122 @Test 1123 @SmallTest testRetryOutgoingOriginalConnection_redialTempFailTwoSlot_twoFailure()1124 public void testRetryOutgoingOriginalConnection_redialTempFailTwoSlot_twoFailure() { 1125 TestTelephonyConnection c = new TestTelephonyConnection(); 1126 Phone slot0Phone = c.getPhone(); 1127 when(slot0Phone.getPhoneId()).thenReturn(SLOT_0_PHONE_ID); 1128 Phone slot1Phone = makeTestPhone(SLOT_1_PHONE_ID, ServiceState.STATE_OUT_OF_SERVICE, 1129 false /*isEmergencyOnly*/); 1130 setPhonesDialConnection(slot1Phone, c.getOriginalConnection()); 1131 c.setAddress(TEST_ADDRESS, TelecomManager.PRESENTATION_ALLOWED); 1132 List<Phone> phones = new ArrayList<>(2); 1133 phones.add(slot0Phone); 1134 phones.add(slot1Phone); 1135 setPhones(phones); 1136 doReturn(PHONE_ACCOUNT_HANDLE_1).when(mPhoneUtilsProxy).makePstnPhoneAccountHandle( 1137 slot0Phone); 1138 doReturn(PHONE_ACCOUNT_HANDLE_2).when(mPhoneUtilsProxy).makePstnPhoneAccountHandle( 1139 slot1Phone); 1140 1141 // First Temporary failure 1142 mTestConnectionService.retryOutgoingOriginalConnection(c, 1143 c.getPhone(), false /*isPermanentFailure*/); 1144 // Set the Phone to the new phone that was just used to dial. 1145 c.setMockPhone(slot1Phone); 1146 // The cache should still contain all of the Phones, since it was a temporary failure. 1147 assertEquals(2, mTestConnectionService.mEmergencyRetryCache.second.size()); 1148 // Make sure slot 1 is next in the queue. 1149 assertEquals(slot1Phone, mTestConnectionService.mEmergencyRetryCache.second.peek()); 1150 // Second Temporary failure 1151 mTestConnectionService.retryOutgoingOriginalConnection(c, 1152 c.getPhone(), false /*isPermanentFailure*/); 1153 // Set the Phone to the new phone that was just used to dial. 1154 c.setMockPhone(slot0Phone); 1155 // The cache should still contain all of the Phones, since it was a temporary failure. 1156 assertEquals(2, mTestConnectionService.mEmergencyRetryCache.second.size()); 1157 // Make sure slot 0 is next in the queue. 1158 assertEquals(slot0Phone, mTestConnectionService.mEmergencyRetryCache.second.peek()); 1159 1160 // We need to be notified in Telecom that the PhoneAccount has changed, because it was 1161 // redialed on another slot 1162 assertEquals(2, c.getNotifyPhoneAccountChangedCount()); 1163 try { 1164 verify(slot0Phone).dial(anyString(), any(), any()); 1165 verify(slot1Phone).dial(anyString(), any(), any()); 1166 } catch (CallStateException e) { 1167 // This shouldn't happen 1168 fail(); 1169 } 1170 } 1171 1172 /** 1173 * The modem has returned a permanent failure twice while placing an emergency call on a phone 1174 * with two SIM slots. 1175 * 1176 * Verify that the emergency call is dialed on slot 1 and then disconnected and telecom is 1177 * notified of the change to slot 1. 1178 */ 1179 @Test 1180 @SmallTest testRetryOutgoingOriginalConnection_redialPermFailTwoSlot_twoFailure()1181 public void testRetryOutgoingOriginalConnection_redialPermFailTwoSlot_twoFailure() { 1182 TestTelephonyConnection c = new TestTelephonyConnection(); 1183 Phone slot0Phone = c.getPhone(); 1184 when(slot0Phone.getPhoneId()).thenReturn(SLOT_0_PHONE_ID); 1185 Phone slot1Phone = makeTestPhone(SLOT_1_PHONE_ID, ServiceState.STATE_OUT_OF_SERVICE, 1186 false /*isEmergencyOnly*/); 1187 setPhonesDialConnection(slot1Phone, c.getOriginalConnection()); 1188 c.setAddress(TEST_ADDRESS, TelecomManager.PRESENTATION_ALLOWED); 1189 List<Phone> phones = new ArrayList<>(2); 1190 phones.add(slot0Phone); 1191 phones.add(slot1Phone); 1192 setPhones(phones); 1193 doReturn(PHONE_ACCOUNT_HANDLE_1).when(mPhoneUtilsProxy).makePstnPhoneAccountHandle( 1194 slot0Phone); 1195 doReturn(PHONE_ACCOUNT_HANDLE_2).when(mPhoneUtilsProxy).makePstnPhoneAccountHandle( 1196 slot1Phone); 1197 1198 // First Permanent failure 1199 mTestConnectionService.retryOutgoingOriginalConnection(c, 1200 c.getPhone(), true /*isPermanentFailure*/); 1201 // Set the Phone to the new phone that was just used to dial. 1202 c.setMockPhone(slot1Phone); 1203 // The cache should only contain one phone 1204 assertEquals(1, mTestConnectionService.mEmergencyRetryCache.second.size()); 1205 // Make sure slot 1 is next in the queue. 1206 assertEquals(slot1Phone, mTestConnectionService.mEmergencyRetryCache.second.peek()); 1207 // Second Permanent failure 1208 mTestConnectionService.retryOutgoingOriginalConnection(c, 1209 c.getPhone(), true /*isPermanentFailure*/); 1210 // The cache should be empty 1211 assertEquals(true, mTestConnectionService.mEmergencyRetryCache.second.isEmpty()); 1212 1213 assertEquals(c.getState(), android.telecom.Connection.STATE_DISCONNECTED); 1214 assertEquals(c.getDisconnectCause().getCode(), DisconnectCause.ERROR); 1215 // We need to be notified in Telecom that the PhoneAccount has changed, because it was 1216 // redialed on another slot 1217 assertEquals(1, c.getNotifyPhoneAccountChangedCount()); 1218 try { 1219 verify(slot1Phone).dial(anyString(), any(), any()); 1220 verify(slot0Phone, never()).dial(anyString(), any(), any()); 1221 } catch (CallStateException e) { 1222 // This shouldn't happen 1223 fail(); 1224 } 1225 } 1226 1227 @Test 1228 @SmallTest testSuppServiceNotification()1229 public void testSuppServiceNotification() { 1230 TestTelephonyConnection c = new TestTelephonyConnection(); 1231 1232 // We need to set the original connection to cause the supp service notification 1233 // registration to occur. 1234 Phone phone = c.getPhone(); 1235 c.setOriginalConnection(c.getOriginalConnection()); 1236 doReturn(mContext).when(phone).getContext(); 1237 1238 // When the registration occurs, we'll capture the handler and message so we can post our 1239 // own messages to it. 1240 ArgumentCaptor<Handler> handlerCaptor = ArgumentCaptor.forClass(Handler.class); 1241 ArgumentCaptor<Integer> messageCaptor = ArgumentCaptor.forClass(Integer.class); 1242 verify(phone).registerForSuppServiceNotification(handlerCaptor.capture(), 1243 messageCaptor.capture(), any()); 1244 Handler handler = handlerCaptor.getValue(); 1245 int message = messageCaptor.getValue(); 1246 1247 // With the handler and message now known, we'll post a supp service notification. 1248 AsyncResult result = getSuppServiceNotification( 1249 SuppServiceNotification.NOTIFICATION_TYPE_CODE_1, 1250 SuppServiceNotification.CODE_1_CALL_FORWARDED); 1251 handler.obtainMessage(message, result).sendToTarget(); 1252 waitForHandlerAction(handler, TIMEOUT_MS); 1253 1254 assertTrue(c.getLastConnectionEvents().contains(TelephonyManager.EVENT_CALL_FORWARDED)); 1255 1256 // With the handler and message now known, we'll post a supp service notification. 1257 result = getSuppServiceNotification( 1258 SuppServiceNotification.NOTIFICATION_TYPE_CODE_1, 1259 SuppServiceNotification.CODE_1_CALL_IS_WAITING); 1260 handler.obtainMessage(message, result).sendToTarget(); 1261 waitForHandlerAction(handler, TIMEOUT_MS); 1262 1263 // We we want the 3rd event since the forwarding one above sends 2. 1264 assertEquals(c.getLastConnectionEvents().get(2), 1265 TelephonyManager.EVENT_SUPPLEMENTARY_SERVICE_NOTIFICATION); 1266 Bundle extras = c.getLastConnectionEventExtras().get(2); 1267 assertEquals(SuppServiceNotification.NOTIFICATION_TYPE_CODE_1, 1268 extras.getInt(TelephonyManager.EXTRA_NOTIFICATION_TYPE)); 1269 assertEquals(SuppServiceNotification.CODE_1_CALL_IS_WAITING, 1270 extras.getInt(TelephonyManager.EXTRA_NOTIFICATION_CODE)); 1271 } 1272 1273 /** 1274 * Test that the TelephonyConnectionService successfully performs a DDS switch before a call 1275 * when we are not roaming and the carrier only supports SUPL over the data plane. 1276 */ 1277 @Test 1278 @SmallTest testCreateOutgoingEmergencyConnection_delayDial_carrierconfig_dds()1279 public void testCreateOutgoingEmergencyConnection_delayDial_carrierconfig_dds() { 1280 // Setup test to not support SUPL on the non-DDS subscription 1281 doReturn(true).when(mDeviceState).isSuplDdsSwitchRequiredForEmergencyCall(any()); 1282 getTestContext().getCarrierConfig(0 /*subId*/).putStringArray( 1283 CarrierConfigManager.Gps.KEY_ES_SUPL_DATA_PLANE_ONLY_ROAMING_PLMN_STRING_ARRAY, 1284 null); 1285 getTestContext().getCarrierConfig(0 /*subId*/).putInt( 1286 CarrierConfigManager.Gps.KEY_ES_SUPL_CONTROL_PLANE_SUPPORT_INT, 1287 CarrierConfigManager.Gps.SUPL_EMERGENCY_MODE_TYPE_DP_ONLY); 1288 getTestContext().getCarrierConfig(0 /*subId*/).putString( 1289 CarrierConfigManager.Gps.KEY_ES_EXTENSION_SEC_STRING, "150"); 1290 1291 Phone testPhone = setupConnectionServiceForDelayDial( 1292 false /* isRoaming */, false /* setOperatorName */, null /* operator long name*/, 1293 null /* operator short name */, null /* operator numeric name */); 1294 verify(mPhoneSwitcher).overrideDefaultDataForEmergency(eq(0) /*phoneId*/ , 1295 eq(150) /*extensionTime*/, any()); 1296 } 1297 1298 /** 1299 * Test that the TelephonyConnectionService successfully turns radio on before placing the 1300 * emergency call. 1301 */ 1302 @Test 1303 @SmallTest testCreateOutgoingEmerge_exitingApm_disconnected()1304 public void testCreateOutgoingEmerge_exitingApm_disconnected() { 1305 when(mDeviceState.isAirplaneModeOn(any())).thenReturn(true); 1306 Phone testPhone = setupConnectionServiceInApm(); 1307 1308 ArgumentCaptor<RadioOnStateListener.Callback> callback = 1309 ArgumentCaptor.forClass(RadioOnStateListener.Callback.class); 1310 verify(mRadioOnHelper).triggerRadioOnAndListen(callback.capture(), eq(true), 1311 eq(testPhone), eq(false), eq(0)); 1312 1313 assertFalse(callback.getValue() 1314 .isOkToCall(testPhone, ServiceState.STATE_OUT_OF_SERVICE, false)); 1315 when(mSST.isRadioOn()).thenReturn(true); 1316 assertTrue(callback.getValue() 1317 .isOkToCall(testPhone, ServiceState.STATE_OUT_OF_SERVICE, false)); 1318 1319 mConnection.setDisconnected(null); 1320 callback.getValue().onComplete(null, true); 1321 for (Phone phone : mPhoneFactoryProxy.getPhones()) { 1322 verify(phone).setRadioPower(true, false, false, true); 1323 } 1324 } 1325 1326 /** 1327 * Test that the TelephonyConnectionService successfully turns radio on before placing the 1328 * emergency call. 1329 */ 1330 @Test 1331 @SmallTest testCreateOutgoingEmergencyConnection_exitingApm_placeCall()1332 public void testCreateOutgoingEmergencyConnection_exitingApm_placeCall() { 1333 when(mDeviceState.isAirplaneModeOn(any())).thenReturn(true); 1334 Phone testPhone = setupConnectionServiceInApm(); 1335 1336 ArgumentCaptor<RadioOnStateListener.Callback> callback = 1337 ArgumentCaptor.forClass(RadioOnStateListener.Callback.class); 1338 verify(mRadioOnHelper).triggerRadioOnAndListen(callback.capture(), eq(true), 1339 eq(testPhone), eq(false), eq(0)); 1340 1341 assertFalse(callback.getValue() 1342 .isOkToCall(testPhone, ServiceState.STATE_OUT_OF_SERVICE, false)); 1343 when(mSST.isRadioOn()).thenReturn(true); 1344 assertTrue(callback.getValue() 1345 .isOkToCall(testPhone, ServiceState.STATE_OUT_OF_SERVICE, false)); 1346 1347 callback.getValue().onComplete(null, true); 1348 1349 try { 1350 doAnswer(invocation -> null).when(mContext).startActivityAsUser(any(), any()); 1351 verify(testPhone).dial(anyString(), any(), any()); 1352 } catch (CallStateException e) { 1353 // This shouldn't happen 1354 fail(); 1355 } 1356 verify(mSatelliteSOSMessageRecommender).onEmergencyCallStarted(any(), anyBoolean()); 1357 } 1358 1359 /** 1360 * Test that the TelephonyConnectionService successfully dials an outgoing normal routed 1361 * emergency call on an in-service sim. 1362 */ 1363 @Test 1364 @SmallTest testCreateOutgoingConnectionForNormalRoutedEmergencyCall()1365 public void testCreateOutgoingConnectionForNormalRoutedEmergencyCall() 1366 throws CallStateException { 1367 // A whole load of annoying mocks to set up to test this scenario. 1368 // We'll purposely try to start the call on the limited service phone. 1369 ConnectionRequest connectionRequest = new ConnectionRequest.Builder() 1370 .setAccountHandle(PHONE_ACCOUNT_HANDLE_1) 1371 .setAddress(Uri.fromParts(PhoneAccount.SCHEME_TEL, NORMAL_ROUTED_EMERGENCY_NUMBER, 1372 null)) 1373 .build(); 1374 1375 // First phone is in limited service. 1376 Phone testPhone0 = makeTestPhone(0 /*phoneId*/, ServiceState.STATE_EMERGENCY_ONLY, 1377 true /*isEmergencyOnly*/); 1378 doReturn(ImsRegistrationImplBase.REGISTRATION_TECH_LTE).when(testPhone0) 1379 .getImsRegistrationTech(); 1380 doReturn(0).when(testPhone0).getSubId(); 1381 setupMockEmergencyNumbers(testPhone0, List.of(MOCK_NORMAL_NUMBER, 1382 MOCK_NORMAL_NUMBER_WITH_UNKNOWN_ROUTING, MOCK_EMERGENCY_NUMBER)); 1383 1384 // Second phone is in full service; this is ultimately the one we want to pick. 1385 Phone testPhone1 = makeTestPhone(1 /*phoneId*/, ServiceState.STATE_IN_SERVICE, 1386 false /*isEmergencyOnly*/); 1387 doReturn(ImsRegistrationImplBase.REGISTRATION_TECH_LTE).when(testPhone1) 1388 .getImsRegistrationTech(); 1389 doReturn(1).when(testPhone1).getSubId(); 1390 setupMockEmergencyNumbers(testPhone1, List.of(MOCK_NORMAL_NUMBER, 1391 MOCK_NORMAL_NUMBER_WITH_UNKNOWN_ROUTING, MOCK_EMERGENCY_NUMBER)); 1392 1393 // Make sure both phones are going to prefer in service for normal routed ecalls. 1394 doReturn(true).when(testPhone0).shouldPreferInServiceSimForNormalRoutedEmergencyCall(); 1395 doReturn(true).when(testPhone1).shouldPreferInServiceSimForNormalRoutedEmergencyCall(); 1396 1397 // A whole load of other stuff that needs to be setup for this to work. 1398 doReturn(GSM_PHONE).when(testPhone0).getPhoneType(); 1399 doReturn(GSM_PHONE).when(testPhone1).getPhoneType(); 1400 List<Phone> phones = new ArrayList<>(2); 1401 doReturn(true).when(testPhone0).isRadioOn(); 1402 doReturn(true).when(testPhone1).isRadioOn(); 1403 phones.add(testPhone0); 1404 phones.add(testPhone1); 1405 setPhones(phones); 1406 doReturn(0).when(mPhoneUtilsProxy).getSubIdForPhoneAccountHandle( 1407 eq(PHONE_ACCOUNT_HANDLE_1)); 1408 doReturn(1).when(mPhoneUtilsProxy).getSubIdForPhoneAccountHandle( 1409 eq(PHONE_ACCOUNT_HANDLE_2)); 1410 setupHandleToPhoneMap(PHONE_ACCOUNT_HANDLE_1, testPhone0); 1411 setupHandleToPhoneMap(PHONE_ACCOUNT_HANDLE_2, testPhone1); 1412 setupDeviceConfig(testPhone0, testPhone1, 0); 1413 doReturn(true).when(mTelephonyManagerProxy).isCurrentEmergencyNumber( 1414 eq(NORMAL_ROUTED_EMERGENCY_NUMBER)); 1415 HashMap<Integer, List<EmergencyNumber>> emergencyNumbers = new HashMap<>(1); 1416 List<EmergencyNumber> numbers = new ArrayList<>(); 1417 numbers.add(MOCK_EMERGENCY_NUMBER); 1418 numbers.add(MOCK_NORMAL_NUMBER); 1419 numbers.add(MOCK_NORMAL_NUMBER_WITH_UNKNOWN_ROUTING); 1420 emergencyNumbers.put(0 /*subId*/, numbers); 1421 doReturn(emergencyNumbers).when(mTelephonyManagerProxy).getCurrentEmergencyNumberList(); 1422 doReturn(2).when(mTelephonyManagerProxy).getPhoneCount(); 1423 1424 // All of that for... this. 1425 mConnection = mTestConnectionService.onCreateOutgoingConnection( 1426 PHONE_ACCOUNT_HANDLE_1, connectionRequest); 1427 assertNotNull("test connection was not set up correctly.", mConnection); 1428 1429 // Lets make sure we DID try to place the call on phone 1, which is the in service phone. 1430 verify(testPhone1).dial(anyString(), any(DialArgs.class), any(Consumer.class)); 1431 // And make sure we DID NOT try to place the call on phone 0, which is in limited service. 1432 verify(testPhone0, never()).dial(anyString(), any(DialArgs.class), any(Consumer.class)); 1433 } 1434 1435 /** 1436 * Test that the TelephonyConnectionService successfully turns satellite off before placing the 1437 * emergency call. 1438 */ 1439 @Test 1440 @SmallTest testCreateOutgoingEmergencyConnection_exitingSatellite_placeCall()1441 public void testCreateOutgoingEmergencyConnection_exitingSatellite_placeCall() { 1442 when(mSatelliteController.isSatelliteEnabledOrBeingEnabled()).thenReturn(true); 1443 doReturn(true).when(mMockResources).getBoolean(anyInt()); 1444 doReturn(true).when(mTelephonyManagerProxy).isCurrentEmergencyNumber( 1445 anyString()); 1446 Phone testPhone = setupConnectionServiceInApm(); 1447 1448 ArgumentCaptor<RadioOnStateListener.Callback> callback = 1449 ArgumentCaptor.forClass(RadioOnStateListener.Callback.class); 1450 verify(mRadioOnHelper).triggerRadioOnAndListen(callback.capture(), eq(true), 1451 eq(testPhone), eq(false), eq(0)); 1452 1453 assertFalse(callback.getValue() 1454 .isOkToCall(testPhone, ServiceState.STATE_OUT_OF_SERVICE, false)); 1455 when(mSST.isRadioOn()).thenReturn(true); 1456 assertFalse(callback.getValue() 1457 .isOkToCall(testPhone, ServiceState.STATE_OUT_OF_SERVICE, false)); 1458 when(mSatelliteController.isSatelliteEnabledOrBeingEnabled()).thenReturn(false); 1459 assertTrue(callback.getValue() 1460 .isOkToCall(testPhone, ServiceState.STATE_OUT_OF_SERVICE, false)); 1461 1462 callback.getValue().onComplete(null, true); 1463 1464 try { 1465 doAnswer(invocation -> null).when(mContext).startActivityAsUser(any(), any()); 1466 verify(testPhone).dial(anyString(), any(), any()); 1467 } catch (CallStateException e) { 1468 // This shouldn't happen 1469 fail(); 1470 } 1471 verify(mSatelliteSOSMessageRecommender).onEmergencyCallStarted(any(), anyBoolean()); 1472 } 1473 1474 /** 1475 * Test that the TelephonyConnectionService successfully placing the emergency call based on 1476 * CarrierRoaming mode of Satellite. 1477 */ 1478 @Test 1479 @SmallTest testCreateOutgoingEmergencyConnection_exitingSatellite_EmergencySatellite()1480 public void testCreateOutgoingEmergencyConnection_exitingSatellite_EmergencySatellite() 1481 throws Exception { 1482 doReturn(true).when(mFeatureFlags).carrierRoamingNbIotNtn(); 1483 doReturn(true).when(mSatelliteController).isSatelliteEnabledOrBeingEnabled(); 1484 1485 // Set config_turn_off_non_emergency_nb_iot_ntn_satellite_for_emergency_call as true 1486 doReturn(true).when(mMockResources).getBoolean(anyInt()); 1487 doReturn(true).when(mTelephonyManagerProxy).isCurrentEmergencyNumber(anyString()); 1488 doReturn(false).when(mSatelliteController).isDemoModeEnabled(); 1489 1490 // Satellite is not for emergency, allow EMC 1491 doReturn(false).when(mSatelliteController).getRequestIsEmergency(); 1492 // Setup outgoing emergency call 1493 setupConnectionServiceInApm(); 1494 1495 // Verify emergency call go through 1496 assertNull(mConnection.getDisconnectCause()); 1497 } 1498 1499 @Test 1500 @SmallTest testCreateOutgoingEmergencyConnection_exitingSatellite_OEM()1501 public void testCreateOutgoingEmergencyConnection_exitingSatellite_OEM() throws Exception { 1502 doReturn(true).when(mFeatureFlags).carrierRoamingNbIotNtn(); 1503 doReturn(true).when(mSatelliteController).isSatelliteEnabledOrBeingEnabled(); 1504 1505 // Set config_turn_off_oem_enabled_satellite_during_emergency_call as false 1506 doReturn(false).when(mMockResources).getBoolean(anyInt()); 1507 doReturn(true).when(mTelephonyManagerProxy).isCurrentEmergencyNumber(anyString()); 1508 doReturn(false).when(mSatelliteController).isDemoModeEnabled(); 1509 1510 // Satellite is for emergency 1511 doReturn(true).when(mSatelliteController).getRequestIsEmergency(); 1512 doReturn(1).when(mSatelliteController).getSelectedSatelliteSubId(); 1513 SubscriptionManagerService isub = mock(SubscriptionManagerService.class); 1514 replaceInstance(SubscriptionManagerService.class, "sInstance", null, isub); 1515 SubscriptionInfoInternal info = mock(SubscriptionInfoInternal.class); 1516 doReturn(info).when(isub).getSubscriptionInfoInternal(1); 1517 1518 // Setup outgoing emergency call 1519 setupConnectionServiceInApm(); 1520 1521 // Verify DisconnectCause which not allows emergency call 1522 assertNotNull(mConnection.getDisconnectCause()); 1523 assertEquals(android.telephony.DisconnectCause.SATELLITE_ENABLED, 1524 mConnection.getDisconnectCause().getTelephonyDisconnectCause()); 1525 1526 // OEM: config_turn_off_oem_enabled_satellite_during_emergency_call = true 1527 doReturn(1).when(info).getOnlyNonTerrestrialNetwork(); 1528 doReturn(true).when(mMockResources).getBoolean(anyInt()); 1529 // Setup outgoing emergency call 1530 setupConnectionServiceInApm(); 1531 1532 // Verify emergency call go through 1533 assertNull(mConnection.getDisconnectCause()); 1534 } 1535 1536 @Test 1537 @SmallTest testCreateOutgoingEmergencyConnection_exitingSatellite_Carrier()1538 public void testCreateOutgoingEmergencyConnection_exitingSatellite_Carrier() throws Exception { 1539 doReturn(true).when(mFeatureFlags).carrierRoamingNbIotNtn(); 1540 doReturn(true).when(mSatelliteController).isSatelliteEnabledOrBeingEnabled(); 1541 1542 // Set config_turn_off_oem_enabled_satellite_during_emergency_call as false 1543 doReturn(false).when(mMockResources).getBoolean(anyInt()); 1544 doReturn(true).when(mTelephonyManagerProxy).isCurrentEmergencyNumber(anyString()); 1545 doReturn(false).when(mSatelliteController).isDemoModeEnabled(); 1546 1547 // Satellite is for emergency 1548 doReturn(true).when(mSatelliteController).getRequestIsEmergency(); 1549 doReturn(1).when(mSatelliteController).getSelectedSatelliteSubId(); 1550 SubscriptionManagerService isub = mock(SubscriptionManagerService.class); 1551 replaceInstance(SubscriptionManagerService.class, "sInstance", null, isub); 1552 SubscriptionInfoInternal info = mock(SubscriptionInfoInternal.class); 1553 doReturn(info).when(isub).getSubscriptionInfoInternal(1); 1554 1555 // Carrier: shouldTurnOffCarrierSatelliteForEmergencyCall = false 1556 doReturn(0).when(info).getOnlyNonTerrestrialNetwork(); 1557 doReturn(false).when(mSatelliteController).shouldTurnOffCarrierSatelliteForEmergencyCall(); 1558 setupConnectionServiceInApm(); 1559 1560 // Verify DisconnectCause which not allows emergency call 1561 assertNotNull(mConnection.getDisconnectCause()); 1562 assertEquals(android.telephony.DisconnectCause.SATELLITE_ENABLED, 1563 mConnection.getDisconnectCause().getTelephonyDisconnectCause()); 1564 1565 // Carrier: shouldTurnOffCarrierSatelliteForEmergencyCall = true 1566 doReturn(true).when(mMockResources).getBoolean(anyInt()); 1567 doReturn(true).when(mSatelliteController).shouldTurnOffCarrierSatelliteForEmergencyCall(); 1568 setupConnectionServiceInApm(); 1569 1570 // Verify emergency call go through 1571 assertNull(mConnection.getDisconnectCause()); 1572 } 1573 1574 @Test 1575 @SmallTest testCreateOutgoingEmergencyConnection_NonEmergencySatelliteSession()1576 public void testCreateOutgoingEmergencyConnection_NonEmergencySatelliteSession() { 1577 doReturn(true).when(mFeatureFlags).carrierRoamingNbIotNtn(); 1578 doReturn(true).when(mSatelliteController).isSatelliteEnabledOrBeingEnabled(); 1579 1580 // Set config_turn_off_non_emergency_nb_iot_ntn_satellite_for_emergency_call as false 1581 doReturn(false).when(mMockResources).getBoolean(anyInt()); 1582 doReturn(true).when(mTelephonyManagerProxy).isCurrentEmergencyNumber(anyString()); 1583 doReturn(false).when(mSatelliteController).isDemoModeEnabled(); 1584 1585 // Satellite is for emergency 1586 doReturn(false).when(mSatelliteController).getRequestIsEmergency(); 1587 1588 setupConnectionServiceInApm(); 1589 1590 // Verify DisconnectCause which not allows emergency call 1591 assertNotNull(mConnection.getDisconnectCause()); 1592 assertEquals(android.telephony.DisconnectCause.SATELLITE_ENABLED, 1593 mConnection.getDisconnectCause().getTelephonyDisconnectCause()); 1594 } 1595 1596 /** 1597 * Test that the TelephonyConnectionService successfully turns radio on before placing the 1598 * call when radio off because bluetooth on and wifi calling is not enabled 1599 */ 1600 @Test 1601 @SmallTest testCreateOutgoingCall_turnOnRadio_bluetoothOn()1602 public void testCreateOutgoingCall_turnOnRadio_bluetoothOn() { 1603 doReturn(true).when(mDeviceState).isRadioPowerDownAllowedOnBluetooth(any()); 1604 doReturn(PhoneConstants.CELL_ON_FLAG).when(mDeviceState).getCellOnStatus(any()); 1605 Phone testPhone0 = makeTestPhone(0 /*phoneId*/, ServiceState.STATE_POWER_OFF, 1606 false /*isEmergencyOnly*/); 1607 Phone testPhone1 = makeTestPhone(1 /*phoneId*/, ServiceState.STATE_POWER_OFF, 1608 false /*isEmergencyOnly*/); 1609 doReturn(false).when(testPhone0).isRadioOn(); 1610 doReturn(false).when(testPhone0).isWifiCallingEnabled(); 1611 doReturn(false).when(testPhone1).isRadioOn(); 1612 doReturn(false).when(testPhone1).isWifiCallingEnabled(); 1613 List<Phone> phones = new ArrayList<>(2); 1614 phones.add(testPhone0); 1615 phones.add(testPhone1); 1616 setPhones(phones); 1617 setupHandleToPhoneMap(PHONE_ACCOUNT_HANDLE_1, testPhone0); 1618 ConnectionRequest connectionRequest = new ConnectionRequest.Builder() 1619 .setAccountHandle(PHONE_ACCOUNT_HANDLE_1) 1620 .setAddress(TEST_ADDRESS) 1621 .build(); 1622 mConnection = mTestConnectionService.onCreateOutgoingConnection( 1623 PHONE_ACCOUNT_HANDLE_1, connectionRequest); 1624 1625 verify(mRadioOnHelper).triggerRadioOnAndListen(any(), eq(false), 1626 eq(testPhone0), eq(false), eq(0)); 1627 } 1628 1629 /** 1630 * Test that the TelephonyConnectionService successfully turns radio on before placing the 1631 * call when phone is null, radio off because bluetooth on and wifi calling is not enabled 1632 */ 1633 @Test 1634 @SmallTest testCreateOutgoingCall_forWearWatch_whenPhoneIsNull()1635 public void testCreateOutgoingCall_forWearWatch_whenPhoneIsNull() { 1636 doReturn(-1).when(mPhoneUtilsProxy).getSubIdForPhoneAccountHandle(any()); 1637 doReturn(true).when(mDeviceState).isRadioPowerDownAllowedOnBluetooth(any()); 1638 doReturn(PhoneConstants.CELL_ON_FLAG).when(mDeviceState).getCellOnStatus(any()); 1639 Phone testPhone0 = makeTestPhone(0 /*phoneId*/, ServiceState.STATE_POWER_OFF, 1640 false /*isEmergencyOnly*/); 1641 Phone testPhone1 = makeTestPhone(1 /*phoneId*/, ServiceState.STATE_POWER_OFF, 1642 false /*isEmergencyOnly*/); 1643 doReturn(false).when(testPhone0).isRadioOn(); 1644 doReturn(false).when(testPhone0).isWifiCallingEnabled(); 1645 doReturn(false).when(testPhone1).isRadioOn(); 1646 doReturn(false).when(testPhone1).isWifiCallingEnabled(); 1647 List<Phone> phones = new ArrayList<>(2); 1648 phones.add(testPhone0); 1649 phones.add(testPhone1); 1650 setPhones(phones); 1651 setupHandleToPhoneMap(PHONE_ACCOUNT_HANDLE_1, testPhone0); 1652 ConnectionRequest connectionRequest = new ConnectionRequest.Builder() 1653 .setAccountHandle(PHONE_ACCOUNT_HANDLE_1) 1654 .setAddress(TEST_ADDRESS) 1655 .build(); 1656 mConnection = mTestConnectionService.onCreateOutgoingConnection( 1657 PHONE_ACCOUNT_HANDLE_1, connectionRequest); 1658 1659 verify(mRadioOnHelper).triggerRadioOnAndListen(any(), eq(false), 1660 eq(testPhone0), eq(false), eq(0)); 1661 } 1662 1663 /** 1664 * Test that the TelephonyConnectionService will not turns radio on before placing the 1665 * call when radio off because bluetooth on and wifi calling is enabled 1666 */ 1667 @Test 1668 @SmallTest testCreateOutgoingCall_notTurnOnRadio_bluetoothOnWifiCallingEnabled()1669 public void testCreateOutgoingCall_notTurnOnRadio_bluetoothOnWifiCallingEnabled() { 1670 doReturn(true).when(mDeviceState).isRadioPowerDownAllowedOnBluetooth(any()); 1671 doReturn(PhoneConstants.CELL_ON_FLAG).when(mDeviceState).getCellOnStatus(any()); 1672 Phone testPhone0 = makeTestPhone(0 /*phoneId*/, ServiceState.STATE_POWER_OFF, 1673 false /*isEmergencyOnly*/); 1674 Phone testPhone1 = makeTestPhone(1 /*phoneId*/, ServiceState.STATE_POWER_OFF, 1675 false /*isEmergencyOnly*/); 1676 doReturn(false).when(testPhone0).isRadioOn(); 1677 doReturn(true).when(testPhone0).isWifiCallingEnabled(); 1678 doReturn(false).when(testPhone1).isRadioOn(); 1679 doReturn(true).when(testPhone1).isWifiCallingEnabled(); 1680 List<Phone> phones = new ArrayList<>(2); 1681 phones.add(testPhone0); 1682 phones.add(testPhone1); 1683 setPhones(phones); 1684 setupHandleToPhoneMap(PHONE_ACCOUNT_HANDLE_1, testPhone0); 1685 ConnectionRequest connectionRequest = new ConnectionRequest.Builder() 1686 .setAccountHandle(PHONE_ACCOUNT_HANDLE_1) 1687 .setAddress(TEST_ADDRESS) 1688 .build(); 1689 mConnection = mTestConnectionService.onCreateOutgoingConnection( 1690 PHONE_ACCOUNT_HANDLE_1, connectionRequest); 1691 1692 verify(mRadioOnHelper, times(0)).triggerRadioOnAndListen(any(), 1693 eq(true), eq(testPhone0), eq(false), eq(0)); 1694 } 1695 1696 /** 1697 * Test that the TelephonyConnectionService does not perform a DDS switch when the carrier 1698 * supports control-plane fallback. 1699 */ 1700 @Test 1701 @SmallTest testCreateOutgoingEmergencyConnection_delayDial_nocarrierconfig()1702 public void testCreateOutgoingEmergencyConnection_delayDial_nocarrierconfig() { 1703 // Setup test to not support SUPL on the non-DDS subscription 1704 doReturn(true).when(mDeviceState).isSuplDdsSwitchRequiredForEmergencyCall(any()); 1705 getTestContext().getCarrierConfig(0 /*subId*/).putStringArray( 1706 CarrierConfigManager.Gps.KEY_ES_SUPL_DATA_PLANE_ONLY_ROAMING_PLMN_STRING_ARRAY, 1707 null); 1708 getTestContext().getCarrierConfig(0 /*subId*/).putInt( 1709 CarrierConfigManager.Gps.KEY_ES_SUPL_CONTROL_PLANE_SUPPORT_INT, 1710 CarrierConfigManager.Gps.SUPL_EMERGENCY_MODE_TYPE_CP_FALLBACK); 1711 getTestContext().getCarrierConfig(0 /*subId*/).putString( 1712 CarrierConfigManager.Gps.KEY_ES_EXTENSION_SEC_STRING, "0"); 1713 1714 Phone testPhone = setupConnectionServiceForDelayDial( 1715 false /* isRoaming */, false /* setOperatorName */, null /* operator long name*/, 1716 null /* operator short name */, null /* operator numeric name */); 1717 verify(mPhoneSwitcher, never()).overrideDefaultDataForEmergency(anyInt(), anyInt(), any()); 1718 } 1719 1720 /** 1721 * Test that the TelephonyConnectionService does not perform a DDS switch when the carrier 1722 * supports control-plane fallback. 1723 */ 1724 @Test 1725 @SmallTest testCreateOutgoingEmergencyConnection_delayDial_supportsuplondds()1726 public void testCreateOutgoingEmergencyConnection_delayDial_supportsuplondds() { 1727 // If the non-DDS supports SUPL, don't switch data 1728 doReturn(false).when(mDeviceState).isSuplDdsSwitchRequiredForEmergencyCall(any()); 1729 getTestContext().getCarrierConfig(0 /*subId*/).putStringArray( 1730 CarrierConfigManager.Gps.KEY_ES_SUPL_DATA_PLANE_ONLY_ROAMING_PLMN_STRING_ARRAY, 1731 null); 1732 getTestContext().getCarrierConfig(0 /*subId*/).putInt( 1733 CarrierConfigManager.Gps.KEY_ES_SUPL_CONTROL_PLANE_SUPPORT_INT, 1734 CarrierConfigManager.Gps.SUPL_EMERGENCY_MODE_TYPE_DP_ONLY); 1735 getTestContext().getCarrierConfig(0 /*subId*/).putString( 1736 CarrierConfigManager.Gps.KEY_ES_EXTENSION_SEC_STRING, "0"); 1737 1738 Phone testPhone = setupConnectionServiceForDelayDial( 1739 false /* isRoaming */, false /* setOperatorName */, null /* operator long name*/, 1740 null /* operator short name */, null /* operator numeric name */); 1741 verify(mPhoneSwitcher, never()).overrideDefaultDataForEmergency(anyInt(), anyInt(), any()); 1742 } 1743 1744 /** 1745 * Test that the TelephonyConnectionService does not perform a DDS switch when the carrier does 1746 * not support control-plane fallback CarrierConfig while roaming. 1747 */ 1748 @Test 1749 @SmallTest testCreateOutgoingEmergencyConnection_delayDial_roaming_nocarrierconfig()1750 public void testCreateOutgoingEmergencyConnection_delayDial_roaming_nocarrierconfig() { 1751 // Setup test to not support SUPL on the non-DDS subscription 1752 doReturn(true).when(mDeviceState).isSuplDdsSwitchRequiredForEmergencyCall(any()); 1753 getTestContext().getCarrierConfig(0 /*subId*/).putStringArray( 1754 CarrierConfigManager.Gps.KEY_ES_SUPL_DATA_PLANE_ONLY_ROAMING_PLMN_STRING_ARRAY, 1755 null); 1756 getTestContext().getCarrierConfig(0 /*subId*/).putInt( 1757 CarrierConfigManager.Gps.KEY_ES_SUPL_CONTROL_PLANE_SUPPORT_INT, 1758 CarrierConfigManager.Gps.SUPL_EMERGENCY_MODE_TYPE_DP_ONLY); 1759 getTestContext().getCarrierConfig(0 /*subId*/).putString( 1760 CarrierConfigManager.Gps.KEY_ES_EXTENSION_SEC_STRING, "0"); 1761 1762 Phone testPhone = setupConnectionServiceForDelayDial( 1763 true /* isRoaming */, false /* setOperatorName */, null /* operator long name*/, 1764 null /* operator short name */, null /* operator numeric name */); 1765 verify(mPhoneSwitcher, never()).overrideDefaultDataForEmergency(anyInt(), anyInt(), any()); 1766 } 1767 1768 /** 1769 * Test that the TelephonyConnectionService does perform a DDS switch even though the carrier 1770 * supports control-plane fallback CarrierConfig and the roaming partner is configured to look 1771 * like a home network. 1772 */ 1773 @Test 1774 @SmallTest testCreateOutgoingEmergencyConnection_delayDial_roamingcarrierconfig()1775 public void testCreateOutgoingEmergencyConnection_delayDial_roamingcarrierconfig() { 1776 doReturn(true).when(mDeviceState).isSuplDdsSwitchRequiredForEmergencyCall(any()); 1777 // Setup voice roaming scenario 1778 String testRoamingOperator = "001001"; 1779 // Setup test to not support SUPL on the non-DDS subscription 1780 String[] roamingPlmns = new String[1]; 1781 roamingPlmns[0] = testRoamingOperator; 1782 getTestContext().getCarrierConfig(0 /*subId*/).putStringArray( 1783 CarrierConfigManager.Gps.KEY_ES_SUPL_DATA_PLANE_ONLY_ROAMING_PLMN_STRING_ARRAY, 1784 roamingPlmns); 1785 getTestContext().getCarrierConfig(0 /*subId*/).putInt( 1786 CarrierConfigManager.Gps.KEY_ES_SUPL_CONTROL_PLANE_SUPPORT_INT, 1787 CarrierConfigManager.Gps.SUPL_EMERGENCY_MODE_TYPE_CP_FALLBACK); 1788 getTestContext().getCarrierConfig(0 /*subId*/).putString( 1789 CarrierConfigManager.Gps.KEY_ES_EXTENSION_SEC_STRING, "0"); 1790 1791 Phone testPhone = setupConnectionServiceForDelayDial( 1792 false /* isRoaming */, true /* setOperatorName */, 1793 "TestTel" /* operator long name*/, "TestTel" /* operator short name */, 1794 testRoamingOperator /* operator numeric name */); 1795 verify(mPhoneSwitcher).overrideDefaultDataForEmergency(eq(0) /*phoneId*/ , 1796 eq(0) /*extensionTime*/, any()); 1797 } 1798 1799 /** 1800 * Test that the TelephonyConnectionService does perform a DDS switch even though the carrier 1801 * supports control-plane fallback CarrierConfig if we are roaming and the roaming partner is 1802 * configured to use data plane only SUPL. 1803 */ 1804 @Test 1805 @SmallTest testCreateOutgoingEmergencyConnection_delayDial__roaming_roamingcarrierconfig()1806 public void testCreateOutgoingEmergencyConnection_delayDial__roaming_roamingcarrierconfig() { 1807 // Setup test to not support SUPL on the non-DDS subscription 1808 doReturn(true).when(mDeviceState).isSuplDdsSwitchRequiredForEmergencyCall(any()); 1809 // Setup voice roaming scenario 1810 String testRoamingOperator = "001001"; 1811 String[] roamingPlmns = new String[1]; 1812 roamingPlmns[0] = testRoamingOperator; 1813 getTestContext().getCarrierConfig(0 /*subId*/).putStringArray( 1814 CarrierConfigManager.Gps.KEY_ES_SUPL_DATA_PLANE_ONLY_ROAMING_PLMN_STRING_ARRAY, 1815 roamingPlmns); 1816 getTestContext().getCarrierConfig(0 /*subId*/).putInt( 1817 CarrierConfigManager.Gps.KEY_ES_SUPL_CONTROL_PLANE_SUPPORT_INT, 1818 CarrierConfigManager.Gps.SUPL_EMERGENCY_MODE_TYPE_CP_FALLBACK); 1819 getTestContext().getCarrierConfig(0 /*subId*/).putString( 1820 CarrierConfigManager.Gps.KEY_ES_EXTENSION_SEC_STRING, "0"); 1821 1822 Phone testPhone = setupConnectionServiceForDelayDial( 1823 false /* isRoaming */, true /* setOperatorName */, 1824 "TestTel" /* operator long name*/, "TestTel" /* operator short name */, 1825 testRoamingOperator /* operator numeric name */); 1826 verify(mPhoneSwitcher).overrideDefaultDataForEmergency(eq(0) /*phoneId*/ , 1827 eq(0) /*extensionTime*/, any()); 1828 } 1829 1830 /** 1831 * Verifies for an incoming call on the same SIM that we don't set 1832 * {@link android.telecom.Connection#EXTRA_ANSWERING_DROPS_FG_CALL} on the incoming call extras. 1833 * @throws Exception 1834 */ 1835 @Test 1836 @SmallTest testIncomingDoesntRequestDisconnect()1837 public void testIncomingDoesntRequestDisconnect() throws Exception { 1838 setupForCallTest(); 1839 1840 mBinderStub.createConnection(PHONE_ACCOUNT_HANDLE_1, "TC@1", 1841 new ConnectionRequest(PHONE_ACCOUNT_HANDLE_1, Uri.parse("tel:16505551212"), 1842 new Bundle()), 1843 true, false, null); 1844 waitForHandlerAction(mTestConnectionService.getHandler(), TIMEOUT_MS); 1845 assertEquals(1, mTestConnectionService.getAllConnections().size()); 1846 1847 // Make sure the extras do not indicate that it answering will disconnect another call. 1848 android.telecom.Connection connection = (android.telecom.Connection) 1849 mTestConnectionService.getAllConnections().toArray()[0]; 1850 assertFalse(connection.getExtras() != null && connection.getExtras().containsKey( 1851 android.telecom.Connection.EXTRA_ANSWERING_DROPS_FG_CALL)); 1852 } 1853 1854 /** 1855 * Verifies where there is another call on the same sub, we don't set 1856 * {@link android.telecom.Connection#EXTRA_ANSWERING_DROPS_FG_CALL} on the incoming call extras. 1857 * @throws Exception 1858 */ 1859 @Test 1860 @SmallTest testSecondCallSameSubWontDisconnect()1861 public void testSecondCallSameSubWontDisconnect() throws Exception { 1862 // Previous test gets us into a good enough state 1863 testIncomingDoesntRequestDisconnect(); 1864 1865 when(mCall.getState()).thenReturn(Call.State.ACTIVE); 1866 when(mCall2.getState()).thenReturn(Call.State.WAITING); 1867 when(mCall2.getLatestConnection()).thenReturn(mInternalConnection2); 1868 when(mPhone0.getRingingCall()).thenReturn(mCall2); 1869 1870 mBinderStub.createConnection(PHONE_ACCOUNT_HANDLE_1, "TC@2", 1871 new ConnectionRequest(PHONE_ACCOUNT_HANDLE_1, Uri.parse("tel:16505551213"), 1872 new Bundle()), 1873 true, false, null); 1874 waitForHandlerAction(mTestConnectionService.getHandler(), TIMEOUT_MS); 1875 assertEquals(2, mTestConnectionService.getAllConnections().size()); 1876 1877 // None of the connections should have the extra set. 1878 assertEquals(0, mTestConnectionService.getAllConnections().stream() 1879 .filter(c -> c.getExtras() != null && c.getExtras().containsKey( 1880 android.telecom.Connection.EXTRA_ANSWERING_DROPS_FG_CALL)) 1881 .count()); 1882 } 1883 1884 /** 1885 * Verifies where there is another call on a different sub, we set 1886 * {@link android.telecom.Connection#EXTRA_ANSWERING_DROPS_FG_CALL} on the incoming call extras. 1887 * @throws Exception 1888 */ 1889 @Test 1890 @SmallTest testSecondCallDifferentSubWillDisconnect()1891 public void testSecondCallDifferentSubWillDisconnect() throws Exception { 1892 // Previous test gets us into a good enough state 1893 testIncomingDoesntRequestDisconnect(); 1894 1895 when(mCall.getState()).thenReturn(Call.State.ACTIVE); 1896 when(mCall2.getState()).thenReturn(Call.State.WAITING); 1897 when(mCall2.getLatestConnection()).thenReturn(mInternalConnection2); 1898 // At this point the call is ringing on the second phone. 1899 when(mPhone0.getRingingCall()).thenReturn(null); 1900 when(mPhone1.getRingingCall()).thenReturn(mCall2); 1901 1902 mBinderStub.createConnection(PHONE_ACCOUNT_HANDLE_2, "TC@2", 1903 new ConnectionRequest(PHONE_ACCOUNT_HANDLE_2, Uri.parse("tel:16505551213"), 1904 new Bundle()), 1905 true, false, null); 1906 waitForHandlerAction(mTestConnectionService.getHandler(), TIMEOUT_MS); 1907 assertEquals(2, mTestConnectionService.getAllConnections().size()); 1908 1909 // The incoming connection should have the extra set. 1910 assertEquals(1, mTestConnectionService.getAllConnections().stream() 1911 .filter(c -> c.getExtras() != null && c.getExtras().containsKey( 1912 android.telecom.Connection.EXTRA_ANSWERING_DROPS_FG_CALL)) 1913 .count()); 1914 } 1915 1916 /** 1917 * For virtual DSDA-enabled devices, verifies where there is another call on the same sub, we 1918 * don't set {@link android.telecom.Connection#EXTRA_ANSWERING_DROPS_FG_CALL} on the incoming 1919 * call extras. 1920 * @throws Exception 1921 */ 1922 @Test 1923 @SmallTest testSecondCallDifferentSubWontDisconnectForDsdaDevice()1924 public void testSecondCallDifferentSubWontDisconnectForDsdaDevice() throws Exception { 1925 // Re-uses existing test for setup, then configures device as virtual DSDA for test duration 1926 testIncomingDoesntRequestDisconnect(); 1927 when(mTelephonyManagerProxy.isConcurrentCallsPossible()).thenReturn(true); 1928 1929 when(mCall.getState()).thenReturn(Call.State.ACTIVE); 1930 when(mCall2.getState()).thenReturn(Call.State.WAITING); 1931 when(mCall2.getLatestConnection()).thenReturn(mInternalConnection2); 1932 // At this point the call is ringing on the second phone. 1933 when(mPhone0.getRingingCall()).thenReturn(null); 1934 when(mPhone1.getRingingCall()).thenReturn(mCall2); 1935 1936 mBinderStub.createConnection(PHONE_ACCOUNT_HANDLE_2, "TC@2", 1937 new ConnectionRequest(PHONE_ACCOUNT_HANDLE_2, Uri.parse("tel:16505551213"), 1938 new Bundle()), 1939 true, false, null); 1940 waitForHandlerAction(mTestConnectionService.getHandler(), TIMEOUT_MS); 1941 assertEquals(2, mTestConnectionService.getAllConnections().size()); 1942 1943 // None of the connections should have the extra set. 1944 assertEquals(0, mTestConnectionService.getAllConnections().stream() 1945 .filter(c -> c.getExtras() != null && c.getExtras().containsKey( 1946 android.telecom.Connection.EXTRA_ANSWERING_DROPS_FG_CALL)) 1947 .count()); 1948 } 1949 1950 private static final PhoneAccountHandle SUB1_HANDLE = new PhoneAccountHandle( 1951 new ComponentName("test", "class"), "1"); 1952 private static final PhoneAccountHandle SUB2_HANDLE = new PhoneAccountHandle( 1953 new ComponentName("test", "class"), "2"); 1954 1955 @Test 1956 @SmallTest testDontDisconnectSameSub()1957 public void testDontDisconnectSameSub() { 1958 ArrayList<android.telecom.Connection> tcs = new ArrayList<>(); 1959 SimpleTelephonyConnection tc1 = createTestConnection(SUB1_HANDLE, 0, false); 1960 tcs.add(tc1); 1961 TelephonyConnectionService.maybeDisconnectCallsOnOtherSubs( 1962 tcs, SUB1_HANDLE, false, mTelephonyManagerProxy); 1963 // Would've preferred to use mockito, but can't mock out TelephonyConnection/Connection 1964 // easily. 1965 assertFalse(tc1.wasDisconnected); 1966 } 1967 1968 @Test 1969 @SmallTest testDontDisconnectEmergency()1970 public void testDontDisconnectEmergency() { 1971 ArrayList<android.telecom.Connection> tcs = new ArrayList<>(); 1972 SimpleTelephonyConnection tc1 = createTestConnection(SUB1_HANDLE, 0, true); 1973 tcs.add(tc1); 1974 TelephonyConnectionService.maybeDisconnectCallsOnOtherSubs( 1975 tcs, SUB2_HANDLE, false, mTelephonyManagerProxy); 1976 // Other call is an emergency call, so don't disconnect it. 1977 assertFalse(tc1.wasDisconnected); 1978 } 1979 1980 @Test 1981 @SmallTest testDontDisconnectExternal()1982 public void testDontDisconnectExternal() { 1983 ArrayList<android.telecom.Connection> tcs = new ArrayList<>(); 1984 SimpleTelephonyConnection tc1 = createTestConnection(SUB1_HANDLE, 1985 android.telecom.Connection.PROPERTY_IS_EXTERNAL_CALL, false); 1986 tcs.add(tc1); 1987 TelephonyConnectionService.maybeDisconnectCallsOnOtherSubs( 1988 tcs, SUB2_HANDLE, false, mTelephonyManagerProxy); 1989 // Other call is an external call, so don't disconnect it. 1990 assertFalse(tc1.wasDisconnected); 1991 } 1992 1993 @Test 1994 @SmallTest testDisconnectDifferentSub()1995 public void testDisconnectDifferentSub() { 1996 ArrayList<android.telecom.Connection> tcs = new ArrayList<>(); 1997 SimpleTelephonyConnection tc1 = createTestConnection(SUB1_HANDLE, 0, false); 1998 tcs.add(tc1); 1999 TelephonyConnectionService.maybeDisconnectCallsOnOtherSubs( 2000 tcs, SUB2_HANDLE, false, mTelephonyManagerProxy); 2001 assertTrue(tc1.wasDisconnected); 2002 } 2003 2004 @Test 2005 @SmallTest testDisconnectDifferentSubTwoCalls()2006 public void testDisconnectDifferentSubTwoCalls() { 2007 ArrayList<android.telecom.Connection> tcs = new ArrayList<>(); 2008 SimpleTelephonyConnection tc1 = createTestConnection(SUB1_HANDLE, 0, false); 2009 SimpleTelephonyConnection tc2 = createTestConnection(SUB1_HANDLE, 0, false); 2010 2011 tcs.add(tc1); 2012 tcs.add(tc2); 2013 TelephonyConnectionService.maybeDisconnectCallsOnOtherSubs( 2014 tcs, SUB2_HANDLE, false, mTelephonyManagerProxy); 2015 assertTrue(tc1.wasDisconnected); 2016 assertTrue(tc2.wasDisconnected); 2017 } 2018 2019 /** 2020 * Verifies that DSDA or virtual DSDA-enabled devices can support active non-emergency calls on 2021 * separate subs, when the extra EXTRA_ANSWERING_DROPS_FG_CALL is not set on the incoming call. 2022 */ 2023 @Test 2024 @SmallTest testDontDisconnectDifferentSubForVirtualDsdaDevice()2025 public void testDontDisconnectDifferentSubForVirtualDsdaDevice() { 2026 when(mTelephonyManagerProxy.isConcurrentCallsPossible()).thenReturn(true); 2027 2028 ArrayList<android.telecom.Connection> tcs = new ArrayList<>(); 2029 SimpleTelephonyConnection tc1 = createTestConnection(SUB1_HANDLE, 0, false); 2030 tcs.add(tc1); 2031 TelephonyConnectionService.maybeDisconnectCallsOnOtherSubs( 2032 tcs, SUB2_HANDLE, false, mTelephonyManagerProxy); 2033 assertFalse(tc1.wasDisconnected); 2034 } 2035 2036 /** 2037 * Verifies that DSDA or virtual DSDA-enabled devices will disconnect the existing call when the 2038 * call extra EXTRA_ANSWERING_DROPS_FG_CALL is set on the incoming call on a different sub. 2039 */ 2040 @Test 2041 @SmallTest testDisconnectDifferentSubForVirtualDsdaDevice_ifCallExtraSet()2042 public void testDisconnectDifferentSubForVirtualDsdaDevice_ifCallExtraSet() { 2043 when(mTelephonyManagerProxy.isConcurrentCallsPossible()).thenReturn(true); 2044 2045 ArrayList<android.telecom.Connection> tcs = new ArrayList<>(); 2046 SimpleTelephonyConnection tc1 = createTestConnection(SUB1_HANDLE, 0, false); 2047 tcs.add(tc1); 2048 TelephonyConnectionService.maybeDisconnectCallsOnOtherSubs( 2049 tcs, SUB2_HANDLE, true, mTelephonyManagerProxy); 2050 assertTrue(tc1.wasDisconnected); 2051 } 2052 2053 /** 2054 * For calls on the same sub, the Dialer implements the 'swap' functionality to perform hold and 2055 * unhold, so we do not additionally unhold when 'hold' button is pressed. 2056 */ 2057 @Test 2058 @SmallTest testDontUnholdOnSameSubForVirtualDsdaDevice()2059 public void testDontUnholdOnSameSubForVirtualDsdaDevice() { 2060 when(mTelephonyManagerProxy.isConcurrentCallsPossible()).thenReturn(true); 2061 2062 ArrayList<android.telecom.Connection> tcs = new ArrayList<>(); 2063 Collection<Conference> conferences = new ArrayList<>(); 2064 SimpleTelephonyConnection tc1 = createTestConnection(SUB1_HANDLE, 0, false); 2065 tcs.add(tc1); 2066 TelephonyConnectionService.maybeUnholdCallsOnOtherSubs( 2067 tcs, conferences, SUB1_HANDLE, mTelephonyManagerProxy); 2068 assertFalse(tc1.wasUnheld); 2069 } 2070 2071 /** 2072 * Triggering 'Hold' on 1 call will unhold the other call for DSDA or Virtual DSDA 2073 * enabled devices, effectively constituting 'swap' functionality. 2074 */ 2075 @Test 2076 @SmallTest testUnholdOnOtherSubForVirtualDsdaDevice()2077 public void testUnholdOnOtherSubForVirtualDsdaDevice() { 2078 when(mTelephonyManagerProxy.isConcurrentCallsPossible()).thenReturn(true); 2079 2080 ArrayList<android.telecom.Connection> tcs = new ArrayList<>(); 2081 SimpleTelephonyConnection tc1 = createTestConnection(SUB1_HANDLE, 0, false); 2082 tcs.add(tc1); 2083 TelephonyConnectionService.maybeUnholdCallsOnOtherSubs( 2084 tcs, new ArrayList<>(), SUB2_HANDLE, mTelephonyManagerProxy); 2085 assertTrue(tc1.wasUnheld); 2086 } 2087 2088 /** 2089 * Verifies hold/unhold behavior for a conference on the other sub. It does not disturb the 2090 * individual connections that participate in the conference. 2091 */ 2092 @Test 2093 @SmallTest testUnholdConferenceOnOtherSubForVirtualDsdaDevice()2094 public void testUnholdConferenceOnOtherSubForVirtualDsdaDevice() { 2095 when(mTelephonyManagerProxy.isConcurrentCallsPossible()).thenReturn(true); 2096 SimpleTelephonyConnection tc1 = 2097 createTestConnection(SUB1_HANDLE, 0, false); 2098 SimpleTelephonyConnection tc2 = 2099 createTestConnection(SUB1_HANDLE, 0, false); 2100 List<android.telecom.Connection> conferenceParticipants = Arrays.asList(tc1, tc2); 2101 2102 SimpleConference testConference = createTestConference(SUB1_HANDLE, 0); 2103 List<Conference> conferences = Arrays.asList(testConference); 2104 2105 TelephonyConnectionService.maybeUnholdCallsOnOtherSubs( 2106 conferenceParticipants, conferences, SUB2_HANDLE, mTelephonyManagerProxy); 2107 2108 assertTrue(testConference.wasUnheld); 2109 assertFalse(tc1.wasUnheld); 2110 assertFalse(tc2.wasUnheld); 2111 } 2112 2113 /** 2114 * For DSDA devices, placing an outgoing call on a 2nd sub will hold the existing ACTIVE 2115 * connection on the first sub. 2116 */ 2117 @Test 2118 @SmallTest testHoldOnOtherSubForVirtualDsdaDevice()2119 public void testHoldOnOtherSubForVirtualDsdaDevice() { 2120 when(mTelephonyManagerProxy.isConcurrentCallsPossible()).thenReturn(true); 2121 2122 ArrayList<android.telecom.Connection> tcs = new ArrayList<>(); 2123 SimpleTelephonyConnection tc1 = createTestConnection(SUB1_HANDLE, 0, false); 2124 tc1.setTelephonyConnectionActive(); 2125 tcs.add(tc1); 2126 2127 Conferenceable c = TelephonyConnectionService.maybeHoldCallsOnOtherSubs( 2128 tcs, new ArrayList<>(), SUB2_HANDLE, mTelephonyManagerProxy); 2129 assertTrue(c.equals(tc1)); 2130 assertTrue(tc1.wasHeld); 2131 } 2132 2133 /** 2134 * For DSDA devices with AP domain selection service enabled, placing an outgoing call 2135 * on a 2nd sub will hold the existing ACTIVE connection on the first sub. 2136 */ 2137 @Test 2138 @SmallTest testHoldOnOtherSubForVirtualDsdaDeviceWithDomainSelectionEnabled()2139 public void testHoldOnOtherSubForVirtualDsdaDeviceWithDomainSelectionEnabled() { 2140 when(mTelephonyManagerProxy.isConcurrentCallsPossible()).thenReturn(true); 2141 doReturn(true).when(mDomainSelectionResolver).isDomainSelectionSupported(); 2142 2143 ArrayList<android.telecom.Connection> tcs = new ArrayList<>(); 2144 SimpleTelephonyConnection tc1 = createTestConnection(SUB1_HANDLE, 0, false); 2145 tc1.setTelephonyConnectionActive(); 2146 tcs.add(tc1); 2147 2148 Conferenceable c = TelephonyConnectionService.maybeHoldCallsOnOtherSubs( 2149 tcs, new ArrayList<>(), SUB2_HANDLE, mTelephonyManagerProxy); 2150 assertTrue(c.equals(tc1)); 2151 assertTrue(tc1.wasHeld); 2152 } 2153 2154 /** 2155 * For DSDA devices, if the existing connection was already held, placing an outgoing call on a 2156 * 2nd sub will not attempt to hold the existing connection on the first sub. 2157 */ 2158 @Test 2159 @SmallTest testNoHold_ifExistingConnectionAlreadyHeld_ForVirtualDsdaDevice()2160 public void testNoHold_ifExistingConnectionAlreadyHeld_ForVirtualDsdaDevice() { 2161 when(mTelephonyManagerProxy.isConcurrentCallsPossible()).thenReturn(true); 2162 2163 ArrayList<android.telecom.Connection> tcs = new ArrayList<>(); 2164 SimpleTelephonyConnection tc1 = createTestConnection(SUB1_HANDLE, 0, false); 2165 tc1.setTelephonyConnectionOnHold(); 2166 tcs.add(tc1); 2167 2168 Conferenceable c = TelephonyConnectionService.maybeHoldCallsOnOtherSubs( 2169 tcs, new ArrayList<>(), SUB2_HANDLE, mTelephonyManagerProxy); 2170 assertNull(c); 2171 } 2172 2173 // For 'Virtual DSDA' devices, if there is an existing call on sub1, an outgoing call on sub2 2174 // will place the sub1 call on hold. 2175 @Test 2176 @SmallTest testOutgoingCallOnOtherSubPutsFirstCallOnHoldForVirtualDsdaDevice()2177 public void testOutgoingCallOnOtherSubPutsFirstCallOnHoldForVirtualDsdaDevice() 2178 throws Exception { 2179 setupForCallTest(); 2180 when(mTelephonyManagerProxy.isConcurrentCallsPossible()).thenReturn(true); 2181 doNothing().when(mContext).startActivityAsUser(any(), any()); 2182 2183 mBinderStub.createConnection(PHONE_ACCOUNT_HANDLE_1, "TC@1", 2184 new ConnectionRequest(PHONE_ACCOUNT_HANDLE_1, Uri.parse("tel:16505551212"), 2185 new Bundle()), 2186 true, false, null); 2187 waitForHandlerAction(mTestConnectionService.getHandler(), TIMEOUT_MS); 2188 assertEquals(1, mTestConnectionService.getAllConnections().size()); 2189 2190 TelephonyConnection connection1 = (TelephonyConnection) 2191 mTestConnectionService.getAllConnections().toArray()[0]; 2192 2193 TelephonyConnection connection2 = (TelephonyConnection) mTestConnectionService 2194 .onCreateOutgoingConnection(PHONE_ACCOUNT_HANDLE_2, 2195 createConnectionRequest(PHONE_ACCOUNT_HANDLE_2, "1234", "TC@2")); 2196 assertNotNull("test connection was not set up correctly.", connection2); 2197 2198 // Simulates that connection1 is placed on HOLD. 2199 connection1.setTelephonyConnectionOnHold(); 2200 2201 verify(mPhone1).dial(anyString(), any(), any()); 2202 assertEquals(connection1.getState(), android.telecom.Connection.STATE_HOLDING); 2203 } 2204 2205 // For 'Virtual DSDA' devices, if the carrier config 'KEY_ALLOW_HOLD_CALL_DURING_EMERGENCY_BOOL' 2206 // is not configured, or set to true, an outgoing emergency call will place the existing call on 2207 // a different sub on hold. 2208 @Test 2209 @SmallTest testEmergencyCallOnOtherSubPutsFirstCallOnHoldForVirtualDsdaDevice()2210 public void testEmergencyCallOnOtherSubPutsFirstCallOnHoldForVirtualDsdaDevice() 2211 throws Exception { 2212 setupForCallTest(); 2213 when(mTelephonyManagerProxy.isConcurrentCallsPossible()).thenReturn(true); 2214 doNothing().when(mContext).startActivityAsUser(any(), any()); 2215 2216 doReturn(true).when(mTelephonyManagerProxy).isCurrentEmergencyNumber(anyString()); 2217 mBinderStub.createConnection(PHONE_ACCOUNT_HANDLE_1, "TC@1", 2218 new ConnectionRequest(PHONE_ACCOUNT_HANDLE_1, Uri.parse("tel:16505551212"), 2219 new Bundle()), 2220 true, false, null); 2221 waitForHandlerAction(mTestConnectionService.getHandler(), TIMEOUT_MS); 2222 assertEquals(1, mTestConnectionService.getAllConnections().size()); 2223 2224 TelephonyConnection connection1 = (TelephonyConnection) 2225 mTestConnectionService.getAllConnections().toArray()[0]; 2226 2227 // Simulates an outgoing emergency call. 2228 TelephonyConnection connection2 = (TelephonyConnection) mTestConnectionService 2229 .onCreateOutgoingConnection(PHONE_ACCOUNT_HANDLE_2, 2230 createConnectionRequest(PHONE_ACCOUNT_HANDLE_2, 2231 TEST_EMERGENCY_NUMBER, "TC@2")); 2232 assertNotNull("test connection was not set up correctly.", connection2); 2233 2234 // Simulates that connection1 is placed on HOLD. 2235 connection1.setTelephonyConnectionOnHold(); 2236 2237 verify(mPhone1).dial(anyString(), any(), any()); 2238 assertEquals(connection1.getState(), android.telecom.Connection.STATE_HOLDING); 2239 } 2240 2241 // For 'Virtual DSDA' devices If the carrier config 'KEY_ALLOW_HOLD_CALL_DURING_EMERGENCY_BOOL' 2242 // is explicitly configured false, an outgoing emergency call will disconnect all existing 2243 // calls, across subscriptions. 2244 @Test 2245 @SmallTest testEmergencyCallOnOtherSubDisconnectsExistingCallForVirtualDsdaDevice()2246 public void testEmergencyCallOnOtherSubDisconnectsExistingCallForVirtualDsdaDevice() 2247 throws Exception { 2248 setupForCallTest(); 2249 when(mTelephonyManagerProxy.isConcurrentCallsPossible()).thenReturn(true); 2250 doNothing().when(mContext).startActivityAsUser(any(), any()); 2251 2252 doReturn(true).when(mTelephonyManagerProxy).isCurrentEmergencyNumber(anyString()); 2253 getTestContext().getCarrierConfig(0 /*subId*/).putBoolean( 2254 CarrierConfigManager.KEY_ALLOW_HOLD_CALL_DURING_EMERGENCY_BOOL, false); 2255 2256 mBinderStub.createConnection(PHONE_ACCOUNT_HANDLE_1, "TC@1", 2257 new ConnectionRequest(PHONE_ACCOUNT_HANDLE_1, Uri.parse("tel:16505551212"), 2258 new Bundle()), 2259 true, false, null); 2260 waitForHandlerAction(mTestConnectionService.getHandler(), TIMEOUT_MS); 2261 assertEquals(1, mTestConnectionService.getAllConnections().size()); 2262 2263 TelephonyConnection connection1 = (TelephonyConnection) 2264 mTestConnectionService.getAllConnections().toArray()[0]; 2265 2266 // Simulates an outgoing emergency call. 2267 TelephonyConnection connection2 = (TelephonyConnection) mTestConnectionService 2268 .onCreateOutgoingConnection(PHONE_ACCOUNT_HANDLE_2, 2269 createConnectionRequest(PHONE_ACCOUNT_HANDLE_2, 2270 TEST_EMERGENCY_NUMBER, "TC@2")); 2271 assertNotNull("test connection was not set up correctly.", connection2); 2272 2273 verify(mPhone1).dial(anyString(), any(), any()); 2274 assertEquals(connection1.getState(), android.telecom.Connection.STATE_DISCONNECTED); 2275 } 2276 2277 /** 2278 * Verifies that TelephonyManager is used to determine whether a connection is Emergency when 2279 * creating an outgoing connection. 2280 */ 2281 @Test 2282 @SmallTest testIsEmergencyDeterminedByTelephonyManager()2283 public void testIsEmergencyDeterminedByTelephonyManager() { 2284 ConnectionRequest connectionRequest = new ConnectionRequest.Builder() 2285 .setAccountHandle(PHONE_ACCOUNT_HANDLE_1) 2286 .setAddress(TEST_ADDRESS) 2287 .build(); 2288 mConnection = mTestConnectionService.onCreateOutgoingConnection( 2289 PHONE_ACCOUNT_HANDLE_1, connectionRequest); 2290 2291 verify(mTelephonyManagerProxy) 2292 .isCurrentEmergencyNumber(TEST_ADDRESS.getSchemeSpecificPart()); 2293 } 2294 2295 @Test testDomainSelectionCs()2296 public void testDomainSelectionCs() throws Exception { 2297 setupForCallTest(); 2298 2299 int selectedDomain = DOMAIN_CS; 2300 2301 setupForDialForDomainSelection(mPhone0, selectedDomain, true); 2302 2303 mTestConnectionService.onCreateOutgoingConnection(PHONE_ACCOUNT_HANDLE_1, 2304 createConnectionRequest(PHONE_ACCOUNT_HANDLE_1, 2305 TEST_EMERGENCY_NUMBER, TELECOM_CALL_ID1)); 2306 2307 ArgumentCaptor<android.telecom.Connection> connectionCaptor = 2308 ArgumentCaptor.forClass(android.telecom.Connection.class); 2309 2310 verify(mDomainSelectionResolver) 2311 .getDomainSelectionConnection(eq(mPhone0), eq(SELECTOR_TYPE_CALLING), eq(true)); 2312 verify(mEmergencyStateTracker) 2313 .startEmergencyCall(eq(mPhone0), connectionCaptor.capture(), eq(false)); 2314 verify(mSatelliteSOSMessageRecommender, times(2)).onEmergencyCallStarted(any(), 2315 anyBoolean()); 2316 verify(mEmergencyCallDomainSelectionConnection).createEmergencyConnection(any(), any()); 2317 2318 android.telecom.Connection tc = connectionCaptor.getValue(); 2319 2320 assertNotNull(tc); 2321 assertEquals(TELECOM_CALL_ID1, tc.getTelecomCallId()); 2322 assertEquals(mTestConnectionService.getEmergencyConnection(), tc); 2323 2324 ArgumentCaptor<DialArgs> argsCaptor = ArgumentCaptor.forClass(DialArgs.class); 2325 2326 verify(mPhone0).dial(anyString(), argsCaptor.capture(), any()); 2327 DialArgs dialArgs = argsCaptor.getValue(); 2328 assertNotNull("DialArgs param is null", dialArgs); 2329 assertNotNull("intentExtras is null", dialArgs.intentExtras); 2330 assertTrue(dialArgs.intentExtras.containsKey(PhoneConstants.EXTRA_DIAL_DOMAIN)); 2331 assertEquals(selectedDomain, 2332 dialArgs.intentExtras.getInt(PhoneConstants.EXTRA_DIAL_DOMAIN, -1)); 2333 } 2334 2335 @Test testDomainSelectionPs()2336 public void testDomainSelectionPs() throws Exception { 2337 setupForCallTest(); 2338 2339 int selectedDomain = DOMAIN_PS; 2340 2341 setupForDialForDomainSelection(mPhone0, selectedDomain, true); 2342 2343 mTestConnectionService.onCreateOutgoingConnection(PHONE_ACCOUNT_HANDLE_1, 2344 createConnectionRequest(PHONE_ACCOUNT_HANDLE_1, 2345 TEST_EMERGENCY_NUMBER, TELECOM_CALL_ID1)); 2346 2347 ArgumentCaptor<android.telecom.Connection> connectionCaptor = 2348 ArgumentCaptor.forClass(android.telecom.Connection.class); 2349 2350 verify(mDomainSelectionResolver) 2351 .getDomainSelectionConnection(eq(mPhone0), eq(SELECTOR_TYPE_CALLING), eq(true)); 2352 verify(mEmergencyStateTracker) 2353 .startEmergencyCall(eq(mPhone0), connectionCaptor.capture(), eq(false)); 2354 verify(mSatelliteSOSMessageRecommender, times(2)).onEmergencyCallStarted(any(), 2355 anyBoolean()); 2356 verify(mEmergencyCallDomainSelectionConnection).createEmergencyConnection(any(), any()); 2357 2358 android.telecom.Connection tc = connectionCaptor.getValue(); 2359 2360 assertNotNull(tc); 2361 assertEquals(TELECOM_CALL_ID1, tc.getTelecomCallId()); 2362 assertEquals(mTestConnectionService.getEmergencyConnection(), tc); 2363 2364 ArgumentCaptor<DialArgs> argsCaptor = ArgumentCaptor.forClass(DialArgs.class); 2365 2366 verify(mPhone0).dial(anyString(), argsCaptor.capture(), any()); 2367 DialArgs dialArgs = argsCaptor.getValue(); 2368 assertNotNull("DialArgs param is null", dialArgs); 2369 assertNotNull("intentExtras is null", dialArgs.intentExtras); 2370 assertTrue(dialArgs.intentExtras.containsKey(PhoneConstants.EXTRA_DIAL_DOMAIN)); 2371 assertEquals(selectedDomain, 2372 dialArgs.intentExtras.getInt(PhoneConstants.EXTRA_DIAL_DOMAIN, -1)); 2373 } 2374 2375 @Test testDomainSelectionCsForTty()2376 public void testDomainSelectionCsForTty() throws Exception { 2377 setupForCallTest(); 2378 2379 ImsManager imsManager = Mockito.mock(ImsManager.class); 2380 doReturn(false).when(imsManager).isNonTtyOrTtyOnVolteEnabled(); 2381 replaceInstance(TelephonyConnectionService.class, 2382 "mImsManager", mTestConnectionService, imsManager); 2383 2384 int selectedDomain = DOMAIN_PS; 2385 2386 setupForDialForDomainSelection(mPhone0, selectedDomain, true); 2387 2388 mTestConnectionService.onCreateOutgoingConnection(PHONE_ACCOUNT_HANDLE_1, 2389 createConnectionRequest(PHONE_ACCOUNT_HANDLE_1, 2390 TEST_EMERGENCY_NUMBER, TELECOM_CALL_ID1)); 2391 2392 ArgumentCaptor<android.telecom.Connection> connectionCaptor = 2393 ArgumentCaptor.forClass(android.telecom.Connection.class); 2394 2395 verify(mDomainSelectionResolver) 2396 .getDomainSelectionConnection(eq(mPhone0), eq(SELECTOR_TYPE_CALLING), eq(true)); 2397 verify(mEmergencyStateTracker) 2398 .startEmergencyCall(eq(mPhone0), connectionCaptor.capture(), eq(false)); 2399 verify(mSatelliteSOSMessageRecommender, times(2)).onEmergencyCallStarted(any(), 2400 anyBoolean()); 2401 verify(mEmergencyCallDomainSelectionConnection).createEmergencyConnection(any(), any()); 2402 2403 android.telecom.Connection tc = connectionCaptor.getValue(); 2404 2405 assertNotNull(tc); 2406 assertEquals(TELECOM_CALL_ID1, tc.getTelecomCallId()); 2407 assertEquals(mTestConnectionService.getEmergencyConnection(), tc); 2408 2409 ArgumentCaptor<DialArgs> argsCaptor = ArgumentCaptor.forClass(DialArgs.class); 2410 2411 verify(mPhone0).dial(anyString(), argsCaptor.capture(), any()); 2412 DialArgs dialArgs = argsCaptor.getValue(); 2413 assertNotNull("DialArgs param is null", dialArgs); 2414 assertNotNull("intentExtras is null", dialArgs.intentExtras); 2415 assertTrue(dialArgs.intentExtras.containsKey(PhoneConstants.EXTRA_DIAL_DOMAIN)); 2416 assertEquals(selectedDomain, 2417 dialArgs.intentExtras.getInt(PhoneConstants.EXTRA_DIAL_DOMAIN, -1)); 2418 } 2419 2420 @Test testDomainSelectionRedialCs()2421 public void testDomainSelectionRedialCs() throws Exception { 2422 setupForCallTest(); 2423 2424 int preciseDisconnectCause = com.android.internal.telephony.CallFailCause.ERROR_UNSPECIFIED; 2425 int disconnectCause = android.telephony.DisconnectCause.ERROR_UNSPECIFIED; 2426 int selectedDomain = DOMAIN_CS; 2427 2428 TestTelephonyConnection c = setupForReDialForDomainSelection( 2429 mPhone0, selectedDomain, preciseDisconnectCause, disconnectCause, true); 2430 2431 assertTrue(mTestConnectionService.maybeReselectDomain(c, null, true, 2432 android.telephony.DisconnectCause.NOT_VALID)); 2433 verify(mEmergencyCallDomainSelectionConnection).reselectDomain(any()); 2434 verify(mEmergencyCallDomainSelectionConnection).setDisconnectCause( 2435 eq(disconnectCause), eq(preciseDisconnectCause), any()); 2436 2437 ArgumentCaptor<DialArgs> argsCaptor = ArgumentCaptor.forClass(DialArgs.class); 2438 2439 doReturn(mInternalConnection).when(mPhone0).dial(anyString(), any(), any()); 2440 2441 verify(mPhone0).dial(anyString(), argsCaptor.capture(), any()); 2442 DialArgs dialArgs = argsCaptor.getValue(); 2443 assertNotNull("DialArgs param is null", dialArgs); 2444 assertNotNull("intentExtras is null", dialArgs.intentExtras); 2445 assertTrue(dialArgs.intentExtras.containsKey(PhoneConstants.EXTRA_DIAL_DOMAIN)); 2446 assertEquals(selectedDomain, 2447 dialArgs.intentExtras.getInt(PhoneConstants.EXTRA_DIAL_DOMAIN, -1)); 2448 } 2449 2450 @Test testDomainSelectionRedialPs()2451 public void testDomainSelectionRedialPs() throws Exception { 2452 setupForCallTest(); 2453 2454 int preciseDisconnectCause = com.android.internal.telephony.CallFailCause.ERROR_UNSPECIFIED; 2455 int disconnectCause = android.telephony.DisconnectCause.ERROR_UNSPECIFIED; 2456 int selectedDomain = DOMAIN_PS; 2457 2458 TestTelephonyConnection c = setupForReDialForDomainSelection( 2459 mPhone0, selectedDomain, preciseDisconnectCause, disconnectCause, true); 2460 2461 assertTrue(mTestConnectionService.maybeReselectDomain(c, null, false, 2462 android.telephony.DisconnectCause.ICC_ERROR)); 2463 verify(mEmergencyCallDomainSelectionConnection).reselectDomain(any()); 2464 verify(mEmergencyCallDomainSelectionConnection).setDisconnectCause( 2465 eq(android.telephony.DisconnectCause.ICC_ERROR), 2466 eq(com.android.internal.telephony.CallFailCause.NOT_VALID), 2467 any()); 2468 2469 ArgumentCaptor<DialArgs> argsCaptor = ArgumentCaptor.forClass(DialArgs.class); 2470 2471 doReturn(mInternalConnection).when(mPhone0).dial(anyString(), any(), any()); 2472 2473 verify(mPhone0).dial(anyString(), argsCaptor.capture(), any()); 2474 DialArgs dialArgs = argsCaptor.getValue(); 2475 assertNotNull("DialArgs param is null", dialArgs); 2476 assertNotNull("intentExtras is null", dialArgs.intentExtras); 2477 assertTrue(dialArgs.intentExtras.containsKey(PhoneConstants.EXTRA_DIAL_DOMAIN)); 2478 assertEquals(selectedDomain, 2479 dialArgs.intentExtras.getInt(PhoneConstants.EXTRA_DIAL_DOMAIN, -1)); 2480 } 2481 2482 @Test testDomainSelectionRedialFailedWithException()2483 public void testDomainSelectionRedialFailedWithException() throws Exception { 2484 setupForCallTest(); 2485 2486 int preciseDisconnectCause = com.android.internal.telephony.CallFailCause.ERROR_UNSPECIFIED; 2487 int disconnectCause = android.telephony.DisconnectCause.ERROR_UNSPECIFIED; 2488 int selectedDomain = DOMAIN_CS; 2489 2490 TestTelephonyConnection c = setupForReDialForDomainSelection( 2491 mPhone0, selectedDomain, preciseDisconnectCause, disconnectCause, true); 2492 2493 CallStateException cse = new CallStateException(CallStateException.ERROR_CALLING_DISABLED, 2494 "Calling disabled via ro.telephony.disable-call property"); 2495 doThrow(cse).when(mPhone0).dial(anyString(), any(), any()); 2496 2497 assertTrue(mTestConnectionService.maybeReselectDomain(c, null, true, 2498 android.telephony.DisconnectCause.NOT_VALID)); 2499 verify(mEmergencyCallDomainSelectionConnection).reselectDomain(any()); 2500 verify(mEmergencyCallDomainSelectionConnection).cancelSelection(); 2501 verify(mEmergencyStateTracker).endCall(any()); 2502 } 2503 2504 @Test testDomainSelectionRejectIncoming()2505 public void testDomainSelectionRejectIncoming() throws Exception { 2506 setupForCallTest(); 2507 2508 int selectedDomain = DOMAIN_CS; 2509 2510 setupForDialForDomainSelection(mPhone0, selectedDomain, true); 2511 2512 doReturn(mInternalConnection2).when(mCall).getLatestConnection(); 2513 doReturn(Call.State.INCOMING).when(mCall).getState(); 2514 doReturn(mCall).when(mPhone0).getRingingCall(); 2515 2516 mTestConnectionService.onCreateOutgoingConnection(PHONE_ACCOUNT_HANDLE_1, 2517 createConnectionRequest(PHONE_ACCOUNT_HANDLE_1, 2518 TEST_EMERGENCY_NUMBER, TELECOM_CALL_ID1)); 2519 2520 ArgumentCaptor<android.telecom.Connection> connectionCaptor = 2521 ArgumentCaptor.forClass(android.telecom.Connection.class); 2522 2523 verify(mDomainSelectionResolver) 2524 .getDomainSelectionConnection(eq(mPhone0), eq(SELECTOR_TYPE_CALLING), eq(true)); 2525 verify(mEmergencyStateTracker) 2526 .startEmergencyCall(eq(mPhone0), connectionCaptor.capture(), eq(false)); 2527 verify(mEmergencyCallDomainSelectionConnection).createEmergencyConnection(any(), any()); 2528 2529 android.telecom.Connection tc = connectionCaptor.getValue(); 2530 2531 assertNotNull(tc); 2532 assertEquals(TELECOM_CALL_ID1, tc.getTelecomCallId()); 2533 assertEquals(mTestConnectionService.getEmergencyConnection(), tc); 2534 2535 ArgumentCaptor<Connection.Listener> listenerCaptor = 2536 ArgumentCaptor.forClass(Connection.Listener.class); 2537 2538 verify(mInternalConnection2).addListener(listenerCaptor.capture()); 2539 verify(mCall).hangup(); 2540 verify(mPhone0, never()).dial(anyString(), any(), any()); 2541 2542 Connection.Listener listener = listenerCaptor.getValue(); 2543 2544 assertNotNull(listener); 2545 2546 listener.onDisconnect(0); 2547 2548 verify(mSatelliteSOSMessageRecommender, times(2)).onEmergencyCallStarted(any(), 2549 anyBoolean()); 2550 2551 ArgumentCaptor<DialArgs> argsCaptor = ArgumentCaptor.forClass(DialArgs.class); 2552 2553 verify(mPhone0).dial(anyString(), argsCaptor.capture(), any()); 2554 2555 DialArgs dialArgs = argsCaptor.getValue(); 2556 2557 assertNotNull("DialArgs param is null", dialArgs); 2558 assertNotNull("intentExtras is null", dialArgs.intentExtras); 2559 assertTrue(dialArgs.intentExtras.containsKey(PhoneConstants.EXTRA_DIAL_DOMAIN)); 2560 assertEquals(selectedDomain, 2561 dialArgs.intentExtras.getInt(PhoneConstants.EXTRA_DIAL_DOMAIN, -1)); 2562 } 2563 2564 @Test testDomainSelectionRedialRejectIncoming()2565 public void testDomainSelectionRedialRejectIncoming() throws Exception { 2566 setupForCallTest(); 2567 2568 int preciseDisconnectCause = com.android.internal.telephony.CallFailCause.ERROR_UNSPECIFIED; 2569 int disconnectCause = android.telephony.DisconnectCause.ERROR_UNSPECIFIED; 2570 int selectedDomain = DOMAIN_CS; 2571 2572 TestTelephonyConnection c = setupForReDialForDomainSelection( 2573 mPhone0, selectedDomain, preciseDisconnectCause, disconnectCause, true); 2574 2575 doReturn(mInternalConnection2).when(mCall).getLatestConnection(); 2576 doReturn(Call.State.DISCONNECTING).when(mCall).getState(); 2577 doReturn(mCall).when(mPhone0).getRingingCall(); 2578 2579 assertTrue(mTestConnectionService.maybeReselectDomain(c, null, true, 2580 android.telephony.DisconnectCause.NOT_VALID)); 2581 verify(mEmergencyCallDomainSelectionConnection).reselectDomain(any()); 2582 2583 ArgumentCaptor<Connection.Listener> listenerCaptor = 2584 ArgumentCaptor.forClass(Connection.Listener.class); 2585 2586 verify(mInternalConnection2).addListener(listenerCaptor.capture()); 2587 verify(mCall).hangup(); 2588 verify(mPhone0, never()).dial(anyString(), any(), any()); 2589 2590 Connection.Listener listener = listenerCaptor.getValue(); 2591 2592 assertNotNull(listener); 2593 2594 listener.onDisconnect(0); 2595 2596 ArgumentCaptor<DialArgs> argsCaptor = ArgumentCaptor.forClass(DialArgs.class); 2597 2598 verify(mPhone0).dial(anyString(), argsCaptor.capture(), any()); 2599 DialArgs dialArgs = argsCaptor.getValue(); 2600 assertNotNull("DialArgs param is null", dialArgs); 2601 assertNotNull("intentExtras is null", dialArgs.intentExtras); 2602 assertTrue(dialArgs.intentExtras.containsKey(PhoneConstants.EXTRA_DIAL_DOMAIN)); 2603 assertEquals(selectedDomain, 2604 dialArgs.intentExtras.getInt(PhoneConstants.EXTRA_DIAL_DOMAIN, -1)); 2605 } 2606 2607 @Test testDomainSelectionNormalRoutingEmergencyNumber()2608 public void testDomainSelectionNormalRoutingEmergencyNumber() throws Exception { 2609 setupForCallTest(); 2610 int selectedDomain = DOMAIN_PS; 2611 2612 EmergencyNumber emergencyNumber = new EmergencyNumber(TEST_EMERGENCY_NUMBER, "", "", 2613 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED, 2614 Collections.emptyList(), 2615 EmergencyNumber.EMERGENCY_NUMBER_SOURCE_DATABASE, 2616 EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL); 2617 2618 setupForDialForDomainSelection(mPhone0, selectedDomain, false); 2619 doReturn(true).when(mTelephonyManagerProxy).isCurrentEmergencyNumber(anyString()); 2620 doReturn(emergencyNumber).when(mEmergencyNumberTracker).getEmergencyNumber(anyString()); 2621 doReturn(Arrays.asList(emergencyNumber)).when(mEmergencyNumberTracker).getEmergencyNumbers( 2622 anyString()); 2623 2624 mTestConnectionService.onCreateOutgoingConnection(PHONE_ACCOUNT_HANDLE_1, 2625 createConnectionRequest(PHONE_ACCOUNT_HANDLE_1, 2626 TEST_EMERGENCY_NUMBER, TELECOM_CALL_ID1)); 2627 2628 ArgumentCaptor<TelephonyConnection> connectionCaptor = 2629 ArgumentCaptor.forClass(TelephonyConnection.class); 2630 ArgumentCaptor<Consumer<Boolean>> consumerCaptor = ArgumentCaptor 2631 .forClass(Consumer.class); 2632 2633 verify(mEmergencyStateTracker).startNormalRoutingEmergencyCall(eq(mPhone0), 2634 connectionCaptor.capture(), consumerCaptor.capture()); 2635 2636 TelephonyConnection tc = connectionCaptor.getValue(); 2637 2638 assertNotNull(tc); 2639 assertNotNull(mTestConnectionService.getNormalRoutingEmergencyConnection()); 2640 assertEquals(mTestConnectionService.getNormalRoutingEmergencyConnection(), tc); 2641 2642 verify(mDomainSelectionResolver, never()) 2643 .getDomainSelectionConnection(eq(mPhone0), eq(SELECTOR_TYPE_CALLING), eq(false)); 2644 verify(mNormalCallDomainSelectionConnection, never()).createNormalConnection(any(), any()); 2645 2646 Consumer<Boolean> consumer = consumerCaptor.getValue(); 2647 2648 assertNotNull(consumer); 2649 2650 consumer.accept(true); 2651 2652 verify(mDomainSelectionResolver) 2653 .getDomainSelectionConnection(eq(mPhone0), eq(SELECTOR_TYPE_CALLING), eq(false)); 2654 verify(mNormalCallDomainSelectionConnection).createNormalConnection(any(), any()); 2655 verify(mSatelliteSOSMessageRecommender).onEmergencyCallStarted(any(), anyBoolean()); 2656 2657 ArgumentCaptor<DialArgs> argsCaptor = ArgumentCaptor.forClass(DialArgs.class); 2658 2659 verify(mPhone0).dial(anyString(), argsCaptor.capture(), any()); 2660 DialArgs dialArgs = argsCaptor.getValue(); 2661 assertNotNull("DialArgs param is null", dialArgs); 2662 assertNotNull("intentExtras is null", dialArgs.intentExtras); 2663 assertTrue(dialArgs.intentExtras.containsKey(PhoneConstants.EXTRA_DIAL_DOMAIN)); 2664 assertEquals( 2665 selectedDomain, dialArgs.intentExtras.getInt(PhoneConstants.EXTRA_DIAL_DOMAIN, -1)); 2666 } 2667 2668 @Test testDomainSelectionNormalRoutingEmergencyNumberAndDiscarded()2669 public void testDomainSelectionNormalRoutingEmergencyNumberAndDiscarded() throws Exception { 2670 setupForCallTest(); 2671 int selectedDomain = DOMAIN_PS; 2672 2673 EmergencyNumber emergencyNumber = new EmergencyNumber(TEST_EMERGENCY_NUMBER, "", "", 2674 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED, 2675 Collections.emptyList(), 2676 EmergencyNumber.EMERGENCY_NUMBER_SOURCE_DATABASE, 2677 EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL); 2678 2679 setupForDialForDomainSelection(mPhone0, selectedDomain, false); 2680 doReturn(true).when(mTelephonyManagerProxy).isCurrentEmergencyNumber(anyString()); 2681 doReturn(emergencyNumber).when(mEmergencyNumberTracker).getEmergencyNumber(anyString()); 2682 doReturn(Arrays.asList(emergencyNumber)).when(mEmergencyNumberTracker).getEmergencyNumbers( 2683 anyString()); 2684 2685 mTestConnectionService.onCreateOutgoingConnection(PHONE_ACCOUNT_HANDLE_1, 2686 createConnectionRequest(PHONE_ACCOUNT_HANDLE_1, 2687 TEST_EMERGENCY_NUMBER, TELECOM_CALL_ID1)); 2688 2689 ArgumentCaptor<TelephonyConnection> connectionCaptor = 2690 ArgumentCaptor.forClass(TelephonyConnection.class); 2691 ArgumentCaptor<Consumer<Boolean>> consumerCaptor = ArgumentCaptor 2692 .forClass(Consumer.class); 2693 2694 verify(mEmergencyStateTracker).startNormalRoutingEmergencyCall(eq(mPhone0), 2695 connectionCaptor.capture(), consumerCaptor.capture()); 2696 2697 TelephonyConnection tc = connectionCaptor.getValue(); 2698 2699 assertNotNull(tc); 2700 assertNotNull(mTestConnectionService.getNormalRoutingEmergencyConnection()); 2701 assertEquals(mTestConnectionService.getNormalRoutingEmergencyConnection(), tc); 2702 2703 verify(mDomainSelectionResolver, never()) 2704 .getDomainSelectionConnection(eq(mPhone0), eq(SELECTOR_TYPE_CALLING), eq(false)); 2705 verify(mNormalCallDomainSelectionConnection, never()).createNormalConnection(any(), any()); 2706 2707 Consumer<Boolean> consumer = consumerCaptor.getValue(); 2708 2709 assertNotNull(consumer); 2710 2711 // Discard dialing 2712 tc.hangup(android.telephony.DisconnectCause.LOCAL); 2713 2714 consumer.accept(true); 2715 2716 verify(mDomainSelectionResolver, never()) 2717 .getDomainSelectionConnection(eq(mPhone0), eq(SELECTOR_TYPE_CALLING), eq(false)); 2718 verify(mNormalCallDomainSelectionConnection, never()).createNormalConnection(any(), any()); 2719 } 2720 2721 @Test testDomainSelectionDialedSimEmergencyNumberOnlyFalse()2722 public void testDomainSelectionDialedSimEmergencyNumberOnlyFalse() throws Exception { 2723 setupForCallTest(); 2724 2725 int selectedDomain = DOMAIN_PS; 2726 2727 EmergencyNumber emergencyNumber = new EmergencyNumber(TEST_EMERGENCY_NUMBER, "", "", 2728 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED, 2729 Collections.emptyList(), 2730 EmergencyNumber.EMERGENCY_NUMBER_SOURCE_DATABASE, 2731 EmergencyNumber.EMERGENCY_CALL_ROUTING_EMERGENCY); 2732 2733 setupForDialForDomainSelection(mPhone0, selectedDomain, true); 2734 doReturn(emergencyNumber).when(mEmergencyNumberTracker).getEmergencyNumber(anyString()); 2735 doReturn(Arrays.asList(emergencyNumber)).when(mEmergencyNumberTracker).getEmergencyNumbers( 2736 anyString()); 2737 doReturn(false).when(mEmergencyNumberTracker).isEmergencyNumber(anyString()); 2738 getTestContext().getCarrierConfig(0 /*subId*/).putBoolean( 2739 CarrierConfigManager.KEY_USE_ONLY_DIALED_SIM_ECC_LIST_BOOL, false); 2740 2741 mTestConnectionService.onCreateOutgoingConnection(PHONE_ACCOUNT_HANDLE_1, 2742 createConnectionRequest(PHONE_ACCOUNT_HANDLE_1, 2743 TEST_EMERGENCY_NUMBER, TELECOM_CALL_ID1)); 2744 2745 ArgumentCaptor<android.telecom.Connection> connectionCaptor = 2746 ArgumentCaptor.forClass(android.telecom.Connection.class); 2747 2748 verify(mDomainSelectionResolver) 2749 .getDomainSelectionConnection(eq(mPhone0), eq(SELECTOR_TYPE_CALLING), eq(true)); 2750 verify(mEmergencyStateTracker) 2751 .startEmergencyCall(eq(mPhone0), connectionCaptor.capture(), eq(false)); 2752 verify(mSatelliteSOSMessageRecommender, times(2)).onEmergencyCallStarted(any(), 2753 anyBoolean()); 2754 verify(mEmergencyCallDomainSelectionConnection).createEmergencyConnection(any(), any()); 2755 2756 android.telecom.Connection tc = connectionCaptor.getValue(); 2757 2758 assertNotNull(tc); 2759 assertEquals(TELECOM_CALL_ID1, tc.getTelecomCallId()); 2760 assertEquals(mTestConnectionService.getEmergencyConnection(), tc); 2761 2762 ArgumentCaptor<DialArgs> argsCaptor = ArgumentCaptor.forClass(DialArgs.class); 2763 2764 verify(mPhone0).dial(anyString(), argsCaptor.capture(), any()); 2765 DialArgs dialArgs = argsCaptor.getValue(); 2766 assertNotNull("DialArgs param is null", dialArgs); 2767 assertNotNull("intentExtras is null", dialArgs.intentExtras); 2768 assertTrue(dialArgs.intentExtras.containsKey(PhoneConstants.EXTRA_DIAL_DOMAIN)); 2769 assertEquals(selectedDomain, 2770 dialArgs.intentExtras.getInt(PhoneConstants.EXTRA_DIAL_DOMAIN, -1)); 2771 } 2772 2773 @Test testDomainSelectionDialedSimEmergencyNumberOnlyTrue()2774 public void testDomainSelectionDialedSimEmergencyNumberOnlyTrue() throws Exception { 2775 setupForCallTest(); 2776 int selectedDomain = DOMAIN_PS; 2777 2778 EmergencyNumber emergencyNumber = new EmergencyNumber(TEST_EMERGENCY_NUMBER, "", "", 2779 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED, 2780 Collections.emptyList(), 2781 EmergencyNumber.EMERGENCY_NUMBER_SOURCE_DATABASE, 2782 EmergencyNumber.EMERGENCY_CALL_ROUTING_EMERGENCY); 2783 2784 setupForDialForDomainSelection(mPhone0, selectedDomain, false); 2785 doReturn(true).when(mTelephonyManagerProxy).isCurrentEmergencyNumber(anyString()); 2786 doReturn(emergencyNumber).when(mEmergencyNumberTracker).getEmergencyNumber(anyString()); 2787 doReturn(Arrays.asList(emergencyNumber)).when(mEmergencyNumberTracker).getEmergencyNumbers( 2788 anyString()); 2789 doReturn(false).when(mEmergencyNumberTracker).isEmergencyNumber(anyString()); 2790 getTestContext().getCarrierConfig(0 /*subId*/).putBoolean( 2791 CarrierConfigManager.KEY_USE_ONLY_DIALED_SIM_ECC_LIST_BOOL, true); 2792 2793 mTestConnectionService.onCreateOutgoingConnection(PHONE_ACCOUNT_HANDLE_1, 2794 createConnectionRequest(PHONE_ACCOUNT_HANDLE_1, 2795 TEST_EMERGENCY_NUMBER, TELECOM_CALL_ID1)); 2796 2797 ArgumentCaptor<TelephonyConnection> connectionCaptor = 2798 ArgumentCaptor.forClass(TelephonyConnection.class); 2799 ArgumentCaptor<Consumer<Boolean>> consumerCaptor = ArgumentCaptor 2800 .forClass(Consumer.class); 2801 2802 verify(mEmergencyStateTracker).startNormalRoutingEmergencyCall(eq(mPhone0), 2803 connectionCaptor.capture(), consumerCaptor.capture()); 2804 2805 TelephonyConnection tc = connectionCaptor.getValue(); 2806 2807 assertNotNull(tc); 2808 assertNotNull(mTestConnectionService.getNormalRoutingEmergencyConnection()); 2809 assertEquals(mTestConnectionService.getNormalRoutingEmergencyConnection(), tc); 2810 2811 verify(mDomainSelectionResolver, never()) 2812 .getDomainSelectionConnection(eq(mPhone0), eq(SELECTOR_TYPE_CALLING), eq(false)); 2813 verify(mNormalCallDomainSelectionConnection, never()).createNormalConnection(any(), any()); 2814 2815 Consumer<Boolean> consumer = consumerCaptor.getValue(); 2816 2817 assertNotNull(consumer); 2818 2819 consumer.accept(true); 2820 2821 verify(mDomainSelectionResolver) 2822 .getDomainSelectionConnection(eq(mPhone0), eq(SELECTOR_TYPE_CALLING), eq(false)); 2823 verify(mNormalCallDomainSelectionConnection).createNormalConnection(any(), any()); 2824 verify(mSatelliteSOSMessageRecommender).onEmergencyCallStarted(any(), anyBoolean()); 2825 2826 ArgumentCaptor<DialArgs> argsCaptor = ArgumentCaptor.forClass(DialArgs.class); 2827 2828 verify(mPhone0).dial(anyString(), argsCaptor.capture(), any()); 2829 DialArgs dialArgs = argsCaptor.getValue(); 2830 assertNotNull("DialArgs param is null", dialArgs); 2831 assertNotNull("intentExtras is null", dialArgs.intentExtras); 2832 assertTrue(dialArgs.intentExtras.containsKey(PhoneConstants.EXTRA_DIAL_DOMAIN)); 2833 assertEquals( 2834 selectedDomain, dialArgs.intentExtras.getInt(PhoneConstants.EXTRA_DIAL_DOMAIN, -1)); 2835 } 2836 2837 @Test testDomainSelectionNormalRoutingEmergencyNumber_exitingApm_InService()2838 public void testDomainSelectionNormalRoutingEmergencyNumber_exitingApm_InService() 2839 throws Exception { 2840 when(mDeviceState.isAirplaneModeOn(any())).thenReturn(true); 2841 Phone testPhone = setupConnectionServiceInApmForDomainSelection(true); 2842 2843 ArgumentCaptor<RadioOnStateListener.Callback> callback = 2844 ArgumentCaptor.forClass(RadioOnStateListener.Callback.class); 2845 verify(mRadioOnHelper).triggerRadioOnAndListen(callback.capture(), eq(true), 2846 eq(testPhone), eq(false), eq(TIMEOUT_TO_DYNAMIC_ROUTING_MS)); 2847 2848 ServiceState ss = new ServiceState(); 2849 ss.setState(ServiceState.STATE_OUT_OF_SERVICE); 2850 when(testPhone.getServiceState()).thenReturn(ss); 2851 when(mSST.getServiceState()).thenReturn(ss); 2852 2853 assertFalse(callback.getValue() 2854 .isOkToCall(testPhone, ServiceState.STATE_OUT_OF_SERVICE, false)); 2855 2856 when(mSST.isRadioOn()).thenReturn(true); 2857 2858 assertFalse(callback.getValue() 2859 .isOkToCall(testPhone, ServiceState.STATE_OUT_OF_SERVICE, false)); 2860 2861 Phone otherPhone = makeTestPhone(1, ServiceState.STATE_OUT_OF_SERVICE, false); 2862 when(otherPhone.getServiceState()).thenReturn(ss); 2863 2864 // Radio on is OK for other phone 2865 assertTrue(callback.getValue() 2866 .isOkToCall(otherPhone, ServiceState.STATE_OUT_OF_SERVICE, false)); 2867 2868 ss.setState(ServiceState.STATE_IN_SERVICE); 2869 2870 assertTrue(callback.getValue() 2871 .isOkToCall(testPhone, ServiceState.STATE_IN_SERVICE, false)); 2872 2873 mConnection.setDisconnected(null); 2874 } 2875 2876 @Test testDomainSelectionNormalRoutingEmergencyNumber_exitingApm_Timeout()2877 public void testDomainSelectionNormalRoutingEmergencyNumber_exitingApm_Timeout() 2878 throws Exception { 2879 when(mDeviceState.isAirplaneModeOn(any())).thenReturn(true); 2880 Phone testPhone = setupConnectionServiceInApmForDomainSelection(true); 2881 2882 ArgumentCaptor<RadioOnStateListener.Callback> callback = 2883 ArgumentCaptor.forClass(RadioOnStateListener.Callback.class); 2884 verify(mRadioOnHelper).triggerRadioOnAndListen(callback.capture(), eq(true), 2885 eq(testPhone), eq(false), eq(TIMEOUT_TO_DYNAMIC_ROUTING_MS)); 2886 2887 ServiceState ss = new ServiceState(); 2888 ss.setState(ServiceState.STATE_OUT_OF_SERVICE); 2889 when(testPhone.getServiceState()).thenReturn(ss); 2890 when(mSST.getServiceState()).thenReturn(ss); 2891 when(mSST.isRadioOn()).thenReturn(true); 2892 2893 assertFalse(callback.getValue() 2894 .isOkToCall(testPhone, ServiceState.STATE_OUT_OF_SERVICE, false)); 2895 assertTrue(callback.getValue() 2896 .onTimeout(testPhone, ServiceState.STATE_OUT_OF_SERVICE, false)); 2897 2898 mConnection.setDisconnected(null); 2899 } 2900 2901 @Test testDomainSelectionNormalRoutingEmergencyNumber_exitingApm_CombinedAttach()2902 public void testDomainSelectionNormalRoutingEmergencyNumber_exitingApm_CombinedAttach() 2903 throws Exception { 2904 when(mDeviceState.isAirplaneModeOn(any())).thenReturn(true); 2905 Phone testPhone = setupConnectionServiceInApmForDomainSelection(true); 2906 2907 ArgumentCaptor<RadioOnStateListener.Callback> callback = 2908 ArgumentCaptor.forClass(RadioOnStateListener.Callback.class); 2909 verify(mRadioOnHelper).triggerRadioOnAndListen(callback.capture(), eq(true), 2910 eq(testPhone), eq(false), eq(TIMEOUT_TO_DYNAMIC_ROUTING_MS)); 2911 2912 ServiceState ss = new ServiceState(); 2913 ss.setState(ServiceState.STATE_IN_SERVICE); 2914 when(testPhone.getServiceState()).thenReturn(ss); 2915 when(mSST.getServiceState()).thenReturn(ss); 2916 when(mSST.isRadioOn()).thenReturn(true); 2917 2918 DataSpecificRegistrationInfo dsri = new DataSpecificRegistrationInfo.Builder(3) 2919 .setLteAttachResultType(DataSpecificRegistrationInfo.LTE_ATTACH_TYPE_COMBINED) 2920 .build(); 2921 2922 NetworkRegistrationInfo nri = new NetworkRegistrationInfo.Builder() 2923 .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN) 2924 .setDomain(NetworkRegistrationInfo.DOMAIN_PS) 2925 .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_LTE) 2926 .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME) 2927 .setDataSpecificInfo(dsri) 2928 .build(); 2929 ss.addNetworkRegistrationInfo(nri); 2930 2931 assertTrue(callback.getValue() 2932 .isOkToCall(testPhone, ServiceState.STATE_IN_SERVICE, false)); 2933 2934 mConnection.setDisconnected(null); 2935 } 2936 2937 @Test testDomainSelectionNormalRoutingEmergencyNumber_exitingApm_PsOnly()2938 public void testDomainSelectionNormalRoutingEmergencyNumber_exitingApm_PsOnly() 2939 throws Exception { 2940 when(mDeviceState.isAirplaneModeOn(any())).thenReturn(true); 2941 Phone testPhone = setupConnectionServiceInApmForDomainSelection(true); 2942 2943 ArgumentCaptor<RadioOnStateListener.Callback> callback = 2944 ArgumentCaptor.forClass(RadioOnStateListener.Callback.class); 2945 verify(mRadioOnHelper).triggerRadioOnAndListen(callback.capture(), eq(true), 2946 eq(testPhone), eq(false), eq(TIMEOUT_TO_DYNAMIC_ROUTING_MS)); 2947 2948 ServiceState ss = new ServiceState(); 2949 ss.setState(ServiceState.STATE_IN_SERVICE); 2950 when(testPhone.getServiceState()).thenReturn(ss); 2951 when(mSST.getServiceState()).thenReturn(ss); 2952 when(mSST.isRadioOn()).thenReturn(true); 2953 2954 DataSpecificRegistrationInfo dsri = new DataSpecificRegistrationInfo.Builder(3) 2955 .build(); 2956 2957 NetworkRegistrationInfo nri = new NetworkRegistrationInfo.Builder() 2958 .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN) 2959 .setDomain(NetworkRegistrationInfo.DOMAIN_PS) 2960 .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_LTE) 2961 .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME) 2962 .setDataSpecificInfo(dsri) 2963 .build(); 2964 ss.addNetworkRegistrationInfo(nri); 2965 2966 assertFalse(callback.getValue() 2967 .isOkToCall(testPhone, ServiceState.STATE_IN_SERVICE, false)); 2968 assertTrue(callback.getValue() 2969 .onTimeout(testPhone, ServiceState.STATE_IN_SERVICE, false)); 2970 2971 mConnection.setDisconnected(null); 2972 } 2973 2974 @Test testDomainSelectionNormalRoutingEmergencyNumber_exitingApm_PsOnly_ImsRegistered()2975 public void testDomainSelectionNormalRoutingEmergencyNumber_exitingApm_PsOnly_ImsRegistered() 2976 throws Exception { 2977 when(mDeviceState.isAirplaneModeOn(any())).thenReturn(true); 2978 Phone testPhone = setupConnectionServiceInApmForDomainSelection(true); 2979 2980 ArgumentCaptor<RadioOnStateListener.Callback> callback = 2981 ArgumentCaptor.forClass(RadioOnStateListener.Callback.class); 2982 verify(mRadioOnHelper).triggerRadioOnAndListen(callback.capture(), eq(true), 2983 eq(testPhone), eq(false), eq(TIMEOUT_TO_DYNAMIC_ROUTING_MS)); 2984 2985 ServiceState ss = new ServiceState(); 2986 ss.setState(ServiceState.STATE_IN_SERVICE); 2987 when(testPhone.getServiceState()).thenReturn(ss); 2988 when(mSST.getServiceState()).thenReturn(ss); 2989 when(mSST.isRadioOn()).thenReturn(true); 2990 2991 DataSpecificRegistrationInfo dsri = new DataSpecificRegistrationInfo.Builder(3) 2992 .build(); 2993 2994 NetworkRegistrationInfo nri = new NetworkRegistrationInfo.Builder() 2995 .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN) 2996 .setDomain(NetworkRegistrationInfo.DOMAIN_PS) 2997 .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_LTE) 2998 .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME) 2999 .setDataSpecificInfo(dsri) 3000 .build(); 3001 ss.addNetworkRegistrationInfo(nri); 3002 3003 assertFalse(callback.getValue() 3004 .isOkToCall(testPhone, ServiceState.STATE_IN_SERVICE, false)); 3005 assertTrue(callback.getValue() 3006 .isOkToCall(testPhone, ServiceState.STATE_IN_SERVICE, true)); 3007 3008 mConnection.setDisconnected(null); 3009 } 3010 3011 @Test testDomainSelectionNormalRoutingEmergencyNumber_exitingApm_DiscardDialing()3012 public void testDomainSelectionNormalRoutingEmergencyNumber_exitingApm_DiscardDialing() 3013 throws Exception { 3014 when(mDeviceState.isAirplaneModeOn(any())).thenReturn(true); 3015 Phone testPhone = setupConnectionServiceInApmForDomainSelection(true); 3016 3017 ArgumentCaptor<RadioOnStateListener.Callback> callback = 3018 ArgumentCaptor.forClass(RadioOnStateListener.Callback.class); 3019 verify(mRadioOnHelper).triggerRadioOnAndListen(callback.capture(), eq(true), 3020 eq(testPhone), eq(false), eq(TIMEOUT_TO_DYNAMIC_ROUTING_MS)); 3021 3022 mConnection.setDisconnected(null); 3023 3024 assertTrue(callback.getValue() 3025 .isOkToCall(testPhone, ServiceState.STATE_POWER_OFF, false)); 3026 } 3027 3028 @Test testDomainSelectionNormalToEmergencyCs()3029 public void testDomainSelectionNormalToEmergencyCs() throws Exception { 3030 setupForCallTest(); 3031 3032 int preciseDisconnectCause = com.android.internal.telephony.CallFailCause.ERROR_UNSPECIFIED; 3033 int disconnectCause = android.telephony.DisconnectCause.ERROR_UNSPECIFIED; 3034 int eccCategory = EMERGENCY_SERVICE_CATEGORY_POLICE; 3035 int selectedDomain = DOMAIN_CS; 3036 3037 setupForDialForDomainSelection(mPhone0, selectedDomain, true); 3038 doReturn(mPhone0).when(mImsPhone).getDefaultPhone(); 3039 doReturn(mInternalConnection).when(mPhone0).dial(anyString(), any(), any()); 3040 3041 TestTelephonyConnection c = setupForReDialForDomainSelection( 3042 mImsPhone, selectedDomain, preciseDisconnectCause, disconnectCause, false); 3043 c.setEmergencyServiceCategory(eccCategory); 3044 c.setAddress(TEST_ADDRESS, TelecomManager.PRESENTATION_ALLOWED); 3045 3046 ImsReasonInfo reasonInfo = new ImsReasonInfo(CODE_SIP_ALTERNATE_EMERGENCY_CALL, 0, null); 3047 assertTrue(mTestConnectionService.maybeReselectDomain(c, reasonInfo, true, 3048 android.telephony.DisconnectCause.NOT_VALID)); 3049 3050 ArgumentCaptor<android.telecom.Connection> connectionCaptor = 3051 ArgumentCaptor.forClass(android.telecom.Connection.class); 3052 3053 verify(mDomainSelectionResolver) 3054 .getDomainSelectionConnection(eq(mPhone0), eq(SELECTOR_TYPE_CALLING), eq(true)); 3055 verify(mEmergencyStateTracker) 3056 .startEmergencyCall(eq(mPhone0), connectionCaptor.capture(), eq(false)); 3057 verify(mSatelliteSOSMessageRecommender).onEmergencyCallStarted(any(), anyBoolean()); 3058 verify(mEmergencyCallDomainSelectionConnection).createEmergencyConnection(any(), any()); 3059 3060 android.telecom.Connection tc = connectionCaptor.getValue(); 3061 3062 assertNotNull(tc); 3063 assertEquals(TELECOM_CALL_ID1, tc.getTelecomCallId()); 3064 assertEquals(mTestConnectionService.getEmergencyConnection(), tc); 3065 3066 ArgumentCaptor<DialArgs> argsCaptor = ArgumentCaptor.forClass(DialArgs.class); 3067 3068 verify(mPhone0).dial(anyString(), argsCaptor.capture(), any()); 3069 DialArgs dialArgs = argsCaptor.getValue(); 3070 assertNotNull("DialArgs param is null", dialArgs); 3071 assertNotNull("intentExtras is null", dialArgs.intentExtras); 3072 assertTrue(dialArgs.intentExtras.containsKey(PhoneConstants.EXTRA_DIAL_DOMAIN)); 3073 assertEquals(selectedDomain, 3074 dialArgs.intentExtras.getInt(PhoneConstants.EXTRA_DIAL_DOMAIN, -1)); 3075 assertTrue(dialArgs.isEmergency); 3076 assertEquals(eccCategory, dialArgs.eccCategory); 3077 assertTrue(dialArgs.intentExtras.getBoolean( 3078 PhoneConstants.EXTRA_USE_EMERGENCY_ROUTING, false)); 3079 } 3080 3081 @Test testDomainSelectionNormalToEmergencyPs()3082 public void testDomainSelectionNormalToEmergencyPs() throws Exception { 3083 setupForCallTest(); 3084 3085 int preciseDisconnectCause = com.android.internal.telephony.CallFailCause.ERROR_UNSPECIFIED; 3086 int disconnectCause = android.telephony.DisconnectCause.ERROR_UNSPECIFIED; 3087 int eccCategory = EMERGENCY_SERVICE_CATEGORY_POLICE; 3088 int selectedDomain = DOMAIN_PS; 3089 3090 setupForDialForDomainSelection(mPhone0, selectedDomain, true); 3091 doReturn(mPhone0).when(mImsPhone).getDefaultPhone(); 3092 doReturn(mInternalConnection).when(mPhone0).dial(anyString(), any(), any()); 3093 3094 TestTelephonyConnection c = setupForReDialForDomainSelection( 3095 mImsPhone, selectedDomain, preciseDisconnectCause, disconnectCause, false); 3096 c.setEmergencyServiceCategory(eccCategory); 3097 c.setAddress(TEST_ADDRESS, TelecomManager.PRESENTATION_ALLOWED); 3098 3099 ImsReasonInfo reasonInfo = new ImsReasonInfo(CODE_SIP_ALTERNATE_EMERGENCY_CALL, 0, null); 3100 assertTrue(mTestConnectionService.maybeReselectDomain(c, reasonInfo, true, 3101 android.telephony.DisconnectCause.NOT_VALID)); 3102 3103 ArgumentCaptor<android.telecom.Connection> connectionCaptor = 3104 ArgumentCaptor.forClass(android.telecom.Connection.class); 3105 3106 verify(mDomainSelectionResolver) 3107 .getDomainSelectionConnection(eq(mPhone0), eq(SELECTOR_TYPE_CALLING), eq(true)); 3108 verify(mEmergencyStateTracker) 3109 .startEmergencyCall(eq(mPhone0), connectionCaptor.capture(), eq(false)); 3110 verify(mSatelliteSOSMessageRecommender).onEmergencyCallStarted(any(), anyBoolean()); 3111 verify(mEmergencyCallDomainSelectionConnection).createEmergencyConnection(any(), any()); 3112 3113 android.telecom.Connection tc = connectionCaptor.getValue(); 3114 3115 assertNotNull(tc); 3116 assertEquals(TELECOM_CALL_ID1, tc.getTelecomCallId()); 3117 assertEquals(mTestConnectionService.getEmergencyConnection(), tc); 3118 3119 ArgumentCaptor<DialArgs> argsCaptor = ArgumentCaptor.forClass(DialArgs.class); 3120 3121 verify(mPhone0).dial(anyString(), argsCaptor.capture(), any()); 3122 DialArgs dialArgs = argsCaptor.getValue(); 3123 assertNotNull("DialArgs param is null", dialArgs); 3124 assertNotNull("intentExtras is null", dialArgs.intentExtras); 3125 assertTrue(dialArgs.intentExtras.containsKey(PhoneConstants.EXTRA_DIAL_DOMAIN)); 3126 assertEquals(selectedDomain, 3127 dialArgs.intentExtras.getInt(PhoneConstants.EXTRA_DIAL_DOMAIN, -1)); 3128 assertTrue(dialArgs.isEmergency); 3129 assertEquals(eccCategory, dialArgs.eccCategory); 3130 assertTrue(dialArgs.intentExtras.getBoolean( 3131 PhoneConstants.EXTRA_USE_EMERGENCY_ROUTING, false)); 3132 } 3133 3134 @Test testDomainSelectionSwitchPhones()3135 public void testDomainSelectionSwitchPhones() throws Exception { 3136 setupForCallTest(); 3137 3138 doReturn(CompletableFuture.completedFuture(EMERGENCY_PERM_FAILURE)) 3139 .when(mEmergencyStateTracker) 3140 .startEmergencyCall(eq(mPhone0), any(), eq(false)); 3141 doReturn(CompletableFuture.completedFuture(NOT_DISCONNECTED)) 3142 .when(mEmergencyStateTracker) 3143 .startEmergencyCall(eq(mPhone1), any(), eq(false)); 3144 3145 doReturn(mEmergencyCallDomainSelectionConnection).when(mDomainSelectionResolver) 3146 .getDomainSelectionConnection(any(), anyInt(), eq(true)); 3147 doReturn(true).when(mTelephonyManagerProxy).isCurrentEmergencyNumber(anyString()); 3148 3149 doReturn(true).when(mDomainSelectionResolver).isDomainSelectionSupported(); 3150 3151 mTestConnectionService.onCreateOutgoingConnection(PHONE_ACCOUNT_HANDLE_1, 3152 createConnectionRequest(PHONE_ACCOUNT_HANDLE_1, 3153 TEST_EMERGENCY_NUMBER, TELECOM_CALL_ID1)); 3154 3155 ArgumentCaptor<DomainSelectionService.SelectionAttributes> attrCaptor = 3156 ArgumentCaptor.forClass( 3157 DomainSelectionService.SelectionAttributes.class); 3158 3159 verify(mEmergencyStateTracker).startEmergencyCall(eq(mPhone0), any(), anyBoolean()); 3160 verify(mEmergencyStateTracker).startEmergencyCall(eq(mPhone1), any(), anyBoolean()); 3161 verify(mEmergencyCallDomainSelectionConnection).createEmergencyConnection( 3162 attrCaptor.capture(), any()); 3163 3164 DomainSelectionService.SelectionAttributes attr = attrCaptor.getValue(); 3165 3166 assertEquals(mPhone1.getPhoneId(), attr.getSlotIndex()); 3167 } 3168 3169 @Test testOnSelectionTerminatedPerm()3170 public void testOnSelectionTerminatedPerm() throws Exception { 3171 setupForCallTest(); 3172 3173 doReturn(mEmergencyCallDomainSelectionConnection).when(mDomainSelectionResolver) 3174 .getDomainSelectionConnection(any(), anyInt(), eq(true)); 3175 doReturn(mPhone0).when(mEmergencyCallDomainSelectionConnection).getPhone(); 3176 doReturn(true).when(mTelephonyManagerProxy).isCurrentEmergencyNumber(anyString()); 3177 3178 doReturn(true).when(mDomainSelectionResolver).isDomainSelectionSupported(); 3179 doReturn(mImsPhone).when(mPhone0).getImsPhone(); 3180 3181 mTestConnectionService.onCreateOutgoingConnection(PHONE_ACCOUNT_HANDLE_1, 3182 createConnectionRequest(PHONE_ACCOUNT_HANDLE_1, 3183 TEST_EMERGENCY_NUMBER, TELECOM_CALL_ID1)); 3184 3185 ArgumentCaptor<DomainSelectionConnection.DomainSelectionConnectionCallback> callbackCaptor = 3186 ArgumentCaptor.forClass( 3187 DomainSelectionConnection.DomainSelectionConnectionCallback.class); 3188 3189 verify(mEmergencyCallDomainSelectionConnection).createEmergencyConnection( 3190 any(), callbackCaptor.capture()); 3191 3192 DomainSelectionConnection.DomainSelectionConnectionCallback callback = 3193 callbackCaptor.getValue(); 3194 3195 assertNotNull(callback); 3196 3197 EmergencyCallDomainSelectionConnection ecdsc = 3198 Mockito.mock(EmergencyCallDomainSelectionConnection.class); 3199 doReturn(ecdsc).when(mDomainSelectionResolver) 3200 .getDomainSelectionConnection(any(), anyInt(), eq(true)); 3201 3202 callback.onSelectionTerminated(EMERGENCY_PERM_FAILURE); 3203 3204 ArgumentCaptor<DomainSelectionService.SelectionAttributes> attrCaptor = 3205 ArgumentCaptor.forClass( 3206 DomainSelectionService.SelectionAttributes.class); 3207 3208 verify(ecdsc).createEmergencyConnection(attrCaptor.capture(), any()); 3209 3210 DomainSelectionService.SelectionAttributes attr = attrCaptor.getValue(); 3211 3212 assertEquals(mPhone1.getPhoneId(), attr.getSlotIndex()); 3213 } 3214 3215 @Test testOnSelectionTerminatedTemp()3216 public void testOnSelectionTerminatedTemp() throws Exception { 3217 setupForCallTest(); 3218 3219 doReturn(mEmergencyCallDomainSelectionConnection).when(mDomainSelectionResolver) 3220 .getDomainSelectionConnection(any(), anyInt(), eq(true)); 3221 doReturn(mPhone0).when(mEmergencyCallDomainSelectionConnection).getPhone(); 3222 doReturn(true).when(mTelephonyManagerProxy).isCurrentEmergencyNumber(anyString()); 3223 3224 doReturn(true).when(mDomainSelectionResolver).isDomainSelectionSupported(); 3225 doReturn(mImsPhone).when(mPhone0).getImsPhone(); 3226 3227 mTestConnectionService.onCreateOutgoingConnection(PHONE_ACCOUNT_HANDLE_1, 3228 createConnectionRequest(PHONE_ACCOUNT_HANDLE_1, 3229 TEST_EMERGENCY_NUMBER, TELECOM_CALL_ID1)); 3230 3231 ArgumentCaptor<DomainSelectionConnection.DomainSelectionConnectionCallback> callbackCaptor = 3232 ArgumentCaptor.forClass( 3233 DomainSelectionConnection.DomainSelectionConnectionCallback.class); 3234 3235 verify(mEmergencyCallDomainSelectionConnection).createEmergencyConnection( 3236 any(), callbackCaptor.capture()); 3237 3238 DomainSelectionConnection.DomainSelectionConnectionCallback callback = 3239 callbackCaptor.getValue(); 3240 3241 assertNotNull(callback); 3242 3243 EmergencyCallDomainSelectionConnection ecdsc = 3244 Mockito.mock(EmergencyCallDomainSelectionConnection.class); 3245 doReturn(ecdsc).when(mDomainSelectionResolver) 3246 .getDomainSelectionConnection(any(), anyInt(), eq(true)); 3247 3248 callback.onSelectionTerminated(EMERGENCY_TEMP_FAILURE); 3249 3250 ArgumentCaptor<DomainSelectionService.SelectionAttributes> attrCaptor = 3251 ArgumentCaptor.forClass( 3252 DomainSelectionService.SelectionAttributes.class); 3253 3254 verify(ecdsc).createEmergencyConnection(attrCaptor.capture(), any()); 3255 3256 DomainSelectionService.SelectionAttributes attr = attrCaptor.getValue(); 3257 3258 assertEquals(mPhone1.getPhoneId(), attr.getSlotIndex()); 3259 } 3260 3261 @Test testOnSelectionTerminatedUnspecified()3262 public void testOnSelectionTerminatedUnspecified() throws Exception { 3263 setupForCallTest(); 3264 3265 doReturn(mEmergencyCallDomainSelectionConnection).when(mDomainSelectionResolver) 3266 .getDomainSelectionConnection(any(), anyInt(), eq(true)); 3267 doReturn(mPhone0).when(mEmergencyCallDomainSelectionConnection).getPhone(); 3268 doReturn(true).when(mTelephonyManagerProxy).isCurrentEmergencyNumber(anyString()); 3269 3270 doReturn(true).when(mDomainSelectionResolver).isDomainSelectionSupported(); 3271 doReturn(mImsPhone).when(mPhone0).getImsPhone(); 3272 3273 mTestConnectionService.onCreateOutgoingConnection(PHONE_ACCOUNT_HANDLE_1, 3274 createConnectionRequest(PHONE_ACCOUNT_HANDLE_1, 3275 TEST_EMERGENCY_NUMBER, TELECOM_CALL_ID1)); 3276 3277 TelephonyConnection c = mTestConnectionService.getEmergencyConnection(); 3278 3279 assertNotNull(c); 3280 assertNull(c.getOriginalConnection()); 3281 3282 ArgumentCaptor<DomainSelectionConnection.DomainSelectionConnectionCallback> callbackCaptor = 3283 ArgumentCaptor.forClass( 3284 DomainSelectionConnection.DomainSelectionConnectionCallback.class); 3285 3286 verify(mEmergencyCallDomainSelectionConnection).createEmergencyConnection( 3287 any(), callbackCaptor.capture()); 3288 3289 DomainSelectionConnection.DomainSelectionConnectionCallback callback = 3290 callbackCaptor.getValue(); 3291 3292 assertNotNull(callback); 3293 3294 callback.onSelectionTerminated(ERROR_UNSPECIFIED); 3295 3296 verify(mEmergencyCallDomainSelectionConnection).cancelSelection(); 3297 verify(mEmergencyStateTracker).endCall(eq(c)); 3298 3299 android.telecom.DisconnectCause disconnectCause = c.getDisconnectCause(); 3300 3301 assertNotNull(disconnectCause); 3302 assertEquals(ERROR_UNSPECIFIED, disconnectCause.getTelephonyDisconnectCause()); 3303 } 3304 3305 @Test testDomainSelectionDialFailedByException()3306 public void testDomainSelectionDialFailedByException() throws Exception { 3307 setupForCallTest(); 3308 3309 int selectedDomain = DOMAIN_CS; 3310 3311 setupForDialForDomainSelection(mPhone0, selectedDomain, true); 3312 3313 CallStateException cse = new CallStateException(CallStateException.ERROR_CALLING_DISABLED, 3314 "Calling disabled via ro.telephony.disable-call property"); 3315 doThrow(cse).when(mPhone0).dial(anyString(), any(), any()); 3316 3317 mTestConnectionService.onCreateOutgoingConnection(PHONE_ACCOUNT_HANDLE_1, 3318 createConnectionRequest(PHONE_ACCOUNT_HANDLE_1, 3319 TEST_EMERGENCY_NUMBER, TELECOM_CALL_ID1)); 3320 3321 verify(mEmergencyStateTracker) 3322 .startEmergencyCall(any(), any(), anyBoolean()); 3323 verify(mEmergencyCallDomainSelectionConnection).cancelSelection(); 3324 verify(mEmergencyStateTracker).endCall(any()); 3325 } 3326 3327 @Test testDomainSelectionLocalHangupStartEmergencyCall()3328 public void testDomainSelectionLocalHangupStartEmergencyCall() throws Exception { 3329 setupForCallTest(); 3330 3331 int selectedDomain = DOMAIN_CS; 3332 3333 setupForDialForDomainSelection(mPhone0, selectedDomain, true); 3334 3335 CompletableFuture<Integer> future = new CompletableFuture<>(); 3336 doReturn(future).when(mEmergencyStateTracker) 3337 .startEmergencyCall(any(), any(), eq(false)); 3338 3339 mTestConnectionService.onCreateOutgoingConnection(PHONE_ACCOUNT_HANDLE_1, 3340 createConnectionRequest(PHONE_ACCOUNT_HANDLE_1, 3341 TEST_EMERGENCY_NUMBER, TELECOM_CALL_ID1)); 3342 3343 verify(mEmergencyStateTracker) 3344 .startEmergencyCall(eq(mPhone0), any(), eq(false)); 3345 3346 // dialing is canceled 3347 mTestConnectionService.onLocalHangup(mTestConnectionService.getEmergencyConnection()); 3348 3349 // startEmergencyCall has completed 3350 future.complete(NOT_DISCONNECTED); 3351 3352 // verify that createEmergencyConnection is discarded 3353 verify(mEmergencyCallDomainSelectionConnection, never()) 3354 .createEmergencyConnection(any(), any()); 3355 } 3356 3357 @Test testDomainSelectionLocalHangupCreateEmergencyConnection()3358 public void testDomainSelectionLocalHangupCreateEmergencyConnection() throws Exception { 3359 setupForCallTest(); 3360 3361 int selectedDomain = DOMAIN_CS; 3362 3363 setupForDialForDomainSelection(mPhone0, selectedDomain, true); 3364 3365 CompletableFuture<Integer> future = new CompletableFuture<>(); 3366 doReturn(future).when(mEmergencyCallDomainSelectionConnection) 3367 .createEmergencyConnection(any(), any()); 3368 3369 mTestConnectionService.onCreateOutgoingConnection(PHONE_ACCOUNT_HANDLE_1, 3370 createConnectionRequest(PHONE_ACCOUNT_HANDLE_1, 3371 TEST_EMERGENCY_NUMBER, TELECOM_CALL_ID1)); 3372 3373 verify(mEmergencyCallDomainSelectionConnection).createEmergencyConnection(any(), any()); 3374 3375 // dialing is canceled 3376 mTestConnectionService.onLocalHangup(mTestConnectionService.getEmergencyConnection()); 3377 3378 // domain selection has completed 3379 future.complete(selectedDomain); 3380 3381 // verify that dialing is discarded 3382 verify(mPhone0, never()).dial(anyString(), any(), any()); 3383 } 3384 3385 @Test testDomainSelectionRedialLocalHangupReselectDomain()3386 public void testDomainSelectionRedialLocalHangupReselectDomain() throws Exception { 3387 setupForCallTest(); 3388 3389 int preciseDisconnectCause = com.android.internal.telephony.CallFailCause.ERROR_UNSPECIFIED; 3390 int disconnectCause = android.telephony.DisconnectCause.ERROR_UNSPECIFIED; 3391 int selectedDomain = DOMAIN_CS; 3392 3393 TestTelephonyConnection c = setupForReDialForDomainSelection( 3394 mPhone0, selectedDomain, preciseDisconnectCause, disconnectCause, true); 3395 3396 CompletableFuture<Integer> future = new CompletableFuture<>(); 3397 doReturn(future).when(mEmergencyCallDomainSelectionConnection) 3398 .reselectDomain(any()); 3399 3400 assertTrue(mTestConnectionService.maybeReselectDomain(c, null, true, 3401 android.telephony.DisconnectCause.NOT_VALID)); 3402 verify(mEmergencyCallDomainSelectionConnection).reselectDomain(any()); 3403 3404 // dialing is canceled 3405 mTestConnectionService.onLocalHangup(c); 3406 3407 // domain selection has completed 3408 future.complete(selectedDomain); 3409 3410 // verify that dialing is discarded 3411 verify(mPhone0, times(0)).dial(anyString(), any(), any()); 3412 } 3413 3414 @Test testDomainSelectionNormalToEmergencyLocalHangupStartEmergencyCall()3415 public void testDomainSelectionNormalToEmergencyLocalHangupStartEmergencyCall() 3416 throws Exception { 3417 setupForCallTest(); 3418 3419 int preciseDisconnectCause = com.android.internal.telephony.CallFailCause.ERROR_UNSPECIFIED; 3420 int disconnectCause = android.telephony.DisconnectCause.ERROR_UNSPECIFIED; 3421 int eccCategory = EMERGENCY_SERVICE_CATEGORY_POLICE; 3422 int selectedDomain = DOMAIN_CS; 3423 3424 setupForDialForDomainSelection(mPhone0, selectedDomain, true); 3425 doReturn(mPhone0).when(mImsPhone).getDefaultPhone(); 3426 3427 TestTelephonyConnection c = setupForReDialForDomainSelection( 3428 mImsPhone, selectedDomain, preciseDisconnectCause, disconnectCause, false); 3429 c.setEmergencyServiceCategory(eccCategory); 3430 c.setAddress(TEST_ADDRESS, TelecomManager.PRESENTATION_ALLOWED); 3431 3432 CompletableFuture<Integer> future = new CompletableFuture<>(); 3433 doReturn(future).when(mEmergencyStateTracker) 3434 .startEmergencyCall(any(), any(), eq(false)); 3435 3436 ImsReasonInfo reasonInfo = new ImsReasonInfo(CODE_SIP_ALTERNATE_EMERGENCY_CALL, 0, null); 3437 assertTrue(mTestConnectionService.maybeReselectDomain(c, reasonInfo, true, 3438 android.telephony.DisconnectCause.NOT_VALID)); 3439 3440 ArgumentCaptor<android.telecom.Connection> connectionCaptor = 3441 ArgumentCaptor.forClass(android.telecom.Connection.class); 3442 3443 verify(mEmergencyStateTracker) 3444 .startEmergencyCall(eq(mPhone0), connectionCaptor.capture(), eq(false)); 3445 verify(mSatelliteSOSMessageRecommender).onEmergencyCallStarted(any(), anyBoolean()); 3446 3447 android.telecom.Connection tc = connectionCaptor.getValue(); 3448 3449 assertNotNull(tc); 3450 assertEquals(TELECOM_CALL_ID1, tc.getTelecomCallId()); 3451 assertEquals(mTestConnectionService.getEmergencyConnection(), tc); 3452 3453 // dialing is canceled 3454 mTestConnectionService.onLocalHangup(c); 3455 3456 // startEmergencyCall has completed 3457 future.complete(NOT_DISCONNECTED); 3458 3459 // verify that createEmergencyConnection is discarded 3460 verify(mEmergencyCallDomainSelectionConnection, times(0)) 3461 .createEmergencyConnection(any(), any()); 3462 } 3463 3464 @Test testDomainSelectionNormalToEmergencyLocalHangupCreateEmergencyConnection()3465 public void testDomainSelectionNormalToEmergencyLocalHangupCreateEmergencyConnection() 3466 throws Exception { 3467 setupForCallTest(); 3468 3469 int preciseDisconnectCause = com.android.internal.telephony.CallFailCause.ERROR_UNSPECIFIED; 3470 int disconnectCause = android.telephony.DisconnectCause.ERROR_UNSPECIFIED; 3471 int eccCategory = EMERGENCY_SERVICE_CATEGORY_POLICE; 3472 int selectedDomain = DOMAIN_CS; 3473 3474 setupForDialForDomainSelection(mPhone0, selectedDomain, true); 3475 doReturn(mPhone0).when(mImsPhone).getDefaultPhone(); 3476 3477 TestTelephonyConnection c = setupForReDialForDomainSelection( 3478 mImsPhone, selectedDomain, preciseDisconnectCause, disconnectCause, false); 3479 c.setEmergencyServiceCategory(eccCategory); 3480 c.setAddress(TEST_ADDRESS, TelecomManager.PRESENTATION_ALLOWED); 3481 3482 CompletableFuture<Integer> future = new CompletableFuture<>(); 3483 doReturn(future).when(mEmergencyCallDomainSelectionConnection) 3484 .createEmergencyConnection(any(), any()); 3485 3486 ImsReasonInfo reasonInfo = new ImsReasonInfo(CODE_SIP_ALTERNATE_EMERGENCY_CALL, 0, null); 3487 assertTrue(mTestConnectionService.maybeReselectDomain(c, reasonInfo, true, 3488 android.telephony.DisconnectCause.NOT_VALID)); 3489 3490 verify(mEmergencyCallDomainSelectionConnection).createEmergencyConnection(any(), any()); 3491 3492 // dialing is canceled 3493 mTestConnectionService.onLocalHangup(c); 3494 3495 // domain selection has completed 3496 future.complete(selectedDomain); 3497 3498 // verify that dialing is discarded 3499 verify(mPhone0, never()).dial(anyString(), any(), any()); 3500 } 3501 3502 @Test testDomainSelectionListenOriginalConnectionConfigChange()3503 public void testDomainSelectionListenOriginalConnectionConfigChange() throws Exception { 3504 setupForCallTest(); 3505 3506 int selectedDomain = DOMAIN_PS; 3507 3508 setupForDialForDomainSelection(mPhone0, selectedDomain, true); 3509 3510 mTestConnectionService.onCreateOutgoingConnection(PHONE_ACCOUNT_HANDLE_1, 3511 createConnectionRequest(PHONE_ACCOUNT_HANDLE_1, 3512 TEST_EMERGENCY_NUMBER, TELECOM_CALL_ID1)); 3513 3514 ArgumentCaptor<android.telecom.Connection> connectionCaptor = 3515 ArgumentCaptor.forClass(android.telecom.Connection.class); 3516 3517 verify(mDomainSelectionResolver) 3518 .getDomainSelectionConnection(eq(mPhone0), eq(SELECTOR_TYPE_CALLING), eq(true)); 3519 verify(mEmergencyStateTracker) 3520 .startEmergencyCall(eq(mPhone0), connectionCaptor.capture(), eq(false)); 3521 verify(mSatelliteSOSMessageRecommender, times(2)).onEmergencyCallStarted(any(), 3522 anyBoolean()); 3523 verify(mEmergencyCallDomainSelectionConnection).createEmergencyConnection(any(), any()); 3524 verify(mPhone0).dial(anyString(), any(), any()); 3525 3526 android.telecom.Connection tc = connectionCaptor.getValue(); 3527 3528 assertNotNull(tc); 3529 assertEquals(TELECOM_CALL_ID1, tc.getTelecomCallId()); 3530 assertEquals(mTestConnectionService.getEmergencyConnection(), tc); 3531 3532 TestTelephonyConnection c = new TestTelephonyConnection(); 3533 mTestConnectionService.setEmergencyConnection(c); 3534 c.setTelecomCallId(TELECOM_CALL_ID1); 3535 c.setIsImsConnection(true); 3536 Connection orgConn = c.getOriginalConnection(); 3537 doReturn(PhoneConstants.PHONE_TYPE_IMS).when(orgConn).getPhoneType(); 3538 3539 TelephonyConnection.TelephonyConnectionListener connectionListener = 3540 mTestConnectionService.getEmergencyConnectionListener(); 3541 TelephonyConnection.TelephonyConnectionListener connectionSatelliteListener = 3542 mTestConnectionService.getEmergencyConnectionSatelliteListener(); 3543 3544 connectionListener.onOriginalConnectionConfigured(c); 3545 3546 verify(mEmergencyStateTracker, times(1)).onEmergencyCallDomainUpdated( 3547 eq(PhoneConstants.PHONE_TYPE_IMS), eq(c)); 3548 3549 verify(mEmergencyStateTracker, times(0)).onEmergencyCallStateChanged( 3550 any(), eq(c)); 3551 verify(mSatelliteSOSMessageRecommender, times(2)) 3552 .onEmergencyCallConnectionStateChanged(eq(TELECOM_CALL_ID1), anyInt()); 3553 3554 c.setActive(); 3555 doReturn(Call.State.ACTIVE).when(orgConn).getState(); 3556 connectionListener.onStateChanged(c, c.getState()); 3557 connectionSatelliteListener.onStateChanged(c, c.getState()); 3558 3559 // ACTIVE sate is notified 3560 verify(mEmergencyStateTracker, times(1)).onEmergencyCallStateChanged( 3561 eq(Call.State.ACTIVE), eq(c)); 3562 verify(mSatelliteSOSMessageRecommender, times(1)) 3563 .onEmergencyCallConnectionStateChanged(eq(TELECOM_CALL_ID1), 3564 eq(android.telecom.Connection.STATE_ACTIVE)); 3565 3566 // state change to HOLDING 3567 c.setOnHold(); 3568 doReturn(Call.State.HOLDING).when(orgConn).getState(); 3569 connectionListener.onStateChanged(c, c.getState()); 3570 connectionSatelliteListener.onStateChanged(c, c.getState()); 3571 3572 // state change not notified any more after CONNECTED once 3573 verify(mEmergencyStateTracker, times(1)).onEmergencyCallStateChanged( 3574 any(), eq(c)); 3575 verify(mSatelliteSOSMessageRecommender, times(3)) 3576 .onEmergencyCallConnectionStateChanged(eq(TELECOM_CALL_ID1), anyInt()); 3577 3578 // state change to ACTIVE again 3579 c.setActive(); 3580 doReturn(Call.State.ACTIVE).when(orgConn).getState(); 3581 connectionListener.onStateChanged(c, c.getState()); 3582 connectionSatelliteListener.onStateChanged(c, c.getState()); 3583 3584 // state change not notified any more after CONNECTED once 3585 verify(mEmergencyStateTracker, times(1)).onEmergencyCallStateChanged( 3586 any(), eq(c)); 3587 verify(mSatelliteSOSMessageRecommender, times(3)) 3588 .onEmergencyCallConnectionStateChanged(eq(TELECOM_CALL_ID1), anyInt()); 3589 3590 // SRVCC happens 3591 c.setIsImsConnection(false); 3592 orgConn = c.getOriginalConnection(); 3593 doReturn(PhoneConstants.PHONE_TYPE_GSM).when(orgConn).getPhoneType(); 3594 connectionListener.onOriginalConnectionConfigured(c); 3595 3596 // domain change notified 3597 verify(mEmergencyStateTracker, times(1)).onEmergencyCallDomainUpdated( 3598 eq(PhoneConstants.PHONE_TYPE_GSM), eq(c)); 3599 3600 // state change to DISCONNECTED 3601 c.setDisconnected(null); 3602 doReturn(Call.State.DISCONNECTED).when(orgConn).getState(); 3603 connectionListener.onStateChanged(c, c.getState()); 3604 connectionSatelliteListener.onStateChanged(c, c.getState()); 3605 3606 // state change not notified 3607 verify(mEmergencyStateTracker, times(1)).onEmergencyCallStateChanged( 3608 any(), eq(c)); 3609 verify(mSatelliteSOSMessageRecommender, times(3)) 3610 .onEmergencyCallConnectionStateChanged(eq(TELECOM_CALL_ID1), anyInt()); 3611 } 3612 3613 @Test testDomainSelectionListenOriginalConnectionPropertiesChange()3614 public void testDomainSelectionListenOriginalConnectionPropertiesChange() throws Exception { 3615 setupForCallTest(); 3616 3617 int selectedDomain = DOMAIN_PS; 3618 3619 setupForDialForDomainSelection(mPhone0, selectedDomain, true); 3620 3621 mTestConnectionService.onCreateOutgoingConnection(PHONE_ACCOUNT_HANDLE_1, 3622 createConnectionRequest(PHONE_ACCOUNT_HANDLE_1, 3623 TEST_EMERGENCY_NUMBER, TELECOM_CALL_ID1)); 3624 3625 ArgumentCaptor<android.telecom.Connection> connectionCaptor = 3626 ArgumentCaptor.forClass(android.telecom.Connection.class); 3627 3628 verify(mDomainSelectionResolver) 3629 .getDomainSelectionConnection(eq(mPhone0), eq(SELECTOR_TYPE_CALLING), eq(true)); 3630 verify(mEmergencyStateTracker) 3631 .startEmergencyCall(eq(mPhone0), connectionCaptor.capture(), eq(false)); 3632 verify(mEmergencyCallDomainSelectionConnection).createEmergencyConnection(any(), any()); 3633 verify(mPhone0).dial(anyString(), any(), any()); 3634 3635 android.telecom.Connection tc = connectionCaptor.getValue(); 3636 3637 assertNotNull(tc); 3638 assertEquals(TELECOM_CALL_ID1, tc.getTelecomCallId()); 3639 assertEquals(mTestConnectionService.getEmergencyConnection(), tc); 3640 3641 TestTelephonyConnection c = new TestTelephonyConnection(); 3642 mTestConnectionService.setEmergencyConnection(c); 3643 c.setIsImsConnection(true); 3644 Connection orgConn = c.getOriginalConnection(); 3645 doReturn(PhoneConstants.PHONE_TYPE_IMS).when(orgConn).getPhoneType(); 3646 3647 TelephonyConnection.TelephonyConnectionListener connectionListener = 3648 mTestConnectionService.getEmergencyConnectionListener(); 3649 3650 doReturn(Call.State.DISCONNECTING).when(orgConn).getState(); 3651 connectionListener.onConnectionPropertiesChanged(c, PROPERTY_WIFI); 3652 3653 verify(mEmergencyStateTracker, times(0)).onEmergencyCallPropertiesChanged( 3654 anyInt(), any()); 3655 3656 doReturn(Call.State.ACTIVE).when(orgConn).getState(); 3657 connectionListener.onConnectionPropertiesChanged(c, PROPERTY_WIFI); 3658 3659 verify(mEmergencyStateTracker, times(1)).onEmergencyCallPropertiesChanged( 3660 eq(PROPERTY_WIFI), eq(c)); 3661 3662 connectionListener.onConnectionPropertiesChanged(c, 0); 3663 3664 verify(mEmergencyStateTracker, times(1)).onEmergencyCallPropertiesChanged( 3665 eq(0), eq(c)); 3666 } 3667 3668 @Test testDomainSelectionTempFailure()3669 public void testDomainSelectionTempFailure() throws Exception { 3670 setupForCallTest(); 3671 3672 int preciseDisconnectCause = 3673 com.android.internal.telephony.CallFailCause.EMERGENCY_TEMP_FAILURE; 3674 int disconnectCause = android.telephony.DisconnectCause.EMERGENCY_TEMP_FAILURE; 3675 int selectedDomain = DOMAIN_CS; 3676 3677 TestTelephonyConnection c = setupForReDialForDomainSelection( 3678 mPhone0, selectedDomain, preciseDisconnectCause, disconnectCause, true); 3679 3680 doReturn(new CompletableFuture()).when(mEmergencyCallDomainSelectionConnection) 3681 .reselectDomain(any()); 3682 3683 assertTrue(mTestConnectionService.maybeReselectDomain(c, null, true, 3684 android.telephony.DisconnectCause.NOT_VALID)); 3685 verify(mEmergencyCallDomainSelectionConnection).reselectDomain(any()); 3686 } 3687 3688 @Test testDomainSelectionPermFailure()3689 public void testDomainSelectionPermFailure() throws Exception { 3690 setupForCallTest(); 3691 3692 int preciseDisconnectCause = 3693 com.android.internal.telephony.CallFailCause.EMERGENCY_PERM_FAILURE; 3694 int disconnectCause = android.telephony.DisconnectCause.EMERGENCY_PERM_FAILURE; 3695 int selectedDomain = DOMAIN_CS; 3696 3697 TestTelephonyConnection c = setupForReDialForDomainSelection( 3698 mPhone0, selectedDomain, preciseDisconnectCause, disconnectCause, true); 3699 3700 doReturn(new CompletableFuture()).when(mEmergencyCallDomainSelectionConnection) 3701 .reselectDomain(any()); 3702 3703 assertTrue(mTestConnectionService.maybeReselectDomain(c, null, true, 3704 android.telephony.DisconnectCause.NOT_VALID)); 3705 verify(mEmergencyCallDomainSelectionConnection).reselectDomain(any()); 3706 } 3707 3708 @Test testDomainSelectionWithMmiCode()3709 public void testDomainSelectionWithMmiCode() { 3710 //UT domain selection should not be handled by new domain selector. 3711 doNothing().when(mContext).startActivityAsUser(any(), any()); 3712 setupForCallTest(); 3713 setupForDialForDomainSelection(mPhone0, 0, false); 3714 mTestConnectionService.onCreateOutgoingConnection(PHONE_ACCOUNT_HANDLE_1, 3715 createConnectionRequest(PHONE_ACCOUNT_HANDLE_1, "*%2321%23", TELECOM_CALL_ID1)); 3716 3717 verifyZeroInteractions(mNormalCallDomainSelectionConnection); 3718 } 3719 3720 @Test testNormalCallPsDomainSelection()3721 public void testNormalCallPsDomainSelection() throws Exception { 3722 setupForCallTest(); 3723 int selectedDomain = DOMAIN_PS; 3724 setupForDialForDomainSelection(mPhone0, selectedDomain, false); 3725 3726 mTestConnectionService.onCreateOutgoingConnection(PHONE_ACCOUNT_HANDLE_1, 3727 createConnectionRequest(PHONE_ACCOUNT_HANDLE_1, "1234", TELECOM_CALL_ID1)); 3728 3729 verify(mDomainSelectionResolver) 3730 .getDomainSelectionConnection(eq(mPhone0), eq(SELECTOR_TYPE_CALLING), eq(false)); 3731 verify(mNormalCallDomainSelectionConnection).createNormalConnection(any(), any()); 3732 verify(mSatelliteSOSMessageRecommender, never()).onEmergencyCallStarted(any(), 3733 anyBoolean()); 3734 3735 ArgumentCaptor<DialArgs> argsCaptor = ArgumentCaptor.forClass(DialArgs.class); 3736 3737 verify(mPhone0).dial(anyString(), argsCaptor.capture(), any()); 3738 DialArgs dialArgs = argsCaptor.getValue(); 3739 assertNotNull("DialArgs param is null", dialArgs); 3740 assertNotNull("intentExtras is null", dialArgs.intentExtras); 3741 assertTrue(dialArgs.intentExtras.containsKey(PhoneConstants.EXTRA_DIAL_DOMAIN)); 3742 assertEquals( 3743 selectedDomain, dialArgs.intentExtras.getInt(PhoneConstants.EXTRA_DIAL_DOMAIN, -1)); 3744 } 3745 3746 @Test testNormalCallCsDomainSelection()3747 public void testNormalCallCsDomainSelection() throws Exception { 3748 setupForCallTest(); 3749 int selectedDomain = DOMAIN_CS; 3750 setupForDialForDomainSelection(mPhone0, selectedDomain, false); 3751 3752 mTestConnectionService.onCreateOutgoingConnection(PHONE_ACCOUNT_HANDLE_1, 3753 createConnectionRequest(PHONE_ACCOUNT_HANDLE_1, "1234", TELECOM_CALL_ID1)); 3754 3755 verify(mDomainSelectionResolver) 3756 .getDomainSelectionConnection(eq(mPhone0), eq(SELECTOR_TYPE_CALLING), eq(false)); 3757 verify(mNormalCallDomainSelectionConnection).createNormalConnection(any(), any()); 3758 verify(mSatelliteSOSMessageRecommender, never()).onEmergencyCallStarted(any(), 3759 anyBoolean()); 3760 3761 ArgumentCaptor<DialArgs> argsCaptor = ArgumentCaptor.forClass(DialArgs.class); 3762 3763 verify(mPhone0).dial(anyString(), argsCaptor.capture(), any()); 3764 DialArgs dialArgs = argsCaptor.getValue(); 3765 assertNotNull("DialArgs param is null", dialArgs); 3766 assertNotNull("intentExtras is null", dialArgs.intentExtras); 3767 assertTrue(dialArgs.intentExtras.containsKey(PhoneConstants.EXTRA_DIAL_DOMAIN)); 3768 assertEquals( 3769 selectedDomain, dialArgs.intentExtras.getInt(PhoneConstants.EXTRA_DIAL_DOMAIN, -1)); 3770 } 3771 3772 @Test testNormalCallSatelliteEnabled()3773 public void testNormalCallSatelliteEnabled() { 3774 setupForCallTest(); 3775 doReturn(true).when(mSatelliteController).isSatelliteEnabledOrBeingEnabled(); 3776 3777 mConnection = mTestConnectionService.onCreateOutgoingConnection(PHONE_ACCOUNT_HANDLE_1, 3778 createConnectionRequest(PHONE_ACCOUNT_HANDLE_1, "1234", TELECOM_CALL_ID1)); 3779 DisconnectCause disconnectCause = mConnection.getDisconnectCause(); 3780 assertEquals(android.telephony.DisconnectCause.SATELLITE_ENABLED, 3781 disconnectCause.getTelephonyDisconnectCause()); 3782 assertEquals(DISCONNECT_REASON_SATELLITE_ENABLED, disconnectCause.getReason()); 3783 } 3784 3785 @Test testEmergencyCallSatelliteEnabled_blockEmergencyCall()3786 public void testEmergencyCallSatelliteEnabled_blockEmergencyCall() { 3787 setupForCallTest(); 3788 doReturn(true).when(mSatelliteController).isSatelliteEnabledOrBeingEnabled(); 3789 doReturn(false).when(mMockResources).getBoolean(anyInt()); 3790 doReturn(true).when(mTelephonyManagerProxy).isCurrentEmergencyNumber( 3791 anyString()); 3792 3793 // Simulates an outgoing emergency call. 3794 mConnection = mTestConnectionService.onCreateOutgoingConnection(PHONE_ACCOUNT_HANDLE_1, 3795 createConnectionRequest(PHONE_ACCOUNT_HANDLE_1, 3796 TEST_EMERGENCY_NUMBER, TELECOM_CALL_ID1)); 3797 DisconnectCause disconnectCause = mConnection.getDisconnectCause(); 3798 assertEquals(android.telephony.DisconnectCause.SATELLITE_ENABLED, 3799 disconnectCause.getTelephonyDisconnectCause()); 3800 assertEquals(DISCONNECT_REASON_SATELLITE_ENABLED, disconnectCause.getReason()); 3801 } 3802 3803 @Test testNormalCallUsingNonTerrestrialNetwork_enableFlag()3804 public void testNormalCallUsingNonTerrestrialNetwork_enableFlag() throws Exception { 3805 mSetFlagsRule.enableFlags(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG); 3806 3807 setupForCallTest(); 3808 // Call is not supported while using satellite 3809 when(mSatelliteController.isInSatelliteModeForCarrierRoaming(any())).thenReturn(true); 3810 when(mSatelliteController.getCapabilitiesForCarrierRoamingSatelliteMode(any())) 3811 .thenReturn(List.of(NetworkRegistrationInfo.SERVICE_TYPE_DATA)); 3812 3813 mConnection = mTestConnectionService.onCreateOutgoingConnection(PHONE_ACCOUNT_HANDLE_1, 3814 createConnectionRequest(PHONE_ACCOUNT_HANDLE_1, "1234", TELECOM_CALL_ID1)); 3815 DisconnectCause disconnectCause = mConnection.getDisconnectCause(); 3816 assertEquals(android.telephony.DisconnectCause.SATELLITE_ENABLED, 3817 disconnectCause.getTelephonyDisconnectCause()); 3818 assertEquals(DISCONNECT_REASON_CARRIER_ROAMING_SATELLITE_MODE, disconnectCause.getReason()); 3819 3820 // Call is supported while using satellite 3821 when(mSatelliteController.getCapabilitiesForCarrierRoamingSatelliteMode(any())) 3822 .thenReturn(List.of(NetworkRegistrationInfo.SERVICE_TYPE_VOICE)); 3823 3824 // UnsupportedOperationException is thrown as we cannot perform actual call 3825 assertThrows(UnsupportedOperationException.class, () -> mTestConnectionService 3826 .onCreateOutgoingConnection(PHONE_ACCOUNT_HANDLE_1, 3827 createConnectionRequest(PHONE_ACCOUNT_HANDLE_1, "1234", "TC@2"))); 3828 } 3829 3830 @Test testNormalCallUsingSatelliteConnectedWithinHysteresisTime()3831 public void testNormalCallUsingSatelliteConnectedWithinHysteresisTime() throws Exception { 3832 mSetFlagsRule.enableFlags(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG); 3833 3834 // Call is not supported when device is connected to satellite within hysteresis time 3835 setupForCallTest(); 3836 when(mSatelliteController.isInSatelliteModeForCarrierRoaming(any())).thenReturn(true); 3837 when(mSatelliteController.getCapabilitiesForCarrierRoamingSatelliteMode(any())) 3838 .thenReturn(List.of(NetworkRegistrationInfo.SERVICE_TYPE_DATA)); 3839 3840 mConnection = mTestConnectionService.onCreateOutgoingConnection(PHONE_ACCOUNT_HANDLE_1, 3841 createConnectionRequest(PHONE_ACCOUNT_HANDLE_1, "1234", TELECOM_CALL_ID1)); 3842 DisconnectCause disconnectCause = mConnection.getDisconnectCause(); 3843 assertEquals(android.telephony.DisconnectCause.SATELLITE_ENABLED, 3844 disconnectCause.getTelephonyDisconnectCause()); 3845 assertEquals(DISCONNECT_REASON_CARRIER_ROAMING_SATELLITE_MODE, disconnectCause.getReason()); 3846 3847 // Call is supported when device is connected to satellite within hysteresis time 3848 setupForCallTest(); 3849 when(mSatelliteController.getCapabilitiesForCarrierRoamingSatelliteMode(any())).thenReturn( 3850 List.of(NetworkRegistrationInfo.SERVICE_TYPE_VOICE)); 3851 3852 // UnsupportedOperationException is thrown as we cannot perform actual call 3853 assertThrows(UnsupportedOperationException.class, () -> mTestConnectionService 3854 .onCreateOutgoingConnection(PHONE_ACCOUNT_HANDLE_1, 3855 createConnectionRequest(PHONE_ACCOUNT_HANDLE_1, "1234", "TC@2"))); 3856 } 3857 3858 @Test testNormalCallUsingNonTerrestrialNetwork_disableFlag()3859 public void testNormalCallUsingNonTerrestrialNetwork_disableFlag() throws Exception { 3860 mSetFlagsRule.disableFlags(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG); 3861 3862 setupForCallTest(); 3863 // Flag is disabled, so call is supported while using satellite 3864 when(mSatelliteController.isInSatelliteModeForCarrierRoaming(any())).thenReturn(true); 3865 when(mSatelliteController.getCapabilitiesForCarrierRoamingSatelliteMode(any())).thenReturn( 3866 List.of(NetworkRegistrationInfo.SERVICE_TYPE_VOICE)); 3867 3868 // UnsupportedOperationException is thrown as we cannot perform actual call 3869 assertThrows(UnsupportedOperationException.class, () -> mTestConnectionService 3870 .onCreateOutgoingConnection(PHONE_ACCOUNT_HANDLE_1, 3871 createConnectionRequest(PHONE_ACCOUNT_HANDLE_1, "1234", TELECOM_CALL_ID1))); 3872 } 3873 3874 @Test testNormalCallUsingNonTerrestrialNetwork_canMakeWifiCall()3875 public void testNormalCallUsingNonTerrestrialNetwork_canMakeWifiCall() throws Exception { 3876 mSetFlagsRule.enableFlags(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG); 3877 3878 setupForCallTest(); 3879 // Call is not supported while using satellite 3880 when(mSatelliteController.isInSatelliteModeForCarrierRoaming(any())).thenReturn(true); 3881 when(mSatelliteController.getCapabilitiesForCarrierRoamingSatelliteMode(any())) 3882 .thenReturn(List.of(NetworkRegistrationInfo.SERVICE_TYPE_DATA)); 3883 // Wi-Fi call is possible 3884 doReturn(true).when(mImsPhone).canMakeWifiCall(); 3885 when(mPhone0.getImsPhone()).thenReturn(mImsPhone); 3886 3887 // UnsupportedOperationException is thrown as we cannot perform actual call 3888 assertThrows(UnsupportedOperationException.class, () -> mTestConnectionService 3889 .onCreateOutgoingConnection(PHONE_ACCOUNT_HANDLE_1, 3890 createConnectionRequest(PHONE_ACCOUNT_HANDLE_1, "1234", TELECOM_CALL_ID1))); 3891 } 3892 3893 @Test testIsAvailableForEmergencyCallsNotForCrossSim()3894 public void testIsAvailableForEmergencyCallsNotForCrossSim() { 3895 Phone mockPhone = Mockito.mock(Phone.class); 3896 when(mockPhone.getImsRegistrationTech()).thenReturn( 3897 ImsRegistrationImplBase.REGISTRATION_TECH_CROSS_SIM); 3898 assertFalse(mTestConnectionService.isAvailableForEmergencyCalls(mockPhone, 3899 EmergencyNumber.EMERGENCY_CALL_ROUTING_EMERGENCY)); 3900 assertFalse(mTestConnectionService.isAvailableForEmergencyCalls(mockPhone, 3901 EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL)); 3902 assertFalse(mTestConnectionService.isAvailableForEmergencyCalls(mockPhone, 3903 EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN)); 3904 } 3905 3906 @Test testIsAvailableForEmergencyCallsUsingNonTerrestrialNetwork_enableFlag()3907 public void testIsAvailableForEmergencyCallsUsingNonTerrestrialNetwork_enableFlag() { 3908 mSetFlagsRule.enableFlags(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG); 3909 3910 // Call is not supported while using satellite 3911 when(mSatelliteController.isInSatelliteModeForCarrierRoaming(any())).thenReturn(true); 3912 when(mSatelliteController.getCapabilitiesForCarrierRoamingSatelliteMode(any())) 3913 .thenReturn(List.of(NetworkRegistrationInfo.SERVICE_TYPE_DATA)); 3914 Phone mockPhone = Mockito.mock(Phone.class); 3915 ServiceState ss = new ServiceState(); 3916 ss.setEmergencyOnly(true); 3917 ss.setState(ServiceState.STATE_EMERGENCY_ONLY); 3918 when(mockPhone.getServiceState()).thenReturn(ss); 3919 when(mPhoneFactoryProxy.getPhones()).thenReturn(new Phone[] {mockPhone}); 3920 3921 assertFalse(mTestConnectionService.isAvailableForEmergencyCalls(mockPhone, 3922 EmergencyNumber.EMERGENCY_CALL_ROUTING_EMERGENCY)); 3923 assertFalse(mTestConnectionService.isAvailableForEmergencyCalls(mockPhone, 3924 EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL)); 3925 assertFalse(mTestConnectionService.isAvailableForEmergencyCalls(mockPhone, 3926 EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN)); 3927 } 3928 3929 @Test testIsAvailableForEmergencyCallsUsingNonTerrestrialNetwork_disableFlag()3930 public void testIsAvailableForEmergencyCallsUsingNonTerrestrialNetwork_disableFlag() { 3931 mSetFlagsRule.disableFlags(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG); 3932 3933 // Call is supported while using satellite 3934 when(mSatelliteController.isInSatelliteModeForCarrierRoaming(any())).thenReturn(true); 3935 when(mSatelliteController.getCapabilitiesForCarrierRoamingSatelliteMode(any())) 3936 .thenReturn(List.of(NetworkRegistrationInfo.SERVICE_TYPE_VOICE)); 3937 Phone mockPhone = Mockito.mock(Phone.class); 3938 ServiceState ss = new ServiceState(); 3939 ss.setEmergencyOnly(true); 3940 ss.setState(ServiceState.STATE_EMERGENCY_ONLY); 3941 when(mockPhone.getServiceState()).thenReturn(ss); 3942 3943 when(mPhoneFactoryProxy.getPhones()).thenReturn(new Phone[] {mockPhone}); 3944 3945 assertTrue(mTestConnectionService.isAvailableForEmergencyCalls(mockPhone, 3946 EmergencyNumber.EMERGENCY_CALL_ROUTING_EMERGENCY)); 3947 assertFalse(mTestConnectionService.isAvailableForEmergencyCalls(mockPhone, 3948 EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL)); 3949 assertTrue(mTestConnectionService.isAvailableForEmergencyCalls(mockPhone, 3950 EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN)); 3951 } 3952 3953 @Test testIsAvailableForEmergencyCallsUsingNTN_CellularAvailable()3954 public void testIsAvailableForEmergencyCallsUsingNTN_CellularAvailable() { 3955 mSetFlagsRule.enableFlags(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG); 3956 3957 // Call is not supported while using satellite 3958 when(mSatelliteController.isInSatelliteModeForCarrierRoaming(any())).thenReturn(true); 3959 when(mSatelliteController.getCapabilitiesForCarrierRoamingSatelliteMode(any())) 3960 .thenReturn(List.of(NetworkRegistrationInfo.SERVICE_TYPE_DATA)); 3961 3962 Phone mockPhone = Mockito.mock(Phone.class); 3963 ServiceState ss = new ServiceState(); 3964 ss.setEmergencyOnly(true); 3965 ss.setState(ServiceState.STATE_EMERGENCY_ONLY); 3966 when(mockPhone.getServiceState()).thenReturn(ss); 3967 3968 // Phone2 is in limited service 3969 Phone mockPhone2 = Mockito.mock(Phone.class); 3970 ServiceState ss2 = new ServiceState(); 3971 ss2.setEmergencyOnly(true); 3972 ss2.setState(ServiceState.STATE_EMERGENCY_ONLY); 3973 when(mockPhone2.getServiceState()).thenReturn(ss2); 3974 3975 Phone[] phones = {mockPhone, mockPhone2}; 3976 when(mPhoneFactoryProxy.getPhones()).thenReturn(phones); 3977 3978 assertFalse(mTestConnectionService.isAvailableForEmergencyCalls(mockPhone, 3979 EmergencyNumber.EMERGENCY_CALL_ROUTING_EMERGENCY)); 3980 assertFalse(mTestConnectionService.isAvailableForEmergencyCalls(mockPhone, 3981 EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL)); 3982 assertFalse(mTestConnectionService.isAvailableForEmergencyCalls(mockPhone, 3983 EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN)); 3984 } 3985 3986 @Test testIsAvailableForEmergencyCallsUsingNTN_CellularNotAvailable()3987 public void testIsAvailableForEmergencyCallsUsingNTN_CellularNotAvailable() { 3988 mSetFlagsRule.enableFlags(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG); 3989 3990 // Call is not supported while using satellite 3991 when(mSatelliteController.isInSatelliteModeForCarrierRoaming(any())).thenReturn(true); 3992 when(mSatelliteController.getCapabilitiesForCarrierRoamingSatelliteMode(any())) 3993 .thenReturn(List.of(NetworkRegistrationInfo.SERVICE_TYPE_DATA)); 3994 3995 NetworkRegistrationInfo nri = new NetworkRegistrationInfo.Builder() 3996 .setIsNonTerrestrialNetwork(true) 3997 .setAvailableServices(List.of(NetworkRegistrationInfo.SERVICE_TYPE_DATA)) 3998 .build(); 3999 Phone mockPhone = Mockito.mock(Phone.class); 4000 ServiceState ss = new ServiceState(); 4001 ss.addNetworkRegistrationInfo(nri); 4002 ss.setEmergencyOnly(true); 4003 ss.setState(ServiceState.STATE_EMERGENCY_ONLY); 4004 when(mockPhone.getServiceState()).thenReturn(ss); 4005 4006 // Phone2 is out of service 4007 Phone mockPhone2 = Mockito.mock(Phone.class); 4008 ServiceState ss2 = new ServiceState(); 4009 ss2.setEmergencyOnly(false); 4010 ss2.setState(ServiceState.STATE_OUT_OF_SERVICE); 4011 when(mockPhone2.getServiceState()).thenReturn(ss2); 4012 4013 Phone[] phones = {mockPhone, mockPhone2}; 4014 when(mPhoneFactoryProxy.getPhones()).thenReturn(phones); 4015 4016 assertTrue(mTestConnectionService.isAvailableForEmergencyCalls(mockPhone, 4017 EmergencyNumber.EMERGENCY_CALL_ROUTING_EMERGENCY)); 4018 assertFalse(mTestConnectionService.isAvailableForEmergencyCalls(mockPhone, 4019 EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL)); 4020 assertTrue(mTestConnectionService.isAvailableForEmergencyCalls(mockPhone, 4021 EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN)); 4022 } 4023 4024 @Test testIsAvailableForEmergencyCallsForEmergencyRoutingInEmergencyOnly()4025 public void testIsAvailableForEmergencyCallsForEmergencyRoutingInEmergencyOnly() { 4026 ServiceState mockService = Mockito.mock(ServiceState.class); 4027 when(mockService.isEmergencyOnly()).thenReturn(true); 4028 when(mockService.getState()).thenReturn(ServiceState.STATE_EMERGENCY_ONLY); 4029 4030 Phone mockPhone = Mockito.mock(Phone.class); 4031 when(mockPhone.getImsRegistrationTech()).thenReturn( 4032 ImsRegistrationImplBase.REGISTRATION_TECH_LTE); 4033 when(mockPhone.getServiceState()).thenReturn(mockService); 4034 4035 assertTrue(mTestConnectionService.isAvailableForEmergencyCalls(mockPhone, 4036 EmergencyNumber.EMERGENCY_CALL_ROUTING_EMERGENCY)); 4037 assertFalse(mTestConnectionService.isAvailableForEmergencyCalls(mockPhone, 4038 EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL)); 4039 assertTrue(mTestConnectionService.isAvailableForEmergencyCalls(mockPhone, 4040 EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN)); 4041 } 4042 4043 @Test testIsAvailableForEmergencyCallsForEmergencyRoutingInService()4044 public void testIsAvailableForEmergencyCallsForEmergencyRoutingInService() { 4045 ServiceState mockService = Mockito.mock(ServiceState.class); 4046 when(mockService.isEmergencyOnly()).thenReturn(false); 4047 when(mockService.getState()).thenReturn(ServiceState.STATE_IN_SERVICE); 4048 4049 Phone mockPhone = Mockito.mock(Phone.class); 4050 when(mockPhone.getImsRegistrationTech()).thenReturn( 4051 ImsRegistrationImplBase.REGISTRATION_TECH_LTE); 4052 when(mockPhone.getServiceState()).thenReturn(mockService); 4053 4054 assertTrue(mTestConnectionService.isAvailableForEmergencyCalls(mockPhone, 4055 EmergencyNumber.EMERGENCY_CALL_ROUTING_EMERGENCY)); 4056 assertTrue(mTestConnectionService.isAvailableForEmergencyCalls(mockPhone, 4057 EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL)); 4058 assertTrue(mTestConnectionService.isAvailableForEmergencyCalls(mockPhone, 4059 EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN)); 4060 } 4061 4062 /** 4063 * Verify that is the carrier config indicates that the carrier does not prefer to use an in 4064 * service sim for a normal routed emergency call that we'll get no result. 4065 */ 4066 @Test testGetPhoneForNormalRoutedEmergencyCallWhenCarrierDoesntSupport()4067 public void testGetPhoneForNormalRoutedEmergencyCallWhenCarrierDoesntSupport() { 4068 ServiceState mockService = Mockito.mock(ServiceState.class); 4069 when(mockService.isEmergencyOnly()).thenReturn(false); 4070 when(mockService.getState()).thenReturn(ServiceState.STATE_IN_SERVICE); 4071 4072 Phone mockPhone = Mockito.mock(Phone.class); 4073 when(mockPhone.shouldPreferInServiceSimForNormalRoutedEmergencyCall()).thenReturn( 4074 false); 4075 setupMockEmergencyNumbers(mockPhone, List.of(MOCK_NORMAL_NUMBER)); 4076 when(mPhoneFactoryProxy.getPhones()).thenReturn(new Phone[] {mockPhone}); 4077 4078 assertNull(mTestConnectionService.getPhoneForNormalRoutedEmergencyCall( 4079 NORMAL_ROUTED_EMERGENCY_NUMBER)); 4080 } 4081 4082 /** 4083 * Verify that is the carrier config indicates that the carrier prefers to use an in service sim 4084 * for a normal routed emergency call that we'll get the in service sim that supports it. 4085 */ 4086 @Test testGetPhoneForNormalRoutedEmergencyCallWhenCarrierDoesSupport()4087 public void testGetPhoneForNormalRoutedEmergencyCallWhenCarrierDoesSupport() { 4088 ServiceState mockService = Mockito.mock(ServiceState.class); 4089 when(mockService.isEmergencyOnly()).thenReturn(false); 4090 when(mockService.getState()).thenReturn(ServiceState.STATE_IN_SERVICE); 4091 4092 Phone mockPhone = Mockito.mock(Phone.class); 4093 when(mockPhone.shouldPreferInServiceSimForNormalRoutedEmergencyCall()).thenReturn( 4094 true); 4095 when(mockPhone.getServiceState()).thenReturn(mockService); 4096 setupMockEmergencyNumbers(mockPhone, List.of(MOCK_NORMAL_NUMBER)); 4097 when(mPhoneFactoryProxy.getPhones()).thenReturn(new Phone[] {mockPhone}); 4098 4099 assertEquals(mockPhone, 4100 mTestConnectionService.getPhoneForNormalRoutedEmergencyCall( 4101 NORMAL_ROUTED_EMERGENCY_NUMBER)); 4102 } 4103 4104 /** 4105 * Verify where there are two sims, one in limited service, and another in full service, if the 4106 * carrier prefers to use an in-service sim, we choose the in-service sim. 4107 */ 4108 @Test testGetPhoneForNormalRoutedEmergencyCallWhenCarrierDoesSupportMultiSim()4109 public void testGetPhoneForNormalRoutedEmergencyCallWhenCarrierDoesSupportMultiSim() { 4110 ServiceState mockInService = Mockito.mock(ServiceState.class); 4111 when(mockInService.isEmergencyOnly()).thenReturn(false); 4112 when(mockInService.getState()).thenReturn(ServiceState.STATE_IN_SERVICE); 4113 ServiceState mockLimitedService = Mockito.mock(ServiceState.class); 4114 when(mockLimitedService.isEmergencyOnly()).thenReturn(true); 4115 when(mockLimitedService.getState()).thenReturn(ServiceState.STATE_EMERGENCY_ONLY); 4116 4117 Phone mockInservicePhone = Mockito.mock(Phone.class); 4118 when(mockInservicePhone.shouldPreferInServiceSimForNormalRoutedEmergencyCall()).thenReturn( 4119 true); 4120 when(mockInservicePhone.getServiceState()).thenReturn(mockInService); 4121 setupMockEmergencyNumbers(mockInservicePhone, List.of(MOCK_NORMAL_NUMBER)); 4122 4123 Phone mockLimitedServicePhone = Mockito.mock(Phone.class); 4124 when(mockLimitedServicePhone.shouldPreferInServiceSimForNormalRoutedEmergencyCall()) 4125 .thenReturn(true); 4126 when(mockLimitedServicePhone.getServiceState()).thenReturn(mockLimitedService); 4127 setupMockEmergencyNumbers(mockLimitedServicePhone, List.of(MOCK_NORMAL_NUMBER)); 4128 4129 when(mPhoneFactoryProxy.getPhones()).thenReturn(new Phone[] {mockLimitedServicePhone, 4130 mockInservicePhone}); 4131 4132 assertEquals(mockInservicePhone, 4133 mTestConnectionService.getPhoneForNormalRoutedEmergencyCall( 4134 NORMAL_ROUTED_EMERGENCY_NUMBER)); 4135 } 4136 4137 /** 4138 * Verify where there are two sims, we choose the sim in emergency callback mode for the 4139 * next emergency call. 4140 */ 4141 @Test testGetPhoneInEmergencyCallbackModeMultiSim()4142 public void testGetPhoneInEmergencyCallbackModeMultiSim() { 4143 Phone mockPhone1 = Mockito.mock(Phone.class); 4144 Phone mockPhone2 = Mockito.mock(Phone.class); 4145 4146 when(mPhoneFactoryProxy.getPhones()).thenReturn( 4147 new Phone[] {mockPhone1, mockPhone2}); 4148 4149 doReturn(false).when(mEmergencyStateTracker).isInEcm(eq(mockPhone1)); 4150 doReturn(true).when(mEmergencyStateTracker).isInEcm(eq(mockPhone2)); 4151 4152 // Only applicable for AP domain seleciton service 4153 assertNull(mTestConnectionService.getPhoneInEmergencyCallbackMode()); 4154 4155 doReturn(true).when(mDomainSelectionResolver).isDomainSelectionSupported(); 4156 4157 assertEquals(mockPhone2, 4158 mTestConnectionService.getPhoneInEmergencyCallbackMode()); 4159 } 4160 setupMockEmergencyNumbers(Phone mockPhone, List<EmergencyNumber> numbers)4161 private void setupMockEmergencyNumbers(Phone mockPhone, List<EmergencyNumber> numbers) { 4162 EmergencyNumberTracker emergencyNumberTracker = Mockito.mock(EmergencyNumberTracker.class); 4163 // Yuck. There should really be a fake emergency number class which makes it easy to inject 4164 // the numbers for testing. 4165 ArrayMap<String, List<EmergencyNumber>> numbersMap = new ArrayMap<>(); 4166 for (EmergencyNumber number : numbers) { 4167 when(emergencyNumberTracker.getEmergencyNumber(eq(number.getNumber()))) 4168 .thenReturn(number); 4169 if (!numbersMap.containsKey(number.getNumber())) { 4170 numbersMap.put(number.getNumber(), new ArrayList<>()); 4171 } 4172 numbersMap.get(number.getNumber()).add(number); 4173 } 4174 // Double yuck. 4175 for (Map.Entry<String, List<EmergencyNumber>> entry : numbersMap.entrySet()) { 4176 when(emergencyNumberTracker.getEmergencyNumbers(eq(entry.getKey()))).thenReturn( 4177 entry.getValue()); 4178 } 4179 when(mockPhone.getEmergencyNumberTracker()).thenReturn(emergencyNumberTracker); 4180 } 4181 setupForDialForDomainSelection(Phone mockPhone, int domain, boolean isEmergency)4182 private void setupForDialForDomainSelection(Phone mockPhone, int domain, boolean isEmergency) { 4183 if (isEmergency) { 4184 doReturn(mEmergencyCallDomainSelectionConnection).when(mDomainSelectionResolver) 4185 .getDomainSelectionConnection(any(), anyInt(), eq(true)); 4186 doReturn(CompletableFuture.completedFuture(domain)) 4187 .when(mEmergencyCallDomainSelectionConnection) 4188 .createEmergencyConnection(any(), any()); 4189 doReturn(true).when(mTelephonyManagerProxy).isCurrentEmergencyNumber(anyString()); 4190 } else { 4191 doReturn(mNormalCallDomainSelectionConnection).when(mDomainSelectionResolver) 4192 .getDomainSelectionConnection(any(), eq(SELECTOR_TYPE_CALLING), eq(false)); 4193 doReturn(CompletableFuture.completedFuture(domain)) 4194 .when(mNormalCallDomainSelectionConnection) 4195 .createNormalConnection(any(), any()); 4196 doReturn(false).when(mTelephonyManagerProxy).isCurrentEmergencyNumber(anyString()); 4197 } 4198 4199 doReturn(true).when(mDomainSelectionResolver).isDomainSelectionSupported(); 4200 doReturn(mImsPhone).when(mockPhone).getImsPhone(); 4201 } 4202 setupConnectionServiceInApmForDomainSelection(boolean normalRouting)4203 private Phone setupConnectionServiceInApmForDomainSelection(boolean normalRouting) { 4204 ConnectionRequest connectionRequest = new ConnectionRequest.Builder() 4205 .setAccountHandle(PHONE_ACCOUNT_HANDLE_1) 4206 .setAddress(TEST_ADDRESS) 4207 .build(); 4208 Phone testPhone0 = makeTestPhone(0 /*phoneId*/, ServiceState.STATE_POWER_OFF, 4209 false /*isEmergencyOnly*/); 4210 Phone testPhone1 = makeTestPhone(1 /*phoneId*/, ServiceState.STATE_POWER_OFF, 4211 false /*isEmergencyOnly*/); 4212 doReturn(GSM_PHONE).when(testPhone0).getPhoneType(); 4213 doReturn(GSM_PHONE).when(testPhone1).getPhoneType(); 4214 List<Phone> phones = new ArrayList<>(2); 4215 doReturn(false).when(testPhone0).isRadioOn(); 4216 doReturn(false).when(testPhone1).isRadioOn(); 4217 phones.add(testPhone0); 4218 phones.add(testPhone1); 4219 setPhones(phones); 4220 setupHandleToPhoneMap(PHONE_ACCOUNT_HANDLE_1, testPhone0); 4221 setupDeviceConfig(testPhone0, testPhone1, 0); 4222 setupForDialForDomainSelection(testPhone0, DOMAIN_CS, false); 4223 4224 EmergencyNumber emergencyNumber; 4225 if (normalRouting) { 4226 emergencyNumber = new EmergencyNumber(TEST_ADDRESS.getSchemeSpecificPart(), "", "", 4227 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED, 4228 Collections.emptyList(), 4229 EmergencyNumber.EMERGENCY_NUMBER_SOURCE_DATABASE, 4230 EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL); 4231 } else { 4232 emergencyNumber = setupEmergencyNumber(TEST_ADDRESS); 4233 } 4234 doReturn(true).when(mTelephonyManagerProxy).isCurrentEmergencyNumber(anyString()); 4235 doReturn(emergencyNumber).when(mEmergencyNumberTracker).getEmergencyNumber(anyString()); 4236 doReturn(Arrays.asList(emergencyNumber)).when(mEmergencyNumberTracker).getEmergencyNumbers( 4237 anyString()); 4238 doReturn(2).when(mTelephonyManagerProxy).getPhoneCount(); 4239 4240 mConnection = mTestConnectionService.onCreateOutgoingConnection( 4241 PHONE_ACCOUNT_HANDLE_1, connectionRequest); 4242 assertNotNull("test connection was not set up correctly.", mConnection); 4243 4244 return testPhone0; 4245 } 4246 setupForReDialForDomainSelection( Phone mockPhone, int domain, int preciseDisconnectCause, int disconnectCause, boolean fromEmergency)4247 private TestTelephonyConnection setupForReDialForDomainSelection( 4248 Phone mockPhone, int domain, int preciseDisconnectCause, 4249 int disconnectCause, boolean fromEmergency) throws Exception { 4250 TestTelephonyConnection c = new TestTelephonyConnection(); 4251 try { 4252 if (fromEmergency) { 4253 doReturn(CompletableFuture.completedFuture(domain)) 4254 .when(mEmergencyCallDomainSelectionConnection) 4255 .reselectDomain(any()); 4256 replaceInstance(TelephonyConnectionService.class, 4257 "mEmergencyCallDomainSelectionConnection", 4258 mTestConnectionService, mEmergencyCallDomainSelectionConnection); 4259 replaceInstance(TelephonyConnectionService.class, "mEmergencyConnection", 4260 mTestConnectionService, c); 4261 } else { 4262 doReturn(CompletableFuture.completedFuture(domain)) 4263 .when(mNormalCallDomainSelectionConnection).reselectDomain(any()); 4264 replaceInstance(TelephonyConnectionService.class, "mDomainSelectionConnection", 4265 mTestConnectionService, mNormalCallDomainSelectionConnection); 4266 } 4267 } catch (Exception e) { 4268 // This shouldn't happen 4269 fail(); 4270 } 4271 4272 doReturn(true).when(mDomainSelectionResolver).isDomainSelectionSupported(); 4273 4274 c.setTelecomCallId(TELECOM_CALL_ID1); 4275 c.setMockPhone(mockPhone); 4276 c.setAddress(TEST_ADDRESS, TelecomManager.PRESENTATION_ALLOWED); 4277 4278 Connection oc = c.getOriginalConnection(); 4279 doReturn(disconnectCause).when(oc).getDisconnectCause(); 4280 doReturn(preciseDisconnectCause).when(oc).getPreciseDisconnectCause(); 4281 4282 return c; 4283 } 4284 createTestConnection(PhoneAccountHandle handle, int properties, boolean isEmergency)4285 private SimpleTelephonyConnection createTestConnection(PhoneAccountHandle handle, 4286 int properties, boolean isEmergency) { 4287 SimpleTelephonyConnection connection = new SimpleTelephonyConnection(); 4288 connection.setShouldTreatAsEmergencyCall(isEmergency); 4289 connection.setConnectionProperties(properties); 4290 connection.setPhoneAccountHandle(handle); 4291 return connection; 4292 } 4293 createTestConference(PhoneAccountHandle handle, int properties)4294 private SimpleConference createTestConference(PhoneAccountHandle handle, int properties) { 4295 SimpleConference conference = new SimpleConference(handle); 4296 conference.setConnectionProperties(properties); 4297 return conference; 4298 } 4299 4300 /** 4301 * Setup the mess of mocks for {@link #testSecondCallSameSubWontDisconnect()} and 4302 * {@link #testIncomingDoesntRequestDisconnect()}. 4303 */ setupForCallTest()4304 private void setupForCallTest() { 4305 // Setup a bunch of stuff. Blech. 4306 mTestConnectionService.setReadyForTest(); 4307 mPhone0 = makeTestPhone(0 /*phoneId*/, ServiceState.STATE_IN_SERVICE, 4308 false /*isEmergencyOnly*/); 4309 when(mCall.getState()).thenReturn(Call.State.INCOMING); 4310 when(mCall.getPhone()).thenReturn(mPhone0); 4311 when(mPhone0.getRingingCall()).thenReturn(mCall); 4312 mPhone1 = makeTestPhone(1 /*phoneId*/, ServiceState.STATE_IN_SERVICE, 4313 false /*isEmergencyOnly*/); 4314 when(mCall2.getPhone()).thenReturn(mPhone1); 4315 List<Phone> phones = new ArrayList<>(2); 4316 doReturn(true).when(mPhone0).isRadioOn(); 4317 doReturn(true).when(mPhone1).isRadioOn(); 4318 doReturn(GSM_PHONE).when(mPhone0).getPhoneType(); 4319 doReturn(GSM_PHONE).when(mPhone1).getPhoneType(); 4320 phones.add(mPhone0); 4321 phones.add(mPhone1); 4322 setPhones(phones); 4323 when(mPhoneUtilsProxy.getSubIdForPhoneAccountHandle(eq(PHONE_ACCOUNT_HANDLE_1))) 4324 .thenReturn(0); 4325 when(mSubscriptionManagerProxy.getPhoneId(0)).thenReturn(0); 4326 when(mPhoneFactoryProxy.getPhone(eq(0))).thenReturn(mPhone0); 4327 when(mPhoneUtilsProxy.getSubIdForPhoneAccountHandle(eq(PHONE_ACCOUNT_HANDLE_2))) 4328 .thenReturn(1); 4329 when(mSubscriptionManagerProxy.getPhoneId(1)).thenReturn(1); 4330 when(mPhoneFactoryProxy.getPhone(eq(1))).thenReturn(mPhone1); 4331 setupDeviceConfig(mPhone0, mPhone1, 1); 4332 4333 when(mInternalConnection.getCall()).thenReturn(mCall); 4334 when(mInternalConnection.getState()).thenReturn(Call.State.ACTIVE); 4335 when(mInternalConnection2.getCall()).thenReturn(mCall2); 4336 when(mInternalConnection2.getState()).thenReturn(Call.State.WAITING); 4337 } 4338 4339 /** 4340 * Set up a mock MSIM device with TEST_ADDRESS set as an emergency number. 4341 * @param isRoaming whether it is roaming 4342 * @param setOperatorName whether operator name needs to set 4343 * @param operatorNameLongName the operator long name if needs to set 4344 * @param operatorNameShortName the operator short name if needs to set 4345 * @param operatorNameNumeric the operator numeric name if needs to set 4346 * @return the Phone associated with slot 0. 4347 */ setupConnectionServiceForDelayDial(boolean isRoaming, boolean setOperatorName, String operatorNameLongName, String operatorNameShortName, String operatorNameNumeric)4348 private Phone setupConnectionServiceForDelayDial(boolean isRoaming, boolean setOperatorName, 4349 String operatorNameLongName, String operatorNameShortName, 4350 String operatorNameNumeric) { 4351 ConnectionRequest connectionRequest = new ConnectionRequest.Builder() 4352 .setAccountHandle(PHONE_ACCOUNT_HANDLE_1) 4353 .setAddress(TEST_ADDRESS) 4354 .build(); 4355 Phone testPhone0 = makeTestPhone(0 /*phoneId*/, ServiceState.STATE_IN_SERVICE, 4356 false /*isEmergencyOnly*/); 4357 Phone testPhone1 = makeTestPhone(1 /*phoneId*/, ServiceState.STATE_OUT_OF_SERVICE, 4358 false /*isEmergencyOnly*/); 4359 List<Phone> phones = new ArrayList<>(2); 4360 doReturn(true).when(testPhone0).isRadioOn(); 4361 doReturn(true).when(testPhone1).isRadioOn(); 4362 phones.add(testPhone0); 4363 phones.add(testPhone1); 4364 setPhones(phones); 4365 setupHandleToPhoneMap(PHONE_ACCOUNT_HANDLE_1, testPhone0); 4366 setupDeviceConfig(testPhone0, testPhone1, 1); 4367 doReturn(true).when(mTelephonyManagerProxy).isCurrentEmergencyNumber( 4368 TEST_ADDRESS.getSchemeSpecificPart()); 4369 HashMap<Integer, List<EmergencyNumber>> emergencyNumbers = new HashMap<>(1); 4370 List<EmergencyNumber> numbers = new ArrayList<>(); 4371 numbers.add(setupEmergencyNumber(TEST_ADDRESS)); 4372 emergencyNumbers.put(0 /*subId*/, numbers); 4373 doReturn(emergencyNumbers).when(mTelephonyManagerProxy).getCurrentEmergencyNumberList(); 4374 doReturn(2).when(mTelephonyManagerProxy).getPhoneCount(); 4375 testPhone0.getServiceState().setRoaming(isRoaming); 4376 if (setOperatorName) { 4377 testPhone0.getServiceState().setOperatorName(operatorNameLongName, 4378 operatorNameShortName, operatorNameNumeric); 4379 } 4380 mConnection = mTestConnectionService.onCreateOutgoingConnection( 4381 PHONE_ACCOUNT_HANDLE_1, connectionRequest); 4382 assertNotNull("test connection was not set up correctly.", mConnection); 4383 return testPhone0; 4384 } 4385 4386 /** 4387 * Set up a mock MSIM device with TEST_ADDRESS set as an emergency number in airplane mode. 4388 * @return the Phone associated with slot 0. 4389 */ setupConnectionServiceInApm()4390 private Phone setupConnectionServiceInApm() { 4391 ConnectionRequest connectionRequest = new ConnectionRequest.Builder() 4392 .setAccountHandle(PHONE_ACCOUNT_HANDLE_1) 4393 .setAddress(TEST_ADDRESS) 4394 .build(); 4395 Phone testPhone0 = makeTestPhone(0 /*phoneId*/, ServiceState.STATE_POWER_OFF, 4396 false /*isEmergencyOnly*/); 4397 Phone testPhone1 = makeTestPhone(1 /*phoneId*/, ServiceState.STATE_POWER_OFF, 4398 false /*isEmergencyOnly*/); 4399 doReturn(GSM_PHONE).when(testPhone0).getPhoneType(); 4400 doReturn(GSM_PHONE).when(testPhone1).getPhoneType(); 4401 List<Phone> phones = new ArrayList<>(2); 4402 doReturn(false).when(testPhone0).isRadioOn(); 4403 doReturn(false).when(testPhone1).isRadioOn(); 4404 phones.add(testPhone0); 4405 phones.add(testPhone1); 4406 setPhones(phones); 4407 setupHandleToPhoneMap(PHONE_ACCOUNT_HANDLE_1, testPhone0); 4408 setupDeviceConfig(testPhone0, testPhone1, 0); 4409 doReturn(true).when(mTelephonyManagerProxy).isCurrentEmergencyNumber( 4410 TEST_ADDRESS.getSchemeSpecificPart()); 4411 HashMap<Integer, List<EmergencyNumber>> emergencyNumbers = new HashMap<>(1); 4412 List<EmergencyNumber> numbers = new ArrayList<>(); 4413 numbers.add(setupEmergencyNumber(TEST_ADDRESS)); 4414 emergencyNumbers.put(0 /*subId*/, numbers); 4415 doReturn(emergencyNumbers).when(mTelephonyManagerProxy).getCurrentEmergencyNumberList(); 4416 doReturn(2).when(mTelephonyManagerProxy).getPhoneCount(); 4417 4418 mConnection = mTestConnectionService.onCreateOutgoingConnection( 4419 PHONE_ACCOUNT_HANDLE_1, connectionRequest); 4420 assertNotNull("test connection was not set up correctly.", mConnection); 4421 4422 return testPhone0; 4423 } 4424 setupEmergencyNumber(Uri address)4425 private EmergencyNumber setupEmergencyNumber(Uri address) { 4426 return new EmergencyNumber(address.getSchemeSpecificPart(), "", "", 4427 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED, 4428 Collections.emptyList(), 4429 EmergencyNumber.EMERGENCY_NUMBER_SOURCE_SIM, 4430 EmergencyNumber.EMERGENCY_CALL_ROUTING_EMERGENCY); 4431 } 4432 setupHandleToPhoneMap(PhoneAccountHandle handle, Phone phone)4433 private void setupHandleToPhoneMap(PhoneAccountHandle handle, Phone phone) { 4434 // The specified handle has an id which is subID 4435 doReturn(Integer.parseInt(handle.getId())).when(mPhoneUtilsProxy) 4436 .getSubIdForPhoneAccountHandle(eq(handle)); 4437 // The specified sub id in the passed handle will correspond to the phone's phone id. 4438 doReturn(phone.getPhoneId()).when(mSubscriptionManagerProxy) 4439 .getPhoneId(eq(Integer.parseInt(handle.getId()))); 4440 int phoneId = phone.getPhoneId(); 4441 doReturn(phone).when(mPhoneFactoryProxy).getPhone(eq(phoneId)); 4442 } 4443 getSuppServiceNotification(int notificationType, int code)4444 private AsyncResult getSuppServiceNotification(int notificationType, int code) { 4445 SuppServiceNotification notification = new SuppServiceNotification(); 4446 notification.notificationType = notificationType; 4447 notification.code = code; 4448 return new AsyncResult(null, notification, null); 4449 } 4450 makeTestPhone(int phoneId, int serviceState, boolean isEmergencyOnly)4451 private Phone makeTestPhone(int phoneId, int serviceState, boolean isEmergencyOnly) { 4452 Phone phone = mock(Phone.class); 4453 ServiceState testServiceState = new ServiceState(); 4454 testServiceState.setState(serviceState); 4455 testServiceState.setEmergencyOnly(isEmergencyOnly); 4456 when(phone.getContext()).thenReturn(mContext); 4457 when(phone.getServiceState()).thenReturn(testServiceState); 4458 when(phone.getPhoneId()).thenReturn(phoneId); 4459 when(phone.getDefaultPhone()).thenReturn(phone); 4460 when(phone.getEmergencyNumberTracker()).thenReturn(mEmergencyNumberTracker); 4461 when(phone.getServiceStateTracker()).thenReturn(mSST); 4462 doNothing().when(phone).registerForPreciseCallStateChanged(any(Handler.class), anyInt(), 4463 any(Object.class)); 4464 when(mEmergencyNumberTracker.getEmergencyNumber(anyString())).thenReturn(null); 4465 return phone; 4466 } 4467 4468 // Setup 2 SIM device setupDeviceConfig(Phone slot0Phone, Phone slot1Phone, int defaultVoicePhoneId)4469 private void setupDeviceConfig(Phone slot0Phone, Phone slot1Phone, int defaultVoicePhoneId) { 4470 when(mTelephonyManagerProxy.getPhoneCount()).thenReturn(2); 4471 when(mTelephonyManagerProxy.isConcurrentCallsPossible()).thenReturn(false); 4472 when(mSubscriptionManagerProxy.getDefaultVoicePhoneId()).thenReturn(defaultVoicePhoneId); 4473 when(mPhoneFactoryProxy.getPhone(eq(SLOT_0_PHONE_ID))).thenReturn(slot0Phone); 4474 when(mPhoneFactoryProxy.getPhone(eq(SLOT_1_PHONE_ID))).thenReturn(slot1Phone); 4475 } 4476 setDefaultDataPhoneId(int defaultDataPhoneId)4477 private void setDefaultDataPhoneId(int defaultDataPhoneId) { 4478 when(mSubscriptionManagerProxy.getDefaultDataPhoneId()).thenReturn(defaultDataPhoneId); 4479 } 4480 setPhoneRadioAccessFamily(Phone phone, int radioAccessFamily)4481 private void setPhoneRadioAccessFamily(Phone phone, int radioAccessFamily) { 4482 when(phone.getRadioAccessFamily()).thenReturn(radioAccessFamily); 4483 } 4484 setEmergencySmsMode(Phone phone, boolean isInEmergencySmsMode)4485 private void setEmergencySmsMode(Phone phone, boolean isInEmergencySmsMode) { 4486 when(phone.isInEmergencySmsMode()).thenReturn(isInEmergencySmsMode); 4487 } 4488 setPhoneSlotState(int slotId, int slotState)4489 private void setPhoneSlotState(int slotId, int slotState) { 4490 when(mSubscriptionManagerProxy.getSimStateForSlotIdx(slotId)).thenReturn(slotState); 4491 } 4492 setDefaultPhone(Phone phone)4493 private void setDefaultPhone(Phone phone) { 4494 when(mPhoneFactoryProxy.getDefaultPhone()).thenReturn(phone); 4495 } 4496 setPhones(List<Phone> phones)4497 private void setPhones(List<Phone> phones) { 4498 when(mPhoneFactoryProxy.getPhones()).thenReturn(phones.toArray(new Phone[phones.size()])); 4499 when(mPhoneFactoryProxy.getDefaultPhone()).thenReturn(phones.get(0)); 4500 } 4501 setPhonesDialConnection(Phone phone, Connection c)4502 private void setPhonesDialConnection(Phone phone, Connection c) { 4503 try { 4504 when(phone.dial(anyString(), any(), any())).thenReturn(c); 4505 } catch (CallStateException e) { 4506 // this shouldn't happen 4507 fail(); 4508 } 4509 } 4510 createConnectionRequest( PhoneAccountHandle accountHandle, String address, String callId)4511 private ConnectionRequest createConnectionRequest( 4512 PhoneAccountHandle accountHandle, String address, String callId) { 4513 return new ConnectionRequest.Builder() 4514 .setAccountHandle(accountHandle) 4515 .setAddress(Uri.parse("tel:" + address)) 4516 .setExtras(new Bundle()) 4517 .setTelecomCallId(callId) 4518 .build(); 4519 } 4520 getExecutor()4521 private Executor getExecutor() { 4522 return Runnable::run; 4523 } 4524 } 4525