diff options
9 files changed, 211 insertions, 14 deletions
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java index 31f466f0fdf9..087817f0ec81 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java @@ -113,6 +113,22 @@ public class KeyguardStatusView extends GridLayout { } } + /** Sets a translationY value on every child view except for the media view. */ + public void setChildrenTranslationYExcludingMediaView(float translationY) { + setChildrenTranslationYExcluding(translationY, Set.of(mMediaHostContainer)); + } + + /** Sets a translationY value on every view except for the views in the provided set. */ + private void setChildrenTranslationYExcluding(float translationY, Set<View> excludedViews) { + for (int i = 0; i < mStatusViewContainer.getChildCount(); i++) { + final View child = mStatusViewContainer.getChildAt(i); + + if (!excludedViews.contains(child)) { + child.setTranslationY(translationY); + } + } + } + public float getChildrenAlphaExcludingSmartSpace() { return mChildrenAlphaExcludingSmartSpace; } diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java index af3da9f940bd..14c9cb2022bc 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java @@ -137,6 +137,13 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV } /** + * Sets a translationY on the views on the keyguard, except on the media view. + */ + public void setTranslationYExcludingMedia(float translationY) { + mView.setChildrenTranslationYExcludingMediaView(translationY); + } + + /** * Set keyguard status view alpha. */ public void setAlpha(float alpha) { diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt index 18b6699c80e9..7a4dee294dd6 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt +++ b/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt @@ -292,6 +292,18 @@ class MediaHierarchyManager @Inject constructor( } /** + * Returns the amount of translationY of the media container, during the current guided + * transformation, if running. If there is no guided transformation running, it will return 0. + */ + fun getGuidedTransformationTranslationY(): Int { + if (!isCurrentlyInGuidedTransformation()) { + return -1 + } + val startHost = getHost(previousLocation) ?: return 0 + return targetBounds.top - startHost.currentBounds.top + } + + /** * Is the shade currently collapsing from the expanded qs? If we're on the lockscreen and in qs, * we wouldn't want to transition in that case. */ diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt index 1ab03455cca2..ab4d0dd355f3 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt @@ -406,6 +406,7 @@ class LockscreenShadeTransitionController @Inject constructor( mediaHierarchyManager.setTransitionToFullShadeAmount(field) transitionToShadeAmountCommon(field) + transitionToShadeAmountKeyguard(field) } } } @@ -420,11 +421,6 @@ class LockscreenShadeTransitionController @Inject constructor( val scrimProgress = MathUtils.saturate(dragDownAmount / scrimTransitionDistance) scrimController.setTransitionToFullShadeProgress(scrimProgress) - // Fade out all content only visible on the lockscreen - val npvcProgress = - MathUtils.saturate(dragDownAmount / npvcKeyguardContentAlphaTransitionDistance) - notificationPanelController.setKeyguardOnlyContentAlpha(1.0f - npvcProgress) - if (depthControllerTransitionDistance > 0) { val depthProgress = MathUtils.saturate(dragDownAmount / depthControllerTransitionDistance) @@ -438,6 +434,22 @@ class LockscreenShadeTransitionController @Inject constructor( centralSurfaces.setTransitionToFullShadeProgress(statusBarProgress) } + private fun transitionToShadeAmountKeyguard(dragDownAmount: Float) { + // Fade out all content only visible on the lockscreen + val keyguardAlphaProgress = + MathUtils.saturate(dragDownAmount / npvcKeyguardContentAlphaTransitionDistance) + val keyguardAlpha = 1f - keyguardAlphaProgress + val keyguardTranslationY = if (useSplitShade) { + // On split-shade, the translationY of the keyguard should stay in sync with the + // translation of media. + mediaHierarchyManager.getGuidedTransformationTranslationY() + } else { + 0 + } + notificationPanelController + .setKeyguardTransitionProgress(keyguardAlpha, keyguardTranslationY) + } + private fun setDragDownAmountAnimated( target: Float, delay: Long = 0, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java index 0a2ea4cfe11a..cbdf5c8017c6 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java @@ -616,6 +616,11 @@ public class NotificationPanelViewController extends PanelViewController { */ private float mKeyguardOnlyContentAlpha = 1.0f; + /** + * The translationY of the views which only show on the keyguard but in shade / shade locked. + */ + private int mKeyguardOnlyTransitionTranslationY = 0; + private float mUdfpsMaxYBurnInOffset; /** @@ -1575,6 +1580,8 @@ public class NotificationPanelViewController extends PanelViewController { private void updateClock() { float alpha = mClockPositionResult.clockAlpha * mKeyguardOnlyContentAlpha; mKeyguardStatusViewController.setAlpha(alpha); + mKeyguardStatusViewController + .setTranslationYExcludingMedia(mKeyguardOnlyTransitionTranslationY); if (mKeyguardQsUserSwitchController != null) { mKeyguardQsUserSwitchController.setAlpha(alpha); } @@ -2732,11 +2739,12 @@ public class NotificationPanelViewController extends PanelViewController { } /** - * Set the alpha of the keyguard elements which only show on the lockscreen, but not in - * shade locked / shade. This is used when dragging down to the full shade. + * Set the alpha and translationY of the keyguard elements which only show on the lockscreen, + * but not in shade locked / shade. This is used when dragging down to the full shade. */ - public void setKeyguardOnlyContentAlpha(float keyguardAlpha) { + public void setKeyguardTransitionProgress(float keyguardAlpha, int keyguardTranslationY) { mKeyguardOnlyContentAlpha = Interpolators.ALPHA_IN.getInterpolation(keyguardAlpha); + mKeyguardOnlyTransitionTranslationY = keyguardTranslationY; if (mBarState == KEYGUARD) { // If the animator is running, it's already fading out the content and this is a reset mBottomAreaShadeAlpha = mKeyguardOnlyContentAlpha; diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerTest.java index 2fc912288623..1753157c631d 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerTest.java @@ -112,4 +112,13 @@ public class KeyguardStatusViewControllerTest extends SysuiTestCase { mKeyguardUpdateMonitorCallbackCaptor.getValue().onUserSwitchComplete(0); verify(mKeyguardClockSwitchController).refreshFormat(); } + + @Test + public void setTranslationYExcludingMedia_forwardsCallToView() { + float translationY = 123f; + + mController.setTranslationYExcludingMedia(translationY); + + verify(mKeyguardStatusView).setChildrenTranslationYExcludingMediaView(translationY); + } } diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.kt new file mode 100644 index 000000000000..ce44f4d82d69 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.kt @@ -0,0 +1,55 @@ +package com.android.keyguard + +import android.test.suitebuilder.annotation.SmallTest +import android.testing.AndroidTestingRunner +import android.testing.TestableLooper.RunWithLooper +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import com.android.systemui.R +import com.android.systemui.SysuiTestCase +import com.android.systemui.util.children +import com.google.common.truth.Truth.assertThat +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith + +@SmallTest +@RunWith(AndroidTestingRunner::class) +@RunWithLooper(setAsMainLooper = true) +class KeyguardStatusViewTest : SysuiTestCase() { + + private lateinit var keyguardStatusView: KeyguardStatusView + private val mediaView: View + get() = keyguardStatusView.findViewById(R.id.status_view_media_container) + private val statusViewContainer: ViewGroup + get() = keyguardStatusView.findViewById(R.id.status_view_container) + private val childrenExcludingMedia + get() = statusViewContainer.children.filter { it != mediaView } + + @Before + fun setUp() { + keyguardStatusView = LayoutInflater.from(context) + .inflate(R.layout.keyguard_status_view, /* root= */ null) as KeyguardStatusView + } + + @Test + fun setChildrenTranslationYExcludingMediaView_mediaViewIsNotTranslated() { + val translationY = 1234f + + keyguardStatusView.setChildrenTranslationYExcludingMediaView(translationY) + + assertThat(mediaView.translationY).isEqualTo(0) + } + + @Test + fun setChildrenTranslationYExcludingMediaView_childrenAreTranslated() { + val translationY = 1234f + + keyguardStatusView.setChildrenTranslationYExcludingMediaView(translationY) + + childrenExcludingMedia.forEach { + assertThat(it.translationY).isEqualTo(translationY) + } + } +}
\ No newline at end of file diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaHierarchyManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaHierarchyManagerTest.kt index b359ae5317b1..8e201b5a3e87 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaHierarchyManagerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaHierarchyManagerTest.kt @@ -117,9 +117,9 @@ class MediaHierarchyManagerTest : SysuiTestCase() { dreamOverlayStateController) verify(wakefulnessLifecycle).addObserver(wakefullnessObserver.capture()) verify(statusBarStateController).addCallback(statusBarCallback.capture()) - setupHost(lockHost, MediaHierarchyManager.LOCATION_LOCKSCREEN) - setupHost(qsHost, MediaHierarchyManager.LOCATION_QS) - setupHost(qqsHost, MediaHierarchyManager.LOCATION_QQS) + setupHost(lockHost, MediaHierarchyManager.LOCATION_LOCKSCREEN, LOCKSCREEN_TOP) + setupHost(qsHost, MediaHierarchyManager.LOCATION_QS, QS_TOP) + setupHost(qqsHost, MediaHierarchyManager.LOCATION_QQS, QQS_TOP) `when`(statusBarStateController.state).thenReturn(StatusBarState.SHADE) `when`(mediaCarouselController.mediaCarouselScrollHandler) .thenReturn(mediaCarouselScrollHandler) @@ -130,9 +130,9 @@ class MediaHierarchyManagerTest : SysuiTestCase() { clearInvocations(mediaCarouselController) } - private fun setupHost(host: MediaHost, location: Int) { + private fun setupHost(host: MediaHost, location: Int, top: Int) { `when`(host.location).thenReturn(location) - `when`(host.currentBounds).thenReturn(Rect()) + `when`(host.currentBounds).thenReturn(Rect(0, top, 0, top)) `when`(host.hostView).thenReturn(uniqueObjectHostView) `when`(host.visible).thenReturn(true) mediaHiearchyManager.register(host) @@ -257,6 +257,20 @@ class MediaHierarchyManagerTest : SysuiTestCase() { verify(mediaCarouselController).closeGuts() } + @Test + fun getGuidedTransformationTranslationY_notInGuidedTransformation_returnsNegativeNumber() { + assertThat(mediaHiearchyManager.getGuidedTransformationTranslationY()).isLessThan(0) + } + + @Test + fun getGuidedTransformationTranslationY_inGuidedTransformation_returnsCurrentTranslation() { + enterGuidedTransformation() + + val expectedTranslation = LOCKSCREEN_TOP - QS_TOP + assertThat(mediaHiearchyManager.getGuidedTransformationTranslationY()) + .isEqualTo(expectedTranslation) + } + private fun enableSplitShade() { context.getOrCreateTestableResources().addOverride( R.bool.config_use_split_notification_shade, true @@ -284,4 +298,16 @@ class MediaHierarchyManagerTest : SysuiTestCase() { private fun expandQS() { mediaHiearchyManager.qsExpansion = 1.0f } + + private fun enterGuidedTransformation() { + mediaHiearchyManager.qsExpansion = 1.0f + goToLockscreen() + mediaHiearchyManager.setTransitionToFullShadeAmount(123f) + } + + companion object { + private const val QQS_TOP = 123 + private const val QS_TOP = 456 + private const val LOCKSCREEN_TOP = 789 + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt index 067caa98102b..64a0a2342a44 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt @@ -44,6 +44,7 @@ import org.mockito.Mockito.never import org.mockito.Mockito.verify import org.mockito.junit.MockitoJUnit import org.mockito.Mockito.`when` as whenever +import org.mockito.ArgumentMatchers.eq private fun <T> anyObject(): T { return Mockito.anyObject<T>() @@ -260,6 +261,49 @@ class LockscreenShadeTransitionControllerTest : SysuiTestCase() { } @Test + fun setDragAmount_setsKeyguardTransitionProgress() { + transitionController.dragDownAmount = 10f + + verify(notificationPanelController).setKeyguardTransitionProgress(anyFloat(), anyInt()) + } + + @Test + fun setDragAmount_setsKeyguardAlphaBasedOnDistance() { + val alphaDistance = context.resources.getDimensionPixelSize( + R.dimen.lockscreen_shade_npvc_keyguard_content_alpha_transition_distance) + transitionController.dragDownAmount = 10f + + val expectedAlpha = 1 - 10f / alphaDistance + verify(notificationPanelController) + .setKeyguardTransitionProgress(eq(expectedAlpha), anyInt()) + } + + @Test + fun setDragAmount_notInSplitShade_setsKeyguardTranslationToZero() { + val mediaTranslationY = 123 + disableSplitShade() + whenever(mediaHierarchyManager.getGuidedTransformationTranslationY()) + .thenReturn(mediaTranslationY) + + transitionController.dragDownAmount = 10f + + verify(notificationPanelController).setKeyguardTransitionProgress(anyFloat(), eq(0)) + } + + @Test + fun setDragAmount_inSplitShade_setsKeyguardTranslationBasedOnMediaTranslation() { + val mediaTranslationY = 123 + enableSplitShade() + whenever(mediaHierarchyManager.getGuidedTransformationTranslationY()) + .thenReturn(mediaTranslationY) + + transitionController.dragDownAmount = 10f + + verify(notificationPanelController) + .setKeyguardTransitionProgress(anyFloat(), eq(mediaTranslationY)) + } + + @Test fun setDragDownAmount_setsValueOnMediaHierarchyManager() { transitionController.dragDownAmount = 10f @@ -276,8 +320,16 @@ class LockscreenShadeTransitionControllerTest : SysuiTestCase() { } private fun enableSplitShade() { + setSplitShadeEnabled(true) + } + + private fun disableSplitShade() { + setSplitShadeEnabled(false) + } + + private fun setSplitShadeEnabled(enabled: Boolean) { context.getOrCreateTestableResources().addOverride( - R.bool.config_use_split_notification_shade, true + R.bool.config_use_split_notification_shade, enabled ) configurationController.notifyConfigurationChanged() } |