diff --git a/core/java/android/app/DisabledWallpaperManager.java b/core/java/android/app/DisabledWallpaperManager.java index 1f323c3780936..ae3a9e6668ab0 100644 --- a/core/java/android/app/DisabledWallpaperManager.java +++ b/core/java/android/app/DisabledWallpaperManager.java @@ -74,6 +74,11 @@ final class DisabledWallpaperManager extends WallpaperManager { return false; } + private static int unsupportedInt() { + if (DEBUG) Log.w(TAG, "unsupported method called; returning -1", new Exception()); + return -1; + } + @Override public Drawable getDrawable() { return unsupported(); @@ -189,12 +194,12 @@ final class DisabledWallpaperManager extends WallpaperManager { @Override public int getWallpaperId(int which) { - return unsupported(); + return unsupportedInt(); } @Override public int getWallpaperIdForUser(int which, int userId) { - return unsupported(); + return unsupportedInt(); } @Override @@ -209,7 +214,8 @@ final class DisabledWallpaperManager extends WallpaperManager { @Override public int setResource(int resid, int which) throws IOException { - return unsupported(); + unsupported(); + return 0; } @Override @@ -220,19 +226,22 @@ final class DisabledWallpaperManager extends WallpaperManager { @Override public int setBitmap(Bitmap fullImage, Rect visibleCropHint, boolean allowBackup) throws IOException { - return unsupported(); + unsupported(); + return 0; } @Override public int setBitmap(Bitmap fullImage, Rect visibleCropHint, boolean allowBackup, int which) throws IOException { - return unsupported(); + unsupported(); + return 0; } @Override public int setBitmap(Bitmap fullImage, Rect visibleCropHint, boolean allowBackup, int which, int userId) throws IOException { - return unsupported(); + unsupported(); + return 0; } @Override @@ -243,13 +252,15 @@ final class DisabledWallpaperManager extends WallpaperManager { @Override public int setStream(InputStream bitmapData, Rect visibleCropHint, boolean allowBackup) throws IOException { - return unsupported(); + unsupported(); + return 0; } @Override public int setStream(InputStream bitmapData, Rect visibleCropHint, boolean allowBackup, int which) throws IOException { - return unsupported(); + unsupported(); + return 0; } @Override @@ -259,12 +270,12 @@ final class DisabledWallpaperManager extends WallpaperManager { @Override public int getDesiredMinimumWidth() { - return unsupported(); + return unsupportedInt(); } @Override public int getDesiredMinimumHeight() { - return unsupported(); + return unsupportedInt(); } @Override diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp index d051290cb4b48..6671308ef66ad 100644 --- a/packages/SystemUI/Android.bp +++ b/packages/SystemUI/Android.bp @@ -92,6 +92,7 @@ android_library { "iconloader_base", "SystemUI-tags", "SystemUI-proto", + "monet", "dagger2", "jsr330", "lottie", @@ -179,6 +180,7 @@ android_library { "mockito-target-extended-minus-junit4", "testables", "truth-prebuilt", + "monet", "dagger2", "jsr330", "WindowManager-Shell", diff --git a/packages/SystemUI/monet/Android.bp b/packages/SystemUI/monet/Android.bp new file mode 100644 index 0000000000000..507ea25083e12 --- /dev/null +++ b/packages/SystemUI/monet/Android.bp @@ -0,0 +1,31 @@ +// +// Copyright (C) 2021 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +package { + default_applicable_licenses: ["Android-Apache-2.0"], +} + +java_library { + name: "monet", + platform_apis: true, + static_libs: [ + "androidx.annotation_annotation", + "androidx.core_core", + ], + srcs: [ + "src/**/*.java", + "src/**/*.kt", + ], +} diff --git a/packages/SystemUI/monet/AndroidManifest.xml b/packages/SystemUI/monet/AndroidManifest.xml new file mode 100644 index 0000000000000..1fab52877847e --- /dev/null +++ b/packages/SystemUI/monet/AndroidManifest.xml @@ -0,0 +1,20 @@ + + + + + diff --git a/packages/SystemUI/monet/src/com/android/systemui/monet/ColorScheme.kt b/packages/SystemUI/monet/src/com/android/systemui/monet/ColorScheme.kt new file mode 100644 index 0000000000000..b8039e13b2a5d --- /dev/null +++ b/packages/SystemUI/monet/src/com/android/systemui/monet/ColorScheme.kt @@ -0,0 +1,246 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.monet + +import android.annotation.ColorInt +import android.app.WallpaperColors +import android.graphics.Color +import com.android.internal.graphics.ColorUtils +import com.android.internal.graphics.cam.Cam +import com.android.internal.graphics.cam.CamUtils.lstarFromInt +import kotlin.math.absoluteValue +import kotlin.math.roundToInt + +const val TAG = "ColorScheme" + +const val ACCENT1_CHROMA = 48.0f +const val ACCENT2_CHROMA = 16.0f +const val ACCENT3_CHROMA = 32.0f +const val ACCENT3_HUE_SHIFT = 60.0f + +const val NEUTRAL1_CHROMA = 4.0f +const val NEUTRAL2_CHROMA = 8.0f + +const val GOOGLE_BLUE = 0xFF1b6ef3.toInt() + +const val MIN_CHROMA = 15 +const val MIN_LSTAR = 10 + +public class ColorScheme(@ColorInt seed: Int, val darkTheme: Boolean) { + + val accent1: List + val accent2: List + val accent3: List + val neutral1: List + val neutral2: List + + constructor(wallpaperColors: WallpaperColors, darkTheme: Boolean): + this(getSeedColor(wallpaperColors), darkTheme) + + val allAccentColors: List + get() { + val allColors = mutableListOf() + allColors.addAll(accent1) + allColors.addAll(accent2) + allColors.addAll(accent3) + return allColors + } + + val allNeutralColors: List + get() { + val allColors = mutableListOf() + allColors.addAll(neutral1) + allColors.addAll(neutral2) + return allColors + } + + val backgroundColor + get() = ColorUtils.setAlphaComponent(if (darkTheme) neutral1[8] else neutral1[0], 0xFF) + + val accentColor + get() = ColorUtils.setAlphaComponent(if (darkTheme) accent1[2] else accent1[6], 0xFF) + + init { + val seedArgb = if (seed == Color.TRANSPARENT) GOOGLE_BLUE else seed + val camSeed = Cam.fromInt(seedArgb) + val hue = camSeed.hue + val chroma = camSeed.chroma.coerceAtLeast(ACCENT1_CHROMA) + accent1 = Shades.of(hue, chroma).toList() + accent2 = Shades.of(hue, ACCENT2_CHROMA).toList() + accent3 = Shades.of(hue + ACCENT3_HUE_SHIFT, ACCENT3_CHROMA).toList() + neutral1 = Shades.of(hue, NEUTRAL1_CHROMA).toList() + neutral2 = Shades.of(hue, NEUTRAL2_CHROMA).toList() + } + + override fun toString(): String { + return "ColorScheme {\n" + + " neutral1: ${humanReadable(neutral1)}\n" + + " neutral2: ${humanReadable(neutral2)}\n" + + " accent1: ${humanReadable(accent1)}\n" + + " accent2: ${humanReadable(accent2)}\n" + + " accent3: ${humanReadable(accent3)}\n" + + "}" + } + + companion object { + /** + * Identifies a color to create a color scheme from. + * + * @param wallpaperColors Colors extracted from an image via quantization. + * @return ARGB int representing the color + */ + @JvmStatic + @ColorInt + fun getSeedColor(wallpaperColors: WallpaperColors): Int { + return getSeedColors(wallpaperColors).first() + } + + /** + * Filters and ranks colors from WallpaperColors. + * + * @param wallpaperColors Colors extracted from an image via quantization. + * @return List of ARGB ints, ordered from highest scoring to lowest. + */ + @JvmStatic + fun getSeedColors(wallpaperColors: WallpaperColors): List { + val totalPopulation = wallpaperColors.allColors.values.reduce { a, b -> a + b } + .toDouble() + val totalPopulationMeaningless = (totalPopulation == 0.0) + if (totalPopulationMeaningless) { + // WallpaperColors with a population of 0 indicate the colors didn't come from + // quantization. Instead of scoring, trust the ordering of the provided primary + // secondary/tertiary colors. + // + // In this case, the colors are usually from a Live Wallpaper. + val distinctColors = wallpaperColors.mainColors.map { + it.toArgb() + }.distinct().filter { + val cam = Cam.fromInt(it) + val lstar = lstarFromInt(it) + cam.chroma >= MIN_CHROMA && lstar >= MIN_LSTAR + }.toList() + + if (distinctColors.isEmpty()) { + return listOf(GOOGLE_BLUE) + } + return distinctColors + } + + val intToProportion = wallpaperColors.allColors.mapValues { + it.value.toDouble() / totalPopulation + } + val intToCam = wallpaperColors.allColors.mapValues { Cam.fromInt(it.key) } + + // Get an array with 360 slots. A slot contains the percentage of colors with that hue. + val hueProportions = huePopulations(intToCam, intToProportion) + // Map each color to the percentage of the image with its hue. + val intToHueProportion = wallpaperColors.allColors.mapValues { + val cam = intToCam[it.key]!! + val hue = cam.hue.roundToInt() + var proportion = 0.0 + for (i in hue - 15..hue + 15) { + proportion += hueProportions[wrapDegrees(i)] + } + proportion + } + // Remove any inappropriate seed colors. For example, low chroma colors look grayscale + // raising their chroma will turn them to a much louder color that may not have been + // in the image. + val filteredIntToCam = intToCam.filter { + val cam = it.value + val lstar = lstarFromInt(it.key) + val proportion = intToHueProportion[it.key]!! + cam.chroma >= MIN_CHROMA && lstar >= MIN_LSTAR && + (totalPopulationMeaningless || proportion > 0.01) + } + // Sort the colors by score, from high to low. + val seeds = mutableListOf() + val intToScoreIntermediate = filteredIntToCam.mapValues { + score(it.value, intToHueProportion[it.key]!!) + } + val intToScore = intToScoreIntermediate.entries.toMutableList() + intToScore.sortByDescending { it.value } + + // Go through the colors, from high score to low score. If there isn't already a seed + // color with a hue close to color being examined, add the color being examined to the + // seed colors. + for (entry in intToScore) { + val int = entry.key + val existingSeedNearby = seeds.find { + val hueA = intToCam[int]!!.hue + val hueB = intToCam[it]!!.hue + hueDiff(hueA, hueB) < 15 } != null + if (existingSeedNearby) { + continue + } + seeds.add(int) + } + + if (seeds.isEmpty()) { + // Use gBlue 500 if there are 0 colors + seeds.add(GOOGLE_BLUE) + } + + return seeds + } + + private fun wrapDegrees(degrees: Int): Int { + return when { + degrees < 0 -> { + (degrees % 360) + 360 + } + degrees >= 360 -> { + degrees % 360 + } + else -> { + degrees + } + } + } + + private fun hueDiff(a: Float, b: Float): Float { + return 180f - ((a - b).absoluteValue - 180f).absoluteValue + } + + private fun humanReadable(colors: List): String { + return colors.joinToString { "#" + Integer.toHexString(it) } + } + + private fun score(cam: Cam, proportion: Double): Double { + val proportionScore = 0.7 * 100.0 * proportion + val chromaScore = if (cam.chroma < ACCENT1_CHROMA) 0.1 * (cam.chroma - ACCENT1_CHROMA) + else 0.3 * (cam.chroma - ACCENT1_CHROMA) + return chromaScore + proportionScore + } + + private fun huePopulations( + camByColor: Map, + populationByColor: Map + ): List { + val huePopulation = List(size = 360, init = { 0.0 }).toMutableList() + + for (entry in populationByColor.entries) { + val population = populationByColor[entry.key]!! + val cam = camByColor[entry.key]!! + val hue = cam.hue.roundToInt() % 360 + huePopulation[hue] = huePopulation[hue] + population + } + + return huePopulation + } + } +} \ No newline at end of file diff --git a/packages/SystemUI/monet/src/com/android/systemui/monet/Shades.java b/packages/SystemUI/monet/src/com/android/systemui/monet/Shades.java new file mode 100644 index 0000000000000..498b7dd8658cf --- /dev/null +++ b/packages/SystemUI/monet/src/com/android/systemui/monet/Shades.java @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.systemui.monet; + + +import androidx.annotation.ColorInt; + +import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.graphics.ColorUtils; + + +/** + * Generate sets of colors that are shades of the same color + */ +@VisibleForTesting +public class Shades { + /** + * Combining the ability to convert between relative luminance and perceptual luminance with + * contrast leads to a design system that can be based on a linear value to determine contrast, + * rather than a ratio. + * + * This codebase implements a design system that has that property, and as a result, we can + * guarantee that any shades 5 steps from each other have a contrast ratio of at least 4.5. + * 4.5 is the requirement for smaller text contrast in WCAG 2.1 and earlier. + * + * However, lstar 50 does _not_ have a contrast ratio >= 4.5 with lstar 100. + * lstar 49.6 is the smallest lstar that will lead to a contrast ratio >= 4.5 with lstar 100, + * and it also contrasts >= 4.5 with lstar 100. + */ + public static final float MIDDLE_LSTAR = 49.6f; + + /** + * Generate shades of a color. Ordered in lightness _descending_. + *

+ * The first shade will be at 95% lightness, the next at 90, 80, etc. through 0. + * + * @param hue hue in CAM16 color space + * @param chroma chroma in CAM16 color space + * @return shades of a color, as argb integers. Ordered by lightness descending. + */ + public static @ColorInt int[] of(float hue, float chroma) { + int[] shades = new int[12]; + shades[0] = ColorUtils.CAMToColor(hue, chroma, 99); + shades[1] = ColorUtils.CAMToColor(hue, chroma, 95); + for (int i = 2; i < 12; i++) { + float lStar = (i == 6) ? MIDDLE_LSTAR : 100 - 10 * (i - 1); + shades[i] = ColorUtils.CAMToColor(hue, chroma, lStar); + } + return shades; + } +} diff --git a/packages/SystemUI/res/values/flags.xml b/packages/SystemUI/res/values/flags.xml index c2b87a55f3667..d442cc51cfd76 100644 --- a/packages/SystemUI/res/values/flags.xml +++ b/packages/SystemUI/res/values/flags.xml @@ -22,7 +22,7 @@ false true - false + true true diff --git a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java index 0130cb2f8cd35..a288d999550a4 100644 --- a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java +++ b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java @@ -37,6 +37,7 @@ import android.content.IntentFilter; import android.content.om.FabricatedOverlay; import android.content.om.OverlayIdentifier; import android.content.pm.UserInfo; +import android.content.res.Configuration; import android.database.ContentObserver; import android.graphics.Color; import android.net.Uri; @@ -47,9 +48,11 @@ import android.provider.Settings; import android.text.TextUtils; import android.util.ArrayMap; import android.util.Log; +import android.util.TypedValue; import androidx.annotation.NonNull; +import com.android.internal.graphics.ColorUtils; import com.android.systemui.Dumpable; import com.android.systemui.SystemUI; import com.android.systemui.broadcast.BroadcastDispatcher; @@ -59,6 +62,7 @@ import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.dump.DumpManager; import com.android.systemui.flags.FeatureFlags; import com.android.systemui.keyguard.WakefulnessLifecycle; +import com.android.systemui.monet.ColorScheme; import com.android.systemui.settings.UserTracker; import com.android.systemui.statusbar.policy.DeviceProvisionedController; import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceProvisionedListener; @@ -71,6 +75,7 @@ import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.Collection; import java.util.HashSet; +import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.Executor; @@ -107,6 +112,7 @@ public class ThemeOverlayController extends SystemUI implements Dumpable { private DeviceProvisionedController mDeviceProvisionedController; private WallpaperColors mCurrentColors; private WallpaperManager mWallpaperManager; + private ColorScheme mColorScheme; // If fabricated overlays were already created for the current theme. private boolean mNeedsOverlayCreation; // Dominant color extracted from wallpaper, NOT the color used on the overlay @@ -403,25 +409,47 @@ public class ThemeOverlayController extends SystemUI implements Dumpable { * Return the main theme color from a given {@link WallpaperColors} instance. */ protected int getNeutralColor(@NonNull WallpaperColors wallpaperColors) { - return wallpaperColors.getPrimaryColor().toArgb(); + return ColorScheme.getSeedColor(wallpaperColors); } protected int getAccentColor(@NonNull WallpaperColors wallpaperColors) { - Color accentCandidate = wallpaperColors.getSecondaryColor(); - if (accentCandidate == null) { - accentCandidate = wallpaperColors.getTertiaryColor(); - } - if (accentCandidate == null) { - accentCandidate = wallpaperColors.getPrimaryColor(); - } - return accentCandidate.toArgb(); + return ColorScheme.getSeedColor(wallpaperColors); } /** * Given a color candidate, return an overlay definition. */ protected @Nullable FabricatedOverlay getOverlay(int color, int type) { - return null; + boolean nightMode = (mContext.getResources().getConfiguration().uiMode + & Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES; + + mColorScheme = new ColorScheme(color, nightMode); + List colorShades = type == ACCENT + ? mColorScheme.getAllAccentColors() : mColorScheme.getAllNeutralColors(); + String name = type == ACCENT ? "accent" : "neutral"; + int paletteSize = mColorScheme.getAccent1().size(); + FabricatedOverlay.Builder overlay = + new FabricatedOverlay.Builder("com.android.systemui", name, "android"); + for (int i = 0; i < colorShades.size(); i++) { + int luminosity = i % paletteSize; + int paletteIndex = i / paletteSize + 1; + String resourceName; + switch (luminosity) { + case 0: + resourceName = "android:color/system_" + name + paletteIndex + "_10"; + break; + case 1: + resourceName = "android:color/system_" + name + paletteIndex + "_50"; + break; + default: + int l = luminosity - 1; + resourceName = "android:color/system_" + name + paletteIndex + "_" + l + "00"; + } + overlay.setResourceValue(resourceName, TypedValue.TYPE_INT_COLOR_ARGB8, + ColorUtils.setAlphaComponent(colorShades.get(i), 0xFF)); + } + + return overlay.build(); } private void updateThemeOverlays() { @@ -521,7 +549,7 @@ public class ThemeOverlayController extends SystemUI implements Dumpable { .map(key -> key + " -> " + categoryToPackage.get(key)).collect( Collectors.joining(", "))); } - Runnable overlaysAppliedRunnable = () -> onOverlaysApplied(); + Runnable overlaysAppliedRunnable = this::onOverlaysApplied; if (mNeedsOverlayCreation) { mNeedsOverlayCreation = false; mThemeManager.applyCurrentUserOverlays(categoryToPackage, new FabricatedOverlay[] { @@ -544,6 +572,7 @@ public class ThemeOverlayController extends SystemUI implements Dumpable { pw.println("mSecondaryOverlay=" + mSecondaryOverlay); pw.println("mNeutralOverlay=" + mNeutralOverlay); pw.println("mIsMonetEnabled=" + mIsMonetEnabled); + pw.println("mColorScheme=" + mColorScheme); pw.println("mNeedsOverlayCreation=" + mNeedsOverlayCreation); pw.println("mAcceptColorEvents=" + mAcceptColorEvents); pw.println("mDeferredThemeEvaluation=" + mDeferredThemeEvaluation); diff --git a/packages/SystemUI/tests/src/com/android/systemui/monet/ColorSchemeTest.java b/packages/SystemUI/tests/src/com/android/systemui/monet/ColorSchemeTest.java new file mode 100644 index 0000000000000..bc86ef98c6fe6 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/monet/ColorSchemeTest.java @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.monet; + +import android.app.WallpaperColors; +import android.graphics.Color; +import android.testing.AndroidTestingRunner; + +import androidx.test.filters.SmallTest; + +import com.android.systemui.SysuiTestCase; + +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.util.List; + +@SmallTest +@RunWith(AndroidTestingRunner.class) +public class ColorSchemeTest extends SysuiTestCase { + @Test + public void testFilterTransparency() { + ColorScheme colorScheme = new ColorScheme(Color.TRANSPARENT, false /* darkTheme */); + Assert.assertEquals(colorScheme.getAllAccentColors(), + new ColorScheme(0xFF1b6ef3, false).getAllAccentColors()); + } + + @Test + public void testDontFilterOpaque() { + ColorScheme colorScheme = new ColorScheme(0xFFFF0000, false /* darkTheme */); + Assert.assertNotEquals(colorScheme.getAllAccentColors(), + new ColorScheme(0xFF1b6ef3, false).getAllAccentColors()); + } + + @Test + public void testUniqueColors() { + WallpaperColors wallpaperColors = new WallpaperColors(Color.valueOf(0xffaec00a), + Color.valueOf(0xffaec00a), Color.valueOf(0xffaec00a)); + + List rankedSeedColors = ColorScheme.getSeedColors(wallpaperColors); + Assert.assertEquals(rankedSeedColors, List.of(0xffaec00a)); + } + + + @Test + public void testFiltersInvalidColors() { + WallpaperColors wallpaperColors = new WallpaperColors(Color.valueOf(0xff5e7ea2), + Color.valueOf(0xff5e7ea2), Color.valueOf(0xff000000)); + + List rankedSeedColors = ColorScheme.getSeedColors(wallpaperColors); + Assert.assertEquals(rankedSeedColors, List.of(0xff5e7ea2)); + } + + @Test + public void testInvalidColorBecomesGBlue() { + WallpaperColors wallpaperColors = new WallpaperColors(Color.valueOf(0xff000000), null, + null); + + List rankedSeedColors = ColorScheme.getSeedColors(wallpaperColors); + Assert.assertEquals(rankedSeedColors, List.of(0xFF1b6ef3)); + } + + @Test + public void testDontFilterRRGGBB() { + ColorScheme colorScheme = new ColorScheme(0xFF0000, false /* darkTheme */); + Assert.assertEquals(colorScheme.getAllAccentColors(), + new ColorScheme(0xFFFF0000, false).getAllAccentColors()); + } + + @Test + public void testNoPopulationSignal() { + WallpaperColors wallpaperColors = new WallpaperColors(Color.valueOf(0xffaec00a), + Color.valueOf(0xffbe0000), Color.valueOf(0xffcc040f)); + + List rankedSeedColors = ColorScheme.getSeedColors(wallpaperColors); + Assert.assertEquals(rankedSeedColors, List.of(0xffaec00a, 0xffbe0000, 0xffcc040f)); + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayControllerTest.java index cd911cc533f72..4c282bfaed93d 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayControllerTest.java @@ -167,7 +167,7 @@ public class ThemeOverlayControllerTest extends SysuiTestCase { assertThat(themeOverlays.getValue().get(OVERLAY_CATEGORY_SYSTEM_PALETTE)) .isEqualTo(new OverlayIdentifier("ffff0000")); assertThat(themeOverlays.getValue().get(OVERLAY_CATEGORY_ACCENT_COLOR)) - .isEqualTo(new OverlayIdentifier("ff0000ff")); + .isEqualTo(new OverlayIdentifier("ffff0000")); // Should not ask again if changed to same value mColorsListener.getValue().onColorsChanged(mainColors, WallpaperManager.FLAG_SYSTEM);