blob: 4e82ceb882a835ec60432a14616a2588563c3369 [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
Garfield Tan98eead32019-11-18 13:24:53 -080019import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
Andrii Kulian92c9a942017-10-10 00:41:41 -070020import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
21import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
22import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
Tiger Huang86e6d072019-05-02 20:23:47 +080023import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_USER;
Tiger Huang51c5a1d2018-12-11 20:24:51 +080024import static android.os.Build.VERSION_CODES.P;
25import static android.os.Build.VERSION_CODES.Q;
Wale Ogunwale34247952017-02-19 11:57:53 -080026import static android.view.Display.DEFAULT_DISPLAY;
Issei Suzuki43190bd2018-08-20 17:28:41 +020027import static android.view.DisplayCutout.BOUNDS_POSITION_LEFT;
28import static android.view.DisplayCutout.BOUNDS_POSITION_TOP;
Adrian Roos24264212018-02-19 16:26:15 +010029import static android.view.DisplayCutout.fromBoundingRect;
Riddle Hsu9239d7c62020-02-20 01:35:56 +080030import static android.view.Surface.ROTATION_0;
Evan Rosky69cace42019-09-20 16:28:13 -070031import static android.view.Surface.ROTATION_90;
Adrian Roos019a52b2019-07-02 16:47:44 +020032import static android.view.View.SYSTEM_UI_FLAG_FULLSCREEN;
33import static android.view.View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
34import static android.view.View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
Adrian Roos4ffc8972019-02-07 20:45:11 +010035import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR;
36import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
Adrian Roos019a52b2019-07-02 16:47:44 +020037import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
38import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION;
Wale Ogunwale34247952017-02-19 11:57:53 -080039import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
40import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
Tiger Huang86e6d072019-05-02 20:23:47 +080041import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
Wale Ogunwale34247952017-02-19 11:57:53 -080042import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
wilsonshihe8321942019-10-18 18:39:46 +080043import static android.view.WindowManager.LayoutParams.TYPE_NOTIFICATION_SHADE;
Mark Renoufa9279292020-04-17 12:22:50 -040044import static android.view.WindowManager.LayoutParams.TYPE_SCREENSHOT;
Andrii Kulian92c9a942017-10-10 00:41:41 -070045import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
Wale Ogunwale34247952017-02-19 11:57:53 -080046import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION;
Riddle Hsub2297ad2019-07-26 23:37:25 -060047import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
Brett Chabota26eda92018-07-23 13:08:30 -070048
Garfield Tan90b04282018-12-11 14:04:42 -080049import static com.android.dx.mockito.inline.extended.ExtendedMockito.any;
50import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyBoolean;
Tadashi G. Takaokabf0d57b2018-11-19 16:09:58 +090051import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
Riddle Hsu6d6f67c2019-03-14 16:54:26 +080052import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
Garfield Tan90b04282018-12-11 14:04:42 -080053import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
54import static com.android.dx.mockito.inline.extended.ExtendedMockito.never;
Riddle Hsub2297ad2019-07-26 23:37:25 -060055import static com.android.dx.mockito.inline.extended.ExtendedMockito.reset;
Garfield Tan90b04282018-12-11 14:04:42 -080056import static com.android.dx.mockito.inline.extended.ExtendedMockito.same;
Riddle Hsu6d6f67c2019-03-14 16:54:26 +080057import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
Tadashi G. Takaokabf0d57b2018-11-19 16:09:58 +090058import static com.android.dx.mockito.inline.extended.ExtendedMockito.times;
59import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
David Stevens46939562017-03-24 13:04:00 -070060import static com.android.server.wm.WindowContainer.POSITION_TOP;
Tiger Huang1e5b10a2018-07-30 20:19:51 +080061import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_NORMAL;
chaviwebcbc342018-02-07 13:19:00 -080062
Riddle Hsu12c05452020-01-09 00:39:52 +080063import static com.google.common.truth.Truth.assertThat;
64
Adrian Roos5251b1d2018-03-23 18:57:43 +010065import static org.hamcrest.Matchers.is;
Wale Ogunwale34247952017-02-19 11:57:53 -080066import static org.junit.Assert.assertEquals;
Andrii Kulianf0379de2018-03-14 16:24:07 -070067import static org.junit.Assert.assertFalse;
Jorim Jaggicc57cb72020-04-09 14:54:13 +020068import static org.junit.Assert.assertNotEquals;
Arthur Hungbe5ce212018-09-13 18:41:56 +080069import static org.junit.Assert.assertNotNull;
lumarkff0ab692018-11-05 20:32:30 +080070import static org.junit.Assert.assertNull;
Adrian Roos5251b1d2018-03-23 18:57:43 +010071import static org.junit.Assert.assertThat;
Wale Ogunwale34247952017-02-19 11:57:53 -080072import static org.junit.Assert.assertTrue;
Evan Rosky69cace42019-09-20 16:28:13 -070073import static org.mockito.ArgumentMatchers.anyInt;
Tarandeep Singha6f35612019-01-11 19:50:46 -080074import static org.mockito.ArgumentMatchers.eq;
Charles Chen770597c2020-05-18 19:58:23 +080075import static org.mockito.Mockito.doAnswer;
Wale Ogunwale34247952017-02-19 11:57:53 -080076
Andrii Kulian92c9a942017-10-10 00:41:41 -070077import android.annotation.SuppressLint;
Mark Renoufa9279292020-04-17 12:22:50 -040078import android.app.ActivityTaskManager;
Tarandeep Singha6f35612019-01-11 19:50:46 -080079import android.app.WindowConfiguration;
Andrii Kuliand68501e2017-01-10 22:57:27 -080080import android.content.res.Configuration;
Adrian Roos1cf585052018-01-03 18:43:27 +010081import android.graphics.Rect;
Adrian Roos4ffc8972019-02-07 20:45:11 +010082import android.graphics.Region;
Susi Kharraz-Post9893b8c2019-02-12 14:21:29 -050083import android.metrics.LogMaker;
Evan Rosky69cace42019-09-20 16:28:13 -070084import android.os.RemoteException;
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -070085import android.os.SystemClock;
Wale Ogunwaleb783fd82016-11-04 09:51:54 -070086import android.platform.test.annotations.Presubmit;
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -070087import android.util.DisplayMetrics;
Adrian Roos1cf585052018-01-03 18:43:27 +010088import android.view.DisplayCutout;
Riddle Hsua4d6fa22018-08-11 00:50:39 +080089import android.view.Gravity;
Jorim Jaggicc57cb72020-04-09 14:54:13 +020090import android.view.IDisplayWindowInsetsController;
Evan Rosky69cace42019-09-20 16:28:13 -070091import android.view.IDisplayWindowRotationCallback;
92import android.view.IDisplayWindowRotationController;
Adrian Roos4ffc8972019-02-07 20:45:11 +010093import android.view.ISystemGestureExclusionListener;
Garfield Tana3f19032019-11-19 18:04:50 -080094import android.view.IWindowManager;
Jorim Jaggicc57cb72020-04-09 14:54:13 +020095import android.view.InsetsSourceControl;
96import android.view.InsetsState;
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -070097import android.view.MotionEvent;
Adrian Roos1cf585052018-01-03 18:43:27 +010098import android.view.Surface;
Riddle Hsu3d0aa4f2020-04-09 17:58:50 +080099import android.view.SurfaceControl.Transaction;
Riddle Hsu12c05452020-01-09 00:39:52 +0800100import android.view.WindowManager;
Wale Ogunwaleb783fd82016-11-04 09:51:54 -0700101
Brett Chabota26eda92018-07-23 13:08:30 -0700102import androidx.test.filters.SmallTest;
Brett Chabota26eda92018-07-23 13:08:30 -0700103
Susi Kharraz-Post9893b8c2019-02-12 14:21:29 -0500104import com.android.internal.logging.MetricsLogger;
105import com.android.internal.logging.nano.MetricsProto;
Adrian Roos6a4fa0e2018-03-05 19:50:16 +0100106import com.android.server.wm.utils.WmDisplayCutout;
107
Brett Chabota26eda92018-07-23 13:08:30 -0700108import org.junit.Test;
Riddle Hsu73f53572019-09-23 23:13:01 +0800109import org.junit.runner.RunWith;
Garfield Tan90b04282018-12-11 14:04:42 -0800110import org.mockito.ArgumentCaptor;
Susi Kharraz-Post9893b8c2019-02-12 14:21:29 -0500111import org.mockito.Mockito;
Brett Chabota26eda92018-07-23 13:08:30 -0700112
Adrian Roos0f9368c2018-04-08 10:59:08 -0700113import java.util.ArrayList;
Wale Ogunwale34247952017-02-19 11:57:53 -0800114import java.util.Arrays;
Adrian Roos0f9368c2018-04-08 10:59:08 -0700115import java.util.Collections;
Wale Ogunwale34247952017-02-19 11:57:53 -0800116import java.util.LinkedList;
117import java.util.List;
Wale Ogunwaleb783fd82016-11-04 09:51:54 -0700118
119/**
120 * Tests for the {@link DisplayContent} class.
121 *
122 * Build/Install/Run:
Yunfan Chen6dd9a622019-02-18 15:12:33 +0900123 * atest WmTests:DisplayContentTests
Wale Ogunwaleb783fd82016-11-04 09:51:54 -0700124 */
125@SmallTest
126@Presubmit
Riddle Hsu73f53572019-09-23 23:13:01 +0800127@RunWith(WindowTestRunner.class)
Wale Ogunwale44fbdf52016-11-16 10:18:45 -0800128public class DisplayContentTests extends WindowTestsBase {
Wale Ogunwaleb783fd82016-11-04 09:51:54 -0700129
130 @Test
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700131 public void testForAllWindows() {
Wale Ogunwale3c1170d2016-12-02 14:44:52 -0800132 final WindowState exitingAppWindow = createWindow(null, TYPE_BASE_APPLICATION,
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700133 mDisplayContent, "exiting app");
Garfield Tane8d84ab2019-10-11 09:49:40 -0700134 final ActivityRecord exitingApp = exitingAppWindow.mActivityRecord;
Yunfan Chen6dd9a622019-02-18 15:12:33 +0900135 // Wait until everything in animation handler get executed to prevent the exiting window
136 // from being removed during WindowSurfacePlacer Traversal.
137 waitUntilHandlersIdle();
138
Garfield Tane8d84ab2019-10-11 09:49:40 -0700139 exitingApp.mIsExiting = true;
Wale Ogunwale0b3d2922019-12-30 08:55:07 -0800140 exitingApp.getTask().getStack().mExitingActivities.add(exitingApp);
Wale Ogunwaleb783fd82016-11-04 09:51:54 -0700141
Wale Ogunwale34247952017-02-19 11:57:53 -0800142 assertForAllWindowsOrder(Arrays.asList(
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700143 mWallpaperWindow,
Wale Ogunwale34247952017-02-19 11:57:53 -0800144 exitingAppWindow,
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700145 mChildAppWindowBelow,
146 mAppWindow,
147 mChildAppWindowAbove,
148 mDockedDividerWindow,
Adrian Roos22a20a82019-10-23 19:05:33 +0200149 mImeWindow,
150 mImeDialogWindow,
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700151 mStatusBarWindow,
wilsonshihe8321942019-10-18 18:39:46 +0800152 mNotificationShadeWindow,
Adrian Roos22a20a82019-10-23 19:05:33 +0200153 mNavBarWindow));
Wale Ogunwale3c1170d2016-12-02 14:44:52 -0800154 }
155
156 @Test
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700157 public void testForAllWindows_WithAppImeTarget() {
Wale Ogunwale3c1170d2016-12-02 14:44:52 -0800158 final WindowState imeAppTarget =
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700159 createWindow(null, TYPE_BASE_APPLICATION, mDisplayContent, "imeAppTarget");
Wale Ogunwale3c1170d2016-12-02 14:44:52 -0800160
lumarkff0ab692018-11-05 20:32:30 +0800161 mDisplayContent.mInputMethodTarget = imeAppTarget;
Wale Ogunwale3c1170d2016-12-02 14:44:52 -0800162
Wale Ogunwale34247952017-02-19 11:57:53 -0800163 assertForAllWindowsOrder(Arrays.asList(
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700164 mWallpaperWindow,
165 mChildAppWindowBelow,
166 mAppWindow,
167 mChildAppWindowAbove,
Wale Ogunwale34247952017-02-19 11:57:53 -0800168 imeAppTarget,
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700169 mImeWindow,
170 mImeDialogWindow,
171 mDockedDividerWindow,
172 mStatusBarWindow,
wilsonshihe8321942019-10-18 18:39:46 +0800173 mNotificationShadeWindow,
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700174 mNavBarWindow));
Wale Ogunwale34247952017-02-19 11:57:53 -0800175 }
Wale Ogunwale3c1170d2016-12-02 14:44:52 -0800176
Wale Ogunwale34247952017-02-19 11:57:53 -0800177 @Test
lumarkff0ab692018-11-05 20:32:30 +0800178 public void testForAllWindows_WithChildWindowImeTarget() throws Exception {
179 mDisplayContent.mInputMethodTarget = mChildAppWindowAbove;
Wale Ogunwale3c1170d2016-12-02 14:44:52 -0800180
Wale Ogunwale34247952017-02-19 11:57:53 -0800181 assertForAllWindowsOrder(Arrays.asList(
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700182 mWallpaperWindow,
183 mChildAppWindowBelow,
184 mAppWindow,
185 mChildAppWindowAbove,
186 mImeWindow,
187 mImeDialogWindow,
188 mDockedDividerWindow,
189 mStatusBarWindow,
wilsonshihe8321942019-10-18 18:39:46 +0800190 mNotificationShadeWindow,
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700191 mNavBarWindow));
Wale Ogunwaleb783fd82016-11-04 09:51:54 -0700192 }
Wale Ogunwale5d7e7f12016-12-12 14:47:05 -0800193
194 @Test
lumarkff0ab692018-11-05 20:32:30 +0800195 public void testForAllWindows_WithStatusBarImeTarget() throws Exception {
196 mDisplayContent.mInputMethodTarget = mStatusBarWindow;
Wale Ogunwale6ce0fb82016-12-13 14:24:00 -0800197
Wale Ogunwale34247952017-02-19 11:57:53 -0800198 assertForAllWindowsOrder(Arrays.asList(
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700199 mWallpaperWindow,
200 mChildAppWindowBelow,
201 mAppWindow,
202 mChildAppWindowAbove,
203 mDockedDividerWindow,
204 mStatusBarWindow,
205 mImeWindow,
206 mImeDialogWindow,
wilsonshihe8321942019-10-18 18:39:46 +0800207 mNotificationShadeWindow,
208 mNavBarWindow));
209 }
210
211 @Test
212 public void testForAllWindows_WithNotificationShadeImeTarget() throws Exception {
213 mDisplayContent.mInputMethodTarget = mNotificationShadeWindow;
214
215 assertForAllWindowsOrder(Arrays.asList(
216 mWallpaperWindow,
217 mChildAppWindowBelow,
218 mAppWindow,
219 mChildAppWindowAbove,
220 mDockedDividerWindow,
221 mStatusBarWindow,
222 mNotificationShadeWindow,
223 mImeWindow,
224 mImeDialogWindow,
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700225 mNavBarWindow));
Wale Ogunwale6ce0fb82016-12-13 14:24:00 -0800226 }
227
228 @Test
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700229 public void testForAllWindows_WithInBetweenWindowToken() {
Wale Ogunwale5d7e7f12016-12-12 14:47:05 -0800230 // This window is set-up to be z-ordered between some windows that go in the same token like
231 // the nav bar and status bar.
232 final WindowState voiceInteractionWindow = createWindow(null, TYPE_VOICE_INTERACTION,
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700233 mDisplayContent, "voiceInteractionWindow");
Wale Ogunwale5d7e7f12016-12-12 14:47:05 -0800234
Wale Ogunwale34247952017-02-19 11:57:53 -0800235 assertForAllWindowsOrder(Arrays.asList(
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700236 mWallpaperWindow,
237 mChildAppWindowBelow,
238 mAppWindow,
239 mChildAppWindowAbove,
240 mDockedDividerWindow,
Wale Ogunwale34247952017-02-19 11:57:53 -0800241 voiceInteractionWindow,
Adrian Roos22a20a82019-10-23 19:05:33 +0200242 mImeWindow,
243 mImeDialogWindow,
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700244 mStatusBarWindow,
wilsonshihe8321942019-10-18 18:39:46 +0800245 mNotificationShadeWindow,
Adrian Roos22a20a82019-10-23 19:05:33 +0200246 mNavBarWindow));
Wale Ogunwale34247952017-02-19 11:57:53 -0800247 }
Wale Ogunwale5d7e7f12016-12-12 14:47:05 -0800248
Wale Ogunwale34247952017-02-19 11:57:53 -0800249 @Test
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700250 public void testComputeImeTarget() {
Wale Ogunwale34247952017-02-19 11:57:53 -0800251 // Verify that an app window can be an ime target.
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700252 final WindowState appWin = createWindow(null, TYPE_APPLICATION, mDisplayContent, "appWin");
Wale Ogunwale34247952017-02-19 11:57:53 -0800253 appWin.setHasSurface(true);
254 assertTrue(appWin.canBeImeTarget());
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700255 WindowState imeTarget = mDisplayContent.computeImeTarget(false /* updateImeTarget */);
Wale Ogunwale34247952017-02-19 11:57:53 -0800256 assertEquals(appWin, imeTarget);
chaviwebcbc342018-02-07 13:19:00 -0800257 appWin.mHidden = false;
Wale Ogunwale5d7e7f12016-12-12 14:47:05 -0800258
Wale Ogunwale34247952017-02-19 11:57:53 -0800259 // Verify that an child window can be an ime target.
260 final WindowState childWin = createWindow(appWin,
261 TYPE_APPLICATION_ATTACHED_DIALOG, "childWin");
262 childWin.setHasSurface(true);
263 assertTrue(childWin.canBeImeTarget());
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700264 imeTarget = mDisplayContent.computeImeTarget(false /* updateImeTarget */);
Wale Ogunwale34247952017-02-19 11:57:53 -0800265 assertEquals(childWin, imeTarget);
Wale Ogunwale5d7e7f12016-12-12 14:47:05 -0800266 }
Andrii Kulian6cc1a1d2016-12-27 23:52:59 -0800267
Andrii Kuliand68501e2017-01-10 22:57:27 -0800268 /**
269 * This tests stack movement between displays and proper stack's, task's and app token's display
270 * container references updates.
271 */
Andrii Kulian6cc1a1d2016-12-27 23:52:59 -0800272 @Test
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700273 public void testMoveStackBetweenDisplays() {
Andrii Kulian367ff7f2017-01-25 19:45:34 -0800274 // Create a second display.
275 final DisplayContent dc = createNewDisplay();
Andrii Kulian6cc1a1d2016-12-27 23:52:59 -0800276
277 // Add stack with activity.
Wale Ogunwalebebd8cd2019-10-28 15:53:31 -0700278 final ActivityStack stack = createTaskStackOnDisplay(dc);
Andrii Kulian6cc1a1d2016-12-27 23:52:59 -0800279 assertEquals(dc.getDisplayId(), stack.getDisplayContent().getDisplayId());
Andrii Kulian6cc1a1d2016-12-27 23:52:59 -0800280 assertEquals(dc, stack.getDisplayContent());
281
282 final Task task = createTaskInStack(stack, 0 /* userId */);
Garfield Tane8d84ab2019-10-11 09:49:40 -0700283 final ActivityRecord activity = WindowTestUtils.createTestActivityRecord(dc);
284 task.addChild(activity, 0);
Andrii Kulian6cc1a1d2016-12-27 23:52:59 -0800285 assertEquals(dc, task.getDisplayContent());
Garfield Tane8d84ab2019-10-11 09:49:40 -0700286 assertEquals(dc, activity.getDisplayContent());
Andrii Kulian6cc1a1d2016-12-27 23:52:59 -0800287
288 // Move stack to first display.
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -0700289 stack.reparent(mDisplayContent.getDefaultTaskDisplayArea(), true /* onTop */);
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700290 assertEquals(mDisplayContent.getDisplayId(), stack.getDisplayContent().getDisplayId());
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700291 assertEquals(mDisplayContent, stack.getDisplayContent());
292 assertEquals(mDisplayContent, task.getDisplayContent());
Garfield Tane8d84ab2019-10-11 09:49:40 -0700293 assertEquals(mDisplayContent, activity.getDisplayContent());
Andrii Kulian6cc1a1d2016-12-27 23:52:59 -0800294 }
Andrii Kuliand68501e2017-01-10 22:57:27 -0800295
296 /**
297 * This tests override configuration updates for display content.
298 */
299 @Test
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700300 public void testDisplayOverrideConfigUpdate() {
Evan Roskydfe3da72018-10-26 17:21:06 -0700301 final Configuration currentOverrideConfig =
302 mDisplayContent.getRequestedOverrideConfiguration();
Andrii Kuliand68501e2017-01-10 22:57:27 -0800303
304 // Create new, slightly changed override configuration and apply it to the display.
305 final Configuration newOverrideConfig = new Configuration(currentOverrideConfig);
306 newOverrideConfig.densityDpi += 120;
307 newOverrideConfig.fontScale += 0.3;
308
Evan Roskye747c3e2018-10-30 20:06:41 -0700309 mWm.setNewDisplayOverrideConfiguration(newOverrideConfig, mDisplayContent);
Andrii Kuliand68501e2017-01-10 22:57:27 -0800310
311 // Check that override config is applied.
Evan Roskydfe3da72018-10-26 17:21:06 -0700312 assertEquals(newOverrideConfig, mDisplayContent.getRequestedOverrideConfiguration());
Andrii Kulian367ff7f2017-01-25 19:45:34 -0800313 }
314
315 /**
316 * This tests global configuration updates when default display config is updated.
317 */
318 @Test
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700319 public void testDefaultDisplayOverrideConfigUpdate() {
Evan Roskye747c3e2018-10-30 20:06:41 -0700320 DisplayContent defaultDisplay = mWm.mRoot.getDisplayContent(DEFAULT_DISPLAY);
321 final Configuration currentConfig = defaultDisplay.getConfiguration();
Andrii Kulian367ff7f2017-01-25 19:45:34 -0800322
323 // Create new, slightly changed override configuration and apply it to the display.
Andrii Kuliana95bfff2017-03-30 19:00:41 -0700324 final Configuration newOverrideConfig = new Configuration(currentConfig);
Andrii Kulian367ff7f2017-01-25 19:45:34 -0800325 newOverrideConfig.densityDpi += 120;
326 newOverrideConfig.fontScale += 0.3;
327
Evan Roskye747c3e2018-10-30 20:06:41 -0700328 mWm.setNewDisplayOverrideConfiguration(newOverrideConfig, defaultDisplay);
Andrii Kuliand68501e2017-01-10 22:57:27 -0800329
330 // Check that global configuration is updated, as we've updated default display's config.
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700331 Configuration globalConfig = mWm.mRoot.getConfiguration();
Andrii Kuliand68501e2017-01-10 22:57:27 -0800332 assertEquals(newOverrideConfig.densityDpi, globalConfig.densityDpi);
333 assertEquals(newOverrideConfig.fontScale, globalConfig.fontScale, 0.1 /* delta */);
Andrii Kulian367ff7f2017-01-25 19:45:34 -0800334
335 // Return back to original values.
Evan Roskye747c3e2018-10-30 20:06:41 -0700336 mWm.setNewDisplayOverrideConfiguration(currentConfig, defaultDisplay);
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700337 globalConfig = mWm.mRoot.getConfiguration();
Andrii Kuliana95bfff2017-03-30 19:00:41 -0700338 assertEquals(currentConfig.densityDpi, globalConfig.densityDpi);
339 assertEquals(currentConfig.fontScale, globalConfig.fontScale, 0.1 /* delta */);
Andrii Kuliand68501e2017-01-10 22:57:27 -0800340 }
Wale Ogunwale34247952017-02-19 11:57:53 -0800341
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -0700342 /**
343 * Tests tapping on a stack in different display results in window gaining focus.
344 */
345 @Test
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700346 public void testInputEventBringsCorrectDisplayInFocus() {
347 DisplayContent dc0 = mWm.getDefaultDisplayContentLocked();
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -0700348 // Create a second display
349 final DisplayContent dc1 = createNewDisplay();
350
351 // Add stack with activity.
Wale Ogunwalebebd8cd2019-10-28 15:53:31 -0700352 final ActivityStack stack0 = createTaskStackOnDisplay(dc0);
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -0700353 final Task task0 = createTaskInStack(stack0, 0 /* userId */);
Garfield Tane8d84ab2019-10-11 09:49:40 -0700354 final ActivityRecord activity =
355 WindowTestUtils.createTestActivityRecord(dc0);
356 task0.addChild(activity, 0);
Arthur Hungbe5ce212018-09-13 18:41:56 +0800357 dc0.configureDisplayPolicy();
358 assertNotNull(dc0.mTapDetector);
359
Wale Ogunwalebebd8cd2019-10-28 15:53:31 -0700360 final ActivityStack stack1 = createTaskStackOnDisplay(dc1);
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -0700361 final Task task1 = createTaskInStack(stack1, 0 /* userId */);
Garfield Tane8d84ab2019-10-11 09:49:40 -0700362 final ActivityRecord activity1 =
363 WindowTestUtils.createTestActivityRecord(dc0);
364 task1.addChild(activity1, 0);
Arthur Hungbe5ce212018-09-13 18:41:56 +0800365 dc1.configureDisplayPolicy();
366 assertNotNull(dc1.mTapDetector);
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -0700367
Arthur Hungbe5ce212018-09-13 18:41:56 +0800368 // tap on primary display.
369 tapOnDisplay(dc0);
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -0700370 // Check focus is on primary display.
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700371 assertEquals(mWm.mRoot.getTopFocusedDisplayContent().mCurrentFocus,
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800372 dc0.findFocusedWindow());
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -0700373
Arthur Hungbe5ce212018-09-13 18:41:56 +0800374 // Tap on secondary display.
375 tapOnDisplay(dc1);
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -0700376 // Check focus is on secondary.
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700377 assertEquals(mWm.mRoot.getTopFocusedDisplayContent().mCurrentFocus,
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800378 dc1.findFocusedWindow());
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -0700379 }
380
David Stevens46939562017-03-24 13:04:00 -0700381 @Test
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700382 public void testFocusedWindowMultipleDisplays() {
Tiger Huang51c5a1d2018-12-11 20:24:51 +0800383 doTestFocusedWindowMultipleDisplays(false /* perDisplayFocusEnabled */, Q);
384 }
385
386 @Test
387 public void testFocusedWindowMultipleDisplaysPerDisplayFocusEnabled() {
388 doTestFocusedWindowMultipleDisplays(true /* perDisplayFocusEnabled */, Q);
389 }
390
391 @Test
392 public void testFocusedWindowMultipleDisplaysPerDisplayFocusEnabledLegacyApp() {
393 doTestFocusedWindowMultipleDisplays(true /* perDisplayFocusEnabled */, P);
394 }
395
396 private void doTestFocusedWindowMultipleDisplays(boolean perDisplayFocusEnabled,
397 int targetSdk) {
398 mWm.mPerDisplayFocusEnabled = perDisplayFocusEnabled;
399
Andrii Kulian0214ed92017-05-16 13:44:05 -0700400 // Create a focusable window and check that focus is calculated correctly
David Stevens46939562017-03-24 13:04:00 -0700401 final WindowState window1 =
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700402 createWindow(null, TYPE_BASE_APPLICATION, mDisplayContent, "window1");
Garfield Tane8d84ab2019-10-11 09:49:40 -0700403 window1.mActivityRecord.mTargetSdk = targetSdk;
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800404 updateFocusedWindow();
405 assertTrue(window1.isFocused());
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700406 assertEquals(window1, mWm.mRoot.getTopFocusedDisplayContent().mCurrentFocus);
David Stevens46939562017-03-24 13:04:00 -0700407
408 // Check that a new display doesn't affect focus
409 final DisplayContent dc = createNewDisplay();
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800410 updateFocusedWindow();
411 assertTrue(window1.isFocused());
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700412 assertEquals(window1, mWm.mRoot.getTopFocusedDisplayContent().mCurrentFocus);
David Stevens46939562017-03-24 13:04:00 -0700413
414 // Add a window to the second display, and it should be focused
415 final WindowState window2 = createWindow(null, TYPE_BASE_APPLICATION, dc, "window2");
Garfield Tane8d84ab2019-10-11 09:49:40 -0700416 window2.mActivityRecord.mTargetSdk = targetSdk;
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800417 updateFocusedWindow();
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800418 assertTrue(window2.isFocused());
Tiger Huang51c5a1d2018-12-11 20:24:51 +0800419 assertEquals(perDisplayFocusEnabled && targetSdk >= Q, window1.isFocused());
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700420 assertEquals(window2, mWm.mRoot.getTopFocusedDisplayContent().mCurrentFocus);
David Stevens46939562017-03-24 13:04:00 -0700421
Tiger Huang51c5a1d2018-12-11 20:24:51 +0800422 // Move the first window to top including parents, and make sure focus is updated
David Stevens46939562017-03-24 13:04:00 -0700423 window1.getParent().positionChildAt(POSITION_TOP, window1, true);
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800424 updateFocusedWindow();
425 assertTrue(window1.isFocused());
Tiger Huang51c5a1d2018-12-11 20:24:51 +0800426 assertEquals(perDisplayFocusEnabled && targetSdk >= Q, window2.isFocused());
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700427 assertEquals(window1, mWm.mRoot.getTopFocusedDisplayContent().mCurrentFocus);
Louis Changa9350fe2019-04-25 17:14:20 +0800428
429 // Make sure top focused display not changed if there is a focused app.
Issei Suzuki1669ea42019-11-06 14:20:59 +0100430 window1.mActivityRecord.mVisibleRequested = false;
Garfield Tane8d84ab2019-10-11 09:49:40 -0700431 window1.getDisplayContent().setFocusedApp(window1.mActivityRecord);
Louis Changa9350fe2019-04-25 17:14:20 +0800432 updateFocusedWindow();
433 assertTrue(!window1.isFocused());
434 assertEquals(window1.getDisplayId(),
435 mWm.mRoot.getTopFocusedDisplayContent().getDisplayId());
Adrian Roos4163d622018-05-22 16:56:35 +0200436 }
437
Riddle Hsub2297ad2019-07-26 23:37:25 -0600438 @Test
439 public void testShouldWaitForSystemDecorWindowsOnBoot_OnDefaultDisplay() {
440 mWm.mSystemBooted = true;
441 final DisplayContent defaultDisplay = mWm.getDefaultDisplayContentLocked();
442 final WindowState[] windows = createNotDrawnWindowsOn(defaultDisplay,
443 TYPE_WALLPAPER, TYPE_APPLICATION);
444
445 // Verify waiting for windows to be drawn.
446 assertTrue(defaultDisplay.shouldWaitForSystemDecorWindowsOnBoot());
447
448 // Verify not waiting for drawn windows.
Lais Andrade57283fb2020-04-21 18:58:15 +0000449 makeWindowsDrawnState(windows, WindowStateAnimator.HAS_DRAWN);
Riddle Hsub2297ad2019-07-26 23:37:25 -0600450 assertFalse(defaultDisplay.shouldWaitForSystemDecorWindowsOnBoot());
451 }
452
453 @Test
454 public void testShouldWaitForSystemDecorWindowsOnBoot_OnSecondaryDisplay() {
455 mWm.mSystemBooted = true;
456 final DisplayContent secondaryDisplay = createNewDisplay();
457 final WindowState[] windows = createNotDrawnWindowsOn(secondaryDisplay,
458 TYPE_WALLPAPER, TYPE_APPLICATION);
459
460 // Verify not waiting for display without system decorations.
461 doReturn(false).when(secondaryDisplay).supportsSystemDecorations();
462 assertFalse(secondaryDisplay.shouldWaitForSystemDecorWindowsOnBoot());
463
464 // Verify waiting for non-drawn windows on display with system decorations.
465 reset(secondaryDisplay);
466 doReturn(true).when(secondaryDisplay).supportsSystemDecorations();
467 assertTrue(secondaryDisplay.shouldWaitForSystemDecorWindowsOnBoot());
468
469 // Verify not waiting for drawn windows on display with system decorations.
Lais Andrade57283fb2020-04-21 18:58:15 +0000470 makeWindowsDrawnState(windows, WindowStateAnimator.HAS_DRAWN);
Riddle Hsub2297ad2019-07-26 23:37:25 -0600471 assertFalse(secondaryDisplay.shouldWaitForSystemDecorWindowsOnBoot());
472 }
473
Lais Andrade57283fb2020-04-21 18:58:15 +0000474 @Test
475 public void testShouldWaitForSystemDecorWindowsOnBoot_OnWindowReadyToShowAndDrawn() {
476 mWm.mSystemBooted = true;
477 final DisplayContent defaultDisplay = mWm.getDefaultDisplayContentLocked();
478 final WindowState[] windows = createNotDrawnWindowsOn(defaultDisplay,
479 TYPE_WALLPAPER, TYPE_APPLICATION);
480
481 // Verify waiting for windows to be drawn.
482 makeWindowsDrawnState(windows, WindowStateAnimator.READY_TO_SHOW);
483 assertTrue(defaultDisplay.shouldWaitForSystemDecorWindowsOnBoot());
484
485 // Verify not waiting for drawn windows.
486 makeWindowsDrawnState(windows, WindowStateAnimator.HAS_DRAWN);
487 assertFalse(defaultDisplay.shouldWaitForSystemDecorWindowsOnBoot());
488 }
489
Riddle Hsub2297ad2019-07-26 23:37:25 -0600490 private WindowState[] createNotDrawnWindowsOn(DisplayContent displayContent, int... types) {
491 final WindowState[] windows = new WindowState[types.length];
492 for (int i = 0; i < types.length; i++) {
493 final int type = types[i];
494 windows[i] = createWindow(null /* parent */, type, displayContent, "window-" + type);
495 windows[i].mHasSurface = false;
496 }
497 return windows;
498 }
499
Lais Andrade57283fb2020-04-21 18:58:15 +0000500 private static void makeWindowsDrawnState(WindowState[] windows, int state) {
Riddle Hsub2297ad2019-07-26 23:37:25 -0600501 for (WindowState window : windows) {
502 window.mHasSurface = true;
Lais Andrade57283fb2020-04-21 18:58:15 +0000503 window.mWinAnimator.mDrawState = state;
Riddle Hsub2297ad2019-07-26 23:37:25 -0600504 }
505 }
506
Bryce Lee27cec322017-03-21 09:41:37 -0700507 /**
508 * This tests setting the maximum ui width on a display.
509 */
510 @Test
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700511 public void testMaxUiWidth() {
Riddle Hsu654a6f92018-07-13 22:59:36 +0800512 // Prevent base display metrics for test from being updated to the value of real display.
513 final DisplayContent displayContent = createDisplayNoUpdateDisplayInfo();
Bryce Lee27cec322017-03-21 09:41:37 -0700514 final int baseWidth = 1440;
515 final int baseHeight = 2560;
516 final int baseDensity = 300;
517
Riddle Hsu654a6f92018-07-13 22:59:36 +0800518 displayContent.updateBaseDisplayMetrics(baseWidth, baseHeight, baseDensity);
Bryce Lee27cec322017-03-21 09:41:37 -0700519
520 final int maxWidth = 300;
521 final int resultingHeight = (maxWidth * baseHeight) / baseWidth;
522 final int resultingDensity = (maxWidth * baseDensity) / baseWidth;
523
Riddle Hsu654a6f92018-07-13 22:59:36 +0800524 displayContent.setMaxUiWidth(maxWidth);
525 verifySizes(displayContent, maxWidth, resultingHeight, resultingDensity);
Bryce Lee27cec322017-03-21 09:41:37 -0700526
527 // Assert setting values again does not change;
Riddle Hsu654a6f92018-07-13 22:59:36 +0800528 displayContent.updateBaseDisplayMetrics(baseWidth, baseHeight, baseDensity);
529 verifySizes(displayContent, maxWidth, resultingHeight, resultingDensity);
Bryce Lee27cec322017-03-21 09:41:37 -0700530
531 final int smallerWidth = 200;
532 final int smallerHeight = 400;
533 final int smallerDensity = 100;
534
535 // Specify smaller dimension, verify that it is honored
Riddle Hsu654a6f92018-07-13 22:59:36 +0800536 displayContent.updateBaseDisplayMetrics(smallerWidth, smallerHeight, smallerDensity);
537 verifySizes(displayContent, smallerWidth, smallerHeight, smallerDensity);
Bryce Lee27cec322017-03-21 09:41:37 -0700538
539 // Verify that setting the max width to a greater value than the base width has no effect
Riddle Hsu654a6f92018-07-13 22:59:36 +0800540 displayContent.setMaxUiWidth(maxWidth);
541 verifySizes(displayContent, smallerWidth, smallerHeight, smallerDensity);
Bryce Lee27cec322017-03-21 09:41:37 -0700542 }
543
Andrii Kulian92c9a942017-10-10 00:41:41 -0700544 @Test
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700545 public void testDisplayCutout_rot0() {
Riddle Hsu73f53572019-09-23 23:13:01 +0800546 final DisplayContent dc = createNewDisplay();
547 dc.mInitialDisplayWidth = 200;
548 dc.mInitialDisplayHeight = 400;
549 final Rect r = new Rect(80, 0, 120, 10);
550 final DisplayCutout cutout = new WmDisplayCutout(
551 fromBoundingRect(r.left, r.top, r.right, r.bottom, BOUNDS_POSITION_TOP), null)
552 .computeSafeInsets(200, 400).getDisplayCutout();
Adrian Roos1cf585052018-01-03 18:43:27 +0100553
Riddle Hsu73f53572019-09-23 23:13:01 +0800554 dc.mInitialDisplayCutout = cutout;
555 dc.getDisplayRotation().setRotation(Surface.ROTATION_0);
556 dc.computeScreenConfiguration(new Configuration()); // recomputes dc.mDisplayInfo.
Adrian Roos1cf585052018-01-03 18:43:27 +0100557
Riddle Hsu73f53572019-09-23 23:13:01 +0800558 assertEquals(cutout, dc.getDisplayInfo().displayCutout);
Adrian Roos1cf585052018-01-03 18:43:27 +0100559 }
560
561 @Test
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700562 public void testDisplayCutout_rot90() {
Riddle Hsu73f53572019-09-23 23:13:01 +0800563 // Prevent mInitialDisplayCutout from being updated from real display (e.g. null
564 // if the device has no cutout).
565 final DisplayContent dc = createDisplayNoUpdateDisplayInfo();
Garfield Tan7cb30142019-12-20 16:43:06 -0800566 // This test assumes it's a top cutout on a portrait display, so if it happens to be a
567 // landscape display let's rotate it.
568 if (dc.mInitialDisplayHeight < dc.mInitialDisplayWidth) {
569 int tmp = dc.mInitialDisplayHeight;
570 dc.mInitialDisplayHeight = dc.mInitialDisplayWidth;
571 dc.mInitialDisplayWidth = tmp;
572 }
Riddle Hsu73f53572019-09-23 23:13:01 +0800573 // Rotation may use real display info to compute bound, so here also uses the
574 // same width and height.
575 final int displayWidth = dc.mInitialDisplayWidth;
576 final int displayHeight = dc.mInitialDisplayHeight;
577 final int cutoutWidth = 40;
578 final int cutoutHeight = 10;
579 final int left = (displayWidth - cutoutWidth) / 2;
580 final int top = 0;
581 final int right = (displayWidth + cutoutWidth) / 2;
582 final int bottom = cutoutHeight;
Riddle Hsu654a6f92018-07-13 22:59:36 +0800583
Riddle Hsu73f53572019-09-23 23:13:01 +0800584 final Rect r1 = new Rect(left, top, right, bottom);
585 final DisplayCutout cutout = new WmDisplayCutout(
586 fromBoundingRect(r1.left, r1.top, r1.right, r1.bottom, BOUNDS_POSITION_TOP), null)
587 .computeSafeInsets(displayWidth, displayHeight).getDisplayCutout();
Adrian Roos1cf585052018-01-03 18:43:27 +0100588
Riddle Hsu73f53572019-09-23 23:13:01 +0800589 dc.mInitialDisplayCutout = cutout;
590 dc.getDisplayRotation().setRotation(Surface.ROTATION_90);
591 dc.computeScreenConfiguration(new Configuration()); // recomputes dc.mDisplayInfo.
Adrian Roos1cf585052018-01-03 18:43:27 +0100592
Riddle Hsu73f53572019-09-23 23:13:01 +0800593 // ----o---------- -------------
594 // | | | | |
595 // | ------o | o---
596 // | | | |
597 // | | -> | |
598 // | | ---o
599 // | | |
600 // | | -------------
601 final Rect r = new Rect(top, left, bottom, right);
602 assertEquals(new WmDisplayCutout(
603 fromBoundingRect(r.left, r.top, r.right, r.bottom, BOUNDS_POSITION_LEFT), null)
604 .computeSafeInsets(displayHeight, displayWidth).getDisplayCutout(),
605 dc.getDisplayInfo().displayCutout);
Adrian Roos1cf585052018-01-03 18:43:27 +0100606 }
607
608 @Test
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700609 public void testLayoutSeq_assignedDuringLayout() {
Riddle Hsu73f53572019-09-23 23:13:01 +0800610 final DisplayContent dc = createNewDisplay();
611 final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, dc, "w");
Adrian Roos5251b1d2018-03-23 18:57:43 +0100612
Riddle Hsu12c05452020-01-09 00:39:52 +0800613 performLayout(dc);
Adrian Roos5251b1d2018-03-23 18:57:43 +0100614
Riddle Hsu73f53572019-09-23 23:13:01 +0800615 assertThat(win.mLayoutSeq, is(dc.mLayoutSeq));
Adrian Roos5251b1d2018-03-23 18:57:43 +0100616 }
617
618 @Test
Andrii Kulian92c9a942017-10-10 00:41:41 -0700619 @SuppressLint("InlinedApi")
620 public void testOrientationDefinedByKeyguard() {
621 final DisplayContent dc = createNewDisplay();
Garfield Tan90b04282018-12-11 14:04:42 -0800622
623 // When display content is created its configuration is not yet initialized, which could
624 // cause unnecessary configuration propagation, so initialize it here.
625 final Configuration config = new Configuration();
626 dc.computeScreenConfiguration(config);
627 dc.onRequestedOverrideConfigurationChanged(config);
628
Andrii Kulian92c9a942017-10-10 00:41:41 -0700629 // Create a window that requests landscape orientation. It will define device orientation
630 // by default.
631 final WindowState window = createWindow(null /* parent */, TYPE_BASE_APPLICATION, dc, "w");
Garfield Tane8d84ab2019-10-11 09:49:40 -0700632 window.mActivityRecord.setOrientation(SCREEN_ORIENTATION_LANDSCAPE);
Andrii Kulian92c9a942017-10-10 00:41:41 -0700633
wilsonshihe8321942019-10-18 18:39:46 +0800634 final WindowState keyguard = createWindow(null, TYPE_NOTIFICATION_SHADE , dc, "keyguard");
Andrii Kulian92c9a942017-10-10 00:41:41 -0700635 keyguard.mHasSurface = true;
636 keyguard.mAttrs.screenOrientation = SCREEN_ORIENTATION_UNSPECIFIED;
637
638 assertEquals("Screen orientation must be defined by the app window by default",
639 SCREEN_ORIENTATION_LANDSCAPE, dc.getOrientation());
640
641 keyguard.mAttrs.screenOrientation = SCREEN_ORIENTATION_PORTRAIT;
642 assertEquals("Visible keyguard must influence device orientation",
643 SCREEN_ORIENTATION_PORTRAIT, dc.getOrientation());
644
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700645 mWm.setKeyguardGoingAway(true);
Andrii Kulian92c9a942017-10-10 00:41:41 -0700646 assertEquals("Keyguard that is going away must not influence device orientation",
647 SCREEN_ORIENTATION_LANDSCAPE, dc.getOrientation());
648 }
649
Andrii Kulianf0379de2018-03-14 16:24:07 -0700650 @Test
Tiger Huang86e6d072019-05-02 20:23:47 +0800651 public void testOrientationForAspectRatio() {
652 final DisplayContent dc = createNewDisplay();
653
654 // When display content is created its configuration is not yet initialized, which could
655 // cause unnecessary configuration propagation, so initialize it here.
656 final Configuration config = new Configuration();
657 dc.computeScreenConfiguration(config);
658 dc.onRequestedOverrideConfigurationChanged(config);
659
660 // Create a window that requests a fixed orientation. It will define device orientation
661 // by default.
662 final WindowState window = createWindow(null /* parent */, TYPE_APPLICATION_OVERLAY, dc,
663 "window");
664 window.mHasSurface = true;
665 window.mAttrs.screenOrientation = SCREEN_ORIENTATION_LANDSCAPE;
666
667 // --------------------------------
668 // Test non-close-to-square display
669 // --------------------------------
670 dc.mBaseDisplayWidth = 1000;
671 dc.mBaseDisplayHeight = (int) (dc.mBaseDisplayWidth * dc.mCloseToSquareMaxAspectRatio * 2f);
672 dc.configureDisplayPolicy();
673
674 assertEquals("Screen orientation must be defined by the window by default.",
675 window.mAttrs.screenOrientation, dc.getOrientation());
676
677 // ----------------------------
678 // Test close-to-square display
679 // ----------------------------
680 dc.mBaseDisplayHeight = dc.mBaseDisplayWidth;
681 dc.configureDisplayPolicy();
682
683 assertEquals("Screen orientation must be SCREEN_ORIENTATION_USER.",
684 SCREEN_ORIENTATION_USER, dc.getOrientation());
685 }
686
687 @Test
Andrii Kulianf0379de2018-03-14 16:24:07 -0700688 public void testDisableDisplayInfoOverrideFromWindowManager() {
689 final DisplayContent dc = createNewDisplay();
690
691 assertTrue(dc.mShouldOverrideDisplayConfiguration);
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700692 mWm.dontOverrideDisplayInfo(dc.getDisplayId());
Andrii Kulianf0379de2018-03-14 16:24:07 -0700693
694 assertFalse(dc.mShouldOverrideDisplayConfiguration);
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700695 verify(mWm.mDisplayManagerInternal, times(1))
Andrii Kulianf0379de2018-03-14 16:24:07 -0700696 .setDisplayInfoOverrideFromWindowManager(dc.getDisplayId(), null);
697 }
698
Riddle Hsua4d6fa22018-08-11 00:50:39 +0800699 @Test
Riddle Hsu85bd04b2018-11-17 00:34:36 +0800700 public void testClearLastFocusWhenReparentingFocusedWindow() {
701 final DisplayContent defaultDisplay = mWm.getDefaultDisplayContentLocked();
702 final WindowState window = createWindow(null /* parent */, TYPE_BASE_APPLICATION,
703 defaultDisplay, "window");
704 defaultDisplay.mLastFocus = window;
705 mDisplayContent.mCurrentFocus = window;
706 mDisplayContent.reParentWindowToken(window.mToken);
707
708 assertNull(defaultDisplay.mLastFocus);
709 }
710
711 @Test
Riddle Hsua4d6fa22018-08-11 00:50:39 +0800712 public void testGetPreferredOptionsPanelGravityFromDifferentDisplays() {
713 final DisplayContent portraitDisplay = createNewDisplay();
714 portraitDisplay.mInitialDisplayHeight = 2000;
715 portraitDisplay.mInitialDisplayWidth = 1000;
716
Riddle Hsuccf09402019-08-13 00:33:06 +0800717 portraitDisplay.getDisplayRotation().setRotation(Surface.ROTATION_0);
Riddle Hsua4d6fa22018-08-11 00:50:39 +0800718 assertFalse(isOptionsPanelAtRight(portraitDisplay.getDisplayId()));
Evan Rosky69cace42019-09-20 16:28:13 -0700719 portraitDisplay.getDisplayRotation().setRotation(ROTATION_90);
Riddle Hsua4d6fa22018-08-11 00:50:39 +0800720 assertTrue(isOptionsPanelAtRight(portraitDisplay.getDisplayId()));
721
722 final DisplayContent landscapeDisplay = createNewDisplay();
723 landscapeDisplay.mInitialDisplayHeight = 1000;
724 landscapeDisplay.mInitialDisplayWidth = 2000;
725
Riddle Hsuccf09402019-08-13 00:33:06 +0800726 landscapeDisplay.getDisplayRotation().setRotation(Surface.ROTATION_0);
Riddle Hsua4d6fa22018-08-11 00:50:39 +0800727 assertTrue(isOptionsPanelAtRight(landscapeDisplay.getDisplayId()));
Evan Rosky69cace42019-09-20 16:28:13 -0700728 landscapeDisplay.getDisplayRotation().setRotation(ROTATION_90);
Riddle Hsua4d6fa22018-08-11 00:50:39 +0800729 assertFalse(isOptionsPanelAtRight(landscapeDisplay.getDisplayId()));
730 }
731
lumarkff0ab692018-11-05 20:32:30 +0800732 @Test
733 public void testInputMethodTargetUpdateWhenSwitchingOnDisplays() {
734 final DisplayContent newDisplay = createNewDisplay();
735
736 final WindowState appWin = createWindow(null, TYPE_APPLICATION, mDisplayContent, "appWin");
737 final WindowState appWin1 = createWindow(null, TYPE_APPLICATION, newDisplay, "appWin1");
738 appWin.setHasSurface(true);
739 appWin1.setHasSurface(true);
740
741 // Set current input method window on default display, make sure the input method target
742 // is appWin & null on the other display.
743 mDisplayContent.setInputMethodWindowLocked(mImeWindow);
744 newDisplay.setInputMethodWindowLocked(null);
Wale Ogunwale3198da42019-10-10 14:45:03 +0200745 assertEquals("appWin should be IME target window",
746 appWin, mDisplayContent.mInputMethodTarget);
lumarkff0ab692018-11-05 20:32:30 +0800747 assertNull("newDisplay Ime target: ", newDisplay.mInputMethodTarget);
748
749 // Switch input method window on new display & make sure the input method target also
750 // switched as expected.
751 newDisplay.setInputMethodWindowLocked(mImeWindow);
752 mDisplayContent.setInputMethodWindowLocked(null);
Wale Ogunwale3198da42019-10-10 14:45:03 +0200753 assertEquals("appWin1 should be IME target window", appWin1, newDisplay.mInputMethodTarget);
lumarkff0ab692018-11-05 20:32:30 +0800754 assertNull("default display Ime target: ", mDisplayContent.mInputMethodTarget);
755 }
756
Garfield Tan90b04282018-12-11 14:04:42 -0800757 @Test
Garfield Tan98eead32019-11-18 13:24:53 -0800758 public void testAllowsTopmostFullscreenOrientation() {
759 final DisplayContent dc = createNewDisplay();
760 dc.getDisplayRotation().setFixedToUserRotation(
Garfield Tana3f19032019-11-19 18:04:50 -0800761 IWindowManager.FIXED_TO_USER_ROTATION_DISABLED);
Garfield Tan98eead32019-11-18 13:24:53 -0800762
763 final ActivityStack stack =
Louis Chang149d5c82019-12-30 09:47:39 +0800764 new ActivityTestsBase.StackBuilder(mWm.mAtmService.mRootWindowContainer)
Louis Chang2453d062019-11-19 22:30:48 +0800765 .setDisplay(dc)
Garfield Tan98eead32019-11-18 13:24:53 -0800766 .build();
767 doReturn(true).when(stack).isVisible();
768
769 final ActivityStack freeformStack =
Louis Chang149d5c82019-12-30 09:47:39 +0800770 new ActivityTestsBase.StackBuilder(mWm.mAtmService.mRootWindowContainer)
Louis Chang2453d062019-11-19 22:30:48 +0800771 .setDisplay(dc)
Garfield Tan98eead32019-11-18 13:24:53 -0800772 .setWindowingMode(WINDOWING_MODE_FREEFORM)
773 .build();
774 doReturn(true).when(freeformStack).isVisible();
775 freeformStack.getTopChild().setBounds(100, 100, 300, 400);
776
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -0700777 assertTrue(dc.getDefaultTaskDisplayArea().isStackVisible(WINDOWING_MODE_FREEFORM));
Garfield Tan98eead32019-11-18 13:24:53 -0800778
779 freeformStack.getTopNonFinishingActivity().setOrientation(SCREEN_ORIENTATION_LANDSCAPE);
780 stack.getTopNonFinishingActivity().setOrientation(SCREEN_ORIENTATION_PORTRAIT);
781 assertEquals(SCREEN_ORIENTATION_PORTRAIT, dc.getOrientation());
782
783 stack.getTopNonFinishingActivity().setOrientation(SCREEN_ORIENTATION_LANDSCAPE);
784 freeformStack.getTopNonFinishingActivity().setOrientation(SCREEN_ORIENTATION_PORTRAIT);
785 assertEquals(SCREEN_ORIENTATION_LANDSCAPE, dc.getOrientation());
786 }
787
788 @Test
Garfield Tan90b04282018-12-11 14:04:42 -0800789 public void testOnDescendantOrientationRequestChanged() {
Garfield Tan49dae102019-02-04 09:51:59 -0800790 final DisplayContent dc = createNewDisplay();
Wale Ogunwale8a1860a2019-06-05 08:57:19 -0700791 dc.getDisplayRotation().setFixedToUserRotation(
Garfield Tana3f19032019-11-19 18:04:50 -0800792 IWindowManager.FIXED_TO_USER_ROTATION_DISABLED);
Riddle Hsud4957432020-04-24 22:06:29 +0800793 final int newOrientation = getRotatedOrientation(dc);
Garfield Tan90b04282018-12-11 14:04:42 -0800794
Wale Ogunwale8a1860a2019-06-05 08:57:19 -0700795 final ActivityStack stack =
Louis Chang149d5c82019-12-30 09:47:39 +0800796 new ActivityTestsBase.StackBuilder(mWm.mAtmService.mRootWindowContainer)
Louis Chang2453d062019-11-19 22:30:48 +0800797 .setDisplay(dc).build();
Wale Ogunwale85fb19a2019-12-05 10:41:05 +0900798 final ActivityRecord activity = stack.getTopMostTask().getTopNonFinishingActivity();
Garfield Tan90b04282018-12-11 14:04:42 -0800799
Wale Ogunwale8a1860a2019-06-05 08:57:19 -0700800 activity.setRequestedOrientation(newOrientation);
Garfield Tan90b04282018-12-11 14:04:42 -0800801
Wale Ogunwale8a1860a2019-06-05 08:57:19 -0700802 final int expectedOrientation = newOrientation == SCREEN_ORIENTATION_PORTRAIT
803 ? Configuration.ORIENTATION_PORTRAIT
804 : Configuration.ORIENTATION_LANDSCAPE;
Evan Rosky01775072019-09-11 17:28:07 -0700805 assertEquals(expectedOrientation, dc.getConfiguration().orientation);
Garfield Tan90b04282018-12-11 14:04:42 -0800806 }
807
808 @Test
809 public void testOnDescendantOrientationRequestChanged_FrozenToUserRotation() {
Garfield Tan49dae102019-02-04 09:51:59 -0800810 final DisplayContent dc = createNewDisplay();
Garfield Tan7fbca052019-02-19 10:45:35 -0800811 dc.getDisplayRotation().setFixedToUserRotation(
Garfield Tana3f19032019-11-19 18:04:50 -0800812 IWindowManager.FIXED_TO_USER_ROTATION_ENABLED);
Riddle Hsud4957432020-04-24 22:06:29 +0800813 final int newOrientation = getRotatedOrientation(dc);
Garfield Tan90b04282018-12-11 14:04:42 -0800814
Wale Ogunwale8a1860a2019-06-05 08:57:19 -0700815 final ActivityStack stack =
Louis Chang149d5c82019-12-30 09:47:39 +0800816 new ActivityTestsBase.StackBuilder(mWm.mAtmService.mRootWindowContainer)
Louis Chang2453d062019-11-19 22:30:48 +0800817 .setDisplay(dc).build();
Wale Ogunwale85fb19a2019-12-05 10:41:05 +0900818 final ActivityRecord activity = stack.getTopMostTask().getTopNonFinishingActivity();
Garfield Tan90b04282018-12-11 14:04:42 -0800819
Wale Ogunwale8a1860a2019-06-05 08:57:19 -0700820 activity.setRequestedOrientation(newOrientation);
Garfield Tan90b04282018-12-11 14:04:42 -0800821
Louis Chang677921f2019-12-06 16:44:24 +0800822 verify(dc, never()).updateDisplayOverrideConfigurationLocked(any(), eq(activity),
823 anyBoolean(), same(null));
Wale Ogunwale8a1860a2019-06-05 08:57:19 -0700824 assertEquals(dc.getDisplayRotation().getUserRotation(), dc.getRotation());
Garfield Tan90b04282018-12-11 14:04:42 -0800825 }
826
Tarandeep Singha6f35612019-01-11 19:50:46 -0800827 @Test
828 public void testComputeImeParent_app() throws Exception {
Jorim Jaggicc57cb72020-04-09 14:54:13 +0200829 final DisplayContent dc = createNewDisplay();
830 dc.mInputMethodTarget = createWindow(null, TYPE_BASE_APPLICATION, "app");
831 assertEquals(dc.mInputMethodTarget.mActivityRecord.getSurfaceControl(),
832 dc.computeImeParent());
Tarandeep Singha6f35612019-01-11 19:50:46 -0800833 }
834
835 @Test
836 public void testComputeImeParent_app_notFullscreen() throws Exception {
Jorim Jaggicc57cb72020-04-09 14:54:13 +0200837 final DisplayContent dc = createNewDisplay();
838 dc.mInputMethodTarget = createWindow(null, TYPE_STATUS_BAR, "app");
839 dc.mInputMethodTarget.setWindowingMode(
840 WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
841 assertEquals(dc.getImeContainer().getParentSurfaceControl(), dc.computeImeParent());
Tarandeep Singha6f35612019-01-11 19:50:46 -0800842 }
843
844 @Test
Riddle Hsu6d6f67c2019-03-14 16:54:26 +0800845 public void testComputeImeParent_app_notMatchParentBounds() {
Garfield Tane8d84ab2019-10-11 09:49:40 -0700846 spyOn(mAppWindow.mActivityRecord);
847 doReturn(false).when(mAppWindow.mActivityRecord).matchParentBounds();
Riddle Hsu6d6f67c2019-03-14 16:54:26 +0800848 mDisplayContent.mInputMethodTarget = mAppWindow;
849 // The surface parent of IME should be the display instead of app window.
Adrian Roos329cbd02020-04-14 15:42:41 +0200850 assertEquals(mDisplayContent.getImeContainer().getParentSurfaceControl(),
851 mDisplayContent.computeImeParent());
Riddle Hsu6d6f67c2019-03-14 16:54:26 +0800852 }
853
854 @Test
Tarandeep Singha6f35612019-01-11 19:50:46 -0800855 public void testComputeImeParent_noApp() throws Exception {
Jorim Jaggicc57cb72020-04-09 14:54:13 +0200856 final DisplayContent dc = createNewDisplay();
857 dc.mInputMethodTarget = createWindow(null, TYPE_STATUS_BAR, "statusBar");
858 assertEquals(dc.getImeContainer().getParentSurfaceControl(), dc.computeImeParent());
859 }
860
861 @Test
862 public void testComputeImeControlTarget() throws Exception {
863 final DisplayContent dc = createNewDisplay();
864 dc.setRemoteInsetsController(createDisplayWindowInsetsController());
865 dc.mInputMethodInputTarget = createWindow(null, TYPE_BASE_APPLICATION, "app");
866 dc.mInputMethodTarget = dc.mInputMethodInputTarget;
867 assertEquals(dc.mInputMethodInputTarget, dc.computeImeControlTarget());
868 }
869
870 @Test
871 public void testComputeImeControlTarget_splitscreen() throws Exception {
872 final DisplayContent dc = createNewDisplay();
873 dc.mInputMethodInputTarget = createWindow(null, TYPE_BASE_APPLICATION, "app");
874 dc.mInputMethodInputTarget.setWindowingMode(
875 WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
876 dc.mInputMethodTarget = dc.mInputMethodInputTarget;
877 dc.setRemoteInsetsController(createDisplayWindowInsetsController());
878 assertNotEquals(dc.mInputMethodInputTarget, dc.computeImeControlTarget());
879 }
880
881 @Test
882 public void testComputeImeControlTarget_notMatchParentBounds() throws Exception {
883 spyOn(mAppWindow.mActivityRecord);
884 doReturn(false).when(mAppWindow.mActivityRecord).matchParentBounds();
885 mDisplayContent.mInputMethodInputTarget = mAppWindow;
886 mDisplayContent.mInputMethodTarget = mDisplayContent.mInputMethodInputTarget;
887 mDisplayContent.setRemoteInsetsController(createDisplayWindowInsetsController());
888 assertEquals(mAppWindow, mDisplayContent.computeImeControlTarget());
889 }
890
891 private IDisplayWindowInsetsController createDisplayWindowInsetsController() {
892 return new IDisplayWindowInsetsController.Stub() {
893
894 @Override
895 public void insetsChanged(InsetsState insetsState) throws RemoteException {
896 }
897
898 @Override
899 public void insetsControlChanged(InsetsState insetsState,
900 InsetsSourceControl[] insetsSourceControls) throws RemoteException {
901 }
902
903 @Override
904 public void showInsets(int i, boolean b) throws RemoteException {
905 }
906
907 @Override
908 public void hideInsets(int i, boolean b) throws RemoteException {
909 }
910 };
Tarandeep Singha6f35612019-01-11 19:50:46 -0800911 }
912
Susi Kharraz-Post9893b8c2019-02-12 14:21:29 -0500913 @Test
Adrian Roos4ffc8972019-02-07 20:45:11 +0100914 public void testUpdateSystemGestureExclusion() throws Exception {
915 final DisplayContent dc = createNewDisplay();
916 final WindowState win = createWindow(null, TYPE_BASE_APPLICATION, dc, "win");
917 win.getAttrs().flags |= FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR;
918 win.setSystemGestureExclusion(Collections.singletonList(new Rect(10, 20, 30, 40)));
919
Riddle Hsu12c05452020-01-09 00:39:52 +0800920 performLayout(dc);
Adrian Roos4ffc8972019-02-07 20:45:11 +0100921
922 win.setHasSurface(true);
923 dc.updateSystemGestureExclusion();
924
Riddle Hsu73f53572019-09-23 23:13:01 +0800925 final boolean[] invoked = { false };
Adrian Roos4ffc8972019-02-07 20:45:11 +0100926 final ISystemGestureExclusionListener.Stub verifier =
927 new ISystemGestureExclusionListener.Stub() {
928 @Override
Adrian Roos5f2c9a12019-07-03 18:31:46 +0200929 public void onSystemGestureExclusionChanged(int displayId, Region actual,
930 Region unrestricted) {
Adrian Roos4ffc8972019-02-07 20:45:11 +0100931 Region expected = Region.obtain();
932 expected.set(10, 20, 30, 40);
933 assertEquals(expected, actual);
Riddle Hsu73f53572019-09-23 23:13:01 +0800934 invoked[0] = true;
Adrian Roos4ffc8972019-02-07 20:45:11 +0100935 }
936 };
937 try {
938 dc.registerSystemGestureExclusionListener(verifier);
939 } finally {
940 dc.unregisterSystemGestureExclusionListener(verifier);
941 }
Riddle Hsu73f53572019-09-23 23:13:01 +0800942 assertTrue("SystemGestureExclusionListener was not invoked", invoked[0]);
Adrian Roos4ffc8972019-02-07 20:45:11 +0100943 }
944
945 @Test
946 public void testCalculateSystemGestureExclusion() throws Exception {
947 final DisplayContent dc = createNewDisplay();
948 final WindowState win = createWindow(null, TYPE_BASE_APPLICATION, dc, "win");
949 win.getAttrs().flags |= FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR;
950 win.setSystemGestureExclusion(Collections.singletonList(new Rect(10, 20, 30, 40)));
951
952 final WindowState win2 = createWindow(null, TYPE_APPLICATION, dc, "win2");
953 win2.getAttrs().flags |= FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR;
954 win2.setSystemGestureExclusion(Collections.singletonList(new Rect(20, 30, 40, 50)));
955
Riddle Hsu12c05452020-01-09 00:39:52 +0800956 performLayout(dc);
Adrian Roos4ffc8972019-02-07 20:45:11 +0100957
958 win.setHasSurface(true);
959 win2.setHasSurface(true);
960
961 final Region expected = Region.obtain();
962 expected.set(20, 30, 40, 50);
Adrian Roos5f2c9a12019-07-03 18:31:46 +0200963 assertEquals(expected, calculateSystemGestureExclusion(dc));
964 }
965
966 private Region calculateSystemGestureExclusion(DisplayContent dc) {
967 Region out = Region.obtain();
968 Region unrestricted = Region.obtain();
969 dc.calculateSystemGestureExclusion(out, unrestricted);
970 return out;
Adrian Roos4ffc8972019-02-07 20:45:11 +0100971 }
972
973 @Test
Adrian Roosb1063792019-06-28 12:10:51 +0200974 public void testCalculateSystemGestureExclusion_modal() throws Exception {
975 final DisplayContent dc = createNewDisplay();
976 final WindowState win = createWindow(null, TYPE_BASE_APPLICATION, dc, "base");
977 win.getAttrs().flags |= FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR;
978 win.setSystemGestureExclusion(Collections.singletonList(new Rect(0, 0, 1000, 1000)));
979
980 final WindowState win2 = createWindow(null, TYPE_APPLICATION, dc, "modal");
981 win2.getAttrs().flags |= FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR;
982 win2.getAttrs().privateFlags |= PRIVATE_FLAG_NO_MOVE_ANIMATION;
983 win2.getAttrs().width = 10;
984 win2.getAttrs().height = 10;
985 win2.setSystemGestureExclusion(Collections.emptyList());
986
Riddle Hsu12c05452020-01-09 00:39:52 +0800987 performLayout(dc);
Adrian Roosb1063792019-06-28 12:10:51 +0200988
989 win.setHasSurface(true);
990 win2.setHasSurface(true);
991
992 final Region expected = Region.obtain();
Adrian Roos5f2c9a12019-07-03 18:31:46 +0200993 assertEquals(expected, calculateSystemGestureExclusion(dc));
Adrian Roosb1063792019-06-28 12:10:51 +0200994 }
995
996 @Test
Adrian Roos019a52b2019-07-02 16:47:44 +0200997 public void testCalculateSystemGestureExclusion_immersiveStickyLegacyWindow() throws Exception {
Adrian Roos1c2e9a12019-08-20 18:23:47 +0200998 mWm.mConstants.mSystemGestureExcludedByPreQStickyImmersive = true;
Adrian Roos019a52b2019-07-02 16:47:44 +0200999
Riddle Hsu73f53572019-09-23 23:13:01 +08001000 final DisplayContent dc = createNewDisplay();
1001 final WindowState win = createWindow(null, TYPE_BASE_APPLICATION, dc, "win");
1002 win.getAttrs().flags |= FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR;
1003 win.getAttrs().layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
1004 win.getAttrs().privateFlags |= PRIVATE_FLAG_NO_MOVE_ANIMATION;
1005 win.getAttrs().subtreeSystemUiVisibility = win.mSystemUiVisibility =
1006 SYSTEM_UI_FLAG_FULLSCREEN | SYSTEM_UI_FLAG_HIDE_NAVIGATION
1007 | SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
Garfield Tane8d84ab2019-10-11 09:49:40 -07001008 win.mActivityRecord.mTargetSdk = P;
Adrian Roos019a52b2019-07-02 16:47:44 +02001009
Riddle Hsu12c05452020-01-09 00:39:52 +08001010 performLayout(dc);
Adrian Roos019a52b2019-07-02 16:47:44 +02001011
Riddle Hsu73f53572019-09-23 23:13:01 +08001012 win.setHasSurface(true);
Adrian Roos019a52b2019-07-02 16:47:44 +02001013
Riddle Hsu73f53572019-09-23 23:13:01 +08001014 final Region expected = Region.obtain();
1015 expected.set(dc.getBounds());
1016 assertEquals(expected, calculateSystemGestureExclusion(dc));
Adrian Roos019a52b2019-07-02 16:47:44 +02001017
Riddle Hsu73f53572019-09-23 23:13:01 +08001018 win.setHasSurface(false);
Adrian Roos019a52b2019-07-02 16:47:44 +02001019 }
1020
1021 @Test
Riddle Hsu12c05452020-01-09 00:39:52 +08001022 public void testRequestResizeForEmptyFrames() {
1023 final WindowState win = mChildAppWindowAbove;
1024 makeWindowVisible(win, win.getParentWindow());
1025 win.setRequestedSize(mDisplayContent.mBaseDisplayWidth, 0 /* height */);
1026 win.mAttrs.width = win.mAttrs.height = WindowManager.LayoutParams.WRAP_CONTENT;
1027 win.mAttrs.gravity = Gravity.CENTER;
1028 performLayout(mDisplayContent);
1029
1030 // The frame is empty because the requested height is zero.
1031 assertTrue(win.getFrameLw().isEmpty());
1032 // The window should be scheduled to resize then the client may report a new non-empty size.
1033 win.updateResizingWindowIfNeeded();
1034 assertThat(mWm.mResizingWindows).contains(win);
1035 }
1036
1037 @Test
Susi Kharraz-Post9893b8c2019-02-12 14:21:29 -05001038 public void testOrientationChangeLogging() {
1039 MetricsLogger mockLogger = mock(MetricsLogger.class);
1040 Configuration oldConfig = new Configuration();
1041 oldConfig.orientation = Configuration.ORIENTATION_LANDSCAPE;
1042
1043 Configuration newConfig = new Configuration();
1044 newConfig.orientation = Configuration.ORIENTATION_PORTRAIT;
Riddle Hsu73f53572019-09-23 23:13:01 +08001045 final DisplayContent displayContent = createNewDisplay();
Susi Kharraz-Post9893b8c2019-02-12 14:21:29 -05001046 Mockito.doReturn(mockLogger).when(displayContent).getMetricsLogger();
1047 Mockito.doReturn(oldConfig).doReturn(newConfig).when(displayContent).getConfiguration();
Louis Chang2453d062019-11-19 22:30:48 +08001048 doNothing().when(displayContent).preOnConfigurationChanged();
Susi Kharraz-Post9893b8c2019-02-12 14:21:29 -05001049
1050 displayContent.onConfigurationChanged(newConfig);
1051
1052 ArgumentCaptor<LogMaker> logMakerCaptor = ArgumentCaptor.forClass(LogMaker.class);
1053 verify(mockLogger).write(logMakerCaptor.capture());
1054 assertThat(logMakerCaptor.getValue().getCategory(),
1055 is(MetricsProto.MetricsEvent.ACTION_PHONE_ORIENTATION_CHANGED));
1056 assertThat(logMakerCaptor.getValue().getSubtype(),
1057 is(Configuration.ORIENTATION_PORTRAIT));
1058 }
1059
Evan Rosky69cace42019-09-20 16:28:13 -07001060 @Test
Riddle Hsu6f548e92020-01-13 13:34:09 +08001061 public void testApplyTopFixedRotationTransform() {
1062 mWm.mIsFixedRotationTransformEnabled = true;
1063 final Configuration config90 = new Configuration();
Riddle Hsu9239d7c62020-02-20 01:35:56 +08001064 mDisplayContent.computeScreenConfiguration(config90, ROTATION_90);
Riddle Hsu6f548e92020-01-13 13:34:09 +08001065
1066 final Configuration config = new Configuration();
Riddle Hsu9239d7c62020-02-20 01:35:56 +08001067 mDisplayContent.getDisplayRotation().setRotation(ROTATION_0);
Riddle Hsu6f548e92020-01-13 13:34:09 +08001068 mDisplayContent.computeScreenConfiguration(config);
1069 mDisplayContent.onRequestedOverrideConfigurationChanged(config);
1070
1071 final ActivityRecord app = mAppWindow.mActivityRecord;
1072 mDisplayContent.prepareAppTransition(WindowManager.TRANSIT_ACTIVITY_OPEN,
1073 false /* alwaysKeepCurrent */);
1074 mDisplayContent.mOpeningApps.add(app);
Riddle Hsud4957432020-04-24 22:06:29 +08001075 final int newOrientation = getRotatedOrientation(mDisplayContent);
1076 app.setRequestedOrientation(newOrientation);
Riddle Hsu6f548e92020-01-13 13:34:09 +08001077
1078 assertTrue(app.isFixedRotationTransforming());
Riddle Hsu9239d7c62020-02-20 01:35:56 +08001079 assertTrue(mDisplayContent.getDisplayRotation().shouldRotateSeamlessly(
1080 ROTATION_0 /* oldRotation */, ROTATION_90 /* newRotation */,
1081 false /* forceUpdate */));
Riddle Hsuf41034c2020-03-19 13:10:46 +08001082
1083 final Rect outFrame = new Rect();
1084 final Rect outInsets = new Rect();
1085 final Rect outStableInsets = new Rect();
1086 final Rect outSurfaceInsets = new Rect();
1087 mAppWindow.getAnimationFrames(outFrame, outInsets, outStableInsets, outSurfaceInsets);
1088 // The animation frames should not be rotated because display hasn't rotated.
1089 assertEquals(mDisplayContent.getBounds(), outFrame);
1090
Riddle Hsu9239d7c62020-02-20 01:35:56 +08001091 // The display should keep current orientation and the rotated configuration should apply
1092 // to the activity.
Riddle Hsu6f548e92020-01-13 13:34:09 +08001093 assertEquals(config.orientation, mDisplayContent.getConfiguration().orientation);
1094 assertEquals(config90.orientation, app.getConfiguration().orientation);
Riddle Hsu9239d7c62020-02-20 01:35:56 +08001095 assertEquals(config90.windowConfiguration.getBounds(), app.getBounds());
Riddle Hsu6f548e92020-01-13 13:34:09 +08001096
Riddle Hsu3d0aa4f2020-04-09 17:58:50 +08001097 // Make wallaper laid out with the fixed rotation transform.
1098 final WindowToken wallpaperToken = mWallpaperWindow.mToken;
1099 wallpaperToken.linkFixedRotationTransform(app);
1100 mWallpaperWindow.mLayoutNeeded = true;
1101 performLayout(mDisplayContent);
1102
Riddle Hsu6da58ac2020-04-02 01:04:40 +08001103 // Force the negative offset to verify it can be updated.
1104 mWallpaperWindow.mWinAnimator.mXOffset = mWallpaperWindow.mWinAnimator.mYOffset = -1;
1105 assertTrue(mDisplayContent.mWallpaperController.updateWallpaperOffset(mWallpaperWindow,
1106 false /* sync */));
1107 assertThat(mWallpaperWindow.mWinAnimator.mXOffset).isGreaterThan(-1);
1108 assertThat(mWallpaperWindow.mWinAnimator.mYOffset).isGreaterThan(-1);
1109
Riddle Hsu3d0aa4f2020-04-09 17:58:50 +08001110 // The wallpaper need to animate with transformed position, so its surface position should
1111 // not be reset.
1112 final Transaction t = wallpaperToken.getPendingTransaction();
1113 spyOn(t);
1114 mWallpaperWindow.mToken.onAnimationLeashCreated(t, null /* leash */);
1115 verify(t, never()).setPosition(any(), eq(0), eq(0));
1116
Riddle Hsud4957432020-04-24 22:06:29 +08001117 // Launch another activity before the transition is finished.
1118 final ActivityRecord app2 = new ActivityTestsBase.StackBuilder(mWm.mRoot)
1119 .setDisplay(mDisplayContent).build().getTopMostActivity();
1120 mDisplayContent.prepareAppTransition(WindowManager.TRANSIT_ACTIVITY_OPEN,
1121 false /* alwaysKeepCurrent */);
1122 mDisplayContent.mOpeningApps.add(app2);
1123 app2.setRequestedOrientation(newOrientation);
1124
1125 // The activity should share the same transform state as the existing one.
1126 assertTrue(app.hasFixedRotationTransform(app2));
1127
1128 // The display should be rotated after the launch is finished.
Riddle Hsu6f548e92020-01-13 13:34:09 +08001129 mDisplayContent.mAppTransition.notifyAppTransitionFinishedLocked(app.token);
1130
Riddle Hsud4957432020-04-24 22:06:29 +08001131 // The fixed rotation should be cleared and the new rotation is applied to display.
Riddle Hsu6f548e92020-01-13 13:34:09 +08001132 assertFalse(app.hasFixedRotationTransform());
Riddle Hsud4957432020-04-24 22:06:29 +08001133 assertFalse(app2.hasFixedRotationTransform());
Riddle Hsu6f548e92020-01-13 13:34:09 +08001134 assertEquals(config90.orientation, mDisplayContent.getConfiguration().orientation);
1135 }
1136
1137 @Test
Evan Rosky69cace42019-09-20 16:28:13 -07001138 public void testRemoteRotation() {
1139 DisplayContent dc = createNewDisplay();
1140
1141 final DisplayRotation dr = dc.getDisplayRotation();
1142 Mockito.doCallRealMethod().when(dr).updateRotationUnchecked(anyBoolean());
1143 Mockito.doReturn(ROTATION_90).when(dr).rotationForOrientation(anyInt(), anyInt());
1144 final boolean[] continued = new boolean[1];
Louis Chang2453d062019-11-19 22:30:48 +08001145 // TODO(display-merge): Remove cast
Charles Chen770597c2020-05-18 19:58:23 +08001146 doAnswer(
Evan Rosky69cace42019-09-20 16:28:13 -07001147 invocation -> {
1148 continued[0] = true;
1149 return true;
Louis Chang677921f2019-12-06 16:44:24 +08001150 }).when(dc).updateDisplayOverrideConfigurationLocked();
Evan Rosky69cace42019-09-20 16:28:13 -07001151 final boolean[] called = new boolean[1];
1152 mWm.mDisplayRotationController =
1153 new IDisplayWindowRotationController.Stub() {
1154 @Override
1155 public void onRotateDisplay(int displayId, int fromRotation, int toRotation,
1156 IDisplayWindowRotationCallback callback) {
1157 called[0] = true;
1158
1159 try {
1160 callback.continueRotateDisplay(toRotation, null);
1161 } catch (RemoteException e) {
1162 assertTrue(false);
1163 }
1164 }
1165 };
1166
1167 // kill any existing rotation animation (vestigial from test setup).
1168 dc.setRotationAnimation(null);
1169
1170 mWm.updateRotation(true /* alwaysSendConfiguration */, false /* forceRelayout */);
1171 assertTrue(called[0]);
1172 waitUntilHandlersIdle();
1173 assertTrue(continued[0]);
1174 }
1175
Darryl L Johnson3388bd22019-12-19 17:38:41 -08001176 @Test
1177 public void testGetOrCreateRootHomeTask_defaultDisplay() {
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -07001178 TaskDisplayArea defaultTaskDisplayArea = mWm.mRoot.getDefaultTaskDisplayArea();
Darryl L Johnson3388bd22019-12-19 17:38:41 -08001179
1180 // Remove the current home stack if it exists so a new one can be created below.
Andrii Kulian86d676c2020-03-27 19:34:54 -07001181 ActivityStack homeTask = defaultTaskDisplayArea.getRootHomeTask();
Darryl L Johnson3388bd22019-12-19 17:38:41 -08001182 if (homeTask != null) {
Andrii Kulian86d676c2020-03-27 19:34:54 -07001183 defaultTaskDisplayArea.removeChild(homeTask);
Darryl L Johnson3388bd22019-12-19 17:38:41 -08001184 }
Andrii Kulian86d676c2020-03-27 19:34:54 -07001185 assertNull(defaultTaskDisplayArea.getRootHomeTask());
Darryl L Johnson3388bd22019-12-19 17:38:41 -08001186
Andrii Kulian86d676c2020-03-27 19:34:54 -07001187 assertNotNull(defaultTaskDisplayArea.getOrCreateRootHomeTask());
Darryl L Johnson3388bd22019-12-19 17:38:41 -08001188 }
1189
1190 @Test
1191 public void testGetOrCreateRootHomeTask_supportedSecondaryDisplay() {
1192 DisplayContent display = createNewDisplay();
1193 doReturn(true).when(display).supportsSystemDecorations();
1194 doReturn(false).when(display).isUntrustedVirtualDisplay();
1195
1196 // Remove the current home stack if it exists so a new one can be created below.
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -07001197 TaskDisplayArea taskDisplayArea = display.getDefaultTaskDisplayArea();
Andrii Kulian86d676c2020-03-27 19:34:54 -07001198 ActivityStack homeTask = taskDisplayArea.getRootHomeTask();
Darryl L Johnson3388bd22019-12-19 17:38:41 -08001199 if (homeTask != null) {
Andrii Kulian86d676c2020-03-27 19:34:54 -07001200 taskDisplayArea.removeChild(homeTask);
Darryl L Johnson3388bd22019-12-19 17:38:41 -08001201 }
Andrii Kulian86d676c2020-03-27 19:34:54 -07001202 assertNull(taskDisplayArea.getRootHomeTask());
Darryl L Johnson3388bd22019-12-19 17:38:41 -08001203
Andrii Kulian86d676c2020-03-27 19:34:54 -07001204 assertNotNull(taskDisplayArea.getOrCreateRootHomeTask());
Darryl L Johnson3388bd22019-12-19 17:38:41 -08001205 }
1206
1207 @Test
1208 public void testGetOrCreateRootHomeTask_unsupportedSystemDecorations() {
1209 DisplayContent display = createNewDisplay();
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -07001210 TaskDisplayArea taskDisplayArea = display.getDefaultTaskDisplayArea();
Darryl L Johnson3388bd22019-12-19 17:38:41 -08001211 doReturn(false).when(display).supportsSystemDecorations();
1212
Andrii Kulian86d676c2020-03-27 19:34:54 -07001213 assertNull(taskDisplayArea.getRootHomeTask());
1214 assertNull(taskDisplayArea.getOrCreateRootHomeTask());
Darryl L Johnson3388bd22019-12-19 17:38:41 -08001215 }
1216
1217 @Test
1218 public void testGetOrCreateRootHomeTask_untrustedVirtualDisplay() {
1219 DisplayContent display = createNewDisplay();
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -07001220 TaskDisplayArea taskDisplayArea = display.getDefaultTaskDisplayArea();
Darryl L Johnson3388bd22019-12-19 17:38:41 -08001221 doReturn(true).when(display).isUntrustedVirtualDisplay();
1222
Andrii Kulian86d676c2020-03-27 19:34:54 -07001223 assertNull(taskDisplayArea.getRootHomeTask());
1224 assertNull(taskDisplayArea.getOrCreateRootHomeTask());
Darryl L Johnson3388bd22019-12-19 17:38:41 -08001225 }
1226
Mark Renoufa9279292020-04-17 12:22:50 -04001227 @Test
1228 public void testFindScrollCaptureTargetWindow_behindWindow() {
1229 DisplayContent display = createNewDisplay();
1230 ActivityStack stack = createTaskStackOnDisplay(display);
1231 Task task = createTaskInStack(stack, 0 /* userId */);
1232 WindowState activityWindow = createAppWindow(task, TYPE_APPLICATION, "App Window");
1233 WindowState behindWindow = createWindow(null, TYPE_SCREENSHOT, display, "Screenshot");
1234
1235 WindowState result = display.findScrollCaptureTargetWindow(behindWindow,
1236 ActivityTaskManager.INVALID_TASK_ID);
1237 assertEquals(activityWindow, result);
1238 }
1239
1240 @Test
1241 public void testFindScrollCaptureTargetWindow_taskId() {
1242 DisplayContent display = createNewDisplay();
1243 ActivityStack stack = createTaskStackOnDisplay(display);
1244 Task task = createTaskInStack(stack, 0 /* userId */);
1245 WindowState window = createAppWindow(task, TYPE_APPLICATION, "App Window");
1246 WindowState behindWindow = createWindow(null, TYPE_SCREENSHOT, display, "Screenshot");
1247
1248 WindowState result = display.findScrollCaptureTargetWindow(null, task.mTaskId);
1249 assertEquals(window, result);
1250 }
1251
Charles Chen770597c2020-05-18 19:58:23 +08001252 @Test
1253 public void testEnsureActivitiesVisibleNotRecursive() {
1254 final TaskDisplayArea mockTda = mock(TaskDisplayArea.class);
1255 doReturn(mockTda).when(mDisplayContent).getTaskDisplayAreaAt(anyInt());
1256 final boolean[] called = { false };
1257 doAnswer(invocation -> {
1258 // The assertion will fail if DisplayArea#ensureActivitiesVisible is called twice.
1259 assertFalse(called[0]);
1260 called[0] = true;
1261 mDisplayContent.ensureActivitiesVisible(null, 0, false, false);
1262 return null;
1263 }).when(mockTda).ensureActivitiesVisible(any(), anyInt(), anyBoolean(), anyBoolean());
1264
1265 mDisplayContent.ensureActivitiesVisible(null, 0, false, false);
1266 }
1267
Riddle Hsua4d6fa22018-08-11 00:50:39 +08001268 private boolean isOptionsPanelAtRight(int displayId) {
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -07001269 return (mWm.getPreferredOptionsPanelGravity(displayId) & Gravity.RIGHT) == Gravity.RIGHT;
Riddle Hsua4d6fa22018-08-11 00:50:39 +08001270 }
1271
Bryce Lee27cec322017-03-21 09:41:37 -07001272 private static void verifySizes(DisplayContent displayContent, int expectedBaseWidth,
1273 int expectedBaseHeight, int expectedBaseDensity) {
1274 assertEquals(displayContent.mBaseDisplayWidth, expectedBaseWidth);
1275 assertEquals(displayContent.mBaseDisplayHeight, expectedBaseHeight);
1276 assertEquals(displayContent.mBaseDisplayDensity, expectedBaseDensity);
1277 }
1278
Tiger Huang1e5b10a2018-07-30 20:19:51 +08001279 private void updateFocusedWindow() {
Riddle Hsu73f53572019-09-23 23:13:01 +08001280 mWm.updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, false /* updateInputWindows */);
Tiger Huang1e5b10a2018-07-30 20:19:51 +08001281 }
1282
Riddle Hsu12c05452020-01-09 00:39:52 +08001283 private void performLayout(DisplayContent dc) {
1284 dc.setLayoutNeeded();
1285 dc.performLayout(true /* initial */, false /* updateImeWindows */);
1286 }
1287
Riddle Hsu654a6f92018-07-13 22:59:36 +08001288 /**
1289 * Create DisplayContent that does not update display base/initial values from device to keep
1290 * the values set by test.
1291 */
1292 private DisplayContent createDisplayNoUpdateDisplayInfo() {
Riddle Hsu73f53572019-09-23 23:13:01 +08001293 final DisplayContent displayContent = createNewDisplay();
Riddle Hsu654a6f92018-07-13 22:59:36 +08001294 doNothing().when(displayContent).updateDisplayInfo();
1295 return displayContent;
1296 }
1297
Adrian Roos0f9368c2018-04-08 10:59:08 -07001298 private void assertForAllWindowsOrder(List<WindowState> expectedWindowsBottomToTop) {
1299 final LinkedList<WindowState> actualWindows = new LinkedList<>();
Wale Ogunwale34247952017-02-19 11:57:53 -08001300
1301 // Test forward traversal.
Wale Ogunwale11cc5162017-04-25 20:29:13 -07001302 mDisplayContent.forAllWindows(actualWindows::addLast, false /* traverseTopToBottom */);
Adrian Roos0f9368c2018-04-08 10:59:08 -07001303 assertThat("bottomToTop", actualWindows, is(expectedWindowsBottomToTop));
1304
1305 actualWindows.clear();
Wale Ogunwale34247952017-02-19 11:57:53 -08001306
1307 // Test backward traversal.
Wale Ogunwale11cc5162017-04-25 20:29:13 -07001308 mDisplayContent.forAllWindows(actualWindows::addLast, true /* traverseTopToBottom */);
Adrian Roos0f9368c2018-04-08 10:59:08 -07001309 assertThat("topToBottom", actualWindows, is(reverseList(expectedWindowsBottomToTop)));
1310 }
1311
Riddle Hsud4957432020-04-24 22:06:29 +08001312 private static int getRotatedOrientation(DisplayContent dc) {
1313 return dc.getLastOrientation() == SCREEN_ORIENTATION_LANDSCAPE
1314 ? SCREEN_ORIENTATION_PORTRAIT
1315 : SCREEN_ORIENTATION_LANDSCAPE;
1316 }
1317
Adrian Roos0f9368c2018-04-08 10:59:08 -07001318 private static List<WindowState> reverseList(List<WindowState> list) {
1319 final ArrayList<WindowState> result = new ArrayList<>(list);
1320 Collections.reverse(result);
1321 return result;
Wale Ogunwale34247952017-02-19 11:57:53 -08001322 }
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -07001323
Arthur Hungbe5ce212018-09-13 18:41:56 +08001324 private void tapOnDisplay(final DisplayContent dc) {
1325 final DisplayMetrics dm = dc.getDisplayMetrics();
1326 final float x = dm.widthPixels / 2;
1327 final float y = dm.heightPixels / 2;
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -07001328 final long downTime = SystemClock.uptimeMillis();
1329 final long eventTime = SystemClock.uptimeMillis() + 100;
Arthur Hungbe5ce212018-09-13 18:41:56 +08001330 // sending ACTION_DOWN
1331 final MotionEvent downEvent = MotionEvent.obtain(
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -07001332 downTime,
Arthur Hungbe5ce212018-09-13 18:41:56 +08001333 downTime,
1334 MotionEvent.ACTION_DOWN,
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -07001335 x,
1336 y,
Arthur Hungbe5ce212018-09-13 18:41:56 +08001337 0 /*metaState*/);
1338 downEvent.setDisplayId(dc.getDisplayId());
1339 dc.mTapDetector.onPointerEvent(downEvent);
1340
1341 // sending ACTION_UP
1342 final MotionEvent upEvent = MotionEvent.obtain(
1343 downTime,
1344 eventTime,
1345 MotionEvent.ACTION_UP,
1346 x,
1347 y,
1348 0 /*metaState*/);
1349 upEvent.setDisplayId(dc.getDisplayId());
1350 dc.mTapDetector.onPointerEvent(upEvent);
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -07001351 }
Wale Ogunwaleb783fd82016-11-04 09:51:54 -07001352}