Loading packages/SystemUI/aconfig/systemui.aconfig +10 −0 Original line number Diff line number Diff line Loading @@ -2037,3 +2037,13 @@ flag { description: "Enables ongoing activity chips in dream status bar" bug: "418243972" } flag { name: "instant_hide_shade" namespace: "systemui" description: "Enables the Shade to hide instantaneously at the end of a launch animation, preventing flickers." bug: "419304171" metadata { purpose: PURPOSE_BUGFIX } } packages/SystemUI/animation/src/com/android/systemui/animation/ActivityTransitionAnimator.kt +4 −1 Original line number Diff line number Diff line Loading @@ -62,6 +62,7 @@ import com.android.app.animation.Interpolators import com.android.internal.annotations.VisibleForTesting import com.android.internal.policy.ScreenDecorationsUtils import com.android.systemui.Flags.animationLibraryDelayLeashCleanup import com.android.systemui.Flags.instantHideShade import com.android.systemui.Flags.moveTransitionAnimationLayer import com.android.systemui.animation.TransitionAnimator.Companion.assertLongLivedReturnAnimations import com.android.systemui.animation.TransitionAnimator.Companion.assertReturnAnimations Loading Loading @@ -1568,7 +1569,7 @@ constructor( override fun onTransitionAnimationEnd(isExpandingFullyAbove: Boolean) { listener?.onTransitionAnimationEnd() iCallback?.invoke() if (!instantHideShade()) iCallback?.invoke() if (reparent) { val cleanUpTransitionLeash: () -> Unit = { Loading Loading @@ -1616,6 +1617,8 @@ constructor( ) } delegate.onTransitionAnimationEnd(isExpandingFullyAbove) if (instantHideShade()) iCallback?.invoke() } override fun onTransitionAnimationProgress( Loading packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationShadeWindowControllerImplTest.java +33 −0 Original line number Diff line number Diff line Loading @@ -53,6 +53,7 @@ import android.view.WindowManager; import androidx.test.filters.SmallTest; import com.android.internal.colorextraction.ColorExtractor; import com.android.systemui.Flags; import com.android.systemui.SysuiTestCase; import com.android.systemui.biometrics.AuthController; import com.android.systemui.colorextraction.SysuiColorExtractor; Loading Loading @@ -546,6 +547,38 @@ public class NotificationShadeWindowControllerImplTest extends SysuiTestCase { assertThat(lp.preferredMinDisplayRefreshRate).isEqualTo(0); } @EnableFlags(Flags.FLAG_INSTANT_HIDE_SHADE) @Test public void afterActivityLaunch_rootViewInvisible() { // GIVEN the panel is visible mNotificationShadeWindowController.setPanelVisible(true); verify(mNotificationShadeWindowView).setVisibility(eq(View.VISIBLE)); // WHEN the shade is force-hidden at the end of an activity launch mNotificationShadeWindowController.setLaunchingActivity(true); mNotificationShadeWindowController.setForceHideAfterActivityLaunch(true); // THEN the panel is invisible verify(mNotificationShadeWindowView).setVisibility(eq(View.INVISIBLE)); } @EnableFlags(Flags.FLAG_INSTANT_HIDE_SHADE) @Test public void setKeyguardFadingAway_doesNothing_whenForceHidden() { // GIVEN the panel is visible force-hidden at the end of an activity launch mNotificationShadeWindowController.setLaunchingActivity(true); mNotificationShadeWindowController.setForceHideAfterActivityLaunch(true); verify(mNotificationShadeWindowView).setVisibility(eq(View.INVISIBLE)); reset(mNotificationShadeWindowView); // WHEN keyguard is fading away, followed by the panel not being force-hidden anymore mNotificationShadeWindowController.setKeyguardFadingAway(true); mNotificationShadeWindowController.setLaunchingActivity(false); // THEN the panel remains invisible verify(mNotificationShadeWindowView, never()).setVisibility(eq(View.VISIBLE)); } @Test @EnableSceneContainer public void configChanged_boundsUpdate() { Loading packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ShadeControllerImplTest.kt +20 −0 Original line number Diff line number Diff line Loading @@ -16,12 +16,14 @@ package com.android.systemui.shade import android.platform.test.annotations.EnableFlags import android.testing.TestableLooper.RunWithLooper import android.view.Display import android.view.WindowManager import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.internal.statusbar.IStatusBarService import com.android.systemui.Flags import com.android.systemui.SysuiTestCase import com.android.systemui.assist.AssistManager import com.android.systemui.flags.DisableSceneContainer Loading @@ -34,6 +36,7 @@ import com.android.systemui.scene.data.repository.WindowRootViewVisibilityReposi import com.android.systemui.scene.domain.interactor.WindowRootViewVisibilityInteractor import com.android.systemui.scene.domain.interactor.sceneInteractor import com.android.systemui.statusbar.CommandQueue import com.android.systemui.statusbar.NotificationPresenter import com.android.systemui.statusbar.NotificationShadeWindowController import com.android.systemui.statusbar.notification.domain.interactor.activeNotificationsInteractor import com.android.systemui.statusbar.notification.headsup.HeadsUpManager Loading Loading @@ -85,6 +88,7 @@ class ShadeControllerImplTest : SysuiTestCase() { @Mock private lateinit var touchLog: LogBuffer @Mock private lateinit var iStatusBarService: IStatusBarService @Mock private lateinit var headsUpManager: HeadsUpManager @Mock private lateinit var notifPresenter: NotificationPresenter private val windowRootViewVisibilityInteractor: WindowRootViewVisibilityInteractor by lazy { WindowRootViewVisibilityInteractor( Loading Loading @@ -192,4 +196,20 @@ class ShadeControllerImplTest : SysuiTestCase() { // THEN the interactor is notified assertThat(windowRootViewVisibilityInteractor.isLockscreenOrShadeVisible.value).isFalse() } @EnableFlags(Flags.FLAG_INSTANT_HIDE_SHADE) @Test fun visible_launchAnimationEnds_windowControllerInstantlyHidden() { // GIVEN the shade is currently expanded shadeController.setNotificationPresenter(notifPresenter) shadeController.makeExpandedVisible(true) assertThat(windowRootViewVisibilityInteractor.isLockscreenOrShadeVisible.value).isTrue() // WHEN a fullscreen launch animation ends shadeController.onLaunchAnimationEnd(launchIsFullScreen = true) // THEN the window controller is forced to hide the shade synchronously verify(notificationShadeWindowController).setPanelVisible(false) verify(notificationShadeWindowController).setForceHideAfterActivityLaunch(true) } } packages/SystemUI/src/com/android/systemui/shade/BaseShadeControllerImpl.kt +7 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.systemui.shade import com.android.keyguard.KeyguardViewController import com.android.systemui.Flags import com.android.systemui.assist.AssistManager import com.android.systemui.statusbar.CommandQueue import com.android.systemui.statusbar.NotificationPresenter Loading Loading @@ -74,6 +75,12 @@ abstract class BaseShadeControllerImpl( onClosingFinished() } if (launchIsFullScreen) { if (Flags.instantHideShade()) { // Make sure that visually the Shade is gone immediately, even though the rest of // the state takes a little time to catch up. notificationShadeWindowController.setPanelVisible(false) notificationShadeWindowController.setForceHideAfterActivityLaunch(true) } instantCollapseShade() } } Loading Loading
packages/SystemUI/aconfig/systemui.aconfig +10 −0 Original line number Diff line number Diff line Loading @@ -2037,3 +2037,13 @@ flag { description: "Enables ongoing activity chips in dream status bar" bug: "418243972" } flag { name: "instant_hide_shade" namespace: "systemui" description: "Enables the Shade to hide instantaneously at the end of a launch animation, preventing flickers." bug: "419304171" metadata { purpose: PURPOSE_BUGFIX } }
packages/SystemUI/animation/src/com/android/systemui/animation/ActivityTransitionAnimator.kt +4 −1 Original line number Diff line number Diff line Loading @@ -62,6 +62,7 @@ import com.android.app.animation.Interpolators import com.android.internal.annotations.VisibleForTesting import com.android.internal.policy.ScreenDecorationsUtils import com.android.systemui.Flags.animationLibraryDelayLeashCleanup import com.android.systemui.Flags.instantHideShade import com.android.systemui.Flags.moveTransitionAnimationLayer import com.android.systemui.animation.TransitionAnimator.Companion.assertLongLivedReturnAnimations import com.android.systemui.animation.TransitionAnimator.Companion.assertReturnAnimations Loading Loading @@ -1568,7 +1569,7 @@ constructor( override fun onTransitionAnimationEnd(isExpandingFullyAbove: Boolean) { listener?.onTransitionAnimationEnd() iCallback?.invoke() if (!instantHideShade()) iCallback?.invoke() if (reparent) { val cleanUpTransitionLeash: () -> Unit = { Loading Loading @@ -1616,6 +1617,8 @@ constructor( ) } delegate.onTransitionAnimationEnd(isExpandingFullyAbove) if (instantHideShade()) iCallback?.invoke() } override fun onTransitionAnimationProgress( Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationShadeWindowControllerImplTest.java +33 −0 Original line number Diff line number Diff line Loading @@ -53,6 +53,7 @@ import android.view.WindowManager; import androidx.test.filters.SmallTest; import com.android.internal.colorextraction.ColorExtractor; import com.android.systemui.Flags; import com.android.systemui.SysuiTestCase; import com.android.systemui.biometrics.AuthController; import com.android.systemui.colorextraction.SysuiColorExtractor; Loading Loading @@ -546,6 +547,38 @@ public class NotificationShadeWindowControllerImplTest extends SysuiTestCase { assertThat(lp.preferredMinDisplayRefreshRate).isEqualTo(0); } @EnableFlags(Flags.FLAG_INSTANT_HIDE_SHADE) @Test public void afterActivityLaunch_rootViewInvisible() { // GIVEN the panel is visible mNotificationShadeWindowController.setPanelVisible(true); verify(mNotificationShadeWindowView).setVisibility(eq(View.VISIBLE)); // WHEN the shade is force-hidden at the end of an activity launch mNotificationShadeWindowController.setLaunchingActivity(true); mNotificationShadeWindowController.setForceHideAfterActivityLaunch(true); // THEN the panel is invisible verify(mNotificationShadeWindowView).setVisibility(eq(View.INVISIBLE)); } @EnableFlags(Flags.FLAG_INSTANT_HIDE_SHADE) @Test public void setKeyguardFadingAway_doesNothing_whenForceHidden() { // GIVEN the panel is visible force-hidden at the end of an activity launch mNotificationShadeWindowController.setLaunchingActivity(true); mNotificationShadeWindowController.setForceHideAfterActivityLaunch(true); verify(mNotificationShadeWindowView).setVisibility(eq(View.INVISIBLE)); reset(mNotificationShadeWindowView); // WHEN keyguard is fading away, followed by the panel not being force-hidden anymore mNotificationShadeWindowController.setKeyguardFadingAway(true); mNotificationShadeWindowController.setLaunchingActivity(false); // THEN the panel remains invisible verify(mNotificationShadeWindowView, never()).setVisibility(eq(View.VISIBLE)); } @Test @EnableSceneContainer public void configChanged_boundsUpdate() { Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ShadeControllerImplTest.kt +20 −0 Original line number Diff line number Diff line Loading @@ -16,12 +16,14 @@ package com.android.systemui.shade import android.platform.test.annotations.EnableFlags import android.testing.TestableLooper.RunWithLooper import android.view.Display import android.view.WindowManager import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.internal.statusbar.IStatusBarService import com.android.systemui.Flags import com.android.systemui.SysuiTestCase import com.android.systemui.assist.AssistManager import com.android.systemui.flags.DisableSceneContainer Loading @@ -34,6 +36,7 @@ import com.android.systemui.scene.data.repository.WindowRootViewVisibilityReposi import com.android.systemui.scene.domain.interactor.WindowRootViewVisibilityInteractor import com.android.systemui.scene.domain.interactor.sceneInteractor import com.android.systemui.statusbar.CommandQueue import com.android.systemui.statusbar.NotificationPresenter import com.android.systemui.statusbar.NotificationShadeWindowController import com.android.systemui.statusbar.notification.domain.interactor.activeNotificationsInteractor import com.android.systemui.statusbar.notification.headsup.HeadsUpManager Loading Loading @@ -85,6 +88,7 @@ class ShadeControllerImplTest : SysuiTestCase() { @Mock private lateinit var touchLog: LogBuffer @Mock private lateinit var iStatusBarService: IStatusBarService @Mock private lateinit var headsUpManager: HeadsUpManager @Mock private lateinit var notifPresenter: NotificationPresenter private val windowRootViewVisibilityInteractor: WindowRootViewVisibilityInteractor by lazy { WindowRootViewVisibilityInteractor( Loading Loading @@ -192,4 +196,20 @@ class ShadeControllerImplTest : SysuiTestCase() { // THEN the interactor is notified assertThat(windowRootViewVisibilityInteractor.isLockscreenOrShadeVisible.value).isFalse() } @EnableFlags(Flags.FLAG_INSTANT_HIDE_SHADE) @Test fun visible_launchAnimationEnds_windowControllerInstantlyHidden() { // GIVEN the shade is currently expanded shadeController.setNotificationPresenter(notifPresenter) shadeController.makeExpandedVisible(true) assertThat(windowRootViewVisibilityInteractor.isLockscreenOrShadeVisible.value).isTrue() // WHEN a fullscreen launch animation ends shadeController.onLaunchAnimationEnd(launchIsFullScreen = true) // THEN the window controller is forced to hide the shade synchronously verify(notificationShadeWindowController).setPanelVisible(false) verify(notificationShadeWindowController).setForceHideAfterActivityLaunch(true) } }
packages/SystemUI/src/com/android/systemui/shade/BaseShadeControllerImpl.kt +7 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.systemui.shade import com.android.keyguard.KeyguardViewController import com.android.systemui.Flags import com.android.systemui.assist.AssistManager import com.android.systemui.statusbar.CommandQueue import com.android.systemui.statusbar.NotificationPresenter Loading Loading @@ -74,6 +75,12 @@ abstract class BaseShadeControllerImpl( onClosingFinished() } if (launchIsFullScreen) { if (Flags.instantHideShade()) { // Make sure that visually the Shade is gone immediately, even though the rest of // the state takes a little time to catch up. notificationShadeWindowController.setPanelVisible(false) notificationShadeWindowController.setForceHideAfterActivityLaunch(true) } instantCollapseShade() } } Loading