1 /* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.graphics.drawable.cts; 18 19 import static org.junit.Assert.assertEquals; 20 import static org.junit.Assert.assertFalse; 21 import static org.junit.Assert.assertNotNull; 22 import static org.junit.Assert.assertNotSame; 23 import static org.junit.Assert.assertNull; 24 import static org.junit.Assert.assertSame; 25 import static org.junit.Assert.assertTrue; 26 import static org.junit.Assert.fail; 27 28 import android.content.Context; 29 import android.content.res.Resources; 30 import android.content.res.XmlResourceParser; 31 import android.graphics.Bitmap; 32 import android.graphics.Bitmap.Config; 33 import android.graphics.BitmapFactory; 34 import android.graphics.BlendMode; 35 import android.graphics.Canvas; 36 import android.graphics.Color; 37 import android.graphics.ColorFilter; 38 import android.graphics.Insets; 39 import android.graphics.Paint; 40 import android.graphics.PixelFormat; 41 import android.graphics.PorterDuff.Mode; 42 import android.graphics.Shader; 43 import android.graphics.Shader.TileMode; 44 import android.graphics.cts.R; 45 import android.graphics.drawable.BitmapDrawable; 46 import android.graphics.drawable.Drawable.ConstantState; 47 import android.util.AttributeSet; 48 import android.view.Gravity; 49 50 import androidx.test.InstrumentationRegistry; 51 import androidx.test.filters.SmallTest; 52 import androidx.test.runner.AndroidJUnit4; 53 54 import org.junit.Before; 55 import org.junit.Test; 56 import org.junit.runner.RunWith; 57 import org.xmlpull.v1.XmlPullParserException; 58 59 import java.io.ByteArrayInputStream; 60 import java.io.IOException; 61 import java.io.InputStream; 62 63 @SmallTest 64 @RunWith(AndroidJUnit4.class) 65 public class BitmapDrawableTest { 66 // A small value is actually making sure that the values are matching 67 // exactly with the golden image. 68 // We can increase the threshold if the Skia is drawing with some variance 69 // on different devices. So far, the tests show they are matching correctly. 70 private static final float PIXEL_ERROR_THRESHOLD = 0.03f; 71 private static final float PIXEL_ERROR_COUNT_THRESHOLD = 0.005f; 72 73 // Set true to generate golden images, false for normal tests. 74 private static final boolean DBG_DUMP_PNG = false; 75 76 // The target context. 77 private Context mContext; 78 79 @Before 80 public void setup() { 81 mContext = InstrumentationRegistry.getTargetContext(); 82 } 83 84 @SuppressWarnings("deprecation") 85 @Test 86 public void testConstructor() { 87 // TODO: should default paint flags be left as an untested implementation detail? 88 final int defaultPaintFlags = Paint.FILTER_BITMAP_FLAG | Paint.DITHER_FLAG | 89 Paint.DEV_KERN_TEXT_FLAG | Paint.EMBEDDED_BITMAP_TEXT_FLAG; 90 BitmapDrawable bitmapDrawable = new BitmapDrawable(); 91 assertNotNull(bitmapDrawable.getPaint()); 92 assertEquals(defaultPaintFlags, 93 bitmapDrawable.getPaint().getFlags()); 94 assertNull(bitmapDrawable.getBitmap()); 95 96 Bitmap bitmap = Bitmap.createBitmap(200, 300, Config.ARGB_8888); 97 bitmapDrawable = new BitmapDrawable(bitmap); 98 assertNotNull(bitmapDrawable.getPaint()); 99 assertEquals(defaultPaintFlags, 100 bitmapDrawable.getPaint().getFlags()); 101 assertEquals(bitmap, bitmapDrawable.getBitmap()); 102 103 new BitmapDrawable(mContext.getResources()); 104 105 new BitmapDrawable(mContext.getResources(), bitmap); 106 107 new BitmapDrawable(mContext.getFilesDir().getPath()); 108 109 new BitmapDrawable(new ByteArrayInputStream("test constructor".getBytes())); 110 111 // exceptional test 112 new BitmapDrawable((Bitmap) null); 113 114 new BitmapDrawable(mContext.getResources(), (String) null); 115 116 new BitmapDrawable((String) null); 117 118 new BitmapDrawable(mContext.getResources(), (InputStream) null); 119 120 new BitmapDrawable((InputStream) null); 121 } 122 123 @Test 124 public void testAccessGravity() { 125 InputStream source = mContext.getResources().openRawResource(R.raw.testimage); 126 BitmapDrawable bitmapDrawable = new BitmapDrawable(source); 127 128 assertEquals(Gravity.FILL, bitmapDrawable.getGravity()); 129 130 bitmapDrawable.setGravity(Gravity.CENTER); 131 assertEquals(Gravity.CENTER, bitmapDrawable.getGravity()); 132 133 bitmapDrawable.setGravity(-1); 134 assertEquals(-1, bitmapDrawable.getGravity()); 135 136 bitmapDrawable.setGravity(Integer.MAX_VALUE); 137 assertEquals(Integer.MAX_VALUE, bitmapDrawable.getGravity()); 138 } 139 140 @Test 141 public void testBitmapDrawableOpticalInset() { 142 InputStream source = mContext.getResources().openRawResource(R.raw.testimage); 143 BitmapDrawable bitmapDrawable = new BitmapDrawable(source); 144 145 int intrinsicWidth = bitmapDrawable.getIntrinsicWidth(); 146 int intrinsicHeight = bitmapDrawable.getIntrinsicHeight(); 147 148 bitmapDrawable.setGravity(Gravity.CENTER); 149 bitmapDrawable.setBounds(0, 0, intrinsicWidth * 3, intrinsicHeight * 3); 150 151 Insets opticalInsets = bitmapDrawable.getOpticalInsets(); 152 Insets expected = Insets.of(intrinsicWidth, intrinsicHeight, intrinsicWidth, 153 intrinsicHeight); 154 assertEquals(expected, opticalInsets); 155 } 156 157 @Test 158 public void testAccessMipMap() { 159 Bitmap source = BitmapFactory.decodeResource(mContext.getResources(), R.raw.testimage); 160 BitmapDrawable bitmapDrawable = new BitmapDrawable(source); 161 162 bitmapDrawable.setMipMap(true); 163 assertTrue(source.hasMipMap()); 164 165 bitmapDrawable.setMipMap(false); 166 assertFalse(source.hasMipMap()); 167 } 168 169 @Test 170 public void testSetAntiAlias() { 171 InputStream source = mContext.getResources().openRawResource(R.raw.testimage); 172 BitmapDrawable bitmapDrawable = new BitmapDrawable(source); 173 174 assertFalse(bitmapDrawable.getPaint().isAntiAlias()); 175 176 bitmapDrawable.setAntiAlias(true); 177 assertTrue(bitmapDrawable.getPaint().isAntiAlias()); 178 179 bitmapDrawable.setAntiAlias(false); 180 assertFalse(bitmapDrawable.getPaint().isAntiAlias()); 181 } 182 183 @Test 184 public void testSetFilterBitmap() { 185 InputStream source = mContext.getResources().openRawResource(R.raw.testimage); 186 BitmapDrawable bitmapDrawable = new BitmapDrawable(source); 187 188 assertTrue(bitmapDrawable.getPaint().isFilterBitmap()); 189 190 bitmapDrawable.setFilterBitmap(false); 191 assertFalse(bitmapDrawable.getPaint().isFilterBitmap()); 192 193 bitmapDrawable.setFilterBitmap(true); 194 assertTrue(bitmapDrawable.getPaint().isFilterBitmap()); 195 } 196 197 @Test 198 public void testIsFilterBitmap() { 199 InputStream source = mContext.getResources().openRawResource(R.raw.testimage); 200 BitmapDrawable bitmapDrawable = new BitmapDrawable(source); 201 202 assertTrue(bitmapDrawable.isFilterBitmap()); 203 204 bitmapDrawable.setFilterBitmap(false); 205 assertFalse(bitmapDrawable.isFilterBitmap()); 206 assertEquals(bitmapDrawable.isFilterBitmap(), bitmapDrawable.getPaint().isFilterBitmap()); 207 208 209 bitmapDrawable.setFilterBitmap(true); 210 assertTrue(bitmapDrawable.isFilterBitmap()); 211 assertEquals(bitmapDrawable.isFilterBitmap(), bitmapDrawable.getPaint().isFilterBitmap()); 212 } 213 214 @Test 215 public void testSetDither() { 216 InputStream source = mContext.getResources().openRawResource(R.raw.testimage); 217 BitmapDrawable bitmapDrawable = new BitmapDrawable(source); 218 219 assertTrue(bitmapDrawable.getPaint().isDither()); 220 221 bitmapDrawable.setDither(false); 222 assertFalse(bitmapDrawable.getPaint().isDither()); 223 224 bitmapDrawable.setDither(true); 225 assertTrue(bitmapDrawable.getPaint().isDither()); 226 227 } 228 229 @Test 230 public void testAccessTileMode() { 231 InputStream source = mContext.getResources().openRawResource(R.raw.testimage); 232 BitmapDrawable bitmapDrawable = new BitmapDrawable(source); 233 234 assertNull(bitmapDrawable.getTileModeX()); 235 assertNull(bitmapDrawable.getTileModeY()); 236 assertNull(bitmapDrawable.getPaint().getShader()); 237 238 bitmapDrawable.setTileModeX(TileMode.CLAMP); 239 assertEquals(TileMode.CLAMP, bitmapDrawable.getTileModeX()); 240 assertNull(bitmapDrawable.getTileModeY()); 241 242 bitmapDrawable.draw(new Canvas()); 243 assertNotNull(bitmapDrawable.getPaint().getShader()); 244 Shader oldShader = bitmapDrawable.getPaint().getShader(); 245 246 bitmapDrawable.setTileModeY(TileMode.REPEAT); 247 assertEquals(TileMode.CLAMP, bitmapDrawable.getTileModeX()); 248 assertEquals(TileMode.REPEAT, bitmapDrawable.getTileModeY()); 249 250 bitmapDrawable.draw(new Canvas()); 251 assertNotSame(oldShader, bitmapDrawable.getPaint().getShader()); 252 oldShader = bitmapDrawable.getPaint().getShader(); 253 254 bitmapDrawable.setTileModeXY(TileMode.REPEAT, TileMode.MIRROR); 255 assertEquals(TileMode.REPEAT, bitmapDrawable.getTileModeX()); 256 assertEquals(TileMode.MIRROR, bitmapDrawable.getTileModeY()); 257 258 bitmapDrawable.draw(new Canvas()); 259 assertNotSame(oldShader, bitmapDrawable.getPaint().getShader()); 260 oldShader = bitmapDrawable.getPaint().getShader(); 261 262 bitmapDrawable.setTileModeX(TileMode.MIRROR); 263 assertEquals(TileMode.MIRROR, bitmapDrawable.getTileModeX()); 264 assertEquals(TileMode.MIRROR, bitmapDrawable.getTileModeY()); 265 266 bitmapDrawable.draw(new Canvas()); 267 assertNotSame(oldShader, bitmapDrawable.getPaint().getShader()); 268 } 269 270 @Test 271 public void testGetChangingConfigurations() { 272 InputStream source = mContext.getResources().openRawResource(R.raw.testimage); 273 BitmapDrawable bitmapDrawable = new BitmapDrawable(source); 274 275 assertEquals(0, bitmapDrawable.getChangingConfigurations()); 276 277 bitmapDrawable.setChangingConfigurations(1); 278 assertEquals(1, bitmapDrawable.getChangingConfigurations()); 279 280 bitmapDrawable.setChangingConfigurations(2); 281 assertEquals(2, bitmapDrawable.getChangingConfigurations()); 282 } 283 284 @Test 285 public void testSetAlpha() { 286 InputStream source = mContext.getResources().openRawResource(R.raw.testimage); 287 BitmapDrawable bitmapDrawable = new BitmapDrawable(source); 288 289 assertEquals(255, bitmapDrawable.getPaint().getAlpha()); 290 291 bitmapDrawable.setAlpha(0); 292 assertEquals(0, bitmapDrawable.getPaint().getAlpha()); 293 294 bitmapDrawable.setAlpha(100); 295 assertEquals(100, bitmapDrawable.getPaint().getAlpha()); 296 297 // exceptional test 298 bitmapDrawable.setAlpha(-1); 299 assertTrue(0 <= bitmapDrawable.getPaint().getAlpha() 300 && bitmapDrawable.getPaint().getAlpha() <= 255); 301 302 bitmapDrawable.setAlpha(256); 303 assertTrue(0 <= bitmapDrawable.getPaint().getAlpha() 304 && bitmapDrawable.getPaint().getAlpha() <= 255); 305 } 306 307 @Test 308 public void testSetColorFilter() { 309 InputStream source = mContext.getResources().openRawResource(R.raw.testimage); 310 BitmapDrawable bitmapDrawable = new BitmapDrawable(source); 311 312 assertNull(bitmapDrawable.getPaint().getColorFilter()); 313 314 ColorFilter colorFilter = new ColorFilter(); 315 bitmapDrawable.setColorFilter(colorFilter); 316 assertSame(colorFilter, bitmapDrawable.getPaint().getColorFilter()); 317 318 bitmapDrawable.setColorFilter(null); 319 assertNull(bitmapDrawable.getPaint().getColorFilter()); 320 } 321 322 @Test 323 public void testSetTint() { 324 final InputStream source = mContext.getResources().openRawResource(R.raw.testimage); 325 final BitmapDrawable d = new BitmapDrawable(source); 326 327 d.setTint(Color.BLACK); 328 d.setTintMode(Mode.SRC_OVER); 329 assertEquals("Nine-patch is tinted", Color.BLACK, DrawableTestUtils.getPixel(d, 0, 0)); 330 331 } 332 333 @Test 334 public void testSetBlendMode() { 335 final InputStream source = mContext.getResources().openRawResource(R.raw.testimage); 336 final BitmapDrawable d = new BitmapDrawable(source); 337 338 d.setTint(Color.BLACK); 339 d.setTintBlendMode(BlendMode.SRC_OVER); 340 assertEquals("Nine-patch is tinted", Color.BLACK, DrawableTestUtils.getPixel(d, 0, 0)); 341 342 } 343 344 @Test 345 public void testGetOpacity() { 346 BitmapDrawable bitmapDrawable = new BitmapDrawable(); 347 assertEquals(Gravity.FILL, bitmapDrawable.getGravity()); 348 assertEquals(PixelFormat.TRANSLUCENT, bitmapDrawable.getOpacity()); 349 350 InputStream source = mContext.getResources().openRawResource(R.raw.testimage); 351 bitmapDrawable = new BitmapDrawable(source); 352 assertEquals(Gravity.FILL, bitmapDrawable.getGravity()); 353 assertEquals(PixelFormat.OPAQUE, bitmapDrawable.getOpacity()); 354 bitmapDrawable.setGravity(Gravity.BOTTOM); 355 assertEquals(PixelFormat.TRANSLUCENT, bitmapDrawable.getOpacity()); 356 357 source = mContext.getResources().openRawResource(R.raw.testimage); 358 bitmapDrawable = new BitmapDrawable(source); 359 assertEquals(Gravity.FILL, bitmapDrawable.getGravity()); 360 assertEquals(PixelFormat.OPAQUE, bitmapDrawable.getOpacity()); 361 bitmapDrawable.setAlpha(120); 362 assertEquals(PixelFormat.TRANSLUCENT, bitmapDrawable.getOpacity()); 363 } 364 365 @Test 366 public void testGetConstantState() { 367 InputStream source = mContext.getResources().openRawResource(R.raw.testimage); 368 BitmapDrawable bitmapDrawable = new BitmapDrawable(source); 369 ConstantState constantState = bitmapDrawable.getConstantState(); 370 assertNotNull(constantState); 371 assertEquals(0, constantState.getChangingConfigurations()); 372 373 bitmapDrawable.setChangingConfigurations(1); 374 constantState = bitmapDrawable.getConstantState(); 375 assertNotNull(constantState); 376 assertEquals(1, constantState.getChangingConfigurations()); 377 } 378 379 @SuppressWarnings("deprecation") 380 @Test 381 public void testGetIntrinsicSize() { 382 BitmapDrawable bitmapDrawable = new BitmapDrawable(); 383 assertEquals(-1, bitmapDrawable.getIntrinsicWidth()); 384 assertEquals(-1, bitmapDrawable.getIntrinsicHeight()); 385 386 Bitmap bitmap = Bitmap.createBitmap(200, 300, Config.RGB_565); 387 bitmapDrawable = new BitmapDrawable(bitmap); 388 bitmapDrawable.setTargetDensity(bitmap.getDensity()); 389 assertEquals(200, bitmapDrawable.getIntrinsicWidth()); 390 assertEquals(300, bitmapDrawable.getIntrinsicHeight()); 391 392 InputStream source = mContext.getResources().openRawResource(R.drawable.size_48x48); 393 bitmapDrawable = new BitmapDrawable(source); 394 bitmapDrawable.setTargetDensity(bitmapDrawable.getBitmap().getDensity()); 395 assertEquals(48, bitmapDrawable.getIntrinsicWidth()); 396 assertEquals(48, bitmapDrawable.getIntrinsicHeight()); 397 } 398 399 @SuppressWarnings("deprecation") 400 @Test 401 public void testSetTargetDensity() { 402 int sourceWidth, targetWidth; 403 int sourceHeight, targetHeight; 404 int sourceDensity, targetDensity; 405 BitmapDrawable bitmapDrawable; 406 Bitmap bitmap; 407 408 sourceWidth = 200; 409 sourceHeight = 300; 410 bitmap = Bitmap.createBitmap(sourceWidth, sourceHeight, Config.RGB_565); 411 Canvas canvas = new Canvas(bitmap); 412 bitmapDrawable = new BitmapDrawable(bitmap); 413 sourceDensity = bitmap.getDensity(); 414 targetDensity = canvas.getDensity(); 415 bitmapDrawable.setTargetDensity(canvas); 416 targetWidth = DrawableTestUtils.scaleBitmapFromDensity( 417 sourceWidth, sourceDensity, targetDensity); 418 targetHeight = DrawableTestUtils.scaleBitmapFromDensity( 419 sourceHeight, sourceDensity, targetDensity); 420 assertEquals(targetWidth, bitmapDrawable.getIntrinsicWidth()); 421 assertEquals(targetHeight, bitmapDrawable.getIntrinsicHeight()); 422 423 sourceWidth = 200; 424 sourceHeight = 300; 425 bitmap = Bitmap.createBitmap(sourceWidth, sourceHeight, Config.RGB_565); 426 bitmapDrawable = new BitmapDrawable(bitmap); 427 sourceDensity = bitmap.getDensity(); 428 targetDensity = mContext.getResources().getDisplayMetrics().densityDpi; 429 bitmapDrawable.setTargetDensity(mContext.getResources().getDisplayMetrics()); 430 targetWidth = DrawableTestUtils.scaleBitmapFromDensity( 431 sourceWidth, sourceDensity, targetDensity); 432 targetHeight = DrawableTestUtils.scaleBitmapFromDensity( 433 sourceHeight, sourceDensity, targetDensity); 434 assertEquals(targetWidth, bitmapDrawable.getIntrinsicWidth()); 435 assertEquals(targetHeight, bitmapDrawable.getIntrinsicHeight()); 436 437 sourceWidth = 48; 438 sourceHeight = 48; 439 InputStream source = mContext.getResources().openRawResource(R.drawable.size_48x48); 440 bitmapDrawable = new BitmapDrawable(source); 441 bitmap = bitmapDrawable.getBitmap(); 442 sourceDensity = bitmap.getDensity(); 443 targetDensity = sourceDensity * 2; 444 bitmapDrawable.setTargetDensity(targetDensity); 445 targetWidth = DrawableTestUtils.scaleBitmapFromDensity( 446 sourceWidth, sourceDensity, targetDensity); 447 targetHeight = DrawableTestUtils.scaleBitmapFromDensity( 448 sourceHeight, sourceDensity, targetDensity); 449 assertEquals(targetWidth, bitmapDrawable.getIntrinsicWidth()); 450 assertEquals(targetHeight, bitmapDrawable.getIntrinsicHeight()); 451 } 452 453 @SuppressWarnings("deprecation") 454 @Test 455 public void testInflate() throws IOException, XmlPullParserException { 456 BitmapDrawable bitmapDrawable = new BitmapDrawable(); 457 458 XmlResourceParser parser = mContext.getResources().getXml(R.xml.bitmapdrawable); 459 AttributeSet attrs = DrawableTestUtils.getAttributeSet( 460 mContext.getResources().getXml(R.xml.bitmapdrawable), "bitmap_allattrs"); 461 bitmapDrawable.inflate(mContext.getResources(), parser, attrs); 462 assertEquals(Gravity.TOP | Gravity.RIGHT, bitmapDrawable.getGravity()); 463 assertTrue(bitmapDrawable.getPaint().isDither()); 464 assertTrue(bitmapDrawable.getPaint().isAntiAlias()); 465 assertFalse(bitmapDrawable.getPaint().isFilterBitmap()); 466 assertEquals(TileMode.REPEAT, bitmapDrawable.getTileModeX()); 467 assertEquals(TileMode.REPEAT, bitmapDrawable.getTileModeY()); 468 469 bitmapDrawable = new BitmapDrawable(); 470 attrs = DrawableTestUtils.getAttributeSet( 471 mContext.getResources().getXml(R.xml.bitmapdrawable), "bitmap_partattrs"); 472 // when parser is null 473 bitmapDrawable.inflate(mContext.getResources(), null, attrs); 474 assertEquals(Gravity.CENTER, bitmapDrawable.getGravity()); 475 assertEquals(TileMode.MIRROR, bitmapDrawable.getTileModeX()); 476 assertEquals(TileMode.MIRROR, bitmapDrawable.getTileModeY()); 477 // default value 478 assertTrue(bitmapDrawable.getPaint().isDither()); 479 assertFalse(bitmapDrawable.getPaint().isAntiAlias()); 480 assertTrue(bitmapDrawable.getPaint().isFilterBitmap()); 481 482 attrs = DrawableTestUtils.getAttributeSet( 483 mContext.getResources().getXml(R.xml.bitmapdrawable), "bitmap_wrongsrc"); 484 try { 485 bitmapDrawable = new BitmapDrawable(); 486 bitmapDrawable.inflate(mContext.getResources(), parser, attrs); 487 fail("Should throw XmlPullParserException if the bitmap source can't be decoded."); 488 } catch (XmlPullParserException e) { 489 } 490 491 attrs = DrawableTestUtils.getAttributeSet( 492 mContext.getResources().getXml(R.xml.bitmapdrawable), "bitmap_nosrc"); 493 try { 494 bitmapDrawable = new BitmapDrawable(); 495 bitmapDrawable.inflate(mContext.getResources(), parser, attrs); 496 fail("Should throw XmlPullParserException if the bitmap src is not defined."); 497 } catch (XmlPullParserException e) { 498 } 499 500 attrs = DrawableTestUtils.getAttributeSet( 501 mContext.getResources().getXml(R.xml.bitmapdrawable), "bitmap_allattrs"); 502 try { 503 bitmapDrawable = new BitmapDrawable(); 504 bitmapDrawable.inflate(null, parser, attrs); 505 fail("Should throw NullPointerException if resource is null"); 506 } catch (NullPointerException e) { 507 } 508 509 try { 510 bitmapDrawable = new BitmapDrawable(); 511 bitmapDrawable.inflate(mContext.getResources(), parser, null); 512 fail("Should throw NullPointerException if attribute set is null"); 513 } catch (NullPointerException e) { 514 } 515 } 516 517 @Test 518 public void testDraw() { 519 InputStream source = mContext.getResources().openRawResource(R.raw.testimage); 520 BitmapDrawable bitmapDrawable = new BitmapDrawable(source); 521 522 // if the function draw() does not throw any exception, we think it is right. 523 bitmapDrawable.draw(new Canvas()); 524 525 // input null as param 526 try { 527 bitmapDrawable.draw(null); 528 fail("Should throw NullPointerException."); 529 } catch (NullPointerException e) { 530 } 531 } 532 533 @Test 534 public void testMutate() { 535 Resources resources = mContext.getResources(); 536 BitmapDrawable d1 = (BitmapDrawable) resources.getDrawable(R.drawable.testimage); 537 BitmapDrawable d2 = (BitmapDrawable) resources.getDrawable(R.drawable.testimage); 538 BitmapDrawable d3 = (BitmapDrawable) resources.getDrawable(R.drawable.testimage); 539 int restoreAlpha = d1.getAlpha(); 540 541 try { 542 // verify bad behavior - modify before mutate pollutes other drawables 543 d1.setAlpha(100); 544 assertEquals(100, d1.getPaint().getAlpha()); 545 assertEquals(100, d2.getPaint().getAlpha()); 546 assertEquals(100, d3.getPaint().getAlpha()); 547 548 d1.mutate(); 549 d1.setAlpha(200); 550 assertEquals(200, d1.getPaint().getAlpha()); 551 assertEquals(100, d2.getPaint().getAlpha()); 552 assertEquals(100, d3.getPaint().getAlpha()); 553 d2.setAlpha(50); 554 assertEquals(200, d1.getPaint().getAlpha()); 555 assertEquals(50, d2.getPaint().getAlpha()); 556 assertEquals(50, d3.getPaint().getAlpha()); 557 } finally { 558 // restore externally visible state, since other tests may use the drawable 559 resources.getDrawable(R.drawable.testimage).setAlpha(restoreAlpha); 560 } 561 } 562 } 563