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.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.assertTrue; 24 import static org.junit.Assert.fail; 25 26 import android.content.Context; 27 import android.content.res.ColorStateList; 28 import android.content.res.Resources; 29 import android.content.res.Resources.Theme; 30 import android.content.res.XmlResourceParser; 31 import android.graphics.Bitmap; 32 import android.graphics.Canvas; 33 import android.graphics.Color; 34 import android.graphics.ColorFilter; 35 import android.graphics.Insets; 36 import android.graphics.PixelFormat; 37 import android.graphics.Rect; 38 import android.graphics.cts.R; 39 import android.graphics.drawable.Drawable.ConstantState; 40 import android.graphics.drawable.GradientDrawable; 41 import android.graphics.drawable.GradientDrawable.Orientation; 42 import android.util.AttributeSet; 43 import android.util.Xml; 44 import android.view.ContextThemeWrapper; 45 46 import androidx.test.InstrumentationRegistry; 47 import androidx.test.filters.SmallTest; 48 import androidx.test.runner.AndroidJUnit4; 49 50 import org.junit.Before; 51 import org.junit.Test; 52 import org.junit.runner.RunWith; 53 import org.xmlpull.v1.XmlPullParser; 54 import org.xmlpull.v1.XmlPullParserException; 55 56 import java.io.IOException; 57 import java.util.Arrays; 58 59 @SmallTest 60 @RunWith(AndroidJUnit4.class) 61 public class GradientDrawableTest { 62 private Resources mResources; 63 64 @Before 65 public void setup() { 66 mResources = InstrumentationRegistry.getTargetContext().getResources(); 67 } 68 69 @Test 70 public void testConstructor() { 71 int[] color = new int[] {1, 2, 3}; 72 73 new GradientDrawable(); 74 new GradientDrawable(GradientDrawable.Orientation.BL_TR, color); 75 new GradientDrawable(null, null); 76 } 77 78 @Test 79 public void testGetOpacity() { 80 GradientDrawable gradientDrawable = new GradientDrawable(); 81 assertEquals("Default opacity is TRANSLUCENT", 82 PixelFormat.TRANSLUCENT, gradientDrawable.getOpacity()); 83 84 gradientDrawable.setColor(Color.TRANSPARENT); 85 assertEquals("Color.TRANSPARENT is TRANSLUCENT", 86 PixelFormat.TRANSLUCENT, gradientDrawable.getOpacity()); 87 88 gradientDrawable.setColor(0x80FFFFFF); 89 assertEquals("0x80FFFFFF is TRANSLUCENT", 90 PixelFormat.TRANSLUCENT, gradientDrawable.getOpacity()); 91 92 gradientDrawable.setColors(new int[] { Color.RED, Color.TRANSPARENT }); 93 assertEquals("{ RED, TRANSPARENT } is TRANSLUCENT", 94 PixelFormat.TRANSLUCENT, gradientDrawable.getOpacity()); 95 96 gradientDrawable.setColors(new int[] { Color.RED, Color.BLUE }); 97 assertEquals("{ RED, BLUE } is OPAQUE", 98 PixelFormat.OPAQUE, gradientDrawable.getOpacity()); 99 100 gradientDrawable.setColor(Color.RED); 101 assertEquals("RED is OPAQUE", 102 PixelFormat.OPAQUE, gradientDrawable.getOpacity()); 103 104 gradientDrawable.setCornerRadius(10); 105 assertEquals("RED with corner radius is TRANSLUCENT", 106 PixelFormat.TRANSLUCENT, gradientDrawable.getOpacity()); 107 108 gradientDrawable.setCornerRadius(0); 109 assertEquals("RED with no corner radius is OPAQUE", 110 PixelFormat.OPAQUE, gradientDrawable.getOpacity()); 111 112 gradientDrawable.setCornerRadii(new float[] { 2, 2, 0, 0, 0, 0, 0, 0}); 113 assertEquals("RED with corner radii is TRANSLUCENT", 114 PixelFormat.TRANSLUCENT, gradientDrawable.getOpacity()); 115 116 gradientDrawable.setCornerRadii(null); 117 assertEquals("RED with no corner radii is OPAQUE", 118 PixelFormat.OPAQUE, gradientDrawable.getOpacity()); 119 } 120 121 @Test 122 public void testSetOrientation() { 123 GradientDrawable gradientDrawable = new GradientDrawable(); 124 Orientation orientation; 125 126 orientation = Orientation.BL_TR; 127 gradientDrawable.setOrientation(orientation); 128 assertEquals("Orientation set/get are symmetric", 129 orientation, gradientDrawable.getOrientation()); 130 } 131 132 @Test 133 public void testSetCornerRadii() { 134 float[] radii = new float[] {1.0f, 2.0f, 3.0f}; 135 136 GradientDrawable gradientDrawable = new GradientDrawable(); 137 gradientDrawable.setCornerRadii(radii); 138 139 float[] radiiActual = gradientDrawable.getCornerRadii(); 140 assertArrayEquals("Gradient radius set/get are symmetric", 141 radii, radiiActual, 0); 142 143 ConstantState constantState = gradientDrawable.getConstantState(); 144 assertNotNull(constantState); 145 146 // input null as param 147 gradientDrawable.setCornerRadii(null); 148 } 149 150 @Test 151 public void testSetCornerRadius() { 152 GradientDrawable gradientDrawable = new GradientDrawable(); 153 154 gradientDrawable.setCornerRadius(2.5f); 155 gradientDrawable.setCornerRadius(-2.5f); 156 } 157 158 @Test 159 public void testGetCornerRadius() { 160 GradientDrawable gradientDrawable = new GradientDrawable(); 161 gradientDrawable.setCornerRadius(5.5f); 162 assertEquals(gradientDrawable.getCornerRadius(), 5.5f, 0); 163 float[] radii = new float[] {1.0f, 2.0f, 3.0f}; 164 gradientDrawable.setCornerRadii(radii); 165 assertEquals(5.5f, gradientDrawable.getCornerRadius(), 0); 166 gradientDrawable.setShape(GradientDrawable.OVAL); 167 assertEquals(5.5f, gradientDrawable.getCornerRadius(), 0); 168 gradientDrawable.setCornerRadii(null); 169 assertEquals(0, gradientDrawable.getCornerRadius(), 0); 170 } 171 172 @Test 173 public void testSetStroke() { 174 helpTestSetStroke(2, Color.RED); 175 helpTestSetStroke(-2, Color.TRANSPARENT); 176 helpTestSetStroke(0, 0); 177 } 178 179 private void helpTestSetStroke(int width, int color) { 180 GradientDrawable gradientDrawable = new GradientDrawable(); 181 gradientDrawable.setStroke(width, color); 182 // TODO: Verify stroke properties. 183 } 184 185 @Test 186 public void testSetStroke_WidthGap() { 187 verifySetStroke_WidthGap(2, Color.RED, 3.4f, 5.5f); 188 verifySetStroke_WidthGap(-2, Color.TRANSPARENT, -3.4f, -5.5f); 189 verifySetStroke_WidthGap(0, 0, 0, (float) 0.0f); 190 } 191 192 private void verifySetStroke_WidthGap(int width, int color, 193 float dashWidth, float dashGap) { 194 GradientDrawable gradientDrawable = new GradientDrawable(); 195 gradientDrawable.setStroke(width, color, dashWidth, dashGap); 196 // TODO: Verify stroke properties. 197 } 198 199 @Test 200 public void testSetStrokeList() { 201 verifySetStrokeList(2, ColorStateList.valueOf(Color.RED)); 202 verifySetStrokeList(-2, ColorStateList.valueOf(Color.TRANSPARENT)); 203 verifySetStrokeList(0, null); 204 } 205 206 private void verifySetStrokeList(int width, 207 ColorStateList colorList) { 208 GradientDrawable gradientDrawable = new GradientDrawable(); 209 gradientDrawable.setStroke(width, colorList); 210 // TODO: Verify stroke properties. 211 } 212 213 @Test 214 public void testSetStrokeList_WidthGap() { 215 verifySetStrokeList_WidthGap(2, ColorStateList.valueOf(Color.RED), 3.4f, 5.5f); 216 verifySetStrokeList_WidthGap(-2, ColorStateList.valueOf(Color.TRANSPARENT), -3.4f, -5.5f); 217 verifySetStrokeList_WidthGap(0, null, 0.0f, 0.0f); 218 } 219 220 private void verifySetStrokeList_WidthGap(int width, ColorStateList colorList, 221 float dashWidth, float dashGap) { 222 GradientDrawable gradientDrawable = new GradientDrawable(); 223 gradientDrawable.setStroke(width, colorList, dashWidth, dashGap); 224 // TODO: Verify stroke properties. 225 } 226 227 @Test 228 public void testSetSize() { 229 verifySetSize(6, 4); 230 verifySetSize(-30, -40); 231 verifySetSize(0, 0); 232 verifySetSize(Integer.MAX_VALUE, Integer.MIN_VALUE); 233 } 234 235 private void verifySetSize(int width, int height) { 236 GradientDrawable gradientDrawable = new GradientDrawable(); 237 gradientDrawable.setSize(width, height); 238 assertEquals(width, gradientDrawable.getIntrinsicWidth()); 239 assertEquals(height, gradientDrawable.getIntrinsicHeight()); 240 } 241 242 @Test 243 public void testSetShape() { 244 GradientDrawable gradientDrawable = new GradientDrawable(); 245 int shape; 246 247 shape = GradientDrawable.OVAL; 248 gradientDrawable.setShape(shape); 249 assertEquals("Gradient shape set/get are symmetric", 250 shape, gradientDrawable.getShape()); 251 252 shape = -1; 253 gradientDrawable.setShape(shape); 254 assertEquals("Invalid gradient shape set/get are symmetric", 255 shape, gradientDrawable.getShape()); 256 } 257 258 @Test 259 public void testSetGradientType() { 260 GradientDrawable gradientDrawable = new GradientDrawable(); 261 int gradientType; 262 263 gradientType = GradientDrawable.LINEAR_GRADIENT; 264 gradientDrawable.setGradientType(gradientType); 265 assertEquals("Gradient type set/get are symmetric", 266 gradientType, gradientDrawable.getGradientType()); 267 268 gradientType = -1; 269 gradientDrawable.setGradientType(gradientType); 270 assertEquals("Invalid gradient type set/get are symmetric", 271 gradientType, gradientDrawable.getGradientType()); 272 } 273 274 @Test 275 public void testSetGradientCenter() { 276 GradientDrawable gradientDrawable = new GradientDrawable(); 277 float centerX; 278 float centerY; 279 280 centerX = 0.5f; 281 centerY = 0.5f; 282 assertEquals(centerX, gradientDrawable.getGradientCenterX(), 0.01f); 283 assertEquals(centerY, gradientDrawable.getGradientCenterY(), 0.01f); 284 285 centerX = -0.5f; 286 centerY = -0.5f; 287 gradientDrawable.setGradientCenter(centerX, centerY); 288 assertEquals(centerX, gradientDrawable.getGradientCenterX(), 0.01f); 289 assertEquals(centerY, gradientDrawable.getGradientCenterY(), 0.01f); 290 291 centerX = 0.0f; 292 centerY = 0.0f; 293 gradientDrawable.setGradientCenter(centerX, centerY); 294 assertEquals(centerX, gradientDrawable.getGradientCenterX(), 0.01f); 295 assertEquals(centerY, gradientDrawable.getGradientCenterY(), 0.01f); 296 } 297 298 @Test 299 public void testSetGradientRadius() { 300 GradientDrawable gradientDrawable = new GradientDrawable(); 301 302 gradientDrawable.setGradientRadius(3.6f); 303 gradientDrawable.setGradientRadius(-3.6f); 304 } 305 306 @Test 307 public void testSetUseLevel() { 308 GradientDrawable gradientDrawable = new GradientDrawable(); 309 boolean useLevel; 310 311 assertFalse("Default useLevel is false", gradientDrawable.getUseLevel()); 312 313 useLevel = true; 314 gradientDrawable.setUseLevel(useLevel); 315 assertEquals("Gradient set/get useLevel is symmetric", 316 useLevel, gradientDrawable.getUseLevel()); 317 318 useLevel = false; 319 gradientDrawable.setUseLevel(useLevel); 320 assertEquals("Gradient set/get useLevel is symmetric", 321 useLevel, gradientDrawable.getUseLevel()); 322 } 323 324 @Test 325 public void testDraw() { 326 GradientDrawable gradientDrawable = new GradientDrawable(); 327 Canvas c = new Canvas(); 328 gradientDrawable.draw(c); 329 330 // input null as param 331 gradientDrawable.draw(null); 332 } 333 334 @Test 335 public void testSetColor() { 336 GradientDrawable gradientDrawable = new GradientDrawable(); 337 int color; 338 339 color = Color.RED; 340 gradientDrawable.setColor(color); 341 assertEquals("Color was set to " + color, color, 342 gradientDrawable.getColor().getDefaultColor()); 343 344 color = Color.TRANSPARENT; 345 gradientDrawable.setColor(color); 346 assertEquals("Color was set to " + color, color, 347 gradientDrawable.getColor().getDefaultColor()); 348 } 349 350 @Test 351 public void testSetColors() { 352 GradientDrawable gradientDrawable = new GradientDrawable(); 353 int[] colors; 354 355 colors = new int[] { Color.RED }; 356 gradientDrawable.setColors(colors); 357 assertArrayEquals("Color was set to " + Arrays.toString(colors), 358 colors, gradientDrawable.getColors()); 359 360 colors = null; 361 gradientDrawable.setColors(colors); 362 assertArrayEquals("Color was set to " + Arrays.toString(colors), 363 colors, gradientDrawable.getColors()); 364 } 365 366 @Test 367 public void testSetColorList() { 368 GradientDrawable gradientDrawable = new GradientDrawable(); 369 ColorStateList color; 370 371 color = ColorStateList.valueOf(Color.RED); 372 gradientDrawable.setColor(color); 373 assertEquals("Color was set to RED", color, gradientDrawable.getColor()); 374 375 gradientDrawable.setColor(null); 376 assertEquals("Color was set to null (TRANSPARENT)", 377 ColorStateList.valueOf(Color.TRANSPARENT), gradientDrawable.getColor()); 378 } 379 380 @Test 381 public void testGetChangingConfigurations() { 382 GradientDrawable gradientDrawable = new GradientDrawable(); 383 assertEquals(0, gradientDrawable.getChangingConfigurations()); 384 385 gradientDrawable.setChangingConfigurations(10); 386 assertEquals(10, gradientDrawable.getChangingConfigurations()); 387 388 gradientDrawable.setChangingConfigurations(-20); 389 assertEquals(-20, gradientDrawable.getChangingConfigurations()); 390 } 391 392 @Test 393 public void testSetAlpha() { 394 GradientDrawable gradientDrawable = new GradientDrawable(); 395 396 gradientDrawable.setAlpha(1); 397 gradientDrawable.setAlpha(-1); 398 } 399 400 @Test 401 public void testSetDither() { 402 GradientDrawable gradientDrawable = new GradientDrawable(); 403 404 gradientDrawable.setDither(true); 405 gradientDrawable.setDither(false); 406 } 407 408 @Test 409 public void testSetColorFilter() { 410 GradientDrawable gradientDrawable = new GradientDrawable(); 411 ColorFilter cf = new ColorFilter(); 412 gradientDrawable.setColorFilter(cf); 413 414 // input null as param 415 gradientDrawable.setColorFilter(null); 416 } 417 418 @Test 419 public void testInflate() throws XmlPullParserException, IOException { 420 GradientDrawable gradientDrawable = new GradientDrawable(); 421 Rect rect = new Rect(); 422 assertFalse(gradientDrawable.getPadding(rect)); 423 assertEquals(0, rect.left); 424 assertEquals(0, rect.top); 425 assertEquals(0, rect.right); 426 assertEquals(0, rect.bottom); 427 428 XmlPullParser parser = mResources.getXml(R.drawable.gradientdrawable); 429 AttributeSet attrs = Xml.asAttributeSet(parser); 430 431 // find the START_TAG 432 int type; 433 while ((type = parser.next()) != XmlPullParser.START_TAG && 434 type != XmlPullParser.END_DOCUMENT) { 435 // Empty loop 436 } 437 assertEquals(XmlPullParser.START_TAG, type); 438 439 // padding is set in gradientdrawable.xml 440 gradientDrawable.inflate(mResources, parser, attrs); 441 assertTrue(gradientDrawable.getPadding(rect)); 442 assertEquals(4, rect.left); 443 assertEquals(2, rect.top); 444 assertEquals(6, rect.right); 445 assertEquals(10, rect.bottom); 446 447 try { 448 gradientDrawable.getPadding(null); 449 fail("did not throw NullPointerException when rect is null."); 450 } catch (NullPointerException e) { 451 // expected, test success 452 } 453 454 try { 455 gradientDrawable.inflate(null, null, null); 456 fail("did not throw NullPointerException when parameters are null."); 457 } catch (NullPointerException e) { 458 // expected, test success 459 } 460 } 461 462 @Test 463 public void testGradientPadding() { 464 GradientDrawable drawable = new GradientDrawable(); 465 drawable.setPadding(1, 2, 3, 4); 466 467 Rect padding = new Rect(); 468 drawable.getPadding(padding); 469 470 assertEquals(1, padding.left); 471 assertEquals(2, padding.top); 472 assertEquals(3, padding.right); 473 assertEquals(4, padding.bottom); 474 } 475 476 @Test 477 public void testGradientThickness() { 478 GradientDrawable drawable = new GradientDrawable(); 479 int thickness = 17; 480 481 drawable.setThickness(thickness); 482 assertEquals(thickness, drawable.getThickness()); 483 } 484 485 @Test 486 public void testNegativeGradientThickness() { 487 try { 488 new GradientDrawable().setThicknessRatio(-1); 489 fail("Did not throw IllegalArgumentException with negative thickness ratio"); 490 } catch (IllegalArgumentException e) { 491 // expected, test success 492 } 493 } 494 495 @Test 496 public void testZeroGradientThickness() { 497 try { 498 new GradientDrawable().setThicknessRatio(0); 499 fail("Did not throw IllegalArgumentException with zero thickness ratio"); 500 } catch (IllegalArgumentException e) { 501 // expected, test success 502 } 503 504 } 505 506 @Test 507 public void testGradientThicknessRatio() { 508 GradientDrawable drawable = new GradientDrawable(); 509 510 float thicknessRatio = 3.9f; 511 512 drawable.setThicknessRatio(thicknessRatio); 513 assertEquals(0, Float.compare(thicknessRatio, drawable.getThicknessRatio())); 514 } 515 516 @Test 517 public void testGradientInnerRadius() { 518 GradientDrawable drawable = new GradientDrawable(); 519 int innerRadius = 12; 520 drawable.setInnerRadius(innerRadius); 521 522 assertEquals(innerRadius, drawable.getInnerRadius()); 523 } 524 525 @Test 526 public void testNegativeInnerRadiusRatio() { 527 try { 528 new GradientDrawable().setInnerRadiusRatio(-1); 529 fail("Did not throw IllegalArgumentException with negative thickness ratio"); 530 } catch (IllegalArgumentException e) { 531 // expected, test success 532 } 533 } 534 535 @Test 536 public void testZeroInnerRadiusRatio() { 537 try { 538 new GradientDrawable().setInnerRadiusRatio(0); 539 fail("Did not throw IllegalArgumentException with zero thickness ratio"); 540 } catch (IllegalArgumentException e) { 541 // expected, test success 542 } 543 } 544 545 @Test 546 public void testGradientInnerRadiusRatio() { 547 GradientDrawable drawable = new GradientDrawable(); 548 float innerRadiusRatio = 3.8f; 549 drawable.setInnerRadiusRatio(innerRadiusRatio); 550 551 assertEquals(0, Float.compare(innerRadiusRatio, drawable.getInnerRadiusRatio())); 552 } 553 554 @Test 555 public void testGradientPositions() throws XmlPullParserException, IOException { 556 GradientDrawable gradientDrawable = new GradientDrawable(); 557 XmlPullParser parser = mResources.getXml(R.drawable.gradientdrawable); 558 AttributeSet attrs = Xml.asAttributeSet(parser); 559 560 // find the START_TAG 561 int type; 562 while ((type = parser.next()) != XmlPullParser.START_TAG 563 && type != XmlPullParser.END_DOCUMENT) { 564 // Empty loop 565 } 566 assertEquals(XmlPullParser.START_TAG, type); 567 568 // padding is set in gradientdrawable.xml 569 gradientDrawable.inflate(mResources, parser, attrs); 570 571 gradientDrawable.setColors(new int[]{ Color.RED, Color.BLUE}); 572 573 Canvas canvas = new Canvas(Bitmap.createBitmap(100, 100, 574 Bitmap.Config.ARGB_8888)); 575 576 gradientDrawable.setBounds(0, 0, 100, 100); 577 // Verify that calling draw does not crash 578 gradientDrawable.draw(canvas); 579 580 } 581 582 @Test 583 public void testInflateGradientRadius() throws XmlPullParserException, IOException { 584 Rect parentBounds = new Rect(0, 0, 100, 100); 585 586 GradientDrawable gradientDrawable; 587 float radius; 588 589 gradientDrawable = (GradientDrawable) mResources.getDrawable( 590 R.drawable.gradientdrawable_radius_base); 591 gradientDrawable.setBounds(parentBounds); 592 radius = gradientDrawable.getGradientRadius(); 593 assertEquals(25.0f, radius, 0.0f); 594 595 gradientDrawable = (GradientDrawable) mResources.getDrawable( 596 R.drawable.gradientdrawable_radius_parent); 597 gradientDrawable.setBounds(parentBounds); 598 radius = gradientDrawable.getGradientRadius(); 599 assertEquals(50.0f, radius, 0.0f); 600 } 601 602 @Test 603 public void testGetIntrinsicWidth() { 604 GradientDrawable gradientDrawable = new GradientDrawable(); 605 gradientDrawable.setSize(6, 4); 606 assertEquals(6, gradientDrawable.getIntrinsicWidth()); 607 608 gradientDrawable.setSize(-10, -20); 609 assertEquals(-10, gradientDrawable.getIntrinsicWidth()); 610 } 611 612 @Test 613 public void testGetIntrinsicHeight() { 614 GradientDrawable gradientDrawable = new GradientDrawable(); 615 gradientDrawable.setSize(5, 3); 616 assertEquals(3, gradientDrawable.getIntrinsicHeight()); 617 618 gradientDrawable.setSize(-5, -15); 619 assertEquals(-15, gradientDrawable.getIntrinsicHeight()); 620 } 621 622 @Test 623 public void testGetConstantState() { 624 GradientDrawable gradientDrawable = new GradientDrawable(); 625 assertNotNull(gradientDrawable.getConstantState()); 626 } 627 628 @Test 629 public void testMutate() { 630 GradientDrawable d1 = 631 (GradientDrawable) mResources.getDrawable(R.drawable.gradientdrawable); 632 GradientDrawable d2 = 633 (GradientDrawable) mResources.getDrawable(R.drawable.gradientdrawable); 634 GradientDrawable d3 = 635 (GradientDrawable) mResources.getDrawable(R.drawable.gradientdrawable); 636 637 d1.setSize(10, 10); 638 assertEquals(10, d1.getIntrinsicHeight()); 639 assertEquals(10, d1.getIntrinsicWidth()); 640 assertEquals(10, d2.getIntrinsicHeight()); 641 assertEquals(10, d2.getIntrinsicWidth()); 642 assertEquals(10, d3.getIntrinsicHeight()); 643 assertEquals(10, d3.getIntrinsicWidth()); 644 645 d1.mutate(); 646 d1.setSize(20, 30); 647 assertEquals(30, d1.getIntrinsicHeight()); 648 assertEquals(20, d1.getIntrinsicWidth()); 649 assertEquals(10, d2.getIntrinsicHeight()); 650 assertEquals(10, d2.getIntrinsicWidth()); 651 assertEquals(10, d3.getIntrinsicHeight()); 652 assertEquals(10, d3.getIntrinsicWidth()); 653 654 d2.setSize(40, 50); 655 assertEquals(30, d1.getIntrinsicHeight()); 656 assertEquals(20, d1.getIntrinsicWidth()); 657 assertEquals(50, d2.getIntrinsicHeight()); 658 assertEquals(40, d2.getIntrinsicWidth()); 659 assertEquals(50, d3.getIntrinsicHeight()); 660 assertEquals(40, d3.getIntrinsicWidth()); 661 } 662 663 @Test 664 public void testPreloadDensity() throws XmlPullParserException, IOException { 665 final int densityDpi = mResources.getConfiguration().densityDpi; 666 try { 667 DrawableTestUtils.setResourcesDensity(mResources, densityDpi); 668 verifyPreloadDensityInner(mResources, densityDpi); 669 } finally { 670 DrawableTestUtils.setResourcesDensity(mResources, densityDpi); 671 } 672 } 673 674 @Test 675 public void testPreloadDensity_tvdpi() throws XmlPullParserException, IOException { 676 final int densityDpi = mResources.getConfiguration().densityDpi; 677 try { 678 DrawableTestUtils.setResourcesDensity(mResources, 213); 679 verifyPreloadDensityInner(mResources, 213); 680 } finally { 681 DrawableTestUtils.setResourcesDensity(mResources, densityDpi); 682 } 683 } 684 685 @Test 686 public void testOpticalInsets() { 687 GradientDrawable drawable = 688 (GradientDrawable) mResources.getDrawable(R.drawable.gradientdrawable); 689 assertEquals(Insets.of(1, 2, 3, 4), drawable.getOpticalInsets()); 690 } 691 692 @Test 693 public void testInflationWithThemeAndNonThemeResources() { 694 final Context context = InstrumentationRegistry.getTargetContext(); 695 final Theme theme = context.getResources().newTheme(); 696 theme.applyStyle(R.style.Theme_MixedGradientTheme, true); 697 final Theme ctxTheme = context.getTheme(); 698 ctxTheme.setTo(theme); 699 700 GradientDrawable drawable = (GradientDrawable) 701 ctxTheme.getDrawable(R.drawable.gradientdrawable_mix_theme); 702 703 Bitmap bitmap = Bitmap.createBitmap(10, 10, Bitmap.Config.ARGB_8888); 704 Canvas canvas = new Canvas(bitmap); 705 drawable.setBounds(0, 0, 10, 10); 706 drawable.draw(canvas); 707 int[] colors = drawable.getColors(); 708 assertEquals(3, colors.length); 709 assertEquals(0, colors[0]); 710 assertEquals(context.getColor(R.color.colorPrimary), colors[1]); 711 assertEquals(context.getColor(R.color.colorPrimaryDark), colors[2]); 712 } 713 714 @Test 715 public void testRadialInflationWithThemeAndNonThemeResources() { 716 final Context context = new ContextThemeWrapper(InstrumentationRegistry.getTargetContext(), 717 R.style.Theme_MixedGradientTheme); 718 719 GradientDrawable drawable = (GradientDrawable) 720 context.getDrawable(R.drawable.gradientdrawable_mix_theme); 721 722 // Verify that despite multiple inflation passes are done to inflate both 723 // the non-theme attributes as well as the themed attributes 724 assertEquals(GradientDrawable.RADIAL_GRADIENT, drawable.getGradientType()); 725 assertEquals(87.0f, drawable.getGradientRadius(), 0.0f); 726 } 727 728 @Test 729 public void testRadialGradientWithInvalidRadius() { 730 final Context context = InstrumentationRegistry.getTargetContext(); 731 GradientDrawable radiusDrawable = (GradientDrawable) 732 context.getDrawable(R.drawable.gradientdrawable_invalid_radius); 733 734 Bitmap bitmap = Bitmap.createBitmap(10, 10, Bitmap.Config.ARGB_8888); 735 Canvas canvas = new Canvas(bitmap); 736 737 try { 738 radiusDrawable.setBounds(0, 0, 10, 10); 739 radiusDrawable.draw(canvas); 740 } catch (Exception e) { 741 fail("Threw exception: " + e + " with negative radius"); 742 } 743 } 744 745 @Test 746 public void testGradientNegativeAngle() { 747 final Context context = InstrumentationRegistry.getTargetContext(); 748 GradientDrawable drawable = (GradientDrawable) 749 context.getDrawable(R.drawable.gradientdrawable_negative_angle); 750 assertEquals(Orientation.TOP_BOTTOM, drawable.getOrientation()); 751 } 752 753 @Test 754 public void testGradientDrawableOrientationConstructor() { 755 GradientDrawable drawable = new GradientDrawable(Orientation.TOP_BOTTOM, null); 756 assertEquals(Orientation.TOP_BOTTOM, drawable.getOrientation()); 757 } 758 759 @Test 760 public void testInflatedGradientOrientationUpdated() { 761 final Context context = new ContextThemeWrapper(InstrumentationRegistry.getTargetContext(), 762 R.style.Theme_MixedGradientTheme); 763 764 GradientDrawable drawable = (GradientDrawable) 765 context.getDrawable(R.drawable.gradientdrawable); 766 767 assertEquals(Orientation.BL_TR, drawable.getOrientation()); 768 769 drawable.setOrientation(Orientation.BOTTOM_TOP); 770 assertEquals(Orientation.BOTTOM_TOP, drawable.getOrientation()); 771 } 772 773 private void verifyPreloadDensityInner(Resources res, int densityDpi) 774 throws XmlPullParserException, IOException { 775 final Rect tempPadding = new Rect(); 776 777 // Capture initial state at default density. 778 final XmlResourceParser parser = DrawableTestUtils.getResourceParser( 779 res, R.drawable.gradient_drawable_density); 780 final GradientDrawable preloadedDrawable = new GradientDrawable(); 781 preloadedDrawable.inflate(res, parser, Xml.asAttributeSet(parser)); 782 final ConstantState preloadedConstantState = preloadedDrawable.getConstantState(); 783 final int origWidth = preloadedDrawable.getIntrinsicWidth(); 784 final int origHeight = preloadedDrawable.getIntrinsicHeight(); 785 final Rect origPadding = new Rect(); 786 preloadedDrawable.getPadding(origPadding); 787 788 // Set density to approximately half of original. Unlike offsets, which are 789 // truncated, dimensions are rounded to the nearest pixel. 790 DrawableTestUtils.setResourcesDensity(res, densityDpi / 2); 791 final GradientDrawable halfDrawable = 792 (GradientDrawable) preloadedConstantState.newDrawable(res); 793 // NOTE: densityDpi may not be an even number, so account for *actual* scaling in asserts 794 final float approxHalf = (float)(densityDpi / 2) / densityDpi; 795 assertEquals(Math.round(origWidth * approxHalf), halfDrawable.getIntrinsicWidth()); 796 assertEquals(Math.round(origHeight * approxHalf), halfDrawable.getIntrinsicHeight()); 797 assertTrue(halfDrawable.getPadding(tempPadding)); 798 assertEquals((int) (origPadding.left * approxHalf), tempPadding.left); 799 800 // Set density to double original. 801 DrawableTestUtils.setResourcesDensity(res, densityDpi * 2); 802 final GradientDrawable doubleDrawable = 803 (GradientDrawable) preloadedConstantState.newDrawable(res); 804 assertEquals(origWidth * 2, doubleDrawable.getIntrinsicWidth()); 805 assertEquals(origHeight * 2, doubleDrawable.getIntrinsicHeight()); 806 assertTrue(doubleDrawable.getPadding(tempPadding)); 807 assertEquals(origPadding.left * 2, tempPadding.left); 808 809 // Restore original density. 810 DrawableTestUtils.setResourcesDensity(res, densityDpi); 811 final GradientDrawable origDrawable = 812 (GradientDrawable) preloadedConstantState.newDrawable(); 813 assertEquals(origWidth, origDrawable.getIntrinsicWidth()); 814 assertEquals(origHeight, origDrawable.getIntrinsicHeight()); 815 assertTrue(origDrawable.getPadding(tempPadding)); 816 assertEquals(origPadding, tempPadding); 817 818 // Reproduce imprecise truncated scale down, and back up. Note these aren't rounded. 819 final float approxDouble = 1 / approxHalf; 820 final Rect sloppyOrigPadding = new Rect(); 821 sloppyOrigPadding.left = (int)(approxDouble * ((int)(origPadding.left * approxHalf))); 822 sloppyOrigPadding.top = (int)(approxDouble * ((int)(origPadding.top * approxHalf))); 823 sloppyOrigPadding.right = (int)(approxDouble * ((int)(origPadding.right * approxHalf))); 824 sloppyOrigPadding.bottom = (int)(approxDouble * ((int)(origPadding.bottom * approxHalf))); 825 826 // Ensure theme density is applied correctly. 827 final Theme t = res.newTheme(); 828 halfDrawable.applyTheme(t); 829 assertEquals(Math.round(approxDouble * Math.round(origWidth * approxHalf)), 830 halfDrawable.getIntrinsicWidth()); 831 assertEquals(Math.round(approxDouble * Math.round(origHeight * approxHalf)), 832 halfDrawable.getIntrinsicHeight()); 833 assertTrue(halfDrawable.getPadding(tempPadding)); 834 assertEquals(sloppyOrigPadding, tempPadding); 835 doubleDrawable.applyTheme(t); 836 assertEquals(origWidth, doubleDrawable.getIntrinsicWidth()); 837 assertEquals(origHeight, doubleDrawable.getIntrinsicHeight()); 838 assertTrue(doubleDrawable.getPadding(tempPadding)); 839 assertEquals(origPadding, tempPadding); 840 } 841 } 842