1 /*
2  * Copyright (C) 2020 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.navigationbar;
18 
19 import static android.app.StatusBarManager.NAVIGATION_HINT_BACK_ALT;
20 import static android.app.StatusBarManager.NAVIGATION_HINT_IME_SHOWN;
21 import static android.app.StatusBarManager.NAVIGATION_HINT_IME_SWITCHER_SHOWN;
22 import static android.inputmethodservice.InputMethodService.BACK_DISPOSITION_DEFAULT;
23 import static android.inputmethodservice.InputMethodService.IME_INVISIBLE;
24 import static android.inputmethodservice.InputMethodService.IME_VISIBLE;
25 import static android.view.Display.DEFAULT_DISPLAY;
26 import static android.view.DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS;
27 import static android.view.WindowInsets.Type.ime;
28 
29 import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.HOME_BUTTON_LONG_PRESS_DURATION_MS;
30 import static com.android.systemui.navigationbar.NavigationBar.NavBarActionEvent.NAVBAR_ASSIST_LONGPRESS;
31 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_SCREEN_PINNING;
32 
33 import static org.junit.Assert.assertEquals;
34 import static org.junit.Assert.assertFalse;
35 import static org.junit.Assert.assertTrue;
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.Matchers.eq;
40 import static org.mockito.Mockito.doNothing;
41 import static org.mockito.Mockito.doReturn;
42 import static org.mockito.Mockito.mock;
43 import static org.mockito.Mockito.spy;
44 import static org.mockito.Mockito.times;
45 import static org.mockito.Mockito.verify;
46 import static org.mockito.Mockito.when;
47 
48 import android.app.ActivityManager;
49 import android.content.Context;
50 import android.content.res.Resources;
51 import android.hardware.display.DisplayManagerGlobal;
52 import android.os.Handler;
53 import android.os.SystemClock;
54 import android.provider.DeviceConfig;
55 import android.telecom.TelecomManager;
56 import android.testing.AndroidTestingRunner;
57 import android.testing.TestableLooper;
58 import android.testing.TestableLooper.RunWithLooper;
59 import android.view.Display;
60 import android.view.DisplayInfo;
61 import android.view.IWindowManager;
62 import android.view.MotionEvent;
63 import android.view.View;
64 import android.view.ViewRootImpl;
65 import android.view.ViewTreeObserver;
66 import android.view.WindowInsets;
67 import android.view.WindowManager;
68 import android.view.WindowMetrics;
69 import android.view.accessibility.AccessibilityManager;
70 import android.view.inputmethod.InputMethodManager;
71 
72 import androidx.test.filters.SmallTest;
73 
74 import com.android.internal.logging.MetricsLogger;
75 import com.android.internal.logging.UiEventLogger;
76 import com.android.systemui.SysuiTestCase;
77 import com.android.systemui.SysuiTestableContext;
78 import com.android.systemui.accessibility.AccessibilityButtonModeObserver;
79 import com.android.systemui.accessibility.AccessibilityButtonTargetsObserver;
80 import com.android.systemui.accessibility.SystemActions;
81 import com.android.systemui.assist.AssistManager;
82 import com.android.systemui.dump.DumpManager;
83 import com.android.systemui.keyguard.WakefulnessLifecycle;
84 import com.android.systemui.model.SysUiState;
85 import com.android.systemui.navigationbar.buttons.ButtonDispatcher;
86 import com.android.systemui.navigationbar.buttons.DeadZone;
87 import com.android.systemui.navigationbar.gestural.EdgeBackGestureHandler;
88 import com.android.systemui.plugins.statusbar.StatusBarStateController;
89 import com.android.systemui.recents.OverviewProxyService;
90 import com.android.systemui.recents.Recents;
91 import com.android.systemui.settings.DisplayTracker;
92 import com.android.systemui.settings.FakeDisplayTracker;
93 import com.android.systemui.settings.UserContextProvider;
94 import com.android.systemui.settings.UserTracker;
95 import com.android.systemui.shade.NotificationShadeWindowView;
96 import com.android.systemui.shade.ShadeController;
97 import com.android.systemui.shade.ShadeViewController;
98 import com.android.systemui.shared.rotation.RotationButtonController;
99 import com.android.systemui.shared.system.TaskStackChangeListeners;
100 import com.android.systemui.statusbar.CommandQueue;
101 import com.android.systemui.statusbar.NotificationRemoteInputManager;
102 import com.android.systemui.statusbar.NotificationShadeDepthController;
103 import com.android.systemui.statusbar.NotificationShadeWindowController;
104 import com.android.systemui.statusbar.phone.AutoHideController;
105 import com.android.systemui.statusbar.phone.CentralSurfaces;
106 import com.android.systemui.statusbar.phone.LightBarController;
107 import com.android.systemui.statusbar.phone.LightBarTransitionsController;
108 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
109 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
110 import com.android.systemui.statusbar.policy.KeyguardStateController;
111 import com.android.systemui.util.DeviceConfigProxyFake;
112 import com.android.systemui.util.concurrency.FakeExecutor;
113 import com.android.systemui.util.time.FakeSystemClock;
114 import com.android.systemui.utils.leaks.LeakCheckedTest;
115 import com.android.wm.shell.back.BackAnimation;
116 import com.android.wm.shell.pip.Pip;
117 
118 import org.junit.Before;
119 import org.junit.Rule;
120 import org.junit.Test;
121 import org.junit.runner.RunWith;
122 import org.mockito.Mock;
123 import org.mockito.MockitoAnnotations;
124 
125 import java.util.Optional;
126 import java.util.concurrent.Executor;
127 
128 @RunWith(AndroidTestingRunner.class)
129 @RunWithLooper(setAsMainLooper = true)
130 @SmallTest
131 public class NavigationBarTest extends SysuiTestCase {
132     private static final int EXTERNAL_DISPLAY_ID = 2;
133 
134     private NavigationBar mNavigationBar;
135     private NavigationBar mExternalDisplayNavigationBar;
136 
137     private SysuiTestableContext mSysuiTestableContextExternal;
138     @Mock
139     NavigationBarView mNavigationBarView;
140     @Mock
141     NavigationBarFrame mNavigationBarFrame;
142     @Mock
143     ButtonDispatcher mHomeButton;
144     @Mock
145     ButtonDispatcher mRecentsButton;
146     @Mock
147     ButtonDispatcher mAccessibilityButton;
148     @Mock
149     ButtonDispatcher mImeSwitchButton;
150     @Mock
151     ButtonDispatcher mBackButton;
152     @Mock
153     NavigationBarTransitions mNavigationBarTransitions;
154     @Mock
155     RotationButtonController mRotationButtonController;
156     @Mock
157     LightBarTransitionsController mLightBarTransitionsController;
158     @Mock
159     private SystemActions mSystemActions;
160     @Mock
161     private OverviewProxyService mOverviewProxyService;
162     @Mock
163     private StatusBarStateController mStatusBarStateController;
164     @Mock
165     private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
166     @Mock
167     private NavigationModeController mNavigationModeController;
168     @Mock
169     private CommandQueue mCommandQueue;
170     private SysUiState mMockSysUiState;
171     @Mock
172     private Handler mHandler;
173     @Mock
174     private UserTracker mUserTracker;
175     @Mock
176     private UiEventLogger mUiEventLogger;
177     @Mock
178     private ViewTreeObserver mViewTreeObserver;
179     NavBarHelper mNavBarHelper;
180     @Mock
181     private LightBarController mLightBarController;
182     @Mock
183     private LightBarController.Factory mLightBarcontrollerFactory;
184     @Mock
185     private AutoHideController mAutoHideController;
186     @Mock
187     private AutoHideController.Factory mAutoHideControllerFactory;
188     @Mock
189     private WindowManager mWindowManager;
190     @Mock
191     private TelecomManager mTelecomManager;
192     @Mock
193     private InputMethodManager mInputMethodManager;
194     @Mock
195     private AssistManager mAssistManager;
196     @Mock
197     private DeadZone mDeadZone;
198     @Mock
199     private CentralSurfaces mCentralSurfaces;
200     @Mock
201     private KeyguardStateController mKeyguardStateController;
202     @Mock
203     private UserContextProvider mUserContextProvider;
204     @Mock
205     private WakefulnessLifecycle mWakefulnessLifecycle;
206     @Mock
207     private Resources mResources;
208     @Mock
209     private ViewRootImpl mViewRootImpl;
210     @Mock
211     private EdgeBackGestureHandler.Factory mEdgeBackGestureHandlerFactory;
212     @Mock
213     private EdgeBackGestureHandler mEdgeBackGestureHandler;
214     @Mock
215     private NotificationShadeWindowController mNotificationShadeWindowController;
216     private FakeExecutor mFakeExecutor = new FakeExecutor(new FakeSystemClock());
217     private DeviceConfigProxyFake mDeviceConfigProxyFake = new DeviceConfigProxyFake();
218     private TaskStackChangeListeners mTaskStackChangeListeners =
219             TaskStackChangeListeners.getTestInstance();
220 
221     @Rule
222     public final LeakCheckedTest.SysuiLeakCheck mLeakCheck = new LeakCheckedTest.SysuiLeakCheck();
223 
224     @Before
setup()225     public void setup() throws Exception {
226         MockitoAnnotations.initMocks(this);
227 
228         when(mLightBarcontrollerFactory.create(any(Context.class))).thenReturn(mLightBarController);
229         when(mAutoHideControllerFactory.create(any(Context.class))).thenReturn(mAutoHideController);
230         when(mNavigationBarView.getHomeButton()).thenReturn(mHomeButton);
231         when(mNavigationBarView.getRecentsButton()).thenReturn(mRecentsButton);
232         when(mNavigationBarView.getAccessibilityButton()).thenReturn(mAccessibilityButton);
233         when(mNavigationBarView.getImeSwitchButton()).thenReturn(mImeSwitchButton);
234         when(mNavigationBarView.getBackButton()).thenReturn(mBackButton);
235         when(mNavigationBarView.getRotationButtonController())
236                 .thenReturn(mRotationButtonController);
237         when(mNavigationBarTransitions.getLightTransitionsController())
238                 .thenReturn(mLightBarTransitionsController);
239         when(mStatusBarKeyguardViewManager.isNavBarVisible()).thenReturn(true);
240         when(mNavigationBarView.getViewTreeObserver()).thenReturn(mViewTreeObserver);
241         when(mUserContextProvider.createCurrentUserContext(any(Context.class)))
242                 .thenReturn(mContext);
243         when(mNavigationBarView.getResources()).thenReturn(mResources);
244         when(mNavigationBarView.getViewRootImpl()).thenReturn(mViewRootImpl);
245         when(mEdgeBackGestureHandlerFactory.create(any())).thenReturn(mEdgeBackGestureHandler);
246         setupSysuiDependency();
247         // This class inflates views that call Dependency.get, thus these injections are still
248         // necessary.
249         mDependency.injectTestDependency(AssistManager.class, mAssistManager);
250         mDependency.injectMockDependency(KeyguardStateController.class);
251         mDependency.injectTestDependency(StatusBarStateController.class, mStatusBarStateController);
252         mDependency.injectMockDependency(NavigationBarController.class);
253         mDependency.injectTestDependency(OverviewProxyService.class, mOverviewProxyService);
254         mDependency.injectTestDependency(NavigationModeController.class, mNavigationModeController);
255         TestableLooper.get(this).runWithLooper(() -> {
256             mNavBarHelper = spy(new NavBarHelper(mContext, mock(AccessibilityManager.class),
257                     mock(AccessibilityButtonModeObserver.class),
258                     mock(AccessibilityButtonTargetsObserver.class),
259                     mSystemActions, mOverviewProxyService,
260                     () -> mock(AssistManager.class), () -> Optional.of(mCentralSurfaces),
261                     mKeyguardStateController, mock(NavigationModeController.class),
262                     mEdgeBackGestureHandlerFactory, mock(IWindowManager.class),
263                     mock(UserTracker.class), mock(DisplayTracker.class),
264                     mNotificationShadeWindowController, mock(DumpManager.class),
265                     mock(CommandQueue.class)));
266             mNavigationBar = createNavBar(mContext);
267             mExternalDisplayNavigationBar = createNavBar(mSysuiTestableContextExternal);
268         });
269     }
270 
setupSysuiDependency()271     private void setupSysuiDependency() {
272         Display display = new Display(DisplayManagerGlobal.getInstance(), EXTERNAL_DISPLAY_ID,
273                 new DisplayInfo(), DEFAULT_DISPLAY_ADJUSTMENTS);
274         mSysuiTestableContextExternal = (SysuiTestableContext) getContext().createDisplayContext(
275                 display);
276 
277         Display defaultDisplay = mContext.getDisplay();
278         when(mWindowManager.getDefaultDisplay()).thenReturn(defaultDisplay);
279         WindowMetrics metrics = mContext.getSystemService(WindowManager.class)
280                 .getMaximumWindowMetrics();
281         when(mWindowManager.getMaximumWindowMetrics()).thenReturn(metrics);
282         WindowMetrics currentWindowMetrics = mContext.getSystemService(WindowManager.class)
283                 .getCurrentWindowMetrics();
284         when(mWindowManager.getCurrentWindowMetrics()).thenReturn(currentWindowMetrics);
285         doNothing().when(mWindowManager).addView(any(), any());
286         doNothing().when(mWindowManager).removeViewImmediate(any());
287         mMockSysUiState = mock(SysUiState.class);
288         when(mMockSysUiState.setFlag(anyInt(), anyBoolean())).thenReturn(mMockSysUiState);
289 
290         mContext.addMockSystemService(WindowManager.class, mWindowManager);
291         mSysuiTestableContextExternal.addMockSystemService(WindowManager.class, mWindowManager);
292     }
293 
294     @Test
testHomeLongPress()295     public void testHomeLongPress() {
296         mNavigationBar.init();
297         mNavigationBar.onViewAttached();
298         mNavigationBar.onHomeLongClick(mNavigationBar.getView());
299 
300         verify(mUiEventLogger, times(1)).log(NAVBAR_ASSIST_LONGPRESS);
301     }
302 
303     @Test
testHomeLongPressWithCustomDuration()304     public void testHomeLongPressWithCustomDuration() throws Exception {
305         mDeviceConfigProxyFake.setProperty(
306                 DeviceConfig.NAMESPACE_SYSTEMUI,
307                 HOME_BUTTON_LONG_PRESS_DURATION_MS,
308                 "100",
309                 false);
310         when(mNavBarHelper.getLongPressHomeEnabled()).thenReturn(true);
311         mNavigationBar.init();
312         mNavigationBar.onViewAttached();
313 
314         mNavigationBar.onHomeTouch(mNavigationBar.getView(), MotionEvent.obtain(
315                 /*downTime=*/SystemClock.uptimeMillis(),
316                 /*eventTime=*/SystemClock.uptimeMillis(),
317                 /*action=*/MotionEvent.ACTION_DOWN,
318                 0, 0, 0
319         ));
320         verify(mHandler, times(1)).postDelayed(any(), eq(100L));
321 
322         mNavigationBar.onHomeTouch(mNavigationBar.getView(), MotionEvent.obtain(
323                 /*downTime=*/SystemClock.uptimeMillis(),
324                 /*eventTime=*/SystemClock.uptimeMillis(),
325                 /*action=*/MotionEvent.ACTION_UP,
326                 0, 0, 0
327         ));
328 
329         verify(mHandler, times(1)).removeCallbacks(any());
330     }
331 
332     @Test
testRegisteredWithUserTracker()333     public void testRegisteredWithUserTracker() {
334         mNavigationBar.init();
335         mNavigationBar.onViewAttached();
336         verify(mUserTracker).addCallback(any(UserTracker.Callback.class), any(Executor.class));
337     }
338 
339     @Test
testSetImeWindowStatusWhenImeSwitchOnDisplay()340     public void testSetImeWindowStatusWhenImeSwitchOnDisplay() {
341         // Create default & external NavBar fragment.
342         NavigationBar defaultNavBar = mNavigationBar;
343         NavigationBar externalNavBar = mExternalDisplayNavigationBar;
344         NotificationShadeWindowView mockShadeWindowView = mock(NotificationShadeWindowView.class);
345         WindowInsets windowInsets = new WindowInsets.Builder().setVisible(ime(), false).build();
346         doReturn(windowInsets).when(mockShadeWindowView).getRootWindowInsets();
347         doReturn(true).when(mockShadeWindowView).isAttachedToWindow();
348         doNothing().when(defaultNavBar).checkNavBarModes();
349         doNothing().when(externalNavBar).checkNavBarModes();
350         defaultNavBar.init();
351         externalNavBar.init();
352 
353         defaultNavBar.setImeWindowStatus(DEFAULT_DISPLAY, null, IME_VISIBLE,
354                 BACK_DISPOSITION_DEFAULT, true);
355 
356         // Verify IME window state will be updated in default NavBar & external NavBar state reset.
357         assertEquals(NAVIGATION_HINT_BACK_ALT | NAVIGATION_HINT_IME_SHOWN
358                         | NAVIGATION_HINT_IME_SWITCHER_SHOWN,
359                 defaultNavBar.getNavigationIconHints());
360         assertFalse((externalNavBar.getNavigationIconHints() & NAVIGATION_HINT_BACK_ALT) != 0);
361         assertFalse((externalNavBar.getNavigationIconHints() & NAVIGATION_HINT_IME_SHOWN) != 0);
362         assertFalse((externalNavBar.getNavigationIconHints() & NAVIGATION_HINT_IME_SWITCHER_SHOWN)
363                 != 0);
364 
365         externalNavBar.setImeWindowStatus(EXTERNAL_DISPLAY_ID, null, IME_VISIBLE,
366                 BACK_DISPOSITION_DEFAULT, true);
367         defaultNavBar.setImeWindowStatus(
368                 DEFAULT_DISPLAY, null, IME_INVISIBLE, BACK_DISPOSITION_DEFAULT, false);
369         // Verify IME window state will be updated in external NavBar & default NavBar state reset.
370         assertEquals(NAVIGATION_HINT_BACK_ALT | NAVIGATION_HINT_IME_SHOWN
371                         | NAVIGATION_HINT_IME_SWITCHER_SHOWN,
372                 externalNavBar.getNavigationIconHints());
373         assertFalse((defaultNavBar.getNavigationIconHints() & NAVIGATION_HINT_BACK_ALT) != 0);
374         assertFalse((defaultNavBar.getNavigationIconHints() & NAVIGATION_HINT_IME_SHOWN) != 0);
375         assertFalse((defaultNavBar.getNavigationIconHints() & NAVIGATION_HINT_IME_SWITCHER_SHOWN)
376                 != 0);
377     }
378 
379     @Test
testSetImeWindowStatusWhenKeyguardLockingAndImeInsetsChange()380     public void testSetImeWindowStatusWhenKeyguardLockingAndImeInsetsChange() {
381         NotificationShadeWindowView mockShadeWindowView = mock(NotificationShadeWindowView.class);
382         doReturn(mockShadeWindowView).when(mNotificationShadeWindowController).getWindowRootView();
383         doReturn(true).when(mockShadeWindowView).isAttachedToWindow();
384         doNothing().when(mNavigationBar).checkNavBarModes();
385         mNavigationBar.init();
386         WindowInsets windowInsets = new WindowInsets.Builder().setVisible(ime(), false).build();
387         doReturn(windowInsets).when(mockShadeWindowView).getRootWindowInsets();
388 
389         // Verify navbar altered back icon when an app is showing IME
390         mNavigationBar.setImeWindowStatus(DEFAULT_DISPLAY, null, IME_VISIBLE,
391                 BACK_DISPOSITION_DEFAULT, true);
392         assertTrue((mNavigationBar.getNavigationIconHints() & NAVIGATION_HINT_BACK_ALT) != 0);
393         assertTrue((mNavigationBar.getNavigationIconHints() & NAVIGATION_HINT_IME_SHOWN) != 0);
394         assertTrue((mNavigationBar.getNavigationIconHints() & NAVIGATION_HINT_IME_SWITCHER_SHOWN)
395                 != 0);
396 
397         // Verify navbar didn't alter and showing back icon when the keyguard is showing without
398         // requesting IME insets visible.
399         doReturn(true).when(mKeyguardStateController).isShowing();
400         mNavigationBar.setImeWindowStatus(DEFAULT_DISPLAY, null, IME_VISIBLE,
401                 BACK_DISPOSITION_DEFAULT, true);
402         assertFalse((mNavigationBar.getNavigationIconHints() & NAVIGATION_HINT_BACK_ALT) != 0);
403         assertFalse((mNavigationBar.getNavigationIconHints() & NAVIGATION_HINT_IME_SHOWN) != 0);
404         assertFalse((mNavigationBar.getNavigationIconHints() & NAVIGATION_HINT_IME_SWITCHER_SHOWN)
405                 != 0);
406 
407         // Verify navbar altered and showing back icon when the keyguard is showing and
408         // requesting IME insets visible.
409         windowInsets = new WindowInsets.Builder().setVisible(ime(), true).build();
410         doReturn(windowInsets).when(mockShadeWindowView).getRootWindowInsets();
411         mNavigationBar.setImeWindowStatus(DEFAULT_DISPLAY, null, IME_VISIBLE,
412                 BACK_DISPOSITION_DEFAULT, true);
413         assertTrue((mNavigationBar.getNavigationIconHints() & NAVIGATION_HINT_BACK_ALT) != 0);
414         assertTrue((mNavigationBar.getNavigationIconHints() & NAVIGATION_HINT_IME_SHOWN) != 0);
415         assertTrue((mNavigationBar.getNavigationIconHints() & NAVIGATION_HINT_IME_SWITCHER_SHOWN)
416                 != 0);
417     }
418 
419     @Test
testA11yEventAfterDetach()420     public void testA11yEventAfterDetach() {
421         mNavigationBar.init();
422         mNavigationBar.onViewAttached();
423         verify(mNavBarHelper).registerNavTaskStateUpdater(any(
424                 NavBarHelper.NavbarTaskbarStateUpdater.class));
425         mNavigationBar.onViewDetached();
426         verify(mNavBarHelper).removeNavTaskStateUpdater(any(
427                 NavBarHelper.NavbarTaskbarStateUpdater.class));
428 
429         // Should be safe even though the internal view is now null.
430         mNavigationBar.updateAccessibilityStateFlags();
431     }
432 
433     @Test
testCreateView_initiallyVisible_viewIsVisible()434     public void testCreateView_initiallyVisible_viewIsVisible() {
435         when(mStatusBarKeyguardViewManager.isNavBarVisible()).thenReturn(true);
436         mNavigationBar.init();
437         mNavigationBar.onViewAttached();
438 
439         verify(mNavigationBarView).setVisibility(View.VISIBLE);
440     }
441 
442     @Test
testCreateView_initiallyNotVisible_viewIsNotVisible()443     public void testCreateView_initiallyNotVisible_viewIsNotVisible() {
444         when(mStatusBarKeyguardViewManager.isNavBarVisible()).thenReturn(false);
445         mNavigationBar.init();
446         mNavigationBar.onViewAttached();
447 
448         verify(mNavigationBarView).setVisibility(View.INVISIBLE);
449     }
450 
451     @Test
testOnInit_readCurrentSysuiState()452     public void testOnInit_readCurrentSysuiState() {
453         mNavigationBar.init();
454         verify(mNavBarHelper, times(1)).getCurrentSysuiState();
455     }
456 
457     @Test
testScreenPinningEnabled_updatesSysuiState()458     public void testScreenPinningEnabled_updatesSysuiState() {
459         mNavigationBar.init();
460         mTaskStackChangeListeners.getListenerImpl().onLockTaskModeChanged(
461                 ActivityManager.LOCK_TASK_MODE_PINNED);
462         verify(mMockSysUiState).setFlag(eq(SYSUI_STATE_SCREEN_PINNING), eq(true));
463     }
464 
createNavBar(Context context)465     private NavigationBar createNavBar(Context context) {
466         DeviceProvisionedController deviceProvisionedController =
467                 mock(DeviceProvisionedController.class);
468         when(deviceProvisionedController.isDeviceProvisioned()).thenReturn(true);
469         return spy(new NavigationBar(
470                 mNavigationBarView,
471                 mock(ShadeController.class),
472                 mNavigationBarFrame,
473                 null,
474                 context,
475                 mWindowManager,
476                 () -> mAssistManager,
477                 mock(AccessibilityManager.class),
478                 deviceProvisionedController,
479                 new MetricsLogger(),
480                 mOverviewProxyService,
481                 mNavigationModeController,
482                 mStatusBarStateController,
483                 mStatusBarKeyguardViewManager,
484                 mMockSysUiState,
485                 mUserTracker,
486                 mCommandQueue,
487                 Optional.of(mock(Pip.class)),
488                 Optional.of(mock(Recents.class)),
489                 () -> Optional.of(mCentralSurfaces),
490                 mock(ShadeViewController.class),
491                 mock(NotificationRemoteInputManager.class),
492                 mock(NotificationShadeDepthController.class),
493                 mHandler,
494                 mFakeExecutor,
495                 mFakeExecutor,
496                 mUiEventLogger,
497                 mNavBarHelper,
498                 mLightBarController,
499                 mLightBarcontrollerFactory,
500                 mAutoHideController,
501                 mAutoHideControllerFactory,
502                 Optional.of(mTelecomManager),
503                 mInputMethodManager,
504                 mDeadZone,
505                 mDeviceConfigProxyFake,
506                 mNavigationBarTransitions,
507                 Optional.of(mock(BackAnimation.class)),
508                 mUserContextProvider,
509                 mWakefulnessLifecycle,
510                 mTaskStackChangeListeners,
511                 new FakeDisplayTracker(mContext)));
512     }
513 
processAllMessages()514     private void processAllMessages() {
515         TestableLooper.get(this).processAllMessages();
516     }
517 }
518