Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2e85836c authored by Luca Zuccarini's avatar Luca Zuccarini
Browse files

Allow Shade to be hidden instantaneously at the end of a launch.

Right now there is a race condition between the time it takes to hide
the Shade and the end of the transition. The delay in the former can
cause flickers.

Bug: 419304171
Flag: com.android.systemui.instant_hide_shade
Test: atest NotificationShadeWindowControllerImplTest ShadeControllerImplTest
Change-Id: I64e985e12d20338a3e5d98c80d324c57e15691bf
parent bf0fa11b
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -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
    }
}
+4 −1
Original line number Diff line number Diff line
@@ -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
@@ -1568,7 +1569,7 @@ constructor(

                    override fun onTransitionAnimationEnd(isExpandingFullyAbove: Boolean) {
                        listener?.onTransitionAnimationEnd()
                        iCallback?.invoke()
                        if (!instantHideShade()) iCallback?.invoke()

                        if (reparent) {
                            val cleanUpTransitionLeash: () -> Unit = {
@@ -1616,6 +1617,8 @@ constructor(
                            )
                        }
                        delegate.onTransitionAnimationEnd(isExpandingFullyAbove)

                        if (instantHideShade()) iCallback?.invoke()
                    }

                    override fun onTransitionAnimationProgress(
+33 −0
Original line number Diff line number Diff line
@@ -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;
@@ -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() {
+20 −0
Original line number Diff line number Diff line
@@ -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
@@ -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
@@ -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(
@@ -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)
    }
}
+7 −0
Original line number Diff line number Diff line
@@ -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
@@ -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