From f3bfe4e156389290c99b7afce9f8b3e31831f0e5 Mon Sep 17 00:00:00 2001 From: Jeremy Sim Date: Mon, 19 Sep 2022 21:53:53 -0700 Subject: [PATCH] Update animations for TM-QPR: Home > OverviewSplitSelect transition This change updates the animation for initiating a split from the home screen. Also fixes a bug where icons were getting severely pixelated mid-animation. Fixes: 236759099 Fixes: 244499770 Test: Manual Change-Id: I56a76cbf286bd30540f3debdcb681d39c890a445 --- .../popup/QuickstepSystemShortcut.java | 1 + .../taskbar/TaskbarPopupController.java | 1 + .../QuickstepAtomicAnimationFactory.java | 8 ++++ .../quickstep/util/NormalToSplitTimings.java | 43 +++++++++++++++++++ .../util/OverviewToSplitTimings.java | 13 +++--- .../quickstep/util/SplitAnimationTimings.java | 34 +++++++++------ .../quickstep/util/SplitToConfirmTimings.java | 13 +++--- .../quickstep/views/FloatingTaskView.java | 41 ++++++++++-------- .../android/quickstep/views/RecentsView.java | 3 +- 9 files changed, 114 insertions(+), 43 deletions(-) create mode 100644 quickstep/src/com/android/quickstep/util/NormalToSplitTimings.java diff --git a/quickstep/src/com/android/launcher3/popup/QuickstepSystemShortcut.java b/quickstep/src/com/android/launcher3/popup/QuickstepSystemShortcut.java index 9a682c6e53..7c3281a046 100644 --- a/quickstep/src/com/android/launcher3/popup/QuickstepSystemShortcut.java +++ b/quickstep/src/com/android/launcher3/popup/QuickstepSystemShortcut.java @@ -55,6 +55,7 @@ public interface QuickstepSystemShortcut { @Override public void onClick(View view) { + // Initiate splitscreen from the Home screen or Home All Apps Bitmap bitmap; Intent intent; if (mItemInfo instanceof WorkspaceItemInfo) { diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarPopupController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarPopupController.java index 49d0873037..da6dab1e10 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarPopupController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarPopupController.java @@ -270,6 +270,7 @@ public class TaskbarPopupController implements TaskbarControllers.LoggableTaskba @Override public void onClick(View view) { + // Initiate splitscreen from the in-app Taskbar or Taskbar All Apps Pair instanceIds = LogUtils.getShellShareableInstanceId(); mTarget.getStatsLogManager().logger() diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java b/quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java index bfece6c5e2..f75a404821 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java +++ b/quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java @@ -34,6 +34,7 @@ import static com.android.launcher3.anim.Interpolators.EMPHASIZED_DECELERATE; import static com.android.launcher3.anim.Interpolators.FINAL_FRAME; import static com.android.launcher3.anim.Interpolators.INSTANT; import static com.android.launcher3.anim.Interpolators.LINEAR; +import static com.android.launcher3.anim.Interpolators.OVERSHOOT_0_75; import static com.android.launcher3.anim.Interpolators.OVERSHOOT_1_2; import static com.android.launcher3.anim.Interpolators.clampToProgress; import static com.android.launcher3.states.StateAnimationConfig.ANIM_ALL_APPS_FADE; @@ -194,6 +195,13 @@ public class QuickstepAtomicAnimationFactory extends config.setInterpolator(ANIM_OVERVIEW_ACTIONS_FADE, clampToProgress(LINEAR, timings.getActionsFadeStartOffset(), timings.getActionsFadeEndOffset())); + } else if (fromState == NORMAL && toState == OVERVIEW_SPLIT_SELECT) { + SplitAnimationTimings timings = SplitAnimationTimings.NORMAL_TO_SPLIT; + config.setInterpolator(ANIM_SCRIM_FADE, clampToProgress(LINEAR, + timings.getScrimFadeInStartOffset(), + timings.getScrimFadeInEndOffset())); + config.setInterpolator(ANIM_OVERVIEW_TRANSLATE_X, OVERSHOOT_0_75); + config.setInterpolator(ANIM_OVERVIEW_TRANSLATE_Y, OVERSHOOT_0_75); } } } diff --git a/quickstep/src/com/android/quickstep/util/NormalToSplitTimings.java b/quickstep/src/com/android/quickstep/util/NormalToSplitTimings.java new file mode 100644 index 0000000000..1bf5a5dda7 --- /dev/null +++ b/quickstep/src/com/android/quickstep/util/NormalToSplitTimings.java @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.quickstep.util; + +import static com.android.launcher3.anim.Interpolators.LINEAR; + +import android.view.animation.Interpolator; + +/** + * Timings for the Normal > OverviewSplitSelect animation. + */ +public class NormalToSplitTimings extends OverviewToSplitTimings implements SplitAnimationTimings { + @Override + public Interpolator getStagedRectXInterpolator() { return LINEAR; } + @Override + public Interpolator getStagedRectScaleXInterpolator() { return LINEAR; } + @Override + public Interpolator getStagedRectScaleYInterpolator() { return LINEAR; } + + public int getScrimFadeInStart() { return 0; } + public int getScrimFadeInEnd() { return 167; } + + public float getScrimFadeInStartOffset() { + return (float) getScrimFadeInStart() / getDuration(); + } + public float getScrimFadeInEndOffset() { + return (float) getScrimFadeInEnd() / getDuration(); + } +} diff --git a/quickstep/src/com/android/quickstep/util/OverviewToSplitTimings.java b/quickstep/src/com/android/quickstep/util/OverviewToSplitTimings.java index 40e547b749..f44796b79e 100644 --- a/quickstep/src/com/android/quickstep/util/OverviewToSplitTimings.java +++ b/quickstep/src/com/android/quickstep/util/OverviewToSplitTimings.java @@ -24,10 +24,10 @@ import android.view.animation.Interpolator; * Timings for the Overview > OverviewSplitSelect animation. */ public class OverviewToSplitTimings implements SplitAnimationTimings { - public int getThumbnailFadeToGrayStart() { return 0; } - public int getThumbnailFadeToGrayEnd() { return 133; } - public int getDockedIconFadeInStart() { return 167; } - public int getDockedIconFadeInEnd() { return 250; } + public int getPlaceholderFadeInStart() { return 0; } + public int getPlaceholderFadeInEnd() { return 133; } + public int getPlaceholderIconFadeInStart() { return 167; } + public int getPlaceholderIconFadeInEnd() { return 250; } public int getStagedRectSlideStart() { return 0; } public int getStagedRectSlideEnd() { return 417; } public int getGridSlideStart() { return 67; } @@ -45,7 +45,10 @@ public class OverviewToSplitTimings implements SplitAnimationTimings { public int getInstructionsUnfoldEnd() { return 500; } public int getDuration() { return ENTER_DURATION; } - public Interpolator getStagedRectSlideInterpolator() { return DEACCEL_2; } + public Interpolator getStagedRectXInterpolator() { return DEACCEL_2; } + public Interpolator getStagedRectYInterpolator() { return DEACCEL_2; } + public Interpolator getStagedRectScaleXInterpolator() { return DEACCEL_2; } + public Interpolator getStagedRectScaleYInterpolator() { return DEACCEL_2; } public float getGridSlideStartOffset() { return (float) getGridSlideStart() / getDuration(); diff --git a/quickstep/src/com/android/quickstep/util/SplitAnimationTimings.java b/quickstep/src/com/android/quickstep/util/SplitAnimationTimings.java index c6f7fb125a..133be0394e 100644 --- a/quickstep/src/com/android/quickstep/util/SplitAnimationTimings.java +++ b/quickstep/src/com/android/quickstep/util/SplitAnimationTimings.java @@ -27,28 +27,32 @@ public interface SplitAnimationTimings { int CONFIRM_DURATION = 383; SplitAnimationTimings OVERVIEW_TO_SPLIT = new OverviewToSplitTimings(); + SplitAnimationTimings NORMAL_TO_SPLIT = new NormalToSplitTimings(); SplitAnimationTimings SPLIT_TO_CONFIRM = new SplitToConfirmTimings(); // Shared methods int getDuration(); - int getThumbnailFadeToGrayStart(); - int getThumbnailFadeToGrayEnd(); - int getDockedIconFadeInStart(); - int getDockedIconFadeInEnd(); + int getPlaceholderFadeInStart(); + int getPlaceholderFadeInEnd(); + int getPlaceholderIconFadeInStart(); + int getPlaceholderIconFadeInEnd(); int getStagedRectSlideStart(); int getStagedRectSlideEnd(); - Interpolator getStagedRectSlideInterpolator(); - default float getThumbnailFadeToGrayStartOffset() { - return (float) getThumbnailFadeToGrayStart() / getDuration(); + Interpolator getStagedRectXInterpolator(); + Interpolator getStagedRectYInterpolator(); + Interpolator getStagedRectScaleXInterpolator(); + Interpolator getStagedRectScaleYInterpolator(); + default float getPlaceholderFadeInStartOffset() { + return (float) getPlaceholderFadeInStart() / getDuration(); } - default float getThumbnailFadeToGrayEndOffset() { - return (float) getThumbnailFadeToGrayEnd() / getDuration(); + default float getPlaceholderFadeInEndOffset() { + return (float) getPlaceholderFadeInEnd() / getDuration(); } - default float getDockedIconFadeInStartOffset() { - return (float) getDockedIconFadeInStart() / getDuration(); + default float getPlaceholderIconFadeInStartOffset() { + return (float) getPlaceholderIconFadeInStart() / getDuration(); } - default float getDockedIconFadeInEndOffset() { - return (float) getDockedIconFadeInEnd() / getDuration(); + default float getPlaceholderIconFadeInEndOffset() { + return (float) getPlaceholderIconFadeInEnd() / getDuration(); } default float getStagedRectSlideStartOffset() { return (float) getStagedRectSlideStart() / getDuration(); @@ -72,6 +76,10 @@ public interface SplitAnimationTimings { default float getInstructionsUnfoldStartOffset() { return 0; } default float getInstructionsUnfoldEndOffset() { return 0; } + // Defaults for NormalToSplit + default float getScrimFadeInStartOffset() { return 0; } + default float getScrimFadeInEndOffset() { return 0; } + // Defaults for SplitToConfirm default float getInstructionsFadeStartOffset() { return 0; } default float getInstructionsFadeEndOffset() { return 0; } diff --git a/quickstep/src/com/android/quickstep/util/SplitToConfirmTimings.java b/quickstep/src/com/android/quickstep/util/SplitToConfirmTimings.java index 2eb0941aa2..84cfb0be94 100644 --- a/quickstep/src/com/android/quickstep/util/SplitToConfirmTimings.java +++ b/quickstep/src/com/android/quickstep/util/SplitToConfirmTimings.java @@ -24,17 +24,20 @@ import android.view.animation.Interpolator; * Timings for the OverviewSplitSelect > confirmed animation. */ public class SplitToConfirmTimings implements SplitAnimationTimings { - public int getThumbnailFadeToGrayStart() { return 0; } - public int getThumbnailFadeToGrayEnd() { return 133; } - public int getDockedIconFadeInStart() { return 167; } - public int getDockedIconFadeInEnd() { return 250; } + public int getPlaceholderFadeInStart() { return 0; } + public int getPlaceholderFadeInEnd() { return 133; } + public int getPlaceholderIconFadeInStart() { return 167; } + public int getPlaceholderIconFadeInEnd() { return 250; } public int getStagedRectSlideStart() { return 0; } public int getStagedRectSlideEnd() { return 383; } public int getInstructionsFadeStart() { return 0; } public int getInstructionsFadeEnd() { return 67; } public int getDuration() { return CONFIRM_DURATION; } - public Interpolator getStagedRectSlideInterpolator() { return LINEAR; } + public Interpolator getStagedRectXInterpolator() { return LINEAR; } + public Interpolator getStagedRectYInterpolator() { return LINEAR; } + public Interpolator getStagedRectScaleXInterpolator() { return LINEAR; } + public Interpolator getStagedRectScaleYInterpolator() { return LINEAR; } public float getInstructionsFadeStartOffset() { return (float) getInstructionsFadeStart() / getDuration(); diff --git a/quickstep/src/com/android/quickstep/views/FloatingTaskView.java b/quickstep/src/com/android/quickstep/views/FloatingTaskView.java index 1d58748b62..bf88702972 100644 --- a/quickstep/src/com/android/quickstep/views/FloatingTaskView.java +++ b/quickstep/src/com/android/quickstep/views/FloatingTaskView.java @@ -1,8 +1,6 @@ package com.android.quickstep.views; import static com.android.launcher3.AbstractFloatingView.TYPE_TASK_MENU; -import static com.android.launcher3.anim.Interpolators.ACCEL; -import static com.android.launcher3.anim.Interpolators.INSTANT; import static com.android.launcher3.anim.Interpolators.LINEAR; import static com.android.launcher3.anim.Interpolators.clampToProgress; @@ -217,8 +215,11 @@ public class FloatingTaskView extends FrameLayout { */ public void addStagingAnimation(PendingAnimation animation, RectF startingBounds, Rect endBounds, boolean fadeWithThumbnail, boolean isStagedTask) { + SplitAnimationTimings timings = fadeWithThumbnail + ? SplitAnimationTimings.OVERVIEW_TO_SPLIT + : SplitAnimationTimings.NORMAL_TO_SPLIT; addAnimation(animation, startingBounds, endBounds, fadeWithThumbnail, isStagedTask, - SplitAnimationTimings.OVERVIEW_TO_SPLIT); + timings); } /** @@ -257,47 +258,40 @@ public class FloatingTaskView extends FrameLayout { // FloatingTaskThumbnailView: thumbnail fades out to transparent animation.setViewAlpha(mThumbnailView, 0, clampToProgress(LINEAR, - timings.getThumbnailFadeToGrayStartOffset(), - timings.getThumbnailFadeToGrayEndOffset())); + timings.getPlaceholderFadeInStartOffset(), + timings.getPlaceholderFadeInEndOffset())); // SplitPlaceholderView: gray background fades in at same time, then new icon fades in - animation.setViewAlpha(mSplitPlaceholderView, 1, clampToProgress(LINEAR, - timings.getThumbnailFadeToGrayStartOffset(), - timings.getThumbnailFadeToGrayEndOffset())); - animation.setViewAlpha(mSplitPlaceholderView.getIconView(), 1, clampToProgress( - LINEAR, - timings.getDockedIconFadeInStartOffset(), - timings.getDockedIconFadeInEndOffset())); + fadeInSplitPlaceholder(animation, timings); } else if (isStagedTask) { // This code block runs for the placeholder view during Normal > OverviewSplitSelect // and for the placeholder (primary) thumbnail during OverviewSplitSelect > Confirmed // Fade in the placeholder view during Normal > OverviewSplitSelect if (mSplitPlaceholderView.getAlpha() == 0) { - animation.setViewAlpha(mSplitPlaceholderView, 0.3f, INSTANT); - animation.setViewAlpha(mSplitPlaceholderView, 1, ACCEL); + mSplitPlaceholderView.getIconView().setAlpha(0); + fadeInSplitPlaceholder(animation, timings); } // No-op for placeholder during OverviewSplitSelect > Confirmed, alpha should be set } - MultiValueUpdateListener listener = new MultiValueUpdateListener() { // SplitPlaceholderView: rectangle translates and stretches to new position final FloatProp mDx = new FloatProp(0, prop.dX, 0, animDuration, - clampToProgress(timings.getStagedRectSlideInterpolator(), + clampToProgress(timings.getStagedRectXInterpolator(), timings.getStagedRectSlideStartOffset(), timings.getStagedRectSlideEndOffset())); final FloatProp mDy = new FloatProp(0, prop.dY, 0, animDuration, - clampToProgress(timings.getStagedRectSlideInterpolator(), + clampToProgress(timings.getStagedRectYInterpolator(), timings.getStagedRectSlideStartOffset(), timings.getStagedRectSlideEndOffset())); final FloatProp mTaskViewScaleX = new FloatProp(1f, prop.finalTaskViewScaleX, 0, - animDuration, clampToProgress(timings.getStagedRectSlideInterpolator(), + animDuration, clampToProgress(timings.getStagedRectScaleXInterpolator(), timings.getStagedRectSlideStartOffset(), timings.getStagedRectSlideEndOffset())); final FloatProp mTaskViewScaleY = new FloatProp(1f, prop.finalTaskViewScaleY, 0, - animDuration, clampToProgress(timings.getStagedRectSlideInterpolator(), + animDuration, clampToProgress(timings.getStagedRectScaleYInterpolator(), timings.getStagedRectSlideStartOffset(), timings.getStagedRectSlideEndOffset())); @Override @@ -315,6 +309,15 @@ public class FloatingTaskView extends FrameLayout { transitionAnimator.addUpdateListener(listener); } + void fadeInSplitPlaceholder(PendingAnimation animation, SplitAnimationTimings timings) { + animation.setViewAlpha(mSplitPlaceholderView, 1, clampToProgress(LINEAR, + timings.getPlaceholderFadeInStartOffset(), + timings.getPlaceholderFadeInEndOffset())); + animation.setViewAlpha(mSplitPlaceholderView.getIconView(), 1, clampToProgress(LINEAR, + timings.getPlaceholderIconFadeInStartOffset(), + timings.getPlaceholderIconFadeInEndOffset())); + } + void drawRoundedRect(Canvas canvas, Paint paint) { if (mFullscreenParams == null) { return; diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java index 9b1a92a86f..50cc39d151 100644 --- a/quickstep/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/src/com/android/quickstep/views/RecentsView.java @@ -2814,7 +2814,7 @@ public abstract class RecentsView