2 * Copyright (C) 2019 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package com.android.keyguard;
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_DEFAULT_SOURCE;
24 import static junit.framework.Assert.assertTrue;
26 import static org.junit.Assert.assertEquals;
27 import static org.mockito.ArgumentMatchers.any;
28 import static org.mockito.ArgumentMatchers.anyBoolean;
29 import static org.mockito.ArgumentMatchers.anyInt;
30 import static org.mockito.Mockito.never;
31 import static org.mockito.Mockito.reset;
32 import static org.mockito.Mockito.verify;
33 import static org.mockito.Mockito.when;
35 import android.content.Context;
36 import android.net.ConnectivityManager;
37 import android.net.wifi.WifiManager;
38 import android.os.Handler;
39 import android.provider.Settings;
40 import android.telephony.SubscriptionInfo;
41 import android.telephony.SubscriptionManager;
42 import android.telephony.TelephonyManager;
43 import android.test.suitebuilder.annotation.SmallTest;
44 import android.testing.AndroidTestingRunner;
45 import android.testing.TestableLooper;
47 import com.android.internal.telephony.IccCardConstants;
48 import com.android.systemui.Dependency;
49 import com.android.systemui.SysuiTestCase;
50 import com.android.systemui.keyguard.WakefulnessLifecycle;
52 import org.junit.Before;
53 import org.junit.Test;
54 import org.junit.runner.RunWith;
55 import org.mockito.ArgumentCaptor;
56 import org.mockito.Mock;
57 import org.mockito.MockitoAnnotations;
59 import java.util.ArrayList;
60 import java.util.HashMap;
61 import java.util.List;
64 @RunWith(AndroidTestingRunner.class)
65 @TestableLooper.RunWithLooper
66 public class CarrierTextControllerTest extends SysuiTestCase {
68 private static final CharSequence SEPARATOR = " \u2014 ";
69 private static final CharSequence INVALID_CARD_TEXT = "Invalid card";
70 private static final CharSequence AIRPLANE_MODE_TEXT = "Airplane mode";
71 private static final String TEST_CARRIER = "TEST_CARRIER";
72 private static final String TEST_CARRIER_2 = "TEST_CARRIER_2";
73 private static final String TEST_GROUP_UUID = "59b5c870-fc4c-47a4-a99e-9db826b48b24";
74 private static final int TEST_CARRIER_ID = 1;
75 private static final SubscriptionInfo TEST_SUBSCRIPTION = new SubscriptionInfo(0, "", 0,
76 TEST_CARRIER, TEST_CARRIER, NAME_SOURCE_DEFAULT_SOURCE, 0xFFFFFF, "",
77 DATA_ROAMING_DISABLE, null, null, null, null, false, null, "", false, TEST_GROUP_UUID,
79 private static final SubscriptionInfo TEST_SUBSCRIPTION_2 = new SubscriptionInfo(0, "", 0,
80 TEST_CARRIER, TEST_CARRIER_2, NAME_SOURCE_DEFAULT_SOURCE, 0xFFFFFF, "",
81 DATA_ROAMING_DISABLE, null, null, null, null, false, null, "", true, TEST_GROUP_UUID,
83 private static final SubscriptionInfo TEST_SUBSCRIPTION_ROAMING = new SubscriptionInfo(0, "", 0,
84 TEST_CARRIER, TEST_CARRIER, NAME_SOURCE_DEFAULT_SOURCE, 0xFFFFFF, "",
85 DATA_ROAMING_ENABLE, null, null, null, null, false, null, "");
87 private WifiManager mWifiManager;
89 private CarrierTextController.CarrierTextCallback mCarrierTextCallback;
91 private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
93 private ConnectivityManager mConnectivityManager;
95 private TelephonyManager mTelephonyManager;
97 private SubscriptionManager mSubscriptionManager;
98 private CarrierTextController.CarrierTextCallbackInfo mCarrierTextCallbackInfo;
100 private CarrierTextController mCarrierTextController;
101 private TestableLooper mTestableLooper;
104 public void setUp() {
105 MockitoAnnotations.initMocks(this);
106 mTestableLooper = TestableLooper.get(this);
108 mContext.addMockSystemService(WifiManager.class, mWifiManager);
109 mContext.addMockSystemService(ConnectivityManager.class, mConnectivityManager);
110 mContext.addMockSystemService(TelephonyManager.class, mTelephonyManager);
111 mContext.addMockSystemService(SubscriptionManager.class, mSubscriptionManager);
112 mContext.getOrCreateTestableResources().addOverride(
113 R.string.keyguard_sim_error_message_short, INVALID_CARD_TEXT);
114 mContext.getOrCreateTestableResources().addOverride(
115 R.string.airplane_mode, AIRPLANE_MODE_TEXT);
116 mDependency.injectMockDependency(WakefulnessLifecycle.class);
117 mDependency.injectTestDependency(Dependency.MAIN_HANDLER,
118 new Handler(mTestableLooper.getLooper()));
120 mCarrierTextCallbackInfo = new CarrierTextController.CarrierTextCallbackInfo("",
121 new CharSequence[]{}, false, new int[]{});
122 when(mTelephonyManager.getPhoneCount()).thenReturn(3);
124 mCarrierTextController = new TestCarrierTextController(mContext, SEPARATOR, true, true,
125 mKeyguardUpdateMonitor);
126 // This should not start listening on any of the real dependencies
127 mCarrierTextController.setListening(mCarrierTextCallback);
128 mCarrierTextController.updateDisplayOpportunisticSubscriptionCarrierText(false);
132 public void testAirplaneMode() {
133 Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, 1);
134 reset(mCarrierTextCallback);
135 List<SubscriptionInfo> list = new ArrayList<>();
136 list.add(TEST_SUBSCRIPTION);
137 when(mKeyguardUpdateMonitor.getSubscriptionInfo(anyBoolean())).thenReturn(list);
138 when(mKeyguardUpdateMonitor.getSimState(0)).thenReturn(IccCardConstants.State.READY);
139 mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();
141 mCarrierTextController.updateCarrierText();
143 ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor =
144 ArgumentCaptor.forClass(
145 CarrierTextController.CarrierTextCallbackInfo.class);
147 mTestableLooper.processAllMessages();
148 verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
149 assertEquals(AIRPLANE_MODE_TEXT, captor.getValue().carrierText);
153 public void testCardIOError() {
154 reset(mCarrierTextCallback);
155 List<SubscriptionInfo> list = new ArrayList<>();
156 list.add(TEST_SUBSCRIPTION);
157 when(mKeyguardUpdateMonitor.getSubscriptionInfo(anyBoolean())).thenReturn(list);
158 when(mKeyguardUpdateMonitor.getSimState(0)).thenReturn(IccCardConstants.State.READY);
159 when(mKeyguardUpdateMonitor.getSimState(1)).thenReturn(
160 IccCardConstants.State.CARD_IO_ERROR);
161 mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();
163 mCarrierTextController.mCallback.onSimStateChanged(3, 1,
164 IccCardConstants.State.CARD_IO_ERROR);
166 ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor =
167 ArgumentCaptor.forClass(
168 CarrierTextController.CarrierTextCallbackInfo.class);
170 mTestableLooper.processAllMessages();
171 verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
172 assertEquals("TEST_CARRIER" + SEPARATOR + INVALID_CARD_TEXT, captor.getValue().carrierText);
173 // There's only one subscription in the list
174 assertEquals(1, captor.getValue().listOfCarriers.length);
175 assertEquals(TEST_CARRIER, captor.getValue().listOfCarriers[0]);
179 public void testWrongSlots() {
180 reset(mCarrierTextCallback);
181 when(mKeyguardUpdateMonitor.getSubscriptionInfo(anyBoolean())).thenReturn(
183 when(mKeyguardUpdateMonitor.getSimState(anyInt())).thenReturn(
184 IccCardConstants.State.CARD_IO_ERROR);
185 // This should not produce an out of bounds error, even though there are no subscriptions
186 mCarrierTextController.mCallback.onSimStateChanged(0, -3,
187 IccCardConstants.State.CARD_IO_ERROR);
188 mCarrierTextController.mCallback.onSimStateChanged(0, 3, IccCardConstants.State.READY);
189 verify(mCarrierTextCallback, never()).updateCarrierInfo(any());
193 public void testMoreSlotsThanSubs() {
194 reset(mCarrierTextCallback);
195 when(mKeyguardUpdateMonitor.getSubscriptionInfo(anyBoolean())).thenReturn(
198 // STOPSHIP(b/130246708) This line makes sure that SubscriptionManager provides the
199 // same answer as KeyguardUpdateMonitor. Remove when this is addressed
200 when(mSubscriptionManager.getActiveSubscriptionInfoList(anyBoolean())).thenReturn(
203 when(mKeyguardUpdateMonitor.getSimState(anyInt())).thenReturn(
204 IccCardConstants.State.CARD_IO_ERROR);
205 // This should not produce an out of bounds error, even though there are no subscriptions
206 mCarrierTextController.mCallback.onSimStateChanged(0, 1,
207 IccCardConstants.State.CARD_IO_ERROR);
209 mTestableLooper.processAllMessages();
210 verify(mCarrierTextCallback).updateCarrierInfo(
211 any(CarrierTextController.CarrierTextCallbackInfo.class));
215 public void testCallback() {
216 reset(mCarrierTextCallback);
217 mCarrierTextController.postToCallback(mCarrierTextCallbackInfo);
218 mTestableLooper.processAllMessages();
220 ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor =
221 ArgumentCaptor.forClass(
222 CarrierTextController.CarrierTextCallbackInfo.class);
223 verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
224 assertEquals(mCarrierTextCallbackInfo, captor.getValue());
228 public void testNullingCallback() {
229 reset(mCarrierTextCallback);
231 mCarrierTextController.postToCallback(mCarrierTextCallbackInfo);
232 mCarrierTextController.setListening(null);
234 // This shouldn't produce NPE
235 mTestableLooper.processAllMessages();
236 verify(mCarrierTextCallback).updateCarrierInfo(any());
240 public void testCreateInfo_OneValidSubscription() {
241 reset(mCarrierTextCallback);
242 List<SubscriptionInfo> list = new ArrayList<>();
243 list.add(TEST_SUBSCRIPTION);
244 when(mKeyguardUpdateMonitor.getSimState(anyInt())).thenReturn(IccCardConstants.State.READY);
245 when(mKeyguardUpdateMonitor.getSubscriptionInfo(anyBoolean())).thenReturn(list);
247 mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();
249 ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor =
250 ArgumentCaptor.forClass(
251 CarrierTextController.CarrierTextCallbackInfo.class);
253 mCarrierTextController.updateCarrierText();
254 mTestableLooper.processAllMessages();
255 verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
257 CarrierTextController.CarrierTextCallbackInfo info = captor.getValue();
258 assertEquals(1, info.listOfCarriers.length);
259 assertEquals(TEST_CARRIER, info.listOfCarriers[0]);
260 assertEquals(1, info.subscriptionIds.length);
264 public void testCreateInfo_OneValidSubscriptionWithRoaming() {
265 reset(mCarrierTextCallback);
266 List<SubscriptionInfo> list = new ArrayList<>();
267 list.add(TEST_SUBSCRIPTION_ROAMING);
268 when(mKeyguardUpdateMonitor.getSimState(anyInt())).thenReturn(IccCardConstants.State.READY);
269 when(mKeyguardUpdateMonitor.getSubscriptionInfo(anyBoolean())).thenReturn(list);
271 mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();
273 ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor =
274 ArgumentCaptor.forClass(
275 CarrierTextController.CarrierTextCallbackInfo.class);
277 mCarrierTextController.updateCarrierText();
278 mTestableLooper.processAllMessages();
279 verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
281 CarrierTextController.CarrierTextCallbackInfo info = captor.getValue();
282 assertEquals(1, info.listOfCarriers.length);
283 assertTrue(info.listOfCarriers[0].toString().contains(TEST_CARRIER));
284 assertEquals(1, info.subscriptionIds.length);
288 public void testCreateInfo_noSubscriptions() {
289 reset(mCarrierTextCallback);
290 when(mKeyguardUpdateMonitor.getSubscriptionInfo(anyBoolean())).thenReturn(
293 ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor =
294 ArgumentCaptor.forClass(
295 CarrierTextController.CarrierTextCallbackInfo.class);
297 mCarrierTextController.updateCarrierText();
298 mTestableLooper.processAllMessages();
299 verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
301 CarrierTextController.CarrierTextCallbackInfo info = captor.getValue();
302 assertEquals(0, info.listOfCarriers.length);
303 assertEquals(0, info.subscriptionIds.length);
308 public void testCarrierText_twoValidSubscriptions() {
309 reset(mCarrierTextCallback);
310 List<SubscriptionInfo> list = new ArrayList<>();
311 list.add(TEST_SUBSCRIPTION);
312 list.add(TEST_SUBSCRIPTION);
313 when(mKeyguardUpdateMonitor.getSimState(anyInt())).thenReturn(IccCardConstants.State.READY);
314 when(mKeyguardUpdateMonitor.getSubscriptionInfo(anyBoolean())).thenReturn(list);
316 mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();
318 ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor =
319 ArgumentCaptor.forClass(
320 CarrierTextController.CarrierTextCallbackInfo.class);
322 mCarrierTextController.updateCarrierText();
323 mTestableLooper.processAllMessages();
324 verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
326 assertEquals(TEST_CARRIER + SEPARATOR + TEST_CARRIER,
327 captor.getValue().carrierText);
331 public void testCarrierText_oneDisabledSub() {
332 reset(mCarrierTextCallback);
333 List<SubscriptionInfo> list = new ArrayList<>();
334 list.add(TEST_SUBSCRIPTION);
335 list.add(TEST_SUBSCRIPTION);
336 when(mKeyguardUpdateMonitor.getSimState(anyInt()))
337 .thenReturn(IccCardConstants.State.READY)
338 .thenReturn(IccCardConstants.State.NOT_READY);
339 when(mKeyguardUpdateMonitor.getSubscriptionInfo(anyBoolean())).thenReturn(list);
341 mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();
343 ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor =
344 ArgumentCaptor.forClass(
345 CarrierTextController.CarrierTextCallbackInfo.class);
347 mCarrierTextController.updateCarrierText();
348 mTestableLooper.processAllMessages();
349 verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
351 assertEquals(TEST_CARRIER,
352 captor.getValue().carrierText);
356 public void testCarrierText_firstDisabledSub() {
357 reset(mCarrierTextCallback);
358 List<SubscriptionInfo> list = new ArrayList<>();
359 list.add(TEST_SUBSCRIPTION);
360 list.add(TEST_SUBSCRIPTION);
361 when(mKeyguardUpdateMonitor.getSimState(anyInt()))
362 .thenReturn(IccCardConstants.State.NOT_READY)
363 .thenReturn(IccCardConstants.State.READY);
364 when(mKeyguardUpdateMonitor.getSubscriptionInfo(anyBoolean())).thenReturn(list);
366 mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();
368 ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor =
369 ArgumentCaptor.forClass(
370 CarrierTextController.CarrierTextCallbackInfo.class);
372 mCarrierTextController.updateCarrierText();
373 mTestableLooper.processAllMessages();
374 verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
376 assertEquals(TEST_CARRIER,
377 captor.getValue().carrierText);
381 public void testCarrierText_threeSubsMiddleDisabled() {
382 reset(mCarrierTextCallback);
383 List<SubscriptionInfo> list = new ArrayList<>();
384 list.add(TEST_SUBSCRIPTION);
385 list.add(TEST_SUBSCRIPTION);
386 list.add(TEST_SUBSCRIPTION);
387 when(mKeyguardUpdateMonitor.getSimState(anyInt()))
388 .thenReturn(IccCardConstants.State.READY)
389 .thenReturn(IccCardConstants.State.NOT_READY)
390 .thenReturn(IccCardConstants.State.READY);
391 when(mKeyguardUpdateMonitor.getSubscriptionInfo(anyBoolean())).thenReturn(list);
392 mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();
394 ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor =
395 ArgumentCaptor.forClass(
396 CarrierTextController.CarrierTextCallbackInfo.class);
398 mCarrierTextController.updateCarrierText();
399 mTestableLooper.processAllMessages();
400 verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
402 assertEquals(TEST_CARRIER + SEPARATOR + TEST_CARRIER,
403 captor.getValue().carrierText);
407 public void testCarrierText_GroupedSubWithOpportunisticCarrierText() {
408 reset(mCarrierTextCallback);
409 List<SubscriptionInfo> list = new ArrayList<>();
410 list.add(TEST_SUBSCRIPTION);
411 list.add(TEST_SUBSCRIPTION_2);
412 when(mKeyguardUpdateMonitor.getSimState(anyInt()))
413 .thenReturn(IccCardConstants.State.READY);
415 mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();
416 mCarrierTextController.updateDisplayOpportunisticSubscriptionCarrierText(true);
417 when(mSubscriptionManager.getActiveSubscriptionInfoList(anyBoolean())).thenReturn(list);
419 ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor =
420 ArgumentCaptor.forClass(
421 CarrierTextController.CarrierTextCallbackInfo.class);
423 mCarrierTextController.updateCarrierText();
424 mTestableLooper.processAllMessages();
425 verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
427 assertEquals(TEST_CARRIER_2, captor.getValue().carrierText);
430 public static class TestCarrierTextController extends CarrierTextController {
431 private KeyguardUpdateMonitor mKUM;
433 public TestCarrierTextController(Context context, CharSequence separator,
434 boolean showAirplaneMode, boolean showMissingSim, KeyguardUpdateMonitor kum) {
435 super(context, separator, showAirplaneMode, showMissingSim);
440 public void setListening(CarrierTextCallback callback) {
441 super.setListening(callback);
442 mKeyguardUpdateMonitor = mKUM;