diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt index f71a46caef344..be0fcd3cd7234 100644 --- a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt +++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt @@ -676,6 +676,10 @@ object Flags { val TRIM_RESOURCES_WITH_BACKGROUND_TRIM_AT_LOCK = unreleasedFlag(2401, "trim_resources_with_background_trim_on_lock") + // TODO:(b/283203305): Tracking bug + @JvmField + val TRIM_FONT_CACHES_AT_UNLOCK = releasedFlag(2402, "trim_font_caches_on_unlock") + // 2700 - unfold transitions // TODO(b/265764985): Tracking Bug @Keep diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ResourceTrimmer.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ResourceTrimmer.kt index 8386a05b6647f..d8affa4d6c21a 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ResourceTrimmer.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ResourceTrimmer.kt @@ -18,6 +18,7 @@ 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 @@ -27,12 +28,13 @@ 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.TransitionState import com.android.systemui.keyguard.shared.model.WakefulnessState import com.android.systemui.utils.GlobalWindowManager import javax.inject.Inject import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.map @@ -50,6 +52,7 @@ class ResourceTrimmer @Inject constructor( private val keyguardInteractor: KeyguardInteractor, + private val keyguardTransitionInteractor: KeyguardTransitionInteractor, private val globalWindowManager: GlobalWindowManager, @Application private val applicationScope: CoroutineScope, @Background private val bgDispatcher: CoroutineDispatcher, @@ -58,7 +61,10 @@ constructor( override fun start() { Log.d(LOG_TAG, "Resource trimmer registered.") - if (!featureFlags.isEnabled(Flags.TRIM_RESOURCES_WITH_BACKGROUND_TRIM_AT_LOCK)) { + if ( + !(featureFlags.isEnabled(Flags.TRIM_RESOURCES_WITH_BACKGROUND_TRIM_AT_LOCK) || + featureFlags.isEnabled(Flags.TRIM_FONT_CACHES_AT_UNLOCK)) + ) { return } @@ -78,6 +84,30 @@ constructor( .distinctUntilChanged() .collect { onWakefulnessUpdated(it.first, it.second, it.third) } } + + applicationScope.launch(bgDispatcher) { + // We drop 1 to avoid triggering on initial collect(). + keyguardTransitionInteractor.anyStateToGoneTransition.collect { transition -> + if (transition.transitionState == TransitionState.FINISHED) { + onKeyguardGone() + } + } + } + } + + @WorkerThread + private fun onKeyguardGone() { + if (!featureFlags.isEnabled(Flags.TRIM_FONT_CACHES_AT_UNLOCK)) { + return + } + + if (DEBUG) { + Log.d(LOG_TAG, "Trimming font caches since keyguard went away.") + } + // We want to clear temporary caches we've created while rendering and animating + // lockscreen elements, especially clocks. + globalWindowManager.trimMemory(ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) + globalWindowManager.trimCaches(HardwareRenderer.CACHE_TRIM_FONT) } @WorkerThread diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java index df68e7eb037b8..0414a14205d7b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java @@ -23,7 +23,6 @@ import static com.android.systemui.plugins.ActivityStarter.OnDismissAction; import static com.android.systemui.statusbar.phone.BiometricUnlockController.MODE_WAKE_AND_UNLOCK; import static com.android.systemui.statusbar.phone.BiometricUnlockController.MODE_WAKE_AND_UNLOCK_PULSING; -import android.content.ComponentCallbacks2; import android.content.Context; import android.content.res.ColorStateList; import android.hardware.biometrics.BiometricSourceType; @@ -36,7 +35,6 @@ import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.view.ViewRootImpl; -import android.view.WindowManagerGlobal; import android.window.BackEvent; import android.window.OnBackAnimationCallback; import android.window.OnBackInvokedDispatcher; @@ -985,8 +983,6 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb mShadeViewController.resetViewGroupFade(); mCentralSurfaces.finishKeyguardFadingAway(); mBiometricUnlockController.finishKeyguardFadingAway(); - WindowManagerGlobal.getInstance().trimMemory( - ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); } private void wakeAndUnlockDejank() { diff --git a/packages/SystemUI/src/com/android/systemui/utils/GlobalWindowManager.kt b/packages/SystemUI/src/com/android/systemui/utils/GlobalWindowManager.kt index 038fddc1f7a9c..4111850b53ed8 100644 --- a/packages/SystemUI/src/com/android/systemui/utils/GlobalWindowManager.kt +++ b/packages/SystemUI/src/com/android/systemui/utils/GlobalWindowManager.kt @@ -1,5 +1,6 @@ package com.android.systemui.utils +import android.graphics.HardwareRenderer.CacheTrimLevel import android.view.WindowManagerGlobal import javax.inject.Inject @@ -13,4 +14,9 @@ class GlobalWindowManager @Inject constructor() { fun trimMemory(level: Int) { WindowManagerGlobal.getInstance().trimMemory(level) } + + /** Sends a trim caches command to [WindowManagerGlobal]. */ + fun trimCaches(@CacheTrimLevel level: Int) { + WindowManagerGlobal.getInstance().trimCaches(level) + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ResourceTrimmerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ResourceTrimmerTest.kt index 367d206814cbc..548d26f2aaed3 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ResourceTrimmerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ResourceTrimmerTest.kt @@ -1,6 +1,7 @@ package com.android.systemui.keyguard import android.content.ComponentCallbacks2 +import android.graphics.HardwareRenderer import android.testing.AndroidTestingRunner import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase @@ -9,7 +10,11 @@ import com.android.systemui.flags.Flags import com.android.systemui.keyguard.data.repository.FakeCommandQueue import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository +import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor +import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor +import com.android.systemui.keyguard.shared.model.KeyguardState +import com.android.systemui.keyguard.shared.model.TransitionStep import com.android.systemui.keyguard.shared.model.WakeSleepReason import com.android.systemui.keyguard.shared.model.WakefulnessModel import com.android.systemui.keyguard.shared.model.WakefulnessState @@ -25,6 +30,7 @@ import org.junit.runner.RunWith import org.mockito.Mock import org.mockito.Mockito.times import org.mockito.Mockito.verify +import org.mockito.Mockito.verifyNoMoreInteractions import org.mockito.Mockito.verifyZeroInteractions import org.mockito.MockitoAnnotations @@ -37,6 +43,7 @@ class ResourceTrimmerTest : SysuiTestCase() { private val testScope = TestScope(testDispatcher) private val keyguardRepository = FakeKeyguardRepository() private val featureFlags = FakeFeatureFlags() + private val keyguardTransitionRepository = FakeKeyguardTransitionRepository() @Mock private lateinit var globalWindowManager: GlobalWindowManager private lateinit var resourceTrimmer: ResourceTrimmer @@ -45,13 +52,15 @@ class ResourceTrimmerTest : SysuiTestCase() { fun setUp() { MockitoAnnotations.initMocks(this) featureFlags.set(Flags.TRIM_RESOURCES_WITH_BACKGROUND_TRIM_AT_LOCK, true) + featureFlags.set(Flags.TRIM_FONT_CACHES_AT_UNLOCK, true) featureFlags.set(Flags.FACE_AUTH_REFACTOR, false) keyguardRepository.setWakefulnessModel( WakefulnessModel(WakefulnessState.AWAKE, WakeSleepReason.OTHER, WakeSleepReason.OTHER) ) keyguardRepository.setDozeAmount(0f) + keyguardRepository.setKeyguardGoingAway(false) - val interactor = + val keyguardInteractor = KeyguardInteractor( keyguardRepository, FakeCommandQueue(), @@ -60,7 +69,8 @@ class ResourceTrimmerTest : SysuiTestCase() { ) resourceTrimmer = ResourceTrimmer( - interactor, + keyguardInteractor, + KeyguardTransitionInteractor(keyguardTransitionRepository), globalWindowManager, testScope.backgroundScope, testDispatcher, @@ -191,4 +201,26 @@ class ResourceTrimmerTest : SysuiTestCase() { verifyZeroInteractions(globalWindowManager) } } + + @Test + fun keyguardTransitionsToGone_trimsFontCache() = + testScope.runTest { + keyguardTransitionRepository.sendTransitionStep( + TransitionStep(KeyguardState.LOCKSCREEN, KeyguardState.GONE) + ) + verify(globalWindowManager, times(1)) + .trimMemory(ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) + verify(globalWindowManager, times(1)).trimCaches(HardwareRenderer.CACHE_TRIM_FONT) + verifyNoMoreInteractions(globalWindowManager) + } + + @Test + fun keyguardTransitionsToGone_flagDisabled_doesNotTrimFontCache() = + testScope.runTest { + featureFlags.set(Flags.TRIM_FONT_CACHES_AT_UNLOCK, false) + keyguardTransitionRepository.sendTransitionStep( + TransitionStep(KeyguardState.LOCKSCREEN, KeyguardState.GONE) + ) + verifyNoMoreInteractions(globalWindowManager) + } }