diff options
| author | 2023-03-03 23:28:56 +0000 | |
|---|---|---|
| committer | 2023-03-09 17:29:27 +0000 | |
| commit | f07c2b4c12e229fb660666bd6526efab30f6415b (patch) | |
| tree | fac7486a1b1d0ecf273a382d815f5053fa318754 | |
| parent | 42ea6883674e449cbb4d530868c2aac799680d3c (diff) | |
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
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 5b27c40740da..53fab69bd3b8 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<Integer> 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<Integer> 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 731f712c57c8..24098122aec6 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<AssistManager> 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<Optional<CentralSurfaces>> 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 1c36e92cff00..db545099f8ac 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<NavigationBarView> 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<NavigationBarView> 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<NavigationBarView> 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<NavigationBarView> implements return mNavBarMode == NAV_BAR_MODE_GESTURAL && mOrientationHandle != null; } - private final Consumer<Integer> 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 63fb4996fbbf..47701afc387b 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 fbe83af78080..1076f9f1a947 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 764ddc49d110..35ab10ff4c16 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); }); |