From 308b7849db91b6ff23618bd86f6f1abcb7b8545e Mon Sep 17 00:00:00 2001 From: Mike Schneider Date: Thu, 2 Mar 2023 15:39:33 +0100 Subject: [PATCH] Do not perform invisible transitions while the screen is off. This change caches whether launcher was active at the time of the screen off, and assumes this last state when the screen is actually off. While trying to understand the code, I renamed a couple class-internal methods and flags, plus added comments. If they are not accurate, its due to a misunderstanding on my part, and I will gladly revisit and check whether all the assumptions I made still hold. Bug: 261418621 Test: manually Change-Id: I2ad25caf478100781a063c356c5fd2d20d3e1917 Merged-In: I2ad25caf478100781a063c356c5fd2d20d3e1917 --- .../taskbar/LauncherTaskbarUIController.java | 20 +- .../taskbar/TaskbarActivityContext.java | 5 +- .../launcher3/taskbar/TaskbarControllers.java | 1 - .../taskbar/TaskbarKeyguardController.java | 57 +++--- .../TaskbarLauncherStateController.java | 192 ++++++++++++------ .../taskbar/TaskbarStashController.java | 27 +-- .../taskbar/TaskbarUIController.java | 6 + 7 files changed, 187 insertions(+), 121 deletions(-) diff --git a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java index 95fea3ed8c..e03c24dd81 100644 --- a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java +++ b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java @@ -84,7 +84,6 @@ public class LauncherTaskbarUIController extends TaskbarUIController { }; // Initialized in init. - private TaskbarKeyguardController mKeyguardController; private final TaskbarLauncherStateController mTaskbarLauncherStateController = new TaskbarLauncherStateController(); @@ -99,11 +98,12 @@ public class LauncherTaskbarUIController extends TaskbarUIController { mTaskbarLauncherStateController.init(mControllers, mLauncher); mLauncher.setTaskbarUIController(this); - mKeyguardController = taskbarControllers.taskbarKeyguardController; onLauncherResumedOrPaused(mLauncher.hasBeenResumed(), true /* fromInit */); onStashedInAppChanged(mLauncher.getDeviceProfile()); + mTaskbarLauncherStateController.onChangeScreenState( + mControllers.getSharedState().sysuiStateFlags, true /* fromInit */); mLauncher.addOnDeviceProfileChangeListener(mOnDeviceProfileChangeListener); } @@ -121,7 +121,7 @@ public class LauncherTaskbarUIController extends TaskbarUIController { @Override protected boolean isTaskbarTouchable() { return !(mTaskbarLauncherStateController.isAnimatingToLauncher() - && mTaskbarLauncherStateController.goingToAlignedLauncherState()); + && mTaskbarLauncherStateController.isTaskbarAlignedWithHotseat()); } public void setShouldDelayLauncherStateAnim(boolean shouldDelayLauncherStateAnim) { @@ -169,15 +169,6 @@ public class LauncherTaskbarUIController extends TaskbarUIController { @Nullable private Animator onLauncherResumedOrPaused( boolean isResumed, boolean fromInit, boolean startAnimation, int duration) { - if (mKeyguardController.isScreenOff()) { - if (!isResumed) { - return null; - } else { - // Resuming implicitly means device unlocked - mKeyguardController.setScreenOn(); - } - } - if (ENABLE_SHELL_TRANSITIONS && isResumed && !mLauncher.getStateManager().getState().isTaskbarAlignedWithHotseat(mLauncher)) { // Launcher is resumed, but in a state where taskbar is still independent, so @@ -328,6 +319,11 @@ public class LauncherTaskbarUIController extends TaskbarUIController { mTaskbarLauncherStateController.applyState(); } + @Override + public void onChangeScreenState(int screenState) { + mTaskbarLauncherStateController.onChangeScreenState(screenState, false /* fromInit */); + } + @Override public boolean isIconAlignedWithHotseat() { return mTaskbarLauncherStateController.isIconAlignedWithHotseat(); diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java index 62713ca557..a14931eff0 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java @@ -32,6 +32,7 @@ import static com.android.launcher3.taskbar.TaskbarManager.FLAG_HIDE_NAVBAR_WIND import static com.android.launcher3.testing.shared.ResourceUtils.getBoolByName; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_QUICK_SETTINGS_EXPANDED; +import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_SCREEN_STATE_MASK; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_VOICE_INTERACTION_WINDOW_SHOWING; import android.animation.AnimatorSet; @@ -56,7 +57,6 @@ import android.view.Gravity; import android.view.RoundedCorner; import android.view.View; import android.view.WindowManager; -import android.view.WindowManagerGlobal; import android.widget.FrameLayout; import android.widget.Toast; @@ -578,6 +578,9 @@ public class TaskbarActivityContext extends BaseTaskbarContext { mControllers.taskbarForceVisibleImmersiveController.updateSysuiFlags(systemUiStateFlags); mControllers.voiceInteractionWindowController.setIsVoiceInteractionWindowVisible( (systemUiStateFlags & SYSUI_STATE_VOICE_INTERACTION_WINDOW_SHOWING) != 0, fromInit); + + mControllers.uiController.onChangeScreenState( + systemUiStateFlags & SYSUI_STATE_SCREEN_STATE_MASK); } /** diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java index 931d79f885..e00c45c348 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java @@ -209,7 +209,6 @@ public class TaskbarControllers { uiController.onDestroy(); rotationButtonController.onDestroy(); taskbarDragLayerController.onDestroy(); - taskbarKeyguardController.onDestroy(); taskbarUnfoldAnimationController.onDestroy(); taskbarViewController.onDestroy(); stashedHandleViewController.onDestroy(); diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarKeyguardController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarKeyguardController.java index 93ba4eb002..4e390f106e 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarKeyguardController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarKeyguardController.java @@ -1,19 +1,20 @@ package com.android.launcher3.taskbar; import static com.android.launcher3.AbstractFloatingView.TYPE_ALL; +import static com.android.systemui.shared.system.QuickStepContract.SCREEN_STATE_OFF; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BACK_DISABLED; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BOUNCER_SHOWING; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_DEVICE_DOZING; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_HOME_DISABLED; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_OVERVIEW_DISABLED; +import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_SCREEN_ON; +import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_SCREEN_STATE_MASK; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED; import android.app.KeyguardManager; import com.android.launcher3.AbstractFloatingView; -import com.android.launcher3.util.ScreenOnTracker; -import com.android.launcher3.util.ScreenOnTracker.ScreenOnListener; import com.android.systemui.shared.system.QuickStepContract; import java.io.PrintWriter; @@ -23,36 +24,35 @@ import java.io.PrintWriter; */ public class TaskbarKeyguardController implements TaskbarControllers.LoggableTaskbarController { - private static final int KEYGUARD_SYSUI_FLAGS = SYSUI_STATE_BOUNCER_SHOWING | - SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING | SYSUI_STATE_DEVICE_DOZING | - SYSUI_STATE_OVERVIEW_DISABLED | SYSUI_STATE_HOME_DISABLED | - SYSUI_STATE_BACK_DISABLED | SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED; + private static final int KEYGUARD_SYSUI_FLAGS = SYSUI_STATE_BOUNCER_SHOWING + | SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING | SYSUI_STATE_DEVICE_DOZING + | SYSUI_STATE_OVERVIEW_DISABLED | SYSUI_STATE_HOME_DISABLED + | SYSUI_STATE_BACK_DISABLED | SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED + | SYSUI_STATE_SCREEN_STATE_MASK; - private final ScreenOnListener mScreenOnListener; private final TaskbarActivityContext mContext; private int mKeyguardSysuiFlags; private boolean mBouncerShowing; private NavbarButtonsViewController mNavbarButtonsViewController; private final KeyguardManager mKeyguardManager; - private boolean mIsScreenOff; public TaskbarKeyguardController(TaskbarActivityContext context) { mContext = context; - mScreenOnListener = isOn -> { - if (!isOn) { - mIsScreenOff = true; - AbstractFloatingView.closeOpenViews(mContext, false, TYPE_ALL); - } - }; mKeyguardManager = mContext.getSystemService(KeyguardManager.class); } public void init(NavbarButtonsViewController navbarButtonUIController) { mNavbarButtonsViewController = navbarButtonUIController; - ScreenOnTracker.INSTANCE.get(mContext).addListener(mScreenOnListener); } public void updateStateForSysuiFlags(int systemUiStateFlags) { + int interestingKeyguardFlags = systemUiStateFlags & KEYGUARD_SYSUI_FLAGS; + if (interestingKeyguardFlags == mKeyguardSysuiFlags) { + // No change in keyguard relevant flags + return; + } + mKeyguardSysuiFlags = interestingKeyguardFlags; + boolean bouncerShowing = (systemUiStateFlags & SYSUI_STATE_BOUNCER_SHOWING) != 0; boolean keyguardShowing = (systemUiStateFlags & SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING) != 0; @@ -60,11 +60,6 @@ public class TaskbarKeyguardController implements TaskbarControllers.LoggableTas (systemUiStateFlags & SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED) != 0; boolean dozing = (systemUiStateFlags & SYSUI_STATE_DEVICE_DOZING) != 0; - int interestingKeyguardFlags = systemUiStateFlags & KEYGUARD_SYSUI_FLAGS; - if (interestingKeyguardFlags == mKeyguardSysuiFlags) { - return; - } - mKeyguardSysuiFlags = interestingKeyguardFlags; mBouncerShowing = bouncerShowing; @@ -72,19 +67,17 @@ public class TaskbarKeyguardController implements TaskbarControllers.LoggableTas keyguardOccluded); updateIconsForBouncer(); - if (keyguardShowing) { - AbstractFloatingView.closeOpenViews(mContext, true, TYPE_ALL); + boolean screenOffOrTransitioningOff = (systemUiStateFlags & SYSUI_STATE_SCREEN_ON) == 0; + boolean closeFloatingViews = keyguardShowing || screenOffOrTransitioningOff; + + if (closeFloatingViews) { + // animate the closing of the views, unless the screen is already fully turned off. + boolean animateViewClosing = + (systemUiStateFlags & SYSUI_STATE_SCREEN_STATE_MASK) != SCREEN_STATE_OFF; + AbstractFloatingView.closeOpenViews(mContext, animateViewClosing, TYPE_ALL); } } - public boolean isScreenOff() { - return mIsScreenOff; - } - - public void setScreenOn() { - mIsScreenOff = false; - } - /** * Hides/shows taskbar when keyguard is up */ @@ -95,9 +88,6 @@ public class TaskbarKeyguardController implements TaskbarControllers.LoggableTas mNavbarButtonsViewController.setBackForBouncer(showBackForBouncer); } - public void onDestroy() { - ScreenOnTracker.INSTANCE.get(mContext).removeListener(mScreenOnListener); - } @Override public void dumpLogs(String prefix, PrintWriter pw) { @@ -106,6 +96,5 @@ public class TaskbarKeyguardController implements TaskbarControllers.LoggableTas pw.println(prefix + "\tmKeyguardSysuiFlags=" + QuickStepContract.getSystemUiStateString( mKeyguardSysuiFlags)); pw.println(prefix + "\tmBouncerShowing=" + mBouncerShowing); - pw.println(prefix + "\tmIsScreenOff=" + mIsScreenOff); } } diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java index 7d5a400f13..93a0c11316 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java @@ -18,7 +18,10 @@ package com.android.launcher3.taskbar; import static com.android.launcher3.taskbar.TaskbarStashController.FLAG_IN_APP; import static com.android.launcher3.taskbar.TaskbarStashController.FLAG_IN_STASHED_LAUNCHER_STATE; import static com.android.launcher3.taskbar.TaskbarViewController.ALPHA_INDEX_HOME; +import static com.android.launcher3.util.FlagDebugUtils.appendFlag; +import static com.android.launcher3.util.FlagDebugUtils.formatFlagChange; import static com.android.systemui.animation.Interpolators.EMPHASIZED; +import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_SCREEN_ON; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; @@ -53,16 +56,43 @@ import java.util.StringJoiner; * Track LauncherState, RecentsAnimation, resumed state for task bar in one place here and animate * the task bar accordingly. */ - public class TaskbarLauncherStateController { +public class TaskbarLauncherStateController { private static final String TAG = TaskbarLauncherStateController.class.getSimpleName(); private static final boolean DEBUG = false; + /** Launcher activity is resumed and focused. */ public static final int FLAG_RESUMED = 1 << 0; - public static final int FLAG_RECENTS_ANIMATION_RUNNING = 1 << 1; - public static final int FLAG_TRANSITION_STATE_RUNNING = 1 << 2; - private static final int FLAGS_LAUNCHER = FLAG_RESUMED | FLAG_RECENTS_ANIMATION_RUNNING; + /** + * A external transition / animation is running that will result in FLAG_RESUMED being set. + **/ + public static final int FLAG_TRANSITION_TO_RESUMED = 1 << 1; + + /** + * Set while the launcher state machine is performing a state transition, see {@link + * StateManager.StateListener}. + */ + public static final int FLAG_LAUNCHER_IN_STATE_TRANSITION = 1 << 2; + + /** + * Whether the screen is currently on, or is transitioning to be on. + * + * This is cleared as soon as the screen begins to transition off. + */ + private static final int FLAG_SCREEN_ON = 1 << 3; + + /** + * Captures whether the launcher was active at the time the FLAG_SCREEN_ON was cleared. + * Always cleared when FLAG_SCREEN_ON is set. + *

