From 91fb2f2e5e2c1f61adb78fbcfebc22cdb9210b3a Mon Sep 17 00:00:00 2001 From: Jeremy Sim Date: Thu, 13 Jun 2024 12:41:39 -0700 Subject: [PATCH] Fix flickering issues with divider during split animation This CL makes changes to the "split divider placeholder view", which was intended to cover up the backdrop a little during the split confirm animation. The placeholder view is now larger (fullscreen) and fades in with the animation movement, so there is no longer a period of time when it looks like an awkward rectangle. New timings and interpolators confirmed with UX. Also renamed some variables and added comments for clarity. Fixes: 344573331 Test: Manually verified that the visual bug no longer happens on large and small screen, and from desktop and Overview. Flag: EXEMPT bugfix Change-Id: I3b37f2b0478035d7a3181ae7c23962fe75a13b2c --- .../util/PhoneSplitToConfirmTimings.java | 2 + .../util/SplitAnimationController.kt | 61 +++++++------------ .../quickstep/util/SplitToConfirmTimings.java | 10 +++ .../util/SplitToWorkspaceController.java | 7 +-- .../util/TabletSplitToConfirmTimings.java | 2 + .../android/quickstep/views/RecentsView.java | 13 ++-- 6 files changed, 46 insertions(+), 49 deletions(-) diff --git a/quickstep/src/com/android/quickstep/util/PhoneSplitToConfirmTimings.java b/quickstep/src/com/android/quickstep/util/PhoneSplitToConfirmTimings.java index 3d9e09ee81..cbe0f19c01 100644 --- a/quickstep/src/com/android/quickstep/util/PhoneSplitToConfirmTimings.java +++ b/quickstep/src/com/android/quickstep/util/PhoneSplitToConfirmTimings.java @@ -27,6 +27,8 @@ public class PhoneSplitToConfirmTimings public int getPlaceholderIconFadeInEnd() { return 133; } public int getStagedRectSlideStart() { return 0; } public int getStagedRectSlideEnd() { return 333; } + public int getBackingScrimFadeInStart() { return 0; } + public int getBackingScrimFadeInEnd() { return 266; } public int getDuration() { return PHONE_CONFIRM_DURATION; } } diff --git a/quickstep/src/com/android/quickstep/util/SplitAnimationController.kt b/quickstep/src/com/android/quickstep/util/SplitAnimationController.kt index 8243ededd2..4bef51851c 100644 --- a/quickstep/src/com/android/quickstep/util/SplitAnimationController.kt +++ b/quickstep/src/com/android/quickstep/util/SplitAnimationController.kt @@ -281,64 +281,45 @@ class SplitAnimationController(val splitSelectStateController: SplitSelectStateC } /** - * Creates and returns a view to fade in at .4 animation progress and adds it to the provided - * [pendingAnimation]. Assumes that animation will be the final split placeholder launch anim. - * - * [secondPlaceholderEndingBounds] refers to the second placeholder view that gets added on - * screen, not the logical second app. For landscape it's the left app and for portrait the top - * one. + * Creates and returns a fullscreen scrim to fade in behind the split confirm animation, and + * adds it to the provided [pendingAnimation]. */ - fun addDividerPlaceholderViewToAnim( + fun addScrimBehindAnim( pendingAnimation: PendingAnimation, container: RecentsViewContainer, - secondPlaceholderEndingBounds: Rect, context: Context ): View { - val mSplitDividerPlaceholderView = View(context) + val scrim = View(context) val recentsView = container.getOverviewPanel>() - val dp: com.android.launcher3.DeviceProfile = container.getDeviceProfile() + val dp: DeviceProfile = container.getDeviceProfile() // Add it before/under the most recently added first floating taskView val firstAddedSplitViewIndex: Int = container .getDragLayer() .indexOfChild(recentsView.splitSelectController.firstFloatingTaskView) - container.getDragLayer().addView(mSplitDividerPlaceholderView, firstAddedSplitViewIndex) - val lp = mSplitDividerPlaceholderView.layoutParams as InsettableFrameLayout.LayoutParams + container.getDragLayer().addView(scrim, firstAddedSplitViewIndex) + // Make the scrim fullscreen + val lp = scrim.layoutParams as InsettableFrameLayout.LayoutParams lp.topMargin = 0 + lp.height = dp.heightPx + lp.width = dp.widthPx - if (dp.isLeftRightSplit) { - lp.height = secondPlaceholderEndingBounds.height() - lp.width = - container - .asContext() - .resources - .getDimensionPixelSize(R.dimen.split_divider_handle_region_height) - mSplitDividerPlaceholderView.translationX = - secondPlaceholderEndingBounds.right - lp.width / 2f - mSplitDividerPlaceholderView.translationY = 0f - } else { - lp.height = - container - .asContext() - .resources - .getDimensionPixelSize(R.dimen.split_divider_handle_region_height) - lp.width = secondPlaceholderEndingBounds.width() - mSplitDividerPlaceholderView.translationY = - secondPlaceholderEndingBounds.top - lp.height / 2f - mSplitDividerPlaceholderView.translationX = 0f - } - - mSplitDividerPlaceholderView.alpha = 0f - mSplitDividerPlaceholderView.setBackgroundColor( + scrim.alpha = 0f + scrim.setBackgroundColor( container.asContext().resources.getColor(R.color.taskbar_background_dark) ) - val timings = AnimUtils.getDeviceSplitToConfirmTimings(dp.isTablet) + val timings = AnimUtils.getDeviceSplitToConfirmTimings(dp.isTablet) as SplitToConfirmTimings pendingAnimation.setViewAlpha( - mSplitDividerPlaceholderView, + scrim, 1f, - Interpolators.clampToProgress(timings.stagedRectScaleXInterpolator, 0.4f, 1f) + Interpolators.clampToProgress( + timings.backingScrimFadeInterpolator, + timings.backingScrimFadeInStartOffset, + timings.backingScrimFadeInEndOffset + ) ) - return mSplitDividerPlaceholderView + + return scrim } /** Does not play any animation if user is not currently in split selection state. */ diff --git a/quickstep/src/com/android/quickstep/util/SplitToConfirmTimings.java b/quickstep/src/com/android/quickstep/util/SplitToConfirmTimings.java index d1ec2b6f23..7557ad1b86 100644 --- a/quickstep/src/com/android/quickstep/util/SplitToConfirmTimings.java +++ b/quickstep/src/com/android/quickstep/util/SplitToConfirmTimings.java @@ -17,6 +17,7 @@ package com.android.quickstep.util; import static com.android.app.animation.Interpolators.EMPHASIZED; +import static com.android.app.animation.Interpolators.LINEAR; import android.view.animation.Interpolator; @@ -31,6 +32,8 @@ abstract class SplitToConfirmTimings implements SplitAnimationTimings { abstract public int getPlaceholderIconFadeInEnd(); abstract public int getStagedRectSlideStart(); abstract public int getStagedRectSlideEnd(); + abstract public int getBackingScrimFadeInStart(); + abstract public int getBackingScrimFadeInEnd(); // Common timings public int getInstructionsFadeStart() { return 0; } @@ -39,6 +42,7 @@ abstract class SplitToConfirmTimings implements SplitAnimationTimings { public Interpolator getStagedRectYInterpolator() { return EMPHASIZED; } public Interpolator getStagedRectScaleXInterpolator() { return EMPHASIZED; } public Interpolator getStagedRectScaleYInterpolator() { return EMPHASIZED; } + public Interpolator getBackingScrimFadeInterpolator() { return LINEAR; } abstract public int getDuration(); @@ -48,4 +52,10 @@ abstract class SplitToConfirmTimings implements SplitAnimationTimings { public float getInstructionsFadeEndOffset() { return (float) getInstructionsFadeEnd() / getDuration(); } + public float getBackingScrimFadeInStartOffset() { + return (float) getBackingScrimFadeInStart() / getDuration(); + } + public float getBackingScrimFadeInEndOffset() { + return (float) getBackingScrimFadeInEnd() / getDuration(); + } } diff --git a/quickstep/src/com/android/quickstep/util/SplitToWorkspaceController.java b/quickstep/src/com/android/quickstep/util/SplitToWorkspaceController.java index 2396512866..4962367bd2 100644 --- a/quickstep/src/com/android/quickstep/util/SplitToWorkspaceController.java +++ b/quickstep/src/com/android/quickstep/util/SplitToWorkspaceController.java @@ -163,9 +163,8 @@ public class SplitToWorkspaceController { new RectF(firstTaskStartingBounds), firstTaskEndingBounds, false /* fadeWithThumbnail */, true /* isStagedTask */); - View mSplitDividerPlaceholderView = recentsView.getSplitSelectController() - .getSplitAnimationController().addDividerPlaceholderViewToAnim(pendingAnimation, - mLauncher, secondTaskEndingBounds, view.getContext()); + View backingScrim = recentsView.getSplitSelectController().getSplitAnimationController() + .addScrimBehindAnim(pendingAnimation, mLauncher, view.getContext()); FloatingTaskView secondFloatingTaskView = FloatingTaskView.getFloatingTaskView(mLauncher, view, bitmap, icon, secondTaskStartingBounds); @@ -197,7 +196,7 @@ public class SplitToWorkspaceController { private void cleanUp() { mLauncher.getDragLayer().removeView(firstFloatingTaskView); mLauncher.getDragLayer().removeView(secondFloatingTaskView); - mLauncher.getDragLayer().removeView(mSplitDividerPlaceholderView); + mLauncher.getDragLayer().removeView(backingScrim); mController.getSplitAnimationController().removeSplitInstructionsView(mLauncher); mController.resetState(); } diff --git a/quickstep/src/com/android/quickstep/util/TabletSplitToConfirmTimings.java b/quickstep/src/com/android/quickstep/util/TabletSplitToConfirmTimings.java index 3756b4af59..d74473ceaf 100644 --- a/quickstep/src/com/android/quickstep/util/TabletSplitToConfirmTimings.java +++ b/quickstep/src/com/android/quickstep/util/TabletSplitToConfirmTimings.java @@ -27,6 +27,8 @@ public class TabletSplitToConfirmTimings public int getPlaceholderIconFadeInEnd() { return 250; } public int getStagedRectSlideStart() { return 0; } public int getStagedRectSlideEnd() { return 500; } + public int getBackingScrimFadeInStart() { return 0; } + public int getBackingScrimFadeInEnd() { return 400; } public int getDuration() { return TABLET_CONFIRM_DURATION; } } diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java index 9096b75eaa..01cc53490f 100644 --- a/quickstep/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/src/com/android/quickstep/views/RecentsView.java @@ -738,7 +738,11 @@ public abstract class RecentsView