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

Commit 1b0b0490 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Adding unfold latency tracking to DisplaySwitchLatencyTracker" into main

parents 49df72cb 0e0daefa
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -1945,6 +1945,16 @@ flag {
   bug: "390179908"
}

flag {
    name: "unfold_latency_tracking_fix"
    namespace: "systemui"
    description: "New implementation to track unfold latency that excludes broken cases"
    bug: "390649568"
    metadata {
        purpose: PURPOSE_BUGFIX
   }
}

flag {
    name: "ui_rich_ongoing_force_expanded"
    namespace: "systemui"
+261 −0
Original line number Diff line number Diff line
@@ -20,9 +20,12 @@ import android.content.Context
import android.content.res.Resources
import android.hardware.devicestate.DeviceStateManager
import android.os.PowerManager.GO_TO_SLEEP_REASON_DEVICE_FOLD
import android.os.PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.internal.R
import com.android.internal.util.LatencyTracker
import com.android.internal.util.LatencyTracker.ACTION_SWITCH_DISPLAY_UNFOLD
import com.android.systemui.SysuiTestCase
import com.android.systemui.common.ui.data.repository.ConfigurationRepositoryImpl
import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractorImpl
@@ -44,8 +47,10 @@ import com.android.systemui.power.shared.model.ScreenPowerState.SCREEN_OFF
import com.android.systemui.power.shared.model.ScreenPowerState.SCREEN_ON
import com.android.systemui.shared.system.SysUiStatsLog
import com.android.systemui.statusbar.policy.FakeConfigurationController
import com.android.systemui.unfold.DisplaySwitchLatencyTracker.Companion.COOL_DOWN_DURATION
import com.android.systemui.unfold.DisplaySwitchLatencyTracker.Companion.FOLDABLE_DEVICE_STATE_CLOSED
import com.android.systemui.unfold.DisplaySwitchLatencyTracker.Companion.FOLDABLE_DEVICE_STATE_HALF_OPEN
import com.android.systemui.unfold.DisplaySwitchLatencyTracker.Companion.SCREEN_EVENT_TIMEOUT
import com.android.systemui.unfold.DisplaySwitchLatencyTracker.DisplaySwitchLatencyEvent
import com.android.systemui.unfold.data.repository.UnfoldTransitionRepositoryImpl
import com.android.systemui.unfold.domain.interactor.UnfoldTransitionInteractor
@@ -56,11 +61,13 @@ import com.android.systemui.util.mockito.capture
import com.android.systemui.util.time.FakeSystemClock
import com.google.common.truth.Truth.assertThat
import java.util.Optional
import kotlin.time.Duration.Companion.milliseconds
import kotlinx.coroutines.asExecutor
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.test.StandardTestDispatcher
import kotlinx.coroutines.test.TestDispatcher
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.advanceTimeBy
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
import org.junit.Before
@@ -73,6 +80,7 @@ import org.mockito.Mockito.verify
import org.mockito.Mockito.`when` as whenever
import org.mockito.MockitoAnnotations
import org.mockito.kotlin.mock
import org.mockito.kotlin.times

@RunWith(AndroidJUnit4::class)
@SmallTest
@@ -88,6 +96,7 @@ class DisplaySwitchLatencyTrackerTest : SysuiTestCase() {
    private val animationStatusRepository = kosmos.fakeAnimationStatusRepository
    private val keyguardInteractor = mock<KeyguardInteractor>()
    private val displaySwitchLatencyLogger = mock<DisplaySwitchLatencyLogger>()
    private val latencyTracker = mock<LatencyTracker>()

    private val deviceStateManager = kosmos.deviceStateManager
    private val closedDeviceState = kosmos.foldedDeviceStateList.first()
@@ -142,6 +151,7 @@ class DisplaySwitchLatencyTrackerTest : SysuiTestCase() {
                displaySwitchLatencyLogger,
                systemClock,
                deviceStateManager,
                latencyTracker,
            )
    }

@@ -195,6 +205,7 @@ class DisplaySwitchLatencyTrackerTest : SysuiTestCase() {
                    displaySwitchLatencyLogger,
                    systemClock,
                    deviceStateManager,
                    latencyTracker,
                )

            displaySwitchLatencyTracker.start()
@@ -370,6 +381,256 @@ class DisplaySwitchLatencyTrackerTest : SysuiTestCase() {
        }
    }

    @Test
    fun unfoldingDevice_startsLatencyTracking() {
        testScope.runTest {
            startInFoldedState(displaySwitchLatencyTracker)

            startUnfolding()

            verify(latencyTracker).onActionStart(ACTION_SWITCH_DISPLAY_UNFOLD)
        }
    }

    @Test
    fun foldingDevice_doesntTrackLatency() {
        testScope.runTest {
            setDeviceState(UNFOLDED)
            displaySwitchLatencyTracker.start()
            runCurrent()

            startFolding()

            verify(latencyTracker, never()).onActionStart(ACTION_SWITCH_DISPLAY_UNFOLD)
        }
    }

    @Test
    fun foldedState_doesntStartTrackingOnScreenOn() {
        testScope.runTest {
            startInFoldedState(displaySwitchLatencyTracker)

            powerInteractor.setScreenPowerState(SCREEN_ON)
            runCurrent()

            verify(latencyTracker, never()).onActionStart(ACTION_SWITCH_DISPLAY_UNFOLD)
        }
    }

    @Test
    fun unfoldingDevice_endsLatencyTrackingWhenTransitionStarts() {
        testScope.runTest {
            startInFoldedState(displaySwitchLatencyTracker)

            startUnfolding()
            unfoldTransitionProgressProvider.onTransitionStarted()
            runCurrent()

            verify(latencyTracker).onActionEnd(ACTION_SWITCH_DISPLAY_UNFOLD)
        }
    }

    @Test
    fun unfoldingDevice_animationsDisabled_endsLatencyTrackingWhenScreenOn() {
        testScope.runTest {
            animationStatusRepository.onAnimationStatusChanged(enabled = false)
            startInFoldedState(displaySwitchLatencyTracker)

            startUnfolding()
            powerInteractor.setScreenPowerState(SCREEN_ON)
            runCurrent()

            verify(latencyTracker).onActionEnd(ACTION_SWITCH_DISPLAY_UNFOLD)
        }
    }

    @Test
    fun unfoldingDevice_doesntEndLatencyTrackingWhenScreenOn() {
        testScope.runTest {
            startInFoldedState(displaySwitchLatencyTracker)

            startUnfolding()
            powerInteractor.setScreenPowerState(SCREEN_ON)
            runCurrent()

            verify(latencyTracker, never()).onActionEnd(ACTION_SWITCH_DISPLAY_UNFOLD)
        }
    }

    @Test
    fun unfoldingDevice_animationsDisabled_endsLatencyTrackingWhenDeviceGoesToSleep() {
        testScope.runTest {
            animationStatusRepository.onAnimationStatusChanged(enabled = false)
            startInFoldedState(displaySwitchLatencyTracker)

            startUnfolding()
            powerInteractor.setAsleepForTest(sleepReason = GO_TO_SLEEP_REASON_POWER_BUTTON)
            runCurrent()

            verify(latencyTracker).onActionEnd(ACTION_SWITCH_DISPLAY_UNFOLD)
        }
    }

    @Test
    fun displaySwitchInterrupted_cancelsTrackingWhenNewDeviceStateEmitted() {
        testScope.runTest {
            startInFoldedState(displaySwitchLatencyTracker)

            startUnfolding()
            startFolding()
            finishFolding()

            verify(latencyTracker).onActionCancel(ACTION_SWITCH_DISPLAY_UNFOLD)
            verify(latencyTracker, never()).onActionEnd(ACTION_SWITCH_DISPLAY_UNFOLD)
        }
    }

    @Test
    fun displaySwitchInterrupted_cancelsTrackingForManyStateChanges() {
        testScope.runTest {
            startInFoldedState(displaySwitchLatencyTracker)

            startUnfolding()
            startFolding()
            startUnfolding()
            startFolding()
            startUnfolding()
            finishUnfolding()

            verify(latencyTracker).onActionCancel(ACTION_SWITCH_DISPLAY_UNFOLD)
            verify(latencyTracker, never()).onActionEnd(ACTION_SWITCH_DISPLAY_UNFOLD)
        }
    }

    @Test
    fun displaySwitchInterrupted_startsOneTrackingForManyStateChanges() {
        testScope.runTest {
            startInFoldedState(displaySwitchLatencyTracker)

            startUnfolding()
            startFolding()
            startUnfolding()
            startFolding()
            startUnfolding()

            verify(latencyTracker, times(1)).onActionStart(ACTION_SWITCH_DISPLAY_UNFOLD)
        }
    }

    @Test
    fun interruptedDisplaySwitchFinished_inCoolDownPeriod_trackingDisabled() {
        testScope.runTest {
            startInFoldedState(displaySwitchLatencyTracker)

            startUnfolding()
            startFolding()
            finishFolding()

            advanceTimeBy(COOL_DOWN_DURATION.minus(10.milliseconds))
            startUnfolding()
            finishUnfolding()

            verify(latencyTracker, times(1)).onActionStart(ACTION_SWITCH_DISPLAY_UNFOLD)
            verify(latencyTracker, never()).onActionEnd(ACTION_SWITCH_DISPLAY_UNFOLD)
        }
    }

    @Test
    fun interruptedDisplaySwitchFinished_coolDownPassed_trackingWorksAsUsual() {
        testScope.runTest {
            startInFoldedState(displaySwitchLatencyTracker)

            startUnfolding()
            startFolding()
            finishFolding()

            advanceTimeBy(COOL_DOWN_DURATION.plus(10.milliseconds))
            startUnfolding()
            finishUnfolding()

            verify(latencyTracker, times(2)).onActionStart(ACTION_SWITCH_DISPLAY_UNFOLD)
            verify(latencyTracker).onActionEnd(ACTION_SWITCH_DISPLAY_UNFOLD)
        }
    }

    @Test
    fun displaySwitchInterrupted_coolDownExtendedByStartEvents() {
        testScope.runTest {
            startInFoldedState(displaySwitchLatencyTracker)

            startUnfolding()
            startFolding()
            advanceTimeBy(COOL_DOWN_DURATION.minus(10.milliseconds))
            startUnfolding()
            advanceTimeBy(20.milliseconds)

            startFolding()
            finishUnfolding()

            verify(latencyTracker, never()).onActionEnd(ACTION_SWITCH_DISPLAY_UNFOLD)
        }
    }

    @Test
    fun displaySwitchInterrupted_coolDownExtendedByAnyEndEvent() {
        testScope.runTest {
            startInFoldedState(displaySwitchLatencyTracker)

            startUnfolding()
            startFolding()
            startUnfolding()
            advanceTimeBy(COOL_DOWN_DURATION - 10.milliseconds)
            powerInteractor.setScreenPowerState(SCREEN_ON)
            advanceTimeBy(20.milliseconds)

            startFolding()
            finishUnfolding()

            verify(latencyTracker, never()).onActionEnd(ACTION_SWITCH_DISPLAY_UNFOLD)
        }
    }

    @Test
    fun displaySwitchTimedOut_trackingCancelled() {
        testScope.runTest {
            startInFoldedState(displaySwitchLatencyTracker)

            startUnfolding()
            advanceTimeBy(SCREEN_EVENT_TIMEOUT + 10.milliseconds)
            finishUnfolding()

            verify(latencyTracker).onActionCancel(ACTION_SWITCH_DISPLAY_UNFOLD)
        }
    }

    private suspend fun TestScope.startInFoldedState(tracker: DisplaySwitchLatencyTracker) {
        setDeviceState(FOLDED)
        tracker.start()
        runCurrent()
    }

    private suspend fun TestScope.startUnfolding() {
        setDeviceState(HALF_FOLDED)
        powerInteractor.setScreenPowerState(SCREEN_OFF)
        runCurrent()
    }

    private suspend fun TestScope.startFolding() {
        setDeviceState(FOLDED)
        powerInteractor.setScreenPowerState(SCREEN_OFF)
        runCurrent()
    }

    private fun TestScope.finishFolding() {
        powerInteractor.setScreenPowerState(SCREEN_ON)
        runCurrent()
    }

    private fun TestScope.finishUnfolding() {
        unfoldTransitionProgressProvider.onTransitionStarted()
        runCurrent()
    }

    private suspend fun setDeviceState(state: DeviceState) {
        foldStateRepository.emit(state)
    }
