Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f90d7a97 authored by Sunny Goyal's avatar Sunny Goyal
Browse files

Generalizing monochrome icon into theme icon

Bug: 381897614
Flag: EXEMPT refactor
Test: atest MonoIconThemeControllerTest
      atest MonoThemedBitmapTest

Change-Id: I8e0f594498c16a1afd8dc7b24727235455065852
parent 0a6acc76
Loading
Loading
Loading
Loading
+9 −41
Original line number Diff line number Diff line
@@ -87,7 +87,7 @@ public class BaseIconFactory implements AutoCloseable {
    protected final int mFullResIconDpi;
    protected final int mIconBitmapSize;

    protected boolean mMonoIconEnabled;
    protected IconThemeController mThemeController;

    @Nullable
    private IconNormalizer mNormalizer;
@@ -144,6 +144,11 @@ public class BaseIconFactory implements AutoCloseable {
        return mNormalizer;
    }

    @Nullable
    public IconThemeController getThemeController() {
        return mThemeController;
    }

    public int getFullResIconDpi() {
        return mFullResIconDpi;
    }
@@ -237,30 +242,13 @@ public class BaseIconFactory implements AutoCloseable {

        if (adaptiveIcon instanceof BitmapInfo.Extender extender) {
            info = extender.getExtendedInfo(bitmap, color, this, scale[0]);
        } else if (IconProvider.ATLEAST_T && mMonoIconEnabled) {
            Drawable mono = getMonochromeDrawable(adaptiveIcon);
            if (mono != null) {
                info.setMonoIcon(createIconBitmap(mono, scale[0], MODE_ALPHA), this);
            }
        } else if (IconProvider.ATLEAST_T && mThemeController != null && adaptiveIcon != null) {
            info.setThemedBitmap(mThemeController.createThemedBitmap(adaptiveIcon, info, this));
        }
        info = info.withFlags(getBitmapFlagOp(options));
        return info;
    }

    /**
     * Returns a monochromatic version of the given drawable or null, if it is not supported
     *
     * @param base the original icon
     */
    @TargetApi(Build.VERSION_CODES.TIRAMISU)
    protected Drawable getMonochromeDrawable(AdaptiveIconDrawable base) {
        Drawable mono = base.getMonochrome();
        if (mono != null) {
            return new ClippedMonoDrawable(mono);
        }
        return null;
    }

    @NonNull
    public FlagOp getBitmapFlagOp(@Nullable IconOptions options) {
        FlagOp op = FlagOp.NO_OP;
@@ -386,7 +374,7 @@ public class BaseIconFactory implements AutoCloseable {
    }

    @NonNull
    protected Bitmap createIconBitmap(@Nullable final Drawable icon, final float scale,
    public Bitmap createIconBitmap(@Nullable final Drawable icon, final float scale,
            @BitmapGenerationMode int bitmapGenerationMode) {
        final int size = mIconBitmapSize;
        final Bitmap bitmap;
@@ -610,26 +598,6 @@ public class BaseIconFactory implements AutoCloseable {
        }
    }

    protected static class ClippedMonoDrawable extends InsetDrawable {

        @NonNull
        private final AdaptiveIconDrawable mCrop;

        public ClippedMonoDrawable(@Nullable final Drawable base) {
            super(base, -getExtraInsetFraction());
            mCrop = new AdaptiveIconDrawable(new ColorDrawable(Color.BLACK), null);
        }

        @Override
        public void draw(Canvas canvas) {
            mCrop.setBounds(getBounds());
            int saveCount = canvas.save();
            canvas.clipPath(mCrop.getIconMask());
            super.draw(canvas);
            canvas.restoreToCount(saveCount);
        }
    }

    private static class CenterTextDrawable extends ColorDrawable {

        @NonNull
+11 −13
Original line number Diff line number Diff line
@@ -60,8 +60,7 @@ public class BitmapInfo {
    public final int color;

    @Nullable
    protected Bitmap mMono;
    protected Bitmap mWhiteShadowLayer;
    private ThemedBitmap mThemedBitmap;

    public @BitmapInfoFlags int flags;
    private BitmapInfo badgeInfo;
@@ -90,8 +89,7 @@ public class BitmapInfo {
    }

    protected BitmapInfo copyInternalsTo(BitmapInfo target) {
        target.mMono = mMono;
        target.mWhiteShadowLayer = mWhiteShadowLayer;
        target.mThemedBitmap = mThemedBitmap;
        target.flags = flags;
        target.badgeInfo = badgeInfo;
        return target;
@@ -102,9 +100,13 @@ public class BitmapInfo {
        return copyInternalsTo(new BitmapInfo(icon, color));
    }

    public void setMonoIcon(Bitmap mono, BaseIconFactory iconFactory) {
        mMono = mono;
        mWhiteShadowLayer = iconFactory.getWhiteShadowLayer();
    public void setThemedBitmap(@Nullable ThemedBitmap themedBitmap) {
        mThemedBitmap = themedBitmap;
    }

    @Nullable
    public ThemedBitmap getThemedBitmap() {
        return mThemedBitmap;
    }

    /**
@@ -125,10 +127,6 @@ public class BitmapInfo {
        return !isNullOrLowRes();
    }

    public Bitmap getMono() {
        return mMono;
    }

    /**
     * Creates a drawable for the provided BitmapInfo
     */
@@ -143,8 +141,8 @@ public class BitmapInfo {
        FastBitmapDrawable drawable;
        if (isLowRes()) {
            drawable = new PlaceHolderIconDrawable(this, context);
        } else  if ((creationFlags & FLAG_THEMED) != 0 && mMono != null) {
            drawable = ThemedIconDrawable.newDrawable(this, context);
        } else  if ((creationFlags & FLAG_THEMED) != 0 && mThemedBitmap != null) {
            drawable = mThemedBitmap.newDrawable(this, context);
        } else {
            drawable = new FastBitmapDrawable(this);
        }
+4 −44
Original line number Diff line number Diff line
@@ -22,7 +22,6 @@ 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.BlendMode;
import android.graphics.BlendModeColorFilter;
@@ -39,11 +38,8 @@ import android.os.Build;
import android.os.Bundle;
import android.os.SystemClock;
import android.util.Log;
import android.util.TypedValue;

import androidx.annotation.Nullable;

import com.android.launcher3.icons.IconProvider.ThemeData;
import com.android.launcher3.icons.mono.ThemedIconDrawable;

import java.util.Calendar;
import java.util.concurrent.TimeUnit;
@@ -53,7 +49,6 @@ import java.util.function.IntFunction;
 * Wrapper over {@link AdaptiveIconDrawable} to intercept icon flattening logic for dynamic
 * clock icons
 */
@TargetApi(Build.VERSION_CODES.O)
public class ClockDrawableWrapper extends AdaptiveIconDrawable implements BitmapInfo.Extender {

    public static boolean sRunningInTest = false;
@@ -94,34 +89,6 @@ public class ClockDrawableWrapper extends AdaptiveIconDrawable implements Bitmap
        super(base.getBackground(), base.getForeground());
    }

    private void applyThemeData(ThemeData themeData) {
        if (!IconProvider.ATLEAST_T || mThemeInfo != null) {
            return;
        }
        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(extras, resId -> {
                Drawable bg = new ColorDrawable(Color.WHITE);
                Drawable fg = themeData.mResources.getDrawable(resId).mutate();
                return new AdaptiveIconDrawable(bg, fg);
            });
            if (drawable != null) {
                mThemeInfo = drawable.mAnimationInfo;
            }
        } catch (Exception e) {
            Log.e(TAG, "Error loading themed clock", e);
        }
    }

    @Override
    public Drawable getMonochrome() {
        if (mThemeInfo == null) {
@@ -140,26 +107,19 @@ public class ClockDrawableWrapper extends AdaptiveIconDrawable implements Bitmap
     * Loads and returns the wrapper from the provided package, or returns null
     * if it is unable to load.
     */
    public static ClockDrawableWrapper forPackage(Context context, String pkg, int iconDpi,
            @Nullable ThemeData themeData) {
    public static ClockDrawableWrapper forPackage(Context context, String pkg, int iconDpi) {
        try {
            PackageManager pm = context.getPackageManager();
            ApplicationInfo appInfo =  pm.getApplicationInfo(pkg,
                    PackageManager.MATCH_UNINSTALLED_PACKAGES | PackageManager.GET_META_DATA);
            Resources res = pm.getResourcesForApplication(appInfo);
            ClockDrawableWrapper wrapper = forExtras(appInfo.metaData,
                    resId -> res.getDrawableForDensity(resId, iconDpi));
            if (wrapper != null && themeData != null) {
                wrapper.applyThemeData(themeData);
            }
            return wrapper;
            return forExtras(appInfo.metaData, resId -> res.getDrawableForDensity(resId, iconDpi));
        } catch (Exception e) {
            Log.d(TAG, "Unable to load clock drawable info", e);
        }
        return null;
    }

    @TargetApi(Build.VERSION_CODES.TIRAMISU)
    private static ClockDrawableWrapper forExtras(
            Bundle metadata, IntFunction<Drawable> drawableProvider) {
        if (metadata == null) {
@@ -220,7 +180,7 @@ public class ClockDrawableWrapper extends AdaptiveIconDrawable implements Bitmap
                BaseIconFactory.MODE_HARDWARE_WITH_SHADOW);

        // Only pass theme info if mono-icon is enabled
        AnimationInfo themeInfo = iconFactory.mMonoIconEnabled ? mThemeInfo : null;
        AnimationInfo themeInfo = iconFactory.getThemeController() != null ? mThemeInfo : null;
        Bitmap themeBG = themeInfo == null ? null : iconFactory.getWhiteShadowLayer();
        return new ClockBitmapInfo(bitmap, color, normalizationScale,
                mAnimationInfo, flattenBG, themeInfo, themeBG);
+1 −1
Original line number Diff line number Diff line
@@ -73,7 +73,7 @@ public class FastBitmapDrawable extends Drawable implements Drawable.Callback {
    @VisibleForTesting protected boolean mIsPressed;
    @VisibleForTesting protected boolean mIsHovered;
    protected boolean mIsDisabled;
    float mDisabledAlpha = 1f;
    protected float mDisabledAlpha = 1f;

    @DrawableCreationFlags int mCreationFlags = 0;

+1 −1
Original line number Diff line number Diff line
@@ -151,7 +151,7 @@ public class IconProvider {
        if (mCalendar != null && mCalendar.getPackageName().equals(packageName)) {
            icon = loadCalendarDrawable(iconDpi, td);
        } else if (mClock != null && mClock.getPackageName().equals(packageName)) {
            icon = ClockDrawableWrapper.forPackage(mContext, mClock.getPackageName(), iconDpi, td);
            icon = ClockDrawableWrapper.forPackage(mContext, mClock.getPackageName(), iconDpi);
        }
        if (icon == null) {
            icon = loadPackageIcon(info, appInfo, iconDpi);
Loading