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