1 /* 2 * Copyright (C) 2017 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.statusbar.phone; 18 19 import static com.android.systemui.qs.dagger.QSFlagsModule.RBC_AVAILABLE; 20 import static com.android.systemui.statusbar.phone.AutoTileManager.DEVICE_CONTROLS; 21 22 import static org.junit.Assert.assertEquals; 23 import static org.junit.Assert.assertFalse; 24 import static org.junit.Assert.assertNull; 25 import static org.junit.Assert.assertTrue; 26 import static org.junit.Assert.fail; 27 import static org.mockito.ArgumentMatchers.any; 28 import static org.mockito.ArgumentMatchers.eq; 29 import static org.mockito.ArgumentMatchers.isNotNull; 30 import static org.mockito.ArgumentMatchers.isNull; 31 import static org.mockito.Mockito.doReturn; 32 import static org.mockito.Mockito.inOrder; 33 import static org.mockito.Mockito.mock; 34 import static org.mockito.Mockito.never; 35 import static org.mockito.Mockito.times; 36 import static org.mockito.Mockito.verify; 37 import static org.mockito.Mockito.verifyNoMoreInteractions; 38 import static org.mockito.Mockito.when; 39 40 import android.content.ComponentName; 41 import android.content.Context; 42 import android.content.pm.PackageManager; 43 import android.hardware.display.ColorDisplayManager; 44 import android.hardware.display.NightDisplayListener; 45 import android.os.Handler; 46 import android.os.UserHandle; 47 import android.testing.AndroidTestingRunner; 48 import android.testing.TestableLooper; 49 import android.testing.TestableLooper.RunWithLooper; 50 51 import androidx.test.filters.SmallTest; 52 53 import com.android.systemui.R; 54 import com.android.systemui.SysuiTestCase; 55 import com.android.systemui.dagger.NightDisplayListenerModule; 56 import com.android.systemui.plugins.qs.QSTile; 57 import com.android.systemui.qs.AutoAddTracker; 58 import com.android.systemui.qs.QSHost; 59 import com.android.systemui.qs.ReduceBrightColorsController; 60 import com.android.systemui.qs.SettingObserver; 61 import com.android.systemui.qs.external.CustomTile; 62 import com.android.systemui.statusbar.policy.CastController; 63 import com.android.systemui.statusbar.policy.CastController.CastDevice; 64 import com.android.systemui.statusbar.policy.DataSaverController; 65 import com.android.systemui.statusbar.policy.DeviceControlsController; 66 import com.android.systemui.statusbar.policy.HotspotController; 67 import com.android.systemui.statusbar.policy.SafetyController; 68 import com.android.systemui.statusbar.policy.WalletController; 69 import com.android.systemui.util.settings.FakeSettings; 70 import com.android.systemui.util.settings.SecureSettings; 71 72 import org.junit.After; 73 import org.junit.Before; 74 import org.junit.Test; 75 import org.junit.runner.RunWith; 76 import org.mockito.Answers; 77 import org.mockito.ArgumentCaptor; 78 import org.mockito.InOrder; 79 import org.mockito.Mock; 80 import org.mockito.Mockito; 81 import org.mockito.MockitoAnnotations; 82 import org.mockito.Spy; 83 import org.mockito.stubbing.Answer; 84 85 import java.util.ArrayList; 86 import java.util.Collections; 87 import java.util.List; 88 89 import javax.inject.Named; 90 91 @RunWith(AndroidTestingRunner.class) 92 @RunWithLooper 93 @SmallTest 94 public class AutoTileManagerTest extends SysuiTestCase { 95 96 private static final String TEST_SETTING = "setting"; 97 private static final String TEST_SPEC = "spec"; 98 private static final String TEST_SETTING_COMPONENT = "setting_component"; 99 private static final String TEST_COMPONENT = "test_pkg/test_cls"; 100 private static final String TEST_CUSTOM_SPEC = "custom(" + TEST_COMPONENT + ")"; 101 private static final String TEST_CUSTOM_SAFETY_CLASS = "safety_cls"; 102 private static final String TEST_CUSTOM_SAFETY_PKG = "safety_pkg"; 103 private static final String TEST_CUSTOM_SAFETY_SPEC = CustomTile.toSpec(new ComponentName( 104 TEST_CUSTOM_SAFETY_PKG, TEST_CUSTOM_SAFETY_CLASS)); 105 private static final String SEPARATOR = AutoTileManager.SETTING_SEPARATOR; 106 107 private static final int USER = 0; 108 109 @Mock private QSHost mQsHost; 110 @Mock private AutoAddTracker mAutoAddTracker; 111 @Mock private CastController mCastController; 112 @Mock private HotspotController mHotspotController; 113 @Mock private DataSaverController mDataSaverController; 114 @Mock private ManagedProfileController mManagedProfileController; 115 @Mock private NightDisplayListener mNightDisplayListener; 116 @Mock(answer = Answers.RETURNS_SELF) 117 private NightDisplayListenerModule.Builder mNightDisplayListenerBuilder; 118 @Mock private ReduceBrightColorsController mReduceBrightColorsController; 119 @Mock private DeviceControlsController mDeviceControlsController; 120 @Mock private WalletController mWalletController; 121 @Mock private SafetyController mSafetyController; 122 @Mock(answer = Answers.RETURNS_SELF) 123 private AutoAddTracker.Builder mAutoAddTrackerBuilder; 124 @Mock private Context mUserContext; 125 @Spy private PackageManager mPackageManager; 126 private final boolean mIsReduceBrightColorsAvailable = true; 127 128 private AutoTileManager mAutoTileManager; // under test 129 130 private SecureSettings mSecureSettings; 131 private ManagedProfileController.Callback mManagedProfileCallback; 132 133 @Before setUp()134 public void setUp() throws Exception { 135 MockitoAnnotations.initMocks(this); 136 mSecureSettings = new FakeSettings(); 137 138 mContext.getOrCreateTestableResources().addOverride( 139 R.array.config_quickSettingsAutoAdd, 140 new String[] { 141 TEST_SETTING + SEPARATOR + TEST_SPEC, 142 TEST_SETTING_COMPONENT + SEPARATOR + TEST_CUSTOM_SPEC 143 } 144 ); 145 mContext.getOrCreateTestableResources().addOverride( 146 com.android.internal.R.bool.config_nightDisplayAvailable, true); 147 mContext.getOrCreateTestableResources().addOverride( 148 R.string.safety_quick_settings_tile_class, TEST_CUSTOM_SAFETY_CLASS); 149 150 when(mAutoAddTrackerBuilder.build()).thenReturn(mAutoAddTracker); 151 when(mQsHost.getUserContext()).thenReturn(mUserContext); 152 when(mUserContext.getUser()).thenReturn(UserHandle.of(USER)); 153 mPackageManager = Mockito.spy(mContext.getPackageManager()); 154 when(mPackageManager.getPermissionControllerPackageName()) 155 .thenReturn(TEST_CUSTOM_SAFETY_PKG); 156 Context context = Mockito.spy(mContext); 157 when(context.getPackageManager()).thenReturn(mPackageManager); 158 when(mNightDisplayListenerBuilder.build()).thenReturn(mNightDisplayListener); 159 160 mAutoTileManager = createAutoTileManager(context); 161 mAutoTileManager.init(); 162 } 163 164 @After tearDown()165 public void tearDown() { 166 mAutoTileManager.destroy(); 167 } 168 createAutoTileManager( Context context, AutoAddTracker.Builder autoAddTrackerBuilder, HotspotController hotspotController, DataSaverController dataSaverController, ManagedProfileController managedProfileController, NightDisplayListenerModule.Builder nightDisplayListenerBuilder, CastController castController, ReduceBrightColorsController reduceBrightColorsController, DeviceControlsController deviceControlsController, WalletController walletController, SafetyController safetyController, @Named(RBC_AVAILABLE) boolean isReduceBrightColorsAvailable)169 private AutoTileManager createAutoTileManager( 170 Context context, 171 AutoAddTracker.Builder autoAddTrackerBuilder, 172 HotspotController hotspotController, 173 DataSaverController dataSaverController, 174 ManagedProfileController managedProfileController, 175 NightDisplayListenerModule.Builder nightDisplayListenerBuilder, 176 CastController castController, 177 ReduceBrightColorsController reduceBrightColorsController, 178 DeviceControlsController deviceControlsController, 179 WalletController walletController, 180 SafetyController safetyController, 181 @Named(RBC_AVAILABLE) boolean isReduceBrightColorsAvailable) { 182 return new AutoTileManager(context, autoAddTrackerBuilder, mQsHost, 183 Handler.createAsync(TestableLooper.get(this).getLooper()), 184 mSecureSettings, 185 hotspotController, 186 dataSaverController, 187 managedProfileController, 188 mNightDisplayListenerBuilder, 189 castController, 190 reduceBrightColorsController, 191 deviceControlsController, 192 walletController, 193 safetyController, 194 isReduceBrightColorsAvailable); 195 } 196 createAutoTileManager(Context context)197 private AutoTileManager createAutoTileManager(Context context) { 198 return createAutoTileManager(context, mAutoAddTrackerBuilder, mHotspotController, 199 mDataSaverController, mManagedProfileController, mNightDisplayListenerBuilder, 200 mCastController, mReduceBrightColorsController, mDeviceControlsController, 201 mWalletController, mSafetyController, mIsReduceBrightColorsAvailable); 202 } 203 204 @Test testCreatedAutoTileManagerIsNotInitialized()205 public void testCreatedAutoTileManagerIsNotInitialized() { 206 AutoAddTracker.Builder builder = mock(AutoAddTracker.Builder.class, Answers.RETURNS_SELF); 207 AutoAddTracker tracker = mock(AutoAddTracker.class); 208 when(builder.build()).thenReturn(tracker); 209 HotspotController hC = mock(HotspotController.class); 210 DataSaverController dSC = mock(DataSaverController.class); 211 ManagedProfileController mPC = mock(ManagedProfileController.class); 212 NightDisplayListenerModule.Builder nDSB = mock(NightDisplayListenerModule.Builder.class); 213 CastController cC = mock(CastController.class); 214 ReduceBrightColorsController rBC = mock(ReduceBrightColorsController.class); 215 DeviceControlsController dCC = mock(DeviceControlsController.class); 216 WalletController wC = mock(WalletController.class); 217 SafetyController sC = mock(SafetyController.class); 218 219 AutoTileManager manager = 220 createAutoTileManager(mock(Context.class), builder, hC, dSC, mPC, nDSB, cC, rBC, 221 dCC, wC, sC, true); 222 223 verify(tracker, never()).initialize(); 224 verify(hC, never()).addCallback(any()); 225 verify(dSC, never()).addCallback(any()); 226 verify(mPC, never()).addCallback(any()); 227 verifyNoMoreInteractions(nDSB); 228 verify(cC, never()).addCallback(any()); 229 verify(rBC, never()).addCallback(any()); 230 verify(dCC, never()).setCallback(any()); 231 verify(wC, never()).getWalletPosition(); 232 verify(sC, never()).addCallback(any()); 233 assertNull(manager.getSecureSettingForKey(TEST_SETTING)); 234 assertNull(manager.getSecureSettingForKey(TEST_SETTING_COMPONENT)); 235 } 236 237 @Test testChangeUserWhenNotInitializedThrows()238 public void testChangeUserWhenNotInitializedThrows() { 239 AutoTileManager manager = createAutoTileManager(mock(Context.class)); 240 241 try { 242 manager.changeUser(UserHandle.of(USER + 1)); 243 fail(); 244 } catch (Exception e) { 245 // This should throw and take this path 246 } 247 } 248 249 @Test testChangeUserCallbacksStoppedAndStarted()250 public void testChangeUserCallbacksStoppedAndStarted() throws Exception { 251 TestableLooper.get(this).runWithLooper(() -> 252 mAutoTileManager.changeUser(UserHandle.of(USER + 1)) 253 ); 254 255 InOrder inOrderHotspot = inOrder(mHotspotController); 256 inOrderHotspot.verify(mHotspotController).removeCallback(any()); 257 inOrderHotspot.verify(mHotspotController).addCallback(any()); 258 259 InOrder inOrderDataSaver = inOrder(mDataSaverController); 260 inOrderDataSaver.verify(mDataSaverController).removeCallback(any()); 261 inOrderDataSaver.verify(mDataSaverController).addCallback(any()); 262 263 InOrder inOrderManagedProfile = inOrder(mManagedProfileController); 264 inOrderManagedProfile.verify(mManagedProfileController).removeCallback(any()); 265 inOrderManagedProfile.verify(mManagedProfileController).addCallback(any()); 266 267 if (ColorDisplayManager.isNightDisplayAvailable(mContext)) { 268 InOrder inOrderNightDisplay = inOrder(mNightDisplayListener); 269 inOrderNightDisplay.verify(mNightDisplayListener).setCallback(isNull()); 270 inOrderNightDisplay.verify(mNightDisplayListener).setCallback(isNotNull()); 271 } 272 273 InOrder inOrderReduceBrightColors = inOrder(mReduceBrightColorsController); 274 inOrderReduceBrightColors.verify(mReduceBrightColorsController).removeCallback(any()); 275 inOrderReduceBrightColors.verify(mReduceBrightColorsController).addCallback(any()); 276 277 InOrder inOrderCast = inOrder(mCastController); 278 inOrderCast.verify(mCastController).removeCallback(any()); 279 inOrderCast.verify(mCastController).addCallback(any()); 280 281 InOrder inOrderDevices = inOrder(mDeviceControlsController); 282 inOrderDevices.verify(mDeviceControlsController).removeCallback(); 283 inOrderDevices.verify(mDeviceControlsController).setCallback(any()); 284 285 verify(mWalletController, times(2)).getWalletPosition(); 286 287 InOrder inOrderSafety = inOrder(mSafetyController); 288 inOrderSafety.verify(mSafetyController).removeCallback(any()); 289 inOrderSafety.verify(mSafetyController).addCallback(any()); 290 291 SettingObserver setting = mAutoTileManager.getSecureSettingForKey(TEST_SETTING); 292 assertEquals(USER + 1, setting.getCurrentUser()); 293 assertTrue(setting.isListening()); 294 } 295 296 @Test testChangeUserSomeCallbacksNotAdded()297 public void testChangeUserSomeCallbacksNotAdded() throws Exception { 298 when(mAutoAddTracker.isAdded("hotspot")).thenReturn(true); 299 when(mAutoAddTracker.isAdded("work")).thenReturn(true); 300 when(mAutoAddTracker.isAdded("cast")).thenReturn(true); 301 when(mAutoAddTracker.isAdded(TEST_SPEC)).thenReturn(true); 302 303 TestableLooper.get(this).runWithLooper(() -> 304 mAutoTileManager.changeUser(UserHandle.of(USER + 1)) 305 ); 306 307 verify(mAutoAddTracker).changeUser(UserHandle.of(USER + 1)); 308 309 InOrder inOrderHotspot = inOrder(mHotspotController); 310 inOrderHotspot.verify(mHotspotController).removeCallback(any()); 311 inOrderHotspot.verify(mHotspotController, never()).addCallback(any()); 312 313 InOrder inOrderDataSaver = inOrder(mDataSaverController); 314 inOrderDataSaver.verify(mDataSaverController).removeCallback(any()); 315 inOrderDataSaver.verify(mDataSaverController).addCallback(any()); 316 317 InOrder inOrderManagedProfile = inOrder(mManagedProfileController); 318 inOrderManagedProfile.verify(mManagedProfileController).removeCallback(any()); 319 inOrderManagedProfile.verify(mManagedProfileController).addCallback(any()); 320 321 if (ColorDisplayManager.isNightDisplayAvailable(mContext)) { 322 InOrder inOrderNightDisplay = inOrder(mNightDisplayListener); 323 inOrderNightDisplay.verify(mNightDisplayListener).setCallback(isNull()); 324 inOrderNightDisplay.verify(mNightDisplayListener).setCallback(isNotNull()); 325 } 326 327 InOrder inOrderReduceBrightColors = inOrder(mReduceBrightColorsController); 328 inOrderReduceBrightColors.verify(mReduceBrightColorsController).removeCallback(any()); 329 inOrderReduceBrightColors.verify(mReduceBrightColorsController).addCallback(any()); 330 331 InOrder inOrderCast = inOrder(mCastController); 332 inOrderCast.verify(mCastController).removeCallback(any()); 333 inOrderCast.verify(mCastController, never()).addCallback(any()); 334 335 InOrder inOrderDevices = inOrder(mDeviceControlsController); 336 inOrderDevices.verify(mDeviceControlsController).removeCallback(); 337 inOrderDevices.verify(mDeviceControlsController).setCallback(any()); 338 339 verify(mWalletController, times(2)).getWalletPosition(); 340 341 InOrder inOrderSafety = inOrder(mSafetyController); 342 inOrderSafety.verify(mSafetyController).removeCallback(any()); 343 inOrderSafety.verify(mSafetyController).addCallback(any()); 344 345 SettingObserver setting = mAutoTileManager.getSecureSettingForKey(TEST_SETTING); 346 assertEquals(USER + 1, setting.getCurrentUser()); 347 assertFalse(setting.isListening()); 348 } 349 350 @Test testGetCurrentUserId()351 public void testGetCurrentUserId() throws Exception { 352 assertEquals(USER, mAutoTileManager.getCurrentUserId()); 353 354 TestableLooper.get(this).runWithLooper(() -> 355 mAutoTileManager.changeUser(UserHandle.of(USER + 100)) 356 ); 357 358 assertEquals(USER + 100, mAutoTileManager.getCurrentUserId()); 359 } 360 361 @Test nightTileAdded_whenActivated()362 public void nightTileAdded_whenActivated() { 363 if (!ColorDisplayManager.isNightDisplayAvailable(mContext)) { 364 return; 365 } 366 mAutoTileManager.mNightDisplayCallback.onActivated(true); 367 verify(mQsHost).addTile("night"); 368 } 369 370 @Test nightTileNotAdded_whenDeactivated()371 public void nightTileNotAdded_whenDeactivated() { 372 if (!ColorDisplayManager.isNightDisplayAvailable(mContext)) { 373 return; 374 } 375 mAutoTileManager.mNightDisplayCallback.onActivated(false); 376 verify(mQsHost, never()).addTile("night"); 377 } 378 379 @Test nightTileAdded_whenNightModeTwilight()380 public void nightTileAdded_whenNightModeTwilight() { 381 if (!ColorDisplayManager.isNightDisplayAvailable(mContext)) { 382 return; 383 } 384 mAutoTileManager.mNightDisplayCallback.onAutoModeChanged( 385 ColorDisplayManager.AUTO_MODE_TWILIGHT); 386 verify(mQsHost).addTile("night"); 387 } 388 389 @Test nightTileAdded_whenNightModeCustom()390 public void nightTileAdded_whenNightModeCustom() { 391 if (!ColorDisplayManager.isNightDisplayAvailable(mContext)) { 392 return; 393 } 394 mAutoTileManager.mNightDisplayCallback.onAutoModeChanged( 395 ColorDisplayManager.AUTO_MODE_CUSTOM_TIME); 396 verify(mQsHost).addTile("night"); 397 } 398 399 @Test nightTileNotAdded_whenNightModeDisabled()400 public void nightTileNotAdded_whenNightModeDisabled() { 401 if (!ColorDisplayManager.isNightDisplayAvailable(mContext)) { 402 return; 403 } 404 mAutoTileManager.mNightDisplayCallback.onAutoModeChanged( 405 ColorDisplayManager.AUTO_MODE_DISABLED); 406 verify(mQsHost, never()).addTile("night"); 407 } 408 409 @Test reduceBrightColorsTileAdded_whenActivated()410 public void reduceBrightColorsTileAdded_whenActivated() { 411 mAutoTileManager.mReduceBrightColorsCallback.onActivated(true); 412 verify(mQsHost).addTile("reduce_brightness"); 413 } 414 415 @Test reduceBrightColorsTileNotAdded_whenDeactivated()416 public void reduceBrightColorsTileNotAdded_whenDeactivated() { 417 mAutoTileManager.mReduceBrightColorsCallback.onActivated(false); 418 verify(mQsHost, never()).addTile("reduce_brightness"); 419 } 420 buildFakeCastDevice(boolean isCasting)421 private static List<CastDevice> buildFakeCastDevice(boolean isCasting) { 422 CastDevice cd = new CastDevice(); 423 cd.state = isCasting ? CastDevice.STATE_CONNECTED : CastDevice.STATE_DISCONNECTED; 424 return Collections.singletonList(cd); 425 } 426 427 @Test castTileAdded_whenDeviceIsCasting()428 public void castTileAdded_whenDeviceIsCasting() { 429 doReturn(buildFakeCastDevice(true)).when(mCastController).getCastDevices(); 430 mAutoTileManager.mCastCallback.onCastDevicesChanged(); 431 verify(mQsHost).addTile("cast"); 432 } 433 434 @Test castTileNotAdded_whenDeviceIsNotCasting()435 public void castTileNotAdded_whenDeviceIsNotCasting() { 436 doReturn(buildFakeCastDevice(false)).when(mCastController).getCastDevices(); 437 mAutoTileManager.mCastCallback.onCastDevicesChanged(); 438 verify(mQsHost, never()).addTile("cast"); 439 } 440 441 @Test testSettingTileAdded_onChanged()442 public void testSettingTileAdded_onChanged() { 443 changeValue(TEST_SETTING, 1); 444 verify(mAutoAddTracker).setTileAdded(TEST_SPEC); 445 verify(mQsHost).addTile(TEST_SPEC); 446 } 447 448 @Test testSettingTileAddedComponentAtEnd_onChanged()449 public void testSettingTileAddedComponentAtEnd_onChanged() { 450 changeValue(TEST_SETTING_COMPONENT, 1); 451 verify(mAutoAddTracker).setTileAdded(TEST_CUSTOM_SPEC); 452 verify(mQsHost).addTile(ComponentName.unflattenFromString(TEST_COMPONENT) 453 , /* end */ true); 454 } 455 456 @Test testSettingTileAdded_onlyOnce()457 public void testSettingTileAdded_onlyOnce() { 458 changeValue(TEST_SETTING, 1); 459 changeValue(TEST_SETTING, 2); 460 verify(mAutoAddTracker).setTileAdded(TEST_SPEC); 461 verify(mQsHost).addTile(TEST_SPEC); 462 } 463 464 @Test testSettingTileNotAdded_onChangedTo0()465 public void testSettingTileNotAdded_onChangedTo0() { 466 changeValue(TEST_SETTING, 0); 467 verify(mAutoAddTracker, never()).setTileAdded(TEST_SPEC); 468 verify(mQsHost, never()).addTile(TEST_SPEC); 469 } 470 471 @Test testSettingTileNotAdded_ifPreviouslyAdded()472 public void testSettingTileNotAdded_ifPreviouslyAdded() { 473 when(mAutoAddTracker.isAdded(TEST_SPEC)).thenReturn(true); 474 475 changeValue(TEST_SETTING, 1); 476 verify(mAutoAddTracker, never()).setTileAdded(TEST_SPEC); 477 verify(mQsHost, never()).addTile(TEST_SPEC); 478 } 479 480 @Test testSafetyTileNotAdded_ifPreviouslyAdded()481 public void testSafetyTileNotAdded_ifPreviouslyAdded() { 482 ComponentName safetyComponent = CustomTile.getComponentFromSpec(TEST_CUSTOM_SAFETY_SPEC); 483 mAutoTileManager.init(); 484 verify(mQsHost, times(1)).addTile(safetyComponent, true); 485 when(mAutoAddTracker.isAdded(TEST_CUSTOM_SAFETY_SPEC)).thenReturn(true); 486 mAutoTileManager.init(); 487 verify(mQsHost, times(1)).addTile(safetyComponent, true); 488 } 489 490 @Test testSafetyTileAdded_onUserChange()491 public void testSafetyTileAdded_onUserChange() { 492 ComponentName safetyComponent = CustomTile.getComponentFromSpec(TEST_CUSTOM_SAFETY_SPEC); 493 mAutoTileManager.init(); 494 verify(mQsHost, times(1)).addTile(safetyComponent, true); 495 when(mAutoAddTracker.isAdded(TEST_CUSTOM_SAFETY_SPEC)).thenReturn(false); 496 mAutoTileManager.changeUser(UserHandle.of(USER + 1)); 497 verify(mQsHost, times(2)).addTile(safetyComponent, true); 498 } 499 500 @Test testSafetyTileRemoved_onSafetyCenterDisable()501 public void testSafetyTileRemoved_onSafetyCenterDisable() { 502 ComponentName safetyComponent = CustomTile.getComponentFromSpec(TEST_CUSTOM_SAFETY_SPEC); 503 mAutoTileManager.init(); 504 when(mAutoAddTracker.isAdded(TEST_CUSTOM_SAFETY_SPEC)).thenReturn(true); 505 mAutoTileManager.mSafetyCallback.onSafetyCenterEnableChanged(false); 506 verify(mQsHost, times(1)).removeTile(TEST_CUSTOM_SAFETY_SPEC); 507 } 508 509 @Test testSafetyTileAdded_onSafetyCenterEnable()510 public void testSafetyTileAdded_onSafetyCenterEnable() { 511 ComponentName safetyComponent = CustomTile.getComponentFromSpec(TEST_CUSTOM_SAFETY_SPEC); 512 mAutoTileManager.init(); 513 verify(mQsHost, times(1)).addTile(safetyComponent, true); 514 mAutoTileManager.mSafetyCallback.onSafetyCenterEnableChanged(false); 515 mAutoTileManager.mSafetyCallback.onSafetyCenterEnableChanged(true); 516 verify(mQsHost, times(2)).addTile(safetyComponent, true); 517 } 518 519 @Test managedProfileAdded_tileAdded()520 public void managedProfileAdded_tileAdded() { 521 when(mAutoAddTracker.isAdded(eq("work"))).thenReturn(false); 522 when(mAutoAddTracker.getRestoredTilePosition(eq("work"))).thenReturn(2); 523 mAutoTileManager = createAutoTileManager(mContext); 524 Mockito.doAnswer((Answer<Object>) invocation -> { 525 mManagedProfileCallback = invocation.getArgument(0); 526 return null; 527 }).when(mManagedProfileController).addCallback(any()); 528 mAutoTileManager.init(); 529 when(mManagedProfileController.hasActiveProfile()).thenReturn(true); 530 531 mManagedProfileCallback.onManagedProfileChanged(); 532 533 verify(mQsHost, times(1)).addTile(eq("work"), eq(2)); 534 verify(mAutoAddTracker, times(1)).setTileAdded(eq("work")); 535 } 536 537 @Test managedProfileRemoved_tileRemoved()538 public void managedProfileRemoved_tileRemoved() { 539 when(mAutoAddTracker.isAdded(eq("work"))).thenReturn(true); 540 mAutoTileManager = createAutoTileManager(mContext); 541 Mockito.doAnswer((Answer<Object>) invocation -> { 542 mManagedProfileCallback = invocation.getArgument(0); 543 return null; 544 }).when(mManagedProfileController).addCallback(any()); 545 mAutoTileManager.init(); 546 when(mManagedProfileController.hasActiveProfile()).thenReturn(false); 547 548 mManagedProfileCallback.onManagedProfileChanged(); 549 550 verify(mQsHost, times(1)).removeTile(eq("work")); 551 verify(mAutoAddTracker, times(1)).setTileRemoved(eq("work")); 552 } 553 554 @Test testAddControlsTileIfNotPresent()555 public void testAddControlsTileIfNotPresent() { 556 String spec = DEVICE_CONTROLS; 557 when(mAutoAddTracker.isAdded(eq(spec))).thenReturn(false); 558 when(mQsHost.getTiles()).thenReturn(new ArrayList<>()); 559 560 mAutoTileManager.init(); 561 ArgumentCaptor<DeviceControlsController.Callback> captor = 562 ArgumentCaptor.forClass(DeviceControlsController.Callback.class); 563 564 verify(mDeviceControlsController).setCallback(captor.capture()); 565 566 captor.getValue().onControlsUpdate(3); 567 verify(mQsHost).addTile(spec, 3); 568 verify(mAutoAddTracker).setTileAdded(spec); 569 } 570 571 @Test testDontAddControlsTileIfPresent()572 public void testDontAddControlsTileIfPresent() { 573 String spec = DEVICE_CONTROLS; 574 when(mAutoAddTracker.isAdded(eq(spec))).thenReturn(false); 575 when(mQsHost.getTiles()).thenReturn(new ArrayList<>()); 576 577 mAutoTileManager.init(); 578 ArgumentCaptor<DeviceControlsController.Callback> captor = 579 ArgumentCaptor.forClass(DeviceControlsController.Callback.class); 580 581 verify(mDeviceControlsController).setCallback(captor.capture()); 582 583 captor.getValue().removeControlsAutoTracker(); 584 verify(mQsHost, never()).addTile(spec, 3); 585 verify(mAutoAddTracker, never()).setTileAdded(spec); 586 verify(mAutoAddTracker).setTileRemoved(spec); 587 } 588 589 @Test testRemoveControlsTileFromTrackerWhenRequested()590 public void testRemoveControlsTileFromTrackerWhenRequested() { 591 String spec = "controls"; 592 when(mAutoAddTracker.isAdded(eq(spec))).thenReturn(true); 593 QSTile mockTile = mock(QSTile.class); 594 when(mockTile.getTileSpec()).thenReturn(spec); 595 when(mQsHost.getTiles()).thenReturn(List.of(mockTile)); 596 597 mAutoTileManager.init(); 598 ArgumentCaptor<DeviceControlsController.Callback> captor = 599 ArgumentCaptor.forClass(DeviceControlsController.Callback.class); 600 601 verify(mDeviceControlsController).setCallback(captor.capture()); 602 603 captor.getValue().onControlsUpdate(3); 604 verify(mQsHost, never()).addTile(spec, 3); 605 verify(mAutoAddTracker, never()).setTileAdded(spec); 606 } 607 608 609 @Test testEmptyArray_doesNotCrash()610 public void testEmptyArray_doesNotCrash() { 611 mContext.getOrCreateTestableResources().addOverride( 612 R.array.config_quickSettingsAutoAdd, new String[0]); 613 createAutoTileManager(mContext).destroy(); 614 } 615 616 @Test testMissingConfig_doesNotCrash()617 public void testMissingConfig_doesNotCrash() { 618 mContext.getOrCreateTestableResources().addOverride( 619 R.array.config_quickSettingsAutoAdd, null); 620 createAutoTileManager(mContext).destroy(); 621 } 622 623 @Test testUserChange_newNightDisplayListenerCreated()624 public void testUserChange_newNightDisplayListenerCreated() { 625 UserHandle newUser = UserHandle.of(1000); 626 mAutoTileManager.changeUser(newUser); 627 InOrder inOrder = inOrder(mNightDisplayListenerBuilder); 628 inOrder.verify(mNightDisplayListenerBuilder).setUser(newUser.getIdentifier()); 629 inOrder.verify(mNightDisplayListenerBuilder).build(); 630 } 631 632 // Will only notify if it's listening changeValue(String key, int value)633 private void changeValue(String key, int value) { 634 mSecureSettings.putIntForUser(key, value, USER); 635 TestableLooper.get(this).processAllMessages(); 636 } 637 } 638