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

Commit 4d20ee8c authored by Hyunyoung Song's avatar Hyunyoung Song Committed by Android (Google) Code Review
Browse files

Merge "Icon class should support Maskable bitmap type"

parents 817c2097 9ee90a42
Loading
Loading
Loading
Loading
+2 −3
Original line number Diff line number Diff line
@@ -13780,6 +13780,7 @@ package android.graphics.drawable {
    method public static android.graphics.drawable.Icon createWithContentUri(android.net.Uri);
    method public static android.graphics.drawable.Icon createWithData(byte[], int, int);
    method public static android.graphics.drawable.Icon createWithFilePath(java.lang.String);
    method public static android.graphics.drawable.Icon createWithMaskableBitmap(android.graphics.Bitmap);
    method public static android.graphics.drawable.Icon createWithResource(android.content.Context, int);
    method public static android.graphics.drawable.Icon createWithResource(java.lang.String, int);
    method public int describeContents();
@@ -13863,9 +13864,9 @@ package android.graphics.drawable {
  }
  public class MaskableIconDrawable extends android.graphics.drawable.Drawable implements android.graphics.drawable.Drawable.Callback {
    ctor public MaskableIconDrawable(android.graphics.drawable.Drawable, android.graphics.drawable.Drawable);
    method public void draw(android.graphics.Canvas);
    method public android.graphics.drawable.Drawable getBackground();
    method public static float getExtraInsetPercentage();
    method public android.graphics.drawable.Drawable getForeground();
    method public android.graphics.Path getIconMask();
    method public int getOpacity();
@@ -13875,8 +13876,6 @@ package android.graphics.drawable {
    method public void setColorFilter(android.graphics.ColorFilter);
    method public void setOpacity(int);
    method public void unscheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable);
    field public static final float DEFAULT_VIEW_PORT_SCALE = 0.6666667f;
    field public static final float MASK_SIZE = 100.0f;
  }
  public class NinePatchDrawable extends android.graphics.drawable.Drawable {
+2 −3
Original line number Diff line number Diff line
@@ -14369,6 +14369,7 @@ package android.graphics.drawable {
    method public static android.graphics.drawable.Icon createWithContentUri(android.net.Uri);
    method public static android.graphics.drawable.Icon createWithData(byte[], int, int);
    method public static android.graphics.drawable.Icon createWithFilePath(java.lang.String);
    method public static android.graphics.drawable.Icon createWithMaskableBitmap(android.graphics.Bitmap);
    method public static android.graphics.drawable.Icon createWithResource(android.content.Context, int);
    method public static android.graphics.drawable.Icon createWithResource(java.lang.String, int);
    method public int describeContents();
@@ -14452,9 +14453,9 @@ package android.graphics.drawable {
  }
  public class MaskableIconDrawable extends android.graphics.drawable.Drawable implements android.graphics.drawable.Drawable.Callback {
    ctor public MaskableIconDrawable(android.graphics.drawable.Drawable, android.graphics.drawable.Drawable);
    method public void draw(android.graphics.Canvas);
    method public android.graphics.drawable.Drawable getBackground();
    method public static float getExtraInsetPercentage();
    method public android.graphics.drawable.Drawable getForeground();
    method public android.graphics.Path getIconMask();
    method public int getOpacity();
@@ -14464,8 +14465,6 @@ package android.graphics.drawable {
    method public void setColorFilter(android.graphics.ColorFilter);
    method public void setOpacity(int);
    method public void unscheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable);
    field public static final float DEFAULT_VIEW_PORT_SCALE = 0.6666667f;
    field public static final float MASK_SIZE = 100.0f;
  }
  public class NinePatchDrawable extends android.graphics.drawable.Drawable {
+3 −3
Original line number Diff line number Diff line
@@ -13814,6 +13814,7 @@ package android.graphics.drawable {
    method public static android.graphics.drawable.Icon createWithContentUri(android.net.Uri);
    method public static android.graphics.drawable.Icon createWithData(byte[], int, int);
    method public static android.graphics.drawable.Icon createWithFilePath(java.lang.String);
    method public static android.graphics.drawable.Icon createWithMaskableBitmap(android.graphics.Bitmap);
    method public static android.graphics.drawable.Icon createWithResource(android.content.Context, int);
    method public static android.graphics.drawable.Icon createWithResource(java.lang.String, int);
    method public int describeContents();
@@ -13897,20 +13898,19 @@ package android.graphics.drawable {
  }
  public class MaskableIconDrawable extends android.graphics.drawable.Drawable implements android.graphics.drawable.Drawable.Callback {
    ctor public MaskableIconDrawable(android.graphics.drawable.Drawable, android.graphics.drawable.Drawable);
    method public void draw(android.graphics.Canvas);
    method public android.graphics.drawable.Drawable getBackground();
    method public static float getExtraInsetPercentage();
    method public android.graphics.drawable.Drawable getForeground();
    method public android.graphics.Path getIconMask();
    method public int getOpacity();
    method public android.graphics.Region getSafeZone();
    method public void invalidateDrawable(android.graphics.drawable.Drawable);
    method public void scheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable, long);
    method public void setAlpha(int);
    method public void setColorFilter(android.graphics.ColorFilter);
    method public void setOpacity(int);
    method public void unscheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable);
    field public static final float DEFAULT_VIEW_PORT_SCALE = 0.6666667f;
    field public static final float MASK_SIZE = 100.0f;
  }
  public class NinePatchDrawable extends android.graphics.drawable.Drawable {
+31 −3
Original line number Diff line number Diff line
@@ -67,6 +67,8 @@ public final class Icon implements Parcelable {
    public static final int TYPE_DATA     = 3;
    /** @hide */
    public static final int TYPE_URI      = 4;
    /** @hide */
    public static final int TYPE_BITMAP_MASKABLE      = 5;

    private static final int VERSION_STREAM_SERIALIZER = 1;

@@ -101,6 +103,7 @@ public final class Icon implements Parcelable {
     * {@link #TYPE_RESOURCE},
     * {@link #TYPE_DATA}, or
     * {@link #TYPE_URI}.
     * {@link #TYPE_BITMAP_MASKABLE}
     * @hide
     */
    public int getType() {
@@ -112,7 +115,7 @@ public final class Icon implements Parcelable {
     * @hide
     */
    public Bitmap getBitmap() {
        if (mType != TYPE_BITMAP) {
        if (mType != TYPE_BITMAP && mType != TYPE_BITMAP_MASKABLE) {
            throw new IllegalStateException("called getBitmap() on " + this);
        }
        return (Bitmap) mObj1;
@@ -218,6 +221,7 @@ public final class Icon implements Parcelable {
    private static final String typeToString(int x) {
        switch (x) {
            case TYPE_BITMAP: return "BITMAP";
            case TYPE_BITMAP_MASKABLE: return "BITMAP_MASKABLE";
            case TYPE_DATA: return "DATA";
            case TYPE_RESOURCE: return "RESOURCE";
            case TYPE_URI: return "URI";
@@ -285,6 +289,9 @@ public final class Icon implements Parcelable {
        switch (mType) {
            case TYPE_BITMAP:
                return new BitmapDrawable(context.getResources(), getBitmap());
            case TYPE_BITMAP_MASKABLE:
                return new MaskableIconDrawable(null,
                    new BitmapDrawable(context.getResources(), getBitmap()));
            case TYPE_RESOURCE:
                if (getResources() == null) {
                    // figure out where to load resources from
@@ -388,7 +395,7 @@ public final class Icon implements Parcelable {
     * @hide
     */
    public void convertToAshmem() {
        if (mType == TYPE_BITMAP &&
        if ((mType == TYPE_BITMAP || mType == TYPE_BITMAP_MASKABLE) &&
            getBitmap().isMutable() &&
            getBitmap().getAllocationByteCount() >= MIN_ASHMEM_ICON_SIZE) {
            setBitmap(getBitmap().createAshmemBitmap());
@@ -409,6 +416,7 @@ public final class Icon implements Parcelable {

        switch (mType) {
            case TYPE_BITMAP:
            case TYPE_BITMAP_MASKABLE:
                getBitmap().compress(Bitmap.CompressFormat.PNG, 100, dataStream);
                break;
            case TYPE_DATA:
@@ -444,6 +452,8 @@ public final class Icon implements Parcelable {
            switch (type) {
                case TYPE_BITMAP:
                    return createWithBitmap(BitmapFactory.decodeStream(inputStream));
                case TYPE_BITMAP_MASKABLE:
                    return createWithMaskableBitmap(BitmapFactory.decodeStream(inputStream));
                case TYPE_DATA:
                    final int length = inputStream.readInt();
                    final byte[] data = new byte[length];
@@ -478,6 +488,7 @@ public final class Icon implements Parcelable {
        }
        switch (mType) {
            case TYPE_BITMAP:
            case TYPE_BITMAP_MASKABLE:
                return getBitmap() == otherIcon.getBitmap();
            case TYPE_DATA:
                return getDataLength() == otherIcon.getDataLength()
@@ -550,6 +561,20 @@ public final class Icon implements Parcelable {
        return rep;
    }

    /**
     * Create an Icon pointing to a bitmap in memory that follows the icon design guideline defined
     * by {@link MaskableIconDrawable}.
     * @param bits A valid {@link android.graphics.Bitmap} object
     */
    public static Icon createWithMaskableBitmap(Bitmap bits) {
        if (bits == null) {
            throw new IllegalArgumentException("Bitmap must not be null.");
        }
        final Icon rep = new Icon(TYPE_BITMAP_MASKABLE);
        rep.setBitmap(bits);
        return rep;
    }

    /**
     * Create an Icon pointing to a compressed bitmap stored in a byte array.
     * @param data Byte array storing compressed bitmap data of a type that
@@ -654,6 +679,7 @@ public final class Icon implements Parcelable {
        final StringBuilder sb = new StringBuilder("Icon(typ=").append(typeToString(mType));
        switch (mType) {
            case TYPE_BITMAP:
            case TYPE_BITMAP_MASKABLE:
                sb.append(" size=")
                        .append(getBitmap().getWidth())
                        .append("x")
@@ -692,7 +718,7 @@ public final class Icon implements Parcelable {
     * Parcelable interface
     */
    public int describeContents() {
        return (mType == TYPE_BITMAP || mType == TYPE_DATA)
        return (mType == TYPE_BITMAP || mType == TYPE_BITMAP_MASKABLE || mType == TYPE_DATA)
                ? Parcelable.CONTENTS_FILE_DESCRIPTOR : 0;
    }

@@ -702,6 +728,7 @@ public final class Icon implements Parcelable {
        this(in.readInt());
        switch (mType) {
            case TYPE_BITMAP:
            case TYPE_BITMAP_MASKABLE:
                final Bitmap bits = Bitmap.CREATOR.createFromParcel(in);
                mObj1 = bits;
                break;
@@ -740,6 +767,7 @@ public final class Icon implements Parcelable {
        dest.writeInt(mType);
        switch (mType) {
            case TYPE_BITMAP:
            case TYPE_BITMAP_MASKABLE:
                final Bitmap bits = getBitmap();
                getBitmap().writeToParcel(dest, flags);
                break;
+50 −8
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import static android.graphics.drawable.Drawable.obtainAttributes;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.TestApi;
import android.content.pm.ActivityInfo.Config;
import android.content.res.ColorStateList;
import android.content.res.Resources;
@@ -62,17 +63,22 @@ public class MaskableIconDrawable extends Drawable implements Drawable.Callback

    /**
     * Mask path is defined inside device configuration in following dimension: [100 x 100]
     * @hide
     */
    public static final float MASK_SIZE = 100f;
    private static final float SAFEZONE_SCALE = .9f;

    /**
     * The view port of the layers is smaller than their intrinsic width and height by this factor.
     *
     * It is part of the API contract that all four sides of the layers are padded so as to provide
     * All four sides of the layers are padded with extra inset so as to provide
     * extra content to reveal within the clip path when performing affine transformations on the
     * layers.
     *
     * Each layers will reserve 25% of it's width and height.
     *
     * As a result, the view port of the layers is smaller than their intrinsic width and height.
     */
    public static final float DEFAULT_VIEW_PORT_SCALE = 2f / 3f;
    private static final float EXTRA_INSET_PERCENTAGE = 1 / 4f;
    private static final float DEFAULT_VIEW_PORT_SCALE = 1f / (1 + 2 * EXTRA_INSET_PERCENTAGE);

    /**
     * Clip path defined in {@link com.android.internal.R.string.config_icon_mask}.
@@ -155,13 +161,18 @@ public class MaskableIconDrawable extends Drawable implements Drawable.Callback
     *
     * @param backgroundDrawable drawable that should be rendered in the background
     * @param foregroundDrawable drawable that should be rendered in the foreground
     * @hide
     */
    public MaskableIconDrawable(Drawable backgroundDrawable,
            Drawable foregroundDrawable) {
        this((LayerState)null, null);
        if (backgroundDrawable != null) {
            addLayer(BACKGROUND_ID, createChildDrawable(backgroundDrawable));
        }
        if (foregroundDrawable != null) {
            addLayer(FOREGROUND_ID, createChildDrawable(foregroundDrawable));
        }
    }

    /**
     * Sets the layer to the {@param index} and invalidates cache.
@@ -198,6 +209,15 @@ public class MaskableIconDrawable extends Drawable implements Drawable.Callback
        inflateLayers(r, parser, attrs, theme);
    }

    /**
     * All four sides of the layers are padded with extra inset so as to provide
     * extra content to reveal within the clip path when performing affine transformations on the
     * layers.
     */
    public static float getExtraInsetPercentage() {
        return EXTRA_INSET_PERCENTAGE;
    }

    /**
     * @return the mask path object used to clip the drawable
     */
@@ -242,13 +262,20 @@ public class MaskableIconDrawable extends Drawable implements Drawable.Callback
        int cY = bounds.centerY();

        for (int i = 0, count = mLayerState.N_CHILDREN; i < count; i++) {
            final ChildDrawable r = mLayerState.mChildren[i];
            if (r == null) {
                continue;
            }
            final Drawable d = r.mDrawable;
            if (d == null) {
                continue;
            }

            int insetWidth = (int) (bounds.width() / (DEFAULT_VIEW_PORT_SCALE * 2));
            int insetHeight = (int) (bounds.height() / (DEFAULT_VIEW_PORT_SCALE * 2));
            final Rect outRect = mTmpOutRect;
            outRect.set(cX - insetWidth, cY - insetHeight, cX + insetWidth, cY + insetHeight);

            final ChildDrawable r = mLayerState.mChildren[i];
            final Drawable d = r.mDrawable;
            d.setBounds(outRect);
        }
    }
@@ -273,6 +300,9 @@ public class MaskableIconDrawable extends Drawable implements Drawable.Callback
        if (mLayersShader == null) {
            mCanvas.setBitmap(mLayersBitmap);
            for (int i = 0; i < mLayerState.N_CHILDREN; i++) {
                if (mLayerState.mChildren[i] == null) {
                    continue;
                }
                final Drawable dr = mLayerState.mChildren[i].mDrawable;
                if (dr != null) {
                    dr.draw(mCanvas);
@@ -295,6 +325,18 @@ public class MaskableIconDrawable extends Drawable implements Drawable.Callback
        outline.setConvexPath(mMask);
    }

    /** @hide */
    @TestApi
    public Region getSafeZone() {
        mMaskMatrix.reset();
        mMaskMatrix.setScale(SAFEZONE_SCALE, SAFEZONE_SCALE, getBounds().centerX(), getBounds().centerY());
        Path p = new Path();
        mMask.transform(mMaskMatrix, p);
        Region safezoneRegion = new Region(getBounds());
        safezoneRegion.setPath(p, safezoneRegion);
        return safezoneRegion;
    }

    @Override
    public @Nullable Region getTransparentRegion() {
        if (mTransparentRegion.isEmpty()) {
Loading