Merge "[Motion] Split-shade expansion on LS: move keyguard views" into tm-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
c00f6054af
@@ -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;
|
||||
}
|
||||
|
||||
@@ -136,6 +136,13 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
|
||||
return mKeyguardClockSwitchController.hasCustomClock();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
@@ -291,6 +291,18 @@ class MediaHierarchyManager @Inject constructor(
|
||||
fullShadeTransitionProgress = progress
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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>()
|
||||
@@ -259,6 +260,49 @@ class LockscreenShadeTransitionControllerTest : SysuiTestCase() {
|
||||
verify(depthController, never()).transitionToFullShadeProgress
|
||||
}
|
||||
|
||||
@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()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user