blob: ac87de33dac77c95f226dc10d30be479b07c3264 [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 Huang86e6d072019-05-02 20:23:47 +080022import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_USER;
Tiger Huang51c5a1d2018-12-11 20:24:51 +080023import static android.os.Build.VERSION_CODES.P;
24import static android.os.Build.VERSION_CODES.Q;
Wale Ogunwale34247952017-02-19 11:57:53 -080025import static android.view.Display.DEFAULT_DISPLAY;
Issei Suzuki43190bd2018-08-20 17:28:41 +020026import static android.view.DisplayCutout.BOUNDS_POSITION_LEFT;
27import static android.view.DisplayCutout.BOUNDS_POSITION_TOP;
Adrian Roos24264212018-02-19 16:26:15 +010028import static android.view.DisplayCutout.fromBoundingRect;
Evan Rosky69cace42019-09-20 16:28:13 -070029import static android.view.Surface.ROTATION_90;
Adrian Roos019a52b2019-07-02 16:47:44 +020030import static android.view.View.SYSTEM_UI_FLAG_FULLSCREEN;
31import static android.view.View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
32import static android.view.View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
Adrian Roos4ffc8972019-02-07 20:45:11 +010033import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR;
34import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
Adrian Roos019a52b2019-07-02 16:47:44 +020035import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
36import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION;
Wale Ogunwale34247952017-02-19 11:57:53 -080037import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
38import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
Tiger Huang86e6d072019-05-02 20:23:47 +080039import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
Wale Ogunwale34247952017-02-19 11:57:53 -080040import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
Andrii Kulian92c9a942017-10-10 00:41:41 -070041import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
Wale Ogunwale34247952017-02-19 11:57:53 -080042import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION;
Riddle Hsub2297ad2019-07-26 23:37:25 -060043import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
Brett Chabota26eda92018-07-23 13:08:30 -070044
Garfield Tan90b04282018-12-11 14:04:42 -080045import static com.android.dx.mockito.inline.extended.ExtendedMockito.any;
46import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyBoolean;
Tadashi G. Takaokabf0d57b2018-11-19 16:09:58 +090047import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
Riddle Hsu6d6f67c2019-03-14 16:54:26 +080048import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
Garfield Tan90b04282018-12-11 14:04:42 -080049import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
50import static com.android.dx.mockito.inline.extended.ExtendedMockito.never;
Riddle Hsub2297ad2019-07-26 23:37:25 -060051import static com.android.dx.mockito.inline.extended.ExtendedMockito.reset;
Garfield Tan90b04282018-12-11 14:04:42 -080052import static com.android.dx.mockito.inline.extended.ExtendedMockito.same;
Riddle Hsu6d6f67c2019-03-14 16:54:26 +080053import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
Tadashi G. Takaokabf0d57b2018-11-19 16:09:58 +090054import static com.android.dx.mockito.inline.extended.ExtendedMockito.times;
55import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
David Stevens46939562017-03-24 13:04:00 -070056import static com.android.server.wm.WindowContainer.POSITION_TOP;
Tiger Huang1e5b10a2018-07-30 20:19:51 +080057import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_NORMAL;
chaviwebcbc342018-02-07 13:19:00 -080058
Adrian Roos5251b1d2018-03-23 18:57:43 +010059import static org.hamcrest.Matchers.is;
Wale Ogunwale34247952017-02-19 11:57:53 -080060import static org.junit.Assert.assertEquals;
Andrii Kulianf0379de2018-03-14 16:24:07 -070061import static org.junit.Assert.assertFalse;
Arthur Hungbe5ce212018-09-13 18:41:56 +080062import static org.junit.Assert.assertNotNull;
lumarkff0ab692018-11-05 20:32:30 +080063import static org.junit.Assert.assertNull;
Adrian Roos5251b1d2018-03-23 18:57:43 +010064import static org.junit.Assert.assertThat;
Wale Ogunwale34247952017-02-19 11:57:53 -080065import static org.junit.Assert.assertTrue;
Evan Rosky69cace42019-09-20 16:28:13 -070066import static org.mockito.ArgumentMatchers.anyInt;
Tarandeep Singha6f35612019-01-11 19:50:46 -080067import static org.mockito.ArgumentMatchers.eq;
Wale Ogunwale34247952017-02-19 11:57:53 -080068
Andrii Kulian92c9a942017-10-10 00:41:41 -070069import android.annotation.SuppressLint;
Tarandeep Singha6f35612019-01-11 19:50:46 -080070import android.app.WindowConfiguration;
Andrii Kuliand68501e2017-01-10 22:57:27 -080071import android.content.res.Configuration;
Adrian Roos1cf585052018-01-03 18:43:27 +010072import android.graphics.Rect;
Adrian Roos4ffc8972019-02-07 20:45:11 +010073import android.graphics.Region;
Susi Kharraz-Post9893b8c2019-02-12 14:21:29 -050074import android.metrics.LogMaker;
Evan Rosky69cace42019-09-20 16:28:13 -070075import android.os.RemoteException;
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -070076import android.os.SystemClock;
Wale Ogunwaleb783fd82016-11-04 09:51:54 -070077import android.platform.test.annotations.Presubmit;
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -070078import android.util.DisplayMetrics;
Adrian Roos1cf585052018-01-03 18:43:27 +010079import android.view.DisplayCutout;
Riddle Hsua4d6fa22018-08-11 00:50:39 +080080import android.view.Gravity;
Evan Rosky69cace42019-09-20 16:28:13 -070081import android.view.IDisplayWindowRotationCallback;
82import android.view.IDisplayWindowRotationController;
Adrian Roos4ffc8972019-02-07 20:45:11 +010083import android.view.ISystemGestureExclusionListener;
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -070084import android.view.MotionEvent;
Adrian Roos1cf585052018-01-03 18:43:27 +010085import android.view.Surface;
Tarandeep Singha6f35612019-01-11 19:50:46 -080086import android.view.ViewRootImpl;
87import android.view.test.InsetsModeSession;
Wale Ogunwaleb783fd82016-11-04 09:51:54 -070088
Brett Chabota26eda92018-07-23 13:08:30 -070089import androidx.test.filters.SmallTest;
Brett Chabota26eda92018-07-23 13:08:30 -070090
Susi Kharraz-Post9893b8c2019-02-12 14:21:29 -050091import com.android.internal.logging.MetricsLogger;
92import com.android.internal.logging.nano.MetricsProto;
Adrian Roos6a4fa0e2018-03-05 19:50:16 +010093import com.android.server.wm.utils.WmDisplayCutout;
94
Brett Chabota26eda92018-07-23 13:08:30 -070095import org.junit.Test;
Riddle Hsu73f53572019-09-23 23:13:01 +080096import org.junit.runner.RunWith;
Garfield Tan90b04282018-12-11 14:04:42 -080097import org.mockito.ArgumentCaptor;
Susi Kharraz-Post9893b8c2019-02-12 14:21:29 -050098import org.mockito.Mockito;
Brett Chabota26eda92018-07-23 13:08:30 -070099
Adrian Roos0f9368c2018-04-08 10:59:08 -0700100import java.util.ArrayList;
Wale Ogunwale34247952017-02-19 11:57:53 -0800101import java.util.Arrays;
Adrian Roos0f9368c2018-04-08 10:59:08 -0700102import java.util.Collections;
Wale Ogunwale34247952017-02-19 11:57:53 -0800103import java.util.LinkedList;
104import java.util.List;
Wale Ogunwaleb783fd82016-11-04 09:51:54 -0700105
106/**
107 * Tests for the {@link DisplayContent} class.
108 *
109 * Build/Install/Run:
Yunfan Chen6dd9a622019-02-18 15:12:33 +0900110 * atest WmTests:DisplayContentTests
Wale Ogunwaleb783fd82016-11-04 09:51:54 -0700111 */
112@SmallTest
113@Presubmit
Riddle Hsu73f53572019-09-23 23:13:01 +0800114@RunWith(WindowTestRunner.class)
Wale Ogunwale44fbdf52016-11-16 10:18:45 -0800115public class DisplayContentTests extends WindowTestsBase {
Wale Ogunwaleb783fd82016-11-04 09:51:54 -0700116
117 @Test
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700118 public void testForAllWindows() {
Wale Ogunwale3c1170d2016-12-02 14:44:52 -0800119 final WindowState exitingAppWindow = createWindow(null, TYPE_BASE_APPLICATION,
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700120 mDisplayContent, "exiting app");
Garfield Tane8d84ab2019-10-11 09:49:40 -0700121 final ActivityRecord exitingApp = exitingAppWindow.mActivityRecord;
Yunfan Chen6dd9a622019-02-18 15:12:33 +0900122 // Wait until everything in animation handler get executed to prevent the exiting window
123 // from being removed during WindowSurfacePlacer Traversal.
124 waitUntilHandlersIdle();
125
Garfield Tane8d84ab2019-10-11 09:49:40 -0700126 exitingApp.mIsExiting = true;
Wale Ogunwale8577a052019-10-26 23:22:34 -0700127 exitingApp.getTask().getTaskStack().mExitingActivities.add(exitingApp);
Wale Ogunwaleb783fd82016-11-04 09:51:54 -0700128
Wale Ogunwale34247952017-02-19 11:57:53 -0800129 assertForAllWindowsOrder(Arrays.asList(
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700130 mWallpaperWindow,
Wale Ogunwale34247952017-02-19 11:57:53 -0800131 exitingAppWindow,
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700132 mChildAppWindowBelow,
133 mAppWindow,
134 mChildAppWindowAbove,
135 mDockedDividerWindow,
136 mStatusBarWindow,
137 mNavBarWindow,
138 mImeWindow,
139 mImeDialogWindow));
Wale Ogunwale3c1170d2016-12-02 14:44:52 -0800140 }
141
142 @Test
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700143 public void testForAllWindows_WithAppImeTarget() {
Wale Ogunwale3c1170d2016-12-02 14:44:52 -0800144 final WindowState imeAppTarget =
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700145 createWindow(null, TYPE_BASE_APPLICATION, mDisplayContent, "imeAppTarget");
Wale Ogunwale3c1170d2016-12-02 14:44:52 -0800146
lumarkff0ab692018-11-05 20:32:30 +0800147 mDisplayContent.mInputMethodTarget = imeAppTarget;
Wale Ogunwale3c1170d2016-12-02 14:44:52 -0800148
Wale Ogunwale34247952017-02-19 11:57:53 -0800149 assertForAllWindowsOrder(Arrays.asList(
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700150 mWallpaperWindow,
151 mChildAppWindowBelow,
152 mAppWindow,
153 mChildAppWindowAbove,
Wale Ogunwale34247952017-02-19 11:57:53 -0800154 imeAppTarget,
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700155 mImeWindow,
156 mImeDialogWindow,
157 mDockedDividerWindow,
158 mStatusBarWindow,
159 mNavBarWindow));
Wale Ogunwale34247952017-02-19 11:57:53 -0800160 }
Wale Ogunwale3c1170d2016-12-02 14:44:52 -0800161
Wale Ogunwale34247952017-02-19 11:57:53 -0800162 @Test
lumarkff0ab692018-11-05 20:32:30 +0800163 public void testForAllWindows_WithChildWindowImeTarget() throws Exception {
164 mDisplayContent.mInputMethodTarget = mChildAppWindowAbove;
Wale Ogunwale3c1170d2016-12-02 14:44:52 -0800165
Wale Ogunwale34247952017-02-19 11:57:53 -0800166 assertForAllWindowsOrder(Arrays.asList(
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700167 mWallpaperWindow,
168 mChildAppWindowBelow,
169 mAppWindow,
170 mChildAppWindowAbove,
171 mImeWindow,
172 mImeDialogWindow,
173 mDockedDividerWindow,
174 mStatusBarWindow,
175 mNavBarWindow));
Wale Ogunwaleb783fd82016-11-04 09:51:54 -0700176 }
Wale Ogunwale5d7e7f12016-12-12 14:47:05 -0800177
178 @Test
lumarkff0ab692018-11-05 20:32:30 +0800179 public void testForAllWindows_WithStatusBarImeTarget() throws Exception {
180 mDisplayContent.mInputMethodTarget = mStatusBarWindow;
Wale Ogunwale6ce0fb82016-12-13 14:24:00 -0800181
Wale Ogunwale34247952017-02-19 11:57:53 -0800182 assertForAllWindowsOrder(Arrays.asList(
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700183 mWallpaperWindow,
184 mChildAppWindowBelow,
185 mAppWindow,
186 mChildAppWindowAbove,
187 mDockedDividerWindow,
188 mStatusBarWindow,
189 mImeWindow,
190 mImeDialogWindow,
191 mNavBarWindow));
Wale Ogunwale6ce0fb82016-12-13 14:24:00 -0800192 }
193
194 @Test
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700195 public void testForAllWindows_WithInBetweenWindowToken() {
Wale Ogunwale5d7e7f12016-12-12 14:47:05 -0800196 // This window is set-up to be z-ordered between some windows that go in the same token like
197 // the nav bar and status bar.
198 final WindowState voiceInteractionWindow = createWindow(null, TYPE_VOICE_INTERACTION,
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700199 mDisplayContent, "voiceInteractionWindow");
Wale Ogunwale5d7e7f12016-12-12 14:47:05 -0800200
Wale Ogunwale34247952017-02-19 11:57:53 -0800201 assertForAllWindowsOrder(Arrays.asList(
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700202 mWallpaperWindow,
203 mChildAppWindowBelow,
204 mAppWindow,
205 mChildAppWindowAbove,
206 mDockedDividerWindow,
Wale Ogunwale34247952017-02-19 11:57:53 -0800207 voiceInteractionWindow,
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700208 mStatusBarWindow,
209 mNavBarWindow,
210 mImeWindow,
211 mImeDialogWindow));
Wale Ogunwale34247952017-02-19 11:57:53 -0800212 }
Wale Ogunwale5d7e7f12016-12-12 14:47:05 -0800213
Wale Ogunwale34247952017-02-19 11:57:53 -0800214 @Test
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700215 public void testComputeImeTarget() {
Wale Ogunwale34247952017-02-19 11:57:53 -0800216 // Verify that an app window can be an ime target.
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700217 final WindowState appWin = createWindow(null, TYPE_APPLICATION, mDisplayContent, "appWin");
Wale Ogunwale34247952017-02-19 11:57:53 -0800218 appWin.setHasSurface(true);
219 assertTrue(appWin.canBeImeTarget());
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700220 WindowState imeTarget = mDisplayContent.computeImeTarget(false /* updateImeTarget */);
Wale Ogunwale34247952017-02-19 11:57:53 -0800221 assertEquals(appWin, imeTarget);
chaviwebcbc342018-02-07 13:19:00 -0800222 appWin.mHidden = false;
Wale Ogunwale5d7e7f12016-12-12 14:47:05 -0800223
Wale Ogunwale34247952017-02-19 11:57:53 -0800224 // Verify that an child window can be an ime target.
225 final WindowState childWin = createWindow(appWin,
226 TYPE_APPLICATION_ATTACHED_DIALOG, "childWin");
227 childWin.setHasSurface(true);
228 assertTrue(childWin.canBeImeTarget());
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700229 imeTarget = mDisplayContent.computeImeTarget(false /* updateImeTarget */);
Wale Ogunwale34247952017-02-19 11:57:53 -0800230 assertEquals(childWin, imeTarget);
Wale Ogunwale5d7e7f12016-12-12 14:47:05 -0800231 }
Andrii Kulian6cc1a1d2016-12-27 23:52:59 -0800232
Andrii Kuliand68501e2017-01-10 22:57:27 -0800233 /**
234 * This tests stack movement between displays and proper stack's, task's and app token's display
235 * container references updates.
236 */
Andrii Kulian6cc1a1d2016-12-27 23:52:59 -0800237 @Test
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700238 public void testMoveStackBetweenDisplays() {
Andrii Kulian367ff7f2017-01-25 19:45:34 -0800239 // Create a second display.
240 final DisplayContent dc = createNewDisplay();
Andrii Kulian6cc1a1d2016-12-27 23:52:59 -0800241
242 // Add stack with activity.
Wale Ogunwalebebd8cd2019-10-28 15:53:31 -0700243 final ActivityStack stack = createTaskStackOnDisplay(dc);
Andrii Kulian6cc1a1d2016-12-27 23:52:59 -0800244 assertEquals(dc.getDisplayId(), stack.getDisplayContent().getDisplayId());
245 assertEquals(dc, stack.getParent().getParent());
246 assertEquals(dc, stack.getDisplayContent());
247
248 final Task task = createTaskInStack(stack, 0 /* userId */);
Garfield Tane8d84ab2019-10-11 09:49:40 -0700249 final ActivityRecord activity = WindowTestUtils.createTestActivityRecord(dc);
250 task.addChild(activity, 0);
Andrii Kulian6cc1a1d2016-12-27 23:52:59 -0800251 assertEquals(dc, task.getDisplayContent());
Garfield Tane8d84ab2019-10-11 09:49:40 -0700252 assertEquals(dc, activity.getDisplayContent());
Andrii Kulian6cc1a1d2016-12-27 23:52:59 -0800253
254 // Move stack to first display.
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700255 mDisplayContent.moveStackToDisplay(stack, true /* onTop */);
256 assertEquals(mDisplayContent.getDisplayId(), stack.getDisplayContent().getDisplayId());
257 assertEquals(mDisplayContent, stack.getParent().getParent());
258 assertEquals(mDisplayContent, stack.getDisplayContent());
259 assertEquals(mDisplayContent, task.getDisplayContent());
Garfield Tane8d84ab2019-10-11 09:49:40 -0700260 assertEquals(mDisplayContent, activity.getDisplayContent());
Andrii Kulian6cc1a1d2016-12-27 23:52:59 -0800261 }
Andrii Kuliand68501e2017-01-10 22:57:27 -0800262
263 /**
264 * This tests override configuration updates for display content.
265 */
266 @Test
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700267 public void testDisplayOverrideConfigUpdate() {
Evan Roskydfe3da72018-10-26 17:21:06 -0700268 final Configuration currentOverrideConfig =
269 mDisplayContent.getRequestedOverrideConfiguration();
Andrii Kuliand68501e2017-01-10 22:57:27 -0800270
271 // Create new, slightly changed override configuration and apply it to the display.
272 final Configuration newOverrideConfig = new Configuration(currentOverrideConfig);
273 newOverrideConfig.densityDpi += 120;
274 newOverrideConfig.fontScale += 0.3;
275
Evan Roskye747c3e2018-10-30 20:06:41 -0700276 mWm.setNewDisplayOverrideConfiguration(newOverrideConfig, mDisplayContent);
Andrii Kuliand68501e2017-01-10 22:57:27 -0800277
278 // Check that override config is applied.
Evan Roskydfe3da72018-10-26 17:21:06 -0700279 assertEquals(newOverrideConfig, mDisplayContent.getRequestedOverrideConfiguration());
Andrii Kulian367ff7f2017-01-25 19:45:34 -0800280 }
281
282 /**
283 * This tests global configuration updates when default display config is updated.
284 */
285 @Test
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700286 public void testDefaultDisplayOverrideConfigUpdate() {
Evan Roskye747c3e2018-10-30 20:06:41 -0700287 DisplayContent defaultDisplay = mWm.mRoot.getDisplayContent(DEFAULT_DISPLAY);
288 final Configuration currentConfig = defaultDisplay.getConfiguration();
Andrii Kulian367ff7f2017-01-25 19:45:34 -0800289
290 // Create new, slightly changed override configuration and apply it to the display.
Andrii Kuliana95bfff2017-03-30 19:00:41 -0700291 final Configuration newOverrideConfig = new Configuration(currentConfig);
Andrii Kulian367ff7f2017-01-25 19:45:34 -0800292 newOverrideConfig.densityDpi += 120;
293 newOverrideConfig.fontScale += 0.3;
294
Evan Roskye747c3e2018-10-30 20:06:41 -0700295 mWm.setNewDisplayOverrideConfiguration(newOverrideConfig, defaultDisplay);
Andrii Kuliand68501e2017-01-10 22:57:27 -0800296
297 // Check that global configuration is updated, as we've updated default display's config.
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700298 Configuration globalConfig = mWm.mRoot.getConfiguration();
Andrii Kuliand68501e2017-01-10 22:57:27 -0800299 assertEquals(newOverrideConfig.densityDpi, globalConfig.densityDpi);
300 assertEquals(newOverrideConfig.fontScale, globalConfig.fontScale, 0.1 /* delta */);
Andrii Kulian367ff7f2017-01-25 19:45:34 -0800301
302 // Return back to original values.
Evan Roskye747c3e2018-10-30 20:06:41 -0700303 mWm.setNewDisplayOverrideConfiguration(currentConfig, defaultDisplay);
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700304 globalConfig = mWm.mRoot.getConfiguration();
Andrii Kuliana95bfff2017-03-30 19:00:41 -0700305 assertEquals(currentConfig.densityDpi, globalConfig.densityDpi);
306 assertEquals(currentConfig.fontScale, globalConfig.fontScale, 0.1 /* delta */);
Andrii Kuliand68501e2017-01-10 22:57:27 -0800307 }
Wale Ogunwale34247952017-02-19 11:57:53 -0800308
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -0700309 /**
310 * Tests tapping on a stack in different display results in window gaining focus.
311 */
312 @Test
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700313 public void testInputEventBringsCorrectDisplayInFocus() {
314 DisplayContent dc0 = mWm.getDefaultDisplayContentLocked();
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -0700315 // Create a second display
316 final DisplayContent dc1 = createNewDisplay();
317
318 // Add stack with activity.
Wale Ogunwalebebd8cd2019-10-28 15:53:31 -0700319 final ActivityStack stack0 = createTaskStackOnDisplay(dc0);
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -0700320 final Task task0 = createTaskInStack(stack0, 0 /* userId */);
Garfield Tane8d84ab2019-10-11 09:49:40 -0700321 final ActivityRecord activity =
322 WindowTestUtils.createTestActivityRecord(dc0);
323 task0.addChild(activity, 0);
Arthur Hungbe5ce212018-09-13 18:41:56 +0800324 dc0.configureDisplayPolicy();
325 assertNotNull(dc0.mTapDetector);
326
Wale Ogunwalebebd8cd2019-10-28 15:53:31 -0700327 final ActivityStack stack1 = createTaskStackOnDisplay(dc1);
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -0700328 final Task task1 = createTaskInStack(stack1, 0 /* userId */);
Garfield Tane8d84ab2019-10-11 09:49:40 -0700329 final ActivityRecord activity1 =
330 WindowTestUtils.createTestActivityRecord(dc0);
331 task1.addChild(activity1, 0);
Arthur Hungbe5ce212018-09-13 18:41:56 +0800332 dc1.configureDisplayPolicy();
333 assertNotNull(dc1.mTapDetector);
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -0700334
Arthur Hungbe5ce212018-09-13 18:41:56 +0800335 // tap on primary display.
336 tapOnDisplay(dc0);
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -0700337 // Check focus is on primary display.
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700338 assertEquals(mWm.mRoot.getTopFocusedDisplayContent().mCurrentFocus,
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800339 dc0.findFocusedWindow());
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -0700340
Arthur Hungbe5ce212018-09-13 18:41:56 +0800341 // Tap on secondary display.
342 tapOnDisplay(dc1);
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -0700343 // Check focus is on secondary.
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700344 assertEquals(mWm.mRoot.getTopFocusedDisplayContent().mCurrentFocus,
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800345 dc1.findFocusedWindow());
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -0700346 }
347
David Stevens46939562017-03-24 13:04:00 -0700348 @Test
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700349 public void testFocusedWindowMultipleDisplays() {
Tiger Huang51c5a1d2018-12-11 20:24:51 +0800350 doTestFocusedWindowMultipleDisplays(false /* perDisplayFocusEnabled */, Q);
351 }
352
353 @Test
354 public void testFocusedWindowMultipleDisplaysPerDisplayFocusEnabled() {
355 doTestFocusedWindowMultipleDisplays(true /* perDisplayFocusEnabled */, Q);
356 }
357
358 @Test
359 public void testFocusedWindowMultipleDisplaysPerDisplayFocusEnabledLegacyApp() {
360 doTestFocusedWindowMultipleDisplays(true /* perDisplayFocusEnabled */, P);
361 }
362
363 private void doTestFocusedWindowMultipleDisplays(boolean perDisplayFocusEnabled,
364 int targetSdk) {
365 mWm.mPerDisplayFocusEnabled = perDisplayFocusEnabled;
366
Andrii Kulian0214ed92017-05-16 13:44:05 -0700367 // Create a focusable window and check that focus is calculated correctly
David Stevens46939562017-03-24 13:04:00 -0700368 final WindowState window1 =
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700369 createWindow(null, TYPE_BASE_APPLICATION, mDisplayContent, "window1");
Garfield Tane8d84ab2019-10-11 09:49:40 -0700370 window1.mActivityRecord.mTargetSdk = targetSdk;
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800371 updateFocusedWindow();
372 assertTrue(window1.isFocused());
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700373 assertEquals(window1, mWm.mRoot.getTopFocusedDisplayContent().mCurrentFocus);
David Stevens46939562017-03-24 13:04:00 -0700374
375 // Check that a new display doesn't affect focus
376 final DisplayContent dc = createNewDisplay();
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800377 updateFocusedWindow();
378 assertTrue(window1.isFocused());
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700379 assertEquals(window1, mWm.mRoot.getTopFocusedDisplayContent().mCurrentFocus);
David Stevens46939562017-03-24 13:04:00 -0700380
381 // Add a window to the second display, and it should be focused
382 final WindowState window2 = createWindow(null, TYPE_BASE_APPLICATION, dc, "window2");
Garfield Tane8d84ab2019-10-11 09:49:40 -0700383 window2.mActivityRecord.mTargetSdk = targetSdk;
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800384 updateFocusedWindow();
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800385 assertTrue(window2.isFocused());
Tiger Huang51c5a1d2018-12-11 20:24:51 +0800386 assertEquals(perDisplayFocusEnabled && targetSdk >= Q, window1.isFocused());
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700387 assertEquals(window2, mWm.mRoot.getTopFocusedDisplayContent().mCurrentFocus);
David Stevens46939562017-03-24 13:04:00 -0700388
Tiger Huang51c5a1d2018-12-11 20:24:51 +0800389 // Move the first window to top including parents, and make sure focus is updated
David Stevens46939562017-03-24 13:04:00 -0700390 window1.getParent().positionChildAt(POSITION_TOP, window1, true);
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800391 updateFocusedWindow();
392 assertTrue(window1.isFocused());
Tiger Huang51c5a1d2018-12-11 20:24:51 +0800393 assertEquals(perDisplayFocusEnabled && targetSdk >= Q, window2.isFocused());
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700394 assertEquals(window1, mWm.mRoot.getTopFocusedDisplayContent().mCurrentFocus);
Louis Changa9350fe2019-04-25 17:14:20 +0800395
396 // Make sure top focused display not changed if there is a focused app.
Issei Suzuki430a1112019-11-14 16:20:52 +0100397 window1.mActivityRecord.hiddenRequested = true;
Garfield Tane8d84ab2019-10-11 09:49:40 -0700398 window1.getDisplayContent().setFocusedApp(window1.mActivityRecord);
Louis Changa9350fe2019-04-25 17:14:20 +0800399 updateFocusedWindow();
400 assertTrue(!window1.isFocused());
401 assertEquals(window1.getDisplayId(),
402 mWm.mRoot.getTopFocusedDisplayContent().getDisplayId());
Adrian Roos4163d622018-05-22 16:56:35 +0200403 }
404
Riddle Hsub2297ad2019-07-26 23:37:25 -0600405 @Test
406 public void testShouldWaitForSystemDecorWindowsOnBoot_OnDefaultDisplay() {
407 mWm.mSystemBooted = true;
408 final DisplayContent defaultDisplay = mWm.getDefaultDisplayContentLocked();
409 final WindowState[] windows = createNotDrawnWindowsOn(defaultDisplay,
410 TYPE_WALLPAPER, TYPE_APPLICATION);
411
412 // Verify waiting for windows to be drawn.
413 assertTrue(defaultDisplay.shouldWaitForSystemDecorWindowsOnBoot());
414
415 // Verify not waiting for drawn windows.
416 makeWindowsDrawn(windows);
417 assertFalse(defaultDisplay.shouldWaitForSystemDecorWindowsOnBoot());
418 }
419
420 @Test
421 public void testShouldWaitForSystemDecorWindowsOnBoot_OnSecondaryDisplay() {
422 mWm.mSystemBooted = true;
423 final DisplayContent secondaryDisplay = createNewDisplay();
424 final WindowState[] windows = createNotDrawnWindowsOn(secondaryDisplay,
425 TYPE_WALLPAPER, TYPE_APPLICATION);
426
427 // Verify not waiting for display without system decorations.
428 doReturn(false).when(secondaryDisplay).supportsSystemDecorations();
429 assertFalse(secondaryDisplay.shouldWaitForSystemDecorWindowsOnBoot());
430
431 // Verify waiting for non-drawn windows on display with system decorations.
432 reset(secondaryDisplay);
433 doReturn(true).when(secondaryDisplay).supportsSystemDecorations();
434 assertTrue(secondaryDisplay.shouldWaitForSystemDecorWindowsOnBoot());
435
436 // Verify not waiting for drawn windows on display with system decorations.
437 makeWindowsDrawn(windows);
438 assertFalse(secondaryDisplay.shouldWaitForSystemDecorWindowsOnBoot());
439 }
440
441 private WindowState[] createNotDrawnWindowsOn(DisplayContent displayContent, int... types) {
442 final WindowState[] windows = new WindowState[types.length];
443 for (int i = 0; i < types.length; i++) {
444 final int type = types[i];
445 windows[i] = createWindow(null /* parent */, type, displayContent, "window-" + type);
446 windows[i].mHasSurface = false;
447 }
448 return windows;
449 }
450
451 private static void makeWindowsDrawn(WindowState[] windows) {
452 for (WindowState window : windows) {
453 window.mHasSurface = true;
454 window.mWinAnimator.mDrawState = WindowStateAnimator.HAS_DRAWN;
455 }
456 }
457
Bryce Lee27cec322017-03-21 09:41:37 -0700458 /**
459 * This tests setting the maximum ui width on a display.
460 */
461 @Test
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700462 public void testMaxUiWidth() {
Riddle Hsu654a6f92018-07-13 22:59:36 +0800463 // Prevent base display metrics for test from being updated to the value of real display.
464 final DisplayContent displayContent = createDisplayNoUpdateDisplayInfo();
Bryce Lee27cec322017-03-21 09:41:37 -0700465 final int baseWidth = 1440;
466 final int baseHeight = 2560;
467 final int baseDensity = 300;
468
Riddle Hsu654a6f92018-07-13 22:59:36 +0800469 displayContent.updateBaseDisplayMetrics(baseWidth, baseHeight, baseDensity);
Bryce Lee27cec322017-03-21 09:41:37 -0700470
471 final int maxWidth = 300;
472 final int resultingHeight = (maxWidth * baseHeight) / baseWidth;
473 final int resultingDensity = (maxWidth * baseDensity) / baseWidth;
474
Riddle Hsu654a6f92018-07-13 22:59:36 +0800475 displayContent.setMaxUiWidth(maxWidth);
476 verifySizes(displayContent, maxWidth, resultingHeight, resultingDensity);
Bryce Lee27cec322017-03-21 09:41:37 -0700477
478 // Assert setting values again does not change;
Riddle Hsu654a6f92018-07-13 22:59:36 +0800479 displayContent.updateBaseDisplayMetrics(baseWidth, baseHeight, baseDensity);
480 verifySizes(displayContent, maxWidth, resultingHeight, resultingDensity);
Bryce Lee27cec322017-03-21 09:41:37 -0700481
482 final int smallerWidth = 200;
483 final int smallerHeight = 400;
484 final int smallerDensity = 100;
485
486 // Specify smaller dimension, verify that it is honored
Riddle Hsu654a6f92018-07-13 22:59:36 +0800487 displayContent.updateBaseDisplayMetrics(smallerWidth, smallerHeight, smallerDensity);
488 verifySizes(displayContent, smallerWidth, smallerHeight, smallerDensity);
Bryce Lee27cec322017-03-21 09:41:37 -0700489
490 // Verify that setting the max width to a greater value than the base width has no effect
Riddle Hsu654a6f92018-07-13 22:59:36 +0800491 displayContent.setMaxUiWidth(maxWidth);
492 verifySizes(displayContent, smallerWidth, smallerHeight, smallerDensity);
Bryce Lee27cec322017-03-21 09:41:37 -0700493 }
494
Andrii Kulian92c9a942017-10-10 00:41:41 -0700495 @Test
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700496 public void testDisplayCutout_rot0() {
Riddle Hsu73f53572019-09-23 23:13:01 +0800497 final DisplayContent dc = createNewDisplay();
498 dc.mInitialDisplayWidth = 200;
499 dc.mInitialDisplayHeight = 400;
500 final Rect r = new Rect(80, 0, 120, 10);
501 final DisplayCutout cutout = new WmDisplayCutout(
502 fromBoundingRect(r.left, r.top, r.right, r.bottom, BOUNDS_POSITION_TOP), null)
503 .computeSafeInsets(200, 400).getDisplayCutout();
Adrian Roos1cf585052018-01-03 18:43:27 +0100504
Riddle Hsu73f53572019-09-23 23:13:01 +0800505 dc.mInitialDisplayCutout = cutout;
506 dc.getDisplayRotation().setRotation(Surface.ROTATION_0);
507 dc.computeScreenConfiguration(new Configuration()); // recomputes dc.mDisplayInfo.
Adrian Roos1cf585052018-01-03 18:43:27 +0100508
Riddle Hsu73f53572019-09-23 23:13:01 +0800509 assertEquals(cutout, dc.getDisplayInfo().displayCutout);
Adrian Roos1cf585052018-01-03 18:43:27 +0100510 }
511
512 @Test
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700513 public void testDisplayCutout_rot90() {
Riddle Hsu73f53572019-09-23 23:13:01 +0800514 // Prevent mInitialDisplayCutout from being updated from real display (e.g. null
515 // if the device has no cutout).
516 final DisplayContent dc = createDisplayNoUpdateDisplayInfo();
517 // Rotation may use real display info to compute bound, so here also uses the
518 // same width and height.
519 final int displayWidth = dc.mInitialDisplayWidth;
520 final int displayHeight = dc.mInitialDisplayHeight;
521 final int cutoutWidth = 40;
522 final int cutoutHeight = 10;
523 final int left = (displayWidth - cutoutWidth) / 2;
524 final int top = 0;
525 final int right = (displayWidth + cutoutWidth) / 2;
526 final int bottom = cutoutHeight;
Riddle Hsu654a6f92018-07-13 22:59:36 +0800527
Riddle Hsu73f53572019-09-23 23:13:01 +0800528 final Rect r1 = new Rect(left, top, right, bottom);
529 final DisplayCutout cutout = new WmDisplayCutout(
530 fromBoundingRect(r1.left, r1.top, r1.right, r1.bottom, BOUNDS_POSITION_TOP), null)
531 .computeSafeInsets(displayWidth, displayHeight).getDisplayCutout();
Adrian Roos1cf585052018-01-03 18:43:27 +0100532
Riddle Hsu73f53572019-09-23 23:13:01 +0800533 dc.mInitialDisplayCutout = cutout;
534 dc.getDisplayRotation().setRotation(Surface.ROTATION_90);
535 dc.computeScreenConfiguration(new Configuration()); // recomputes dc.mDisplayInfo.
Adrian Roos1cf585052018-01-03 18:43:27 +0100536
Riddle Hsu73f53572019-09-23 23:13:01 +0800537 // ----o---------- -------------
538 // | | | | |
539 // | ------o | o---
540 // | | | |
541 // | | -> | |
542 // | | ---o
543 // | | |
544 // | | -------------
545 final Rect r = new Rect(top, left, bottom, right);
546 assertEquals(new WmDisplayCutout(
547 fromBoundingRect(r.left, r.top, r.right, r.bottom, BOUNDS_POSITION_LEFT), null)
548 .computeSafeInsets(displayHeight, displayWidth).getDisplayCutout(),
549 dc.getDisplayInfo().displayCutout);
Adrian Roos1cf585052018-01-03 18:43:27 +0100550 }
551
552 @Test
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700553 public void testLayoutSeq_assignedDuringLayout() {
Riddle Hsu73f53572019-09-23 23:13:01 +0800554 final DisplayContent dc = createNewDisplay();
555 final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, dc, "w");
Adrian Roos5251b1d2018-03-23 18:57:43 +0100556
Riddle Hsu73f53572019-09-23 23:13:01 +0800557 dc.setLayoutNeeded();
558 dc.performLayout(true /* initial */, false /* updateImeWindows */);
Adrian Roos5251b1d2018-03-23 18:57:43 +0100559
Riddle Hsu73f53572019-09-23 23:13:01 +0800560 assertThat(win.mLayoutSeq, is(dc.mLayoutSeq));
Adrian Roos5251b1d2018-03-23 18:57:43 +0100561 }
562
563 @Test
Andrii Kulian92c9a942017-10-10 00:41:41 -0700564 @SuppressLint("InlinedApi")
565 public void testOrientationDefinedByKeyguard() {
566 final DisplayContent dc = createNewDisplay();
Garfield Tan90b04282018-12-11 14:04:42 -0800567
568 // When display content is created its configuration is not yet initialized, which could
569 // cause unnecessary configuration propagation, so initialize it here.
570 final Configuration config = new Configuration();
571 dc.computeScreenConfiguration(config);
572 dc.onRequestedOverrideConfigurationChanged(config);
573
Andrii Kulian92c9a942017-10-10 00:41:41 -0700574 // Create a window that requests landscape orientation. It will define device orientation
575 // by default.
576 final WindowState window = createWindow(null /* parent */, TYPE_BASE_APPLICATION, dc, "w");
Garfield Tane8d84ab2019-10-11 09:49:40 -0700577 window.mActivityRecord.setOrientation(SCREEN_ORIENTATION_LANDSCAPE);
Andrii Kulian92c9a942017-10-10 00:41:41 -0700578
579 final WindowState keyguard = createWindow(null, TYPE_STATUS_BAR, dc, "keyguard");
580 keyguard.mHasSurface = true;
581 keyguard.mAttrs.screenOrientation = SCREEN_ORIENTATION_UNSPECIFIED;
582
583 assertEquals("Screen orientation must be defined by the app window by default",
584 SCREEN_ORIENTATION_LANDSCAPE, dc.getOrientation());
585
586 keyguard.mAttrs.screenOrientation = SCREEN_ORIENTATION_PORTRAIT;
587 assertEquals("Visible keyguard must influence device orientation",
588 SCREEN_ORIENTATION_PORTRAIT, dc.getOrientation());
589
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700590 mWm.setKeyguardGoingAway(true);
Andrii Kulian92c9a942017-10-10 00:41:41 -0700591 assertEquals("Keyguard that is going away must not influence device orientation",
592 SCREEN_ORIENTATION_LANDSCAPE, dc.getOrientation());
593 }
594
Andrii Kulianf0379de2018-03-14 16:24:07 -0700595 @Test
Tiger Huang86e6d072019-05-02 20:23:47 +0800596 public void testOrientationForAspectRatio() {
597 final DisplayContent dc = createNewDisplay();
598
599 // When display content is created its configuration is not yet initialized, which could
600 // cause unnecessary configuration propagation, so initialize it here.
601 final Configuration config = new Configuration();
602 dc.computeScreenConfiguration(config);
603 dc.onRequestedOverrideConfigurationChanged(config);
604
605 // Create a window that requests a fixed orientation. It will define device orientation
606 // by default.
607 final WindowState window = createWindow(null /* parent */, TYPE_APPLICATION_OVERLAY, dc,
608 "window");
609 window.mHasSurface = true;
610 window.mAttrs.screenOrientation = SCREEN_ORIENTATION_LANDSCAPE;
611
612 // --------------------------------
613 // Test non-close-to-square display
614 // --------------------------------
615 dc.mBaseDisplayWidth = 1000;
616 dc.mBaseDisplayHeight = (int) (dc.mBaseDisplayWidth * dc.mCloseToSquareMaxAspectRatio * 2f);
617 dc.configureDisplayPolicy();
618
619 assertEquals("Screen orientation must be defined by the window by default.",
620 window.mAttrs.screenOrientation, dc.getOrientation());
621
622 // ----------------------------
623 // Test close-to-square display
624 // ----------------------------
625 dc.mBaseDisplayHeight = dc.mBaseDisplayWidth;
626 dc.configureDisplayPolicy();
627
628 assertEquals("Screen orientation must be SCREEN_ORIENTATION_USER.",
629 SCREEN_ORIENTATION_USER, dc.getOrientation());
630 }
631
632 @Test
Andrii Kulianf0379de2018-03-14 16:24:07 -0700633 public void testDisableDisplayInfoOverrideFromWindowManager() {
634 final DisplayContent dc = createNewDisplay();
635
636 assertTrue(dc.mShouldOverrideDisplayConfiguration);
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700637 mWm.dontOverrideDisplayInfo(dc.getDisplayId());
Andrii Kulianf0379de2018-03-14 16:24:07 -0700638
639 assertFalse(dc.mShouldOverrideDisplayConfiguration);
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700640 verify(mWm.mDisplayManagerInternal, times(1))
Andrii Kulianf0379de2018-03-14 16:24:07 -0700641 .setDisplayInfoOverrideFromWindowManager(dc.getDisplayId(), null);
642 }
643
Riddle Hsua4d6fa22018-08-11 00:50:39 +0800644 @Test
Riddle Hsu85bd04b2018-11-17 00:34:36 +0800645 public void testClearLastFocusWhenReparentingFocusedWindow() {
646 final DisplayContent defaultDisplay = mWm.getDefaultDisplayContentLocked();
647 final WindowState window = createWindow(null /* parent */, TYPE_BASE_APPLICATION,
648 defaultDisplay, "window");
649 defaultDisplay.mLastFocus = window;
650 mDisplayContent.mCurrentFocus = window;
651 mDisplayContent.reParentWindowToken(window.mToken);
652
653 assertNull(defaultDisplay.mLastFocus);
654 }
655
656 @Test
Riddle Hsua4d6fa22018-08-11 00:50:39 +0800657 public void testGetPreferredOptionsPanelGravityFromDifferentDisplays() {
658 final DisplayContent portraitDisplay = createNewDisplay();
659 portraitDisplay.mInitialDisplayHeight = 2000;
660 portraitDisplay.mInitialDisplayWidth = 1000;
661
Riddle Hsuccf09402019-08-13 00:33:06 +0800662 portraitDisplay.getDisplayRotation().setRotation(Surface.ROTATION_0);
Riddle Hsua4d6fa22018-08-11 00:50:39 +0800663 assertFalse(isOptionsPanelAtRight(portraitDisplay.getDisplayId()));
Evan Rosky69cace42019-09-20 16:28:13 -0700664 portraitDisplay.getDisplayRotation().setRotation(ROTATION_90);
Riddle Hsua4d6fa22018-08-11 00:50:39 +0800665 assertTrue(isOptionsPanelAtRight(portraitDisplay.getDisplayId()));
666
667 final DisplayContent landscapeDisplay = createNewDisplay();
668 landscapeDisplay.mInitialDisplayHeight = 1000;
669 landscapeDisplay.mInitialDisplayWidth = 2000;
670
Riddle Hsuccf09402019-08-13 00:33:06 +0800671 landscapeDisplay.getDisplayRotation().setRotation(Surface.ROTATION_0);
Riddle Hsua4d6fa22018-08-11 00:50:39 +0800672 assertTrue(isOptionsPanelAtRight(landscapeDisplay.getDisplayId()));
Evan Rosky69cace42019-09-20 16:28:13 -0700673 landscapeDisplay.getDisplayRotation().setRotation(ROTATION_90);
Riddle Hsua4d6fa22018-08-11 00:50:39 +0800674 assertFalse(isOptionsPanelAtRight(landscapeDisplay.getDisplayId()));
675 }
676
lumarkff0ab692018-11-05 20:32:30 +0800677 @Test
678 public void testInputMethodTargetUpdateWhenSwitchingOnDisplays() {
679 final DisplayContent newDisplay = createNewDisplay();
680
681 final WindowState appWin = createWindow(null, TYPE_APPLICATION, mDisplayContent, "appWin");
682 final WindowState appWin1 = createWindow(null, TYPE_APPLICATION, newDisplay, "appWin1");
683 appWin.setHasSurface(true);
684 appWin1.setHasSurface(true);
685
686 // Set current input method window on default display, make sure the input method target
687 // is appWin & null on the other display.
688 mDisplayContent.setInputMethodWindowLocked(mImeWindow);
689 newDisplay.setInputMethodWindowLocked(null);
Wale Ogunwale3198da42019-10-10 14:45:03 +0200690 assertEquals("appWin should be IME target window",
691 appWin, mDisplayContent.mInputMethodTarget);
lumarkff0ab692018-11-05 20:32:30 +0800692 assertNull("newDisplay Ime target: ", newDisplay.mInputMethodTarget);
693
694 // Switch input method window on new display & make sure the input method target also
695 // switched as expected.
696 newDisplay.setInputMethodWindowLocked(mImeWindow);
697 mDisplayContent.setInputMethodWindowLocked(null);
Wale Ogunwale3198da42019-10-10 14:45:03 +0200698 assertEquals("appWin1 should be IME target window", appWin1, newDisplay.mInputMethodTarget);
lumarkff0ab692018-11-05 20:32:30 +0800699 assertNull("default display Ime target: ", mDisplayContent.mInputMethodTarget);
700 }
701
Garfield Tan90b04282018-12-11 14:04:42 -0800702 @Test
703 public void testOnDescendantOrientationRequestChanged() {
Garfield Tan49dae102019-02-04 09:51:59 -0800704 final DisplayContent dc = createNewDisplay();
Wale Ogunwale8a1860a2019-06-05 08:57:19 -0700705 dc.getDisplayRotation().setFixedToUserRotation(
706 DisplayRotation.FIXED_TO_USER_ROTATION_DISABLED);
Garfield Tan49dae102019-02-04 09:51:59 -0800707 final int newOrientation = dc.getLastOrientation() == SCREEN_ORIENTATION_LANDSCAPE
708 ? SCREEN_ORIENTATION_PORTRAIT
709 : SCREEN_ORIENTATION_LANDSCAPE;
Garfield Tan90b04282018-12-11 14:04:42 -0800710
Wale Ogunwale8a1860a2019-06-05 08:57:19 -0700711 final ActivityStack stack =
712 new ActivityTestsBase.StackBuilder(mWm.mAtmService.mRootActivityContainer)
Riddle Hsud1549d22019-10-07 17:00:47 +0800713 .setDisplay(dc.mActivityDisplay).build();
Wale Ogunwale21e06482019-11-18 05:14:15 -0800714 final ActivityRecord activity = stack.topTask().getTopNonFinishingActivity();
Garfield Tan90b04282018-12-11 14:04:42 -0800715
Wale Ogunwale8a1860a2019-06-05 08:57:19 -0700716 activity.setRequestedOrientation(newOrientation);
Garfield Tan90b04282018-12-11 14:04:42 -0800717
Wale Ogunwale8a1860a2019-06-05 08:57:19 -0700718 final int expectedOrientation = newOrientation == SCREEN_ORIENTATION_PORTRAIT
719 ? Configuration.ORIENTATION_PORTRAIT
720 : Configuration.ORIENTATION_LANDSCAPE;
Evan Rosky01775072019-09-11 17:28:07 -0700721 assertEquals(expectedOrientation, dc.getConfiguration().orientation);
Garfield Tan90b04282018-12-11 14:04:42 -0800722 }
723
724 @Test
725 public void testOnDescendantOrientationRequestChanged_FrozenToUserRotation() {
Garfield Tan49dae102019-02-04 09:51:59 -0800726 final DisplayContent dc = createNewDisplay();
Garfield Tan7fbca052019-02-19 10:45:35 -0800727 dc.getDisplayRotation().setFixedToUserRotation(
728 DisplayRotation.FIXED_TO_USER_ROTATION_ENABLED);
Garfield Tan49dae102019-02-04 09:51:59 -0800729 final int newOrientation = dc.getLastOrientation() == SCREEN_ORIENTATION_LANDSCAPE
730 ? SCREEN_ORIENTATION_PORTRAIT
731 : SCREEN_ORIENTATION_LANDSCAPE;
Garfield Tan90b04282018-12-11 14:04:42 -0800732
Wale Ogunwale8a1860a2019-06-05 08:57:19 -0700733 final ActivityStack stack =
734 new ActivityTestsBase.StackBuilder(mWm.mAtmService.mRootActivityContainer)
Riddle Hsud1549d22019-10-07 17:00:47 +0800735 .setDisplay(dc.mActivityDisplay).build();
Wale Ogunwale21e06482019-11-18 05:14:15 -0800736 final ActivityRecord activity = stack.topTask().getTopNonFinishingActivity();
Garfield Tan90b04282018-12-11 14:04:42 -0800737
Wale Ogunwale8a1860a2019-06-05 08:57:19 -0700738 activity.setRequestedOrientation(newOrientation);
Garfield Tan90b04282018-12-11 14:04:42 -0800739
Riddle Hsud1549d22019-10-07 17:00:47 +0800740 verify(dc.mActivityDisplay, never()).updateDisplayOverrideConfigurationLocked(any(),
Wale Ogunwale8a1860a2019-06-05 08:57:19 -0700741 eq(activity), anyBoolean(), same(null));
742 assertEquals(dc.getDisplayRotation().getUserRotation(), dc.getRotation());
Garfield Tan90b04282018-12-11 14:04:42 -0800743 }
744
Tarandeep Singha6f35612019-01-11 19:50:46 -0800745 @Test
746 public void testComputeImeParent_app() throws Exception {
747 try (final InsetsModeSession session =
748 new InsetsModeSession(ViewRootImpl.NEW_INSETS_MODE_IME)) {
749 final DisplayContent dc = createNewDisplay();
750 dc.mInputMethodTarget = createWindow(null, TYPE_BASE_APPLICATION, "app");
Garfield Tane8d84ab2019-10-11 09:49:40 -0700751 assertEquals(dc.mInputMethodTarget.mActivityRecord.getSurfaceControl(),
Tarandeep Singha6f35612019-01-11 19:50:46 -0800752 dc.computeImeParent());
753 }
754 }
755
756 @Test
757 public void testComputeImeParent_app_notFullscreen() throws Exception {
758 try (final InsetsModeSession session =
759 new InsetsModeSession(ViewRootImpl.NEW_INSETS_MODE_IME)) {
760 final DisplayContent dc = createNewDisplay();
761 dc.mInputMethodTarget = createWindow(null, TYPE_STATUS_BAR, "app");
762 dc.mInputMethodTarget.setWindowingMode(
763 WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
764 assertEquals(dc.getWindowingLayer(), dc.computeImeParent());
765 }
766 }
767
768 @Test
Riddle Hsu6d6f67c2019-03-14 16:54:26 +0800769 public void testComputeImeParent_app_notMatchParentBounds() {
Garfield Tane8d84ab2019-10-11 09:49:40 -0700770 spyOn(mAppWindow.mActivityRecord);
771 doReturn(false).when(mAppWindow.mActivityRecord).matchParentBounds();
Riddle Hsu6d6f67c2019-03-14 16:54:26 +0800772 mDisplayContent.mInputMethodTarget = mAppWindow;
773 // The surface parent of IME should be the display instead of app window.
774 assertEquals(mDisplayContent.getWindowingLayer(), mDisplayContent.computeImeParent());
775 }
776
777 @Test
Tarandeep Singha6f35612019-01-11 19:50:46 -0800778 public void testComputeImeParent_noApp() throws Exception {
779 try (final InsetsModeSession session =
780 new InsetsModeSession(ViewRootImpl.NEW_INSETS_MODE_IME)) {
781 final DisplayContent dc = createNewDisplay();
782 dc.mInputMethodTarget = createWindow(null, TYPE_STATUS_BAR, "statusBar");
783 assertEquals(dc.getWindowingLayer(), dc.computeImeParent());
784 }
785 }
786
Susi Kharraz-Post9893b8c2019-02-12 14:21:29 -0500787 @Test
Adrian Roos4ffc8972019-02-07 20:45:11 +0100788 public void testUpdateSystemGestureExclusion() throws Exception {
789 final DisplayContent dc = createNewDisplay();
790 final WindowState win = createWindow(null, TYPE_BASE_APPLICATION, dc, "win");
791 win.getAttrs().flags |= FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR;
792 win.setSystemGestureExclusion(Collections.singletonList(new Rect(10, 20, 30, 40)));
793
794 dc.setLayoutNeeded();
795 dc.performLayout(true /* initial */, false /* updateImeWindows */);
796
797 win.setHasSurface(true);
798 dc.updateSystemGestureExclusion();
799
Riddle Hsu73f53572019-09-23 23:13:01 +0800800 final boolean[] invoked = { false };
Adrian Roos4ffc8972019-02-07 20:45:11 +0100801 final ISystemGestureExclusionListener.Stub verifier =
802 new ISystemGestureExclusionListener.Stub() {
803 @Override
Adrian Roos5f2c9a12019-07-03 18:31:46 +0200804 public void onSystemGestureExclusionChanged(int displayId, Region actual,
805 Region unrestricted) {
Adrian Roos4ffc8972019-02-07 20:45:11 +0100806 Region expected = Region.obtain();
807 expected.set(10, 20, 30, 40);
808 assertEquals(expected, actual);
Riddle Hsu73f53572019-09-23 23:13:01 +0800809 invoked[0] = true;
Adrian Roos4ffc8972019-02-07 20:45:11 +0100810 }
811 };
812 try {
813 dc.registerSystemGestureExclusionListener(verifier);
814 } finally {
815 dc.unregisterSystemGestureExclusionListener(verifier);
816 }
Riddle Hsu73f53572019-09-23 23:13:01 +0800817 assertTrue("SystemGestureExclusionListener was not invoked", invoked[0]);
Adrian Roos4ffc8972019-02-07 20:45:11 +0100818 }
819
820 @Test
821 public void testCalculateSystemGestureExclusion() throws Exception {
822 final DisplayContent dc = createNewDisplay();
823 final WindowState win = createWindow(null, TYPE_BASE_APPLICATION, dc, "win");
824 win.getAttrs().flags |= FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR;
825 win.setSystemGestureExclusion(Collections.singletonList(new Rect(10, 20, 30, 40)));
826
827 final WindowState win2 = createWindow(null, TYPE_APPLICATION, dc, "win2");
828 win2.getAttrs().flags |= FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR;
829 win2.setSystemGestureExclusion(Collections.singletonList(new Rect(20, 30, 40, 50)));
830
831 dc.setLayoutNeeded();
832 dc.performLayout(true /* initial */, false /* updateImeWindows */);
833
834 win.setHasSurface(true);
835 win2.setHasSurface(true);
836
837 final Region expected = Region.obtain();
838 expected.set(20, 30, 40, 50);
Adrian Roos5f2c9a12019-07-03 18:31:46 +0200839 assertEquals(expected, calculateSystemGestureExclusion(dc));
840 }
841
842 private Region calculateSystemGestureExclusion(DisplayContent dc) {
843 Region out = Region.obtain();
844 Region unrestricted = Region.obtain();
845 dc.calculateSystemGestureExclusion(out, unrestricted);
846 return out;
Adrian Roos4ffc8972019-02-07 20:45:11 +0100847 }
848
849 @Test
Adrian Roosb1063792019-06-28 12:10:51 +0200850 public void testCalculateSystemGestureExclusion_modal() throws Exception {
851 final DisplayContent dc = createNewDisplay();
852 final WindowState win = createWindow(null, TYPE_BASE_APPLICATION, dc, "base");
853 win.getAttrs().flags |= FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR;
854 win.setSystemGestureExclusion(Collections.singletonList(new Rect(0, 0, 1000, 1000)));
855
856 final WindowState win2 = createWindow(null, TYPE_APPLICATION, dc, "modal");
857 win2.getAttrs().flags |= FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR;
858 win2.getAttrs().privateFlags |= PRIVATE_FLAG_NO_MOVE_ANIMATION;
859 win2.getAttrs().width = 10;
860 win2.getAttrs().height = 10;
861 win2.setSystemGestureExclusion(Collections.emptyList());
862
863 dc.setLayoutNeeded();
864 dc.performLayout(true /* initial */, false /* updateImeWindows */);
865
866 win.setHasSurface(true);
867 win2.setHasSurface(true);
868
869 final Region expected = Region.obtain();
Adrian Roos5f2c9a12019-07-03 18:31:46 +0200870 assertEquals(expected, calculateSystemGestureExclusion(dc));
Adrian Roosb1063792019-06-28 12:10:51 +0200871 }
872
873 @Test
Adrian Roos019a52b2019-07-02 16:47:44 +0200874 public void testCalculateSystemGestureExclusion_immersiveStickyLegacyWindow() throws Exception {
Adrian Roos1c2e9a12019-08-20 18:23:47 +0200875 mWm.mConstants.mSystemGestureExcludedByPreQStickyImmersive = true;
Adrian Roos019a52b2019-07-02 16:47:44 +0200876
Riddle Hsu73f53572019-09-23 23:13:01 +0800877 final DisplayContent dc = createNewDisplay();
878 final WindowState win = createWindow(null, TYPE_BASE_APPLICATION, dc, "win");
879 win.getAttrs().flags |= FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR;
880 win.getAttrs().layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
881 win.getAttrs().privateFlags |= PRIVATE_FLAG_NO_MOVE_ANIMATION;
882 win.getAttrs().subtreeSystemUiVisibility = win.mSystemUiVisibility =
883 SYSTEM_UI_FLAG_FULLSCREEN | SYSTEM_UI_FLAG_HIDE_NAVIGATION
884 | SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
Garfield Tane8d84ab2019-10-11 09:49:40 -0700885 win.mActivityRecord.mTargetSdk = P;
Adrian Roos019a52b2019-07-02 16:47:44 +0200886
Riddle Hsu73f53572019-09-23 23:13:01 +0800887 dc.setLayoutNeeded();
888 dc.performLayout(true /* initial */, false /* updateImeWindows */);
Adrian Roos019a52b2019-07-02 16:47:44 +0200889
Riddle Hsu73f53572019-09-23 23:13:01 +0800890 win.setHasSurface(true);
Adrian Roos019a52b2019-07-02 16:47:44 +0200891
Riddle Hsu73f53572019-09-23 23:13:01 +0800892 final Region expected = Region.obtain();
893 expected.set(dc.getBounds());
894 assertEquals(expected, calculateSystemGestureExclusion(dc));
Adrian Roos019a52b2019-07-02 16:47:44 +0200895
Riddle Hsu73f53572019-09-23 23:13:01 +0800896 win.setHasSurface(false);
Adrian Roos019a52b2019-07-02 16:47:44 +0200897 }
898
899 @Test
Susi Kharraz-Post9893b8c2019-02-12 14:21:29 -0500900 public void testOrientationChangeLogging() {
901 MetricsLogger mockLogger = mock(MetricsLogger.class);
902 Configuration oldConfig = new Configuration();
903 oldConfig.orientation = Configuration.ORIENTATION_LANDSCAPE;
904
905 Configuration newConfig = new Configuration();
906 newConfig.orientation = Configuration.ORIENTATION_PORTRAIT;
Riddle Hsu73f53572019-09-23 23:13:01 +0800907 final DisplayContent displayContent = createNewDisplay();
Susi Kharraz-Post9893b8c2019-02-12 14:21:29 -0500908 Mockito.doReturn(mockLogger).when(displayContent).getMetricsLogger();
909 Mockito.doReturn(oldConfig).doReturn(newConfig).when(displayContent).getConfiguration();
910
911 displayContent.onConfigurationChanged(newConfig);
912
913 ArgumentCaptor<LogMaker> logMakerCaptor = ArgumentCaptor.forClass(LogMaker.class);
914 verify(mockLogger).write(logMakerCaptor.capture());
915 assertThat(logMakerCaptor.getValue().getCategory(),
916 is(MetricsProto.MetricsEvent.ACTION_PHONE_ORIENTATION_CHANGED));
917 assertThat(logMakerCaptor.getValue().getSubtype(),
918 is(Configuration.ORIENTATION_PORTRAIT));
919 }
920
Evan Rosky69cace42019-09-20 16:28:13 -0700921 @Test
922 public void testRemoteRotation() {
923 DisplayContent dc = createNewDisplay();
924
925 final DisplayRotation dr = dc.getDisplayRotation();
926 Mockito.doCallRealMethod().when(dr).updateRotationUnchecked(anyBoolean());
927 Mockito.doReturn(ROTATION_90).when(dr).rotationForOrientation(anyInt(), anyInt());
928 final boolean[] continued = new boolean[1];
929 spyOn(dc.mActivityDisplay);
930 Mockito.doAnswer(
931 invocation -> {
932 continued[0] = true;
933 return true;
934 }).when(dc.mActivityDisplay).updateDisplayOverrideConfigurationLocked();
935 final boolean[] called = new boolean[1];
936 mWm.mDisplayRotationController =
937 new IDisplayWindowRotationController.Stub() {
938 @Override
939 public void onRotateDisplay(int displayId, int fromRotation, int toRotation,
940 IDisplayWindowRotationCallback callback) {
941 called[0] = true;
942
943 try {
944 callback.continueRotateDisplay(toRotation, null);
945 } catch (RemoteException e) {
946 assertTrue(false);
947 }
948 }
949 };
950
951 // kill any existing rotation animation (vestigial from test setup).
952 dc.setRotationAnimation(null);
953
954 mWm.updateRotation(true /* alwaysSendConfiguration */, false /* forceRelayout */);
955 assertTrue(called[0]);
956 waitUntilHandlersIdle();
957 assertTrue(continued[0]);
958 }
959
Riddle Hsua4d6fa22018-08-11 00:50:39 +0800960 private boolean isOptionsPanelAtRight(int displayId) {
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700961 return (mWm.getPreferredOptionsPanelGravity(displayId) & Gravity.RIGHT) == Gravity.RIGHT;
Riddle Hsua4d6fa22018-08-11 00:50:39 +0800962 }
963
Bryce Lee27cec322017-03-21 09:41:37 -0700964 private static void verifySizes(DisplayContent displayContent, int expectedBaseWidth,
965 int expectedBaseHeight, int expectedBaseDensity) {
966 assertEquals(displayContent.mBaseDisplayWidth, expectedBaseWidth);
967 assertEquals(displayContent.mBaseDisplayHeight, expectedBaseHeight);
968 assertEquals(displayContent.mBaseDisplayDensity, expectedBaseDensity);
969 }
970
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800971 private void updateFocusedWindow() {
Riddle Hsu73f53572019-09-23 23:13:01 +0800972 mWm.updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, false /* updateInputWindows */);
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800973 }
974
Riddle Hsu654a6f92018-07-13 22:59:36 +0800975 /**
976 * Create DisplayContent that does not update display base/initial values from device to keep
977 * the values set by test.
978 */
979 private DisplayContent createDisplayNoUpdateDisplayInfo() {
Riddle Hsu73f53572019-09-23 23:13:01 +0800980 final DisplayContent displayContent = createNewDisplay();
Riddle Hsu654a6f92018-07-13 22:59:36 +0800981 doNothing().when(displayContent).updateDisplayInfo();
982 return displayContent;
983 }
984
Adrian Roos0f9368c2018-04-08 10:59:08 -0700985 private void assertForAllWindowsOrder(List<WindowState> expectedWindowsBottomToTop) {
986 final LinkedList<WindowState> actualWindows = new LinkedList<>();
Wale Ogunwale34247952017-02-19 11:57:53 -0800987
988 // Test forward traversal.
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700989 mDisplayContent.forAllWindows(actualWindows::addLast, false /* traverseTopToBottom */);
Adrian Roos0f9368c2018-04-08 10:59:08 -0700990 assertThat("bottomToTop", actualWindows, is(expectedWindowsBottomToTop));
991
992 actualWindows.clear();
Wale Ogunwale34247952017-02-19 11:57:53 -0800993
994 // Test backward traversal.
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700995 mDisplayContent.forAllWindows(actualWindows::addLast, true /* traverseTopToBottom */);
Adrian Roos0f9368c2018-04-08 10:59:08 -0700996 assertThat("topToBottom", actualWindows, is(reverseList(expectedWindowsBottomToTop)));
997 }
998
999 private static List<WindowState> reverseList(List<WindowState> list) {
1000 final ArrayList<WindowState> result = new ArrayList<>(list);
1001 Collections.reverse(result);
1002 return result;
Wale Ogunwale34247952017-02-19 11:57:53 -08001003 }
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -07001004
Arthur Hungbe5ce212018-09-13 18:41:56 +08001005 private void tapOnDisplay(final DisplayContent dc) {
1006 final DisplayMetrics dm = dc.getDisplayMetrics();
1007 final float x = dm.widthPixels / 2;
1008 final float y = dm.heightPixels / 2;
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -07001009 final long downTime = SystemClock.uptimeMillis();
1010 final long eventTime = SystemClock.uptimeMillis() + 100;
Arthur Hungbe5ce212018-09-13 18:41:56 +08001011 // sending ACTION_DOWN
1012 final MotionEvent downEvent = MotionEvent.obtain(
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -07001013 downTime,
Arthur Hungbe5ce212018-09-13 18:41:56 +08001014 downTime,
1015 MotionEvent.ACTION_DOWN,
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -07001016 x,
1017 y,
Arthur Hungbe5ce212018-09-13 18:41:56 +08001018 0 /*metaState*/);
1019 downEvent.setDisplayId(dc.getDisplayId());
1020 dc.mTapDetector.onPointerEvent(downEvent);
1021
1022 // sending ACTION_UP
1023 final MotionEvent upEvent = MotionEvent.obtain(
1024 downTime,
1025 eventTime,
1026 MotionEvent.ACTION_UP,
1027 x,
1028 y,
1029 0 /*metaState*/);
1030 upEvent.setDisplayId(dc.getDisplayId());
1031 dc.mTapDetector.onPointerEvent(upEvent);
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -07001032 }
Wale Ogunwaleb783fd82016-11-04 09:51:54 -07001033}