blob: 3826fac22b05b7fd32161bffd936d6f7ed89a9fd [file] [log] [blame]
Wale Ogunwaleb783fd82016-11-04 09:51:54 -07001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -070014 * limitations under the License.
Wale Ogunwaleb783fd82016-11-04 09:51:54 -070015 */
16
17package com.android.server.wm;
18
Andrii Kulian92c9a942017-10-10 00:41:41 -070019import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
20import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
21import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
Tiger Huang51c5a1d2018-12-11 20:24:51 +080022import static android.os.Build.VERSION_CODES.P;
23import static android.os.Build.VERSION_CODES.Q;
Wale Ogunwale34247952017-02-19 11:57:53 -080024import static android.view.Display.DEFAULT_DISPLAY;
Issei Suzuki43190bd2018-08-20 17:28:41 +020025import static android.view.DisplayCutout.BOUNDS_POSITION_LEFT;
26import static android.view.DisplayCutout.BOUNDS_POSITION_TOP;
Adrian Roos24264212018-02-19 16:26:15 +010027import static android.view.DisplayCutout.fromBoundingRect;
Wale Ogunwale34247952017-02-19 11:57:53 -080028import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
29import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
30import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
Andrii Kulian92c9a942017-10-10 00:41:41 -070031import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
Wale Ogunwale34247952017-02-19 11:57:53 -080032import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION;
Brett Chabota26eda92018-07-23 13:08:30 -070033
Garfield Tan90b04282018-12-11 14:04:42 -080034import static com.android.dx.mockito.inline.extended.ExtendedMockito.any;
35import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyBoolean;
Tadashi G. Takaokabf0d57b2018-11-19 16:09:58 +090036import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
Garfield Tan90b04282018-12-11 14:04:42 -080037import static com.android.dx.mockito.inline.extended.ExtendedMockito.eq;
38import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
39import static com.android.dx.mockito.inline.extended.ExtendedMockito.never;
40import static com.android.dx.mockito.inline.extended.ExtendedMockito.same;
Tadashi G. Takaokabf0d57b2018-11-19 16:09:58 +090041import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy;
42import static com.android.dx.mockito.inline.extended.ExtendedMockito.times;
43import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
David Stevens46939562017-03-24 13:04:00 -070044import static com.android.server.wm.WindowContainer.POSITION_TOP;
Tiger Huang1e5b10a2018-07-30 20:19:51 +080045import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_NORMAL;
chaviwebcbc342018-02-07 13:19:00 -080046
Adrian Roos5251b1d2018-03-23 18:57:43 +010047import static org.hamcrest.Matchers.is;
Wale Ogunwale34247952017-02-19 11:57:53 -080048import static org.junit.Assert.assertEquals;
Andrii Kulianf0379de2018-03-14 16:24:07 -070049import static org.junit.Assert.assertFalse;
Arthur Hungbe5ce212018-09-13 18:41:56 +080050import static org.junit.Assert.assertNotNull;
lumarkff0ab692018-11-05 20:32:30 +080051import static org.junit.Assert.assertNull;
Adrian Roos5251b1d2018-03-23 18:57:43 +010052import static org.junit.Assert.assertThat;
Wale Ogunwale34247952017-02-19 11:57:53 -080053import static org.junit.Assert.assertTrue;
54
Andrii Kulian92c9a942017-10-10 00:41:41 -070055import android.annotation.SuppressLint;
Andrii Kuliand68501e2017-01-10 22:57:27 -080056import android.content.res.Configuration;
Adrian Roos1cf585052018-01-03 18:43:27 +010057import android.graphics.Rect;
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -070058import android.os.SystemClock;
Wale Ogunwaleb783fd82016-11-04 09:51:54 -070059import android.platform.test.annotations.Presubmit;
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -070060import android.util.DisplayMetrics;
Adrian Roos1cf585052018-01-03 18:43:27 +010061import android.view.DisplayCutout;
Riddle Hsua4d6fa22018-08-11 00:50:39 +080062import android.view.Gravity;
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -070063import android.view.MotionEvent;
Adrian Roos1cf585052018-01-03 18:43:27 +010064import android.view.Surface;
Wale Ogunwaleb783fd82016-11-04 09:51:54 -070065
Brett Chabota26eda92018-07-23 13:08:30 -070066import androidx.test.filters.FlakyTest;
67import androidx.test.filters.SmallTest;
Brett Chabota26eda92018-07-23 13:08:30 -070068
Garfield Tan90b04282018-12-11 14:04:42 -080069import com.android.dx.mockito.inline.extended.ExtendedMockito;
Adrian Roos6a4fa0e2018-03-05 19:50:16 +010070import com.android.server.wm.utils.WmDisplayCutout;
71
Brett Chabota26eda92018-07-23 13:08:30 -070072import org.junit.Test;
Garfield Tan90b04282018-12-11 14:04:42 -080073import org.mockito.ArgumentCaptor;
Brett Chabota26eda92018-07-23 13:08:30 -070074
Adrian Roos0f9368c2018-04-08 10:59:08 -070075import java.util.ArrayList;
Wale Ogunwale34247952017-02-19 11:57:53 -080076import java.util.Arrays;
Adrian Roos0f9368c2018-04-08 10:59:08 -070077import java.util.Collections;
Wale Ogunwale34247952017-02-19 11:57:53 -080078import java.util.LinkedList;
79import java.util.List;
Wale Ogunwaleb783fd82016-11-04 09:51:54 -070080
81/**
82 * Tests for the {@link DisplayContent} class.
83 *
84 * Build/Install/Run:
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -070085 * atest FrameworksServicesTests:DisplayContentTests
Wale Ogunwaleb783fd82016-11-04 09:51:54 -070086 */
87@SmallTest
88@Presubmit
Wale Ogunwale44fbdf52016-11-16 10:18:45 -080089public class DisplayContentTests extends WindowTestsBase {
Wale Ogunwaleb783fd82016-11-04 09:51:54 -070090
91 @Test
Adrian Roos0f9368c2018-04-08 10:59:08 -070092 @FlakyTest(bugId = 77772044)
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -070093 public void testForAllWindows() {
Wale Ogunwale3c1170d2016-12-02 14:44:52 -080094 final WindowState exitingAppWindow = createWindow(null, TYPE_BASE_APPLICATION,
Wale Ogunwale11cc5162017-04-25 20:29:13 -070095 mDisplayContent, "exiting app");
Wale Ogunwaleb783fd82016-11-04 09:51:54 -070096 final AppWindowToken exitingAppToken = exitingAppWindow.mAppToken;
97 exitingAppToken.mIsExiting = true;
Bryce Lee6d410262017-02-28 15:30:17 -080098 exitingAppToken.getTask().mStack.mExitingAppTokens.add(exitingAppToken);
Wale Ogunwaleb783fd82016-11-04 09:51:54 -070099
Wale Ogunwale34247952017-02-19 11:57:53 -0800100 assertForAllWindowsOrder(Arrays.asList(
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700101 mWallpaperWindow,
Wale Ogunwale34247952017-02-19 11:57:53 -0800102 exitingAppWindow,
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700103 mChildAppWindowBelow,
104 mAppWindow,
105 mChildAppWindowAbove,
106 mDockedDividerWindow,
107 mStatusBarWindow,
108 mNavBarWindow,
109 mImeWindow,
110 mImeDialogWindow));
Wale Ogunwale3c1170d2016-12-02 14:44:52 -0800111 }
112
113 @Test
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700114 public void testForAllWindows_WithAppImeTarget() {
Wale Ogunwale3c1170d2016-12-02 14:44:52 -0800115 final WindowState imeAppTarget =
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700116 createWindow(null, TYPE_BASE_APPLICATION, mDisplayContent, "imeAppTarget");
Wale Ogunwale3c1170d2016-12-02 14:44:52 -0800117
lumarkff0ab692018-11-05 20:32:30 +0800118 mDisplayContent.mInputMethodTarget = imeAppTarget;
Wale Ogunwale3c1170d2016-12-02 14:44:52 -0800119
Wale Ogunwale34247952017-02-19 11:57:53 -0800120 assertForAllWindowsOrder(Arrays.asList(
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700121 mWallpaperWindow,
122 mChildAppWindowBelow,
123 mAppWindow,
124 mChildAppWindowAbove,
Wale Ogunwale34247952017-02-19 11:57:53 -0800125 imeAppTarget,
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700126 mImeWindow,
127 mImeDialogWindow,
128 mDockedDividerWindow,
129 mStatusBarWindow,
130 mNavBarWindow));
Wale Ogunwale34247952017-02-19 11:57:53 -0800131 }
Wale Ogunwale3c1170d2016-12-02 14:44:52 -0800132
Wale Ogunwale34247952017-02-19 11:57:53 -0800133 @Test
lumarkff0ab692018-11-05 20:32:30 +0800134 public void testForAllWindows_WithChildWindowImeTarget() throws Exception {
135 mDisplayContent.mInputMethodTarget = mChildAppWindowAbove;
Wale Ogunwale3c1170d2016-12-02 14:44:52 -0800136
Wale Ogunwale34247952017-02-19 11:57:53 -0800137 assertForAllWindowsOrder(Arrays.asList(
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700138 mWallpaperWindow,
139 mChildAppWindowBelow,
140 mAppWindow,
141 mChildAppWindowAbove,
142 mImeWindow,
143 mImeDialogWindow,
144 mDockedDividerWindow,
145 mStatusBarWindow,
146 mNavBarWindow));
Wale Ogunwaleb783fd82016-11-04 09:51:54 -0700147 }
Wale Ogunwale5d7e7f12016-12-12 14:47:05 -0800148
149 @Test
lumarkff0ab692018-11-05 20:32:30 +0800150 public void testForAllWindows_WithStatusBarImeTarget() throws Exception {
151 mDisplayContent.mInputMethodTarget = mStatusBarWindow;
Wale Ogunwale6ce0fb82016-12-13 14:24:00 -0800152
Wale Ogunwale34247952017-02-19 11:57:53 -0800153 assertForAllWindowsOrder(Arrays.asList(
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700154 mWallpaperWindow,
155 mChildAppWindowBelow,
156 mAppWindow,
157 mChildAppWindowAbove,
158 mDockedDividerWindow,
159 mStatusBarWindow,
160 mImeWindow,
161 mImeDialogWindow,
162 mNavBarWindow));
Wale Ogunwale6ce0fb82016-12-13 14:24:00 -0800163 }
164
165 @Test
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700166 public void testForAllWindows_WithInBetweenWindowToken() {
Wale Ogunwale5d7e7f12016-12-12 14:47:05 -0800167 // This window is set-up to be z-ordered between some windows that go in the same token like
168 // the nav bar and status bar.
169 final WindowState voiceInteractionWindow = createWindow(null, TYPE_VOICE_INTERACTION,
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700170 mDisplayContent, "voiceInteractionWindow");
Wale Ogunwale5d7e7f12016-12-12 14:47:05 -0800171
Wale Ogunwale34247952017-02-19 11:57:53 -0800172 assertForAllWindowsOrder(Arrays.asList(
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700173 mWallpaperWindow,
174 mChildAppWindowBelow,
175 mAppWindow,
176 mChildAppWindowAbove,
177 mDockedDividerWindow,
Wale Ogunwale34247952017-02-19 11:57:53 -0800178 voiceInteractionWindow,
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700179 mStatusBarWindow,
180 mNavBarWindow,
181 mImeWindow,
182 mImeDialogWindow));
Wale Ogunwale34247952017-02-19 11:57:53 -0800183 }
Wale Ogunwale5d7e7f12016-12-12 14:47:05 -0800184
Wale Ogunwale34247952017-02-19 11:57:53 -0800185 @Test
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700186 public void testComputeImeTarget() {
Wale Ogunwale34247952017-02-19 11:57:53 -0800187 // Verify that an app window can be an ime target.
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700188 final WindowState appWin = createWindow(null, TYPE_APPLICATION, mDisplayContent, "appWin");
Wale Ogunwale34247952017-02-19 11:57:53 -0800189 appWin.setHasSurface(true);
190 assertTrue(appWin.canBeImeTarget());
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700191 WindowState imeTarget = mDisplayContent.computeImeTarget(false /* updateImeTarget */);
Wale Ogunwale34247952017-02-19 11:57:53 -0800192 assertEquals(appWin, imeTarget);
chaviwebcbc342018-02-07 13:19:00 -0800193 appWin.mHidden = false;
Wale Ogunwale5d7e7f12016-12-12 14:47:05 -0800194
Wale Ogunwale34247952017-02-19 11:57:53 -0800195 // Verify that an child window can be an ime target.
196 final WindowState childWin = createWindow(appWin,
197 TYPE_APPLICATION_ATTACHED_DIALOG, "childWin");
198 childWin.setHasSurface(true);
199 assertTrue(childWin.canBeImeTarget());
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700200 imeTarget = mDisplayContent.computeImeTarget(false /* updateImeTarget */);
Wale Ogunwale34247952017-02-19 11:57:53 -0800201 assertEquals(childWin, imeTarget);
Wale Ogunwale5d7e7f12016-12-12 14:47:05 -0800202 }
Andrii Kulian6cc1a1d2016-12-27 23:52:59 -0800203
Andrii Kuliand68501e2017-01-10 22:57:27 -0800204 /**
205 * This tests stack movement between displays and proper stack's, task's and app token's display
206 * container references updates.
207 */
Andrii Kulian6cc1a1d2016-12-27 23:52:59 -0800208 @Test
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700209 public void testMoveStackBetweenDisplays() {
Andrii Kulian367ff7f2017-01-25 19:45:34 -0800210 // Create a second display.
211 final DisplayContent dc = createNewDisplay();
Andrii Kulian6cc1a1d2016-12-27 23:52:59 -0800212
213 // Add stack with activity.
214 final TaskStack stack = createTaskStackOnDisplay(dc);
215 assertEquals(dc.getDisplayId(), stack.getDisplayContent().getDisplayId());
216 assertEquals(dc, stack.getParent().getParent());
217 assertEquals(dc, stack.getDisplayContent());
218
219 final Task task = createTaskInStack(stack, 0 /* userId */);
chaviw97d28202018-02-27 16:23:53 -0800220 final WindowTestUtils.TestAppWindowToken token = WindowTestUtils.createTestAppWindowToken(
221 dc);
Andrii Kulian6cc1a1d2016-12-27 23:52:59 -0800222 task.addChild(token, 0);
223 assertEquals(dc, task.getDisplayContent());
224 assertEquals(dc, token.getDisplayContent());
225
226 // Move stack to first display.
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700227 mDisplayContent.moveStackToDisplay(stack, true /* onTop */);
228 assertEquals(mDisplayContent.getDisplayId(), stack.getDisplayContent().getDisplayId());
229 assertEquals(mDisplayContent, stack.getParent().getParent());
230 assertEquals(mDisplayContent, stack.getDisplayContent());
231 assertEquals(mDisplayContent, task.getDisplayContent());
232 assertEquals(mDisplayContent, token.getDisplayContent());
Andrii Kulian6cc1a1d2016-12-27 23:52:59 -0800233 }
Andrii Kuliand68501e2017-01-10 22:57:27 -0800234
235 /**
236 * This tests override configuration updates for display content.
237 */
238 @Test
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700239 public void testDisplayOverrideConfigUpdate() {
Evan Roskydfe3da72018-10-26 17:21:06 -0700240 final Configuration currentOverrideConfig =
241 mDisplayContent.getRequestedOverrideConfiguration();
Andrii Kuliand68501e2017-01-10 22:57:27 -0800242
243 // Create new, slightly changed override configuration and apply it to the display.
244 final Configuration newOverrideConfig = new Configuration(currentOverrideConfig);
245 newOverrideConfig.densityDpi += 120;
246 newOverrideConfig.fontScale += 0.3;
247
Evan Roskye747c3e2018-10-30 20:06:41 -0700248 mWm.setNewDisplayOverrideConfiguration(newOverrideConfig, mDisplayContent);
Andrii Kuliand68501e2017-01-10 22:57:27 -0800249
250 // Check that override config is applied.
Evan Roskydfe3da72018-10-26 17:21:06 -0700251 assertEquals(newOverrideConfig, mDisplayContent.getRequestedOverrideConfiguration());
Andrii Kulian367ff7f2017-01-25 19:45:34 -0800252 }
253
254 /**
255 * This tests global configuration updates when default display config is updated.
256 */
257 @Test
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700258 public void testDefaultDisplayOverrideConfigUpdate() {
Evan Roskye747c3e2018-10-30 20:06:41 -0700259 DisplayContent defaultDisplay = mWm.mRoot.getDisplayContent(DEFAULT_DISPLAY);
260 final Configuration currentConfig = defaultDisplay.getConfiguration();
Andrii Kulian367ff7f2017-01-25 19:45:34 -0800261
262 // Create new, slightly changed override configuration and apply it to the display.
Andrii Kuliana95bfff2017-03-30 19:00:41 -0700263 final Configuration newOverrideConfig = new Configuration(currentConfig);
Andrii Kulian367ff7f2017-01-25 19:45:34 -0800264 newOverrideConfig.densityDpi += 120;
265 newOverrideConfig.fontScale += 0.3;
266
Evan Roskye747c3e2018-10-30 20:06:41 -0700267 mWm.setNewDisplayOverrideConfiguration(newOverrideConfig, defaultDisplay);
Andrii Kuliand68501e2017-01-10 22:57:27 -0800268
269 // Check that global configuration is updated, as we've updated default display's config.
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700270 Configuration globalConfig = mWm.mRoot.getConfiguration();
Andrii Kuliand68501e2017-01-10 22:57:27 -0800271 assertEquals(newOverrideConfig.densityDpi, globalConfig.densityDpi);
272 assertEquals(newOverrideConfig.fontScale, globalConfig.fontScale, 0.1 /* delta */);
Andrii Kulian367ff7f2017-01-25 19:45:34 -0800273
274 // Return back to original values.
Evan Roskye747c3e2018-10-30 20:06:41 -0700275 mWm.setNewDisplayOverrideConfiguration(currentConfig, defaultDisplay);
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700276 globalConfig = mWm.mRoot.getConfiguration();
Andrii Kuliana95bfff2017-03-30 19:00:41 -0700277 assertEquals(currentConfig.densityDpi, globalConfig.densityDpi);
278 assertEquals(currentConfig.fontScale, globalConfig.fontScale, 0.1 /* delta */);
Andrii Kuliand68501e2017-01-10 22:57:27 -0800279 }
Wale Ogunwale34247952017-02-19 11:57:53 -0800280
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -0700281 /**
282 * Tests tapping on a stack in different display results in window gaining focus.
283 */
284 @Test
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700285 public void testInputEventBringsCorrectDisplayInFocus() {
286 DisplayContent dc0 = mWm.getDefaultDisplayContentLocked();
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -0700287 // Create a second display
288 final DisplayContent dc1 = createNewDisplay();
289
290 // Add stack with activity.
291 final TaskStack stack0 = createTaskStackOnDisplay(dc0);
292 final Task task0 = createTaskInStack(stack0, 0 /* userId */);
293 final WindowTestUtils.TestAppWindowToken token =
chaviw97d28202018-02-27 16:23:53 -0800294 WindowTestUtils.createTestAppWindowToken(dc0);
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -0700295 task0.addChild(token, 0);
Arthur Hungbe5ce212018-09-13 18:41:56 +0800296 dc0.configureDisplayPolicy();
297 assertNotNull(dc0.mTapDetector);
298
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -0700299 final TaskStack stack1 = createTaskStackOnDisplay(dc1);
300 final Task task1 = createTaskInStack(stack1, 0 /* userId */);
301 final WindowTestUtils.TestAppWindowToken token1 =
chaviw97d28202018-02-27 16:23:53 -0800302 WindowTestUtils.createTestAppWindowToken(dc0);
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -0700303 task1.addChild(token1, 0);
Arthur Hungbe5ce212018-09-13 18:41:56 +0800304 dc1.configureDisplayPolicy();
305 assertNotNull(dc1.mTapDetector);
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -0700306
Arthur Hungbe5ce212018-09-13 18:41:56 +0800307 // tap on primary display.
308 tapOnDisplay(dc0);
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -0700309 // Check focus is on primary display.
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700310 assertEquals(mWm.mRoot.getTopFocusedDisplayContent().mCurrentFocus,
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800311 dc0.findFocusedWindow());
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -0700312
Arthur Hungbe5ce212018-09-13 18:41:56 +0800313 // Tap on secondary display.
314 tapOnDisplay(dc1);
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -0700315 // Check focus is on secondary.
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700316 assertEquals(mWm.mRoot.getTopFocusedDisplayContent().mCurrentFocus,
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800317 dc1.findFocusedWindow());
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -0700318 }
319
David Stevens46939562017-03-24 13:04:00 -0700320 @Test
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700321 public void testFocusedWindowMultipleDisplays() {
Tiger Huang51c5a1d2018-12-11 20:24:51 +0800322 doTestFocusedWindowMultipleDisplays(false /* perDisplayFocusEnabled */, Q);
323 }
324
325 @Test
326 public void testFocusedWindowMultipleDisplaysPerDisplayFocusEnabled() {
327 doTestFocusedWindowMultipleDisplays(true /* perDisplayFocusEnabled */, Q);
328 }
329
330 @Test
331 public void testFocusedWindowMultipleDisplaysPerDisplayFocusEnabledLegacyApp() {
332 doTestFocusedWindowMultipleDisplays(true /* perDisplayFocusEnabled */, P);
333 }
334
335 private void doTestFocusedWindowMultipleDisplays(boolean perDisplayFocusEnabled,
336 int targetSdk) {
337 mWm.mPerDisplayFocusEnabled = perDisplayFocusEnabled;
338
Andrii Kulian0214ed92017-05-16 13:44:05 -0700339 // Create a focusable window and check that focus is calculated correctly
David Stevens46939562017-03-24 13:04:00 -0700340 final WindowState window1 =
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700341 createWindow(null, TYPE_BASE_APPLICATION, mDisplayContent, "window1");
Tiger Huang51c5a1d2018-12-11 20:24:51 +0800342 window1.mAppToken.mTargetSdk = targetSdk;
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800343 updateFocusedWindow();
344 assertTrue(window1.isFocused());
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700345 assertEquals(window1, mWm.mRoot.getTopFocusedDisplayContent().mCurrentFocus);
David Stevens46939562017-03-24 13:04:00 -0700346
347 // Check that a new display doesn't affect focus
348 final DisplayContent dc = createNewDisplay();
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800349 updateFocusedWindow();
350 assertTrue(window1.isFocused());
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700351 assertEquals(window1, mWm.mRoot.getTopFocusedDisplayContent().mCurrentFocus);
David Stevens46939562017-03-24 13:04:00 -0700352
353 // Add a window to the second display, and it should be focused
354 final WindowState window2 = createWindow(null, TYPE_BASE_APPLICATION, dc, "window2");
Tiger Huang51c5a1d2018-12-11 20:24:51 +0800355 window2.mAppToken.mTargetSdk = targetSdk;
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800356 updateFocusedWindow();
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800357 assertTrue(window2.isFocused());
Tiger Huang51c5a1d2018-12-11 20:24:51 +0800358 assertEquals(perDisplayFocusEnabled && targetSdk >= Q, window1.isFocused());
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700359 assertEquals(window2, mWm.mRoot.getTopFocusedDisplayContent().mCurrentFocus);
David Stevens46939562017-03-24 13:04:00 -0700360
Tiger Huang51c5a1d2018-12-11 20:24:51 +0800361 // Move the first window to top including parents, and make sure focus is updated
David Stevens46939562017-03-24 13:04:00 -0700362 window1.getParent().positionChildAt(POSITION_TOP, window1, true);
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800363 updateFocusedWindow();
364 assertTrue(window1.isFocused());
Tiger Huang51c5a1d2018-12-11 20:24:51 +0800365 assertEquals(perDisplayFocusEnabled && targetSdk >= Q, window2.isFocused());
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700366 assertEquals(window1, mWm.mRoot.getTopFocusedDisplayContent().mCurrentFocus);
Adrian Roos4163d622018-05-22 16:56:35 +0200367 }
368
Bryce Lee27cec322017-03-21 09:41:37 -0700369 /**
370 * This tests setting the maximum ui width on a display.
371 */
372 @Test
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700373 public void testMaxUiWidth() {
Riddle Hsu654a6f92018-07-13 22:59:36 +0800374 // Prevent base display metrics for test from being updated to the value of real display.
375 final DisplayContent displayContent = createDisplayNoUpdateDisplayInfo();
Bryce Lee27cec322017-03-21 09:41:37 -0700376 final int baseWidth = 1440;
377 final int baseHeight = 2560;
378 final int baseDensity = 300;
379
Riddle Hsu654a6f92018-07-13 22:59:36 +0800380 displayContent.updateBaseDisplayMetrics(baseWidth, baseHeight, baseDensity);
Bryce Lee27cec322017-03-21 09:41:37 -0700381
382 final int maxWidth = 300;
383 final int resultingHeight = (maxWidth * baseHeight) / baseWidth;
384 final int resultingDensity = (maxWidth * baseDensity) / baseWidth;
385
Riddle Hsu654a6f92018-07-13 22:59:36 +0800386 displayContent.setMaxUiWidth(maxWidth);
387 verifySizes(displayContent, maxWidth, resultingHeight, resultingDensity);
Bryce Lee27cec322017-03-21 09:41:37 -0700388
389 // Assert setting values again does not change;
Riddle Hsu654a6f92018-07-13 22:59:36 +0800390 displayContent.updateBaseDisplayMetrics(baseWidth, baseHeight, baseDensity);
391 verifySizes(displayContent, maxWidth, resultingHeight, resultingDensity);
Bryce Lee27cec322017-03-21 09:41:37 -0700392
393 final int smallerWidth = 200;
394 final int smallerHeight = 400;
395 final int smallerDensity = 100;
396
397 // Specify smaller dimension, verify that it is honored
Riddle Hsu654a6f92018-07-13 22:59:36 +0800398 displayContent.updateBaseDisplayMetrics(smallerWidth, smallerHeight, smallerDensity);
399 verifySizes(displayContent, smallerWidth, smallerHeight, smallerDensity);
Bryce Lee27cec322017-03-21 09:41:37 -0700400
401 // Verify that setting the max width to a greater value than the base width has no effect
Riddle Hsu654a6f92018-07-13 22:59:36 +0800402 displayContent.setMaxUiWidth(maxWidth);
403 verifySizes(displayContent, smallerWidth, smallerHeight, smallerDensity);
Bryce Lee27cec322017-03-21 09:41:37 -0700404 }
405
Andrii Kulian92c9a942017-10-10 00:41:41 -0700406 @Test
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700407 public void testDisplayCutout_rot0() {
408 synchronized (mWm.getWindowManagerLock()) {
Adrian Roos1cf585052018-01-03 18:43:27 +0100409 final DisplayContent dc = createNewDisplay();
410 dc.mInitialDisplayWidth = 200;
411 dc.mInitialDisplayHeight = 400;
Adrian Roos24264212018-02-19 16:26:15 +0100412 Rect r = new Rect(80, 0, 120, 10);
Adrian Roos6a4fa0e2018-03-05 19:50:16 +0100413 final DisplayCutout cutout = new WmDisplayCutout(
Issei Suzuki43190bd2018-08-20 17:28:41 +0200414 fromBoundingRect(r.left, r.top, r.right, r.bottom, BOUNDS_POSITION_TOP), null)
Adrian Roos6a4fa0e2018-03-05 19:50:16 +0100415 .computeSafeInsets(200, 400).getDisplayCutout();
Adrian Roos1cf585052018-01-03 18:43:27 +0100416
417 dc.mInitialDisplayCutout = cutout;
418 dc.setRotation(Surface.ROTATION_0);
419 dc.computeScreenConfiguration(new Configuration()); // recomputes dc.mDisplayInfo.
420
421 assertEquals(cutout, dc.getDisplayInfo().displayCutout);
422 }
423 }
424
425 @Test
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700426 public void testDisplayCutout_rot90() {
427 synchronized (mWm.getWindowManagerLock()) {
Riddle Hsu654a6f92018-07-13 22:59:36 +0800428 // Prevent mInitialDisplayCutout from being updated from real display (e.g. null
429 // if the device has no cutout).
430 final DisplayContent dc = createDisplayNoUpdateDisplayInfo();
431 // Rotation may use real display info to compute bound, so here also uses the
432 // same width and height.
433 final int displayWidth = dc.mInitialDisplayWidth;
434 final int displayHeight = dc.mInitialDisplayHeight;
435 final int cutoutWidth = 40;
436 final int cutoutHeight = 10;
437 final int left = (displayWidth - cutoutWidth) / 2;
438 final int top = 0;
439 final int right = (displayWidth + cutoutWidth) / 2;
440 final int bottom = cutoutHeight;
441
442 final Rect r1 = new Rect(left, top, right, bottom);
Adrian Roos6a4fa0e2018-03-05 19:50:16 +0100443 final DisplayCutout cutout = new WmDisplayCutout(
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700444 fromBoundingRect(r1.left, r1.top, r1.right, r1.bottom, BOUNDS_POSITION_TOP),
445 null)
Riddle Hsu654a6f92018-07-13 22:59:36 +0800446 .computeSafeInsets(displayWidth, displayHeight).getDisplayCutout();
Adrian Roos1cf585052018-01-03 18:43:27 +0100447
448 dc.mInitialDisplayCutout = cutout;
449 dc.setRotation(Surface.ROTATION_90);
450 dc.computeScreenConfiguration(new Configuration()); // recomputes dc.mDisplayInfo.
451
Riddle Hsu654a6f92018-07-13 22:59:36 +0800452 // ----o---------- -------------
453 // | | | | |
454 // | ------o | o---
455 // | | | |
456 // | | -> | |
457 // | | ---o
458 // | | |
459 // | | -------------
460 final Rect r = new Rect(top, left, bottom, right);
Adrian Roos6a4fa0e2018-03-05 19:50:16 +0100461 assertEquals(new WmDisplayCutout(
Issei Suzuki43190bd2018-08-20 17:28:41 +0200462 fromBoundingRect(r.left, r.top, r.right, r.bottom, BOUNDS_POSITION_LEFT), null)
Riddle Hsu654a6f92018-07-13 22:59:36 +0800463 .computeSafeInsets(displayHeight, displayWidth)
464 .getDisplayCutout(), dc.getDisplayInfo().displayCutout);
Adrian Roos1cf585052018-01-03 18:43:27 +0100465 }
466 }
467
468 @Test
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700469 public void testLayoutSeq_assignedDuringLayout() {
470 synchronized (mWm.getWindowManagerLock()) {
Adrian Roos5251b1d2018-03-23 18:57:43 +0100471
472 final DisplayContent dc = createNewDisplay();
473 final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, dc, "w");
474
475 dc.setLayoutNeeded();
476 dc.performLayout(true /* initial */, false /* updateImeWindows */);
477
478 assertThat(win.mLayoutSeq, is(dc.mLayoutSeq));
479 }
480 }
481
482 @Test
Andrii Kulian92c9a942017-10-10 00:41:41 -0700483 @SuppressLint("InlinedApi")
484 public void testOrientationDefinedByKeyguard() {
485 final DisplayContent dc = createNewDisplay();
Garfield Tan90b04282018-12-11 14:04:42 -0800486
487 // When display content is created its configuration is not yet initialized, which could
488 // cause unnecessary configuration propagation, so initialize it here.
489 final Configuration config = new Configuration();
490 dc.computeScreenConfiguration(config);
491 dc.onRequestedOverrideConfigurationChanged(config);
492
Andrii Kulian92c9a942017-10-10 00:41:41 -0700493 // Create a window that requests landscape orientation. It will define device orientation
494 // by default.
495 final WindowState window = createWindow(null /* parent */, TYPE_BASE_APPLICATION, dc, "w");
496 window.mAppToken.setOrientation(SCREEN_ORIENTATION_LANDSCAPE);
497
498 final WindowState keyguard = createWindow(null, TYPE_STATUS_BAR, dc, "keyguard");
499 keyguard.mHasSurface = true;
500 keyguard.mAttrs.screenOrientation = SCREEN_ORIENTATION_UNSPECIFIED;
501
502 assertEquals("Screen orientation must be defined by the app window by default",
503 SCREEN_ORIENTATION_LANDSCAPE, dc.getOrientation());
504
505 keyguard.mAttrs.screenOrientation = SCREEN_ORIENTATION_PORTRAIT;
506 assertEquals("Visible keyguard must influence device orientation",
507 SCREEN_ORIENTATION_PORTRAIT, dc.getOrientation());
508
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700509 mWm.setKeyguardGoingAway(true);
Andrii Kulian92c9a942017-10-10 00:41:41 -0700510 assertEquals("Keyguard that is going away must not influence device orientation",
511 SCREEN_ORIENTATION_LANDSCAPE, dc.getOrientation());
512 }
513
Andrii Kulianf0379de2018-03-14 16:24:07 -0700514 @Test
515 public void testDisableDisplayInfoOverrideFromWindowManager() {
516 final DisplayContent dc = createNewDisplay();
517
518 assertTrue(dc.mShouldOverrideDisplayConfiguration);
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700519 mWm.dontOverrideDisplayInfo(dc.getDisplayId());
Andrii Kulianf0379de2018-03-14 16:24:07 -0700520
521 assertFalse(dc.mShouldOverrideDisplayConfiguration);
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700522 verify(mWm.mDisplayManagerInternal, times(1))
Andrii Kulianf0379de2018-03-14 16:24:07 -0700523 .setDisplayInfoOverrideFromWindowManager(dc.getDisplayId(), null);
524 }
525
Riddle Hsua4d6fa22018-08-11 00:50:39 +0800526 @Test
Riddle Hsu85bd04b2018-11-17 00:34:36 +0800527 public void testClearLastFocusWhenReparentingFocusedWindow() {
528 final DisplayContent defaultDisplay = mWm.getDefaultDisplayContentLocked();
529 final WindowState window = createWindow(null /* parent */, TYPE_BASE_APPLICATION,
530 defaultDisplay, "window");
531 defaultDisplay.mLastFocus = window;
532 mDisplayContent.mCurrentFocus = window;
533 mDisplayContent.reParentWindowToken(window.mToken);
534
535 assertNull(defaultDisplay.mLastFocus);
536 }
537
538 @Test
Riddle Hsua4d6fa22018-08-11 00:50:39 +0800539 public void testGetPreferredOptionsPanelGravityFromDifferentDisplays() {
540 final DisplayContent portraitDisplay = createNewDisplay();
541 portraitDisplay.mInitialDisplayHeight = 2000;
542 portraitDisplay.mInitialDisplayWidth = 1000;
543
544 portraitDisplay.setRotation(Surface.ROTATION_0);
545 assertFalse(isOptionsPanelAtRight(portraitDisplay.getDisplayId()));
546 portraitDisplay.setRotation(Surface.ROTATION_90);
547 assertTrue(isOptionsPanelAtRight(portraitDisplay.getDisplayId()));
548
549 final DisplayContent landscapeDisplay = createNewDisplay();
550 landscapeDisplay.mInitialDisplayHeight = 1000;
551 landscapeDisplay.mInitialDisplayWidth = 2000;
552
553 landscapeDisplay.setRotation(Surface.ROTATION_0);
554 assertTrue(isOptionsPanelAtRight(landscapeDisplay.getDisplayId()));
555 landscapeDisplay.setRotation(Surface.ROTATION_90);
556 assertFalse(isOptionsPanelAtRight(landscapeDisplay.getDisplayId()));
557 }
558
lumarkff0ab692018-11-05 20:32:30 +0800559 @Test
560 public void testInputMethodTargetUpdateWhenSwitchingOnDisplays() {
561 final DisplayContent newDisplay = createNewDisplay();
562
563 final WindowState appWin = createWindow(null, TYPE_APPLICATION, mDisplayContent, "appWin");
564 final WindowState appWin1 = createWindow(null, TYPE_APPLICATION, newDisplay, "appWin1");
565 appWin.setHasSurface(true);
566 appWin1.setHasSurface(true);
567
568 // Set current input method window on default display, make sure the input method target
569 // is appWin & null on the other display.
570 mDisplayContent.setInputMethodWindowLocked(mImeWindow);
571 newDisplay.setInputMethodWindowLocked(null);
572 assertTrue("appWin should be IME target window",
573 appWin.equals(mDisplayContent.mInputMethodTarget));
574 assertNull("newDisplay Ime target: ", newDisplay.mInputMethodTarget);
575
576 // Switch input method window on new display & make sure the input method target also
577 // switched as expected.
578 newDisplay.setInputMethodWindowLocked(mImeWindow);
579 mDisplayContent.setInputMethodWindowLocked(null);
580 assertTrue("appWin1 should be IME target window",
581 appWin1.equals(newDisplay.mInputMethodTarget));
582 assertNull("default display Ime target: ", mDisplayContent.mInputMethodTarget);
583 }
584
Garfield Tan90b04282018-12-11 14:04:42 -0800585 @Test
586 public void testOnDescendantOrientationRequestChanged() {
Garfield Tan49dae102019-02-04 09:51:59 -0800587 final DisplayContent dc = createNewDisplay();
Garfield Tan90b04282018-12-11 14:04:42 -0800588 mWm.mAtmService.mRootActivityContainer = mock(RootActivityContainer.class);
Garfield Tan49dae102019-02-04 09:51:59 -0800589 final int newOrientation = dc.getLastOrientation() == SCREEN_ORIENTATION_LANDSCAPE
590 ? SCREEN_ORIENTATION_PORTRAIT
591 : SCREEN_ORIENTATION_LANDSCAPE;
Garfield Tan90b04282018-12-11 14:04:42 -0800592
593 final WindowState window = createWindow(null /* parent */, TYPE_BASE_APPLICATION, dc, "w");
594 window.getTask().mTaskRecord = mock(TaskRecord.class, ExtendedMockito.RETURNS_DEEP_STUBS);
Garfield Tan49dae102019-02-04 09:51:59 -0800595 window.mAppToken.setOrientation(newOrientation);
Garfield Tan90b04282018-12-11 14:04:42 -0800596
597 ActivityRecord activityRecord = mock(ActivityRecord.class);
598
599 assertTrue("Display should rotate to handle orientation request by default.",
600 dc.onDescendantOrientationChanged(window.mToken.token, activityRecord));
601
602 final ArgumentCaptor<Configuration> captor = ArgumentCaptor.forClass(Configuration.class);
603 verify(mWm.mAtmService).updateDisplayOverrideConfigurationLocked(captor.capture(),
604 same(activityRecord), anyBoolean(), eq(dc.getDisplayId()));
605 final Configuration newDisplayConfig = captor.getValue();
Garfield Tan49dae102019-02-04 09:51:59 -0800606 assertEquals(Configuration.ORIENTATION_PORTRAIT, newDisplayConfig.orientation);
Garfield Tan90b04282018-12-11 14:04:42 -0800607 }
608
609 @Test
610 public void testOnDescendantOrientationRequestChanged_FrozenToUserRotation() {
Garfield Tan49dae102019-02-04 09:51:59 -0800611 final DisplayContent dc = createNewDisplay();
Garfield Tan90b04282018-12-11 14:04:42 -0800612 dc.getDisplayRotation().setFixedToUserRotation(true);
613 mWm.mAtmService.mRootActivityContainer = mock(RootActivityContainer.class);
Garfield Tan49dae102019-02-04 09:51:59 -0800614 final int newOrientation = dc.getLastOrientation() == SCREEN_ORIENTATION_LANDSCAPE
615 ? SCREEN_ORIENTATION_PORTRAIT
616 : SCREEN_ORIENTATION_LANDSCAPE;
Garfield Tan90b04282018-12-11 14:04:42 -0800617
618 final WindowState window = createWindow(null /* parent */, TYPE_BASE_APPLICATION, dc, "w");
619 window.getTask().mTaskRecord = mock(TaskRecord.class, ExtendedMockito.RETURNS_DEEP_STUBS);
Garfield Tan49dae102019-02-04 09:51:59 -0800620 window.mAppToken.setOrientation(newOrientation);
Garfield Tan90b04282018-12-11 14:04:42 -0800621
622 ActivityRecord activityRecord = mock(ActivityRecord.class);
623
624 assertFalse("Display shouldn't rotate to handle orientation request if fixed to"
625 + " user rotation.",
626 dc.onDescendantOrientationChanged(window.mToken.token, activityRecord));
627 verify(mWm.mAtmService, never()).updateDisplayOverrideConfigurationLocked(any(),
628 eq(activityRecord), anyBoolean(), eq(dc.getDisplayId()));
629 }
630
Riddle Hsua4d6fa22018-08-11 00:50:39 +0800631 private boolean isOptionsPanelAtRight(int displayId) {
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700632 return (mWm.getPreferredOptionsPanelGravity(displayId) & Gravity.RIGHT) == Gravity.RIGHT;
Riddle Hsua4d6fa22018-08-11 00:50:39 +0800633 }
634
Bryce Lee27cec322017-03-21 09:41:37 -0700635 private static void verifySizes(DisplayContent displayContent, int expectedBaseWidth,
636 int expectedBaseHeight, int expectedBaseDensity) {
637 assertEquals(displayContent.mBaseDisplayWidth, expectedBaseWidth);
638 assertEquals(displayContent.mBaseDisplayHeight, expectedBaseHeight);
639 assertEquals(displayContent.mBaseDisplayDensity, expectedBaseDensity);
640 }
641
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800642 private void updateFocusedWindow() {
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700643 synchronized (mWm.mGlobalLock) {
644 mWm.updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, false);
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800645 }
646 }
647
Riddle Hsu654a6f92018-07-13 22:59:36 +0800648 /**
649 * Create DisplayContent that does not update display base/initial values from device to keep
650 * the values set by test.
651 */
652 private DisplayContent createDisplayNoUpdateDisplayInfo() {
653 final DisplayContent displayContent = spy(createNewDisplay());
654 doNothing().when(displayContent).updateDisplayInfo();
655 return displayContent;
656 }
657
Adrian Roos0f9368c2018-04-08 10:59:08 -0700658 private void assertForAllWindowsOrder(List<WindowState> expectedWindowsBottomToTop) {
659 final LinkedList<WindowState> actualWindows = new LinkedList<>();
Wale Ogunwale34247952017-02-19 11:57:53 -0800660
661 // Test forward traversal.
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700662 mDisplayContent.forAllWindows(actualWindows::addLast, false /* traverseTopToBottom */);
Adrian Roos0f9368c2018-04-08 10:59:08 -0700663 assertThat("bottomToTop", actualWindows, is(expectedWindowsBottomToTop));
664
665 actualWindows.clear();
Wale Ogunwale34247952017-02-19 11:57:53 -0800666
667 // Test backward traversal.
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700668 mDisplayContent.forAllWindows(actualWindows::addLast, true /* traverseTopToBottom */);
Adrian Roos0f9368c2018-04-08 10:59:08 -0700669 assertThat("topToBottom", actualWindows, is(reverseList(expectedWindowsBottomToTop)));
670 }
671
672 private static List<WindowState> reverseList(List<WindowState> list) {
673 final ArrayList<WindowState> result = new ArrayList<>(list);
674 Collections.reverse(result);
675 return result;
Wale Ogunwale34247952017-02-19 11:57:53 -0800676 }
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -0700677
Arthur Hungbe5ce212018-09-13 18:41:56 +0800678 private void tapOnDisplay(final DisplayContent dc) {
679 final DisplayMetrics dm = dc.getDisplayMetrics();
680 final float x = dm.widthPixels / 2;
681 final float y = dm.heightPixels / 2;
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -0700682 final long downTime = SystemClock.uptimeMillis();
683 final long eventTime = SystemClock.uptimeMillis() + 100;
Arthur Hungbe5ce212018-09-13 18:41:56 +0800684 // sending ACTION_DOWN
685 final MotionEvent downEvent = MotionEvent.obtain(
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -0700686 downTime,
Arthur Hungbe5ce212018-09-13 18:41:56 +0800687 downTime,
688 MotionEvent.ACTION_DOWN,
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -0700689 x,
690 y,
Arthur Hungbe5ce212018-09-13 18:41:56 +0800691 0 /*metaState*/);
692 downEvent.setDisplayId(dc.getDisplayId());
693 dc.mTapDetector.onPointerEvent(downEvent);
694
695 // sending ACTION_UP
696 final MotionEvent upEvent = MotionEvent.obtain(
697 downTime,
698 eventTime,
699 MotionEvent.ACTION_UP,
700 x,
701 y,
702 0 /*metaState*/);
703 upEvent.setDisplayId(dc.getDisplayId());
704 dc.mTapDetector.onPointerEvent(upEvent);
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -0700705 }
Wale Ogunwaleb783fd82016-11-04 09:51:54 -0700706}