Merge "Theme picker polish fixes." into ub-launcher3-qt-dev
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 8f1ecdd..217b0ef 100755
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -67,7 +67,7 @@
<string name="option_previewed_description"><xliff:g name="style_name">%1$s</xliff:g>, currently previewed</string>
<!-- Sample text used to show a preview of a selected font [CHAR LIMIT=3] -->
- <string name="theme_font_example">ABC</string>
+ <string name="theme_font_example" translatable="false">ABC</string>
<!-- Content description for previewing a style, describing each of their components. [CHAR_LIMIT=NONE] -->
<string name="theme_description">Font: <xliff:g name="font_name">%1$s</xliff:g>, icons: <xliff:g name="icon_name">%2$s</xliff:g>, shape: <xliff:g name="shape_name">%3$s</xliff:g>, color: <xliff:g name="color_name">%4$s</xliff:g> </string>
diff --git a/src/com/android/customization/model/theme/DefaultThemeProvider.java b/src/com/android/customization/model/theme/DefaultThemeProvider.java
index a4f9a31..c1c6bbe 100644
--- a/src/com/android/customization/model/theme/DefaultThemeProvider.java
+++ b/src/com/android/customization/model/theme/DefaultThemeProvider.java
@@ -86,6 +86,8 @@
private static final String WALLPAPER_ACTION_PREFIX = "theme_wallpaper_action_";
private static final String DEFAULT_THEME_NAME= "default";
+ private static final String THEME_TITLE_FIELD = "_theme_title";
+ private static final String THEME_ID_FIELD = "_theme_id";
private final OverlayThemeExtractor mOverlayProvider;
private List<ThemeBundle> mThemes;
@@ -306,23 +308,41 @@
}
private void addCustomThemeAndStore(CustomTheme theme) {
- mThemes.add(theme);
+ if (!mThemes.contains(theme)) {
+ mThemes.add(theme);
+ } else {
+ mThemes.replaceAll(t -> theme.equals(t) ? theme : t);
+ }
JSONArray themesArray = new JSONArray();
mThemes.stream()
.filter(themeBundle -> themeBundle instanceof CustomTheme
&& !themeBundle.getPackagesByCategory().isEmpty())
- .forEachOrdered(themeBundle -> themesArray.put(themeBundle.getJsonPackages()));
+ .forEachOrdered(themeBundle -> addThemeBundleToArray(themesArray, themeBundle));
mCustomizationPreferences.storeCustomThemes(themesArray.toString());
}
+ private void addThemeBundleToArray(JSONArray themesArray, ThemeBundle themeBundle) {
+ JSONObject jsonPackages = themeBundle.getJsonPackages();
+ try {
+ jsonPackages.put(THEME_TITLE_FIELD, themeBundle.getTitle());
+ if (themeBundle instanceof CustomTheme) {
+ jsonPackages.put(THEME_ID_FIELD, ((CustomTheme)themeBundle).getId());
+ }
+ } catch (JSONException e) {
+ Log.w("Exception saving theme's title", e);
+ }
+ themesArray.put(jsonPackages);
+ }
+
@Override
public void removeCustomTheme(CustomTheme theme) {
JSONArray themesArray = new JSONArray();
mThemes.stream()
- .filter(themeBundle -> themeBundle instanceof CustomTheme)
- .forEachOrdered(themeBundle -> {
- if (!themeBundle.equals(theme)) {
- themesArray.put(themeBundle.getJsonPackages());
+ .filter(themeBundle -> themeBundle instanceof CustomTheme
+ && ((CustomTheme) themeBundle).isDefined())
+ .forEachOrdered(customTheme -> {
+ if (!customTheme.equals(theme)) {
+ addThemeBundleToArray(themesArray, customTheme);
}
});
mCustomizationPreferences.storeCustomThemes(themesArray.toString());
@@ -335,40 +355,43 @@
try {
JSONArray customThemes = new JSONArray(serializedThemes);
for (int i = 0; i < customThemes.length(); i++) {
- ThemeBundle.Builder builder = convertJsonToBuilder(
- customThemes.getJSONObject(i));
+ JSONObject jsonTheme = customThemes.getJSONObject(i);
+ ThemeBundle.Builder builder = convertJsonToBuilder(jsonTheme);
if (builder != null) {
- builder.setTitle(mContext.getString(R.string.custom_theme_title,
- customThemesCount + 1));
+ if (TextUtils.isEmpty(builder.getTitle())) {
+ builder.setTitle(mContext.getString(R.string.custom_theme_title,
+ customThemesCount + 1));
+ }
mThemes.add(builder.build(mContext));
} else {
Log.w(TAG, "Couldn't read stored custom theme, resetting");
- mThemes.add(new CustomTheme(mContext.getString(R.string.custom_theme_title,
+ mThemes.add(new CustomTheme(CustomTheme.newId(),
+ mContext.getString(R.string.custom_theme_title,
customThemesCount + 1), new HashMap<>(), null));
}
customThemesCount++;
}
} catch (JSONException e) {
Log.w(TAG, "Couldn't read stored custom theme, resetting", e);
- mThemes.add(new CustomTheme(mContext.getString(R.string.custom_theme_title,
+ mThemes.add(new CustomTheme(CustomTheme.newId(), mContext.getString(R.string.custom_theme_title,
customThemesCount + 1), new HashMap<>(), null));
}
}
// Add an empty one at the end.
- mThemes.add(new CustomTheme(mContext.getString(R.string.custom_theme_title,
+ mThemes.add(new CustomTheme(CustomTheme.newId(), mContext.getString(R.string.custom_theme_title,
customThemesCount + 1), new HashMap<>(), null));
}
@Override
- public Builder parseCustomTheme(String serializedTheme) throws JSONException {
+ public CustomTheme.Builder parseCustomTheme(String serializedTheme) throws JSONException {
JSONObject theme = new JSONObject(serializedTheme);
return convertJsonToBuilder(theme);
}
@Nullable
- private Builder convertJsonToBuilder(JSONObject theme) throws JSONException {
+ private CustomTheme.Builder convertJsonToBuilder(JSONObject theme) throws JSONException {
try {
Map<String, String> customPackages = new HashMap<>();
Iterator<String> keysIterator = theme.keys();
@@ -394,7 +417,12 @@
customPackages.get(OVERLAY_CATEGORY_ICON_LAUNCHER));
mOverlayProvider.addNoPreviewIconOverlay(builder,
customPackages.get(OVERLAY_CATEGORY_ICON_THEMEPICKER));
-
+ if (theme.has(THEME_TITLE_FIELD)) {
+ builder.setTitle(theme.getString(THEME_TITLE_FIELD));
+ }
+ if (theme.has(THEME_ID_FIELD)) {
+ builder.setId(theme.getString(THEME_ID_FIELD));
+ }
return builder;
} catch (NameNotFoundException | NotFoundException e) {
Log.i(TAG, "Couldn't parse serialized custom theme", e);
diff --git a/src/com/android/customization/model/theme/ThemeBundle.java b/src/com/android/customization/model/theme/ThemeBundle.java
index ad21405..9d2f397 100644
--- a/src/com/android/customization/model/theme/ThemeBundle.java
+++ b/src/com/android/customization/model/theme/ThemeBundle.java
@@ -332,6 +332,10 @@
mWallpaperAsset, shapeIcons);
}
+ public String getTitle() {
+ return mTitle;
+ }
+
public Builder setTitle(String title) {
mTitle = title;
return this;
diff --git a/src/com/android/customization/model/theme/ThemeBundleProvider.java b/src/com/android/customization/model/theme/ThemeBundleProvider.java
index 578b96c..fac11cd 100644
--- a/src/com/android/customization/model/theme/ThemeBundleProvider.java
+++ b/src/com/android/customization/model/theme/ThemeBundleProvider.java
@@ -18,7 +18,6 @@
import androidx.annotation.Nullable;
import com.android.customization.model.CustomizationManager.OptionsFetchedListener;
-import com.android.customization.model.theme.ThemeBundle.Builder;
import com.android.customization.model.theme.custom.CustomTheme;
import org.json.JSONException;
@@ -44,7 +43,7 @@
void removeCustomTheme(CustomTheme theme);
- @Nullable Builder parseCustomTheme(String serializedTheme) throws JSONException;
+ @Nullable CustomTheme.Builder parseCustomTheme(String serializedTheme) throws JSONException;
ThemeBundle findEquivalent(ThemeBundle other);
}
diff --git a/src/com/android/customization/model/theme/custom/CustomTheme.java b/src/com/android/customization/model/theme/custom/CustomTheme.java
index 5e809a0..15e4eb8 100644
--- a/src/com/android/customization/model/theme/custom/CustomTheme.java
+++ b/src/com/android/customization/model/theme/custom/CustomTheme.java
@@ -18,6 +18,7 @@
import android.content.Context;
import android.view.View;
+import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.customization.model.CustomizationManager;
@@ -25,12 +26,38 @@
import com.android.wallpaper.R;
import java.util.Map;
+import java.util.UUID;
public class CustomTheme extends ThemeBundle {
- public CustomTheme(String title, Map<String, String> overlayPackages,
+ public static String newId() {
+ return UUID.randomUUID().toString();
+ }
+
+ private final String mId;
+
+ public CustomTheme(@NonNull String id, String title, Map<String, String> overlayPackages,
@Nullable PreviewInfo previewInfo) {
super(title, overlayPackages, false, null, previewInfo);
+ mId = id;
+ }
+
+ public String getId() {
+ return mId;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof CustomTheme)) {
+ return false;
+ }
+ CustomTheme other = (CustomTheme) obj;
+ return mId.equals(other.mId);
+ }
+
+ @Override
+ public int hashCode() {
+ return mId.hashCode();
}
@Override
@@ -60,9 +87,16 @@
}
public static class Builder extends ThemeBundle.Builder {
+ private String mId;
+
@Override
public CustomTheme build(Context context) {
- return new CustomTheme(mTitle, mPackages, createPreviewInfo(context));
+ return new CustomTheme(mId, mTitle, mPackages, createPreviewInfo(context));
+ }
+
+ public Builder setId(String id) {
+ mId = id;
+ return this;
}
}
}
diff --git a/src/com/android/customization/model/theme/custom/CustomThemeManager.java b/src/com/android/customization/model/theme/custom/CustomThemeManager.java
index 5463eb0..0cc0161 100644
--- a/src/com/android/customization/model/theme/custom/CustomThemeManager.java
+++ b/src/com/android/customization/model/theme/custom/CustomThemeManager.java
@@ -16,6 +16,7 @@
package com.android.customization.model.theme.custom;
import android.content.Context;
+import android.text.TextUtils;
import androidx.annotation.Nullable;
@@ -44,7 +45,11 @@
@Override
public void apply(ThemeComponentOption option, @Nullable Callback callback) {
- mOverlayPackages.putAll(option.getOverlayPackages());
+ option.getOverlayPackages().forEach((category, packageName) -> {
+ if (!TextUtils.isEmpty(packageName)) {
+ mOverlayPackages.put(category, packageName);
+ }
+ });
if (callback != null) {
callback.onSuccess();
}
@@ -54,8 +59,8 @@
return mOverlayPackages;
}
- public CustomTheme buildPartialCustomTheme(String title) {
- return new CustomTheme(title, mOverlayPackages, null);
+ public CustomTheme buildPartialCustomTheme(String id, String title) {
+ return new CustomTheme(id, title, mOverlayPackages, null);
}
@Override
@@ -73,6 +78,6 @@
return new CustomThemeManager(customTheme.getPackagesByCategory(), customTheme);
}
// Seed the first custom theme with the currently applied theme.
- return new CustomThemeManager(themeManager.getCurrentOverlays(), null);
+ return new CustomThemeManager(themeManager.getCurrentOverlays(), customTheme);
}
}
diff --git a/src/com/android/customization/picker/theme/CustomThemeActivity.java b/src/com/android/customization/picker/theme/CustomThemeActivity.java
index 8cccd54..0ea9617 100644
--- a/src/com/android/customization/picker/theme/CustomThemeActivity.java
+++ b/src/com/android/customization/picker/theme/CustomThemeActivity.java
@@ -63,6 +63,7 @@
public class CustomThemeActivity extends FragmentActivity implements
CustomThemeComponentFragmentHost {
+ public static final String EXTRA_THEME_ID = "CustomThemeActivity.ThemeId";
public static final String EXTRA_THEME_TITLE = "CustomThemeActivity.ThemeTitle";
public static final String EXTRA_THEME_PACKAGES = "CustomThemeActivity.ThemePackages";
public static final int REQUEST_CODE_CUSTOM_THEME = 1;
@@ -87,16 +88,16 @@
Intent intent = getIntent();
CustomTheme customTheme = null;
if (intent != null && intent.hasExtra(EXTRA_THEME_PACKAGES)
- && intent.hasExtra(EXTRA_THEME_TITLE)) {
+ && intent.hasExtra(EXTRA_THEME_TITLE) && intent.hasExtra(EXTRA_THEME_ID)) {
ThemeBundleProvider themeProvider =
new DefaultThemeProvider(this, injector.getCustomizationPreferences(this));
- Builder themeBuilder = null;
try {
- themeBuilder = themeProvider.parseCustomTheme(
+ CustomTheme.Builder themeBuilder = themeProvider.parseCustomTheme(
intent.getStringExtra(EXTRA_THEME_PACKAGES));
if (themeBuilder != null) {
+ themeBuilder.setId(intent.getStringExtra(EXTRA_THEME_ID));
themeBuilder.setTitle(intent.getStringExtra(EXTRA_THEME_TITLE));
- customTheme = (CustomTheme) themeBuilder.build(this);
+ customTheme = themeBuilder.build(this);
}
} catch (JSONException e) {
Log.w(TAG, "Couldn't parse provided custom theme, will override it");
@@ -143,7 +144,7 @@
private void navigateToStep(int i) {
FragmentManager fragmentManager = getSupportFragmentManager();
ComponentStep step = mSteps.get(i);
- Fragment fragment = step.getFragment();
+ Fragment fragment = step.getFragment(mCustomThemeManager.getOriginalTheme().getTitle());
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.fragment_container, fragment);
@@ -178,16 +179,12 @@
// We're on the last step, apply theme and leave
CustomTheme themeToApply = mCustomThemeManager.buildPartialCustomTheme(
- originalTheme != null
- ? originalTheme.getTitle()
- : getString(R.string.custom_theme_title,
- 0));
+ originalTheme.getId(), originalTheme.getTitle());
// If the current theme is equal to the original theme being edited, then
// don't search for an equivalent, let the user apply the same one by keeping
// it null.
- ThemeBundle equivalent = (originalTheme != null
- && originalTheme.isEquivalent(themeToApply))
+ ThemeBundle equivalent = (originalTheme.isEquivalent(themeToApply))
? null : mThemeManager.findThemeByPackages(themeToApply);
if (equivalent != null) {
@@ -296,9 +293,9 @@
this.position = position;
}
- CustomThemeComponentFragment getFragment() {
+ CustomThemeComponentFragment getFragment(String title) {
if (mFragment == null) {
- mFragment = createFragment();
+ mFragment = createFragment(title);
}
return mFragment;
}
@@ -306,7 +303,7 @@
/**
* @return a newly created fragment that will handle this step's UI.
*/
- abstract CustomThemeComponentFragment createFragment();
+ abstract CustomThemeComponentFragment createFragment(String title);
}
private class FontStep extends ComponentStep<FontOption> {
@@ -317,9 +314,9 @@
}
@Override
- CustomThemeComponentFragment createFragment() {
+ CustomThemeComponentFragment createFragment(String title) {
return CustomThemeComponentFragment.newInstance(
- CustomThemeActivity.this.getString(R.string.custom_theme_fragment_title),
+ title,
position,
titleResId);
}
@@ -333,9 +330,9 @@
}
@Override
- CustomThemeComponentFragment createFragment() {
+ CustomThemeComponentFragment createFragment(String title) {
return CustomThemeComponentFragment.newInstance(
- CustomThemeActivity.this.getString(R.string.custom_theme_fragment_title),
+ title,
position,
titleResId);
}
@@ -349,9 +346,9 @@
}
@Override
- CustomThemeComponentFragment createFragment() {
+ CustomThemeComponentFragment createFragment(String title) {
return CustomThemeComponentFragment.newInstance(
- CustomThemeActivity.this.getString(R.string.custom_theme_fragment_title),
+ title,
position,
titleResId,
true);
@@ -366,9 +363,9 @@
}
@Override
- CustomThemeComponentFragment createFragment() {
+ CustomThemeComponentFragment createFragment(String title) {
return CustomThemeComponentFragment.newInstance(
- CustomThemeActivity.this.getString(R.string.custom_theme_fragment_title),
+ title,
position,
titleResId);
}
diff --git a/src/com/android/customization/picker/theme/ThemeFragment.java b/src/com/android/customization/picker/theme/ThemeFragment.java
index e3695e4..5b590f0 100644
--- a/src/com/android/customization/picker/theme/ThemeFragment.java
+++ b/src/com/android/customization/picker/theme/ThemeFragment.java
@@ -234,7 +234,7 @@
mOptionsController = new OptionSelectorController<>(mOptionsContainer, options);
mOptionsController.addListener(selected -> {
if (selected instanceof CustomTheme && !((CustomTheme) selected).isDefined()) {
- navigateToCustomTheme(null);
+ navigateToCustomTheme((CustomTheme) selected);
} else {
mSelectedTheme = (ThemeBundle) selected;
if (mUseMyWallpaper || mSelectedTheme instanceof CustomTheme) {
@@ -292,13 +292,12 @@
}, true);
}
- private void navigateToCustomTheme(@Nullable CustomTheme themeToEdit) {
+ private void navigateToCustomTheme(CustomTheme themeToEdit) {
Intent intent = new Intent(getActivity(), CustomThemeActivity.class);
- if (themeToEdit != null) {
- intent.putExtra(CustomThemeActivity.EXTRA_THEME_TITLE, themeToEdit.getTitle());
- intent.putExtra(CustomThemeActivity.EXTRA_THEME_PACKAGES,
- themeToEdit.getSerializedPackages());
- }
+ intent.putExtra(CustomThemeActivity.EXTRA_THEME_TITLE, themeToEdit.getTitle());
+ intent.putExtra(CustomThemeActivity.EXTRA_THEME_ID, themeToEdit.getId());
+ intent.putExtra(CustomThemeActivity.EXTRA_THEME_PACKAGES,
+ themeToEdit.getSerializedPackages());
startActivityForResult(intent, CustomThemeActivity.REQUEST_CODE_CUSTOM_THEME);
}