1 /*
2  * Copyright (C) 2021 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 
20 import static android.app.StatusBarManager.DISABLE2_SYSTEM_ICONS;
21 import static android.app.StatusBarManager.DISABLE_SYSTEM_INFO;
22 
23 import static com.android.systemui.Flags.FLAG_UPDATE_USER_SWITCHER_BACKGROUND;
24 import static com.android.systemui.statusbar.StatusBarState.KEYGUARD;
25 import static com.android.systemui.statusbar.StatusBarState.SHADE;
26 
27 import static com.google.common.truth.Truth.assertThat;
28 
29 import static org.junit.Assert.assertFalse;
30 import static org.junit.Assert.assertTrue;
31 import static org.mockito.ArgumentMatchers.any;
32 import static org.mockito.ArgumentMatchers.anyBoolean;
33 import static org.mockito.Mockito.clearInvocations;
34 import static org.mockito.Mockito.never;
35 import static org.mockito.Mockito.reset;
36 import static org.mockito.Mockito.spy;
37 import static org.mockito.Mockito.verify;
38 import static org.mockito.Mockito.when;
39 
40 import android.os.UserHandle;
41 import android.os.UserManager;
42 import android.platform.test.annotations.DisableFlags;
43 import android.platform.test.annotations.EnableFlags;
44 import android.provider.Settings;
45 import android.testing.TestableLooper;
46 import android.view.LayoutInflater;
47 import android.view.View;
48 
49 import androidx.test.ext.junit.runners.AndroidJUnit4;
50 import androidx.test.filters.SmallTest;
51 
52 import com.android.keyguard.CarrierTextController;
53 import com.android.keyguard.KeyguardUpdateMonitor;
54 import com.android.keyguard.KeyguardUpdateMonitorCallback;
55 import com.android.keyguard.TestScopeProvider;
56 import com.android.keyguard.logging.KeyguardLogger;
57 import com.android.systemui.SysuiTestCase;
58 import com.android.systemui.battery.BatteryMeterViewController;
59 import com.android.systemui.bouncer.data.repository.FakeKeyguardBouncerRepository;
60 import com.android.systemui.common.ui.data.repository.FakeConfigurationRepository;
61 import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor;
62 import com.android.systemui.flags.DisableSceneContainer;
63 import com.android.systemui.flags.EnableSceneContainer;
64 import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository;
65 import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor;
66 import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor;
67 import com.android.systemui.kosmos.KosmosJavaAdapter;
68 import com.android.systemui.plugins.statusbar.StatusBarStateController;
69 import com.android.systemui.power.domain.interactor.PowerInteractorFactory;
70 import com.android.systemui.res.R;
71 import com.android.systemui.shade.ShadeViewStateProvider;
72 import com.android.systemui.shade.data.repository.FakeShadeRepository;
73 import com.android.systemui.statusbar.CommandQueue;
74 import com.android.systemui.statusbar.SysuiStatusBarStateController;
75 import com.android.systemui.statusbar.data.repository.FakeKeyguardStatusBarRepository;
76 import com.android.systemui.statusbar.domain.interactor.KeyguardStatusBarInteractor;
77 import com.android.systemui.statusbar.events.SystemStatusAnimationScheduler;
78 import com.android.systemui.statusbar.phone.ui.StatusBarIconController;
79 import com.android.systemui.statusbar.phone.ui.TintedIconManager;
80 import com.android.systemui.statusbar.policy.BatteryController;
81 import com.android.systemui.statusbar.policy.ConfigurationController;
82 import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
83 import com.android.systemui.statusbar.policy.KeyguardStateController;
84 import com.android.systemui.statusbar.policy.UserInfoController;
85 import com.android.systemui.statusbar.ui.viewmodel.KeyguardStatusBarViewModel;
86 import com.android.systemui.user.ui.viewmodel.StatusBarUserChipViewModel;
87 import com.android.systemui.util.concurrency.FakeExecutor;
88 import com.android.systemui.util.settings.SecureSettings;
89 import com.android.systemui.util.time.FakeSystemClock;
90 
91 import kotlinx.coroutines.test.TestScope;
92 
93 import org.junit.Before;
94 import org.junit.Test;
95 import org.junit.runner.RunWith;
96 import org.mockito.ArgumentCaptor;
97 import org.mockito.Captor;
98 import org.mockito.Mock;
99 import org.mockito.MockitoAnnotations;
100 
101 @SmallTest
102 @RunWith(AndroidJUnit4.class)
103 @TestableLooper.RunWithLooper
104 public class KeyguardStatusBarViewControllerTest extends SysuiTestCase {
105     @Mock
106     private CarrierTextController mCarrierTextController;
107     @Mock
108     private ConfigurationController mConfigurationController;
109     @Mock
110     private SystemStatusAnimationScheduler mAnimationScheduler;
111     @Mock
112     private BatteryController mBatteryController;
113     @Mock
114     private UserInfoController mUserInfoController;
115     @Mock
116     private StatusBarIconController mStatusBarIconController;
117     @Mock
118     private TintedIconManager.Factory mIconManagerFactory;
119     @Mock
120     private TintedIconManager mIconManager;
121     @Mock
122     private BatteryMeterViewController mBatteryMeterViewController;
123     @Mock
124     private KeyguardStateController mKeyguardStateController;
125     @Mock
126     private KeyguardBypassController mKeyguardBypassController;
127     @Mock
128     private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
129     @Mock
130     private BiometricUnlockController mBiometricUnlockController;
131     @Mock
132     private SysuiStatusBarStateController mStatusBarStateController;
133     @Mock
134     private StatusBarContentInsetsProvider mStatusBarContentInsetsProvider;
135     @Mock
136     private UserManager mUserManager;
137     @Mock
138     private StatusBarUserChipViewModel mStatusBarUserChipViewModel;
139     @Captor
140     private ArgumentCaptor<ConfigurationListener> mConfigurationListenerCaptor;
141     @Captor
142     private ArgumentCaptor<KeyguardUpdateMonitorCallback> mKeyguardCallbackCaptor;
143     @Mock private SecureSettings mSecureSettings;
144     @Mock private CommandQueue mCommandQueue;
145     @Mock private KeyguardLogger mLogger;
146     @Mock private StatusOverlayHoverListenerFactory mStatusOverlayHoverListenerFactory;
147 
148     private TestShadeViewStateProvider mShadeViewStateProvider;
149     private KeyguardStatusBarView mKeyguardStatusBarView;
150     private KeyguardStatusBarViewController mController;
151     private FakeExecutor mFakeExecutor = new FakeExecutor(new FakeSystemClock());
152     private final FakeExecutor mBackgroundExecutor = new FakeExecutor(new FakeSystemClock());
153     private final TestScope mTestScope = TestScopeProvider.getTestScope();
154     private final FakeKeyguardRepository mKeyguardRepository = new FakeKeyguardRepository();
155     private final KosmosJavaAdapter mKosmos = new KosmosJavaAdapter(this);
156     private KeyguardInteractor mKeyguardInteractor;
157     private KeyguardStatusBarViewModel mViewModel;
158 
159     @Before
setup()160     public void setup() throws Exception {
161         mShadeViewStateProvider = new TestShadeViewStateProvider();
162 
163         MockitoAnnotations.initMocks(this);
164 
165         when(mIconManagerFactory.create(any(), any())).thenReturn(mIconManager);
166         KeyguardTransitionInteractor keyguardTransitionInteractor =
167                 mKosmos.getKeyguardTransitionInteractor();
168         mKeyguardInteractor = new KeyguardInteractor(
169                 mKeyguardRepository,
170                 mCommandQueue,
171                 PowerInteractorFactory.create().getPowerInteractor(),
172                 new FakeKeyguardBouncerRepository(),
173                 new ConfigurationInteractor(new FakeConfigurationRepository()),
174                 new FakeShadeRepository(),
175                 keyguardTransitionInteractor,
176                 () -> mKosmos.getSceneInteractor(),
177                 () -> mKosmos.getFromGoneTransitionInteractor(),
178                 () -> mKosmos.getFromLockscreenTransitionInteractor(),
179                 () -> mKosmos.getSharedNotificationContainerInteractor(),
180                 mTestScope);
181         mViewModel =
182                 new KeyguardStatusBarViewModel(
183                         mTestScope.getBackgroundScope(),
184                         mKosmos.getHeadsUpNotificationInteractor(),
185                         mKeyguardInteractor,
186                         new KeyguardStatusBarInteractor(new FakeKeyguardStatusBarRepository()),
187                         mBatteryController);
188 
189         allowTestableLooperAsMainThread();
190         TestableLooper.get(this).runWithLooper(() -> {
191             mKeyguardStatusBarView =
192                     spy((KeyguardStatusBarView) LayoutInflater.from(mContext)
193                             .inflate(R.layout.keyguard_status_bar, null));
194             when(mKeyguardStatusBarView.getDisplay()).thenReturn(mContext.getDisplay());
195         });
196 
197         mController = createController();
198     }
199 
createController()200     private KeyguardStatusBarViewController createController() {
201         return new KeyguardStatusBarViewController(
202                 mKeyguardStatusBarView,
203                 mCarrierTextController,
204                 mConfigurationController,
205                 mAnimationScheduler,
206                 mBatteryController,
207                 mUserInfoController,
208                 mStatusBarIconController,
209                 mIconManagerFactory,
210                 mBatteryMeterViewController,
211                 mShadeViewStateProvider,
212                 mKeyguardStateController,
213                 mKeyguardBypassController,
214                 mKeyguardUpdateMonitor,
215                 mViewModel,
216                 mBiometricUnlockController,
217                 mStatusBarStateController,
218                 mStatusBarContentInsetsProvider,
219                 mUserManager,
220                 mStatusBarUserChipViewModel,
221                 mSecureSettings,
222                 mCommandQueue,
223                 mFakeExecutor,
224                 mBackgroundExecutor,
225                 mLogger,
226                 mStatusOverlayHoverListenerFactory,
227                 mKosmos.getCommunalSceneInteractor()
228         );
229     }
230 
231     @Test
232     @EnableFlags(FLAG_UPDATE_USER_SWITCHER_BACKGROUND)
onViewAttached_updateUserSwitcherFlagEnabled_callbacksRegistered()233     public void onViewAttached_updateUserSwitcherFlagEnabled_callbacksRegistered() {
234         mController.onViewAttached();
235 
236         runAllScheduled();
237         verify(mConfigurationController).addCallback(any());
238         verify(mAnimationScheduler).addCallback(any());
239         verify(mUserInfoController).addCallback(any());
240         verify(mCommandQueue).addCallback(any());
241         verify(mStatusBarIconController).addIconGroup(any());
242         verify(mUserManager).isUserSwitcherEnabled(anyBoolean());
243     }
244 
245     @Test
246     @DisableFlags(FLAG_UPDATE_USER_SWITCHER_BACKGROUND)
onViewAttached_updateUserSwitcherFlagDisabled_callbacksRegistered()247     public void onViewAttached_updateUserSwitcherFlagDisabled_callbacksRegistered() {
248         mController.onViewAttached();
249 
250         verify(mConfigurationController).addCallback(any());
251         verify(mAnimationScheduler).addCallback(any());
252         verify(mUserInfoController).addCallback(any());
253         verify(mCommandQueue).addCallback(any());
254         verify(mStatusBarIconController).addIconGroup(any());
255         verify(mUserManager).isUserSwitcherEnabled(anyBoolean());
256     }
257 
258     @Test
259     @EnableFlags(FLAG_UPDATE_USER_SWITCHER_BACKGROUND)
260     public void
onConfigurationChanged_updateUserSwitcherFlagEnabled_updatesUserSwitcherVisibility()261             onConfigurationChanged_updateUserSwitcherFlagEnabled_updatesUserSwitcherVisibility() {
262         mController.onViewAttached();
263         runAllScheduled();
264         verify(mConfigurationController).addCallback(mConfigurationListenerCaptor.capture());
265         clearInvocations(mUserManager);
266         clearInvocations(mKeyguardStatusBarView);
267 
268         mConfigurationListenerCaptor.getValue().onConfigChanged(null);
269 
270         runAllScheduled();
271         verify(mUserManager).isUserSwitcherEnabled(anyBoolean());
272         verify(mKeyguardStatusBarView).setUserSwitcherEnabled(anyBoolean());
273     }
274 
275     @Test
276     @DisableFlags(FLAG_UPDATE_USER_SWITCHER_BACKGROUND)
277     public void
onConfigurationChanged_updateUserSwitcherFlagDisabled_updatesUserSwitcherVisibility()278             onConfigurationChanged_updateUserSwitcherFlagDisabled_updatesUserSwitcherVisibility() {
279         mController.onViewAttached();
280         verify(mConfigurationController).addCallback(mConfigurationListenerCaptor.capture());
281         clearInvocations(mUserManager);
282         clearInvocations(mKeyguardStatusBarView);
283 
284         mConfigurationListenerCaptor.getValue().onConfigChanged(null);
285         verify(mUserManager).isUserSwitcherEnabled(anyBoolean());
286         verify(mKeyguardStatusBarView).setUserSwitcherEnabled(anyBoolean());
287     }
288 
289     @Test
290     @EnableFlags(FLAG_UPDATE_USER_SWITCHER_BACKGROUND)
291     public void
onKeyguardVisibilityChanged_userSwitcherFlagEnabled_updatesUserSwitcherVisibility()292             onKeyguardVisibilityChanged_userSwitcherFlagEnabled_updatesUserSwitcherVisibility() {
293         mController.onViewAttached();
294         runAllScheduled();
295         verify(mKeyguardUpdateMonitor).registerCallback(mKeyguardCallbackCaptor.capture());
296         clearInvocations(mUserManager);
297         clearInvocations(mKeyguardStatusBarView);
298 
299         mKeyguardCallbackCaptor.getValue().onKeyguardVisibilityChanged(true);
300 
301         runAllScheduled();
302         verify(mUserManager).isUserSwitcherEnabled(anyBoolean());
303         verify(mKeyguardStatusBarView).setUserSwitcherEnabled(anyBoolean());
304     }
305 
306     @Test
307     @DisableFlags(FLAG_UPDATE_USER_SWITCHER_BACKGROUND)
308     public void
onKeyguardVisibilityChanged_userSwitcherFlagDisabled_updatesUserSwitcherVisibility()309             onKeyguardVisibilityChanged_userSwitcherFlagDisabled_updatesUserSwitcherVisibility() {
310         mController.onViewAttached();
311         verify(mKeyguardUpdateMonitor).registerCallback(mKeyguardCallbackCaptor.capture());
312         clearInvocations(mUserManager);
313         clearInvocations(mKeyguardStatusBarView);
314 
315         mKeyguardCallbackCaptor.getValue().onKeyguardVisibilityChanged(true);
316         verify(mUserManager).isUserSwitcherEnabled(anyBoolean());
317         verify(mKeyguardStatusBarView).setUserSwitcherEnabled(anyBoolean());
318     }
319 
320     @Test
onViewDetached_callbacksUnregistered()321     public void onViewDetached_callbacksUnregistered() {
322         // Set everything up first.
323         mController.onViewAttached();
324 
325         mController.onViewDetached();
326 
327         verify(mConfigurationController).removeCallback(any());
328         verify(mAnimationScheduler).removeCallback(any());
329         verify(mUserInfoController).removeCallback(any());
330         verify(mCommandQueue).removeCallback(any());
331         verify(mStatusBarIconController).removeIconGroup(any());
332     }
333 
334     @Test
335     @DisableSceneContainer
onViewReAttached_flagOff_iconManagerNotReRegistered()336     public void onViewReAttached_flagOff_iconManagerNotReRegistered() {
337         mController.onViewAttached();
338         mController.onViewDetached();
339         reset(mStatusBarIconController);
340 
341         mController.onViewAttached();
342 
343         verify(mStatusBarIconController, never()).addIconGroup(any());
344     }
345 
346     @Test
347     @EnableSceneContainer
onViewReAttached_flagOn_iconManagerReRegistered()348     public void onViewReAttached_flagOn_iconManagerReRegistered() {
349         mController.onViewAttached();
350         mController.onViewDetached();
351         reset(mStatusBarIconController);
352 
353         mController.onViewAttached();
354 
355         verify(mStatusBarIconController).addIconGroup(any());
356     }
357 
358     @Test
setBatteryListening_true_callbackAdded()359     public void setBatteryListening_true_callbackAdded() {
360         mController.setBatteryListening(true);
361 
362         verify(mBatteryController).addCallback(any());
363     }
364 
365     @Test
setBatteryListening_false_callbackRemoved()366     public void setBatteryListening_false_callbackRemoved() {
367         // First set to true so that we know setting to false is a change in state.
368         mController.setBatteryListening(true);
369 
370         mController.setBatteryListening(false);
371 
372         verify(mBatteryController).removeCallback(any());
373     }
374 
375     @Test
setBatteryListening_trueThenTrue_callbackAddedOnce()376     public void setBatteryListening_trueThenTrue_callbackAddedOnce() {
377         mController.setBatteryListening(true);
378         mController.setBatteryListening(true);
379 
380         verify(mBatteryController).addCallback(any());
381     }
382 
383     @Test
384     @EnableSceneContainer
setBatteryListening_true_flagOn_callbackNotAdded()385     public void setBatteryListening_true_flagOn_callbackNotAdded() {
386         mController.setBatteryListening(true);
387 
388         verify(mBatteryController, never()).addCallback(any());
389     }
390 
391     @Test
updateTopClipping_viewClippingUpdated()392     public void updateTopClipping_viewClippingUpdated() {
393         int viewTop = 20;
394         mKeyguardStatusBarView.setTop(viewTop);
395         int notificationPanelTop = 30;
396 
397         mController.updateTopClipping(notificationPanelTop);
398 
399         assertThat(mKeyguardStatusBarView.getClipBounds().top).isEqualTo(
400                 notificationPanelTop - viewTop);
401     }
402 
403     @Test
setNotTopClipping_viewClippingUpdatedToZero()404     public void setNotTopClipping_viewClippingUpdatedToZero() {
405         // Start out with some amount of top clipping.
406         mController.updateTopClipping(50);
407         assertThat(mKeyguardStatusBarView.getClipBounds().top).isGreaterThan(0);
408 
409         mController.setNoTopClipping();
410 
411         assertThat(mKeyguardStatusBarView.getClipBounds().top).isEqualTo(0);
412     }
413 
414     @Test
updateViewState_alphaAndVisibilityGiven_viewUpdated()415     public void updateViewState_alphaAndVisibilityGiven_viewUpdated() {
416         // Verify the initial values so we know the method triggers changes.
417         assertThat(mKeyguardStatusBarView.getAlpha()).isEqualTo(1f);
418         assertThat(mKeyguardStatusBarView.getVisibility()).isEqualTo(View.VISIBLE);
419 
420         float newAlpha = 0.5f;
421         int newVisibility = View.INVISIBLE;
422         mController.updateViewState(newAlpha, newVisibility);
423 
424         assertThat(mKeyguardStatusBarView.getAlpha()).isEqualTo(newAlpha);
425         assertThat(mKeyguardStatusBarView.getVisibility()).isEqualTo(newVisibility);
426     }
427 
428     @Test
updateViewState_paramVisibleButIsDisabled_viewIsInvisible()429     public void updateViewState_paramVisibleButIsDisabled_viewIsInvisible() {
430         mController.onViewAttached();
431         setDisableSystemIcons(true);
432 
433         mController.updateViewState(1f, View.VISIBLE);
434 
435         // Since we're disabled, we stay invisible
436         assertThat(mKeyguardStatusBarView.getVisibility()).isEqualTo(View.INVISIBLE);
437     }
438 
439     @Test
updateViewState_notKeyguardState_nothingUpdated()440     public void updateViewState_notKeyguardState_nothingUpdated() {
441         mController.onViewAttached();
442         updateStateToNotKeyguard();
443 
444         float oldAlpha = mKeyguardStatusBarView.getAlpha();
445 
446         mController.updateViewState();
447 
448         assertThat(mKeyguardStatusBarView.getAlpha()).isEqualTo(oldAlpha);
449     }
450 
451     @Test
updateViewState_bypassEnabledAndShouldListenForFace_viewHidden()452     public void updateViewState_bypassEnabledAndShouldListenForFace_viewHidden() {
453         mController.onViewAttached();
454         updateStateToKeyguard();
455         assertThat(mKeyguardStatusBarView.getVisibility()).isEqualTo(View.VISIBLE);
456 
457         when(mKeyguardUpdateMonitor.shouldListenForFace()).thenReturn(true);
458         when(mKeyguardBypassController.getBypassEnabled()).thenReturn(true);
459         onFinishedGoingToSleep();
460 
461         mController.updateViewState();
462 
463         assertThat(mKeyguardStatusBarView.getVisibility()).isEqualTo(View.INVISIBLE);
464     }
465 
466     @Test
updateViewState_bypassNotEnabled_viewShown()467     public void updateViewState_bypassNotEnabled_viewShown() {
468         mController.onViewAttached();
469         updateStateToKeyguard();
470 
471         when(mKeyguardUpdateMonitor.shouldListenForFace()).thenReturn(true);
472         when(mKeyguardBypassController.getBypassEnabled()).thenReturn(false);
473         onFinishedGoingToSleep();
474 
475         mController.updateViewState();
476 
477         assertThat(mKeyguardStatusBarView.getVisibility()).isEqualTo(View.VISIBLE);
478     }
479 
480     @Test
updateViewState_shouldNotListenForFace_viewShown()481     public void updateViewState_shouldNotListenForFace_viewShown() {
482         mController.onViewAttached();
483         updateStateToKeyguard();
484 
485         when(mKeyguardUpdateMonitor.shouldListenForFace()).thenReturn(false);
486         when(mKeyguardBypassController.getBypassEnabled()).thenReturn(true);
487         onFinishedGoingToSleep();
488 
489         mController.updateViewState();
490 
491         assertThat(mKeyguardStatusBarView.getVisibility()).isEqualTo(View.VISIBLE);
492     }
493 
494     @Test
updateViewState_panelExpandedHeightZero_viewHidden()495     public void updateViewState_panelExpandedHeightZero_viewHidden() {
496         mController.onViewAttached();
497         updateStateToKeyguard();
498 
499         mShadeViewStateProvider.setPanelViewExpandedHeight(0);
500 
501         mController.updateViewState();
502 
503         assertThat(mKeyguardStatusBarView.getVisibility()).isEqualTo(View.INVISIBLE);
504     }
505 
506     @Test
updateViewState_dragProgressOne_viewHidden()507     public void updateViewState_dragProgressOne_viewHidden() {
508         mController.onViewAttached();
509         updateStateToKeyguard();
510 
511         mShadeViewStateProvider.setLockscreenShadeDragProgress(1f);
512 
513         mController.updateViewState();
514 
515         assertThat(mKeyguardStatusBarView.getVisibility()).isEqualTo(View.INVISIBLE);
516     }
517 
518     @Test
updateViewState_disableSystemInfoFalse_viewShown()519     public void updateViewState_disableSystemInfoFalse_viewShown() {
520         mController.onViewAttached();
521         updateStateToKeyguard();
522         setDisableSystemInfo(false);
523 
524         mController.updateViewState();
525 
526         assertThat(mKeyguardStatusBarView.getVisibility()).isEqualTo(View.VISIBLE);
527     }
528 
529     @Test
updateViewState_disableSystemInfoTrue_viewHidden()530     public void updateViewState_disableSystemInfoTrue_viewHidden() {
531         mController.onViewAttached();
532         updateStateToKeyguard();
533         setDisableSystemInfo(true);
534 
535         mController.updateViewState();
536 
537         assertThat(mKeyguardStatusBarView.getVisibility()).isEqualTo(View.INVISIBLE);
538     }
539 
540     @Test
updateViewState_disableSystemIconsFalse_viewShown()541     public void updateViewState_disableSystemIconsFalse_viewShown() {
542         mController.onViewAttached();
543         updateStateToKeyguard();
544         setDisableSystemIcons(false);
545 
546         mController.updateViewState();
547 
548         assertThat(mKeyguardStatusBarView.getVisibility()).isEqualTo(View.VISIBLE);
549     }
550 
551     @Test
updateViewState_disableSystemIconsTrue_viewHidden()552     public void updateViewState_disableSystemIconsTrue_viewHidden() {
553         mController.onViewAttached();
554         updateStateToKeyguard();
555         setDisableSystemIcons(true);
556 
557         mController.updateViewState();
558 
559         assertThat(mKeyguardStatusBarView.getVisibility()).isEqualTo(View.INVISIBLE);
560     }
561 
562     @Test
563     @DisableSceneContainer
updateViewState_dozingTrue_flagOff_viewHidden()564     public void updateViewState_dozingTrue_flagOff_viewHidden() {
565         mController.init();
566         mController.onViewAttached();
567         updateStateToKeyguard();
568 
569         mController.setDozing(true);
570         mController.updateViewState();
571 
572         assertThat(mKeyguardStatusBarView.getVisibility()).isEqualTo(View.INVISIBLE);
573     }
574 
575     @Test
576     @DisableSceneContainer
updateViewState_dozingFalse_flagOff_viewShown()577     public void updateViewState_dozingFalse_flagOff_viewShown() {
578         mController.init();
579         mController.onViewAttached();
580         updateStateToKeyguard();
581 
582         mController.setDozing(false);
583         mController.updateViewState();
584 
585         assertThat(mKeyguardStatusBarView.getVisibility()).isEqualTo(View.VISIBLE);
586     }
587 
588     @Test
589     @EnableSceneContainer
updateViewState_flagOn_doesNothing()590     public void updateViewState_flagOn_doesNothing() {
591         mController.init();
592         mController.onViewAttached();
593         updateStateToKeyguard();
594 
595         mKeyguardStatusBarView.setVisibility(View.GONE);
596         mKeyguardStatusBarView.setAlpha(0.456f);
597 
598         mController.updateViewState();
599 
600         assertThat(mKeyguardStatusBarView.getVisibility()).isEqualTo(View.GONE);
601         assertThat(mKeyguardStatusBarView.getAlpha()).isEqualTo(0.456f);
602     }
603 
604     @Test
605     @EnableSceneContainer
updateViewStateWithAlphaAndVis_flagOn_doesNothing()606     public void updateViewStateWithAlphaAndVis_flagOn_doesNothing() {
607         mController.init();
608         mController.onViewAttached();
609         updateStateToKeyguard();
610 
611         mKeyguardStatusBarView.setVisibility(View.GONE);
612         mKeyguardStatusBarView.setAlpha(0.456f);
613 
614         mController.updateViewState(0.789f, View.VISIBLE);
615 
616         assertThat(mKeyguardStatusBarView.getVisibility()).isEqualTo(View.GONE);
617         assertThat(mKeyguardStatusBarView.getAlpha()).isEqualTo(0.456f);
618     }
619 
620     @Test
621     @EnableSceneContainer
setAlpha_flagOn_doesNothing()622     public void setAlpha_flagOn_doesNothing() {
623         mController.init();
624         mController.onViewAttached();
625         updateStateToKeyguard();
626 
627         mKeyguardStatusBarView.setAlpha(0.456f);
628 
629         mController.setAlpha(0.123f);
630 
631         assertThat(mKeyguardStatusBarView.getAlpha()).isEqualTo(0.456f);
632     }
633 
634     @Test
635     @EnableSceneContainer
setDozing_flagOn_doesNothing()636     public void setDozing_flagOn_doesNothing() {
637         mController.init();
638         mController.onViewAttached();
639         updateStateToKeyguard();
640         assertThat(mKeyguardStatusBarView.getVisibility()).isEqualTo(View.VISIBLE);
641 
642         mController.setDozing(true);
643         mController.updateViewState();
644 
645         // setDozing(true) should typically cause the view to hide. But since the flag is on, we
646         // should ignore these set dozing calls and stay the same visibility.
647         assertThat(mKeyguardStatusBarView.getVisibility()).isEqualTo(View.VISIBLE);
648     }
649 
650     @Test
setAlpha_explicitAlpha_setsExplicitAlpha()651     public void setAlpha_explicitAlpha_setsExplicitAlpha() {
652         mController.onViewAttached();
653         updateStateToKeyguard();
654 
655         mController.setAlpha(0.5f);
656 
657         assertThat(mKeyguardStatusBarView.getAlpha()).isEqualTo(0.5f);
658     }
659 
660     @Test
setAlpha_explicitAlpha_thenMinusOneAlpha_setsAlphaBasedOnDefaultCriteria()661     public void setAlpha_explicitAlpha_thenMinusOneAlpha_setsAlphaBasedOnDefaultCriteria() {
662         mController.onViewAttached();
663         updateStateToKeyguard();
664 
665         mController.setAlpha(0.5f);
666         mController.setAlpha(-1f);
667 
668         assertThat(mKeyguardStatusBarView.getAlpha()).isGreaterThan(0);
669         assertThat(mKeyguardStatusBarView.getAlpha()).isNotEqualTo(0.5f);
670     }
671 
672     // TODO(b/195442899): Add more tests for #updateViewState once CLs are finalized.
673 
674     @Test
updateForHeadsUp_headsUpShouldBeVisible_viewHidden()675     public void updateForHeadsUp_headsUpShouldBeVisible_viewHidden() {
676         mController.onViewAttached();
677         updateStateToKeyguard();
678         mKeyguardStatusBarView.setVisibility(View.VISIBLE);
679 
680         mShadeViewStateProvider.setShouldHeadsUpBeVisible(true);
681         mController.updateForHeadsUp(/* animate= */ false);
682 
683         assertThat(mKeyguardStatusBarView.getVisibility()).isEqualTo(View.INVISIBLE);
684     }
685 
686     @Test
updateForHeadsUp_headsUpShouldNotBeVisible_viewShown()687     public void updateForHeadsUp_headsUpShouldNotBeVisible_viewShown() {
688         mController.onViewAttached();
689         updateStateToKeyguard();
690 
691         // Start with the opposite state.
692         mShadeViewStateProvider.setShouldHeadsUpBeVisible(true);
693         mController.updateForHeadsUp(/* animate= */ false);
694 
695         mShadeViewStateProvider.setShouldHeadsUpBeVisible(false);
696         mController.updateForHeadsUp(/* animate= */ false);
697 
698         assertThat(mKeyguardStatusBarView.getVisibility()).isEqualTo(View.VISIBLE);
699     }
700 
701     @Test
testNewUserSwitcherDisablesAvatar_newUiOn()702     public void testNewUserSwitcherDisablesAvatar_newUiOn() {
703         // GIVEN the status bar user switcher chip is enabled
704         when(mStatusBarUserChipViewModel.getChipEnabled()).thenReturn(true);
705 
706         // WHEN the controller is created
707         mController = createController();
708 
709         // THEN keyguard status bar view avatar is disabled
710         assertThat(mKeyguardStatusBarView.isKeyguardUserAvatarEnabled()).isFalse();
711     }
712 
713     @Test
testNewUserSwitcherDisablesAvatar_newUiOff()714     public void testNewUserSwitcherDisablesAvatar_newUiOff() {
715         // GIVEN the status bar user switcher chip is disabled
716         when(mStatusBarUserChipViewModel.getChipEnabled()).thenReturn(false);
717 
718         // WHEN the controller is created
719         mController = createController();
720 
721         // THEN keyguard status bar view avatar is enabled
722         assertThat(mKeyguardStatusBarView.isKeyguardUserAvatarEnabled()).isTrue();
723     }
724 
725     @Test
testBlockedIcons_obeysSettingForVibrateIcon_settingOff()726     public void testBlockedIcons_obeysSettingForVibrateIcon_settingOff() {
727         String str = mContext.getString(com.android.internal.R.string.status_bar_volume);
728 
729         // GIVEN the setting is off
730         when(mSecureSettings.getInt(Settings.Secure.STATUS_BAR_SHOW_VIBRATE_ICON, 0))
731                 .thenReturn(0);
732 
733         // WHEN CollapsedStatusBarFragment builds the blocklist
734         mController.updateBlockedIcons();
735 
736         // THEN status_bar_volume SHOULD be present in the list
737         boolean contains = mController.getBlockedIcons().contains(str);
738         assertTrue(contains);
739     }
740 
741     @Test
testBlockedIcons_obeysSettingForVibrateIcon_settingOn()742     public void testBlockedIcons_obeysSettingForVibrateIcon_settingOn() {
743         String str = mContext.getString(com.android.internal.R.string.status_bar_volume);
744 
745         // GIVEN the setting is ON
746         when(mSecureSettings.getIntForUser(Settings.Secure.STATUS_BAR_SHOW_VIBRATE_ICON, 0,
747                 UserHandle.USER_CURRENT))
748                 .thenReturn(1);
749 
750         // WHEN CollapsedStatusBarFragment builds the blocklist
751         mController.updateBlockedIcons();
752 
753         // THEN status_bar_volume SHOULD NOT be present in the list
754         boolean contains = mController.getBlockedIcons().contains(str);
755         assertFalse(contains);
756     }
757 
updateStateToNotKeyguard()758     private void updateStateToNotKeyguard() {
759         updateStatusBarState(SHADE);
760     }
761 
updateStateToKeyguard()762     private void updateStateToKeyguard() {
763         updateStatusBarState(KEYGUARD);
764     }
765 
updateStatusBarState(int state)766     private void updateStatusBarState(int state) {
767         ArgumentCaptor<StatusBarStateController.StateListener> statusBarStateListenerCaptor =
768                 ArgumentCaptor.forClass(StatusBarStateController.StateListener.class);
769         verify(mStatusBarStateController).addCallback(statusBarStateListenerCaptor.capture());
770         StatusBarStateController.StateListener callback = statusBarStateListenerCaptor.getValue();
771 
772         callback.onStateChanged(state);
773     }
774 
775     @Test
animateKeyguardStatusBarIn_isDisabled_viewStillHidden()776     public void animateKeyguardStatusBarIn_isDisabled_viewStillHidden() {
777         mController.onViewAttached();
778         updateStateToKeyguard();
779         setDisableSystemInfo(true);
780         assertThat(mKeyguardStatusBarView.getVisibility()).isEqualTo(View.INVISIBLE);
781 
782         mController.animateKeyguardStatusBarIn();
783 
784         // Since we're disabled, we don't actually animate in and stay invisible
785         assertThat(mKeyguardStatusBarView.getVisibility()).isEqualTo(View.INVISIBLE);
786     }
787 
788     /**
789      * Calls {@link com.android.keyguard.KeyguardUpdateMonitorCallback#onFinishedGoingToSleep(int)}
790      * to ensure values are updated properly.
791      */
onFinishedGoingToSleep()792     private void onFinishedGoingToSleep() {
793         ArgumentCaptor<KeyguardUpdateMonitorCallback> keyguardUpdateCallbackCaptor =
794                 ArgumentCaptor.forClass(KeyguardUpdateMonitorCallback.class);
795         verify(mKeyguardUpdateMonitor).registerCallback(keyguardUpdateCallbackCaptor.capture());
796         KeyguardUpdateMonitorCallback callback = keyguardUpdateCallbackCaptor.getValue();
797 
798         callback.onFinishedGoingToSleep(0);
799     }
800 
setDisableSystemInfo(boolean disabled)801     private void setDisableSystemInfo(boolean disabled) {
802         CommandQueue.Callbacks callback = getCommandQueueCallback();
803         int disabled1 = disabled ? DISABLE_SYSTEM_INFO : 0;
804         callback.disable(mContext.getDisplayId(), disabled1, 0, false);
805     }
806 
setDisableSystemIcons(boolean disabled)807     private void setDisableSystemIcons(boolean disabled) {
808         CommandQueue.Callbacks callback = getCommandQueueCallback();
809         int disabled2 = disabled ? DISABLE2_SYSTEM_ICONS : 0;
810         callback.disable(mContext.getDisplayId(), 0, disabled2, false);
811     }
812 
getCommandQueueCallback()813     private CommandQueue.Callbacks getCommandQueueCallback() {
814         ArgumentCaptor<CommandQueue.Callbacks> captor =
815                 ArgumentCaptor.forClass(CommandQueue.Callbacks.class);
816         verify(mCommandQueue).addCallback(captor.capture());
817         return captor.getValue();
818     }
819 
runAllScheduled()820     private void runAllScheduled() {
821         mBackgroundExecutor.runAllReady();
822         mFakeExecutor.runAllReady();
823     }
824 
825     private static class TestShadeViewStateProvider
826             implements ShadeViewStateProvider {
827 
TestShadeViewStateProvider()828         TestShadeViewStateProvider() {}
829 
830         private float mPanelViewExpandedHeight = 100f;
831         private boolean mShouldHeadsUpBeVisible = false;
832         private float mLockscreenShadeDragProgress = 0f;
833 
834         @Override
getPanelViewExpandedHeight()835         public float getPanelViewExpandedHeight() {
836             return mPanelViewExpandedHeight;
837         }
838 
839         @Override
shouldHeadsUpBeVisible()840         public boolean shouldHeadsUpBeVisible() {
841             return mShouldHeadsUpBeVisible;
842         }
843 
844         @Override
getLockscreenShadeDragProgress()845         public float getLockscreenShadeDragProgress() {
846             return mLockscreenShadeDragProgress;
847         }
848 
setPanelViewExpandedHeight(float panelViewExpandedHeight)849         public void setPanelViewExpandedHeight(float panelViewExpandedHeight) {
850             this.mPanelViewExpandedHeight = panelViewExpandedHeight;
851         }
852 
setShouldHeadsUpBeVisible(boolean shouldHeadsUpBeVisible)853         public void setShouldHeadsUpBeVisible(boolean shouldHeadsUpBeVisible) {
854             this.mShouldHeadsUpBeVisible = shouldHeadsUpBeVisible;
855         }
856 
setLockscreenShadeDragProgress(float lockscreenShadeDragProgress)857         public void setLockscreenShadeDragProgress(float lockscreenShadeDragProgress) {
858             this.mLockscreenShadeDragProgress = lockscreenShadeDragProgress;
859         }
860     }
861 }
862