+15 −6
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.systemui.dagger

import com.android.keyguard.KeyguardBiometricLockoutLogger
import com.android.systemui.CoreStartable
import com.android.systemui.Flags.unfoldLatencyTrackingFix
import com.android.systemui.LatencyTester
import com.android.systemui.SliceBroadcastRelayHandler
import com.android.systemui.accessibility.Magnification
@@ -60,6 +61,7 @@ import com.android.systemui.stylus.StylusUsiPowerStartable
import com.android.systemui.temporarydisplay.chipbar.ChipbarCoordinator
import com.android.systemui.theme.ThemeOverlayController
import com.android.systemui.unfold.DisplaySwitchLatencyTracker
import com.android.systemui.unfold.NoCooldownDisplaySwitchLatencyTracker
import com.android.systemui.usb.StorageNotification
import com.android.systemui.util.NotificationChannels
import com.android.systemui.util.StartBinderLoggerModule
@@ -67,8 +69,10 @@ import com.android.systemui.wallpapers.dagger.WallpaperModule
import com.android.systemui.wmshell.WMShell
import dagger.Binds
import dagger.Module
import dagger.Provides
import dagger.multibindings.ClassKey
import dagger.multibindings.IntoMap
import javax.inject.Provider

/**
 * DEPRECATED: DO NOT ADD THINGS TO THIS FILE.
@@ -148,12 +152,6 @@ abstract class SystemUICoreStartableModule {
    @ClassKey(LatencyTester::class)
    abstract fun bindLatencyTester(sysui: LatencyTester): CoreStartable

    /** Inject into DisplaySwitchLatencyTracker. */
    @Binds
    @IntoMap
    @ClassKey(DisplaySwitchLatencyTracker::class)
    abstract fun bindDisplaySwitchLatencyTracker(sysui: DisplaySwitchLatencyTracker): CoreStartable

    /** Inject into NotificationChannels. */
    @Binds
    @IntoMap
