[Motion] Split-shade expansion on LS: adjust timing for notifications scrim

- Delay the fade in start
- Shorten the fade duration

Test: Unit tests + Manually
Fixes: 222034044
Change-Id: I844a1a925eb3dcd10598ff1174b0c50c68f7db1b
This commit is contained in:
Christian Göllner
2022-03-10 17:01:42 +01:00
parent c515a0aed9
commit ef77925ac0
8 changed files with 171 additions and 24 deletions

View File

@@ -53,6 +53,14 @@
the shade (in alpha) -->
<dimen name="lockscreen_shade_scrim_transition_distance">80dp</dimen>
<!-- The notifications scrim transition should start when the other scrims' transition is at
95%. -->
<dimen name="lockscreen_shade_notifications_scrim_transition_delay">76dp</dimen>
<!-- The notifications scrim transition duration is 66.6% of the duration of the other scrims'
transition. -->
<dimen name="lockscreen_shade_notifications_scrim_transition_distance">53.28dp</dimen>
<!-- Distance that the full shade transition takes in order for the keyguard content on
NotificationPanelViewController to fully fade (e.g. Clock & Smartspace) -->
<dimen name="lockscreen_shade_npvc_keyguard_content_alpha_transition_distance">80dp</dimen>

View File

@@ -1138,6 +1138,12 @@
the shade (in alpha) -->
<dimen name="lockscreen_shade_scrim_transition_distance">@dimen/lockscreen_shade_full_transition_distance</dimen>
<!-- Distance that it takes in order for the notifications scrim fade in to start. -->
<dimen name="lockscreen_shade_notifications_scrim_transition_delay">0dp</dimen>
<!-- Distance that it takes for the notifications scrim to fully fade if after it started. -->
<dimen name="lockscreen_shade_notifications_scrim_transition_distance">@dimen/lockscreen_shade_scrim_transition_distance</dimen>
<!-- Distance that the full shade transition takes in order for the keyguard content on
NotificationPanelViewController to fully fade (e.g. Clock & Smartspace) -->
<dimen name="lockscreen_shade_npvc_keyguard_content_alpha_transition_distance">@dimen/lockscreen_shade_full_transition_distance</dimen>

View File

