Merge "LS Wallpaper Sampling for LS Smartspace" into udc-dev

This commit is contained in:
Florence Yang
2023-05-16 18:52:23 +00:00
committed by Android (Google) Code Review
7 changed files with 348 additions and 118 deletions

View File

@@ -588,7 +588,7 @@ public final class WallpaperColors implements Parcelable {
int hints = 0;
double meanLuminance = totalLuminance / pixels.length;
if (meanLuminance > BRIGHT_IMAGE_MEAN_LUMINANCE && darkPixels < maxDarkPixels) {
if (meanLuminance > BRIGHT_IMAGE_MEAN_LUMINANCE && darkPixels <= maxDarkPixels) {
hints |= HINT_SUPPORTS_DARK_TEXT;
}
if (meanLuminance < DARK_THEME_MEAN_LUMINANCE) {

View File

@@ -1680,14 +1680,14 @@ public class WallpaperManager {
* @hide
*/
public void addOnColorsChangedListener(@NonNull LocalWallpaperColorConsumer callback,
List<RectF> regions) throws IllegalArgumentException {
List<RectF> regions, int which) throws IllegalArgumentException {
for (RectF region : regions) {
if (!LOCAL_COLOR_BOUNDS.contains(region)) {
throw new IllegalArgumentException("Regions must be within bounds "
+ LOCAL_COLOR_BOUNDS);
}
}
sGlobals.addOnColorsChangedListener(callback, regions, FLAG_SYSTEM,
sGlobals.addOnColorsChangedListener(callback, regions, which,
mContext.getUserId(), mContext.getDisplayId());
}

View File

@@ -21,9 +21,9 @@ import android.graphics.Color
import android.graphics.Point
import android.graphics.Rect
import android.graphics.RectF
import android.util.Log
import android.view.View
import androidx.annotation.VisibleForTesting
import com.android.systemui.shared.navigationbar.RegionSamplingHelper
import java.io.PrintWriter
import java.util.concurrent.Executor
@@ -31,20 +31,21 @@ import java.util.concurrent.Executor
open class RegionSampler
@JvmOverloads
constructor(
val sampledView: View?,
val sampledView: View,
mainExecutor: Executor?,
val bgExecutor: Executor?,
val regionSamplingEnabled: Boolean,
val isLockscreen: Boolean = false,
val wallpaperManager: WallpaperManager? = WallpaperManager.getInstance(sampledView.context),
val updateForegroundColor: UpdateColorCallback,
val wallpaperManager: WallpaperManager? = WallpaperManager.getInstance(sampledView?.context)
) : WallpaperManager.LocalWallpaperColorConsumer {
private var regionDarkness = RegionDarkness.DEFAULT
private var samplingBounds = Rect()
private val tmpScreenLocation = IntArray(2)
@VisibleForTesting var regionSampler: RegionSamplingHelper? = null
private var lightForegroundColor = Color.WHITE
private var darkForegroundColor = Color.BLACK
private val displaySize = Point()
@VisibleForTesting val displaySize = Point()
private var initialSampling: WallpaperColors? = null
/**
* Sets the colors to be used for Dark and Light Foreground.
@@ -57,6 +58,36 @@ constructor(
darkForegroundColor = darkColor
}
private val layoutChangedListener =
object : View.OnLayoutChangeListener {
override fun onLayoutChange(
view: View?,
left: Int,
top: Int,
right: Int,
bottom: Int,
oldLeft: Int,
oldTop: Int,
oldRight: Int,
oldBottom: Int
) {
// don't pass in negative bounds when region is in transition state
if (sampledView.locationOnScreen[0] < 0 || sampledView.locationOnScreen[1] < 0) {
return
}
val currentViewRect = Rect(left, top, right, bottom)
val oldViewRect = Rect(oldLeft, oldTop, oldRight, oldBottom)
if (currentViewRect != oldViewRect) {
stopRegionSampler()
startRegionSampler()
}
}
}
/**
* Determines which foreground color to use based on region darkness.
*
@@ -84,40 +115,57 @@ constructor(
/** Start region sampler */
fun startRegionSampler() {
if (!regionSamplingEnabled || sampledView == null) {
if (!regionSamplingEnabled) {
if (DEBUG) Log.d(TAG, "startRegionSampler() | RegionSampling flag not enabled")
return
}
val sampledRegion = calculateSampledRegion(sampledView)
val regions = ArrayList<RectF>()
val sampledRegionWithOffset = convertBounds(sampledRegion)
sampledView.addOnLayoutChangeListener(layoutChangedListener)
val screenLocationBounds = calculateScreenLocation(sampledView)
if (screenLocationBounds == null) {
if (DEBUG) Log.d(TAG, "startRegionSampler() | passed in null region")
return
}
if (screenLocationBounds.isEmpty) {
if (DEBUG) Log.d(TAG, "startRegionSampler() | passed in empty region")
return
}
val sampledRegionWithOffset = convertBounds(screenLocationBounds)
if (
sampledRegionWithOffset.left < 0.0 ||
sampledRegionWithOffset.right > 1.0 ||
sampledRegionWithOffset.top < 0.0 ||
sampledRegionWithOffset.bottom > 1.0
) {
android.util.Log.e(
"RegionSampler",
"view out of bounds: $sampledRegion | " +
"screen width: ${displaySize.x}, screen height: ${displaySize.y}",
Exception()
)
if (DEBUG)
Log.d(
TAG,
"startRegionSampler() | view out of bounds: $screenLocationBounds | " +
"screen width: ${displaySize.x}, screen height: ${displaySize.y}",
Exception()
)
return
}
val regions = ArrayList<RectF>()
regions.add(sampledRegionWithOffset)
wallpaperManager?.removeOnColorsChangedListener(this)
wallpaperManager?.addOnColorsChangedListener(this, regions)
wallpaperManager?.addOnColorsChangedListener(
this,
regions,
if (isLockscreen) WallpaperManager.FLAG_LOCK else WallpaperManager.FLAG_SYSTEM
)
// TODO(b/265969235): conditionally set FLAG_LOCK or FLAG_SYSTEM once HS smartspace
// implemented
bgExecutor?.execute(
Runnable {
val initialSampling =
wallpaperManager?.getWallpaperColors(WallpaperManager.FLAG_LOCK)
initialSampling =
wallpaperManager?.getWallpaperColors(
if (isLockscreen) WallpaperManager.FLAG_LOCK
else WallpaperManager.FLAG_SYSTEM
)
onColorsChanged(sampledRegionWithOffset, initialSampling)
}
)
@@ -126,6 +174,7 @@ constructor(
/** Stop region sampler */
fun stopRegionSampler() {
wallpaperManager?.removeOnColorsChangedListener(this)
sampledView.removeOnLayoutChangeListener(layoutChangedListener)
}
/** Dump region sampler */
@@ -138,22 +187,23 @@ constructor(
pw.println("passed-in sampledView: $sampledView")
pw.println("calculated samplingBounds: $samplingBounds")
pw.println(
"sampledView width: ${sampledView?.width}, sampledView height: ${sampledView?.height}"
"sampledView width: ${sampledView.width}, sampledView height: ${sampledView.height}"
)
pw.println("screen width: ${displaySize.x}, screen height: ${displaySize.y}")
pw.println(
"sampledRegionWithOffset: ${convertBounds(calculateSampledRegion(sampledView!!))}"
"sampledRegionWithOffset: ${convertBounds(
calculateScreenLocation(sampledView) ?: RectF())}"
)
// TODO(b/265969235): mock initialSampling based on if component is on HS or LS wallpaper
// HS Smartspace - wallpaperManager?.getWallpaperColors(WallpaperManager.FLAG_SYSTEM)
// LS Smartspace, clock - wallpaperManager?.getWallpaperColors(WallpaperManager.FLAG_LOCK)
pw.println(
"initialSampling for lockscreen: " +
"${wallpaperManager?.getWallpaperColors(WallpaperManager.FLAG_LOCK)}"
"initialSampling for ${if (isLockscreen) "lockscreen" else "homescreen" }" +
": $initialSampling"
)
}
fun calculateSampledRegion(sampledView: View): RectF {
fun calculateScreenLocation(sampledView: View): RectF? {
if (!sampledView.isLaidOut) return null
val screenLocation = tmpScreenLocation
/**
* The method getLocationOnScreen is used to obtain the view coordinates relative to its
@@ -181,7 +231,8 @@ constructor(
*/
fun convertBounds(originalBounds: RectF): RectF {
// TODO(b/265969235): GRAB # PAGES + CURRENT WALLPAPER PAGE # FROM LAUNCHER
// TODO(b/265969235): GRAB # PAGES + CURRENT WALLPAPER PAGE # FROM LAUNCHER (--> HS
// Smartspace always on 1st page)
// TODO(b/265968912): remove hard-coded value once LS wallpaper supported
val wallpaperPageNum = 0
val numScreens = 1
@@ -214,6 +265,11 @@ constructor(
)
updateForegroundColor()
}
companion object {
private const val TAG = "RegionSampler"
private const val DEBUG = false
}
}
typealias UpdateColorCallback = () -> Unit

View File

@@ -21,13 +21,11 @@ import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.content.res.Resources
import android.graphics.Rect
import android.text.format.DateFormat
import android.util.TypedValue
import android.view.View
import android.view.View.OnAttachStateChangeListener
import android.view.ViewTreeObserver
import android.widget.FrameLayout
import androidx.annotation.VisibleForTesting
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.repeatOnLifecycle
@@ -55,16 +53,16 @@ import com.android.systemui.statusbar.policy.BatteryController
import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback
import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.util.concurrency.DelayableExecutor
import java.util.Locale
import java.util.TimeZone
import java.util.concurrent.Executor
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.DisposableHandle
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.launch
import java.util.Locale
import java.util.TimeZone
import java.util.concurrent.Executor
import javax.inject.Inject
/**
* Controller for a Clock provided by the registry and used on the keyguard. Instantiated by
@@ -98,12 +96,7 @@ constructor(
value.initialize(resources, dozeAmount, 0f)
if (regionSamplingEnabled) {
clock?.run {
smallClock.view.addOnLayoutChangeListener(mLayoutChangedListener)
largeClock.view.addOnLayoutChangeListener(mLayoutChangedListener)
}
} else {
if (!regionSamplingEnabled) {
updateColors()
}
updateFontSizes()
@@ -140,44 +133,10 @@ constructor(
private var disposableHandle: DisposableHandle? = null
private val regionSamplingEnabled = featureFlags.isEnabled(REGION_SAMPLING)
private val mLayoutChangedListener =
object : View.OnLayoutChangeListener {
override fun onLayoutChange(
view: View?,
left: Int,
top: Int,
right: Int,
bottom: Int,
oldLeft: Int,
oldTop: Int,
oldRight: Int,
oldBottom: Int
) {
view?.removeOnLayoutChangeListener(this)
val parent = (view?.parent) as FrameLayout
// don't pass in negative bounds when clocks are in transition state
if (view.locationOnScreen[0] < 0 || view.locationOnScreen[1] < 0) {
return
}
val currentViewRect = Rect(left, top, right, bottom)
val oldViewRect = Rect(oldLeft, oldTop, oldRight, oldBottom)
if (
currentViewRect.width() != oldViewRect.width() ||
currentViewRect.height() != oldViewRect.height()
) {
updateRegionSampler(view)
}
}
}
private fun updateColors() {
val wallpaperManager = WallpaperManager.getInstance(context)
if (regionSamplingEnabled && !wallpaperManager.lockScreenWallpaperExists()) {
if (regionSamplingEnabled) {
regionSampler?.let { regionSampler ->
clock?.let { clock ->
if (regionSampler.sampledView == clock.smallClock.view) {
@@ -212,6 +171,7 @@ constructor(
mainExecutor,
bgExecutor,
regionSamplingEnabled,
isLockscreen = true,
::updateColors
)
?.apply { startRegionSampler() }
@@ -220,10 +180,11 @@ constructor(
}
protected open fun createRegionSampler(
sampledView: View?,
sampledView: View,
mainExecutor: Executor?,
bgExecutor: Executor?,
regionSamplingEnabled: Boolean,
isLockscreen: Boolean,
updateColors: () -> Unit
): RegionSampler? {
return RegionSampler(
@@ -231,8 +192,8 @@ constructor(
mainExecutor,
bgExecutor,
regionSamplingEnabled,
updateColors
)
isLockscreen,
) { updateColors() }
}
var regionSampler: RegionSampler? = null

View File

@@ -17,7 +17,6 @@
package com.android.systemui.statusbar.lockscreen
import android.app.PendingIntent
import android.app.WallpaperManager
import android.app.smartspace.SmartspaceConfig
import android.app.smartspace.SmartspaceManager
import android.app.smartspace.SmartspaceSession
@@ -56,7 +55,6 @@ import com.android.systemui.plugins.WeatherData
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.settings.UserTracker
import com.android.systemui.shared.regionsampling.RegionSampler
import com.android.systemui.shared.regionsampling.UpdateColorCallback
import com.android.systemui.smartspace.dagger.SmartspaceModule.Companion.DATE_SMARTSPACE_DATA_PLUGIN
import com.android.systemui.smartspace.dagger.SmartspaceModule.Companion.WEATHER_SMARTSPACE_DATA_PLUGIN
import com.android.systemui.statusbar.phone.KeyguardBypassController
@@ -120,7 +118,7 @@ constructor(
private val regionSamplingEnabled =
featureFlags.isEnabled(Flags.REGION_SAMPLING)
private var isContentUpdatedOnce = false
private var isRegionSamplersCreated = false
private var showNotifications = false
private var showSensitiveContentForCurrentUser = false
private var showSensitiveContentForManagedUser = false
@@ -128,7 +126,6 @@ constructor(
// TODO(b/202758428): refactor so that we can test color updates via region samping, similar to
// how we test color updates when theme changes (See testThemeChangeUpdatesTextColor).
private val updateFun: UpdateColorCallback = { updateTextColorFromRegionSampler() }
// TODO: Move logic into SmartspaceView
var stateChangeListener = object : View.OnAttachStateChangeListener {
@@ -144,6 +141,9 @@ constructor(
override fun onViewDetachedFromWindow(v: View) {
smartspaceViews.remove(v as SmartspaceView)
regionSamplers[v]?.stopRegionSampler()
regionSamplers.remove(v as SmartspaceView)
if (smartspaceViews.isEmpty()) {
disconnect()
}
@@ -170,7 +170,7 @@ constructor(
val filteredTargets = targets.filter(::filterSmartspaceTarget)
plugin?.onTargetsAvailable(filteredTargets)
if (!isContentUpdatedOnce) {
if (!isRegionSamplersCreated) {
for (v in smartspaceViews) {
if (regionSamplingEnabled) {
var regionSampler = RegionSampler(
@@ -178,15 +178,14 @@ constructor(
uiExecutor,
bgExecutor,
regionSamplingEnabled,
updateFun
)
isLockscreen = true,
) { updateTextColorFromRegionSampler() }
initializeTextColors(regionSampler)
regionSamplers[v] = regionSampler
regionSampler.startRegionSampler()
}
updateTextColorFromWallpaper()
}
isContentUpdatedOnce = true
isRegionSamplersCreated = true
}
}
@@ -504,18 +503,16 @@ constructor(
}
private fun updateTextColorFromRegionSampler() {
smartspaceViews.forEach {
val textColor = regionSamplers.get(it)?.currentForegroundColor()
regionSamplers.forEach { (view, region) ->
val textColor = region.currentForegroundColor()
if (textColor != null) {
it.setPrimaryTextColor(textColor)
view.setPrimaryTextColor(textColor)
}
}
}
private fun updateTextColorFromWallpaper() {
val wallpaperManager = WallpaperManager.getInstance(context)
if (!regionSamplingEnabled || wallpaperManager.lockScreenWallpaperExists() ||
regionSamplers.isEmpty()) {
if (!regionSamplingEnabled || regionSamplers.isEmpty()) {
val wallpaperTextColor =
Utils.getColorAttrDefaultColor(context, R.attr.wallpaperTextColor)
smartspaceViews.forEach { it.setPrimaryTextColor(wallpaperTextColor) }

View File

@@ -1,17 +1,30 @@
package com.android.systemui.shared.regionsampling
import android.app.WallpaperColors
import android.app.WallpaperManager
import android.graphics.Color
import android.graphics.RectF
import android.testing.AndroidTestingRunner
import android.view.View
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.capture
import com.google.common.truth.Truth.assertThat
import java.io.PrintWriter
import java.util.concurrent.Executor
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentCaptor
import org.mockito.ArgumentMatchers.eq
import org.mockito.Captor
import org.mockito.Mock
import org.mockito.Mockito.clearInvocations
import org.mockito.Mockito.never
import org.mockito.Mockito.verify
import org.mockito.Mockito.`when` as whenever
import org.mockito.junit.MockitoJUnit
@@ -26,25 +39,188 @@ class RegionSamplerTest : SysuiTestCase() {
@Mock private lateinit var bgExecutor: Executor
@Mock private lateinit var pw: PrintWriter
@Mock private lateinit var wallpaperManager: WallpaperManager
@Mock private lateinit var updateForegroundColor: UpdateColorCallback
private lateinit var mRegionSampler: RegionSampler
private var updateFun: UpdateColorCallback = {}
private lateinit var regionSampler: RegionSampler // lockscreen
private lateinit var homescreenRegionSampler: RegionSampler
@Captor
private lateinit var colorsChangedListener:
ArgumentCaptor<WallpaperManager.LocalWallpaperColorConsumer>
@Captor private lateinit var layoutChangedListener: ArgumentCaptor<View.OnLayoutChangeListener>
@Before
fun setUp() {
whenever(sampledView.isAttachedToWindow).thenReturn(true)
whenever(sampledView.width).thenReturn(100)
whenever(sampledView.height).thenReturn(100)
whenever(sampledView.isLaidOut).thenReturn(true)
whenever(sampledView.locationOnScreen).thenReturn(intArrayOf(0, 0))
mRegionSampler =
RegionSampler(sampledView, mainExecutor, bgExecutor, true, updateFun, wallpaperManager)
regionSampler =
RegionSampler(
sampledView,
mainExecutor,
bgExecutor,
regionSamplingEnabled = true,
isLockscreen = true,
wallpaperManager,
updateForegroundColor
)
regionSampler.displaySize.set(1080, 2050)
// TODO(b/265969235): test sampling on home screen via WallpaperManager.FLAG_SYSTEM
homescreenRegionSampler =
RegionSampler(
sampledView,
mainExecutor,
bgExecutor,
regionSamplingEnabled = true,
isLockscreen = false,
wallpaperManager,
updateForegroundColor
)
}
@Test
fun testStartRegionSampler() {
mRegionSampler.startRegionSampler()
fun testCalculatedBounds_inRange() {
// test calculations return region within [0,1]
sampledView.setLeftTopRightBottom(100, 100, 200, 200)
var fractionalBounds =
regionSampler.calculateScreenLocation(sampledView)?.let {
regionSampler.convertBounds(it)
}
assertTrue(fractionalBounds?.left!! >= 0.0f)
assertTrue(fractionalBounds.right <= 1.0f)
assertTrue(fractionalBounds.top >= 0.0f)
assertTrue(fractionalBounds.bottom <= 1.0f)
}
@Test
fun testEmptyView_returnsEarly() {
sampledView.setLeftTopRightBottom(0, 0, 0, 0)
whenever(sampledView.width).thenReturn(0)
whenever(sampledView.height).thenReturn(0)
regionSampler.startRegionSampler()
// returns early so should never call this function
verify(wallpaperManager, never())
.addOnColorsChangedListener(
any(WallpaperManager.LocalWallpaperColorConsumer::class.java),
any(),
any()
)
}
@Test
fun testLayoutChange_notifiesListener() {
regionSampler.startRegionSampler()
// don't count addOnColorsChangedListener() call made in startRegionSampler()
clearInvocations(wallpaperManager)
verify(sampledView).addOnLayoutChangeListener(capture(layoutChangedListener))
layoutChangedListener.value.onLayoutChange(
sampledView,
300,
300,
400,
400,
100,
100,
200,
200
)
verify(sampledView).removeOnLayoutChangeListener(layoutChangedListener.value)
verify(wallpaperManager)
.removeOnColorsChangedListener(
any(WallpaperManager.LocalWallpaperColorConsumer::class.java)
)
verify(wallpaperManager)
.addOnColorsChangedListener(
any(WallpaperManager.LocalWallpaperColorConsumer::class.java),
any(),
any()
)
}
@Test
fun testColorsChanged_triggersCallback() {
regionSampler.startRegionSampler()
verify(wallpaperManager)
.addOnColorsChangedListener(
capture(colorsChangedListener),
any(),
eq(WallpaperManager.FLAG_LOCK)
)
setWhiteWallpaper()
verify(updateForegroundColor).invoke()
}
@Test
fun testRegionDarkness() {
regionSampler.startRegionSampler()
verify(wallpaperManager)
.addOnColorsChangedListener(
capture(colorsChangedListener),
any(),
eq(WallpaperManager.FLAG_LOCK)
)
// should detect dark region
setBlackWallpaper()
assertThat(regionSampler.currentRegionDarkness()).isEqualTo(RegionDarkness.DARK)
// should detect light region
setWhiteWallpaper()
assertThat(regionSampler.currentRegionDarkness()).isEqualTo(RegionDarkness.LIGHT)
}
@Test
fun testForegroundColor() {
regionSampler.setForegroundColors(Color.WHITE, Color.BLACK)
regionSampler.startRegionSampler()
verify(wallpaperManager)
.addOnColorsChangedListener(
capture(colorsChangedListener),
any(),
eq(WallpaperManager.FLAG_LOCK)
)
// dark background, light text
setBlackWallpaper()
assertThat(regionSampler.currentForegroundColor()).isEqualTo(Color.WHITE)
// light background, dark text
setWhiteWallpaper()
assertThat(regionSampler.currentForegroundColor()).isEqualTo(Color.BLACK)
}
private fun setBlackWallpaper() {
val wallpaperColors =
WallpaperColors(Color.valueOf(Color.BLACK), Color.valueOf(Color.BLACK), null)
colorsChangedListener.value.onColorsChanged(
RectF(100.0f, 100.0f, 200.0f, 200.0f),
wallpaperColors
)
}
private fun setWhiteWallpaper() {
val wallpaperColors =
WallpaperColors(
Color.valueOf(Color.WHITE),
Color.valueOf(Color.WHITE),
null,
WallpaperColors.HINT_SUPPORTS_DARK_TEXT
)
colorsChangedListener.value.onColorsChanged(
RectF(100.0f, 100.0f, 200.0f, 200.0f),
wallpaperColors
)
}
@Test
fun testDump() {
mRegionSampler.dump(pw)
regionSampler.dump(pw)
homescreenRegionSampler.dump(pw)
}
}

View File

@@ -48,10 +48,10 @@ public class WallpaperColorsTest {
}
/**
* Check that white supports dark text and black doesn't
* Check that white surface supports dark text
*/
@Test
public void colorHintsTest() {
public void whiteSurfaceColorHintsTest() {
Bitmap image = Bitmap.createBitmap(30, 30, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(image);
@@ -59,28 +59,68 @@ public class WallpaperColorsTest {
int hints = WallpaperColors.fromBitmap(image).getColorHints();
boolean supportsDarkText = (hints & WallpaperColors.HINT_SUPPORTS_DARK_TEXT) != 0;
boolean supportsDarkTheme = (hints & WallpaperColors.HINT_SUPPORTS_DARK_THEME) != 0;
boolean fromBitmap = (hints & WallpaperColors.HINT_FROM_BITMAP) != 0;
Assert.assertTrue("White surface should support dark text.", supportsDarkText);
Assert.assertFalse("White surface shouldn't support dark theme.", supportsDarkTheme);
Assert.assertTrue("From bitmap should be true if object was created "
+ "using WallpaperColors#fromBitmap.", fromBitmap);
canvas.drawColor(Color.BLACK);
hints = WallpaperColors.fromBitmap(image).getColorHints();
supportsDarkText = (hints & WallpaperColors.HINT_SUPPORTS_DARK_TEXT) != 0;
supportsDarkTheme = (hints & WallpaperColors.HINT_SUPPORTS_DARK_THEME) != 0;
Assert.assertFalse("Black surface shouldn't support dark text.", supportsDarkText);
Assert.assertTrue("Black surface should support dark theme.", supportsDarkTheme);
Paint paint = new Paint();
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.BLACK);
canvas.drawColor(Color.WHITE);
canvas.drawRect(0, 0, 8, 8, paint);
supportsDarkText = (WallpaperColors.fromBitmap(image)
.getColorHints() & WallpaperColors.HINT_SUPPORTS_DARK_TEXT) != 0;
Assert.assertFalse("Light surface shouldn't support dark text "
+ "when it contains dark pixels.", supportsDarkText);
}
/**
* Check that x-small white region supports dark text when max number of dark pixels = 0
*/
@Test
public void xSmallWhiteSurfaceColorHintsTest() {
Bitmap xsmall_image = Bitmap.createBitmap(1, 5, Bitmap.Config.ARGB_8888);
Canvas xsmall_canvas = new Canvas(xsmall_image);
xsmall_canvas.drawColor(Color.WHITE);
int hints = WallpaperColors.fromBitmap(xsmall_image).getColorHints();
boolean supportsDarkText = (hints & WallpaperColors.HINT_SUPPORTS_DARK_TEXT) != 0;
boolean supportsDarkTheme = (hints & WallpaperColors.HINT_SUPPORTS_DARK_THEME) != 0;
Assert.assertTrue("X-small white surface should support dark text.",
supportsDarkText);
Assert.assertFalse("X-small white surface shouldn't support dark theme.",
supportsDarkTheme);
}
/**
* Check that black surface doesn't support dark text
*/
@Test
public void blackSurfaceColorHintsTest() {
Bitmap image = Bitmap.createBitmap(30, 30, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(image);
canvas.drawColor(Color.BLACK);
int hints = WallpaperColors.fromBitmap(image).getColorHints();
boolean supportsDarkText = (hints & WallpaperColors.HINT_SUPPORTS_DARK_TEXT) != 0;
boolean supportsDarkTheme = (hints & WallpaperColors.HINT_SUPPORTS_DARK_THEME) != 0;
Assert.assertFalse("Black surface shouldn't support dark text.", supportsDarkText);
Assert.assertTrue("Black surface should support dark theme.", supportsDarkTheme);
}
/**
* Check that bitmap hint properly indicates when object created via WallpaperColors#fromBitmap
* versus WallpaperColors() public constructor
*/
@Test
public void bitmapHintsTest() {
Bitmap image = Bitmap.createBitmap(30, 30, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(image);
canvas.drawColor(Color.WHITE);
int hints = WallpaperColors.fromBitmap(image).getColorHints();
boolean fromBitmap = (hints & WallpaperColors.HINT_FROM_BITMAP) != 0;
Assert.assertTrue("From bitmap should be true if object was created "
+ "using WallpaperColors#fromBitmap.", fromBitmap);
WallpaperColors colors = new WallpaperColors(Color.valueOf(Color.GREEN), null, null);
fromBitmap = (colors.getColorHints() & WallpaperColors.HINT_FROM_BITMAP) != 0;