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

Commit be1055f1 authored by Android Build Coastguard Worker's avatar Android Build Coastguard Worker
Browse files

Snap for 12918425 from c40e2aa0 to 25Q2-release

Change-Id: Icda3b6ccf3a71779f87b33f7362dba78164df0cb
parents 16aa76ca c40e2aa0
Loading
Loading
Loading
Loading
+59 −41
Original line number Diff line number Diff line
package com.android.launcher3.icons;

import static android.graphics.Color.BLACK;
import static android.graphics.Paint.ANTI_ALIAS_FLAG;
import static android.graphics.Paint.DITHER_FLAG;
import static android.graphics.Paint.FILTER_BITMAP_FLAG;
@@ -7,6 +8,7 @@ import static android.graphics.drawable.AdaptiveIconDrawable.getExtraInsetFracti

import static com.android.launcher3.icons.BitmapInfo.FLAG_INSTANT;
import static com.android.launcher3.icons.ShadowGenerator.BLUR_FACTOR;
import static com.android.launcher3.icons.ShadowGenerator.ICON_SCALE_FOR_SHADOWS;

import static java.lang.annotation.RetentionPolicy.SOURCE;

@@ -21,8 +23,8 @@ import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PaintFlagsDrawFilter;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.AdaptiveIconDrawable;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
@@ -38,6 +40,7 @@ import androidx.annotation.IntDef;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.android.launcher3.Flags;
import com.android.launcher3.icons.BitmapInfo.Extender;
import com.android.launcher3.util.FlagOp;
import com.android.launcher3.util.UserIconInfo;
@@ -95,20 +98,20 @@ public class BaseIconFactory implements AutoCloseable {
    @Nullable
    private ShadowGenerator mShadowGenerator;

    private final boolean mShapeDetection;

    // Shadow bitmap used as background for theme icons
    private Bitmap mWhiteShadowLayer;

    private Drawable mWrapperIcon;
    private int mWrapperBackgroundColor = DEFAULT_WRAPPER_BACKGROUND;

    private static int PLACEHOLDER_BACKGROUND_COLOR = Color.rgb(245, 245, 245);

    protected BaseIconFactory(Context context, int fullResIconDpi, int iconBitmapSize,
            boolean shapeDetection) {
            boolean unused) {
        this(context, fullResIconDpi, iconBitmapSize);
    }

    public BaseIconFactory(Context context, int fullResIconDpi, int iconBitmapSize) {
        mContext = context.getApplicationContext();
        mShapeDetection = shapeDetection;
        mFullResIconDpi = fullResIconDpi;
        mIconBitmapSize = iconBitmapSize;

@@ -120,10 +123,6 @@ public class BaseIconFactory implements AutoCloseable {
        clear();
    }

    public BaseIconFactory(Context context, int fullResIconDpi, int iconBitmapSize) {
        this(context, fullResIconDpi, iconBitmapSize, false);
    }

    protected void clear() {
        mWrapperBackgroundColor = DEFAULT_WRAPPER_BACKGROUND;
    }
@@ -139,7 +138,7 @@ public class BaseIconFactory implements AutoCloseable {
    @NonNull
    public IconNormalizer getNormalizer() {
        if (mNormalizer == null) {
            mNormalizer = new IconNormalizer(mContext, mIconBitmapSize, mShapeDetection);
            mNormalizer = new IconNormalizer(mContext, mIconBitmapSize);
        }
        return mNormalizer;
    }
@@ -232,7 +231,7 @@ public class BaseIconFactory implements AutoCloseable {
            // Need to convert to Adaptive Icon with insets to avoid cropping.
            tempIcon = createShapedAdaptiveIcon(bitmapDrawable.getBitmap());
        }
        AdaptiveIconDrawable adaptiveIcon = normalizeAndWrapToAdaptiveIcon(tempIcon, null, scale);
        AdaptiveIconDrawable adaptiveIcon = normalizeAndWrapToAdaptiveIcon(tempIcon, scale);
        Bitmap bitmap = createIconBitmap(adaptiveIcon, scale[0],
                options == null ? MODE_WITH_SHADOW : options.mGenerationMode);

@@ -240,7 +239,7 @@ public class BaseIconFactory implements AutoCloseable {
                ? options.mExtractedColor : mColorExtractor.findDominantColorByHue(bitmap);
        BitmapInfo info = BitmapInfo.of(bitmap, color);

        if (adaptiveIcon instanceof BitmapInfo.Extender extender) {
        if (adaptiveIcon instanceof Extender extender) {
            info = extender.getExtendedInfo(bitmap, color, this, scale[0]);
        } else if (IconProvider.ATLEAST_T && mThemeController != null && adaptiveIcon != null) {
            info.setThemedBitmap(mThemeController.createThemedBitmap(adaptiveIcon, info, this));
@@ -286,6 +285,11 @@ public class BaseIconFactory implements AutoCloseable {
        return info;
    }

    @NonNull
    protected Path getShapePath(AdaptiveIconDrawable drawable, Rect iconBounds) {
        return drawable.getIconMask();
    }

    @NonNull
    public Bitmap getWhiteShadowLayer() {
        if (mWhiteShadowLayer == null) {
@@ -298,11 +302,9 @@ public class BaseIconFactory implements AutoCloseable {

    @NonNull
    public Bitmap createScaledBitmap(@NonNull Drawable icon, @BitmapGenerationMode int mode) {
        RectF iconBounds = new RectF();
        float[] scale = new float[1];
        icon = normalizeAndWrapToAdaptiveIcon(icon, iconBounds, scale);
        return createIconBitmap(icon,
                Math.min(scale[0], ShadowGenerator.getScaleForBounds(iconBounds)), mode);
        icon = normalizeAndWrapToAdaptiveIcon(icon, scale);
        return createIconBitmap(icon, Math.min(scale[0], ICON_SCALE_FOR_SHADOWS), mode);
    }

    /**
@@ -313,17 +315,14 @@ public class BaseIconFactory implements AutoCloseable {
    }

    @Nullable
    protected AdaptiveIconDrawable normalizeAndWrapToAdaptiveIcon(@Nullable Drawable icon,
            @Nullable final RectF outIconBounds, @NonNull final float[] outScale) {
    protected AdaptiveIconDrawable normalizeAndWrapToAdaptiveIcon(
            @Nullable Drawable icon, @NonNull final float[] outScale) {
        if (icon == null) {
            return null;
        }

        AdaptiveIconDrawable adaptiveIcon;
        float scale;
        adaptiveIcon = wrapToAdaptiveIcon(icon, outIconBounds);
        scale = getNormalizer().getScale(adaptiveIcon, outIconBounds, null, null);
        outScale[0] = scale;
        AdaptiveIconDrawable adaptiveIcon = wrapToAdaptiveIcon(icon);
        outScale[0] = getNormalizer().getScale(adaptiveIcon);
        return adaptiveIcon;
    }

@@ -348,8 +347,7 @@ public class BaseIconFactory implements AutoCloseable {
    /**
     * Wraps the provided icon in an adaptive icon drawable
     */
    public AdaptiveIconDrawable wrapToAdaptiveIcon(@NonNull Drawable icon,
            @Nullable final RectF outIconBounds) {
    public AdaptiveIconDrawable wrapToAdaptiveIcon(@NonNull Drawable icon) {
        if (icon instanceof AdaptiveIconDrawable aid) {
            return aid;
        } else {
@@ -357,13 +355,8 @@ public class BaseIconFactory implements AutoCloseable {
            AdaptiveIconDrawable dr = new AdaptiveIconDrawable(
                    new ColorDrawable(mWrapperBackgroundColor), foreground);
            dr.setBounds(0, 0, 1, 1);
            boolean[] outShape = new boolean[1];
            float scale = getNormalizer().getScale(icon, outIconBounds, dr.getIconMask(), outShape);
            if (!outShape[0]) {
            float scale = getNormalizer().getScale(icon);
            foreground.setDrawable(createScaledDrawable(icon, scale * LEGACY_ICON_SCALE));
            } else {
                foreground.setDrawable(createScaledDrawable(icon, 1 - getExtraInsetFraction()));
            }
            return dr;
        }
    }
@@ -401,31 +394,31 @@ public class BaseIconFactory implements AutoCloseable {
        return bitmap;
    }

    private void drawIconBitmap(@NonNull Canvas canvas, @Nullable final Drawable icon,
    private void drawIconBitmap(@NonNull Canvas canvas, @Nullable Drawable icon,
            final float scale, @BitmapGenerationMode int bitmapGenerationMode,
            @Nullable Bitmap targetBitmap) {
        final int size = mIconBitmapSize;
        mOldBounds.set(icon.getBounds());

        if (icon instanceof AdaptiveIconDrawable) {
        if (icon instanceof AdaptiveIconDrawable aid) {
            // We are ignoring KEY_SHADOW_DISTANCE because regular icons ignore this at the
            // moment b/298203449
            int offset = Math.max((int) Math.ceil(BLUR_FACTOR * size),
                    Math.round(size * (1 - scale) / 2));
            // b/211896569: AdaptiveIconDrawable do not work properly for non top-left bounds
            icon.setBounds(0, 0, size - offset - offset, size - offset - offset);
            int newBounds = size - offset * 2;
            icon.setBounds(0, 0, newBounds, newBounds);
            Path shapePath = getShapePath(aid, icon.getBounds());
            int count = canvas.save();
            canvas.translate(offset, offset);
            if (bitmapGenerationMode == MODE_WITH_SHADOW
                    || bitmapGenerationMode == MODE_HARDWARE_WITH_SHADOW) {
                getShadowGenerator().addPathShadow(
                        ((AdaptiveIconDrawable) icon).getIconMask(), canvas);
                getShadowGenerator().addPathShadow(shapePath, canvas);
            }

            if (icon instanceof BitmapInfo.Extender) {
            if (icon instanceof Extender) {
                ((Extender) icon).drawForPersistence(canvas);
            } else {
                icon.draw(canvas);
                drawAdaptiveIcon(canvas, aid, shapePath);
            }
            canvas.restoreToCount(count);
        } else {
@@ -473,6 +466,31 @@ public class BaseIconFactory implements AutoCloseable {
        icon.setBounds(mOldBounds);
    }

    /**
     * Draws AdaptiveIconDrawable onto canvas.
     * @param canvas canvas to draw on
     * @param drawable AdaptiveIconDrawable to draw
     * @param overridePath path to clip icon with for shapes
     */
    protected void drawAdaptiveIcon(
            @NonNull Canvas canvas,
            @NonNull AdaptiveIconDrawable drawable,
            @NonNull Path overridePath
    ) {
        if (!Flags.enableLauncherIconShapes()) {
            drawable.draw(canvas);
            return;
        }
        canvas.clipPath(overridePath);
        canvas.drawColor(BLACK);
        if (drawable.getBackground() != null) {
            drawable.getBackground().draw(canvas);
        }
        if (drawable.getForeground() != null) {
            drawable.getForeground().draw(canvas);
        }
    }

    @Override
    public void close() {
        clear();
+1 −3
Original line number Diff line number Diff line
@@ -77,9 +77,7 @@ public class BubbleIconFactory extends BaseIconFactory {
        if (outScale == null) {
            outScale = new float[1];
        }
        icon = normalizeAndWrapToAdaptiveIcon(icon,
                null /* outscale */,
                outScale);
        icon = normalizeAndWrapToAdaptiveIcon(icon, outScale);
        return createIconBitmap(icon, outScale[0], MODE_WITH_SHADOW);
    }

+6 −38
Original line number Diff line number Diff line
@@ -18,7 +18,6 @@ package com.android.launcher3.icons;

import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
@@ -28,17 +27,15 @@ import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Region;
import android.graphics.drawable.AdaptiveIconDrawable;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.util.Log;

import java.nio.ByteBuffer;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import java.nio.ByteBuffer;

public class IconNormalizer {

@@ -72,11 +69,8 @@ public class IconNormalizer {
    private final Paint mPaintMaskShapeOutline;
    private final byte[] mPixels;

    private final RectF mAdaptiveIconBounds;
    private float mAdaptiveIconScale;

    private boolean mEnableShapeDetection;

    // for each y, stores the position of the leftmost x and the rightmost x
    private final float[] mLeftBorder;
    private final float[] mRightBorder;
@@ -85,7 +79,7 @@ public class IconNormalizer {
    private final Matrix mMatrix;

    /** package private **/
    IconNormalizer(Context context, int iconBitmapSize, boolean shapeDetection) {
    IconNormalizer(Context context, int iconBitmapSize) {
        // Use twice the icon size as maximum size to avoid scaling down twice.
        mMaxSize = iconBitmapSize * 2;
        mBitmap = Bitmap.createBitmap(mMaxSize, mMaxSize, Bitmap.Config.ALPHA_8);
@@ -94,7 +88,6 @@ public class IconNormalizer {
        mLeftBorder = new float[mMaxSize];
        mRightBorder = new float[mMaxSize];
        mBounds = new Rect();
        mAdaptiveIconBounds = new RectF();

        mPaintMaskShape = new Paint();
        mPaintMaskShape.setColor(Color.RED);
@@ -111,7 +104,6 @@ public class IconNormalizer {
        mShapePath = new Path();
        mMatrix = new Matrix();
        mAdaptiveIconScale = SCALE_NOT_INITIALIZED;
        mEnableShapeDetection = shapeDetection;
    }

    private static float getScale(float hullArea, float boundingArea, float fullArea) {
@@ -133,7 +125,7 @@ public class IconNormalizer {
     * @param size Canvas size to use
     */
    @TargetApi(Build.VERSION_CODES.O)
    public static float normalizeAdaptiveIcon(Drawable d, int size, @Nullable RectF outBounds) {
    public static float normalizeAdaptiveIcon(Drawable d, int size) {
        Rect tmpBounds = new Rect(d.getBounds());
        d.setBounds(0, 0, size, size);

@@ -141,17 +133,7 @@ public class IconNormalizer {
        Region region = new Region();
        region.setPath(path, new Region(0, 0, size, size));

        Rect hullBounds = region.getBounds();
        int hullArea = GraphicsUtils.getArea(region);

        if (outBounds != null) {
            float sizeF = size;
            outBounds.set(
                    hullBounds.left / sizeF,
                    hullBounds.top / sizeF,
                    1 - (hullBounds.right / sizeF),
                    1 - (hullBounds.bottom / sizeF));
        }
        d.setBounds(tmpBounds);
        return getScale(hullArea, hullArea, size * size);
    }
@@ -233,17 +215,11 @@ public class IconNormalizer {
     *
     * This closeness is used to determine the ratio of hull area to the full icon size.
     * Refer {@link #MAX_CIRCLE_AREA_FACTOR} and {@link #MAX_SQUARE_AREA_FACTOR}
     *
     * @param outBounds optional rect to receive the fraction distance from each edge.
     */
    public synchronized float getScale(@NonNull Drawable d, @Nullable RectF outBounds,
            @Nullable Path path, @Nullable boolean[] outMaskShape) {
    public synchronized float getScale(@NonNull Drawable d) {
        if (d instanceof AdaptiveIconDrawable) {
            if (mAdaptiveIconScale == SCALE_NOT_INITIALIZED) {
                mAdaptiveIconScale = normalizeAdaptiveIcon(d, mMaxSize, mAdaptiveIconBounds);
            }
            if (outBounds != null) {
                outBounds.set(mAdaptiveIconBounds);
                mAdaptiveIconScale = normalizeAdaptiveIcon(d, mMaxSize);
            }
            return mAdaptiveIconScale;
        }
@@ -334,14 +310,6 @@ public class IconNormalizer {
        mBounds.top = topY;
        mBounds.bottom = bottomY;

        if (outBounds != null) {
            outBounds.set(((float) mBounds.left) / width, ((float) mBounds.top) / height,
                    1 - ((float) mBounds.right) / width,
                    1 - ((float) mBounds.bottom) / height);
        }
        if (outMaskShape != null && mEnableShapeDetection && outMaskShape.length > 0) {
            outMaskShape[0] = isShape(path);
        }
        // Area of the rectangle required to fit the convex hull
        float rectArea = (bottomY + 1 - topY) * (rightX + 1 - leftX);
        return getScale(area, rectArea, width * height);
+5 −24
Original line number Diff line number Diff line
@@ -45,6 +45,11 @@ public class ShadowGenerator {
    private static final float HALF_DISTANCE = 0.5f;
    private static final int AMBIENT_SHADOW_ALPHA = 25;

    // Amount by which an icon should be scaled down to make room for shadows.
    // We are ignoring KEY_SHADOW_DISTANCE because regular icons also ignore this: b/298203449
    public static final float ICON_SCALE_FOR_SHADOWS =
            (HALF_DISTANCE - BLUR_FACTOR) / HALF_DISTANCE;

    private final int mIconSize;

    private final Paint mBlurPaint;
@@ -95,30 +100,6 @@ public class ShadowGenerator {
        }
    }

    /**
     * Returns the minimum amount by which an icon with {@param bounds} should be scaled
     * so that the shadows do not get clipped.
     */
    public static float getScaleForBounds(RectF bounds) {
        float scale = 1;

        if (ENABLE_SHADOWS) {
            // For top, left & right, we need same space.
            float minSide = Math.min(Math.min(bounds.left, bounds.right), bounds.top);
            if (minSide < BLUR_FACTOR) {
                scale = (HALF_DISTANCE - BLUR_FACTOR) / (HALF_DISTANCE - minSide);
            }

            // We are ignoring KEY_SHADOW_DISTANCE because regular icons ignore this at the moment b/298203449
            float bottomSpace = BLUR_FACTOR;
            if (bounds.bottom < bottomSpace) {
                scale = Math.min(scale,
                        (HALF_DISTANCE - bottomSpace) / (HALF_DISTANCE - bounds.bottom));
            }
        }
        return scale;
    }

    public static class Builder {

        public final RectF bounds = new RectF();
+1 −6
Original line number Diff line number Diff line
@@ -51,12 +51,7 @@ class MonoIconThemeController : IconThemeController {
        val mono = getMonochromeDrawable(icon, info)
        if (mono != null) {
            val scale =
                factory.normalizer.getScale(
                    AdaptiveIconDrawable(ColorDrawable(Color.BLACK), null),
                    null,
                    null,
                    null,
                )
                factory.normalizer.getScale(AdaptiveIconDrawable(ColorDrawable(Color.BLACK), null))
            return MonoThemedBitmap(
                factory.createIconBitmap(mono, scale, BaseIconFactory.MODE_ALPHA),
                factory.whiteShadowLayer,
Loading