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 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.assertSame;
     23 import static org.junit.Assert.assertTrue;
     24 import static org.junit.Assert.fail;
     25 import static org.mockito.Matchers.any;
     26 import static org.mockito.Matchers.anyBoolean;
     27 import static org.mockito.Matchers.anyInt;
     28 import static org.mockito.Matchers.anyLong;
     29 import static org.mockito.Mockito.atLeastOnce;
     30 import static org.mockito.Mockito.doNothing;
     31 import static org.mockito.Mockito.mock;
     32 import static org.mockito.Mockito.never;
     33 import static org.mockito.Mockito.reset;
     34 import static org.mockito.Mockito.spy;
     35 import static org.mockito.Mockito.times;
     36 import static org.mockito.Mockito.verify;
     37 
     38 import android.content.Context;
     39 import android.content.res.Resources;
     40 import android.content.res.XmlResourceParser;
     41 import android.graphics.Canvas;
     42 import android.graphics.Color;
     43 import android.graphics.ColorFilter;
     44 import android.graphics.Rect;
     45 import android.graphics.cts.R;
     46 import android.graphics.drawable.BitmapDrawable;
     47 import android.graphics.drawable.ColorDrawable;
     48 import android.graphics.drawable.Drawable;
     49 import android.graphics.drawable.Drawable.ConstantState;
     50 import android.graphics.drawable.ScaleDrawable;
     51 import android.support.test.InstrumentationRegistry;
     52 import android.support.test.filters.SmallTest;
     53 import android.support.test.runner.AndroidJUnit4;
     54 import android.util.AttributeSet;
     55 import android.util.StateSet;
     56 import android.view.Gravity;
     57 
     58 import org.junit.Before;
     59 import org.junit.Test;
     60 import org.junit.runner.RunWith;
     61 import org.xmlpull.v1.XmlPullParserException;
     62 
     63 import java.io.IOException;
     64 import java.util.Arrays;
     65 
     66 @SmallTest
     67 @RunWith(AndroidJUnit4.class)
     68 public class ScaleDrawableTest {
     69     private Context mContext;
     70 
     71     @Before
     72     public void setup() {
     73         mContext = InstrumentationRegistry.getTargetContext();
     74     }
     75 
     76     @SuppressWarnings("deprecation")
     77     @Test
     78     public void testConstructor() {
     79         Drawable d = new BitmapDrawable();
     80         ScaleDrawable scaleDrawable = new ScaleDrawable(d, Gravity.CENTER, 100, 200);
     81         assertSame(d, scaleDrawable.getDrawable());
     82 
     83         new ScaleDrawable(null, -1, Float.MAX_VALUE, Float.MIN_VALUE);
     84     }
     85 
     86     @SuppressWarnings("deprecation")
     87     @Test
     88     public void testInvalidateDrawable() {
     89         ScaleDrawable scaleDrawable = new ScaleDrawable(new BitmapDrawable(),
     90                 Gravity.CENTER, 100, 200);
     91 
     92         Drawable.Callback callback = mock(Drawable.Callback.class);
     93         scaleDrawable.setCallback(callback);
     94         scaleDrawable.invalidateDrawable(null);
     95         verify(callback, times(1)).invalidateDrawable(any());
     96 
     97         reset(callback);
     98         scaleDrawable.invalidateDrawable(new BitmapDrawable());
     99         verify(callback, times(1)).invalidateDrawable(any());
    100 
    101         reset(callback);
    102         scaleDrawable.setCallback(null);
    103         scaleDrawable.invalidateDrawable(null);
    104         verify(callback, never()).invalidateDrawable(any());
    105     }
    106 
    107     @SuppressWarnings("deprecation")
    108     @Test
    109     public void testScheduleDrawable() {
    110         ScaleDrawable scaleDrawable = new ScaleDrawable(new BitmapDrawable(),
    111                 Gravity.CENTER, 100, 200);
    112 
    113         Drawable.Callback callback = mock(Drawable.Callback.class);
    114         scaleDrawable.setCallback(callback);
    115         scaleDrawable.scheduleDrawable(null, null, 0);
    116         verify(callback, times(1)).scheduleDrawable(any(), any(), anyLong());
    117 
    118         reset(callback);
    119         scaleDrawable.scheduleDrawable(new BitmapDrawable(), () -> {}, 1000L);
    120         verify(callback, times(1)).scheduleDrawable(any(), any(), anyLong());
    121 
    122         reset(callback);
    123         scaleDrawable.setCallback(null);
    124         scaleDrawable.scheduleDrawable(null, null, 0);
    125         verify(callback, never()).scheduleDrawable(any(), any(), anyLong());
    126     }
    127 
    128     @SuppressWarnings("deprecation")
    129     @Test
    130     public void testUnscheduleDrawable() {
    131         ScaleDrawable scaleDrawable = new ScaleDrawable(new BitmapDrawable(),
    132                 Gravity.CENTER, 100, 200);
    133 
    134         Drawable.Callback callback = mock(Drawable.Callback.class);
    135         scaleDrawable.setCallback(callback);
    136         scaleDrawable.unscheduleDrawable(null, null);
    137         verify(callback, times(1)).unscheduleDrawable(any(), any());
    138 
    139         reset(callback);
    140         scaleDrawable.unscheduleDrawable(new BitmapDrawable(), () -> {});
    141         verify(callback, times(1)).unscheduleDrawable(any(), any());
    142 
    143         reset(callback);
    144         scaleDrawable.setCallback(null);
    145         scaleDrawable.unscheduleDrawable(null, null);
    146         verify(callback, never()).unscheduleDrawable(any(), any());
    147     }
    148 
    149     @Test
    150     public void testDraw() {
    151         Drawable mockDrawable = spy(new ColorDrawable(Color.RED));
    152         ScaleDrawable scaleDrawable = new ScaleDrawable(mockDrawable, Gravity.CENTER, 100, 200);
    153 
    154         scaleDrawable.draw(new Canvas());
    155         verify(mockDrawable, never()).draw(any());
    156 
    157         // this method will call the contained drawable's draw method
    158         // if the contained drawable's level doesn't equal 0.
    159         mockDrawable.setLevel(1);
    160         scaleDrawable.draw(new Canvas());
    161         verify(mockDrawable, times(1)).draw(any());
    162 
    163         reset(mockDrawable);
    164         doNothing().when(mockDrawable).draw(any());
    165         scaleDrawable.draw(null);
    166         verify(mockDrawable, times(1)).draw(any());
    167     }
    168 
    169     @Test
    170     public void testGetChangingConfigurations() {
    171         final int SUPER_CONFIG = 1;
    172         final int CONTAINED_DRAWABLE_CONFIG = 2;
    173 
    174         Drawable mockDrawable = new ColorDrawable(Color.YELLOW);
    175         ScaleDrawable scaleDrawable = new ScaleDrawable(mockDrawable, Gravity.CENTER, 100, 200);
    176 
    177         assertEquals(0, scaleDrawable.getChangingConfigurations());
    178 
    179         mockDrawable.setChangingConfigurations(CONTAINED_DRAWABLE_CONFIG);
    180         assertEquals(CONTAINED_DRAWABLE_CONFIG, scaleDrawable.getChangingConfigurations());
    181 
    182         scaleDrawable.setChangingConfigurations(SUPER_CONFIG);
    183         assertEquals(SUPER_CONFIG | CONTAINED_DRAWABLE_CONFIG,
    184                 scaleDrawable.getChangingConfigurations());
    185     }
    186 
    187     @Test
    188     public void testGetPadding() {
    189         Drawable mockDrawable = spy(new ColorDrawable(Color.RED));
    190         ScaleDrawable scaleDrawable = new ScaleDrawable(mockDrawable, Gravity.CENTER, 100, 200);
    191 
    192         // this method will call contained drawable's getPadding method.
    193         scaleDrawable.getPadding(new Rect());
    194         verify(mockDrawable, times(1)).getPadding(any());
    195     }
    196 
    197     @Test(expected=NullPointerException.class)
    198     public void testGetPaddingNull() {
    199         Drawable mockDrawable = new ColorDrawable(Color.YELLOW);
    200         ScaleDrawable scaleDrawable = new ScaleDrawable(mockDrawable, Gravity.CENTER, 100, 200);
    201 
    202         scaleDrawable.getPadding(null);
    203     }
    204 
    205     @Test
    206     public void testSetVisible() {
    207         Drawable mockDrawable = spy(new ColorDrawable(Color.RED));
    208         ScaleDrawable scaleDrawable = new ScaleDrawable(mockDrawable, Gravity.CENTER, 100, 200);
    209         assertTrue(scaleDrawable.isVisible());
    210 
    211         assertTrue(scaleDrawable.setVisible(false, false));
    212         assertFalse(scaleDrawable.isVisible());
    213         verify(mockDrawable, atLeastOnce()).setVisible(anyBoolean(), anyBoolean());
    214 
    215         reset(mockDrawable);
    216         assertFalse(scaleDrawable.setVisible(false, false));
    217         assertFalse(scaleDrawable.isVisible());
    218         verify(mockDrawable, times(1)).setVisible(anyBoolean(), anyBoolean());
    219 
    220         reset(mockDrawable);
    221         assertTrue(scaleDrawable.setVisible(true, false));
    222         assertTrue(scaleDrawable.isVisible());
    223         verify(mockDrawable, times(1)).setVisible(anyBoolean(), anyBoolean());
    224     }
    225 
    226     @Test
    227     public void testSetAlpha() {
    228         Drawable mockDrawable = spy(new ColorDrawable(Color.RED));
    229         ScaleDrawable scaleDrawable = new ScaleDrawable(mockDrawable, Gravity.CENTER, 100, 200);
    230 
    231         // this method will call contained drawable's setAlpha method.
    232         scaleDrawable.setAlpha(100);
    233         verify(mockDrawable, times(1)).setAlpha(anyInt());
    234 
    235         reset(mockDrawable);
    236         scaleDrawable.setAlpha(Integer.MAX_VALUE);
    237         verify(mockDrawable, times(1)).setAlpha(anyInt());
    238 
    239         reset(mockDrawable);
    240         scaleDrawable.setAlpha(-1);
    241         verify(mockDrawable, times(1)).setAlpha(anyInt());
    242     }
    243 
    244     @Test
    245     public void testSetColorFilter() {
    246         Drawable mockDrawable = spy(new ColorDrawable(Color.RED));
    247         ScaleDrawable scaleDrawable = new ScaleDrawable(mockDrawable, Gravity.CENTER, 100, 200);
    248 
    249         // this method will call contained drawable's setColorFilter method.
    250         scaleDrawable.setColorFilter(new ColorFilter());
    251         verify(mockDrawable, times(1)).setColorFilter(any());
    252 
    253         reset(mockDrawable);
    254         scaleDrawable.setColorFilter(null);
    255         verify(mockDrawable, times(1)).setColorFilter(any());
    256     }
    257 
    258     @Test
    259     public void testGetOpacity() {
    260         Drawable mockDrawable = spy(new ColorDrawable(Color.RED));
    261         ScaleDrawable scaleDrawable = new ScaleDrawable(mockDrawable, Gravity.CENTER, 100, 200);
    262 
    263         // This method will call contained drawable's getOpacity method.
    264         scaleDrawable.setLevel(1);
    265         scaleDrawable.getOpacity();
    266         verify(mockDrawable, times(1)).getOpacity();
    267     }
    268 
    269     @Test
    270     public void testIsStateful() {
    271         Drawable mockDrawable = spy(new ColorDrawable(Color.RED));
    272         ScaleDrawable scaleDrawable = new ScaleDrawable(mockDrawable, Gravity.CENTER, 100, 200);
    273 
    274         // this method will call contained drawable's isStateful method.
    275         scaleDrawable.isStateful();
    276         verify(mockDrawable, times(1)).isStateful();
    277     }
    278 
    279     @Test
    280     public void testOnStateChange() {
    281         Drawable d = new MockDrawable();
    282         MockScaleDrawable scaleDrawable = new MockScaleDrawable(d, Gravity.CENTER, 100, 200);
    283         assertEquals("initial child state is empty", d.getState(), StateSet.WILD_CARD);
    284 
    285         int[] state = new int[] {1, 2, 3};
    286         assertFalse("child did not change", scaleDrawable.onStateChange(state));
    287         assertEquals("child state did not change", d.getState(), StateSet.WILD_CARD);
    288 
    289         d = mContext.getDrawable(R.drawable.statelistdrawable);
    290         scaleDrawable = new MockScaleDrawable(d, Gravity.CENTER, 100, 200);
    291         assertEquals("initial child state is empty", d.getState(), StateSet.WILD_CARD);
    292         scaleDrawable.onStateChange(state);
    293         assertTrue("child state changed", Arrays.equals(state, d.getState()));
    294 
    295         // input null as param
    296         scaleDrawable.onStateChange(null);
    297         // expected, no Exception thrown out, test success
    298     }
    299 
    300     @Test
    301     public void testInitialLevel() throws XmlPullParserException, IOException {
    302         ScaleDrawable dr = new ScaleDrawable(null, Gravity.CENTER, 1, 1);
    303         Resources res = mContext.getResources();
    304         XmlResourceParser parser = res.getXml(R.xml.scaledrawable_level);
    305         AttributeSet attrs = DrawableTestUtils.getAttributeSet(parser, "scale_allattrs");
    306 
    307         // Ensure that initial level is loaded from XML.
    308         dr.inflate(res, parser, attrs);
    309         assertEquals(5000, dr.getLevel());
    310 
    311         dr.setLevel(0);
    312         assertEquals(0, dr.getLevel());
    313 
    314         // Ensure that initial level is propagated to constant state clones.
    315         ScaleDrawable clone = (ScaleDrawable) dr.getConstantState().newDrawable(res);
    316         assertEquals(5000, clone.getLevel());
    317 
    318         // Ensure that current level is not tied to constant state.
    319         dr.setLevel(1000);
    320         assertEquals(1000, dr.getLevel());
    321         assertEquals(5000, clone.getLevel());
    322     }
    323 
    324     @Test
    325     public void testOnLevelChange() {
    326         MockDrawable mockDrawable = new MockDrawable();
    327         MockScaleDrawable mockScaleDrawable = new MockScaleDrawable(
    328                 mockDrawable, Gravity.CENTER, 100, 200);
    329 
    330         assertTrue(mockScaleDrawable.onLevelChange(0));
    331         assertFalse(mockDrawable.hasCalledOnLevelChange());
    332         assertTrue(mockScaleDrawable.hasCalledOnBoundsChange());
    333 
    334         mockDrawable.reset();
    335         mockScaleDrawable.reset();
    336         assertTrue(mockScaleDrawable.onLevelChange(Integer.MIN_VALUE));
    337         assertTrue(mockDrawable.hasCalledOnLevelChange());
    338         assertTrue(mockScaleDrawable.hasCalledOnBoundsChange());
    339     }
    340 
    341     @Test
    342     public void testOnBoundsChange() {
    343         Drawable mockDrawable = new ColorDrawable(Color.YELLOW);
    344         float scaleWidth = 0.3f;
    345         float scaleHeight = 0.3f;
    346         MockScaleDrawable mockScaleDrawable = new MockScaleDrawable(
    347                 mockDrawable, Gravity.LEFT, scaleWidth, scaleHeight);
    348         Rect bounds = new Rect(2, 2, 26, 32);
    349         mockDrawable.setBounds(bounds);
    350         mockScaleDrawable.onBoundsChange(bounds);
    351         Rect expected = new Rect();
    352         Gravity.apply(Gravity.LEFT, bounds.width() - (int) (bounds.width() * scaleWidth),
    353                 bounds.height() - (int) (bounds.height() * scaleHeight), bounds, expected);
    354         assertEquals(expected.left, mockDrawable.getBounds().left);
    355         assertEquals(expected.top, mockDrawable.getBounds().top);
    356         assertEquals(expected.right, mockDrawable.getBounds().right);
    357         assertEquals(expected.bottom, mockDrawable.getBounds().bottom);
    358 
    359         scaleWidth = 0.6f;
    360         scaleHeight = 0.7f;
    361         int level = 4000;
    362         mockScaleDrawable = new MockScaleDrawable(
    363                 mockDrawable, Gravity.BOTTOM | Gravity.RIGHT, scaleWidth, scaleHeight);
    364         mockDrawable.setBounds(bounds);
    365         mockScaleDrawable.setLevel(level);
    366         mockScaleDrawable.onBoundsChange(bounds);
    367         Gravity.apply(Gravity.BOTTOM | Gravity.RIGHT,
    368                 bounds.width() - (int) (bounds.width() * scaleWidth * (10000 - level) / 10000),
    369                 bounds.height() - (int) (bounds.height() * scaleHeight * (10000 - level) / 10000),
    370                 bounds, expected);
    371         assertEquals(expected.left, mockDrawable.getBounds().left);
    372         assertEquals(expected.top, mockDrawable.getBounds().top);
    373         assertEquals(expected.right, mockDrawable.getBounds().right);
    374         assertEquals(expected.bottom, mockDrawable.getBounds().bottom);
    375 
    376         scaleWidth = 0f;
    377         scaleHeight = -0.3f;
    378         mockScaleDrawable = new MockScaleDrawable(
    379                 mockDrawable, Gravity.BOTTOM | Gravity.RIGHT, scaleWidth, scaleHeight);
    380         mockDrawable.setBounds(bounds);
    381         mockScaleDrawable.onBoundsChange(bounds);
    382         assertEquals(bounds.left, mockDrawable.getBounds().left);
    383         assertEquals(bounds.top, mockDrawable.getBounds().top);
    384         assertEquals(bounds.right, mockDrawable.getBounds().right);
    385         assertEquals(bounds.bottom, mockDrawable.getBounds().bottom);
    386 
    387         scaleWidth = 1f;
    388         scaleHeight = 1.7f;
    389         mockScaleDrawable = new MockScaleDrawable(
    390                 mockDrawable, Gravity.BOTTOM | Gravity.RIGHT, scaleWidth, scaleHeight);
    391         mockDrawable.setBounds(bounds);
    392         mockScaleDrawable.onBoundsChange(bounds);
    393         assertEquals(bounds.left, mockDrawable.getBounds().left);
    394         assertEquals(bounds.top, mockDrawable.getBounds().top);
    395         assertEquals(bounds.right, mockDrawable.getBounds().right);
    396         assertEquals(bounds.bottom, mockDrawable.getBounds().bottom);
    397     }
    398 
    399     @Test
    400     public void testGetIntrinsicWidth() {
    401         Drawable mockDrawable = spy(new ColorDrawable(Color.RED));
    402         ScaleDrawable scaleDrawable = new ScaleDrawable(mockDrawable, Gravity.CENTER, 100, 200);
    403 
    404         // this method will call contained drawable's getIntrinsicWidth method.
    405         scaleDrawable.getIntrinsicWidth();
    406         verify(mockDrawable, times(1)).getIntrinsicWidth();
    407     }
    408 
    409     @Test
    410     public void testGetIntrinsicHeight() {
    411         Drawable mockDrawable = spy(new ColorDrawable(Color.RED));
    412         ScaleDrawable scaleDrawable = new ScaleDrawable(mockDrawable, Gravity.CENTER, 100, 200);
    413 
    414         // this method will call contained drawable's getIntrinsicHeight method.
    415         scaleDrawable.getIntrinsicHeight();
    416         verify(mockDrawable, times(1)).getIntrinsicHeight();
    417     }
    418 
    419     @SuppressWarnings("deprecation")
    420     @Test
    421     public void testGetConstantState() {
    422         ScaleDrawable scaleDrawable = new ScaleDrawable(new BitmapDrawable(),
    423                 Gravity.CENTER, 100, 200);
    424 
    425         ConstantState constantState = scaleDrawable.getConstantState();
    426         assertNotNull(constantState);
    427         assertEquals(0, constantState.getChangingConfigurations());
    428 
    429         scaleDrawable.setChangingConfigurations(1);
    430         constantState = scaleDrawable.getConstantState();
    431         assertNotNull(constantState);
    432         assertEquals(1, constantState.getChangingConfigurations());
    433     }
    434 
    435     @SuppressWarnings("deprecation")
    436     @Test
    437     public void testInflate() throws XmlPullParserException, IOException {
    438         ScaleDrawable scaleDrawable = new ScaleDrawable(new BitmapDrawable(),
    439                 Gravity.RIGHT, 100, 200);
    440 
    441         Resources res = mContext.getResources();
    442         XmlResourceParser parser = res.getXml(R.xml.scaledrawable);
    443         AttributeSet attrs = DrawableTestUtils.getAttributeSet(parser, "scale_allattrs");
    444         scaleDrawable.inflate(res, parser, attrs);
    445         final int bitmapSize = Math.round(48f * res.getDisplayMetrics().density);
    446         assertEquals(bitmapSize, scaleDrawable.getIntrinsicWidth());
    447         assertEquals(bitmapSize, scaleDrawable.getIntrinsicHeight());
    448 
    449         parser = res.getXml(R.xml.scaledrawable);
    450         attrs = DrawableTestUtils.getAttributeSet(parser, "scale_nodrawable");
    451         try {
    452             Drawable.createFromXmlInner(res, parser, attrs);
    453             fail("Should throw XmlPullParserException if missing drawable");
    454         } catch (XmlPullParserException e) {
    455         }
    456 
    457         try {
    458             Drawable.createFromXmlInner(null, parser, attrs);
    459             fail("Should throw NullPointerException if resource is null");
    460         } catch (NullPointerException e) {
    461         }
    462 
    463         try {
    464             Drawable.createFromXmlInner(res, null, attrs);
    465             fail("Should throw NullPointerException if parser is null");
    466         } catch (NullPointerException e) {
    467         }
    468 
    469         try {
    470             Drawable.createFromXmlInner(res, parser, null);
    471             fail("Should throw NullPointerException if attribute set is null");
    472         } catch (NullPointerException e) {
    473         }
    474     }
    475 
    476     @Test
    477     public void testMutate() {
    478         ScaleDrawable d1 = (ScaleDrawable) mContext.getDrawable(R.drawable.scaledrawable);
    479         ScaleDrawable d2 = (ScaleDrawable) mContext.getDrawable(R.drawable.scaledrawable);
    480         ScaleDrawable d3 = (ScaleDrawable) mContext.getDrawable(R.drawable.scaledrawable);
    481         int restoreAlpha = d1.getAlpha();
    482 
    483         try {
    484             // verify bad behavior - modify before mutate pollutes other drawables
    485             d1.setAlpha(100);
    486             assertEquals(100, ((BitmapDrawable) d1.getDrawable()).getPaint().getAlpha());
    487             assertEquals(100, ((BitmapDrawable) d2.getDrawable()).getPaint().getAlpha());
    488             assertEquals(100, ((BitmapDrawable) d3.getDrawable()).getPaint().getAlpha());
    489 
    490             d1.mutate();
    491             d1.setAlpha(200);
    492             assertEquals(200, ((BitmapDrawable) d1.getDrawable()).getPaint().getAlpha());
    493             assertEquals(100, ((BitmapDrawable) d2.getDrawable()).getPaint().getAlpha());
    494             assertEquals(100, ((BitmapDrawable) d3.getDrawable()).getPaint().getAlpha());
    495 
    496             d2.setAlpha(50);
    497             assertEquals(200, ((BitmapDrawable) d1.getDrawable()).getPaint().getAlpha());
    498             assertEquals(50, ((BitmapDrawable) d2.getDrawable()).getPaint().getAlpha());
    499             assertEquals(50, ((BitmapDrawable) d3.getDrawable()).getPaint().getAlpha());
    500         } finally {
    501             // restore externally visible state, since other tests may use the drawable
    502             mContext.getDrawable(R.drawable.scaledrawable).setAlpha(restoreAlpha);
    503         }
    504     }
    505 
    506     // Since Mockito can't mock or spy on protected methods, we have a custom extension
    507     // of Drawable to track calls to protected methods. This class also has empty implementations
    508     // of the base abstract methods.
    509     private static class MockDrawable extends Drawable {
    510         private boolean mCalledOnLevelChange = false;
    511 
    512         @Override
    513         public void draw(Canvas canvas) {
    514         }
    515 
    516         @Override
    517         public int getOpacity() {
    518             return 0;
    519         }
    520 
    521         @Override
    522         public void setAlpha(int alpha) {
    523         }
    524 
    525         @Override
    526         public void setColorFilter(ColorFilter cf) {
    527         }
    528 
    529         @Override
    530         protected boolean onLevelChange(int level) {
    531             mCalledOnLevelChange = true;
    532             return super.onLevelChange(level);
    533         }
    534 
    535         public boolean hasCalledOnLevelChange() {
    536             return mCalledOnLevelChange;
    537         }
    538 
    539         public void reset() {
    540             mCalledOnLevelChange = false;
    541         }
    542     }
    543 
    544     private static class MockScaleDrawable extends ScaleDrawable {
    545         private boolean mCalledOnBoundsChange = false;
    546 
    547         MockScaleDrawable() {
    548             super(null, Gravity.CENTER, 100, 200);
    549         }
    550 
    551         public MockScaleDrawable(Drawable drawable, int gravity,
    552                 float scaleWidth, float scaleHeight) {
    553             super(drawable, gravity, scaleWidth, scaleHeight);
    554         }
    555 
    556         @Override
    557         protected boolean onStateChange(int[] state) {
    558             return super.onStateChange(state);
    559         }
    560 
    561         @Override
    562         protected boolean onLevelChange(int level) {
    563             return super.onLevelChange(level);
    564         }
    565 
    566         @Override
    567         protected void onBoundsChange(Rect bounds) {
    568             mCalledOnBoundsChange = true;
    569             super.onBoundsChange(bounds);
    570         }
    571 
    572         public boolean hasCalledOnBoundsChange() {
    573             return mCalledOnBoundsChange;
    574         }
    575 
    576         public void reset() {
    577             mCalledOnBoundsChange = false;
    578         }
    579     }
    580 }
    581