Merge changes from topic "am-c2841e6a-5061-492f-abbf-dfb8b89ccc04" into ub-launcher3-master
* changes:
[automerger] Fix some state issues with user-controlled animations am: 31fbd4c08b
Fix some state issues with user-controlled animations
diff --git a/quickstep/src/com/android/launcher3/uioverrides/PortraitStatesTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/PortraitStatesTouchController.java
index 2e95c04..2a603d7 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/PortraitStatesTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/PortraitStatesTouchController.java
@@ -187,10 +187,7 @@
builder = new AnimatorSetBuilder();
}
- if (mPendingAnimation != null) {
- mPendingAnimation.finish(false, Touch.SWIPE);
- mPendingAnimation = null;
- }
+ cancelPendingAnim();
RecentsView recentsView = mLauncher.getOverviewPanel();
TaskView taskView = (TaskView) recentsView.getChildAt(recentsView.getNextPage());
@@ -199,10 +196,16 @@
mPendingAnimation = recentsView.createTaskLauncherAnimation(taskView, maxAccuracy);
mPendingAnimation.anim.setInterpolator(Interpolators.ZOOM_IN);
- mCurrentAnimation = AnimatorPlaybackController.wrap(mPendingAnimation.anim, maxAccuracy);
+ Runnable onCancelRunnable = () -> {
+ cancelPendingAnim();
+ clearState();
+ };
+ mCurrentAnimation = AnimatorPlaybackController.wrap(mPendingAnimation.anim, maxAccuracy,
+ onCancelRunnable);
+ mLauncher.getStateManager().setCurrentUserControlledAnimation(mCurrentAnimation);
} else {
mCurrentAnimation = mLauncher.getStateManager()
- .createAnimationToNewWorkspace(mToState, builder, maxAccuracy);
+ .createAnimationToNewWorkspace(mToState, builder, maxAccuracy, this::clearState);
}
if (totalShift == 0) {
@@ -212,6 +215,13 @@
return 1 / totalShift;
}
+ private void cancelPendingAnim() {
+ if (mPendingAnimation != null) {
+ mPendingAnimation.finish(false, Touch.SWIPE);
+ mPendingAnimation = null;
+ }
+ }
+
@Override
protected void updateSwipeCompleteAnimation(ValueAnimator animator, long expectedDuration,
LauncherState targetState, float velocity, boolean isFling) {
diff --git a/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java b/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java
index 49d4931..2579bc2 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java
@@ -63,7 +63,7 @@
@Override
public void setStateWithAnimation(final LauncherState toState,
AnimatorSetBuilder builder, AnimationConfig config) {
- PropertySetter setter = config.getProperSetter(builder);
+ PropertySetter setter = config.getPropertySetter(builder);
float[] scaleTranslationYFactor = toState.getOverviewScaleAndTranslationYFactor(mLauncher);
setter.setFloat(mRecentsView, ADJACENT_SCALE, scaleTranslationYFactor[0],
builder.getInterpolator(ANIM_OVERVIEW_TRANSLATION, LINEAR));
diff --git a/quickstep/src/com/android/launcher3/uioverrides/TaskViewTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/TaskViewTouchController.java
index 63a7984..dc3f79c 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/TaskViewTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/TaskViewTouchController.java
@@ -87,12 +87,14 @@
protected abstract boolean isRecentsInteractive();
+ protected void onUserControlledAnimationCreated(AnimatorPlaybackController animController) {
+ }
+
@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());
- mDetector.finishedScrolling();
- mCurrentAnimation = null;
+ clearState();
}
}
@@ -194,8 +196,12 @@
mEndDisplacement = dl.getHeight() - mTempCords[1];
}
+ if (mCurrentAnimation != null) {
+ mCurrentAnimation.setOnCancelRunnable(null);
+ }
mCurrentAnimation = AnimatorPlaybackController
- .wrap(mPendingAnimation.anim, maxDuration);
+ .wrap(mPendingAnimation.anim, maxDuration, this::clearState);
+ onUserControlledAnimationCreated(mCurrentAnimation);
mCurrentAnimation.getTarget().addListener(this);
mCurrentAnimation.dispatchOnStart();
mProgressMultiplier = 1 / mEndDisplacement;
@@ -271,8 +277,17 @@
mPendingAnimation.finish(wasSuccess, logAction);
mPendingAnimation = null;
}
+ clearState();
+ }
+
+ private void clearState() {
mDetector.finishedScrolling();
+ mDetector.setDetectableScrollConditions(0, false);
mTaskBeingDragged = null;
mCurrentAnimation = null;
+ if (mPendingAnimation != null) {
+ mPendingAnimation.finish(false, Touch.SWIPE);
+ mPendingAnimation = null;
+ }
}
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java b/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java
index 01e2bf3..cb83a0d 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java
@@ -29,6 +29,7 @@
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
import com.android.launcher3.LauncherStateManager.StateHandler;
+import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.util.TouchController;
import com.android.quickstep.OverviewInteractionState;
import com.android.quickstep.RecentsModel;
@@ -44,19 +45,19 @@
return new TouchController[] {
launcher.getDragController(),
new OverviewToAllAppsTouchController(launcher),
- new LauncherTaskViewcontroller(launcher)};
+ new LauncherTaskViewController(launcher)};
}
if (launcher.getDeviceProfile().isVerticalBarLayout()) {
return new TouchController[] {
launcher.getDragController(),
new OverviewToAllAppsTouchController(launcher),
new LandscapeEdgeSwipeController(launcher),
- new LauncherTaskViewcontroller(launcher)};
+ new LauncherTaskViewController(launcher)};
} else {
return new TouchController[] {
launcher.getDragController(),
new PortraitStatesTouchController(launcher),
- new LauncherTaskViewcontroller(launcher)};
+ new LauncherTaskViewController(launcher)};
}
}
@@ -114,9 +115,9 @@
}
}
- private static class LauncherTaskViewcontroller extends TaskViewTouchController<Launcher> {
+ private static class LauncherTaskViewController extends TaskViewTouchController<Launcher> {
- public LauncherTaskViewcontroller(Launcher activity) {
+ public LauncherTaskViewController(Launcher activity) {
super(activity);
}
@@ -124,5 +125,10 @@
protected boolean isRecentsInteractive() {
return mActivity.isInState(OVERVIEW);
}
+
+ @Override
+ protected void onUserControlledAnimationCreated(AnimatorPlaybackController animController) {
+ mActivity.getStateManager().setCurrentUserControlledAnimation(animController);
+ }
}
}
diff --git a/src/com/android/launcher3/LauncherStateManager.java b/src/com/android/launcher3/LauncherStateManager.java
index d196c37..7f25301 100644
--- a/src/com/android/launcher3/LauncherStateManager.java
+++ b/src/com/android/launcher3/LauncherStateManager.java
@@ -238,16 +238,18 @@
*/
public AnimatorPlaybackController createAnimationToNewWorkspace(
LauncherState state, long duration) {
- return createAnimationToNewWorkspace(state, new AnimatorSetBuilder(), duration);
+ return createAnimationToNewWorkspace(state, new AnimatorSetBuilder(), duration, null);
}
- public AnimatorPlaybackController createAnimationToNewWorkspace(
- LauncherState state, AnimatorSetBuilder builder, long duration) {
+ public AnimatorPlaybackController createAnimationToNewWorkspace(LauncherState state,
+ AnimatorSetBuilder builder, long duration, Runnable onCancelRunnable) {
mConfig.reset();
mConfig.userControlled = true;
mConfig.duration = duration;
- return AnimatorPlaybackController.wrap(
- createAnimationToNewWorkspaceInternal(state, builder, null), duration);
+ mConfig.playbackController = AnimatorPlaybackController.wrap(
+ createAnimationToNewWorkspaceInternal(state, builder, null), duration,
+ onCancelRunnable);
+ return mConfig.playbackController;
}
protected AnimatorSet createAnimationToNewWorkspaceInternal(final LauncherState state,
@@ -358,6 +360,12 @@
mConfig.reset();
}
+ public void setCurrentUserControlledAnimation(AnimatorPlaybackController controller) {
+ setCurrentAnimation(controller.getTarget());
+ mConfig.userControlled = true;
+ mConfig.playbackController = controller;
+ }
+
/**
* Sets the animation as the current state animation, i.e., canceled when
* starting another animation and may block some launcher interactions while running.
@@ -405,30 +413,39 @@
public static class AnimationConfig extends AnimatorListenerAdapter {
public long duration;
public boolean userControlled;
- private PropertySetter mProperSetter;
+ public AnimatorPlaybackController playbackController;
+ private PropertySetter mPropertySetter;
private AnimatorSet mCurrentAnimation;
private LauncherState mTargetState;
+ /**
+ * Cancels the current animation and resets config variables.
+ */
public void reset() {
duration = 0;
userControlled = false;
- mProperSetter = null;
+ mPropertySetter = null;
mTargetState = null;
- if (mCurrentAnimation != null) {
+ if (playbackController != null) {
+ playbackController.getAnimationPlayer().cancel();
+ playbackController.dispatchOnCancel();
+ } else if (mCurrentAnimation != null) {
mCurrentAnimation.setDuration(0);
mCurrentAnimation.cancel();
- mCurrentAnimation = null;
}
+
+ mCurrentAnimation = null;
+ playbackController = null;
}
- public PropertySetter getProperSetter(AnimatorSetBuilder builder) {
- if (mProperSetter == null) {
- mProperSetter = duration == 0 ? NO_ANIM_PROPERTY_SETTER
+ public PropertySetter getPropertySetter(AnimatorSetBuilder builder) {
+ if (mPropertySetter == null) {
+ mPropertySetter = duration == 0 ? NO_ANIM_PROPERTY_SETTER
: new AnimatedPropertySetter(duration, builder);
}
- return mProperSetter;
+ return mPropertySetter;
}
@Override
diff --git a/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java b/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java
index 420a7c4..77a45bf 100644
--- a/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java
+++ b/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java
@@ -53,7 +53,7 @@
public void setStateWithAnimation(LauncherState toState, AnimatorSetBuilder builder,
AnimationConfig config) {
- setWorkspaceProperty(toState, config.getProperSetter(builder));
+ setWorkspaceProperty(toState, config.getPropertySetter(builder));
}
public float getFinalScale() {
diff --git a/src/com/android/launcher3/allapps/AllAppsTransitionController.java b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
index 6a0e1cc..53d3da6 100644
--- a/src/com/android/launcher3/allapps/AllAppsTransitionController.java
+++ b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
@@ -163,7 +163,7 @@
AnimatorSetBuilder builder, AnimationConfig config) {
float targetProgress = toState.getVerticalProgress(mLauncher);
if (Float.compare(mProgress, targetProgress) == 0) {
- setAlphas(toState, config.getProperSetter(builder));
+ setAlphas(toState, config.getPropertySetter(builder));
// Fail fast
onProgressAnimationEnd();
return;
@@ -178,7 +178,7 @@
builder.play(anim);
- setAlphas(toState, config.getProperSetter(builder));
+ setAlphas(toState, config.getPropertySetter(builder));
}
private void setAlphas(LauncherState toState, PropertySetter setter) {
diff --git a/src/com/android/launcher3/anim/AnimatorPlaybackController.java b/src/com/android/launcher3/anim/AnimatorPlaybackController.java
index 1dba7d6..8e729e8 100644
--- a/src/com/android/launcher3/anim/AnimatorPlaybackController.java
+++ b/src/com/android/launcher3/anim/AnimatorPlaybackController.java
@@ -35,18 +35,23 @@
*/
public abstract class AnimatorPlaybackController implements ValueAnimator.AnimatorUpdateListener {
+ public static AnimatorPlaybackController wrap(AnimatorSet anim, long duration) {
+ return wrap(anim, duration, null);
+ }
+
/**
* Creates an animation controller for the provided animation.
* The actual duration does not matter as the animation is manually controlled. It just
* needs to be larger than the total number of pixels so that we don't have jittering due
* to float (animation-fraction * total duration) to int conversion.
*/
- public static AnimatorPlaybackController wrap(AnimatorSet anim, long duration) {
+ public static AnimatorPlaybackController wrap(AnimatorSet anim, long duration,
+ Runnable onCancelRunnable) {
/**
* TODO: use {@link AnimatorSet#setCurrentPlayTime(long)} once b/68382377 is fixed.
*/
- return new AnimatorPlaybackControllerVL(anim, duration);
+ return new AnimatorPlaybackControllerVL(anim, duration, onCancelRunnable);
}
private final ValueAnimator mAnimationPlayer;
@@ -58,10 +63,13 @@
private Runnable mEndAction;
protected boolean mTargetCancelled = false;
+ protected Runnable mOnCancelRunnable;
- protected AnimatorPlaybackController(AnimatorSet anim, long duration) {
+ protected AnimatorPlaybackController(AnimatorSet anim, long duration,
+ Runnable onCancelRunnable) {
mAnim = anim;
mDuration = duration;
+ mOnCancelRunnable = onCancelRunnable;
mAnimationPlayer = ValueAnimator.ofFloat(0, 1);
mAnimationPlayer.setInterpolator(Interpolators.LINEAR);
@@ -72,6 +80,21 @@
@Override
public void onAnimationCancel(Animator animation) {
mTargetCancelled = true;
+ if (mOnCancelRunnable != null) {
+ mOnCancelRunnable.run();
+ mOnCancelRunnable = null;
+ }
+ }
+
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mTargetCancelled = false;
+ mOnCancelRunnable = null;
+ }
+
+ @Override
+ public void onAnimationStart(Animator animation) {
+ mTargetCancelled = false;
}
});
}
@@ -163,12 +186,33 @@
}
}
+ public void dispatchOnCancel() {
+ dispatchOnCancelRecursively(mAnim);
+ }
+
+ private void dispatchOnCancelRecursively(Animator animator) {
+ for (AnimatorListener l : nonNullList(animator.getListeners())) {
+ l.onAnimationCancel(animator);
+ }
+
+ if (animator instanceof AnimatorSet) {
+ for (Animator anim : nonNullList(((AnimatorSet) animator).getChildAnimations())) {
+ dispatchOnCancelRecursively(anim);
+ }
+ }
+ }
+
+ public void setOnCancelRunnable(Runnable runnable) {
+ mOnCancelRunnable = runnable;
+ }
+
public static class AnimatorPlaybackControllerVL extends AnimatorPlaybackController {
private final ValueAnimator[] mChildAnimations;
- private AnimatorPlaybackControllerVL(AnimatorSet anim, long duration) {
- super(anim, duration);
+ private AnimatorPlaybackControllerVL(AnimatorSet anim, long duration,
+ Runnable onCancelRunnable) {
+ super(anim, duration, onCancelRunnable);
// Build animation list
ArrayList<ValueAnimator> childAnims = new ArrayList<>();
diff --git a/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java b/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java
index c0ad110..d5c0788 100644
--- a/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java
+++ b/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java
@@ -18,10 +18,7 @@
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.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 @@
mToState = newToState;
mStartProgress = 0;
+ if (mCurrentAnimation != null) {
+ mCurrentAnimation.setOnCancelRunnable(null);
+ }
mProgressMultiplier = initCurrentAnimation();
- mCurrentAnimation.getTarget().addListener(this);
mCurrentAnimation.dispatchOnStart();
return true;
}
@@ -203,7 +202,6 @@
targetState = (progress > SUCCESS_TRANSITION_PROGRESS) ? mToState : mFromState;
}
-
final float endProgress;
final float startProgress;
final long duration;
@@ -220,6 +218,8 @@
endProgress - Math.max(progress, 0));
}
} else {
+ mCurrentAnimation.setOnCancelRunnable(null);
+ mCurrentAnimation.dispatchOnCancel();
endProgress = 0;
if (progress <= 0) {
duration = 0;
@@ -236,6 +236,7 @@
ValueAnimator anim = mCurrentAnimation.getAnimationPlayer();
anim.setFloatValues(startProgress, endProgress);
updateSwipeCompleteAnimation(anim, duration, targetState, velocity, fling);
+ mCurrentAnimation.dispatchOnStart();
anim.start();
}
@@ -275,13 +276,6 @@
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);
}
}