+ * FLAG_RESUMED will be cleared when the screen is off, since all apps get paused at this point. + * Thus, this flag indicates whether the launcher will be shown when the screen gets turned on + * again. + */ + private static final int FLAG_LAUNCHER_ACTIVE_AT_SCREEN_OFF = 1 << 4; + + private static final int FLAGS_LAUNCHER_ACTIVE = FLAG_RESUMED | FLAG_TRANSITION_TO_RESUMED; /** Equivalent to an int with all 1s for binary operation purposes */ private static final int FLAGS_ALL = ~0; @@ -115,12 +145,13 @@ import java.util.StringJoiner; @Override public void onStateTransitionStart(LauncherState toState) { if (toState != mLauncherState) { - // Treat FLAG_TRANSITION_STATE_RUNNING as a changed flag even if a previous - // state transition was already running, so we update the new target. - mPrevState &= ~FLAG_TRANSITION_STATE_RUNNING; + // Treat FLAG_LAUNCHER_IN_STATE_TRANSITION as a changed flag even if a + // previous state transition was already running, so we update the new + // target. + mPrevState &= ~FLAG_LAUNCHER_IN_STATE_TRANSITION; mLauncherState = toState; } - updateStateForFlag(FLAG_TRANSITION_STATE_RUNNING, true); + updateStateForFlag(FLAG_LAUNCHER_IN_STATE_TRANSITION, true); if (!mShouldDelayLauncherStateAnim) { if (toState == LauncherState.NORMAL) { applyState(QuickstepTransitionManager.TASKBAR_TO_HOME_DURATION); @@ -133,7 +164,7 @@ import java.util.StringJoiner; @Override public void onStateTransitionComplete(LauncherState finalState) { mLauncherState = finalState; - updateStateForFlag(FLAG_TRANSITION_STATE_RUNNING, false); + updateStateForFlag(FLAG_LAUNCHER_IN_STATE_TRANSITION, false); applyState(); boolean disallowLongClick = finalState == LauncherState.OVERVIEW_SPLIT_SELECT; com.android.launcher3.taskbar.Utilities.setOverviewDragState( @@ -159,9 +190,6 @@ import java.util.StringJoiner; resetIconAlignment(); mLauncher.getStateManager().addStateListener(mStateListener); - - // Initialize to the current launcher state - updateStateForFlag(FLAG_RESUMED, launcher.hasBeenResumed()); mLauncherState = launcher.getStateManager().getState(); applyState(0); @@ -182,6 +210,12 @@ import java.util.StringJoiner; mLauncher.removeOnDeviceProfileChangeListener(mOnDeviceProfileChangeListener); } + /** + * Creates a transition animation to the launcher activity. + * + * Warning: the resulting animation must be played, since this method has side effects on this + * controller's state. + */ public Animator createAnimToLauncher(@NonNull LauncherState toState, @NonNull RecentsAnimationCallbacks callbacks, long duration) { // If going to overview, stash the task bar @@ -197,7 +231,7 @@ import java.util.StringJoiner; } stashController.updateStateForFlag(FLAG_IN_APP, false); - updateStateForFlag(FLAG_RECENTS_ANIMATION_RUNNING, true); + updateStateForFlag(FLAG_TRANSITION_TO_RESUMED, true); animatorSet.play(stashController.createApplyStateAnimator(duration)); animatorSet.play(applyState(duration, false)); @@ -225,12 +259,30 @@ import java.util.StringJoiner; mShouldDelayLauncherStateAnim = shouldDelayLauncherStateAnim; } + /** Screen state changed, see QuickStepContract.SCREEN_STATE_* values. */ + public void onChangeScreenState(int screenState, boolean fromInit) { + final boolean prevScreenIsOn = hasAnyFlag(FLAG_SCREEN_ON); + final boolean currScreenIsOn = hasAnyFlag(screenState, SYSUI_STATE_SCREEN_ON); + + if (prevScreenIsOn == currScreenIsOn) return; + + updateStateForFlag(FLAG_SCREEN_ON, currScreenIsOn); + updateStateForFlag(FLAG_LAUNCHER_ACTIVE_AT_SCREEN_OFF, + prevScreenIsOn && hasAnyFlag(FLAGS_LAUNCHER_ACTIVE)); + + if (fromInit) { + applyState(0); + } else { + applyState(); + } + } + /** * Updates the proper flag to change the state of the task bar. * * Note that this only updates the flag. {@link #applyState()} needs to be called separately. * - * @param flag The flag to update. + * @param flag The flag to update. * @param enabled Whether to enable the flag */ public void updateStateForFlag(int flag, boolean enabled) { @@ -269,6 +321,19 @@ import java.util.StringJoiner; if (mPrevState == null || mPrevState != mState) { // If this is our initial state, treat all flags as changed. int changedFlags = mPrevState == null ? FLAGS_ALL : mPrevState ^ mState; + + if (DEBUG) { + String stateString; + if (mPrevState == null) { + stateString = getStateString(mState) + "(initial update)"; + } else { + stateString = formatFlagChange(mState, mPrevState, + TaskbarLauncherStateController::getStateString); + } + Log.d(TAG, "applyState: " + stateString + + ", duration: " + duration + + ", start: " + start); + } mPrevState = mState; animator = onStateChangeApplied(changedFlags, duration, start); } @@ -276,26 +341,23 @@ import java.util.StringJoiner; } private Animator onStateChangeApplied(int changedFlags, long duration, boolean start) { - final boolean goingToLauncher = isInLauncher(); + final boolean isInLauncher = isInLauncher(); final boolean isIconAlignedWithHotseat = isIconAlignedWithHotseat(); final float toAlignment = isIconAlignedWithHotseat ? 1 : 0; boolean handleOpenFloatingViews = false; if (DEBUG) { - Log.d(TAG, "onStateChangeApplied - mState: " + getStateString(mState) - + ", changedFlags: " + getStateString(changedFlags) - + ", goingToLauncher: " + goingToLauncher + Log.d(TAG, "onStateChangeApplied - isInLauncher: " + isInLauncher + ", mLauncherState: " + mLauncherState + ", toAlignment: " + toAlignment); } AnimatorSet animatorSet = new AnimatorSet(); - // Add the state animation first to ensure FLAG_IN_STASHED_LAUNCHER_STATE is set and we can - // determine whether goingToUnstashedLauncherStateChanged. - if (hasAnyFlag(changedFlags, FLAG_TRANSITION_STATE_RUNNING)) { - boolean committed = !hasAnyFlag(FLAG_TRANSITION_STATE_RUNNING); - playStateTransitionAnim(animatorSet, duration, committed); + if (hasAnyFlag(changedFlags, FLAG_LAUNCHER_IN_STATE_TRANSITION)) { + boolean launcherTransitionCompleted = !hasAnyFlag(FLAG_LAUNCHER_IN_STATE_TRANSITION); + playStateTransitionAnim(animatorSet, duration, launcherTransitionCompleted); - if (committed && mLauncherState == LauncherState.QUICK_SWITCH_FROM_HOME) { + if (launcherTransitionCompleted + && mLauncherState == LauncherState.QUICK_SWITCH_FROM_HOME) { // We're about to be paused, set immediately to ensure seamless handoff. updateStateForFlag(FLAG_RESUMED, false); applyState(0 /* duration */); @@ -306,37 +368,37 @@ import java.util.StringJoiner; } } - if (hasAnyFlag(changedFlags, FLAGS_LAUNCHER)) { + if (hasAnyFlag(changedFlags, FLAGS_LAUNCHER_ACTIVE)) { animatorSet.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - mIsAnimatingToLauncher = false; - } - @Override public void onAnimationStart(Animator animation) { - mIsAnimatingToLauncher = goingToLauncher; + mIsAnimatingToLauncher = isInLauncher; TaskbarStashController stashController = mControllers.taskbarStashController; if (DEBUG) { - Log.d(TAG, "onAnimationStart - FLAG_IN_APP: " + !goingToLauncher); + Log.d(TAG, "onAnimationStart - FLAG_IN_APP: " + !isInLauncher); } - stashController.updateStateForFlag(FLAG_IN_APP, !goingToLauncher); + stashController.updateStateForFlag(FLAG_IN_APP, !isInLauncher); stashController.applyState(duration); } + + @Override + public void onAnimationEnd(Animator animation) { + mIsAnimatingToLauncher = false; + } }); // Handle closing open popups when going home/overview handleOpenFloatingViews = true; } - if (handleOpenFloatingViews && goingToLauncher) { + + if (handleOpenFloatingViews && isInLauncher) { AbstractFloatingView.closeAllOpenViews(mControllers.taskbarActivityContext); } - float backgroundAlpha = - goingToLauncher && mLauncherState.isTaskbarAlignedWithHotseat(mLauncher) - ? 0 : 1; + float backgroundAlpha = isInLauncher && isTaskbarAlignedWithHotseat() ? 0 : 1; + // Don't animate if background has reached desired value. if (mTaskbarBackgroundAlpha.isAnimating() || mTaskbarBackgroundAlpha.value != backgroundAlpha) { @@ -347,21 +409,20 @@ import java.util.StringJoiner; + " -> " + backgroundAlpha + ": " + duration); } - boolean goingToLauncherIconNotAligned = goingToLauncher && !isIconAlignedWithHotseat; - boolean notGoingToLauncherIconNotAligned = !goingToLauncher - && !isIconAlignedWithHotseat; - boolean goingToLauncherIconIsAligned = goingToLauncher && isIconAlignedWithHotseat; + boolean isInLauncherIconNotAligned = isInLauncher && !isIconAlignedWithHotseat; + boolean notInLauncherIconNotAligned = !isInLauncher && !isIconAlignedWithHotseat; + boolean isInLauncherIconIsAligned = isInLauncher && isIconAlignedWithHotseat; float startDelay = 0; // We want to delay the background from fading in so that the icons have time to move // into the bounds of the background before it appears. - if (goingToLauncherIconNotAligned) { + if (isInLauncherIconNotAligned) { startDelay = duration * TASKBAR_BG_ALPHA_LAUNCHER_NOT_ALIGNED_DELAY_MULT; - } else if (notGoingToLauncherIconNotAligned) { + } else if (notInLauncherIconNotAligned) { startDelay = duration * TASKBAR_BG_ALPHA_NOT_LAUNCHER_NOT_ALIGNED_DELAY_MULT; } float newDuration = duration - startDelay; - if (goingToLauncherIconIsAligned) { + if (isInLauncherIconIsAligned) { // Make the background fade out faster so that it is gone by the time the // icons move outside of the bounds of the background. newDuration = duration * TASKBAR_BG_ALPHA_LAUNCHER_IS_ALIGNED_DURATION_MULT; @@ -373,7 +434,8 @@ import java.util.StringJoiner; animatorSet.play(taskbarBackgroundAlpha); } - float cornerRoundness = goingToLauncher ? 0 : 1; + float cornerRoundness = isInLauncher ? 0 : 1; + // Don't animate if corner roundness has reached desired value. if (mTaskbarCornerRoundness.isAnimating() || mTaskbarCornerRoundness.value != cornerRoundness) { @@ -412,8 +474,12 @@ import java.util.StringJoiner; return animatorSet; } - /** Returns whether we're going to a state where taskbar icons should align with launcher. */ - public boolean goingToAlignedLauncherState() { + /** + * Whether the taskbar is aligned with the hotseat in the current/target launcher state. + * + * This refers to the intended state - a transition to this state might be in progress. + */ + public boolean isTaskbarAlignedWithHotseat() { return mLauncherState.isTaskbarAlignedWithHotseat(mLauncher); } @@ -481,8 +547,13 @@ import java.util.StringJoiner; } } + /** Whether the launcher is considered active. */ private boolean isInLauncher() { - return (mState & FLAGS_LAUNCHER) != 0; + if (hasAnyFlag(FLAG_SCREEN_ON)) { + return hasAnyFlag(FLAGS_LAUNCHER_ACTIVE); + } else { + return hasAnyFlag(FLAG_LAUNCHER_ACTIVE_AT_SCREEN_OFF); + } } /** @@ -509,7 +580,8 @@ import java.util.StringJoiner; if (firstFrameVisChanged && mCanSyncViews && !Utilities.isRunningInTestHarness()) { ViewRootSync.synchronizeNextDraw(mLauncher.getHotseat(), mControllers.taskbarActivityContext.getDragLayer(), - () -> {}); + () -> { + }); } } @@ -562,7 +634,7 @@ import java.util.StringJoiner; // Update the resumed state immediately to ensure a seamless handoff boolean launcherResumed = !finishedToApp; - updateStateForFlag(FLAG_RECENTS_ANIMATION_RUNNING, false); + updateStateForFlag(FLAG_TRANSITION_TO_RESUMED, false); updateStateForFlag(FLAG_RESUMED, launcherResumed); applyState(); @@ -576,17 +648,15 @@ import java.util.StringJoiner; } private static String getStateString(int flags) { - StringJoiner str = new StringJoiner("|"); - if ((flags & FLAG_RESUMED) != 0) { - str.add("FLAG_RESUMED"); - } - if ((flags & FLAG_RECENTS_ANIMATION_RUNNING) != 0) { - str.add("FLAG_RECENTS_ANIMATION_RUNNING"); - } - if ((flags & FLAG_TRANSITION_STATE_RUNNING) != 0) { - str.add("FLAG_TRANSITION_STATE_RUNNING"); - } - return str.toString(); + StringJoiner result = new StringJoiner("|"); + appendFlag(result, flags, FLAG_RESUMED, "resumed"); + appendFlag(result, flags, FLAG_TRANSITION_TO_RESUMED, "transition_to_resumed"); + appendFlag(result, flags, FLAG_LAUNCHER_IN_STATE_TRANSITION, + "launcher_in_state_transition"); + appendFlag(result, flags, FLAG_SCREEN_ON, "screen_on"); + appendFlag(result, flags, FLAG_LAUNCHER_ACTIVE_AT_SCREEN_OFF, + "launcher_active_at_screen_off"); + return result.toString(); } protected void dumpLogs(String prefix, PrintWriter pw) { diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java index cbc1672794..43a11fecca 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java @@ -81,7 +81,7 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba public static final int FLAG_IN_APP = 1 << 0; public static final int FLAG_STASHED_IN_APP_MANUAL = 1 << 1; // long press, persisted - public static final int FLAG_STASHED_IN_SYSUI_STATE = 1 << 2; // app pinning, keyguard, etc. + public static final int FLAG_STASHED_IN_APP_SYSUI = 1 << 2; // shade open, ... public static final int FLAG_STASHED_IN_APP_SETUP = 1 << 3; // setup wizard and AllSetActivity public static final int FLAG_STASHED_IN_APP_IME = 1 << 4; // IME is visible public static final int FLAG_IN_STASHED_LAUNCHER_STATE = 1 << 5; @@ -89,13 +89,14 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba public static final int FLAG_IN_SETUP = 1 << 7; // In the Setup Wizard public static final int FLAG_STASHED_SMALL_SCREEN = 1 << 8; // phone screen gesture nav, stashed public static final int FLAG_STASHED_IN_APP_AUTO = 1 << 9; // Autohide (transient taskbar). + public static final int FLAG_STASHED_SYSUI = 1 << 10; // app pinning, keyguard, etc. // If any of these flags are enabled, isInApp should return true. private static final int FLAGS_IN_APP = FLAG_IN_APP | FLAG_IN_SETUP; // If we're in an app and any of these flags are enabled, taskbar should be stashed. private static final int FLAGS_STASHED_IN_APP = FLAG_STASHED_IN_APP_MANUAL - | FLAG_STASHED_IN_SYSUI_STATE | FLAG_STASHED_IN_APP_SETUP + | FLAG_STASHED_IN_APP_SYSUI | FLAG_STASHED_IN_APP_SETUP | FLAG_STASHED_IN_APP_IME | FLAG_STASHED_IN_TASKBAR_ALL_APPS | FLAG_STASHED_SMALL_SCREEN | FLAG_STASHED_IN_APP_AUTO; @@ -218,11 +219,11 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba boolean inApp = hasAnyFlag(flags, FLAGS_IN_APP); boolean stashedInApp = hasAnyFlag(flags, FLAGS_STASHED_IN_APP); boolean stashedLauncherState = hasAnyFlag(flags, FLAG_IN_STASHED_LAUNCHER_STATE); - boolean stashedInTaskbarAllApps = - hasAnyFlag(flags, FLAG_STASHED_IN_TASKBAR_ALL_APPS); - boolean stashedForSmallScreen = hasAnyFlag(flags, FLAG_STASHED_SMALL_SCREEN); - return (inApp && stashedInApp) || (!inApp && stashedLauncherState) - || stashedInTaskbarAllApps || stashedForSmallScreen; + boolean forceStashed = hasAnyFlag(flags, + FLAG_STASHED_SYSUI + | FLAG_STASHED_IN_TASKBAR_ALL_APPS + | FLAG_STASHED_SMALL_SCREEN); + return (inApp && stashedInApp) || (!inApp && stashedLauncherState) || forceStashed; }); public TaskbarStashController(TaskbarActivityContext activity) { @@ -898,13 +899,14 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba long animDuration = TASKBAR_STASH_DURATION; long startDelay = 0; - updateStateForFlag(FLAG_STASHED_IN_SYSUI_STATE, hasAnyFlag(systemUiStateFlags, + updateStateForFlag(FLAG_STASHED_IN_APP_SYSUI, hasAnyFlag(systemUiStateFlags, + SYSUI_STATE_QUICK_SETTINGS_EXPANDED + | SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED)); + updateStateForFlag(FLAG_STASHED_SYSUI, hasAnyFlag(systemUiStateFlags, SYSUI_STATE_SCREEN_PINNING | SYSUI_STATE_BOUNCER_SHOWING | SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING - | SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED - | SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED - | SYSUI_STATE_QUICK_SETTINGS_EXPANDED)); + | SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED)); // Only update FLAG_STASHED_IN_APP_IME when system gesture is not in progress. mIsImeShowing = hasAnyFlag(systemUiStateFlags, SYSUI_STATE_IME_SHOWING); @@ -1068,13 +1070,14 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba StringJoiner sj = new StringJoiner("|"); appendFlag(sj, flags, FLAGS_IN_APP, "FLAG_IN_APP"); appendFlag(sj, flags, FLAG_STASHED_IN_APP_MANUAL, "FLAG_STASHED_IN_APP_MANUAL"); - appendFlag(sj, flags, FLAG_STASHED_IN_SYSUI_STATE, "FLAG_STASHED_IN_SYSUI_STATE"); + appendFlag(sj, flags, FLAG_STASHED_IN_APP_SYSUI, "FLAG_STASHED_IN_APP_SYSUI"); appendFlag(sj, flags, FLAG_STASHED_IN_APP_SETUP, "FLAG_STASHED_IN_APP_SETUP"); appendFlag(sj, flags, FLAG_STASHED_IN_APP_IME, "FLAG_STASHED_IN_APP_IME"); appendFlag(sj, flags, FLAG_IN_STASHED_LAUNCHER_STATE, "FLAG_IN_STASHED_LAUNCHER_STATE"); appendFlag(sj, flags, FLAG_STASHED_IN_TASKBAR_ALL_APPS, "FLAG_STASHED_IN_TASKBAR_ALL_APPS"); appendFlag(sj, flags, FLAG_IN_SETUP, "FLAG_IN_SETUP"); appendFlag(sj, flags, FLAG_STASHED_IN_APP_AUTO, "FLAG_STASHED_IN_APP_AUTO"); + appendFlag(sj, flags, FLAG_STASHED_SYSUI, "FLAG_STASHED_SYSUI"); return sj.toString(); } diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java index 4c6d3faf1d..8046cd6a48 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java @@ -124,6 +124,12 @@ public class TaskbarUIController { } } + /** + * Screen state changed, see QuickStepContract.SCREEN_STATE_* values. + */ + public void onChangeScreenState(int screenState){ + } + /** * Returns {@code true} iff taskbar is stashed. */