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 android.app.StatusBarManager.WINDOW_STATE_HIDDEN;
20 import static android.app.StatusBarManager.WINDOW_STATE_SHOWING;
21 import static android.provider.Settings.Global.HEADS_UP_NOTIFICATIONS_ENABLED;
22 import static android.provider.Settings.Global.HEADS_UP_ON;
23 
24 import static com.android.systemui.Flags.FLAG_DEVICE_ENTRY_UDFPS_REFACTOR;
25 import static com.android.systemui.Flags.FLAG_KEYBOARD_SHORTCUT_HELPER_REWRITE;
26 import static com.android.systemui.Flags.FLAG_LIGHT_REVEAL_MIGRATION;
27 import static com.android.systemui.flags.Flags.SHORTCUT_LIST_SEARCH_LAYOUT;
28 import static com.android.systemui.statusbar.StatusBarState.KEYGUARD;
29 import static com.android.systemui.statusbar.StatusBarState.SHADE;
30 import static com.android.systemui.statusbar.phone.CentralSurfaces.MSG_DISMISS_KEYBOARD_SHORTCUTS_MENU;
31 
32 import static com.google.common.truth.Truth.assertThat;
33 
34 import static kotlinx.coroutines.flow.FlowKt.flowOf;
35 
36 import static org.mockito.ArgumentMatchers.any;
37 import static org.mockito.ArgumentMatchers.anyBoolean;
38 import static org.mockito.ArgumentMatchers.anyInt;
39 import static org.mockito.ArgumentMatchers.eq;
40 import static org.mockito.Mockito.atLeastOnce;
41 import static org.mockito.Mockito.clearInvocations;
42 import static org.mockito.Mockito.doAnswer;
43 import static org.mockito.Mockito.mock;
44 import static org.mockito.Mockito.never;
45 import static org.mockito.Mockito.reset;
46 import static org.mockito.Mockito.spy;
47 import static org.mockito.Mockito.times;
48 import static org.mockito.Mockito.verify;
49 import static org.mockito.Mockito.verifyNoMoreInteractions;
50 import static org.mockito.Mockito.when;
51 
52 import static java.util.Collections.emptySet;
53 
54 import android.app.ActivityManager;
55 import android.app.IWallpaperManager;
56 import android.app.WallpaperManager;
57 import android.app.trust.TrustManager;
58 import android.content.BroadcastReceiver;
59 import android.content.IntentFilter;
60 import android.content.pm.PackageManager;
61 import android.content.res.Configuration;
62 import android.graphics.Rect;
63 import android.hardware.devicestate.DeviceState;
64 import android.hardware.devicestate.DeviceStateManager;
65 import android.hardware.display.AmbientDisplayConfiguration;
66 import android.hardware.fingerprint.FingerprintManager;
67 import android.metrics.LogMaker;
68 import android.os.Binder;
69 import android.os.Handler;
70 import android.os.IPowerManager;
71 import android.os.IThermalService;
72 import android.os.Looper;
73 import android.os.PowerManager;
74 import android.os.UserHandle;
75 import android.platform.test.annotations.DisableFlags;
76 import android.platform.test.annotations.EnableFlags;
77 import android.service.dreams.IDreamManager;
78 import android.support.test.metricshelper.MetricsAsserts;
79 import android.testing.TestableLooper;
80 import android.testing.TestableLooper.RunWithLooper;
81 import android.util.DisplayMetrics;
82 import android.util.SparseArray;
83 import android.view.ViewGroup;
84 import android.view.ViewGroup.LayoutParams;
85 import android.view.WindowManager;
86 import android.view.WindowMetrics;
87 
88 import androidx.test.ext.junit.runners.AndroidJUnit4;
89 import androidx.test.filters.SmallTest;
90 
91 import com.android.compose.animation.scene.ObservableTransitionState;
92 import com.android.internal.colorextraction.ColorExtractor;
93 import com.android.internal.logging.UiEventLogger;
94 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
95 import com.android.internal.logging.testing.FakeMetricsLogger;
96 import com.android.internal.statusbar.IStatusBarService;
97 import com.android.keyguard.KeyguardUpdateMonitor;
98 import com.android.keyguard.ViewMediatorCallback;
99 import com.android.systemui.InitController;
100 import com.android.systemui.SysuiTestCase;
101 import com.android.systemui.accessibility.floatingmenu.AccessibilityFloatingMenuController;
102 import com.android.systemui.animation.ActivityTransitionAnimator;
103 import com.android.systemui.assist.AssistManager;
104 import com.android.systemui.back.domain.interactor.BackActionInteractor;
105 import com.android.systemui.biometrics.AuthRippleController;
106 import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor;
107 import com.android.systemui.broadcast.BroadcastDispatcher;
108 import com.android.systemui.charging.WiredChargingRippleController;
109 import com.android.systemui.classifier.FalsingCollectorFake;
110 import com.android.systemui.classifier.FalsingManagerFake;
111 import com.android.systemui.colorextraction.SysuiColorExtractor;
112 import com.android.systemui.communal.shared.model.CommunalScenes;
113 import com.android.systemui.demomode.DemoModeController;
114 import com.android.systemui.dump.DumpManager;
115 import com.android.systemui.emergency.EmergencyGestureModule.EmergencyGestureIntentFactory;
116 import com.android.systemui.flags.DisableSceneContainer;
117 import com.android.systemui.flags.EnableSceneContainer;
118 import com.android.systemui.flags.FakeFeatureFlags;
119 import com.android.systemui.flags.Flags;
120 import com.android.systemui.fragments.FragmentService;
121 import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
122 import com.android.systemui.keyguard.KeyguardViewMediator;
123 import com.android.systemui.keyguard.ScreenLifecycle;
124 import com.android.systemui.keyguard.WakefulnessLifecycle;
125 import com.android.systemui.keyguard.ui.viewmodel.LightRevealScrimViewModel;
126 import com.android.systemui.kosmos.KosmosJavaAdapter;
127 import com.android.systemui.navigationbar.NavigationBarController;
128 import com.android.systemui.notetask.NoteTaskController;
129 import com.android.systemui.plugins.ActivityStarter;
130 import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
131 import com.android.systemui.plugins.PluginDependencyProvider;
132 import com.android.systemui.plugins.PluginManager;
133 import com.android.systemui.plugins.statusbar.StatusBarStateController;
134 import com.android.systemui.power.domain.interactor.PowerInteractor;
135 import com.android.systemui.res.R;
136 import com.android.systemui.scene.domain.interactor.WindowRootViewVisibilityInteractor;
137 import com.android.systemui.scene.domain.startable.ScrimStartable;
138 import com.android.systemui.scene.shared.flag.SceneContainerFlag;
139 import com.android.systemui.settings.UserTracker;
140 import com.android.systemui.settings.brightness.BrightnessSliderController;
141 import com.android.systemui.settings.brightness.domain.interactor.BrightnessMirrorShowingInteractor;
142 import com.android.systemui.shade.CameraLauncher;
143 import com.android.systemui.shade.GlanceableHubContainerController;
144 import com.android.systemui.shade.NotificationPanelView;
145 import com.android.systemui.shade.NotificationPanelViewController;
146 import com.android.systemui.shade.NotificationShadeWindowViewController;
147 import com.android.systemui.shade.QuickSettingsController;
148 import com.android.systemui.shade.ShadeController;
149 import com.android.systemui.shade.ShadeControllerImpl;
150 import com.android.systemui.shade.ShadeExpansionStateManager;
151 import com.android.systemui.shade.ShadeLogger;
152 import com.android.systemui.statusbar.CommandQueue;
153 import com.android.systemui.statusbar.KeyboardShortcutListSearch;
154 import com.android.systemui.statusbar.KeyboardShortcuts;
155 import com.android.systemui.statusbar.KeyguardIndicationController;
156 import com.android.systemui.statusbar.LightRevealScrim;
157 import com.android.systemui.statusbar.LockscreenShadeTransitionController;
158 import com.android.systemui.statusbar.NotificationLockscreenUserManager;
159 import com.android.systemui.statusbar.NotificationMediaManager;
160 import com.android.systemui.statusbar.NotificationPresenter;
161 import com.android.systemui.statusbar.NotificationRemoteInputManager;
162 import com.android.systemui.statusbar.NotificationShadeDepthController;
163 import com.android.systemui.statusbar.NotificationShadeWindowController;
164 import com.android.systemui.statusbar.OperatorNameViewController;
165 import com.android.systemui.statusbar.PulseExpansionHandler;
166 import com.android.systemui.statusbar.StatusBarState;
167 import com.android.systemui.statusbar.StatusBarStateControllerImpl;
168 import com.android.systemui.statusbar.core.StatusBarInitializer;
169 import com.android.systemui.statusbar.data.repository.FakeStatusBarModeRepository;
170 import com.android.systemui.statusbar.notification.NotifPipelineFlags;
171 import com.android.systemui.statusbar.notification.NotificationActivityStarter;
172 import com.android.systemui.statusbar.notification.NotificationLaunchAnimatorControllerProvider;
173 import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
174 import com.android.systemui.statusbar.notification.init.NotificationsController;
175 import com.android.systemui.statusbar.notification.interruption.AvalancheProvider;
176 import com.android.systemui.statusbar.notification.interruption.KeyguardNotificationVisibilityProvider;
177 import com.android.systemui.statusbar.notification.interruption.NotificationInterruptLogger;
178 import com.android.systemui.statusbar.notification.interruption.VisualInterruptionDecisionLogger;
179 import com.android.systemui.statusbar.notification.interruption.VisualInterruptionDecisionProvider;
180 import com.android.systemui.statusbar.notification.interruption.VisualInterruptionDecisionProviderTestUtil;
181 import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
182 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
183 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
184 import com.android.systemui.statusbar.phone.fragment.CollapsedStatusBarFragment;
185 import com.android.systemui.statusbar.policy.BatteryController;
186 import com.android.systemui.statusbar.policy.ConfigurationController;
187 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
188 import com.android.systemui.statusbar.policy.ExtensionController;
189 import com.android.systemui.statusbar.policy.HeadsUpManager;
190 import com.android.systemui.statusbar.policy.KeyguardStateController;
191 import com.android.systemui.statusbar.policy.UserInfoControllerImpl;
192 import com.android.systemui.statusbar.window.StatusBarWindowController;
193 import com.android.systemui.statusbar.window.StatusBarWindowStateController;
194 import com.android.systemui.util.FakeEventLog;
195 import com.android.systemui.util.WallpaperController;
196 import com.android.systemui.util.concurrency.FakeExecutor;
197 import com.android.systemui.util.concurrency.MessageRouterImpl;
198 import com.android.systemui.util.kotlin.JavaAdapter;
199 import com.android.systemui.util.settings.FakeGlobalSettings;
200 import com.android.systemui.util.settings.FakeSettings;
201 import com.android.systemui.util.settings.SystemSettings;
202 import com.android.systemui.util.time.FakeSystemClock;
203 import com.android.systemui.volume.VolumeComponent;
204 import com.android.wm.shell.bubbles.Bubbles;
205 import com.android.wm.shell.startingsurface.StartingSurface;
206 
207 import dagger.Lazy;
208 
209 import kotlinx.coroutines.test.TestScope;
210 
211 import org.junit.Before;
212 import org.junit.Test;
213 import org.junit.runner.RunWith;
214 import org.mockito.ArgumentCaptor;
215 import org.mockito.Mock;
216 import org.mockito.Mockito;
217 import org.mockito.MockitoAnnotations;
218 
219 import java.io.ByteArrayOutputStream;
220 import java.io.PrintWriter;
221 import java.util.Optional;
222 
223 import javax.inject.Provider;
224 
225 @SmallTest
226 @RunWith(AndroidJUnit4.class)
227 @RunWithLooper(setAsMainLooper = true)
228 @EnableFlags(FLAG_LIGHT_REVEAL_MIGRATION)
229 public class CentralSurfacesImplTest extends SysuiTestCase {
230 
231     private static final int FOLD_STATE_FOLDED = 0;
232     private static final int FOLD_STATE_UNFOLDED = 1;
233 
234     private final KosmosJavaAdapter mKosmos = new KosmosJavaAdapter(this);
235 
236     private CentralSurfacesImpl mCentralSurfaces;
237     private FakeMetricsLogger mMetricsLogger;
238     private PowerManager mPowerManager;
239     private VisualInterruptionDecisionProvider mVisualInterruptionDecisionProvider;
240 
241 
242     private final TestScope mTestScope = mKosmos.getTestScope();
243     @Mock private NotificationsController mNotificationsController;
244     @Mock private LightBarController mLightBarController;
245     @Mock private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
246     @Mock private KeyguardStateController mKeyguardStateController;
247     @Mock private KeyguardIndicationController mKeyguardIndicationController;
248     @Mock private NotificationStackScrollLayout mStackScroller;
249     @Mock private NotificationStackScrollLayoutController mStackScrollerController;
250     @Mock private HeadsUpManager mHeadsUpManager;
251     @Mock private NotificationPanelViewController mNotificationPanelViewController;
252     @Mock private ShadeLogger mShadeLogger;
253     @Mock private NotificationPanelView mNotificationPanelView;
254     @Mock private QuickSettingsController mQuickSettingsController;
255     @Mock private IStatusBarService mBarService;
256     @Mock private IDreamManager mDreamManager;
257     @Mock private LightRevealScrimViewModel mLightRevealScrimViewModel;
258     @Mock private LightRevealScrim mLightRevealScrim;
259     @Mock private DozeScrimController mDozeScrimController;
260     @Mock private Lazy<BiometricUnlockController> mBiometricUnlockControllerLazy;
261     @Mock private BiometricUnlockController mBiometricUnlockController;
262     @Mock private AuthRippleController mAuthRippleController;
263     @Mock private KeyguardViewMediator mKeyguardViewMediator;
264     @Mock private NotificationLockscreenUserManager mLockscreenUserManager;
265     @Mock private NotificationRemoteInputManager mRemoteInputManager;
266     @Mock private StatusBarStateControllerImpl mStatusBarStateController;
267     @Mock private BatteryController mBatteryController;
268     @Mock private DeviceProvisionedController mDeviceProvisionedController;
269     @Mock private NotificationLaunchAnimatorControllerProvider
270             mNotifTransitionAnimControllerProvider;
271     @Mock private StatusBarNotificationPresenter mNotificationPresenter;
272     @Mock private NotificationActivityStarter mNotificationActivityStarter;
273     @Mock private AmbientDisplayConfiguration mAmbientDisplayConfiguration;
274     @Mock private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
275     @Mock private StatusBarSignalPolicy mStatusBarSignalPolicy;
276     @Mock private BroadcastDispatcher mBroadcastDispatcher;
277     @Mock private AssistManager mAssistManager;
278     @Mock private NotificationGutsManager mNotificationGutsManager;
279     @Mock private NotificationMediaManager mNotificationMediaManager;
280     @Mock private NavigationBarController mNavigationBarController;
281     @Mock private AccessibilityFloatingMenuController mAccessibilityFloatingMenuController;
282     @Mock private SysuiColorExtractor mColorExtractor;
283     private WakefulnessLifecycle mWakefulnessLifecycle;
284     @Mock private PowerInteractor mPowerInteractor;
285     @Mock private ColorExtractor.GradientColors mGradientColors;
286     @Mock private PulseExpansionHandler mPulseExpansionHandler;
287     @Mock private NotificationWakeUpCoordinator mNotificationWakeUpCoordinator;
288     @Mock private KeyguardBypassController mKeyguardBypassController;
289     @Mock private AutoHideController mAutoHideController;
290     @Mock private StatusBarWindowController mStatusBarWindowController;
291     @Mock private Provider<CollapsedStatusBarFragment> mCollapsedStatusBarFragmentProvider;
292     @Mock private StatusBarWindowStateController mStatusBarWindowStateController;
293     @Mock private Bubbles mBubbles;
294     @Mock private NoteTaskController mNoteTaskController;
295     @Mock private NotificationShadeWindowController mNotificationShadeWindowController;
296     @Mock private NotificationIconAreaController mNotificationIconAreaController;
297     @Mock private NotificationShadeWindowViewController mNotificationShadeWindowViewController;
298     @Mock private Lazy<NotificationShadeWindowViewController>
299             mNotificationShadeWindowViewControllerLazy;
300     @Mock private DozeParameters mDozeParameters;
301     @Mock private DozeServiceHost mDozeServiceHost;
302     @Mock private BackActionInteractor mBackActionInteractor;
303     @Mock private ViewMediatorCallback mKeyguardVieMediatorCallback;
304     @Mock private VolumeComponent mVolumeComponent;
305     @Mock private CommandQueue mCommandQueue;
306     @Mock private CentralSurfacesCommandQueueCallbacks mCentralSurfacesCommandQueueCallbacks;
307     @Mock private PluginManager mPluginManager;
308     @Mock private ViewMediatorCallback mViewMediatorCallback;
309     @Mock private StatusBarTouchableRegionManager mStatusBarTouchableRegionManager;
310     @Mock private PluginDependencyProvider mPluginDependencyProvider;
311     @Mock private ExtensionController mExtensionController;
312     @Mock private UserInfoControllerImpl mUserInfoControllerImpl;
313     @Mock private PhoneStatusBarPolicy mPhoneStatusBarPolicy;
314     @Mock private DemoModeController mDemoModeController;
315     @Mock private Lazy<NotificationShadeDepthController> mNotificationShadeDepthControllerLazy;
316     @Mock private BrightnessSliderController.Factory mBrightnessSliderFactory;
317     @Mock private WallpaperController mWallpaperController;
318     @Mock private StatusBarHideIconsForBouncerManager mStatusBarHideIconsForBouncerManager;
319     @Mock private LockscreenShadeTransitionController mLockscreenTransitionController;
320     @Mock private WallpaperManager mWallpaperManager;
321     @Mock private IWallpaperManager mIWallpaperManager;
322     @Mock private KeyguardUnlockAnimationController mKeyguardUnlockAnimationController;
323     @Mock private ScreenOffAnimationController mScreenOffAnimationController;
324     @Mock private StartingSurface mStartingSurface;
325     @Mock private OperatorNameViewController mOperatorNameViewController;
326     @Mock private OperatorNameViewController.Factory mOperatorNameViewControllerFactory;
327     @Mock private ActivityTransitionAnimator mActivityTransitionAnimator;
328     @Mock private DeviceStateManager mDeviceStateManager;
329     @Mock private WiredChargingRippleController mWiredChargingRippleController;
330     @Mock private Lazy<CameraLauncher> mCameraLauncherLazy;
331     @Mock private CameraLauncher mCameraLauncher;
332     @Mock private AlternateBouncerInteractor mAlternateBouncerInteractor;
333     @Mock private UserTracker mUserTracker;
334     @Mock private AvalancheProvider mAvalancheProvider;
335     @Mock private FingerprintManager mFingerprintManager;
336     @Mock IPowerManager mPowerManagerService;
337     @Mock ActivityStarter mActivityStarter;
338     @Mock private WindowRootViewVisibilityInteractor mWindowRootViewVisibilityInteractor;
339     @Mock private KeyboardShortcuts mKeyboardShortcuts;
340     @Mock private KeyboardShortcutListSearch mKeyboardShortcutListSearch;
341     @Mock private PackageManager mPackageManager;
342     @Mock private GlanceableHubContainerController mGlanceableHubContainerController;
343     @Mock private EmergencyGestureIntentFactory mEmergencyGestureIntentFactory;
344 
345     private ShadeController mShadeController;
346     private final FakeSystemClock mFakeSystemClock = new FakeSystemClock();
347     private final FakeGlobalSettings mFakeGlobalSettings = new FakeGlobalSettings();
348     private final SystemSettings mSystemSettings = new FakeSettings();
349     private final FakeEventLog mFakeEventLog = new FakeEventLog();
350     private FakeExecutor mMainExecutor = new FakeExecutor(mFakeSystemClock);
351     private final FakeExecutor mUiBgExecutor = new FakeExecutor(mFakeSystemClock);
352     private final FakeFeatureFlags mFeatureFlags = new FakeFeatureFlags();
353     private final InitController mInitController = new InitController();
354     private final DumpManager mDumpManager = new DumpManager();
355     private final ScreenLifecycle mScreenLifecycle = new ScreenLifecycle(mDumpManager);
356     private MessageRouterImpl mMessageRouter = new MessageRouterImpl(mMainExecutor);
357 
358     private final BrightnessMirrorShowingInteractor mBrightnessMirrorShowingInteractor =
359             mKosmos.getBrightnessMirrorShowingInteractor();
360     private ScrimController mScrimController;
361 
362     @Before
setup()363     public void setup() throws Exception {
364         MockitoAnnotations.initMocks(this);
365 
366         // Set default value to avoid IllegalStateException.
367         mFeatureFlags.set(SHORTCUT_LIST_SEARCH_LAYOUT, false);
368         // Turn AOD on and toggle feature flag for jank fixes
369         mFeatureFlags.set(Flags.ZJ_285570694_LOCKSCREEN_TRANSITION_FROM_AOD, true);
370         when(mDozeParameters.getAlwaysOn()).thenReturn(true);
371 
372         IThermalService thermalService = mock(IThermalService.class);
373         mPowerManager = new PowerManager(mContext, mPowerManagerService, thermalService,
374                 Handler.createAsync(Looper.myLooper()));
375 
376         mFakeGlobalSettings.putInt(HEADS_UP_NOTIFICATIONS_ENABLED, HEADS_UP_ON);
377 
378         when(mBubbles.canShowBubbleNotification()).thenReturn(true);
379 
380         mVisualInterruptionDecisionProvider =
381                 VisualInterruptionDecisionProviderTestUtil.INSTANCE.createProviderByFlag(
382                         mAmbientDisplayConfiguration,
383                         mBatteryController,
384                         mDeviceProvisionedController,
385                         mFakeEventLog,
386                         mock(NotifPipelineFlags.class),
387                         mFakeGlobalSettings,
388                         mHeadsUpManager,
389                         mock(KeyguardNotificationVisibilityProvider.class),
390                         mKeyguardStateController,
391                         new Handler(TestableLooper.get(this).getLooper()),
392                         mock(VisualInterruptionDecisionLogger.class),
393                         mock(NotificationInterruptLogger.class),
394                         mPowerManager,
395                         mStatusBarStateController,
396                         mFakeSystemClock,
397                         mock(UiEventLogger.class),
398                         mUserTracker,
399                         mAvalancheProvider,
400                         mSystemSettings,
401                         mPackageManager,
402                         Optional.of(mBubbles));
403         mVisualInterruptionDecisionProvider.start();
404 
405         mContext.addMockSystemService(TrustManager.class, mock(TrustManager.class));
406         mContext.addMockSystemService(FingerprintManager.class, mock(FingerprintManager.class));
407 
408         mMetricsLogger = new FakeMetricsLogger();
409 
410         when(mCommandQueue.asBinder()).thenReturn(new Binder());
411 
412         mContext.setTheme(R.style.Theme_SystemUI_LightWallpaper);
413 
414         when(mStackScrollerController.getView()).thenReturn(mStackScroller);
415         when(mStackScroller.generateLayoutParams(any())).thenReturn(new LayoutParams(0, 0));
416         when(mNotificationPanelView.getLayoutParams()).thenReturn(new LayoutParams(0, 0));
417         when(mPowerManagerService.isInteractive()).thenReturn(true);
418 
419         doAnswer(invocation -> {
420             OnDismissAction onDismissAction = (OnDismissAction) invocation.getArguments()[0];
421             onDismissAction.onDismiss();
422             return null;
423         }).when(mStatusBarKeyguardViewManager).dismissWithAction(any(), any(), anyBoolean());
424 
425         doAnswer(invocation -> {
426             Runnable runnable = (Runnable) invocation.getArguments()[0];
427             runnable.run();
428             return null;
429         }).when(mStatusBarKeyguardViewManager).addAfterKeyguardGoneRunnable(any());
430 
431         mWakefulnessLifecycle =
432                 new WakefulnessLifecycle(mContext, mIWallpaperManager, mFakeSystemClock,
433                         mDumpManager);
434         mWakefulnessLifecycle.dispatchStartedWakingUp(PowerManager.WAKE_REASON_UNKNOWN);
435         mWakefulnessLifecycle.dispatchFinishedWakingUp();
436 
437         when(mGradientColors.supportsDarkText()).thenReturn(true);
438         when(mColorExtractor.getNeutralColors()).thenReturn(mGradientColors);
439 
440         when(mBiometricUnlockControllerLazy.get()).thenReturn(mBiometricUnlockController);
441         when(mCameraLauncherLazy.get()).thenReturn(mCameraLauncher);
442         when(mNotificationShadeWindowViewControllerLazy.get())
443                 .thenReturn(mNotificationShadeWindowViewController);
444 
445         doAnswer(invocation -> {
446             ((Runnable) invocation.getArgument(0)).run();
447             return null;
448         }).when(mNotificationShadeWindowController).batchApplyWindowLayoutParams(any());
449         if (SceneContainerFlag.isEnabled()) {
450             mShadeController = spy(mKosmos.getShadeController());
451         } else {
452             mShadeController = spy(new ShadeControllerImpl(
453                     mCommandQueue,
454                     mMainExecutor,
455                     mock(WindowRootViewVisibilityInteractor.class),
456                     mKeyguardStateController,
457                     mStatusBarStateController,
458                     mStatusBarKeyguardViewManager,
459                     mStatusBarWindowController,
460                     mDeviceProvisionedController,
461                     mNotificationShadeWindowController,
462                     0,
463                     () -> mNotificationPanelViewController,
464                     () -> mAssistManager,
465                     () -> mNotificationGutsManager
466             ));
467         }
468         mShadeController.setNotificationShadeWindowViewController(
469                 mNotificationShadeWindowViewController);
470         mShadeController.setNotificationPresenter(mNotificationPresenter);
471 
472         when(mOperatorNameViewControllerFactory.create(any()))
473                 .thenReturn(mOperatorNameViewController);
474         when(mUserTracker.getUserId()).thenReturn(ActivityManager.getCurrentUser());
475         when(mUserTracker.getUserHandle()).thenReturn(
476                 UserHandle.of(ActivityManager.getCurrentUser()));
477 
478         mScrimController = mKosmos.getScrimController();
479 
480         createCentralSurfaces();
481     }
482 
createCentralSurfaces()483     private void createCentralSurfaces() {
484         mMainExecutor = new FakeExecutor(mFakeSystemClock);
485         mMessageRouter = new MessageRouterImpl(mMainExecutor);
486         mKeyboardShortcuts = mock(KeyboardShortcuts.class);
487         mKeyboardShortcutListSearch = mock(KeyboardShortcutListSearch.class);
488         // Test setup for legacy version
489         mKeyboardShortcuts.mContext = mContext;
490         mKeyboardShortcutListSearch.mContext = mContext;
491         KeyboardShortcuts.sInstance = mKeyboardShortcuts;
492         KeyboardShortcutListSearch.sInstance = mKeyboardShortcutListSearch;
493 
494         ConfigurationController configurationController = new ConfigurationControllerImpl(mContext);
495         mCentralSurfaces = new CentralSurfacesImpl(
496                 mContext,
497                 mNotificationsController,
498                 mock(FragmentService.class),
499                 mLightBarController,
500                 mAutoHideController,
501                 new StatusBarInitializer(
502                         mStatusBarWindowController,
503                         mCollapsedStatusBarFragmentProvider,
504                         emptySet()),
505                 mStatusBarWindowController,
506                 mStatusBarWindowStateController,
507                 new FakeStatusBarModeRepository(),
508                 mKeyguardUpdateMonitor,
509                 mStatusBarSignalPolicy,
510                 mPulseExpansionHandler,
511                 mNotificationWakeUpCoordinator,
512                 mKeyguardBypassController,
513                 mKeyguardStateController,
514                 mHeadsUpManager,
515                 new FalsingManagerFake(),
516                 new FalsingCollectorFake(),
517                 mBroadcastDispatcher,
518                 mNotificationGutsManager,
519                 new ShadeExpansionStateManager(),
520                 mKeyguardViewMediator,
521                 new DisplayMetrics(),
522                 mMetricsLogger,
523                 mShadeLogger,
524                 new JavaAdapter(mTestScope),
525                 mUiBgExecutor,
526                 mNotificationPanelViewController,
527                 mNotificationMediaManager,
528                 mLockscreenUserManager,
529                 mRemoteInputManager,
530                 mQuickSettingsController,
531                 mBatteryController,
532                 mColorExtractor,
533                 mScreenLifecycle,
534                 mWakefulnessLifecycle,
535                 mPowerInteractor,
536                 mKosmos.getCommunalInteractor(),
537                 mStatusBarStateController,
538                 Optional.of(mBubbles),
539                 () -> mNoteTaskController,
540                 mDeviceProvisionedController,
541                 mNavigationBarController,
542                 mAccessibilityFloatingMenuController,
543                 () -> mAssistManager,
544                 configurationController,
545                 mNotificationShadeWindowController,
546                 mNotificationShadeWindowViewControllerLazy,
547                 mStackScrollerController,
548                 (Lazy<NotificationPresenter>) () -> mNotificationPresenter,
549                 (Lazy<NotificationActivityStarter>) () -> mNotificationActivityStarter,
550                 mNotifTransitionAnimControllerProvider,
551                 mDozeParameters,
552                 mScrimController,
553                 mBiometricUnlockControllerLazy,
554                 mAuthRippleController,
555                 mDozeServiceHost,
556                 mBackActionInteractor,
557                 mPowerManager,
558                 mDozeScrimController,
559                 mVolumeComponent,
560                 mCommandQueue,
561                 () -> mCentralSurfacesCommandQueueCallbacks,
562                 mPluginManager,
563                 mShadeController,
564                 mWindowRootViewVisibilityInteractor,
565                 mStatusBarKeyguardViewManager,
566                 mViewMediatorCallback,
567                 mInitController,
568                 new Handler(TestableLooper.get(this).getLooper()),
569                 mPluginDependencyProvider,
570                 mExtensionController,
571                 mUserInfoControllerImpl,
572                 mPhoneStatusBarPolicy,
573                 mKeyguardIndicationController,
574                 mDemoModeController,
575                 mNotificationShadeDepthControllerLazy,
576                 mStatusBarTouchableRegionManager,
577                 mNotificationIconAreaController,
578                 mBrightnessSliderFactory,
579                 mScreenOffAnimationController,
580                 mWallpaperController,
581                 mStatusBarHideIconsForBouncerManager,
582                 mLockscreenTransitionController,
583                 mFeatureFlags,
584                 mKeyguardUnlockAnimationController,
585                 mMainExecutor,
586                 mMessageRouter,
587                 mWallpaperManager,
588                 Optional.of(mStartingSurface),
589                 mActivityTransitionAnimator,
590                 mDeviceStateManager,
591                 mWiredChargingRippleController,
592                 mDreamManager,
593                 mCameraLauncherLazy,
594                 () -> mLightRevealScrimViewModel,
595                 mLightRevealScrim,
596                 mAlternateBouncerInteractor,
597                 mUserTracker,
598                 () -> mFingerprintManager,
599                 mActivityStarter,
600                 mBrightnessMirrorShowingInteractor,
601                 mGlanceableHubContainerController,
602                 mEmergencyGestureIntentFactory
603         );
604         mScreenLifecycle.addObserver(mCentralSurfaces.mScreenObserver);
605         mCentralSurfaces.initShadeVisibilityListener();
606         when(mKeyguardViewMediator.registerCentralSurfaces(
607                 any(CentralSurfacesImpl.class),
608                 any(NotificationPanelViewController.class),
609                 any(ShadeExpansionStateManager.class),
610                 any(BiometricUnlockController.class),
611                 any(ViewGroup.class)))
612                 .thenReturn(mStatusBarKeyguardViewManager);
613 
614         when(mKeyguardViewMediator.getViewMediatorCallback()).thenReturn(
615                 mKeyguardVieMediatorCallback);
616 
617         // TODO(b/277764509): we should be able to call mCentralSurfaces.start() and have all the
618         //  below values initialized automatically.
619         mCentralSurfaces.mDozeScrimController = mDozeScrimController;
620         mCentralSurfaces.mKeyguardIndicationController = mKeyguardIndicationController;
621         mCentralSurfaces.mBarService = mBarService;
622         mCentralSurfaces.mGestureWakeLock = mPowerManager.newWakeLock(
623                 PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "sysui:GestureWakeLock");
624         mCentralSurfaces.startKeyguard();
625         mInitController.executePostInitTasks();
626         mCentralSurfaces.registerCallbacks();
627     }
628 
629     @Test
testSetBouncerShowing_noCrash()630     public void testSetBouncerShowing_noCrash() {
631         mCentralSurfaces.setBouncerShowing(true);
632     }
633 
634     @Test
lockscreenStateMetrics_notShowing()635     public void lockscreenStateMetrics_notShowing() {
636         // uninteresting state, except that fingerprint must be non-zero
637         when(mKeyguardStateController.isOccluded()).thenReturn(false);
638         when(mKeyguardStateController.canDismissLockScreen()).thenReturn(true);
639         // interesting state
640         when(mKeyguardStateController.isShowing()).thenReturn(false);
641         when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(false);
642         when(mKeyguardStateController.isMethodSecure()).thenReturn(false);
643         mCentralSurfaces.onKeyguardViewManagerStatesUpdated();
644 
645         MetricsAsserts.assertHasLog("missing hidden insecure lockscreen log",
646                 mMetricsLogger.getLogs(),
647                 new LogMaker(MetricsEvent.LOCKSCREEN)
648                         .setType(MetricsEvent.TYPE_CLOSE)
649                         .setSubtype(0));
650     }
651 
652     @Test
lockscreenStateMetrics_notShowing_secure()653     public void lockscreenStateMetrics_notShowing_secure() {
654         // uninteresting state, except that fingerprint must be non-zero
655         when(mKeyguardStateController.isOccluded()).thenReturn(false);
656         when(mKeyguardStateController.canDismissLockScreen()).thenReturn(true);
657         // interesting state
658         when(mKeyguardStateController.isShowing()).thenReturn(false);
659         when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(false);
660         when(mKeyguardStateController.isMethodSecure()).thenReturn(true);
661 
662         mCentralSurfaces.onKeyguardViewManagerStatesUpdated();
663 
664         MetricsAsserts.assertHasLog("missing hidden secure lockscreen log",
665                 mMetricsLogger.getLogs(),
666                 new LogMaker(MetricsEvent.LOCKSCREEN)
667                         .setType(MetricsEvent.TYPE_CLOSE)
668                         .setSubtype(1));
669     }
670 
671     @Test
lockscreenStateMetrics_isShowing()672     public void lockscreenStateMetrics_isShowing() {
673         // uninteresting state, except that fingerprint must be non-zero
674         when(mKeyguardStateController.isOccluded()).thenReturn(false);
675         when(mKeyguardStateController.canDismissLockScreen()).thenReturn(true);
676         // interesting state
677         when(mKeyguardStateController.isShowing()).thenReturn(true);
678         when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(false);
679         when(mKeyguardStateController.isMethodSecure()).thenReturn(false);
680 
681         mCentralSurfaces.onKeyguardViewManagerStatesUpdated();
682 
683         MetricsAsserts.assertHasLog("missing insecure lockscreen showing",
684                 mMetricsLogger.getLogs(),
685                 new LogMaker(MetricsEvent.LOCKSCREEN)
686                         .setType(MetricsEvent.TYPE_OPEN)
687                         .setSubtype(0));
688     }
689 
690     @Test
lockscreenStateMetrics_isShowing_secure()691     public void lockscreenStateMetrics_isShowing_secure() {
692         // uninteresting state, except that fingerprint must be non-zero
693         when(mKeyguardStateController.isOccluded()).thenReturn(false);
694         when(mKeyguardStateController.canDismissLockScreen()).thenReturn(true);
695         // interesting state
696         when(mKeyguardStateController.isShowing()).thenReturn(true);
697         when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(false);
698         when(mKeyguardStateController.isMethodSecure()).thenReturn(true);
699 
700         mCentralSurfaces.onKeyguardViewManagerStatesUpdated();
701 
702         MetricsAsserts.assertHasLog("missing secure lockscreen showing log",
703                 mMetricsLogger.getLogs(),
704                 new LogMaker(MetricsEvent.LOCKSCREEN)
705                         .setType(MetricsEvent.TYPE_OPEN)
706                         .setSubtype(1));
707     }
708 
709     @Test
lockscreenStateMetrics_isShowingBouncer()710     public void lockscreenStateMetrics_isShowingBouncer() {
711         // uninteresting state, except that fingerprint must be non-zero
712         when(mKeyguardStateController.isOccluded()).thenReturn(false);
713         when(mKeyguardStateController.canDismissLockScreen()).thenReturn(true);
714         // interesting state
715         when(mKeyguardStateController.isShowing()).thenReturn(true);
716         when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(true);
717         when(mKeyguardStateController.isMethodSecure()).thenReturn(true);
718 
719         mCentralSurfaces.onKeyguardViewManagerStatesUpdated();
720 
721         MetricsAsserts.assertHasLog("missing bouncer log",
722                 mMetricsLogger.getLogs(),
723                 new LogMaker(MetricsEvent.BOUNCER)
724                         .setType(MetricsEvent.TYPE_OPEN)
725                         .setSubtype(1));
726     }
727 
728     @Test
testDump_DoesNotCrash()729     public void testDump_DoesNotCrash() {
730         mCentralSurfaces.dump(new PrintWriter(new ByteArrayOutputStream()), null);
731     }
732 
733     @Test
testDumpBarTransitions_DoesNotCrash()734     public void testDumpBarTransitions_DoesNotCrash() {
735         CentralSurfaces.dumpBarTransitions(
736                 new PrintWriter(new ByteArrayOutputStream()), "var", /* transitions= */ null);
737     }
738 
739     @Test
testFingerprintNotification_UpdatesScrims()740     public void testFingerprintNotification_UpdatesScrims() {
741         mCentralSurfaces.notifyBiometricAuthModeChanged();
742         verify(mScrimController).legacyTransitionTo(any(), any());
743     }
744 
745     @Test
testFingerprintUnlock_UpdatesScrims()746     public void testFingerprintUnlock_UpdatesScrims() {
747         // Simulate unlocking from AoD with fingerprint.
748         when(mBiometricUnlockController.getMode())
749                 .thenReturn(BiometricUnlockController.MODE_WAKE_AND_UNLOCK);
750         mCentralSurfaces.updateScrimController();
751         verify(mScrimController).legacyTransitionTo(eq(ScrimState.UNLOCKED), any());
752     }
753 
754     @Test
testTransitionLaunch_goesToUnlocked()755     public void testTransitionLaunch_goesToUnlocked() {
756         mCentralSurfaces.setBarStateForTest(StatusBarState.KEYGUARD);
757         mCentralSurfaces.showKeyguardImpl();
758 
759         // Starting a pulse should change the scrim controller to the pulsing state
760         when(mCameraLauncher.isLaunchingAffordance()).thenReturn(true);
761         mCentralSurfaces.updateScrimController();
762         verify(mScrimController).legacyTransitionTo(eq(ScrimState.UNLOCKED), any());
763     }
764 
765     @Test
testSetExpansionAffectsAlpha_whenKeyguardShowingButGoingAwayForAnyReason()766     public void testSetExpansionAffectsAlpha_whenKeyguardShowingButGoingAwayForAnyReason() {
767         mCentralSurfaces.updateScrimController();
768         verify(mScrimController).setExpansionAffectsAlpha(eq(true));
769 
770         clearInvocations(mScrimController);
771         when(mKeyguardStateController.isShowing()).thenReturn(true);
772         when(mKeyguardStateController.isKeyguardGoingAway()).thenReturn(false);
773         mCentralSurfaces.updateScrimController();
774         verify(mScrimController).setExpansionAffectsAlpha(eq(true));
775 
776         clearInvocations(mScrimController);
777         when(mKeyguardStateController.isShowing()).thenReturn(true);
778         when(mKeyguardStateController.isKeyguardGoingAway()).thenReturn(true);
779         mCentralSurfaces.updateScrimController();
780         verify(mScrimController).setExpansionAffectsAlpha(eq(false));
781 
782         clearInvocations(mScrimController);
783         when(mKeyguardStateController.isShowing()).thenReturn(true);
784         when(mKeyguardStateController.isKeyguardFadingAway()).thenReturn(true);
785         mCentralSurfaces.updateScrimController();
786         verify(mScrimController).setExpansionAffectsAlpha(eq(false));
787     }
788 
789     @Test
testTransitionLaunch_noPreview_doesntGoUnlocked()790     public void testTransitionLaunch_noPreview_doesntGoUnlocked() {
791         mCentralSurfaces.setBarStateForTest(StatusBarState.KEYGUARD);
792         when(mKeyguardStateController.isShowing()).thenReturn(true);
793         mCentralSurfaces.showKeyguardImpl();
794 
795         // Starting a pulse should change the scrim controller to the pulsing state
796         when(mCameraLauncher.isLaunchingAffordance()).thenReturn(false);
797         mCentralSurfaces.updateScrimController();
798         verify(mScrimController).legacyTransitionTo(eq(ScrimState.KEYGUARD));
799     }
800 
801     @Test
testSetOccluded_propagatesToScrimController()802     public void testSetOccluded_propagatesToScrimController() {
803         ArgumentCaptor<KeyguardStateController.Callback> callbackCaptor =
804                 ArgumentCaptor.forClass(KeyguardStateController.Callback.class);
805         verify(mKeyguardStateController).addCallback(callbackCaptor.capture());
806 
807         when(mKeyguardStateController.isOccluded()).thenReturn(true);
808         callbackCaptor.getValue().onKeyguardShowingChanged();
809         verify(mScrimController).setKeyguardOccluded(eq(true));
810 
811         reset(mScrimController);
812         when(mKeyguardStateController.isOccluded()).thenReturn(false);
813         callbackCaptor.getValue().onKeyguardShowingChanged();
814         verify(mScrimController).setKeyguardOccluded(eq(false));
815     }
816 
817     @Test
testPulseWhileDozing_updatesScrimController()818     public void testPulseWhileDozing_updatesScrimController() {
819         mCentralSurfaces.setBarStateForTest(StatusBarState.KEYGUARD);
820         when(mKeyguardStateController.isShowing()).thenReturn(true);
821         mCentralSurfaces.showKeyguardImpl();
822 
823         // Starting a pulse should change the scrim controller to the pulsing state
824         when(mDozeServiceHost.isPulsing()).thenReturn(true);
825         mCentralSurfaces.updateScrimController();
826         verify(mScrimController).legacyTransitionTo(eq(ScrimState.PULSING), any());
827 
828         // Ending a pulse should take it back to keyguard state
829         when(mDozeServiceHost.isPulsing()).thenReturn(false);
830         mCentralSurfaces.updateScrimController();
831         verify(mScrimController).legacyTransitionTo(eq(ScrimState.KEYGUARD));
832     }
833 
834     @Test
testSetDozingNotUnlocking_transitionToAOD_cancelKeyguardFadingAway()835     public void testSetDozingNotUnlocking_transitionToAOD_cancelKeyguardFadingAway() {
836         setDozing(true);
837         when(mKeyguardStateController.isShowing()).thenReturn(false);
838         when(mKeyguardStateController.isKeyguardFadingAway()).thenReturn(true);
839 
840         mCentralSurfaces.updateScrimController();
841 
842         verify(mScrimController, times(2)).legacyTransitionTo(eq(ScrimState.AOD));
843         verify(mStatusBarKeyguardViewManager).onKeyguardFadedAway();
844     }
845 
846     @Test
847     @DisableFlags(FLAG_DEVICE_ENTRY_UDFPS_REFACTOR)
testSetDozingNotUnlocking_transitionToAuthScrimmed_cancelKeyguardFadingAway()848     public void testSetDozingNotUnlocking_transitionToAuthScrimmed_cancelKeyguardFadingAway() {
849         when(mAlternateBouncerInteractor.isVisibleState()).thenReturn(true);
850         when(mKeyguardStateController.isKeyguardFadingAway()).thenReturn(true);
851 
852         mCentralSurfaces.updateScrimController();
853 
854         verify(mScrimController).legacyTransitionTo(eq(ScrimState.AUTH_SCRIMMED_SHADE));
855         verify(mStatusBarKeyguardViewManager).onKeyguardFadedAway();
856     }
857 
858     @Test
859     @DisableFlags(FLAG_DEVICE_ENTRY_UDFPS_REFACTOR)
testOccludingQSNotExpanded_flagOff_transitionToAuthScrimmed()860     public void testOccludingQSNotExpanded_flagOff_transitionToAuthScrimmed() {
861         when(mAlternateBouncerInteractor.isVisibleState()).thenReturn(true);
862 
863         // GIVEN device occluded and panel is NOT expanded
864         mCentralSurfaces.setBarStateForTest(SHADE); // occluding on LS has StatusBarState = SHADE
865         when(mKeyguardStateController.isOccluded()).thenReturn(true);
866         when(mNotificationPanelViewController.isPanelExpanded()).thenReturn(false);
867 
868         mCentralSurfaces.updateScrimController();
869 
870         verify(mScrimController).legacyTransitionTo(eq(ScrimState.AUTH_SCRIMMED));
871     }
872 
873     @Test
874     @EnableFlags(FLAG_DEVICE_ENTRY_UDFPS_REFACTOR)
testNotOccluding_QSNotExpanded_flagOn_doesNotTransitionScrimState()875     public void testNotOccluding_QSNotExpanded_flagOn_doesNotTransitionScrimState() {
876         when(mAlternateBouncerInteractor.isVisibleState()).thenReturn(true);
877 
878         // GIVEN device occluded and panel is NOT expanded
879         mCentralSurfaces.setBarStateForTest(SHADE);
880         when(mKeyguardStateController.isOccluded()).thenReturn(false);
881         when(mNotificationPanelViewController.isPanelExpanded()).thenReturn(false);
882 
883         mCentralSurfaces.updateScrimController();
884 
885         // Tests the safeguard to reset the scrimstate
886         verify(mScrimController, never()).legacyTransitionTo(any());
887     }
888 
889     @Test
890     @EnableFlags(FLAG_DEVICE_ENTRY_UDFPS_REFACTOR)
testNotOccluding_QSExpanded_flagOn_doesTransitionScrimStateToKeyguard()891     public void testNotOccluding_QSExpanded_flagOn_doesTransitionScrimStateToKeyguard() {
892         when(mAlternateBouncerInteractor.isVisibleState()).thenReturn(true);
893 
894         // GIVEN device occluded and panel is NOT expanded
895         mCentralSurfaces.setBarStateForTest(SHADE);
896         when(mKeyguardStateController.isOccluded()).thenReturn(false);
897         when(mNotificationPanelViewController.isPanelExpanded()).thenReturn(true);
898 
899         mCentralSurfaces.updateScrimController();
900 
901         // Tests the safeguard to reset the scrimstate
902         verify(mScrimController, never()).legacyTransitionTo(eq(ScrimState.KEYGUARD));
903     }
904 
905     @Test
906     @DisableFlags(FLAG_DEVICE_ENTRY_UDFPS_REFACTOR)
testOccludingQSExpanded_transitionToAuthScrimmedShade()907     public void testOccludingQSExpanded_transitionToAuthScrimmedShade() {
908         when(mAlternateBouncerInteractor.isVisibleState()).thenReturn(true);
909 
910         // GIVEN device occluded and qs IS expanded
911         mCentralSurfaces.setBarStateForTest(SHADE); // occluding on LS has StatusBarState = SHADE
912         when(mKeyguardStateController.isOccluded()).thenReturn(true);
913         when(mNotificationPanelViewController.isPanelExpanded()).thenReturn(true);
914 
915         mCentralSurfaces.updateScrimController();
916 
917         verify(mScrimController).legacyTransitionTo(eq(ScrimState.AUTH_SCRIMMED_SHADE));
918     }
919 
920     @Test
testEnteringGlanceableHub_updatesScrim()921     public void testEnteringGlanceableHub_updatesScrim() {
922         // Transition to the glanceable hub.
923         mKosmos.getCommunalRepository()
924                 .setTransitionState(
925                         flowOf(new ObservableTransitionState.Idle(CommunalScenes.Communal)));
926         mTestScope.getTestScheduler().runCurrent();
927 
928         // ScrimState also transitions.
929         verify(mScrimController).legacyTransitionTo(ScrimState.GLANCEABLE_HUB);
930 
931         // Transition away from the glanceable hub.
932         mKosmos.getCommunalRepository()
933                 .setTransitionState(
934                         flowOf(new ObservableTransitionState.Idle(CommunalScenes.Blank)));
935         mTestScope.getTestScheduler().runCurrent();
936 
937         // ScrimState goes back to UNLOCKED.
938         verify(mScrimController).legacyTransitionTo(eq(ScrimState.UNLOCKED), any());
939     }
940 
941     @Test
testEnteringGlanceableHub_whenDreaming_updatesScrim()942     public void testEnteringGlanceableHub_whenDreaming_updatesScrim() {
943         when(mKeyguardStateController.isShowing()).thenReturn(true);
944         when(mKeyguardStateController.isOccluded()).thenReturn(true);
945         when(mKeyguardUpdateMonitor.isDreaming()).thenReturn(true);
946 
947         // Transition to the glanceable hub.
948         mKosmos.getCommunalRepository()
949                 .setTransitionState(
950                         flowOf(new ObservableTransitionState.Idle(CommunalScenes.Communal)));
951         mTestScope.getTestScheduler().runCurrent();
952 
953         // ScrimState also transitions.
954         verify(mScrimController).legacyTransitionTo(ScrimState.GLANCEABLE_HUB_OVER_DREAM);
955 
956         // Transition away from the glanceable hub.
957         mKosmos.getCommunalRepository()
958                 .setTransitionState(
959                         flowOf(new ObservableTransitionState.Idle(CommunalScenes.Blank)));
960         mTestScope.getTestScheduler().runCurrent();
961 
962         // ScrimState goes back to UNLOCKED.
963         verify(mScrimController).legacyTransitionTo(eq(ScrimState.DREAMING));
964     }
965 
966     @Test
testShowKeyguardImplementation_setsState()967     public void testShowKeyguardImplementation_setsState() {
968         when(mLockscreenUserManager.getCurrentProfiles()).thenReturn(new SparseArray<>());
969 
970         mCentralSurfaces.setBarStateForTest(SHADE);
971 
972         // By default, showKeyguardImpl sets state to KEYGUARD.
973         mCentralSurfaces.showKeyguardImpl();
974         verify(mStatusBarStateController).setState(
975                 eq(StatusBarState.KEYGUARD), eq(false) /* force */);
976     }
977 
978     @Test
testOnStartedWakingUp_isNotDozing()979     public void testOnStartedWakingUp_isNotDozing() {
980         mCentralSurfaces.setBarStateForTest(StatusBarState.KEYGUARD);
981         when(mStatusBarStateController.isKeyguardRequested()).thenReturn(true);
982         when(mDozeServiceHost.getDozingRequested()).thenReturn(true);
983         mCentralSurfaces.updateIsKeyguard();
984         // TODO: mNotificationPanelView.expand(false) gets called twice. Should be once.
985         verify(mNotificationPanelViewController, times(2)).expand(eq(false));
986         clearInvocations(mNotificationPanelViewController);
987 
988         mCentralSurfaces.mWakefulnessObserver.onStartedWakingUp();
989         verify(mDozeServiceHost, never()).stopDozing();
990         verify(mNotificationPanelViewController).expand(eq(false));
991         mCentralSurfaces.mWakefulnessObserver.onFinishedWakingUp();
992         verify(mDozeServiceHost).stopDozing();
993     }
994 
995     @Test
testOnStartedWakingUp_doesNotDismissBouncer_whenPulsing()996     public void testOnStartedWakingUp_doesNotDismissBouncer_whenPulsing() {
997         mCentralSurfaces.setBarStateForTest(StatusBarState.KEYGUARD);
998         when(mStatusBarStateController.isKeyguardRequested()).thenReturn(true);
999         when(mDozeServiceHost.getDozingRequested()).thenReturn(true);
1000         mCentralSurfaces.updateIsKeyguard();
1001         clearInvocations(mNotificationPanelViewController);
1002 
1003         mCentralSurfaces.setBouncerShowing(true);
1004         mCentralSurfaces.mWakefulnessObserver.onStartedWakingUp();
1005         verify(mNotificationPanelViewController, never()).expand(anyBoolean());
1006         mCentralSurfaces.mWakefulnessObserver.onFinishedWakingUp();
1007         verify(mDozeServiceHost).stopDozing();
1008     }
1009 
1010     @Test
testRegisterBroadcastsonDispatcher()1011     public void testRegisterBroadcastsonDispatcher() {
1012         mCentralSurfaces.registerBroadcastReceiver();
1013         verify(mBroadcastDispatcher).registerReceiver(
1014                 any(BroadcastReceiver.class),
1015                 any(IntentFilter.class),
1016                 eq(null),
1017                 any(UserHandle.class));
1018     }
1019 
1020     @Test
testUpdateResources_updatesBouncer()1021     public void testUpdateResources_updatesBouncer() {
1022         mCentralSurfaces.updateResources();
1023 
1024         verify(mStatusBarKeyguardViewManager).updateResources();
1025     }
1026 
1027     @Test
deviceStateChange_unfolded_shadeOpen_setsLeaveOpenOnKeyguardHide()1028     public void deviceStateChange_unfolded_shadeOpen_setsLeaveOpenOnKeyguardHide() {
1029         setFoldedStates(FOLD_STATE_FOLDED);
1030         setGoToSleepStates(FOLD_STATE_FOLDED);
1031         mCentralSurfaces.setBarStateForTest(SHADE);
1032         when(mNotificationPanelViewController.isShadeFullyExpanded()).thenReturn(true);
1033 
1034         setDeviceState(FOLD_STATE_UNFOLDED);
1035 
1036         verify(mStatusBarStateController).setLeaveOpenOnKeyguardHide(true);
1037     }
1038 
1039     @Test
deviceStateChange_unfolded_shadeOpen_onKeyguard_doesNotSetLeaveOpenOnKeyguardHide()1040     public void deviceStateChange_unfolded_shadeOpen_onKeyguard_doesNotSetLeaveOpenOnKeyguardHide() {
1041         setFoldedStates(FOLD_STATE_FOLDED);
1042         setGoToSleepStates(FOLD_STATE_FOLDED);
1043         mCentralSurfaces.setBarStateForTest(KEYGUARD);
1044         when(mNotificationPanelViewController.isShadeFullyExpanded()).thenReturn(true);
1045 
1046         setDeviceState(FOLD_STATE_UNFOLDED);
1047 
1048         verify(mStatusBarStateController, never()).setLeaveOpenOnKeyguardHide(true);
1049     }
1050 
1051 
1052     @Test
deviceStateChange_unfolded_shadeClose_doesNotSetLeaveOpenOnKeyguardHide()1053     public void deviceStateChange_unfolded_shadeClose_doesNotSetLeaveOpenOnKeyguardHide() {
1054         setFoldedStates(FOLD_STATE_FOLDED);
1055         setGoToSleepStates(FOLD_STATE_FOLDED);
1056         mCentralSurfaces.setBarStateForTest(SHADE);
1057         when(mNotificationPanelViewController.isShadeFullyExpanded()).thenReturn(false);
1058 
1059         setDeviceState(FOLD_STATE_UNFOLDED);
1060 
1061         verify(mStatusBarStateController, never()).setLeaveOpenOnKeyguardHide(true);
1062     }
1063 
1064     @Test
deviceStateChange_unfolded_shadeExpanding_onKeyguard_closesQS()1065     public void deviceStateChange_unfolded_shadeExpanding_onKeyguard_closesQS() {
1066         setFoldedStates(FOLD_STATE_FOLDED);
1067         setGoToSleepStates(FOLD_STATE_FOLDED);
1068         mCentralSurfaces.setBarStateForTest(KEYGUARD);
1069         when(mNotificationPanelViewController.isExpandingOrCollapsing()).thenReturn(true);
1070 
1071         setDeviceState(FOLD_STATE_UNFOLDED);
1072         mScreenLifecycle.dispatchScreenTurnedOff();
1073 
1074         verify(mQuickSettingsController).closeQs();
1075     }
1076 
1077     @Test
deviceStateChange_unfolded_shadeExpanded_onKeyguard_closesQS()1078     public void deviceStateChange_unfolded_shadeExpanded_onKeyguard_closesQS() {
1079         setFoldedStates(FOLD_STATE_FOLDED);
1080         setGoToSleepStates(FOLD_STATE_FOLDED);
1081         mCentralSurfaces.setBarStateForTest(KEYGUARD);
1082         when(mNotificationPanelViewController.isShadeFullyExpanded()).thenReturn(true);
1083 
1084         setDeviceState(FOLD_STATE_UNFOLDED);
1085         mScreenLifecycle.dispatchScreenTurnedOff();
1086 
1087         verify(mQuickSettingsController).closeQs();
1088     }
1089 
1090     @Test
testKeyguardHideDelayedIfOcclusionAnimationRunning()1091     public void testKeyguardHideDelayedIfOcclusionAnimationRunning() {
1092         // Show the keyguard and verify we've done so.
1093         setKeyguardShowingAndOccluded(true /* showing */, false /* occluded */);
1094         verify(mStatusBarStateController).setState(StatusBarState.KEYGUARD);
1095 
1096         // Request to hide the keyguard, but while the occlude animation is playing. We should delay
1097         // this hide call, since we're playing the occlude animation over the keyguard and thus want
1098         // it to remain visible.
1099         when(mKeyguardViewMediator.isOccludeAnimationPlaying()).thenReturn(true);
1100         setKeyguardShowingAndOccluded(false /* showing */, true /* occluded */);
1101         verify(mStatusBarStateController, never()).setState(SHADE);
1102 
1103         // Once the animation ends, verify that the keyguard is actually hidden.
1104         when(mKeyguardViewMediator.isOccludeAnimationPlaying()).thenReturn(false);
1105         setKeyguardShowingAndOccluded(false /* showing */, true /* occluded */);
1106         verify(mStatusBarStateController).setState(SHADE);
1107     }
1108 
1109     @Test
testKeyguardHideNotDelayedIfOcclusionAnimationNotRunning()1110     public void testKeyguardHideNotDelayedIfOcclusionAnimationNotRunning() {
1111         // Show the keyguard and verify we've done so.
1112         setKeyguardShowingAndOccluded(true /* showing */, false /* occluded */);
1113         verify(mStatusBarStateController).setState(StatusBarState.KEYGUARD);
1114 
1115         // Hide the keyguard while the occlusion animation is not running. Verify that we
1116         // immediately hide the keyguard.
1117         when(mKeyguardViewMediator.isOccludeAnimationPlaying()).thenReturn(false);
1118         setKeyguardShowingAndOccluded(false /* showing */, true /* occluded */);
1119         verify(mStatusBarStateController).setState(SHADE);
1120     }
1121 
1122     /** Regression test for b/298355063 */
1123     @Test
fingerprintManagerNull_noNPE()1124     public void fingerprintManagerNull_noNPE() {
1125         // GIVEN null fingerprint manager
1126         mFingerprintManager = null;
1127         createCentralSurfaces();
1128 
1129         // GIVEN should animate doze wakeup
1130         when(mDozeServiceHost.shouldAnimateWakeup()).thenReturn(true);
1131         when(mBiometricUnlockController.getMode()).thenReturn(
1132                 BiometricUnlockController.MODE_ONLY_WAKE);
1133         when(mDozeServiceHost.isPulsing()).thenReturn(false);
1134         when(mStatusBarStateController.getDozeAmount()).thenReturn(1f);
1135 
1136         // WHEN waking up from the power button
1137         mWakefulnessLifecycle.dispatchStartedWakingUp(PowerManager.WAKE_REASON_POWER_BUTTON);
1138         mCentralSurfaces.mWakefulnessObserver.onStartedWakingUp();
1139 
1140         // THEN no NPE when fingerprintManager is null
1141     }
1142 
1143     @Test
bubbleBarVisibility()1144     public void bubbleBarVisibility() {
1145         createCentralSurfaces();
1146         mCentralSurfaces.onStatusBarWindowStateChanged(WINDOW_STATE_HIDDEN);
1147         verify(mBubbles).onStatusBarVisibilityChanged(false);
1148 
1149         mCentralSurfaces.onStatusBarWindowStateChanged(WINDOW_STATE_SHOWING);
1150         verify(mBubbles).onStatusBarVisibilityChanged(true);
1151     }
1152 
1153     @Test
1154     @EnableFlags(com.android.systemui.Flags.FLAG_TRUNCATED_STATUS_BAR_ICONS_FIX)
updateResources_flagEnabled_doesNotUpdateStatusBarWindowHeight()1155     public void updateResources_flagEnabled_doesNotUpdateStatusBarWindowHeight() {
1156         mCentralSurfaces.updateResources();
1157 
1158         verify(mStatusBarWindowController, never()).refreshStatusBarHeight();
1159     }
1160 
1161     @Test
1162     @DisableFlags(com.android.systemui.Flags.FLAG_TRUNCATED_STATUS_BAR_ICONS_FIX)
updateResources_flagDisabled_updatesStatusBarWindowHeight()1163     public void updateResources_flagDisabled_updatesStatusBarWindowHeight() {
1164         mCentralSurfaces.updateResources();
1165 
1166         verify(mStatusBarWindowController).refreshStatusBarHeight();
1167     }
1168 
1169     @Test
1170     @EnableSceneContainer
brightnesShowingChanged_flagEnabled_ScrimControllerNotified()1171     public void brightnesShowingChanged_flagEnabled_ScrimControllerNotified() {
1172         mCentralSurfaces.registerCallbacks();
1173         final ScrimStartable scrimStartable = mKosmos.getScrimStartable();
1174         scrimStartable.start();
1175 
1176         mBrightnessMirrorShowingInteractor.setMirrorShowing(true);
1177         mTestScope.getTestScheduler().runCurrent();
1178         verify(mScrimController, atLeastOnce()).transitionTo(ScrimState.BRIGHTNESS_MIRROR);
1179 
1180         mBrightnessMirrorShowingInteractor.setMirrorShowing(false);
1181         mTestScope.getTestScheduler().runCurrent();
1182         ArgumentCaptor<ScrimState> captor = ArgumentCaptor.forClass(ScrimState.class);
1183         // The default is to call the one with the callback argument
1184         verify(mScrimController, atLeastOnce()).transitionTo(captor.capture());
1185         assertThat(captor.getValue()).isNotEqualTo(ScrimState.BRIGHTNESS_MIRROR);
1186     }
1187 
1188     @Test
1189     @DisableSceneContainer
brightnesShowingChanged_flagDisabled_ScrimControllerNotified()1190     public void brightnesShowingChanged_flagDisabled_ScrimControllerNotified() {
1191         mCentralSurfaces.registerCallbacks();
1192 
1193         mBrightnessMirrorShowingInteractor.setMirrorShowing(true);
1194         mTestScope.getTestScheduler().runCurrent();
1195         verify(mScrimController, never()).legacyTransitionTo(ScrimState.BRIGHTNESS_MIRROR);
1196         verify(mScrimController, never())
1197                 .legacyTransitionTo(eq(ScrimState.BRIGHTNESS_MIRROR), any());
1198     }
1199 
1200     @Test
1201     @EnableFlags(FLAG_KEYBOARD_SHORTCUT_HELPER_REWRITE)
dismissKeyboardShortcuts_largeScreen_bothFlagsEnabled_doesNotDismissAny()1202     public void dismissKeyboardShortcuts_largeScreen_bothFlagsEnabled_doesNotDismissAny() {
1203         switchToLargeScreen();
1204         mFeatureFlags.set(SHORTCUT_LIST_SEARCH_LAYOUT, true);
1205         createCentralSurfaces();
1206 
1207         dismissKeyboardShortcuts();
1208 
1209         verifyNoMoreInteractions(mKeyboardShortcuts, mKeyboardShortcutListSearch);
1210     }
1211 
1212     @Test
1213     @DisableFlags(FLAG_KEYBOARD_SHORTCUT_HELPER_REWRITE)
dismissKeyboardShortcuts_largeScreen_newFlagsDisabled_dismissesTabletVersion()1214     public void dismissKeyboardShortcuts_largeScreen_newFlagsDisabled_dismissesTabletVersion() {
1215         switchToLargeScreen();
1216         mFeatureFlags.set(SHORTCUT_LIST_SEARCH_LAYOUT, true);
1217         createCentralSurfaces();
1218 
1219         dismissKeyboardShortcuts();
1220 
1221         verify(mKeyboardShortcutListSearch).dismissKeyboardShortcuts();
1222     }
1223 
1224     @Test
1225     @DisableFlags(FLAG_KEYBOARD_SHORTCUT_HELPER_REWRITE)
dismissKeyboardShortcuts_largeScreen_bothFlagsDisabled_dismissesPhoneVersion()1226     public void dismissKeyboardShortcuts_largeScreen_bothFlagsDisabled_dismissesPhoneVersion() {
1227         switchToLargeScreen();
1228         mFeatureFlags.set(SHORTCUT_LIST_SEARCH_LAYOUT, false);
1229         createCentralSurfaces();
1230 
1231         dismissKeyboardShortcuts();
1232 
1233         verify(mKeyboardShortcuts).dismissKeyboardShortcuts();
1234         verifyNoMoreInteractions(mKeyboardShortcutListSearch);
1235     }
1236 
1237     @Test
1238     @EnableFlags(FLAG_KEYBOARD_SHORTCUT_HELPER_REWRITE)
dismissKeyboardShortcuts_smallScreen_bothFlagsEnabled_doesNotDismissAny()1239     public void dismissKeyboardShortcuts_smallScreen_bothFlagsEnabled_doesNotDismissAny() {
1240         switchToSmallScreen();
1241         mFeatureFlags.set(SHORTCUT_LIST_SEARCH_LAYOUT, true);
1242         createCentralSurfaces();
1243 
1244         dismissKeyboardShortcuts();
1245 
1246         verifyNoMoreInteractions(mKeyboardShortcuts, mKeyboardShortcutListSearch);
1247     }
1248 
1249     @Test
1250     @DisableFlags(FLAG_KEYBOARD_SHORTCUT_HELPER_REWRITE)
dismissKeyboardShortcuts_smallScreen_newFlagsDisabled_dismissesPhoneVersion()1251     public void dismissKeyboardShortcuts_smallScreen_newFlagsDisabled_dismissesPhoneVersion() {
1252         switchToSmallScreen();
1253         mFeatureFlags.set(SHORTCUT_LIST_SEARCH_LAYOUT, true);
1254         createCentralSurfaces();
1255 
1256         dismissKeyboardShortcuts();
1257 
1258         verify(mKeyboardShortcuts).dismissKeyboardShortcuts();
1259         verifyNoMoreInteractions(mKeyboardShortcutListSearch);
1260     }
1261 
1262     @Test
1263     @DisableFlags(FLAG_KEYBOARD_SHORTCUT_HELPER_REWRITE)
dismissKeyboardShortcuts_smallScreen_bothFlagsDisabled_dismissesPhoneVersion()1264     public void dismissKeyboardShortcuts_smallScreen_bothFlagsDisabled_dismissesPhoneVersion() {
1265         switchToSmallScreen();
1266         mFeatureFlags.set(SHORTCUT_LIST_SEARCH_LAYOUT, false);
1267         createCentralSurfaces();
1268 
1269         dismissKeyboardShortcuts();
1270 
1271         verify(mKeyboardShortcuts).dismissKeyboardShortcuts();
1272         verifyNoMoreInteractions(mKeyboardShortcutListSearch);
1273     }
1274 
1275     @Test
1276     @EnableFlags(FLAG_KEYBOARD_SHORTCUT_HELPER_REWRITE)
toggleKeyboardShortcuts_largeScreen_bothFlagsEnabled_doesNotTogglesAny()1277     public void toggleKeyboardShortcuts_largeScreen_bothFlagsEnabled_doesNotTogglesAny() {
1278         switchToLargeScreen();
1279         mFeatureFlags.set(SHORTCUT_LIST_SEARCH_LAYOUT, true);
1280         createCentralSurfaces();
1281 
1282         int deviceId = 321;
1283         toggleKeyboardShortcuts(/* deviceId= */ deviceId);
1284 
1285         verifyNoMoreInteractions(mKeyboardShortcuts, mKeyboardShortcutListSearch);
1286     }
1287 
1288     @Test
1289     @DisableFlags(FLAG_KEYBOARD_SHORTCUT_HELPER_REWRITE)
toggleKeyboardShortcuts_largeScreen_newFlagsDisabled_togglesTabletVersion()1290     public void toggleKeyboardShortcuts_largeScreen_newFlagsDisabled_togglesTabletVersion() {
1291         switchToLargeScreen();
1292         mFeatureFlags.set(SHORTCUT_LIST_SEARCH_LAYOUT, true);
1293         createCentralSurfaces();
1294 
1295         int deviceId = 654;
1296         toggleKeyboardShortcuts(deviceId);
1297 
1298         verify(mKeyboardShortcutListSearch).showKeyboardShortcuts(deviceId);
1299         verifyNoMoreInteractions(mKeyboardShortcuts);
1300     }
1301 
1302     @Test
1303     @DisableFlags(FLAG_KEYBOARD_SHORTCUT_HELPER_REWRITE)
toggleKeyboardShortcuts_largeScreen_bothFlagsDisabled_togglesPhoneVersion()1304     public void toggleKeyboardShortcuts_largeScreen_bothFlagsDisabled_togglesPhoneVersion() {
1305         switchToLargeScreen();
1306         mFeatureFlags.set(SHORTCUT_LIST_SEARCH_LAYOUT, false);
1307         createCentralSurfaces();
1308 
1309         int deviceId = 987;
1310         toggleKeyboardShortcuts(deviceId);
1311 
1312         verify(mKeyboardShortcuts).showKeyboardShortcuts(deviceId);
1313         verifyNoMoreInteractions(mKeyboardShortcutListSearch);
1314     }
1315 
1316     @Test
1317     @EnableFlags(FLAG_KEYBOARD_SHORTCUT_HELPER_REWRITE)
toggleKeyboardShortcuts_smallScreen_bothFlagsEnabled_doesNotToggleAny()1318     public void toggleKeyboardShortcuts_smallScreen_bothFlagsEnabled_doesNotToggleAny() {
1319         switchToSmallScreen();
1320         mFeatureFlags.set(SHORTCUT_LIST_SEARCH_LAYOUT, true);
1321         createCentralSurfaces();
1322 
1323         int deviceId = 789;
1324         toggleKeyboardShortcuts(/* deviceId= */ deviceId);
1325 
1326         verifyNoMoreInteractions(mKeyboardShortcuts, mKeyboardShortcutListSearch);
1327     }
1328 
1329     @Test
1330     @DisableFlags(FLAG_KEYBOARD_SHORTCUT_HELPER_REWRITE)
toggleKeyboardShortcuts_smallScreen_newFlagsDisabled_togglesPhoneVersion()1331     public void toggleKeyboardShortcuts_smallScreen_newFlagsDisabled_togglesPhoneVersion() {
1332         switchToSmallScreen();
1333         mFeatureFlags.set(SHORTCUT_LIST_SEARCH_LAYOUT, true);
1334         createCentralSurfaces();
1335 
1336         int deviceId = 456;
1337         toggleKeyboardShortcuts(deviceId);
1338 
1339         verify(mKeyboardShortcuts).showKeyboardShortcuts(deviceId);
1340         verifyNoMoreInteractions(mKeyboardShortcutListSearch);
1341     }
1342 
1343     @Test
1344     @DisableFlags(FLAG_KEYBOARD_SHORTCUT_HELPER_REWRITE)
toggleKeyboardShortcuts_smallScreen_bothFlagsDisabled_togglesPhoneVersion()1345     public void toggleKeyboardShortcuts_smallScreen_bothFlagsDisabled_togglesPhoneVersion() {
1346         switchToSmallScreen();
1347         mFeatureFlags.set(SHORTCUT_LIST_SEARCH_LAYOUT, false);
1348         createCentralSurfaces();
1349 
1350         int deviceId = 123;
1351         toggleKeyboardShortcuts(deviceId);
1352 
1353         verify(mKeyboardShortcuts).showKeyboardShortcuts(deviceId);
1354         verifyNoMoreInteractions(mKeyboardShortcutListSearch);
1355     }
1356 
dismissKeyboardShortcuts()1357     private void dismissKeyboardShortcuts() {
1358         mMessageRouter.sendMessage(MSG_DISMISS_KEYBOARD_SHORTCUTS_MENU);
1359         mMainExecutor.runAllReady();
1360     }
1361 
toggleKeyboardShortcuts(int deviceId)1362     private void toggleKeyboardShortcuts(int deviceId) {
1363         mMessageRouter.sendMessage(new CentralSurfaces.KeyboardShortcutsMessage(deviceId));
1364         mMainExecutor.runAllReady();
1365     }
1366 
switchToLargeScreen()1367     private void switchToLargeScreen() {
1368         switchToScreenSize(1280, 800);
1369     }
1370 
switchToSmallScreen()1371     private void switchToSmallScreen() {
1372         switchToScreenSize(504, 1122);
1373     }
1374 
switchToScreenSize(int widthDp, int heightDp)1375     private void switchToScreenSize(int widthDp, int heightDp) {
1376         WindowMetrics windowMetrics = Mockito.mock(WindowMetrics.class);
1377         WindowManager windowManager = Mockito.mock(WindowManager.class);
1378 
1379         Configuration configuration = new Configuration();
1380         configuration.densityDpi = DisplayMetrics.DENSITY_DEFAULT;
1381         mContext.getOrCreateTestableResources().overrideConfiguration(configuration);
1382 
1383         when(windowMetrics.getBounds()).thenReturn(new Rect(0, 0, widthDp, heightDp));
1384         when(windowManager.getCurrentWindowMetrics()).thenReturn(windowMetrics);
1385         mContext.addMockSystemService(WindowManager.class, windowManager);
1386     }
1387 
1388     /**
1389      * Configures the appropriate mocks and then calls {@link CentralSurfacesImpl#updateIsKeyguard}
1390      * to reconfigure the keyguard to reflect the requested showing/occluded states.
1391      */
setKeyguardShowingAndOccluded(boolean showing, boolean occluded)1392     private void setKeyguardShowingAndOccluded(boolean showing, boolean occluded) {
1393         when(mStatusBarStateController.isKeyguardRequested()).thenReturn(showing);
1394         when(mKeyguardStateController.isOccluded()).thenReturn(occluded);
1395 
1396         // If we want to show the keyguard, make sure that we think we're awake and not unlocking.
1397         if (showing) {
1398             when(mBiometricUnlockController.isWakeAndUnlock()).thenReturn(false);
1399             mWakefulnessLifecycle.dispatchStartedWakingUp(PowerManager.WAKE_REASON_UNKNOWN);
1400         }
1401 
1402         mCentralSurfaces.updateIsKeyguard(false /* forceStateChange */);
1403     }
1404 
setDeviceState(int state)1405     private void setDeviceState(int state) {
1406         DeviceState deviceState = new DeviceState(
1407                 new DeviceState.Configuration.Builder(state, "TEST").build());
1408         ArgumentCaptor<DeviceStateManager.DeviceStateCallback> callbackCaptor =
1409                 ArgumentCaptor.forClass(DeviceStateManager.DeviceStateCallback.class);
1410         verify(mDeviceStateManager).registerCallback(any(), callbackCaptor.capture());
1411         callbackCaptor.getValue().onDeviceStateChanged(deviceState);
1412     }
1413 
setGoToSleepStates(int... states)1414     private void setGoToSleepStates(int... states) {
1415         mContext.getOrCreateTestableResources().addOverride(
1416                 com.android.internal.R.array.config_deviceStatesOnWhichToSleep,
1417                 states);
1418     }
1419 
setFoldedStates(int... states)1420     private void setFoldedStates(int... states) {
1421         mContext.getOrCreateTestableResources().addOverride(
1422                 com.android.internal.R.array.config_foldedDeviceStates,
1423                 states);
1424     }
1425 
setDozing(boolean isDozing)1426     private void setDozing(boolean isDozing) {
1427         ArgumentCaptor<StatusBarStateController.StateListener> callbackCaptor =
1428                 ArgumentCaptor.forClass(StatusBarStateController.StateListener.class);
1429         verify(mStatusBarStateController).addCallback(callbackCaptor.capture(), anyInt());
1430         callbackCaptor.getValue().onDozingChanged(isDozing);
1431     }
1432 }
1433