1 /* <lambda>null2 * Copyright (C) 2023 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.systemui.keyguard 18 19 import android.annotation.WorkerThread 20 import android.content.ComponentCallbacks2 21 import android.util.Log 22 import com.android.app.tracing.coroutines.launchTraced as launch 23 import com.android.systemui.CoreStartable 24 import com.android.systemui.dagger.SysUISingleton 25 import com.android.systemui.dagger.qualifiers.Application 26 import com.android.systemui.dagger.qualifiers.Background 27 import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor 28 import com.android.systemui.keyguard.shared.model.KeyguardState.GONE 29 import com.android.systemui.scene.shared.model.Scenes 30 import com.android.systemui.utils.GlobalWindowManager 31 import javax.inject.Inject 32 import kotlinx.coroutines.CoroutineDispatcher 33 import kotlinx.coroutines.CoroutineScope 34 import kotlinx.coroutines.flow.filter 35 36 /** 37 * Releases cached resources on allocated by keyguard. 38 * 39 * We release most resources when device goes idle since that's the least likely time it'll cause 40 * jank during use. Idle in this case means after lockscreen -> AoD transition completes or when the 41 * device screen is turned off, depending on settings. 42 */ 43 @SysUISingleton 44 class ResourceTrimmer 45 @Inject 46 constructor( 47 private val keyguardTransitionInteractor: KeyguardTransitionInteractor, 48 private val globalWindowManager: GlobalWindowManager, 49 @Application private val applicationScope: CoroutineScope, 50 @Background private val bgDispatcher: CoroutineDispatcher, 51 ) : CoreStartable { 52 53 override fun start() { 54 Log.d(LOG_TAG, "Resource trimmer registered.") 55 applicationScope.launch(context = bgDispatcher) { 56 keyguardTransitionInteractor 57 .isFinishedIn(content = Scenes.Gone, stateWithoutSceneContainer = GONE) 58 .filter { isOnGone -> isOnGone } 59 .collect { onKeyguardGone() } 60 } 61 } 62 63 @WorkerThread 64 private fun onKeyguardGone() { 65 // We want to clear temporary caches we've created while rendering and animating 66 // lockscreen elements, especially clocks. 67 Log.d(LOG_TAG, "Sending TRIM_MEMORY_UI_HIDDEN.") 68 globalWindowManager.trimMemory(ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) 69 } 70 71 companion object { 72 private const val LOG_TAG = "ResourceTrimmer" 73 } 74 } 75