@@ -353,4 +351,15 @@ abstract class SystemUICoreStartableModule {
    @IntoMap
    @ClassKey(ComplicationTypesUpdater::class)
    abstract fun bindComplicationTypesUpdater(updater: ComplicationTypesUpdater): CoreStartable

    companion object {
        @Provides
        @IntoMap
        @ClassKey(DisplaySwitchLatencyTracker::class)
        fun provideDisplaySwitchLatencyTracker(
            noCoolDownVariant: Provider<NoCooldownDisplaySwitchLatencyTracker>,
            coolDownVariant: Provider<DisplaySwitchLatencyTracker>,
        ): CoreStartable =
            if (unfoldLatencyTrackingFix()) coolDownVariant.get() else noCoolDownVariant.get()
    }
}
+105 −48
Original line number Diff line number Diff line
@@ -19,8 +19,11 @@ package com.android.systemui.unfold
import android.content.Context
import android.hardware.devicestate.DeviceStateManager
import android.util.Log
import androidx.annotation.VisibleForTesting
import com.android.app.tracing.TraceUtils.traceAsync
import com.android.app.tracing.instantForTrack
import com.android.internal.util.LatencyTracker
import com.android.internal.util.LatencyTracker.ACTION_SWITCH_DISPLAY_UNFOLD
import com.android.systemui.CoreStartable
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
@@ -30,10 +33,12 @@ import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
import com.android.systemui.power.domain.interactor.PowerInteractor
import com.android.systemui.power.shared.model.ScreenPowerState
import com.android.systemui.power.shared.model.WakeSleepReason
import com.android.systemui.power.shared.model.WakefulnessModel
import com.android.systemui.power.shared.model.WakefulnessState
import com.android.systemui.shared.system.SysUiStatsLog
import com.android.systemui.unfold.DisplaySwitchLatencyTracker.DisplaySwitchLatencyEvent
import com.android.systemui.unfold.dagger.UnfoldSingleThreadBg
import com.android.systemui.unfold.data.repository.UnfoldTransitionStatus.TransitionStarted
import com.android.systemui.unfold.domain.interactor.UnfoldTransitionInteractor
import com.android.systemui.util.Compile
import com.android.systemui.util.Utils.isDeviceFoldable
@@ -42,17 +47,23 @@ import com.android.systemui.util.kotlin.pairwise
import com.android.systemui.util.kotlin.race
import com.android.systemui.util.time.SystemClock
import com.android.systemui.util.time.measureTimeMillis
import java.time.Duration
import java.util.concurrent.Executor
import javax.inject.Inject
import kotlin.coroutines.cancellation.CancellationException
import kotlin.time.Duration.Companion.seconds
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.TimeoutCancellationException
import kotlinx.coroutines.asCoroutineDispatcher
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.drop
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flow
import com.android.app.tracing.coroutines.launchTraced as launch
import kotlinx.coroutines.flow.merge
import kotlinx.coroutines.flow.timeout
import kotlinx.coroutines.launch
import kotlinx.coroutines.withTimeout

