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 static org.junit.Assert.assertEquals;
20 import static org.junit.Assert.assertNotNull;
21 import static org.junit.Assert.assertNull;
22 import static org.junit.Assert.assertTrue;
23 import static org.junit.Assert.fail;
24 import static org.junit.Assume.assumeTrue;
25 
26 import android.content.Context;
27 import android.content.cts.R;
28 import android.content.pm.ApplicationInfo;
29 import android.content.pm.PackageManager;
30 import android.content.pm.PackageManager.NameNotFoundException;
31 import android.content.res.AssetManager;
32 import android.content.res.Configuration;
33 import android.content.res.Resources;
34 import android.content.res.Resources.NotFoundException;
35 import android.content.res.TypedArray;
36 import android.platform.test.annotations.AppModeSdkSandbox;
37 import android.util.DisplayMetrics;
38 
39 import androidx.test.InstrumentationRegistry;
40 import androidx.test.runner.AndroidJUnit4;
41 
42 import org.junit.Before;
43 import org.junit.Test;
44 import org.junit.runner.RunWith;
45 
46 import java.util.ArrayList;
47 import java.util.List;
48 import java.util.Locale;
49 
50 @AppModeSdkSandbox(reason = "Allow test in the SDK sandbox (does not prevent other modes).")
51 @RunWith(AndroidJUnit4.class)
52 public class ConfigTest {
53     private static final String TEST_PACKAGE = "android.content.cts";
54 
55     private Context mContext;
56     private int mTargetSdkVersion;
57 
58     enum Properties {
59         LANGUAGE,
60         COUNTRY,
61         SCRIPT,
62         VARIANT,
63         GRAMMATICAL_GENDER,
64         MCC,
65         MNC,
66         TOUCHSCREEN,
67         KEYBOARD,
68         KEYBOARDHIDDEN,
69         NAVIGATION,
70         ORIENTATION,
71         COLOR_MODE,
72         WIDTH,
73         HEIGHT,
74         DENSITY,
75         SCREENLAYOUT,
76         SWIDTH_DP,
77         WIDTH_DP,
78         HEIGHT_DP
79     }
80 
checkValue(final Resources res, final int resId, final String expectedValue)81     private static void checkValue(final Resources res, final int resId,
82             final String expectedValue) {
83         try {
84             final String actual = res.getString(resId);
85             assertNotNull("Returned wrong configuration-based simple value: expected <nothing>, "
86                     + "got '" + actual + "' from resource 0x" + Integer.toHexString(resId),
87                     expectedValue);
88             assertEquals("Returned wrong configuration-based simple value: expected '"
89                     + expectedValue + "', got '" + actual + "' from resource 0x"
90                     + Integer.toHexString(resId), expectedValue, actual);
91         } catch (NotFoundException e) {
92             assertNull("Resource not found for configuration-based simple value: expecting \""
93                     + expectedValue + "\"", expectedValue);
94         }
95     }
96 
checkValue(final Resources res, final int resId, final int[] styleable, final String[] expectedValues)97     private static void checkValue(final Resources res, final int resId,
98             final int[] styleable, final String[] expectedValues) {
99         final Resources.Theme theme = res.newTheme();
100         final TypedArray sa = theme.obtainStyledAttributes(resId, styleable);
101         for (int i = 0; i < styleable.length; i++) {
102             final String actual = sa.getString(i);
103             assertEquals("Returned wrong configuration-based style value: expected '"
104                     + expectedValues[i] + "', got '" + actual + "' from attr "
105                     + i + " of resource 0x" + Integer.toHexString(resId),
106                     expectedValues[i], actual);
107         }
108         sa.recycle();
109     }
110 
111     private class TotalConfig {
112         final Configuration mConfig;
113         final DisplayMetrics mMetrics;
114 
TotalConfig()115         public TotalConfig() {
116             mConfig = new Configuration();
117             mMetrics = new DisplayMetrics();
118             mConfig.locale = Locale.ROOT;
119         }
120 
setProperty(final Properties p, final int value)121         public void setProperty(final Properties p, final int value) {
122             switch(p) {
123                 case GRAMMATICAL_GENDER:
124                     mConfig.setGrammaticalGender(value);
125                     break;
126                 case MCC:
127                     mConfig.mcc = value;
128                     break;
129                 case MNC:
130                     mConfig.mnc = value;
131                     break;
132                 case TOUCHSCREEN:
133                     mConfig.touchscreen = value;
134                     break;
135                 case KEYBOARD:
136                     mConfig.keyboard = value;
137                     break;
138                 case KEYBOARDHIDDEN:
139                     mConfig.keyboardHidden = value;
140                     break;
141                 case NAVIGATION:
142                     mConfig.navigation = value;
143                     break;
144                 case ORIENTATION:
145                     mConfig.orientation = value;
146                     break;
147                 case COLOR_MODE:
148                     mConfig.colorMode = value;
149                     break;
150                 case WIDTH:
151                     mMetrics.widthPixels = value;
152                     mMetrics.noncompatWidthPixels = value;
153                     break;
154                 case HEIGHT:
155                     mMetrics.heightPixels = value;
156                     mMetrics.noncompatHeightPixels = value;
157                     break;
158                 case DENSITY:
159                     // this is the ratio from the standard
160                     mMetrics.density = (((float)value)/((float)DisplayMetrics.DENSITY_DEFAULT));
161                     mMetrics.noncompatDensity = mMetrics.density;
162                     mConfig.densityDpi = value;
163                     break;
164                 case SCREENLAYOUT:
165                     mConfig.screenLayout = value;
166                     break;
167                 case SWIDTH_DP:
168                     mConfig.smallestScreenWidthDp = value;
169                     break;
170                 case WIDTH_DP:
171                     mConfig.screenWidthDp = value;
172                     break;
173                 case HEIGHT_DP:
174                     mConfig.screenHeightDp = value;
175                     break;
176                 default:
177                     assert(false);
178                     break;
179             }
180         }
181 
setProperty(final Properties p, final String value)182         public void setProperty(final Properties p, final String value) {
183             switch(p) {
184                 case LANGUAGE:
185                     mConfig.locale = new Locale.Builder()
186                             .setLocale(mConfig.locale)
187                             .setLanguage(value)
188                             .build();
189                     break;
190                 case COUNTRY:
191                     mConfig.locale = new Locale.Builder()
192                             .setLocale(mConfig.locale)
193                             .setRegion(value)
194                             .build();
195                     break;
196                 case SCRIPT:
197                     mConfig.locale = new Locale.Builder()
198                             .setLocale(mConfig.locale)
199                             .setScript(value)
200                             .build();
201                     break;
202                 case VARIANT:
203                     mConfig.locale = new Locale.Builder()
204                             .setLocale(mConfig.locale)
205                             .setVariant(value)
206                             .build();
207                     break;
208                 default:
209                     assert(false);
210                     break;
211             }
212         }
213 
getResources()214         public Resources getResources() {
215             final AssetManager assmgr = new AssetManager();
216             assmgr.addAssetPath(mContext.getPackageResourcePath());
217             return new Resources(assmgr, mMetrics, mConfig);
218         }
219     }
220 
makeEmptyConfig()221     public TotalConfig makeEmptyConfig() {
222         return new TotalConfig();
223     }
224 
makeClassicConfig()225     public TotalConfig makeClassicConfig() {
226         TotalConfig config = new TotalConfig();
227         config.setProperty(Properties.LANGUAGE, "en");
228         config.setProperty(Properties.COUNTRY, "US");
229         config.setProperty(Properties.MCC, 310);
230         config.setProperty(Properties.MNC, 001); // unused
231         config.setProperty(Properties.TOUCHSCREEN, Configuration.TOUCHSCREEN_FINGER);
232         config.setProperty(Properties.KEYBOARD, Configuration.KEYBOARD_QWERTY);
233         config.setProperty(Properties.KEYBOARDHIDDEN, Configuration.KEYBOARDHIDDEN_YES);
234         config.setProperty(Properties.NAVIGATION, Configuration.NAVIGATION_TRACKBALL);
235         config.setProperty(Properties.ORIENTATION, Configuration.ORIENTATION_PORTRAIT);
236         config.setProperty(Properties.SWIDTH_DP, 320);
237         config.setProperty(Properties.WIDTH_DP, 320);
238         config.setProperty(Properties.HEIGHT_DP, 480);
239         config.setProperty(Properties.DENSITY, 160);
240         config.setProperty(Properties.WIDTH, 200);
241         config.setProperty(Properties.HEIGHT, 320);
242         return config;
243     }
244 
checkPair(Resources res, int[] notResIds, int simpleRes, String simpleString, int bagRes, String bagString)245     private static void checkPair(Resources res, int[] notResIds,
246             int simpleRes, String simpleString,
247             int bagRes, String bagString) {
248         boolean willHave = true;
249         if (notResIds != null) {
250             for (int i : notResIds) {
251                 if (i == simpleRes) {
252                     willHave = false;
253                     break;
254                 }
255             }
256         }
257         checkValue(res, simpleRes, willHave ? simpleString : null);
258         checkValue(res, bagRes, R.styleable.TestConfig,
259                 new String[]{willHave ? bagString : null});
260     }
261 
262     @Before
setUp()263     public void setUp() {
264         mContext = InstrumentationRegistry.getContext();
265         final PackageManager pm = mContext.getPackageManager();
266         try {
267             ApplicationInfo appInfo = pm.getApplicationInfo(TEST_PACKAGE,
268                     PackageManager.ApplicationInfoFlags.of(0));
269             mTargetSdkVersion = appInfo.targetSdkVersion;
270         } catch (NameNotFoundException e) {
271             fail("Should be able to find application info for this package");
272         }
273     }
274 
275     @Test
testAllEmptyConfigs()276     public void testAllEmptyConfigs() {
277         /**
278          * Test a resource that contains a value for each possible single
279          * configuration value.
280          */
281         TotalConfig config = makeEmptyConfig();
282         Resources res = config.getResources();
283         checkValue(res, R.string.simple, "simple default");
284         checkValue(res, R.style.bag,
285                 R.styleable.TestConfig, new String[]{"bag default"});
286 
287         config = makeEmptyConfig();
288         config.setProperty(Properties.LANGUAGE, "xx");
289         res = config.getResources();
290         checkValue(res, R.string.simple, "simple xx");
291         checkValue(res, R.style.bag,
292                 R.styleable.TestConfig, new String[]{"bag xx"});
293 
294         config = makeEmptyConfig();
295         config.setProperty(Properties.LANGUAGE, "xx");
296         config.setProperty(Properties.COUNTRY, "YY");
297         res = config.getResources();
298         checkValue(res, R.string.simple, "simple xx-rYY");
299         checkValue(res, R.style.bag,
300                 R.styleable.TestConfig, new String[]{"bag xx-rYY"});
301 
302         config = makeEmptyConfig();
303         config.setProperty(Properties.MCC, 111);
304         res = config.getResources();
305         checkValue(res, R.string.simple, "simple mcc111");
306         checkValue(res, R.style.bag,
307                 R.styleable.TestConfig, new String[]{"bag mcc111"});
308 
309         config = makeEmptyConfig();
310         config.setProperty(Properties.MNC, 222);
311         res = config.getResources();
312         checkValue(res, R.string.simple, "simple mnc222");
313         checkValue(res, R.style.bag,
314                 R.styleable.TestConfig, new String[]{"bag mnc222"});
315 
316         config = makeEmptyConfig();
317         config.setProperty(Properties.TOUCHSCREEN, Configuration.TOUCHSCREEN_NOTOUCH);
318         res = config.getResources();
319         checkValue(res, R.string.simple, "simple notouch");
320         checkValue(res, R.style.bag,
321                 R.styleable.TestConfig, new String[]{"bag notouch"});
322 
323         config = makeEmptyConfig();
324         config.setProperty(Properties.TOUCHSCREEN, Configuration.TOUCHSCREEN_STYLUS);
325         res = config.getResources();
326         checkValue(res, R.string.simple, "simple stylus");
327         checkValue(res, R.style.bag,
328                 R.styleable.TestConfig, new String[]{"bag stylus"});
329 
330         config = makeEmptyConfig();
331         config.setProperty(Properties.KEYBOARD, Configuration.KEYBOARD_NOKEYS);
332         res = config.getResources();
333         checkValue(res, R.string.simple, "simple nokeys");
334         checkValue(res, R.style.bag,
335                 R.styleable.TestConfig, new String[]{"bag nokeys"});
336 
337         config = makeEmptyConfig();
338         config.setProperty(Properties.KEYBOARD, Configuration.KEYBOARD_12KEY);
339         res = config.getResources();
340         checkValue(res, R.string.simple, "simple 12key");
341         checkValue(res, R.style.bag,
342                 R.styleable.TestConfig, new String[]{"bag 12key"});
343 
344         config = makeEmptyConfig();
345         config.setProperty(Properties.KEYBOARDHIDDEN, Configuration.KEYBOARDHIDDEN_NO);
346         res = config.getResources();
347         checkValue(res, R.string.simple, "simple keysexposed");
348         checkValue(res, R.style.bag,
349                 R.styleable.TestConfig, new String[]{"bag keysexposed"});
350 
351         config = makeEmptyConfig();
352         config.setProperty(Properties.NAVIGATION, Configuration.NAVIGATION_NONAV);
353         res = config.getResources();
354         checkValue(res, R.string.simple, "simple nonav");
355         checkValue(res, R.style.bag,
356                 R.styleable.TestConfig, new String[]{"bag nonav"});
357 
358         config = makeEmptyConfig();
359         config.setProperty(Properties.NAVIGATION, Configuration.NAVIGATION_DPAD);
360         res = config.getResources();
361         checkValue(res, R.string.simple, "simple dpad");
362         checkValue(res, R.style.bag,
363                 R.styleable.TestConfig, new String[]{"bag dpad"});
364 
365         config = makeEmptyConfig();
366         config.setProperty(Properties.NAVIGATION, Configuration.NAVIGATION_WHEEL);
367         res = config.getResources();
368         checkValue(res, R.string.simple, "simple wheel");
369         checkValue(res, R.style.bag,
370                 R.styleable.TestConfig, new String[]{"bag wheel"});
371 
372         config = makeEmptyConfig();
373         config.setProperty(Properties.HEIGHT, 480);
374         config.setProperty(Properties.WIDTH, 320);
375         res = config.getResources();
376         checkValue(res, R.string.simple, "simple 480x320");
377         checkValue(res, R.style.bag,
378                 R.styleable.TestConfig, new String[]{"bag 480x320"});
379 
380         config = makeEmptyConfig();
381         config.setProperty(Properties.DENSITY, 240);
382         res = config.getResources();
383         checkValue(res, R.string.simple, "simple 240dpi");
384         checkValue(res, R.style.bag,
385                 R.styleable.TestConfig, new String[]{"bag 240dpi"});
386 
387         config = makeEmptyConfig();
388         config.setProperty(Properties.ORIENTATION, Configuration.ORIENTATION_LANDSCAPE);
389         res = config.getResources();
390         checkValue(res, R.string.simple, "simple landscape");
391         checkValue(res, R.style.bag,
392                 R.styleable.TestConfig, new String[]{"bag landscape"});
393 
394         config = makeEmptyConfig();
395         config.setProperty(Properties.ORIENTATION, Configuration.ORIENTATION_SQUARE);
396         res = config.getResources();
397         checkValue(res, R.string.simple, "simple square");
398         checkValue(res, R.style.bag,
399                 R.styleable.TestConfig, new String[]{"bag square"});
400 
401         config = makeEmptyConfig();
402         config.setProperty(Properties.COLOR_MODE, Configuration.COLOR_MODE_HDR_YES);
403         res = config.getResources();
404         checkValue(res, R.string.simple, "simple hdr");
405         checkValue(res, R.style.bag,
406                 R.styleable.TestConfig, new String[]{"bag hdr"});
407 
408         config = makeEmptyConfig();
409         config.setProperty(Properties.COLOR_MODE, Configuration.COLOR_MODE_HDR_NO);
410         res = config.getResources();
411         checkValue(res, R.string.simple, "simple ldr");
412         checkValue(res, R.style.bag,
413                 R.styleable.TestConfig, new String[]{"bag ldr"});
414 
415         config = makeEmptyConfig();
416         config.setProperty(Properties.COLOR_MODE, Configuration.COLOR_MODE_WIDE_COLOR_GAMUT_YES);
417         res = config.getResources();
418         checkValue(res, R.string.simple, "simple widecg");
419         checkValue(res, R.style.bag,
420                 R.styleable.TestConfig, new String[]{"bag widecg"});
421 
422         config = makeEmptyConfig();
423         config.setProperty(Properties.COLOR_MODE, Configuration.COLOR_MODE_WIDE_COLOR_GAMUT_NO);
424         res = config.getResources();
425         checkValue(res, R.string.simple, "simple nowidecg");
426         checkValue(res, R.style.bag,
427                 R.styleable.TestConfig, new String[]{"bag nowidecg"});
428 
429         config = makeEmptyConfig();
430         config.setProperty(Properties.SCREENLAYOUT, Configuration.SCREENLAYOUT_SIZE_SMALL);
431         res = config.getResources();
432         checkValue(res, R.string.simple, "simple small");
433         checkValue(res, R.style.bag,
434                 R.styleable.TestConfig, new String[]{"bag small"});
435 
436         config = makeEmptyConfig();
437         config.setProperty(Properties.SCREENLAYOUT, Configuration.SCREENLAYOUT_SIZE_NORMAL);
438         res = config.getResources();
439         checkValue(res, R.string.simple, "simple normal");
440         checkValue(res, R.style.bag,
441                 R.styleable.TestConfig, new String[]{"bag normal"});
442 
443         config = makeEmptyConfig();
444         config.setProperty(Properties.SCREENLAYOUT, Configuration.SCREENLAYOUT_SIZE_LARGE);
445         res = config.getResources();
446         checkValue(res, R.string.simple, "simple large");
447         checkValue(res, R.style.bag,
448                 R.styleable.TestConfig, new String[]{"bag large"});
449 
450         config = makeEmptyConfig();
451         config.setProperty(Properties.SCREENLAYOUT, Configuration.SCREENLAYOUT_SIZE_XLARGE);
452         res = config.getResources();
453         checkValue(res, R.string.simple, "simple xlarge");
454         checkValue(res, R.style.bag,
455                 R.styleable.TestConfig, new String[]{"bag xlarge"});
456 
457         config = makeEmptyConfig();
458         config.setProperty(Properties.SWIDTH_DP, 600);
459         res = config.getResources();
460         checkValue(res, R.string.simple, "simple sw600");
461         checkValue(res, R.style.bag,
462                 R.styleable.TestConfig, new String[]{"bag sw600"});
463 
464         config = makeEmptyConfig();
465         config.setProperty(Properties.SWIDTH_DP, 600);
466         res = config.getResources();
467         checkValue(res, R.string.simple, "simple sw600");
468         checkValue(res, R.style.bag,
469                 R.styleable.TestConfig, new String[]{"bag sw600"});
470 
471         config = makeEmptyConfig();
472         config.setProperty(Properties.SWIDTH_DP, 720);
473         res = config.getResources();
474         checkValue(res, R.string.simple, "simple sw720");
475         checkValue(res, R.style.bag,
476                 R.styleable.TestConfig, new String[]{"bag sw720"});
477 
478         config = makeEmptyConfig();
479         config.setProperty(Properties.WIDTH_DP, 600);
480         res = config.getResources();
481         checkValue(res, R.string.simple, "simple w600");
482         checkValue(res, R.style.bag,
483                 R.styleable.TestConfig, new String[]{"bag w600"});
484 
485         config = makeEmptyConfig();
486         config.setProperty(Properties.WIDTH_DP, 720);
487         res = config.getResources();
488         checkValue(res, R.string.simple, "simple w720");
489         checkValue(res, R.style.bag,
490                 R.styleable.TestConfig, new String[]{"bag w720"});
491 
492         config = makeEmptyConfig();
493         config.setProperty(Properties.HEIGHT_DP, 550);
494         res = config.getResources();
495         checkValue(res, R.string.simple, "simple h550");
496         checkValue(res, R.style.bag,
497                 R.styleable.TestConfig, new String[]{"bag h550"});
498 
499         config = makeEmptyConfig();
500         config.setProperty(Properties.HEIGHT_DP, 670);
501         res = config.getResources();
502         checkValue(res, R.string.simple, "simple h670");
503         checkValue(res, R.style.bag,
504                 R.styleable.TestConfig, new String[]{"bag h670"});
505 
506         config = makeEmptyConfig();
507         config.setProperty(Properties.GRAMMATICAL_GENDER,
508                 Configuration.GRAMMATICAL_GENDER_FEMININE);
509         res = config.getResources();
510         checkValue(res, R.string.simple, "simple feminine");
511         checkValue(res, R.style.bag,
512                 R.styleable.TestConfig, new String[]{"bag feminine"});
513 
514         config = makeEmptyConfig();
515         config.setProperty(Properties.GRAMMATICAL_GENDER,
516                 Configuration.GRAMMATICAL_GENDER_MASCULINE);
517         res = config.getResources();
518         checkValue(res, R.string.simple, "simple masculine");
519         checkValue(res, R.style.bag,
520                 R.styleable.TestConfig, new String[]{"bag masculine"});
521 
522         config = makeEmptyConfig();
523         config.setProperty(Properties.GRAMMATICAL_GENDER,
524                 Configuration.GRAMMATICAL_GENDER_NEUTRAL);
525         res = config.getResources();
526         checkValue(res, R.string.simple, "simple neuter");
527         checkValue(res, R.style.bag,
528                 R.styleable.TestConfig, new String[]{"bag neuter"});
529     }
530 
531     @Test
testAllClassicConfigs()532     public void testAllClassicConfigs() {
533         /**
534          * Test a resource that contains a value for each possible single
535          * configuration value.
536          */
537         TotalConfig config = makeClassicConfig();
538         Resources res = config.getResources();
539         checkValue(res, R.string.simple, "simple default");
540         checkValue(res, R.style.bag,
541                 R.styleable.TestConfig, new String[]{"bag default"});
542 
543         config = makeClassicConfig();
544         config.setProperty(Properties.LANGUAGE, "xx");
545         res = config.getResources();
546         checkValue(res, R.string.simple, "simple xx");
547         checkValue(res, R.style.bag,
548                 R.styleable.TestConfig, new String[]{"bag xx"});
549 
550         config = makeClassicConfig();
551         config.setProperty(Properties.LANGUAGE, "xx");
552         config.setProperty(Properties.COUNTRY, "YY");
553         res = config.getResources();
554         checkValue(res, R.string.simple, "simple xx-rYY");
555         checkValue(res, R.style.bag,
556                 R.styleable.TestConfig, new String[]{"bag xx-rYY"});
557 
558         config = makeClassicConfig();
559         config.setProperty(Properties.MCC, 111);
560         res = config.getResources();
561         checkValue(res, R.string.simple, "simple mcc111");
562         checkValue(res, R.style.bag,
563                 R.styleable.TestConfig, new String[]{"bag mcc111"});
564 
565         config = makeClassicConfig();
566         config.setProperty(Properties.MNC, 222);
567         res = config.getResources();
568         checkValue(res, R.string.simple, "simple mnc222");
569         checkValue(res, R.style.bag,
570                 R.styleable.TestConfig, new String[]{"bag mnc222"});
571 
572         config = makeClassicConfig();
573         config.setProperty(Properties.TOUCHSCREEN, Configuration.TOUCHSCREEN_NOTOUCH);
574         res = config.getResources();
575         checkValue(res, R.string.simple, "simple notouch");
576         checkValue(res, R.style.bag,
577                 R.styleable.TestConfig, new String[]{"bag notouch"});
578 
579         config = makeClassicConfig();
580         config.setProperty(Properties.TOUCHSCREEN, Configuration.TOUCHSCREEN_STYLUS);
581         res = config.getResources();
582         checkValue(res, R.string.simple, "simple stylus");
583         checkValue(res, R.style.bag,
584                 R.styleable.TestConfig, new String[]{"bag stylus"});
585 
586         config = makeClassicConfig();
587         config.setProperty(Properties.KEYBOARD, Configuration.KEYBOARD_NOKEYS);
588         res = config.getResources();
589         checkValue(res, R.string.simple, "simple nokeys");
590         checkValue(res, R.style.bag,
591                 R.styleable.TestConfig, new String[]{"bag nokeys"});
592 
593         config = makeClassicConfig();
594         config.setProperty(Properties.KEYBOARD, Configuration.KEYBOARD_12KEY);
595         res = config.getResources();
596         checkValue(res, R.string.simple, "simple 12key 63x57");
597         checkValue(res, R.style.bag,
598                 R.styleable.TestConfig, new String[]{"bag 12key 63x57"});
599 
600         config = makeClassicConfig();
601         config.setProperty(Properties.KEYBOARDHIDDEN, Configuration.KEYBOARDHIDDEN_NO);
602         res = config.getResources();
603         checkValue(res, R.string.simple, "simple keysexposed");
604         checkValue(res, R.style.bag,
605                 R.styleable.TestConfig, new String[]{"bag keysexposed"});
606 
607         config = makeClassicConfig();
608         config.setProperty(Properties.NAVIGATION, Configuration.NAVIGATION_NONAV);
609         res = config.getResources();
610         checkValue(res, R.string.simple, "simple nonav");
611         checkValue(res, R.style.bag,
612                 R.styleable.TestConfig, new String[]{"bag nonav"});
613 
614         config = makeClassicConfig();
615         config.setProperty(Properties.NAVIGATION, Configuration.NAVIGATION_DPAD);
616         res = config.getResources();
617         checkValue(res, R.string.simple, "simple dpad 63x57");
618         checkValue(res, R.style.bag,
619                 R.styleable.TestConfig, new String[]{"bag dpad 63x57"});
620 
621         config = makeClassicConfig();
622         config.setProperty(Properties.NAVIGATION, Configuration.NAVIGATION_WHEEL);
623         res = config.getResources();
624         checkValue(res, R.string.simple, "simple wheel");
625         checkValue(res, R.style.bag,
626                 R.styleable.TestConfig, new String[]{"bag wheel"});
627 
628         config = makeClassicConfig();
629         config.setProperty(Properties.HEIGHT, 480);
630         config.setProperty(Properties.WIDTH, 320);
631         res = config.getResources();
632         checkValue(res, R.string.simple, "simple 480x320");
633         checkValue(res, R.style.bag,
634                 R.styleable.TestConfig, new String[]{"bag 480x320"});
635 
636         config = makeClassicConfig();
637         config.setProperty(Properties.DENSITY, 240);
638         res = config.getResources();
639         checkValue(res, R.string.simple, "simple 240dpi");
640         checkValue(res, R.style.bag,
641                 R.styleable.TestConfig, new String[]{"bag 240dpi"});
642 
643         config = makeClassicConfig();
644         config.setProperty(Properties.ORIENTATION, Configuration.ORIENTATION_LANDSCAPE);
645         res = config.getResources();
646         checkValue(res, R.string.simple, "simple landscape");
647         checkValue(res, R.style.bag,
648                 R.styleable.TestConfig, new String[]{"bag landscape"});
649 
650         config = makeClassicConfig();
651         config.setProperty(Properties.ORIENTATION, Configuration.ORIENTATION_SQUARE);
652         res = config.getResources();
653         checkValue(res, R.string.simple, "simple square");
654         checkValue(res, R.style.bag,
655                 R.styleable.TestConfig, new String[]{"bag square"});
656 
657         config = makeClassicConfig();
658         config.setProperty(Properties.SCREENLAYOUT, Configuration.SCREENLAYOUT_SIZE_SMALL);
659         res = config.getResources();
660         checkValue(res, R.string.simple, "simple small");
661         checkValue(res, R.style.bag,
662                 R.styleable.TestConfig, new String[]{"bag small"});
663 
664         config = makeClassicConfig();
665         config.setProperty(Properties.SCREENLAYOUT, Configuration.SCREENLAYOUT_SIZE_NORMAL);
666         res = config.getResources();
667         checkValue(res, R.string.simple, "simple normal");
668         checkValue(res, R.style.bag,
669                 R.styleable.TestConfig, new String[]{"bag normal"});
670 
671         config = makeClassicConfig();
672         config.setProperty(Properties.SCREENLAYOUT, Configuration.SCREENLAYOUT_SIZE_LARGE);
673         res = config.getResources();
674         checkValue(res, R.string.simple, "simple large");
675         checkValue(res, R.style.bag,
676                 R.styleable.TestConfig, new String[]{"bag large"});
677 
678         config = makeClassicConfig();
679         config.setProperty(Properties.SCREENLAYOUT, Configuration.SCREENLAYOUT_SIZE_XLARGE);
680         res = config.getResources();
681         checkValue(res, R.string.simple, "simple xlarge");
682         checkValue(res, R.style.bag,
683                 R.styleable.TestConfig, new String[]{"bag xlarge"});
684 
685         config = makeClassicConfig();
686         config.setProperty(Properties.SWIDTH_DP, 600);
687         res = config.getResources();
688         checkValue(res, R.string.simple, "simple sw600");
689         checkValue(res, R.style.bag,
690                 R.styleable.TestConfig, new String[]{"bag sw600"});
691 
692         config = makeClassicConfig();
693         config.setProperty(Properties.SWIDTH_DP, 600);
694         config.setProperty(Properties.ORIENTATION, Configuration.ORIENTATION_LANDSCAPE);
695         res = config.getResources();
696         checkValue(res, R.string.simple, "simple sw600 land");
697         checkValue(res, R.style.bag,
698                 R.styleable.TestConfig, new String[]{"bag sw600 land"});
699 
700         config = makeClassicConfig();
701         config.setProperty(Properties.SWIDTH_DP, 720);
702         res = config.getResources();
703         checkValue(res, R.string.simple, "simple sw720");
704         checkValue(res, R.style.bag,
705                 R.styleable.TestConfig, new String[]{"bag sw720"});
706 
707         config = makeClassicConfig();
708         config.setProperty(Properties.WIDTH_DP, 600);
709         res = config.getResources();
710         checkValue(res, R.string.simple, "simple w600");
711         checkValue(res, R.style.bag,
712                 R.styleable.TestConfig, new String[]{"bag w600"});
713 
714         config = makeClassicConfig();
715         config.setProperty(Properties.WIDTH_DP, 720);
716         res = config.getResources();
717         checkValue(res, R.string.simple, "simple w720");
718         checkValue(res, R.style.bag,
719                 R.styleable.TestConfig, new String[]{"bag w720"});
720 
721         config = makeClassicConfig();
722         config.setProperty(Properties.HEIGHT_DP, 550);
723         res = config.getResources();
724         checkValue(res, R.string.simple, "simple h550");
725         checkValue(res, R.style.bag,
726                 R.styleable.TestConfig, new String[]{"bag h550"});
727 
728         config = makeClassicConfig();
729         config.setProperty(Properties.HEIGHT_DP, 670);
730         res = config.getResources();
731         checkValue(res, R.string.simple, "simple h670");
732         checkValue(res, R.style.bag,
733                 R.styleable.TestConfig, new String[]{"bag h670"});
734     }
735 
736     @Test
testDensity()737     public void testDensity() throws Exception {
738         // Have 32, 240 and the default 160 content.
739         // Rule is that next highest wins.
740         TotalConfig config = makeClassicConfig();
741         config.setProperty(Properties.DENSITY, 2);
742         Resources res = config.getResources();
743         checkValue(res, R.string.simple, "simple 32dpi");
744         checkValue(res, R.style.bag,
745                 R.styleable.TestConfig, new String[]{"bag 32dpi"});
746 
747         config = makeClassicConfig();
748         config.setProperty(Properties.DENSITY, 32);
749         res = config.getResources();
750         checkValue(res, R.string.simple, "simple 32dpi");
751         checkValue(res, R.style.bag,
752                 R.styleable.TestConfig, new String[]{"bag 32dpi"});
753 
754         config = makeClassicConfig();
755         config.setProperty(Properties.DENSITY, 48);
756         res = config.getResources();
757         checkValue(res, R.string.simple, "simple default");
758         checkValue(res, R.style.bag,
759                 R.styleable.TestConfig, new String[]{"bag default"});
760 
761         config = makeClassicConfig();
762         config.setProperty(Properties.DENSITY, 150);
763         res = config.getResources();
764         checkValue(res, R.string.simple, "simple default");
765         checkValue(res, R.style.bag,
766                 R.styleable.TestConfig, new String[]{"bag default"});
767 
768         config = makeClassicConfig();
769         config.setProperty(Properties.DENSITY, 181);
770         res = config.getResources();
771         checkValue(res, R.string.simple, "simple 240dpi");
772         checkValue(res, R.style.bag,
773                 R.styleable.TestConfig, new String[]{"bag 240dpi"});
774 
775         config = makeClassicConfig();
776         config.setProperty(Properties.DENSITY, 239);
777         res = config.getResources();
778         checkValue(res, R.string.simple, "simple 240dpi");
779         checkValue(res, R.style.bag,
780                 R.styleable.TestConfig, new String[]{"bag 240dpi"});
781 
782         config = makeClassicConfig();
783         config.setProperty(Properties.DENSITY, 490);
784         res = config.getResources();
785         checkValue(res, R.string.simple, "simple 240dpi");
786         checkValue(res, R.style.bag,
787                 R.styleable.TestConfig, new String[]{"bag 240dpi"});
788     }
789 
790     @Test
testScreenSize()791     public void testScreenSize() throws Exception {
792         // ensure that we fall back to the best available screen size
793         // for a given configuration.
794         TotalConfig config = makeClassicConfig();
795         config.setProperty(Properties.SCREENLAYOUT, Configuration.SCREENLAYOUT_SIZE_SMALL);
796         Resources res = config.getResources();
797         checkValue(res, R.string.simple, "simple small");
798         checkValue(res, R.string.small, "small");
799         checkValue(res, R.string.normal, "default");
800         checkValue(res, R.string.large, "default");
801         checkValue(res, R.string.xlarge, "default");
802 
803         config = makeClassicConfig();
804         config.setProperty(Properties.SCREENLAYOUT, Configuration.SCREENLAYOUT_SIZE_NORMAL);
805         res = config.getResources();
806         checkValue(res, R.string.simple, "simple normal");
807         checkValue(res, R.string.small, "default");
808         checkValue(res, R.string.normal, "normal");
809         checkValue(res, R.string.large, "default");
810         checkValue(res, R.string.xlarge, "default");
811 
812         config = makeClassicConfig();
813         config.setProperty(Properties.SCREENLAYOUT, Configuration.SCREENLAYOUT_SIZE_LARGE);
814         res = config.getResources();
815         checkValue(res, R.string.simple, "simple large");
816         checkValue(res, R.string.small, "default");
817         checkValue(res, R.string.normal, "normal");
818         checkValue(res, R.string.large, "large");
819         checkValue(res, R.string.xlarge, "default");
820 
821         config = makeClassicConfig();
822         config.setProperty(Properties.SCREENLAYOUT, Configuration.SCREENLAYOUT_SIZE_XLARGE);
823         res = config.getResources();
824         checkValue(res, R.string.simple, "simple xlarge");
825         checkValue(res, R.string.small, "default");
826         checkValue(res, R.string.normal, "normal");
827         checkValue(res, R.string.large, "large");
828         checkValue(res, R.string.xlarge, "xlarge");
829     }
830 
831     @Test
testNewScreenSize()832     public void testNewScreenSize() throws Exception {
833         // ensure that swNNNdp, wNNNdp, and hNNNdp are working correctly
834         // for various common screen configurations.
835         TotalConfig config = makeClassicConfig();
836         config.setProperty(Properties.SWIDTH_DP, 589);
837         config.setProperty(Properties.WIDTH_DP, 589);
838         config.setProperty(Properties.HEIGHT_DP, 500);
839         config.setProperty(Properties.ORIENTATION, Configuration.ORIENTATION_LANDSCAPE);
840         config.setProperty(Properties.SCREENLAYOUT, Configuration.SCREENLAYOUT_SIZE_LARGE);
841         Resources res = config.getResources();
842         checkValue(res, R.string.simple, "simple large");
843         checkValue(res, R.string.sw, "default");
844         checkValue(res, R.string.w, "default");
845         checkValue(res, R.string.h, "default");
846         checkValue(res, R.string.wh, "default");
847 
848         config = makeClassicConfig();
849         config.setProperty(Properties.SWIDTH_DP, 590);
850         config.setProperty(Properties.WIDTH_DP, 590);
851         config.setProperty(Properties.HEIGHT_DP, 500);
852         config.setProperty(Properties.ORIENTATION, Configuration.ORIENTATION_LANDSCAPE);
853         config.setProperty(Properties.SCREENLAYOUT, Configuration.SCREENLAYOUT_SIZE_LARGE);
854         config.setProperty(Properties.DENSITY, DisplayMetrics.DENSITY_MEDIUM);
855         res = config.getResources();
856         checkValue(res, R.string.simple, "simple sw590 mdpi");
857         checkValue(res, R.string.sw, "590 mdpi");
858 
859         config.setProperty(Properties.DENSITY, DisplayMetrics.DENSITY_HIGH);
860         res = config.getResources();
861         checkValue(res, R.string.simple, "simple sw590 hdpi");
862         checkValue(res, R.string.sw, "590 hdpi");
863 
864         config.setProperty(Properties.DENSITY, DisplayMetrics.DENSITY_XHIGH);
865         res = config.getResources();
866         checkValue(res, R.string.simple, "simple sw590 xhdpi");
867         checkValue(res, R.string.sw, "590 xhdpi");
868 
869         config.setProperty(Properties.SWIDTH_DP, 591);
870         config.setProperty(Properties.WIDTH_DP, 591);
871         config.setProperty(Properties.DENSITY, DisplayMetrics.DENSITY_MEDIUM);
872         res = config.getResources();
873         checkValue(res, R.string.simple, "simple sw591");
874         checkValue(res, R.string.sw, "591");
875 
876         config.setProperty(Properties.DENSITY, DisplayMetrics.DENSITY_HIGH);
877         res = config.getResources();
878         checkValue(res, R.string.simple, "simple sw591 hdpi");
879         checkValue(res, R.string.sw, "591 hdpi");
880 
881         config.setProperty(Properties.DENSITY, DisplayMetrics.DENSITY_XHIGH);
882         res = config.getResources();
883         checkValue(res, R.string.simple, "simple sw591 hdpi");
884         checkValue(res, R.string.sw, "591 hdpi");
885 
886         config = makeClassicConfig();
887         config.setProperty(Properties.SWIDTH_DP, 480);
888         config.setProperty(Properties.WIDTH_DP, 800);
889         config.setProperty(Properties.HEIGHT_DP, 480);
890         config.setProperty(Properties.ORIENTATION, Configuration.ORIENTATION_LANDSCAPE);
891         config.setProperty(Properties.SCREENLAYOUT, Configuration.SCREENLAYOUT_SIZE_LARGE);
892         res = config.getResources();
893         checkValue(res, R.string.simple, "simple w720");
894         checkValue(res, R.string.sw, "default");
895         checkValue(res, R.string.w, "720");
896         checkValue(res, R.string.h, "default");
897         checkValue(res, R.string.wh, "600");
898 
899         config = makeClassicConfig();
900         config.setProperty(Properties.SWIDTH_DP, 600);
901         config.setProperty(Properties.WIDTH_DP, 1024);
902         config.setProperty(Properties.HEIGHT_DP, 552);
903         config.setProperty(Properties.ORIENTATION, Configuration.ORIENTATION_LANDSCAPE);
904         config.setProperty(Properties.SCREENLAYOUT, Configuration.SCREENLAYOUT_SIZE_LARGE);
905         res = config.getResources();
906         checkValue(res, R.string.simple, "simple sw600 land");
907         checkValue(res, R.string.sw, "600 land");
908         checkValue(res, R.string.w, "720");
909         checkValue(res, R.string.h, "550");
910         checkValue(res, R.string.wh, "600-550");
911 
912         config = makeClassicConfig();
913         config.setProperty(Properties.SWIDTH_DP, 600);
914         config.setProperty(Properties.WIDTH_DP, 600);
915         config.setProperty(Properties.HEIGHT_DP, 974);
916         config.setProperty(Properties.ORIENTATION, Configuration.ORIENTATION_PORTRAIT);
917         config.setProperty(Properties.SCREENLAYOUT, Configuration.SCREENLAYOUT_SIZE_LARGE);
918         res = config.getResources();
919         checkValue(res, R.string.simple, "simple sw600");
920         checkValue(res, R.string.sw, "600");
921         checkValue(res, R.string.w, "600");
922         checkValue(res, R.string.h, "670");
923         checkValue(res, R.string.wh, "600-550");
924 
925         config = makeClassicConfig();
926         config.setProperty(Properties.SWIDTH_DP, 719);
927         config.setProperty(Properties.WIDTH_DP, 1279);
928         config.setProperty(Properties.HEIGHT_DP, 669);
929         config.setProperty(Properties.ORIENTATION, Configuration.ORIENTATION_LANDSCAPE);
930         config.setProperty(Properties.SCREENLAYOUT, Configuration.SCREENLAYOUT_SIZE_LARGE);
931         res = config.getResources();
932         checkValue(res, R.string.simple, "simple sw600 land");
933         checkValue(res, R.string.sw, "600 land");
934         checkValue(res, R.string.w, "720");
935         checkValue(res, R.string.h, "550");
936         checkValue(res, R.string.wh, "600-550");
937 
938         config = makeClassicConfig();
939         config.setProperty(Properties.SWIDTH_DP, 800);
940         config.setProperty(Properties.WIDTH_DP, 1280);
941         config.setProperty(Properties.HEIGHT_DP, 672);
942         config.setProperty(Properties.ORIENTATION, Configuration.ORIENTATION_LANDSCAPE);
943         config.setProperty(Properties.SCREENLAYOUT, Configuration.SCREENLAYOUT_SIZE_XLARGE);
944         res = config.getResources();
945         checkValue(res, R.string.simple, "simple sw720");
946         checkValue(res, R.string.sw, "720");
947         checkValue(res, R.string.w, "720");
948         checkValue(res, R.string.h, "670");
949         checkValue(res, R.string.wh, "720-670");
950 
951         config = makeClassicConfig();
952         config.setProperty(Properties.SWIDTH_DP, 800);
953         config.setProperty(Properties.WIDTH_DP, 720);
954         config.setProperty(Properties.HEIGHT_DP, 1230);
955         config.setProperty(Properties.ORIENTATION, Configuration.ORIENTATION_PORTRAIT);
956         config.setProperty(Properties.SCREENLAYOUT, Configuration.SCREENLAYOUT_SIZE_XLARGE);
957         res = config.getResources();
958         checkValue(res, R.string.simple, "simple sw720");
959         checkValue(res, R.string.sw, "720");
960         checkValue(res, R.string.w, "720");
961         checkValue(res, R.string.h, "670");
962         checkValue(res, R.string.wh, "720-670");
963     }
964 
965 // TODO - add tests for special cases - ie, other key params seem ignored if
966 // nokeys is set
967 
968     @Test
testPrecedence()969     public void testPrecedence() {
970         /**
971          * Check for precedence of resources selected when there are multiple
972          * options matching the current config.
973          */
974         TotalConfig config = makeEmptyConfig();
975         config.setProperty(Properties.HEIGHT, 640);
976         config.setProperty(Properties.WIDTH, 400);
977         Resources res = config.getResources();
978         checkValue(res, R.string.simple, "simple 640x400");
979         checkValue(res, R.style.bag,
980                 R.styleable.TestConfig, new String[]{"bag 640x400"});
981 
982         config.setProperty(Properties.NAVIGATION, Configuration.NAVIGATION_NONAV);
983         res = config.getResources();
984         checkValue(res, R.string.simple, "simple nonav");
985         checkValue(res, R.style.bag,
986                 R.styleable.TestConfig, new String[]{"bag nonav"});
987 
988         config.setProperty(Properties.KEYBOARD, Configuration.KEYBOARD_NOKEYS);
989         res = config.getResources();
990         checkValue(res, R.string.simple, "simple nokeys");
991         checkValue(res, R.style.bag,
992                 R.styleable.TestConfig, new String[]{"bag nokeys"});
993 
994         config.setProperty(Properties.KEYBOARDHIDDEN, Configuration.KEYBOARDHIDDEN_NO);
995         res = config.getResources();
996         checkValue(res, R.string.simple, "simple keysexposed");
997         checkValue(res, R.style.bag,
998                 R.styleable.TestConfig, new String[]{"bag keysexposed"});
999 
1000         config.setProperty(Properties.TOUCHSCREEN, Configuration.TOUCHSCREEN_NOTOUCH);
1001         res = config.getResources();
1002         checkValue(res, R.string.simple, "simple notouch");
1003         checkValue(res, R.style.bag,
1004                 R.styleable.TestConfig, new String[]{"bag notouch"});
1005 
1006         config.setProperty(Properties.DENSITY, 240);
1007         res = config.getResources();
1008         checkValue(res, R.string.simple, "simple 240dpi");
1009         checkValue(res, R.style.bag,
1010                 R.styleable.TestConfig, new String[]{"bag 240dpi"});
1011 
1012         config.setProperty(Properties.ORIENTATION, Configuration.ORIENTATION_LANDSCAPE);
1013         res = config.getResources();
1014         checkValue(res, R.string.simple, "simple landscape");
1015         checkValue(res, R.style.bag,
1016                 R.styleable.TestConfig, new String[]{"bag landscape"});
1017 
1018         config.setProperty(Properties.COLOR_MODE, Configuration.COLOR_MODE_HDR_YES);
1019         res = config.getResources();
1020         checkValue(res, R.string.simple, "simple hdr");
1021         checkValue(res, R.style.bag,
1022                 R.styleable.TestConfig, new String[]{"bag hdr"});
1023 
1024         config.setProperty(Properties.COLOR_MODE, Configuration.COLOR_MODE_WIDE_COLOR_GAMUT_YES);
1025         res = config.getResources();
1026         checkValue(res, R.string.simple, "simple widecg");
1027         checkValue(res, R.style.bag,
1028                 R.styleable.TestConfig, new String[]{"bag widecg"});
1029 
1030         config.setProperty(Properties.SCREENLAYOUT, Configuration.SCREENLAYOUT_SIZE_XLARGE);
1031         res = config.getResources();
1032         checkValue(res, R.string.simple, "simple xlarge");
1033         checkValue(res, R.style.bag,
1034                 R.styleable.TestConfig, new String[]{"bag xlarge"});
1035 
1036         config.setProperty(Properties.HEIGHT_DP, 670);
1037         res = config.getResources();
1038         checkValue(res, R.string.simple, "simple h670");
1039         checkValue(res, R.style.bag,
1040                 R.styleable.TestConfig, new String[]{"bag h670"});
1041 
1042         config.setProperty(Properties.WIDTH_DP, 720);
1043         res = config.getResources();
1044         checkValue(res, R.string.simple, "simple 720-670");
1045         checkValue(res, R.style.bag,
1046                 R.styleable.TestConfig, new String[]{"bag 720-670"});
1047 
1048         config.setProperty(Properties.SWIDTH_DP, 720);
1049         res = config.getResources();
1050         checkValue(res, R.string.simple, "simple sw720");
1051         checkValue(res, R.style.bag,
1052                 R.styleable.TestConfig, new String[]{"bag sw720"});
1053 
1054         config.setProperty(Properties.GRAMMATICAL_GENDER,
1055                 Configuration.GRAMMATICAL_GENDER_FEMININE);
1056         res = config.getResources();
1057         checkValue(res, R.string.simple, "simple feminine");
1058         checkValue(res, R.style.bag,
1059                 R.styleable.TestConfig, new String[]{"bag feminine"});
1060 
1061         config.setProperty(Properties.LANGUAGE, "xx");
1062         config.setProperty(Properties.COUNTRY, "YY");
1063         res = config.getResources();
1064         checkValue(res, R.string.simple, "simple xx-rYY");
1065         checkValue(res, R.style.bag,
1066                 R.styleable.TestConfig, new String[]{"bag xx-rYY"});
1067 
1068         config.setProperty(Properties.MCC, 111);
1069         res = config.getResources();
1070         checkValue(res, R.string.simple, "simple mcc111 xx-rYY");
1071         checkValue(res, R.style.bag,
1072                 R.styleable.TestConfig, new String[]{"bag mcc111 xx-rYY"});
1073 
1074         config.setProperty(Properties.MNC, 222);
1075         res = config.getResources();
1076         checkValue(res, R.string.simple, "simple mcc111 mnc222");
1077         checkValue(res, R.style.bag,
1078                 R.styleable.TestConfig, new String[]{"bag mcc111 mnc222"});
1079     }
1080 
1081     @Test
testCombinations()1082     public void testCombinations() {
1083         /**
1084          * Verify that in cases of ties, the specific ordering is followed
1085          */
1086 
1087         /**
1088          * Precidence order: mcc, mnc, locale, swdp, wdp, hdp, screenlayout-size,
1089          * screenlayout-long, orientation, density,
1090          * touchscreen, hidden, keyboard, navigation, width-height
1091          */
1092 
1093         /**
1094          * verify mcc trumps mnc.  Have 110-xx, 220-xx but no 110-220
1095          * so which is selected?  Should be mcc110-xx.
1096          */
1097         TotalConfig config = makeClassicConfig();
1098         config.setProperty(Properties.MCC, 110);
1099         config.setProperty(Properties.MNC, 220);
1100         config.setProperty(Properties.LANGUAGE, "xx");
1101         Resources res = config.getResources();
1102         checkValue(res, R.string.simple, "simple mcc110 xx");
1103         checkValue(res, R.style.bag,
1104                 R.styleable.TestConfig, new String[]{"bag mcc110 xx"});
1105 
1106         /* full A + B + C doesn't exist.  Do we get A + C or B + C?
1107          */
1108         config = makeClassicConfig();
1109         config.setProperty(Properties.MCC, 111);
1110         config.setProperty(Properties.MNC, 222);
1111         config.setProperty(Properties.LANGUAGE, "xx");
1112         res = config.getResources();
1113         checkValue(res, R.string.simple, "simple mcc111 mnc222");
1114         checkValue(res, R.style.bag,
1115                 R.styleable.TestConfig, new String[]{"bag mcc111 mnc222"});
1116 
1117         config = makeClassicConfig();
1118         config.setProperty(Properties.MNC, 222);
1119         config.setProperty(Properties.LANGUAGE, "xx");
1120         config.setProperty(Properties.ORIENTATION,
1121                 Configuration.ORIENTATION_SQUARE);
1122         res = config.getResources();
1123         checkValue(res, R.string.simple, "simple mnc222 xx");
1124         checkValue(res, R.style.bag,
1125                 R.styleable.TestConfig, new String[]{"bag mnc222 xx"});
1126 
1127         config = makeClassicConfig();
1128         config.setProperty(Properties.LANGUAGE, "xx");
1129         config.setProperty(Properties.ORIENTATION,
1130                 Configuration.ORIENTATION_SQUARE);
1131         config.setProperty(Properties.DENSITY, 32);
1132         res = config.getResources();
1133         checkValue(res, R.string.simple, "simple xx square");
1134         checkValue(res, R.style.bag,
1135                 R.styleable.TestConfig, new String[]{"bag xx square"});
1136 
1137         /**
1138          * Verify that proper strings are found for multiple-selectivity case
1139          * (ie, a string set for locale and mcc is found only when both are
1140          * true).
1141          */
1142         config = makeClassicConfig();
1143         config.setProperty(Properties.LANGUAGE, "xx");
1144         config.setProperty(Properties.COUNTRY, "YY");
1145         config.setProperty(Properties.MCC, 111);
1146         res = config.getResources();
1147         checkValue(res, R.string.simple, "simple mcc111 xx-rYY");
1148         checkValue(res, R.style.bag, R.styleable.TestConfig,
1149                 new String[] { "bag mcc111 xx-rYY" });
1150 
1151         config = makeClassicConfig();
1152         config.setProperty(Properties.LANGUAGE, "xx");
1153         config.setProperty(Properties.COUNTRY, "YY");
1154         config.setProperty(Properties.MCC, 333);
1155         res = config.getResources();
1156         checkValue(res, R.string.simple, "simple xx-rYY");
1157         checkValue(res, R.style.bag,
1158                 R.styleable.TestConfig, new String[] { "bag xx-rYY" });
1159 
1160         config = makeClassicConfig();
1161         config.setProperty(Properties.MNC, 333);
1162         res = config.getResources();
1163         checkValue(res, R.string.simple, "simple default");
1164         checkValue(res, R.style.bag,
1165                 R.styleable.TestConfig, new String[]{"bag default"});
1166 
1167         config = makeClassicConfig();
1168         config.setProperty(Properties.ORIENTATION,
1169                 Configuration.ORIENTATION_SQUARE);
1170         config.setProperty(Properties.DENSITY, 32);
1171         config.setProperty(Properties.TOUCHSCREEN,
1172                 Configuration.TOUCHSCREEN_STYLUS);
1173         res = config.getResources();
1174         checkValue(res, R.string.simple, "simple square 32dpi");
1175         checkValue(res, R.style.bag,
1176                 R.styleable.TestConfig, new String[]{"bag square 32dpi"});
1177 
1178         config = makeClassicConfig();
1179         config.setProperty(Properties.DENSITY, 32);
1180         config.setProperty(Properties.TOUCHSCREEN,
1181                 Configuration.TOUCHSCREEN_STYLUS);
1182         config.setProperty(Properties.KEYBOARDHIDDEN,
1183                 Configuration.KEYBOARDHIDDEN_NO);
1184         res = config.getResources();
1185         checkValue(res, R.string.simple, "simple 32dpi stylus");
1186         checkValue(res, R.style.bag,
1187                 R.styleable.TestConfig, new String[]{"bag 32dpi stylus"});
1188 
1189         config = makeClassicConfig();
1190         config.setProperty(Properties.TOUCHSCREEN,
1191                 Configuration.TOUCHSCREEN_STYLUS);
1192         config.setProperty(Properties.KEYBOARDHIDDEN,
1193                 Configuration.KEYBOARDHIDDEN_NO);
1194         config.setProperty(Properties.KEYBOARD, Configuration.KEYBOARD_12KEY);
1195         res = config.getResources();
1196         checkValue(res, R.string.simple, "simple stylus keysexposed");
1197         checkValue(res, R.style.bag,
1198                 R.styleable.TestConfig, new String[]{"bag stylus keysexposed"});
1199 
1200         config = makeClassicConfig();
1201         config.setProperty(Properties.KEYBOARDHIDDEN,
1202                 Configuration.KEYBOARDHIDDEN_NO);
1203         config.setProperty(Properties.KEYBOARD, Configuration.KEYBOARD_12KEY);
1204         config.setProperty(Properties.NAVIGATION,
1205                 Configuration.NAVIGATION_DPAD);
1206         res = config.getResources();
1207         checkValue(res, R.string.simple, "simple keysexposed 12key");
1208         checkValue(res, R.style.bag,
1209                 R.styleable.TestConfig, new String[]{"bag keysexposed 12key"});
1210 
1211         config = makeClassicConfig();
1212         config.setProperty(Properties.KEYBOARD, Configuration.KEYBOARD_12KEY);
1213         config.setProperty(Properties.NAVIGATION,
1214                 Configuration.NAVIGATION_DPAD);
1215         config.setProperty(Properties.HEIGHT, 63);
1216         config.setProperty(Properties.WIDTH, 57);
1217         res = config.getResources();
1218         checkValue(res, R.string.simple, "simple 12key dpad");
1219         checkValue(res, R.style.bag,
1220                 R.styleable.TestConfig, new String[]{"bag 12key dpad"});
1221 
1222         config = makeClassicConfig();
1223         config.setProperty(Properties.NAVIGATION,
1224                 Configuration.NAVIGATION_DPAD);
1225         config.setProperty(Properties.HEIGHT, 640);
1226         config.setProperty(Properties.WIDTH, 400);
1227         res = config.getResources();
1228         checkValue(res, R.string.simple, "simple dpad 63x57");
1229         checkValue(res, R.style.bag,
1230                 R.styleable.TestConfig, new String[]{"bag dpad 63x57"});
1231     }
1232 
1233     @Test
testVersions()1234     public void testVersions() {
1235         final boolean isReleaseBuild = "REL".equals(android.os.Build.VERSION.CODENAME);
1236 
1237         // Release builds must not have a dev SDK version
1238         if (isReleaseBuild) {
1239             assertTrue("Release builds must build with a valid SDK version",
1240                     mTargetSdkVersion < 10000);
1241         }
1242 
1243         // ...and skip this test if this is a dev-SDK-version build
1244         assumeTrue("This product was built with non-release SDK level 10000",
1245                 mTargetSdkVersion < 10000);
1246 
1247         // Check that we get the most recent resources that are <= our
1248         // current version.  Note the special version adjustment, so that
1249         // during development the resource version is incremented to the
1250         // next one.
1251         int vers = android.os.Build.VERSION.SDK_INT;
1252         if (!isReleaseBuild) {
1253             vers++;
1254         }
1255         String expected = "v" + vers + "cur";
1256         assertEquals(expected, mContext.getResources().getString(R.string.version_cur));
1257         assertEquals("base",  mContext.getResources().getString(R.string.version_old));
1258         assertEquals("v3",  mContext.getResources().getString(R.string.version_v3));
1259     }
1260 
1261     @Test
testNormalLocales()1262     public void testNormalLocales() {
1263         Resources res;
1264         TotalConfig config = makeClassicConfig();
1265         // Hebrew
1266         config.setProperty(Properties.LANGUAGE, "iw");
1267         res = config.getResources();
1268         checkValue(res, R.string.simple, "simple iw");
1269         checkValue(res, R.style.bag,
1270                 R.styleable.TestConfig, new String[]{"bag iw"});
1271 
1272         // Hebrew for Israel
1273         config.setProperty(Properties.LANGUAGE, "iw");
1274         config.setProperty(Properties.COUNTRY, "IL");
1275         res = config.getResources();
1276         checkValue(res, R.string.simple, "simple iw IL");
1277         checkValue(res, R.style.bag,
1278                 R.styleable.TestConfig, new String[]{"bag iw IL"});
1279 
1280         config = makeClassicConfig();
1281         // Macedonian
1282         config.setProperty(Properties.LANGUAGE, "mk");
1283         res = config.getResources();
1284         checkValue(res, R.string.simple, "simple mk");
1285         checkValue(res, R.style.bag,
1286                 R.styleable.TestConfig, new String[]{"bag mk"});
1287 
1288         // Macedonian for Macedonia
1289         config.setProperty(Properties.LANGUAGE, "mk");
1290         config.setProperty(Properties.COUNTRY, "MK");
1291         res = config.getResources();
1292         checkValue(res, R.string.simple, "simple mk MK");
1293         checkValue(res, R.style.bag,
1294                 R.styleable.TestConfig, new String[]{"bag mk MK"});
1295     }
1296 
1297     @Test
testExtendedLocales()1298     public void testExtendedLocales() {
1299         TotalConfig config = makeClassicConfig();
1300         // BCP 47 Locale kok
1301         config.setProperty(Properties.LANGUAGE, "kok");
1302         Resources res = config.getResources();
1303         checkValue(res, R.string.simple, "simple kok");
1304         checkValue(res, R.style.bag,
1305                 R.styleable.TestConfig, new String[]{"bag kok"});
1306 
1307         // BCP 47 Locale kok-IN
1308         config.setProperty(Properties.COUNTRY, "IN");
1309         res = config.getResources();
1310         checkValue(res, R.string.simple, "simple kok IN");
1311         checkValue(res, R.style.bag,
1312                 R.styleable.TestConfig, new String[]{"bag kok IN"});
1313 
1314         // BCP 47 Locale kok-419
1315         config.setProperty(Properties.COUNTRY, "419");
1316         res = config.getResources();
1317         checkValue(res, R.string.simple, "simple kok 419");
1318         checkValue(res, R.style.bag,
1319                 R.styleable.TestConfig, new String[]{"bag kok 419"});
1320 
1321 
1322         // BCP 47 Locale kok-419-VARIANT
1323         config.setProperty(Properties.VARIANT, "VARIANT");
1324         res = config.getResources();
1325         checkValue(res, R.string.simple, "simple kok 419 VARIANT");
1326         checkValue(res, R.style.bag,
1327                 R.styleable.TestConfig, new String[]{"bag kok 419 VARIANT"});
1328 
1329         // BCP 47 Locale kok-Knda
1330         config = makeClassicConfig();
1331         config.setProperty(Properties.LANGUAGE, "kok");
1332         config.setProperty(Properties.SCRIPT, "Knda");
1333         res = config.getResources();
1334         checkValue(res, R.string.simple, "simple kok Knda");
1335         checkValue(res, R.style.bag,
1336                 R.styleable.TestConfig, new String[]{"bag kok Knda"});
1337 
1338         // BCP 47 Locale kok-Knda-419
1339         config.setProperty(Properties.COUNTRY, "419");
1340         res = config.getResources();
1341         checkValue(res, R.string.simple, "simple kok Knda 419");
1342         checkValue(res, R.style.bag,
1343                 R.styleable.TestConfig, new String[]{"bag kok Knda 419"});
1344 
1345         // BCP 47 Locale kok-Knda-419-VARIANT
1346         config.setProperty(Properties.VARIANT, "VARIANT");
1347         res = config.getResources();
1348         checkValue(res, R.string.simple, "simple kok Knda 419 VARIANT");
1349         checkValue(res, R.style.bag,
1350                 R.styleable.TestConfig, new String[]{"bag kok Knda 419 VARIANT"});
1351 
1352         // BCP 47 Locale kok-VARIANT
1353         config = makeClassicConfig();
1354         config.setProperty(Properties.LANGUAGE, "kok");
1355         config.setProperty(Properties.VARIANT, "VARIANT");
1356         res = config.getResources();
1357         checkValue(res, R.string.simple, "simple kok VARIANT");
1358         checkValue(res, R.style.bag,
1359                 R.styleable.TestConfig, new String[]{"bag kok VARIANT"});
1360     }
1361 
1362     @Test
testTlAndFilConversion()1363     public void testTlAndFilConversion() {
1364         TotalConfig config = makeClassicConfig();
1365 
1366         // Ensure that "fil" is mapped to "tl" correctly.
1367         config.setProperty(Properties.LANGUAGE, "fil");
1368         config.setProperty(Properties.COUNTRY, "US");
1369         Resources res = config.getResources();
1370         checkValue(res, R.string.simple, "simple fil");  // We have this resource in 'fil'
1371         checkValue(res, R.style.bag,
1372                 R.styleable.TestConfig, new String[] { "bag tl" });  // But this comes from 'tl'
1373 
1374         // Ensure that "fil-PH" is mapped to "tl-PH" correctly.
1375         config = makeClassicConfig();
1376         config.setProperty(Properties.LANGUAGE, "fil");
1377         config.setProperty(Properties.COUNTRY, "PH");
1378         res = config.getResources();
1379         checkValue(res, R.string.simple, "simple tl PH");
1380         checkValue(res, R.style.bag,
1381                 R.styleable.TestConfig, new String[] { "bag tl PH" });
1382 
1383         // Ensure that "fil-SA" works with no "tl" version.
1384         config = makeClassicConfig();
1385         config.setProperty(Properties.LANGUAGE, "fil");
1386         config.setProperty(Properties.COUNTRY, "SA");
1387         res = config.getResources();
1388         checkValue(res, R.string.simple, "simple fil");  // This comes from 'fil'
1389         checkValue(res, R.style.bag,
1390                 R.styleable.TestConfig, new String[] { "bag fil SA" });  // And this from 'fil-SA'
1391 
1392         // Ensure that "tlh" is not mistakenly treated as a "tl" variant.
1393         config = makeClassicConfig();
1394         config.setProperty(Properties.LANGUAGE, "tlh");
1395         config.setProperty(Properties.COUNTRY, "US");
1396         res = config.getResources();
1397         checkValue(res, R.string.simple, "simple tlh");
1398         checkValue(res, R.style.bag,
1399                 R.styleable.TestConfig, new String[] { "bag tlh" });
1400 
1401         config = makeClassicConfig();
1402         config.setProperty(Properties.LANGUAGE, "tgl");
1403         res = config.getResources();
1404         checkValue(res, R.string.simple, "simple tgl");
1405         checkValue(res, R.style.bag,
1406                 R.styleable.TestConfig, new String[] { "bag tgl" });
1407 
1408         config = makeClassicConfig();
1409         config.setProperty(Properties.LANGUAGE, "tgl");
1410         config.setProperty(Properties.COUNTRY, "PH");
1411         res = config.getResources();
1412         checkValue(res, R.string.simple, "simple tgl PH");
1413         checkValue(res, R.style.bag,
1414                 R.styleable.TestConfig, new String[] { "bag tgl PH" });
1415     }
1416 
1417     @Test
testGetLocalesConvertsTlToFil()1418     public void testGetLocalesConvertsTlToFil() {
1419         TotalConfig config = makeClassicConfig();
1420 
1421         // Check that the list of locales doesn't contain any of the
1422         // "tl" variants. They should've been converted to "fil"
1423         // locales.
1424         AssetManager am = config.getResources().getAssets();
1425         String[] locales = am.getLocales();
1426         final List<String> tlLocales = new ArrayList<String>(4);
1427         final List<String> filLocales = new ArrayList<String>(4);
1428         for (String locale : locales) {
1429             if (locale.startsWith("tl-") || locale.equals("tl")) {
1430                 tlLocales.add(locale);
1431             }
1432 
1433             if (locale.startsWith("fil-") || locale.equals("fil")) {
1434                 filLocales.add(locale);
1435             }
1436         }
1437 
1438         assertEquals(0, tlLocales.size());
1439         assertEquals(3, filLocales.size());
1440         assertTrue(filLocales.contains("fil"));
1441         assertTrue(filLocales.contains("fil-PH"));
1442         assertTrue(filLocales.contains("fil-SA"));
1443     }
1444 }
1445