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.content.res.cts;
     18 
     19 import static com.google.common.truth.Truth.assertThat;
     20 
     21 import android.content.cts.R;
     22 import android.content.cts.util.XmlUtils;
     23 import android.content.pm.ActivityInfo;
     24 import android.content.res.Resources;
     25 import android.content.res.TypedArray;
     26 import android.content.res.XmlResourceParser;
     27 import android.graphics.Typeface;
     28 import android.test.AndroidTestCase;
     29 import android.util.AttributeSet;
     30 import android.util.TypedValue;
     31 import android.util.Xml;
     32 import android.view.ContextThemeWrapper;
     33 
     34 import org.xmlpull.v1.XmlPullParser;
     35 import org.xmlpull.v1.XmlPullParserException;
     36 
     37 import java.io.IOException;
     38 
     39 public class TypedArrayTest extends AndroidTestCase {
     40     private static final int DEFINT = -1;
     41     private static final float DEFFLOAT = -1.0f;
     42     private static final int EXPECTED_COLOR = 0xff0000ff;
     43     private static final int EXPECTED_COLOR_STATE = 0xff00ff00;
     44     private static final float EXPECTED_DIMENSION = 0.75f;
     45     private static final int EXPECTED_PIXEL_OFFSET = 10;
     46     private static final int EXPECTED_LAYOUT_DIMENSION = 10;
     47     private static final int EXPECTED_PIXEL_SIZE = 18;
     48     private static final float EXPECTED_FLOAT = 3.14f;
     49     private static final float EXPECTED_FRACTION = 10.0f;
     50     private static final int EXPECTED_INT = 365;
     51     private static final String EXPECTED_STRING = "Hello, Android!";
     52     private static final String EXPECTED_TEXT = "TypedArray Test!";
     53     private static final String[] EXPECTED_TEXT_ARRAY = {"Easy", "Medium", "Hard"};
     54     private static final int EXPECTED_INDEX_COUNT = 19;
     55     private static final String EXPTECTED_POS_DESCRIP = "<internal>";
     56     private static final int EXPECTED_LENGTH = 20;
     57     private static final String EXPECTED_NON_RESOURCE_STRING = "testNonResourcesString";
     58     private static final String XML_BEGIN = "resources";
     59     private static final int EXPECTED_INT_ATT = 86400;
     60     private static final int EXPECTED_CHANGING_CONFIG = ActivityInfo.CONFIG_ORIENTATION;
     61 
     62     private TypedArray mTypedArray;
     63 
     64     @Override
     65     protected void setUp() throws Exception {
     66         super.setUp();
     67         mTypedArray = getContext().getTheme()
     68                 .obtainStyledAttributes(R.style.Whatever, R.styleable.style1);
     69     }
     70 
     71     @Override
     72     protected void tearDown() throws Exception {
     73         super.tearDown();
     74         mTypedArray.recycle();
     75     }
     76 
     77     public void testSourceResourceIdFromStyle() {
     78         final TypedArray t = getContext().getTheme().obtainStyledAttributes(
     79                 R.style.StyleA, R.styleable.style1);
     80 
     81         assertEquals(R.style.StyleA, t.getSourceResourceId(R.styleable.style1_type1, 0));
     82         assertEquals(R.style.StyleB, t.getSourceResourceId(R.styleable.style1_type2, 0));
     83         assertEquals(R.style.StyleC, t.getSourceResourceId(R.styleable.style1_type3, 0));
     84         assertEquals(R.style.StyleB, t.getSourceResourceId(R.styleable.style1_type4, 0));
     85         assertEquals(0, t.getSourceResourceId(R.styleable.style1_type5, 0));
     86         assertEquals(R.style.StyleA, t.getSourceResourceId(R.styleable.style1_type17, 0));
     87 
     88         t.recycle();
     89     }
     90 
     91     public void testSourceResourceIdFromLayout() throws Exception {
     92         XmlResourceParser parser =
     93                 getContext().getResources().getLayout(R.layout.source_style_layout);
     94 
     95         final AttributeSet attrs = Xml.asAttributeSet(parser);
     96 
     97         // Look for the root node.
     98         assertEquals(XmlPullParser.START_DOCUMENT, parser.next());
     99         assertEquals(XmlPullParser.START_TAG, parser.next());
    100 
    101         final TypedArray t = getContext().getTheme().obtainStyledAttributes(
    102                 attrs, R.styleable.style1, 0, 0);
    103         assertEquals(R.layout.source_style_layout,
    104                 t.getSourceResourceId(R.styleable.style1_type1, 0));
    105         assertEquals(R.style.StyleB, t.getSourceResourceId(R.styleable.style1_type2, 0));
    106         assertEquals(R.style.StyleC, t.getSourceResourceId(R.styleable.style1_type3, 0));
    107         assertEquals(R.style.StyleB, t.getSourceResourceId(R.styleable.style1_type4, 0));
    108         assertEquals(0, t.getSourceResourceId(R.styleable.style1_type5, 0));
    109         assertEquals(R.style.StyleA, t.getSourceResourceId(R.styleable.style1_type17, 0));
    110     }
    111 
    112     public void testGetType() {
    113         final TypedArray t = getContext().getTheme().obtainStyledAttributes(
    114                 R.style.Whatever, R.styleable.style1);
    115 
    116         assertEquals(TypedValue.TYPE_INT_BOOLEAN, t.getType(R.styleable.style1_type1));
    117         assertEquals(TypedValue.TYPE_INT_BOOLEAN, t.getType(R.styleable.style1_type2));
    118         assertEquals(TypedValue.TYPE_INT_COLOR_ARGB8, t.getType(R.styleable.style1_type3));
    119         assertEquals(TypedValue.TYPE_INT_COLOR_ARGB8, t.getType(R.styleable.style1_type4));
    120         assertEquals(TypedValue.TYPE_DIMENSION, t.getType(R.styleable.style1_type5));
    121         assertEquals(TypedValue.TYPE_DIMENSION, t.getType(R.styleable.style1_type6));
    122         assertEquals(TypedValue.TYPE_DIMENSION, t.getType(R.styleable.style1_type7));
    123         assertEquals(TypedValue.TYPE_STRING, t.getType(R.styleable.style1_type8));
    124         assertEquals(TypedValue.TYPE_FLOAT, t.getType(R.styleable.style1_type9));
    125         assertEquals(TypedValue.TYPE_FRACTION, t.getType(R.styleable.style1_type10));
    126         assertEquals(TypedValue.TYPE_INT_DEC, t.getType(R.styleable.style1_type11));
    127         assertEquals(TypedValue.TYPE_INT_DEC, t.getType(R.styleable.style1_type12));
    128         assertEquals(TypedValue.TYPE_STRING, t.getType(R.styleable.style1_type13));
    129         assertEquals(TypedValue.TYPE_STRING, t.getType(R.styleable.style1_type14));
    130         assertEquals(TypedValue.TYPE_REFERENCE, t.getType(R.styleable.style1_type15));
    131         assertEquals(TypedValue.TYPE_STRING, t.getType(R.styleable.style1_type16));
    132         assertEquals(TypedValue.TYPE_NULL, t.getType(R.styleable.style1_typeEmpty));
    133         assertEquals(TypedValue.TYPE_NULL, t.getType(R.styleable.style1_typeUndefined));
    134 
    135         t.recycle();
    136     }
    137 
    138     public void testBasics() {
    139         final TypedArray t = getContext().getTheme().obtainStyledAttributes(
    140                 R.style.Whatever, R.styleable.style1);
    141 
    142         assertEquals(EXPECTED_CHANGING_CONFIG, t.getChangingConfigurations());
    143         assertEquals(EXPECTED_INDEX_COUNT, t.getIndexCount());
    144         assertEquals(EXPTECTED_POS_DESCRIP, t.getPositionDescription());
    145         assertEquals(EXPECTED_LENGTH, t.length());
    146         assertEquals(getContext().getResources(), t.getResources());
    147         assertNotNull(t.toString());
    148 
    149         t.recycle();
    150     }
    151 
    152     public void testGetAttributes() {
    153         final TypedArray t = getContext().getTheme().obtainStyledAttributes(
    154                 R.style.Whatever, R.styleable.style1);
    155 
    156         assertTrue(t.getBoolean(R.styleable.style1_type1, false));
    157         assertFalse(t.getBoolean(R.styleable.style1_type2, true));
    158 
    159         assertEquals(EXPECTED_COLOR,
    160                 t.getColor(R.styleable.style1_type3, DEFINT));
    161         assertEquals(EXPECTED_COLOR_STATE,
    162                 t.getColorStateList(R.styleable.style1_type4).getDefaultColor());
    163 
    164         // This get values equals attribute dimension value set in styles.xml
    165         // multiplied by the appropriate metric, the metric is unknown.
    166         assertEquals(EXPECTED_DIMENSION,
    167                 t.getDimension(R.styleable.style1_type5, DEFFLOAT));
    168 
    169         assertEquals(EXPECTED_PIXEL_OFFSET,
    170                 t.getDimensionPixelOffset(R.styleable.style1_type6, DEFINT));
    171         assertEquals(EXPECTED_LAYOUT_DIMENSION,
    172                 t.getLayoutDimension(R.styleable.style1_type6, "type6"));
    173         assertEquals(EXPECTED_LAYOUT_DIMENSION,
    174                 t.getLayoutDimension(R.styleable.style1_type6, 0));
    175 
    176         assertEquals(EXPECTED_PIXEL_SIZE,
    177                 t.getDimensionPixelSize(R.styleable.style1_type7, DEFINT));
    178 
    179         assertNotNull(t.getDrawable(R.styleable.style1_type8));
    180         assertEquals(R.drawable.pass, t.getResourceId(R.styleable.style1_type8, DEFINT));
    181 
    182         assertEquals(EXPECTED_FLOAT,
    183                 t.getFloat(R.styleable.style1_type9, DEFFLOAT));
    184         assertEquals(EXPECTED_FRACTION,
    185                 t.getFraction(R.styleable.style1_type10, 10, 10, DEFFLOAT));
    186         assertEquals(EXPECTED_INT,
    187                 t.getInt(R.styleable.style1_type11, DEFINT));
    188         assertEquals(EXPECTED_INT_ATT,
    189                 t.getInteger(R.styleable.style1_type12, DEFINT));
    190 
    191         assertEquals(EXPECTED_STRING, t.getString(R.styleable.style1_type13));
    192         assertNull(t.getNonResourceString(R.styleable.style1_type14));
    193         assertEquals(EXPECTED_TEXT, t.getText(R.styleable.style1_type14));
    194 
    195         final CharSequence[] textArray = t.getTextArray(R.styleable.style1_type15);
    196         assertEquals(EXPECTED_TEXT_ARRAY[0], textArray[0]);
    197         assertEquals(EXPECTED_TEXT_ARRAY[1], textArray[1]);
    198         assertEquals(EXPECTED_TEXT_ARRAY[2], textArray[2]);
    199 
    200         // Verify that all the attributes retrieved are expected and present.
    201         final int[] actual_indices = new int[t.getIndexCount()];
    202         for (int idx = 0; idx < t.getIndexCount(); idx++) {
    203             final int attr_index = t.getIndex(idx);
    204             assertTrue(t.hasValueOrEmpty(attr_index));
    205             actual_indices[idx] = attr_index;
    206         }
    207 
    208         final Typeface font = t.getFont(R.styleable.style1_type18);
    209         assertEquals(mContext.getResources().getFont(R.font.sample_regular_font), font);
    210 
    211         // NOTE: order does not matter here.
    212         // R.styleable.style1_typeUndefined is not expected because TYPE_NULL values do not get
    213         // included in the index list.
    214         assertThat(actual_indices).asList().containsExactly(
    215                 R.styleable.style1_type1,
    216                 R.styleable.style1_type2,
    217                 R.styleable.style1_type3,
    218                 R.styleable.style1_type4,
    219                 R.styleable.style1_type5,
    220                 R.styleable.style1_type6,
    221                 R.styleable.style1_type7,
    222                 R.styleable.style1_type8,
    223                 R.styleable.style1_type9,
    224                 R.styleable.style1_type10,
    225                 R.styleable.style1_type11,
    226                 R.styleable.style1_type12,
    227                 R.styleable.style1_type13,
    228                 R.styleable.style1_type14,
    229                 R.styleable.style1_type15,
    230                 R.styleable.style1_type16,
    231                 R.styleable.style1_type17,
    232                 R.styleable.style1_type18,
    233                 R.styleable.style1_typeEmpty);
    234     }
    235 
    236     public void testPeekValue() {
    237         final TypedArray t = getContext().getTheme().obtainStyledAttributes(
    238                 R.style.Whatever, R.styleable.style1);
    239 
    240         final TypedValue v = t.peekValue(R.styleable.style1_type11);
    241         assertNotNull(v);
    242         assertEquals(TypedValue.TYPE_INT_DEC, v.type);
    243         assertEquals(EXPECTED_INT, v.data);
    244 
    245         t.recycle();
    246     }
    247 
    248     public void testHasValue() {
    249         final TypedArray t = getContext().getTheme().obtainStyledAttributes(
    250                 R.style.Whatever, R.styleable.style1);
    251 
    252         // hasValue()
    253         assertTrue(t.hasValue(R.styleable.style1_type16));
    254         assertFalse(t.hasValue(R.styleable.style1_typeEmpty));
    255         assertFalse(t.hasValue(R.styleable.style1_typeUndefined));
    256 
    257         // hasValueOrEmpty()
    258         assertTrue(t.hasValueOrEmpty(R.styleable.style1_type16));
    259         assertTrue(t.hasValueOrEmpty(R.styleable.style1_typeEmpty));
    260         assertFalse(t.hasValueOrEmpty(R.styleable.style1_typeUndefined));
    261 
    262         t.recycle();
    263     }
    264 
    265     public void testRecycle() {
    266         final ContextThemeWrapper contextThemeWrapper = new ContextThemeWrapper(getContext(), 0);
    267         contextThemeWrapper.setTheme(R.style.TextAppearance);
    268         final TypedArray test = contextThemeWrapper.getTheme().obtainStyledAttributes(
    269                 R.styleable.TextAppearance);
    270         test.recycle();
    271     }
    272 
    273     public void testNonResourceString() throws XmlPullParserException, IOException {
    274         final XmlResourceParser parser = getContext().getResources().getXml(R.xml.test_color);
    275         XmlUtils.beginDocument(parser, XML_BEGIN);
    276         final AttributeSet set = parser;
    277         assertEquals(1, set.getAttributeCount());
    278         final TypedArray ta = getContext().getResources().obtainAttributes(set,
    279                 com.android.internal.R.styleable.AndroidManifest);
    280         assertEquals(1, ta.getIndexCount());
    281         assertEquals(EXPECTED_NON_RESOURCE_STRING, ta.getNonResourceString(
    282                 com.android.internal.R.styleable.AndroidManifest_versionName));
    283         ta.recycle();
    284         parser.close();
    285     }
    286 
    287     public void testEmptyXmlAttributeDoesNotFallbackToTheme() throws Exception {
    288         final Resources resources = getContext().getResources();
    289         try (final XmlResourceParser parser = resources.getXml(R.xml.empty)) {
    290             XmlUtils.beginDocument(parser, "element");
    291             assertEquals(1, parser.getAttributeCount());
    292 
    293             final Resources.Theme theme = resources.newTheme();
    294             theme.applyStyle(R.style.Whatever, false);
    295 
    296             final TypedArray ta = theme.obtainStyledAttributes(parser, R.styleable.style1, 0, 0);
    297             try {
    298                 assertTrue(ta.hasValueOrEmpty(R.styleable.style1_type1));
    299                 assertEquals(TypedValue.TYPE_NULL, ta.getType(R.styleable.style1_type1));
    300             } finally {
    301                 ta.recycle();
    302             }
    303         }
    304     }
    305 }
    306