1 /*
2  * Copyright (C) 2009 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 com.android.cts.content.R;
20 
21 import org.xmlpull.v1.XmlPullParser;
22 import org.xmlpull.v1.XmlPullParserException;
23 
24 import android.content.Context;
25 import android.content.cts.util.XmlUtils;
26 import android.content.res.AssetManager;
27 import android.content.res.ColorStateList;
28 import android.content.res.Configuration;
29 import android.content.res.Resources;
30 import android.content.res.Resources.NotFoundException;
31 import android.content.res.TypedArray;
32 import android.content.res.XmlResourceParser;
33 import android.graphics.drawable.Drawable;
34 import android.os.Bundle;
35 import android.test.AndroidTestCase;
36 import android.util.AttributeSet;
37 import android.util.DisplayMetrics;
38 import android.util.TypedValue;
39 import android.util.Xml;
40 import android.view.Display;
41 import android.view.WindowManager;
42 
43 import java.io.IOException;
44 import java.io.InputStream;
45 import java.util.Locale;
46 
47 public class ResourcesTest extends AndroidTestCase {
48     private static final String CONFIG_VARYING = "configVarying";
49     private static final String SIMPLE = "simple";
50     private static final String CONFIG_VARYING_SIMPLE = "configVarying/simple";
51     private static final String PACKAGE_NAME = "com.android.cts.content";
52     private static final String COM_ANDROID_CTS_STUB_IDENTIFIER =
53                 "com.android.cts.content:configVarying/simple";
54     private Resources mResources;
55 
56     @Override
setUp()57     protected void setUp() throws Exception {
58         super.setUp();
59 
60         mResources = getContext().getResources();
61     }
62 
testResources()63     public void testResources() {
64         final AssetManager am = new AssetManager();
65         final Configuration cfg = new Configuration();
66         cfg.keyboard = Configuration.KEYBOARDHIDDEN_YES;
67         final DisplayMetrics dm = new DisplayMetrics();
68         dm.setToDefaults();
69 
70         final Resources r = new Resources(am, dm, cfg);
71         final Configuration c = r.getConfiguration();
72         assertEquals(Configuration.KEYBOARDHIDDEN_YES, c.keyboard);
73     }
74 
testGetString()75     public void testGetString() {
76         try {
77             mResources.getString(-1, "%s");
78             fail("Failed at testGetString2");
79         } catch (NotFoundException e) {
80           //expected
81         }
82 
83         final String strGo = mResources.getString(R.string.go, "%1$s%%", 12);
84         assertEquals("Go", strGo);
85     }
86 
testObtainAttributes()87     public void testObtainAttributes() throws XmlPullParserException, IOException {
88         final XmlPullParser parser = mResources.getXml(R.xml.test_color);
89         XmlUtils.beginDocument(parser, "resources");
90         final AttributeSet set = Xml.asAttributeSet(parser);
91         final TypedArray testTypedArray = mResources.obtainAttributes(set, R.styleable.Style1);
92         assertNotNull(testTypedArray);
93         assertEquals(2, testTypedArray.length());
94         assertEquals(0, testTypedArray.getColor(0, 0));
95         assertEquals(128, testTypedArray.getColor(1, 128));
96         assertEquals(mResources, testTypedArray.getResources());
97         testTypedArray.recycle();
98     }
99 
testObtainTypedArray()100     public void testObtainTypedArray() {
101         try {
102             mResources.obtainTypedArray(-1);
103             fail("Failed at testObtainTypedArray");
104         } catch (NotFoundException e) {
105             //expected
106         }
107 
108         final TypedArray ta = mResources.obtainTypedArray(R.array.string);
109         assertEquals(3, ta.length());
110         assertEquals("Test String 1", ta.getString(0));
111         assertEquals("Test String 2", ta.getString(1));
112         assertEquals("Test String 3", ta.getString(2));
113         assertEquals(mResources, ta.getResources());
114     }
115 
getResources(final Configuration config, final int mcc, final int mnc, final int touchscreen, final int keyboard, final int keysHidden, final int navigation, final int width, final int height)116     private Resources getResources(final Configuration config, final int mcc, final int mnc,
117             final int touchscreen, final int keyboard, final int keysHidden, final int navigation,
118             final int width, final int height) {
119         final AssetManager assmgr = new AssetManager();
120         assmgr.addAssetPath(mContext.getPackageResourcePath());
121         final DisplayMetrics metrics = new DisplayMetrics();
122         final WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
123         final Display d = wm.getDefaultDisplay();
124         d.getMetrics(metrics);
125         config.mcc = mcc;
126         config.mnc = mnc;
127         config.touchscreen = touchscreen;
128         config.keyboard = keyboard;
129         config.keyboardHidden = keysHidden;
130         config.navigation = navigation;
131         metrics.widthPixels = width;
132         metrics.heightPixels = height;
133         return new Resources(assmgr, metrics, config);
134     }
135 
checkGetText1(final Resources res, final int resId, final String expectedValue)136     private static void checkGetText1(final Resources res, final int resId,
137             final String expectedValue) {
138         final String actual = res.getText(resId).toString();
139         assertNotNull("Returned wrong configuration-based simple value: expected <nothing>, "
140                 + "got '" + actual + "' from resource 0x" + Integer.toHexString(resId),
141                 expectedValue);
142         assertEquals("Returned wrong configuration-based simple value: expected " + expectedValue
143                 + ", got '" + actual + "' from resource 0x" + Integer.toHexString(resId),
144                 expectedValue, actual);
145     }
146 
checkGetText2(final Resources res, final int resId, final String expectedValue)147     private static void checkGetText2(final Resources res, final int resId,
148             final String expectedValue) {
149         final String actual = res.getText(resId, null).toString();
150         assertNotNull("Returned wrong configuration-based simple value: expected <nothing>, "
151                 + "got '" + actual + "' from resource 0x" + Integer.toHexString(resId),
152                 expectedValue);
153         assertEquals("Returned wrong configuration-based simple value: expected " + expectedValue
154                 + ", got '" + actual + "' from resource 0x" + Integer.toHexString(resId),
155                 expectedValue, actual);
156     }
157 
testGetMovie()158     public void testGetMovie() {
159         try {
160             mResources.getMovie(-1);
161             fail("Failed at testGetMovie");
162         } catch (NotFoundException e) {
163             //expected
164         }
165     }
166 
testGetDimension()167     public void testGetDimension() {
168         try {
169             mResources.getDimension(-1);
170             fail("Failed at testGetDimension");
171         } catch (NotFoundException e) {
172             //expected
173         }
174 
175         // app_icon_size is 48px, as defined in cts/tests/res/values/resources_test.xml
176         final float dim = mResources.getDimension(R.dimen.app_icon_size);
177         assertEquals(48.0f, dim);
178     }
179 
testGetDimensionPixelOffset()180     public void testGetDimensionPixelOffset() {
181         try {
182             mResources.getDimensionPixelOffset(-1);
183             fail("Failed at testGetDimensionPixelOffset");
184         } catch (NotFoundException e) {
185             //expected
186         }
187 
188         // app_icon_size is 48px, as defined in cts/tests/res/values/resources_test.xml
189         final int dim = mResources.getDimensionPixelOffset(R.dimen.app_icon_size);
190         assertEquals(48, dim);
191     }
192 
testGetColorStateList()193     public void testGetColorStateList() {
194         try {
195             mResources.getColorStateList(-1);
196             fail("Failed at testGetColorStateList");
197         } catch (NotFoundException e) {
198             //expected
199         }
200 
201         final ColorStateList colorStateList = mResources.getColorStateList(R.color.color1);
202         final int[] focusedState = {android.R.attr.state_focused};
203         final int focusColor = colorStateList.getColorForState(focusedState, R.color.failColor);
204         assertEquals(mResources.getColor(R.color.testcolor1), focusColor);
205     }
206 
testGetColor()207     public void testGetColor() {
208         try {
209             mResources.getColor(-1);
210             fail("Failed at testGetColor");
211         } catch (NotFoundException e) {
212             //expected
213         }
214 
215         final int color = mResources.getColor(R.color.testcolor1);
216         assertEquals(0xff00ff00, color);
217     }
218 
testUpdateConfiguration()219     public void testUpdateConfiguration() {
220         final Configuration cfg = mResources.getConfiguration();
221         assertTrue(cfg.fontScale != 5);
222 
223         cfg.fontScale = 5;
224         mResources.updateConfiguration(cfg, null);
225         Configuration cfgNew = mResources.getConfiguration();
226         assertEquals(5.0f, cfgNew.fontScale, 0.001f);
227     }
228 
testGetDimensionPixelSize()229     public void testGetDimensionPixelSize() {
230         try {
231             mResources.getDimensionPixelSize(-1);
232             fail("Failed at testGetDimensionPixelSize");
233         } catch (NotFoundException e) {
234             //expected
235         }
236 
237         // app_icon_size is 48px, as defined in cts/tests/res/values/resources_test.xml
238         final int size = mResources.getDimensionPixelSize(R.dimen.app_icon_size);
239         assertEquals(48, size);
240     }
241 
testGetDrawable()242     public void testGetDrawable() {
243         try {
244             mResources.getDrawable(-1);
245             fail("Failed at testGetDrawable");
246         } catch (NotFoundException e) {
247             //expected
248         }
249 
250         // testimage is defined in cts/tests/res/drawable/testimage.jpg and measures 212px x 142px
251         final Drawable draw = mResources.getDrawable(R.drawable.testimage);
252         int targetDensity = mResources.getDisplayMetrics().densityDpi;
253         int defaultDensity = DisplayMetrics.DENSITY_DEFAULT;
254         assertNotNull(draw);
255         assertEquals(212 * targetDensity / defaultDensity, draw.getIntrinsicWidth(), 1);
256         assertEquals(142 * targetDensity / defaultDensity, draw.getIntrinsicHeight(), 1);
257     }
258 
testGetAnimation()259     public void testGetAnimation() throws Exception {
260         try {
261             mResources.getAnimation(-1);
262             fail("Failed at testGetAnimation");
263         } catch (NotFoundException e) {
264             //expected
265         }
266 
267         final XmlResourceParser ani = mResources.getAnimation(R.anim.anim_rotate);
268         assertNotNull(ani);
269         XmlUtils.beginDocument(ani, "rotate");
270         assertEquals(7, ani.getAttributeCount());
271         assertEquals("Binary XML file line #18", ani.getPositionDescription());
272         assertEquals("interpolator", ani.getAttributeName(0));
273         assertEquals("@17432582", ani.getAttributeValue(0));
274     }
275 
testGetQuantityString1()276     public void testGetQuantityString1() {
277         try {
278             mResources.getQuantityString(-1, 1, "");
279             fail("Failed at testGetQuantityString1");
280         } catch (NotFoundException e) {
281             //expected
282         }
283 
284         final String strGo = mResources.getQuantityString(R.plurals.plurals_test, 1, "");
285         assertEquals("A dog", strGo);
286     }
287 
testGetQuantityString2()288     public void testGetQuantityString2() {
289         try {
290             mResources.getQuantityString(-1, 1);
291             fail("Failed at testGetQuantityString2");
292         } catch (NotFoundException e) {
293             //expected
294         }
295 
296         final String strGo = mResources.getQuantityString(R.plurals.plurals_test, 1);
297         assertEquals("A dog", strGo);
298     }
299 
testGetInteger()300     public void testGetInteger() {
301         try {
302             mResources.getInteger(-1);
303             fail("Failed at testGetInteger");
304         } catch (NotFoundException e) {
305             //expected
306         }
307 
308         final int i = mResources.getInteger(R.integer.resource_test_int);
309         assertEquals(10, i);
310     }
311 
testGetValue()312     public void testGetValue() {
313         final TypedValue tv = new TypedValue();
314 
315         try {
316             mResources.getValue("null", tv, false);
317             fail("Failed at testGetValue");
318         } catch (NotFoundException e) {
319             //expected
320         }
321 
322         mResources.getValue("com.android.cts.content:raw/text", tv, false);
323         assertNotNull(tv);
324         assertEquals("res/raw/text.txt", tv.coerceToString());
325     }
326 
testGetAssets()327     public void testGetAssets() {
328         final AssetManager aM = mResources.getAssets();
329         assertNotNull(aM);
330         assertTrue(aM.isUpToDate());
331     }
332 
testGetSystem()333     public void testGetSystem() {
334         assertNotNull(Resources.getSystem());
335     }
336 
testGetLayout()337     public void testGetLayout() throws Exception {
338         try {
339             mResources.getLayout(-1);
340             fail("Failed at testGetLayout");
341         } catch (NotFoundException e) {
342             //expected
343         }
344 
345         final XmlResourceParser layout = mResources.getLayout(R.layout.abslistview_layout);
346         assertNotNull(layout);
347         XmlUtils.beginDocument(layout, "ViewGroup_Layout");
348         assertEquals(3, layout.getAttributeCount());
349         assertEquals("id", layout.getAttributeName(0));
350         assertEquals("@" + R.id.abslistview_root, layout.getAttributeValue(0));
351     }
352 
testGetBoolean()353     public void testGetBoolean() {
354         try {
355             mResources.getBoolean(-1);
356             fail("Failed at testGetBoolean");
357         } catch (NotFoundException e) {
358             //expected
359         }
360 
361         final boolean b = mResources.getBoolean(R.integer.resource_test_int);
362         assertTrue(b);
363     }
364 
testgetFraction()365     public void testgetFraction() {
366         assertEquals(1, (int)mResources.getFraction(R.dimen.frac100perc, 1, 1));
367         assertEquals(100, (int)mResources.getFraction(R.dimen.frac100perc, 100, 1));
368     }
369 
testParseBundleExtras()370     public void testParseBundleExtras() throws XmlPullParserException, IOException {
371         final Bundle b = new Bundle();
372         XmlResourceParser parser = mResources.getXml(R.xml.extra);
373         XmlUtils.beginDocument(parser, "tag");
374 
375         assertEquals(0, b.size());
376         mResources.parseBundleExtras(parser, b);
377         assertEquals(1, b.size());
378         assertEquals("android", b.getString("google"));
379     }
380 
testParseBundleExtra()381     public void testParseBundleExtra() throws XmlPullParserException, IOException {
382         final Bundle b = new Bundle();
383         XmlResourceParser parser = mResources.getXml(R.xml.extra);
384 
385         XmlUtils.beginDocument(parser, "tag");
386         assertEquals(0, b.size());
387         mResources.parseBundleExtra("test", parser, b);
388         assertEquals(1, b.size());
389         assertEquals("Lee", b.getString("Bruce"));
390     }
391 
testGetIdentifier()392     public void testGetIdentifier() {
393 
394         int resid = mResources.getIdentifier(COM_ANDROID_CTS_STUB_IDENTIFIER, null, null);
395         assertEquals(R.configVarying.simple, resid);
396 
397         resid = mResources.getIdentifier(CONFIG_VARYING_SIMPLE, null, PACKAGE_NAME);
398         assertEquals(R.configVarying.simple, resid);
399 
400         resid = mResources.getIdentifier(SIMPLE, CONFIG_VARYING, PACKAGE_NAME);
401         assertEquals(R.configVarying.simple, resid);
402     }
403 
testGetIntArray()404     public void testGetIntArray() {
405         final int NO_EXIST_ID = -1;
406         try {
407             mResources.getIntArray(NO_EXIST_ID);
408             fail("should throw out NotFoundException");
409         } catch (NotFoundException e) {
410             // expected
411         }
412         // expected value is defined in res/value/arrays.xml
413         final int[] expectedArray1 = new int[] {
414                 0, 0, 0
415         };
416         final int[] expectedArray2 = new int[] {
417                 0, 1, 101
418         };
419         int[]array1 = mResources.getIntArray(R.array.strings);
420         int[]array2 = mResources.getIntArray(R.array.integers);
421 
422         checkArrayEqual(expectedArray1, array1);
423         checkArrayEqual(expectedArray2, array2);
424 
425     }
426 
checkArrayEqual(int[] array1, int[] array2)427     private void checkArrayEqual(int[] array1, int[] array2) {
428         assertNotNull(array2);
429         assertEquals(array1.length, array2.length);
430         for (int i = 0; i < array1.length; i++) {
431             assertEquals(array1[i], array2[i]);
432         }
433     }
434 
testGetQuantityText()435     public void testGetQuantityText() {
436         CharSequence cs;
437         final Resources res = resourcesForLanguage("cs");
438 
439         cs = res.getQuantityText(R.plurals.plurals_test, 0);
440         assertEquals("Some Czech dogs", cs.toString());
441 
442         cs = res.getQuantityText(R.plurals.plurals_test, 1);
443         assertEquals("A Czech dog", cs.toString());
444 
445         cs = res.getQuantityText(R.plurals.plurals_test, 2);
446         assertEquals("Few Czech dogs", cs.toString());
447 
448         cs = res.getQuantityText(R.plurals.plurals_test, 5);
449         assertEquals("Some Czech dogs", cs.toString());
450 
451         cs = res.getQuantityText(R.plurals.plurals_test, 500);
452         assertEquals("Some Czech dogs", cs.toString());
453 
454     }
455 
resourcesForLanguage(final String lang)456     private Resources resourcesForLanguage(final String lang) {
457         final Configuration config = new Configuration();
458         config.updateFrom(mResources.getConfiguration());
459         config.locale = new Locale(lang);
460         return new Resources(mResources.getAssets(), mResources.getDisplayMetrics(), config);
461     }
462 
testGetResourceEntryName()463     public void testGetResourceEntryName() {
464         assertEquals(SIMPLE, mResources.getResourceEntryName(R.configVarying.simple));
465     }
466 
testGetResourceName()467     public void testGetResourceName() {
468         final String fullName = mResources.getResourceName(R.configVarying.simple);
469         assertEquals(COM_ANDROID_CTS_STUB_IDENTIFIER, fullName);
470 
471         final String packageName = mResources.getResourcePackageName(R.configVarying.simple);
472         assertEquals(PACKAGE_NAME, packageName);
473 
474         final String typeName = mResources.getResourceTypeName(R.configVarying.simple);
475         assertEquals(CONFIG_VARYING, typeName);
476     }
477 
testGetStringWithIntParam()478     public void testGetStringWithIntParam() {
479         checkString(R.string.formattedStringNone,
480                 mResources.getString(R.string.formattedStringNone),
481                 "Format[]");
482         checkString(R.string.formattedStringOne,
483                 mResources.getString(R.string.formattedStringOne),
484                 "Format[%d]");
485         checkString(R.string.formattedStringTwo, mResources.getString(R.string.formattedStringTwo),
486                 "Format[%3$d,%2$s]");
487         // Make sure the formatted one works
488         checkString(R.string.formattedStringNone,
489                 mResources.getString(R.string.formattedStringNone),
490                 "Format[]");
491         checkString(R.string.formattedStringOne,
492                 mResources.getString(R.string.formattedStringOne, 42),
493                 "Format[42]");
494         checkString(R.string.formattedStringTwo,
495                 mResources.getString(R.string.formattedStringTwo, "unused", "hi", 43),
496                 "Format[43,hi]");
497     }
498 
checkString(final int resid, final String actual, final String expected)499     private static void checkString(final int resid, final String actual, final String expected) {
500         assertEquals("Expecting string value \"" + expected + "\" got \""
501                 + actual + "\" in resources 0x" + Integer.toHexString(resid),
502                 expected, actual);
503     }
504 
testGetStringArray()505     public void testGetStringArray() {
506         checkStringArray(R.array.strings, new String[] {
507                 "zero", "1", "here"
508         });
509         checkTextArray(R.array.strings, new String[] {
510                 "zero", "1", "here"
511         });
512         checkStringArray(R.array.integers, new String[] {
513                 null, null, null
514         });
515         checkTextArray(R.array.integers, new String[] {
516                 null, null, null
517         });
518     }
519 
checkStringArray(final int resid, final String[] expected)520     private void checkStringArray(final int resid, final String[] expected) {
521         final String[] res = mResources.getStringArray(resid);
522         assertEquals(res.length, expected.length);
523         for (int i = 0; i < expected.length; i++) {
524             checkEntry(resid, i, res[i], expected[i]);
525         }
526     }
527 
checkEntry(final int resid, final int index, final Object res, final Object expected)528     private void checkEntry(final int resid, final int index, final Object res,
529             final Object expected) {
530         assertEquals("in resource 0x" + Integer.toHexString(resid)
531                 + " at index " + index, expected, res);
532     }
533 
checkTextArray(final int resid, final String[] expected)534     private void checkTextArray(final int resid, final String[] expected) {
535         final CharSequence[] res = mResources.getTextArray(resid);
536         assertEquals(res.length, expected.length);
537         for (int i = 0; i < expected.length; i++) {
538             checkEntry(resid, i, res[i], expected[i]);
539         }
540     }
541 
testGetValueWithID()542     public void testGetValueWithID() {
543         tryBoolean(R.bool.trueRes, true);
544         tryBoolean(R.bool.falseRes, false);
545 
546         tryString(R.string.coerceIntegerToString, "100");
547         tryString(R.string.coerceBooleanToString, "true");
548         tryString(R.string.coerceColorToString, "#fff");
549         tryString(R.string.coerceFloatToString, "100.0");
550         tryString(R.string.coerceDimensionToString, "100px");
551         tryString(R.string.coerceFractionToString, "100%");
552     }
553 
tryBoolean(final int resid, final boolean expected)554     private void tryBoolean(final int resid, final boolean expected) {
555         final TypedValue v = new TypedValue();
556         mContext.getResources().getValue(resid, v, true);
557         assertEquals(TypedValue.TYPE_INT_BOOLEAN, v.type);
558         assertEquals("Expecting boolean value " + expected + " got " + v
559                 + " from TypedValue: in resource 0x" + Integer.toHexString(resid),
560                 expected, v.data != 0);
561         assertEquals("Expecting boolean value " + expected + " got " + v
562                 + " from getBoolean(): in resource 0x" + Integer.toHexString(resid),
563                 expected, mContext.getResources().getBoolean(resid));
564     }
565 
tryString(final int resid, final String expected)566     private void tryString(final int resid, final String expected) {
567         final TypedValue v = new TypedValue();
568         mContext.getResources().getValue(resid, v, true);
569         assertEquals(TypedValue.TYPE_STRING, v.type);
570         assertEquals("Expecting string value " + expected + " got " + v
571                 + ": in resource 0x" + Integer.toHexString(resid),
572                 expected, v.string);
573     }
574 
testRawResource()575     public void testRawResource() throws Exception {
576         assertNotNull(mResources.newTheme());
577 
578         InputStream is = mResources.openRawResource(R.raw.text);
579         verifyTextAsset(is);
580 
581         is = mResources.openRawResource(R.raw.text, new TypedValue());
582         verifyTextAsset(is);
583 
584         assertNotNull(mResources.openRawResourceFd(R.raw.text));
585     }
586 
verifyTextAsset(final InputStream is)587     static void verifyTextAsset(final InputStream is) throws IOException {
588         final String expectedString = "OneTwoThreeFourFiveSixSevenEightNineTen";
589         final byte[] buffer = new byte[10];
590 
591         int readCount;
592         int curIndex = 0;
593         while ((readCount = is.read(buffer, 0, buffer.length)) > 0) {
594             for (int i = 0; i < readCount; i++) {
595                 assertEquals("At index " + curIndex
596                             + " expected " + expectedString.charAt(curIndex)
597                             + " but found " + ((char) buffer[i]),
598                         buffer[i], expectedString.charAt(curIndex));
599                 curIndex++;
600             }
601         }
602 
603         readCount = is.read(buffer, 0, buffer.length);
604         assertEquals("Reading end of buffer: expected readCount=-1 but got " + readCount,
605                 -1, readCount);
606 
607         readCount = is.read(buffer, buffer.length, 0);
608         assertEquals("Reading end of buffer length 0: expected readCount=0 but got " + readCount,
609                 0, readCount);
610 
611         is.close();
612     }
613 }
614