Home | History | Annotate | Download | only in cts
      1 /*
      2  * Copyright (C) 2016 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 org.xmlpull.v1.XmlPullParser;
     20 import org.xmlpull.v1.XmlPullParserException;
     21 
     22 import android.R.attr;
     23 import android.content.Context;
     24 import android.content.res.Resources;
     25 import android.content.res.XmlResourceParser;
     26 import android.graphics.Canvas;
     27 import android.graphics.ColorFilter;
     28 import android.graphics.cts.R;
     29 import android.graphics.drawable.Animatable;
     30 import android.graphics.drawable.Animatable2;
     31 import android.graphics.drawable.AnimatedStateListDrawable;
     32 import android.graphics.drawable.Drawable;
     33 import android.graphics.drawable.DrawableContainer.DrawableContainerState;
     34 import android.graphics.drawable.StateListDrawable;
     35 import android.test.InstrumentationTestCase;
     36 import android.util.StateSet;
     37 import android.util.Xml;
     38 
     39 import java.io.IOException;
     40 import java.util.Arrays;
     41 import java.util.HashSet;
     42 
     43 import static org.mockito.Mockito.mock;
     44 
     45 public class AnimatedStateListDrawableTest extends InstrumentationTestCase {
     46     private static final int[] STATE_EMPTY = new int[] { };
     47     private static final int[] STATE_FOCUSED = new int[] { attr.state_focused };
     48 
     49     private Context mContext;
     50     private Resources mResources;
     51 
     52     @Override
     53     protected void setUp() throws Exception {
     54         super.setUp();
     55 
     56         mContext = getInstrumentation().getTargetContext();
     57         mResources = mContext.getResources();
     58     }
     59 
     60     public void testStateListDrawable() {
     61         new AnimatedStateListDrawable();
     62 
     63         // Check the values set in the constructor
     64         assertNotNull(new AnimatedStateListDrawable().getConstantState());
     65     }
     66 
     67     public void testAddState() {
     68         AnimatedStateListDrawable asld = new AnimatedStateListDrawable();
     69         DrawableContainerState cs = (DrawableContainerState) asld.getConstantState();
     70         assertEquals(0, cs.getChildCount());
     71 
     72         try {
     73             asld.addState(StateSet.WILD_CARD, null, R.id.focused);
     74             fail("Expected IllegalArgumentException");
     75         } catch (IllegalArgumentException e) {
     76             // Expected.
     77         }
     78 
     79         Drawable unfocused = mock(Drawable.class);
     80         asld.addState(StateSet.WILD_CARD, unfocused, R.id.focused);
     81         assertEquals(1, cs.getChildCount());
     82 
     83         Drawable focused = mock(Drawable.class);
     84         asld.addState(STATE_FOCUSED, focused, R.id.unfocused);
     85         assertEquals(2, cs.getChildCount());
     86     }
     87 
     88     public void testAddTransition() {
     89         AnimatedStateListDrawable asld = new AnimatedStateListDrawable();
     90         DrawableContainerState cs = (DrawableContainerState) asld.getConstantState();
     91 
     92         Drawable focused = mock(Drawable.class);
     93         Drawable unfocused = mock(Drawable.class);
     94         asld.addState(STATE_FOCUSED, focused, R.id.focused);
     95         asld.addState(StateSet.WILD_CARD, unfocused, R.id.unfocused);
     96 
     97         try {
     98             asld.addTransition(R.id.focused, R.id.focused, null, false);
     99             fail("Expected IllegalArgumentException");
    100         } catch (IllegalArgumentException e) {
    101             // Expected.
    102         }
    103 
    104         MockTransition focusedToUnfocused = mock(MockTransition.class);
    105         asld.addTransition(R.id.focused, R.id.unfocused, focusedToUnfocused, false);
    106         assertEquals(3, cs.getChildCount());
    107 
    108         MockTransition unfocusedToFocused = mock(MockTransition.class);
    109         asld.addTransition(R.id.unfocused, R.id.focused, unfocusedToFocused, false);
    110         assertEquals(4, cs.getChildCount());
    111 
    112         MockTransition reversible = mock(MockTransition.class);
    113         asld.addTransition(R.id.focused, R.id.unfocused, reversible, true);
    114         assertEquals(5, cs.getChildCount());
    115     }
    116 
    117     public void testIsStateful() {
    118         assertTrue(new AnimatedStateListDrawable().isStateful());
    119     }
    120 
    121     public void testOnStateChange() {
    122         AnimatedStateListDrawable asld = new AnimatedStateListDrawable();
    123 
    124         Drawable focused = mock(Drawable.class);
    125         Drawable unfocused = mock(Drawable.class);
    126         asld.addState(STATE_FOCUSED, focused, R.id.focused);
    127         asld.addState(StateSet.WILD_CARD, unfocused, R.id.unfocused);
    128 
    129         MockTransition focusedToUnfocused = mock(MockTransition.class);
    130         MockTransition unfocusedToFocused = mock(MockTransition.class);
    131         asld.addTransition(R.id.focused, R.id.unfocused, focusedToUnfocused, false);
    132         asld.addTransition(R.id.unfocused, R.id.focused, unfocusedToFocused, false);
    133 
    134         asld.setState(STATE_EMPTY);
    135         assertSame(unfocused, asld.getCurrent());
    136 
    137         asld.setState(STATE_FOCUSED);
    138         assertSame(unfocusedToFocused, asld.getCurrent());
    139 
    140         asld.setState(STATE_FOCUSED);
    141         assertSame(unfocusedToFocused, asld.getCurrent());
    142     }
    143 
    144     public void testPreloadDensity() throws XmlPullParserException, IOException {
    145         runPreloadDensityTestForDrawable(
    146                 R.drawable.animated_state_list_density, false);
    147     }
    148 
    149     public void testPreloadDensityConstantSize() throws XmlPullParserException, IOException {
    150         runPreloadDensityTestForDrawable(
    151                 R.drawable.animated_state_list_density_constant_size, true);
    152     }
    153 
    154     private void runPreloadDensityTestForDrawable(int drawableResId, boolean isConstantSize)
    155             throws XmlPullParserException, IOException {
    156         final Resources res = mResources;
    157         final int densityDpi = res.getConfiguration().densityDpi;
    158         try {
    159             runPreloadDensityTestForDrawableInner(res, densityDpi, drawableResId, isConstantSize);
    160         } finally {
    161             DrawableTestUtils.setResourcesDensity(res, densityDpi);
    162         }
    163     }
    164 
    165     private void runPreloadDensityTestForDrawableInner(Resources res, int densityDpi,
    166             int drawableResId, boolean isConstantSize) throws XmlPullParserException, IOException {
    167         // Capture initial state at default density.
    168         final XmlResourceParser parser = getResourceParser(drawableResId);
    169         final AnimatedStateListDrawable asld = new AnimatedStateListDrawable();
    170         asld.inflate(res, parser, Xml.asAttributeSet(parser));
    171 
    172         final DrawableContainerState cs = (DrawableContainerState) asld.getConstantState();
    173         final int count = cs.getChildCount();
    174         final int[] origWidth = new int[count];
    175         int max = 0;
    176         for (int i = 0; i < count; i++) {
    177             final int width = cs.getChild(i).getIntrinsicWidth();
    178             max = Math.max(max, width);
    179             origWidth[i] = width;
    180         }
    181         if (isConstantSize) {
    182             Arrays.fill(origWidth, max);
    183         }
    184 
    185         // Set density to half of original.
    186         DrawableTestUtils.setResourcesDensity(res, densityDpi / 2);
    187         final StateListDrawable halfDrawable =
    188                 (StateListDrawable) cs.newDrawable(res);
    189         for (int i = 0; i < count; i++) {
    190             halfDrawable.selectDrawable(i);
    191             assertEquals(Math.round(origWidth[i] / 2f), halfDrawable.getIntrinsicWidth());
    192         }
    193 
    194         // Set density to double original.
    195         DrawableTestUtils.setResourcesDensity(res, densityDpi * 2);
    196         final StateListDrawable doubleDrawable =
    197                 (StateListDrawable) cs.newDrawable(res);
    198         for (int i = 0; i < count; i++) {
    199             doubleDrawable.selectDrawable(i);
    200             assertEquals(origWidth[i] * 2, doubleDrawable.getIntrinsicWidth());
    201         }
    202 
    203         // Restore original configuration and metrics.
    204         DrawableTestUtils.setResourcesDensity(res, densityDpi);
    205         final StateListDrawable origDrawable =
    206                 (StateListDrawable) cs.newDrawable(res);
    207         for (int i = 0; i < count; i++) {
    208             origDrawable.selectDrawable(i);
    209             assertEquals(origWidth[i], origDrawable.getIntrinsicWidth());
    210         }
    211     }
    212 
    213     private XmlResourceParser getResourceParser(int resId) throws XmlPullParserException,
    214             IOException {
    215         XmlResourceParser parser = getInstrumentation().getTargetContext().getResources().getXml(
    216                 resId);
    217         int type;
    218         while ((type = parser.next()) != XmlPullParser.START_TAG
    219                 && type != XmlPullParser.END_DOCUMENT) {
    220             // Empty loop
    221         }
    222         return parser;
    223     }
    224 
    225     public void testInflate() throws XmlPullParserException, IOException {
    226         AnimatedStateListDrawable asld = (AnimatedStateListDrawable) mContext.getDrawable(
    227                 R.drawable.animated_state_list_density);
    228         DrawableContainerState asldState = (DrawableContainerState) asld.getConstantState();
    229         assertTrue(asld.isVisible());
    230         assertFalse(asldState.isConstantSize());
    231         assertNull(asldState.getConstantPadding());
    232         assertEquals(4, asldState.getChildCount());
    233     }
    234 
    235     public abstract class MockTransition extends MockDrawable implements Animatable, Animatable2 {
    236         private HashSet<AnimationCallback> mCallbacks = new HashSet<>();
    237 
    238         @Override
    239         public void registerAnimationCallback(AnimationCallback callback) {
    240             mCallbacks.add(callback);
    241         }
    242 
    243         @Override
    244         public boolean unregisterAnimationCallback(AnimationCallback callback) {
    245             return mCallbacks.remove(callback);
    246         }
    247 
    248         @Override
    249         public void clearAnimationCallbacks() {
    250             mCallbacks.clear();
    251         }
    252     }
    253 
    254     public class MockDrawable extends Drawable {
    255         @Override
    256         public void draw(Canvas canvas) {
    257         }
    258 
    259         @Override
    260         public int getOpacity() {
    261             return 0;
    262         }
    263 
    264         @Override
    265         public void setAlpha(int alpha) {
    266         }
    267 
    268         @Override
    269         public void setColorFilter(ColorFilter cf) {
    270         }
    271     }
    272 }
    273