Loading packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java +21 −5 Original line number Diff line number Diff line Loading @@ -44,6 +44,7 @@ import android.view.animation.Interpolator; import androidx.annotation.NonNull; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.jank.InteractionJankMonitor; import com.android.internal.jank.InteractionJankMonitor.Configuration; import com.android.internal.logging.UiEventLogger; Loading Loading @@ -335,10 +336,24 @@ public class StatusBarStateControllerImpl implements ? Interpolators.FAST_OUT_SLOW_IN : Interpolators.TOUCH_RESPONSE_REVERSE; } mDarkAnimator = ObjectAnimator.ofFloat(this, SET_DARK_AMOUNT_PROPERTY, mDozeAmountTarget); mDarkAnimator.setInterpolator(Interpolators.LINEAR); mDarkAnimator.setDuration(StackStateAnimator.ANIMATION_DURATION_WAKEUP); mDarkAnimator.addListener(new AnimatorListenerAdapter() { if (mDozeAmount == 1f && !mIsDozing) { // Workaround to force relayoutWindow to be called a frame earlier. Otherwise, if // mDozeAmount = 1f, then neither start() nor the first frame of the animation will // cause the scrim opacity to change, which ultimately results in an extra relayout and // causes us to miss a frame. By settings the doze amount to be <1f a frame earlier, // we can batch the relayout with the one in NotificationShadeWindowControllerImpl. setDozeAmountInternal(0.99f); } mDarkAnimator = createDarkAnimator(); } @VisibleForTesting protected ObjectAnimator createDarkAnimator() { ObjectAnimator darkAnimator = ObjectAnimator.ofFloat( this, SET_DARK_AMOUNT_PROPERTY, mDozeAmountTarget); darkAnimator.setInterpolator(Interpolators.LINEAR); darkAnimator.setDuration(StackStateAnimator.ANIMATION_DURATION_WAKEUP); darkAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationCancel(Animator animation) { cancelInteractionJankMonitor(); Loading @@ -354,7 +369,8 @@ public class StatusBarStateControllerImpl implements beginInteractionJankMonitor(); } }); mDarkAnimator.start(); darkAnimator.start(); return darkAnimator; } private void setDozeAmountInternal(float dozeAmount) { Loading packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarStateControllerImplTest.kt +25 −2 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.systemui.statusbar import android.animation.ObjectAnimator import android.testing.AndroidTestingRunner import android.testing.TestableLooper import androidx.test.filters.SmallTest Loading Loading @@ -46,6 +47,7 @@ import org.mockito.Mockito.`when` as whenever class StatusBarStateControllerImplTest : SysuiTestCase() { @Mock lateinit var interactionJankMonitor: InteractionJankMonitor @Mock private lateinit var mockDarkAnimator: ObjectAnimator private lateinit var controller: StatusBarStateControllerImpl private lateinit var uiEventLogger: UiEventLoggerFake Loading @@ -57,11 +59,13 @@ class StatusBarStateControllerImplTest : SysuiTestCase() { whenever(interactionJankMonitor.end(anyInt())).thenReturn(true) uiEventLogger = UiEventLoggerFake() controller = StatusBarStateControllerImpl( controller = object : StatusBarStateControllerImpl( uiEventLogger, mock(DumpManager::class.java), interactionJankMonitor ) ) { override fun createDarkAnimator(): ObjectAnimator { return mockDarkAnimator } } } @Test Loading Loading @@ -127,4 +131,23 @@ class StatusBarStateControllerImplTest : SysuiTestCase() { // Double check that we can still force it to happen. assertTrue(controller.setState(StatusBarState.SHADE, true /* force */)) } @Test fun testSetDozeAmount_immediatelyChangesDozeAmount_lockscreenTransitionFromAod() { // Put controller in AOD state controller.setDozeAmount(1f, false) // When waking from doze, CentralSurfaces#updateDozingState will update the dozing state // before the doze amount changes controller.setIsDozing(false) // Animate the doze amount to 0f, as would normally happen controller.setAndInstrumentDozeAmount(null, 0f, true) // Check that the doze amount is immediately set to a value slightly less than 1f. This is // to ensure that any scrim implementation changes its opacity immediately rather than // waiting an extra frame. Waiting an extra frame will cause a relayout (which is expensive) // and cause us to drop a frame during the LOCKSCREEN_TRANSITION_FROM_AOD CUJ. assertEquals(0.99f, controller.dozeAmount, 0.009f) } } Loading
packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java +21 −5 Original line number Diff line number Diff line Loading @@ -44,6 +44,7 @@ import android.view.animation.Interpolator; import androidx.annotation.NonNull; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.jank.InteractionJankMonitor; import com.android.internal.jank.InteractionJankMonitor.Configuration; import com.android.internal.logging.UiEventLogger; Loading Loading @@ -335,10 +336,24 @@ public class StatusBarStateControllerImpl implements ? Interpolators.FAST_OUT_SLOW_IN : Interpolators.TOUCH_RESPONSE_REVERSE; } mDarkAnimator = ObjectAnimator.ofFloat(this, SET_DARK_AMOUNT_PROPERTY, mDozeAmountTarget); mDarkAnimator.setInterpolator(Interpolators.LINEAR); mDarkAnimator.setDuration(StackStateAnimator.ANIMATION_DURATION_WAKEUP); mDarkAnimator.addListener(new AnimatorListenerAdapter() { if (mDozeAmount == 1f && !mIsDozing) { // Workaround to force relayoutWindow to be called a frame earlier. Otherwise, if // mDozeAmount = 1f, then neither start() nor the first frame of the animation will // cause the scrim opacity to change, which ultimately results in an extra relayout and // causes us to miss a frame. By settings the doze amount to be <1f a frame earlier, // we can batch the relayout with the one in NotificationShadeWindowControllerImpl. setDozeAmountInternal(0.99f); } mDarkAnimator = createDarkAnimator(); } @VisibleForTesting protected ObjectAnimator createDarkAnimator() { ObjectAnimator darkAnimator = ObjectAnimator.ofFloat( this, SET_DARK_AMOUNT_PROPERTY, mDozeAmountTarget); darkAnimator.setInterpolator(Interpolators.LINEAR); darkAnimator.setDuration(StackStateAnimator.ANIMATION_DURATION_WAKEUP); darkAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationCancel(Animator animation) { cancelInteractionJankMonitor(); Loading @@ -354,7 +369,8 @@ public class StatusBarStateControllerImpl implements beginInteractionJankMonitor(); } }); mDarkAnimator.start(); darkAnimator.start(); return darkAnimator; } private void setDozeAmountInternal(float dozeAmount) { Loading
packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarStateControllerImplTest.kt +25 −2 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.systemui.statusbar import android.animation.ObjectAnimator import android.testing.AndroidTestingRunner import android.testing.TestableLooper import androidx.test.filters.SmallTest Loading Loading @@ -46,6 +47,7 @@ import org.mockito.Mockito.`when` as whenever class StatusBarStateControllerImplTest : SysuiTestCase() { @Mock lateinit var interactionJankMonitor: InteractionJankMonitor @Mock private lateinit var mockDarkAnimator: ObjectAnimator private lateinit var controller: StatusBarStateControllerImpl private lateinit var uiEventLogger: UiEventLoggerFake Loading @@ -57,11 +59,13 @@ class StatusBarStateControllerImplTest : SysuiTestCase() { whenever(interactionJankMonitor.end(anyInt())).thenReturn(true) uiEventLogger = UiEventLoggerFake() controller = StatusBarStateControllerImpl( controller = object : StatusBarStateControllerImpl( uiEventLogger, mock(DumpManager::class.java), interactionJankMonitor ) ) { override fun createDarkAnimator(): ObjectAnimator { return mockDarkAnimator } } } @Test Loading Loading @@ -127,4 +131,23 @@ class StatusBarStateControllerImplTest : SysuiTestCase() { // Double check that we can still force it to happen. assertTrue(controller.setState(StatusBarState.SHADE, true /* force */)) } @Test fun testSetDozeAmount_immediatelyChangesDozeAmount_lockscreenTransitionFromAod() { // Put controller in AOD state controller.setDozeAmount(1f, false) // When waking from doze, CentralSurfaces#updateDozingState will update the dozing state // before the doze amount changes controller.setIsDozing(false) // Animate the doze amount to 0f, as would normally happen controller.setAndInstrumentDozeAmount(null, 0f, true) // Check that the doze amount is immediately set to a value slightly less than 1f. This is // to ensure that any scrim implementation changes its opacity immediately rather than // waiting an extra frame. Waiting an extra frame will cause a relayout (which is expensive) // and cause us to drop a frame during the LOCKSCREEN_TRANSITION_FROM_AOD CUJ. assertEquals(0.99f, controller.dozeAmount, 0.009f) } }