Loading core/java/android/provider/Settings.java +29 −0 Original line number Diff line number Diff line Loading @@ -7120,6 +7120,35 @@ public final class Settings { */ 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. * @hide Loading core/tests/coretests/src/android/provider/SettingsBackupTest.java +1 −0 Original line number Diff line number Diff line Loading @@ -593,6 +593,7 @@ public class SettingsBackupTest { Settings.Secure.SHOW_ROTATION_SUGGESTIONS, Settings.Secure.SKIP_FIRST_USE_HINTS, // candidate? Settings.Secure.SMS_DEFAULT_APPLICATION, Settings.Secure.THEME_MODE, Settings.Secure.TRUST_AGENTS_INITIALIZED, Settings.Secure.TV_INPUT_CUSTOM_LABELS, Settings.Secure.TV_INPUT_HIDDEN_INPUTS, Loading services/core/java/com/android/server/wallpaper/WallpaperManagerService.java +147 −1 Original line number Diff line number Diff line Loading @@ -51,6 +51,7 @@ import android.content.pm.ResolveInfo; import android.content.pm.ServiceInfo; import android.content.pm.UserInfo; import android.content.res.Resources; import android.database.ContentObserver; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.BitmapRegionDecoder; Loading @@ -75,6 +76,7 @@ import android.os.ServiceManager; import android.os.SystemClock; import android.os.UserHandle; import android.os.UserManager; import android.provider.Settings; import android.service.wallpaper.IWallpaperConnection; import android.service.wallpaper.IWallpaperEngine; import android.service.wallpaper.IWallpaperService; Loading Loading @@ -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() { final IWallpaperManagerCallback cb = mKeyguardListener; if (cb != null) { Loading Loading @@ -413,6 +511,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub } userAllColorListeners.finishBroadcast(); } wallpaperColors = getThemeColorsLocked(wallpaperColors); } final int count = colorListeners.size(); Loading Loading @@ -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 * for display. Loading Loading @@ -676,6 +809,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub final SparseArray<Boolean> mUserRestorecon = new SparseArray<Boolean>(); int mCurrentUserId = UserHandle.USER_NULL; boolean mInAmbientMode; int mThemeMode; static class WallpaperData { Loading Loading @@ -734,6 +868,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub long lastDiedTime; boolean wallpaperUpdating; WallpaperObserver wallpaperObserver; ThemeSettingsObserver themeSettingsObserver; /** * List of callbacks registered they should each be notified when the wallpaper is changed. Loading Loading @@ -1279,6 +1414,10 @@ public class WallpaperManagerService extends IWallpaperManager.Stub wallpaper.wallpaperObserver.stopWatching(); wallpaper.wallpaperObserver = null; } if (wallpaper.themeSettingsObserver != null) { wallpaper.themeSettingsObserver.stopObserving(mContext); wallpaper.themeSettingsObserver = null; } } } Loading Loading @@ -1362,6 +1501,13 @@ public class WallpaperManagerService extends IWallpaperManager.Stub systemWallpaper.wallpaperObserver = new WallpaperObserver(systemWallpaper); 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); } Loading Loading @@ -1835,7 +1981,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub } synchronized (mLock) { return wallpaperData.primaryColors; return getThemeColorsLocked(wallpaperData.primaryColors); } } Loading Loading
core/java/android/provider/Settings.java +29 −0 Original line number Diff line number Diff line Loading @@ -7120,6 +7120,35 @@ public final class Settings { */ 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. * @hide Loading
core/tests/coretests/src/android/provider/SettingsBackupTest.java +1 −0 Original line number Diff line number Diff line Loading @@ -593,6 +593,7 @@ public class SettingsBackupTest { Settings.Secure.SHOW_ROTATION_SUGGESTIONS, Settings.Secure.SKIP_FIRST_USE_HINTS, // candidate? Settings.Secure.SMS_DEFAULT_APPLICATION, Settings.Secure.THEME_MODE, Settings.Secure.TRUST_AGENTS_INITIALIZED, Settings.Secure.TV_INPUT_CUSTOM_LABELS, Settings.Secure.TV_INPUT_HIDDEN_INPUTS, Loading
services/core/java/com/android/server/wallpaper/WallpaperManagerService.java +147 −1 Original line number Diff line number Diff line Loading @@ -51,6 +51,7 @@ import android.content.pm.ResolveInfo; import android.content.pm.ServiceInfo; import android.content.pm.UserInfo; import android.content.res.Resources; import android.database.ContentObserver; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.BitmapRegionDecoder; Loading @@ -75,6 +76,7 @@ import android.os.ServiceManager; import android.os.SystemClock; import android.os.UserHandle; import android.os.UserManager; import android.provider.Settings; import android.service.wallpaper.IWallpaperConnection; import android.service.wallpaper.IWallpaperEngine; import android.service.wallpaper.IWallpaperService; Loading Loading @@ -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() { final IWallpaperManagerCallback cb = mKeyguardListener; if (cb != null) { Loading Loading @@ -413,6 +511,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub } userAllColorListeners.finishBroadcast(); } wallpaperColors = getThemeColorsLocked(wallpaperColors); } final int count = colorListeners.size(); Loading Loading @@ -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 * for display. Loading Loading @@ -676,6 +809,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub final SparseArray<Boolean> mUserRestorecon = new SparseArray<Boolean>(); int mCurrentUserId = UserHandle.USER_NULL; boolean mInAmbientMode; int mThemeMode; static class WallpaperData { Loading Loading @@ -734,6 +868,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub long lastDiedTime; boolean wallpaperUpdating; WallpaperObserver wallpaperObserver; ThemeSettingsObserver themeSettingsObserver; /** * List of callbacks registered they should each be notified when the wallpaper is changed. Loading Loading @@ -1279,6 +1414,10 @@ public class WallpaperManagerService extends IWallpaperManager.Stub wallpaper.wallpaperObserver.stopWatching(); wallpaper.wallpaperObserver = null; } if (wallpaper.themeSettingsObserver != null) { wallpaper.themeSettingsObserver.stopObserving(mContext); wallpaper.themeSettingsObserver = null; } } } Loading Loading @@ -1362,6 +1501,13 @@ public class WallpaperManagerService extends IWallpaperManager.Stub systemWallpaper.wallpaperObserver = new WallpaperObserver(systemWallpaper); 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); } Loading Loading @@ -1835,7 +1981,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub } synchronized (mLock) { return wallpaperData.primaryColors; return getThemeColorsLocked(wallpaperData.primaryColors); } } Loading