1/*
2 * Copyright (C) 2014 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
17package android.content.res;
18
19import android.test.ActivityInstrumentationTestCase2;
20import android.test.suitebuilder.annotation.SmallTest;
21import android.util.TypedValue;
22
23import com.android.frameworks.coretests.R;
24
25import java.lang.reflect.InvocationTargetException;
26
27public class ConfigurationBoundResourceCacheTest
28        extends ActivityInstrumentationTestCase2<ResourceCacheActivity> {
29
30    ConfigurationBoundResourceCache<Float> mCache;
31
32    public ConfigurationBoundResourceCacheTest() {
33        super(ResourceCacheActivity.class);
34    }
35
36    @Override
37    protected void setUp() throws Exception {
38        super.setUp();
39        mCache = new ConfigurationBoundResourceCache<>();
40    }
41
42    @SmallTest
43    public void testGetEmpty() {
44        final Resources res = getActivity().getResources();
45        assertNull(mCache.getInstance(-1, res, null));
46    }
47
48    @SmallTest
49    public void testSetGet() {
50        mCache.put(1, null, new DummyFloatConstantState(5f));
51        final Resources res = getActivity().getResources();
52        assertEquals(5f, mCache.getInstance(1, res, null));
53        assertNotSame(5f, mCache.getInstance(1, res, null));
54        assertEquals(null, mCache.getInstance(1, res, getActivity().getTheme()));
55    }
56
57    @SmallTest
58    public void testSetGetThemed() {
59        mCache.put(1, getActivity().getTheme(), new DummyFloatConstantState(5f));
60        final Resources res = getActivity().getResources();
61        assertEquals(null, mCache.getInstance(1, res, null));
62        assertEquals(5f, mCache.getInstance(1, res, getActivity().getTheme()));
63        assertNotSame(5f, mCache.getInstance(1, res, getActivity().getTheme()));
64    }
65
66    @SmallTest
67    public void testMultiThreadPutGet() {
68        mCache.put(1, getActivity().getTheme(), new DummyFloatConstantState(5f));
69        mCache.put(1, null, new DummyFloatConstantState(10f));
70        final Resources res = getActivity().getResources();
71        assertEquals(10f, mCache.getInstance(1, res, null));
72        assertNotSame(10f, mCache.getInstance(1, res, null));
73        assertEquals(5f, mCache.getInstance(1, res, getActivity().getTheme()));
74        assertNotSame(5f, mCache.getInstance(1, res, getActivity().getTheme()));
75    }
76
77    @SmallTest
78    public void testVoidConfigChange()
79            throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
80        TypedValue staticValue = new TypedValue();
81        long key = 3L;
82        final Resources res = getActivity().getResources();
83        res.getValue(R.dimen.resource_cache_test_generic, staticValue, true);
84        float staticDim = TypedValue.complexToDimension(staticValue.data, res.getDisplayMetrics());
85        mCache.put(key, getActivity().getTheme(),
86                new DummyFloatConstantState(staticDim, staticValue.changingConfigurations));
87        final Configuration cfg = res.getConfiguration();
88        Configuration newCnf = new Configuration(cfg);
89        newCnf.orientation = cfg.orientation == Configuration.ORIENTATION_LANDSCAPE ?
90                Configuration.ORIENTATION_PORTRAIT
91                : Configuration.ORIENTATION_LANDSCAPE;
92        int changes = calcConfigChanges(res, newCnf);
93        assertEquals(staticDim, mCache.getInstance(key, res, getActivity().getTheme()));
94        mCache.onConfigurationChange(changes);
95        assertEquals(staticDim, mCache.getInstance(key, res, getActivity().getTheme()));
96    }
97
98    @SmallTest
99    public void testEffectiveConfigChange()
100            throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
101        TypedValue changingValue = new TypedValue();
102        long key = 4L;
103        final Resources res = getActivity().getResources();
104        res.getValue(R.dimen.resource_cache_test_orientation_dependent, changingValue, true);
105        float changingDim = TypedValue.complexToDimension(changingValue.data,
106                res.getDisplayMetrics());
107        mCache.put(key, getActivity().getTheme(),
108                new DummyFloatConstantState(changingDim, changingValue.changingConfigurations));
109
110        final Configuration cfg = res.getConfiguration();
111        Configuration newCnf = new Configuration(cfg);
112        newCnf.orientation = cfg.orientation == Configuration.ORIENTATION_LANDSCAPE ?
113                Configuration.ORIENTATION_PORTRAIT
114                : Configuration.ORIENTATION_LANDSCAPE;
115        int changes = calcConfigChanges(res, newCnf);
116        assertEquals(changingDim, mCache.getInstance(key, res, getActivity().getTheme()));
117        mCache.onConfigurationChange(changes);
118        assertNull(mCache.get(key, getActivity().getTheme()));
119    }
120
121    @SmallTest
122    public void testConfigChangeMultipleResources()
123            throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
124        TypedValue staticValue = new TypedValue();
125        TypedValue changingValue = new TypedValue();
126        final Resources res = getActivity().getResources();
127        res.getValue(R.dimen.resource_cache_test_generic, staticValue, true);
128        res.getValue(R.dimen.resource_cache_test_orientation_dependent, changingValue, true);
129        float staticDim = TypedValue.complexToDimension(staticValue.data, res.getDisplayMetrics());
130        float changingDim = TypedValue.complexToDimension(changingValue.data,
131                res.getDisplayMetrics());
132        mCache.put(R.dimen.resource_cache_test_generic, getActivity().getTheme(),
133                new DummyFloatConstantState(staticDim, staticValue.changingConfigurations));
134        mCache.put(R.dimen.resource_cache_test_orientation_dependent, getActivity().getTheme(),
135                new DummyFloatConstantState(changingDim, changingValue.changingConfigurations));
136        final Configuration cfg = res.getConfiguration();
137        Configuration newCnf = new Configuration(cfg);
138        newCnf.orientation = cfg.orientation == Configuration.ORIENTATION_LANDSCAPE ?
139                Configuration.ORIENTATION_PORTRAIT
140                : Configuration.ORIENTATION_LANDSCAPE;
141        int changes = calcConfigChanges(res, newCnf);
142        assertEquals(staticDim, mCache.getInstance(R.dimen.resource_cache_test_generic, res,
143                getActivity().getTheme()));
144        assertEquals(changingDim,
145                mCache.getInstance(R.dimen.resource_cache_test_orientation_dependent, res,
146                        getActivity().getTheme()));
147        mCache.onConfigurationChange(changes);
148        assertEquals(staticDim, mCache.getInstance(R.dimen.resource_cache_test_generic, res,
149                getActivity().getTheme()));
150        assertNull(mCache.getInstance(R.dimen.resource_cache_test_orientation_dependent, res,
151                getActivity().getTheme()));
152    }
153
154    @SmallTest
155    public void testConfigChangeMultipleThemes()
156            throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
157        TypedValue[] staticValues = new TypedValue[]{new TypedValue(), new TypedValue()};
158        TypedValue[] changingValues = new TypedValue[]{new TypedValue(), new TypedValue()};
159        float staticDim = 0;
160        float changingDim = 0;
161        final Resources res = getActivity().getResources();
162        for (int i = 0; i < 2; i++) {
163            res.getValue(R.dimen.resource_cache_test_generic, staticValues[i], true);
164            staticDim = TypedValue
165                    .complexToDimension(staticValues[i].data, res.getDisplayMetrics());
166
167            res.getValue(R.dimen.resource_cache_test_orientation_dependent, changingValues[i],
168                    true);
169            changingDim = TypedValue.complexToDimension(changingValues[i].data,
170                    res.getDisplayMetrics());
171            final Resources.Theme theme = i == 0 ? getActivity().getTheme() : null;
172            mCache.put(R.dimen.resource_cache_test_generic, theme,
173                    new DummyFloatConstantState(staticDim, staticValues[i].changingConfigurations));
174            mCache.put(R.dimen.resource_cache_test_orientation_dependent, theme,
175                    new DummyFloatConstantState(changingDim,
176                            changingValues[i].changingConfigurations));
177        }
178        final Configuration cfg = res.getConfiguration();
179        Configuration newCnf = new Configuration(cfg);
180        newCnf.orientation = cfg.orientation == Configuration.ORIENTATION_LANDSCAPE ?
181                Configuration.ORIENTATION_PORTRAIT
182                : Configuration.ORIENTATION_LANDSCAPE;
183        int changes = calcConfigChanges(res, newCnf);
184        for (int i = 0; i < 2; i++) {
185            final Resources.Theme theme = i == 0 ? getActivity().getTheme() : null;
186            assertEquals(staticDim,
187                    mCache.getInstance(R.dimen.resource_cache_test_generic, res, theme));
188            assertEquals(changingDim,
189                    mCache.getInstance(R.dimen.resource_cache_test_orientation_dependent, res,
190                            theme));
191        }
192        mCache.onConfigurationChange(changes);
193        for (int i = 0; i < 2; i++) {
194            final Resources.Theme theme = i == 0 ? getActivity().getTheme() : null;
195            assertEquals(staticDim,
196                    mCache.getInstance(R.dimen.resource_cache_test_generic, res, theme));
197            assertNull(mCache.getInstance(R.dimen.resource_cache_test_orientation_dependent, res,
198                    theme));
199        }
200    }
201
202    private static int calcConfigChanges(Resources resources, Configuration configuration) {
203        return resources.calcConfigChanges(configuration);
204    }
205
206    static class DummyFloatConstantState extends ConstantState<Float> {
207
208        final Float mObj;
209
210        int mChangingConf = 0;
211
212        DummyFloatConstantState(Float obj) {
213            mObj = obj;
214        }
215
216        DummyFloatConstantState(Float obj, int changingConf) {
217            mObj = obj;
218            mChangingConf = changingConf;
219        }
220
221        @Override
222        public int getChangingConfigurations() {
223            return mChangingConf;
224        }
225
226        @Override
227        public Float newInstance() {
228            return new Float(mObj);
229        }
230    }
231}
232