ConfigurationContainerTests.java revision b94292e5fe18a459aa521b9b9631d2db0485ac1b
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        final Configuration mergedOverrideConfig = new Configuration(root.getConfiguration());
101        mergedOverrideConfig.updateFrom(childOverrideConfig);
102
103        // Check configuration update when child is removed from parent.
104        root.removeChild(child);
105        assertEquals(childOverrideConfig, child.getOverrideConfiguration());
106        assertEquals(mergedOverrideConfig, child.getMergedOverrideConfiguration());
107        assertEquals(mergedOverrideConfig, child.getConfiguration());
108
109        // It may be paranoia... but let's check if parent's config didn't change after removal.
110        assertEquals(rootOverrideConfig, root.getOverrideConfiguration());
111        assertEquals(rootOverrideConfig, root.getMergedOverrideConfiguration());
112        assertEquals(rootOverrideConfig, root.getConfiguration());
113
114        // Init different root
115        final TestConfigurationContainer root2 = new TestConfigurationContainer();
116        final Configuration rootOverrideConfig2 = new Configuration();
117        rootOverrideConfig2.fontScale = 1.1f;
118        root2.onOverrideConfigurationChanged(rootOverrideConfig2);
119
120        // Check configuration update when child is added to different parent.
121        mergedOverrideConfig.setTo(rootOverrideConfig2);
122        mergedOverrideConfig.updateFrom(childOverrideConfig);
123        root2.addChild(child);
124        assertEquals(childOverrideConfig, child.getOverrideConfiguration());
125        assertEquals(mergedOverrideConfig, child.getMergedOverrideConfiguration());
126        assertEquals(mergedOverrideConfig, child.getConfiguration());
127    }
128
129    @Test
130    public void testConfigurationChangePropagation() throws Exception {
131        // Builds 3-level vertical hierarchy with one configuration container on each level.
132        // In addition to different overrides on each level, everyone in hierarchy will have one
133        // common overridden value - orientation;
134
135        // Init root's config.
136        final TestConfigurationContainer root = new TestConfigurationContainer();
137        final Configuration rootOverrideConfig = new Configuration();
138        rootOverrideConfig.fontScale = 1.3f;
139        rootOverrideConfig.orientation = SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
140        root.onOverrideConfigurationChanged(rootOverrideConfig);
141
142        // Init children.
143        final TestConfigurationContainer child1 = root.addChild();
144        final Configuration childOverrideConfig1 = new Configuration();
145        childOverrideConfig1.densityDpi = 320;
146        childOverrideConfig1.orientation = SCREEN_ORIENTATION_LANDSCAPE;
147        child1.onOverrideConfigurationChanged(childOverrideConfig1);
148
149        final TestConfigurationContainer child2 = child1.addChild();
150        final Configuration childOverrideConfig2 = new Configuration();
151        childOverrideConfig2.screenWidthDp = 150;
152        childOverrideConfig2.orientation = SCREEN_ORIENTATION_PORTRAIT;
153        child2.onOverrideConfigurationChanged(childOverrideConfig2);
154
155        // Check configuration on all levels when root override is updated.
156        rootOverrideConfig.smallestScreenWidthDp = 200;
157        root.onOverrideConfigurationChanged(rootOverrideConfig);
158
159        final Configuration mergedOverrideConfig1 = new Configuration(rootOverrideConfig);
160        mergedOverrideConfig1.updateFrom(childOverrideConfig1);
161        final Configuration mergedConfig1 = new Configuration(mergedOverrideConfig1);
162
163        final Configuration mergedOverrideConfig2 = new Configuration(mergedOverrideConfig1);
164        mergedOverrideConfig2.updateFrom(childOverrideConfig2);
165        final Configuration mergedConfig2 = new Configuration(mergedOverrideConfig2);
166
167        assertEquals(rootOverrideConfig, root.getOverrideConfiguration());
168        assertEquals(rootOverrideConfig, root.getMergedOverrideConfiguration());
169        assertEquals(rootOverrideConfig, root.getConfiguration());
170
171        assertEquals(childOverrideConfig1, child1.getOverrideConfiguration());
172        assertEquals(mergedOverrideConfig1, child1.getMergedOverrideConfiguration());
173        assertEquals(mergedConfig1, child1.getConfiguration());
174
175        assertEquals(childOverrideConfig2, child2.getOverrideConfiguration());
176        assertEquals(mergedOverrideConfig2, child2.getMergedOverrideConfiguration());
177        assertEquals(mergedConfig2, child2.getConfiguration());
178
179        // Check configuration on all levels when root parent config is updated.
180        final Configuration rootParentConfig = new Configuration();
181        rootParentConfig.screenHeightDp = 100;
182        rootParentConfig.orientation = SCREEN_ORIENTATION_REVERSE_PORTRAIT;
183        root.onConfigurationChanged(rootParentConfig);
184        final Configuration mergedRootConfig = new Configuration(rootParentConfig);
185        mergedRootConfig.updateFrom(rootOverrideConfig);
186
187        mergedConfig1.setTo(mergedRootConfig);
188        mergedConfig1.updateFrom(mergedOverrideConfig1);
189
190        mergedConfig2.setTo(mergedConfig1);
191        mergedConfig2.updateFrom(mergedOverrideConfig2);
192
193        assertEquals(rootOverrideConfig, root.getOverrideConfiguration());
194        assertEquals(rootOverrideConfig, root.getMergedOverrideConfiguration());
195        assertEquals(mergedRootConfig, root.getConfiguration());
196
197        assertEquals(childOverrideConfig1, child1.getOverrideConfiguration());
198        assertEquals(mergedOverrideConfig1, child1.getMergedOverrideConfiguration());
199        assertEquals(mergedConfig1, child1.getConfiguration());
200
201        assertEquals(childOverrideConfig2, child2.getOverrideConfiguration());
202        assertEquals(mergedOverrideConfig2, child2.getMergedOverrideConfiguration());
203        assertEquals(mergedConfig2, child2.getConfiguration());
204    }
205
206    /**
207     * Contains minimal implementation of {@link ConfigurationContainer}'s abstract behavior needed
208     * for testing.
209     */
210    private class TestConfigurationContainer
211            extends ConfigurationContainer<TestConfigurationContainer> {
212        private List<TestConfigurationContainer> mChildren = new ArrayList<>();
213        private TestConfigurationContainer mParent;
214
215        TestConfigurationContainer addChild(TestConfigurationContainer childContainer) {
216            childContainer.mParent = this;
217            childContainer.onParentChanged();
218            mChildren.add(childContainer);
219            return childContainer;
220        }
221
222        TestConfigurationContainer addChild() {
223            return addChild(new TestConfigurationContainer());
224        }
225
226        void removeChild(TestConfigurationContainer child) {
227            child.mParent = null;
228            child.onParentChanged();
229        }
230
231        @Override
232        protected int getChildCount() {
233            return mChildren.size();
234        }
235
236        @Override
237        protected TestConfigurationContainer getChildAt(int index) {
238            return mChildren.get(index);
239        }
240
241        @Override
242        protected ConfigurationContainer getParent() {
243            return mParent;
244        }
245    }
246}
247