diff options
| author | 2024-05-22 12:18:46 +0000 | |
|---|---|---|
| committer | 2024-05-22 12:18:46 +0000 | |
| commit | bef30116cb1a2160a61718570f3cf2f0ccf0809e (patch) | |
| tree | 44a3eb786e74cb68dcb0f2af55a9918bb9f6aba8 | |
| parent | 20bf1d01a0f3ac8a96fec1d716610267248681fd (diff) | |
| parent | 285f790713dce28c019506813408a1863d2347cd (diff) | |
Merge "Moving Server dependencies to frameworks/libs" into main
13 files changed, 7 insertions, 1326 deletions
diff --git a/packages/SystemUI/monet/Android.bp b/packages/SystemUI/monet/Android.bp deleted file mode 100644 index c54fdab4e77f..000000000000 --- a/packages/SystemUI/monet/Android.bp +++ /dev/null @@ -1,33 +0,0 @@ -// -// 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_team: "trendy_team_system_ui_please_use_a_more_specific_subteam_if_possible_", - default_applicable_licenses: ["Android-Apache-2.0"], -} - -java_library { - name: "monet", - platform_apis: true, - static_libs: [ - "androidx.annotation_annotation", - "androidx.core_core", - "libmonet", - ], - srcs: [ - "src/**/*.java", - "src/**/*.kt", - ], -} diff --git a/packages/SystemUI/monet/AndroidManifest.xml b/packages/SystemUI/monet/AndroidManifest.xml deleted file mode 100644 index 1fab52877847..000000000000 --- a/packages/SystemUI/monet/AndroidManifest.xml +++ /dev/null @@ -1,20 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - 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. ---> - -<manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.android.systemui.monet"> -</manifest> diff --git a/packages/SystemUI/monet/src/com/android/systemui/monet/ColorScheme.kt b/packages/SystemUI/monet/src/com/android/systemui/monet/ColorScheme.kt deleted file mode 100644 index 624f18d53a70..000000000000 --- a/packages/SystemUI/monet/src/com/android/systemui/monet/ColorScheme.kt +++ /dev/null @@ -1,372 +0,0 @@ -/* - * 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.google.ux.material.libmonet.hct.Hct -import com.google.ux.material.libmonet.scheme.DynamicScheme -import com.google.ux.material.libmonet.scheme.SchemeContent -import com.google.ux.material.libmonet.scheme.SchemeExpressive -import com.google.ux.material.libmonet.scheme.SchemeFruitSalad -import com.google.ux.material.libmonet.scheme.SchemeMonochrome -import com.google.ux.material.libmonet.scheme.SchemeNeutral -import com.google.ux.material.libmonet.scheme.SchemeRainbow -import com.google.ux.material.libmonet.scheme.SchemeTonalSpot -import com.google.ux.material.libmonet.scheme.SchemeVibrant -import kotlin.math.absoluteValue -import kotlin.math.roundToInt - -const val TAG = "ColorScheme" - -const val ACCENT1_CHROMA = 48.0f -const val GOOGLE_BLUE = 0xFF1b6ef3.toInt() -const val MIN_CHROMA = 5 - -enum class Style{ - SPRITZ, - TONAL_SPOT, - VIBRANT, - EXPRESSIVE, - RAINBOW, - FRUIT_SALAD, - CONTENT, - MONOCHROMATIC, - CLOCK, - CLOCK_VIBRANT -} - -class TonalPalette -internal constructor( - private val materialTonalPalette: com.google.ux.material.libmonet.palettes.TonalPalette -) { - @Deprecated("Do not use. For color system only") - val allShades: List<Int> - val allShadesMapped: Map<Int, Int> - - init{ - allShades = SHADE_KEYS.map {key -> getAtTone(key.toFloat()) } - allShadesMapped = SHADE_KEYS.zip(allShades).toMap() - } - - // Dynamically computed tones across the full range from 0 to 1000 - fun getAtTone(shade: Float): Int = materialTonalPalette.tone(((1000.0f - shade) / 10f).toInt()) - - // Predefined & precomputed tones - val s0: Int - get() = this.allShades[0] - val s10: Int - get() = this.allShades[1] - val s50: Int - get() = this.allShades[2] - val s100: Int - get() = this.allShades[3] - val s200: Int - get() = this.allShades[4] - val s300: Int - get() = this.allShades[5] - val s400: Int - get() = this.allShades[6] - val s500: Int - get() = this.allShades[7] - val s600: Int - get() = this.allShades[8] - val s700: Int - get() = this.allShades[9] - val s800: Int - get() = this.allShades[10] - val s900: Int - get() = this.allShades[11] - val s1000: Int - get() = this.allShades[12] - - companion object { - val SHADE_KEYS = listOf(0, 10, 50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000) - } -} - -@Deprecated("Please use com.google.ux.material.libmonet.dynamiccolor.MaterialDynamicColors " + - "instead") -class ColorScheme( - @ColorInt val seed: Int, - val isDark: Boolean, - val style: Style, - val contrastLevel: Double -) { - var materialScheme: DynamicScheme - - private val proposedSeedHct: Hct = Hct.fromInt(seed) - private val seedHct: Hct = Hct.fromInt(if (seed == Color.TRANSPARENT) { - GOOGLE_BLUE - } else if (style != Style.CONTENT && proposedSeedHct.chroma < 5) { - GOOGLE_BLUE - } else { - seed - }) - - val accent1: TonalPalette - val accent2: TonalPalette - val accent3: TonalPalette - val neutral1: TonalPalette - val neutral2: TonalPalette - - constructor(@ColorInt seed: Int, darkTheme: Boolean) : this(seed, darkTheme, Style.TONAL_SPOT) - - @JvmOverloads - constructor( - @ColorInt seed: Int, - darkTheme: Boolean, - style: Style - ) : this(seed, darkTheme, style, 0.0) - - @JvmOverloads - constructor( - wallpaperColors: WallpaperColors, - darkTheme: Boolean, - style: Style = Style.TONAL_SPOT - ) : this(getSeedColor(wallpaperColors, style != Style.CONTENT), darkTheme, style) - - val backgroundColor - get() = ColorUtils.setAlphaComponent(if (isDark) neutral1.s700 else neutral1.s10, 0xFF) - - val accentColor - get() = ColorUtils.setAlphaComponent(if (isDark) accent1.s100 else accent1.s500, 0xFF) - - init { - materialScheme = when (style) { - Style.SPRITZ -> SchemeNeutral(seedHct, isDark, contrastLevel) - Style.TONAL_SPOT -> SchemeTonalSpot(seedHct, isDark, contrastLevel) - Style.VIBRANT -> SchemeVibrant(seedHct, isDark, contrastLevel) - Style.EXPRESSIVE -> SchemeExpressive(seedHct, isDark, contrastLevel) - Style.RAINBOW -> SchemeRainbow(seedHct, isDark, contrastLevel) - Style.FRUIT_SALAD -> SchemeFruitSalad(seedHct, isDark, contrastLevel) - Style.CONTENT -> SchemeContent(seedHct, isDark, contrastLevel) - Style.MONOCHROMATIC -> SchemeMonochrome(seedHct, isDark, contrastLevel) - - // SystemUI Schemes - Style.CLOCK -> SchemeClock(seedHct, isDark, contrastLevel) - Style.CLOCK_VIBRANT -> SchemeClockVibrant(seedHct, isDark, contrastLevel) - } - - accent1 = TonalPalette(materialScheme.primaryPalette) - accent2 = TonalPalette(materialScheme.secondaryPalette) - accent3 = TonalPalette(materialScheme.tertiaryPalette) - neutral1 = TonalPalette(materialScheme.neutralPalette) - neutral2 = TonalPalette(materialScheme.neutralVariantPalette) - } - - val seedTone: Float - get() = 1000f - proposedSeedHct.tone.toFloat() * 10f - - override fun toString(): String { - return "ColorScheme {\n" + - " seed color: ${stringForColor(seed)}\n" + - " style: $style\n" + - " palettes: \n" + - " ${humanReadable("PRIMARY", accent1.allShades)}\n" + - " ${humanReadable("SECONDARY", accent2.allShades)}\n" + - " ${humanReadable("TERTIARY", accent3.allShades)}\n" + - " ${humanReadable("NEUTRAL", neutral1.allShades)}\n" + - " ${humanReadable("NEUTRAL VARIANT", neutral2.allShades)}\n" + - "}" - } - - companion object { - /** - * Identifies a color to create a color scheme from. - * - * @param wallpaperColors Colors extracted from an image via quantization. - * @param filter If false, allow colors that have low chroma, creating grayscale themes. - * @return ARGB int representing the color - */ - @JvmStatic - @JvmOverloads - @ColorInt - fun getSeedColor(wallpaperColors: WallpaperColors, filter: Boolean = true): Int { - return getSeedColors(wallpaperColors, filter).first() - } - - /** - * Filters and ranks colors from WallpaperColors. - * - * @param wallpaperColors Colors extracted from an image via quantization. - * @param filter If false, allow colors that have low chroma, creating grayscale themes. - * @return List of ARGB ints, ordered from highest scoring to lowest. - */ - @JvmStatic - @JvmOverloads - fun getSeedColors(wallpaperColors: WallpaperColors, filter: Boolean = true): List<Int> { - 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 { - if (!filter) { - true - } else { - Hct.fromInt(it).chroma >= MIN_CHROMA - } - } - .toList() - if (distinctColors.isEmpty()) { - return listOf(GOOGLE_BLUE) - } - return distinctColors - } - - val intToProportion = - wallpaperColors.allColors.mapValues { it.value.toDouble() / totalPopulation } - val intToHct = wallpaperColors.allColors.mapValues { Hct.fromInt(it.key) } - - // Get an array with 360 slots. A slot contains the percentage of colors with that hue. - val hueProportions = huePopulations(intToHct, intToProportion, filter) - // Map each color to the percentage of the image with its hue. - val intToHueProportion = - wallpaperColors.allColors.mapValues { - val hct = intToHct[it.key]!! - val hue = hct.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 filteredIntToHct = - if (!filter) intToHct - else - (intToHct.filter { - val hct = it.value - val proportion = intToHueProportion[it.key]!! - hct.chroma >= MIN_CHROMA && - (totalPopulationMeaningless || proportion > 0.01) - }) - // Sort the colors by score, from high to low. - val intToScoreIntermediate = - filteredIntToHct.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 the color is distinct in hue from colors picked so far, pick the color. - // Iteratively decrease the amount of hue distinctness required, thus ensuring we - // maximize difference between colors. - val minimumHueDistance = 15 - val seeds = mutableListOf<Int>() - maximizeHueDistance@ for (i in 90 downTo minimumHueDistance step 1) { - seeds.clear() - for (entry in intToScore) { - val int = entry.key - val existingSeedNearby = - seeds.find { - val hueA = intToHct[int]!!.hue - val hueB = intToHct[it]!!.hue - hueDiff(hueA, hueB) < i - } != null - if (existingSeedNearby) { - continue - } - seeds.add(int) - if (seeds.size >= 4) { - break@maximizeHueDistance - } - } - } - - 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: Double, b: Double): Double { - return 180f - ((a - b).absoluteValue - 180f).absoluteValue - } - - private fun stringForColor(color: Int): String { - val width = 4 - val hct = Hct.fromInt(color) - val h = "H${hct.hue.roundToInt().toString().padEnd(width)}" - val c = "C${hct.chroma.roundToInt().toString().padEnd(width)}" - val t = "T${hct.tone.roundToInt().toString().padEnd(width)}" - val hex = Integer.toHexString(color and 0xffffff).padStart(6, '0').uppercase() - return "$h$c$t = #$hex" - } - - private fun humanReadable(paletteName: String, colors: List<Int>): String { - return "$paletteName\n" + - colors.map { stringForColor(it) }.joinToString(separator = "\n") { it } - } - - private fun score(hct: Hct, proportion: Double): Double { - val proportionScore = 0.7 * 100.0 * proportion - val chromaScore = - if (hct.chroma < ACCENT1_CHROMA) 0.1 * (hct.chroma - ACCENT1_CHROMA) - else 0.3 * (hct.chroma - ACCENT1_CHROMA) - return chromaScore + proportionScore - } - - private fun huePopulations( - hctByColor: Map<Int, Hct>, - populationByColor: Map<Int, Double>, - filter: Boolean = true - ): List<Double> { - val huePopulation = List(size = 360, init = { 0.0 }).toMutableList() - - for (entry in populationByColor.entries) { - val population = populationByColor[entry.key]!! - val hct = hctByColor[entry.key]!! - val hue = hct.hue.roundToInt() % 360 - if (filter && hct.chroma <= MIN_CHROMA) { - continue - } - huePopulation[hue] = huePopulation[hue] + population - } - - return huePopulation - } - } -} diff --git a/packages/SystemUI/monet/src/com/android/systemui/monet/SchemeClock.java b/packages/SystemUI/monet/src/com/android/systemui/monet/SchemeClock.java deleted file mode 100644 index 4747cc5dbf9c..000000000000 --- a/packages/SystemUI/monet/src/com/android/systemui/monet/SchemeClock.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (C) 2024 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 static com.google.ux.material.libmonet.utils.MathUtils.clampDouble; - -import static java.lang.Double.max; - -import com.google.ux.material.libmonet.hct.Hct; -import com.google.ux.material.libmonet.palettes.TonalPalette; -import com.google.ux.material.libmonet.scheme.DynamicScheme; -import com.google.ux.material.libmonet.scheme.Variant; - -public class SchemeClock extends DynamicScheme { - public SchemeClock(Hct sourceColorHct, boolean isDark, double contrastLevel) { - super( - sourceColorHct, - Variant.MONOCHROME, - isDark, - contrastLevel, - /*primary*/ - TonalPalette.fromHueAndChroma( - /*hue*/ sourceColorHct.getHue(), - /*chroma*/ max(sourceColorHct.getChroma(), 20) - ), - /*secondary*/ - TonalPalette.fromHueAndChroma( - /*hue*/ sourceColorHct.getHue() + 10.0, - /*chroma*/ clampDouble(17, 40, sourceColorHct.getChroma() * 0.85) - ), - /*tertiary*/ - TonalPalette.fromHueAndChroma( - /*hue*/ sourceColorHct.getHue() + 20.0, - /*chroma*/ max(sourceColorHct.getChroma() + 20, 50) - ), - - //not used - TonalPalette.fromHueAndChroma(sourceColorHct.getHue(), 0.0), - TonalPalette.fromHueAndChroma(sourceColorHct.getHue(), 0.0)); - } -} diff --git a/packages/SystemUI/monet/src/com/android/systemui/monet/SchemeClockVibrant.java b/packages/SystemUI/monet/src/com/android/systemui/monet/SchemeClockVibrant.java deleted file mode 100644 index fb5e972434af..000000000000 --- a/packages/SystemUI/monet/src/com/android/systemui/monet/SchemeClockVibrant.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (C) 2024 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 static java.lang.Double.max; - -import com.google.ux.material.libmonet.hct.Hct; -import com.google.ux.material.libmonet.palettes.TonalPalette; -import com.google.ux.material.libmonet.scheme.DynamicScheme; -import com.google.ux.material.libmonet.scheme.Variant; - -public class SchemeClockVibrant extends DynamicScheme { - public SchemeClockVibrant(Hct sourceColorHct, boolean isDark, double contrastLevel) { - super( - sourceColorHct, - Variant.MONOCHROME, - isDark, - contrastLevel, - /*primary*/ - TonalPalette.fromHueAndChroma( - /*hue*/ sourceColorHct.getHue(), - /*chroma*/ max(sourceColorHct.getChroma(), 70) - ), - /*secondary*/ - TonalPalette.fromHueAndChroma( - /*hue*/ sourceColorHct.getHue() + 20.0, - /*chroma*/ max(sourceColorHct.getChroma(), 70) - ), - /*tertiary*/ - TonalPalette.fromHueAndChroma( - /*hue*/ sourceColorHct.getHue() + 60.0, - /*chroma*/ max(sourceColorHct.getChroma(), 70) - ), - - //not used - TonalPalette.fromHueAndChroma(sourceColorHct.getHue(), 0.0), - TonalPalette.fromHueAndChroma(sourceColorHct.getHue(), 0.0)); - } -} diff --git a/packages/SystemUI/monet/src/com/android/systemui/monet/Shades.java b/packages/SystemUI/monet/src/com/android/systemui/monet/Shades.java deleted file mode 100644 index c8b9fe024e7d..000000000000 --- a/packages/SystemUI/monet/src/com/android/systemui/monet/Shades.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * 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_. - * <p> - * 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]; - // At tone 90 and above, blue and yellow hues can reach a much higher chroma. - // To preserve a consistent appearance across all hues, use a maximum chroma of 40. - shades[0] = ColorUtils.CAMToColor(hue, Math.min(40f, chroma), 99); - shades[1] = ColorUtils.CAMToColor(hue, Math.min(40f, 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/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt index bda5be4f6533..fb1853f13ce9 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt @@ -631,7 +631,7 @@ constructor( // color will need to use wallpaper's extracted color and consider if the // wallpaper's color is dark or light. val style = themeStyle ?: fetchThemeStyleFromSetting().also { themeStyle = it } - val wallpaperColorScheme = ColorScheme(colors, darkTheme = false, style) + val wallpaperColorScheme = ColorScheme(colors, false, style) val lightClockColor = wallpaperColorScheme.accent1.s100 val darkClockColor = wallpaperColorScheme.accent2.s600 diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/util/MediaArtworkHelper.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/util/MediaArtworkHelper.kt index 3b09f4138658..c97221e7bd50 100644 --- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/util/MediaArtworkHelper.kt +++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/util/MediaArtworkHelper.kt @@ -107,7 +107,7 @@ object MediaArtworkHelper { return try { // Set up media source app's logo. val icon = applicationContext.packageManager.getApplicationIcon(packageName) - ColorScheme(WallpaperColors.fromDrawable(icon), darkTheme = true, style) + ColorScheme(WallpaperColors.fromDrawable(icon), true, style) } catch (e: PackageManager.NameNotFoundException) { Log.w(tag, "Fail to get media app info", e) null diff --git a/packages/SystemUI/src/com/android/systemui/theme/CustomDynamicColors.java b/packages/SystemUI/src/com/android/systemui/theme/CustomDynamicColors.java deleted file mode 100644 index efeb2f919b56..000000000000 --- a/packages/SystemUI/src/com/android/systemui/theme/CustomDynamicColors.java +++ /dev/null @@ -1,322 +0,0 @@ -/* - * Copyright (C) 2024 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.theme; - -import com.google.ux.material.libmonet.dynamiccolor.ContrastCurve; -import com.google.ux.material.libmonet.dynamiccolor.DynamicColor; -import com.google.ux.material.libmonet.dynamiccolor.MaterialDynamicColors; -import com.google.ux.material.libmonet.dynamiccolor.ToneDeltaPair; -import com.google.ux.material.libmonet.dynamiccolor.TonePolarity; - -class CustomDynamicColors { - private final MaterialDynamicColors mMdc; - - CustomDynamicColors(boolean isExtendedFidelity) { - this.mMdc = new MaterialDynamicColors(isExtendedFidelity); - } - - // CLOCK COLORS - - public DynamicColor widgetBackground() { - return new DynamicColor( - /* name= */ "widget_background", - /* palette= */ (s) -> s.primaryPalette, - /* tone= */ (s) -> s.isDark ? 20.0 : 95.0, - /* isBackground= */ true, - /* background= */ null, - /* secondBackground= */ null, - /* contrastCurve= */ null, - /* toneDeltaPair= */ null); - } - - public DynamicColor clockHour() { - return new DynamicColor( - /* name= */ "clock_hour", - /* palette= */ (s) -> s.secondaryPalette, - /* tone= */ (s) -> s.isDark ? 30.0 : 60.0, - /* isBackground= */ false, - /* background= */ (s) -> widgetBackground(), - /* secondBackground= */ null, - /* contrastCurve= */ new ContrastCurve(1.0, 4.0, 5.0, 15.0), - /* toneDeltaPair= */ - (s) -> new ToneDeltaPair(clockHour(), clockMinute(), 10.0, TonePolarity.DARKER, - false)); - } - - public DynamicColor clockMinute() { - return new DynamicColor( - /* name= */ "clock_minute", - /* palette= */ (s) -> s.primaryPalette, - /* tone= */ (s) -> s.isDark ? 40.0 : 90.0, - /* isBackground= */ false, - /* background= */ (s) -> widgetBackground(), - /* secondBackground= */ null, - /* contrastCurve= */ new ContrastCurve(1.0, 6.5, 10.0, 15.0), - /* toneDeltaPair= */ null); - } - - public DynamicColor clockSecond() { - return new DynamicColor( - /* name= */ "clock_second", - /* palette= */ (s) -> s.tertiaryPalette, - /* tone= */ (s) -> s.isDark ? 40.0 : 90.0, - /* isBackground= */ false, - /* background= */ (s) -> widgetBackground(), - /* secondBackground= */ null, - /* contrastCurve= */ new ContrastCurve(1.0, 5.0, 70.0, 11.0), - /* toneDeltaPair= */ null); - } - - public DynamicColor weatherTemp() { - return new DynamicColor( - /* name= */ "clock_second", - /* palette= */ (s) -> s.primaryPalette, - /* tone= */ (s) -> s.isDark ? 55.0 : 80.0, - /* isBackground= */ false, - /* background= */ (s) -> widgetBackground(), - /* secondBackground= */ null, - /* contrastCurve= */ new ContrastCurve(1.0, 5.0, 70.0, 11.0), - /* toneDeltaPair= */ null); - } - - // THEME APP ICONS - - public DynamicColor themeApp() { - return new DynamicColor( - /* name= */ "theme_app", - /* palette= */ (s) -> s.primaryPalette, - /* tone= */ (s) -> s.isDark ? 90.0 : 30.0, // Adjusted values - /* isBackground= */ true, - /* background= */ null, - /* secondBackground= */ null, - /* contrastCurve= */ null, - /* toneDeltaPair= */ null); - } - - public DynamicColor onThemeApp() { - return new DynamicColor( - /* name= */ "on_theme_app", - /* palette= */ (s) -> s.primaryPalette, - /* tone= */ (s) -> s.isDark ? 40.0 : 80.0, // Adjusted values - /* isBackground= */ false, - /* background= */ (s) -> themeApp(), - /* secondBackground= */ null, - /* contrastCurve= */ new ContrastCurve(1.0, 3.0, 7.0, 10.0), - /* toneDeltaPair= */ null); - } - - public DynamicColor themeAppRing() { - return new DynamicColor( - /* name= */ "theme_app_ring", - /* palette= */ (s) -> s.primaryPalette, - /* tone= */ (s) -> 70.0, - /* isBackground= */ true, - /* background= */ null, - /* secondBackground= */ null, - /* contrastCurve= */ new ContrastCurve(1.0, 1.0, 1.0, 1.0), - /* toneDeltaPair= */ null); - } - - public DynamicColor themeNotif() { - return new DynamicColor( - /* name= */ "theme_notif", - /* palette= */ (s) -> s.tertiaryPalette, - /* tone= */ (s) -> s.isDark ? 80.0 : 90.0, - /* isBackground= */ false, - /* background= */ (s) -> themeAppRing(), - /* secondBackground= */ null, - /* contrastCurve= */ new ContrastCurve(1.0, 1.0, 1.0, 1.0), - /* toneDeltaPair= */ - (s) -> new ToneDeltaPair(themeNotif(), themeAppRing(), 10.0, TonePolarity.NEARER, - false)); - } - - // SUPER G COLORS - - public DynamicColor brandA() { - return new DynamicColor( - /* name= */ "brand_a", - /* palette= */ (s) -> s.primaryPalette, - /* tone= */ (s) -> s.isDark ? 40.0 : 80.0, - /* isBackground= */ true, - /* background= */ (s) -> mMdc.surfaceContainerLow(), - /* secondBackground= */ null, - /* contrastCurve= */ new ContrastCurve(1.0, 3.0, 7.0, 17.0), - /* toneDeltaPair= */ - (s) -> new ToneDeltaPair(brandA(), brandB(), 10.0, TonePolarity.NEARER, false)); - } - - public DynamicColor brandB() { - return new DynamicColor( - /* name= */ "brand_b", - /* palette= */ (s) -> s.secondaryPalette, - /* tone= */ (s) -> s.isDark ? 70.0 : 98.0, - /* isBackground= */ true, - /* background= */ (s) -> mMdc.surfaceContainerLow(), - /* secondBackground= */ null, - /* contrastCurve= */ new ContrastCurve(1.0, 3.0, 3.0, 6.0), - /* toneDeltaPair= */ - (s) -> new ToneDeltaPair(brandB(), brandC(), 10.0, TonePolarity.NEARER, false)); - } - - public DynamicColor brandC() { - return new DynamicColor( - /* name= */ "brand_c", - /* palette= */ (s) -> s.primaryPalette, - /* tone= */ (s) -> s.isDark ? 50.0 : 60.0, - /* isBackground= */ false, - /* background= */ (s) -> mMdc.surfaceContainerLow(), - /* secondBackground= */ null, - /* contrastCurve= */ new ContrastCurve(1.0, 3.0, 4.0, 9.0), - /* toneDeltaPair= */ - (s) -> new ToneDeltaPair(brandC(), brandD(), 10.0, TonePolarity.NEARER, false)); - } - - public DynamicColor brandD() { - return new DynamicColor( - /* name= */ "brand_d", - /* palette= */ (s) -> s.tertiaryPalette, - /* tone= */ (s) -> s.isDark ? 59.0 : 90.0, - /* isBackground= */ false, - /* background= */ (s) -> mMdc.surfaceContainerLow(), - /* secondBackground= */ null, - /* contrastCurve= */ new ContrastCurve(1.0, 3.0, 4.0, 13.0), - /* toneDeltaPair= */ - (s) -> new ToneDeltaPair(brandD(), brandA(), 10.0, TonePolarity.NEARER, false)); - } - - // QUICK SETTING TIILES - - public DynamicColor underSurface() { - return new DynamicColor( - /* name= */ "under_surface", - /* palette= */ (s) -> s.primaryPalette, - /* tone= */ (s) -> 0.0, - /* isBackground= */ true, - /* background= */ null, - /* secondBackground= */ null, - /* contrastCurve= */ null, - /* toneDeltaPair= */ null); - } - - public DynamicColor shadeActive() { - return new DynamicColor( - /* name= */ "shade_active", - /* palette= */ (s) -> s.primaryPalette, - /* tone= */ (s) -> 90.0, - /* isBackground= */ false, - /* background= */ (s) -> underSurface(), - /* secondBackground= */ null, - /* contrastCurve= */ new ContrastCurve(1.0, 3.0, 4.5, 7.0), - /* toneDeltaPair= */ - (s) -> new ToneDeltaPair(shadeActive(), shadeInactive(), 30.0, TonePolarity.LIGHTER, - false)); - } - - public DynamicColor onShadeActive() { - return new DynamicColor( - /* name= */ "on_shade_active", - /* palette= */ (s) -> s.primaryPalette, - /* tone= */ (s) -> 10.0, - /* isBackground= */ false, - /* background= */ (s) -> shadeActive(), - /* secondBackground= */ null, - /* contrastCurve= */ new ContrastCurve(1.0, 4.5, 7.0, 11.0), - /* toneDeltaPair= */ - (s) -> new ToneDeltaPair(onShadeActive(), onShadeActiveVariant(), 20.0, - TonePolarity.NEARER, false)); - } - - public DynamicColor onShadeActiveVariant() { - return new DynamicColor( - /* name= */ "on_shade_active_variant", - /* palette= */ (s) -> s.primaryPalette, - /* tone= */ (s) -> 30.0, - /* isBackground= */ false, - /* background= */ (s) -> shadeActive(), - /* secondBackground= */ null, - /* contrastCurve= */ new ContrastCurve(1.0, 4.5, 7.0, 11.0), - /* toneDeltaPair= */ - (s) -> new ToneDeltaPair(onShadeActiveVariant(), onShadeActive(), 20.0, - TonePolarity.NEARER, false)); - } - - public DynamicColor shadeInactive() { - return new DynamicColor( - /* name= */ "shade_inactive", - /* palette= */ (s) -> s.neutralPalette, - /* tone= */ (s) -> 20.0, - /* isBackground= */ true, - /* background= */ (s) -> underSurface(), - /* secondBackground= */ null, - /* contrastCurve= */ new ContrastCurve(1.0, 1.0, 1.0, 1.0), - /* toneDeltaPair= */(s) -> new ToneDeltaPair(shadeInactive(), shadeDisabled(), 15.0, - TonePolarity.LIGHTER, false)); - } - - public DynamicColor onShadeInactive() { - return new DynamicColor( - /* name= */ "on_shade_inactive", - /* palette= */ (s) -> s.neutralVariantPalette, - /* tone= */ (s) -> 90.0, - /* isBackground= */ true, - /* background= */ (s) -> shadeInactive(), - /* secondBackground= */ null, - /* contrastCurve= */ new ContrastCurve(1.0, 4.5, 7.0, 11.0), - /* toneDeltaPair= */ - (s) -> new ToneDeltaPair(onShadeInactive(), onShadeInactiveVariant(), 10.0, - TonePolarity.NEARER, false)); - } - - public DynamicColor onShadeInactiveVariant() { - return new DynamicColor( - /* name= */ "on_shade_inactive_variant", - /* palette= */ (s) -> s.neutralVariantPalette, - /* tone= */ (s) -> 80.0, - /* isBackground= */ false, - /* background= */ (s) -> shadeInactive(), - /* secondBackground= */ null, - /* contrastCurve= */ new ContrastCurve(1.0, 4.5, 7.0, 11.0), - /* toneDeltaPair= */ - (s) -> new ToneDeltaPair(onShadeInactiveVariant(), onShadeInactive(), 10.0, - TonePolarity.NEARER, false)); - } - - public DynamicColor shadeDisabled() { - return new DynamicColor( - /* name= */ "shade_disabled", - /* palette= */ (s) -> s.neutralPalette, - /* tone= */ (s) -> 4.0, - /* isBackground= */ false, - /* background= */ (s) -> underSurface(), - /* secondBackground= */ null, - /* contrastCurve= */ new ContrastCurve(1.0, 1.0, 1.0, 1.0), - /* toneDeltaPair= */ null); - } - - public DynamicColor overviewBackground() { - return new DynamicColor( - /* name= */ "overview_background", - /* palette= */ (s) -> s.neutralVariantPalette, - /* tone= */ (s) -> s.isDark ? 80.0 : 35.0, - /* isBackground= */ true, - /* background= */ null, - /* secondBackground= */ null, - /* contrastCurve= */null, - /* toneDeltaPair= */ null); - } -} diff --git a/packages/SystemUI/src/com/android/systemui/theme/DynamicColors.kt b/packages/SystemUI/src/com/android/systemui/theme/DynamicColors.kt deleted file mode 100644 index 35187597bd83..000000000000 --- a/packages/SystemUI/src/com/android/systemui/theme/DynamicColors.kt +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright (C) 2023 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.theme - -import android.util.Pair -import com.google.ux.material.libmonet.dynamiccolor.DynamicColor -import com.google.ux.material.libmonet.dynamiccolor.MaterialDynamicColors - -class DynamicColors { - companion object { - @JvmStatic - fun allDynamicColorsMapped(isExtendedFidelity: Boolean): List<Pair<String, DynamicColor>> { - val mdc = MaterialDynamicColors(isExtendedFidelity) - return arrayListOf( - Pair.create("primary_container", mdc.primaryContainer()), - Pair.create("on_primary_container", mdc.onPrimaryContainer()), - Pair.create("primary", mdc.primary()), - Pair.create("on_primary", mdc.onPrimary()), - Pair.create("secondary_container", mdc.secondaryContainer()), - Pair.create("on_secondary_container", mdc.onSecondaryContainer()), - Pair.create("secondary", mdc.secondary()), - Pair.create("on_secondary", mdc.onSecondary()), - Pair.create("tertiary_container", mdc.tertiaryContainer()), - Pair.create("on_tertiary_container", mdc.onTertiaryContainer()), - Pair.create("tertiary", mdc.tertiary()), - Pair.create("on_tertiary", mdc.onTertiary()), - Pair.create("background", mdc.background()), - Pair.create("on_background", mdc.onBackground()), - Pair.create("surface", mdc.surface()), - Pair.create("on_surface", mdc.onSurface()), - Pair.create("surface_container_low", mdc.surfaceContainerLow()), - Pair.create("surface_container_lowest", mdc.surfaceContainerLowest()), - Pair.create("surface_container", mdc.surfaceContainer()), - Pair.create("surface_container_high", mdc.surfaceContainerHigh()), - Pair.create("surface_container_highest", mdc.surfaceContainerHighest()), - Pair.create("surface_bright", mdc.surfaceBright()), - Pair.create("surface_dim", mdc.surfaceDim()), - Pair.create("surface_variant", mdc.surfaceVariant()), - Pair.create("on_surface_variant", mdc.onSurfaceVariant()), - Pair.create("outline", mdc.outline()), - Pair.create("outline_variant", mdc.outlineVariant()), - Pair.create("error", mdc.error()), - Pair.create("on_error", mdc.onError()), - Pair.create("error_container", mdc.errorContainer()), - Pair.create("on_error_container", mdc.onErrorContainer()), - Pair.create("control_activated", mdc.controlActivated()), - Pair.create("control_normal", mdc.controlNormal()), - Pair.create("control_highlight", mdc.controlHighlight()), - Pair.create("text_primary_inverse", mdc.textPrimaryInverse()), - Pair.create( - "text_secondary_and_tertiary_inverse", - mdc.textSecondaryAndTertiaryInverse() - ), - Pair.create( - "text_primary_inverse_disable_only", - mdc.textPrimaryInverseDisableOnly() - ), - Pair.create( - "text_secondary_and_tertiary_inverse_disabled", - mdc.textSecondaryAndTertiaryInverseDisabled() - ), - Pair.create("text_hint_inverse", mdc.textHintInverse()), - Pair.create("palette_key_color_primary", mdc.primaryPaletteKeyColor()), - Pair.create("palette_key_color_secondary", mdc.secondaryPaletteKeyColor()), - Pair.create("palette_key_color_tertiary", mdc.tertiaryPaletteKeyColor()), - Pair.create("palette_key_color_neutral", mdc.neutralPaletteKeyColor()), - Pair.create( - "palette_key_color_neutral_variant", - mdc.neutralVariantPaletteKeyColor() - ), - ) - } - - @JvmStatic - fun getFixedColorsMapped(isExtendedFidelity: Boolean): List<Pair<String, DynamicColor>> { - val mdc = MaterialDynamicColors(isExtendedFidelity) - return arrayListOf( - Pair.create("primary_fixed", mdc.primaryFixed()), - Pair.create("primary_fixed_dim", mdc.primaryFixedDim()), - Pair.create("on_primary_fixed", mdc.onPrimaryFixed()), - Pair.create("on_primary_fixed_variant", mdc.onPrimaryFixedVariant()), - Pair.create("secondary_fixed", mdc.secondaryFixed()), - Pair.create("secondary_fixed_dim", mdc.secondaryFixedDim()), - Pair.create("on_secondary_fixed", mdc.onSecondaryFixed()), - Pair.create("on_secondary_fixed_variant", mdc.onSecondaryFixedVariant()), - Pair.create("tertiary_fixed", mdc.tertiaryFixed()), - Pair.create("tertiary_fixed_dim", mdc.tertiaryFixedDim()), - Pair.create("on_tertiary_fixed", mdc.onTertiaryFixed()), - Pair.create("on_tertiary_fixed_variant", mdc.onTertiaryFixedVariant()), - ) - } - - @JvmStatic - fun getCustomColorsMapped(isExtendedFidelity: Boolean): List<Pair<String, DynamicColor>> { - val customMdc = CustomDynamicColors(isExtendedFidelity) - return arrayListOf( - Pair.create("widget_background", customMdc.widgetBackground()), - Pair.create("clock_hour", customMdc.clockHour()), - Pair.create("clock_minute", customMdc.clockMinute()), - Pair.create("clock_second", customMdc.weatherTemp()), - Pair.create("theme_app", customMdc.themeApp()), - Pair.create("on_theme_app", customMdc.onThemeApp()), - Pair.create("theme_app_ring", customMdc.themeAppRing()), - Pair.create("on_theme_app_ring", customMdc.themeNotif()), - Pair.create("brand_a", customMdc.brandA()), - Pair.create("brand_b", customMdc.brandB()), - Pair.create("brand_c", customMdc.brandC()), - Pair.create("brand_d", customMdc.brandD()), - Pair.create("under_surface", customMdc.underSurface()), - Pair.create("shade_active", customMdc.shadeActive()), - Pair.create("on_shade_active", customMdc.onShadeActive()), - Pair.create("on_shade_active_variant", customMdc.onShadeActiveVariant()), - Pair.create("shade_inactive", customMdc.shadeInactive()), - Pair.create("on_shade_inactive", customMdc.onShadeInactive()), - Pair.create("on_shade_inactive_variant", customMdc.onShadeInactiveVariant()), - Pair.create("shade_disabled", customMdc.shadeDisabled()), - Pair.create("overview_background", customMdc.overviewBackground()) - ) - } - } -} diff --git a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java index d256c4acd955..7494649294f5 100644 --- a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java +++ b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java @@ -77,6 +77,7 @@ import com.android.systemui.keyguard.WakefulnessLifecycle; import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor; import com.android.systemui.keyguard.shared.model.KeyguardState; import com.android.systemui.monet.ColorScheme; +import com.android.systemui.monet.DynamicColors; import com.android.systemui.monet.Style; import com.android.systemui.monet.TonalPalette; import com.android.systemui.settings.UserTracker; @@ -623,7 +624,7 @@ public class ThemeOverlayController implements CoreStartable, Dumpable { TonalPalette tonalPalette) { String resourcePrefix = "android:color/system_" + name; - tonalPalette.getAllShadesMapped().forEach((key, value) -> { + tonalPalette.allShadesMapped.forEach((key, value) -> { String resourceName = resourcePrefix + "_" + key; int colorValue = ColorUtils.setAlphaComponent(value, 0xFF); overlay.setResourceValue(resourceName, TYPE_INT_COLOR_ARGB8, colorValue, @@ -634,7 +635,7 @@ public class ThemeOverlayController implements CoreStartable, Dumpable { protected FabricatedOverlay createDynamicOverlay() { FabricatedOverlay overlay = newFabricatedOverlay("dynamic"); //Themed Colors - assignColorsToOverlay(overlay, DynamicColors.allDynamicColorsMapped(mIsFidelityEnabled), + assignColorsToOverlay(overlay, DynamicColors.getAllDynamicColorsMapped(mIsFidelityEnabled), false); // Fixed Colors assignColorsToOverlay(overlay, DynamicColors.getFixedColorsMapped(mIsFidelityEnabled), diff --git a/packages/SystemUI/tests/src/com/android/systemui/monet/ColorSchemeTest.kt b/packages/SystemUI/tests/src/com/android/systemui/monet/ColorSchemeTest.kt deleted file mode 100644 index 85cc88dd5283..000000000000 --- a/packages/SystemUI/tests/src/com/android/systemui/monet/ColorSchemeTest.kt +++ /dev/null @@ -1,266 +0,0 @@ -/* - * 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.testing.AndroidTestingRunner -import android.util.Log -import android.util.Pair -import androidx.test.filters.SmallTest -import com.android.systemui.SysuiTestCase -import com.android.systemui.theme.DynamicColors -import com.google.ux.material.libmonet.dynamiccolor.DynamicColor -import com.google.ux.material.libmonet.hct.Hct -import com.google.ux.material.libmonet.scheme.SchemeTonalSpot -import java.io.File -import java.io.FileWriter -import java.io.StringWriter -import javax.xml.parsers.DocumentBuilderFactory -import javax.xml.transform.OutputKeys -import javax.xml.transform.TransformerException -import javax.xml.transform.TransformerFactory -import javax.xml.transform.dom.DOMSource -import javax.xml.transform.stream.StreamResult -import kotlin.math.abs -import org.junit.Test -import org.junit.runner.RunWith -import org.w3c.dom.Document -import org.w3c.dom.Element -import org.w3c.dom.Node - -private const val fileHeader = - """ - ~ Copyright (C) 2022 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. -""" - -private fun testName(name: String): String { - return "Auto generated by: atest ColorSchemeTest#$name" -} - -private const val commentRoles = - "Colors used in Android system, from design system. These " + - "values can be overlaid at runtime by OverlayManager RROs." - -private const val commentOverlay = "This value can be overlaid at runtime by OverlayManager RROs." - -private fun commentWhite(paletteName: String): String { - return "Lightest shade of the $paletteName color used by the system. White. $commentOverlay" -} - -private fun commentBlack(paletteName: String): String { - return "Darkest shade of the $paletteName color used by the system. Black. $commentOverlay" -} - -private fun commentShade(paletteName: String, tone: Int): String { - return "Shade of the $paletteName system color at $tone% perceptual luminance (L* in L*a*b* " + - "color space). $commentOverlay" -} - -@SmallTest -@RunWith(AndroidTestingRunner::class) -class ColorSchemeTest : SysuiTestCase() { - private val defaultContrast = 0.0 - private val defaultIsDark = false - private val defaultIsFidelity = false - - @Test - fun generateThemeStyles() { - val document = buildDoc<Any>() - - val themes = document.createElement("themes") - document.appendWithBreak(themes) - - var hue = 0.0 - while (hue < 360) { - val sourceColor = Hct.from(hue, 50.0, 50.0) - val sourceColorHex = sourceColor.toInt().toRGBHex() - - val theme = document.createElement("theme") - theme.setAttribute("color", sourceColorHex) - themes.appendChild(theme) - - for (styleValue in Style.entries) { - if ( - styleValue == Style.CLOCK || - styleValue == Style.CLOCK_VIBRANT || - styleValue == Style.CONTENT - ) { - continue - } - - val style = document.createElement(styleValue.name.lowercase()) - val colorScheme = ColorScheme(sourceColor.toInt(), defaultIsDark, styleValue) - - style.appendChild( - document.createTextNode( - listOf( - colorScheme.accent1, - colorScheme.accent2, - colorScheme.accent3, - colorScheme.neutral1, - colorScheme.neutral2 - ) - .flatMap { a -> listOf(*a.allShades.toTypedArray()) } - .joinToString(",", transform = Int::toRGBHex) - ) - ) - theme.appendChild(style) - } - - hue += 60 - } - - saveFile(document, "current_themes.xml") - } - - @Test - fun generateDefaultValues() { - val document = buildDoc<Any>() - - val resources = document.createElement("resources") - document.appendWithBreak(resources) - - // shade colors - val colorScheme = ColorScheme(GOOGLE_BLUE, defaultIsDark) - arrayOf( - Triple("accent1", "Primary", colorScheme.accent1), - Triple("accent2", "Secondary", colorScheme.accent2), - Triple("accent3", "Tertiary", colorScheme.accent3), - Triple("neutral1", "Neutral", colorScheme.neutral1), - Triple("neutral2", "Secondary Neutral", colorScheme.neutral2) - ) - .forEach { - val (paletteName, readable, palette) = it - palette.allShadesMapped.entries.forEachIndexed { index, (shade, colorValue) -> - val comment = - when (index) { - 0 -> commentWhite(readable) - palette.allShadesMapped.entries.size - 1 -> commentBlack(readable) - else -> commentShade(readable, abs(shade / 10 - 100)) - } - resources.createColorEntry("system_${paletteName}_$shade", colorValue, comment) - } - } - - resources.appendWithBreak(document.createComment(commentRoles), 2) - - fun generateDynamic(pairs: List<Pair<String, DynamicColor>>) { - arrayOf(false, true).forEach { isDark -> - val suffix = if (isDark) "_dark" else "_light" - val dynamicScheme = - SchemeTonalSpot(Hct.fromInt(GOOGLE_BLUE), isDark, defaultContrast) - pairs.forEach { - resources.createColorEntry( - "system_${it.first}$suffix", - it.second.getArgb(dynamicScheme) - ) - } - } - } - - // dynamic colors - generateDynamic(DynamicColors.allDynamicColorsMapped(defaultIsFidelity)) - - // fixed colors - val dynamicScheme = - SchemeTonalSpot(Hct.fromInt(GOOGLE_BLUE), defaultIsDark, defaultContrast) - DynamicColors.getFixedColorsMapped(defaultIsFidelity).forEach { - resources.createColorEntry("system_${it.first}", it.second.getArgb(dynamicScheme)) - } - - resources.appendWithBreak(document.createComment(commentRoles), 2) - - // custom colors - generateDynamic(DynamicColors.getCustomColorsMapped(defaultIsFidelity)) - - saveFile(document, "role_values.xml") - } - - // Helper Functions - - private inline fun <reified T> buildDoc(): Document { - val functionName = T::class.simpleName + "" - val factory = DocumentBuilderFactory.newInstance() - val builder = factory.newDocumentBuilder() - val document = builder.newDocument() - - document.appendWithBreak(document.createComment(fileHeader)) - document.appendWithBreak(document.createComment(testName(functionName))) - - return document - } - - private fun documentToString(document: Document): String { - try { - val transformerFactory = TransformerFactory.newInstance() - val transformer = transformerFactory.newTransformer() - transformer.setOutputProperty(OutputKeys.MEDIA_TYPE, "application/xml") - transformer.setOutputProperty(OutputKeys.METHOD, "xml") - transformer.setOutputProperty(OutputKeys.INDENT, "yes") - transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4") - - val stringWriter = StringWriter() - transformer.transform(DOMSource(document), StreamResult(stringWriter)) - return stringWriter.toString() - } catch (e: TransformerException) { - throw RuntimeException("Error transforming XML", e) - } - } - - private fun saveFile(document: Document, fileName: String) { - val outPath = context.filesDir.path + "/" + fileName - Log.d("ColorSchemeXml", "Artifact $fileName created") - val writer = FileWriter(File(outPath)) - writer.write(documentToString(document)) - writer.close() - } -} - -private fun Element.createColorEntry(name: String, value: Int, comment: String? = null) { - val doc = this.ownerDocument - - if (comment != null) { - this.appendChild(doc.createComment(comment)) - } - - val color = doc.createElement("color") - this.appendChild(color) - - color.setAttribute("name", name) - color.appendChild(doc.createTextNode("#" + value.toRGBHex())) -} - -private fun Node.appendWithBreak(child: Node, lineBreaks: Int = 1): Node { - val doc = if (this is Document) this else this.ownerDocument - val node = doc.createTextNode("\n".repeat(lineBreaks)) - this.appendChild(node) - return this.appendChild(child) -} - -private fun Int.toRGBHex(): String { - return "%06X".format(0xFFFFFF and this) -} 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 a5e7a67b21a2..5ad88ad1f47c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayControllerTest.java @@ -64,6 +64,7 @@ import com.android.systemui.flags.FeatureFlags; import com.android.systemui.flags.Flags; import com.android.systemui.keyguard.WakefulnessLifecycle; import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor; +import com.android.systemui.monet.DynamicColors; import com.android.systemui.monet.Style; import com.android.systemui.settings.UserTracker; import com.android.systemui.statusbar.policy.DeviceProvisionedController; @@ -997,7 +998,7 @@ public class ThemeOverlayControllerTest extends SysuiTestCase { // All fixed colors were added once // All custom dynamic tokens added twice verify(dynamic, times( - DynamicColors.allDynamicColorsMapped(false).size() * 2 + DynamicColors.getAllDynamicColorsMapped(false).size() * 2 + DynamicColors.getFixedColorsMapped(false).size() + DynamicColors.getCustomColorsMapped(false).size() * 2) ).setResourceValue(any(String.class), eq(TYPE_INT_COLOR_ARGB8), anyInt(), eq(null)); |