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

Commit 3e19bedf authored by Jernej Virag's avatar Jernej Virag
Browse files

Cleanup trim caches flags

Enabling those flags creates too much jank so we're not going to roll
them out. Clean up the code behind them.

Bug: 283203305
Bug: 322143614

Flag: com.android.systemui.trim_resources_with_background_trim_at_lock_launch
Test: unit tests present
Change-Id: I2310f14145e93027b4cb6229e7811030f3087aef
parent b9148d32
Loading
Loading
Loading
Loading
+0 −10
Original line number Diff line number Diff line
@@ -735,16 +735,6 @@ flag {
    }
}

flag {
    name: "trim_resources_with_background_trim_at_lock"
    namespace: "systemui"
    description: "Trim fonts and other caches when the device locks to lower memory consumption."
    bug: "322143614"
    metadata {
        purpose: PURPOSE_BUGFIX
    }
}

flag {
    name: "dedicated_notif_inflation_thread"
    namespace: "systemui"
+0 −3
Original line number Diff line number Diff line
@@ -400,9 +400,6 @@ object Flags {
    val WARN_ON_BLOCKING_BINDER_TRANSACTIONS =
        unreleasedFlag("warn_on_blocking_binder_transactions")

    // TODO:(b/283203305): Tracking bug
    @JvmField val TRIM_FONT_CACHES_AT_UNLOCK = unreleasedFlag("trim_font_caches_on_unlock")

    // TODO(b/298380520): Tracking Bug
    @JvmField
    val USER_TRACKER_BACKGROUND_CALLBACKS = unreleasedFlag("user_tracker_background_callbacks")
+1 −70
Original line number Diff line number Diff line
@@ -18,21 +18,15 @@ package com.android.systemui.keyguard

import android.annotation.WorkerThread
import android.content.ComponentCallbacks2
import android.graphics.HardwareRenderer
import android.os.Trace
import android.util.Log
import com.android.systemui.CoreStartable
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.Flags
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
import com.android.systemui.keyguard.shared.model.Edge
import com.android.systemui.keyguard.shared.model.KeyguardState.GONE
import com.android.systemui.keyguard.shared.model.TransitionState
import com.android.systemui.power.domain.interactor.PowerInteractor
import com.android.systemui.scene.domain.interactor.SceneInteractor
import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.scene.shared.model.Scenes
@@ -40,10 +34,7 @@ import com.android.systemui.utils.GlobalWindowManager
import javax.inject.Inject
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch

/**
@@ -57,37 +48,15 @@ import kotlinx.coroutines.launch
class ResourceTrimmer
@Inject
constructor(
    private val keyguardInteractor: KeyguardInteractor,
    private val powerInteractor: PowerInteractor,
    private val keyguardTransitionInteractor: KeyguardTransitionInteractor,
    private val globalWindowManager: GlobalWindowManager,
    @Application private val applicationScope: CoroutineScope,
    @Background private val bgDispatcher: CoroutineDispatcher,
    private val featureFlags: FeatureFlags,
    private val sceneInteractor: SceneInteractor,
) : CoreStartable, WakefulnessLifecycle.Observer {
) : CoreStartable {

    override fun start() {
        Log.d(LOG_TAG, "Resource trimmer registered.")
        if (com.android.systemui.Flags.trimResourcesWithBackgroundTrimAtLock()) {
            applicationScope.launch(bgDispatcher) {
                // We need to wait for the AoD transition (and animation) to complete.
                // This means we're waiting for isDreaming (== implies isDoze) and dozeAmount == 1f
                // signal. This is to make sure we don't clear font caches during animation which
                // would jank and leave stale data in memory.
                val isDozingFully =
                    keyguardInteractor.dozeAmount.map { it == 1f }.distinctUntilChanged()
                combine(
                        powerInteractor.isAsleep,
                        keyguardInteractor.isDreaming,
                        isDozingFully,
                        ::Triple
                    )
                    .distinctUntilChanged()
                    .collect { onWakefulnessUpdated(it.first, it.second, it.third) }
            }
        }

        applicationScope.launch(bgDispatcher) {
            // We drop 1 to avoid triggering on initial collect().
            if (SceneContainerFlag.isEnabled) {
@@ -110,47 +79,9 @@ constructor(
        // lockscreen elements, especially clocks.
        Log.d(LOG_TAG, "Sending TRIM_MEMORY_UI_HIDDEN.")
        globalWindowManager.trimMemory(ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN)
        if (featureFlags.isEnabled(Flags.TRIM_FONT_CACHES_AT_UNLOCK)) {
            if (DEBUG) {
                Log.d(LOG_TAG, "Trimming font caches since keyguard went away.")
            }
            globalWindowManager.trimCaches(HardwareRenderer.CACHE_TRIM_FONT)
        }
    }

    @WorkerThread
    private fun onWakefulnessUpdated(
        isAsleep: Boolean,
        isDreaming: Boolean,
        isDozingFully: Boolean
    ) {
        if (!com.android.systemui.Flags.trimResourcesWithBackgroundTrimAtLock()) {
            return
        }

        if (DEBUG) {
            Log.d(LOG_TAG, "isAsleep: $isAsleep Dreaming: $isDreaming DozeAmount: $isDozingFully")
        }
        // There are three scenarios:
        // * No dozing and no AoD at all - where we go directly to ASLEEP with isDreaming = false
        //      and dozeAmount == 0f
        // * Dozing without Aod - where we go to ASLEEP with isDreaming = true and dozeAmount jumps
        //      to 1f
        // * AoD - where we go to ASLEEP with iDreaming = true and dozeAmount slowly increases
        //      to 1f
        val dozeDisabledAndScreenOff = isAsleep && !isDreaming
        val dozeEnabledAndDozeAnimationCompleted = isAsleep && isDreaming && isDozingFully
        if (dozeDisabledAndScreenOff || dozeEnabledAndDozeAnimationCompleted) {
            Trace.beginSection("ResourceTrimmer#trimMemory")
            Log.d(LOG_TAG, "SysUI asleep, trimming memory.")
            globalWindowManager.trimMemory(ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN)
            globalWindowManager.trimCaches(HardwareRenderer.CACHE_TRIM_ALL)
            Trace.endSection()
        }
    }

    companion object {
        private const val LOG_TAG = "ResourceTrimmer"
        private val DEBUG = Log.isLoggable(LOG_TAG, Log.DEBUG)
    }
}
+2 −117
Original line number Diff line number Diff line
package com.android.systemui.keyguard

import android.content.ComponentCallbacks2
import android.graphics.HardwareRenderer
import android.platform.test.annotations.DisableFlags
import android.platform.test.annotations.EnableFlags
import android.platform.test.flag.junit.SetFlagsRule
import android.testing.AndroidTestingRunner
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.flags.DisableSceneContainer
import com.android.systemui.flags.EnableSceneContainer
import com.android.systemui.flags.Flags
import com.android.systemui.flags.fakeFeatureFlagsClassic
import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractorFactory
import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.kosmos.testDispatcher
@@ -26,7 +21,6 @@ import com.android.systemui.scene.data.repository.setSceneTransition
import com.android.systemui.scene.domain.interactor.sceneInteractor
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.testKosmos
import com.android.systemui.util.mockito.any
import com.android.systemui.utils.GlobalWindowManager
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.runCurrent
@@ -62,52 +56,21 @@ class ResourceTrimmerTest : SysuiTestCase() {
    @Before
    fun setUp() {
        MockitoAnnotations.initMocks(this)
        featureFlags.set(Flags.TRIM_FONT_CACHES_AT_UNLOCK, true)
        keyguardRepository.setDozeAmount(0f)
        keyguardRepository.setKeyguardGoingAway(false)

        val withDeps =
            KeyguardInteractorFactory.create(
                featureFlags = featureFlags,
                repository = keyguardRepository,
            )
        val keyguardInteractor = withDeps.keyguardInteractor
        resourceTrimmer =
            ResourceTrimmer(
                keyguardInteractor,
                powerInteractor = powerInteractor,
                keyguardTransitionInteractor = kosmos.keyguardTransitionInteractor,
                globalWindowManager = globalWindowManager,
                applicationScope = testScope.backgroundScope,
                bgDispatcher = kosmos.testDispatcher,
                featureFlags = featureFlags,
                sceneInteractor = kosmos.sceneInteractor,
            )
        resourceTrimmer.start()
    }

    @Test
    @EnableFlags(com.android.systemui.Flags.FLAG_TRIM_RESOURCES_WITH_BACKGROUND_TRIM_AT_LOCK)
    fun noChange_noOutputChanges() =
        testScope.runTest {
            testScope.runCurrent()
            verifyZeroInteractions(globalWindowManager)
        }

    @Test
    @EnableFlags(com.android.systemui.Flags.FLAG_TRIM_RESOURCES_WITH_BACKGROUND_TRIM_AT_LOCK)
    fun dozeAodDisabled_sleep_trimsMemory() =
        testScope.runTest {
            powerInteractor.setAsleepForTest()
            testScope.runCurrent()
            verify(globalWindowManager, times(1))
                .trimMemory(ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN)
            verify(globalWindowManager, times(1)).trimCaches(HardwareRenderer.CACHE_TRIM_ALL)
        }

    @Test
    @DisableFlags(com.android.systemui.Flags.FLAG_TRIM_RESOURCES_WITH_BACKGROUND_TRIM_AT_LOCK)
    fun dozeAodDisabled_flagDisabled_sleep_doesntTrimMemory() =
    fun dozeAodDisabled_sleep_doesntTrimMemory() =
        testScope.runTest {
            powerInteractor.setAsleepForTest()
            testScope.runCurrent()
@@ -115,8 +78,7 @@ class ResourceTrimmerTest : SysuiTestCase() {
        }

    @Test
    @DisableFlags(com.android.systemui.Flags.FLAG_TRIM_RESOURCES_WITH_BACKGROUND_TRIM_AT_LOCK)
    fun dozeEnabled_flagDisabled_sleepWithFullDozeAmount_doesntTrimMemory() =
    fun dozeEnabled_sleepWithFullDozeAmount_doesntTrimMemory() =
        testScope.runTest {
            keyguardRepository.setDreaming(true)
            keyguardRepository.setDozeAmount(1f)
@@ -126,20 +88,6 @@ class ResourceTrimmerTest : SysuiTestCase() {
        }

    @Test
    @EnableFlags(com.android.systemui.Flags.FLAG_TRIM_RESOURCES_WITH_BACKGROUND_TRIM_AT_LOCK)
    fun dozeEnabled_sleepWithFullDozeAmount_trimsMemory() =
        testScope.runTest {
            keyguardRepository.setDreaming(true)
            keyguardRepository.setDozeAmount(1f)
            powerInteractor.setAsleepForTest()
            testScope.runCurrent()
            verify(globalWindowManager, times(1))
                .trimMemory(ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN)
            verify(globalWindowManager, times(1)).trimCaches(HardwareRenderer.CACHE_TRIM_ALL)
        }

    @Test
    @EnableFlags(com.android.systemui.Flags.FLAG_TRIM_RESOURCES_WITH_BACKGROUND_TRIM_AT_LOCK)
    fun dozeEnabled_sleepWithoutFullDozeAmount_doesntTrimMemory() =
        testScope.runTest {
            keyguardRepository.setDreaming(true)
@@ -150,34 +98,6 @@ class ResourceTrimmerTest : SysuiTestCase() {
        }

    @Test
    @EnableFlags(com.android.systemui.Flags.FLAG_TRIM_RESOURCES_WITH_BACKGROUND_TRIM_AT_LOCK)
    fun aodEnabled_sleepWithFullDozeAmount_trimsMemoryOnce() {
        testScope.runTest {
            keyguardRepository.setDreaming(true)
            keyguardRepository.setDozeAmount(0f)
            powerInteractor.setAsleepForTest()

            testScope.runCurrent()
            verifyZeroInteractions(globalWindowManager)

            generateSequence(0f) { it + 0.1f }
                .takeWhile { it < 1f }
                .forEach {
                    keyguardRepository.setDozeAmount(it)
                    testScope.runCurrent()
                }
            verifyZeroInteractions(globalWindowManager)

            keyguardRepository.setDozeAmount(1f)
            testScope.runCurrent()
            verify(globalWindowManager, times(1))
                .trimMemory(ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN)
            verify(globalWindowManager, times(1)).trimCaches(HardwareRenderer.CACHE_TRIM_ALL)
        }
    }

    @Test
    @EnableFlags(com.android.systemui.Flags.FLAG_TRIM_RESOURCES_WITH_BACKGROUND_TRIM_AT_LOCK)
    fun aodEnabled_deviceWakesHalfWayThrough_doesNotTrimMemory() {
        testScope.runTest {
            keyguardRepository.setDreaming(true)
@@ -209,7 +129,6 @@ class ResourceTrimmerTest : SysuiTestCase() {
    }

    @Test
    @EnableFlags(com.android.systemui.Flags.FLAG_TRIM_RESOURCES_WITH_BACKGROUND_TRIM_AT_LOCK)
    @DisableSceneContainer
    fun keyguardTransitionsToGone_trimsFontCache() =
        testScope.runTest {
@@ -220,12 +139,10 @@ class ResourceTrimmerTest : SysuiTestCase() {
            )
            verify(globalWindowManager, times(1))
                .trimMemory(ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN)
            verify(globalWindowManager, times(1)).trimCaches(HardwareRenderer.CACHE_TRIM_FONT)
            verifyNoMoreInteractions(globalWindowManager)
        }

    @Test
    @EnableFlags(com.android.systemui.Flags.FLAG_TRIM_RESOURCES_WITH_BACKGROUND_TRIM_AT_LOCK)
    @EnableSceneContainer
    fun keyguardTransitionsToGone_trimsFontCache_scene_container() =
        testScope.runTest {
@@ -233,38 +150,6 @@ class ResourceTrimmerTest : SysuiTestCase() {

            verify(globalWindowManager, times(1))
                .trimMemory(ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN)
            verify(globalWindowManager, times(1)).trimCaches(HardwareRenderer.CACHE_TRIM_FONT)
            verifyNoMoreInteractions(globalWindowManager)
        }

    @Test
    @EnableFlags(com.android.systemui.Flags.FLAG_TRIM_RESOURCES_WITH_BACKGROUND_TRIM_AT_LOCK)
    @DisableSceneContainer
    fun keyguardTransitionsToGone_flagDisabled_doesNotTrimFontCache() =
        testScope.runTest {
            featureFlags.set(Flags.TRIM_FONT_CACHES_AT_UNLOCK, false)
            keyguardTransitionRepository.sendTransitionSteps(
                from = KeyguardState.LOCKSCREEN,
                to = KeyguardState.GONE,
                testScope
            )
            // Memory hidden should still be called.
            verify(globalWindowManager, times(1))
                .trimMemory(ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN)
            verify(globalWindowManager, times(0)).trimCaches(any())
        }

    @Test
    @EnableFlags(com.android.systemui.Flags.FLAG_TRIM_RESOURCES_WITH_BACKGROUND_TRIM_AT_LOCK)
    @EnableSceneContainer
    fun keyguardTransitionsToGone_flagDisabled_doesNotTrimFontCache_scene_container() =
        testScope.runTest {
            featureFlags.set(Flags.TRIM_FONT_CACHES_AT_UNLOCK, false)
            kosmos.setSceneTransition(Idle(Scenes.Gone))

            // Memory hidden should still be called.
            verify(globalWindowManager, times(1))
                .trimMemory(ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN)
            verify(globalWindowManager, times(0)).trimCaches(any())
        }
}