@@ -115,6 +115,16 @@ class LockscreenShadeTransitionController @Inject constructor(
*/
private var scrimTransitionDistance = 0
/**
* Distance that it takes in order for the notifications scrim fade in to start.
*/
private var notificationsScrimTransitionDelay = 0
/**
* Distance that it takes for the notifications scrim to fully fade if after it started.
*/
private var notificationsScrimTransitionDistance = 0
/**
* Distance that the full shade transition takes in order for the notification shelf to fully
* expand.
@@ -225,6 +235,10 @@ class LockscreenShadeTransitionController @Inject constructor(
R.dimen.lockscreen_shade_transition_by_tap_distance)
scrimTransitionDistance = context.resources.getDimensionPixelSize(
R.dimen.lockscreen_shade_scrim_transition_distance)
notificationsScrimTransitionDelay = context.resources.getDimensionPixelSize(
R.dimen.lockscreen_shade_notifications_scrim_transition_delay)
notificationsScrimTransitionDistance = context.resources.getDimensionPixelSize(
R.dimen.lockscreen_shade_notifications_scrim_transition_distance)
notificationShelfTransitionDistance = context.resources.getDimensionPixelSize(
R.dimen.lockscreen_shade_notif_shelf_transition_distance)
qsTransitionDistance = context.resources.getDimensionPixelSize(
@@ -405,6 +419,7 @@ class LockscreenShadeTransitionController @Inject constructor(
false /* animate */, 0 /* delay */)
mediaHierarchyManager.setTransitionToFullShadeAmount(field)
transitionToShadeAmountScrim(field)
transitionToShadeAmountCommon(field)
transitionToShadeAmountKeyguard(field)
}
@@ -417,10 +432,15 @@ class LockscreenShadeTransitionController @Inject constructor(
var qSDragProgress = 0f
private set
private fun transitionToShadeAmountCommon(dragDownAmount: Float) {
private fun transitionToShadeAmountScrim(dragDownAmount: Float) {
val scrimProgress = MathUtils.saturate(dragDownAmount / scrimTransitionDistance)
scrimController.setTransitionToFullShadeProgress(scrimProgress)
val notificationsScrimDragAmount = dragDownAmount - notificationsScrimTransitionDelay
val notificationsScrimProgress = MathUtils.saturate(
notificationsScrimDragAmount / notificationsScrimTransitionDistance)
scrimController.setTransitionToFullShadeProgress(scrimProgress, notificationsScrimProgress)
}
private fun transitionToShadeAmountCommon(dragDownAmount: Float) {
if (depthControllerTransitionDistance > 0) {
val depthProgress =
MathUtils.saturate(dragDownAmount / depthControllerTransitionDistance)

View File

@@ -115,6 +115,15 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
*/
private float mTransitionToFullShadeProgress;
/**
* Same as {@link #mTransitionToFullShadeProgress}, but specifically for the notifications scrim
* on the lock screen.
*
* On split shade lock screen we want the different scrims to fade in at different times and
* rates.
*/
private float mTransitionToLockScreenFullShadeNotificationsProgress;
/**
* If we're currently transitioning to the full shade.
*/
@@ -574,11 +583,17 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
* Set the amount of progress we are currently in if we're transitioning to the full shade.
* 0.0f means we're not transitioning yet, while 1 means we're all the way in the full
* shade.
*
* @param progress the progress for all scrims.
* @param lockScreenNotificationsProgress the progress specifically for the notifications scrim.
*/
public void setTransitionToFullShadeProgress(float progress) {
if (progress != mTransitionToFullShadeProgress) {
public void setTransitionToFullShadeProgress(float progress,
float lockScreenNotificationsProgress) {
if (progress != mTransitionToFullShadeProgress || lockScreenNotificationsProgress
!= mTransitionToLockScreenFullShadeNotificationsProgress) {
mTransitionToFullShadeProgress = progress;
setTransitionToFullShade(progress > 0.0f);
mTransitionToLockScreenFullShadeNotificationsProgress = lockScreenNotificationsProgress;
setTransitionToFullShade(progress > 0.0f || lockScreenNotificationsProgress > 0.0f);
applyAndDispatchState();
}
}
@@ -754,12 +769,13 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
} else {
mNotificationsAlpha = Math.max(1.0f - getInterpolatedFraction(), mQsExpansion);
}
if (mState == ScrimState.KEYGUARD && mTransitionToFullShadeProgress > 0.0f) {
if (mState == ScrimState.KEYGUARD
&& mTransitionToLockScreenFullShadeNotificationsProgress > 0.0f) {
// Interpolate the notification alpha when transitioning!
mNotificationsAlpha = MathUtils.lerp(
mNotificationsAlpha,
getInterpolatedFraction(),
mTransitionToFullShadeProgress);
mTransitionToLockScreenFullShadeNotificationsProgress);
}
mNotificationsTint = mState.getNotifTint();
mBehindTint = behindTint;

View File

@@ -208,6 +208,11 @@ public abstract class SysuiTestCase {
}
}
/** Delegates to {@link android.testing.TestableResources#addOverride(int, Object)}. */
protected void overrideResource(int resourceId, Object value) {
mContext.getOrCreateTestableResources().addOverride(resourceId, value);
}
public static final class EmptyRunnable implements Runnable {
public void run() {
}

View File

@@ -1,5 +1,6 @@
package com.android.systemui.statusbar
import org.mockito.Mockito.`when` as whenever
import android.test.suitebuilder.annotation.SmallTest
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
@@ -18,11 +19,11 @@ import com.android.systemui.statusbar.notification.row.NotificationTestHelper
import com.android.systemui.statusbar.notification.stack.AmbientState
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController
import com.android.systemui.statusbar.phone.CentralSurfaces
import com.android.systemui.statusbar.phone.KeyguardBypassController
import com.android.systemui.statusbar.phone.LSShadeTransitionLogger
import com.android.systemui.statusbar.phone.NotificationPanelViewController
import com.android.systemui.statusbar.phone.ScrimController
import com.android.systemui.statusbar.phone.CentralSurfaces
import com.android.systemui.statusbar.policy.FakeConfigurationController
import org.junit.After
import org.junit.Assert.assertFalse
@@ -37,14 +38,13 @@ import org.mockito.ArgumentMatchers.anyBoolean
import org.mockito.ArgumentMatchers.anyFloat
import org.mockito.ArgumentMatchers.anyInt
import org.mockito.ArgumentMatchers.anyLong
import org.mockito.ArgumentMatchers.eq
import org.mockito.Mock
import org.mockito.Mockito
import org.mockito.Mockito.clearInvocations
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>()
@@ -231,7 +231,7 @@ class LockscreenShadeTransitionControllerTest : SysuiTestCase() {
transitionController.dragDownAmount = 10f
verify(nsslController, never()).setTransitionToFullShadeAmount(anyFloat(), anyFloat())
verify(mediaHierarchyManager, never()).setTransitionToFullShadeAmount(anyFloat())
verify(scrimController, never()).setTransitionToFullShadeProgress(anyFloat())
verify(scrimController, never()).setTransitionToFullShadeProgress(anyFloat(), anyFloat())
verify(notificationPanelController, never()).setTransitionToFullShadeAmount(anyFloat(),
anyBoolean(), anyLong())
verify(qS, never()).setTransitionToFullShadeAmount(anyFloat(), anyFloat())
@@ -242,7 +242,7 @@ class LockscreenShadeTransitionControllerTest : SysuiTestCase() {
transitionController.dragDownAmount = 10f
verify(nsslController).setTransitionToFullShadeAmount(anyFloat(), anyFloat())
verify(mediaHierarchyManager).setTransitionToFullShadeAmount(anyFloat())
verify(scrimController).setTransitionToFullShadeProgress(anyFloat())
verify(scrimController).setTransitionToFullShadeProgress(anyFloat(), anyFloat())
verify(notificationPanelController).setTransitionToFullShadeAmount(anyFloat(),
anyBoolean(), anyLong())
verify(qS).setTransitionToFullShadeAmount(anyFloat(), anyFloat())
@@ -310,6 +310,75 @@ class LockscreenShadeTransitionControllerTest : SysuiTestCase() {
verify(mediaHierarchyManager).setTransitionToFullShadeAmount(10f)
}
@Test
fun setDragAmount_setsScrimProgressBasedOnScrimDistance() {
val distance = 10
context.orCreateTestableResources
.addOverride(R.dimen.lockscreen_shade_scrim_transition_distance, distance)
configurationController.notifyConfigurationChanged()
transitionController.dragDownAmount = 5f
verify(scrimController).transitionToFullShadeProgress(
progress = eq(0.5f),
lockScreenNotificationsProgress = anyFloat()
)
}
@Test
fun setDragAmount_setsNotificationsScrimProgressBasedOnNotificationsScrimDistanceAndDelay() {
val distance = 100
val delay = 10
context.orCreateTestableResources.addOverride(
R.dimen.lockscreen_shade_notifications_scrim_transition_distance, distance)
context.orCreateTestableResources.addOverride(
R.dimen.lockscreen_shade_notifications_scrim_transition_delay, delay)
configurationController.notifyConfigurationChanged()
transitionController.dragDownAmount = 20f
verify(scrimController).transitionToFullShadeProgress(
progress = anyFloat(),
lockScreenNotificationsProgress = eq(0.1f)
)
}
@Test
fun setDragAmount_dragAmountLessThanNotifDelayDistance_setsNotificationsScrimProgressToZero() {
val distance = 100
val delay = 50
context.orCreateTestableResources.addOverride(
R.dimen.lockscreen_shade_notifications_scrim_transition_distance, distance)
context.orCreateTestableResources.addOverride(
R.dimen.lockscreen_shade_notifications_scrim_transition_delay, delay)
configurationController.notifyConfigurationChanged()
transitionController.dragDownAmount = 20f
verify(scrimController).transitionToFullShadeProgress(
progress = anyFloat(),
lockScreenNotificationsProgress = eq(0f)
)
}
@Test
fun setDragAmount_dragAmountMoreThanTotalDistance_setsNotificationsScrimProgressToOne() {
val distance = 100
val delay = 50
context.orCreateTestableResources.addOverride(
R.dimen.lockscreen_shade_notifications_scrim_transition_distance, distance)
context.orCreateTestableResources.addOverride(
R.dimen.lockscreen_shade_notifications_scrim_transition_delay, delay)
configurationController.notifyConfigurationChanged()
transitionController.dragDownAmount = 999999f
verify(scrimController).transitionToFullShadeProgress(
progress = anyFloat(),
lockScreenNotificationsProgress = eq(1f)
)
}
@Test
fun setDragDownAmount_inSplitShade_setsValueOnMediaHierarchyManager() {
enableSplitShade()
@@ -328,9 +397,21 @@ class LockscreenShadeTransitionControllerTest : SysuiTestCase() {
}
private fun setSplitShadeEnabled(enabled: Boolean) {
context.getOrCreateTestableResources().addOverride(
R.bool.config_use_split_notification_shade, enabled
)
overrideResource(R.bool.config_use_split_notification_shade, enabled)
configurationController.notifyConfigurationChanged()
}
/**
* Wrapper around [ScrimController.transitionToFullShadeProgress] that has named parameters for
* clarify and easier refactoring of parameter names.
*/
private fun ScrimController.transitionToFullShadeProgress(
progress: Float,
lockScreenNotificationsProgress: Float
) {
scrimController.setTransitionToFullShadeProgress(
progress,
lockScreenNotificationsProgress
)
}
}

View File

@@ -6,7 +6,6 @@ import android.view.View
import android.view.ViewGroup
import android.view.WindowInsets
import android.view.WindowManagerPolicyConstants
import androidx.annotation.AnyRes
import androidx.annotation.IdRes
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.constraintlayout.widget.ConstraintSet
@@ -104,10 +103,6 @@ class NotificationQSContainerControllerTest : SysuiTestCase() {
windowInsetsCallback = windowInsetsCallbackCaptor.value
}
private fun overrideResource(@AnyRes id: Int, value: Any) {
mContext.orCreateTestableResources.addOverride(id, value)
}
@Test
fun testTaskbarVisibleInSplitShade() {
enableSplitShade()

View File

@@ -16,7 +16,6 @@
package com.android.systemui.statusbar.phone;
import static com.android.systemui.statusbar.phone.ScrimController.KEYGUARD_SCRIM_ALPHA;
import static com.android.systemui.statusbar.phone.ScrimController.OPAQUE;
import static com.android.systemui.statusbar.phone.ScrimController.SEMI_TRANSPARENT;
import static com.android.systemui.statusbar.phone.ScrimController.TRANSPARENT;
@@ -1263,19 +1262,36 @@ public class ScrimControllerTest extends SysuiTestCase {
mScrimController.setClipsQsScrim(true);
float progress = 0.5f;
mScrimController.setTransitionToFullShadeProgress(progress);
float lsNotifProgress = 0.3f;
mScrimController.setTransitionToFullShadeProgress(progress, lsNotifProgress);
assertEquals(MathUtils.lerp(keyguardAlpha, shadeLockedAlpha, progress),
mNotificationsScrim.getViewAlpha(), 0.2);
progress = 0.0f;
mScrimController.setTransitionToFullShadeProgress(progress);
mScrimController.setTransitionToFullShadeProgress(progress, lsNotifProgress);
assertEquals(MathUtils.lerp(keyguardAlpha, shadeLockedAlpha, progress),
mNotificationsScrim.getViewAlpha(), 0.2);
progress = 1.0f;
mScrimController.setTransitionToFullShadeProgress(progress);
mScrimController.setTransitionToFullShadeProgress(progress, lsNotifProgress);
assertEquals(MathUtils.lerp(keyguardAlpha, shadeLockedAlpha, progress),
mNotificationsScrim.getViewAlpha(), 0.2);
}
@Test
public void notificationTransparency_followsNotificationScrimProgress() {
mScrimController.transitionTo(ScrimState.SHADE_LOCKED);
mScrimController.setRawPanelExpansionFraction(1.0f);
finishAnimationsImmediately();
mScrimController.transitionTo(ScrimState.KEYGUARD);
mScrimController.setRawPanelExpansionFraction(1.0f);
finishAnimationsImmediately();
float progress = 0.5f;
float notifProgress = 0.3f;
mScrimController.setTransitionToFullShadeProgress(progress, notifProgress);
assertThat(mNotificationsScrim.getViewAlpha()).isEqualTo(notifProgress);
}
private void assertAlphaAfterExpansion(ScrimView scrim, float expectedAlpha, float expansion) {
mScrimController.setRawPanelExpansionFraction(expansion);
finishAnimationsImmediately();