blob: 2c575f59a0209799495689c22cf7a288b5c3555a [file] [log] [blame]
Wale Ogunwaled1c37912016-08-16 03:19:39 -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 Ogunwaled1c37912016-08-16 03:19:39 -070015 */
16
17package com.android.server.wm;
18
Riddle Hsua118b3a2018-10-11 22:05:06 +080019import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
20import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -080021import static android.content.ActivityInfoProto.SCREEN_ORIENTATION_UNSPECIFIED;
Wale Ogunwale5e5a68d2017-03-24 17:36:38 -070022import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND;
Andrii Kulian4ede3e02017-01-12 11:52:31 -080023import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
24import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
Wale Ogunwale5e5a68d2017-03-24 17:36:38 -070025import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
Jorim Jaggiab9fcb22018-03-15 23:46:12 +010026import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
Wale Ogunwaled1c37912016-08-16 03:19:39 -070027import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
Bryce Lee081554b2017-05-25 07:52:12 -070028import static android.view.WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD;
29import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
Wale Ogunwale07bcab72016-10-14 15:30:09 -070030import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
Wale Ogunwaled1c37912016-08-16 03:19:39 -070031import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
32import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
Jorim Jaggiab9fcb22018-03-15 23:46:12 +010033import static android.view.WindowManager.TRANSIT_UNSET;
Brett Chabota26eda92018-07-23 13:08:30 -070034
Yunfan Chen1ee84ea2018-11-13 16:03:37 -080035import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
36
Tadashi G. Takaokabf0d57b2018-11-19 16:09:58 +090037import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
38import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy;
39
Wale Ogunwalea7e3b642016-08-29 10:15:34 -070040import static org.junit.Assert.assertEquals;
Bryce Lee081554b2017-05-25 07:52:12 -070041import static org.junit.Assert.assertFalse;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -080042import static org.junit.Assert.assertNotNull;
Wale Ogunwalea7e3b642016-08-29 10:15:34 -070043import static org.junit.Assert.assertNull;
Wale Ogunwale07bcab72016-10-14 15:30:09 -070044import static org.junit.Assert.assertTrue;
Riddle Hsua118b3a2018-10-11 22:05:06 +080045import static org.mockito.ArgumentMatchers.anyInt;
Riddle Hsu5ce4bb32018-07-18 16:11:30 +080046
Riddle Hsub398da32019-01-21 21:48:16 +080047import android.content.res.Configuration;
Riddle Hsua118b3a2018-10-11 22:05:06 +080048import android.graphics.Point;
49import android.graphics.Rect;
Brett Chabota26eda92018-07-23 13:08:30 -070050import android.platform.test.annotations.Presubmit;
51import android.view.Surface;
52import android.view.WindowManager;
53
Brett Chabota26eda92018-07-23 13:08:30 -070054import androidx.test.filters.SmallTest;
Brett Chabota26eda92018-07-23 13:08:30 -070055
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -070056import org.junit.Before;
Brett Chabota26eda92018-07-23 13:08:30 -070057import org.junit.Test;
Brett Chabota26eda92018-07-23 13:08:30 -070058
Wale Ogunwaled1c37912016-08-16 03:19:39 -070059/**
Wale Ogunwaleb783fd82016-11-04 09:51:54 -070060 * Tests for the {@link AppWindowToken} class.
Wale Ogunwaled1c37912016-08-16 03:19:39 -070061 *
Wale Ogunwale07bcab72016-10-14 15:30:09 -070062 * Build/Install/Run:
Vishnu Naire6e2b0f2019-02-21 10:41:00 -080063 * atest WmTests:AppWindowTokenTests
Wale Ogunwaled1c37912016-08-16 03:19:39 -070064 */
65@SmallTest
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -070066@Presubmit
Wale Ogunwale44fbdf52016-11-16 10:18:45 -080067public class AppWindowTokenTests extends WindowTestsBase {
Wale Ogunwaled1c37912016-08-16 03:19:39 -070068
Robert Carrb1579c82017-09-05 14:54:47 -070069 TaskStack mStack;
70 Task mTask;
71 WindowTestUtils.TestAppWindowToken mToken;
72
Yunfan Chen1ee84ea2018-11-13 16:03:37 -080073 private final String mPackageName = getInstrumentation().getTargetContext().getPackageName();
74
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -070075 @Before
Robert Carrb1579c82017-09-05 14:54:47 -070076 public void setUp() throws Exception {
Robert Carrb1579c82017-09-05 14:54:47 -070077 mStack = createTaskStackOnDisplay(mDisplayContent);
78 mTask = createTaskInStack(mStack, 0 /* userId */);
Vishnu Naire6e2b0f2019-02-21 10:41:00 -080079 mToken = WindowTestUtils.createTestAppWindowToken(mDisplayContent,
80 false /* skipOnParentChanged */);
Robert Carrb1579c82017-09-05 14:54:47 -070081
82 mTask.addChild(mToken, 0);
83 }
84
Wale Ogunwalea7e3b642016-08-29 10:15:34 -070085 @Test
Andrii Kulian6b3a3712017-11-02 11:06:47 -070086 @Presubmit
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -070087 public void testAddWindow_Order() {
Robert Carrb1579c82017-09-05 14:54:47 -070088 assertEquals(0, mToken.getWindowsCount());
Wale Ogunwale07bcab72016-10-14 15:30:09 -070089
Robert Carrb1579c82017-09-05 14:54:47 -070090 final WindowState win1 = createWindow(null, TYPE_APPLICATION, mToken, "win1");
91 final WindowState startingWin = createWindow(null, TYPE_APPLICATION_STARTING, mToken,
Wale Ogunwale44fbdf52016-11-16 10:18:45 -080092 "startingWin");
Robert Carrb1579c82017-09-05 14:54:47 -070093 final WindowState baseWin = createWindow(null, TYPE_BASE_APPLICATION, mToken, "baseWin");
94 final WindowState win4 = createWindow(null, TYPE_APPLICATION, mToken, "win4");
Wale Ogunwale07bcab72016-10-14 15:30:09 -070095
Wale Ogunwale07bcab72016-10-14 15:30:09 -070096 // Should not contain the windows that were added above.
Robert Carrb1579c82017-09-05 14:54:47 -070097 assertEquals(4, mToken.getWindowsCount());
98 assertTrue(mToken.hasWindow(win1));
99 assertTrue(mToken.hasWindow(startingWin));
100 assertTrue(mToken.hasWindow(baseWin));
101 assertTrue(mToken.hasWindow(win4));
Wale Ogunwale07bcab72016-10-14 15:30:09 -0700102
103 // The starting window should be on-top of all other windows.
Robert Carrb1579c82017-09-05 14:54:47 -0700104 assertEquals(startingWin, mToken.getLastChild());
Wale Ogunwale07bcab72016-10-14 15:30:09 -0700105
106 // The base application window should be below all other windows.
Robert Carrb1579c82017-09-05 14:54:47 -0700107 assertEquals(baseWin, mToken.getFirstChild());
108 mToken.removeImmediately();
Wale Ogunwale07bcab72016-10-14 15:30:09 -0700109 }
110
111 @Test
Andrii Kulian6b3a3712017-11-02 11:06:47 -0700112 @Presubmit
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700113 public void testFindMainWindow() {
Robert Carrb1579c82017-09-05 14:54:47 -0700114 assertNull(mToken.findMainWindow());
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700115
Robert Carrb1579c82017-09-05 14:54:47 -0700116 final WindowState window1 = createWindow(null, TYPE_BASE_APPLICATION, mToken, "window1");
117 final WindowState window11 = createWindow(window1, FIRST_SUB_WINDOW, mToken, "window11");
118 final WindowState window12 = createWindow(window1, FIRST_SUB_WINDOW, mToken, "window12");
119 assertEquals(window1, mToken.findMainWindow());
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700120 window1.mAnimatingExit = true;
Robert Carrb1579c82017-09-05 14:54:47 -0700121 assertEquals(window1, mToken.findMainWindow());
Tadashi G. Takaokabf0d57b2018-11-19 16:09:58 +0900122 final WindowState window2 = createWindow(null, TYPE_APPLICATION_STARTING, mToken,
123 "window2");
Robert Carrb1579c82017-09-05 14:54:47 -0700124 assertEquals(window2, mToken.findMainWindow());
125 mToken.removeImmediately();
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700126 }
Andrii Kulian4ede3e02017-01-12 11:52:31 -0800127
128 @Test
Andrii Kulian6b3a3712017-11-02 11:06:47 -0700129 @Presubmit
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700130 public void testGetTopFullscreenWindow() {
Robert Carrb1579c82017-09-05 14:54:47 -0700131 assertNull(mToken.getTopFullscreenWindow());
Jorim Jaggi87fdbcb2017-08-17 13:41:11 +0200132
Robert Carrb1579c82017-09-05 14:54:47 -0700133 final WindowState window1 = createWindow(null, TYPE_BASE_APPLICATION, mToken, "window1");
134 final WindowState window11 = createWindow(null, TYPE_APPLICATION, mToken, "window11");
135 final WindowState window12 = createWindow(null, TYPE_APPLICATION, mToken, "window12");
136 assertEquals(window12, mToken.getTopFullscreenWindow());
Jorim Jaggi87fdbcb2017-08-17 13:41:11 +0200137 window12.mAttrs.width = 500;
Robert Carrb1579c82017-09-05 14:54:47 -0700138 assertEquals(window11, mToken.getTopFullscreenWindow());
Jorim Jaggi87fdbcb2017-08-17 13:41:11 +0200139 window11.mAttrs.width = 500;
Robert Carrb1579c82017-09-05 14:54:47 -0700140 assertEquals(window1, mToken.getTopFullscreenWindow());
141 mToken.removeImmediately();
Jorim Jaggi87fdbcb2017-08-17 13:41:11 +0200142 }
143
144 @Test
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700145 public void testLandscapeSeascapeRotationByApp() {
Andrii Kulian4ede3e02017-01-12 11:52:31 -0800146 // Some plumbing to get the service ready for rotation updates.
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700147 mWm.mDisplayReady = true;
148 mWm.mDisplayEnabled = true;
Andrii Kulian4ede3e02017-01-12 11:52:31 -0800149
Andrii Kulian4ede3e02017-01-12 11:52:31 -0800150 final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(
151 TYPE_BASE_APPLICATION);
152 attrs.setTitle("AppWindow");
Robert Carrb1579c82017-09-05 14:54:47 -0700153 final WindowTestUtils.TestWindowState appWindow = createWindowState(attrs, mToken);
154 mToken.addWindow(appWindow);
Andrii Kulian4ede3e02017-01-12 11:52:31 -0800155
156 // Set initial orientation and update.
Robert Carrb1579c82017-09-05 14:54:47 -0700157 mToken.setOrientation(SCREEN_ORIENTATION_LANDSCAPE);
Garfield Tan90b04282018-12-11 14:04:42 -0800158 mDisplayContent.updateOrientationFromAppTokens(
159 mDisplayContent.getRequestedOverrideConfiguration(),
160 null /* freezeThisOneIfNeeded */, false /* forceUpdate */);
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700161 assertEquals(SCREEN_ORIENTATION_LANDSCAPE, mDisplayContent.getLastOrientation());
Tadashi G. Takaokabf0d57b2018-11-19 16:09:58 +0900162 appWindow.mResizeReported = false;
Andrii Kulian4ede3e02017-01-12 11:52:31 -0800163
164 // Update the orientation to perform 180 degree rotation and check that resize was reported.
Robert Carrb1579c82017-09-05 14:54:47 -0700165 mToken.setOrientation(SCREEN_ORIENTATION_REVERSE_LANDSCAPE);
Garfield Tan90b04282018-12-11 14:04:42 -0800166 mDisplayContent.updateOrientationFromAppTokens(
167 mDisplayContent.getRequestedOverrideConfiguration(),
168 null /* freezeThisOneIfNeeded */, false /* forceUpdate */);
Yunfan Chen0530fe72019-02-12 15:05:49 +0900169 // In this test, DC will not get config update. Set the waiting flag to false.
170 mDisplayContent.mWaitingForConfig = false;
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700171 mWm.mRoot.performSurfacePlacement(false /* recoveringMemory */);
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700172 assertEquals(SCREEN_ORIENTATION_REVERSE_LANDSCAPE, mDisplayContent.getLastOrientation());
Tadashi G. Takaokabf0d57b2018-11-19 16:09:58 +0900173 assertTrue(appWindow.mResizeReported);
Wale Ogunwale1666e312016-12-16 11:27:18 -0800174 appWindow.removeImmediately();
Andrii Kulian4ede3e02017-01-12 11:52:31 -0800175 }
176
177 @Test
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700178 public void testLandscapeSeascapeRotationByPolicy() {
Andrii Kulian4ede3e02017-01-12 11:52:31 -0800179 // Some plumbing to get the service ready for rotation updates.
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700180 mWm.mDisplayReady = true;
181 mWm.mDisplayEnabled = true;
Andrii Kulian4ede3e02017-01-12 11:52:31 -0800182
Riddle Hsu5ce4bb32018-07-18 16:11:30 +0800183 final DisplayRotation spiedRotation = spy(mDisplayContent.getDisplayRotation());
184 mDisplayContent.setDisplayRotation(spiedRotation);
185
Andrii Kulian4ede3e02017-01-12 11:52:31 -0800186 final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(
187 TYPE_BASE_APPLICATION);
188 attrs.setTitle("AppWindow");
Robert Carrb1579c82017-09-05 14:54:47 -0700189 final WindowTestUtils.TestWindowState appWindow = createWindowState(attrs, mToken);
190 mToken.addWindow(appWindow);
Andrii Kulian4ede3e02017-01-12 11:52:31 -0800191
192 // Set initial orientation and update.
Riddle Hsu5ce4bb32018-07-18 16:11:30 +0800193 performRotation(spiedRotation, Surface.ROTATION_90);
Tadashi G. Takaokabf0d57b2018-11-19 16:09:58 +0900194 appWindow.mResizeReported = false;
Andrii Kulian4ede3e02017-01-12 11:52:31 -0800195
196 // Update the rotation to perform 180 degree rotation and check that resize was reported.
Riddle Hsu5ce4bb32018-07-18 16:11:30 +0800197 performRotation(spiedRotation, Surface.ROTATION_270);
Tadashi G. Takaokabf0d57b2018-11-19 16:09:58 +0900198 assertTrue(appWindow.mResizeReported);
Riddle Hsu5ce4bb32018-07-18 16:11:30 +0800199
Wale Ogunwale1666e312016-12-16 11:27:18 -0800200 appWindow.removeImmediately();
Andrii Kulian4ede3e02017-01-12 11:52:31 -0800201 }
Bryce Lee310de9e2017-03-15 10:18:21 -0700202
Riddle Hsu5ce4bb32018-07-18 16:11:30 +0800203 private void performRotation(DisplayRotation spiedRotation, int rotationToReport) {
204 doReturn(rotationToReport).when(spiedRotation).rotationForOrientation(anyInt(), anyInt());
Evan Roskye747c3e2018-10-30 20:06:41 -0700205 int oldRotation = mDisplayContent.getRotation();
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700206 mWm.updateRotation(false, false);
Evan Roskye747c3e2018-10-30 20:06:41 -0700207 // Must manually apply here since ATM doesn't know about the display during this test
208 // (meaning it can't perform the normal sendNewConfiguration flow).
209 mDisplayContent.applyRotationLocked(oldRotation, mDisplayContent.getRotation());
Riddle Hsu5ce4bb32018-07-18 16:11:30 +0800210 // Prevent the next rotation from being deferred by animation.
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700211 mWm.mAnimator.setScreenRotationAnimationLocked(mDisplayContent.getDisplayId(), null);
212 mWm.mRoot.performSurfacePlacement(false /* recoveringMemory */);
Bryce Lee310de9e2017-03-15 10:18:21 -0700213 }
Wale Ogunwale5e5a68d2017-03-24 17:36:38 -0700214
215 @Test
Riddle Hsub398da32019-01-21 21:48:16 +0800216 public void testSizeCompatBounds() {
217 // The real surface transaction is unnecessary.
218 mToken.setSkipPrepareSurfaces(true);
219
220 final Rect fixedBounds = mToken.getRequestedOverrideConfiguration().windowConfiguration
221 .getBounds();
222 fixedBounds.set(0, 0, 1200, 1600);
223 final Configuration newParentConfig = mTask.getConfiguration();
224
225 // Change the size of the container to two times smaller with insets.
226 newParentConfig.windowConfiguration.setAppBounds(200, 0, 800, 800);
227 final Rect containerAppBounds = newParentConfig.windowConfiguration.getAppBounds();
228 final Rect containerBounds = newParentConfig.windowConfiguration.getBounds();
229 containerBounds.set(0, 0, 600, 800);
230 mToken.onConfigurationChanged(newParentConfig);
231
232 assertTrue(mToken.inSizeCompatMode());
233 assertEquals(containerAppBounds, mToken.getBounds());
234 assertEquals((float) containerAppBounds.width() / fixedBounds.width(),
235 mToken.getSizeCompatScale(), 0.0001f /* delta */);
236
237 // Change the width of the container to two times bigger.
238 containerAppBounds.set(0, 0, 2400, 1600);
239 containerBounds.set(containerAppBounds);
240 mToken.onConfigurationChanged(newParentConfig);
241
242 assertTrue(mToken.inSizeCompatMode());
243 // Don't scale up, so the bounds keep the same as the fixed width.
244 assertEquals(fixedBounds.width(), mToken.getBounds().width());
245 // Assert the position is horizontal center.
246 assertEquals((containerAppBounds.width() - fixedBounds.width()) / 2,
247 mToken.getBounds().left);
248 assertEquals(1f, mToken.getSizeCompatScale(), 0.0001f /* delta */);
249
250 // Change the width of the container to fit the fixed bounds.
251 containerBounds.set(0, 0, 1200, 2000);
252 mToken.onConfigurationChanged(newParentConfig);
253 // Assert don't use fixed bounds because the region is enough.
254 assertFalse(mToken.inSizeCompatMode());
255 }
256
257 @Test
Andrii Kulian6b3a3712017-11-02 11:06:47 -0700258 @Presubmit
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700259 public void testGetOrientation() {
Robert Carrb1579c82017-09-05 14:54:47 -0700260 mToken.setOrientation(SCREEN_ORIENTATION_LANDSCAPE);
Wale Ogunwale5e5a68d2017-03-24 17:36:38 -0700261
Robert Carrb1579c82017-09-05 14:54:47 -0700262 mToken.setFillsParent(false);
Bryce Leee83f34cd2017-10-31 19:50:54 -0700263 // Can specify orientation if app doesn't fill parent.
Robert Carrb1579c82017-09-05 14:54:47 -0700264 assertEquals(SCREEN_ORIENTATION_LANDSCAPE, mToken.getOrientation());
Wale Ogunwale5e5a68d2017-03-24 17:36:38 -0700265
Robert Carrb1579c82017-09-05 14:54:47 -0700266 mToken.setFillsParent(true);
Jorim Jaggi980c9de2017-11-17 01:41:37 +0100267 mToken.setHidden(true);
Robert Carrb1579c82017-09-05 14:54:47 -0700268 mToken.sendingToBottom = true;
Wale Ogunwale5e5a68d2017-03-24 17:36:38 -0700269 // Can not specify orientation if app isn't visible even though it fills parent.
Robert Carrb1579c82017-09-05 14:54:47 -0700270 assertEquals(SCREEN_ORIENTATION_UNSET, mToken.getOrientation());
Wale Ogunwale5e5a68d2017-03-24 17:36:38 -0700271 // Can specify orientation if the current orientation candidate is orientation behind.
Tadashi G. Takaokabf0d57b2018-11-19 16:09:58 +0900272 assertEquals(SCREEN_ORIENTATION_LANDSCAPE,
273 mToken.getOrientation(SCREEN_ORIENTATION_BEHIND));
Wale Ogunwale5e5a68d2017-03-24 17:36:38 -0700274 }
Bryce Lee081554b2017-05-25 07:52:12 -0700275
276 @Test
Andrii Kulian6b3a3712017-11-02 11:06:47 -0700277 @Presubmit
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700278 public void testKeyguardFlagsDuringRelaunch() {
Bryce Lee081554b2017-05-25 07:52:12 -0700279 final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(
280 TYPE_BASE_APPLICATION);
281 attrs.flags |= FLAG_SHOW_WHEN_LOCKED | FLAG_DISMISS_KEYGUARD;
282 attrs.setTitle("AppWindow");
Robert Carrb1579c82017-09-05 14:54:47 -0700283 final WindowTestUtils.TestWindowState appWindow = createWindowState(attrs, mToken);
Bryce Lee081554b2017-05-25 07:52:12 -0700284
285 // Add window with show when locked flag
Robert Carrb1579c82017-09-05 14:54:47 -0700286 mToken.addWindow(appWindow);
287 assertTrue(mToken.containsShowWhenLockedWindow() && mToken.containsDismissKeyguardWindow());
Bryce Lee081554b2017-05-25 07:52:12 -0700288
289 // Start relaunching
Robert Carrb1579c82017-09-05 14:54:47 -0700290 mToken.startRelaunching();
291 assertTrue(mToken.containsShowWhenLockedWindow() && mToken.containsDismissKeyguardWindow());
Bryce Lee081554b2017-05-25 07:52:12 -0700292
293 // Remove window and make sure that we still report back flag
Robert Carrb1579c82017-09-05 14:54:47 -0700294 mToken.removeChild(appWindow);
295 assertTrue(mToken.containsShowWhenLockedWindow() && mToken.containsDismissKeyguardWindow());
Bryce Lee081554b2017-05-25 07:52:12 -0700296
297 // Finish relaunching and ensure flag is now not reported
Robert Carrb1579c82017-09-05 14:54:47 -0700298 mToken.finishRelaunching();
Tadashi G. Takaokabf0d57b2018-11-19 16:09:58 +0900299 assertFalse(
300 mToken.containsShowWhenLockedWindow() || mToken.containsDismissKeyguardWindow());
Bryce Lee081554b2017-05-25 07:52:12 -0700301 }
Jorim Jaggiab9fcb22018-03-15 23:46:12 +0100302
303 @Test
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700304 public void testStuckExitingWindow() {
Jorim Jaggiab9fcb22018-03-15 23:46:12 +0100305 final WindowState closingWindow = createWindow(null, FIRST_APPLICATION_WINDOW,
306 "closingWindow");
307 closingWindow.mAnimatingExit = true;
308 closingWindow.mRemoveOnExit = true;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800309 closingWindow.mAppToken.commitVisibility(null, false /* visible */, TRANSIT_UNSET,
Jorim Jaggiab9fcb22018-03-15 23:46:12 +0100310 true /* performLayout */, false /* isVoiceInteraction */);
311
312 // We pretended that we were running an exit animation, but that should have been cleared up
313 // by changing visibility of AppWindowToken
314 closingWindow.removeIfPossible();
315 assertTrue(closingWindow.mRemoved);
316 }
Riddle Hsua118b3a2018-10-11 22:05:06 +0800317
318 @Test
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800319 public void testSetOrientation() {
320 // Assert orientation is unspecified to start.
321 assertEquals(SCREEN_ORIENTATION_UNSPECIFIED, mToken.getOrientation());
322
323 mToken.setOrientation(SCREEN_ORIENTATION_LANDSCAPE);
324 assertEquals(SCREEN_ORIENTATION_LANDSCAPE, mToken.getOrientation());
325
326 mDisplayContent.removeAppToken(mToken.token);
327 // Assert orientation is unset to after container is removed.
328 assertEquals(SCREEN_ORIENTATION_UNSET, mToken.getOrientation());
329
330 // Reset display frozen state
331 mWm.mDisplayFrozen = false;
332 }
333
334 @Test
335 public void testCreateRemoveStartingWindow() {
336 mToken.addStartingWindow(mPackageName,
337 android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false, true,
338 false, false);
339 waitUntilHandlersIdle();
340 assertHasStartingWindow(mToken);
341 mToken.removeStartingWindow();
342 waitUntilHandlersIdle();
343 assertNoStartingWindow(mToken);
344 }
345
346 @Test
347 public void testAddRemoveRace() {
348 // There was once a race condition between adding and removing starting windows
349 for (int i = 0; i < 1000; i++) {
350 final WindowTestUtils.TestAppWindowToken appToken = createIsolatedTestAppWindowToken();
351
352 appToken.addStartingWindow(mPackageName,
353 android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false, true,
354 false, false);
355 appToken.removeStartingWindow();
356 waitUntilHandlersIdle();
357 assertNoStartingWindow(appToken);
358
359 appToken.getParent().getParent().removeImmediately();
360 }
361 }
362
363 @Test
364 public void testTransferStartingWindow() {
365 final WindowTestUtils.TestAppWindowToken token1 = createIsolatedTestAppWindowToken();
366 final WindowTestUtils.TestAppWindowToken token2 = createIsolatedTestAppWindowToken();
367 token1.addStartingWindow(mPackageName,
368 android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false, true,
369 false, false);
370 waitUntilHandlersIdle();
371 token2.addStartingWindow(mPackageName,
372 android.R.style.Theme, null, "Test", 0, 0, 0, 0, token1.appToken.asBinder(),
373 true, true, false, true, false, false);
374 waitUntilHandlersIdle();
375 assertNoStartingWindow(token1);
376 assertHasStartingWindow(token2);
377 }
378
379 @Test
380 public void testTransferStartingWindowWhileCreating() {
381 final WindowTestUtils.TestAppWindowToken token1 = createIsolatedTestAppWindowToken();
382 final WindowTestUtils.TestAppWindowToken token2 = createIsolatedTestAppWindowToken();
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800383 ((TestWindowManagerPolicy) token1.mWmService.mPolicy).setRunnableWhenAddingSplashScreen(
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800384 () -> {
385 // Surprise, ...! Transfer window in the middle of the creation flow.
386 token2.addStartingWindow(mPackageName,
387 android.R.style.Theme, null, "Test", 0, 0, 0, 0,
388 token1.appToken.asBinder(), true, true, false,
389 true, false, false);
390 });
391 token1.addStartingWindow(mPackageName,
392 android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false, true,
393 false, false);
394 waitUntilHandlersIdle();
395 assertNoStartingWindow(token1);
396 assertHasStartingWindow(token2);
397 }
398
399 private WindowTestUtils.TestAppWindowToken createIsolatedTestAppWindowToken() {
400 final TaskStack taskStack = createTaskStackOnDisplay(mDisplayContent);
401 final Task task = createTaskInStack(taskStack, 0 /* userId */);
402 return createTestAppWindowTokenForGivenTask(task);
403 }
404
405 private WindowTestUtils.TestAppWindowToken createTestAppWindowTokenForGivenTask(Task task) {
406 final WindowTestUtils.TestAppWindowToken appToken =
407 WindowTestUtils.createTestAppWindowToken(mDisplayContent);
408 task.addChild(appToken, 0);
409 waitUntilHandlersIdle();
410 return appToken;
411 }
412
413 @Test
414 public void testTryTransferStartingWindowFromHiddenAboveToken() {
415 // Add two tasks on top of each other.
416 final WindowTestUtils.TestAppWindowToken tokenTop = createIsolatedTestAppWindowToken();
417 final WindowTestUtils.TestAppWindowToken tokenBottom =
418 createTestAppWindowTokenForGivenTask(tokenTop.getTask());
419
420 // Add a starting window.
421 tokenTop.addStartingWindow(mPackageName,
422 android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false, true,
423 false, false);
424 waitUntilHandlersIdle();
425
426 // Make the top one invisible, and try transferring the starting window from the top to the
427 // bottom one.
428 tokenTop.setVisibility(false, false);
429 tokenBottom.transferStartingWindowFromHiddenAboveTokenIfNeeded();
Yunfan Chendcb1fcf2019-02-07 19:08:41 +0900430 waitUntilHandlersIdle();
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800431
432 // Assert that the bottom window now has the starting window.
433 assertNoStartingWindow(tokenTop);
434 assertHasStartingWindow(tokenBottom);
435 }
436
437 @Test
Riddle Hsua118b3a2018-10-11 22:05:06 +0800438 public void testTransitionAnimationPositionAndBounds() {
439 final Rect stackBounds = new Rect(
440 0/* left */, 0 /* top */, 1000 /* right */, 1000 /* bottom */);
441 final Rect taskBounds = new Rect(
442 100/* left */, 200 /* top */, 600 /* right */, 600 /* bottom */);
443 mStack.setBounds(stackBounds);
444 mTask.setBounds(taskBounds);
445
446 mTask.setWindowingMode(WINDOWING_MODE_FREEFORM);
447 assertTransitionAnimationPositionAndBounds(taskBounds.left, taskBounds.top, stackBounds);
448
449 mTask.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
450 assertTransitionAnimationPositionAndBounds(stackBounds.left, stackBounds.top, stackBounds);
451 }
452
453 private void assertTransitionAnimationPositionAndBounds(int expectedX, int expectedY,
454 Rect expectedBounds) {
455 final Point outPosition = new Point();
456 final Rect outBounds = new Rect();
457 mToken.getAnimationBounds(outPosition, outBounds);
458 assertEquals(expectedX, outPosition.x);
459 assertEquals(expectedY, outPosition.y);
460 assertEquals(expectedBounds, outBounds);
461 }
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800462
463 private void assertHasStartingWindow(AppWindowToken atoken) {
464 assertNotNull(atoken.startingSurface);
465 assertNotNull(atoken.startingData);
466 assertNotNull(atoken.startingWindow);
467 }
468
469 private void assertNoStartingWindow(AppWindowToken atoken) {
470 assertNull(atoken.startingSurface);
471 assertNull(atoken.startingWindow);
472 assertNull(atoken.startingData);
473 atoken.forAllWindows(windowState -> {
474 assertFalse(windowState.getBaseType() == TYPE_APPLICATION_STARTING);
475 }, true);
476 }
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700477}