From d9aac37c805b58da8a44a1bdc9a977e41b2b855c Mon Sep 17 00:00:00 2001 From: Johannes Gallmann Date: Mon, 5 Dec 2022 16:43:39 +0100 Subject: [PATCH] Fix notification launch animation for split shade The launchAnimationParams contain global coordinates. These need to be translated to local coordinates, since the NotificationStackScrollLayout does not have its origin at (0,0) in the split shade case. Test: Manual, i.e. posting various types of notifications and analyzing the animations in screenrecordings. Bug: 246932690 Change-Id: I9dd233d282d05fc25b3601180c775916ddb5197c --- .../notification/LaunchAnimationParameters.kt | 4 ++- .../NotificationLaunchAnimatorController.kt | 5 ++-- .../row/ExpandableNotificationRow.java | 26 ++++++++++++------- .../stack/NotificationStackScrollLayout.java | 14 +++++++--- 4 files changed, 32 insertions(+), 17 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/LaunchAnimationParameters.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/LaunchAnimationParameters.kt index 42edb309d5773..c22dbf615190a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/LaunchAnimationParameters.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/LaunchAnimationParameters.kt @@ -27,8 +27,10 @@ class LaunchAnimationParameters( /** * The top position of the notification at the start of the animation. This is needed in order * to keep the notification at its place when launching a notification that is clipped rounded. + * This value is in absolute screen coordinates. */ - var startNotificationTop = 0f + var startNotificationTop = 0 + var notificationParentTop = 0 var startClipTopAmount = 0 var parentStartClipTopAmount = 0 var progress = 0f diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorController.kt index 0d35fdce953eb..798bbe8aff7a1 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorController.kt @@ -92,11 +92,12 @@ class NotificationLaunchAnimatorController( ) params.startTranslationZ = notification.translationZ - params.startNotificationTop = notification.translationY + params.startNotificationTop = location[1] + params.notificationParentTop = notificationListContainer + .getViewParentForNotification(notificationEntry).locationOnScreen[1] params.startRoundedTopClipping = roundedTopClipping params.startClipTopAmount = notification.clipTopAmount if (notification.isChildInGroup) { - params.startNotificationTop += notification.notificationParent.translationY val locationOnScreen = notification.notificationParent.locationOnScreen[1] val parentRoundedClip = (clipStartLocation - locationOnScreen).coerceAtLeast(0) params.parentStartRoundedTopClipping = parentRoundedClip diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java index c7c1634ea1055..a487af1998fcd 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java @@ -2223,6 +2223,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView if (mNotificationParent != null) { mNotificationParent.setClipTopAmount(0); } + setTranslationX(0); return; } @@ -2241,6 +2242,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView setTranslationZ(translationZ); float extraWidthForClipping = params.getWidth() - getWidth(); setExtraWidthForClipping(extraWidthForClipping); + int top; if (params.getStartRoundedTopClipping() > 0) { // If we were clipping initially, let's interpolate from the start position to the @@ -2248,20 +2250,22 @@ public class ExpandableNotificationRow extends ActivatableNotificationView float expandProgress = Interpolators.FAST_OUT_SLOW_IN.getInterpolation( params.getProgress(0, NotificationLaunchAnimatorController.ANIMATION_DURATION_TOP_ROUNDING)); - float startTop = params.getStartNotificationTop(); - top = (int) Math.min(MathUtils.lerp(startTop, - params.getTop(), expandProgress), + int startTop = params.getStartNotificationTop(); + top = (int) Math.min(MathUtils.lerp(startTop, params.getTop(), expandProgress), startTop); } else { top = params.getTop(); } int actualHeight = params.getBottom() - top; setActualHeight(actualHeight); + + int notificationStackTop = params.getNotificationParentTop(); + top -= notificationStackTop; int startClipTopAmount = params.getStartClipTopAmount(); int clipTopAmount = (int) MathUtils.lerp(startClipTopAmount, 0, params.getProgress()); if (mNotificationParent != null) { - float parentY = mNotificationParent.getTranslationY(); - top -= parentY; + float parentTranslationY = mNotificationParent.getTranslationY(); + top -= parentTranslationY; mNotificationParent.setTranslationZ(translationZ); // When the expanding notification is below its parent, the parent must be clipped @@ -2270,15 +2274,14 @@ public class ExpandableNotificationRow extends ActivatableNotificationView // pixels to show the expanding notification, while still taking the decreasing // notification clipTopAmount into consideration, so 'top + clipTopAmount'. int parentStartClipTopAmount = params.getParentStartClipTopAmount(); - int parentClipTopAmount = Math.min(parentStartClipTopAmount, - top + clipTopAmount); + int parentClipTopAmount = Math.min(parentStartClipTopAmount, top + clipTopAmount); mNotificationParent.setClipTopAmount(parentClipTopAmount); mNotificationParent.setExtraWidthForClipping(extraWidthForClipping); - float clipBottom = Math.max(params.getBottom(), - parentY + mNotificationParent.getActualHeight() + float clipBottom = Math.max(params.getBottom() - notificationStackTop, + parentTranslationY + mNotificationParent.getActualHeight() - mNotificationParent.getClipBottomAmount()); - float clipTop = Math.min(params.getTop(), parentY); + float clipTop = Math.min(params.getTop() - notificationStackTop, parentTranslationY); int minimumHeightForClipping = (int) (clipBottom - clipTop); mNotificationParent.setMinimumHeightForClipping(minimumHeightForClipping); } else if (startClipTopAmount != 0) { @@ -2286,6 +2289,9 @@ public class ExpandableNotificationRow extends ActivatableNotificationView } setTranslationY(top); + float absoluteCenterX = getLocationOnScreen()[0] + getWidth() / 2f - getTranslationX(); + setTranslationX(params.getCenterX() - absoluteCenterX); + final float maxRadius = getMaxRadius(); mTopRoundnessDuringLaunchAnimation = params.getTopCornerRadius() / maxRadius; mBottomRoundnessDuringLaunchAnimation = params.getBottomCornerRadius() / maxRadius; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java index 21e2bd877baee..d22bfe8b9e3ca 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java @@ -5772,14 +5772,20 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable || mExpandingNotificationRow == null) { return; } - int left = Math.min(mLaunchAnimationParams.getLeft(), mRoundedRectClippingLeft); - int right = Math.max(mLaunchAnimationParams.getRight(), mRoundedRectClippingRight); - int bottom = Math.max(mLaunchAnimationParams.getBottom(), mRoundedRectClippingBottom); + int[] absoluteCoords = new int[2]; + getLocationOnScreen(absoluteCoords); + + int left = Math.min(mLaunchAnimationParams.getLeft() - absoluteCoords[0], + mRoundedRectClippingLeft); + int right = Math.max(mLaunchAnimationParams.getRight() - absoluteCoords[0], + mRoundedRectClippingRight); + int bottom = Math.max(mLaunchAnimationParams.getBottom() - absoluteCoords[1], + mRoundedRectClippingBottom); float expandProgress = Interpolators.FAST_OUT_SLOW_IN.getInterpolation( mLaunchAnimationParams.getProgress(0, NotificationLaunchAnimatorController.ANIMATION_DURATION_TOP_ROUNDING)); int top = (int) Math.min(MathUtils.lerp(mRoundedRectClippingTop, - mLaunchAnimationParams.getTop(), expandProgress), + mLaunchAnimationParams.getTop() - absoluteCoords[1], expandProgress), mRoundedRectClippingTop); float topRadius = mLaunchAnimationParams.getTopCornerRadius(); float bottomRadius = mLaunchAnimationParams.getBottomCornerRadius();