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