blob: 1b5a24d75e76f0d8597e0d654a53bfe8ba323531 [file] [log] [blame]
Wale Ogunwaleb699ce02016-07-18 12:05:30 -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 Ogunwaleb699ce02016-07-18 12:05:30 -070015 */
16
17package com.android.server.wm;
18
chaviwb28de1f2018-03-02 10:42:36 -080019import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
20import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
lumarkf948afe2019-05-23 21:22:36 +080021import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
Adrian Roos0e7b70a2018-06-07 15:29:34 +020022import static android.hardware.camera2.params.OutputConfiguration.ROTATION_90;
Jorim Jaggicfd6f3b2018-11-07 15:30:18 +010023import static android.view.InsetsState.TYPE_TOP_BAR;
Adrian Roos0e7b70a2018-06-07 15:29:34 +020024import static android.view.Surface.ROTATION_0;
Yunfan Chen5e696f12019-02-07 22:02:08 +090025import static android.view.ViewRootImpl.NEW_INSETS_MODE_FULL;
Wale Ogunwaleb699ce02016-07-18 12:05:30 -070026import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
Wale Ogunwale805d9ec2016-12-07 12:22:08 -080027import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
28import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
Wale Ogunwaleb699ce02016-07-18 12:05:30 -070029import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
Wale Ogunwale34247952017-02-19 11:57:53 -080030import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ABOVE_SUB_PANEL;
31import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
32import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA;
33import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY;
Suprabh Shukla69c71422018-04-02 18:39:01 -070034import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
Wale Ogunwale34247952017-02-19 11:57:53 -080035import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL;
Wale Ogunwale805d9ec2016-12-07 12:22:08 -080036import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
Jorim Jaggicfd6f3b2018-11-07 15:30:18 +010037import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
chaviwebcbc342018-02-07 13:19:00 -080038
Yunfan Chend6c85a42019-02-18 15:52:17 +090039import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
lumarkf948afe2019-05-23 21:22:36 +080040import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
Tadashi G. Takaokabf0d57b2018-11-19 16:09:58 +090041import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
42import static com.android.dx.mockito.inline.extended.ExtendedMockito.never;
43import static com.android.dx.mockito.inline.extended.ExtendedMockito.reset;
44import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy;
Yunfan Chendb39c162019-02-08 16:14:14 +090045import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
Tadashi G. Takaokabf0d57b2018-11-19 16:09:58 +090046import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
47
Adrian Roos5251b1d2018-03-23 18:57:43 +010048import static org.hamcrest.Matchers.is;
49import static org.hamcrest.Matchers.not;
Wale Ogunwalea7e3b642016-08-29 10:15:34 -070050import static org.junit.Assert.assertEquals;
51import static org.junit.Assert.assertFalse;
52import static org.junit.Assert.assertNull;
Adrian Roos5251b1d2018-03-23 18:57:43 +010053import static org.junit.Assert.assertThat;
Wale Ogunwalea7e3b642016-08-29 10:15:34 -070054import static org.junit.Assert.assertTrue;
Vishnu Nairddd80742018-08-21 14:12:46 -070055import static org.mockito.ArgumentMatchers.any;
Michael Wrighte3001042019-02-05 00:13:14 +000056import static org.mockito.ArgumentMatchers.anyInt;
chaviw40234662018-02-07 09:37:16 -080057import static org.mockito.ArgumentMatchers.anyLong;
58import static org.mockito.ArgumentMatchers.anyString;
Vishnu Nairddd80742018-08-21 14:12:46 -070059import static org.mockito.ArgumentMatchers.eq;
Vinit Nayak8009e922019-09-05 11:49:53 -070060import static org.mockito.Mockito.when;
Wale Ogunwaleb699ce02016-07-18 12:05:30 -070061
Issei Suzuki43190bd2018-08-20 17:28:41 +020062import android.graphics.Insets;
Vishnu Nairddd80742018-08-21 14:12:46 -070063import android.graphics.Matrix;
Adrian Roos49c27ff2018-08-31 13:07:33 -070064import android.graphics.Rect;
Brett Chabota26eda92018-07-23 13:08:30 -070065import android.platform.test.annotations.Presubmit;
Adrian Roos49c27ff2018-08-31 13:07:33 -070066import android.util.Size;
67import android.view.DisplayCutout;
Jorim Jaggicfd6f3b2018-11-07 15:30:18 +010068import android.view.InsetsSource;
Brett Chabota26eda92018-07-23 13:08:30 -070069import android.view.SurfaceControl;
Yunfan Chen5e696f12019-02-07 22:02:08 +090070import android.view.ViewRootImpl;
Brett Chabota26eda92018-07-23 13:08:30 -070071import android.view.WindowManager;
72
Yunfan Chendb39c162019-02-08 16:14:14 +090073import androidx.test.filters.FlakyTest;
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -070074import androidx.test.filters.SmallTest;
75
Adrian Roos49c27ff2018-08-31 13:07:33 -070076import com.android.server.wm.utils.WmDisplayCutout;
77
Yunfan Chen5e696f12019-02-07 22:02:08 +090078import org.junit.AfterClass;
Yunfan Chendb39c162019-02-08 16:14:14 +090079import org.junit.Before;
Yunfan Chen5e696f12019-02-07 22:02:08 +090080import org.junit.BeforeClass;
Brett Chabota26eda92018-07-23 13:08:30 -070081import org.junit.Test;
Riddle Hsu2da2d032019-08-28 21:08:58 +080082import org.junit.runner.RunWith;
Brett Chabota26eda92018-07-23 13:08:30 -070083
84import java.util.LinkedList;
85
Wale Ogunwaleb699ce02016-07-18 12:05:30 -070086/**
87 * Tests for the {@link WindowState} class.
88 *
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -070089 * Build/Install/Run:
90 * atest FrameworksServicesTests:WindowStateTests
Wale Ogunwaleb699ce02016-07-18 12:05:30 -070091 */
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -070092@SmallTest
93@Presubmit
Riddle Hsu2da2d032019-08-28 21:08:58 +080094@RunWith(WindowTestRunner.class)
Wale Ogunwale44fbdf52016-11-16 10:18:45 -080095public class WindowStateTests extends WindowTestsBase {
Yunfan Chen5e696f12019-02-07 22:02:08 +090096 private static int sPreviousNewInsetsMode;
97
98 @BeforeClass
99 public static void setUpOnce() {
Yunfan Chendb39c162019-02-08 16:14:14 +0900100 // TODO: Make use of SettingsSession when it becomes feasible for this.
Yunfan Chen5e696f12019-02-07 22:02:08 +0900101 sPreviousNewInsetsMode = ViewRootImpl.sNewInsetsMode;
102 // To let the insets provider control the insets visibility, the insets mode has to be
103 // NEW_INSETS_MODE_FULL.
104 ViewRootImpl.sNewInsetsMode = NEW_INSETS_MODE_FULL;
105 }
106
107 @AfterClass
108 public static void tearDownOnce() {
109 ViewRootImpl.sNewInsetsMode = sPreviousNewInsetsMode;
110 }
Wale Ogunwaleb699ce02016-07-18 12:05:30 -0700111
Yunfan Chendb39c162019-02-08 16:14:14 +0900112 @Before
113 public void setUp() {
114 // TODO: Let the insets source with new mode keep the visibility control, and remove this
115 // setup code. Now mTopFullscreenOpaqueWindowState will take back the control of insets
116 // visibility.
Riddle Hsu2da2d032019-08-28 21:08:58 +0800117 spyOn(mDisplayContent);
118 doNothing().when(mDisplayContent).layoutAndAssignWindowLayersIfNeeded();
Yunfan Chendb39c162019-02-08 16:14:14 +0900119 }
120
Wale Ogunwalea7e3b642016-08-29 10:15:34 -0700121 @Test
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700122 public void testIsParentWindowHidden() {
Wale Ogunwale805d9ec2016-12-07 12:22:08 -0800123 final WindowState parentWindow = createWindow(null, TYPE_APPLICATION, "parentWindow");
124 final WindowState child1 = createWindow(parentWindow, FIRST_SUB_WINDOW, "child1");
125 final WindowState child2 = createWindow(parentWindow, FIRST_SUB_WINDOW, "child2");
Wale Ogunwale9d147902016-07-16 11:58:55 -0700126
chaviwebcbc342018-02-07 13:19:00 -0800127 // parentWindow is initially set to hidden.
128 assertTrue(parentWindow.mHidden);
129 assertFalse(parentWindow.isParentWindowHidden());
130 assertTrue(child1.isParentWindowHidden());
131 assertTrue(child2.isParentWindowHidden());
132
133 parentWindow.mHidden = false;
Wale Ogunwale9d147902016-07-16 11:58:55 -0700134 assertFalse(parentWindow.isParentWindowHidden());
135 assertFalse(child1.isParentWindowHidden());
136 assertFalse(child2.isParentWindowHidden());
Wale Ogunwale9d147902016-07-16 11:58:55 -0700137 }
138
Wale Ogunwalea7e3b642016-08-29 10:15:34 -0700139 @Test
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700140 public void testIsChildWindow() {
Wale Ogunwale805d9ec2016-12-07 12:22:08 -0800141 final WindowState parentWindow = createWindow(null, TYPE_APPLICATION, "parentWindow");
142 final WindowState child1 = createWindow(parentWindow, FIRST_SUB_WINDOW, "child1");
143 final WindowState child2 = createWindow(parentWindow, FIRST_SUB_WINDOW, "child2");
144 final WindowState randomWindow = createWindow(null, TYPE_APPLICATION, "randomWindow");
Wale Ogunwaleadde52e2016-07-16 13:11:55 -0700145
146 assertFalse(parentWindow.isChildWindow());
147 assertTrue(child1.isChildWindow());
148 assertTrue(child2.isChildWindow());
149 assertFalse(randomWindow.isChildWindow());
150 }
151
Wale Ogunwalea7e3b642016-08-29 10:15:34 -0700152 @Test
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700153 public void testHasChild() {
Wale Ogunwale805d9ec2016-12-07 12:22:08 -0800154 final WindowState win1 = createWindow(null, TYPE_APPLICATION, "win1");
155 final WindowState win11 = createWindow(win1, FIRST_SUB_WINDOW, "win11");
156 final WindowState win12 = createWindow(win1, FIRST_SUB_WINDOW, "win12");
157 final WindowState win2 = createWindow(null, TYPE_APPLICATION, "win2");
158 final WindowState win21 = createWindow(win2, FIRST_SUB_WINDOW, "win21");
159 final WindowState randomWindow = createWindow(null, TYPE_APPLICATION, "randomWindow");
Wale Ogunwaleadde52e2016-07-16 13:11:55 -0700160
161 assertTrue(win1.hasChild(win11));
162 assertTrue(win1.hasChild(win12));
163 assertTrue(win2.hasChild(win21));
164
165 assertFalse(win1.hasChild(win21));
166 assertFalse(win1.hasChild(randomWindow));
167
168 assertFalse(win2.hasChild(win11));
169 assertFalse(win2.hasChild(win12));
170 assertFalse(win2.hasChild(randomWindow));
171 }
172
Wale Ogunwalea7e3b642016-08-29 10:15:34 -0700173 @Test
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700174 public void testGetParentWindow() {
Wale Ogunwale805d9ec2016-12-07 12:22:08 -0800175 final WindowState parentWindow = createWindow(null, TYPE_APPLICATION, "parentWindow");
176 final WindowState child1 = createWindow(parentWindow, FIRST_SUB_WINDOW, "child1");
177 final WindowState child2 = createWindow(parentWindow, FIRST_SUB_WINDOW, "child2");
Wale Ogunwalecaa53af2016-07-17 14:50:26 -0700178
179 assertNull(parentWindow.getParentWindow());
180 assertEquals(parentWindow, child1.getParentWindow());
181 assertEquals(parentWindow, child2.getParentWindow());
182 }
183
Wale Ogunwalea7e3b642016-08-29 10:15:34 -0700184 @Test
Suprabh Shukla69c71422018-04-02 18:39:01 -0700185 public void testOverlayWindowHiddenWhenSuspended() {
186 final WindowState overlayWindow = spy(createWindow(null, TYPE_APPLICATION_OVERLAY,
187 "overlayWindow"));
188 overlayWindow.setHiddenWhileSuspended(true);
189 verify(overlayWindow).hideLw(true, true);
190 overlayWindow.setHiddenWhileSuspended(false);
191 verify(overlayWindow).showLw(true, true);
192 }
193
194 @Test
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700195 public void testGetTopParentWindow() {
Wale Ogunwale805d9ec2016-12-07 12:22:08 -0800196 final WindowState root = createWindow(null, TYPE_APPLICATION, "root");
197 final WindowState child1 = createWindow(root, FIRST_SUB_WINDOW, "child1");
198 final WindowState child2 = createWindow(child1, FIRST_SUB_WINDOW, "child2");
Wale Ogunwalecaa53af2016-07-17 14:50:26 -0700199
200 assertEquals(root, root.getTopParentWindow());
201 assertEquals(root, child1.getTopParentWindow());
202 assertEquals(child1, child2.getParentWindow());
203 assertEquals(root, child2.getTopParentWindow());
Wale Ogunwaleea92d972016-12-08 07:33:13 -0800204
205 // Test case were child is detached from parent.
206 root.removeChild(child1);
207 assertEquals(child1, child1.getTopParentWindow());
208 assertEquals(child1, child2.getParentWindow());
Wale Ogunwalecaa53af2016-07-17 14:50:26 -0700209 }
210
Jorim Jaggiaf221d12016-11-15 14:59:57 -0800211 @Test
212 public void testIsOnScreen_hiddenByPolicy() {
Wale Ogunwale805d9ec2016-12-07 12:22:08 -0800213 final WindowState window = createWindow(null, TYPE_APPLICATION, "window");
Jorim Jaggiaf221d12016-11-15 14:59:57 -0800214 window.setHasSurface(true);
215 assertTrue(window.isOnScreen());
216 window.hideLw(false /* doAnimation */);
217 assertFalse(window.isOnScreen());
218 }
Wale Ogunwale805d9ec2016-12-07 12:22:08 -0800219
220 @Test
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700221 public void testCanBeImeTarget() {
Wale Ogunwale805d9ec2016-12-07 12:22:08 -0800222 final WindowState appWindow = createWindow(null, TYPE_APPLICATION, "appWindow");
223 final WindowState imeWindow = createWindow(null, TYPE_INPUT_METHOD, "imeWindow");
224
Tarandeep Singh0ffa15a2019-11-04 13:40:15 -0800225 // Setting FLAG_NOT_FOCUSABLE prevents the window from being an IME target.
Wale Ogunwale805d9ec2016-12-07 12:22:08 -0800226 appWindow.mAttrs.flags |= FLAG_NOT_FOCUSABLE;
227 imeWindow.mAttrs.flags |= FLAG_NOT_FOCUSABLE;
228
229 // Make windows visible
230 appWindow.setHasSurface(true);
231 imeWindow.setHasSurface(true);
232
Tarandeep Singh0ffa15a2019-11-04 13:40:15 -0800233 // Windows with FLAG_NOT_FOCUSABLE can't be IME targets
Wale Ogunwale805d9ec2016-12-07 12:22:08 -0800234 assertFalse(appWindow.canBeImeTarget());
235 assertFalse(imeWindow.canBeImeTarget());
236
237 // Add IME target flags
238 appWindow.mAttrs.flags |= (FLAG_NOT_FOCUSABLE | FLAG_ALT_FOCUSABLE_IM);
239 imeWindow.mAttrs.flags |= (FLAG_NOT_FOCUSABLE | FLAG_ALT_FOCUSABLE_IM);
240
Tarandeep Singh0ffa15a2019-11-04 13:40:15 -0800241 // Visible app window with flags FLAG_NOT_FOCUSABLE or FLAG_ALT_FOCUSABLE_IM can't be IME
242 // target while an IME window can never be an IME target regardless of its visibility
243 // or flags.
244 assertFalse(appWindow.canBeImeTarget());
Wale Ogunwale805d9ec2016-12-07 12:22:08 -0800245 assertFalse(imeWindow.canBeImeTarget());
246
Tarandeep Singh0ffa15a2019-11-04 13:40:15 -0800247 appWindow.mAttrs.flags &= ~FLAG_ALT_FOCUSABLE_IM;
248 assertFalse(appWindow.canBeImeTarget());
249 appWindow.mAttrs.flags &= ~FLAG_NOT_FOCUSABLE;
250 assertTrue(appWindow.canBeImeTarget());
251
Wale Ogunwale805d9ec2016-12-07 12:22:08 -0800252 // Make windows invisible
253 appWindow.hideLw(false /* doAnimation */);
254 imeWindow.hideLw(false /* doAnimation */);
255
256 // Invisible window can't be IME targets even if they have the right flags.
257 assertFalse(appWindow.canBeImeTarget());
258 assertFalse(imeWindow.canBeImeTarget());
lumarkf948afe2019-05-23 21:22:36 +0800259
260 // Simulate the window is in split screen primary stack and the current state is
261 // minimized and home stack is resizable, so that we should ignore input for the stack.
262 final DockedStackDividerController controller =
263 mDisplayContent.getDockedDividerController();
Louis Changdc077272019-11-12 16:52:56 +0800264 final ActivityStack stack = createTaskStackOnDisplay(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY,
lumarkf948afe2019-05-23 21:22:36 +0800265 ACTIVITY_TYPE_STANDARD, mDisplayContent);
266 spyOn(appWindow);
267 spyOn(controller);
268 spyOn(stack);
269 doReturn(true).when(controller).isMinimizedDock();
270 doReturn(true).when(controller).isHomeStackResizable();
271 doReturn(stack).when(appWindow).getStack();
272
273 // Make sure canBeImeTarget is false due to shouldIgnoreInput is true;
274 assertFalse(appWindow.canBeImeTarget());
275 assertTrue(stack.shouldIgnoreInput());
Wale Ogunwale805d9ec2016-12-07 12:22:08 -0800276 }
Wale Ogunwale34247952017-02-19 11:57:53 -0800277
278 @Test
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700279 public void testGetWindow() {
Wale Ogunwale34247952017-02-19 11:57:53 -0800280 final WindowState root = createWindow(null, TYPE_APPLICATION, "root");
281 final WindowState mediaChild = createWindow(root, TYPE_APPLICATION_MEDIA, "mediaChild");
282 final WindowState mediaOverlayChild = createWindow(root,
283 TYPE_APPLICATION_MEDIA_OVERLAY, "mediaOverlayChild");
284 final WindowState attachedDialogChild = createWindow(root,
285 TYPE_APPLICATION_ATTACHED_DIALOG, "attachedDialogChild");
286 final WindowState subPanelChild = createWindow(root,
287 TYPE_APPLICATION_SUB_PANEL, "subPanelChild");
288 final WindowState aboveSubPanelChild = createWindow(root,
289 TYPE_APPLICATION_ABOVE_SUB_PANEL, "aboveSubPanelChild");
290
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700291 final LinkedList<WindowState> windows = new LinkedList<>();
Wale Ogunwale34247952017-02-19 11:57:53 -0800292
293 root.getWindow(w -> {
294 windows.addLast(w);
295 return false;
296 });
297
298 // getWindow should have returned candidate windows in z-order.
299 assertEquals(aboveSubPanelChild, windows.pollFirst());
300 assertEquals(subPanelChild, windows.pollFirst());
301 assertEquals(attachedDialogChild, windows.pollFirst());
302 assertEquals(root, windows.pollFirst());
303 assertEquals(mediaOverlayChild, windows.pollFirst());
304 assertEquals(mediaChild, windows.pollFirst());
305 assertTrue(windows.isEmpty());
306 }
Bryce Leeae73ba42017-05-05 09:58:25 -0700307
308 @Test
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700309 public void testPrepareWindowToDisplayDuringRelayout() {
Riddle Hsu4bb06be2019-07-02 01:03:07 +0800310 // Call prepareWindowToDisplayDuringRelayout for a window without FLAG_TURN_SCREEN_ON before
Garfield Tane8d84ab2019-10-11 09:49:40 -0700311 // calling setCurrentLaunchCanTurnScreenOn for windows with flag in the same activity.
312 final ActivityRecord activity = createActivityRecord(mDisplayContent,
chaviwb28de1f2018-03-02 10:42:36 -0800313 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
Garfield Tane8d84ab2019-10-11 09:49:40 -0700314 final WindowState first = createWindow(null, TYPE_APPLICATION, activity, "first");
315 final WindowState second = createWindow(null, TYPE_APPLICATION, activity, "second");
chaviwb28de1f2018-03-02 10:42:36 -0800316 second.mAttrs.flags |= WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON;
317
Riddle Hsu4bb06be2019-07-02 01:03:07 +0800318 testPrepareWindowToDisplayDuringRelayout(first, false /* expectedWakeupCalled */,
319 true /* expectedCurrentLaunchCanTurnScreenOn */);
320 testPrepareWindowToDisplayDuringRelayout(second, true /* expectedWakeupCalled */,
321 false /* expectedCurrentLaunchCanTurnScreenOn */);
chaviwb28de1f2018-03-02 10:42:36 -0800322
323 // Call prepareWindowToDisplayDuringRelayout for two window that have FLAG_TURN_SCREEN_ON
Garfield Tane8d84ab2019-10-11 09:49:40 -0700324 // from the same activity. Only one should trigger the wakeup.
325 activity.setCurrentLaunchCanTurnScreenOn(true);
chaviwb28de1f2018-03-02 10:42:36 -0800326 first.mAttrs.flags |= WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON;
327 second.mAttrs.flags |= WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON;
328
Riddle Hsu4bb06be2019-07-02 01:03:07 +0800329 testPrepareWindowToDisplayDuringRelayout(first, true /* expectedWakeupCalled */,
330 false /* expectedCurrentLaunchCanTurnScreenOn */);
331 testPrepareWindowToDisplayDuringRelayout(second, false /* expectedWakeupCalled */,
332 false /* expectedCurrentLaunchCanTurnScreenOn */);
chaviwb28de1f2018-03-02 10:42:36 -0800333
Riddle Hsu4bb06be2019-07-02 01:03:07 +0800334 // Without window flags, the state of ActivityRecord.canTurnScreenOn should still be able to
335 // turn on the screen.
Garfield Tane8d84ab2019-10-11 09:49:40 -0700336 activity.setCurrentLaunchCanTurnScreenOn(true);
Riddle Hsu4bb06be2019-07-02 01:03:07 +0800337 first.mAttrs.flags &= ~WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON;
Garfield Tane8d84ab2019-10-11 09:49:40 -0700338 doReturn(true).when(activity).canTurnScreenOn();
Riddle Hsu4bb06be2019-07-02 01:03:07 +0800339
340 testPrepareWindowToDisplayDuringRelayout(first, true /* expectedWakeupCalled */,
341 false /* expectedCurrentLaunchCanTurnScreenOn */);
chaviwb28de1f2018-03-02 10:42:36 -0800342
343 // Call prepareWindowToDisplayDuringRelayout for a windows that are not children of an
Garfield Tane8d84ab2019-10-11 09:49:40 -0700344 // activity. Both windows have the FLAG_TURNS_SCREEN_ON so both should call wakeup
chaviw97d28202018-02-27 16:23:53 -0800345 final WindowToken windowToken = WindowTestUtils.createTestWindowToken(FIRST_SUB_WINDOW,
chaviwb28de1f2018-03-02 10:42:36 -0800346 mDisplayContent);
347 final WindowState firstWindow = createWindow(null, TYPE_APPLICATION, windowToken,
348 "firstWindow");
349 final WindowState secondWindow = createWindow(null, TYPE_APPLICATION, windowToken,
350 "secondWindow");
351 firstWindow.mAttrs.flags |= WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON;
352 secondWindow.mAttrs.flags |= WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON;
353
Garfield Tane3d37b52019-07-23 12:43:05 -0700354 final WindowState.PowerManagerWrapper powerManagerWrapper =
355 mSystemServicesTestRule.getPowerManagerWrapper();
356 reset(powerManagerWrapper);
chaviwb28de1f2018-03-02 10:42:36 -0800357 firstWindow.prepareWindowToDisplayDuringRelayout(false /*wasVisible*/);
Garfield Tane3d37b52019-07-23 12:43:05 -0700358 verify(powerManagerWrapper).wakeUp(anyLong(), anyInt(), anyString());
chaviwb28de1f2018-03-02 10:42:36 -0800359
Garfield Tane3d37b52019-07-23 12:43:05 -0700360 reset(powerManagerWrapper);
chaviwb28de1f2018-03-02 10:42:36 -0800361 secondWindow.prepareWindowToDisplayDuringRelayout(false /*wasVisible*/);
Garfield Tane3d37b52019-07-23 12:43:05 -0700362 verify(powerManagerWrapper).wakeUp(anyLong(), anyInt(), anyString());
Bryce Leeae73ba42017-05-05 09:58:25 -0700363 }
364
Riddle Hsu4bb06be2019-07-02 01:03:07 +0800365 private void testPrepareWindowToDisplayDuringRelayout(WindowState appWindow,
366 boolean expectedWakeupCalled, boolean expectedCurrentLaunchCanTurnScreenOn) {
Garfield Tane3d37b52019-07-23 12:43:05 -0700367 final WindowState.PowerManagerWrapper powerManagerWrapper =
368 mSystemServicesTestRule.getPowerManagerWrapper();
369 reset(powerManagerWrapper);
Riddle Hsu4bb06be2019-07-02 01:03:07 +0800370 appWindow.prepareWindowToDisplayDuringRelayout(false /* wasVisible */);
371
372 if (expectedWakeupCalled) {
Garfield Tane3d37b52019-07-23 12:43:05 -0700373 verify(powerManagerWrapper).wakeUp(anyLong(), anyInt(), anyString());
Riddle Hsu4bb06be2019-07-02 01:03:07 +0800374 } else {
Garfield Tane3d37b52019-07-23 12:43:05 -0700375 verify(powerManagerWrapper, never()).wakeUp(anyLong(), anyInt(), anyString());
Riddle Hsu4bb06be2019-07-02 01:03:07 +0800376 }
377 // If wakeup is expected to be called, the currentLaunchCanTurnScreenOn should be false
378 // because the state will be consumed.
Garfield Tane8d84ab2019-10-11 09:49:40 -0700379 assertThat(appWindow.mActivityRecord.currentLaunchCanTurnScreenOn(),
Riddle Hsu4bb06be2019-07-02 01:03:07 +0800380 is(expectedCurrentLaunchCanTurnScreenOn));
381 }
382
Jorim Jaggi72207752018-01-08 13:16:59 +0100383 @Test
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700384 public void testCanAffectSystemUiFlags() {
Jorim Jaggi72207752018-01-08 13:16:59 +0100385 final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
Issei Suzuki7b9e2572019-11-14 16:19:54 +0100386 app.mToken.setHidden(false);
Jorim Jaggi72207752018-01-08 13:16:59 +0100387 assertTrue(app.canAffectSystemUiFlags());
Issei Suzuki7b9e2572019-11-14 16:19:54 +0100388 app.mToken.setHidden(true);
Jorim Jaggi72207752018-01-08 13:16:59 +0100389 assertFalse(app.canAffectSystemUiFlags());
Issei Suzuki7b9e2572019-11-14 16:19:54 +0100390 app.mToken.setHidden(false);
Jorim Jaggi72207752018-01-08 13:16:59 +0100391 app.mAttrs.alpha = 0.0f;
392 assertFalse(app.canAffectSystemUiFlags());
Jorim Jaggi50bf59c2018-03-09 17:29:48 +0100393 }
394
395 @Test
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700396 public void testCanAffectSystemUiFlags_disallow() {
Jorim Jaggi50bf59c2018-03-09 17:29:48 +0100397 final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
Issei Suzuki7b9e2572019-11-14 16:19:54 +0100398 app.mToken.setHidden(false);
Jorim Jaggi50bf59c2018-03-09 17:29:48 +0100399 assertTrue(app.canAffectSystemUiFlags());
400 app.getTask().setCanAffectSystemUiFlags(false);
401 assertFalse(app.canAffectSystemUiFlags());
Jorim Jaggi72207752018-01-08 13:16:59 +0100402 }
403
Jorim Jaggi4876b4a2018-01-11 15:43:49 +0100404 @Test
Jorim Jaggi956ca412019-01-07 14:49:14 +0100405 public void testVisibleWithInsetsProvider() {
Jorim Jaggicfd6f3b2018-11-07 15:30:18 +0100406 final WindowState topBar = createWindow(null, TYPE_STATUS_BAR, "topBar");
407 final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
408 topBar.mHasSurface = true;
409 assertTrue(topBar.isVisible());
410 mDisplayContent.getInsetsStateController().getSourceProvider(TYPE_TOP_BAR)
Jorim Jaggi956ca412019-01-07 14:49:14 +0100411 .setWindow(topBar, null /* frameProvider */);
412 mDisplayContent.getInsetsStateController().onBarControlTargetChanged(
413 app, null /* fakeTopControlling */, app, null /* fakeNavControlling */);
Jorim Jaggicfd6f3b2018-11-07 15:30:18 +0100414 mDisplayContent.getInsetsStateController().getSourceProvider(TYPE_TOP_BAR)
415 .onInsetsModified(app, new InsetsSource(TYPE_TOP_BAR));
Yunfan Chendb39c162019-02-08 16:14:14 +0900416 waitUntilHandlersIdle();
Jorim Jaggicfd6f3b2018-11-07 15:30:18 +0100417 assertFalse(topBar.isVisible());
418 }
419
420 @Test
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700421 public void testIsSelfOrAncestorWindowAnimating() {
Jorim Jaggi4876b4a2018-01-11 15:43:49 +0100422 final WindowState root = createWindow(null, TYPE_APPLICATION, "root");
423 final WindowState child1 = createWindow(root, FIRST_SUB_WINDOW, "child1");
424 final WindowState child2 = createWindow(child1, FIRST_SUB_WINDOW, "child2");
425 assertFalse(child2.isSelfOrAncestorWindowAnimatingExit());
426 child2.mAnimatingExit = true;
427 assertTrue(child2.isSelfOrAncestorWindowAnimatingExit());
428 child2.mAnimatingExit = false;
429 root.mAnimatingExit = true;
430 assertTrue(child2.isSelfOrAncestorWindowAnimatingExit());
431 }
432
Adrian Roos5251b1d2018-03-23 18:57:43 +0100433 @Test
Yunfan Chend6c85a42019-02-18 15:52:17 +0900434 @FlakyTest(bugId = 74078662)
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700435 public void testLayoutSeqResetOnReparent() {
Adrian Roos5251b1d2018-03-23 18:57:43 +0100436 final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
437 app.mLayoutSeq = 1;
438 mDisplayContent.mLayoutSeq = 1;
439
Garfield Tane223e682019-04-15 09:59:25 -0700440 DisplayContent newDisplay = createNewDisplay();
441
442 app.onDisplayChanged(newDisplay);
Adrian Roos5251b1d2018-03-23 18:57:43 +0100443
444 assertThat(app.mLayoutSeq, not(is(mDisplayContent.mLayoutSeq)));
445 }
446
Brad Stenningaf596412018-04-02 12:03:19 -0700447 @Test
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700448 public void testDisplayIdUpdatedOnReparent() {
Brad Stenningaf596412018-04-02 12:03:19 -0700449 final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
450 // fake a different display
451 app.mInputWindowHandle.displayId = mDisplayContent.getDisplayId() + 1;
452 app.onDisplayChanged(mDisplayContent);
453
454 assertThat(app.mInputWindowHandle.displayId, is(mDisplayContent.getDisplayId()));
455 assertThat(app.getDisplayId(), is(mDisplayContent.getDisplayId()));
456 }
457
Adrian Roos0e7b70a2018-06-07 15:29:34 +0200458 @Test
459 public void testSeamlesslyRotateWindow() {
460 final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
chaviw619da692019-06-10 15:39:40 -0700461 final SurfaceControl.Transaction t = spy(StubTransaction.class);
Adrian Roos0e7b70a2018-06-07 15:29:34 +0200462
463 app.mHasSurface = true;
Vishnu Naird8c664b2018-09-24 12:52:35 -0700464 app.mSurfaceControl = mock(SurfaceControl.class);
Adrian Roos0e7b70a2018-06-07 15:29:34 +0200465 try {
chaviw492139a2018-07-16 16:07:35 -0700466 app.getFrameLw().set(10, 20, 60, 80);
Vishnu Naird8c664b2018-09-24 12:52:35 -0700467 app.updateSurfacePosition(t);
Adrian Roos0e7b70a2018-06-07 15:29:34 +0200468
Vishnu Nairddd80742018-08-21 14:12:46 -0700469 app.seamlesslyRotateIfAllowed(t, ROTATION_0, ROTATION_90, true);
Adrian Roos0e7b70a2018-06-07 15:29:34 +0200470
471 assertTrue(app.mSeamlesslyRotated);
Vishnu Naird8c664b2018-09-24 12:52:35 -0700472
473 // Verify we un-rotate the window state surface.
Vishnu Nairddd80742018-08-21 14:12:46 -0700474 Matrix matrix = new Matrix();
475 // Un-rotate 90 deg
476 matrix.setRotate(270);
477 // Translate it back to origin
478 matrix.postTranslate(0, mDisplayInfo.logicalWidth);
Vishnu Naird8c664b2018-09-24 12:52:35 -0700479 verify(t).setMatrix(eq(app.mSurfaceControl), eq(matrix), any(float[].class));
480
481 // Verify we update the position as well.
482 float[] currentSurfacePos = {app.mLastSurfacePosition.x, app.mLastSurfacePosition.y};
483 matrix.mapPoints(currentSurfacePos);
484 verify(t).setPosition(eq(app.mSurfaceControl), eq(currentSurfacePos[0]),
485 eq(currentSurfacePos[1]));
Adrian Roos0e7b70a2018-06-07 15:29:34 +0200486 } finally {
Vishnu Naird8c664b2018-09-24 12:52:35 -0700487 app.mSurfaceControl = null;
Adrian Roos0e7b70a2018-06-07 15:29:34 +0200488 app.mHasSurface = false;
489 }
490 }
491
Adrian Roos49c27ff2018-08-31 13:07:33 -0700492 @Test
Yunfan Chend6c85a42019-02-18 15:52:17 +0900493 @FlakyTest(bugId = 74078662)
Adrian Roos49c27ff2018-08-31 13:07:33 -0700494 public void testDisplayCutoutIsCalculatedRelativeToFrame() {
495 final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
chaviw1454b392018-08-06 09:54:04 -0700496 WindowFrames wf = app.getWindowFrames();
Adrian Roos49c27ff2018-08-31 13:07:33 -0700497 wf.mParentFrame.set(7, 10, 185, 380);
498 wf.mDisplayFrame.set(wf.mParentFrame);
Issei Suzuki43190bd2018-08-20 17:28:41 +0200499 final DisplayCutout cutout = new DisplayCutout(
500 Insets.of(0, 15, 0, 22) /* safeInset */,
501 null /* boundLeft */,
502 new Rect(95, 0, 105, 15),
503 null /* boundRight */,
504 new Rect(95, 378, 105, 400));
Adrian Roos49c27ff2018-08-31 13:07:33 -0700505 wf.setDisplayCutout(new WmDisplayCutout(cutout, new Size(200, 400)));
506
chaviw1454b392018-08-06 09:54:04 -0700507 app.computeFrameLw();
Adrian Roos49c27ff2018-08-31 13:07:33 -0700508 assertThat(app.getWmDisplayCutout().getDisplayCutout(), is(cutout.inset(7, 10, 5, 20)));
509 }
510
chaviw15ad49f2019-04-24 15:05:39 -0700511 @Test
512 public void testVisibilityChangeSwitchUser() {
513 final WindowState window = createWindow(null, TYPE_APPLICATION, "app");
514 window.mHasSurface = true;
515 window.setShowToOwnerOnlyLocked(true);
516
517 mWm.mCurrentUserId = 1;
Wale Ogunwalebebd8cd2019-10-28 15:53:31 -0700518 window.switchUser(mWm.mCurrentUserId);
chaviw15ad49f2019-04-24 15:05:39 -0700519 assertFalse(window.isVisible());
520 assertFalse(window.isVisibleByPolicy());
521
522 mWm.mCurrentUserId = 0;
Wale Ogunwalebebd8cd2019-10-28 15:53:31 -0700523 window.switchUser(mWm.mCurrentUserId);
chaviw15ad49f2019-04-24 15:05:39 -0700524 assertTrue(window.isVisible());
525 assertTrue(window.isVisibleByPolicy());
526 }
Tiger Huangd8ec9382019-04-18 14:35:09 -0700527
528 @Test
529 public void testGetTransformationMatrix() {
Wale Ogunwale8a1860a2019-06-05 08:57:19 -0700530 final int PARENT_WINDOW_OFFSET = 1;
531 final int DISPLAY_IN_PARENT_WINDOW_OFFSET = 2;
532 final int WINDOW_OFFSET = 3;
533 final float OFFSET_SUM =
534 PARENT_WINDOW_OFFSET + DISPLAY_IN_PARENT_WINDOW_OFFSET + WINDOW_OFFSET;
535
Riddle Hsu2da2d032019-08-28 21:08:58 +0800536 final WindowState win0 = createWindow(null, TYPE_APPLICATION, "win0");
Tiger Huangd8ec9382019-04-18 14:35:09 -0700537
Riddle Hsu2da2d032019-08-28 21:08:58 +0800538 final DisplayContent dc = createNewDisplay();
539 win0.getFrameLw().offsetTo(PARENT_WINDOW_OFFSET, 0);
540 dc.reparentDisplayContent(win0, win0.getSurfaceControl());
541 dc.updateLocation(win0, DISPLAY_IN_PARENT_WINDOW_OFFSET, 0);
Tiger Huangd8ec9382019-04-18 14:35:09 -0700542
Riddle Hsu2da2d032019-08-28 21:08:58 +0800543 final float[] values = new float[9];
544 final Matrix matrix = new Matrix();
chaviw619da692019-06-10 15:39:40 -0700545 final SurfaceControl.Transaction t = spy(StubTransaction.class);
Riddle Hsu2da2d032019-08-28 21:08:58 +0800546 final WindowState win1 = createWindow(null, TYPE_APPLICATION, dc, "win1");
547 win1.mHasSurface = true;
548 win1.mSurfaceControl = mock(SurfaceControl.class);
549 win1.getFrameLw().offsetTo(WINDOW_OFFSET, 0);
550 win1.updateSurfacePosition(t);
551 win1.getTransformationMatrix(values, matrix);
Tiger Huangd8ec9382019-04-18 14:35:09 -0700552
Riddle Hsu2da2d032019-08-28 21:08:58 +0800553 matrix.getValues(values);
554 assertEquals(OFFSET_SUM, values[Matrix.MTRANS_X], 0f);
555 assertEquals(0f, values[Matrix.MTRANS_Y], 0f);
Tiger Huangd8ec9382019-04-18 14:35:09 -0700556 }
Vinit Nayak8009e922019-09-05 11:49:53 -0700557
558 @Test
559 public void testCantReceiveTouchDuringRecentsAnimation() {
560 final WindowState win0 = createWindow(null, TYPE_APPLICATION, "win0");
561
562 // Mock active recents animation
563 RecentsAnimationController recentsController = mock(RecentsAnimationController.class);
Garfield Tane8d84ab2019-10-11 09:49:40 -0700564 when(recentsController.isAnimatingTask(win0.mActivityRecord.getTask())).thenReturn(true);
Vinit Nayak8009e922019-09-05 11:49:53 -0700565 mWm.setRecentsAnimationController(recentsController);
566 assertTrue(win0.cantReceiveTouchInput());
567 }
568
569 @Test
570 public void testCantReceiveTouchWhenAppTokenHiddenRequested() {
571 final WindowState win0 = createWindow(null, TYPE_APPLICATION, "win0");
Issei Suzuki1669ea42019-11-06 14:20:59 +0100572 win0.mActivityRecord.mVisibleRequested = false;
Vinit Nayak8009e922019-09-05 11:49:53 -0700573 assertTrue(win0.cantReceiveTouchInput());
574 }
575
576 @Test
577 public void testCantReceiveTouchWhenShouldIgnoreInput() {
578 final WindowState win0 = createWindow(null, TYPE_APPLICATION, "win0");
Garfield Tane8d84ab2019-10-11 09:49:40 -0700579 win0.mActivityRecord.getStack().setAdjustedForMinimizedDock(1 /* Any non 0 value works */);
Vinit Nayak8009e922019-09-05 11:49:53 -0700580 assertTrue(win0.cantReceiveTouchInput());
581 }
Wale Ogunwaleb699ce02016-07-18 12:05:30 -0700582}