Loading iconloaderlib/src/com/android/launcher3/icons/BitmapInfo.java +9 −5 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import android.graphics.Bitmap; import android.graphics.Bitmap.Config; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.drawable.Drawable; import android.os.Build; import android.os.UserHandle; import android.util.Log; Loading Loading @@ -146,14 +147,17 @@ public class BitmapInfo { /** * Called for creating a custom BitmapInfo */ default BitmapInfo getExtendedInfo(Bitmap bitmap, int color, BaseIconFactory iconFactory, float normalizationScale, UserHandle user) { return BitmapInfo.of(bitmap, color); } BitmapInfo getExtendedInfo(Bitmap bitmap, int color, BaseIconFactory iconFactory, float normalizationScale, UserHandle user); /** * Called to draw the UI independent of any runtime configurations like time or theme */ default void drawForPersistence(Canvas canvas) { } void drawForPersistence(Canvas canvas); /** * Returns a new icon with theme applied */ Drawable getThemedDrawable(Context context); } } iconloaderlib/src/com/android/launcher3/icons/ClockDrawableWrapper.java +137 −47 Original line number Diff line number Diff line Loading @@ -15,14 +15,25 @@ */ package com.android.launcher3.icons; import static com.android.launcher3.icons.ThemedIconDrawable.getColors; import android.annotation.TargetApi; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.res.Resources; import android.content.res.TypedArray; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.ColorFilter; import android.graphics.Paint; import android.graphics.PorterDuff; import android.graphics.PorterDuff.Mode; import android.graphics.PorterDuffColorFilter; import android.graphics.Rect; import android.graphics.drawable.AdaptiveIconDrawable; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.graphics.drawable.LayerDrawable; import android.os.Build; Loading @@ -31,11 +42,15 @@ import android.os.Process; import android.os.SystemClock; import android.os.UserHandle; import android.util.Log; import android.util.TypedValue; import androidx.annotation.Nullable; import com.android.launcher3.icons.ThemedIconDrawable.ThemeData; import java.util.Calendar; import java.util.concurrent.TimeUnit; import java.util.function.IntFunction; /** * Wrapper over {@link AdaptiveIconDrawable} to intercept icon flattening logic for dynamic Loading Loading @@ -74,6 +89,7 @@ public class ClockDrawableWrapper extends AdaptiveIconDrawable implements Bitmap private final AnimationInfo mAnimationInfo = new AnimationInfo(); private int mTargetSdkVersion; protected ThemeData mThemeData; public ClockDrawableWrapper(AdaptiveIconDrawable base) { super(base.getBackground(), base.getForeground()); Loading @@ -88,7 +104,46 @@ public class ClockDrawableWrapper extends AdaptiveIconDrawable implements Bitmap PackageManager pm = context.getPackageManager(); ApplicationInfo appInfo = pm.getApplicationInfo(pkg, PackageManager.MATCH_UNINSTALLED_PACKAGES | PackageManager.GET_META_DATA); final Bundle metadata = appInfo.metaData; Resources res = pm.getResourcesForApplication(appInfo); return forExtras(appInfo, appInfo.metaData, resId -> res.getDrawableForDensity(resId, iconDpi)); } catch (Exception e) { Log.d(TAG, "Unable to load clock drawable info", e); } return null; } private static ClockDrawableWrapper fromThemeData(Context context, ThemeData themeData) { try { TypedArray ta = themeData.mResources.obtainTypedArray(themeData.mResID); int count = ta.length(); Bundle extras = new Bundle(); for (int i = 0; i < count; i += 2) { TypedValue v = ta.peekValue(i + 1); extras.putInt(ta.getString(i), v.type >= TypedValue.TYPE_FIRST_INT && v.type <= TypedValue.TYPE_LAST_INT ? v.data : v.resourceId); } ta.recycle(); ClockDrawableWrapper drawable = ClockDrawableWrapper.forExtras( context.getApplicationInfo(), extras, resId -> { int[] colors = getColors(context); Drawable bg = new ColorDrawable(colors[0]); Drawable fg = themeData.mResources.getDrawable(resId).mutate(); fg.setTint(colors[1]); return new AdaptiveIconDrawable(bg, fg); }); if (drawable != null) { return drawable; } } catch (Exception e) { Log.e(TAG, "Error loading themed clock", e); } return null; } private static ClockDrawableWrapper forExtras(ApplicationInfo appInfo, Bundle metadata, IntFunction<Drawable> drawableProvider) { if (metadata == null) { return null; } Loading @@ -97,8 +152,7 @@ public class ClockDrawableWrapper extends AdaptiveIconDrawable implements Bitmap return null; } Drawable drawable = pm.getResourcesForApplication(appInfo).getDrawableForDensity( drawableId, iconDpi).mutate(); Drawable drawable = drawableProvider.apply(drawableId).mutate(); if (!(drawable instanceof AdaptiveIconDrawable)) { return null; } Loading Loading @@ -134,14 +188,10 @@ public class ClockDrawableWrapper extends AdaptiveIconDrawable implements Bitmap } info.applyTime(Calendar.getInstance(), foreground); return wrapper; } catch (Exception e) { Log.d(TAG, "Unable to load clock drawable info", e); } return null; } @Override public BitmapInfo getExtendedInfo(Bitmap bitmap, int color, public ClockBitmapInfo getExtendedInfo(Bitmap bitmap, int color, BaseIconFactory iconFactory, float normalizationScale, UserHandle user) { iconFactory.disableColorExtraction(); AdaptiveIconDrawable background = new AdaptiveIconDrawable( Loading @@ -150,7 +200,7 @@ public class ClockDrawableWrapper extends AdaptiveIconDrawable implements Bitmap Process.myUserHandle(), mTargetSdkVersion, false); return new ClockBitmapInfo(bitmap, color, normalizationScale, mAnimationInfo, bitmapInfo.icon); mAnimationInfo, bitmapInfo.icon, mThemeData); } @Override Loading @@ -163,6 +213,15 @@ public class ClockDrawableWrapper extends AdaptiveIconDrawable implements Bitmap mAnimationInfo.applyTime(Calendar.getInstance(), (LayerDrawable) getForeground()); } @Override public Drawable getThemedDrawable(Context context) { if (mThemeData != null) { ClockDrawableWrapper drawable = fromThemeData(context, mThemeData); return drawable == null ? this : drawable; } return this; } private void resetLevel(LayerDrawable drawable, int index) { if (index != INVALID_VALUE) { drawable.getDrawable(index).setLevel(0); Loading Loading @@ -214,20 +273,47 @@ public class ClockDrawableWrapper extends AdaptiveIconDrawable implements Bitmap } } private static class ClockBitmapInfo extends BitmapInfo { static class ClockBitmapInfo extends BitmapInfo { public final float scale; public final int offset; public final AnimationInfo animInfo; public final Bitmap mFlattenedBackground; public final ThemeData themeData; ClockBitmapInfo(Bitmap icon, int color, float scale, AnimationInfo animInfo, Bitmap background) { Bitmap background, ThemeData themeData) { super(icon, color); this.scale = scale; this.animInfo = animInfo; this.offset = (int) Math.ceil(ShadowGenerator.BLUR_FACTOR * icon.getWidth()); this.mFlattenedBackground = background; this.themeData = themeData; } @Override public FastBitmapDrawable newThemedIcon(Context context) { if (themeData != null) { ClockDrawableWrapper wrapper = fromThemeData(context, themeData); if (wrapper != null) { int[] colors = getColors(context); ColorFilter bgFilter = new PorterDuffColorFilter(colors[0], Mode.SRC_ATOP); ClockBitmapInfo bitmapInfo = new ClockBitmapInfo(icon, colors[1], scale, wrapper.mAnimationInfo, mFlattenedBackground, themeData) { @Override void drawBackground(Canvas canvas, Rect bounds, Paint paint) { ColorFilter oldFilter = paint.getColorFilter(); paint.setColorFilter(bgFilter); super.drawBackground(canvas, bounds, paint); paint.setColorFilter(oldFilter); } }; return bitmapInfo.newIcon(context); } } return super.newThemedIcon(context); } @Override Loading @@ -242,6 +328,11 @@ public class ClockDrawableWrapper extends AdaptiveIconDrawable implements Bitmap public byte[] toByteArray() { return null; } void drawBackground(Canvas canvas, Rect bounds, Paint paint) { // draw the background that is already flattened to a bitmap canvas.drawBitmap(mFlattenedBackground, null, bounds, paint); } } private static class ClockIconDrawable extends FastBitmapDrawable implements Runnable { Loading Loading @@ -274,8 +365,7 @@ public class ClockDrawableWrapper extends AdaptiveIconDrawable implements Bitmap super.drawInternal(canvas, bounds); return; } // draw the background that is already flattened to a bitmap canvas.drawBitmap(mInfo.mFlattenedBackground, null, bounds, mPaint); mInfo.drawBackground(canvas, bounds, mPaint); // prepare and draw the foreground mInfo.animInfo.applyTime(mTime, mForeground); Loading iconloaderlib/src/com/android/launcher3/icons/FastBitmapDrawable.java +7 −0 Original line number Diff line number Diff line Loading @@ -113,6 +113,13 @@ public class FastBitmapDrawable extends Drawable { canvas.drawBitmap(mBitmap, null, bounds, mPaint); } /** * Returns the primary icon color */ public int getIconColor() { return mIconColor; } @Override public void setColorFilter(ColorFilter cf) { mColorFilter = cf; Loading iconloaderlib/src/com/android/launcher3/icons/IconProvider.java +13 −3 Original line number Diff line number Diff line Loading @@ -82,6 +82,10 @@ public class IconProvider { private final ComponentName mCalendar; private final ComponentName mClock; static final int ICON_TYPE_DEFAULT = 0; static final int ICON_TYPE_CALENDAR = 1; static final int ICON_TYPE_CLOCK = 2; public IconProvider(Context context) { this(context, false); } Loading Loading @@ -143,17 +147,23 @@ public class IconProvider { Supplier<Drawable> fallback) { Drawable icon = null; int iconType = ICON_TYPE_DEFAULT; if (mCalendar != null && mCalendar.getPackageName().equals(packageName)) { icon = loadCalendarDrawable(iconDpi); iconType = ICON_TYPE_CALENDAR; } else if (mClock != null && mClock.getPackageName().equals(packageName) && Process.myUserHandle().equals(user)) { icon = loadClockDrawable(iconDpi); iconType = ICON_TYPE_CLOCK; } if (icon == null) { icon = fallback.get(); iconType = ICON_TYPE_DEFAULT; } icon = icon == null ? fallback.get() : icon; ThemeData td = getThemedIconMap().get(packageName); return td != null ? td.wrapDrawable(icon) : icon; return td != null ? td.wrapDrawable(icon, iconType) : icon; } private Drawable loadActivityInfoIcon(ActivityInfo ai, int density) { Loading Loading @@ -265,7 +275,7 @@ public class IconProvider { /** * @return Today's day of the month, zero-indexed. */ private int getDay() { static int getDay() { return Calendar.getInstance().get(Calendar.DAY_OF_MONTH) - 1; } Loading iconloaderlib/src/com/android/launcher3/icons/ThemedIconDrawable.java +35 −16 Original line number Diff line number Diff line Loading @@ -20,9 +20,12 @@ import static android.content.res.Configuration.UI_MODE_NIGHT_YES; import static android.content.res.Resources.ID_NULL; import static com.android.launcher3.icons.GraphicsUtils.getExpectedBitmapSize; import static com.android.launcher3.icons.IconProvider.ICON_TYPE_CALENDAR; import static com.android.launcher3.icons.IconProvider.ICON_TYPE_CLOCK; import android.content.Context; import android.content.res.Resources; import android.content.res.TypedArray; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; Loading @@ -38,6 +41,7 @@ import android.util.Log; import androidx.annotation.Nullable; import com.android.launcher3.icons.BitmapInfo.Extender; import com.android.launcher3.icons.ClockDrawableWrapper.ClockBitmapInfo; import com.android.launcher3.icons.cache.BaseIconCache; import java.io.ByteArrayInputStream; Loading @@ -63,7 +67,7 @@ public class ThemedIconDrawable extends FastBitmapDrawable { private final Rect mBadgeBounds; protected ThemedIconDrawable(ThemedConstantState constantState) { super(constantState.mBitmap, constantState.mIconColor, constantState.mIsDisabled); super(constantState.mBitmap, constantState.colorFg, constantState.mIsDisabled); bitmapInfo = constantState.bitmapInfo; colorBg = constantState.colorBg; colorFg = constantState.colorFg; Loading @@ -72,6 +76,7 @@ public class ThemedIconDrawable extends FastBitmapDrawable { mBgWrapper = new AdaptiveIconDrawable(new ColorDrawable(colorBg), null); mBadgeBounds = bitmapInfo.mUserBadge == null ? null : new Rect(0, 0, bitmapInfo.mUserBadge.getWidth(), bitmapInfo.mUserBadge.getHeight()); } @Override Loading Loading @@ -147,7 +152,7 @@ public class ThemedIconDrawable extends FastBitmapDrawable { if (isNullOrLowRes()) { return null; } String resName = mThemeData.mResources.getResourceName(mThemeData.mIconID); String resName = mThemeData.mResources.getResourceName(mThemeData.mResID); ByteArrayOutputStream out = new ByteArrayOutputStream( getExpectedBitmapSize(icon) + 3 + resName.length()); try { Loading Loading @@ -200,30 +205,46 @@ public class ThemedIconDrawable extends FastBitmapDrawable { public static class ThemeData { final Resources mResources; final int mIconID; final int mResID; public ThemeData(Resources resources, int iconID) { public ThemeData(Resources resources, int resID) { mResources = resources; mIconID = iconID; mResID = resID; } Drawable loadMonochromeDrawable(int accentColor) { Drawable d = mResources.getDrawable(mIconID).mutate(); Drawable d = mResources.getDrawable(mResID).mutate(); d.setTint(accentColor); d = new InsetDrawable(d, .15f); d = new InsetDrawable(d, .2f); return d; } public Drawable wrapDrawable(Drawable original) { return (original instanceof AdaptiveIconDrawable) ? new ThemedAdaptiveIcon((AdaptiveIconDrawable) original, this) : original; public Drawable wrapDrawable(Drawable original, int iconType) { if (!(original instanceof AdaptiveIconDrawable)) { return original; } AdaptiveIconDrawable aid = (AdaptiveIconDrawable) original; String resourceType = mResources.getResourceTypeName(mResID); if (iconType == ICON_TYPE_CALENDAR && "array".equals(resourceType)) { TypedArray ta = mResources.obtainTypedArray(mResID); int id = ta.getResourceId(IconProvider.getDay(), ID_NULL); ta.recycle(); return id == ID_NULL ? original : new ThemedAdaptiveIcon(aid, new ThemeData(mResources, id)); } else if (iconType == ICON_TYPE_CLOCK && "array".equals(resourceType)) { ((ClockDrawableWrapper) original).mThemeData = this; return original; } else if ("drawable".equals(resourceType)) { return new ThemedAdaptiveIcon(aid, this); } else { return original; } } } public static class ThemedAdaptiveIcon extends AdaptiveIconDrawable implements Extender { static class ThemedAdaptiveIcon extends AdaptiveIconDrawable implements Extender { private final ThemeData mThemeData; protected final ThemeData mThemeData; public ThemedAdaptiveIcon(AdaptiveIconDrawable parent, ThemeData themeData) { super(parent.getBackground(), parent.getForeground()); Loading @@ -243,9 +264,7 @@ public class ThemedIconDrawable extends FastBitmapDrawable { draw(canvas); } /** * Returns a new icon with theme applied */ @Override public Drawable getThemedDrawable(Context context) { int[] colors = getColors(context); Drawable bg = new ColorDrawable(colors[0]); Loading Loading
iconloaderlib/src/com/android/launcher3/icons/BitmapInfo.java +9 −5 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import android.graphics.Bitmap; import android.graphics.Bitmap.Config; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.drawable.Drawable; import android.os.Build; import android.os.UserHandle; import android.util.Log; Loading Loading @@ -146,14 +147,17 @@ public class BitmapInfo { /** * Called for creating a custom BitmapInfo */ default BitmapInfo getExtendedInfo(Bitmap bitmap, int color, BaseIconFactory iconFactory, float normalizationScale, UserHandle user) { return BitmapInfo.of(bitmap, color); } BitmapInfo getExtendedInfo(Bitmap bitmap, int color, BaseIconFactory iconFactory, float normalizationScale, UserHandle user); /** * Called to draw the UI independent of any runtime configurations like time or theme */ default void drawForPersistence(Canvas canvas) { } void drawForPersistence(Canvas canvas); /** * Returns a new icon with theme applied */ Drawable getThemedDrawable(Context context); } }
iconloaderlib/src/com/android/launcher3/icons/ClockDrawableWrapper.java +137 −47 Original line number Diff line number Diff line Loading @@ -15,14 +15,25 @@ */ package com.android.launcher3.icons; import static com.android.launcher3.icons.ThemedIconDrawable.getColors; import android.annotation.TargetApi; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.res.Resources; import android.content.res.TypedArray; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.ColorFilter; import android.graphics.Paint; import android.graphics.PorterDuff; import android.graphics.PorterDuff.Mode; import android.graphics.PorterDuffColorFilter; import android.graphics.Rect; import android.graphics.drawable.AdaptiveIconDrawable; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.graphics.drawable.LayerDrawable; import android.os.Build; Loading @@ -31,11 +42,15 @@ import android.os.Process; import android.os.SystemClock; import android.os.UserHandle; import android.util.Log; import android.util.TypedValue; import androidx.annotation.Nullable; import com.android.launcher3.icons.ThemedIconDrawable.ThemeData; import java.util.Calendar; import java.util.concurrent.TimeUnit; import java.util.function.IntFunction; /** * Wrapper over {@link AdaptiveIconDrawable} to intercept icon flattening logic for dynamic Loading Loading @@ -74,6 +89,7 @@ public class ClockDrawableWrapper extends AdaptiveIconDrawable implements Bitmap private final AnimationInfo mAnimationInfo = new AnimationInfo(); private int mTargetSdkVersion; protected ThemeData mThemeData; public ClockDrawableWrapper(AdaptiveIconDrawable base) { super(base.getBackground(), base.getForeground()); Loading @@ -88,7 +104,46 @@ public class ClockDrawableWrapper extends AdaptiveIconDrawable implements Bitmap PackageManager pm = context.getPackageManager(); ApplicationInfo appInfo = pm.getApplicationInfo(pkg, PackageManager.MATCH_UNINSTALLED_PACKAGES | PackageManager.GET_META_DATA); final Bundle metadata = appInfo.metaData; Resources res = pm.getResourcesForApplication(appInfo); return forExtras(appInfo, appInfo.metaData, resId -> res.getDrawableForDensity(resId, iconDpi)); } catch (Exception e) { Log.d(TAG, "Unable to load clock drawable info", e); } return null; } private static ClockDrawableWrapper fromThemeData(Context context, ThemeData themeData) { try { TypedArray ta = themeData.mResources.obtainTypedArray(themeData.mResID); int count = ta.length(); Bundle extras = new Bundle(); for (int i = 0; i < count; i += 2) { TypedValue v = ta.peekValue(i + 1); extras.putInt(ta.getString(i), v.type >= TypedValue.TYPE_FIRST_INT && v.type <= TypedValue.TYPE_LAST_INT ? v.data : v.resourceId); } ta.recycle(); ClockDrawableWrapper drawable = ClockDrawableWrapper.forExtras( context.getApplicationInfo(), extras, resId -> { int[] colors = getColors(context); Drawable bg = new ColorDrawable(colors[0]); Drawable fg = themeData.mResources.getDrawable(resId).mutate(); fg.setTint(colors[1]); return new AdaptiveIconDrawable(bg, fg); }); if (drawable != null) { return drawable; } } catch (Exception e) { Log.e(TAG, "Error loading themed clock", e); } return null; } private static ClockDrawableWrapper forExtras(ApplicationInfo appInfo, Bundle metadata, IntFunction<Drawable> drawableProvider) { if (metadata == null) { return null; } Loading @@ -97,8 +152,7 @@ public class ClockDrawableWrapper extends AdaptiveIconDrawable implements Bitmap return null; } Drawable drawable = pm.getResourcesForApplication(appInfo).getDrawableForDensity( drawableId, iconDpi).mutate(); Drawable drawable = drawableProvider.apply(drawableId).mutate(); if (!(drawable instanceof AdaptiveIconDrawable)) { return null; } Loading Loading @@ -134,14 +188,10 @@ public class ClockDrawableWrapper extends AdaptiveIconDrawable implements Bitmap } info.applyTime(Calendar.getInstance(), foreground); return wrapper; } catch (Exception e) { Log.d(TAG, "Unable to load clock drawable info", e); } return null; } @Override public BitmapInfo getExtendedInfo(Bitmap bitmap, int color, public ClockBitmapInfo getExtendedInfo(Bitmap bitmap, int color, BaseIconFactory iconFactory, float normalizationScale, UserHandle user) { iconFactory.disableColorExtraction(); AdaptiveIconDrawable background = new AdaptiveIconDrawable( Loading @@ -150,7 +200,7 @@ public class ClockDrawableWrapper extends AdaptiveIconDrawable implements Bitmap Process.myUserHandle(), mTargetSdkVersion, false); return new ClockBitmapInfo(bitmap, color, normalizationScale, mAnimationInfo, bitmapInfo.icon); mAnimationInfo, bitmapInfo.icon, mThemeData); } @Override Loading @@ -163,6 +213,15 @@ public class ClockDrawableWrapper extends AdaptiveIconDrawable implements Bitmap mAnimationInfo.applyTime(Calendar.getInstance(), (LayerDrawable) getForeground()); } @Override public Drawable getThemedDrawable(Context context) { if (mThemeData != null) { ClockDrawableWrapper drawable = fromThemeData(context, mThemeData); return drawable == null ? this : drawable; } return this; } private void resetLevel(LayerDrawable drawable, int index) { if (index != INVALID_VALUE) { drawable.getDrawable(index).setLevel(0); Loading Loading @@ -214,20 +273,47 @@ public class ClockDrawableWrapper extends AdaptiveIconDrawable implements Bitmap } } private static class ClockBitmapInfo extends BitmapInfo { static class ClockBitmapInfo extends BitmapInfo { public final float scale; public final int offset; public final AnimationInfo animInfo; public final Bitmap mFlattenedBackground; public final ThemeData themeData; ClockBitmapInfo(Bitmap icon, int color, float scale, AnimationInfo animInfo, Bitmap background) { Bitmap background, ThemeData themeData) { super(icon, color); this.scale = scale; this.animInfo = animInfo; this.offset = (int) Math.ceil(ShadowGenerator.BLUR_FACTOR * icon.getWidth()); this.mFlattenedBackground = background; this.themeData = themeData; } @Override public FastBitmapDrawable newThemedIcon(Context context) { if (themeData != null) { ClockDrawableWrapper wrapper = fromThemeData(context, themeData); if (wrapper != null) { int[] colors = getColors(context); ColorFilter bgFilter = new PorterDuffColorFilter(colors[0], Mode.SRC_ATOP); ClockBitmapInfo bitmapInfo = new ClockBitmapInfo(icon, colors[1], scale, wrapper.mAnimationInfo, mFlattenedBackground, themeData) { @Override void drawBackground(Canvas canvas, Rect bounds, Paint paint) { ColorFilter oldFilter = paint.getColorFilter(); paint.setColorFilter(bgFilter); super.drawBackground(canvas, bounds, paint); paint.setColorFilter(oldFilter); } }; return bitmapInfo.newIcon(context); } } return super.newThemedIcon(context); } @Override Loading @@ -242,6 +328,11 @@ public class ClockDrawableWrapper extends AdaptiveIconDrawable implements Bitmap public byte[] toByteArray() { return null; } void drawBackground(Canvas canvas, Rect bounds, Paint paint) { // draw the background that is already flattened to a bitmap canvas.drawBitmap(mFlattenedBackground, null, bounds, paint); } } private static class ClockIconDrawable extends FastBitmapDrawable implements Runnable { Loading Loading @@ -274,8 +365,7 @@ public class ClockDrawableWrapper extends AdaptiveIconDrawable implements Bitmap super.drawInternal(canvas, bounds); return; } // draw the background that is already flattened to a bitmap canvas.drawBitmap(mInfo.mFlattenedBackground, null, bounds, mPaint); mInfo.drawBackground(canvas, bounds, mPaint); // prepare and draw the foreground mInfo.animInfo.applyTime(mTime, mForeground); Loading
iconloaderlib/src/com/android/launcher3/icons/FastBitmapDrawable.java +7 −0 Original line number Diff line number Diff line Loading @@ -113,6 +113,13 @@ public class FastBitmapDrawable extends Drawable { canvas.drawBitmap(mBitmap, null, bounds, mPaint); } /** * Returns the primary icon color */ public int getIconColor() { return mIconColor; } @Override public void setColorFilter(ColorFilter cf) { mColorFilter = cf; Loading
iconloaderlib/src/com/android/launcher3/icons/IconProvider.java +13 −3 Original line number Diff line number Diff line Loading @@ -82,6 +82,10 @@ public class IconProvider { private final ComponentName mCalendar; private final ComponentName mClock; static final int ICON_TYPE_DEFAULT = 0; static final int ICON_TYPE_CALENDAR = 1; static final int ICON_TYPE_CLOCK = 2; public IconProvider(Context context) { this(context, false); } Loading Loading @@ -143,17 +147,23 @@ public class IconProvider { Supplier<Drawable> fallback) { Drawable icon = null; int iconType = ICON_TYPE_DEFAULT; if (mCalendar != null && mCalendar.getPackageName().equals(packageName)) { icon = loadCalendarDrawable(iconDpi); iconType = ICON_TYPE_CALENDAR; } else if (mClock != null && mClock.getPackageName().equals(packageName) && Process.myUserHandle().equals(user)) { icon = loadClockDrawable(iconDpi); iconType = ICON_TYPE_CLOCK; } if (icon == null) { icon = fallback.get(); iconType = ICON_TYPE_DEFAULT; } icon = icon == null ? fallback.get() : icon; ThemeData td = getThemedIconMap().get(packageName); return td != null ? td.wrapDrawable(icon) : icon; return td != null ? td.wrapDrawable(icon, iconType) : icon; } private Drawable loadActivityInfoIcon(ActivityInfo ai, int density) { Loading Loading @@ -265,7 +275,7 @@ public class IconProvider { /** * @return Today's day of the month, zero-indexed. */ private int getDay() { static int getDay() { return Calendar.getInstance().get(Calendar.DAY_OF_MONTH) - 1; } Loading
iconloaderlib/src/com/android/launcher3/icons/ThemedIconDrawable.java +35 −16 Original line number Diff line number Diff line Loading @@ -20,9 +20,12 @@ import static android.content.res.Configuration.UI_MODE_NIGHT_YES; import static android.content.res.Resources.ID_NULL; import static com.android.launcher3.icons.GraphicsUtils.getExpectedBitmapSize; import static com.android.launcher3.icons.IconProvider.ICON_TYPE_CALENDAR; import static com.android.launcher3.icons.IconProvider.ICON_TYPE_CLOCK; import android.content.Context; import android.content.res.Resources; import android.content.res.TypedArray; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; Loading @@ -38,6 +41,7 @@ import android.util.Log; import androidx.annotation.Nullable; import com.android.launcher3.icons.BitmapInfo.Extender; import com.android.launcher3.icons.ClockDrawableWrapper.ClockBitmapInfo; import com.android.launcher3.icons.cache.BaseIconCache; import java.io.ByteArrayInputStream; Loading @@ -63,7 +67,7 @@ public class ThemedIconDrawable extends FastBitmapDrawable { private final Rect mBadgeBounds; protected ThemedIconDrawable(ThemedConstantState constantState) { super(constantState.mBitmap, constantState.mIconColor, constantState.mIsDisabled); super(constantState.mBitmap, constantState.colorFg, constantState.mIsDisabled); bitmapInfo = constantState.bitmapInfo; colorBg = constantState.colorBg; colorFg = constantState.colorFg; Loading @@ -72,6 +76,7 @@ public class ThemedIconDrawable extends FastBitmapDrawable { mBgWrapper = new AdaptiveIconDrawable(new ColorDrawable(colorBg), null); mBadgeBounds = bitmapInfo.mUserBadge == null ? null : new Rect(0, 0, bitmapInfo.mUserBadge.getWidth(), bitmapInfo.mUserBadge.getHeight()); } @Override Loading Loading @@ -147,7 +152,7 @@ public class ThemedIconDrawable extends FastBitmapDrawable { if (isNullOrLowRes()) { return null; } String resName = mThemeData.mResources.getResourceName(mThemeData.mIconID); String resName = mThemeData.mResources.getResourceName(mThemeData.mResID); ByteArrayOutputStream out = new ByteArrayOutputStream( getExpectedBitmapSize(icon) + 3 + resName.length()); try { Loading Loading @@ -200,30 +205,46 @@ public class ThemedIconDrawable extends FastBitmapDrawable { public static class ThemeData { final Resources mResources; final int mIconID; final int mResID; public ThemeData(Resources resources, int iconID) { public ThemeData(Resources resources, int resID) { mResources = resources; mIconID = iconID; mResID = resID; } Drawable loadMonochromeDrawable(int accentColor) { Drawable d = mResources.getDrawable(mIconID).mutate(); Drawable d = mResources.getDrawable(mResID).mutate(); d.setTint(accentColor); d = new InsetDrawable(d, .15f); d = new InsetDrawable(d, .2f); return d; } public Drawable wrapDrawable(Drawable original) { return (original instanceof AdaptiveIconDrawable) ? new ThemedAdaptiveIcon((AdaptiveIconDrawable) original, this) : original; public Drawable wrapDrawable(Drawable original, int iconType) { if (!(original instanceof AdaptiveIconDrawable)) { return original; } AdaptiveIconDrawable aid = (AdaptiveIconDrawable) original; String resourceType = mResources.getResourceTypeName(mResID); if (iconType == ICON_TYPE_CALENDAR && "array".equals(resourceType)) { TypedArray ta = mResources.obtainTypedArray(mResID); int id = ta.getResourceId(IconProvider.getDay(), ID_NULL); ta.recycle(); return id == ID_NULL ? original : new ThemedAdaptiveIcon(aid, new ThemeData(mResources, id)); } else if (iconType == ICON_TYPE_CLOCK && "array".equals(resourceType)) { ((ClockDrawableWrapper) original).mThemeData = this; return original; } else if ("drawable".equals(resourceType)) { return new ThemedAdaptiveIcon(aid, this); } else { return original; } } } public static class ThemedAdaptiveIcon extends AdaptiveIconDrawable implements Extender { static class ThemedAdaptiveIcon extends AdaptiveIconDrawable implements Extender { private final ThemeData mThemeData; protected final ThemeData mThemeData; public ThemedAdaptiveIcon(AdaptiveIconDrawable parent, ThemeData themeData) { super(parent.getBackground(), parent.getForeground()); Loading @@ -243,9 +264,7 @@ public class ThemedIconDrawable extends FastBitmapDrawable { draw(canvas); } /** * Returns a new icon with theme applied */ @Override public Drawable getThemedDrawable(Context context) { int[] colors = getColors(context); Drawable bg = new ColorDrawable(colors[0]); Loading