/*
 * Copyright (C) 2006 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.graphics.drawable;

import android.annotation.ColorInt;
import android.annotation.FloatRange;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.Px;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.pm.ActivityInfo.Config;
import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.content.res.Resources.Theme;
import android.content.res.TypedArray;
import android.graphics.BlendMode;
import android.graphics.BlendModeColorFilter;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.DashPathEffect;
import android.graphics.Insets;
import android.graphics.LinearGradient;
import android.graphics.Outline;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PixelFormat;
import android.graphics.RadialGradient;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.SweepGradient;
import android.graphics.Xfermode;
import android.os.Build;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.TypedValue;

import com.android.internal.R;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

/**
 * A Drawable with a color gradient for buttons, backgrounds, etc.
 *
 * <p>It can be defined in an XML file with the <code>&lt;shape></code> element. For more
 * information, see the guide to <a
 * href="{@docRoot}guide/topics/resources/drawable-resource.html">Drawable Resources</a>.</p>
 *
 * @attr ref android.R.styleable#GradientDrawable_visible
 * @attr ref android.R.styleable#GradientDrawable_shape
 * @attr ref android.R.styleable#GradientDrawable_innerRadiusRatio
 * @attr ref android.R.styleable#GradientDrawable_innerRadius
 * @attr ref android.R.styleable#GradientDrawable_thicknessRatio
 * @attr ref android.R.styleable#GradientDrawable_thickness
 * @attr ref android.R.styleable#GradientDrawable_useLevel
 * @attr ref android.R.styleable#GradientDrawableSize_width
 * @attr ref android.R.styleable#GradientDrawableSize_height
 * @attr ref android.R.styleable#GradientDrawableGradient_startColor
 * @attr ref android.R.styleable#GradientDrawableGradient_centerColor
 * @attr ref android.R.styleable#GradientDrawableGradient_endColor
 * @attr ref android.R.styleable#GradientDrawableGradient_useLevel
 * @attr ref android.R.styleable#GradientDrawableGradient_angle
 * @attr ref android.R.styleable#GradientDrawableGradient_type
 * @attr ref android.R.styleable#GradientDrawableGradient_centerX
 * @attr ref android.R.styleable#GradientDrawableGradient_centerY
 * @attr ref android.R.styleable#GradientDrawableGradient_gradientRadius
 * @attr ref android.R.styleable#GradientDrawableSolid_color
 * @attr ref android.R.styleable#GradientDrawableStroke_width
 * @attr ref android.R.styleable#GradientDrawableStroke_color
 * @attr ref android.R.styleable#GradientDrawableStroke_dashWidth
 * @attr ref android.R.styleable#GradientDrawableStroke_dashGap
 * @attr ref android.R.styleable#GradientDrawablePadding_left
 * @attr ref android.R.styleable#GradientDrawablePadding_top
 * @attr ref android.R.styleable#GradientDrawablePadding_right
 * @attr ref android.R.styleable#GradientDrawablePadding_bottom
 */
public class GradientDrawable extends Drawable {

    /**
     * Flag to determine if we should wrap negative gradient angle measurements
     * for API levels that support it
     * @hide
     */
    public static boolean sWrapNegativeAngleMeasurements = true;

    /**
     * Shape is a rectangle, possibly with rounded corners
     */
    public static final int RECTANGLE = 0;

    /**
     * Shape is an ellipse
     */
    public static final int OVAL = 1;

    /**
     * Shape is a line
     */
    public static final int LINE = 2;

    /**
     * Shape is a ring.
     */
    public static final int RING = 3;

    /** @hide */
    @IntDef({RECTANGLE, OVAL, LINE, RING})
    @Retention(RetentionPolicy.SOURCE)
    public @interface Shape {}

    /**
     * Gradient is linear (default.)
     */
    public static final int LINEAR_GRADIENT = 0;

    /**
     * Gradient is circular.
     */
    public static final int RADIAL_GRADIENT = 1;

    /**
     * Gradient is a sweep.
     */
    public static final int SWEEP_GRADIENT  = 2;

    /** @hide */
    @IntDef({LINEAR_GRADIENT, RADIAL_GRADIENT, SWEEP_GRADIENT})
    @Retention(RetentionPolicy.SOURCE)
    public @interface GradientType {}

    /** Radius is in pixels. */
    private static final int RADIUS_TYPE_PIXELS = 0;

    /** Radius is a fraction of the base size. */
    private static final int RADIUS_TYPE_FRACTION = 1;

    /** Radius is a fraction of the bounds size. */
    private static final int RADIUS_TYPE_FRACTION_PARENT = 2;

    /** Default orientation for GradientDrawable **/
    private static final Orientation DEFAULT_ORIENTATION = Orientation.TOP_BOTTOM;

    /** @hide */
    @IntDef({RADIUS_TYPE_PIXELS, RADIUS_TYPE_FRACTION, RADIUS_TYPE_FRACTION_PARENT})
    @Retention(RetentionPolicy.SOURCE)
    public @interface RadiusType {}

