Add theme mode design let user can choose theme self
Add a ContentObserver on WallpaperManagerService to listen THEME_MODE value change. When changed, call notifyWallpaperColorsChanged and set WallpaperColors color hint by the current mode. Bug: 63903361 Test: manual Change-Id: I4f7aa7b184565b1bb23c7f4f1f07fc310dac7546
This commit is contained in:
@@ -7113,6 +7113,35 @@ public final class Settings {
|
|||||||
*/
|
*/
|
||||||
public static final String UI_NIGHT_MODE = "ui_night_mode";
|
public static final String UI_NIGHT_MODE = "ui_night_mode";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The current device UI theme mode effect SystemUI and Launcher.<br/>
|
||||||
|
* <b>Values:</b><br/>
|
||||||
|
* 0 - The mode that theme will controlled by wallpaper color.<br/>
|
||||||
|
* 1 - The mode that will always light theme.<br/>
|
||||||
|
* 2 - The mode that will always dark theme.<br/>
|
||||||
|
*
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public static final String THEME_MODE = "theme_mode";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* THEME_MODE value for wallpaper mode.
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public static final int THEME_MODE_WALLPAPER = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* THEME_MODE value for light theme mode.
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public static final int THEME_MODE_LIGHT = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* THEME_MODE value for dark theme mode.
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public static final int THEME_MODE_DARK = 2;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether screensavers are enabled.
|
* Whether screensavers are enabled.
|
||||||
* @hide
|
* @hide
|
||||||
|
|||||||
@@ -591,6 +591,7 @@ public class SettingsBackupTest {
|
|||||||
Settings.Secure.SHOW_ROTATION_SUGGESTIONS,
|
Settings.Secure.SHOW_ROTATION_SUGGESTIONS,
|
||||||
Settings.Secure.SKIP_FIRST_USE_HINTS, // candidate?
|
Settings.Secure.SKIP_FIRST_USE_HINTS, // candidate?
|
||||||
Settings.Secure.SMS_DEFAULT_APPLICATION,
|
Settings.Secure.SMS_DEFAULT_APPLICATION,
|
||||||
|
Settings.Secure.THEME_MODE,
|
||||||
Settings.Secure.TRUST_AGENTS_INITIALIZED,
|
Settings.Secure.TRUST_AGENTS_INITIALIZED,
|
||||||
Settings.Secure.TV_INPUT_CUSTOM_LABELS,
|
Settings.Secure.TV_INPUT_CUSTOM_LABELS,
|
||||||
Settings.Secure.TV_INPUT_HIDDEN_INPUTS,
|
Settings.Secure.TV_INPUT_HIDDEN_INPUTS,
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ import android.content.pm.ResolveInfo;
|
|||||||
import android.content.pm.ServiceInfo;
|
import android.content.pm.ServiceInfo;
|
||||||
import android.content.pm.UserInfo;
|
import android.content.pm.UserInfo;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
|
import android.database.ContentObserver;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.BitmapFactory;
|
import android.graphics.BitmapFactory;
|
||||||
import android.graphics.BitmapRegionDecoder;
|
import android.graphics.BitmapRegionDecoder;
|
||||||
@@ -75,6 +76,7 @@ import android.os.ServiceManager;
|
|||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
import android.os.UserManager;
|
import android.os.UserManager;
|
||||||
|
import android.provider.Settings;
|
||||||
import android.service.wallpaper.IWallpaperConnection;
|
import android.service.wallpaper.IWallpaperConnection;
|
||||||
import android.service.wallpaper.IWallpaperEngine;
|
import android.service.wallpaper.IWallpaperEngine;
|
||||||
import android.service.wallpaper.IWallpaperService;
|
import android.service.wallpaper.IWallpaperService;
|
||||||
@@ -336,6 +338,102 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Observes changes of theme settings. It will check whether to call
|
||||||
|
* notifyWallpaperColorsChanged by the current theme and updated theme.
|
||||||
|
* The light theme and dark theme are controlled by the hint values in Wallpaper colors,
|
||||||
|
* threrfore, if light theme mode is chosen, HINT_SUPPORTS_DARK_THEME in hint will be
|
||||||
|
* removed and then notify listeners.
|
||||||
|
*/
|
||||||
|
private class ThemeSettingsObserver extends ContentObserver {
|
||||||
|
|
||||||
|
public ThemeSettingsObserver(Handler handler) {
|
||||||
|
super(handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void startObserving(Context context) {
|
||||||
|
context.getContentResolver().registerContentObserver(
|
||||||
|
Settings.Secure.getUriFor(Settings.Secure.THEME_MODE),
|
||||||
|
false,
|
||||||
|
this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stopObserving(Context context) {
|
||||||
|
context.getContentResolver().unregisterContentObserver(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onChange(boolean selfChange) {
|
||||||
|
onThemeSettingsChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether to call notifyWallpaperColorsChanged. Assumed that the theme mode
|
||||||
|
* was wallpaper theme mode and dark wallpaper was set, therefoe, the theme was dark.
|
||||||
|
* Then theme mode changing to dark theme mode, however, theme should not update since
|
||||||
|
* theme was dark already.
|
||||||
|
*/
|
||||||
|
private boolean needUpdateLocked(WallpaperColors colors, int themeMode) {
|
||||||
|
if (colors == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (themeMode == mThemeMode) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean result = true;
|
||||||
|
boolean supportDarkTheme =
|
||||||
|
(colors.getColorHints() & WallpaperColors.HINT_SUPPORTS_DARK_THEME) != 0;
|
||||||
|
switch (themeMode) {
|
||||||
|
case Settings.Secure.THEME_MODE_WALLPAPER:
|
||||||
|
if (mThemeMode == Settings.Secure.THEME_MODE_LIGHT) {
|
||||||
|
result = supportDarkTheme;
|
||||||
|
} else {
|
||||||
|
result = !supportDarkTheme;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Settings.Secure.THEME_MODE_LIGHT:
|
||||||
|
if (mThemeMode == Settings.Secure.THEME_MODE_WALLPAPER) {
|
||||||
|
result = supportDarkTheme;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Settings.Secure.THEME_MODE_DARK:
|
||||||
|
if (mThemeMode == Settings.Secure.THEME_MODE_WALLPAPER) {
|
||||||
|
result = !supportDarkTheme;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Slog.w(TAG, "unkonwn theme mode " + themeMode);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
mThemeMode = themeMode;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void onThemeSettingsChanged() {
|
||||||
|
WallpaperData wallpaper;
|
||||||
|
synchronized (mLock) {
|
||||||
|
wallpaper = mWallpaperMap.get(mCurrentUserId);
|
||||||
|
int updatedThemeMode = Settings.Secure.getInt(
|
||||||
|
mContext.getContentResolver(), Settings.Secure.THEME_MODE,
|
||||||
|
Settings.Secure.THEME_MODE_WALLPAPER);
|
||||||
|
|
||||||
|
if (DEBUG) {
|
||||||
|
Slog.v(TAG, "onThemeSettingsChanged, mode = " + updatedThemeMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!needUpdateLocked(wallpaper.primaryColors, updatedThemeMode)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wallpaper != null) {
|
||||||
|
notifyWallpaperColorsChanged(wallpaper, FLAG_SYSTEM);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void notifyLockWallpaperChanged() {
|
void notifyLockWallpaperChanged() {
|
||||||
final IWallpaperManagerCallback cb = mKeyguardListener;
|
final IWallpaperManagerCallback cb = mKeyguardListener;
|
||||||
if (cb != null) {
|
if (cb != null) {
|
||||||
@@ -413,6 +511,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
|
|||||||
}
|
}
|
||||||
userAllColorListeners.finishBroadcast();
|
userAllColorListeners.finishBroadcast();
|
||||||
}
|
}
|
||||||
|
wallpaperColors = getThemeColorsLocked(wallpaperColors);
|
||||||
}
|
}
|
||||||
|
|
||||||
final int count = colorListeners.size();
|
final int count = colorListeners.size();
|
||||||
@@ -480,6 +579,40 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We can easily change theme by modified colors hint. This function will check
|
||||||
|
* current theme mode and return the WallpaperColors fit current theme mode.
|
||||||
|
* If color need modified, it will return a copied WallpaperColors which
|
||||||
|
* its ColorsHint is modified to fit current theme mode.
|
||||||
|
*
|
||||||
|
* @param colors a wallpaper primary colors representation
|
||||||
|
*/
|
||||||
|
private WallpaperColors getThemeColorsLocked(WallpaperColors colors) {
|
||||||
|
if (colors == null) {
|
||||||
|
Slog.w(TAG, "Cannot get theme colors because WallpaperColors is null.");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
int colorHints = colors.getColorHints();
|
||||||
|
boolean supportDarkTheme = (colorHints & WallpaperColors.HINT_SUPPORTS_DARK_THEME) != 0;
|
||||||
|
if (mThemeMode == Settings.Secure.THEME_MODE_WALLPAPER ||
|
||||||
|
(mThemeMode == Settings.Secure.THEME_MODE_LIGHT && !supportDarkTheme) ||
|
||||||
|
(mThemeMode == Settings.Secure.THEME_MODE_DARK && supportDarkTheme)) {
|
||||||
|
return colors;
|
||||||
|
}
|
||||||
|
|
||||||
|
WallpaperColors themeColors = new WallpaperColors(colors.getPrimaryColor(),
|
||||||
|
colors.getSecondaryColor(), colors.getTertiaryColor());
|
||||||
|
|
||||||
|
if (mThemeMode == Settings.Secure.THEME_MODE_LIGHT) {
|
||||||
|
colorHints &= ~WallpaperColors.HINT_SUPPORTS_DARK_THEME;
|
||||||
|
} else if (mThemeMode == Settings.Secure.THEME_MODE_DARK) {
|
||||||
|
colorHints |= WallpaperColors.HINT_SUPPORTS_DARK_THEME;
|
||||||
|
}
|
||||||
|
themeColors.setColorHints(colorHints);
|
||||||
|
return themeColors;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Once a new wallpaper has been written via setWallpaper(...), it needs to be cropped
|
* Once a new wallpaper has been written via setWallpaper(...), it needs to be cropped
|
||||||
* for display.
|
* for display.
|
||||||
@@ -676,6 +809,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
|
|||||||
final SparseArray<Boolean> mUserRestorecon = new SparseArray<Boolean>();
|
final SparseArray<Boolean> mUserRestorecon = new SparseArray<Boolean>();
|
||||||
int mCurrentUserId = UserHandle.USER_NULL;
|
int mCurrentUserId = UserHandle.USER_NULL;
|
||||||
boolean mInAmbientMode;
|
boolean mInAmbientMode;
|
||||||
|
int mThemeMode;
|
||||||
|
|
||||||
static class WallpaperData {
|
static class WallpaperData {
|
||||||
|
|
||||||
@@ -734,6 +868,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
|
|||||||
long lastDiedTime;
|
long lastDiedTime;
|
||||||
boolean wallpaperUpdating;
|
boolean wallpaperUpdating;
|
||||||
WallpaperObserver wallpaperObserver;
|
WallpaperObserver wallpaperObserver;
|
||||||
|
ThemeSettingsObserver themeSettingsObserver;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List of callbacks registered they should each be notified when the wallpaper is changed.
|
* List of callbacks registered they should each be notified when the wallpaper is changed.
|
||||||
@@ -1279,6 +1414,10 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
|
|||||||
wallpaper.wallpaperObserver.stopWatching();
|
wallpaper.wallpaperObserver.stopWatching();
|
||||||
wallpaper.wallpaperObserver = null;
|
wallpaper.wallpaperObserver = null;
|
||||||
}
|
}
|
||||||
|
if (wallpaper.themeSettingsObserver != null) {
|
||||||
|
wallpaper.themeSettingsObserver.stopObserving(mContext);
|
||||||
|
wallpaper.themeSettingsObserver = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1362,6 +1501,13 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
|
|||||||
systemWallpaper.wallpaperObserver = new WallpaperObserver(systemWallpaper);
|
systemWallpaper.wallpaperObserver = new WallpaperObserver(systemWallpaper);
|
||||||
systemWallpaper.wallpaperObserver.startWatching();
|
systemWallpaper.wallpaperObserver.startWatching();
|
||||||
}
|
}
|
||||||
|
if (systemWallpaper.themeSettingsObserver == null) {
|
||||||
|
systemWallpaper.themeSettingsObserver = new ThemeSettingsObserver(null);
|
||||||
|
systemWallpaper.themeSettingsObserver.startObserving(mContext);
|
||||||
|
}
|
||||||
|
mThemeMode = Settings.Secure.getInt(
|
||||||
|
mContext.getContentResolver(), Settings.Secure.THEME_MODE,
|
||||||
|
Settings.Secure.THEME_MODE_WALLPAPER);
|
||||||
switchWallpaper(systemWallpaper, reply);
|
switchWallpaper(systemWallpaper, reply);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1835,7 +1981,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
|
|||||||
}
|
}
|
||||||
|
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
return wallpaperData.primaryColors;
|
return getThemeColorsLocked(wallpaperData.primaryColors);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user