blob: a62bc713db40a4e7d55eefd6a7e26cd6a89d7080 [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
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -070014 * limitations under the License.
Wale Ogunwaleb783fd82016-11-04 09:51:54 -070015 */
16
17package com.android.server.wm;
18
Andrii Kulian92c9a942017-10-10 00:41:41 -070019import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
20import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
21import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
Tiger Huang51c5a1d2018-12-11 20:24:51 +080022import static android.os.Build.VERSION_CODES.P;
23import static android.os.Build.VERSION_CODES.Q;
Wale Ogunwale34247952017-02-19 11:57:53 -080024import static android.view.Display.DEFAULT_DISPLAY;
Issei Suzuki43190bd2018-08-20 17:28:41 +020025import static android.view.DisplayCutout.BOUNDS_POSITION_LEFT;
26import static android.view.DisplayCutout.BOUNDS_POSITION_TOP;
Adrian Roos24264212018-02-19 16:26:15 +010027import static android.view.DisplayCutout.fromBoundingRect;
Wale Ogunwale34247952017-02-19 11:57:53 -080028import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
29import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
30import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
Andrii Kulian92c9a942017-10-10 00:41:41 -070031import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
Wale Ogunwale34247952017-02-19 11:57:53 -080032import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION;
Brett Chabota26eda92018-07-23 13:08:30 -070033
Garfield Tan90b04282018-12-11 14:04:42 -080034import static com.android.dx.mockito.inline.extended.ExtendedMockito.any;
35import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyBoolean;
Tadashi G. Takaokabf0d57b2018-11-19 16:09:58 +090036import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
Garfield Tan90b04282018-12-11 14:04:42 -080037import static com.android.dx.mockito.inline.extended.ExtendedMockito.eq;
38import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
39import static com.android.dx.mockito.inline.extended.ExtendedMockito.never;
40import static com.android.dx.mockito.inline.extended.ExtendedMockito.same;
Tadashi G. Takaokabf0d57b2018-11-19 16:09:58 +090041import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy;
42import static com.android.dx.mockito.inline.extended.ExtendedMockito.times;
43import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
David Stevens46939562017-03-24 13:04:00 -070044import static com.android.server.wm.WindowContainer.POSITION_TOP;
Tiger Huang1e5b10a2018-07-30 20:19:51 +080045import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_NORMAL;
chaviwebcbc342018-02-07 13:19:00 -080046
Adrian Roos5251b1d2018-03-23 18:57:43 +010047import static org.hamcrest.Matchers.is;
Wale Ogunwale34247952017-02-19 11:57:53 -080048import static org.junit.Assert.assertEquals;
Andrii Kulianf0379de2018-03-14 16:24:07 -070049import static org.junit.Assert.assertFalse;
Arthur Hungbe5ce212018-09-13 18:41:56 +080050import static org.junit.Assert.assertNotNull;
lumarkff0ab692018-11-05 20:32:30 +080051import static org.junit.Assert.assertNull;
Adrian Roos5251b1d2018-03-23 18:57:43 +010052import static org.junit.Assert.assertThat;
Wale Ogunwale34247952017-02-19 11:57:53 -080053import static org.junit.Assert.assertTrue;
Tarandeep Singha6f35612019-01-11 19:50:46 -080054import static org.mockito.ArgumentMatchers.eq;
Wale Ogunwale34247952017-02-19 11:57:53 -080055
Andrii Kulian92c9a942017-10-10 00:41:41 -070056import android.annotation.SuppressLint;
Tarandeep Singha6f35612019-01-11 19:50:46 -080057import android.app.WindowConfiguration;
Andrii Kuliand68501e2017-01-10 22:57:27 -080058import android.content.res.Configuration;
Adrian Roos1cf585052018-01-03 18:43:27 +010059import android.graphics.Rect;
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -070060import android.os.SystemClock;
Wale Ogunwaleb783fd82016-11-04 09:51:54 -070061import android.platform.test.annotations.Presubmit;
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -070062import android.util.DisplayMetrics;
Adrian Roos1cf585052018-01-03 18:43:27 +010063import android.view.DisplayCutout;
Tarandeep Singha6f35612019-01-11 19:50:46 -080064import android.view.DisplayInfo;
Riddle Hsua4d6fa22018-08-11 00:50:39 +080065import android.view.Gravity;
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -070066import android.view.MotionEvent;
Adrian Roos1cf585052018-01-03 18:43:27 +010067import android.view.Surface;
Tarandeep Singha6f35612019-01-11 19:50:46 -080068import android.view.ViewRootImpl;
69import android.view.test.InsetsModeSession;
Wale Ogunwaleb783fd82016-11-04 09:51:54 -070070
Brett Chabota26eda92018-07-23 13:08:30 -070071import androidx.test.filters.FlakyTest;
72import androidx.test.filters.SmallTest;
Brett Chabota26eda92018-07-23 13:08:30 -070073
Garfield Tan90b04282018-12-11 14:04:42 -080074import com.android.dx.mockito.inline.extended.ExtendedMockito;
Adrian Roos6a4fa0e2018-03-05 19:50:16 +010075import com.android.server.wm.utils.WmDisplayCutout;
76
Brett Chabota26eda92018-07-23 13:08:30 -070077import org.junit.Test;
Garfield Tan90b04282018-12-11 14:04:42 -080078import org.mockito.ArgumentCaptor;
Brett Chabota26eda92018-07-23 13:08:30 -070079
Adrian Roos0f9368c2018-04-08 10:59:08 -070080import java.util.ArrayList;
Wale Ogunwale34247952017-02-19 11:57:53 -080081import java.util.Arrays;
Adrian Roos0f9368c2018-04-08 10:59:08 -070082import java.util.Collections;
Wale Ogunwale34247952017-02-19 11:57:53 -080083import java.util.LinkedList;
84import java.util.List;
Wale Ogunwaleb783fd82016-11-04 09:51:54 -070085
86/**
87 * Tests for the {@link DisplayContent} class.
88 *
89 * Build/Install/Run:
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -070090 * atest FrameworksServicesTests:DisplayContentTests
Wale Ogunwaleb783fd82016-11-04 09:51:54 -070091 */
92@SmallTest
93@Presubmit
Wale Ogunwale44fbdf52016-11-16 10:18:45 -080094public class DisplayContentTests extends WindowTestsBase {
Wale Ogunwaleb783fd82016-11-04 09:51:54 -070095
96 @Test
Adrian Roos0f9368c2018-04-08 10:59:08 -070097 @FlakyTest(bugId = 77772044)
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -070098 public void testForAllWindows() {
Wale Ogunwale3c1170d2016-12-02 14:44:52 -080099 final WindowState exitingAppWindow = createWindow(null, TYPE_BASE_APPLICATION,
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700100 mDisplayContent, "exiting app");
Wale Ogunwaleb783fd82016-11-04 09:51:54 -0700101 final AppWindowToken exitingAppToken = exitingAppWindow.mAppToken;
102 exitingAppToken.mIsExiting = true;
Bryce Lee6d410262017-02-28 15:30:17 -0800103 exitingAppToken.getTask().mStack.mExitingAppTokens.add(exitingAppToken);
Wale Ogunwaleb783fd82016-11-04 09:51:54 -0700104
Wale Ogunwale34247952017-02-19 11:57:53 -0800105 assertForAllWindowsOrder(Arrays.asList(
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700106 mWallpaperWindow,
Wale Ogunwale34247952017-02-19 11:57:53 -0800107 exitingAppWindow,
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700108 mChildAppWindowBelow,
109 mAppWindow,
110 mChildAppWindowAbove,
111 mDockedDividerWindow,
112 mStatusBarWindow,
113 mNavBarWindow,
114 mImeWindow,
115 mImeDialogWindow));
Wale Ogunwale3c1170d2016-12-02 14:44:52 -0800116 }
117
118 @Test
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700119 public void testForAllWindows_WithAppImeTarget() {
Wale Ogunwale3c1170d2016-12-02 14:44:52 -0800120 final WindowState imeAppTarget =
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700121 createWindow(null, TYPE_BASE_APPLICATION, mDisplayContent, "imeAppTarget");
Wale Ogunwale3c1170d2016-12-02 14:44:52 -0800122
lumarkff0ab692018-11-05 20:32:30 +0800123 mDisplayContent.mInputMethodTarget = imeAppTarget;
Wale Ogunwale3c1170d2016-12-02 14:44:52 -0800124
Wale Ogunwale34247952017-02-19 11:57:53 -0800125 assertForAllWindowsOrder(Arrays.asList(
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700126 mWallpaperWindow,
127 mChildAppWindowBelow,
128 mAppWindow,
129 mChildAppWindowAbove,
Wale Ogunwale34247952017-02-19 11:57:53 -0800130 imeAppTarget,
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700131 mImeWindow,
132 mImeDialogWindow,
133 mDockedDividerWindow,
134 mStatusBarWindow,
135 mNavBarWindow));
Wale Ogunwale34247952017-02-19 11:57:53 -0800136 }
Wale Ogunwale3c1170d2016-12-02 14:44:52 -0800137
Wale Ogunwale34247952017-02-19 11:57:53 -0800138 @Test
lumarkff0ab692018-11-05 20:32:30 +0800139 public void testForAllWindows_WithChildWindowImeTarget() throws Exception {
140 mDisplayContent.mInputMethodTarget = mChildAppWindowAbove;
Wale Ogunwale3c1170d2016-12-02 14:44:52 -0800141
Wale Ogunwale34247952017-02-19 11:57:53 -0800142 assertForAllWindowsOrder(Arrays.asList(
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700143 mWallpaperWindow,
144 mChildAppWindowBelow,
145 mAppWindow,
146 mChildAppWindowAbove,
147 mImeWindow,
148 mImeDialogWindow,
149 mDockedDividerWindow,
150 mStatusBarWindow,
151 mNavBarWindow));
Wale Ogunwaleb783fd82016-11-04 09:51:54 -0700152 }
Wale Ogunwale5d7e7f12016-12-12 14:47:05 -0800153
154 @Test
lumarkff0ab692018-11-05 20:32:30 +0800155 public void testForAllWindows_WithStatusBarImeTarget() throws Exception {
156 mDisplayContent.mInputMethodTarget = mStatusBarWindow;
Wale Ogunwale6ce0fb82016-12-13 14:24:00 -0800157
Wale Ogunwale34247952017-02-19 11:57:53 -0800158 assertForAllWindowsOrder(Arrays.asList(
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700159 mWallpaperWindow,
160 mChildAppWindowBelow,
161 mAppWindow,
162 mChildAppWindowAbove,
163 mDockedDividerWindow,
164 mStatusBarWindow,
165 mImeWindow,
166 mImeDialogWindow,
167 mNavBarWindow));
Wale Ogunwale6ce0fb82016-12-13 14:24:00 -0800168 }
169
170 @Test
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700171 public void testForAllWindows_WithInBetweenWindowToken() {
Wale Ogunwale5d7e7f12016-12-12 14:47:05 -0800172 // This window is set-up to be z-ordered between some windows that go in the same token like
173 // the nav bar and status bar.
174 final WindowState voiceInteractionWindow = createWindow(null, TYPE_VOICE_INTERACTION,
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700175 mDisplayContent, "voiceInteractionWindow");
Wale Ogunwale5d7e7f12016-12-12 14:47:05 -0800176
Wale Ogunwale34247952017-02-19 11:57:53 -0800177 assertForAllWindowsOrder(Arrays.asList(
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700178 mWallpaperWindow,
179 mChildAppWindowBelow,
180 mAppWindow,
181 mChildAppWindowAbove,
182 mDockedDividerWindow,
Wale Ogunwale34247952017-02-19 11:57:53 -0800183 voiceInteractionWindow,
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700184 mStatusBarWindow,
185 mNavBarWindow,
186 mImeWindow,
187 mImeDialogWindow));
Wale Ogunwale34247952017-02-19 11:57:53 -0800188 }
Wale Ogunwale5d7e7f12016-12-12 14:47:05 -0800189
Wale Ogunwale34247952017-02-19 11:57:53 -0800190 @Test
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700191 public void testComputeImeTarget() {
Wale Ogunwale34247952017-02-19 11:57:53 -0800192 // Verify that an app window can be an ime target.
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700193 final WindowState appWin = createWindow(null, TYPE_APPLICATION, mDisplayContent, "appWin");
Wale Ogunwale34247952017-02-19 11:57:53 -0800194 appWin.setHasSurface(true);
195 assertTrue(appWin.canBeImeTarget());
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700196 WindowState imeTarget = mDisplayContent.computeImeTarget(false /* updateImeTarget */);
Wale Ogunwale34247952017-02-19 11:57:53 -0800197 assertEquals(appWin, imeTarget);
chaviwebcbc342018-02-07 13:19:00 -0800198 appWin.mHidden = false;
Wale Ogunwale5d7e7f12016-12-12 14:47:05 -0800199
Wale Ogunwale34247952017-02-19 11:57:53 -0800200 // Verify that an child window can be an ime target.
201 final WindowState childWin = createWindow(appWin,
202 TYPE_APPLICATION_ATTACHED_DIALOG, "childWin");
203 childWin.setHasSurface(true);
204 assertTrue(childWin.canBeImeTarget());
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700205 imeTarget = mDisplayContent.computeImeTarget(false /* updateImeTarget */);
Wale Ogunwale34247952017-02-19 11:57:53 -0800206 assertEquals(childWin, imeTarget);
Wale Ogunwale5d7e7f12016-12-12 14:47:05 -0800207 }
Andrii Kulian6cc1a1d2016-12-27 23:52:59 -0800208
Andrii Kuliand68501e2017-01-10 22:57:27 -0800209 /**
210 * This tests stack movement between displays and proper stack's, task's and app token's display
211 * container references updates.
212 */
Andrii Kulian6cc1a1d2016-12-27 23:52:59 -0800213 @Test
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700214 public void testMoveStackBetweenDisplays() {
Andrii Kulian367ff7f2017-01-25 19:45:34 -0800215 // Create a second display.
216 final DisplayContent dc = createNewDisplay();
Andrii Kulian6cc1a1d2016-12-27 23:52:59 -0800217
218 // Add stack with activity.
219 final TaskStack stack = createTaskStackOnDisplay(dc);
220 assertEquals(dc.getDisplayId(), stack.getDisplayContent().getDisplayId());
221 assertEquals(dc, stack.getParent().getParent());
222 assertEquals(dc, stack.getDisplayContent());
223
224 final Task task = createTaskInStack(stack, 0 /* userId */);
chaviw97d28202018-02-27 16:23:53 -0800225 final WindowTestUtils.TestAppWindowToken token = WindowTestUtils.createTestAppWindowToken(
226 dc);
Andrii Kulian6cc1a1d2016-12-27 23:52:59 -0800227 task.addChild(token, 0);
228 assertEquals(dc, task.getDisplayContent());
229 assertEquals(dc, token.getDisplayContent());
230
231 // Move stack to first display.
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700232 mDisplayContent.moveStackToDisplay(stack, true /* onTop */);
233 assertEquals(mDisplayContent.getDisplayId(), stack.getDisplayContent().getDisplayId());
234 assertEquals(mDisplayContent, stack.getParent().getParent());
235 assertEquals(mDisplayContent, stack.getDisplayContent());
236 assertEquals(mDisplayContent, task.getDisplayContent());
237 assertEquals(mDisplayContent, token.getDisplayContent());
Andrii Kulian6cc1a1d2016-12-27 23:52:59 -0800238 }
Andrii Kuliand68501e2017-01-10 22:57:27 -0800239
240 /**
241 * This tests override configuration updates for display content.
242 */
243 @Test
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700244 public void testDisplayOverrideConfigUpdate() {
Evan Roskydfe3da72018-10-26 17:21:06 -0700245 final Configuration currentOverrideConfig =
246 mDisplayContent.getRequestedOverrideConfiguration();
Andrii Kuliand68501e2017-01-10 22:57:27 -0800247
248 // Create new, slightly changed override configuration and apply it to the display.
249 final Configuration newOverrideConfig = new Configuration(currentOverrideConfig);
250 newOverrideConfig.densityDpi += 120;
251 newOverrideConfig.fontScale += 0.3;
252
Evan Roskye747c3e2018-10-30 20:06:41 -0700253 mWm.setNewDisplayOverrideConfiguration(newOverrideConfig, mDisplayContent);
Andrii Kuliand68501e2017-01-10 22:57:27 -0800254
255 // Check that override config is applied.
Evan Roskydfe3da72018-10-26 17:21:06 -0700256 assertEquals(newOverrideConfig, mDisplayContent.getRequestedOverrideConfiguration());
Andrii Kulian367ff7f2017-01-25 19:45:34 -0800257 }
258
259 /**
260 * This tests global configuration updates when default display config is updated.
261 */
262 @Test
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700263 public void testDefaultDisplayOverrideConfigUpdate() {
Evan Roskye747c3e2018-10-30 20:06:41 -0700264 DisplayContent defaultDisplay = mWm.mRoot.getDisplayContent(DEFAULT_DISPLAY);
265 final Configuration currentConfig = defaultDisplay.getConfiguration();
Andrii Kulian367ff7f2017-01-25 19:45:34 -0800266
267 // Create new, slightly changed override configuration and apply it to the display.
Andrii Kuliana95bfff2017-03-30 19:00:41 -0700268 final Configuration newOverrideConfig = new Configuration(currentConfig);
Andrii Kulian367ff7f2017-01-25 19:45:34 -0800269 newOverrideConfig.densityDpi += 120;
270 newOverrideConfig.fontScale += 0.3;
271
Evan Roskye747c3e2018-10-30 20:06:41 -0700272 mWm.setNewDisplayOverrideConfiguration(newOverrideConfig, defaultDisplay);
Andrii Kuliand68501e2017-01-10 22:57:27 -0800273
274 // Check that global configuration is updated, as we've updated default display's config.
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700275 Configuration globalConfig = mWm.mRoot.getConfiguration();
Andrii Kuliand68501e2017-01-10 22:57:27 -0800276 assertEquals(newOverrideConfig.densityDpi, globalConfig.densityDpi);
277 assertEquals(newOverrideConfig.fontScale, globalConfig.fontScale, 0.1 /* delta */);
Andrii Kulian367ff7f2017-01-25 19:45:34 -0800278
279 // Return back to original values.
Evan Roskye747c3e2018-10-30 20:06:41 -0700280 mWm.setNewDisplayOverrideConfiguration(currentConfig, defaultDisplay);
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700281 globalConfig = mWm.mRoot.getConfiguration();
Andrii Kuliana95bfff2017-03-30 19:00:41 -0700282 assertEquals(currentConfig.densityDpi, globalConfig.densityDpi);
283 assertEquals(currentConfig.fontScale, globalConfig.fontScale, 0.1 /* delta */);
Andrii Kuliand68501e2017-01-10 22:57:27 -0800284 }
Wale Ogunwale34247952017-02-19 11:57:53 -0800285
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -0700286 /**
287 * Tests tapping on a stack in different display results in window gaining focus.
288 */
289 @Test
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700290 public void testInputEventBringsCorrectDisplayInFocus() {
291 DisplayContent dc0 = mWm.getDefaultDisplayContentLocked();
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -0700292 // Create a second display
293 final DisplayContent dc1 = createNewDisplay();
294
295 // Add stack with activity.
296 final TaskStack stack0 = createTaskStackOnDisplay(dc0);
297 final Task task0 = createTaskInStack(stack0, 0 /* userId */);
298 final WindowTestUtils.TestAppWindowToken token =
chaviw97d28202018-02-27 16:23:53 -0800299 WindowTestUtils.createTestAppWindowToken(dc0);
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -0700300 task0.addChild(token, 0);
Arthur Hungbe5ce212018-09-13 18:41:56 +0800301 dc0.configureDisplayPolicy();
302 assertNotNull(dc0.mTapDetector);
303
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -0700304 final TaskStack stack1 = createTaskStackOnDisplay(dc1);
305 final Task task1 = createTaskInStack(stack1, 0 /* userId */);
306 final WindowTestUtils.TestAppWindowToken token1 =
chaviw97d28202018-02-27 16:23:53 -0800307 WindowTestUtils.createTestAppWindowToken(dc0);
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -0700308 task1.addChild(token1, 0);
Arthur Hungbe5ce212018-09-13 18:41:56 +0800309 dc1.configureDisplayPolicy();
310 assertNotNull(dc1.mTapDetector);
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -0700311
Arthur Hungbe5ce212018-09-13 18:41:56 +0800312 // tap on primary display.
313 tapOnDisplay(dc0);
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -0700314 // Check focus is on primary display.
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700315 assertEquals(mWm.mRoot.getTopFocusedDisplayContent().mCurrentFocus,
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800316 dc0.findFocusedWindow());
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -0700317
Arthur Hungbe5ce212018-09-13 18:41:56 +0800318 // Tap on secondary display.
319 tapOnDisplay(dc1);
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -0700320 // Check focus is on secondary.
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700321 assertEquals(mWm.mRoot.getTopFocusedDisplayContent().mCurrentFocus,
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800322 dc1.findFocusedWindow());
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -0700323 }
324
David Stevens46939562017-03-24 13:04:00 -0700325 @Test
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700326 public void testFocusedWindowMultipleDisplays() {
Tiger Huang51c5a1d2018-12-11 20:24:51 +0800327 doTestFocusedWindowMultipleDisplays(false /* perDisplayFocusEnabled */, Q);
328 }
329
330 @Test
331 public void testFocusedWindowMultipleDisplaysPerDisplayFocusEnabled() {
332 doTestFocusedWindowMultipleDisplays(true /* perDisplayFocusEnabled */, Q);
333 }
334
335 @Test
336 public void testFocusedWindowMultipleDisplaysPerDisplayFocusEnabledLegacyApp() {
337 doTestFocusedWindowMultipleDisplays(true /* perDisplayFocusEnabled */, P);
338 }
339
340 private void doTestFocusedWindowMultipleDisplays(boolean perDisplayFocusEnabled,
341 int targetSdk) {
342 mWm.mPerDisplayFocusEnabled = perDisplayFocusEnabled;
343
Andrii Kulian0214ed92017-05-16 13:44:05 -0700344 // Create a focusable window and check that focus is calculated correctly
David Stevens46939562017-03-24 13:04:00 -0700345 final WindowState window1 =
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700346 createWindow(null, TYPE_BASE_APPLICATION, mDisplayContent, "window1");
Tiger Huang51c5a1d2018-12-11 20:24:51 +0800347 window1.mAppToken.mTargetSdk = targetSdk;
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800348 updateFocusedWindow();
349 assertTrue(window1.isFocused());
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700350 assertEquals(window1, mWm.mRoot.getTopFocusedDisplayContent().mCurrentFocus);
David Stevens46939562017-03-24 13:04:00 -0700351
352 // Check that a new display doesn't affect focus
353 final DisplayContent dc = createNewDisplay();
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800354 updateFocusedWindow();
355 assertTrue(window1.isFocused());
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700356 assertEquals(window1, mWm.mRoot.getTopFocusedDisplayContent().mCurrentFocus);
David Stevens46939562017-03-24 13:04:00 -0700357
358 // Add a window to the second display, and it should be focused
359 final WindowState window2 = createWindow(null, TYPE_BASE_APPLICATION, dc, "window2");
Tiger Huang51c5a1d2018-12-11 20:24:51 +0800360 window2.mAppToken.mTargetSdk = targetSdk;
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800361 updateFocusedWindow();
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800362 assertTrue(window2.isFocused());
Tiger Huang51c5a1d2018-12-11 20:24:51 +0800363 assertEquals(perDisplayFocusEnabled && targetSdk >= Q, window1.isFocused());
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700364 assertEquals(window2, mWm.mRoot.getTopFocusedDisplayContent().mCurrentFocus);
David Stevens46939562017-03-24 13:04:00 -0700365
Tiger Huang51c5a1d2018-12-11 20:24:51 +0800366 // Move the first window to top including parents, and make sure focus is updated
David Stevens46939562017-03-24 13:04:00 -0700367 window1.getParent().positionChildAt(POSITION_TOP, window1, true);
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800368 updateFocusedWindow();
369 assertTrue(window1.isFocused());
Tiger Huang51c5a1d2018-12-11 20:24:51 +0800370 assertEquals(perDisplayFocusEnabled && targetSdk >= Q, window2.isFocused());
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700371 assertEquals(window1, mWm.mRoot.getTopFocusedDisplayContent().mCurrentFocus);
Adrian Roos4163d622018-05-22 16:56:35 +0200372 }
373
Bryce Lee27cec322017-03-21 09:41:37 -0700374 /**
375 * This tests setting the maximum ui width on a display.
376 */
377 @Test
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700378 public void testMaxUiWidth() {
Riddle Hsu654a6f92018-07-13 22:59:36 +0800379 // Prevent base display metrics for test from being updated to the value of real display.
380 final DisplayContent displayContent = createDisplayNoUpdateDisplayInfo();
Bryce Lee27cec322017-03-21 09:41:37 -0700381 final int baseWidth = 1440;
382 final int baseHeight = 2560;
383 final int baseDensity = 300;
384
Riddle Hsu654a6f92018-07-13 22:59:36 +0800385 displayContent.updateBaseDisplayMetrics(baseWidth, baseHeight, baseDensity);
Bryce Lee27cec322017-03-21 09:41:37 -0700386
387 final int maxWidth = 300;
388 final int resultingHeight = (maxWidth * baseHeight) / baseWidth;
389 final int resultingDensity = (maxWidth * baseDensity) / baseWidth;
390
Riddle Hsu654a6f92018-07-13 22:59:36 +0800391 displayContent.setMaxUiWidth(maxWidth);
392 verifySizes(displayContent, maxWidth, resultingHeight, resultingDensity);
Bryce Lee27cec322017-03-21 09:41:37 -0700393
394 // Assert setting values again does not change;
Riddle Hsu654a6f92018-07-13 22:59:36 +0800395 displayContent.updateBaseDisplayMetrics(baseWidth, baseHeight, baseDensity);
396 verifySizes(displayContent, maxWidth, resultingHeight, resultingDensity);
Bryce Lee27cec322017-03-21 09:41:37 -0700397
398 final int smallerWidth = 200;
399 final int smallerHeight = 400;
400 final int smallerDensity = 100;
401
402 // Specify smaller dimension, verify that it is honored
Riddle Hsu654a6f92018-07-13 22:59:36 +0800403 displayContent.updateBaseDisplayMetrics(smallerWidth, smallerHeight, smallerDensity);
404 verifySizes(displayContent, smallerWidth, smallerHeight, smallerDensity);
Bryce Lee27cec322017-03-21 09:41:37 -0700405
406 // Verify that setting the max width to a greater value than the base width has no effect
Riddle Hsu654a6f92018-07-13 22:59:36 +0800407 displayContent.setMaxUiWidth(maxWidth);
408 verifySizes(displayContent, smallerWidth, smallerHeight, smallerDensity);
Bryce Lee27cec322017-03-21 09:41:37 -0700409 }
410
Andrii Kulian92c9a942017-10-10 00:41:41 -0700411 @Test
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700412 public void testDisplayCutout_rot0() {
413 synchronized (mWm.getWindowManagerLock()) {
Adrian Roos1cf585052018-01-03 18:43:27 +0100414 final DisplayContent dc = createNewDisplay();
415 dc.mInitialDisplayWidth = 200;
416 dc.mInitialDisplayHeight = 400;
Adrian Roos24264212018-02-19 16:26:15 +0100417 Rect r = new Rect(80, 0, 120, 10);
Adrian Roos6a4fa0e2018-03-05 19:50:16 +0100418 final DisplayCutout cutout = new WmDisplayCutout(
Issei Suzuki43190bd2018-08-20 17:28:41 +0200419 fromBoundingRect(r.left, r.top, r.right, r.bottom, BOUNDS_POSITION_TOP), null)
Adrian Roos6a4fa0e2018-03-05 19:50:16 +0100420 .computeSafeInsets(200, 400).getDisplayCutout();
Adrian Roos1cf585052018-01-03 18:43:27 +0100421
422 dc.mInitialDisplayCutout = cutout;
423 dc.setRotation(Surface.ROTATION_0);
424 dc.computeScreenConfiguration(new Configuration()); // recomputes dc.mDisplayInfo.
425
426 assertEquals(cutout, dc.getDisplayInfo().displayCutout);
427 }
428 }
429
430 @Test
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700431 public void testDisplayCutout_rot90() {
432 synchronized (mWm.getWindowManagerLock()) {
Riddle Hsu654a6f92018-07-13 22:59:36 +0800433 // Prevent mInitialDisplayCutout from being updated from real display (e.g. null
434 // if the device has no cutout).
435 final DisplayContent dc = createDisplayNoUpdateDisplayInfo();
436 // Rotation may use real display info to compute bound, so here also uses the
437 // same width and height.
438 final int displayWidth = dc.mInitialDisplayWidth;
439 final int displayHeight = dc.mInitialDisplayHeight;
440 final int cutoutWidth = 40;
441 final int cutoutHeight = 10;
442 final int left = (displayWidth - cutoutWidth) / 2;
443 final int top = 0;
444 final int right = (displayWidth + cutoutWidth) / 2;
445 final int bottom = cutoutHeight;
446
447 final Rect r1 = new Rect(left, top, right, bottom);
Adrian Roos6a4fa0e2018-03-05 19:50:16 +0100448 final DisplayCutout cutout = new WmDisplayCutout(
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700449 fromBoundingRect(r1.left, r1.top, r1.right, r1.bottom, BOUNDS_POSITION_TOP),
450 null)
Riddle Hsu654a6f92018-07-13 22:59:36 +0800451 .computeSafeInsets(displayWidth, displayHeight).getDisplayCutout();
Adrian Roos1cf585052018-01-03 18:43:27 +0100452
453 dc.mInitialDisplayCutout = cutout;
454 dc.setRotation(Surface.ROTATION_90);
455 dc.computeScreenConfiguration(new Configuration()); // recomputes dc.mDisplayInfo.
456
Riddle Hsu654a6f92018-07-13 22:59:36 +0800457 // ----o---------- -------------
458 // | | | | |
459 // | ------o | o---
460 // | | | |
461 // | | -> | |
462 // | | ---o
463 // | | |
464 // | | -------------
465 final Rect r = new Rect(top, left, bottom, right);
Adrian Roos6a4fa0e2018-03-05 19:50:16 +0100466 assertEquals(new WmDisplayCutout(
Issei Suzuki43190bd2018-08-20 17:28:41 +0200467 fromBoundingRect(r.left, r.top, r.right, r.bottom, BOUNDS_POSITION_LEFT), null)
Riddle Hsu654a6f92018-07-13 22:59:36 +0800468 .computeSafeInsets(displayHeight, displayWidth)
469 .getDisplayCutout(), dc.getDisplayInfo().displayCutout);
Adrian Roos1cf585052018-01-03 18:43:27 +0100470 }
471 }
472
473 @Test
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700474 public void testLayoutSeq_assignedDuringLayout() {
475 synchronized (mWm.getWindowManagerLock()) {
Adrian Roos5251b1d2018-03-23 18:57:43 +0100476
477 final DisplayContent dc = createNewDisplay();
478 final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, dc, "w");
479
480 dc.setLayoutNeeded();
481 dc.performLayout(true /* initial */, false /* updateImeWindows */);
482
483 assertThat(win.mLayoutSeq, is(dc.mLayoutSeq));
484 }
485 }
486
487 @Test
Andrii Kulian92c9a942017-10-10 00:41:41 -0700488 @SuppressLint("InlinedApi")
489 public void testOrientationDefinedByKeyguard() {
490 final DisplayContent dc = createNewDisplay();
Garfield Tan90b04282018-12-11 14:04:42 -0800491
492 // When display content is created its configuration is not yet initialized, which could
493 // cause unnecessary configuration propagation, so initialize it here.
494 final Configuration config = new Configuration();
495 dc.computeScreenConfiguration(config);
496 dc.onRequestedOverrideConfigurationChanged(config);
497
Andrii Kulian92c9a942017-10-10 00:41:41 -0700498 // Create a window that requests landscape orientation. It will define device orientation
499 // by default.
500 final WindowState window = createWindow(null /* parent */, TYPE_BASE_APPLICATION, dc, "w");
501 window.mAppToken.setOrientation(SCREEN_ORIENTATION_LANDSCAPE);
502
503 final WindowState keyguard = createWindow(null, TYPE_STATUS_BAR, dc, "keyguard");
504 keyguard.mHasSurface = true;
505 keyguard.mAttrs.screenOrientation = SCREEN_ORIENTATION_UNSPECIFIED;
506
507 assertEquals("Screen orientation must be defined by the app window by default",
508 SCREEN_ORIENTATION_LANDSCAPE, dc.getOrientation());
509
510 keyguard.mAttrs.screenOrientation = SCREEN_ORIENTATION_PORTRAIT;
511 assertEquals("Visible keyguard must influence device orientation",
512 SCREEN_ORIENTATION_PORTRAIT, dc.getOrientation());
513
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700514 mWm.setKeyguardGoingAway(true);
Andrii Kulian92c9a942017-10-10 00:41:41 -0700515 assertEquals("Keyguard that is going away must not influence device orientation",
516 SCREEN_ORIENTATION_LANDSCAPE, dc.getOrientation());
517 }
518
Andrii Kulianf0379de2018-03-14 16:24:07 -0700519 @Test
520 public void testDisableDisplayInfoOverrideFromWindowManager() {
521 final DisplayContent dc = createNewDisplay();
522
523 assertTrue(dc.mShouldOverrideDisplayConfiguration);
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700524 mWm.dontOverrideDisplayInfo(dc.getDisplayId());
Andrii Kulianf0379de2018-03-14 16:24:07 -0700525
526 assertFalse(dc.mShouldOverrideDisplayConfiguration);
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700527 verify(mWm.mDisplayManagerInternal, times(1))
Andrii Kulianf0379de2018-03-14 16:24:07 -0700528 .setDisplayInfoOverrideFromWindowManager(dc.getDisplayId(), null);
529 }
530
Riddle Hsua4d6fa22018-08-11 00:50:39 +0800531 @Test
Riddle Hsu85bd04b2018-11-17 00:34:36 +0800532 public void testClearLastFocusWhenReparentingFocusedWindow() {
533 final DisplayContent defaultDisplay = mWm.getDefaultDisplayContentLocked();
534 final WindowState window = createWindow(null /* parent */, TYPE_BASE_APPLICATION,
535 defaultDisplay, "window");
536 defaultDisplay.mLastFocus = window;
537 mDisplayContent.mCurrentFocus = window;
538 mDisplayContent.reParentWindowToken(window.mToken);
539
540 assertNull(defaultDisplay.mLastFocus);
541 }
542
543 @Test
Riddle Hsua4d6fa22018-08-11 00:50:39 +0800544 public void testGetPreferredOptionsPanelGravityFromDifferentDisplays() {
545 final DisplayContent portraitDisplay = createNewDisplay();
546 portraitDisplay.mInitialDisplayHeight = 2000;
547 portraitDisplay.mInitialDisplayWidth = 1000;
548
549 portraitDisplay.setRotation(Surface.ROTATION_0);
550 assertFalse(isOptionsPanelAtRight(portraitDisplay.getDisplayId()));
551 portraitDisplay.setRotation(Surface.ROTATION_90);
552 assertTrue(isOptionsPanelAtRight(portraitDisplay.getDisplayId()));
553
554 final DisplayContent landscapeDisplay = createNewDisplay();
555 landscapeDisplay.mInitialDisplayHeight = 1000;
556 landscapeDisplay.mInitialDisplayWidth = 2000;
557
558 landscapeDisplay.setRotation(Surface.ROTATION_0);
559 assertTrue(isOptionsPanelAtRight(landscapeDisplay.getDisplayId()));
560 landscapeDisplay.setRotation(Surface.ROTATION_90);
561 assertFalse(isOptionsPanelAtRight(landscapeDisplay.getDisplayId()));
562 }
563
lumarkff0ab692018-11-05 20:32:30 +0800564 @Test
565 public void testInputMethodTargetUpdateWhenSwitchingOnDisplays() {
566 final DisplayContent newDisplay = createNewDisplay();
567
568 final WindowState appWin = createWindow(null, TYPE_APPLICATION, mDisplayContent, "appWin");
569 final WindowState appWin1 = createWindow(null, TYPE_APPLICATION, newDisplay, "appWin1");
570 appWin.setHasSurface(true);
571 appWin1.setHasSurface(true);
572
573 // Set current input method window on default display, make sure the input method target
574 // is appWin & null on the other display.
575 mDisplayContent.setInputMethodWindowLocked(mImeWindow);
576 newDisplay.setInputMethodWindowLocked(null);
577 assertTrue("appWin should be IME target window",
578 appWin.equals(mDisplayContent.mInputMethodTarget));
579 assertNull("newDisplay Ime target: ", newDisplay.mInputMethodTarget);
580
581 // Switch input method window on new display & make sure the input method target also
582 // switched as expected.
583 newDisplay.setInputMethodWindowLocked(mImeWindow);
584 mDisplayContent.setInputMethodWindowLocked(null);
585 assertTrue("appWin1 should be IME target window",
586 appWin1.equals(newDisplay.mInputMethodTarget));
587 assertNull("default display Ime target: ", mDisplayContent.mInputMethodTarget);
588 }
589
Garfield Tan90b04282018-12-11 14:04:42 -0800590 @Test
591 public void testOnDescendantOrientationRequestChanged() {
Garfield Tan49dae102019-02-04 09:51:59 -0800592 final DisplayContent dc = createNewDisplay();
Garfield Tan90b04282018-12-11 14:04:42 -0800593 mWm.mAtmService.mRootActivityContainer = mock(RootActivityContainer.class);
Garfield Tan49dae102019-02-04 09:51:59 -0800594 final int newOrientation = dc.getLastOrientation() == SCREEN_ORIENTATION_LANDSCAPE
595 ? SCREEN_ORIENTATION_PORTRAIT
596 : SCREEN_ORIENTATION_LANDSCAPE;
Garfield Tan90b04282018-12-11 14:04:42 -0800597
598 final WindowState window = createWindow(null /* parent */, TYPE_BASE_APPLICATION, dc, "w");
599 window.getTask().mTaskRecord = mock(TaskRecord.class, ExtendedMockito.RETURNS_DEEP_STUBS);
Garfield Tan49dae102019-02-04 09:51:59 -0800600 window.mAppToken.setOrientation(newOrientation);
Garfield Tan90b04282018-12-11 14:04:42 -0800601
602 ActivityRecord activityRecord = mock(ActivityRecord.class);
603
604 assertTrue("Display should rotate to handle orientation request by default.",
605 dc.onDescendantOrientationChanged(window.mToken.token, activityRecord));
606
607 final ArgumentCaptor<Configuration> captor = ArgumentCaptor.forClass(Configuration.class);
608 verify(mWm.mAtmService).updateDisplayOverrideConfigurationLocked(captor.capture(),
609 same(activityRecord), anyBoolean(), eq(dc.getDisplayId()));
610 final Configuration newDisplayConfig = captor.getValue();
Garfield Tan49dae102019-02-04 09:51:59 -0800611 assertEquals(Configuration.ORIENTATION_PORTRAIT, newDisplayConfig.orientation);
Garfield Tan90b04282018-12-11 14:04:42 -0800612 }
613
614 @Test
615 public void testOnDescendantOrientationRequestChanged_FrozenToUserRotation() {
Garfield Tan49dae102019-02-04 09:51:59 -0800616 final DisplayContent dc = createNewDisplay();
Garfield Tan90b04282018-12-11 14:04:42 -0800617 dc.getDisplayRotation().setFixedToUserRotation(true);
618 mWm.mAtmService.mRootActivityContainer = mock(RootActivityContainer.class);
Garfield Tan49dae102019-02-04 09:51:59 -0800619 final int newOrientation = dc.getLastOrientation() == SCREEN_ORIENTATION_LANDSCAPE
620 ? SCREEN_ORIENTATION_PORTRAIT
621 : SCREEN_ORIENTATION_LANDSCAPE;
Garfield Tan90b04282018-12-11 14:04:42 -0800622
623 final WindowState window = createWindow(null /* parent */, TYPE_BASE_APPLICATION, dc, "w");
624 window.getTask().mTaskRecord = mock(TaskRecord.class, ExtendedMockito.RETURNS_DEEP_STUBS);
Garfield Tan49dae102019-02-04 09:51:59 -0800625 window.mAppToken.setOrientation(newOrientation);
Garfield Tan90b04282018-12-11 14:04:42 -0800626
627 ActivityRecord activityRecord = mock(ActivityRecord.class);
628
629 assertFalse("Display shouldn't rotate to handle orientation request if fixed to"
630 + " user rotation.",
631 dc.onDescendantOrientationChanged(window.mToken.token, activityRecord));
632 verify(mWm.mAtmService, never()).updateDisplayOverrideConfigurationLocked(any(),
633 eq(activityRecord), anyBoolean(), eq(dc.getDisplayId()));
634 }
635
Tarandeep Singha6f35612019-01-11 19:50:46 -0800636 @Test
637 public void testComputeImeParent_app() throws Exception {
638 try (final InsetsModeSession session =
639 new InsetsModeSession(ViewRootImpl.NEW_INSETS_MODE_IME)) {
640 final DisplayContent dc = createNewDisplay();
641 dc.mInputMethodTarget = createWindow(null, TYPE_BASE_APPLICATION, "app");
642 assertEquals(dc.mInputMethodTarget.mAppToken.getSurfaceControl(),
643 dc.computeImeParent());
644 }
645 }
646
647 @Test
648 public void testComputeImeParent_app_notFullscreen() throws Exception {
649 try (final InsetsModeSession session =
650 new InsetsModeSession(ViewRootImpl.NEW_INSETS_MODE_IME)) {
651 final DisplayContent dc = createNewDisplay();
652 dc.mInputMethodTarget = createWindow(null, TYPE_STATUS_BAR, "app");
653 dc.mInputMethodTarget.setWindowingMode(
654 WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
655 assertEquals(dc.getWindowingLayer(), dc.computeImeParent());
656 }
657 }
658
659 @Test
660 public void testComputeImeParent_noApp() throws Exception {
661 try (final InsetsModeSession session =
662 new InsetsModeSession(ViewRootImpl.NEW_INSETS_MODE_IME)) {
663 final DisplayContent dc = createNewDisplay();
664 dc.mInputMethodTarget = createWindow(null, TYPE_STATUS_BAR, "statusBar");
665 assertEquals(dc.getWindowingLayer(), dc.computeImeParent());
666 }
667 }
668
Riddle Hsua4d6fa22018-08-11 00:50:39 +0800669 private boolean isOptionsPanelAtRight(int displayId) {
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700670 return (mWm.getPreferredOptionsPanelGravity(displayId) & Gravity.RIGHT) == Gravity.RIGHT;
Riddle Hsua4d6fa22018-08-11 00:50:39 +0800671 }
672
Bryce Lee27cec322017-03-21 09:41:37 -0700673 private static void verifySizes(DisplayContent displayContent, int expectedBaseWidth,
674 int expectedBaseHeight, int expectedBaseDensity) {
675 assertEquals(displayContent.mBaseDisplayWidth, expectedBaseWidth);
676 assertEquals(displayContent.mBaseDisplayHeight, expectedBaseHeight);
677 assertEquals(displayContent.mBaseDisplayDensity, expectedBaseDensity);
678 }
679
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800680 private void updateFocusedWindow() {
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700681 synchronized (mWm.mGlobalLock) {
682 mWm.updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, false);
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800683 }
684 }
685
Riddle Hsu654a6f92018-07-13 22:59:36 +0800686 /**
687 * Create DisplayContent that does not update display base/initial values from device to keep
688 * the values set by test.
689 */
690 private DisplayContent createDisplayNoUpdateDisplayInfo() {
691 final DisplayContent displayContent = spy(createNewDisplay());
692 doNothing().when(displayContent).updateDisplayInfo();
693 return displayContent;
694 }
695
Adrian Roos0f9368c2018-04-08 10:59:08 -0700696 private void assertForAllWindowsOrder(List<WindowState> expectedWindowsBottomToTop) {
697 final LinkedList<WindowState> actualWindows = new LinkedList<>();
Wale Ogunwale34247952017-02-19 11:57:53 -0800698
699 // Test forward traversal.
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700700 mDisplayContent.forAllWindows(actualWindows::addLast, false /* traverseTopToBottom */);
Adrian Roos0f9368c2018-04-08 10:59:08 -0700701 assertThat("bottomToTop", actualWindows, is(expectedWindowsBottomToTop));
702
703 actualWindows.clear();
Wale Ogunwale34247952017-02-19 11:57:53 -0800704
705 // Test backward traversal.
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700706 mDisplayContent.forAllWindows(actualWindows::addLast, true /* traverseTopToBottom */);
Adrian Roos0f9368c2018-04-08 10:59:08 -0700707 assertThat("topToBottom", actualWindows, is(reverseList(expectedWindowsBottomToTop)));
708 }
709
710 private static List<WindowState> reverseList(List<WindowState> list) {
711 final ArrayList<WindowState> result = new ArrayList<>(list);
712 Collections.reverse(result);
713 return result;
Wale Ogunwale34247952017-02-19 11:57:53 -0800714 }
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -0700715
Arthur Hungbe5ce212018-09-13 18:41:56 +0800716 private void tapOnDisplay(final DisplayContent dc) {
717 final DisplayMetrics dm = dc.getDisplayMetrics();
718 final float x = dm.widthPixels / 2;
719 final float y = dm.heightPixels / 2;
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -0700720 final long downTime = SystemClock.uptimeMillis();
721 final long eventTime = SystemClock.uptimeMillis() + 100;
Arthur Hungbe5ce212018-09-13 18:41:56 +0800722 // sending ACTION_DOWN
723 final MotionEvent downEvent = MotionEvent.obtain(
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -0700724 downTime,
Arthur Hungbe5ce212018-09-13 18:41:56 +0800725 downTime,
726 MotionEvent.ACTION_DOWN,
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -0700727 x,
728 y,
Arthur Hungbe5ce212018-09-13 18:41:56 +0800729 0 /*metaState*/);
730 downEvent.setDisplayId(dc.getDisplayId());
731 dc.mTapDetector.onPointerEvent(downEvent);
732
733 // sending ACTION_UP
734 final MotionEvent upEvent = MotionEvent.obtain(
735 downTime,
736 eventTime,
737 MotionEvent.ACTION_UP,
738 x,
739 y,
740 0 /*metaState*/);
741 upEvent.setDisplayId(dc.getDisplayId());
742 dc.mTapDetector.onPointerEvent(upEvent);
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -0700743 }
Wale Ogunwaleb783fd82016-11-04 09:51:54 -0700744}