Custom Theme 5/n: apply custom theme
Bug: 124796742
Change-Id: I9ec8d029c2fd1598753ea0fed471831c3cf692a6
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 990f043..0046cad 100755
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
package="com.android.wallpaper">
<uses-sdk android:targetSdkVersion="Q" android:minSdkVersion="28"/>
@@ -15,7 +16,9 @@
android:requiredForAllUsers="true"
android:restoreAnyVersion="true"
android:supportsRtl="true"
- android:theme="@style/CustomizationTheme">
+ android:name="com.android.customization.picker.CustomizationPickerApplication"
+ android:theme="@style/CustomizationTheme"
+ tools:replace="android:name">
<activity
android:name="com.android.customization.picker.CustomizationPickerActivity"
android:label="@string/app_name"
diff --git a/res/values/override.xml b/res/values/override.xml
index 2de29c4..b3e4701 100644
--- a/res/values/override.xml
+++ b/res/values/override.xml
@@ -25,4 +25,6 @@
corresponding to a ContentProvider in launcher to provide available grids and
allow for changing them -->
<string name="grid_control_metadata_name" translatable="false">com.android.launcher3.grid.control</string>
+
+ <string name="launcher_overlayable_package" translatable="false">com.android.launcher3</string>
</resources>
\ No newline at end of file
diff --git a/src/com/android/customization/model/ResourceConstants.java b/src/com/android/customization/model/ResourceConstants.java
index f4c48c0..3b831b3 100644
--- a/src/com/android/customization/model/ResourceConstants.java
+++ b/src/com/android/customization/model/ResourceConstants.java
@@ -15,8 +15,14 @@
*/
package com.android.customization.model;
+import android.content.Context;
import android.provider.Settings.Secure;
+import com.android.wallpaper.R;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+
/**
* Holds common strings used to reference system resources.
*/
@@ -37,8 +43,6 @@
*/
String SYSUI_PACKAGE = "com.android.systemui";
- String [] DEFAULT_TARGET_PACKAGES = {ANDROID_PACKAGE, SETTINGS_PACKAGE, SYSUI_PACKAGE};
-
/**
* Name of the system resource for icon mask
*/
@@ -53,6 +57,7 @@
String OVERLAY_CATEGORY_ICON_ANDROID = "android.theme.customization.icon_pack.android";
String OVERLAY_CATEGORY_ICON_SETTINGS = "android.theme.customization.icon_pack.settings";
String OVERLAY_CATEGORY_ICON_SYSUI = "android.theme.customization.icon_pack.systemui";
+ String OVERLAY_CATEGORY_ICON_LAUNCHER = "android.theme.customization.icon_pack.launcher";
/**
* Secure Setting used to store the currently set theme.
@@ -68,4 +73,19 @@
"ic_qs_auto_rotate",
"ic_signal_airplane"
};
+
+ ArrayList<String> sTargetPackages = new ArrayList<>();
+
+ static String[] getPackagesToOverlay(Context context) {
+ if (sTargetPackages.isEmpty()) {
+ sTargetPackages.addAll(Arrays.asList(ANDROID_PACKAGE, SETTINGS_PACKAGE,
+ SYSUI_PACKAGE));
+ sTargetPackages.add(getLauncherPackage(context));
+ }
+ return sTargetPackages.toArray(new String[0]);
+ }
+
+ static String getLauncherPackage(Context context) {
+ return context.getString(R.string.launcher_overlayable_package);
+ }
}
diff --git a/src/com/android/customization/model/theme/DefaultThemeProvider.java b/src/com/android/customization/model/theme/DefaultThemeProvider.java
index 4d3b90b..02a0047 100644
--- a/src/com/android/customization/model/theme/DefaultThemeProvider.java
+++ b/src/com/android/customization/model/theme/DefaultThemeProvider.java
@@ -18,6 +18,11 @@
import static com.android.customization.model.ResourceConstants.ANDROID_PACKAGE;
import static com.android.customization.model.ResourceConstants.CONFIG_ICON_MASK;
import static com.android.customization.model.ResourceConstants.ICON_PREVIEW_DRAWABLE_NAME;
+import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_FONT;
+import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_ICON_ANDROID;
+import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_ICON_LAUNCHER;
+import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_ICON_SETTINGS;
+import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_ICON_SYSUI;
import static com.android.customization.model.ResourceConstants.SETTINGS_PACKAGE;
import static com.android.customization.model.ResourceConstants.SYSUI_ICONS_FOR_PREVIEW;
import static com.android.customization.model.ResourceConstants.SYSUI_PACKAGE;
@@ -41,13 +46,18 @@
import com.android.customization.model.ResourcesApkProvider;
import com.android.customization.model.theme.ThemeBundle.Builder;
import com.android.customization.model.theme.custom.CustomTheme;
+import com.android.customization.module.CustomizationPreferences;
import com.android.wallpaper.R;
import com.android.wallpaper.asset.ResourceAsset;
import com.bumptech.glide.request.RequestOptions;
+import org.json.JSONException;
+import org.json.JSONObject;
+
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
@@ -84,10 +94,12 @@
private List<ThemeBundle> mThemes;
private Map<String, OverlayInfo> mOverlayInfos;
+ private final CustomizationPreferences mCustomizationPreferences;
- public DefaultThemeProvider(Context context) {
+ public DefaultThemeProvider(Context context, CustomizationPreferences customizationPrefs) {
super(context, context.getString(R.string.themes_stub_package));
OverlayManager om = context.getSystemService(OverlayManager.class);
+ mCustomizationPreferences = customizationPrefs;
mOverlayInfos = new HashMap<>();
Consumer<OverlayInfo> addToMap = overlayInfo -> mOverlayInfos.put(
@@ -95,6 +107,8 @@
om.getOverlayInfosForTarget(ANDROID_PACKAGE, UserHandle.myUserId()).forEach(addToMap);
om.getOverlayInfosForTarget(SYSUI_PACKAGE, UserHandle.myUserId()).forEach(addToMap);
om.getOverlayInfosForTarget(SETTINGS_PACKAGE, UserHandle.myUserId()).forEach(addToMap);
+ om.getOverlayInfosForTarget(ResourceConstants.getLauncherPackage(context),
+ UserHandle.myUserId()).forEach(addToMap);
}
@Override
@@ -127,16 +141,7 @@
String fontOverlayPackage = getOverlayPackage(FONT_PREFIX, themeName);
- if (!TextUtils.isEmpty(fontOverlayPackage)) {
- builder.addOverlayPackage(getOverlayCategory(fontOverlayPackage),
- fontOverlayPackage)
- .setBodyFontFamily(loadTypeface(
- ResourceConstants.CONFIG_BODY_FONT_FAMILY,
- fontOverlayPackage))
- .setHeadlineFontFamily(loadTypeface(
- ResourceConstants.CONFIG_HEADLINE_FONT_FAMILY,
- fontOverlayPackage));
- }
+ addFontOverlay(builder, fontOverlayPackage);
String colorOverlayPackage = getOverlayPackage(COLOR_PREFIX, themeName);
@@ -168,43 +173,20 @@
String iconAndroidOverlayPackage = getOverlayPackage(ICON_ANDROID_PREFIX,
themeName);
- if (!TextUtils.isEmpty(iconAndroidOverlayPackage)) {
- builder.addOverlayPackage(getOverlayCategory(iconAndroidOverlayPackage),
- iconAndroidOverlayPackage)
- .addIcon(loadIconPreviewDrawable(
- ICON_PREVIEW_DRAWABLE_NAME,
- iconAndroidOverlayPackage));
- } else {
- builder.addIcon(mContext.getResources().getDrawable(
- Resources.getSystem().getIdentifier(
- ICON_PREVIEW_DRAWABLE_NAME,
- "drawable", ANDROID_PACKAGE), null));
- }
+ addAndroidIconOverlay(builder, iconAndroidOverlayPackage);
String iconSysUiOverlayPackage = getOverlayPackage(ICON_SYSUI_PREFIX, themeName);
- if (!TextUtils.isEmpty(iconSysUiOverlayPackage)) {
- builder.addOverlayPackage(getOverlayCategory(iconSysUiOverlayPackage),
- iconSysUiOverlayPackage);
- for (String iconName : SYSUI_ICONS_FOR_PREVIEW) {
- builder.addIcon(loadIconPreviewDrawable(iconName, iconSysUiOverlayPackage));
- }
- }
+ addSysUiIconOverlay(builder, iconSysUiOverlayPackage);
String iconLauncherOverlayPackage = getOverlayPackage(ICON_LAUNCHER_PREFIX,
themeName);
- if (!TextUtils.isEmpty(iconLauncherOverlayPackage)) {
- builder.addOverlayPackage(getOverlayCategory(iconLauncherOverlayPackage),
- iconLauncherOverlayPackage);
- }
+ addNoPreviewIconOverlay(builder,iconLauncherOverlayPackage);
String iconSettingsOverlayPackage = getOverlayPackage(ICON_SETTINGS_PREFIX,
themeName);
- if (!TextUtils.isEmpty(iconSettingsOverlayPackage)) {
- builder.addOverlayPackage(getOverlayCategory(iconSettingsOverlayPackage),
- iconSettingsOverlayPackage);
- }
+ addNoPreviewIconOverlay(builder, iconSettingsOverlayPackage);
try {
String wallpaperResName = WALLPAPER_PREFIX + themeName;
@@ -239,6 +221,54 @@
}
}
+ private void addNoPreviewIconOverlay(Builder builder, String overlayPackage) {
+ if (!TextUtils.isEmpty(overlayPackage)) {
+ builder.addOverlayPackage(getOverlayCategory(overlayPackage),
+ overlayPackage);
+ }
+ }
+
+ private void addSysUiIconOverlay(Builder builder, String iconSysUiOverlayPackage)
+ throws NameNotFoundException {
+ if (!TextUtils.isEmpty(iconSysUiOverlayPackage)) {
+ builder.addOverlayPackage(getOverlayCategory(iconSysUiOverlayPackage),
+ iconSysUiOverlayPackage);
+ for (String iconName : SYSUI_ICONS_FOR_PREVIEW) {
+ builder.addIcon(loadIconPreviewDrawable(iconName, iconSysUiOverlayPackage));
+ }
+ }
+ }
+
+ private void addAndroidIconOverlay(Builder builder, String iconAndroidOverlayPackage)
+ throws NameNotFoundException {
+ if (!TextUtils.isEmpty(iconAndroidOverlayPackage)) {
+ builder.addOverlayPackage(getOverlayCategory(iconAndroidOverlayPackage),
+ iconAndroidOverlayPackage)
+ .addIcon(loadIconPreviewDrawable(
+ ICON_PREVIEW_DRAWABLE_NAME,
+ iconAndroidOverlayPackage));
+ } else {
+ builder.addIcon(mContext.getResources().getDrawable(
+ Resources.getSystem().getIdentifier(
+ ICON_PREVIEW_DRAWABLE_NAME,
+ "drawable", ANDROID_PACKAGE), null));
+ }
+ }
+
+ private void addFontOverlay(Builder builder, String fontOverlayPackage)
+ throws NameNotFoundException {
+ if (!TextUtils.isEmpty(fontOverlayPackage)) {
+ builder.addOverlayPackage(getOverlayCategory(fontOverlayPackage),
+ fontOverlayPackage)
+ .setBodyFontFamily(loadTypeface(
+ ResourceConstants.CONFIG_BODY_FONT_FAMILY,
+ fontOverlayPackage))
+ .setHeadlineFontFamily(loadTypeface(
+ ResourceConstants.CONFIG_HEADLINE_FONT_FAMILY,
+ fontOverlayPackage));
+ }
+ }
+
/**
* Default theme requires different treatment: if there are overlay packages specified in the
* stub apk, we'll use those, otherwise we'll get the System default values. But we cannot skip
@@ -331,13 +361,7 @@
try {
String iconSysUiOverlayPackage = getOverlayPackage(ICON_SYSUI_PREFIX,
DEFAULT_THEME_NAME);
- if (!TextUtils.isEmpty(iconSysUiOverlayPackage)) {
- builder.addOverlayPackage(getOverlayCategory(iconSysUiOverlayPackage),
- iconSysUiOverlayPackage);
- for (String iconName : SYSUI_ICONS_FOR_PREVIEW) {
- builder.addIcon(loadIconPreviewDrawable(iconName, iconSysUiOverlayPackage));
- }
- }
+ addSysUiIconOverlay(builder, iconSysUiOverlayPackage);
} catch (NameNotFoundException | NotFoundException e) {
Log.d(TAG, "Didn't find SystemUi icons overlay for default theme, using system default",
e);
@@ -377,9 +401,41 @@
mThemes.add(builder.build());
}
+ @Override
+ public void storeCustomTheme(CustomTheme theme) {
+ mCustomizationPreferences.storeCustomTheme(theme.getSerializedPackages());
+ }
+
private void addCustomTheme() {
- mThemes.add(new CustomTheme(mContext.getString(R.string.custom_theme_title),
- new HashMap<>(), null));
+ String serializedTheme = mCustomizationPreferences.getSerializedCustomTheme();
+ if (TextUtils.isEmpty(serializedTheme)) {
+ mThemes.add(new CustomTheme(mContext.getString(R.string.custom_theme_title),
+ new HashMap<>(), null));
+ return;
+ }
+ Map<String, String> customPackages = new HashMap<>();
+ try {
+ JSONObject theme = new JSONObject(serializedTheme);
+ Iterator<String> keysIterator = theme.keys();
+
+ while (keysIterator.hasNext()) {
+ String category = keysIterator.next();
+ customPackages.put(category, theme.getString(category));
+ }
+ CustomTheme.Builder builder = new CustomTheme.Builder();
+ builder.setTitle(mContext.getString(R.string.custom_theme_title));
+ addFontOverlay(builder, customPackages.get(OVERLAY_CATEGORY_FONT));
+ addAndroidIconOverlay(builder, customPackages.get(OVERLAY_CATEGORY_ICON_ANDROID));
+ addSysUiIconOverlay(builder, customPackages.get(OVERLAY_CATEGORY_ICON_SYSUI));
+ addNoPreviewIconOverlay(builder, customPackages.get(OVERLAY_CATEGORY_ICON_SETTINGS));
+ addNoPreviewIconOverlay(builder, customPackages.get(OVERLAY_CATEGORY_ICON_LAUNCHER));
+
+ mThemes.add(builder.build());
+ } catch (JSONException | NameNotFoundException | NotFoundException e) {
+ Log.w(TAG, "Couldn't read stored custom theme, resetting", e);
+ mThemes.add(new CustomTheme(mContext.getString(R.string.custom_theme_title),
+ new HashMap<>(), null));
+ }
}
private String getOverlayPackage(String prefix, String themeName) {
diff --git a/src/com/android/customization/model/theme/OverlayManagerCompat.java b/src/com/android/customization/model/theme/OverlayManagerCompat.java
index c2e4c8e..611b23c 100644
--- a/src/com/android/customization/model/theme/OverlayManagerCompat.java
+++ b/src/com/android/customization/model/theme/OverlayManagerCompat.java
@@ -36,10 +36,12 @@
*/
public class OverlayManagerCompat {
private final OverlayManager mOverlayManager;
+ private final String[] mTargetPackages;
private Map<Integer, Map<String, List<OverlayInfo>>> mOverlayByUser;
public OverlayManagerCompat(Context context) {
mOverlayManager = context.getSystemService(OverlayManager.class);
+ mTargetPackages = ResourceConstants.getPackagesToOverlay(context);
}
/**
@@ -108,7 +110,7 @@
}
if (!mOverlayByUser.containsKey(userId)) {
Map<String, List<OverlayInfo>> overlaysByTarget = new HashMap<>();
- for (String target : ResourceConstants.DEFAULT_TARGET_PACKAGES) {
+ for (String target : mTargetPackages) {
overlaysByTarget.put(target, getOverlayInfosForTarget(target, userId));
}
mOverlayByUser.put(userId, overlaysByTarget);
diff --git a/src/com/android/customization/model/theme/ThemeBundle.java b/src/com/android/customization/model/theme/ThemeBundle.java
index 5851a23..22bde72 100644
--- a/src/com/android/customization/model/theme/ThemeBundle.java
+++ b/src/com/android/customization/model/theme/ThemeBundle.java
@@ -60,7 +60,7 @@
private final String mTitle;
private final PreviewInfo mPreviewInfo;
private final boolean mIsDefault;
- private final Map<String, String> mPackagesByCategory;
+ protected final Map<String, String> mPackagesByCategory;
@Nullable private final WallpaperInfo mWallpaperInfo;
private WallpaperInfo mOverrideWallpaper;
@@ -197,7 +197,7 @@
public static class Builder {
private static final float PATH_SIZE = 100f;
- private String mTitle;
+ protected String mTitle;
private Typeface mBodyFontFamily;
private Typeface mHeadlineFontFamily;
@ColorInt private int mColorAccentLight;
@@ -209,21 +209,25 @@
private ResourceAsset mColorPreview;
private ResourceAsset mShapePreview;
private WallpaperInfo mWallpaperInfo;
- private Map<String, String> mPackages = new HashMap<>();
+ protected Map<String, String> mPackages = new HashMap<>();
public ThemeBundle build() {
+ return new ThemeBundle(mTitle, mPackages, mIsDefault, mWallpaperInfo,
+ createPreviewInfo());
+ }
+
+ protected PreviewInfo createPreviewInfo() {
ShapeDrawable shapeDrawable = null;
if (!TextUtils.isEmpty(mShapePath)) {
PathShape shape = new PathShape(PathParser.createPathFromPathData(mShapePath),
- PATH_SIZE, PATH_SIZE);
+ PATH_SIZE, PATH_SIZE);
shapeDrawable = new ShapeDrawable(shape);
shapeDrawable.setIntrinsicHeight((int) PATH_SIZE);
shapeDrawable.setIntrinsicWidth((int) PATH_SIZE);
}
- return new ThemeBundle(mTitle, mPackages, mIsDefault, mWallpaperInfo,
- new PreviewInfo(mBodyFontFamily, mHeadlineFontFamily, mColorAccentLight,
- mColorAccentDark, mIcons, shapeDrawable, mWallpaperAsset,
- mColorPreview, mShapePreview));
+ return new PreviewInfo(mBodyFontFamily, mHeadlineFontFamily, mColorAccentLight,
+ mColorAccentDark, mIcons, shapeDrawable, mWallpaperAsset,
+ mColorPreview, mShapePreview);
}
public Builder setTitle(String title) {
diff --git a/src/com/android/customization/model/theme/ThemeBundleProvider.java b/src/com/android/customization/model/theme/ThemeBundleProvider.java
index dbcebef..ba4ee5d 100644
--- a/src/com/android/customization/model/theme/ThemeBundleProvider.java
+++ b/src/com/android/customization/model/theme/ThemeBundleProvider.java
@@ -16,6 +16,7 @@
package com.android.customization.model.theme;
import com.android.customization.model.CustomizationManager.OptionsFetchedListener;
+import com.android.customization.model.theme.custom.CustomTheme;
/**
* Interface for a class that can retrieve Themes from the system.
@@ -34,4 +35,5 @@
*/
void fetch(OptionsFetchedListener<ThemeBundle> callback, boolean reload);
+ void storeCustomTheme(CustomTheme theme);
}
diff --git a/src/com/android/customization/model/theme/ThemeManager.java b/src/com/android/customization/model/theme/ThemeManager.java
index 91192dc..ee8a6ef 100644
--- a/src/com/android/customization/model/theme/ThemeManager.java
+++ b/src/com/android/customization/model/theme/ThemeManager.java
@@ -16,7 +16,13 @@
package com.android.customization.model.theme;
import static com.android.customization.model.ResourceConstants.ANDROID_PACKAGE;
-import static com.android.customization.model.ResourceConstants.DEFAULT_TARGET_PACKAGES;
+import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_COLOR;
+import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_FONT;
+import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_ICON_ANDROID;
+import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_ICON_LAUNCHER;
+import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_ICON_SETTINGS;
+import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_ICON_SYSUI;
+import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_SHAPE;
import static com.android.customization.model.ResourceConstants.SETTINGS_PACKAGE;
import static com.android.customization.model.ResourceConstants.SYSUI_PACKAGE;
@@ -29,6 +35,7 @@
import com.android.customization.model.CustomizationManager;
import com.android.customization.model.ResourceConstants;
+import com.android.customization.model.theme.custom.CustomTheme;
import com.android.wallpaper.asset.Asset;
import com.android.wallpaper.module.WallpaperPersister;
import com.android.wallpaper.module.WallpaperPersister.SetWallpaperCallback;
@@ -43,12 +50,13 @@
private static final Set<String> THEME_CATEGORIES = new HashSet<>();
static {
- THEME_CATEGORIES.add(ResourceConstants.OVERLAY_CATEGORY_COLOR);
- THEME_CATEGORIES.add(ResourceConstants.OVERLAY_CATEGORY_FONT);
- THEME_CATEGORIES.add(ResourceConstants.OVERLAY_CATEGORY_SHAPE);
- THEME_CATEGORIES.add(ResourceConstants.OVERLAY_CATEGORY_ICON_ANDROID);
- THEME_CATEGORIES.add(ResourceConstants.OVERLAY_CATEGORY_ICON_SETTINGS);
- THEME_CATEGORIES.add(ResourceConstants.OVERLAY_CATEGORY_ICON_SYSUI);
+ THEME_CATEGORIES.add(OVERLAY_CATEGORY_COLOR);
+ THEME_CATEGORIES.add(OVERLAY_CATEGORY_FONT);
+ THEME_CATEGORIES.add(OVERLAY_CATEGORY_SHAPE);
+ THEME_CATEGORIES.add(OVERLAY_CATEGORY_ICON_ANDROID);
+ THEME_CATEGORIES.add(OVERLAY_CATEGORY_ICON_SETTINGS);
+ THEME_CATEGORIES.add(OVERLAY_CATEGORY_ICON_SYSUI);
+ THEME_CATEGORIES.add(OVERLAY_CATEGORY_ICON_LAUNCHER);
};
@@ -116,12 +124,14 @@
private void applyOverlays(ThemeBundle theme, Callback callback) {
boolean allApplied = true;
if (theme.isDefault()) {
- allApplied &= disableCurrentOverlay(ANDROID_PACKAGE, ResourceConstants.OVERLAY_CATEGORY_COLOR);
- allApplied &= disableCurrentOverlay(ANDROID_PACKAGE, ResourceConstants.OVERLAY_CATEGORY_FONT);
- allApplied &= disableCurrentOverlay(ANDROID_PACKAGE, ResourceConstants.OVERLAY_CATEGORY_SHAPE);
- allApplied &= disableCurrentOverlay(ANDROID_PACKAGE, ResourceConstants.OVERLAY_CATEGORY_ICON_ANDROID);
- allApplied &= disableCurrentOverlay(SYSUI_PACKAGE, ResourceConstants.OVERLAY_CATEGORY_ICON_SYSUI);
- allApplied &= disableCurrentOverlay(SETTINGS_PACKAGE, ResourceConstants.OVERLAY_CATEGORY_ICON_SETTINGS);
+ allApplied &= disableCurrentOverlay(ANDROID_PACKAGE, OVERLAY_CATEGORY_COLOR);
+ allApplied &= disableCurrentOverlay(ANDROID_PACKAGE, OVERLAY_CATEGORY_FONT);
+ allApplied &= disableCurrentOverlay(ANDROID_PACKAGE, OVERLAY_CATEGORY_SHAPE);
+ allApplied &= disableCurrentOverlay(ANDROID_PACKAGE, OVERLAY_CATEGORY_ICON_ANDROID);
+ allApplied &= disableCurrentOverlay(SYSUI_PACKAGE, OVERLAY_CATEGORY_ICON_SYSUI);
+ allApplied &= disableCurrentOverlay(SETTINGS_PACKAGE, OVERLAY_CATEGORY_ICON_SETTINGS);
+ allApplied &= disableCurrentOverlay(ResourceConstants.getLauncherPackage(mActivity),
+ OVERLAY_CATEGORY_ICON_LAUNCHER);
} else {
for (String packageName : theme.getAllPackages()) {
if (packageName != null) {
@@ -132,6 +142,9 @@
}
allApplied &= Settings.Secure.putString(mActivity.getContentResolver(),
ResourceConstants.THEME_SETTING, theme.getSerializedPackages());
+ if (theme instanceof CustomTheme) {
+ storeCustomTheme((CustomTheme) theme);
+ }
mCurrentOverlays = null;
if (allApplied) {
callback.onSuccess();
@@ -140,6 +153,10 @@
}
}
+ private void storeCustomTheme(CustomTheme theme) {
+ mProvider.storeCustomTheme(theme);
+ }
+
@Override
public void fetchOptions(OptionsFetchedListener<ThemeBundle> callback) {
mProvider.fetch(callback, false);
@@ -157,7 +174,7 @@
public Map<String, String> getCurrentOverlays() {
if (mCurrentOverlays == null) {
mCurrentOverlays = mOverlayManagerCompat.getEnabledOverlaysForTargets(
- DEFAULT_TARGET_PACKAGES);
+ ResourceConstants.getPackagesToOverlay(mActivity));
mCurrentOverlays.entrySet().removeIf(
categoryAndPackage -> !THEME_CATEGORIES.contains(categoryAndPackage.getKey()));
}
diff --git a/src/com/android/customization/model/theme/custom/CustomTheme.java b/src/com/android/customization/model/theme/custom/CustomTheme.java
index 982378f..aea6897 100644
--- a/src/com/android/customization/model/theme/custom/CustomTheme.java
+++ b/src/com/android/customization/model/theme/custom/CustomTheme.java
@@ -17,6 +17,9 @@
import android.view.View;
+import androidx.annotation.Nullable;
+
+import com.android.customization.model.CustomizationManager;
import com.android.customization.model.theme.ThemeBundle;
import com.android.wallpaper.R;
@@ -25,7 +28,7 @@
public class CustomTheme extends ThemeBundle {
public CustomTheme(String title, Map<String, String> overlayPackages,
- PreviewInfo previewInfo) {
+ @Nullable PreviewInfo previewInfo) {
super(title, overlayPackages, false, null, previewInfo);
}
@@ -46,7 +49,23 @@
return false;
}
+ @Override
+ public boolean isActive(CustomizationManager<ThemeBundle> manager) {
+ return isDefined() && super.isActive(manager);
+ }
+
public boolean isDefined() {
return getPreviewInfo() != null;
}
+
+ Map<String, String> getPackagesByCategory() {
+ return mPackagesByCategory;
+ }
+
+ public static class Builder extends ThemeBundle.Builder {
+ @Override
+ public CustomTheme build() {
+ return new CustomTheme(mTitle, mPackages, createPreviewInfo());
+ }
+ }
}
diff --git a/src/com/android/customization/model/theme/custom/CustomThemeManager.java b/src/com/android/customization/model/theme/custom/CustomThemeManager.java
index 0a46ecf..1613199 100644
--- a/src/com/android/customization/model/theme/custom/CustomThemeManager.java
+++ b/src/com/android/customization/model/theme/custom/CustomThemeManager.java
@@ -15,21 +15,50 @@
*/
package com.android.customization.model.theme.custom;
+import android.content.Context;
+
+import androidx.annotation.Nullable;
+
import com.android.customization.model.CustomizationManager;
+import com.android.wallpaper.R;
+
+import java.util.HashMap;
+import java.util.Map;
public class CustomThemeManager implements CustomizationManager<ThemeComponentOption> {
- @Override
- public boolean isAvailable() {
- return false;
+
+ private final Map<String, String> overlayPackages = new HashMap<>();
+
+ public CustomThemeManager(@Nullable CustomTheme existingTheme) {
+ if (existingTheme != null && existingTheme.isDefined()) {
+ overlayPackages.putAll(existingTheme.getPackagesByCategory());
+ }
}
@Override
- public void apply(ThemeComponentOption option, Callback callback) {
+ public boolean isAvailable() {
+ return true;
+ }
+ @Override
+ public void apply(ThemeComponentOption option, @Nullable Callback callback) {
+ overlayPackages.putAll(option.getOverlayPackages());
+ if (callback != null) {
+ callback.onSuccess();
+ }
+ }
+
+ public Map<String, String> getOverlayPackages() {
+ return overlayPackages;
+ }
+
+ public CustomTheme buildPartialCustomTheme(Context context) {
+ return new CustomTheme(context.getString(R.string.custom_theme_title),
+ overlayPackages, null);
}
@Override
public void fetchOptions(OptionsFetchedListener<ThemeComponentOption> callback) {
-
+ //Unused
}
}
diff --git a/src/com/android/customization/model/theme/custom/IconOptionsProvider.java b/src/com/android/customization/model/theme/custom/IconOptionsProvider.java
index 6c85fc8..6850e90 100644
--- a/src/com/android/customization/model/theme/custom/IconOptionsProvider.java
+++ b/src/com/android/customization/model/theme/custom/IconOptionsProvider.java
@@ -16,9 +16,9 @@
package com.android.customization.model.theme.custom;
import static com.android.customization.model.ResourceConstants.ANDROID_PACKAGE;
-import static com.android.customization.model.ResourceConstants.DEFAULT_TARGET_PACKAGES;
import static com.android.customization.model.ResourceConstants.ICON_PREVIEW_DRAWABLE_NAME;
import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_ICON_ANDROID;
+import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_ICON_LAUNCHER;
import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_ICON_SETTINGS;
import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_ICON_SYSUI;
import static com.android.customization.model.ResourceConstants.SYSUI_ICONS_FOR_PREVIEW;
@@ -32,6 +32,7 @@
import android.os.UserHandle;
import android.util.Log;
+import com.android.customization.model.ResourceConstants;
import com.android.customization.model.theme.OverlayManagerCompat;
import com.android.customization.model.theme.custom.ThemeComponentOption.IconOption;
import com.android.wallpaper.R;
@@ -51,13 +52,17 @@
private final List<String> mSysUiIconsOverlayPackages = new ArrayList<>();
private final List<String> mSettingsIconsOverlayPackages = new ArrayList<>();
+ private final List<String> mLauncherIconsOverlayPackages = new ArrayList<>();
public IconOptionsProvider(Context context, OverlayManagerCompat manager) {
super(context, manager, OVERLAY_CATEGORY_ICON_ANDROID);
+ String[] targetPackages = ResourceConstants.getPackagesToOverlay(context);
mSysUiIconsOverlayPackages.addAll(manager.getOverlayPackagesForCategory(
- OVERLAY_CATEGORY_ICON_SYSUI, UserHandle.myUserId(), DEFAULT_TARGET_PACKAGES));
+ OVERLAY_CATEGORY_ICON_SYSUI, UserHandle.myUserId(), targetPackages));
mSettingsIconsOverlayPackages.addAll(manager.getOverlayPackagesForCategory(
- OVERLAY_CATEGORY_ICON_SETTINGS, UserHandle.myUserId(), DEFAULT_TARGET_PACKAGES));
+ OVERLAY_CATEGORY_ICON_SETTINGS, UserHandle.myUserId(), targetPackages));
+ mLauncherIconsOverlayPackages.addAll(manager.getOverlayPackagesForCategory(
+ OVERLAY_CATEGORY_ICON_LAUNCHER, UserHandle.myUserId(), targetPackages));
}
@Override
@@ -93,8 +98,12 @@
addOrUpdateOption(optionsByPrefix, overlayPackage, OVERLAY_CATEGORY_ICON_SETTINGS);
}
+ for (String overlayPackage : mLauncherIconsOverlayPackages) {
+ addOrUpdateOption(optionsByPrefix, overlayPackage, OVERLAY_CATEGORY_ICON_LAUNCHER);
+ }
+
for (IconOption option : optionsByPrefix.values()) {
- if (option.isValid()) {
+ if (option.isValid(mContext)) {
mOptions.add(option);
option.setLabel(mContext.getString(R.string.icon_component_label, mOptions.size()));
}
diff --git a/src/com/android/customization/model/theme/custom/ThemeComponentOption.java b/src/com/android/customization/model/theme/custom/ThemeComponentOption.java
index f973ac5..33dfc2f 100644
--- a/src/com/android/customization/model/theme/custom/ThemeComponentOption.java
+++ b/src/com/android/customization/model/theme/custom/ThemeComponentOption.java
@@ -15,12 +15,12 @@
*/
package com.android.customization.model.theme.custom;
-import static com.android.customization.model.ResourceConstants.DEFAULT_TARGET_PACKAGES;
import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_COLOR;
import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_FONT;
import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_SHAPE;
import static com.android.customization.model.ResourceConstants.SYSUI_ICONS_FOR_PREVIEW;
+import android.content.Context;
import android.content.res.Resources;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
@@ -32,12 +32,14 @@
import com.android.customization.model.CustomizationManager;
import com.android.customization.model.CustomizationOption;
+import com.android.customization.model.ResourceConstants;
import com.android.wallpaper.R;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
/**
* Represents an option of a component of a custom Theme (for example, a possible color, or font,
@@ -53,7 +55,7 @@
mOverlayPackageNames.put(category, packageName);
}
- public Map<String, String> getOverlayPackageNames() {
+ public Map<String, String> getOverlayPackages() {
return mOverlayPackageNames;
}
@@ -91,7 +93,9 @@
@Override
public boolean isActive(CustomizationManager<ThemeComponentOption> manager) {
- return false;
+ CustomThemeManager customThemeManager = (CustomThemeManager) manager;
+ return Objects.equals(getOverlayPackages().get(OVERLAY_CATEGORY_FONT),
+ customThemeManager.getOverlayPackages().get(OVERLAY_CATEGORY_FONT));
}
@Override
@@ -140,7 +144,14 @@
@Override
public boolean isActive(CustomizationManager<ThemeComponentOption> manager) {
- return false;
+ CustomThemeManager customThemeManager = (CustomThemeManager) manager;
+ for (Map.Entry<String, String> overlayEntry : getOverlayPackages().entrySet()) {
+ if(!Objects.equals(overlayEntry.getValue(),
+ customThemeManager.getOverlayPackages().get(overlayEntry.getKey()))) {
+ return false;
+ }
+ }
+ return true;
}
@Override
@@ -169,8 +180,12 @@
mIcons.add(previewIcon);
}
- public boolean isValid() {
- return getOverlayPackageNames().keySet().size() == DEFAULT_TARGET_PACKAGES.length
+ /**
+ * @return whether this icon option has overlays and previews for all the required packages
+ */
+ public boolean isValid(Context context) {
+ return getOverlayPackages().keySet().size() ==
+ ResourceConstants.getPackagesToOverlay(context).length
&& mIcons.size() == SYSUI_ICONS_FOR_PREVIEW.length + 1;
}
diff --git a/src/com/android/customization/model/theme/custom/ThemeComponentOptionProvider.java b/src/com/android/customization/model/theme/custom/ThemeComponentOptionProvider.java
index 316ee99..992c47c 100644
--- a/src/com/android/customization/model/theme/custom/ThemeComponentOptionProvider.java
+++ b/src/com/android/customization/model/theme/custom/ThemeComponentOptionProvider.java
@@ -15,14 +15,13 @@
*/
package com.android.customization.model.theme.custom;
-import static com.android.customization.model.ResourceConstants.DEFAULT_TARGET_PACKAGES;
-
import android.content.Context;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Resources;
import android.os.UserHandle;
import com.android.customization.model.CustomizationManager.OptionsFetchedListener;
+import com.android.customization.model.ResourceConstants;
import com.android.customization.model.theme.OverlayManagerCompat;
import java.util.ArrayList;
@@ -44,7 +43,7 @@
mOverlayPackages = new ArrayList<>();
for (String category : categories) {
mOverlayPackages.addAll(manager.getOverlayPackagesForCategory(category,
- UserHandle.myUserId(), DEFAULT_TARGET_PACKAGES));
+ UserHandle.myUserId(), ResourceConstants.getPackagesToOverlay(mContext)));
}
}
diff --git a/src/com/android/customization/module/CustomizationInjector.java b/src/com/android/customization/module/CustomizationInjector.java
new file mode 100644
index 0000000..90333f0
--- /dev/null
+++ b/src/com/android/customization/module/CustomizationInjector.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.customization.module;
+
+import android.content.Context;
+
+import com.android.wallpaper.module.Injector;
+
+public interface CustomizationInjector extends Injector {
+
+ CustomizationPreferences getCustomizationPreferences(Context context);
+}
diff --git a/src/com/android/customization/module/CustomizationPreferences.java b/src/com/android/customization/module/CustomizationPreferences.java
new file mode 100644
index 0000000..2692946
--- /dev/null
+++ b/src/com/android/customization/module/CustomizationPreferences.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.customization.module;
+
+import com.android.wallpaper.module.WallpaperPreferences;
+
+public interface CustomizationPreferences extends WallpaperPreferences {
+
+ String KEY_CUSTOM_THEME= "themepicker_custom_theme";
+
+ String getSerializedCustomTheme();
+
+ void storeCustomTheme(String serializedCustomTheme);
+}
diff --git a/src/com/android/customization/module/DefaultCustomizationInjector.java b/src/com/android/customization/module/DefaultCustomizationInjector.java
new file mode 100644
index 0000000..a5a3626
--- /dev/null
+++ b/src/com/android/customization/module/DefaultCustomizationInjector.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.customization.module;
+
+import android.content.Context;
+
+import androidx.fragment.app.Fragment;
+
+import com.android.wallpaper.model.CategoryProvider;
+import com.android.wallpaper.model.WallpaperInfo;
+import com.android.wallpaper.module.BaseWallpaperInjector;
+import com.android.wallpaper.module.DefaultCategoryProvider;
+import com.android.wallpaper.module.LoggingOptInStatusProvider;
+import com.android.wallpaper.module.NoOpUserEventLogger;
+import com.android.wallpaper.module.UserEventLogger;
+import com.android.wallpaper.module.WallpaperPreferences;
+import com.android.wallpaper.module.WallpaperRotationRefresher;
+import com.android.wallpaper.monitor.PerformanceMonitor;
+import com.android.wallpaper.picker.PreviewFragment;
+
+public class DefaultCustomizationInjector extends BaseWallpaperInjector
+ implements CustomizationInjector {
+ private CategoryProvider mCategoryProvider;
+ private UserEventLogger mUserEventLogger;
+ private WallpaperRotationRefresher mWallpaperRotationRefresher;
+ private PerformanceMonitor mPerformanceMonitor;
+ private WallpaperPreferences mPrefs;
+
+ @Override
+ public synchronized WallpaperPreferences getPreferences(Context context) {
+ if (mPrefs == null) {
+ mPrefs = new DefaultCustomizationPreferences(context.getApplicationContext());
+ }
+ return mPrefs;
+ }
+
+
+ @Override
+ public CustomizationPreferences getCustomizationPreferences(Context context) {
+ return (CustomizationPreferences) getPreferences(context);
+ }
+
+ @Override
+ public synchronized CategoryProvider getCategoryProvider(Context context) {
+ if (mCategoryProvider == null) {
+ mCategoryProvider = new DefaultCategoryProvider(context.getApplicationContext());
+ }
+ return mCategoryProvider;
+ }
+
+ @Override
+ public synchronized UserEventLogger getUserEventLogger(Context context) {
+ if (mUserEventLogger == null) {
+ mUserEventLogger = new NoOpUserEventLogger();
+ }
+ return mUserEventLogger;
+ }
+
+ @Override
+ public synchronized WallpaperRotationRefresher getWallpaperRotationRefresher() {
+ if (mWallpaperRotationRefresher == null) {
+ mWallpaperRotationRefresher = new WallpaperRotationRefresher() {
+ @Override
+ public void refreshWallpaper(Context context, Listener listener) {
+ // Not implemented
+ listener.onError();
+ }
+ };
+ }
+ return mWallpaperRotationRefresher;
+ }
+
+ @Override
+ public Fragment getPreviewFragment(
+ WallpaperInfo wallpaperInfo,
+ int mode,
+ boolean testingModeEnabled) {
+ return PreviewFragment.newInstance(wallpaperInfo, mode, testingModeEnabled);
+ }
+
+ @Override
+ public synchronized PerformanceMonitor getPerformanceMonitor() {
+ if (mPerformanceMonitor == null) {
+ mPerformanceMonitor = new PerformanceMonitor() {
+ @Override
+ public void recordFullResPreviewLoadedMemorySnapshot() {
+ // No Op
+ }
+ };
+ }
+ return mPerformanceMonitor;
+ }
+
+ @Override
+ public synchronized LoggingOptInStatusProvider getLoggingOptInStatusProvider(Context context) {
+ return null;
+ }
+
+}
diff --git a/src/com/android/customization/module/DefaultCustomizationPreferences.java b/src/com/android/customization/module/DefaultCustomizationPreferences.java
new file mode 100644
index 0000000..22220d3
--- /dev/null
+++ b/src/com/android/customization/module/DefaultCustomizationPreferences.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.customization.module;
+
+import android.content.Context;
+
+import com.android.wallpaper.module.DefaultWallpaperPreferences;
+
+public class DefaultCustomizationPreferences extends DefaultWallpaperPreferences
+ implements CustomizationPreferences {
+
+ public DefaultCustomizationPreferences(Context context) {
+ super(context);
+ }
+
+
+ @Override
+ public String getSerializedCustomTheme() {
+ return mSharedPrefs.getString(KEY_CUSTOM_THEME, null);
+ }
+
+ @Override
+ public void storeCustomTheme(String serializedCustomTheme) {
+ mSharedPrefs.edit().putString(KEY_CUSTOM_THEME, serializedCustomTheme).apply();
+ }
+}
diff --git a/src/com/android/customization/picker/CustomizationPickerActivity.java b/src/com/android/customization/picker/CustomizationPickerActivity.java
index de19aa7..70c0d82 100644
--- a/src/com/android/customization/picker/CustomizationPickerActivity.java
+++ b/src/com/android/customization/picker/CustomizationPickerActivity.java
@@ -43,6 +43,7 @@
import com.android.customization.model.theme.OverlayManagerCompat;
import com.android.customization.model.theme.ThemeBundle;
import com.android.customization.model.theme.ThemeManager;
+import com.android.customization.module.CustomizationInjector;
import com.android.customization.picker.clock.ClockFragment;
import com.android.customization.picker.clock.ClockFragment.ClockFragmentHost;
import com.android.customization.picker.grid.GridFragment;
@@ -156,10 +157,12 @@
return;
}
//Theme
- Injector injector = InjectorProvider.getInjector();
+ CustomizationInjector injector = (CustomizationInjector) InjectorProvider.getInjector();
mWallpaperSetter = new WallpaperSetter(injector.getWallpaperPersister(this),
injector.getPreferences(this), mUserEventLogger, false);
- ThemeManager themeManager = new ThemeManager(new DefaultThemeProvider(this), this,
+ ThemeManager themeManager = new ThemeManager(
+ new DefaultThemeProvider(this, injector.getCustomizationPreferences(this)),
+ this,
mWallpaperSetter, new OverlayManagerCompat(this));
if (themeManager.isAvailable()) {
mSections.put(R.id.nav_theme, new ThemeSection(R.id.nav_theme, themeManager));
diff --git a/src/com/android/customization/picker/CustomizationPickerApplication.java b/src/com/android/customization/picker/CustomizationPickerApplication.java
new file mode 100644
index 0000000..79d075a
--- /dev/null
+++ b/src/com/android/customization/picker/CustomizationPickerApplication.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.customization.picker;
+
+import android.app.Application;
+
+import com.android.customization.module.DefaultCustomizationInjector;
+import com.android.wallpaper.module.InjectorProvider;
+
+public class CustomizationPickerApplication extends Application {
+ @Override
+ public void onCreate() {
+ super.onCreate();
+
+ // Initialize the injector.
+ InjectorProvider.setInjector(new DefaultCustomizationInjector());
+ }
+}
diff --git a/src/com/android/customization/picker/theme/CustomThemeActivity.java b/src/com/android/customization/picker/theme/CustomThemeActivity.java
index 1b668d9..9d0c7bb 100644
--- a/src/com/android/customization/picker/theme/CustomThemeActivity.java
+++ b/src/com/android/customization/picker/theme/CustomThemeActivity.java
@@ -16,15 +16,21 @@
package com.android.customization.picker.theme;
import android.os.Bundle;
+import android.util.Log;
import android.widget.TextView;
+import android.widget.Toast;
+import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
+import com.android.customization.model.CustomizationManager.Callback;
+import com.android.customization.model.theme.DefaultThemeProvider;
import com.android.customization.model.theme.OverlayManagerCompat;
+import com.android.customization.model.theme.ThemeManager;
import com.android.customization.model.theme.custom.CustomThemeManager;
import com.android.customization.model.theme.custom.FontOptionsProvider;
import com.android.customization.model.theme.custom.IconOptionsProvider;
@@ -32,28 +38,39 @@
import com.android.customization.model.theme.custom.ThemeComponentOption.FontOption;
import com.android.customization.model.theme.custom.ThemeComponentOption.IconOption;
import com.android.customization.model.theme.custom.ThemeComponentOptionProvider;
+import com.android.customization.module.CustomizationInjector;
import com.android.customization.picker.theme.CustomThemeComponentFragment.CustomThemeComponentFragmentHost;
import com.android.wallpaper.R;
-import com.android.wallpaper.module.Injector;
import com.android.wallpaper.module.InjectorProvider;
import com.android.wallpaper.module.UserEventLogger;
+import com.android.wallpaper.module.WallpaperSetter;
import java.util.ArrayList;
import java.util.List;
public class CustomThemeActivity extends FragmentActivity implements
CustomThemeComponentFragmentHost {
+ private static final String TAG = "CustomThemeActivity";
private UserEventLogger mUserEventLogger;
private List<ComponentStep<?>> mSteps;
private int mCurrentStep;
+ private CustomThemeManager mCustomThemeManager;
+ private ThemeManager mThemeManager;
private TextView mApplyButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- Injector injector = InjectorProvider.getInjector();
+ CustomizationInjector injector = (CustomizationInjector) InjectorProvider.getInjector();
mUserEventLogger = injector.getUserEventLogger(this);
+ mCustomThemeManager = new CustomThemeManager(null);
+ mThemeManager = new ThemeManager(
+ new DefaultThemeProvider(this, injector.getCustomizationPreferences(this)),
+ this,
+ new WallpaperSetter(injector.getWallpaperPersister(this),
+ injector.getPreferences(this), mUserEventLogger, false),
+ new OverlayManagerCompat(this));
setContentView(R.layout.activity_custom_theme);
mApplyButton = findViewById(R.id.next_button);
mApplyButton.setOnClickListener(view -> onNextOrApply());
@@ -92,11 +109,47 @@
}
private void onNextOrApply() {
- if (mCurrentStep < mSteps.size() - 1) {
- // TODO: gather current step's selection
- navigateToStep(mCurrentStep + 1);
- }
- // TODO: handle Apply
+ mCustomThemeManager.apply(getCurrentStepFragment().getSelectedOption(), new Callback() {
+ @Override
+ public void onSuccess() {
+ if (mCurrentStep < mSteps.size() - 1) {
+ navigateToStep(mCurrentStep + 1);
+ } else {
+ // We're on the last step, apply theme and leave
+ // TODO: Verify that custom theme doesn't collide with existing one
+ // (compare overlay packages)
+ mThemeManager.apply(mCustomThemeManager.buildPartialCustomTheme(
+ CustomThemeActivity.this), new Callback() {
+ @Override
+ public void onSuccess() {
+ Toast.makeText(CustomThemeActivity.this, R.string.applied_theme_msg,
+ Toast.LENGTH_LONG).show();
+ finish();
+ }
+
+ @Override
+ public void onError(@Nullable Throwable throwable) {
+ Log.w(TAG, "Error applying custom theme", throwable);
+ Toast.makeText(CustomThemeActivity.this,
+ R.string.apply_theme_error_msg,
+ Toast.LENGTH_LONG).show();
+ }
+ });
+ }
+ }
+
+ @Override
+ public void onError(@Nullable Throwable throwable) {
+ Log.w(TAG, "Error applying custom theme component", throwable);
+ Toast.makeText(CustomThemeActivity.this, R.string.apply_theme_error_msg,
+ Toast.LENGTH_LONG).show();
+ }
+ });
+ }
+
+ private CustomThemeComponentFragment getCurrentStepFragment() {
+ return (CustomThemeComponentFragment)
+ getSupportFragmentManager().findFragmentById(R.id.fragment_container);
}
@Override
@@ -128,7 +181,7 @@
@Override
public CustomThemeManager getCustomThemeManager() {
- return null;
+ return mCustomThemeManager;
}
/**
diff --git a/src/com/android/customization/picker/theme/CustomThemeComponentFragment.java b/src/com/android/customization/picker/theme/CustomThemeComponentFragment.java
index d2dcd61..eda44c9 100644
--- a/src/com/android/customization/picker/theme/CustomThemeComponentFragment.java
+++ b/src/com/android/customization/picker/theme/CustomThemeComponentFragment.java
@@ -116,6 +116,10 @@
mHost.setCurrentStep(mPosition);
}
+ public ThemeComponentOption getSelectedOption() {
+ return mSelectedOption;
+ }
+
private void bindPreview() {
mSelectedOption.bindPreview(mPreviewCard);
}