1 package com.android.systemui.keyguard
2 
3 import android.content.ComponentCallbacks2
4 import android.platform.test.flag.junit.SetFlagsRule
5 import androidx.test.ext.junit.runners.AndroidJUnit4
6 import androidx.test.filters.SmallTest
7 import com.android.systemui.SysuiTestCase
8 import com.android.systemui.flags.DisableSceneContainer
9 import com.android.systemui.flags.EnableSceneContainer
10 import com.android.systemui.flags.fakeFeatureFlagsClassic
11 import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
12 import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
13 import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
14 import com.android.systemui.keyguard.shared.model.KeyguardState
15 import com.android.systemui.kosmos.testDispatcher
16 import com.android.systemui.kosmos.testScope
17 import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAsleepForTest
18 import com.android.systemui.power.domain.interactor.powerInteractor
19 import com.android.systemui.scene.data.repository.Idle
20 import com.android.systemui.scene.data.repository.setSceneTransition
21 import com.android.systemui.scene.domain.interactor.sceneInteractor
22 import com.android.systemui.scene.shared.model.Scenes
23 import com.android.systemui.testKosmos
24 import com.android.systemui.utils.GlobalWindowManager
25 import kotlinx.coroutines.ExperimentalCoroutinesApi
26 import kotlinx.coroutines.test.runCurrent
27 import kotlinx.coroutines.test.runTest
28 import org.junit.Before
29 import org.junit.Rule
30 import org.junit.Test
31 import org.junit.runner.RunWith
32 import org.mockito.Mock
33 import org.mockito.Mockito.times
34 import org.mockito.Mockito.verify
35 import org.mockito.Mockito.verifyNoMoreInteractions
36 import org.mockito.Mockito.verifyZeroInteractions
37 import org.mockito.MockitoAnnotations
38 
39 @OptIn(ExperimentalCoroutinesApi::class)
40 @RunWith(AndroidJUnit4::class)
41 @SmallTest
42 class ResourceTrimmerTest : SysuiTestCase() {
43     val kosmos = testKosmos()
44 
45     private val testScope = kosmos.testScope
46     private val keyguardRepository = kosmos.fakeKeyguardRepository
47     private val featureFlags = kosmos.fakeFeatureFlagsClassic
48     private val keyguardTransitionRepository = kosmos.fakeKeyguardTransitionRepository
49     private val powerInteractor = kosmos.powerInteractor
50 
51     @Mock private lateinit var globalWindowManager: GlobalWindowManager
52     private lateinit var resourceTrimmer: ResourceTrimmer
53 
54     @Rule @JvmField public val setFlagsRule = SetFlagsRule()
55 
56     @Before
setUpnull57     fun setUp() {
58         MockitoAnnotations.initMocks(this)
59         keyguardRepository.setDozeAmount(0f)
60         keyguardRepository.setKeyguardGoingAway(false)
61         resourceTrimmer =
62             ResourceTrimmer(
63                 keyguardTransitionInteractor = kosmos.keyguardTransitionInteractor,
64                 globalWindowManager = globalWindowManager,
65                 applicationScope = testScope.backgroundScope,
66                 bgDispatcher = kosmos.testDispatcher,
67                 sceneInteractor = kosmos.sceneInteractor,
68             )
69         resourceTrimmer.start()
70     }
71 
72     @Test
dozeAodDisabled_sleep_doesntTrimMemorynull73     fun dozeAodDisabled_sleep_doesntTrimMemory() =
74         testScope.runTest {
75             powerInteractor.setAsleepForTest()
76             testScope.runCurrent()
77             verifyZeroInteractions(globalWindowManager)
78         }
79 
80     @Test
dozeEnabled_sleepWithFullDozeAmount_doesntTrimMemorynull81     fun dozeEnabled_sleepWithFullDozeAmount_doesntTrimMemory() =
82         testScope.runTest {
83             keyguardRepository.setDreaming(true)
84             keyguardRepository.setDozeAmount(1f)
85             powerInteractor.setAsleepForTest()
86             testScope.runCurrent()
87             verifyZeroInteractions(globalWindowManager)
88         }
89 
90     @Test
dozeEnabled_sleepWithoutFullDozeAmount_doesntTrimMemorynull91     fun dozeEnabled_sleepWithoutFullDozeAmount_doesntTrimMemory() =
92         testScope.runTest {
93             keyguardRepository.setDreaming(true)
94             keyguardRepository.setDozeAmount(0f)
95             powerInteractor.setAsleepForTest()
96             testScope.runCurrent()
97             verifyZeroInteractions(globalWindowManager)
98         }
99 
100     @Test
aodEnabled_deviceWakesHalfWayThrough_doesNotTrimMemorynull101     fun aodEnabled_deviceWakesHalfWayThrough_doesNotTrimMemory() {
102         testScope.runTest {
103             keyguardRepository.setDreaming(true)
104             keyguardRepository.setDozeAmount(0f)
105             powerInteractor.setAsleepForTest()
106 
107             testScope.runCurrent()
108             verifyZeroInteractions(globalWindowManager)
109 
110             generateSequence(0f) { it + 0.1f }
111                 .takeWhile { it < 0.8f }
112                 .forEach {
113                     keyguardRepository.setDozeAmount(it)
114                     testScope.runCurrent()
115                 }
116             verifyZeroInteractions(globalWindowManager)
117 
118             generateSequence(0.8f) { it - 0.1f }
119                 .takeWhile { it >= 0f }
120                 .forEach {
121                     keyguardRepository.setDozeAmount(it)
122                     testScope.runCurrent()
123                 }
124 
125             keyguardRepository.setDozeAmount(0f)
126             testScope.runCurrent()
127             verifyZeroInteractions(globalWindowManager)
128         }
129     }
130 
131     @Test
132     @DisableSceneContainer
keyguardTransitionsToGone_trimsFontCachenull133     fun keyguardTransitionsToGone_trimsFontCache() =
134         testScope.runTest {
135             keyguardTransitionRepository.sendTransitionSteps(
136                 from = KeyguardState.LOCKSCREEN,
137                 to = KeyguardState.GONE,
138                 testScope
139             )
140             verify(globalWindowManager, times(1))
141                 .trimMemory(ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN)
142             verifyNoMoreInteractions(globalWindowManager)
143         }
144 
145     @Test
146     @EnableSceneContainer
keyguardTransitionsToGone_trimsFontCache_scene_containernull147     fun keyguardTransitionsToGone_trimsFontCache_scene_container() =
148         testScope.runTest {
149             kosmos.setSceneTransition(Idle(Scenes.Gone))
150 
151             verify(globalWindowManager, times(1))
152                 .trimMemory(ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN)
153             verifyNoMoreInteractions(globalWindowManager)
154         }
155 }
156