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