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