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

Commit 22392c86 authored by Jernej Virag's avatar Jernej Virag Committed by Android (Google) Code Review
Browse files

Merge "Cleanup trim caches flags" into main

parents a36d1042 3e19bedf
Loading
Loading
Loading
Loading
+0 −10
Original line number Original line 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 {
flag {
    name: "dedicated_notif_inflation_thread"
    name: "dedicated_notif_inflation_thread"
    namespace: "systemui"
    namespace: "systemui"
+0 −3
Original line number Original line Diff line number Diff line
@@ -378,9 +378,6 @@ object Flags {
    val WARN_ON_BLOCKING_BINDER_TRANSACTIONS =
    val WARN_ON_BLOCKING_BINDER_TRANSACTIONS =
        unreleasedFlag("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
    // TODO(b/298380520): Tracking Bug
    @JvmField
    @JvmField
    val USER_TRACKER_BACKGROUND_CALLBACKS = unreleasedFlag("user_tracker_background_callbacks")
    val USER_TRACKER_BACKGROUND_CALLBACKS = unreleasedFlag("user_tracker_background_callbacks")
+1 −70
Original line number Original line Diff line number Diff line
@@ -18,21 +18,15 @@ package com.android.systemui.keyguard


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


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


    override fun start() {
    override fun start() {
        Log.d(LOG_TAG, "Resource trimmer registered.")
        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) {
        applicationScope.launch(bgDispatcher) {
            // We drop 1 to avoid triggering on initial collect().
            // We drop 1 to avoid triggering on initial collect().
            if (SceneContainerFlag.isEnabled) {
            if (SceneContainerFlag.isEnabled) {
@@ -110,47 +79,9 @@ constructor(
        // lockscreen elements, especially clocks.
        // lockscreen elements, especially clocks.
        Log.d(LOG_TAG, "Sending TRIM_MEMORY_UI_HIDDEN.")
        Log.d(LOG_TAG, "Sending TRIM_MEMORY_UI_HIDDEN.")
        globalWindowManager.trimMemory(ComponentCallbacks2.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 {
    companion object {
        private const val LOG_TAG = "ResourceTrimmer"
        private const val LOG_TAG = "ResourceTrimmer"
        private val DEBUG = Log.isLoggable(LOG_TAG, Log.DEBUG)
    }
    }
}
}
+2 −117
Original line number Original line Diff line number Diff line
package com.android.systemui.keyguard
package com.android.systemui.keyguard


import android.content.ComponentCallbacks2
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.platform.test.flag.junit.SetFlagsRule
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.SysuiTestCase
import com.android.systemui.flags.DisableSceneContainer
import com.android.systemui.flags.DisableSceneContainer
import com.android.systemui.flags.EnableSceneContainer
import com.android.systemui.flags.EnableSceneContainer
import com.android.systemui.flags.Flags
import com.android.systemui.flags.fakeFeatureFlagsClassic
import com.android.systemui.flags.fakeFeatureFlagsClassic
import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
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.domain.interactor.keyguardTransitionInteractor
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.kosmos.testDispatcher
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.domain.interactor.sceneInteractor
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.testKosmos
import com.android.systemui.testKosmos
import com.android.systemui.util.mockito.any
import com.android.systemui.utils.GlobalWindowManager
import com.android.systemui.utils.GlobalWindowManager
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runCurrent
@@ -62,52 +56,21 @@ class ResourceTrimmerTest : SysuiTestCase() {
    @Before
    @Before
    fun setUp() {
    fun setUp() {
        MockitoAnnotations.initMocks(this)
        MockitoAnnotations.initMocks(this)
        featureFlags.set(Flags.TRIM_FONT_CACHES_AT_UNLOCK, true)
        keyguardRepository.setDozeAmount(0f)
        keyguardRepository.setDozeAmount(0f)
        keyguardRepository.setKeyguardGoingAway(false)
        keyguardRepository.setKeyguardGoingAway(false)

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


    @Test
    @Test
    @EnableFlags(com.android.systemui.Flags.FLAG_TRIM_RESOURCES_WITH_BACKGROUND_TRIM_AT_LOCK)
    fun dozeAodDisabled_sleep_doesntTrimMemory() =
    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() =
        testScope.runTest {
        testScope.runTest {
            powerInteractor.setAsleepForTest()
            powerInteractor.setAsleepForTest()
            testScope.runCurrent()
            testScope.runCurrent()
@@ -115,8 +78,7 @@ class ResourceTrimmerTest : SysuiTestCase() {
        }
        }


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


    @Test
    @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() =
    fun dozeEnabled_sleepWithoutFullDozeAmount_doesntTrimMemory() =
        testScope.runTest {
        testScope.runTest {
            keyguardRepository.setDreaming(true)
            keyguardRepository.setDreaming(true)
@@ -150,34 +98,6 @@ class ResourceTrimmerTest : SysuiTestCase() {
        }
        }


    @Test
    @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() {
    fun aodEnabled_deviceWakesHalfWayThrough_doesNotTrimMemory() {
        testScope.runTest {
        testScope.runTest {
            keyguardRepository.setDreaming(true)
            keyguardRepository.setDreaming(true)
@@ -209,7 +129,6 @@ class ResourceTrimmerTest : SysuiTestCase() {
    }
    }


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


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


            verify(globalWindowManager, times(1))
            verify(globalWindowManager, times(1))
                .trimMemory(ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN)
                .trimMemory(ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN)
            verify(globalWindowManager, times(1)).trimCaches(HardwareRenderer.CACHE_TRIM_FONT)
            verifyNoMoreInteractions(globalWindowManager)
            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())
        }
}
}