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