Track OverviewToHomeAnim with StateManager

This way we mark the the current state as NORMAL at the start of
the animation, and cancel it as part of other state transitions.
This allows us to interact with launcher (e.g. to go to all apps
or pull down the notification shade) during the animation.

Also use OverviewToHomeAnim from RecentsView#startHome() to
ensure the animation is consistent, e.g. doesn't fade out
RecentsView, scrolls to page 1, etc.

Bug: 144170434
Change-Id: I5348565b9e705d8ffba39818dde9efe82b16bb7a
Merged-In: I5348565b9e705d8ffba39818dde9efe82b16bb7a
This commit is contained in:
Tony Wickham 2020-08-10 18:33:01 -07:00
parent 03a4a0cd53
commit 9dfcc316c1
5 changed files with 40 additions and 11 deletions

View File

@ -76,6 +76,7 @@ public class OverviewToHomeAnim {
if (startState != OVERVIEW) {
Log.e(TAG, "animateFromOverviewToHome: unexpected start state " + startState);
}
AnimatorSet anim = new AnimatorSet();
boolean playStaggeredWorkspaceAnim = velocity < 0;
if (playStaggeredWorkspaceAnim) {
@ -87,7 +88,8 @@ public class OverviewToHomeAnim {
mIsHomeStaggeredAnimFinished = true;
maybeOverviewToHomeAnimComplete();
}
}).start();
});
anim.play(staggeredWorkspaceAnim.getAnimators());
} else {
mIsHomeStaggeredAnimFinished = true;
}
@ -108,16 +110,17 @@ public class OverviewToHomeAnim {
config.setInterpolator(ANIM_OVERVIEW_TRANSLATE_Y, FINAL_FRAME);
config.setInterpolator(ANIM_OVERVIEW_SCALE, FINAL_FRAME);
config.setInterpolator(ANIM_OVERVIEW_ACTIONS_FADE, INSTANT);
AnimatorSet anim = stateManager.createAtomicAnimation(
AnimatorSet stateAnim = stateManager.createAtomicAnimation(
startState, NORMAL, config);
anim.addListener(new AnimationSuccessListener() {
stateAnim.addListener(new AnimationSuccessListener() {
@Override
public void onAnimationSuccess(Animator animator) {
mIsOverviewHidden = true;
maybeOverviewToHomeAnimComplete();
}
});
stateManager.cancelAnimation();
anim.play(stateAnim);
stateManager.setCurrentAnimation(anim, NORMAL);
anim.start();
recentsView.snapToPage(DEFAULT_PAGE, duration);
}

View File

@ -51,6 +51,7 @@ import com.android.launcher3.util.TraceHelper;
import com.android.launcher3.views.ScrimView;
import com.android.quickstep.LauncherActivityInterface;
import com.android.quickstep.SysUINavigationMode;
import com.android.quickstep.util.OverviewToHomeAnim;
import com.android.quickstep.util.TransformParams;
import com.android.systemui.plugins.PluginListener;
import com.android.systemui.plugins.RecentsExtraCard;
@ -105,12 +106,14 @@ public class LauncherRecentsView extends RecentsView<BaseQuickstepLauncher>
@Override
public void startHome() {
Runnable onReachedHome = () -> mActivity.getStateManager().goToState(NORMAL, false);
OverviewToHomeAnim overviewToHomeAnim = new OverviewToHomeAnim(mActivity, onReachedHome);
if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
switchToScreenshot(null,
() -> finishRecentsAnimation(true /* toRecents */,
() -> mActivity.getStateManager().goToState(NORMAL)));
() -> overviewToHomeAnim.animateWithVelocity(0)));
} else {
mActivity.getStateManager().goToState(NORMAL);
overviewToHomeAnim.animateWithVelocity(0);
}
}

View File

@ -18,6 +18,7 @@ package com.android.launcher3.uioverrides.states;
import static com.android.launcher3.anim.Interpolators.DEACCEL_2;
import static com.android.launcher3.config.FeatureFlags.ENABLE_OVERVIEW_ACTIONS;
import static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON;
import static com.android.quickstep.SysUINavigationMode.removeShelfFromOverview;
import android.content.Context;
@ -92,7 +93,8 @@ public class AllAppsState extends LauncherState {
@Override
public float[] getOverviewScaleAndOffset(Launcher launcher) {
return new float[] {0.9f, 0};
float offset = ENABLE_OVERVIEW_ACTIONS.get() && removeShelfFromOverview(launcher) ? 1 : 0;
return new float[] {0.9f, offset};
}
@Override

View File

@ -142,6 +142,10 @@ public class PortraitStatesTouchController extends AbstractStateChangeTouchContr
Log.d(TestProtocol.OVERIEW_NOT_ALLAPPS,
"PortraitStatesTouchController.getTargetState 1");
}
if (ENABLE_OVERVIEW_ACTIONS.get() && removeShelfFromOverview(mLauncher)) {
// Don't allow swiping down to overview.
return NORMAL;
}
return TouchInteractionService.isConnected() ?
mLauncher.getStateManager().getLastState() : NORMAL;
} else if (fromState == OVERVIEW) {

View File

@ -311,7 +311,13 @@ public class StateManager<STATE_TYPE extends BaseState<STATE_TYPE>> {
handler.setStateWithAnimation(state, mConfig, builder);
}
}
builder.addListener(new AnimationSuccessListener() {
builder.addListener(createStateAnimationListener(state));
mConfig.setAnimation(builder.buildAnim(), state);
return builder;
}
private AnimatorListener createStateAnimationListener(STATE_TYPE state) {
return new AnimationSuccessListener() {
@Override
public void onAnimationStart(Animator animation) {
@ -326,9 +332,7 @@ public class StateManager<STATE_TYPE extends BaseState<STATE_TYPE>> {
}
onStateTransitionEnd(state);
}
});
mConfig.setAnimation(builder.buildAnim(), state);
return builder;
};
}
private void onStateTransitionStart(STATE_TYPE state) {
@ -395,6 +399,19 @@ public class StateManager<STATE_TYPE extends BaseState<STATE_TYPE>> {
mConfig.playbackController = controller;
}
/**
* @see #setCurrentAnimation(AnimatorSet, Animator...). Using this method tells the StateManager
* that this is a custom animation to the given state, and thus the StateManager will add an
* animation listener to call {@link #onStateTransitionStart} and {@link #onStateTransitionEnd}.
* @param anim The custom animation to the given state.
* @param toState The state we are animating towards.
*/
public void setCurrentAnimation(AnimatorSet anim, STATE_TYPE toState) {
cancelAnimation();
setCurrentAnimation(anim);
anim.addListener(createStateAnimationListener(toState));
}
/**
* Sets the animation as the current state animation, i.e., canceled when
* starting another animation and may block some launcher interactions while running.