ConfigurationContainerTests.java revision 1779e6108ab264689b7d5e5c42ba3cbca6c8189f
1/*
2 * Copyright (C) 2016 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 com.android.server.am;
18
19
20import org.junit.Test;
21import org.junit.runner.RunWith;
22
23import android.content.res.Configuration;
24import android.platform.test.annotations.Presubmit;
25import android.support.test.filters.SmallTest;
26import android.support.test.runner.AndroidJUnit4;
27
28import java.util.ArrayList;
29import java.util.List;
30
31import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
32import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
33import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
34import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
35import static org.junit.Assert.assertEquals;
36
37/**
38 * Test class for {@link ConfigurationContainer}. Mostly duplicates configuration tests from
39 * {@link com.android.server.wm.WindowContainerTests}.
40 *
41 * Build: mmma -j32 frameworks/base/services/tests/servicestests
42 * Install: adb install -r out/target/product/$TARGET_PRODUCT/data/app/FrameworksServicesTests/FrameworksServicesTests.apk
43 * Run: adb shell am instrument -w -e class com.android.server.am.ConfigurationContainerTests com.android.frameworks.servicestests/android.support.test.runner.AndroidJUnitRunner
44 */
45@SmallTest
46@Presubmit
47@RunWith(AndroidJUnit4.class)
48public class ConfigurationContainerTests {
49
50    @Test
51    public void testConfigurationInit() throws Exception {
52        // Check root container initial config.
53        final TestConfigurationContainer root = new TestConfigurationContainer();
54        assertEquals(Configuration.EMPTY, root.getOverrideConfiguration());
55        assertEquals(Configuration.EMPTY, root.getMergedOverrideConfiguration());
56        assertEquals(Configuration.EMPTY, root.getConfiguration());
57
58        // Check child initial config.
59        final TestConfigurationContainer child1 = root.addChild();
60        assertEquals(Configuration.EMPTY, child1.getOverrideConfiguration());
61        assertEquals(Configuration.EMPTY, child1.getMergedOverrideConfiguration());
62        assertEquals(Configuration.EMPTY, child1.getConfiguration());
63
64        // Check child initial config if root has overrides.
65        final Configuration rootOverrideConfig = new Configuration();
66        rootOverrideConfig.fontScale = 1.3f;
67        root.onOverrideConfigurationChanged(rootOverrideConfig);
68        final TestConfigurationContainer child2 = root.addChild();
69        assertEquals(Configuration.EMPTY, child2.getOverrideConfiguration());
70        assertEquals(rootOverrideConfig, child2.getMergedOverrideConfiguration());
71        assertEquals(rootOverrideConfig, child2.getConfiguration());
72
73        // Check child initial config if root has parent config set.
74        final Configuration rootParentConfig = new Configuration();
75        rootParentConfig.fontScale = 0.8f;
76        rootParentConfig.orientation = SCREEN_ORIENTATION_LANDSCAPE;
77        root.onConfigurationChanged(rootParentConfig);
78        final Configuration rootFullConfig = new Configuration(rootParentConfig);
79        rootFullConfig.updateFrom(rootOverrideConfig);
80
81        final TestConfigurationContainer child3 = root.addChild();
82        assertEquals(Configuration.EMPTY, child3.getOverrideConfiguration());
83        assertEquals(rootOverrideConfig, child3.getMergedOverrideConfiguration());
84        assertEquals(rootFullConfig, child3.getConfiguration());
85    }
86
87    @Test
88    public void testConfigurationChangeOnAddRemove() throws Exception {
89        // Init root's config.
90        final TestConfigurationContainer root = new TestConfigurationContainer();
91        final Configuration rootOverrideConfig = new Configuration();
92        rootOverrideConfig.fontScale = 1.3f;
93        root.onOverrideConfigurationChanged(rootOverrideConfig);
94
95        // Init child's config.
96        final TestConfigurationContainer child = root.addChild();
97        final Configuration childOverrideConfig = new Configuration();
98        childOverrideConfig.densityDpi = 320;
99        child.onOverrideConfigurationChanged(childOverrideConfig);
100
101        // Check configuration update when child is removed from parent.
102        root.removeChild(child);
103        assertEquals(childOverrideConfig, child.getOverrideConfiguration());
104        assertEquals(childOverrideConfig, child.getMergedOverrideConfiguration());
105        assertEquals(childOverrideConfig, child.getConfiguration());
106
107        // It may be paranoia... but let's check if parent's config didn't change after removal.
108        assertEquals(rootOverrideConfig, root.getOverrideConfiguration());
109        assertEquals(rootOverrideConfig, root.getMergedOverrideConfiguration());
110        assertEquals(rootOverrideConfig, root.getConfiguration());
111
112        // Check configuration update when child is added to parent.
113        final Configuration mergedOverrideConfig = new Configuration(root.getConfiguration());
114        mergedOverrideConfig.updateFrom(childOverrideConfig);
115        root.addChild(child);
116        assertEquals(childOverrideConfig, child.getOverrideConfiguration());
117        assertEquals(mergedOverrideConfig, child.getMergedOverrideConfiguration());
118        assertEquals(mergedOverrideConfig, child.getConfiguration());
119    }
120
121    @Test
122    public void testConfigurationChangePropagation() throws Exception {
123        // Builds 3-level vertical hierarchy with one configuration container on each level.
124        // In addition to different overrides on each level, everyone in hierarchy will have one
125        // common overridden value - orientation;
126
127        // Init root's config.
128        final TestConfigurationContainer root = new TestConfigurationContainer();
129        final Configuration rootOverrideConfig = new Configuration();
130        rootOverrideConfig.fontScale = 1.3f;
131        rootOverrideConfig.orientation = SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
132        root.onOverrideConfigurationChanged(rootOverrideConfig);
133
134        // Init children.
135        final TestConfigurationContainer child1 = root.addChild();
136        final Configuration childOverrideConfig1 = new Configuration();
137        childOverrideConfig1.densityDpi = 320;
138        childOverrideConfig1.orientation = SCREEN_ORIENTATION_LANDSCAPE;
139        child1.onOverrideConfigurationChanged(childOverrideConfig1);
140
141        final TestConfigurationContainer child2 = child1.addChild();
142        final Configuration childOverrideConfig2 = new Configuration();
143        childOverrideConfig2.screenWidthDp = 150;
144        childOverrideConfig2.orientation = SCREEN_ORIENTATION_PORTRAIT;
145        child2.onOverrideConfigurationChanged(childOverrideConfig2);
146
147        // Check configuration on all levels when root override is updated.
148        rootOverrideConfig.smallestScreenWidthDp = 200;
149        root.onOverrideConfigurationChanged(rootOverrideConfig);
150
151        final Configuration mergedOverrideConfig1 = new Configuration(rootOverrideConfig);
152        mergedOverrideConfig1.updateFrom(childOverrideConfig1);
153        final Configuration mergedConfig1 = new Configuration(mergedOverrideConfig1);
154
155        final Configuration mergedOverrideConfig2 = new Configuration(mergedOverrideConfig1);
156        mergedOverrideConfig2.updateFrom(childOverrideConfig2);
157        final Configuration mergedConfig2 = new Configuration(mergedOverrideConfig2);
158
159        assertEquals(rootOverrideConfig, root.getOverrideConfiguration());
160        assertEquals(rootOverrideConfig, root.getMergedOverrideConfiguration());
161        assertEquals(rootOverrideConfig, root.getConfiguration());
162
163        assertEquals(childOverrideConfig1, child1.getOverrideConfiguration());
164        assertEquals(mergedOverrideConfig1, child1.getMergedOverrideConfiguration());
165        assertEquals(mergedConfig1, child1.getConfiguration());
166
167        assertEquals(childOverrideConfig2, child2.getOverrideConfiguration());
168        assertEquals(mergedOverrideConfig2, child2.getMergedOverrideConfiguration());
169        assertEquals(mergedConfig2, child2.getConfiguration());
170
171        // Check configuration on all levels when root parent config is updated.
172        final Configuration rootParentConfig = new Configuration();
173        rootParentConfig.screenHeightDp = 100;
174        rootParentConfig.orientation = SCREEN_ORIENTATION_REVERSE_PORTRAIT;
175        root.onConfigurationChanged(rootParentConfig);
176        final Configuration mergedRootConfig = new Configuration(rootParentConfig);
177        mergedRootConfig.updateFrom(rootOverrideConfig);
178
179        mergedConfig1.setTo(mergedRootConfig);
180        mergedConfig1.updateFrom(mergedOverrideConfig1);
181
182        mergedConfig2.setTo(mergedConfig1);
183        mergedConfig2.updateFrom(mergedOverrideConfig2);
184
185        assertEquals(rootOverrideConfig, root.getOverrideConfiguration());
186        assertEquals(rootOverrideConfig, root.getMergedOverrideConfiguration());
187        assertEquals(mergedRootConfig, root.getConfiguration());
188
189        assertEquals(childOverrideConfig1, child1.getOverrideConfiguration());
190        assertEquals(mergedOverrideConfig1, child1.getMergedOverrideConfiguration());
191        assertEquals(mergedConfig1, child1.getConfiguration());
192
193        assertEquals(childOverrideConfig2, child2.getOverrideConfiguration());
194        assertEquals(mergedOverrideConfig2, child2.getMergedOverrideConfiguration());
195        assertEquals(mergedConfig2, child2.getConfiguration());
196    }
197
198    /**
199     * Contains minimal implementation of {@link ConfigurationContainer}'s abstract behavior needed
200     * for testing.
201     */
202    private class TestConfigurationContainer
203            extends ConfigurationContainer<TestConfigurationContainer> {
204        private List<TestConfigurationContainer> mChildren = new ArrayList<>();
205        private TestConfigurationContainer mParent;
206
207        TestConfigurationContainer addChild(TestConfigurationContainer childContainer) {
208            childContainer.mParent = this;
209            childContainer.onParentChanged();
210            mChildren.add(childContainer);
211            return childContainer;
212        }
213
214        TestConfigurationContainer addChild() {
215            return addChild(new TestConfigurationContainer());
216        }
217
218        void removeChild(TestConfigurationContainer child) {
219            child.mParent = null;
220            child.onParentChanged();
221        }
222
223        @Override
224        protected int getChildCount() {
225            return mChildren.size();
226        }
227
228        @Override
229        protected TestConfigurationContainer getChildAt(int index) {
230            return mChildren.get(index);
231        }
232
233        @Override
234        protected ConfigurationContainer getParent() {
235            return mParent;
236        }
237    }
238}
239