blob: 68b40b92b9ccad841cc38bfa858c996feccb8600 [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;
Wale Ogunwale5e5a68d2017-03-24 17:36:38 -070021import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND;
Andrii Kulian4ede3e02017-01-12 11:52:31 -080022import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
23import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
Wale Ogunwale5e5a68d2017-03-24 17:36:38 -070024import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
Garfield Tanb6776602019-02-20 14:44:26 -080025import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
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;
Garfield Tanb6776602019-02-20 14:44:26 -080045import static org.mockito.ArgumentMatchers.any;
Riddle Hsua118b3a2018-10-11 22:05:06 +080046import static org.mockito.ArgumentMatchers.anyInt;
Garfield Tanb6776602019-02-20 14:44:26 -080047import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
48import static org.mockito.Mockito.verify;
Riddle Hsu5ce4bb32018-07-18 16:11:30 +080049
Riddle Hsub398da32019-01-21 21:48:16 +080050import android.content.res.Configuration;
Riddle Hsua118b3a2018-10-11 22:05:06 +080051import android.graphics.Point;
52import android.graphics.Rect;
Brett Chabota26eda92018-07-23 13:08:30 -070053import android.platform.test.annotations.Presubmit;
Garfield Tanb6776602019-02-20 14:44:26 -080054import android.view.Display;
Brett Chabota26eda92018-07-23 13:08:30 -070055import android.view.Surface;
56import android.view.WindowManager;
57
Brett Chabota26eda92018-07-23 13:08:30 -070058import androidx.test.filters.SmallTest;
Brett Chabota26eda92018-07-23 13:08:30 -070059
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -070060import org.junit.Before;
Brett Chabota26eda92018-07-23 13:08:30 -070061import org.junit.Test;
Garfield Tanb6776602019-02-20 14:44:26 -080062import org.mockito.Mockito;
Brett Chabota26eda92018-07-23 13:08:30 -070063
Wale Ogunwaled1c37912016-08-16 03:19:39 -070064/**
Wale Ogunwaleb783fd82016-11-04 09:51:54 -070065 * Tests for the {@link AppWindowToken} class.
Wale Ogunwaled1c37912016-08-16 03:19:39 -070066 *
Wale Ogunwale07bcab72016-10-14 15:30:09 -070067 * Build/Install/Run:
Vishnu Naire6e2b0f2019-02-21 10:41:00 -080068 * atest WmTests:AppWindowTokenTests
Wale Ogunwaled1c37912016-08-16 03:19:39 -070069 */
70@SmallTest
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -070071@Presubmit
Wale Ogunwale44fbdf52016-11-16 10:18:45 -080072public class AppWindowTokenTests extends WindowTestsBase {
Wale Ogunwaled1c37912016-08-16 03:19:39 -070073
Robert Carrb1579c82017-09-05 14:54:47 -070074 TaskStack mStack;
75 Task mTask;
76 WindowTestUtils.TestAppWindowToken mToken;
77
Yunfan Chen1ee84ea2018-11-13 16:03:37 -080078 private final String mPackageName = getInstrumentation().getTargetContext().getPackageName();
79
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -070080 @Before
Robert Carrb1579c82017-09-05 14:54:47 -070081 public void setUp() throws Exception {
Robert Carrb1579c82017-09-05 14:54:47 -070082 mStack = createTaskStackOnDisplay(mDisplayContent);
83 mTask = createTaskInStack(mStack, 0 /* userId */);
Vishnu Naire6e2b0f2019-02-21 10:41:00 -080084 mToken = WindowTestUtils.createTestAppWindowToken(mDisplayContent,
85 false /* skipOnParentChanged */);
Robert Carrb1579c82017-09-05 14:54:47 -070086
87 mTask.addChild(mToken, 0);
88 }
89
Wale Ogunwalea7e3b642016-08-29 10:15:34 -070090 @Test
Andrii Kulian6b3a3712017-11-02 11:06:47 -070091 @Presubmit
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -070092 public void testAddWindow_Order() {
Robert Carrb1579c82017-09-05 14:54:47 -070093 assertEquals(0, mToken.getWindowsCount());
Wale Ogunwale07bcab72016-10-14 15:30:09 -070094
Robert Carrb1579c82017-09-05 14:54:47 -070095 final WindowState win1 = createWindow(null, TYPE_APPLICATION, mToken, "win1");
96 final WindowState startingWin = createWindow(null, TYPE_APPLICATION_STARTING, mToken,
Wale Ogunwale44fbdf52016-11-16 10:18:45 -080097 "startingWin");
Robert Carrb1579c82017-09-05 14:54:47 -070098 final WindowState baseWin = createWindow(null, TYPE_BASE_APPLICATION, mToken, "baseWin");
99 final WindowState win4 = createWindow(null, TYPE_APPLICATION, mToken, "win4");
Wale Ogunwale07bcab72016-10-14 15:30:09 -0700100
Wale Ogunwale07bcab72016-10-14 15:30:09 -0700101 // Should not contain the windows that were added above.
Robert Carrb1579c82017-09-05 14:54:47 -0700102 assertEquals(4, mToken.getWindowsCount());
103 assertTrue(mToken.hasWindow(win1));
104 assertTrue(mToken.hasWindow(startingWin));
105 assertTrue(mToken.hasWindow(baseWin));
106 assertTrue(mToken.hasWindow(win4));
Wale Ogunwale07bcab72016-10-14 15:30:09 -0700107
108 // The starting window should be on-top of all other windows.
Robert Carrb1579c82017-09-05 14:54:47 -0700109 assertEquals(startingWin, mToken.getLastChild());
Wale Ogunwale07bcab72016-10-14 15:30:09 -0700110
111 // The base application window should be below all other windows.
Robert Carrb1579c82017-09-05 14:54:47 -0700112 assertEquals(baseWin, mToken.getFirstChild());
113 mToken.removeImmediately();
Wale Ogunwale07bcab72016-10-14 15:30:09 -0700114 }
115
116 @Test
Andrii Kulian6b3a3712017-11-02 11:06:47 -0700117 @Presubmit
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700118 public void testFindMainWindow() {
Robert Carrb1579c82017-09-05 14:54:47 -0700119 assertNull(mToken.findMainWindow());
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700120
Robert Carrb1579c82017-09-05 14:54:47 -0700121 final WindowState window1 = createWindow(null, TYPE_BASE_APPLICATION, mToken, "window1");
122 final WindowState window11 = createWindow(window1, FIRST_SUB_WINDOW, mToken, "window11");
123 final WindowState window12 = createWindow(window1, FIRST_SUB_WINDOW, mToken, "window12");
124 assertEquals(window1, mToken.findMainWindow());
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700125 window1.mAnimatingExit = true;
Robert Carrb1579c82017-09-05 14:54:47 -0700126 assertEquals(window1, mToken.findMainWindow());
Tadashi G. Takaokabf0d57b2018-11-19 16:09:58 +0900127 final WindowState window2 = createWindow(null, TYPE_APPLICATION_STARTING, mToken,
128 "window2");
Robert Carrb1579c82017-09-05 14:54:47 -0700129 assertEquals(window2, mToken.findMainWindow());
130 mToken.removeImmediately();
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700131 }
Andrii Kulian4ede3e02017-01-12 11:52:31 -0800132
133 @Test
Andrii Kulian6b3a3712017-11-02 11:06:47 -0700134 @Presubmit
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700135 public void testGetTopFullscreenWindow() {
Robert Carrb1579c82017-09-05 14:54:47 -0700136 assertNull(mToken.getTopFullscreenWindow());
Jorim Jaggi87fdbcb2017-08-17 13:41:11 +0200137
Robert Carrb1579c82017-09-05 14:54:47 -0700138 final WindowState window1 = createWindow(null, TYPE_BASE_APPLICATION, mToken, "window1");
139 final WindowState window11 = createWindow(null, TYPE_APPLICATION, mToken, "window11");
140 final WindowState window12 = createWindow(null, TYPE_APPLICATION, mToken, "window12");
141 assertEquals(window12, mToken.getTopFullscreenWindow());
Jorim Jaggi87fdbcb2017-08-17 13:41:11 +0200142 window12.mAttrs.width = 500;
Robert Carrb1579c82017-09-05 14:54:47 -0700143 assertEquals(window11, mToken.getTopFullscreenWindow());
Jorim Jaggi87fdbcb2017-08-17 13:41:11 +0200144 window11.mAttrs.width = 500;
Robert Carrb1579c82017-09-05 14:54:47 -0700145 assertEquals(window1, mToken.getTopFullscreenWindow());
146 mToken.removeImmediately();
Jorim Jaggi87fdbcb2017-08-17 13:41:11 +0200147 }
148
149 @Test
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700150 public void testLandscapeSeascapeRotationByApp() {
Andrii Kulian4ede3e02017-01-12 11:52:31 -0800151 // Some plumbing to get the service ready for rotation updates.
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700152 mWm.mDisplayReady = true;
153 mWm.mDisplayEnabled = true;
Andrii Kulian4ede3e02017-01-12 11:52:31 -0800154
Andrii Kulian4ede3e02017-01-12 11:52:31 -0800155 final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(
156 TYPE_BASE_APPLICATION);
157 attrs.setTitle("AppWindow");
Robert Carrb1579c82017-09-05 14:54:47 -0700158 final WindowTestUtils.TestWindowState appWindow = createWindowState(attrs, mToken);
159 mToken.addWindow(appWindow);
Andrii Kulian4ede3e02017-01-12 11:52:31 -0800160
161 // Set initial orientation and update.
Robert Carrb1579c82017-09-05 14:54:47 -0700162 mToken.setOrientation(SCREEN_ORIENTATION_LANDSCAPE);
Garfield Tan90b04282018-12-11 14:04:42 -0800163 mDisplayContent.updateOrientationFromAppTokens(
164 mDisplayContent.getRequestedOverrideConfiguration(),
165 null /* freezeThisOneIfNeeded */, false /* forceUpdate */);
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700166 assertEquals(SCREEN_ORIENTATION_LANDSCAPE, mDisplayContent.getLastOrientation());
Tadashi G. Takaokabf0d57b2018-11-19 16:09:58 +0900167 appWindow.mResizeReported = false;
Andrii Kulian4ede3e02017-01-12 11:52:31 -0800168
169 // Update the orientation to perform 180 degree rotation and check that resize was reported.
Robert Carrb1579c82017-09-05 14:54:47 -0700170 mToken.setOrientation(SCREEN_ORIENTATION_REVERSE_LANDSCAPE);
Garfield Tan90b04282018-12-11 14:04:42 -0800171 mDisplayContent.updateOrientationFromAppTokens(
172 mDisplayContent.getRequestedOverrideConfiguration(),
173 null /* freezeThisOneIfNeeded */, false /* forceUpdate */);
Yunfan Chen0530fe72019-02-12 15:05:49 +0900174 // In this test, DC will not get config update. Set the waiting flag to false.
175 mDisplayContent.mWaitingForConfig = false;
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700176 mWm.mRoot.performSurfacePlacement(false /* recoveringMemory */);
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700177 assertEquals(SCREEN_ORIENTATION_REVERSE_LANDSCAPE, mDisplayContent.getLastOrientation());
Tadashi G. Takaokabf0d57b2018-11-19 16:09:58 +0900178 assertTrue(appWindow.mResizeReported);
Wale Ogunwale1666e312016-12-16 11:27:18 -0800179 appWindow.removeImmediately();
Andrii Kulian4ede3e02017-01-12 11:52:31 -0800180 }
181
182 @Test
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700183 public void testLandscapeSeascapeRotationByPolicy() {
Andrii Kulian4ede3e02017-01-12 11:52:31 -0800184 // Some plumbing to get the service ready for rotation updates.
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700185 mWm.mDisplayReady = true;
186 mWm.mDisplayEnabled = true;
Andrii Kulian4ede3e02017-01-12 11:52:31 -0800187
Riddle Hsu5ce4bb32018-07-18 16:11:30 +0800188 final DisplayRotation spiedRotation = spy(mDisplayContent.getDisplayRotation());
189 mDisplayContent.setDisplayRotation(spiedRotation);
190
Andrii Kulian4ede3e02017-01-12 11:52:31 -0800191 final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(
192 TYPE_BASE_APPLICATION);
193 attrs.setTitle("AppWindow");
Robert Carrb1579c82017-09-05 14:54:47 -0700194 final WindowTestUtils.TestWindowState appWindow = createWindowState(attrs, mToken);
195 mToken.addWindow(appWindow);
Andrii Kulian4ede3e02017-01-12 11:52:31 -0800196
197 // Set initial orientation and update.
Riddle Hsu5ce4bb32018-07-18 16:11:30 +0800198 performRotation(spiedRotation, Surface.ROTATION_90);
Tadashi G. Takaokabf0d57b2018-11-19 16:09:58 +0900199 appWindow.mResizeReported = false;
Andrii Kulian4ede3e02017-01-12 11:52:31 -0800200
201 // Update the rotation to perform 180 degree rotation and check that resize was reported.
Riddle Hsu5ce4bb32018-07-18 16:11:30 +0800202 performRotation(spiedRotation, Surface.ROTATION_270);
Tadashi G. Takaokabf0d57b2018-11-19 16:09:58 +0900203 assertTrue(appWindow.mResizeReported);
Riddle Hsu5ce4bb32018-07-18 16:11:30 +0800204
Wale Ogunwale1666e312016-12-16 11:27:18 -0800205 appWindow.removeImmediately();
Andrii Kulian4ede3e02017-01-12 11:52:31 -0800206 }
Bryce Lee310de9e2017-03-15 10:18:21 -0700207
Riddle Hsu5ce4bb32018-07-18 16:11:30 +0800208 private void performRotation(DisplayRotation spiedRotation, int rotationToReport) {
209 doReturn(rotationToReport).when(spiedRotation).rotationForOrientation(anyInt(), anyInt());
Evan Roskye747c3e2018-10-30 20:06:41 -0700210 int oldRotation = mDisplayContent.getRotation();
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700211 mWm.updateRotation(false, false);
Evan Roskye747c3e2018-10-30 20:06:41 -0700212 // Must manually apply here since ATM doesn't know about the display during this test
213 // (meaning it can't perform the normal sendNewConfiguration flow).
214 mDisplayContent.applyRotationLocked(oldRotation, mDisplayContent.getRotation());
Riddle Hsu5ce4bb32018-07-18 16:11:30 +0800215 // Prevent the next rotation from being deferred by animation.
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700216 mWm.mAnimator.setScreenRotationAnimationLocked(mDisplayContent.getDisplayId(), null);
217 mWm.mRoot.performSurfacePlacement(false /* recoveringMemory */);
Bryce Lee310de9e2017-03-15 10:18:21 -0700218 }
Wale Ogunwale5e5a68d2017-03-24 17:36:38 -0700219
220 @Test
Riddle Hsub398da32019-01-21 21:48:16 +0800221 public void testSizeCompatBounds() {
222 // The real surface transaction is unnecessary.
223 mToken.setSkipPrepareSurfaces(true);
224
225 final Rect fixedBounds = mToken.getRequestedOverrideConfiguration().windowConfiguration
226 .getBounds();
227 fixedBounds.set(0, 0, 1200, 1600);
228 final Configuration newParentConfig = mTask.getConfiguration();
229
230 // Change the size of the container to two times smaller with insets.
231 newParentConfig.windowConfiguration.setAppBounds(200, 0, 800, 800);
232 final Rect containerAppBounds = newParentConfig.windowConfiguration.getAppBounds();
233 final Rect containerBounds = newParentConfig.windowConfiguration.getBounds();
234 containerBounds.set(0, 0, 600, 800);
235 mToken.onConfigurationChanged(newParentConfig);
236
237 assertTrue(mToken.inSizeCompatMode());
238 assertEquals(containerAppBounds, mToken.getBounds());
239 assertEquals((float) containerAppBounds.width() / fixedBounds.width(),
240 mToken.getSizeCompatScale(), 0.0001f /* delta */);
241
242 // Change the width of the container to two times bigger.
243 containerAppBounds.set(0, 0, 2400, 1600);
244 containerBounds.set(containerAppBounds);
245 mToken.onConfigurationChanged(newParentConfig);
246
247 assertTrue(mToken.inSizeCompatMode());
248 // Don't scale up, so the bounds keep the same as the fixed width.
249 assertEquals(fixedBounds.width(), mToken.getBounds().width());
250 // Assert the position is horizontal center.
251 assertEquals((containerAppBounds.width() - fixedBounds.width()) / 2,
252 mToken.getBounds().left);
253 assertEquals(1f, mToken.getSizeCompatScale(), 0.0001f /* delta */);
254
255 // Change the width of the container to fit the fixed bounds.
256 containerBounds.set(0, 0, 1200, 2000);
257 mToken.onConfigurationChanged(newParentConfig);
258 // Assert don't use fixed bounds because the region is enough.
259 assertFalse(mToken.inSizeCompatMode());
260 }
261
262 @Test
Andrii Kulian6b3a3712017-11-02 11:06:47 -0700263 @Presubmit
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700264 public void testGetOrientation() {
Robert Carrb1579c82017-09-05 14:54:47 -0700265 mToken.setOrientation(SCREEN_ORIENTATION_LANDSCAPE);
Wale Ogunwale5e5a68d2017-03-24 17:36:38 -0700266
Robert Carrb1579c82017-09-05 14:54:47 -0700267 mToken.setFillsParent(false);
Bryce Leee83f34cd2017-10-31 19:50:54 -0700268 // Can specify orientation if app doesn't fill parent.
Robert Carrb1579c82017-09-05 14:54:47 -0700269 assertEquals(SCREEN_ORIENTATION_LANDSCAPE, mToken.getOrientation());
Wale Ogunwale5e5a68d2017-03-24 17:36:38 -0700270
Robert Carrb1579c82017-09-05 14:54:47 -0700271 mToken.setFillsParent(true);
Jorim Jaggi980c9de2017-11-17 01:41:37 +0100272 mToken.setHidden(true);
Robert Carrb1579c82017-09-05 14:54:47 -0700273 mToken.sendingToBottom = true;
Wale Ogunwale5e5a68d2017-03-24 17:36:38 -0700274 // Can not specify orientation if app isn't visible even though it fills parent.
Robert Carrb1579c82017-09-05 14:54:47 -0700275 assertEquals(SCREEN_ORIENTATION_UNSET, mToken.getOrientation());
Wale Ogunwale5e5a68d2017-03-24 17:36:38 -0700276 // Can specify orientation if the current orientation candidate is orientation behind.
Tadashi G. Takaokabf0d57b2018-11-19 16:09:58 +0900277 assertEquals(SCREEN_ORIENTATION_LANDSCAPE,
278 mToken.getOrientation(SCREEN_ORIENTATION_BEHIND));
Wale Ogunwale5e5a68d2017-03-24 17:36:38 -0700279 }
Bryce Lee081554b2017-05-25 07:52:12 -0700280
281 @Test
Andrii Kulian6b3a3712017-11-02 11:06:47 -0700282 @Presubmit
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700283 public void testKeyguardFlagsDuringRelaunch() {
Bryce Lee081554b2017-05-25 07:52:12 -0700284 final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(
285 TYPE_BASE_APPLICATION);
286 attrs.flags |= FLAG_SHOW_WHEN_LOCKED | FLAG_DISMISS_KEYGUARD;
287 attrs.setTitle("AppWindow");
Robert Carrb1579c82017-09-05 14:54:47 -0700288 final WindowTestUtils.TestWindowState appWindow = createWindowState(attrs, mToken);
Bryce Lee081554b2017-05-25 07:52:12 -0700289
290 // Add window with show when locked flag
Robert Carrb1579c82017-09-05 14:54:47 -0700291 mToken.addWindow(appWindow);
292 assertTrue(mToken.containsShowWhenLockedWindow() && mToken.containsDismissKeyguardWindow());
Bryce Lee081554b2017-05-25 07:52:12 -0700293
294 // Start relaunching
Robert Carrb1579c82017-09-05 14:54:47 -0700295 mToken.startRelaunching();
296 assertTrue(mToken.containsShowWhenLockedWindow() && mToken.containsDismissKeyguardWindow());
Bryce Lee081554b2017-05-25 07:52:12 -0700297
298 // Remove window and make sure that we still report back flag
Robert Carrb1579c82017-09-05 14:54:47 -0700299 mToken.removeChild(appWindow);
300 assertTrue(mToken.containsShowWhenLockedWindow() && mToken.containsDismissKeyguardWindow());
Bryce Lee081554b2017-05-25 07:52:12 -0700301
302 // Finish relaunching and ensure flag is now not reported
Robert Carrb1579c82017-09-05 14:54:47 -0700303 mToken.finishRelaunching();
Tadashi G. Takaokabf0d57b2018-11-19 16:09:58 +0900304 assertFalse(
305 mToken.containsShowWhenLockedWindow() || mToken.containsDismissKeyguardWindow());
Bryce Lee081554b2017-05-25 07:52:12 -0700306 }
Jorim Jaggiab9fcb22018-03-15 23:46:12 +0100307
308 @Test
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700309 public void testStuckExitingWindow() {
Jorim Jaggiab9fcb22018-03-15 23:46:12 +0100310 final WindowState closingWindow = createWindow(null, FIRST_APPLICATION_WINDOW,
311 "closingWindow");
312 closingWindow.mAnimatingExit = true;
313 closingWindow.mRemoveOnExit = true;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800314 closingWindow.mAppToken.commitVisibility(null, false /* visible */, TRANSIT_UNSET,
Jorim Jaggiab9fcb22018-03-15 23:46:12 +0100315 true /* performLayout */, false /* isVoiceInteraction */);
316
317 // We pretended that we were running an exit animation, but that should have been cleared up
318 // by changing visibility of AppWindowToken
319 closingWindow.removeIfPossible();
320 assertTrue(closingWindow.mRemoved);
321 }
Riddle Hsua118b3a2018-10-11 22:05:06 +0800322
323 @Test
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800324 public void testSetOrientation() {
325 // Assert orientation is unspecified to start.
326 assertEquals(SCREEN_ORIENTATION_UNSPECIFIED, mToken.getOrientation());
327
328 mToken.setOrientation(SCREEN_ORIENTATION_LANDSCAPE);
329 assertEquals(SCREEN_ORIENTATION_LANDSCAPE, mToken.getOrientation());
330
331 mDisplayContent.removeAppToken(mToken.token);
332 // Assert orientation is unset to after container is removed.
333 assertEquals(SCREEN_ORIENTATION_UNSET, mToken.getOrientation());
334
335 // Reset display frozen state
336 mWm.mDisplayFrozen = false;
337 }
338
339 @Test
Garfield Tanb6776602019-02-20 14:44:26 -0800340 public void testReportOrientationChangeOnVisibilityChange() {
341 synchronized (mWm.mGlobalLock) {
342 mToken.setOrientation(SCREEN_ORIENTATION_LANDSCAPE);
343
344 mDisplayContent.getDisplayRotation().setFixedToUserRotation(
345 DisplayRotation.FIXED_TO_USER_ROTATION_ENABLED);
346
347 doReturn(Configuration.ORIENTATION_LANDSCAPE).when(mToken.mActivityRecord)
348 .getRequestedConfigurationOrientation();
349
350 mTask.mTaskRecord = Mockito.mock(TaskRecord.class, RETURNS_DEEP_STUBS);
351 mToken.commitVisibility(null, false /* visible */, TRANSIT_UNSET,
352 true /* performLayout */, false /* isVoiceInteraction */);
353 }
354
355 verify(mTask.mTaskRecord).onConfigurationChanged(any(Configuration.class));
356 }
357
358 @Test
359 public void testReportOrientationChangeOnOpeningClosingAppChange() {
360 synchronized (mWm.mGlobalLock) {
361 mToken.setOrientation(SCREEN_ORIENTATION_LANDSCAPE);
362
363 mDisplayContent.getDisplayRotation().setFixedToUserRotation(
364 DisplayRotation.FIXED_TO_USER_ROTATION_ENABLED);
365 mDisplayContent.getDisplayInfo().state = Display.STATE_ON;
366 mDisplayContent.prepareAppTransition(WindowManager.TRANSIT_ACTIVITY_CLOSE,
367 false /* alwaysKeepCurrent */, 0 /* flags */, true /* forceOverride */);
368
369 doReturn(Configuration.ORIENTATION_LANDSCAPE).when(mToken.mActivityRecord)
370 .getRequestedConfigurationOrientation();
371
372 mTask.mTaskRecord = Mockito.mock(TaskRecord.class, RETURNS_DEEP_STUBS);
373 mToken.setVisibility(false, false);
374 }
375
376 verify(mTask.mTaskRecord).onConfigurationChanged(any(Configuration.class));
377 }
378
379 @Test
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800380 public void testCreateRemoveStartingWindow() {
381 mToken.addStartingWindow(mPackageName,
382 android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false, true,
383 false, false);
384 waitUntilHandlersIdle();
385 assertHasStartingWindow(mToken);
386 mToken.removeStartingWindow();
387 waitUntilHandlersIdle();
388 assertNoStartingWindow(mToken);
389 }
390
391 @Test
392 public void testAddRemoveRace() {
393 // There was once a race condition between adding and removing starting windows
394 for (int i = 0; i < 1000; i++) {
395 final WindowTestUtils.TestAppWindowToken appToken = createIsolatedTestAppWindowToken();
396
397 appToken.addStartingWindow(mPackageName,
398 android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false, true,
399 false, false);
400 appToken.removeStartingWindow();
401 waitUntilHandlersIdle();
402 assertNoStartingWindow(appToken);
403
404 appToken.getParent().getParent().removeImmediately();
405 }
406 }
407
408 @Test
409 public void testTransferStartingWindow() {
410 final WindowTestUtils.TestAppWindowToken token1 = createIsolatedTestAppWindowToken();
411 final WindowTestUtils.TestAppWindowToken token2 = createIsolatedTestAppWindowToken();
412 token1.addStartingWindow(mPackageName,
413 android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false, true,
414 false, false);
415 waitUntilHandlersIdle();
416 token2.addStartingWindow(mPackageName,
417 android.R.style.Theme, null, "Test", 0, 0, 0, 0, token1.appToken.asBinder(),
418 true, true, false, true, false, false);
419 waitUntilHandlersIdle();
420 assertNoStartingWindow(token1);
421 assertHasStartingWindow(token2);
422 }
423
424 @Test
425 public void testTransferStartingWindowWhileCreating() {
426 final WindowTestUtils.TestAppWindowToken token1 = createIsolatedTestAppWindowToken();
427 final WindowTestUtils.TestAppWindowToken token2 = createIsolatedTestAppWindowToken();
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800428 ((TestWindowManagerPolicy) token1.mWmService.mPolicy).setRunnableWhenAddingSplashScreen(
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800429 () -> {
430 // Surprise, ...! Transfer window in the middle of the creation flow.
431 token2.addStartingWindow(mPackageName,
432 android.R.style.Theme, null, "Test", 0, 0, 0, 0,
433 token1.appToken.asBinder(), true, true, false,
434 true, false, false);
435 });
436 token1.addStartingWindow(mPackageName,
437 android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false, true,
438 false, false);
439 waitUntilHandlersIdle();
440 assertNoStartingWindow(token1);
441 assertHasStartingWindow(token2);
442 }
443
444 private WindowTestUtils.TestAppWindowToken createIsolatedTestAppWindowToken() {
445 final TaskStack taskStack = createTaskStackOnDisplay(mDisplayContent);
446 final Task task = createTaskInStack(taskStack, 0 /* userId */);
447 return createTestAppWindowTokenForGivenTask(task);
448 }
449
450 private WindowTestUtils.TestAppWindowToken createTestAppWindowTokenForGivenTask(Task task) {
451 final WindowTestUtils.TestAppWindowToken appToken =
452 WindowTestUtils.createTestAppWindowToken(mDisplayContent);
453 task.addChild(appToken, 0);
454 waitUntilHandlersIdle();
455 return appToken;
456 }
457
458 @Test
459 public void testTryTransferStartingWindowFromHiddenAboveToken() {
460 // Add two tasks on top of each other.
461 final WindowTestUtils.TestAppWindowToken tokenTop = createIsolatedTestAppWindowToken();
462 final WindowTestUtils.TestAppWindowToken tokenBottom =
463 createTestAppWindowTokenForGivenTask(tokenTop.getTask());
464
465 // Add a starting window.
466 tokenTop.addStartingWindow(mPackageName,
467 android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false, true,
468 false, false);
469 waitUntilHandlersIdle();
470
471 // Make the top one invisible, and try transferring the starting window from the top to the
472 // bottom one.
473 tokenTop.setVisibility(false, false);
474 tokenBottom.transferStartingWindowFromHiddenAboveTokenIfNeeded();
Yunfan Chendcb1fcf2019-02-07 19:08:41 +0900475 waitUntilHandlersIdle();
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800476
477 // Assert that the bottom window now has the starting window.
478 assertNoStartingWindow(tokenTop);
479 assertHasStartingWindow(tokenBottom);
480 }
481
482 @Test
Riddle Hsua118b3a2018-10-11 22:05:06 +0800483 public void testTransitionAnimationPositionAndBounds() {
484 final Rect stackBounds = new Rect(
485 0/* left */, 0 /* top */, 1000 /* right */, 1000 /* bottom */);
486 final Rect taskBounds = new Rect(
487 100/* left */, 200 /* top */, 600 /* right */, 600 /* bottom */);
488 mStack.setBounds(stackBounds);
489 mTask.setBounds(taskBounds);
490
491 mTask.setWindowingMode(WINDOWING_MODE_FREEFORM);
492 assertTransitionAnimationPositionAndBounds(taskBounds.left, taskBounds.top, stackBounds);
493
494 mTask.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
495 assertTransitionAnimationPositionAndBounds(stackBounds.left, stackBounds.top, stackBounds);
496 }
497
498 private void assertTransitionAnimationPositionAndBounds(int expectedX, int expectedY,
499 Rect expectedBounds) {
500 final Point outPosition = new Point();
501 final Rect outBounds = new Rect();
502 mToken.getAnimationBounds(outPosition, outBounds);
503 assertEquals(expectedX, outPosition.x);
504 assertEquals(expectedY, outPosition.y);
505 assertEquals(expectedBounds, outBounds);
506 }
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800507
508 private void assertHasStartingWindow(AppWindowToken atoken) {
509 assertNotNull(atoken.startingSurface);
510 assertNotNull(atoken.startingData);
511 assertNotNull(atoken.startingWindow);
512 }
513
514 private void assertNoStartingWindow(AppWindowToken atoken) {
515 assertNull(atoken.startingSurface);
516 assertNull(atoken.startingWindow);
517 assertNull(atoken.startingData);
518 atoken.forAllWindows(windowState -> {
519 assertFalse(windowState.getBaseType() == TYPE_APPLICATION_STARTING);
520 }, true);
521 }
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700522}