• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.widget.cts;
18 
19 import static org.junit.Assert.assertArrayEquals;
20 import static org.junit.Assert.assertEquals;
21 import static org.junit.Assert.assertFalse;
22 import static org.junit.Assert.assertNotNull;
23 import static org.junit.Assert.assertNotSame;
24 import static org.junit.Assert.assertNull;
25 import static org.junit.Assert.assertSame;
26 import static org.junit.Assert.assertTrue;
27 import static org.junit.Assert.fail;
28 import static org.mockito.Matchers.any;
29 import static org.mockito.Matchers.anyInt;
30 import static org.mockito.Mockito.atLeastOnce;
31 import static org.mockito.Mockito.never;
32 import static org.mockito.Mockito.spy;
33 import static org.mockito.Mockito.times;
34 import static org.mockito.Mockito.verify;
35 
36 import android.annotation.Nullable;
37 import android.app.Activity;
38 import android.content.Context;
39 import android.content.res.ColorStateList;
40 import android.graphics.Bitmap;
41 import android.graphics.BitmapFactory;
42 import android.graphics.BlendMode;
43 import android.graphics.BlendModeColorFilter;
44 import android.graphics.Canvas;
45 import android.graphics.Color;
46 import android.graphics.ColorFilter;
47 import android.graphics.Matrix;
48 import android.graphics.PixelFormat;
49 import android.graphics.PorterDuff;
50 import android.graphics.PorterDuff.Mode;
51 import android.graphics.PorterDuffColorFilter;
52 import android.graphics.PorterDuffXfermode;
53 import android.graphics.Rect;
54 import android.graphics.Xfermode;
55 import android.graphics.drawable.BitmapDrawable;
56 import android.graphics.drawable.ColorDrawable;
57 import android.graphics.drawable.Drawable;
58 import android.graphics.drawable.Icon;
59 import android.graphics.drawable.PaintDrawable;
60 import android.net.Uri;
61 import android.util.AttributeSet;
62 import android.util.Xml;
63 import android.view.View;
64 import android.widget.ImageView;
65 import android.widget.ImageView.ScaleType;
66 import android.widget.cts.util.TestUtils;
67 
68 import androidx.test.InstrumentationRegistry;
69 import androidx.test.annotation.UiThreadTest;
70 import androidx.test.filters.MediumTest;
71 import androidx.test.rule.ActivityTestRule;
72 import androidx.test.runner.AndroidJUnit4;
73 
74 import com.android.compatibility.common.util.WidgetTestUtils;
75 
76 import org.junit.Before;
77 import org.junit.Rule;
78 import org.junit.Test;
79 import org.junit.runner.RunWith;
80 import org.xmlpull.v1.XmlPullParser;
81 
82 import java.io.File;
83 import java.io.FileOutputStream;
84 import java.io.IOException;
85 import java.io.InputStream;
86 import java.io.OutputStream;
87 
88 /**
89  * Test {@link ImageView}.
90  */
91 @MediumTest
92 @RunWith(AndroidJUnit4.class)
93 public class ImageViewTest {
94     private Activity mActivity;
95     private ImageView mImageViewRegular;
96 
97     @Rule
98     public ActivityTestRule<ImageViewCtsActivity> mActivityRule =
99             new ActivityTestRule<>(ImageViewCtsActivity.class);
100 
101     @Before
setup()102     public void setup() {
103         mActivity = mActivityRule.getActivity();
104         mImageViewRegular = (ImageView) mActivity.findViewById(R.id.imageview_regular);
105     }
106 
107     /**
108      * Find the ImageView specified by id.
109      *
110      * @param id the id
111      * @return the ImageView
112      */
findImageViewById(int id)113     private ImageView findImageViewById(int id) {
114         return (ImageView) mActivity.findViewById(id);
115     }
116 
createSampleImage(File imagefile, int resid)117     private void createSampleImage(File imagefile, int resid) {
118         try (InputStream source = mActivity.getResources().openRawResource(resid);
119              OutputStream target = new FileOutputStream(imagefile)) {
120             byte[] buffer = new byte[1024];
121             for (int len = source.read(buffer); len > 0; len = source.read(buffer)) {
122                 target.write(buffer, 0, len);
123             }
124         } catch (IOException e) {
125             fail(e.getMessage());
126         }
127     }
128 
129     @Test
testConstructor()130     public void testConstructor() {
131         new ImageView(mActivity);
132 
133         new ImageView(mActivity, null);
134 
135         new ImageView(mActivity, null, 0);
136 
137         new ImageView(mActivity, null, 0, 0);
138 
139         XmlPullParser parser = mActivity.getResources().getXml(R.layout.imageview_layout);
140         AttributeSet attrs = Xml.asAttributeSet(parser);
141         new ImageView(mActivity, attrs);
142         new ImageView(mActivity, attrs, 0);
143     }
144 
145 
146     @Test(expected=NullPointerException.class)
testConstructorNullContext1()147     public void testConstructorNullContext1() {
148         new ImageView(null);
149     }
150 
151     @Test(expected=NullPointerException.class)
testConstructorNullContext2()152     public void testConstructorNullContext2() {
153         new ImageView(null, null);
154     }
155 
156     @Test(expected=NullPointerException.class)
testConstructorNullContext3()157     public void testConstructorNullContext3() {
158         new ImageView(null, null, -1);
159     }
160 
161     @UiThreadTest
162     @Test
testConstructorImportantForAutofill()163     public void testConstructorImportantForAutofill() {
164         ImageView imageView = new ImageView(mActivity);
165         assertEquals(View.IMPORTANT_FOR_AUTOFILL_NO, imageView.getImportantForAutofill());
166         assertFalse(imageView.isImportantForAutofill());
167 
168         imageView = new ImageView(mActivity, null);
169         assertEquals(View.IMPORTANT_FOR_AUTOFILL_NO, imageView.getImportantForAutofill());
170         assertFalse(imageView.isImportantForAutofill());
171 
172         imageView = mActivity.findViewById(R.id.imageview_important_auto);
173         assertEquals(View.IMPORTANT_FOR_AUTOFILL_NO, imageView.getImportantForAutofill());
174         assertFalse(imageView.isImportantForAutofill());
175 
176         imageView = mActivity.findViewById(R.id.imageview_important_no);
177         assertEquals(View.IMPORTANT_FOR_AUTOFILL_NO, imageView.getImportantForAutofill());
178         assertFalse(imageView.isImportantForAutofill());
179 
180         imageView = mActivity.findViewById(R.id.imageview_important_yes);
181         assertEquals(View.IMPORTANT_FOR_AUTOFILL_YES, imageView.getImportantForAutofill());
182         assertTrue(imageView.isImportantForAutofill());
183     }
184 
185     @UiThreadTest
186     @Test
testConstructorImportantForContentCapture()187     public void testConstructorImportantForContentCapture() {
188         ImageView imageView = new ImageView(mActivity);
189         assertEquals(View.IMPORTANT_FOR_CONTENT_CAPTURE_YES,
190                 imageView.getImportantForContentCapture());
191         assertTrue(imageView.isImportantForContentCapture());
192 
193         imageView = new ImageView(mActivity, null);
194         assertEquals(View.IMPORTANT_FOR_CONTENT_CAPTURE_YES,
195                 imageView.getImportantForContentCapture());
196         assertTrue(imageView.isImportantForContentCapture());
197 
198         imageView = mActivity.findViewById(R.id.imageview_important_auto);
199         assertEquals(View.IMPORTANT_FOR_CONTENT_CAPTURE_YES,
200                 imageView.getImportantForContentCapture());
201         assertTrue(imageView.isImportantForContentCapture());
202 
203         imageView = mActivity.findViewById(R.id.imageview_important_no);
204         assertEquals(View.IMPORTANT_FOR_CONTENT_CAPTURE_NO,
205                 imageView.getImportantForContentCapture());
206         assertFalse(imageView.isImportantForContentCapture());
207 
208         imageView = mActivity.findViewById(R.id.imageview_important_yes);
209         assertEquals(View.IMPORTANT_FOR_CONTENT_CAPTURE_YES,
210                 imageView.getImportantForContentCapture());
211         assertTrue(imageView.isImportantForContentCapture());
212     }
213 
214     @UiThreadTest
215     @Test
testInvalidateDrawable()216     public void testInvalidateDrawable() {
217         mImageViewRegular.invalidateDrawable(null);
218     }
219 
220     @UiThreadTest
221     @Test
testSetAdjustViewBounds()222     public void testSetAdjustViewBounds() {
223         mImageViewRegular.setScaleType(ScaleType.FIT_XY);
224 
225         mImageViewRegular.setAdjustViewBounds(false);
226         assertFalse(mImageViewRegular.getAdjustViewBounds());
227         assertEquals(ScaleType.FIT_XY, mImageViewRegular.getScaleType());
228 
229         mImageViewRegular.setAdjustViewBounds(true);
230         assertTrue(mImageViewRegular.getAdjustViewBounds());
231         assertEquals(ScaleType.FIT_CENTER, mImageViewRegular.getScaleType());
232     }
233 
234     @UiThreadTest
235     @Test
testSetMaxWidth()236     public void testSetMaxWidth() {
237         mImageViewRegular.setMaxWidth(120);
238         mImageViewRegular.setMaxWidth(-1);
239     }
240 
241     @UiThreadTest
242     @Test
testSetMaxHeight()243     public void testSetMaxHeight() {
244         mImageViewRegular.setMaxHeight(120);
245         mImageViewRegular.setMaxHeight(-1);
246     }
247 
248     @UiThreadTest
249     @Test
testGetDrawable()250     public void testGetDrawable() {
251         final PaintDrawable drawable1 = new PaintDrawable();
252         final PaintDrawable drawable2 = new PaintDrawable();
253 
254         assertNull(mImageViewRegular.getDrawable());
255 
256         mImageViewRegular.setImageDrawable(drawable1);
257         assertEquals(drawable1, mImageViewRegular.getDrawable());
258         assertNotSame(drawable2, mImageViewRegular.getDrawable());
259     }
260 
261     @UiThreadTest
262     @Test
testSetImageIcon()263     public void testSetImageIcon() {
264         mImageViewRegular.setImageIcon(null);
265         assertNull(mImageViewRegular.getDrawable());
266 
267         Icon icon = Icon.createWithResource(mActivity, R.drawable.testimage);
268         mImageViewRegular.setImageIcon(icon);
269         assertTrue(mImageViewRegular.isLayoutRequested());
270         assertNotNull(mImageViewRegular.getDrawable());
271         Drawable drawable = mActivity.getDrawable(R.drawable.testimage);
272         BitmapDrawable testimageBitmap = (BitmapDrawable) drawable;
273         Drawable imageViewDrawable = mImageViewRegular.getDrawable();
274         BitmapDrawable imageViewBitmap = (BitmapDrawable) imageViewDrawable;
275         WidgetTestUtils.assertEquals(testimageBitmap.getBitmap(), imageViewBitmap.getBitmap());
276     }
277 
278     @UiThreadTest
279     @Test
testSetImageResource()280     public void testSetImageResource() {
281         mImageViewRegular.setImageResource(-1);
282         assertNull(mImageViewRegular.getDrawable());
283 
284         mImageViewRegular.setImageResource(R.drawable.testimage);
285         assertTrue(mImageViewRegular.isLayoutRequested());
286         assertNotNull(mImageViewRegular.getDrawable());
287         Drawable drawable = mActivity.getDrawable(R.drawable.testimage);
288         BitmapDrawable testimageBitmap = (BitmapDrawable) drawable;
289         Drawable imageViewDrawable = mImageViewRegular.getDrawable();
290         BitmapDrawable imageViewBitmap = (BitmapDrawable) imageViewDrawable;
291         WidgetTestUtils.assertEquals(testimageBitmap.getBitmap(), imageViewBitmap.getBitmap());
292     }
293 
294     @UiThreadTest
295     @Test
testSetImageURI()296     public void testSetImageURI() {
297         mImageViewRegular.setImageURI(null);
298         assertNull(mImageViewRegular.getDrawable());
299 
300         File dbDir = mActivity.getDir("tests", Context.MODE_PRIVATE);
301         File imagefile = new File(dbDir, "tempimage.jpg");
302         if (imagefile.exists()) {
303             imagefile.delete();
304         }
305         createSampleImage(imagefile, R.raw.testimage);
306         final String path = imagefile.getPath();
307         mImageViewRegular.setImageURI(Uri.parse(path));
308         assertTrue(mImageViewRegular.isLayoutRequested());
309         assertNotNull(mImageViewRegular.getDrawable());
310 
311         Drawable imageViewDrawable = mImageViewRegular.getDrawable();
312         BitmapDrawable imageViewBitmap = (BitmapDrawable) imageViewDrawable;
313         Bitmap.Config viewConfig = imageViewBitmap.getBitmap().getConfig();
314         Bitmap testimageBitmap = WidgetTestUtils.getUnscaledAndDitheredBitmap(
315                 mActivity.getResources(), R.raw.testimage, viewConfig);
316 
317         WidgetTestUtils.assertEquals(testimageBitmap, imageViewBitmap.getBitmap());
318     }
319 
320     @UiThreadTest
321     @Test
testSetImageDrawable()322     public void testSetImageDrawable() {
323         mImageViewRegular.setImageDrawable(null);
324         assertNull(mImageViewRegular.getDrawable());
325 
326         final Drawable drawable = mActivity.getDrawable(R.drawable.testimage);
327         drawable.setLevel(1);
328         mImageViewRegular.setImageDrawable(drawable);
329         assertTrue(mImageViewRegular.isLayoutRequested());
330         assertNotNull(mImageViewRegular.getDrawable());
331         assertEquals(1, mImageViewRegular.getDrawable().getLevel());
332         BitmapDrawable testimageBitmap = (BitmapDrawable) drawable;
333         Drawable imageViewDrawable = mImageViewRegular.getDrawable();
334         BitmapDrawable imageViewBitmap = (BitmapDrawable) imageViewDrawable;
335         WidgetTestUtils.assertEquals(testimageBitmap.getBitmap(), imageViewBitmap.getBitmap());
336     }
337 
338     @UiThreadTest
339     @Test
testSetImageLevelAfterSetImageDrawable()340     public void testSetImageLevelAfterSetImageDrawable() {
341         mImageViewRegular.setImageDrawable(null);
342         assertNull(mImageViewRegular.getDrawable());
343 
344         final Drawable drawable = mActivity.getDrawable(R.drawable.testimage);
345         drawable.setLevel(1);
346         mImageViewRegular.setImageDrawable(drawable);
347         assertEquals(1, mImageViewRegular.getDrawable().getLevel());
348         mImageViewRegular.setImageLevel(3);
349         mImageViewRegular.setImageDrawable(drawable);
350         assertEquals(3, mImageViewRegular.getDrawable().getLevel());
351     }
352 
353     @UiThreadTest
354     @Test
testSetImageBitmap()355     public void testSetImageBitmap() {
356         mImageViewRegular.setImageBitmap(null);
357         // A BitmapDrawable is always created for the ImageView.
358         assertNotNull(mImageViewRegular.getDrawable());
359 
360         final Bitmap bitmap =
361             BitmapFactory.decodeResource(mActivity.getResources(), R.drawable.testimage);
362         mImageViewRegular.setImageBitmap(bitmap);
363         assertTrue(mImageViewRegular.isLayoutRequested());
364         assertNotNull(mImageViewRegular.getDrawable());
365         Drawable imageViewDrawable = mImageViewRegular.getDrawable();
366         BitmapDrawable imageViewBitmap = (BitmapDrawable) imageViewDrawable;
367         WidgetTestUtils.assertEquals(bitmap, imageViewBitmap.getBitmap());
368     }
369 
370     @UiThreadTest
371     @Test
testSetImageState()372     public void testSetImageState() {
373         int[] state = new int[8];
374         mImageViewRegular.setImageState(state, false);
375         assertSame(state, mImageViewRegular.onCreateDrawableState(0));
376     }
377 
378     @UiThreadTest
379     @Test
testSetSelected()380     public void testSetSelected() {
381         assertFalse(mImageViewRegular.isSelected());
382 
383         mImageViewRegular.setSelected(true);
384         assertTrue(mImageViewRegular.isSelected());
385 
386         mImageViewRegular.setSelected(false);
387         assertFalse(mImageViewRegular.isSelected());
388     }
389 
390     @UiThreadTest
391     @Test
testSetImageLevel()392     public void testSetImageLevel() {
393         PaintDrawable drawable = new PaintDrawable();
394         drawable.setLevel(0);
395 
396         mImageViewRegular.setImageDrawable(drawable);
397         mImageViewRegular.setImageLevel(1);
398         assertEquals(1, drawable.getLevel());
399     }
400 
401     @UiThreadTest
402     @Test
testAccessScaleType()403     public void testAccessScaleType() {
404         assertNotNull(mImageViewRegular.getScaleType());
405 
406         mImageViewRegular.setScaleType(ImageView.ScaleType.CENTER);
407         assertEquals(ImageView.ScaleType.CENTER, mImageViewRegular.getScaleType());
408 
409         mImageViewRegular.setScaleType(ImageView.ScaleType.MATRIX);
410         assertEquals(ImageView.ScaleType.MATRIX, mImageViewRegular.getScaleType());
411 
412         mImageViewRegular.setScaleType(ImageView.ScaleType.FIT_START);
413         assertEquals(ImageView.ScaleType.FIT_START, mImageViewRegular.getScaleType());
414 
415         mImageViewRegular.setScaleType(ImageView.ScaleType.FIT_END);
416         assertEquals(ImageView.ScaleType.FIT_END, mImageViewRegular.getScaleType());
417 
418         mImageViewRegular.setScaleType(ImageView.ScaleType.CENTER_CROP);
419         assertEquals(ImageView.ScaleType.CENTER_CROP, mImageViewRegular.getScaleType());
420 
421         mImageViewRegular.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
422         assertEquals(ImageView.ScaleType.CENTER_INSIDE, mImageViewRegular.getScaleType());
423     }
424 
425     @UiThreadTest
426     @Test(expected=NullPointerException.class)
testSetNullScaleType()427     public void testSetNullScaleType() {
428         mImageViewRegular.setScaleType(null);
429     }
430 
431     @UiThreadTest
432     @Test
testAccessImageMatrix()433     public void testAccessImageMatrix() {
434         mImageViewRegular.setImageMatrix(null);
435         assertNotNull(mImageViewRegular.getImageMatrix());
436 
437         final Matrix matrix = new Matrix();
438         mImageViewRegular.setImageMatrix(matrix);
439         assertEquals(matrix, mImageViewRegular.getImageMatrix());
440     }
441 
442     @UiThreadTest
443     @Test
testAccessBaseline()444     public void testAccessBaseline() {
445         mImageViewRegular.setImageDrawable(null);
446         assertNull(mImageViewRegular.getDrawable());
447 
448         final Drawable drawable = mActivity.getDrawable(R.drawable.testimage);
449         mImageViewRegular.setImageDrawable(drawable);
450 
451         assertEquals(-1, mImageViewRegular.getBaseline());
452 
453         mImageViewRegular.setBaseline(50);
454         assertEquals(50, mImageViewRegular.getBaseline());
455 
456         mImageViewRegular.setBaselineAlignBottom(true);
457         assertTrue(mImageViewRegular.getBaselineAlignBottom());
458         assertEquals(mImageViewRegular.getMeasuredHeight(), mImageViewRegular.getBaseline());
459 
460         mImageViewRegular.setBaselineAlignBottom(false);
461         assertFalse(mImageViewRegular.getBaselineAlignBottom());
462         assertEquals(50, mImageViewRegular.getBaseline());
463     }
464 
465     @UiThreadTest
466     @Test
testSetColorFilter1()467     public void testSetColorFilter1() {
468         final Drawable drawable = mActivity.getDrawable(R.drawable.testimage);
469         mImageViewRegular.setImageDrawable(drawable);
470 
471         mImageViewRegular.setColorFilter(null);
472         assertNull(drawable.getColorFilter());
473 
474         mImageViewRegular.setColorFilter(0, PorterDuff.Mode.CLEAR);
475         assertNotNull(drawable.getColorFilter());
476         assertNotNull(mImageViewRegular.getColorFilter());
477     }
478 
479     @UiThreadTest
480     @Test
testSetColorFilterTintBlendMode()481     public void testSetColorFilterTintBlendMode() {
482         final Drawable drawable = mActivity.getDrawable(R.drawable.testimage);
483         mImageViewRegular.setImageDrawable(drawable);
484 
485         mImageViewRegular.setColorFilter(null);
486         assertNull(drawable.getColorFilter());
487 
488         mImageViewRegular.setColorFilter(new BlendModeColorFilter(0, BlendMode.CLEAR));
489         assertNotNull(drawable.getColorFilter());
490         assertNotNull(mImageViewRegular.getColorFilter());
491     }
492 
493     @UiThreadTest
494     @Test
testClearColorFilter()495     public void testClearColorFilter() {
496         final Drawable drawable = mActivity.getDrawable(R.drawable.testimage);
497         mImageViewRegular.setImageDrawable(drawable);
498 
499         ColorFilter cf = new ColorFilter();
500         mImageViewRegular.setColorFilter(cf);
501 
502         mImageViewRegular.clearColorFilter();
503         assertNull(drawable.getColorFilter());
504         assertNull(mImageViewRegular.getColorFilter());
505     }
506 
507     @UiThreadTest
508     @Test
testSetColorFilter2()509     public void testSetColorFilter2() {
510         final Drawable drawable = mActivity.getDrawable(R.drawable.testimage);
511         mImageViewRegular.setImageDrawable(drawable);
512 
513         mImageViewRegular.setColorFilter(null);
514         assertNull(drawable.getColorFilter());
515         assertNull(mImageViewRegular.getColorFilter());
516 
517         ColorFilter cf = new ColorFilter();
518         mImageViewRegular.setColorFilter(cf);
519         assertSame(cf, drawable.getColorFilter());
520         assertSame(cf, mImageViewRegular.getColorFilter());
521     }
522 
523     @Test
testDrawableStateChanged()524     public void testDrawableStateChanged() {
525         MockImageView imageView = spy(new MockImageView(mActivity));
526         Drawable selectorDrawable = mActivity.getDrawable(R.drawable.statelistdrawable);
527         imageView.setImageDrawable(selectorDrawable);
528 
529         // We shouldn't have been called on state change yet
530         verify(imageView, never()).drawableStateChanged();
531         // Mark image view as selected. Since our selector drawable has an "entry" for selected
532         // state, that should cause a call to drawableStateChanged()
533         imageView.setSelected(true);
534         // Test that our image view has indeed called its own drawableStateChanged()
535         verify(imageView, times(1)).drawableStateChanged();
536         // And verify that image view's state matches that of our drawable
537         assertArrayEquals(imageView.getDrawableState(), selectorDrawable.getState());
538     }
539 
540     @Test
testOnCreateDrawableState()541     public void testOnCreateDrawableState() {
542         MockImageView mockImageView = new MockImageView(mActivity);
543 
544         assertArrayEquals(MockImageView.getEnabledStateSet(),
545                 mockImageView.onCreateDrawableState(0));
546 
547         int[] expected = new int[]{1, 2, 3};
548         mockImageView.setImageState(expected, false);
549         assertArrayEquals(expected, mockImageView.onCreateDrawableState(1));
550 
551         mockImageView.setImageState(expected, true);
552     }
553 
554     @Test(expected=IndexOutOfBoundsException.class)
testOnCreateDrawableStateInvalid()555     public void testOnCreateDrawableStateInvalid() {
556         MockImageView mockImageView = (MockImageView) findImageViewById(R.id.imageview_custom);
557         mockImageView.setImageState(new int[] {1, 2, 3}, true);
558         mockImageView.onCreateDrawableState(-1);
559     }
560 
561     @UiThreadTest
562     @Test
testOnDraw()563     public void testOnDraw() {
564         MockImageView mockImageView = (MockImageView) findImageViewById(R.id.imageview_custom);
565 
566         Drawable drawable = spy(mActivity.getDrawable(R.drawable.icon_red));
567         mockImageView.setImageDrawable(drawable);
568         mockImageView.onDraw(new Canvas());
569 
570         verify(drawable, atLeastOnce()).draw(any(Canvas.class));
571     }
572 
573     @UiThreadTest
574     @Test
testOnMeasure()575     public void testOnMeasure() {
576         mImageViewRegular.measure(200, 150);
577         assertTrue(mImageViewRegular.getMeasuredWidth() <= 200);
578         assertTrue(mImageViewRegular.getMeasuredHeight() <= 150);
579     }
580 
581     @Test
testSetFrame()582     public void testSetFrame() {
583         MockImageView mockImageView = spy(new MockImageView(mActivity));
584         verify(mockImageView, never()).onSizeChanged(anyInt(), anyInt(), anyInt(), anyInt());
585 
586         assertTrue(mockImageView.setFrame(5, 10, 100, 200));
587         assertEquals(5, mockImageView.getLeft());
588         assertEquals(10, mockImageView.getTop());
589         assertEquals(100, mockImageView.getRight());
590         assertEquals(200, mockImageView.getBottom());
591         verify(mockImageView, times(1)).onSizeChanged(95, 190, 0, 0);
592 
593         assertFalse(mockImageView.setFrame(5, 10, 100, 200));
594         // Verify that there were no more calls to onSizeChanged (since the new frame is the
595         // same frame as we had before).
596         verify(mockImageView, times(1)).onSizeChanged(anyInt(), anyInt(), anyInt(), anyInt());
597     }
598 
599     @Test
testSetColorFilterPreservesDrawableProperties()600     public void testSetColorFilterPreservesDrawableProperties() {
601         ImageView imageView = new ImageView(InstrumentationRegistry.getTargetContext());
602 
603         int colorAlpha = 128;
604         MockDrawable mockDrawable = new MockDrawable();
605         mockDrawable.setAlpha(colorAlpha);
606         mockDrawable.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
607 
608         imageView.setImageDrawable(mockDrawable);
609 
610         imageView.setColorFilter(Color.RED);
611         assertEquals(colorAlpha, mockDrawable.getAlpha());
612         assertNotNull(mockDrawable.getXfermode());
613     }
614 
615     @Test
testSetColorFilterPreservesDrawablePropertiesTintBlendMode()616     public void testSetColorFilterPreservesDrawablePropertiesTintBlendMode() {
617         ImageView imageView = new ImageView(InstrumentationRegistry.getTargetContext());
618 
619         int colorAlpha = 128;
620         MockDrawable mockDrawable = new MockDrawable();
621         mockDrawable.setAlpha(colorAlpha);
622         mockDrawable.setTintBlendMode(BlendMode.SRC_IN);
623 
624         imageView.setImageDrawable(mockDrawable);
625 
626         imageView.setColorFilter(Color.RED);
627         assertEquals(colorAlpha, mockDrawable.getAlpha());
628         assertNotNull(mockDrawable.getBlendMode());
629     }
630 
631     @Test
testImageViewSetColorFilterPropagatedToDrawable()632     public void testImageViewSetColorFilterPropagatedToDrawable() {
633         ImageView imageView = new ImageView(InstrumentationRegistry.getTargetContext());
634 
635         MockDrawable mockDrawable = new MockDrawable();
636         imageView.setImageDrawable(mockDrawable);
637         imageView.setColorFilter(Color.RED);
638 
639         ColorFilter imageViewColorFilter = imageView.getColorFilter();
640         assertTrue(imageViewColorFilter instanceof PorterDuffColorFilter);
641 
642         PorterDuffColorFilter imageViewPorterDuffFilter =
643                 (PorterDuffColorFilter) imageViewColorFilter;
644         assertEquals(Color.RED, imageViewPorterDuffFilter.getColor());
645         assertEquals(Mode.SRC_ATOP, imageViewPorterDuffFilter.getMode());
646 
647         ColorFilter colorFilter = mockDrawable.getColorFilter();
648         assertTrue(colorFilter instanceof PorterDuffColorFilter);
649 
650         PorterDuffColorFilter porterDuffColorFilter = (PorterDuffColorFilter) colorFilter;
651         assertEquals(Color.RED, porterDuffColorFilter.getColor());
652         assertEquals(PorterDuff.Mode.SRC_ATOP, porterDuffColorFilter.getMode());
653     }
654 
655     @UiThreadTest
656     @Test
testVerifyDrawable()657     public void testVerifyDrawable() {
658         MockImageView mockImageView = (MockImageView) findImageViewById(R.id.imageview_custom);
659 
660         Drawable drawable = new ColorDrawable(0xFFFF0000);
661         mockImageView.setImageDrawable(drawable);
662         Drawable backgroundDrawable = new ColorDrawable(0xFF0000FF);
663         mockImageView.setBackgroundDrawable(backgroundDrawable);
664 
665         assertFalse(mockImageView.verifyDrawable(new ColorDrawable(0xFF00FF00)));
666         assertTrue(mockImageView.verifyDrawable(drawable));
667         assertTrue(mockImageView.verifyDrawable(backgroundDrawable));
668     }
669 
670     @UiThreadTest
671     @Test
testImageTintBasics()672     public void testImageTintBasics() {
673         ImageView imageViewTinted = (ImageView) mActivity.findViewById(R.id.imageview_tint);
674 
675         assertEquals("Image tint inflated correctly",
676                 Color.WHITE, imageViewTinted.getImageTintList().getDefaultColor());
677         assertEquals("Image tint mode inflated correctly",
678                 PorterDuff.Mode.SRC_OVER, imageViewTinted.getImageTintMode());
679 
680         imageViewTinted.setImageTintMode(PorterDuff.Mode.SRC_IN);
681         assertEquals(PorterDuff.Mode.SRC_IN, imageViewTinted.getImageTintMode());
682     }
683 
684     @UiThreadTest
685     @Test
testImageTintBlendModeBasics()686     public void testImageTintBlendModeBasics() {
687         ImageView imageViewTinted = (ImageView) mActivity.findViewById(R.id.imageview_tint);
688 
689         assertEquals("Image tint inflated correctly",
690                 Color.WHITE, imageViewTinted.getImageTintList().getDefaultColor());
691         assertEquals("Image tint mode inflated correctly",
692                 BlendMode.SRC_OVER, imageViewTinted.getImageTintBlendMode());
693 
694         imageViewTinted.setImageTintMode(PorterDuff.Mode.SRC_IN);
695         assertEquals(BlendMode.SRC_IN, imageViewTinted.getImageTintBlendMode());
696     }
697 
698     @UiThreadTest
699     @Test
testImageTintDrawableUpdates()700     public void testImageTintDrawableUpdates() {
701         Drawable drawable = spy(mActivity.getDrawable(R.drawable.icon_red));
702 
703         mImageViewRegular.setImageDrawable(drawable);
704         // No image tint applied by default
705         verify(drawable, never()).setTintList(any(ColorStateList.class));
706 
707         mImageViewRegular.setImageTintList(ColorStateList.valueOf(Color.WHITE));
708         // Image tint applied when setImageTintList() called after setImageDrawable()
709         verify(drawable, times(1)).setTintList(any(ColorStateList.class));
710 
711         mImageViewRegular.setImageDrawable(null);
712         mImageViewRegular.setImageDrawable(drawable);
713         // Image tint applied when setImageTintList() called before setImageDrawable()
714         verify(drawable, times(2)).setTintList(any(ColorStateList.class));
715     }
716 
717     @UiThreadTest
718     @Test
testImageTintVisuals()719     public void testImageTintVisuals() {
720         ImageView imageViewTinted = (ImageView) mActivity.findViewById(
721                 R.id.imageview_tint_with_source);
722 
723         TestUtils.assertAllPixelsOfColor("All pixels should be white", imageViewTinted,
724                 0xFFFFFFFF, 1, false);
725 
726         // Use translucent white tint. Together with SRC_OVER mode (defined in XML) the end
727         // result should be a fully opaque image view with solid fill color in between red
728         // and white.
729         imageViewTinted.setImageTintList(ColorStateList.valueOf(0x80FFFFFF));
730         TestUtils.assertAllPixelsOfColor("All pixels should be light red", imageViewTinted,
731                 0xFFFF8080, 1, false);
732 
733         // Switch to SRC_IN mode. This should completely ignore the original drawable set on
734         // the image view and use the last set tint color (50% alpha white).
735         imageViewTinted.setImageTintMode(PorterDuff.Mode.SRC_IN);
736         TestUtils.assertAllPixelsOfColor("All pixels should be 50% alpha white", imageViewTinted,
737                 0x80FFFFFF, 1, false);
738 
739         // Switch to DST mode. This should completely ignore the last set tint color and use the
740         // the original drawable set on the image view.
741         imageViewTinted.setImageTintMode(PorterDuff.Mode.DST);
742         TestUtils.assertAllPixelsOfColor("All pixels should be red", imageViewTinted,
743                 0xFFFF0000, 1, false);
744     }
745 
746     @UiThreadTest
747     @Test
testImageTintBlendModeVisuals()748     public void testImageTintBlendModeVisuals() {
749         ImageView imageViewTinted = (ImageView) mActivity.findViewById(
750                 R.id.imageview_tint_with_source);
751 
752         TestUtils.assertAllPixelsOfColor("All pixels should be white", imageViewTinted,
753                 0xFFFFFFFF, 1, false);
754 
755         // Use translucent white tint. Together with SRC_OVER mode (defined in XML) the end
756         // result should be a fully opaque image view with solid fill color in between red
757         // and white.
758         imageViewTinted.setImageTintList(ColorStateList.valueOf(0x80FFFFFF));
759         TestUtils.assertAllPixelsOfColor("All pixels should be light red", imageViewTinted,
760                 0xFFFF8080, 1, false);
761 
762         // Switch to SRC_IN mode. This should completely ignore the original drawable set on
763         // the image view and use the last set tint color (50% alpha white).
764         imageViewTinted.setImageTintBlendMode(BlendMode.SRC_IN);
765         TestUtils.assertAllPixelsOfColor("All pixels should be 50% alpha white", imageViewTinted,
766                 0x80FFFFFF, 1, false);
767 
768         // Switch to DST mode. This should completely ignore the last set tint color and use the
769         // the original drawable set on the image view.
770         imageViewTinted.setImageTintBlendMode(BlendMode.DST);
771         TestUtils.assertAllPixelsOfColor("All pixels should be red", imageViewTinted,
772                 0xFFFF0000, 1, false);
773     }
774 
775     @UiThreadTest
776     @Test
testAlpha()777     public void testAlpha() {
778         mImageViewRegular.setImageResource(R.drawable.blue_fill);
779 
780         TestUtils.assertAllPixelsOfColor("All pixels should be blue", mImageViewRegular,
781                 0xFF0000FF, 1, false);
782 
783         mImageViewRegular.setAlpha(128);
784         TestUtils.assertAllPixelsOfColor("All pixels should be 50% alpha blue", mImageViewRegular,
785                 0x800000FF, 1, false);
786 
787         mImageViewRegular.setAlpha(0);
788         TestUtils.assertAllPixelsOfColor("All pixels should be transparent", mImageViewRegular,
789                 0x00000000, 1, false);
790 
791         mImageViewRegular.setAlpha(255);
792         TestUtils.assertAllPixelsOfColor("All pixels should be blue", mImageViewRegular,
793                 0xFF0000FF, 1, false);
794     }
795 
796     @UiThreadTest
797     @Test
testImageAlpha()798     public void testImageAlpha() {
799         mImageViewRegular.setImageResource(R.drawable.blue_fill);
800 
801         assertEquals(255, mImageViewRegular.getImageAlpha());
802         TestUtils.assertAllPixelsOfColor("All pixels should be blue", mImageViewRegular,
803                 0xFF0000FF, 1, false);
804 
805         mImageViewRegular.setImageAlpha(128);
806         assertEquals(128, mImageViewRegular.getImageAlpha());
807         TestUtils.assertAllPixelsOfColor("All pixels should be 50% alpha blue", mImageViewRegular,
808                 0x800000FF, 1, false);
809 
810         mImageViewRegular.setImageAlpha(0);
811         assertEquals(0, mImageViewRegular.getImageAlpha());
812         TestUtils.assertAllPixelsOfColor("All pixels should be transparent", mImageViewRegular,
813                 0x00000000, 1, false);
814 
815         mImageViewRegular.setImageAlpha(255);
816         assertEquals(255, mImageViewRegular.getImageAlpha());
817         TestUtils.assertAllPixelsOfColor("All pixels should be blue", mImageViewRegular,
818                 0xFF0000FF, 1, false);
819     }
820 
821     @UiThreadTest
822     @Test
testAnimateTransform()823     public void testAnimateTransform() {
824         Bitmap bitmap = Bitmap.createBitmap(100, 100, Bitmap.Config.ALPHA_8);
825         mImageViewRegular.setScaleType(ScaleType.FIT_XY);
826         mImageViewRegular.setImageBitmap(bitmap);
827         Rect viewRect = new Rect(0, 0, mImageViewRegular.getWidth(), mImageViewRegular.getHeight());
828         Rect bitmapRect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
829 
830         assertEquals(viewRect, mImageViewRegular.getDrawable().getBounds());
831         assertTrue(mImageViewRegular.getImageMatrix().isIdentity());
832 
833         Matrix matrix = new Matrix();
834         mImageViewRegular.animateTransform(matrix);
835 
836         assertEquals(bitmapRect, mImageViewRegular.getDrawable().getBounds());
837         assertEquals(matrix, mImageViewRegular.getImageMatrix());
838 
839         // clear temporary transformation
840         mImageViewRegular.setImageBitmap(bitmap);
841 
842         assertEquals(viewRect, mImageViewRegular.getDrawable().getBounds());
843         assertTrue(mImageViewRegular.getImageMatrix().isIdentity());
844     }
845 
846     @UiThreadTest
847     @Test
testAnimateTransformWithNullPassed()848     public void testAnimateTransformWithNullPassed() {
849         Bitmap bitmap = Bitmap.createBitmap(100, 100, Bitmap.Config.ALPHA_8);
850         mImageViewRegular.setScaleType(ScaleType.CENTER);
851         mImageViewRegular.setImageBitmap(bitmap);
852         Rect viewRect = new Rect(0, 0, mImageViewRegular.getWidth(), mImageViewRegular.getHeight());
853         Rect bitmapRect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
854 
855         assertEquals(bitmapRect, mImageViewRegular.getDrawable().getBounds());
856         assertFalse(mImageViewRegular.getImageMatrix().isIdentity());
857 
858         mImageViewRegular.animateTransform(null);
859 
860         assertEquals(viewRect, mImageViewRegular.getDrawable().getBounds());
861         assertTrue(mImageViewRegular.getImageMatrix().isIdentity());
862 
863         // clear temporary transformation
864         mImageViewRegular.setImageBitmap(bitmap);
865 
866         assertEquals(bitmapRect, mImageViewRegular.getDrawable().getBounds());
867         assertFalse(mImageViewRegular.getImageMatrix().isIdentity());
868     }
869 
870     public static class MockImageView extends ImageView {
MockImageView(Context context)871         public MockImageView(Context context) {
872             super(context);
873         }
874 
MockImageView(Context context, AttributeSet attrs)875         public MockImageView(Context context, AttributeSet attrs) {
876             super(context, attrs);
877         }
878 
MockImageView(Context context, AttributeSet attrs, int defStyle)879         public MockImageView(Context context, AttributeSet attrs, int defStyle) {
880             super(context, attrs, defStyle);
881         }
882 
getEnabledStateSet()883         public static int[] getEnabledStateSet() {
884             return ENABLED_STATE_SET;
885         }
886 
887         @Override
drawableStateChanged()888         protected void drawableStateChanged() {
889             super.drawableStateChanged();
890         }
891 
892         @Override
onDraw(Canvas canvas)893         protected void onDraw(Canvas canvas) {
894             super.onDraw(canvas);
895         }
896 
897         @Override
onMeasure(int widthMeasureSpec, int heightMeasureSpec)898         protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
899             super.onMeasure(widthMeasureSpec, heightMeasureSpec);
900         }
901 
902         @Override
onSetAlpha(int alpha)903         protected boolean onSetAlpha(int alpha) {
904             return super.onSetAlpha(alpha);
905         }
906 
907         @Override
setFrame(int l, int t, int r, int b)908         protected boolean setFrame(int l, int t, int r, int b) {
909             return super.setFrame(l, t, r, b);
910         }
911 
912         @Override
verifyDrawable(Drawable dr)913         protected boolean verifyDrawable(Drawable dr) {
914             return super.verifyDrawable(dr);
915         }
916 
onSizeChanged(int w, int h, int oldw, int oldh)917         protected void onSizeChanged(int w, int h, int oldw, int oldh) {
918             super.onSizeChanged(w, h, oldw, oldh);
919         }
920     }
921 
922     public static class MockDrawable extends Drawable {
923 
924         private ColorFilter mFilter;
925         private int mAlpha;
926         private Xfermode mXfermode;
927         private BlendMode mBlendMode;
928 
929         @Override
draw(Canvas canvas)930         public void draw(Canvas canvas) {
931             // NO-OP
932         }
933 
934         @Override
setAlpha(int alpha)935         public void setAlpha(int alpha) {
936             mAlpha = alpha;
937         }
938 
getAlpha()939         public int getAlpha() {
940             return mAlpha;
941         }
942 
943         @Override
setColorFilter(ColorFilter colorFilter)944         public void setColorFilter(ColorFilter colorFilter) {
945             mFilter = colorFilter;
946         }
947 
948         @Override
setXfermode(Xfermode mode)949         public void setXfermode(Xfermode mode) {
950             mXfermode = mode;
951         }
952 
953         @Override
setTintBlendMode(BlendMode mode)954         public void setTintBlendMode(BlendMode mode) {
955             mBlendMode = mode;
956         }
957 
getXfermode()958         public @Nullable Xfermode getXfermode() {
959             return mXfermode;
960         }
961 
getBlendMode()962         public @Nullable BlendMode getBlendMode() {
963             return mBlendMode;
964         }
965 
966         @Override
getColorFilter()967         public @Nullable ColorFilter getColorFilter() {
968             return mFilter;
969         }
970 
971         @Override
getOpacity()972         public int getOpacity() {
973             return PixelFormat.TRANSLUCENT;
974         }
975     }
976 }
977