diff options
| author | 2021-02-11 18:53:39 +0000 | |
|---|---|---|
| committer | 2021-02-11 18:53:39 +0000 | |
| commit | 10baf9c064165c4556c67bf12cff272c92a689d8 (patch) | |
| tree | ad2ac22551efa87b1cd29307fc31023d293a1c2c | |
| parent | 7f2d4b02951f07d104d5aad79bb9f9688d1fbacd (diff) | |
| parent | 4222ef14390d9009e6c2978686eabc241baea268 (diff) | |
Merge "User OverlayIdentifier instead of @ColorInt" into sc-dev
6 files changed, 195 insertions, 247 deletions
diff --git a/packages/SystemUI/res/values/flags.xml b/packages/SystemUI/res/values/flags.xml index 6196e4a6613a..f83965eb7378 100644 --- a/packages/SystemUI/res/values/flags.xml +++ b/packages/SystemUI/res/values/flags.xml @@ -23,6 +23,7 @@ <bool name="flag_notif_updates">false</bool> <bool name="flag_shade_is_opaque">false</bool> + <bool name="flag_monet">false</bool> <!-- b/171917882 --> <bool name="flag_notification_twocolumn">false</bool> diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/FeatureFlags.java b/packages/SystemUI/src/com/android/systemui/statusbar/FeatureFlags.java index 778f813b8d07..862c27907e0f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/FeatureFlags.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/FeatureFlags.java @@ -78,4 +78,8 @@ public class FeatureFlags { public boolean isToastStyleEnabled() { return mFlagReader.isEnabled(R.bool.flag_toast_style); } + + public boolean isMonetEnabled() { + return mFlagReader.isEnabled(R.bool.flag_monet); + } } diff --git a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayApplier.java b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayApplier.java index 78639147a375..3f0141416f0c 100644 --- a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayApplier.java +++ b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayApplier.java @@ -15,11 +15,11 @@ */ package com.android.systemui.theme; +import android.content.om.FabricatedOverlay; import android.content.om.OverlayIdentifier; import android.content.om.OverlayInfo; import android.content.om.OverlayManager; import android.content.om.OverlayManagerTransaction; -import android.os.SystemProperties; import android.os.UserHandle; import android.util.ArrayMap; import android.util.Log; @@ -53,13 +53,6 @@ import java.util.stream.Collectors; public class ThemeOverlayApplier implements Dumpable { private static final String TAG = "ThemeOverlayApplier"; private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); - private static final boolean MONET_ENABLED = SystemProperties - .getBoolean("persist.sysui.monet", false); - - @VisibleForTesting - static final String MONET_ACCENT_COLOR_PACKAGE = "com.android.theme.accentcolor.color"; - @VisibleForTesting - static final String MONET_SYSTEM_PALETTE_PACKAGE = "com.android.theme.systemcolors.color"; @VisibleForTesting static final String ANDROID_PACKAGE = "android"; @@ -68,10 +61,8 @@ public class ThemeOverlayApplier implements Dumpable { @VisibleForTesting static final String SYSUI_PACKAGE = "com.android.systemui"; - @VisibleForTesting static final String OVERLAY_CATEGORY_ACCENT_COLOR = "android.theme.customization.accent_color"; - @VisibleForTesting static final String OVERLAY_CATEGORY_SYSTEM_PALETTE = "android.theme.customization.system_palette"; @VisibleForTesting @@ -120,16 +111,6 @@ public class ThemeOverlayApplier implements Dumpable { OVERLAY_CATEGORY_ICON_ANDROID, OVERLAY_CATEGORY_ICON_SYSUI); - /** - * List of main colors of Monet themes. These are extracted from overlays installed - * on the system. - */ - private final ArrayList<Integer> mMainSystemColors = new ArrayList<>(); - /** - * Same as above, but providing accent colors instead of a system palette. - */ - private final ArrayList<Integer> mAccentColors = new ArrayList<>(); - /* Allowed overlay categories for each target package. */ private final Map<String, Set<String>> mTargetPackageToCategories = new ArrayMap<>(); /* Target package for each overlay category. */ @@ -165,64 +146,17 @@ public class ThemeOverlayApplier implements Dumpable { mCategoryToTargetPackage.put(OVERLAY_CATEGORY_ICON_LAUNCHER, mLauncherPackage); mCategoryToTargetPackage.put(OVERLAY_CATEGORY_ICON_THEME_PICKER, mThemePickerPackage); - collectMonetSystemOverlays(); dumpManager.registerDumpable(TAG, this); } /** - * List of accent colors available as Monet overlays. - */ - List<Integer> getAvailableAccentColors() { - return mAccentColors; - } - - /** - * List of main system colors available as Monet overlays. - */ - List<Integer> getAvailableSystemColors() { - return mMainSystemColors; - } - - private void collectMonetSystemOverlays() { - if (!MONET_ENABLED) { - return; - } - List<OverlayInfo> androidOverlays = mOverlayManager - .getOverlayInfosForTarget(ANDROID_PACKAGE, UserHandle.SYSTEM); - for (OverlayInfo overlayInfo : androidOverlays) { - String packageName = overlayInfo.packageName; - if (DEBUG) { - Log.d(TAG, "Processing overlay " + packageName); - } - if (OVERLAY_CATEGORY_SYSTEM_PALETTE.equals(overlayInfo.category) - && packageName.startsWith(MONET_SYSTEM_PALETTE_PACKAGE)) { - try { - String color = packageName.replace(MONET_SYSTEM_PALETTE_PACKAGE, ""); - mMainSystemColors.add(Integer.parseInt(color, 16)); - } catch (NumberFormatException e) { - Log.w(TAG, "Invalid package name for overlay " + packageName, e); - } - } else if (OVERLAY_CATEGORY_ACCENT_COLOR.equals(overlayInfo.category) - && packageName.startsWith(MONET_ACCENT_COLOR_PACKAGE)) { - try { - String color = packageName.replace(MONET_ACCENT_COLOR_PACKAGE, ""); - mAccentColors.add(Integer.parseInt(color, 16)); - } catch (NumberFormatException e) { - Log.w(TAG, "Invalid package name for overlay " + packageName, e); - } - } else if (DEBUG) { - Log.d(TAG, "Unknown overlay: " + packageName + " category: " - + overlayInfo.category); - } - } - } - - /** * Apply the set of overlay packages to the set of {@code UserHandle}s provided. Overlays that * affect sysui will also be applied to the system user. */ void applyCurrentUserOverlays( - Map<String, String> categoryToPackage, Set<UserHandle> userHandles) { + Map<String, OverlayIdentifier> categoryToPackage, + FabricatedOverlay[] pendingCreation, + Set<UserHandle> userHandles) { // Disable all overlays that have not been specified in the user setting. final Set<String> overlayCategoriesToDisable = new HashSet<>(THEME_CATEGORIES); overlayCategoriesToDisable.removeAll(categoryToPackage.keySet()); @@ -241,11 +175,16 @@ public class ThemeOverlayApplier implements Dumpable { .collect(Collectors.toList()); OverlayManagerTransaction.Builder transaction = getTransactionBuilder(); + if (pendingCreation != null) { + for (FabricatedOverlay overlay : pendingCreation) { + transaction.registerFabricatedOverlay(overlay); + } + } + // Toggle overlays in the order of THEME_CATEGORIES. for (String category : THEME_CATEGORIES) { if (categoryToPackage.containsKey(category)) { - OverlayIdentifier overlayInfo = - new OverlayIdentifier(categoryToPackage.get(category)); + OverlayIdentifier overlayInfo = categoryToPackage.get(category); setEnabled(transaction, overlayInfo, category, userHandles, true); } } @@ -284,7 +223,7 @@ public class ThemeOverlayApplier implements Dumpable { */ @Override public void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter pw, @NonNull String[] args) { - pw.println("mMainSystemColors=" + mMainSystemColors.size()); - pw.println("mAccentColors=" + mAccentColors.size()); + pw.println("mTargetPackageToCategories=" + mTargetPackageToCategories); + pw.println("mCategoryToTargetPackage=" + mCategoryToTargetPackage); } } diff --git a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java index d9f474480bc9..522a42b8d4b4 100644 --- a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java +++ b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java @@ -18,6 +18,7 @@ package com.android.systemui.theme; import static com.android.systemui.theme.ThemeOverlayApplier.OVERLAY_CATEGORY_ACCENT_COLOR; import static com.android.systemui.theme.ThemeOverlayApplier.OVERLAY_CATEGORY_SYSTEM_PALETTE; +import android.annotation.Nullable; import android.app.ActivityManager; import android.app.WallpaperColors; import android.app.WallpaperManager; @@ -25,6 +26,8 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.content.om.FabricatedOverlay; +import android.content.om.OverlayIdentifier; import android.content.pm.UserInfo; import android.database.ContentObserver; import android.graphics.Color; @@ -40,7 +43,6 @@ import android.util.Log; import androidx.annotation.NonNull; import com.android.internal.annotations.VisibleForTesting; -import com.android.internal.graphics.ColorUtils; import com.android.systemui.Dumpable; import com.android.systemui.SystemUI; import com.android.systemui.broadcast.BroadcastDispatcher; @@ -48,6 +50,7 @@ import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.dump.DumpManager; +import com.android.systemui.statusbar.FeatureFlags; import com.android.systemui.statusbar.policy.KeyguardStateController; import com.android.systemui.util.settings.SecureSettings; @@ -59,10 +62,10 @@ import org.json.JSONObject; import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.Collection; -import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.Executor; +import java.util.stream.Collectors; import javax.inject.Inject; @@ -77,9 +80,12 @@ import javax.inject.Inject; */ @SysUISingleton public class ThemeOverlayController extends SystemUI implements Dumpable { - private static final String TAG = "ThemeOverlayController"; + protected static final String TAG = "ThemeOverlayController"; private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); + protected static final int MAIN = 0; + protected static final int ACCENT = 1; + // If lock screen wallpaper colors should also be considered when selecting the theme. // Doing this has performance impact, given that overlays would need to be swapped when // the device unlocks. @@ -95,16 +101,19 @@ public class ThemeOverlayController extends SystemUI implements Dumpable { private final Handler mBgHandler; private final WallpaperManager mWallpaperManager; private final KeyguardStateController mKeyguardStateController; + private final boolean mIsMonetEnabled; private WallpaperColors mLockColors; private WallpaperColors mSystemColors; - // Color extracted from wallpaper, NOT the color used on the overlay + // If fabricated overlays were already created for the current theme. + private boolean mNeedsOverlayCreation; + // Dominant olor extracted from wallpaper, NOT the color used on the overlay protected int mMainWallpaperColor = Color.TRANSPARENT; - // Color extracted from wallpaper, NOT the color used on the overlay + // Accent color extracted from wallpaper, NOT the color used on the overlay protected int mWallpaperAccentColor = Color.TRANSPARENT; - // Main system color that maps to an overlay color - private int mSystemOverlayColor = Color.TRANSPARENT; - // Accent color that maps to an overlay color - private int mAccentOverlayColor = Color.TRANSPARENT; + // System colors overlay + private FabricatedOverlay mSystemOverlay; + // Accent colors overlay + private FabricatedOverlay mAccentOverlay; @Inject public ThemeOverlayController(Context context, BroadcastDispatcher broadcastDispatcher, @@ -112,9 +121,10 @@ public class ThemeOverlayController extends SystemUI implements Dumpable { @Background Executor bgExecutor, ThemeOverlayApplier themeOverlayApplier, SecureSettings secureSettings, WallpaperManager wallpaperManager, UserManager userManager, KeyguardStateController keyguardStateController, - DumpManager dumpManager) { + DumpManager dumpManager, FeatureFlags featureFlags) { super(context); + mIsMonetEnabled = featureFlags.isMonetEnabled(); mBroadcastDispatcher = broadcastDispatcher; mUserManager = userManager; mBgExecutor = bgExecutor; @@ -221,20 +231,16 @@ public class ThemeOverlayController extends SystemUI implements Dumpable { mMainWallpaperColor = mainColor; mWallpaperAccentColor = accentCandidate; - // Let's compare these colors to our finite set of overlays, and then pick an overlay. - List<Integer> systemColors = mThemeManager.getAvailableSystemColors(); - List<Integer> accentColors = mThemeManager.getAvailableAccentColors(); - - if (systemColors.size() == 0 || accentColors.size() == 0) { + if (mIsMonetEnabled) { + mSystemOverlay = getOverlay(mMainWallpaperColor, MAIN); + mAccentOverlay = getOverlay(mWallpaperAccentColor, ACCENT); + mNeedsOverlayCreation = true; if (DEBUG) { - Log.d(TAG, "Cannot apply system theme, palettes are unavailable"); + Log.d(TAG, "fetched overlays. system: " + mSystemOverlay + " accent: " + + mAccentOverlay); } - return; } - mSystemOverlayColor = getClosest(systemColors, mMainWallpaperColor); - mAccentOverlayColor = getClosest(accentColors, mWallpaperAccentColor); - updateThemeOverlays(); } @@ -257,42 +263,10 @@ public class ThemeOverlayController extends SystemUI implements Dumpable { } /** - * Given a color and a list of candidates, return the candidate that's the most similar to the - * given color. + * Given a color candidate, return an overlay definition. */ - protected int getClosest(List<Integer> candidates, int color) { - float[] hslMain = new float[3]; - float[] hslCandidate = new float[3]; - - ColorUtils.RGBToHSL(Color.red(color), Color.green(color), Color.blue(color), hslMain); - hslMain[0] /= 360f; - - // To close to white or black, let's use the default system theme instead of - // applying a colorized one. - if (hslMain[2] < 0.05 || hslMain[2] > 0.95) { - return Color.TRANSPARENT; - } - - float minDistance = Float.MAX_VALUE; - int closestColor = Color.TRANSPARENT; - for (int candidate: candidates) { - ColorUtils.RGBToHSL(Color.red(candidate), Color.green(candidate), Color.blue(candidate), - hslCandidate); - hslCandidate[0] /= 360f; - - float sqDistance = squared(hslCandidate[0] - hslMain[0]) - + squared(hslCandidate[1] - hslMain[1]) - + squared(hslCandidate[2] - hslMain[2]); - if (sqDistance < minDistance) { - minDistance = sqDistance; - closestColor = candidate; - } - } - return closestColor; - } - - private static float squared(float f) { - return f * f; + protected @Nullable FabricatedOverlay getOverlay(int color, int type) { + return null; } private void updateThemeOverlays() { @@ -301,20 +275,15 @@ public class ThemeOverlayController extends SystemUI implements Dumpable { Settings.Secure.THEME_CUSTOMIZATION_OVERLAY_PACKAGES, currentUser); if (DEBUG) Log.d(TAG, "updateThemeOverlays. Setting: " + overlayPackageJson); - boolean hasSystemPalette = false; - boolean hasAccentColor = false; - final Map<String, String> categoryToPackage = new ArrayMap<>(); + final Map<String, OverlayIdentifier> categoryToPackage = new ArrayMap<>(); if (!TextUtils.isEmpty(overlayPackageJson)) { try { JSONObject object = new JSONObject(overlayPackageJson); for (String category : ThemeOverlayApplier.THEME_CATEGORIES) { if (object.has(category)) { - if (category.equals(OVERLAY_CATEGORY_ACCENT_COLOR)) { - hasAccentColor = true; - } else if (category.equals(OVERLAY_CATEGORY_SYSTEM_PALETTE)) { - hasSystemPalette = true; - } - categoryToPackage.put(category, object.getString(category)); + OverlayIdentifier identifier = + new OverlayIdentifier(object.getString(category)); + categoryToPackage.put(category, identifier); } } } catch (JSONException e) { @@ -322,17 +291,41 @@ public class ThemeOverlayController extends SystemUI implements Dumpable { } } - // Let's apply the system palette, but only if it was not overridden by the style picker. - if (!hasSystemPalette && mSystemOverlayColor != Color.TRANSPARENT) { - categoryToPackage.put(OVERLAY_CATEGORY_SYSTEM_PALETTE, - ThemeOverlayApplier.MONET_SYSTEM_PALETTE_PACKAGE - + getColorString(mSystemOverlayColor)); + // Let's generate system overlay if the style picker decided to override it. + OverlayIdentifier systemPalette = categoryToPackage.get(OVERLAY_CATEGORY_SYSTEM_PALETTE); + if (mIsMonetEnabled && systemPalette != null && systemPalette.getPackageName() != null) { + try { + int color = Integer.parseInt(systemPalette.getPackageName().toLowerCase(), 16); + mSystemOverlay = getOverlay(color, MAIN); + mNeedsOverlayCreation = true; + categoryToPackage.remove(OVERLAY_CATEGORY_SYSTEM_PALETTE); + } catch (NumberFormatException e) { + Log.w(TAG, "Invalid color definition: " + systemPalette.getPackageName()); + } + } + + // Same for accent color. + OverlayIdentifier accentPalette = categoryToPackage.get(OVERLAY_CATEGORY_ACCENT_COLOR); + if (mIsMonetEnabled && accentPalette != null && accentPalette.getPackageName() != null) { + try { + int color = Integer.parseInt(accentPalette.getPackageName().toLowerCase(), 16); + mAccentOverlay = getOverlay(color, ACCENT); + mNeedsOverlayCreation = true; + categoryToPackage.remove(OVERLAY_CATEGORY_ACCENT_COLOR); + } catch (NumberFormatException e) { + Log.w(TAG, "Invalid color definition: " + accentPalette.getPackageName()); + } + } + + // Compatibility with legacy themes, where full packages were defined, instead of just + // colors. + if (!categoryToPackage.containsKey(OVERLAY_CATEGORY_SYSTEM_PALETTE) + && mSystemOverlay != null) { + categoryToPackage.put(OVERLAY_CATEGORY_SYSTEM_PALETTE, mSystemOverlay.getIdentifier()); } - // Same for the accent color - if (!hasAccentColor && mAccentOverlayColor != Color.TRANSPARENT) { - categoryToPackage.put(OVERLAY_CATEGORY_ACCENT_COLOR, - ThemeOverlayApplier.MONET_ACCENT_COLOR_PACKAGE - + getColorString(mAccentOverlayColor)); + if (!categoryToPackage.containsKey(OVERLAY_CATEGORY_ACCENT_COLOR) + && mAccentOverlay != null) { + categoryToPackage.put(OVERLAY_CATEGORY_ACCENT_COLOR, mAccentOverlay.getIdentifier()); } Set<UserHandle> userHandles = Sets.newHashSet(UserHandle.of(currentUser)); @@ -341,28 +334,31 @@ public class ThemeOverlayController extends SystemUI implements Dumpable { userHandles.add(userInfo.getUserHandle()); } } - mThemeManager.applyCurrentUserOverlays(categoryToPackage, userHandles); - } - - private String getColorString(int color) { - String colorString = Integer.toHexString(color).toUpperCase(); - while (colorString.length() < 6) { - colorString = "0" + colorString; + if (DEBUG) { + Log.d(TAG, "Applying overlays: " + categoryToPackage.keySet().stream() + .map(key -> key + " -> " + categoryToPackage.get(key)).collect( + Collectors.joining(", "))); } - // Remove alpha component - if (colorString.length() > 6) { - colorString = colorString.substring(colorString.length() - 6); + if (mNeedsOverlayCreation) { + mNeedsOverlayCreation = false; + mThemeManager.applyCurrentUserOverlays(categoryToPackage, new FabricatedOverlay[] { + mSystemOverlay, mAccentOverlay + }, userHandles); + } else { + mThemeManager.applyCurrentUserOverlays(categoryToPackage, null, userHandles); } - return colorString; } @Override public void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter pw, @NonNull String[] args) { + pw.println("USE_LOCK_SCREEN_WALLPAPER=" + USE_LOCK_SCREEN_WALLPAPER); pw.println("mLockColors=" + mLockColors); pw.println("mSystemColors=" + mSystemColors); pw.println("mMainWallpaperColor=" + Integer.toHexString(mMainWallpaperColor)); pw.println("mWallpaperAccentColor=" + Integer.toHexString(mWallpaperAccentColor)); - pw.println("mSystemOverlayColor=" + Integer.toHexString(mSystemOverlayColor)); - pw.println("mAccentOverlayColor=" + Integer.toHexString(mAccentOverlayColor)); + pw.println("mSystemOverlayColor=" + mSystemOverlay); + pw.println("mAccentOverlayColor=" + mAccentOverlay); + pw.println("mIsMonetEnabled=" + mIsMonetEnabled); + pw.println("mNeedsOverlayCreation=" + mNeedsOverlayCreation); } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayApplierTest.java b/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayApplierTest.java index 6c99efcc7128..45828c3f73ad 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayApplierTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayApplierTest.java @@ -34,10 +34,12 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.clearInvocations; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import android.content.om.FabricatedOverlay; import android.content.om.OverlayIdentifier; import android.content.om.OverlayInfo; import android.content.om.OverlayManager; @@ -73,11 +75,12 @@ public class ThemeOverlayApplierTest extends SysuiTestCase { private static final String TEST_DISABLED_PREFIX = "com.example."; private static final String TEST_ENABLED_PREFIX = "com.example.enabled."; - private static final Map<String, String> ALL_CATEGORIES_MAP = Maps.newArrayMap(); + private static final Map<String, OverlayIdentifier> ALL_CATEGORIES_MAP = Maps.newArrayMap(); static { for (String category : THEME_CATEGORIES) { - ALL_CATEGORIES_MAP.put(category, TEST_DISABLED_PREFIX + category); + ALL_CATEGORIES_MAP.put(category, + new OverlayIdentifier(TEST_DISABLED_PREFIX + category)); } } @@ -157,27 +160,26 @@ public class ThemeOverlayApplierTest extends SysuiTestCase { @Test public void allCategoriesSpecified_allEnabledExclusively() { - mManager.applyCurrentUserOverlays(ALL_CATEGORIES_MAP, TEST_USER_HANDLES); + mManager.applyCurrentUserOverlays(ALL_CATEGORIES_MAP, null, TEST_USER_HANDLES); verify(mOverlayManager).commit(any()); - for (String overlayPackage : ALL_CATEGORIES_MAP.values()) { - verify(mTransactionBuilder).setEnabled(eq(new OverlayIdentifier(overlayPackage)), - eq(true), eq(TEST_USER.getIdentifier())); + for (OverlayIdentifier overlayPackage : ALL_CATEGORIES_MAP.values()) { + verify(mTransactionBuilder).setEnabled(eq(overlayPackage), eq(true), + eq(TEST_USER.getIdentifier())); } } @Test public void allCategoriesSpecified_sysuiCategoriesAlsoAppliedToSysuiUser() { - mManager.applyCurrentUserOverlays(ALL_CATEGORIES_MAP, TEST_USER_HANDLES); + mManager.applyCurrentUserOverlays(ALL_CATEGORIES_MAP, null, TEST_USER_HANDLES); - for (Map.Entry<String, String> entry : ALL_CATEGORIES_MAP.entrySet()) { + for (Map.Entry<String, OverlayIdentifier> entry : ALL_CATEGORIES_MAP.entrySet()) { if (SYSTEM_USER_CATEGORIES.contains(entry.getKey())) { - verify(mTransactionBuilder).setEnabled(eq(new OverlayIdentifier(entry.getValue())), - eq(true), eq(UserHandle.SYSTEM.getIdentifier())); + verify(mTransactionBuilder).setEnabled(eq(entry.getValue()), eq(true), + eq(UserHandle.SYSTEM.getIdentifier())); } else { verify(mTransactionBuilder, never()).setEnabled( - eq(new OverlayIdentifier(entry.getValue())), - eq(true), eq(UserHandle.SYSTEM.getIdentifier())); + eq(entry.getValue()), eq(true), eq(UserHandle.SYSTEM.getIdentifier())); } } } @@ -187,19 +189,34 @@ public class ThemeOverlayApplierTest extends SysuiTestCase { Set<UserHandle> userHandles = Sets.newHashSet(TEST_USER_HANDLES); UserHandle newUserHandle = UserHandle.of(10); userHandles.add(newUserHandle); - mManager.applyCurrentUserOverlays(ALL_CATEGORIES_MAP, userHandles); + mManager.applyCurrentUserOverlays(ALL_CATEGORIES_MAP, null, userHandles); + + for (OverlayIdentifier overlayPackage : ALL_CATEGORIES_MAP.values()) { + verify(mTransactionBuilder).setEnabled(eq(overlayPackage), eq(true), + eq(TEST_USER.getIdentifier())); + verify(mTransactionBuilder).setEnabled(eq(overlayPackage), eq(true), + eq(newUserHandle.getIdentifier())); + } + } + + @Test + public void applyCurrentUserOverlays_createsPendingOverlays() { + Set<UserHandle> userHandles = Sets.newHashSet(TEST_USER_HANDLES); + UserHandle newUserHandle = UserHandle.of(10); + userHandles.add(newUserHandle); + FabricatedOverlay[] pendingCreation = new FabricatedOverlay[] { + mock(FabricatedOverlay.class) + }; + mManager.applyCurrentUserOverlays(ALL_CATEGORIES_MAP, pendingCreation, userHandles); - for (String overlayPackage : ALL_CATEGORIES_MAP.values()) { - verify(mTransactionBuilder).setEnabled(eq(new OverlayIdentifier(overlayPackage)), - eq(true), eq(TEST_USER.getIdentifier())); - verify(mTransactionBuilder).setEnabled(eq(new OverlayIdentifier(overlayPackage)), - eq(true), eq(newUserHandle.getIdentifier())); + for (FabricatedOverlay overlay : pendingCreation) { + verify(mTransactionBuilder).registerFabricatedOverlay(eq(overlay)); } } @Test public void allCategoriesSpecified_overlayManagerNotQueried() { - mManager.applyCurrentUserOverlays(ALL_CATEGORIES_MAP, TEST_USER_HANDLES); + mManager.applyCurrentUserOverlays(ALL_CATEGORIES_MAP, null, TEST_USER_HANDLES); verify(mOverlayManager, never()) .getOverlayInfosForTarget(anyString(), any(UserHandle.class)); @@ -207,15 +224,15 @@ public class ThemeOverlayApplierTest extends SysuiTestCase { @Test public void someCategoriesSpecified_specifiedEnabled_unspecifiedDisabled() { - Map<String, String> categoryToPackage = new HashMap<>(ALL_CATEGORIES_MAP); + Map<String, OverlayIdentifier> categoryToPackage = new HashMap<>(ALL_CATEGORIES_MAP); categoryToPackage.remove(OVERLAY_CATEGORY_ICON_SETTINGS); categoryToPackage.remove(OVERLAY_CATEGORY_ICON_ANDROID); - mManager.applyCurrentUserOverlays(categoryToPackage, TEST_USER_HANDLES); + mManager.applyCurrentUserOverlays(categoryToPackage, null, TEST_USER_HANDLES); - for (String overlayPackage : categoryToPackage.values()) { - verify(mTransactionBuilder).setEnabled(eq(new OverlayIdentifier(overlayPackage)), - eq(true), eq(TEST_USER.getIdentifier())); + for (OverlayIdentifier overlayPackage : categoryToPackage.values()) { + verify(mTransactionBuilder).setEnabled(eq(overlayPackage), eq(true), + eq(TEST_USER.getIdentifier())); } verify(mTransactionBuilder).setEnabled( eq(new OverlayIdentifier(TEST_ENABLED_PREFIX + OVERLAY_CATEGORY_ICON_SETTINGS)), @@ -227,7 +244,7 @@ public class ThemeOverlayApplierTest extends SysuiTestCase { @Test public void zeroCategoriesSpecified_allDisabled() { - mManager.applyCurrentUserOverlays(Maps.newArrayMap(), TEST_USER_HANDLES); + mManager.applyCurrentUserOverlays(Maps.newArrayMap(), null, TEST_USER_HANDLES); for (String category : THEME_CATEGORIES) { verify(mTransactionBuilder).setEnabled( @@ -238,10 +255,10 @@ public class ThemeOverlayApplierTest extends SysuiTestCase { @Test public void nonThemeCategorySpecified_ignored() { - Map<String, String> categoryToPackage = new HashMap<>(ALL_CATEGORIES_MAP); - categoryToPackage.put("blah.category", "com.example.blah.category"); + Map<String, OverlayIdentifier> categoryToPackage = new HashMap<>(ALL_CATEGORIES_MAP); + categoryToPackage.put("blah.category", new OverlayIdentifier("com.example.blah.category")); - mManager.applyCurrentUserOverlays(categoryToPackage, TEST_USER_HANDLES); + mManager.applyCurrentUserOverlays(categoryToPackage, null, TEST_USER_HANDLES); verify(mTransactionBuilder, never()).setEnabled( eq(new OverlayIdentifier("com.example.blah.category")), eq(false), @@ -253,10 +270,10 @@ public class ThemeOverlayApplierTest extends SysuiTestCase { @Test public void overlayManagerOnlyQueriedForUnspecifiedPackages() { - Map<String, String> categoryToPackage = new HashMap<>(ALL_CATEGORIES_MAP); + Map<String, OverlayIdentifier> categoryToPackage = new HashMap<>(ALL_CATEGORIES_MAP); categoryToPackage.remove(OVERLAY_CATEGORY_ICON_SETTINGS); - mManager.applyCurrentUserOverlays(categoryToPackage, TEST_USER_HANDLES); + mManager.applyCurrentUserOverlays(categoryToPackage, null, TEST_USER_HANDLES); verify(mOverlayManager).getOverlayInfosForTarget(SETTINGS_PACKAGE, UserHandle.SYSTEM); verify(mOverlayManager, never()).getOverlayInfosForTarget(ANDROID_PACKAGE, @@ -270,7 +287,8 @@ public class ThemeOverlayApplierTest extends SysuiTestCase { private static OverlayInfo createOverlayInfo(String packageName, String targetPackageName, String category, boolean enabled) { - return new OverlayInfo(packageName, targetPackageName, null, category, "", - enabled ? OverlayInfo.STATE_ENABLED : OverlayInfo.STATE_DISABLED, 0, 0, false); + return new OverlayInfo(packageName, null, targetPackageName, null, category, "", + enabled ? OverlayInfo.STATE_ENABLED : OverlayInfo.STATE_DISABLED, 0, 0, false, + false); } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayControllerTest.java index d33fac0d3b25..f7f8d03da1c2 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayControllerTest.java @@ -16,8 +16,6 @@ package com.android.systemui.theme; -import static com.android.systemui.theme.ThemeOverlayApplier.MONET_ACCENT_COLOR_PACKAGE; -import static com.android.systemui.theme.ThemeOverlayApplier.MONET_SYSTEM_PALETTE_PACKAGE; import static com.android.systemui.theme.ThemeOverlayApplier.OVERLAY_CATEGORY_ACCENT_COLOR; import static com.android.systemui.theme.ThemeOverlayApplier.OVERLAY_CATEGORY_SYSTEM_PALETTE; import static com.android.systemui.theme.ThemeOverlayController.USE_LOCK_SCREEN_WALLPAPER; @@ -27,12 +25,15 @@ import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; import android.app.WallpaperColors; import android.app.WallpaperManager; +import android.content.om.FabricatedOverlay; +import android.content.om.OverlayIdentifier; import android.graphics.Color; import android.os.Handler; import android.os.UserHandle; @@ -40,11 +41,13 @@ import android.os.UserManager; import android.provider.Settings; import android.testing.AndroidTestingRunner; +import androidx.annotation.Nullable; import androidx.test.filters.SmallTest; import com.android.systemui.SysuiTestCase; import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.dump.DumpManager; +import com.android.systemui.statusbar.FeatureFlags; import com.android.systemui.statusbar.policy.KeyguardStateController; import com.android.systemui.util.settings.SecureSettings; @@ -56,7 +59,6 @@ import org.mockito.Captor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; -import java.util.List; import java.util.Map; import java.util.concurrent.Executor; @@ -85,6 +87,8 @@ public class ThemeOverlayControllerTest extends SysuiTestCase { private KeyguardStateController mKeyguardStateController; @Mock private DumpManager mDumpManager; + @Mock + private FeatureFlags mFeatureFlags; @Captor private ArgumentCaptor<KeyguardStateController.Callback> mKeyguardStateControllerCallback; @Captor @@ -93,10 +97,20 @@ public class ThemeOverlayControllerTest extends SysuiTestCase { @Before public void setup() { MockitoAnnotations.initMocks(this); + when(mFeatureFlags.isMonetEnabled()).thenReturn(true); mThemeOverlayController = new ThemeOverlayController(null /* context */, mBroadcastDispatcher, mBgHandler, mMainExecutor, mBgExecutor, mThemeOverlayApplier, mSecureSettings, mWallpaperManager, mUserManager, mKeyguardStateController, - mDumpManager); + mDumpManager, mFeatureFlags) { + @Nullable + @Override + protected FabricatedOverlay getOverlay(int color, int type) { + FabricatedOverlay overlay = mock(FabricatedOverlay.class); + when(overlay.getIdentifier()) + .thenReturn(new OverlayIdentifier(Integer.toHexString(color | 0xff000000))); + return overlay; + } + }; mThemeOverlayController.start(); if (USE_LOCK_SCREEN_WALLPAPER) { @@ -106,10 +120,6 @@ public class ThemeOverlayControllerTest extends SysuiTestCase { verify(mWallpaperManager).addOnColorsChangedListener(mColorsListener.capture(), eq(null), eq(UserHandle.USER_ALL)); verify(mDumpManager).registerDumpable(any(), any()); - - List<Integer> colorList = List.of(Color.RED, Color.BLUE, 0x0CCCCC, 0x000CCC); - when(mThemeOverlayApplier.getAvailableAccentColors()).thenReturn(colorList); - when(mThemeOverlayApplier.getAvailableSystemColors()).thenReturn(colorList); } @Test @@ -128,17 +138,17 @@ public class ThemeOverlayControllerTest extends SysuiTestCase { WallpaperColors mainColors = new WallpaperColors(Color.valueOf(Color.RED), Color.valueOf(Color.BLUE), null); mColorsListener.getValue().onColorsChanged(mainColors, WallpaperManager.FLAG_SYSTEM); - ArgumentCaptor<Map<String, String>> themeOverlays = ArgumentCaptor.forClass(Map.class); + ArgumentCaptor<Map<String, OverlayIdentifier>> themeOverlays = + ArgumentCaptor.forClass(Map.class); - verify(mThemeOverlayApplier).getAvailableSystemColors(); - verify(mThemeOverlayApplier).getAvailableAccentColors(); - verify(mThemeOverlayApplier).applyCurrentUserOverlays(themeOverlays.capture(), any()); + verify(mThemeOverlayApplier) + .applyCurrentUserOverlays(themeOverlays.capture(), any(), any()); // Assert that we received the colors that we were expecting assertThat(themeOverlays.getValue().get(OVERLAY_CATEGORY_SYSTEM_PALETTE)) - .isEqualTo(MONET_SYSTEM_PALETTE_PACKAGE + "FF0000"); + .isEqualTo(new OverlayIdentifier("ffff0000")); assertThat(themeOverlays.getValue().get(OVERLAY_CATEGORY_ACCENT_COLOR)) - .isEqualTo(MONET_ACCENT_COLOR_PACKAGE + "0000FF"); + .isEqualTo(new OverlayIdentifier("ff0000ff")); // Should not ask again if changed to same value mColorsListener.getValue().onColorsChanged(mainColors, WallpaperManager.FLAG_SYSTEM); @@ -146,69 +156,49 @@ public class ThemeOverlayControllerTest extends SysuiTestCase { } @Test - public void onWallpaperColorsChanged_whiteTheme() { - WallpaperColors mainColors = new WallpaperColors(Color.valueOf(Color.WHITE), - Color.valueOf(Color.BLUE), null); - mColorsListener.getValue().onColorsChanged(mainColors, WallpaperManager.FLAG_SYSTEM); - ArgumentCaptor<Map<String, String>> themeOverlays = ArgumentCaptor.forClass(Map.class); - - verify(mThemeOverlayApplier).applyCurrentUserOverlays(themeOverlays.capture(), any()); - - // Assert that we received the colors that we were expecting - assertThat(themeOverlays.getValue().containsKey(OVERLAY_CATEGORY_SYSTEM_PALETTE)).isFalse(); - } - - @Test - public void onWallpaperColorsChanged_blackTheme() { - WallpaperColors mainColors = new WallpaperColors(Color.valueOf(Color.BLACK), + public void onWallpaperColorsChanged_preservesWallpaperPickerTheme() { + // Should ask for a new theme when wallpaper colors change + WallpaperColors mainColors = new WallpaperColors(Color.valueOf(Color.RED), Color.valueOf(Color.BLUE), null); - mColorsListener.getValue().onColorsChanged(mainColors, WallpaperManager.FLAG_SYSTEM); - ArgumentCaptor<Map<String, String>> themeOverlays = ArgumentCaptor.forClass(Map.class); - verify(mThemeOverlayApplier).applyCurrentUserOverlays(themeOverlays.capture(), any()); - - // Assert that we received the colors that we were expecting - assertThat(themeOverlays.getValue().containsKey(OVERLAY_CATEGORY_SYSTEM_PALETTE)).isFalse(); - } + String jsonString = + "{\"android.theme.customization.system_palette\":\"override.package.name\"}"; + when(mSecureSettings.getStringForUser( + eq(Settings.Secure.THEME_CUSTOMIZATION_OVERLAY_PACKAGES), anyInt())) + .thenReturn(jsonString); - @Test - public void onWallpaperColorsChanged_addsLeadingZerosToColors() { - // Should ask for a new theme when wallpaper colors change - WallpaperColors mainColors = new WallpaperColors(Color.valueOf(0x0CCCCC), - Color.valueOf(0x000CCC), null); mColorsListener.getValue().onColorsChanged(mainColors, WallpaperManager.FLAG_SYSTEM); - ArgumentCaptor<Map<String, String>> themeOverlays = ArgumentCaptor.forClass(Map.class); + ArgumentCaptor<Map<String, OverlayIdentifier>> themeOverlays = + ArgumentCaptor.forClass(Map.class); - verify(mThemeOverlayApplier).applyCurrentUserOverlays(themeOverlays.capture(), any()); + verify(mThemeOverlayApplier) + .applyCurrentUserOverlays(themeOverlays.capture(), any(), any()); // Assert that we received the colors that we were expecting assertThat(themeOverlays.getValue().get(OVERLAY_CATEGORY_SYSTEM_PALETTE)) - .isEqualTo(MONET_SYSTEM_PALETTE_PACKAGE + "0CCCCC"); - assertThat(themeOverlays.getValue().get(OVERLAY_CATEGORY_ACCENT_COLOR)) - .isEqualTo(MONET_ACCENT_COLOR_PACKAGE + "000CCC"); + .isEqualTo(new OverlayIdentifier("override.package.name")); } @Test - public void onWallpaperColorsChanged_preservesWallpaperPickerTheme() { - // Should ask for a new theme when wallpaper colors change + public void onWallpaperColorsChanged_parsesColorsFromWallpaperPicker() { WallpaperColors mainColors = new WallpaperColors(Color.valueOf(Color.RED), Color.valueOf(Color.BLUE), null); String jsonString = - "{\"android.theme.customization.system_palette\":\"override.package.name\"}"; + "{\"android.theme.customization.system_palette\":\"00FF00\"}"; when(mSecureSettings.getStringForUser( eq(Settings.Secure.THEME_CUSTOMIZATION_OVERLAY_PACKAGES), anyInt())) .thenReturn(jsonString); mColorsListener.getValue().onColorsChanged(mainColors, WallpaperManager.FLAG_SYSTEM); - ArgumentCaptor<Map<String, String>> themeOverlays = ArgumentCaptor.forClass(Map.class); + ArgumentCaptor<Map<String, OverlayIdentifier>> themeOverlays = + ArgumentCaptor.forClass(Map.class); - verify(mThemeOverlayApplier).getAvailableSystemColors(); - verify(mThemeOverlayApplier).getAvailableAccentColors(); - verify(mThemeOverlayApplier).applyCurrentUserOverlays(themeOverlays.capture(), any()); + verify(mThemeOverlayApplier) + .applyCurrentUserOverlays(themeOverlays.capture(), any(), any()); // Assert that we received the colors that we were expecting assertThat(themeOverlays.getValue().get(OVERLAY_CATEGORY_SYSTEM_PALETTE)) - .isEqualTo("override.package.name"); + .isEqualTo(new OverlayIdentifier("ff00ff00")); } } |