1 package com.android.systemui.shared.regionsampling 2 3 import android.app.WallpaperColors 4 import android.app.WallpaperManager 5 import android.graphics.Color 6 import android.graphics.RectF 7 import android.view.View 8 import androidx.test.ext.junit.runners.AndroidJUnit4 9 import androidx.test.filters.SmallTest 10 import com.android.systemui.SysuiTestCase 11 import com.android.systemui.util.mockito.any 12 import com.android.systemui.util.mockito.capture 13 import com.google.common.truth.Truth.assertThat 14 import java.io.PrintWriter 15 import java.util.concurrent.Executor 16 import org.junit.Assert.assertTrue 17 import org.junit.Before 18 import org.junit.Rule 19 import org.junit.Test 20 import org.junit.runner.RunWith 21 import org.mockito.ArgumentCaptor 22 import org.mockito.ArgumentMatchers.eq 23 import org.mockito.Captor 24 import org.mockito.Mock 25 import org.mockito.Mockito.clearInvocations 26 import org.mockito.Mockito.never 27 import org.mockito.Mockito.verify 28 import org.mockito.Mockito.`when` as whenever 29 import org.mockito.junit.MockitoJUnit 30 31 @RunWith(AndroidJUnit4::class) 32 @SmallTest 33 class RegionSamplerTest : SysuiTestCase() { 34 35 @JvmField @Rule val mockito = MockitoJUnit.rule() 36 37 @Mock private lateinit var sampledView: View 38 @Mock private lateinit var mainExecutor: Executor 39 @Mock private lateinit var bgExecutor: Executor 40 @Mock private lateinit var pw: PrintWriter 41 @Mock private lateinit var wallpaperManager: WallpaperManager 42 @Mock private lateinit var updateForegroundColor: UpdateColorCallback 43 44 private lateinit var regionSampler: RegionSampler // lockscreen 45 private lateinit var homescreenRegionSampler: RegionSampler 46 47 @Captor 48 private lateinit var colorsChangedListener: 49 ArgumentCaptor<WallpaperManager.LocalWallpaperColorConsumer> 50 51 @Captor private lateinit var layoutChangedListener: ArgumentCaptor<View.OnLayoutChangeListener> 52 53 @Before setUpnull54 fun setUp() { 55 whenever(sampledView.isAttachedToWindow).thenReturn(true) 56 whenever(sampledView.width).thenReturn(100) 57 whenever(sampledView.height).thenReturn(100) 58 whenever(sampledView.isLaidOut).thenReturn(true) 59 whenever(sampledView.locationOnScreen).thenReturn(intArrayOf(0, 0)) 60 61 regionSampler = 62 RegionSampler( 63 sampledView, 64 mainExecutor, 65 bgExecutor, 66 regionSamplingEnabled = true, 67 isLockscreen = true, 68 wallpaperManager, 69 updateForegroundColor 70 ) 71 regionSampler.displaySize.set(1080, 2050) 72 73 // TODO(b/265969235): test sampling on home screen via WallpaperManager.FLAG_SYSTEM 74 homescreenRegionSampler = 75 RegionSampler( 76 sampledView, 77 mainExecutor, 78 bgExecutor, 79 regionSamplingEnabled = true, 80 isLockscreen = false, 81 wallpaperManager, 82 updateForegroundColor 83 ) 84 } 85 86 @Test testCalculatedBounds_inRangenull87 fun testCalculatedBounds_inRange() { 88 // test calculations return region within [0,1] 89 sampledView.setLeftTopRightBottom(100, 100, 200, 200) 90 var fractionalBounds = 91 regionSampler.calculateScreenLocation(sampledView)?.let { 92 regionSampler.convertBounds(it) 93 } 94 95 assertTrue(fractionalBounds?.left!! >= 0.0f) 96 assertTrue(fractionalBounds.right <= 1.0f) 97 assertTrue(fractionalBounds.top >= 0.0f) 98 assertTrue(fractionalBounds.bottom <= 1.0f) 99 } 100 101 @Test testEmptyView_returnsEarlynull102 fun testEmptyView_returnsEarly() { 103 sampledView.setLeftTopRightBottom(0, 0, 0, 0) 104 whenever(sampledView.width).thenReturn(0) 105 whenever(sampledView.height).thenReturn(0) 106 regionSampler.startRegionSampler() 107 // returns early so should never call this function 108 verify(wallpaperManager, never()) 109 .addOnColorsChangedListener( 110 any(WallpaperManager.LocalWallpaperColorConsumer::class.java), 111 any(), 112 any() 113 ) 114 } 115 116 @Test testLayoutChange_notifiesListenernull117 fun testLayoutChange_notifiesListener() { 118 regionSampler.startRegionSampler() 119 // don't count addOnColorsChangedListener() call made in startRegionSampler() 120 clearInvocations(wallpaperManager) 121 122 verify(sampledView).addOnLayoutChangeListener(capture(layoutChangedListener)) 123 layoutChangedListener.value.onLayoutChange( 124 sampledView, 125 300, 126 300, 127 400, 128 400, 129 100, 130 100, 131 200, 132 200 133 ) 134 verify(sampledView).removeOnLayoutChangeListener(layoutChangedListener.value) 135 verify(wallpaperManager) 136 .removeOnColorsChangedListener( 137 any(WallpaperManager.LocalWallpaperColorConsumer::class.java) 138 ) 139 verify(wallpaperManager) 140 .addOnColorsChangedListener( 141 any(WallpaperManager.LocalWallpaperColorConsumer::class.java), 142 any(), 143 any() 144 ) 145 } 146 147 @Test testColorsChanged_triggersCallbacknull148 fun testColorsChanged_triggersCallback() { 149 regionSampler.startRegionSampler() 150 verify(wallpaperManager) 151 .addOnColorsChangedListener( 152 capture(colorsChangedListener), 153 any(), 154 eq(WallpaperManager.FLAG_LOCK) 155 ) 156 setWhiteWallpaper() 157 verify(updateForegroundColor).invoke() 158 } 159 160 @Test testRegionDarknessnull161 fun testRegionDarkness() { 162 regionSampler.startRegionSampler() 163 verify(wallpaperManager) 164 .addOnColorsChangedListener( 165 capture(colorsChangedListener), 166 any(), 167 eq(WallpaperManager.FLAG_LOCK) 168 ) 169 170 // should detect dark region 171 setBlackWallpaper() 172 assertThat(regionSampler.currentRegionDarkness()).isEqualTo(RegionDarkness.DARK) 173 174 // should detect light region 175 setWhiteWallpaper() 176 assertThat(regionSampler.currentRegionDarkness()).isEqualTo(RegionDarkness.LIGHT) 177 } 178 179 @Test testForegroundColornull180 fun testForegroundColor() { 181 regionSampler.setForegroundColors(Color.WHITE, Color.BLACK) 182 regionSampler.startRegionSampler() 183 verify(wallpaperManager) 184 .addOnColorsChangedListener( 185 capture(colorsChangedListener), 186 any(), 187 eq(WallpaperManager.FLAG_LOCK) 188 ) 189 190 // dark background, light text 191 setBlackWallpaper() 192 assertThat(regionSampler.currentForegroundColor()).isEqualTo(Color.WHITE) 193 194 // light background, dark text 195 setWhiteWallpaper() 196 assertThat(regionSampler.currentForegroundColor()).isEqualTo(Color.BLACK) 197 } 198 setBlackWallpapernull199 private fun setBlackWallpaper() { 200 val wallpaperColors = 201 WallpaperColors(Color.valueOf(Color.BLACK), Color.valueOf(Color.BLACK), null) 202 colorsChangedListener.value.onColorsChanged( 203 RectF(100.0f, 100.0f, 200.0f, 200.0f), 204 wallpaperColors 205 ) 206 } setWhiteWallpapernull207 private fun setWhiteWallpaper() { 208 val wallpaperColors = 209 WallpaperColors( 210 Color.valueOf(Color.WHITE), 211 Color.valueOf(Color.WHITE), 212 null, 213 WallpaperColors.HINT_SUPPORTS_DARK_TEXT 214 ) 215 colorsChangedListener.value.onColorsChanged( 216 RectF(100.0f, 100.0f, 200.0f, 200.0f), 217 wallpaperColors 218 ) 219 } 220 221 @Test testDumpnull222 fun testDump() { 223 regionSampler.dump(pw) 224 homescreenRegionSampler.dump(pw) 225 } 226 } 227