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.graphics.cts.R;
20 
21 import org.xmlpull.v1.XmlPullParser;
22 import org.xmlpull.v1.XmlPullParserException;
23 
24 import java.io.IOException;
25 import java.util.Arrays;
26 
27 import android.graphics.Bitmap;
28 import android.graphics.Bitmap.Config;
29 import android.graphics.Canvas;
30 import android.graphics.ColorFilter;
31 import android.graphics.PixelFormat;
32 import android.graphics.Rect;
33 import android.graphics.drawable.BitmapDrawable;
34 import android.graphics.drawable.ClipDrawable;
35 import android.graphics.drawable.Drawable;
36 import android.graphics.drawable.Drawable.ConstantState;
37 import android.test.AndroidTestCase;
38 import android.util.AttributeSet;
39 import android.util.StateSet;
40 import android.util.Xml;
41 import android.view.Gravity;
42 
43 public class ClipDrawableTest extends AndroidTestCase {
44     @SuppressWarnings("deprecation")
testClipDrawable()45     public void testClipDrawable() {
46         new ClipDrawable((Drawable) null, Gravity.BOTTOM, ClipDrawable.HORIZONTAL);
47 
48         BitmapDrawable bmpDrawable = new BitmapDrawable();
49         new ClipDrawable(bmpDrawable, Gravity.BOTTOM, ClipDrawable.HORIZONTAL);
50     }
51 
testDraw()52     public void testDraw() {
53         MockDrawable mockDrawable = new MockDrawable();
54         mockDrawable.setLevel(5000);
55         ClipDrawable clipDrawable = new ClipDrawable(mockDrawable,
56                 Gravity.BOTTOM, ClipDrawable.HORIZONTAL);
57         clipDrawable.setBounds(new Rect(0, 0, 100, 100));
58         clipDrawable.setLevel(5000);
59         assertFalse(mockDrawable.getCalledDraw());
60         clipDrawable.draw(new Canvas());
61         assertTrue(mockDrawable.getCalledDraw());
62 
63         try {
64             clipDrawable.draw(null);
65             fail("should throw NullPointerException.");
66         } catch (NullPointerException e) {
67         }
68     }
69 
testGetChangingConfigurations()70     public void testGetChangingConfigurations() {
71         final int SUPER_CONFIG = 1;
72         final int CONTAINED_DRAWABLE_CONFIG = 2;
73 
74         MockDrawable mockDrawable = new MockDrawable();
75         ClipDrawable clipDrawable = new ClipDrawable(mockDrawable,
76                 Gravity.BOTTOM, ClipDrawable.HORIZONTAL);
77 
78         assertEquals(0, clipDrawable.getChangingConfigurations());
79 
80         mockDrawable.setChangingConfigurations(CONTAINED_DRAWABLE_CONFIG);
81         assertEquals(CONTAINED_DRAWABLE_CONFIG, clipDrawable.getChangingConfigurations());
82 
83         clipDrawable.setChangingConfigurations(SUPER_CONFIG);
84         assertEquals(SUPER_CONFIG | CONTAINED_DRAWABLE_CONFIG,
85                 clipDrawable.getChangingConfigurations());
86     }
87 
testGetConstantState()88     public void testGetConstantState() {
89         MockDrawable mockDrawable = new MockDrawable();
90         ClipDrawable clipDrawable = new ClipDrawable(mockDrawable,
91                 Gravity.BOTTOM, ClipDrawable.HORIZONTAL);
92         assertNull(clipDrawable.getConstantState());
93 
94         mockDrawable.setConstantState(new MockConstantState());
95         clipDrawable = new ClipDrawable(mockDrawable, Gravity.BOTTOM, ClipDrawable.HORIZONTAL);
96         clipDrawable.setChangingConfigurations(1);
97         assertNotNull(clipDrawable.getConstantState());
98         assertEquals(1, clipDrawable.getConstantState().getChangingConfigurations());
99     }
100 
101     @SuppressWarnings("deprecation")
testGetIntrinsicHeight()102     public void testGetIntrinsicHeight() {
103         MockDrawable mockDrawable = new MockDrawable();
104         ClipDrawable clipDrawable = new ClipDrawable(mockDrawable,
105                 Gravity.BOTTOM, ClipDrawable.HORIZONTAL);
106         assertEquals(-1, clipDrawable.getIntrinsicHeight());
107 
108         Bitmap bitmap = Bitmap.createBitmap(100, 50, Config.RGB_565);
109         BitmapDrawable bmpDrawable = new BitmapDrawable(bitmap);
110         bmpDrawable.setTargetDensity(bitmap.getDensity()); // avoid scaling
111         clipDrawable = new ClipDrawable(bmpDrawable, Gravity.BOTTOM, ClipDrawable.HORIZONTAL);
112         assertEquals(50, clipDrawable.getIntrinsicHeight());
113     }
114 
115     @SuppressWarnings("deprecation")
testGetIntrinsicWidth()116     public void testGetIntrinsicWidth() {
117         MockDrawable mockDrawable = new MockDrawable();
118         ClipDrawable clipDrawable = new ClipDrawable(mockDrawable,
119                 Gravity.BOTTOM, ClipDrawable.HORIZONTAL);
120         assertEquals(-1, clipDrawable.getIntrinsicWidth());
121 
122         Bitmap bitmap = Bitmap.createBitmap(100, 50, Config.RGB_565);
123         BitmapDrawable bmpDrawable = new BitmapDrawable(bitmap);
124         bmpDrawable.setTargetDensity(bitmap.getDensity()); // avoid scaling
125         clipDrawable = new ClipDrawable(bmpDrawable, Gravity.BOTTOM, ClipDrawable.HORIZONTAL);
126         assertEquals(100, clipDrawable.getIntrinsicWidth());
127     }
128 
129     @SuppressWarnings("deprecation")
testGetOpacity()130     public void testGetOpacity() {
131         MockDrawable dr;
132         ClipDrawable clipDrawable;
133 
134         dr = new MockDrawable();
135         dr.setOpacity(PixelFormat.OPAQUE);
136         clipDrawable = new ClipDrawable(dr, Gravity.BOTTOM, ClipDrawable.HORIZONTAL);
137         clipDrawable.setLevel(0);
138         assertEquals("Fully-clipped opaque drawable is transparent",
139                 PixelFormat.TRANSPARENT, clipDrawable.getOpacity());
140         clipDrawable.setLevel(5000);
141         assertEquals("Partially-clipped opaque drawable is translucent",
142                 PixelFormat.TRANSLUCENT, clipDrawable.getOpacity());
143         clipDrawable.setLevel(10000);
144         assertEquals("Unclipped opaque drawable is opaque",
145                 PixelFormat.OPAQUE, clipDrawable.getOpacity());
146 
147         dr = new MockDrawable();
148         dr.setOpacity(PixelFormat.TRANSLUCENT);
149         clipDrawable = new ClipDrawable(dr, Gravity.BOTTOM, ClipDrawable.HORIZONTAL);
150         clipDrawable.setLevel(10000);
151         assertEquals("Unclipped translucent drawable is translucent",
152                 PixelFormat.TRANSLUCENT, clipDrawable.getOpacity());
153     }
154 
testGetPadding()155     public void testGetPadding() {
156         MockDrawable mockDrawable = new MockDrawable();
157         ClipDrawable clipDrawable = new ClipDrawable(mockDrawable,
158                 Gravity.BOTTOM, ClipDrawable.HORIZONTAL);
159         Rect padding = new Rect(10, 10, 100, 100);
160         assertFalse(clipDrawable.getPadding(padding));
161         assertEquals(0, padding.left);
162         assertEquals(0, padding.top);
163         assertEquals(0, padding.bottom);
164         assertEquals(0, padding.right);
165 
166         try {
167             clipDrawable.getPadding(null);
168             fail("should throw NullPointerException.");
169         } catch (NullPointerException e) {
170         }
171     }
172 
173     @SuppressWarnings("deprecation")
testInflate()174     public void testInflate() throws XmlPullParserException, IOException {
175         BitmapDrawable bmpDrawable = new BitmapDrawable();
176         ClipDrawable clipDrawable = new ClipDrawable(bmpDrawable,
177                 Gravity.BOTTOM, ClipDrawable.HORIZONTAL);
178 
179         XmlPullParser parser = mContext.getResources().getXml(R.drawable.gradientdrawable);
180         AttributeSet attrs = Xml.asAttributeSet(parser);
181         clipDrawable.inflate(mContext.getResources(), parser, attrs);
182     }
183 
testInvalidateDrawable()184     public void testInvalidateDrawable() {
185         MockDrawable mockDrawable = new MockDrawable();
186         ClipDrawable clipDrawable = new ClipDrawable(mockDrawable,
187                 Gravity.BOTTOM, ClipDrawable.HORIZONTAL);
188         MockCallback callback = new MockCallback();
189         clipDrawable.setCallback(callback);
190         clipDrawable.invalidateDrawable(mockDrawable);
191         assertSame(clipDrawable, callback.getInvalidateDrawable());
192 
193         clipDrawable.invalidateDrawable(null);
194     }
195 
196     @SuppressWarnings("deprecation")
testIsStateful()197     public void testIsStateful() {
198         MockDrawable mockDrawable = new MockDrawable();
199         ClipDrawable clipDrawable = new ClipDrawable(mockDrawable,
200                 Gravity.BOTTOM, ClipDrawable.HORIZONTAL);
201         assertFalse(clipDrawable.isStateful());
202 
203         BitmapDrawable bmpDrawable =
204                 new BitmapDrawable(Bitmap.createBitmap(100, 50, Config.RGB_565));
205         clipDrawable = new ClipDrawable(bmpDrawable, Gravity.BOTTOM, ClipDrawable.HORIZONTAL);
206         assertFalse(clipDrawable.isStateful());
207     }
208 
testOnBoundsChange()209     public void testOnBoundsChange() {
210         MockDrawable mockDrawable = new MockDrawable();
211         MockClipDrawable mockClipDrawable = new MockClipDrawable(mockDrawable,
212                 Gravity.BOTTOM, ClipDrawable.HORIZONTAL);
213         assertEquals(0, mockDrawable.getBounds().left);
214         assertEquals(0, mockDrawable.getBounds().top);
215         assertEquals(0, mockDrawable.getBounds().bottom);
216         assertEquals(0, mockDrawable.getBounds().right);
217         mockClipDrawable.onBoundsChange(new Rect(10, 10, 100, 100));
218         assertEquals(10, mockDrawable.getBounds().left);
219         assertEquals(10, mockDrawable.getBounds().top);
220         assertEquals(100, mockDrawable.getBounds().bottom);
221         assertEquals(100, mockDrawable.getBounds().right);
222 
223         try {
224             mockClipDrawable.onBoundsChange(null);
225             fail("should throw NullPointerException.");
226         } catch (NullPointerException e) {
227         }
228     }
229 
testOnLevelChange()230     public void testOnLevelChange() {
231         MockDrawable mockDrawable = new MockDrawable();
232         MockClipDrawable mockClipDrawable = new MockClipDrawable(mockDrawable,
233                 Gravity.BOTTOM, ClipDrawable.HORIZONTAL);
234         MockCallback callback = new MockCallback();
235         mockClipDrawable.setCallback(callback);
236 
237         assertEquals("Default level is 0", 0, mockDrawable.getLevel());
238         mockClipDrawable.onLevelChange(1000);
239         assertEquals(1000, mockDrawable.getLevel());
240         assertSame(mockClipDrawable, callback.getInvalidateDrawable());
241 
242         mockClipDrawable.onLevelChange(0);
243         assertEquals(0, mockDrawable.getLevel());
244 
245         mockClipDrawable.onLevelChange(10000);
246         assertEquals(10000, mockDrawable.getLevel());
247     }
248 
testOnStateChange()249     public void testOnStateChange() {
250         Drawable d = mContext.getDrawable(R.drawable.pass);
251         MockClipDrawable clipDrawable = new MockClipDrawable(d,
252                 Gravity.BOTTOM, ClipDrawable.HORIZONTAL);
253         assertEquals("initial child state is empty", d.getState(), StateSet.WILD_CARD);
254 
255         int[] state = new int[] {1, 2, 3};
256         assertFalse("child did not change", clipDrawable.onStateChange(state));
257         assertEquals("child state did not change", d.getState(), StateSet.WILD_CARD);
258 
259         d = mContext.getDrawable(R.drawable.statelistdrawable);
260         clipDrawable = new MockClipDrawable(d, Gravity.BOTTOM, ClipDrawable.HORIZONTAL);
261         assertEquals("initial child state is empty", d.getState(), StateSet.WILD_CARD);
262         clipDrawable.onStateChange(state);
263         assertTrue("child state changed", Arrays.equals(state, d.getState()));
264 
265         // input null as param
266         clipDrawable.onStateChange(null);
267         // expected, no Exception thrown out, test success
268     }
269 
testScheduleDrawable()270     public void testScheduleDrawable() {
271         MockDrawable mockDrawable = new MockDrawable();
272         ClipDrawable clipDrawable = new ClipDrawable(mockDrawable,
273                 Gravity.BOTTOM, ClipDrawable.HORIZONTAL);
274         MockCallback callback = new MockCallback();
275         clipDrawable.setCallback(callback);
276         clipDrawable.scheduleDrawable(mockDrawable, null, 1000L);
277         assertEquals(clipDrawable, callback.getScheduleDrawable());
278         assertNull(callback.getRunnable());
279         assertEquals(1000L, callback.getWhen());
280     }
281 
testSetAlpha()282     public void testSetAlpha() {
283         MockDrawable mockDrawable = new MockDrawable();
284         ClipDrawable clipDrawable = new ClipDrawable(mockDrawable,
285                 Gravity.BOTTOM, ClipDrawable.HORIZONTAL);
286 
287         clipDrawable.setAlpha(0);
288         assertEquals(0, mockDrawable.getAlpha());
289 
290         clipDrawable.setAlpha(128);
291         assertEquals(128, mockDrawable.getAlpha());
292 
293         clipDrawable.setAlpha(255);
294         assertEquals(255, mockDrawable.getAlpha());
295     }
296 
testSetColorFilter()297     public void testSetColorFilter() {
298         MockDrawable mockDrawable = new MockDrawable();
299         ClipDrawable clipDrawable = new ClipDrawable(mockDrawable,
300                 Gravity.BOTTOM, ClipDrawable.HORIZONTAL);
301 
302         ColorFilter cf = new ColorFilter();
303         clipDrawable.setColorFilter(cf);
304         assertSame(cf, mockDrawable.getColorFilter());
305 
306         clipDrawable.setColorFilter(null);
307         assertNull(mockDrawable.getColorFilter());
308     }
309 
testSetVisible()310     public void testSetVisible() {
311         MockDrawable mockDrawable = new MockDrawable();
312         ClipDrawable clipDrawable = new ClipDrawable(mockDrawable,
313                 Gravity.BOTTOM, ClipDrawable.HORIZONTAL);
314         assertTrue(clipDrawable.isVisible());
315 
316         assertTrue(clipDrawable.setVisible(false, false));
317         assertFalse(clipDrawable.isVisible());
318 
319         assertFalse(clipDrawable.setVisible(false, false));
320         assertFalse(clipDrawable.isVisible());
321 
322         assertTrue(clipDrawable.setVisible(true, false));
323         assertTrue(clipDrawable.isVisible());
324     }
325 
testUnscheduleDrawable()326     public void testUnscheduleDrawable() {
327         MockDrawable mockDrawable = new MockDrawable();
328         ClipDrawable clipDrawable = new ClipDrawable(mockDrawable,
329                 Gravity.BOTTOM, ClipDrawable.HORIZONTAL);
330         MockCallback callback = new MockCallback();
331         clipDrawable.setCallback(callback);
332         clipDrawable.unscheduleDrawable(mockDrawable, null);
333         assertEquals(clipDrawable, callback.getScheduleDrawable());
334         assertNull(callback.getRunnable());
335     }
336 
337     private class MockClipDrawable extends ClipDrawable {
MockClipDrawable(Drawable drawable, int gravity, int orientation)338         public MockClipDrawable(Drawable drawable, int gravity, int orientation) {
339             super(drawable, gravity, orientation);
340         }
341 
342         @Override
onStateChange(int[] state)343         protected boolean onStateChange(int[] state) {
344             return super.onStateChange(state);
345         }
346 
347         @Override
onLevelChange(int level)348         protected boolean onLevelChange(int level) {
349             return super.onLevelChange(level);
350         }
351 
352         @Override
onBoundsChange(Rect bounds)353         protected void onBoundsChange(Rect bounds) {
354             super.onBoundsChange(bounds);
355         }
356     }
357 
358     private class MockDrawable extends Drawable {
359         private ColorFilter mColorFilter;
360         private ConstantState mConstantState;
361         private int mOpacity;
362         private boolean mCalledDraw = false;
363         private int mAlpha;
364 
getCalledDraw()365         public boolean getCalledDraw() {
366             return mCalledDraw;
367         }
368 
draw(Canvas canvas)369         public void draw(Canvas canvas) {
370             mCalledDraw = true;
371         }
372 
setAlpha(int alpha)373         public void setAlpha(int alpha) {
374             mAlpha = alpha;
375         }
376 
getAlpha()377         public int getAlpha() {
378             return mAlpha;
379         }
380 
setColorFilter(ColorFilter cf)381         public void setColorFilter(ColorFilter cf) {
382             mColorFilter = cf;
383         }
384 
getColorFilter()385         public ColorFilter getColorFilter() {
386             return mColorFilter;
387         }
388 
getOpacity()389         public int getOpacity() {
390             return mOpacity;
391         }
392 
setOpacity(int opacity)393         public void setOpacity(int opacity) {
394             mOpacity = opacity;
395         }
396 
onBoundsChange(Rect bounds)397         protected void onBoundsChange(Rect bounds) {
398             super.onBoundsChange(bounds);
399         }
400 
onLevelChange(int level)401         protected boolean onLevelChange(int level) {
402             return super.onLevelChange(level);
403         }
404 
onStateChange(int[] state)405         protected boolean onStateChange(int[] state) {
406             return super.onStateChange(state);
407         }
408 
getConstantState()409         public ConstantState getConstantState() {
410             return mConstantState;
411         }
412 
setConstantState(ConstantState cs)413         public void setConstantState(ConstantState cs) {
414             mConstantState = cs;
415         }
416     }
417 
418     private class MockConstantState extends ConstantState {
newDrawable()419         public Drawable newDrawable() {
420             return null;
421         }
422 
getChangingConfigurations()423         public int getChangingConfigurations() {
424             return 0;
425         }
426     }
427 
428     private class MockCallback implements Drawable.Callback {
429         private Drawable mInvalidateDrawable;
430         private Drawable mScheduleDrawable;
431         private Runnable mRunnable;
432         private long mWhen;
433 
getInvalidateDrawable()434         public Drawable getInvalidateDrawable() {
435             return mInvalidateDrawable;
436         }
437 
getScheduleDrawable()438         public Drawable getScheduleDrawable() {
439             return mScheduleDrawable;
440         }
441 
getRunnable()442         public Runnable getRunnable() {
443             return mRunnable;
444         }
445 
getWhen()446         public long getWhen() {
447             return mWhen;
448         }
449 
invalidateDrawable(Drawable who)450         public void invalidateDrawable(Drawable who) {
451             mInvalidateDrawable = who;
452         }
453 
scheduleDrawable(Drawable who, Runnable what, long when)454         public void scheduleDrawable(Drawable who, Runnable what, long when) {
455             mScheduleDrawable = who;
456             mRunnable = what;
457             mWhen = when;
458         }
459 
unscheduleDrawable(Drawable who, Runnable what)460         public void unscheduleDrawable(Drawable who, Runnable what) {
461             mScheduleDrawable = who;
462             mRunnable = what;
463         }
464 
getResolvedLayoutDirection(Drawable who)465         public int getResolvedLayoutDirection(Drawable who) {
466             return 0;
467         }
468     }
469 }
470