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 mImageViewRegular.setImageDrawable(drawable); 328 assertTrue(mImageViewRegular.isLayoutRequested()); 329 assertNotNull(mImageViewRegular.getDrawable()); 330 BitmapDrawable testimageBitmap = (BitmapDrawable) drawable; 331 Drawable imageViewDrawable = mImageViewRegular.getDrawable(); 332 BitmapDrawable imageViewBitmap = (BitmapDrawable) imageViewDrawable; 333 WidgetTestUtils.assertEquals(testimageBitmap.getBitmap(), imageViewBitmap.getBitmap()); 334 } 335 336 @UiThreadTest 337 @Test testSetImageBitmap()338 public void testSetImageBitmap() { 339 mImageViewRegular.setImageBitmap(null); 340 // A BitmapDrawable is always created for the ImageView. 341 assertNotNull(mImageViewRegular.getDrawable()); 342 343 final Bitmap bitmap = 344 BitmapFactory.decodeResource(mActivity.getResources(), R.drawable.testimage); 345 mImageViewRegular.setImageBitmap(bitmap); 346 assertTrue(mImageViewRegular.isLayoutRequested()); 347 assertNotNull(mImageViewRegular.getDrawable()); 348 Drawable imageViewDrawable = mImageViewRegular.getDrawable(); 349 BitmapDrawable imageViewBitmap = (BitmapDrawable) imageViewDrawable; 350 WidgetTestUtils.assertEquals(bitmap, imageViewBitmap.getBitmap()); 351 } 352 353 @UiThreadTest 354 @Test testSetImageState()355 public void testSetImageState() { 356 int[] state = new int[8]; 357 mImageViewRegular.setImageState(state, false); 358 assertSame(state, mImageViewRegular.onCreateDrawableState(0)); 359 } 360 361 @UiThreadTest 362 @Test testSetSelected()363 public void testSetSelected() { 364 assertFalse(mImageViewRegular.isSelected()); 365 366 mImageViewRegular.setSelected(true); 367 assertTrue(mImageViewRegular.isSelected()); 368 369 mImageViewRegular.setSelected(false); 370 assertFalse(mImageViewRegular.isSelected()); 371 } 372 373 @UiThreadTest 374 @Test testSetImageLevel()375 public void testSetImageLevel() { 376 PaintDrawable drawable = new PaintDrawable(); 377 drawable.setLevel(0); 378 379 mImageViewRegular.setImageDrawable(drawable); 380 mImageViewRegular.setImageLevel(1); 381 assertEquals(1, drawable.getLevel()); 382 } 383 384 @UiThreadTest 385 @Test testAccessScaleType()386 public void testAccessScaleType() { 387 assertNotNull(mImageViewRegular.getScaleType()); 388 389 mImageViewRegular.setScaleType(ImageView.ScaleType.CENTER); 390 assertEquals(ImageView.ScaleType.CENTER, mImageViewRegular.getScaleType()); 391 392 mImageViewRegular.setScaleType(ImageView.ScaleType.MATRIX); 393 assertEquals(ImageView.ScaleType.MATRIX, mImageViewRegular.getScaleType()); 394 395 mImageViewRegular.setScaleType(ImageView.ScaleType.FIT_START); 396 assertEquals(ImageView.ScaleType.FIT_START, mImageViewRegular.getScaleType()); 397 398 mImageViewRegular.setScaleType(ImageView.ScaleType.FIT_END); 399 assertEquals(ImageView.ScaleType.FIT_END, mImageViewRegular.getScaleType()); 400 401 mImageViewRegular.setScaleType(ImageView.ScaleType.CENTER_CROP); 402 assertEquals(ImageView.ScaleType.CENTER_CROP, mImageViewRegular.getScaleType()); 403 404 mImageViewRegular.setScaleType(ImageView.ScaleType.CENTER_INSIDE); 405 assertEquals(ImageView.ScaleType.CENTER_INSIDE, mImageViewRegular.getScaleType()); 406 } 407 408 @UiThreadTest 409 @Test(expected=NullPointerException.class) testSetNullScaleType()410 public void testSetNullScaleType() { 411 mImageViewRegular.setScaleType(null); 412 } 413 414 @UiThreadTest 415 @Test testAccessImageMatrix()416 public void testAccessImageMatrix() { 417 mImageViewRegular.setImageMatrix(null); 418 assertNotNull(mImageViewRegular.getImageMatrix()); 419 420 final Matrix matrix = new Matrix(); 421 mImageViewRegular.setImageMatrix(matrix); 422 assertEquals(matrix, mImageViewRegular.getImageMatrix()); 423 } 424 425 @UiThreadTest 426 @Test testAccessBaseline()427 public void testAccessBaseline() { 428 mImageViewRegular.setImageDrawable(null); 429 assertNull(mImageViewRegular.getDrawable()); 430 431 final Drawable drawable = mActivity.getDrawable(R.drawable.testimage); 432 mImageViewRegular.setImageDrawable(drawable); 433 434 assertEquals(-1, mImageViewRegular.getBaseline()); 435 436 mImageViewRegular.setBaseline(50); 437 assertEquals(50, mImageViewRegular.getBaseline()); 438 439 mImageViewRegular.setBaselineAlignBottom(true); 440 assertTrue(mImageViewRegular.getBaselineAlignBottom()); 441 assertEquals(mImageViewRegular.getMeasuredHeight(), mImageViewRegular.getBaseline()); 442 443 mImageViewRegular.setBaselineAlignBottom(false); 444 assertFalse(mImageViewRegular.getBaselineAlignBottom()); 445 assertEquals(50, mImageViewRegular.getBaseline()); 446 } 447 448 @UiThreadTest 449 @Test testSetColorFilter1()450 public void testSetColorFilter1() { 451 final Drawable drawable = mActivity.getDrawable(R.drawable.testimage); 452 mImageViewRegular.setImageDrawable(drawable); 453 454 mImageViewRegular.setColorFilter(null); 455 assertNull(drawable.getColorFilter()); 456 457 mImageViewRegular.setColorFilter(0, PorterDuff.Mode.CLEAR); 458 assertNotNull(drawable.getColorFilter()); 459 assertNotNull(mImageViewRegular.getColorFilter()); 460 } 461 462 @UiThreadTest 463 @Test testSetColorFilterTintBlendMode()464 public void testSetColorFilterTintBlendMode() { 465 final Drawable drawable = mActivity.getDrawable(R.drawable.testimage); 466 mImageViewRegular.setImageDrawable(drawable); 467 468 mImageViewRegular.setColorFilter(null); 469 assertNull(drawable.getColorFilter()); 470 471 mImageViewRegular.setColorFilter(new BlendModeColorFilter(0, BlendMode.CLEAR)); 472 assertNotNull(drawable.getColorFilter()); 473 assertNotNull(mImageViewRegular.getColorFilter()); 474 } 475 476 @UiThreadTest 477 @Test testClearColorFilter()478 public void testClearColorFilter() { 479 final Drawable drawable = mActivity.getDrawable(R.drawable.testimage); 480 mImageViewRegular.setImageDrawable(drawable); 481 482 ColorFilter cf = new ColorFilter(); 483 mImageViewRegular.setColorFilter(cf); 484 485 mImageViewRegular.clearColorFilter(); 486 assertNull(drawable.getColorFilter()); 487 assertNull(mImageViewRegular.getColorFilter()); 488 } 489 490 @UiThreadTest 491 @Test testSetColorFilter2()492 public void testSetColorFilter2() { 493 final Drawable drawable = mActivity.getDrawable(R.drawable.testimage); 494 mImageViewRegular.setImageDrawable(drawable); 495 496 mImageViewRegular.setColorFilter(null); 497 assertNull(drawable.getColorFilter()); 498 assertNull(mImageViewRegular.getColorFilter()); 499 500 ColorFilter cf = new ColorFilter(); 501 mImageViewRegular.setColorFilter(cf); 502 assertSame(cf, drawable.getColorFilter()); 503 assertSame(cf, mImageViewRegular.getColorFilter()); 504 } 505 506 @Test testDrawableStateChanged()507 public void testDrawableStateChanged() { 508 MockImageView imageView = spy(new MockImageView(mActivity)); 509 Drawable selectorDrawable = mActivity.getDrawable(R.drawable.statelistdrawable); 510 imageView.setImageDrawable(selectorDrawable); 511 512 // We shouldn't have been called on state change yet 513 verify(imageView, never()).drawableStateChanged(); 514 // Mark image view as selected. Since our selector drawable has an "entry" for selected 515 // state, that should cause a call to drawableStateChanged() 516 imageView.setSelected(true); 517 // Test that our image view has indeed called its own drawableStateChanged() 518 verify(imageView, times(1)).drawableStateChanged(); 519 // And verify that image view's state matches that of our drawable 520 assertArrayEquals(imageView.getDrawableState(), selectorDrawable.getState()); 521 } 522 523 @Test testOnCreateDrawableState()524 public void testOnCreateDrawableState() { 525 MockImageView mockImageView = new MockImageView(mActivity); 526 527 assertArrayEquals(MockImageView.getEnabledStateSet(), 528 mockImageView.onCreateDrawableState(0)); 529 530 int[] expected = new int[]{1, 2, 3}; 531 mockImageView.setImageState(expected, false); 532 assertArrayEquals(expected, mockImageView.onCreateDrawableState(1)); 533 534 mockImageView.setImageState(expected, true); 535 } 536 537 @Test(expected=IndexOutOfBoundsException.class) testOnCreateDrawableStateInvalid()538 public void testOnCreateDrawableStateInvalid() { 539 MockImageView mockImageView = (MockImageView) findImageViewById(R.id.imageview_custom); 540 mockImageView.setImageState(new int[] {1, 2, 3}, true); 541 mockImageView.onCreateDrawableState(-1); 542 } 543 544 @UiThreadTest 545 @Test testOnDraw()546 public void testOnDraw() { 547 MockImageView mockImageView = (MockImageView) findImageViewById(R.id.imageview_custom); 548 549 Drawable drawable = spy(mActivity.getDrawable(R.drawable.icon_red)); 550 mockImageView.setImageDrawable(drawable); 551 mockImageView.onDraw(new Canvas()); 552 553 verify(drawable, atLeastOnce()).draw(any(Canvas.class)); 554 } 555 556 @UiThreadTest 557 @Test testOnMeasure()558 public void testOnMeasure() { 559 mImageViewRegular.measure(200, 150); 560 assertTrue(mImageViewRegular.getMeasuredWidth() <= 200); 561 assertTrue(mImageViewRegular.getMeasuredHeight() <= 150); 562 } 563 564 @Test testSetFrame()565 public void testSetFrame() { 566 MockImageView mockImageView = spy(new MockImageView(mActivity)); 567 verify(mockImageView, never()).onSizeChanged(anyInt(), anyInt(), anyInt(), anyInt()); 568 569 assertTrue(mockImageView.setFrame(5, 10, 100, 200)); 570 assertEquals(5, mockImageView.getLeft()); 571 assertEquals(10, mockImageView.getTop()); 572 assertEquals(100, mockImageView.getRight()); 573 assertEquals(200, mockImageView.getBottom()); 574 verify(mockImageView, times(1)).onSizeChanged(95, 190, 0, 0); 575 576 assertFalse(mockImageView.setFrame(5, 10, 100, 200)); 577 // Verify that there were no more calls to onSizeChanged (since the new frame is the 578 // same frame as we had before). 579 verify(mockImageView, times(1)).onSizeChanged(anyInt(), anyInt(), anyInt(), anyInt()); 580 } 581 582 @Test testSetColorFilterPreservesDrawableProperties()583 public void testSetColorFilterPreservesDrawableProperties() { 584 ImageView imageView = new ImageView(InstrumentationRegistry.getTargetContext()); 585 586 int colorAlpha = 128; 587 MockDrawable mockDrawable = new MockDrawable(); 588 mockDrawable.setAlpha(colorAlpha); 589 mockDrawable.setXfermode(new PorterDuffXfermode(Mode.SRC_IN)); 590 591 imageView.setImageDrawable(mockDrawable); 592 593 imageView.setColorFilter(Color.RED); 594 assertEquals(colorAlpha, mockDrawable.getAlpha()); 595 assertNotNull(mockDrawable.getXfermode()); 596 } 597 598 @Test testSetColorFilterPreservesDrawablePropertiesTintBlendMode()599 public void testSetColorFilterPreservesDrawablePropertiesTintBlendMode() { 600 ImageView imageView = new ImageView(InstrumentationRegistry.getTargetContext()); 601 602 int colorAlpha = 128; 603 MockDrawable mockDrawable = new MockDrawable(); 604 mockDrawable.setAlpha(colorAlpha); 605 mockDrawable.setTintBlendMode(BlendMode.SRC_IN); 606 607 imageView.setImageDrawable(mockDrawable); 608 609 imageView.setColorFilter(Color.RED); 610 assertEquals(colorAlpha, mockDrawable.getAlpha()); 611 assertNotNull(mockDrawable.getBlendMode()); 612 } 613 614 @Test testImageViewSetColorFilterPropagatedToDrawable()615 public void testImageViewSetColorFilterPropagatedToDrawable() { 616 ImageView imageView = new ImageView(InstrumentationRegistry.getTargetContext()); 617 618 MockDrawable mockDrawable = new MockDrawable(); 619 imageView.setImageDrawable(mockDrawable); 620 imageView.setColorFilter(Color.RED); 621 622 ColorFilter imageViewColorFilter = imageView.getColorFilter(); 623 assertTrue(imageViewColorFilter instanceof PorterDuffColorFilter); 624 625 PorterDuffColorFilter imageViewPorterDuffFilter = 626 (PorterDuffColorFilter) imageViewColorFilter; 627 assertEquals(Color.RED, imageViewPorterDuffFilter.getColor()); 628 assertEquals(Mode.SRC_ATOP, imageViewPorterDuffFilter.getMode()); 629 630 ColorFilter colorFilter = mockDrawable.getColorFilter(); 631 assertTrue(colorFilter instanceof PorterDuffColorFilter); 632 633 PorterDuffColorFilter porterDuffColorFilter = (PorterDuffColorFilter) colorFilter; 634 assertEquals(Color.RED, porterDuffColorFilter.getColor()); 635 assertEquals(PorterDuff.Mode.SRC_ATOP, porterDuffColorFilter.getMode()); 636 } 637 638 @UiThreadTest 639 @Test testVerifyDrawable()640 public void testVerifyDrawable() { 641 MockImageView mockImageView = (MockImageView) findImageViewById(R.id.imageview_custom); 642 643 Drawable drawable = new ColorDrawable(0xFFFF0000); 644 mockImageView.setImageDrawable(drawable); 645 Drawable backgroundDrawable = new ColorDrawable(0xFF0000FF); 646 mockImageView.setBackgroundDrawable(backgroundDrawable); 647 648 assertFalse(mockImageView.verifyDrawable(new ColorDrawable(0xFF00FF00))); 649 assertTrue(mockImageView.verifyDrawable(drawable)); 650 assertTrue(mockImageView.verifyDrawable(backgroundDrawable)); 651 } 652 653 @UiThreadTest 654 @Test testImageTintBasics()655 public void testImageTintBasics() { 656 ImageView imageViewTinted = (ImageView) mActivity.findViewById(R.id.imageview_tint); 657 658 assertEquals("Image tint inflated correctly", 659 Color.WHITE, imageViewTinted.getImageTintList().getDefaultColor()); 660 assertEquals("Image tint mode inflated correctly", 661 PorterDuff.Mode.SRC_OVER, imageViewTinted.getImageTintMode()); 662 663 imageViewTinted.setImageTintMode(PorterDuff.Mode.SRC_IN); 664 assertEquals(PorterDuff.Mode.SRC_IN, imageViewTinted.getImageTintMode()); 665 } 666 667 @UiThreadTest 668 @Test testImageTintBlendModeBasics()669 public void testImageTintBlendModeBasics() { 670 ImageView imageViewTinted = (ImageView) mActivity.findViewById(R.id.imageview_tint); 671 672 assertEquals("Image tint inflated correctly", 673 Color.WHITE, imageViewTinted.getImageTintList().getDefaultColor()); 674 assertEquals("Image tint mode inflated correctly", 675 BlendMode.SRC_OVER, imageViewTinted.getImageTintBlendMode()); 676 677 imageViewTinted.setImageTintMode(PorterDuff.Mode.SRC_IN); 678 assertEquals(BlendMode.SRC_IN, imageViewTinted.getImageTintBlendMode()); 679 } 680 681 @UiThreadTest 682 @Test testImageTintDrawableUpdates()683 public void testImageTintDrawableUpdates() { 684 Drawable drawable = spy(mActivity.getDrawable(R.drawable.icon_red)); 685 686 mImageViewRegular.setImageDrawable(drawable); 687 // No image tint applied by default 688 verify(drawable, never()).setTintList(any(ColorStateList.class)); 689 690 mImageViewRegular.setImageTintList(ColorStateList.valueOf(Color.WHITE)); 691 // Image tint applied when setImageTintList() called after setImageDrawable() 692 verify(drawable, times(1)).setTintList(any(ColorStateList.class)); 693 694 mImageViewRegular.setImageDrawable(null); 695 mImageViewRegular.setImageDrawable(drawable); 696 // Image tint applied when setImageTintList() called before setImageDrawable() 697 verify(drawable, times(2)).setTintList(any(ColorStateList.class)); 698 } 699 700 @UiThreadTest 701 @Test testImageTintVisuals()702 public void testImageTintVisuals() { 703 ImageView imageViewTinted = (ImageView) mActivity.findViewById( 704 R.id.imageview_tint_with_source); 705 706 TestUtils.assertAllPixelsOfColor("All pixels should be white", imageViewTinted, 707 0xFFFFFFFF, 1, false); 708 709 // Use translucent white tint. Together with SRC_OVER mode (defined in XML) the end 710 // result should be a fully opaque image view with solid fill color in between red 711 // and white. 712 imageViewTinted.setImageTintList(ColorStateList.valueOf(0x80FFFFFF)); 713 TestUtils.assertAllPixelsOfColor("All pixels should be light red", imageViewTinted, 714 0xFFFF8080, 1, false); 715 716 // Switch to SRC_IN mode. This should completely ignore the original drawable set on 717 // the image view and use the last set tint color (50% alpha white). 718 imageViewTinted.setImageTintMode(PorterDuff.Mode.SRC_IN); 719 TestUtils.assertAllPixelsOfColor("All pixels should be 50% alpha white", imageViewTinted, 720 0x80FFFFFF, 1, false); 721 722 // Switch to DST mode. This should completely ignore the last set tint color and use the 723 // the original drawable set on the image view. 724 imageViewTinted.setImageTintMode(PorterDuff.Mode.DST); 725 TestUtils.assertAllPixelsOfColor("All pixels should be red", imageViewTinted, 726 0xFFFF0000, 1, false); 727 } 728 729 @UiThreadTest 730 @Test testImageTintBlendModeVisuals()731 public void testImageTintBlendModeVisuals() { 732 ImageView imageViewTinted = (ImageView) mActivity.findViewById( 733 R.id.imageview_tint_with_source); 734 735 TestUtils.assertAllPixelsOfColor("All pixels should be white", imageViewTinted, 736 0xFFFFFFFF, 1, false); 737 738 // Use translucent white tint. Together with SRC_OVER mode (defined in XML) the end 739 // result should be a fully opaque image view with solid fill color in between red 740 // and white. 741 imageViewTinted.setImageTintList(ColorStateList.valueOf(0x80FFFFFF)); 742 TestUtils.assertAllPixelsOfColor("All pixels should be light red", imageViewTinted, 743 0xFFFF8080, 1, false); 744 745 // Switch to SRC_IN mode. This should completely ignore the original drawable set on 746 // the image view and use the last set tint color (50% alpha white). 747 imageViewTinted.setImageTintBlendMode(BlendMode.SRC_IN); 748 TestUtils.assertAllPixelsOfColor("All pixels should be 50% alpha white", imageViewTinted, 749 0x80FFFFFF, 1, false); 750 751 // Switch to DST mode. This should completely ignore the last set tint color and use the 752 // the original drawable set on the image view. 753 imageViewTinted.setImageTintBlendMode(BlendMode.DST); 754 TestUtils.assertAllPixelsOfColor("All pixels should be red", imageViewTinted, 755 0xFFFF0000, 1, false); 756 } 757 758 @UiThreadTest 759 @Test testAlpha()760 public void testAlpha() { 761 mImageViewRegular.setImageResource(R.drawable.blue_fill); 762 763 TestUtils.assertAllPixelsOfColor("All pixels should be blue", mImageViewRegular, 764 0xFF0000FF, 1, false); 765 766 mImageViewRegular.setAlpha(128); 767 TestUtils.assertAllPixelsOfColor("All pixels should be 50% alpha blue", mImageViewRegular, 768 0x800000FF, 1, false); 769 770 mImageViewRegular.setAlpha(0); 771 TestUtils.assertAllPixelsOfColor("All pixels should be transparent", mImageViewRegular, 772 0x00000000, 1, false); 773 774 mImageViewRegular.setAlpha(255); 775 TestUtils.assertAllPixelsOfColor("All pixels should be blue", mImageViewRegular, 776 0xFF0000FF, 1, false); 777 } 778 779 @UiThreadTest 780 @Test testImageAlpha()781 public void testImageAlpha() { 782 mImageViewRegular.setImageResource(R.drawable.blue_fill); 783 784 assertEquals(255, mImageViewRegular.getImageAlpha()); 785 TestUtils.assertAllPixelsOfColor("All pixels should be blue", mImageViewRegular, 786 0xFF0000FF, 1, false); 787 788 mImageViewRegular.setImageAlpha(128); 789 assertEquals(128, mImageViewRegular.getImageAlpha()); 790 TestUtils.assertAllPixelsOfColor("All pixels should be 50% alpha blue", mImageViewRegular, 791 0x800000FF, 1, false); 792 793 mImageViewRegular.setImageAlpha(0); 794 assertEquals(0, mImageViewRegular.getImageAlpha()); 795 TestUtils.assertAllPixelsOfColor("All pixels should be transparent", mImageViewRegular, 796 0x00000000, 1, false); 797 798 mImageViewRegular.setImageAlpha(255); 799 assertEquals(255, mImageViewRegular.getImageAlpha()); 800 TestUtils.assertAllPixelsOfColor("All pixels should be blue", mImageViewRegular, 801 0xFF0000FF, 1, false); 802 } 803 804 @UiThreadTest 805 @Test testAnimateTransform()806 public void testAnimateTransform() { 807 Bitmap bitmap = Bitmap.createBitmap(100, 100, Bitmap.Config.ALPHA_8); 808 mImageViewRegular.setScaleType(ScaleType.FIT_XY); 809 mImageViewRegular.setImageBitmap(bitmap); 810 Rect viewRect = new Rect(0, 0, mImageViewRegular.getWidth(), mImageViewRegular.getHeight()); 811 Rect bitmapRect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()); 812 813 assertEquals(viewRect, mImageViewRegular.getDrawable().getBounds()); 814 assertTrue(mImageViewRegular.getImageMatrix().isIdentity()); 815 816 Matrix matrix = new Matrix(); 817 mImageViewRegular.animateTransform(matrix); 818 819 assertEquals(bitmapRect, mImageViewRegular.getDrawable().getBounds()); 820 assertEquals(matrix, mImageViewRegular.getImageMatrix()); 821 822 // clear temporary transformation 823 mImageViewRegular.setImageBitmap(bitmap); 824 825 assertEquals(viewRect, mImageViewRegular.getDrawable().getBounds()); 826 assertTrue(mImageViewRegular.getImageMatrix().isIdentity()); 827 } 828 829 @UiThreadTest 830 @Test testAnimateTransformWithNullPassed()831 public void testAnimateTransformWithNullPassed() { 832 Bitmap bitmap = Bitmap.createBitmap(100, 100, Bitmap.Config.ALPHA_8); 833 mImageViewRegular.setScaleType(ScaleType.CENTER); 834 mImageViewRegular.setImageBitmap(bitmap); 835 Rect viewRect = new Rect(0, 0, mImageViewRegular.getWidth(), mImageViewRegular.getHeight()); 836 Rect bitmapRect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()); 837 838 assertEquals(bitmapRect, mImageViewRegular.getDrawable().getBounds()); 839 assertFalse(mImageViewRegular.getImageMatrix().isIdentity()); 840 841 mImageViewRegular.animateTransform(null); 842 843 assertEquals(viewRect, mImageViewRegular.getDrawable().getBounds()); 844 assertTrue(mImageViewRegular.getImageMatrix().isIdentity()); 845 846 // clear temporary transformation 847 mImageViewRegular.setImageBitmap(bitmap); 848 849 assertEquals(bitmapRect, mImageViewRegular.getDrawable().getBounds()); 850 assertFalse(mImageViewRegular.getImageMatrix().isIdentity()); 851 } 852 853 public static class MockImageView extends ImageView { MockImageView(Context context)854 public MockImageView(Context context) { 855 super(context); 856 } 857 MockImageView(Context context, AttributeSet attrs)858 public MockImageView(Context context, AttributeSet attrs) { 859 super(context, attrs); 860 } 861 MockImageView(Context context, AttributeSet attrs, int defStyle)862 public MockImageView(Context context, AttributeSet attrs, int defStyle) { 863 super(context, attrs, defStyle); 864 } 865 getEnabledStateSet()866 public static int[] getEnabledStateSet() { 867 return ENABLED_STATE_SET; 868 } 869 870 @Override drawableStateChanged()871 protected void drawableStateChanged() { 872 super.drawableStateChanged(); 873 } 874 875 @Override onDraw(Canvas canvas)876 protected void onDraw(Canvas canvas) { 877 super.onDraw(canvas); 878 } 879 880 @Override onMeasure(int widthMeasureSpec, int heightMeasureSpec)881 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 882 super.onMeasure(widthMeasureSpec, heightMeasureSpec); 883 } 884 885 @Override onSetAlpha(int alpha)886 protected boolean onSetAlpha(int alpha) { 887 return super.onSetAlpha(alpha); 888 } 889 890 @Override setFrame(int l, int t, int r, int b)891 protected boolean setFrame(int l, int t, int r, int b) { 892 return super.setFrame(l, t, r, b); 893 } 894 895 @Override verifyDrawable(Drawable dr)896 protected boolean verifyDrawable(Drawable dr) { 897 return super.verifyDrawable(dr); 898 } 899 onSizeChanged(int w, int h, int oldw, int oldh)900 protected void onSizeChanged(int w, int h, int oldw, int oldh) { 901 super.onSizeChanged(w, h, oldw, oldh); 902 } 903 } 904 905 public static class MockDrawable extends Drawable { 906 907 private ColorFilter mFilter; 908 private int mAlpha; 909 private Xfermode mXfermode; 910 private BlendMode mBlendMode; 911 912 @Override draw(Canvas canvas)913 public void draw(Canvas canvas) { 914 // NO-OP 915 } 916 917 @Override setAlpha(int alpha)918 public void setAlpha(int alpha) { 919 mAlpha = alpha; 920 } 921 getAlpha()922 public int getAlpha() { 923 return mAlpha; 924 } 925 926 @Override setColorFilter(ColorFilter colorFilter)927 public void setColorFilter(ColorFilter colorFilter) { 928 mFilter = colorFilter; 929 } 930 931 @Override setXfermode(Xfermode mode)932 public void setXfermode(Xfermode mode) { 933 mXfermode = mode; 934 } 935 936 @Override setTintBlendMode(BlendMode mode)937 public void setTintBlendMode(BlendMode mode) { 938 mBlendMode = mode; 939 } 940 getXfermode()941 public @Nullable Xfermode getXfermode() { 942 return mXfermode; 943 } 944 getBlendMode()945 public @Nullable BlendMode getBlendMode() { 946 return mBlendMode; 947 } 948 949 @Override getColorFilter()950 public @Nullable ColorFilter getColorFilter() { 951 return mFilter; 952 } 953 954 @Override getOpacity()955 public int getOpacity() { 956 return PixelFormat.TRANSLUCENT; 957 } 958 } 959 } 960