blob: 7f1bcac05ffed34c2c13fe96abc3b261c7d98ea4 [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;
Adrian Roos24264212018-02-19 16:26:15 +010025import static android.view.DisplayCutout.fromBoundingRect;
Wale Ogunwale34247952017-02-19 11:57:53 -080026import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
27import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
28import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
Andrii Kulian92c9a942017-10-10 00:41:41 -070029import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
Wale Ogunwale34247952017-02-19 11:57:53 -080030import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION;
David Stevens46939562017-03-24 13:04:00 -070031import static com.android.server.wm.WindowContainer.POSITION_TOP;
chaviwebcbc342018-02-07 13:19:00 -080032
Adrian Roos5251b1d2018-03-23 18:57:43 +010033import static org.hamcrest.Matchers.is;
Wale Ogunwale34247952017-02-19 11:57:53 -080034import static org.junit.Assert.assertEquals;
Andrii Kulianf0379de2018-03-14 16:24:07 -070035import static org.junit.Assert.assertFalse;
Adrian Roos5251b1d2018-03-23 18:57:43 +010036import static org.junit.Assert.assertThat;
Wale Ogunwale34247952017-02-19 11:57:53 -080037import static org.junit.Assert.assertTrue;
Andrii Kulianf0379de2018-03-14 16:24:07 -070038import static org.mockito.Mockito.times;
39import static org.mockito.Mockito.verify;
Wale Ogunwale34247952017-02-19 11:57:53 -080040
Wale Ogunwaleb783fd82016-11-04 09:51:54 -070041import org.junit.Test;
42import org.junit.runner.RunWith;
43
Andrii Kulian92c9a942017-10-10 00:41:41 -070044import android.annotation.SuppressLint;
Andrii Kuliand68501e2017-01-10 22:57:27 -080045import android.content.res.Configuration;
Adrian Roos1cf585052018-01-03 18:43:27 +010046import android.graphics.Rect;
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -070047import android.os.SystemClock;
Wale Ogunwaleb783fd82016-11-04 09:51:54 -070048import android.platform.test.annotations.Presubmit;
Wale Ogunwaleb783fd82016-11-04 09:51:54 -070049import android.support.test.filters.SmallTest;
50import android.support.test.runner.AndroidJUnit4;
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -070051import android.util.DisplayMetrics;
Andrii Kulian0214ed92017-05-16 13:44:05 -070052import android.util.SparseIntArray;
Adrian Roos1cf585052018-01-03 18:43:27 +010053import android.view.DisplayCutout;
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -070054import android.view.MotionEvent;
Adrian Roos1cf585052018-01-03 18:43:27 +010055import android.view.Surface;
Wale Ogunwaleb783fd82016-11-04 09:51:54 -070056
Adrian Roos6a4fa0e2018-03-05 19:50:16 +010057import com.android.server.wm.utils.WmDisplayCutout;
58
Wale Ogunwale34247952017-02-19 11:57:53 -080059import java.util.Arrays;
60import java.util.LinkedList;
61import java.util.List;
Wale Ogunwaleb783fd82016-11-04 09:51:54 -070062
63/**
64 * Tests for the {@link DisplayContent} class.
65 *
66 * Build/Install/Run:
Adrian Roos1cf585052018-01-03 18:43:27 +010067 * atest com.android.server.wm.DisplayContentTests
Wale Ogunwaleb783fd82016-11-04 09:51:54 -070068 */
69@SmallTest
70@Presubmit
71@RunWith(AndroidJUnit4.class)
Wale Ogunwale44fbdf52016-11-16 10:18:45 -080072public class DisplayContentTests extends WindowTestsBase {
Wale Ogunwaleb783fd82016-11-04 09:51:54 -070073
74 @Test
75 public void testForAllWindows() throws Exception {
Wale Ogunwale3c1170d2016-12-02 14:44:52 -080076 final WindowState exitingAppWindow = createWindow(null, TYPE_BASE_APPLICATION,
Wale Ogunwale11cc5162017-04-25 20:29:13 -070077 mDisplayContent, "exiting app");
Wale Ogunwaleb783fd82016-11-04 09:51:54 -070078 final AppWindowToken exitingAppToken = exitingAppWindow.mAppToken;
79 exitingAppToken.mIsExiting = true;
Bryce Lee6d410262017-02-28 15:30:17 -080080 exitingAppToken.getTask().mStack.mExitingAppTokens.add(exitingAppToken);
Wale Ogunwaleb783fd82016-11-04 09:51:54 -070081
Wale Ogunwale34247952017-02-19 11:57:53 -080082 assertForAllWindowsOrder(Arrays.asList(
Wale Ogunwale11cc5162017-04-25 20:29:13 -070083 mWallpaperWindow,
Wale Ogunwale34247952017-02-19 11:57:53 -080084 exitingAppWindow,
Wale Ogunwale11cc5162017-04-25 20:29:13 -070085 mChildAppWindowBelow,
86 mAppWindow,
87 mChildAppWindowAbove,
88 mDockedDividerWindow,
89 mStatusBarWindow,
90 mNavBarWindow,
91 mImeWindow,
92 mImeDialogWindow));
Wale Ogunwale3c1170d2016-12-02 14:44:52 -080093 }
94
95 @Test
Wale Ogunwale6ce0fb82016-12-13 14:24:00 -080096 public void testForAllWindows_WithAppImeTarget() throws Exception {
Wale Ogunwale3c1170d2016-12-02 14:44:52 -080097 final WindowState imeAppTarget =
Wale Ogunwale11cc5162017-04-25 20:29:13 -070098 createWindow(null, TYPE_BASE_APPLICATION, mDisplayContent, "imeAppTarget");
Wale Ogunwale3c1170d2016-12-02 14:44:52 -080099
100 sWm.mInputMethodTarget = imeAppTarget;
101
Wale Ogunwale34247952017-02-19 11:57:53 -0800102 assertForAllWindowsOrder(Arrays.asList(
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700103 mWallpaperWindow,
104 mChildAppWindowBelow,
105 mAppWindow,
106 mChildAppWindowAbove,
Wale Ogunwale34247952017-02-19 11:57:53 -0800107 imeAppTarget,
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700108 mImeWindow,
109 mImeDialogWindow,
110 mDockedDividerWindow,
111 mStatusBarWindow,
112 mNavBarWindow));
Wale Ogunwale34247952017-02-19 11:57:53 -0800113 }
Wale Ogunwale3c1170d2016-12-02 14:44:52 -0800114
Wale Ogunwale34247952017-02-19 11:57:53 -0800115 @Test
116 public void testForAllWindows_WithChildWindowImeTarget() throws Exception {
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700117 sWm.mInputMethodTarget = mChildAppWindowAbove;
Wale Ogunwale3c1170d2016-12-02 14:44:52 -0800118
Wale Ogunwale34247952017-02-19 11:57:53 -0800119 assertForAllWindowsOrder(Arrays.asList(
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700120 mWallpaperWindow,
121 mChildAppWindowBelow,
122 mAppWindow,
123 mChildAppWindowAbove,
124 mImeWindow,
125 mImeDialogWindow,
126 mDockedDividerWindow,
127 mStatusBarWindow,
128 mNavBarWindow));
Wale Ogunwaleb783fd82016-11-04 09:51:54 -0700129 }
Wale Ogunwale5d7e7f12016-12-12 14:47:05 -0800130
131 @Test
Wale Ogunwale6ce0fb82016-12-13 14:24:00 -0800132 public void testForAllWindows_WithStatusBarImeTarget() throws Exception {
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700133 sWm.mInputMethodTarget = mStatusBarWindow;
Wale Ogunwale6ce0fb82016-12-13 14:24:00 -0800134
Wale Ogunwale34247952017-02-19 11:57:53 -0800135 assertForAllWindowsOrder(Arrays.asList(
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700136 mWallpaperWindow,
137 mChildAppWindowBelow,
138 mAppWindow,
139 mChildAppWindowAbove,
140 mDockedDividerWindow,
141 mStatusBarWindow,
142 mImeWindow,
143 mImeDialogWindow,
144 mNavBarWindow));
Wale Ogunwale6ce0fb82016-12-13 14:24:00 -0800145 }
146
147 @Test
Wale Ogunwale5d7e7f12016-12-12 14:47:05 -0800148 public void testForAllWindows_WithInBetweenWindowToken() throws Exception {
149 // This window is set-up to be z-ordered between some windows that go in the same token like
150 // the nav bar and status bar.
151 final WindowState voiceInteractionWindow = createWindow(null, TYPE_VOICE_INTERACTION,
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700152 mDisplayContent, "voiceInteractionWindow");
Wale Ogunwale5d7e7f12016-12-12 14:47:05 -0800153
Wale Ogunwale34247952017-02-19 11:57:53 -0800154 assertForAllWindowsOrder(Arrays.asList(
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700155 mWallpaperWindow,
156 mChildAppWindowBelow,
157 mAppWindow,
158 mChildAppWindowAbove,
159 mDockedDividerWindow,
Wale Ogunwale34247952017-02-19 11:57:53 -0800160 voiceInteractionWindow,
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700161 mStatusBarWindow,
162 mNavBarWindow,
163 mImeWindow,
164 mImeDialogWindow));
Wale Ogunwale34247952017-02-19 11:57:53 -0800165 }
Wale Ogunwale5d7e7f12016-12-12 14:47:05 -0800166
Wale Ogunwale34247952017-02-19 11:57:53 -0800167 @Test
168 public void testComputeImeTarget() throws Exception {
169 // Verify that an app window can be an ime target.
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700170 final WindowState appWin = createWindow(null, TYPE_APPLICATION, mDisplayContent, "appWin");
Wale Ogunwale34247952017-02-19 11:57:53 -0800171 appWin.setHasSurface(true);
172 assertTrue(appWin.canBeImeTarget());
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700173 WindowState imeTarget = mDisplayContent.computeImeTarget(false /* updateImeTarget */);
Wale Ogunwale34247952017-02-19 11:57:53 -0800174 assertEquals(appWin, imeTarget);
chaviwebcbc342018-02-07 13:19:00 -0800175 appWin.mHidden = false;
Wale Ogunwale5d7e7f12016-12-12 14:47:05 -0800176
Wale Ogunwale34247952017-02-19 11:57:53 -0800177 // Verify that an child window can be an ime target.
178 final WindowState childWin = createWindow(appWin,
179 TYPE_APPLICATION_ATTACHED_DIALOG, "childWin");
180 childWin.setHasSurface(true);
181 assertTrue(childWin.canBeImeTarget());
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700182 imeTarget = mDisplayContent.computeImeTarget(false /* updateImeTarget */);
Wale Ogunwale34247952017-02-19 11:57:53 -0800183 assertEquals(childWin, imeTarget);
Wale Ogunwale5d7e7f12016-12-12 14:47:05 -0800184 }
Andrii Kulian6cc1a1d2016-12-27 23:52:59 -0800185
Andrii Kuliand68501e2017-01-10 22:57:27 -0800186 /**
187 * This tests stack movement between displays and proper stack's, task's and app token's display
188 * container references updates.
189 */
Andrii Kulian6cc1a1d2016-12-27 23:52:59 -0800190 @Test
191 public void testMoveStackBetweenDisplays() throws Exception {
Andrii Kulian367ff7f2017-01-25 19:45:34 -0800192 // Create a second display.
193 final DisplayContent dc = createNewDisplay();
Andrii Kulian6cc1a1d2016-12-27 23:52:59 -0800194
195 // Add stack with activity.
196 final TaskStack stack = createTaskStackOnDisplay(dc);
197 assertEquals(dc.getDisplayId(), stack.getDisplayContent().getDisplayId());
198 assertEquals(dc, stack.getParent().getParent());
199 assertEquals(dc, stack.getDisplayContent());
200
201 final Task task = createTaskInStack(stack, 0 /* userId */);
chaviw97d28202018-02-27 16:23:53 -0800202 final WindowTestUtils.TestAppWindowToken token = WindowTestUtils.createTestAppWindowToken(
203 dc);
Andrii Kulian6cc1a1d2016-12-27 23:52:59 -0800204 task.addChild(token, 0);
205 assertEquals(dc, task.getDisplayContent());
206 assertEquals(dc, token.getDisplayContent());
207
208 // Move stack to first display.
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700209 mDisplayContent.moveStackToDisplay(stack, true /* onTop */);
210 assertEquals(mDisplayContent.getDisplayId(), stack.getDisplayContent().getDisplayId());
211 assertEquals(mDisplayContent, stack.getParent().getParent());
212 assertEquals(mDisplayContent, stack.getDisplayContent());
213 assertEquals(mDisplayContent, task.getDisplayContent());
214 assertEquals(mDisplayContent, token.getDisplayContent());
Andrii Kulian6cc1a1d2016-12-27 23:52:59 -0800215 }
Andrii Kuliand68501e2017-01-10 22:57:27 -0800216
217 /**
218 * This tests override configuration updates for display content.
219 */
220 @Test
221 public void testDisplayOverrideConfigUpdate() throws Exception {
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700222 final int displayId = mDisplayContent.getDisplayId();
223 final Configuration currentOverrideConfig = mDisplayContent.getOverrideConfiguration();
Andrii Kuliand68501e2017-01-10 22:57:27 -0800224
225 // Create new, slightly changed override configuration and apply it to the display.
226 final Configuration newOverrideConfig = new Configuration(currentOverrideConfig);
227 newOverrideConfig.densityDpi += 120;
228 newOverrideConfig.fontScale += 0.3;
229
230 sWm.setNewDisplayOverrideConfiguration(newOverrideConfig, displayId);
231
232 // Check that override config is applied.
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700233 assertEquals(newOverrideConfig, mDisplayContent.getOverrideConfiguration());
Andrii Kulian367ff7f2017-01-25 19:45:34 -0800234 }
235
236 /**
237 * This tests global configuration updates when default display config is updated.
238 */
239 @Test
240 public void testDefaultDisplayOverrideConfigUpdate() throws Exception {
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700241 final Configuration currentConfig = mDisplayContent.getConfiguration();
Andrii Kulian367ff7f2017-01-25 19:45:34 -0800242
243 // Create new, slightly changed override configuration and apply it to the display.
Andrii Kuliana95bfff2017-03-30 19:00:41 -0700244 final Configuration newOverrideConfig = new Configuration(currentConfig);
Andrii Kulian367ff7f2017-01-25 19:45:34 -0800245 newOverrideConfig.densityDpi += 120;
246 newOverrideConfig.fontScale += 0.3;
247
248 sWm.setNewDisplayOverrideConfiguration(newOverrideConfig, DEFAULT_DISPLAY);
Andrii Kuliand68501e2017-01-10 22:57:27 -0800249
250 // Check that global configuration is updated, as we've updated default display's config.
Andrii Kulian367ff7f2017-01-25 19:45:34 -0800251 Configuration globalConfig = sWm.mRoot.getConfiguration();
Andrii Kuliand68501e2017-01-10 22:57:27 -0800252 assertEquals(newOverrideConfig.densityDpi, globalConfig.densityDpi);
253 assertEquals(newOverrideConfig.fontScale, globalConfig.fontScale, 0.1 /* delta */);
Andrii Kulian367ff7f2017-01-25 19:45:34 -0800254
255 // Return back to original values.
Andrii Kuliana95bfff2017-03-30 19:00:41 -0700256 sWm.setNewDisplayOverrideConfiguration(currentConfig, DEFAULT_DISPLAY);
Andrii Kulian367ff7f2017-01-25 19:45:34 -0800257 globalConfig = sWm.mRoot.getConfiguration();
Andrii Kuliana95bfff2017-03-30 19:00:41 -0700258 assertEquals(currentConfig.densityDpi, globalConfig.densityDpi);
259 assertEquals(currentConfig.fontScale, globalConfig.fontScale, 0.1 /* delta */);
Andrii Kuliand68501e2017-01-10 22:57:27 -0800260 }
Wale Ogunwale34247952017-02-19 11:57:53 -0800261
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -0700262 /**
263 * Tests tapping on a stack in different display results in window gaining focus.
264 */
265 @Test
266 public void testInputEventBringsCorrectDisplayInFocus() throws Exception {
267 DisplayContent dc0 = sWm.getDefaultDisplayContentLocked();
268 // Create a second display
269 final DisplayContent dc1 = createNewDisplay();
270
271 // Add stack with activity.
272 final TaskStack stack0 = createTaskStackOnDisplay(dc0);
273 final Task task0 = createTaskInStack(stack0, 0 /* userId */);
274 final WindowTestUtils.TestAppWindowToken token =
chaviw97d28202018-02-27 16:23:53 -0800275 WindowTestUtils.createTestAppWindowToken(dc0);
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -0700276 task0.addChild(token, 0);
277 dc0.mTapDetector = new TaskTapPointerEventListener(sWm, dc0);
278 sWm.registerPointerEventListener(dc0.mTapDetector);
279 final TaskStack stack1 = createTaskStackOnDisplay(dc1);
280 final Task task1 = createTaskInStack(stack1, 0 /* userId */);
281 final WindowTestUtils.TestAppWindowToken token1 =
chaviw97d28202018-02-27 16:23:53 -0800282 WindowTestUtils.createTestAppWindowToken(dc0);
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -0700283 task1.addChild(token1, 0);
284 dc1.mTapDetector = new TaskTapPointerEventListener(sWm, dc0);
285 sWm.registerPointerEventListener(dc1.mTapDetector);
286
287 // tap on primary display (by sending ACTION_DOWN followed by ACTION_UP)
288 DisplayMetrics dm0 = dc0.getDisplayMetrics();
289 dc0.mTapDetector.onPointerEvent(
290 createTapEvent(dm0.widthPixels / 2, dm0.heightPixels / 2, true));
291 dc0.mTapDetector.onPointerEvent(
292 createTapEvent(dm0.widthPixels / 2, dm0.heightPixels / 2, false));
293
294 // Check focus is on primary display.
295 assertEquals(sWm.mCurrentFocus, dc0.findFocusedWindow());
296
297 // Tap on secondary display
298 DisplayMetrics dm1 = dc1.getDisplayMetrics();
299 dc1.mTapDetector.onPointerEvent(
300 createTapEvent(dm1.widthPixels / 2, dm1.heightPixels / 2, true));
301 dc1.mTapDetector.onPointerEvent(
302 createTapEvent(dm1.widthPixels / 2, dm1.heightPixels / 2, false));
303
304 // Check focus is on secondary.
305 assertEquals(sWm.mCurrentFocus, dc1.findFocusedWindow());
306 }
307
David Stevens46939562017-03-24 13:04:00 -0700308 @Test
309 public void testFocusedWindowMultipleDisplays() throws Exception {
Andrii Kulian0214ed92017-05-16 13:44:05 -0700310 // Create a focusable window and check that focus is calculated correctly
David Stevens46939562017-03-24 13:04:00 -0700311 final WindowState window1 =
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700312 createWindow(null, TYPE_BASE_APPLICATION, mDisplayContent, "window1");
David Stevens46939562017-03-24 13:04:00 -0700313 assertEquals(window1, sWm.mRoot.computeFocusedWindow());
314
315 // Check that a new display doesn't affect focus
316 final DisplayContent dc = createNewDisplay();
317 assertEquals(window1, sWm.mRoot.computeFocusedWindow());
318
319 // Add a window to the second display, and it should be focused
320 final WindowState window2 = createWindow(null, TYPE_BASE_APPLICATION, dc, "window2");
321 assertEquals(window2, sWm.mRoot.computeFocusedWindow());
322
323 // Move the first window to the to including parents, and make sure focus is updated
324 window1.getParent().positionChildAt(POSITION_TOP, window1, true);
325 assertEquals(window1, sWm.mRoot.computeFocusedWindow());
326 }
327
Bryce Lee27cec322017-03-21 09:41:37 -0700328 /**
329 * This tests setting the maximum ui width on a display.
330 */
331 @Test
332 public void testMaxUiWidth() throws Exception {
333 final int baseWidth = 1440;
334 final int baseHeight = 2560;
335 final int baseDensity = 300;
336
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700337 mDisplayContent.updateBaseDisplayMetrics(baseWidth, baseHeight, baseDensity);
Bryce Lee27cec322017-03-21 09:41:37 -0700338
339 final int maxWidth = 300;
340 final int resultingHeight = (maxWidth * baseHeight) / baseWidth;
341 final int resultingDensity = (maxWidth * baseDensity) / baseWidth;
342
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700343 mDisplayContent.setMaxUiWidth(maxWidth);
344 verifySizes(mDisplayContent, maxWidth, resultingHeight, resultingDensity);
Bryce Lee27cec322017-03-21 09:41:37 -0700345
346 // Assert setting values again does not change;
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700347 mDisplayContent.updateBaseDisplayMetrics(baseWidth, baseHeight, baseDensity);
348 verifySizes(mDisplayContent, maxWidth, resultingHeight, resultingDensity);
Bryce Lee27cec322017-03-21 09:41:37 -0700349
350 final int smallerWidth = 200;
351 final int smallerHeight = 400;
352 final int smallerDensity = 100;
353
354 // Specify smaller dimension, verify that it is honored
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700355 mDisplayContent.updateBaseDisplayMetrics(smallerWidth, smallerHeight, smallerDensity);
356 verifySizes(mDisplayContent, smallerWidth, smallerHeight, smallerDensity);
Bryce Lee27cec322017-03-21 09:41:37 -0700357
358 // Verify that setting the max width to a greater value than the base width has no effect
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700359 mDisplayContent.setMaxUiWidth(maxWidth);
360 verifySizes(mDisplayContent, smallerWidth, smallerHeight, smallerDensity);
Bryce Lee27cec322017-03-21 09:41:37 -0700361 }
362
Bryce Lee48f4b572017-04-10 10:54:15 -0700363 /**
364 * This test enforces that the pinned stack is always kept as the top stack.
365 */
366 @Test
367 public void testPinnedStackLocation() {
Wale Ogunwale61911492017-10-11 08:50:50 -0700368 final TaskStack pinnedStack = createStackControllerOnStackOnDisplay(
369 WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, mDisplayContent).mContainer;
370 // Ensure that the pinned stack is the top stack
371 assertEquals(pinnedStack, mDisplayContent.getPinnedStack());
372 assertEquals(pinnedStack, mDisplayContent.getTopStack());
Bryce Lee48f4b572017-04-10 10:54:15 -0700373 // By default, this should try to create a new stack on top
Wale Ogunwale61911492017-10-11 08:50:50 -0700374 final TaskStack otherStack = createTaskStackOnDisplay(mDisplayContent);
375 // Ensure that the other stack is on the display.
376 assertEquals(mDisplayContent, otherStack.getDisplayContent());
Bryce Lee48f4b572017-04-10 10:54:15 -0700377 // Ensure that the pinned stack is still on top
Wale Ogunwale61911492017-10-11 08:50:50 -0700378 assertEquals(pinnedStack, mDisplayContent.getTopStack());
Bryce Lee48f4b572017-04-10 10:54:15 -0700379 }
380
Andrii Kulian0214ed92017-05-16 13:44:05 -0700381 /**
382 * Test that WM does not report displays to AM that are pending to be removed.
383 */
384 @Test
385 public void testDontReportDeferredRemoval() {
386 // Create a display and add an animating window to it.
387 final DisplayContent dc = createNewDisplay();
388 final WindowState window = createWindow(null /* parent */, TYPE_BASE_APPLICATION, dc, "w");
389 window.mAnimatingExit = true;
390 // Request display removal, it should be deferred.
391 dc.removeIfPossible();
392 // Request ordered display ids from WM.
393 final SparseIntArray orderedDisplayIds = new SparseIntArray();
394 sWm.getDisplaysInFocusOrder(orderedDisplayIds);
395 // Make sure that display that is marked for removal is not reported.
396 assertEquals(-1, orderedDisplayIds.indexOfValue(dc.getDisplayId()));
397 }
398
Andrii Kulian92c9a942017-10-10 00:41:41 -0700399 @Test
Adrian Roos1cf585052018-01-03 18:43:27 +0100400 public void testDisplayCutout_rot0() throws Exception {
401 synchronized (sWm.getWindowManagerLock()) {
402 final DisplayContent dc = createNewDisplay();
403 dc.mInitialDisplayWidth = 200;
404 dc.mInitialDisplayHeight = 400;
Adrian Roos24264212018-02-19 16:26:15 +0100405 Rect r = new Rect(80, 0, 120, 10);
Adrian Roos6a4fa0e2018-03-05 19:50:16 +0100406 final DisplayCutout cutout = new WmDisplayCutout(
407 fromBoundingRect(r.left, r.top, r.right, r.bottom), null)
408 .computeSafeInsets(200, 400).getDisplayCutout();
Adrian Roos1cf585052018-01-03 18:43:27 +0100409
410 dc.mInitialDisplayCutout = cutout;
411 dc.setRotation(Surface.ROTATION_0);
412 dc.computeScreenConfiguration(new Configuration()); // recomputes dc.mDisplayInfo.
413
414 assertEquals(cutout, dc.getDisplayInfo().displayCutout);
415 }
416 }
417
418 @Test
419 public void testDisplayCutout_rot90() throws Exception {
420 synchronized (sWm.getWindowManagerLock()) {
421 final DisplayContent dc = createNewDisplay();
422 dc.mInitialDisplayWidth = 200;
423 dc.mInitialDisplayHeight = 400;
Adrian Roos24264212018-02-19 16:26:15 +0100424 Rect r1 = new Rect(80, 0, 120, 10);
Adrian Roos6a4fa0e2018-03-05 19:50:16 +0100425 final DisplayCutout cutout = new WmDisplayCutout(
426 fromBoundingRect(r1.left, r1.top, r1.right, r1.bottom), null)
427 .computeSafeInsets(200, 400).getDisplayCutout();
Adrian Roos1cf585052018-01-03 18:43:27 +0100428
429 dc.mInitialDisplayCutout = cutout;
430 dc.setRotation(Surface.ROTATION_90);
431 dc.computeScreenConfiguration(new Configuration()); // recomputes dc.mDisplayInfo.
432
Adrian Roos24264212018-02-19 16:26:15 +0100433 final Rect r = new Rect(0, 80, 10, 120);
Adrian Roos6a4fa0e2018-03-05 19:50:16 +0100434 assertEquals(new WmDisplayCutout(
435 fromBoundingRect(r.left, r.top, r.right, r.bottom), null)
436 .computeSafeInsets(400, 200).getDisplayCutout(), dc.getDisplayInfo().displayCutout);
Adrian Roos1cf585052018-01-03 18:43:27 +0100437 }
438 }
439
440 @Test
Adrian Roos5251b1d2018-03-23 18:57:43 +0100441 public void testLayoutSeq_assignedDuringLayout() throws Exception {
442 synchronized (sWm.getWindowManagerLock()) {
443
444 final DisplayContent dc = createNewDisplay();
445 final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, dc, "w");
446
447 dc.setLayoutNeeded();
448 dc.performLayout(true /* initial */, false /* updateImeWindows */);
449
450 assertThat(win.mLayoutSeq, is(dc.mLayoutSeq));
451 }
452 }
453
454 @Test
Andrii Kulian92c9a942017-10-10 00:41:41 -0700455 @SuppressLint("InlinedApi")
456 public void testOrientationDefinedByKeyguard() {
457 final DisplayContent dc = createNewDisplay();
458 // Create a window that requests landscape orientation. It will define device orientation
459 // by default.
460 final WindowState window = createWindow(null /* parent */, TYPE_BASE_APPLICATION, dc, "w");
461 window.mAppToken.setOrientation(SCREEN_ORIENTATION_LANDSCAPE);
462
463 final WindowState keyguard = createWindow(null, TYPE_STATUS_BAR, dc, "keyguard");
464 keyguard.mHasSurface = true;
465 keyguard.mAttrs.screenOrientation = SCREEN_ORIENTATION_UNSPECIFIED;
466
467 assertEquals("Screen orientation must be defined by the app window by default",
468 SCREEN_ORIENTATION_LANDSCAPE, dc.getOrientation());
469
470 keyguard.mAttrs.screenOrientation = SCREEN_ORIENTATION_PORTRAIT;
471 assertEquals("Visible keyguard must influence device orientation",
472 SCREEN_ORIENTATION_PORTRAIT, dc.getOrientation());
473
474 sWm.setKeyguardGoingAway(true);
475 assertEquals("Keyguard that is going away must not influence device orientation",
476 SCREEN_ORIENTATION_LANDSCAPE, dc.getOrientation());
477 }
478
Andrii Kulianf0379de2018-03-14 16:24:07 -0700479 @Test
480 public void testDisableDisplayInfoOverrideFromWindowManager() {
481 final DisplayContent dc = createNewDisplay();
482
483 assertTrue(dc.mShouldOverrideDisplayConfiguration);
484 sWm.dontOverrideDisplayInfo(dc.getDisplayId());
485
486 assertFalse(dc.mShouldOverrideDisplayConfiguration);
487 verify(sWm.mDisplayManagerInternal, times(1))
488 .setDisplayInfoOverrideFromWindowManager(dc.getDisplayId(), null);
489 }
490
Bryce Lee27cec322017-03-21 09:41:37 -0700491 private static void verifySizes(DisplayContent displayContent, int expectedBaseWidth,
492 int expectedBaseHeight, int expectedBaseDensity) {
493 assertEquals(displayContent.mBaseDisplayWidth, expectedBaseWidth);
494 assertEquals(displayContent.mBaseDisplayHeight, expectedBaseHeight);
495 assertEquals(displayContent.mBaseDisplayDensity, expectedBaseDensity);
496 }
497
Wale Ogunwale34247952017-02-19 11:57:53 -0800498 private void assertForAllWindowsOrder(List<WindowState> expectedWindows) {
499 final LinkedList<WindowState> actualWindows = new LinkedList();
500
501 // Test forward traversal.
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700502 mDisplayContent.forAllWindows(actualWindows::addLast, false /* traverseTopToBottom */);
Wale Ogunwale34247952017-02-19 11:57:53 -0800503 assertEquals(expectedWindows.size(), actualWindows.size());
504 for (WindowState w : expectedWindows) {
505 assertEquals(w, actualWindows.pollFirst());
506 }
507 assertTrue(actualWindows.isEmpty());
508
509 // Test backward traversal.
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700510 mDisplayContent.forAllWindows(actualWindows::addLast, true /* traverseTopToBottom */);
Wale Ogunwale34247952017-02-19 11:57:53 -0800511 assertEquals(expectedWindows.size(), actualWindows.size());
512 for (WindowState w : expectedWindows) {
513 assertEquals(w, actualWindows.pollLast());
514 }
515 assertTrue(actualWindows.isEmpty());
516 }
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -0700517
518 private MotionEvent createTapEvent(float x, float y, boolean isDownEvent) {
519 final long downTime = SystemClock.uptimeMillis();
520 final long eventTime = SystemClock.uptimeMillis() + 100;
521 final int metaState = 0;
522
523 return MotionEvent.obtain(
524 downTime,
525 eventTime,
526 isDownEvent ? MotionEvent.ACTION_DOWN : MotionEvent.ACTION_UP,
527 x,
528 y,
529 metaState);
530 }
Wale Ogunwaleb783fd82016-11-04 09:51:54 -0700531}