diff options
5 files changed, 108 insertions, 18 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt index d7322a04ba49..fd44f04a0d80 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt @@ -32,6 +32,7 @@ import com.android.systemui.Dumpable import com.android.systemui.Interpolators import com.android.systemui.dump.DumpManager import com.android.systemui.plugins.statusbar.StatusBarStateController +import com.android.systemui.statusbar.notification.ActivityLaunchAnimator import com.android.systemui.statusbar.phone.BiometricUnlockController import com.android.systemui.statusbar.phone.BiometricUnlockController.MODE_WAKE_AND_UNLOCK import com.android.systemui.statusbar.phone.NotificationShadeWindowController @@ -68,6 +69,7 @@ class NotificationShadeDepthController @Inject constructor( private var notificationAnimator: Animator? = null private var updateScheduled: Boolean = false private var shadeExpansion = 0f + private var ignoreShadeBlurUntilHidden: Boolean = false @VisibleForTesting var shadeSpring = DepthAnimation() @VisibleForTesting @@ -83,6 +85,26 @@ class NotificationShadeDepthController @Inject constructor( } /** + * When launching an app from the shade, the animations progress should affect how blurry the + * shade is, overriding the expansion amount. + */ + var notificationLaunchAnimationParams: ActivityLaunchAnimator.ExpandAnimationParameters? = null + set(value) { + field = value + if (value != null) { + scheduleUpdate() + return + } + + if (shadeSpring.radius == 0) { + return + } + ignoreShadeBlurUntilHidden = true + shadeSpring.animateTo(0) + shadeSpring.finishIfRunning() + } + + /** * Blur radius of the wake-up animation on this frame. */ private var wakeAndUnlockBlurRadius = 0 @@ -99,9 +121,19 @@ class NotificationShadeDepthController @Inject constructor( val updateBlurCallback = Choreographer.FrameCallback { updateScheduled = false - var shadeRadius = max(shadeSpring.radius, wakeAndUnlockBlurRadius) - shadeRadius = (shadeRadius * (1f - brightnessMirrorSpring.ratio)).toInt() - val blur = max(shadeRadius, globalActionsSpring.radius) + var shadeRadius = max(shadeSpring.radius, wakeAndUnlockBlurRadius).toFloat() + shadeRadius *= 1f - brightnessMirrorSpring.ratio + val launchProgress = notificationLaunchAnimationParams?.linearProgress ?: 0f + shadeRadius *= (1f - launchProgress) * (1f - launchProgress) + + if (ignoreShadeBlurUntilHidden) { + if (shadeRadius == 0f) { + ignoreShadeBlurUntilHidden = false + } else { + shadeRadius = 0f + } + } + val blur = max(shadeRadius.toInt(), globalActionsSpring.radius) blurUtils.applyBlur(blurRoot?.viewRootImpl ?: root.viewRootImpl, blur) try { wallpaperManager.setWallpaperZoomOut(root.windowToken, @@ -187,7 +219,6 @@ class NotificationShadeDepthController @Inject constructor( if (statusBarStateController.state == StatusBarState.SHADE) { newBlur = blurUtils.blurRadiusOfRatio(shadeExpansion) } - shadeSpring.animateTo(newBlur) } @@ -212,6 +243,9 @@ class NotificationShadeDepthController @Inject constructor( it.println("globalActionsRadius: ${globalActionsSpring.radius}") it.println("brightnessMirrorRadius: ${brightnessMirrorSpring.radius}") it.println("wakeAndUnlockBlur: $wakeAndUnlockBlurRadius") + it.println("notificationLaunchAnimationProgress: " + + "${notificationLaunchAnimationParams?.linearProgress}") + it.println("ignoreShadeBlurUntilHidden: $ignoreShadeBlurUntilHidden") } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java index 7c061574f19c..6aef6b407f37 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java @@ -34,6 +34,7 @@ import android.view.View; import com.android.internal.policy.ScreenDecorationsUtils; import com.android.systemui.Interpolators; +import com.android.systemui.statusbar.NotificationShadeDepthController; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import com.android.systemui.statusbar.notification.stack.NotificationListContainer; import com.android.systemui.statusbar.phone.CollapsedStatusBarFragment; @@ -57,6 +58,7 @@ public class ActivityLaunchAnimator { private final NotificationListContainer mNotificationContainer; private final float mWindowCornerRadius; private final NotificationShadeWindowViewController mNotificationShadeWindowViewController; + private final NotificationShadeDepthController mDepthController; private Callback mCallback; private final Runnable mTimeoutRunnable = () -> { setAnimationPending(false); @@ -70,9 +72,11 @@ public class ActivityLaunchAnimator { NotificationShadeWindowViewController notificationShadeWindowViewController, Callback callback, NotificationPanelViewController notificationPanel, + NotificationShadeDepthController depthController, NotificationListContainer container) { mNotificationPanel = notificationPanel; mNotificationContainer = container; + mDepthController = depthController; mNotificationShadeWindowViewController = notificationShadeWindowViewController; mCallback = callback; mWindowCornerRadius = ScreenDecorationsUtils @@ -212,7 +216,7 @@ public class ActivityLaunchAnimator { mWindowCornerRadius, progress); applyParamsToWindow(primary); applyParamsToNotification(mParams); - applyParamsToNotificationList(mParams); + applyParamsToNotificationShade(mParams); } }); anim.addListener(new AnimatorListenerAdapter() { @@ -256,14 +260,15 @@ public class ActivityLaunchAnimator { if (!running) { mCallback.onExpandAnimationFinished(mIsFullScreenLaunch); applyParamsToNotification(null); - applyParamsToNotificationList(null); + applyParamsToNotificationShade(null); } } - private void applyParamsToNotificationList(ExpandAnimationParameters params) { + private void applyParamsToNotificationShade(ExpandAnimationParameters params) { mNotificationContainer.applyExpandAnimationParams(params); mNotificationPanel.applyExpandAnimationParams(params); + mDepthController.setNotificationLaunchAnimationParams(params); } private void applyParamsToNotification(ExpandAnimationParameters params) { @@ -295,7 +300,7 @@ public class ActivityLaunchAnimator { }; public static class ExpandAnimationParameters { - float linearProgress; + public float linearProgress; int[] startPosition; float startTranslationZ; int left; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java index ae2c78b121ba..34bca7449589 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java @@ -1235,6 +1235,7 @@ public class StatusBar extends SystemUI implements DemoMode, // Set up the initial notification state. mActivityLaunchAnimator = new ActivityLaunchAnimator( mNotificationShadeWindowViewController, this, mNotificationPanelViewController, + mNotificationShadeDepthControllerLazy.get(), (NotificationListContainer) mStackScroller); // TODO: inject this. diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt index 1e3636b4ed63..6b7a3bfce5ad 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt @@ -26,6 +26,7 @@ import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.dump.DumpManager import com.android.systemui.plugins.statusbar.StatusBarStateController +import com.android.systemui.statusbar.notification.ActivityLaunchAnimator import com.android.systemui.statusbar.phone.BiometricUnlockController import com.android.systemui.statusbar.phone.NotificationShadeWindowController import com.android.systemui.statusbar.policy.KeyguardStateController @@ -43,6 +44,7 @@ import org.mockito.Mockito.anyFloat import org.mockito.Mockito.anyString import org.mockito.Mockito.clearInvocations import org.mockito.Mockito.doThrow +import org.mockito.Mockito.never import org.mockito.Mockito.verify import org.mockito.junit.MockitoJUnit @@ -128,6 +130,23 @@ class NotificationShadeDepthControllerTest : SysuiTestCase() { } @Test + fun updateBlurCallback_setsBlur_whenExpanded() { + `when`(shadeSpring.radius).thenReturn(maxBlur) + notificationShadeDepthController.updateBlurCallback.doFrame(0) + verify(blurUtils).applyBlur(any(), eq(maxBlur)) + } + + @Test + fun updateBlurCallback_appLaunchAnimation_overridesZoom() { + `when`(shadeSpring.radius).thenReturn(maxBlur) + val animProgress = ActivityLaunchAnimator.ExpandAnimationParameters() + animProgress.linearProgress = 1f + notificationShadeDepthController.notificationLaunchAnimationParams = animProgress + notificationShadeDepthController.updateBlurCallback.doFrame(0) + verify(blurUtils).applyBlur(any(), eq(0)) + } + + @Test fun updateBlurCallback_invalidWindow() { doThrow(IllegalArgumentException("test exception")).`when`(wallpaperManager) .setWallpaperZoomOut(any(), anyFloat()) @@ -159,6 +178,24 @@ class NotificationShadeDepthControllerTest : SysuiTestCase() { verify(blurUtils).applyBlur(safeEq(viewRootImpl), eq(0)) } + @Test + fun setNotificationLaunchAnimationParams_schedulesFrame() { + val animProgress = ActivityLaunchAnimator.ExpandAnimationParameters() + animProgress.linearProgress = 0.5f + notificationShadeDepthController.notificationLaunchAnimationParams = animProgress + verify(choreographer).postFrameCallback( + eq(notificationShadeDepthController.updateBlurCallback)) + } + + @Test + fun setNotificationLaunchAnimationParams_whennNull_ignoresIfShadeHasNoBlur() { + val animProgress = ActivityLaunchAnimator.ExpandAnimationParameters() + animProgress.linearProgress = 0.5f + `when`(shadeSpring.radius).thenReturn(0) + notificationShadeDepthController.notificationLaunchAnimationParams = animProgress + verify(shadeSpring, never()).animateTo(anyInt(), any()) + } + private fun <T : Any> safeEq(value: T): T { return eq(value) ?: value } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimatorTest.java index a07cfc3c3226..cdef49d6c94d 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimatorTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimatorTest.java @@ -19,7 +19,6 @@ package com.android.systemui.statusbar.notification; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -31,6 +30,7 @@ import android.view.RemoteAnimationAdapter; import android.view.View; import com.android.systemui.SysuiTestCase; +import com.android.systemui.statusbar.NotificationShadeDepthController; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import com.android.systemui.statusbar.notification.stack.NotificationListContainer; import com.android.systemui.statusbar.phone.NotificationPanelViewController; @@ -39,8 +39,12 @@ import com.android.systemui.statusbar.phone.NotificationShadeWindowViewControlle import org.junit.Assert; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; @SmallTest @RunWith(AndroidTestingRunner.class) @@ -48,14 +52,22 @@ import org.junit.runner.RunWith; public class ActivityLaunchAnimatorTest extends SysuiTestCase { private ActivityLaunchAnimator mLaunchAnimator; - private ActivityLaunchAnimator.Callback mCallback = mock(ActivityLaunchAnimator.Callback.class); - private NotificationShadeWindowViewController mNotificationShadeWindowViewController = mock( - NotificationShadeWindowViewController.class); - private NotificationShadeWindowView mNotificationShadeWindowView = mock( - NotificationShadeWindowView.class); - private NotificationListContainer mNotificationContainer - = mock(NotificationListContainer.class); - private ExpandableNotificationRow mRow = mock(ExpandableNotificationRow.class); + @Mock + private ActivityLaunchAnimator.Callback mCallback; + @Mock + private NotificationShadeWindowViewController mNotificationShadeWindowViewController; + @Mock + private NotificationShadeWindowView mNotificationShadeWindowView; + @Mock + private NotificationListContainer mNotificationContainer; + @Mock + private ExpandableNotificationRow mRow; + @Mock + private NotificationShadeDepthController mNotificationShadeDepthController; + @Mock + private NotificationPanelViewController mNotificationPanelViewController; + @Rule + public MockitoRule rule = MockitoJUnit.rule(); @Before public void setUp() throws Exception { @@ -66,7 +78,8 @@ public class ActivityLaunchAnimatorTest extends SysuiTestCase { mLaunchAnimator = new ActivityLaunchAnimator( mNotificationShadeWindowViewController, mCallback, - mock(NotificationPanelViewController.class), + mNotificationPanelViewController, + mNotificationShadeDepthController, mNotificationContainer); } |