/**
@@ -73,63 +84,96 @@ constructor(
    @Application private val applicationScope: CoroutineScope,
    private val displaySwitchLatencyLogger: DisplaySwitchLatencyLogger,
    private val systemClock: SystemClock,
    private val deviceStateManager: DeviceStateManager
    private val deviceStateManager: DeviceStateManager,
    private val latencyTracker: LatencyTracker,
) : CoreStartable {

    private val backgroundDispatcher = singleThreadBgExecutor.asCoroutineDispatcher()
    private val isAodEnabled: Boolean
        get() = keyguardInteractor.isAodAvailable.value

    override fun start() {
        if (!isDeviceFoldable(context.resources, deviceStateManager)) {
            return
        }
        applicationScope.launch(context = backgroundDispatcher) {
            deviceStateRepository.state
                .pairwise()
                .filter {
    private val displaySwitchStarted =
        deviceStateRepository.state.pairwise().filter {
            // Start tracking only when the foldable device is
                    // folding(UNFOLDED/HALF_FOLDED -> FOLDED) or
                    // unfolding(FOLDED -> HALF_FOLD/UNFOLDED)
            // folding(UNFOLDED/HALF_FOLDED -> FOLDED) or unfolding(FOLDED -> HALF_FOLD/UNFOLDED)
            foldableDeviceState ->
            foldableDeviceState.previousValue == DeviceState.FOLDED ||
                foldableDeviceState.newValue == DeviceState.FOLDED
        }
                .flatMapLatest { foldableDeviceState ->
                    flow {
                        var displaySwitchLatencyEvent = DisplaySwitchLatencyEvent()
                        val toFoldableDeviceState = foldableDeviceState.newValue.toStatsInt()
                        displaySwitchLatencyEvent =
                            displaySwitchLatencyEvent.withBeforeFields(
                                foldableDeviceState.previousValue.toStatsInt()
                            )

                        val displaySwitchTimeMs =
                            measureTimeMillis(systemClock) {
    private var startOrEndEvent: Flow<Any> = merge(displaySwitchStarted, anyEndEventFlow())

    private var isCoolingDown = false

    override fun start() {
        if (!isDeviceFoldable(context.resources, deviceStateManager)) {
            return
        }
        applicationScope.launch(context = backgroundDispatcher) {
            displaySwitchStarted.collectLatest { (previousState, newState) ->
                if (isCoolingDown) return@collectLatest
                if (previousState == DeviceState.FOLDED) {
                    latencyTracker.onActionStart(ACTION_SWITCH_DISPLAY_UNFOLD)
                    instantForTrack(TAG) { "unfold latency tracking started" }
                }
                try {
                    withTimeout(SCREEN_EVENT_TIMEOUT) {
                        val event =
                            DisplaySwitchLatencyEvent().withBeforeFields(previousState.toStatsInt())
                        val displaySwitchTimeMs =
                            measureTimeMillis(systemClock) {
                                traceAsync(TAG, "displaySwitch") {
                                            waitForDisplaySwitch(toFoldableDeviceState)
                                    waitForDisplaySwitch(newState.toStatsInt())
                                }
                            }
                        if (previousState == DeviceState.FOLDED) {
                            latencyTracker.onActionEnd(ACTION_SWITCH_DISPLAY_UNFOLD)
                        }
                        logDisplaySwitchEvent(event, newState, displaySwitchTimeMs)
                    }
                } catch (e: TimeoutCancellationException) {
                                    Log.e(TAG, "Wait for display switch timed out")
                    instantForTrack(TAG) { "tracking timed out" }
                    latencyTracker.onActionCancel(ACTION_SWITCH_DISPLAY_UNFOLD)
                } catch (e: CancellationException) {
                    instantForTrack(TAG) { "new state interrupted, entering cool down" }
                    latencyTracker.onActionCancel(ACTION_SWITCH_DISPLAY_UNFOLD)
                    startCoolDown()
                }
            }
        }
    }

                        displaySwitchLatencyEvent =
                            displaySwitchLatencyEvent.withAfterFields(
                                toFoldableDeviceState,
                                displaySwitchTimeMs.toInt(),
                                getCurrentState()
                            )
                        emit(displaySwitchLatencyEvent)
    @OptIn(FlowPreview::class)
    private fun startCoolDown() {
        if (isCoolingDown) return
        isCoolingDown = true
        applicationScope.launch(context = backgroundDispatcher) {
            val startTime = systemClock.elapsedRealtime()
            try {
                startOrEndEvent.timeout(COOL_DOWN_DURATION).collect()
            } catch (e: TimeoutCancellationException) {
                instantForTrack(TAG) {
                    "cool down finished, lasted ${systemClock.elapsedRealtime() - startTime} ms"
                }
                isCoolingDown = false
            }
                .collect { displaySwitchLatencyLogger.log(it) }
        }
    }

    private fun logDisplaySwitchEvent(
        event: DisplaySwitchLatencyEvent,
        toFoldableDeviceState: DeviceState,
        displaySwitchTimeMs: Long,
    ) {
        displaySwitchLatencyLogger.log(
            event.withAfterFields(
                toFoldableDeviceState.toStatsInt(),
                displaySwitchTimeMs.toInt(),
                getCurrentState(),
            )
        )
    }

    private fun DeviceState.toStatsInt(): Int =
        when (this) {
            DeviceState.FOLDED -> FOLDABLE_DEVICE_STATE_CLOSED
@@ -152,9 +196,20 @@ constructor(
        }
    }

    private fun anyEndEventFlow(): Flow<Any> {
        val unfoldStatus =
            unfoldTransitionInteractor.unfoldTransitionStatus.filter { it is TransitionStarted }
        // dropping first emission as we're only interested in new emissions, not current state
        val screenOn =
            powerInteractor.screenPowerState.drop(1).filter { it == ScreenPowerState.SCREEN_ON }
        val goToSleep =
            powerInteractor.detailedWakefulness.drop(1).filter { sleepWithScreenOff(it) }
        return merge(screenOn, goToSleep, unfoldStatus)
    }

    private fun shouldWaitForTransitionStart(
        toFoldableDeviceState: Int,
        isTransitionEnabled: Boolean
        isTransitionEnabled: Boolean,
    ): Boolean = (toFoldableDeviceState != FOLDABLE_DEVICE_STATE_CLOSED && isTransitionEnabled)

    private suspend fun waitForScreenTurnedOn() {
@@ -165,12 +220,13 @@ constructor(

    private suspend fun waitForGoToSleepWithScreenOff() {
        traceAsync(TAG, "waitForGoToSleepWithScreenOff()") {
            powerInteractor.detailedWakefulness
                .filter { it.internalWakefulnessState == WakefulnessState.ASLEEP && !isAodEnabled }
                .first()
            powerInteractor.detailedWakefulness.filter { sleepWithScreenOff(it) }.first()
        }
    }

    private fun sleepWithScreenOff(model: WakefulnessModel) =
        model.internalWakefulnessState == WakefulnessState.ASLEEP && !isAodEnabled

    private fun getCurrentState(): Int =
        when {
            isStateAod() -> SysUiStatsLog.DISPLAY_SWITCH_LATENCY_TRACKED__TO_STATE__AOD
@@ -205,7 +261,7 @@ constructor(
    private fun DisplaySwitchLatencyEvent.withAfterFields(
        toFoldableDeviceState: Int,
        displaySwitchTimeMs: Int,
        toState: Int
        toState: Int,
    ): DisplaySwitchLatencyEvent {
        log {
            "toFoldableDeviceState=$toFoldableDeviceState, " +
@@ -217,7 +273,7 @@ constructor(
        return copy(
            toFoldableDeviceState = toFoldableDeviceState,
            latencyMs = displaySwitchTimeMs,
            toState = toState
            toState = toState,
        )
    }

@@ -250,14 +306,15 @@ constructor(
        val hallSensorToFirstHingeAngleChangeMs: Int = VALUE_UNKNOWN,
        val hallSensorToDeviceStateChangeMs: Int = VALUE_UNKNOWN,
        val onScreenTurningOnToOnDrawnMs: Int = VALUE_UNKNOWN,
        val onDrawnToOnScreenTurnedOnMs: Int = VALUE_UNKNOWN
        val onDrawnToOnScreenTurnedOnMs: Int = VALUE_UNKNOWN,
    )

    companion object {
        private const val VALUE_UNKNOWN = -1
        private const val TAG = "DisplaySwitchLatency"
        private val DEBUG = Compile.IS_DEBUG && Log.isLoggable(TAG, Log.VERBOSE)
        private val SCREEN_EVENT_TIMEOUT = Duration.ofMillis(15000).toMillis()
        @VisibleForTesting val SCREEN_EVENT_TIMEOUT = 15.seconds
        @VisibleForTesting val COOL_DOWN_DURATION = 2.seconds

        private const val FOLDABLE_DEVICE_STATE_UNKNOWN =
            SysUiStatsLog.DISPLAY_SWITCH_LATENCY_TRACKED__FROM_FOLDABLE_DEVICE_STATE__STATE_UNKNOWN
+243 −0

File added.

Preview size limit exceeded, changes collapsed.

Loading