Improve quick switch from home to taskbar

- Add LauncherState#isTaskbarAlignedWithHotseat() which defaults to !isTaskbarStashed(), but is always false for quick switch from home
- Replaced FLAG_TRANSITION_STATE_START_STASHED and FLAG_TRANSITION_STATE_COMMITTED_STASHED with FLAG_STATE_TRANSITION_RUNNING and a reference to mLauncherState. STATE_START is equivalent to TRANSITION_RUNNING changing to true, and STATE_COMMITTED is equivalent to TRANSITION_RUNNING changing to false. Then can get details from the state such as whether taskbar is stashed and icon alignment from mLauncherState

Test: quick switch from home, both with taskbar stashed in apps and not
Fixes: 194728611
Bug: 204657916
Change-Id: I6cf84ec73a4036e14cc7268667c6f62100884c27
This commit is contained in:
Tony Wickham 2021-11-24 15:43:52 -08:00
parent 9566290e13
commit 24675d36b7
7 changed files with 68 additions and 36 deletions

View File

@ -49,8 +49,7 @@ import java.util.function.Supplier;
public static final int FLAG_RESUMED = 1 << 0; public static final int FLAG_RESUMED = 1 << 0;
public static final int FLAG_RECENTS_ANIMATION_RUNNING = 1 << 1; 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_RUNNING = 1 << 2;
public static final int FLAG_TRANSITION_STATE_COMMITTED_STASHED = 1 << 3;
/** Equivalent to an int with all 1s for binary operation purposes */ /** Equivalent to an int with all 1s for binary operation purposes */
private static final int FLAGS_ALL = ~0; private static final int FLAGS_ALL = ~0;
@ -69,6 +68,7 @@ import java.util.function.Supplier;
private Integer mPrevState; private Integer mPrevState;
private int mState; private int mState;
private LauncherState mLauncherState = LauncherState.NORMAL;
private boolean mIsAnimatingToLauncherViaGesture; private boolean mIsAnimatingToLauncherViaGesture;
private boolean mIsAnimatingToLauncherViaResume; private boolean mIsAnimatingToLauncherViaResume;
@ -78,15 +78,20 @@ import java.util.function.Supplier;
@Override @Override
public void onStateTransitionStart(LauncherState toState) { public void onStateTransitionStart(LauncherState toState) {
updateStateForFlag(FLAG_TRANSITION_STATE_START_STASHED, if (toState != mLauncherState) {
toState.isTaskbarStashed()); // 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(); applyState();
} }
@Override @Override
public void onStateTransitionComplete(LauncherState finalState) { public void onStateTransitionComplete(LauncherState finalState) {
updateStateForFlag(FLAG_TRANSITION_STATE_COMMITTED_STASHED, mLauncherState = finalState;
finalState.isTaskbarStashed()); updateStateForFlag(FLAG_TRANSITION_STATE_RUNNING, false);
applyState(); applyState();
} }
}; };
@ -127,7 +132,7 @@ import java.util.function.Supplier;
// Update stashed flags first to ensure goingToUnstashedLauncherState() returns correctly. // Update stashed flags first to ensure goingToUnstashedLauncherState() returns correctly.
TaskbarStashController stashController = mControllers.taskbarStashController; TaskbarStashController stashController = mControllers.taskbarStashController;
stashController.updateStateForFlag(FLAG_IN_STASHED_LAUNCHER_STATE, stashController.updateStateForFlag(FLAG_IN_STASHED_LAUNCHER_STATE,
toState.isTaskbarStashed()); toState.isTaskbarStashed(mLauncher));
stashController.updateStateForFlag(FLAG_IN_APP, false); stashController.updateStateForFlag(FLAG_IN_APP, false);
updateStateForFlag(FLAG_RECENTS_ANIMATION_RUNNING, true); updateStateForFlag(FLAG_RECENTS_ANIMATION_RUNNING, true);
@ -189,8 +194,8 @@ import java.util.function.Supplier;
if (mPrevState == null || mPrevState != mState) { if (mPrevState == null || mPrevState != mState) {
// If this is our initial state, treat all flags as changed. // If this is our initial state, treat all flags as changed.
int changedFlags = mPrevState == null ? FLAGS_ALL : mPrevState ^ mState; int changedFlags = mPrevState == null ? FLAGS_ALL : mPrevState ^ mState;
animator = onStateChangeApplied(changedFlags, duration, start);
mPrevState = mState; mPrevState = mState;
animator = onStateChangeApplied(changedFlags, duration, start);
} }
return animator; return animator;
} }
@ -250,14 +255,15 @@ import java.util.function.Supplier;
.setDuration(duration)); .setDuration(duration));
} }
if (hasAnyFlag(changedFlags, FLAG_TRANSITION_STATE_START_STASHED)) { if (hasAnyFlag(changedFlags, FLAG_TRANSITION_STATE_RUNNING)) {
playStateTransitionAnim(isTransitionStateStartStashed(), animatorSet, duration, boolean committed = !hasAnyFlag(FLAG_TRANSITION_STATE_RUNNING);
false /* committed */); playStateTransitionAnim(animatorSet, duration, committed);
}
if (hasAnyFlag(changedFlags, FLAG_TRANSITION_STATE_COMMITTED_STASHED)) { if (committed && mLauncherState == LauncherState.QUICK_SWITCH) {
playStateTransitionAnim(isTransitionStateCommittedStashed(), animatorSet, duration, // We're about to be paused, set immediately to ensure seamless handoff.
true /* committed */); updateStateForFlag(FLAG_RESUMED, false);
applyState(0 /* duration */);
}
} }
if (start) { if (start) {
@ -271,17 +277,19 @@ import java.util.function.Supplier;
return !mControllers.taskbarStashController.isInStashedLauncherState(); return !mControllers.taskbarStashController.isInStashedLauncherState();
} }
private void playStateTransitionAnim(boolean isTransitionStateStashed, private void playStateTransitionAnim(AnimatorSet animatorSet, long duration,
AnimatorSet animatorSet, long duration, boolean committed) { boolean committed) {
boolean isInStashedState = mLauncherState.isTaskbarStashed(mLauncher);
float toAlignment = mLauncherState.isTaskbarAlignedWithHotseat(mLauncher) ? 1 : 0;
TaskbarStashController controller = mControllers.taskbarStashController; TaskbarStashController controller = mControllers.taskbarStashController;
controller.updateStateForFlag(FLAG_IN_STASHED_LAUNCHER_STATE, controller.updateStateForFlag(FLAG_IN_STASHED_LAUNCHER_STATE, isInStashedState);
isTransitionStateStashed);
Animator stashAnimator = controller.applyStateWithoutStart(duration); Animator stashAnimator = controller.applyStateWithoutStart(duration);
if (stashAnimator != null) { if (stashAnimator != null) {
stashAnimator.addListener(new AnimatorListenerAdapter() { stashAnimator.addListener(new AnimatorListenerAdapter() {
@Override @Override
public void onAnimationEnd(Animator animation) { public void onAnimationEnd(Animator animation) {
if (isTransitionStateStashed && committed) { if (isInStashedState && committed) {
// Reset hotseat alpha to default // Reset hotseat alpha to default
mLauncher.getHotseat().setIconsAlpha(1); mLauncher.getHotseat().setIconsAlpha(1);
} }
@ -295,10 +303,10 @@ import java.util.function.Supplier;
} }
}); });
animatorSet.play(stashAnimator); animatorSet.play(stashAnimator);
animatorSet.play(mIconAlignmentForLauncherState.animateToValue(
getCurrentIconAlignmentRatioForLauncherState(),
isTransitionStateStashed ? 0 : 1));
} }
animatorSet.play(mIconAlignmentForLauncherState.animateToValue(toAlignment)
.setDuration(duration));
} }
private boolean isResumed() { private boolean isResumed() {
@ -309,14 +317,6 @@ import java.util.function.Supplier;
return (mState & FLAG_RECENTS_ANIMATION_RUNNING) != 0; 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() { private void onIconAlignmentRatioChangedForStateTransition() {
if (!isResumed()) { if (!isResumed()) {
return; return;

View File

@ -69,7 +69,7 @@ public class AllAppsState extends LauncherState {
} }
@Override @Override
public boolean isTaskbarStashed() { public boolean isTaskbarStashed(Launcher launcher) {
return true; return true;
} }

View File

@ -92,7 +92,7 @@ public class OverviewState extends LauncherState {
} }
@Override @Override
public boolean isTaskbarStashed() { public boolean isTaskbarStashed(Launcher launcher) {
return true; return true;
} }

View File

@ -17,6 +17,7 @@ package com.android.launcher3.uioverrides.states;
import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_BACKGROUND; import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_BACKGROUND;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Launcher; import com.android.launcher3.Launcher;
import com.android.launcher3.R; import com.android.launcher3.R;
import com.android.launcher3.util.Themes; import com.android.launcher3.util.Themes;
@ -42,6 +43,10 @@ public class QuickSwitchState extends BackgroundAppState {
@Override @Override
public int getWorkspaceScrimColor(Launcher launcher) { 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); return Themes.getAttrColor(launcher, R.attr.overviewScrimColor);
} }
@ -55,4 +60,14 @@ public class QuickSwitchState extends BackgroundAppState {
public int getVisibleElements(Launcher launcher) { public int getVisibleElements(Launcher launcher) {
return TASKBAR; return TASKBAR;
} }
@Override
public boolean isTaskbarStashed(Launcher launcher) {
return !launcher.getDeviceProfile().isTaskbarPresentInApps;
}
@Override
public boolean isTaskbarAlignedWithHotseat(Launcher launcher) {
return false;
}
} }

View File

@ -236,8 +236,10 @@ public class NoButtonQuickSwitchTouchController implements TouchController,
// - RecentsView fade (if it's empty) // - RecentsView fade (if it's empty)
PendingAnimation xAnim = new PendingAnimation((long) (mXRange * 2)); PendingAnimation xAnim = new PendingAnimation((long) (mXRange * 2));
xAnim.setFloat(mRecentsView, ADJACENT_PAGE_HORIZONTAL_OFFSET, scaleAndOffset[1], LINEAR); 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(), xAnim.setViewBackgroundColor(mLauncher.getScrimView(),
toState.getWorkspaceScrimColor(mLauncher), LINEAR); QUICK_SWITCH.getWorkspaceScrimColor(mLauncher), LINEAR);
if (mRecentsView.getTaskViewCount() == 0) { if (mRecentsView.getTaskViewCount() == 0) {
xAnim.addFloat(mRecentsView, CONTENT_ALPHA, 0f, 1f, LINEAR); xAnim.addFloat(mRecentsView, CONTENT_ALPHA, 0f, 1f, LINEAR);
} }
@ -310,6 +312,11 @@ public class NoButtonQuickSwitchTouchController implements TouchController,
} }
}); });
overviewAnim.start(); overviewAnim.start();
// Create an empty state transition so StateListeners get onStateTransitionStart().
mLauncher.getStateManager().createAnimationToNewWorkspace(
OVERVIEW, config.duration, StateAnimationConfig.SKIP_ALL_ANIMATIONS)
.dispatchOnStart();
return; return;
} }
@ -384,6 +391,7 @@ public class NoButtonQuickSwitchTouchController implements TouchController,
config.animFlags = SKIP_ALL_ANIMATIONS; config.animFlags = SKIP_ALL_ANIMATIONS;
updateNonOverviewAnim(targetState, config); updateNonOverviewAnim(targetState, config);
nonOverviewAnim = mNonOverviewAnim.getAnimationPlayer(); nonOverviewAnim = mNonOverviewAnim.getAnimationPlayer();
mNonOverviewAnim.dispatchOnStart();
new WorkspaceRevealAnim(mLauncher, false /* animateOverviewScrim */).start(); new WorkspaceRevealAnim(mLauncher, false /* animateOverviewScrim */).start();
} else { } else {

View File

@ -629,7 +629,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
* this doesn't get adjusted to reflect the new child count after the taskView is dismissed/ * this doesn't get adjusted to reflect the new child count after the taskView is dismissed/
* removed from recentsView * removed from recentsView
*/ */
private int mSplitHiddenTaskViewIndex; private int mSplitHiddenTaskViewIndex = -1;
@Nullable @Nullable
private FloatingTaskView mFirstFloatingTaskView; private FloatingTaskView mFirstFloatingTaskView;
@Nullable @Nullable
@ -3959,6 +3959,9 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
/** TODO(b/181707736) More gracefully handle exiting split selection state */ /** TODO(b/181707736) More gracefully handle exiting split selection state */
private void resetFromSplitSelectionState() { private void resetFromSplitSelectionState() {
if (mSplitHiddenTaskViewIndex == -1) {
return;
}
if (!mActivity.getDeviceProfile().overviewShowAsGrid) { if (!mActivity.getDeviceProfile().overviewShowAsGrid) {
int pageToSnapTo = mCurrentPage; int pageToSnapTo = mCurrentPage;
if (mSplitHiddenTaskViewIndex <= pageToSnapTo) { if (mSplitHiddenTaskViewIndex <= pageToSnapTo) {

View File

@ -197,10 +197,16 @@ public abstract class LauncherState implements BaseState<LauncherState> {
return (getVisibleElements(launcher) & elements) == elements; 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; 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 * Fraction shift in the vertical translation UI and related properties
* *