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