Home | History | Annotate | Download | only in cts
      1 /*
      2  * Copyright (C) 2008 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package android.graphics.drawable.cts;
     18 
     19 import static org.junit.Assert.assertEquals;
     20 import static org.junit.Assert.assertFalse;
     21 import static org.junit.Assert.assertNotNull;
     22 import static org.junit.Assert.assertNotSame;
     23 import static org.junit.Assert.assertNull;
     24 import static org.junit.Assert.assertSame;
     25 import static org.junit.Assert.assertTrue;
     26 import static org.junit.Assert.fail;
     27 import static org.mockito.ArgumentMatchers.anyInt;
     28 import static org.mockito.Matchers.any;
     29 import static org.mockito.Matchers.anyBoolean;
     30 import static org.mockito.Matchers.anyLong;
     31 import static org.mockito.Mockito.doAnswer;
     32 import static org.mockito.Mockito.doNothing;
     33 import static org.mockito.Mockito.doReturn;
     34 import static org.mockito.Mockito.mock;
     35 import static org.mockito.Mockito.never;
     36 import static org.mockito.Mockito.reset;
     37 import static org.mockito.Mockito.spy;
     38 import static org.mockito.Mockito.times;
     39 import static org.mockito.Mockito.verify;
     40 
     41 import android.content.Context;
     42 import android.content.res.ColorStateList;
     43 import android.content.res.Resources;
     44 import android.content.res.Resources.Theme;
     45 import android.content.res.XmlResourceParser;
     46 import android.graphics.BitmapFactory;
     47 import android.graphics.Canvas;
     48 import android.graphics.Color;
     49 import android.graphics.ColorFilter;
     50 import android.graphics.PixelFormat;
     51 import android.graphics.PorterDuff;
     52 import android.graphics.Rect;
     53 import android.graphics.cts.R;
     54 import android.graphics.drawable.BitmapDrawable;
     55 import android.graphics.drawable.ColorDrawable;
     56 import android.graphics.drawable.Drawable;
     57 import android.graphics.drawable.Drawable.ConstantState;
     58 import android.graphics.drawable.GradientDrawable;
     59 import android.graphics.drawable.LayerDrawable;
     60 import android.graphics.drawable.RippleDrawable;
     61 import android.graphics.drawable.RotateDrawable;
     62 import android.graphics.drawable.ShapeDrawable;
     63 import android.graphics.drawable.StateListDrawable;
     64 import android.util.AttributeSet;
     65 import android.util.StateSet;
     66 import android.util.Xml;
     67 import android.view.Gravity;
     68 import android.view.View;
     69 
     70 import androidx.test.InstrumentationRegistry;
     71 import androidx.test.filters.SmallTest;
     72 import androidx.test.runner.AndroidJUnit4;
     73 
     74 import org.junit.Before;
     75 import org.junit.Test;
     76 import org.junit.runner.RunWith;
     77 import org.xmlpull.v1.XmlPullParserException;
     78 
     79 import java.io.IOException;
     80 
     81 @SmallTest
     82 @RunWith(AndroidJUnit4.class)
     83 public class LayerDrawableTest {
     84     private Context mContext;
     85     private ColorDrawable mColorDrawable;
     86     private BitmapDrawable mBitmapDrawable;
     87 
     88     @Before
     89     public void setup() {
     90         mContext = InstrumentationRegistry.getTargetContext();
     91         Resources resources = mContext.getResources();
     92         mColorDrawable = new ColorDrawable(Color.BLUE);
     93         mBitmapDrawable = new BitmapDrawable(resources,
     94                 BitmapFactory.decodeResource(resources, R.drawable.icon_blue));
     95     }
     96 
     97     @Test
     98     public void testConstructor() {
     99         Drawable[] array = new Drawable[]{mBitmapDrawable, mColorDrawable};
    100         LayerDrawable layerDrawable = new LayerDrawable(array);
    101         assertEquals(array.length, layerDrawable.getNumberOfLayers());
    102         assertSame(mBitmapDrawable, layerDrawable.getDrawable(0));
    103         assertSame(mColorDrawable, layerDrawable.getDrawable(1));
    104 
    105         array = new Drawable[0];
    106         layerDrawable = new LayerDrawable(array);
    107         assertEquals(0, layerDrawable.getNumberOfLayers());
    108     }
    109 
    110     @Test(expected=IllegalArgumentException.class)
    111     public void testConstructorNull() {
    112         new LayerDrawable(null);
    113     }
    114 
    115     @Test
    116     public void testInflate() throws XmlPullParserException, IOException {
    117         Drawable[] array = new Drawable[0];
    118         LayerDrawable layerDrawable = new LayerDrawable(array);
    119 
    120         XmlResourceParser parser = mContext.getResources().getXml(R.xml.layerdrawable);
    121         AttributeSet attrs = DrawableTestUtils.getAttributeSet(parser, "layer-list_full");
    122 
    123         layerDrawable.inflate(mContext.getResources(), parser, attrs);
    124 
    125         assertEquals(4, layerDrawable.getNumberOfLayers());
    126         assertEquals(ColorDrawable.class, layerDrawable.getDrawable(0).getClass());
    127         assertEquals(0x88, layerDrawable.getDrawable(0).getAlpha());
    128         assertEquals(View.NO_ID, layerDrawable.getId(0));
    129         assertEquals(BitmapDrawable.class, layerDrawable.getDrawable(1).getClass());
    130         assertEquals(View.NO_ID, layerDrawable.getId(1));
    131         assertEquals(RotateDrawable.class, layerDrawable.getDrawable(2).getClass());
    132         assertEquals(View.NO_ID, layerDrawable.getId(2));
    133         assertEquals(GradientDrawable.class, layerDrawable.getDrawable(3).getClass());
    134         assertEquals(R.id.background, layerDrawable.getId(3));
    135 
    136         layerDrawable = new LayerDrawable(array);
    137         parser = mContext.getResources().getXml(R.xml.layerdrawable);
    138         attrs = DrawableTestUtils.getAttributeSet(parser, "layer-list_empty");
    139         layerDrawable.inflate(mContext.getResources(), parser, attrs);
    140         assertEquals(0, layerDrawable.getNumberOfLayers());
    141 
    142         parser = mContext.getResources().getXml(R.xml.layerdrawable);
    143         attrs = DrawableTestUtils.getAttributeSet(parser, "layer-list_exception");
    144         try {
    145             layerDrawable.inflate(mContext.getResources(), parser, attrs);
    146             fail("Should throw XmlPullParserException if neither 'drawable' attribute" +
    147                     " nor child tag defining a drawable in <item> tag.");
    148         } catch (XmlPullParserException e) {
    149         }
    150 
    151         try {
    152             layerDrawable.inflate(null, parser, attrs);
    153             fail("Should throw NullPointerException if resource is null");
    154         } catch (NullPointerException e) {
    155         }
    156 
    157         try {
    158             layerDrawable.inflate(mContext.getResources(), null, attrs);
    159             fail("Should throw NullPointerException if parser is null");
    160         } catch (NullPointerException e) {
    161         }
    162 
    163         try {
    164             layerDrawable.inflate(mContext.getResources(), parser, null);
    165             fail("Should throw NullPointerException if attribute set is null");
    166         } catch (NullPointerException e) {
    167         }
    168     }
    169 
    170     @Test
    171     public void testFindDrawableByLayerId() {
    172         Drawable[] array = new Drawable[] { mBitmapDrawable, mColorDrawable };
    173         LayerDrawable layerDrawable = new LayerDrawable(array);
    174 
    175         layerDrawable.setId(0, 10);
    176         layerDrawable.setId(1, 20);
    177         assertSame(mBitmapDrawable, layerDrawable.findDrawableByLayerId(10));
    178         assertSame(mColorDrawable, layerDrawable.findDrawableByLayerId(20));
    179         assertNull(layerDrawable.findDrawableByLayerId(30));
    180 
    181         layerDrawable.setId(0, Integer.MIN_VALUE);
    182         layerDrawable.setId(1, Integer.MAX_VALUE);
    183         assertSame(mBitmapDrawable, layerDrawable.findDrawableByLayerId(Integer.MIN_VALUE));
    184         assertSame(mColorDrawable, layerDrawable.findDrawableByLayerId(Integer.MAX_VALUE));
    185 
    186         layerDrawable.setId(0, 10);
    187         layerDrawable.setId(1, 10);
    188         assertSame(mColorDrawable, layerDrawable.findDrawableByLayerId(10));
    189         assertNull(layerDrawable.findDrawableByLayerId(30));
    190     }
    191 
    192     @Test
    193     public void testAccessId() {
    194         Drawable[] array = new Drawable[] { mBitmapDrawable, mColorDrawable };
    195         LayerDrawable layerDrawable = new LayerDrawable(array);
    196 
    197         layerDrawable.setId(0, 10);
    198         layerDrawable.setId(1, 20);
    199         assertEquals(10, layerDrawable.getId(0));
    200         assertEquals(20, layerDrawable.getId(1));
    201 
    202         layerDrawable.setId(0, Integer.MIN_VALUE);
    203         layerDrawable.setId(1, Integer.MAX_VALUE);
    204         assertEquals(Integer.MIN_VALUE, layerDrawable.getId(0));
    205         assertEquals(Integer.MAX_VALUE, layerDrawable.getId(1));
    206     }
    207 
    208     @Test(expected=IndexOutOfBoundsException.class)
    209     public void testSetIdIndexTooLow() {
    210         Drawable[] array = new Drawable[] { mBitmapDrawable, mColorDrawable };
    211         LayerDrawable layerDrawable = new LayerDrawable(array);
    212         layerDrawable.setId(-1, 20);
    213     }
    214 
    215     @Test(expected=IndexOutOfBoundsException.class)
    216     public void testSetIdIndexTooHigh() {
    217         Drawable[] array = new Drawable[] { mBitmapDrawable, mColorDrawable };
    218         LayerDrawable layerDrawable = new LayerDrawable(array);
    219         layerDrawable.setId(layerDrawable.getNumberOfLayers(), 20);
    220     }
    221 
    222     @Test(expected=IndexOutOfBoundsException.class)
    223     public void testGetIdIndexTooLow() {
    224         Drawable[] array = new Drawable[] { mBitmapDrawable, mColorDrawable };
    225         LayerDrawable layerDrawable = new LayerDrawable(array);
    226         layerDrawable.getId(-1);
    227     }
    228 
    229     @Test(expected=IndexOutOfBoundsException.class)
    230     public void testGetIdIndexTooHigh() {
    231         Drawable[] array = new Drawable[] { mBitmapDrawable, mColorDrawable };
    232         LayerDrawable layerDrawable = new LayerDrawable(array);
    233         layerDrawable.getId(layerDrawable.getNumberOfLayers());
    234     }
    235 
    236     @Test
    237     public void testGetNumberOfLayers() {
    238         Drawable[] array = new Drawable[] { mBitmapDrawable, mColorDrawable };
    239         LayerDrawable layerDrawable = new LayerDrawable(array);
    240         assertEquals(2, layerDrawable.getNumberOfLayers());
    241 
    242         array = new Drawable[5];
    243         for (int i = 0; i < 5; i++) {
    244             array[i] = new BitmapDrawable();
    245         }
    246         layerDrawable = new LayerDrawable(array);
    247         assertEquals(5, layerDrawable.getNumberOfLayers());
    248 
    249         array = new Drawable[0];
    250         layerDrawable = new LayerDrawable(array);
    251         assertEquals(0, layerDrawable.getNumberOfLayers());
    252     }
    253 
    254     @Test
    255     public void testAccessDrawable() {
    256         Drawable[] array = new Drawable[] { mBitmapDrawable, mColorDrawable };
    257         LayerDrawable layerDrawable = new LayerDrawable(array);
    258         assertSame(mBitmapDrawable, layerDrawable.getDrawable(0));
    259         assertSame(mColorDrawable, layerDrawable.getDrawable(1));
    260 
    261         layerDrawable.setId(0, 10);
    262         layerDrawable.setId(1, 20);
    263         Drawable d1 = new ColorDrawable(Color.GREEN);
    264         Drawable d2 = new BitmapDrawable();
    265         layerDrawable.setDrawableByLayerId(10, d1);
    266         layerDrawable.setDrawableByLayerId(20, d2);
    267         assertEquals(d1, layerDrawable.getDrawable(0));
    268         assertEquals(d2, layerDrawable.getDrawable(1));
    269 
    270         assertFalse(layerDrawable.setDrawableByLayerId(30, d1));
    271 
    272         try {
    273             layerDrawable.getDrawable(layerDrawable.getNumberOfLayers());
    274             fail("Should throw IndexOutOfBoundsException");
    275         } catch (IndexOutOfBoundsException e) {
    276         }
    277 
    278         try {
    279             layerDrawable.getDrawable(-1);
    280             fail("Should throw IndexOutOfBoundsException");
    281         } catch (IndexOutOfBoundsException e) {
    282         }
    283     }
    284 
    285     @Test
    286     public void testSetDrawableByLayerId() {
    287         Drawable layer1A  = new ColorDrawable(Color.RED);
    288         Drawable layer2A  = new ColorDrawable(Color.BLUE);
    289         LayerDrawable layerDrawable = new LayerDrawable(new Drawable[] { layer1A, layer2A });
    290         layerDrawable.setId(0, 10);
    291         layerDrawable.setId(1, 20);
    292 
    293         Drawable layer1B = new ColorDrawable(Color.GREEN);
    294         layer1B.setLevel(10000);
    295         Drawable layer2B = new ColorDrawable(Color.YELLOW);
    296         layer2B.setLevel(5000);
    297         layerDrawable.setDrawableByLayerId(10, layer1B);
    298         layerDrawable.setDrawableByLayerId(20, layer2B);
    299 
    300         assertEquals("Level is unchanged after setDrawableByLayerId()",
    301                 10000, layerDrawable.findDrawableByLayerId(10).getLevel());
    302         assertEquals("Level is unchanged after setDrawableByLayerId()",
    303                 5000, layerDrawable.findDrawableByLayerId(20).getLevel());
    304     }
    305 
    306     @Test
    307     public void testSetLayerInset() {
    308         Drawable firstLayer = spy(new ColorDrawable(Color.YELLOW));
    309         doReturn(10).when(firstLayer).getIntrinsicWidth();
    310         doReturn(10).when(firstLayer).getIntrinsicHeight();
    311         Drawable secondLayer = spy(new ColorDrawable(Color.YELLOW));
    312         doReturn(-1).when(secondLayer).getIntrinsicWidth();
    313         doReturn(-1).when(secondLayer).getIntrinsicHeight();
    314 
    315         Drawable[] array = new Drawable[] { firstLayer, secondLayer };
    316         LayerDrawable layerDrawable = new LayerDrawable(array);
    317 
    318         // set inset for layer 0
    319         int left = 10;
    320         int top = 20;
    321         int right = 30;
    322         int bottom = 40;
    323         layerDrawable.setLayerInset(0, left, top, right, bottom);
    324         assertEquals(layerDrawable.getDrawable(0).getIntrinsicWidth() + left + right,
    325                 layerDrawable.getIntrinsicWidth());
    326         assertEquals(layerDrawable.getDrawable(0).getIntrinsicHeight() + top + bottom,
    327                 layerDrawable.getIntrinsicHeight());
    328 
    329         // The drawable at index 0 has no intrinsic width or height, so it
    330         // won't be counted for the overall intrinsic width or height.
    331         layerDrawable.setLayerInset(1, 10, 10, 10, 10);
    332         assertEquals(layerDrawable.getDrawable(0).getIntrinsicWidth() + left + right,
    333                 layerDrawable.getIntrinsicWidth());
    334         assertEquals(layerDrawable.getDrawable(0).getIntrinsicHeight() + top + bottom,
    335                 layerDrawable.getIntrinsicHeight());
    336 
    337         try {
    338             layerDrawable.setLayerInset(-1, left, top, right, bottom);
    339             fail("Should throw IndexOutOfBoundsException");
    340         } catch (IndexOutOfBoundsException e) {
    341         }
    342     }
    343 
    344     @Test
    345     public void testInvalidateDrawable() {
    346         Drawable[] array = new Drawable[0];
    347         LayerDrawable layerDrawable = new LayerDrawable(array);
    348 
    349         Drawable.Callback cb = mock(Drawable.Callback.class);
    350         layerDrawable.setCallback(cb);
    351         layerDrawable.invalidateDrawable(null);
    352         verify(cb, times(1)).invalidateDrawable(any());
    353 
    354         reset(cb);
    355         layerDrawable.invalidateDrawable(new BitmapDrawable());
    356         verify(cb, times(1)).invalidateDrawable(any());
    357 
    358         reset(cb);
    359         layerDrawable.setCallback(null);
    360         layerDrawable.invalidateDrawable(null);
    361         verify(cb, never()).invalidateDrawable(any());
    362     }
    363 
    364     @Test
    365     public void testScheduleDrawable() {
    366         Drawable[] array = new Drawable[0];
    367         LayerDrawable layerDrawable = new LayerDrawable(array);
    368 
    369         Drawable.Callback cb = mock(Drawable.Callback.class);
    370         layerDrawable.setCallback(cb);
    371         layerDrawable.scheduleDrawable(null, null, 0);
    372         verify(cb, times(1)).scheduleDrawable(any(), any(), anyLong());
    373 
    374         reset(cb);
    375         layerDrawable.scheduleDrawable(mBitmapDrawable, () -> {}, 1000L);
    376         verify(cb, times(1)).scheduleDrawable(any(), any(), anyLong());
    377 
    378         reset(cb);
    379         layerDrawable.setCallback(null);
    380         layerDrawable.scheduleDrawable(null, null, 0);
    381         verify(cb, never()).scheduleDrawable(any(), any(), anyLong());
    382     }
    383 
    384     @Test
    385     public void testUnscheduleDrawable() {
    386         Drawable[] array = new Drawable[0];
    387         LayerDrawable layerDrawable = new LayerDrawable(array);
    388 
    389         Drawable.Callback cb = mock(Drawable.Callback.class);
    390         layerDrawable.setCallback(cb);
    391         layerDrawable.unscheduleDrawable(null, null);
    392         verify(cb, times(1)).unscheduleDrawable(any(), any());
    393 
    394         reset(cb);
    395         layerDrawable.unscheduleDrawable(mBitmapDrawable, () -> {});
    396         verify(cb, times(1)).unscheduleDrawable(any(), any());
    397 
    398         reset(cb);
    399         layerDrawable.setCallback(null);
    400         layerDrawable.unscheduleDrawable(null, null);
    401         verify(cb, never()).unscheduleDrawable(any(), any());
    402     }
    403 
    404     @Test
    405     public void testDraw() {
    406         Drawable mockDrawable1 = spy(new ColorDrawable(Color.BLUE));
    407         Drawable mockDrawable2 = spy(new ColorDrawable(Color.RED));
    408         Drawable[] array = new Drawable[] { mockDrawable1, mockDrawable2 };
    409         LayerDrawable layerDrawable = new LayerDrawable(array);
    410 
    411         // this method will call each child's draw().
    412         layerDrawable.draw(new Canvas());
    413         verify(mockDrawable1, times(1)).draw(any());
    414         verify(mockDrawable2, times(1)).draw(any());
    415 
    416         reset(mockDrawable1);
    417         reset(mockDrawable2);
    418         doNothing().when(mockDrawable1).draw(any());
    419         doNothing().when(mockDrawable2).draw(any());
    420         layerDrawable.draw(null);
    421         verify(mockDrawable1, times(1)).draw(any());
    422         verify(mockDrawable2, times(1)).draw(any());
    423     }
    424 
    425     @Test
    426     public void testGetChangingConfigurations() {
    427         final int superConfig = 1;
    428         final int gradientDrawableConfig = 2;
    429         final int colorDrawableConfig = 4;
    430         final int childConfig = gradientDrawableConfig | colorDrawableConfig;
    431 
    432         mBitmapDrawable.setChangingConfigurations(gradientDrawableConfig);
    433         mColorDrawable.setChangingConfigurations(colorDrawableConfig);
    434         Drawable[] array = new Drawable[] { mBitmapDrawable, mColorDrawable };
    435         LayerDrawable layerDrawable = new LayerDrawable(array);
    436 
    437         assertEquals(childConfig, layerDrawable.getChangingConfigurations());
    438 
    439         layerDrawable.setChangingConfigurations(superConfig);
    440         assertEquals(superConfig | childConfig, layerDrawable.getChangingConfigurations());
    441     }
    442 
    443     @Test
    444     public void testAccessPadding() {
    445         Drawable[] array = new Drawable[] { new ShapeDrawable(), new ShapeDrawable() };
    446         LayerDrawable layerDrawable = new LayerDrawable(array);
    447 
    448         Rect rc = new Rect();
    449         layerDrawable.getPadding(rc);
    450         assertEquals(0, rc.left);
    451         assertEquals(0, rc.top);
    452         assertEquals(0, rc.right);
    453         assertEquals(0, rc.bottom);
    454 
    455         Rect padding0 = new Rect(10, 20, 30, 40);
    456         ((ShapeDrawable) layerDrawable.getDrawable(0)).setPadding(padding0);
    457         layerDrawable.getPadding(rc);
    458         assertEquals(padding0.left, rc.left);
    459         assertEquals(padding0.top, rc.top);
    460         assertEquals(padding0.right, rc.right);
    461         assertEquals(padding0.bottom, rc.bottom);
    462 
    463         Rect padding1 = new Rect(20, 30, 40, 50);
    464         ((ShapeDrawable) layerDrawable.getDrawable(1)).setPadding(padding1);
    465         layerDrawable.getPadding(rc);
    466         assertEquals(padding0.left + padding1.left, rc.left);
    467         assertEquals(padding0.top + padding1.top, rc.top);
    468         assertEquals(padding0.right + padding1.right, rc.right);
    469         assertEquals(padding0.bottom + padding1.bottom, rc.bottom);
    470     }
    471 
    472     @Test
    473     public void testAccessPaddingMode() {
    474         Rect padding = new Rect();
    475         Drawable dr0 = new IntrinsicSizeDrawable(20, 30, new Rect(1, 2, 3, 4));
    476         Drawable dr1 = new IntrinsicSizeDrawable(30, 40, new Rect(9, 8, 7, 6));
    477         LayerDrawable layerDrawable = new LayerDrawable(new Drawable[] { dr0, dr1 });
    478 
    479         assertEquals("Default padding mode is NEST",
    480                 LayerDrawable.PADDING_MODE_NEST, layerDrawable.getPaddingMode());
    481         assertEquals(34, layerDrawable.getIntrinsicWidth());
    482         assertEquals(46, layerDrawable.getIntrinsicHeight());
    483         assertTrue(layerDrawable.getPadding(padding));
    484         assertEquals(new Rect(10, 10, 10, 10), padding);
    485 
    486         layerDrawable.setPaddingMode(LayerDrawable.PADDING_MODE_STACK);
    487         assertEquals(LayerDrawable.PADDING_MODE_STACK, layerDrawable.getPaddingMode());
    488         assertEquals(30, layerDrawable.getIntrinsicWidth());
    489         assertEquals(40, layerDrawable.getIntrinsicHeight());
    490         assertTrue(layerDrawable.getPadding(padding));
    491         assertEquals(new Rect(9, 8, 7, 6), padding);
    492     }
    493 
    494     @Test
    495     public void testSetVisible() {
    496         Drawable[] array = new Drawable[] { mBitmapDrawable, mColorDrawable };
    497         LayerDrawable layerDrawable = new LayerDrawable(array);
    498 
    499         assertTrue(layerDrawable.setVisible(false, true));
    500         assertFalse(layerDrawable.isVisible());
    501         assertFalse(layerDrawable.getDrawable(0).isVisible());
    502         assertFalse(layerDrawable.getDrawable(1).isVisible());
    503 
    504         assertFalse(layerDrawable.setVisible(false, false));
    505 
    506         assertTrue(layerDrawable.setVisible(true, false));
    507         assertTrue(layerDrawable.isVisible());
    508         assertTrue(layerDrawable.getDrawable(0).isVisible());
    509         assertTrue(layerDrawable.getDrawable(1).isVisible());
    510     }
    511 
    512     @Test
    513     public void testSetDither() {
    514         Drawable mockDrawable1 = spy(new ColorDrawable(Color.BLUE));
    515         Drawable mockDrawable2 = spy(new ColorDrawable(Color.BLACK));
    516         Drawable[] array = new Drawable[] { mockDrawable1, mockDrawable2 };
    517         LayerDrawable layerDrawable = new LayerDrawable(array);
    518 
    519         layerDrawable.setDither(true);
    520         verify(mockDrawable1, times(1)).setDither(anyBoolean());
    521         verify(mockDrawable2, times(1)).setDither(anyBoolean());
    522 
    523         reset(mockDrawable1);
    524         reset(mockDrawable2);
    525         layerDrawable.setDither(false);
    526         verify(mockDrawable1, times(1)).setDither(anyBoolean());
    527         verify(mockDrawable2, times(1)).setDither(anyBoolean());
    528     }
    529 
    530     @Test
    531     public void testSetHotspotBounds() {
    532         Rect bounds = new Rect(10, 15, 100, 150);
    533         Drawable mockDrawable1 = new ColorDrawable(Color.BLUE);
    534         Drawable mockDrawable2 = new ColorDrawable(Color.GREEN);
    535         Drawable[] array = new Drawable[] { mockDrawable1, mockDrawable2 };
    536         LayerDrawable layerDrawable = new LayerDrawable(array);
    537 
    538         layerDrawable.setHotspotBounds(bounds.left, bounds.top, bounds.right, bounds.bottom);
    539         Rect outRect = new Rect();
    540         layerDrawable.getHotspotBounds(outRect);
    541         assertTrue(bounds.equals(outRect));
    542     }
    543 
    544     @Test
    545     public void testGetHotspotBounds() {
    546         Rect bounds = new Rect(10, 15, 100, 150);
    547         Drawable mockDrawable1 = new ColorDrawable(Color.BLUE);
    548         Drawable mockDrawable2 = new ColorDrawable(Color.GREEN);
    549         Drawable[] array = new Drawable[] { mockDrawable1, mockDrawable2 };
    550         LayerDrawable layerDrawable = new LayerDrawable(array);
    551 
    552         layerDrawable.setHotspotBounds(bounds.left, bounds.top, bounds.right, bounds.bottom);
    553         Rect outRect = new Rect();
    554         layerDrawable.getHotspotBounds(outRect);
    555         assertTrue(bounds.equals(outRect));
    556     }
    557 
    558     @Test
    559     public void testSetAlpha() {
    560         Drawable mockDrawable1 = spy(new ColorDrawable(Color.BLUE));
    561         Drawable mockDrawable2 = spy(new ColorDrawable(Color.BLACK));
    562         Drawable[] array = new Drawable[] { mockDrawable1, mockDrawable2 };
    563         LayerDrawable layerDrawable = new LayerDrawable(array);
    564 
    565         layerDrawable.setAlpha(0);
    566         verify(mockDrawable1, times(1)).setAlpha(anyInt());
    567         verify(mockDrawable2, times(1)).setAlpha(anyInt());
    568 
    569         reset(mockDrawable1);
    570         reset(mockDrawable2);
    571         layerDrawable.setAlpha(Integer.MAX_VALUE);
    572         verify(mockDrawable1, times(1)).setAlpha(anyInt());
    573         verify(mockDrawable2, times(1)).setAlpha(anyInt());
    574     }
    575 
    576     @Test
    577     public void testSetColorFilter() {
    578         Drawable mockDrawable1 = spy(new ColorDrawable(Color.BLUE));
    579         Drawable mockDrawable2 = spy(new ColorDrawable(Color.BLACK));
    580         Drawable[] array = new Drawable[] { mockDrawable1, mockDrawable2 };
    581         LayerDrawable layerDrawable = new LayerDrawable(array);
    582 
    583         layerDrawable.setColorFilter(new ColorFilter());
    584         verify(mockDrawable1, times(1)).setColorFilter(any());
    585         verify(mockDrawable2, times(1)).setColorFilter(any());
    586 
    587         reset(mockDrawable1);
    588         reset(mockDrawable2);
    589         layerDrawable.setColorFilter(null);
    590         verify(mockDrawable1, times(1)).setColorFilter(any());
    591         verify(mockDrawable2, times(1)).setColorFilter(any());
    592     }
    593 
    594     @Test
    595     public void testAccessOpacity() {
    596         Drawable[] array = new Drawable[0];
    597         LayerDrawable layerDrawable = new LayerDrawable(array);
    598         assertEquals(PixelFormat.TRANSPARENT, layerDrawable.getOpacity());
    599 
    600         Drawable mockDrawable1 = spy(new ColorDrawable(Color.BLUE));
    601         Drawable mockDrawable2 = spy(new ColorDrawable(Color.GREEN));
    602         array = new Drawable[] { mockDrawable1, mockDrawable2 };
    603         layerDrawable = new LayerDrawable(array);
    604         assertEquals(PixelFormat.OPAQUE, layerDrawable.getOpacity());
    605 
    606         layerDrawable = new LayerDrawable(array);
    607         doReturn(PixelFormat.OPAQUE).when(mockDrawable1).getOpacity();
    608         doReturn(PixelFormat.TRANSPARENT).when(mockDrawable2).getOpacity();
    609         assertEquals(PixelFormat.TRANSPARENT, layerDrawable.getOpacity());
    610 
    611         layerDrawable = new LayerDrawable(array);
    612         doReturn(PixelFormat.TRANSLUCENT).when(mockDrawable1).getOpacity();
    613         doReturn(PixelFormat.TRANSPARENT).when(mockDrawable2).getOpacity();
    614         assertEquals(PixelFormat.TRANSLUCENT, layerDrawable.getOpacity());
    615 
    616         layerDrawable = new LayerDrawable(array);
    617         doReturn(PixelFormat.TRANSLUCENT).when(mockDrawable1).getOpacity();
    618         doReturn(PixelFormat.UNKNOWN).when(mockDrawable2).getOpacity();
    619         assertEquals(PixelFormat.UNKNOWN, layerDrawable.getOpacity());
    620 
    621         layerDrawable = new LayerDrawable(array);
    622         layerDrawable.setOpacity(PixelFormat.OPAQUE);
    623         doReturn(PixelFormat.TRANSLUCENT).when(mockDrawable1).getOpacity();
    624         doReturn(PixelFormat.UNKNOWN).when(mockDrawable2).getOpacity();
    625         assertEquals(PixelFormat.OPAQUE, layerDrawable.getOpacity());
    626 
    627     }
    628 
    629     @Test
    630     public void testIsStateful() {
    631         Drawable[] array = new Drawable[0];
    632         LayerDrawable layerDrawable = new LayerDrawable(array);
    633         assertFalse(layerDrawable.isStateful());
    634 
    635         array = new Drawable[] { new GradientDrawable(), new MockDrawable(false) };
    636         layerDrawable = new LayerDrawable(array);
    637         assertFalse(layerDrawable.isStateful());
    638 
    639         array = new Drawable[] { new GradientDrawable(), new StateListDrawable() };
    640         layerDrawable = new LayerDrawable(array);
    641         assertTrue(layerDrawable.isStateful());
    642     }
    643 
    644     @Test
    645     public void testSetState() {
    646         MockDrawable mockDrawable1 = new MockDrawable(true);
    647         MockDrawable mockDrawable2 = new MockDrawable(true);
    648         Drawable[] array = new Drawable[] { mockDrawable1, mockDrawable2 };
    649         LayerDrawable layerDrawable = new LayerDrawable(array);
    650 
    651         // Call onStateChange() without actually changing the state.
    652         assertFalse(layerDrawable.setState(StateSet.WILD_CARD));
    653         assertFalse(mockDrawable1.hasCalledSetState());
    654         assertFalse(mockDrawable2.hasCalledSetState());
    655         assertFalse(mockDrawable1.hasCalledOnBoundsChange());
    656         assertFalse(mockDrawable2.hasCalledOnBoundsChange());
    657 
    658         // Call onStateChange() to change the state from WILD_CARD to null.
    659         // This alters the padding of both layers, which forces a bounds change
    660         // for the second layer due to the default "nest" padding mode.
    661         mockDrawable1.reset();
    662         mockDrawable2.reset();
    663         assertTrue(layerDrawable.setState(null));
    664         assertTrue(mockDrawable1.hasCalledSetState());
    665         assertTrue(mockDrawable2.hasCalledSetState());
    666         assertFalse(mockDrawable1.hasCalledOnBoundsChange());
    667         assertTrue(mockDrawable2.hasCalledOnBoundsChange());
    668 
    669         // Call onStateChange() to change the state from null to valid state
    670         // set. This alters the padding of both layers, which forces a bounds
    671         // change for the second layer due to the default "nest" padding mode.
    672         mockDrawable1.reset();
    673         mockDrawable2.reset();
    674         assertTrue(layerDrawable.setState(new int[]{
    675                 android.R.attr.state_checked, android.R.attr.state_empty}));
    676         assertTrue(mockDrawable1.hasCalledSetState());
    677         assertTrue(mockDrawable2.hasCalledSetState());
    678         assertFalse(mockDrawable1.hasCalledOnBoundsChange());
    679         assertTrue(mockDrawable2.hasCalledOnBoundsChange());
    680     }
    681 
    682     @Test
    683     public void testJumpToCurrentState() {
    684         Drawable mockDrawable1 = spy(new ColorDrawable(Color.BLUE));
    685         Drawable mockDrawable2 = spy(new ColorDrawable(Color.BLACK));
    686         Drawable[] array = new Drawable[] { mockDrawable1, mockDrawable2 };
    687         LayerDrawable layerDrawable = new LayerDrawable(array);
    688 
    689         verify(mockDrawable1, never()).jumpToCurrentState();
    690         verify(mockDrawable2, never()).jumpToCurrentState();
    691 
    692         layerDrawable.jumpToCurrentState();
    693 
    694         verify(mockDrawable1, times(1)).jumpToCurrentState();
    695         verify(mockDrawable2, times(1)).jumpToCurrentState();
    696     }
    697 
    698     @Test
    699     public void testSetLevel() {
    700         MockDrawable mockDrawable1 = new MockDrawable();
    701         MockDrawable mockDrawable2 = new MockDrawable();
    702         Drawable[] array = new Drawable[] { mockDrawable1, mockDrawable2 };
    703         LayerDrawable layerDrawable = new LayerDrawable(array);
    704 
    705         // Call onLevelChange() without actually changing the level.
    706         assertFalse(layerDrawable.setLevel(0));
    707         assertFalse(mockDrawable1.hasCalledOnLevelChange());
    708         assertFalse(mockDrawable2.hasCalledOnLevelChange());
    709         assertFalse(mockDrawable1.hasCalledOnBoundsChange());
    710         assertFalse(mockDrawable2.hasCalledOnBoundsChange());
    711 
    712         // Call onLevelChange() to change the level from 0 to MAX_VALUE. This
    713         // alters the padding of both layers, which forces a bounds change for
    714         // the second layer due to the default "nest" padding mode.
    715         mockDrawable1.reset();
    716         mockDrawable2.reset();
    717         assertTrue(layerDrawable.setLevel(Integer.MAX_VALUE));
    718         assertTrue(mockDrawable1.hasCalledOnLevelChange());
    719         assertTrue(mockDrawable2.hasCalledOnLevelChange());
    720         assertFalse(mockDrawable1.hasCalledOnBoundsChange());
    721         assertTrue(mockDrawable2.hasCalledOnBoundsChange());
    722 
    723         // Call onLevelChange() to change the level from MAX_VALUE to
    724         // MIN_VALUE. This alters the padding of both layers, which forces a
    725         // bounds change for the second layer due to the default "nest" padding
    726         // mode.
    727         mockDrawable1.reset();
    728         mockDrawable2.reset();
    729         assertTrue(layerDrawable.setLevel(Integer.MIN_VALUE));
    730         assertTrue(mockDrawable1.hasCalledOnLevelChange());
    731         assertTrue(mockDrawable2.hasCalledOnLevelChange());
    732         assertFalse(mockDrawable1.hasCalledOnBoundsChange());
    733         assertTrue(mockDrawable2.hasCalledOnBoundsChange());
    734     }
    735 
    736     @Test
    737     public void testSetBounds() {
    738         Drawable mockDrawable1 = spy(new ColorDrawable(Color.GREEN));
    739         Drawable mockDrawable2 = spy(new ColorDrawable(Color.BLUE));
    740         Drawable[] array = new Drawable[] { mockDrawable1, mockDrawable2 };
    741         LayerDrawable layerDrawable = new LayerDrawable(array);
    742 
    743         Rect inset1 = new Rect(1, 2, 3, 4);
    744         Rect inset2 = new Rect(2, 4, 6, 7);
    745         Rect padding1 = new Rect(11, 22, 33, 44);
    746         Rect padding2 = new Rect(21, 32, 43, 54);
    747         layerDrawable.setLayerInset(0, inset1.left, inset1.top, inset1.right, inset1.bottom);
    748         layerDrawable.setLayerInset(1, inset2.left, inset2.top, inset2.right, inset2.bottom);
    749         doAnswer(invocation -> {
    750             Rect target = (Rect) invocation.getArguments() [0];
    751             target.set(padding1);
    752             return true;
    753         }).when(mockDrawable1).getPadding(any());
    754         doAnswer(invocation -> {
    755             Rect target = (Rect) invocation.getArguments() [0];
    756             target.set(padding2);
    757             return true;
    758         }).when(mockDrawable2).getPadding(any());
    759         layerDrawable.getPadding(new Rect());
    760 
    761         // the children's bounds before call onBoundsChange
    762         assertEquals(0, mockDrawable1.getBounds().left);
    763         assertEquals(0, mockDrawable1.getBounds().top);
    764         assertEquals(0, mockDrawable1.getBounds().right);
    765         assertEquals(0, mockDrawable1.getBounds().bottom);
    766         assertEquals(0, mockDrawable2.getBounds().left);
    767         assertEquals(0, mockDrawable2.getBounds().top);
    768         assertEquals(0, mockDrawable2.getBounds().right);
    769         assertEquals(0, mockDrawable2.getBounds().bottom);
    770 
    771         Rect bounds = new Rect(10, 20, 30, 40);
    772         layerDrawable.setBounds(bounds);
    773 
    774         // all children's bounds will be changed after call onBoundsChange
    775         assertEquals(bounds.left + inset1.left, mockDrawable1.getBounds().left);
    776         assertEquals(bounds.top + inset1.top, mockDrawable1.getBounds().top);
    777         assertEquals(bounds.right - inset1.right, mockDrawable1.getBounds().right);
    778         assertEquals(bounds.bottom - inset1.bottom, mockDrawable1.getBounds().bottom);
    779         assertEquals(bounds.left + inset2.left + padding1.left, mockDrawable2.getBounds().left);
    780         assertEquals(bounds.top + inset2.top + padding1.top, mockDrawable2.getBounds().top);
    781         assertEquals(bounds.right - inset2.right - padding1.right,
    782                 mockDrawable2.getBounds().right);
    783         assertEquals(bounds.bottom - inset2.bottom - padding1.bottom,
    784                 mockDrawable2.getBounds().bottom);
    785     }
    786 
    787     @Test
    788     public void testGetIntrinsicWidth() {
    789         Drawable largeMockDrawable = spy(new ColorDrawable(Color.YELLOW));
    790         doReturn(10).when(largeMockDrawable).getIntrinsicWidth();
    791         doReturn(10).when(largeMockDrawable).getIntrinsicHeight();
    792         Drawable smallMockDrawable = spy(new ColorDrawable(Color.MAGENTA));
    793         doReturn(1).when(smallMockDrawable).getIntrinsicWidth();
    794         doReturn(1).when(smallMockDrawable).getIntrinsicHeight();
    795 
    796         Drawable[] array = new Drawable[] { largeMockDrawable, smallMockDrawable };
    797         LayerDrawable layerDrawable = new LayerDrawable(array);
    798         assertEquals(largeMockDrawable.getIntrinsicWidth(), layerDrawable.getIntrinsicWidth());
    799 
    800         Rect inset1 = new Rect(1, 2, 3, 4);
    801         Rect inset2 = new Rect(2, 4, 6, 7);
    802         final Rect padding1 = new Rect(11, 22, 33, 44);
    803         final Rect padding2 = new Rect(21, 32, 43, 54);
    804         layerDrawable.setLayerInset(0, inset1.left, inset1.top, inset1.right, inset1.bottom);
    805         layerDrawable.setLayerInset(1, inset2.left, inset2.top, inset2.right, inset2.bottom);
    806 
    807         doAnswer(invocation -> {
    808             Rect target = (Rect) invocation.getArguments() [0];
    809             target.set(padding1);
    810             return true;
    811         }).when(largeMockDrawable).getPadding(any());
    812         doAnswer(invocation -> {
    813             Rect target = (Rect) invocation.getArguments() [0];
    814             target.set(padding2);
    815             return true;
    816         }).when(smallMockDrawable).getPadding(any());
    817 
    818         layerDrawable.getPadding(new Rect());
    819         assertEquals(smallMockDrawable.getIntrinsicWidth() + inset2.left
    820                 + inset2.right + padding1.left + padding1.right,
    821                 layerDrawable.getIntrinsicWidth());
    822 
    823         inset1 = new Rect(inset2.left + padding1.left + 1, inset2.top + padding1.top + 1,
    824                 inset2.right + padding1.right + 1, inset2.bottom + padding1.bottom + 1);
    825         layerDrawable.setLayerInset(0, inset1.left, inset1.top, inset1.right, inset1.bottom);
    826         assertEquals(largeMockDrawable.getIntrinsicWidth() + inset1.left + inset1.right,
    827                 layerDrawable.getIntrinsicWidth());
    828     }
    829 
    830     @Test
    831     public void testGetIntrinsicHeight() {
    832         Drawable largeMockDrawable = spy(new ColorDrawable(Color.CYAN));
    833         doReturn(10).when(largeMockDrawable).getIntrinsicWidth();
    834         doReturn(10).when(largeMockDrawable).getIntrinsicHeight();
    835         Drawable smallMockDrawable = spy(new ColorDrawable(Color.DKGRAY));
    836         doReturn(1).when(smallMockDrawable).getIntrinsicWidth();
    837         doReturn(1).when(smallMockDrawable).getIntrinsicHeight();
    838 
    839         Drawable[] array = new Drawable[] { largeMockDrawable, smallMockDrawable };
    840         LayerDrawable layerDrawable = new LayerDrawable(array);
    841         assertEquals(largeMockDrawable.getIntrinsicHeight(), layerDrawable.getIntrinsicHeight());
    842 
    843         Rect inset1 = new Rect(1, 2, 3, 4);
    844         Rect inset2 = new Rect(2, 4, 6, 7);
    845         final Rect padding1 = new Rect(11, 22, 33, 44);
    846         final Rect padding2 = new Rect(21, 32, 43, 54);
    847         layerDrawable.setLayerInset(0, inset1.left, inset1.top, inset1.right, inset1.bottom);
    848         layerDrawable.setLayerInset(1, inset2.left, inset2.top, inset2.right, inset2.bottom);
    849 
    850         doAnswer(invocation -> {
    851             Rect target = (Rect) invocation.getArguments() [0];
    852             target.set(padding1);
    853             return true;
    854         }).when(largeMockDrawable).getPadding(any());
    855         doAnswer(invocation -> {
    856             Rect target = (Rect) invocation.getArguments() [0];
    857             target.set(padding2);
    858             return true;
    859         }).when(smallMockDrawable).getPadding(any());
    860 
    861         layerDrawable.getPadding(new Rect());
    862         assertEquals(smallMockDrawable.getIntrinsicHeight() + inset2.top
    863                 + inset2.bottom + padding1.top + padding1.bottom,
    864                 layerDrawable.getIntrinsicHeight());
    865 
    866         inset1 = new Rect(inset2.left + padding1.left + 1, inset2.top + padding1.top + 1,
    867                 inset2.right + padding1.right + 1, inset2.bottom + padding1.bottom + 1);
    868         layerDrawable.setLayerInset(0, inset1.left, inset1.top, inset1.right, inset1.bottom);
    869         assertEquals(largeMockDrawable.getIntrinsicHeight() + inset1.top + inset1.bottom,
    870                 layerDrawable.getIntrinsicHeight());
    871     }
    872 
    873     @Test
    874     public void testGetConstantState() {
    875         Drawable[] array = new Drawable[] { mBitmapDrawable, mColorDrawable };
    876         LayerDrawable layerDrawable = new LayerDrawable(array);
    877         ConstantState constantState = layerDrawable.getConstantState();
    878         assertNotNull(constantState);
    879         assertEquals(0, constantState.getChangingConfigurations());
    880 
    881         layerDrawable.setChangingConfigurations(1);
    882         constantState = layerDrawable.getConstantState();
    883         assertNotNull(constantState);
    884         assertEquals(1, constantState.getChangingConfigurations());
    885     }
    886 
    887     @Test
    888     public void testAddLayer() {
    889         Drawable[] array = new Drawable[] { new GradientDrawable(), new ColorDrawable(Color.BLUE) };
    890         LayerDrawable layerDrawable = new LayerDrawable(array);
    891         GradientDrawable newDrawable = new GradientDrawable();
    892         int index = layerDrawable.addLayer(newDrawable);
    893 
    894         final int numLayers = layerDrawable.getNumberOfLayers();
    895         assertEquals(index, numLayers - 1);
    896         assertEquals(newDrawable, layerDrawable.getDrawable(index));
    897     }
    898 
    899     @Test
    900     public void testGetDrawable() {
    901         Drawable[] array = new Drawable[] { mBitmapDrawable, mColorDrawable };
    902         LayerDrawable layerDrawable = new LayerDrawable(array);
    903 
    904         assertEquals(array[0], layerDrawable.getDrawable(0));
    905         assertEquals(array[1], layerDrawable.getDrawable(1));
    906         try {
    907             assertEquals(null, layerDrawable.getDrawable(2));
    908             fail("Should throw IndexOutOfBoundsException");
    909         } catch (IndexOutOfBoundsException e) {
    910         }
    911     }
    912 
    913     @Test
    914     public void testFindIndexByLayerId() {
    915         Drawable[] array = new Drawable[] { mBitmapDrawable, mColorDrawable };
    916         LayerDrawable layerDrawable = new LayerDrawable(array);
    917 
    918         layerDrawable.setId(0, 10);
    919         layerDrawable.setId(1, 20);
    920 
    921         assertEquals(0, layerDrawable.findIndexByLayerId(10));
    922         assertEquals(1, layerDrawable.findIndexByLayerId(20));
    923         assertEquals(-1, layerDrawable.findIndexByLayerId(30));
    924     }
    925 
    926     @Test
    927     public void testSetDrawable() {
    928         Drawable[] array = new Drawable[] { mBitmapDrawable, mColorDrawable };
    929         LayerDrawable layerDrawable = new LayerDrawable(array);
    930         BitmapDrawable newBitmapDrawable = new BitmapDrawable();
    931         ColorDrawable newColorDrawable = new ColorDrawable(Color.GREEN);
    932         layerDrawable.setDrawable(0, newColorDrawable);
    933         layerDrawable.setDrawable(1, newBitmapDrawable);
    934 
    935         final int numLayers = layerDrawable.getNumberOfLayers();
    936         assertEquals(2, numLayers);
    937         assertEquals(newColorDrawable, layerDrawable.getDrawable(0));
    938         assertEquals(newBitmapDrawable, layerDrawable.getDrawable(1));
    939         try {
    940             assertEquals(null, layerDrawable.getDrawable(2));
    941             fail("Should throw IndexOutOfBoundsException");
    942         } catch (IndexOutOfBoundsException e) {
    943         }
    944     }
    945 
    946     @Test
    947     public void testGetLeftPadding() {
    948         Drawable[] array = new Drawable[] { mBitmapDrawable };
    949         LayerDrawable layerDrawable = new LayerDrawable(array);
    950         layerDrawable.setPadding(10, 11, 20, 21);
    951 
    952         assertEquals(10, layerDrawable.getLeftPadding());
    953     }
    954 
    955     @Test
    956     public void testGetTopPadding() {
    957         Drawable[] array = new Drawable[] { mBitmapDrawable };
    958         LayerDrawable layerDrawable = new LayerDrawable(array);
    959         layerDrawable.setPadding(10, 11, 20, 21);
    960 
    961         assertEquals(11, layerDrawable.getTopPadding());
    962     }
    963 
    964     @Test
    965     public void testGetRightPadding() {
    966         Drawable[] array = new Drawable[] { mBitmapDrawable };
    967         LayerDrawable layerDrawable = new LayerDrawable(array);
    968         layerDrawable.setPadding(10, 11, 20, 21);
    969 
    970         assertEquals(20, layerDrawable.getRightPadding());
    971     }
    972 
    973     @Test
    974     public void testGetBottomPadding() {
    975         Drawable[] array = new Drawable[] { mBitmapDrawable };
    976         LayerDrawable layerDrawable = new LayerDrawable(array);
    977         layerDrawable.setPadding(10, 11, 20, 21);
    978 
    979         assertEquals(21, layerDrawable.getBottomPadding());
    980     }
    981 
    982     @Test
    983     public void testGetStartPadding() {
    984         Drawable[] array = new Drawable[] { mBitmapDrawable };
    985         LayerDrawable layerDrawable = new LayerDrawable(array);
    986         layerDrawable.setPadding(10, 11, 20, 21);
    987 
    988         assertEquals(-1, layerDrawable.getStartPadding());
    989         layerDrawable.setPaddingRelative(10, 11, 20, 21);
    990         assertEquals(10, layerDrawable.getStartPadding());
    991     }
    992 
    993     @Test
    994     public void testGetEndPadding() {
    995         Drawable[] array = new Drawable[] { mBitmapDrawable };
    996         LayerDrawable layerDrawable = new LayerDrawable(array);
    997         layerDrawable.setPadding(10, 11, 20, 21);
    998 
    999         assertEquals(-1, layerDrawable.getEndPadding());
   1000         layerDrawable.setPaddingRelative(10, 11, 20, 21);
   1001         assertEquals(20, layerDrawable.getEndPadding());
   1002     }
   1003 
   1004     @Test
   1005     public void testSetPadding() {
   1006         Drawable[] array = new Drawable[] { mBitmapDrawable };
   1007         LayerDrawable layerDrawable = new LayerDrawable(array);
   1008         layerDrawable.setPadding(10, 11, 20, 21);
   1009 
   1010         assertEquals(10, layerDrawable.getLeftPadding());
   1011         assertEquals(11, layerDrawable.getTopPadding());
   1012         assertEquals(20, layerDrawable.getRightPadding());
   1013         assertEquals(21, layerDrawable.getBottomPadding());
   1014         assertEquals(-1, layerDrawable.getStartPadding());
   1015         assertEquals(-1, layerDrawable.getEndPadding());
   1016     }
   1017 
   1018     @Test
   1019     public void testSetPaddingRelative() {
   1020         Drawable[] array = new Drawable[] { mBitmapDrawable };
   1021         LayerDrawable layerDrawable = new LayerDrawable(array);
   1022         layerDrawable.setPaddingRelative(10, 11, 20, 21);
   1023 
   1024         assertEquals(10, layerDrawable.getStartPadding());
   1025         assertEquals(11, layerDrawable.getTopPadding());
   1026         assertEquals(20, layerDrawable.getEndPadding());
   1027         assertEquals(21, layerDrawable.getBottomPadding());
   1028         assertEquals(-1, layerDrawable.getLeftPadding());
   1029         assertEquals(-1, layerDrawable.getRightPadding());
   1030     }
   1031 
   1032     @Test
   1033     public void testSetLayerGravity() {
   1034         Drawable[] array = new Drawable[] { mBitmapDrawable, mColorDrawable };
   1035         LayerDrawable layerDrawable = new LayerDrawable(array);
   1036 
   1037         layerDrawable.setLayerGravity(0, Gravity.CENTER);
   1038         layerDrawable.setLayerGravity(1, Gravity.NO_GRAVITY);
   1039 
   1040         try {
   1041             layerDrawable.setLayerGravity(2, Gravity.TOP);
   1042             fail("Should throw ArrayIndexOutOfBoundsException");
   1043         } catch (ArrayIndexOutOfBoundsException e) {
   1044         }
   1045         assertEquals(Gravity.CENTER, layerDrawable.getLayerGravity(0));
   1046         assertEquals(Gravity.NO_GRAVITY, layerDrawable.getLayerGravity(1));
   1047     }
   1048 
   1049     @Test
   1050     public void testGetLayerGravity() {
   1051         Drawable[] array = new Drawable[] { mBitmapDrawable, mColorDrawable };
   1052         LayerDrawable layerDrawable = new LayerDrawable(array);
   1053 
   1054         layerDrawable.setLayerGravity(0, Gravity.CENTER);
   1055         layerDrawable.setLayerGravity(1, Gravity.NO_GRAVITY);
   1056 
   1057         assertEquals(Gravity.CENTER, layerDrawable.getLayerGravity(0));
   1058         assertEquals(Gravity.NO_GRAVITY, layerDrawable.getLayerGravity(1));
   1059         try {
   1060             layerDrawable.getLayerGravity(2);
   1061             fail("Should throw ArrayIndexOutOfBoundsException");
   1062         } catch (ArrayIndexOutOfBoundsException e) {
   1063         }
   1064     }
   1065 
   1066     @Test
   1067     public void testSetLayerWidth() {
   1068         Drawable[] array = new Drawable[] { mBitmapDrawable, mColorDrawable };
   1069         LayerDrawable layerDrawable = new LayerDrawable(array);
   1070 
   1071         layerDrawable.setLayerWidth(0, 100);
   1072         layerDrawable.setLayerWidth(1, 200);
   1073 
   1074         try {
   1075             layerDrawable.setLayerWidth(2, 300);
   1076             fail("Should throw ArrayIndexOutOfBoundsException");
   1077         } catch (ArrayIndexOutOfBoundsException e) {
   1078         }
   1079         assertEquals(100, layerDrawable.getLayerWidth(0));
   1080         assertEquals(200, layerDrawable.getLayerWidth(1));
   1081     }
   1082 
   1083     @Test
   1084     public void testGetLayerWidth() {
   1085         Drawable[] array = new Drawable[] { mBitmapDrawable, mColorDrawable };
   1086         LayerDrawable layerDrawable = new LayerDrawable(array);
   1087 
   1088         layerDrawable.setLayerWidth(0, 100);
   1089         layerDrawable.setLayerWidth(1, 200);
   1090 
   1091         assertEquals(100, layerDrawable.getLayerWidth(0));
   1092         assertEquals(200, layerDrawable.getLayerWidth(1));
   1093         try {
   1094             layerDrawable.getLayerWidth(2);
   1095             fail("Should throw ArrayIndexOutOfBoundsException");
   1096         } catch (ArrayIndexOutOfBoundsException e) {
   1097         }
   1098     }
   1099 
   1100     @Test
   1101     public void testSetLayerHeight() {
   1102         Drawable[] array = new Drawable[] { mBitmapDrawable, mColorDrawable };
   1103         LayerDrawable layerDrawable = new LayerDrawable(array);
   1104 
   1105         layerDrawable.setLayerHeight(0, 100);
   1106         layerDrawable.setLayerHeight(1, 200);
   1107 
   1108         try {
   1109             layerDrawable.setLayerHeight(2, 300);
   1110             fail("Should throw ArrayIndexOutOfBoundsException");
   1111         } catch (ArrayIndexOutOfBoundsException e) {
   1112         }
   1113         assertEquals(100, layerDrawable.getLayerHeight(0));
   1114         assertEquals(200, layerDrawable.getLayerHeight(1));
   1115     }
   1116 
   1117     @Test
   1118     public void testGetLayerHeight() {
   1119         Drawable[] array = new Drawable[] { mBitmapDrawable, mColorDrawable };
   1120         LayerDrawable layerDrawable = new LayerDrawable(array);
   1121 
   1122         layerDrawable.setLayerHeight(0, 100);
   1123         layerDrawable.setLayerHeight(1, 200);
   1124 
   1125         assertEquals(100, layerDrawable.getLayerHeight(0));
   1126         assertEquals(200, layerDrawable.getLayerHeight(1));
   1127         try {
   1128             layerDrawable.getLayerHeight(2);
   1129             fail("Should throw ArrayIndexOutOfBoundsException");
   1130         } catch (ArrayIndexOutOfBoundsException e) {
   1131         }
   1132     }
   1133 
   1134     @Test
   1135     public void testSetLayerSize() {
   1136         Drawable[] array = new Drawable[] { mBitmapDrawable, mColorDrawable };
   1137         LayerDrawable layerDrawable = new LayerDrawable(array);
   1138 
   1139         layerDrawable.setLayerSize(0, 100, 200);
   1140         layerDrawable.setLayerSize(1, 300, 400);
   1141 
   1142         try {
   1143             layerDrawable.setLayerSize(2, 500, 600);
   1144             fail("Should throw ArrayIndexOutOfBoundsException");
   1145         } catch (ArrayIndexOutOfBoundsException e) {
   1146         }
   1147         assertEquals(100, layerDrawable.getLayerWidth(0));
   1148         assertEquals(200, layerDrawable.getLayerHeight(0));
   1149         assertEquals(300, layerDrawable.getLayerWidth(1));
   1150         assertEquals(400, layerDrawable.getLayerHeight(1));
   1151     }
   1152 
   1153     @Test
   1154     public void testSetLayerInsetRelative() {
   1155         Drawable firstLayer = spy(new ColorDrawable(Color.YELLOW));
   1156         doReturn(10).when(firstLayer).getIntrinsicWidth();
   1157         doReturn(10).when(firstLayer).getIntrinsicHeight();
   1158         Drawable secondLayer = spy(new ColorDrawable(Color.YELLOW));
   1159         doReturn(-1).when(secondLayer).getIntrinsicWidth();
   1160         doReturn(-1).when(secondLayer).getIntrinsicHeight();
   1161 
   1162         Drawable[] array = new Drawable[] { firstLayer, secondLayer };
   1163         LayerDrawable layerDrawable = new LayerDrawable(array);
   1164 
   1165         int start = 10;
   1166         int top = 20;
   1167         int end = 30;
   1168         int bottom = 40;
   1169         layerDrawable.setLayerInsetRelative(0, start, top, end, bottom);
   1170         assertEquals(layerDrawable.getDrawable(0).getIntrinsicWidth() + start + end,
   1171                 layerDrawable.getIntrinsicWidth());
   1172         assertEquals(layerDrawable.getDrawable(0).getIntrinsicHeight() + top + bottom,
   1173                 layerDrawable.getIntrinsicHeight());
   1174         assertEquals(start, layerDrawable.getLayerInsetStart(0));
   1175         assertEquals(top, layerDrawable.getLayerInsetTop(0));
   1176         assertEquals(end, layerDrawable.getLayerInsetEnd(0));
   1177         assertEquals(bottom, layerDrawable.getLayerInsetBottom(0));
   1178         assertEquals(0, layerDrawable.getLayerInsetLeft(0));
   1179         assertEquals(0, layerDrawable.getLayerInsetRight(0));
   1180 
   1181         // The drawable at index 1 has no intrinsic width or height, so it
   1182         // won't be counted for the overall intrinsic width or height.
   1183         layerDrawable.setLayerInsetRelative(1, 10, 10, 10, 10);
   1184         assertEquals(layerDrawable.getDrawable(0).getIntrinsicWidth() + start + end,
   1185                 layerDrawable.getIntrinsicWidth());
   1186         assertEquals(layerDrawable.getDrawable(0).getIntrinsicHeight() + top + bottom,
   1187                 layerDrawable.getIntrinsicHeight());
   1188 
   1189         try {
   1190             layerDrawable.setLayerInsetRelative(-1, start, top, end, bottom);
   1191             fail("Should throw IndexOutOfBoundsException");
   1192         } catch (IndexOutOfBoundsException e) {
   1193         }
   1194     }
   1195 
   1196     @Test
   1197     public void testSetLayerInsetLeft() {
   1198         Drawable[] array = new Drawable[] { mBitmapDrawable };
   1199         LayerDrawable layerDrawable = new LayerDrawable(array);
   1200 
   1201         // set inset for layer 0
   1202         int left = 10;
   1203         int top = 20;
   1204         int right = 30;
   1205         int bottom = 40;
   1206         layerDrawable.setLayerInset(0, left, top, right, bottom);
   1207         assertEquals(layerDrawable.getDrawable(0).getIntrinsicWidth() + left + right,
   1208                 layerDrawable.getIntrinsicWidth());
   1209         left += 5;
   1210         layerDrawable.setLayerInsetLeft(0, left);
   1211         assertEquals(layerDrawable.getDrawable(0).getIntrinsicWidth() + left + right,
   1212                 layerDrawable.getIntrinsicWidth());
   1213         assertEquals(left, layerDrawable.getLayerInsetLeft(0));
   1214 
   1215         try {
   1216             layerDrawable.setLayerInsetLeft(1, left);
   1217             fail("Should throw IndexOutOfBoundsException");
   1218         } catch (IndexOutOfBoundsException e) {
   1219         }
   1220     }
   1221 
   1222     @Test
   1223     public void testGetLayerInsetLeft() {
   1224         Drawable[] array = new Drawable[] { mBitmapDrawable };
   1225         LayerDrawable layerDrawable = new LayerDrawable(array);
   1226 
   1227         // set inset for layer 0
   1228         int left = 10;
   1229         int top = 20;
   1230         int right = 30;
   1231         int bottom = 40;
   1232         layerDrawable.setLayerInset(0, left, top, right, bottom);
   1233         assertEquals(left, layerDrawable.getLayerInsetLeft(0));
   1234         left += 5;
   1235         layerDrawable.setLayerInsetLeft(0, left);
   1236         assertEquals(left, layerDrawable.getLayerInsetLeft(0));
   1237 
   1238         try {
   1239             layerDrawable.getLayerInsetLeft(1);
   1240             fail("Should throw IndexOutOfBoundsException");
   1241         } catch (IndexOutOfBoundsException e) {
   1242         }
   1243     }
   1244 
   1245     @Test
   1246     public void testSetLayerInsetTop() {
   1247         Drawable[] array = new Drawable[] { mBitmapDrawable };
   1248         LayerDrawable layerDrawable = new LayerDrawable(array);
   1249 
   1250         // set inset for layer 0
   1251         int left = 10;
   1252         int top = 20;
   1253         int right = 30;
   1254         int bottom = 40;
   1255         layerDrawable.setLayerInset(0, left, top, right, bottom);
   1256         assertEquals(layerDrawable.getDrawable(0).getIntrinsicHeight() + top + bottom,
   1257                 layerDrawable.getIntrinsicHeight());
   1258         top += 5;
   1259         layerDrawable.setLayerInsetTop(0, top);
   1260         assertEquals(layerDrawable.getDrawable(0).getIntrinsicHeight() + top + bottom,
   1261                 layerDrawable.getIntrinsicHeight());
   1262         assertEquals(top, layerDrawable.getLayerInsetTop(0));
   1263 
   1264         try {
   1265             layerDrawable.setLayerInsetTop(1, top);
   1266             fail("Should throw IndexOutOfBoundsException");
   1267         } catch (IndexOutOfBoundsException e) {
   1268         }
   1269     }
   1270 
   1271     @Test
   1272     public void testGetLayerInsetTop() {
   1273         Drawable[] array = new Drawable[] { mBitmapDrawable };
   1274         LayerDrawable layerDrawable = new LayerDrawable(array);
   1275 
   1276         // set inset for layer 0
   1277         int left = 10;
   1278         int top = 20;
   1279         int right = 30;
   1280         int bottom = 40;
   1281         layerDrawable.setLayerInset(0, left, top, right, bottom);
   1282         assertEquals(top, layerDrawable.getLayerInsetTop(0));
   1283         top += 5;
   1284         layerDrawable.setLayerInsetTop(0, top);
   1285         assertEquals(top, layerDrawable.getLayerInsetTop(0));
   1286 
   1287         try {
   1288             layerDrawable.getLayerInsetTop(1);
   1289             fail("Should throw IndexOutOfBoundsException");
   1290         } catch (IndexOutOfBoundsException e) {
   1291         }
   1292     }
   1293 
   1294     @Test
   1295     public void testSetLayerInsetRight() {
   1296         Drawable[] array = new Drawable[] { mBitmapDrawable };
   1297         LayerDrawable layerDrawable = new LayerDrawable(array);
   1298 
   1299         // set inset for layer 0
   1300         int left = 10;
   1301         int top = 20;
   1302         int right = 30;
   1303         int bottom = 40;
   1304         layerDrawable.setLayerInset(0, left, top, right, bottom);
   1305         assertEquals(layerDrawable.getDrawable(0).getIntrinsicWidth() + left + right,
   1306                 layerDrawable.getIntrinsicWidth());
   1307         right += 5;
   1308         layerDrawable.setLayerInsetRight(0, right);
   1309         assertEquals(layerDrawable.getDrawable(0).getIntrinsicWidth() + left + right,
   1310                 layerDrawable.getIntrinsicWidth());
   1311         assertEquals(right, layerDrawable.getLayerInsetRight(0));
   1312 
   1313         try {
   1314             layerDrawable.setLayerInsetRight(1, right);
   1315             fail("Should throw IndexOutOfBoundsException");
   1316         } catch (IndexOutOfBoundsException e) {
   1317         }
   1318     }
   1319 
   1320     @Test
   1321     public void testGetLayerInsetRight() {
   1322         Drawable[] array = new Drawable[] { mBitmapDrawable };
   1323         LayerDrawable layerDrawable = new LayerDrawable(array);
   1324 
   1325         // set inset for layer 0
   1326         int left = 10;
   1327         int top = 20;
   1328         int right = 30;
   1329         int bottom = 40;
   1330         layerDrawable.setLayerInset(0, left, top, right, bottom);
   1331         assertEquals(right, layerDrawable.getLayerInsetRight(0));
   1332         right += 5;
   1333         layerDrawable.setLayerInsetRight(0, right);
   1334         assertEquals(right, layerDrawable.getLayerInsetRight(0));
   1335 
   1336         try {
   1337             layerDrawable.getLayerInsetRight(1);
   1338             fail("Should throw IndexOutOfBoundsException");
   1339         } catch (IndexOutOfBoundsException e) {
   1340         }
   1341     }
   1342 
   1343     @Test
   1344     public void testSetLayerInsetBottom() {
   1345         Drawable[] array = new Drawable[] { mBitmapDrawable };
   1346         LayerDrawable layerDrawable = new LayerDrawable(array);
   1347 
   1348         // set inset for layer 0
   1349         int left = 10;
   1350         int top = 20;
   1351         int right = 30;
   1352         int bottom = 40;
   1353         layerDrawable.setLayerInset(0, left, top, right, bottom);
   1354         assertEquals(layerDrawable.getDrawable(0).getIntrinsicHeight() + top + bottom,
   1355                 layerDrawable.getIntrinsicHeight());
   1356         bottom += 5;
   1357         layerDrawable.setLayerInsetBottom(0, bottom);
   1358         assertEquals(layerDrawable.getDrawable(0).getIntrinsicHeight() + top + bottom,
   1359                 layerDrawable.getIntrinsicHeight());
   1360         assertEquals(bottom, layerDrawable.getLayerInsetBottom(0));
   1361 
   1362         try {
   1363             layerDrawable.setLayerInsetBottom(1, bottom);
   1364             fail("Should throw IndexOutOfBoundsException");
   1365         } catch (IndexOutOfBoundsException e) {
   1366         }
   1367     }
   1368 
   1369     @Test
   1370     public void testGetLayerInsetBottom() {
   1371         Drawable[] array = new Drawable[] { mBitmapDrawable };
   1372         LayerDrawable layerDrawable = new LayerDrawable(array);
   1373 
   1374         // set inset for layer 0
   1375         int left = 10;
   1376         int top = 20;
   1377         int right = 30;
   1378         int bottom = 40;
   1379         layerDrawable.setLayerInset(0, left, top, right, bottom);
   1380         assertEquals(bottom, layerDrawable.getLayerInsetBottom(0));
   1381         bottom += 5;
   1382         layerDrawable.setLayerInsetBottom(0, bottom);
   1383         assertEquals(bottom, layerDrawable.getLayerInsetBottom(0));
   1384 
   1385         try {
   1386             layerDrawable.getLayerInsetBottom(1);
   1387             fail("Should throw IndexOutOfBoundsException");
   1388         } catch (IndexOutOfBoundsException e) {
   1389         }
   1390     }
   1391 
   1392     @Test
   1393     public void testSetLayerInsetStart() {
   1394         Drawable[] array = new Drawable[] { mBitmapDrawable };
   1395         LayerDrawable layerDrawable = new LayerDrawable(array);
   1396 
   1397         // set inset for layer 0
   1398         int start = 10;
   1399         int top = 20;
   1400         int end = 30;
   1401         int bottom = 40;
   1402         layerDrawable.setLayerInsetRelative(0, start, top, end, bottom);
   1403         assertEquals(layerDrawable.getDrawable(0).getIntrinsicWidth() + start + end,
   1404                 layerDrawable.getIntrinsicWidth());
   1405         start += 5;
   1406         layerDrawable.setLayerInsetStart(0, start);
   1407         assertEquals(layerDrawable.getDrawable(0).getIntrinsicWidth() + start + end,
   1408                 layerDrawable.getIntrinsicWidth());
   1409         assertEquals(start, layerDrawable.getLayerInsetStart(0));
   1410 
   1411         try {
   1412             layerDrawable.setLayerInset(1, start, top, end, bottom);
   1413             fail("Should throw IndexOutOfBoundsException");
   1414         } catch (IndexOutOfBoundsException e) {
   1415         }
   1416     }
   1417 
   1418     @Test
   1419     public void testGetLayerInsetStart() {
   1420         Drawable[] array = new Drawable[] { mBitmapDrawable };
   1421         LayerDrawable layerDrawable = new LayerDrawable(array);
   1422 
   1423         // set inset for layer 0
   1424         int start = 10;
   1425         int top = 20;
   1426         int end = 30;
   1427         int bottom = 40;
   1428         layerDrawable.setLayerInsetRelative(0, start, top, end, bottom);
   1429         assertEquals(start, layerDrawable.getLayerInsetStart(0));
   1430         start += 5;
   1431         layerDrawable.setLayerInsetStart(0, start);
   1432         assertEquals(start, layerDrawable.getLayerInsetStart(0));
   1433 
   1434         try {
   1435             layerDrawable.getLayerInsetStart(1);
   1436             fail("Should throw IndexOutOfBoundsException");
   1437         } catch (IndexOutOfBoundsException e) {
   1438         }
   1439     }
   1440 
   1441     @Test
   1442     public void testSetLayerInsetEnd() {
   1443         Drawable[] array = new Drawable[] { mBitmapDrawable };
   1444         LayerDrawable layerDrawable = new LayerDrawable(array);
   1445 
   1446         // set inset for layer 0
   1447         int start = 10;
   1448         int top = 20;
   1449         int end = 30;
   1450         int bottom = 40;
   1451         layerDrawable.setLayerInsetRelative(0, start, top, end, bottom);
   1452         assertEquals(end, layerDrawable.getLayerInsetEnd(0));
   1453         assertEquals(layerDrawable.getDrawable(0).getIntrinsicWidth() + start + end,
   1454                 layerDrawable.getIntrinsicWidth());
   1455         end += 5;
   1456         layerDrawable.setLayerInsetEnd(0, end);
   1457         assertEquals(layerDrawable.getDrawable(0).getIntrinsicWidth() + start + end,
   1458                 layerDrawable.getIntrinsicWidth());
   1459         assertEquals(end, layerDrawable.getLayerInsetEnd(0));
   1460 
   1461         try {
   1462             layerDrawable.setLayerInsetEnd(1, end);
   1463             fail("Should throw IndexOutOfBoundsException");
   1464         } catch (IndexOutOfBoundsException e) {
   1465         }
   1466     }
   1467 
   1468     @Test
   1469     public void testGetLayerInsetEnd() {
   1470         Drawable[] array = new Drawable[] { mBitmapDrawable };
   1471         LayerDrawable layerDrawable = new LayerDrawable(array);
   1472 
   1473         // set inset for layer 0
   1474         int start = 10;
   1475         int top = 20;
   1476         int end = 30;
   1477         int bottom = 40;
   1478         layerDrawable.setLayerInsetRelative(0, start, top, end, bottom);
   1479         assertEquals(end, layerDrawable.getLayerInsetEnd(0));
   1480         end += 5;
   1481         layerDrawable.setLayerInsetEnd(0, end);
   1482         assertEquals(end, layerDrawable.getLayerInsetEnd(0));
   1483 
   1484         try {
   1485             layerDrawable.getLayerInsetEnd(1);
   1486             fail("Should throw IndexOutOfBoundsException");
   1487         } catch (IndexOutOfBoundsException e) {
   1488         }
   1489     }
   1490 
   1491     @Test
   1492     public void testChildIntrinsicSize() {
   1493         LayerDrawable dr;
   1494 
   1495         // Ensure that a child with no intrinsic size correctly reports bounds.
   1496         dr = (LayerDrawable) mContext.getDrawable(R.drawable.layer_drawable_intrinsic);
   1497         assertEquals(-1, dr.getIntrinsicWidth());
   1498         assertEquals(-1, dr.getIntrinsicHeight());
   1499 
   1500         // Check when creating the drawble from code.
   1501         dr = new LayerDrawable(new Drawable[] { new ColorDrawable(Color.RED) });
   1502         dr.setLayerInset(0, 10, 10, 10, 10);
   1503         assertEquals(-1, dr.getIntrinsicWidth());
   1504         assertEquals(-1, dr.getIntrinsicHeight());
   1505 
   1506         // Ensure mixed children report bounds correctly as well.
   1507         dr = (LayerDrawable) mContext.getDrawable(R.drawable.layer_drawable_intrinsic_mixed);
   1508         int width = dr.getLayerInsetLeft(0) + dr.getLayerInsetRight(0)
   1509                 + dr.getDrawable(0).getIntrinsicWidth();
   1510         int height = dr.getLayerInsetTop(0) + dr.getLayerInsetBottom(0)
   1511                 + dr.getDrawable(0).getIntrinsicHeight();
   1512         assertEquals(width, dr.getIntrinsicWidth());
   1513         assertEquals(height, dr.getIntrinsicHeight());
   1514     }
   1515 
   1516     @Test
   1517     public void testIsProjectedWithNullLayer() {
   1518         try {
   1519             LayerDrawable dr = new LayerDrawable(new Drawable[] {null});
   1520             dr.isProjected();
   1521         } catch (NullPointerException excep) {
   1522             fail("isProjected should support null child layer drawables");
   1523         }
   1524     }
   1525 
   1526     // Since Mockito can't mock or spy on protected methods, we have a custom extension
   1527     // of Drawable to track calls to protected methods. This class also has empty implementations
   1528     // of the base abstract methods. In addition, this class also updates its padding on every
   1529     // change in level or state.
   1530     private static class MockDrawable extends Drawable {
   1531         private boolean mCalledSetState = false;
   1532         private boolean mCalledOnLevelChange = false;
   1533         private boolean mCalledOnBoundsChange = false;
   1534 
   1535         private boolean mIsStateful = false;
   1536 
   1537         private Rect mPadding = null;
   1538 
   1539         public MockDrawable() {
   1540             this(false);
   1541         }
   1542 
   1543         public MockDrawable(boolean isStateful) {
   1544             mIsStateful = isStateful;
   1545         }
   1546 
   1547         @Override
   1548         public void draw(Canvas canvas) {
   1549         }
   1550 
   1551         @Override
   1552         public int getOpacity() {
   1553             return PixelFormat.OPAQUE;
   1554         }
   1555 
   1556         @Override
   1557         public void setAlpha(int alpha) {
   1558         }
   1559 
   1560         @Override
   1561         public void setColorFilter(ColorFilter cf) {
   1562         }
   1563 
   1564         public void reset() {
   1565             mCalledSetState = false;
   1566             mCalledOnLevelChange = false;
   1567             mCalledOnBoundsChange = false;
   1568         }
   1569 
   1570         @Override
   1571         protected boolean onStateChange(int[] state) {
   1572             increasePadding();
   1573             return mIsStateful;
   1574         }
   1575 
   1576         private void increasePadding() {
   1577             Rect padding = new Rect();
   1578             getPadding(padding);
   1579             padding.left++;
   1580             padding.top++;
   1581             padding.right++;
   1582             padding.bottom++;
   1583 
   1584             setPadding(padding);
   1585         }
   1586 
   1587         @Override
   1588         protected boolean onLevelChange(int level) {
   1589             increasePadding();
   1590             mCalledOnLevelChange = true;
   1591             return true;
   1592         }
   1593 
   1594         @Override
   1595         protected void onBoundsChange(Rect bounds) {
   1596             mCalledOnBoundsChange = true;
   1597             super.onBoundsChange(bounds);
   1598         }
   1599 
   1600         public boolean hasCalledOnBoundsChange() {
   1601             return mCalledOnBoundsChange;
   1602         }
   1603 
   1604         @Override
   1605         public boolean isStateful() {
   1606             return mIsStateful;
   1607         }
   1608 
   1609         public boolean hasCalledSetState() {
   1610             return mCalledSetState;
   1611         }
   1612 
   1613         @Override
   1614         public boolean setState(final int[] stateSet) {
   1615             mCalledSetState = true;
   1616             return super.setState(stateSet);
   1617         }
   1618 
   1619         public boolean hasCalledOnLevelChange() {
   1620             return mCalledOnLevelChange;
   1621         }
   1622 
   1623         private void setPadding(Rect padding) {
   1624             if (padding == null) {
   1625                 mPadding = null;
   1626             } else {
   1627                 if (mPadding == null) {
   1628                     mPadding = new Rect();
   1629                 }
   1630                 mPadding.set(padding);
   1631             }
   1632         }
   1633 
   1634         @Override
   1635         public boolean getPadding(Rect padding) {
   1636             if (mPadding != null) {
   1637                 padding.set(mPadding);
   1638                 return true;
   1639             } else {
   1640                 return super.getPadding(padding);
   1641             }
   1642         }
   1643     }
   1644 
   1645     @Test
   1646     public void testMutate() {
   1647         LayerDrawable d1 = (LayerDrawable) mContext.getDrawable(R.drawable.layerdrawable);
   1648         LayerDrawable d2 = (LayerDrawable) mContext.getDrawable(R.drawable.layerdrawable);
   1649         LayerDrawable d3 = (LayerDrawable) mContext.getDrawable(R.drawable.layerdrawable);
   1650         int restoreAlpha = d1.getAlpha();
   1651 
   1652         try {
   1653             // verify bad behavior - modify before mutate pollutes other drawables
   1654             d1.setAlpha(100);
   1655             assertEquals(100, ((BitmapDrawable) d1.getDrawable(0)).getPaint().getAlpha());
   1656             assertEquals(100, ((BitmapDrawable) d1.getDrawable(0)).getPaint().getAlpha());
   1657             assertEquals(100, ((BitmapDrawable) d2.getDrawable(0)).getPaint().getAlpha());
   1658             assertEquals(100, ((BitmapDrawable) d2.getDrawable(0)).getPaint().getAlpha());
   1659             assertEquals(100, ((BitmapDrawable) d3.getDrawable(0)).getPaint().getAlpha());
   1660             assertEquals(100, ((BitmapDrawable) d2.getDrawable(0)).getPaint().getAlpha());
   1661 
   1662             d1.mutate();
   1663             d1.setAlpha(200);
   1664             assertEquals(200, ((BitmapDrawable) d1.getDrawable(0)).getPaint().getAlpha());
   1665             assertEquals(200, ((BitmapDrawable) d1.getDrawable(0)).getPaint().getAlpha());
   1666             assertEquals(100, ((BitmapDrawable) d2.getDrawable(0)).getPaint().getAlpha());
   1667             assertEquals(100, ((BitmapDrawable) d2.getDrawable(0)).getPaint().getAlpha());
   1668             assertEquals(100, ((BitmapDrawable) d3.getDrawable(0)).getPaint().getAlpha());
   1669             assertEquals(100, ((BitmapDrawable) d3.getDrawable(0)).getPaint().getAlpha());
   1670 
   1671             d2.setAlpha(50);
   1672             assertEquals(200, ((BitmapDrawable) d1.getDrawable(0)).getPaint().getAlpha());
   1673             assertEquals(200, ((BitmapDrawable) d1.getDrawable(0)).getPaint().getAlpha());
   1674             assertEquals(50, ((BitmapDrawable) d2.getDrawable(0)).getPaint().getAlpha());
   1675             assertEquals(50, ((BitmapDrawable) d2.getDrawable(0)).getPaint().getAlpha());
   1676             assertEquals(50, ((BitmapDrawable) d3.getDrawable(0)).getPaint().getAlpha());
   1677             assertEquals(50, ((BitmapDrawable) d3.getDrawable(0)).getPaint().getAlpha());
   1678         } finally {
   1679             // restore externally visible state, since other tests may use the drawable
   1680             mContext.getDrawable(R.drawable.layerdrawable).setAlpha(restoreAlpha);
   1681         }
   1682     }
   1683 
   1684     @Test
   1685     public void testPreloadDensity() throws XmlPullParserException, IOException {
   1686         final Resources res = mContext.getResources();
   1687         final int densityDpi = res.getConfiguration().densityDpi;
   1688         try {
   1689             DrawableTestUtils.setResourcesDensity(res, densityDpi);
   1690             verifyPreloadDensityInner(res, densityDpi);
   1691         } finally {
   1692             DrawableTestUtils.setResourcesDensity(res, densityDpi);
   1693         }
   1694     }
   1695 
   1696     @Test
   1697     public void testPreloadDensity_tvdpi() throws XmlPullParserException, IOException {
   1698         final Resources res = mContext.getResources();
   1699         final int densityDpi = res.getConfiguration().densityDpi;
   1700         try {
   1701             DrawableTestUtils.setResourcesDensity(res, 213);
   1702             verifyPreloadDensityInner(res, 213);
   1703         } finally {
   1704             DrawableTestUtils.setResourcesDensity(res, densityDpi);
   1705         }
   1706     }
   1707 
   1708     private void verifyPreloadDensityInner(Resources res, int densityDpi)
   1709             throws XmlPullParserException, IOException {
   1710         // Capture initial state at default density.
   1711         final XmlResourceParser parser = DrawableTestUtils.getResourceParser(
   1712                 res, R.drawable.layer_drawable_density);
   1713         final LayerDrawable preloadedDrawable = new LayerDrawable(new Drawable[0]);
   1714         preloadedDrawable.inflate(res, parser, Xml.asAttributeSet(parser));
   1715         final ConstantState preloadedConstantState = preloadedDrawable.getConstantState();
   1716         final int initialLeftPadding = preloadedDrawable.getLeftPadding();
   1717         final int initialRightPadding = preloadedDrawable.getRightPadding();
   1718         final int initialContentInsetL = preloadedDrawable.getLayerInsetLeft(0);
   1719         final int initialContentInsetR = preloadedDrawable.getLayerInsetRight(0);
   1720         final int initialContentWidth = preloadedDrawable.getLayerWidth(0);
   1721         final int initialIntrinsicWidth = preloadedDrawable.getIntrinsicWidth();
   1722         final int initialBottomPadding = preloadedDrawable.getBottomPadding();
   1723         final int initialTopPadding = preloadedDrawable.getTopPadding();
   1724         final int initialLayerInsetLeft = preloadedDrawable.getLayerInsetLeft(0);
   1725         final int initialLayerInsetRight = preloadedDrawable.getLayerInsetRight(0);
   1726         final int initialLayerInsetTop = preloadedDrawable.getLayerInsetTop(0);
   1727         final int initialLayerInsetBottom = preloadedDrawable.getLayerInsetBottom(0);
   1728         final int initialLayerWidth = preloadedDrawable.getLayerWidth(0);
   1729         final int initialLayerHeight = preloadedDrawable.getLayerHeight(0);
   1730 
   1731         // Set density to half of original. Padding and insets are
   1732         // truncated, dimensions are rounded to the nearest pixel. Because
   1733         // LayerDrawable's intrinsic width is a combination of padding and
   1734         // dimensions, some computation is necessary.
   1735         DrawableTestUtils.setResourcesDensity(res, densityDpi / 2);
   1736         final LayerDrawable halfDrawable =
   1737                 (LayerDrawable) preloadedConstantState.newDrawable(res);
   1738         // NOTE: densityDpi may not be an even number, so account for *actual* scaling in asserts
   1739         final float approxHalf = (float)(densityDpi / 2) / densityDpi;
   1740         final int halfContentWidth = Math.round(initialContentWidth * approxHalf);
   1741         final int halfLeftPadding = (int) (initialLeftPadding * approxHalf);
   1742         final int halfRightPadding = (int) (initialRightPadding * approxHalf);
   1743         final int halfContentInsetL = (int) (initialContentInsetL * approxHalf);
   1744         final int halfContentInsetR = (int) (initialContentInsetR * approxHalf);
   1745         final int halfIntrinsicWidth = halfContentWidth + halfContentInsetL + halfContentInsetR;
   1746         assertEquals(halfLeftPadding, halfDrawable.getLeftPadding());
   1747         assertEquals(halfRightPadding, halfDrawable.getRightPadding());
   1748         assertEquals(halfContentInsetL, halfDrawable.getLayerInsetRight(0));
   1749         assertEquals(halfContentInsetR, halfDrawable.getLayerInsetLeft(0));
   1750         assertEquals(halfContentWidth, halfDrawable.getLayerWidth(0));
   1751         assertEquals(halfIntrinsicWidth, halfDrawable.getIntrinsicWidth());
   1752         assertEquals((int) (initialBottomPadding * approxHalf), halfDrawable.getBottomPadding());
   1753         assertEquals((int) (initialTopPadding * approxHalf), halfDrawable.getTopPadding());
   1754         assertEquals((int) (initialLayerInsetLeft * approxHalf),
   1755                 halfDrawable.getLayerInsetLeft(0));
   1756         assertEquals((int) (initialLayerInsetRight * approxHalf),
   1757                 halfDrawable.getLayerInsetRight(0));
   1758         assertEquals((int) (initialLayerInsetTop * approxHalf),
   1759                 halfDrawable.getLayerInsetTop(0));
   1760         assertEquals((int) (initialLayerInsetBottom * approxHalf),
   1761                 halfDrawable.getLayerInsetBottom(0));
   1762         assertEquals(Math.round(initialLayerWidth * approxHalf), halfDrawable.getLayerWidth(0));
   1763         assertEquals(Math.round(initialLayerHeight * approxHalf), halfDrawable.getLayerHeight(0));
   1764 
   1765         // Set density to double original.
   1766         DrawableTestUtils.setResourcesDensity(res, densityDpi * 2);
   1767         final LayerDrawable doubleDrawable =
   1768                 (LayerDrawable) preloadedConstantState.newDrawable(res);
   1769         assertEquals(initialLeftPadding * 2, doubleDrawable.getLeftPadding());
   1770         assertEquals(initialRightPadding * 2, doubleDrawable.getRightPadding());
   1771         assertEquals(initialContentInsetL * 2, doubleDrawable.getLayerInsetRight(0));
   1772         assertEquals(initialContentInsetR * 2, doubleDrawable.getLayerInsetLeft(0));
   1773         assertEquals(initialContentWidth * 2, doubleDrawable.getLayerWidth(0));
   1774         assertEquals(initialIntrinsicWidth * 2, doubleDrawable.getIntrinsicWidth());
   1775         assertEquals(initialBottomPadding * 2, doubleDrawable.getBottomPadding());
   1776         assertEquals(initialTopPadding * 2, doubleDrawable.getTopPadding());
   1777         assertEquals(initialLayerInsetLeft * 2, doubleDrawable.getLayerInsetLeft(0));
   1778         assertEquals(initialLayerInsetRight * 2, doubleDrawable.getLayerInsetRight(0));
   1779         assertEquals(initialLayerInsetTop * 2, doubleDrawable.getLayerInsetTop(0));
   1780         assertEquals(initialLayerInsetBottom * 2, doubleDrawable.getLayerInsetBottom(0));
   1781         assertEquals(initialLayerWidth * 2, doubleDrawable.getLayerWidth(0));
   1782         assertEquals(initialLayerHeight * 2, doubleDrawable.getLayerHeight(0));
   1783 
   1784         // Restore original configuration and metrics.
   1785         DrawableTestUtils.setResourcesDensity(res, densityDpi);
   1786         final LayerDrawable origDrawable =
   1787                 (LayerDrawable) preloadedConstantState.newDrawable(res);
   1788         assertEquals(initialLeftPadding, origDrawable.getLeftPadding());
   1789         assertEquals(initialRightPadding, origDrawable.getRightPadding());
   1790         assertEquals(initialContentInsetL, origDrawable.getLayerInsetRight(0));
   1791         assertEquals(initialContentInsetR, origDrawable.getLayerInsetLeft(0));
   1792         assertEquals(initialContentWidth, origDrawable.getLayerWidth(0));
   1793         assertEquals(initialIntrinsicWidth, origDrawable.getIntrinsicWidth());
   1794         assertEquals(initialBottomPadding, origDrawable.getBottomPadding());
   1795         assertEquals(initialTopPadding, origDrawable.getTopPadding());
   1796         assertEquals(initialLayerInsetLeft, origDrawable.getLayerInsetLeft(0));
   1797         assertEquals(initialLayerInsetRight, origDrawable.getLayerInsetRight(0));
   1798         assertEquals(initialLayerInsetTop, origDrawable.getLayerInsetTop(0));
   1799         assertEquals(initialLayerInsetBottom, origDrawable.getLayerInsetBottom(0));
   1800         assertEquals(initialLayerWidth, origDrawable.getLayerWidth(0));
   1801         assertEquals(initialLayerHeight, origDrawable.getLayerHeight(0));
   1802 
   1803         // Ensure theme density is applied correctly.
   1804         final Theme t = res.newTheme();
   1805 
   1806         // The half-density drawable will scale-up all of the values that were
   1807         // previously scaled-down, so we need to capture the rounding errors.
   1808         halfDrawable.applyTheme(t);
   1809 
   1810         // Reproduce imprecise truncated scale down, and back up. Note that we don't round.
   1811         float approxDouble = 1 / approxHalf;
   1812         assertEquals((int) (halfLeftPadding * approxDouble), halfDrawable.getLeftPadding());
   1813         assertEquals((int) (halfRightPadding * approxDouble), halfDrawable.getRightPadding());
   1814         assertEquals((int) (halfContentInsetL * approxDouble), halfDrawable.getLayerInsetRight(0));
   1815         assertEquals((int) (halfContentInsetR * approxDouble), halfDrawable.getLayerInsetLeft(0));
   1816         assertEquals((int) (halfContentWidth * approxDouble), halfDrawable.getLayerWidth(0));
   1817         assertEquals(halfIntrinsicWidth * 2, halfDrawable.getIntrinsicWidth());
   1818         assertEquals((int) ((int) (initialBottomPadding * approxHalf) * approxDouble),
   1819                 halfDrawable.getBottomPadding());
   1820         assertEquals((int) ((int) (initialTopPadding * approxHalf) * approxDouble),
   1821                 halfDrawable.getTopPadding());
   1822         assertEquals((int) ((int) (initialLayerInsetLeft * approxHalf) * approxDouble),
   1823                 halfDrawable.getLayerInsetLeft(0));
   1824         assertEquals((int) ((int) (initialLayerInsetRight * approxHalf) * approxDouble),
   1825                 halfDrawable.getLayerInsetRight(0));
   1826         assertEquals((int) ((int) (initialLayerInsetTop * approxHalf) * approxDouble),
   1827                 halfDrawable.getLayerInsetTop(0));
   1828         assertEquals((int) ((int) (initialLayerInsetBottom * approxHalf) * approxDouble),
   1829                 halfDrawable.getLayerInsetBottom(0));
   1830         assertEquals(Math.round(Math.round(initialLayerWidth * approxHalf) * approxDouble),
   1831                 halfDrawable.getLayerWidth(0));
   1832         assertEquals(Math.round(Math.round(initialLayerHeight * approxHalf) * approxDouble),
   1833                 halfDrawable.getLayerHeight(0));
   1834 
   1835         // The double-density drawable will scale-down all of the values that
   1836         // were previously scaled-up, so we don't need to worry about rounding.
   1837         doubleDrawable.applyTheme(t);
   1838         assertEquals(initialLeftPadding, doubleDrawable.getLeftPadding());
   1839         assertEquals(initialRightPadding, doubleDrawable.getRightPadding());
   1840         assertEquals(initialContentInsetL, doubleDrawable.getLayerInsetRight(0));
   1841         assertEquals(initialContentInsetR, doubleDrawable.getLayerInsetLeft(0));
   1842         assertEquals(initialContentWidth, doubleDrawable.getLayerWidth(0));
   1843         assertEquals(initialIntrinsicWidth, doubleDrawable.getIntrinsicWidth());
   1844         assertEquals(initialBottomPadding, doubleDrawable.getBottomPadding());
   1845         assertEquals(initialTopPadding, doubleDrawable.getTopPadding());
   1846         assertEquals(initialLayerInsetLeft, doubleDrawable.getLayerInsetLeft(0));
   1847         assertEquals(initialLayerInsetRight, doubleDrawable.getLayerInsetRight(0));
   1848         assertEquals(initialLayerInsetTop, doubleDrawable.getLayerInsetTop(0));
   1849         assertEquals(initialLayerInsetBottom, doubleDrawable.getLayerInsetBottom(0));
   1850         assertEquals(initialLayerWidth, doubleDrawable.getLayerWidth(0));
   1851         assertEquals(initialLayerHeight, doubleDrawable.getLayerHeight(0));
   1852     }
   1853 
   1854     @Test
   1855     public void testOpacityChange() {
   1856         ColorDrawable c1 = new ColorDrawable(Color.RED);
   1857         ColorDrawable c2 = new ColorDrawable(Color.BLUE);
   1858         LayerDrawable dr = new LayerDrawable(new ColorDrawable[] { c1, c2 });
   1859         assertEquals(PixelFormat.OPAQUE, dr.getOpacity());
   1860 
   1861         c1.setTint(0x80FF0000);
   1862         c1.setTintMode(PorterDuff.Mode.SRC);
   1863         c2.setTint(0x800000FF);
   1864         c2.setTintMode(PorterDuff.Mode.SRC);
   1865         assertEquals(PixelFormat.TRANSLUCENT, dr.getOpacity());
   1866     }
   1867 
   1868     @Test
   1869     public void testStatefulnessChange() {
   1870         ColorDrawable c1 = new ColorDrawable(Color.RED);
   1871         ColorDrawable c2 = new ColorDrawable(Color.BLUE);
   1872         LayerDrawable dr = new LayerDrawable(new ColorDrawable[] { c1, c2 });
   1873         assertEquals(false, dr.isStateful());
   1874 
   1875         ColorStateList csl = new ColorStateList(
   1876                 new int[][] { { android.R.attr.state_enabled }, { } },
   1877                 new int[] { Color.RED, Color.BLUE });
   1878         c1.setTintList(csl);
   1879         assertEquals(true, dr.isStateful());
   1880     }
   1881 
   1882     @Test
   1883     public void testInvalidateDuringInit() {
   1884         Drawable layer = new RippleDrawable(ColorStateList.valueOf(Color.BLACK), null, null);
   1885 
   1886         LayerDrawable orig = new LayerDrawable(new Drawable[] { layer });
   1887         orig.setBounds(0, 0, 100, 100);
   1888 
   1889         // This will invoke the layer's invalidateSelf() during construction.
   1890         LayerDrawable copy = (LayerDrawable) orig.getConstantState().newDrawable();
   1891         assertNotSame(orig, copy);
   1892     }
   1893 
   1894     private static class IntrinsicSizeDrawable extends Drawable {
   1895         private final int mIntrinsicWidth;
   1896         private final int mIntrinsicHeight;
   1897         private final Rect mPadding;
   1898 
   1899         public IntrinsicSizeDrawable(int intrinsicWidth, int intrinsicHeight, Rect padding) {
   1900             mIntrinsicWidth = intrinsicWidth;
   1901             mIntrinsicHeight = intrinsicHeight;
   1902             mPadding = new Rect(padding);
   1903         }
   1904 
   1905         @Override
   1906         public boolean getPadding(Rect padding) {
   1907             padding.set(mPadding);
   1908             return true;
   1909         }
   1910 
   1911         @Override
   1912         public int getIntrinsicHeight() {
   1913             return mIntrinsicHeight;
   1914         }
   1915 
   1916         @Override
   1917         public int getIntrinsicWidth() {
   1918             return mIntrinsicWidth;
   1919         }
   1920 
   1921         @Override
   1922         public void draw(Canvas canvas) {
   1923         }
   1924 
   1925         @Override
   1926         public void setAlpha(int alpha) {
   1927         }
   1928 
   1929         @Override
   1930         public void setColorFilter(ColorFilter colorFilter) {
   1931         }
   1932 
   1933         @Override
   1934         public int getOpacity() {
   1935             return 0;
   1936         }
   1937     }
   1938 }
   1939