1 /* 2 * Copyright (C) 2022 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.domainselection; 18 19 import static android.telephony.DomainSelectionService.SELECTOR_TYPE_CALLING; 20 21 import static org.junit.Assert.assertEquals; 22 import static org.junit.Assert.assertFalse; 23 import static org.junit.Assert.assertTrue; 24 import static org.junit.Assert.fail; 25 import static org.mockito.Mockito.any; 26 import static org.mockito.Mockito.doNothing; 27 import static org.mockito.Mockito.doReturn; 28 29 import android.annotation.NonNull; 30 import android.content.Context; 31 import android.net.Uri; 32 import android.os.CancellationSignal; 33 import android.os.HandlerThread; 34 import android.os.Looper; 35 import android.os.PersistableBundle; 36 import android.telecom.PhoneAccount; 37 import android.telecom.TelecomManager; 38 import android.telephony.AccessNetworkConstants; 39 import android.telephony.CarrierConfigManager; 40 import android.telephony.DisconnectCause; 41 import android.telephony.DomainSelectionService; 42 import android.telephony.DomainSelector; 43 import android.telephony.EmergencyRegistrationResult; 44 import android.telephony.NetworkRegistrationInfo; 45 import android.telephony.ServiceState; 46 import android.telephony.SubscriptionManager; 47 import android.telephony.TransportSelectorCallback; 48 import android.telephony.WwanSelectorCallback; 49 import android.telephony.ims.ImsManager; 50 import android.telephony.ims.ImsMmTelManager; 51 import android.telephony.ims.ImsReasonInfo; 52 import android.testing.TestableLooper; 53 import android.util.Log; 54 55 import androidx.test.runner.AndroidJUnit4; 56 57 import com.android.internal.telephony.CallFailCause; 58 59 import org.junit.After; 60 import org.junit.Before; 61 import org.junit.Test; 62 import org.junit.runner.RunWith; 63 import org.mockito.Mock; 64 import org.mockito.MockitoAnnotations; 65 66 import java.util.List; 67 import java.util.function.Consumer; 68 69 /** 70 * Unit tests for DomainSelectorBase. 71 */ 72 @RunWith(AndroidJUnit4.class) 73 public class NormalCallDomainSelectorTest { 74 private static final String TAG = "NormalCallDomainSelectorTest"; 75 76 private static final int SELECTOR_TYPE_UT = 3; 77 private static final int SLOT_ID = 0; 78 private static final int SUB_ID_1 = 1; 79 private static final int SUB_ID_2 = 2; 80 private static final String TEST_CALLID = "01234"; 81 private static final Uri TEST_URI = Uri.fromParts(PhoneAccount.SCHEME_TEL, "123456789", null); 82 83 private HandlerThread mHandlerThread; 84 private NormalCallDomainSelector mNormalCallDomainSelector; 85 private TestableLooper mTestableLooper; 86 @Mock private Context mMockContext; 87 @Mock private CarrierConfigManager mMockCarrierConfigMgr; 88 @Mock private ImsManager mMockImsManager; 89 @Mock private ImsMmTelManager mMockMmTelManager; 90 @Mock private ImsStateTracker mMockImsStateTracker; 91 @Mock private DomainSelectorBase.DestroyListener mMockDestroyListener; 92 @Mock private TelecomManager mMockTelecomManager; 93 94 @Before setUp()95 public void setUp() throws Exception { 96 MockitoAnnotations.initMocks(this); 97 98 doReturn(Context.TELEPHONY_IMS_SERVICE).when(mMockContext) 99 .getSystemServiceName(ImsManager.class); 100 doReturn(mMockImsManager).when(mMockContext) 101 .getSystemService(Context.TELEPHONY_IMS_SERVICE); 102 103 doReturn(Context.CARRIER_CONFIG_SERVICE).when(mMockContext) 104 .getSystemServiceName(CarrierConfigManager.class); 105 doReturn(mMockCarrierConfigMgr).when(mMockContext) 106 .getSystemService(Context.CARRIER_CONFIG_SERVICE); 107 108 doReturn(Context.TELECOM_SERVICE).when(mMockContext) 109 .getSystemServiceName(TelecomManager.class); 110 doReturn(mMockTelecomManager).when(mMockContext) 111 .getSystemService(Context.TELECOM_SERVICE); 112 113 doReturn(mMockMmTelManager).when(mMockImsManager).getImsMmTelManager(SUB_ID_1); 114 doReturn(mMockMmTelManager).when(mMockImsManager).getImsMmTelManager(SUB_ID_2); 115 doNothing().when(mMockImsStateTracker).removeServiceStateListener(any()); 116 doNothing().when(mMockImsStateTracker).removeImsStateListener(any()); 117 doReturn(true).when(mMockImsStateTracker).isMmTelFeatureAvailable(); 118 119 // Set up the looper if it does not exist on the test thread. 120 if (Looper.myLooper() == null) { 121 Looper.prepare(); 122 } 123 124 mHandlerThread = new HandlerThread( 125 NormalCallDomainSelectorTest.class.getSimpleName()); 126 mHandlerThread.start(); 127 128 mNormalCallDomainSelector = new NormalCallDomainSelector(mMockContext, SLOT_ID, SUB_ID_1, 129 mHandlerThread.getLooper(), mMockImsStateTracker, mMockDestroyListener); 130 131 try { 132 setUpTestableLooper(); 133 } catch (Exception e) { 134 fail(e.toString()); 135 } 136 } 137 138 @After tearDown()139 public void tearDown() throws Exception { 140 if (mHandlerThread != null) { 141 mHandlerThread.quit(); 142 } 143 144 if (mTestableLooper != null) { 145 mTestableLooper.destroy(); 146 mTestableLooper = null; 147 } 148 } 149 setUpTestableLooper()150 private void setUpTestableLooper() throws Exception { 151 mTestableLooper = new TestableLooper(mNormalCallDomainSelector.getLooper()); 152 } 153 processAllMessages()154 private void processAllMessages() { 155 Log.d(TAG, "processAllMessages - start"); 156 while (!mTestableLooper.getLooper().getQueue().isIdle()) { 157 mTestableLooper.processAllMessages(); 158 } 159 Log.d(TAG, "processAllMessages - end"); 160 } 161 initialize(ServiceState serviceState, boolean isImsRegistered, boolean isImsRegisteredOverWlan, boolean isImsVoiceCapable, boolean isImsVideoCapable)162 private void initialize(ServiceState serviceState, boolean isImsRegistered, 163 boolean isImsRegisteredOverWlan, boolean isImsVoiceCapable, 164 boolean isImsVideoCapable) { 165 if (serviceState != null) mNormalCallDomainSelector.onServiceStateUpdated(serviceState); 166 doReturn(isImsRegistered).when(mMockImsStateTracker).isImsStateReady(); 167 doReturn(isImsRegistered).when(mMockImsStateTracker).isImsRegistered(); 168 doReturn(isImsVoiceCapable).when(mMockImsStateTracker).isImsVoiceCapable(); 169 doReturn(isImsVideoCapable).when(mMockImsStateTracker).isImsVideoCapable(); 170 doReturn(isImsRegisteredOverWlan).when(mMockImsStateTracker).isImsRegisteredOverWlan(); 171 mNormalCallDomainSelector.onImsRegistrationStateChanged(); 172 mNormalCallDomainSelector.onImsMmTelCapabilitiesChanged(); 173 } 174 175 @Test testInit()176 public void testInit() { 177 assertEquals(SLOT_ID, mNormalCallDomainSelector.getSlotId()); 178 assertEquals(SUB_ID_1, mNormalCallDomainSelector.getSubId()); 179 } 180 181 @Test testInitialState()182 public void testInitialState() { 183 assertEquals(NormalCallDomainSelector.SelectorState.INACTIVE, 184 mNormalCallDomainSelector.getSelectorState()); 185 } 186 187 @Test testDestroyedState()188 public void testDestroyedState() { 189 mNormalCallDomainSelector.destroy(); 190 191 assertEquals(NormalCallDomainSelector.SelectorState.DESTROYED, 192 mNormalCallDomainSelector.getSelectorState()); 193 } 194 195 @Test testDestroyedDuringActiveState()196 public void testDestroyedDuringActiveState() { 197 TestTransportSelectorCallback transportSelectorCallback = 198 new TestTransportSelectorCallback(mNormalCallDomainSelector); 199 200 DomainSelectionService.SelectionAttributes attributes = 201 new DomainSelectionService.SelectionAttributes.Builder( 202 SLOT_ID, SUB_ID_1, SELECTOR_TYPE_CALLING) 203 .setAddress(TEST_URI) 204 .setCallId(TEST_CALLID) 205 .setEmergency(false) 206 .setVideoCall(true) 207 .setExitedFromAirplaneMode(false) 208 .build(); 209 210 mNormalCallDomainSelector.selectDomain(attributes, transportSelectorCallback); 211 212 assertEquals(NormalCallDomainSelector.SelectorState.ACTIVE, 213 mNormalCallDomainSelector.getSelectorState()); 214 215 mNormalCallDomainSelector.destroy(); 216 217 assertEquals(NormalCallDomainSelector.SelectorState.DESTROYED, 218 mNormalCallDomainSelector.getSelectorState()); 219 } 220 221 @Test testSelectDomainInputParams()222 public void testSelectDomainInputParams() { 223 TestTransportSelectorCallback transportSelectorCallback = 224 new TestTransportSelectorCallback(mNormalCallDomainSelector); 225 226 DomainSelectionService.SelectionAttributes attributes = 227 new DomainSelectionService.SelectionAttributes.Builder( 228 SLOT_ID, SUB_ID_1, SELECTOR_TYPE_CALLING) 229 .setAddress(TEST_URI) 230 .setCallId(TEST_CALLID) 231 .setEmergency(false) 232 .setVideoCall(true) 233 .setExitedFromAirplaneMode(false) 234 .build(); 235 mNormalCallDomainSelector.selectDomain(attributes, transportSelectorCallback); 236 237 assertEquals(NormalCallDomainSelector.SelectorState.ACTIVE, 238 mNormalCallDomainSelector.getSelectorState()); 239 240 // Case 1: null inputs 241 try { 242 mNormalCallDomainSelector.selectDomain(null, null); 243 } catch (Exception e) { 244 fail("Invalid input params not handled." + e.getMessage()); 245 } 246 247 assertEquals(NormalCallDomainSelector.SelectorState.INACTIVE, 248 mNormalCallDomainSelector.getSelectorState()); 249 250 // Case 2: null TransportSelectorCallback 251 try { 252 mNormalCallDomainSelector.selectDomain(attributes, null); 253 } catch (Exception e) { 254 fail("Invalid params (SelectionAttributes) not handled." + e.getMessage()); 255 } 256 257 assertEquals(NormalCallDomainSelector.SelectorState.INACTIVE, 258 mNormalCallDomainSelector.getSelectorState()); 259 260 // Case 3: null SelectionAttributes 261 transportSelectorCallback.mSelectionTerminated = false; 262 try { 263 mNormalCallDomainSelector.selectDomain(null, transportSelectorCallback); 264 } catch (Exception e) { 265 fail("Invalid params (SelectionAttributes) not handled." + e.getMessage()); 266 } 267 268 assertTrue(transportSelectorCallback.mSelectionTerminated); 269 assertEquals(transportSelectorCallback.mCauseCode, DisconnectCause.OUTGOING_FAILURE); 270 assertEquals(NormalCallDomainSelector.SelectorState.DESTROYED, 271 mNormalCallDomainSelector.getSelectorState()); 272 273 // Case 4: Invalid Subscription-id 274 attributes = new DomainSelectionService.SelectionAttributes.Builder( 275 SLOT_ID, SubscriptionManager.INVALID_SUBSCRIPTION_ID, SELECTOR_TYPE_CALLING) 276 .setAddress(TEST_URI) 277 .setCallId(TEST_CALLID) 278 .setEmergency(false) 279 .setVideoCall(true) 280 .setExitedFromAirplaneMode(false) 281 .build(); 282 try { 283 mNormalCallDomainSelector.selectDomain(attributes, transportSelectorCallback); 284 } catch (Exception e) { 285 fail("Invalid params (SelectionAttributes) not handled." + e.getMessage()); 286 } 287 288 assertTrue(transportSelectorCallback.mSelectionTerminated); 289 assertEquals(transportSelectorCallback.mCauseCode, DisconnectCause.OUTGOING_FAILURE); 290 assertEquals(NormalCallDomainSelector.SelectorState.DESTROYED, 291 mNormalCallDomainSelector.getSelectorState()); 292 293 // Case 5: Invalid SELECTOR_TYPE 294 attributes = 295 new DomainSelectionService.SelectionAttributes.Builder( 296 SLOT_ID, SUB_ID_1, SELECTOR_TYPE_UT) 297 .setAddress(TEST_URI) 298 .setCallId(TEST_CALLID) 299 .setEmergency(false) 300 .setVideoCall(true) 301 .setExitedFromAirplaneMode(false) 302 .build(); 303 try { 304 mNormalCallDomainSelector.selectDomain(attributes, transportSelectorCallback); 305 } catch (Exception e) { 306 fail("Invalid params (SelectionAttributes) not handled." + e.getMessage()); 307 } 308 309 assertTrue(transportSelectorCallback.mSelectionTerminated); 310 assertEquals(transportSelectorCallback.mCauseCode, DisconnectCause.OUTGOING_FAILURE); 311 assertEquals(NormalCallDomainSelector.SelectorState.DESTROYED, 312 mNormalCallDomainSelector.getSelectorState()); 313 314 // Case 6: Emergency Call 315 attributes = new DomainSelectionService.SelectionAttributes.Builder( 316 SLOT_ID, SUB_ID_1, SELECTOR_TYPE_CALLING) 317 .setAddress(TEST_URI) 318 .setCallId(TEST_CALLID) 319 .setEmergency(true) 320 .setVideoCall(true) 321 .setExitedFromAirplaneMode(false) 322 .build(); 323 try { 324 mNormalCallDomainSelector.selectDomain(attributes, transportSelectorCallback); 325 } catch (Exception e) { 326 fail("Invalid params (SelectionAttributes) not handled." + e.getMessage()); 327 } 328 329 assertTrue(transportSelectorCallback.mSelectionTerminated); 330 assertEquals(transportSelectorCallback.mCauseCode, DisconnectCause.OUTGOING_FAILURE); 331 assertEquals(NormalCallDomainSelector.SelectorState.DESTROYED, 332 mNormalCallDomainSelector.getSelectorState()); 333 } 334 335 @Test testOutOfService()336 public void testOutOfService() { 337 final TestTransportSelectorCallback transportSelectorCallback = 338 new TestTransportSelectorCallback(mNormalCallDomainSelector); 339 mNormalCallDomainSelector.post(() -> { 340 341 DomainSelectionService.SelectionAttributes attributes = 342 new DomainSelectionService.SelectionAttributes.Builder( 343 SLOT_ID, SUB_ID_1, SELECTOR_TYPE_CALLING) 344 .setAddress(TEST_URI) 345 .setCallId(TEST_CALLID) 346 .setEmergency(false) 347 .setVideoCall(true) 348 .setExitedFromAirplaneMode(false) 349 .build(); 350 351 ServiceState serviceState = new ServiceState(); 352 serviceState.setStateOutOfService(); 353 initialize(serviceState, false, false, false, false); 354 355 mNormalCallDomainSelector.selectDomain(attributes, transportSelectorCallback); 356 }); 357 358 processAllMessages(); 359 assertTrue(transportSelectorCallback.mSelectionTerminated); 360 assertEquals(DisconnectCause.OUT_OF_SERVICE, transportSelectorCallback.mCauseCode); 361 362 assertEquals(NormalCallDomainSelector.SelectorState.DESTROYED, 363 mNormalCallDomainSelector.getSelectorState()); 364 } 365 366 @Test testDomainSelection()367 public void testDomainSelection() { 368 final TestTransportSelectorCallback transportSelectorCallback = 369 new TestTransportSelectorCallback(mNormalCallDomainSelector); 370 371 final ServiceState serviceState = new ServiceState(); 372 serviceState.setState(ServiceState.STATE_IN_SERVICE); 373 initialize(serviceState, true, true, true, true); 374 transportSelectorCallback.reset(); 375 DomainSelectionService.SelectionAttributes attributes = 376 new DomainSelectionService.SelectionAttributes.Builder( 377 SLOT_ID, SUB_ID_1, SELECTOR_TYPE_CALLING) 378 .setAddress(TEST_URI) 379 .setCallId(TEST_CALLID) 380 .setEmergency(false) 381 .setVideoCall(false) 382 .setExitedFromAirplaneMode(false) 383 .build(); 384 385 // Case 1: WLAN 386 mNormalCallDomainSelector.selectDomain(attributes, transportSelectorCallback); 387 388 processAllMessages(); 389 assertTrue(transportSelectorCallback.mWlanSelected); 390 assertEquals(NormalCallDomainSelector.SelectorState.INACTIVE, 391 mNormalCallDomainSelector.getSelectorState()); 392 393 // Case 2: 5G 394 serviceState.setState(ServiceState.STATE_IN_SERVICE); 395 initialize(serviceState, true, false, true, true); 396 transportSelectorCallback.reset(); 397 attributes = new DomainSelectionService.SelectionAttributes.Builder( 398 SLOT_ID, SUB_ID_1, SELECTOR_TYPE_CALLING) 399 .setAddress(TEST_URI) 400 .setCallId(TEST_CALLID) 401 .setEmergency(false) 402 .setVideoCall(false) 403 .setExitedFromAirplaneMode(false) 404 .build(); 405 406 mNormalCallDomainSelector.selectDomain(attributes, transportSelectorCallback); 407 408 processAllMessages(); 409 assertTrue(transportSelectorCallback.mWwanSelected); 410 assertEquals(NetworkRegistrationInfo.DOMAIN_PS, transportSelectorCallback.mSelectedDomain); 411 assertEquals(NormalCallDomainSelector.SelectorState.INACTIVE, 412 mNormalCallDomainSelector.getSelectorState()); 413 414 415 // Case 3: PS -> CS redial 416 final ImsReasonInfo imsReasonInfoCsRetry = new ImsReasonInfo( 417 ImsReasonInfo.CODE_LOCAL_CALL_CS_RETRY_REQUIRED, 0, null); 418 transportSelectorCallback.reset(); 419 attributes = new DomainSelectionService.SelectionAttributes.Builder( 420 SLOT_ID, SUB_ID_1, SELECTOR_TYPE_CALLING) 421 .setAddress(TEST_URI) 422 .setCallId(TEST_CALLID) 423 .setEmergency(false) 424 .setVideoCall(false) 425 .setExitedFromAirplaneMode(false) 426 .setPsDisconnectCause(imsReasonInfoCsRetry) 427 .build(); 428 429 mNormalCallDomainSelector.reselectDomain(attributes); 430 431 processAllMessages(); 432 assertEquals(transportSelectorCallback.mSelectedDomain, NetworkRegistrationInfo.DOMAIN_CS); 433 assertEquals(NormalCallDomainSelector.SelectorState.INACTIVE, 434 mNormalCallDomainSelector.getSelectorState()); 435 436 // Case 4: CS call 437 transportSelectorCallback.reset(); 438 initialize(serviceState, false, false, false, false); 439 NetworkRegistrationInfo nwRegistrationInfo = new NetworkRegistrationInfo( 440 NetworkRegistrationInfo.DOMAIN_CS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN, 441 NetworkRegistrationInfo.REGISTRATION_STATE_HOME, 442 AccessNetworkConstants.AccessNetworkType.UTRAN, 0, false, 443 null, null, null, false, 0, 0, 0); 444 serviceState.addNetworkRegistrationInfo(nwRegistrationInfo); 445 attributes = new DomainSelectionService.SelectionAttributes.Builder( 446 SLOT_ID, SUB_ID_1, SELECTOR_TYPE_CALLING) 447 .setAddress(TEST_URI) 448 .setCallId(TEST_CALLID) 449 .setEmergency(false) 450 .setVideoCall(false) 451 .setExitedFromAirplaneMode(false) 452 .build(); 453 454 mNormalCallDomainSelector.selectDomain(attributes, transportSelectorCallback); 455 456 processAllMessages(); 457 assertEquals(transportSelectorCallback.mSelectedDomain, NetworkRegistrationInfo.DOMAIN_CS); 458 assertEquals(NormalCallDomainSelector.SelectorState.INACTIVE, 459 mNormalCallDomainSelector.getSelectorState()); 460 461 //Case 5: Backup calling 462 serviceState.setStateOutOfService(); 463 transportSelectorCallback.reset(); 464 attributes = new DomainSelectionService.SelectionAttributes.Builder( 465 SLOT_ID, SUB_ID_1, SELECTOR_TYPE_CALLING) 466 .setAddress(TEST_URI) 467 .setCallId(TEST_CALLID) 468 .setEmergency(false) 469 .setVideoCall(false) 470 .setExitedFromAirplaneMode(false) 471 .setPsDisconnectCause(imsReasonInfoCsRetry) 472 .build(); 473 initialize(serviceState, true, true, true, true); 474 mNormalCallDomainSelector.selectDomain(attributes, transportSelectorCallback); 475 476 processAllMessages(); 477 assertTrue(transportSelectorCallback.mWlanSelected); 478 assertEquals(NormalCallDomainSelector.SelectorState.INACTIVE, 479 mNormalCallDomainSelector.getSelectorState()); 480 } 481 482 @Test testWPSCallDomainSelection()483 public void testWPSCallDomainSelection() { 484 TestTransportSelectorCallback transportSelectorCallback = 485 new TestTransportSelectorCallback(mNormalCallDomainSelector); 486 DomainSelectionService.SelectionAttributes attributes = 487 new DomainSelectionService.SelectionAttributes.Builder( 488 SLOT_ID, SUB_ID_1, SELECTOR_TYPE_CALLING) 489 .setAddress(Uri.fromParts(PhoneAccount.SCHEME_TEL, "*272121", null)) 490 .setCallId(TEST_CALLID) 491 .setEmergency(false) 492 .setVideoCall(false) 493 .setExitedFromAirplaneMode(false) 494 .build(); 495 496 //Case 1: WPS not supported by IMS 497 PersistableBundle config = new PersistableBundle(); 498 config.putBoolean(CarrierConfigManager.KEY_SUPPORT_WPS_OVER_IMS_BOOL, false); 499 doReturn(config).when(mMockCarrierConfigMgr).getConfigForSubId(SUB_ID_1, 500 new String[]{CarrierConfigManager.KEY_SUPPORT_WPS_OVER_IMS_BOOL}); 501 502 ServiceState serviceState = new ServiceState(); 503 serviceState.setState(ServiceState.STATE_IN_SERVICE); 504 initialize(serviceState, true, true, true, true); 505 506 mNormalCallDomainSelector.selectDomain(attributes, transportSelectorCallback); 507 508 processAllMessages(); 509 assertTrue(transportSelectorCallback.mWwanSelected); 510 assertEquals(transportSelectorCallback.mSelectedDomain, NetworkRegistrationInfo.DOMAIN_CS); 511 assertEquals(NormalCallDomainSelector.SelectorState.INACTIVE, 512 mNormalCallDomainSelector.getSelectorState()); 513 514 //Case 2: WPS supported by IMS and WLAN registered 515 transportSelectorCallback.reset(); 516 config.putBoolean(CarrierConfigManager.KEY_SUPPORT_WPS_OVER_IMS_BOOL, true); 517 serviceState.setState(ServiceState.STATE_IN_SERVICE); 518 initialize(serviceState, true, true, true, true); 519 520 mNormalCallDomainSelector.selectDomain(attributes, transportSelectorCallback); 521 522 processAllMessages(); 523 assertTrue(transportSelectorCallback.mWlanSelected); 524 assertEquals(mNormalCallDomainSelector.getSelectorState(), 525 NormalCallDomainSelector.SelectorState.INACTIVE); 526 527 //Case 2: WPS supported by IMS and LTE registered 528 transportSelectorCallback.reset(); 529 config.putBoolean(CarrierConfigManager.KEY_SUPPORT_WPS_OVER_IMS_BOOL, true); 530 serviceState.setState(ServiceState.STATE_IN_SERVICE); 531 initialize(serviceState, true, false, true, true); 532 533 mNormalCallDomainSelector.selectDomain(attributes, transportSelectorCallback); 534 535 processAllMessages(); 536 assertEquals(transportSelectorCallback.mSelectedDomain, NetworkRegistrationInfo.DOMAIN_PS); 537 assertEquals(NormalCallDomainSelector.SelectorState.INACTIVE, 538 mNormalCallDomainSelector.getSelectorState()); 539 } 540 541 @Test testTtyCallDomainSelection()542 public void testTtyCallDomainSelection() { 543 TestTransportSelectorCallback transportSelectorCallback = 544 new TestTransportSelectorCallback(mNormalCallDomainSelector); 545 DomainSelectionService.SelectionAttributes attributes = 546 new DomainSelectionService.SelectionAttributes.Builder( 547 SLOT_ID, SUB_ID_1, SELECTOR_TYPE_CALLING) 548 .setAddress(TEST_URI) 549 .setCallId(TEST_CALLID) 550 .setEmergency(false) 551 .setVideoCall(false) 552 .setExitedFromAirplaneMode(false) 553 .build(); 554 555 //Case 1: TTY not supported by IMS and TTY enabled 556 doReturn(TelecomManager.TTY_MODE_FULL).when(mMockTelecomManager).getCurrentTtyMode(); 557 PersistableBundle config = new PersistableBundle(); 558 config.putBoolean(CarrierConfigManager.KEY_CARRIER_VOLTE_TTY_SUPPORTED_BOOL, false); 559 doReturn(config).when(mMockCarrierConfigMgr).getConfigForSubId(SUB_ID_1, 560 new String[]{CarrierConfigManager.KEY_CARRIER_VOLTE_TTY_SUPPORTED_BOOL}); 561 562 ServiceState serviceState = new ServiceState(); 563 serviceState.setState(ServiceState.STATE_IN_SERVICE); 564 initialize(serviceState, true, false, true, true); 565 566 mNormalCallDomainSelector.selectDomain(attributes, transportSelectorCallback); 567 568 processAllMessages(); 569 assertTrue(transportSelectorCallback.mWwanSelected); 570 assertEquals(transportSelectorCallback.mSelectedDomain, NetworkRegistrationInfo.DOMAIN_CS); 571 assertEquals(NormalCallDomainSelector.SelectorState.INACTIVE, 572 mNormalCallDomainSelector.getSelectorState()); 573 574 //Case 2: TTY supported by IMS and TTY enabled 575 transportSelectorCallback.reset(); 576 config.putBoolean(CarrierConfigManager.KEY_CARRIER_VOLTE_TTY_SUPPORTED_BOOL, true); 577 mNormalCallDomainSelector.selectDomain(attributes, transportSelectorCallback); 578 579 processAllMessages(); 580 assertEquals(transportSelectorCallback.mSelectedDomain, NetworkRegistrationInfo.DOMAIN_PS); 581 assertEquals(NormalCallDomainSelector.SelectorState.INACTIVE, 582 mNormalCallDomainSelector.getSelectorState()); 583 584 //Case 3: TTY supported by IMS and TTY disabled 585 transportSelectorCallback.reset(); 586 doReturn(TelecomManager.TTY_MODE_OFF).when(mMockTelecomManager).getCurrentTtyMode(); 587 mNormalCallDomainSelector.selectDomain(attributes, transportSelectorCallback); 588 589 processAllMessages(); 590 assertEquals(transportSelectorCallback.mSelectedDomain, NetworkRegistrationInfo.DOMAIN_PS); 591 assertEquals(NormalCallDomainSelector.SelectorState.INACTIVE, 592 mNormalCallDomainSelector.getSelectorState()); 593 } 594 595 @Test testEmcCsFailureAndPsRedial()596 public void testEmcCsFailureAndPsRedial() { 597 final TestTransportSelectorCallback transportSelectorCallback = 598 new TestTransportSelectorCallback(mNormalCallDomainSelector); 599 600 final ServiceState serviceState = new ServiceState(); 601 602 // dial CS call 603 serviceState.setState(ServiceState.STATE_IN_SERVICE); 604 initialize(serviceState, false, false, false, false); 605 NetworkRegistrationInfo nwRegistrationInfo = new NetworkRegistrationInfo( 606 NetworkRegistrationInfo.DOMAIN_CS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN, 607 NetworkRegistrationInfo.REGISTRATION_STATE_HOME, 608 AccessNetworkConstants.AccessNetworkType.UTRAN, 0, false, 609 null, null, null, false, 0, 0, 0); 610 serviceState.addNetworkRegistrationInfo(nwRegistrationInfo); 611 DomainSelectionService.SelectionAttributes attributes = 612 new DomainSelectionService.SelectionAttributes.Builder( 613 SLOT_ID, SUB_ID_1, SELECTOR_TYPE_CALLING) 614 .setAddress(TEST_URI) 615 .setCallId(TEST_CALLID) 616 .setEmergency(false) 617 .setVideoCall(false) 618 .setExitedFromAirplaneMode(false) 619 .build(); 620 621 mNormalCallDomainSelector.selectDomain(attributes, transportSelectorCallback); 622 623 processAllMessages(); 624 assertEquals(transportSelectorCallback.mSelectedDomain, NetworkRegistrationInfo.DOMAIN_CS); 625 assertEquals(NormalCallDomainSelector.SelectorState.INACTIVE, 626 mNormalCallDomainSelector.getSelectorState()); 627 628 // EMC_REDIAL_ON_IMS 629 transportSelectorCallback.reset(); 630 serviceState.setState(ServiceState.STATE_IN_SERVICE); 631 initialize(serviceState, true, false, true, false); 632 attributes = new DomainSelectionService.SelectionAttributes.Builder( 633 SLOT_ID, SUB_ID_1, SELECTOR_TYPE_CALLING) 634 .setAddress(TEST_URI) 635 .setCallId(TEST_CALLID) 636 .setEmergency(false) 637 .setVideoCall(false) 638 .setExitedFromAirplaneMode(false) 639 .setCsDisconnectCause(CallFailCause.EMC_REDIAL_ON_IMS) 640 .build(); 641 642 mNormalCallDomainSelector.reselectDomain(attributes); 643 644 processAllMessages(); 645 assertTrue(transportSelectorCallback.mWwanSelected); 646 assertEquals(NetworkRegistrationInfo.DOMAIN_PS, transportSelectorCallback.mSelectedDomain); 647 assertEquals(NormalCallDomainSelector.SelectorState.INACTIVE, 648 mNormalCallDomainSelector.getSelectorState()); 649 650 // EMC_REDIAL_ON_VOWIFI 651 transportSelectorCallback.reset(); 652 initialize(serviceState, true, true, true, false); 653 attributes = new DomainSelectionService.SelectionAttributes.Builder( 654 SLOT_ID, SUB_ID_1, SELECTOR_TYPE_CALLING) 655 .setAddress(TEST_URI) 656 .setCallId(TEST_CALLID) 657 .setEmergency(false) 658 .setVideoCall(false) 659 .setExitedFromAirplaneMode(false) 660 .setCsDisconnectCause(CallFailCause.EMC_REDIAL_ON_VOWIFI) 661 .build(); 662 663 mNormalCallDomainSelector.reselectDomain(attributes); 664 665 processAllMessages(); 666 assertTrue(transportSelectorCallback.mWlanSelected); 667 assertEquals(NormalCallDomainSelector.SelectorState.INACTIVE, 668 mNormalCallDomainSelector.getSelectorState()); 669 } 670 671 @Test testImsRegistrationStateTimeoutMessage()672 public void testImsRegistrationStateTimeoutMessage() { 673 final TestTransportSelectorCallback transportSelectorCallback = 674 new TestTransportSelectorCallback(mNormalCallDomainSelector); 675 676 final ServiceState serviceState = new ServiceState(); 677 serviceState.setState(ServiceState.STATE_IN_SERVICE); 678 mNormalCallDomainSelector.onServiceStateUpdated(serviceState); 679 doReturn(true).when(mMockImsStateTracker).isImsStateReady(); 680 doReturn(true).when(mMockImsStateTracker).isImsRegistered(); 681 doReturn(true).when(mMockImsStateTracker).isImsVoiceCapable(); 682 doReturn(false).when(mMockImsStateTracker).isImsVideoCapable(); 683 doReturn(true).when(mMockImsStateTracker).isImsRegisteredOverWlan(); 684 685 DomainSelectionService.SelectionAttributes attributes = 686 new DomainSelectionService.SelectionAttributes.Builder( 687 SLOT_ID, SUB_ID_1, SELECTOR_TYPE_CALLING) 688 .setAddress(TEST_URI) 689 .setCallId(TEST_CALLID) 690 .setEmergency(false) 691 .setVideoCall(false) 692 .setExitedFromAirplaneMode(false) 693 .build(); 694 695 mNormalCallDomainSelector.selectDomain(attributes, transportSelectorCallback); 696 assertTrue(mNormalCallDomainSelector.hasMessages( 697 NormalCallDomainSelector.MSG_WAIT_FOR_IMS_STATE_TIMEOUT)); 698 699 mNormalCallDomainSelector.onImsRegistrationStateChanged(); 700 mNormalCallDomainSelector.onImsMmTelCapabilitiesChanged(); 701 processAllMessages(); 702 703 assertFalse(mNormalCallDomainSelector.hasMessages( 704 NormalCallDomainSelector.MSG_WAIT_FOR_IMS_STATE_TIMEOUT)); 705 assertTrue(transportSelectorCallback.mWlanSelected); 706 assertEquals(NormalCallDomainSelector.SelectorState.INACTIVE, 707 mNormalCallDomainSelector.getSelectorState()); 708 } 709 710 @Test testImsRegistrationStateTimeoutHandler()711 public void testImsRegistrationStateTimeoutHandler() { 712 final TestTransportSelectorCallback transportSelectorCallback = 713 new TestTransportSelectorCallback(mNormalCallDomainSelector); 714 715 final ServiceState serviceState = new ServiceState(); 716 serviceState.setState(ServiceState.STATE_IN_SERVICE); 717 mNormalCallDomainSelector.onServiceStateUpdated(serviceState); 718 doReturn(true).when(mMockImsStateTracker).isImsStateReady(); 719 doReturn(false).when(mMockImsStateTracker).isImsRegistered(); 720 doReturn(true).when(mMockImsStateTracker).isImsVoiceCapable(); 721 doReturn(false).when(mMockImsStateTracker).isImsVideoCapable(); 722 doReturn(true).when(mMockImsStateTracker).isImsRegisteredOverWlan(); 723 724 DomainSelectionService.SelectionAttributes attributes = 725 new DomainSelectionService.SelectionAttributes.Builder( 726 SLOT_ID, SUB_ID_1, SELECTOR_TYPE_CALLING) 727 .setAddress(TEST_URI) 728 .setCallId(TEST_CALLID) 729 .setEmergency(false) 730 .setVideoCall(false) 731 .setExitedFromAirplaneMode(false) 732 .build(); 733 734 mNormalCallDomainSelector.selectDomain(attributes, transportSelectorCallback); 735 assertTrue(mNormalCallDomainSelector.hasMessages( 736 NormalCallDomainSelector.MSG_WAIT_FOR_IMS_STATE_TIMEOUT)); 737 738 mTestableLooper.moveTimeForward( 739 NormalCallDomainSelector.WAIT_FOR_IMS_STATE_TIMEOUT_MS + 10); 740 processAllMessages(); 741 742 assertEquals(transportSelectorCallback.mSelectedDomain, NetworkRegistrationInfo.DOMAIN_CS); 743 assertEquals(NormalCallDomainSelector.SelectorState.INACTIVE, 744 mNormalCallDomainSelector.getSelectorState()); 745 } 746 747 static class TestTransportSelectorCallback implements TransportSelectorCallback, 748 WwanSelectorCallback { 749 public boolean mCreated; 750 public boolean mWlanSelected; 751 public boolean mWwanSelected; 752 public boolean mSelectionTerminated; 753 public boolean mDomainSelected; 754 int mCauseCode; 755 int mSelectedDomain; 756 NormalCallDomainSelector mNormalCallDomainSelector; 757 TestTransportSelectorCallback(NormalCallDomainSelector normalCallDomainSelector)758 TestTransportSelectorCallback(NormalCallDomainSelector normalCallDomainSelector) { 759 mNormalCallDomainSelector = normalCallDomainSelector; 760 mCauseCode = DisconnectCause.NOT_VALID; 761 } 762 763 @Override onCreated(DomainSelector selector)764 public synchronized void onCreated(DomainSelector selector) { 765 Log.d(TAG, "onCreated"); 766 mCreated = true; 767 768 assertEquals(NormalCallDomainSelector.SelectorState.INACTIVE, 769 mNormalCallDomainSelector.getSelectorState()); 770 } 771 772 @Override onWlanSelected(boolean useEmergencyPdn)773 public synchronized void onWlanSelected(boolean useEmergencyPdn) { 774 Log.d(TAG, "onWlanSelected"); 775 mWlanSelected = true; 776 } 777 778 @Override onWwanSelected(final Consumer<WwanSelectorCallback> consumer)779 public void onWwanSelected(final Consumer<WwanSelectorCallback> consumer) { 780 Log.d(TAG, "onWwanSelected"); 781 mWwanSelected = true; 782 consumer.accept(this); 783 } 784 785 @Override onSelectionTerminated(int cause)786 public synchronized void onSelectionTerminated(int cause) { 787 Log.i(TAG, "onSelectionTerminated - called"); 788 mCauseCode = cause; 789 mSelectionTerminated = true; 790 791 assertEquals(NormalCallDomainSelector.SelectorState.INACTIVE, 792 mNormalCallDomainSelector.getSelectorState()); 793 794 notifyAll(); 795 } 796 797 @Override onRequestEmergencyNetworkScan(@onNull List<Integer> preferredNetworks, int scanType, boolean resetScan, @NonNull CancellationSignal signal, @NonNull Consumer<EmergencyRegistrationResult> consumer)798 public void onRequestEmergencyNetworkScan(@NonNull List<Integer> preferredNetworks, 799 int scanType, 800 boolean resetScan, 801 @NonNull CancellationSignal signal, 802 @NonNull Consumer<EmergencyRegistrationResult> consumer) { 803 Log.i(TAG, "onRequestEmergencyNetworkScan - called"); 804 805 } 806 onDomainSelected(@etworkRegistrationInfo.Domain int domain, boolean useEmergencyPdn)807 public synchronized void onDomainSelected(@NetworkRegistrationInfo.Domain int domain, 808 boolean useEmergencyPdn) { 809 Log.i(TAG, "onDomainSelected - called"); 810 mSelectedDomain = domain; 811 mDomainSelected = true; 812 mWwanSelected = true; 813 814 assertEquals(NormalCallDomainSelector.SelectorState.INACTIVE, 815 mNormalCallDomainSelector.getSelectorState()); 816 817 notifyAll(); 818 } reset()819 public void reset() { 820 mCreated = false; 821 mWlanSelected = false; 822 mWwanSelected = false; 823 mSelectionTerminated = false; 824 mDomainSelected = false; 825 mCauseCode = DisconnectCause.NOT_VALID; 826 mSelectedDomain = NetworkRegistrationInfo.DOMAIN_UNKNOWN; 827 } 828 } 829 } 830