blob: 2284bbbbf3acd3c3bd71aa38bd7406c2e8d619e7 [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 Ogunwale68278562017-09-23 17:13:55 -070019import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
20import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
Andrii Kulian92c9a942017-10-10 00:41:41 -070021import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
22import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
23import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
Wale Ogunwale34247952017-02-19 11:57:53 -080024import static android.view.Display.DEFAULT_DISPLAY;
25import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
26import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
27import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
Andrii Kulian92c9a942017-10-10 00:41:41 -070028import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
Wale Ogunwale34247952017-02-19 11:57:53 -080029import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION;
David Stevens46939562017-03-24 13:04:00 -070030import static com.android.server.wm.WindowContainer.POSITION_TOP;
Wale Ogunwale34247952017-02-19 11:57:53 -080031import static org.junit.Assert.assertEquals;
32import static org.junit.Assert.assertTrue;
33
Wale Ogunwale42bab782017-05-02 13:16:39 -070034import org.junit.Ignore;
Wale Ogunwaleb783fd82016-11-04 09:51:54 -070035import org.junit.Test;
36import org.junit.runner.RunWith;
37
Andrii Kulian92c9a942017-10-10 00:41:41 -070038import android.annotation.SuppressLint;
Andrii Kuliand68501e2017-01-10 22:57:27 -080039import android.content.res.Configuration;
Adrian Roos1cf585052018-01-03 18:43:27 +010040import android.graphics.Path;
41import android.graphics.Point;
42import android.graphics.Rect;
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -070043import android.os.SystemClock;
Wale Ogunwaleb783fd82016-11-04 09:51:54 -070044import android.platform.test.annotations.Presubmit;
Wale Ogunwaleb783fd82016-11-04 09:51:54 -070045import android.support.test.filters.SmallTest;
46import android.support.test.runner.AndroidJUnit4;
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -070047import android.util.DisplayMetrics;
Andrii Kulian0214ed92017-05-16 13:44:05 -070048import android.util.SparseIntArray;
Adrian Roos1cf585052018-01-03 18:43:27 +010049import android.view.DisplayCutout;
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -070050import android.view.MotionEvent;
Adrian Roos1cf585052018-01-03 18:43:27 +010051import android.view.Surface;
Wale Ogunwaleb783fd82016-11-04 09:51:54 -070052
Wale Ogunwale34247952017-02-19 11:57:53 -080053import java.util.Arrays;
54import java.util.LinkedList;
55import java.util.List;
Wale Ogunwaleb783fd82016-11-04 09:51:54 -070056
57/**
58 * Tests for the {@link DisplayContent} class.
59 *
60 * Build/Install/Run:
Adrian Roos1cf585052018-01-03 18:43:27 +010061 * atest com.android.server.wm.DisplayContentTests
Wale Ogunwaleb783fd82016-11-04 09:51:54 -070062 */
63@SmallTest
64@Presubmit
65@RunWith(AndroidJUnit4.class)
Wale Ogunwale44fbdf52016-11-16 10:18:45 -080066public class DisplayContentTests extends WindowTestsBase {
Wale Ogunwaleb783fd82016-11-04 09:51:54 -070067
68 @Test
69 public void testForAllWindows() throws Exception {
Wale Ogunwale3c1170d2016-12-02 14:44:52 -080070 final WindowState exitingAppWindow = createWindow(null, TYPE_BASE_APPLICATION,
Wale Ogunwale11cc5162017-04-25 20:29:13 -070071 mDisplayContent, "exiting app");
Wale Ogunwaleb783fd82016-11-04 09:51:54 -070072 final AppWindowToken exitingAppToken = exitingAppWindow.mAppToken;
73 exitingAppToken.mIsExiting = true;
Bryce Lee6d410262017-02-28 15:30:17 -080074 exitingAppToken.getTask().mStack.mExitingAppTokens.add(exitingAppToken);
Wale Ogunwaleb783fd82016-11-04 09:51:54 -070075
Wale Ogunwale34247952017-02-19 11:57:53 -080076 assertForAllWindowsOrder(Arrays.asList(
Wale Ogunwale11cc5162017-04-25 20:29:13 -070077 mWallpaperWindow,
Wale Ogunwale34247952017-02-19 11:57:53 -080078 exitingAppWindow,
Wale Ogunwale11cc5162017-04-25 20:29:13 -070079 mChildAppWindowBelow,
80 mAppWindow,
81 mChildAppWindowAbove,
82 mDockedDividerWindow,
83 mStatusBarWindow,
84 mNavBarWindow,
85 mImeWindow,
86 mImeDialogWindow));
Wale Ogunwale3c1170d2016-12-02 14:44:52 -080087 }
88
89 @Test
Wale Ogunwale6ce0fb82016-12-13 14:24:00 -080090 public void testForAllWindows_WithAppImeTarget() throws Exception {
Wale Ogunwale3c1170d2016-12-02 14:44:52 -080091 final WindowState imeAppTarget =
Wale Ogunwale11cc5162017-04-25 20:29:13 -070092 createWindow(null, TYPE_BASE_APPLICATION, mDisplayContent, "imeAppTarget");
Wale Ogunwale3c1170d2016-12-02 14:44:52 -080093
94 sWm.mInputMethodTarget = imeAppTarget;
95
Wale Ogunwale34247952017-02-19 11:57:53 -080096 assertForAllWindowsOrder(Arrays.asList(
Wale Ogunwale11cc5162017-04-25 20:29:13 -070097 mWallpaperWindow,
98 mChildAppWindowBelow,
99 mAppWindow,
100 mChildAppWindowAbove,
Wale Ogunwale34247952017-02-19 11:57:53 -0800101 imeAppTarget,
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700102 mImeWindow,
103 mImeDialogWindow,
104 mDockedDividerWindow,
105 mStatusBarWindow,
106 mNavBarWindow));
Wale Ogunwale34247952017-02-19 11:57:53 -0800107 }
Wale Ogunwale3c1170d2016-12-02 14:44:52 -0800108
Wale Ogunwale34247952017-02-19 11:57:53 -0800109 @Test
110 public void testForAllWindows_WithChildWindowImeTarget() throws Exception {
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700111 sWm.mInputMethodTarget = mChildAppWindowAbove;
Wale Ogunwale3c1170d2016-12-02 14:44:52 -0800112
Wale Ogunwale34247952017-02-19 11:57:53 -0800113 assertForAllWindowsOrder(Arrays.asList(
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700114 mWallpaperWindow,
115 mChildAppWindowBelow,
116 mAppWindow,
117 mChildAppWindowAbove,
118 mImeWindow,
119 mImeDialogWindow,
120 mDockedDividerWindow,
121 mStatusBarWindow,
122 mNavBarWindow));
Wale Ogunwaleb783fd82016-11-04 09:51:54 -0700123 }
Wale Ogunwale5d7e7f12016-12-12 14:47:05 -0800124
125 @Test
Wale Ogunwale6ce0fb82016-12-13 14:24:00 -0800126 public void testForAllWindows_WithStatusBarImeTarget() throws Exception {
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700127 sWm.mInputMethodTarget = mStatusBarWindow;
Wale Ogunwale6ce0fb82016-12-13 14:24:00 -0800128
Wale Ogunwale34247952017-02-19 11:57:53 -0800129 assertForAllWindowsOrder(Arrays.asList(
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700130 mWallpaperWindow,
131 mChildAppWindowBelow,
132 mAppWindow,
133 mChildAppWindowAbove,
134 mDockedDividerWindow,
135 mStatusBarWindow,
136 mImeWindow,
137 mImeDialogWindow,
138 mNavBarWindow));
Wale Ogunwale6ce0fb82016-12-13 14:24:00 -0800139 }
140
141 @Test
Wale Ogunwale5d7e7f12016-12-12 14:47:05 -0800142 public void testForAllWindows_WithInBetweenWindowToken() throws Exception {
143 // This window is set-up to be z-ordered between some windows that go in the same token like
144 // the nav bar and status bar.
145 final WindowState voiceInteractionWindow = createWindow(null, TYPE_VOICE_INTERACTION,
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700146 mDisplayContent, "voiceInteractionWindow");
Wale Ogunwale5d7e7f12016-12-12 14:47:05 -0800147
Wale Ogunwale34247952017-02-19 11:57:53 -0800148 assertForAllWindowsOrder(Arrays.asList(
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700149 mWallpaperWindow,
150 mChildAppWindowBelow,
151 mAppWindow,
152 mChildAppWindowAbove,
153 mDockedDividerWindow,
Wale Ogunwale34247952017-02-19 11:57:53 -0800154 voiceInteractionWindow,
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700155 mStatusBarWindow,
156 mNavBarWindow,
157 mImeWindow,
158 mImeDialogWindow));
Wale Ogunwale34247952017-02-19 11:57:53 -0800159 }
Wale Ogunwale5d7e7f12016-12-12 14:47:05 -0800160
Wale Ogunwale34247952017-02-19 11:57:53 -0800161 @Test
162 public void testComputeImeTarget() throws Exception {
163 // Verify that an app window can be an ime target.
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700164 final WindowState appWin = createWindow(null, TYPE_APPLICATION, mDisplayContent, "appWin");
Wale Ogunwale34247952017-02-19 11:57:53 -0800165 appWin.setHasSurface(true);
166 assertTrue(appWin.canBeImeTarget());
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700167 WindowState imeTarget = mDisplayContent.computeImeTarget(false /* updateImeTarget */);
Wale Ogunwale34247952017-02-19 11:57:53 -0800168 assertEquals(appWin, imeTarget);
Wale Ogunwale5d7e7f12016-12-12 14:47:05 -0800169
Wale Ogunwale34247952017-02-19 11:57:53 -0800170 // Verify that an child window can be an ime target.
171 final WindowState childWin = createWindow(appWin,
172 TYPE_APPLICATION_ATTACHED_DIALOG, "childWin");
173 childWin.setHasSurface(true);
174 assertTrue(childWin.canBeImeTarget());
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700175 imeTarget = mDisplayContent.computeImeTarget(false /* updateImeTarget */);
Wale Ogunwale34247952017-02-19 11:57:53 -0800176 assertEquals(childWin, imeTarget);
Wale Ogunwale5d7e7f12016-12-12 14:47:05 -0800177 }
Andrii Kulian6cc1a1d2016-12-27 23:52:59 -0800178
Andrii Kuliand68501e2017-01-10 22:57:27 -0800179 /**
180 * This tests stack movement between displays and proper stack's, task's and app token's display
181 * container references updates.
182 */
Andrii Kulian6cc1a1d2016-12-27 23:52:59 -0800183 @Test
184 public void testMoveStackBetweenDisplays() throws Exception {
Andrii Kulian367ff7f2017-01-25 19:45:34 -0800185 // Create a second display.
186 final DisplayContent dc = createNewDisplay();
Andrii Kulian6cc1a1d2016-12-27 23:52:59 -0800187
188 // Add stack with activity.
189 final TaskStack stack = createTaskStackOnDisplay(dc);
190 assertEquals(dc.getDisplayId(), stack.getDisplayContent().getDisplayId());
191 assertEquals(dc, stack.getParent().getParent());
192 assertEquals(dc, stack.getDisplayContent());
193
194 final Task task = createTaskInStack(stack, 0 /* userId */);
Bryce Leeaf691c02017-03-20 14:20:22 -0700195 final WindowTestUtils.TestAppWindowToken token = new WindowTestUtils.TestAppWindowToken(dc);
Andrii Kulian6cc1a1d2016-12-27 23:52:59 -0800196 task.addChild(token, 0);
197 assertEquals(dc, task.getDisplayContent());
198 assertEquals(dc, token.getDisplayContent());
199
200 // Move stack to first display.
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700201 mDisplayContent.moveStackToDisplay(stack, true /* onTop */);
202 assertEquals(mDisplayContent.getDisplayId(), stack.getDisplayContent().getDisplayId());
203 assertEquals(mDisplayContent, stack.getParent().getParent());
204 assertEquals(mDisplayContent, stack.getDisplayContent());
205 assertEquals(mDisplayContent, task.getDisplayContent());
206 assertEquals(mDisplayContent, token.getDisplayContent());
Andrii Kulian6cc1a1d2016-12-27 23:52:59 -0800207 }
Andrii Kuliand68501e2017-01-10 22:57:27 -0800208
209 /**
210 * This tests override configuration updates for display content.
211 */
212 @Test
213 public void testDisplayOverrideConfigUpdate() throws Exception {
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700214 final int displayId = mDisplayContent.getDisplayId();
215 final Configuration currentOverrideConfig = mDisplayContent.getOverrideConfiguration();
Andrii Kuliand68501e2017-01-10 22:57:27 -0800216
217 // Create new, slightly changed override configuration and apply it to the display.
218 final Configuration newOverrideConfig = new Configuration(currentOverrideConfig);
219 newOverrideConfig.densityDpi += 120;
220 newOverrideConfig.fontScale += 0.3;
221
222 sWm.setNewDisplayOverrideConfiguration(newOverrideConfig, displayId);
223
224 // Check that override config is applied.
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700225 assertEquals(newOverrideConfig, mDisplayContent.getOverrideConfiguration());
Andrii Kulian367ff7f2017-01-25 19:45:34 -0800226 }
227
228 /**
229 * This tests global configuration updates when default display config is updated.
230 */
231 @Test
232 public void testDefaultDisplayOverrideConfigUpdate() throws Exception {
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700233 final Configuration currentConfig = mDisplayContent.getConfiguration();
Andrii Kulian367ff7f2017-01-25 19:45:34 -0800234
235 // Create new, slightly changed override configuration and apply it to the display.
Andrii Kuliana95bfff2017-03-30 19:00:41 -0700236 final Configuration newOverrideConfig = new Configuration(currentConfig);
Andrii Kulian367ff7f2017-01-25 19:45:34 -0800237 newOverrideConfig.densityDpi += 120;
238 newOverrideConfig.fontScale += 0.3;
239
240 sWm.setNewDisplayOverrideConfiguration(newOverrideConfig, DEFAULT_DISPLAY);
Andrii Kuliand68501e2017-01-10 22:57:27 -0800241
242 // Check that global configuration is updated, as we've updated default display's config.
Andrii Kulian367ff7f2017-01-25 19:45:34 -0800243 Configuration globalConfig = sWm.mRoot.getConfiguration();
Andrii Kuliand68501e2017-01-10 22:57:27 -0800244 assertEquals(newOverrideConfig.densityDpi, globalConfig.densityDpi);
245 assertEquals(newOverrideConfig.fontScale, globalConfig.fontScale, 0.1 /* delta */);
Andrii Kulian367ff7f2017-01-25 19:45:34 -0800246
247 // Return back to original values.
Andrii Kuliana95bfff2017-03-30 19:00:41 -0700248 sWm.setNewDisplayOverrideConfiguration(currentConfig, DEFAULT_DISPLAY);
Andrii Kulian367ff7f2017-01-25 19:45:34 -0800249 globalConfig = sWm.mRoot.getConfiguration();
Andrii Kuliana95bfff2017-03-30 19:00:41 -0700250 assertEquals(currentConfig.densityDpi, globalConfig.densityDpi);
251 assertEquals(currentConfig.fontScale, globalConfig.fontScale, 0.1 /* delta */);
Andrii Kuliand68501e2017-01-10 22:57:27 -0800252 }
Wale Ogunwale34247952017-02-19 11:57:53 -0800253
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -0700254 /**
255 * Tests tapping on a stack in different display results in window gaining focus.
256 */
257 @Test
258 public void testInputEventBringsCorrectDisplayInFocus() throws Exception {
259 DisplayContent dc0 = sWm.getDefaultDisplayContentLocked();
260 // Create a second display
261 final DisplayContent dc1 = createNewDisplay();
262
263 // Add stack with activity.
264 final TaskStack stack0 = createTaskStackOnDisplay(dc0);
265 final Task task0 = createTaskInStack(stack0, 0 /* userId */);
266 final WindowTestUtils.TestAppWindowToken token =
267 new WindowTestUtils.TestAppWindowToken(dc0);
268 task0.addChild(token, 0);
269 dc0.mTapDetector = new TaskTapPointerEventListener(sWm, dc0);
270 sWm.registerPointerEventListener(dc0.mTapDetector);
271 final TaskStack stack1 = createTaskStackOnDisplay(dc1);
272 final Task task1 = createTaskInStack(stack1, 0 /* userId */);
273 final WindowTestUtils.TestAppWindowToken token1 =
274 new WindowTestUtils.TestAppWindowToken(dc0);
275 task1.addChild(token1, 0);
276 dc1.mTapDetector = new TaskTapPointerEventListener(sWm, dc0);
277 sWm.registerPointerEventListener(dc1.mTapDetector);
278
279 // tap on primary display (by sending ACTION_DOWN followed by ACTION_UP)
280 DisplayMetrics dm0 = dc0.getDisplayMetrics();
281 dc0.mTapDetector.onPointerEvent(
282 createTapEvent(dm0.widthPixels / 2, dm0.heightPixels / 2, true));
283 dc0.mTapDetector.onPointerEvent(
284 createTapEvent(dm0.widthPixels / 2, dm0.heightPixels / 2, false));
285
286 // Check focus is on primary display.
287 assertEquals(sWm.mCurrentFocus, dc0.findFocusedWindow());
288
289 // Tap on secondary display
290 DisplayMetrics dm1 = dc1.getDisplayMetrics();
291 dc1.mTapDetector.onPointerEvent(
292 createTapEvent(dm1.widthPixels / 2, dm1.heightPixels / 2, true));
293 dc1.mTapDetector.onPointerEvent(
294 createTapEvent(dm1.widthPixels / 2, dm1.heightPixels / 2, false));
295
296 // Check focus is on secondary.
297 assertEquals(sWm.mCurrentFocus, dc1.findFocusedWindow());
298 }
299
David Stevens46939562017-03-24 13:04:00 -0700300 @Test
Wale Ogunwale42bab782017-05-02 13:16:39 -0700301 @Ignore
David Stevens46939562017-03-24 13:04:00 -0700302 public void testFocusedWindowMultipleDisplays() throws Exception {
Andrii Kulian0214ed92017-05-16 13:44:05 -0700303 // Create a focusable window and check that focus is calculated correctly
David Stevens46939562017-03-24 13:04:00 -0700304 final WindowState window1 =
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700305 createWindow(null, TYPE_BASE_APPLICATION, mDisplayContent, "window1");
David Stevens46939562017-03-24 13:04:00 -0700306 assertEquals(window1, sWm.mRoot.computeFocusedWindow());
307
308 // Check that a new display doesn't affect focus
309 final DisplayContent dc = createNewDisplay();
310 assertEquals(window1, sWm.mRoot.computeFocusedWindow());
311
312 // Add a window to the second display, and it should be focused
313 final WindowState window2 = createWindow(null, TYPE_BASE_APPLICATION, dc, "window2");
314 assertEquals(window2, sWm.mRoot.computeFocusedWindow());
315
316 // Move the first window to the to including parents, and make sure focus is updated
317 window1.getParent().positionChildAt(POSITION_TOP, window1, true);
318 assertEquals(window1, sWm.mRoot.computeFocusedWindow());
319 }
320
Bryce Lee27cec322017-03-21 09:41:37 -0700321 /**
322 * This tests setting the maximum ui width on a display.
323 */
324 @Test
325 public void testMaxUiWidth() throws Exception {
326 final int baseWidth = 1440;
327 final int baseHeight = 2560;
328 final int baseDensity = 300;
329
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700330 mDisplayContent.updateBaseDisplayMetrics(baseWidth, baseHeight, baseDensity);
Bryce Lee27cec322017-03-21 09:41:37 -0700331
332 final int maxWidth = 300;
333 final int resultingHeight = (maxWidth * baseHeight) / baseWidth;
334 final int resultingDensity = (maxWidth * baseDensity) / baseWidth;
335
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700336 mDisplayContent.setMaxUiWidth(maxWidth);
337 verifySizes(mDisplayContent, maxWidth, resultingHeight, resultingDensity);
Bryce Lee27cec322017-03-21 09:41:37 -0700338
339 // Assert setting values again does not change;
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700340 mDisplayContent.updateBaseDisplayMetrics(baseWidth, baseHeight, baseDensity);
341 verifySizes(mDisplayContent, maxWidth, resultingHeight, resultingDensity);
Bryce Lee27cec322017-03-21 09:41:37 -0700342
343 final int smallerWidth = 200;
344 final int smallerHeight = 400;
345 final int smallerDensity = 100;
346
347 // Specify smaller dimension, verify that it is honored
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700348 mDisplayContent.updateBaseDisplayMetrics(smallerWidth, smallerHeight, smallerDensity);
349 verifySizes(mDisplayContent, smallerWidth, smallerHeight, smallerDensity);
Bryce Lee27cec322017-03-21 09:41:37 -0700350
351 // Verify that setting the max width to a greater value than the base width has no effect
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700352 mDisplayContent.setMaxUiWidth(maxWidth);
353 verifySizes(mDisplayContent, smallerWidth, smallerHeight, smallerDensity);
Bryce Lee27cec322017-03-21 09:41:37 -0700354 }
355
Bryce Lee48f4b572017-04-10 10:54:15 -0700356 /**
357 * This test enforces that the pinned stack is always kept as the top stack.
358 */
359 @Test
360 public void testPinnedStackLocation() {
Wale Ogunwale61911492017-10-11 08:50:50 -0700361 final TaskStack pinnedStack = createStackControllerOnStackOnDisplay(
362 WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, mDisplayContent).mContainer;
363 // Ensure that the pinned stack is the top stack
364 assertEquals(pinnedStack, mDisplayContent.getPinnedStack());
365 assertEquals(pinnedStack, mDisplayContent.getTopStack());
Bryce Lee48f4b572017-04-10 10:54:15 -0700366 // By default, this should try to create a new stack on top
Wale Ogunwale61911492017-10-11 08:50:50 -0700367 final TaskStack otherStack = createTaskStackOnDisplay(mDisplayContent);
368 // Ensure that the other stack is on the display.
369 assertEquals(mDisplayContent, otherStack.getDisplayContent());
Bryce Lee48f4b572017-04-10 10:54:15 -0700370 // Ensure that the pinned stack is still on top
Wale Ogunwale61911492017-10-11 08:50:50 -0700371 assertEquals(pinnedStack, mDisplayContent.getTopStack());
Bryce Lee48f4b572017-04-10 10:54:15 -0700372 }
373
Andrii Kulian0214ed92017-05-16 13:44:05 -0700374 /**
375 * Test that WM does not report displays to AM that are pending to be removed.
376 */
377 @Test
378 public void testDontReportDeferredRemoval() {
379 // Create a display and add an animating window to it.
380 final DisplayContent dc = createNewDisplay();
381 final WindowState window = createWindow(null /* parent */, TYPE_BASE_APPLICATION, dc, "w");
382 window.mAnimatingExit = true;
383 // Request display removal, it should be deferred.
384 dc.removeIfPossible();
385 // Request ordered display ids from WM.
386 final SparseIntArray orderedDisplayIds = new SparseIntArray();
387 sWm.getDisplaysInFocusOrder(orderedDisplayIds);
388 // Make sure that display that is marked for removal is not reported.
389 assertEquals(-1, orderedDisplayIds.indexOfValue(dc.getDisplayId()));
390 }
391
Andrii Kulian92c9a942017-10-10 00:41:41 -0700392 @Test
Adrian Roos1cf585052018-01-03 18:43:27 +0100393 public void testDisplayCutout_rot0() throws Exception {
394 synchronized (sWm.getWindowManagerLock()) {
395 final DisplayContent dc = createNewDisplay();
396 dc.mInitialDisplayWidth = 200;
397 dc.mInitialDisplayHeight = 400;
398 final DisplayCutout cutout = createCutout(new Rect(80, 0, 120, 10));
399
400 dc.mInitialDisplayCutout = cutout;
401 dc.setRotation(Surface.ROTATION_0);
402 dc.computeScreenConfiguration(new Configuration()); // recomputes dc.mDisplayInfo.
403
404 assertEquals(cutout, dc.getDisplayInfo().displayCutout);
405 }
406 }
407
408 @Test
409 public void testDisplayCutout_rot90() throws Exception {
410 synchronized (sWm.getWindowManagerLock()) {
411 final DisplayContent dc = createNewDisplay();
412 dc.mInitialDisplayWidth = 200;
413 dc.mInitialDisplayHeight = 400;
414 final DisplayCutout cutout = createCutout(new Rect(80, 0, 120, 10));
415
416 dc.mInitialDisplayCutout = cutout;
417 dc.setRotation(Surface.ROTATION_90);
418 dc.computeScreenConfiguration(new Configuration()); // recomputes dc.mDisplayInfo.
419
420 assertEquals(createCutout(new Rect(0, 80, 10, 120)), dc.getDisplayInfo().displayCutout);
421 }
422 }
423
424 @Test
Andrii Kulian92c9a942017-10-10 00:41:41 -0700425 @SuppressLint("InlinedApi")
426 public void testOrientationDefinedByKeyguard() {
427 final DisplayContent dc = createNewDisplay();
428 // Create a window that requests landscape orientation. It will define device orientation
429 // by default.
430 final WindowState window = createWindow(null /* parent */, TYPE_BASE_APPLICATION, dc, "w");
431 window.mAppToken.setOrientation(SCREEN_ORIENTATION_LANDSCAPE);
432
433 final WindowState keyguard = createWindow(null, TYPE_STATUS_BAR, dc, "keyguard");
434 keyguard.mHasSurface = true;
435 keyguard.mAttrs.screenOrientation = SCREEN_ORIENTATION_UNSPECIFIED;
436
437 assertEquals("Screen orientation must be defined by the app window by default",
438 SCREEN_ORIENTATION_LANDSCAPE, dc.getOrientation());
439
440 keyguard.mAttrs.screenOrientation = SCREEN_ORIENTATION_PORTRAIT;
441 assertEquals("Visible keyguard must influence device orientation",
442 SCREEN_ORIENTATION_PORTRAIT, dc.getOrientation());
443
444 sWm.setKeyguardGoingAway(true);
445 assertEquals("Keyguard that is going away must not influence device orientation",
446 SCREEN_ORIENTATION_LANDSCAPE, dc.getOrientation());
447 }
448
Bryce Lee27cec322017-03-21 09:41:37 -0700449 private static void verifySizes(DisplayContent displayContent, int expectedBaseWidth,
450 int expectedBaseHeight, int expectedBaseDensity) {
451 assertEquals(displayContent.mBaseDisplayWidth, expectedBaseWidth);
452 assertEquals(displayContent.mBaseDisplayHeight, expectedBaseHeight);
453 assertEquals(displayContent.mBaseDisplayDensity, expectedBaseDensity);
454 }
455
Wale Ogunwale34247952017-02-19 11:57:53 -0800456 private void assertForAllWindowsOrder(List<WindowState> expectedWindows) {
457 final LinkedList<WindowState> actualWindows = new LinkedList();
458
459 // Test forward traversal.
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700460 mDisplayContent.forAllWindows(actualWindows::addLast, false /* traverseTopToBottom */);
Wale Ogunwale34247952017-02-19 11:57:53 -0800461 assertEquals(expectedWindows.size(), actualWindows.size());
462 for (WindowState w : expectedWindows) {
463 assertEquals(w, actualWindows.pollFirst());
464 }
465 assertTrue(actualWindows.isEmpty());
466
467 // Test backward traversal.
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700468 mDisplayContent.forAllWindows(actualWindows::addLast, true /* traverseTopToBottom */);
Wale Ogunwale34247952017-02-19 11:57:53 -0800469 assertEquals(expectedWindows.size(), actualWindows.size());
470 for (WindowState w : expectedWindows) {
471 assertEquals(w, actualWindows.pollLast());
472 }
473 assertTrue(actualWindows.isEmpty());
474 }
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -0700475
476 private MotionEvent createTapEvent(float x, float y, boolean isDownEvent) {
477 final long downTime = SystemClock.uptimeMillis();
478 final long eventTime = SystemClock.uptimeMillis() + 100;
479 final int metaState = 0;
480
481 return MotionEvent.obtain(
482 downTime,
483 eventTime,
484 isDownEvent ? MotionEvent.ACTION_DOWN : MotionEvent.ACTION_UP,
485 x,
486 y,
487 metaState);
488 }
Adrian Roos1cf585052018-01-03 18:43:27 +0100489
490 private DisplayCutout createCutout(Rect r) {
491 Path p = new Path();
492 p.addRect(r.left, r.top, r.right, r.bottom, Path.Direction.CCW);
493 return DisplayCutout.fromBounds(p);
494 }
Wale Ogunwaleb783fd82016-11-04 09:51:54 -0700495}