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