Fix some state issues with user-controlled animations

Previously, user-controlled animations weren't properly being canceled when a
non-user-controlled animation started, e.g. when hitting home. Thus, we could
end in the wrong or inconsistent state because the user-controlled animation's
end runnable was still used. Now we add a cleanup callback for when we reset
the user-controlled animation for one that isn't user-controlled.

Also fixed a couple typos.

Tests (easier with animation durations extended):
- Swipe up and hit home before reaching overview -> land on home
- Go to overview, swipe down slightly (before threshold to go to workspace)
  and let go -> return to overview without flash (recents was resetting)
- Swipe up, press home while swiping -> goes home, stops responding to drag
- Start dismissing task and hit home before it finishes (or while dragging)
  -> goes home, stops responding to drag

Bug: 78249220
Change-Id: If11d8999e3fadba38c987b25af67cd2304cd859b
This commit is contained in:
Tony
2018-04-27 12:33:24 -05:00
parent 3aa3eb51e2
commit 31fbd4c08b
9 changed files with 137 additions and 51 deletions

View File

@@ -18,10 +18,7 @@ package com.android.launcher3.touch;
import static com.android.launcher3.Utilities.SINGLE_FRAME_MS;
import static com.android.launcher3.anim.Interpolators.scrollInterpolatorForVelocity;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.util.Log;
import android.view.MotionEvent;
import com.android.launcher3.Launcher;
@@ -30,13 +27,13 @@ import com.android.launcher3.Utilities;
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction;
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
import com.android.launcher3.util.TouchController;
import com.android.launcher3.util.PendingAnimation;
import com.android.launcher3.util.TouchController;
/**
* TouchController for handling state changes
*/
public abstract class AbstractStateChangeTouchController extends AnimatorListenerAdapter
public abstract class AbstractStateChangeTouchController
implements TouchController, SwipeDetector.Listener {
private static final String TAG = "ASCTouchController";
@@ -146,8 +143,10 @@ public abstract class AbstractStateChangeTouchController extends AnimatorListene
mToState = newToState;
mStartProgress = 0;
if (mCurrentAnimation != null) {
mCurrentAnimation.setOnCancelRunnable(null);
}
mProgressMultiplier = initCurrentAnimation();
mCurrentAnimation.getTarget().addListener(this);
mCurrentAnimation.dispatchOnStart();
return true;
}
@@ -203,7 +202,6 @@ public abstract class AbstractStateChangeTouchController extends AnimatorListene
targetState = (progress > SUCCESS_TRANSITION_PROGRESS) ? mToState : mFromState;
}
final float endProgress;
final float startProgress;
final long duration;
@@ -220,6 +218,8 @@ public abstract class AbstractStateChangeTouchController extends AnimatorListene
endProgress - Math.max(progress, 0));
}
} else {
mCurrentAnimation.setOnCancelRunnable(null);
mCurrentAnimation.dispatchOnCancel();
endProgress = 0;
if (progress <= 0) {
duration = 0;
@@ -236,6 +236,7 @@ public abstract class AbstractStateChangeTouchController extends AnimatorListene
ValueAnimator anim = mCurrentAnimation.getAnimationPlayer();
anim.setFloatValues(startProgress, endProgress);
updateSwipeCompleteAnimation(anim, duration, targetState, velocity, fling);
mCurrentAnimation.dispatchOnStart();
anim.start();
}
@@ -275,13 +276,6 @@ public abstract class AbstractStateChangeTouchController extends AnimatorListene
protected void clearState() {
mCurrentAnimation = null;
mDetector.finishedScrolling();
}
@Override
public void onAnimationCancel(Animator animation) {
if (mCurrentAnimation != null && animation == mCurrentAnimation.getTarget()) {
Log.e(TAG, "Who dare cancel the animation when I am in control", new Exception());
clearState();
}
mDetector.setDetectableScrollConditions(0, false);
}
}