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; 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.stub.ImsRegistrationImplBase.REGISTRATION_TECH_CROSS_SIM; 27 import static android.telephony.ims.stub.ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN; 28 import static android.telephony.ims.stub.ImsRegistrationImplBase.REGISTRATION_TECH_LTE; 29 30 import static com.android.internal.telephony.PhoneSwitcher.ECBM_DEFAULT_DATA_SWITCH_BASE_TIME_MS; 31 import static com.android.internal.telephony.PhoneSwitcher.EVENT_DATA_ENABLED_CHANGED; 32 import static com.android.internal.telephony.PhoneSwitcher.EVENT_IMS_RADIO_TECH_CHANGED; 33 import static com.android.internal.telephony.PhoneSwitcher.EVENT_MULTI_SIM_CONFIG_CHANGED; 34 import static com.android.internal.telephony.PhoneSwitcher.EVENT_PRECISE_CALL_STATE_CHANGED; 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.Matchers.eq; 45 import static org.mockito.Mockito.clearInvocations; 46 import static org.mockito.Mockito.doAnswer; 47 import static org.mockito.Mockito.doReturn; 48 import static org.mockito.Mockito.never; 49 import static org.mockito.Mockito.times; 50 import static org.mockito.Mockito.verify; 51 52 import android.content.Context; 53 import android.content.Intent; 54 import android.net.ConnectivityManager; 55 import android.net.NetworkCapabilities; 56 import android.net.NetworkProvider; 57 import android.net.NetworkRequest; 58 import android.net.TelephonyNetworkSpecifier; 59 import android.os.AsyncResult; 60 import android.os.Handler; 61 import android.os.Looper; 62 import android.os.Message; 63 import android.os.Messenger; 64 import android.telephony.PhoneCapability; 65 import android.telephony.SubscriptionInfo; 66 import android.telephony.SubscriptionManager; 67 import android.telephony.data.ApnSetting; 68 import android.test.suitebuilder.annotation.SmallTest; 69 import android.testing.AndroidTestingRunner; 70 import android.testing.TestableLooper; 71 72 import com.android.internal.telephony.dataconnection.DataEnabledSettings; 73 74 import org.junit.After; 75 import org.junit.Before; 76 import org.junit.Test; 77 import org.junit.runner.RunWith; 78 import org.mockito.ArgumentCaptor; 79 import org.mockito.Mock; 80 81 import java.util.concurrent.CompletableFuture; 82 import java.util.concurrent.LinkedBlockingQueue; 83 84 @RunWith(AndroidTestingRunner.class) 85 @TestableLooper.RunWithLooper 86 public class PhoneSwitcherTest extends TelephonyTest { 87 private static final int ACTIVE_PHONE_SWITCH = 1; 88 private static final int EVENT_RADIO_ON = 108; 89 private static final int EVENT_MODEM_COMMAND_DONE = 112; 90 91 @Mock 92 private CommandsInterface mCommandsInterface0; 93 @Mock 94 private CommandsInterface mCommandsInterface1; 95 @Mock 96 private Phone mPhone2; // mPhone as phone 1 is already defined in TelephonyTest. 97 @Mock 98 private Phone mImsPhone; 99 @Mock 100 private DataEnabledSettings mDataEnabledSettings2; 101 @Mock 102 private Handler mActivePhoneSwitchHandler; 103 @Mock 104 private GsmCdmaCall mActiveCall; 105 @Mock 106 private GsmCdmaCall mHoldingCall; 107 @Mock 108 private GsmCdmaCall mInactiveCall; 109 @Mock 110 private ISetOpportunisticDataCallback mSetOpptDataCallback1; 111 @Mock 112 private ISetOpportunisticDataCallback mSetOpptDataCallback2; 113 @Mock 114 CompletableFuture<Boolean> mFuturePhone; 115 @Mock 116 PhoneSwitcher.ImsRegTechProvider mMockImsRegTechProvider; 117 @Mock 118 private SubscriptionInfo mSubscriptionInfo; 119 120 private PhoneSwitcher mPhoneSwitcher; 121 private SubscriptionManager.OnSubscriptionsChangedListener mSubChangedListener; 122 private ConnectivityManager mConnectivityManager; 123 // The messenger of PhoneSwitcher used to receive network requests. 124 private Messenger mNetworkProviderMessenger = null; 125 private int mDefaultDataSub = SubscriptionManager.INVALID_SUBSCRIPTION_ID; 126 private int[][] mSlotIndexToSubId; 127 private boolean[] mDataAllowed; 128 private int mActiveModemCount = 2; 129 private int mSupportedModemCount = 2; 130 private int mMaxDataAttachModemCount = 1; 131 132 @Before setUp()133 public void setUp() throws Exception { 134 super.setUp(getClass().getSimpleName()); 135 136 PhoneCapability phoneCapability = new PhoneCapability(1, 1, null, false, new int[0]); 137 doReturn(phoneCapability).when(mPhoneConfigurationManager).getCurrentPhoneCapability(); 138 139 doReturn(Call.State.ACTIVE).when(mActiveCall).getState(); 140 doReturn(Call.State.IDLE).when(mInactiveCall).getState(); 141 doReturn(Call.State.HOLDING).when(mHoldingCall).getState(); 142 143 replaceInstance(Phone.class, "mCi", mPhone, mCommandsInterface0); 144 replaceInstance(Phone.class, "mCi", mPhone2, mCommandsInterface1); 145 } 146 147 @After tearDown()148 public void tearDown() throws Exception { 149 super.tearDown(); 150 } 151 152 /** 153 * Test that a single phone case results in our phone being active and the RIL called 154 */ 155 @Test 156 @SmallTest testRegister()157 public void testRegister() throws Exception { 158 initialize(); 159 160 // verify nothing has been done while there are no inputs 161 assertFalse("data allowed initially", mDataAllowed[0]); 162 assertFalse("data allowed initially", mDataAllowed[1]); 163 164 NetworkRequest internetNetworkRequest = addInternetNetworkRequest(null, 50); 165 166 assertFalse("phone active after request", mPhoneSwitcher 167 .shouldApplyNetworkRequest(internetNetworkRequest, 0)); 168 169 // not registered yet - shouldn't inc 170 verify(mActivePhoneSwitchHandler, never()).sendMessageAtTime(any(), anyLong()); 171 172 mPhoneSwitcher.registerForActivePhoneSwitch(mActivePhoneSwitchHandler, 173 ACTIVE_PHONE_SWITCH, null); 174 175 verify(mActivePhoneSwitchHandler, times(1)).sendMessageAtTime(any(), anyLong()); 176 clearInvocations(mActivePhoneSwitchHandler); 177 178 setDefaultDataSubId(0); 179 180 verify(mActivePhoneSwitchHandler, never()).sendMessageAtTime(any(), anyLong()); 181 182 setSlotIndexToSubId(0, 0); 183 mSubChangedListener.onSubscriptionsChanged(); 184 processAllMessages(); 185 186 AsyncResult res = new AsyncResult(1, null, null); 187 Message.obtain(mPhoneSwitcher, EVENT_MODEM_COMMAND_DONE, res).sendToTarget(); 188 processAllMessages(); 189 verify(mActivePhoneSwitchHandler, times(1)).sendMessageAtTime(any(), anyLong()); 190 clearInvocations(mActivePhoneSwitchHandler); 191 assertTrue("data not allowed", mDataAllowed[0]); 192 193 // now try various things that should cause the active phone to switch: 194 // 1 lose default via default sub change 195 // 2 gain default via default sub change 196 // 3 lose default via sub->phone change 197 // 4 gain default via sub->phone change 198 // 5 lose default network request 199 // 6 gain subscription-specific request 200 // 7 lose via sub->phone change 201 // 8 gain via sub->phone change 202 // 9 lose subscription-specific request 203 // 10 don't switch phones when in emergency mode 204 205 // 1 lose default via default sub change 206 setDefaultDataSubId(1); 207 208 Message.obtain(mPhoneSwitcher, EVENT_MODEM_COMMAND_DONE, res).sendToTarget(); 209 processAllMessages(); 210 verify(mActivePhoneSwitchHandler, times(1)).sendMessageAtTime(any(), anyLong()); 211 clearInvocations(mActivePhoneSwitchHandler); 212 assertFalse("data allowed", mDataAllowed[0]); 213 214 setSlotIndexToSubId(1, 1); 215 mSubChangedListener.onSubscriptionsChanged(); 216 processAllMessages(); 217 218 Message.obtain(mPhoneSwitcher, EVENT_MODEM_COMMAND_DONE, res).sendToTarget(); 219 processAllMessages(); 220 verify(mActivePhoneSwitchHandler, times(1)).sendMessageAtTime(any(), anyLong()); 221 clearInvocations(mActivePhoneSwitchHandler); 222 assertFalse("data allowed", mDataAllowed[0]); 223 assertTrue("data not allowed", mDataAllowed[1]); 224 225 // 2 gain default via default sub change 226 setDefaultDataSubId(0); 227 228 Message.obtain(mPhoneSwitcher, EVENT_MODEM_COMMAND_DONE, res).sendToTarget(); 229 processAllMessages(); 230 verify(mActivePhoneSwitchHandler, times(1)).sendMessageAtTime(any(), anyLong()); 231 clearInvocations(mActivePhoneSwitchHandler); 232 assertFalse("data allowed", mDataAllowed[1]); 233 assertTrue("data not allowed", mDataAllowed[0]); 234 235 // 3 lose default via sub->phone change 236 setSlotIndexToSubId(0, 2); 237 mSubChangedListener.onSubscriptionsChanged(); 238 processAllMessages(); 239 Message.obtain(mPhoneSwitcher, EVENT_MODEM_COMMAND_DONE, res).sendToTarget(); 240 processAllMessages(); 241 242 verify(mActivePhoneSwitchHandler, times(1)).sendMessageAtTime(any(), anyLong()); 243 clearInvocations(mActivePhoneSwitchHandler); 244 assertFalse("data allowed", mDataAllowed[0]); 245 assertFalse("data allowed", mDataAllowed[1]); 246 247 // 4 gain default via sub->phone change 248 setSlotIndexToSubId(0, 0); 249 mSubChangedListener.onSubscriptionsChanged(); 250 processAllMessages(); 251 252 Message.obtain(mPhoneSwitcher, EVENT_MODEM_COMMAND_DONE, res).sendToTarget(); 253 processAllMessages(); 254 verify(mActivePhoneSwitchHandler, times(1)).sendMessageAtTime(any(), anyLong()); 255 clearInvocations(mActivePhoneSwitchHandler); 256 assertTrue("data not allowed", mDataAllowed[0]); 257 assertFalse("data allowed", mDataAllowed[1]); 258 259 // 5 lose default network request 260 releaseNetworkRequest(internetNetworkRequest); 261 262 Message.obtain(mPhoneSwitcher, EVENT_MODEM_COMMAND_DONE, res).sendToTarget(); 263 processAllMessages(); 264 verify(mActivePhoneSwitchHandler, times(1)).sendMessageAtTime(any(), anyLong()); 265 clearInvocations(mActivePhoneSwitchHandler); 266 assertFalse("data allowed", mDataAllowed[0]); 267 assertFalse("data allowed", mDataAllowed[1]); 268 269 // 6 gain subscription-specific request 270 NetworkRequest specificInternetRequest = addInternetNetworkRequest(0, 50); 271 272 Message.obtain(mPhoneSwitcher, EVENT_MODEM_COMMAND_DONE, res).sendToTarget(); 273 processAllMessages(); 274 verify(mActivePhoneSwitchHandler, times(1)).sendMessageAtTime(any(), anyLong()); 275 clearInvocations(mActivePhoneSwitchHandler); 276 assertTrue("data not allowed", mDataAllowed[0]); 277 assertFalse("data allowed", mDataAllowed[1]); 278 279 // 7 lose via sub->phone change 280 setSlotIndexToSubId(0, 1); 281 mSubChangedListener.onSubscriptionsChanged(); 282 processAllMessages(); 283 284 Message.obtain(mPhoneSwitcher, EVENT_MODEM_COMMAND_DONE, res).sendToTarget(); 285 processAllMessages(); 286 verify(mActivePhoneSwitchHandler, times(1)).sendMessageAtTime(any(), anyLong()); 287 clearInvocations(mActivePhoneSwitchHandler); 288 assertFalse("data allowed", mDataAllowed[0]); 289 assertFalse("data allowed", mDataAllowed[1]); 290 291 // 8 gain via sub->phone change 292 setSlotIndexToSubId(0, 0); 293 mSubChangedListener.onSubscriptionsChanged(); 294 processAllMessages(); 295 296 Message.obtain(mPhoneSwitcher, EVENT_MODEM_COMMAND_DONE, res).sendToTarget(); 297 processAllMessages(); 298 verify(mActivePhoneSwitchHandler, times(1)).sendMessageAtTime(any(), anyLong()); 299 clearInvocations(mActivePhoneSwitchHandler); 300 assertTrue("data not allowed", mDataAllowed[0]); 301 assertFalse("data allowed", mDataAllowed[1]); 302 303 // 9 lose subscription-specific request 304 releaseNetworkRequest(specificInternetRequest); 305 306 Message.obtain(mPhoneSwitcher, EVENT_MODEM_COMMAND_DONE, res).sendToTarget(); 307 processAllMessages(); 308 verify(mActivePhoneSwitchHandler, times(1)).sendMessageAtTime(any(), anyLong()); 309 clearInvocations(mActivePhoneSwitchHandler); 310 assertFalse("data allowed", mDataAllowed[0]); 311 assertFalse("data allowed", mDataAllowed[1]); 312 313 // 10 don't switch phones when in emergency mode 314 // not ready yet - Phone turns out to be hard to stub out 315 // phones[0].setInEmergencyCall(true); 316 // connectivityServiceMock.addDefaultRequest(); 317 // processAllMessages(); 318 // if (testHandler.getActivePhoneSwitchCount() != 11) { 319 // fail("after release of request, ActivePhoneSwitchCount not 11!"); 320 // } 321 // if (commandsInterfaces[0].isDataAllowed()) fail("data allowed"); 322 // if (commandsInterfaces[1].isDataAllowed()) fail("data allowed"); 323 // 324 // phones[0].setInEmergencyCall(false); 325 // connectivityServiceMock.addDefaultRequest(); 326 // processAllMessages(); 327 // if (testHandler.getActivePhoneSwitchCount() != 12) { 328 // fail("after release of request, ActivePhoneSwitchCount not 11!"); 329 // } 330 // if (commandsInterfaces[0].isDataAllowed()) fail("data allowed"); 331 // if (commandsInterfaces[1].isDataAllowed()) fail("data allowed"); 332 } 333 334 /** 335 * Test a multi-sim case with limited active phones: 336 * - lose default via default sub change 337 * - lose default via sub->phone change 338 * - gain default via sub->phone change 339 * - gain default via default sub change 340 * - lose default network request 341 * - gain subscription-specific request 342 * - lose via sub->phone change 343 * - gain via sub->phone change 344 * - lose subscription-specific request 345 * - tear down low priority phone when new request comes in 346 * - tear down low priority phone when sub change causes split 347 * - bring up low priority phone when sub change causes join 348 * - don't switch phones when in emergency mode 349 */ 350 @Test 351 @SmallTest testPrioritization()352 public void testPrioritization() throws Exception { 353 initialize(); 354 355 addInternetNetworkRequest(null, 50); 356 setSlotIndexToSubId(0, 0); 357 setSlotIndexToSubId(1, 1); 358 setDefaultDataSubId(0); 359 mPhoneSwitcher.registerForActivePhoneSwitch(mActivePhoneSwitchHandler, 360 ACTIVE_PHONE_SWITCH, null); 361 processAllMessages(); 362 // verify initial conditions 363 verify(mActivePhoneSwitchHandler, times(1)).sendMessageAtTime(any(), anyLong()); 364 365 assertTrue("data not allowed", mDataAllowed[0]); 366 assertFalse("data allowed", mDataAllowed[1]); 367 368 // now start a higher priority connection on the other sub 369 addMmsNetworkRequest(1); 370 371 AsyncResult res = new AsyncResult(1, null, null); 372 Message.obtain(mPhoneSwitcher, EVENT_MODEM_COMMAND_DONE, res).sendToTarget(); 373 processAllMessages(); 374 375 // After gain of network request, mActivePhoneSwitchHandler should be notified 2 times. 376 verify(mActivePhoneSwitchHandler, times(2)).sendMessageAtTime(any(), anyLong()); 377 assertFalse("data allowed", mDataAllowed[0]); 378 assertTrue("data not allowed", mDataAllowed[1]); 379 } 380 381 /** 382 * Verify we don't send spurious DATA_ALLOWED calls when another NetworkProvider 383 * wins (ie, switch to wifi). 384 */ 385 @Test 386 @SmallTest testHigherPriorityDefault()387 public void testHigherPriorityDefault() throws Exception { 388 initialize(); 389 390 addInternetNetworkRequest(null, 50); 391 392 setSlotIndexToSubId(0, 0); 393 setSlotIndexToSubId(1, 1); 394 setDefaultDataSubId(0); 395 396 // Phone 0 should be active 397 assertTrue("data not allowed", mDataAllowed[0]); 398 assertFalse("data allowed", mDataAllowed[1]); 399 400 addInternetNetworkRequest(null, 100); 401 402 // should be no change 403 assertTrue("data not allowed", mDataAllowed[0]); 404 assertFalse("data allowed", mDataAllowed[1]); 405 406 addInternetNetworkRequest(null, 0); 407 // should be no change 408 assertTrue("data not allowed", mDataAllowed[0]); 409 assertFalse("data allowed", mDataAllowed[1]); 410 } 411 412 /** 413 * Verify testSetPreferredData. 414 * When preferredData is set, it overwrites defaultData sub to be active sub in single 415 * active phone mode. If it's unset (to DEFAULT_SUBSCRIPTION_ID), defaultData sub becomes 416 * active one. 417 */ 418 @Test 419 @SmallTest testSetPreferredData()420 public void testSetPreferredData() throws Exception { 421 initialize(); 422 423 // Phone 0 has sub 1, phone 1 has sub 2. 424 // Sub 1 is default data sub. 425 // Both are active subscriptions are active sub, as they are in both active slots. 426 setSlotIndexToSubId(0, 1); 427 setSlotIndexToSubId(1, 2); 428 setDefaultDataSubId(1); 429 430 doReturn(true).when(mSubscriptionController).isOpportunistic(2); 431 432 // Notify phoneSwitcher about default data sub and default network request. 433 addInternetNetworkRequest(null, 50); 434 // Phone 0 (sub 1) should be activated as it has default data sub. 435 assertTrue(mDataAllowed[0]); 436 437 // Set sub 2 as preferred sub should make phone 1 activated and phone 0 deactivated. 438 mPhoneSwitcher.trySetOpportunisticDataSubscription(2, false, null); 439 processAllMessages(); 440 mPhoneSwitcher.mValidationCallback.onNetworkAvailable(null, 2); 441 processAllMessages(); 442 assertFalse(mDataAllowed[0]); 443 assertTrue(mDataAllowed[1]); 444 445 // Unset preferred sub should make default data sub (phone 0 / sub 1) activated again. 446 mPhoneSwitcher.trySetOpportunisticDataSubscription( 447 SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, false, null); 448 processAllMessages(); 449 mPhoneSwitcher.mValidationCallback.onNetworkAvailable(null, 1); 450 processAllMessages(); 451 assertTrue(mDataAllowed[0]); 452 assertFalse(mDataAllowed[1]); 453 } 454 455 @Test 456 @SmallTest testSetPreferredDataModemCommand()457 public void testSetPreferredDataModemCommand() throws Exception { 458 doReturn(true).when(mMockRadioConfig).isSetPreferredDataCommandSupported(); 459 initialize(); 460 mPhoneSwitcher.registerForActivePhoneSwitch(mActivePhoneSwitchHandler, 461 ACTIVE_PHONE_SWITCH, null); 462 mPhoneSwitcher.registerForActivePhoneSwitch(mActivePhoneSwitchHandler, 463 ACTIVE_PHONE_SWITCH, null); 464 verify(mActivePhoneSwitchHandler, times(2)).sendMessageAtTime(any(), anyLong()); 465 clearInvocations(mMockRadioConfig); 466 clearInvocations(mActivePhoneSwitchHandler); 467 468 // Phone 0 has sub 1, phone 1 has sub 2. 469 // Sub 1 is default data sub. 470 // Both are active subscriptions are active sub, as they are in both active slots. 471 setSlotIndexToSubId(0, 1); 472 setSlotIndexToSubId(1, 2); 473 setDefaultDataSubId(1); 474 // Phone 0 (sub 1) should be preferred data phone as it has default data sub. 475 verify(mMockRadioConfig).setPreferredDataModem(eq(0), any()); 476 AsyncResult res = new AsyncResult(1, null, null); 477 Message.obtain(mPhoneSwitcher, EVENT_MODEM_COMMAND_DONE, res).sendToTarget(); 478 processAllMessages(); 479 verify(mActivePhoneSwitchHandler, times(2)).sendMessageAtTime(any(), anyLong()); 480 clearInvocations(mMockRadioConfig); 481 clearInvocations(mActivePhoneSwitchHandler); 482 483 // Notify phoneSwitcher about default data sub and default network request. 484 // It shouldn't change anything. 485 NetworkRequest internetRequest = addInternetNetworkRequest(null, 50); 486 NetworkRequest mmsRequest = addMmsNetworkRequest(2); 487 verify(mMockRadioConfig, never()).setPreferredDataModem(anyInt(), any()); 488 verify(mActivePhoneSwitchHandler, never()).sendMessageAtTime(any(), anyLong()); 489 assertTrue(mPhoneSwitcher.shouldApplyNetworkRequest(internetRequest, 0)); 490 assertFalse(mPhoneSwitcher.shouldApplyNetworkRequest(mmsRequest, 0)); 491 assertFalse(mPhoneSwitcher.shouldApplyNetworkRequest(internetRequest, 1)); 492 assertTrue(mPhoneSwitcher.shouldApplyNetworkRequest(mmsRequest, 1)); 493 494 // Set sub 2 as preferred sub should make phone 1 preferredDataModem 495 doReturn(true).when(mSubscriptionController).isOpportunistic(2); 496 mPhoneSwitcher.trySetOpportunisticDataSubscription(2, false, null); 497 processAllMessages(); 498 mPhoneSwitcher.mValidationCallback.onNetworkAvailable(null, 2); 499 processAllMessages(); 500 verify(mMockRadioConfig).setPreferredDataModem(eq(1), any()); 501 Message.obtain(mPhoneSwitcher, EVENT_MODEM_COMMAND_DONE, res).sendToTarget(); 502 processAllMessages(); 503 verify(mActivePhoneSwitchHandler, times(2)).sendMessageAtTime(any(), anyLong()); 504 assertFalse(mPhoneSwitcher.shouldApplyNetworkRequest(internetRequest, 0)); 505 assertFalse(mPhoneSwitcher.shouldApplyNetworkRequest(mmsRequest, 0)); 506 assertTrue(mPhoneSwitcher.shouldApplyNetworkRequest(internetRequest, 1)); 507 assertTrue(mPhoneSwitcher.shouldApplyNetworkRequest(mmsRequest, 1)); 508 509 clearInvocations(mMockRadioConfig); 510 clearInvocations(mActivePhoneSwitchHandler); 511 512 // Unset preferred sub should make phone0 preferredDataModem again. 513 mPhoneSwitcher.trySetOpportunisticDataSubscription( 514 SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, false, null); 515 processAllMessages(); 516 mPhoneSwitcher.mValidationCallback.onNetworkAvailable(null, 1); 517 processAllMessages(); 518 519 verify(mMockRadioConfig).setPreferredDataModem(eq(0), any()); 520 Message.obtain(mPhoneSwitcher, EVENT_MODEM_COMMAND_DONE, res).sendToTarget(); 521 processAllMessages(); 522 verify(mActivePhoneSwitchHandler, times(2)).sendMessageAtTime(any(), anyLong()); 523 assertTrue(mPhoneSwitcher.shouldApplyNetworkRequest(internetRequest, 0)); 524 assertFalse(mPhoneSwitcher.shouldApplyNetworkRequest(mmsRequest, 0)); 525 assertFalse(mPhoneSwitcher.shouldApplyNetworkRequest(internetRequest, 1)); 526 assertTrue(mPhoneSwitcher.shouldApplyNetworkRequest(mmsRequest, 1)); 527 528 // SetDataAllowed should never be triggered. 529 verify(mCommandsInterface0, never()).setDataAllowed(anyBoolean(), any()); 530 verify(mCommandsInterface1, never()).setDataAllowed(anyBoolean(), any()); 531 532 // Set preferred data modem should be triggered after radio on or available. 533 clearInvocations(mMockRadioConfig); 534 Message.obtain(mPhoneSwitcher, EVENT_RADIO_ON, res).sendToTarget(); 535 processAllMessages(); 536 verify(mMockRadioConfig).setPreferredDataModem(eq(0), any()); 537 } 538 539 @Test 540 @SmallTest testSetPreferredDataWithValidation()541 public void testSetPreferredDataWithValidation() throws Exception { 542 doReturn(true).when(mMockRadioConfig).isSetPreferredDataCommandSupported(); 543 initialize(); 544 545 // Mark sub 2 as opportunistic. 546 doReturn(true).when(mSubscriptionController).isOpportunistic(2); 547 // Phone 0 has sub 1, phone 1 has sub 2. 548 // Sub 1 is default data sub. 549 // Both are active subscriptions are active sub, as they are in both active slots. 550 setSlotIndexToSubId(0, 1); 551 setSlotIndexToSubId(1, 2); 552 setDefaultDataSubId(1); 553 554 // Phone 0 (sub 1) should be activated as it has default data sub. 555 assertEquals(0, mPhoneSwitcher.getPreferredDataPhoneId()); 556 557 // Set sub 2 as preferred sub should make phone 1 activated and phone 0 deactivated. 558 mPhoneSwitcher.trySetOpportunisticDataSubscription(2, true, null); 559 processAllMessages(); 560 verify(mCellularNetworkValidator).validate(eq(2), anyLong(), eq(false), 561 eq(mPhoneSwitcher.mValidationCallback)); 562 // Validation failed. Preferred data sub should remain 1, data phone should remain 0. 563 mPhoneSwitcher.mValidationCallback.onValidationDone(false, 2); 564 processAllMessages(); 565 assertEquals(0, mPhoneSwitcher.getPreferredDataPhoneId()); 566 567 // Validation succeeds. Preferred data sub changes to 2, data phone changes to 1. 568 mPhoneSwitcher.trySetOpportunisticDataSubscription(2, true, null); 569 processAllMessages(); 570 mPhoneSwitcher.mValidationCallback.onValidationDone(true, 2); 571 processAllMessages(); 572 assertEquals(1, mPhoneSwitcher.getPreferredDataPhoneId()); 573 574 // Switching data back to primary (subId 1) with customized validation timeout. 575 long timeout = 1234; 576 mContextFixture.getCarrierConfigBundle().putLong( 577 KEY_DATA_SWITCH_VALIDATION_TIMEOUT_LONG, timeout); 578 mPhoneSwitcher.trySetOpportunisticDataSubscription( 579 SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, true, null); 580 processAllMessages(); 581 verify(mCellularNetworkValidator).validate(eq(1), eq(timeout), eq(false), 582 eq(mPhoneSwitcher.mValidationCallback)); 583 mPhoneSwitcher.mValidationCallback.onValidationDone(true, 1); 584 processAllMessages(); 585 assertEquals(0, mPhoneSwitcher.getPreferredDataPhoneId()); 586 } 587 mockImsRegTech(int phoneId, int regTech)588 private void mockImsRegTech(int phoneId, int regTech) { 589 doReturn(regTech).when(mMockImsRegTechProvider).get(any(), eq(phoneId)); 590 mPhoneSwitcher.mImsRegTechProvider = mMockImsRegTechProvider; 591 } 592 593 @Test 594 @SmallTest testNonDefaultDataPhoneInCall_ImsCallOnLte_shouldSwitchDds()595 public void testNonDefaultDataPhoneInCall_ImsCallOnLte_shouldSwitchDds() throws Exception { 596 initialize(); 597 setAllPhonesInactive(); 598 599 // Phone 0 has sub 1, phone 1 has sub 2. 600 // Sub 1 is default data sub. 601 // Both are active subscriptions are active sub, as they are in both active slots. 602 setSlotIndexToSubId(0, 1); 603 setSlotIndexToSubId(1, 2); 604 setDefaultDataSubId(1); 605 processAllMessages(); 606 607 // Phone 0 should be the default data phoneId. 608 assertEquals(0, mPhoneSwitcher.getPreferredDataPhoneId()); 609 610 // Phone2 has active IMS call on LTE. And data of DEFAULT apn is enabled. This should 611 // trigger data switch. 612 doReturn(mImsPhone).when(mPhone2).getImsPhone(); 613 doReturn(true).when(mDataEnabledSettings2).isDataEnabled(ApnSetting.TYPE_DEFAULT); 614 mockImsRegTech(1, REGISTRATION_TECH_LTE); 615 notifyPhoneAsInCall(mImsPhone); 616 617 // Phone 1 should become the default data phone. 618 assertEquals(1, mPhoneSwitcher.getPreferredDataPhoneId()); 619 } 620 621 @Test 622 @SmallTest testNonDefaultDataPhoneInCall_ImsCallOnWlan_shouldNotSwitchDds()623 public void testNonDefaultDataPhoneInCall_ImsCallOnWlan_shouldNotSwitchDds() throws Exception { 624 initialize(); 625 setAllPhonesInactive(); 626 627 // Phone 0 has sub 1, phone 1 has sub 2. 628 // Sub 1 is default data sub. 629 // Both are active subscriptions are active sub, as they are in both active slots. 630 setSlotIndexToSubId(0, 1); 631 setSlotIndexToSubId(1, 2); 632 setDefaultDataSubId(1); 633 processAllMessages(); 634 635 // Phone 0 should be the default data phoneId. 636 assertEquals(0, mPhoneSwitcher.getPreferredDataPhoneId()); 637 638 // Phone2 has active call, but data is turned off. So no data switching should happen. 639 doReturn(mImsPhone).when(mPhone2).getImsPhone(); 640 doReturn(true).when(mDataEnabledSettings2).isDataEnabled(ApnSetting.TYPE_DEFAULT); 641 mockImsRegTech(1, REGISTRATION_TECH_IWLAN); 642 notifyPhoneAsInCall(mImsPhone); 643 644 // Phone 0 should remain the default data phone. 645 assertEquals(0, mPhoneSwitcher.getPreferredDataPhoneId()); 646 } 647 648 @Test 649 @SmallTest testNonDefaultDataPhoneInCall_ImsCallOnCrossSIM_HandoverToLTE()650 public void testNonDefaultDataPhoneInCall_ImsCallOnCrossSIM_HandoverToLTE() throws Exception { 651 initialize(); 652 setAllPhonesInactive(); 653 654 // Phone 0 has sub 1, phone 1 has sub 2. 655 // Sub 1 is default data sub. 656 // Both are active subscriptions are active sub, as they are in both active slots. 657 setSlotIndexToSubId(0, 1); 658 setSlotIndexToSubId(1, 2); 659 setDefaultDataSubId(1); 660 processAllMessages(); 661 662 // Phone 0 should be the default data phoneId. 663 assertEquals(0, mPhoneSwitcher.getPreferredDataPhoneId()); 664 665 // Phone 1 has active IMS call on CROSS_SIM. And data of DEFAULT apn is enabled. This should 666 // not trigger data switch. 667 doReturn(mImsPhone).when(mPhone2).getImsPhone(); 668 doReturn(true).when(mDataEnabledSettings2).isDataEnabled(ApnSetting.TYPE_DEFAULT); 669 mockImsRegTech(1, REGISTRATION_TECH_CROSS_SIM); 670 notifyPhoneAsInCall(mImsPhone); 671 672 // Phone 0 should remain the default data phone. 673 assertEquals(0, mPhoneSwitcher.getPreferredDataPhoneId()); 674 675 // Phone 1 has has handed over the call to LTE. And data of DEFAULT apn is enabled. 676 // This should trigger data switch. 677 mockImsRegTech(1, REGISTRATION_TECH_LTE); 678 notifyImsRegistrationTechChange(mPhone2); 679 680 // Phone 1 should become the default data phone. 681 assertEquals(1, mPhoneSwitcher.getPreferredDataPhoneId()); 682 } 683 684 @Test 685 @SmallTest testNonDefaultDataPhoneInCall()686 public void testNonDefaultDataPhoneInCall() throws Exception { 687 doReturn(true).when(mMockRadioConfig).isSetPreferredDataCommandSupported(); 688 initialize(); 689 // Phone 0 has sub 1, phone 1 has sub 2. 690 // Sub 1 is default data sub. 691 // Both are active subscriptions are active sub, as they are in both active slots. 692 setSlotIndexToSubId(0, 1); 693 setSlotIndexToSubId(1, 2); 694 setDefaultDataSubId(1); 695 NetworkRequest internetRequest = addInternetNetworkRequest(null, 50); 696 assertTrue(mPhoneSwitcher.shouldApplyNetworkRequest(internetRequest, 0)); 697 assertFalse(mPhoneSwitcher.shouldApplyNetworkRequest(internetRequest, 1)); 698 clearInvocations(mMockRadioConfig); 699 setAllPhonesInactive(); 700 // Initialization done. 701 702 // Phone2 has active call, but data is turned off. So no data switching should happen. 703 notifyDataEnabled(false); 704 notifyPhoneAsInCall(mPhone2); 705 verify(mMockRadioConfig, never()).setPreferredDataModem(anyInt(), any()); 706 assertTrue(mPhoneSwitcher.shouldApplyNetworkRequest(internetRequest, 0)); 707 assertFalse(mPhoneSwitcher.shouldApplyNetworkRequest(internetRequest, 1)); 708 709 // Phone2 has active call. So data switch to it. 710 notifyDataEnabled(true); 711 verify(mMockRadioConfig).setPreferredDataModem(eq(1), any()); 712 assertTrue(mPhoneSwitcher.shouldApplyNetworkRequest(internetRequest, 1)); 713 assertFalse(mPhoneSwitcher.shouldApplyNetworkRequest(internetRequest, 0)); 714 clearInvocations(mMockRadioConfig); 715 716 // Phone2 call ended. So data switch back to default data sub. 717 notifyPhoneAsInactive(mPhone2); 718 verify(mMockRadioConfig).setPreferredDataModem(eq(0), any()); 719 assertTrue(mPhoneSwitcher.shouldApplyNetworkRequest(internetRequest, 0)); 720 assertFalse(mPhoneSwitcher.shouldApplyNetworkRequest(internetRequest, 1)); 721 clearInvocations(mMockRadioConfig); 722 723 // Phone2 has holding call, but data is turned off. So no data switching should happen. 724 notifyPhoneAsInHoldingCall(mPhone2); 725 verify(mMockRadioConfig).setPreferredDataModem(eq(1), any()); 726 assertTrue(mPhoneSwitcher.shouldApplyNetworkRequest(internetRequest, 1)); 727 assertFalse(mPhoneSwitcher.shouldApplyNetworkRequest(internetRequest, 0)); 728 } 729 730 731 @Test 732 @SmallTest testNetworkRequestOnNonDefaultData()733 public void testNetworkRequestOnNonDefaultData() throws Exception { 734 doReturn(true).when(mMockRadioConfig).isSetPreferredDataCommandSupported(); 735 initialize(); 736 // Phone 0 has sub 1, phone 1 has sub 2. 737 // Sub 1 is default data sub. 738 // Both are active subscriptions are active sub, as they are in both active slots. 739 setSlotIndexToSubId(0, 1); 740 setSlotIndexToSubId(1, 2); 741 setDefaultDataSubId(1); 742 NetworkRequest internetRequest = addInternetNetworkRequest(2, 50); 743 assertFalse(mPhoneSwitcher.shouldApplyNetworkRequest(internetRequest, 0)); 744 assertFalse(mPhoneSwitcher.shouldApplyNetworkRequest(internetRequest, 1)); 745 746 // Restricted network request will should be applied. 747 internetRequest = addInternetNetworkRequest(2, 50, true); 748 assertFalse(mPhoneSwitcher.shouldApplyNetworkRequest(internetRequest, 0)); 749 assertTrue(mPhoneSwitcher.shouldApplyNetworkRequest(internetRequest, 1)); 750 } 751 752 @Test 753 @SmallTest testEmergencyOverrideSuccessBeforeCallStarts()754 public void testEmergencyOverrideSuccessBeforeCallStarts() throws Exception { 755 doReturn(true).when(mMockRadioConfig).isSetPreferredDataCommandSupported(); 756 initialize(); 757 // Phone 0 has sub 1, phone 1 has sub 2. 758 // Sub 1 is default data sub. 759 // Both are active subscriptions are active sub, as they are in both active slots. 760 setMsimDefaultDataSubId(1); 761 clearInvocations(mMockRadioConfig); 762 763 // override the phone ID in prep for emergency call 764 mPhoneSwitcher.overrideDefaultDataForEmergency(1, 1, mFuturePhone); 765 sendPreferredDataSuccessResult(1); 766 processAllMessages(); 767 verify(mFuturePhone).complete(true); 768 769 // Make sure the correct broadcast is sent out for the overridden phone ID 770 verify(mTelephonyRegistryManager).notifyActiveDataSubIdChanged(eq(2)); 771 } 772 773 @Test 774 @SmallTest testEmergencyOverrideNoDdsChange()775 public void testEmergencyOverrideNoDdsChange() throws Exception { 776 doReturn(true).when(mMockRadioConfig).isSetPreferredDataCommandSupported(); 777 initialize(); 778 // Phone 0 has sub 1, phone 1 has sub 2. 779 // Sub 1 is default data sub. 780 // Both are active subscriptions are active sub, as they are in both active slots. 781 setMsimDefaultDataSubId(1); 782 clearInvocations(mMockRadioConfig); 783 784 // override the phone ID in prep for emergency call 785 mPhoneSwitcher.overrideDefaultDataForEmergency(0, 1, mFuturePhone); 786 processAllMessages(); 787 // The radio command should never be called because the DDS hasn't changed. 788 verify(mMockRadioConfig, never()).setPreferredDataModem(eq(0), any()); 789 processAllMessages(); 790 verify(mFuturePhone).complete(true); 791 } 792 793 @Test 794 @SmallTest testEmergencyOverrideEndSuccess()795 public void testEmergencyOverrideEndSuccess() throws Exception { 796 PhoneSwitcher.ECBM_DEFAULT_DATA_SWITCH_BASE_TIME_MS = 500; 797 doReturn(true).when(mMockRadioConfig).isSetPreferredDataCommandSupported(); 798 initialize(); 799 // Phone 0 has sub 1, phone 1 has sub 2. 800 // Sub 1 is default data sub. 801 // Both are active subscriptions are active sub, as they are in both active slots. 802 setMsimDefaultDataSubId(1); 803 setAllPhonesInactive(); 804 clearInvocations(mMockRadioConfig); 805 clearInvocations(mTelephonyRegistryManager); 806 807 // override the phone ID in prep for emergency call 808 809 mPhoneSwitcher.overrideDefaultDataForEmergency(1, 1, mFuturePhone); 810 sendPreferredDataSuccessResult(1); 811 processAllMessages(); 812 verify(mFuturePhone).complete(true); 813 814 // Start and end the emergency call, which will start override timer 815 notifyPhoneAsInCall(mPhone2); 816 notifyPhoneAsInactive(mPhone2); 817 818 clearInvocations(mTelephonyRegistryManager); 819 // Verify that the DDS is successfully switched back after 1 second + base ECBM timeout 820 moveTimeForward(ECBM_DEFAULT_DATA_SWITCH_BASE_TIME_MS + 1000); 821 processAllMessages(); 822 verify(mMockRadioConfig).setPreferredDataModem(eq(0), any()); 823 AsyncResult res = new AsyncResult(1, null, null); 824 Message.obtain(mPhoneSwitcher, EVENT_MODEM_COMMAND_DONE, res).sendToTarget(); 825 processAllMessages(); 826 827 // Make sure the correct broadcast is sent out for the phone ID 828 verify(mTelephonyRegistryManager).notifyActiveDataSubIdChanged(eq(1)); 829 } 830 831 @Test 832 @SmallTest testEmergencyOverrideEcbmStartEnd()833 public void testEmergencyOverrideEcbmStartEnd() throws Exception { 834 PhoneSwitcher.ECBM_DEFAULT_DATA_SWITCH_BASE_TIME_MS = 500; 835 doReturn(true).when(mMockRadioConfig).isSetPreferredDataCommandSupported(); 836 initialize(); 837 // Phone 0 has sub 1, phone 1 has sub 2. 838 // Sub 1 is default data sub. 839 // Both are active subscriptions are active sub, as they are in both active slots. 840 setMsimDefaultDataSubId(1); 841 setAllPhonesInactive(); 842 clearInvocations(mMockRadioConfig); 843 clearInvocations(mTelephonyRegistryManager); 844 845 // override the phone ID in prep for emergency call 846 mPhoneSwitcher.overrideDefaultDataForEmergency(1, 1, mFuturePhone); 847 sendPreferredDataSuccessResult(1); 848 processAllMessages(); 849 verify(mFuturePhone).complete(true); 850 851 // Start and end the emergency call, which will start override timer 852 notifyPhoneAsInCall(mPhone2); 853 notifyPhoneAsInactive(mPhone2); 854 // Start ECBM 855 Message ecbmMessage = getEcbmRegistration(mPhone2); 856 notifyEcbmStart(mPhone2, ecbmMessage); 857 858 // DDS should not be switched back until ECBM ends, make sure there is no further 859 // interaction. 860 moveTimeForward(ECBM_DEFAULT_DATA_SWITCH_BASE_TIME_MS + 2000); 861 processAllMessages(); 862 verify(mMockRadioConfig, never()).setPreferredDataModem(eq(0), any()); 863 // Make sure the correct broadcast is sent out for the phone ID 864 verify(mTelephonyRegistryManager).notifyActiveDataSubIdChanged(eq(2)); 865 866 // End ECBM 867 clearInvocations(mTelephonyRegistryManager); 868 ecbmMessage = getEcbmRegistration(mPhone2); 869 notifyEcbmEnd(mPhone2, ecbmMessage); 870 // Verify that the DDS is successfully switched back after 1 second. 871 moveTimeForward(1000); 872 processAllMessages(); 873 verify(mMockRadioConfig).setPreferredDataModem(eq(0), any()); 874 AsyncResult res = new AsyncResult(1, null, null); 875 Message.obtain(mPhoneSwitcher, EVENT_MODEM_COMMAND_DONE, res).sendToTarget(); 876 processAllMessages(); 877 // Make sure the correct broadcast is sent out for the phone ID 878 verify(mTelephonyRegistryManager).notifyActiveDataSubIdChanged(eq(1)); 879 } 880 881 @Test 882 @SmallTest testEmergencyOverrideNoCallStart()883 public void testEmergencyOverrideNoCallStart() throws Exception { 884 PhoneSwitcher.DEFAULT_DATA_OVERRIDE_TIMEOUT_MS = 500; 885 doReturn(true).when(mMockRadioConfig).isSetPreferredDataCommandSupported(); 886 initialize(); 887 // Phone 0 has sub 1, phone 1 has sub 2. 888 // Sub 1 is default data sub. 889 // Both are active subscriptions are active sub, as they are in both active slots. 890 setMsimDefaultDataSubId(1); 891 setAllPhonesInactive(); 892 clearInvocations(mMockRadioConfig); 893 clearInvocations(mTelephonyRegistryManager); 894 895 // override the phone ID in prep for emergency call 896 mPhoneSwitcher.overrideDefaultDataForEmergency(1, 1, mFuturePhone); 897 sendPreferredDataSuccessResult(1); 898 processAllMessages(); 899 verify(mFuturePhone).complete(true); 900 901 // Do not start the call and make sure the override is removed once the timeout expires 902 moveTimeForward(PhoneSwitcher.DEFAULT_DATA_OVERRIDE_TIMEOUT_MS); 903 processAllMessages(); 904 verify(mMockRadioConfig).setPreferredDataModem(eq(0), any()); 905 AsyncResult res = new AsyncResult(1, null, null); 906 Message.obtain(mPhoneSwitcher, EVENT_MODEM_COMMAND_DONE, res).sendToTarget(); 907 processAllMessages(); 908 909 // Make sure the correct broadcast is sent out for the phone ID 910 verify(mTelephonyRegistryManager).notifyActiveDataSubIdChanged(eq(1)); 911 } 912 913 @Test 914 @SmallTest testEmergencyOverrideMultipleOverrideRequests()915 public void testEmergencyOverrideMultipleOverrideRequests() throws Exception { 916 PhoneSwitcher.ECBM_DEFAULT_DATA_SWITCH_BASE_TIME_MS = 500; 917 doReturn(true).when(mMockRadioConfig).isSetPreferredDataCommandSupported(); 918 initialize(); 919 // Phone 0 has sub 1, phone 1 has sub 2. 920 // Sub 1 is default data sub. 921 // Both are active subscriptions are active sub, as they are in both active slots. 922 setMsimDefaultDataSubId(1); 923 setAllPhonesInactive(); 924 clearInvocations(mMockRadioConfig); 925 clearInvocations(mTelephonyRegistryManager); 926 927 // override the phone ID in prep for emergency call 928 LinkedBlockingQueue<Boolean> queue = new LinkedBlockingQueue<>(); 929 CompletableFuture<Boolean> futurePhone = new CompletableFuture<>(); 930 futurePhone.whenComplete((r, error) -> queue.offer(r)); 931 mPhoneSwitcher.overrideDefaultDataForEmergency(1, 1, futurePhone); 932 sendPreferredDataSuccessResult(1); 933 processAllMessages(); 934 Boolean result = queue.poll(); 935 assertNotNull(result); 936 assertTrue(result); 937 938 // try override the phone ID again while there is an existing override for a different phone 939 futurePhone = new CompletableFuture<>(); 940 futurePhone.whenComplete((r, error) -> queue.offer(r)); 941 mPhoneSwitcher.overrideDefaultDataForEmergency(0, 1, futurePhone); 942 processAllMessages(); 943 result = queue.poll(); 944 assertNotNull(result); 945 assertFalse(result); 946 verify(mMockRadioConfig, never()).setPreferredDataModem(eq(0), any()); 947 948 // Start and end the emergency call, which will start override timer 949 notifyPhoneAsInCall(mPhone2); 950 notifyPhoneAsInactive(mPhone2); 951 952 // Verify that the DDS is successfully switched back after 1 second + base ECBM timeout 953 moveTimeForward(ECBM_DEFAULT_DATA_SWITCH_BASE_TIME_MS + 1000); 954 processAllMessages(); 955 verify(mMockRadioConfig).setPreferredDataModem(eq(0), any()); 956 AsyncResult res = new AsyncResult(1, null, null); 957 Message.obtain(mPhoneSwitcher, EVENT_MODEM_COMMAND_DONE, res).sendToTarget(); 958 processAllMessages(); 959 960 // Make sure the correct broadcast is sent out for the phone ID 961 verify(mTelephonyRegistryManager).notifyActiveDataSubIdChanged(eq(1)); 962 } 963 964 @Test 965 @SmallTest testSetPreferredDataCallback()966 public void testSetPreferredDataCallback() throws Exception { 967 doReturn(true).when(mMockRadioConfig).isSetPreferredDataCommandSupported(); 968 initialize(); 969 970 // Mark sub 2 as opportunistic. 971 doReturn(true).when(mSubscriptionController).isOpportunistic(2); 972 // Phone 0 has sub 1, phone 1 has sub 2. 973 // Sub 1 is default data sub. 974 // Both are active subscriptions are active sub, as they are in both active slots. 975 setSlotIndexToSubId(0, 1); 976 setSlotIndexToSubId(1, 2); 977 setDefaultDataSubId(1); 978 979 // Validating on sub 10 which is inactive. 980 mPhoneSwitcher.trySetOpportunisticDataSubscription(10, true, mSetOpptDataCallback1); 981 processAllMessages(); 982 verify(mSetOpptDataCallback1).onComplete(SET_OPPORTUNISTIC_SUB_INACTIVE_SUBSCRIPTION); 983 984 // Switch to active subId without validating. Should always succeed. 985 mPhoneSwitcher.trySetOpportunisticDataSubscription(2, false, mSetOpptDataCallback1); 986 processAllMessages(); 987 mPhoneSwitcher.mValidationCallback.onNetworkAvailable(null, 2); 988 processAllMessages(); 989 verify(mSetOpptDataCallback1).onComplete(SET_OPPORTUNISTIC_SUB_SUCCESS); 990 991 // Validating on sub 1 and fails. 992 clearInvocations(mSetOpptDataCallback1); 993 mPhoneSwitcher.trySetOpportunisticDataSubscription(1, true, mSetOpptDataCallback1); 994 processAllMessages(); 995 mPhoneSwitcher.mValidationCallback.onValidationDone(false, 1); 996 processAllMessages(); 997 verify(mSetOpptDataCallback1).onComplete(SET_OPPORTUNISTIC_SUB_VALIDATION_FAILED); 998 999 // Validating on sub 2 and succeeds. 1000 mPhoneSwitcher.trySetOpportunisticDataSubscription(2, true, mSetOpptDataCallback2); 1001 processAllMessages(); 1002 mPhoneSwitcher.mValidationCallback.onValidationDone(true, 2); 1003 processAllMessages(); 1004 verify(mSetOpptDataCallback2).onComplete(SET_OPPORTUNISTIC_SUB_SUCCESS); 1005 1006 // Switching data back to primary and validation fails. 1007 clearInvocations(mSetOpptDataCallback2); 1008 mPhoneSwitcher.trySetOpportunisticDataSubscription( 1009 SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, true, mSetOpptDataCallback2); 1010 processAllMessages(); 1011 mPhoneSwitcher.mValidationCallback.onValidationDone(false, 1); 1012 processAllMessages(); 1013 verify(mSetOpptDataCallback1).onComplete(SET_OPPORTUNISTIC_SUB_VALIDATION_FAILED); 1014 1015 // Switching data back to primary and succeeds. 1016 clearInvocations(mSetOpptDataCallback2); 1017 mPhoneSwitcher.trySetOpportunisticDataSubscription( 1018 SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, true, mSetOpptDataCallback2); 1019 processAllMessages(); 1020 mPhoneSwitcher.mValidationCallback.onValidationDone(true, 1); 1021 processAllMessages(); 1022 verify(mSetOpptDataCallback2).onComplete(SET_OPPORTUNISTIC_SUB_SUCCESS); 1023 1024 // Back to back call on same subId. 1025 clearInvocations(mSetOpptDataCallback1); 1026 clearInvocations(mSetOpptDataCallback2); 1027 clearInvocations(mCellularNetworkValidator); 1028 mPhoneSwitcher.trySetOpportunisticDataSubscription(2, true, mSetOpptDataCallback1); 1029 processAllMessages(); 1030 verify(mCellularNetworkValidator).validate(eq(2), anyLong(), eq(false), 1031 eq(mPhoneSwitcher.mValidationCallback)); 1032 doReturn(true).when(mCellularNetworkValidator).isValidating(); 1033 mPhoneSwitcher.trySetOpportunisticDataSubscription(2, true, mSetOpptDataCallback2); 1034 processAllMessages(); 1035 verify(mSetOpptDataCallback1).onComplete(SET_OPPORTUNISTIC_SUB_VALIDATION_FAILED); 1036 verify(mSetOpptDataCallback2, never()).onComplete(anyInt()); 1037 // Validation succeeds. 1038 doReturn(false).when(mCellularNetworkValidator).isValidating(); 1039 mPhoneSwitcher.mValidationCallback.onValidationDone(true, 2); 1040 processAllMessages(); 1041 verify(mSetOpptDataCallback2).onComplete(SET_OPPORTUNISTIC_SUB_SUCCESS); 1042 1043 mPhoneSwitcher.trySetOpportunisticDataSubscription( 1044 SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, false, null); 1045 processAllMessages(); 1046 mPhoneSwitcher.mValidationCallback.onNetworkAvailable(null, 1); 1047 processAllMessages(); 1048 clearInvocations(mSetOpptDataCallback1); 1049 clearInvocations(mSetOpptDataCallback2); 1050 clearInvocations(mCellularNetworkValidator); 1051 // Back to back call, call 1 to switch to subId 2, call 2 to switch back. 1052 mPhoneSwitcher.trySetOpportunisticDataSubscription(2, true, mSetOpptDataCallback1); 1053 processAllMessages(); 1054 verify(mCellularNetworkValidator).validate(eq(2), anyLong(), eq(false), 1055 eq(mPhoneSwitcher.mValidationCallback)); 1056 doReturn(true).when(mCellularNetworkValidator).isValidating(); 1057 mPhoneSwitcher.trySetOpportunisticDataSubscription( 1058 SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, true, mSetOpptDataCallback2); 1059 processAllMessages(); 1060 // Call 1 should be cancelled and failed. Call 2 return success immediately as there's no 1061 // change. 1062 verify(mSetOpptDataCallback1).onComplete(SET_OPPORTUNISTIC_SUB_VALIDATION_FAILED); 1063 verify(mSetOpptDataCallback2).onComplete(SET_OPPORTUNISTIC_SUB_SUCCESS); 1064 } 1065 1066 @Test 1067 @SmallTest testMultiSimConfigChange()1068 public void testMultiSimConfigChange() throws Exception { 1069 doReturn(true).when(mMockRadioConfig).isSetPreferredDataCommandSupported(); 1070 mActiveModemCount = 1; 1071 initialize(); 1072 sendPreferredDataSuccessResult(0); 1073 1074 // Phone 0 has sub 1, phone 1 has sub 2. 1075 // Sub 1 is default data sub. 1076 // Both are active subscriptions are active sub, as they are in both active slots. 1077 setSlotIndexToSubId(0, 1); 1078 setDefaultDataSubId(1); 1079 1080 setNumPhones(2, 2); 1081 AsyncResult result = new AsyncResult(null, 2, null); 1082 Message.obtain(mPhoneSwitcher, EVENT_MULTI_SIM_CONFIG_CHANGED, result).sendToTarget(); 1083 processAllMessages(); 1084 1085 verify(mPhone2).registerForEmergencyCallToggle(any(), anyInt(), any()); 1086 verify(mPhone2).registerForPreciseCallStateChanged(any(), anyInt(), any()); 1087 verify(mDataEnabledSettings2).registerForDataEnabledChanged(any(), anyInt(), any()); 1088 1089 clearInvocations(mMockRadioConfig); 1090 setSlotIndexToSubId(1, 2); 1091 setDefaultDataSubId(2); 1092 verify(mMockRadioConfig).setPreferredDataModem(eq(1), any()); 1093 } 1094 1095 @Test 1096 @SmallTest testValidationOffSwitch_shouldSwitchOnNetworkAvailable()1097 public void testValidationOffSwitch_shouldSwitchOnNetworkAvailable() throws Exception { 1098 doReturn(true).when(mMockRadioConfig).isSetPreferredDataCommandSupported(); 1099 initialize(); 1100 // Phone 0 has sub 1, phone 1 has sub 2. 1101 // Sub 1 is default data sub. 1102 // Both are active subscriptions are active sub, as they are in both active slots. 1103 setSlotIndexToSubId(0, 1); 1104 setSlotIndexToSubId(1, 2); 1105 setDefaultDataSubId(1); 1106 NetworkRequest internetRequest = addInternetNetworkRequest(null, 50); 1107 assertTrue(mPhoneSwitcher.shouldApplyNetworkRequest(internetRequest, 0)); 1108 assertFalse(mPhoneSwitcher.shouldApplyNetworkRequest(internetRequest, 1)); 1109 clearInvocations(mMockRadioConfig); 1110 setAllPhonesInactive(); 1111 // Initialization done. 1112 1113 doReturn(true).when(mSubscriptionController).isOpportunistic(2); 1114 mPhoneSwitcher.trySetOpportunisticDataSubscription(2, false, mSetOpptDataCallback1); 1115 processAllMessages(); 1116 verify(mCellularNetworkValidator).validate(eq(2), anyLong(), eq(false), 1117 eq(mPhoneSwitcher.mValidationCallback)); 1118 doReturn(true).when(mCellularNetworkValidator).isValidating(); 1119 1120 // Network available on different sub. Should do nothing. 1121 mPhoneSwitcher.mValidationCallback.onNetworkAvailable(null, 1); 1122 processAllMessages(); 1123 verify(mMockRadioConfig, never()).setPreferredDataModem(anyInt(), any()); 1124 1125 // Network available on corresponding sub. Should confirm switch. 1126 mPhoneSwitcher.mValidationCallback.onNetworkAvailable(null, 2); 1127 processAllMessages(); 1128 verify(mMockRadioConfig).setPreferredDataModem(eq(1), any()); 1129 } 1130 1131 @Test 1132 @SmallTest testValidationOffSwitch_shouldSwitchOnTimeOut()1133 public void testValidationOffSwitch_shouldSwitchOnTimeOut() throws Exception { 1134 doReturn(true).when(mMockRadioConfig).isSetPreferredDataCommandSupported(); 1135 initialize(); 1136 // Phone 0 has sub 1, phone 1 has sub 2. 1137 // Sub 1 is default data sub. 1138 // Both are active subscriptions are active sub, as they are in both active slots. 1139 setSlotIndexToSubId(0, 1); 1140 setSlotIndexToSubId(1, 2); 1141 setDefaultDataSubId(1); 1142 NetworkRequest internetRequest = addInternetNetworkRequest(null, 50); 1143 assertTrue(mPhoneSwitcher.shouldApplyNetworkRequest(internetRequest, 0)); 1144 assertFalse(mPhoneSwitcher.shouldApplyNetworkRequest(internetRequest, 1)); 1145 clearInvocations(mMockRadioConfig); 1146 setAllPhonesInactive(); 1147 // Initialization done. 1148 1149 doReturn(true).when(mSubscriptionController).isOpportunistic(2); 1150 mPhoneSwitcher.trySetOpportunisticDataSubscription(2, false, mSetOpptDataCallback1); 1151 processAllMessages(); 1152 verify(mCellularNetworkValidator).validate(eq(2), anyLong(), eq(false), 1153 eq(mPhoneSwitcher.mValidationCallback)); 1154 doReturn(true).when(mCellularNetworkValidator).isValidating(); 1155 1156 // Validation failed on different sub. Should do nothing. 1157 mPhoneSwitcher.mValidationCallback.onValidationDone(false, 1); 1158 processAllMessages(); 1159 verify(mMockRadioConfig, never()).setPreferredDataModem(anyInt(), any()); 1160 1161 // Network available on corresponding sub. Should confirm switch. 1162 mPhoneSwitcher.mValidationCallback.onValidationDone(false, 2); 1163 processAllMessages(); 1164 verify(mMockRadioConfig).setPreferredDataModem(eq(1), any()); 1165 } 1166 1167 @Test testRetry_DDS_switch_Failure()1168 public void testRetry_DDS_switch_Failure() throws Exception { 1169 doReturn(true).when(mMockRadioConfig).isSetPreferredDataCommandSupported(); 1170 mActiveModemCount = 2; 1171 initialize(); 1172 setSlotIndexToSubId(0, 1); 1173 setDefaultDataSubId(1); 1174 1175 clearInvocations(mMockRadioConfig); 1176 // for exceptions OP_NOT_ALLOWED_DURING_VOICE_CALL and INVALID_SIM_STATE, 1177 // modem retry not invoked. 1178 AsyncResult res1 = new AsyncResult(0, null, 1179 new CommandException(CommandException.Error.INVALID_SIM_STATE)); 1180 Message.obtain(mPhoneSwitcher, EVENT_MODEM_COMMAND_DONE, res1).sendToTarget(); 1181 processAllMessages(); 1182 moveTimeForward(5000); 1183 processAllMessages(); 1184 verify(mMockRadioConfig, times(0)).setPreferredDataModem(eq(0), any()); 1185 1186 doReturn(0).when(mSubscriptionController).getPhoneId(anyInt()); 1187 AsyncResult res2 = new AsyncResult(0, null, 1188 new CommandException(CommandException.Error.NETWORK_NOT_READY)); 1189 Message.obtain(mPhoneSwitcher, EVENT_MODEM_COMMAND_DONE, res2).sendToTarget(); 1190 processAllMessages(); 1191 moveTimeForward(5000); 1192 processAllMessages(); 1193 1194 verify(mMockRadioConfig, times(1)).setPreferredDataModem(eq(0), any()); 1195 1196 clearInvocations(mMockRadioConfig); 1197 doReturn(mSubscriptionInfo).when(mSubscriptionController) 1198 .getActiveSubscriptionInfoForSimSlotIndex(eq(0), any(), any()); 1199 doReturn(true).when(mSubscriptionInfo).areUiccApplicationsEnabled(); 1200 doReturn(mIccCard).when(mPhone).getIccCard(); 1201 doReturn(true).when(mIccCard).isEmptyProfile(); 1202 final Intent intent1 = new Intent(ACTION_SIM_APPLICATION_STATE_CHANGED); 1203 intent1.putExtra(EXTRA_SIM_STATE, SIM_STATE_LOADED); 1204 intent1.putExtra(SubscriptionManager.EXTRA_SLOT_INDEX, 0); 1205 mContext.sendBroadcast(intent1); 1206 processAllMessages(); 1207 1208 verify(mMockRadioConfig, times(0)).setPreferredDataModem(eq(0), any()); 1209 1210 doReturn(false).when(mIccCard).isEmptyProfile(); 1211 final Intent intent2 = new Intent(ACTION_SIM_APPLICATION_STATE_CHANGED); 1212 intent2.putExtra(EXTRA_SIM_STATE, SIM_STATE_LOADED); 1213 intent2.putExtra(SubscriptionManager.EXTRA_SLOT_INDEX, 0); 1214 mContext.sendBroadcast(intent2); 1215 processAllMessages(); 1216 1217 verify(mMockRadioConfig, times(1)).setPreferredDataModem(eq(0), any()); 1218 } 1219 1220 /* Private utility methods start here */ 1221 setAllPhonesInactive()1222 private void setAllPhonesInactive() { 1223 doReturn(mInactiveCall).when(mPhone).getForegroundCall(); 1224 doReturn(mInactiveCall).when(mPhone).getBackgroundCall(); 1225 doReturn(mInactiveCall).when(mPhone).getRingingCall(); 1226 doReturn(mInactiveCall).when(mPhone2).getForegroundCall(); 1227 doReturn(mInactiveCall).when(mPhone2).getBackgroundCall(); 1228 doReturn(mInactiveCall).when(mPhone2).getRingingCall(); 1229 doReturn(mInactiveCall).when(mImsPhone).getForegroundCall(); 1230 doReturn(mInactiveCall).when(mImsPhone).getBackgroundCall(); 1231 doReturn(mInactiveCall).when(mImsPhone).getRingingCall(); 1232 } 1233 notifyPhoneAsInCall(Phone phone)1234 private void notifyPhoneAsInCall(Phone phone) { 1235 doReturn(mActiveCall).when(phone).getForegroundCall(); 1236 mPhoneSwitcher.sendEmptyMessage(EVENT_PRECISE_CALL_STATE_CHANGED); 1237 processAllMessages(); 1238 } 1239 notifyPhoneAsInHoldingCall(Phone phone)1240 private void notifyPhoneAsInHoldingCall(Phone phone) { 1241 doReturn(mHoldingCall).when(phone).getBackgroundCall(); 1242 mPhoneSwitcher.sendEmptyMessage(EVENT_PRECISE_CALL_STATE_CHANGED); 1243 processAllMessages(); 1244 } 1245 notifyPhoneAsInactive(Phone phone)1246 private void notifyPhoneAsInactive(Phone phone) { 1247 doReturn(mInactiveCall).when(phone).getForegroundCall(); 1248 mPhoneSwitcher.sendEmptyMessage(EVENT_PRECISE_CALL_STATE_CHANGED); 1249 processAllMessages(); 1250 } 1251 notifyDataEnabled(boolean dataEnabled)1252 private void notifyDataEnabled(boolean dataEnabled) { 1253 doReturn(dataEnabled).when(mDataEnabledSettings).isDataEnabled(anyInt()); 1254 doReturn(dataEnabled).when(mDataEnabledSettings2).isDataEnabled(anyInt()); 1255 mPhoneSwitcher.sendEmptyMessage(EVENT_DATA_ENABLED_CHANGED); 1256 processAllMessages(); 1257 } 1258 notifyImsRegistrationTechChange(Phone phone)1259 private void notifyImsRegistrationTechChange(Phone phone) { 1260 mPhoneSwitcher.sendEmptyMessage(EVENT_IMS_RADIO_TECH_CHANGED); 1261 processAllMessages(); 1262 } 1263 getEcbmRegistration(Phone phone)1264 private Message getEcbmRegistration(Phone phone) { 1265 ArgumentCaptor<Handler> handlerCaptor = ArgumentCaptor.forClass(Handler.class); 1266 ArgumentCaptor<Integer> intCaptor = ArgumentCaptor.forClass(Integer.class); 1267 1268 verify(phone).registerForEmergencyCallToggle(handlerCaptor.capture(), intCaptor.capture(), 1269 any()); 1270 assertNotNull(handlerCaptor.getValue()); 1271 assertNotNull(intCaptor.getValue()); 1272 Message message = Message.obtain(handlerCaptor.getValue(), intCaptor.getValue()); 1273 return message; 1274 } 1275 notifyEcbmStart(Phone phone, Message ecmMessage)1276 private void notifyEcbmStart(Phone phone, Message ecmMessage) { 1277 doReturn(mInactiveCall).when(phone).getForegroundCall(); 1278 doReturn(true).when(phone).isInEcm(); 1279 ecmMessage.sendToTarget(); 1280 processAllMessages(); 1281 } 1282 notifyEcbmEnd(Phone phone, Message ecmMessage)1283 private void notifyEcbmEnd(Phone phone, Message ecmMessage) { 1284 doReturn(false).when(phone).isInEcm(); 1285 ecmMessage.sendToTarget(); 1286 processAllMessages(); 1287 } 1288 sendPreferredDataSuccessResult(int phoneId)1289 private void sendPreferredDataSuccessResult(int phoneId) { 1290 // make sure the radio command is called and then send a success result 1291 processAllMessages(); 1292 ArgumentCaptor<Message> msgCaptor = ArgumentCaptor.forClass(Message.class); 1293 verify(mMockRadioConfig).setPreferredDataModem(eq(phoneId), msgCaptor.capture()); 1294 assertNotNull(msgCaptor.getValue()); 1295 // Send back successful result 1296 AsyncResult.forMessage(msgCaptor.getValue(), null, null); 1297 msgCaptor.getValue().sendToTarget(); 1298 processAllMessages(); 1299 } 1300 setMsimDefaultDataSubId(int defaultDataSub)1301 private void setMsimDefaultDataSubId(int defaultDataSub) throws Exception { 1302 for (int i = 0; i < mActiveModemCount; i++) { 1303 setSlotIndexToSubId(i, i + 1); 1304 } 1305 setDefaultDataSubId(defaultDataSub); 1306 NetworkRequest internetRequest = addInternetNetworkRequest(null, 50); 1307 for (int i = 0; i < mActiveModemCount; i++) { 1308 if (defaultDataSub == (i + 1)) { 1309 // sub id is always phoneId+1 for testing 1310 assertTrue(mPhoneSwitcher.shouldApplyNetworkRequest(internetRequest, i)); 1311 } else { 1312 assertFalse(mPhoneSwitcher.shouldApplyNetworkRequest(internetRequest, i)); 1313 } 1314 } 1315 } 1316 sendDefaultDataSubChanged()1317 private void sendDefaultDataSubChanged() { 1318 final Intent intent = new Intent(TelephonyIntents.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED); 1319 mContext.sendBroadcast(intent); 1320 processAllMessages(); 1321 } 1322 initialize()1323 private void initialize() throws Exception { 1324 setNumPhones(mActiveModemCount, mSupportedModemCount); 1325 1326 initializeSubControllerMock(); 1327 initializeCommandInterfacesMock(); 1328 initializeTelRegistryMock(); 1329 initializeConnManagerMock(); 1330 1331 mPhoneSwitcher = new PhoneSwitcher(mMaxDataAttachModemCount, mContext, Looper.myLooper()); 1332 processAllMessages(); 1333 1334 verify(mTelephonyRegistryManager).addOnSubscriptionsChangedListener(any(), any()); 1335 } 1336 1337 /** 1338 * Certain variables needs initialized depending on number of phones. 1339 */ setNumPhones(int activeModemCount, int supportedModemCount)1340 private void setNumPhones(int activeModemCount, int supportedModemCount) throws Exception { 1341 mDataAllowed = new boolean[supportedModemCount]; 1342 mSlotIndexToSubId = new int[supportedModemCount][]; 1343 doReturn(0).when(mPhone).getPhoneId(); 1344 doReturn(1).when(mPhone2).getPhoneId(); 1345 doReturn(true).when(mPhone2).isUserDataEnabled(); 1346 doReturn(mDataEnabledSettings2).when(mPhone2).getDataEnabledSettings(); 1347 for (int i = 0; i < supportedModemCount; i++) { 1348 mSlotIndexToSubId[i] = new int[1]; 1349 mSlotIndexToSubId[i][0] = SubscriptionManager.INVALID_SUBSCRIPTION_ID; 1350 } 1351 1352 doReturn(activeModemCount).when(mTelephonyManager).getPhoneCount(); 1353 doReturn(activeModemCount).when(mTelephonyManager).getActiveModemCount(); 1354 doReturn(supportedModemCount).when(mTelephonyManager).getSupportedModemCount(); 1355 1356 if (activeModemCount == 1) { 1357 mPhones = new Phone[]{mPhone}; 1358 } else if (activeModemCount == 2) { 1359 mPhones = new Phone[]{mPhone, mPhone2}; 1360 } 1361 1362 replaceInstance(PhoneFactory.class, "sPhones", null, mPhones); 1363 } 1364 initializeCommandInterfacesMock()1365 private void initializeCommandInterfacesMock() { 1366 // Tell PhoneSwitcher that radio is on. 1367 doAnswer(invocation -> { 1368 Handler handler = (Handler) invocation.getArguments()[0]; 1369 int message = (int) invocation.getArguments()[1]; 1370 Object obj = invocation.getArguments()[2]; 1371 handler.obtainMessage(message, obj).sendToTarget(); 1372 return null; 1373 }).when(mCommandsInterface0).registerForAvailable(any(), anyInt(), any()); 1374 1375 // Store values of dataAllowed in mDataAllowed[] for easier checking. 1376 doAnswer(invocation -> { 1377 mDataAllowed[0] = (boolean) invocation.getArguments()[0]; 1378 return null; 1379 }).when(mCommandsInterface0).setDataAllowed(anyBoolean(), any()); 1380 1381 if (mSupportedModemCount > 1) { 1382 doAnswer(invocation -> { 1383 mDataAllowed[1] = (boolean) invocation.getArguments()[0]; 1384 return null; 1385 }).when(mCommandsInterface1).setDataAllowed(anyBoolean(), any()); 1386 } 1387 } 1388 1389 /** 1390 * Store subChangedListener of PhoneSwitcher so that testing can notify 1391 * PhoneSwitcher of sub change. 1392 */ initializeTelRegistryMock()1393 private void initializeTelRegistryMock() throws Exception { 1394 doAnswer(invocation -> { 1395 SubscriptionManager.OnSubscriptionsChangedListener subChangedListener = 1396 (SubscriptionManager.OnSubscriptionsChangedListener) invocation.getArguments()[0]; 1397 mSubChangedListener = subChangedListener; 1398 mSubChangedListener.onSubscriptionsChanged(); 1399 return null; 1400 }).when(mTelephonyRegistryManager).addOnSubscriptionsChangedListener(any(), any()); 1401 } 1402 1403 /** 1404 * Capture mNetworkProviderMessenger so that testing can request or release 1405 * network requests on PhoneSwitcher. 1406 */ initializeConnManagerMock()1407 private void initializeConnManagerMock() { 1408 mConnectivityManager = (ConnectivityManager) 1409 mContext.getSystemService(Context.CONNECTIVITY_SERVICE); 1410 1411 doAnswer(invocation -> { 1412 mNetworkProviderMessenger = 1413 ((NetworkProvider) invocation.getArgument(0)).getMessenger(); 1414 return null; 1415 }).when(mConnectivityManager).registerNetworkProvider(any()); 1416 } 1417 1418 /** 1419 * Capture mNetworkProviderMessenger so that testing can request or release 1420 * network requests on PhoneSwitcher. 1421 */ initializeSubControllerMock()1422 private void initializeSubControllerMock() { 1423 doReturn(mDefaultDataSub).when(mSubscriptionController).getDefaultDataSubId(); 1424 doAnswer(invocation -> { 1425 int phoneId = (int) invocation.getArguments()[0]; 1426 if (phoneId == SubscriptionManager.INVALID_PHONE_INDEX) { 1427 return SubscriptionManager.INVALID_SUBSCRIPTION_ID; 1428 } else if (phoneId == SubscriptionManager.DEFAULT_PHONE_INDEX) { 1429 return mSlotIndexToSubId[0][0]; 1430 } else { 1431 return mSlotIndexToSubId[phoneId][0]; 1432 } 1433 }).when(mSubscriptionController).getSubIdUsingPhoneId(anyInt()); 1434 1435 doAnswer(invocation -> { 1436 int subId = (int) invocation.getArguments()[0]; 1437 1438 if (!SubscriptionManager.isUsableSubIdValue(subId)) return false; 1439 1440 for (int i = 0; i < mSlotIndexToSubId.length; i++) { 1441 if (mSlotIndexToSubId[i][0] == subId) return true; 1442 } 1443 return false; 1444 }).when(mSubscriptionController).isActiveSubId(anyInt()); 1445 } 1446 setDefaultDataSubId(int defaultDataSub)1447 private void setDefaultDataSubId(int defaultDataSub) { 1448 mDefaultDataSub = defaultDataSub; 1449 doReturn(mDefaultDataSub).when(mSubscriptionController).getDefaultDataSubId(); 1450 sendDefaultDataSubChanged(); 1451 } 1452 setSlotIndexToSubId(int slotId, int subId)1453 private void setSlotIndexToSubId(int slotId, int subId) { 1454 mSlotIndexToSubId[slotId][0] = subId; 1455 } 1456 1457 /** 1458 * Create an internet PDN network request and send it to PhoneSwitcher. 1459 */ addInternetNetworkRequest(Integer subId, int score)1460 private NetworkRequest addInternetNetworkRequest(Integer subId, int score) throws Exception { 1461 return addInternetNetworkRequest(subId, score, false); 1462 } 1463 addInternetNetworkRequest(Integer subId, int score, boolean restricted)1464 private NetworkRequest addInternetNetworkRequest(Integer subId, int score, boolean restricted) 1465 throws Exception { 1466 NetworkCapabilities netCap = (new NetworkCapabilities()) 1467 .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) 1468 .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR); 1469 if (restricted) { 1470 netCap.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED); 1471 } 1472 1473 if (subId != null) { 1474 netCap.setNetworkSpecifier(new TelephonyNetworkSpecifier.Builder() 1475 .setSubscriptionId(subId).build()); 1476 } 1477 NetworkRequest networkRequest = new NetworkRequest(netCap, ConnectivityManager.TYPE_NONE, 1478 0, NetworkRequest.Type.REQUEST); 1479 1480 Message message = Message.obtain(); 1481 message.what = android.net.NetworkProvider.CMD_REQUEST_NETWORK; 1482 message.arg1 = score; 1483 message.obj = networkRequest; 1484 mNetworkProviderMessenger.send(message); 1485 processAllMessages(); 1486 1487 return networkRequest; 1488 } 1489 1490 /** 1491 * Create a mms PDN network request and send it to PhoneSwitcher. 1492 */ addMmsNetworkRequest(Integer subId)1493 private NetworkRequest addMmsNetworkRequest(Integer subId) throws Exception { 1494 NetworkCapabilities netCap = (new NetworkCapabilities()) 1495 .addCapability(NetworkCapabilities.NET_CAPABILITY_MMS) 1496 .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED) 1497 .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR); 1498 if (subId != null) { 1499 netCap.setNetworkSpecifier(new TelephonyNetworkSpecifier.Builder() 1500 .setSubscriptionId(subId).build()); 1501 } 1502 NetworkRequest networkRequest = new NetworkRequest(netCap, ConnectivityManager.TYPE_NONE, 1503 1, NetworkRequest.Type.REQUEST); 1504 1505 Message message = Message.obtain(); 1506 message.what = android.net.NetworkProvider.CMD_REQUEST_NETWORK; 1507 message.arg1 = 50; // Score 1508 message.obj = networkRequest; 1509 mNetworkProviderMessenger.send(message); 1510 processAllMessages(); 1511 1512 return networkRequest; 1513 } 1514 1515 /** 1516 * Tell PhoneSwitcher to release a network request. 1517 */ releaseNetworkRequest(NetworkRequest networkRequest)1518 private void releaseNetworkRequest(NetworkRequest networkRequest) throws Exception { 1519 Message message = Message.obtain(); 1520 message.what = android.net.NetworkProvider.CMD_CANCEL_REQUEST; 1521 message.obj = networkRequest; 1522 mNetworkProviderMessenger.send(message); 1523 processAllMessages(); 1524 } 1525 } 1526