1 /* 2 * Copyright (C) 2019 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.TelephonyManager.ACTION_PRIMARY_SUBSCRIPTION_LIST_CHANGED; 20 import static android.telephony.TelephonyManager.EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE; 21 import static android.telephony.TelephonyManager.EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_DATA; 22 import static android.telephony.TelephonyManager.EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_DISMISS; 23 24 import static org.junit.Assert.assertEquals; 25 import static org.junit.Assert.assertFalse; 26 import static org.junit.Assert.assertNotNull; 27 import static org.junit.Assert.assertTrue; 28 import static org.mockito.ArgumentMatchers.any; 29 import static org.mockito.ArgumentMatchers.anyBoolean; 30 import static org.mockito.ArgumentMatchers.anyInt; 31 import static org.mockito.ArgumentMatchers.anyString; 32 import static org.mockito.ArgumentMatchers.eq; 33 import static org.mockito.ArgumentMatchers.nullable; 34 import static org.mockito.Mockito.clearInvocations; 35 import static org.mockito.Mockito.doAnswer; 36 import static org.mockito.Mockito.doReturn; 37 import static org.mockito.Mockito.mock; 38 import static org.mockito.Mockito.never; 39 import static org.mockito.Mockito.times; 40 import static org.mockito.Mockito.verify; 41 42 import android.content.Intent; 43 import android.content.res.Resources; 44 import android.os.AsyncResult; 45 import android.os.HandlerThread; 46 import android.os.ParcelUuid; 47 import android.os.PersistableBundle; 48 import android.provider.Settings; 49 import android.telephony.CarrierConfigManager; 50 import android.telephony.SubscriptionInfo; 51 import android.telephony.SubscriptionManager; 52 import android.telephony.TelephonyManager; 53 import android.testing.AndroidTestingRunner; 54 import android.testing.TestableLooper; 55 56 import androidx.test.InstrumentationRegistry; 57 import androidx.test.filters.SmallTest; 58 59 import com.android.internal.telephony.data.DataSettingsManager; 60 import com.android.internal.telephony.subscription.SubscriptionInfoInternal; 61 import com.android.internal.telephony.test.SimulatedCommands; 62 63 import org.junit.After; 64 import org.junit.Assert; 65 import org.junit.Before; 66 import org.junit.Test; 67 import org.junit.runner.RunWith; 68 import org.mockito.ArgumentCaptor; 69 70 import java.util.ArrayList; 71 import java.util.Arrays; 72 import java.util.List; 73 import java.util.UUID; 74 import java.util.concurrent.CountDownLatch; 75 import java.util.concurrent.TimeUnit; 76 import java.util.concurrent.atomic.AtomicBoolean; 77 78 @RunWith(AndroidTestingRunner.class) 79 @TestableLooper.RunWithLooper 80 public class MultiSimSettingControllerTest extends TelephonyTest { 81 private static final int DUAL_SIM = 2; 82 private static final String PHONE_PACKAGE = "com.android.internal.telephony"; 83 private MultiSimSettingController mMultiSimSettingControllerUT; 84 private Phone[] mPhones; 85 private ParcelUuid mGroupUuid1 = new ParcelUuid(UUID.randomUUID()); 86 private CarrierConfigManager.CarrierConfigChangeListener mCarrierConfigChangeListener; 87 88 // Mocked classes 89 private Phone mPhoneMock1; 90 private Phone mPhoneMock2; 91 private DataSettingsManager mDataSettingsManagerMock1; 92 private DataSettingsManager mDataSettingsManagerMock2; 93 private CommandsInterface mMockCi; 94 95 private final SubscriptionInfoInternal[] mSubInfo = new SubscriptionInfoInternal[10]; 96 initializeSubs()97 private void initializeSubs() { 98 mSubInfo[1] = new SubscriptionInfoInternal.Builder() 99 .setId(1) 100 .setIccId("subInfo1 IccId") 101 .setSimSlotIndex(0) 102 .setDisplayName("T-mobile") 103 .setCarrierName("T-mobile") 104 .setDisplayNameSource(SubscriptionManager.NAME_SOURCE_CARRIER) 105 .setIconTint(255) 106 .setNumber("12345") 107 .setMcc("310") 108 .setMnc("260") 109 .setCountryIso("us") 110 .build(); 111 112 mSubInfo[2] = new SubscriptionInfoInternal.Builder(mSubInfo[1]) 113 .setId(2) 114 .setIccId("subInfo2 IccId") 115 .setSimSlotIndex(1) 116 .setGroupUuid(mGroupUuid1.toString()) 117 .build(); 118 119 mSubInfo[3] = new SubscriptionInfoInternal.Builder(mSubInfo[1]) 120 .setId(3) 121 .setIccId("subInfo3 IccId") 122 .setSimSlotIndex(-1) 123 .setGroupUuid(mGroupUuid1.toString()) 124 .build(); 125 126 mSubInfo[4] = new SubscriptionInfoInternal.Builder( 127 mSubInfo[1]) 128 .setId(4) 129 .setIccId("subInfo4 IccId") 130 .setSimSlotIndex(-1) 131 .setGroupUuid(mGroupUuid1.toString()) 132 .build(); 133 } 134 setSimSlotIndex(int subId, int simSlotIndex)135 private void setSimSlotIndex(int subId, int simSlotIndex) { 136 mSubInfo[subId] = new SubscriptionInfoInternal.Builder(mSubInfo[subId]) 137 .setSimSlotIndex(simSlotIndex).build(); 138 } 139 sendCarrierConfigChanged(int phoneId, int subId)140 private void sendCarrierConfigChanged(int phoneId, int subId) { 141 mCarrierConfigChangeListener.onCarrierConfigChanged(phoneId, subId, 142 TelephonyManager.UNKNOWN_CARRIER_ID, TelephonyManager.UNKNOWN_CARRIER_ID); 143 } 144 145 @Before setUp()146 public void setUp() throws Exception { 147 super.setUp(getClass().getSimpleName()); 148 initializeSubs(); 149 mPhoneMock1 = mock(Phone.class); 150 mPhoneMock2 = mock(Phone.class); 151 mDataSettingsManagerMock1 = mock(DataSettingsManager.class); 152 mDataSettingsManagerMock2 = mock(DataSettingsManager.class); 153 mMockCi = mock(CommandsInterface.class); 154 155 doReturn(mSubscriptionManagerService).when(mIBinder).queryLocalInterface(anyString()); 156 doReturn(mPhone).when(mPhone).getImsPhone(); 157 mServiceManagerMockedServices.put("isub", mIBinder); 158 159 doReturn(mSubscriptionManagerService).when(mIBinder) 160 .queryLocalInterface(anyString()); 161 162 // Default configuration: 163 // DSDS device. 164 // Sub 1 is the default sub. 165 // Sub 1 is in slot 0; sub 2 is in slot 1. 166 doReturn(DUAL_SIM).when(mTelephonyManager).getPhoneCount(); 167 doReturn(DUAL_SIM).when(mTelephonyManager).getActiveModemCount(); 168 doReturn(1).when(mSubscriptionManagerService).getDefaultDataSubId(); 169 doReturn(1).when(mSubscriptionManagerService).getDefaultVoiceSubId(); 170 doReturn(1).when(mSubscriptionManagerService).getDefaultSmsSubId(); 171 mPhoneMock1.mCi = mSimulatedCommands; 172 mPhoneMock2.mCi = mSimulatedCommands; 173 174 mPhones = new Phone[] {mPhoneMock1, mPhoneMock2}; 175 doReturn(mDataSettingsManagerMock1).when(mPhoneMock1).getDataSettingsManager(); 176 doReturn(mDataSettingsManagerMock2).when(mPhoneMock2).getDataSettingsManager(); 177 178 doAnswer(invocation -> { 179 final int subId = (int) invocation.getArguments()[0]; 180 if (subId < 0 || subId >= mSubInfo.length) return null; 181 return mSubInfo[subId].toSubscriptionInfo(); 182 }).when(mSubscriptionManagerService).getSubscriptionInfo(anyInt()); 183 184 doAnswer(invocation -> { 185 final int subId = (int) invocation.getArguments()[0]; 186 if (subId < 0 || subId >= mSubInfo.length) return null; 187 return mSubInfo[subId]; 188 }).when(mSubscriptionManagerService).getSubscriptionInfoInternal(anyInt()); 189 190 doAnswer(invocation -> { 191 List<SubscriptionInfo> subscriptionInfoList = new ArrayList<>(); 192 for (int i = 1; i < mSubInfo.length; i++) { 193 if (mSubInfo[i] != null && mSubInfo[i].isActive()) { 194 subscriptionInfoList.add(mSubInfo[i].toSubscriptionInfo()); 195 } 196 } 197 return subscriptionInfoList; 198 }).when(mSubscriptionManagerService).getActiveSubscriptionInfoList( 199 anyString(), nullable(String.class), anyBoolean()); 200 201 doAnswer(invocation -> { 202 final boolean visibleOnly = (boolean) invocation.getArguments()[0]; 203 List<Integer> subIdList = new ArrayList<>(); 204 for (int i = 1; i < mSubInfo.length; i++) { 205 if (mSubInfo[i] != null && mSubInfo[i].isActive() 206 && (!visibleOnly || mSubInfo[i].isVisible())) { 207 subIdList.add(i); 208 } 209 } 210 return subIdList.stream().mapToInt(i -> i).toArray(); 211 }).when(mSubscriptionManagerService).getActiveSubIdList(anyBoolean()); 212 213 doAnswer(invocation -> { 214 final String uuid = (String) invocation.getArguments()[1]; 215 List<SubscriptionInfo> subscriptionInfoList = new ArrayList<>(); 216 for (int i = 1; i < mSubInfo.length; i++) { 217 if (mSubInfo[i] != null && mSubInfo[i].getGroupUuid().equals(uuid)) { 218 subscriptionInfoList.add(mSubInfo[i].toSubscriptionInfo()); 219 } 220 } 221 return subscriptionInfoList; 222 }).when(mSubscriptionManagerService).getSubscriptionsInGroup( 223 any(), anyString(), nullable(String.class)); 224 225 doAnswer(invocation -> { 226 final int subId = (int) invocation.getArguments()[0]; 227 if (!SubscriptionManager.isValidSubscriptionId(subId)) { 228 return SubscriptionManager.INVALID_PHONE_INDEX; 229 } 230 if (mSubInfo[subId] == null) return SubscriptionManager.INVALID_PHONE_INDEX; 231 return mSubInfo[subId].getSimSlotIndex(); 232 }).when(mSubscriptionManagerService).getPhoneId(anyInt()); 233 234 doAnswer(invocation -> { 235 for (int i = 1; i < mSubInfo.length; i++) { 236 if (mSubInfo[i] != null && mSubInfo[i].getSimSlotIndex() == 0) return i; 237 } 238 return SubscriptionManager.INVALID_SUBSCRIPTION_ID; 239 }).when(mPhoneMock1).getSubId(); 240 241 doAnswer(invocation -> { 242 for (int i = 1; i < mSubInfo.length; i++) { 243 if (mSubInfo[i] != null && mSubInfo[i].getSimSlotIndex() == 1) return i; 244 } 245 return SubscriptionManager.INVALID_SUBSCRIPTION_ID; 246 }).when(mPhoneMock2).getSubId(); 247 248 PersistableBundle bundle = new PersistableBundle(); 249 bundle.putBoolean(CarrierConfigManager.KEY_CARRIER_CONFIG_APPLIED_BOOL, true); 250 doReturn(bundle).when(mCarrierConfigManager).getConfigForSubId(anyInt()); 251 252 doReturn(true).when(mFeatureFlags).resetPrimarySimDefaultValues(); 253 254 replaceInstance(PhoneFactory.class, "sPhones", null, mPhones); 255 // Capture listener to emulate the carrier config change notification used later 256 ArgumentCaptor<CarrierConfigManager.CarrierConfigChangeListener> listenerArgumentCaptor = 257 ArgumentCaptor.forClass(CarrierConfigManager.CarrierConfigChangeListener.class); 258 mMultiSimSettingControllerUT = new MultiSimSettingController(mContext, mFeatureFlags); 259 processAllMessages(); 260 verify(mCarrierConfigManager).registerCarrierConfigChangeListener(any(), 261 listenerArgumentCaptor.capture()); 262 mCarrierConfigChangeListener = listenerArgumentCaptor.getAllValues().get(0); 263 assertNotNull(mCarrierConfigChangeListener); 264 } 265 266 @After tearDown()267 public void tearDown() throws Exception { 268 mPhones = null; 269 mGroupUuid1 = null; 270 mMultiSimSettingControllerUT = null; 271 super.tearDown(); 272 } 273 markSubscriptionInactive(int subId)274 private void markSubscriptionInactive(int subId) { 275 setSimSlotIndex(subId, SubscriptionManager.INVALID_SIM_SLOT_INDEX); 276 } 277 278 @Test 279 @SmallTest testSubInfoChangeBeforeAllSubReady()280 public void testSubInfoChangeBeforeAllSubReady() throws Exception { 281 doReturn(SubscriptionManager.INVALID_SUBSCRIPTION_ID).when(mSubscriptionManagerService) 282 .getDefaultDataSubId(); 283 doReturn(SubscriptionManager.INVALID_SUBSCRIPTION_ID).when(mSubscriptionManagerService) 284 .getDefaultVoiceSubId(); 285 doReturn(SubscriptionManager.INVALID_SUBSCRIPTION_ID).when(mSubscriptionManagerService) 286 .getDefaultSmsSubId(); 287 288 // Mark sub 2 as inactive. 289 markSubscriptionInactive(2); 290 291 // Mark subscription ready as false. The below sub info change should be ignored. 292 mMultiSimSettingControllerUT.notifySubscriptionInfoChanged(); 293 processAllMessages(); 294 verify(mSubscriptionManagerService, never()).setDefaultDataSubId(anyInt()); 295 verify(mSubscriptionManagerService, never()).setDefaultVoiceSubId(anyInt()); 296 verify(mSubscriptionManagerService, never()).setDefaultSmsSubId(anyInt()); 297 298 mMultiSimSettingControllerUT.notifyAllSubscriptionLoaded(); 299 sendCarrierConfigChanged(0, 1); 300 processAllMessages(); 301 302 // Sub 1 should be default sub silently. 303 verify(mSubscriptionManagerService).setDefaultDataSubId(1); 304 verify(mSubscriptionManagerService).setDefaultVoiceSubId(1); 305 verify(mSubscriptionManagerService).setDefaultSmsSubId(1); 306 verifyDismissIntentSent(); 307 } 308 309 @Test testSubInfoChangeAfterRadioUnavailable()310 public void testSubInfoChangeAfterRadioUnavailable() throws Exception { 311 int phone1SubId = 1; 312 int phone2SubId = 2; 313 // Mock DSDS, mock Phone 2 314 SimulatedCommands simulatedCommands2 = mock(SimulatedCommands.class); 315 mPhone2.mCi = simulatedCommands2; 316 doReturn(mDataSettingsManagerMock2).when(mPhone2).getDataSettingsManager(); 317 mPhones = new Phone[]{mPhone, mPhone2}; 318 replaceInstance(PhoneFactory.class, "sPhones", null, mPhones); 319 // Load carrier config for all subs 320 mMultiSimSettingControllerUT.notifyAllSubscriptionLoaded(); 321 sendCarrierConfigChanged(0, phone1SubId); 322 sendCarrierConfigChanged(1, phone2SubId); 323 processAllMessages(); 324 325 // Ensure all subscription loaded only updates state once 326 clearInvocations(mSubscriptionManagerService); 327 mMultiSimSettingControllerUT.notifyAllSubscriptionLoaded(); 328 processAllMessages(); 329 verify(mSubscriptionManagerService, never()).setDefaultDataSubId(anyInt()); 330 verify(mSubscriptionManagerService, never()).setDefaultVoiceSubId(anyInt()); 331 verify(mSubscriptionManagerService, never()).setDefaultSmsSubId(anyInt()); 332 333 // DSDS -> single active modem, radio available on phone 0 but unavailable on phone 1 334 doReturn(TelephonyManager.RADIO_POWER_UNAVAILABLE).when(simulatedCommands2).getRadioState(); 335 markSubscriptionInactive(phone2SubId); 336 AsyncResult result = new AsyncResult(null, 1/*activeModemCount*/, null); 337 clearInvocations(mSubscriptionManagerService); 338 mMultiSimSettingControllerUT.obtainMessage( 339 MultiSimSettingController.EVENT_MULTI_SIM_CONFIG_CHANGED, result).sendToTarget(); 340 mMultiSimSettingControllerUT.notifySubscriptionInfoChanged(); 341 processAllMessages(); 342 343 // Should still set defaults to the only remaining sub 344 verify(mSubscriptionManagerService).setDefaultDataSubId(phone1SubId); 345 verify(mSubscriptionManagerService).setDefaultVoiceSubId(phone1SubId); 346 verify(mSubscriptionManagerService).setDefaultSmsSubId(phone1SubId); 347 348 // Notify radio unavailable on all subs. 349 replaceInstance(BaseCommands.class, "mState", mSimulatedCommands, 350 TelephonyManager.RADIO_POWER_UNAVAILABLE); 351 mMultiSimSettingControllerUT.obtainMessage( 352 MultiSimSettingController.EVENT_RADIO_STATE_CHANGED).sendToTarget(); 353 354 // Mark all subs as inactive. 355 markSubscriptionInactive(1); 356 clearInvocations(mSubscriptionManagerService); 357 358 // The below sub info change should be ignored. 359 mMultiSimSettingControllerUT.notifySubscriptionInfoChanged(); 360 processAllMessages(); 361 verify(mSubscriptionManagerService, never()).setDefaultDataSubId(anyInt()); 362 verify(mSubscriptionManagerService, never()).setDefaultVoiceSubId(anyInt()); 363 verify(mSubscriptionManagerService, never()).setDefaultSmsSubId(anyInt()); 364 365 // Send all sub ready notification 366 mMultiSimSettingControllerUT.notifyAllSubscriptionLoaded(); 367 processAllMessages(); 368 369 // Everything should be set to invalid since nothing is active. 370 verify(mSubscriptionManagerService).setDefaultDataSubId( 371 SubscriptionManager.INVALID_SUBSCRIPTION_ID); 372 verify(mSubscriptionManagerService) 373 .setDefaultVoiceSubId(SubscriptionManager.INVALID_SUBSCRIPTION_ID); 374 verify(mSubscriptionManagerService).setDefaultSmsSubId( 375 SubscriptionManager.INVALID_SUBSCRIPTION_ID); 376 } 377 378 @Test 379 @SmallTest testSingleActiveDsds()380 public void testSingleActiveDsds() throws Exception { 381 doReturn(SubscriptionManager.INVALID_SUBSCRIPTION_ID).when(mSubscriptionManagerService) 382 .getDefaultDataSubId(); 383 doReturn(SubscriptionManager.INVALID_SUBSCRIPTION_ID).when(mSubscriptionManagerService) 384 .getDefaultVoiceSubId(); 385 doReturn(SubscriptionManager.INVALID_SUBSCRIPTION_ID).when(mSubscriptionManagerService) 386 .getDefaultSmsSubId(); 387 388 // Mark sub 2 as inactive. 389 markSubscriptionInactive(2); 390 391 mMultiSimSettingControllerUT.notifyAllSubscriptionLoaded(); 392 sendCarrierConfigChanged(0, 1); 393 processAllMessages(); 394 verifyDismissIntentSent(); 395 clearInvocations(mContext); 396 397 // Sub 1 should be default sub silently. 398 // Sub 1 switches to sub 2 in the same slot. 399 markSubscriptionInactive(1); 400 setSimSlotIndex(2, 0); 401 402 mMultiSimSettingControllerUT.notifySubscriptionInfoChanged(); 403 sendCarrierConfigChanged(0, 2); 404 processAllMessages(); 405 406 // Sub 1 should be default sub silently. 407 verify(mSubscriptionManagerService).setDefaultDataSubId(2); 408 verify(mSubscriptionManagerService).setDefaultVoiceSubId(2); 409 verify(mSubscriptionManagerService).setDefaultSmsSubId(2); 410 verifyDismissIntentSent(); 411 } 412 413 @Test 414 @SmallTest testActivatingSecondSub()415 public void testActivatingSecondSub() throws Exception { 416 // Mark sub 2 as inactive. 417 markSubscriptionInactive(2); 418 419 mMultiSimSettingControllerUT.notifyAllSubscriptionLoaded(); 420 sendCarrierConfigChanged(0, 1); 421 processAllMessages(); 422 423 // Sub 1 should be default sub silently. 424 verify(mSubscriptionManagerService).setDefaultDataSubId(1); 425 verify(mSubscriptionManagerService).setDefaultVoiceSubId(1); 426 verify(mSubscriptionManagerService).setDefaultSmsSubId(1); 427 verifyDismissIntentSent(); 428 429 // Mark sub 2 as active in phone[1]. 430 setSimSlotIndex(2, 1); 431 clearInvocations(mSubscriptionManagerService); 432 clearInvocations(mContext); 433 mSubInfo[2] = new SubscriptionInfoInternal.Builder().setId(2).setSimSlotIndex(1).build(); 434 435 mMultiSimSettingControllerUT.notifySubscriptionInfoChanged(); 436 sendCarrierConfigChanged(1, 2); 437 processAllMessages(); 438 439 // Intent should be broadcast to ask default data selection. 440 Intent intent = captureBroadcastIntent(); 441 assertEquals(ACTION_PRIMARY_SUBSCRIPTION_LIST_CHANGED, intent.getAction()); 442 assertEquals(EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_DATA, 443 intent.getIntExtra(EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE, -1)); 444 445 clearInvocations(mContext); 446 // Switch from sub 2 to sub 3 in phone[1]. This should again trigger default data selection 447 // dialog. 448 markSubscriptionInactive(2); 449 setSimSlotIndex(3, 1); 450 451 mMultiSimSettingControllerUT.notifySubscriptionInfoChanged(); 452 sendCarrierConfigChanged(1, 3); 453 processAllMessages(); 454 455 // Intent should be broadcast to ask default data selection. 456 intent = captureBroadcastIntent(); 457 assertEquals(ACTION_PRIMARY_SUBSCRIPTION_LIST_CHANGED, intent.getAction()); 458 assertEquals(EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_DATA, 459 intent.getIntExtra(EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE, -1)); 460 } 461 462 @Test 463 @SmallTest testSimpleDsds()464 public void testSimpleDsds() throws Exception { 465 doReturn(true).when(mPhoneMock1).isUserDataEnabled(); 466 doReturn(true).when(mPhoneMock2).isUserDataEnabled(); 467 // After initialization, sub 2 should have mobile data off. 468 mMultiSimSettingControllerUT.notifyAllSubscriptionLoaded(); 469 sendCarrierConfigChanged(0, 1); 470 sendCarrierConfigChanged(1, 2); 471 processAllMessages(); 472 verify(mDataSettingsManagerMock2).setDataEnabled( 473 TelephonyManager.DATA_ENABLED_REASON_USER, false, PHONE_PACKAGE); 474 475 // Enable on non-default sub should trigger setDefaultDataSubId. 476 mMultiSimSettingControllerUT.notifyUserDataEnabled(2, true); 477 processAllMessages(); 478 verify(mSubscriptionManagerService).setDefaultDataSubId(2); 479 480 // Changing default data to sub 2 should trigger disabling data on sub 1. 481 doReturn(2).when(mSubscriptionManagerService).getDefaultDataSubId(); 482 mMultiSimSettingControllerUT.notifyDefaultDataSubChanged(); 483 processAllMessages(); 484 verify(mDataSettingsManagerMock1).setDataEnabled( 485 TelephonyManager.DATA_ENABLED_REASON_USER, false, PHONE_PACKAGE); 486 487 doReturn(1).when(mSubscriptionManagerService).getDefaultDataSubId(); 488 doReturn(1).when(mSubscriptionManagerService).getDefaultSmsSubId(); 489 doReturn(2).when(mSubscriptionManagerService).getDefaultVoiceSubId(); 490 491 // Taking out SIM 1. 492 clearInvocations(mSubscriptionManagerService); 493 markSubscriptionInactive(1); 494 mMultiSimSettingControllerUT.notifySubscriptionInfoChanged(); 495 processAllMessages(); 496 sendCarrierConfigChanged(1, SubscriptionManager.INVALID_SUBSCRIPTION_ID); 497 processAllMessages(); 498 499 verify(mSubscriptionManagerService).setDefaultDataSubId(2); 500 verify(mSubscriptionManagerService).setDefaultSmsSubId(2); 501 verify(mSubscriptionManagerService).setDefaultVoiceSubId(2); 502 } 503 504 @Test 505 @SmallTest testSimpleDsdsFirstBoot()506 public void testSimpleDsdsFirstBoot() throws Exception { 507 // at first boot default is not set 508 doReturn(-1).when(mSubscriptionManagerService).getDefaultDataSubId(); 509 510 doReturn(true).when(mPhoneMock1).isUserDataEnabled(); 511 doReturn(true).when(mPhoneMock2).isUserDataEnabled(); 512 // After initialization, sub 2 should have mobile data off. 513 mMultiSimSettingControllerUT.notifyAllSubscriptionLoaded(); 514 sendCarrierConfigChanged(0, 1); 515 sendCarrierConfigChanged(1, 2); 516 processAllMessages(); 517 verify(mDataSettingsManagerMock1).setDataEnabled( 518 TelephonyManager.DATA_ENABLED_REASON_USER, false, PHONE_PACKAGE); 519 verify(mDataSettingsManagerMock2).setDataEnabled( 520 TelephonyManager.DATA_ENABLED_REASON_USER, false, PHONE_PACKAGE); 521 522 // as a result of the above calls, update new values to be returned 523 doReturn(false).when(mPhoneMock1).isUserDataEnabled(); 524 doReturn(false).when(mPhoneMock2).isUserDataEnabled(); 525 526 Intent intent = captureBroadcastIntent(); 527 assertEquals(ACTION_PRIMARY_SUBSCRIPTION_LIST_CHANGED, intent.getAction()); 528 assertEquals(EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_DATA, 529 intent.getIntExtra(EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE, -1)); 530 531 // Setting default data should not trigger any more setDataEnabled(). 532 doReturn(2).when(mSubscriptionManagerService).getDefaultDataSubId(); 533 doReturn(2).when(mSubscriptionManagerService).getDefaultDataSubId(); 534 mMultiSimSettingControllerUT.notifyDefaultDataSubChanged(); 535 processAllMessages(); 536 verify(mDataSettingsManagerMock1, times(1)) 537 .setDataEnabled(anyInt(), anyBoolean(), anyString()); 538 verify(mDataSettingsManagerMock2, times(1)) 539 .setDataEnabled(anyInt(), anyBoolean(), anyString()); 540 } 541 542 @Test 543 @SmallTest testSimpleDsdsInSuW()544 public void testSimpleDsdsInSuW() throws Exception { 545 // at first boot default is not set 546 doReturn(-1).when(mSubscriptionManagerService).getDefaultDataSubId(); 547 548 doReturn(true).when(mPhoneMock1).isUserDataEnabled(); 549 doReturn(true).when(mPhoneMock2).isUserDataEnabled(); 550 // setting DEVICE_PROVISIONED as 0 to indicate SuW is running. 551 Settings.Global.putInt(mContext.getContentResolver(), 552 Settings.Global.DEVICE_PROVISIONED, 0); 553 // After initialization, sub 2 should have mobile data off. 554 mMultiSimSettingControllerUT.notifyAllSubscriptionLoaded(); 555 sendCarrierConfigChanged(0, 1); 556 sendCarrierConfigChanged(1, 2); 557 processAllMessages(); 558 verify(mDataSettingsManagerMock1).setDataEnabled( 559 TelephonyManager.DATA_ENABLED_REASON_USER, false, PHONE_PACKAGE); 560 verify(mDataSettingsManagerMock2).setDataEnabled( 561 TelephonyManager.DATA_ENABLED_REASON_USER, false, PHONE_PACKAGE); 562 563 // as a result of the above calls, update new values to be returned 564 doReturn(false).when(mPhoneMock1).isUserDataEnabled(); 565 doReturn(false).when(mPhoneMock2).isUserDataEnabled(); 566 567 // No user selection needed, no intent should be sent. 568 verify(mContext, never()).sendBroadcast(any()); 569 } 570 571 @Test 572 @SmallTest testDsdsGrouping()573 public void testDsdsGrouping() throws Exception { 574 doReturn(2).when(mSubscriptionManagerService).getDefaultDataSubId(); 575 doReturn(false).when(mPhoneMock1).isUserDataEnabled(); 576 doReturn(true).when(mPhoneMock2).isUserDataEnabled(); 577 GlobalSettingsHelper.setBoolean(mContext, Settings.Global.MOBILE_DATA, 2, true); 578 GlobalSettingsHelper.setBoolean(mContext, Settings.Global.DATA_ROAMING, 2, false); 579 mMultiSimSettingControllerUT.notifyAllSubscriptionLoaded(); 580 sendCarrierConfigChanged(0, 1); 581 sendCarrierConfigChanged(1, 2); 582 processAllMessages(); 583 584 // Create subscription grouping. 585 doReturn(Arrays.asList(mSubInfo[2].toSubscriptionInfo(), mSubInfo[3].toSubscriptionInfo(), 586 mSubInfo[4].toSubscriptionInfo())).when(mSubscriptionManagerService) 587 .getSubscriptionsInGroup(any(), anyString(), nullable(String.class)); 588 mMultiSimSettingControllerUT.notifySubscriptionGroupChanged(mGroupUuid1); 589 processAllMessages(); 590 // This should result in setting sync. 591 assertTrue(GlobalSettingsHelper.getBoolean( 592 mContext, Settings.Global.MOBILE_DATA, 3, false)); 593 assertTrue(GlobalSettingsHelper.getBoolean( 594 mContext, Settings.Global.MOBILE_DATA, 4, false)); 595 assertFalse(GlobalSettingsHelper.getBoolean( 596 mContext, Settings.Global.DATA_ROAMING, 3, true)); 597 assertFalse(GlobalSettingsHelper.getBoolean( 598 mContext, Settings.Global.DATA_ROAMING, 4, true)); 599 verify(mSubscriptionManagerService).setDataRoaming(/*enable*/0, /*subId*/2); 600 // No user selection needed, no intent should be sent. 601 verify(mContext, never()).sendBroadcast(any()); 602 603 // Making sub 1 default data sub should result in disabling data on sub 2, 3, 4. 604 doReturn(1).when(mSubscriptionManagerService).getDefaultDataSubId(); 605 mMultiSimSettingControllerUT.notifyDefaultDataSubChanged(); 606 processAllMessages(); 607 verify(mDataSettingsManagerMock2).setDataEnabled( 608 TelephonyManager.DATA_ENABLED_REASON_USER, false, PHONE_PACKAGE); 609 mMultiSimSettingControllerUT.notifyUserDataEnabled(2, false); 610 processAllMessages(); 611 assertFalse(GlobalSettingsHelper.getBoolean( 612 mContext, Settings.Global.MOBILE_DATA, 3, true)); 613 assertFalse(GlobalSettingsHelper.getBoolean( 614 mContext, Settings.Global.MOBILE_DATA, 4, true)); 615 // No user selection needed, no intent should be sent. 616 verify(mContext, never()).sendBroadcast(any()); 617 618 // Switch within group (from sub 2 to sub 3). 619 // Default data and default sms should become subscription 3. 620 clearInvocations(mSubscriptionManagerService); 621 doReturn(2).when(mSubscriptionManagerService).getDefaultDataSubId(); 622 doReturn(2).when(mSubscriptionManagerService).getDefaultSmsSubId(); 623 doReturn(1).when(mSubscriptionManagerService).getDefaultVoiceSubId(); 624 setSimSlotIndex(3, 1); 625 markSubscriptionInactive(2); 626 627 mMultiSimSettingControllerUT.notifySubscriptionInfoChanged(); 628 sendCarrierConfigChanged(1, 3); 629 processAllMessages(); 630 631 verify(mSubscriptionManagerService).setDefaultDataSubId(3); 632 verify(mSubscriptionManagerService).setDefaultSmsSubId(3); 633 verify(mSubscriptionManagerService, never()).setDefaultVoiceSubId(anyInt()); 634 // No user selection needed, no intent should be sent. 635 verify(mContext, never()).sendBroadcast(any()); 636 } 637 638 @Test 639 @SmallTest testCbrs()640 public void testCbrs() throws Exception { 641 mSubInfo[1] = new SubscriptionInfoInternal.Builder(mSubInfo[1]).setOpportunistic(1).build(); 642 643 doReturn(true).when(mPhoneMock1).isUserDataEnabled(); 644 doReturn(true).when(mPhoneMock2).isUserDataEnabled(); 645 GlobalSettingsHelper.setBoolean(mContext, Settings.Global.DATA_ROAMING, 2, false); 646 647 // Notify subscriptions ready. Sub 2 should become the default. But shouldn't turn off 648 // data of oppt sub 1. 649 mMultiSimSettingControllerUT.notifyAllSubscriptionLoaded(); 650 sendCarrierConfigChanged(0, 1); 651 sendCarrierConfigChanged(1, 2); 652 processAllMessages(); 653 verify(mSubscriptionManagerService).setDefaultDataSubId(2); 654 verify(mDataSettingsManagerMock1, never()).setDataEnabled( 655 anyInt(), anyBoolean(), anyString()); 656 verifyDismissIntentSent(); 657 658 clearInvocations(mSubscriptionManagerService); 659 clearInvocations(mDataSettingsManagerMock1); 660 clearInvocations(mDataSettingsManagerMock2); 661 doReturn(2).when(mSubscriptionManagerService).getDefaultDataSubId(); 662 // Toggle data on sub 1 or sub 2. Nothing should happen as they are independent. 663 mMultiSimSettingControllerUT.notifyUserDataEnabled(1, false); 664 mMultiSimSettingControllerUT.notifyUserDataEnabled(1, true); 665 processAllMessages(); 666 verify(mSubscriptionManagerService, never()).setDefaultDataSubId(anyInt()); 667 mMultiSimSettingControllerUT.notifyUserDataEnabled(2, false); 668 mMultiSimSettingControllerUT.notifyUserDataEnabled(2, true); 669 processAllMessages(); 670 verify(mSubscriptionManagerService, never()).setDefaultDataSubId(anyInt()); 671 verify(mDataSettingsManagerMock1, never()).setDataEnabled( 672 eq(TelephonyManager.DATA_ENABLED_REASON_USER), anyBoolean(), anyString()); 673 verify(mDataSettingsManagerMock2, never()).setDataEnabled( 674 eq(TelephonyManager.DATA_ENABLED_REASON_USER), eq(false), anyString()); 675 } 676 verifyDismissIntentSent()677 private void verifyDismissIntentSent() { 678 Intent intentSent = captureBroadcastIntent(); 679 assertEquals(EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_DISMISS, 680 intentSent.getIntExtra(EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE, -1)); 681 assertEquals(ACTION_PRIMARY_SUBSCRIPTION_LIST_CHANGED, intentSent.getAction()); 682 } 683 684 @Test 685 @SmallTest testGroupedCbrs()686 public void testGroupedCbrs() throws Exception { 687 // Mark sub 1 as opportunistic. 688 mSubInfo[1] = new SubscriptionInfoInternal.Builder(mSubInfo[1]) 689 .setOpportunistic(1).setGroupUuid(mGroupUuid1.toString()).build(); 690 // Make opportunistic sub 1 and sub 2 data enabled. 691 doReturn(true).when(mPhoneMock1).isUserDataEnabled(); 692 doReturn(true).when(mPhoneMock2).isUserDataEnabled(); 693 GlobalSettingsHelper.setBoolean(mContext, Settings.Global.DATA_ROAMING, 2, false); 694 695 // Notify subscriptions ready. Sub 2 should become the default, as sub 1 is opportunistic. 696 mMultiSimSettingControllerUT.notifyAllSubscriptionLoaded(); 697 sendCarrierConfigChanged(0, 1); 698 sendCarrierConfigChanged(1, 2); 699 processAllMessages(); 700 verify(mSubscriptionManagerService).setDefaultDataSubId(2); 701 702 // Mark sub 2 as data off. 703 doReturn(false).when(mPhoneMock2).isUserDataEnabled(); 704 GlobalSettingsHelper.setBoolean(mContext, Settings.Global.MOBILE_DATA, 2, false); 705 // Group sub 1 with sub 2. 706 doReturn(Arrays.asList(mSubInfo[1].toSubscriptionInfo(), mSubInfo[2].toSubscriptionInfo())) 707 .when(mSubscriptionManagerService) 708 .getSubscriptionsInGroup(any(), anyString(), nullable(String.class)); 709 mMultiSimSettingControllerUT.notifySubscriptionGroupChanged(mGroupUuid1); 710 processAllMessages(); 711 // This should result in setting sync. 712 verify(mDataSettingsManagerMock1).setDataEnabled(TelephonyManager.DATA_ENABLED_REASON_USER, 713 false, PHONE_PACKAGE); 714 assertFalse(GlobalSettingsHelper.getBoolean( 715 mContext, Settings.Global.DATA_ROAMING, 1, true)); 716 717 doReturn(false).when(mPhoneMock1).isUserDataEnabled(); 718 doReturn(false).when(mPhoneMock2).isUserDataEnabled(); 719 // Turning data on on sub 2. Sub 1 should also be turned on. 720 mMultiSimSettingControllerUT.notifyUserDataEnabled(2, true); 721 processAllMessages(); 722 verify(mDataSettingsManagerMock1).setDataEnabled(TelephonyManager.DATA_ENABLED_REASON_USER, 723 true, PHONE_PACKAGE); 724 verifyDismissIntentSent(); 725 } 726 727 @Test 728 @SmallTest testGroupedPrimaryRemoved()729 public void testGroupedPrimaryRemoved() throws Exception { 730 // Create subscription grouping of subs 1 and 2. 731 mSubInfo[1] = new SubscriptionInfoInternal.Builder(mSubInfo[1]) 732 .setGroupUuid(mGroupUuid1.toString()).build(); 733 734 mMultiSimSettingControllerUT.notifyAllSubscriptionLoaded(); 735 mMultiSimSettingControllerUT.notifySubscriptionGroupChanged(mGroupUuid1); 736 sendCarrierConfigChanged(0, 1); 737 sendCarrierConfigChanged(1, 2); 738 processAllMessages(); 739 740 // Defaults not touched, sub 1 is already default. 741 verify(mSubscriptionManagerService, never()).setDefaultDataSubId(anyInt()); 742 743 // Take out SIM 1. 744 clearInvocations(mSubscriptionManagerService); 745 markSubscriptionInactive(1); 746 mMultiSimSettingControllerUT.notifySubscriptionInfoChanged(); 747 sendCarrierConfigChanged(0, SubscriptionManager.INVALID_SUBSCRIPTION_ID); 748 processAllMessages(); 749 750 // Sub 2 should be made the default sub silently. 751 verify(mSubscriptionManagerService).setDefaultDataSubId(2); 752 verify(mSubscriptionManagerService).setDefaultVoiceSubId(2); 753 verify(mSubscriptionManagerService).setDefaultSmsSubId(2); 754 verifyDismissIntentSent(); 755 } 756 captureBroadcastIntent()757 private Intent captureBroadcastIntent() { 758 ArgumentCaptor<Intent> intentCapture = ArgumentCaptor.forClass(Intent.class); 759 verify(mContext).sendBroadcast(intentCapture.capture()); 760 return intentCapture.getValue(); 761 } 762 763 @Test 764 @SmallTest testGroupedPrimarySubscriptions()765 public void testGroupedPrimarySubscriptions() throws Exception { 766 doReturn(1).when(mSubscriptionManagerService).getDefaultDataSubId(); 767 doReturn(true).when(mPhoneMock1).isUserDataEnabled(); 768 doReturn(false).when(mPhoneMock2).isUserDataEnabled(); 769 GlobalSettingsHelper.setBoolean(mContext, Settings.Global.MOBILE_DATA, 1, true); 770 GlobalSettingsHelper.setBoolean(mContext, Settings.Global.DATA_ROAMING, 1, false); 771 mMultiSimSettingControllerUT.notifyAllSubscriptionLoaded(); 772 sendCarrierConfigChanged(0, 1); 773 sendCarrierConfigChanged(1, 2); 774 processAllMessages(); 775 776 // Create subscription grouping. 777 mSubInfo[1] = new SubscriptionInfoInternal.Builder(mSubInfo[1]) 778 .setGroupUuid(mGroupUuid1.toString()).build(); 779 doReturn(Arrays.asList(mSubInfo[1].toSubscriptionInfo(), mSubInfo[2].toSubscriptionInfo())) 780 .when(mSubscriptionManagerService).getSubscriptionsInGroup(any(), anyString(), 781 nullable(String.class)); 782 mMultiSimSettingControllerUT.notifySubscriptionGroupChanged(mGroupUuid1); 783 processAllMessages(); 784 // This should result in setting sync. 785 verify(mDataSettingsManagerMock2).setDataEnabled(TelephonyManager.DATA_ENABLED_REASON_USER, 786 true, PHONE_PACKAGE); 787 assertFalse(GlobalSettingsHelper.getBoolean( 788 mContext, Settings.Global.DATA_ROAMING, 2, true)); 789 verify(mSubscriptionManagerService).setDataRoaming(/*enable*/0, /*subId*/1); 790 791 // Turning off user data on sub 1. 792 doReturn(false).when(mPhoneMock1).isUserDataEnabled(); 793 mMultiSimSettingControllerUT.notifyUserDataEnabled(1, false); 794 processAllMessages(); 795 verify(mDataSettingsManagerMock2).setDataEnabled(TelephonyManager.DATA_ENABLED_REASON_USER, 796 false, PHONE_PACKAGE); 797 } 798 799 @Test 800 @SmallTest testCarrierConfigLoading()801 public void testCarrierConfigLoading() throws Exception { 802 doReturn(true).when(mPhoneMock1).isUserDataEnabled(); 803 doReturn(true).when(mPhoneMock2).isUserDataEnabled(); 804 mSubInfo[2] = new SubscriptionInfoInternal.Builder(mSubInfo[2]).setGroupUuid("").build(); 805 mSubInfo[3] = new SubscriptionInfoInternal.Builder(mSubInfo[3]).setGroupUuid("").build(); 806 // Sub 2 should have mobile data off, but it shouldn't happen until carrier configs are 807 // loaded on both subscriptions. 808 mMultiSimSettingControllerUT.notifyAllSubscriptionLoaded(); 809 processAllMessages(); 810 verify(mDataSettingsManagerMock2, never()).setDataEnabled( 811 TelephonyManager.DATA_ENABLED_REASON_USER, false, PHONE_PACKAGE); 812 sendCarrierConfigChanged(0, 1); 813 processAllMessages(); 814 verify(mDataSettingsManagerMock2, never()).setDataEnabled( 815 TelephonyManager.DATA_ENABLED_REASON_USER, false, PHONE_PACKAGE); 816 sendCarrierConfigChanged(1, 2); 817 processAllMessages(); 818 verify(mDataSettingsManagerMock2).setDataEnabled( 819 TelephonyManager.DATA_ENABLED_REASON_USER, false, PHONE_PACKAGE); 820 821 // Switch from sub 2 to sub 3 in phone[1]. 822 clearInvocations(mSubscriptionManagerService); 823 markSubscriptionInactive(2); 824 setSimSlotIndex(3, 1); 825 826 // Nothing should happen until carrier config change is notified on sub 3. 827 mMultiSimSettingControllerUT.notifySubscriptionInfoChanged(); 828 processAllMessages(); 829 verify(mContext, never()).sendBroadcast(any()); 830 831 sendCarrierConfigChanged(1, 3); 832 processAllMessages(); 833 // Intent should be broadcast to ask default data selection. 834 Intent intent = captureBroadcastIntent(); 835 assertEquals(ACTION_PRIMARY_SUBSCRIPTION_LIST_CHANGED, intent.getAction()); 836 assertEquals(EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_DATA, 837 intent.getIntExtra(EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE, -1)); 838 } 839 840 @Test 841 @SmallTest 842 // b/146446143 testGroupChangeOnInactiveSub_shouldNotMarkAsDefaultDataSub()843 public void testGroupChangeOnInactiveSub_shouldNotMarkAsDefaultDataSub() throws Exception { 844 // Make sub1 and sub3 as active sub. 845 markSubscriptionInactive(2); 846 setSimSlotIndex(3, 1); 847 doReturn(Arrays.asList(mSubInfo[2].toSubscriptionInfo(), mSubInfo[3].toSubscriptionInfo(), 848 mSubInfo[4].toSubscriptionInfo())).when(mSubscriptionManagerService) 849 .getSubscriptionsInGroup(any(), anyString(), nullable(String.class)); 850 851 // Sub 3 and sub 2's mobile data are enabled, and sub 3 is the default data sub. 852 doReturn(3).when(mSubscriptionManagerService).getDefaultDataSubId(); 853 GlobalSettingsHelper.setBoolean(mContext, Settings.Global.MOBILE_DATA, 1, false); 854 GlobalSettingsHelper.setBoolean(mContext, Settings.Global.MOBILE_DATA, 2, true); 855 GlobalSettingsHelper.setBoolean(mContext, Settings.Global.MOBILE_DATA, 3, true); 856 doReturn(false).when(mPhoneMock1).isUserDataEnabled(); 857 doReturn(true).when(mPhoneMock2).isUserDataEnabled(); 858 // Sub 2 should have mobile data off, but it shouldn't happen until carrier configs are 859 // loaded on both subscriptions. 860 mMultiSimSettingControllerUT.notifyAllSubscriptionLoaded(); 861 sendCarrierConfigChanged(0, 1); 862 sendCarrierConfigChanged(1, 3); 863 processAllMessages(); 864 865 // Mark sub3 as oppt and notify grouping 866 mSubInfo[3] = new SubscriptionInfoInternal.Builder(mSubInfo[3]).setOpportunistic(1).build(); 867 setSimSlotIndex(3, 0); 868 mMultiSimSettingControllerUT.notifySubscriptionGroupChanged(mGroupUuid1); 869 processAllMessages(); 870 // Shouldn't mark sub 2 as default data, as sub 2 is in active. 871 verify(mSubscriptionManagerService, never()).setDefaultDataSubId(2); 872 } 873 874 @Test 875 @SmallTest 876 // b/146446143 testCarrierConfigChangeWithInvalidSubId_shouldAlwaysTryToGetSubId()877 public void testCarrierConfigChangeWithInvalidSubId_shouldAlwaysTryToGetSubId() 878 throws Exception { 879 doReturn(true).when(mPhoneMock1).isUserDataEnabled(); 880 doReturn(true).when(mPhoneMock2).isUserDataEnabled(); 881 mMultiSimSettingControllerUT.notifyAllSubscriptionLoaded(); 882 processAllMessages(); 883 884 PersistableBundle bundle = new PersistableBundle(); 885 bundle.putBoolean(CarrierConfigManager.KEY_CARRIER_CONFIG_APPLIED_BOOL, true); 886 doReturn(bundle).when(mCarrierConfigManager).getConfigForSubId(eq(1)); 887 PersistableBundle bundle2 = new PersistableBundle(); 888 doReturn(bundle).when(mCarrierConfigManager).getConfigForSubId(eq(2)); 889 890 sendCarrierConfigChanged(0, 1); 891 // Notify carrier config change on phone1 without specifying subId. 892 sendCarrierConfigChanged(1, SubscriptionManager.INVALID_SUBSCRIPTION_ID); 893 processAllMessages(); 894 // Nothing should happen as carrier config is not ready for sub 2. 895 verify(mDataSettingsManagerMock2, never()).setDataEnabled( 896 TelephonyManager.DATA_ENABLED_REASON_USER, false, PHONE_PACKAGE); 897 898 logd("Sending the correct phone id and sub id"); 899 bundle2.putBoolean(CarrierConfigManager.KEY_CARRIER_CONFIG_APPLIED_BOOL, true); 900 sendCarrierConfigChanged(1, 2); 901 processAllMessages(); 902 // This time user data should be disabled on phone1. 903 verify(mDataSettingsManagerMock2).setDataEnabled( 904 TelephonyManager.DATA_ENABLED_REASON_USER, false, PHONE_PACKAGE); 905 906 // Remove and insert back SIM before it's loaded. 907 clearInvocations(mSubscriptionManagerService); 908 markSubscriptionInactive(1/*subid*/); 909 sendCarrierConfigChanged(0/*phoneid*/, SubscriptionManager.INVALID_SUBSCRIPTION_ID); 910 911 verify(mSubscriptionManagerService).setDefaultDataSubId(2); 912 913 // insert it back, but carrier config not loaded yet 914 clearInvocations(mSubscriptionManagerService); 915 setSimSlotIndex(1/*subid*/, 0/*phoneid*/); 916 mMultiSimSettingControllerUT.notifySubscriptionInfoChanged(); 917 sendCarrierConfigChanged(0/*phoneid*/, SubscriptionManager.INVALID_SUBSCRIPTION_ID); 918 919 verify(mSubscriptionManagerService, never()).setDefaultDataSubId( 920 SubscriptionManager.INVALID_SUBSCRIPTION_ID); 921 922 // carrier config loaded 923 clearInvocations(mContext); 924 sendCarrierConfigChanged(0/*phoneid*/, 1/*subid*/); 925 verify(mContext).sendBroadcast(any()); 926 } 927 928 @Test 929 @SmallTest testOnPhoneRemoved()930 public void testOnPhoneRemoved() { 931 try { 932 mMultiSimSettingControllerUT.onPhoneRemoved(); 933 } catch (RuntimeException re) { 934 Assert.fail("Exception not expected when calling from the same thread"); 935 } 936 } 937 938 @Test 939 @SmallTest testOnPhoneRemoved_DifferentThread()940 public void testOnPhoneRemoved_DifferentThread() { 941 AtomicBoolean result = new AtomicBoolean(false); 942 CountDownLatch latch = new CountDownLatch(1); 943 HandlerThread handlerThread = new HandlerThread("MultiSimSettingControllerTest") { 944 public void onLooperPrepared() { 945 try { 946 mMultiSimSettingControllerUT.onPhoneRemoved(); 947 } catch (RuntimeException re) { 948 result.set(true); // true to indicate that the test passed 949 } 950 latch.countDown(); 951 } 952 }; 953 handlerThread.start(); 954 try { 955 if (!latch.await(5, TimeUnit.SECONDS)) { 956 Assert.fail("CountDownLatch did not reach 0"); 957 } else if (!result.get()) { 958 Assert.fail("Exception expected when not calling from the same thread"); 959 } 960 } catch (InterruptedException ie) { 961 Assert.fail("InterruptedException during latch.await"); 962 } 963 } 964 965 @Test 966 @SmallTest testVoiceDataSmsAutoFallback()967 public void testVoiceDataSmsAutoFallback() throws Exception { 968 doReturn(1).when(mSubscriptionManagerService).getDefaultDataSubId(); 969 mMultiSimSettingControllerUT.notifyAllSubscriptionLoaded(); 970 sendCarrierConfigChanged(0, 1); 971 sendCarrierConfigChanged(2, 2); 972 processAllMessages(); 973 verify(mSubscriptionManagerService, never()).setDefaultDataSubId(anyInt()); 974 verify(mSubscriptionManagerService, never()).getActiveSubInfoCountMax(); 975 doReturn(2).when(mSubscriptionManagerService).getActiveSubInfoCountMax(); 976 mPhoneMock1.mCi = mMockCi; 977 mPhoneMock2.mCi = mMockCi; 978 doReturn(TelephonyManager.RADIO_POWER_ON).when(mMockCi).getRadioState(); 979 doReturn(false).when(mPhoneMock1).isShuttingDown(); 980 doReturn(false).when(mPhoneMock2).isShuttingDown(); 981 android.provider.Settings.Global.putInt(InstrumentationRegistry.getTargetContext(). 982 getContentResolver(), "user_preferred_data_sub", 2); 983 Resources resources = mContext.getResources(); 984 doReturn(true).when(resources).getBoolean( 985 com.android.internal.R.bool.config_voice_data_sms_auto_fallback); 986 mMultiSimSettingControllerUT.notifyAllSubscriptionLoaded(); 987 sendCarrierConfigChanged(0, 1); 988 sendCarrierConfigChanged(1, 2); 989 processAllMessages(); 990 verify(mSubscriptionManagerService).getActiveSubInfoCountMax(); 991 verify(mSubscriptionManagerService).setDefaultDataSubId(anyInt()); 992 } 993 994 @Test onSubscriptionGroupChanged_hasActiveSubNotPartOfGroup()995 public void onSubscriptionGroupChanged_hasActiveSubNotPartOfGroup() { 996 // sub1 and sub2 are active subs already 997 // Create a subscription group with only sub2 998 doReturn(Arrays.asList(mSubInfo[2].toSubscriptionInfo())).when(mSubscriptionManagerService) 999 .getSubscriptionsInGroup(any(), anyString(), nullable(String.class)); 1000 mMultiSimSettingControllerUT.notifySubscriptionGroupChanged(mGroupUuid1); 1001 processAllMessages(); 1002 // Default data is not modified as sub1 is active sub not part of this groupUuid 1003 verify(mSubscriptionManagerService, never()).setDefaultDataSubId(anyInt()); 1004 } 1005 1006 @Test onSubscriptionGroupChanged_allActiveSubArePartOfGroup()1007 public void onSubscriptionGroupChanged_allActiveSubArePartOfGroup() throws Exception { 1008 doReturn(3).when(mSubscriptionManagerService).getDefaultDataSubId(); 1009 // Create subscription grouping of subs 1 and 2. 1010 mSubInfo[1] = new SubscriptionInfoInternal.Builder(mSubInfo[1]) 1011 .setGroupUuid(mGroupUuid1.toString()).build(); 1012 GlobalSettingsHelper.setBoolean(mContext, Settings.Global.MOBILE_DATA, 1, true); 1013 doReturn(Arrays.asList(mSubInfo[1].toSubscriptionInfo(), mSubInfo[2].toSubscriptionInfo())) 1014 .when(mSubscriptionManagerService) 1015 .getSubscriptionsInGroup(any(), anyString(), nullable(String.class)); 1016 1017 mMultiSimSettingControllerUT.notifySubscriptionGroupChanged(mGroupUuid1); 1018 processAllMessages(); 1019 // Default data is set to sub1 1020 verify(mSubscriptionManagerService).syncGroupedSetting(1); 1021 } 1022 1023 @Test testDailogsAndWarnings_WithBootstrapSim()1024 public void testDailogsAndWarnings_WithBootstrapSim() { 1025 doReturn(true).when(mFeatureFlags).esimBootstrapProvisioningFlag(); 1026 1027 // Mark sub 2 as inactive. 1028 markSubscriptionInactive(2); 1029 mMultiSimSettingControllerUT.notifyAllSubscriptionLoaded(); 1030 sendCarrierConfigChanged(0, 1); 1031 processAllMessages(); 1032 1033 // Sub 1 should be default sub silently. 1034 verify(mSubscriptionManagerService).setDefaultDataSubId(1); 1035 verify(mSubscriptionManagerService).setDefaultVoiceSubId(1); 1036 verify(mSubscriptionManagerService).setDefaultSmsSubId(1); 1037 verifyDismissIntentSent(); 1038 1039 // Mark sub 2 bootstrap sim as active in phone[1]. 1040 doReturn(true).when(mSubscriptionManagerService).isEsimBootStrapProvisioningActivated(); 1041 setSimSlotIndex(2, 1); 1042 clearInvocations(mSubscriptionManagerService); 1043 clearInvocations(mContext); 1044 mSubInfo[2] = new SubscriptionInfoInternal.Builder().setId(2).setSimSlotIndex(1) 1045 .setProfileClass(SubscriptionManager.PROFILE_CLASS_PROVISIONING).build(); 1046 mMultiSimSettingControllerUT.notifySubscriptionInfoChanged(); 1047 sendCarrierConfigChanged(1, 2); 1048 processAllMessages(); 1049 1050 // Taking out SIM 1. 1051 clearInvocations(mSubscriptionManagerService); 1052 markSubscriptionInactive(1/*subid*/); 1053 mMultiSimSettingControllerUT.notifySubscriptionInfoChanged(); 1054 sendCarrierConfigChanged(0/*phoneid*/, SubscriptionManager.INVALID_SUBSCRIPTION_ID); 1055 processAllMessages(); 1056 1057 // No user selection needed, no intent should be sent for notification 1058 verify(mContext, never()).sendBroadcast(any()); 1059 1060 //Insert back sim1 and switch from sub 1 to sub 3 in phone[0]. 1061 clearInvocations(mSubscriptionManagerService); 1062 markSubscriptionInactive(1); 1063 setSimSlotIndex(3, 0); 1064 mMultiSimSettingControllerUT.notifySubscriptionInfoChanged(); 1065 sendCarrierConfigChanged(0/*phoneid*/, 3/*subid*/); 1066 processAllMessages(); 1067 1068 // Sub 3 should be default sub. 1069 verify(mSubscriptionManagerService).setDefaultDataSubId(3); 1070 verify(mSubscriptionManagerService).setDefaultVoiceSubId(3); 1071 verify(mSubscriptionManagerService).setDefaultSmsSubId(3); 1072 verify(mContext, never()).sendBroadcast(any()); 1073 } 1074 1075 } 1076