1 /* 2 * Copyright (C) 2023 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.systemui.shade.carrier; 18 19 import static com.google.common.truth.Truth.assertThat; 20 21 import static org.junit.Assert.assertEquals; 22 import static org.junit.Assert.assertFalse; 23 import static org.mockito.ArgumentMatchers.any; 24 import static org.mockito.ArgumentMatchers.anyBoolean; 25 import static org.mockito.ArgumentMatchers.anyInt; 26 import static org.mockito.ArgumentMatchers.anyString; 27 import static org.mockito.ArgumentMatchers.eq; 28 import static org.mockito.Mockito.doAnswer; 29 import static org.mockito.Mockito.mock; 30 import static org.mockito.Mockito.never; 31 import static org.mockito.Mockito.reset; 32 import static org.mockito.Mockito.times; 33 import static org.mockito.Mockito.verify; 34 import static org.mockito.Mockito.verifyZeroInteractions; 35 import static org.mockito.Mockito.when; 36 37 import android.content.Context; 38 import android.content.Intent; 39 import android.os.Handler; 40 import android.provider.Settings; 41 import android.testing.AndroidTestingRunner; 42 import android.testing.TestableLooper; 43 import android.view.View; 44 import android.widget.TextView; 45 46 import androidx.test.filters.SmallTest; 47 48 import com.android.keyguard.CarrierTextManager; 49 import com.android.systemui.plugins.ActivityStarter; 50 import com.android.systemui.statusbar.connectivity.IconState; 51 import com.android.systemui.statusbar.connectivity.MobileDataIndicators; 52 import com.android.systemui.statusbar.connectivity.NetworkController; 53 import com.android.systemui.statusbar.connectivity.SignalCallback; 54 import com.android.systemui.statusbar.connectivity.ui.MobileContextProvider; 55 import com.android.systemui.statusbar.pipeline.StatusBarPipelineFlags; 56 import com.android.systemui.statusbar.pipeline.mobile.ui.MobileUiAdapter; 57 import com.android.systemui.statusbar.pipeline.mobile.ui.MobileViewLogger; 58 import com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel.MobileIconsViewModel; 59 import com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel.ShadeCarrierGroupMobileIconViewModel; 60 import com.android.systemui.util.CarrierConfigTracker; 61 import com.android.systemui.util.kotlin.FlowProviderKt; 62 import com.android.systemui.utils.leaks.LeakCheckedTest; 63 import com.android.systemui.utils.os.FakeHandler; 64 65 import org.junit.Before; 66 import org.junit.Test; 67 import org.junit.runner.RunWith; 68 import org.mockito.ArgumentCaptor; 69 import org.mockito.Mock; 70 import org.mockito.MockitoAnnotations; 71 72 import java.util.ArrayList; 73 import java.util.Arrays; 74 import java.util.List; 75 76 import kotlinx.coroutines.flow.MutableStateFlow; 77 78 @RunWith(AndroidTestingRunner.class) 79 @TestableLooper.RunWithLooper 80 @SmallTest 81 public class ShadeCarrierGroupControllerTest extends LeakCheckedTest { 82 83 private static final String SINGLE_CARRIER_TEXT = "singleCarrierText"; 84 private static final String MULTI_CARRIER_TEXT = "multiCarrierText"; 85 private static final String FIRST_CARRIER_NAME = "carrier1"; 86 private static final String SECOND_CARRIER_NAME = "carrier2"; 87 88 private ShadeCarrierGroupController mShadeCarrierGroupController; 89 private SignalCallback mSignalCallback; 90 private CarrierTextManager.CarrierTextCallback mCallback; 91 @Mock 92 private ShadeCarrierGroup mShadeCarrierGroup; 93 @Mock 94 private ActivityStarter mActivityStarter; 95 @Mock 96 private NetworkController mNetworkController; 97 @Mock 98 private CarrierTextManager.Builder mCarrierTextControllerBuilder; 99 @Mock 100 private CarrierTextManager mCarrierTextManager; 101 @Mock 102 private CarrierConfigTracker mCarrierConfigTracker; 103 @Mock 104 private ShadeCarrier mShadeCarrier1; 105 @Mock 106 private ShadeCarrier mShadeCarrier2; 107 @Mock 108 private ShadeCarrier mShadeCarrier3; 109 private TestableLooper mTestableLooper; 110 @Mock 111 private ShadeCarrierGroupController.OnSingleCarrierChangedListener 112 mOnSingleCarrierChangedListener; 113 @Mock 114 private MobileUiAdapter mMobileUiAdapter; 115 @Mock 116 private MobileIconsViewModel mMobileIconsViewModel; 117 @Mock 118 private ShadeCarrierGroupMobileIconViewModel mShadeCarrierGroupMobileIconViewModel; 119 @Mock 120 private MobileViewLogger mMobileViewLogger; 121 @Mock 122 private MobileContextProvider mMobileContextProvider; 123 @Mock 124 private StatusBarPipelineFlags mStatusBarPipelineFlags; 125 126 private final MutableStateFlow<Boolean> mIsVisibleFlow = 127 FlowProviderKt.getMutableStateFlow(true); 128 129 private FakeSlotIndexResolver mSlotIndexResolver; 130 private ClickListenerTextView mNoCarrierTextView; 131 132 @Before setup()133 public void setup() throws Exception { 134 MockitoAnnotations.initMocks(this); 135 injectLeakCheckedDependencies(ALL_SUPPORTED_CLASSES); 136 mTestableLooper = TestableLooper.get(this); 137 Handler handler = new FakeHandler(TestableLooper.get(this).getLooper()); 138 139 when(mNetworkController.hasVoiceCallingFeature()).thenReturn(true); 140 doAnswer(invocation -> mSignalCallback = invocation.getArgument(0)) 141 .when(mNetworkController) 142 .addCallback(any(SignalCallback.class)); 143 144 when(mCarrierTextControllerBuilder.setShowAirplaneMode(anyBoolean())) 145 .thenReturn(mCarrierTextControllerBuilder); 146 when(mCarrierTextControllerBuilder.setShowMissingSim(anyBoolean())) 147 .thenReturn(mCarrierTextControllerBuilder); 148 when(mCarrierTextControllerBuilder.setDebugLocationString(anyString())) 149 .thenReturn(mCarrierTextControllerBuilder); 150 when(mCarrierTextControllerBuilder.build()).thenReturn(mCarrierTextManager); 151 152 doAnswer(invocation -> mCallback = invocation.getArgument(0)) 153 .when(mCarrierTextManager) 154 .setListening(any(CarrierTextManager.CarrierTextCallback.class)); 155 156 mNoCarrierTextView = new ClickListenerTextView(mContext); 157 when(mShadeCarrierGroup.getNoSimTextView()).thenReturn(mNoCarrierTextView); 158 when(mShadeCarrierGroup.getCarrier1View()).thenReturn(mShadeCarrier1); 159 when(mShadeCarrierGroup.getCarrier2View()).thenReturn(mShadeCarrier2); 160 when(mShadeCarrierGroup.getCarrier3View()).thenReturn(mShadeCarrier3); 161 when(mShadeCarrierGroup.getCarrierDivider1()).thenReturn(new View(mContext)); 162 when(mShadeCarrierGroup.getCarrierDivider2()).thenReturn(new View(mContext)); 163 164 mSlotIndexResolver = new FakeSlotIndexResolver(); 165 166 when(mMobileUiAdapter.getMobileIconsViewModel()).thenReturn(mMobileIconsViewModel); 167 168 mShadeCarrierGroupController = new ShadeCarrierGroupController.Builder( 169 mActivityStarter, 170 handler, 171 TestableLooper.get(this).getLooper(), 172 mNetworkController, 173 mCarrierTextControllerBuilder, 174 mContext, 175 mCarrierConfigTracker, 176 mSlotIndexResolver, 177 mMobileUiAdapter, 178 mMobileContextProvider, 179 mStatusBarPipelineFlags 180 ) 181 .setShadeCarrierGroup(mShadeCarrierGroup) 182 .build(); 183 184 mShadeCarrierGroupController.setListening(true); 185 } 186 setupWithNewPipeline()187 private void setupWithNewPipeline() { 188 when(mStatusBarPipelineFlags.useNewShadeCarrierGroupMobileIcons()).thenReturn(true); 189 when(mMobileContextProvider.getMobileContextForSub(anyInt(), any())).thenReturn(mContext); 190 when(mMobileIconsViewModel.getLogger()).thenReturn(mMobileViewLogger); 191 when(mShadeCarrierGroupMobileIconViewModel.isVisible()).thenReturn(mIsVisibleFlow); 192 when(mMobileIconsViewModel.viewModelForSub(anyInt(), any())) 193 .thenReturn(mShadeCarrierGroupMobileIconViewModel); 194 } 195 196 @Test testInitiallyMultiCarrier()197 public void testInitiallyMultiCarrier() { 198 assertFalse(mShadeCarrierGroupController.isSingleCarrier()); 199 } 200 201 @Test // throws no Exception testUpdateCarrierText_sameLengths()202 public void testUpdateCarrierText_sameLengths() { 203 // listOfCarriers length 1, subscriptionIds length 1, anySims false 204 CarrierTextManager.CarrierTextCallbackInfo 205 c1 = new CarrierTextManager.CarrierTextCallbackInfo( 206 SINGLE_CARRIER_TEXT, 207 new CharSequence[]{FIRST_CARRIER_NAME}, 208 false, 209 new int[]{0}); 210 mCallback.updateCarrierInfo(c1); 211 212 // listOfCarriers length 1, subscriptionIds length 1, anySims true 213 CarrierTextManager.CarrierTextCallbackInfo 214 c2 = new CarrierTextManager.CarrierTextCallbackInfo( 215 SINGLE_CARRIER_TEXT, 216 new CharSequence[]{FIRST_CARRIER_NAME}, 217 true, 218 new int[]{0}); 219 mCallback.updateCarrierInfo(c2); 220 221 // listOfCarriers length 2, subscriptionIds length 2, anySims false 222 CarrierTextManager.CarrierTextCallbackInfo 223 c3 = new CarrierTextManager.CarrierTextCallbackInfo( 224 MULTI_CARRIER_TEXT, 225 new CharSequence[]{FIRST_CARRIER_NAME, SECOND_CARRIER_NAME}, 226 false, 227 new int[]{0, 1}); 228 mCallback.updateCarrierInfo(c3); 229 230 // listOfCarriers length 2, subscriptionIds length 2, anySims true 231 CarrierTextManager.CarrierTextCallbackInfo 232 c4 = new CarrierTextManager.CarrierTextCallbackInfo( 233 MULTI_CARRIER_TEXT, 234 new CharSequence[]{FIRST_CARRIER_NAME, SECOND_CARRIER_NAME}, 235 true, 236 new int[]{0, 1}); 237 mCallback.updateCarrierInfo(c4); 238 239 mTestableLooper.processAllMessages(); 240 } 241 242 @Test // throws no Exception testUpdateCarrierText_differentLength()243 public void testUpdateCarrierText_differentLength() { 244 // listOfCarriers length 2, subscriptionIds length 1, anySims false 245 CarrierTextManager.CarrierTextCallbackInfo 246 c1 = new CarrierTextManager.CarrierTextCallbackInfo( 247 MULTI_CARRIER_TEXT, 248 new CharSequence[]{FIRST_CARRIER_NAME, SECOND_CARRIER_NAME}, 249 false, 250 new int[]{0}); 251 mCallback.updateCarrierInfo(c1); 252 253 // listOfCarriers length 2, subscriptionIds length 1, anySims true 254 CarrierTextManager.CarrierTextCallbackInfo 255 c2 = new CarrierTextManager.CarrierTextCallbackInfo( 256 MULTI_CARRIER_TEXT, 257 new CharSequence[]{FIRST_CARRIER_NAME, SECOND_CARRIER_NAME}, 258 true, 259 new int[]{0}); 260 mCallback.updateCarrierInfo(c2); 261 262 // listOfCarriers length 1, subscriptionIds length 2, anySims false 263 CarrierTextManager.CarrierTextCallbackInfo 264 c3 = new CarrierTextManager.CarrierTextCallbackInfo( 265 SINGLE_CARRIER_TEXT, 266 new CharSequence[]{FIRST_CARRIER_NAME}, 267 false, 268 new int[]{0, 1}); 269 mCallback.updateCarrierInfo(c3); 270 271 // listOfCarriers length 1, subscriptionIds length 2, anySims true 272 CarrierTextManager.CarrierTextCallbackInfo 273 c4 = new CarrierTextManager.CarrierTextCallbackInfo( 274 SINGLE_CARRIER_TEXT, 275 new CharSequence[]{FIRST_CARRIER_NAME}, 276 true, 277 new int[]{0, 1}); 278 mCallback.updateCarrierInfo(c4); 279 mTestableLooper.processAllMessages(); 280 } 281 282 @Test // throws no Exception testUpdateCarrierText_invalidSim()283 public void testUpdateCarrierText_invalidSim() { 284 mSlotIndexResolver.overrideInvalid = true; 285 286 CarrierTextManager.CarrierTextCallbackInfo 287 c4 = new CarrierTextManager.CarrierTextCallbackInfo( 288 MULTI_CARRIER_TEXT, 289 new CharSequence[]{FIRST_CARRIER_NAME, SECOND_CARRIER_NAME}, 290 true, 291 new int[]{0, 1}); 292 mCallback.updateCarrierInfo(c4); 293 mTestableLooper.processAllMessages(); 294 } 295 296 @Test // throws no Exception testSetMobileDataIndicators_invalidSim()297 public void testSetMobileDataIndicators_invalidSim() { 298 mSlotIndexResolver.overrideInvalid = true; 299 300 MobileDataIndicators indicators = new MobileDataIndicators( 301 mock(IconState.class), 302 mock(IconState.class), 303 0, 0, true, true, "", "", "", 0, true, true); 304 mSignalCallback.setMobileDataIndicators(indicators); 305 } 306 307 @Test testNoEmptyVisibleView_airplaneMode()308 public void testNoEmptyVisibleView_airplaneMode() { 309 CarrierTextManager.CarrierTextCallbackInfo 310 info = new CarrierTextManager.CarrierTextCallbackInfo( 311 "", 312 new CharSequence[]{""}, 313 true, 314 new int[]{0}, 315 true /* airplaneMode */); 316 mCallback.updateCarrierInfo(info); 317 mTestableLooper.processAllMessages(); 318 assertEquals(View.GONE, mShadeCarrierGroup.getNoSimTextView().getVisibility()); 319 } 320 321 @Test testVisibleView_airplaneMode_WFCOn()322 public void testVisibleView_airplaneMode_WFCOn() { 323 CarrierTextManager.CarrierTextCallbackInfo 324 info = new CarrierTextManager.CarrierTextCallbackInfo( 325 "", 326 new CharSequence[]{FIRST_CARRIER_NAME, ""}, 327 true, 328 new int[]{0, 1}, 329 false /* airplaneMode */); 330 mCallback.updateCarrierInfo(info); 331 mTestableLooper.processAllMessages(); 332 assertEquals(View.VISIBLE, mShadeCarrierGroupController.getShadeCarrierVisibility(0)); 333 } 334 335 @Test testListenerNotCalledOnRegistreation()336 public void testListenerNotCalledOnRegistreation() { 337 mShadeCarrierGroupController 338 .setOnSingleCarrierChangedListener(mOnSingleCarrierChangedListener); 339 340 verify(mOnSingleCarrierChangedListener, never()).onSingleCarrierChanged(anyBoolean()); 341 } 342 343 @Test testSingleCarrier()344 public void testSingleCarrier() { 345 // Only one element in the info 346 CarrierTextManager.CarrierTextCallbackInfo 347 info = new CarrierTextManager.CarrierTextCallbackInfo( 348 SINGLE_CARRIER_TEXT, 349 new CharSequence[]{SINGLE_CARRIER_TEXT}, 350 true, 351 new int[]{0}, 352 false /* airplaneMode */); 353 354 mCallback.updateCarrierInfo(info); 355 mTestableLooper.processAllMessages(); 356 357 verify(mShadeCarrier1).updateState(any(), eq(true)); 358 verify(mShadeCarrier2).updateState(any(), eq(true)); 359 verify(mShadeCarrier3).updateState(any(), eq(true)); 360 } 361 362 @Test testMultiCarrier()363 public void testMultiCarrier() { 364 // More than one element in the info 365 CarrierTextManager.CarrierTextCallbackInfo 366 info = new CarrierTextManager.CarrierTextCallbackInfo( 367 MULTI_CARRIER_TEXT, 368 new CharSequence[]{FIRST_CARRIER_NAME, SECOND_CARRIER_NAME}, 369 true, 370 new int[]{0, 1}, 371 false /* airplaneMode */); 372 373 mCallback.updateCarrierInfo(info); 374 mTestableLooper.processAllMessages(); 375 376 verify(mShadeCarrier1).updateState(any(), eq(false)); 377 verify(mShadeCarrier2).updateState(any(), eq(false)); 378 verify(mShadeCarrier3).updateState(any(), eq(false)); 379 } 380 381 @Test testSingleMultiCarrierSwitch()382 public void testSingleMultiCarrierSwitch() { 383 CarrierTextManager.CarrierTextCallbackInfo 384 singleCarrierInfo = new CarrierTextManager.CarrierTextCallbackInfo( 385 SINGLE_CARRIER_TEXT, 386 new CharSequence[]{FIRST_CARRIER_NAME}, 387 true, 388 new int[]{0}, 389 false /* airplaneMode */); 390 391 CarrierTextManager.CarrierTextCallbackInfo 392 multiCarrierInfo = new CarrierTextManager.CarrierTextCallbackInfo( 393 MULTI_CARRIER_TEXT, 394 new CharSequence[]{FIRST_CARRIER_NAME, SECOND_CARRIER_NAME}, 395 true, 396 new int[]{0, 1}, 397 false /* airplaneMode */); 398 399 mCallback.updateCarrierInfo(singleCarrierInfo); 400 mTestableLooper.processAllMessages(); 401 402 mShadeCarrierGroupController 403 .setOnSingleCarrierChangedListener(mOnSingleCarrierChangedListener); 404 reset(mOnSingleCarrierChangedListener); 405 406 mCallback.updateCarrierInfo(multiCarrierInfo); 407 mTestableLooper.processAllMessages(); 408 verify(mOnSingleCarrierChangedListener).onSingleCarrierChanged(false); 409 410 mCallback.updateCarrierInfo(singleCarrierInfo); 411 mTestableLooper.processAllMessages(); 412 verify(mOnSingleCarrierChangedListener).onSingleCarrierChanged(true); 413 } 414 415 @Test testNoCallbackIfSingleCarrierDoesntChange()416 public void testNoCallbackIfSingleCarrierDoesntChange() { 417 CarrierTextManager.CarrierTextCallbackInfo 418 singleCarrierInfo = new CarrierTextManager.CarrierTextCallbackInfo( 419 SINGLE_CARRIER_TEXT, 420 new CharSequence[]{FIRST_CARRIER_NAME}, 421 true, 422 new int[]{0}, 423 false /* airplaneMode */); 424 425 mCallback.updateCarrierInfo(singleCarrierInfo); 426 mTestableLooper.processAllMessages(); 427 428 mShadeCarrierGroupController 429 .setOnSingleCarrierChangedListener(mOnSingleCarrierChangedListener); 430 431 mCallback.updateCarrierInfo(singleCarrierInfo); 432 mTestableLooper.processAllMessages(); 433 434 verify(mOnSingleCarrierChangedListener, never()).onSingleCarrierChanged(anyBoolean()); 435 } 436 437 @Test testNoCallbackIfMultiCarrierDoesntChange()438 public void testNoCallbackIfMultiCarrierDoesntChange() { 439 CarrierTextManager.CarrierTextCallbackInfo 440 multiCarrierInfo = new CarrierTextManager.CarrierTextCallbackInfo( 441 MULTI_CARRIER_TEXT, 442 new CharSequence[]{FIRST_CARRIER_NAME, SECOND_CARRIER_NAME}, 443 true, 444 new int[]{0, 1}, 445 false /* airplaneMode */); 446 447 mCallback.updateCarrierInfo(multiCarrierInfo); 448 mTestableLooper.processAllMessages(); 449 450 mShadeCarrierGroupController 451 .setOnSingleCarrierChangedListener(mOnSingleCarrierChangedListener); 452 453 mCallback.updateCarrierInfo(multiCarrierInfo); 454 mTestableLooper.processAllMessages(); 455 456 verify(mOnSingleCarrierChangedListener, never()).onSingleCarrierChanged(anyBoolean()); 457 } 458 459 @TestableLooper.RunWithLooper(setAsMainLooper = true) 460 @Test testUpdateModernMobileIcons_addSubscription()461 public void testUpdateModernMobileIcons_addSubscription() { 462 setupWithNewPipeline(); 463 464 mShadeCarrier1.setVisibility(View.GONE); 465 mShadeCarrier2.setVisibility(View.GONE); 466 mShadeCarrier3.setVisibility(View.GONE); 467 468 List<Integer> subIds = new ArrayList<>(); 469 subIds.add(0); 470 mShadeCarrierGroupController.updateModernMobileIcons(subIds); 471 472 verify(mShadeCarrier1).addModernMobileView(any()); 473 verify(mShadeCarrier2, never()).addModernMobileView(any()); 474 verify(mShadeCarrier3, never()).addModernMobileView(any()); 475 476 resetShadeCarriers(); 477 478 subIds.add(1); 479 mShadeCarrierGroupController.updateModernMobileIcons(subIds); 480 481 verify(mShadeCarrier1, times(1)).removeModernMobileView(); 482 483 verify(mShadeCarrier1).addModernMobileView(any()); 484 verify(mShadeCarrier2).addModernMobileView(any()); 485 verify(mShadeCarrier3, never()).addModernMobileView(any()); 486 } 487 488 @TestableLooper.RunWithLooper(setAsMainLooper = true) 489 @Test testUpdateModernMobileIcons_removeSubscription()490 public void testUpdateModernMobileIcons_removeSubscription() { 491 setupWithNewPipeline(); 492 493 List<Integer> subIds = new ArrayList<>(); 494 subIds.add(0); 495 subIds.add(1); 496 mShadeCarrierGroupController.updateModernMobileIcons(subIds); 497 498 verify(mShadeCarrier1).addModernMobileView(any()); 499 verify(mShadeCarrier2).addModernMobileView(any()); 500 verify(mShadeCarrier3, never()).addModernMobileView(any()); 501 502 resetShadeCarriers(); 503 504 subIds.remove(1); 505 mShadeCarrierGroupController.updateModernMobileIcons(subIds); 506 507 verify(mShadeCarrier1, times(1)).removeModernMobileView(); 508 verify(mShadeCarrier2, times(1)).removeModernMobileView(); 509 510 verify(mShadeCarrier1).addModernMobileView(any()); 511 verify(mShadeCarrier2, never()).addModernMobileView(any()); 512 verify(mShadeCarrier3, never()).addModernMobileView(any()); 513 } 514 515 @TestableLooper.RunWithLooper(setAsMainLooper = true) 516 @Test testUpdateModernMobileIcons_removeSubscriptionOutOfOrder()517 public void testUpdateModernMobileIcons_removeSubscriptionOutOfOrder() { 518 setupWithNewPipeline(); 519 520 List<Integer> subIds = new ArrayList<>(); 521 subIds.add(0); 522 subIds.add(1); 523 subIds.add(2); 524 mShadeCarrierGroupController.updateModernMobileIcons(subIds); 525 526 verify(mShadeCarrier1).addModernMobileView(any()); 527 verify(mShadeCarrier2).addModernMobileView(any()); 528 verify(mShadeCarrier3).addModernMobileView(any()); 529 530 resetShadeCarriers(); 531 532 subIds.remove(1); 533 mShadeCarrierGroupController.updateModernMobileIcons(subIds); 534 535 verify(mShadeCarrier1).removeModernMobileView(); 536 verify(mShadeCarrier2).removeModernMobileView(); 537 verify(mShadeCarrier3).removeModernMobileView(); 538 539 verify(mShadeCarrier1).addModernMobileView(any()); 540 verify(mShadeCarrier2, never()).addModernMobileView(any()); 541 verify(mShadeCarrier3).addModernMobileView(any()); 542 } 543 544 @TestableLooper.RunWithLooper(setAsMainLooper = true) 545 @Test testProcessSubIdList_moreSubsThanSimSlots_listLimitedToMax()546 public void testProcessSubIdList_moreSubsThanSimSlots_listLimitedToMax() { 547 setupWithNewPipeline(); 548 549 List<Integer> subIds = Arrays.asList(0, 1, 2, 2); 550 551 assertThat(mShadeCarrierGroupController.processSubIdList(subIds).size()).isEqualTo(3); 552 } 553 554 @TestableLooper.RunWithLooper(setAsMainLooper = true) 555 @Test testProcessSubIdList_invalidSimSlotIndexFilteredOut()556 public void testProcessSubIdList_invalidSimSlotIndexFilteredOut() { 557 setupWithNewPipeline(); 558 559 List<Integer> subIds = Arrays.asList(0, 1, -1); 560 561 List<ShadeCarrierGroupController.IconData> processedSubs = 562 mShadeCarrierGroupController.processSubIdList(subIds); 563 assertThat(processedSubs).hasSize(2); 564 assertThat(processedSubs.get(0).subId).isNotEqualTo(-1); 565 assertThat(processedSubs.get(1).subId).isNotEqualTo(-1); 566 } 567 568 @TestableLooper.RunWithLooper(setAsMainLooper = true) 569 @Test testProcessSubIdList_indexGreaterThanSimSlotsFilteredOut()570 public void testProcessSubIdList_indexGreaterThanSimSlotsFilteredOut() { 571 setupWithNewPipeline(); 572 573 List<Integer> subIds = Arrays.asList(0, 4); 574 575 List<ShadeCarrierGroupController.IconData> processedSubs = 576 mShadeCarrierGroupController.processSubIdList(subIds); 577 assertThat(processedSubs).hasSize(1); 578 assertThat(processedSubs.get(0).subId).isNotEqualTo(4); 579 } 580 581 582 @Test testOnlyInternalViewsHaveClickableListener()583 public void testOnlyInternalViewsHaveClickableListener() { 584 ArgumentCaptor<View.OnClickListener> captor = 585 ArgumentCaptor.forClass(View.OnClickListener.class); 586 587 verify(mShadeCarrier1).setOnClickListener(captor.capture()); 588 verify(mShadeCarrier2).setOnClickListener(captor.getValue()); 589 verify(mShadeCarrier3).setOnClickListener(captor.getValue()); 590 591 assertThat(mNoCarrierTextView.getOnClickListener()).isSameInstanceAs(captor.getValue()); 592 verify(mShadeCarrierGroup, never()).setOnClickListener(any()); 593 } 594 595 @Test testOnClickListenerDoesntStartActivityIfViewNotVisible()596 public void testOnClickListenerDoesntStartActivityIfViewNotVisible() { 597 ArgumentCaptor<View.OnClickListener> captor = 598 ArgumentCaptor.forClass(View.OnClickListener.class); 599 600 verify(mShadeCarrier1).setOnClickListener(captor.capture()); 601 when(mShadeCarrier1.isVisibleToUser()).thenReturn(false); 602 603 captor.getValue().onClick(mShadeCarrier1); 604 verifyZeroInteractions(mActivityStarter); 605 } 606 607 @Test testOnClickListenerLaunchesActivityIfViewVisible()608 public void testOnClickListenerLaunchesActivityIfViewVisible() { 609 ArgumentCaptor<View.OnClickListener> listenerCaptor = 610 ArgumentCaptor.forClass(View.OnClickListener.class); 611 ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class); 612 613 verify(mShadeCarrier1).setOnClickListener(listenerCaptor.capture()); 614 when(mShadeCarrier1.isVisibleToUser()).thenReturn(true); 615 616 listenerCaptor.getValue().onClick(mShadeCarrier1); 617 verify(mActivityStarter) 618 .postStartActivityDismissingKeyguard(intentCaptor.capture(), anyInt()); 619 assertThat(intentCaptor.getValue().getAction()) 620 .isEqualTo(Settings.ACTION_WIRELESS_SETTINGS); 621 } 622 resetShadeCarriers()623 private void resetShadeCarriers() { 624 reset(mShadeCarrier1); 625 reset(mShadeCarrier2); 626 reset(mShadeCarrier3); 627 } 628 629 private class FakeSlotIndexResolver implements ShadeCarrierGroupController.SlotIndexResolver { 630 public boolean overrideInvalid; 631 632 @Override getSlotIndex(int subscriptionId)633 public int getSlotIndex(int subscriptionId) { 634 return overrideInvalid ? -1 : subscriptionId; 635 } 636 } 637 638 private class ClickListenerTextView extends TextView { 639 View.OnClickListener mListener = null; 640 ClickListenerTextView(Context context)641 ClickListenerTextView(Context context) { 642 super(context); 643 } 644 645 @Override setOnClickListener(OnClickListener l)646 public void setOnClickListener(OnClickListener l) { 647 super.setOnClickListener(l); 648 mListener = l; 649 } 650 getOnClickListener()651 View.OnClickListener getOnClickListener() { 652 return mListener; 653 } 654 } 655 } 656