From 86a2f911019c9f9f4b7ffc4d9489657d27b5ace8 Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Thu, 7 May 2020 02:15:56 -0700 Subject: [PATCH] Using TaskViewSimulator for both Launcher and fallback recents Fixing fling to home animation in landscape and multi-window orientation Bug: 155896573 Bug: 155816922 Change-Id: I5fdff8694eced415978345b026858f5167c2a198 --- .../android/quickstep/BaseSwipeUpHandler.java | 358 ++++++++++-------- .../quickstep/FallbackActivityInterface.java | 37 -- .../quickstep/FallbackSwipeHandler.java | 31 +- .../quickstep/LauncherActivityInterface.java | 65 ---- .../quickstep/LauncherSwipeHandler.java | 130 +++---- .../util/AppWindowAnimationHelper.java | 10 - .../quickstep/util/TaskViewSimulator.java | 51 ++- .../quickstep/util/TransformParams.java | 32 -- .../quickstep/BaseActivityInterface.java | 36 -- .../quickstep/util/RecentsOrientedState.java | 19 - 10 files changed, 311 insertions(+), 458 deletions(-) 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 ea0d84036c..f76b18b920 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java @@ -15,6 +15,8 @@ */ 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; @@ -23,9 +25,13 @@ 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; +import android.graphics.Matrix; +import android.graphics.Matrix.ScaleToFit; import android.graphics.PointF; import android.graphics.Rect; import android.graphics.RectF; @@ -35,32 +41,34 @@ import android.view.MotionEvent; import android.view.View; import android.view.animation.Interpolator; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.annotation.UiThread; import com.android.launcher3.BaseDraggingActivity; import com.android.launcher3.DeviceProfile; import com.android.launcher3.InvariantDeviceProfile; -import com.android.launcher3.R; import com.android.launcher3.Utilities; import com.android.launcher3.anim.AnimationSuccessListener; import com.android.launcher3.anim.AnimatorPlaybackController; import com.android.launcher3.touch.PagedOrientationHandler; import com.android.launcher3.util.VibratorWrapper; import com.android.launcher3.views.FloatingIconView; -import com.android.quickstep.BaseActivityInterface.HomeAnimationFactory; import com.android.quickstep.RecentsAnimationCallbacks.RecentsAnimationListener; import com.android.quickstep.util.ActiveGestureLog; import com.android.quickstep.util.ActivityInitListener; -import com.android.quickstep.util.AppWindowAnimationHelper; -import com.android.quickstep.util.RecentsOrientedState; import com.android.quickstep.util.RectFSpringAnim; +import com.android.quickstep.util.TaskViewSimulator; import com.android.quickstep.util.TransformParams; +import com.android.quickstep.util.TransformParams.BuilderProxy; +import com.android.quickstep.util.WindowSizeStrategy; import com.android.quickstep.views.RecentsView; import com.android.quickstep.views.TaskView; import com.android.systemui.shared.recents.model.ThumbnailData; import com.android.systemui.shared.system.InputConsumerController; import com.android.systemui.shared.system.RemoteAnimationTargetCompat; import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat; +import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat.SurfaceParams.Builder; import java.util.ArrayList; import java.util.function.Consumer; @@ -93,7 +101,9 @@ public abstract class BaseSwipeUpHandler mActivityInterface; protected final InputConsumerController mInputConsumer; - protected AppWindowAnimationHelper mAppWindowAnimationHelper; + protected final TaskViewSimulator mTaskViewSimulator; + private AnimatorPlaybackController mWindowTransitionController; + protected final TransformParams mTransformParams = new TransformParams(); // Shift in the range of [0, 1]. @@ -113,7 +123,6 @@ public abstract class BaseSwipeUpHandler mRecentsView.setRecentsAnimationTargets(mRecentsAnimationController, mRecentsAnimationTargets)); @@ -247,36 +253,29 @@ public abstract class BaseSwipeUpHandler 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); } /** @@ -385,9 +384,6 @@ public abstract class BaseSwipeUpHandler= end) { - return 0f; - } - return Utilities.mapToRange(progress, start, end, 1, 0, ACCEL_1_5); - } - public interface Factory { BaseSwipeUpHandler newHandler(GestureState gestureState, long touchTimeMs, @@ -609,4 +530,135 @@ public abstract class BaseSwipeUpHandler= end) { + return 0f; + } + return Utilities.mapToRange(progress, start, end, 1, 0, ACCEL_1_5); + } + + protected abstract class HomeAnimationFactory { + + private FloatingIconView mIconView; + + public HomeAnimationFactory(@Nullable FloatingIconView iconView) { + mIconView = iconView; + } + + public @NonNull RectF getWindowTargetRect() { + PagedOrientationHandler orientationHandler = getOrientationHandler(); + DeviceProfile dp = mDp; + final int halfIconSize = dp.iconSizePx / 2; + float primaryDimension = orientationHandler + .getPrimaryValue(dp.availableWidthPx, dp.availableHeightPx); + float secondaryDimension = orientationHandler + .getSecondaryValue(dp.availableWidthPx, dp.availableHeightPx); + final float targetX = primaryDimension / 2f; + final float targetY = secondaryDimension - dp.hotseatBarSizePx; + // Fallback to animate to center of screen. + return new RectF(targetX - halfIconSize, targetY - halfIconSize, + targetX + halfIconSize, targetY + halfIconSize); + } + + public abstract @NonNull AnimatorPlaybackController createActivityAnimationToHome(); + + public void playAtomicAnimation(float velocity) { + // No-op + } + } + + private class SpringAnimationRunner extends AnimationSuccessListener + implements RectFSpringAnim.OnUpdateListener, BuilderProxy { + + final Rect mCropRect = new Rect(); + final Matrix mMatrix = new Matrix(); + + final RectF mWindowCurrentRect = new RectF(); + final Matrix mHomeToWindowPositionMap; + + final FloatingIconView mFIV; + final AnimatorPlaybackController mHomeAnim; + final RectF mCropRectF; + + final float mStartRadius; + final float mEndRadius; + final float mWindowAlphaThreshold; + + SpringAnimationRunner(HomeAnimationFactory factory, RectF cropRectF, + Matrix homeToWindowPositionMap) { + mHomeAnim = factory.createActivityAnimationToHome(); + mCropRectF = cropRectF; + mHomeToWindowPositionMap = homeToWindowPositionMap; + + cropRectF.roundOut(mCropRect); + mFIV = factory.mIconView; + + // End on a "round-enough" radius so that the shape reveal doesn't have to do too much + // rounding at the end of the animation. + mStartRadius = mTaskViewSimulator.getCurrentCornerRadius(); + mEndRadius = cropRectF.width() / 2f; + + // We want the window alpha to be 0 once this threshold is met, so that the + // FolderIconView can be seen morphing into the icon shape. + mWindowAlphaThreshold = mFIV != null ? 1f - SHAPE_PROGRESS_DURATION : 1f; + } + + @Override + public void onUpdate(RectF currentRect, float progress) { + mHomeAnim.setPlayFraction(progress); + mHomeToWindowPositionMap.mapRect(mWindowCurrentRect, currentRect); + + mMatrix.setRectToRect(mCropRectF, mWindowCurrentRect, ScaleToFit.FILL); + float cornerRadius = Utilities.mapRange(progress, mStartRadius, mEndRadius); + mTransformParams + .setTargetAlpha(getWindowAlpha(progress)) + .setCornerRadius(cornerRadius); + + mTransformParams.applySurfaceParams(mTransformParams.createSurfaceParams(this)); + if (mFIV != null) { + mFIV.update(currentRect, 1f, progress, + mWindowAlphaThreshold, mMatrix.mapRadius(cornerRadius), false); + } + } + + @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()); + } + } + + @Override + public void onCancel() { + if (mFIV != null) { + mFIV.fastFinish(); + } + } + + @Override + public void onAnimationStart(Animator animation) { + mHomeAnim.dispatchOnStart(); + } + + @Override + public void onAnimationSuccess(Animator animator) { + mHomeAnim.getAnimationPlayer().end(); + } + } } diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/FallbackActivityInterface.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/FallbackActivityInterface.java index 88dbbe13a5..4ce972e422 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/FallbackActivityInterface.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/FallbackActivityInterface.java @@ -21,18 +21,14 @@ import static com.android.quickstep.fallback.FallbackRecentsView.ZOOM_PROGRESS; import static com.android.quickstep.util.WindowSizeStrategy.FALLBACK_RECENTS_SIZE_STRATEGY; import static com.android.quickstep.views.RecentsView.CONTENT_ALPHA; -import android.animation.Animator; import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.content.Context; import android.graphics.Rect; -import android.graphics.RectF; -import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.android.launcher3.DeviceProfile; -import com.android.launcher3.anim.AnimationSuccessListener; import com.android.launcher3.anim.AnimatorPlaybackController; import com.android.launcher3.userevent.nano.LauncherLogProto; import com.android.quickstep.fallback.FallbackRecentsView; @@ -89,39 +85,6 @@ public final class FallbackActivityInterface implements // set to zero prior to this class becoming active. } - @NonNull - @Override - public HomeAnimationFactory prepareHomeUI() { - RecentsActivity activity = getCreatedActivity(); - RecentsView recentsView = activity.getOverviewPanel(); - - return new HomeAnimationFactory() { - @NonNull - @Override - public RectF getWindowTargetRect() { - float centerX = recentsView.getPivotX(); - float centerY = recentsView.getPivotY(); - return new RectF(centerX, centerY, centerX, centerY); - } - - @NonNull - @Override - public AnimatorPlaybackController createActivityAnimationToHome() { - Animator anim = ObjectAnimator.ofFloat(recentsView, CONTENT_ALPHA, 0); - anim.addListener(new AnimationSuccessListener() { - @Override - public void onAnimationSuccess(Animator animator) { - recentsView.startHome(); - } - }); - AnimatorSet animatorSet = new AnimatorSet(); - animatorSet.play(anim); - long accuracy = 2 * Math.max(recentsView.getWidth(), recentsView.getHeight()); - return AnimatorPlaybackController.wrap(animatorSet, accuracy); - } - }; - } - @Override public AnimationFactory prepareRecentsUI(boolean activityVisible, boolean animateActivity, Consumer callback) { diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/FallbackSwipeHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/FallbackSwipeHandler.java index d24b16a6ab..8ce6bbccfa 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/FallbackSwipeHandler.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/FallbackSwipeHandler.java @@ -24,6 +24,7 @@ import static com.android.quickstep.GestureState.GestureEndTarget.RECENTS; import static com.android.quickstep.MultiStateCallback.DEBUG_STATES; import static com.android.quickstep.RecentsActivity.EXTRA_TASK_ID; import static com.android.quickstep.RecentsActivity.EXTRA_THUMBNAIL; +import static com.android.quickstep.util.WindowSizeStrategy.FALLBACK_RECENTS_SIZE_STRATEGY; import static com.android.quickstep.views.RecentsView.UPDATE_SYSUI_FLAGS_THRESHOLD; import android.animation.Animator; @@ -32,7 +33,6 @@ import android.app.ActivityOptions; import android.content.Context; import android.content.Intent; import android.graphics.PointF; -import android.graphics.RectF; import android.os.Bundle; import android.util.ArrayMap; import android.view.MotionEvent; @@ -40,9 +40,7 @@ import android.view.MotionEvent; import com.android.launcher3.R; import com.android.launcher3.anim.AnimationSuccessListener; import com.android.launcher3.anim.AnimatorPlaybackController; -import com.android.launcher3.touch.PagedOrientationHandler; import com.android.launcher3.util.ObjectWrapper; -import com.android.quickstep.BaseActivityInterface.HomeAnimationFactory; import com.android.quickstep.GestureState.GestureEndTarget; import com.android.quickstep.fallback.FallbackRecentsView; import com.android.quickstep.util.RectFSpringAnim; @@ -108,7 +106,7 @@ public class FallbackSwipeHandler extends BaseSwipeUpHandler= MIN_PROGRESS_FOR_OVERVIEW); } - if (mRecentsAnimationTargets != null) { - applyTransformUnchecked(); - } + applyWindowTransform(); } @Override @@ -468,11 +464,7 @@ public class FallbackSwipeHandler extends BaseSwipeUpHandler callback) { diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherSwipeHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherSwipeHandler.java index e0393c7725..4386d0b97c 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherSwipeHandler.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherSwipeHandler.java @@ -17,8 +17,7 @@ package com.android.quickstep; import static com.android.launcher3.BaseActivity.INVISIBLE_BY_STATE_HANDLER; import static com.android.launcher3.BaseActivity.STATE_HANDLER_INVISIBILITY_FLAGS; -import static com.android.launcher3.LauncherState.BACKGROUND_APP; -import static com.android.launcher3.LauncherState.OVERVIEW; +import static com.android.launcher3.LauncherState.NORMAL; import static com.android.launcher3.anim.Interpolators.DEACCEL; import static com.android.launcher3.anim.Interpolators.LINEAR; import static com.android.launcher3.anim.Interpolators.OVERSHOOT_1_2; @@ -41,17 +40,16 @@ import static com.android.quickstep.views.RecentsView.UPDATE_SYSUI_FLAGS_THRESHO import android.animation.Animator; import android.animation.AnimatorSet; -import android.animation.ObjectAnimator; import android.animation.TimeInterpolator; import android.animation.ValueAnimator; import android.annotation.TargetApi; import android.content.Context; import android.content.Intent; import android.graphics.PointF; -import android.graphics.Rect; import android.graphics.RectF; import android.os.Build; import android.os.SystemClock; +import android.os.UserHandle; import android.view.View; import android.view.View.OnApplyWindowInsetsListener; import android.view.ViewTreeObserver.OnDrawListener; @@ -64,6 +62,7 @@ import androidx.annotation.UiThread; import com.android.launcher3.AbstractFloatingView; import com.android.launcher3.BaseDraggingActivity; import com.android.launcher3.DeviceProfile; +import com.android.launcher3.Launcher; import com.android.launcher3.R; import com.android.launcher3.Utilities; import com.android.launcher3.anim.AnimationSuccessListener; @@ -74,15 +73,15 @@ import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction; import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch; import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType; import com.android.launcher3.util.TraceHelper; +import com.android.launcher3.views.FloatingIconView; import com.android.quickstep.BaseActivityInterface.AnimationFactory; -import com.android.quickstep.BaseActivityInterface.HomeAnimationFactory; import com.android.quickstep.GestureState.GestureEndTarget; import com.android.quickstep.inputconsumers.OverviewInputConsumer; import com.android.quickstep.util.ActiveGestureLog; import com.android.quickstep.util.RectFSpringAnim; import com.android.quickstep.util.ShelfPeekAnim; import com.android.quickstep.util.ShelfPeekAnim.ShelfAnimState; -import com.android.quickstep.util.TaskViewSimulator; +import com.android.quickstep.util.StaggeredWorkspaceAnim; import com.android.quickstep.util.TransformParams.TargetAlphaProvider; import com.android.quickstep.views.LiveTileOverlay; import com.android.quickstep.views.RecentsView; @@ -96,8 +95,8 @@ import com.android.systemui.shared.system.RemoteAnimationTargetCompat; * Handles the navigation gestures when Launcher is the default home activity. */ @TargetApi(Build.VERSION_CODES.O) -public class LauncherSwipeHandler - extends BaseSwipeUpHandler implements OnApplyWindowInsetsListener { +public class LauncherSwipeHandler extends BaseSwipeUpHandler + implements OnApplyWindowInsetsListener { private static final String TAG = LauncherSwipeHandler.class.getSimpleName(); private static final String[] STATE_NAMES = DEBUG_STATES ? new String[16] : null; @@ -151,7 +150,6 @@ public class LauncherSwipeHandler STATE_LAUNCHER_PRESENT | STATE_LAUNCHER_DRAWN | STATE_LAUNCHER_STARTED; public static final long MAX_SWIPE_DURATION = 350; - public static final long MIN_SWIPE_DURATION = 80; public static final long MIN_OVERSHOOT_DURATION = 120; public static final float MIN_PROGRESS_FOR_OVERVIEW = 0.7f; @@ -180,9 +178,6 @@ public class LauncherSwipeHandler private AnimatorPlaybackController mLauncherTransitionController; private boolean mHasLauncherTransitionControllerStarted; - private final TaskViewSimulator mTaskViewSimulator; - private AnimatorPlaybackController mWindowTransitionController; - private AnimationFactory mAnimationFactory = (t) -> { }; private boolean mWasLauncherAlreadyVisible; @@ -203,11 +198,10 @@ public class LauncherSwipeHandler TaskAnimationManager taskAnimationManager, GestureState gestureState, long touchTimeMs, boolean continuingLastGesture, InputConsumerController inputConsumer) { - super(context, deviceState, gestureState, inputConsumer); + super(context, deviceState, gestureState, inputConsumer, LAUNCHER_ACTIVITY_SIZE_STRATEGY); mTaskAnimationManager = taskAnimationManager; mTouchTimeMs = touchTimeMs; mContinuingLastGesture = continuingLastGesture; - mTaskViewSimulator = new TaskViewSimulator(context, LAUNCHER_ACTIVITY_SIZE_STRATEGY); initAfterSubclassConstructor(); initStateCallbacks(); @@ -279,7 +273,7 @@ public class LauncherSwipeHandler @Override protected boolean onActivityInit(Boolean alreadyOnHome) { super.onActivityInit(alreadyOnHome); - final T activity = mActivityInterface.getCreatedActivity(); + final Launcher activity = mActivityInterface.getCreatedActivity(); if (mActivity == activity) { return true; } @@ -327,7 +321,7 @@ public class LauncherSwipeHandler } private void onLauncherStart() { - final T activity = mActivityInterface.getCreatedActivity(); + final Launcher activity = mActivityInterface.getCreatedActivity(); if (mActivity != activity) { return; } @@ -518,34 +512,6 @@ public class LauncherSwipeHandler mAnimationFactory.createActivityInterface(mTransitionDragLength); } - @Override - protected void updateSource(Rect stackBounds, RemoteAnimationTargetCompat runningTarget) { - super.updateSource(stackBounds, runningTarget); - mTaskViewSimulator.setPreview(runningTarget, mRecentsAnimationTargets); - } - - @Override - protected void initTransitionEndpoints(DeviceProfile dp) { - super.initTransitionEndpoints(dp); - mTaskViewSimulator.setDp(dp); - mTaskViewSimulator.setLayoutRotation( - mDeviceState.getCurrentActiveRotation(), - mDeviceState.getDisplayRotation()); - - 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); - } - /** * We don't want to change mLauncherTransitionController if mGestureState.getEndTarget() == HOME * (it has its own animation) or if we're already animating the current controller. @@ -576,18 +542,11 @@ public class LauncherSwipeHandler @Override public void updateFinalShift() { - if (mRecentsAnimationTargets != null) { - // Base class expects applyTransformUnchecked to be called here. - // TODO: Remove this dependency for swipe-up animation. - // applyTransformUnchecked(); - updateSysUiFlags(mCurrentShift.value); - } - if (ENABLE_QUICKSTEP_LIVE_TILE.get()) { if (mRecentsAnimationTargets != null) { LiveTileOverlay.INSTANCE.update( - mAppWindowAnimationHelper.getCurrentRectWithInsets(), - mAppWindowAnimationHelper.getCurrentCornerRadius()); + mTaskViewSimulator.getCurrentCropRect(), + mTaskViewSimulator.getCurrentCornerRadius()); } } @@ -599,14 +558,8 @@ public class LauncherSwipeHandler } } - if (mWindowTransitionController != null) { - float progress = mCurrentShift.value / mDragLengthFactor; - mWindowTransitionController.setPlayFraction(progress); - mTransformParams.setTargetSet(mRecentsAnimationTargets); - - mTaskViewSimulator.setScroll(mRecentsView == null ? 0 : mRecentsView.getScrollOffset()); - mTaskViewSimulator.apply(mTransformParams); - } + updateSysUiFlags(mCurrentShift.value); + applyWindowTransform(); updateLauncherTransitionProgress(); } @@ -680,7 +633,7 @@ public class LauncherSwipeHandler */ @UiThread private void notifyGestureStartedAsync() { - final T curActivity = mActivity; + final Launcher curActivity = mActivity; if (curActivity != null) { // Once the gesture starts, we can no longer transition home through the button, so // reset the force override of the activity visibility @@ -962,24 +915,61 @@ public class LauncherSwipeHandler Interpolator interpolator, GestureEndTarget target, PointF velocityPxPerMs) { // Set the state, but don't notify until the animation completes mGestureState.setEndTarget(target, false /* isAtomic */); - maybeUpdateRecentsAttachedState(); if (mGestureState.getEndTarget() == HOME) { HomeAnimationFactory homeAnimFactory; if (mActivity != null) { - homeAnimFactory = mActivityInterface.prepareHomeUI(); - } else { - homeAnimFactory = new HomeAnimationFactory() { - @NonNull + final TaskView runningTaskView = mRecentsView.getRunningTaskView(); + final View workspaceView; + if (runningTaskView != null + && runningTaskView.getTask().key.getComponent() != null) { + workspaceView = mActivity.getWorkspace().getFirstMatchForAppClose( + runningTaskView.getTask().key.getComponent().getPackageName(), + UserHandle.of(runningTaskView.getTask().key.userId)); + } else { + workspaceView = null; + } + final RectF iconLocation = new RectF(); + boolean canUseWorkspaceView = + workspaceView != null && workspaceView.isAttachedToWindow(); + FloatingIconView floatingIconView = canUseWorkspaceView + ? FloatingIconView.getFloatingIconView(mActivity, workspaceView, + true /* hideOriginal */, iconLocation, false /* isOpening */) + : null; + + mActivity.getRootView().setForceHideBackArrow(true); + + homeAnimFactory = new HomeAnimationFactory(floatingIconView) { + @Override public RectF getWindowTargetRect() { - RectF fallbackTarget = new RectF(mAppWindowAnimationHelper.getTargetRect()); - Utilities.scaleRectFAboutCenter(fallbackTarget, 0.25f); - return fallbackTarget; + if (canUseWorkspaceView) { + return iconLocation; + } else { + return super.getWindowTargetRect(); + } } @NonNull + @Override + public AnimatorPlaybackController createActivityAnimationToHome() { + // Return an empty APC here since we have an non-user controlled animation + // to home. + long accuracy = 2 * Math.max(mDp.widthPx, mDp.heightPx); + return mActivity.getStateManager().createAnimationToNewWorkspace( + NORMAL, accuracy, 0 /* animComponents */); + } + + @Override + public void playAtomicAnimation(float velocity) { + new StaggeredWorkspaceAnim(mActivity, velocity, + true /* animateOverviewScrim */).start(); + } + }; + + } else { + homeAnimFactory = new HomeAnimationFactory(null) { @Override public AnimatorPlaybackController createActivityAnimationToHome() { return AnimatorPlaybackController.wrap(new AnimatorSet(), duration); 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 d3bd01289b..a7979cce96 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 @@ -222,18 +222,8 @@ public class AppWindowAnimationHelper implements TransformParams.BuilderProxy { mCurrentRect.set(params.getCurrentRect()); } else { mTmpRectF.set(mTargetRect); - Utilities.scaleRectFAboutCenter(mTmpRectF, params.getOffsetScale()); mCurrentRect.set(mRectFEvaluator.evaluate( params.getProgress(), mSourceRect, mTmpRectF)); - if (mOrientedState == null - || !mOrientedState.isMultipleOrientationSupportedByDevice()) { - mCurrentRect.offset(params.getOffset(), 0); - } else { - int displayRotation = mOrientedState.getDisplayRotation(); - int launcherRotation = mOrientedState.getLauncherRotation(); - mOrientedState.getOrientationHandler().offsetTaskRect( - mCurrentRect, params.getOffset(), displayRotation, launcherRotation); - } } updateClipRect(params); 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 832f0e2dce..efdd3a73c4 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 @@ -33,7 +33,6 @@ import com.android.launcher3.R; import com.android.launcher3.Utilities; import com.android.launcher3.touch.PagedOrientationHandler; import com.android.quickstep.AnimatedFloat; -import com.android.quickstep.RecentsAnimationTargets; import com.android.quickstep.views.RecentsView.ScrollState; import com.android.quickstep.views.TaskThumbnailView.PreviewPositionHelper; import com.android.quickstep.views.TaskView; @@ -61,7 +60,6 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy { private final Matrix mMatrix = new Matrix(); private RemoteAnimationTargetCompat mRunningTarget; - private RecentsAnimationTargets mAllTargets; // Thumbnail view properties private final Rect mThumbnailPosition = new Rect(); @@ -135,10 +133,8 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy { /** * Sets the targets which the simulator will control */ - public void setPreview( - RemoteAnimationTargetCompat runningTarget, RecentsAnimationTargets allTargets) { + public void setPreview(RemoteAnimationTargetCompat runningTarget) { mRunningTarget = runningTarget; - mAllTargets = allTargets; mThumbnailData.insets.set(mRunningTarget.contentInsets); // TODO: What is this? @@ -160,6 +156,43 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy { } } + /** + * Returns the current clipped/visible window bounds in the window coordinate space + */ + public RectF getCurrentCropRect() { + // Crop rect is the inverse of thumbnail matrix + RectF insets = mCurrentFullscreenParams.mCurrentDrawnInsets; + mTempRectF.set(-insets.left, -insets.top, + mTaskRect.width() + insets.right, mTaskRect.height() + insets.bottom); + mInversePositionMatrix.mapRect(mTempRectF); + return mTempRectF; + } + + public RecentsOrientedState getOrientationState() { + return mOrientationState; + } + + /** + * Returns the current transform applied to the window + */ + public Matrix getCurrentMatrix() { + return mMatrix; + } + + /** + * Applies the rotation on the matrix to so that it maps from launcher coordinate space to + * window coordinate space. + */ + public void applyWindowToHomeRotation(Matrix matrix) { + mMatrix.postTranslate(mDp.windowX, mDp.windowY); + postDisplayRotation(deltaRotation( + mOrientationState.getLauncherRotation(), mOrientationState.getDisplayRotation()), + mDp.widthPx, mDp.heightPx, matrix); + if (mRunningTarget != null) { + matrix.postTranslate(-mRunningTarget.position.x, -mRunningTarget.position.y); + } + } + /** * Applies the target to the previously set parameters */ @@ -217,11 +250,7 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy { // Apply recensView matrix mMatrix.postScale(recentsViewScale.value, recentsViewScale.value, mPivot.x, mPivot.y); - postDisplayRotation(deltaRotation( - mOrientationState.getLauncherRotation(), mOrientationState.getDisplayRotation()), - mDp.widthPx, mDp.heightPx, mMatrix); - mMatrix.postTranslate(mDp.windowX - mRunningTarget.position.x, - mDp.windowY - mRunningTarget.position.y); + applyWindowToHomeRotation(mMatrix); // Crop rect is the inverse of thumbnail matrix mTempRectF.set(-insets.left, -insets.top, @@ -235,7 +264,7 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy { @Override public void onBuildParams(Builder builder, RemoteAnimationTargetCompat app, int targetMode, TransformParams params) { - if (app.mode == mAllTargets.targetMode + if (app.mode == targetMode && app.activityType != RemoteAnimationTargetCompat.ACTIVITY_TYPE_HOME) { builder.withMatrix(mMatrix) .withWindowCrop(mTmpCropRect) 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 02e2142d7d..83b64db024 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 @@ -30,8 +30,6 @@ import com.android.systemui.shared.system.TransactionCompat; public class TransformParams { private float mProgress; - private float mOffset; - private float mOffsetScale; private @Nullable RectF mCurrentRect; private float mTargetAlpha; private float mCornerRadius; @@ -43,8 +41,6 @@ public class TransformParams { public TransformParams() { mProgress = 0; - mOffset = 0; - mOffsetScale = 1; mCurrentRect = null; mTargetAlpha = 1; mCornerRadius = -1; @@ -89,26 +85,6 @@ public class TransformParams { return this; } - /** - * If {@link #mCurrentRect} is null (i.e. {@link #setCurrentRect(RectF)} hasn't overridden - * the default), then offset the current rect by this amount after computing the rect based - * on {@link #mProgress}. - */ - public TransformParams setOffset(float offset) { - mOffset = offset; - return this; - } - - /** - * If {@link #mCurrentRect} is null (i.e. {@link #setCurrentRect(RectF)} hasn't overridden - * the default), then scale the current rect by this amount after computing the rect based - * on {@link #mProgress}. - */ - public TransformParams setOffsetScale(float offsetScale) { - mOffsetScale = offsetScale; - return this; - } - /** * Specifies the set of RemoteAnimationTargetCompats that are included in the transformation * that these TransformParams help compute. These TransformParams generally only apply to @@ -183,14 +159,6 @@ public class TransformParams { return mProgress; } - public float getOffset() { - return mOffset; - } - - public float getOffsetScale() { - return mOffsetScale; - } - @Nullable public RectF getCurrentRect() { return mCurrentRect; diff --git a/quickstep/src/com/android/quickstep/BaseActivityInterface.java b/quickstep/src/com/android/quickstep/BaseActivityInterface.java index d51d6df489..bdddb3f8aa 100644 --- a/quickstep/src/com/android/quickstep/BaseActivityInterface.java +++ b/quickstep/src/com/android/quickstep/BaseActivityInterface.java @@ -18,14 +18,12 @@ package com.android.quickstep; import android.annotation.TargetApi; import android.content.Context; import android.graphics.Rect; -import android.graphics.RectF; import android.os.Build; import android.util.Pair; import android.view.MotionEvent; import android.view.View; import android.view.animation.Interpolator; -import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.UiThread; @@ -33,7 +31,6 @@ import com.android.launcher3.BaseDraggingActivity; import com.android.launcher3.DeviceProfile; import com.android.launcher3.anim.AnimatorPlaybackController; import com.android.launcher3.statehandlers.DepthController; -import com.android.launcher3.touch.PagedOrientationHandler; import com.android.quickstep.util.ActivityInitListener; import com.android.quickstep.util.ShelfPeekAnim; import com.android.systemui.shared.recents.model.ThumbnailData; @@ -66,8 +63,6 @@ public interface BaseActivityInterface { default void onSwipeUpToHomeComplete() { } void onAssistantVisibilityChanged(float visibility); - @NonNull HomeAnimationFactory prepareHomeUI(); - AnimationFactory prepareRecentsUI(boolean activityVisible, boolean animateActivity, Consumer callback); @@ -152,35 +147,4 @@ public interface BaseActivityInterface { */ default void setRecentsAttachedToAppWindow(boolean attached, boolean animate) { } } - - interface HomeAnimationFactory { - - /** Return the floating view that will animate in sync with the closing window. */ - default @Nullable View getFloatingView() { - return null; - } - - @NonNull RectF getWindowTargetRect(); - - @NonNull AnimatorPlaybackController createActivityAnimationToHome(); - - default void playAtomicAnimation(float velocity) { - // No-op - } - - static RectF getDefaultWindowTargetRect(PagedOrientationHandler orientationHandler, - DeviceProfile dp) { - final int halfIconSize = dp.iconSizePx / 2; - float primaryDimension = orientationHandler - .getPrimaryValue(dp.availableWidthPx, dp.availableHeightPx); - float secondaryDimension = orientationHandler - .getSecondaryValue(dp.availableWidthPx, dp.availableHeightPx); - final float targetX = primaryDimension / 2f; - final float targetY = secondaryDimension - dp.hotseatBarSizePx; - // Fallback to animate to center of screen. - return new RectF(targetX - halfIconSize, targetY - halfIconSize, - targetX + halfIconSize, targetY + halfIconSize); - } - - } } diff --git a/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java b/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java index f6c4e666c6..0418379898 100644 --- a/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java +++ b/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java @@ -36,7 +36,6 @@ import android.database.ContentObserver; import android.graphics.Matrix; import android.graphics.PointF; import android.graphics.Rect; -import android.graphics.RectF; import android.os.Handler; import android.provider.Settings; import android.util.Log; @@ -121,7 +120,6 @@ public final class RecentsOrientedState implements SharedPreferences.OnSharedPre private final WindowSizeStrategy mSizeStrategy; private final Matrix mTmpMatrix = new Matrix(); - private final Matrix mTmpInverseMatrix = new Matrix(); private int mFlags; private int mPreviousRotation = ROTATION_0; @@ -403,23 +401,6 @@ public final class RecentsOrientedState implements SharedPreferences.OnSharedPre */ } - public void mapRectFromNormalOrientation(RectF src, int screenWidth, int screenHeight) { - mapRectFromRotation(mDisplayRotation, src, screenWidth, screenHeight); - } - - public void mapRectFromRotation(int rotation, RectF src, int screenWidth, int screenHeight) { - mTmpMatrix.reset(); - postDisplayRotation(rotation, screenWidth, screenHeight, mTmpMatrix); - mTmpMatrix.mapRect(src); - } - - public void mapInverseRectFromNormalOrientation(RectF src, int screenWidth, int screenHeight) { - mTmpMatrix.reset(); - postDisplayRotation(mDisplayRotation, screenWidth, screenHeight, mTmpMatrix); - mTmpMatrix.invert(mTmpInverseMatrix); - mTmpInverseMatrix.mapRect(src); - } - @SurfaceRotation public static int getRotationForUserDegreesRotated(float degrees, int currentRotation) { if (degrees == ORIENTATION_UNKNOWN) {