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