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

Commit fbd96fab authored by Nick Chameyev's avatar Nick Chameyev Committed by Automerger Merge Worker
Browse files

Merge "[Unfold transition] Update latency tracker to listen for animation...

Merge "[Unfold transition] Update latency tracker to listen for animation start" into tm-qpr-dev am: 596e3f90

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/20637217



Change-Id: Ie5445ece5ea5d0c19d7f0e37306a6f8cb297ad99
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents 27c9c83f 596e3f90
Loading
Loading
Loading
Loading
+12 −3
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@ package com.android.systemui.keyguard

import com.android.systemui.unfold.updates.screen.ScreenStatusProvider
import com.android.systemui.unfold.updates.screen.ScreenStatusProvider.ScreenListener
import com.android.systemui.util.traceSection
import javax.inject.Inject
import javax.inject.Singleton

@@ -39,14 +40,22 @@ class LifecycleScreenStatusProvider @Inject constructor(screenLifecycle: ScreenL
    }

    override fun onScreenTurnedOn() {
        traceSection("$TRACE_TAG#onScreenTurnedOn") {
            listeners.forEach(ScreenListener::onScreenTurnedOn)
        }
    }

    override fun onScreenTurningOff() {
        traceSection("$TRACE_TAG#onScreenTurningOff") {
            listeners.forEach(ScreenListener::onScreenTurningOff)
        }
    }

    override fun onScreenTurningOn() {
        traceSection("$TRACE_TAG#onScreenTurningOn") {
            listeners.forEach(ScreenListener::onScreenTurningOn)
        }
    }
}

private const val TRACE_TAG = "LifecycleScreenStatusProvider"
 No newline at end of file
+78 −6
Original line number Diff line number Diff line
@@ -16,12 +16,18 @@

package com.android.systemui.unfold

import android.content.ContentResolver
import android.content.Context
import android.hardware.devicestate.DeviceStateManager
import android.util.Log
import com.android.internal.util.LatencyTracker
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.UiBackground
import com.android.systemui.keyguard.ScreenLifecycle
import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionProgressListener
import com.android.systemui.unfold.util.ScaleAwareTransitionProgressProvider.Companion.areAnimationsEnabled
import com.android.systemui.util.Compile
import java.util.Optional
import java.util.concurrent.Executor
import javax.inject.Inject

