Loading monet/src/com/android/systemui/monet/ColorScheme.java +18 −12 Original line number Diff line number Diff line Loading @@ -59,6 +59,7 @@ public class ColorScheme { private final TonalPalette mAccent3; private final TonalPalette mNeutral1; private final TonalPalette mNeutral2; private final TonalPalette mError; private final Hct mProposedSeedHct; Loading Loading @@ -96,6 +97,7 @@ public class ColorScheme { mAccent3 = new TonalPalette(mMaterialScheme.tertiaryPalette); mNeutral1 = new TonalPalette(mMaterialScheme.neutralPalette); mNeutral2 = new TonalPalette(mMaterialScheme.neutralVariantPalette); mError = new TonalPalette(mMaterialScheme.errorPalette); } public ColorScheme(@ColorInt int seed, boolean darkTheme) { Loading Loading @@ -162,6 +164,10 @@ public class ColorScheme { return mNeutral2; } public TonalPalette getError() { return mError; } @Override public String toString() { return "ColorScheme {\n" Loading monet/src/com/android/systemui/monet/CustomDynamicColors.java +28 −0 Original line number Diff line number Diff line Loading @@ -22,11 +22,39 @@ import com.google.ux.material.libmonet.dynamiccolor.MaterialDynamicColors; import com.google.ux.material.libmonet.dynamiccolor.ToneDeltaPair; import com.google.ux.material.libmonet.dynamiccolor.TonePolarity; import java.util.function.Supplier; class CustomDynamicColors { private final MaterialDynamicColors mMdc; public final Supplier<DynamicColor>[] allColors; CustomDynamicColors(boolean isExtendedFidelity) { this.mMdc = new MaterialDynamicColors(isExtendedFidelity); allColors = new Supplier[]{ this::widgetBackground, this::clockHour, this::clockMinute, this::clockSecond, this::weatherTemp, this::themeApp, this::onThemeApp, this::themeAppRing, this::themeNotif, this::brandA, this::brandB, this::brandC, this::brandD, this::underSurface, this::shadeActive, this::onShadeActive, this::onShadeActiveVariant, this::shadeInactive, this::onShadeInactive, this::onShadeInactiveVariant, this::shadeDisabled, this::overviewBackground }; } // CLOCK COLORS Loading monet/src/com/android/systemui/monet/DynamicColors.java +96 −84 Original line number Diff line number Diff line Loading @@ -22,7 +22,9 @@ import com.google.ux.material.libmonet.dynamiccolor.DynamicColor; import com.google.ux.material.libmonet.dynamiccolor.MaterialDynamicColors; import java.util.ArrayList; import java.util.Comparator; import java.util.List; import java.util.function.Supplier; public class DynamicColors { Loading @@ -35,55 +37,60 @@ public class DynamicColors { public static List<Pair<String, DynamicColor>> getAllDynamicColorsMapped( boolean isExtendedFidelity) { MaterialDynamicColors mdc = new MaterialDynamicColors(isExtendedFidelity); List<Pair<String, DynamicColor>> list = new ArrayList<>(); list.add(Pair.create("primary_container", mdc.primaryContainer())); list.add(Pair.create("on_primary_container", mdc.onPrimaryContainer())); list.add(Pair.create("primary", mdc.primary())); list.add(Pair.create("on_primary", mdc.onPrimary())); list.add(Pair.create("secondary_container", mdc.secondaryContainer())); list.add(Pair.create("on_secondary_container", mdc.onSecondaryContainer())); list.add(Pair.create("secondary", mdc.secondary())); list.add(Pair.create("on_secondary", mdc.onSecondary())); list.add(Pair.create("tertiary_container", mdc.tertiaryContainer())); list.add(Pair.create("on_tertiary_container", mdc.onTertiaryContainer())); list.add(Pair.create("tertiary", mdc.tertiary())); list.add(Pair.create("on_tertiary", mdc.onTertiary())); list.add(Pair.create("background", mdc.background())); list.add(Pair.create("on_background", mdc.onBackground())); list.add(Pair.create("surface", mdc.surface())); list.add(Pair.create("on_surface", mdc.onSurface())); list.add(Pair.create("surface_container_low", mdc.surfaceContainerLow())); list.add(Pair.create("surface_container_lowest", mdc.surfaceContainerLowest())); list.add(Pair.create("surface_container", mdc.surfaceContainer())); list.add(Pair.create("surface_container_high", mdc.surfaceContainerHigh())); list.add(Pair.create("surface_container_highest", mdc.surfaceContainerHighest())); list.add(Pair.create("surface_bright", mdc.surfaceBright())); list.add(Pair.create("surface_dim", mdc.surfaceDim())); list.add(Pair.create("surface_variant", mdc.surfaceVariant())); list.add(Pair.create("on_surface_variant", mdc.onSurfaceVariant())); list.add(Pair.create("outline", mdc.outline())); list.add(Pair.create("outline_variant", mdc.outlineVariant())); list.add(Pair.create("error", mdc.error())); list.add(Pair.create("on_error", mdc.onError())); list.add(Pair.create("error_container", mdc.errorContainer())); list.add(Pair.create("on_error_container", mdc.onErrorContainer())); list.add(Pair.create("control_activated", mdc.controlActivated())); list.add(Pair.create("control_normal", mdc.controlNormal())); list.add(Pair.create("control_highlight", mdc.controlHighlight())); list.add(Pair.create("text_primary_inverse", mdc.textPrimaryInverse())); list.add(Pair.create("text_secondary_and_tertiary_inverse", mdc.textSecondaryAndTertiaryInverse())); list.add(Pair.create("text_primary_inverse_disable_only", mdc.textPrimaryInverseDisableOnly())); list.add(Pair.create("text_secondary_and_tertiary_inverse_disabled", mdc.textSecondaryAndTertiaryInverseDisabled())); list.add(Pair.create("text_hint_inverse", mdc.textHintInverse())); list.add(Pair.create("palette_key_color_primary", mdc.primaryPaletteKeyColor())); list.add(Pair.create("palette_key_color_secondary", mdc.secondaryPaletteKeyColor())); list.add(Pair.create("palette_key_color_tertiary", mdc.tertiaryPaletteKeyColor())); list.add(Pair.create("palette_key_color_neutral", mdc.neutralPaletteKeyColor())); list.add(Pair.create("palette_key_color_neutral_variant", mdc.neutralVariantPaletteKeyColor())); final Supplier<DynamicColor>[] allColors = new Supplier[]{ mdc::primaryPaletteKeyColor, mdc::secondaryPaletteKeyColor, mdc::tertiaryPaletteKeyColor, mdc::neutralPaletteKeyColor, mdc::neutralVariantPaletteKeyColor, mdc::background, mdc::onBackground, mdc::surface, mdc::surfaceDim, mdc::surfaceBright, mdc::surfaceContainerLowest, mdc::surfaceContainerLow, mdc::surfaceContainer, mdc::surfaceContainerHigh, mdc::surfaceContainerHighest, mdc::onSurface, mdc::surfaceVariant, mdc::onSurfaceVariant, mdc::inverseSurface, mdc::inverseOnSurface, mdc::outline, mdc::outlineVariant, mdc::shadow, mdc::scrim, mdc::surfaceTint, mdc::primary, mdc::onPrimary, mdc::primaryContainer, mdc::onPrimaryContainer, mdc::inversePrimary, mdc::secondary, mdc::onSecondary, mdc::secondaryContainer, mdc::onSecondaryContainer, mdc::tertiary, mdc::onTertiary, mdc::tertiaryContainer, mdc::onTertiaryContainer, mdc::error, mdc::onError, mdc::errorContainer, mdc::onErrorContainer, mdc::controlActivated, mdc::controlNormal, mdc::controlHighlight, mdc::textPrimaryInverse, mdc::textSecondaryAndTertiaryInverse, mdc::textPrimaryInverseDisableOnly, mdc::textSecondaryAndTertiaryInverseDisabled, mdc::textHintInverse }; List<Pair<String, DynamicColor>> list = generateSysUINames(allColors); return list; } Loading @@ -96,19 +103,23 @@ public class DynamicColors { public static List<Pair<String, DynamicColor>> getFixedColorsMapped( boolean isExtendedFidelity) { MaterialDynamicColors mdc = new MaterialDynamicColors(isExtendedFidelity); List<Pair<String, DynamicColor>> list = new ArrayList<>(); list.add(Pair.create("primary_fixed", mdc.primaryFixed())); list.add(Pair.create("primary_fixed_dim", mdc.primaryFixedDim())); list.add(Pair.create("on_primary_fixed", mdc.onPrimaryFixed())); list.add(Pair.create("on_primary_fixed_variant", mdc.onPrimaryFixedVariant())); list.add(Pair.create("secondary_fixed", mdc.secondaryFixed())); list.add(Pair.create("secondary_fixed_dim", mdc.secondaryFixedDim())); list.add(Pair.create("on_secondary_fixed", mdc.onSecondaryFixed())); list.add(Pair.create("on_secondary_fixed_variant", mdc.onSecondaryFixedVariant())); list.add(Pair.create("tertiary_fixed", mdc.tertiaryFixed())); list.add(Pair.create("tertiary_fixed_dim", mdc.tertiaryFixedDim())); list.add(Pair.create("on_tertiary_fixed", mdc.onTertiaryFixed())); list.add(Pair.create("on_tertiary_fixed_variant", mdc.onTertiaryFixedVariant())); final Supplier<DynamicColor>[] allColors = new Supplier[]{ mdc::primaryFixed, mdc::primaryFixedDim, mdc::onPrimaryFixed, mdc::onPrimaryFixedVariant, mdc::secondaryFixed, mdc::secondaryFixedDim, mdc::onSecondaryFixed, mdc::onSecondaryFixedVariant, mdc::tertiaryFixed, mdc::tertiaryFixedDim, mdc::onTertiaryFixed, mdc::onTertiaryFixedVariant }; List<Pair<String, DynamicColor>> list = generateSysUINames(allColors); return list; } Loading @@ -122,29 +133,30 @@ public class DynamicColors { public static List<Pair<String, DynamicColor>> getCustomColorsMapped( boolean isExtendedFidelity) { CustomDynamicColors customMdc = new CustomDynamicColors(isExtendedFidelity); List<Pair<String, DynamicColor>> list = new ArrayList<>(); list.add(Pair.create("widget_background", customMdc.widgetBackground())); list.add(Pair.create("clock_hour", customMdc.clockHour())); list.add(Pair.create("clock_minute", customMdc.clockMinute())); list.add(Pair.create("clock_second", customMdc.weatherTemp())); list.add(Pair.create("theme_app", customMdc.themeApp())); list.add(Pair.create("on_theme_app", customMdc.onThemeApp())); list.add(Pair.create("theme_app_ring", customMdc.themeAppRing())); list.add(Pair.create("theme_notif", customMdc.themeNotif())); list.add(Pair.create("brand_a", customMdc.brandA())); list.add(Pair.create("brand_b", customMdc.brandB())); list.add(Pair.create("brand_c", customMdc.brandC())); list.add(Pair.create("brand_d", customMdc.brandD())); list.add(Pair.create("under_surface", customMdc.underSurface())); list.add(Pair.create("shade_active", customMdc.shadeActive())); list.add(Pair.create("on_shade_active", customMdc.onShadeActive())); list.add(Pair.create("on_shade_active_variant", customMdc.onShadeActiveVariant())); list.add(Pair.create("shade_inactive", customMdc.shadeInactive())); list.add(Pair.create("on_shade_inactive", customMdc.onShadeInactive())); list.add(Pair.create("on_shade_inactive_variant", customMdc.onShadeInactiveVariant())); list.add(Pair.create("shade_disabled", customMdc.shadeDisabled())); list.add(Pair.create("overview_background", customMdc.overviewBackground())); List<Pair<String, DynamicColor>> list = generateSysUINames(customMdc.allColors); return list; } private static List<Pair<String, DynamicColor>> generateSysUINames( Supplier<DynamicColor>[] allColors) { List<Pair<String, DynamicColor>> list = new ArrayList<>(); for (Supplier<DynamicColor> supplier : allColors) { DynamicColor dynamicColor = supplier.get(); String name = dynamicColor.name; // Fix tokens containing `palette_key_color` for SysUI requirements: // In SysUI palette_key_color should come first in the token name; String paletteMark = "palette_key_color"; if (name.contains("_" + paletteMark)) { name = paletteMark + "_" + name.replace("_" + paletteMark, ""); } list.add(new Pair(name, dynamicColor)); } list.sort(Comparator.comparing(pair -> pair.first)); return list; } } monet/tests/com/android/systemui/monet/ColorSchemeTest.kt +166 −14 Original line number Diff line number Diff line Loading @@ -38,6 +38,10 @@ import org.w3c.dom.Document import org.w3c.dom.Element import org.w3c.dom.Node private const val CONTRAST = 0.0 private const val IS_FIDELITY_ENABLED = false private const val fileHeader = """ ~ Copyright (C) 2022 The Android Open Source Project Loading Loading @@ -116,7 +120,8 @@ class ColorSchemeTest { colorScheme.accent2, colorScheme.accent3, colorScheme.neutral1, colorScheme.neutral2 colorScheme.neutral2, colorScheme.error, ) .flatMap { a -> listOf(*a.allShades.toTypedArray()) } .joinToString(",", transform = Int::toRGBHex) Loading @@ -128,7 +133,7 @@ class ColorSchemeTest { hue += 60 } saveFile(document, "current_themes.xml") saveFile(document, "themes.xml") } @Test Loading @@ -145,11 +150,14 @@ class ColorSchemeTest { Triple("accent2", "Secondary", colorScheme.accent2), Triple("accent3", "Tertiary", colorScheme.accent3), Triple("neutral1", "Neutral", colorScheme.neutral1), Triple("neutral2", "Secondary Neutral", colorScheme.neutral2) Triple("neutral2", "Secondary Neutral", colorScheme.neutral2), Triple("error", "Error", colorScheme.error), ) .forEach { val (paletteName, readable, palette) = it palette.allShadesMapped.entries.forEachIndexed { index, (shade, colorValue) -> palette.allShadesMapped.toSortedMap().entries.forEachIndexed { index, (shade, colorValue) -> val comment = when (index) { 0 -> commentWhite(readable) Loading @@ -165,22 +173,145 @@ class ColorSchemeTest { // dynamic colors arrayOf(false, true).forEach { isDark -> val suffix = if (isDark) "_dark" else "_light" val dynamicScheme = SchemeTonalSpot(Hct.fromInt(GOOGLE_BLUE), isDark, 0.5) DynamicColors.getAllDynamicColorsMapped(false).forEach { val dynamicScheme = SchemeTonalSpot(Hct.fromInt(GOOGLE_BLUE), isDark, CONTRAST) DynamicColors.getAllDynamicColorsMapped(IS_FIDELITY_ENABLED).forEach { resources.createColorEntry( "system_${it.first}$suffix", it.second.getArgb(dynamicScheme) it.second.getArgb(dynamicScheme), ) } } // fixed colors val dynamicScheme = SchemeTonalSpot(Hct.fromInt(GOOGLE_BLUE), false, 0.5) DynamicColors.getFixedColorsMapped(false).forEach { val dynamicScheme = SchemeTonalSpot(Hct.fromInt(GOOGLE_BLUE), false, CONTRAST) DynamicColors.getFixedColorsMapped(IS_FIDELITY_ENABLED).forEach { resources.createColorEntry("system_${it.first}", it.second.getArgb(dynamicScheme)) } saveFile(document, "role_values.xml") // custom colors arrayOf(false, true).forEach { isDark -> val suffix = if (isDark) "_dark" else "_light" val dynamicScheme = SchemeTonalSpot(Hct.fromInt(GOOGLE_BLUE), isDark, CONTRAST) DynamicColors.getCustomColorsMapped(IS_FIDELITY_ENABLED).forEach { resources.createColorEntry( "system_${it.first}$suffix", it.second.getArgb(dynamicScheme), ) } } saveFile(document, "colors.xml") } @Test fun generateSymbols() { val document = buildDoc<Any>() val resources = document.createElement("resources") document.appendWithBreak(resources) (DynamicColors.getAllDynamicColorsMapped(IS_FIDELITY_ENABLED) + DynamicColors.getFixedColorsMapped(IS_FIDELITY_ENABLED)) .forEach { val newName = ("material_color_" + it.first).snakeToLowerCamelCase() resources.createEntry( "java-symbol", arrayOf(Pair("name", newName), Pair("type", "color")), null, ) } DynamicColors.getCustomColorsMapped(IS_FIDELITY_ENABLED).forEach { val newName = ("custom_color_" + it.first).snakeToLowerCamelCase() resources.createEntry( "java-symbol", arrayOf(Pair("name", newName), Pair("type", "color")), null, ) } arrayOf("_light", "_dark").forEach { suffix -> DynamicColors.getCustomColorsMapped(IS_FIDELITY_ENABLED).forEach { val newName = "system_" + it.first + suffix resources.createEntry( "java-symbol", arrayOf(Pair("name", newName), Pair("type", "color")), null, ) } } saveFile(document, "symbols.xml") } @Test fun generateDynamicColors() { arrayOf(false, true).forEach { isDark -> val document = buildDoc<Any>() val resources = document.createElement("resources") document.appendWithBreak(resources) (DynamicColors.getAllDynamicColorsMapped(IS_FIDELITY_ENABLED) + DynamicColors.getFixedColorsMapped(IS_FIDELITY_ENABLED)) .forEach { val newName = ("material_color_" + it.first).snakeToLowerCamelCase() val suffix = if (isDark) "_dark" else "_light" val colorValue = "@color/system_" + it.first + if (it.first.contains("fixed")) "" else suffix resources.createColorEntry(newName, colorValue) } val suffix = if (isDark) "_dark" else "_light" DynamicColors.getCustomColorsMapped(IS_FIDELITY_ENABLED).forEach { val newName = ("custom_color_" + it.first).snakeToLowerCamelCase() resources.createColorEntry(newName, "@color/system_" + it.first + suffix) } saveFile(document, "colors_dynamic_$suffix.xml") } } @Test fun generatePublic() { val document = buildDoc<Any>() val resources = document.createElement("resources") val group = document.createElement("staging-public-group") resources.appendChild(group) document.appendWithBreak(resources) val context = InstrumentationRegistry.getInstrumentation().targetContext val res = context.resources val rClass = com.android.internal.R.color::class.java val existingFields = rClass.declaredFields.map { it.name }.toSet() arrayOf("_light", "_dark").forEach { suffix -> DynamicColors.getAllDynamicColorsMapped(IS_FIDELITY_ENABLED).forEach { val name = "system_" + it.first + suffix if (!existingFields.contains(name)) { group.createEntry("public", arrayOf(Pair("name", name)), null) } } } DynamicColors.getFixedColorsMapped(IS_FIDELITY_ENABLED).forEach { val name = "system_${it.first}" if (!existingFields.contains(name)) { group.createEntry("public", arrayOf(Pair("name", name)), null) } } saveFile(document, "public.xml") } // Helper Functions Loading Loading @@ -225,17 +356,33 @@ class ColorSchemeTest { } private fun Element.createColorEntry(name: String, value: Int, comment: String? = null) { this.createColorEntry(name, "#" + value.toRGBHex(), comment) } private fun Element.createColorEntry(name: String, value: String, comment: String? = null) { this.createEntry("color", arrayOf(Pair("name", name)), value, comment) } private fun Element.createEntry( tagName: String, attrs: Array<Pair<String, String>>, value: String?, comment: String? = null, ) { val doc = this.ownerDocument if (comment != null) { this.appendChild(doc.createComment(comment)) } val color = doc.createElement("color") this.appendChild(color) val child = doc.createElement(tagName) this.appendChild(child) attrs.forEach { child.setAttribute(it.first, it.second) } color.setAttribute("name", name) color.appendChild(doc.createTextNode("#" + value.toRGBHex())) if (value !== null) { child.appendChild(doc.createTextNode(value)) } } private fun Node.appendWithBreak(child: Node, lineBreaks: Int = 1): Node { Loading @@ -248,3 +395,8 @@ private fun Node.appendWithBreak(child: Node, lineBreaks: Int = 1): Node { private fun Int.toRGBHex(): String { return "%06X".format(0xFFFFFF and this) } private fun String.snakeToLowerCamelCase(): String { val pattern = "_[a-z]".toRegex() return replace(pattern) { it.value.last().uppercase() } } Loading
monet/src/com/android/systemui/monet/ColorScheme.java +18 −12 Original line number Diff line number Diff line Loading @@ -59,6 +59,7 @@ public class ColorScheme { private final TonalPalette mAccent3; private final TonalPalette mNeutral1; private final TonalPalette mNeutral2; private final TonalPalette mError; private final Hct mProposedSeedHct; Loading Loading @@ -96,6 +97,7 @@ public class ColorScheme { mAccent3 = new TonalPalette(mMaterialScheme.tertiaryPalette); mNeutral1 = new TonalPalette(mMaterialScheme.neutralPalette); mNeutral2 = new TonalPalette(mMaterialScheme.neutralVariantPalette); mError = new TonalPalette(mMaterialScheme.errorPalette); } public ColorScheme(@ColorInt int seed, boolean darkTheme) { Loading Loading @@ -162,6 +164,10 @@ public class ColorScheme { return mNeutral2; } public TonalPalette getError() { return mError; } @Override public String toString() { return "ColorScheme {\n" Loading
monet/src/com/android/systemui/monet/CustomDynamicColors.java +28 −0 Original line number Diff line number Diff line Loading @@ -22,11 +22,39 @@ import com.google.ux.material.libmonet.dynamiccolor.MaterialDynamicColors; import com.google.ux.material.libmonet.dynamiccolor.ToneDeltaPair; import com.google.ux.material.libmonet.dynamiccolor.TonePolarity; import java.util.function.Supplier; class CustomDynamicColors { private final MaterialDynamicColors mMdc; public final Supplier<DynamicColor>[] allColors; CustomDynamicColors(boolean isExtendedFidelity) { this.mMdc = new MaterialDynamicColors(isExtendedFidelity); allColors = new Supplier[]{ this::widgetBackground, this::clockHour, this::clockMinute, this::clockSecond, this::weatherTemp, this::themeApp, this::onThemeApp, this::themeAppRing, this::themeNotif, this::brandA, this::brandB, this::brandC, this::brandD, this::underSurface, this::shadeActive, this::onShadeActive, this::onShadeActiveVariant, this::shadeInactive, this::onShadeInactive, this::onShadeInactiveVariant, this::shadeDisabled, this::overviewBackground }; } // CLOCK COLORS Loading
monet/src/com/android/systemui/monet/DynamicColors.java +96 −84 Original line number Diff line number Diff line Loading @@ -22,7 +22,9 @@ import com.google.ux.material.libmonet.dynamiccolor.DynamicColor; import com.google.ux.material.libmonet.dynamiccolor.MaterialDynamicColors; import java.util.ArrayList; import java.util.Comparator; import java.util.List; import java.util.function.Supplier; public class DynamicColors { Loading @@ -35,55 +37,60 @@ public class DynamicColors { public static List<Pair<String, DynamicColor>> getAllDynamicColorsMapped( boolean isExtendedFidelity) { MaterialDynamicColors mdc = new MaterialDynamicColors(isExtendedFidelity); List<Pair<String, DynamicColor>> list = new ArrayList<>(); list.add(Pair.create("primary_container", mdc.primaryContainer())); list.add(Pair.create("on_primary_container", mdc.onPrimaryContainer())); list.add(Pair.create("primary", mdc.primary())); list.add(Pair.create("on_primary", mdc.onPrimary())); list.add(Pair.create("secondary_container", mdc.secondaryContainer())); list.add(Pair.create("on_secondary_container", mdc.onSecondaryContainer())); list.add(Pair.create("secondary", mdc.secondary())); list.add(Pair.create("on_secondary", mdc.onSecondary())); list.add(Pair.create("tertiary_container", mdc.tertiaryContainer())); list.add(Pair.create("on_tertiary_container", mdc.onTertiaryContainer())); list.add(Pair.create("tertiary", mdc.tertiary())); list.add(Pair.create("on_tertiary", mdc.onTertiary())); list.add(Pair.create("background", mdc.background())); list.add(Pair.create("on_background", mdc.onBackground())); list.add(Pair.create("surface", mdc.surface())); list.add(Pair.create("on_surface", mdc.onSurface())); list.add(Pair.create("surface_container_low", mdc.surfaceContainerLow())); list.add(Pair.create("surface_container_lowest", mdc.surfaceContainerLowest())); list.add(Pair.create("surface_container", mdc.surfaceContainer())); list.add(Pair.create("surface_container_high", mdc.surfaceContainerHigh())); list.add(Pair.create("surface_container_highest", mdc.surfaceContainerHighest())); list.add(Pair.create("surface_bright", mdc.surfaceBright())); list.add(Pair.create("surface_dim", mdc.surfaceDim())); list.add(Pair.create("surface_variant", mdc.surfaceVariant())); list.add(Pair.create("on_surface_variant", mdc.onSurfaceVariant())); list.add(Pair.create("outline", mdc.outline())); list.add(Pair.create("outline_variant", mdc.outlineVariant())); list.add(Pair.create("error", mdc.error())); list.add(Pair.create("on_error", mdc.onError())); list.add(Pair.create("error_container", mdc.errorContainer())); list.add(Pair.create("on_error_container", mdc.onErrorContainer())); list.add(Pair.create("control_activated", mdc.controlActivated())); list.add(Pair.create("control_normal", mdc.controlNormal())); list.add(Pair.create("control_highlight", mdc.controlHighlight())); list.add(Pair.create("text_primary_inverse", mdc.textPrimaryInverse())); list.add(Pair.create("text_secondary_and_tertiary_inverse", mdc.textSecondaryAndTertiaryInverse())); list.add(Pair.create("text_primary_inverse_disable_only", mdc.textPrimaryInverseDisableOnly())); list.add(Pair.create("text_secondary_and_tertiary_inverse_disabled", mdc.textSecondaryAndTertiaryInverseDisabled())); list.add(Pair.create("text_hint_inverse", mdc.textHintInverse())); list.add(Pair.create("palette_key_color_primary", mdc.primaryPaletteKeyColor())); list.add(Pair.create("palette_key_color_secondary", mdc.secondaryPaletteKeyColor())); list.add(Pair.create("palette_key_color_tertiary", mdc.tertiaryPaletteKeyColor())); list.add(Pair.create("palette_key_color_neutral", mdc.neutralPaletteKeyColor())); list.add(Pair.create("palette_key_color_neutral_variant", mdc.neutralVariantPaletteKeyColor())); final Supplier<DynamicColor>[] allColors = new Supplier[]{ mdc::primaryPaletteKeyColor, mdc::secondaryPaletteKeyColor, mdc::tertiaryPaletteKeyColor, mdc::neutralPaletteKeyColor, mdc::neutralVariantPaletteKeyColor, mdc::background, mdc::onBackground, mdc::surface, mdc::surfaceDim, mdc::surfaceBright, mdc::surfaceContainerLowest, mdc::surfaceContainerLow, mdc::surfaceContainer, mdc::surfaceContainerHigh, mdc::surfaceContainerHighest, mdc::onSurface, mdc::surfaceVariant, mdc::onSurfaceVariant, mdc::inverseSurface, mdc::inverseOnSurface, mdc::outline, mdc::outlineVariant, mdc::shadow, mdc::scrim, mdc::surfaceTint, mdc::primary, mdc::onPrimary, mdc::primaryContainer, mdc::onPrimaryContainer, mdc::inversePrimary, mdc::secondary, mdc::onSecondary, mdc::secondaryContainer, mdc::onSecondaryContainer, mdc::tertiary, mdc::onTertiary, mdc::tertiaryContainer, mdc::onTertiaryContainer, mdc::error, mdc::onError, mdc::errorContainer, mdc::onErrorContainer, mdc::controlActivated, mdc::controlNormal, mdc::controlHighlight, mdc::textPrimaryInverse, mdc::textSecondaryAndTertiaryInverse, mdc::textPrimaryInverseDisableOnly, mdc::textSecondaryAndTertiaryInverseDisabled, mdc::textHintInverse }; List<Pair<String, DynamicColor>> list = generateSysUINames(allColors); return list; } Loading @@ -96,19 +103,23 @@ public class DynamicColors { public static List<Pair<String, DynamicColor>> getFixedColorsMapped( boolean isExtendedFidelity) { MaterialDynamicColors mdc = new MaterialDynamicColors(isExtendedFidelity); List<Pair<String, DynamicColor>> list = new ArrayList<>(); list.add(Pair.create("primary_fixed", mdc.primaryFixed())); list.add(Pair.create("primary_fixed_dim", mdc.primaryFixedDim())); list.add(Pair.create("on_primary_fixed", mdc.onPrimaryFixed())); list.add(Pair.create("on_primary_fixed_variant", mdc.onPrimaryFixedVariant())); list.add(Pair.create("secondary_fixed", mdc.secondaryFixed())); list.add(Pair.create("secondary_fixed_dim", mdc.secondaryFixedDim())); list.add(Pair.create("on_secondary_fixed", mdc.onSecondaryFixed())); list.add(Pair.create("on_secondary_fixed_variant", mdc.onSecondaryFixedVariant())); list.add(Pair.create("tertiary_fixed", mdc.tertiaryFixed())); list.add(Pair.create("tertiary_fixed_dim", mdc.tertiaryFixedDim())); list.add(Pair.create("on_tertiary_fixed", mdc.onTertiaryFixed())); list.add(Pair.create("on_tertiary_fixed_variant", mdc.onTertiaryFixedVariant())); final Supplier<DynamicColor>[] allColors = new Supplier[]{ mdc::primaryFixed, mdc::primaryFixedDim, mdc::onPrimaryFixed, mdc::onPrimaryFixedVariant, mdc::secondaryFixed, mdc::secondaryFixedDim, mdc::onSecondaryFixed, mdc::onSecondaryFixedVariant, mdc::tertiaryFixed, mdc::tertiaryFixedDim, mdc::onTertiaryFixed, mdc::onTertiaryFixedVariant }; List<Pair<String, DynamicColor>> list = generateSysUINames(allColors); return list; } Loading @@ -122,29 +133,30 @@ public class DynamicColors { public static List<Pair<String, DynamicColor>> getCustomColorsMapped( boolean isExtendedFidelity) { CustomDynamicColors customMdc = new CustomDynamicColors(isExtendedFidelity); List<Pair<String, DynamicColor>> list = new ArrayList<>(); list.add(Pair.create("widget_background", customMdc.widgetBackground())); list.add(Pair.create("clock_hour", customMdc.clockHour())); list.add(Pair.create("clock_minute", customMdc.clockMinute())); list.add(Pair.create("clock_second", customMdc.weatherTemp())); list.add(Pair.create("theme_app", customMdc.themeApp())); list.add(Pair.create("on_theme_app", customMdc.onThemeApp())); list.add(Pair.create("theme_app_ring", customMdc.themeAppRing())); list.add(Pair.create("theme_notif", customMdc.themeNotif())); list.add(Pair.create("brand_a", customMdc.brandA())); list.add(Pair.create("brand_b", customMdc.brandB())); list.add(Pair.create("brand_c", customMdc.brandC())); list.add(Pair.create("brand_d", customMdc.brandD())); list.add(Pair.create("under_surface", customMdc.underSurface())); list.add(Pair.create("shade_active", customMdc.shadeActive())); list.add(Pair.create("on_shade_active", customMdc.onShadeActive())); list.add(Pair.create("on_shade_active_variant", customMdc.onShadeActiveVariant())); list.add(Pair.create("shade_inactive", customMdc.shadeInactive())); list.add(Pair.create("on_shade_inactive", customMdc.onShadeInactive())); list.add(Pair.create("on_shade_inactive_variant", customMdc.onShadeInactiveVariant())); list.add(Pair.create("shade_disabled", customMdc.shadeDisabled())); list.add(Pair.create("overview_background", customMdc.overviewBackground())); List<Pair<String, DynamicColor>> list = generateSysUINames(customMdc.allColors); return list; } private static List<Pair<String, DynamicColor>> generateSysUINames( Supplier<DynamicColor>[] allColors) { List<Pair<String, DynamicColor>> list = new ArrayList<>(); for (Supplier<DynamicColor> supplier : allColors) { DynamicColor dynamicColor = supplier.get(); String name = dynamicColor.name; // Fix tokens containing `palette_key_color` for SysUI requirements: // In SysUI palette_key_color should come first in the token name; String paletteMark = "palette_key_color"; if (name.contains("_" + paletteMark)) { name = paletteMark + "_" + name.replace("_" + paletteMark, ""); } list.add(new Pair(name, dynamicColor)); } list.sort(Comparator.comparing(pair -> pair.first)); return list; } }
monet/tests/com/android/systemui/monet/ColorSchemeTest.kt +166 −14 Original line number Diff line number Diff line Loading @@ -38,6 +38,10 @@ import org.w3c.dom.Document import org.w3c.dom.Element import org.w3c.dom.Node private const val CONTRAST = 0.0 private const val IS_FIDELITY_ENABLED = false private const val fileHeader = """ ~ Copyright (C) 2022 The Android Open Source Project Loading Loading @@ -116,7 +120,8 @@ class ColorSchemeTest { colorScheme.accent2, colorScheme.accent3, colorScheme.neutral1, colorScheme.neutral2 colorScheme.neutral2, colorScheme.error, ) .flatMap { a -> listOf(*a.allShades.toTypedArray()) } .joinToString(",", transform = Int::toRGBHex) Loading @@ -128,7 +133,7 @@ class ColorSchemeTest { hue += 60 } saveFile(document, "current_themes.xml") saveFile(document, "themes.xml") } @Test Loading @@ -145,11 +150,14 @@ class ColorSchemeTest { Triple("accent2", "Secondary", colorScheme.accent2), Triple("accent3", "Tertiary", colorScheme.accent3), Triple("neutral1", "Neutral", colorScheme.neutral1), Triple("neutral2", "Secondary Neutral", colorScheme.neutral2) Triple("neutral2", "Secondary Neutral", colorScheme.neutral2), Triple("error", "Error", colorScheme.error), ) .forEach { val (paletteName, readable, palette) = it palette.allShadesMapped.entries.forEachIndexed { index, (shade, colorValue) -> palette.allShadesMapped.toSortedMap().entries.forEachIndexed { index, (shade, colorValue) -> val comment = when (index) { 0 -> commentWhite(readable) Loading @@ -165,22 +173,145 @@ class ColorSchemeTest { // dynamic colors arrayOf(false, true).forEach { isDark -> val suffix = if (isDark) "_dark" else "_light" val dynamicScheme = SchemeTonalSpot(Hct.fromInt(GOOGLE_BLUE), isDark, 0.5) DynamicColors.getAllDynamicColorsMapped(false).forEach { val dynamicScheme = SchemeTonalSpot(Hct.fromInt(GOOGLE_BLUE), isDark, CONTRAST) DynamicColors.getAllDynamicColorsMapped(IS_FIDELITY_ENABLED).forEach { resources.createColorEntry( "system_${it.first}$suffix", it.second.getArgb(dynamicScheme) it.second.getArgb(dynamicScheme), ) } } // fixed colors val dynamicScheme = SchemeTonalSpot(Hct.fromInt(GOOGLE_BLUE), false, 0.5) DynamicColors.getFixedColorsMapped(false).forEach { val dynamicScheme = SchemeTonalSpot(Hct.fromInt(GOOGLE_BLUE), false, CONTRAST) DynamicColors.getFixedColorsMapped(IS_FIDELITY_ENABLED).forEach { resources.createColorEntry("system_${it.first}", it.second.getArgb(dynamicScheme)) } saveFile(document, "role_values.xml") // custom colors arrayOf(false, true).forEach { isDark -> val suffix = if (isDark) "_dark" else "_light" val dynamicScheme = SchemeTonalSpot(Hct.fromInt(GOOGLE_BLUE), isDark, CONTRAST) DynamicColors.getCustomColorsMapped(IS_FIDELITY_ENABLED).forEach { resources.createColorEntry( "system_${it.first}$suffix", it.second.getArgb(dynamicScheme), ) } } saveFile(document, "colors.xml") } @Test fun generateSymbols() { val document = buildDoc<Any>() val resources = document.createElement("resources") document.appendWithBreak(resources) (DynamicColors.getAllDynamicColorsMapped(IS_FIDELITY_ENABLED) + DynamicColors.getFixedColorsMapped(IS_FIDELITY_ENABLED)) .forEach { val newName = ("material_color_" + it.first).snakeToLowerCamelCase() resources.createEntry( "java-symbol", arrayOf(Pair("name", newName), Pair("type", "color")), null, ) } DynamicColors.getCustomColorsMapped(IS_FIDELITY_ENABLED).forEach { val newName = ("custom_color_" + it.first).snakeToLowerCamelCase() resources.createEntry( "java-symbol", arrayOf(Pair("name", newName), Pair("type", "color")), null, ) } arrayOf("_light", "_dark").forEach { suffix -> DynamicColors.getCustomColorsMapped(IS_FIDELITY_ENABLED).forEach { val newName = "system_" + it.first + suffix resources.createEntry( "java-symbol", arrayOf(Pair("name", newName), Pair("type", "color")), null, ) } } saveFile(document, "symbols.xml") } @Test fun generateDynamicColors() { arrayOf(false, true).forEach { isDark -> val document = buildDoc<Any>() val resources = document.createElement("resources") document.appendWithBreak(resources) (DynamicColors.getAllDynamicColorsMapped(IS_FIDELITY_ENABLED) + DynamicColors.getFixedColorsMapped(IS_FIDELITY_ENABLED)) .forEach { val newName = ("material_color_" + it.first).snakeToLowerCamelCase() val suffix = if (isDark) "_dark" else "_light" val colorValue = "@color/system_" + it.first + if (it.first.contains("fixed")) "" else suffix resources.createColorEntry(newName, colorValue) } val suffix = if (isDark) "_dark" else "_light" DynamicColors.getCustomColorsMapped(IS_FIDELITY_ENABLED).forEach { val newName = ("custom_color_" + it.first).snakeToLowerCamelCase() resources.createColorEntry(newName, "@color/system_" + it.first + suffix) } saveFile(document, "colors_dynamic_$suffix.xml") } } @Test fun generatePublic() { val document = buildDoc<Any>() val resources = document.createElement("resources") val group = document.createElement("staging-public-group") resources.appendChild(group) document.appendWithBreak(resources) val context = InstrumentationRegistry.getInstrumentation().targetContext val res = context.resources val rClass = com.android.internal.R.color::class.java val existingFields = rClass.declaredFields.map { it.name }.toSet() arrayOf("_light", "_dark").forEach { suffix -> DynamicColors.getAllDynamicColorsMapped(IS_FIDELITY_ENABLED).forEach { val name = "system_" + it.first + suffix if (!existingFields.contains(name)) { group.createEntry("public", arrayOf(Pair("name", name)), null) } } } DynamicColors.getFixedColorsMapped(IS_FIDELITY_ENABLED).forEach { val name = "system_${it.first}" if (!existingFields.contains(name)) { group.createEntry("public", arrayOf(Pair("name", name)), null) } } saveFile(document, "public.xml") } // Helper Functions Loading Loading @@ -225,17 +356,33 @@ class ColorSchemeTest { } private fun Element.createColorEntry(name: String, value: Int, comment: String? = null) { this.createColorEntry(name, "#" + value.toRGBHex(), comment) } private fun Element.createColorEntry(name: String, value: String, comment: String? = null) { this.createEntry("color", arrayOf(Pair("name", name)), value, comment) } private fun Element.createEntry( tagName: String, attrs: Array<Pair<String, String>>, value: String?, comment: String? = null, ) { val doc = this.ownerDocument if (comment != null) { this.appendChild(doc.createComment(comment)) } val color = doc.createElement("color") this.appendChild(color) val child = doc.createElement(tagName) this.appendChild(child) attrs.forEach { child.setAttribute(it.first, it.second) } color.setAttribute("name", name) color.appendChild(doc.createTextNode("#" + value.toRGBHex())) if (value !== null) { child.appendChild(doc.createTextNode(value)) } } private fun Node.appendWithBreak(child: Node, lineBreaks: Int = 1): Node { Loading @@ -248,3 +395,8 @@ private fun Node.appendWithBreak(child: Node, lineBreaks: Int = 1): Node { private fun Int.toRGBHex(): String { return "%06X".format(0xFFFFFF and this) } private fun String.snakeToLowerCamelCase(): String { val pattern = "_[a-z]".toRegex() return replace(pattern) { it.value.last().uppercase() } }