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