/*
 * Copyright (C) 2008 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.cts;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyBoolean;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyLong;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.annotation.NonNull;
import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.content.res.Resources.Theme;
import android.content.res.XmlResourceParser;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff;
import android.graphics.Rect;
import android.graphics.cts.R;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Drawable.ConstantState;
import android.graphics.drawable.GradientDrawable;
import android.graphics.drawable.LayerDrawable;
import android.graphics.drawable.RippleDrawable;
import android.graphics.drawable.RotateDrawable;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.StateListDrawable;
import android.support.test.InstrumentationRegistry;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
import android.util.AttributeSet;
import android.util.StateSet;
import android.util.Xml;
import android.view.Gravity;
import android.view.View;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.xmlpull.v1.XmlPullParserException;

import java.io.IOException;

@SmallTest
@RunWith(AndroidJUnit4.class)
public class LayerDrawableTest {
    private Context mContext;
    private ColorDrawable mColorDrawable;
    private BitmapDrawable mBitmapDrawable;

    @Before
    public void setup() {
        mContext = InstrumentationRegistry.getTargetContext();
        Resources resources = mContext.getResources();
        mColorDrawable = new ColorDrawable(Color.BLUE);
        mBitmapDrawable = new BitmapDrawable(resources,
                BitmapFactory.decodeResource(resources, R.drawable.icon_blue));
    }

    @Test
    public void testConstructor() {
        Drawable[] array = new Drawable[]{mBitmapDrawable, mColorDrawable};
        LayerDrawable layerDrawable = new LayerDrawable(array);
        assertEquals(array.length, layerDrawable.getNumberOfLayers());
        assertSame(mBitmapDrawable, layerDrawable.getDrawable(0));
        assertSame(mColorDrawable, layerDrawable.getDrawable(1));

        array = new Drawable[0];
        layerDrawable = new LayerDrawable(array);
        assertEquals(0, layerDrawable.getNumberOfLayers());
    }

    @Test(expected=IllegalArgumentException.class)
    public void testConstructorNull() {
        new LayerDrawable(null);
    }

    @Test
    public void testInflate() throws XmlPullParserException, IOException {
        Drawable[] array = new Drawable[0];
        LayerDrawable layerDrawable = new LayerDrawable(array);

        XmlResourceParser parser = mContext.getResources().getXml(R.xml.layerdrawable);
        AttributeSet attrs = DrawableTestUtils.getAttributeSet(parser, "layer-list_full");

        layerDrawable.inflate(mContext.getResources(), parser, attrs);

        assertEquals(4, layerDrawable.getNumberOfLayers());
        assertEquals(ColorDrawable.class, layerDrawable.getDrawable(0).getClass());
        assertEquals(0x88, layerDrawable.getDrawable(0).getAlpha());
        assertEquals(View.NO_ID, layerDrawable.getId(0));
        assertEquals(BitmapDrawable.class, layerDrawable.getDrawable(1).getClass());
        assertEquals(View.NO_ID, layerDrawable.getId(1));
        assertEquals(RotateDrawable.class, layerDrawable.getDrawable(2).getClass());
        assertEquals(View.NO_ID, layerDrawable.getId(2));
        assertEquals(GradientDrawable.class, layerDrawable.getDrawable(3).getClass());
        assertEquals(R.id.background, layerDrawable.getId(3));

        layerDrawable = new LayerDrawable(array);
        parser = mContext.getResources().getXml(R.xml.layerdrawable);
        attrs = DrawableTestUtils.getAttributeSet(parser, "layer-list_empty");
        layerDrawable.inflate(mContext.getResources(), parser, attrs);
        assertEquals(0, layerDrawable.getNumberOfLayers());

        parser = mContext.getResources().getXml(R.xml.layerdrawable);
        attrs = DrawableTestUtils.getAttributeSet(parser, "layer-list_exception");
        try {
            layerDrawable.inflate(mContext.getResources(), parser, attrs);
            fail("Should throw XmlPullParserException if neither 'drawable' attribute" +
                    " nor child tag defining a drawable in <item> tag.");
        } catch (XmlPullParserException e) {
        }

        try {
            layerDrawable.inflate(null, parser, attrs);
            fail("Should throw NullPointerException if resource is null");
        } catch (NullPointerException e) {
        }

        try {
            layerDrawable.inflate(mContext.getResources(), null, attrs);
            fail("Should throw NullPointerException if parser is null");
        } catch (NullPointerException e) {
        }

        try {
            layerDrawable.inflate(mContext.getResources(), parser, null);
            fail("Should throw NullPointerException if attribute set is null");
        } catch (NullPointerException e) {
        }
    }

    @Test
    public void testFindDrawableByLayerId() {
        Drawable[] array = new Drawable[] { mBitmapDrawable, mColorDrawable };
        LayerDrawable layerDrawable = new LayerDrawable(array);

        layerDrawable.setId(0, 10);
        layerDrawable.setId(1, 20);
        assertSame(mBitmapDrawable, layerDrawable.findDrawableByLayerId(10));
        assertSame(mColorDrawable, layerDrawable.findDrawableByLayerId(20));
        assertNull(layerDrawable.findDrawableByLayerId(30));

        layerDrawable.setId(0, Integer.MIN_VALUE);
        layerDrawable.setId(1, Integer.MAX_VALUE);
        assertSame(mBitmapDrawable, layerDrawable.findDrawableByLayerId(Integer.MIN_VALUE));
        assertSame(mColorDrawable, layerDrawable.findDrawableByLayerId(Integer.MAX_VALUE));

        layerDrawable.setId(0, 10);
        layerDrawable.setId(1, 10);
        assertSame(mColorDrawable, layerDrawable.findDrawableByLayerId(10));
        assertNull(layerDrawable.findDrawableByLayerId(30));
    }

    @Test
    public void testAccessId() {
        Drawable[] array = new Drawable[] { mBitmapDrawable, mColorDrawable };
        LayerDrawable layerDrawable = new LayerDrawable(array);

        layerDrawable.setId(0, 10);
        layerDrawable.setId(1, 20);
        assertEquals(10, layerDrawable.getId(0));
        assertEquals(20, layerDrawable.getId(1));

        layerDrawable.setId(0, Integer.MIN_VALUE);
        layerDrawable.setId(1, Integer.MAX_VALUE);
        assertEquals(Integer.MIN_VALUE, layerDrawable.getId(0));
        assertEquals(Integer.MAX_VALUE, layerDrawable.getId(1));
    }

    @Test(expected=IndexOutOfBoundsException.class)
    public void testSetIdIndexTooLow() {
        Drawable[] array = new Drawable[] { mBitmapDrawable, mColorDrawable };
        LayerDrawable layerDrawable = new LayerDrawable(array);
        layerDrawable.setId(-1, 20);
    }

    @Test(expected=IndexOutOfBoundsException.class)
    public void testSetIdIndexTooHigh() {
        Drawable[] array = new Drawable[] { mBitmapDrawable, mColorDrawable };
        LayerDrawable layerDrawable = new LayerDrawable(array);
        layerDrawable.setId(layerDrawable.getNumberOfLayers(), 20);
    }

    @Test(expected=IndexOutOfBoundsException.class)
    public void testGetIdIndexTooLow() {
        Drawable[] array = new Drawable[] { mBitmapDrawable, mColorDrawable };
        LayerDrawable layerDrawable = new LayerDrawable(array);
        layerDrawable.getId(-1);
    }

    @Test(expected=IndexOutOfBoundsException.class)
    public void testGetIdIndexTooHigh() {
        Drawable[] array = new Drawable[] { mBitmapDrawable, mColorDrawable };
        LayerDrawable layerDrawable = new LayerDrawable(array);
        layerDrawable.getId(layerDrawable.getNumberOfLayers());
    }

    @Test
    public void testGetNumberOfLayers() {
        Drawable[] array = new Drawable[] { mBitmapDrawable, mColorDrawable };
        LayerDrawable layerDrawable = new LayerDrawable(array);
        assertEquals(2, layerDrawable.getNumberOfLayers());

        array = new Drawable[5];
        for (int i = 0; i < 5; i++) {
            array[i] = new BitmapDrawable();
        }
        layerDrawable = new LayerDrawable(array);
        assertEquals(5, layerDrawable.getNumberOfLayers());

        array = new Drawable[0];
        layerDrawable = new LayerDrawable(array);
        assertEquals(0, layerDrawable.getNumberOfLayers());
    }

    @Test
    public void testAccessDrawable() {
        Drawable[] array = new Drawable[] { mBitmapDrawable, mColorDrawable };
        LayerDrawable layerDrawable = new LayerDrawable(array);
        assertSame(mBitmapDrawable, layerDrawable.getDrawable(0));
        assertSame(mColorDrawable, layerDrawable.getDrawable(1));

        layerDrawable.setId(0, 10);
        layerDrawable.setId(1, 20);
        Drawable d1 = new ColorDrawable(Color.GREEN);
        Drawable d2 = new BitmapDrawable();
        layerDrawable.setDrawableByLayerId(10, d1);
        layerDrawable.setDrawableByLayerId(20, d2);
        assertEquals(d1, layerDrawable.getDrawable(0));
        assertEquals(d2, layerDrawable.getDrawable(1));

        assertFalse(layerDrawable.setDrawableByLayerId(30, d1));

        try {
            layerDrawable.getDrawable(layerDrawable.getNumberOfLayers());
            fail("Should throw IndexOutOfBoundsException");
        } catch (IndexOutOfBoundsException e) {
        }

        try {
            layerDrawable.getDrawable(-1);
            fail("Should throw IndexOutOfBoundsException");
        } catch (IndexOutOfBoundsException e) {
        }
    }

    @Test
    public void testSetDrawableByLayerId() {
        Drawable layer1A  = new ColorDrawable(Color.RED);
        Drawable layer2A  = new ColorDrawable(Color.BLUE);
        LayerDrawable layerDrawable = new LayerDrawable(new Drawable[] { layer1A, layer2A });
        layerDrawable.setId(0, 10);
        layerDrawable.setId(1, 20);

        Drawable layer1B = new ColorDrawable(Color.GREEN);
        layer1B.setLevel(10000);
        Drawable layer2B = new ColorDrawable(Color.YELLOW);
        layer2B.setLevel(5000);
        layerDrawable.setDrawableByLayerId(10, layer1B);
        layerDrawable.setDrawableByLayerId(20, layer2B);

        assertEquals("Level is unchanged after setDrawableByLayerId()",
                10000, layerDrawable.findDrawableByLayerId(10).getLevel());
        assertEquals("Level is unchanged after setDrawableByLayerId()",
                5000, layerDrawable.findDrawableByLayerId(20).getLevel());
    }

    @Test
    public void testSetLayerInset() {
        Drawable firstLayer = spy(new ColorDrawable(Color.YELLOW));
        doReturn(10).when(firstLayer).getIntrinsicWidth();
        doReturn(10).when(firstLayer).getIntrinsicHeight();
        Drawable secondLayer = spy(new ColorDrawable(Color.YELLOW));
        doReturn(-1).when(secondLayer).getIntrinsicWidth();
        doReturn(-1).when(secondLayer).getIntrinsicHeight();

        Drawable[] array = new Drawable[] { firstLayer, secondLayer };
        LayerDrawable layerDrawable = new LayerDrawable(array);

        // set inset for layer 0
        int left = 10;
        int top = 20;
        int right = 30;
        int bottom = 40;
        layerDrawable.setLayerInset(0, left, top, right, bottom);
        assertEquals(layerDrawable.getDrawable(0).getIntrinsicWidth() + left + right,
                layerDrawable.getIntrinsicWidth());
        assertEquals(layerDrawable.getDrawable(0).getIntrinsicHeight() + top + bottom,
                layerDrawable.getIntrinsicHeight());

        // The drawable at index 0 has no intrinsic width or height, so it
        // won't be counted for the overall intrinsic width or height.
        layerDrawable.setLayerInset(1, 10, 10, 10, 10);
        assertEquals(layerDrawable.getDrawable(0).getIntrinsicWidth() + left + right,
                layerDrawable.getIntrinsicWidth());
        assertEquals(layerDrawable.getDrawable(0).getIntrinsicHeight() + top + bottom,
                layerDrawable.getIntrinsicHeight());

        try {
            layerDrawable.setLayerInset(-1, left, top, right, bottom);
            fail("Should throw IndexOutOfBoundsException");
        } catch (IndexOutOfBoundsException e) {
        }
    }

    @Test
    public void testInvalidateDrawable() {
        Drawable[] array = new Drawable[0];
        LayerDrawable layerDrawable = new LayerDrawable(array);

        Drawable.Callback cb = mock(Drawable.Callback.class);
        layerDrawable.setCallback(cb);
        layerDrawable.invalidateDrawable(null);
        verify(cb, times(1)).invalidateDrawable(any());

        reset(cb);
        layerDrawable.invalidateDrawable(new BitmapDrawable());
        verify(cb, times(1)).invalidateDrawable(any());

        reset(cb);
        layerDrawable.setCallback(null);
        layerDrawable.invalidateDrawable(null);
        verify(cb, never()).invalidateDrawable(any());
    }

    @Test
    public void testScheduleDrawable() {
        Drawable[] array = new Drawable[0];
        LayerDrawable layerDrawable = new LayerDrawable(array);

        Drawable.Callback cb = mock(Drawable.Callback.class);
        layerDrawable.setCallback(cb);
        layerDrawable.scheduleDrawable(null, null, 0);
        verify(cb, times(1)).scheduleDrawable(any(), any(), anyLong());

        reset(cb);
        layerDrawable.scheduleDrawable(mBitmapDrawable, () -> {}, 1000L);
        verify(cb, times(1)).scheduleDrawable(any(), any(), anyLong());

        reset(cb);
        layerDrawable.setCallback(null);
        layerDrawable.scheduleDrawable(null, null, 0);
        verify(cb, never()).scheduleDrawable(any(), any(), anyLong());
    }

    @Test
    public void testUnscheduleDrawable() {
        Drawable[] array = new Drawable[0];
        LayerDrawable layerDrawable = new LayerDrawable(array);

        Drawable.Callback cb = mock(Drawable.Callback.class);
        layerDrawable.setCallback(cb);
        layerDrawable.unscheduleDrawable(null, null);
        verify(cb, times(1)).unscheduleDrawable(any(), any());

        reset(cb);
        layerDrawable.unscheduleDrawable(mBitmapDrawable, () -> {});
        verify(cb, times(1)).unscheduleDrawable(any(), any());

        reset(cb);
        layerDrawable.setCallback(null);
        layerDrawable.unscheduleDrawable(null, null);
        verify(cb, never()).unscheduleDrawable(any(), any());
    }

    @Test
    public void testDraw() {
        Drawable mockDrawable1 = spy(new ColorDrawable(Color.BLUE));
        Drawable mockDrawable2 = spy(new ColorDrawable(Color.RED));
        Drawable[] array = new Drawable[] { mockDrawable1, mockDrawable2 };
        LayerDrawable layerDrawable = new LayerDrawable(array);

        // this method will call each child's draw().
        layerDrawable.draw(new Canvas());
        verify(mockDrawable1, times(1)).draw(any());
        verify(mockDrawable2, times(1)).draw(any());

        reset(mockDrawable1);
        reset(mockDrawable2);
        doNothing().when(mockDrawable1).draw(any());
        doNothing().when(mockDrawable2).draw(any());
        layerDrawable.draw(null);
        verify(mockDrawable1, times(1)).draw(any());
        verify(mockDrawable2, times(1)).draw(any());
    }

    @Test
    public void testGetChangingConfigurations() {
        final int superConfig = 1;
        final int gradientDrawableConfig = 2;
        final int colorDrawableConfig = 4;
        final int childConfig = gradientDrawableConfig | colorDrawableConfig;

        mBitmapDrawable.setChangingConfigurations(gradientDrawableConfig);
        mColorDrawable.setChangingConfigurations(colorDrawableConfig);
        Drawable[] array = new Drawable[] { mBitmapDrawable, mColorDrawable };
        LayerDrawable layerDrawable = new LayerDrawable(array);

        assertEquals(childConfig, layerDrawable.getChangingConfigurations());

        layerDrawable.setChangingConfigurations(superConfig);
        assertEquals(superConfig | childConfig, layerDrawable.getChangingConfigurations());
    }

    @Test
    public void testAccessPadding() {
        Drawable[] array = new Drawable[] { new ShapeDrawable(), new ShapeDrawable() };
        LayerDrawable layerDrawable = new LayerDrawable(array);

        Rect rc = new Rect();
        layerDrawable.getPadding(rc);
        assertEquals(0, rc.left);
        assertEquals(0, rc.top);
        assertEquals(0, rc.right);
        assertEquals(0, rc.bottom);

        Rect padding0 = new Rect(10, 20, 30, 40);
        ((ShapeDrawable) layerDrawable.getDrawable(0)).setPadding(padding0);
        layerDrawable.getPadding(rc);
        assertEquals(padding0.left, rc.left);
        assertEquals(padding0.top, rc.top);
        assertEquals(padding0.right, rc.right);
        assertEquals(padding0.bottom, rc.bottom);

        Rect padding1 = new Rect(20, 30, 40, 50);
        ((ShapeDrawable) layerDrawable.getDrawable(1)).setPadding(padding1);
        layerDrawable.getPadding(rc);
        assertEquals(padding0.left + padding1.left, rc.left);
        assertEquals(padding0.top + padding1.top, rc.top);
        assertEquals(padding0.right + padding1.right, rc.right);
        assertEquals(padding0.bottom + padding1.bottom, rc.bottom);
    }

    @Test
    public void testAccessPaddingMode() {
        Rect padding = new Rect();
        Drawable dr0 = new IntrinsicSizeDrawable(20, 30, new Rect(1, 2, 3, 4));
        Drawable dr1 = new IntrinsicSizeDrawable(30, 40, new Rect(9, 8, 7, 6));
        LayerDrawable layerDrawable = new LayerDrawable(new Drawable[] { dr0, dr1 });

        assertEquals("Default padding mode is NEST",
                LayerDrawable.PADDING_MODE_NEST, layerDrawable.getPaddingMode());
        assertEquals(34, layerDrawable.getIntrinsicWidth());
        assertEquals(46, layerDrawable.getIntrinsicHeight());
        assertTrue(layerDrawable.getPadding(padding));
        assertEquals(new Rect(10, 10, 10, 10), padding);

        layerDrawable.setPaddingMode(LayerDrawable.PADDING_MODE_STACK);
        assertEquals(LayerDrawable.PADDING_MODE_STACK, layerDrawable.getPaddingMode());
        assertEquals(30, layerDrawable.getIntrinsicWidth());
        assertEquals(40, layerDrawable.getIntrinsicHeight());
        assertTrue(layerDrawable.getPadding(padding));
        assertEquals(new Rect(9, 8, 7, 6), padding);
    }

    @Test
    public void testSetVisible() {
        Drawable[] array = new Drawable[] { mBitmapDrawable, mColorDrawable };
        LayerDrawable layerDrawable = new LayerDrawable(array);

        assertTrue(layerDrawable.setVisible(false, true));
        assertFalse(layerDrawable.isVisible());
        assertFalse(layerDrawable.getDrawable(0).isVisible());
        assertFalse(layerDrawable.getDrawable(1).isVisible());

        assertFalse(layerDrawable.setVisible(false, false));

        assertTrue(layerDrawable.setVisible(true, false));
        assertTrue(layerDrawable.isVisible());
        assertTrue(layerDrawable.getDrawable(0).isVisible());
        assertTrue(layerDrawable.getDrawable(1).isVisible());
    }

    @Test
    public void testSetDither() {
        Drawable mockDrawable1 = spy(new ColorDrawable(Color.BLUE));
        Drawable mockDrawable2 = spy(new ColorDrawable(Color.BLACK));
        Drawable[] array = new Drawable[] { mockDrawable1, mockDrawable2 };
        LayerDrawable layerDrawable = new LayerDrawable(array);

        layerDrawable.setDither(true);
        verify(mockDrawable1, times(1)).setDither(anyBoolean());
        verify(mockDrawable2, times(1)).setDither(anyBoolean());

        reset(mockDrawable1);
        reset(mockDrawable2);
        layerDrawable.setDither(false);
        verify(mockDrawable1, times(1)).setDither(anyBoolean());
        verify(mockDrawable2, times(1)).setDither(anyBoolean());
    }

    @Test
    public void testSetHotspotBounds() {
        Rect bounds = new Rect(10, 15, 100, 150);
        Drawable mockDrawable1 = new ColorDrawable(Color.BLUE);
        Drawable mockDrawable2 = new ColorDrawable(Color.GREEN);
        Drawable[] array = new Drawable[] { mockDrawable1, mockDrawable2 };
        LayerDrawable layerDrawable = new LayerDrawable(array);

        layerDrawable.setHotspotBounds(bounds.left, bounds.top, bounds.right, bounds.bottom);
        Rect outRect = new Rect();
        layerDrawable.getHotspotBounds(outRect);
        assertTrue(bounds.equals(outRect));
    }

    @Test
    public void testGetHotspotBounds() {
        Rect bounds = new Rect(10, 15, 100, 150);
        Drawable mockDrawable1 = new ColorDrawable(Color.BLUE);
        Drawable mockDrawable2 = new ColorDrawable(Color.GREEN);
        Drawable[] array = new Drawable[] { mockDrawable1, mockDrawable2 };
        LayerDrawable layerDrawable = new LayerDrawable(array);

        layerDrawable.setHotspotBounds(bounds.left, bounds.top, bounds.right, bounds.bottom);
        Rect outRect = new Rect();
        layerDrawable.getHotspotBounds(outRect);
        assertTrue(bounds.equals(outRect));
    }

    @Test
    public void testSetAlpha() {
        Drawable mockDrawable1 = spy(new ColorDrawable(Color.BLUE));
        Drawable mockDrawable2 = spy(new ColorDrawable(Color.BLACK));
        Drawable[] array = new Drawable[] { mockDrawable1, mockDrawable2 };
        LayerDrawable layerDrawable = new LayerDrawable(array);

        layerDrawable.setAlpha(0);
        verify(mockDrawable1, times(1)).setAlpha(anyInt());
        verify(mockDrawable2, times(1)).setAlpha(anyInt());

        reset(mockDrawable1);
        reset(mockDrawable2);
        layerDrawable.setAlpha(Integer.MAX_VALUE);
        verify(mockDrawable1, times(1)).setAlpha(anyInt());
        verify(mockDrawable2, times(1)).setAlpha(anyInt());
    }

    @Test
    public void testSetColorFilter() {
        Drawable mockDrawable1 = spy(new ColorDrawable(Color.BLUE));
        Drawable mockDrawable2 = spy(new ColorDrawable(Color.BLACK));
        Drawable[] array = new Drawable[] { mockDrawable1, mockDrawable2 };
        LayerDrawable layerDrawable = new LayerDrawable(array);

        layerDrawable.setColorFilter(new ColorFilter());
        verify(mockDrawable1, times(1)).setColorFilter(any());
        verify(mockDrawable2, times(1)).setColorFilter(any());

        reset(mockDrawable1);
        reset(mockDrawable2);
        layerDrawable.setColorFilter(null);
        verify(mockDrawable1, times(1)).setColorFilter(any());
        verify(mockDrawable2, times(1)).setColorFilter(any());
    }

    @Test
    public void testAccessOpacity() {
        Drawable[] array = new Drawable[0];
        LayerDrawable layerDrawable = new LayerDrawable(array);
        assertEquals(PixelFormat.TRANSPARENT, layerDrawable.getOpacity());

        Drawable mockDrawable1 = spy(new ColorDrawable(Color.BLUE));
        Drawable mockDrawable2 = spy(new ColorDrawable(Color.GREEN));
        array = new Drawable[] { mockDrawable1, mockDrawable2 };
        layerDrawable = new LayerDrawable(array);
        assertEquals(PixelFormat.OPAQUE, layerDrawable.getOpacity());

        layerDrawable = new LayerDrawable(array);
        doReturn(PixelFormat.OPAQUE).when(mockDrawable1).getOpacity();
        doReturn(PixelFormat.TRANSPARENT).when(mockDrawable2).getOpacity();
        assertEquals(PixelFormat.TRANSPARENT, layerDrawable.getOpacity());

        layerDrawable = new LayerDrawable(array);
        doReturn(PixelFormat.TRANSLUCENT).when(mockDrawable1).getOpacity();
        doReturn(PixelFormat.TRANSPARENT).when(mockDrawable2).getOpacity();
        assertEquals(PixelFormat.TRANSLUCENT, layerDrawable.getOpacity());

        layerDrawable = new LayerDrawable(array);
        doReturn(PixelFormat.TRANSLUCENT).when(mockDrawable1).getOpacity();
        doReturn(PixelFormat.UNKNOWN).when(mockDrawable2).getOpacity();
        assertEquals(PixelFormat.UNKNOWN, layerDrawable.getOpacity());

        layerDrawable = new LayerDrawable(array);
        layerDrawable.setOpacity(PixelFormat.OPAQUE);
        doReturn(PixelFormat.TRANSLUCENT).when(mockDrawable1).getOpacity();
        doReturn(PixelFormat.UNKNOWN).when(mockDrawable2).getOpacity();
        assertEquals(PixelFormat.OPAQUE, layerDrawable.getOpacity());

    }

    @Test
    public void testIsStateful() {
        Drawable[] array = new Drawable[0];
        LayerDrawable layerDrawable = new LayerDrawable(array);
        assertFalse(layerDrawable.isStateful());

        array = new Drawable[] { new GradientDrawable(), new MockDrawable(false) };
        layerDrawable = new LayerDrawable(array);
        assertFalse(layerDrawable.isStateful());

        array = new Drawable[] { new GradientDrawable(), new StateListDrawable() };
        layerDrawable = new LayerDrawable(array);
        assertTrue(layerDrawable.isStateful());
    }

    @Test
    public void testSetState() {
        MockDrawable mockDrawable1 = new MockDrawable(true);
        MockDrawable mockDrawable2 = new MockDrawable(true);
        Drawable[] array = new Drawable[] { mockDrawable1, mockDrawable2 };
        LayerDrawable layerDrawable = new LayerDrawable(array);

        // Call onStateChange() without actually changing the state.
        assertFalse(layerDrawable.setState(StateSet.WILD_CARD));
        assertFalse(mockDrawable1.hasCalledSetState());
        assertFalse(mockDrawable2.hasCalledSetState());
        assertFalse(mockDrawable1.hasCalledOnBoundsChange());
        assertFalse(mockDrawable2.hasCalledOnBoundsChange());

        // Call onStateChange() to change the state from WILD_CARD to null.
        // This alters the padding of both layers, which forces a bounds change
        // for the second layer due to the default "nest" padding mode.
        mockDrawable1.reset();
        mockDrawable2.reset();
        assertTrue(layerDrawable.setState(null));
        assertTrue(mockDrawable1.hasCalledSetState());
        assertTrue(mockDrawable2.hasCalledSetState());
        assertFalse(mockDrawable1.hasCalledOnBoundsChange());
        assertTrue(mockDrawable2.hasCalledOnBoundsChange());

        // Call onStateChange() to change the state from null to valid state
        // set. This alters the padding of both layers, which forces a bounds
        // change for the second layer due to the default "nest" padding mode.
        mockDrawable1.reset();
        mockDrawable2.reset();
        assertTrue(layerDrawable.setState(new int[]{
                android.R.attr.state_checked, android.R.attr.state_empty}));
        assertTrue(mockDrawable1.hasCalledSetState());
        assertTrue(mockDrawable2.hasCalledSetState());
        assertFalse(mockDrawable1.hasCalledOnBoundsChange());
        assertTrue(mockDrawable2.hasCalledOnBoundsChange());
    }

    @Test
    public void testJumpToCurrentState() {
        Drawable mockDrawable1 = spy(new ColorDrawable(Color.BLUE));
        Drawable mockDrawable2 = spy(new ColorDrawable(Color.BLACK));
        Drawable[] array = new Drawable[] { mockDrawable1, mockDrawable2 };
        LayerDrawable layerDrawable = new LayerDrawable(array);

        verify(mockDrawable1, never()).jumpToCurrentState();
        verify(mockDrawable2, never()).jumpToCurrentState();

        layerDrawable.jumpToCurrentState();

        verify(mockDrawable1, times(1)).jumpToCurrentState();
        verify(mockDrawable2, times(1)).jumpToCurrentState();
    }

    @Test
    public void testSetLevel() {
        MockDrawable mockDrawable1 = new MockDrawable();
        MockDrawable mockDrawable2 = new MockDrawable();
        Drawable[] array = new Drawable[] { mockDrawable1, mockDrawable2 };
        LayerDrawable layerDrawable = new LayerDrawable(array);

        // Call onLevelChange() without actually changing the level.
        assertFalse(layerDrawable.setLevel(0));
        assertFalse(mockDrawable1.hasCalledOnLevelChange());
        assertFalse(mockDrawable2.hasCalledOnLevelChange());
        assertFalse(mockDrawable1.hasCalledOnBoundsChange());
        assertFalse(mockDrawable2.hasCalledOnBoundsChange());

        // Call onLevelChange() to change the level from 0 to MAX_VALUE. This
        // alters the padding of both layers, which forces a bounds change for
        // the second layer due to the default "nest" padding mode.
        mockDrawable1.reset();
        mockDrawable2.reset();
        assertTrue(layerDrawable.setLevel(Integer.MAX_VALUE));
        assertTrue(mockDrawable1.hasCalledOnLevelChange());
        assertTrue(mockDrawable2.hasCalledOnLevelChange());
        assertFalse(mockDrawable1.hasCalledOnBoundsChange());
        assertTrue(mockDrawable2.hasCalledOnBoundsChange());

        // Call onLevelChange() to change the level from MAX_VALUE to
        // MIN_VALUE. This alters the padding of both layers, which forces a
        // bounds change for the second layer due to the default "nest" padding
        // mode.
        mockDrawable1.reset();
        mockDrawable2.reset();
        assertTrue(layerDrawable.setLevel(Integer.MIN_VALUE));
        assertTrue(mockDrawable1.hasCalledOnLevelChange());
        assertTrue(mockDrawable2.hasCalledOnLevelChange());
        assertFalse(mockDrawable1.hasCalledOnBoundsChange());
        assertTrue(mockDrawable2.hasCalledOnBoundsChange());
    }

    @Test
    public void testSetBounds() {
        Drawable mockDrawable1 = spy(new ColorDrawable(Color.GREEN));
        Drawable mockDrawable2 = spy(new ColorDrawable(Color.BLUE));
        Drawable[] array = new Drawable[] { mockDrawable1, mockDrawable2 };
        LayerDrawable layerDrawable = new LayerDrawable(array);

        Rect inset1 = new Rect(1, 2, 3, 4);
        Rect inset2 = new Rect(2, 4, 6, 7);
        Rect padding1 = new Rect(11, 22, 33, 44);
        Rect padding2 = new Rect(21, 32, 43, 54);
        layerDrawable.setLayerInset(0, inset1.left, inset1.top, inset1.right, inset1.bottom);
        layerDrawable.setLayerInset(1, inset2.left, inset2.top, inset2.right, inset2.bottom);
        doAnswer(invocation -> {
            Rect target = (Rect) invocation.getArguments() [0];
            target.set(padding1);
            return true;
        }).when(mockDrawable1).getPadding(any());
        doAnswer(invocation -> {
            Rect target = (Rect) invocation.getArguments() [0];
            target.set(padding2);
            return true;
        }).when(mockDrawable2).getPadding(any());
        layerDrawable.getPadding(new Rect());

        // the children's bounds before call onBoundsChange
        assertEquals(0, mockDrawable1.getBounds().left);
        assertEquals(0, mockDrawable1.getBounds().top);
        assertEquals(0, mockDrawable1.getBounds().right);
        assertEquals(0, mockDrawable1.getBounds().bottom);
        assertEquals(0, mockDrawable2.getBounds().left);
        assertEquals(0, mockDrawable2.getBounds().top);
        assertEquals(0, mockDrawable2.getBounds().right);
        assertEquals(0, mockDrawable2.getBounds().bottom);

        Rect bounds = new Rect(10, 20, 30, 40);
        layerDrawable.setBounds(bounds);

        // all children's bounds will be changed after call onBoundsChange
        assertEquals(bounds.left + inset1.left, mockDrawable1.getBounds().left);
        assertEquals(bounds.top + inset1.top, mockDrawable1.getBounds().top);
        assertEquals(bounds.right - inset1.right, mockDrawable1.getBounds().right);
        assertEquals(bounds.bottom - inset1.bottom, mockDrawable1.getBounds().bottom);
        assertEquals(bounds.left + inset2.left + padding1.left, mockDrawable2.getBounds().left);
        assertEquals(bounds.top + inset2.top + padding1.top, mockDrawable2.getBounds().top);
        assertEquals(bounds.right - inset2.right - padding1.right,
                mockDrawable2.getBounds().right);
        assertEquals(bounds.bottom - inset2.bottom - padding1.bottom,
                mockDrawable2.getBounds().bottom);
    }

    @Test
    public void testGetIntrinsicWidth() {
        Drawable largeMockDrawable = spy(new ColorDrawable(Color.YELLOW));
        doReturn(10).when(largeMockDrawable).getIntrinsicWidth();
        doReturn(10).when(largeMockDrawable).getIntrinsicHeight();
        Drawable smallMockDrawable = spy(new ColorDrawable(Color.MAGENTA));
        doReturn(1).when(smallMockDrawable).getIntrinsicWidth();
        doReturn(1).when(smallMockDrawable).getIntrinsicHeight();

        Drawable[] array = new Drawable[] { largeMockDrawable, smallMockDrawable };
        LayerDrawable layerDrawable = new LayerDrawable(array);
        assertEquals(largeMockDrawable.getIntrinsicWidth(), layerDrawable.getIntrinsicWidth());

        Rect inset1 = new Rect(1, 2, 3, 4);
        Rect inset2 = new Rect(2, 4, 6, 7);
        final Rect padding1 = new Rect(11, 22, 33, 44);
        final Rect padding2 = new Rect(21, 32, 43, 54);
        layerDrawable.setLayerInset(0, inset1.left, inset1.top, inset1.right, inset1.bottom);
        layerDrawable.setLayerInset(1, inset2.left, inset2.top, inset2.right, inset2.bottom);

        doAnswer(invocation -> {
            Rect target = (Rect) invocation.getArguments() [0];
            target.set(padding1);
            return true;
        }).when(largeMockDrawable).getPadding(any());
        doAnswer(invocation -> {
            Rect target = (Rect) invocation.getArguments() [0];
            target.set(padding2);
            return true;
        }).when(smallMockDrawable).getPadding(any());

        layerDrawable.getPadding(new Rect());
        assertEquals(smallMockDrawable.getIntrinsicWidth() + inset2.left
                + inset2.right + padding1.left + padding1.right,
                layerDrawable.getIntrinsicWidth());

        inset1 = new Rect(inset2.left + padding1.left + 1, inset2.top + padding1.top + 1,
                inset2.right + padding1.right + 1, inset2.bottom + padding1.bottom + 1);
        layerDrawable.setLayerInset(0, inset1.left, inset1.top, inset1.right, inset1.bottom);
        assertEquals(largeMockDrawable.getIntrinsicWidth() + inset1.left + inset1.right,
                layerDrawable.getIntrinsicWidth());
    }

    @Test
    public void testGetIntrinsicHeight() {
        Drawable largeMockDrawable = spy(new ColorDrawable(Color.CYAN));
        doReturn(10).when(largeMockDrawable).getIntrinsicWidth();
        doReturn(10).when(largeMockDrawable).getIntrinsicHeight();
        Drawable smallMockDrawable = spy(new ColorDrawable(Color.DKGRAY));
        doReturn(1).when(smallMockDrawable).getIntrinsicWidth();
        doReturn(1).when(smallMockDrawable).getIntrinsicHeight();

        Drawable[] array = new Drawable[] { largeMockDrawable, smallMockDrawable };
        LayerDrawable layerDrawable = new LayerDrawable(array);
        assertEquals(largeMockDrawable.getIntrinsicHeight(), layerDrawable.getIntrinsicHeight());

        Rect inset1 = new Rect(1, 2, 3, 4);
        Rect inset2 = new Rect(2, 4, 6, 7);
        final Rect padding1 = new Rect(11, 22, 33, 44);
        final Rect padding2 = new Rect(21, 32, 43, 54);
        layerDrawable.setLayerInset(0, inset1.left, inset1.top, inset1.right, inset1.bottom);
        layerDrawable.setLayerInset(1, inset2.left, inset2.top, inset2.right, inset2.bottom);

        doAnswer(invocation -> {
            Rect target = (Rect) invocation.getArguments() [0];
            target.set(padding1);
            return true;
        }).when(largeMockDrawable).getPadding(any());
        doAnswer(invocation -> {
            Rect target = (Rect) invocation.getArguments() [0];
            target.set(padding2);
            return true;
        }).when(smallMockDrawable).getPadding(any());

        layerDrawable.getPadding(new Rect());
        assertEquals(smallMockDrawable.getIntrinsicHeight() + inset2.top
                + inset2.bottom + padding1.top + padding1.bottom,
                layerDrawable.getIntrinsicHeight());

        inset1 = new Rect(inset2.left + padding1.left + 1, inset2.top + padding1.top + 1,
                inset2.right + padding1.right + 1, inset2.bottom + padding1.bottom + 1);
        layerDrawable.setLayerInset(0, inset1.left, inset1.top, inset1.right, inset1.bottom);
        assertEquals(largeMockDrawable.getIntrinsicHeight() + inset1.top + inset1.bottom,
                layerDrawable.getIntrinsicHeight());
    }

    @Test
    public void testGetConstantState() {
        Drawable[] array = new Drawable[] { mBitmapDrawable, mColorDrawable };
        LayerDrawable layerDrawable = new LayerDrawable(array);
        ConstantState constantState = layerDrawable.getConstantState();
        assertNotNull(constantState);
        assertEquals(0, constantState.getChangingConfigurations());

        layerDrawable.setChangingConfigurations(1);
        constantState = layerDrawable.getConstantState();
        assertNotNull(constantState);
        assertEquals(1, constantState.getChangingConfigurations());
    }

    @Test
    public void testAddLayer() {
        Drawable[] array = new Drawable[] { new GradientDrawable(), new ColorDrawable(Color.BLUE) };
        LayerDrawable layerDrawable = new LayerDrawable(array);
        GradientDrawable newDrawable = new GradientDrawable();
        int index = layerDrawable.addLayer(newDrawable);

        final int numLayers = layerDrawable.getNumberOfLayers();
        assertEquals(index, numLayers - 1);
        assertEquals(newDrawable, layerDrawable.getDrawable(index));
    }

    @Test
    public void testGetDrawable() {
        Drawable[] array = new Drawable[] { mBitmapDrawable, mColorDrawable };
        LayerDrawable layerDrawable = new LayerDrawable(array);

        assertEquals(array[0], layerDrawable.getDrawable(0));
        assertEquals(array[1], layerDrawable.getDrawable(1));
        try {
            assertEquals(null, layerDrawable.getDrawable(2));
            fail("Should throw IndexOutOfBoundsException");
        } catch (IndexOutOfBoundsException e) {
        }
    }

    @Test
    public void testFindIndexByLayerId() {
        Drawable[] array = new Drawable[] { mBitmapDrawable, mColorDrawable };
        LayerDrawable layerDrawable = new LayerDrawable(array);

        layerDrawable.setId(0, 10);
        layerDrawable.setId(1, 20);

        assertEquals(0, layerDrawable.findIndexByLayerId(10));
        assertEquals(1, layerDrawable.findIndexByLayerId(20));
        assertEquals(-1, layerDrawable.findIndexByLayerId(30));
    }

    @Test
    public void testSetDrawable() {
        Drawable[] array = new Drawable[] { mBitmapDrawable, mColorDrawable };
        LayerDrawable layerDrawable = new LayerDrawable(array);
        BitmapDrawable newBitmapDrawable = new BitmapDrawable();
        ColorDrawable newColorDrawable = new ColorDrawable(Color.GREEN);
        layerDrawable.setDrawable(0, newColorDrawable);
        layerDrawable.setDrawable(1, newBitmapDrawable);

        final int numLayers = layerDrawable.getNumberOfLayers();
        assertEquals(2, numLayers);
        assertEquals(newColorDrawable, layerDrawable.getDrawable(0));
        assertEquals(newBitmapDrawable, layerDrawable.getDrawable(1));
        try {
            assertEquals(null, layerDrawable.getDrawable(2));
            fail("Should throw IndexOutOfBoundsException");
        } catch (IndexOutOfBoundsException e) {
        }
    }

    @Test
    public void testGetLeftPadding() {
        Drawable[] array = new Drawable[] { mBitmapDrawable };
        LayerDrawable layerDrawable = new LayerDrawable(array);
        layerDrawable.setPadding(10, 11, 20, 21);

        assertEquals(10, layerDrawable.getLeftPadding());
    }

    @Test
    public void testGetTopPadding() {
        Drawable[] array = new Drawable[] { mBitmapDrawable };
        LayerDrawable layerDrawable = new LayerDrawable(array);
        layerDrawable.setPadding(10, 11, 20, 21);

        assertEquals(11, layerDrawable.getTopPadding());
    }

    @Test
    public void testGetRightPadding() {
        Drawable[] array = new Drawable[] { mBitmapDrawable };
        LayerDrawable layerDrawable = new LayerDrawable(array);
        layerDrawable.setPadding(10, 11, 20, 21);

        assertEquals(20, layerDrawable.getRightPadding());
    }

    @Test
    public void testGetBottomPadding() {
        Drawable[] array = new Drawable[] { mBitmapDrawable };
        LayerDrawable layerDrawable = new LayerDrawable(array);
        layerDrawable.setPadding(10, 11, 20, 21);

        assertEquals(21, layerDrawable.getBottomPadding());
    }

    @Test
    public void testGetStartPadding() {
        Drawable[] array = new Drawable[] { mBitmapDrawable };
        LayerDrawable layerDrawable = new LayerDrawable(array);
        layerDrawable.setPadding(10, 11, 20, 21);

        assertEquals(-1, layerDrawable.getStartPadding());
        layerDrawable.setPaddingRelative(10, 11, 20, 21);
        assertEquals(10, layerDrawable.getStartPadding());
    }

    @Test
    public void testGetEndPadding() {
        Drawable[] array = new Drawable[] { mBitmapDrawable };
        LayerDrawable layerDrawable = new LayerDrawable(array);
        layerDrawable.setPadding(10, 11, 20, 21);

        assertEquals(-1, layerDrawable.getEndPadding());
        layerDrawable.setPaddingRelative(10, 11, 20, 21);
        assertEquals(20, layerDrawable.getEndPadding());
    }

    @Test
    public void testSetPadding() {
        Drawable[] array = new Drawable[] { mBitmapDrawable };
        LayerDrawable layerDrawable = new LayerDrawable(array);
        layerDrawable.setPadding(10, 11, 20, 21);

        assertEquals(10, layerDrawable.getLeftPadding());
        assertEquals(11, layerDrawable.getTopPadding());
        assertEquals(20, layerDrawable.getRightPadding());
        assertEquals(21, layerDrawable.getBottomPadding());
        assertEquals(-1, layerDrawable.getStartPadding());
        assertEquals(-1, layerDrawable.getEndPadding());
    }

    @Test
    public void testSetPaddingRelative() {
        Drawable[] array = new Drawable[] { mBitmapDrawable };
        LayerDrawable layerDrawable = new LayerDrawable(array);
        layerDrawable.setPaddingRelative(10, 11, 20, 21);

        assertEquals(10, layerDrawable.getStartPadding());
        assertEquals(11, layerDrawable.getTopPadding());
        assertEquals(20, layerDrawable.getEndPadding());
        assertEquals(21, layerDrawable.getBottomPadding());
        assertEquals(-1, layerDrawable.getLeftPadding());
        assertEquals(-1, layerDrawable.getRightPadding());
    }

    @Test
    public void testSetLayerGravity() {
        Drawable[] array = new Drawable[] { mBitmapDrawable, mColorDrawable };
        LayerDrawable layerDrawable = new LayerDrawable(array);

        layerDrawable.setLayerGravity(0, Gravity.CENTER);
        layerDrawable.setLayerGravity(1, Gravity.NO_GRAVITY);

        try {
            layerDrawable.setLayerGravity(2, Gravity.TOP);
            fail("Should throw ArrayIndexOutOfBoundsException");
        } catch (ArrayIndexOutOfBoundsException e) {
        }
        assertEquals(Gravity.CENTER, layerDrawable.getLayerGravity(0));
        assertEquals(Gravity.NO_GRAVITY, layerDrawable.getLayerGravity(1));
    }

    @Test
    public void testGetLayerGravity() {
        Drawable[] array = new Drawable[] { mBitmapDrawable, mColorDrawable };
        LayerDrawable layerDrawable = new LayerDrawable(array);

        layerDrawable.setLayerGravity(0, Gravity.CENTER);
        layerDrawable.setLayerGravity(1, Gravity.NO_GRAVITY);

        assertEquals(Gravity.CENTER, layerDrawable.getLayerGravity(0));
        assertEquals(Gravity.NO_GRAVITY, layerDrawable.getLayerGravity(1));
        try {
            layerDrawable.getLayerGravity(2);
            fail("Should throw ArrayIndexOutOfBoundsException");
        } catch (ArrayIndexOutOfBoundsException e) {
        }
    }

    @Test
    public void testSetLayerWidth() {
        Drawable[] array = new Drawable[] { mBitmapDrawable, mColorDrawable };
        LayerDrawable layerDrawable = new LayerDrawable(array);

        layerDrawable.setLayerWidth(0, 100);
        layerDrawable.setLayerWidth(1, 200);

        try {
            layerDrawable.setLayerWidth(2, 300);
            fail("Should throw ArrayIndexOutOfBoundsException");
        } catch (ArrayIndexOutOfBoundsException e) {
        }
        assertEquals(100, layerDrawable.getLayerWidth(0));
        assertEquals(200, layerDrawable.getLayerWidth(1));
    }

    @Test
    public void testGetLayerWidth() {
        Drawable[] array = new Drawable[] { mBitmapDrawable, mColorDrawable };
        LayerDrawable layerDrawable = new LayerDrawable(array);

        layerDrawable.setLayerWidth(0, 100);
        layerDrawable.setLayerWidth(1, 200);

        assertEquals(100, layerDrawable.getLayerWidth(0));
        assertEquals(200, layerDrawable.getLayerWidth(1));
        try {
            layerDrawable.getLayerWidth(2);
            fail("Should throw ArrayIndexOutOfBoundsException");
        } catch (ArrayIndexOutOfBoundsException e) {
        }
    }

    @Test
    public void testSetLayerHeight() {
        Drawable[] array = new Drawable[] { mBitmapDrawable, mColorDrawable };
        LayerDrawable layerDrawable = new LayerDrawable(array);

        layerDrawable.setLayerHeight(0, 100);
        layerDrawable.setLayerHeight(1, 200);

        try {
            layerDrawable.setLayerHeight(2, 300);
            fail("Should throw ArrayIndexOutOfBoundsException");
        } catch (ArrayIndexOutOfBoundsException e) {
        }
        assertEquals(100, layerDrawable.getLayerHeight(0));
        assertEquals(200, layerDrawable.getLayerHeight(1));
    }

    @Test
    public void testGetLayerHeight() {
        Drawable[] array = new Drawable[] { mBitmapDrawable, mColorDrawable };
        LayerDrawable layerDrawable = new LayerDrawable(array);

        layerDrawable.setLayerHeight(0, 100);
        layerDrawable.setLayerHeight(1, 200);

        assertEquals(100, layerDrawable.getLayerHeight(0));
        assertEquals(200, layerDrawable.getLayerHeight(1));
        try {
            layerDrawable.getLayerHeight(2);
            fail("Should throw ArrayIndexOutOfBoundsException");
        } catch (ArrayIndexOutOfBoundsException e) {
        }
    }

    @Test
    public void testSetLayerSize() {
        Drawable[] array = new Drawable[] { mBitmapDrawable, mColorDrawable };
        LayerDrawable layerDrawable = new LayerDrawable(array);

        layerDrawable.setLayerSize(0, 100, 200);
        layerDrawable.setLayerSize(1, 300, 400);

        try {
            layerDrawable.setLayerSize(2, 500, 600);
            fail("Should throw ArrayIndexOutOfBoundsException");
        } catch (ArrayIndexOutOfBoundsException e) {
        }
        assertEquals(100, layerDrawable.getLayerWidth(0));
        assertEquals(200, layerDrawable.getLayerHeight(0));
        assertEquals(300, layerDrawable.getLayerWidth(1));
        assertEquals(400, layerDrawable.getLayerHeight(1));
    }

    @Test
    public void testSetLayerInsetRelative() {
        Drawable firstLayer = spy(new ColorDrawable(Color.YELLOW));
        doReturn(10).when(firstLayer).getIntrinsicWidth();
        doReturn(10).when(firstLayer).getIntrinsicHeight();
        Drawable secondLayer = spy(new ColorDrawable(Color.YELLOW));
        doReturn(-1).when(secondLayer).getIntrinsicWidth();
        doReturn(-1).when(secondLayer).getIntrinsicHeight();

        Drawable[] array = new Drawable[] { firstLayer, secondLayer };
        LayerDrawable layerDrawable = new LayerDrawable(array);

        int start = 10;
        int top = 20;
        int end = 30;
        int bottom = 40;
        layerDrawable.setLayerInsetRelative(0, start, top, end, bottom);
        assertEquals(layerDrawable.getDrawable(0).getIntrinsicWidth() + start + end,
                layerDrawable.getIntrinsicWidth());
        assertEquals(layerDrawable.getDrawable(0).getIntrinsicHeight() + top + bottom,
                layerDrawable.getIntrinsicHeight());
        assertEquals(start, layerDrawable.getLayerInsetStart(0));
        assertEquals(top, layerDrawable.getLayerInsetTop(0));
        assertEquals(end, layerDrawable.getLayerInsetEnd(0));
        assertEquals(bottom, layerDrawable.getLayerInsetBottom(0));
        assertEquals(0, layerDrawable.getLayerInsetLeft(0));
        assertEquals(0, layerDrawable.getLayerInsetRight(0));

        // The drawable at index 1 has no intrinsic width or height, so it
        // won't be counted for the overall intrinsic width or height.
        layerDrawable.setLayerInsetRelative(1, 10, 10, 10, 10);
        assertEquals(layerDrawable.getDrawable(0).getIntrinsicWidth() + start + end,
                layerDrawable.getIntrinsicWidth());
        assertEquals(layerDrawable.getDrawable(0).getIntrinsicHeight() + top + bottom,
                layerDrawable.getIntrinsicHeight());

        try {
            layerDrawable.setLayerInsetRelative(-1, start, top, end, bottom);
            fail("Should throw IndexOutOfBoundsException");
        } catch (IndexOutOfBoundsException e) {
        }
    }

    @Test
    public void testSetLayerInsetLeft() {
        Drawable[] array = new Drawable[] { mBitmapDrawable };
        LayerDrawable layerDrawable = new LayerDrawable(array);

        // set inset for layer 0
        int left = 10;
        int top = 20;
        int right = 30;
        int bottom = 40;
        layerDrawable.setLayerInset(0, left, top, right, bottom);
        assertEquals(layerDrawable.getDrawable(0).getIntrinsicWidth() + left + right,
                layerDrawable.getIntrinsicWidth());
        left += 5;
        layerDrawable.setLayerInsetLeft(0, left);
        assertEquals(layerDrawable.getDrawable(0).getIntrinsicWidth() + left + right,
                layerDrawable.getIntrinsicWidth());
        assertEquals(left, layerDrawable.getLayerInsetLeft(0));

        try {
            layerDrawable.setLayerInsetLeft(1, left);
            fail("Should throw IndexOutOfBoundsException");
        } catch (IndexOutOfBoundsException e) {
        }
    }

    @Test
    public void testGetLayerInsetLeft() {
        Drawable[] array = new Drawable[] { mBitmapDrawable };
        LayerDrawable layerDrawable = new LayerDrawable(array);

        // set inset for layer 0
        int left = 10;
        int top = 20;
        int right = 30;
        int bottom = 40;
        layerDrawable.setLayerInset(0, left, top, right, bottom);
        assertEquals(left, layerDrawable.getLayerInsetLeft(0));
        left += 5;
        layerDrawable.setLayerInsetLeft(0, left);
        assertEquals(left, layerDrawable.getLayerInsetLeft(0));

        try {
            layerDrawable.getLayerInsetLeft(1);
            fail("Should throw IndexOutOfBoundsException");
        } catch (IndexOutOfBoundsException e) {
        }
    }

    @Test
    public void testSetLayerInsetTop() {
        Drawable[] array = new Drawable[] { mBitmapDrawable };
        LayerDrawable layerDrawable = new LayerDrawable(array);

        // set inset for layer 0
        int left = 10;
        int top = 20;
        int right = 30;
        int bottom = 40;
        layerDrawable.setLayerInset(0, left, top, right, bottom);
        assertEquals(layerDrawable.getDrawable(0).getIntrinsicHeight() + top + bottom,
                layerDrawable.getIntrinsicHeight());
        top += 5;
        layerDrawable.setLayerInsetTop(0, top);
        assertEquals(layerDrawable.getDrawable(0).getIntrinsicHeight() + top + bottom,
                layerDrawable.getIntrinsicHeight());
        assertEquals(top, layerDrawable.getLayerInsetTop(0));

        try {
            layerDrawable.setLayerInsetTop(1, top);
            fail("Should throw IndexOutOfBoundsException");
        } catch (IndexOutOfBoundsException e) {
        }
    }

    @Test
    public void testGetLayerInsetTop() {
        Drawable[] array = new Drawable[] { mBitmapDrawable };
        LayerDrawable layerDrawable = new LayerDrawable(array);

        // set inset for layer 0
        int left = 10;
        int top = 20;
        int right = 30;
        int bottom = 40;
        layerDrawable.setLayerInset(0, left, top, right, bottom);
        assertEquals(top, layerDrawable.getLayerInsetTop(0));
        top += 5;
        layerDrawable.setLayerInsetTop(0, top);
        assertEquals(top, layerDrawable.getLayerInsetTop(0));

        try {
            layerDrawable.getLayerInsetTop(1);
            fail("Should throw IndexOutOfBoundsException");
        } catch (IndexOutOfBoundsException e) {
        }
    }

    @Test
    public void testSetLayerInsetRight() {
        Drawable[] array = new Drawable[] { mBitmapDrawable };
        LayerDrawable layerDrawable = new LayerDrawable(array);

        // set inset for layer 0
        int left = 10;
        int top = 20;
        int right = 30;
        int bottom = 40;
        layerDrawable.setLayerInset(0, left, top, right, bottom);
        assertEquals(layerDrawable.getDrawable(0).getIntrinsicWidth() + left + right,
                layerDrawable.getIntrinsicWidth());
        right += 5;
        layerDrawable.setLayerInsetRight(0, right);
        assertEquals(layerDrawable.getDrawable(0).getIntrinsicWidth() + left + right,
                layerDrawable.getIntrinsicWidth());
        assertEquals(right, layerDrawable.getLayerInsetRight(0));

        try {
            layerDrawable.setLayerInsetRight(1, right);
            fail("Should throw IndexOutOfBoundsException");
        } catch (IndexOutOfBoundsException e) {
        }
    }

    @Test
    public void testGetLayerInsetRight() {
        Drawable[] array = new Drawable[] { mBitmapDrawable };
        LayerDrawable layerDrawable = new LayerDrawable(array);

        // set inset for layer 0
        int left = 10;
        int top = 20;
        int right = 30;
        int bottom = 40;
        layerDrawable.setLayerInset(0, left, top, right, bottom);
        assertEquals(right, layerDrawable.getLayerInsetRight(0));
        right += 5;
        layerDrawable.setLayerInsetRight(0, right);
        assertEquals(right, layerDrawable.getLayerInsetRight(0));

        try {
            layerDrawable.getLayerInsetRight(1);
            fail("Should throw IndexOutOfBoundsException");
        } catch (IndexOutOfBoundsException e) {
        }
    }

    @Test
    public void testSetLayerInsetBottom() {
        Drawable[] array = new Drawable[] { mBitmapDrawable };
        LayerDrawable layerDrawable = new LayerDrawable(array);

        // set inset for layer 0
        int left = 10;
        int top = 20;
        int right = 30;
        int bottom = 40;
        layerDrawable.setLayerInset(0, left, top, right, bottom);
        assertEquals(layerDrawable.getDrawable(0).getIntrinsicHeight() + top + bottom,
                layerDrawable.getIntrinsicHeight());
        bottom += 5;
        layerDrawable.setLayerInsetBottom(0, bottom);
        assertEquals(layerDrawable.getDrawable(0).getIntrinsicHeight() + top + bottom,
                layerDrawable.getIntrinsicHeight());
        assertEquals(bottom, layerDrawable.getLayerInsetBottom(0));

        try {
            layerDrawable.setLayerInsetBottom(1, bottom);
            fail("Should throw IndexOutOfBoundsException");
        } catch (IndexOutOfBoundsException e) {
        }
    }

    @Test
    public void testGetLayerInsetBottom() {
        Drawable[] array = new Drawable[] { mBitmapDrawable };
        LayerDrawable layerDrawable = new LayerDrawable(array);

        // set inset for layer 0
        int left = 10;
        int top = 20;
        int right = 30;
        int bottom = 40;
        layerDrawable.setLayerInset(0, left, top, right, bottom);
        assertEquals(bottom, layerDrawable.getLayerInsetBottom(0));
        bottom += 5;
        layerDrawable.setLayerInsetBottom(0, bottom);
        assertEquals(bottom, layerDrawable.getLayerInsetBottom(0));

        try {
            layerDrawable.getLayerInsetBottom(1);
            fail("Should throw IndexOutOfBoundsException");
        } catch (IndexOutOfBoundsException e) {
        }
    }

    @Test
    public void testSetLayerInsetStart() {
        Drawable[] array = new Drawable[] { mBitmapDrawable };
        LayerDrawable layerDrawable = new LayerDrawable(array);

        // set inset for layer 0
        int start = 10;
        int top = 20;
        int end = 30;
        int bottom = 40;
        layerDrawable.setLayerInsetRelative(0, start, top, end, bottom);
        assertEquals(layerDrawable.getDrawable(0).getIntrinsicWidth() + start + end,
                layerDrawable.getIntrinsicWidth());
        start += 5;
        layerDrawable.setLayerInsetStart(0, start);
        assertEquals(layerDrawable.getDrawable(0).getIntrinsicWidth() + start + end,
                layerDrawable.getIntrinsicWidth());
        assertEquals(start, layerDrawable.getLayerInsetStart(0));

        try {
            layerDrawable.setLayerInset(1, start, top, end, bottom);
            fail("Should throw IndexOutOfBoundsException");
        } catch (IndexOutOfBoundsException e) {
        }
    }

    @Test
    public void testGetLayerInsetStart() {
        Drawable[] array = new Drawable[] { mBitmapDrawable };
        LayerDrawable layerDrawable = new LayerDrawable(array);

        // set inset for layer 0
        int start = 10;
        int top = 20;
        int end = 30;
        int bottom = 40;
        layerDrawable.setLayerInsetRelative(0, start, top, end, bottom);
        assertEquals(start, layerDrawable.getLayerInsetStart(0));
        start += 5;
        layerDrawable.setLayerInsetStart(0, start);
        assertEquals(start, layerDrawable.getLayerInsetStart(0));

        try {
            layerDrawable.getLayerInsetStart(1);
            fail("Should throw IndexOutOfBoundsException");
        } catch (IndexOutOfBoundsException e) {
        }
    }

    @Test
    public void testSetLayerInsetEnd() {
        Drawable[] array = new Drawable[] { mBitmapDrawable };
        LayerDrawable layerDrawable = new LayerDrawable(array);

        // set inset for layer 0
        int start = 10;
        int top = 20;
        int end = 30;
        int bottom = 40;
        layerDrawable.setLayerInsetRelative(0, start, top, end, bottom);
        assertEquals(end, layerDrawable.getLayerInsetEnd(0));
        assertEquals(layerDrawable.getDrawable(0).getIntrinsicWidth() + start + end,
                layerDrawable.getIntrinsicWidth());
        end += 5;
        layerDrawable.setLayerInsetEnd(0, end);
        assertEquals(layerDrawable.getDrawable(0).getIntrinsicWidth() + start + end,
                layerDrawable.getIntrinsicWidth());
        assertEquals(end, layerDrawable.getLayerInsetEnd(0));

        try {
            layerDrawable.setLayerInsetEnd(1, end);
            fail("Should throw IndexOutOfBoundsException");
        } catch (IndexOutOfBoundsException e) {
        }
    }

    @Test
    public void testGetLayerInsetEnd() {
        Drawable[] array = new Drawable[] { mBitmapDrawable };
        LayerDrawable layerDrawable = new LayerDrawable(array);

        // set inset for layer 0
        int start = 10;
        int top = 20;
        int end = 30;
        int bottom = 40;
        layerDrawable.setLayerInsetRelative(0, start, top, end, bottom);
        assertEquals(end, layerDrawable.getLayerInsetEnd(0));
        end += 5;
        layerDrawable.setLayerInsetEnd(0, end);
        assertEquals(end, layerDrawable.getLayerInsetEnd(0));

        try {
            layerDrawable.getLayerInsetEnd(1);
            fail("Should throw IndexOutOfBoundsException");
        } catch (IndexOutOfBoundsException e) {
        }
    }

    @Test
    public void testChildIntrinsicSize() {
        LayerDrawable dr;

        // Ensure that a child with no intrinsic size correctly reports bounds.
        dr = (LayerDrawable) mContext.getDrawable(R.drawable.layer_drawable_intrinsic);
        assertEquals(-1, dr.getIntrinsicWidth());
        assertEquals(-1, dr.getIntrinsicHeight());

        // Check when creating the drawble from code.
        dr = new LayerDrawable(new Drawable[] { new ColorDrawable(Color.RED) });
        dr.setLayerInset(0, 10, 10, 10, 10);
        assertEquals(-1, dr.getIntrinsicWidth());
        assertEquals(-1, dr.getIntrinsicHeight());

        // Ensure mixed children report bounds correctly as well.
        dr = (LayerDrawable) mContext.getDrawable(R.drawable.layer_drawable_intrinsic_mixed);
        int width = dr.getLayerInsetLeft(0) + dr.getLayerInsetRight(0)
                + dr.getDrawable(0).getIntrinsicWidth();
        int height = dr.getLayerInsetTop(0) + dr.getLayerInsetBottom(0)
                + dr.getDrawable(0).getIntrinsicHeight();
        assertEquals(width, dr.getIntrinsicWidth());
        assertEquals(height, dr.getIntrinsicHeight());
    }

    // Since Mockito can't mock or spy on protected methods, we have a custom extension
    // of Drawable to track calls to protected methods. This class also has empty implementations
    // of the base abstract methods. In addition, this class also updates its padding on every
    // change in level or state.
    private static class MockDrawable extends Drawable {
        private boolean mCalledSetState = false;
        private boolean mCalledOnLevelChange = false;
        private boolean mCalledOnBoundsChange = false;

        private boolean mIsStateful = false;

        private Rect mPadding = null;

        public MockDrawable() {
            this(false);
        }

        public MockDrawable(boolean isStateful) {
            mIsStateful = isStateful;
        }

        @Override
        public void draw(Canvas canvas) {
        }

        @Override
        public int getOpacity() {
            return PixelFormat.OPAQUE;
        }

        @Override
        public void setAlpha(int alpha) {
        }

        @Override
        public void setColorFilter(ColorFilter cf) {
        }

        public void reset() {
            mCalledSetState = false;
            mCalledOnLevelChange = false;
            mCalledOnBoundsChange = false;
        }

        @Override
        protected boolean onStateChange(int[] state) {
            increasePadding();
            return mIsStateful;
        }

        private void increasePadding() {
            Rect padding = new Rect();
            getPadding(padding);
            padding.left++;
            padding.top++;
            padding.right++;
            padding.bottom++;

            setPadding(padding);
        }

        @Override
        protected boolean onLevelChange(int level) {
            increasePadding();
            mCalledOnLevelChange = true;
            return true;
        }

        @Override
        protected void onBoundsChange(Rect bounds) {
            mCalledOnBoundsChange = true;
            super.onBoundsChange(bounds);
        }

        public boolean hasCalledOnBoundsChange() {
            return mCalledOnBoundsChange;
        }

        @Override
        public boolean isStateful() {
            return mIsStateful;
        }

        public boolean hasCalledSetState() {
            return mCalledSetState;
        }

        @Override
        public boolean setState(final int[] stateSet) {
            mCalledSetState = true;
            return super.setState(stateSet);
        }

        public boolean hasCalledOnLevelChange() {
            return mCalledOnLevelChange;
        }

        private void setPadding(Rect padding) {
            if (padding == null) {
                mPadding = null;
            } else {
                if (mPadding == null) {
                    mPadding = new Rect();
                }
                mPadding.set(padding);
            }
        }

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

    @Test
    public void testMutate() {
        LayerDrawable d1 = (LayerDrawable) mContext.getDrawable(R.drawable.layerdrawable);
        LayerDrawable d2 = (LayerDrawable) mContext.getDrawable(R.drawable.layerdrawable);
        LayerDrawable d3 = (LayerDrawable) mContext.getDrawable(R.drawable.layerdrawable);
        int restoreAlpha = d1.getAlpha();

        try {
            // verify bad behavior - modify before mutate pollutes other drawables
            d1.setAlpha(100);
            assertEquals(100, ((BitmapDrawable) d1.getDrawable(0)).getPaint().getAlpha());
            assertEquals(100, ((BitmapDrawable) d1.getDrawable(0)).getPaint().getAlpha());
            assertEquals(100, ((BitmapDrawable) d2.getDrawable(0)).getPaint().getAlpha());
            assertEquals(100, ((BitmapDrawable) d2.getDrawable(0)).getPaint().getAlpha());
            assertEquals(100, ((BitmapDrawable) d3.getDrawable(0)).getPaint().getAlpha());
            assertEquals(100, ((BitmapDrawable) d2.getDrawable(0)).getPaint().getAlpha());

            d1.mutate();
            d1.setAlpha(200);
            assertEquals(200, ((BitmapDrawable) d1.getDrawable(0)).getPaint().getAlpha());
            assertEquals(200, ((BitmapDrawable) d1.getDrawable(0)).getPaint().getAlpha());
            assertEquals(100, ((BitmapDrawable) d2.getDrawable(0)).getPaint().getAlpha());
            assertEquals(100, ((BitmapDrawable) d2.getDrawable(0)).getPaint().getAlpha());
            assertEquals(100, ((BitmapDrawable) d3.getDrawable(0)).getPaint().getAlpha());
            assertEquals(100, ((BitmapDrawable) d3.getDrawable(0)).getPaint().getAlpha());

            d2.setAlpha(50);
            assertEquals(200, ((BitmapDrawable) d1.getDrawable(0)).getPaint().getAlpha());
            assertEquals(200, ((BitmapDrawable) d1.getDrawable(0)).getPaint().getAlpha());
            assertEquals(50, ((BitmapDrawable) d2.getDrawable(0)).getPaint().getAlpha());
            assertEquals(50, ((BitmapDrawable) d2.getDrawable(0)).getPaint().getAlpha());
            assertEquals(50, ((BitmapDrawable) d3.getDrawable(0)).getPaint().getAlpha());
            assertEquals(50, ((BitmapDrawable) d3.getDrawable(0)).getPaint().getAlpha());
        } finally {
            // restore externally visible state, since other tests may use the drawable
            mContext.getDrawable(R.drawable.layerdrawable).setAlpha(restoreAlpha);
        }
    }

    @Test
    public void testPreloadDensity() throws XmlPullParserException, IOException {
        final Resources res = mContext.getResources();
        final int densityDpi = res.getConfiguration().densityDpi;
        try {
            DrawableTestUtils.setResourcesDensity(res, densityDpi);
            verifyPreloadDensityInner(res, densityDpi);
        } finally {
            DrawableTestUtils.setResourcesDensity(res, densityDpi);
        }
    }

    @Test
    public void testPreloadDensity_tvdpi() throws XmlPullParserException, IOException {
        final Resources res = mContext.getResources();
        final int densityDpi = res.getConfiguration().densityDpi;
        try {
            DrawableTestUtils.setResourcesDensity(res, 213);
            verifyPreloadDensityInner(res, 213);
        } finally {
            DrawableTestUtils.setResourcesDensity(res, densityDpi);
        }
    }

    private void verifyPreloadDensityInner(Resources res, int densityDpi)
            throws XmlPullParserException, IOException {
        // Capture initial state at default density.
        final XmlResourceParser parser = DrawableTestUtils.getResourceParser(
                res, R.drawable.layer_drawable_density);
        final LayerDrawable preloadedDrawable = new LayerDrawable(new Drawable[0]);
        preloadedDrawable.inflate(res, parser, Xml.asAttributeSet(parser));
        final ConstantState preloadedConstantState = preloadedDrawable.getConstantState();
        final int initialLeftPadding = preloadedDrawable.getLeftPadding();
        final int initialRightPadding = preloadedDrawable.getRightPadding();
        final int initialContentInsetL = preloadedDrawable.getLayerInsetLeft(0);
        final int initialContentInsetR = preloadedDrawable.getLayerInsetRight(0);
        final int initialContentWidth = preloadedDrawable.getLayerWidth(0);
        final int initialIntrinsicWidth = preloadedDrawable.getIntrinsicWidth();
        final int initialBottomPadding = preloadedDrawable.getBottomPadding();
        final int initialTopPadding = preloadedDrawable.getTopPadding();
        final int initialLayerInsetLeft = preloadedDrawable.getLayerInsetLeft(0);
        final int initialLayerInsetRight = preloadedDrawable.getLayerInsetRight(0);
        final int initialLayerInsetTop = preloadedDrawable.getLayerInsetTop(0);
        final int initialLayerInsetBottom = preloadedDrawable.getLayerInsetBottom(0);
        final int initialLayerWidth = preloadedDrawable.getLayerWidth(0);
        final int initialLayerHeight = preloadedDrawable.getLayerHeight(0);

        // Set density to half of original. Padding and insets are
        // truncated, dimensions are rounded to the nearest pixel. Because
        // LayerDrawable's intrinsic width is a combination of padding and
        // dimensions, some computation is necessary.
        DrawableTestUtils.setResourcesDensity(res, densityDpi / 2);
        final LayerDrawable halfDrawable =
                (LayerDrawable) preloadedConstantState.newDrawable(res);
        // NOTE: densityDpi may not be an even number, so account for *actual* scaling in asserts
        final float approxHalf = (float)(densityDpi / 2) / densityDpi;
        final int halfContentWidth = Math.round(initialContentWidth * approxHalf);
        final int halfLeftPadding = (int) (initialLeftPadding * approxHalf);
        final int halfRightPadding = (int) (initialRightPadding * approxHalf);
        final int halfContentInsetL = (int) (initialContentInsetL * approxHalf);
        final int halfContentInsetR = (int) (initialContentInsetR * approxHalf);
        final int halfIntrinsicWidth = halfContentWidth + halfContentInsetL + halfContentInsetR;
        assertEquals(halfLeftPadding, halfDrawable.getLeftPadding());
        assertEquals(halfRightPadding, halfDrawable.getRightPadding());
        assertEquals(halfContentInsetL, halfDrawable.getLayerInsetRight(0));
        assertEquals(halfContentInsetR, halfDrawable.getLayerInsetLeft(0));
        assertEquals(halfContentWidth, halfDrawable.getLayerWidth(0));
        assertEquals(halfIntrinsicWidth, halfDrawable.getIntrinsicWidth());
        assertEquals((int) (initialBottomPadding * approxHalf), halfDrawable.getBottomPadding());
        assertEquals((int) (initialTopPadding * approxHalf), halfDrawable.getTopPadding());
        assertEquals((int) (initialLayerInsetLeft * approxHalf),
                halfDrawable.getLayerInsetLeft(0));
        assertEquals((int) (initialLayerInsetRight * approxHalf),
                halfDrawable.getLayerInsetRight(0));
        assertEquals((int) (initialLayerInsetTop * approxHalf),
                halfDrawable.getLayerInsetTop(0));
        assertEquals((int) (initialLayerInsetBottom * approxHalf),
                halfDrawable.getLayerInsetBottom(0));
        assertEquals(Math.round(initialLayerWidth * approxHalf), halfDrawable.getLayerWidth(0));
        assertEquals(Math.round(initialLayerHeight * approxHalf), halfDrawable.getLayerHeight(0));

        // Set density to double original.
        DrawableTestUtils.setResourcesDensity(res, densityDpi * 2);
        final LayerDrawable doubleDrawable =
                (LayerDrawable) preloadedConstantState.newDrawable(res);
        assertEquals(initialLeftPadding * 2, doubleDrawable.getLeftPadding());
        assertEquals(initialRightPadding * 2, doubleDrawable.getRightPadding());
        assertEquals(initialContentInsetL * 2, doubleDrawable.getLayerInsetRight(0));
        assertEquals(initialContentInsetR * 2, doubleDrawable.getLayerInsetLeft(0));
        assertEquals(initialContentWidth * 2, doubleDrawable.getLayerWidth(0));
        assertEquals(initialIntrinsicWidth * 2, doubleDrawable.getIntrinsicWidth());
        assertEquals(initialBottomPadding * 2, doubleDrawable.getBottomPadding());
        assertEquals(initialTopPadding * 2, doubleDrawable.getTopPadding());
        assertEquals(initialLayerInsetLeft * 2, doubleDrawable.getLayerInsetLeft(0));
        assertEquals(initialLayerInsetRight * 2, doubleDrawable.getLayerInsetRight(0));
        assertEquals(initialLayerInsetTop * 2, doubleDrawable.getLayerInsetTop(0));
        assertEquals(initialLayerInsetBottom * 2, doubleDrawable.getLayerInsetBottom(0));
        assertEquals(initialLayerWidth * 2, doubleDrawable.getLayerWidth(0));
        assertEquals(initialLayerHeight * 2, doubleDrawable.getLayerHeight(0));

        // Restore original configuration and metrics.
        DrawableTestUtils.setResourcesDensity(res, densityDpi);
        final LayerDrawable origDrawable =
                (LayerDrawable) preloadedConstantState.newDrawable(res);
        assertEquals(initialLeftPadding, origDrawable.getLeftPadding());
        assertEquals(initialRightPadding, origDrawable.getRightPadding());
        assertEquals(initialContentInsetL, origDrawable.getLayerInsetRight(0));
        assertEquals(initialContentInsetR, origDrawable.getLayerInsetLeft(0));
        assertEquals(initialContentWidth, origDrawable.getLayerWidth(0));
        assertEquals(initialIntrinsicWidth, origDrawable.getIntrinsicWidth());
        assertEquals(initialBottomPadding, origDrawable.getBottomPadding());
        assertEquals(initialTopPadding, origDrawable.getTopPadding());
        assertEquals(initialLayerInsetLeft, origDrawable.getLayerInsetLeft(0));
        assertEquals(initialLayerInsetRight, origDrawable.getLayerInsetRight(0));
        assertEquals(initialLayerInsetTop, origDrawable.getLayerInsetTop(0));
        assertEquals(initialLayerInsetBottom, origDrawable.getLayerInsetBottom(0));
        assertEquals(initialLayerWidth, origDrawable.getLayerWidth(0));
        assertEquals(initialLayerHeight, origDrawable.getLayerHeight(0));

        // Ensure theme density is applied correctly.
        final Theme t = res.newTheme();

        // The half-density drawable will scale-up all of the values that were
        // previously scaled-down, so we need to capture the rounding errors.
        halfDrawable.applyTheme(t);

        // Reproduce imprecise truncated scale down, and back up. Note that we don't round.
        float approxDouble = 1 / approxHalf;
        assertEquals((int) (halfLeftPadding * approxDouble), halfDrawable.getLeftPadding());
        assertEquals((int) (halfRightPadding * approxDouble), halfDrawable.getRightPadding());
        assertEquals((int) (halfContentInsetL * approxDouble), halfDrawable.getLayerInsetRight(0));
        assertEquals((int) (halfContentInsetR * approxDouble), halfDrawable.getLayerInsetLeft(0));
        assertEquals((int) (halfContentWidth * approxDouble), halfDrawable.getLayerWidth(0));
        assertEquals(halfIntrinsicWidth * 2, halfDrawable.getIntrinsicWidth());
        assertEquals((int) ((int) (initialBottomPadding * approxHalf) * approxDouble),
                halfDrawable.getBottomPadding());
        assertEquals((int) ((int) (initialTopPadding * approxHalf) * approxDouble),
                halfDrawable.getTopPadding());
        assertEquals((int) ((int) (initialLayerInsetLeft * approxHalf) * approxDouble),
                halfDrawable.getLayerInsetLeft(0));
        assertEquals((int) ((int) (initialLayerInsetRight * approxHalf) * approxDouble),
                halfDrawable.getLayerInsetRight(0));
        assertEquals((int) ((int) (initialLayerInsetTop * approxHalf) * approxDouble),
                halfDrawable.getLayerInsetTop(0));
        assertEquals((int) ((int) (initialLayerInsetBottom * approxHalf) * approxDouble),
                halfDrawable.getLayerInsetBottom(0));
        assertEquals(Math.round(Math.round(initialLayerWidth * approxHalf) * approxDouble),
                halfDrawable.getLayerWidth(0));
        assertEquals(Math.round(Math.round(initialLayerHeight * approxHalf) * approxDouble),
                halfDrawable.getLayerHeight(0));

        // The double-density drawable will scale-down all of the values that
        // were previously scaled-up, so we don't need to worry about rounding.
        doubleDrawable.applyTheme(t);
        assertEquals(initialLeftPadding, doubleDrawable.getLeftPadding());
        assertEquals(initialRightPadding, doubleDrawable.getRightPadding());
        assertEquals(initialContentInsetL, doubleDrawable.getLayerInsetRight(0));
        assertEquals(initialContentInsetR, doubleDrawable.getLayerInsetLeft(0));
        assertEquals(initialContentWidth, doubleDrawable.getLayerWidth(0));
        assertEquals(initialIntrinsicWidth, doubleDrawable.getIntrinsicWidth());
        assertEquals(initialBottomPadding, doubleDrawable.getBottomPadding());
        assertEquals(initialTopPadding, doubleDrawable.getTopPadding());
        assertEquals(initialLayerInsetLeft, doubleDrawable.getLayerInsetLeft(0));
        assertEquals(initialLayerInsetRight, doubleDrawable.getLayerInsetRight(0));
        assertEquals(initialLayerInsetTop, doubleDrawable.getLayerInsetTop(0));
        assertEquals(initialLayerInsetBottom, doubleDrawable.getLayerInsetBottom(0));
        assertEquals(initialLayerWidth, doubleDrawable.getLayerWidth(0));
        assertEquals(initialLayerHeight, doubleDrawable.getLayerHeight(0));
    }

    @Test
    public void testOpacityChange() {
        ColorDrawable c1 = new ColorDrawable(Color.RED);
        ColorDrawable c2 = new ColorDrawable(Color.BLUE);
        LayerDrawable dr = new LayerDrawable(new ColorDrawable[] { c1, c2 });
        assertEquals(PixelFormat.OPAQUE, dr.getOpacity());

        c1.setTint(0x80FF0000);
        c1.setTintMode(PorterDuff.Mode.SRC);
        c2.setTint(0x800000FF);
        c2.setTintMode(PorterDuff.Mode.SRC);
        assertEquals(PixelFormat.TRANSLUCENT, dr.getOpacity());
    }

    @Test
    public void testStatefulnessChange() {
        ColorDrawable c1 = new ColorDrawable(Color.RED);
        ColorDrawable c2 = new ColorDrawable(Color.BLUE);
        LayerDrawable dr = new LayerDrawable(new ColorDrawable[] { c1, c2 });
        assertEquals(false, dr.isStateful());

        ColorStateList csl = new ColorStateList(
                new int[][] { { android.R.attr.state_enabled }, { } },
                new int[] { Color.RED, Color.BLUE });
        c1.setTintList(csl);
        assertEquals(true, dr.isStateful());
    }

    @Test
    public void testInvalidateDuringInit() {
        Drawable layer = new RippleDrawable(ColorStateList.valueOf(Color.BLACK), null, null);

        LayerDrawable orig = new LayerDrawable(new Drawable[] { layer });
        orig.setBounds(0, 0, 100, 100);

        // This will invoke the layer's invalidateSelf() during construction.
        LayerDrawable copy = (LayerDrawable) orig.getConstantState().newDrawable();
        assertNotSame(orig, copy);
    }

    private static class IntrinsicSizeDrawable extends Drawable {
        private final int mIntrinsicWidth;
        private final int mIntrinsicHeight;
        private final Rect mPadding;

        public IntrinsicSizeDrawable(int intrinsicWidth, int intrinsicHeight, Rect padding) {
            mIntrinsicWidth = intrinsicWidth;
            mIntrinsicHeight = intrinsicHeight;
            mPadding = new Rect(padding);
        }

        @Override
        public boolean getPadding(Rect padding) {
            padding.set(mPadding);
            return true;
        }

        @Override
        public int getIntrinsicHeight() {
            return mIntrinsicHeight;
        }

        @Override
        public int getIntrinsicWidth() {
            return mIntrinsicWidth;
        }

        @Override
        public void draw(Canvas canvas) {
        }

        @Override
        public void setAlpha(int alpha) {
        }

        @Override
        public void setColorFilter(ColorFilter colorFilter) {
        }

        @Override
        public int getOpacity() {
            return 0;
        }
    }
}
