Home | History | Annotate | Download | only in cts
      1 /*
      2  * Copyright (C) 2017 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.assertTrue;
     23 
     24 import android.content.Context;
     25 import android.content.res.ColorStateList;
     26 import android.content.res.Resources;
     27 import android.graphics.Bitmap;
     28 import android.graphics.Bitmap.Config;
     29 import android.graphics.BitmapFactory;
     30 import android.graphics.NinePatch;
     31 import android.graphics.Picture;
     32 import android.graphics.cts.R;
     33 import android.graphics.drawable.BitmapDrawable;
     34 import android.graphics.drawable.ColorDrawable;
     35 import android.graphics.drawable.Drawable;
     36 import android.graphics.drawable.DrawableContainer;
     37 import android.graphics.drawable.DrawableContainer.DrawableContainerState;
     38 import android.graphics.drawable.GradientDrawable;
     39 import android.graphics.drawable.LevelListDrawable;
     40 import android.graphics.drawable.NinePatchDrawable;
     41 import android.graphics.drawable.PaintDrawable;
     42 import android.graphics.drawable.PictureDrawable;
     43 import android.graphics.drawable.RippleDrawable;
     44 import android.graphics.drawable.ShapeDrawable;
     45 import android.graphics.drawable.StateListDrawable;
     46 import android.graphics.drawable.shapes.RectShape;
     47 import android.support.test.InstrumentationRegistry;
     48 import android.support.test.annotation.UiThreadTest;
     49 import android.support.test.filters.SmallTest;
     50 import android.support.test.runner.AndroidJUnit4;
     51 import android.util.StateSet;
     52 
     53 import org.junit.Before;
     54 import org.junit.Test;
     55 import org.junit.runner.RunWith;
     56 
     57 @SmallTest
     58 @RunWith(AndroidJUnit4.class)
     59 public class DefaultFocusHighlightTest {
     60 
     61     // The target context.
     62     private Context mContext;
     63 
     64     @Before
     65     public void setup() {
     66         mContext = InstrumentationRegistry.getTargetContext();
     67     }
     68 
     69     private static final int A_COLOR = 0x920424;
     70     private static final int[] NO_STATE_FOCUSED = new int[] { android.R.attr.state_enabled };
     71     private static final int[] ONLY_STATE_FOCUSED = new int[] { android.R.attr.state_focused };
     72     private static final int[] STATE_FOCUSED_WITH_POS =
     73             new int[] { android.R.attr.state_focused, android.R.attr.state_hovered };
     74     private static final int[] STATE_FOCUSED_WITH_NEG =
     75             new int[] { android.R.attr.state_focused,  -android.R.attr.state_hovered };
     76     private static final int[] STATE_FOCUSED_WITH_ENABLED =
     77             new int[] { android.R.attr.state_focused, android.R.attr.state_enabled };
     78 
     79     final static int[] FOCUSED_STATE =
     80             new int[] { android.R.attr.state_focused, android.R.attr.state_enabled };
     81 
     82     @UiThreadTest
     83     @Test
     84     public void testStateListDrawable() {
     85         Drawable d;
     86         // Empty state spec
     87         d = DrawableFactory.createStateListDrawable(
     88                 new int[][] {}
     89             );
     90         d.setState(FOCUSED_STATE);
     91         assertFalse(d.hasFocusStateSpecified());
     92 
     93         // Wild card
     94         d = DrawableFactory.createStateListDrawable(
     95                 new int[][] { StateSet.WILD_CARD }
     96             );
     97         d.setState(FOCUSED_STATE);
     98         assertFalse(d.hasFocusStateSpecified());
     99 
    100         // No state spec of state_focused=true
    101         d = DrawableFactory.createStateListDrawable(
    102                 new int[][] { NO_STATE_FOCUSED }
    103             );
    104         d.setState(FOCUSED_STATE);
    105         assertFalse(d.hasFocusStateSpecified());
    106 
    107         // One state spec of only state_focused=true
    108         d = DrawableFactory.createStateListDrawable(
    109                 new int[][] { ONLY_STATE_FOCUSED }
    110             );
    111         d.setState(FOCUSED_STATE);
    112         assertTrue(d.hasFocusStateSpecified());
    113 
    114         // One state spec of state_focused=true and something=true, but no state spec of
    115         // state_focused=true and something=false (something is not enabled)
    116         d = DrawableFactory.createStateListDrawable(
    117                 new int[][] { STATE_FOCUSED_WITH_POS }
    118             );
    119         d.setState(FOCUSED_STATE);
    120         assertTrue(d.hasFocusStateSpecified());
    121 
    122         // One state spec of state_focused=true and something=true, and one spec of
    123         // state_focused=true and something=false (something is not enabled)
    124         d = DrawableFactory.createStateListDrawable(
    125             new int[][] { STATE_FOCUSED_WITH_POS, STATE_FOCUSED_WITH_NEG }
    126         );
    127         d.setState(FOCUSED_STATE);
    128         assertTrue(d.hasFocusStateSpecified());
    129 
    130         // One state spec of state_focused=true and enabled=true
    131         d = DrawableFactory.createStateListDrawable(
    132             new int[][] { STATE_FOCUSED_WITH_ENABLED }
    133         );
    134         d.setState(FOCUSED_STATE);
    135         assertTrue(d.hasFocusStateSpecified());
    136     }
    137 
    138     @UiThreadTest
    139     @Test
    140     public void testRippleDrawable() {
    141         Drawable d = DrawableFactory.createRippleDrawable();
    142         d.setState(FOCUSED_STATE);
    143         assertTrue(d.hasFocusStateSpecified());
    144     }
    145 
    146     @UiThreadTest
    147     @Test
    148     public void testPictureDrawable() {
    149         Drawable d = DrawableFactory.createPictureDrawable(null);
    150         d.setState(FOCUSED_STATE);
    151         assertFalse(d.hasFocusStateSpecified());
    152 
    153         d = DrawableFactory.createPictureDrawable(new Picture());
    154         d.setState(FOCUSED_STATE);
    155         assertFalse(d.hasFocusStateSpecified());
    156     }
    157 
    158     @UiThreadTest
    159     @Test
    160     public void testColorStateListHandledDrawable() {
    161         final Drawable[] drawables = new Drawable[] {
    162             DrawableFactory.createShapeDrawable(),
    163             DrawableFactory.createPaintDrawable(),
    164             DrawableFactory.createBitmapDrawable(mContext),
    165             DrawableFactory.createColorDrawable(),
    166             DrawableFactory.createGradientDrawable(),
    167             DrawableFactory.createNinePatchDrawable(mContext),
    168         };
    169         final ColorStateList[] stateLists = new ColorStateList[] {
    170             // Empty state spec
    171             new ColorStateList(
    172                 new int[][] {  },
    173                 new int[] {  }),
    174             // Wild card
    175             new ColorStateList(
    176                 new int[][] { StateSet.WILD_CARD },
    177                 new int[] { A_COLOR }),
    178             // No state spec of state_focused=true
    179             new ColorStateList(
    180                 new int[][] { NO_STATE_FOCUSED },
    181                 new int[] { A_COLOR }),
    182             // One state spec of only state_focused=true
    183             new ColorStateList(
    184                 new int[][] { ONLY_STATE_FOCUSED },
    185                 new int[] { A_COLOR }),
    186             // One state spec of state_focused=true and something=true,
    187             // but no state spec of state_focused=true and something=false
    188             new ColorStateList(
    189                 new int[][] { STATE_FOCUSED_WITH_POS },
    190                 new int[] { A_COLOR }),
    191             // One state spec of state_focused=true and something=true,
    192             // and one spec of state_focused=true and something=false
    193             new ColorStateList(
    194                 new int[][] { STATE_FOCUSED_WITH_POS, STATE_FOCUSED_WITH_NEG },
    195                 new int[] { A_COLOR, A_COLOR }),
    196         };
    197         final boolean[] expectedResults = new boolean[] {
    198             // Empty state spec
    199             false,
    200             // Wild card
    201             false,
    202             // No state spec of state_focused=true
    203             false,
    204             // One state spec of only state_focused=true
    205             true,
    206             // One state spec of state_focused=true and something=true,
    207             // but no state spec of state_focused=true and something=false
    208             true,
    209             // One state spec of state_focused=true and something=true,
    210             // and one spec of state_focused=true and something=false
    211             true
    212         };
    213         assertEquals(stateLists.length, expectedResults.length);
    214         for (Drawable drawable : drawables) {
    215             // No ColorStateList set
    216             String drawableName = drawable.getClass().toString();
    217             String errorMsg = "[" + drawableName + "] Testing no ColorStateList failed.";
    218             drawable.setState(FOCUSED_STATE);
    219             assertFalse(errorMsg, drawable.hasFocusStateSpecified());
    220             // With ColorStateList set
    221             for (int i = 0; i < stateLists.length; i++) {
    222                 ColorStateList stateList = stateLists[i];
    223                 boolean expectedResult = expectedResults[i];
    224                 drawable.setTintList(stateList);
    225                 errorMsg = "[" + drawableName + "] Testing ColorStateList No." + i + " failed.";
    226 
    227                 drawable.setState(FOCUSED_STATE);
    228                 if (expectedResult) {
    229                     assertTrue(errorMsg, drawable.hasFocusStateSpecified());
    230                 } else {
    231                     assertFalse(errorMsg, drawable.hasFocusStateSpecified());
    232                 }
    233             }
    234         }
    235     }
    236 
    237     @UiThreadTest
    238     @Test
    239     public void testDrawableContainer() {
    240         MockDrawableContainer container;
    241         DrawableContainerState containerState;
    242 
    243         // Empty
    244         container = new MockDrawableContainer();
    245         containerState = (DrawableContainerState) new LevelListDrawable().getConstantState();
    246         assertNotNull(containerState);
    247         container.setConstantState(containerState);
    248         container.setState(FOCUSED_STATE);
    249         assertFalse(container.hasFocusStateSpecified());
    250 
    251         // No drawable of state_focused=true
    252         container = new MockDrawableContainer();
    253         containerState = (DrawableContainerState) new LevelListDrawable().getConstantState();
    254         assertNotNull(containerState);
    255         container.setConstantState(containerState);
    256         containerState.addChild(DrawableFactory.createPaintDrawable());
    257         containerState.addChild(DrawableFactory.createBitmapDrawable(mContext));
    258         containerState.addChild(DrawableFactory.createColorDrawable());
    259         container.selectDrawable(0);
    260         container.setState(FOCUSED_STATE);
    261         assertFalse(container.hasFocusStateSpecified());
    262         container.selectDrawable(1);
    263         container.setState(FOCUSED_STATE);
    264         assertFalse(container.hasFocusStateSpecified());
    265         container.selectDrawable(2);
    266         container.setState(FOCUSED_STATE);
    267         assertFalse(container.hasFocusStateSpecified());
    268 
    269         // Only drawables of state_focused=true
    270         container = new MockDrawableContainer();
    271         containerState = (DrawableContainerState) new LevelListDrawable().getConstantState();
    272         assertNotNull(containerState);
    273         container.setConstantState(containerState);
    274         containerState.addChild(DrawableFactory.createRippleDrawable());
    275         containerState.addChild(
    276             DrawableFactory.createStateListDrawable(
    277                 new int[][] { STATE_FOCUSED_WITH_POS, STATE_FOCUSED_WITH_NEG }
    278             )
    279         );
    280         container.selectDrawable(0);
    281         container.setState(FOCUSED_STATE);
    282         assertTrue(container.hasFocusStateSpecified());
    283         container.selectDrawable(1);
    284         container.setState(FOCUSED_STATE);
    285         assertTrue(container.hasFocusStateSpecified());
    286 
    287         // Both drawables of state_focused=true and state_focused=false
    288         containerState.addChild(DrawableFactory.createColorDrawable());
    289         container.selectDrawable(2);
    290         container.setState(FOCUSED_STATE);
    291         assertFalse(container.hasFocusStateSpecified());
    292         container.selectDrawable(1);
    293         container.setState(FOCUSED_STATE);
    294         assertTrue(container.hasFocusStateSpecified());
    295         container.selectDrawable(0);
    296         container.setState(FOCUSED_STATE);
    297         assertTrue(container.hasFocusStateSpecified());
    298     }
    299 
    300     static class DrawableFactory {
    301         static ShapeDrawable createShapeDrawable() {
    302             return new ShapeDrawable(new RectShape());
    303         }
    304         static PaintDrawable createPaintDrawable() {
    305             PaintDrawable paintDrawable = new PaintDrawable();
    306             paintDrawable.setCornerRadius(1.5f);
    307             return paintDrawable;
    308         }
    309         static BitmapDrawable createBitmapDrawable(Context context) {
    310             Bitmap bitmap = Bitmap.createBitmap(200, 300, Config.ARGB_8888);
    311             BitmapDrawable bitmapDrawable = new BitmapDrawable(context.getResources(), bitmap);
    312             return bitmapDrawable;
    313         }
    314         static ColorDrawable createColorDrawable() {
    315             return new ColorDrawable(A_COLOR);
    316         }
    317         static GradientDrawable createGradientDrawable() {
    318             GradientDrawable gradientDrawable = new GradientDrawable();
    319             gradientDrawable.setColor(A_COLOR);
    320             gradientDrawable.setCornerRadius(10f);
    321             return gradientDrawable;
    322         }
    323         static NinePatchDrawable createNinePatchDrawable(Context context) {
    324             Resources res = context.getResources();
    325             Bitmap bitmap = BitmapFactory.decodeResource(res, R.drawable.ninepatch_0);
    326             NinePatch np = new NinePatch(bitmap, bitmap.getNinePatchChunk(), null);
    327             NinePatchDrawable ninePatchDrawable = new NinePatchDrawable(res, np);
    328             return ninePatchDrawable;
    329         }
    330         static RippleDrawable createRippleDrawable() {
    331             RippleDrawable rippleDrawable =
    332                     new RippleDrawable(ColorStateList.valueOf(A_COLOR), null, null);
    333             return rippleDrawable;
    334         }
    335         static PictureDrawable createPictureDrawable(Picture picture) {
    336             PictureDrawable pictureDrawable = new PictureDrawable(picture);
    337             return pictureDrawable;
    338         }
    339         static StateListDrawable createStateListDrawable(int[][] stateList) {
    340             StateListDrawable drawable = new StateListDrawable();
    341             ColorDrawable colorDrawable = DrawableFactory.createColorDrawable();
    342             for (int i = 0; i < stateList.length; i++) {
    343                 drawable.addState(stateList[i], colorDrawable);
    344             }
    345             return drawable;
    346         }
    347     }
    348 
    349     // We're calling protected methods in DrawableContainer.
    350     // So we have to extend it here to make it accessible.
    351     private class MockDrawableContainer extends DrawableContainer {
    352         @Override
    353         protected void setConstantState(DrawableContainerState state) {
    354             super.setConstantState(state);
    355         }
    356     }
    357 
    358 }
    359