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 junit.framework.TestCase; 20 21 import java.util.Arrays; 22 23 import android.graphics.Canvas; 24 import android.graphics.Color; 25 import android.graphics.ColorFilter; 26 import android.graphics.PixelFormat; 27 import android.graphics.PorterDuff.Mode; 28 import android.graphics.Rect; 29 import android.graphics.drawable.Drawable; 30 import android.graphics.drawable.DrawableContainer; 31 import android.graphics.drawable.DrawableContainer.DrawableContainerState; 32 import android.graphics.drawable.LevelListDrawable; 33 34 public class DrawableContainerTest extends TestCase { 35 private DrawableContainerState mDrawableContainerState; 36 37 private MockDrawableContainer mMockDrawableContainer; 38 private DrawableContainer mDrawableContainer; 39 40 @Override setUp()41 protected void setUp() throws Exception { 42 super.setUp(); 43 44 // DrawableContainerState has no public constructor. Obtain an instance through 45 // LevelListDrawable.getConstants(). This is fine for testing the final methods of 46 // DrawableContainerState. 47 mDrawableContainerState = 48 (DrawableContainerState) new LevelListDrawable().getConstantState(); 49 assertNotNull(mDrawableContainerState); 50 51 mMockDrawableContainer = new MockDrawableContainer(); 52 mDrawableContainer = mMockDrawableContainer; 53 } 54 testDraw()55 public void testDraw() { 56 assertConstantStateNotSet(); 57 assertNull(mDrawableContainer.getCurrent()); 58 59 mDrawableContainer.draw(null); 60 mDrawableContainer.draw(new Canvas()); 61 62 mMockDrawableContainer.setConstantState(mDrawableContainerState); 63 MockDrawable dr = new MockDrawable(); 64 addAndSelectDrawable(dr); 65 66 dr.reset(); 67 mDrawableContainer.draw(null); 68 assertTrue(dr.hasDrawCalled()); 69 70 dr.reset(); 71 mDrawableContainer.draw(new Canvas()); 72 assertTrue(dr.hasDrawCalled()); 73 } 74 testSetEnterFadeDuration()75 public void testSetEnterFadeDuration() { 76 helpTestSetEnterFadeDuration(1000); 77 helpTestSetEnterFadeDuration(0); 78 } 79 helpTestSetEnterFadeDuration(int enterFadeDuration)80 private void helpTestSetEnterFadeDuration(int enterFadeDuration) { 81 DrawableContainer container = new LevelListDrawable(); 82 DrawableContainerState cs = ((DrawableContainerState) container.getConstantState()); 83 container.setEnterFadeDuration(enterFadeDuration); 84 assertEquals(enterFadeDuration, cs.getEnterFadeDuration()); 85 } 86 testSetExitFadeDuration()87 public void testSetExitFadeDuration() { 88 helpTestSetExitFadeDuration(1000); 89 helpTestSetExitFadeDuration(0); 90 } 91 helpTestSetExitFadeDuration(int exitFadeDuration)92 private void helpTestSetExitFadeDuration(int exitFadeDuration) { 93 DrawableContainer container = new LevelListDrawable(); 94 DrawableContainerState cs = ((DrawableContainerState) container.getConstantState()); 95 container.setExitFadeDuration(exitFadeDuration); 96 assertEquals(exitFadeDuration, cs.getExitFadeDuration()); 97 } 98 testGetChangingConfigurations()99 public void testGetChangingConfigurations() { 100 // Workaround for CTS coverage not recognizing calls on subclasses. 101 DrawableContainer dr = mDrawableContainer; 102 103 assertConstantStateNotSet(); 104 105 try { 106 mDrawableContainer.getChangingConfigurations(); 107 fail("Should throw NullPointerException if the constant state is not set."); 108 } catch (NullPointerException e) { 109 } 110 111 mMockDrawableContainer.setConstantState(mDrawableContainerState); 112 MockDrawable dr0 = new MockDrawable(); 113 dr0.setChangingConfigurations(0x001); 114 mDrawableContainerState.addChild(dr0); 115 MockDrawable dr1 = new MockDrawable(); 116 dr1.setChangingConfigurations(0x010); 117 mDrawableContainerState.addChild(dr1); 118 dr.selectDrawable(0); 119 assertSame(dr0, mDrawableContainer.getCurrent()); 120 121 // can not set mDrawableContainerState's ChangingConfigurations 122 mDrawableContainer.setChangingConfigurations(0x100); 123 assertEquals(0x111 | mDrawableContainerState.getChangingConfigurations(), 124 mDrawableContainer.getChangingConfigurations()); 125 } 126 testGetPadding()127 public void testGetPadding() { 128 // Workaround for CTS coverage not recognizing calls on subclasses. 129 DrawableContainer dr = mDrawableContainer; 130 131 assertConstantStateNotSet(); 132 assertNull(mDrawableContainer.getCurrent()); 133 134 Rect result = new Rect(1, 1, 1, 1); 135 try { 136 mDrawableContainer.getPadding(result); 137 fail("Should throw NullPointerException if the constant state is not set."); 138 } catch (NullPointerException e) { 139 } 140 141 mMockDrawableContainer.setConstantState(mDrawableContainerState); 142 MockDrawable dr0 = new MockDrawable(); 143 dr0.setPadding(new Rect(1, 2, 0, 0)); 144 mDrawableContainerState.addChild(dr0); 145 MockDrawable dr1 = new MockDrawable(); 146 dr1.setPadding(new Rect(0, 0, 3, 4)); 147 mDrawableContainerState.addChild(dr1); 148 dr.selectDrawable(0); 149 assertSame(dr0, mDrawableContainer.getCurrent()); 150 151 // use the current drawable's padding 152 mDrawableContainerState.setVariablePadding(true); 153 assertNull(mDrawableContainerState.getConstantPadding()); 154 assertTrue(mDrawableContainer.getPadding(result)); 155 assertEquals(new Rect(1, 2, 0, 0), result); 156 157 // use constant state's padding 158 mDrawableContainerState.setVariablePadding(false); 159 assertNotNull(mDrawableContainerState.getConstantPadding()); 160 assertTrue(mDrawableContainer.getPadding(result)); 161 assertEquals(mDrawableContainerState.getConstantPadding(), result); 162 163 // use default padding 164 dr.selectDrawable(-1); 165 assertNull(mDrawableContainer.getCurrent()); 166 mDrawableContainerState.setVariablePadding(true); 167 assertNull(mDrawableContainerState.getConstantPadding()); 168 assertFalse(mDrawableContainer.getPadding(result)); 169 assertEquals(new Rect(0, 0, 0, 0), result); 170 171 try { 172 mDrawableContainer.getPadding(null); 173 fail("Should throw NullPointerException if the padding is null."); 174 } catch (NullPointerException e) { 175 } 176 } 177 testSetAlpha()178 public void testSetAlpha() { 179 // Workaround for CTS coverage not recognizing calls on subclasses. 180 DrawableContainer dr = mDrawableContainer; 181 182 assertConstantStateNotSet(); 183 assertNull(mDrawableContainer.getCurrent()); 184 185 dr.setAlpha(0); 186 187 mMockDrawableContainer.setConstantState(mDrawableContainerState); 188 MockDrawable mockDrawable = new MockDrawable(); 189 addAndSelectDrawable(mockDrawable); 190 191 // call current drawable's setAlpha if alpha is changed. 192 mockDrawable.reset(); 193 dr.setAlpha(1); 194 assertTrue(mockDrawable.hasSetAlphaCalled()); 195 196 // does not call it if alpha is not changed. 197 mockDrawable.reset(); 198 dr.setAlpha(1); 199 assertFalse(mockDrawable.hasSetAlphaCalled()); 200 } 201 testSetDither()202 public void testSetDither() { 203 assertConstantStateNotSet(); 204 assertNull(mDrawableContainer.getCurrent()); 205 206 mMockDrawableContainer.setConstantState(mDrawableContainerState); 207 mDrawableContainer.setDither(false); 208 mDrawableContainer.setDither(true); 209 210 MockDrawable dr = new MockDrawable(); 211 addAndSelectDrawable(dr); 212 213 // call current drawable's setDither if dither is changed. 214 dr.reset(); 215 mDrawableContainer.setDither(false); 216 assertTrue(dr.hasSetDitherCalled()); 217 218 // does not call it if dither is not changed. 219 dr.reset(); 220 mDrawableContainer.setDither(true); 221 assertTrue(dr.hasSetDitherCalled()); 222 } 223 testSetHotspotBounds()224 public void testSetHotspotBounds() { 225 Rect bounds = new Rect(10, 15, 100, 150); 226 assertConstantStateNotSet(); 227 assertNull(mDrawableContainer.getCurrent()); 228 229 mMockDrawableContainer.setConstantState(mDrawableContainerState); 230 231 MockDrawable dr = new MockDrawable(); 232 addAndSelectDrawable(dr); 233 234 dr.reset(); 235 mDrawableContainer.setHotspotBounds(bounds.left, bounds.top, bounds.right, bounds.bottom); 236 Rect outRect = new Rect(); 237 mDrawableContainer.getHotspotBounds(outRect); 238 assertEquals(bounds, outRect); 239 240 dr.reset(); 241 } 242 testGetHotspotBounds()243 public void testGetHotspotBounds() { 244 Rect bounds = new Rect(10, 15, 100, 150); 245 assertConstantStateNotSet(); 246 assertNull(mDrawableContainer.getCurrent()); 247 248 mMockDrawableContainer.setConstantState(mDrawableContainerState); 249 250 MockDrawable dr = new MockDrawable(); 251 addAndSelectDrawable(dr); 252 253 dr.reset(); 254 mDrawableContainer.setHotspotBounds(bounds.left, bounds.top, bounds.right, bounds.bottom); 255 Rect outRect = new Rect(); 256 mDrawableContainer.getHotspotBounds(outRect); 257 assertEquals(bounds, outRect); 258 259 dr.reset(); 260 } 261 testSetColorFilter()262 public void testSetColorFilter() { 263 // Workaround for CTS coverage not recognizing calls on subclasses. 264 DrawableContainer dr = mDrawableContainer; 265 266 assertConstantStateNotSet(); 267 assertNull(mDrawableContainer.getCurrent()); 268 269 mMockDrawableContainer.setConstantState(mDrawableContainerState); 270 dr.setColorFilter(null); 271 dr.setColorFilter(new ColorFilter()); 272 273 MockDrawable mockDrawable = new MockDrawable(); 274 addAndSelectDrawable(mockDrawable); 275 276 // call current drawable's setColorFilter if filter is changed. 277 mockDrawable.reset(); 278 dr.setColorFilter(null); 279 assertTrue(mockDrawable.hasSetColorFilterCalled()); 280 281 // does not call it if filter is not changed. 282 mockDrawable.reset(); 283 dr.setColorFilter(new ColorFilter()); 284 assertTrue(mockDrawable.hasSetColorFilterCalled()); 285 } 286 testSetTint()287 public void testSetTint() { 288 assertConstantStateNotSet(); 289 assertNull(mDrawableContainer.getCurrent()); 290 291 mMockDrawableContainer.setConstantState(mDrawableContainerState); 292 mDrawableContainer.setTint(Color.BLACK); 293 mDrawableContainer.setTintMode(Mode.SRC_OVER); 294 295 MockDrawable dr = new MockDrawable(); 296 addAndSelectDrawable(dr); 297 298 assertEquals("Initial tint propagates", Mode.SRC_OVER, dr.getTintMode()); 299 300 dr.reset(); 301 mDrawableContainer.setTintList(null); 302 mDrawableContainer.setTintMode(null); 303 assertTrue("setImageTintList() propagates", dr.hasSetTintCalled()); 304 } 305 testOnBoundsChange()306 public void testOnBoundsChange() { 307 assertConstantStateNotSet(); 308 assertNull(mDrawableContainer.getCurrent()); 309 310 mMockDrawableContainer.onBoundsChange(new Rect()); 311 mMockDrawableContainer.onBoundsChange(null); 312 313 mMockDrawableContainer.setConstantState(mDrawableContainerState); 314 MockDrawable dr = new MockDrawable(); 315 dr.setBounds(new Rect()); 316 addAndSelectDrawable(dr); 317 318 // set current drawable's bounds. 319 dr.reset(); 320 assertEquals(new Rect(), dr.getBounds()); 321 mMockDrawableContainer.onBoundsChange(new Rect(1, 1, 1, 1)); 322 assertTrue(dr.hasOnBoundsChangedCalled()); 323 assertEquals(new Rect(1, 1, 1, 1), dr.getBounds()); 324 325 dr.reset(); 326 mMockDrawableContainer.onBoundsChange(new Rect(1, 1, 1, 1)); 327 assertFalse(dr.hasOnBoundsChangedCalled()); 328 assertEquals(new Rect(1, 1, 1, 1), dr.getBounds()); 329 330 try { 331 mMockDrawableContainer.onBoundsChange(null); 332 fail("Should throw NullPointerException if the bounds is null."); 333 } catch (NullPointerException e) { 334 } 335 } 336 testIsStateful()337 public void testIsStateful() { 338 assertConstantStateNotSet(); 339 340 try { 341 mDrawableContainer.isStateful(); 342 fail("Should throw NullPointerException if the constant state is not set."); 343 } catch (NullPointerException e) { 344 } 345 346 mMockDrawableContainer.setConstantState(mDrawableContainerState); 347 MockDrawable dr0 = new MockDrawable(); 348 dr0.setStateful(true); 349 mDrawableContainerState.addChild(dr0); 350 MockDrawable dr1 = new MockDrawable(); 351 dr1.setStateful(false); 352 mDrawableContainerState.addChild(dr1); 353 354 // return result of constant state's isStateful 355 assertEquals(mDrawableContainerState.isStateful(), mDrawableContainer.isStateful()); 356 assertEquals(true, mDrawableContainer.isStateful()); 357 358 mDrawableContainer.selectDrawable(1); 359 assertEquals(mDrawableContainerState.isStateful(), mDrawableContainer.isStateful()); 360 assertEquals(true, mDrawableContainer.isStateful()); 361 } 362 testOnStateChange()363 public void testOnStateChange() { 364 assertConstantStateNotSet(); 365 assertNull(mDrawableContainer.getCurrent()); 366 367 assertFalse(mMockDrawableContainer.onStateChange(new int[] { 0 })); 368 assertFalse(mMockDrawableContainer.onStateChange(null)); 369 370 mMockDrawableContainer.setConstantState(mDrawableContainerState); 371 MockDrawable dr = new MockDrawable(); 372 dr.setState(new int[] { 0 }); 373 addAndSelectDrawable(dr); 374 375 // set current drawable's state. 376 dr.reset(); 377 assertNotNull(dr.getState()); 378 mMockDrawableContainer.onStateChange(null); 379 assertTrue(dr.hasOnStateChangedCalled()); 380 assertNull(dr.getState()); 381 382 dr.reset(); 383 mMockDrawableContainer.onStateChange(new int[] { 0 }); 384 assertTrue(dr.hasOnStateChangedCalled()); 385 assertTrue(Arrays.equals(new int[] { 0 }, dr.getState())); 386 387 dr.reset(); 388 assertFalse(mMockDrawableContainer.onStateChange(new int[] { 0 })); 389 assertFalse(dr.hasOnStateChangedCalled()); 390 assertTrue(Arrays.equals(new int[] { 0 }, dr.getState())); 391 } 392 testOnLevelChange()393 public void testOnLevelChange() { 394 assertConstantStateNotSet(); 395 assertNull(mDrawableContainer.getCurrent()); 396 397 assertFalse(mMockDrawableContainer.onLevelChange(Integer.MAX_VALUE)); 398 assertFalse(mMockDrawableContainer.onLevelChange(Integer.MIN_VALUE)); 399 400 mMockDrawableContainer.setConstantState(mDrawableContainerState); 401 MockDrawable dr = new MockDrawable(); 402 dr.setLevel(0); 403 addAndSelectDrawable(dr); 404 405 // set current drawable's level. 406 dr.reset(); 407 assertEquals(0, dr.getLevel()); 408 mMockDrawableContainer.onLevelChange(Integer.MAX_VALUE); 409 assertEquals(Integer.MAX_VALUE, dr.getLevel()); 410 assertTrue(dr.hasOnLevelChangedCalled()); 411 412 dr.reset(); 413 assertEquals(Integer.MAX_VALUE, dr.getLevel()); 414 mMockDrawableContainer.onLevelChange(Integer.MIN_VALUE); 415 assertEquals(Integer.MIN_VALUE, dr.getLevel()); 416 assertTrue(dr.hasOnLevelChangedCalled()); 417 418 dr.reset(); 419 assertEquals(Integer.MIN_VALUE, dr.getLevel()); 420 assertFalse(mMockDrawableContainer.onLevelChange(Integer.MIN_VALUE)); 421 assertEquals(Integer.MIN_VALUE, dr.getLevel()); 422 assertFalse(dr.hasOnLevelChangedCalled()); 423 } 424 testGetIntrinsicWidth()425 public void testGetIntrinsicWidth() { 426 assertConstantStateNotSet(); 427 428 try { 429 mDrawableContainer.getIntrinsicWidth(); 430 fail("Should throw NullPointerException if the constant state is not set."); 431 } catch (NullPointerException e) { 432 } 433 434 mMockDrawableContainer.setConstantState(mDrawableContainerState); 435 MockDrawable dr0 = new MockDrawable(); 436 dr0.setIntrinsicWidth(1); 437 mDrawableContainerState.addChild(dr0); 438 MockDrawable dr1 = new MockDrawable(); 439 dr1.setIntrinsicWidth(2); 440 mDrawableContainerState.addChild(dr1); 441 442 // return result of constant state's getConstantWidth 443 mDrawableContainerState.setConstantSize(true); 444 assertEquals(mDrawableContainerState.getConstantWidth(), 445 mDrawableContainer.getIntrinsicWidth()); 446 assertEquals(2, mDrawableContainer.getIntrinsicWidth()); 447 448 // return default value 449 mDrawableContainerState.setConstantSize(false); 450 assertNull(mDrawableContainer.getCurrent()); 451 assertEquals(-1, mDrawableContainer.getIntrinsicWidth()); 452 453 // return current drawable's getIntrinsicWidth 454 mDrawableContainer.selectDrawable(0); 455 assertSame(dr0, mDrawableContainer.getCurrent()); 456 assertEquals(1, mDrawableContainer.getIntrinsicWidth()); 457 } 458 testGetIntrinsicHeight()459 public void testGetIntrinsicHeight() { 460 assertConstantStateNotSet(); 461 462 try { 463 mDrawableContainer.getIntrinsicHeight(); 464 fail("Should throw NullPointerException if the constant state is not set."); 465 } catch (NullPointerException e) { 466 } 467 468 mMockDrawableContainer.setConstantState(mDrawableContainerState); 469 MockDrawable dr0 = new MockDrawable(); 470 dr0.setIntrinsicHeight(1); 471 mDrawableContainerState.addChild(dr0); 472 MockDrawable dr1 = new MockDrawable(); 473 dr1.setIntrinsicHeight(2); 474 mDrawableContainerState.addChild(dr1); 475 476 // return result of constant state's getConstantHeight 477 mDrawableContainerState.setConstantSize(true); 478 assertEquals(mDrawableContainerState.getConstantHeight(), 479 mDrawableContainer.getIntrinsicHeight()); 480 assertEquals(2, mDrawableContainer.getIntrinsicHeight()); 481 482 // return default value 483 mDrawableContainerState.setConstantSize(false); 484 assertNull(mDrawableContainer.getCurrent()); 485 assertEquals(-1, mDrawableContainer.getIntrinsicHeight()); 486 487 // return current drawable's getIntrinsicHeight 488 mDrawableContainer.selectDrawable(0); 489 assertSame(dr0, mDrawableContainer.getCurrent()); 490 assertEquals(1, mDrawableContainer.getIntrinsicHeight()); 491 } 492 testGetMinimumWidth()493 public void testGetMinimumWidth() { 494 assertConstantStateNotSet(); 495 496 try { 497 mDrawableContainer.getMinimumWidth(); 498 fail("Should throw NullPointerException if the constant state is not set."); 499 } catch (NullPointerException e) { 500 } 501 502 mMockDrawableContainer.setConstantState(mDrawableContainerState); 503 MockDrawable dr0 = new MockDrawable(); 504 dr0.setMinimumWidth(1); 505 mDrawableContainerState.addChild(dr0); 506 MockDrawable dr1 = new MockDrawable(); 507 dr1.setMinimumWidth(2); 508 mDrawableContainerState.addChild(dr1); 509 510 // return result of constant state's getConstantMinimumWidth 511 mDrawableContainerState.setConstantSize(true); 512 assertEquals(mDrawableContainerState.getConstantMinimumWidth(), 513 mDrawableContainer.getMinimumWidth()); 514 assertEquals(2, mDrawableContainer.getMinimumWidth()); 515 516 // return default value 517 mDrawableContainerState.setConstantSize(false); 518 assertNull(mDrawableContainer.getCurrent()); 519 assertEquals(0, mDrawableContainer.getMinimumWidth()); 520 521 // return current drawable's getMinimumWidth 522 mDrawableContainer.selectDrawable(0); 523 assertSame(dr0, mDrawableContainer.getCurrent()); 524 assertEquals(1, mDrawableContainer.getMinimumWidth()); 525 } 526 testGetMinimumHeight()527 public void testGetMinimumHeight() { 528 assertConstantStateNotSet(); 529 530 try { 531 mDrawableContainer.getMinimumHeight(); 532 fail("Should throw NullPointerException if the constant state is not set."); 533 } catch (NullPointerException e) { 534 } 535 536 mMockDrawableContainer.setConstantState(mDrawableContainerState); 537 MockDrawable dr0 = new MockDrawable(); 538 dr0.setMinimumHeight(1); 539 mDrawableContainerState.addChild(dr0); 540 MockDrawable dr1 = new MockDrawable(); 541 dr1.setMinimumHeight(2); 542 mDrawableContainerState.addChild(dr1); 543 544 // return result of constant state's getConstantMinimumHeight 545 mDrawableContainerState.setConstantSize(true); 546 assertEquals(mDrawableContainerState.getConstantMinimumHeight(), 547 mDrawableContainer.getMinimumHeight()); 548 assertEquals(2, mDrawableContainer.getMinimumHeight()); 549 550 // return default value 551 mDrawableContainerState.setConstantSize(false); 552 assertNull(mDrawableContainer.getCurrent()); 553 assertEquals(0, mDrawableContainer.getMinimumHeight()); 554 555 // return current drawable's getMinimumHeight 556 mDrawableContainer.selectDrawable(0); 557 assertSame(dr0, mDrawableContainer.getCurrent()); 558 assertEquals(1, mDrawableContainer.getMinimumHeight()); 559 } 560 testInvalidateDrawable()561 public void testInvalidateDrawable() { 562 // Workaround for CTS coverage not recognizing calls on subclasses. 563 DrawableContainer dr = mDrawableContainer; 564 565 assertConstantStateNotSet(); 566 assertNull(mDrawableContainer.getCurrent()); 567 568 mDrawableContainer.setCallback(null); 569 dr.invalidateDrawable(mDrawableContainer); 570 dr.invalidateDrawable(null); 571 572 MockCallBack callback = new MockCallBack(); 573 mDrawableContainer.setCallback(callback); 574 575 callback.reset(); 576 dr.invalidateDrawable(mDrawableContainer); 577 assertFalse(callback.hasInvalidateDrawableCalled()); 578 579 // the callback method can be called if the drawable passed in and the 580 // current drawble are both null 581 callback.reset(); 582 dr.invalidateDrawable(null); 583 assertTrue(callback.hasInvalidateDrawableCalled()); 584 585 mMockDrawableContainer.setConstantState(mDrawableContainerState); 586 MockDrawable mockDrawable = new MockDrawable(); 587 addAndSelectDrawable(mockDrawable); 588 589 callback.reset(); 590 dr.invalidateDrawable(mDrawableContainer); 591 assertFalse(callback.hasInvalidateDrawableCalled()); 592 593 callback.reset(); 594 dr.invalidateDrawable(null); 595 assertFalse(callback.hasInvalidateDrawableCalled()); 596 597 // Call the callback method if the drawable is selected. 598 callback.reset(); 599 dr.invalidateDrawable(mockDrawable); 600 assertTrue(callback.hasInvalidateDrawableCalled()); 601 } 602 testScheduleDrawable()603 public void testScheduleDrawable() { 604 // Workaround for CTS coverage not recognizing calls on subclasses. 605 DrawableContainer dr = mDrawableContainer; 606 607 assertConstantStateNotSet(); 608 assertNull(mDrawableContainer.getCurrent()); 609 610 mDrawableContainer.setCallback(null); 611 dr.scheduleDrawable(mDrawableContainer, null, 0); 612 dr.scheduleDrawable(null, new Runnable() { 613 public void run() { 614 } 615 }, 0); 616 617 MockCallBack callback = new MockCallBack(); 618 mDrawableContainer.setCallback(callback); 619 620 callback.reset(); 621 dr.scheduleDrawable(mDrawableContainer, null, 0); 622 assertFalse(callback.hasScheduleDrawableCalled()); 623 624 // the callback method can be called if the drawable passed in and the 625 // current drawble are both null 626 callback.reset(); 627 dr.scheduleDrawable(null, new Runnable() { 628 public void run() { 629 } 630 }, 0); 631 assertTrue(callback.hasScheduleDrawableCalled()); 632 633 mMockDrawableContainer.setConstantState(mDrawableContainerState); 634 MockDrawable mockDrawable = new MockDrawable(); 635 addAndSelectDrawable(mockDrawable); 636 637 callback.reset(); 638 dr.scheduleDrawable(mDrawableContainer, null, 0); 639 assertFalse(callback.hasScheduleDrawableCalled()); 640 641 callback.reset(); 642 dr.scheduleDrawable(null, new Runnable() { 643 public void run() { 644 } 645 }, 0); 646 assertFalse(callback.hasScheduleDrawableCalled()); 647 648 // Call the callback method if the drawable is selected. 649 callback.reset(); 650 dr.scheduleDrawable(mockDrawable, null, 0); 651 assertTrue(callback.hasScheduleDrawableCalled()); 652 } 653 testUnscheduleDrawable()654 public void testUnscheduleDrawable() { 655 // Workaround for CTS coverage not recognizing calls on subclasses. 656 DrawableContainer dr = mDrawableContainer; 657 658 assertConstantStateNotSet(); 659 assertNull(mDrawableContainer.getCurrent()); 660 661 mDrawableContainer.setCallback(null); 662 dr.unscheduleDrawable(mDrawableContainer, null); 663 dr.unscheduleDrawable(null, new Runnable() { 664 public void run() { 665 } 666 }); 667 668 MockCallBack callback = new MockCallBack(); 669 mDrawableContainer.setCallback(callback); 670 671 callback.reset(); 672 dr.unscheduleDrawable(mDrawableContainer, null); 673 assertFalse(callback.hasUnscheduleDrawableCalled()); 674 675 // the callback method can be called if the drawable passed in and the 676 // current drawble are both null 677 callback.reset(); 678 dr.unscheduleDrawable(null, new Runnable() { 679 public void run() { 680 } 681 }); 682 assertTrue(callback.hasUnscheduleDrawableCalled()); 683 684 mMockDrawableContainer.setConstantState(mDrawableContainerState); 685 MockDrawable mockDrawable = new MockDrawable(); 686 addAndSelectDrawable(mockDrawable); 687 688 callback.reset(); 689 dr.unscheduleDrawable(mDrawableContainer, null); 690 assertFalse(callback.hasUnscheduleDrawableCalled()); 691 692 callback.reset(); 693 dr.unscheduleDrawable(null, new Runnable() { 694 public void run() { 695 } 696 }); 697 assertFalse(callback.hasUnscheduleDrawableCalled()); 698 699 // Call the callback method if the drawable is selected. 700 callback.reset(); 701 dr.unscheduleDrawable(mockDrawable, null); 702 assertTrue(callback.hasUnscheduleDrawableCalled()); 703 } 704 testSetVisible()705 public void testSetVisible() { 706 assertConstantStateNotSet(); 707 assertNull(mDrawableContainer.getCurrent()); 708 709 assertTrue(mDrawableContainer.isVisible()); 710 assertFalse(mDrawableContainer.setVisible(true, false)); 711 assertTrue(mDrawableContainer.setVisible(false, false)); 712 assertFalse(mDrawableContainer.setVisible(false, false)); 713 assertTrue(mDrawableContainer.setVisible(true, false)); 714 715 mMockDrawableContainer.setConstantState(mDrawableContainerState); 716 MockDrawable dr = new MockDrawable(); 717 addAndSelectDrawable(dr); 718 719 // set current drawable's visibility 720 assertTrue(mDrawableContainer.isVisible()); 721 assertTrue(dr.isVisible()); 722 assertTrue(mDrawableContainer.setVisible(false, false)); 723 assertFalse(mDrawableContainer.isVisible()); 724 assertFalse(dr.isVisible()); 725 } 726 testGetOpacity()727 public void testGetOpacity() { 728 // Workaround for CTS coverage not recognizing calls on subclasses. 729 DrawableContainer dr = mDrawableContainer; 730 731 assertConstantStateNotSet(); 732 733 // there is no child, so the container is transparent 734 assertEquals(PixelFormat.TRANSPARENT, dr.getOpacity()); 735 736 mMockDrawableContainer.setConstantState(mDrawableContainerState); 737 MockDrawable dr0 = new MockDrawable(); 738 dr0.setOpacity(PixelFormat.OPAQUE); 739 mDrawableContainerState.addChild(dr0); 740 // no child selected yet 741 assertEquals(PixelFormat.TRANSPARENT, dr.getOpacity()); 742 743 dr.selectDrawable(0); 744 assertEquals(mDrawableContainerState.getOpacity(), dr.getOpacity()); 745 assertEquals(PixelFormat.OPAQUE, mDrawableContainer.getOpacity()); 746 747 MockDrawable dr1 = new MockDrawable(); 748 dr1.setOpacity(PixelFormat.TRANSLUCENT); 749 mDrawableContainerState.addChild(dr1); 750 751 dr.selectDrawable(1); 752 assertEquals(mDrawableContainerState.getOpacity(), dr.getOpacity()); 753 assertEquals(PixelFormat.TRANSLUCENT, dr.getOpacity()); 754 } 755 testAccessCurrentDrawable()756 public void testAccessCurrentDrawable() { 757 // Workaround for CTS coverage not recognizing calls on subclasses. 758 DrawableContainer dr = mDrawableContainer; 759 760 assertConstantStateNotSet(); 761 762 assertNull(mDrawableContainer.getCurrent()); 763 try { 764 dr.selectDrawable(0); 765 fail("Should throw NullPointerException if the constant state is not set."); 766 } catch (NullPointerException e) { 767 } 768 769 mMockDrawableContainer.setConstantState(mDrawableContainerState); 770 MockDrawable dr0 = new MockDrawable(); 771 dr0.setVisible(false, false); 772 assertFalse(dr0.isVisible()); 773 mDrawableContainerState.addChild(dr0); 774 MockDrawable dr1 = new MockDrawable(); 775 dr1.setVisible(false, false); 776 assertFalse(dr1.isVisible()); 777 mDrawableContainerState.addChild(dr1); 778 779 assertTrue(dr.selectDrawable(0)); 780 assertSame(dr0, mDrawableContainer.getCurrent()); 781 assertTrue(dr0.isVisible()); 782 783 assertFalse(dr.selectDrawable(0)); 784 785 assertTrue(dr.selectDrawable(1)); 786 assertSame(dr1, mDrawableContainer.getCurrent()); 787 assertTrue(dr1.isVisible()); 788 assertFalse(dr0.isVisible()); 789 790 assertFalse(dr.selectDrawable(1)); 791 792 assertTrue(dr.selectDrawable(-1)); 793 assertNull(mDrawableContainer.getCurrent()); 794 assertFalse(dr0.isVisible()); 795 assertFalse(dr1.isVisible()); 796 797 assertTrue(dr.selectDrawable(2)); 798 assertNull(mDrawableContainer.getCurrent()); 799 assertFalse(dr0.isVisible()); 800 assertFalse(dr1.isVisible()); 801 } 802 testAccessConstantState()803 public void testAccessConstantState() { 804 try { 805 mDrawableContainer.getConstantState(); 806 fail("Should throw NullPointerException if the constant state is not set."); 807 } catch (NullPointerException e) { 808 } 809 810 mMockDrawableContainer.setConstantState(mDrawableContainerState); 811 assertSame(mDrawableContainerState, mDrawableContainer.getConstantState()); 812 813 mMockDrawableContainer.setConstantState(null); 814 assertConstantStateNotSet(); 815 } 816 testMutate()817 public void testMutate() { 818 assertConstantStateNotSet(); 819 try { 820 mDrawableContainer.mutate(); 821 fail("Should throw NullPointerException."); 822 } catch (NullPointerException e) { 823 } 824 825 mMockDrawableContainer.setConstantState(mDrawableContainerState); 826 MockDrawable dr0 = new MockDrawable(); 827 mDrawableContainerState.addChild(dr0); 828 mDrawableContainer.mutate(); 829 assertTrue(dr0.hasMutateCalled()); 830 } 831 addAndSelectDrawable(MockDrawable mockDrawable)832 private void addAndSelectDrawable(MockDrawable mockDrawable) { 833 // Workaround for CTS coverage not recognizing calls on subclasses. 834 DrawableContainer dr = mDrawableContainer; 835 836 int pos = mDrawableContainerState.addChild(mockDrawable); 837 dr.selectDrawable(pos); 838 assertSame(mockDrawable, dr.getCurrent()); 839 } 840 assertConstantStateNotSet()841 private void assertConstantStateNotSet() { 842 try { 843 mDrawableContainer.getConstantState(); 844 fail("Should throw NullPointerException."); 845 } catch (NullPointerException e) { 846 } 847 } 848 849 private class MockDrawableContainer extends DrawableContainer { 850 @Override onBoundsChange(Rect bounds)851 protected void onBoundsChange(Rect bounds) { 852 super.onBoundsChange(bounds); 853 } 854 855 @Override onLevelChange(int level)856 protected boolean onLevelChange(int level) { 857 return super.onLevelChange(level); 858 } 859 860 @Override onStateChange(int[] state)861 protected boolean onStateChange(int[] state) { 862 return super.onStateChange(state); 863 } 864 865 @Override setConstantState(DrawableContainerState state)866 protected void setConstantState(DrawableContainerState state) { 867 super.setConstantState(state); 868 } 869 } 870 871 private class MockDrawable extends Drawable { 872 private boolean mHasCalledDraw; 873 private boolean mHasCalledSetAlpha; 874 private boolean mHasCalledSetColorFilter; 875 private boolean mHasCalledSetDither; 876 private boolean mHasCalledSetTint; 877 private boolean mHasCalledOnBoundsChanged; 878 private boolean mHasCalledOnStateChanged; 879 private boolean mHasCalledOnLevelChanged; 880 private boolean mHasCalledMutate; 881 882 private boolean mIsStateful; 883 884 private Rect mPadding; 885 886 private int mIntrinsicHeight; 887 private int mIntrinsicWidth; 888 889 private int mMinimumHeight; 890 private int mMinimumWidth; 891 892 private int mOpacity; 893 894 private Mode mTintMode; 895 896 @Override getOpacity()897 public int getOpacity() { 898 return mOpacity; 899 } 900 901 @Override isStateful()902 public boolean isStateful() { 903 return mIsStateful; 904 } 905 setStateful(boolean isStateful)906 public void setStateful(boolean isStateful) { 907 mIsStateful = isStateful; 908 } 909 getTintMode()910 public Mode getTintMode() { 911 return mTintMode; 912 } 913 setPadding(Rect rect)914 public void setPadding(Rect rect) { 915 if (mPadding == null) { 916 mPadding = new Rect(); 917 } 918 mPadding.set(rect); 919 } 920 921 @Override getPadding(Rect padding)922 public boolean getPadding(Rect padding) { 923 if (padding == null || mPadding == null) { 924 return false; 925 } 926 padding.set(mPadding); 927 return true; 928 } 929 930 @Override getMinimumHeight()931 public int getMinimumHeight() { 932 return mMinimumHeight; 933 } 934 935 @Override getMinimumWidth()936 public int getMinimumWidth() { 937 return mMinimumWidth; 938 } 939 940 @Override getIntrinsicHeight()941 public int getIntrinsicHeight() { 942 return mIntrinsicHeight; 943 } 944 945 @Override getIntrinsicWidth()946 public int getIntrinsicWidth() { 947 return mIntrinsicWidth; 948 } 949 950 @Override mutate()951 public Drawable mutate() { 952 mHasCalledMutate = true; 953 return this; 954 } 955 956 @Override setTintMode(Mode tintMode)957 public void setTintMode(Mode tintMode) { 958 mTintMode = tintMode; 959 mHasCalledSetTint = true; 960 } 961 setMinimumHeight(int h)962 public void setMinimumHeight(int h) { 963 mMinimumHeight = h; 964 } 965 setMinimumWidth(int w)966 public void setMinimumWidth(int w) { 967 mMinimumWidth = w; 968 } 969 setIntrinsicHeight(int h)970 public void setIntrinsicHeight(int h) { 971 mIntrinsicHeight = h; 972 } 973 setIntrinsicWidth(int w)974 public void setIntrinsicWidth(int w) { 975 mIntrinsicWidth = w; 976 } 977 setOpacity(int opacity)978 public void setOpacity(int opacity) { 979 mOpacity = opacity; 980 } 981 hasDrawCalled()982 public boolean hasDrawCalled() { 983 return mHasCalledDraw; 984 } 985 hasSetAlphaCalled()986 public boolean hasSetAlphaCalled() { 987 return mHasCalledSetAlpha; 988 } 989 hasSetColorFilterCalled()990 public boolean hasSetColorFilterCalled() { 991 return mHasCalledSetColorFilter; 992 } 993 hasSetDitherCalled()994 public boolean hasSetDitherCalled() { 995 return mHasCalledSetDither; 996 } 997 hasSetTintCalled()998 public boolean hasSetTintCalled() { 999 return mHasCalledSetTint; 1000 } 1001 hasOnBoundsChangedCalled()1002 public boolean hasOnBoundsChangedCalled() { 1003 return mHasCalledOnBoundsChanged; 1004 } 1005 hasOnStateChangedCalled()1006 public boolean hasOnStateChangedCalled() { 1007 return mHasCalledOnStateChanged; 1008 } 1009 hasOnLevelChangedCalled()1010 public boolean hasOnLevelChangedCalled() { 1011 return mHasCalledOnLevelChanged; 1012 } 1013 hasMutateCalled()1014 public boolean hasMutateCalled() { 1015 return mHasCalledMutate; 1016 } 1017 reset()1018 public void reset() { 1019 mHasCalledOnLevelChanged = false; 1020 mHasCalledOnStateChanged = false; 1021 mHasCalledOnBoundsChanged = false; 1022 mHasCalledSetDither = false; 1023 mHasCalledSetColorFilter = false; 1024 mHasCalledSetAlpha = false; 1025 mHasCalledDraw = false; 1026 mHasCalledMutate = false; 1027 } 1028 1029 @Override draw(Canvas canvas)1030 public void draw(Canvas canvas) { 1031 mHasCalledDraw = true; 1032 } 1033 1034 @Override setAlpha(int alpha)1035 public void setAlpha(int alpha) { 1036 mHasCalledSetAlpha = true; 1037 } 1038 1039 @Override setColorFilter(ColorFilter cf)1040 public void setColorFilter(ColorFilter cf) { 1041 mHasCalledSetColorFilter = true; 1042 } 1043 1044 @Override onBoundsChange(Rect bounds)1045 protected void onBoundsChange(Rect bounds) { 1046 super.onBoundsChange(bounds); 1047 mHasCalledOnBoundsChanged = true; 1048 } 1049 1050 @Override onLevelChange(int level)1051 protected boolean onLevelChange(int level) { 1052 boolean result = super.onLevelChange(level); 1053 mHasCalledOnLevelChanged = true; 1054 return result; 1055 } 1056 1057 @Override onStateChange(int[] state)1058 protected boolean onStateChange(int[] state) { 1059 boolean result = super.onStateChange(state); 1060 mHasCalledOnStateChanged = true; 1061 return result; 1062 1063 } 1064 1065 @Override setDither(boolean dither)1066 public void setDither(boolean dither) { 1067 super.setDither(dither); 1068 mHasCalledSetDither = true; 1069 } 1070 } 1071 1072 private class MockCallBack implements Drawable.Callback { 1073 private boolean mCalledInvalidateDrawable; 1074 1075 private boolean mCalledScheduleDrawable; 1076 1077 private boolean mCalledUnscheduleDrawable; 1078 hasInvalidateDrawableCalled()1079 public boolean hasInvalidateDrawableCalled() { 1080 return mCalledInvalidateDrawable; 1081 } 1082 hasScheduleDrawableCalled()1083 public boolean hasScheduleDrawableCalled() { 1084 return mCalledScheduleDrawable; 1085 } 1086 hasUnscheduleDrawableCalled()1087 public boolean hasUnscheduleDrawableCalled() { 1088 return mCalledUnscheduleDrawable; 1089 } 1090 reset()1091 public void reset() { 1092 mCalledUnscheduleDrawable = false; 1093 mCalledScheduleDrawable = false; 1094 mCalledInvalidateDrawable = false; 1095 } 1096 invalidateDrawable(Drawable who)1097 public void invalidateDrawable(Drawable who) { 1098 mCalledInvalidateDrawable = true; 1099 } 1100 scheduleDrawable(Drawable who, Runnable what, long when)1101 public void scheduleDrawable(Drawable who, Runnable what, long when) { 1102 mCalledScheduleDrawable = true; 1103 } 1104 unscheduleDrawable(Drawable who, Runnable what)1105 public void unscheduleDrawable(Drawable who, Runnable what) { 1106 mCalledUnscheduleDrawable = true; 1107 } 1108 getResolvedLayoutDirection(Drawable who)1109 public int getResolvedLayoutDirection(Drawable who) { 1110 return 0; 1111 } 1112 } 1113 } 1114