summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/rotation/RotationButtonController.java91
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/NavBarHelper.java49
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java19
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavBarHelperTest.java25
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java5
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);
});