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

Commit 9ec7e7c5 authored by Nicolo' Mazzucato's avatar Nicolo' Mazzucato
Browse files

Run the ondrawn Keyguard callback in the bg thread

This should give some unfold latency improvements, as the screen is on only when the pending tasks registered in ScreenOnCoordinator are completed.

If there are some long running computations in the main thread, calling onDrawn.run() will result in delays.

Flag: ACONFIG enable_background_keyguard_ondrawn_callback DISABLED
Bug: 295873557
Test: ScreenOnCoordinatorTest
Change-Id: Ie0202eb96d7b155f0f3be90dc35a3b0ae9b8e8e3
parent 01fa80d3
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -144,6 +144,16 @@ flag {
    bug: "277879146"
}

flag {
    name: "enable_background_keyguard_ondrawn_callback"
    namespace: "systemui"
    description: "Calls the onDrawn keyguard in the background, without being blocked by main"
        "thread work. This results in the screen to turn on earlier when the main thread is stuck. "
        "Note that, even after this callback is called, we're waiting for all windows to finish "
        " drawing."
    bug: "295873557"
}

flag {
    name: "qs_new_pipeline"
    namespace: "systemui"
+5 −1
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.keyguard.mediator
import android.annotation.BinderThread
import android.os.Handler
import android.os.Trace
import com.android.systemui.Flags
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.unfold.SysUIUnfoldComponent
@@ -59,8 +60,11 @@ class ScreenOnCoordinator @Inject constructor(
        foldAodAnimationController?.onScreenTurningOn(pendingTasks.registerTask("fold-to-aod"))

        pendingTasks.onTasksComplete {
            mainHandler.post {
            if (Flags.enableBackgroundKeyguardOndrawnCallback()) {
                // called by whatever thread completes the last task registered.
                onDrawn.run()
            } else {
                mainHandler.post { onDrawn.run() }
            }
        }
        Trace.endSection()
+47 −8
Original line number Diff line number Diff line
@@ -16,16 +16,21 @@

package com.android.keyguard.mediator

import android.os.Handler
import android.os.Looper
import android.platform.test.flag.junit.SetFlagsRule
import android.platform.test.flag.junit.SetFlagsRule.DefaultInitValueType.DEVICE_DEFAULT
import android.testing.AndroidTestingRunner
import androidx.test.filters.SmallTest
import com.android.systemui.Flags
import com.android.systemui.SysuiTestCase
import com.android.systemui.unfold.FoldAodAnimationController
import com.android.systemui.unfold.SysUIUnfoldComponent
import com.android.systemui.unfold.UnfoldLightRevealOverlayAnimation
import com.android.systemui.util.mockito.capture
import com.android.systemui.utils.os.FakeHandler
import com.android.systemui.utils.os.FakeHandler.Mode.QUEUEING
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentCaptor
@@ -52,10 +57,13 @@ class ScreenOnCoordinatorTest : SysuiTestCase() {
    @Captor
    private lateinit var readyCaptor: ArgumentCaptor<Runnable>

    private val testHandler = Handler(Looper.getMainLooper())
    private val testHandler = FakeHandler(Looper.getMainLooper()).apply { setMode(QUEUEING) }

    private lateinit var screenOnCoordinator: ScreenOnCoordinator

    @get:Rule
    val setFlagsRule = SetFlagsRule(DEVICE_DEFAULT)

    @Before
    fun setUp() {
        MockitoAnnotations.initMocks(this)
@@ -77,7 +85,7 @@ class ScreenOnCoordinatorTest : SysuiTestCase() {

        onUnfoldOverlayReady()
        onFoldAodReady()
        waitHandlerIdle(testHandler)
        waitHandlerIdle()

        // Should be called when both unfold overlay and keyguard drawn ready
        verify(runnable).run()
@@ -90,7 +98,7 @@ class ScreenOnCoordinatorTest : SysuiTestCase() {

        onUnfoldOverlayReady()
        onFoldAodReady()
        waitHandlerIdle(testHandler)
        waitHandlerIdle()

        // Should be called when both unfold overlay and keyguard drawn ready
        verify(runnable).run()
@@ -104,7 +112,8 @@ class ScreenOnCoordinatorTest : SysuiTestCase() {

        onUnfoldOverlayReady()
        onFoldAodReady()
        waitHandlerIdle(testHandler)
        waitHandlerIdle()


        // Should not be called because this screen turning on call is not valid anymore
        verify(runnable, never()).run()
@@ -112,13 +121,43 @@ class ScreenOnCoordinatorTest : SysuiTestCase() {

    @Test
    fun testUnfoldTransitionDisabledDrawnTasksReady_onScreenTurningOn_callsDrawnCallback() {
        setFlagsRule.disableFlags(Flags.FLAG_ENABLE_BACKGROUND_KEYGUARD_ONDRAWN_CALLBACK)
        // Recreate with empty unfoldComponent
        screenOnCoordinator = ScreenOnCoordinator(
            Optional.empty(),
            testHandler
        )
        screenOnCoordinator.onScreenTurningOn(runnable)
        waitHandlerIdle()

        // Should be called when only keyguard drawn
        verify(runnable).run()
    }
    @Test
    fun testUnfoldTransitionDisabledDrawnTasksReady_onScreenTurningOn_usesMainHandler() {
        setFlagsRule.disableFlags(Flags.FLAG_ENABLE_BACKGROUND_KEYGUARD_ONDRAWN_CALLBACK)
        // Recreate with empty unfoldComponent
        screenOnCoordinator = ScreenOnCoordinator(
                Optional.empty(),
                testHandler
        )
        screenOnCoordinator.onScreenTurningOn(runnable)

        // Never called as the main handler didn't schedule it yet.
        verify(runnable, never()).run()
    }

    @Test
    fun unfoldTransitionDisabledDrawnTasksReady_onScreenTurningOn_bgCallback_callsDrawnCallback() {
        setFlagsRule.enableFlags(Flags.FLAG_ENABLE_BACKGROUND_KEYGUARD_ONDRAWN_CALLBACK)
        // Recreate with empty unfoldComponent
        screenOnCoordinator = ScreenOnCoordinator(
                Optional.empty(),
                testHandler
        )
        screenOnCoordinator.onScreenTurningOn(runnable)
        waitHandlerIdle(testHandler)
        // No need to wait for the handler to be idle, as it shouldn't be used
        // waitHandlerIdle()

        // Should be called when only keyguard drawn
        verify(runnable).run()
@@ -134,7 +173,7 @@ class ScreenOnCoordinatorTest : SysuiTestCase() {
        readyCaptor.value.run()
    }

    private fun waitHandlerIdle(handler: Handler) {
        handler.runWithScissors({},  /* timeout= */ 0)
    private fun waitHandlerIdle() {
        testHandler.dispatchQueuedMessages()
    }
}