1 /* 2 * Copyright (C) 2006 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.internal.telephony.data; 18 19 import static android.telephony.CarrierConfigManager.KEY_DATA_SWITCH_VALIDATION_TIMEOUT_LONG; 20 import static android.telephony.TelephonyManager.ACTION_SIM_APPLICATION_STATE_CHANGED; 21 import static android.telephony.TelephonyManager.EXTRA_SIM_STATE; 22 import static android.telephony.TelephonyManager.SET_OPPORTUNISTIC_SUB_INACTIVE_SUBSCRIPTION; 23 import static android.telephony.TelephonyManager.SET_OPPORTUNISTIC_SUB_SUCCESS; 24 import static android.telephony.TelephonyManager.SET_OPPORTUNISTIC_SUB_VALIDATION_FAILED; 25 import static android.telephony.TelephonyManager.SIM_STATE_LOADED; 26 import static android.telephony.ims.RegistrationManager.REGISTRATION_STATE_NOT_REGISTERED; 27 import static android.telephony.ims.RegistrationManager.REGISTRATION_STATE_REGISTERED; 28 import static android.telephony.ims.stub.ImsRegistrationImplBase.REGISTRATION_TECH_CROSS_SIM; 29 import static android.telephony.ims.stub.ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN; 30 import static android.telephony.ims.stub.ImsRegistrationImplBase.REGISTRATION_TECH_LTE; 31 import static android.telephony.ims.stub.ImsRegistrationImplBase.REGISTRATION_TECH_NONE; 32 33 import static com.android.internal.telephony.data.AutoDataSwitchController.EVALUATION_REASON_VOICE_CALL_END; 34 import static com.android.internal.telephony.data.PhoneSwitcher.ECBM_DEFAULT_DATA_SWITCH_BASE_TIME_MS; 35 36 import static org.junit.Assert.assertEquals; 37 import static org.junit.Assert.assertFalse; 38 import static org.junit.Assert.assertNotNull; 39 import static org.junit.Assert.assertTrue; 40 import static org.mockito.ArgumentMatchers.any; 41 import static org.mockito.ArgumentMatchers.anyBoolean; 42 import static org.mockito.ArgumentMatchers.anyInt; 43 import static org.mockito.ArgumentMatchers.anyLong; 44 import static org.mockito.ArgumentMatchers.anyString; 45 import static org.mockito.Matchers.eq; 46 import static org.mockito.Mockito.clearInvocations; 47 import static org.mockito.Mockito.doAnswer; 48 import static org.mockito.Mockito.doNothing; 49 import static org.mockito.Mockito.doReturn; 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 55 import android.content.Intent; 56 import android.net.ConnectivityManager; 57 import android.net.NetworkCapabilities; 58 import android.net.NetworkRequest; 59 import android.net.TelephonyNetworkSpecifier; 60 import android.os.AsyncResult; 61 import android.os.Handler; 62 import android.os.Looper; 63 import android.os.Message; 64 import android.telephony.AccessNetworkConstants; 65 import android.telephony.NetworkRegistrationInfo; 66 import android.telephony.PhoneCapability; 67 import android.telephony.ServiceState; 68 import android.telephony.SubscriptionInfo; 69 import android.telephony.SubscriptionManager; 70 import android.telephony.TelephonyDisplayInfo; 71 import android.telephony.TelephonyManager; 72 import android.testing.AndroidTestingRunner; 73 import android.testing.TestableLooper; 74 75 import com.android.ims.ImsException; 76 import com.android.internal.telephony.Call; 77 import com.android.internal.telephony.CommandException; 78 import com.android.internal.telephony.CommandsInterface; 79 import com.android.internal.telephony.GsmCdmaCall; 80 import com.android.internal.telephony.ISetOpportunisticDataCallback; 81 import com.android.internal.telephony.ISub; 82 import com.android.internal.telephony.Phone; 83 import com.android.internal.telephony.PhoneFactory; 84 import com.android.internal.telephony.ServiceStateTracker; 85 import com.android.internal.telephony.TelephonyTest; 86 import com.android.internal.telephony.imsphone.ImsPhone; 87 import com.android.internal.telephony.imsphone.ImsPhoneCall; 88 import com.android.internal.telephony.subscription.SubscriptionInfoInternal; 89 import com.android.internal.telephony.subscription.SubscriptionManagerService.SubscriptionManagerServiceCallback; 90 91 import org.junit.After; 92 import org.junit.Before; 93 import org.junit.Test; 94 import org.junit.runner.RunWith; 95 import org.mockito.ArgumentCaptor; 96 97 import java.lang.reflect.Field; 98 import java.util.Map; 99 import java.util.concurrent.CompletableFuture; 100 import java.util.concurrent.LinkedBlockingQueue; 101 102 @RunWith(AndroidTestingRunner.class) 103 @TestableLooper.RunWithLooper 104 public class PhoneSwitcherTest extends TelephonyTest { 105 private static final int ACTIVE_PHONE_SWITCH = 1; 106 private static final int EVENT_RADIO_ON = 108; 107 private static final int EVENT_MODEM_COMMAND_DONE = 112; 108 private static final int EVENT_EVALUATE_AUTO_SWITCH = 111; 109 private static final int EVENT_IMS_RADIO_TECH_CHANGED = 120; 110 private static final int EVENT_MULTI_SIM_CONFIG_CHANGED = 117; 111 private static final int EVENT_PRECISE_CALL_STATE_CHANGED = 109; 112 private static final int EVENT_SERVICE_STATE_CHANGED = 114; 113 114 // Mocked classes 115 CompletableFuture<Boolean> mFuturePhone; 116 private CommandsInterface mCommandsInterface0; 117 private CommandsInterface mCommandsInterface1; 118 private ServiceStateTracker mSST2; 119 private Phone mImsPhone; 120 private DataSettingsManager mDataSettingsManager2; 121 private Handler mActivePhoneSwitchHandler; 122 private GsmCdmaCall mActiveCall; 123 private GsmCdmaCall mHoldingCall; 124 private GsmCdmaCall mInactiveCall; 125 private GsmCdmaCall mDialCall; 126 private GsmCdmaCall mIncomingCall; 127 private GsmCdmaCall mAlertingCall; 128 private ISetOpportunisticDataCallback mSetOpptDataCallback1; 129 private ISetOpportunisticDataCallback mSetOpptDataCallback2; 130 PhoneSwitcher.ImsRegTechProvider mMockImsRegTechProvider; 131 PhoneSwitcher.ImsRegisterCallback mMockImsRegisterCallback; 132 private SubscriptionInfo mSubscriptionInfo; 133 private ISub mMockedIsub; 134 private AutoDataSwitchController mAutoDataSwitchController; 135 136 private PhoneSwitcher mPhoneSwitcherUT; 137 private SubscriptionManager.OnSubscriptionsChangedListener mSubChangedListener; 138 private Map<Integer, DataSettingsManager.DataSettingsManagerCallback> 139 mDataSettingsManagerCallbacks; 140 private int mDefaultDataSub = SubscriptionManager.INVALID_SUBSCRIPTION_ID; 141 private int[][] mSlotIndexToSubId; 142 private boolean[] mDataAllowed; 143 private int mActiveModemCount = 2; 144 private int mSupportedModemCount = 2; 145 private int mMaxDataAttachModemCount = 1; 146 private AutoDataSwitchController.AutoDataSwitchControllerCallback mAutoDataSwitchCallback; 147 private TelephonyDisplayInfo mTelephonyDisplayInfo = new TelephonyDisplayInfo( 148 TelephonyManager.NETWORK_TYPE_NR, 149 TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE, false, false, false); 150 private SubscriptionManagerServiceCallback mSubscriptionManagerServiceCallback; 151 152 @Before setUp()153 public void setUp() throws Exception { 154 super.setUp(getClass().getSimpleName()); 155 mFuturePhone = mock(CompletableFuture.class); 156 mCommandsInterface0 = mock(CommandsInterface.class); 157 mCommandsInterface1 = mock(CommandsInterface.class); 158 mSST2 = mock(ServiceStateTracker.class); 159 mImsPhone = mock(Phone.class); 160 mDataSettingsManager2 = mock(DataSettingsManager.class); 161 mActivePhoneSwitchHandler = mock(Handler.class); 162 mActiveCall = mock(GsmCdmaCall.class); 163 mHoldingCall = mock(GsmCdmaCall.class); 164 mInactiveCall = mock(GsmCdmaCall.class); 165 mDialCall = mock(GsmCdmaCall.class); 166 mIncomingCall = mock(GsmCdmaCall.class); 167 mAlertingCall = mock(GsmCdmaCall.class); 168 mSetOpptDataCallback1 = mock(ISetOpportunisticDataCallback.class); 169 mSetOpptDataCallback2 = mock(ISetOpportunisticDataCallback.class); 170 mMockImsRegTechProvider = mock(PhoneSwitcher.ImsRegTechProvider.class); 171 mMockImsRegisterCallback = mock(PhoneSwitcher.ImsRegisterCallback.class); 172 mSubscriptionInfo = mock(SubscriptionInfo.class); 173 mMockedIsub = mock(ISub.class); 174 mAutoDataSwitchController = mock(AutoDataSwitchController.class); 175 176 PhoneCapability phoneCapability = new PhoneCapability(1, 1, null, false, new int[0]); 177 doReturn(phoneCapability).when(mPhoneConfigurationManager).getCurrentPhoneCapability(); 178 179 doReturn(Call.State.ACTIVE).when(mActiveCall).getState(); 180 doReturn(Call.State.IDLE).when(mInactiveCall).getState(); 181 doReturn(Call.State.HOLDING).when(mHoldingCall).getState(); 182 doReturn(Call.State.DIALING).when(mDialCall).getState(); 183 doReturn(Call.State.INCOMING).when(mIncomingCall).getState(); 184 doReturn(Call.State.ALERTING).when(mAlertingCall).getState(); 185 186 doReturn(true).when(mInactiveCall).isIdle(); 187 doReturn(false).when(mActiveCall).isIdle(); 188 doReturn(false).when(mHoldingCall).isIdle(); 189 190 replaceInstance(Phone.class, "mCi", mPhone, mCommandsInterface0); 191 replaceInstance(Phone.class, "mCi", mPhone2, mCommandsInterface1); 192 193 doReturn(1).when(mMockedIsub).getDefaultDataSubId(); 194 doReturn(mMockedIsub).when(mIBinder).queryLocalInterface(anyString()); 195 doReturn(mPhone).when(mPhone).getImsPhone(); 196 mServiceManagerMockedServices.put("isub", mIBinder); 197 198 doReturn(mTelephonyDisplayInfo).when(mDisplayInfoController).getTelephonyDisplayInfo(); 199 doReturn(true).when(mFeatureFlags).ddsCallback(); 200 } 201 202 @After tearDown()203 public void tearDown() throws Exception { 204 mPhoneSwitcherUT = null; 205 mSubChangedListener = null; 206 mTelephonyDisplayInfo = null; 207 super.tearDown(); 208 } 209 210 /** 211 * Test that a single phone case results in our phone being active and the RIL called 212 */ 213 @Test testRegister()214 public void testRegister() throws Exception { 215 initialize(); 216 217 // verify nothing has been done while there are no inputs 218 assertTrue("data should be always allowed for emergency", mDataAllowed[0]); 219 assertFalse("data allowed initially", mDataAllowed[1]); 220 221 NetworkRequest internetNetworkRequest = addInternetNetworkRequest(null, 50); 222 223 assertFalse("phone active after request", mPhoneSwitcherUT 224 .shouldApplyNetworkRequest(new TelephonyNetworkRequest( 225 internetNetworkRequest, mPhone, mFeatureFlags), 0)); 226 227 // not registered yet - shouldn't inc 228 verify(mActivePhoneSwitchHandler, never()).sendMessageAtTime(any(), anyLong()); 229 230 mPhoneSwitcherUT.registerForActivePhoneSwitch(mActivePhoneSwitchHandler, 231 ACTIVE_PHONE_SWITCH, null); 232 233 verify(mActivePhoneSwitchHandler, times(1)).sendMessageAtTime(any(), anyLong()); 234 clearInvocations(mActivePhoneSwitchHandler); 235 236 setDefaultDataSubId(0); 237 238 verify(mActivePhoneSwitchHandler, never()).sendMessageAtTime(any(), anyLong()); 239 240 setSlotIndexToSubId(0, 0); 241 mSubChangedListener.onSubscriptionsChanged(); 242 processAllMessages(); 243 244 AsyncResult res = new AsyncResult(1, null, null); 245 Message.obtain(mPhoneSwitcherUT, EVENT_MODEM_COMMAND_DONE, res).sendToTarget(); 246 processAllMessages(); 247 verify(mActivePhoneSwitchHandler, times(1)).sendMessageAtTime(any(), anyLong()); 248 clearInvocations(mActivePhoneSwitchHandler); 249 assertTrue("data not allowed", mDataAllowed[0]); 250 251 // now try various things that should cause the active phone to switch: 252 // 1 lose default via default sub change 253 // 2 gain default via default sub change 254 // 3 lose default via sub->phone change 255 // 4 gain default via sub->phone change 256 // 5 lose default network request 257 // 6 gain subscription-specific request 258 // 7 lose via sub->phone change 259 // 8 gain via sub->phone change 260 // 9 lose subscription-specific request 261 // 10 don't switch phones when in emergency mode 262 263 // 1 lose default via default sub change 264 setDefaultDataSubId(1); 265 266 Message.obtain(mPhoneSwitcherUT, EVENT_MODEM_COMMAND_DONE, res).sendToTarget(); 267 processAllMessages(); 268 verify(mActivePhoneSwitchHandler, times(1)).sendMessageAtTime(any(), anyLong()); 269 clearInvocations(mActivePhoneSwitchHandler); 270 assertFalse("data allowed", mDataAllowed[0]); 271 272 setSlotIndexToSubId(1, 1); 273 clearInvocations(mAutoDataSwitchController); 274 mSubChangedListener.onSubscriptionsChanged(); 275 processAllMessages(); 276 277 Message.obtain(mPhoneSwitcherUT, EVENT_MODEM_COMMAND_DONE, res).sendToTarget(); 278 processAllMessages(); 279 verify(mActivePhoneSwitchHandler, times(1)).sendMessageAtTime(any(), anyLong()); 280 verify(mAutoDataSwitchController).notifySubscriptionsMappingChanged(); 281 clearInvocations(mActivePhoneSwitchHandler); 282 assertFalse("data allowed", mDataAllowed[0]); 283 assertTrue("data not allowed", mDataAllowed[1]); 284 285 // 2 gain default via default sub change 286 setDefaultDataSubId(0); 287 288 Message.obtain(mPhoneSwitcherUT, EVENT_MODEM_COMMAND_DONE, res).sendToTarget(); 289 processAllMessages(); 290 verify(mActivePhoneSwitchHandler, times(1)).sendMessageAtTime(any(), anyLong()); 291 clearInvocations(mActivePhoneSwitchHandler); 292 assertFalse("data allowed", mDataAllowed[1]); 293 assertTrue("data not allowed", mDataAllowed[0]); 294 295 // 3 lose default via sub->phone change 296 setSlotIndexToSubId(0, 2); 297 clearInvocations(mAutoDataSwitchController); 298 mSubChangedListener.onSubscriptionsChanged(); 299 processAllMessages(); 300 verify(mAutoDataSwitchController).notifySubscriptionsMappingChanged(); 301 Message.obtain(mPhoneSwitcherUT, EVENT_MODEM_COMMAND_DONE, res).sendToTarget(); 302 processAllMessages(); 303 304 verify(mActivePhoneSwitchHandler, times(1)).sendMessageAtTime(any(), anyLong()); 305 clearInvocations(mActivePhoneSwitchHandler); 306 assertFalse("data allowed", mDataAllowed[0]); 307 assertFalse("data allowed", mDataAllowed[1]); 308 309 // 4 gain default via sub->phone change 310 setSlotIndexToSubId(0, 0); 311 mSubChangedListener.onSubscriptionsChanged(); 312 processAllMessages(); 313 314 Message.obtain(mPhoneSwitcherUT, EVENT_MODEM_COMMAND_DONE, res).sendToTarget(); 315 processAllMessages(); 316 verify(mActivePhoneSwitchHandler, times(1)).sendMessageAtTime(any(), anyLong()); 317 clearInvocations(mActivePhoneSwitchHandler); 318 assertTrue("data not allowed", mDataAllowed[0]); 319 assertFalse("data allowed", mDataAllowed[1]); 320 321 // 5 lose default network request 322 releaseNetworkRequest(internetNetworkRequest); 323 324 Message.obtain(mPhoneSwitcherUT, EVENT_MODEM_COMMAND_DONE, res).sendToTarget(); 325 processAllMessages(); 326 verify(mActivePhoneSwitchHandler, times(1)).sendMessageAtTime(any(), anyLong()); 327 clearInvocations(mActivePhoneSwitchHandler); 328 assertTrue("data not allowed", mDataAllowed[0]); 329 assertFalse("data allowed", mDataAllowed[1]); 330 331 // 6 gain subscription-specific request 332 NetworkRequest specificInternetRequest = addInternetNetworkRequest(0, 50); 333 334 Message.obtain(mPhoneSwitcherUT, EVENT_MODEM_COMMAND_DONE, res).sendToTarget(); 335 processAllMessages(); 336 verify(mActivePhoneSwitchHandler, times(1)).sendMessageAtTime(any(), anyLong()); 337 clearInvocations(mActivePhoneSwitchHandler); 338 assertTrue("data not allowed", mDataAllowed[0]); 339 assertFalse("data allowed", mDataAllowed[1]); 340 341 // 7 lose via sub->phone change 342 setSlotIndexToSubId(0, 1); 343 mSubChangedListener.onSubscriptionsChanged(); 344 processAllMessages(); 345 346 Message.obtain(mPhoneSwitcherUT, EVENT_MODEM_COMMAND_DONE, res).sendToTarget(); 347 processAllMessages(); 348 verify(mActivePhoneSwitchHandler, times(1)).sendMessageAtTime(any(), anyLong()); 349 clearInvocations(mActivePhoneSwitchHandler); 350 assertFalse("data allowed", mDataAllowed[0]); 351 assertFalse("data allowed", mDataAllowed[1]); 352 353 // 8 gain via sub->phone change 354 setSlotIndexToSubId(0, 0); 355 mSubChangedListener.onSubscriptionsChanged(); 356 processAllMessages(); 357 358 Message.obtain(mPhoneSwitcherUT, EVENT_MODEM_COMMAND_DONE, res).sendToTarget(); 359 processAllMessages(); 360 verify(mActivePhoneSwitchHandler, times(1)).sendMessageAtTime(any(), anyLong()); 361 clearInvocations(mActivePhoneSwitchHandler); 362 assertTrue("data not allowed", mDataAllowed[0]); 363 assertFalse("data allowed", mDataAllowed[1]); 364 365 // 9 lose subscription-specific request 366 releaseNetworkRequest(specificInternetRequest); 367 368 Message.obtain(mPhoneSwitcherUT, EVENT_MODEM_COMMAND_DONE, res).sendToTarget(); 369 processAllMessages(); 370 verify(mActivePhoneSwitchHandler, times(1)).sendMessageAtTime(any(), anyLong()); 371 clearInvocations(mActivePhoneSwitchHandler); 372 assertTrue("data not allowed", mDataAllowed[0]); 373 assertFalse("data allowed", mDataAllowed[1]); 374 375 // 10 don't switch phones when in emergency mode 376 // not ready yet - Phone turns out to be hard to stub out 377 // phones[0].setInEmergencyCall(true); 378 // connectivityServiceMock.addDefaultRequest(); 379 // processAllMessages(); 380 // if (testHandler.getActivePhoneSwitchCount() != 11) { 381 // fail("after release of request, ActivePhoneSwitchCount not 11!"); 382 // } 383 // if (commandsInterfaces[0].isDataAllowed()) fail("data allowed"); 384 // if (commandsInterfaces[1].isDataAllowed()) fail("data allowed"); 385 // 386 // phones[0].setInEmergencyCall(false); 387 // connectivityServiceMock.addDefaultRequest(); 388 // processAllMessages(); 389 // if (testHandler.getActivePhoneSwitchCount() != 12) { 390 // fail("after release of request, ActivePhoneSwitchCount not 11!"); 391 // } 392 // if (commandsInterfaces[0].isDataAllowed()) fail("data allowed"); 393 // if (commandsInterfaces[1].isDataAllowed()) fail("data allowed"); 394 } 395 396 /** Test Data Auto Switch **/ 397 @Test testAutoDataSwitch_retry()398 public void testAutoDataSwitch_retry() throws Exception { 399 initialize(); 400 // Phone 0 has sub 1, phone 1 has sub 2. 401 // Sub 1 is default data sub. 402 setSlotIndexToSubId(0, 1); 403 setSlotIndexToSubId(1, 2); 404 setDefaultDataSubId(1); 405 406 mAutoDataSwitchCallback.onRequireValidation(1/*Phone2*/, true); 407 processAllFutureMessages(); 408 409 // Mock validation failed, expect retry attempt 410 verify(mCellularNetworkValidator).validate(eq(2), anyLong(), eq(false), 411 eq(mPhoneSwitcherUT.mValidationCallback)); 412 mPhoneSwitcherUT.mValidationCallback.onValidationDone(false, 2/*Phone2*/); 413 processAllMessages(); 414 415 verify(mAutoDataSwitchController).evaluateRetryOnValidationFailed(); 416 417 // Test clear failed count upon switch succeeded. 418 mAutoDataSwitchCallback.onRequireValidation(1/*Phone2*/, true); 419 processAllFutureMessages(); 420 mPhoneSwitcherUT.mValidationCallback.onValidationDone(true, 2/*Phone2*/); 421 processAllMessages(); 422 423 verify(mAutoDataSwitchController).resetFailedCount(); 424 } 425 426 @Test testAutoDataSwitch_setNotification()427 public void testAutoDataSwitch_setNotification() throws Exception { 428 initialize(); 429 // Phone 0 has sub 1, phone 1 has sub 2. 430 // Sub 1 is default data sub. 431 setSlotIndexToSubId(0, 1); 432 setSlotIndexToSubId(1, 2); 433 setDefaultDataSubId(1); 434 435 // Verify no notification check if switch failed. 436 Message.obtain(mPhoneSwitcherUT, EVENT_MODEM_COMMAND_DONE, new AsyncResult(1/*phoneId*/, 437 null, new Throwable())).sendToTarget(); 438 processAllMessages(); 439 verify(mAutoDataSwitchController, never()).displayAutoDataSwitchNotification( 440 anyInt(), anyBoolean()); 441 442 // Verify for switch not due to auto 443 Message.obtain(mPhoneSwitcherUT, EVENT_MODEM_COMMAND_DONE, new AsyncResult(1/*phoneId*/, 444 null, null)).sendToTarget(); 445 processAllMessages(); 446 verify(mAutoDataSwitchController).displayAutoDataSwitchNotification(1/*phoneId*/, false); 447 448 // Verify for switch due to auto 449 mAutoDataSwitchCallback.onRequireValidation(1/*Phone2*/, false); 450 processAllMessages(); 451 mPhoneSwitcherUT.mValidationCallback.onValidationDone(true, 2/*Phone2*/); 452 Message.obtain(mPhoneSwitcherUT, EVENT_MODEM_COMMAND_DONE, new AsyncResult(1/*phoneId*/, 453 null, null)).sendToTarget(); 454 processAllMessages(); 455 456 verify(mAutoDataSwitchController).displayAutoDataSwitchNotification(1/*phoneId*/, true); 457 } 458 459 @Test testAutoDataSwitch_exemptPingTest()460 public void testAutoDataSwitch_exemptPingTest() throws Exception { 461 initialize(); 462 463 // Phone 0 has sub 1, phone 1 has sub 2. 464 // Sub 1 is default data sub. 465 setSlotIndexToSubId(0, 1); 466 setSlotIndexToSubId(1, 2); 467 468 //Attempting to switch to nDDS, switch even if validation failed 469 mAutoDataSwitchCallback.onRequireValidation(1/*Phone2*/, false); 470 processAllFutureMessages(); 471 472 verify(mCellularNetworkValidator).validate(eq(2), anyLong(), eq(false), 473 eq(mPhoneSwitcherUT.mValidationCallback)); 474 mPhoneSwitcherUT.mValidationCallback.onValidationDone(false, 2/*Phone2*/); 475 processAllMessages(); 476 477 assertEquals(2, mPhoneSwitcherUT.getActiveDataSubId()); // switch succeeds 478 } 479 480 /** 481 * Test a multi-sim case with limited active phones: 482 * - lose default via default sub change 483 * - lose default via sub->phone change 484 * - gain default via sub->phone change 485 * - gain default via default sub change 486 * - lose default network request 487 * - gain subscription-specific request 488 * - lose via sub->phone change 489 * - gain via sub->phone change 490 * - lose subscription-specific request 491 * - tear down low priority phone when new request comes in 492 * - tear down low priority phone when sub change causes split 493 * - bring up low priority phone when sub change causes join 494 * - don't switch phones when in emergency mode 495 */ 496 @Test testPrioritization()497 public void testPrioritization() throws Exception { 498 initialize(); 499 500 addInternetNetworkRequest(null, 50); 501 setSlotIndexToSubId(0, 0); 502 setSlotIndexToSubId(1, 1); 503 setDefaultDataSubId(0); 504 mPhoneSwitcherUT.registerForActivePhoneSwitch(mActivePhoneSwitchHandler, 505 ACTIVE_PHONE_SWITCH, null); 506 processAllMessages(); 507 // verify initial conditions 508 verify(mActivePhoneSwitchHandler, times(1)).sendMessageAtTime(any(), anyLong()); 509 510 assertTrue("data not allowed", mDataAllowed[0]); 511 assertFalse("data allowed", mDataAllowed[1]); 512 513 // now start a higher priority connection on the other sub 514 addMmsNetworkRequest(1); 515 516 AsyncResult res = new AsyncResult(1, null, null); 517 Message.obtain(mPhoneSwitcherUT, EVENT_MODEM_COMMAND_DONE, res).sendToTarget(); 518 processAllMessages(); 519 520 // After gain of network request, mActivePhoneSwitchHandler should be notified 2 times. 521 verify(mActivePhoneSwitchHandler, times(2)).sendMessageAtTime(any(), anyLong()); 522 assertFalse("data allowed", mDataAllowed[0]); 523 assertTrue("data not allowed", mDataAllowed[1]); 524 } 525 526 /** 527 * Verify we don't send spurious DATA_ALLOWED calls when another NetworkProvider 528 * wins (ie, switch to wifi). 529 */ 530 @Test testHigherPriorityDefault()531 public void testHigherPriorityDefault() throws Exception { 532 initialize(); 533 534 addInternetNetworkRequest(null, 50); 535 536 setSlotIndexToSubId(0, 0); 537 setSlotIndexToSubId(1, 1); 538 setDefaultDataSubId(0); 539 540 // Phone 0 should be active 541 assertTrue("data not allowed", mDataAllowed[0]); 542 assertFalse("data allowed", mDataAllowed[1]); 543 544 addInternetNetworkRequest(null, 100); 545 546 // should be no change 547 assertTrue("data not allowed", mDataAllowed[0]); 548 assertFalse("data allowed", mDataAllowed[1]); 549 550 addInternetNetworkRequest(null, 0); 551 // should be no change 552 assertTrue("data not allowed", mDataAllowed[0]); 553 assertFalse("data allowed", mDataAllowed[1]); 554 } 555 556 /** 557 * Verify testSetPreferredData. 558 * When preferredData is set, it overwrites defaultData sub to be active sub in single 559 * active phone mode. If it's unset (to DEFAULT_SUBSCRIPTION_ID), defaultData sub becomes 560 * active one. 561 */ 562 @Test testSetPreferredData()563 public void testSetPreferredData() throws Exception { 564 initialize(); 565 566 // Phone 0 has sub 1, phone 1 has sub 2. 567 // Sub 1 is default data sub. 568 // Both are active subscriptions are active sub, as they are in both active slots. 569 setSlotIndexToSubId(0, 1); 570 setSlotIndexToSubId(1, 2); 571 setDefaultDataSubId(1); 572 573 doReturn(new SubscriptionInfoInternal.Builder(mSubscriptionManagerService 574 .getSubscriptionInfoInternal(2)).setOpportunistic(1).build()) 575 .when(mSubscriptionManagerService).getSubscriptionInfoInternal(2); 576 577 // Notify phoneSwitcher about default data sub and default network request. 578 addInternetNetworkRequest(null, 50); 579 // Phone 0 (sub 1) should be activated as it has default data sub. 580 assertTrue(mDataAllowed[0]); 581 582 // Set sub 2 as preferred sub should make phone 1 activated and phone 0 deactivated. 583 mPhoneSwitcherUT.trySetOpportunisticDataSubscription(2, false, null); 584 processAllMessages(); 585 mPhoneSwitcherUT.mValidationCallback.onNetworkAvailable(null, 2); 586 processAllMessages(); 587 assertFalse(mDataAllowed[0]); 588 assertTrue(mDataAllowed[1]); 589 590 // Unset preferred sub should make default data sub (phone 0 / sub 1) activated again. 591 mPhoneSwitcherUT.trySetOpportunisticDataSubscription( 592 SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, false, null); 593 processAllMessages(); 594 mPhoneSwitcherUT.mValidationCallback.onNetworkAvailable(null, 1); 595 processAllMessages(); 596 assertTrue(mDataAllowed[0]); 597 assertFalse(mDataAllowed[1]); 598 } 599 600 /** 601 * TestSetPreferredData in the event of different priorities. 602 * The following events can set preferred data subId with priority in the order of 603 * 1. Emergency call 604 * 2. Voice call (when data during call feature is enabled). 605 * 3. CBRS requests OR Auto switch requests - only one case applies at a time 606 */ 607 @Test testSetPreferredDataCasePriority_CbrsWaitsForVoiceCall()608 public void testSetPreferredDataCasePriority_CbrsWaitsForVoiceCall() throws Exception { 609 initialize(); 610 setAllPhonesInactive(); 611 612 // Phone 0 has sub 1, phone 1 has sub 2. 613 // Sub 1 is default data sub. 614 // Both are active subscriptions are active sub, as they are in both active slots. 615 setSlotIndexToSubId(0, 1); 616 setSlotIndexToSubId(1, 2); 617 // single visible sub, as the other one is CBRS 618 doReturn(new int[1]).when(mSubscriptionManagerService).getActiveSubIdList(true); 619 setDefaultDataSubId(1); 620 621 // Notify phoneSwitcher about default data sub and default network request. 622 NetworkRequest internetRequest = addInternetNetworkRequest(null, 50); 623 // Phone 0 (sub 1) should be activated as it has default data sub. 624 assertEquals(1, mPhoneSwitcherUT.getActiveDataSubId()); 625 assertTrue(mPhoneSwitcherUT.shouldApplyNetworkRequest( 626 new TelephonyNetworkRequest(internetRequest, mPhone, mFeatureFlags), 0)); 627 assertFalse(mPhoneSwitcherUT.shouldApplyNetworkRequest( 628 new TelephonyNetworkRequest(internetRequest, mPhone, mFeatureFlags), 1)); 629 630 // Set sub 2 as preferred sub should make phone 1 activated and phone 0 deactivated. 631 mPhoneSwitcherUT.trySetOpportunisticDataSubscription(2, false, null); 632 processAllMessages(); 633 mPhoneSwitcherUT.mValidationCallback.onNetworkAvailable(null, 2); 634 // A higher priority event occurring E.g. Phone1 has active IMS call on LTE. 635 doReturn(mImsPhone).when(mPhone).getImsPhone(); 636 doReturn(true).when(mPhone).isUserDataEnabled(); 637 doReturn(true).when(mDataSettingsManager).isDataEnabled(); 638 mockImsRegTech(0, REGISTRATION_TECH_LTE); 639 notifyPhoneAsInCall(mPhone); 640 641 // switch shouldn't occur due to the higher priority event 642 assertTrue(mPhoneSwitcherUT.shouldApplyNetworkRequest( 643 new TelephonyNetworkRequest(internetRequest, mPhone, mFeatureFlags), 0)); 644 assertFalse(mPhoneSwitcherUT.shouldApplyNetworkRequest( 645 new TelephonyNetworkRequest(internetRequest, mPhone, mFeatureFlags), 1)); 646 assertEquals(1, mPhoneSwitcherUT.getActiveDataSubId()); 647 assertEquals(2, mPhoneSwitcherUT.getAutoSelectedDataSubId()); 648 649 // The higher priority event ends, time to switch to auto selected subId. 650 notifyPhoneAsInactive(mPhone); 651 652 assertEquals(2, mPhoneSwitcherUT.getActiveDataSubId()); 653 assertEquals(2, mPhoneSwitcherUT.getAutoSelectedDataSubId()); 654 assertTrue(mPhoneSwitcherUT.shouldApplyNetworkRequest( 655 new TelephonyNetworkRequest(internetRequest, mPhone, mFeatureFlags), 1)); 656 assertFalse(mPhoneSwitcherUT.shouldApplyNetworkRequest( 657 new TelephonyNetworkRequest(internetRequest, mPhone, mFeatureFlags), 0)); 658 } 659 660 @Test testSetPreferredData_NoAutoSwitchWhenCbrs()661 public void testSetPreferredData_NoAutoSwitchWhenCbrs() throws Exception { 662 initialize(); 663 setAllPhonesInactive(); 664 665 // Phone 0 has sub 1, phone 1 has sub 2. 666 // Sub 1 is default data sub. 667 // Both are active subscriptions are active sub, as they are in both active slots. 668 setSlotIndexToSubId(0, 1); 669 setSlotIndexToSubId(1, 2); 670 setDefaultDataSubId(1); 671 672 clearInvocations(mCellularNetworkValidator); 673 doReturn(new int[1]).when(mSubscriptionManagerService).getActiveSubIdList(true); 674 prepareIdealAutoSwitchCondition(); 675 processAllFutureMessages(); 676 677 verify(mCellularNetworkValidator, never()).validate(eq(2), anyLong(), eq(false), 678 eq(mPhoneSwitcherUT.mValidationCallback)); 679 assertEquals(1, mPhoneSwitcherUT.getActiveDataSubId()); 680 } 681 682 @Test testSetAutoSelectedValidationFeatureNotSupported()683 public void testSetAutoSelectedValidationFeatureNotSupported() throws Exception { 684 doReturn(false).when(mCellularNetworkValidator).isValidationFeatureSupported(); 685 initialize(); 686 687 // Phone 0 has sub 1, phone 1 has sub 2. 688 // Sub 1 is default data sub. 689 // Both are active subscriptions are active sub, as they are in both active slots. 690 setSlotIndexToSubId(0, 1); 691 setSlotIndexToSubId(1, 2); 692 setDefaultDataSubId(1); 693 694 doReturn(new SubscriptionInfoInternal.Builder(mSubscriptionManagerService 695 .getSubscriptionInfoInternal(2)).setOpportunistic(1).build()) 696 .when(mSubscriptionManagerService).getSubscriptionInfoInternal(2); 697 698 mPhoneSwitcherUT.trySetOpportunisticDataSubscription(2, false, mSetOpptDataCallback1); 699 processAllMessages(); 700 mPhoneSwitcherUT.mValidationCallback.onNetworkAvailable(null, 2); 701 processAllMessages(); 702 assertEquals(2, mPhoneSwitcherUT.getAutoSelectedDataSubId()); 703 704 // Switch to the default sub, verify AutoSelectedDataSubId is the default value. 705 clearInvocations(mSetOpptDataCallback1); 706 mPhoneSwitcherUT.trySetOpportunisticDataSubscription(SubscriptionManager 707 .DEFAULT_SUBSCRIPTION_ID, true, mSetOpptDataCallback1); 708 processAllMessages(); 709 assertEquals(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, 710 mPhoneSwitcherUT.getAutoSelectedDataSubId()); 711 } 712 713 @Test testSetPreferredDataModemCommand()714 public void testSetPreferredDataModemCommand() throws Exception { 715 doReturn(true).when(mMockRadioConfig).isSetPreferredDataCommandSupported(); 716 initialize(); 717 mPhoneSwitcherUT.registerForActivePhoneSwitch(mActivePhoneSwitchHandler, 718 ACTIVE_PHONE_SWITCH, null); 719 mPhoneSwitcherUT.registerForActivePhoneSwitch(mActivePhoneSwitchHandler, 720 ACTIVE_PHONE_SWITCH, null); 721 verify(mActivePhoneSwitchHandler, times(2)).sendMessageAtTime(any(), anyLong()); 722 clearInvocations(mMockRadioConfig); 723 clearInvocations(mActivePhoneSwitchHandler); 724 725 // Phone 0 has sub 1, phone 1 has sub 2. 726 // Sub 1 is default data sub. 727 // Both are active subscriptions are active sub, as they are in both active slots. 728 setSlotIndexToSubId(0, 1); 729 setSlotIndexToSubId(1, 2); 730 setDefaultDataSubId(1); 731 // Phone 0 (sub 1) should be preferred data phone as it has default data sub. 732 verify(mMockRadioConfig).setPreferredDataModem(eq(0), any()); 733 AsyncResult res = new AsyncResult(1, null, null); 734 Message.obtain(mPhoneSwitcherUT, EVENT_MODEM_COMMAND_DONE, res).sendToTarget(); 735 processAllMessages(); 736 verify(mActivePhoneSwitchHandler, times(2)).sendMessageAtTime(any(), anyLong()); 737 clearInvocations(mMockRadioConfig); 738 clearInvocations(mActivePhoneSwitchHandler); 739 740 // Notify phoneSwitcher about default data sub and default network request. 741 // It shouldn't change anything. 742 NetworkRequest internetRequest = addInternetNetworkRequest(null, 50); 743 NetworkRequest mmsRequest = addMmsNetworkRequest(2); 744 verify(mMockRadioConfig, never()).setPreferredDataModem(anyInt(), any()); 745 verify(mActivePhoneSwitchHandler, never()).sendMessageAtTime(any(), anyLong()); 746 assertTrue(mPhoneSwitcherUT.shouldApplyNetworkRequest( 747 new TelephonyNetworkRequest(internetRequest, mPhone, mFeatureFlags), 0)); 748 assertFalse(mPhoneSwitcherUT.shouldApplyNetworkRequest( 749 new TelephonyNetworkRequest(mmsRequest, mPhone, mFeatureFlags), 0)); 750 assertFalse(mPhoneSwitcherUT.shouldApplyNetworkRequest( 751 new TelephonyNetworkRequest(internetRequest, mPhone, mFeatureFlags), 1)); 752 assertTrue(mPhoneSwitcherUT.shouldApplyNetworkRequest( 753 new TelephonyNetworkRequest(mmsRequest, mPhone, mFeatureFlags), 1)); 754 755 // Set sub 2 as preferred sub should make phone 1 preferredDataModem 756 doReturn(new SubscriptionInfoInternal.Builder(mSubscriptionManagerService 757 .getSubscriptionInfoInternal(2)).setOpportunistic(1).build()) 758 .when(mSubscriptionManagerService).getSubscriptionInfoInternal(2); 759 760 mPhoneSwitcherUT.trySetOpportunisticDataSubscription(2, false, null); 761 processAllMessages(); 762 mPhoneSwitcherUT.mValidationCallback.onNetworkAvailable(null, 2); 763 processAllMessages(); 764 verify(mMockRadioConfig).setPreferredDataModem(eq(1), any()); 765 Message.obtain(mPhoneSwitcherUT, EVENT_MODEM_COMMAND_DONE, res).sendToTarget(); 766 processAllMessages(); 767 verify(mActivePhoneSwitchHandler, times(2)).sendMessageAtTime(any(), anyLong()); 768 assertFalse(mPhoneSwitcherUT.shouldApplyNetworkRequest( 769 new TelephonyNetworkRequest(internetRequest, mPhone, mFeatureFlags), 0)); 770 assertFalse(mPhoneSwitcherUT.shouldApplyNetworkRequest( 771 new TelephonyNetworkRequest(mmsRequest, mPhone, mFeatureFlags), 0)); 772 assertTrue(mPhoneSwitcherUT.shouldApplyNetworkRequest( 773 new TelephonyNetworkRequest(internetRequest, mPhone, mFeatureFlags), 1)); 774 assertTrue(mPhoneSwitcherUT.shouldApplyNetworkRequest( 775 new TelephonyNetworkRequest(mmsRequest, mPhone, mFeatureFlags), 1)); 776 777 clearInvocations(mMockRadioConfig); 778 clearInvocations(mActivePhoneSwitchHandler); 779 780 // Unset preferred sub should make phone0 preferredDataModem again. 781 mPhoneSwitcherUT.trySetOpportunisticDataSubscription( 782 SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, false, null); 783 processAllMessages(); 784 mPhoneSwitcherUT.mValidationCallback.onNetworkAvailable(null, 1); 785 processAllMessages(); 786 787 verify(mMockRadioConfig).setPreferredDataModem(eq(0), any()); 788 Message.obtain(mPhoneSwitcherUT, EVENT_MODEM_COMMAND_DONE, res).sendToTarget(); 789 processAllMessages(); 790 verify(mActivePhoneSwitchHandler, times(2)).sendMessageAtTime(any(), anyLong()); 791 assertTrue(mPhoneSwitcherUT.shouldApplyNetworkRequest( 792 new TelephonyNetworkRequest(internetRequest, mPhone, mFeatureFlags), 0)); 793 assertFalse(mPhoneSwitcherUT.shouldApplyNetworkRequest( 794 new TelephonyNetworkRequest(mmsRequest, mPhone, mFeatureFlags), 0)); 795 assertFalse(mPhoneSwitcherUT.shouldApplyNetworkRequest( 796 new TelephonyNetworkRequest(internetRequest, mPhone, mFeatureFlags), 1)); 797 assertTrue(mPhoneSwitcherUT.shouldApplyNetworkRequest( 798 new TelephonyNetworkRequest(mmsRequest, mPhone, mFeatureFlags), 1)); 799 800 // SetDataAllowed should never be triggered. 801 verify(mCommandsInterface0, never()).setDataAllowed(anyBoolean(), any()); 802 verify(mCommandsInterface1, never()).setDataAllowed(anyBoolean(), any()); 803 804 // Set preferred data modem should be triggered after radio on or available. 805 clearInvocations(mMockRadioConfig); 806 Message.obtain(mPhoneSwitcherUT, EVENT_RADIO_ON, res).sendToTarget(); 807 processAllMessages(); 808 verify(mMockRadioConfig).setPreferredDataModem(eq(0), any()); 809 } 810 811 @Test testSetPreferredDataWithValidation()812 public void testSetPreferredDataWithValidation() throws Exception { 813 doReturn(true).when(mMockRadioConfig).isSetPreferredDataCommandSupported(); 814 initialize(); 815 816 // Phone 0 has sub 1, phone 1 has sub 2. 817 // Sub 1 is default data sub. 818 // Both are active subscriptions are active sub, as they are in both active slots. 819 setSlotIndexToSubId(0, 1); 820 setSlotIndexToSubId(1, 2); 821 setDefaultDataSubId(1); 822 823 doReturn(new SubscriptionInfoInternal.Builder(mSubscriptionManagerService 824 .getSubscriptionInfoInternal(2)).setOpportunistic(1).build()) 825 .when(mSubscriptionManagerService).getSubscriptionInfoInternal(2); 826 827 // Phone 0 (sub 1) should be activated as it has default data sub. 828 assertEquals(0, mPhoneSwitcherUT.getPreferredDataPhoneId()); 829 830 // Set sub 2 as preferred sub should make phone 1 activated and phone 0 deactivated. 831 mPhoneSwitcherUT.trySetOpportunisticDataSubscription(2, true, null); 832 processAllMessages(); 833 verify(mCellularNetworkValidator).validate(eq(2), anyLong(), eq(false), 834 eq(mPhoneSwitcherUT.mValidationCallback)); 835 // Validation failed. Preferred data sub should remain 1, data phone should remain 0. 836 mPhoneSwitcherUT.mValidationCallback.onValidationDone(false, 2); 837 processAllMessages(); 838 assertEquals(0, mPhoneSwitcherUT.getPreferredDataPhoneId()); 839 840 // Validation succeeds. Preferred data sub changes to 2, data phone changes to 1. 841 mPhoneSwitcherUT.trySetOpportunisticDataSubscription(2, true, null); 842 processAllMessages(); 843 mPhoneSwitcherUT.mValidationCallback.onValidationDone(true, 2); 844 processAllMessages(); 845 assertEquals(1, mPhoneSwitcherUT.getPreferredDataPhoneId()); 846 847 // Switching data back to primary (subId 1) with customized validation timeout. 848 long timeout = 1234; 849 mContextFixture.getCarrierConfigBundle().putLong( 850 KEY_DATA_SWITCH_VALIDATION_TIMEOUT_LONG, timeout); 851 mPhoneSwitcherUT.trySetOpportunisticDataSubscription( 852 SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, true, null); 853 processAllMessages(); 854 verify(mCellularNetworkValidator).validate(eq(1), eq(timeout), eq(false), 855 eq(mPhoneSwitcherUT.mValidationCallback)); 856 mPhoneSwitcherUT.mValidationCallback.onValidationDone(true, 1); 857 processAllMessages(); 858 assertEquals(0, mPhoneSwitcherUT.getPreferredDataPhoneId()); 859 } 860 mockImsRegTech(int phoneId, int regTech)861 private void mockImsRegTech(int phoneId, int regTech) { 862 doReturn(regTech).when(mMockImsRegTechProvider).get(any(), eq(phoneId)); 863 mPhoneSwitcherUT.mImsRegTechProvider = mMockImsRegTechProvider; 864 } 865 mockImsRegisterCallback(int phoneId)866 private void mockImsRegisterCallback(int phoneId) throws ImsException { 867 doNothing().when(mMockImsRegisterCallback).setCallback(any(), eq(phoneId), any(), any()); 868 mPhoneSwitcherUT.mImsRegisterCallback = mMockImsRegisterCallback; 869 } 870 871 @Test testNonDefaultDataPhoneInCall_ImsCallOnLte_shouldSwitchDds()872 public void testNonDefaultDataPhoneInCall_ImsCallOnLte_shouldSwitchDds() throws Exception { 873 initialize(); 874 setAllPhonesInactive(); 875 876 // Phone 0 has sub 1, phone 1 has sub 2. 877 // Sub 1 is default data sub. 878 // Both are active subscriptions are active sub, as they are in both active slots. 879 setSlotIndexToSubId(0, 1); 880 setSlotIndexToSubId(1, 2); 881 setDefaultDataSubId(1); 882 processAllMessages(); 883 884 // Phone 0 should be the default data phoneId. 885 assertEquals(0, mPhoneSwitcherUT.getPreferredDataPhoneId()); 886 887 // Phone2 has active IMS call on LTE. And data of DEFAULT apn is enabled. This should 888 // trigger data switch. 889 doReturn(mImsPhone).when(mPhone2).getImsPhone(); 890 doReturn(true).when(mDataSettingsManager2).isDataEnabled(); 891 mockImsRegTech(1, REGISTRATION_TECH_LTE); 892 notifyPhoneAsInCall(mImsPhone); 893 894 // Phone 1 should become the preferred data phone. 895 assertEquals(1, mPhoneSwitcherUT.getPreferredDataPhoneId()); 896 } 897 898 @Test testNonDefaultDataPhoneInCall_ImsCallDialingOnLte_shouldSwitchDds()899 public void testNonDefaultDataPhoneInCall_ImsCallDialingOnLte_shouldSwitchDds() 900 throws Exception { 901 initialize(); 902 setAllPhonesInactive(); 903 904 // Phone 0 has sub 1, phone 1 has sub 2. 905 // Sub 1 is default data sub. 906 // Both are active subscriptions are active sub, as they are in both active slots. 907 setSlotIndexToSubId(0, 1); 908 setSlotIndexToSubId(1, 2); 909 setDefaultDataSubId(1); 910 processAllMessages(); 911 912 // Phone 0 should be the default data phoneId. 913 assertEquals(0, mPhoneSwitcherUT.getPreferredDataPhoneId()); 914 915 // Dialing shouldn't trigger switch because we give modem time to deal with the dialing call 916 // first. Phone2 has active IMS call on LTE. And data of DEFAULT apn is enabled. 917 doReturn(mImsPhone).when(mPhone2).getImsPhone(); 918 doReturn(true).when(mDataSettingsManager2).isDataEnabled(); 919 mockImsRegTech(1, REGISTRATION_TECH_LTE); 920 notifyPhoneAsInDial(mImsPhone); 921 922 // Phone1 should remain as the preferred data phone 923 assertEquals(0, mPhoneSwitcherUT.getPreferredDataPhoneId()); 924 925 // Dialing -> Alert, should trigger phone switch 926 notifyPhoneAsAlerting(mImsPhone); 927 928 // Phone2 should be preferred data phone 929 assertEquals(1, mPhoneSwitcherUT.getPreferredDataPhoneId()); 930 } 931 @Test testNonDefaultDataPhoneInCall_ImsCallIncomingOnLte_shouldSwitchDds()932 public void testNonDefaultDataPhoneInCall_ImsCallIncomingOnLte_shouldSwitchDds() 933 throws Exception { 934 initialize(); 935 setAllPhonesInactive(); 936 937 // Phone 0 has sub 1, phone 1 has sub 2. 938 // Sub 1 is default data sub. 939 // Both are active subscriptions are active sub, as they are in both active slots. 940 setSlotIndexToSubId(0, 1); 941 setSlotIndexToSubId(1, 2); 942 setDefaultDataSubId(1); 943 processAllMessages(); 944 945 // Phone 0 should be the default data phoneId. 946 assertEquals(0, mPhoneSwitcherUT.getPreferredDataPhoneId()); 947 948 // Phone2 has active IMS call on LTE. And data of DEFAULT apn is enabled. This should 949 // trigger data switch. 950 doReturn(mImsPhone).when(mPhone2).getImsPhone(); 951 doReturn(true).when(mDataSettingsManager2).isDataEnabled(); 952 mockImsRegTech(1, REGISTRATION_TECH_LTE); 953 notifyPhoneAsInIncomingCall(mImsPhone); 954 955 // Phone 1 should become the preferred data phone. 956 assertEquals(1, mPhoneSwitcherUT.getPreferredDataPhoneId()); 957 } 958 959 @Test testNonDefaultDataPhoneInCall_ImsCallOnWlan_shouldNotSwitchDds()960 public void testNonDefaultDataPhoneInCall_ImsCallOnWlan_shouldNotSwitchDds() throws Exception { 961 initialize(); 962 setAllPhonesInactive(); 963 964 // Phone 0 has sub 1, phone 1 has sub 2. 965 // Sub 1 is default data sub. 966 // Both are active subscriptions are active sub, as they are in both active slots. 967 setSlotIndexToSubId(0, 1); 968 setSlotIndexToSubId(1, 2); 969 setDefaultDataSubId(1); 970 processAllMessages(); 971 972 // Phone 0 should be the default data phoneId. 973 assertEquals(0, mPhoneSwitcherUT.getPreferredDataPhoneId()); 974 975 // Phone2 has active call, but data is turned off. So no data switching should happen. 976 doReturn(mImsPhone).when(mPhone2).getImsPhone(); 977 doReturn(true).when(mDataSettingsManager2).isDataEnabled(); 978 mockImsRegTech(1, REGISTRATION_TECH_IWLAN); 979 notifyPhoneAsInCall(mImsPhone); 980 981 // Phone 0 should remain the default data phone. 982 assertEquals(0, mPhoneSwitcherUT.getPreferredDataPhoneId()); 983 } 984 985 @Test testNonDefaultDataPhoneInCall_ImsCallOnCrossSIM_HandoverToLTE()986 public void testNonDefaultDataPhoneInCall_ImsCallOnCrossSIM_HandoverToLTE() throws Exception { 987 initialize(); 988 setAllPhonesInactive(); 989 990 // Phone 0 has sub 1, phone 1 has sub 2. 991 // Sub 1 is default data sub. 992 // Both are active subscriptions are active sub, as they are in both active slots. 993 setSlotIndexToSubId(0, 1); 994 setSlotIndexToSubId(1, 2); 995 setDefaultDataSubId(1); 996 processAllMessages(); 997 998 // Phone 0 should be the default data phoneId. 999 assertEquals(0, mPhoneSwitcherUT.getPreferredDataPhoneId()); 1000 1001 // Phone 1 has active IMS call on CROSS_SIM. And data of DEFAULT apn is enabled. This should 1002 // not trigger data switch. 1003 doReturn(mImsPhone).when(mPhone2).getImsPhone(); 1004 doReturn(true).when(mPhone).isUserDataEnabled(); 1005 doReturn(true).when(mDataSettingsManager2).isDataEnabled(); 1006 mockImsRegTech(1, REGISTRATION_TECH_CROSS_SIM); 1007 notifyPhoneAsInCall(mImsPhone); 1008 1009 // Phone 0 should remain the default data phone. 1010 assertEquals(0, mPhoneSwitcherUT.getPreferredDataPhoneId()); 1011 1012 // Phone 1 has has handed over the call to LTE. And data of DEFAULT apn is enabled. 1013 // This should trigger data switch. 1014 mockImsRegTech(1, REGISTRATION_TECH_LTE); 1015 notifyImsRegistrationTechChange(mPhone2); 1016 1017 // Phone 1 should become the default data phone. 1018 assertEquals(1, mPhoneSwitcherUT.getPreferredDataPhoneId()); 1019 } 1020 1021 @Test testNonDefaultDataPhoneInCall()1022 public void testNonDefaultDataPhoneInCall() throws Exception { 1023 doReturn(true).when(mMockRadioConfig).isSetPreferredDataCommandSupported(); 1024 initialize(); 1025 // Phone 0 has sub 1, phone 1 has sub 2. 1026 // Sub 1 is default data sub. 1027 // Both are active subscriptions are active sub, as they are in both active slots. 1028 setSlotIndexToSubId(0, 1); 1029 setSlotIndexToSubId(1, 2); 1030 setDefaultDataSubId(1); 1031 NetworkRequest internetRequest = addInternetNetworkRequest(null, 50); 1032 assertTrue(mPhoneSwitcherUT.shouldApplyNetworkRequest( 1033 new TelephonyNetworkRequest(internetRequest, mPhone, mFeatureFlags), 0)); 1034 assertFalse(mPhoneSwitcherUT.shouldApplyNetworkRequest( 1035 new TelephonyNetworkRequest(internetRequest, mPhone, mFeatureFlags), 1)); 1036 clearInvocations(mMockRadioConfig); 1037 setAllPhonesInactive(); 1038 // Initialization done. 1039 1040 // Phone2 has active call, but data is turned off. So no data switching should happen. 1041 notifyDataEnabled(false); 1042 notifyPhoneAsInCall(mPhone2); 1043 verify(mMockRadioConfig, never()).setPreferredDataModem(anyInt(), any()); 1044 assertTrue(mPhoneSwitcherUT.shouldApplyNetworkRequest( 1045 new TelephonyNetworkRequest(internetRequest, mPhone, mFeatureFlags), 0)); 1046 assertFalse(mPhoneSwitcherUT.shouldApplyNetworkRequest( 1047 new TelephonyNetworkRequest(internetRequest, mPhone, mFeatureFlags), 1)); 1048 1049 // Phone2 has active call, and data is on. So data switch to it. 1050 doReturn(true).when(mPhone).isUserDataEnabled(); 1051 notifyDataEnabled(true); 1052 verify(mMockRadioConfig).setPreferredDataModem(eq(1), any()); 1053 assertTrue(mPhoneSwitcherUT.shouldApplyNetworkRequest( 1054 new TelephonyNetworkRequest(internetRequest, mPhone, mFeatureFlags), 1)); 1055 assertFalse(mPhoneSwitcherUT.shouldApplyNetworkRequest( 1056 new TelephonyNetworkRequest(internetRequest, mPhone, mFeatureFlags), 0)); 1057 clearInvocations(mMockRadioConfig); 1058 1059 // Phone2(nDDS) call ended. But Phone1 having cross-SIM call. Don't switch. 1060 mockImsRegTech(0, REGISTRATION_TECH_CROSS_SIM); 1061 notifyPhoneAsInIncomingCall(mPhone); 1062 notifyPhoneAsInactive(mPhone2); 1063 verify(mMockRadioConfig, never()).setPreferredDataModem(anyInt(), any()); 1064 assertTrue(mPhoneSwitcherUT.shouldApplyNetworkRequest( 1065 new TelephonyNetworkRequest(internetRequest, mPhone, mFeatureFlags), 1)); 1066 assertFalse(mPhoneSwitcherUT.shouldApplyNetworkRequest( 1067 new TelephonyNetworkRequest(internetRequest, mPhone, mFeatureFlags), 0)); 1068 1069 // Phone(DDS) call ended. 1070 // Honor auto data switch's suggestion: if DDS is OOS, auto switch to Phone2(nDDS). 1071 notifyPhoneAsInactive(mPhone); 1072 verify(mAutoDataSwitchController).evaluateAutoDataSwitch(EVALUATION_REASON_VOICE_CALL_END); 1073 mAutoDataSwitchCallback.onRequireValidation(1 /*Phone2*/, true); 1074 1075 // verify immediately switch back to DDS upon call ends 1076 verify(mMockRadioConfig).setPreferredDataModem(eq(0), any()); 1077 assertTrue(mPhoneSwitcherUT.shouldApplyNetworkRequest( 1078 new TelephonyNetworkRequest(internetRequest, mPhone, mFeatureFlags), 0)); 1079 assertFalse(mPhoneSwitcherUT.shouldApplyNetworkRequest( 1080 new TelephonyNetworkRequest(internetRequest, mPhone, mFeatureFlags), 1)); 1081 1082 // verify the attempt to do auto data switch to Phone2(nDDS) 1083 processAllFutureMessages(); 1084 verify(mCellularNetworkValidator).validate(eq(2), anyLong(), eq(false), 1085 eq(mPhoneSwitcherUT.mValidationCallback)); 1086 1087 // Phone2 has holding call on VoWifi, no need to switch data 1088 clearInvocations(mMockRadioConfig); 1089 mockImsRegTech(1, REGISTRATION_TECH_IWLAN); 1090 notifyPhoneAsInHoldingCall(mPhone2); 1091 verify(mMockRadioConfig, never()).setPreferredDataModem(anyInt(), any()); 1092 assertTrue(mPhoneSwitcherUT.shouldApplyNetworkRequest( 1093 new TelephonyNetworkRequest(internetRequest, mPhone, mFeatureFlags), 0)); 1094 assertFalse(mPhoneSwitcherUT.shouldApplyNetworkRequest( 1095 new TelephonyNetworkRequest(internetRequest, mPhone, mFeatureFlags), 1)); 1096 } 1097 1098 @Test testDataEnabledChangedDuringVoiceCall()1099 public void testDataEnabledChangedDuringVoiceCall() throws Exception { 1100 doReturn(true).when(mMockRadioConfig).isSetPreferredDataCommandSupported(); 1101 initialize(); 1102 // Phone 0 has sub 1, phone 1 has sub 2. 1103 // Sub 1 is default data sub. 1104 // Both are active subscriptions are active sub, as they are in both active slots. 1105 setSlotIndexToSubId(0, 1); 1106 setSlotIndexToSubId(1, 2); 1107 setDefaultDataSubId(1); 1108 NetworkRequest internetRequest = addInternetNetworkRequest(null, 50); 1109 assertTrue(mPhoneSwitcherUT.shouldApplyNetworkRequest( 1110 new TelephonyNetworkRequest(internetRequest, mPhone, mFeatureFlags), 0)); 1111 assertFalse(mPhoneSwitcherUT.shouldApplyNetworkRequest( 1112 new TelephonyNetworkRequest(internetRequest, mPhone, mFeatureFlags), 1)); 1113 clearInvocations(mMockRadioConfig); 1114 setAllPhonesInactive(); 1115 // Initialization done. 1116 1117 // Phone2 has active call and data is on. So switch to nDDS Phone2 1118 notifyDataEnabled(true); 1119 notifyPhoneAsInCall(mPhone2); 1120 verify(mMockRadioConfig).setPreferredDataModem(eq(1), any()); 1121 assertFalse(mPhoneSwitcherUT.shouldApplyNetworkRequest( 1122 new TelephonyNetworkRequest(internetRequest, mPhone, mFeatureFlags), 0)); 1123 assertTrue(mPhoneSwitcherUT.shouldApplyNetworkRequest( 1124 new TelephonyNetworkRequest(internetRequest, mPhone, mFeatureFlags), 1)); 1125 1126 // During the active call, user turns off data, should immediately switch back to DDS 1127 notifyDataEnabled(false); 1128 verify(mMockRadioConfig).setPreferredDataModem(eq(0), any()); 1129 assertTrue(mPhoneSwitcherUT.shouldApplyNetworkRequest( 1130 new TelephonyNetworkRequest(internetRequest, mPhone, mFeatureFlags), 0)); 1131 assertFalse(mPhoneSwitcherUT.shouldApplyNetworkRequest( 1132 new TelephonyNetworkRequest(internetRequest, mPhone, mFeatureFlags), 1)); 1133 } 1134 1135 @Test testRoamingToggle()1136 public void testRoamingToggle() throws Exception { 1137 initialize(); 1138 setSlotIndexToSubId(0, 1); 1139 1140 mDataSettingsManagerCallbacks.get(0).onDataRoamingEnabledChanged(true); 1141 processAllMessages(); 1142 1143 verify(mAutoDataSwitchController).evaluateAutoDataSwitch(AutoDataSwitchController 1144 .EVALUATION_REASON_DATA_SETTINGS_CHANGED); 1145 } 1146 1147 @Test testNetworkRequestOnNonDefaultData()1148 public void testNetworkRequestOnNonDefaultData() throws Exception { 1149 doReturn(true).when(mMockRadioConfig).isSetPreferredDataCommandSupported(); 1150 initialize(); 1151 // Phone 0 has sub 1, phone 1 has sub 2. 1152 // Sub 1 is default data sub. 1153 // Both are active subscriptions are active sub, as they are in both active slots. 1154 setSlotIndexToSubId(0, 1); 1155 setSlotIndexToSubId(1, 2); 1156 setDefaultDataSubId(1); 1157 NetworkRequest internetRequest = addInternetNetworkRequest(2, 50); 1158 assertFalse(mPhoneSwitcherUT.shouldApplyNetworkRequest( 1159 new TelephonyNetworkRequest(internetRequest, mPhone, mFeatureFlags), 0)); 1160 assertFalse(mPhoneSwitcherUT.shouldApplyNetworkRequest( 1161 new TelephonyNetworkRequest(internetRequest, mPhone, mFeatureFlags), 1)); 1162 1163 // Restricted network request will should be applied. 1164 internetRequest = addInternetNetworkRequest(2, 50, true); 1165 assertFalse(mPhoneSwitcherUT.shouldApplyNetworkRequest( 1166 new TelephonyNetworkRequest(internetRequest, mPhone, mFeatureFlags), 0)); 1167 assertTrue(mPhoneSwitcherUT.shouldApplyNetworkRequest( 1168 new TelephonyNetworkRequest(internetRequest, mPhone, mFeatureFlags), 1)); 1169 } 1170 1171 @Test testEmergencyOverrideSuccessBeforeCallStarts()1172 public void testEmergencyOverrideSuccessBeforeCallStarts() throws Exception { 1173 doReturn(true).when(mMockRadioConfig).isSetPreferredDataCommandSupported(); 1174 initialize(); 1175 // Phone 0 has sub 1, phone 1 has sub 2. 1176 // Sub 1 is default data sub. 1177 // Both are active subscriptions are active sub, as they are in both active slots. 1178 setMsimDefaultDataSubId(1); 1179 clearInvocations(mMockRadioConfig); 1180 1181 // override the phone ID in prep for emergency call 1182 mPhoneSwitcherUT.overrideDefaultDataForEmergency(1, 1, mFuturePhone); 1183 sendPreferredDataSuccessResult(1); 1184 processAllMessages(); 1185 verify(mFuturePhone).complete(true); 1186 1187 // Make sure the correct broadcast is sent out for the overridden phone ID 1188 verify(mTelephonyRegistryManager).notifyActiveDataSubIdChanged(eq(2)); 1189 } 1190 1191 @Test testEmergencyOverrideNoDdsChange()1192 public void testEmergencyOverrideNoDdsChange() throws Exception { 1193 doReturn(true).when(mMockRadioConfig).isSetPreferredDataCommandSupported(); 1194 initialize(); 1195 // Phone 0 has sub 1, phone 1 has sub 2. 1196 // Sub 1 is default data sub. 1197 // Both are active subscriptions are active sub, as they are in both active slots. 1198 setMsimDefaultDataSubId(1); 1199 clearInvocations(mMockRadioConfig); 1200 1201 // override the phone ID in prep for emergency call 1202 mPhoneSwitcherUT.overrideDefaultDataForEmergency(0, 1, mFuturePhone); 1203 processAllMessages(); 1204 // The radio command should never be called because the DDS hasn't changed. 1205 verify(mMockRadioConfig, never()).setPreferredDataModem(eq(0), any()); 1206 processAllMessages(); 1207 verify(mFuturePhone).complete(true); 1208 } 1209 1210 @Test testEmergencyOverrideEndSuccess()1211 public void testEmergencyOverrideEndSuccess() throws Exception { 1212 PhoneSwitcher.ECBM_DEFAULT_DATA_SWITCH_BASE_TIME_MS = 500; 1213 doReturn(true).when(mMockRadioConfig).isSetPreferredDataCommandSupported(); 1214 initialize(); 1215 // Phone 0 has sub 1, phone 1 has sub 2. 1216 // Sub 1 is default data sub. 1217 // Both are active subscriptions are active sub, as they are in both active slots. 1218 setMsimDefaultDataSubId(1); 1219 setAllPhonesInactive(); 1220 clearInvocations(mMockRadioConfig); 1221 clearInvocations(mTelephonyRegistryManager); 1222 1223 // override the phone ID in prep for emergency call 1224 1225 mPhoneSwitcherUT.overrideDefaultDataForEmergency(1, 1, mFuturePhone); 1226 sendPreferredDataSuccessResult(1); 1227 processAllMessages(); 1228 verify(mFuturePhone).complete(true); 1229 1230 // Start and end the emergency call, which will start override timer 1231 notifyPhoneAsInCall(mPhone2); 1232 notifyPhoneAsInactive(mPhone2); 1233 1234 clearInvocations(mTelephonyRegistryManager); 1235 // Verify that the DDS is successfully switched back after 1 second + base ECBM timeout 1236 moveTimeForward(ECBM_DEFAULT_DATA_SWITCH_BASE_TIME_MS + 1000); 1237 processAllMessages(); 1238 verify(mMockRadioConfig).setPreferredDataModem(eq(0), any()); 1239 AsyncResult res = new AsyncResult(1, null, null); 1240 Message.obtain(mPhoneSwitcherUT, EVENT_MODEM_COMMAND_DONE, res).sendToTarget(); 1241 processAllMessages(); 1242 1243 // Make sure the correct broadcast is sent out for the phone ID 1244 verify(mTelephonyRegistryManager).notifyActiveDataSubIdChanged(eq(1)); 1245 } 1246 1247 @Test testEmergencyOverrideEcbmStartEnd()1248 public void testEmergencyOverrideEcbmStartEnd() throws Exception { 1249 PhoneSwitcher.ECBM_DEFAULT_DATA_SWITCH_BASE_TIME_MS = 500; 1250 doReturn(true).when(mMockRadioConfig).isSetPreferredDataCommandSupported(); 1251 initialize(); 1252 // Phone 0 has sub 1, phone 1 has sub 2. 1253 // Sub 1 is default data sub. 1254 // Both are active subscriptions are active sub, as they are in both active slots. 1255 setMsimDefaultDataSubId(1); 1256 setAllPhonesInactive(); 1257 clearInvocations(mMockRadioConfig); 1258 clearInvocations(mTelephonyRegistryManager); 1259 1260 // override the phone ID in prep for emergency call 1261 mPhoneSwitcherUT.overrideDefaultDataForEmergency(1, 1, mFuturePhone); 1262 sendPreferredDataSuccessResult(1); 1263 processAllMessages(); 1264 verify(mFuturePhone).complete(true); 1265 1266 // Start and end the emergency call, which will start override timer 1267 notifyPhoneAsInCall(mPhone2); 1268 notifyPhoneAsInactive(mPhone2); 1269 // Start ECBM 1270 Message ecbmMessage = getEcbmRegistration(mPhone2); 1271 notifyEcbmStart(mPhone2, ecbmMessage); 1272 1273 // DDS should not be switched back until ECBM ends, make sure there is no further 1274 // interaction. 1275 moveTimeForward(ECBM_DEFAULT_DATA_SWITCH_BASE_TIME_MS + 2000); 1276 processAllMessages(); 1277 verify(mMockRadioConfig, never()).setPreferredDataModem(eq(0), any()); 1278 // Make sure the correct broadcast is sent out for the phone ID 1279 verify(mTelephonyRegistryManager).notifyActiveDataSubIdChanged(eq(2)); 1280 1281 // End ECBM 1282 clearInvocations(mTelephonyRegistryManager); 1283 ecbmMessage = getEcbmRegistration(mPhone2); 1284 notifyEcbmEnd(mPhone2, ecbmMessage); 1285 // Verify that the DDS is successfully switched back after 1 second. 1286 moveTimeForward(1000); 1287 processAllMessages(); 1288 verify(mMockRadioConfig).setPreferredDataModem(eq(0), any()); 1289 AsyncResult res = new AsyncResult(1, null, null); 1290 Message.obtain(mPhoneSwitcherUT, EVENT_MODEM_COMMAND_DONE, res).sendToTarget(); 1291 processAllMessages(); 1292 // Make sure the correct broadcast is sent out for the phone ID 1293 verify(mTelephonyRegistryManager).notifyActiveDataSubIdChanged(eq(1)); 1294 } 1295 1296 @Test testEmergencyOverrideNoCallStart()1297 public void testEmergencyOverrideNoCallStart() throws Exception { 1298 PhoneSwitcher.DEFAULT_DATA_OVERRIDE_TIMEOUT_MS = 500; 1299 doReturn(true).when(mMockRadioConfig).isSetPreferredDataCommandSupported(); 1300 initialize(); 1301 // Phone 0 has sub 1, phone 1 has sub 2. 1302 // Sub 1 is default data sub. 1303 // Both are active subscriptions are active sub, as they are in both active slots. 1304 setMsimDefaultDataSubId(1); 1305 setAllPhonesInactive(); 1306 clearInvocations(mMockRadioConfig); 1307 clearInvocations(mTelephonyRegistryManager); 1308 1309 // override the phone ID in prep for emergency call 1310 mPhoneSwitcherUT.overrideDefaultDataForEmergency(1, 1, mFuturePhone); 1311 sendPreferredDataSuccessResult(1); 1312 processAllMessages(); 1313 verify(mFuturePhone).complete(true); 1314 1315 // Do not start the call and make sure the override is removed once the timeout expires 1316 moveTimeForward(PhoneSwitcher.DEFAULT_DATA_OVERRIDE_TIMEOUT_MS); 1317 processAllMessages(); 1318 verify(mMockRadioConfig).setPreferredDataModem(eq(0), any()); 1319 AsyncResult res = new AsyncResult(1, null, null); 1320 Message.obtain(mPhoneSwitcherUT, EVENT_MODEM_COMMAND_DONE, res).sendToTarget(); 1321 processAllMessages(); 1322 1323 // Make sure the correct broadcast is sent out for the phone ID 1324 verify(mTelephonyRegistryManager).notifyActiveDataSubIdChanged(eq(1)); 1325 } 1326 1327 @Test testEmergencyOverrideMultipleOverrideRequests()1328 public void testEmergencyOverrideMultipleOverrideRequests() throws Exception { 1329 PhoneSwitcher.ECBM_DEFAULT_DATA_SWITCH_BASE_TIME_MS = 500; 1330 doReturn(true).when(mMockRadioConfig).isSetPreferredDataCommandSupported(); 1331 initialize(); 1332 // Phone 0 has sub 1, phone 1 has sub 2. 1333 // Sub 1 is default data sub. 1334 // Both are active subscriptions are active sub, as they are in both active slots. 1335 setMsimDefaultDataSubId(1); 1336 setAllPhonesInactive(); 1337 clearInvocations(mMockRadioConfig); 1338 clearInvocations(mTelephonyRegistryManager); 1339 1340 // override the phone ID in prep for emergency call 1341 LinkedBlockingQueue<Boolean> queue = new LinkedBlockingQueue<>(); 1342 CompletableFuture<Boolean> futurePhone = new CompletableFuture<>(); 1343 futurePhone.whenComplete((r, error) -> queue.offer(r)); 1344 mPhoneSwitcherUT.overrideDefaultDataForEmergency(1, 1, futurePhone); 1345 sendPreferredDataSuccessResult(1); 1346 processAllMessages(); 1347 Boolean result = queue.poll(); 1348 assertNotNull(result); 1349 assertTrue(result); 1350 1351 // try override the phone ID again while there is an existing override for a different phone 1352 futurePhone = new CompletableFuture<>(); 1353 futurePhone.whenComplete((r, error) -> queue.offer(r)); 1354 mPhoneSwitcherUT.overrideDefaultDataForEmergency(0, 1, futurePhone); 1355 processAllMessages(); 1356 result = queue.poll(); 1357 assertNotNull(result); 1358 assertFalse(result); 1359 verify(mMockRadioConfig, never()).setPreferredDataModem(eq(0), any()); 1360 1361 // Start and end the emergency call, which will start override timer 1362 notifyPhoneAsInCall(mPhone2); 1363 notifyPhoneAsInactive(mPhone2); 1364 1365 // Verify that the DDS is successfully switched back after 1 second + base ECBM timeout 1366 moveTimeForward(ECBM_DEFAULT_DATA_SWITCH_BASE_TIME_MS + 1000); 1367 processAllMessages(); 1368 verify(mMockRadioConfig).setPreferredDataModem(eq(0), any()); 1369 AsyncResult res = new AsyncResult(1, null, null); 1370 Message.obtain(mPhoneSwitcherUT, EVENT_MODEM_COMMAND_DONE, res).sendToTarget(); 1371 processAllMessages(); 1372 1373 // Make sure the correct broadcast is sent out for the phone ID 1374 verify(mTelephonyRegistryManager).notifyActiveDataSubIdChanged(eq(1)); 1375 } 1376 1377 @Test testSetPreferredDataCallback()1378 public void testSetPreferredDataCallback() throws Exception { 1379 doReturn(true).when(mMockRadioConfig).isSetPreferredDataCommandSupported(); 1380 initialize(); 1381 1382 // Phone 0 has sub 1, phone 1 has sub 2. 1383 // Sub 1 is default data sub. 1384 // Both are active subscriptions are active sub, as they are in both active slots. 1385 setSlotIndexToSubId(0, 1); 1386 setSlotIndexToSubId(1, 2); 1387 1388 doReturn(new SubscriptionInfoInternal.Builder(mSubscriptionManagerService 1389 .getSubscriptionInfoInternal(2)).setOpportunistic(1).build()) 1390 .when(mSubscriptionManagerService).getSubscriptionInfoInternal(2); 1391 1392 // Switch to primary before a primary is selected/inactive. 1393 setDefaultDataSubId(SubscriptionManager.INVALID_SUBSCRIPTION_ID); 1394 mPhoneSwitcherUT.trySetOpportunisticDataSubscription( 1395 SubscriptionManager.INVALID_SUBSCRIPTION_ID, false, mSetOpptDataCallback1); 1396 processAllMessages(); 1397 1398 assertEquals(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, 1399 mPhoneSwitcherUT.getAutoSelectedDataSubId()); 1400 verify(mSetOpptDataCallback1).onComplete(SET_OPPORTUNISTIC_SUB_INACTIVE_SUBSCRIPTION); 1401 1402 // Verify that the switch to default sub is successful 1403 mPhoneSwitcherUT.trySetOpportunisticDataSubscription( 1404 SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, false, mSetOpptDataCallback1); 1405 processAllMessages(); 1406 1407 assertEquals(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, 1408 mPhoneSwitcherUT.getAutoSelectedDataSubId()); 1409 verify(mSetOpptDataCallback1).onComplete(SET_OPPORTUNISTIC_SUB_SUCCESS); 1410 1411 // once the primary is selected, it becomes the active sub. 1412 setDefaultDataSubId(2); 1413 assertEquals(2, mPhoneSwitcherUT.getActiveDataSubId()); 1414 1415 setDefaultDataSubId(1); 1416 // Validating on sub 10 which is inactive. 1417 clearInvocations(mSetOpptDataCallback1); 1418 mPhoneSwitcherUT.trySetOpportunisticDataSubscription(10, true, mSetOpptDataCallback1); 1419 processAllMessages(); 1420 verify(mSetOpptDataCallback1).onComplete(SET_OPPORTUNISTIC_SUB_INACTIVE_SUBSCRIPTION); 1421 1422 // Switch to active subId without validating. Should always succeed. 1423 mPhoneSwitcherUT.trySetOpportunisticDataSubscription(2, false, mSetOpptDataCallback1); 1424 processAllMessages(); 1425 mPhoneSwitcherUT.mValidationCallback.onNetworkAvailable(null, 2); 1426 processAllMessages(); 1427 verify(mSetOpptDataCallback1).onComplete(SET_OPPORTUNISTIC_SUB_SUCCESS); 1428 1429 // Validating on sub 1 and fails. 1430 clearInvocations(mSetOpptDataCallback1); 1431 mPhoneSwitcherUT.trySetOpportunisticDataSubscription(1, true, mSetOpptDataCallback1); 1432 processAllMessages(); 1433 mPhoneSwitcherUT.mValidationCallback.onValidationDone(false, 1); 1434 processAllMessages(); 1435 verify(mSetOpptDataCallback1).onComplete(SET_OPPORTUNISTIC_SUB_VALIDATION_FAILED); 1436 1437 // Validating on sub 2 and succeeds. 1438 mPhoneSwitcherUT.trySetOpportunisticDataSubscription(2, true, mSetOpptDataCallback2); 1439 processAllMessages(); 1440 mPhoneSwitcherUT.mValidationCallback.onValidationDone(true, 2); 1441 processAllMessages(); 1442 verify(mSetOpptDataCallback2).onComplete(SET_OPPORTUNISTIC_SUB_SUCCESS); 1443 1444 // Switching data back to primary and validation fails. 1445 clearInvocations(mSetOpptDataCallback2); 1446 mPhoneSwitcherUT.trySetOpportunisticDataSubscription( 1447 SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, true, mSetOpptDataCallback2); 1448 processAllMessages(); 1449 mPhoneSwitcherUT.mValidationCallback.onValidationDone(false, 1); 1450 processAllMessages(); 1451 verify(mSetOpptDataCallback1).onComplete(SET_OPPORTUNISTIC_SUB_VALIDATION_FAILED); 1452 1453 // Switching data back to primary and succeeds. 1454 clearInvocations(mSetOpptDataCallback2); 1455 mPhoneSwitcherUT.trySetOpportunisticDataSubscription( 1456 SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, true, mSetOpptDataCallback2); 1457 processAllMessages(); 1458 mPhoneSwitcherUT.mValidationCallback.onValidationDone(true, 1); 1459 processAllMessages(); 1460 verify(mSetOpptDataCallback2).onComplete(SET_OPPORTUNISTIC_SUB_SUCCESS); 1461 1462 // Back to back call on same subId. 1463 clearInvocations(mSetOpptDataCallback1); 1464 clearInvocations(mSetOpptDataCallback2); 1465 clearInvocations(mCellularNetworkValidator); 1466 mPhoneSwitcherUT.trySetOpportunisticDataSubscription(2, true, mSetOpptDataCallback1); 1467 processAllMessages(); 1468 verify(mCellularNetworkValidator).validate(eq(2), anyLong(), eq(false), 1469 eq(mPhoneSwitcherUT.mValidationCallback)); 1470 doReturn(true).when(mCellularNetworkValidator).isValidating(); 1471 mPhoneSwitcherUT.trySetOpportunisticDataSubscription(2, true, mSetOpptDataCallback2); 1472 processAllMessages(); 1473 verify(mSetOpptDataCallback1).onComplete(SET_OPPORTUNISTIC_SUB_VALIDATION_FAILED); 1474 verify(mSetOpptDataCallback2, never()).onComplete(anyInt()); 1475 // Validation succeeds. 1476 doReturn(false).when(mCellularNetworkValidator).isValidating(); 1477 mPhoneSwitcherUT.mValidationCallback.onValidationDone(true, 2); 1478 processAllMessages(); 1479 verify(mSetOpptDataCallback2).onComplete(SET_OPPORTUNISTIC_SUB_SUCCESS); 1480 1481 mPhoneSwitcherUT.trySetOpportunisticDataSubscription( 1482 SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, false, null); 1483 processAllMessages(); 1484 mPhoneSwitcherUT.mValidationCallback.onNetworkAvailable(null, 1); 1485 processAllMessages(); 1486 clearInvocations(mSetOpptDataCallback1); 1487 clearInvocations(mSetOpptDataCallback2); 1488 clearInvocations(mCellularNetworkValidator); 1489 // Back to back call, call 1 to switch to subId 2, call 2 to switch back. 1490 mPhoneSwitcherUT.trySetOpportunisticDataSubscription(2, true, mSetOpptDataCallback1); 1491 processAllMessages(); 1492 verify(mCellularNetworkValidator).validate(eq(2), anyLong(), eq(false), 1493 eq(mPhoneSwitcherUT.mValidationCallback)); 1494 doReturn(true).when(mCellularNetworkValidator).isValidating(); 1495 mPhoneSwitcherUT.trySetOpportunisticDataSubscription( 1496 SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, true, mSetOpptDataCallback2); 1497 processAllMessages(); 1498 // Call 1 should be cancelled and failed. Call 2 return success immediately as there's no 1499 // change. 1500 verify(mSetOpptDataCallback1).onComplete(SET_OPPORTUNISTIC_SUB_VALIDATION_FAILED); 1501 verify(mSetOpptDataCallback2).onComplete(SET_OPPORTUNISTIC_SUB_SUCCESS); 1502 } 1503 1504 @Test testSetPreferredDataCallback_voiceCall()1505 public void testSetPreferredDataCallback_voiceCall() throws Exception { 1506 doReturn(true).when(mMockRadioConfig).isSetPreferredDataCommandSupported(); 1507 initialize(); 1508 setAllPhonesInactive(); 1509 1510 // Phone 0 has sub 1, phone 1 has sub 2. 1511 // Sub 1 is default data sub. 1512 // Both are active subscriptions are active sub, as they are in both active slots. 1513 setSlotIndexToSubId(0, 1); 1514 setSlotIndexToSubId(1, 2); 1515 setDefaultDataSubId(1); 1516 assertEquals(1, mPhoneSwitcherUT.getActiveDataSubId()); 1517 1518 doReturn(new SubscriptionInfoInternal.Builder(mSubscriptionManagerService 1519 .getSubscriptionInfoInternal(2)).setOpportunistic(1).build()) 1520 .when(mSubscriptionManagerService).getSubscriptionInfoInternal(2); 1521 1522 // First temporarily switched to the opportunistic sub 2 1523 mPhoneSwitcherUT.trySetOpportunisticDataSubscription(2, false, mSetOpptDataCallback1); 1524 processAllMessages(); 1525 mPhoneSwitcherUT.mValidationCallback.onNetworkAvailable(null, 2); 1526 processAllMessages(); 1527 verify(mSetOpptDataCallback1).onComplete(SET_OPPORTUNISTIC_SUB_SUCCESS); 1528 1529 // Voice call led back to default sub 1 1530 doReturn(mImsPhone).when(mPhone).getImsPhone(); 1531 doReturn(true).when(mPhone).isUserDataEnabled(); 1532 doReturn(true).when(mDataSettingsManager).isDataEnabled(); 1533 mockImsRegTech(0, REGISTRATION_TECH_LTE); 1534 notifyPhoneAsInCall(mPhone); 1535 1536 assertEquals(1, mPhoneSwitcherUT.getActiveDataSubId()); 1537 assertEquals(2, mPhoneSwitcherUT.getAutoSelectedDataSubId()); 1538 1539 // CBRS set preferred data back to default during the phone call 1540 clearInvocations(mSetOpptDataCallback1); 1541 mPhoneSwitcherUT.trySetOpportunisticDataSubscription(SubscriptionManager 1542 .DEFAULT_SUBSCRIPTION_ID, false, mSetOpptDataCallback1); 1543 processAllMessages(); 1544 1545 verify(mSetOpptDataCallback1).onComplete(SET_OPPORTUNISTIC_SUB_SUCCESS); 1546 assertEquals(1, mPhoneSwitcherUT.getActiveDataSubId()); 1547 assertEquals(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, 1548 mPhoneSwitcherUT.getAutoSelectedDataSubId()); 1549 } 1550 1551 @Test testMultiSimConfigChange()1552 public void testMultiSimConfigChange() throws Exception { 1553 doReturn(true).when(mMockRadioConfig).isSetPreferredDataCommandSupported(); 1554 mActiveModemCount = 1; 1555 initialize(); 1556 sendPreferredDataSuccessResult(0); 1557 1558 // Phone 0 has sub 1, phone 1 has sub 2. 1559 // Sub 1 is default data sub. 1560 // Both are active subscriptions are active sub, as they are in both active slots. 1561 setSlotIndexToSubId(0, 1); 1562 setDefaultDataSubId(1); 1563 1564 setNumPhones(2, 2); 1565 AsyncResult result = new AsyncResult(null, 2, null); 1566 Message.obtain(mPhoneSwitcherUT, EVENT_MULTI_SIM_CONFIG_CHANGED, result).sendToTarget(); 1567 processAllMessages(); 1568 1569 verify(mPhone2).registerForEmergencyCallToggle(any(), anyInt(), any()); 1570 verify(mPhone2).registerForPreciseCallStateChanged(any(), anyInt(), any()); 1571 1572 clearInvocations(mMockRadioConfig); 1573 setSlotIndexToSubId(1, 2); 1574 setDefaultDataSubId(2); 1575 verify(mMockRadioConfig).setPreferredDataModem(eq(1), any()); 1576 } 1577 1578 @Test testValidationOffSwitch_shouldSwitchOnNetworkAvailable()1579 public void testValidationOffSwitch_shouldSwitchOnNetworkAvailable() throws Exception { 1580 doReturn(true).when(mMockRadioConfig).isSetPreferredDataCommandSupported(); 1581 initialize(); 1582 // Phone 0 has sub 1, phone 1 has sub 2. 1583 // Sub 1 is default data sub. 1584 // Both are active subscriptions are active sub, as they are in both active slots. 1585 setSlotIndexToSubId(0, 1); 1586 setSlotIndexToSubId(1, 2); 1587 setDefaultDataSubId(1); 1588 NetworkRequest internetRequest = addInternetNetworkRequest(null, 50); 1589 assertTrue(mPhoneSwitcherUT.shouldApplyNetworkRequest( 1590 new TelephonyNetworkRequest(internetRequest, mPhone, mFeatureFlags), 0)); 1591 assertFalse(mPhoneSwitcherUT.shouldApplyNetworkRequest( 1592 new TelephonyNetworkRequest(internetRequest, mPhone, mFeatureFlags), 1)); 1593 clearInvocations(mMockRadioConfig); 1594 setAllPhonesInactive(); 1595 // Initialization done. 1596 1597 doReturn(new SubscriptionInfoInternal.Builder(mSubscriptionManagerService 1598 .getSubscriptionInfoInternal(2)).setOpportunistic(1).build()) 1599 .when(mSubscriptionManagerService).getSubscriptionInfoInternal(2); 1600 1601 mPhoneSwitcherUT.trySetOpportunisticDataSubscription(2, false, mSetOpptDataCallback1); 1602 processAllMessages(); 1603 verify(mCellularNetworkValidator).validate(eq(2), anyLong(), eq(false), 1604 eq(mPhoneSwitcherUT.mValidationCallback)); 1605 doReturn(true).when(mCellularNetworkValidator).isValidating(); 1606 1607 // Network available on different sub. Should do nothing. 1608 mPhoneSwitcherUT.mValidationCallback.onNetworkAvailable(null, 1); 1609 processAllMessages(); 1610 verify(mMockRadioConfig, never()).setPreferredDataModem(anyInt(), any()); 1611 1612 // Network available on corresponding sub. Should confirm switch. 1613 mPhoneSwitcherUT.mValidationCallback.onNetworkAvailable(null, 2); 1614 processAllMessages(); 1615 verify(mMockRadioConfig).setPreferredDataModem(eq(1), any()); 1616 } 1617 1618 @Test testValidationOffSwitch_shouldSwitchOnTimeOut()1619 public void testValidationOffSwitch_shouldSwitchOnTimeOut() throws Exception { 1620 doReturn(true).when(mMockRadioConfig).isSetPreferredDataCommandSupported(); 1621 initialize(); 1622 // Phone 0 has sub 1, phone 1 has sub 2. 1623 // Sub 1 is default data sub. 1624 // Both are active subscriptions are active sub, as they are in both active slots. 1625 setSlotIndexToSubId(0, 1); 1626 setSlotIndexToSubId(1, 2); 1627 setDefaultDataSubId(1); 1628 NetworkRequest internetRequest = addInternetNetworkRequest(null, 50); 1629 assertTrue(mPhoneSwitcherUT.shouldApplyNetworkRequest( 1630 new TelephonyNetworkRequest(internetRequest, mPhone, mFeatureFlags), 0)); 1631 assertFalse(mPhoneSwitcherUT.shouldApplyNetworkRequest( 1632 new TelephonyNetworkRequest(internetRequest, mPhone, mFeatureFlags), 1)); 1633 clearInvocations(mMockRadioConfig); 1634 setAllPhonesInactive(); 1635 // Initialization done. 1636 1637 doReturn(new SubscriptionInfoInternal.Builder(mSubscriptionManagerService 1638 .getSubscriptionInfoInternal(2)).setOpportunistic(1).build()) 1639 .when(mSubscriptionManagerService).getSubscriptionInfoInternal(2); 1640 1641 mPhoneSwitcherUT.trySetOpportunisticDataSubscription(2, false, mSetOpptDataCallback1); 1642 processAllMessages(); 1643 verify(mCellularNetworkValidator).validate(eq(2), anyLong(), eq(false), 1644 eq(mPhoneSwitcherUT.mValidationCallback)); 1645 doReturn(true).when(mCellularNetworkValidator).isValidating(); 1646 1647 // Validation failed on different sub. Should do nothing. 1648 mPhoneSwitcherUT.mValidationCallback.onValidationDone(false, 1); 1649 processAllMessages(); 1650 verify(mMockRadioConfig, never()).setPreferredDataModem(anyInt(), any()); 1651 1652 // Network available on corresponding sub. Should confirm switch. 1653 mPhoneSwitcherUT.mValidationCallback.onValidationDone(false, 2); 1654 processAllMessages(); 1655 verify(mMockRadioConfig).setPreferredDataModem(eq(1), any()); 1656 } 1657 1658 @Test testRetry_DDS_switch_Failure()1659 public void testRetry_DDS_switch_Failure() throws Exception { 1660 doReturn(true).when(mMockRadioConfig).isSetPreferredDataCommandSupported(); 1661 mActiveModemCount = 2; 1662 initialize(); 1663 setSlotIndexToSubId(0, 1); 1664 setDefaultDataSubId(1); 1665 1666 clearInvocations(mMockRadioConfig); 1667 // for exceptions OP_NOT_ALLOWED_DURING_VOICE_CALL and INVALID_SIM_STATE, 1668 // modem retry not invoked. 1669 AsyncResult res1 = new AsyncResult(0, null, 1670 new CommandException(CommandException.Error.INVALID_SIM_STATE)); 1671 Message.obtain(mPhoneSwitcherUT, EVENT_MODEM_COMMAND_DONE, res1).sendToTarget(); 1672 processAllMessages(); 1673 moveTimeForward(5000); 1674 processAllMessages(); 1675 verify(mMockRadioConfig, times(0)).setPreferredDataModem(eq(0), any()); 1676 1677 AsyncResult res2 = new AsyncResult(0, null, 1678 new CommandException(CommandException.Error.NETWORK_NOT_READY)); 1679 Message.obtain(mPhoneSwitcherUT, EVENT_MODEM_COMMAND_DONE, res2).sendToTarget(); 1680 processAllMessages(); 1681 moveTimeForward(5000); 1682 processAllMessages(); 1683 1684 verify(mMockRadioConfig, times(1)).setPreferredDataModem(eq(0), any()); 1685 1686 clearInvocations(mMockRadioConfig); 1687 doReturn(mSubscriptionInfo).when(mSubscriptionManagerService) 1688 .getActiveSubscriptionInfoForSimSlotIndex(eq(0), any(), any()); 1689 doReturn(true).when(mSubscriptionInfo).areUiccApplicationsEnabled(); 1690 doReturn(mIccCard).when(mPhone).getIccCard(); 1691 doReturn(true).when(mIccCard).isEmptyProfile(); 1692 final Intent intent1 = new Intent(ACTION_SIM_APPLICATION_STATE_CHANGED); 1693 intent1.putExtra(EXTRA_SIM_STATE, SIM_STATE_LOADED); 1694 intent1.putExtra(SubscriptionManager.EXTRA_SLOT_INDEX, 0); 1695 mContext.sendBroadcast(intent1); 1696 processAllMessages(); 1697 1698 verify(mMockRadioConfig, times(0)).setPreferredDataModem(eq(0), any()); 1699 1700 doReturn(false).when(mIccCard).isEmptyProfile(); 1701 final Intent intent2 = new Intent(ACTION_SIM_APPLICATION_STATE_CHANGED); 1702 intent2.putExtra(EXTRA_SIM_STATE, SIM_STATE_LOADED); 1703 intent2.putExtra(SubscriptionManager.EXTRA_SLOT_INDEX, 0); 1704 mContext.sendBroadcast(intent2); 1705 processAllMessages(); 1706 1707 verify(mMockRadioConfig, times(1)).setPreferredDataModem(eq(0), any()); 1708 } 1709 1710 @Test testScheduledRetryWhileMultiSimConfigChange()1711 public void testScheduledRetryWhileMultiSimConfigChange() throws Exception { 1712 doReturn(true).when(mMockRadioConfig).isSetPreferredDataCommandSupported(); 1713 initialize(); 1714 1715 // Phone 0 has sub 1, phone 1 has sub 2. 1716 // Sub 1 is default data sub. 1717 setSlotIndexToSubId(0, 1); 1718 setSlotIndexToSubId(1, 2); 1719 1720 // for EVENT_MODEM_COMMAND_RETRY 1721 AsyncResult res = new AsyncResult( 1722 1, null, new CommandException(CommandException.Error.GENERIC_FAILURE)); 1723 Message.obtain(mPhoneSwitcherUT, EVENT_MODEM_COMMAND_DONE, res).sendToTarget(); 1724 processAllMessages(); 1725 1726 // reduce count of phone 1727 setNumPhones(1, 1); 1728 AsyncResult result = new AsyncResult(null, 1, null); 1729 Message.obtain(mPhoneSwitcherUT, EVENT_MULTI_SIM_CONFIG_CHANGED, result).sendToTarget(); 1730 processAllMessages(); 1731 1732 // fire retries 1733 moveTimeForward(5000); 1734 processAllMessages(); 1735 1736 verify(mCommandsInterface0, never()).setDataAllowed(anyBoolean(), any()); 1737 verify(mCommandsInterface1, never()).setDataAllowed(anyBoolean(), any()); 1738 } 1739 1740 @Test testRegisterForImsRegistrationCallback()1741 public void testRegisterForImsRegistrationCallback() throws Exception { 1742 initialize(); 1743 setAllPhonesInactive(); 1744 1745 // Phone 0 has sub 1, phone 1 has sub 2. 1746 // Sub 1 is default data sub. 1747 // Both are active subscriptions are active sub, as they are in both active slots. 1748 setSlotIndexToSubId(0, 1); 1749 setSlotIndexToSubId(1, 2); 1750 setDefaultDataSubId(1); 1751 processAllMessages(); 1752 1753 // Phone 0 should be the default data phoneId. 1754 assertEquals(0, mPhoneSwitcherUT.getPreferredDataPhoneId()); 1755 1756 doReturn(true).when(mPhone).isUserDataEnabled(); 1757 mockImsRegTech(0, REGISTRATION_TECH_LTE); 1758 mockImsRegisterCallback(0); 1759 mockImsRegisterCallback(1); 1760 1761 notifyImsRegistrationTechChange(mPhone); 1762 1763 // Verify that the callback is re-registered when the IMS registration callback is called. 1764 verify(mMockImsRegisterCallback, times(2)).setCallback(any(), anyInt(), any(), any()); 1765 } 1766 1767 @Test testReceivingImsRegistrationTech()1768 public void testReceivingImsRegistrationTech() throws Exception { 1769 doReturn(true).when(mFeatureFlags).changeMethodOfObtainingImsRegistrationRadioTech(); 1770 1771 // Set up input and output for testing 1772 ImsPhone testImsPhone = mock(ImsPhone.class); 1773 doReturn(testImsPhone).when(mPhone).getImsPhone(); 1774 doReturn(testImsPhone).when(mPhone2).getImsPhone(); 1775 ImsPhoneCall testImsPhoneCall = mock(ImsPhoneCall.class); 1776 doReturn(Call.State.IDLE).when(testImsPhoneCall).getState(); 1777 doReturn(true).when(testImsPhoneCall).isIdle(); 1778 doReturn(testImsPhoneCall).when(testImsPhone).getForegroundCall(); 1779 doReturn(testImsPhoneCall).when(testImsPhone).getBackgroundCall(); 1780 doReturn(testImsPhoneCall).when(testImsPhone).getRingingCall(); 1781 1782 doNothing().when(testImsPhone).registerForImsRegistrationChanges(any(), anyInt(), any()); 1783 1784 initialize(); 1785 setAllPhonesInactive(); 1786 1787 // Phone 0 has sub 1, phone 1 has sub 2. 1788 // Sub 1 is default data sub. 1789 // Both are active subscriptions are active sub, as they are in both active slots. 1790 setSlotIndexToSubId(0, 1); 1791 setSlotIndexToSubId(1, 2); 1792 setDefaultDataSubId(1); 1793 processAllMessages(); 1794 1795 // Phone 0 should be the default data phoneId. 1796 assertEquals(0, mPhoneSwitcherUT.getPreferredDataPhoneId()); 1797 1798 doReturn(true).when(mPhone).isUserDataEnabled(); 1799 mockImsRegTech(0, REGISTRATION_TECH_NONE); 1800 mockImsRegisterCallback(0); 1801 mockImsRegisterCallback(1); 1802 1803 AsyncResult ar = new AsyncResult(null, new ImsPhone.ImsRegistrationRadioTechInfo( 1804 0, REGISTRATION_TECH_LTE, REGISTRATION_STATE_REGISTERED), null); 1805 notifyImsRegistrationTechChangeWithAsyncResult(ar); 1806 1807 // Verify cached IMS registration tech is LTE 1808 assertTrue(REGISTRATION_TECH_LTE == mPhoneSwitcherUT.mImsRegistrationRadioTechMap.get(0)); 1809 1810 ar = new AsyncResult(null, new ImsPhone.ImsRegistrationRadioTechInfo( 1811 0, REGISTRATION_TECH_IWLAN, REGISTRATION_STATE_REGISTERED), null); 1812 notifyImsRegistrationTechChangeWithAsyncResult(ar); 1813 1814 // Verify cached IMS registration tech is WiFi 1815 assertTrue(REGISTRATION_TECH_IWLAN 1816 == mPhoneSwitcherUT.mImsRegistrationRadioTechMap.get(0)); 1817 1818 ar = new AsyncResult(null, new ImsPhone.ImsRegistrationRadioTechInfo( 1819 0, REGISTRATION_TECH_NONE, REGISTRATION_STATE_NOT_REGISTERED), null); 1820 notifyImsRegistrationTechChangeWithAsyncResult(ar); 1821 1822 // Verify cached IMS registration tech is NONE 1823 assertTrue(REGISTRATION_TECH_NONE == mPhoneSwitcherUT.mImsRegistrationRadioTechMap.get(0)); 1824 1825 // Verify there is no crash 1826 notifyImsRegistrationTechChangeWithAsyncResult(null); 1827 1828 // Verify that the callback is not re-registered 1829 // when the IMS registration callback is called. 1830 verify(mMockImsRegisterCallback, never()).setCallback(any(), anyInt(), any(), any()); 1831 } 1832 1833 /* Private utility methods start here */ 1834 prepareIdealAutoSwitchCondition()1835 private void prepareIdealAutoSwitchCondition() { 1836 // 1. service state changes 1837 serviceStateChanged(1, NetworkRegistrationInfo.REGISTRATION_STATE_HOME); 1838 serviceStateChanged(0, NetworkRegistrationInfo 1839 .REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING); 1840 1841 // 2.1 User data enabled on primary SIM 1842 doReturn(true).when(mPhone).isUserDataEnabled(); 1843 1844 // 2.2 Auto switch feature is enabled 1845 doReturn(true).when(mPhone2).isDataAllowed(); 1846 doReturn(true).when(mDataSettingsManager2).isDataEnabled(); 1847 1848 mPhoneSwitcherUT.sendEmptyMessage(EVENT_EVALUATE_AUTO_SWITCH); 1849 } 1850 serviceStateChanged(int phoneId, @NetworkRegistrationInfo.RegistrationState int dataRegState)1851 private void serviceStateChanged(int phoneId, 1852 @NetworkRegistrationInfo.RegistrationState int dataRegState) { 1853 1854 ServiceState ss = new ServiceState(); 1855 1856 ss.addNetworkRegistrationInfo(new NetworkRegistrationInfo.Builder() 1857 .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN) 1858 .setRegistrationState(dataRegState) 1859 .setDomain(NetworkRegistrationInfo.DOMAIN_PS) 1860 .build()); 1861 1862 ss.setDataRoamingFromRegistration(dataRegState 1863 == NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING); 1864 1865 doReturn(ss).when(mPhones[phoneId]).getServiceState(); 1866 1867 Message msg = mPhoneSwitcherUT.obtainMessage(EVENT_SERVICE_STATE_CHANGED); 1868 msg.obj = new AsyncResult(phoneId, null, null); 1869 mPhoneSwitcherUT.sendMessage(msg); 1870 } 1871 setAllPhonesInactive()1872 private void setAllPhonesInactive() { 1873 doReturn(mInactiveCall).when(mPhone).getForegroundCall(); 1874 doReturn(mInactiveCall).when(mPhone).getBackgroundCall(); 1875 doReturn(mInactiveCall).when(mPhone).getRingingCall(); 1876 doReturn(mInactiveCall).when(mPhone2).getForegroundCall(); 1877 doReturn(mInactiveCall).when(mPhone2).getBackgroundCall(); 1878 doReturn(mInactiveCall).when(mPhone2).getRingingCall(); 1879 doReturn(mInactiveCall).when(mImsPhone).getForegroundCall(); 1880 doReturn(mInactiveCall).when(mImsPhone).getBackgroundCall(); 1881 doReturn(mInactiveCall).when(mImsPhone).getRingingCall(); 1882 } 1883 notifyPhoneAsInCall(Phone phone)1884 private void notifyPhoneAsInCall(Phone phone) { 1885 doReturn(mActiveCall).when(phone).getForegroundCall(); 1886 mPhoneSwitcherUT.sendEmptyMessage(EVENT_PRECISE_CALL_STATE_CHANGED); 1887 processAllMessages(); 1888 } 1889 notifyPhoneAsInDial(Phone phone)1890 private void notifyPhoneAsInDial(Phone phone) { 1891 doReturn(mDialCall).when(phone).getForegroundCall(); 1892 mPhoneSwitcherUT.sendEmptyMessage(EVENT_PRECISE_CALL_STATE_CHANGED); 1893 processAllMessages(); 1894 } 1895 notifyPhoneAsAlerting(Phone phone)1896 private void notifyPhoneAsAlerting(Phone phone) { 1897 doReturn(mAlertingCall).when(phone).getForegroundCall(); 1898 mPhoneSwitcherUT.sendEmptyMessage(EVENT_PRECISE_CALL_STATE_CHANGED); 1899 processAllMessages(); 1900 } 1901 notifyPhoneAsInIncomingCall(Phone phone)1902 private void notifyPhoneAsInIncomingCall(Phone phone) { 1903 doReturn(mIncomingCall).when(phone).getForegroundCall(); 1904 mPhoneSwitcherUT.sendEmptyMessage(EVENT_PRECISE_CALL_STATE_CHANGED); 1905 processAllMessages(); 1906 } 1907 notifyPhoneAsInHoldingCall(Phone phone)1908 private void notifyPhoneAsInHoldingCall(Phone phone) { 1909 doReturn(mHoldingCall).when(phone).getBackgroundCall(); 1910 mPhoneSwitcherUT.sendEmptyMessage(EVENT_PRECISE_CALL_STATE_CHANGED); 1911 processAllMessages(); 1912 } 1913 notifyPhoneAsInactive(Phone phone)1914 private void notifyPhoneAsInactive(Phone phone) { 1915 doReturn(mInactiveCall).when(phone).getForegroundCall(); 1916 mPhoneSwitcherUT.sendEmptyMessage(EVENT_PRECISE_CALL_STATE_CHANGED); 1917 processAllMessages(); 1918 } 1919 notifyDataEnabled(boolean dataEnabled)1920 private void notifyDataEnabled(boolean dataEnabled) { 1921 doReturn(true).when(mPhone).isUserDataEnabled(); 1922 doReturn(dataEnabled).when(mDataSettingsManager).isDataEnabled(); 1923 doReturn(dataEnabled).when(mDataSettingsManager2).isDataEnabled(); 1924 mDataSettingsManagerCallbacks.get(0).onDataEnabledChanged(dataEnabled, 123 , ""); 1925 if (mDataSettingsManagerCallbacks.size() > 1) { 1926 mDataSettingsManagerCallbacks.get(1).onDataEnabledChanged(dataEnabled, 123, ""); 1927 } 1928 processAllMessages(); 1929 } 1930 notifyImsRegistrationTechChange(Phone phone)1931 private void notifyImsRegistrationTechChange(Phone phone) { 1932 mPhoneSwitcherUT.sendEmptyMessage(EVENT_IMS_RADIO_TECH_CHANGED); 1933 processAllMessages(); 1934 } 1935 notifyImsRegistrationTechChangeWithAsyncResult(AsyncResult ar)1936 private void notifyImsRegistrationTechChangeWithAsyncResult(AsyncResult ar) { 1937 mPhoneSwitcherUT.sendMessage( 1938 mPhoneSwitcherUT.obtainMessage(EVENT_IMS_RADIO_TECH_CHANGED, ar)); 1939 processAllMessages(); 1940 } 1941 getEcbmRegistration(Phone phone)1942 private Message getEcbmRegistration(Phone phone) { 1943 ArgumentCaptor<Handler> handlerCaptor = ArgumentCaptor.forClass(Handler.class); 1944 ArgumentCaptor<Integer> intCaptor = ArgumentCaptor.forClass(Integer.class); 1945 1946 verify(phone).registerForEmergencyCallToggle(handlerCaptor.capture(), intCaptor.capture(), 1947 any()); 1948 assertNotNull(handlerCaptor.getValue()); 1949 assertNotNull(intCaptor.getValue()); 1950 Message message = Message.obtain(handlerCaptor.getValue(), intCaptor.getValue()); 1951 return message; 1952 } 1953 notifyEcbmStart(Phone phone, Message ecmMessage)1954 private void notifyEcbmStart(Phone phone, Message ecmMessage) { 1955 doReturn(mInactiveCall).when(phone).getForegroundCall(); 1956 doReturn(true).when(phone).isInEcm(); 1957 ecmMessage.sendToTarget(); 1958 processAllMessages(); 1959 } 1960 notifyEcbmEnd(Phone phone, Message ecmMessage)1961 private void notifyEcbmEnd(Phone phone, Message ecmMessage) { 1962 doReturn(false).when(phone).isInEcm(); 1963 ecmMessage.sendToTarget(); 1964 processAllMessages(); 1965 } 1966 sendPreferredDataSuccessResult(int phoneId)1967 private void sendPreferredDataSuccessResult(int phoneId) { 1968 // make sure the radio command is called and then send a success result 1969 processAllMessages(); 1970 ArgumentCaptor<Message> msgCaptor = ArgumentCaptor.forClass(Message.class); 1971 verify(mMockRadioConfig).setPreferredDataModem(eq(phoneId), msgCaptor.capture()); 1972 assertNotNull(msgCaptor.getValue()); 1973 // Send back successful result 1974 AsyncResult.forMessage(msgCaptor.getValue(), null, null); 1975 msgCaptor.getValue().sendToTarget(); 1976 processAllMessages(); 1977 } 1978 setMsimDefaultDataSubId(int defaultDataSub)1979 private void setMsimDefaultDataSubId(int defaultDataSub) throws Exception { 1980 for (int i = 0; i < mActiveModemCount; i++) { 1981 setSlotIndexToSubId(i, i + 1); 1982 } 1983 setDefaultDataSubId(defaultDataSub); 1984 NetworkRequest internetRequest = addInternetNetworkRequest(null, 50); 1985 for (int i = 0; i < mActiveModemCount; i++) { 1986 if (defaultDataSub == (i + 1)) { 1987 // sub id is always phoneId+1 for testing 1988 assertTrue(mPhoneSwitcherUT.shouldApplyNetworkRequest( 1989 new TelephonyNetworkRequest(internetRequest, mPhone, mFeatureFlags), i)); 1990 } else { 1991 assertFalse(mPhoneSwitcherUT.shouldApplyNetworkRequest( 1992 new TelephonyNetworkRequest(internetRequest, mPhone, mFeatureFlags), i)); 1993 } 1994 } 1995 } 1996 initialize()1997 private void initialize() throws Exception { 1998 setNumPhones(mActiveModemCount, mSupportedModemCount); 1999 2000 initializeSubControllerMock(); 2001 initializeCommandInterfacesMock(); 2002 initializeTelRegistryMock(); 2003 initializeConfigMock(); 2004 2005 mPhoneSwitcherUT = new PhoneSwitcher(mMaxDataAttachModemCount, mContext, Looper.myLooper(), 2006 mFeatureFlags); 2007 2008 Field field = PhoneSwitcher.class.getDeclaredField("mDataSettingsManagerCallbacks"); 2009 field.setAccessible(true); 2010 mDataSettingsManagerCallbacks = 2011 (Map<Integer, DataSettingsManager.DataSettingsManagerCallback>) 2012 field.get(mPhoneSwitcherUT); 2013 2014 field = PhoneSwitcher.class.getDeclaredField("mAutoDataSwitchCallback"); 2015 field.setAccessible(true); 2016 mAutoDataSwitchCallback = (AutoDataSwitchController.AutoDataSwitchControllerCallback) 2017 field.get(mPhoneSwitcherUT); 2018 2019 replaceInstance(PhoneSwitcher.class, "mAutoDataSwitchController", mPhoneSwitcherUT, 2020 mAutoDataSwitchController); 2021 processAllMessages(); 2022 2023 verify(mTelephonyRegistryManager).addOnSubscriptionsChangedListener(any(), any()); 2024 2025 ArgumentCaptor<SubscriptionManagerServiceCallback> callbackCaptor = 2026 ArgumentCaptor.forClass(SubscriptionManagerServiceCallback.class); 2027 verify(mSubscriptionManagerService).registerCallback(callbackCaptor.capture()); 2028 mSubscriptionManagerServiceCallback = callbackCaptor.getValue(); 2029 } 2030 2031 /** 2032 * Certain variables needs initialized depending on number of phones. 2033 */ setNumPhones(int activeModemCount, int supportedModemCount)2034 private void setNumPhones(int activeModemCount, int supportedModemCount) throws Exception { 2035 mDataAllowed = new boolean[supportedModemCount]; 2036 mSlotIndexToSubId = new int[supportedModemCount][]; 2037 doReturn(0).when(mPhone).getPhoneId(); 2038 doReturn(1).when(mPhone2).getPhoneId(); 2039 doReturn(true).when(mPhone2).isUserDataEnabled(); 2040 doReturn(mDataSettingsManager2).when(mPhone2).getDataSettingsManager(); 2041 doReturn(mSST2).when(mPhone2).getServiceStateTracker(); 2042 doReturn(mDisplayInfoController).when(mPhone2).getDisplayInfoController(); 2043 doReturn(mSignalStrengthController).when(mPhone2).getSignalStrengthController(); 2044 doReturn(mSignalStrength).when(mPhone2).getSignalStrength(); 2045 for (int i = 0; i < supportedModemCount; i++) { 2046 mSlotIndexToSubId[i] = new int[1]; 2047 mSlotIndexToSubId[i][0] = SubscriptionManager.INVALID_SUBSCRIPTION_ID; 2048 } 2049 2050 doReturn(activeModemCount).when(mTelephonyManager).getPhoneCount(); 2051 doReturn(activeModemCount).when(mTelephonyManager).getActiveModemCount(); 2052 doReturn(supportedModemCount).when(mTelephonyManager).getSupportedModemCount(); 2053 2054 if (activeModemCount == 1) { 2055 mPhones = new Phone[]{mPhone}; 2056 } else if (activeModemCount == 2) { 2057 mPhones = new Phone[]{mPhone, mPhone2}; 2058 } 2059 2060 replaceInstance(PhoneFactory.class, "sPhones", null, mPhones); 2061 for (Phone phone : mPhones) { 2062 ServiceState ss = new ServiceState(); 2063 2064 ss.addNetworkRegistrationInfo(new NetworkRegistrationInfo.Builder() 2065 .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN) 2066 .setRegistrationState( 2067 NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING) 2068 .setDomain(NetworkRegistrationInfo.DOMAIN_PS) 2069 .build()); 2070 doReturn(ss).when(phone).getServiceState(); 2071 } 2072 } 2073 initializeCommandInterfacesMock()2074 private void initializeCommandInterfacesMock() { 2075 // Tell PhoneSwitcher that radio is on. 2076 doAnswer(invocation -> { 2077 Handler handler = (Handler) invocation.getArguments()[0]; 2078 int message = (int) invocation.getArguments()[1]; 2079 Object obj = invocation.getArguments()[2]; 2080 handler.obtainMessage(message, obj).sendToTarget(); 2081 return null; 2082 }).when(mCommandsInterface0).registerForAvailable(any(), anyInt(), any()); 2083 2084 // Store values of dataAllowed in mDataAllowed[] for easier checking. 2085 doAnswer(invocation -> { 2086 mDataAllowed[0] = (boolean) invocation.getArguments()[0]; 2087 return null; 2088 }).when(mCommandsInterface0).setDataAllowed(anyBoolean(), any()); 2089 2090 if (mSupportedModemCount > 1) { 2091 doAnswer(invocation -> { 2092 mDataAllowed[1] = (boolean) invocation.getArguments()[0]; 2093 return null; 2094 }).when(mCommandsInterface1).setDataAllowed(anyBoolean(), any()); 2095 } 2096 } 2097 2098 /** 2099 * Store subChangedListener of PhoneSwitcher so that testing can notify 2100 * PhoneSwitcher of sub change. 2101 */ initializeTelRegistryMock()2102 private void initializeTelRegistryMock() throws Exception { 2103 doAnswer(invocation -> { 2104 SubscriptionManager.OnSubscriptionsChangedListener subChangedListener = 2105 (SubscriptionManager.OnSubscriptionsChangedListener) invocation.getArguments()[0]; 2106 mSubChangedListener = subChangedListener; 2107 mSubChangedListener.onSubscriptionsChanged(); 2108 return null; 2109 }).when(mTelephonyRegistryManager).addOnSubscriptionsChangedListener(any(), any()); 2110 } 2111 2112 /** 2113 * Capture mNetworkProviderMessenger so that testing can request or release 2114 * network requests on PhoneSwitcher. 2115 */ initializeSubControllerMock()2116 private void initializeSubControllerMock() throws Exception { 2117 doReturn(mDefaultDataSub).when(mSubscriptionManagerService).getDefaultDataSubId(); 2118 doReturn(mDefaultDataSub).when(mMockedIsub).getDefaultDataSubId(); 2119 doReturn(0).when(mSubscriptionManagerService).getPhoneId(1); 2120 doReturn(0).when(mMockedIsub).getPhoneId(1); 2121 doReturn(1).when(mSubscriptionManagerService).getPhoneId(2); 2122 doReturn(1).when(mMockedIsub).getPhoneId(2); 2123 2124 doAnswer(invocation -> { 2125 int phoneId = (int) invocation.getArguments()[0]; 2126 if (phoneId == SubscriptionManager.INVALID_PHONE_INDEX) { 2127 return SubscriptionManager.INVALID_SUBSCRIPTION_ID; 2128 } else if (phoneId == SubscriptionManager.DEFAULT_PHONE_INDEX) { 2129 return mSlotIndexToSubId[0][0]; 2130 } else { 2131 return mSlotIndexToSubId[phoneId][0]; 2132 } 2133 }).when(mMockedIsub).getSubId(anyInt()); 2134 2135 doAnswer(invocation -> { 2136 int phoneId = (int) invocation.getArguments()[0]; 2137 if (phoneId == SubscriptionManager.INVALID_PHONE_INDEX) { 2138 return SubscriptionManager.INVALID_SUBSCRIPTION_ID; 2139 } else if (phoneId == SubscriptionManager.DEFAULT_PHONE_INDEX) { 2140 return mSlotIndexToSubId[0][0]; 2141 } else { 2142 return mSlotIndexToSubId[phoneId][0]; 2143 } 2144 }).when(mSubscriptionManagerService).getSubId(anyInt()); 2145 2146 doAnswer(invocation -> { 2147 int subId = (int) invocation.getArguments()[0]; 2148 2149 if (!SubscriptionManager.isUsableSubIdValue(subId)) return null; 2150 2151 int slotIndex = -1; 2152 for (int i = 0; i < mSlotIndexToSubId.length; i++) { 2153 if (mSlotIndexToSubId[i][0] == subId) slotIndex = i; 2154 } 2155 return new SubscriptionInfoInternal.Builder() 2156 .setSimSlotIndex(slotIndex).setId(subId).build(); 2157 }).when(mSubscriptionManagerService).getSubscriptionInfoInternal(anyInt()); 2158 2159 doReturn(new int[mSlotIndexToSubId.length]).when(mSubscriptionManagerService) 2160 .getActiveSubIdList(true); 2161 } 2162 initializeConfigMock()2163 private void initializeConfigMock() { 2164 doReturn(mDataNetworkController).when(mPhone).getDataNetworkController(); 2165 doReturn(mDataConfigManager).when(mDataNetworkController).getDataConfigManager(); 2166 doReturn(1000L).when(mDataConfigManager) 2167 .getAutoDataSwitchAvailabilityStabilityTimeThreshold(); 2168 doReturn(7).when(mDataConfigManager).getAutoDataSwitchValidationMaxRetry(); 2169 doReturn(true).when(mDataConfigManager).isPingTestBeforeAutoDataSwitchRequired(); 2170 } 2171 setDefaultDataSubId(int defaultDataSub)2172 private void setDefaultDataSubId(int defaultDataSub) { 2173 mDefaultDataSub = defaultDataSub; 2174 doReturn(mDefaultDataSub).when(mSubscriptionManagerService).getDefaultDataSubId(); 2175 for (Phone phone : mPhones) { 2176 doAnswer(invocation -> phone.getSubId() == mDefaultDataSub) 2177 .when(phone).isUserDataEnabled(); 2178 } 2179 mSubscriptionManagerServiceCallback.onDefaultDataSubscriptionChanged(defaultDataSub); 2180 processAllMessages(); 2181 } 2182 setSlotIndexToSubId(int slotId, int subId)2183 private void setSlotIndexToSubId(int slotId, int subId) { 2184 mSlotIndexToSubId[slotId][0] = subId; 2185 Phone phone = slotId == 0 ? mPhone : mPhone2; 2186 doReturn(subId).when(phone).getSubId(); 2187 } 2188 2189 /** 2190 * Create an internet PDN network request and send it to PhoneSwitcher. 2191 */ addInternetNetworkRequest(Integer subId, int score)2192 private NetworkRequest addInternetNetworkRequest(Integer subId, int score) throws Exception { 2193 return addInternetNetworkRequest(subId, score, false); 2194 } 2195 addInternetNetworkRequest(Integer subId, int score, boolean restricted)2196 private NetworkRequest addInternetNetworkRequest(Integer subId, int score, boolean restricted) 2197 throws Exception { 2198 NetworkCapabilities netCap = (new NetworkCapabilities()) 2199 .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) 2200 .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR); 2201 if (restricted) { 2202 netCap.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED); 2203 } 2204 2205 if (subId != null) { 2206 netCap.setNetworkSpecifier(new TelephonyNetworkSpecifier.Builder() 2207 .setSubscriptionId(subId).build()); 2208 } 2209 NetworkRequest networkRequest = new NetworkRequest(netCap, ConnectivityManager.TYPE_NONE, 2210 0, NetworkRequest.Type.REQUEST); 2211 2212 mPhoneSwitcherUT.onRequestNetwork(networkRequest); 2213 return networkRequest; 2214 } 2215 2216 /** 2217 * Create a mms PDN network request and send it to PhoneSwitcher. 2218 */ addMmsNetworkRequest(Integer subId)2219 private NetworkRequest addMmsNetworkRequest(Integer subId) throws Exception { 2220 NetworkCapabilities netCap = (new NetworkCapabilities()) 2221 .addCapability(NetworkCapabilities.NET_CAPABILITY_MMS) 2222 .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED) 2223 .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR); 2224 if (subId != null) { 2225 netCap.setNetworkSpecifier(new TelephonyNetworkSpecifier.Builder() 2226 .setSubscriptionId(subId).build()); 2227 } 2228 NetworkRequest networkRequest = new NetworkRequest(netCap, ConnectivityManager.TYPE_NONE, 2229 1, NetworkRequest.Type.REQUEST); 2230 mPhoneSwitcherUT.onRequestNetwork(networkRequest); 2231 return networkRequest; 2232 } 2233 2234 /** 2235 * Tell PhoneSwitcher to release a network request. 2236 */ releaseNetworkRequest(NetworkRequest networkRequest)2237 private void releaseNetworkRequest(NetworkRequest networkRequest) throws Exception { 2238 mPhoneSwitcherUT.onReleaseNetwork(networkRequest); 2239 } 2240 } 2241