From 42ea6883674e449cbb4d530868c2aac799680d3c Mon Sep 17 00:00:00 2001 From: Winson Chung Date: Fri, 3 Mar 2023 21:43:19 +0000 Subject: [PATCH 1/4] 1/ Initialize assistant state change listeners once with the nav bar helper - Consolidate the meaning of init/destroy into the registration/unregistration of the nav bar helper state callbacks. This allows us to track the case where we are replacing the bars to prevent churn in unregistering and reregistering shared callbacks - Using the above, we can only register the assistant content observers when the first bar is registered, and keep it registered across bar replacements Bug: 219035565 Test: atest NavBarHelperTests Test: atest SystemUITests Change-Id: I2444bb0b27086b72212ef05b8c975c19a05a35d5 --- .../systemui/navigationbar/NavBarHelper.java | 86 +++++++++++++------ .../systemui/navigationbar/NavigationBar.java | 9 +- .../NavigationBarController.java | 11 ++- .../navigationbar/TaskbarDelegate.java | 2 - .../navigationbar/NavBarHelperTest.java | 53 ++++++++---- 5 files changed, 110 insertions(+), 51 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavBarHelper.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavBarHelper.java index 1121e160c3537..731f712c57c8d 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavBarHelper.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavBarHelper.java @@ -90,6 +90,7 @@ public final class NavBarHelper implements AccessibilityButtonTargetsObserver.TargetsChangedListener, OverviewProxyService.OverviewProxyListener, NavigationModeController.ModeChangedListener, Dumpable, CommandQueue.Callbacks { + private final Handler mHandler = new Handler(Looper.getMainLooper()); private final AccessibilityManager mAccessibilityManager; private final Lazy mAssistManagerLazy; private final Lazy> mCentralSurfacesOptionalLazy; @@ -98,7 +99,7 @@ public final class NavBarHelper implements private final SystemActions mSystemActions; private final AccessibilityButtonModeObserver mAccessibilityButtonModeObserver; private final AccessibilityButtonTargetsObserver mAccessibilityButtonTargetsObserver; - private final List mA11yEventListeners = new ArrayList<>(); + private final List mStateListeners = new ArrayList<>(); private final Context mContext; private final CommandQueue mCommandQueue; private final ContentResolver mContentResolver; @@ -107,13 +108,14 @@ public final class NavBarHelper implements private boolean mAssistantTouchGestureEnabled; private int mNavBarMode; private int mA11yButtonState; + private boolean mTogglingNavbarTaskbar; // Attributes used in NavBarHelper.CurrentSysuiState private int mWindowStateDisplayId; private @WindowVisibleState int mWindowState; - private final ContentObserver mAssistContentObserver = new ContentObserver( - new Handler(Looper.getMainLooper())) { + // Listens for changes to the assistant + private final ContentObserver mAssistContentObserver = new ContentObserver(mHandler) { @Override public void onChange(boolean selfChange, Uri uri) { updateAssistantAvailability(); @@ -147,18 +149,33 @@ public final class NavBarHelper implements mKeyguardStateController = keyguardStateController; mUserTracker = userTracker; mSystemActions = systemActions; - accessibilityManager.addAccessibilityServicesStateChangeListener(this); mAccessibilityButtonModeObserver = accessibilityButtonModeObserver; mAccessibilityButtonTargetsObserver = accessibilityButtonTargetsObserver; - mAccessibilityButtonModeObserver.addListener(this); - mAccessibilityButtonTargetsObserver.addListener(this); mNavBarMode = navigationModeController.addListener(this); + mCommandQueue.addCallback(this); overviewProxyService.addCallback(this); dumpManager.registerDumpable(this); } - public void init() { + /** + * Hints to the helper that bars are being replaced, which is a signal to potentially suppress + * normal setup/cleanup when no bars are present. + */ + public void setTogglingNavbarTaskbar(boolean togglingNavbarTaskbar) { + mTogglingNavbarTaskbar = togglingNavbarTaskbar; + } + + /** + * Called when the first (non-replacing) bar is registered. + */ + private void setupOnFirstBar() { + // Setup accessibility listeners + mAccessibilityManager.addAccessibilityServicesStateChangeListener(this); + mAccessibilityButtonModeObserver.addListener(this); + mAccessibilityButtonTargetsObserver.addListener(this); + + // Setup assistant listener mContentResolver.registerContentObserver( Settings.Secure.getUriFor(Settings.Secure.ASSISTANT), false /* notifyForDescendants */, mAssistContentObserver, UserHandle.USER_ALL); @@ -168,59 +185,76 @@ public final class NavBarHelper implements mContentResolver.registerContentObserver( Settings.Secure.getUriFor(Settings.Secure.ASSIST_TOUCH_GESTURE_ENABLED), false, mAssistContentObserver, UserHandle.USER_ALL); - updateAssistantAvailability(); - updateA11yState(); - mCommandQueue.addCallback(this); - - } - - public void destroy() { - mContentResolver.unregisterContentObserver(mAssistContentObserver); - mCommandQueue.removeCallback(this); } /** + * Called after the last (non-replacing) bar is unregistered. + */ + private void cleanupAfterLastBar() { + // Clean up accessibility listeners + mAccessibilityManager.removeAccessibilityServicesStateChangeListener(this); + mAccessibilityButtonModeObserver.removeListener(this); + mAccessibilityButtonTargetsObserver.removeListener(this); + + // Clean up assistant listeners + mContentResolver.unregisterContentObserver(mAssistContentObserver); + } + + /** + * Registers a listener for future updates to the shared navbar/taskbar state. * @param listener Will immediately get callbacks based on current state */ public void registerNavTaskStateUpdater(NavbarTaskbarStateUpdater listener) { - mA11yEventListeners.add(listener); - listener.updateAccessibilityServicesState(); - listener.updateAssistantAvailable(mAssistantAvailable, mLongPressHomeEnabled); + mStateListeners.add(listener); + if (!mTogglingNavbarTaskbar && mStateListeners.size() == 1) { + setupOnFirstBar(); + + // Update the state once the first bar is registered + updateAssistantAvailability(); + updateA11yState(); + mCommandQueue.recomputeDisableFlags(mContext.getDisplayId(), false /* animate */); + } else { + listener.updateAccessibilityServicesState(); + listener.updateAssistantAvailable(mAssistantAvailable, mLongPressHomeEnabled); + } } + /** + * Removes a previously registered listener. + */ public void removeNavTaskStateUpdater(NavbarTaskbarStateUpdater listener) { - mA11yEventListeners.remove(listener); + mStateListeners.remove(listener); + if (!mTogglingNavbarTaskbar && mStateListeners.isEmpty()) { + cleanupAfterLastBar(); + } } private void dispatchA11yEventUpdate() { - for (NavbarTaskbarStateUpdater listener : mA11yEventListeners) { + for (NavbarTaskbarStateUpdater listener : mStateListeners) { listener.updateAccessibilityServicesState(); } } private void dispatchAssistantEventUpdate(boolean assistantAvailable, boolean longPressHomeEnabled) { - for (NavbarTaskbarStateUpdater listener : mA11yEventListeners) { + for (NavbarTaskbarStateUpdater listener : mStateListeners) { listener.updateAssistantAvailable(assistantAvailable, longPressHomeEnabled); } } @Override public void onAccessibilityServicesStateChanged(AccessibilityManager manager) { - dispatchA11yEventUpdate(); updateA11yState(); } @Override public void onAccessibilityButtonModeChanged(int mode) { updateA11yState(); - dispatchA11yEventUpdate(); } @Override public void onAccessibilityButtonTargetsChanged(String targets) { updateA11yState(); - dispatchA11yEventUpdate(); } /** @@ -262,6 +296,8 @@ public final class NavBarHelper implements updateSystemAction(clickable, SYSTEM_ACTION_ID_ACCESSIBILITY_BUTTON); updateSystemAction(longClickable, SYSTEM_ACTION_ID_ACCESSIBILITY_BUTTON_CHOOSER); } + + dispatchA11yEventUpdate(); } /** diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java index f81743928e3bd..1c36e92cff003 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java @@ -677,13 +677,14 @@ public class NavigationBar extends ViewController implements // start firing, since the latter is source of truth parseCurrentSysuiState(); mCommandQueue.addCallback(this); - mLongPressHomeEnabled = mNavBarHelper.getLongPressHomeEnabled(); - mNavBarHelper.init(); mHomeButtonLongPressDurationMs = Optional.of(mDeviceConfigProxy.getLong( DeviceConfig.NAMESPACE_SYSTEMUI, HOME_BUTTON_LONG_PRESS_DURATION_MS, /* defaultValue = */ 0 )).filter(duration -> duration != 0); + // This currently MUST be called after mHomeButtonLongPressDurationMs is initialized since + // the registration callbacks will trigger code that uses it + mNavBarHelper.registerNavTaskStateUpdater(mNavbarTaskbarStateUpdater); mDeviceConfigProxy.addOnPropertiesChangedListener( DeviceConfig.NAMESPACE_SYSTEMUI, mHandler::post, mOnPropertiesChangedListener); @@ -709,7 +710,6 @@ public class NavigationBar extends ViewController implements mNavigationModeController.removeListener(mModeChangedListener); mNavBarHelper.removeNavTaskStateUpdater(mNavbarTaskbarStateUpdater); - mNavBarHelper.destroy(); mNotificationShadeDepthController.removeListener(mDepthListener); mDeviceConfigProxy.removeOnPropertiesChangedListener(mOnPropertiesChangedListener); @@ -746,8 +746,6 @@ public class NavigationBar extends ViewController implements mView.getViewRootImpl().addSurfaceChangedCallback(mSurfaceChangedCallback); notifyNavigationBarSurface(); - mNavBarHelper.registerNavTaskStateUpdater(mNavbarTaskbarStateUpdater); - mPipOptional.ifPresent(mView::addPipExclusionBoundsChangeListener); mBackAnimation.ifPresent(mView::registerBackAnimation); @@ -1487,6 +1485,7 @@ public class NavigationBar extends ViewController implements } void updateAccessibilityStateFlags() { + mLongPressHomeEnabled = mNavBarHelper.getLongPressHomeEnabled(); if (mView != null) { int a11yFlags = mNavBarHelper.getA11yButtonState(); boolean clickable = (a11yFlags & SYSUI_STATE_A11Y_BUTTON_CLICKABLE) != 0; diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java index 153d5a651f9ca..21398e23cc100 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java @@ -90,6 +90,7 @@ public class NavigationBarController implements private final DisplayTracker mDisplayTracker; private final DisplayManager mDisplayManager; private final TaskbarDelegate mTaskbarDelegate; + private final NavBarHelper mNavBarHelper; private int mNavMode; @VisibleForTesting boolean mIsLargeScreen; @@ -133,6 +134,7 @@ public class NavigationBarController implements configurationController.addCallback(this); mConfigChanges.applyNewConfig(mContext.getResources()); mNavMode = navigationModeController.addListener(this); + mNavBarHelper = navBarHelper; mTaskbarDelegate = taskbarDelegate; mTaskbarDelegate.setDependencies(commandQueue, overviewProxyService, navBarHelper, navigationModeController, sysUiFlagsContainer, @@ -241,10 +243,15 @@ public class NavigationBarController implements if (taskbarEnabled) { Trace.beginSection("NavigationBarController#initializeTaskbarIfNecessary"); + final int displayId = mContext.getDisplayId(); + // Hint to NavBarHelper if we are replacing an existing bar to skip extra work + mNavBarHelper.setTogglingNavbarTaskbar(mNavigationBars.contains(displayId)); // Remove navigation bar when taskbar is showing - removeNavigationBar(mContext.getDisplayId()); - mTaskbarDelegate.init(mContext.getDisplayId()); + removeNavigationBar(displayId); + mTaskbarDelegate.init(displayId); + mNavBarHelper.setTogglingNavbarTaskbar(false); Trace.endSection(); + } else { mTaskbarDelegate.destroy(); } diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java b/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java index 5b02aaf089e07..dc5c9bd7b38a8 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java @@ -239,7 +239,6 @@ public class TaskbarDelegate implements CommandQueue.Callbacks, mOverviewProxyService.addCallback(this); onNavigationModeChanged(mNavigationModeController.addListener(this)); mNavBarHelper.registerNavTaskStateUpdater(mNavbarTaskbarStateUpdater); - mNavBarHelper.init(); mEdgeBackGestureHandler.onNavBarAttached(); // Initialize component callback Display display = mDisplayManager.getDisplay(displayId); @@ -264,7 +263,6 @@ public class TaskbarDelegate implements CommandQueue.Callbacks, mOverviewProxyService.removeCallback(this); mNavigationModeController.removeListener(this); mNavBarHelper.removeNavTaskStateUpdater(mNavbarTaskbarStateUpdater); - mNavBarHelper.destroy(); mEdgeBackGestureHandler.onNavBarDetached(); mScreenPinningNotify = null; mWindowContext = null; diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavBarHelperTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavBarHelperTest.java index ce6a98c9e1626..fbe83af78080a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavBarHelperTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavBarHelperTest.java @@ -128,20 +128,49 @@ public class NavBarHelperTest extends SysuiTestCase { @Test public void registerListenersInCtor() { - verify(mAccessibilityButtonModeObserver, times(1)).addListener(mNavBarHelper); verify(mNavigationModeController, times(1)).addListener(mNavBarHelper); verify(mOverviewProxyService, times(1)).addCallback(mNavBarHelper); + verify(mCommandQueue, times(1)).addCallback(any()); + } + + @Test + public void registerAccessibilityContentObserver() { + mNavBarHelper.registerNavTaskStateUpdater(mNavbarTaskbarStateUpdater); + verify(mAccessibilityButtonModeObserver, times(1)).addListener(mNavBarHelper); + verify(mAccessibilityButtonTargetObserver, times(1)).addListener(mNavBarHelper); + verify(mAccessibilityManager, times(1)).addAccessibilityServicesStateChangeListener( + mNavBarHelper); + } + + @Test + public void unregisterAccessibilityContentObserver() { + mNavBarHelper.registerNavTaskStateUpdater(mNavbarTaskbarStateUpdater); + mNavBarHelper.removeNavTaskStateUpdater(mNavbarTaskbarStateUpdater); + verify(mAccessibilityButtonModeObserver, times(1)).removeListener(mNavBarHelper); + verify(mAccessibilityButtonTargetObserver, times(1)).removeListener(mNavBarHelper); + verify(mAccessibilityManager, times(1)).removeAccessibilityServicesStateChangeListener( + mNavBarHelper); } @Test public void registerAssistantContentObserver() { - mNavBarHelper.init(); + mNavBarHelper.registerNavTaskStateUpdater(mNavbarTaskbarStateUpdater); verify(mAssistManager, times(1)).getAssistInfoForUser(anyInt()); } + @Test + public void replacingBarsHint() { + mNavBarHelper.registerNavTaskStateUpdater(mNavbarTaskbarStateUpdater); + mNavBarHelper.setTogglingNavbarTaskbar(true); + mNavBarHelper.removeNavTaskStateUpdater(mNavbarTaskbarStateUpdater); + mNavBarHelper.registerNavTaskStateUpdater(mNavbarTaskbarStateUpdater); + mNavBarHelper.setTogglingNavbarTaskbar(false); + // Use any state in cleanup to verify it was not called + verify(mAccessibilityButtonModeObserver, times(0)).removeListener(mNavBarHelper); + } + @Test public void callbacksFiredWhenRegistering() { - mNavBarHelper.init(); mNavBarHelper.registerNavTaskStateUpdater(mNavbarTaskbarStateUpdater); verify(mNavbarTaskbarStateUpdater, times(1)) .updateAccessibilityServicesState(); @@ -151,7 +180,6 @@ public class NavBarHelperTest extends SysuiTestCase { @Test public void assistantCallbacksFiredAfterConnecting() { - mNavBarHelper.init(); // 1st set of callbacks get called when registering mNavBarHelper.registerNavTaskStateUpdater(mNavbarTaskbarStateUpdater); @@ -172,7 +200,6 @@ public class NavBarHelperTest extends SysuiTestCase { @Test public void a11yCallbacksFiredAfterModeChange() { - mNavBarHelper.init(); // 1st set of callbacks get called when registering mNavBarHelper.registerNavTaskStateUpdater(mNavbarTaskbarStateUpdater); @@ -185,7 +212,6 @@ public class NavBarHelperTest extends SysuiTestCase { @Test public void assistantCallbacksFiredAfterNavModeChange() { - mNavBarHelper.init(); // 1st set of callbacks get called when registering mNavBarHelper.registerNavTaskStateUpdater(mNavbarTaskbarStateUpdater); @@ -198,7 +224,6 @@ public class NavBarHelperTest extends SysuiTestCase { @Test public void removeListenerNoCallbacksFired() { - mNavBarHelper.init(); // 1st set of callbacks get called when registering mNavBarHelper.registerNavTaskStateUpdater(mNavbarTaskbarStateUpdater); @@ -220,7 +245,7 @@ public class NavBarHelperTest extends SysuiTestCase { when(mAccessibilityManager.getAccessibilityShortcutTargets( AccessibilityManager.ACCESSIBILITY_BUTTON)).thenReturn(createFakeShortcutTargets()); - mNavBarHelper.init(); + mNavBarHelper.registerNavTaskStateUpdater(mNavbarTaskbarStateUpdater); assertThat(mNavBarHelper.getA11yButtonState()).isEqualTo( ACCESSIBILITY_BUTTON_CLICKABLE_STATE); @@ -230,13 +255,15 @@ public class NavBarHelperTest extends SysuiTestCase { public void initAccessibilityStateWithFloatingMenuModeAndTargets_disableClickableState() { when(mAccessibilityButtonModeObserver.getCurrentAccessibilityButtonMode()).thenReturn( ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU); - mNavBarHelper.init(); + + mNavBarHelper.registerNavTaskStateUpdater(mNavbarTaskbarStateUpdater); assertThat(mNavBarHelper.getA11yButtonState()).isEqualTo(/* disable_clickable_state */ 0); } @Test public void onA11yServicesStateChangedWithMultipleServices_a11yButtonClickableState() { + mNavBarHelper.registerNavTaskStateUpdater(mNavbarTaskbarStateUpdater); when(mAccessibilityButtonModeObserver.getCurrentAccessibilityButtonMode()).thenReturn( ACCESSIBILITY_BUTTON_MODE_NAVIGATION_BAR); @@ -249,15 +276,8 @@ public class NavBarHelperTest extends SysuiTestCase { ACCESSIBILITY_BUTTON_CLICKABLE_STATE); } - @Test - public void registerCommandQueueCallbacks() { - mNavBarHelper.init(); - verify(mCommandQueue, times(1)).addCallback(any()); - } - @Test public void saveMostRecentSysuiState() { - mNavBarHelper.init(); mNavBarHelper.setWindowState(DISPLAY_ID, WINDOW, STATE_ID); NavBarHelper.CurrentSysuiState state1 = mNavBarHelper.getCurrentSysuiState(); @@ -274,7 +294,6 @@ public class NavBarHelperTest extends SysuiTestCase { @Test public void ignoreNonNavbarSysuiState() { - mNavBarHelper.init(); mNavBarHelper.setWindowState(DISPLAY_ID, WINDOW, STATE_ID); NavBarHelper.CurrentSysuiState state1 = mNavBarHelper.getCurrentSysuiState(); From f07c2b4c12e229fb660666bd6526efab30f6415b Mon Sep 17 00:00:00 2001 From: Winson Chung Date: Fri, 3 Mar 2023 23:28:56 +0000 Subject: [PATCH 2/4] 2/ Add path for feeding rotation watcher signals to RotationButtonController - A new rotation button controller is created for each nav/task bar as the controller currently is coupled with the view that it updates. Since the controller needs to listen for rotation watcher signals, we need to pull that out into a persistent place in NavBarHelper for the nav bar, but the taskbar flow will continue to use the controller to register for these changes. - Because the flow is now from NavBarHelper -> NavBar -> RBC, we can also remove the existing callback from RBC -> NavBar Bug: 219035565 Test: atest NavBarHelperTests Test: atest SystemUITests Change-Id: I2e26d0ce8f4184d1deb25300875ebf9035d7c538 --- .../rotation/RotationButtonController.java | 91 +++++++++++-------- .../systemui/navigationbar/NavBarHelper.java | 49 ++++++++++ .../systemui/navigationbar/NavigationBar.java | 19 ++-- .../navigationbar/NavigationBarView.java | 2 +- .../navigationbar/NavBarHelperTest.java | 25 +++-- .../navigationbar/NavigationBarTest.java | 5 +- 6 files changed, 133 insertions(+), 58 deletions(-) diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/rotation/RotationButtonController.java b/packages/SystemUI/shared/src/com/android/systemui/shared/rotation/RotationButtonController.java index 5b27c40740daf..53fab69bd3b84 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/rotation/RotationButtonController.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/rotation/RotationButtonController.java @@ -96,9 +96,9 @@ public class RotationButtonController { private boolean mHoveringRotationSuggestion; private final AccessibilityManager mAccessibilityManager; private final TaskStackListenerImpl mTaskStackListener; - private Consumer mRotWatcherListener; private boolean mListenersRegistered = false; + private boolean mRotationWatcherRegistered = false; private boolean mIsNavigationBarShowing; @SuppressLint("InlinedApi") private @WindowInsetsController.Behavior @@ -140,22 +140,7 @@ public class RotationButtonController { // We need this to be scheduled as early as possible to beat the redrawing of // window in response to the orientation change. mMainThreadHandler.postAtFrontOfQueue(() -> { - // If the screen rotation changes while locked, potentially update lock to flow with - // new screen rotation and hide any showing suggestions. - boolean rotationLocked = isRotationLocked(); - // The isVisible check makes the rotation button disappear when we are not locked - // (e.g. for tabletop auto-rotate). - if (rotationLocked || mRotationButton.isVisible()) { - // Do not allow a change in rotation to set user rotation when docked. - if (shouldOverrideUserLockPrefs(rotation) && rotationLocked && !mDocked) { - setRotationLockedAtAngle(rotation); - } - setRotateSuggestionButtonState(false /* visible */, true /* forced */); - } - - if (mRotWatcherListener != null) { - mRotWatcherListener.accept(rotation); - } + onRotationWatcherChanged(rotation); }); } }; @@ -206,8 +191,11 @@ public class RotationButtonController { return mContext; } + /** + * Called during Taskbar initialization. + */ public void init() { - registerListeners(); + registerListeners(true /* registerRotationWatcher */); if (mContext.getDisplay().getDisplayId() != DEFAULT_DISPLAY) { // Currently there is no accelerometer sensor on non-default display, disable fixed // rotation for non-default display @@ -215,11 +203,14 @@ public class RotationButtonController { } } + /** + * Called during Taskbar uninitialization. + */ public void onDestroy() { unregisterListeners(); } - public void registerListeners() { + public void registerListeners(boolean registerRotationWatcher) { if (mListenersRegistered || getContext().getPackageManager().hasSystemFeature(FEATURE_PC)) { return; } @@ -229,15 +220,18 @@ public class RotationButtonController { updateDockedState(mContext.registerReceiver(mDockedReceiver, new IntentFilter(Intent.ACTION_DOCK_EVENT))); - try { - WindowManagerGlobal.getWindowManagerService() - .watchRotation(mRotationWatcher, DEFAULT_DISPLAY); - } catch (IllegalArgumentException e) { - mListenersRegistered = false; - Log.w(TAG, "RegisterListeners for the display failed"); - } catch (RemoteException e) { - Log.e(TAG, "RegisterListeners caught a RemoteException", e); - return; + if (registerRotationWatcher) { + try { + WindowManagerGlobal.getWindowManagerService() + .watchRotation(mRotationWatcher, DEFAULT_DISPLAY); + mRotationWatcherRegistered = true; + } catch (IllegalArgumentException e) { + mListenersRegistered = false; + Log.w(TAG, "RegisterListeners for the display failed", e); + } catch (RemoteException e) { + Log.e(TAG, "RegisterListeners caught a RemoteException", e); + return; + } } TaskStackChangeListeners.getInstance().registerTaskStackListener(mTaskStackListener); @@ -251,20 +245,19 @@ public class RotationButtonController { mListenersRegistered = false; mContext.unregisterReceiver(mDockedReceiver); - try { - WindowManagerGlobal.getWindowManagerService().removeRotationWatcher(mRotationWatcher); - } catch (RemoteException e) { - Log.e(TAG, "UnregisterListeners caught a RemoteException", e); - return; + if (mRotationWatcherRegistered) { + try { + WindowManagerGlobal.getWindowManagerService().removeRotationWatcher( + mRotationWatcher); + } catch (RemoteException e) { + Log.e(TAG, "UnregisterListeners caught a RemoteException", e); + return; + } } TaskStackChangeListeners.getInstance().unregisterTaskStackListener(mTaskStackListener); } - public void setRotationCallback(Consumer watcher) { - mRotWatcherListener = watcher; - } - public void setRotationLockedAtAngle(int rotationSuggestion) { RotationPolicy.setRotationLockAtAngle(mContext, /* enabled= */ isRotationLocked(), /* rotation= */ rotationSuggestion); @@ -427,6 +420,30 @@ public class RotationButtonController { } } + /** + * Called when the rotation watcher rotation changes, either from the watcher registered + * internally in this class, or a signal propagated from NavBarHelper. + */ + public void onRotationWatcherChanged(int rotation) { + if (!mListenersRegistered) { + // Ignore if not registered + return; + } + + // If the screen rotation changes while locked, potentially update lock to flow with + // new screen rotation and hide any showing suggestions. + boolean rotationLocked = isRotationLocked(); + // The isVisible check makes the rotation button disappear when we are not locked + // (e.g. for tabletop auto-rotate). + if (rotationLocked || mRotationButton.isVisible()) { + // Do not allow a change in rotation to set user rotation when docked. + if (shouldOverrideUserLockPrefs(rotation) && rotationLocked && !mDocked) { + setRotationLockedAtAngle(rotation); + } + setRotateSuggestionButtonState(false /* visible */, true /* forced */); + } + } + public void onDisable2FlagChanged(int state2) { final boolean rotateSuggestionsDisabled = hasDisable2RotateSuggestionFlag(state2); if (rotateSuggestionsDisabled) onRotationSuggestionsDisabled(); diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavBarHelper.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavBarHelper.java index 731f712c57c8d..24098122aec6a 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavBarHelper.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavBarHelper.java @@ -41,11 +41,16 @@ import android.net.Uri; import android.os.Bundle; import android.os.Handler; import android.os.Looper; +import android.os.RemoteException; import android.os.UserHandle; import android.provider.Settings; import android.provider.Settings.Secure; +import android.util.Log; +import android.view.IRotationWatcher; +import android.view.IWindowManager; import android.view.View; import android.view.WindowInsets; +import android.view.WindowManagerGlobal; import android.view.accessibility.AccessibilityManager; import androidx.annotation.NonNull; @@ -58,6 +63,7 @@ import com.android.systemui.assist.AssistManager; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dump.DumpManager; import com.android.systemui.recents.OverviewProxyService; +import com.android.systemui.settings.DisplayTracker; import com.android.systemui.settings.UserTracker; import com.android.systemui.shared.system.QuickStepContract; import com.android.systemui.statusbar.CommandQueue; @@ -90,6 +96,7 @@ public final class NavBarHelper implements AccessibilityButtonTargetsObserver.TargetsChangedListener, OverviewProxyService.OverviewProxyListener, NavigationModeController.ModeChangedListener, Dumpable, CommandQueue.Callbacks { + private static final String TAG = NavBarHelper.class.getSimpleName(); private final Handler mHandler = new Handler(Looper.getMainLooper()); private final AccessibilityManager mAccessibilityManager; private final Lazy mAssistManagerLazy; @@ -103,11 +110,14 @@ public final class NavBarHelper implements private final Context mContext; private final CommandQueue mCommandQueue; private final ContentResolver mContentResolver; + private final IWindowManager mWm; + private final int mDefaultDisplayId; private boolean mAssistantAvailable; private boolean mLongPressHomeEnabled; private boolean mAssistantTouchGestureEnabled; private int mNavBarMode; private int mA11yButtonState; + private int mRotationWatcherRotation; private boolean mTogglingNavbarTaskbar; // Attributes used in NavBarHelper.CurrentSysuiState @@ -122,6 +132,19 @@ public final class NavBarHelper implements } }; + // Listens for changes to display rotation + private final IRotationWatcher mRotationWatcher = new IRotationWatcher.Stub() { + @Override + public void onRotationChanged(final int rotation) { + // We need this to be scheduled as early as possible to beat the redrawing of + // window in response to the orientation change. + mHandler.postAtFrontOfQueue(() -> { + mRotationWatcherRotation = rotation; + dispatchRotationChanged(rotation); + }); + } + }; + /** * @param context This is not display specific, then again neither is any of the code in * this class. Once there's display specific code, we may want to create an @@ -137,7 +160,9 @@ public final class NavBarHelper implements Lazy> centralSurfacesOptionalLazy, KeyguardStateController keyguardStateController, NavigationModeController navigationModeController, + IWindowManager wm, UserTracker userTracker, + DisplayTracker displayTracker, DumpManager dumpManager, CommandQueue commandQueue) { mContext = context; @@ -151,6 +176,8 @@ public final class NavBarHelper implements mSystemActions = systemActions; mAccessibilityButtonModeObserver = accessibilityButtonModeObserver; mAccessibilityButtonTargetsObserver = accessibilityButtonTargetsObserver; + mWm = wm; + mDefaultDisplayId = displayTracker.getDefaultDisplayId(); mNavBarMode = navigationModeController.addListener(this); mCommandQueue.addCallback(this); @@ -185,6 +212,13 @@ public final class NavBarHelper implements mContentResolver.registerContentObserver( Settings.Secure.getUriFor(Settings.Secure.ASSIST_TOUCH_GESTURE_ENABLED), false, mAssistContentObserver, UserHandle.USER_ALL); + + // Setup display rotation watcher + try { + mWm.watchRotation(mRotationWatcher, mDefaultDisplayId); + } catch (Exception e) { + Log.w(TAG, "Failed to register rotation watcher", e); + } } /** @@ -198,6 +232,13 @@ public final class NavBarHelper implements // Clean up assistant listeners mContentResolver.unregisterContentObserver(mAssistContentObserver); + + // Clean up display rotation watcher + try { + mWm.removeRotationWatcher(mRotationWatcher); + } catch (Exception e) { + Log.w(TAG, "Failed to unregister rotation watcher", e); + } } /** @@ -217,6 +258,7 @@ public final class NavBarHelper implements listener.updateAccessibilityServicesState(); listener.updateAssistantAvailable(mAssistantAvailable, mLongPressHomeEnabled); } + listener.updateRotationWatcherState(mRotationWatcherRotation); } /** @@ -393,6 +435,12 @@ public final class NavBarHelper implements mWindowState = state; } + private void dispatchRotationChanged(int rotation) { + for (NavbarTaskbarStateUpdater listener : mStateListeners) { + listener.updateRotationWatcherState(rotation); + } + } + public CurrentSysuiState getCurrentSysuiState() { return new CurrentSysuiState(); } @@ -404,6 +452,7 @@ public final class NavBarHelper implements public interface NavbarTaskbarStateUpdater { void updateAccessibilityServicesState(); void updateAssistantAvailable(boolean available, boolean longPressHomeEnabled); + default void updateRotationWatcherState(int rotation) {} } /** Data class to help Taskbar/Navbar initiate state correctly when switching between the two.*/ diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java index 1c36e92cff003..db545099f8ac5 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java @@ -350,6 +350,15 @@ public class NavigationBar extends ViewController implements mLongPressHomeEnabled = longPressHomeEnabled; updateAssistantEntrypoints(available, longPressHomeEnabled); } + @Override + public void updateRotationWatcherState(int rotation) { + if (mIsOnDefaultDisplay && mView != null) { + mView.getRotationButtonController().onRotationWatcherChanged(rotation); + if (mView.needsReorient(rotation)) { + repositionNavigationBar(rotation); + } + } + } }; private final OverviewProxyListener mOverviewProxyListener = new OverviewProxyListener() { @@ -763,7 +772,6 @@ public class NavigationBar extends ViewController implements if (mIsOnDefaultDisplay) { final RotationButtonController rotationButtonController = mView.getRotationButtonController(); - rotationButtonController.setRotationCallback(mRotationWatcher); // Reset user rotation pref to match that of the WindowManager if starting in locked // mode. This will automatically happen when switching from auto-rotate to locked mode. @@ -797,9 +805,6 @@ public class NavigationBar extends ViewController implements @Override public void onViewDetached() { - final RotationButtonController rotationButtonController = - mView.getRotationButtonController(); - rotationButtonController.setRotationCallback(null); mView.setUpdateActiveTouchRegionsCallback(null); getBarTransitions().destroy(); mOverviewProxyService.removeCallback(mOverviewProxyListener); @@ -1701,12 +1706,6 @@ public class NavigationBar extends ViewController implements return mNavBarMode == NAV_BAR_MODE_GESTURAL && mOrientationHandle != null; } - private final Consumer mRotationWatcher = rotation -> { - if (mView != null && mView.needsReorient(rotation)) { - repositionNavigationBar(rotation); - } - }; - private final UserTracker.Callback mUserChangedCallback = new UserTracker.Callback() { @Override diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java index 63fb4996fbbf5..47701afc387b7 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java @@ -1099,7 +1099,7 @@ public class NavigationBarView extends FrameLayout { requestApplyInsets(); reorient(); if (mRotationButtonController != null) { - mRotationButtonController.registerListeners(); + mRotationButtonController.registerListeners(false /* registerRotationWatcher */); } updateNavButtonIcons(); diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavBarHelperTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavBarHelperTest.java index fbe83af78080a..1076f9f1a9474 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavBarHelperTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavBarHelperTest.java @@ -35,6 +35,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.content.ComponentName; +import android.view.IWindowManager; import android.view.accessibility.AccessibilityManager; import androidx.test.filters.SmallTest; @@ -47,6 +48,7 @@ import com.android.systemui.accessibility.SystemActions; import com.android.systemui.assist.AssistManager; import com.android.systemui.dump.DumpManager; import com.android.systemui.recents.OverviewProxyService; +import com.android.systemui.settings.DisplayTracker; import com.android.systemui.settings.UserTracker; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.phone.CentralSurfaces; @@ -101,6 +103,10 @@ public class NavBarHelperTest extends SysuiTestCase { NavBarHelper.NavbarTaskbarStateUpdater mNavbarTaskbarStateUpdater; @Mock CommandQueue mCommandQueue; + @Mock + IWindowManager mWm; + @Mock + DisplayTracker mDisplayTracker; private AccessibilityManager.AccessibilityServicesStateChangeListener mAccessibilityServicesStateChangeListener; @@ -114,6 +120,7 @@ public class NavBarHelperTest extends SysuiTestCase { when(mAssistManagerLazy.get()).thenReturn(mAssistManager); when(mAssistManager.getAssistInfoForUser(anyInt())).thenReturn(mAssistantComponent); when(mUserTracker.getUserId()).thenReturn(1); + when(mDisplayTracker.getDefaultDisplayId()).thenReturn(0); doAnswer((invocation) -> mAccessibilityServicesStateChangeListener = invocation.getArgument(0)).when( @@ -122,7 +129,8 @@ public class NavBarHelperTest extends SysuiTestCase { mAccessibilityButtonModeObserver, mAccessibilityButtonTargetObserver, mSystemActions, mOverviewProxyService, mAssistManagerLazy, () -> Optional.of(mock(CentralSurfaces.class)), mock(KeyguardStateController.class), - mNavigationModeController, mUserTracker, mDumpManager, mCommandQueue); + mNavigationModeController, mWm, mUserTracker, mDisplayTracker, mDumpManager, + mCommandQueue); } @@ -134,28 +142,25 @@ public class NavBarHelperTest extends SysuiTestCase { } @Test - public void registerAccessibilityContentObserver() { + public void testSetupBarsRegistersListeners() throws Exception { mNavBarHelper.registerNavTaskStateUpdater(mNavbarTaskbarStateUpdater); verify(mAccessibilityButtonModeObserver, times(1)).addListener(mNavBarHelper); verify(mAccessibilityButtonTargetObserver, times(1)).addListener(mNavBarHelper); verify(mAccessibilityManager, times(1)).addAccessibilityServicesStateChangeListener( mNavBarHelper); + verify(mAssistManager, times(1)).getAssistInfoForUser(anyInt()); + verify(mWm, times(1)).watchRotation(any(), anyInt()); } @Test - public void unregisterAccessibilityContentObserver() { + public void testCleanupBarsUnregistersListeners() throws Exception { mNavBarHelper.registerNavTaskStateUpdater(mNavbarTaskbarStateUpdater); mNavBarHelper.removeNavTaskStateUpdater(mNavbarTaskbarStateUpdater); verify(mAccessibilityButtonModeObserver, times(1)).removeListener(mNavBarHelper); verify(mAccessibilityButtonTargetObserver, times(1)).removeListener(mNavBarHelper); verify(mAccessibilityManager, times(1)).removeAccessibilityServicesStateChangeListener( mNavBarHelper); - } - - @Test - public void registerAssistantContentObserver() { - mNavBarHelper.registerNavTaskStateUpdater(mNavbarTaskbarStateUpdater); - verify(mAssistManager, times(1)).getAssistInfoForUser(anyInt()); + verify(mWm, times(1)).removeRotationWatcher(any()); } @Test @@ -176,6 +181,8 @@ public class NavBarHelperTest extends SysuiTestCase { .updateAccessibilityServicesState(); verify(mNavbarTaskbarStateUpdater, times(1)) .updateAssistantAvailable(anyBoolean(), anyBoolean()); + verify(mNavbarTaskbarStateUpdater, times(1)) + .updateRotationWatcherState(anyInt()); } @Test diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java index 764ddc49d1101..35ab10ff4c164 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java @@ -58,6 +58,7 @@ import android.testing.TestableLooper; import android.testing.TestableLooper.RunWithLooper; import android.view.Display; import android.view.DisplayInfo; +import android.view.IWindowManager; import android.view.MotionEvent; import android.view.View; import android.view.ViewRootImpl; @@ -87,6 +88,7 @@ import com.android.systemui.navigationbar.gestural.EdgeBackGestureHandler; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.recents.OverviewProxyService; import com.android.systemui.recents.Recents; +import com.android.systemui.settings.DisplayTracker; import com.android.systemui.settings.FakeDisplayTracker; import com.android.systemui.settings.UserContextProvider; import com.android.systemui.settings.UserTracker; @@ -250,7 +252,8 @@ public class NavigationBarTest extends SysuiTestCase { mSystemActions, mOverviewProxyService, () -> mock(AssistManager.class), () -> Optional.of(mCentralSurfaces), mKeyguardStateController, mock(NavigationModeController.class), - mock(UserTracker.class), mock(DumpManager.class), mock(CommandQueue.class))); + mock(IWindowManager.class), mock(UserTracker.class), mock(DisplayTracker.class), + mock(DumpManager.class), mock(CommandQueue.class))); mNavigationBar = createNavBar(mContext); mExternalDisplayNavigationBar = createNavBar(mSysuiTestableContextExternal); }); From 81d1f12f5b0e2fbf38b01cf8a06f81a42e722a01 Mon Sep 17 00:00:00 2001 From: Winson Chung Date: Thu, 9 Mar 2023 17:34:58 +0000 Subject: [PATCH 3/4] 3/ Move wallpaper visibility listener to nav bar helper - The bar transitions update based on the wallpaper visibility but this can be expensive to register/unregister frequently. Instead, pull the listener out to NavBarHelper and keep it registered across the bars (it's a no-op for taskbar currently) - We don't need the weak reference since nav bar helper is a singleton Bug: 219035565 Test: atest NavBarHelperTests Test: atest SystemUITests Change-Id: I4b93437abd5e404981f119916557776090223cda --- .../systemui/navigationbar/NavBarHelper.java | 39 +++++++++++++++ .../systemui/navigationbar/NavigationBar.java | 7 ++- .../NavigationBarTransitions.java | 48 ++----------------- .../navigationbar/NavBarHelperTest.java | 4 ++ .../NavigationBarTransitionsTest.java | 5 +- 5 files changed, 55 insertions(+), 48 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavBarHelper.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavBarHelper.java index 24098122aec6a..59d6bfae53682 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavBarHelper.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavBarHelper.java @@ -47,6 +47,7 @@ import android.provider.Settings; import android.provider.Settings.Secure; import android.util.Log; import android.view.IRotationWatcher; +import android.view.IWallpaperVisibilityListener; import android.view.IWindowManager; import android.view.View; import android.view.WindowInsets; @@ -119,6 +120,7 @@ public final class NavBarHelper implements private int mA11yButtonState; private int mRotationWatcherRotation; private boolean mTogglingNavbarTaskbar; + private boolean mWallpaperVisible; // Attributes used in NavBarHelper.CurrentSysuiState private int mWindowStateDisplayId; @@ -132,6 +134,19 @@ public final class NavBarHelper implements } }; + // Listens for changes to the wallpaper visibility + private final IWallpaperVisibilityListener mWallpaperVisibilityListener = + new IWallpaperVisibilityListener.Stub() { + @Override + public void onWallpaperVisibilityChanged(boolean visible, + int displayId) throws RemoteException { + mHandler.post(() -> { + mWallpaperVisible = visible; + dispatchWallpaperVisibilityChanged(visible, displayId); + }); + } + }; + // Listens for changes to display rotation private final IRotationWatcher mRotationWatcher = new IRotationWatcher.Stub() { @Override @@ -219,6 +234,14 @@ public final class NavBarHelper implements } catch (Exception e) { Log.w(TAG, "Failed to register rotation watcher", e); } + + // Setup wallpaper visibility listener + try { + mWallpaperVisible = mWm.registerWallpaperVisibilityListener( + mWallpaperVisibilityListener, mDefaultDisplayId); + } catch (Exception e) { + Log.w(TAG, "Failed to register wallpaper visibility listener", e); + } } /** @@ -239,6 +262,14 @@ public final class NavBarHelper implements } catch (Exception e) { Log.w(TAG, "Failed to unregister rotation watcher", e); } + + // Clean up wallpaper visibility listener + try { + mWm.unregisterWallpaperVisibilityListener(mWallpaperVisibilityListener, + mDefaultDisplayId); + } catch (Exception e) { + Log.w(TAG, "Failed to register wallpaper visibility listener", e); + } } /** @@ -258,6 +289,7 @@ public final class NavBarHelper implements listener.updateAccessibilityServicesState(); listener.updateAssistantAvailable(mAssistantAvailable, mLongPressHomeEnabled); } + listener.updateWallpaperVisibility(mWallpaperVisible, mDefaultDisplayId); listener.updateRotationWatcherState(mRotationWatcherRotation); } @@ -435,6 +467,12 @@ public final class NavBarHelper implements mWindowState = state; } + private void dispatchWallpaperVisibilityChanged(boolean visible, int displayId) { + for (NavbarTaskbarStateUpdater listener : mStateListeners) { + listener.updateWallpaperVisibility(visible, displayId); + } + } + private void dispatchRotationChanged(int rotation) { for (NavbarTaskbarStateUpdater listener : mStateListeners) { listener.updateRotationWatcherState(rotation); @@ -452,6 +490,7 @@ public final class NavBarHelper implements public interface NavbarTaskbarStateUpdater { void updateAccessibilityServicesState(); void updateAssistantAvailable(boolean available, boolean longPressHomeEnabled); + default void updateWallpaperVisibility(boolean visible, int displayId) {} default void updateRotationWatcherState(int rotation) {} } diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java index db545099f8ac5..ab7581d2d10db 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java @@ -164,7 +164,6 @@ import java.util.Locale; import java.util.Map; import java.util.Optional; import java.util.concurrent.Executor; -import java.util.function.Consumer; import javax.inject.Inject; @@ -350,6 +349,12 @@ public class NavigationBar extends ViewController implements mLongPressHomeEnabled = longPressHomeEnabled; updateAssistantEntrypoints(available, longPressHomeEnabled); } + + @Override + public void updateWallpaperVisibility(boolean visible, int displayId) { + mNavigationBarTransitions.setWallpaperVisibility(visible); + } + @Override public void updateRotationWatcherState(int rotation) { if (mIsOnDefaultDisplay && mView != null) { diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarTransitions.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarTransitions.java index 20b50325f65f2..1d73bc205dc4f 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarTransitions.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarTransitions.java @@ -21,11 +21,7 @@ import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON; import static com.android.systemui.util.Utils.isGesturalModeOnDefaultDisplay; import android.graphics.Rect; -import android.os.Handler; -import android.os.RemoteException; import android.util.SparseArray; -import android.view.IWallpaperVisibilityListener; -import android.view.IWindowManager; import android.view.View; import com.android.systemui.R; @@ -36,7 +32,6 @@ import com.android.systemui.statusbar.phone.BarTransitions; import com.android.systemui.statusbar.phone.LightBarTransitionsController; import java.io.PrintWriter; -import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.List; @@ -63,8 +58,6 @@ public final class NavigationBarTransitions extends BarTransitions implements } private final NavigationBarView mView; - @org.jetbrains.annotations.NotNull - private final IWindowManager mWindowManagerService; private final LightBarTransitionsController mLightTransitionsController; private final DisplayTracker mDisplayTracker; private final boolean mAllowAutoDimWallpaperNotVisible; @@ -76,51 +69,20 @@ public final class NavigationBarTransitions extends BarTransitions implements private int mNavBarMode = NAV_BAR_MODE_3BUTTON; private List mDarkIntensityListeners; - private final Handler mHandler = Handler.getMain(); - - static final class WallpaperVisibilityListener extends IWallpaperVisibilityListener.Stub { - private final WeakReference mSelf; - - WallpaperVisibilityListener(NavigationBarTransitions self) { - mSelf = new WeakReference<>(self); - } - - @Override - public void onWallpaperVisibilityChanged(boolean newVisibility, - int displayId) throws RemoteException { - NavigationBarTransitions self = mSelf.get(); - if (self == null) { - return; - } - self.mWallpaperVisible = newVisibility; - self.mHandler.post(() -> self.applyLightsOut(true, false)); - } - } - - private final IWallpaperVisibilityListener mWallpaperVisibilityListener; - @Inject public NavigationBarTransitions( NavigationBarView view, - IWindowManager windowManagerService, LightBarTransitionsController.Factory lightBarTransitionsControllerFactory, DisplayTracker displayTracker) { super(view, R.drawable.nav_background); mView = view; - mWindowManagerService = windowManagerService; mLightTransitionsController = lightBarTransitionsControllerFactory.create(this); mDisplayTracker = displayTracker; mAllowAutoDimWallpaperNotVisible = view.getContext().getResources() .getBoolean(R.bool.config_navigation_bar_enable_auto_dim_no_visible_wallpaper); mDarkIntensityListeners = new ArrayList(); - mWallpaperVisibilityListener = new WallpaperVisibilityListener(this); - try { - mWallpaperVisible = mWindowManagerService.registerWallpaperVisibilityListener( - mWallpaperVisibilityListener, mDisplayTracker.getDefaultDisplayId()); - } catch (RemoteException e) { - } mView.addOnLayoutChangeListener( (v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> { View currentView = mView.getCurrentView(); @@ -142,14 +104,14 @@ public final class NavigationBarTransitions extends BarTransitions implements @Override public void destroy() { - try { - mWindowManagerService.unregisterWallpaperVisibilityListener(mWallpaperVisibilityListener, - mDisplayTracker.getDefaultDisplayId()); - } catch (RemoteException e) { - } mLightTransitionsController.destroy(); } + void setWallpaperVisibility(boolean visible) { + mWallpaperVisible = visible; + applyLightsOut(true, false); + } + @Override public void setAutoDim(boolean autoDim) { // Ensure we aren't in gestural nav if we are triggering auto dim diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavBarHelperTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavBarHelperTest.java index 1076f9f1a9474..56894d7903dc7 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavBarHelperTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavBarHelperTest.java @@ -150,6 +150,7 @@ public class NavBarHelperTest extends SysuiTestCase { mNavBarHelper); verify(mAssistManager, times(1)).getAssistInfoForUser(anyInt()); verify(mWm, times(1)).watchRotation(any(), anyInt()); + verify(mWm, times(1)).registerWallpaperVisibilityListener(any(), anyInt()); } @Test @@ -161,6 +162,7 @@ public class NavBarHelperTest extends SysuiTestCase { verify(mAccessibilityManager, times(1)).removeAccessibilityServicesStateChangeListener( mNavBarHelper); verify(mWm, times(1)).removeRotationWatcher(any()); + verify(mWm, times(1)).unregisterWallpaperVisibilityListener(any(), anyInt()); } @Test @@ -183,6 +185,8 @@ public class NavBarHelperTest extends SysuiTestCase { .updateAssistantAvailable(anyBoolean(), anyBoolean()); verify(mNavbarTaskbarStateUpdater, times(1)) .updateRotationWatcherState(anyInt()); + verify(mNavbarTaskbarStateUpdater, times(1)) + .updateWallpaperVisibility(anyBoolean(), anyInt()); } @Test diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTransitionsTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTransitionsTest.java index 5270737b7f3ed..54aec3014f956 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTransitionsTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTransitionsTest.java @@ -27,7 +27,6 @@ import static org.mockito.Mockito.when; import android.content.Context; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper.RunWithLooper; -import android.view.IWindowManager; import androidx.test.filters.SmallTest; @@ -60,8 +59,6 @@ public class NavigationBarTransitionsTest extends SysuiTestCase { EdgeBackGestureHandler.Factory mEdgeBackGestureHandlerFactory; @Mock EdgeBackGestureHandler mEdgeBackGestureHandler; - @Mock - IWindowManager mIWindowManager; private NavigationBarTransitions mTransitions; private final FakeDisplayTracker mDisplayTracker = new FakeDisplayTracker(mContext); @@ -88,7 +85,7 @@ public class NavigationBarTransitionsTest extends SysuiTestCase { when(navBar.getCurrentView()).thenReturn(navBar); when(navBar.findViewById(anyInt())).thenReturn(navBar); mTransitions = new NavigationBarTransitions( - navBar, mIWindowManager, mLightBarTransitionsFactory, mDisplayTracker); + navBar, mLightBarTransitionsFactory, mDisplayTracker); } @Test From a9001493800b8e5e0e20a0754d5e89bf950b8c4f Mon Sep 17 00:00:00 2001 From: Winson Chung Date: Sat, 4 Mar 2023 00:35:01 +0000 Subject: [PATCH 4/4] 4/ Keep EdgeBackGestureHandler state across nav/taskbar changes - Don't update the edge back handler state when switching between nav and taskbar (since the nav mode doesn't change and a bar still exists across the change) Bug: 219035565 Test: atest NavBarHelperTests Test: atest SystemUITests Change-Id: If930d8950e5cc19eb8d6e86f01b676c1acabbe2b --- .../systemui/navigationbar/NavBarHelper.java | 15 +++++++++++++++ .../systemui/navigationbar/NavigationBar.java | 6 +++--- .../systemui/navigationbar/NavigationBarView.java | 5 ----- .../systemui/navigationbar/TaskbarDelegate.java | 11 +++++------ .../gestural/EdgeBackGestureHandler.java | 4 ++-- .../systemui/navigationbar/NavBarHelperTest.java | 12 ++++++++++-- .../systemui/navigationbar/NavigationBarTest.java | 13 ++++++++----- .../systemui/navigationbar/TaskbarDelegateTest.kt | 8 +++----- 8 files changed, 46 insertions(+), 28 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavBarHelper.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavBarHelper.java index 59d6bfae53682..1da8718b111fb 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavBarHelper.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavBarHelper.java @@ -63,6 +63,7 @@ import com.android.systemui.accessibility.SystemActions; import com.android.systemui.assist.AssistManager; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dump.DumpManager; +import com.android.systemui.navigationbar.gestural.EdgeBackGestureHandler; import com.android.systemui.recents.OverviewProxyService; import com.android.systemui.settings.DisplayTracker; import com.android.systemui.settings.UserTracker; @@ -98,6 +99,7 @@ public final class NavBarHelper implements OverviewProxyService.OverviewProxyListener, NavigationModeController.ModeChangedListener, Dumpable, CommandQueue.Callbacks { private static final String TAG = NavBarHelper.class.getSimpleName(); + private final Handler mHandler = new Handler(Looper.getMainLooper()); private final AccessibilityManager mAccessibilityManager; private final Lazy mAssistManagerLazy; @@ -111,6 +113,7 @@ public final class NavBarHelper implements private final Context mContext; private final CommandQueue mCommandQueue; private final ContentResolver mContentResolver; + private final EdgeBackGestureHandler mEdgeBackGestureHandler; private final IWindowManager mWm; private final int mDefaultDisplayId; private boolean mAssistantAvailable; @@ -175,6 +178,7 @@ public final class NavBarHelper implements Lazy> centralSurfacesOptionalLazy, KeyguardStateController keyguardStateController, NavigationModeController navigationModeController, + EdgeBackGestureHandler.Factory edgeBackGestureHandlerFactory, IWindowManager wm, UserTracker userTracker, DisplayTracker displayTracker, @@ -193,6 +197,7 @@ public final class NavBarHelper implements mAccessibilityButtonTargetsObserver = accessibilityButtonTargetsObserver; mWm = wm; mDefaultDisplayId = displayTracker.getDefaultDisplayId(); + mEdgeBackGestureHandler = edgeBackGestureHandlerFactory.create(context); mNavBarMode = navigationModeController.addListener(this); mCommandQueue.addCallback(this); @@ -242,6 +247,9 @@ public final class NavBarHelper implements } catch (Exception e) { Log.w(TAG, "Failed to register wallpaper visibility listener", e); } + + // Attach the back handler only when the first bar is registered + mEdgeBackGestureHandler.onNavBarAttached(); } /** @@ -270,6 +278,9 @@ public final class NavBarHelper implements } catch (Exception e) { Log.w(TAG, "Failed to register wallpaper visibility listener", e); } + + // No more bars, detach the back handler for now + mEdgeBackGestureHandler.onNavBarDetached(); } /** @@ -429,6 +440,10 @@ public final class NavBarHelper implements return mLongPressHomeEnabled; } + public EdgeBackGestureHandler getEdgeBackGestureHandler() { + return mEdgeBackGestureHandler; + } + @Override public void startAssistant(Bundle bundle) { mAssistManagerLazy.get().startAssist(bundle); diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java index ab7581d2d10db..941770cff0147 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java @@ -208,7 +208,6 @@ public class NavigationBar extends ViewController implements private final Optional mRecentsOptional; private final DeviceConfigProxy mDeviceConfigProxy; private final NavigationBarTransitions mNavigationBarTransitions; - private final EdgeBackGestureHandler mEdgeBackGestureHandler; private final Optional mBackAnimation; private final Handler mHandler; private final UiEventLogger mUiEventLogger; @@ -220,6 +219,7 @@ public class NavigationBar extends ViewController implements private final DisplayTracker mDisplayTracker; private final RegionSamplingHelper mRegionSamplingHelper; private final int mNavColorSampleMargin; + private EdgeBackGestureHandler mEdgeBackGestureHandler; private NavigationBarFrame mFrame; private @WindowVisibleState int mNavigationBarWindowState = WINDOW_STATE_SHOWING; @@ -557,7 +557,6 @@ public class NavigationBar extends ViewController implements DeadZone deadZone, DeviceConfigProxy deviceConfigProxy, NavigationBarTransitions navigationBarTransitions, - EdgeBackGestureHandler edgeBackGestureHandler, Optional backAnimation, UserContextProvider userContextProvider, WakefulnessLifecycle wakefulnessLifecycle, @@ -587,7 +586,6 @@ public class NavigationBar extends ViewController implements mDeadZone = deadZone; mDeviceConfigProxy = deviceConfigProxy; mNavigationBarTransitions = navigationBarTransitions; - mEdgeBackGestureHandler = edgeBackGestureHandler; mBackAnimation = backAnimation; mHandler = mainHandler; mUiEventLogger = uiEventLogger; @@ -603,6 +601,7 @@ public class NavigationBar extends ViewController implements mWakefulnessLifecycle = wakefulnessLifecycle; mTaskStackChangeListeners = taskStackChangeListeners; mDisplayTracker = displayTracker; + mEdgeBackGestureHandler = navBarHelper.getEdgeBackGestureHandler(); mNavColorSampleMargin = getResources() .getDimensionPixelSize(R.dimen.navigation_handle_sample_horizontal_margin); @@ -722,6 +721,7 @@ public class NavigationBar extends ViewController implements mCommandQueue.removeCallback(this); mWindowManager.removeViewImmediate(mView.getRootView()); mNavigationModeController.removeListener(mModeChangedListener); + mEdgeBackGestureHandler.setStateChangeCallback(null); mNavBarHelper.removeNavTaskStateUpdater(mNavbarTaskbarStateUpdater); mNotificationShadeDepthController.removeListener(mDepthListener); diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java index 47701afc387b7..5d598e8dc765b 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java @@ -1093,9 +1093,6 @@ public class NavigationBarView extends FrameLayout { @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); - // This needs to happen first as it can changed the enabled state which can affect whether - // the back button is visible - mEdgeBackGestureHandler.onNavBarAttached(); requestApplyInsets(); reorient(); if (mRotationButtonController != null) { @@ -1115,8 +1112,6 @@ public class NavigationBarView extends FrameLayout { mFloatingRotationButton.hide(); mRotationButtonController.unregisterListeners(); } - - mEdgeBackGestureHandler.onNavBarDetached(); } void dump(PrintWriter pw) { diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java b/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java index dc5c9bd7b38a8..85d0ce53d9ff9 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java @@ -93,7 +93,7 @@ public class TaskbarDelegate implements CommandQueue.Callbacks, Dumpable { private static final String TAG = TaskbarDelegate.class.getSimpleName(); - private final EdgeBackGestureHandler mEdgeBackGestureHandler; + private EdgeBackGestureHandler mEdgeBackGestureHandler; private final LightBarTransitionsController.Factory mLightBarTransitionsControllerFactory; private boolean mInitialized; private CommandQueue mCommandQueue; @@ -171,15 +171,15 @@ public class TaskbarDelegate implements CommandQueue.Callbacks, private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager; @Inject public TaskbarDelegate(Context context, - EdgeBackGestureHandler.Factory edgeBackGestureHandlerFactory, LightBarTransitionsController.Factory lightBarTransitionsControllerFactory, StatusBarKeyguardViewManager statusBarKeyguardViewManager) { mLightBarTransitionsControllerFactory = lightBarTransitionsControllerFactory; - mEdgeBackGestureHandler = edgeBackGestureHandlerFactory.create(context); mContext = context; mDisplayManager = mContext.getSystemService(DisplayManager.class); - mPipListener = mEdgeBackGestureHandler::setPipStashExclusionBounds; + mPipListener = (bounds) -> { + mEdgeBackGestureHandler.setPipStashExclusionBounds(bounds); + }; mStatusBarKeyguardViewManager = statusBarKeyguardViewManager; mStatusBarKeyguardViewManager.setTaskbarDelegate(this); } @@ -207,6 +207,7 @@ public class TaskbarDelegate implements CommandQueue.Callbacks, mBackAnimation = backAnimation; mLightBarTransitionsController = createLightBarTransitionsController(); mTaskStackChangeListeners = taskStackChangeListeners; + mEdgeBackGestureHandler = navBarHelper.getEdgeBackGestureHandler(); } // Separated into a method to keep setDependencies() clean/readable. @@ -239,7 +240,6 @@ public class TaskbarDelegate implements CommandQueue.Callbacks, mOverviewProxyService.addCallback(this); onNavigationModeChanged(mNavigationModeController.addListener(this)); mNavBarHelper.registerNavTaskStateUpdater(mNavbarTaskbarStateUpdater); - mEdgeBackGestureHandler.onNavBarAttached(); // Initialize component callback Display display = mDisplayManager.getDisplay(displayId); mWindowContext = mContext.createWindowContext(display, TYPE_APPLICATION, null); @@ -263,7 +263,6 @@ public class TaskbarDelegate implements CommandQueue.Callbacks, mOverviewProxyService.removeCallback(this); mNavigationModeController.removeListener(this); mNavBarHelper.removeNavTaskStateUpdater(mNavbarTaskbarStateUpdater); - mEdgeBackGestureHandler.onNavBarDetached(); mScreenPinningNotify = null; mWindowContext = null; mAutoHideController.setNavigationBar(null); diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java index eea0e4cd94b94..c6f3968cec986 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java @@ -453,7 +453,7 @@ public class EdgeBackGestureHandler implements PluginListener mAccessibilityServicesStateChangeListener = invocation.getArgument(0)).when( @@ -129,8 +135,8 @@ public class NavBarHelperTest extends SysuiTestCase { mAccessibilityButtonModeObserver, mAccessibilityButtonTargetObserver, mSystemActions, mOverviewProxyService, mAssistManagerLazy, () -> Optional.of(mock(CentralSurfaces.class)), mock(KeyguardStateController.class), - mNavigationModeController, mWm, mUserTracker, mDisplayTracker, mDumpManager, - mCommandQueue); + mNavigationModeController, mEdgeBackGestureHandlerFactory, mWm, mUserTracker, + mDisplayTracker, mDumpManager, mCommandQueue); } @@ -151,6 +157,7 @@ public class NavBarHelperTest extends SysuiTestCase { verify(mAssistManager, times(1)).getAssistInfoForUser(anyInt()); verify(mWm, times(1)).watchRotation(any(), anyInt()); verify(mWm, times(1)).registerWallpaperVisibilityListener(any(), anyInt()); + verify(mEdgeBackGestureHandler, times(1)).onNavBarAttached(); } @Test @@ -163,6 +170,7 @@ public class NavBarHelperTest extends SysuiTestCase { mNavBarHelper); verify(mWm, times(1)).removeRotationWatcher(any()); verify(mWm, times(1)).unregisterWallpaperVisibilityListener(any(), anyInt()); + verify(mEdgeBackGestureHandler, times(1)).onNavBarDetached(); } @Test diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java index 35ab10ff4c164..f062ec732b21c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java @@ -174,8 +174,6 @@ public class NavigationBarTest extends SysuiTestCase { private UiEventLogger mUiEventLogger; @Mock private ViewTreeObserver mViewTreeObserver; - @Mock - EdgeBackGestureHandler mEdgeBackGestureHandler; NavBarHelper mNavBarHelper; @Mock private LightBarController mLightBarController; @@ -207,6 +205,10 @@ public class NavigationBarTest extends SysuiTestCase { private Resources mResources; @Mock private ViewRootImpl mViewRootImpl; + @Mock + private EdgeBackGestureHandler.Factory mEdgeBackGestureHandlerFactory; + @Mock + private EdgeBackGestureHandler mEdgeBackGestureHandler; private FakeExecutor mFakeExecutor = new FakeExecutor(new FakeSystemClock()); private DeviceConfigProxyFake mDeviceConfigProxyFake = new DeviceConfigProxyFake(); private TaskStackChangeListeners mTaskStackChangeListeners = @@ -236,6 +238,7 @@ public class NavigationBarTest extends SysuiTestCase { .thenReturn(mContext); when(mNavigationBarView.getResources()).thenReturn(mResources); when(mNavigationBarView.getViewRootImpl()).thenReturn(mViewRootImpl); + when(mEdgeBackGestureHandlerFactory.create(any())).thenReturn(mEdgeBackGestureHandler); setupSysuiDependency(); // This class inflates views that call Dependency.get, thus these injections are still // necessary. @@ -252,8 +255,9 @@ public class NavigationBarTest extends SysuiTestCase { mSystemActions, mOverviewProxyService, () -> mock(AssistManager.class), () -> Optional.of(mCentralSurfaces), mKeyguardStateController, mock(NavigationModeController.class), - mock(IWindowManager.class), mock(UserTracker.class), mock(DisplayTracker.class), - mock(DumpManager.class), mock(CommandQueue.class))); + mEdgeBackGestureHandlerFactory, mock(IWindowManager.class), + mock(UserTracker.class), mock(DisplayTracker.class), mock(DumpManager.class), + mock(CommandQueue.class))); mNavigationBar = createNavBar(mContext); mExternalDisplayNavigationBar = createNavBar(mSysuiTestableContextExternal); }); @@ -495,7 +499,6 @@ public class NavigationBarTest extends SysuiTestCase { mDeadZone, mDeviceConfigProxyFake, mNavigationBarTransitions, - mEdgeBackGestureHandler, Optional.of(mock(BackAnimation.class)), mUserContextProvider, mWakefulnessLifecycle, diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/TaskbarDelegateTest.kt b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/TaskbarDelegateTest.kt index 1c9336a3fc66c..8d01e80d37d4e 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/TaskbarDelegateTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/TaskbarDelegateTest.kt @@ -38,8 +38,6 @@ class TaskbarDelegateTest : SysuiTestCase() { private lateinit var mTaskStackChangeListeners: TaskStackChangeListeners private lateinit var mTaskbarDelegate: TaskbarDelegate @Mock - lateinit var mEdgeBackGestureHandlerFactory : EdgeBackGestureHandler.Factory - @Mock lateinit var mEdgeBackGestureHandler : EdgeBackGestureHandler @Mock lateinit var mLightBarControllerFactory : LightBarTransitionsController.Factory @@ -73,13 +71,13 @@ class TaskbarDelegateTest : SysuiTestCase() { @Before fun setup() { MockitoAnnotations.initMocks(this) - `when`(mEdgeBackGestureHandlerFactory.create(context)).thenReturn(mEdgeBackGestureHandler) + `when`(mNavBarHelper.edgeBackGestureHandler).thenReturn(mEdgeBackGestureHandler) `when`(mLightBarControllerFactory.create(any())).thenReturn(mLightBarTransitionController) `when`(mNavBarHelper.currentSysuiState).thenReturn(mCurrentSysUiState) `when`(mSysUiState.setFlag(anyInt(), anyBoolean())).thenReturn(mSysUiState) mTaskStackChangeListeners = TaskStackChangeListeners.getTestInstance() - mTaskbarDelegate = TaskbarDelegate(context, mEdgeBackGestureHandlerFactory, - mLightBarControllerFactory, mStatusBarKeyguardViewManager) + mTaskbarDelegate = TaskbarDelegate(context, mLightBarControllerFactory, + mStatusBarKeyguardViewManager) mTaskbarDelegate.setDependencies(mCommandQueue, mOverviewProxyService, mNavBarHelper, mNavigationModeController, mSysUiState, mDumpManager, mAutoHideController, mLightBarController, mOptionalPip, mBackAnimation, mTaskStackChangeListeners)