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 import static org.mockito.ArgumentMatchers.anyInt; 28 import static org.mockito.Matchers.any; 29 import static org.mockito.Matchers.anyBoolean; 30 import static org.mockito.Matchers.anyLong; 31 import static org.mockito.Mockito.doAnswer; 32 import static org.mockito.Mockito.doNothing; 33 import static org.mockito.Mockito.doReturn; 34 import static org.mockito.Mockito.mock; 35 import static org.mockito.Mockito.never; 36 import static org.mockito.Mockito.reset; 37 import static org.mockito.Mockito.spy; 38 import static org.mockito.Mockito.times; 39 import static org.mockito.Mockito.verify; 40 41 import android.content.Context; 42 import android.content.res.ColorStateList; 43 import android.content.res.Resources; 44 import android.content.res.Resources.Theme; 45 import android.content.res.XmlResourceParser; 46 import android.graphics.BitmapFactory; 47 import android.graphics.Canvas; 48 import android.graphics.Color; 49 import android.graphics.ColorFilter; 50 import android.graphics.PixelFormat; 51 import android.graphics.PorterDuff; 52 import android.graphics.Rect; 53 import android.graphics.cts.R; 54 import android.graphics.drawable.BitmapDrawable; 55 import android.graphics.drawable.ColorDrawable; 56 import android.graphics.drawable.Drawable; 57 import android.graphics.drawable.Drawable.ConstantState; 58 import android.graphics.drawable.GradientDrawable; 59 import android.graphics.drawable.LayerDrawable; 60 import android.graphics.drawable.RippleDrawable; 61 import android.graphics.drawable.RotateDrawable; 62 import android.graphics.drawable.ShapeDrawable; 63 import android.graphics.drawable.StateListDrawable; 64 import android.util.AttributeSet; 65 import android.util.StateSet; 66 import android.util.Xml; 67 import android.view.Gravity; 68 import android.view.View; 69 70 import androidx.test.InstrumentationRegistry; 71 import androidx.test.filters.SmallTest; 72 import androidx.test.runner.AndroidJUnit4; 73 74 import org.junit.Before; 75 import org.junit.Test; 76 import org.junit.runner.RunWith; 77 import org.xmlpull.v1.XmlPullParserException; 78 79 import java.io.IOException; 80 81 @SmallTest 82 @RunWith(AndroidJUnit4.class) 83 public class LayerDrawableTest { 84 private Context mContext; 85 private ColorDrawable mColorDrawable; 86 private BitmapDrawable mBitmapDrawable; 87 88 @Before setup()89 public void setup() { 90 mContext = InstrumentationRegistry.getTargetContext(); 91 Resources resources = mContext.getResources(); 92 mColorDrawable = new ColorDrawable(Color.BLUE); 93 mBitmapDrawable = new BitmapDrawable(resources, 94 BitmapFactory.decodeResource(resources, R.drawable.icon_blue)); 95 } 96 97 @Test testConstructor()98 public void testConstructor() { 99 Drawable[] array = new Drawable[]{mBitmapDrawable, mColorDrawable}; 100 LayerDrawable layerDrawable = new LayerDrawable(array); 101 assertEquals(array.length, layerDrawable.getNumberOfLayers()); 102 assertSame(mBitmapDrawable, layerDrawable.getDrawable(0)); 103 assertSame(mColorDrawable, layerDrawable.getDrawable(1)); 104 105 array = new Drawable[0]; 106 layerDrawable = new LayerDrawable(array); 107 assertEquals(0, layerDrawable.getNumberOfLayers()); 108 } 109 110 @Test(expected=IllegalArgumentException.class) testConstructorNull()111 public void testConstructorNull() { 112 new LayerDrawable(null); 113 } 114 115 @Test testInflate()116 public void testInflate() throws XmlPullParserException, IOException { 117 Drawable[] array = new Drawable[0]; 118 LayerDrawable layerDrawable = new LayerDrawable(array); 119 120 XmlResourceParser parser = mContext.getResources().getXml(R.xml.layerdrawable); 121 AttributeSet attrs = DrawableTestUtils.getAttributeSet(parser, "layer-list_full"); 122 123 layerDrawable.inflate(mContext.getResources(), parser, attrs); 124 125 assertEquals(4, layerDrawable.getNumberOfLayers()); 126 assertEquals(ColorDrawable.class, layerDrawable.getDrawable(0).getClass()); 127 assertEquals(0x88, layerDrawable.getDrawable(0).getAlpha()); 128 assertEquals(View.NO_ID, layerDrawable.getId(0)); 129 assertEquals(BitmapDrawable.class, layerDrawable.getDrawable(1).getClass()); 130 assertEquals(View.NO_ID, layerDrawable.getId(1)); 131 assertEquals(RotateDrawable.class, layerDrawable.getDrawable(2).getClass()); 132 assertEquals(View.NO_ID, layerDrawable.getId(2)); 133 assertEquals(GradientDrawable.class, layerDrawable.getDrawable(3).getClass()); 134 assertEquals(R.id.background, layerDrawable.getId(3)); 135 136 layerDrawable = new LayerDrawable(array); 137 parser = mContext.getResources().getXml(R.xml.layerdrawable); 138 attrs = DrawableTestUtils.getAttributeSet(parser, "layer-list_empty"); 139 layerDrawable.inflate(mContext.getResources(), parser, attrs); 140 assertEquals(0, layerDrawable.getNumberOfLayers()); 141 142 parser = mContext.getResources().getXml(R.xml.layerdrawable); 143 attrs = DrawableTestUtils.getAttributeSet(parser, "layer-list_exception"); 144 try { 145 layerDrawable.inflate(mContext.getResources(), parser, attrs); 146 fail("Should throw XmlPullParserException if neither 'drawable' attribute" + 147 " nor child tag defining a drawable in <item> tag."); 148 } catch (XmlPullParserException e) { 149 } 150 151 try { 152 layerDrawable.inflate(null, parser, attrs); 153 fail("Should throw NullPointerException if resource is null"); 154 } catch (NullPointerException e) { 155 } 156 157 try { 158 layerDrawable.inflate(mContext.getResources(), null, attrs); 159 fail("Should throw NullPointerException if parser is null"); 160 } catch (NullPointerException e) { 161 } 162 163 try { 164 layerDrawable.inflate(mContext.getResources(), parser, null); 165 fail("Should throw NullPointerException if attribute set is null"); 166 } catch (NullPointerException e) { 167 } 168 } 169 170 @Test testFindDrawableByLayerId()171 public void testFindDrawableByLayerId() { 172 Drawable[] array = new Drawable[] { mBitmapDrawable, mColorDrawable }; 173 LayerDrawable layerDrawable = new LayerDrawable(array); 174 175 layerDrawable.setId(0, 10); 176 layerDrawable.setId(1, 20); 177 assertSame(mBitmapDrawable, layerDrawable.findDrawableByLayerId(10)); 178 assertSame(mColorDrawable, layerDrawable.findDrawableByLayerId(20)); 179 assertNull(layerDrawable.findDrawableByLayerId(30)); 180 181 layerDrawable.setId(0, Integer.MIN_VALUE); 182 layerDrawable.setId(1, Integer.MAX_VALUE); 183 assertSame(mBitmapDrawable, layerDrawable.findDrawableByLayerId(Integer.MIN_VALUE)); 184 assertSame(mColorDrawable, layerDrawable.findDrawableByLayerId(Integer.MAX_VALUE)); 185 186 layerDrawable.setId(0, 10); 187 layerDrawable.setId(1, 10); 188 assertSame(mColorDrawable, layerDrawable.findDrawableByLayerId(10)); 189 assertNull(layerDrawable.findDrawableByLayerId(30)); 190 } 191 192 @Test testAccessId()193 public void testAccessId() { 194 Drawable[] array = new Drawable[] { mBitmapDrawable, mColorDrawable }; 195 LayerDrawable layerDrawable = new LayerDrawable(array); 196 197 layerDrawable.setId(0, 10); 198 layerDrawable.setId(1, 20); 199 assertEquals(10, layerDrawable.getId(0)); 200 assertEquals(20, layerDrawable.getId(1)); 201 202 layerDrawable.setId(0, Integer.MIN_VALUE); 203 layerDrawable.setId(1, Integer.MAX_VALUE); 204 assertEquals(Integer.MIN_VALUE, layerDrawable.getId(0)); 205 assertEquals(Integer.MAX_VALUE, layerDrawable.getId(1)); 206 } 207 208 @Test(expected=IndexOutOfBoundsException.class) testSetIdIndexTooLow()209 public void testSetIdIndexTooLow() { 210 Drawable[] array = new Drawable[] { mBitmapDrawable, mColorDrawable }; 211 LayerDrawable layerDrawable = new LayerDrawable(array); 212 layerDrawable.setId(-1, 20); 213 } 214 215 @Test(expected=IndexOutOfBoundsException.class) testSetIdIndexTooHigh()216 public void testSetIdIndexTooHigh() { 217 Drawable[] array = new Drawable[] { mBitmapDrawable, mColorDrawable }; 218 LayerDrawable layerDrawable = new LayerDrawable(array); 219 layerDrawable.setId(layerDrawable.getNumberOfLayers(), 20); 220 } 221 222 @Test(expected=IndexOutOfBoundsException.class) testGetIdIndexTooLow()223 public void testGetIdIndexTooLow() { 224 Drawable[] array = new Drawable[] { mBitmapDrawable, mColorDrawable }; 225 LayerDrawable layerDrawable = new LayerDrawable(array); 226 layerDrawable.getId(-1); 227 } 228 229 @Test(expected=IndexOutOfBoundsException.class) testGetIdIndexTooHigh()230 public void testGetIdIndexTooHigh() { 231 Drawable[] array = new Drawable[] { mBitmapDrawable, mColorDrawable }; 232 LayerDrawable layerDrawable = new LayerDrawable(array); 233 layerDrawable.getId(layerDrawable.getNumberOfLayers()); 234 } 235 236 @Test testGetNumberOfLayers()237 public void testGetNumberOfLayers() { 238 Drawable[] array = new Drawable[] { mBitmapDrawable, mColorDrawable }; 239 LayerDrawable layerDrawable = new LayerDrawable(array); 240 assertEquals(2, layerDrawable.getNumberOfLayers()); 241 242 array = new Drawable[5]; 243 for (int i = 0; i < 5; i++) { 244 array[i] = new BitmapDrawable(); 245 } 246 layerDrawable = new LayerDrawable(array); 247 assertEquals(5, layerDrawable.getNumberOfLayers()); 248 249 array = new Drawable[0]; 250 layerDrawable = new LayerDrawable(array); 251 assertEquals(0, layerDrawable.getNumberOfLayers()); 252 } 253 254 @Test testAccessDrawable()255 public void testAccessDrawable() { 256 Drawable[] array = new Drawable[] { mBitmapDrawable, mColorDrawable }; 257 LayerDrawable layerDrawable = new LayerDrawable(array); 258 assertSame(mBitmapDrawable, layerDrawable.getDrawable(0)); 259 assertSame(mColorDrawable, layerDrawable.getDrawable(1)); 260 261 layerDrawable.setId(0, 10); 262 layerDrawable.setId(1, 20); 263 Drawable d1 = new ColorDrawable(Color.GREEN); 264 Drawable d2 = new BitmapDrawable(); 265 layerDrawable.setDrawableByLayerId(10, d1); 266 layerDrawable.setDrawableByLayerId(20, d2); 267 assertEquals(d1, layerDrawable.getDrawable(0)); 268 assertEquals(d2, layerDrawable.getDrawable(1)); 269 270 assertFalse(layerDrawable.setDrawableByLayerId(30, d1)); 271 272 try { 273 layerDrawable.getDrawable(layerDrawable.getNumberOfLayers()); 274 fail("Should throw IndexOutOfBoundsException"); 275 } catch (IndexOutOfBoundsException e) { 276 } 277 278 try { 279 layerDrawable.getDrawable(-1); 280 fail("Should throw IndexOutOfBoundsException"); 281 } catch (IndexOutOfBoundsException e) { 282 } 283 } 284 285 @Test testSetDrawableByLayerId()286 public void testSetDrawableByLayerId() { 287 Drawable layer1A = new ColorDrawable(Color.RED); 288 Drawable layer2A = new ColorDrawable(Color.BLUE); 289 LayerDrawable layerDrawable = new LayerDrawable(new Drawable[] { layer1A, layer2A }); 290 layerDrawable.setId(0, 10); 291 layerDrawable.setId(1, 20); 292 293 Drawable layer1B = new ColorDrawable(Color.GREEN); 294 layer1B.setLevel(10000); 295 Drawable layer2B = new ColorDrawable(Color.YELLOW); 296 layer2B.setLevel(5000); 297 layerDrawable.setDrawableByLayerId(10, layer1B); 298 layerDrawable.setDrawableByLayerId(20, layer2B); 299 300 assertEquals("Level is unchanged after setDrawableByLayerId()", 301 10000, layerDrawable.findDrawableByLayerId(10).getLevel()); 302 assertEquals("Level is unchanged after setDrawableByLayerId()", 303 5000, layerDrawable.findDrawableByLayerId(20).getLevel()); 304 } 305 306 @Test testSetLayerInset()307 public void testSetLayerInset() { 308 Drawable firstLayer = spy(new ColorDrawable(Color.YELLOW)); 309 doReturn(10).when(firstLayer).getIntrinsicWidth(); 310 doReturn(10).when(firstLayer).getIntrinsicHeight(); 311 Drawable secondLayer = spy(new ColorDrawable(Color.YELLOW)); 312 doReturn(-1).when(secondLayer).getIntrinsicWidth(); 313 doReturn(-1).when(secondLayer).getIntrinsicHeight(); 314 315 Drawable[] array = new Drawable[] { firstLayer, secondLayer }; 316 LayerDrawable layerDrawable = new LayerDrawable(array); 317 318 // set inset for layer 0 319 int left = 10; 320 int top = 20; 321 int right = 30; 322 int bottom = 40; 323 layerDrawable.setLayerInset(0, left, top, right, bottom); 324 assertEquals(layerDrawable.getDrawable(0).getIntrinsicWidth() + left + right, 325 layerDrawable.getIntrinsicWidth()); 326 assertEquals(layerDrawable.getDrawable(0).getIntrinsicHeight() + top + bottom, 327 layerDrawable.getIntrinsicHeight()); 328 329 // The drawable at index 0 has no intrinsic width or height, so it 330 // won't be counted for the overall intrinsic width or height. 331 layerDrawable.setLayerInset(1, 10, 10, 10, 10); 332 assertEquals(layerDrawable.getDrawable(0).getIntrinsicWidth() + left + right, 333 layerDrawable.getIntrinsicWidth()); 334 assertEquals(layerDrawable.getDrawable(0).getIntrinsicHeight() + top + bottom, 335 layerDrawable.getIntrinsicHeight()); 336 337 try { 338 layerDrawable.setLayerInset(-1, left, top, right, bottom); 339 fail("Should throw IndexOutOfBoundsException"); 340 } catch (IndexOutOfBoundsException e) { 341 } 342 } 343 344 @Test testInvalidateDrawable()345 public void testInvalidateDrawable() { 346 Drawable[] array = new Drawable[0]; 347 LayerDrawable layerDrawable = new LayerDrawable(array); 348 349 Drawable.Callback cb = mock(Drawable.Callback.class); 350 layerDrawable.setCallback(cb); 351 layerDrawable.invalidateDrawable(null); 352 verify(cb, times(1)).invalidateDrawable(any()); 353 354 reset(cb); 355 layerDrawable.invalidateDrawable(new BitmapDrawable()); 356 verify(cb, times(1)).invalidateDrawable(any()); 357 358 reset(cb); 359 layerDrawable.setCallback(null); 360 layerDrawable.invalidateDrawable(null); 361 verify(cb, never()).invalidateDrawable(any()); 362 } 363 364 @Test testScheduleDrawable()365 public void testScheduleDrawable() { 366 Drawable[] array = new Drawable[0]; 367 LayerDrawable layerDrawable = new LayerDrawable(array); 368 369 Drawable.Callback cb = mock(Drawable.Callback.class); 370 layerDrawable.setCallback(cb); 371 layerDrawable.scheduleDrawable(null, null, 0); 372 verify(cb, times(1)).scheduleDrawable(any(), any(), anyLong()); 373 374 reset(cb); 375 layerDrawable.scheduleDrawable(mBitmapDrawable, () -> {}, 1000L); 376 verify(cb, times(1)).scheduleDrawable(any(), any(), anyLong()); 377 378 reset(cb); 379 layerDrawable.setCallback(null); 380 layerDrawable.scheduleDrawable(null, null, 0); 381 verify(cb, never()).scheduleDrawable(any(), any(), anyLong()); 382 } 383 384 @Test testUnscheduleDrawable()385 public void testUnscheduleDrawable() { 386 Drawable[] array = new Drawable[0]; 387 LayerDrawable layerDrawable = new LayerDrawable(array); 388 389 Drawable.Callback cb = mock(Drawable.Callback.class); 390 layerDrawable.setCallback(cb); 391 layerDrawable.unscheduleDrawable(null, null); 392 verify(cb, times(1)).unscheduleDrawable(any(), any()); 393 394 reset(cb); 395 layerDrawable.unscheduleDrawable(mBitmapDrawable, () -> {}); 396 verify(cb, times(1)).unscheduleDrawable(any(), any()); 397 398 reset(cb); 399 layerDrawable.setCallback(null); 400 layerDrawable.unscheduleDrawable(null, null); 401 verify(cb, never()).unscheduleDrawable(any(), any()); 402 } 403 404 @Test testDraw()405 public void testDraw() { 406 Drawable mockDrawable1 = spy(new ColorDrawable(Color.BLUE)); 407 Drawable mockDrawable2 = spy(new ColorDrawable(Color.RED)); 408 Drawable[] array = new Drawable[] { mockDrawable1, mockDrawable2 }; 409 LayerDrawable layerDrawable = new LayerDrawable(array); 410 411 // this method will call each child's draw(). 412 layerDrawable.draw(new Canvas()); 413 verify(mockDrawable1, times(1)).draw(any()); 414 verify(mockDrawable2, times(1)).draw(any()); 415 416 reset(mockDrawable1); 417 reset(mockDrawable2); 418 doNothing().when(mockDrawable1).draw(any()); 419 doNothing().when(mockDrawable2).draw(any()); 420 layerDrawable.draw(null); 421 verify(mockDrawable1, times(1)).draw(any()); 422 verify(mockDrawable2, times(1)).draw(any()); 423 } 424 425 @Test testGetChangingConfigurations()426 public void testGetChangingConfigurations() { 427 final int superConfig = 1; 428 final int gradientDrawableConfig = 2; 429 final int colorDrawableConfig = 4; 430 final int childConfig = gradientDrawableConfig | colorDrawableConfig; 431 432 mBitmapDrawable.setChangingConfigurations(gradientDrawableConfig); 433 mColorDrawable.setChangingConfigurations(colorDrawableConfig); 434 Drawable[] array = new Drawable[] { mBitmapDrawable, mColorDrawable }; 435 LayerDrawable layerDrawable = new LayerDrawable(array); 436 437 assertEquals(childConfig, layerDrawable.getChangingConfigurations()); 438 439 layerDrawable.setChangingConfigurations(superConfig); 440 assertEquals(superConfig | childConfig, layerDrawable.getChangingConfigurations()); 441 } 442 443 @Test testAccessPadding()444 public void testAccessPadding() { 445 Drawable[] array = new Drawable[] { new ShapeDrawable(), new ShapeDrawable() }; 446 LayerDrawable layerDrawable = new LayerDrawable(array); 447 448 Rect rc = new Rect(); 449 layerDrawable.getPadding(rc); 450 assertEquals(0, rc.left); 451 assertEquals(0, rc.top); 452 assertEquals(0, rc.right); 453 assertEquals(0, rc.bottom); 454 455 Rect padding0 = new Rect(10, 20, 30, 40); 456 ((ShapeDrawable) layerDrawable.getDrawable(0)).setPadding(padding0); 457 layerDrawable.getPadding(rc); 458 assertEquals(padding0.left, rc.left); 459 assertEquals(padding0.top, rc.top); 460 assertEquals(padding0.right, rc.right); 461 assertEquals(padding0.bottom, rc.bottom); 462 463 Rect padding1 = new Rect(20, 30, 40, 50); 464 ((ShapeDrawable) layerDrawable.getDrawable(1)).setPadding(padding1); 465 layerDrawable.getPadding(rc); 466 assertEquals(padding0.left + padding1.left, rc.left); 467 assertEquals(padding0.top + padding1.top, rc.top); 468 assertEquals(padding0.right + padding1.right, rc.right); 469 assertEquals(padding0.bottom + padding1.bottom, rc.bottom); 470 } 471 472 @Test testAccessPaddingMode()473 public void testAccessPaddingMode() { 474 Rect padding = new Rect(); 475 Drawable dr0 = new IntrinsicSizeDrawable(20, 30, new Rect(1, 2, 3, 4)); 476 Drawable dr1 = new IntrinsicSizeDrawable(30, 40, new Rect(9, 8, 7, 6)); 477 LayerDrawable layerDrawable = new LayerDrawable(new Drawable[] { dr0, dr1 }); 478 479 assertEquals("Default padding mode is NEST", 480 LayerDrawable.PADDING_MODE_NEST, layerDrawable.getPaddingMode()); 481 assertEquals(34, layerDrawable.getIntrinsicWidth()); 482 assertEquals(46, layerDrawable.getIntrinsicHeight()); 483 assertTrue(layerDrawable.getPadding(padding)); 484 assertEquals(new Rect(10, 10, 10, 10), padding); 485 486 layerDrawable.setPaddingMode(LayerDrawable.PADDING_MODE_STACK); 487 assertEquals(LayerDrawable.PADDING_MODE_STACK, layerDrawable.getPaddingMode()); 488 assertEquals(30, layerDrawable.getIntrinsicWidth()); 489 assertEquals(40, layerDrawable.getIntrinsicHeight()); 490 assertTrue(layerDrawable.getPadding(padding)); 491 assertEquals(new Rect(9, 8, 7, 6), padding); 492 } 493 494 @Test testSetVisible()495 public void testSetVisible() { 496 Drawable[] array = new Drawable[] { mBitmapDrawable, mColorDrawable }; 497 LayerDrawable layerDrawable = new LayerDrawable(array); 498 499 assertTrue(layerDrawable.setVisible(false, true)); 500 assertFalse(layerDrawable.isVisible()); 501 assertFalse(layerDrawable.getDrawable(0).isVisible()); 502 assertFalse(layerDrawable.getDrawable(1).isVisible()); 503 504 assertFalse(layerDrawable.setVisible(false, false)); 505 506 assertTrue(layerDrawable.setVisible(true, false)); 507 assertTrue(layerDrawable.isVisible()); 508 assertTrue(layerDrawable.getDrawable(0).isVisible()); 509 assertTrue(layerDrawable.getDrawable(1).isVisible()); 510 } 511 512 @Test testSetDither()513 public void testSetDither() { 514 Drawable mockDrawable1 = spy(new ColorDrawable(Color.BLUE)); 515 Drawable mockDrawable2 = spy(new ColorDrawable(Color.BLACK)); 516 Drawable[] array = new Drawable[] { mockDrawable1, mockDrawable2 }; 517 LayerDrawable layerDrawable = new LayerDrawable(array); 518 519 layerDrawable.setDither(true); 520 verify(mockDrawable1, times(1)).setDither(anyBoolean()); 521 verify(mockDrawable2, times(1)).setDither(anyBoolean()); 522 523 reset(mockDrawable1); 524 reset(mockDrawable2); 525 layerDrawable.setDither(false); 526 verify(mockDrawable1, times(1)).setDither(anyBoolean()); 527 verify(mockDrawable2, times(1)).setDither(anyBoolean()); 528 } 529 530 @Test testSetHotspotBounds()531 public void testSetHotspotBounds() { 532 Rect bounds = new Rect(10, 15, 100, 150); 533 Drawable mockDrawable1 = new ColorDrawable(Color.BLUE); 534 Drawable mockDrawable2 = new ColorDrawable(Color.GREEN); 535 Drawable[] array = new Drawable[] { mockDrawable1, mockDrawable2 }; 536 LayerDrawable layerDrawable = new LayerDrawable(array); 537 538 layerDrawable.setHotspotBounds(bounds.left, bounds.top, bounds.right, bounds.bottom); 539 Rect outRect = new Rect(); 540 layerDrawable.getHotspotBounds(outRect); 541 assertTrue(bounds.equals(outRect)); 542 } 543 544 @Test testGetHotspotBounds()545 public void testGetHotspotBounds() { 546 Rect bounds = new Rect(10, 15, 100, 150); 547 Drawable mockDrawable1 = new ColorDrawable(Color.BLUE); 548 Drawable mockDrawable2 = new ColorDrawable(Color.GREEN); 549 Drawable[] array = new Drawable[] { mockDrawable1, mockDrawable2 }; 550 LayerDrawable layerDrawable = new LayerDrawable(array); 551 552 layerDrawable.setHotspotBounds(bounds.left, bounds.top, bounds.right, bounds.bottom); 553 Rect outRect = new Rect(); 554 layerDrawable.getHotspotBounds(outRect); 555 assertTrue(bounds.equals(outRect)); 556 } 557 558 @Test testSetAlpha()559 public void testSetAlpha() { 560 Drawable mockDrawable1 = spy(new ColorDrawable(Color.BLUE)); 561 Drawable mockDrawable2 = spy(new ColorDrawable(Color.BLACK)); 562 Drawable[] array = new Drawable[] { mockDrawable1, mockDrawable2 }; 563 LayerDrawable layerDrawable = new LayerDrawable(array); 564 565 layerDrawable.setAlpha(0); 566 verify(mockDrawable1, times(1)).setAlpha(anyInt()); 567 verify(mockDrawable2, times(1)).setAlpha(anyInt()); 568 569 reset(mockDrawable1); 570 reset(mockDrawable2); 571 layerDrawable.setAlpha(Integer.MAX_VALUE); 572 verify(mockDrawable1, times(1)).setAlpha(anyInt()); 573 verify(mockDrawable2, times(1)).setAlpha(anyInt()); 574 } 575 576 @Test testSetColorFilter()577 public void testSetColorFilter() { 578 Drawable mockDrawable1 = spy(new ColorDrawable(Color.BLUE)); 579 Drawable mockDrawable2 = spy(new ColorDrawable(Color.BLACK)); 580 Drawable[] array = new Drawable[] { mockDrawable1, mockDrawable2 }; 581 LayerDrawable layerDrawable = new LayerDrawable(array); 582 583 layerDrawable.setColorFilter(new ColorFilter()); 584 verify(mockDrawable1, times(1)).setColorFilter(any()); 585 verify(mockDrawable2, times(1)).setColorFilter(any()); 586 587 reset(mockDrawable1); 588 reset(mockDrawable2); 589 layerDrawable.setColorFilter(null); 590 verify(mockDrawable1, times(1)).setColorFilter(any()); 591 verify(mockDrawable2, times(1)).setColorFilter(any()); 592 } 593 594 @Test testAccessOpacity()595 public void testAccessOpacity() { 596 Drawable[] array = new Drawable[0]; 597 LayerDrawable layerDrawable = new LayerDrawable(array); 598 assertEquals(PixelFormat.TRANSPARENT, layerDrawable.getOpacity()); 599 600 Drawable mockDrawable1 = spy(new ColorDrawable(Color.BLUE)); 601 Drawable mockDrawable2 = spy(new ColorDrawable(Color.GREEN)); 602 array = new Drawable[] { mockDrawable1, mockDrawable2 }; 603 layerDrawable = new LayerDrawable(array); 604 assertEquals(PixelFormat.OPAQUE, layerDrawable.getOpacity()); 605 606 layerDrawable = new LayerDrawable(array); 607 doReturn(PixelFormat.OPAQUE).when(mockDrawable1).getOpacity(); 608 doReturn(PixelFormat.TRANSPARENT).when(mockDrawable2).getOpacity(); 609 assertEquals(PixelFormat.TRANSPARENT, layerDrawable.getOpacity()); 610 611 layerDrawable = new LayerDrawable(array); 612 doReturn(PixelFormat.TRANSLUCENT).when(mockDrawable1).getOpacity(); 613 doReturn(PixelFormat.TRANSPARENT).when(mockDrawable2).getOpacity(); 614 assertEquals(PixelFormat.TRANSLUCENT, layerDrawable.getOpacity()); 615 616 layerDrawable = new LayerDrawable(array); 617 doReturn(PixelFormat.TRANSLUCENT).when(mockDrawable1).getOpacity(); 618 doReturn(PixelFormat.UNKNOWN).when(mockDrawable2).getOpacity(); 619 assertEquals(PixelFormat.UNKNOWN, layerDrawable.getOpacity()); 620 621 layerDrawable = new LayerDrawable(array); 622 layerDrawable.setOpacity(PixelFormat.OPAQUE); 623 doReturn(PixelFormat.TRANSLUCENT).when(mockDrawable1).getOpacity(); 624 doReturn(PixelFormat.UNKNOWN).when(mockDrawable2).getOpacity(); 625 assertEquals(PixelFormat.OPAQUE, layerDrawable.getOpacity()); 626 627 } 628 629 @Test testIsStateful()630 public void testIsStateful() { 631 Drawable[] array = new Drawable[0]; 632 LayerDrawable layerDrawable = new LayerDrawable(array); 633 assertFalse(layerDrawable.isStateful()); 634 635 array = new Drawable[] { new GradientDrawable(), new MockDrawable(false) }; 636 layerDrawable = new LayerDrawable(array); 637 assertFalse(layerDrawable.isStateful()); 638 639 array = new Drawable[] { new GradientDrawable(), new StateListDrawable() }; 640 layerDrawable = new LayerDrawable(array); 641 assertTrue(layerDrawable.isStateful()); 642 } 643 644 @Test testSetState()645 public void testSetState() { 646 MockDrawable mockDrawable1 = new MockDrawable(true); 647 MockDrawable mockDrawable2 = new MockDrawable(true); 648 Drawable[] array = new Drawable[] { mockDrawable1, mockDrawable2 }; 649 LayerDrawable layerDrawable = new LayerDrawable(array); 650 651 // Call onStateChange() without actually changing the state. 652 assertFalse(layerDrawable.setState(StateSet.WILD_CARD)); 653 assertFalse(mockDrawable1.hasCalledSetState()); 654 assertFalse(mockDrawable2.hasCalledSetState()); 655 assertFalse(mockDrawable1.hasCalledOnBoundsChange()); 656 assertFalse(mockDrawable2.hasCalledOnBoundsChange()); 657 658 // Call onStateChange() to change the state from WILD_CARD to null. 659 // This alters the padding of both layers, which forces a bounds change 660 // for the second layer due to the default "nest" padding mode. 661 mockDrawable1.reset(); 662 mockDrawable2.reset(); 663 assertTrue(layerDrawable.setState(null)); 664 assertTrue(mockDrawable1.hasCalledSetState()); 665 assertTrue(mockDrawable2.hasCalledSetState()); 666 assertFalse(mockDrawable1.hasCalledOnBoundsChange()); 667 assertTrue(mockDrawable2.hasCalledOnBoundsChange()); 668 669 // Call onStateChange() to change the state from null to valid state 670 // set. This alters the padding of both layers, which forces a bounds 671 // change for the second layer due to the default "nest" padding mode. 672 mockDrawable1.reset(); 673 mockDrawable2.reset(); 674 assertTrue(layerDrawable.setState(new int[]{ 675 android.R.attr.state_checked, android.R.attr.state_empty})); 676 assertTrue(mockDrawable1.hasCalledSetState()); 677 assertTrue(mockDrawable2.hasCalledSetState()); 678 assertFalse(mockDrawable1.hasCalledOnBoundsChange()); 679 assertTrue(mockDrawable2.hasCalledOnBoundsChange()); 680 } 681 682 @Test testJumpToCurrentState()683 public void testJumpToCurrentState() { 684 Drawable mockDrawable1 = spy(new ColorDrawable(Color.BLUE)); 685 Drawable mockDrawable2 = spy(new ColorDrawable(Color.BLACK)); 686 Drawable[] array = new Drawable[] { mockDrawable1, mockDrawable2 }; 687 LayerDrawable layerDrawable = new LayerDrawable(array); 688 689 verify(mockDrawable1, never()).jumpToCurrentState(); 690 verify(mockDrawable2, never()).jumpToCurrentState(); 691 692 layerDrawable.jumpToCurrentState(); 693 694 verify(mockDrawable1, times(1)).jumpToCurrentState(); 695 verify(mockDrawable2, times(1)).jumpToCurrentState(); 696 } 697 698 @Test testSetLevel()699 public void testSetLevel() { 700 MockDrawable mockDrawable1 = new MockDrawable(); 701 MockDrawable mockDrawable2 = new MockDrawable(); 702 Drawable[] array = new Drawable[] { mockDrawable1, mockDrawable2 }; 703 LayerDrawable layerDrawable = new LayerDrawable(array); 704 705 // Call onLevelChange() without actually changing the level. 706 assertFalse(layerDrawable.setLevel(0)); 707 assertFalse(mockDrawable1.hasCalledOnLevelChange()); 708 assertFalse(mockDrawable2.hasCalledOnLevelChange()); 709 assertFalse(mockDrawable1.hasCalledOnBoundsChange()); 710 assertFalse(mockDrawable2.hasCalledOnBoundsChange()); 711 712 // Call onLevelChange() to change the level from 0 to MAX_VALUE. This 713 // alters the padding of both layers, which forces a bounds change for 714 // the second layer due to the default "nest" padding mode. 715 mockDrawable1.reset(); 716 mockDrawable2.reset(); 717 assertTrue(layerDrawable.setLevel(Integer.MAX_VALUE)); 718 assertTrue(mockDrawable1.hasCalledOnLevelChange()); 719 assertTrue(mockDrawable2.hasCalledOnLevelChange()); 720 assertFalse(mockDrawable1.hasCalledOnBoundsChange()); 721 assertTrue(mockDrawable2.hasCalledOnBoundsChange()); 722 723 // Call onLevelChange() to change the level from MAX_VALUE to 724 // MIN_VALUE. This alters the padding of both layers, which forces a 725 // bounds change for the second layer due to the default "nest" padding 726 // mode. 727 mockDrawable1.reset(); 728 mockDrawable2.reset(); 729 assertTrue(layerDrawable.setLevel(Integer.MIN_VALUE)); 730 assertTrue(mockDrawable1.hasCalledOnLevelChange()); 731 assertTrue(mockDrawable2.hasCalledOnLevelChange()); 732 assertFalse(mockDrawable1.hasCalledOnBoundsChange()); 733 assertTrue(mockDrawable2.hasCalledOnBoundsChange()); 734 } 735 736 @Test testSetBounds()737 public void testSetBounds() { 738 Drawable mockDrawable1 = spy(new ColorDrawable(Color.GREEN)); 739 Drawable mockDrawable2 = spy(new ColorDrawable(Color.BLUE)); 740 Drawable[] array = new Drawable[] { mockDrawable1, mockDrawable2 }; 741 LayerDrawable layerDrawable = new LayerDrawable(array); 742 743 Rect inset1 = new Rect(1, 2, 3, 4); 744 Rect inset2 = new Rect(2, 4, 6, 7); 745 Rect padding1 = new Rect(11, 22, 33, 44); 746 Rect padding2 = new Rect(21, 32, 43, 54); 747 layerDrawable.setLayerInset(0, inset1.left, inset1.top, inset1.right, inset1.bottom); 748 layerDrawable.setLayerInset(1, inset2.left, inset2.top, inset2.right, inset2.bottom); 749 doAnswer(invocation -> { 750 Rect target = (Rect) invocation.getArguments() [0]; 751 target.set(padding1); 752 return true; 753 }).when(mockDrawable1).getPadding(any()); 754 doAnswer(invocation -> { 755 Rect target = (Rect) invocation.getArguments() [0]; 756 target.set(padding2); 757 return true; 758 }).when(mockDrawable2).getPadding(any()); 759 layerDrawable.getPadding(new Rect()); 760 761 // the children's bounds before call onBoundsChange 762 assertEquals(0, mockDrawable1.getBounds().left); 763 assertEquals(0, mockDrawable1.getBounds().top); 764 assertEquals(0, mockDrawable1.getBounds().right); 765 assertEquals(0, mockDrawable1.getBounds().bottom); 766 assertEquals(0, mockDrawable2.getBounds().left); 767 assertEquals(0, mockDrawable2.getBounds().top); 768 assertEquals(0, mockDrawable2.getBounds().right); 769 assertEquals(0, mockDrawable2.getBounds().bottom); 770 771 Rect bounds = new Rect(10, 20, 30, 40); 772 layerDrawable.setBounds(bounds); 773 774 // all children's bounds will be changed after call onBoundsChange 775 assertEquals(bounds.left + inset1.left, mockDrawable1.getBounds().left); 776 assertEquals(bounds.top + inset1.top, mockDrawable1.getBounds().top); 777 assertEquals(bounds.right - inset1.right, mockDrawable1.getBounds().right); 778 assertEquals(bounds.bottom - inset1.bottom, mockDrawable1.getBounds().bottom); 779 assertEquals(bounds.left + inset2.left + padding1.left, mockDrawable2.getBounds().left); 780 assertEquals(bounds.top + inset2.top + padding1.top, mockDrawable2.getBounds().top); 781 assertEquals(bounds.right - inset2.right - padding1.right, 782 mockDrawable2.getBounds().right); 783 assertEquals(bounds.bottom - inset2.bottom - padding1.bottom, 784 mockDrawable2.getBounds().bottom); 785 } 786 787 @Test testGetIntrinsicWidth()788 public void testGetIntrinsicWidth() { 789 Drawable largeMockDrawable = spy(new ColorDrawable(Color.YELLOW)); 790 doReturn(10).when(largeMockDrawable).getIntrinsicWidth(); 791 doReturn(10).when(largeMockDrawable).getIntrinsicHeight(); 792 Drawable smallMockDrawable = spy(new ColorDrawable(Color.MAGENTA)); 793 doReturn(1).when(smallMockDrawable).getIntrinsicWidth(); 794 doReturn(1).when(smallMockDrawable).getIntrinsicHeight(); 795 796 Drawable[] array = new Drawable[] { largeMockDrawable, smallMockDrawable }; 797 LayerDrawable layerDrawable = new LayerDrawable(array); 798 assertEquals(largeMockDrawable.getIntrinsicWidth(), layerDrawable.getIntrinsicWidth()); 799 800 Rect inset1 = new Rect(1, 2, 3, 4); 801 Rect inset2 = new Rect(2, 4, 6, 7); 802 final Rect padding1 = new Rect(11, 22, 33, 44); 803 final Rect padding2 = new Rect(21, 32, 43, 54); 804 layerDrawable.setLayerInset(0, inset1.left, inset1.top, inset1.right, inset1.bottom); 805 layerDrawable.setLayerInset(1, inset2.left, inset2.top, inset2.right, inset2.bottom); 806 807 doAnswer(invocation -> { 808 Rect target = (Rect) invocation.getArguments() [0]; 809 target.set(padding1); 810 return true; 811 }).when(largeMockDrawable).getPadding(any()); 812 doAnswer(invocation -> { 813 Rect target = (Rect) invocation.getArguments() [0]; 814 target.set(padding2); 815 return true; 816 }).when(smallMockDrawable).getPadding(any()); 817 818 layerDrawable.getPadding(new Rect()); 819 assertEquals(smallMockDrawable.getIntrinsicWidth() + inset2.left 820 + inset2.right + padding1.left + padding1.right, 821 layerDrawable.getIntrinsicWidth()); 822 823 inset1 = new Rect(inset2.left + padding1.left + 1, inset2.top + padding1.top + 1, 824 inset2.right + padding1.right + 1, inset2.bottom + padding1.bottom + 1); 825 layerDrawable.setLayerInset(0, inset1.left, inset1.top, inset1.right, inset1.bottom); 826 assertEquals(largeMockDrawable.getIntrinsicWidth() + inset1.left + inset1.right, 827 layerDrawable.getIntrinsicWidth()); 828 } 829 830 @Test testGetIntrinsicHeight()831 public void testGetIntrinsicHeight() { 832 Drawable largeMockDrawable = spy(new ColorDrawable(Color.CYAN)); 833 doReturn(10).when(largeMockDrawable).getIntrinsicWidth(); 834 doReturn(10).when(largeMockDrawable).getIntrinsicHeight(); 835 Drawable smallMockDrawable = spy(new ColorDrawable(Color.DKGRAY)); 836 doReturn(1).when(smallMockDrawable).getIntrinsicWidth(); 837 doReturn(1).when(smallMockDrawable).getIntrinsicHeight(); 838 839 Drawable[] array = new Drawable[] { largeMockDrawable, smallMockDrawable }; 840 LayerDrawable layerDrawable = new LayerDrawable(array); 841 assertEquals(largeMockDrawable.getIntrinsicHeight(), layerDrawable.getIntrinsicHeight()); 842 843 Rect inset1 = new Rect(1, 2, 3, 4); 844 Rect inset2 = new Rect(2, 4, 6, 7); 845 final Rect padding1 = new Rect(11, 22, 33, 44); 846 final Rect padding2 = new Rect(21, 32, 43, 54); 847 layerDrawable.setLayerInset(0, inset1.left, inset1.top, inset1.right, inset1.bottom); 848 layerDrawable.setLayerInset(1, inset2.left, inset2.top, inset2.right, inset2.bottom); 849 850 doAnswer(invocation -> { 851 Rect target = (Rect) invocation.getArguments() [0]; 852 target.set(padding1); 853 return true; 854 }).when(largeMockDrawable).getPadding(any()); 855 doAnswer(invocation -> { 856 Rect target = (Rect) invocation.getArguments() [0]; 857 target.set(padding2); 858 return true; 859 }).when(smallMockDrawable).getPadding(any()); 860 861 layerDrawable.getPadding(new Rect()); 862 assertEquals(smallMockDrawable.getIntrinsicHeight() + inset2.top 863 + inset2.bottom + padding1.top + padding1.bottom, 864 layerDrawable.getIntrinsicHeight()); 865 866 inset1 = new Rect(inset2.left + padding1.left + 1, inset2.top + padding1.top + 1, 867 inset2.right + padding1.right + 1, inset2.bottom + padding1.bottom + 1); 868 layerDrawable.setLayerInset(0, inset1.left, inset1.top, inset1.right, inset1.bottom); 869 assertEquals(largeMockDrawable.getIntrinsicHeight() + inset1.top + inset1.bottom, 870 layerDrawable.getIntrinsicHeight()); 871 } 872 873 @Test testGetConstantState()874 public void testGetConstantState() { 875 Drawable[] array = new Drawable[] { mBitmapDrawable, mColorDrawable }; 876 LayerDrawable layerDrawable = new LayerDrawable(array); 877 ConstantState constantState = layerDrawable.getConstantState(); 878 assertNotNull(constantState); 879 assertEquals(0, constantState.getChangingConfigurations()); 880 881 layerDrawable.setChangingConfigurations(1); 882 constantState = layerDrawable.getConstantState(); 883 assertNotNull(constantState); 884 assertEquals(1, constantState.getChangingConfigurations()); 885 } 886 887 @Test testAddLayer()888 public void testAddLayer() { 889 Drawable[] array = new Drawable[] { new GradientDrawable(), new ColorDrawable(Color.BLUE) }; 890 LayerDrawable layerDrawable = new LayerDrawable(array); 891 GradientDrawable newDrawable = new GradientDrawable(); 892 int index = layerDrawable.addLayer(newDrawable); 893 894 final int numLayers = layerDrawable.getNumberOfLayers(); 895 assertEquals(index, numLayers - 1); 896 assertEquals(newDrawable, layerDrawable.getDrawable(index)); 897 } 898 899 @Test testGetDrawable()900 public void testGetDrawable() { 901 Drawable[] array = new Drawable[] { mBitmapDrawable, mColorDrawable }; 902 LayerDrawable layerDrawable = new LayerDrawable(array); 903 904 assertEquals(array[0], layerDrawable.getDrawable(0)); 905 assertEquals(array[1], layerDrawable.getDrawable(1)); 906 try { 907 assertEquals(null, layerDrawable.getDrawable(2)); 908 fail("Should throw IndexOutOfBoundsException"); 909 } catch (IndexOutOfBoundsException e) { 910 } 911 } 912 913 @Test testFindIndexByLayerId()914 public void testFindIndexByLayerId() { 915 Drawable[] array = new Drawable[] { mBitmapDrawable, mColorDrawable }; 916 LayerDrawable layerDrawable = new LayerDrawable(array); 917 918 layerDrawable.setId(0, 10); 919 layerDrawable.setId(1, 20); 920 921 assertEquals(0, layerDrawable.findIndexByLayerId(10)); 922 assertEquals(1, layerDrawable.findIndexByLayerId(20)); 923 assertEquals(-1, layerDrawable.findIndexByLayerId(30)); 924 } 925 926 @Test testSetDrawable()927 public void testSetDrawable() { 928 Drawable[] array = new Drawable[] { mBitmapDrawable, mColorDrawable }; 929 LayerDrawable layerDrawable = new LayerDrawable(array); 930 BitmapDrawable newBitmapDrawable = new BitmapDrawable(); 931 ColorDrawable newColorDrawable = new ColorDrawable(Color.GREEN); 932 layerDrawable.setDrawable(0, newColorDrawable); 933 layerDrawable.setDrawable(1, newBitmapDrawable); 934 935 final int numLayers = layerDrawable.getNumberOfLayers(); 936 assertEquals(2, numLayers); 937 assertEquals(newColorDrawable, layerDrawable.getDrawable(0)); 938 assertEquals(newBitmapDrawable, layerDrawable.getDrawable(1)); 939 try { 940 assertEquals(null, layerDrawable.getDrawable(2)); 941 fail("Should throw IndexOutOfBoundsException"); 942 } catch (IndexOutOfBoundsException e) { 943 } 944 } 945 946 @Test testGetLeftPadding()947 public void testGetLeftPadding() { 948 Drawable[] array = new Drawable[] { mBitmapDrawable }; 949 LayerDrawable layerDrawable = new LayerDrawable(array); 950 layerDrawable.setPadding(10, 11, 20, 21); 951 952 assertEquals(10, layerDrawable.getLeftPadding()); 953 } 954 955 @Test testGetTopPadding()956 public void testGetTopPadding() { 957 Drawable[] array = new Drawable[] { mBitmapDrawable }; 958 LayerDrawable layerDrawable = new LayerDrawable(array); 959 layerDrawable.setPadding(10, 11, 20, 21); 960 961 assertEquals(11, layerDrawable.getTopPadding()); 962 } 963 964 @Test testGetRightPadding()965 public void testGetRightPadding() { 966 Drawable[] array = new Drawable[] { mBitmapDrawable }; 967 LayerDrawable layerDrawable = new LayerDrawable(array); 968 layerDrawable.setPadding(10, 11, 20, 21); 969 970 assertEquals(20, layerDrawable.getRightPadding()); 971 } 972 973 @Test testGetBottomPadding()974 public void testGetBottomPadding() { 975 Drawable[] array = new Drawable[] { mBitmapDrawable }; 976 LayerDrawable layerDrawable = new LayerDrawable(array); 977 layerDrawable.setPadding(10, 11, 20, 21); 978 979 assertEquals(21, layerDrawable.getBottomPadding()); 980 } 981 982 @Test testGetStartPadding()983 public void testGetStartPadding() { 984 Drawable[] array = new Drawable[] { mBitmapDrawable }; 985 LayerDrawable layerDrawable = new LayerDrawable(array); 986 layerDrawable.setPadding(10, 11, 20, 21); 987 988 assertEquals(-1, layerDrawable.getStartPadding()); 989 layerDrawable.setPaddingRelative(10, 11, 20, 21); 990 assertEquals(10, layerDrawable.getStartPadding()); 991 } 992 993 @Test testGetEndPadding()994 public void testGetEndPadding() { 995 Drawable[] array = new Drawable[] { mBitmapDrawable }; 996 LayerDrawable layerDrawable = new LayerDrawable(array); 997 layerDrawable.setPadding(10, 11, 20, 21); 998 999 assertEquals(-1, layerDrawable.getEndPadding()); 1000 layerDrawable.setPaddingRelative(10, 11, 20, 21); 1001 assertEquals(20, layerDrawable.getEndPadding()); 1002 } 1003 1004 @Test testSetPadding()1005 public void testSetPadding() { 1006 Drawable[] array = new Drawable[] { mBitmapDrawable }; 1007 LayerDrawable layerDrawable = new LayerDrawable(array); 1008 layerDrawable.setPadding(10, 11, 20, 21); 1009 1010 assertEquals(10, layerDrawable.getLeftPadding()); 1011 assertEquals(11, layerDrawable.getTopPadding()); 1012 assertEquals(20, layerDrawable.getRightPadding()); 1013 assertEquals(21, layerDrawable.getBottomPadding()); 1014 assertEquals(-1, layerDrawable.getStartPadding()); 1015 assertEquals(-1, layerDrawable.getEndPadding()); 1016 } 1017 1018 @Test testSetPaddingRelative()1019 public void testSetPaddingRelative() { 1020 Drawable[] array = new Drawable[] { mBitmapDrawable }; 1021 LayerDrawable layerDrawable = new LayerDrawable(array); 1022 layerDrawable.setPaddingRelative(10, 11, 20, 21); 1023 1024 assertEquals(10, layerDrawable.getStartPadding()); 1025 assertEquals(11, layerDrawable.getTopPadding()); 1026 assertEquals(20, layerDrawable.getEndPadding()); 1027 assertEquals(21, layerDrawable.getBottomPadding()); 1028 assertEquals(-1, layerDrawable.getLeftPadding()); 1029 assertEquals(-1, layerDrawable.getRightPadding()); 1030 } 1031 1032 @Test testSetLayerGravity()1033 public void testSetLayerGravity() { 1034 Drawable[] array = new Drawable[] { mBitmapDrawable, mColorDrawable }; 1035 LayerDrawable layerDrawable = new LayerDrawable(array); 1036 1037 layerDrawable.setLayerGravity(0, Gravity.CENTER); 1038 layerDrawable.setLayerGravity(1, Gravity.NO_GRAVITY); 1039 1040 try { 1041 layerDrawable.setLayerGravity(2, Gravity.TOP); 1042 fail("Should throw ArrayIndexOutOfBoundsException"); 1043 } catch (ArrayIndexOutOfBoundsException e) { 1044 } 1045 assertEquals(Gravity.CENTER, layerDrawable.getLayerGravity(0)); 1046 assertEquals(Gravity.NO_GRAVITY, layerDrawable.getLayerGravity(1)); 1047 } 1048 1049 @Test testGetLayerGravity()1050 public void testGetLayerGravity() { 1051 Drawable[] array = new Drawable[] { mBitmapDrawable, mColorDrawable }; 1052 LayerDrawable layerDrawable = new LayerDrawable(array); 1053 1054 layerDrawable.setLayerGravity(0, Gravity.CENTER); 1055 layerDrawable.setLayerGravity(1, Gravity.NO_GRAVITY); 1056 1057 assertEquals(Gravity.CENTER, layerDrawable.getLayerGravity(0)); 1058 assertEquals(Gravity.NO_GRAVITY, layerDrawable.getLayerGravity(1)); 1059 try { 1060 layerDrawable.getLayerGravity(2); 1061 fail("Should throw ArrayIndexOutOfBoundsException"); 1062 } catch (ArrayIndexOutOfBoundsException e) { 1063 } 1064 } 1065 1066 @Test testSetLayerWidth()1067 public void testSetLayerWidth() { 1068 Drawable[] array = new Drawable[] { mBitmapDrawable, mColorDrawable }; 1069 LayerDrawable layerDrawable = new LayerDrawable(array); 1070 1071 layerDrawable.setLayerWidth(0, 100); 1072 layerDrawable.setLayerWidth(1, 200); 1073 1074 try { 1075 layerDrawable.setLayerWidth(2, 300); 1076 fail("Should throw ArrayIndexOutOfBoundsException"); 1077 } catch (ArrayIndexOutOfBoundsException e) { 1078 } 1079 assertEquals(100, layerDrawable.getLayerWidth(0)); 1080 assertEquals(200, layerDrawable.getLayerWidth(1)); 1081 } 1082 1083 @Test testGetLayerWidth()1084 public void testGetLayerWidth() { 1085 Drawable[] array = new Drawable[] { mBitmapDrawable, mColorDrawable }; 1086 LayerDrawable layerDrawable = new LayerDrawable(array); 1087 1088 layerDrawable.setLayerWidth(0, 100); 1089 layerDrawable.setLayerWidth(1, 200); 1090 1091 assertEquals(100, layerDrawable.getLayerWidth(0)); 1092 assertEquals(200, layerDrawable.getLayerWidth(1)); 1093 try { 1094 layerDrawable.getLayerWidth(2); 1095 fail("Should throw ArrayIndexOutOfBoundsException"); 1096 } catch (ArrayIndexOutOfBoundsException e) { 1097 } 1098 } 1099 1100 @Test testSetLayerHeight()1101 public void testSetLayerHeight() { 1102 Drawable[] array = new Drawable[] { mBitmapDrawable, mColorDrawable }; 1103 LayerDrawable layerDrawable = new LayerDrawable(array); 1104 1105 layerDrawable.setLayerHeight(0, 100); 1106 layerDrawable.setLayerHeight(1, 200); 1107 1108 try { 1109 layerDrawable.setLayerHeight(2, 300); 1110 fail("Should throw ArrayIndexOutOfBoundsException"); 1111 } catch (ArrayIndexOutOfBoundsException e) { 1112 } 1113 assertEquals(100, layerDrawable.getLayerHeight(0)); 1114 assertEquals(200, layerDrawable.getLayerHeight(1)); 1115 } 1116 1117 @Test testGetLayerHeight()1118 public void testGetLayerHeight() { 1119 Drawable[] array = new Drawable[] { mBitmapDrawable, mColorDrawable }; 1120 LayerDrawable layerDrawable = new LayerDrawable(array); 1121 1122 layerDrawable.setLayerHeight(0, 100); 1123 layerDrawable.setLayerHeight(1, 200); 1124 1125 assertEquals(100, layerDrawable.getLayerHeight(0)); 1126 assertEquals(200, layerDrawable.getLayerHeight(1)); 1127 try { 1128 layerDrawable.getLayerHeight(2); 1129 fail("Should throw ArrayIndexOutOfBoundsException"); 1130 } catch (ArrayIndexOutOfBoundsException e) { 1131 } 1132 } 1133 1134 @Test testSetLayerSize()1135 public void testSetLayerSize() { 1136 Drawable[] array = new Drawable[] { mBitmapDrawable, mColorDrawable }; 1137 LayerDrawable layerDrawable = new LayerDrawable(array); 1138 1139 layerDrawable.setLayerSize(0, 100, 200); 1140 layerDrawable.setLayerSize(1, 300, 400); 1141 1142 try { 1143 layerDrawable.setLayerSize(2, 500, 600); 1144 fail("Should throw ArrayIndexOutOfBoundsException"); 1145 } catch (ArrayIndexOutOfBoundsException e) { 1146 } 1147 assertEquals(100, layerDrawable.getLayerWidth(0)); 1148 assertEquals(200, layerDrawable.getLayerHeight(0)); 1149 assertEquals(300, layerDrawable.getLayerWidth(1)); 1150 assertEquals(400, layerDrawable.getLayerHeight(1)); 1151 } 1152 1153 @Test testSetLayerInsetRelative()1154 public void testSetLayerInsetRelative() { 1155 Drawable firstLayer = spy(new ColorDrawable(Color.YELLOW)); 1156 doReturn(10).when(firstLayer).getIntrinsicWidth(); 1157 doReturn(10).when(firstLayer).getIntrinsicHeight(); 1158 Drawable secondLayer = spy(new ColorDrawable(Color.YELLOW)); 1159 doReturn(-1).when(secondLayer).getIntrinsicWidth(); 1160 doReturn(-1).when(secondLayer).getIntrinsicHeight(); 1161 1162 Drawable[] array = new Drawable[] { firstLayer, secondLayer }; 1163 LayerDrawable layerDrawable = new LayerDrawable(array); 1164 1165 int start = 10; 1166 int top = 20; 1167 int end = 30; 1168 int bottom = 40; 1169 layerDrawable.setLayerInsetRelative(0, start, top, end, bottom); 1170 assertEquals(layerDrawable.getDrawable(0).getIntrinsicWidth() + start + end, 1171 layerDrawable.getIntrinsicWidth()); 1172 assertEquals(layerDrawable.getDrawable(0).getIntrinsicHeight() + top + bottom, 1173 layerDrawable.getIntrinsicHeight()); 1174 assertEquals(start, layerDrawable.getLayerInsetStart(0)); 1175 assertEquals(top, layerDrawable.getLayerInsetTop(0)); 1176 assertEquals(end, layerDrawable.getLayerInsetEnd(0)); 1177 assertEquals(bottom, layerDrawable.getLayerInsetBottom(0)); 1178 assertEquals(0, layerDrawable.getLayerInsetLeft(0)); 1179 assertEquals(0, layerDrawable.getLayerInsetRight(0)); 1180 1181 // The drawable at index 1 has no intrinsic width or height, so it 1182 // won't be counted for the overall intrinsic width or height. 1183 layerDrawable.setLayerInsetRelative(1, 10, 10, 10, 10); 1184 assertEquals(layerDrawable.getDrawable(0).getIntrinsicWidth() + start + end, 1185 layerDrawable.getIntrinsicWidth()); 1186 assertEquals(layerDrawable.getDrawable(0).getIntrinsicHeight() + top + bottom, 1187 layerDrawable.getIntrinsicHeight()); 1188 1189 try { 1190 layerDrawable.setLayerInsetRelative(-1, start, top, end, bottom); 1191 fail("Should throw IndexOutOfBoundsException"); 1192 } catch (IndexOutOfBoundsException e) { 1193 } 1194 } 1195 1196 @Test testSetLayerInsetLeft()1197 public void testSetLayerInsetLeft() { 1198 Drawable[] array = new Drawable[] { mBitmapDrawable }; 1199 LayerDrawable layerDrawable = new LayerDrawable(array); 1200 1201 // set inset for layer 0 1202 int left = 10; 1203 int top = 20; 1204 int right = 30; 1205 int bottom = 40; 1206 layerDrawable.setLayerInset(0, left, top, right, bottom); 1207 assertEquals(layerDrawable.getDrawable(0).getIntrinsicWidth() + left + right, 1208 layerDrawable.getIntrinsicWidth()); 1209 left += 5; 1210 layerDrawable.setLayerInsetLeft(0, left); 1211 assertEquals(layerDrawable.getDrawable(0).getIntrinsicWidth() + left + right, 1212 layerDrawable.getIntrinsicWidth()); 1213 assertEquals(left, layerDrawable.getLayerInsetLeft(0)); 1214 1215 try { 1216 layerDrawable.setLayerInsetLeft(1, left); 1217 fail("Should throw IndexOutOfBoundsException"); 1218 } catch (IndexOutOfBoundsException e) { 1219 } 1220 } 1221 1222 @Test testGetLayerInsetLeft()1223 public void testGetLayerInsetLeft() { 1224 Drawable[] array = new Drawable[] { mBitmapDrawable }; 1225 LayerDrawable layerDrawable = new LayerDrawable(array); 1226 1227 // set inset for layer 0 1228 int left = 10; 1229 int top = 20; 1230 int right = 30; 1231 int bottom = 40; 1232 layerDrawable.setLayerInset(0, left, top, right, bottom); 1233 assertEquals(left, layerDrawable.getLayerInsetLeft(0)); 1234 left += 5; 1235 layerDrawable.setLayerInsetLeft(0, left); 1236 assertEquals(left, layerDrawable.getLayerInsetLeft(0)); 1237 1238 try { 1239 layerDrawable.getLayerInsetLeft(1); 1240 fail("Should throw IndexOutOfBoundsException"); 1241 } catch (IndexOutOfBoundsException e) { 1242 } 1243 } 1244 1245 @Test testSetLayerInsetTop()1246 public void testSetLayerInsetTop() { 1247 Drawable[] array = new Drawable[] { mBitmapDrawable }; 1248 LayerDrawable layerDrawable = new LayerDrawable(array); 1249 1250 // set inset for layer 0 1251 int left = 10; 1252 int top = 20; 1253 int right = 30; 1254 int bottom = 40; 1255 layerDrawable.setLayerInset(0, left, top, right, bottom); 1256 assertEquals(layerDrawable.getDrawable(0).getIntrinsicHeight() + top + bottom, 1257 layerDrawable.getIntrinsicHeight()); 1258 top += 5; 1259 layerDrawable.setLayerInsetTop(0, top); 1260 assertEquals(layerDrawable.getDrawable(0).getIntrinsicHeight() + top + bottom, 1261 layerDrawable.getIntrinsicHeight()); 1262 assertEquals(top, layerDrawable.getLayerInsetTop(0)); 1263 1264 try { 1265 layerDrawable.setLayerInsetTop(1, top); 1266 fail("Should throw IndexOutOfBoundsException"); 1267 } catch (IndexOutOfBoundsException e) { 1268 } 1269 } 1270 1271 @Test testGetLayerInsetTop()1272 public void testGetLayerInsetTop() { 1273 Drawable[] array = new Drawable[] { mBitmapDrawable }; 1274 LayerDrawable layerDrawable = new LayerDrawable(array); 1275 1276 // set inset for layer 0 1277 int left = 10; 1278 int top = 20; 1279 int right = 30; 1280 int bottom = 40; 1281 layerDrawable.setLayerInset(0, left, top, right, bottom); 1282 assertEquals(top, layerDrawable.getLayerInsetTop(0)); 1283 top += 5; 1284 layerDrawable.setLayerInsetTop(0, top); 1285 assertEquals(top, layerDrawable.getLayerInsetTop(0)); 1286 1287 try { 1288 layerDrawable.getLayerInsetTop(1); 1289 fail("Should throw IndexOutOfBoundsException"); 1290 } catch (IndexOutOfBoundsException e) { 1291 } 1292 } 1293 1294 @Test testSetLayerInsetRight()1295 public void testSetLayerInsetRight() { 1296 Drawable[] array = new Drawable[] { mBitmapDrawable }; 1297 LayerDrawable layerDrawable = new LayerDrawable(array); 1298 1299 // set inset for layer 0 1300 int left = 10; 1301 int top = 20; 1302 int right = 30; 1303 int bottom = 40; 1304 layerDrawable.setLayerInset(0, left, top, right, bottom); 1305 assertEquals(layerDrawable.getDrawable(0).getIntrinsicWidth() + left + right, 1306 layerDrawable.getIntrinsicWidth()); 1307 right += 5; 1308 layerDrawable.setLayerInsetRight(0, right); 1309 assertEquals(layerDrawable.getDrawable(0).getIntrinsicWidth() + left + right, 1310 layerDrawable.getIntrinsicWidth()); 1311 assertEquals(right, layerDrawable.getLayerInsetRight(0)); 1312 1313 try { 1314 layerDrawable.setLayerInsetRight(1, right); 1315 fail("Should throw IndexOutOfBoundsException"); 1316 } catch (IndexOutOfBoundsException e) { 1317 } 1318 } 1319 1320 @Test testGetLayerInsetRight()1321 public void testGetLayerInsetRight() { 1322 Drawable[] array = new Drawable[] { mBitmapDrawable }; 1323 LayerDrawable layerDrawable = new LayerDrawable(array); 1324 1325 // set inset for layer 0 1326 int left = 10; 1327 int top = 20; 1328 int right = 30; 1329 int bottom = 40; 1330 layerDrawable.setLayerInset(0, left, top, right, bottom); 1331 assertEquals(right, layerDrawable.getLayerInsetRight(0)); 1332 right += 5; 1333 layerDrawable.setLayerInsetRight(0, right); 1334 assertEquals(right, layerDrawable.getLayerInsetRight(0)); 1335 1336 try { 1337 layerDrawable.getLayerInsetRight(1); 1338 fail("Should throw IndexOutOfBoundsException"); 1339 } catch (IndexOutOfBoundsException e) { 1340 } 1341 } 1342 1343 @Test testSetLayerInsetBottom()1344 public void testSetLayerInsetBottom() { 1345 Drawable[] array = new Drawable[] { mBitmapDrawable }; 1346 LayerDrawable layerDrawable = new LayerDrawable(array); 1347 1348 // set inset for layer 0 1349 int left = 10; 1350 int top = 20; 1351 int right = 30; 1352 int bottom = 40; 1353 layerDrawable.setLayerInset(0, left, top, right, bottom); 1354 assertEquals(layerDrawable.getDrawable(0).getIntrinsicHeight() + top + bottom, 1355 layerDrawable.getIntrinsicHeight()); 1356 bottom += 5; 1357 layerDrawable.setLayerInsetBottom(0, bottom); 1358 assertEquals(layerDrawable.getDrawable(0).getIntrinsicHeight() + top + bottom, 1359 layerDrawable.getIntrinsicHeight()); 1360 assertEquals(bottom, layerDrawable.getLayerInsetBottom(0)); 1361 1362 try { 1363 layerDrawable.setLayerInsetBottom(1, bottom); 1364 fail("Should throw IndexOutOfBoundsException"); 1365 } catch (IndexOutOfBoundsException e) { 1366 } 1367 } 1368 1369 @Test testGetLayerInsetBottom()1370 public void testGetLayerInsetBottom() { 1371 Drawable[] array = new Drawable[] { mBitmapDrawable }; 1372 LayerDrawable layerDrawable = new LayerDrawable(array); 1373 1374 // set inset for layer 0 1375 int left = 10; 1376 int top = 20; 1377 int right = 30; 1378 int bottom = 40; 1379 layerDrawable.setLayerInset(0, left, top, right, bottom); 1380 assertEquals(bottom, layerDrawable.getLayerInsetBottom(0)); 1381 bottom += 5; 1382 layerDrawable.setLayerInsetBottom(0, bottom); 1383 assertEquals(bottom, layerDrawable.getLayerInsetBottom(0)); 1384 1385 try { 1386 layerDrawable.getLayerInsetBottom(1); 1387 fail("Should throw IndexOutOfBoundsException"); 1388 } catch (IndexOutOfBoundsException e) { 1389 } 1390 } 1391 1392 @Test testSetLayerInsetStart()1393 public void testSetLayerInsetStart() { 1394 Drawable[] array = new Drawable[] { mBitmapDrawable }; 1395 LayerDrawable layerDrawable = new LayerDrawable(array); 1396 1397 // set inset for layer 0 1398 int start = 10; 1399 int top = 20; 1400 int end = 30; 1401 int bottom = 40; 1402 layerDrawable.setLayerInsetRelative(0, start, top, end, bottom); 1403 assertEquals(layerDrawable.getDrawable(0).getIntrinsicWidth() + start + end, 1404 layerDrawable.getIntrinsicWidth()); 1405 start += 5; 1406 layerDrawable.setLayerInsetStart(0, start); 1407 assertEquals(layerDrawable.getDrawable(0).getIntrinsicWidth() + start + end, 1408 layerDrawable.getIntrinsicWidth()); 1409 assertEquals(start, layerDrawable.getLayerInsetStart(0)); 1410 1411 try { 1412 layerDrawable.setLayerInset(1, start, top, end, bottom); 1413 fail("Should throw IndexOutOfBoundsException"); 1414 } catch (IndexOutOfBoundsException e) { 1415 } 1416 } 1417 1418 @Test testGetLayerInsetStart()1419 public void testGetLayerInsetStart() { 1420 Drawable[] array = new Drawable[] { mBitmapDrawable }; 1421 LayerDrawable layerDrawable = new LayerDrawable(array); 1422 1423 // set inset for layer 0 1424 int start = 10; 1425 int top = 20; 1426 int end = 30; 1427 int bottom = 40; 1428 layerDrawable.setLayerInsetRelative(0, start, top, end, bottom); 1429 assertEquals(start, layerDrawable.getLayerInsetStart(0)); 1430 start += 5; 1431 layerDrawable.setLayerInsetStart(0, start); 1432 assertEquals(start, layerDrawable.getLayerInsetStart(0)); 1433 1434 try { 1435 layerDrawable.getLayerInsetStart(1); 1436 fail("Should throw IndexOutOfBoundsException"); 1437 } catch (IndexOutOfBoundsException e) { 1438 } 1439 } 1440 1441 @Test testSetLayerInsetEnd()1442 public void testSetLayerInsetEnd() { 1443 Drawable[] array = new Drawable[] { mBitmapDrawable }; 1444 LayerDrawable layerDrawable = new LayerDrawable(array); 1445 1446 // set inset for layer 0 1447 int start = 10; 1448 int top = 20; 1449 int end = 30; 1450 int bottom = 40; 1451 layerDrawable.setLayerInsetRelative(0, start, top, end, bottom); 1452 assertEquals(end, layerDrawable.getLayerInsetEnd(0)); 1453 assertEquals(layerDrawable.getDrawable(0).getIntrinsicWidth() + start + end, 1454 layerDrawable.getIntrinsicWidth()); 1455 end += 5; 1456 layerDrawable.setLayerInsetEnd(0, end); 1457 assertEquals(layerDrawable.getDrawable(0).getIntrinsicWidth() + start + end, 1458 layerDrawable.getIntrinsicWidth()); 1459 assertEquals(end, layerDrawable.getLayerInsetEnd(0)); 1460 1461 try { 1462 layerDrawable.setLayerInsetEnd(1, end); 1463 fail("Should throw IndexOutOfBoundsException"); 1464 } catch (IndexOutOfBoundsException e) { 1465 } 1466 } 1467 1468 @Test testGetLayerInsetEnd()1469 public void testGetLayerInsetEnd() { 1470 Drawable[] array = new Drawable[] { mBitmapDrawable }; 1471 LayerDrawable layerDrawable = new LayerDrawable(array); 1472 1473 // set inset for layer 0 1474 int start = 10; 1475 int top = 20; 1476 int end = 30; 1477 int bottom = 40; 1478 layerDrawable.setLayerInsetRelative(0, start, top, end, bottom); 1479 assertEquals(end, layerDrawable.getLayerInsetEnd(0)); 1480 end += 5; 1481 layerDrawable.setLayerInsetEnd(0, end); 1482 assertEquals(end, layerDrawable.getLayerInsetEnd(0)); 1483 1484 try { 1485 layerDrawable.getLayerInsetEnd(1); 1486 fail("Should throw IndexOutOfBoundsException"); 1487 } catch (IndexOutOfBoundsException e) { 1488 } 1489 } 1490 1491 @Test testChildIntrinsicSize()1492 public void testChildIntrinsicSize() { 1493 LayerDrawable dr; 1494 1495 // Ensure that a child with no intrinsic size correctly reports bounds. 1496 dr = (LayerDrawable) mContext.getDrawable(R.drawable.layer_drawable_intrinsic); 1497 assertEquals(-1, dr.getIntrinsicWidth()); 1498 assertEquals(-1, dr.getIntrinsicHeight()); 1499 1500 // Check when creating the drawble from code. 1501 dr = new LayerDrawable(new Drawable[] { new ColorDrawable(Color.RED) }); 1502 dr.setLayerInset(0, 10, 10, 10, 10); 1503 assertEquals(-1, dr.getIntrinsicWidth()); 1504 assertEquals(-1, dr.getIntrinsicHeight()); 1505 1506 // Ensure mixed children report bounds correctly as well. 1507 dr = (LayerDrawable) mContext.getDrawable(R.drawable.layer_drawable_intrinsic_mixed); 1508 int width = dr.getLayerInsetLeft(0) + dr.getLayerInsetRight(0) 1509 + dr.getDrawable(0).getIntrinsicWidth(); 1510 int height = dr.getLayerInsetTop(0) + dr.getLayerInsetBottom(0) 1511 + dr.getDrawable(0).getIntrinsicHeight(); 1512 assertEquals(width, dr.getIntrinsicWidth()); 1513 assertEquals(height, dr.getIntrinsicHeight()); 1514 } 1515 1516 @Test testIsProjectedWithNullLayer()1517 public void testIsProjectedWithNullLayer() { 1518 try { 1519 LayerDrawable dr = new LayerDrawable(new Drawable[] {null}); 1520 dr.isProjected(); 1521 } catch (NullPointerException excep) { 1522 fail("isProjected should support null child layer drawables"); 1523 } 1524 } 1525 1526 // Since Mockito can't mock or spy on protected methods, we have a custom extension 1527 // of Drawable to track calls to protected methods. This class also has empty implementations 1528 // of the base abstract methods. In addition, this class also updates its padding on every 1529 // change in level or state. 1530 private static class MockDrawable extends Drawable { 1531 private boolean mCalledSetState = false; 1532 private boolean mCalledOnLevelChange = false; 1533 private boolean mCalledOnBoundsChange = false; 1534 1535 private boolean mIsStateful = false; 1536 1537 private Rect mPadding = null; 1538 MockDrawable()1539 public MockDrawable() { 1540 this(false); 1541 } 1542 MockDrawable(boolean isStateful)1543 public MockDrawable(boolean isStateful) { 1544 mIsStateful = isStateful; 1545 } 1546 1547 @Override draw(Canvas canvas)1548 public void draw(Canvas canvas) { 1549 } 1550 1551 @Override getOpacity()1552 public int getOpacity() { 1553 return PixelFormat.OPAQUE; 1554 } 1555 1556 @Override setAlpha(int alpha)1557 public void setAlpha(int alpha) { 1558 } 1559 1560 @Override setColorFilter(ColorFilter cf)1561 public void setColorFilter(ColorFilter cf) { 1562 } 1563 reset()1564 public void reset() { 1565 mCalledSetState = false; 1566 mCalledOnLevelChange = false; 1567 mCalledOnBoundsChange = false; 1568 } 1569 1570 @Override onStateChange(int[] state)1571 protected boolean onStateChange(int[] state) { 1572 increasePadding(); 1573 return mIsStateful; 1574 } 1575 increasePadding()1576 private void increasePadding() { 1577 Rect padding = new Rect(); 1578 getPadding(padding); 1579 padding.left++; 1580 padding.top++; 1581 padding.right++; 1582 padding.bottom++; 1583 1584 setPadding(padding); 1585 } 1586 1587 @Override onLevelChange(int level)1588 protected boolean onLevelChange(int level) { 1589 increasePadding(); 1590 mCalledOnLevelChange = true; 1591 return true; 1592 } 1593 1594 @Override onBoundsChange(Rect bounds)1595 protected void onBoundsChange(Rect bounds) { 1596 mCalledOnBoundsChange = true; 1597 super.onBoundsChange(bounds); 1598 } 1599 hasCalledOnBoundsChange()1600 public boolean hasCalledOnBoundsChange() { 1601 return mCalledOnBoundsChange; 1602 } 1603 1604 @Override isStateful()1605 public boolean isStateful() { 1606 return mIsStateful; 1607 } 1608 hasCalledSetState()1609 public boolean hasCalledSetState() { 1610 return mCalledSetState; 1611 } 1612 1613 @Override setState(final int[] stateSet)1614 public boolean setState(final int[] stateSet) { 1615 mCalledSetState = true; 1616 return super.setState(stateSet); 1617 } 1618 hasCalledOnLevelChange()1619 public boolean hasCalledOnLevelChange() { 1620 return mCalledOnLevelChange; 1621 } 1622 setPadding(Rect padding)1623 private void setPadding(Rect padding) { 1624 if (padding == null) { 1625 mPadding = null; 1626 } else { 1627 if (mPadding == null) { 1628 mPadding = new Rect(); 1629 } 1630 mPadding.set(padding); 1631 } 1632 } 1633 1634 @Override getPadding(Rect padding)1635 public boolean getPadding(Rect padding) { 1636 if (mPadding != null) { 1637 padding.set(mPadding); 1638 return true; 1639 } else { 1640 return super.getPadding(padding); 1641 } 1642 } 1643 } 1644 1645 @Test testMutate()1646 public void testMutate() { 1647 LayerDrawable d1 = (LayerDrawable) mContext.getDrawable(R.drawable.layerdrawable); 1648 LayerDrawable d2 = (LayerDrawable) mContext.getDrawable(R.drawable.layerdrawable); 1649 LayerDrawable d3 = (LayerDrawable) mContext.getDrawable(R.drawable.layerdrawable); 1650 int restoreAlpha = d1.getAlpha(); 1651 1652 try { 1653 // verify bad behavior - modify before mutate pollutes other drawables 1654 d1.setAlpha(100); 1655 assertEquals(100, ((BitmapDrawable) d1.getDrawable(0)).getPaint().getAlpha()); 1656 assertEquals(100, ((BitmapDrawable) d1.getDrawable(0)).getPaint().getAlpha()); 1657 assertEquals(100, ((BitmapDrawable) d2.getDrawable(0)).getPaint().getAlpha()); 1658 assertEquals(100, ((BitmapDrawable) d2.getDrawable(0)).getPaint().getAlpha()); 1659 assertEquals(100, ((BitmapDrawable) d3.getDrawable(0)).getPaint().getAlpha()); 1660 assertEquals(100, ((BitmapDrawable) d2.getDrawable(0)).getPaint().getAlpha()); 1661 1662 d1.mutate(); 1663 d1.setAlpha(200); 1664 assertEquals(200, ((BitmapDrawable) d1.getDrawable(0)).getPaint().getAlpha()); 1665 assertEquals(200, ((BitmapDrawable) d1.getDrawable(0)).getPaint().getAlpha()); 1666 assertEquals(100, ((BitmapDrawable) d2.getDrawable(0)).getPaint().getAlpha()); 1667 assertEquals(100, ((BitmapDrawable) d2.getDrawable(0)).getPaint().getAlpha()); 1668 assertEquals(100, ((BitmapDrawable) d3.getDrawable(0)).getPaint().getAlpha()); 1669 assertEquals(100, ((BitmapDrawable) d3.getDrawable(0)).getPaint().getAlpha()); 1670 1671 d2.setAlpha(50); 1672 assertEquals(200, ((BitmapDrawable) d1.getDrawable(0)).getPaint().getAlpha()); 1673 assertEquals(200, ((BitmapDrawable) d1.getDrawable(0)).getPaint().getAlpha()); 1674 assertEquals(50, ((BitmapDrawable) d2.getDrawable(0)).getPaint().getAlpha()); 1675 assertEquals(50, ((BitmapDrawable) d2.getDrawable(0)).getPaint().getAlpha()); 1676 assertEquals(50, ((BitmapDrawable) d3.getDrawable(0)).getPaint().getAlpha()); 1677 assertEquals(50, ((BitmapDrawable) d3.getDrawable(0)).getPaint().getAlpha()); 1678 } finally { 1679 // restore externally visible state, since other tests may use the drawable 1680 mContext.getDrawable(R.drawable.layerdrawable).setAlpha(restoreAlpha); 1681 } 1682 } 1683 1684 @Test testPreloadDensity()1685 public void testPreloadDensity() throws XmlPullParserException, IOException { 1686 final Resources res = mContext.getResources(); 1687 final int densityDpi = res.getConfiguration().densityDpi; 1688 try { 1689 DrawableTestUtils.setResourcesDensity(res, densityDpi); 1690 verifyPreloadDensityInner(res, densityDpi); 1691 } finally { 1692 DrawableTestUtils.setResourcesDensity(res, densityDpi); 1693 } 1694 } 1695 1696 @Test testPreloadDensity_tvdpi()1697 public void testPreloadDensity_tvdpi() throws XmlPullParserException, IOException { 1698 final Resources res = mContext.getResources(); 1699 final int densityDpi = res.getConfiguration().densityDpi; 1700 try { 1701 DrawableTestUtils.setResourcesDensity(res, 213); 1702 verifyPreloadDensityInner(res, 213); 1703 } finally { 1704 DrawableTestUtils.setResourcesDensity(res, densityDpi); 1705 } 1706 } 1707 verifyPreloadDensityInner(Resources res, int densityDpi)1708 private void verifyPreloadDensityInner(Resources res, int densityDpi) 1709 throws XmlPullParserException, IOException { 1710 // Capture initial state at default density. 1711 final XmlResourceParser parser = DrawableTestUtils.getResourceParser( 1712 res, R.drawable.layer_drawable_density); 1713 final LayerDrawable preloadedDrawable = new LayerDrawable(new Drawable[0]); 1714 preloadedDrawable.inflate(res, parser, Xml.asAttributeSet(parser)); 1715 final ConstantState preloadedConstantState = preloadedDrawable.getConstantState(); 1716 final int initialLeftPadding = preloadedDrawable.getLeftPadding(); 1717 final int initialRightPadding = preloadedDrawable.getRightPadding(); 1718 final int initialContentInsetL = preloadedDrawable.getLayerInsetLeft(0); 1719 final int initialContentInsetR = preloadedDrawable.getLayerInsetRight(0); 1720 final int initialContentWidth = preloadedDrawable.getLayerWidth(0); 1721 final int initialIntrinsicWidth = preloadedDrawable.getIntrinsicWidth(); 1722 final int initialBottomPadding = preloadedDrawable.getBottomPadding(); 1723 final int initialTopPadding = preloadedDrawable.getTopPadding(); 1724 final int initialLayerInsetLeft = preloadedDrawable.getLayerInsetLeft(0); 1725 final int initialLayerInsetRight = preloadedDrawable.getLayerInsetRight(0); 1726 final int initialLayerInsetTop = preloadedDrawable.getLayerInsetTop(0); 1727 final int initialLayerInsetBottom = preloadedDrawable.getLayerInsetBottom(0); 1728 final int initialLayerWidth = preloadedDrawable.getLayerWidth(0); 1729 final int initialLayerHeight = preloadedDrawable.getLayerHeight(0); 1730 1731 // Set density to half of original. Padding and insets are 1732 // truncated, dimensions are rounded to the nearest pixel. Because 1733 // LayerDrawable's intrinsic width is a combination of padding and 1734 // dimensions, some computation is necessary. 1735 DrawableTestUtils.setResourcesDensity(res, densityDpi / 2); 1736 final LayerDrawable halfDrawable = 1737 (LayerDrawable) preloadedConstantState.newDrawable(res); 1738 // NOTE: densityDpi may not be an even number, so account for *actual* scaling in asserts 1739 final float approxHalf = (float)(densityDpi / 2) / densityDpi; 1740 final int halfContentWidth = Math.round(initialContentWidth * approxHalf); 1741 final int halfLeftPadding = (int) (initialLeftPadding * approxHalf); 1742 final int halfRightPadding = (int) (initialRightPadding * approxHalf); 1743 final int halfContentInsetL = (int) (initialContentInsetL * approxHalf); 1744 final int halfContentInsetR = (int) (initialContentInsetR * approxHalf); 1745 final int halfIntrinsicWidth = halfContentWidth + halfContentInsetL + halfContentInsetR; 1746 assertEquals(halfLeftPadding, halfDrawable.getLeftPadding()); 1747 assertEquals(halfRightPadding, halfDrawable.getRightPadding()); 1748 assertEquals(halfContentInsetL, halfDrawable.getLayerInsetRight(0)); 1749 assertEquals(halfContentInsetR, halfDrawable.getLayerInsetLeft(0)); 1750 assertEquals(halfContentWidth, halfDrawable.getLayerWidth(0)); 1751 assertEquals(halfIntrinsicWidth, halfDrawable.getIntrinsicWidth()); 1752 assertEquals((int) (initialBottomPadding * approxHalf), halfDrawable.getBottomPadding()); 1753 assertEquals((int) (initialTopPadding * approxHalf), halfDrawable.getTopPadding()); 1754 assertEquals((int) (initialLayerInsetLeft * approxHalf), 1755 halfDrawable.getLayerInsetLeft(0)); 1756 assertEquals((int) (initialLayerInsetRight * approxHalf), 1757 halfDrawable.getLayerInsetRight(0)); 1758 assertEquals((int) (initialLayerInsetTop * approxHalf), 1759 halfDrawable.getLayerInsetTop(0)); 1760 assertEquals((int) (initialLayerInsetBottom * approxHalf), 1761 halfDrawable.getLayerInsetBottom(0)); 1762 assertEquals(Math.round(initialLayerWidth * approxHalf), halfDrawable.getLayerWidth(0)); 1763 assertEquals(Math.round(initialLayerHeight * approxHalf), halfDrawable.getLayerHeight(0)); 1764 1765 // Set density to double original. 1766 DrawableTestUtils.setResourcesDensity(res, densityDpi * 2); 1767 final LayerDrawable doubleDrawable = 1768 (LayerDrawable) preloadedConstantState.newDrawable(res); 1769 assertEquals(initialLeftPadding * 2, doubleDrawable.getLeftPadding()); 1770 assertEquals(initialRightPadding * 2, doubleDrawable.getRightPadding()); 1771 assertEquals(initialContentInsetL * 2, doubleDrawable.getLayerInsetRight(0)); 1772 assertEquals(initialContentInsetR * 2, doubleDrawable.getLayerInsetLeft(0)); 1773 assertEquals(initialContentWidth * 2, doubleDrawable.getLayerWidth(0)); 1774 assertEquals(initialIntrinsicWidth * 2, doubleDrawable.getIntrinsicWidth()); 1775 assertEquals(initialBottomPadding * 2, doubleDrawable.getBottomPadding()); 1776 assertEquals(initialTopPadding * 2, doubleDrawable.getTopPadding()); 1777 assertEquals(initialLayerInsetLeft * 2, doubleDrawable.getLayerInsetLeft(0)); 1778 assertEquals(initialLayerInsetRight * 2, doubleDrawable.getLayerInsetRight(0)); 1779 assertEquals(initialLayerInsetTop * 2, doubleDrawable.getLayerInsetTop(0)); 1780 assertEquals(initialLayerInsetBottom * 2, doubleDrawable.getLayerInsetBottom(0)); 1781 assertEquals(initialLayerWidth * 2, doubleDrawable.getLayerWidth(0)); 1782 assertEquals(initialLayerHeight * 2, doubleDrawable.getLayerHeight(0)); 1783 1784 // Restore original configuration and metrics. 1785 DrawableTestUtils.setResourcesDensity(res, densityDpi); 1786 final LayerDrawable origDrawable = 1787 (LayerDrawable) preloadedConstantState.newDrawable(res); 1788 assertEquals(initialLeftPadding, origDrawable.getLeftPadding()); 1789 assertEquals(initialRightPadding, origDrawable.getRightPadding()); 1790 assertEquals(initialContentInsetL, origDrawable.getLayerInsetRight(0)); 1791 assertEquals(initialContentInsetR, origDrawable.getLayerInsetLeft(0)); 1792 assertEquals(initialContentWidth, origDrawable.getLayerWidth(0)); 1793 assertEquals(initialIntrinsicWidth, origDrawable.getIntrinsicWidth()); 1794 assertEquals(initialBottomPadding, origDrawable.getBottomPadding()); 1795 assertEquals(initialTopPadding, origDrawable.getTopPadding()); 1796 assertEquals(initialLayerInsetLeft, origDrawable.getLayerInsetLeft(0)); 1797 assertEquals(initialLayerInsetRight, origDrawable.getLayerInsetRight(0)); 1798 assertEquals(initialLayerInsetTop, origDrawable.getLayerInsetTop(0)); 1799 assertEquals(initialLayerInsetBottom, origDrawable.getLayerInsetBottom(0)); 1800 assertEquals(initialLayerWidth, origDrawable.getLayerWidth(0)); 1801 assertEquals(initialLayerHeight, origDrawable.getLayerHeight(0)); 1802 1803 // Ensure theme density is applied correctly. 1804 final Theme t = res.newTheme(); 1805 1806 // The half-density drawable will scale-up all of the values that were 1807 // previously scaled-down, so we need to capture the rounding errors. 1808 halfDrawable.applyTheme(t); 1809 1810 // Reproduce imprecise truncated scale down, and back up. Note that we don't round. 1811 float approxDouble = 1 / approxHalf; 1812 assertEquals((int) (halfLeftPadding * approxDouble), halfDrawable.getLeftPadding()); 1813 assertEquals((int) (halfRightPadding * approxDouble), halfDrawable.getRightPadding()); 1814 assertEquals((int) (halfContentInsetL * approxDouble), halfDrawable.getLayerInsetRight(0)); 1815 assertEquals((int) (halfContentInsetR * approxDouble), halfDrawable.getLayerInsetLeft(0)); 1816 assertEquals((int) (halfContentWidth * approxDouble), halfDrawable.getLayerWidth(0)); 1817 assertEquals(halfIntrinsicWidth * 2, halfDrawable.getIntrinsicWidth()); 1818 assertEquals((int) ((int) (initialBottomPadding * approxHalf) * approxDouble), 1819 halfDrawable.getBottomPadding()); 1820 assertEquals((int) ((int) (initialTopPadding * approxHalf) * approxDouble), 1821 halfDrawable.getTopPadding()); 1822 assertEquals((int) ((int) (initialLayerInsetLeft * approxHalf) * approxDouble), 1823 halfDrawable.getLayerInsetLeft(0)); 1824 assertEquals((int) ((int) (initialLayerInsetRight * approxHalf) * approxDouble), 1825 halfDrawable.getLayerInsetRight(0)); 1826 assertEquals((int) ((int) (initialLayerInsetTop * approxHalf) * approxDouble), 1827 halfDrawable.getLayerInsetTop(0)); 1828 assertEquals((int) ((int) (initialLayerInsetBottom * approxHalf) * approxDouble), 1829 halfDrawable.getLayerInsetBottom(0)); 1830 assertEquals(Math.round(Math.round(initialLayerWidth * approxHalf) * approxDouble), 1831 halfDrawable.getLayerWidth(0)); 1832 assertEquals(Math.round(Math.round(initialLayerHeight * approxHalf) * approxDouble), 1833 halfDrawable.getLayerHeight(0)); 1834 1835 // The double-density drawable will scale-down all of the values that 1836 // were previously scaled-up, so we don't need to worry about rounding. 1837 doubleDrawable.applyTheme(t); 1838 assertEquals(initialLeftPadding, doubleDrawable.getLeftPadding()); 1839 assertEquals(initialRightPadding, doubleDrawable.getRightPadding()); 1840 assertEquals(initialContentInsetL, doubleDrawable.getLayerInsetRight(0)); 1841 assertEquals(initialContentInsetR, doubleDrawable.getLayerInsetLeft(0)); 1842 assertEquals(initialContentWidth, doubleDrawable.getLayerWidth(0)); 1843 assertEquals(initialIntrinsicWidth, doubleDrawable.getIntrinsicWidth()); 1844 assertEquals(initialBottomPadding, doubleDrawable.getBottomPadding()); 1845 assertEquals(initialTopPadding, doubleDrawable.getTopPadding()); 1846 assertEquals(initialLayerInsetLeft, doubleDrawable.getLayerInsetLeft(0)); 1847 assertEquals(initialLayerInsetRight, doubleDrawable.getLayerInsetRight(0)); 1848 assertEquals(initialLayerInsetTop, doubleDrawable.getLayerInsetTop(0)); 1849 assertEquals(initialLayerInsetBottom, doubleDrawable.getLayerInsetBottom(0)); 1850 assertEquals(initialLayerWidth, doubleDrawable.getLayerWidth(0)); 1851 assertEquals(initialLayerHeight, doubleDrawable.getLayerHeight(0)); 1852 } 1853 1854 @Test testOpacityChange()1855 public void testOpacityChange() { 1856 ColorDrawable c1 = new ColorDrawable(Color.RED); 1857 ColorDrawable c2 = new ColorDrawable(Color.BLUE); 1858 LayerDrawable dr = new LayerDrawable(new ColorDrawable[] { c1, c2 }); 1859 assertEquals(PixelFormat.OPAQUE, dr.getOpacity()); 1860 1861 c1.setTint(0x80FF0000); 1862 c1.setTintMode(PorterDuff.Mode.SRC); 1863 c2.setTint(0x800000FF); 1864 c2.setTintMode(PorterDuff.Mode.SRC); 1865 assertEquals(PixelFormat.TRANSLUCENT, dr.getOpacity()); 1866 } 1867 1868 @Test testStatefulnessChange()1869 public void testStatefulnessChange() { 1870 ColorDrawable c1 = new ColorDrawable(Color.RED); 1871 ColorDrawable c2 = new ColorDrawable(Color.BLUE); 1872 LayerDrawable dr = new LayerDrawable(new ColorDrawable[] { c1, c2 }); 1873 assertEquals(false, dr.isStateful()); 1874 1875 ColorStateList csl = new ColorStateList( 1876 new int[][] { { android.R.attr.state_enabled }, { } }, 1877 new int[] { Color.RED, Color.BLUE }); 1878 c1.setTintList(csl); 1879 assertEquals(true, dr.isStateful()); 1880 } 1881 1882 @Test testInvalidateDuringInit()1883 public void testInvalidateDuringInit() { 1884 Drawable layer = new RippleDrawable(ColorStateList.valueOf(Color.BLACK), null, null); 1885 1886 LayerDrawable orig = new LayerDrawable(new Drawable[] { layer }); 1887 orig.setBounds(0, 0, 100, 100); 1888 1889 // This will invoke the layer's invalidateSelf() during construction. 1890 LayerDrawable copy = (LayerDrawable) orig.getConstantState().newDrawable(); 1891 assertNotSame(orig, copy); 1892 } 1893 1894 private static class IntrinsicSizeDrawable extends Drawable { 1895 private final int mIntrinsicWidth; 1896 private final int mIntrinsicHeight; 1897 private final Rect mPadding; 1898 IntrinsicSizeDrawable(int intrinsicWidth, int intrinsicHeight, Rect padding)1899 public IntrinsicSizeDrawable(int intrinsicWidth, int intrinsicHeight, Rect padding) { 1900 mIntrinsicWidth = intrinsicWidth; 1901 mIntrinsicHeight = intrinsicHeight; 1902 mPadding = new Rect(padding); 1903 } 1904 1905 @Override getPadding(Rect padding)1906 public boolean getPadding(Rect padding) { 1907 padding.set(mPadding); 1908 return true; 1909 } 1910 1911 @Override getIntrinsicHeight()1912 public int getIntrinsicHeight() { 1913 return mIntrinsicHeight; 1914 } 1915 1916 @Override getIntrinsicWidth()1917 public int getIntrinsicWidth() { 1918 return mIntrinsicWidth; 1919 } 1920 1921 @Override draw(Canvas canvas)1922 public void draw(Canvas canvas) { 1923 } 1924 1925 @Override setAlpha(int alpha)1926 public void setAlpha(int alpha) { 1927 } 1928 1929 @Override setColorFilter(ColorFilter colorFilter)1930 public void setColorFilter(ColorFilter colorFilter) { 1931 } 1932 1933 @Override getOpacity()1934 public int getOpacity() { 1935 return 0; 1936 } 1937 } 1938 } 1939