Merge changes I6cf84ec7,Iea599651,If3238286 into sc-v2-dev am: b5a051ca0b am: b05ad5dcbf
Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/apps/Launcher3/+/16407666
Change-Id: I6e97086358b20240c05ce06d3f2b600d9e139263
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
index b2c29b2..593bfd8 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
@@ -49,13 +49,15 @@
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_START_STASHED = 1 << 2;
- public static final int FLAG_TRANSITION_STATE_COMMITTED_STASHED = 1 << 3;
+ public static final int FLAG_TRANSITION_STATE_RUNNING = 1 << 2;
+
+ /** Equivalent to an int with all 1s for binary operation purposes */
+ private static final int FLAGS_ALL = ~0;
private final AnimatedFloat mIconAlignmentForResumedState =
- new AnimatedFloat(this::onIconAlignmentRatioChanged);
+ new AnimatedFloat(this::onIconAlignmentRatioChangedForAppAndHomeTransition);
private final AnimatedFloat mIconAlignmentForGestureState =
- new AnimatedFloat(this::onIconAlignmentRatioChanged);
+ new AnimatedFloat(this::onIconAlignmentRatioChangedForAppAndHomeTransition);
private final AnimatedFloat mIconAlignmentForLauncherState =
new AnimatedFloat(this::onIconAlignmentRatioChangedForStateTransition);
@@ -64,8 +66,9 @@
private MultiValueAlpha.AlphaProperty mIconAlphaForHome;
private BaseQuickstepLauncher mLauncher;
- private int mPrevState;
+ private Integer mPrevState;
private int mState;
+ private LauncherState mLauncherState = LauncherState.NORMAL;
private boolean mIsAnimatingToLauncherViaGesture;
private boolean mIsAnimatingToLauncherViaResume;
@@ -75,15 +78,20 @@
@Override
public void onStateTransitionStart(LauncherState toState) {
- updateStateForFlag(FLAG_TRANSITION_STATE_START_STASHED,
- toState.isTaskbarStashed());
+ 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;
+ mLauncherState = toState;
+ }
+ updateStateForFlag(FLAG_TRANSITION_STATE_RUNNING, true);
applyState();
}
@Override
public void onStateTransitionComplete(LauncherState finalState) {
- updateStateForFlag(FLAG_TRANSITION_STATE_COMMITTED_STASHED,
- finalState.isTaskbarStashed());
+ mLauncherState = finalState;
+ updateStateForFlag(FLAG_TRANSITION_STATE_RUNNING, false);
applyState();
}
};
@@ -100,7 +108,7 @@
(Consumer<Float>) alpha -> mLauncher.getHotseat().setIconsAlpha(alpha > 0 ? 0 : 1));
mIconAlignmentForResumedState.finishAnimation();
- onIconAlignmentRatioChanged();
+ onIconAlignmentRatioChangedForAppAndHomeTransition();
mLauncher.getStateManager().addStateListener(mStateListener);
}
@@ -121,9 +129,10 @@
// If going home, align the icons to hotseat
AnimatorSet animatorSet = new AnimatorSet();
+ // Update stashed flags first to ensure goingToUnstashedLauncherState() returns correctly.
TaskbarStashController stashController = mControllers.taskbarStashController;
stashController.updateStateForFlag(FLAG_IN_STASHED_LAUNCHER_STATE,
- toState.isTaskbarStashed());
+ toState.isTaskbarStashed(mLauncher));
stashController.updateStateForFlag(FLAG_IN_APP, false);
updateStateForFlag(FLAG_RECENTS_ANIMATION_RUNNING, true);
@@ -182,10 +191,11 @@
public Animator applyState(long duration, boolean start) {
Animator animator = null;
- if (mPrevState != mState) {
- int changedFlags = mPrevState ^ mState;
- animator = onStateChangeApplied(changedFlags, duration, start);
+ if (mPrevState == null || mPrevState != mState) {
+ // If this is our initial state, treat all flags as changed.
+ int changedFlags = mPrevState == null ? FLAGS_ALL : mPrevState ^ mState;
mPrevState = mState;
+ animator = onStateChangeApplied(changedFlags, duration, start);
}
return animator;
}
@@ -195,7 +205,8 @@
if (hasAnyFlag(changedFlags, FLAG_RESUMED)) {
boolean isResumed = isResumed();
ObjectAnimator anim = mIconAlignmentForResumedState
- .animateToValue(isResumed ? 1 : 0)
+ .animateToValue(isResumed && goingToUnstashedLauncherState()
+ ? 1 : 0)
.setDuration(duration);
anim.addListener(new AnimatorListenerAdapter() {
@@ -219,7 +230,8 @@
if (hasAnyFlag(changedFlags, FLAG_RECENTS_ANIMATION_RUNNING)) {
boolean isRecentsAnimationRunning = isRecentsAnimationRunning();
Animator animator = mIconAlignmentForGestureState
- .animateToValue(isRecentsAnimationRunning ? 1 : 0);
+ .animateToValue(isRecentsAnimationRunning && goingToUnstashedLauncherState()
+ ? 1 : 0);
if (isRecentsAnimationRunning) {
animator.setDuration(duration);
}
@@ -237,14 +249,21 @@
animatorSet.play(animator);
}
- if (hasAnyFlag(changedFlags, FLAG_TRANSITION_STATE_START_STASHED)) {
- playStateTransitionAnim(isTransitionStateStartStashed(), animatorSet, duration,
- false /* committed */);
+ if (hasAnyFlag(changedFlags, FLAG_RESUMED | FLAG_RECENTS_ANIMATION_RUNNING)) {
+ boolean goingToLauncher = hasAnyFlag(FLAG_RESUMED | FLAG_RECENTS_ANIMATION_RUNNING);
+ animatorSet.play(mTaskbarBackgroundAlpha.animateToValue(goingToLauncher ? 0 : 1)
+ .setDuration(duration));
}
- if (hasAnyFlag(changedFlags, FLAG_TRANSITION_STATE_COMMITTED_STASHED)) {
- playStateTransitionAnim(isTransitionStateCommittedStashed(), animatorSet, duration,
- true /* committed */);
+ if (hasAnyFlag(changedFlags, FLAG_TRANSITION_STATE_RUNNING)) {
+ boolean committed = !hasAnyFlag(FLAG_TRANSITION_STATE_RUNNING);
+ playStateTransitionAnim(animatorSet, duration, committed);
+
+ if (committed && mLauncherState == LauncherState.QUICK_SWITCH) {
+ // We're about to be paused, set immediately to ensure seamless handoff.
+ updateStateForFlag(FLAG_RESUMED, false);
+ applyState(0 /* duration */);
+ }
}
if (start) {
@@ -253,17 +272,24 @@
return animatorSet;
}
- private void playStateTransitionAnim(boolean isTransitionStateStashed,
- AnimatorSet animatorSet, long duration, boolean committed) {
+ /** Returns whether we're going to a state where taskbar icons should align with launcher. */
+ private boolean goingToUnstashedLauncherState() {
+ return !mControllers.taskbarStashController.isInStashedLauncherState();
+ }
+
+ private void playStateTransitionAnim(AnimatorSet animatorSet, long duration,
+ boolean committed) {
+ boolean isInStashedState = mLauncherState.isTaskbarStashed(mLauncher);
+ float toAlignment = mLauncherState.isTaskbarAlignedWithHotseat(mLauncher) ? 1 : 0;
+
TaskbarStashController controller = mControllers.taskbarStashController;
- controller.updateStateForFlag(FLAG_IN_STASHED_LAUNCHER_STATE,
- isTransitionStateStashed);
+ controller.updateStateForFlag(FLAG_IN_STASHED_LAUNCHER_STATE, isInStashedState);
Animator stashAnimator = controller.applyStateWithoutStart(duration);
if (stashAnimator != null) {
stashAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
- if (isTransitionStateStashed && committed) {
+ if (isInStashedState && committed) {
// Reset hotseat alpha to default
mLauncher.getHotseat().setIconsAlpha(1);
}
@@ -271,14 +297,16 @@
@Override
public void onAnimationStart(Animator animation) {
- mIconAlphaForHome.setValue(mLauncher.getHotseat().getIconsAlpha());
+ if (mLauncher.getHotseat().getIconsAlpha() > 0) {
+ mIconAlphaForHome.setValue(mLauncher.getHotseat().getIconsAlpha());
+ }
}
});
animatorSet.play(stashAnimator);
- animatorSet.play(mIconAlignmentForLauncherState.animateToValue(
- getCurrentIconAlignmentRatioForLauncherState(),
- isTransitionStateStashed ? 0 : 1));
}
+
+ animatorSet.play(mIconAlignmentForLauncherState.animateToValue(toAlignment)
+ .setDuration(duration));
}
private boolean isResumed() {
@@ -289,20 +317,15 @@
return (mState & FLAG_RECENTS_ANIMATION_RUNNING) != 0;
}
- private boolean isTransitionStateStartStashed() {
- return (mState & FLAG_TRANSITION_STATE_START_STASHED) != 0;
- }
-
- private boolean isTransitionStateCommittedStashed() {
- return (mState & FLAG_TRANSITION_STATE_COMMITTED_STASHED) != 0;
- }
-
private void onIconAlignmentRatioChangedForStateTransition() {
+ if (!isResumed()) {
+ return;
+ }
onIconAlignmentRatioChanged(this::getCurrentIconAlignmentRatioForLauncherState);
}
- private void onIconAlignmentRatioChanged() {
- onIconAlignmentRatioChanged(this::getCurrentIconAlignmentRatio);
+ private void onIconAlignmentRatioChangedForAppAndHomeTransition() {
+ onIconAlignmentRatioChanged(this::getCurrentIconAlignmentRatioBetweenAppAndHome);
}
private void onIconAlignmentRatioChanged(Supplier<Float> alignmentSupplier) {
@@ -313,13 +336,11 @@
mControllers.taskbarViewController.setLauncherIconAlignment(
alignment, mLauncher.getDeviceProfile());
- mTaskbarBackgroundAlpha.updateValue(1 - alignment);
-
// Switch taskbar and hotseat in last frame
setTaskbarViewVisible(alignment < 1);
}
- private float getCurrentIconAlignmentRatio() {
+ private float getCurrentIconAlignmentRatioBetweenAppAndHome() {
return Math.max(mIconAlignmentForResumedState.value, mIconAlignmentForGestureState.value);
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
index 8965dc4..a3ad835 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
@@ -216,6 +216,13 @@
return hasAnyFlag(FLAGS_STASHED_IN_APP);
}
+ /**
+ * Returns whether the taskbar should be stashed in the current LauncherState.
+ */
+ public boolean isInStashedLauncherState() {
+ return hasAnyFlag(FLAG_IN_STASHED_LAUNCHER_STATE) && supportsVisualStashing();
+ }
+
private boolean hasAnyFlag(int flagMask) {
return hasAnyFlag(mState, flagMask);
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java b/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java
index c554fd0..8f89d30 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java
@@ -69,7 +69,7 @@
}
@Override
- public boolean isTaskbarStashed() {
+ public boolean isTaskbarStashed(Launcher launcher) {
return true;
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java b/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java
index a4eff87..08d0a80 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java
@@ -92,7 +92,7 @@
}
@Override
- public boolean isTaskbarStashed() {
+ public boolean isTaskbarStashed(Launcher launcher) {
return true;
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/QuickSwitchState.java b/quickstep/src/com/android/launcher3/uioverrides/states/QuickSwitchState.java
index edfb921..969abc2 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/QuickSwitchState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/QuickSwitchState.java
@@ -17,6 +17,7 @@
import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_BACKGROUND;
+import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Launcher;
import com.android.launcher3.R;
import com.android.launcher3.util.Themes;
@@ -42,6 +43,10 @@
@Override
public int getWorkspaceScrimColor(Launcher launcher) {
+ DeviceProfile dp = launcher.getDeviceProfile();
+ if (dp.isTaskbarPresentInApps) {
+ return launcher.getColor(R.color.taskbar_background);
+ }
return Themes.getAttrColor(launcher, R.attr.overviewScrimColor);
}
@@ -55,4 +60,14 @@
public int getVisibleElements(Launcher launcher) {
return NONE;
}
+
+ @Override
+ public boolean isTaskbarStashed(Launcher launcher) {
+ return !launcher.getDeviceProfile().isTaskbarPresentInApps;
+ }
+
+ @Override
+ public boolean isTaskbarAlignedWithHotseat(Launcher launcher) {
+ return false;
+ }
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java
index ff3c517..f6148a7 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java
@@ -236,8 +236,10 @@
// - RecentsView fade (if it's empty)
PendingAnimation xAnim = new PendingAnimation((long) (mXRange * 2));
xAnim.setFloat(mRecentsView, ADJACENT_PAGE_HORIZONTAL_OFFSET, scaleAndOffset[1], LINEAR);
+ // Use QuickSwitchState instead of OverviewState to determine scrim color,
+ // since we need to take potential taskbar into account.
xAnim.setViewBackgroundColor(mLauncher.getScrimView(),
- toState.getWorkspaceScrimColor(mLauncher), LINEAR);
+ QUICK_SWITCH.getWorkspaceScrimColor(mLauncher), LINEAR);
if (mRecentsView.getTaskViewCount() == 0) {
xAnim.addFloat(mRecentsView, CONTENT_ALPHA, 0f, 1f, LINEAR);
}
@@ -310,6 +312,11 @@
}
});
overviewAnim.start();
+
+ // Create an empty state transition so StateListeners get onStateTransitionStart().
+ mLauncher.getStateManager().createAnimationToNewWorkspace(
+ OVERVIEW, config.duration, StateAnimationConfig.SKIP_ALL_ANIMATIONS)
+ .dispatchOnStart();
return;
}
@@ -384,6 +391,7 @@
config.animFlags = SKIP_ALL_ANIMATIONS;
updateNonOverviewAnim(targetState, config);
nonOverviewAnim = mNonOverviewAnim.getAnimationPlayer();
+ mNonOverviewAnim.dispatchOnStart();
new WorkspaceRevealAnim(mLauncher, false /* animateOverviewScrim */).start();
} else {
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index 428cc98..ed238d8 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -630,7 +630,7 @@
* this doesn't get adjusted to reflect the new child count after the taskView is dismissed/
* removed from recentsView
*/
- private int mSplitHiddenTaskViewIndex;
+ private int mSplitHiddenTaskViewIndex = -1;
@Nullable
private FloatingTaskView mFirstFloatingTaskView;
@Nullable
@@ -3969,6 +3969,9 @@
/** TODO(b/181707736) More gracefully handle exiting split selection state */
private void resetFromSplitSelectionState() {
+ if (mSplitHiddenTaskViewIndex == -1) {
+ return;
+ }
if (!mActivity.getDeviceProfile().overviewShowAsGrid) {
int pageToSnapTo = mCurrentPage;
if (mSplitHiddenTaskViewIndex <= pageToSnapTo) {
diff --git a/src/com/android/launcher3/LauncherState.java b/src/com/android/launcher3/LauncherState.java
index 9324ea5..be2cd88 100644
--- a/src/com/android/launcher3/LauncherState.java
+++ b/src/com/android/launcher3/LauncherState.java
@@ -196,10 +196,16 @@
return (getVisibleElements(launcher) & elements) == elements;
}
- public boolean isTaskbarStashed() {
+ /** Returns whether taskbar is stashed and thus should replace hotseat with a handle */
+ public boolean isTaskbarStashed(Launcher launcher) {
return false;
}
+ /** Returns whether taskbar is aligned with the hotseat vs position inside apps */
+ public boolean isTaskbarAlignedWithHotseat(Launcher launcher) {
+ return !isTaskbarStashed(launcher);
+ }
+
/**
* Fraction shift in the vertical translation UI and related properties
*