1package com.android.overlaytest;
2
3import android.content.res.Configuration;
4import android.content.res.Resources;
5import android.content.res.XmlResourceParser;
6import android.test.AndroidTestCase;
7import android.util.AttributeSet;
8import android.util.Xml;
9import java.io.BufferedReader;
10import java.io.InputStream;
11import java.io.InputStreamReader;
12import java.util.Locale;
13
14public abstract class OverlayBaseTest extends AndroidTestCase {
15    private Resources mResources;
16    protected int mMode; // will be set by subclasses
17    static final protected int MODE_NO_OVERLAY = 0;
18    static final protected int MODE_SINGLE_OVERLAY = 1;
19    static final protected int MODE_MULTIPLE_OVERLAYS = 2;
20
21    protected void setUp() {
22        mResources = getContext().getResources();
23    }
24
25    private int calculateRawResourceChecksum(int resId) throws Throwable {
26        InputStream input = null;
27        try {
28            input = mResources.openRawResource(resId);
29            int ch, checksum = 0;
30            while ((ch = input.read()) != -1) {
31                checksum = (checksum + ch) % 0xffddbb00;
32            }
33            return checksum;
34        } finally {
35            input.close();
36        }
37    }
38
39    private void setLocale(Locale locale) {
40        Locale.setDefault(locale);
41        Configuration config = new Configuration();
42        config.locale = locale;
43        mResources.updateConfiguration(config, mResources.getDisplayMetrics());
44    }
45
46    private boolean getExpected(boolean no, boolean so, boolean mo) {
47        switch (mMode) {
48            case MODE_NO_OVERLAY:
49                return no;
50            case MODE_SINGLE_OVERLAY:
51                return so;
52            case MODE_MULTIPLE_OVERLAYS:
53                return mo;
54            default:
55                fail("Unknown mode!");
56                return no;
57        }
58    }
59
60    private String getExpected(String no, String so, String mo) {
61        switch (mMode) {
62            case MODE_NO_OVERLAY:
63                return no;
64            case MODE_SINGLE_OVERLAY:
65                return so;
66            case MODE_MULTIPLE_OVERLAYS:
67                return mo;
68            default:
69                fail("Unknown mode!");
70                return no;
71        }
72    }
73
74    private int getExpected(int no, int so, int mo) {
75        switch (mMode) {
76            case MODE_NO_OVERLAY:
77                return no;
78            case MODE_SINGLE_OVERLAY:
79                return so;
80            case MODE_MULTIPLE_OVERLAYS:
81                return mo;
82            default:
83                fail("Unknown mode!");
84                return no;
85        }
86    }
87
88    private int[] getExpected(int[] no, int[] so, int[] mo) {
89        switch (mMode) {
90            case MODE_NO_OVERLAY:
91                return no;
92            case MODE_SINGLE_OVERLAY:
93                return so;
94            case MODE_MULTIPLE_OVERLAYS:
95                return mo;
96            default:
97                fail("Unknown mode!");
98                return no;
99        }
100    }
101
102    private void assertResource(int resId, boolean no, boolean so, boolean mo) throws Throwable {
103        boolean expected = getExpected(no, so, mo);
104        boolean actual = mResources.getBoolean(resId);
105        assertEquals(expected, actual);
106    }
107
108    private void assertResource(int resId, int no, int so, int mo) throws Throwable {
109        int expected = getExpected(no, so, mo);
110        int actual = mResources.getInteger(resId);
111        assertEquals(expected, actual);
112    }
113
114    private void assertResource(int resId, String no, String so, String mo) throws Throwable {
115        String expected = getExpected(no, so, mo);
116        String actual = mResources.getString(resId);
117        assertEquals(expected, actual);
118    }
119
120    private void assertResource(int resId, int[] no, int[] so, int[] mo) throws Throwable {
121        int[] expected = getExpected(no, so, mo);
122        int[] actual = mResources.getIntArray(resId);
123        assertEquals("length:", expected.length, actual.length);
124        for (int i = 0; i < actual.length; ++i) {
125            assertEquals("index " + i + ":", actual[i], expected[i]);
126        }
127    }
128
129    public void testFrameworkBooleanOverlay() throws Throwable {
130        // config_annoy_dianne has the value:
131        // - true when no overlay exists (MODE_NO_OVERLAY)
132        // - false when a single overlay exists (MODE_SINGLE_OVERLAY)
133        // - false when multiple overlays exists (MODE_MULTIPLE_OVERLAYS)
134        final int resId = com.android.internal.R.bool.config_annoy_dianne;
135        assertResource(resId, true, false, false);
136    }
137
138    public void testBooleanOverlay() throws Throwable {
139        // usually_false has the value:
140        // - false when no overlay exists (MODE_NO_OVERLAY)
141        // - true when a single overlay exists (MODE_SINGLE_OVERLAY)
142        // - false when multiple overlays exists (MODE_MULTIPLE_OVERLAYS)
143        final int resId = R.bool.usually_false;
144        assertResource(resId, false, true, false);
145    }
146
147    public void testBoolean() throws Throwable {
148        // always_true has no overlay
149        final int resId = R.bool.always_true;
150        assertResource(resId, true, true, true);
151    }
152
153    public void testIntegerArrayOverlay() throws Throwable {
154        // fibonacci has values:
155        // - eight first values of Fibonacci sequence, when no overlay exists (MODE_NO_OVERLAY)
156        // - eight first values of Fibonacci sequence (reversed), for single and multiple overlays
157        //   (MODE_SINGLE_OVERLAY, MODE_MULTIPLE_OVERLAYS)
158        final int resId = R.array.fibonacci;
159        assertResource(resId,
160                new int[]{1, 1, 2, 3, 5, 8, 13, 21},
161                new int[]{21, 13, 8, 5, 3, 2, 1, 1},
162                new int[]{21, 13, 8, 5, 3, 2, 1, 1});
163    }
164
165    public void testIntegerArray() throws Throwable {
166        // prime_numbers has no overlay
167        final int resId = R.array.prime_numbers;
168        final int[] expected = {2, 3, 5, 7, 11, 13, 17, 19};
169        assertResource(resId, expected, expected, expected);
170    }
171
172    public void testDrawable() throws Throwable {
173        // drawable-nodpi/drawable has overlay (default config)
174        final int resId = R.drawable.drawable;
175        int actual = calculateRawResourceChecksum(resId);
176        int expected = 0;
177        switch (mMode) {
178            case MODE_NO_OVERLAY:
179                expected = 0x00005665;
180                break;
181            case MODE_SINGLE_OVERLAY:
182            case MODE_MULTIPLE_OVERLAYS:
183                expected = 0x000051da;
184                break;
185            default:
186                fail("Unknown mode " + mMode);
187        }
188        assertEquals(expected, actual);
189    }
190
191    public void testAppString() throws Throwable {
192        final int resId = R.string.str;
193        assertResource(resId, "none", "single", "multiple");
194    }
195
196    public void testApp2() throws Throwable {
197        final int resId = R.string.str2; // only in base package and first app overlay
198        assertResource(resId, "none", "single", "single");
199    }
200
201    public void testAppXml() throws Throwable {
202        int expected = getExpected(0, 1, 2);
203        int actual = -1;
204        XmlResourceParser parser = mResources.getXml(R.xml.integer);
205        int type = parser.getEventType();
206        while (type != XmlResourceParser.END_DOCUMENT && actual == -1) {
207            if (type == XmlResourceParser.START_TAG && "integer".equals(parser.getName())) {
208                AttributeSet as = Xml.asAttributeSet(parser);
209                actual = as.getAttributeIntValue(null, "value", -1);
210            }
211            type = parser.next();
212        }
213        parser.close();
214        assertEquals(expected, actual);
215    }
216
217    public void testAppRaw() throws Throwable {
218        final int resId = R.raw.lorem_ipsum;
219
220        InputStream input = null;
221        BufferedReader reader = null;
222        String actual = "";
223        try {
224            input = mResources.openRawResource(resId);
225            reader = new BufferedReader(new InputStreamReader(input));
226            actual = reader.readLine();
227        } finally {
228            if (reader != null) {
229                reader.close();
230            }
231            if (input != null) {
232                input.close();
233            }
234        }
235
236        final String no = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, " +
237            "sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. " +
238            "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip " +
239            "ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit " +
240            "esse cillum dolore eu fugiat nulla pariatur. " +
241            "Excepteur sint occaecat cupidatat non proident, " +
242            "sunt in culpa qui officia deserunt mollit anim id est laborum.";
243        final String so = "Lorem ipsum: single overlay.";
244        final String mo = "Lorem ipsum: multiple overlays.";
245
246        assertEquals(getExpected(no, so, mo), actual);
247    }
248
249    /*
250     * testMatrix* tests
251     *
252     * The naming convention textMatrixABCDEF refers to in which packages and
253     * which configurations a resource is defined (1 if the resource is
254     * defined). If defined, a slot is always given the same value.
255     *
256     * SLOT  PACKAGE           CONFIGURATION  VALUE
257     * A     target package    (default)      100
258     * B     target package    -sv            200
259     * C     OverlayAppFirst   (default)      300
260     * D     OverlayAppFirst   -sv            400
261     * E     OverlayAppSecond  (default)      500
262     * F     OverlayAppSecond  -sv            600
263     *
264     * Example: in testMatrix101110, the base package defines the
265     * R.integer.matrix101110 resource for the default configuration (value
266     * 100), OverlayAppFirst defines it for both default and Swedish
267     * configurations (values 300 and 400, respectively), and OverlayAppSecond
268     * defines it for the default configuration (value 500). If both overlays
269     * are loaded, the expected value after setting the language to Swedish is
270     * 400.
271     */
272    public void testMatrix100000() throws Throwable {
273        final int resId = R.integer.matrix_100000;
274        setLocale(new Locale("sv", "SE"));
275        assertResource(resId, 100, 100, 100);
276    }
277
278    public void testMatrix100001() throws Throwable {
279        final int resId = R.integer.matrix_100001;
280        setLocale(new Locale("sv", "SE"));
281        assertResource(resId, 100, 100, 600);
282    }
283
284    public void testMatrix100010() throws Throwable {
285        final int resId = R.integer.matrix_100010;
286        setLocale(new Locale("sv", "SE"));
287        assertResource(resId, 100, 100, 500);
288    }
289
290    public void testMatrix100011() throws Throwable {
291        final int resId = R.integer.matrix_100011;
292        setLocale(new Locale("sv", "SE"));
293        assertResource(resId, 100, 100, 600);
294    }
295
296    public void testMatrix100100() throws Throwable {
297        final int resId = R.integer.matrix_100100;
298        setLocale(new Locale("sv", "SE"));
299        assertResource(resId, 100, 400, 400);
300    }
301
302    public void testMatrix100101() throws Throwable {
303        final int resId = R.integer.matrix_100101;
304        setLocale(new Locale("sv", "SE"));
305        assertResource(resId, 100, 400, 600);
306    }
307
308    public void testMatrix100110() throws Throwable {
309        final int resId = R.integer.matrix_100110;
310        setLocale(new Locale("sv", "SE"));
311        assertResource(resId, 100, 400, 400);
312    }
313
314    public void testMatrix100111() throws Throwable {
315        final int resId = R.integer.matrix_100111;
316        setLocale(new Locale("sv", "SE"));
317        assertResource(resId, 100, 400, 600);
318    }
319
320    public void testMatrix101000() throws Throwable {
321        final int resId = R.integer.matrix_101000;
322        setLocale(new Locale("sv", "SE"));
323        assertResource(resId, 100, 300, 300);
324    }
325
326    public void testMatrix101001() throws Throwable {
327        final int resId = R.integer.matrix_101001;
328        setLocale(new Locale("sv", "SE"));
329        assertResource(resId, 100, 300, 600);
330    }
331
332    public void testMatrix101010() throws Throwable {
333        final int resId = R.integer.matrix_101010;
334        setLocale(new Locale("sv", "SE"));
335        assertResource(resId, 100, 300, 500);
336    }
337
338    public void testMatrix101011() throws Throwable {
339        final int resId = R.integer.matrix_101011;
340        setLocale(new Locale("sv", "SE"));
341        assertResource(resId, 100, 300, 600);
342    }
343
344    public void testMatrix101100() throws Throwable {
345        final int resId = R.integer.matrix_101100;
346        setLocale(new Locale("sv", "SE"));
347        assertResource(resId, 100, 400, 400);
348    }
349
350    public void testMatrix101101() throws Throwable {
351        final int resId = R.integer.matrix_101101;
352        setLocale(new Locale("sv", "SE"));
353        assertResource(resId, 100, 400, 600);
354    }
355
356    public void testMatrix101110() throws Throwable {
357        final int resId = R.integer.matrix_101110;
358        setLocale(new Locale("sv", "SE"));
359        assertResource(resId, 100, 400, 400);
360    }
361
362    public void testMatrix101111() throws Throwable {
363        final int resId = R.integer.matrix_101111;
364        setLocale(new Locale("sv", "SE"));
365        assertResource(resId, 100, 400, 600);
366    }
367
368    public void testMatrix110000() throws Throwable {
369        final int resId = R.integer.matrix_110000;
370        setLocale(new Locale("sv", "SE"));
371        assertResource(resId, 200, 200, 200);
372    }
373
374    public void testMatrix110001() throws Throwable {
375        final int resId = R.integer.matrix_110001;
376        setLocale(new Locale("sv", "SE"));
377        assertResource(resId, 200, 200, 600);
378    }
379
380    public void testMatrix110010() throws Throwable {
381        final int resId = R.integer.matrix_110010;
382        setLocale(new Locale("sv", "SE"));
383        assertResource(resId, 200, 200, 200);
384    }
385
386    public void testMatrix110011() throws Throwable {
387        final int resId = R.integer.matrix_110011;
388        setLocale(new Locale("sv", "SE"));
389        assertResource(resId, 200, 200, 600);
390    }
391
392    public void testMatrix110100() throws Throwable {
393        final int resId = R.integer.matrix_110100;
394        setLocale(new Locale("sv", "SE"));
395        assertResource(resId, 200, 400, 400);
396    }
397
398    public void testMatrix110101() throws Throwable {
399        final int resId = R.integer.matrix_110101;
400        setLocale(new Locale("sv", "SE"));
401        assertResource(resId, 200, 400, 600);
402    }
403
404    public void testMatrix110110() throws Throwable {
405        final int resId = R.integer.matrix_110110;
406        setLocale(new Locale("sv", "SE"));
407        assertResource(resId, 200, 400, 400);
408    }
409
410    public void testMatrix110111() throws Throwable {
411        final int resId = R.integer.matrix_110111;
412        setLocale(new Locale("sv", "SE"));
413        assertResource(resId, 200, 400, 600);
414    }
415
416    public void testMatrix111000() throws Throwable {
417        final int resId = R.integer.matrix_111000;
418        setLocale(new Locale("sv", "SE"));
419        assertResource(resId, 200, 200, 200);
420    }
421
422    public void testMatrix111001() throws Throwable {
423        final int resId = R.integer.matrix_111001;
424        setLocale(new Locale("sv", "SE"));
425        assertResource(resId, 200, 200, 600);
426    }
427
428    public void testMatrix111010() throws Throwable {
429        final int resId = R.integer.matrix_111010;
430        setLocale(new Locale("sv", "SE"));
431        assertResource(resId, 200, 200, 200);
432    }
433
434    public void testMatrix111011() throws Throwable {
435        final int resId = R.integer.matrix_111011;
436        setLocale(new Locale("sv", "SE"));
437        assertResource(resId, 200, 200, 600);
438    }
439
440    public void testMatrix111100() throws Throwable {
441        final int resId = R.integer.matrix_111100;
442        setLocale(new Locale("sv", "SE"));
443        assertResource(resId, 200, 400, 400);
444    }
445
446    public void testMatrix111101() throws Throwable {
447        final int resId = R.integer.matrix_111101;
448        setLocale(new Locale("sv", "SE"));
449        assertResource(resId, 200, 400, 600);
450    }
451
452    public void testMatrix111110() throws Throwable {
453        final int resId = R.integer.matrix_111110;
454        setLocale(new Locale("sv", "SE"));
455        assertResource(resId, 200, 400, 400);
456    }
457
458    public void testMatrix111111() throws Throwable {
459        final int resId = R.integer.matrix_111111;
460        setLocale(new Locale("sv", "SE"));
461        assertResource(resId, 200, 400, 600);
462    }
463}
464