DisplayContentTests.java revision 367ff7fd5251790ad8dc086bd386be8cba1dda5c
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.wm;
18
19import org.junit.Test;
20import org.junit.runner.RunWith;
21
22import android.content.res.Configuration;
23import android.hardware.display.DisplayManagerGlobal;
24import android.platform.test.annotations.Presubmit;
25import android.support.test.filters.SmallTest;
26import android.support.test.runner.AndroidJUnit4;
27import android.view.Display;
28import android.view.DisplayInfo;
29
30import java.util.ArrayList;
31
32import static android.view.Display.DEFAULT_DISPLAY;
33import static android.view.DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS;
34import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
35import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION;
36import static org.junit.Assert.assertEquals;
37
38/**
39 * Tests for the {@link DisplayContent} class.
40 *
41 * Build/Install/Run:
42 *  bit FrameworksServicesTests:com.android.server.wm.DisplayContentTests
43 */
44@SmallTest
45@Presubmit
46@RunWith(AndroidJUnit4.class)
47public class DisplayContentTests extends WindowTestsBase {
48
49    @Test
50    public void testForAllWindows() throws Exception {
51        final WindowState exitingAppWindow = createWindow(null, TYPE_BASE_APPLICATION,
52                sDisplayContent, "exiting app");
53        final AppWindowToken exitingAppToken = exitingAppWindow.mAppToken;
54        exitingAppToken.mIsExiting = true;
55        exitingAppToken.mTask.mStack.mExitingAppTokens.add(exitingAppToken);
56
57        final ArrayList<WindowState> windows = new ArrayList();
58
59        // Test forward traversal.
60        sDisplayContent.forAllWindows(w -> {windows.add(w);}, false /* traverseTopToBottom */);
61
62        assertEquals(sWallpaperWindow, windows.get(0));
63        assertEquals(exitingAppWindow, windows.get(1));
64        assertEquals(sChildAppWindowBelow, windows.get(2));
65        assertEquals(sAppWindow, windows.get(3));
66        assertEquals(sChildAppWindowAbove, windows.get(4));
67        assertEquals(sDockedDividerWindow, windows.get(5));
68        assertEquals(sStatusBarWindow, windows.get(6));
69        assertEquals(sNavBarWindow, windows.get(7));
70        assertEquals(sImeWindow, windows.get(8));
71        assertEquals(sImeDialogWindow, windows.get(9));
72
73        // Test backward traversal.
74        windows.clear();
75        sDisplayContent.forAllWindows(w -> {windows.add(w);}, true /* traverseTopToBottom */);
76
77        assertEquals(sWallpaperWindow, windows.get(9));
78        assertEquals(exitingAppWindow, windows.get(8));
79        assertEquals(sChildAppWindowBelow, windows.get(7));
80        assertEquals(sAppWindow, windows.get(6));
81        assertEquals(sChildAppWindowAbove, windows.get(5));
82        assertEquals(sDockedDividerWindow, windows.get(4));
83        assertEquals(sStatusBarWindow, windows.get(3));
84        assertEquals(sNavBarWindow, windows.get(2));
85        assertEquals(sImeWindow, windows.get(1));
86        assertEquals(sImeDialogWindow, windows.get(0));
87
88        exitingAppWindow.removeImmediately();
89    }
90
91    @Test
92    public void testForAllWindows_WithAppImeTarget() throws Exception {
93        final WindowState imeAppTarget =
94                createWindow(null, TYPE_BASE_APPLICATION, sDisplayContent, "imeAppTarget");
95
96        sWm.mInputMethodTarget = imeAppTarget;
97
98        final ArrayList<WindowState> windows = new ArrayList();
99
100        // Test forward traversal.
101        sDisplayContent.forAllWindows(w -> {windows.add(w);}, false /* traverseTopToBottom */);
102
103        assertEquals(sWallpaperWindow, windows.get(0));
104        assertEquals(sChildAppWindowBelow, windows.get(1));
105        assertEquals(sAppWindow, windows.get(2));
106        assertEquals(sChildAppWindowAbove, windows.get(3));
107        assertEquals(imeAppTarget, windows.get(4));
108        assertEquals(sImeWindow, windows.get(5));
109        assertEquals(sImeDialogWindow, windows.get(6));
110        assertEquals(sDockedDividerWindow, windows.get(7));
111        assertEquals(sStatusBarWindow, windows.get(8));
112        assertEquals(sNavBarWindow, windows.get(9));
113
114        // Test backward traversal.
115        windows.clear();
116        sDisplayContent.forAllWindows(w -> {windows.add(w);}, true /* traverseTopToBottom */);
117
118        assertEquals(sWallpaperWindow, windows.get(9));
119        assertEquals(sChildAppWindowBelow, windows.get(8));
120        assertEquals(sAppWindow, windows.get(7));
121        assertEquals(sChildAppWindowAbove, windows.get(6));
122        assertEquals(imeAppTarget, windows.get(5));
123        assertEquals(sImeWindow, windows.get(4));
124        assertEquals(sImeDialogWindow, windows.get(3));
125        assertEquals(sDockedDividerWindow, windows.get(2));
126        assertEquals(sStatusBarWindow, windows.get(1));
127        assertEquals(sNavBarWindow, windows.get(0));
128
129        // Clean-up
130        sWm.mInputMethodTarget = null;
131        imeAppTarget.removeImmediately();
132    }
133
134    @Test
135    public void testForAllWindows_WithStatusBarImeTarget() throws Exception {
136
137        sWm.mInputMethodTarget = sStatusBarWindow;
138
139        final ArrayList<WindowState> windows = new ArrayList();
140
141        // Test forward traversal.
142        sDisplayContent.forAllWindows(w -> {windows.add(w);}, false /* traverseTopToBottom */);
143
144        assertEquals(sWallpaperWindow, windows.get(0));
145        assertEquals(sChildAppWindowBelow, windows.get(1));
146        assertEquals(sAppWindow, windows.get(2));
147        assertEquals(sChildAppWindowAbove, windows.get(3));
148        assertEquals(sDockedDividerWindow, windows.get(4));
149        assertEquals(sStatusBarWindow, windows.get(5));
150        assertEquals(sImeWindow, windows.get(6));
151        assertEquals(sImeDialogWindow, windows.get(7));
152        assertEquals(sNavBarWindow, windows.get(8));
153
154        // Test backward traversal.
155        windows.clear();
156        sDisplayContent.forAllWindows(w -> {windows.add(w);}, true /* traverseTopToBottom */);
157
158        assertEquals(sWallpaperWindow, windows.get(8));
159        assertEquals(sChildAppWindowBelow, windows.get(7));
160        assertEquals(sAppWindow, windows.get(6));
161        assertEquals(sChildAppWindowAbove, windows.get(5));
162        assertEquals(sDockedDividerWindow, windows.get(4));
163        assertEquals(sStatusBarWindow, windows.get(3));
164        assertEquals(sImeWindow, windows.get(2));
165        assertEquals(sImeDialogWindow, windows.get(1));
166        assertEquals(sNavBarWindow, windows.get(0));
167
168        // Clean-up
169        sWm.mInputMethodTarget = null;
170    }
171
172    @Test
173    public void testForAllWindows_WithInBetweenWindowToken() throws Exception {
174        // This window is set-up to be z-ordered between some windows that go in the same token like
175        // the nav bar and status bar.
176        final WindowState voiceInteractionWindow = createWindow(null, TYPE_VOICE_INTERACTION,
177                sDisplayContent, "voiceInteractionWindow");
178
179        final ArrayList<WindowState> windows = new ArrayList();
180
181        // Test forward traversal.
182        sDisplayContent.forAllWindows(w -> {windows.add(w);}, false /* traverseTopToBottom */);
183
184        assertEquals(sWallpaperWindow, windows.get(0));
185        assertEquals(sChildAppWindowBelow, windows.get(1));
186        assertEquals(sAppWindow, windows.get(2));
187        assertEquals(sChildAppWindowAbove, windows.get(3));
188        assertEquals(sDockedDividerWindow, windows.get(4));
189        assertEquals(voiceInteractionWindow, windows.get(5));
190        assertEquals(sStatusBarWindow, windows.get(6));
191        assertEquals(sNavBarWindow, windows.get(7));
192        assertEquals(sImeWindow, windows.get(8));
193        assertEquals(sImeDialogWindow, windows.get(9));
194
195        // Test backward traversal.
196        windows.clear();
197        sDisplayContent.forAllWindows(w -> {windows.add(w);}, true /* traverseTopToBottom */);
198
199        assertEquals(sWallpaperWindow, windows.get(9));
200        assertEquals(sChildAppWindowBelow, windows.get(8));
201        assertEquals(sAppWindow, windows.get(7));
202        assertEquals(sChildAppWindowAbove, windows.get(6));
203        assertEquals(sDockedDividerWindow, windows.get(5));
204        assertEquals(voiceInteractionWindow, windows.get(4));
205        assertEquals(sStatusBarWindow, windows.get(3));
206        assertEquals(sNavBarWindow, windows.get(2));
207        assertEquals(sImeWindow, windows.get(1));
208        assertEquals(sImeDialogWindow, windows.get(0));
209
210        voiceInteractionWindow.removeImmediately();
211    }
212
213    /**
214     * This tests stack movement between displays and proper stack's, task's and app token's display
215     * container references updates.
216     */
217    @Test
218    public void testMoveStackBetweenDisplays() throws Exception {
219        // Create a second display.
220        final DisplayContent dc = createNewDisplay();
221
222        // Add stack with activity.
223        final TaskStack stack = createTaskStackOnDisplay(dc);
224        assertEquals(dc.getDisplayId(), stack.getDisplayContent().getDisplayId());
225        assertEquals(dc, stack.getParent().getParent());
226        assertEquals(dc, stack.getDisplayContent());
227
228        final Task task = createTaskInStack(stack, 0 /* userId */);
229        final TestAppWindowToken token = new TestAppWindowToken(dc);
230        task.addChild(token, 0);
231        assertEquals(dc, task.getDisplayContent());
232        assertEquals(dc, token.getDisplayContent());
233
234        // Move stack to first display.
235        sDisplayContent.moveStackToDisplay(stack);
236        assertEquals(sDisplayContent.getDisplayId(), stack.getDisplayContent().getDisplayId());
237        assertEquals(sDisplayContent, stack.getParent().getParent());
238        assertEquals(sDisplayContent, stack.getDisplayContent());
239        assertEquals(sDisplayContent, task.getDisplayContent());
240        assertEquals(sDisplayContent, token.getDisplayContent());
241    }
242
243    /**
244     * This tests override configuration updates for display content.
245     */
246    @Test
247    public void testDisplayOverrideConfigUpdate() throws Exception {
248        final int displayId = sDisplayContent.getDisplayId();
249        final Configuration currentOverrideConfig = sDisplayContent.getOverrideConfiguration();
250
251        // Create new, slightly changed override configuration and apply it to the display.
252        final Configuration newOverrideConfig = new Configuration(currentOverrideConfig);
253        newOverrideConfig.densityDpi += 120;
254        newOverrideConfig.fontScale += 0.3;
255
256        sWm.setNewDisplayOverrideConfiguration(newOverrideConfig, displayId);
257
258        // Check that override config is applied.
259        assertEquals(newOverrideConfig, sDisplayContent.getOverrideConfiguration());
260    }
261
262    /**
263     * This tests global configuration updates when default display config is updated.
264     */
265    @Test
266    public void testDefaultDisplayOverrideConfigUpdate() throws Exception {
267        final Configuration currentOverrideConfig = sDisplayContent.getOverrideConfiguration();
268
269        // Create new, slightly changed override configuration and apply it to the display.
270        final Configuration newOverrideConfig = new Configuration(currentOverrideConfig);
271        newOverrideConfig.densityDpi += 120;
272        newOverrideConfig.fontScale += 0.3;
273
274        sWm.setNewDisplayOverrideConfiguration(newOverrideConfig, DEFAULT_DISPLAY);
275
276        // Check that global configuration is updated, as we've updated default display's config.
277        Configuration globalConfig = sWm.mRoot.getConfiguration();
278        assertEquals(newOverrideConfig.densityDpi, globalConfig.densityDpi);
279        assertEquals(newOverrideConfig.fontScale, globalConfig.fontScale, 0.1 /* delta */);
280
281        // Return back to original values.
282        sWm.setNewDisplayOverrideConfiguration(currentOverrideConfig, DEFAULT_DISPLAY);
283        globalConfig = sWm.mRoot.getConfiguration();
284        assertEquals(currentOverrideConfig.densityDpi, globalConfig.densityDpi);
285        assertEquals(currentOverrideConfig.fontScale, globalConfig.fontScale, 0.1 /* delta */);
286    }
287}
288