Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d69ab74e authored by Lucas Dupin's avatar Lucas Dupin Committed by Android (Google) Code Review
Browse files

Merge "Skip theme application if it's already current" into tm-dev

parents e6185447 c1716e05
Loading
Loading
Loading
Loading
+48 −18
Original line number Diff line number Diff line
@@ -38,6 +38,7 @@ import android.content.om.FabricatedOverlay;
import android.content.om.OverlayIdentifier;
import android.content.pm.UserInfo;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.database.ContentObserver;
import android.graphics.Color;
import android.net.Uri;
@@ -53,6 +54,7 @@ import android.util.SparseIntArray;
import android.util.TypedValue;

import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;

import com.android.internal.graphics.ColorUtils;
import com.android.systemui.CoreStartable;
@@ -114,10 +116,12 @@ public class ThemeOverlayController extends CoreStartable implements Dumpable {
    private final boolean mIsMonetEnabled;
    private final UserTracker mUserTracker;
    private final DeviceProvisionedController mDeviceProvisionedController;
    private final Resources mResources;
    // Current wallpaper colors associated to a user.
    private final SparseArray<WallpaperColors> mCurrentColors = new SparseArray<>();
    private final WallpaperManager mWallpaperManager;
    private ColorScheme mColorScheme;
    @VisibleForTesting
    protected ColorScheme mColorScheme;
    // If fabricated overlays were already created for the current theme.
    private boolean mNeedsOverlayCreation;
    // Dominant color extracted from wallpaper, NOT the color used on the overlay
@@ -344,7 +348,7 @@ public class ThemeOverlayController extends CoreStartable implements Dumpable {
            SecureSettings secureSettings, WallpaperManager wallpaperManager,
            UserManager userManager, DeviceProvisionedController deviceProvisionedController,
            UserTracker userTracker, DumpManager dumpManager, FeatureFlags featureFlags,
            WakefulnessLifecycle wakefulnessLifecycle) {
            @Main Resources resources, WakefulnessLifecycle wakefulnessLifecycle) {
        super(context);

        mIsMonetEnabled = featureFlags.isEnabled(Flags.MONET);
@@ -358,6 +362,7 @@ public class ThemeOverlayController extends CoreStartable implements Dumpable {
        mSecureSettings = secureSettings;
        mWallpaperManager = wallpaperManager;
        mUserTracker = userTracker;
        mResources = resources;
        mWakefulnessLifecycle = wakefulnessLifecycle;
        dumpManager.registerDumpable(TAG, this);
    }
@@ -466,8 +471,13 @@ public class ThemeOverlayController extends CoreStartable implements Dumpable {
        mMainWallpaperColor = mainColor;

        if (mIsMonetEnabled) {
            mThemeStyle = fetchThemeStyleFromSetting();
            mSecondaryOverlay = getOverlay(mMainWallpaperColor, ACCENT, mThemeStyle);
            mNeutralOverlay = getOverlay(mMainWallpaperColor, NEUTRAL, mThemeStyle);
            if (colorSchemeIsApplied()) {
                Log.d(TAG, "Skipping overlay creation. Theme was already: " + mColorScheme);
                return;
            }
            mNeedsOverlayCreation = true;
            if (DEBUG) {
                Log.d(TAG, "fetched overlays. accent: " + mSecondaryOverlay
@@ -493,7 +503,7 @@ public class ThemeOverlayController extends CoreStartable implements Dumpable {
     * Given a color candidate, return an overlay definition.
     */
    protected @Nullable FabricatedOverlay getOverlay(int color, int type, Style style) {
        boolean nightMode = (mContext.getResources().getConfiguration().uiMode
        boolean nightMode = (mResources.getConfiguration().uiMode
                & Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES;

        mColorScheme = new ColorScheme(color, nightMode, style);
@@ -525,6 +535,23 @@ public class ThemeOverlayController extends CoreStartable implements Dumpable {
        return overlay.build();
    }

    /**
     * Checks if the color scheme in mColorScheme matches the current system palettes.
     */
    private boolean colorSchemeIsApplied() {
        return mResources.getColor(
                android.R.color.system_accent1_500, mContext.getTheme())
                        == mColorScheme.getAccent1().get(6)
                && mResources.getColor(android.R.color.system_accent2_500, mContext.getTheme())
                        == mColorScheme.getAccent2().get(6)
                && mResources.getColor(android.R.color.system_accent3_500, mContext.getTheme())
                        == mColorScheme.getAccent3().get(6)
                && mResources.getColor(android.R.color.system_neutral1_500, mContext.getTheme())
                        == mColorScheme.getNeutral1().get(6)
                && mResources.getColor(android.R.color.system_neutral2_500, mContext.getTheme())
                        == mColorScheme.getNeutral2().get(6);
    }

    private void updateThemeOverlays() {
        final int currentUser = mUserTracker.getUserId();
        final String overlayPackageJson = mSecureSettings.getStringForUser(
@@ -532,7 +559,6 @@ public class ThemeOverlayController extends CoreStartable implements Dumpable {
                currentUser);
        if (DEBUG) Log.d(TAG, "updateThemeOverlays. Setting: " + overlayPackageJson);
        final Map<String, OverlayIdentifier> categoryToPackage = new ArrayMap<>();
        Style newStyle = mThemeStyle;
        if (!TextUtils.isEmpty(overlayPackageJson)) {
            try {
                JSONObject object = new JSONObject(overlayPackageJson);
@@ -543,25 +569,11 @@ public class ThemeOverlayController extends CoreStartable implements Dumpable {
                        categoryToPackage.put(category, identifier);
                    }
                }

                try {
                    newStyle = Style.valueOf(
                            object.getString(ThemeOverlayApplier.OVERLAY_CATEGORY_THEME_STYLE));
                } catch (IllegalArgumentException e) {
                    newStyle = Style.TONAL_SPOT;
                }
            } catch (JSONException e) {
                Log.i(TAG, "Failed to parse THEME_CUSTOMIZATION_OVERLAY_PACKAGES.", e);
            }
        }

        if (mIsMonetEnabled && newStyle != mThemeStyle) {
            mThemeStyle = newStyle;
            mNeutralOverlay = getOverlay(mMainWallpaperColor, NEUTRAL, mThemeStyle);
            mSecondaryOverlay = getOverlay(mMainWallpaperColor, ACCENT, mThemeStyle);
            mNeedsOverlayCreation = true;
        }

        // 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) {
@@ -626,6 +638,24 @@ public class ThemeOverlayController extends CoreStartable implements Dumpable {
        }
    }

    private Style fetchThemeStyleFromSetting() {
        Style style = mThemeStyle;
        final String overlayPackageJson = mSecureSettings.getStringForUser(
                Settings.Secure.THEME_CUSTOMIZATION_OVERLAY_PACKAGES,
                mUserTracker.getUserId());
        if (!TextUtils.isEmpty(overlayPackageJson)) {
            try {
                JSONObject object = new JSONObject(overlayPackageJson);
                style = Style.valueOf(
                        object.getString(ThemeOverlayApplier.OVERLAY_CATEGORY_THEME_STYLE));
            } catch (JSONException | IllegalArgumentException e) {
                Log.i(TAG, "Failed to parse THEME_CUSTOMIZATION_OVERLAY_PACKAGES.", e);
                style = Style.TONAL_SPOT;
            }
        }
        return style;
    }

    @Override
    public void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter pw, @NonNull String[] args) {
        pw.println("mSystemColors=" + mCurrentColors);
+23 −6
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.om.FabricatedOverlay;
import android.content.om.OverlayIdentifier;
import android.content.res.Resources;
import android.database.ContentObserver;
import android.graphics.Color;
import android.os.Handler;
@@ -56,6 +57,7 @@ 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;
@@ -108,6 +110,8 @@ public class ThemeOverlayControllerTest extends SysuiTestCase {
    @Mock
    private FeatureFlags mFeatureFlags;
    @Mock
    private Resources mResources;
    @Mock
    private WakefulnessLifecycle mWakefulnessLifecycle;
    @Captor
    private ArgumentCaptor<BroadcastReceiver> mBroadcastReceiver;
@@ -129,10 +133,20 @@ public class ThemeOverlayControllerTest extends SysuiTestCase {
        when(mFeatureFlags.isEnabled(Flags.MONET)).thenReturn(true);
        when(mWakefulnessLifecycle.getWakefulness()).thenReturn(WAKEFULNESS_AWAKE);
        when(mDeviceProvisionedController.isCurrentUserSetup()).thenReturn(true);
        mThemeOverlayController = new ThemeOverlayController(null /* context */,
        when(mResources.getColor(eq(android.R.color.system_accent1_500), any()))
                .thenReturn(Color.RED);
        when(mResources.getColor(eq(android.R.color.system_accent2_500), any()))
                .thenReturn(Color.GREEN);
        when(mResources.getColor(eq(android.R.color.system_accent3_500), any()))
                .thenReturn(Color.BLUE);
        when(mResources.getColor(eq(android.R.color.system_neutral1_500), any()))
                .thenReturn(Color.YELLOW);
        when(mResources.getColor(eq(android.R.color.system_neutral2_500), any()))
                .thenReturn(Color.BLACK);
        mThemeOverlayController = new ThemeOverlayController(mContext,
                mBroadcastDispatcher, mBgHandler, mMainExecutor, mBgExecutor, mThemeOverlayApplier,
                mSecureSettings, mWallpaperManager, mUserManager, mDeviceProvisionedController,
                mUserTracker, mDumpManager, mFeatureFlags, mWakefulnessLifecycle) {
                mUserTracker, mDumpManager, mFeatureFlags, mResources, mWakefulnessLifecycle) {
            @Nullable
            @Override
            protected FabricatedOverlay getOverlay(int color, int type, Style style) {
@@ -140,6 +154,7 @@ public class ThemeOverlayControllerTest extends SysuiTestCase {
                when(overlay.getIdentifier())
                        .thenReturn(new OverlayIdentifier(Integer.toHexString(color | 0xff000000)));
                mCurrentStyle = style;
                mColorScheme = new ColorScheme(color, false /* nightMode */, style);
                return overlay;
            }
        };
@@ -643,16 +658,17 @@ public class ThemeOverlayControllerTest extends SysuiTestCase {

        Executor executor = MoreExecutors.directExecutor();

        mThemeOverlayController = new ThemeOverlayController(null /* context */,
        mThemeOverlayController = new ThemeOverlayController(mContext,
                mBroadcastDispatcher, mBgHandler, executor, executor, mThemeOverlayApplier,
                mSecureSettings, mWallpaperManager, mUserManager, mDeviceProvisionedController,
                mUserTracker, mDumpManager, mFeatureFlags, mWakefulnessLifecycle) {
                mUserTracker, mDumpManager, mFeatureFlags, mResources, mWakefulnessLifecycle) {
            @Nullable
            @Override
            protected FabricatedOverlay getOverlay(int color, int type, Style style) {
                FabricatedOverlay overlay = mock(FabricatedOverlay.class);
                when(overlay.getIdentifier())
                        .thenReturn(new OverlayIdentifier("com.thebest.livewallpaperapp.ever"));
                mColorScheme = new ColorScheme(color, false /* nightMode */, style);
                return overlay;
            }

@@ -679,16 +695,17 @@ public class ThemeOverlayControllerTest extends SysuiTestCase {
                .thenReturn(new WallpaperColors(Color.valueOf(Color.GRAY), null, null));

        Executor executor = MoreExecutors.directExecutor();
        mThemeOverlayController = new ThemeOverlayController(null /* context */,
        mThemeOverlayController = new ThemeOverlayController(mContext,
                mBroadcastDispatcher, mBgHandler, executor, executor, mThemeOverlayApplier,
                mSecureSettings, mWallpaperManager, mUserManager, mDeviceProvisionedController,
                mUserTracker, mDumpManager, mFeatureFlags, mWakefulnessLifecycle) {
                mUserTracker, mDumpManager, mFeatureFlags, mResources, mWakefulnessLifecycle) {
            @Nullable
            @Override
            protected FabricatedOverlay getOverlay(int color, int type, Style style) {
                FabricatedOverlay overlay = mock(FabricatedOverlay.class);
                when(overlay.getIdentifier())
                        .thenReturn(new OverlayIdentifier(Integer.toHexString(color | 0xff000000)));
                mColorScheme = new ColorScheme(color, false /* nightMode */, style);
                return overlay;
            }
        };