ResourcesCompatTest.java revision f2b8aa644529539d113e87cbaf0e21e49a70fac3
1/*
2 * Copyright (C) 2015 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 */
16package android.support.v4.content.res;
17
18import static org.junit.Assert.assertEquals;
19import static org.junit.Assert.assertNotNull;
20import static org.junit.Assert.assertNotSame;
21import static org.junit.Assert.assertNull;
22import static org.junit.Assert.assertSame;
23
24import android.content.Context;
25import android.content.res.ColorStateList;
26import android.content.res.Resources;
27import android.graphics.Typeface;
28import android.graphics.drawable.Drawable;
29import android.os.Build;
30import android.support.compat.test.R;
31import android.support.test.InstrumentationRegistry;
32import android.support.test.filters.SmallTest;
33import android.support.v4.testutils.TestUtils;
34import android.util.DisplayMetrics;
35
36import org.junit.Before;
37import org.junit.Test;
38
39@SmallTest
40public class ResourcesCompatTest {
41    private Context mContext;
42    private Resources mResources;
43
44    @Before
45    public void setup() {
46        mContext = InstrumentationRegistry.getContext();
47        mResources = mContext.getResources();
48    }
49
50    @Test
51    public void testGetColor() throws Throwable {
52        assertEquals("Unthemed color load",
53                ResourcesCompat.getColor(mResources, R.color.text_color, null),
54                0xFFFF8090);
55
56        if (Build.VERSION.SDK_INT >= 23) {
57            // The following tests are only expected to pass on v23+ devices. The result of
58            // calling theme-aware getColor() in pre-v23 is undefined.
59            final Resources.Theme yellowTheme = mResources.newTheme();
60            yellowTheme.applyStyle(R.style.YellowTheme, true);
61            assertEquals("Themed yellow color load", 0xFFF0B000,
62                    ResourcesCompat.getColor(mResources, R.color.simple_themed_selector,
63                            yellowTheme));
64
65            final Resources.Theme lilacTheme = mResources.newTheme();
66            lilacTheme.applyStyle(R.style.LilacTheme, true);
67            assertEquals("Themed lilac color load", 0xFFF080F0,
68                    ResourcesCompat.getColor(mResources, R.color.simple_themed_selector,
69                            lilacTheme));
70        }
71    }
72
73    @Test
74    public void testGetColorStateList() throws Throwable {
75        final ColorStateList unthemedColorStateList =
76                ResourcesCompat.getColorStateList(mResources, R.color.complex_unthemed_selector,
77                        null);
78        assertEquals("Unthemed color state list load: default", 0xFF70A0C0,
79                unthemedColorStateList.getDefaultColor());
80        assertEquals("Unthemed color state list load: focused", 0xFF70B0F0,
81                unthemedColorStateList.getColorForState(
82                        new int[]{android.R.attr.state_focused}, 0));
83        assertEquals("Unthemed color state list load: pressed", 0xFF6080B0,
84                unthemedColorStateList.getColorForState(
85                        new int[]{android.R.attr.state_pressed}, 0));
86
87        if (Build.VERSION.SDK_INT >= 23) {
88            // The following tests are only expected to pass on v23+ devices. The result of
89            // calling theme-aware getColorStateList() in pre-v23 is undefined.
90            final Resources.Theme yellowTheme = mResources.newTheme();
91            yellowTheme.applyStyle(R.style.YellowTheme, true);
92            final ColorStateList themedYellowColorStateList =
93                    ResourcesCompat.getColorStateList(mResources, R.color.complex_themed_selector,
94                            yellowTheme);
95            assertEquals("Themed yellow color state list load: default", 0xFFF0B000,
96                    themedYellowColorStateList.getDefaultColor());
97            assertEquals("Themed yellow color state list load: focused", 0xFFF0A020,
98                    themedYellowColorStateList.getColorForState(
99                            new int[]{android.R.attr.state_focused}, 0));
100            assertEquals("Themed yellow color state list load: pressed", 0xFFE0A040,
101                    themedYellowColorStateList.getColorForState(
102                            new int[]{android.R.attr.state_pressed}, 0));
103
104            final Resources.Theme lilacTheme = mResources.newTheme();
105            lilacTheme.applyStyle(R.style.LilacTheme, true);
106            final ColorStateList themedLilacColorStateList =
107                    ResourcesCompat.getColorStateList(mResources, R.color.complex_themed_selector,
108                            lilacTheme);
109            assertEquals("Themed lilac color state list load: default", 0xFFF080F0,
110                    themedLilacColorStateList.getDefaultColor());
111            assertEquals("Themed lilac color state list load: focused", 0xFFF070D0,
112                    themedLilacColorStateList.getColorForState(
113                            new int[]{android.R.attr.state_focused}, 0));
114            assertEquals("Themed lilac color state list load: pressed", 0xFFE070A0,
115                    themedLilacColorStateList.getColorForState(
116                            new int[]{android.R.attr.state_pressed}, 0));
117        }
118    }
119
120    @Test
121    public void testGetDrawable() throws Throwable {
122        final Drawable unthemedDrawable =
123                ResourcesCompat.getDrawable(mResources, R.drawable.test_drawable_red, null);
124        TestUtils.assertAllPixelsOfColor("Unthemed drawable load",
125                unthemedDrawable, mResources.getColor(R.color.test_red));
126
127        if (Build.VERSION.SDK_INT >= 23) {
128            // The following tests are only expected to pass on v23+ devices. The result of
129            // calling theme-aware getDrawable() in pre-v23 is undefined.
130            final Resources.Theme yellowTheme = mResources.newTheme();
131            yellowTheme.applyStyle(R.style.YellowTheme, true);
132            final Drawable themedYellowDrawable =
133                    ResourcesCompat.getDrawable(mResources, R.drawable.themed_drawable,
134                            yellowTheme);
135            TestUtils.assertAllPixelsOfColor("Themed yellow drawable load",
136                    themedYellowDrawable, 0xFFF0B000);
137
138            final Resources.Theme lilacTheme = mResources.newTheme();
139            lilacTheme.applyStyle(R.style.LilacTheme, true);
140            final Drawable themedLilacDrawable =
141                    ResourcesCompat.getDrawable(mResources, R.drawable.themed_drawable, lilacTheme);
142            TestUtils.assertAllPixelsOfColor("Themed lilac drawable load",
143                    themedLilacDrawable, 0xFFF080F0);
144        }
145    }
146
147    @Test
148    public void testGetDrawableForDensityUnthemed() throws Throwable {
149        // Density-aware drawable loading for now only works on raw bitmap drawables.
150
151        // Different variants of density_aware_drawable are set up in the following way:
152        //    mdpi - 12x12 px which is 12x12 dip
153        //    hdpi - 21x21 px which is 14x14 dip
154        //   xhdpi - 32x32 px which is 16x16 dip
155        //  xxhdpi - 54x54 px which is 18x18 dip
156        // The tests below (on v15+ devices) are checking that an unthemed density-aware
157        // loading of raw bitmap drawables returns a drawable with matching intrinsic
158        // dimensions.
159
160        final Drawable unthemedDrawableForMediumDensity =
161                ResourcesCompat.getDrawableForDensity(mResources, R.drawable.density_aware_drawable,
162                        DisplayMetrics.DENSITY_MEDIUM, null);
163        // For pre-v15 devices we should get a drawable that corresponds to the density of the
164        // current device. For v15+ devices we should get a drawable that corresponds to the
165        // density requested in the API call.
166        final int expectedSizeForMediumDensity = (Build.VERSION.SDK_INT < 15) ?
167                mResources.getDimensionPixelSize(R.dimen.density_aware_size) : 12;
168        assertEquals("Unthemed density-aware drawable load: medium width",
169                expectedSizeForMediumDensity, unthemedDrawableForMediumDensity.getIntrinsicWidth());
170        assertEquals("Unthemed density-aware drawable load: medium height",
171                expectedSizeForMediumDensity,
172                unthemedDrawableForMediumDensity.getIntrinsicHeight());
173
174        final Drawable unthemedDrawableForHighDensity =
175                ResourcesCompat.getDrawableForDensity(mResources, R.drawable.density_aware_drawable,
176                        DisplayMetrics.DENSITY_HIGH, null);
177        // For pre-v15 devices we should get a drawable that corresponds to the density of the
178        // current device. For v15+ devices we should get a drawable that corresponds to the
179        // density requested in the API call.
180        final int expectedSizeForHighDensity = (Build.VERSION.SDK_INT < 15) ?
181                mResources.getDimensionPixelSize(R.dimen.density_aware_size) : 21;
182        assertEquals("Unthemed density-aware drawable load: high width",
183                expectedSizeForHighDensity, unthemedDrawableForHighDensity.getIntrinsicWidth());
184        assertEquals("Unthemed density-aware drawable load: high height",
185                expectedSizeForHighDensity, unthemedDrawableForHighDensity.getIntrinsicHeight());
186
187        final Drawable unthemedDrawableForXHighDensity =
188                ResourcesCompat.getDrawableForDensity(mResources, R.drawable.density_aware_drawable,
189                        DisplayMetrics.DENSITY_XHIGH, null);
190        // For pre-v15 devices we should get a drawable that corresponds to the density of the
191        // current device. For v15+ devices we should get a drawable that corresponds to the
192        // density requested in the API call.
193        final int expectedSizeForXHighDensity = (Build.VERSION.SDK_INT < 15) ?
194                mResources.getDimensionPixelSize(R.dimen.density_aware_size) : 32;
195        assertEquals("Unthemed density-aware drawable load: xhigh width",
196                expectedSizeForXHighDensity, unthemedDrawableForXHighDensity.getIntrinsicWidth());
197        assertEquals("Unthemed density-aware drawable load: xhigh height",
198                expectedSizeForXHighDensity, unthemedDrawableForXHighDensity.getIntrinsicHeight());
199
200        final Drawable unthemedDrawableForXXHighDensity =
201                ResourcesCompat.getDrawableForDensity(mResources, R.drawable.density_aware_drawable,
202                        DisplayMetrics.DENSITY_XXHIGH, null);
203        // For pre-v15 devices we should get a drawable that corresponds to the density of the
204        // current device. For v15+ devices we should get a drawable that corresponds to the
205        // density requested in the API call.
206        final int expectedSizeForXXHighDensity = (Build.VERSION.SDK_INT < 15) ?
207                mResources.getDimensionPixelSize(R.dimen.density_aware_size) : 54;
208        assertEquals("Unthemed density-aware drawable load: xxhigh width",
209                expectedSizeForXXHighDensity, unthemedDrawableForXXHighDensity.getIntrinsicWidth());
210        assertEquals("Unthemed density-aware drawable load: xxhigh height",
211                expectedSizeForXXHighDensity,
212                unthemedDrawableForXXHighDensity.getIntrinsicHeight());
213    }
214
215    @Test
216    public void testGetDrawableForDensityThemed() throws Throwable {
217        if (Build.VERSION.SDK_INT < 21) {
218            // The following tests are only expected to pass on v21+ devices. The result of
219            // calling theme-aware getDrawableForDensity() in pre-v21 is undefined.
220            return;
221        }
222
223        // Density- and theme-aware drawable loading for now only works partially. This test
224        // checks only for theming of a tinted bitmap XML drawable, but not correct scaling.
225
226        // Set up the two test themes, yellow and lilac.
227        final Resources.Theme yellowTheme = mResources.newTheme();
228        yellowTheme.applyStyle(R.style.YellowTheme, true);
229
230        final Resources.Theme lilacTheme = mResources.newTheme();
231        lilacTheme.applyStyle(R.style.LilacTheme, true);
232
233        Drawable themedYellowDrawableForMediumDensity =
234                ResourcesCompat.getDrawableForDensity(mResources, R.drawable.themed_bitmap,
235                        DisplayMetrics.DENSITY_MEDIUM, yellowTheme);
236        // We should get a drawable that corresponds to the theme requested in the API call.
237        TestUtils.assertAllPixelsOfColor("Themed yellow density-aware drawable load : medium color",
238                themedYellowDrawableForMediumDensity, 0xFFF0B000);
239
240        Drawable themedLilacDrawableForMediumDensity =
241                ResourcesCompat.getDrawableForDensity(mResources, R.drawable.themed_bitmap,
242                        DisplayMetrics.DENSITY_MEDIUM, lilacTheme);
243        // We should get a drawable that corresponds to the theme requested in the API call.
244        TestUtils.assertAllPixelsOfColor("Themed lilac density-aware drawable load : medium color",
245                themedLilacDrawableForMediumDensity, 0xFFF080F0);
246
247        Drawable themedYellowDrawableForHighDensity =
248                ResourcesCompat.getDrawableForDensity(mResources, R.drawable.themed_bitmap,
249                        DisplayMetrics.DENSITY_HIGH, yellowTheme);
250        // We should get a drawable that corresponds to the theme requested in the API call.
251        TestUtils.assertAllPixelsOfColor("Themed yellow density-aware drawable load : high color",
252                themedYellowDrawableForHighDensity, 0xFFF0B000);
253
254        Drawable themedLilacDrawableForHighDensity =
255                ResourcesCompat.getDrawableForDensity(mResources, R.drawable.themed_bitmap,
256                        DisplayMetrics.DENSITY_HIGH, lilacTheme);
257        // We should get a drawable that corresponds to the theme requested in the API call.
258        TestUtils.assertAllPixelsOfColor("Themed lilac density-aware drawable load : high color",
259                themedLilacDrawableForHighDensity, 0xFFF080F0);
260
261        Drawable themedYellowDrawableForXHighDensity =
262                ResourcesCompat.getDrawableForDensity(mResources, R.drawable.themed_bitmap,
263                        DisplayMetrics.DENSITY_XHIGH, yellowTheme);
264        // We should get a drawable that corresponds to the theme requested in the API call.
265        TestUtils.assertAllPixelsOfColor("Themed yellow density-aware drawable load : xhigh color",
266                themedYellowDrawableForXHighDensity, 0xFFF0B000);
267
268        Drawable themedLilacDrawableForXHighDensity =
269                ResourcesCompat.getDrawableForDensity(mResources, R.drawable.themed_bitmap,
270                        DisplayMetrics.DENSITY_XHIGH, lilacTheme);
271        // We should get a drawable that corresponds to the theme requested in the API call.
272        TestUtils.assertAllPixelsOfColor("Themed lilac density-aware drawable load : xhigh color",
273                themedLilacDrawableForXHighDensity, 0xFFF080F0);
274
275        Drawable themedYellowDrawableForXXHighDensity =
276                ResourcesCompat.getDrawableForDensity(mResources, R.drawable.themed_bitmap,
277                        DisplayMetrics.DENSITY_XXHIGH, yellowTheme);
278        // We should get a drawable that corresponds to the theme requested in the API call.
279        TestUtils.assertAllPixelsOfColor("Themed yellow density-aware drawable load : xxhigh color",
280                themedYellowDrawableForXXHighDensity, 0xFFF0B000);
281
282        Drawable themedLilacDrawableForXXHighDensity =
283                ResourcesCompat.getDrawableForDensity(mResources, R.drawable.themed_bitmap,
284                        DisplayMetrics.DENSITY_XXHIGH, lilacTheme);
285        // We should get a drawable that corresponds to the theme requested in the API call.
286        TestUtils.assertAllPixelsOfColor("Themed lilac density-aware drawable load : xxhigh color",
287                themedLilacDrawableForXXHighDensity, 0xFFF080F0);
288    }
289
290    @Test(expected = Resources.NotFoundException.class)
291    public void testGetFont_invalidResourceId() {
292        ResourcesCompat.getFont(mContext, -1);
293    }
294
295    @Test
296    public void testGetFont_fontFile() {
297        Typeface font = ResourcesCompat.getFont(mContext, R.font.samplefont);
298
299        assertNotNull(font);
300        assertNotSame(Typeface.DEFAULT, font);
301    }
302
303    @Test
304    public void testGetFont_xmlFile() {
305        Typeface font = ResourcesCompat.getFont(mContext, R.font.samplexmlfont);
306
307        assertNotNull(font);
308        assertNotSame(Typeface.DEFAULT, font);
309    }
310
311    @Test
312    public void testGetFont_invalidXmlFile() {
313        try {
314            assertNull(
315                    ResourcesCompat.getFont(mContext, R.font.invalid_xmlfamily));
316        } catch (Resources.NotFoundException e) {
317            // pass
318        }
319
320        try {
321            assertNull(ResourcesCompat.getFont(mContext, R.font.invalid_xmlempty));
322        } catch (Resources.NotFoundException e) {
323            // pass
324        }
325    }
326
327    @Test
328    public void testGetFont_fontFileIsCached() {
329        Typeface font = ResourcesCompat.getFont(mContext, R.font.samplefont);
330        Typeface font2 = ResourcesCompat.getFont(mContext, R.font.samplefont);
331
332        assertSame(font, font2);
333    }
334
335    @Test
336    public void testGetFont_xmlFileIsCached() {
337        Typeface font = ResourcesCompat.getFont(mContext, R.font.samplexmlfont);
338        Typeface font2 = ResourcesCompat.getFont(mContext, R.font.samplexmlfont);
339
340        assertSame(font, font2);
341    }
342}
343