diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsViewStateController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsViewStateController.java index a1cc60ec71..085b9b3af9 100644 --- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsViewStateController.java +++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsViewStateController.java @@ -71,7 +71,7 @@ public final class RecentsViewStateController extends builder.addOnFrameCallback(mRecentsView::loadVisibleTaskData); mRecentsView.updateEmptyMessage(); } else { - builder.getAnim().addListener( + builder.addListener( AnimationSuccessListener.forRunnable(mRecentsView::resetTaskVisuals)); } diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/AppToOverviewAnimationProvider.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/AppToOverviewAnimationProvider.java index f38ff10cc2..dc8fb9e124 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/AppToOverviewAnimationProvider.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/AppToOverviewAnimationProvider.java @@ -18,29 +18,26 @@ package com.android.quickstep; import static com.android.launcher3.LauncherState.BACKGROUND_APP; import static com.android.launcher3.LauncherState.OVERVIEW; import static com.android.launcher3.anim.Interpolators.TOUCH_RESPONSE_INTERPOLATOR; +import static com.android.launcher3.anim.Interpolators.clampToProgress; import static com.android.launcher3.statehandlers.DepthController.DEPTH; import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_CLOSING; -import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_OPENING; import android.animation.Animator; import android.animation.AnimatorSet; -import android.animation.ObjectAnimator; -import android.animation.ValueAnimator; -import android.graphics.Rect; import android.util.Log; -import android.view.View; +import android.view.animation.Interpolator; import com.android.launcher3.AbstractFloatingView; import com.android.launcher3.anim.AnimationSuccessListener; +import com.android.launcher3.anim.PendingAnimation; import com.android.launcher3.statehandlers.DepthController; import com.android.launcher3.statemanager.StatefulActivity; -import com.android.quickstep.util.AppWindowAnimationHelper; import com.android.quickstep.util.RemoteAnimationProvider; +import com.android.quickstep.util.TaskViewSimulator; import com.android.quickstep.util.TransformParams; import com.android.quickstep.views.RecentsView; import com.android.systemui.shared.system.RemoteAnimationTargetCompat; import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat; -import com.android.systemui.shared.system.TransactionCompat; /** * Provider for the atomic (for 3-button mode) remote window animation from the app to the overview. @@ -97,32 +94,25 @@ final class AppToOverviewAnimationProvider> extend @Override public AnimatorSet createWindowAnimation(RemoteAnimationTargetCompat[] appTargets, RemoteAnimationTargetCompat[] wallpaperTargets) { - if (mRecentsView != null) { - mRecentsView.setRunningTaskIconScaledDown(true); + PendingAnimation pa = new PendingAnimation(RECENTS_LAUNCH_DURATION); + if (mActivity == null) { + Log.e(TAG, "Animation created, before activity"); + return pa.buildAnim(); } - AnimatorSet anim = new AnimatorSet(); - anim.addListener(new AnimationSuccessListener() { + mRecentsView.setRunningTaskIconScaledDown(true); + pa.addListener(new AnimationSuccessListener() { @Override public void onAnimationSuccess(Animator animator) { mActivityInterface.onSwipeUpToRecentsComplete(); - if (mRecentsView != null) { - mRecentsView.animateUpRunningTaskIconScale(); - } + mRecentsView.animateUpRunningTaskIconScale(); } }); - if (mActivity == null) { - Log.e(TAG, "Animation created, before activity"); - anim.play(ValueAnimator.ofInt(0, 1).setDuration(RECENTS_LAUNCH_DURATION)); - return anim; - } DepthController depthController = mActivityInterface.getDepthController(); if (depthController != null) { - anim.play(ObjectAnimator.ofFloat(depthController, DEPTH, - BACKGROUND_APP.getDepth(mActivity), - OVERVIEW.getDepth(mActivity)) - .setDuration(RECENTS_LAUNCH_DURATION)); + pa.addFloat(depthController, DEPTH, BACKGROUND_APP.getDepth(mActivity), + OVERVIEW.getDepth(mActivity), TOUCH_RESPONSE_INTERPOLATOR); } RemoteAnimationTargets targets = new RemoteAnimationTargets(appTargets, @@ -132,53 +122,39 @@ final class AppToOverviewAnimationProvider> extend RemoteAnimationTargetCompat runningTaskTarget = targets.findTask(mTargetTaskId); if (runningTaskTarget == null) { Log.e(TAG, "No closing app"); - anim.play(ValueAnimator.ofInt(0, 1).setDuration(RECENTS_LAUNCH_DURATION)); - return anim; + return pa.buildAnim(); } - final AppWindowAnimationHelper clipHelper = new AppWindowAnimationHelper( - mRecentsView.getPagedViewOrientedState(), mActivity); - - // At this point, the activity is already started and laid-out. Get the home-bounds - // relative to the screen using the rootView of the activity. - int loc[] = new int[2]; - View rootView = mActivity.getRootView(); - rootView.getLocationOnScreen(loc); - Rect homeBounds = new Rect(loc[0], loc[1], - loc[0] + rootView.getWidth(), loc[1] + rootView.getHeight()); - clipHelper.updateSource(homeBounds, runningTaskTarget); - - Rect targetRect = new Rect(); - mActivityInterface.getSwipeUpDestinationAndLength(mActivity.getDeviceProfile(), mActivity, - targetRect); - clipHelper.updateTargetRect(targetRect); - clipHelper.prepareAnimation(mActivity.getDeviceProfile()); + TaskViewSimulator tsv = new TaskViewSimulator(mActivity, mRecentsView.getSizeStrategy()); + tsv.setDp(mActivity.getDeviceProfile()); + tsv.setPreview(runningTaskTarget); + tsv.setLayoutRotation(mRecentsView.getPagedViewOrientedState().getTouchRotation(), + mRecentsView.getPagedViewOrientedState().getDisplayRotation()); TransformParams params = new TransformParams() - .setSyncTransactionApplier(new SyncRtSurfaceTransactionApplierCompat(rootView)); - ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 1); - valueAnimator.setDuration(RECENTS_LAUNCH_DURATION); - valueAnimator.setInterpolator(TOUCH_RESPONSE_INTERPOLATOR); - valueAnimator.addUpdateListener((v) -> { - params.setProgress((float) v.getAnimatedValue()).setTargetSet(targets); - clipHelper.applyTransform(params); - }); + .setTargetSet(targets) + .setSyncTransactionApplier( + new SyncRtSurfaceTransactionApplierCompat(mActivity.getRootView())); + AnimatedFloat recentsAlpha = new AnimatedFloat(() -> { }); + params.setBaseAlphaCallback((t, a) -> recentsAlpha.value); + + Interpolator taskInterpolator; if (targets.isAnimatingHome()) { - // If we are animating home, fade in the opening targets - RemoteAnimationTargets openingSet = new RemoteAnimationTargets(appTargets, - wallpaperTargets, MODE_OPENING); - - TransactionCompat transaction = new TransactionCompat(); - valueAnimator.addUpdateListener((v) -> { - for (RemoteAnimationTargetCompat app : openingSet.apps) { - transaction.setAlpha(app.leash, (float) v.getAnimatedValue()); - } - transaction.apply(); - }); + taskInterpolator = TOUCH_RESPONSE_INTERPOLATOR; + pa.addFloat(recentsAlpha, AnimatedFloat.VALUE, 0, 1, TOUCH_RESPONSE_INTERPOLATOR); + } else { + // When animation from app to recents, the recents layer is drawn on top of the app. To + // prevent the overlap, we animate the task first and then quickly fade in the recents. + taskInterpolator = clampToProgress(TOUCH_RESPONSE_INTERPOLATOR, 0, 0.8f); + pa.addFloat(recentsAlpha, AnimatedFloat.VALUE, 0, 1, + clampToProgress(TOUCH_RESPONSE_INTERPOLATOR, 0.8f, 1)); } - anim.play(valueAnimator); - return anim; + + pa.addFloat(params, TransformParams.PROGRESS, 0, 1, taskInterpolator); + tsv.addAppToOverviewAnim(pa, taskInterpolator); + pa.addOnFrameCallback(() -> tsv.apply(params)); + return pa.buildAnim(); } /** diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java index b6ccdc55e1..614ba46503 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java @@ -15,8 +15,6 @@ */ package com.android.quickstep; -import static com.android.launcher3.LauncherState.BACKGROUND_APP; -import static com.android.launcher3.LauncherState.OVERVIEW; import static com.android.launcher3.anim.Interpolators.ACCEL_1_5; import static com.android.launcher3.anim.Interpolators.DEACCEL; import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE; @@ -25,8 +23,6 @@ import static com.android.launcher3.util.VibratorWrapper.OVERVIEW_HAPTIC; import static com.android.launcher3.views.FloatingIconView.SHAPE_PROGRESS_DURATION; import android.animation.Animator; -import android.animation.AnimatorSet; -import android.animation.ObjectAnimator; import android.annotation.TargetApi; import android.content.Context; import android.content.Intent; @@ -50,6 +46,7 @@ import com.android.launcher3.InvariantDeviceProfile; import com.android.launcher3.Utilities; import com.android.launcher3.anim.AnimationSuccessListener; import com.android.launcher3.anim.AnimatorPlaybackController; +import com.android.launcher3.anim.PendingAnimation; import com.android.launcher3.statemanager.StatefulActivity; import com.android.launcher3.testing.TestProtocol; import com.android.launcher3.touch.PagedOrientationHandler; @@ -380,18 +377,9 @@ public abstract class BaseSwipeUpHandler, Q extend mDragLengthFactorStartPullback = mDragLengthFactorMaxPullback = 1; } - AnimatorSet anim = new AnimatorSet(); - anim.setDuration(mTransitionDragLength * 2); - anim.setInterpolator(t -> t * mDragLengthFactor); - anim.play(ObjectAnimator.ofFloat(mTaskViewSimulator.recentsViewScale, - AnimatedFloat.VALUE, - mTaskViewSimulator.getFullScreenScale(), 1)); - anim.play(ObjectAnimator.ofFloat(mTaskViewSimulator.fullScreenProgress, - AnimatedFloat.VALUE, - BACKGROUND_APP.getOverviewFullscreenProgress(), - OVERVIEW.getOverviewFullscreenProgress())); - mWindowTransitionController = - AnimatorPlaybackController.wrap(anim, mTransitionDragLength * 2); + PendingAnimation pa = new PendingAnimation(mTransitionDragLength * 2); + mTaskViewSimulator.addAppToOverviewAnim(pa, t -> t * mDragLengthFactor); + mWindowTransitionController = pa.createPlaybackController(); } /** @@ -663,14 +651,11 @@ public abstract class BaseSwipeUpHandler, Q extend } @Override - public void onBuildParams(Builder builder, RemoteAnimationTargetCompat app, int targetMode, - TransformParams params) { - if (app.mode == targetMode - && app.activityType != RemoteAnimationTargetCompat.ACTIVITY_TYPE_HOME) { - builder.withMatrix(mMatrix) - .withWindowCrop(mCropRect) - .withCornerRadius(params.getCornerRadius()); - } + public void onBuildTargetParams( + Builder builder, RemoteAnimationTargetCompat app, TransformParams params) { + builder.withMatrix(mMatrix) + .withWindowCrop(mCropRect) + .withCornerRadius(params.getCornerRadius()); } @Override diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java index 2dc7f5ff5c..abe4af4705 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java @@ -18,6 +18,7 @@ package com.android.quickstep.inputconsumers; import static android.view.MotionEvent.ACTION_CANCEL; import static android.view.MotionEvent.ACTION_POINTER_DOWN; import static android.view.MotionEvent.ACTION_UP; + import static com.android.launcher3.Utilities.squaredHypot; import static com.android.launcher3.Utilities.squaredTouchSlop; import static com.android.quickstep.LauncherSwipeHandler.MIN_PROGRESS_FOR_OVERVIEW; @@ -26,21 +27,22 @@ import static com.android.quickstep.util.ActiveGestureLog.INTENT_EXTRA_LOG_TRACE import android.animation.Animator; import android.animation.AnimatorListenerAdapter; -import android.animation.ValueAnimator; +import android.animation.ObjectAnimator; import android.content.Context; import android.content.Intent; +import android.graphics.Matrix; import android.graphics.Point; import android.graphics.PointF; -import android.graphics.Rect; import android.view.MotionEvent; import android.view.VelocityTracker; import android.view.ViewConfiguration; + import com.android.launcher3.R; -import com.android.launcher3.Utilities; import com.android.launcher3.anim.Interpolators; import com.android.launcher3.testing.TestLogging; import com.android.launcher3.testing.TestProtocol; import com.android.launcher3.util.DefaultDisplay; +import com.android.quickstep.AnimatedFloat; import com.android.quickstep.GestureState; import com.android.quickstep.InputConsumer; import com.android.quickstep.MultiStateCallback; @@ -49,18 +51,19 @@ import com.android.quickstep.RecentsAnimationController; import com.android.quickstep.RecentsAnimationDeviceState; import com.android.quickstep.RecentsAnimationTargets; import com.android.quickstep.TaskAnimationManager; -import com.android.quickstep.util.AppWindowAnimationHelper; import com.android.quickstep.util.TransformParams; +import com.android.quickstep.util.TransformParams.BuilderProxy; import com.android.systemui.shared.recents.model.ThumbnailData; import com.android.systemui.shared.system.ActivityManagerWrapper; import com.android.systemui.shared.system.InputMonitorCompat; import com.android.systemui.shared.system.RemoteAnimationTargetCompat; +import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat.SurfaceParams.Builder; /** * A dummy input consumer used when the device is still locked, e.g. from secure camera. */ public class DeviceLockedInputConsumer implements InputConsumer, - RecentsAnimationCallbacks.RecentsAnimationListener { + RecentsAnimationCallbacks.RecentsAnimationListener, BuilderProxy { private static final String[] STATE_NAMES = DEBUG_STATES ? new String[2] : null; private static int getFlagForIndex(int index, String name) { @@ -83,19 +86,20 @@ public class DeviceLockedInputConsumer implements InputConsumer, private final InputMonitorCompat mInputMonitorCompat; private final PointF mTouchDown = new PointF(); - private final AppWindowAnimationHelper mAppWindowAnimationHelper; private final TransformParams mTransformParams; - private final Point mDisplaySize; private final MultiStateCallback mStateCallback; + private final Point mDisplaySize; + private final Matrix mMatrix = new Matrix(); + private final float mMaxTranslationY; + private VelocityTracker mVelocityTracker; - private float mProgress; + private final AnimatedFloat mProgress = new AnimatedFloat(this::applyTransform); private boolean mThresholdCrossed = false; private boolean mHomeLaunched = false; private RecentsAnimationController mRecentsAnimationController; - private RecentsAnimationTargets mRecentsAnimationTargets; public DeviceLockedInputConsumer(Context context, RecentsAnimationDeviceState deviceState, TaskAnimationManager taskAnimationManager, GestureState gestureState, @@ -105,9 +109,10 @@ public class DeviceLockedInputConsumer implements InputConsumer, mTaskAnimationManager = taskAnimationManager; mGestureState = gestureState; mTouchSlopSquared = squaredTouchSlop(context); - mAppWindowAnimationHelper = new AppWindowAnimationHelper(context); mTransformParams = new TransformParams(); mInputMonitorCompat = inputMonitorCompat; + mMaxTranslationY = context.getResources().getDimensionPixelSize( + R.dimen.device_locked_y_offset); // Do not use DeviceProfile as the user data might be locked mDisplaySize = DefaultDisplay.INSTANCE.get(context).getInfo().realSize; @@ -158,9 +163,7 @@ public class DeviceLockedInputConsumer implements InputConsumer, } } else { float dy = Math.max(mTouchDown.y - y, 0); - mProgress = dy / mDisplaySize.y; - mTransformParams.setProgress(mProgress); - mAppWindowAnimationHelper.applyTransform(mTransformParams); + mProgress.updateValue(dy / mDisplaySize.y); } break; } @@ -189,20 +192,13 @@ public class DeviceLockedInputConsumer implements InputConsumer, // Is fling dismissTask = velocityY < 0; } else { - dismissTask = mProgress >= (1 - MIN_PROGRESS_FOR_OVERVIEW); + dismissTask = mProgress.value >= (1 - MIN_PROGRESS_FOR_OVERVIEW); } // Animate back to fullscreen before finishing - ValueAnimator animator = ValueAnimator.ofFloat(mTransformParams.getProgress(), 0f); + ObjectAnimator animator = mProgress.animateToValue(mProgress.value, 0); animator.setDuration(100); animator.setInterpolator(Interpolators.ACCEL); - animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { - @Override - public void onAnimationUpdate(ValueAnimator valueAnimator) { - mTransformParams.setProgress((float) valueAnimator.getAnimatedValue()); - mAppWindowAnimationHelper.applyTransform(mTransformParams); - } - }); animator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { @@ -239,29 +235,15 @@ public class DeviceLockedInputConsumer implements InputConsumer, public void onRecentsAnimationStart(RecentsAnimationController controller, RecentsAnimationTargets targets) { mRecentsAnimationController = controller; - mRecentsAnimationTargets = targets; - - Rect displaySize = new Rect(0, 0, mDisplaySize.x, mDisplaySize.y); - RemoteAnimationTargetCompat targetCompat = targets.findTask( - mGestureState.getRunningTaskId()); - if (targetCompat != null) { - mAppWindowAnimationHelper.updateSource(displaySize, targetCompat); - } - - // Offset the surface slightly - displaySize.offset(0, mContext.getResources().getDimensionPixelSize( - R.dimen.device_locked_y_offset)); - mTransformParams.setTargetSet(mRecentsAnimationTargets); - mAppWindowAnimationHelper.updateTargetRect(displaySize); - mAppWindowAnimationHelper.applyTransform(mTransformParams); - + mTransformParams.setTargetSet(targets); + applyTransform(); mStateCallback.setState(STATE_TARGET_RECEIVED); } @Override public void onRecentsAnimationCanceled(ThumbnailData thumbnailData) { mRecentsAnimationController = null; - mRecentsAnimationTargets = null; + mTransformParams.setTargetSet(null); } private void endRemoteAnimation() { @@ -273,6 +255,20 @@ public class DeviceLockedInputConsumer implements InputConsumer, } } + private void applyTransform() { + mTransformParams.setProgress(mProgress.value); + if (mTransformParams.getTargetSet() != null) { + mTransformParams.applySurfaceParams(mTransformParams.createSurfaceParams(this)); + } + } + + @Override + public void onBuildTargetParams( + Builder builder, RemoteAnimationTargetCompat app, TransformParams params) { + mMatrix.setTranslate(0, mProgress.value * mMaxTranslationY); + builder.withMatrix(mMatrix); + } + @Override public void onConsumerAboutToBeSwitched() { mStateCallback.setState(STATE_HANDLER_INVALIDATED); diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/AppWindowAnimationHelper.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/AppWindowAnimationHelper.java index a7979cce96..d22755e727 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/AppWindowAnimationHelper.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/AppWindowAnimationHelper.java @@ -77,7 +77,6 @@ public class AppWindowAnimationHelper implements TransformParams.BuilderProxy { private final Matrix mTmpMatrix = new Matrix(); private final Rect mTmpRect = new Rect(); private final RectF mTmpRectF = new RectF(); - private final RectF mCurrentRectWithInsets = new RectF(); private RecentsOrientedState mOrientedState; // Corner radius of windows, in pixels private final float mWindowCornerRadius; @@ -88,9 +87,6 @@ public class AppWindowAnimationHelper implements TransformParams.BuilderProxy { // Whether or not to actually use the rounded cornders on windows private boolean mUseRoundedCornersOnWindows; - // Corner radius currently applied to transformed window. - private float mCurrentCornerRadius; - public AppWindowAnimationHelper(RecentsOrientedState orientedState, Context context) { Resources res = context.getResources(); mOrientedState = orientedState; @@ -100,10 +96,6 @@ public class AppWindowAnimationHelper implements TransformParams.BuilderProxy { mUseRoundedCornersOnWindows = mSupportsRoundedCornersOnWindows; } - public AppWindowAnimationHelper(Context context) { - this(null, context); - } - private void updateSourceStack(RemoteAnimationTargetCompat target) { mSourceInsets.set(target.contentInsets); mSourceStackBounds.set(target.screenSpaceBounds); @@ -112,15 +104,6 @@ public class AppWindowAnimationHelper implements TransformParams.BuilderProxy { mSourceStackBounds.offsetTo(target.position.x, target.position.y); } - public void updateSource(Rect homeStackBounds, RemoteAnimationTargetCompat target) { - updateSourceStack(target); - updateHomeBounds(homeStackBounds); - } - - public void updateHomeBounds(Rect homeStackBounds) { - mHomeStackBounds.set(homeStackBounds); - } - public void updateTargetRect(Rect targetRect) { mSourceRect.set(mSourceInsets.left, mSourceInsets.top, mSourceStackBounds.width() - mSourceInsets.right, @@ -205,7 +188,6 @@ public class AppWindowAnimationHelper implements TransformParams.BuilderProxy { cornerRadius = mapRange(boundToRange(params.getProgress(), 0, 1), windowCornerRadius, mTaskCornerRadius); } - mCurrentCornerRadius = cornerRadius; } builder.withMatrix(mTmpMatrix) @@ -241,11 +223,6 @@ public class AppWindowAnimationHelper implements TransformParams.BuilderProxy { mSourceStackBounds.height() - (mSourceWindowClipInsets.bottom * progress); } - public RectF getCurrentRectWithInsets() { - mTmpMatrix.mapRect(mCurrentRectWithInsets, mCurrentClipRectF); - return mCurrentRectWithInsets; - } - public void fromTaskThumbnailView(TaskThumbnailView ttv, RecentsView rv, @Nullable RemoteAnimationTargetCompat target) { BaseDraggingActivity activity = BaseDraggingActivity.fromContext(ttv.getContext()); @@ -317,8 +294,4 @@ public class AppWindowAnimationHelper implements TransformParams.BuilderProxy { return mTargetRect; } - public float getCurrentCornerRadius() { - return mCurrentCornerRadius; - } - } diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java index 32fc0de0a8..3e0daaf2ea 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java @@ -212,12 +212,13 @@ public class StaggeredWorkspaceAnim { } private void addScrimAnimationForState(Launcher launcher, LauncherState state, long duration) { - PendingAnimation builder = new PendingAnimation(duration, mAnimators); + PendingAnimation builder = new PendingAnimation(duration); launcher.getWorkspace().getStateTransitionAnimation().setScrim(builder, state); builder.setFloat( launcher.getDragLayer().getOverviewScrim(), OverviewScrim.SCRIM_PROGRESS, state.getOverviewScrimAlpha(launcher), ACCEL_DEACCEL); + mAnimators.play(builder.buildAnim()); } } diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/TaskViewSimulator.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/TaskViewSimulator.java index a3db940211..f4f7e9c957 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/TaskViewSimulator.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/TaskViewSimulator.java @@ -20,6 +20,7 @@ import static com.android.launcher3.touch.PagedOrientationHandler.MATRIX_POST_TR import static com.android.quickstep.util.RecentsOrientedState.postDisplayRotation; import static com.android.systemui.shared.system.WindowManagerWrapper.WINDOWING_MODE_FULLSCREEN; +import android.animation.TimeInterpolator; import android.content.Context; import android.graphics.Matrix; import android.graphics.PointF; @@ -29,6 +30,7 @@ import android.graphics.RectF; import com.android.launcher3.DeviceProfile; import com.android.launcher3.R; import com.android.launcher3.Utilities; +import com.android.launcher3.anim.PendingAnimation; import com.android.launcher3.touch.PagedOrientationHandler; import com.android.quickstep.AnimatedFloat; import com.android.quickstep.BaseActivityInterface; @@ -144,6 +146,14 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy { } } + /** + * Adds animation for all the components corresponding to transition from an app to overview + */ + public void addAppToOverviewAnim(PendingAnimation pa, TimeInterpolator interpolator) { + pa.addFloat(fullScreenProgress, AnimatedFloat.VALUE, 1, 0, interpolator); + pa.addFloat(recentsViewScale, AnimatedFloat.VALUE, getFullScreenScale(), 1, interpolator); + } + /** * Returns the current clipped/visible window bounds in the window coordinate space */ @@ -250,14 +260,11 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy { } @Override - public void onBuildParams(Builder builder, RemoteAnimationTargetCompat app, - int targetMode, TransformParams params) { - if (app.mode == targetMode - && app.activityType != RemoteAnimationTargetCompat.ACTIVITY_TYPE_HOME) { - builder.withMatrix(mMatrix) - .withWindowCrop(mTmpCropRect) - .withCornerRadius(getCurrentCornerRadius()); - } + public void onBuildTargetParams( + Builder builder, RemoteAnimationTargetCompat app, TransformParams params) { + builder.withMatrix(mMatrix) + .withWindowCrop(mTmpCropRect) + .withCornerRadius(getCurrentCornerRadius()); } /** diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/TransformParams.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/TransformParams.java index 83b64db024..d837e54835 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/TransformParams.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/TransformParams.java @@ -16,6 +16,7 @@ package com.android.quickstep.util; import android.graphics.RectF; +import android.util.FloatProperty; import androidx.annotation.Nullable; @@ -29,6 +30,19 @@ import com.android.systemui.shared.system.TransactionCompat; public class TransformParams { + public static FloatProperty PROGRESS = + new FloatProperty("progress") { + @Override + public void setValue(TransformParams params, float v) { + params.setProgress(v); + } + + @Override + public Float get(TransformParams params) { + return params.getProgress(); + } + }; + private float mProgress; private @Nullable RectF mCurrentRect; private float mTargetAlpha; @@ -176,10 +190,6 @@ public class TransformParams { return mTargetSet; } - public SyncRtSurfaceTransactionApplierCompat getSyncTransactionApplier() { - return mSyncTransactionApplier; - } - public void applySurfaceParams(SurfaceParams[] params) { if (mSyncTransactionApplier != null) { mSyncTransactionApplier.scheduleApply(params); @@ -199,7 +209,15 @@ public class TransformParams { public interface BuilderProxy { - void onBuildParams(SurfaceParams.Builder builder, - RemoteAnimationTargetCompat app, int targetMode, TransformParams params); + default void onBuildParams(SurfaceParams.Builder builder, + RemoteAnimationTargetCompat app, int targetMode, TransformParams params) { + if (app.mode == targetMode + && app.activityType != RemoteAnimationTargetCompat.ACTIVITY_TYPE_HOME) { + onBuildTargetParams(builder, app, params); + } + } + + default void onBuildTargetParams(SurfaceParams.Builder builder, + RemoteAnimationTargetCompat app, TransformParams params) { } } } diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java index 253e83cab4..3fc235c2f0 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java @@ -2190,6 +2190,10 @@ public abstract class RecentsView extends PagedView impl */ public void setModalStateEnabled(boolean isModalState) { } + public BaseActivityInterface getSizeStrategy() { + return mSizeStrategy; + } + /** * Used to register callbacks for when our empty message state changes. * diff --git a/quickstep/src/com/android/quickstep/RemoteAnimationTargets.java b/quickstep/src/com/android/quickstep/RemoteAnimationTargets.java index 5fa6bc79e1..f90df4563f 100644 --- a/quickstep/src/com/android/quickstep/RemoteAnimationTargets.java +++ b/quickstep/src/com/android/quickstep/RemoteAnimationTargets.java @@ -68,7 +68,7 @@ public class RemoteAnimationTargets { } public boolean isAnimatingHome() { - for (RemoteAnimationTargetCompat target : apps) { + for (RemoteAnimationTargetCompat target : unfilteredApps) { if (target.activityType == RemoteAnimationTargetCompat.ACTIVITY_TYPE_HOME) { return true; } diff --git a/src/com/android/launcher3/anim/PendingAnimation.java b/src/com/android/launcher3/anim/PendingAnimation.java index 740f7f2469..0f04104ca8 100644 --- a/src/com/android/launcher3/anim/PendingAnimation.java +++ b/src/com/android/launcher3/anim/PendingAnimation.java @@ -18,6 +18,7 @@ package com.android.launcher3.anim; import static com.android.launcher3.anim.AnimatorPlaybackController.addAnimationHoldersRecur; import android.animation.Animator; +import android.animation.Animator.AnimatorListener; import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.animation.TimeInterpolator; @@ -51,12 +52,8 @@ public class PendingAnimation implements PropertySetter { private ValueAnimator mProgressAnimator; public PendingAnimation(long duration) { - this(duration, new AnimatorSet()); - } - - public PendingAnimation(long duration, AnimatorSet targetSet) { mDuration = duration; - mAnim = targetSet; + mAnim = new AnimatorSet(); } /** @@ -129,13 +126,32 @@ public class PendingAnimation implements PropertySetter { public void addOnFrameCallback(Runnable runnable) { if (mProgressAnimator == null) { mProgressAnimator = ValueAnimator.ofFloat(0, 1).setDuration(mDuration); - add(mProgressAnimator); } mProgressAnimator.addUpdateListener(anim -> runnable.run()); } - public AnimatorSet getAnim() { + /** + * @see AnimatorSet#addListener(AnimatorListener) + */ + public void addListener(Animator.AnimatorListener listener) { + mAnim.addListener(listener); + } + + /** + * Creates and returns the underlying AnimatorSet + */ + public AnimatorSet buildAnim() { + // Add progress animation to the end, so that frame callback is called after all the other + // animation update. + if (mProgressAnimator != null) { + add(mProgressAnimator); + mProgressAnimator = null; + } + if (mAnimHolders.isEmpty()) { + // Add a dummy animation to that the duration is respected + add(ValueAnimator.ofFloat(0, 1)); + } return mAnim; } @@ -143,7 +159,7 @@ public class PendingAnimation implements PropertySetter { * Creates a controller for this animation */ public AnimatorPlaybackController createPlaybackController() { - return new AnimatorPlaybackController(mAnim, mDuration, mAnimHolders); + return new AnimatorPlaybackController(buildAnim(), mDuration, mAnimHolders); } /** diff --git a/src/com/android/launcher3/statemanager/StateManager.java b/src/com/android/launcher3/statemanager/StateManager.java index 44471660af..97dc0524f1 100644 --- a/src/com/android/launcher3/statemanager/StateManager.java +++ b/src/com/android/launcher3/statemanager/StateManager.java @@ -239,7 +239,7 @@ public class StateManager> { ? fromState.getTransitionDuration(mActivity) : state.getTransitionDuration(mActivity); prepareForAtomicAnimation(fromState, state, mConfig); - AnimatorSet animation = createAnimationToNewWorkspaceInternal(state).getAnim(); + AnimatorSet animation = createAnimationToNewWorkspaceInternal(state).buildAnim(); if (onCompleteRunnable != null) { animation.addListener(AnimationSuccessListener.forRunnable(onCompleteRunnable)); } @@ -267,7 +267,7 @@ public class StateManager> { for (StateHandler handler : mActivity.getStateManager().getStateHandlers()) { handler.setStateWithAnimation(toState, config, builder); } - return builder.getAnim(); + return builder.buildAnim(); } /** @@ -309,7 +309,7 @@ public class StateManager> { for (StateHandler handler : getStateHandlers()) { handler.setStateWithAnimation(state, mConfig, builder); } - builder.getAnim().addListener(new AnimationSuccessListener() { + builder.addListener(new AnimationSuccessListener() { @Override public void onAnimationStart(Animator animation) { @@ -325,7 +325,7 @@ public class StateManager> { onStateTransitionEnd(state); } }); - mConfig.setAnimation(builder.getAnim(), state); + mConfig.setAnimation(builder.buildAnim(), state); return builder; }