Merge "Populate colors resources for Material color scheme"
This commit is contained in:
committed by
Android (Google) Code Review
commit
f4cdaad437
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* 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)
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -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 =
|
||||
@@ -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,
|
||||
@@ -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,
|
||||
@@ -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,
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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
|
||||
@@ -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;
|
||||
@@ -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);
|
||||
@@ -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);
|
||||
@@ -388,6 +408,7 @@ public class ThemeOverlayController implements CoreStartable, Dumpable {
|
||||
mUserTracker = userTracker;
|
||||
mResources = resources;
|
||||
mWakefulnessLifecycle = wakefulnessLifecycle;
|
||||
mAccessibilityManager = accessibilityManager;
|
||||
dumpManager.registerDumpable(TAG, this);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
& Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES;
|
||||
|
||||
mColorScheme = new ColorScheme(color, nightMode, style);
|
||||
String name = type == ACCENT ? "accent" : "neutral";
|
||||
|
||||
FabricatedOverlay.Builder overlay =
|
||||
new FabricatedOverlay.Builder("com.android.systemui", name, "android");
|
||||
|
||||
if (type == ACCENT) {
|
||||
assignTonalPaletteToOverlay("accent1", overlay, mColorScheme.getAccent1());
|
||||
assignTonalPaletteToOverlay("accent2", overlay, mColorScheme.getAccent2());
|
||||
assignTonalPaletteToOverlay("accent3", overlay, mColorScheme.getAccent3());
|
||||
} else {
|
||||
assignTonalPaletteToOverlay("neutral1", overlay, mColorScheme.getNeutral1());
|
||||
assignTonalPaletteToOverlay("neutral2", overlay, mColorScheme.getNeutral2());
|
||||
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;
|
||||
}
|
||||
|
||||
return overlay.build();
|
||||
}
|
||||
|
||||
private void assignTonalPaletteToOverlay(String name,
|
||||
FabricatedOverlay.Builder overlay, TonalPalette tonalPalette) {
|
||||
@VisibleForTesting
|
||||
protected boolean isNightMode() {
|
||||
return (mResources.getConfiguration().uiMode
|
||||
& Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
protected FabricatedOverlay newFabricatedOverlay(String name) {
|
||||
return new FabricatedOverlay.Builder("com.android.systemui", name, "android").build();
|
||||
}
|
||||
|
||||
private void createOverlays(int color) {
|
||||
boolean nightMode = isNightMode();
|
||||
mColorScheme = new ColorScheme(color, nightMode, mThemeStyle);
|
||||
mNeutralOverlay = createNeutralOverlay();
|
||||
mSecondaryOverlay = createAccentOverlay();
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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 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 */);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
@@ -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
|
||||
}
|
||||
@@ -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)) {
|
||||
@@ -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,
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
@@ -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,
|
||||
@@ -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,
|
||||
|
||||
@@ -47,8 +47,9 @@ import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.provider.Settings;
|
||||
import android.testing.AndroidTestingRunner;
|
||||
import android.view.accessibility.AccessibilityManager;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
@@ -57,7 +58,6 @@ import com.android.systemui.dump.DumpManager;
|
||||
import com.android.systemui.flags.FeatureFlags;
|
||||
import com.android.systemui.flags.Flags;
|
||||
import com.android.systemui.keyguard.WakefulnessLifecycle;
|
||||
import com.android.systemui.monet.ColorScheme;
|
||||
import com.android.systemui.monet.Style;
|
||||
import com.android.systemui.settings.UserTracker;
|
||||
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
|
||||
@@ -115,6 +115,8 @@ public class ThemeOverlayControllerTest extends SysuiTestCase {
|
||||
private Resources mResources;
|
||||
@Mock
|
||||
private WakefulnessLifecycle mWakefulnessLifecycle;
|
||||
@Mock
|
||||
private AccessibilityManager mAccessibilityManager;
|
||||
@Captor
|
||||
private ArgumentCaptor<BroadcastReceiver> mBroadcastReceiver;
|
||||
@Captor
|
||||
@@ -127,13 +129,13 @@ public class ThemeOverlayControllerTest extends SysuiTestCase {
|
||||
private ArgumentCaptor<UserTracker.Callback> mUserTrackerCallback;
|
||||
@Captor
|
||||
private ArgumentCaptor<ContentObserver> mSettingsObserver;
|
||||
private Style mCurrentStyle;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
when(mFeatureFlags.isEnabled(Flags.MONET)).thenReturn(true);
|
||||
when(mWakefulnessLifecycle.getWakefulness()).thenReturn(WAKEFULNESS_AWAKE);
|
||||
when(mAccessibilityManager.getUiContrast()).thenReturn(0.5f);
|
||||
when(mDeviceProvisionedController.isCurrentUserSetup()).thenReturn(true);
|
||||
when(mResources.getColor(eq(android.R.color.system_accent1_500), any()))
|
||||
.thenReturn(Color.RED);
|
||||
@@ -148,15 +150,19 @@ public class ThemeOverlayControllerTest extends SysuiTestCase {
|
||||
mThemeOverlayController = new ThemeOverlayController(mContext,
|
||||
mBroadcastDispatcher, mBgHandler, mMainExecutor, mBgExecutor, mThemeOverlayApplier,
|
||||
mSecureSettings, mWallpaperManager, mUserManager, mDeviceProvisionedController,
|
||||
mUserTracker, mDumpManager, mFeatureFlags, mResources, mWakefulnessLifecycle) {
|
||||
@Nullable
|
||||
@Override
|
||||
protected FabricatedOverlay getOverlay(int color, int type, Style style) {
|
||||
mUserTracker, mDumpManager, mFeatureFlags, mResources, mWakefulnessLifecycle,
|
||||
mAccessibilityManager) {
|
||||
@VisibleForTesting
|
||||
protected boolean isNightMode() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
protected FabricatedOverlay newFabricatedOverlay(String name) {
|
||||
FabricatedOverlay overlay = mock(FabricatedOverlay.class);
|
||||
when(overlay.getIdentifier())
|
||||
.thenReturn(new OverlayIdentifier(Integer.toHexString(color | 0xff000000)));
|
||||
mCurrentStyle = style;
|
||||
mColorScheme = new ColorScheme(color, false /* nightMode */, style);
|
||||
.thenReturn(new OverlayIdentifier(
|
||||
Integer.toHexString(mColorScheme.getSeed() | 0xff000000)));
|
||||
return overlay;
|
||||
}
|
||||
};
|
||||
@@ -416,7 +422,7 @@ public class ThemeOverlayControllerTest extends SysuiTestCase {
|
||||
|
||||
mSettingsObserver.getValue().onChange(true, null, 0, mUserTracker.getUserId());
|
||||
|
||||
assertThat(mCurrentStyle).isEqualTo(style);
|
||||
assertThat(mThemeOverlayController.mThemeStyle).isEqualTo(style);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -432,7 +438,7 @@ public class ThemeOverlayControllerTest extends SysuiTestCase {
|
||||
|
||||
mSettingsObserver.getValue().onChange(true, null, 0, mUserTracker.getUserId());
|
||||
|
||||
assertThat(mCurrentStyle).isEqualTo(Style.TONAL_SPOT);
|
||||
assertThat(mThemeOverlayController.mThemeStyle).isEqualTo(Style.TONAL_SPOT);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -726,17 +732,20 @@ public class ThemeOverlayControllerTest extends SysuiTestCase {
|
||||
mThemeOverlayController = new ThemeOverlayController(mContext,
|
||||
mBroadcastDispatcher, mBgHandler, executor, executor, mThemeOverlayApplier,
|
||||
mSecureSettings, mWallpaperManager, mUserManager, mDeviceProvisionedController,
|
||||
mUserTracker, mDumpManager, mFeatureFlags, mResources, mWakefulnessLifecycle) {
|
||||
@Nullable
|
||||
@Override
|
||||
protected FabricatedOverlay getOverlay(int color, int type, Style style) {
|
||||
mUserTracker, mDumpManager, mFeatureFlags, mResources, mWakefulnessLifecycle,
|
||||
mAccessibilityManager) {
|
||||
@VisibleForTesting
|
||||
protected boolean isNightMode() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
protected FabricatedOverlay newFabricatedOverlay(String name) {
|
||||
FabricatedOverlay overlay = mock(FabricatedOverlay.class);
|
||||
when(overlay.getIdentifier())
|
||||
.thenReturn(new OverlayIdentifier("com.thebest.livewallpaperapp.ever"));
|
||||
mColorScheme = new ColorScheme(color, false /* nightMode */, style);
|
||||
return overlay;
|
||||
}
|
||||
|
||||
};
|
||||
mThemeOverlayController.start();
|
||||
|
||||
@@ -763,14 +772,19 @@ public class ThemeOverlayControllerTest extends SysuiTestCase {
|
||||
mThemeOverlayController = new ThemeOverlayController(mContext,
|
||||
mBroadcastDispatcher, mBgHandler, executor, executor, mThemeOverlayApplier,
|
||||
mSecureSettings, mWallpaperManager, mUserManager, mDeviceProvisionedController,
|
||||
mUserTracker, mDumpManager, mFeatureFlags, mResources, mWakefulnessLifecycle) {
|
||||
@Nullable
|
||||
@Override
|
||||
protected FabricatedOverlay getOverlay(int color, int type, Style style) {
|
||||
mUserTracker, mDumpManager, mFeatureFlags, mResources, mWakefulnessLifecycle,
|
||||
mAccessibilityManager) {
|
||||
@VisibleForTesting
|
||||
protected boolean isNightMode() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
protected FabricatedOverlay newFabricatedOverlay(String name) {
|
||||
FabricatedOverlay overlay = mock(FabricatedOverlay.class);
|
||||
when(overlay.getIdentifier())
|
||||
.thenReturn(new OverlayIdentifier(Integer.toHexString(color | 0xff000000)));
|
||||
mColorScheme = new ColorScheme(color, false /* nightMode */, style);
|
||||
.thenReturn(new OverlayIdentifier(
|
||||
Integer.toHexString(mColorScheme.getSeed() | 0xff000000)));
|
||||
return overlay;
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user