@@ -41,17 +47,19 @@ class UnfoldLatencyTracker
constructor(
    private val latencyTracker: LatencyTracker,
    private val deviceStateManager: DeviceStateManager,
    private val transitionProgressProvider: Optional<UnfoldTransitionProgressProvider>,
    @UiBackground private val uiBgExecutor: Executor,
    private val context: Context,
    private val contentResolver: ContentResolver,
    private val screenLifecycle: ScreenLifecycle
) : ScreenLifecycle.Observer {
) : ScreenLifecycle.Observer, TransitionProgressListener {

    private var folded: Boolean? = null
    private var isTransitionEnabled: Boolean? = null
    private val foldStateListener = FoldStateListener(context)
    private val isFoldable: Boolean
        get() =
            context
                .resources
            context.resources
                .getIntArray(com.android.internal.R.array.config_foldedDeviceStates)
                .isNotEmpty()

@@ -62,6 +70,11 @@ constructor(
        }
        deviceStateManager.registerCallback(uiBgExecutor, foldStateListener)
        screenLifecycle.addObserver(this)
        if (transitionProgressProvider.isPresent) {
            // Might not be present if the device is not a foldable device or unfold transition
            // is disabled in the device configuration
            transitionProgressProvider.get().addCallback(this)
        }
    }

    /**
@@ -71,16 +84,72 @@ constructor(
     * end action event only if we previously received a fold state.
     */
    override fun onScreenTurnedOn() {
        if (folded == false) {
        if (DEBUG) {
            Log.d(
                TAG,
                "onScreenTurnedOn: folded = $folded, isTransitionEnabled = $isTransitionEnabled"
            )
        }

        // We use onScreenTurnedOn event to finish tracking only if we are not playing
        // the unfold animation (e.g. it could be disabled because of battery saver).
        // When animation is enabled finishing of the tracking will be done in onTransitionStarted.
        if (folded == false && isTransitionEnabled == false) {
            latencyTracker.onActionEnd(LatencyTracker.ACTION_SWITCH_DISPLAY_UNFOLD)

            if (DEBUG) {
                Log.d(TAG, "onScreenTurnedOn: ending ACTION_SWITCH_DISPLAY_UNFOLD")
            }
        }
    }

    /**
     * This callback is used to end the metric when the unfold animation is enabled because it could
     * add an additional delay to synchronize with launcher.
     */
    override fun onTransitionStarted() {
        if (DEBUG) {
            Log.d(
                TAG,
                "onTransitionStarted: folded = $folded, isTransitionEnabled = $isTransitionEnabled"
            )
        }

        if (folded == false && isTransitionEnabled == true) {
            latencyTracker.onActionEnd(LatencyTracker.ACTION_SWITCH_DISPLAY_UNFOLD)

            if (DEBUG) {
                Log.d(TAG, "onTransitionStarted: ending ACTION_SWITCH_DISPLAY_UNFOLD")
            }
        }
    }

    private fun onFoldEvent(folded: Boolean) {
        if (this.folded != folded) {
        val oldFolded = this.folded

        if (oldFolded != folded) {
            this.folded = folded
            if (!folded) { // unfolding started

            if (DEBUG) {
                Log.d(TAG, "Received onFoldEvent = $folded")
            }

            // Do not start tracking when oldFolded is null, this means that this is the first
            // onFoldEvent after booting the device or starting SystemUI and not actual folding or
            // unfolding the device.
            if (oldFolded != null && !folded) {
                // Unfolding started
                latencyTracker.onActionStart(LatencyTracker.ACTION_SWITCH_DISPLAY_UNFOLD)
                isTransitionEnabled =
                    transitionProgressProvider.isPresent && contentResolver.areAnimationsEnabled()

                if (DEBUG) {
                    Log.d(
                        TAG,
                        "Starting ACTION_SWITCH_DISPLAY_UNFOLD, " +
                            "isTransitionEnabled = $isTransitionEnabled"
                    )
                }
            }
        }
    }
@@ -88,3 +157,6 @@ constructor(
    private inner class FoldStateListener(context: Context) :
        DeviceStateManager.FoldStateListener(context, { onFoldEvent(it) })
}

private const val TAG = "UnfoldLatencyTracker"
private val DEBUG = Compile.IS_DEBUG && Log.isLoggable(TAG, Log.VERBOSE)
+91 −2
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.systemui.unfold

import android.hardware.devicestate.DeviceStateManager
import android.hardware.devicestate.DeviceStateManager.FoldStateListener
import android.provider.Settings
import android.testing.AndroidTestingRunner
import androidx.test.filters.SmallTest
import com.android.internal.util.LatencyTracker
@@ -32,9 +33,11 @@ import org.junit.runner.RunWith
import org.mockito.ArgumentCaptor
import org.mockito.Captor
import org.mockito.Mock
import org.mockito.Mockito.never
import org.mockito.Mockito.verify
import org.mockito.Mockito.verifyNoMoreInteractions
import org.mockito.MockitoAnnotations
import java.util.Optional

@RunWith(AndroidTestingRunner::class)
@SmallTest
@@ -59,14 +62,18 @@ class UnfoldLatencyTrackerTest : SysuiTestCase() {

    private lateinit var unfoldLatencyTracker: UnfoldLatencyTracker

    private val transitionProgressProvider = TestUnfoldTransitionProvider()

    @Before
    fun setUp() {
        MockitoAnnotations.initMocks(this)
        unfoldLatencyTracker = UnfoldLatencyTracker(
            latencyTracker,
            deviceStateManager,
            Optional.of(transitionProgressProvider),
            context.mainExecutor,
            context,
            context.contentResolver,
            screenLifecycle
        ).apply { init() }
        deviceStates = FoldableTestUtils.findDeviceStates(context)
@@ -76,22 +83,88 @@ class UnfoldLatencyTrackerTest : SysuiTestCase() {
    }

    @Test
    fun unfold_eventPropagated() {
    fun unfold_startedFolded_animationsDisabled_eventPropagatedOnScreenTurnedOnEvent() {
        setAnimationsEnabled(false)
        sendFoldEvent(folded = true)
        sendFoldEvent(folded = false)

        sendScreenTurnedOnEvent()

        verify(latencyTracker).onActionStart(any())
        verify(latencyTracker).onActionEnd(any())
    }

    @Test
    fun unfold_startedFolded_animationsEnabledOnScreenTurnedOn_eventNotFinished() {
        setAnimationsEnabled(true)
        sendFoldEvent(folded = true)
        sendFoldEvent(folded = false)

        sendScreenTurnedOnEvent()

        verify(latencyTracker).onActionStart(any())
        verify(latencyTracker, never()).onActionEnd(any())
    }

    @Test
    fun unfold_firstFoldEventAnimationsEnabledOnScreenTurnedOnAndTransitionStarted_eventNotPropagated() {
        setAnimationsEnabled(true)
        sendFoldEvent(folded = false)

        sendScreenTurnedOnEvent()
        transitionProgressProvider.onTransitionStarted()

        verifyNoMoreInteractions(latencyTracker)
    }

    @Test
    fun unfold_secondFoldEventAnimationsEnabledOnScreenTurnedOnAndTransitionStarted_eventPropagated() {
        setAnimationsEnabled(true)
        sendFoldEvent(folded = true)
        sendFoldEvent(folded = false)

        sendScreenTurnedOnEvent()
        transitionProgressProvider.onTransitionStarted()

        verify(latencyTracker).onActionStart(any())
        verify(latencyTracker).onActionEnd(any())
    }

    @Test
    fun unfold_unfoldFoldUnfoldAnimationsEnabledOnScreenTurnedOnAndTransitionStarted_eventPropagated() {
        setAnimationsEnabled(true)
        sendFoldEvent(folded = false)
        sendFoldEvent(folded = true)
        sendFoldEvent(folded = false)

        sendScreenTurnedOnEvent()
        transitionProgressProvider.onTransitionStarted()

        verify(latencyTracker).onActionStart(any())
        verify(latencyTracker).onActionEnd(any())
    }

    @Test
    fun fold_eventNotPropagated() {
    fun fold_animationsDisabled_screenTurnedOn_eventNotPropagated() {
        setAnimationsEnabled(false)
        sendFoldEvent(folded = true)

        sendScreenTurnedOnEvent() // outer display on.

        verifyNoMoreInteractions(latencyTracker)
    }

    @Test
    fun fold_animationsEnabled_screenTurnedOn_eventNotPropagated() {
        setAnimationsEnabled(true)
        sendFoldEvent(folded = true)

        sendScreenTurnedOnEvent() // outer display on.
        transitionProgressProvider.onTransitionStarted()

        verifyNoMoreInteractions(latencyTracker)
    }

    @Test
    fun onScreenTurnedOn_stateNeverSet_eventNotPropagated() {
        sendScreenTurnedOnEvent()
@@ -107,4 +180,20 @@ class UnfoldLatencyTrackerTest : SysuiTestCase() {
    private fun sendScreenTurnedOnEvent() {
        screenLifecycleCaptor.value.onScreenTurnedOn()
    }

    private fun setAnimationsEnabled(enabled: Boolean) {
        val durationScale =
            if (enabled) {
                1f
            } else {
                0f
            }

        // It uses [TestableSettingsProvider] and it will be cleared after the test
        Settings.Global.putString(
            context.contentResolver,
            Settings.Global.ANIMATOR_DURATION_SCALE,
            durationScale.toString()
        )
    }
}
 No newline at end of file
+4 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@
package com.android.systemui.unfold.progress

import android.os.Trace
import android.os.Trace.TRACE_TAG_APP
import android.util.Log
import androidx.dynamicanimation.animation.DynamicAnimation
import androidx.dynamicanimation.animation.FloatPropertyCompat
@@ -157,7 +158,10 @@ class PhysicsBasedUnfoldTransitionProgressProvider(
    }

    private fun onStartTransition() {
        Trace.beginSection( "$TAG#onStartTransition")
        listeners.forEach { it.onTransitionStarted() }
        Trace.endSection()

        isTransitionRunning = true

        if (DEBUG) {