blob: 1729ceec00052047e21aba27df49480574ba03f8 [file] [log] [blame]
Wale Ogunwaleb783fd82016-11-04 09:51:54 -07001/*
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
Wale Ogunwale34247952017-02-19 11:57:53 -080019import static android.view.Display.DEFAULT_DISPLAY;
20import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
21import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
22import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
23import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION;
David Stevens46939562017-03-24 13:04:00 -070024import static com.android.server.wm.WindowContainer.POSITION_TOP;
Wale Ogunwale34247952017-02-19 11:57:53 -080025import static org.junit.Assert.assertEquals;
26import static org.junit.Assert.assertTrue;
27
Wale Ogunwaleb783fd82016-11-04 09:51:54 -070028import org.junit.Test;
29import org.junit.runner.RunWith;
30
Andrii Kuliand68501e2017-01-10 22:57:27 -080031import android.content.res.Configuration;
Wale Ogunwaleb783fd82016-11-04 09:51:54 -070032import android.platform.test.annotations.Presubmit;
Wale Ogunwaleb783fd82016-11-04 09:51:54 -070033import android.support.test.filters.SmallTest;
34import android.support.test.runner.AndroidJUnit4;
Wale Ogunwaleb783fd82016-11-04 09:51:54 -070035
Wale Ogunwale34247952017-02-19 11:57:53 -080036import java.util.Arrays;
37import java.util.LinkedList;
38import java.util.List;
Wale Ogunwaleb783fd82016-11-04 09:51:54 -070039
40/**
41 * Tests for the {@link DisplayContent} class.
42 *
43 * Build/Install/Run:
44 * bit FrameworksServicesTests:com.android.server.wm.DisplayContentTests
45 */
46@SmallTest
47@Presubmit
48@RunWith(AndroidJUnit4.class)
Wale Ogunwale44fbdf52016-11-16 10:18:45 -080049public class DisplayContentTests extends WindowTestsBase {
Wale Ogunwaleb783fd82016-11-04 09:51:54 -070050
51 @Test
52 public void testForAllWindows() throws Exception {
Wale Ogunwale3c1170d2016-12-02 14:44:52 -080053 final WindowState exitingAppWindow = createWindow(null, TYPE_BASE_APPLICATION,
54 sDisplayContent, "exiting app");
Wale Ogunwaleb783fd82016-11-04 09:51:54 -070055 final AppWindowToken exitingAppToken = exitingAppWindow.mAppToken;
56 exitingAppToken.mIsExiting = true;
Bryce Lee6d410262017-02-28 15:30:17 -080057 exitingAppToken.getTask().mStack.mExitingAppTokens.add(exitingAppToken);
Wale Ogunwaleb783fd82016-11-04 09:51:54 -070058
Wale Ogunwale34247952017-02-19 11:57:53 -080059 assertForAllWindowsOrder(Arrays.asList(
60 sWallpaperWindow,
61 exitingAppWindow,
62 sChildAppWindowBelow,
63 sAppWindow,
64 sChildAppWindowAbove,
65 sDockedDividerWindow,
66 sStatusBarWindow,
67 sNavBarWindow,
68 sImeWindow,
69 sImeDialogWindow));
Wale Ogunwale3c1170d2016-12-02 14:44:52 -080070 }
71
72 @Test
Wale Ogunwale6ce0fb82016-12-13 14:24:00 -080073 public void testForAllWindows_WithAppImeTarget() throws Exception {
Wale Ogunwale3c1170d2016-12-02 14:44:52 -080074 final WindowState imeAppTarget =
75 createWindow(null, TYPE_BASE_APPLICATION, sDisplayContent, "imeAppTarget");
76
77 sWm.mInputMethodTarget = imeAppTarget;
78
Wale Ogunwale34247952017-02-19 11:57:53 -080079 assertForAllWindowsOrder(Arrays.asList(
80 sWallpaperWindow,
81 sChildAppWindowBelow,
82 sAppWindow,
83 sChildAppWindowAbove,
84 imeAppTarget,
85 sImeWindow,
86 sImeDialogWindow,
87 sDockedDividerWindow,
88 sStatusBarWindow,
89 sNavBarWindow));
90 }
Wale Ogunwale3c1170d2016-12-02 14:44:52 -080091
Wale Ogunwale34247952017-02-19 11:57:53 -080092 @Test
93 public void testForAllWindows_WithChildWindowImeTarget() throws Exception {
94 sWm.mInputMethodTarget = sChildAppWindowAbove;
Wale Ogunwale3c1170d2016-12-02 14:44:52 -080095
Wale Ogunwale34247952017-02-19 11:57:53 -080096 assertForAllWindowsOrder(Arrays.asList(
97 sWallpaperWindow,
98 sChildAppWindowBelow,
99 sAppWindow,
100 sChildAppWindowAbove,
101 sImeWindow,
102 sImeDialogWindow,
103 sDockedDividerWindow,
104 sStatusBarWindow,
105 sNavBarWindow));
Wale Ogunwaleb783fd82016-11-04 09:51:54 -0700106 }
Wale Ogunwale5d7e7f12016-12-12 14:47:05 -0800107
108 @Test
Wale Ogunwale6ce0fb82016-12-13 14:24:00 -0800109 public void testForAllWindows_WithStatusBarImeTarget() throws Exception {
Wale Ogunwale6ce0fb82016-12-13 14:24:00 -0800110 sWm.mInputMethodTarget = sStatusBarWindow;
111
Wale Ogunwale34247952017-02-19 11:57:53 -0800112 assertForAllWindowsOrder(Arrays.asList(
113 sWallpaperWindow,
114 sChildAppWindowBelow,
115 sAppWindow,
116 sChildAppWindowAbove,
117 sDockedDividerWindow,
118 sStatusBarWindow,
119 sImeWindow,
120 sImeDialogWindow,
121 sNavBarWindow));
Wale Ogunwale6ce0fb82016-12-13 14:24:00 -0800122 }
123
124 @Test
Wale Ogunwale5d7e7f12016-12-12 14:47:05 -0800125 public void testForAllWindows_WithInBetweenWindowToken() throws Exception {
126 // This window is set-up to be z-ordered between some windows that go in the same token like
127 // the nav bar and status bar.
128 final WindowState voiceInteractionWindow = createWindow(null, TYPE_VOICE_INTERACTION,
129 sDisplayContent, "voiceInteractionWindow");
130
Wale Ogunwale34247952017-02-19 11:57:53 -0800131 assertForAllWindowsOrder(Arrays.asList(
132 sWallpaperWindow,
133 sChildAppWindowBelow,
134 sAppWindow,
135 sChildAppWindowAbove,
136 sDockedDividerWindow,
137 voiceInteractionWindow,
138 sStatusBarWindow,
139 sNavBarWindow,
140 sImeWindow,
141 sImeDialogWindow));
142 }
Wale Ogunwale5d7e7f12016-12-12 14:47:05 -0800143
Wale Ogunwale34247952017-02-19 11:57:53 -0800144 @Test
145 public void testComputeImeTarget() throws Exception {
146 // Verify that an app window can be an ime target.
147 final WindowState appWin = createWindow(null, TYPE_APPLICATION, sDisplayContent, "appWin");
148 appWin.setHasSurface(true);
149 assertTrue(appWin.canBeImeTarget());
150 WindowState imeTarget = sDisplayContent.computeImeTarget(false /* updateImeTarget */);
151 assertEquals(appWin, imeTarget);
Wale Ogunwale5d7e7f12016-12-12 14:47:05 -0800152
Wale Ogunwale34247952017-02-19 11:57:53 -0800153 // Verify that an child window can be an ime target.
154 final WindowState childWin = createWindow(appWin,
155 TYPE_APPLICATION_ATTACHED_DIALOG, "childWin");
156 childWin.setHasSurface(true);
157 assertTrue(childWin.canBeImeTarget());
158 imeTarget = sDisplayContent.computeImeTarget(false /* updateImeTarget */);
159 assertEquals(childWin, imeTarget);
Wale Ogunwale5d7e7f12016-12-12 14:47:05 -0800160 }
Andrii Kulian6cc1a1d2016-12-27 23:52:59 -0800161
Andrii Kuliand68501e2017-01-10 22:57:27 -0800162 /**
163 * This tests stack movement between displays and proper stack's, task's and app token's display
164 * container references updates.
165 */
Andrii Kulian6cc1a1d2016-12-27 23:52:59 -0800166 @Test
167 public void testMoveStackBetweenDisplays() throws Exception {
Andrii Kulian367ff7f2017-01-25 19:45:34 -0800168 // Create a second display.
169 final DisplayContent dc = createNewDisplay();
Andrii Kulian6cc1a1d2016-12-27 23:52:59 -0800170
171 // Add stack with activity.
172 final TaskStack stack = createTaskStackOnDisplay(dc);
173 assertEquals(dc.getDisplayId(), stack.getDisplayContent().getDisplayId());
174 assertEquals(dc, stack.getParent().getParent());
175 assertEquals(dc, stack.getDisplayContent());
176
177 final Task task = createTaskInStack(stack, 0 /* userId */);
178 final TestAppWindowToken token = new TestAppWindowToken(dc);
179 task.addChild(token, 0);
180 assertEquals(dc, task.getDisplayContent());
181 assertEquals(dc, token.getDisplayContent());
182
183 // Move stack to first display.
Wale Ogunwale1666e312016-12-16 11:27:18 -0800184 sDisplayContent.moveStackToDisplay(stack);
Andrii Kulian6cc1a1d2016-12-27 23:52:59 -0800185 assertEquals(sDisplayContent.getDisplayId(), stack.getDisplayContent().getDisplayId());
186 assertEquals(sDisplayContent, stack.getParent().getParent());
187 assertEquals(sDisplayContent, stack.getDisplayContent());
188 assertEquals(sDisplayContent, task.getDisplayContent());
189 assertEquals(sDisplayContent, token.getDisplayContent());
190 }
Andrii Kuliand68501e2017-01-10 22:57:27 -0800191
192 /**
193 * This tests override configuration updates for display content.
194 */
195 @Test
196 public void testDisplayOverrideConfigUpdate() throws Exception {
197 final int displayId = sDisplayContent.getDisplayId();
198 final Configuration currentOverrideConfig = sDisplayContent.getOverrideConfiguration();
199
200 // Create new, slightly changed override configuration and apply it to the display.
201 final Configuration newOverrideConfig = new Configuration(currentOverrideConfig);
202 newOverrideConfig.densityDpi += 120;
203 newOverrideConfig.fontScale += 0.3;
204
205 sWm.setNewDisplayOverrideConfiguration(newOverrideConfig, displayId);
206
207 // Check that override config is applied.
208 assertEquals(newOverrideConfig, sDisplayContent.getOverrideConfiguration());
Andrii Kulian367ff7f2017-01-25 19:45:34 -0800209 }
210
211 /**
212 * This tests global configuration updates when default display config is updated.
213 */
214 @Test
215 public void testDefaultDisplayOverrideConfigUpdate() throws Exception {
216 final Configuration currentOverrideConfig = sDisplayContent.getOverrideConfiguration();
217
218 // Create new, slightly changed override configuration and apply it to the display.
219 final Configuration newOverrideConfig = new Configuration(currentOverrideConfig);
220 newOverrideConfig.densityDpi += 120;
221 newOverrideConfig.fontScale += 0.3;
222
223 sWm.setNewDisplayOverrideConfiguration(newOverrideConfig, DEFAULT_DISPLAY);
Andrii Kuliand68501e2017-01-10 22:57:27 -0800224
225 // Check that global configuration is updated, as we've updated default display's config.
Andrii Kulian367ff7f2017-01-25 19:45:34 -0800226 Configuration globalConfig = sWm.mRoot.getConfiguration();
Andrii Kuliand68501e2017-01-10 22:57:27 -0800227 assertEquals(newOverrideConfig.densityDpi, globalConfig.densityDpi);
228 assertEquals(newOverrideConfig.fontScale, globalConfig.fontScale, 0.1 /* delta */);
Andrii Kulian367ff7f2017-01-25 19:45:34 -0800229
230 // Return back to original values.
231 sWm.setNewDisplayOverrideConfiguration(currentOverrideConfig, DEFAULT_DISPLAY);
232 globalConfig = sWm.mRoot.getConfiguration();
233 assertEquals(currentOverrideConfig.densityDpi, globalConfig.densityDpi);
234 assertEquals(currentOverrideConfig.fontScale, globalConfig.fontScale, 0.1 /* delta */);
Andrii Kuliand68501e2017-01-10 22:57:27 -0800235 }
Wale Ogunwale34247952017-02-19 11:57:53 -0800236
David Stevens46939562017-03-24 13:04:00 -0700237 @Test
238 public void testFocusedWindowMultipleDisplays() throws Exception {
239 // Create a focusable window and check that focus is calcualted correctly
240 final WindowState window1 =
241 createWindow(null, TYPE_BASE_APPLICATION, sDisplayContent, "window1");
242 assertEquals(window1, sWm.mRoot.computeFocusedWindow());
243
244 // Check that a new display doesn't affect focus
245 final DisplayContent dc = createNewDisplay();
246 assertEquals(window1, sWm.mRoot.computeFocusedWindow());
247
248 // Add a window to the second display, and it should be focused
249 final WindowState window2 = createWindow(null, TYPE_BASE_APPLICATION, dc, "window2");
250 assertEquals(window2, sWm.mRoot.computeFocusedWindow());
251
252 // Move the first window to the to including parents, and make sure focus is updated
253 window1.getParent().positionChildAt(POSITION_TOP, window1, true);
254 assertEquals(window1, sWm.mRoot.computeFocusedWindow());
255 }
256
Bryce Lee27cec322017-03-21 09:41:37 -0700257 /**
258 * This tests setting the maximum ui width on a display.
259 */
260 @Test
261 public void testMaxUiWidth() throws Exception {
262 final int baseWidth = 1440;
263 final int baseHeight = 2560;
264 final int baseDensity = 300;
265
266 sDisplayContent.updateBaseDisplayMetrics(baseWidth, baseHeight, baseDensity);
267
268 final int maxWidth = 300;
269 final int resultingHeight = (maxWidth * baseHeight) / baseWidth;
270 final int resultingDensity = (maxWidth * baseDensity) / baseWidth;
271
272 sDisplayContent.setMaxUiWidth(maxWidth);
273 verifySizes(sDisplayContent, maxWidth, resultingHeight, resultingDensity);
274
275 // Assert setting values again does not change;
276 sDisplayContent.updateBaseDisplayMetrics(baseWidth, baseHeight, baseDensity);
277 verifySizes(sDisplayContent, maxWidth, resultingHeight, resultingDensity);
278
279 final int smallerWidth = 200;
280 final int smallerHeight = 400;
281 final int smallerDensity = 100;
282
283 // Specify smaller dimension, verify that it is honored
284 sDisplayContent.updateBaseDisplayMetrics(smallerWidth, smallerHeight, smallerDensity);
285 verifySizes(sDisplayContent, smallerWidth, smallerHeight, smallerDensity);
286
287 // Verify that setting the max width to a greater value than the base width has no effect
288 sDisplayContent.setMaxUiWidth(maxWidth);
289 verifySizes(sDisplayContent, smallerWidth, smallerHeight, smallerDensity);
290 }
291
292 private static void verifySizes(DisplayContent displayContent, int expectedBaseWidth,
293 int expectedBaseHeight, int expectedBaseDensity) {
294 assertEquals(displayContent.mBaseDisplayWidth, expectedBaseWidth);
295 assertEquals(displayContent.mBaseDisplayHeight, expectedBaseHeight);
296 assertEquals(displayContent.mBaseDisplayDensity, expectedBaseDensity);
297 }
298
Wale Ogunwale34247952017-02-19 11:57:53 -0800299 private void assertForAllWindowsOrder(List<WindowState> expectedWindows) {
300 final LinkedList<WindowState> actualWindows = new LinkedList();
301
302 // Test forward traversal.
303 sDisplayContent.forAllWindows(actualWindows::addLast, false /* traverseTopToBottom */);
304 assertEquals(expectedWindows.size(), actualWindows.size());
305 for (WindowState w : expectedWindows) {
306 assertEquals(w, actualWindows.pollFirst());
307 }
308 assertTrue(actualWindows.isEmpty());
309
310 // Test backward traversal.
311 sDisplayContent.forAllWindows(actualWindows::addLast, true /* traverseTopToBottom */);
312 assertEquals(expectedWindows.size(), actualWindows.size());
313 for (WindowState w : expectedWindows) {
314 assertEquals(w, actualWindows.pollLast());
315 }
316 assertTrue(actualWindows.isEmpty());
317 }
Wale Ogunwaleb783fd82016-11-04 09:51:54 -0700318}