blob: 98333b244e3b75f67062ea3d3ee437174e63a803 [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;
Riddle Hsu6d6f67c2019-03-14 16:54:26 +080037import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
Garfield Tan90b04282018-12-11 14:04:42 -080038import 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;
Riddle Hsu6d6f67c2019-03-14 16:54:26 +080042import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
Tadashi G. Takaokabf0d57b2018-11-19 16:09:58 +090043import static com.android.dx.mockito.inline.extended.ExtendedMockito.times;
44import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
David Stevens46939562017-03-24 13:04:00 -070045import static com.android.server.wm.WindowContainer.POSITION_TOP;
Tiger Huang1e5b10a2018-07-30 20:19:51 +080046import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_NORMAL;
chaviwebcbc342018-02-07 13:19:00 -080047
Adrian Roos5251b1d2018-03-23 18:57:43 +010048import static org.hamcrest.Matchers.is;
Wale Ogunwale34247952017-02-19 11:57:53 -080049import static org.junit.Assert.assertEquals;
Andrii Kulianf0379de2018-03-14 16:24:07 -070050import static org.junit.Assert.assertFalse;
Arthur Hungbe5ce212018-09-13 18:41:56 +080051import static org.junit.Assert.assertNotNull;
lumarkff0ab692018-11-05 20:32:30 +080052import static org.junit.Assert.assertNull;
Adrian Roos5251b1d2018-03-23 18:57:43 +010053import static org.junit.Assert.assertThat;
Wale Ogunwale34247952017-02-19 11:57:53 -080054import static org.junit.Assert.assertTrue;
Tarandeep Singha6f35612019-01-11 19:50:46 -080055import static org.mockito.ArgumentMatchers.eq;
Wale Ogunwale34247952017-02-19 11:57:53 -080056
Andrii Kulian92c9a942017-10-10 00:41:41 -070057import android.annotation.SuppressLint;
Tarandeep Singha6f35612019-01-11 19:50:46 -080058import android.app.WindowConfiguration;
Andrii Kuliand68501e2017-01-10 22:57:27 -080059import android.content.res.Configuration;
Adrian Roos1cf585052018-01-03 18:43:27 +010060import android.graphics.Rect;
Susi Kharraz-Post9893b8c2019-02-12 14:21:29 -050061import android.metrics.LogMaker;
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -070062import android.os.SystemClock;
Wale Ogunwaleb783fd82016-11-04 09:51:54 -070063import android.platform.test.annotations.Presubmit;
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -070064import android.util.DisplayMetrics;
Adrian Roos1cf585052018-01-03 18:43:27 +010065import android.view.DisplayCutout;
Riddle Hsua4d6fa22018-08-11 00:50:39 +080066import android.view.Gravity;
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -070067import android.view.MotionEvent;
Adrian Roos1cf585052018-01-03 18:43:27 +010068import android.view.Surface;
Tarandeep Singha6f35612019-01-11 19:50:46 -080069import android.view.ViewRootImpl;
70import android.view.test.InsetsModeSession;
Wale Ogunwaleb783fd82016-11-04 09:51:54 -070071
Brett Chabota26eda92018-07-23 13:08:30 -070072import 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;
Susi Kharraz-Post9893b8c2019-02-12 14:21:29 -050075import com.android.internal.logging.MetricsLogger;
76import com.android.internal.logging.nano.MetricsProto;
Adrian Roos6a4fa0e2018-03-05 19:50:16 +010077import com.android.server.wm.utils.WmDisplayCutout;
78
Brett Chabota26eda92018-07-23 13:08:30 -070079import org.junit.Test;
Garfield Tan90b04282018-12-11 14:04:42 -080080import org.mockito.ArgumentCaptor;
Susi Kharraz-Post9893b8c2019-02-12 14:21:29 -050081import org.mockito.Mockito;
Brett Chabota26eda92018-07-23 13:08:30 -070082
Adrian Roos0f9368c2018-04-08 10:59:08 -070083import java.util.ArrayList;
Wale Ogunwale34247952017-02-19 11:57:53 -080084import java.util.Arrays;
Adrian Roos0f9368c2018-04-08 10:59:08 -070085import java.util.Collections;
Wale Ogunwale34247952017-02-19 11:57:53 -080086import java.util.LinkedList;
87import java.util.List;
Wale Ogunwaleb783fd82016-11-04 09:51:54 -070088
89/**
90 * Tests for the {@link DisplayContent} class.
91 *
92 * Build/Install/Run:
Yunfan Chen6dd9a622019-02-18 15:12:33 +090093 * atest WmTests:DisplayContentTests
Wale Ogunwaleb783fd82016-11-04 09:51:54 -070094 */
95@SmallTest
96@Presubmit
Wale Ogunwale44fbdf52016-11-16 10:18:45 -080097public class DisplayContentTests extends WindowTestsBase {
Wale Ogunwaleb783fd82016-11-04 09:51:54 -070098
99 @Test
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700100 public void testForAllWindows() {
Wale Ogunwale3c1170d2016-12-02 14:44:52 -0800101 final WindowState exitingAppWindow = createWindow(null, TYPE_BASE_APPLICATION,
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700102 mDisplayContent, "exiting app");
Wale Ogunwaleb783fd82016-11-04 09:51:54 -0700103 final AppWindowToken exitingAppToken = exitingAppWindow.mAppToken;
Yunfan Chen6dd9a622019-02-18 15:12:33 +0900104 // Wait until everything in animation handler get executed to prevent the exiting window
105 // from being removed during WindowSurfacePlacer Traversal.
106 waitUntilHandlersIdle();
107
Wale Ogunwaleb783fd82016-11-04 09:51:54 -0700108 exitingAppToken.mIsExiting = true;
Bryce Lee6d410262017-02-28 15:30:17 -0800109 exitingAppToken.getTask().mStack.mExitingAppTokens.add(exitingAppToken);
Wale Ogunwaleb783fd82016-11-04 09:51:54 -0700110
Wale Ogunwale34247952017-02-19 11:57:53 -0800111 assertForAllWindowsOrder(Arrays.asList(
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700112 mWallpaperWindow,
Wale Ogunwale34247952017-02-19 11:57:53 -0800113 exitingAppWindow,
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700114 mChildAppWindowBelow,
115 mAppWindow,
116 mChildAppWindowAbove,
117 mDockedDividerWindow,
118 mStatusBarWindow,
119 mNavBarWindow,
120 mImeWindow,
121 mImeDialogWindow));
Wale Ogunwale3c1170d2016-12-02 14:44:52 -0800122 }
123
124 @Test
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700125 public void testForAllWindows_WithAppImeTarget() {
Wale Ogunwale3c1170d2016-12-02 14:44:52 -0800126 final WindowState imeAppTarget =
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700127 createWindow(null, TYPE_BASE_APPLICATION, mDisplayContent, "imeAppTarget");
Wale Ogunwale3c1170d2016-12-02 14:44:52 -0800128
lumarkff0ab692018-11-05 20:32:30 +0800129 mDisplayContent.mInputMethodTarget = imeAppTarget;
Wale Ogunwale3c1170d2016-12-02 14:44:52 -0800130
Wale Ogunwale34247952017-02-19 11:57:53 -0800131 assertForAllWindowsOrder(Arrays.asList(
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700132 mWallpaperWindow,
133 mChildAppWindowBelow,
134 mAppWindow,
135 mChildAppWindowAbove,
Wale Ogunwale34247952017-02-19 11:57:53 -0800136 imeAppTarget,
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700137 mImeWindow,
138 mImeDialogWindow,
139 mDockedDividerWindow,
140 mStatusBarWindow,
141 mNavBarWindow));
Wale Ogunwale34247952017-02-19 11:57:53 -0800142 }
Wale Ogunwale3c1170d2016-12-02 14:44:52 -0800143
Wale Ogunwale34247952017-02-19 11:57:53 -0800144 @Test
lumarkff0ab692018-11-05 20:32:30 +0800145 public void testForAllWindows_WithChildWindowImeTarget() throws Exception {
146 mDisplayContent.mInputMethodTarget = mChildAppWindowAbove;
Wale Ogunwale3c1170d2016-12-02 14:44:52 -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 mImeWindow,
154 mImeDialogWindow,
155 mDockedDividerWindow,
156 mStatusBarWindow,
157 mNavBarWindow));
Wale Ogunwaleb783fd82016-11-04 09:51:54 -0700158 }
Wale Ogunwale5d7e7f12016-12-12 14:47:05 -0800159
160 @Test
lumarkff0ab692018-11-05 20:32:30 +0800161 public void testForAllWindows_WithStatusBarImeTarget() throws Exception {
162 mDisplayContent.mInputMethodTarget = mStatusBarWindow;
Wale Ogunwale6ce0fb82016-12-13 14:24:00 -0800163
Wale Ogunwale34247952017-02-19 11:57:53 -0800164 assertForAllWindowsOrder(Arrays.asList(
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700165 mWallpaperWindow,
166 mChildAppWindowBelow,
167 mAppWindow,
168 mChildAppWindowAbove,
169 mDockedDividerWindow,
170 mStatusBarWindow,
171 mImeWindow,
172 mImeDialogWindow,
173 mNavBarWindow));
Wale Ogunwale6ce0fb82016-12-13 14:24:00 -0800174 }
175
176 @Test
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700177 public void testForAllWindows_WithInBetweenWindowToken() {
Wale Ogunwale5d7e7f12016-12-12 14:47:05 -0800178 // This window is set-up to be z-ordered between some windows that go in the same token like
179 // the nav bar and status bar.
180 final WindowState voiceInteractionWindow = createWindow(null, TYPE_VOICE_INTERACTION,
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700181 mDisplayContent, "voiceInteractionWindow");
Wale Ogunwale5d7e7f12016-12-12 14:47:05 -0800182
Wale Ogunwale34247952017-02-19 11:57:53 -0800183 assertForAllWindowsOrder(Arrays.asList(
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700184 mWallpaperWindow,
185 mChildAppWindowBelow,
186 mAppWindow,
187 mChildAppWindowAbove,
188 mDockedDividerWindow,
Wale Ogunwale34247952017-02-19 11:57:53 -0800189 voiceInteractionWindow,
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700190 mStatusBarWindow,
191 mNavBarWindow,
192 mImeWindow,
193 mImeDialogWindow));
Wale Ogunwale34247952017-02-19 11:57:53 -0800194 }
Wale Ogunwale5d7e7f12016-12-12 14:47:05 -0800195
Wale Ogunwale34247952017-02-19 11:57:53 -0800196 @Test
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700197 public void testComputeImeTarget() {
Wale Ogunwale34247952017-02-19 11:57:53 -0800198 // Verify that an app window can be an ime target.
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700199 final WindowState appWin = createWindow(null, TYPE_APPLICATION, mDisplayContent, "appWin");
Wale Ogunwale34247952017-02-19 11:57:53 -0800200 appWin.setHasSurface(true);
201 assertTrue(appWin.canBeImeTarget());
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700202 WindowState imeTarget = mDisplayContent.computeImeTarget(false /* updateImeTarget */);
Wale Ogunwale34247952017-02-19 11:57:53 -0800203 assertEquals(appWin, imeTarget);
chaviwebcbc342018-02-07 13:19:00 -0800204 appWin.mHidden = false;
Wale Ogunwale5d7e7f12016-12-12 14:47:05 -0800205
Wale Ogunwale34247952017-02-19 11:57:53 -0800206 // Verify that an child window can be an ime target.
207 final WindowState childWin = createWindow(appWin,
208 TYPE_APPLICATION_ATTACHED_DIALOG, "childWin");
209 childWin.setHasSurface(true);
210 assertTrue(childWin.canBeImeTarget());
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700211 imeTarget = mDisplayContent.computeImeTarget(false /* updateImeTarget */);
Wale Ogunwale34247952017-02-19 11:57:53 -0800212 assertEquals(childWin, imeTarget);
Wale Ogunwale5d7e7f12016-12-12 14:47:05 -0800213 }
Andrii Kulian6cc1a1d2016-12-27 23:52:59 -0800214
Andrii Kuliand68501e2017-01-10 22:57:27 -0800215 /**
216 * This tests stack movement between displays and proper stack's, task's and app token's display
217 * container references updates.
218 */
Andrii Kulian6cc1a1d2016-12-27 23:52:59 -0800219 @Test
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700220 public void testMoveStackBetweenDisplays() {
Andrii Kulian367ff7f2017-01-25 19:45:34 -0800221 // Create a second display.
222 final DisplayContent dc = createNewDisplay();
Andrii Kulian6cc1a1d2016-12-27 23:52:59 -0800223
224 // Add stack with activity.
225 final TaskStack stack = createTaskStackOnDisplay(dc);
226 assertEquals(dc.getDisplayId(), stack.getDisplayContent().getDisplayId());
227 assertEquals(dc, stack.getParent().getParent());
228 assertEquals(dc, stack.getDisplayContent());
229
230 final Task task = createTaskInStack(stack, 0 /* userId */);
chaviw97d28202018-02-27 16:23:53 -0800231 final WindowTestUtils.TestAppWindowToken token = WindowTestUtils.createTestAppWindowToken(
232 dc);
Andrii Kulian6cc1a1d2016-12-27 23:52:59 -0800233 task.addChild(token, 0);
234 assertEquals(dc, task.getDisplayContent());
235 assertEquals(dc, token.getDisplayContent());
236
237 // Move stack to first display.
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700238 mDisplayContent.moveStackToDisplay(stack, true /* onTop */);
239 assertEquals(mDisplayContent.getDisplayId(), stack.getDisplayContent().getDisplayId());
240 assertEquals(mDisplayContent, stack.getParent().getParent());
241 assertEquals(mDisplayContent, stack.getDisplayContent());
242 assertEquals(mDisplayContent, task.getDisplayContent());
243 assertEquals(mDisplayContent, token.getDisplayContent());
Andrii Kulian6cc1a1d2016-12-27 23:52:59 -0800244 }
Andrii Kuliand68501e2017-01-10 22:57:27 -0800245
246 /**
247 * This tests override configuration updates for display content.
248 */
249 @Test
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700250 public void testDisplayOverrideConfigUpdate() {
Evan Roskydfe3da72018-10-26 17:21:06 -0700251 final Configuration currentOverrideConfig =
252 mDisplayContent.getRequestedOverrideConfiguration();
Andrii Kuliand68501e2017-01-10 22:57:27 -0800253
254 // Create new, slightly changed override configuration and apply it to the display.
255 final Configuration newOverrideConfig = new Configuration(currentOverrideConfig);
256 newOverrideConfig.densityDpi += 120;
257 newOverrideConfig.fontScale += 0.3;
258
Evan Roskye747c3e2018-10-30 20:06:41 -0700259 mWm.setNewDisplayOverrideConfiguration(newOverrideConfig, mDisplayContent);
Andrii Kuliand68501e2017-01-10 22:57:27 -0800260
261 // Check that override config is applied.
Evan Roskydfe3da72018-10-26 17:21:06 -0700262 assertEquals(newOverrideConfig, mDisplayContent.getRequestedOverrideConfiguration());
Andrii Kulian367ff7f2017-01-25 19:45:34 -0800263 }
264
265 /**
266 * This tests global configuration updates when default display config is updated.
267 */
268 @Test
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700269 public void testDefaultDisplayOverrideConfigUpdate() {
Evan Roskye747c3e2018-10-30 20:06:41 -0700270 DisplayContent defaultDisplay = mWm.mRoot.getDisplayContent(DEFAULT_DISPLAY);
271 final Configuration currentConfig = defaultDisplay.getConfiguration();
Andrii Kulian367ff7f2017-01-25 19:45:34 -0800272
273 // Create new, slightly changed override configuration and apply it to the display.
Andrii Kuliana95bfff2017-03-30 19:00:41 -0700274 final Configuration newOverrideConfig = new Configuration(currentConfig);
Andrii Kulian367ff7f2017-01-25 19:45:34 -0800275 newOverrideConfig.densityDpi += 120;
276 newOverrideConfig.fontScale += 0.3;
277
Evan Roskye747c3e2018-10-30 20:06:41 -0700278 mWm.setNewDisplayOverrideConfiguration(newOverrideConfig, defaultDisplay);
Andrii Kuliand68501e2017-01-10 22:57:27 -0800279
280 // Check that global configuration is updated, as we've updated default display's config.
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700281 Configuration globalConfig = mWm.mRoot.getConfiguration();
Andrii Kuliand68501e2017-01-10 22:57:27 -0800282 assertEquals(newOverrideConfig.densityDpi, globalConfig.densityDpi);
283 assertEquals(newOverrideConfig.fontScale, globalConfig.fontScale, 0.1 /* delta */);
Andrii Kulian367ff7f2017-01-25 19:45:34 -0800284
285 // Return back to original values.
Evan Roskye747c3e2018-10-30 20:06:41 -0700286 mWm.setNewDisplayOverrideConfiguration(currentConfig, defaultDisplay);
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700287 globalConfig = mWm.mRoot.getConfiguration();
Andrii Kuliana95bfff2017-03-30 19:00:41 -0700288 assertEquals(currentConfig.densityDpi, globalConfig.densityDpi);
289 assertEquals(currentConfig.fontScale, globalConfig.fontScale, 0.1 /* delta */);
Andrii Kuliand68501e2017-01-10 22:57:27 -0800290 }
Wale Ogunwale34247952017-02-19 11:57:53 -0800291
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -0700292 /**
293 * Tests tapping on a stack in different display results in window gaining focus.
294 */
295 @Test
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700296 public void testInputEventBringsCorrectDisplayInFocus() {
297 DisplayContent dc0 = mWm.getDefaultDisplayContentLocked();
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -0700298 // Create a second display
299 final DisplayContent dc1 = createNewDisplay();
300
301 // Add stack with activity.
302 final TaskStack stack0 = createTaskStackOnDisplay(dc0);
303 final Task task0 = createTaskInStack(stack0, 0 /* userId */);
304 final WindowTestUtils.TestAppWindowToken token =
chaviw97d28202018-02-27 16:23:53 -0800305 WindowTestUtils.createTestAppWindowToken(dc0);
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -0700306 task0.addChild(token, 0);
Arthur Hungbe5ce212018-09-13 18:41:56 +0800307 dc0.configureDisplayPolicy();
308 assertNotNull(dc0.mTapDetector);
309
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -0700310 final TaskStack stack1 = createTaskStackOnDisplay(dc1);
311 final Task task1 = createTaskInStack(stack1, 0 /* userId */);
312 final WindowTestUtils.TestAppWindowToken token1 =
chaviw97d28202018-02-27 16:23:53 -0800313 WindowTestUtils.createTestAppWindowToken(dc0);
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -0700314 task1.addChild(token1, 0);
Arthur Hungbe5ce212018-09-13 18:41:56 +0800315 dc1.configureDisplayPolicy();
316 assertNotNull(dc1.mTapDetector);
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -0700317
Arthur Hungbe5ce212018-09-13 18:41:56 +0800318 // tap on primary display.
319 tapOnDisplay(dc0);
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -0700320 // Check focus is on primary display.
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700321 assertEquals(mWm.mRoot.getTopFocusedDisplayContent().mCurrentFocus,
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800322 dc0.findFocusedWindow());
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -0700323
Arthur Hungbe5ce212018-09-13 18:41:56 +0800324 // Tap on secondary display.
325 tapOnDisplay(dc1);
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -0700326 // Check focus is on secondary.
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700327 assertEquals(mWm.mRoot.getTopFocusedDisplayContent().mCurrentFocus,
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800328 dc1.findFocusedWindow());
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -0700329 }
330
David Stevens46939562017-03-24 13:04:00 -0700331 @Test
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700332 public void testFocusedWindowMultipleDisplays() {
Tiger Huang51c5a1d2018-12-11 20:24:51 +0800333 doTestFocusedWindowMultipleDisplays(false /* perDisplayFocusEnabled */, Q);
334 }
335
336 @Test
337 public void testFocusedWindowMultipleDisplaysPerDisplayFocusEnabled() {
338 doTestFocusedWindowMultipleDisplays(true /* perDisplayFocusEnabled */, Q);
339 }
340
341 @Test
342 public void testFocusedWindowMultipleDisplaysPerDisplayFocusEnabledLegacyApp() {
343 doTestFocusedWindowMultipleDisplays(true /* perDisplayFocusEnabled */, P);
344 }
345
346 private void doTestFocusedWindowMultipleDisplays(boolean perDisplayFocusEnabled,
347 int targetSdk) {
348 mWm.mPerDisplayFocusEnabled = perDisplayFocusEnabled;
349
Andrii Kulian0214ed92017-05-16 13:44:05 -0700350 // Create a focusable window and check that focus is calculated correctly
David Stevens46939562017-03-24 13:04:00 -0700351 final WindowState window1 =
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700352 createWindow(null, TYPE_BASE_APPLICATION, mDisplayContent, "window1");
Tiger Huang51c5a1d2018-12-11 20:24:51 +0800353 window1.mAppToken.mTargetSdk = targetSdk;
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 // Check that a new display doesn't affect focus
359 final DisplayContent dc = createNewDisplay();
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800360 updateFocusedWindow();
361 assertTrue(window1.isFocused());
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700362 assertEquals(window1, mWm.mRoot.getTopFocusedDisplayContent().mCurrentFocus);
David Stevens46939562017-03-24 13:04:00 -0700363
364 // Add a window to the second display, and it should be focused
365 final WindowState window2 = createWindow(null, TYPE_BASE_APPLICATION, dc, "window2");
Tiger Huang51c5a1d2018-12-11 20:24:51 +0800366 window2.mAppToken.mTargetSdk = targetSdk;
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800367 updateFocusedWindow();
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800368 assertTrue(window2.isFocused());
Tiger Huang51c5a1d2018-12-11 20:24:51 +0800369 assertEquals(perDisplayFocusEnabled && targetSdk >= Q, window1.isFocused());
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700370 assertEquals(window2, mWm.mRoot.getTopFocusedDisplayContent().mCurrentFocus);
David Stevens46939562017-03-24 13:04:00 -0700371
Tiger Huang51c5a1d2018-12-11 20:24:51 +0800372 // Move the first window to top including parents, and make sure focus is updated
David Stevens46939562017-03-24 13:04:00 -0700373 window1.getParent().positionChildAt(POSITION_TOP, window1, true);
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800374 updateFocusedWindow();
375 assertTrue(window1.isFocused());
Tiger Huang51c5a1d2018-12-11 20:24:51 +0800376 assertEquals(perDisplayFocusEnabled && targetSdk >= Q, window2.isFocused());
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700377 assertEquals(window1, mWm.mRoot.getTopFocusedDisplayContent().mCurrentFocus);
Adrian Roos4163d622018-05-22 16:56:35 +0200378 }
379
Bryce Lee27cec322017-03-21 09:41:37 -0700380 /**
381 * This tests setting the maximum ui width on a display.
382 */
383 @Test
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700384 public void testMaxUiWidth() {
Riddle Hsu654a6f92018-07-13 22:59:36 +0800385 // Prevent base display metrics for test from being updated to the value of real display.
386 final DisplayContent displayContent = createDisplayNoUpdateDisplayInfo();
Bryce Lee27cec322017-03-21 09:41:37 -0700387 final int baseWidth = 1440;
388 final int baseHeight = 2560;
389 final int baseDensity = 300;
390
Riddle Hsu654a6f92018-07-13 22:59:36 +0800391 displayContent.updateBaseDisplayMetrics(baseWidth, baseHeight, baseDensity);
Bryce Lee27cec322017-03-21 09:41:37 -0700392
393 final int maxWidth = 300;
394 final int resultingHeight = (maxWidth * baseHeight) / baseWidth;
395 final int resultingDensity = (maxWidth * baseDensity) / baseWidth;
396
Riddle Hsu654a6f92018-07-13 22:59:36 +0800397 displayContent.setMaxUiWidth(maxWidth);
398 verifySizes(displayContent, maxWidth, resultingHeight, resultingDensity);
Bryce Lee27cec322017-03-21 09:41:37 -0700399
400 // Assert setting values again does not change;
Riddle Hsu654a6f92018-07-13 22:59:36 +0800401 displayContent.updateBaseDisplayMetrics(baseWidth, baseHeight, baseDensity);
402 verifySizes(displayContent, maxWidth, resultingHeight, resultingDensity);
Bryce Lee27cec322017-03-21 09:41:37 -0700403
404 final int smallerWidth = 200;
405 final int smallerHeight = 400;
406 final int smallerDensity = 100;
407
408 // Specify smaller dimension, verify that it is honored
Riddle Hsu654a6f92018-07-13 22:59:36 +0800409 displayContent.updateBaseDisplayMetrics(smallerWidth, smallerHeight, smallerDensity);
410 verifySizes(displayContent, smallerWidth, smallerHeight, smallerDensity);
Bryce Lee27cec322017-03-21 09:41:37 -0700411
412 // Verify that setting the max width to a greater value than the base width has no effect
Riddle Hsu654a6f92018-07-13 22:59:36 +0800413 displayContent.setMaxUiWidth(maxWidth);
414 verifySizes(displayContent, smallerWidth, smallerHeight, smallerDensity);
Bryce Lee27cec322017-03-21 09:41:37 -0700415 }
416
Andrii Kulian92c9a942017-10-10 00:41:41 -0700417 @Test
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700418 public void testDisplayCutout_rot0() {
419 synchronized (mWm.getWindowManagerLock()) {
Adrian Roos1cf585052018-01-03 18:43:27 +0100420 final DisplayContent dc = createNewDisplay();
421 dc.mInitialDisplayWidth = 200;
422 dc.mInitialDisplayHeight = 400;
Adrian Roos24264212018-02-19 16:26:15 +0100423 Rect r = new Rect(80, 0, 120, 10);
Adrian Roos6a4fa0e2018-03-05 19:50:16 +0100424 final DisplayCutout cutout = new WmDisplayCutout(
Issei Suzuki43190bd2018-08-20 17:28:41 +0200425 fromBoundingRect(r.left, r.top, r.right, r.bottom, BOUNDS_POSITION_TOP), null)
Adrian Roos6a4fa0e2018-03-05 19:50:16 +0100426 .computeSafeInsets(200, 400).getDisplayCutout();
Adrian Roos1cf585052018-01-03 18:43:27 +0100427
428 dc.mInitialDisplayCutout = cutout;
429 dc.setRotation(Surface.ROTATION_0);
430 dc.computeScreenConfiguration(new Configuration()); // recomputes dc.mDisplayInfo.
431
432 assertEquals(cutout, dc.getDisplayInfo().displayCutout);
433 }
434 }
435
436 @Test
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700437 public void testDisplayCutout_rot90() {
438 synchronized (mWm.getWindowManagerLock()) {
Riddle Hsu654a6f92018-07-13 22:59:36 +0800439 // Prevent mInitialDisplayCutout from being updated from real display (e.g. null
440 // if the device has no cutout).
441 final DisplayContent dc = createDisplayNoUpdateDisplayInfo();
442 // Rotation may use real display info to compute bound, so here also uses the
443 // same width and height.
444 final int displayWidth = dc.mInitialDisplayWidth;
445 final int displayHeight = dc.mInitialDisplayHeight;
446 final int cutoutWidth = 40;
447 final int cutoutHeight = 10;
448 final int left = (displayWidth - cutoutWidth) / 2;
449 final int top = 0;
450 final int right = (displayWidth + cutoutWidth) / 2;
451 final int bottom = cutoutHeight;
452
453 final Rect r1 = new Rect(left, top, right, bottom);
Adrian Roos6a4fa0e2018-03-05 19:50:16 +0100454 final DisplayCutout cutout = new WmDisplayCutout(
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700455 fromBoundingRect(r1.left, r1.top, r1.right, r1.bottom, BOUNDS_POSITION_TOP),
456 null)
Riddle Hsu654a6f92018-07-13 22:59:36 +0800457 .computeSafeInsets(displayWidth, displayHeight).getDisplayCutout();
Adrian Roos1cf585052018-01-03 18:43:27 +0100458
459 dc.mInitialDisplayCutout = cutout;
460 dc.setRotation(Surface.ROTATION_90);
461 dc.computeScreenConfiguration(new Configuration()); // recomputes dc.mDisplayInfo.
462
Riddle Hsu654a6f92018-07-13 22:59:36 +0800463 // ----o---------- -------------
464 // | | | | |
465 // | ------o | o---
466 // | | | |
467 // | | -> | |
468 // | | ---o
469 // | | |
470 // | | -------------
471 final Rect r = new Rect(top, left, bottom, right);
Adrian Roos6a4fa0e2018-03-05 19:50:16 +0100472 assertEquals(new WmDisplayCutout(
Issei Suzuki43190bd2018-08-20 17:28:41 +0200473 fromBoundingRect(r.left, r.top, r.right, r.bottom, BOUNDS_POSITION_LEFT), null)
Riddle Hsu654a6f92018-07-13 22:59:36 +0800474 .computeSafeInsets(displayHeight, displayWidth)
475 .getDisplayCutout(), dc.getDisplayInfo().displayCutout);
Adrian Roos1cf585052018-01-03 18:43:27 +0100476 }
477 }
478
479 @Test
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700480 public void testLayoutSeq_assignedDuringLayout() {
481 synchronized (mWm.getWindowManagerLock()) {
Adrian Roos5251b1d2018-03-23 18:57:43 +0100482
483 final DisplayContent dc = createNewDisplay();
484 final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, dc, "w");
485
486 dc.setLayoutNeeded();
487 dc.performLayout(true /* initial */, false /* updateImeWindows */);
488
489 assertThat(win.mLayoutSeq, is(dc.mLayoutSeq));
490 }
491 }
492
493 @Test
Andrii Kulian92c9a942017-10-10 00:41:41 -0700494 @SuppressLint("InlinedApi")
495 public void testOrientationDefinedByKeyguard() {
496 final DisplayContent dc = createNewDisplay();
Garfield Tan90b04282018-12-11 14:04:42 -0800497
498 // When display content is created its configuration is not yet initialized, which could
499 // cause unnecessary configuration propagation, so initialize it here.
500 final Configuration config = new Configuration();
501 dc.computeScreenConfiguration(config);
502 dc.onRequestedOverrideConfigurationChanged(config);
503
Andrii Kulian92c9a942017-10-10 00:41:41 -0700504 // Create a window that requests landscape orientation. It will define device orientation
505 // by default.
506 final WindowState window = createWindow(null /* parent */, TYPE_BASE_APPLICATION, dc, "w");
507 window.mAppToken.setOrientation(SCREEN_ORIENTATION_LANDSCAPE);
508
509 final WindowState keyguard = createWindow(null, TYPE_STATUS_BAR, dc, "keyguard");
510 keyguard.mHasSurface = true;
511 keyguard.mAttrs.screenOrientation = SCREEN_ORIENTATION_UNSPECIFIED;
512
513 assertEquals("Screen orientation must be defined by the app window by default",
514 SCREEN_ORIENTATION_LANDSCAPE, dc.getOrientation());
515
516 keyguard.mAttrs.screenOrientation = SCREEN_ORIENTATION_PORTRAIT;
517 assertEquals("Visible keyguard must influence device orientation",
518 SCREEN_ORIENTATION_PORTRAIT, dc.getOrientation());
519
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700520 mWm.setKeyguardGoingAway(true);
Andrii Kulian92c9a942017-10-10 00:41:41 -0700521 assertEquals("Keyguard that is going away must not influence device orientation",
522 SCREEN_ORIENTATION_LANDSCAPE, dc.getOrientation());
523 }
524
Andrii Kulianf0379de2018-03-14 16:24:07 -0700525 @Test
526 public void testDisableDisplayInfoOverrideFromWindowManager() {
527 final DisplayContent dc = createNewDisplay();
528
529 assertTrue(dc.mShouldOverrideDisplayConfiguration);
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700530 mWm.dontOverrideDisplayInfo(dc.getDisplayId());
Andrii Kulianf0379de2018-03-14 16:24:07 -0700531
532 assertFalse(dc.mShouldOverrideDisplayConfiguration);
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700533 verify(mWm.mDisplayManagerInternal, times(1))
Andrii Kulianf0379de2018-03-14 16:24:07 -0700534 .setDisplayInfoOverrideFromWindowManager(dc.getDisplayId(), null);
535 }
536
Riddle Hsua4d6fa22018-08-11 00:50:39 +0800537 @Test
Riddle Hsu85bd04b2018-11-17 00:34:36 +0800538 public void testClearLastFocusWhenReparentingFocusedWindow() {
539 final DisplayContent defaultDisplay = mWm.getDefaultDisplayContentLocked();
540 final WindowState window = createWindow(null /* parent */, TYPE_BASE_APPLICATION,
541 defaultDisplay, "window");
542 defaultDisplay.mLastFocus = window;
543 mDisplayContent.mCurrentFocus = window;
544 mDisplayContent.reParentWindowToken(window.mToken);
545
546 assertNull(defaultDisplay.mLastFocus);
547 }
548
549 @Test
Riddle Hsua4d6fa22018-08-11 00:50:39 +0800550 public void testGetPreferredOptionsPanelGravityFromDifferentDisplays() {
551 final DisplayContent portraitDisplay = createNewDisplay();
552 portraitDisplay.mInitialDisplayHeight = 2000;
553 portraitDisplay.mInitialDisplayWidth = 1000;
554
555 portraitDisplay.setRotation(Surface.ROTATION_0);
556 assertFalse(isOptionsPanelAtRight(portraitDisplay.getDisplayId()));
557 portraitDisplay.setRotation(Surface.ROTATION_90);
558 assertTrue(isOptionsPanelAtRight(portraitDisplay.getDisplayId()));
559
560 final DisplayContent landscapeDisplay = createNewDisplay();
561 landscapeDisplay.mInitialDisplayHeight = 1000;
562 landscapeDisplay.mInitialDisplayWidth = 2000;
563
564 landscapeDisplay.setRotation(Surface.ROTATION_0);
565 assertTrue(isOptionsPanelAtRight(landscapeDisplay.getDisplayId()));
566 landscapeDisplay.setRotation(Surface.ROTATION_90);
567 assertFalse(isOptionsPanelAtRight(landscapeDisplay.getDisplayId()));
568 }
569
lumarkff0ab692018-11-05 20:32:30 +0800570 @Test
571 public void testInputMethodTargetUpdateWhenSwitchingOnDisplays() {
572 final DisplayContent newDisplay = createNewDisplay();
573
574 final WindowState appWin = createWindow(null, TYPE_APPLICATION, mDisplayContent, "appWin");
575 final WindowState appWin1 = createWindow(null, TYPE_APPLICATION, newDisplay, "appWin1");
576 appWin.setHasSurface(true);
577 appWin1.setHasSurface(true);
578
579 // Set current input method window on default display, make sure the input method target
580 // is appWin & null on the other display.
581 mDisplayContent.setInputMethodWindowLocked(mImeWindow);
582 newDisplay.setInputMethodWindowLocked(null);
583 assertTrue("appWin should be IME target window",
584 appWin.equals(mDisplayContent.mInputMethodTarget));
585 assertNull("newDisplay Ime target: ", newDisplay.mInputMethodTarget);
586
587 // Switch input method window on new display & make sure the input method target also
588 // switched as expected.
589 newDisplay.setInputMethodWindowLocked(mImeWindow);
590 mDisplayContent.setInputMethodWindowLocked(null);
591 assertTrue("appWin1 should be IME target window",
592 appWin1.equals(newDisplay.mInputMethodTarget));
593 assertNull("default display Ime target: ", mDisplayContent.mInputMethodTarget);
594 }
595
Garfield Tan90b04282018-12-11 14:04:42 -0800596 @Test
597 public void testOnDescendantOrientationRequestChanged() {
Garfield Tan49dae102019-02-04 09:51:59 -0800598 final DisplayContent dc = createNewDisplay();
Garfield Tan90b04282018-12-11 14:04:42 -0800599 mWm.mAtmService.mRootActivityContainer = mock(RootActivityContainer.class);
Garfield Tan49dae102019-02-04 09:51:59 -0800600 final int newOrientation = dc.getLastOrientation() == SCREEN_ORIENTATION_LANDSCAPE
601 ? SCREEN_ORIENTATION_PORTRAIT
602 : SCREEN_ORIENTATION_LANDSCAPE;
Garfield Tan90b04282018-12-11 14:04:42 -0800603
604 final WindowState window = createWindow(null /* parent */, TYPE_BASE_APPLICATION, dc, "w");
605 window.getTask().mTaskRecord = mock(TaskRecord.class, ExtendedMockito.RETURNS_DEEP_STUBS);
Garfield Tan49dae102019-02-04 09:51:59 -0800606 window.mAppToken.setOrientation(newOrientation);
Garfield Tan90b04282018-12-11 14:04:42 -0800607
608 ActivityRecord activityRecord = mock(ActivityRecord.class);
609
610 assertTrue("Display should rotate to handle orientation request by default.",
611 dc.onDescendantOrientationChanged(window.mToken.token, activityRecord));
612
613 final ArgumentCaptor<Configuration> captor = ArgumentCaptor.forClass(Configuration.class);
614 verify(mWm.mAtmService).updateDisplayOverrideConfigurationLocked(captor.capture(),
615 same(activityRecord), anyBoolean(), eq(dc.getDisplayId()));
616 final Configuration newDisplayConfig = captor.getValue();
Garfield Tan49dae102019-02-04 09:51:59 -0800617 assertEquals(Configuration.ORIENTATION_PORTRAIT, newDisplayConfig.orientation);
Garfield Tan90b04282018-12-11 14:04:42 -0800618 }
619
620 @Test
621 public void testOnDescendantOrientationRequestChanged_FrozenToUserRotation() {
Garfield Tan49dae102019-02-04 09:51:59 -0800622 final DisplayContent dc = createNewDisplay();
Garfield Tan7fbca052019-02-19 10:45:35 -0800623 dc.getDisplayRotation().setFixedToUserRotation(
624 DisplayRotation.FIXED_TO_USER_ROTATION_ENABLED);
Garfield Tan90b04282018-12-11 14:04:42 -0800625 mWm.mAtmService.mRootActivityContainer = mock(RootActivityContainer.class);
Garfield Tan49dae102019-02-04 09:51:59 -0800626 final int newOrientation = dc.getLastOrientation() == SCREEN_ORIENTATION_LANDSCAPE
627 ? SCREEN_ORIENTATION_PORTRAIT
628 : SCREEN_ORIENTATION_LANDSCAPE;
Garfield Tan90b04282018-12-11 14:04:42 -0800629
630 final WindowState window = createWindow(null /* parent */, TYPE_BASE_APPLICATION, dc, "w");
631 window.getTask().mTaskRecord = mock(TaskRecord.class, ExtendedMockito.RETURNS_DEEP_STUBS);
Garfield Tan49dae102019-02-04 09:51:59 -0800632 window.mAppToken.setOrientation(newOrientation);
Garfield Tan90b04282018-12-11 14:04:42 -0800633
634 ActivityRecord activityRecord = mock(ActivityRecord.class);
635
636 assertFalse("Display shouldn't rotate to handle orientation request if fixed to"
637 + " user rotation.",
638 dc.onDescendantOrientationChanged(window.mToken.token, activityRecord));
639 verify(mWm.mAtmService, never()).updateDisplayOverrideConfigurationLocked(any(),
640 eq(activityRecord), anyBoolean(), eq(dc.getDisplayId()));
641 }
642
Tarandeep Singha6f35612019-01-11 19:50:46 -0800643 @Test
644 public void testComputeImeParent_app() throws Exception {
645 try (final InsetsModeSession session =
646 new InsetsModeSession(ViewRootImpl.NEW_INSETS_MODE_IME)) {
647 final DisplayContent dc = createNewDisplay();
648 dc.mInputMethodTarget = createWindow(null, TYPE_BASE_APPLICATION, "app");
649 assertEquals(dc.mInputMethodTarget.mAppToken.getSurfaceControl(),
650 dc.computeImeParent());
651 }
652 }
653
654 @Test
655 public void testComputeImeParent_app_notFullscreen() throws Exception {
656 try (final InsetsModeSession session =
657 new InsetsModeSession(ViewRootImpl.NEW_INSETS_MODE_IME)) {
658 final DisplayContent dc = createNewDisplay();
659 dc.mInputMethodTarget = createWindow(null, TYPE_STATUS_BAR, "app");
660 dc.mInputMethodTarget.setWindowingMode(
661 WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
662 assertEquals(dc.getWindowingLayer(), dc.computeImeParent());
663 }
664 }
665
666 @Test
Riddle Hsu6d6f67c2019-03-14 16:54:26 +0800667 public void testComputeImeParent_app_notMatchParentBounds() {
668 spyOn(mAppWindow.mAppToken);
669 doReturn(false).when(mAppWindow.mAppToken).matchParentBounds();
670 mDisplayContent.mInputMethodTarget = mAppWindow;
671 // The surface parent of IME should be the display instead of app window.
672 assertEquals(mDisplayContent.getWindowingLayer(), mDisplayContent.computeImeParent());
673 }
674
675 @Test
Tarandeep Singha6f35612019-01-11 19:50:46 -0800676 public void testComputeImeParent_noApp() throws Exception {
677 try (final InsetsModeSession session =
678 new InsetsModeSession(ViewRootImpl.NEW_INSETS_MODE_IME)) {
679 final DisplayContent dc = createNewDisplay();
680 dc.mInputMethodTarget = createWindow(null, TYPE_STATUS_BAR, "statusBar");
681 assertEquals(dc.getWindowingLayer(), dc.computeImeParent());
682 }
683 }
684
Susi Kharraz-Post9893b8c2019-02-12 14:21:29 -0500685 @Test
686 public void testOrientationChangeLogging() {
687 MetricsLogger mockLogger = mock(MetricsLogger.class);
688 Configuration oldConfig = new Configuration();
689 oldConfig.orientation = Configuration.ORIENTATION_LANDSCAPE;
690
691 Configuration newConfig = new Configuration();
692 newConfig.orientation = Configuration.ORIENTATION_PORTRAIT;
693 final DisplayContent displayContent = spy(createNewDisplay());
694 Mockito.doReturn(mockLogger).when(displayContent).getMetricsLogger();
695 Mockito.doReturn(oldConfig).doReturn(newConfig).when(displayContent).getConfiguration();
696
697 displayContent.onConfigurationChanged(newConfig);
698
699 ArgumentCaptor<LogMaker> logMakerCaptor = ArgumentCaptor.forClass(LogMaker.class);
700 verify(mockLogger).write(logMakerCaptor.capture());
701 assertThat(logMakerCaptor.getValue().getCategory(),
702 is(MetricsProto.MetricsEvent.ACTION_PHONE_ORIENTATION_CHANGED));
703 assertThat(logMakerCaptor.getValue().getSubtype(),
704 is(Configuration.ORIENTATION_PORTRAIT));
705 }
706
Riddle Hsua4d6fa22018-08-11 00:50:39 +0800707 private boolean isOptionsPanelAtRight(int displayId) {
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700708 return (mWm.getPreferredOptionsPanelGravity(displayId) & Gravity.RIGHT) == Gravity.RIGHT;
Riddle Hsua4d6fa22018-08-11 00:50:39 +0800709 }
710
Bryce Lee27cec322017-03-21 09:41:37 -0700711 private static void verifySizes(DisplayContent displayContent, int expectedBaseWidth,
712 int expectedBaseHeight, int expectedBaseDensity) {
713 assertEquals(displayContent.mBaseDisplayWidth, expectedBaseWidth);
714 assertEquals(displayContent.mBaseDisplayHeight, expectedBaseHeight);
715 assertEquals(displayContent.mBaseDisplayDensity, expectedBaseDensity);
716 }
717
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800718 private void updateFocusedWindow() {
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700719 synchronized (mWm.mGlobalLock) {
720 mWm.updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, false);
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800721 }
722 }
723
Riddle Hsu654a6f92018-07-13 22:59:36 +0800724 /**
725 * Create DisplayContent that does not update display base/initial values from device to keep
726 * the values set by test.
727 */
728 private DisplayContent createDisplayNoUpdateDisplayInfo() {
729 final DisplayContent displayContent = spy(createNewDisplay());
730 doNothing().when(displayContent).updateDisplayInfo();
731 return displayContent;
732 }
733
Adrian Roos0f9368c2018-04-08 10:59:08 -0700734 private void assertForAllWindowsOrder(List<WindowState> expectedWindowsBottomToTop) {
735 final LinkedList<WindowState> actualWindows = new LinkedList<>();
Wale Ogunwale34247952017-02-19 11:57:53 -0800736
737 // Test forward traversal.
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700738 mDisplayContent.forAllWindows(actualWindows::addLast, false /* traverseTopToBottom */);
Adrian Roos0f9368c2018-04-08 10:59:08 -0700739 assertThat("bottomToTop", actualWindows, is(expectedWindowsBottomToTop));
740
741 actualWindows.clear();
Wale Ogunwale34247952017-02-19 11:57:53 -0800742
743 // Test backward traversal.
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700744 mDisplayContent.forAllWindows(actualWindows::addLast, true /* traverseTopToBottom */);
Adrian Roos0f9368c2018-04-08 10:59:08 -0700745 assertThat("topToBottom", actualWindows, is(reverseList(expectedWindowsBottomToTop)));
746 }
747
748 private static List<WindowState> reverseList(List<WindowState> list) {
749 final ArrayList<WindowState> result = new ArrayList<>(list);
750 Collections.reverse(result);
751 return result;
Wale Ogunwale34247952017-02-19 11:57:53 -0800752 }
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -0700753
Arthur Hungbe5ce212018-09-13 18:41:56 +0800754 private void tapOnDisplay(final DisplayContent dc) {
755 final DisplayMetrics dm = dc.getDisplayMetrics();
756 final float x = dm.widthPixels / 2;
757 final float y = dm.heightPixels / 2;
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -0700758 final long downTime = SystemClock.uptimeMillis();
759 final long eventTime = SystemClock.uptimeMillis() + 100;
Arthur Hungbe5ce212018-09-13 18:41:56 +0800760 // sending ACTION_DOWN
761 final MotionEvent downEvent = MotionEvent.obtain(
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -0700762 downTime,
Arthur Hungbe5ce212018-09-13 18:41:56 +0800763 downTime,
764 MotionEvent.ACTION_DOWN,
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -0700765 x,
766 y,
Arthur Hungbe5ce212018-09-13 18:41:56 +0800767 0 /*metaState*/);
768 downEvent.setDisplayId(dc.getDisplayId());
769 dc.mTapDetector.onPointerEvent(downEvent);
770
771 // sending ACTION_UP
772 final MotionEvent upEvent = MotionEvent.obtain(
773 downTime,
774 eventTime,
775 MotionEvent.ACTION_UP,
776 x,
777 y,
778 0 /*metaState*/);
779 upEvent.setDisplayId(dc.getDisplayId());
780 dc.mTapDetector.onPointerEvent(upEvent);
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -0700781 }
Wale Ogunwaleb783fd82016-11-04 09:51:54 -0700782}