Loading packages/SystemUI/src/com/android/systemui/theme/DynamicColors.kt 0 → 100644 +90 −0 Original line number Diff line number Diff line /* * 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.android.systemui.monet.dynamiccolor.DynamicColor import com.android.systemui.monet.dynamiccolor.MaterialDynamicColors as MDC class DynamicColors { companion object { @JvmField val ALL_DYNAMIC_COLORS_MAPPED: List<Pair<String, DynamicColor>> = 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("error", MDC.error), Pair.create("on_error", MDC.onError), Pair.create("error_container", MDC.errorContainer), Pair.create("on_error_container", MDC.onErrorContainer), Pair.create("primary_fixed", MDC.primaryFixed), Pair.create("primary_fixed_darker", MDC.primaryFixedDarker), 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_darker", MDC.secondaryFixedDarker), 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_darker", MDC.tertiaryFixedDarker), Pair.create("on_tertiary_fixed", MDC.onTertiaryFixed), Pair.create("on_tertiary_fixed_variant", MDC.onTertiaryFixedVariant), 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) ) } } packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayApplier.java +6 −0 Original line number Diff line number Diff line Loading @@ -65,6 +65,8 @@ public class ThemeOverlayApplier implements Dumpable { @VisibleForTesting static final String SYSUI_PACKAGE = "com.android.systemui"; static final String OVERLAY_CATEGORY_DYNAMIC_COLOR = "android.theme.customization.dynamic_color"; static final String OVERLAY_CATEGORY_ACCENT_COLOR = "android.theme.customization.accent_color"; static final String OVERLAY_CATEGORY_SYSTEM_PALETTE = Loading Loading @@ -117,6 +119,7 @@ public class ThemeOverlayApplier implements Dumpable { OVERLAY_CATEGORY_SHAPE, OVERLAY_CATEGORY_FONT, OVERLAY_CATEGORY_ACCENT_COLOR, OVERLAY_CATEGORY_DYNAMIC_COLOR, OVERLAY_CATEGORY_ICON_ANDROID, OVERLAY_CATEGORY_ICON_SYSUI, OVERLAY_CATEGORY_ICON_SETTINGS, Loading @@ -127,6 +130,7 @@ public class ThemeOverlayApplier implements Dumpable { static final Set<String> SYSTEM_USER_CATEGORIES = Sets.newHashSet( OVERLAY_CATEGORY_SYSTEM_PALETTE, OVERLAY_CATEGORY_ACCENT_COLOR, OVERLAY_CATEGORY_DYNAMIC_COLOR, OVERLAY_CATEGORY_FONT, OVERLAY_CATEGORY_SHAPE, OVERLAY_CATEGORY_ICON_ANDROID, Loading @@ -153,6 +157,7 @@ public class ThemeOverlayApplier implements Dumpable { mThemePickerPackage = themePickerPackage; mTargetPackageToCategories.put(ANDROID_PACKAGE, Sets.newHashSet( OVERLAY_CATEGORY_SYSTEM_PALETTE, OVERLAY_CATEGORY_ACCENT_COLOR, OVERLAY_CATEGORY_DYNAMIC_COLOR, OVERLAY_CATEGORY_FONT, OVERLAY_CATEGORY_SHAPE, OVERLAY_CATEGORY_ICON_ANDROID)); mTargetPackageToCategories.put(SYSUI_PACKAGE, Loading @@ -164,6 +169,7 @@ public class ThemeOverlayApplier implements Dumpable { mTargetPackageToCategories.put(mThemePickerPackage, Sets.newHashSet(OVERLAY_CATEGORY_ICON_THEME_PICKER)); mCategoryToTargetPackage.put(OVERLAY_CATEGORY_ACCENT_COLOR, ANDROID_PACKAGE); mCategoryToTargetPackage.put(OVERLAY_CATEGORY_DYNAMIC_COLOR, ANDROID_PACKAGE); mCategoryToTargetPackage.put(OVERLAY_CATEGORY_FONT, ANDROID_PACKAGE); mCategoryToTargetPackage.put(OVERLAY_CATEGORY_SHAPE, ANDROID_PACKAGE); mCategoryToTargetPackage.put(OVERLAY_CATEGORY_ICON_ANDROID, ANDROID_PACKAGE); Loading packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java +132 −43 Original line number Diff line number Diff line Loading @@ -15,11 +15,14 @@ */ package com.android.systemui.theme; import static android.util.TypedValue.TYPE_INT_COLOR_ARGB8; import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_ASLEEP; import static com.android.systemui.theme.ThemeOverlayApplier.COLOR_SOURCE_HOME; import static com.android.systemui.theme.ThemeOverlayApplier.COLOR_SOURCE_LOCK; import static com.android.systemui.theme.ThemeOverlayApplier.COLOR_SOURCE_PRESET; import static com.android.systemui.theme.ThemeOverlayApplier.OVERLAY_CATEGORY_ACCENT_COLOR; import static com.android.systemui.theme.ThemeOverlayApplier.OVERLAY_CATEGORY_DYNAMIC_COLOR; import static com.android.systemui.theme.ThemeOverlayApplier.OVERLAY_CATEGORY_SYSTEM_PALETTE; import static com.android.systemui.theme.ThemeOverlayApplier.OVERLAY_COLOR_BOTH; import static com.android.systemui.theme.ThemeOverlayApplier.OVERLAY_COLOR_INDEX; Loading Loading @@ -51,7 +54,7 @@ import android.util.ArraySet; import android.util.Log; import android.util.SparseArray; import android.util.SparseIntArray; import android.util.TypedValue; import android.view.accessibility.AccessibilityManager; import androidx.annotation.NonNull; import androidx.annotation.VisibleForTesting; Loading @@ -70,6 +73,16 @@ import com.android.systemui.keyguard.WakefulnessLifecycle; import com.android.systemui.monet.ColorScheme; import com.android.systemui.monet.Style; import com.android.systemui.monet.TonalPalette; import com.android.systemui.monet.dynamiccolor.MaterialDynamicColors; import com.android.systemui.monet.hct.Hct; import com.android.systemui.monet.scheme.DynamicScheme; import com.android.systemui.monet.scheme.SchemeExpressive; import com.android.systemui.monet.scheme.SchemeFruitSalad; import com.android.systemui.monet.scheme.SchemeMonochrome; import com.android.systemui.monet.scheme.SchemeNeutral; import com.android.systemui.monet.scheme.SchemeRainbow; import com.android.systemui.monet.scheme.SchemeTonalSpot; import com.android.systemui.monet.scheme.SchemeVibrant; import com.android.systemui.settings.UserTracker; import com.android.systemui.statusbar.policy.DeviceProvisionedController; import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceProvisionedListener; Loading Loading @@ -105,9 +118,6 @@ public class ThemeOverlayController implements CoreStartable, Dumpable { protected static final String TAG = "ThemeOverlayController"; private static final boolean DEBUG = true; protected static final int NEUTRAL = 0; protected static final int ACCENT = 1; private final ThemeOverlayApplier mThemeManager; private final UserManager mUserManager; private final BroadcastDispatcher mBroadcastDispatcher; Loading @@ -130,12 +140,17 @@ public class ThemeOverlayController implements CoreStartable, Dumpable { private boolean mNeedsOverlayCreation; // Dominant color extracted from wallpaper, NOT the color used on the overlay protected int mMainWallpaperColor = Color.TRANSPARENT; // UI contrast as reported by AccessibilityManager private float mUiContrast = 0; // Theme variant: Vibrant, Tonal, Expressive, etc private Style mThemeStyle = Style.TONAL_SPOT; @VisibleForTesting protected Style mThemeStyle = Style.TONAL_SPOT; // Accent colors overlay private FabricatedOverlay mSecondaryOverlay; // Neutral system colors overlay private FabricatedOverlay mNeutralOverlay; // Dynamic colors overlay private FabricatedOverlay mDynamicOverlay; // If wallpaper color event will be accepted and change the UI colors. private boolean mAcceptColorEvents = true; // If non-null (per user), colors that were sent to the framework, and processing was deferred Loading @@ -143,6 +158,9 @@ public class ThemeOverlayController implements CoreStartable, Dumpable { private final SparseArray<WallpaperColors> mDeferredWallpaperColors = new SparseArray<>(); private final SparseIntArray mDeferredWallpaperColorsFlags = new SparseIntArray(); private final WakefulnessLifecycle mWakefulnessLifecycle; private final AccessibilityManager mAccessibilityManager; private DynamicScheme mDynamicSchemeDark; private DynamicScheme mDynamicSchemeLight; // Defers changing themes until Setup Wizard is done. private boolean mDeferredThemeEvaluation; Loading Loading @@ -304,6 +322,7 @@ public class ThemeOverlayController implements CoreStartable, Dumpable { mSkipSettingChange = true; if (jsonObject.has(OVERLAY_CATEGORY_ACCENT_COLOR) || jsonObject.has( OVERLAY_CATEGORY_SYSTEM_PALETTE)) { jsonObject.remove(OVERLAY_CATEGORY_DYNAMIC_COLOR); jsonObject.remove(OVERLAY_CATEGORY_ACCENT_COLOR); jsonObject.remove(OVERLAY_CATEGORY_SYSTEM_PALETTE); jsonObject.remove(OVERLAY_COLOR_INDEX); Loading Loading @@ -372,7 +391,8 @@ public class ThemeOverlayController implements CoreStartable, Dumpable { DumpManager dumpManager, FeatureFlags featureFlags, @Main Resources resources, WakefulnessLifecycle wakefulnessLifecycle) { WakefulnessLifecycle wakefulnessLifecycle, AccessibilityManager accessibilityManager) { mContext = context; mIsMonochromaticEnabled = featureFlags.isEnabled(Flags.MONOCHROMATIC_THEME); mIsMonetEnabled = featureFlags.isEnabled(Flags.MONET); Loading @@ -388,6 +408,7 @@ public class ThemeOverlayController implements CoreStartable, Dumpable { mUserTracker = userTracker; mResources = resources; mWakefulnessLifecycle = wakefulnessLifecycle; mAccessibilityManager = accessibilityManager; dumpManager.registerDumpable(TAG, this); } Loading Loading @@ -424,6 +445,12 @@ public class ThemeOverlayController implements CoreStartable, Dumpable { } }, UserHandle.USER_ALL); mUiContrast = mAccessibilityManager.getUiContrast(); mAccessibilityManager.addUiContrastChangeListener(mMainExecutor, uiContrast -> { mUiContrast = uiContrast; // Force reload so that we update even when the main color has not changed reevaluateSystemTheme(true /* forceReload */); }); if (!mIsMonetEnabled) { return; Loading Loading @@ -496,12 +523,11 @@ public class ThemeOverlayController implements CoreStartable, Dumpable { if (mIsMonetEnabled) { mThemeStyle = fetchThemeStyleFromSetting(); mSecondaryOverlay = getOverlay(mMainWallpaperColor, ACCENT, mThemeStyle); mNeutralOverlay = getOverlay(mMainWallpaperColor, NEUTRAL, mThemeStyle); createOverlays(mMainWallpaperColor); mNeedsOverlayCreation = true; if (DEBUG) { Log.d(TAG, "fetched overlays. accent: " + mSecondaryOverlay + " neutral: " + mNeutralOverlay); + " neutral: " + mNeutralOverlay + " dynamic: " + mDynamicOverlay); } } Loading @@ -519,42 +545,95 @@ public class ThemeOverlayController implements CoreStartable, Dumpable { return ColorScheme.getSeedColor(wallpaperColors); } /** * Given a color candidate, return an overlay definition. */ protected FabricatedOverlay getOverlay(int color, int type, Style style) { boolean nightMode = (mResources.getConfiguration().uiMode private static DynamicScheme dynamicSchemeFromStyle(Style style, int color, boolean isDark, double contrastLevel) { Hct sourceColorHct = Hct.fromInt(color); switch (style) { case EXPRESSIVE: return new SchemeExpressive(sourceColorHct, isDark, contrastLevel); case SPRITZ: return new SchemeNeutral(sourceColorHct, isDark, contrastLevel); case TONAL_SPOT: return new SchemeTonalSpot(sourceColorHct, isDark, contrastLevel); case FRUIT_SALAD: return new SchemeFruitSalad(sourceColorHct, isDark, contrastLevel); case RAINBOW: return new SchemeRainbow(sourceColorHct, isDark, contrastLevel); case VIBRANT: return new SchemeVibrant(sourceColorHct, isDark, contrastLevel); case MONOCHROMATIC: return new SchemeMonochrome(sourceColorHct, isDark, contrastLevel); default: return null; } } @VisibleForTesting protected boolean isNightMode() { return (mResources.getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES; } mColorScheme = new ColorScheme(color, nightMode, style); String name = type == ACCENT ? "accent" : "neutral"; @VisibleForTesting protected FabricatedOverlay newFabricatedOverlay(String name) { return new FabricatedOverlay.Builder("com.android.systemui", name, "android").build(); } FabricatedOverlay.Builder overlay = new FabricatedOverlay.Builder("com.android.systemui", name, "android"); private void createOverlays(int color) { boolean nightMode = isNightMode(); mColorScheme = new ColorScheme(color, nightMode, mThemeStyle); mNeutralOverlay = createNeutralOverlay(); mSecondaryOverlay = createAccentOverlay(); if (type == ACCENT) { assignTonalPaletteToOverlay("accent1", overlay, mColorScheme.getAccent1()); assignTonalPaletteToOverlay("accent2", overlay, mColorScheme.getAccent2()); assignTonalPaletteToOverlay("accent3", overlay, mColorScheme.getAccent3()); } else { mDynamicSchemeDark = dynamicSchemeFromStyle( mThemeStyle, color, true /* isDark */, mUiContrast); mDynamicSchemeLight = dynamicSchemeFromStyle( mThemeStyle, color, false /* isDark */, mUiContrast); mDynamicOverlay = createDynamicOverlay(); } protected FabricatedOverlay createNeutralOverlay() { FabricatedOverlay overlay = newFabricatedOverlay("neutral"); assignTonalPaletteToOverlay("neutral1", overlay, mColorScheme.getNeutral1()); assignTonalPaletteToOverlay("neutral2", overlay, mColorScheme.getNeutral2()); return overlay; } return overlay.build(); protected FabricatedOverlay createAccentOverlay() { FabricatedOverlay overlay = newFabricatedOverlay("accent"); assignTonalPaletteToOverlay("accent1", overlay, mColorScheme.getAccent1()); assignTonalPaletteToOverlay("accent2", overlay, mColorScheme.getAccent2()); assignTonalPaletteToOverlay("accent3", overlay, mColorScheme.getAccent3()); return overlay; } private void assignTonalPaletteToOverlay(String name, FabricatedOverlay.Builder overlay, TonalPalette tonalPalette) { private void assignTonalPaletteToOverlay(String name, FabricatedOverlay overlay, TonalPalette tonalPalette) { String resourcePrefix = "android:color/system_" + name; int colorDataType = TypedValue.TYPE_INT_COLOR_ARGB8; tonalPalette.getAllShadesMapped().forEach((key, value) -> { String resourceName = resourcePrefix + "_" + key; int colorValue = ColorUtils.setAlphaComponent(value, 0xFF); overlay.setResourceValue(resourceName, colorDataType, colorValue); overlay.setResourceValue(resourceName, TYPE_INT_COLOR_ARGB8, colorValue, null /* configuration */); }); } protected FabricatedOverlay createDynamicOverlay() { FabricatedOverlay overlay = newFabricatedOverlay("dynamic"); assignDynamicPaletteToOverlay(overlay, true /* isDark */); assignDynamicPaletteToOverlay(overlay, false /* isDark */); return overlay; } private void assignDynamicPaletteToOverlay(FabricatedOverlay overlay, boolean isDark) { String suffix = isDark ? "dark" : "light"; DynamicScheme scheme = isDark ? mDynamicSchemeDark : mDynamicSchemeLight; DynamicColors.ALL_DYNAMIC_COLORS_MAPPED.forEach(p -> { String resourceName = "android:color/system_" + p.first + "_" + suffix; int colorValue = p.second.getArgb(scheme); overlay.setResourceValue(resourceName, TYPE_INT_COLOR_ARGB8, colorValue, null /* configuration */); }); } Loading @@ -568,16 +647,21 @@ public class ThemeOverlayController implements CoreStartable, Dumpable { for (UserHandle userHandle : allProfiles) { Resources res = userHandle.isSystem() ? mResources : mContext.createContextAsUser(userHandle, 0).getResources(); if (!(res.getColor(android.R.color.system_accent1_500, mContext.getTheme()) Resources.Theme theme = mContext.getTheme(); if (!(res.getColor(android.R.color.system_accent1_500, theme) == mColorScheme.getAccent1().getS500() && res.getColor(android.R.color.system_accent2_500, mContext.getTheme()) && res.getColor(android.R.color.system_accent2_500, theme) == mColorScheme.getAccent2().getS500() && res.getColor(android.R.color.system_accent3_500, mContext.getTheme()) && res.getColor(android.R.color.system_accent3_500, theme) == mColorScheme.getAccent3().getS500() && res.getColor(android.R.color.system_neutral1_500, mContext.getTheme()) && res.getColor(android.R.color.system_neutral1_500, theme) == mColorScheme.getNeutral1().getS500() && res.getColor(android.R.color.system_neutral2_500, mContext.getTheme()) == mColorScheme.getNeutral2().getS500())) { && res.getColor(android.R.color.system_neutral2_500, theme) == mColorScheme.getNeutral2().getS500() && res.getColor(android.R.color.system_primary_container_dark, theme) == MaterialDynamicColors.primaryContainer.getArgb(mDynamicSchemeDark) && res.getColor(android.R.color.system_primary_container_light, theme) == MaterialDynamicColors.primaryContainer.getArgb(mDynamicSchemeLight))) { return false; } } Loading Loading @@ -614,12 +698,11 @@ public class ThemeOverlayController implements CoreStartable, Dumpable { if (!colorString.startsWith("#")) { colorString = "#" + colorString; } int color = Color.parseColor(colorString); mNeutralOverlay = getOverlay(color, NEUTRAL, mThemeStyle); mSecondaryOverlay = getOverlay(color, ACCENT, mThemeStyle); createOverlays(Color.parseColor(colorString)); mNeedsOverlayCreation = true; categoryToPackage.remove(OVERLAY_CATEGORY_SYSTEM_PALETTE); categoryToPackage.remove(OVERLAY_CATEGORY_ACCENT_COLOR); categoryToPackage.remove(OVERLAY_CATEGORY_DYNAMIC_COLOR); } catch (Exception e) { // Color.parseColor doesn't catch any exceptions from the calls it makes Log.w(TAG, "Invalid color definition: " + systemPalette.getPackageName(), e); Loading @@ -631,6 +714,7 @@ public class ThemeOverlayController implements CoreStartable, Dumpable { // fail. categoryToPackage.remove(OVERLAY_CATEGORY_SYSTEM_PALETTE); categoryToPackage.remove(OVERLAY_CATEGORY_ACCENT_COLOR); categoryToPackage.remove(OVERLAY_CATEGORY_DYNAMIC_COLOR); } catch (NumberFormatException e) { // This is a package name. All good, let's continue } Loading @@ -647,6 +731,10 @@ public class ThemeOverlayController implements CoreStartable, Dumpable { && mSecondaryOverlay != null) { categoryToPackage.put(OVERLAY_CATEGORY_ACCENT_COLOR, mSecondaryOverlay.getIdentifier()); } if (!categoryToPackage.containsKey(OVERLAY_CATEGORY_DYNAMIC_COLOR) && mDynamicOverlay != null) { categoryToPackage.put(OVERLAY_CATEGORY_DYNAMIC_COLOR, mDynamicOverlay.getIdentifier()); } Set<UserHandle> managedProfiles = new HashSet<>(); for (UserInfo userInfo : mUserManager.getEnabledProfiles(currentUser)) { Loading @@ -668,7 +756,7 @@ public class ThemeOverlayController implements CoreStartable, Dumpable { if (mNeedsOverlayCreation) { mNeedsOverlayCreation = false; mThemeManager.applyCurrentUserOverlays(categoryToPackage, new FabricatedOverlay[]{ mSecondaryOverlay, mNeutralOverlay mSecondaryOverlay, mNeutralOverlay, mDynamicOverlay }, currentUser, managedProfiles); } else { mThemeManager.applyCurrentUserOverlays(categoryToPackage, null, currentUser, Loading Loading @@ -710,6 +798,7 @@ public class ThemeOverlayController implements CoreStartable, Dumpable { pw.println("mMainWallpaperColor=" + Integer.toHexString(mMainWallpaperColor)); pw.println("mSecondaryOverlay=" + mSecondaryOverlay); pw.println("mNeutralOverlay=" + mNeutralOverlay); pw.println("mDynamicOverlay=" + mDynamicOverlay); pw.println("mIsMonetEnabled=" + mIsMonetEnabled); pw.println("mColorScheme=" + mColorScheme); pw.println("mNeedsOverlayCreation=" + mNeedsOverlayCreation); Loading packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayApplierTest.java +5 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.systemui.theme; import static com.android.systemui.theme.ThemeOverlayApplier.ANDROID_PACKAGE; import static com.android.systemui.theme.ThemeOverlayApplier.OVERLAY_CATEGORY_ACCENT_COLOR; import static com.android.systemui.theme.ThemeOverlayApplier.OVERLAY_CATEGORY_DYNAMIC_COLOR; import static com.android.systemui.theme.ThemeOverlayApplier.OVERLAY_CATEGORY_FONT; import static com.android.systemui.theme.ThemeOverlayApplier.OVERLAY_CATEGORY_ICON_ANDROID; import static com.android.systemui.theme.ThemeOverlayApplier.OVERLAY_CATEGORY_ICON_LAUNCHER; Loading Loading @@ -113,6 +114,8 @@ public class ThemeOverlayApplierTest extends SysuiTestCase { }; when(mOverlayManager.getOverlayInfosForTarget(ANDROID_PACKAGE, UserHandle.SYSTEM)) .thenReturn(Lists.newArrayList( createOverlayInfo(TEST_DISABLED_PREFIX + OVERLAY_CATEGORY_DYNAMIC_COLOR, ANDROID_PACKAGE, OVERLAY_CATEGORY_DYNAMIC_COLOR, false), createOverlayInfo(TEST_DISABLED_PREFIX + OVERLAY_CATEGORY_ACCENT_COLOR, ANDROID_PACKAGE, OVERLAY_CATEGORY_ACCENT_COLOR, false), createOverlayInfo(TEST_DISABLED_PREFIX + OVERLAY_CATEGORY_SYSTEM_PALETTE, Loading @@ -123,6 +126,8 @@ public class ThemeOverlayApplierTest extends SysuiTestCase { ANDROID_PACKAGE, OVERLAY_CATEGORY_SHAPE, false), createOverlayInfo(TEST_DISABLED_PREFIX + OVERLAY_CATEGORY_ICON_ANDROID, ANDROID_PACKAGE, OVERLAY_CATEGORY_ICON_ANDROID, false), createOverlayInfo(TEST_ENABLED_PREFIX + OVERLAY_CATEGORY_DYNAMIC_COLOR, ANDROID_PACKAGE, OVERLAY_CATEGORY_DYNAMIC_COLOR, true), createOverlayInfo(TEST_ENABLED_PREFIX + OVERLAY_CATEGORY_ACCENT_COLOR, ANDROID_PACKAGE, OVERLAY_CATEGORY_ACCENT_COLOR, true), createOverlayInfo(TEST_ENABLED_PREFIX + OVERLAY_CATEGORY_SYSTEM_PALETTE, Loading packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayControllerTest.java +38 −24 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
packages/SystemUI/src/com/android/systemui/theme/DynamicColors.kt 0 → 100644 +90 −0 Original line number Diff line number Diff line /* * 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.android.systemui.monet.dynamiccolor.DynamicColor import com.android.systemui.monet.dynamiccolor.MaterialDynamicColors as MDC class DynamicColors { companion object { @JvmField val ALL_DYNAMIC_COLORS_MAPPED: List<Pair<String, DynamicColor>> = 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("error", MDC.error), Pair.create("on_error", MDC.onError), Pair.create("error_container", MDC.errorContainer), Pair.create("on_error_container", MDC.onErrorContainer), Pair.create("primary_fixed", MDC.primaryFixed), Pair.create("primary_fixed_darker", MDC.primaryFixedDarker), 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_darker", MDC.secondaryFixedDarker), 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_darker", MDC.tertiaryFixedDarker), Pair.create("on_tertiary_fixed", MDC.onTertiaryFixed), Pair.create("on_tertiary_fixed_variant", MDC.onTertiaryFixedVariant), 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) ) } }
packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayApplier.java +6 −0 Original line number Diff line number Diff line Loading @@ -65,6 +65,8 @@ public class ThemeOverlayApplier implements Dumpable { @VisibleForTesting static final String SYSUI_PACKAGE = "com.android.systemui"; static final String OVERLAY_CATEGORY_DYNAMIC_COLOR = "android.theme.customization.dynamic_color"; static final String OVERLAY_CATEGORY_ACCENT_COLOR = "android.theme.customization.accent_color"; static final String OVERLAY_CATEGORY_SYSTEM_PALETTE = Loading Loading @@ -117,6 +119,7 @@ public class ThemeOverlayApplier implements Dumpable { OVERLAY_CATEGORY_SHAPE, OVERLAY_CATEGORY_FONT, OVERLAY_CATEGORY_ACCENT_COLOR, OVERLAY_CATEGORY_DYNAMIC_COLOR, OVERLAY_CATEGORY_ICON_ANDROID, OVERLAY_CATEGORY_ICON_SYSUI, OVERLAY_CATEGORY_ICON_SETTINGS, Loading @@ -127,6 +130,7 @@ public class ThemeOverlayApplier implements Dumpable { static final Set<String> SYSTEM_USER_CATEGORIES = Sets.newHashSet( OVERLAY_CATEGORY_SYSTEM_PALETTE, OVERLAY_CATEGORY_ACCENT_COLOR, OVERLAY_CATEGORY_DYNAMIC_COLOR, OVERLAY_CATEGORY_FONT, OVERLAY_CATEGORY_SHAPE, OVERLAY_CATEGORY_ICON_ANDROID, Loading @@ -153,6 +157,7 @@ public class ThemeOverlayApplier implements Dumpable { mThemePickerPackage = themePickerPackage; mTargetPackageToCategories.put(ANDROID_PACKAGE, Sets.newHashSet( OVERLAY_CATEGORY_SYSTEM_PALETTE, OVERLAY_CATEGORY_ACCENT_COLOR, OVERLAY_CATEGORY_DYNAMIC_COLOR, OVERLAY_CATEGORY_FONT, OVERLAY_CATEGORY_SHAPE, OVERLAY_CATEGORY_ICON_ANDROID)); mTargetPackageToCategories.put(SYSUI_PACKAGE, Loading @@ -164,6 +169,7 @@ public class ThemeOverlayApplier implements Dumpable { mTargetPackageToCategories.put(mThemePickerPackage, Sets.newHashSet(OVERLAY_CATEGORY_ICON_THEME_PICKER)); mCategoryToTargetPackage.put(OVERLAY_CATEGORY_ACCENT_COLOR, ANDROID_PACKAGE); mCategoryToTargetPackage.put(OVERLAY_CATEGORY_DYNAMIC_COLOR, ANDROID_PACKAGE); mCategoryToTargetPackage.put(OVERLAY_CATEGORY_FONT, ANDROID_PACKAGE); mCategoryToTargetPackage.put(OVERLAY_CATEGORY_SHAPE, ANDROID_PACKAGE); mCategoryToTargetPackage.put(OVERLAY_CATEGORY_ICON_ANDROID, ANDROID_PACKAGE); Loading
packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java +132 −43 Original line number Diff line number Diff line Loading @@ -15,11 +15,14 @@ */ package com.android.systemui.theme; import static android.util.TypedValue.TYPE_INT_COLOR_ARGB8; import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_ASLEEP; import static com.android.systemui.theme.ThemeOverlayApplier.COLOR_SOURCE_HOME; import static com.android.systemui.theme.ThemeOverlayApplier.COLOR_SOURCE_LOCK; import static com.android.systemui.theme.ThemeOverlayApplier.COLOR_SOURCE_PRESET; import static com.android.systemui.theme.ThemeOverlayApplier.OVERLAY_CATEGORY_ACCENT_COLOR; import static com.android.systemui.theme.ThemeOverlayApplier.OVERLAY_CATEGORY_DYNAMIC_COLOR; import static com.android.systemui.theme.ThemeOverlayApplier.OVERLAY_CATEGORY_SYSTEM_PALETTE; import static com.android.systemui.theme.ThemeOverlayApplier.OVERLAY_COLOR_BOTH; import static com.android.systemui.theme.ThemeOverlayApplier.OVERLAY_COLOR_INDEX; Loading Loading @@ -51,7 +54,7 @@ import android.util.ArraySet; import android.util.Log; import android.util.SparseArray; import android.util.SparseIntArray; import android.util.TypedValue; import android.view.accessibility.AccessibilityManager; import androidx.annotation.NonNull; import androidx.annotation.VisibleForTesting; Loading @@ -70,6 +73,16 @@ import com.android.systemui.keyguard.WakefulnessLifecycle; import com.android.systemui.monet.ColorScheme; import com.android.systemui.monet.Style; import com.android.systemui.monet.TonalPalette; import com.android.systemui.monet.dynamiccolor.MaterialDynamicColors; import com.android.systemui.monet.hct.Hct; import com.android.systemui.monet.scheme.DynamicScheme; import com.android.systemui.monet.scheme.SchemeExpressive; import com.android.systemui.monet.scheme.SchemeFruitSalad; import com.android.systemui.monet.scheme.SchemeMonochrome; import com.android.systemui.monet.scheme.SchemeNeutral; import com.android.systemui.monet.scheme.SchemeRainbow; import com.android.systemui.monet.scheme.SchemeTonalSpot; import com.android.systemui.monet.scheme.SchemeVibrant; import com.android.systemui.settings.UserTracker; import com.android.systemui.statusbar.policy.DeviceProvisionedController; import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceProvisionedListener; Loading Loading @@ -105,9 +118,6 @@ public class ThemeOverlayController implements CoreStartable, Dumpable { protected static final String TAG = "ThemeOverlayController"; private static final boolean DEBUG = true; protected static final int NEUTRAL = 0; protected static final int ACCENT = 1; private final ThemeOverlayApplier mThemeManager; private final UserManager mUserManager; private final BroadcastDispatcher mBroadcastDispatcher; Loading @@ -130,12 +140,17 @@ public class ThemeOverlayController implements CoreStartable, Dumpable { private boolean mNeedsOverlayCreation; // Dominant color extracted from wallpaper, NOT the color used on the overlay protected int mMainWallpaperColor = Color.TRANSPARENT; // UI contrast as reported by AccessibilityManager private float mUiContrast = 0; // Theme variant: Vibrant, Tonal, Expressive, etc private Style mThemeStyle = Style.TONAL_SPOT; @VisibleForTesting protected Style mThemeStyle = Style.TONAL_SPOT; // Accent colors overlay private FabricatedOverlay mSecondaryOverlay; // Neutral system colors overlay private FabricatedOverlay mNeutralOverlay; // Dynamic colors overlay private FabricatedOverlay mDynamicOverlay; // If wallpaper color event will be accepted and change the UI colors. private boolean mAcceptColorEvents = true; // If non-null (per user), colors that were sent to the framework, and processing was deferred Loading @@ -143,6 +158,9 @@ public class ThemeOverlayController implements CoreStartable, Dumpable { private final SparseArray<WallpaperColors> mDeferredWallpaperColors = new SparseArray<>(); private final SparseIntArray mDeferredWallpaperColorsFlags = new SparseIntArray(); private final WakefulnessLifecycle mWakefulnessLifecycle; private final AccessibilityManager mAccessibilityManager; private DynamicScheme mDynamicSchemeDark; private DynamicScheme mDynamicSchemeLight; // Defers changing themes until Setup Wizard is done. private boolean mDeferredThemeEvaluation; Loading Loading @@ -304,6 +322,7 @@ public class ThemeOverlayController implements CoreStartable, Dumpable { mSkipSettingChange = true; if (jsonObject.has(OVERLAY_CATEGORY_ACCENT_COLOR) || jsonObject.has( OVERLAY_CATEGORY_SYSTEM_PALETTE)) { jsonObject.remove(OVERLAY_CATEGORY_DYNAMIC_COLOR); jsonObject.remove(OVERLAY_CATEGORY_ACCENT_COLOR); jsonObject.remove(OVERLAY_CATEGORY_SYSTEM_PALETTE); jsonObject.remove(OVERLAY_COLOR_INDEX); Loading Loading @@ -372,7 +391,8 @@ public class ThemeOverlayController implements CoreStartable, Dumpable { DumpManager dumpManager, FeatureFlags featureFlags, @Main Resources resources, WakefulnessLifecycle wakefulnessLifecycle) { WakefulnessLifecycle wakefulnessLifecycle, AccessibilityManager accessibilityManager) { mContext = context; mIsMonochromaticEnabled = featureFlags.isEnabled(Flags.MONOCHROMATIC_THEME); mIsMonetEnabled = featureFlags.isEnabled(Flags.MONET); Loading @@ -388,6 +408,7 @@ public class ThemeOverlayController implements CoreStartable, Dumpable { mUserTracker = userTracker; mResources = resources; mWakefulnessLifecycle = wakefulnessLifecycle; mAccessibilityManager = accessibilityManager; dumpManager.registerDumpable(TAG, this); } Loading Loading @@ -424,6 +445,12 @@ public class ThemeOverlayController implements CoreStartable, Dumpable { } }, UserHandle.USER_ALL); mUiContrast = mAccessibilityManager.getUiContrast(); mAccessibilityManager.addUiContrastChangeListener(mMainExecutor, uiContrast -> { mUiContrast = uiContrast; // Force reload so that we update even when the main color has not changed reevaluateSystemTheme(true /* forceReload */); }); if (!mIsMonetEnabled) { return; Loading Loading @@ -496,12 +523,11 @@ public class ThemeOverlayController implements CoreStartable, Dumpable { if (mIsMonetEnabled) { mThemeStyle = fetchThemeStyleFromSetting(); mSecondaryOverlay = getOverlay(mMainWallpaperColor, ACCENT, mThemeStyle); mNeutralOverlay = getOverlay(mMainWallpaperColor, NEUTRAL, mThemeStyle); createOverlays(mMainWallpaperColor); mNeedsOverlayCreation = true; if (DEBUG) { Log.d(TAG, "fetched overlays. accent: " + mSecondaryOverlay + " neutral: " + mNeutralOverlay); + " neutral: " + mNeutralOverlay + " dynamic: " + mDynamicOverlay); } } Loading @@ -519,42 +545,95 @@ public class ThemeOverlayController implements CoreStartable, Dumpable { return ColorScheme.getSeedColor(wallpaperColors); } /** * Given a color candidate, return an overlay definition. */ protected FabricatedOverlay getOverlay(int color, int type, Style style) { boolean nightMode = (mResources.getConfiguration().uiMode private static DynamicScheme dynamicSchemeFromStyle(Style style, int color, boolean isDark, double contrastLevel) { Hct sourceColorHct = Hct.fromInt(color); switch (style) { case EXPRESSIVE: return new SchemeExpressive(sourceColorHct, isDark, contrastLevel); case SPRITZ: return new SchemeNeutral(sourceColorHct, isDark, contrastLevel); case TONAL_SPOT: return new SchemeTonalSpot(sourceColorHct, isDark, contrastLevel); case FRUIT_SALAD: return new SchemeFruitSalad(sourceColorHct, isDark, contrastLevel); case RAINBOW: return new SchemeRainbow(sourceColorHct, isDark, contrastLevel); case VIBRANT: return new SchemeVibrant(sourceColorHct, isDark, contrastLevel); case MONOCHROMATIC: return new SchemeMonochrome(sourceColorHct, isDark, contrastLevel); default: return null; } } @VisibleForTesting protected boolean isNightMode() { return (mResources.getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES; } mColorScheme = new ColorScheme(color, nightMode, style); String name = type == ACCENT ? "accent" : "neutral"; @VisibleForTesting protected FabricatedOverlay newFabricatedOverlay(String name) { return new FabricatedOverlay.Builder("com.android.systemui", name, "android").build(); } FabricatedOverlay.Builder overlay = new FabricatedOverlay.Builder("com.android.systemui", name, "android"); private void createOverlays(int color) { boolean nightMode = isNightMode(); mColorScheme = new ColorScheme(color, nightMode, mThemeStyle); mNeutralOverlay = createNeutralOverlay(); mSecondaryOverlay = createAccentOverlay(); if (type == ACCENT) { assignTonalPaletteToOverlay("accent1", overlay, mColorScheme.getAccent1()); assignTonalPaletteToOverlay("accent2", overlay, mColorScheme.getAccent2()); assignTonalPaletteToOverlay("accent3", overlay, mColorScheme.getAccent3()); } else { mDynamicSchemeDark = dynamicSchemeFromStyle( mThemeStyle, color, true /* isDark */, mUiContrast); mDynamicSchemeLight = dynamicSchemeFromStyle( mThemeStyle, color, false /* isDark */, mUiContrast); mDynamicOverlay = createDynamicOverlay(); } protected FabricatedOverlay createNeutralOverlay() { FabricatedOverlay overlay = newFabricatedOverlay("neutral"); assignTonalPaletteToOverlay("neutral1", overlay, mColorScheme.getNeutral1()); assignTonalPaletteToOverlay("neutral2", overlay, mColorScheme.getNeutral2()); return overlay; } return overlay.build(); protected FabricatedOverlay createAccentOverlay() { FabricatedOverlay overlay = newFabricatedOverlay("accent"); assignTonalPaletteToOverlay("accent1", overlay, mColorScheme.getAccent1()); assignTonalPaletteToOverlay("accent2", overlay, mColorScheme.getAccent2()); assignTonalPaletteToOverlay("accent3", overlay, mColorScheme.getAccent3()); return overlay; } private void assignTonalPaletteToOverlay(String name, FabricatedOverlay.Builder overlay, TonalPalette tonalPalette) { private void assignTonalPaletteToOverlay(String name, FabricatedOverlay overlay, TonalPalette tonalPalette) { String resourcePrefix = "android:color/system_" + name; int colorDataType = TypedValue.TYPE_INT_COLOR_ARGB8; tonalPalette.getAllShadesMapped().forEach((key, value) -> { String resourceName = resourcePrefix + "_" + key; int colorValue = ColorUtils.setAlphaComponent(value, 0xFF); overlay.setResourceValue(resourceName, colorDataType, colorValue); overlay.setResourceValue(resourceName, TYPE_INT_COLOR_ARGB8, colorValue, null /* configuration */); }); } protected FabricatedOverlay createDynamicOverlay() { FabricatedOverlay overlay = newFabricatedOverlay("dynamic"); assignDynamicPaletteToOverlay(overlay, true /* isDark */); assignDynamicPaletteToOverlay(overlay, false /* isDark */); return overlay; } private void assignDynamicPaletteToOverlay(FabricatedOverlay overlay, boolean isDark) { String suffix = isDark ? "dark" : "light"; DynamicScheme scheme = isDark ? mDynamicSchemeDark : mDynamicSchemeLight; DynamicColors.ALL_DYNAMIC_COLORS_MAPPED.forEach(p -> { String resourceName = "android:color/system_" + p.first + "_" + suffix; int colorValue = p.second.getArgb(scheme); overlay.setResourceValue(resourceName, TYPE_INT_COLOR_ARGB8, colorValue, null /* configuration */); }); } Loading @@ -568,16 +647,21 @@ public class ThemeOverlayController implements CoreStartable, Dumpable { for (UserHandle userHandle : allProfiles) { Resources res = userHandle.isSystem() ? mResources : mContext.createContextAsUser(userHandle, 0).getResources(); if (!(res.getColor(android.R.color.system_accent1_500, mContext.getTheme()) Resources.Theme theme = mContext.getTheme(); if (!(res.getColor(android.R.color.system_accent1_500, theme) == mColorScheme.getAccent1().getS500() && res.getColor(android.R.color.system_accent2_500, mContext.getTheme()) && res.getColor(android.R.color.system_accent2_500, theme) == mColorScheme.getAccent2().getS500() && res.getColor(android.R.color.system_accent3_500, mContext.getTheme()) && res.getColor(android.R.color.system_accent3_500, theme) == mColorScheme.getAccent3().getS500() && res.getColor(android.R.color.system_neutral1_500, mContext.getTheme()) && res.getColor(android.R.color.system_neutral1_500, theme) == mColorScheme.getNeutral1().getS500() && res.getColor(android.R.color.system_neutral2_500, mContext.getTheme()) == mColorScheme.getNeutral2().getS500())) { && res.getColor(android.R.color.system_neutral2_500, theme) == mColorScheme.getNeutral2().getS500() && res.getColor(android.R.color.system_primary_container_dark, theme) == MaterialDynamicColors.primaryContainer.getArgb(mDynamicSchemeDark) && res.getColor(android.R.color.system_primary_container_light, theme) == MaterialDynamicColors.primaryContainer.getArgb(mDynamicSchemeLight))) { return false; } } Loading Loading @@ -614,12 +698,11 @@ public class ThemeOverlayController implements CoreStartable, Dumpable { if (!colorString.startsWith("#")) { colorString = "#" + colorString; } int color = Color.parseColor(colorString); mNeutralOverlay = getOverlay(color, NEUTRAL, mThemeStyle); mSecondaryOverlay = getOverlay(color, ACCENT, mThemeStyle); createOverlays(Color.parseColor(colorString)); mNeedsOverlayCreation = true; categoryToPackage.remove(OVERLAY_CATEGORY_SYSTEM_PALETTE); categoryToPackage.remove(OVERLAY_CATEGORY_ACCENT_COLOR); categoryToPackage.remove(OVERLAY_CATEGORY_DYNAMIC_COLOR); } catch (Exception e) { // Color.parseColor doesn't catch any exceptions from the calls it makes Log.w(TAG, "Invalid color definition: " + systemPalette.getPackageName(), e); Loading @@ -631,6 +714,7 @@ public class ThemeOverlayController implements CoreStartable, Dumpable { // fail. categoryToPackage.remove(OVERLAY_CATEGORY_SYSTEM_PALETTE); categoryToPackage.remove(OVERLAY_CATEGORY_ACCENT_COLOR); categoryToPackage.remove(OVERLAY_CATEGORY_DYNAMIC_COLOR); } catch (NumberFormatException e) { // This is a package name. All good, let's continue } Loading @@ -647,6 +731,10 @@ public class ThemeOverlayController implements CoreStartable, Dumpable { && mSecondaryOverlay != null) { categoryToPackage.put(OVERLAY_CATEGORY_ACCENT_COLOR, mSecondaryOverlay.getIdentifier()); } if (!categoryToPackage.containsKey(OVERLAY_CATEGORY_DYNAMIC_COLOR) && mDynamicOverlay != null) { categoryToPackage.put(OVERLAY_CATEGORY_DYNAMIC_COLOR, mDynamicOverlay.getIdentifier()); } Set<UserHandle> managedProfiles = new HashSet<>(); for (UserInfo userInfo : mUserManager.getEnabledProfiles(currentUser)) { Loading @@ -668,7 +756,7 @@ public class ThemeOverlayController implements CoreStartable, Dumpable { if (mNeedsOverlayCreation) { mNeedsOverlayCreation = false; mThemeManager.applyCurrentUserOverlays(categoryToPackage, new FabricatedOverlay[]{ mSecondaryOverlay, mNeutralOverlay mSecondaryOverlay, mNeutralOverlay, mDynamicOverlay }, currentUser, managedProfiles); } else { mThemeManager.applyCurrentUserOverlays(categoryToPackage, null, currentUser, Loading Loading @@ -710,6 +798,7 @@ public class ThemeOverlayController implements CoreStartable, Dumpable { pw.println("mMainWallpaperColor=" + Integer.toHexString(mMainWallpaperColor)); pw.println("mSecondaryOverlay=" + mSecondaryOverlay); pw.println("mNeutralOverlay=" + mNeutralOverlay); pw.println("mDynamicOverlay=" + mDynamicOverlay); pw.println("mIsMonetEnabled=" + mIsMonetEnabled); pw.println("mColorScheme=" + mColorScheme); pw.println("mNeedsOverlayCreation=" + mNeedsOverlayCreation); Loading
packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayApplierTest.java +5 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.systemui.theme; import static com.android.systemui.theme.ThemeOverlayApplier.ANDROID_PACKAGE; import static com.android.systemui.theme.ThemeOverlayApplier.OVERLAY_CATEGORY_ACCENT_COLOR; import static com.android.systemui.theme.ThemeOverlayApplier.OVERLAY_CATEGORY_DYNAMIC_COLOR; import static com.android.systemui.theme.ThemeOverlayApplier.OVERLAY_CATEGORY_FONT; import static com.android.systemui.theme.ThemeOverlayApplier.OVERLAY_CATEGORY_ICON_ANDROID; import static com.android.systemui.theme.ThemeOverlayApplier.OVERLAY_CATEGORY_ICON_LAUNCHER; Loading Loading @@ -113,6 +114,8 @@ public class ThemeOverlayApplierTest extends SysuiTestCase { }; when(mOverlayManager.getOverlayInfosForTarget(ANDROID_PACKAGE, UserHandle.SYSTEM)) .thenReturn(Lists.newArrayList( createOverlayInfo(TEST_DISABLED_PREFIX + OVERLAY_CATEGORY_DYNAMIC_COLOR, ANDROID_PACKAGE, OVERLAY_CATEGORY_DYNAMIC_COLOR, false), createOverlayInfo(TEST_DISABLED_PREFIX + OVERLAY_CATEGORY_ACCENT_COLOR, ANDROID_PACKAGE, OVERLAY_CATEGORY_ACCENT_COLOR, false), createOverlayInfo(TEST_DISABLED_PREFIX + OVERLAY_CATEGORY_SYSTEM_PALETTE, Loading @@ -123,6 +126,8 @@ public class ThemeOverlayApplierTest extends SysuiTestCase { ANDROID_PACKAGE, OVERLAY_CATEGORY_SHAPE, false), createOverlayInfo(TEST_DISABLED_PREFIX + OVERLAY_CATEGORY_ICON_ANDROID, ANDROID_PACKAGE, OVERLAY_CATEGORY_ICON_ANDROID, false), createOverlayInfo(TEST_ENABLED_PREFIX + OVERLAY_CATEGORY_DYNAMIC_COLOR, ANDROID_PACKAGE, OVERLAY_CATEGORY_DYNAMIC_COLOR, true), createOverlayInfo(TEST_ENABLED_PREFIX + OVERLAY_CATEGORY_ACCENT_COLOR, ANDROID_PACKAGE, OVERLAY_CATEGORY_ACCENT_COLOR, true), createOverlayInfo(TEST_ENABLED_PREFIX + OVERLAY_CATEGORY_SYSTEM_PALETTE, Loading
packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayControllerTest.java +38 −24 File changed.Preview size limit exceeded, changes collapsed. Show changes