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_DEFAULT_SOURCE; 23 24 import static junit.framework.Assert.assertTrue; 25 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; 34 35 import android.content.Context; 36 import android.net.ConnectivityManager; 37 import android.net.wifi.WifiManager; 38 import android.os.Handler; 39 import android.telephony.SubscriptionInfo; 40 import android.telephony.SubscriptionManager; 41 import android.telephony.TelephonyManager; 42 import android.test.suitebuilder.annotation.SmallTest; 43 import android.testing.AndroidTestingRunner; 44 import android.testing.TestableLooper; 45 46 import com.android.internal.telephony.IccCardConstants; 47 import com.android.systemui.Dependency; 48 import com.android.systemui.SysuiTestCase; 49 import com.android.systemui.keyguard.WakefulnessLifecycle; 50 51 import org.junit.Before; 52 import org.junit.Test; 53 import org.junit.runner.RunWith; 54 import org.mockito.ArgumentCaptor; 55 import org.mockito.Mock; 56 import org.mockito.MockitoAnnotations; 57 58 import java.util.ArrayList; 59 import java.util.HashMap; 60 import java.util.List; 61 62 @SmallTest 63 @RunWith(AndroidTestingRunner.class) 64 @TestableLooper.RunWithLooper 65 public class CarrierTextControllerTest extends SysuiTestCase { 66 67 private static final CharSequence SEPARATOR = " \u2014 "; 68 private static final String TEST_CARRIER = "TEST_CARRIER"; 69 private static final String TEST_CARRIER_2 = "TEST_CARRIER_2"; 70 private static final String TEST_GROUP_UUID = "59b5c870-fc4c-47a4-a99e-9db826b48b24"; 71 private static final int TEST_CARRIER_ID = 1; 72 private static final SubscriptionInfo TEST_SUBSCRIPTION = new SubscriptionInfo(0, "", 0, 73 TEST_CARRIER, TEST_CARRIER, NAME_SOURCE_DEFAULT_SOURCE, 0xFFFFFF, "", 74 DATA_ROAMING_DISABLE, null, null, null, null, false, null, "", false, TEST_GROUP_UUID, 75 TEST_CARRIER_ID, 0); 76 private static final SubscriptionInfo TEST_SUBSCRIPTION_2 = new SubscriptionInfo(0, "", 0, 77 TEST_CARRIER, TEST_CARRIER_2, NAME_SOURCE_DEFAULT_SOURCE, 0xFFFFFF, "", 78 DATA_ROAMING_DISABLE, null, null, null, null, false, null, "", true, TEST_GROUP_UUID, 79 TEST_CARRIER_ID, 0); 80 private static final SubscriptionInfo TEST_SUBSCRIPTION_ROAMING = new SubscriptionInfo(0, "", 0, 81 TEST_CARRIER, TEST_CARRIER, NAME_SOURCE_DEFAULT_SOURCE, 0xFFFFFF, "", 82 DATA_ROAMING_ENABLE, null, null, null, null, false, null, ""); 83 @Mock 84 private WifiManager mWifiManager; 85 @Mock 86 private CarrierTextController.CarrierTextCallback mCarrierTextCallback; 87 @Mock 88 private KeyguardUpdateMonitor mKeyguardUpdateMonitor; 89 @Mock 90 private ConnectivityManager mConnectivityManager; 91 @Mock 92 private TelephonyManager mTelephonyManager; 93 @Mock 94 private SubscriptionManager mSubscriptionManager; 95 private CarrierTextController.CarrierTextCallbackInfo mCarrierTextCallbackInfo; 96 97 private CarrierTextController mCarrierTextController; 98 private TestableLooper mTestableLooper; 99 100 @Before 101 public void setUp() { 102 MockitoAnnotations.initMocks(this); 103 mTestableLooper = TestableLooper.get(this); 104 105 mContext.addMockSystemService(WifiManager.class, mWifiManager); 106 mContext.addMockSystemService(ConnectivityManager.class, mConnectivityManager); 107 mContext.addMockSystemService(TelephonyManager.class, mTelephonyManager); 108 mContext.addMockSystemService(SubscriptionManager.class, mSubscriptionManager); 109 mDependency.injectMockDependency(WakefulnessLifecycle.class); 110 mDependency.injectTestDependency(Dependency.MAIN_HANDLER, 111 new Handler(mTestableLooper.getLooper())); 112 113 mCarrierTextCallbackInfo = new CarrierTextController.CarrierTextCallbackInfo("", 114 new CharSequence[]{}, false, new int[]{}); 115 when(mTelephonyManager.getPhoneCount()).thenReturn(3); 116 117 mCarrierTextController = new TestCarrierTextController(mContext, SEPARATOR, true, true, 118 mKeyguardUpdateMonitor); 119 // This should not start listening on any of the real dependencies 120 mCarrierTextController.setListening(mCarrierTextCallback); 121 mCarrierTextController.updateDisplayOpportunisticSubscriptionCarrierText(false); 122 } 123 124 @Test 125 public void testWrongSlots() { 126 reset(mCarrierTextCallback); 127 when(mKeyguardUpdateMonitor.getSubscriptionInfo(anyBoolean())).thenReturn( 128 new ArrayList<>()); 129 when(mKeyguardUpdateMonitor.getSimState(anyInt())).thenReturn( 130 IccCardConstants.State.CARD_IO_ERROR); 131 // This should not produce an out of bounds error, even though there are no subscriptions 132 mCarrierTextController.mCallback.onSimStateChanged(0, -3, 133 IccCardConstants.State.CARD_IO_ERROR); 134 mCarrierTextController.mCallback.onSimStateChanged(0, 3, IccCardConstants.State.READY); 135 verify(mCarrierTextCallback, never()).updateCarrierInfo(any()); 136 } 137 138 @Test 139 public void testMoreSlotsThanSubs() { 140 reset(mCarrierTextCallback); 141 when(mKeyguardUpdateMonitor.getSubscriptionInfo(anyBoolean())).thenReturn( 142 new ArrayList<>()); 143 144 // STOPSHIP(b/130246708) This line makes sure that SubscriptionManager provides the 145 // same answer as KeyguardUpdateMonitor. Remove when this is addressed 146 when(mSubscriptionManager.getActiveSubscriptionInfoList(anyBoolean())).thenReturn( 147 new ArrayList<>()); 148 149 when(mKeyguardUpdateMonitor.getSimState(anyInt())).thenReturn( 150 IccCardConstants.State.CARD_IO_ERROR); 151 // This should not produce an out of bounds error, even though there are no subscriptions 152 mCarrierTextController.mCallback.onSimStateChanged(0, 1, 153 IccCardConstants.State.CARD_IO_ERROR); 154 155 mTestableLooper.processAllMessages(); 156 verify(mCarrierTextCallback).updateCarrierInfo( 157 any(CarrierTextController.CarrierTextCallbackInfo.class)); 158 } 159 160 @Test 161 public void testCallback() { 162 reset(mCarrierTextCallback); 163 mCarrierTextController.postToCallback(mCarrierTextCallbackInfo); 164 mTestableLooper.processAllMessages(); 165 166 ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor = 167 ArgumentCaptor.forClass( 168 CarrierTextController.CarrierTextCallbackInfo.class); 169 verify(mCarrierTextCallback).updateCarrierInfo(captor.capture()); 170 assertEquals(mCarrierTextCallbackInfo, captor.getValue()); 171 } 172 173 @Test 174 public void testNullingCallback() { 175 reset(mCarrierTextCallback); 176 177 mCarrierTextController.postToCallback(mCarrierTextCallbackInfo); 178 mCarrierTextController.setListening(null); 179 180 // This shouldn't produce NPE 181 mTestableLooper.processAllMessages(); 182 verify(mCarrierTextCallback).updateCarrierInfo(any()); 183 } 184 185 @Test 186 public void testCreateInfo_OneValidSubscription() { 187 reset(mCarrierTextCallback); 188 List<SubscriptionInfo> list = new ArrayList<>(); 189 list.add(TEST_SUBSCRIPTION); 190 when(mKeyguardUpdateMonitor.getSimState(anyInt())).thenReturn(IccCardConstants.State.READY); 191 when(mKeyguardUpdateMonitor.getSubscriptionInfo(anyBoolean())).thenReturn(list); 192 193 mKeyguardUpdateMonitor.mServiceStates = new HashMap<>(); 194 195 ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor = 196 ArgumentCaptor.forClass( 197 CarrierTextController.CarrierTextCallbackInfo.class); 198 199 mCarrierTextController.updateCarrierText(); 200 mTestableLooper.processAllMessages(); 201 verify(mCarrierTextCallback).updateCarrierInfo(captor.capture()); 202 203 CarrierTextController.CarrierTextCallbackInfo info = captor.getValue(); 204 assertEquals(1, info.listOfCarriers.length); 205 assertEquals(TEST_CARRIER, info.listOfCarriers[0]); 206 assertEquals(1, info.subscriptionIds.length); 207 } 208 209 @Test 210 public void testCreateInfo_OneValidSubscriptionWithRoaming() { 211 reset(mCarrierTextCallback); 212 List<SubscriptionInfo> list = new ArrayList<>(); 213 list.add(TEST_SUBSCRIPTION_ROAMING); 214 when(mKeyguardUpdateMonitor.getSimState(anyInt())).thenReturn(IccCardConstants.State.READY); 215 when(mKeyguardUpdateMonitor.getSubscriptionInfo(anyBoolean())).thenReturn(list); 216 217 mKeyguardUpdateMonitor.mServiceStates = new HashMap<>(); 218 219 ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor = 220 ArgumentCaptor.forClass( 221 CarrierTextController.CarrierTextCallbackInfo.class); 222 223 mCarrierTextController.updateCarrierText(); 224 mTestableLooper.processAllMessages(); 225 verify(mCarrierTextCallback).updateCarrierInfo(captor.capture()); 226 227 CarrierTextController.CarrierTextCallbackInfo info = captor.getValue(); 228 assertEquals(1, info.listOfCarriers.length); 229 assertTrue(info.listOfCarriers[0].toString().contains(TEST_CARRIER)); 230 assertEquals(1, info.subscriptionIds.length); 231 } 232 233 @Test 234 public void testCreateInfo_noSubscriptions() { 235 reset(mCarrierTextCallback); 236 when(mKeyguardUpdateMonitor.getSubscriptionInfo(anyBoolean())).thenReturn( 237 new ArrayList<>()); 238 239 ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor = 240 ArgumentCaptor.forClass( 241 CarrierTextController.CarrierTextCallbackInfo.class); 242 243 mCarrierTextController.updateCarrierText(); 244 mTestableLooper.processAllMessages(); 245 verify(mCarrierTextCallback).updateCarrierInfo(captor.capture()); 246 247 CarrierTextController.CarrierTextCallbackInfo info = captor.getValue(); 248 assertEquals(0, info.listOfCarriers.length); 249 assertEquals(0, info.subscriptionIds.length); 250 251 } 252 253 @Test 254 public void testCarrierText_twoValidSubscriptions() { 255 reset(mCarrierTextCallback); 256 List<SubscriptionInfo> list = new ArrayList<>(); 257 list.add(TEST_SUBSCRIPTION); 258 list.add(TEST_SUBSCRIPTION); 259 when(mKeyguardUpdateMonitor.getSimState(anyInt())).thenReturn(IccCardConstants.State.READY); 260 when(mKeyguardUpdateMonitor.getSubscriptionInfo(anyBoolean())).thenReturn(list); 261 262 mKeyguardUpdateMonitor.mServiceStates = new HashMap<>(); 263 264 ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor = 265 ArgumentCaptor.forClass( 266 CarrierTextController.CarrierTextCallbackInfo.class); 267 268 mCarrierTextController.updateCarrierText(); 269 mTestableLooper.processAllMessages(); 270 verify(mCarrierTextCallback).updateCarrierInfo(captor.capture()); 271 272 assertEquals(TEST_CARRIER + SEPARATOR + TEST_CARRIER, 273 captor.getValue().carrierText); 274 } 275 276 @Test 277 public void testCarrierText_oneDisabledSub() { 278 reset(mCarrierTextCallback); 279 List<SubscriptionInfo> list = new ArrayList<>(); 280 list.add(TEST_SUBSCRIPTION); 281 list.add(TEST_SUBSCRIPTION); 282 when(mKeyguardUpdateMonitor.getSimState(anyInt())) 283 .thenReturn(IccCardConstants.State.READY) 284 .thenReturn(IccCardConstants.State.NOT_READY); 285 when(mKeyguardUpdateMonitor.getSubscriptionInfo(anyBoolean())).thenReturn(list); 286 287 mKeyguardUpdateMonitor.mServiceStates = new HashMap<>(); 288 289 ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor = 290 ArgumentCaptor.forClass( 291 CarrierTextController.CarrierTextCallbackInfo.class); 292 293 mCarrierTextController.updateCarrierText(); 294 mTestableLooper.processAllMessages(); 295 verify(mCarrierTextCallback).updateCarrierInfo(captor.capture()); 296 297 assertEquals(TEST_CARRIER, 298 captor.getValue().carrierText); 299 } 300 301 @Test 302 public void testCarrierText_firstDisabledSub() { 303 reset(mCarrierTextCallback); 304 List<SubscriptionInfo> list = new ArrayList<>(); 305 list.add(TEST_SUBSCRIPTION); 306 list.add(TEST_SUBSCRIPTION); 307 when(mKeyguardUpdateMonitor.getSimState(anyInt())) 308 .thenReturn(IccCardConstants.State.NOT_READY) 309 .thenReturn(IccCardConstants.State.READY); 310 when(mKeyguardUpdateMonitor.getSubscriptionInfo(anyBoolean())).thenReturn(list); 311 312 mKeyguardUpdateMonitor.mServiceStates = new HashMap<>(); 313 314 ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor = 315 ArgumentCaptor.forClass( 316 CarrierTextController.CarrierTextCallbackInfo.class); 317 318 mCarrierTextController.updateCarrierText(); 319 mTestableLooper.processAllMessages(); 320 verify(mCarrierTextCallback).updateCarrierInfo(captor.capture()); 321 322 assertEquals(TEST_CARRIER, 323 captor.getValue().carrierText); 324 } 325 326 @Test 327 public void testCarrierText_threeSubsMiddleDisabled() { 328 reset(mCarrierTextCallback); 329 List<SubscriptionInfo> list = new ArrayList<>(); 330 list.add(TEST_SUBSCRIPTION); 331 list.add(TEST_SUBSCRIPTION); 332 list.add(TEST_SUBSCRIPTION); 333 when(mKeyguardUpdateMonitor.getSimState(anyInt())) 334 .thenReturn(IccCardConstants.State.READY) 335 .thenReturn(IccCardConstants.State.NOT_READY) 336 .thenReturn(IccCardConstants.State.READY); 337 when(mKeyguardUpdateMonitor.getSubscriptionInfo(anyBoolean())).thenReturn(list); 338 mKeyguardUpdateMonitor.mServiceStates = new HashMap<>(); 339 340 ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor = 341 ArgumentCaptor.forClass( 342 CarrierTextController.CarrierTextCallbackInfo.class); 343 344 mCarrierTextController.updateCarrierText(); 345 mTestableLooper.processAllMessages(); 346 verify(mCarrierTextCallback).updateCarrierInfo(captor.capture()); 347 348 assertEquals(TEST_CARRIER + SEPARATOR + TEST_CARRIER, 349 captor.getValue().carrierText); 350 } 351 352 @Test 353 public void testCarrierText_GroupedSubWithOpportunisticCarrierText() { 354 reset(mCarrierTextCallback); 355 List<SubscriptionInfo> list = new ArrayList<>(); 356 list.add(TEST_SUBSCRIPTION); 357 list.add(TEST_SUBSCRIPTION_2); 358 when(mKeyguardUpdateMonitor.getSimState(anyInt())) 359 .thenReturn(IccCardConstants.State.READY); 360 361 mKeyguardUpdateMonitor.mServiceStates = new HashMap<>(); 362 mCarrierTextController.updateDisplayOpportunisticSubscriptionCarrierText(true); 363 when(mSubscriptionManager.getActiveSubscriptionInfoList(anyBoolean())).thenReturn(list); 364 365 ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor = 366 ArgumentCaptor.forClass( 367 CarrierTextController.CarrierTextCallbackInfo.class); 368 369 mCarrierTextController.updateCarrierText(); 370 mTestableLooper.processAllMessages(); 371 verify(mCarrierTextCallback).updateCarrierInfo(captor.capture()); 372 373 assertEquals(TEST_CARRIER_2, captor.getValue().carrierText); 374 } 375 376 public static class TestCarrierTextController extends CarrierTextController { 377 private KeyguardUpdateMonitor mKUM; 378 379 public TestCarrierTextController(Context context, CharSequence separator, 380 boolean showAirplaneMode, boolean showMissingSim, KeyguardUpdateMonitor kum) { 381 super(context, separator, showAirplaneMode, showMissingSim); 382 mKUM = kum; 383 } 384 385 @Override 386 public void setListening(CarrierTextCallback callback) { 387 super.setListening(callback); 388 mKeyguardUpdateMonitor = mKUM; 389 } 390 } 391 } 392