Propagate the display id with SysUIState changes to launcher
This changes the ILauncherProxy.aidl interface to also allow propagating the display id from SysUI to launcher for each SysUIState update.
The SysUI part of filling SysUI state correctly has not been implemented yet. But for now, only default display flags are propagated anyway.
On the launcher side, the sysui state is propagated correctly to each taskbar instance (there is one for each display)
Bug: 362719719
Bug: 398011576
Bug: 399371607
Test: LauncherProxyServiceTest
Flag: com.android.systemui.shade_window_goes_around
Change-Id: Ic9fa55ca82e4fe395a915c4d611afc8835c5d65d
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
index 5155ffc..4a8a3de 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
@@ -705,13 +705,14 @@
}
}
- public void onSystemUiFlagsChanged(@SystemUiStateFlags long systemUiStateFlags) {
+ /** Called when the SysUI flags for a given display change. */
+ public void onSystemUiFlagsChanged(@SystemUiStateFlags long systemUiStateFlags, int displayId) {
if (DEBUG) {
Log.d(TAG, "SysUI flags changed: " + formatFlagChange(systemUiStateFlags,
mSharedState.sysuiStateFlags, QuickStepContract::getSystemUiStateString));
}
mSharedState.sysuiStateFlags = systemUiStateFlags;
- TaskbarActivityContext taskbar = getTaskbarForDisplay(getDefaultDisplayId());
+ TaskbarActivityContext taskbar = getTaskbarForDisplay(displayId);
if (taskbar != null) {
taskbar.updateSysuiStateFlags(systemUiStateFlags, false /* fromInit */);
}
diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java b/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
index 090ccdc..74f24ee 100644
--- a/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
+++ b/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
@@ -88,6 +88,9 @@
import com.android.systemui.shared.system.TaskStackChangeListeners;
import java.io.PrintWriter;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
import javax.inject.Inject;
@@ -119,6 +122,7 @@
InputMethodService.canImeRenderGesturalNavButtons();
private @SystemUiStateFlags long mSystemUiStateFlags = QuickStepContract.SYSUI_STATE_AWAKE;
+ private final Map<Integer, Long> mSysUIStateFlagsPerDisplay = new ConcurrentHashMap<>();
private NavigationMode mMode = THREE_BUTTONS;
private NavBarPosition mNavBarPosition;
@@ -353,22 +357,51 @@
}
/**
- * Updates the system ui state flags from SystemUI.
+ * Updates the system ui state flags from SystemUI for a specific display.
+ *
+ * @param stateFlags the current {@link SystemUiStateFlags} for the display.
+ * @param displayId the display's ID.
*/
- public void setSystemUiFlags(@SystemUiStateFlags long stateFlags) {
- mSystemUiStateFlags = stateFlags;
+ public void setSysUIStateFlagsForDisplay(@SystemUiStateFlags long stateFlags,
+ int displayId) {
+ mSysUIStateFlagsPerDisplay.put(displayId, stateFlags);
}
/**
- * @return the system ui state flags.
+ * Clears the system ui state flags for a specific display. This is called when the display is
+ * destroyed.
+ *
+ * @param displayId the display's ID.
+ */
+ public void clearSysUIStateFlagsForDisplay(int displayId) {
+ mSysUIStateFlagsPerDisplay.remove(displayId);
+ }
+
+ /**
+ * @return the system ui state flags for the default display.
*/
// TODO(141886704): See if we can remove this
@SystemUiStateFlags
- public long getSystemUiStateFlags() {
- return mSystemUiStateFlags;
+ public long getSysuiStateFlag() {
+ return getSystemUiStateFlags(DEFAULT_DISPLAY);
}
/**
+ * @return the system ui state flags for a given display ID.
+ */
+ @SystemUiStateFlags
+ public long getSystemUiStateFlags(int displayId) {
+ return mSysUIStateFlagsPerDisplay.getOrDefault(displayId,
+ QuickStepContract.SYSUI_STATE_AWAKE);
+ }
+
+ /**
+ * @return the display ids that have sysui state.
+ */
+ public Set<Integer> getDisplaysWithSysUIState() {
+ return mSysUIStateFlagsPerDisplay.keySet();
+ }
+ /**
* Sets the flag that indicates whether a predictive back-to-home animation is in progress
*/
public void setPredictiveBackToHomeInProgress(boolean isInProgress) {
@@ -386,8 +419,8 @@
* @return whether SystemUI is in a state where we can start a system gesture.
*/
public boolean canStartSystemGesture() {
- boolean canStartWithNavHidden = (mSystemUiStateFlags & SYSUI_STATE_NAV_BAR_HIDDEN) == 0
- || (mSystemUiStateFlags & SYSUI_STATE_ALLOW_GESTURE_IGNORING_BAR_VISIBILITY) != 0
+ boolean canStartWithNavHidden = (getSysuiStateFlag() & SYSUI_STATE_NAV_BAR_HIDDEN) == 0
+ || (getSysuiStateFlag() & SYSUI_STATE_ALLOW_GESTURE_IGNORING_BAR_VISIBILITY) != 0
|| mRotationTouchHelper.isTaskListFrozen();
return canStartWithNavHidden && canStartAnyGesture();
}
@@ -399,7 +432,7 @@
*/
public boolean canStartTrackpadGesture() {
boolean trackpadGesturesEnabled =
- (mSystemUiStateFlags & SYSUI_STATE_TOUCHPAD_GESTURES_DISABLED) == 0;
+ (getSysuiStateFlag() & SYSUI_STATE_TOUCHPAD_GESTURES_DISABLED) == 0;
return trackpadGesturesEnabled && canStartAnyGesture();
}
@@ -407,8 +440,8 @@
* Common logic to determine if either trackpad or finger gesture can be started
*/
private boolean canStartAnyGesture() {
- boolean homeOrOverviewEnabled = (mSystemUiStateFlags & SYSUI_STATE_HOME_DISABLED) == 0
- || (mSystemUiStateFlags & SYSUI_STATE_OVERVIEW_DISABLED) == 0;
+ boolean homeOrOverviewEnabled = (getSysuiStateFlag() & SYSUI_STATE_HOME_DISABLED) == 0
+ || (getSysuiStateFlag() & SYSUI_STATE_OVERVIEW_DISABLED) == 0;
long gestureDisablingStates = SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED
| SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING
| SYSUI_STATE_QUICK_SETTINGS_EXPANDED
@@ -416,7 +449,7 @@
| SYSUI_STATE_DEVICE_DREAMING
| SYSUI_STATE_DISABLE_GESTURE_SPLIT_INVOCATION
| SYSUI_STATE_DISABLE_GESTURE_PIP_ANIMATING;
- return (gestureDisablingStates & mSystemUiStateFlags) == 0 && homeOrOverviewEnabled;
+ return (gestureDisablingStates & getSysuiStateFlag()) == 0 && homeOrOverviewEnabled;
}
/**
@@ -424,35 +457,35 @@
* (like camera or maps)
*/
public boolean isKeyguardShowingOccluded() {
- return (mSystemUiStateFlags & SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED) != 0;
+ return (getSysuiStateFlag() & SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED) != 0;
}
/**
* @return whether screen pinning is enabled and active
*/
public boolean isScreenPinningActive() {
- return (mSystemUiStateFlags & SYSUI_STATE_SCREEN_PINNING) != 0;
+ return (getSysuiStateFlag() & SYSUI_STATE_SCREEN_PINNING) != 0;
}
/**
* @return whether assistant gesture is constraint
*/
public boolean isAssistantGestureIsConstrained() {
- return (mSystemUiStateFlags & SYSUI_STATE_ASSIST_GESTURE_CONSTRAINED) != 0;
+ return (getSysuiStateFlag() & SYSUI_STATE_ASSIST_GESTURE_CONSTRAINED) != 0;
}
/**
* @return whether the bubble stack is expanded
*/
public boolean isBubblesExpanded() {
- return (mSystemUiStateFlags & SYSUI_STATE_BUBBLES_EXPANDED) != 0;
+ return (getSysuiStateFlag() & SYSUI_STATE_BUBBLES_EXPANDED) != 0;
}
/**
* @return whether the global actions dialog is showing
*/
public boolean isSystemUiDialogShowing() {
- return (mSystemUiStateFlags & SYSUI_STATE_DIALOG_SHOWING) != 0;
+ return (getSysuiStateFlag() & SYSUI_STATE_DIALOG_SHOWING) != 0;
}
/**
@@ -466,35 +499,35 @@
* @return whether the accessibility menu is available.
*/
public boolean isAccessibilityMenuAvailable() {
- return (mSystemUiStateFlags & SYSUI_STATE_A11Y_BUTTON_CLICKABLE) != 0;
+ return (getSysuiStateFlag() & SYSUI_STATE_A11Y_BUTTON_CLICKABLE) != 0;
}
/**
* @return whether the accessibility menu shortcut is available.
*/
public boolean isAccessibilityMenuShortcutAvailable() {
- return (mSystemUiStateFlags & SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE) != 0;
+ return (getSysuiStateFlag() & SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE) != 0;
}
/**
* @return whether home is disabled (either by SUW/SysUI/device policy)
*/
public boolean isHomeDisabled() {
- return (mSystemUiStateFlags & SYSUI_STATE_HOME_DISABLED) != 0;
+ return (getSysuiStateFlag() & SYSUI_STATE_HOME_DISABLED) != 0;
}
/**
* @return whether overview is disabled (either by SUW/SysUI/device policy)
*/
public boolean isOverviewDisabled() {
- return (mSystemUiStateFlags & SYSUI_STATE_OVERVIEW_DISABLED) != 0;
+ return (getSysuiStateFlag() & SYSUI_STATE_OVERVIEW_DISABLED) != 0;
}
/**
* @return whether one-handed mode is enabled and active
*/
public boolean isOneHandedModeActive() {
- return (mSystemUiStateFlags & SYSUI_STATE_ONE_HANDED_ACTIVE) != 0;
+ return (getSysuiStateFlag() & SYSUI_STATE_ONE_HANDED_ACTIVE) != 0;
}
/**
@@ -557,7 +590,7 @@
*/
public boolean canTriggerAssistantAction(MotionEvent ev) {
return mAssistantAvailable
- && !QuickStepContract.isAssistantGestureDisabled(mSystemUiStateFlags)
+ && !QuickStepContract.isAssistantGestureDisabled(getSysuiStateFlag())
&& mRotationTouchHelper.touchInAssistantRegion(ev)
&& !isTrackpadScroll(ev)
&& !isLockToAppActive();
@@ -597,7 +630,7 @@
/** Returns whether IME is rendering nav buttons, and IME is currently showing. */
public boolean isImeRenderingNavButtons() {
return mCanImeRenderGesturalNavButtons && mMode == NO_BUTTON
- && ((mSystemUiStateFlags & SYSUI_STATE_IME_VISIBLE) != 0);
+ && ((getSysuiStateFlag() & SYSUI_STATE_IME_VISIBLE) != 0);
}
/**
@@ -629,24 +662,37 @@
return touchSlop * touchSlop;
}
+ /** Returns a string representation of the system ui state flags for the default display. */
public String getSystemUiStateString() {
- return QuickStepContract.getSystemUiStateString(mSystemUiStateFlags);
+ return getSystemUiStateString(getSysuiStateFlag());
+ }
+
+ /** Returns a string representation of the system ui state flags. */
+ public String getSystemUiStateString(long flags) {
+ return QuickStepContract.getSystemUiStateString(flags);
}
public void dump(PrintWriter pw) {
pw.println("DeviceState:");
pw.println(" canStartSystemGesture=" + canStartSystemGesture());
- pw.println(" systemUiFlags=" + mSystemUiStateFlags);
+ pw.println(" systemUiFlagsForDefaultDisplay=" + getSysuiStateFlag());
pw.println(" systemUiFlagsDesc=" + getSystemUiStateString());
pw.println(" assistantAvailable=" + mAssistantAvailable);
pw.println(" assistantDisabled="
- + QuickStepContract.isAssistantGestureDisabled(mSystemUiStateFlags));
+ + QuickStepContract.isAssistantGestureDisabled(getSysuiStateFlag()));
pw.println(" isOneHandedModeEnabled=" + mIsOneHandedModeEnabled);
pw.println(" isSwipeToNotificationEnabled=" + mIsSwipeToNotificationEnabled);
pw.println(" deferredGestureRegion=" + mDeferredGestureRegion.getBounds());
pw.println(" exclusionRegion=" + mExclusionRegion.getBounds());
pw.println(" pipIsActive=" + mPipIsActive);
pw.println(" predictiveBackToHomeInProgress=" + mIsPredictiveBackToHomeInProgress);
+ for (int displayId : mSysUIStateFlagsPerDisplay.keySet()) {
+ pw.println(" systemUiFlagsForDisplay" + displayId + "=" + getSystemUiStateFlags(
+ displayId));
+ pw.println(" systemUiFlagsForDisplay" + displayId + "Desc=" + getSystemUiStateString(
+ getSystemUiStateFlags(displayId)));
+ }
+ pw.println(" RotationTouchHelper:");
mRotationTouchHelper.dump(pw);
}
}
diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java
index ba4c65a..5ca9319 100644
--- a/quickstep/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java
@@ -53,6 +53,7 @@
import android.os.SystemClock;
import android.util.Log;
import android.view.Choreographer;
+import android.view.Display;
import android.view.InputDevice;
import android.view.InputEvent;
import android.view.MotionEvent;
@@ -274,11 +275,12 @@
}
@BinderThread
- public void onSystemUiStateChanged(@SystemUiStateFlags long stateFlags) {
+ public void onSystemUiStateChanged(@SystemUiStateFlags long stateFlags, int displayId) {
MAIN_EXECUTOR.execute(() -> executeForTouchInteractionService(tis -> {
- long lastFlags = tis.mDeviceState.getSystemUiStateFlags();
- tis.mDeviceState.setSystemUiFlags(stateFlags);
- tis.onSystemUiFlagsChanged(lastFlags);
+ // Last flags is only used for the default display case.
+ long lastFlags = tis.mDeviceState.getSysuiStateFlag();
+ tis.mDeviceState.setSysUIStateFlagsForDisplay(stateFlags, displayId);
+ tis.onSystemUiFlagsChanged(lastFlags, displayId);
}));
}
@@ -312,6 +314,9 @@
public void onDisplayRemoved(int displayId) {
executeForTaskbarManager(taskbarManager ->
taskbarManager.onDisplayRemoved(displayId));
+ executeForTouchInteractionService(tis -> {
+ tis.mDeviceState.clearSysUIStateFlagsForDisplay(displayId);
+ });
}
@BinderThread
@@ -649,7 +654,9 @@
mResetGestureInputConsumer = new ResetGestureInputConsumer(
mTaskAnimationManager, mTaskbarManager::getCurrentActivityContext);
mInputConsumer.registerInputConsumer();
- onSystemUiFlagsChanged(mDeviceState.getSystemUiStateFlags());
+ for (int displayId : mDeviceState.getDisplaysWithSysUIState()) {
+ onSystemUiFlagsChanged(mDeviceState.getSystemUiStateFlags(displayId), displayId);
+ }
onAssistantVisibilityChanged();
// Initialize the task tracker
@@ -711,13 +718,19 @@
}
@UiThread
- private void onSystemUiFlagsChanged(@SystemUiStateFlags long lastSysUIFlags) {
+ private void onSystemUiFlagsChanged(@SystemUiStateFlags long lastSysUIFlags, int displayId) {
if (LockedUserState.get(this).isUserUnlocked()) {
- long systemUiStateFlags = mDeviceState.getSystemUiStateFlags();
- SystemUiProxy.INSTANCE.get(this).setLastSystemUiStateFlags(systemUiStateFlags);
- mOverviewComponentObserver.setHomeDisabled(mDeviceState.isHomeDisabled());
- mTaskbarManager.onSystemUiFlagsChanged(systemUiStateFlags);
- mTaskAnimationManager.onSystemUiFlagsChanged(lastSysUIFlags, systemUiStateFlags);
+ long systemUiStateFlags = mDeviceState.getSystemUiStateFlags(displayId);
+ mTaskbarManager.onSystemUiFlagsChanged(systemUiStateFlags, displayId);
+ if (displayId == Display.DEFAULT_DISPLAY) {
+ // The following don't care about non-default displays, at least for now. If they
+ // ever will, they should be taken care of.
+ SystemUiProxy.INSTANCE.get(this).setLastSystemUiStateFlags(systemUiStateFlags);
+ mOverviewComponentObserver.setHomeDisabled(mDeviceState.isHomeDisabled());
+ // TODO b/399371607 - Propagate to taskAnimationManager once overview is multi
+ // display.
+ mTaskAnimationManager.onSystemUiFlagsChanged(lastSysUIFlags, systemUiStateFlags);
+ }
}
}
diff --git a/quickstep/tests/multivalentTests/src/com/android/quickstep/RecentsAnimationDeviceStateTest.kt b/quickstep/tests/multivalentTests/src/com/android/quickstep/RecentsAnimationDeviceStateTest.kt
index b652ee8..a7370b0 100644
--- a/quickstep/tests/multivalentTests/src/com/android/quickstep/RecentsAnimationDeviceStateTest.kt
+++ b/quickstep/tests/multivalentTests/src/com/android/quickstep/RecentsAnimationDeviceStateTest.kt
@@ -1,5 +1,6 @@
package com.android.quickstep
+import android.view.Display
import androidx.test.annotation.UiThreadTest
import androidx.test.filters.SmallTest
import com.android.launcher3.dagger.LauncherComponentProvider
@@ -13,6 +14,7 @@
import com.android.launcher3.util.NavigationMode
import com.android.launcher3.util.SandboxApplication
import com.android.quickstep.util.GestureExclusionManager
+import com.android.systemui.shared.system.QuickStepContract
import com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_ALLOW_GESTURE_IGNORING_BAR_VISIBILITY
import com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_DEVICE_DREAMING
import com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_DISABLE_GESTURE_SPLIT_INVOCATION
@@ -150,7 +152,7 @@
allSysUiStates().forEach { state ->
val canStartGesture = !disablingStates.contains(state)
- underTest.setSystemUiFlags(state)
+ underTest.setSysUIStateFlagsForDisplay(state, Display.DEFAULT_DISPLAY)
assertThat(underTest.canStartTrackpadGesture()).isEqualTo(canStartGesture)
}
}
@@ -166,7 +168,7 @@
)
stateToExpectedResult.forEach { (state, allowed) ->
- underTest.setSystemUiFlags(state)
+ underTest.setSysUIStateFlagsForDisplay(state, Display.DEFAULT_DISPLAY)
assertThat(underTest.canStartTrackpadGesture()).isEqualTo(allowed)
}
}
@@ -177,7 +179,7 @@
allSysUiStates().forEach { state ->
val canStartGesture = !disablingStates.contains(state)
- underTest.setSystemUiFlags(state)
+ underTest.setSysUIStateFlagsForDisplay(state, Display.DEFAULT_DISPLAY)
assertThat(underTest.canStartSystemGesture()).isEqualTo(canStartGesture)
}
}
@@ -197,11 +199,42 @@
)
stateToExpectedResult.forEach { (state, gestureAllowed) ->
- underTest.setSystemUiFlags(state)
+ underTest.setSysUIStateFlagsForDisplay(state, Display.DEFAULT_DISPLAY)
assertThat(underTest.canStartSystemGesture()).isEqualTo(gestureAllowed)
}
}
+ @Test
+ fun getSystemUiStateFlags_defaultAwake() {
+ val NOT_EXISTENT_DISPLAY = 2
+ assertThat(underTest.getSystemUiStateFlags(NOT_EXISTENT_DISPLAY))
+ .isEqualTo(QuickStepContract.SYSUI_STATE_AWAKE)
+ }
+
+ @Test
+ fun clearSysUIStateFlagsForDisplay_displayNotReturnedAnymore() {
+ underTest.setSysUIStateFlagsForDisplay(1, /* displayId= */ 1)
+
+ assertThat(underTest.displaysWithSysUIState).contains(1)
+ assertThat(underTest.getSystemUiStateFlags(1)).isEqualTo(1)
+
+ underTest.clearSysUIStateFlagsForDisplay(1)
+
+ assertThat(underTest.displaysWithSysUIState).doesNotContain(1)
+ assertThat(underTest.getSystemUiStateFlags(1))
+ .isEqualTo(QuickStepContract.SYSUI_STATE_AWAKE)
+ }
+
+ @Test
+ fun setSysUIStateFlagsForDisplay_setsCorrectly() {
+ underTest.setSysUIStateFlagsForDisplay(1, /* displayId= */ 1)
+ underTest.setSysUIStateFlagsForDisplay(2, /* displayId= */ 2)
+
+ assertThat(underTest.getSystemUiStateFlags(1)).isEqualTo(1)
+ assertThat(underTest.getSystemUiStateFlags(2)).isEqualTo(2)
+ assertThat(underTest.displaysWithSysUIState).containsAtLeast(1, 2)
+ }
+
private fun allSysUiStates(): List<Long> {
// SYSUI_STATES_* are binary flags
return (0..SYSUI_STATES_COUNT).map { 1L shl it }