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