From 8b488ccc2e433a708c8b06f0b6866f2a305e4b0a Mon Sep 17 00:00:00 2001 From: Tracy Zhou Date: Wed, 14 Oct 2020 12:13:04 -0700 Subject: [PATCH] [Live Tile] Support launching running task animation Fixes: 170338170 Test: manual Change-Id: I2526b7cfbacaea7899b8e2ed233f913630071d36 --- .../com/android/quickstep/TaskViewUtils.java | 50 +++++++++++++++---- .../quickstep/views/LiveTileOverlay.java | 26 +++++----- .../android/quickstep/views/RecentsView.java | 8 +++ .../com/android/quickstep/views/TaskView.java | 36 +++++++++---- 4 files changed, 87 insertions(+), 33 deletions(-) diff --git a/quickstep/src/com/android/quickstep/TaskViewUtils.java b/quickstep/src/com/android/quickstep/TaskViewUtils.java index 5520ef7751..46c77681ae 100644 --- a/quickstep/src/com/android/quickstep/TaskViewUtils.java +++ b/quickstep/src/com/android/quickstep/TaskViewUtils.java @@ -41,6 +41,7 @@ import android.os.Build; import android.view.View; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import com.android.launcher3.BaseActivity; import com.android.launcher3.DeviceProfile; @@ -129,6 +130,21 @@ public final class TaskViewUtils { return taskView; } + public static void createRecentsWindowAnimator(TaskView v, boolean skipViewChanges, + RemoteAnimationTargetCompat[] appTargets, + RemoteAnimationTargetCompat[] wallpaperTargets, DepthController depthController, + PendingAnimation out) { + boolean isRunningTask = v.isRunningTask(); + TransformParams params = null; + TaskViewSimulator tsv = null; + if (ENABLE_QUICKSTEP_LIVE_TILE.get() && isRunningTask) { + params = v.getRecentsView().getLiveTileParams(); + tsv = v.getRecentsView().getLiveTileTaskViewSimulator(); + } + createRecentsWindowAnimator(v, skipViewChanges, appTargets, wallpaperTargets, + depthController, out, params, tsv); + } + /** * Creates an animation that controls the window of the opening targets for the recents launch * animation. @@ -136,19 +152,25 @@ public final class TaskViewUtils { public static void createRecentsWindowAnimator(TaskView v, boolean skipViewChanges, RemoteAnimationTargetCompat[] appTargets, RemoteAnimationTargetCompat[] wallpaperTargets, DepthController depthController, - PendingAnimation out) { + PendingAnimation out, @Nullable TransformParams params, + @Nullable TaskViewSimulator tsv) { boolean isQuickSwitch = v.isEndQuickswitchCuj(); v.setEndQuickswitchCuj(false); - SurfaceTransactionApplier applier = new SurfaceTransactionApplier(v); + boolean inLiveTileMode = + ENABLE_QUICKSTEP_LIVE_TILE.get() && v.getRecentsView().getRunningTaskIndex() != -1; final RemoteAnimationTargets targets = new RemoteAnimationTargets(appTargets, wallpaperTargets, - ENABLE_QUICKSTEP_LIVE_TILE.get() ? MODE_CLOSING : MODE_OPENING); - targets.addReleaseCheck(applier); + inLiveTileMode ? MODE_CLOSING : MODE_OPENING); - TransformParams params = new TransformParams() + if (params == null) { + SurfaceTransactionApplier applier = new SurfaceTransactionApplier(v); + targets.addReleaseCheck(applier); + + params = new TransformParams() .setSyncTransactionApplier(applier) .setTargetSet(targets); + } final RecentsView recentsView = v.getRecentsView(); int taskIndex = recentsView.indexOfChild(v); @@ -162,8 +184,9 @@ public final class TaskViewUtils { int displayRotation = DisplayController.getDefaultDisplay(context).getInfo().rotation; TaskViewSimulator topMostSimulator = null; - if (targets.apps.length > 0) { - TaskViewSimulator tsv = new TaskViewSimulator(context, recentsView.getSizeStrategy()); + + if (tsv == null && targets.apps.length > 0) { + tsv = new TaskViewSimulator(context, recentsView.getSizeStrategy()); tsv.setDp(dp); tsv.setLayoutRotation(displayRotation, displayRotation); tsv.setPreview(targets.apps[targets.apps.length - 1]); @@ -171,19 +194,24 @@ public final class TaskViewUtils { tsv.recentsViewScale.value = 1; tsv.setScroll(startScroll); + // Fade in the task during the initial 20% of the animation + out.addFloat(params, TransformParams.TARGET_ALPHA, 0, 1, + clampToProgress(LINEAR, 0, 0.2f)); + } + + if (tsv != null) { out.setFloat(tsv.fullScreenProgress, AnimatedFloat.VALUE, 1, TOUCH_RESPONSE_INTERPOLATOR); out.setFloat(tsv.recentsViewScale, AnimatedFloat.VALUE, tsv.getFullScreenScale(), TOUCH_RESPONSE_INTERPOLATOR); out.setInt(tsv, TaskViewSimulator.SCROLL, 0, TOUCH_RESPONSE_INTERPOLATOR); - out.addOnFrameCallback(() -> tsv.apply(params)); + TaskViewSimulator finalTsv = tsv; + TransformParams finalParams = params; + out.addOnFrameCallback(() -> finalTsv.apply(finalParams)); topMostSimulator = tsv; } - // Fade in the task during the initial 20% of the animation - out.addFloat(params, TransformParams.TARGET_ALPHA, 0, 1, clampToProgress(LINEAR, 0, 0.2f)); - if (!skipViewChanges && parallaxCenterAndAdjacentTask && topMostSimulator != null) { out.addFloat(v, VIEW_ALPHA, 1, 0, clampToProgress(LINEAR, 0.2f, 0.4f)); diff --git a/quickstep/src/com/android/quickstep/views/LiveTileOverlay.java b/quickstep/src/com/android/quickstep/views/LiveTileOverlay.java index c6c2d7e4f0..f6eb0e224b 100644 --- a/quickstep/src/com/android/quickstep/views/LiveTileOverlay.java +++ b/quickstep/src/com/android/quickstep/views/LiveTileOverlay.java @@ -65,6 +65,10 @@ public class LiveTileOverlay extends Drawable { invalidateSelf(); } + public void update(float left, float top, float right, float bottom) { + mCurrentRect.set(left, top, right, bottom); + } + public void setIcon(Drawable icon) { mIcon = icon; } @@ -94,18 +98,16 @@ public class LiveTileOverlay extends Drawable { @Override public void draw(Canvas canvas) { - if (mCurrentRect != null) { - canvas.drawRoundRect(mCurrentRect, mCornerRadius, mCornerRadius, mPaint); - if (mIcon != null && mIconAnimationProgress > 0f) { - canvas.save(); - float scale = Interpolators.clampToProgress(FAST_OUT_SLOW_IN, 0f, - 1f).getInterpolation(mIconAnimationProgress); - canvas.translate(mCurrentRect.centerX() - mIcon.getBounds().width() / 2 * scale, - mCurrentRect.top - mIcon.getBounds().height() / 2 * scale); - canvas.scale(scale, scale); - mIcon.draw(canvas); - canvas.restore(); - } + canvas.drawRoundRect(mCurrentRect, mCornerRadius, mCornerRadius, mPaint); + if (mIcon != null && mIconAnimationProgress > 0f) { + canvas.save(); + float scale = Interpolators.clampToProgress(FAST_OUT_SLOW_IN, 0f, + 1f).getInterpolation(mIconAnimationProgress); + canvas.translate(mCurrentRect.centerX() - mIcon.getBounds().width() / 2 * scale, + mCurrentRect.top - mIcon.getBounds().height() / 2 * scale); + canvas.scale(scale, scale); + mIcon.draw(canvas); + canvas.restore(); } } diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java index 2158e03e7e..4c967068a0 100644 --- a/quickstep/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/src/com/android/quickstep/views/RecentsView.java @@ -876,6 +876,10 @@ public abstract class RecentsView extends PagedView mLiveTileTaskViewSimulator.fullScreenProgress.value = 0; mLiveTileTaskViewSimulator.recentsViewScale.value = 1; mLiveTileTaskViewSimulator.setOffsetY(0); + + // Reset the live tile rect + DeviceProfile deviceProfile = mActivity.getDeviceProfile(); + LiveTileOverlay.INSTANCE.update(0, 0, deviceProfile.widthPx, deviceProfile.heightPx); } if (mRunningTaskTileHidden) { setRunningTaskHidden(mRunningTaskTileHidden); @@ -2264,6 +2268,10 @@ public abstract class RecentsView extends PagedView return mLiveTileTaskViewSimulator; } + public TransformParams getLiveTileParams() { + return mLiveTileParams; + } + // TODO: To be removed in a follow up CL public void setRecentsAnimationTargets(RecentsAnimationController recentsAnimationController, RecentsAnimationTargets recentsAnimationTargets) { diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java index 54a793c8e0..5154018f6c 100644 --- a/quickstep/src/com/android/quickstep/views/TaskView.java +++ b/quickstep/src/com/android/quickstep/views/TaskView.java @@ -39,6 +39,7 @@ import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCH import android.animation.Animator; import android.animation.AnimatorListenerAdapter; +import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.animation.TimeInterpolator; import android.animation.ValueAnimator; @@ -65,7 +66,6 @@ import android.view.accessibility.AccessibilityNodeInfo; import android.widget.FrameLayout; import android.widget.Toast; -import com.android.launcher3.BaseDraggingActivity; import com.android.launcher3.DeviceProfile; import com.android.launcher3.LauncherSettings; import com.android.launcher3.R; @@ -75,6 +75,7 @@ import com.android.launcher3.anim.Interpolators; import com.android.launcher3.anim.PendingAnimation; import com.android.launcher3.model.data.WorkspaceItemInfo; import com.android.launcher3.popup.SystemShortcut; +import com.android.launcher3.statemanager.StatefulActivity; import com.android.launcher3.testing.TestLogging; import com.android.launcher3.testing.TestProtocol; import com.android.launcher3.touch.PagedOrientationHandler; @@ -82,10 +83,12 @@ import com.android.launcher3.util.ComponentKey; import com.android.launcher3.util.TransformingTouchDelegate; import com.android.launcher3.util.ViewPool.Reusable; import com.android.quickstep.RecentsModel; +import com.android.quickstep.RemoteAnimationTargets; import com.android.quickstep.TaskIconCache; import com.android.quickstep.TaskOverlayFactory; import com.android.quickstep.TaskThumbnailCache; import com.android.quickstep.TaskUtils; +import com.android.quickstep.TaskViewUtils; import com.android.quickstep.util.CancellableTask; import com.android.quickstep.util.RecentsOrientedState; import com.android.quickstep.util.TaskCornerRadius; @@ -175,7 +178,7 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable { private float mCurveScale; private float mFullscreenProgress; private final FullscreenDrawParams mCurrentFullscreenParams; - private final BaseDraggingActivity mActivity; + private final StatefulActivity mActivity; private ObjectAnimator mIconAndDimAnimator; private float mIconScaleAnimStartProgress = 0; @@ -212,18 +215,31 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable { public TaskView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); - mActivity = BaseDraggingActivity.fromContext(context); + mActivity = StatefulActivity.fromContext(context); setOnClickListener((view) -> { if (getTask() == null) { return; } - if (ENABLE_QUICKSTEP_LIVE_TILE.get()) { - if (isRunningTask()) { - // TODO: Replace this animation with createRecentsWindowAnimator - createLaunchAnimationForRunningTask().start(); - } else { - launchTask(true /* animate */); - } + if (ENABLE_QUICKSTEP_LIVE_TILE.get() && isRunningTask()) { + RecentsView recentsView = getRecentsView(); + RemoteAnimationTargets targets = recentsView.getLiveTileParams().getTargetSet(); + recentsView.getLiveTileTaskViewSimulator().setDrawsBelowRecents(false); + + AnimatorSet anim = new AnimatorSet(); + TaskViewUtils.composeRecentsLaunchAnimator( + anim, this, targets.apps, + targets.wallpapers, true /* launcherClosing */, + mActivity.getStateManager(), recentsView, + recentsView.getDepthController()); + anim.addListener(new AnimatorListenerAdapter() { + + @Override + public void onAnimationEnd(Animator animator) { + recentsView.getLiveTileTaskViewSimulator().setDrawsBelowRecents(true); + recentsView.finishRecentsAnimation(false, null); + } + }); + anim.start(); } else { launchTask(true /* animate */); }