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