mirror of
https://github.com/LawnchairLauncher/lawnchair.git
synced 2026-02-19 02:38:20 +00:00
Factor out explicit animation types for the stash/unstash animations.
This consolidates the logic on what animation to play into one place, and will simplify tuning the lock/unlock transitions Bug: 275319714 Test: manually (http://shortn/_Q1dTzmIpqK), unit tests Change-Id: I9ba9c9f13dbbff88d8515e567fdb3dfe5556553e
This commit is contained in:
@@ -50,6 +50,7 @@ import android.view.ViewConfiguration;
|
||||
import android.view.accessibility.AccessibilityManager;
|
||||
import android.view.animation.Interpolator;
|
||||
|
||||
import androidx.annotation.IntDef;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
@@ -68,6 +69,8 @@ import com.android.launcher3.util.MultiPropertyFactory.MultiProperty;
|
||||
import com.android.quickstep.SystemUiProxy;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.StringJoiner;
|
||||
import java.util.function.IntPredicate;
|
||||
|
||||
@@ -184,6 +187,36 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba
|
||||
// Auto stashes when user has not interacted with the Taskbar after X ms.
|
||||
private static final long NO_TOUCH_TIMEOUT_TO_STASH_MS = 5000;
|
||||
|
||||
/**
|
||||
* The default stash animation, morphing the taskbar into the navbar.
|
||||
*/
|
||||
private static final int TRANSITION_DEFAULT = 0;
|
||||
/**
|
||||
* Transitioning from launcher to app. Same as TRANSITION_DEFAULT, differs in internal
|
||||
* animation timings.
|
||||
*/
|
||||
private static final int TRANSITION_HOME_TO_APP = 1;
|
||||
/**
|
||||
* Fading the navbar in and out, where the taskbar jumpcuts in and out at the very begin/end of
|
||||
* the transition. Used to transition between the hotseat and navbar` without the stash/unstash
|
||||
* transition.
|
||||
*/
|
||||
private static final int TRANSITION_HANDLE_FADE = 2;
|
||||
/**
|
||||
* Same as TRANSITION_DEFAULT, but exclusively used during an "navbar unstash to hotseat
|
||||
* animation" bound to the progress of a swipe gesture. It differs from TRANSITION_DEFAULT
|
||||
* by not scaling the height of the taskbar background.
|
||||
*/
|
||||
private static final int TRANSITION_UNSTASH_SUW_MANUAL = 3;
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef(value = {
|
||||
TRANSITION_DEFAULT,
|
||||
TRANSITION_HOME_TO_APP,
|
||||
TRANSITION_HANDLE_FADE,
|
||||
TRANSITION_UNSTASH_SUW_MANUAL,
|
||||
})
|
||||
private @interface StashAnimation {}
|
||||
|
||||
private final TaskbarActivityContext mActivity;
|
||||
private final SharedPreferences mPrefs;
|
||||
private final int mStashedHeight;
|
||||
@@ -553,8 +586,7 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba
|
||||
createAnimToIsStashed(
|
||||
/* isStashed= */ false,
|
||||
placeholderDuration,
|
||||
/* animateBg= */ false,
|
||||
/* changedFlags=*/ 0);
|
||||
TRANSITION_UNSTASH_SUW_MANUAL);
|
||||
animation.play(mAnimator);
|
||||
}
|
||||
|
||||
@@ -562,10 +594,15 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba
|
||||
* Create a stash animation and save to {@link #mAnimator}.
|
||||
* @param isStashed whether it's a stash animation or an unstash animation
|
||||
* @param duration duration of the animation
|
||||
* @param animateBg whether the taskbar's background should be animated
|
||||
* @param animationType what transition type to play.
|
||||
*/
|
||||
private void createAnimToIsStashed(boolean isStashed, long duration, boolean animateBg,
|
||||
int changedFlags) {
|
||||
private void createAnimToIsStashed(boolean isStashed, long duration,
|
||||
@StashAnimation int animationType) {
|
||||
if (animationType == TRANSITION_UNSTASH_SUW_MANUAL && isStashed) {
|
||||
// The STASH_ANIMATION_SUW_MANUAL must only be used during an unstash animation.
|
||||
Log.e(TAG, "Illegal arguments:Using TRANSITION_UNSTASH_SUW_MANUAL to stash taskbar");
|
||||
}
|
||||
|
||||
if (mAnimator != null) {
|
||||
mAnimator.cancel();
|
||||
}
|
||||
@@ -591,23 +628,10 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba
|
||||
return;
|
||||
}
|
||||
|
||||
// If Hotseat is not the top element during animation to/from Launcher, fade in/out a
|
||||
// already stashed Taskbar.
|
||||
boolean hotseatTopElement = mControllers.uiController.isHotseatIconOnTopWhenAligned()
|
||||
|| !hasAnyFlag(changedFlags, FLAG_IN_APP);
|
||||
// If transitioning to unlocked device, do not play a stash animation.
|
||||
// Keep isUnlockTransition in sync with its counterpart in
|
||||
// TaskbarLauncherStateController#onStateChangeApplied.
|
||||
boolean isUnlockTransition = hasAnyFlag(changedFlags, FLAG_STASHED_DEVICE_LOCKED)
|
||||
&& !hasAnyFlag(FLAG_STASHED_DEVICE_LOCKED);
|
||||
boolean skipStashAnimation = !hotseatTopElement || isUnlockTransition;
|
||||
|
||||
if (isTransientTaskbar) {
|
||||
createTransientAnimToIsStashed(mAnimator, isStashed, duration, animateBg, changedFlags,
|
||||
skipStashAnimation);
|
||||
createTransientAnimToIsStashed(mAnimator, isStashed, duration, animationType);
|
||||
} else {
|
||||
createAnimToIsStashed(mAnimator, isStashed, duration, animateBg, skipStashAnimation,
|
||||
stashTranslation);
|
||||
createAnimToIsStashed(mAnimator, isStashed, duration, stashTranslation, animationType);
|
||||
}
|
||||
|
||||
mAnimator.addListener(new AnimatorListenerAdapter() {
|
||||
@@ -636,7 +660,7 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba
|
||||
}
|
||||
|
||||
private void createAnimToIsStashed(AnimatorSet as, boolean isStashed, long duration,
|
||||
boolean animateBg, boolean skipStashAnimation, float stashTranslation) {
|
||||
float stashTranslation, @StashAnimation int animationType) {
|
||||
AnimatorSet fullLengthAnimatorSet = new AnimatorSet();
|
||||
// Not exactly half and may overlap. See [first|second]HalfDurationScale below.
|
||||
AnimatorSet firstHalfAnimatorSet = new AnimatorSet();
|
||||
@@ -650,12 +674,7 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba
|
||||
secondHalfDurationScale = 0.5f;
|
||||
|
||||
fullLengthAnimatorSet.play(mIconTranslationYForStash.animateToValue(stashTranslation));
|
||||
if (animateBg) {
|
||||
fullLengthAnimatorSet.play(mTaskbarBackgroundOffset.animateToValue(1));
|
||||
} else {
|
||||
fullLengthAnimatorSet.addListener(AnimatorListeners.forEndCallback(
|
||||
() -> mTaskbarBackgroundOffset.updateValue(1)));
|
||||
}
|
||||
fullLengthAnimatorSet.play(mTaskbarBackgroundOffset.animateToValue(1));
|
||||
|
||||
firstHalfAnimatorSet.playTogether(
|
||||
mIconAlphaForStash.animateToValue(0),
|
||||
@@ -666,7 +685,7 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba
|
||||
mTaskbarStashedHandleAlpha.animateToValue(1)
|
||||
);
|
||||
|
||||
if (skipStashAnimation) {
|
||||
if (animationType == TRANSITION_HANDLE_FADE) {
|
||||
fullLengthAnimatorSet.setInterpolator(INSTANT);
|
||||
firstHalfAnimatorSet.setInterpolator(INSTANT);
|
||||
}
|
||||
@@ -677,6 +696,8 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba
|
||||
fullLengthAnimatorSet.playTogether(
|
||||
mIconScaleForStash.animateToValue(1),
|
||||
mIconTranslationYForStash.animateToValue(0));
|
||||
|
||||
final boolean animateBg = animationType != TRANSITION_UNSTASH_SUW_MANUAL;
|
||||
if (animateBg) {
|
||||
fullLengthAnimatorSet.play(mTaskbarBackgroundOffset.animateToValue(0));
|
||||
} else {
|
||||
@@ -691,7 +712,7 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba
|
||||
mIconAlphaForStash.animateToValue(1)
|
||||
);
|
||||
|
||||
if (skipStashAnimation) {
|
||||
if (animationType == TRANSITION_HANDLE_FADE) {
|
||||
fullLengthAnimatorSet.setInterpolator(FINAL_FRAME);
|
||||
secondHalfAnimatorSet.setInterpolator(FINAL_FRAME);
|
||||
}
|
||||
@@ -714,18 +735,13 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba
|
||||
}
|
||||
|
||||
private void createTransientAnimToIsStashed(AnimatorSet as, boolean isStashed, long duration,
|
||||
boolean animateBg, int changedFlags, boolean skipStashAnimation) {
|
||||
@StashAnimation int animationType) {
|
||||
Interpolator skipInterpolator = null;
|
||||
|
||||
if (isStashed) {
|
||||
if (animateBg) {
|
||||
play(as, mTaskbarBackgroundOffset.animateToValue(1), 0, duration, EMPHASIZED);
|
||||
} else {
|
||||
as.addListener(AnimatorListeners.forEndCallback(
|
||||
() -> mTaskbarBackgroundOffset.updateValue(1)));
|
||||
}
|
||||
play(as, mTaskbarBackgroundOffset.animateToValue(1), 0, duration, EMPHASIZED);
|
||||
|
||||
long alphaStartDelay = duration == 0 ? 0 : (changedFlags == FLAG_IN_APP)
|
||||
long alphaStartDelay = duration == 0 ? 0 : animationType == TRANSITION_HOME_TO_APP
|
||||
? TASKBAR_STASH_ICON_ALPHA_HOME_TO_APP_START_DELAY
|
||||
: TASKBAR_STASH_ALPHA_START_DELAY;
|
||||
long alphaDuration = duration == 0 ? 0 : TASKBAR_STASH_ALPHA_DURATION;
|
||||
@@ -736,10 +752,11 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba
|
||||
play(as, mControllers.taskbarSpringOnStashController.createSpringToStash(), 0, duration,
|
||||
LINEAR);
|
||||
|
||||
if (skipStashAnimation) {
|
||||
if (animationType == TRANSITION_HANDLE_FADE) {
|
||||
skipInterpolator = INSTANT;
|
||||
}
|
||||
} else {
|
||||
final boolean animateBg = animationType != TRANSITION_UNSTASH_SUW_MANUAL;
|
||||
if (animateBg) {
|
||||
play(as, mTaskbarBackgroundOffset.animateToValue(0), 0, duration, EMPHASIZED);
|
||||
} else {
|
||||
@@ -752,7 +769,7 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba
|
||||
play(as, mIconAlphaForStash.animateToValue(1), alphaStartDelay, alphaDuration, LINEAR);
|
||||
play(as, mTaskbarStashedHandleAlpha.animateToValue(0), 0, alphaDuration, LINEAR);
|
||||
|
||||
if (skipStashAnimation) {
|
||||
if (animationType == TRANSITION_HANDLE_FADE) {
|
||||
skipInterpolator = FINAL_FRAME;
|
||||
}
|
||||
}
|
||||
@@ -1150,7 +1167,7 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba
|
||||
private final IntPredicate mStashCondition;
|
||||
|
||||
private boolean mIsStashed;
|
||||
private boolean mIsHotseatIconOnTopWhenAligned;
|
||||
private @StashAnimation int mLastStartedTransitionType = TRANSITION_DEFAULT;
|
||||
private int mPrevFlags;
|
||||
|
||||
StatePropertyHolder(IntPredicate stashCondition) {
|
||||
@@ -1182,28 +1199,64 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba
|
||||
onStateChangeApplied(changedFlags);
|
||||
mPrevFlags = flags;
|
||||
}
|
||||
boolean isHotseatIconOnTopWhenAligned =
|
||||
mControllers.uiController.isHotseatIconOnTopWhenAligned();
|
||||
// If an animation has started and mIsHotseatIconOnTopWhenAligned is changed, we need
|
||||
// to restart the animation with new parameters.
|
||||
if (mIsStashed != isStashed
|
||||
|| (mIsHotseatIconOnTopWhenAligned != isHotseatIconOnTopWhenAligned
|
||||
&& mAnimator != null && mAnimator.isStarted())) {
|
||||
|
||||
@StashAnimation int animationType = computeTransitionType(changedFlags);
|
||||
|
||||
// Allow re-starting animation if upgrading from default animation type, otherwise
|
||||
// stick with the already started transition.
|
||||
boolean transitionTypeChanged = mAnimator != null && mAnimator.isStarted()
|
||||
&& mLastStartedTransitionType == TRANSITION_DEFAULT
|
||||
&& animationType != TRANSITION_DEFAULT;
|
||||
|
||||
if (mIsStashed != isStashed || transitionTypeChanged) {
|
||||
if (TestProtocol.sDebugTracing) {
|
||||
Log.d(TestProtocol.TASKBAR_IN_APP_STATE, String.format(
|
||||
"setState: mIsStashed=%b, isStashed=%b, duration=%d",
|
||||
"setState: mIsStashed=%b, isStashed=%b, "
|
||||
+ "mAnimationType=%d, animationType=%d, duration=%d",
|
||||
mIsStashed,
|
||||
isStashed,
|
||||
mLastStartedTransitionType,
|
||||
animationType,
|
||||
duration));
|
||||
}
|
||||
mIsStashed = isStashed;
|
||||
mIsHotseatIconOnTopWhenAligned = isHotseatIconOnTopWhenAligned;
|
||||
mLastStartedTransitionType = animationType;
|
||||
|
||||
// This sets mAnimator.
|
||||
createAnimToIsStashed(mIsStashed, duration, /* animateBg= */ true, changedFlags);
|
||||
createAnimToIsStashed(mIsStashed, duration, animationType);
|
||||
return mAnimator;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private @StashAnimation int computeTransitionType(int changedFlags) {
|
||||
boolean hotseatHiddenDuringAppLaunch =
|
||||
!mControllers.uiController.isHotseatIconOnTopWhenAligned()
|
||||
&& hasAnyFlag(changedFlags, FLAG_IN_APP);
|
||||
if (hotseatHiddenDuringAppLaunch) {
|
||||
// When launching an app from the all-apps drawer, the hotseat is hidden behind the
|
||||
// drawer. In this case, the navbar must just fade in, without a stash transition,
|
||||
// as the taskbar stash animation would otherwise be visible above the all-apps
|
||||
// drawer once the hotseat is detached.
|
||||
return TRANSITION_HANDLE_FADE;
|
||||
}
|
||||
|
||||
boolean isUnlockTransition = hasAnyFlag(changedFlags, FLAG_STASHED_DEVICE_LOCKED)
|
||||
&& !hasAnyFlag(FLAG_STASHED_DEVICE_LOCKED);
|
||||
if (isUnlockTransition) {
|
||||
// When transitioning to unlocked device, the hotseat will already be visible on
|
||||
// the homescreen, thus do not play an un-stash animation.
|
||||
// Keep isUnlockTransition in sync with its counterpart in
|
||||
// TaskbarLauncherStateController#onStateChangeApplied.
|
||||
return TRANSITION_HANDLE_FADE;
|
||||
}
|
||||
|
||||
boolean homeToApp = hasAnyFlag(changedFlags, FLAG_IN_APP) && hasAnyFlag(FLAG_IN_APP);
|
||||
if (homeToApp) {
|
||||
return TRANSITION_HOME_TO_APP;
|
||||
}
|
||||
|
||||
return TRANSITION_DEFAULT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user