1 package com.android.systemui.statusbar.phone
2 
3 import android.graphics.Rect
4 import android.testing.AndroidTestingRunner
5 import android.view.Display
6 import android.view.WindowInsets
7 import android.view.WindowInsetsController
8 import android.view.WindowInsetsController.*
9 import androidx.test.filters.SmallTest
10 import com.android.internal.statusbar.LetterboxDetails
11 import com.android.internal.view.AppearanceRegion
12 import com.android.systemui.SysuiTestCase
13 import com.android.systemui.dump.DumpManager
14 import com.android.systemui.statusbar.SysuiStatusBarStateController
15 import org.junit.Before
16 import org.junit.Test
17 import org.junit.runner.RunWith
18 import org.mockito.ArgumentMatchers.any
19 import org.mockito.ArgumentMatchers.anyBoolean
20 import org.mockito.ArgumentMatchers.anyInt
21 import org.mockito.ArgumentMatchers.eq
22 import org.mockito.Mock
23 import org.mockito.Mockito
24 import org.mockito.Mockito.reset
25 import org.mockito.Mockito.verify
26 import org.mockito.Mockito.verifyZeroInteractions
27 import org.mockito.MockitoAnnotations
28 import org.mockito.Mockito.`when` as whenever
29 
30 @SmallTest
31 @RunWith(AndroidTestingRunner::class)
32 class SystemBarAttributesListenerTest : SysuiTestCase() {
33 
34     @Mock private lateinit var dumpManager: DumpManager
35     @Mock private lateinit var lightBarController: LightBarController
36     @Mock private lateinit var statusBarStateController: SysuiStatusBarStateController
37     @Mock private lateinit var letterboxAppearanceCalculator: LetterboxAppearanceCalculator
38     @Mock private lateinit var centralSurfaces: CentralSurfaces
39 
40     private lateinit var sysBarAttrsListener: SystemBarAttributesListener
41 
42     @Before
43     fun setUp() {
44         MockitoAnnotations.initMocks(this)
45 
46         whenever(
47                 letterboxAppearanceCalculator.getLetterboxAppearance(
48                     anyInt(), anyObject(), anyObject()))
49             .thenReturn(TEST_LETTERBOX_APPEARANCE)
50 
51         sysBarAttrsListener =
52             SystemBarAttributesListener(
53                 centralSurfaces,
54                 letterboxAppearanceCalculator,
55                 statusBarStateController,
56                 lightBarController,
57                 dumpManager)
58     }
59 
60     @Test
61     fun onSysBarAttrsChanged_forwardsAppearanceToCentralSurfaces() {
62         val appearance = APPEARANCE_LIGHT_STATUS_BARS or APPEARANCE_LIGHT_NAVIGATION_BARS
63 
64         changeSysBarAttrs(appearance)
65 
66         verify(centralSurfaces).setAppearance(appearance)
67     }
68 
69     @Test
70     fun onSysBarAttrsChanged_forwardsLetterboxAppearanceToCentralSurfaces() {
71         changeSysBarAttrs(TEST_APPEARANCE, TEST_LETTERBOX_DETAILS)
72 
73         verify(centralSurfaces).setAppearance(TEST_LETTERBOX_APPEARANCE.appearance)
74     }
75 
76     @Test
77     fun onSysBarAttrsChanged_noLetterbox_forwardsOriginalAppearanceToCtrlSrfcs() {
78         changeSysBarAttrs(TEST_APPEARANCE, arrayOf<LetterboxDetails>())
79 
80         verify(centralSurfaces).setAppearance(TEST_APPEARANCE)
81     }
82 
83     @Test
84     fun onSysBarAttrsChanged_forwardsAppearanceToStatusBarStateController() {
85         changeSysBarAttrs(TEST_APPEARANCE)
86 
87         verify(statusBarStateController)
88             .setSystemBarAttributes(eq(TEST_APPEARANCE), anyInt(), anyInt(), any())
89     }
90 
91     @Test
92     fun onSysBarAttrsChanged_forwardsLetterboxAppearanceToStatusBarStateCtrl() {
93         changeSysBarAttrs(TEST_APPEARANCE, TEST_LETTERBOX_DETAILS)
94 
95         verify(statusBarStateController)
96             .setSystemBarAttributes(
97                 eq(TEST_LETTERBOX_APPEARANCE.appearance), anyInt(), anyInt(), any())
98     }
99 
100     @Test
101     fun onSysBarAttrsChanged_forwardsAppearanceToLightBarController() {
102         changeSysBarAttrs(TEST_APPEARANCE, TEST_APPEARANCE_REGIONS)
103 
104         verify(lightBarController)
105             .onStatusBarAppearanceChanged(
106                 eq(TEST_APPEARANCE_REGIONS), anyBoolean(), anyInt(), anyBoolean())
107     }
108 
109     @Test
110     fun onSysBarAttrsChanged_forwardsLetterboxAppearanceToLightBarController() {
111         changeSysBarAttrs(TEST_APPEARANCE, TEST_APPEARANCE_REGIONS, TEST_LETTERBOX_DETAILS)
112 
113         verify(lightBarController)
114             .onStatusBarAppearanceChanged(
115                 eq(TEST_LETTERBOX_APPEARANCE.appearanceRegions),
116                 anyBoolean(),
117                 anyInt(),
118                 anyBoolean())
119     }
120 
121     @Test
122     fun onStatusBarBoundsChanged_forwardsLetterboxAppearanceToStatusBarStateController() {
123         changeSysBarAttrs(TEST_APPEARANCE, TEST_APPEARANCE_REGIONS, TEST_LETTERBOX_DETAILS)
124         reset(centralSurfaces, lightBarController, statusBarStateController)
125 
126         sysBarAttrsListener.onStatusBarBoundsChanged()
127 
128         verify(statusBarStateController)
129             .setSystemBarAttributes(
130                 eq(TEST_LETTERBOX_APPEARANCE.appearance), anyInt(), anyInt(), any())
131     }
132 
133     @Test
134     fun onStatusBarBoundsChanged_forwardsLetterboxAppearanceToLightBarController() {
135         changeSysBarAttrs(TEST_APPEARANCE, TEST_APPEARANCE_REGIONS, TEST_LETTERBOX_DETAILS)
136         reset(centralSurfaces, lightBarController, statusBarStateController)
137 
138         sysBarAttrsListener.onStatusBarBoundsChanged()
139 
140         verify(lightBarController)
141             .onStatusBarAppearanceChanged(
142                 eq(TEST_LETTERBOX_APPEARANCE.appearanceRegions),
143                 anyBoolean(),
144                 anyInt(),
145                 anyBoolean())
146     }
147 
148     @Test
149     fun onStatusBarBoundsChanged_forwardsLetterboxAppearanceToCentralSurfaces() {
150         changeSysBarAttrs(TEST_APPEARANCE, TEST_APPEARANCE_REGIONS, TEST_LETTERBOX_DETAILS)
151         reset(centralSurfaces, lightBarController, statusBarStateController)
152 
153         sysBarAttrsListener.onStatusBarBoundsChanged()
154 
155         verify(centralSurfaces).setAppearance(TEST_LETTERBOX_APPEARANCE.appearance)
156     }
157 
158     @Test
159     fun onStatusBarBoundsChanged_previousCallEmptyLetterbox_doesNothing() {
160         changeSysBarAttrs(TEST_APPEARANCE, TEST_APPEARANCE_REGIONS, arrayOf())
161         reset(centralSurfaces, lightBarController, statusBarStateController)
162 
163         sysBarAttrsListener.onStatusBarBoundsChanged()
164 
165         verifyZeroInteractions(centralSurfaces, lightBarController, statusBarStateController)
166     }
167 
168     private fun changeSysBarAttrs(@Appearance appearance: Int) {
169         changeSysBarAttrs(appearance, arrayOf<LetterboxDetails>())
170     }
171 
172     private fun changeSysBarAttrs(
173         @Appearance appearance: Int,
174         letterboxDetails: Array<LetterboxDetails>
175     ) {
176         changeSysBarAttrs(appearance, arrayOf(), letterboxDetails)
177     }
178 
179     private fun changeSysBarAttrs(
180         @Appearance appearance: Int,
181         appearanceRegions: Array<AppearanceRegion>
182     ) {
183         changeSysBarAttrs(appearance, appearanceRegions, arrayOf())
184     }
185 
186     private fun changeSysBarAttrs(
187         @Appearance appearance: Int,
188         appearanceRegions: Array<AppearanceRegion>,
189         letterboxDetails: Array<LetterboxDetails>
190     ) {
191         sysBarAttrsListener.onSystemBarAttributesChanged(
192             Display.DEFAULT_DISPLAY,
193             appearance,
194             appearanceRegions,
195             /* navbarColorManagedByIme= */ false,
196             WindowInsetsController.BEHAVIOR_DEFAULT,
197             WindowInsets.Type.defaultVisible(),
198             "package name",
199             letterboxDetails)
200     }
201 
202     companion object {
203         private const val TEST_APPEARANCE =
204             APPEARANCE_LIGHT_STATUS_BARS or APPEARANCE_LIGHT_NAVIGATION_BARS
205         private val TEST_APPEARANCE_REGION = AppearanceRegion(TEST_APPEARANCE, Rect(0, 0, 150, 300))
206         private val TEST_APPEARANCE_REGIONS = arrayOf(TEST_APPEARANCE_REGION)
207         private val TEST_LETTERBOX_DETAILS =
208             arrayOf(
209                 LetterboxDetails(
210                     /* letterboxInnerBounds= */ Rect(0, 0, 0, 0),
211                     /* letterboxFullBounds= */ Rect(0, 0, 0, 0),
212                     /* appAppearance= */ 0))
213         private val TEST_LETTERBOX_APPEARANCE =
214             LetterboxAppearance(/* appearance= */ APPEARANCE_LOW_PROFILE_BARS, arrayOf())
215     }
216 }
217 
218 private fun <T> anyObject(): T {
219     return Mockito.anyObject<T>()
220 }
221