Merge "Skip theme application if it's already current" into tm-dev
This commit is contained in:
@@ -38,6 +38,7 @@ import android.content.om.FabricatedOverlay;
|
|||||||
import android.content.om.OverlayIdentifier;
|
import android.content.om.OverlayIdentifier;
|
||||||
import android.content.pm.UserInfo;
|
import android.content.pm.UserInfo;
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
|
import android.content.res.Resources;
|
||||||
import android.database.ContentObserver;
|
import android.database.ContentObserver;
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
@@ -53,6 +54,7 @@ import android.util.SparseIntArray;
|
|||||||
import android.util.TypedValue;
|
import android.util.TypedValue;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.VisibleForTesting;
|
||||||
|
|
||||||
import com.android.internal.graphics.ColorUtils;
|
import com.android.internal.graphics.ColorUtils;
|
||||||
import com.android.systemui.CoreStartable;
|
import com.android.systemui.CoreStartable;
|
||||||
@@ -114,10 +116,12 @@ public class ThemeOverlayController extends CoreStartable implements Dumpable {
|
|||||||
private final boolean mIsMonetEnabled;
|
private final boolean mIsMonetEnabled;
|
||||||
private final UserTracker mUserTracker;
|
private final UserTracker mUserTracker;
|
||||||
private final DeviceProvisionedController mDeviceProvisionedController;
|
private final DeviceProvisionedController mDeviceProvisionedController;
|
||||||
|
private final Resources mResources;
|
||||||
// Current wallpaper colors associated to a user.
|
// Current wallpaper colors associated to a user.
|
||||||
private final SparseArray<WallpaperColors> mCurrentColors = new SparseArray<>();
|
private final SparseArray<WallpaperColors> mCurrentColors = new SparseArray<>();
|
||||||
private final WallpaperManager mWallpaperManager;
|
private final WallpaperManager mWallpaperManager;
|
||||||
private ColorScheme mColorScheme;
|
@VisibleForTesting
|
||||||
|
protected ColorScheme mColorScheme;
|
||||||
// If fabricated overlays were already created for the current theme.
|
// If fabricated overlays were already created for the current theme.
|
||||||
private boolean mNeedsOverlayCreation;
|
private boolean mNeedsOverlayCreation;
|
||||||
// Dominant color extracted from wallpaper, NOT the color used on the overlay
|
// 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,
|
SecureSettings secureSettings, WallpaperManager wallpaperManager,
|
||||||
UserManager userManager, DeviceProvisionedController deviceProvisionedController,
|
UserManager userManager, DeviceProvisionedController deviceProvisionedController,
|
||||||
UserTracker userTracker, DumpManager dumpManager, FeatureFlags featureFlags,
|
UserTracker userTracker, DumpManager dumpManager, FeatureFlags featureFlags,
|
||||||
WakefulnessLifecycle wakefulnessLifecycle) {
|
@Main Resources resources, WakefulnessLifecycle wakefulnessLifecycle) {
|
||||||
super(context);
|
super(context);
|
||||||
|
|
||||||
mIsMonetEnabled = featureFlags.isEnabled(Flags.MONET);
|
mIsMonetEnabled = featureFlags.isEnabled(Flags.MONET);
|
||||||
@@ -358,6 +362,7 @@ public class ThemeOverlayController extends CoreStartable implements Dumpable {
|
|||||||
mSecureSettings = secureSettings;
|
mSecureSettings = secureSettings;
|
||||||
mWallpaperManager = wallpaperManager;
|
mWallpaperManager = wallpaperManager;
|
||||||
mUserTracker = userTracker;
|
mUserTracker = userTracker;
|
||||||
|
mResources = resources;
|
||||||
mWakefulnessLifecycle = wakefulnessLifecycle;
|
mWakefulnessLifecycle = wakefulnessLifecycle;
|
||||||
dumpManager.registerDumpable(TAG, this);
|
dumpManager.registerDumpable(TAG, this);
|
||||||
}
|
}
|
||||||
@@ -466,8 +471,13 @@ public class ThemeOverlayController extends CoreStartable implements Dumpable {
|
|||||||
mMainWallpaperColor = mainColor;
|
mMainWallpaperColor = mainColor;
|
||||||
|
|
||||||
if (mIsMonetEnabled) {
|
if (mIsMonetEnabled) {
|
||||||
|
mThemeStyle = fetchThemeStyleFromSetting();
|
||||||
mSecondaryOverlay = getOverlay(mMainWallpaperColor, ACCENT, mThemeStyle);
|
mSecondaryOverlay = getOverlay(mMainWallpaperColor, ACCENT, mThemeStyle);
|
||||||
mNeutralOverlay = getOverlay(mMainWallpaperColor, NEUTRAL, mThemeStyle);
|
mNeutralOverlay = getOverlay(mMainWallpaperColor, NEUTRAL, mThemeStyle);
|
||||||
|
if (colorSchemeIsApplied()) {
|
||||||
|
Log.d(TAG, "Skipping overlay creation. Theme was already: " + mColorScheme);
|
||||||
|
return;
|
||||||
|
}
|
||||||
mNeedsOverlayCreation = true;
|
mNeedsOverlayCreation = true;
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Log.d(TAG, "fetched overlays. accent: " + mSecondaryOverlay
|
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.
|
* Given a color candidate, return an overlay definition.
|
||||||
*/
|
*/
|
||||||
protected @Nullable FabricatedOverlay getOverlay(int color, int type, Style style) {
|
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;
|
& Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES;
|
||||||
|
|
||||||
mColorScheme = new ColorScheme(color, nightMode, style);
|
mColorScheme = new ColorScheme(color, nightMode, style);
|
||||||
@@ -525,6 +535,23 @@ public class ThemeOverlayController extends CoreStartable implements Dumpable {
|
|||||||
return overlay.build();
|
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() {
|
private void updateThemeOverlays() {
|
||||||
final int currentUser = mUserTracker.getUserId();
|
final int currentUser = mUserTracker.getUserId();
|
||||||
final String overlayPackageJson = mSecureSettings.getStringForUser(
|
final String overlayPackageJson = mSecureSettings.getStringForUser(
|
||||||
@@ -532,7 +559,6 @@ public class ThemeOverlayController extends CoreStartable implements Dumpable {
|
|||||||
currentUser);
|
currentUser);
|
||||||
if (DEBUG) Log.d(TAG, "updateThemeOverlays. Setting: " + overlayPackageJson);
|
if (DEBUG) Log.d(TAG, "updateThemeOverlays. Setting: " + overlayPackageJson);
|
||||||
final Map<String, OverlayIdentifier> categoryToPackage = new ArrayMap<>();
|
final Map<String, OverlayIdentifier> categoryToPackage = new ArrayMap<>();
|
||||||
Style newStyle = mThemeStyle;
|
|
||||||
if (!TextUtils.isEmpty(overlayPackageJson)) {
|
if (!TextUtils.isEmpty(overlayPackageJson)) {
|
||||||
try {
|
try {
|
||||||
JSONObject object = new JSONObject(overlayPackageJson);
|
JSONObject object = new JSONObject(overlayPackageJson);
|
||||||
@@ -543,25 +569,11 @@ public class ThemeOverlayController extends CoreStartable implements Dumpable {
|
|||||||
categoryToPackage.put(category, identifier);
|
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) {
|
} catch (JSONException e) {
|
||||||
Log.i(TAG, "Failed to parse THEME_CUSTOMIZATION_OVERLAY_PACKAGES.", 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.
|
// Let's generate system overlay if the style picker decided to override it.
|
||||||
OverlayIdentifier systemPalette = categoryToPackage.get(OVERLAY_CATEGORY_SYSTEM_PALETTE);
|
OverlayIdentifier systemPalette = categoryToPackage.get(OVERLAY_CATEGORY_SYSTEM_PALETTE);
|
||||||
if (mIsMonetEnabled && systemPalette != null && systemPalette.getPackageName() != null) {
|
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
|
@Override
|
||||||
public void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter pw, @NonNull String[] args) {
|
public void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter pw, @NonNull String[] args) {
|
||||||
pw.println("mSystemColors=" + mCurrentColors);
|
pw.println("mSystemColors=" + mCurrentColors);
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ import android.content.BroadcastReceiver;
|
|||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.om.FabricatedOverlay;
|
import android.content.om.FabricatedOverlay;
|
||||||
import android.content.om.OverlayIdentifier;
|
import android.content.om.OverlayIdentifier;
|
||||||
|
import android.content.res.Resources;
|
||||||
import android.database.ContentObserver;
|
import android.database.ContentObserver;
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
import android.os.Handler;
|
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.FeatureFlags;
|
||||||
import com.android.systemui.flags.Flags;
|
import com.android.systemui.flags.Flags;
|
||||||
import com.android.systemui.keyguard.WakefulnessLifecycle;
|
import com.android.systemui.keyguard.WakefulnessLifecycle;
|
||||||
|
import com.android.systemui.monet.ColorScheme;
|
||||||
import com.android.systemui.monet.Style;
|
import com.android.systemui.monet.Style;
|
||||||
import com.android.systemui.settings.UserTracker;
|
import com.android.systemui.settings.UserTracker;
|
||||||
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
|
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
|
||||||
@@ -108,6 +110,8 @@ public class ThemeOverlayControllerTest extends SysuiTestCase {
|
|||||||
@Mock
|
@Mock
|
||||||
private FeatureFlags mFeatureFlags;
|
private FeatureFlags mFeatureFlags;
|
||||||
@Mock
|
@Mock
|
||||||
|
private Resources mResources;
|
||||||
|
@Mock
|
||||||
private WakefulnessLifecycle mWakefulnessLifecycle;
|
private WakefulnessLifecycle mWakefulnessLifecycle;
|
||||||
@Captor
|
@Captor
|
||||||
private ArgumentCaptor<BroadcastReceiver> mBroadcastReceiver;
|
private ArgumentCaptor<BroadcastReceiver> mBroadcastReceiver;
|
||||||
@@ -129,10 +133,20 @@ public class ThemeOverlayControllerTest extends SysuiTestCase {
|
|||||||
when(mFeatureFlags.isEnabled(Flags.MONET)).thenReturn(true);
|
when(mFeatureFlags.isEnabled(Flags.MONET)).thenReturn(true);
|
||||||
when(mWakefulnessLifecycle.getWakefulness()).thenReturn(WAKEFULNESS_AWAKE);
|
when(mWakefulnessLifecycle.getWakefulness()).thenReturn(WAKEFULNESS_AWAKE);
|
||||||
when(mDeviceProvisionedController.isCurrentUserSetup()).thenReturn(true);
|
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,
|
mBroadcastDispatcher, mBgHandler, mMainExecutor, mBgExecutor, mThemeOverlayApplier,
|
||||||
mSecureSettings, mWallpaperManager, mUserManager, mDeviceProvisionedController,
|
mSecureSettings, mWallpaperManager, mUserManager, mDeviceProvisionedController,
|
||||||
mUserTracker, mDumpManager, mFeatureFlags, mWakefulnessLifecycle) {
|
mUserTracker, mDumpManager, mFeatureFlags, mResources, mWakefulnessLifecycle) {
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
protected FabricatedOverlay getOverlay(int color, int type, Style style) {
|
protected FabricatedOverlay getOverlay(int color, int type, Style style) {
|
||||||
@@ -140,6 +154,7 @@ public class ThemeOverlayControllerTest extends SysuiTestCase {
|
|||||||
when(overlay.getIdentifier())
|
when(overlay.getIdentifier())
|
||||||
.thenReturn(new OverlayIdentifier(Integer.toHexString(color | 0xff000000)));
|
.thenReturn(new OverlayIdentifier(Integer.toHexString(color | 0xff000000)));
|
||||||
mCurrentStyle = style;
|
mCurrentStyle = style;
|
||||||
|
mColorScheme = new ColorScheme(color, false /* nightMode */, style);
|
||||||
return overlay;
|
return overlay;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -643,16 +658,17 @@ public class ThemeOverlayControllerTest extends SysuiTestCase {
|
|||||||
|
|
||||||
Executor executor = MoreExecutors.directExecutor();
|
Executor executor = MoreExecutors.directExecutor();
|
||||||
|
|
||||||
mThemeOverlayController = new ThemeOverlayController(null /* context */,
|
mThemeOverlayController = new ThemeOverlayController(mContext,
|
||||||
mBroadcastDispatcher, mBgHandler, executor, executor, mThemeOverlayApplier,
|
mBroadcastDispatcher, mBgHandler, executor, executor, mThemeOverlayApplier,
|
||||||
mSecureSettings, mWallpaperManager, mUserManager, mDeviceProvisionedController,
|
mSecureSettings, mWallpaperManager, mUserManager, mDeviceProvisionedController,
|
||||||
mUserTracker, mDumpManager, mFeatureFlags, mWakefulnessLifecycle) {
|
mUserTracker, mDumpManager, mFeatureFlags, mResources, mWakefulnessLifecycle) {
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
protected FabricatedOverlay getOverlay(int color, int type, Style style) {
|
protected FabricatedOverlay getOverlay(int color, int type, Style style) {
|
||||||
FabricatedOverlay overlay = mock(FabricatedOverlay.class);
|
FabricatedOverlay overlay = mock(FabricatedOverlay.class);
|
||||||
when(overlay.getIdentifier())
|
when(overlay.getIdentifier())
|
||||||
.thenReturn(new OverlayIdentifier("com.thebest.livewallpaperapp.ever"));
|
.thenReturn(new OverlayIdentifier("com.thebest.livewallpaperapp.ever"));
|
||||||
|
mColorScheme = new ColorScheme(color, false /* nightMode */, style);
|
||||||
return overlay;
|
return overlay;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -679,16 +695,17 @@ public class ThemeOverlayControllerTest extends SysuiTestCase {
|
|||||||
.thenReturn(new WallpaperColors(Color.valueOf(Color.GRAY), null, null));
|
.thenReturn(new WallpaperColors(Color.valueOf(Color.GRAY), null, null));
|
||||||
|
|
||||||
Executor executor = MoreExecutors.directExecutor();
|
Executor executor = MoreExecutors.directExecutor();
|
||||||
mThemeOverlayController = new ThemeOverlayController(null /* context */,
|
mThemeOverlayController = new ThemeOverlayController(mContext,
|
||||||
mBroadcastDispatcher, mBgHandler, executor, executor, mThemeOverlayApplier,
|
mBroadcastDispatcher, mBgHandler, executor, executor, mThemeOverlayApplier,
|
||||||
mSecureSettings, mWallpaperManager, mUserManager, mDeviceProvisionedController,
|
mSecureSettings, mWallpaperManager, mUserManager, mDeviceProvisionedController,
|
||||||
mUserTracker, mDumpManager, mFeatureFlags, mWakefulnessLifecycle) {
|
mUserTracker, mDumpManager, mFeatureFlags, mResources, mWakefulnessLifecycle) {
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
protected FabricatedOverlay getOverlay(int color, int type, Style style) {
|
protected FabricatedOverlay getOverlay(int color, int type, Style style) {
|
||||||
FabricatedOverlay overlay = mock(FabricatedOverlay.class);
|
FabricatedOverlay overlay = mock(FabricatedOverlay.class);
|
||||||
when(overlay.getIdentifier())
|
when(overlay.getIdentifier())
|
||||||
.thenReturn(new OverlayIdentifier(Integer.toHexString(color | 0xff000000)));
|
.thenReturn(new OverlayIdentifier(Integer.toHexString(color | 0xff000000)));
|
||||||
|
mColorScheme = new ColorScheme(color, false /* nightMode */, style);
|
||||||
return overlay;
|
return overlay;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user