[ThemePicker 9/N] Read shape and icon from theme stub
Load the shape and icons from stub and overlays and display
them in the theme thumbnails.
Bug: 120559294
Change-Id: I40ae07070370fb33ada7060bf7161a0565109107
diff --git a/res/drawable/option_color.xml b/res/drawable/option_color.xml
index 87e2532..1fc1837 100644
--- a/res/drawable/option_color.xml
+++ b/res/drawable/option_color.xml
@@ -17,5 +17,5 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@android:color/black" />
- <corners android:radius="8dp" />
+ <corners android:radius="6dp" />
</shape>
diff --git a/res/layout/theme_option.xml b/res/layout/theme_option.xml
index 9e2ef82..5560a35 100644
--- a/res/layout/theme_option.xml
+++ b/res/layout/theme_option.xml
@@ -36,7 +36,7 @@
android:background="@drawable/option_border">
<TextView
android:id="@+id/theme_option_font"
- android:layout_width="wrap_content"
+ android:layout_width="@dimen/theme_option_sample_width"
android:layout_height="@dimen/theme_option_sample_height"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
@@ -45,22 +45,26 @@
android:text="@string/theme_font_example"/>
<ImageView
android:id="@+id/theme_option_shape"
- android:layout_width="@dimen/theme_option_sample_right_width"
+ android:layout_width="@dimen/theme_option_sample_width"
android:layout_height="@dimen/theme_option_sample_height"
android:layout_alignParentTop="true"
- android:layout_alignParentRight="true"/>
+ android:layout_alignParentRight="true"
+ android:layout_centerVertical="true"
+ android:padding="@dimen/theme_option_sample_padding"/>
<ImageView
android:id="@+id/theme_option_color"
- android:layout_width="@dimen/theme_option_sample_left_width"
+ android:layout_width="@dimen/theme_option_sample_width"
android:layout_height="@dimen/theme_option_sample_height"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
+ android:padding="@dimen/theme_option_sample_padding"
android:src="@drawable/option_color"/>
<ImageView
android:id="@+id/theme_option_icon"
- android:layout_width="@dimen/theme_option_sample_right_width"
+ android:layout_width="@dimen/theme_option_sample_width"
android:layout_height="@dimen/theme_option_sample_height"
android:layout_alignParentBottom="true"
- android:layout_alignParentRight="true"/>
+ android:layout_alignParentRight="true"
+ android:padding="@dimen/theme_option_sample_padding"/>
</RelativeLayout>
</LinearLayout>
diff --git a/res/values/colors.xml b/res/values/colors.xml
index 2bdd26a..bbfb5df 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -20,4 +20,7 @@
<color name="system_navigation_bar_background">@android:color/white</color>
<color name="system_navigation_bar_divider">#1f000000</color>
+
+ <color name="shape_thumbnail_color">#b2b2b2</color>
+ <color name="icon_thumbnail_color">@android:color/black</color>
</resources>
\ No newline at end of file
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 10a40f0..9405314 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -34,14 +34,14 @@
<!-- Dimensions for the customization option tiles -->
<dimen name="options_container_height">100dp</dimen>
<dimen name="option_tile_width">72dp</dimen>
- <dimen name="option_tile_padding_vertical">16dp</dimen>
+ <dimen name="theme_option_sample_height">23dp</dimen>
+ <dimen name="theme_option_sample_width">23dp</dimen>
+ <dimen name="theme_option_sample_padding">2dp</dimen>
+ <dimen name="option_tile_padding_vertical">12dp</dimen>
<dimen name="option_tile_padding_horizontal">10dp</dimen>
<!-- Note, using dp instead of sp as this text is more like a "snapshot" of the font -->
<dimen name="theme_option_font_text_size">10dp</dimen>
- <dimen name="theme_option_sample_right_width">20dp</dimen>
- <dimen name="theme_option_sample_height">18dp</dimen>
- <dimen name="theme_option_sample_left_width">22dp</dimen>
<dimen name="option_tile_margin_horizontal">4dp</dimen>
<dimen name="theme_option_label_margin">4dp</dimen>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 01bdca1..1e46cad 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -32,7 +32,7 @@
<item name="android:windowNoTitle">true</item>
</style>
- <style name="BottomNavStyle" parent="@style/Widget.MaterialComponents.BottomNavigationView">
+ <style name="BottomNavStyle">
<item name="itemIconTint">@color/bottom_nav_item_color</item>
<item name="itemTextColor">@color/bottom_nav_item_color</item>
<item name="itemTextAppearanceActive">@style/BottomNavTextAppearance</item>
diff --git a/src/com/android/customization/model/theme/DefaultThemeProvider.java b/src/com/android/customization/model/theme/DefaultThemeProvider.java
index 0ab3bba..92c7946 100644
--- a/src/com/android/customization/model/theme/DefaultThemeProvider.java
+++ b/src/com/android/customization/model/theme/DefaultThemeProvider.java
@@ -22,6 +22,7 @@
import android.content.res.Resources;
import android.content.res.Resources.NotFoundException;
import android.graphics.Typeface;
+import android.graphics.drawable.Drawable;
import android.text.TextUtils;
import android.util.Log;
@@ -43,6 +44,11 @@
private static final String TITLE_PREFIX = "theme_title_";
private static final String FONT_PREFIX = "theme_overlay_font_";
private static final String COLOR_PREFIX = "theme_overlay_color_";
+ private static final String SHAPE_PREFIX = "theme_overlay_shape_";
+ private static final String ICON_ANDROID_PREFIX = "theme_overlay_icon_android_";
+ private static final String ICON_SETTINGS_PREFIX = "theme_overlay_icon_settings_";
+ private static final String ICON_SYSTEM_PREFIX = "theme_overlay_icon_system_";
+ private static final String ICON_PREVIEW_DRAWABLE_NAME = "ic_wifi_signal_3";
private static final String DEFAULT_THEME_NAME= "default";
@@ -50,6 +56,8 @@
private static final String ACCENT_COLOR_DARK_NAME = "accent_device_default_dark";
private static final String CONFIG_BODY_FONT_FAMILY = "config_bodyFontFamily";
private static final String CONFIG_HEADLINE_FONT_FAMILY = "config_headlineFontFamily";
+ private static final String CONFIG_ICON_MASK = "config_icon_mask";
+ private static final String ANDROID_PACKAGE = "android";
private final Context mContext;
private final String mStubPackageName;
@@ -75,7 +83,7 @@
mStubApkResources = pm.getResourcesForApplication(stubAppInfo);
}
} catch (NameNotFoundException e) {
- Log.w(TAG, "Themes stub APK not found.");
+ Log.w(TAG, String.format("Themes stub APK for %s not found.", mStubPackageName));
}
}
@@ -134,7 +142,41 @@
colorOverlayPackage));
}
- //TODO (santie) read the other overlays
+ String shapeOverlayPackage = getOverlayPackage(SHAPE_PREFIX, themeName);
+
+ if (!TextUtils.isEmpty(shapeOverlayPackage)) {
+ builder.setShapePackage(shapeOverlayPackage)
+ .setShapePath(loadString(CONFIG_ICON_MASK, shapeOverlayPackage));
+ } else {
+ builder.setShapePath(mContext.getResources().getString(
+ Resources.getSystem().getIdentifier(CONFIG_ICON_MASK, "string",
+ ANDROID_PACKAGE)));
+ }
+
+ String iconAndroidOverlayPackage = getOverlayPackage(ICON_ANDROID_PREFIX, themeName);
+
+ if (!TextUtils.isEmpty(iconAndroidOverlayPackage)) {
+ builder.addIconPackage(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));
+ }
+
+ String iconSystemOverlayPackage = getOverlayPackage(ICON_SYSTEM_PREFIX, themeName);
+
+ if (!TextUtils.isEmpty(iconSystemOverlayPackage)) {
+ builder.addIconPackage(iconSystemOverlayPackage);
+ }
+
+ String iconSettingsOverlayPackage = getOverlayPackage(ICON_SETTINGS_PREFIX,
+ themeName);
+
+ if (!TextUtils.isEmpty(iconSettingsOverlayPackage)) {
+ builder.addIconPackage(iconSettingsOverlayPackage);
+ }
mThemes.add(builder.build());
} catch (NameNotFoundException | NotFoundException e) {
@@ -171,11 +213,11 @@
} catch (NameNotFoundException | NotFoundException e) {
Log.i(TAG, "Didn't find color overlay for default theme, will use system default", e);
int colorAccentLight = system.getColor(
- system.getIdentifier(ACCENT_COLOR_LIGHT_NAME, "color", "android"), null);
+ system.getIdentifier(ACCENT_COLOR_LIGHT_NAME, "color", ANDROID_PACKAGE), null);
builder.setColorAccentLight(colorAccentLight);
int colorAccentDark = system.getColor(
- system.getIdentifier(ACCENT_COLOR_DARK_NAME, "color", "android"), null);
+ system.getIdentifier(ACCENT_COLOR_DARK_NAME, "color", ANDROID_PACKAGE), null);
builder.setColorAccentDark(colorAccentDark);
builder.setColorPackage(null);
}
@@ -191,14 +233,38 @@
} catch (NameNotFoundException | NotFoundException e) {
Log.i(TAG, "Didn't find font overlay for default theme, will use system default", e);
String headlineFontFamily = system.getString(system.getIdentifier(
- CONFIG_HEADLINE_FONT_FAMILY,"string", "android"));
+ CONFIG_HEADLINE_FONT_FAMILY,"string", ANDROID_PACKAGE));
String bodyFontFamily = system.getString(system.getIdentifier(CONFIG_BODY_FONT_FAMILY,
- "string", "android"));
+ "string", ANDROID_PACKAGE));
builder.setHeadlineFontFamily(Typeface.create(headlineFontFamily, Typeface.NORMAL))
.setBodyFontFamily(Typeface.create(bodyFontFamily, Typeface.NORMAL));
builder.setFontOverlayPackage(null);
}
+ try {
+ builder.setShapePackage(getOverlayPackage(SHAPE_PREFIX, DEFAULT_THEME_NAME))
+ .setShapePath(loadString(ICON_PREVIEW_DRAWABLE_NAME, colorOverlayPackage));
+ } catch (NameNotFoundException | NotFoundException e) {
+ Log.i(TAG, "Didn't find shape overlay for default theme, will use system default", e);
+ String iconMaskPath = system.getString(system.getIdentifier(CONFIG_ICON_MASK,
+ "string", ANDROID_PACKAGE));
+ builder.setShapePath(iconMaskPath);
+ }
+
+
+ try {
+ String iconAndroidOverlayPackage = getOverlayPackage(ICON_ANDROID_PREFIX,
+ DEFAULT_THEME_NAME);
+ builder.addIconPackage(iconAndroidOverlayPackage)
+ .addIcon(loadIconPreviewDrawable(ICON_ANDROID_PREFIX,
+ iconAndroidOverlayPackage));
+ } catch (NameNotFoundException | NotFoundException e) {
+ Log.i(TAG, "Didn't find Android icons overlay for default theme, using system default",
+ e);
+ builder.addIcon(system.getDrawable(system.getIdentifier(ICON_PREVIEW_DRAWABLE_NAME,
+ "drawable", ANDROID_PACKAGE), null));
+ }
+
mThemes.add(builder.build());
}
@@ -229,4 +295,19 @@
return overlayRes.getColor(overlayRes.getIdentifier(colorName, "color", colorPackage),
null);
}
+
+ private String loadString(String stringName, String packageName)
+ throws NameNotFoundException, NotFoundException {
+
+ Resources overlayRes = mContext.getPackageManager().getResourcesForApplication(packageName);
+ return overlayRes.getString(overlayRes.getIdentifier(stringName, "string", packageName));
+ }
+
+ private Drawable loadIconPreviewDrawable(String drawableName, String packageName)
+ throws NameNotFoundException, NotFoundException {
+
+ Resources overlayRes = mContext.getPackageManager().getResourcesForApplication(packageName);
+ return overlayRes.getDrawable(
+ overlayRes.getIdentifier(drawableName, "drawable", packageName), null);
+ }
}
diff --git a/src/com/android/customization/model/theme/ThemeBundle.java b/src/com/android/customization/model/theme/ThemeBundle.java
index 6df7592..cf6055c 100644
--- a/src/com/android/customization/model/theme/ThemeBundle.java
+++ b/src/com/android/customization/model/theme/ThemeBundle.java
@@ -16,8 +16,13 @@
package com.android.customization.model.theme;
import android.content.res.ColorStateList;
+import android.content.res.Resources;
+import android.graphics.PorterDuff.Mode;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
+import android.graphics.drawable.ShapeDrawable;
+import android.graphics.drawable.shapes.PathShape;
+import android.text.TextUtils;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
@@ -25,6 +30,7 @@
import androidx.annotation.ColorInt;
import androidx.annotation.DrawableRes;
import androidx.annotation.Nullable;
+import androidx.core.graphics.PathParser;
import com.android.customization.model.CustomizationOption;
import com.android.wallpaper.R;
@@ -56,10 +62,24 @@
@Override
public void bindThumbnailTile(View view) {
+ Resources res = view.getContext().getResources();
+
((ImageView) view.findViewById(R.id.theme_option_color)).setImageTintList(
ColorStateList.valueOf(mPreviewInfo.colorAccentLight));
((TextView) view.findViewById(R.id.theme_option_font)).setTypeface(
mPreviewInfo.headlineFontFamily);
+ if (mPreviewInfo.shapeDrawable != null) {
+ ((ShapeDrawable)mPreviewInfo.shapeDrawable).getPaint().setColor(res.getColor(
+ R.color.shape_thumbnail_color, null));
+ ((ImageView) view.findViewById(R.id.theme_option_shape)).setImageDrawable(
+ mPreviewInfo.shapeDrawable);
+ }
+ if (!mPreviewInfo.icons.isEmpty()) {
+ Drawable icon = mPreviewInfo.icons.get(0).mutate();
+ icon.setTint(res.getColor(R.color.icon_thumbnail_color, null));
+ ((ImageView) view.findViewById(R.id.theme_option_icon)).setImageDrawable(
+ icon);
+ }
}
@Override
@@ -82,24 +102,25 @@
@ColorInt public final int colorAccentLight;
@ColorInt public final int colorAccentDark;
public final List<Drawable> icons;
- public final String shapePath;
+ public final Drawable shapeDrawable;
@DrawableRes public final int wallpaperDrawableRes;
public PreviewInfo(Typeface bodyFontFamily, Typeface headlineFontFamily,
int colorAccentLight,
- int colorAccentDark, List<Drawable> icons, String shapePath,
+ int colorAccentDark, List<Drawable> icons, Drawable shapeDrawable,
int wallpaperDrawableRes) {
this.bodyFontFamily = bodyFontFamily;
this.headlineFontFamily = headlineFontFamily;
this.colorAccentLight = colorAccentLight;
this.colorAccentDark = colorAccentDark;
this.icons = icons;
- this.shapePath = shapePath;
+ this.shapeDrawable = shapeDrawable;
this.wallpaperDrawableRes = wallpaperDrawableRes;
}
}
public static class Builder {
+ private static final float PATH_SIZE = 100f;
private String mTitle;
private Typeface mBodyFontFamily;
private Typeface mHeadlineFontFamily;
@@ -115,9 +136,17 @@
private String mShapePackage;
public ThemeBundle build() {
+ ShapeDrawable shapeDrawable = null;
+ if (!TextUtils.isEmpty(mShapePath)) {
+ PathShape shape = new PathShape(PathParser.createPathFromPathData(mShapePath),
+ PATH_SIZE, PATH_SIZE);
+ shapeDrawable = new ShapeDrawable(shape);
+ shapeDrawable.setIntrinsicHeight((int) PATH_SIZE);
+ shapeDrawable.setIntrinsicWidth((int) PATH_SIZE);
+ }
return new ThemeBundle(mTitle,
new PreviewInfo(mBodyFontFamily, mHeadlineFontFamily, mColorAccentLight,
- mColorAccentDark, mIcons, mShapePath, mWallpaperDrawableResId));
+ mColorAccentDark, mIcons, shapeDrawable, mWallpaperDrawableResId));
}
public Builder setTitle(String title) {
@@ -154,5 +183,25 @@
mColorAccentDark = colorAccentDark;
return this;
}
+
+ public Builder addIcon(Drawable icon) {
+ mIcons.add(icon);
+ return this;
+ }
+
+ public Builder addIconPackage(String packageName) {
+ mIconPackages.add(packageName);
+ return this;
+ }
+
+ public Builder setShapePackage(String packageName) {
+ mShapePackage = packageName;
+ return this;
+ }
+
+ public Builder setShapePath(String path) {
+ mShapePath = path;
+ return this;
+ }
}
}