    private static final float DEFAULT_INNER_RADIUS_RATIO = 3.0f;
    private static final float DEFAULT_THICKNESS_RATIO = 9.0f;

    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 124050917)
    private GradientState mGradientState;

    @UnsupportedAppUsage
    private final Paint mFillPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 124051827)
    private Rect mPadding;
    @UnsupportedAppUsage
    private Paint mStrokePaint;   // optional, set by the caller
    private ColorFilter mColorFilter;   // optional, set by the caller
    private BlendModeColorFilter mBlendModeColorFilter;
    private int mAlpha = 0xFF;  // modified by the caller

    private final Path mPath = new Path();
    private final RectF mRect = new RectF();

    private Paint mLayerPaint;    // internal, used if we use saveLayer()
    private boolean mGradientIsDirty;
    private boolean mMutated;
    private Path mRingPath;
    private boolean mPathIsDirty = true;

    /** Current gradient radius, valid when {@link #mGradientIsDirty} is false. */
    private float mGradientRadius;

    /**
     * Controls how the gradient is oriented relative to the drawable's bounds
     */
    public enum Orientation {
        /** draw the gradient from the top to the bottom */
        TOP_BOTTOM,
        /** draw the gradient from the top-right to the bottom-left */
        TR_BL,
        /** draw the gradient from the right to the left */
        RIGHT_LEFT,
        /** draw the gradient from the bottom-right to the top-left */
        BR_TL,
        /** draw the gradient from the bottom to the top */
        BOTTOM_TOP,
        /** draw the gradient from the bottom-left to the top-right */
        BL_TR,
        /** draw the gradient from the left to the right */
        LEFT_RIGHT,
        /** draw the gradient from the top-left to the bottom-right */
        TL_BR,
    }

    public GradientDrawable() {
        this(new GradientState(DEFAULT_ORIENTATION, null), null);
    }

    /**
     * Create a new gradient drawable given an orientation and an array
     * of colors for the gradient.
     */
    public GradientDrawable(Orientation orientation, @ColorInt int[] colors) {
        this(new GradientState(orientation, colors), null);
    }

    @Override
    public boolean getPadding(Rect padding) {
        if (mPadding != null) {
            padding.set(mPadding);
            return true;
        } else {
            return super.getPadding(padding);
        }
    }

    /**
     * Specifies radii for each of the 4 corners. For each corner, the array
     * contains 2 values, <code>[X_radius, Y_radius]</code>. The corners are
     * ordered top-left, top-right, bottom-right, bottom-left. This property
     * is honored only when the shape is of type {@link #RECTANGLE}.
     * <p>
     * <strong>Note</strong>: changing this property will affect all instances
     * of a drawable loaded from a resource. It is recommended to invoke
     * {@link #mutate()} before changing this property.
     *
     * @param radii an array of length >= 8 containing 4 pairs of X and Y
     *              radius for each corner, specified in pixels
     *
     * @see #mutate()
     * @see #setShape(int)
     * @see #setCornerRadius(float)
     */
    public void setCornerRadii(@Nullable float[] radii) {
        mGradientState.setCornerRadii(radii);
        mPathIsDirty = true;
        invalidateSelf();
    }

    /**
     * Returns the radii for each of the 4 corners. For each corner, the array
     * contains 2 values, <code>[X_radius, Y_radius]</code>. The corners are
     * ordered top-left, top-right, bottom-right, bottom-left.
     * <p>
     * If the radius was previously set with {@link #setCornerRadius(float)},
     * or if the corners are not rounded, this method will return {@code null}.
     *
     * @return an array containing the radii for each of the 4 corners, or
     *         {@code null}
     * @see #setCornerRadii(float[])
     */
    @Nullable
    public float[] getCornerRadii() {
        float[] radii = mGradientState.mRadiusArray;
        if (radii == null) {
            return null;
        }
        return radii.clone();
    }

    /**
     * Specifies the radius for the corners of the gradient. If this is > 0,
     * then the drawable is drawn in a round-rectangle, rather than a
     * rectangle. This property is honored only when the shape is of type
     * {@link #RECTANGLE}.
     * <p>
     * <strong>Note</strong>: changing this property will affect all instances
     * of a drawable loaded from a resource. It is recommended to invoke
     * {@link #mutate()} before changing this property.
     *
     * @param radius The radius in pixels of the corners of the rectangle shape
     *
     * @see #mutate()
     * @see #setCornerRadii(float[])
     * @see #setShape(int)
     */
    public void setCornerRadius(float radius) {
        mGradientState.setCornerRadius(radius);
        mPathIsDirty = true;
        invalidateSelf();
    }

    /**
     * Returns the radius for the corners of the gradient, that was previously set with
     * {@link #setCornerRadius(float)}.
     * <p>
     * If the radius was previously cleared via passing {@code null}
     * to {@link #setCornerRadii(float[])}, this method will return 0.
     *
     * @return the radius in pixels of the corners of the rectangle shape, or 0
     * @see #setCornerRadius
     */
    public float getCornerRadius() {
        return mGradientState.mRadius;
    }

    /**
     * <p>Set the stroke width and color for the drawable. If width is zero,
     * then no stroke is drawn.</p>
     * <p><strong>Note</strong>: changing this property will affect all instances
     * of a drawable loaded from a resource. It is recommended to invoke
     * {@link #mutate()} before changing this property.</p>
     *
     * @param width The width in pixels of the stroke
     * @param color The color of the stroke
     *
     * @see #mutate()
     * @see #setStroke(int, int, float, float)
     */
    public void setStroke(int width, @ColorInt int color) {
        setStroke(width, color, 0, 0);
    }

    /**
     * <p>Set the stroke width and color state list for the drawable. If width
     * is zero, then no stroke is drawn.</p>
     * <p><strong>Note</strong>: changing this property will affect all instances
     * of a drawable loaded from a resource. It is recommended to invoke
     * {@link #mutate()} before changing this property.</p>
     *
     * @param width The width in pixels of the stroke
     * @param colorStateList The color state list of the stroke
     *
     * @see #mutate()
     * @see #setStroke(int, ColorStateList, float, float)
     */
    public void setStroke(int width, ColorStateList colorStateList) {
        setStroke(width, colorStateList, 0, 0);
    }

    /**
     * <p>Set the stroke width and color for the drawable. If width is zero,
     * then no stroke is drawn. This method can also be used to dash the stroke.</p>
     * <p><strong>Note</strong>: changing this property will affect all instances
     * of a drawable loaded from a resource. It is recommended to invoke
     * {@link #mutate()} before changing this property.</p>
     *
     * @param width The width in pixels of the stroke
     * @param color The color of the stroke
     * @param dashWidth The length in pixels of the dashes, set to 0 to disable dashes
     * @param dashGap The gap in pixels between dashes
     *
     * @see #mutate()
     * @see #setStroke(int, int)
     */
    public void setStroke(int width, @ColorInt int color, float dashWidth, float dashGap) {
        mGradientState.setStroke(width, ColorStateList.valueOf(color), dashWidth, dashGap);
        setStrokeInternal(width, color, dashWidth, dashGap);
    }

    /**
     * <p>Set the stroke width and color state list for the drawable. If width
     * is zero, then no stroke is drawn. This method can also be used to dash
     * the stroke.</p>
     * <p><strong>Note</strong>: changing this property will affect all instances
     * of a drawable loaded from a resource. It is recommended to invoke
     * {@link #mutate()} before changing this property.</p>
     *
     * @param width The width in pixels of the stroke
     * @param colorStateList The color state list of the stroke
     * @param dashWidth The length in pixels of the dashes, set to 0 to disable dashes
     * @param dashGap The gap in pixels between dashes
     *
     * @see #mutate()
     * @see #setStroke(int, ColorStateList)
     */
    public void setStroke(
            int width, ColorStateList colorStateList, float dashWidth, float dashGap) {
        mGradientState.setStroke(width, colorStateList, dashWidth, dashGap);
        final int color;
        if (colorStateList == null) {
            color = Color.TRANSPARENT;
        } else {
            final int[] stateSet = getState();
            color = colorStateList.getColorForState(stateSet, 0);
        }
        setStrokeInternal(width, color, dashWidth, dashGap);
    }

    private void setStrokeInternal(int width, int color, float dashWidth, float dashGap) {
        if (mStrokePaint == null)  {
            mStrokePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
            mStrokePaint.setStyle(Paint.Style.STROKE);
        }
        mStrokePaint.setStrokeWidth(width);
        mStrokePaint.setColor(color);

        DashPathEffect e = null;
        if (dashWidth > 0) {
            e = new DashPathEffect(new float[] { dashWidth, dashGap }, 0);
        }
        mStrokePaint.setPathEffect(e);
        mGradientIsDirty = true;
        invalidateSelf();
    }


    /**
     * <p>Sets the size of the shape drawn by this drawable.</p>
     * <p><strong>Note</strong>: changing this property will affect all instances
     * of a drawable loaded from a resource. It is recommended to invoke
     * {@link #mutate()} before changing this property.</p>
     *
     * @param width The width of the shape used by this drawable
     * @param height The height of the shape used by this drawable
     *
     * @see #mutate()
     * @see #setGradientType(int)
     */
    public void setSize(int width, int height) {
        mGradientState.setSize(width, height);
        mPathIsDirty = true;
        invalidateSelf();
    }

    /**
     * <p>Sets the type of shape used to draw the gradient.</p>
     * <p><strong>Note</strong>: changing this property will affect all instances
     * of a drawable loaded from a resource. It is recommended to invoke
     * {@link #mutate()} before changing this property.</p>
     *
     * @param shape The desired shape for this drawable: {@link #LINE},
     *              {@link #OVAL}, {@link #RECTANGLE} or {@link #RING}
     *
     * @see #mutate()
     */
    public void setShape(@Shape int shape) {
        mRingPath = null;
        mPathIsDirty = true;
        mGradientState.setShape(shape);
        invalidateSelf();
    }

    /**
     * Returns the type of shape used by this drawable, one of {@link #LINE},
     * {@link #OVAL}, {@link #RECTANGLE} or {@link #RING}.
     *
     * @return the type of shape used by this drawable
     * @see #setShape(int)
     */
    @Shape
    public int getShape() {
        return mGradientState.mShape;
    }

    /**
     * Sets the type of gradient used by this drawable.
     * <p>
     * <strong>Note</strong>: changing this property will affect all instances
     * of a drawable loaded from a resource. It is recommended to invoke
     * {@link #mutate()} before changing this property.
     *
     * @param gradient The type of the gradient: {@link #LINEAR_GRADIENT},
     *                 {@link #RADIAL_GRADIENT} or {@link #SWEEP_GRADIENT}
     *
     * @see #mutate()
     * @see #getGradientType()
     */
    public void setGradientType(@GradientType int gradient) {
        mGradientState.setGradientType(gradient);
        mGradientIsDirty = true;
        invalidateSelf();
    }

    /**
     * Returns the type of gradient used by this drawable, one of
     * {@link #LINEAR_GRADIENT}, {@link #RADIAL_GRADIENT}, or
     * {@link #SWEEP_GRADIENT}.
     *
     * @return the type of gradient used by this drawable
     * @see #setGradientType(int)
     */
    @GradientType
    public int getGradientType() {
        return mGradientState.mGradient;
    }

    /**
     * Sets the position of the center of the gradient as a fraction of the
     * width and height.
     * <p>
     * The default value is (0.5, 0.5).
     * <p>
     * <strong>Note</strong>: changing this property will affect all instances
     * of a drawable loaded from a resource. It is recommended to invoke
     * {@link #mutate()} before changing this property.
     *
     * @param x the X-position of the center of the gradient
     * @param y the Y-position of the center of the gradient
     *
     * @see #mutate()
     * @see #setGradientType(int)
     * @see #getGradientCenterX()
     * @see #getGradientCenterY()
     */
    public void setGradientCenter(float x, float y) {
        mGradientState.setGradientCenter(x, y);
        mGradientIsDirty = true;
        invalidateSelf();
    }

    /**
     * Returns the X-position of the center of the gradient as a fraction of
     * the width.
     *
     * @return the X-position of the center of the gradient
     * @see #setGradientCenter(float, float)
     */
    public float getGradientCenterX() {
        return mGradientState.mCenterX;
    }

    /**
     * Returns the Y-position of the center of this gradient as a fraction of
     * the height.
     *
     * @return the Y-position of the center of the gradient
     * @see #setGradientCenter(float, float)
     */
    public float getGradientCenterY() {
        return mGradientState.mCenterY;
    }

    /**
     * Sets the radius of the gradient. The radius is honored only when the
     * gradient type is set to {@link #RADIAL_GRADIENT}.
     * <p>
     * <strong>Note</strong>: changing this property will affect all instances
     * of a drawable loaded from a resource. It is recommended to invoke
     * {@link #mutate()} before changing this property.
     *
     * @param gradientRadius the radius of the gradient in pixels
     *
     * @see #mutate()
     * @see #setGradientType(int)
     * @see #getGradientRadius()
     */
    public void setGradientRadius(float gradientRadius) {
        mGradientState.setGradientRadius(gradientRadius, TypedValue.COMPLEX_UNIT_PX);
        mGradientIsDirty = true;
        invalidateSelf();
    }

    /**
     * Returns the radius of the gradient in pixels. The radius is valid only
     * when the gradient type is set to {@link #RADIAL_GRADIENT}.
     *
     * @return the radius of the gradient in pixels
     * @see #setGradientRadius(float)
     */
    public float getGradientRadius() {
        if (mGradientState.mGradient != RADIAL_GRADIENT) {
            return 0;
        }

        ensureValidRect();
        return mGradientRadius;
    }

    /**
     * Sets whether this drawable's {@code level} property will be used to
     * scale the gradient. If a gradient is not used, this property has no
     * effect.
     * <p>
     * Scaling behavior varies based on gradient type:
     * <ul>
     *     <li>{@link #LINEAR_GRADIENT} adjusts the ending position along the
     *         gradient's axis of orientation (see {@link #getOrientation()})
     *     <li>{@link #RADIAL_GRADIENT} adjusts the outer radius
     *     <li>{@link #SWEEP_GRADIENT} adjusts the ending angle
     * <ul>
     * <p>
     * The default value for this property is {@code false}.
     * <p>
     * <strong>Note</strong>: This property corresponds to the
     * {@code android:useLevel} attribute on the inner {@code <gradient>}
     * tag, NOT the {@code android:useLevel} attribute on the outer
     * {@code <shape>} tag. For example,
     * <pre>{@code
     * <shape ...>
     *     <gradient
     *         ...
     *         android:useLevel="true" />
     * </shape>
     * }</pre><p>
     * <strong>Note</strong>: Changing this property will affect all instances
     * of a drawable loaded from a resource. It is recommended to invoke
     * {@link #mutate()} before changing this property.
     *
     * @param useLevel {@code true} if the gradient should be scaled based on
     *                 level, {@code false} otherwise
     *
     * @see #mutate()
     * @see #setLevel(int)
     * @see #getLevel()
     * @see #getUseLevel()
     * @attr ref android.R.styleable#GradientDrawableGradient_useLevel
     */
    public void setUseLevel(boolean useLevel) {
        mGradientState.mUseLevel = useLevel;
        mGradientIsDirty = true;
        invalidateSelf();
    }

    /**
     * Returns whether this drawable's {@code level} property will be used to
     * scale the gradient.
     *
     * @return {@code true} if the gradient should be scaled based on level,
     *         {@code false} otherwise
     * @see #setUseLevel(boolean)
     * @attr ref android.R.styleable#GradientDrawableGradient_useLevel
     */
    public boolean getUseLevel() {
        return mGradientState.mUseLevel;
    }

    private int modulateAlpha(int alpha) {
        int scale = mAlpha + (mAlpha >> 7);
        return alpha * scale >> 8;
    }

    /**
     * Returns the orientation of the gradient defined in this drawable.
     *
     * @return the orientation of the gradient defined in this drawable
     * @see #setOrientation(Orientation)
     */
    public Orientation getOrientation() {
        return mGradientState.mOrientation;
    }

    /**
     * Sets the orientation of the gradient defined in this drawable.
     * <p>
     * <strong>Note</strong>: changing orientation will affect all instances
     * of a drawable loaded from a resource. It is recommended to invoke
     * {@link #mutate()} before changing the orientation.
     *
     * @param orientation the desired orientation (angle) of the gradient
     *
     * @see #mutate()
     * @see #getOrientation()
     */
    public void setOrientation(Orientation orientation) {
        mGradientState.mOrientation = orientation;
        mGradientIsDirty = true;
        invalidateSelf();
    }

    /**
     * Sets the colors used to draw the gradient.
     * <p>
     * Each color is specified as an ARGB integer and the array must contain at
     * least 2 colors.
     * <p>
     * <strong>Note</strong>: changing colors will affect all instances of a
     * drawable loaded from a resource. It is recommended to invoke
     * {@link #mutate()} before changing the colors.
     *
     * @param colors an array containing 2 or more ARGB colors
     * @see #mutate()
     * @see #setColor(int)
     */
    public void setColors(@Nullable @ColorInt int[] colors) {
        setColors(colors, null);
    }

    /**
     * Sets the colors and offsets used to draw the gradient.
     * <p>
     * Each color is specified as an ARGB integer and the array must contain at
     * least 2 colors.
     * <p>
     * <strong>Note</strong>: changing colors will affect all instances of a
     * drawable loaded from a resource. It is recommended to invoke
     * {@link #mutate()} before changing the colors.
     *
     * @param colors an array containing 2 or more ARGB colors
     * @param offsets optional array of floating point parameters representing the positions
     *                of the colors. Null evenly disperses the colors
     * @see #mutate()
     * @see #setColors(int[])
     */
    public void setColors(@Nullable @ColorInt int[] colors, @Nullable float[] offsets) {
        mGradientState.setGradientColors(colors);
        mGradientState.mPositions = offsets;
        mGradientIsDirty = true;
        invalidateSelf();
    }

    /**
     * Returns the colors used to draw the gradient, or {@code null} if the
     * gradient is drawn using a single color or no colors.
     *
     * @return the colors used to draw the gradient, or {@code null}
     * @see #setColors(int[] colors)
     */
    @Nullable
    public int[] getColors() {
        if (mGradientState.mGradientColors == null) {
            return null;
        } else {
            int[] colors = new int[mGradientState.mGradientColors.length];
            for (int i = 0; i < mGradientState.mGradientColors.length; i++) {
                if (mGradientState.mGradientColors[i] != null) {
                    colors[i] = mGradientState.mGradientColors[i].getDefaultColor();
                }
            }
            return colors;
        }
    }

    @Override
    public void draw(Canvas canvas) {
        if (!ensureValidRect()) {
            // nothing to draw
            return;
        }

        // remember the alpha values, in case we temporarily overwrite them
        // when we modulate them with mAlpha
        final int prevFillAlpha = mFillPaint.getAlpha();
        final int prevStrokeAlpha = mStrokePaint != null ? mStrokePaint.getAlpha() : 0;
        // compute the modulate alpha values
        final int currFillAlpha = modulateAlpha(prevFillAlpha);
        final int currStrokeAlpha = modulateAlpha(prevStrokeAlpha);

        final boolean haveStroke = currStrokeAlpha > 0 && mStrokePaint != null &&
                mStrokePaint.getStrokeWidth() > 0;
        final boolean haveFill = currFillAlpha > 0;
        final GradientState st = mGradientState;
        final ColorFilter colorFilter = mColorFilter != null ? mColorFilter : mBlendModeColorFilter;

        /*  we need a layer iff we're drawing both a fill and stroke, and the
            stroke is non-opaque, and our shapetype actually supports
            fill+stroke. Otherwise we can just draw the stroke (if any) on top
            of the fill (if any) without worrying about blending artifacts.
         */
        final boolean useLayer = haveStroke && haveFill && st.mShape != LINE &&
                 currStrokeAlpha < 255 && (mAlpha < 255 || colorFilter != null);

        /*  Drawing with a layer is slower than direct drawing, but it
            allows us to apply paint effects like alpha and colorfilter to
            the result of multiple separate draws. In our case, if the user
            asks for a non-opaque alpha value (via setAlpha), and we're
            stroking, then we need to apply the alpha AFTER we've drawn
            both the fill and the stroke.
        */
        if (useLayer) {
            if (mLayerPaint == null) {
                mLayerPaint = new Paint();
            }
            mLayerPaint.setDither(st.mDither);
            mLayerPaint.setAlpha(mAlpha);
            mLayerPaint.setColorFilter(colorFilter);

            float rad = mStrokePaint.getStrokeWidth();
            canvas.saveLayer(mRect.left - rad, mRect.top - rad,
                             mRect.right + rad, mRect.bottom + rad,
                             mLayerPaint);

            // don't perform the filter in our individual paints
            // since the layer will do it for us
            mFillPaint.setColorFilter(null);
            mStrokePaint.setColorFilter(null);
        } else {
            /*  if we're not using a layer, apply the dither/filter to our
                individual paints
            */
            mFillPaint.setAlpha(currFillAlpha);
            mFillPaint.setDither(st.mDither);
            mFillPaint.setColorFilter(colorFilter);
            if (colorFilter != null && st.mSolidColors == null) {
                mFillPaint.setColor(mAlpha << 24);
            }
            if (haveStroke) {
                mStrokePaint.setAlpha(currStrokeAlpha);
                mStrokePaint.setDither(st.mDither);
                mStrokePaint.setColorFilter(colorFilter);
            }
        }

        switch (st.mShape) {
            case RECTANGLE:
                if (st.mRadiusArray != null) {
                    buildPathIfDirty();
                    canvas.drawPath(mPath, mFillPaint);
                    if (haveStroke) {
                        canvas.drawPath(mPath, mStrokePaint);
                    }
                } else if (st.mRadius > 0.0f) {
                    // since the caller is only giving us 1 value, we will force
                    // it to be square if the rect is too small in one dimension
                    // to show it. If we did nothing, Skia would clamp the rad
                    // independently along each axis, giving us a thin ellipse
                    // if the rect were very wide but not very tall
                    float rad = Math.min(st.mRadius,
                            Math.min(mRect.width(), mRect.height()) * 0.5f);
                    canvas.drawRoundRect(mRect, rad, rad, mFillPaint);
                    if (haveStroke) {
                        canvas.drawRoundRect(mRect, rad, rad, mStrokePaint);
                    }
                } else {
                    if (mFillPaint.getColor() != 0 || colorFilter != null ||
                            mFillPaint.getShader() != null) {
                        canvas.drawRect(mRect, mFillPaint);
                    }
                    if (haveStroke) {
                        canvas.drawRect(mRect, mStrokePaint);
                    }
                }
                break;
            case OVAL:
                canvas.drawOval(mRect, mFillPaint);
                if (haveStroke) {
                    canvas.drawOval(mRect, mStrokePaint);
                }
                break;
            case LINE: {
                RectF r = mRect;
                float y = r.centerY();
                if (haveStroke) {
                    canvas.drawLine(r.left, y, r.right, y, mStrokePaint);
                }
                break;
            }
            case RING:
                Path path = buildRing(st);
                canvas.drawPath(path, mFillPaint);
                if (haveStroke) {
                    canvas.drawPath(path, mStrokePaint);
                }
                break;
        }

        if (useLayer) {
            canvas.restore();
        } else {
            mFillPaint.setAlpha(prevFillAlpha);
            if (haveStroke) {
                mStrokePaint.setAlpha(prevStrokeAlpha);
            }
        }
    }

    /**
     * @param mode to draw this drawable with
     * @hide
     */
    @Override
    public void setXfermode(@Nullable Xfermode mode) {
        super.setXfermode(mode);
        mFillPaint.setXfermode(mode);
    }

    /**
     * @param aa to draw this drawable with
     * @hide
     */
    public void setAntiAlias(boolean aa) {
        mFillPaint.setAntiAlias(aa);
    }

    private void buildPathIfDirty() {
        final GradientState st = mGradientState;
        if (mPathIsDirty) {
            ensureValidRect();
            mPath.reset();
            mPath.addRoundRect(mRect, st.mRadiusArray, Path.Direction.CW);
            mPathIsDirty = false;
        }
    }

    /**
     * Inner radius of the ring expressed as a ratio of the ring's width.
     *
     * @see #getInnerRadiusRatio()
     * @attr ref android.R.styleable#GradientDrawable_innerRadiusRatio
     */
    public void setInnerRadiusRatio(
            @FloatRange(from = 0.0f, fromInclusive = false) float innerRadiusRatio) {
        if (innerRadiusRatio <= 0) {
            throw new IllegalArgumentException("Ratio must be greater than zero");
        }
        mGradientState.mInnerRadiusRatio = innerRadiusRatio;
        mPathIsDirty = true;
        invalidateSelf();
    }

    /**
     * Return the inner radius of the ring expressed as a ratio of the ring's width.
     *
     * @see #setInnerRadiusRatio(float)
     * @attr ref android.R.styleable#GradientDrawable_innerRadiusRatio
     */
    public float getInnerRadiusRatio() {
        return mGradientState.mInnerRadiusRatio;
    }

    /**
     * Configure the inner radius of the ring.
     *
     * @see #getInnerRadius()
     * @attr ref android.R.styleable#GradientDrawable_innerRadius
     */
    public void setInnerRadius(@Px int innerRadius) {
        mGradientState.mInnerRadius = innerRadius;
        mPathIsDirty = true;
        invalidateSelf();
    }

    /**
     * Return the inner radius of the ring
     *
     * @see #setInnerRadius(int)
     * @attr ref android.R.styleable#GradientDrawable_innerRadius
     */
    public @Px int getInnerRadius() {
        return mGradientState.mInnerRadius;
    }

    /**
     * Configure the thickness of the ring expressed as a ratio of the ring's width.
     *
     * @see #getThicknessRatio()
     * @attr ref android.R.styleable#GradientDrawable_thicknessRatio
     */
    public void setThicknessRatio(
            @FloatRange(from = 0.0f, fromInclusive = false) float thicknessRatio) {
        if (thicknessRatio <= 0) {
            throw new IllegalArgumentException("Ratio must be greater than zero");
        }
        mGradientState.mThicknessRatio = thicknessRatio;
        mPathIsDirty = true;
        invalidateSelf();
    }

    /**
     * Return the thickness ratio of the ring expressed as a ratio of the ring's width.
     *
     * @see #setThicknessRatio(float)
     * @attr ref android.R.styleable#GradientDrawable_thicknessRatio
     */
    public float getThicknessRatio() {
        return mGradientState.mThicknessRatio;
    }

    /**
     * Configure the thickness of the ring.
     *
     * @attr ref android.R.styleable#GradientDrawable_thickness
     */
    public void setThickness(@Px int thickness) {
        mGradientState.mThickness = thickness;
        mPathIsDirty = true;
        invalidateSelf();
    }

    /**
     * Return the thickness of the ring
     *
     * @see #setThickness(int)
     * @attr ref android.R.styleable#GradientDrawable_thickness
     */
    public @Px int getThickness() {
        return mGradientState.mThickness;
    }

    /**
     * Configure the padding of the gradient shape
     * @param left Left padding of the gradient shape
     * @param top Top padding of the gradient shape
     * @param right Right padding of the gradient shape
     * @param bottom Bottom padding of the gradient shape
     *
     * @attr ref android.R.styleable#GradientDrawablePadding_left
     * @attr ref android.R.styleable#GradientDrawablePadding_top
     * @attr ref android.R.styleable#GradientDrawablePadding_right
     * @attr ref android.R.styleable#GradientDrawablePadding_bottom
     */
    public void setPadding(@Px int left, @Px int top, @Px int right, @Px int bottom) {
        if (mGradientState.mPadding == null) {
            mGradientState.mPadding = new Rect();
        }

        mGradientState.mPadding.set(left, top, right, bottom);
        mPadding = mGradientState.mPadding;
        invalidateSelf();
    }

    private Path buildRing(GradientState st) {
        if (mRingPath != null && (!st.mUseLevelForShape || !mPathIsDirty)) return mRingPath;
        mPathIsDirty = false;

        float sweep = st.mUseLevelForShape ? (360.0f * getLevel() / 10000.0f) : 360f;

        RectF bounds = new RectF(mRect);

        float x = bounds.width() / 2.0f;
        float y = bounds.height() / 2.0f;

        float thickness = st.mThickness != -1 ?
                st.mThickness : bounds.width() / st.mThicknessRatio;
        // inner radius
        float radius = st.mInnerRadius != -1 ?
                st.mInnerRadius : bounds.width() / st.mInnerRadiusRatio;

        RectF innerBounds = new RectF(bounds);
        innerBounds.inset(x - radius, y - radius);

        bounds = new RectF(innerBounds);
        bounds.inset(-thickness, -thickness);

        if (mRingPath == null) {
            mRingPath = new Path();
        } else {
            mRingPath.reset();
        }

        final Path ringPath = mRingPath;
        // arcTo treats the sweep angle mod 360, so check for that, since we
        // think 360 means draw the entire oval
        if (sweep < 360 && sweep > -360) {
            ringPath.setFillType(Path.FillType.EVEN_ODD);
            // inner top
            ringPath.moveTo(x + radius, y);
            // outer top
            ringPath.lineTo(x + radius + thickness, y);
            // outer arc
            ringPath.arcTo(bounds, 0.0f, sweep, false);
            // inner arc
            ringPath.arcTo(innerBounds, sweep, -sweep, false);
            ringPath.close();
        } else {
            // add the entire ovals
            ringPath.addOval(bounds, Path.Direction.CW);
            ringPath.addOval(innerBounds, Path.Direction.CCW);
        }

        return ringPath;
    }

    /**
     * Changes this drawable to use a single color instead of a gradient.
     * <p>
     * <strong>Note</strong>: changing color will affect all instances of a
     * drawable loaded from a resource. It is recommended to invoke
     * {@link #mutate()} before changing the color.
     *
     * @param argb The color used to fill the shape
     *
     * @see #mutate()
     * @see #setColors(int[])
     * @see #getColor
     */
    public void setColor(@ColorInt int argb) {
        mGradientState.setSolidColors(ColorStateList.valueOf(argb));
        mFillPaint.setColor(argb);
        invalidateSelf();
    }

    /**
     * Changes this drawable to use a single color state list instead of a
     * gradient. Calling this method with a null argument will clear the color
     * and is equivalent to calling {@link #setColor(int)} with the argument
     * {@link Color#TRANSPARENT}.
     * <p>
     * <strong>Note</strong>: changing color will affect all instances of a
     * drawable loaded from a resource. It is recommended to invoke
     * {@link #mutate()} before changing the color.</p>
     *
     * @param colorStateList The color state list used to fill the shape
     *
     * @see #mutate()
     * @see #getColor
     */
    public void setColor(@Nullable ColorStateList colorStateList) {
        if (colorStateList == null) {
            setColor(Color.TRANSPARENT);
        } else {
            final int[] stateSet = getState();
            final int color = colorStateList.getColorForState(stateSet, 0);
            mGradientState.setSolidColors(colorStateList);
            mFillPaint.setColor(color);
            invalidateSelf();
        }
    }

    /**
     * Returns the color state list used to fill the shape, or {@code null} if
     * the shape is filled with a gradient or has no fill color.
     *
     * @return the color state list used to fill this gradient, or {@code null}
     *
     * @see #setColor(int)
     * @see #setColor(ColorStateList)
     */
    @Nullable
    public ColorStateList getColor() {
        return mGradientState.mSolidColors;
    }

    @Override
    protected boolean onStateChange(int[] stateSet) {
        boolean invalidateSelf = false;

        final GradientState s = mGradientState;
        final ColorStateList solidColors = s.mSolidColors;
        if (solidColors != null) {
            final int newColor = solidColors.getColorForState(stateSet, 0);
            final int oldColor = mFillPaint.getColor();
            if (oldColor != newColor) {
                mFillPaint.setColor(newColor);
                invalidateSelf = true;
            }
        }

        final Paint strokePaint = mStrokePaint;
        if (strokePaint != null) {
            final ColorStateList strokeColors = s.mStrokeColors;
            if (strokeColors != null) {
                final int newColor = strokeColors.getColorForState(stateSet, 0);
                final int oldColor = strokePaint.getColor();
                if (oldColor != newColor) {
                    strokePaint.setColor(newColor);
                    invalidateSelf = true;
                }
            }
        }

        if (s.mTint != null && s.mBlendMode != null) {
            mBlendModeColorFilter = updateBlendModeFilter(mBlendModeColorFilter, s.mTint,
                    s.mBlendMode);
            invalidateSelf = true;
        }

        if (invalidateSelf) {
            invalidateSelf();
            return true;
        }

        return false;
    }

    @Override
    public boolean isStateful() {
        final GradientState s = mGradientState;
        return super.isStateful()
                || (s.mSolidColors != null && s.mSolidColors.isStateful())
                || (s.mStrokeColors != null && s.mStrokeColors.isStateful())
                || (s.mTint != null && s.mTint.isStateful());
    }

    @Override
    public boolean hasFocusStateSpecified() {
        final GradientState s = mGradientState;
        return (s.mSolidColors != null && s.mSolidColors.hasFocusStateSpecified())
                || (s.mStrokeColors != null && s.mStrokeColors.hasFocusStateSpecified())
                || (s.mTint != null && s.mTint.hasFocusStateSpecified());
    }

    @Override
    public @Config int getChangingConfigurations() {
        return super.getChangingConfigurations() | mGradientState.getChangingConfigurations();
    }

    @Override
    public void setAlpha(int alpha) {
        if (alpha != mAlpha) {
            mAlpha = alpha;
            invalidateSelf();
        }
    }

    @Override
    public int getAlpha() {
        return mAlpha;
    }

    @Override
    public void setDither(boolean dither) {
        if (dither != mGradientState.mDither) {
            mGradientState.mDither = dither;
            invalidateSelf();
        }
    }

    @Override
    @Nullable
    public ColorFilter getColorFilter() {
        return mColorFilter;
    }

    @Override
    public void setColorFilter(@Nullable ColorFilter colorFilter) {
        if (colorFilter != mColorFilter) {
            mColorFilter = colorFilter;
            invalidateSelf();
        }
    }

    @Override
    public void setTintList(@Nullable ColorStateList tint) {
        mGradientState.mTint = tint;
        mBlendModeColorFilter =
                updateBlendModeFilter(mBlendModeColorFilter, tint, mGradientState.mBlendMode);
        invalidateSelf();
    }

    @Override
    public void setTintBlendMode(@NonNull BlendMode blendMode) {
        mGradientState.mBlendMode = blendMode;
        mBlendModeColorFilter = updateBlendModeFilter(mBlendModeColorFilter, mGradientState.mTint,
                blendMode);
        invalidateSelf();
    }

    @Override
    public int getOpacity() {
        return (mAlpha == 255 && mGradientState.mOpaqueOverBounds && isOpaqueForState()) ?
                PixelFormat.OPAQUE : PixelFormat.TRANSLUCENT;
    }

    @Override
    protected void onBoundsChange(Rect r) {
        super.onBoundsChange(r);
        mRingPath = null;
        mPathIsDirty = true;
        mGradientIsDirty = true;
    }

    @Override
    protected boolean onLevelChange(int level) {
        super.onLevelChange(level);
        mGradientIsDirty = true;
        mPathIsDirty = true;
        invalidateSelf();
        return true;
    }

    /**
     * This checks mGradientIsDirty, and if it is true, recomputes both our drawing
     * rectangle (mRect) and the gradient itself, since it depends on our
     * rectangle too.
     * @return true if the resulting rectangle is not empty, false otherwise
     */
    private boolean ensureValidRect() {
        if (mGradientIsDirty) {
            mGradientIsDirty = false;

            Rect bounds = getBounds();
            float inset = 0;

            if (mStrokePaint != null) {
                inset = mStrokePaint.getStrokeWidth() * 0.5f;
            }

            final GradientState st = mGradientState;

            mRect.set(bounds.left + inset, bounds.top + inset,
                      bounds.right - inset, bounds.bottom - inset);

            int[] gradientColors = null;
            if (st.mGradientColors != null) {
                gradientColors = new int[st.mGradientColors.length];
                for (int i = 0; i < gradientColors.length; i++) {
                    if (st.mGradientColors[i] != null) {
                        gradientColors[i] = st.mGradientColors[i].getDefaultColor();
                    }
                }
            }
            if (gradientColors != null) {
                final RectF r = mRect;
                final float x0, x1, y0, y1;

                if (st.mGradient == LINEAR_GRADIENT) {
                    final float level = st.mUseLevel ? getLevel() / 10000.0f : 1.0f;
                    switch (st.mOrientation) {
                    case TOP_BOTTOM:
                        x0 = r.left;            y0 = r.top;
                        x1 = x0;                y1 = level * r.bottom;
                        break;
                    case TR_BL:
                        x0 = r.right;           y0 = r.top;
                        x1 = level * r.left;    y1 = level * r.bottom;
                        break;
                    case RIGHT_LEFT:
                        x0 = r.right;           y0 = r.top;
                        x1 = level * r.left;    y1 = y0;
                        break;
                    case BR_TL:
                        x0 = r.right;           y0 = r.bottom;
                        x1 = level * r.left;    y1 = level * r.top;
                        break;
                    case BOTTOM_TOP:
                        x0 = r.left;            y0 = r.bottom;
                        x1 = x0;                y1 = level * r.top;
                        break;
                    case BL_TR:
                        x0 = r.left;            y0 = r.bottom;
                        x1 = level * r.right;   y1 = level * r.top;
                        break;
                    case LEFT_RIGHT:
                        x0 = r.left;            y0 = r.top;
                        x1 = level * r.right;   y1 = y0;
                        break;
                    default:/* TL_BR */
                        x0 = r.left;            y0 = r.top;
                        x1 = level * r.right;   y1 = level * r.bottom;
                        break;
                    }

                    mFillPaint.setShader(new LinearGradient(x0, y0, x1, y1,
                            gradientColors, st.mPositions, Shader.TileMode.CLAMP));
                } else if (st.mGradient == RADIAL_GRADIENT) {
                    x0 = r.left + (r.right - r.left) * st.mCenterX;
                    y0 = r.top + (r.bottom - r.top) * st.mCenterY;

                    float radius = st.mGradientRadius;
                    if (st.mGradientRadiusType == RADIUS_TYPE_FRACTION) {
                        // Fall back to parent width or height if intrinsic
                        // size is not specified.
                        final float width = st.mWidth >= 0 ? st.mWidth : r.width();
                        final float height = st.mHeight >= 0 ? st.mHeight : r.height();
                        radius *= Math.min(width, height);
                    } else if (st.mGradientRadiusType == RADIUS_TYPE_FRACTION_PARENT) {
                        radius *= Math.min(r.width(), r.height());
                    }

                    if (st.mUseLevel) {
                        radius *= getLevel() / 10000.0f;
                    }

                    mGradientRadius = radius;

                    if (radius <= 0) {
                        // We can't have a shader with non-positive radius, so
                        // let's have a very, very small radius.
                        radius = 0.001f;
                    }

                    mFillPaint.setShader(new RadialGradient(
                            x0, y0, radius, gradientColors, null, Shader.TileMode.CLAMP));
                } else if (st.mGradient == SWEEP_GRADIENT) {
                    x0 = r.left + (r.right - r.left) * st.mCenterX;
                    y0 = r.top + (r.bottom - r.top) * st.mCenterY;

                    int[] tempColors = gradientColors;
                    float[] tempPositions = null;

                    if (st.mUseLevel) {
                        tempColors = st.mTempColors;
                        final int length = gradientColors.length;
                        if (tempColors == null || tempColors.length != length + 1) {
                            tempColors = st.mTempColors = new int[length + 1];
                        }
                        System.arraycopy(gradientColors, 0, tempColors, 0, length);
                        tempColors[length] = gradientColors[length - 1];

                        tempPositions = st.mTempPositions;
                        final float fraction = 1.0f / (length - 1);
                        if (tempPositions == null || tempPositions.length != length + 1) {
                            tempPositions = st.mTempPositions = new float[length + 1];
                        }

                        final float level = getLevel() / 10000.0f;
                        for (int i = 0; i < length; i++) {
                            tempPositions[i] = i * fraction * level;
                        }
                        tempPositions[length] = 1.0f;

                    }
                    mFillPaint.setShader(new SweepGradient(x0, y0, tempColors, tempPositions));
                }

                // If we don't have a solid color, the alpha channel must be
                // maxed out so that alpha modulation works correctly.
                if (st.mSolidColors == null) {
                    mFillPaint.setColor(Color.BLACK);
                }
            }
        }
        return !mRect.isEmpty();
    }

    @Override
    public void inflate(@NonNull Resources r, @NonNull XmlPullParser parser,
            @NonNull AttributeSet attrs, @Nullable Theme theme)
            throws XmlPullParserException, IOException {
        super.inflate(r, parser, attrs, theme);

        mGradientState.setDensity(Drawable.resolveDensity(r, 0));

        final TypedArray a = obtainAttributes(r, theme, attrs, R.styleable.GradientDrawable);
        updateStateFromTypedArray(a);
        a.recycle();

        inflateChildElements(r, parser, attrs, theme);

        updateLocalState(r);
    }

    @Override
    public void applyTheme(@NonNull Theme t) {
        super.applyTheme(t);

        final GradientState state = mGradientState;
        if (state == null) {
            return;
        }

        state.setDensity(Drawable.resolveDensity(t.getResources(), 0));

        if (state.mThemeAttrs != null) {
            final TypedArray a = t.resolveAttributes(
                    state.mThemeAttrs, R.styleable.GradientDrawable);
            updateStateFromTypedArray(a);
            a.recycle();
        }

        if (state.mTint != null && state.mTint.canApplyTheme()) {
            state.mTint = state.mTint.obtainForTheme(t);
        }

        if (state.mSolidColors != null && state.mSolidColors.canApplyTheme()) {
            state.mSolidColors = state.mSolidColors.obtainForTheme(t);
        }

        if (state.mStrokeColors != null && state.mStrokeColors.canApplyTheme()) {
            state.mStrokeColors = state.mStrokeColors.obtainForTheme(t);
        }

        if (state.mGradientColors != null) {
            for (int i = 0; i < state.mGradientColors.length; i++) {
                if (state.mGradientColors[i] != null && state.mGradientColors[i].canApplyTheme()) {
                    state.mGradientColors[i] = state.mGradientColors[i].obtainForTheme(t);
                }
            }
        }

        applyThemeChildElements(t);

        updateLocalState(t.getResources());
    }

    /**
     * Updates the constant state from the values in the typed array.
     */
    private void updateStateFromTypedArray(TypedArray a) {
        final GradientState state = mGradientState;

        // Account for any configuration changes.
        state.mChangingConfigurations |= a.getChangingConfigurations();

        // Extract the theme attributes, if any.
        state.mThemeAttrs = a.extractThemeAttrs();

        state.mShape = a.getInt(R.styleable.GradientDrawable_shape, state.mShape);
        state.mDither = a.getBoolean(R.styleable.GradientDrawable_dither, state.mDither);

        if (state.mShape == RING) {
            state.mInnerRadius = a.getDimensionPixelSize(
                    R.styleable.GradientDrawable_innerRadius, state.mInnerRadius);

            if (state.mInnerRadius == -1) {
                state.mInnerRadiusRatio = a.getFloat(
                        R.styleable.GradientDrawable_innerRadiusRatio, state.mInnerRadiusRatio);
            }

            state.mThickness = a.getDimensionPixelSize(
                    R.styleable.GradientDrawable_thickness, state.mThickness);

            if (state.mThickness == -1) {
                state.mThicknessRatio = a.getFloat(
                        R.styleable.GradientDrawable_thicknessRatio, state.mThicknessRatio);
            }

            state.mUseLevelForShape = a.getBoolean(
                    R.styleable.GradientDrawable_useLevel, state.mUseLevelForShape);
        }

        final int tintMode = a.getInt(R.styleable.GradientDrawable_tintMode, -1);
        if (tintMode != -1) {
            state.mBlendMode = Drawable.parseBlendMode(tintMode, BlendMode.SRC_IN);
        }

        final ColorStateList tint = a.getColorStateList(R.styleable.GradientDrawable_tint);
        if (tint != null) {
            state.mTint = tint;
        }

        final int insetLeft = a.getDimensionPixelSize(
                R.styleable.GradientDrawable_opticalInsetLeft, state.mOpticalInsets.left);
        final int insetTop = a.getDimensionPixelSize(
                R.styleable.GradientDrawable_opticalInsetTop, state.mOpticalInsets.top);
        final int insetRight = a.getDimensionPixelSize(
                R.styleable.GradientDrawable_opticalInsetRight, state.mOpticalInsets.right);
        final int insetBottom = a.getDimensionPixelSize(
                R.styleable.GradientDrawable_opticalInsetBottom, state.mOpticalInsets.bottom);
        state.mOpticalInsets = Insets.of(insetLeft, insetTop, insetRight, insetBottom);
    }

    @Override
    public boolean canApplyTheme() {
        return (mGradientState != null && mGradientState.canApplyTheme()) || super.canApplyTheme();
    }

    private void applyThemeChildElements(Theme t) {
        final GradientState st = mGradientState;

        if (st.mAttrSize != null) {
            final TypedArray a = t.resolveAttributes(
                    st.mAttrSize, R.styleable.GradientDrawableSize);
            updateGradientDrawableSize(a);
            a.recycle();
        }

        if (st.mAttrGradient != null) {
            final TypedArray a = t.resolveAttributes(
                    st.mAttrGradient, R.styleable.GradientDrawableGradient);
            try {
                updateGradientDrawableGradient(t.getResources(), a);
            } finally {
                a.recycle();
            }
        }

        if (st.mAttrSolid != null) {
            final TypedArray a = t.resolveAttributes(
                    st.mAttrSolid, R.styleable.GradientDrawableSolid);
            updateGradientDrawableSolid(a);
            a.recycle();
        }

        if (st.mAttrStroke != null) {
            final TypedArray a = t.resolveAttributes(
                    st.mAttrStroke, R.styleable.GradientDrawableStroke);
            updateGradientDrawableStroke(a);
            a.recycle();
        }

        if (st.mAttrCorners != null) {
            final TypedArray a = t.resolveAttributes(
                    st.mAttrCorners, R.styleable.DrawableCorners);
            updateDrawableCorners(a);
            a.recycle();
        }

        if (st.mAttrPadding != null) {
            final TypedArray a = t.resolveAttributes(
                    st.mAttrPadding, R.styleable.GradientDrawablePadding);
            updateGradientDrawablePadding(a);
            a.recycle();
        }
    }

    private void inflateChildElements(Resources r, XmlPullParser parser, AttributeSet attrs,
            Theme theme) throws XmlPullParserException, IOException {
        TypedArray a;
        int type;

        final int innerDepth = parser.getDepth() + 1;
        int depth;
        while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
               && ((depth=parser.getDepth()) >= innerDepth
                       || type != XmlPullParser.END_TAG)) {
            if (type != XmlPullParser.START_TAG) {
                continue;
            }

            if (depth > innerDepth) {
                continue;
            }

            String name = parser.getName();

            if (name.equals("size")) {
                a = obtainAttributes(r, theme, attrs, R.styleable.GradientDrawableSize);
                updateGradientDrawableSize(a);
                a.recycle();
            } else if (name.equals("gradient")) {
                a = obtainAttributes(r, theme, attrs, R.styleable.GradientDrawableGradient);
                updateGradientDrawableGradient(r, a);
                a.recycle();
            } else if (name.equals("solid")) {
                a = obtainAttributes(r, theme, attrs, R.styleable.GradientDrawableSolid);
                updateGradientDrawableSolid(a);
                a.recycle();
            } else if (name.equals("stroke")) {
                a = obtainAttributes(r, theme, attrs, R.styleable.GradientDrawableStroke);
                updateGradientDrawableStroke(a);
                a.recycle();
            } else if (name.equals("corners")) {
                a = obtainAttributes(r, theme, attrs, R.styleable.DrawableCorners);
                updateDrawableCorners(a);
                a.recycle();
            } else if (name.equals("padding")) {
                a = obtainAttributes(r, theme, attrs, R.styleable.GradientDrawablePadding);
                updateGradientDrawablePadding(a);
                a.recycle();
            } else {
                Log.w("drawable", "Bad element under <shape>: " + name);
            }
        }
    }

    private void updateGradientDrawablePadding(TypedArray a) {
        final GradientState st = mGradientState;

        // Account for any configuration changes.
        st.mChangingConfigurations |= a.getChangingConfigurations();

        // Extract the theme attributes, if any.
        st.mAttrPadding = a.extractThemeAttrs();

        if (st.mPadding == null) {
            st.mPadding = new Rect();
        }

        final Rect pad = st.mPadding;
        pad.set(a.getDimensionPixelOffset(R.styleable.GradientDrawablePadding_left, pad.left),
                a.getDimensionPixelOffset(R.styleable.GradientDrawablePadding_top, pad.top),
                a.getDimensionPixelOffset(R.styleable.GradientDrawablePadding_right, pad.right),
                a.getDimensionPixelOffset(R.styleable.GradientDrawablePadding_bottom, pad.bottom));
        mPadding = pad;
    }

    private void updateDrawableCorners(TypedArray a) {
        final GradientState st = mGradientState;

        // Account for any configuration changes.
        st.mChangingConfigurations |= a.getChangingConfigurations();

        // Extract the theme attributes, if any.
        st.mAttrCorners = a.extractThemeAttrs();

        final int radius = a.getDimensionPixelSize(
                R.styleable.DrawableCorners_radius, (int) st.mRadius);
        setCornerRadius(radius);

        // TODO: Update these to be themeable.
        final int topLeftRadius = a.getDimensionPixelSize(
                R.styleable.DrawableCorners_topLeftRadius, radius);
        final int topRightRadius = a.getDimensionPixelSize(
                R.styleable.DrawableCorners_topRightRadius, radius);
        final int bottomLeftRadius = a.getDimensionPixelSize(
                R.styleable.DrawableCorners_bottomLeftRadius, radius);
        final int bottomRightRadius = a.getDimensionPixelSize(
                R.styleable.DrawableCorners_bottomRightRadius, radius);
        if (topLeftRadius != radius || topRightRadius != radius ||
                bottomLeftRadius != radius || bottomRightRadius != radius) {
            // The corner radii are specified in clockwise order (see Path.addRoundRect())
            setCornerRadii(new float[] {
                    topLeftRadius, topLeftRadius,
                    topRightRadius, topRightRadius,
                    bottomRightRadius, bottomRightRadius,
                    bottomLeftRadius, bottomLeftRadius
            });
        }
    }

    private void updateGradientDrawableStroke(TypedArray a) {
        final GradientState st = mGradientState;

        // Account for any configuration changes.
        st.mChangingConfigurations |= a.getChangingConfigurations();

        // Extract the theme attributes, if any.
        st.mAttrStroke = a.extractThemeAttrs();

        // We have an explicit stroke defined, so the default stroke width
        // must be at least 0 or the current stroke width.
        final int defaultStrokeWidth = Math.max(0, st.mStrokeWidth);
        final int width = a.getDimensionPixelSize(
                R.styleable.GradientDrawableStroke_width, defaultStrokeWidth);
        final float dashWidth = a.getDimension(
                R.styleable.GradientDrawableStroke_dashWidth, st.mStrokeDashWidth);

        ColorStateList colorStateList = a.getColorStateList(
                R.styleable.GradientDrawableStroke_color);
        if (colorStateList == null) {
            colorStateList = st.mStrokeColors;
        }

        if (dashWidth != 0.0f) {
            final float dashGap = a.getDimension(
                    R.styleable.GradientDrawableStroke_dashGap, st.mStrokeDashGap);
            setStroke(width, colorStateList, dashWidth, dashGap);
        } else {
            setStroke(width, colorStateList);
        }
    }

    private void updateGradientDrawableSolid(TypedArray a) {
        final GradientState st = mGradientState;

        // Account for any configuration changes.
        st.mChangingConfigurations |= a.getChangingConfigurations();

        // Extract the theme attributes, if any.
        st.mAttrSolid = a.extractThemeAttrs();

        final ColorStateList colorStateList = a.getColorStateList(
                R.styleable.GradientDrawableSolid_color);
        if (colorStateList != null) {
            setColor(colorStateList);
        }
    }

    private void updateGradientDrawableGradient(Resources r, TypedArray a) {
        final GradientState st = mGradientState;

        // Account for any configuration changes.
        st.mChangingConfigurations |= a.getChangingConfigurations();

        // Extract the theme attributes, if any.
        st.mAttrGradient = a.extractThemeAttrs();

        st.mCenterX = getFloatOrFraction(
                a, R.styleable.GradientDrawableGradient_centerX, st.mCenterX);
        st.mCenterY = getFloatOrFraction(
                a, R.styleable.GradientDrawableGradient_centerY, st.mCenterY);
        st.mUseLevel = a.getBoolean(
                R.styleable.GradientDrawableGradient_useLevel, st.mUseLevel);
        st.mGradient = a.getInt(
                R.styleable.GradientDrawableGradient_type, st.mGradient);

        ColorStateList startCSL = a.getColorStateList(
                R.styleable.GradientDrawableGradient_startColor);
        ColorStateList centerCSL = a.getColorStateList(
                R.styleable.GradientDrawableGradient_centerColor);
        ColorStateList endCSL = a.getColorStateList(
                R.styleable.GradientDrawableGradient_endColor);

        final boolean hasGradientColors = st.mGradientColors != null;
        final boolean hasGradientCenter = st.hasCenterColor();

        int startColor = startCSL != null ? startCSL.getDefaultColor() : 0;
        int centerColor = centerCSL != null ? centerCSL.getDefaultColor() : 0;
        int endColor = endCSL != null ? endCSL.getDefaultColor() : 0;

        if (hasGradientColors && st.mGradientColors[0] != null) {
            startColor = st.mGradientColors[0].getDefaultColor();
        }
        if (hasGradientCenter && st.mGradientColors[1] != null) {
            centerColor = st.mGradientColors[1].getDefaultColor();
        }
        if (hasGradientCenter && st.mGradientColors[2] != null) {
            // if there is a center color, the end color is the last of the 3 values
            endColor = st.mGradientColors[2].getDefaultColor();
        } else if (hasGradientColors && st.mGradientColors[1] != null) {
            // if there is not a center color but there are already colors configured, then
            // the end color is the 2nd value in the array
            endColor = st.mGradientColors[1].getDefaultColor();
        }

        final boolean hasCenterColor = a.hasValue(
                R.styleable.GradientDrawableGradient_centerColor) || hasGradientCenter;

        if (hasCenterColor) {
            st.mGradientColors = new ColorStateList[3];
            st.mGradientColors[0] =
                    startCSL != null ? startCSL : ColorStateList.valueOf(startColor);
            st.mGradientColors[1] =
                    centerCSL != null ? centerCSL : ColorStateList.valueOf(centerColor);
            st.mGradientColors[2] =
                    endCSL != null ? endCSL : ColorStateList.valueOf(endColor);

            st.mPositions = new float[3];
            st.mPositions[0] = 0.0f;
            // Since 0.5f is default value, try to take the one that isn't 0.5f
            st.mPositions[1] = st.mCenterX != 0.5f ? st.mCenterX : st.mCenterY;
            st.mPositions[2] = 1f;
        } else {
            st.mGradientColors = new ColorStateList[2];
            st.mGradientColors[0] =
                    startCSL != null ? startCSL : ColorStateList.valueOf(startColor);
            st.mGradientColors[1] =
                    endCSL != null ? endCSL : ColorStateList.valueOf(endColor);
        }

        int angle = (int) a.getFloat(R.styleable.GradientDrawableGradient_angle, st.mAngle);

        // GradientDrawable historically has not parsed negative angle measurements and always
        // stays on the default orientation for API levels older than Q.
        // Only configure the orientation if the angle is greater than zero.
        // Otherwise fallback on Orientation.TOP_BOTTOM
        // In Android Q and later, actually wrap the negative angle measurement to the correct
        // value
        if (sWrapNegativeAngleMeasurements) {
            st.mAngle = ((angle % 360) + 360) % 360; // offset negative angle measures
        } else {
            st.mAngle = angle % 360;
        }

        if (st.mAngle >= 0) {
            switch (st.mAngle) {
                case 0:
                    st.mOrientation = Orientation.LEFT_RIGHT;
                    break;
                case 45:
                    st.mOrientation = Orientation.BL_TR;
                    break;
                case 90:
                    st.mOrientation = Orientation.BOTTOM_TOP;
                    break;
                case 135:
                    st.mOrientation = Orientation.BR_TL;
                    break;
                case 180:
                    st.mOrientation = Orientation.RIGHT_LEFT;
                    break;
                case 225:
                    st.mOrientation = Orientation.TR_BL;
                    break;
                case 270:
                    st.mOrientation = Orientation.TOP_BOTTOM;
                    break;
                case 315:
                    st.mOrientation = Orientation.TL_BR;
                    break;
            }
        } else {
            st.mOrientation = DEFAULT_ORIENTATION;
        }

        final TypedValue tv = a.peekValue(R.styleable.GradientDrawableGradient_gradientRadius);
        if (tv != null) {
            final float radius;
            final @RadiusType int radiusType;
            if (tv.type == TypedValue.TYPE_FRACTION) {
                radius = tv.getFraction(1.0f, 1.0f);

                final int unit = (tv.data >> TypedValue.COMPLEX_UNIT_SHIFT)
                        & TypedValue.COMPLEX_UNIT_MASK;
                if (unit == TypedValue.COMPLEX_UNIT_FRACTION_PARENT) {
                    radiusType = RADIUS_TYPE_FRACTION_PARENT;
                } else {
                    radiusType = RADIUS_TYPE_FRACTION;
                }
            } else if (tv.type == TypedValue.TYPE_DIMENSION) {
                radius = tv.getDimension(r.getDisplayMetrics());
                radiusType = RADIUS_TYPE_PIXELS;
            } else {
                radius = tv.getFloat();
                radiusType = RADIUS_TYPE_PIXELS;
            }

            st.mGradientRadius = radius;
            st.mGradientRadiusType = radiusType;
        }
    }

    private void updateGradientDrawableSize(TypedArray a) {
        final GradientState st = mGradientState;

        // Account for any configuration changes.
        st.mChangingConfigurations |= a.getChangingConfigurations();

        // Extract the theme attributes, if any.
        st.mAttrSize = a.extractThemeAttrs();

        st.mWidth = a.getDimensionPixelSize(R.styleable.GradientDrawableSize_width, st.mWidth);
        st.mHeight = a.getDimensionPixelSize(R.styleable.GradientDrawableSize_height, st.mHeight);
    }

    private static float getFloatOrFraction(TypedArray a, int index, float defaultValue) {
        TypedValue tv = a.peekValue(index);
        float v = defaultValue;
        if (tv != null) {
            boolean vIsFraction = tv.type == TypedValue.TYPE_FRACTION;
            v = vIsFraction ? tv.getFraction(1.0f, 1.0f) : tv.getFloat();
        }
        return v;
    }

    @Override
    public int getIntrinsicWidth() {
        return mGradientState.mWidth;
    }

    @Override
    public int getIntrinsicHeight() {
        return mGradientState.mHeight;
    }

    @Override
    public Insets getOpticalInsets() {
        return mGradientState.mOpticalInsets;
    }

    @Override
    public ConstantState getConstantState() {
        mGradientState.mChangingConfigurations = getChangingConfigurations();
        return mGradientState;
    }

    private boolean isOpaqueForState() {
        if (mGradientState.mStrokeWidth >= 0 && mStrokePaint != null
                && !isOpaque(mStrokePaint.getColor())) {
            return false;
        }

        // Don't check opacity if we're using a gradient, as we've already
        // checked the gradient opacity in mOpaqueOverShape.
        if (mGradientState.mGradientColors == null && !isOpaque(mFillPaint.getColor())) {
            return false;
        }

        return true;
    }

    @Override
    public void getOutline(Outline outline) {
        final GradientState st = mGradientState;
        final Rect bounds = getBounds();
        // only report non-zero alpha if shape being drawn has consistent opacity over shape. Must
        // either not have a stroke, or have same stroke/fill opacity
        boolean useFillOpacity = st.mOpaqueOverShape && (mGradientState.mStrokeWidth <= 0
                || mStrokePaint == null
                || mStrokePaint.getAlpha() == mFillPaint.getAlpha());
        outline.setAlpha(useFillOpacity
                ? modulateAlpha(mFillPaint.getAlpha()) / 255.0f
                : 0.0f);

        switch (st.mShape) {
            case RECTANGLE:
                if (st.mRadiusArray != null) {
                    buildPathIfDirty();
                    outline.setPath(mPath);
                    return;
                }

                float rad = 0;
                if (st.mRadius > 0.0f) {
                    // clamp the radius based on width & height, matching behavior in draw()
                    rad = Math.min(st.mRadius,
                            Math.min(bounds.width(), bounds.height()) * 0.5f);
                }
                outline.setRoundRect(bounds, rad);
                return;
            case OVAL:
                outline.setOval(bounds);
                return;
            case LINE:
                // Hairlines (0-width stroke) must have a non-empty outline for
                // shadows to draw correctly, so we'll use a very small width.
                final float halfStrokeWidth = mStrokePaint == null ?
                        0.0001f : mStrokePaint.getStrokeWidth() * 0.5f;
                final float centerY = bounds.centerY();
                final int top = (int) Math.floor(centerY - halfStrokeWidth);
                final int bottom = (int) Math.ceil(centerY + halfStrokeWidth);

                outline.setRect(bounds.left, top, bounds.right, bottom);
                return;
            default:
                // TODO: support more complex shapes
        }
    }

    @Override
    public Drawable mutate() {
        if (!mMutated && super.mutate() == this) {
            mGradientState = new GradientState(mGradientState, null);
            updateLocalState(null);
            mMutated = true;
        }
        return this;
    }

    /**
     * @hide
     */
    public void clearMutated() {
        super.clearMutated();
        mMutated = false;
    }

    final static class GradientState extends ConstantState {
        public @Config int mChangingConfigurations;
        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 124050917)
        public @Shape int mShape = RECTANGLE;
        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 124050917)
        public @GradientType int mGradient = LINEAR_GRADIENT;
        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 124050917)
        public int mAngle = 0;
        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 124050917)
        public Orientation mOrientation;
        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 124050917)
        public ColorStateList mSolidColors;
        public ColorStateList mStrokeColors;
        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug =  124050917)
        public ColorStateList[] mGradientColors; // no support for state-based color
        public @ColorInt int[] mTempColors; // no need to copy
        public float[] mTempPositions; // no need to copy
        @UnsupportedAppUsage
        public float[] mPositions;
        @UnsupportedAppUsage(trackingBug = 124050917)
        public int mStrokeWidth = -1; // if >= 0 use stroking.
        @UnsupportedAppUsage(trackingBug = 124050917)
        public float mStrokeDashWidth = 0.0f;
        @UnsupportedAppUsage(trackingBug = 124050917)
        public float mStrokeDashGap = 0.0f;
        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 124050917)
        public float mRadius = 0.0f; // use this if mRadiusArray is null
        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 124050917)
        public float[] mRadiusArray = null;
        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 124050917)
        public Rect mPadding = null;
        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 124050917)
        public int mWidth = -1;
        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 124050917)
        public int mHeight = -1;
        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 124050917)
        public float mInnerRadiusRatio = DEFAULT_INNER_RADIUS_RATIO;
        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 124050218)
        public float mThicknessRatio = DEFAULT_THICKNESS_RATIO;
        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 124050917)
        public int mInnerRadius = -1;
        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 124050218)
        public int mThickness = -1;
        public boolean mDither = false;
        public Insets mOpticalInsets = Insets.NONE;

        float mCenterX = 0.5f;
        float mCenterY = 0.5f;
        float mGradientRadius = 0.5f;
        @RadiusType int mGradientRadiusType = RADIUS_TYPE_PIXELS;
        boolean mUseLevel = false;
        boolean mUseLevelForShape = true;

        boolean mOpaqueOverBounds;
        boolean mOpaqueOverShape;

        ColorStateList mTint = null;
        BlendMode mBlendMode = DEFAULT_BLEND_MODE;

        int mDensity = DisplayMetrics.DENSITY_DEFAULT;

        int[] mThemeAttrs;
        int[] mAttrSize;
        int[] mAttrGradient;
        int[] mAttrSolid;
        int[] mAttrStroke;
        int[] mAttrCorners;
        int[] mAttrPadding;

        public GradientState(Orientation orientation, int[] gradientColors) {
            mOrientation = orientation;
            setGradientColors(gradientColors);
        }

        public GradientState(@NonNull GradientState orig, @Nullable Resources res) {
            mChangingConfigurations = orig.mChangingConfigurations;
            mShape = orig.mShape;
            mGradient = orig.mGradient;
            mAngle = orig.mAngle;
            mOrientation = orig.mOrientation;
            mSolidColors = orig.mSolidColors;
            if (orig.mGradientColors != null) {
                mGradientColors = orig.mGradientColors.clone();
            }
            if (orig.mPositions != null) {
                mPositions = orig.mPositions.clone();
            }
            mStrokeColors = orig.mStrokeColors;
            mStrokeWidth = orig.mStrokeWidth;
            mStrokeDashWidth = orig.mStrokeDashWidth;
            mStrokeDashGap = orig.mStrokeDashGap;
            mRadius = orig.mRadius;
            if (orig.mRadiusArray != null) {
                mRadiusArray = orig.mRadiusArray.clone();
            }
            if (orig.mPadding != null) {
                mPadding = new Rect(orig.mPadding);
            }
            mWidth = orig.mWidth;
            mHeight = orig.mHeight;
            mInnerRadiusRatio = orig.mInnerRadiusRatio;
            mThicknessRatio = orig.mThicknessRatio;
            mInnerRadius = orig.mInnerRadius;
            mThickness = orig.mThickness;
            mDither = orig.mDither;
            mOpticalInsets = orig.mOpticalInsets;
            mCenterX = orig.mCenterX;
            mCenterY = orig.mCenterY;
            mGradientRadius = orig.mGradientRadius;
            mGradientRadiusType = orig.mGradientRadiusType;
            mUseLevel = orig.mUseLevel;
            mUseLevelForShape = orig.mUseLevelForShape;
            mOpaqueOverBounds = orig.mOpaqueOverBounds;
            mOpaqueOverShape = orig.mOpaqueOverShape;
            mTint = orig.mTint;
            mBlendMode = orig.mBlendMode;
            mThemeAttrs = orig.mThemeAttrs;
            mAttrSize = orig.mAttrSize;
            mAttrGradient = orig.mAttrGradient;
            mAttrSolid = orig.mAttrSolid;
            mAttrStroke = orig.mAttrStroke;
            mAttrCorners = orig.mAttrCorners;
            mAttrPadding = orig.mAttrPadding;

            mDensity = Drawable.resolveDensity(res, orig.mDensity);
            if (orig.mDensity != mDensity) {
                applyDensityScaling(orig.mDensity, mDensity);
            }
        }

        /**
         * Sets the constant state density.
         * <p>
         * If the density has been previously set, dispatches the change to
         * subclasses so that density-dependent properties may be scaled as
         * necessary.
         *
         * @param targetDensity the new constant state density
         */
        public final void setDensity(int targetDensity) {
            if (mDensity != targetDensity) {
                final int sourceDensity = mDensity;
                mDensity = targetDensity;

                applyDensityScaling(sourceDensity, targetDensity);
            }
        }

        public boolean hasCenterColor() {
            return mGradientColors != null && mGradientColors.length == 3;
        }

        private void applyDensityScaling(int sourceDensity, int targetDensity) {
            if (mInnerRadius > 0) {
                mInnerRadius = Drawable.scaleFromDensity(
                        mInnerRadius, sourceDensity, targetDensity, true);
            }
            if (mThickness > 0) {
                mThickness = Drawable.scaleFromDensity(
                        mThickness, sourceDensity, targetDensity, true);
            }
            if (mOpticalInsets != Insets.NONE) {
                final int left = Drawable.scaleFromDensity(
                        mOpticalInsets.left, sourceDensity, targetDensity, true);
                final int top = Drawable.scaleFromDensity(
                        mOpticalInsets.top, sourceDensity, targetDensity, true);
                final int right = Drawable.scaleFromDensity(
                        mOpticalInsets.right, sourceDensity, targetDensity, true);
                final int bottom = Drawable.scaleFromDensity(
                        mOpticalInsets.bottom, sourceDensity, targetDensity, true);
                mOpticalInsets = Insets.of(left, top, right, bottom);
            }
            if (mPadding != null) {
                mPadding.left = Drawable.scaleFromDensity(
                        mPadding.left, sourceDensity, targetDensity, false);
                mPadding.top = Drawable.scaleFromDensity(
                        mPadding.top, sourceDensity, targetDensity, false);
                mPadding.right = Drawable.scaleFromDensity(
                        mPadding.right, sourceDensity, targetDensity, false);
                mPadding.bottom = Drawable.scaleFromDensity(
                        mPadding.bottom, sourceDensity, targetDensity, false);
            }
            if (mRadius > 0) {
                mRadius = Drawable.scaleFromDensity(mRadius, sourceDensity, targetDensity);
            }
            if (mRadiusArray != null) {
                mRadiusArray[0] = Drawable.scaleFromDensity(
                        (int) mRadiusArray[0], sourceDensity, targetDensity, true);
                mRadiusArray[1] = Drawable.scaleFromDensity(
                        (int) mRadiusArray[1], sourceDensity, targetDensity, true);
                mRadiusArray[2] = Drawable.scaleFromDensity(
                        (int) mRadiusArray[2], sourceDensity, targetDensity, true);
                mRadiusArray[3] = Drawable.scaleFromDensity(
                        (int) mRadiusArray[3], sourceDensity, targetDensity, true);
            }
            if (mStrokeWidth > 0) {
                mStrokeWidth = Drawable.scaleFromDensity(
                        mStrokeWidth, sourceDensity, targetDensity, true);
            }
            if (mStrokeDashWidth > 0) {
                mStrokeDashWidth = Drawable.scaleFromDensity(
                        mStrokeDashGap, sourceDensity, targetDensity);
            }
            if (mStrokeDashGap > 0) {
                mStrokeDashGap = Drawable.scaleFromDensity(
                        mStrokeDashGap, sourceDensity, targetDensity);
            }
            if (mGradientRadiusType == RADIUS_TYPE_PIXELS) {
                mGradientRadius = Drawable.scaleFromDensity(
                        mGradientRadius, sourceDensity, targetDensity);
            }
            if (mWidth > 0) {
                mWidth = Drawable.scaleFromDensity(mWidth, sourceDensity, targetDensity, true);
            }
            if (mHeight > 0) {
                mHeight = Drawable.scaleFromDensity(mHeight, sourceDensity, targetDensity, true);
            }
        }

        @Override
        public boolean canApplyTheme() {
            boolean mGradientColorState = mGradientColors != null;
            if (mGradientColors != null) {
                for (int i = 0; i < mGradientColors.length; i++) {
                    mGradientColorState |= (mGradientColors[i] != null && mGradientColors[i]
                        .canApplyTheme());
                }
            }
            return mThemeAttrs != null
                    || mAttrSize != null || mAttrGradient != null
                    || mAttrSolid != null || mAttrStroke != null
                    || mAttrCorners != null || mAttrPadding != null
                    || (mTint != null && mTint.canApplyTheme())
                    || (mStrokeColors != null && mStrokeColors.canApplyTheme())
                    || (mSolidColors != null && mSolidColors.canApplyTheme())
                    || mGradientColorState
                    || super.canApplyTheme();
        }

        @Override
        public Drawable newDrawable() {
            return new GradientDrawable(this, null);
        }

        @Override
        public Drawable newDrawable(@Nullable Resources res) {
            // If this drawable is being created for a different density,
            // just create a new constant state and call it a day.
            final GradientState state;
            final int density = Drawable.resolveDensity(res, mDensity);
            if (density != mDensity) {
                state = new GradientState(this, res);
            } else {
                state = this;
            }

            return new GradientDrawable(state, res);
        }

        @Override
        public @Config int getChangingConfigurations() {
            return mChangingConfigurations
                    | (mStrokeColors != null ? mStrokeColors.getChangingConfigurations() : 0)
                    | (mSolidColors != null ? mSolidColors.getChangingConfigurations() : 0)
                    | (mTint != null ? mTint.getChangingConfigurations() : 0);
        }

        public void setShape(@Shape int shape) {
            mShape = shape;
            computeOpacity();
        }

        public void setGradientType(@GradientType int gradient) {
            mGradient = gradient;
        }

        public void setGradientCenter(float x, float y) {
            mCenterX = x;
            mCenterY = y;
        }

        @NonNull
        public Orientation getOrientation() {
            return mOrientation;
        }

        public void setGradientColors(@Nullable int[] colors) {
            if (colors == null) {
                mGradientColors = null;
            } else {
                // allocate new CSL array only if the size of the current array is different
                // from the size of the given parameter
                if (mGradientColors == null || mGradientColors.length != colors.length) {
                    mGradientColors = new ColorStateList[colors.length];
                }
                for (int i = 0; i < colors.length; i++) {
                    mGradientColors[i] = ColorStateList.valueOf(colors[i]);
                }
            }
            mSolidColors = null;
            computeOpacity();
        }

        public void setSolidColors(@Nullable ColorStateList colors) {
            mGradientColors = null;
            mSolidColors = colors;
            computeOpacity();
        }

        private void computeOpacity() {
            mOpaqueOverBounds = false;
            mOpaqueOverShape = false;

            if (mGradientColors != null) {
                for (int i = 0; i < mGradientColors.length; i++) {
                    if (mGradientColors[i] != null
                            && !isOpaque(mGradientColors[i].getDefaultColor())) {
                        return;
                    }
                }
            }

            // An unfilled shape is not opaque over bounds or shape
            if (mGradientColors == null && mSolidColors == null) {
                return;
            }

            // Colors are opaque, so opaqueOverShape=true,
            mOpaqueOverShape = true;
            // and opaqueOverBounds=true if shape fills bounds
            mOpaqueOverBounds = mShape == RECTANGLE
                    && mRadius <= 0
                    && mRadiusArray == null;
        }

        public void setStroke(int width, @Nullable ColorStateList colors, float dashWidth,
                float dashGap) {
            mStrokeWidth = width;
            mStrokeColors = colors;
            mStrokeDashWidth = dashWidth;
            mStrokeDashGap = dashGap;
            computeOpacity();
        }

        public void setCornerRadius(float radius) {
            if (radius < 0) {
                radius = 0;
            }
            mRadius = radius;
            mRadiusArray = null;
            computeOpacity();
        }

        public void setCornerRadii(float[] radii) {
            mRadiusArray = radii;
            if (radii == null) {
                mRadius = 0;
            }
            computeOpacity();
        }

        public void setSize(int width, int height) {
            mWidth = width;
            mHeight = height;
        }

        public void setGradientRadius(float gradientRadius, @RadiusType int type) {
            mGradientRadius = gradientRadius;
            mGradientRadiusType = type;
        }
    }

    static boolean isOpaque(int color) {
        return ((color >> 24) & 0xff) == 0xff;
    }

    /**
     * Creates a new themed GradientDrawable based on the specified constant state.
     * <p>
     * The resulting drawable is guaranteed to have a new constant state.
     *
     * @param state Constant state from which the drawable inherits
     */
    private GradientDrawable(@NonNull GradientState state, @Nullable Resources res) {
        mGradientState = state;

        updateLocalState(res);
    }

    private void updateLocalState(Resources res) {
        final GradientState state = mGradientState;

        if (state.mSolidColors != null) {
            final int[] currentState = getState();
            final int stateColor = state.mSolidColors.getColorForState(currentState, 0);
            mFillPaint.setColor(stateColor);
        } else if (state.mGradientColors == null) {
            // If we don't have a solid color and we don't have a gradient,
            // the app is stroking the shape, set the color to the default
            // value of state.mSolidColor
            mFillPaint.setColor(0);
        } else {
            // Otherwise, make sure the fill alpha is maxed out.
            mFillPaint.setColor(Color.BLACK);
        }

        mPadding = state.mPadding;

        if (state.mStrokeWidth >= 0) {
            mStrokePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
            mStrokePaint.setStyle(Paint.Style.STROKE);
            mStrokePaint.setStrokeWidth(state.mStrokeWidth);

            if (state.mStrokeColors != null) {
                final int[] currentState = getState();
                final int strokeStateColor = state.mStrokeColors.getColorForState(
                        currentState, 0);
                mStrokePaint.setColor(strokeStateColor);
            }

            if (state.mStrokeDashWidth != 0.0f) {
                final DashPathEffect e = new DashPathEffect(
                        new float[] { state.mStrokeDashWidth, state.mStrokeDashGap }, 0);
                mStrokePaint.setPathEffect(e);
            }
        }

        mBlendModeColorFilter = updateBlendModeFilter(mBlendModeColorFilter, state.mTint,
                state.mBlendMode);
        mGradientIsDirty = true;

        state.computeOpacity();
    }
}
