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.keyguard;
18 
19 
20 import static android.telephony.SubscriptionManager.DATA_ROAMING_DISABLE;
21 import static android.telephony.SubscriptionManager.DATA_ROAMING_ENABLE;
22 import static android.telephony.SubscriptionManager.NAME_SOURCE_CARRIER_ID;
23 
24 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
25 
26 import static com.google.common.truth.Truth.assertThat;
27 
28 import static junit.framework.Assert.assertTrue;
29 import static junit.framework.TestCase.assertFalse;
30 
31 import static org.junit.Assert.assertEquals;
32 import static org.junit.Assert.assertNotEquals;
33 import static org.mockito.ArgumentMatchers.any;
34 import static org.mockito.ArgumentMatchers.anyInt;
35 import static org.mockito.ArgumentMatchers.eq;
36 import static org.mockito.Mockito.doAnswer;
37 import static org.mockito.Mockito.mock;
38 import static org.mockito.Mockito.never;
39 import static org.mockito.Mockito.reset;
40 import static org.mockito.Mockito.spy;
41 import static org.mockito.Mockito.verify;
42 import static org.mockito.Mockito.when;
43 
44 import android.content.Context;
45 import android.content.Intent;
46 import android.content.IntentFilter;
47 import android.content.pm.PackageManager;
48 import android.provider.Settings;
49 import android.telephony.ServiceState;
50 import android.telephony.SubscriptionInfo;
51 import android.telephony.SubscriptionManager;
52 import android.telephony.TelephonyManager;
53 import android.testing.AndroidTestingRunner;
54 import android.text.TextUtils;
55 
56 import androidx.test.filters.SmallTest;
57 
58 import com.android.keyguard.logging.CarrierTextManagerLogger;
59 import com.android.systemui.SysuiTestCase;
60 import com.android.systemui.keyguard.WakefulnessLifecycle;
61 import com.android.systemui.kosmos.KosmosJavaAdapter;
62 import com.android.systemui.log.LogBufferHelperKt;
63 import com.android.systemui.res.R;
64 import com.android.systemui.statusbar.pipeline.satellite.ui.viewmodel.FakeDeviceBasedSatelliteViewModel;
65 import com.android.systemui.statusbar.pipeline.wifi.data.repository.FakeWifiRepository;
66 import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiNetworkModel;
67 import com.android.systemui.telephony.TelephonyListenerManager;
68 import com.android.systemui.util.concurrency.FakeExecutor;
69 import com.android.systemui.util.kotlin.JavaAdapter;
70 import com.android.systemui.util.time.FakeSystemClock;
71 
72 import kotlinx.coroutines.test.TestScope;
73 
74 import org.junit.Before;
75 import org.junit.Test;
76 import org.junit.runner.RunWith;
77 import org.mockito.ArgumentCaptor;
78 import org.mockito.Mock;
79 import org.mockito.MockitoAnnotations;
80 import org.mockito.invocation.InvocationOnMock;
81 
82 import java.util.ArrayList;
83 import java.util.HashMap;
84 import java.util.List;
85 
86 @SmallTest
87 @RunWith(AndroidTestingRunner.class)
88 public class CarrierTextManagerTest extends SysuiTestCase {
89 
90     private static final CharSequence SEPARATOR = " \u2014 ";
91     private static final CharSequence INVALID_CARD_TEXT = "Invalid card";
92     private static final CharSequence AIRPLANE_MODE_TEXT = "Airplane mode";
93     private static final String TEST_CARRIER = "TEST_CARRIER";
94     private static final String TEST_CARRIER_2 = "TEST_CARRIER_2";
95     private static final int TEST_CARRIER_ID = 1;
96     private static final SubscriptionInfo TEST_SUBSCRIPTION = new SubscriptionInfo(0, "", 0,
97             TEST_CARRIER, TEST_CARRIER, NAME_SOURCE_CARRIER_ID, 0xFFFFFF, "",
98             DATA_ROAMING_DISABLE, null, null, null, null, false, null, "", false, null,
99             TEST_CARRIER_ID, 0);
100     private static final SubscriptionInfo TEST_SUBSCRIPTION_NULL = new SubscriptionInfo(0, "", 0,
101             TEST_CARRIER, null, NAME_SOURCE_CARRIER_ID, 0xFFFFFF, "", DATA_ROAMING_DISABLE,
102             null, null, null, null, false, null, "");
103     private static final SubscriptionInfo TEST_SUBSCRIPTION_ROAMING = new SubscriptionInfo(0, "", 0,
104             TEST_CARRIER, TEST_CARRIER, NAME_SOURCE_CARRIER_ID, 0xFFFFFF, "",
105             DATA_ROAMING_ENABLE, null, null, null, null, false, null, "");
106     private FakeWifiRepository mWifiRepository = new FakeWifiRepository();
107     private final FakeDeviceBasedSatelliteViewModel mSatelliteViewModel =
108             new FakeDeviceBasedSatelliteViewModel();
109     @Mock
110     private WakefulnessLifecycle mWakefulnessLifecycle;
111     @Mock
112     private CarrierTextManager.CarrierTextCallback mCarrierTextCallback;
113     @Mock
114     private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
115     @Mock
116     private PackageManager mPackageManager;
117     @Mock
118     private TelephonyManager mTelephonyManager;
119     @Mock
120     private TelephonyListenerManager mTelephonyListenerManager;
121     private FakeSystemClock mFakeSystemClock = new FakeSystemClock();
122     private FakeExecutor mMainExecutor = new FakeExecutor(mFakeSystemClock);
123     private FakeExecutor mBgExecutor = new FakeExecutor(mFakeSystemClock);
124     @Mock
125     private SubscriptionManager mSubscriptionManager;
126     private CarrierTextManager.CarrierTextCallbackInfo mCarrierTextCallbackInfo;
127 
128     private CarrierTextManager mCarrierTextManager;
129 
130     private CarrierTextManagerLogger mLogger =
131             new CarrierTextManagerLogger(
132                     LogBufferHelperKt.logcatLogBuffer("CarrierTextManagerLog"));
133 
134     private final KosmosJavaAdapter mKosmos = new KosmosJavaAdapter(this);
135     private final TestScope mTestScope = mKosmos.getTestScope();
136     private final JavaAdapter mJavaAdapter = new JavaAdapter(mTestScope.getBackgroundScope());
137 
checkMainThread(InvocationOnMock inv)138     private Void checkMainThread(InvocationOnMock inv) {
139         assertThat(mMainExecutor.isExecuting()).isTrue();
140         assertThat(mBgExecutor.isExecuting()).isFalse();
141         return null;
142     }
143 
144     @Before
setUp()145     public void setUp() {
146         MockitoAnnotations.initMocks(this);
147 
148         mContext.addMockSystemService(PackageManager.class, mPackageManager);
149         when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)).thenReturn(true);
150         mContext.addMockSystemService(TelephonyManager.class, mTelephonyManager);
151         mContext.addMockSystemService(SubscriptionManager.class, mSubscriptionManager);
152         mContext.getOrCreateTestableResources().addOverride(
153                 R.string.keyguard_sim_error_message_short, INVALID_CARD_TEXT);
154         mContext.getOrCreateTestableResources().addOverride(
155                 R.string.airplane_mode, AIRPLANE_MODE_TEXT);
156         mDependency.injectMockDependency(WakefulnessLifecycle.class);
157         mDependency.injectTestDependency(KeyguardUpdateMonitor.class, mKeyguardUpdateMonitor);
158 
159         doAnswer(this::checkMainThread).when(mKeyguardUpdateMonitor)
160                 .registerCallback(any(KeyguardUpdateMonitorCallback.class));
161         doAnswer(this::checkMainThread).when(mKeyguardUpdateMonitor)
162                 .removeCallback(any(KeyguardUpdateMonitorCallback.class));
163 
164         mCarrierTextCallbackInfo = new CarrierTextManager.CarrierTextCallbackInfo(
165                 /* carrierText= */ "",
166                 /* listOfCarriers= */ new CharSequence[]{},
167                 /* anySimReady= */ false,
168                 /* subscriptionIds= */ new int[]{});
169         when(mTelephonyManager.getSupportedModemCount()).thenReturn(3);
170         when(mTelephonyManager.getActiveModemCount()).thenReturn(3);
171 
172         mCarrierTextManager = new CarrierTextManager.Builder(
173                 mContext,
174                 mContext.getResources(),
175                 mWifiRepository,
176                 mSatelliteViewModel,
177                 mJavaAdapter,
178                 mTelephonyManager,
179                 mTelephonyListenerManager,
180                 mWakefulnessLifecycle,
181                 mMainExecutor,
182                 mBgExecutor,
183                 mKeyguardUpdateMonitor,
184                 mLogger)
185                 .setShowAirplaneMode(true)
186                 .setShowMissingSim(true)
187                 .build();
188 
189         // This should not start listening on any of the real dependencies but will test that
190         // callbacks in mKeyguardUpdateMonitor are done in the mTestableLooper thread
191         mCarrierTextManager.setListening(mCarrierTextCallback);
192         FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
193     }
194 
195     @Test
testKeyguardUpdateMonitorCalledInMainThread()196     public void testKeyguardUpdateMonitorCalledInMainThread() throws Exception {
197         mCarrierTextManager.setListening(null);
198         mCarrierTextManager.setListening(mCarrierTextCallback);
199         FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
200     }
201 
202     @Test
testAirplaneMode()203     public void testAirplaneMode() {
204         Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, 1);
205         reset(mCarrierTextCallback);
206         List<SubscriptionInfo> list = new ArrayList<>();
207         list.add(TEST_SUBSCRIPTION);
208         when(mKeyguardUpdateMonitor.getFilteredSubscriptionInfo()).thenReturn(list);
209         when(mKeyguardUpdateMonitor.getSimState(0)).thenReturn(TelephonyManager.SIM_STATE_READY);
210         mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();
211 
212         mCarrierTextManager.updateCarrierText();
213 
214         ArgumentCaptor<CarrierTextManager.CarrierTextCallbackInfo> captor =
215                 ArgumentCaptor.forClass(
216                         CarrierTextManager.CarrierTextCallbackInfo.class);
217 
218         FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
219         verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
220         assertEquals(AIRPLANE_MODE_TEXT, captor.getValue().carrierText);
221     }
222 
223     /** regression test for b/281706473, caused by sending NULL plmn / spn to the logger */
224     @Test
testAirplaneMode_noSim_nullPlmn_nullSpn_doesNotCrash()225     public void testAirplaneMode_noSim_nullPlmn_nullSpn_doesNotCrash() {
226         // GIVEN - sticy broadcast that returns a null PLMN and null SPN
227         Intent stickyIntent = new Intent(TelephonyManager.ACTION_SERVICE_PROVIDERS_UPDATED);
228         stickyIntent.putExtra(TelephonyManager.EXTRA_SHOW_PLMN, true);
229         stickyIntent.removeExtra(TelephonyManager.EXTRA_PLMN);
230         stickyIntent.putExtra(TelephonyManager.EXTRA_SHOW_SPN, true);
231         stickyIntent.removeExtra(TelephonyManager.EXTRA_SPN);
232 
233         mCarrierTextManager = new CarrierTextManager.Builder(
234                 getContextSpyForStickyBroadcast(stickyIntent),
235                 mContext.getResources(),
236                 mWifiRepository,
237                 mSatelliteViewModel,
238                 mJavaAdapter,
239                 mTelephonyManager,
240                 mTelephonyListenerManager,
241                 mWakefulnessLifecycle,
242                 mMainExecutor,
243                 mBgExecutor,
244                 mKeyguardUpdateMonitor,
245                 mLogger
246         )
247                 .setShowAirplaneMode(true)
248                 .setShowMissingSim(true)
249                 .build();
250 
251         // GIVEN - airplane mode is off (causing CTM to fetch the sticky broadcast)
252         Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, 1);
253         reset(mCarrierTextCallback);
254         List<SubscriptionInfo> list = new ArrayList<>();
255         when(mKeyguardUpdateMonitor.getFilteredSubscriptionInfo()).thenReturn(list);
256         when(mKeyguardUpdateMonitor.getSimState(0))
257                 .thenReturn(TelephonyManager.SIM_STATE_NOT_READY);
258         mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();
259 
260         // WHEN CTM fetches the broadcast and attempts to log the result, no crash results
261         mCarrierTextManager.updateCarrierText();
262 
263         // No assert, this test should not crash
264     }
265 
266     @Test
testCardIOError()267     public void testCardIOError() {
268         reset(mCarrierTextCallback);
269         List<SubscriptionInfo> list = new ArrayList<>();
270         list.add(TEST_SUBSCRIPTION);
271         when(mKeyguardUpdateMonitor.getFilteredSubscriptionInfo()).thenReturn(list);
272         when(mKeyguardUpdateMonitor.getSimState(0)).thenReturn(TelephonyManager.SIM_STATE_READY);
273         when(mKeyguardUpdateMonitor.getSimState(1)).thenReturn(
274                 TelephonyManager.SIM_STATE_CARD_IO_ERROR);
275         mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();
276 
277         mCarrierTextManager.mCallback.onSimStateChanged(3, 1,
278                 TelephonyManager.SIM_STATE_CARD_IO_ERROR);
279 
280         ArgumentCaptor<CarrierTextManager.CarrierTextCallbackInfo> captor =
281                 ArgumentCaptor.forClass(
282                         CarrierTextManager.CarrierTextCallbackInfo.class);
283 
284         FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
285         verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
286         assertEquals("TEST_CARRIER" + SEPARATOR + INVALID_CARD_TEXT, captor.getValue().carrierText);
287         // There's only one subscription in the list
288         assertEquals(1, captor.getValue().listOfCarriers.length);
289         assertEquals(TEST_CARRIER, captor.getValue().listOfCarriers[0]);
290 
291         // Now it becomes single SIM active mode.
292         reset(mCarrierTextCallback);
293         when(mTelephonyManager.getActiveModemCount()).thenReturn(1);
294         // Update carrier text. It should ignore error state of subId 3 in inactive slotId.
295         mCarrierTextManager.updateCarrierText();
296         FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
297         verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
298         assertEquals("TEST_CARRIER", captor.getValue().carrierText);
299     }
300 
301     @Test
testWrongSlots()302     public void testWrongSlots() {
303         reset(mCarrierTextCallback);
304         when(mKeyguardUpdateMonitor.getFilteredSubscriptionInfo()).thenReturn(
305                 new ArrayList<>());
306         when(mKeyguardUpdateMonitor.getSimState(anyInt())).thenReturn(
307                 TelephonyManager.SIM_STATE_CARD_IO_ERROR);
308         // This should not produce an out of bounds error, even though there are no subscriptions
309         mCarrierTextManager.mCallback.onSimStateChanged(0, -3,
310                 TelephonyManager.SIM_STATE_CARD_IO_ERROR);
311         mCarrierTextManager.mCallback.onSimStateChanged(0, 3, TelephonyManager.SIM_STATE_READY);
312         verify(mCarrierTextCallback, never()).updateCarrierInfo(any());
313     }
314 
315     @Test
testMoreSlotsThanSubs()316     public void testMoreSlotsThanSubs() {
317         reset(mCarrierTextCallback);
318         when(mKeyguardUpdateMonitor.getFilteredSubscriptionInfo()).thenReturn(
319                 new ArrayList<>());
320 
321         // STOPSHIP(b/130246708) This line makes sure that SubscriptionManager provides the
322         // same answer as KeyguardUpdateMonitor. Remove when this is addressed
323         when(mSubscriptionManager.getCompleteActiveSubscriptionInfoList()).thenReturn(
324                 new ArrayList<>());
325 
326         when(mKeyguardUpdateMonitor.getSimState(anyInt())).thenReturn(
327                 TelephonyManager.SIM_STATE_CARD_IO_ERROR);
328         // This should not produce an out of bounds error, even though there are no subscriptions
329         mCarrierTextManager.mCallback.onSimStateChanged(0, 1,
330                 TelephonyManager.SIM_STATE_CARD_IO_ERROR);
331 
332         FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
333         verify(mCarrierTextCallback).updateCarrierInfo(
334                 any(CarrierTextManager.CarrierTextCallbackInfo.class));
335     }
336 
337     @Test
testCallback()338     public void testCallback() {
339         reset(mCarrierTextCallback);
340         mCarrierTextManager.postToCallback(mCarrierTextCallbackInfo);
341         FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
342 
343         ArgumentCaptor<CarrierTextManager.CarrierTextCallbackInfo> captor =
344                 ArgumentCaptor.forClass(
345                         CarrierTextManager.CarrierTextCallbackInfo.class);
346         verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
347         assertEquals(mCarrierTextCallbackInfo, captor.getValue());
348     }
349 
350     @Test
testNullingCallback()351     public void testNullingCallback() {
352         reset(mCarrierTextCallback);
353 
354         mCarrierTextManager.postToCallback(mCarrierTextCallbackInfo);
355         mCarrierTextManager.setListening(null);
356 
357         // This shouldn't produce NPE
358         FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
359         verify(mCarrierTextCallback).updateCarrierInfo(any());
360     }
361 
362     @Test
testCreateInfo_OneValidSubscription()363     public void testCreateInfo_OneValidSubscription() {
364         reset(mCarrierTextCallback);
365         List<SubscriptionInfo> list = new ArrayList<>();
366         list.add(TEST_SUBSCRIPTION);
367         when(mKeyguardUpdateMonitor.getSimState(anyInt())).thenReturn(
368                 TelephonyManager.SIM_STATE_READY);
369         when(mKeyguardUpdateMonitor.getFilteredSubscriptionInfo()).thenReturn(list);
370 
371         mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();
372 
373         ArgumentCaptor<CarrierTextManager.CarrierTextCallbackInfo> captor =
374                 ArgumentCaptor.forClass(
375                         CarrierTextManager.CarrierTextCallbackInfo.class);
376 
377         mCarrierTextManager.updateCarrierText();
378         FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
379         verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
380 
381         CarrierTextManager.CarrierTextCallbackInfo info = captor.getValue();
382         assertEquals(1, info.listOfCarriers.length);
383         assertEquals(TEST_CARRIER, info.listOfCarriers[0]);
384         assertEquals(1, info.subscriptionIds.length);
385     }
386 
387     @Test
testCreateInfo_OneValidSubscriptionWithRoaming()388     public void testCreateInfo_OneValidSubscriptionWithRoaming() {
389         reset(mCarrierTextCallback);
390         List<SubscriptionInfo> list = new ArrayList<>();
391         list.add(TEST_SUBSCRIPTION_ROAMING);
392         when(mKeyguardUpdateMonitor.getSimState(anyInt())).thenReturn(
393                 TelephonyManager.SIM_STATE_READY);
394         when(mKeyguardUpdateMonitor.getFilteredSubscriptionInfo()).thenReturn(list);
395 
396         mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();
397 
398         ArgumentCaptor<CarrierTextManager.CarrierTextCallbackInfo> captor =
399                 ArgumentCaptor.forClass(
400                         CarrierTextManager.CarrierTextCallbackInfo.class);
401 
402         mCarrierTextManager.updateCarrierText();
403         FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
404         verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
405 
406         CarrierTextManager.CarrierTextCallbackInfo info = captor.getValue();
407         assertEquals(1, info.listOfCarriers.length);
408         assertTrue(info.listOfCarriers[0].toString().contains(TEST_CARRIER));
409         assertEquals(1, info.subscriptionIds.length);
410     }
411 
412     @Test
testCarrierText_noTextOnReadySimWhenNull()413     public void testCarrierText_noTextOnReadySimWhenNull() {
414         reset(mCarrierTextCallback);
415         List<SubscriptionInfo> list = new ArrayList<>();
416         list.add(TEST_SUBSCRIPTION_NULL);
417         when(mKeyguardUpdateMonitor.getSimState(anyInt())).thenReturn(
418                 TelephonyManager.SIM_STATE_READY);
419         when(mKeyguardUpdateMonitor.getFilteredSubscriptionInfo()).thenReturn(list);
420 
421         mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();
422 
423         ArgumentCaptor<CarrierTextManager.CarrierTextCallbackInfo> captor =
424                 ArgumentCaptor.forClass(
425                         CarrierTextManager.CarrierTextCallbackInfo.class);
426 
427         mCarrierTextManager.updateCarrierText();
428         FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
429         verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
430 
431         assertTrue("Carrier text should be empty, instead it's " + captor.getValue().carrierText,
432                 TextUtils.isEmpty(captor.getValue().carrierText));
433         assertFalse("No SIM should be available", captor.getValue().anySimReady);
434     }
435 
436     @Test
testCarrierText_noTextOnReadySimWhenNull_airplaneMode_wifiOn()437     public void testCarrierText_noTextOnReadySimWhenNull_airplaneMode_wifiOn() {
438         Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, 1);
439         reset(mCarrierTextCallback);
440         List<SubscriptionInfo> list = new ArrayList<>();
441         list.add(TEST_SUBSCRIPTION_NULL);
442         when(mKeyguardUpdateMonitor.getSimState(anyInt())).thenReturn(
443                 TelephonyManager.SIM_STATE_READY);
444         when(mKeyguardUpdateMonitor.getFilteredSubscriptionInfo()).thenReturn(list);
445 
446         assertFalse(mWifiRepository.isWifiConnectedWithValidSsid());
447         mWifiRepository.setWifiNetwork(
448                 new WifiNetworkModel.Active(
449                         /* networkId= */ 0,
450                         /* isValidated= */ false,
451                         /* level= */ 0,
452                         /* ssid= */ "",
453                         /* hotspotDeviceType= */ WifiNetworkModel.HotspotDeviceType.NONE,
454                         /* isPasspointAccessPoint= */ false,
455                         /* isOnlineSignUpForPasspointAccessPoint= */ false,
456                         /* passpointProviderFriendlyName= */ null));
457         assertTrue(mWifiRepository.isWifiConnectedWithValidSsid());
458 
459         mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();
460         ServiceState ss = mock(ServiceState.class);
461         when(ss.getDataRegistrationState()).thenReturn(ServiceState.STATE_IN_SERVICE);
462         mKeyguardUpdateMonitor.mServiceStates.put(TEST_SUBSCRIPTION_NULL.getSubscriptionId(), ss);
463 
464         ArgumentCaptor<CarrierTextManager.CarrierTextCallbackInfo> captor =
465                 ArgumentCaptor.forClass(
466                         CarrierTextManager.CarrierTextCallbackInfo.class);
467 
468         mCarrierTextManager.updateCarrierText();
469         FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
470         verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
471 
472         assertFalse("No SIM should be available", captor.getValue().anySimReady);
473         // There's no airplane mode if at least one SIM is State.READY and there's wifi
474         assertFalse("Device should not be in airplane mode", captor.getValue().airplaneMode);
475         assertNotEquals(AIRPLANE_MODE_TEXT, captor.getValue().carrierText);
476     }
477 
478     @Test
carrierText_satelliteTextNull_isSatelliteFalse_textNotUsed()479     public void carrierText_satelliteTextNull_isSatelliteFalse_textNotUsed() {
480         reset(mCarrierTextCallback);
481         List<SubscriptionInfo> list = new ArrayList<>();
482         list.add(TEST_SUBSCRIPTION);
483         when(mKeyguardUpdateMonitor.getSimState(anyInt())).thenReturn(
484                 TelephonyManager.SIM_STATE_READY);
485         when(mKeyguardUpdateMonitor.getFilteredSubscriptionInfo()).thenReturn(list);
486         mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();
487 
488         // WHEN the satellite text is null
489         mSatelliteViewModel.getCarrierText().setValue(null);
490         mTestScope.getTestScheduler().runCurrent();
491 
492         ArgumentCaptor<CarrierTextManager.CarrierTextCallbackInfo> captor =
493                 ArgumentCaptor.forClass(
494                         CarrierTextManager.CarrierTextCallbackInfo.class);
495         FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
496 
497         // THEN satellite mode is false and the default subscription carrier text is used
498         verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
499         assertThat(captor.getValue().isInSatelliteMode).isFalse();
500         assertThat(captor.getValue().carrierText).isEqualTo(TEST_CARRIER);
501     }
502 
503     @Test
carrierText_hasSatelliteText_isSatelliteTrue_textUsed()504     public void carrierText_hasSatelliteText_isSatelliteTrue_textUsed() {
505         reset(mCarrierTextCallback);
506         List<SubscriptionInfo> list = new ArrayList<>();
507         list.add(TEST_SUBSCRIPTION);
508         when(mKeyguardUpdateMonitor.getSimState(anyInt())).thenReturn(
509                 TelephonyManager.SIM_STATE_READY);
510         when(mKeyguardUpdateMonitor.getFilteredSubscriptionInfo()).thenReturn(list);
511         mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();
512 
513         // WHEN the satellite text is non-null
514         mSatelliteViewModel.getCarrierText().setValue("Satellite Test Text");
515         mTestScope.getTestScheduler().runCurrent();
516 
517         ArgumentCaptor<CarrierTextManager.CarrierTextCallbackInfo> captor =
518                 ArgumentCaptor.forClass(
519                         CarrierTextManager.CarrierTextCallbackInfo.class);
520         FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
521 
522         // THEN satellite mode is true and the satellite text is used
523         verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
524         assertThat(captor.getValue().isInSatelliteMode).isTrue();
525         assertThat(captor.getValue().carrierText).isEqualTo("Satellite Test Text");
526     }
527 
528     @Test
carrierText_satelliteTextUpdates_autoTriggersCallback()529     public void carrierText_satelliteTextUpdates_autoTriggersCallback() {
530         reset(mCarrierTextCallback);
531         List<SubscriptionInfo> list = new ArrayList<>();
532         list.add(TEST_SUBSCRIPTION);
533         when(mKeyguardUpdateMonitor.getSimState(anyInt())).thenReturn(
534                 TelephonyManager.SIM_STATE_READY);
535         when(mKeyguardUpdateMonitor.getFilteredSubscriptionInfo()).thenReturn(list);
536         mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();
537 
538         // WHEN the satellite text is set
539         mSatelliteViewModel.getCarrierText().setValue("Test satellite text");
540         mTestScope.getTestScheduler().runCurrent();
541 
542         // THEN we should automatically re-trigger #updateCarrierText and get callback info
543         ArgumentCaptor<CarrierTextManager.CarrierTextCallbackInfo> captor =
544                 ArgumentCaptor.forClass(
545                         CarrierTextManager.CarrierTextCallbackInfo.class);
546         FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
547         verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
548         // AND use the satellite text as the carrier text
549         assertThat(captor.getValue().isInSatelliteMode).isTrue();
550         assertThat(captor.getValue().carrierText).isEqualTo("Test satellite text");
551 
552         // WHEN the satellite text is reset to null
553         reset(mCarrierTextCallback);
554         mSatelliteViewModel.getCarrierText().setValue(null);
555         mTestScope.getTestScheduler().runCurrent();
556 
557         // THEN we should automatically re-trigger #updateCarrierText and get callback info
558         // that doesn't include the satellite info
559         FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
560         verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
561         assertThat(captor.getValue().isInSatelliteMode).isFalse();
562         assertThat(captor.getValue().carrierText).isEqualTo(TEST_CARRIER);
563     }
564 
565     @Test
carrierText_updatedWhileNotListening_getsNewValueWhenListening()566     public void carrierText_updatedWhileNotListening_getsNewValueWhenListening() {
567         reset(mCarrierTextCallback);
568         List<SubscriptionInfo> list = new ArrayList<>();
569         list.add(TEST_SUBSCRIPTION);
570         when(mKeyguardUpdateMonitor.getSimState(anyInt())).thenReturn(
571                 TelephonyManager.SIM_STATE_READY);
572         when(mKeyguardUpdateMonitor.getFilteredSubscriptionInfo()).thenReturn(list);
573         mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();
574 
575         mSatelliteViewModel.getCarrierText().setValue("Old satellite text");
576         mTestScope.getTestScheduler().runCurrent();
577 
578         ArgumentCaptor<CarrierTextManager.CarrierTextCallbackInfo> captor =
579                 ArgumentCaptor.forClass(
580                         CarrierTextManager.CarrierTextCallbackInfo.class);
581         FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
582         verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
583         assertThat(captor.getValue().carrierText).isEqualTo("Old satellite text");
584 
585         // WHEN we stop listening
586         reset(mCarrierTextCallback);
587         mCarrierTextManager.setListening(null);
588 
589         // AND the satellite text updates
590         mSatelliteViewModel.getCarrierText().setValue("New satellite text");
591 
592         // THEN we don't get new callback info because we aren't listening
593         verify(mCarrierTextCallback, never()).updateCarrierInfo(any());
594 
595         // WHEN we start listening again
596         reset(mCarrierTextCallback);
597         mCarrierTextManager.setListening(mCarrierTextCallback);
598 
599         // THEN we should automatically re-trigger #updateCarrierText and get callback info
600         // that includes the new satellite state and text
601         mTestScope.getTestScheduler().runCurrent();
602         FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
603         verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
604         assertThat(captor.getValue().isInSatelliteMode).isTrue();
605         assertThat(captor.getValue().carrierText).isEqualTo("New satellite text");
606     }
607 
608     @Test
testCreateInfo_noSubscriptions()609     public void testCreateInfo_noSubscriptions() {
610         reset(mCarrierTextCallback);
611         when(mKeyguardUpdateMonitor.getFilteredSubscriptionInfo()).thenReturn(
612                 new ArrayList<>());
613 
614         ArgumentCaptor<CarrierTextManager.CarrierTextCallbackInfo> captor =
615                 ArgumentCaptor.forClass(
616                         CarrierTextManager.CarrierTextCallbackInfo.class);
617 
618         mCarrierTextManager.updateCarrierText();
619         FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
620         verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
621 
622         CarrierTextManager.CarrierTextCallbackInfo info = captor.getValue();
623         assertEquals(0, info.listOfCarriers.length);
624         assertEquals(0, info.subscriptionIds.length);
625 
626     }
627 
628     @Test
testCarrierText_oneValidSubscription()629     public void testCarrierText_oneValidSubscription() {
630         reset(mCarrierTextCallback);
631         List<SubscriptionInfo> list = new ArrayList<>();
632         list.add(TEST_SUBSCRIPTION);
633         when(mKeyguardUpdateMonitor.getSimState(anyInt())).thenReturn(
634                 TelephonyManager.SIM_STATE_READY);
635         when(mKeyguardUpdateMonitor.getFilteredSubscriptionInfo()).thenReturn(list);
636 
637         mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();
638 
639         ArgumentCaptor<CarrierTextManager.CarrierTextCallbackInfo> captor =
640                 ArgumentCaptor.forClass(
641                         CarrierTextManager.CarrierTextCallbackInfo.class);
642 
643         mCarrierTextManager.updateCarrierText();
644         FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
645         verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
646 
647         assertThat(captor.getValue().carrierText).isEqualTo(TEST_CARRIER);
648     }
649 
650     @Test
testCarrierText_twoValidSubscriptions()651     public void testCarrierText_twoValidSubscriptions() {
652         reset(mCarrierTextCallback);
653         List<SubscriptionInfo> list = new ArrayList<>();
654         list.add(TEST_SUBSCRIPTION);
655         list.add(TEST_SUBSCRIPTION);
656         when(mKeyguardUpdateMonitor.getSimState(anyInt())).thenReturn(
657                 TelephonyManager.SIM_STATE_READY);
658         when(mKeyguardUpdateMonitor.getFilteredSubscriptionInfo()).thenReturn(list);
659 
660         mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();
661 
662         ArgumentCaptor<CarrierTextManager.CarrierTextCallbackInfo> captor =
663                 ArgumentCaptor.forClass(
664                         CarrierTextManager.CarrierTextCallbackInfo.class);
665 
666         mCarrierTextManager.updateCarrierText();
667         FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
668         verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
669 
670         assertEquals(TEST_CARRIER + SEPARATOR + TEST_CARRIER,
671                 captor.getValue().carrierText);
672     }
673 
674     @Test
testCarrierText_oneDisabledSub()675     public void testCarrierText_oneDisabledSub() {
676         reset(mCarrierTextCallback);
677         List<SubscriptionInfo> list = new ArrayList<>();
678         list.add(TEST_SUBSCRIPTION);
679         list.add(TEST_SUBSCRIPTION);
680         when(mKeyguardUpdateMonitor.getSimState(anyInt()))
681                 .thenReturn(TelephonyManager.SIM_STATE_READY)
682                 .thenReturn(TelephonyManager.SIM_STATE_NOT_READY);
683         when(mKeyguardUpdateMonitor.getFilteredSubscriptionInfo()).thenReturn(list);
684 
685         mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();
686 
687         ArgumentCaptor<CarrierTextManager.CarrierTextCallbackInfo> captor =
688                 ArgumentCaptor.forClass(
689                         CarrierTextManager.CarrierTextCallbackInfo.class);
690 
691         mCarrierTextManager.updateCarrierText();
692         FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
693         verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
694 
695         assertEquals(TEST_CARRIER,
696                 captor.getValue().carrierText);
697     }
698 
699     @Test
testCarrierText_firstDisabledSub()700     public void testCarrierText_firstDisabledSub() {
701         reset(mCarrierTextCallback);
702         List<SubscriptionInfo> list = new ArrayList<>();
703         list.add(TEST_SUBSCRIPTION);
704         list.add(TEST_SUBSCRIPTION);
705         when(mKeyguardUpdateMonitor.getSimState(anyInt()))
706                 .thenReturn(TelephonyManager.SIM_STATE_NOT_READY)
707                 .thenReturn(TelephonyManager.SIM_STATE_READY);
708         when(mKeyguardUpdateMonitor.getFilteredSubscriptionInfo()).thenReturn(list);
709 
710         mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();
711 
712         ArgumentCaptor<CarrierTextManager.CarrierTextCallbackInfo> captor =
713                 ArgumentCaptor.forClass(
714                         CarrierTextManager.CarrierTextCallbackInfo.class);
715 
716         mCarrierTextManager.updateCarrierText();
717         FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
718         verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
719 
720         assertEquals(TEST_CARRIER,
721                 captor.getValue().carrierText);
722     }
723 
724     @Test
testCarrierText_threeSubsMiddleDisabled()725     public void testCarrierText_threeSubsMiddleDisabled() {
726         reset(mCarrierTextCallback);
727         List<SubscriptionInfo> list = new ArrayList<>();
728         list.add(TEST_SUBSCRIPTION);
729         list.add(TEST_SUBSCRIPTION);
730         list.add(TEST_SUBSCRIPTION);
731         when(mKeyguardUpdateMonitor.getSimState(anyInt()))
732                 .thenReturn(TelephonyManager.SIM_STATE_READY)
733                 .thenReturn(TelephonyManager.SIM_STATE_NOT_READY)
734                 .thenReturn(TelephonyManager.SIM_STATE_READY);
735         when(mKeyguardUpdateMonitor.getFilteredSubscriptionInfo()).thenReturn(list);
736         mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();
737 
738         ArgumentCaptor<CarrierTextManager.CarrierTextCallbackInfo> captor =
739                 ArgumentCaptor.forClass(
740                         CarrierTextManager.CarrierTextCallbackInfo.class);
741 
742         mCarrierTextManager.updateCarrierText();
743         FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
744         verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
745 
746         assertEquals(TEST_CARRIER + SEPARATOR + TEST_CARRIER,
747                 captor.getValue().carrierText);
748     }
749 
750     @Test
testGetStatusForIccState()751     public void testGetStatusForIccState() {
752         when(mKeyguardUpdateMonitor.isDeviceProvisioned()).thenReturn(false);
753         assertEquals(CarrierTextManager.StatusMode.SimMissingLocked,
754                 mCarrierTextManager.getStatusForIccState(TelephonyManager.SIM_STATE_ABSENT));
755         assertEquals(CarrierTextManager.StatusMode.NetworkLocked,
756                 mCarrierTextManager.getStatusForIccState(
757                         TelephonyManager.SIM_STATE_NETWORK_LOCKED));
758         assertEquals(CarrierTextManager.StatusMode.SimNotReady,
759                 mCarrierTextManager.getStatusForIccState(TelephonyManager.SIM_STATE_NOT_READY));
760         assertEquals(CarrierTextManager.StatusMode.SimLocked,
761                 mCarrierTextManager.getStatusForIccState(
762                         TelephonyManager.SIM_STATE_PIN_REQUIRED));
763         assertEquals(CarrierTextManager.StatusMode.SimPukLocked,
764                 mCarrierTextManager.getStatusForIccState(
765                         TelephonyManager.SIM_STATE_PUK_REQUIRED));
766         assertEquals(CarrierTextManager.StatusMode.Normal,
767                 mCarrierTextManager.getStatusForIccState(TelephonyManager.SIM_STATE_READY));
768         assertEquals(CarrierTextManager.StatusMode.SimMissingLocked,
769                 mCarrierTextManager.getStatusForIccState(
770                         TelephonyManager.SIM_STATE_PERM_DISABLED));
771         assertEquals(CarrierTextManager.StatusMode.SimUnknown,
772                 mCarrierTextManager.getStatusForIccState(TelephonyManager.SIM_STATE_UNKNOWN));
773         assertEquals(CarrierTextManager.StatusMode.SimIoError,
774                 mCarrierTextManager.getStatusForIccState(
775                         TelephonyManager.SIM_STATE_CARD_IO_ERROR));
776         assertEquals(CarrierTextManager.StatusMode.SimRestricted,
777                 mCarrierTextManager.getStatusForIccState(
778                         TelephonyManager.SIM_STATE_CARD_RESTRICTED));
779 
780         when(mKeyguardUpdateMonitor.isDeviceProvisioned()).thenReturn(true);
781         assertEquals(CarrierTextManager.StatusMode.SimMissing,
782                 mCarrierTextManager.getStatusForIccState(TelephonyManager.SIM_STATE_ABSENT));
783         assertEquals(CarrierTextManager.StatusMode.NetworkLocked,
784                 mCarrierTextManager.getStatusForIccState(
785                         TelephonyManager.SIM_STATE_NETWORK_LOCKED));
786         assertEquals(CarrierTextManager.StatusMode.SimNotReady,
787                 mCarrierTextManager.getStatusForIccState(
788                         TelephonyManager.SIM_STATE_NOT_READY));
789         assertEquals(CarrierTextManager.StatusMode.SimLocked,
790                 mCarrierTextManager.getStatusForIccState(
791                         TelephonyManager.SIM_STATE_PIN_REQUIRED));
792         assertEquals(CarrierTextManager.StatusMode.SimPukLocked,
793                 mCarrierTextManager.getStatusForIccState(
794                         TelephonyManager.SIM_STATE_PUK_REQUIRED));
795         assertEquals(CarrierTextManager.StatusMode.Normal,
796                 mCarrierTextManager.getStatusForIccState(TelephonyManager.SIM_STATE_READY));
797         assertEquals(CarrierTextManager.StatusMode.SimPermDisabled,
798                 mCarrierTextManager.getStatusForIccState(
799                         TelephonyManager.SIM_STATE_PERM_DISABLED));
800         assertEquals(CarrierTextManager.StatusMode.SimUnknown,
801                 mCarrierTextManager.getStatusForIccState(TelephonyManager.SIM_STATE_UNKNOWN));
802         assertEquals(CarrierTextManager.StatusMode.SimIoError,
803                 mCarrierTextManager.getStatusForIccState(
804                         TelephonyManager.SIM_STATE_CARD_IO_ERROR));
805         assertEquals(CarrierTextManager.StatusMode.SimRestricted,
806                 mCarrierTextManager.getStatusForIccState(
807                         TelephonyManager.SIM_STATE_CARD_RESTRICTED));
808     }
809 
getContextSpyForStickyBroadcast(Intent returnVal)810     private Context getContextSpyForStickyBroadcast(Intent returnVal) {
811         Context contextSpy = spy(mContext);
812         doReturn(returnVal).when(contextSpy).registerReceiver(eq(null), any(IntentFilter.class));
813         return contextSpy;
814     }
815 }
816