blob: 1c150969144a68e55fafd919bef86f2ffcda43e4 [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
Evan Rosky641daea2019-04-24 14:45:24 -070019import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
20import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
21import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
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;
Garfield Tanb6776602019-02-20 14:44:26 -080026import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
Jorim Jaggiab9fcb22018-03-15 23:46:12 +010027import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
Wale Ogunwaled1c37912016-08-16 03:19:39 -070028import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
Bryce Lee081554b2017-05-25 07:52:12 -070029import static android.view.WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD;
30import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
Wale Ogunwale07bcab72016-10-14 15:30:09 -070031import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
Wale Ogunwaled1c37912016-08-16 03:19:39 -070032import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
33import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
Jorim Jaggiab9fcb22018-03-15 23:46:12 +010034import static android.view.WindowManager.TRANSIT_UNSET;
Brett Chabota26eda92018-07-23 13:08:30 -070035
Yunfan Chen1ee84ea2018-11-13 16:03:37 -080036import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
37
Wale Ogunwalec17418e2019-10-13 23:00:40 +020038import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
Tadashi G. Takaokabf0d57b2018-11-19 16:09:58 +090039import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
Evan Rosky641daea2019-04-24 14:45:24 -070040import static com.android.server.wm.WindowStateAnimator.STACK_CLIP_AFTER_ANIM;
41import static com.android.server.wm.WindowStateAnimator.STACK_CLIP_BEFORE_ANIM;
42import static com.android.server.wm.WindowStateAnimator.STACK_CLIP_NONE;
Tadashi G. Takaokabf0d57b2018-11-19 16:09:58 +090043
Wale Ogunwalea7e3b642016-08-29 10:15:34 -070044import static org.junit.Assert.assertEquals;
Bryce Lee081554b2017-05-25 07:52:12 -070045import static org.junit.Assert.assertFalse;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -080046import static org.junit.Assert.assertNotNull;
Wale Ogunwalea7e3b642016-08-29 10:15:34 -070047import static org.junit.Assert.assertNull;
Wale Ogunwale07bcab72016-10-14 15:30:09 -070048import static org.junit.Assert.assertTrue;
Garfield Tanb6776602019-02-20 14:44:26 -080049import static org.mockito.ArgumentMatchers.any;
Riddle Hsua118b3a2018-10-11 22:05:06 +080050import static org.mockito.ArgumentMatchers.anyInt;
Wale Ogunwale2322bed2019-10-10 17:24:19 +020051import static org.mockito.Mockito.reset;
Garfield Tanb6776602019-02-20 14:44:26 -080052import static org.mockito.Mockito.verify;
Riddle Hsu5ce4bb32018-07-18 16:11:30 +080053
Riddle Hsub398da32019-01-21 21:48:16 +080054import android.content.res.Configuration;
Riddle Hsua118b3a2018-10-11 22:05:06 +080055import android.graphics.Rect;
Brett Chabota26eda92018-07-23 13:08:30 -070056import android.platform.test.annotations.Presubmit;
57import android.view.Surface;
58import android.view.WindowManager;
59
Yunfan Chenc1caf6b2019-04-12 13:58:51 +090060import androidx.test.filters.FlakyTest;
Brett Chabota26eda92018-07-23 13:08:30 -070061import androidx.test.filters.SmallTest;
Brett Chabota26eda92018-07-23 13:08:30 -070062
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -070063import org.junit.Before;
Brett Chabota26eda92018-07-23 13:08:30 -070064import org.junit.Test;
Riddle Hsu73f53572019-09-23 23:13:01 +080065import org.junit.runner.RunWith;
Brett Chabota26eda92018-07-23 13:08:30 -070066
Wale Ogunwaled1c37912016-08-16 03:19:39 -070067/**
Garfield Tane8d84ab2019-10-11 09:49:40 -070068 * Tests for the {@link ActivityRecord} class.
Wale Ogunwaled1c37912016-08-16 03:19:39 -070069 *
Wale Ogunwale07bcab72016-10-14 15:30:09 -070070 * Build/Install/Run:
Vishnu Naire6e2b0f2019-02-21 10:41:00 -080071 * atest WmTests:AppWindowTokenTests
Wale Ogunwaled1c37912016-08-16 03:19:39 -070072 */
73@SmallTest
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -070074@Presubmit
Riddle Hsu73f53572019-09-23 23:13:01 +080075@RunWith(WindowTestRunner.class)
Wale Ogunwale44fbdf52016-11-16 10:18:45 -080076public class AppWindowTokenTests extends WindowTestsBase {
Wale Ogunwaled1c37912016-08-16 03:19:39 -070077
Wale Ogunwalebebd8cd2019-10-28 15:53:31 -070078 ActivityStack mStack;
Robert Carrb1579c82017-09-05 14:54:47 -070079 Task mTask;
Garfield Tane8d84ab2019-10-11 09:49:40 -070080 ActivityRecord mActivity;
Robert Carrb1579c82017-09-05 14:54:47 -070081
Yunfan Chen1ee84ea2018-11-13 16:03:37 -080082 private final String mPackageName = getInstrumentation().getTargetContext().getPackageName();
83
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -070084 @Before
Robert Carrb1579c82017-09-05 14:54:47 -070085 public void setUp() throws Exception {
Robert Carrb1579c82017-09-05 14:54:47 -070086 mStack = createTaskStackOnDisplay(mDisplayContent);
87 mTask = createTaskInStack(mStack, 0 /* userId */);
Garfield Tane8d84ab2019-10-11 09:49:40 -070088 mActivity = WindowTestUtils.createTestActivityRecord(mDisplayContent);
Robert Carrb1579c82017-09-05 14:54:47 -070089
Garfield Tane8d84ab2019-10-11 09:49:40 -070090 mTask.addChild(mActivity, 0);
Robert Carrb1579c82017-09-05 14:54:47 -070091 }
92
Wale Ogunwalea7e3b642016-08-29 10:15:34 -070093 @Test
Andrii Kulian6b3a3712017-11-02 11:06:47 -070094 @Presubmit
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -070095 public void testAddWindow_Order() {
Garfield Tane8d84ab2019-10-11 09:49:40 -070096 assertEquals(0, mActivity.getChildCount());
Wale Ogunwale07bcab72016-10-14 15:30:09 -070097
Garfield Tane8d84ab2019-10-11 09:49:40 -070098 final WindowState win1 = createWindow(null, TYPE_APPLICATION, mActivity, "win1");
99 final WindowState startingWin = createWindow(null, TYPE_APPLICATION_STARTING, mActivity,
Wale Ogunwale44fbdf52016-11-16 10:18:45 -0800100 "startingWin");
Garfield Tane8d84ab2019-10-11 09:49:40 -0700101 final WindowState baseWin = createWindow(null, TYPE_BASE_APPLICATION, mActivity, "baseWin");
102 final WindowState win4 = createWindow(null, TYPE_APPLICATION, mActivity, "win4");
Wale Ogunwale07bcab72016-10-14 15:30:09 -0700103
Wale Ogunwale07bcab72016-10-14 15:30:09 -0700104 // Should not contain the windows that were added above.
Garfield Tane8d84ab2019-10-11 09:49:40 -0700105 assertEquals(4, mActivity.getChildCount());
106 assertTrue(mActivity.mChildren.contains(win1));
107 assertTrue(mActivity.mChildren.contains(startingWin));
108 assertTrue(mActivity.mChildren.contains(baseWin));
109 assertTrue(mActivity.mChildren.contains(win4));
Wale Ogunwale07bcab72016-10-14 15:30:09 -0700110
111 // The starting window should be on-top of all other windows.
Garfield Tane8d84ab2019-10-11 09:49:40 -0700112 assertEquals(startingWin, mActivity.mChildren.peekLast());
Wale Ogunwale07bcab72016-10-14 15:30:09 -0700113
114 // The base application window should be below all other windows.
Garfield Tane8d84ab2019-10-11 09:49:40 -0700115 assertEquals(baseWin, mActivity.mChildren.peekFirst());
116 mActivity.removeImmediately();
Wale Ogunwale07bcab72016-10-14 15:30:09 -0700117 }
118
119 @Test
Andrii Kulian6b3a3712017-11-02 11:06:47 -0700120 @Presubmit
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700121 public void testFindMainWindow() {
Garfield Tane8d84ab2019-10-11 09:49:40 -0700122 assertNull(mActivity.findMainWindow());
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700123
Garfield Tane8d84ab2019-10-11 09:49:40 -0700124 final WindowState window1 = createWindow(null, TYPE_BASE_APPLICATION, mActivity, "window1");
125 final WindowState window11 = createWindow(window1, FIRST_SUB_WINDOW, mActivity, "window11");
126 final WindowState window12 = createWindow(window1, FIRST_SUB_WINDOW, mActivity, "window12");
127 assertEquals(window1, mActivity.findMainWindow());
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700128 window1.mAnimatingExit = true;
Garfield Tane8d84ab2019-10-11 09:49:40 -0700129 assertEquals(window1, mActivity.findMainWindow());
130 final WindowState window2 = createWindow(null, TYPE_APPLICATION_STARTING, mActivity,
Tadashi G. Takaokabf0d57b2018-11-19 16:09:58 +0900131 "window2");
Garfield Tane8d84ab2019-10-11 09:49:40 -0700132 assertEquals(window2, mActivity.findMainWindow());
133 mActivity.removeImmediately();
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700134 }
Andrii Kulian4ede3e02017-01-12 11:52:31 -0800135
136 @Test
Andrii Kulian6b3a3712017-11-02 11:06:47 -0700137 @Presubmit
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700138 public void testGetTopFullscreenWindow() {
Garfield Tane8d84ab2019-10-11 09:49:40 -0700139 assertNull(mActivity.getTopFullscreenWindow());
Jorim Jaggi87fdbcb2017-08-17 13:41:11 +0200140
Garfield Tane8d84ab2019-10-11 09:49:40 -0700141 final WindowState window1 = createWindow(null, TYPE_BASE_APPLICATION, mActivity, "window1");
142 final WindowState window11 = createWindow(null, TYPE_APPLICATION, mActivity, "window11");
143 final WindowState window12 = createWindow(null, TYPE_APPLICATION, mActivity, "window12");
144 assertEquals(window12, mActivity.getTopFullscreenWindow());
Jorim Jaggi87fdbcb2017-08-17 13:41:11 +0200145 window12.mAttrs.width = 500;
Garfield Tane8d84ab2019-10-11 09:49:40 -0700146 assertEquals(window11, mActivity.getTopFullscreenWindow());
Jorim Jaggi87fdbcb2017-08-17 13:41:11 +0200147 window11.mAttrs.width = 500;
Garfield Tane8d84ab2019-10-11 09:49:40 -0700148 assertEquals(window1, mActivity.getTopFullscreenWindow());
149 mActivity.removeImmediately();
Jorim Jaggi87fdbcb2017-08-17 13:41:11 +0200150 }
151
152 @Test
Wale Ogunwale815c7cb2019-05-02 08:04:01 -0700153 @FlakyTest(bugId = 131005232)
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700154 public void testLandscapeSeascapeRotationByApp() {
Andrii Kulian4ede3e02017-01-12 11:52:31 -0800155 final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(
156 TYPE_BASE_APPLICATION);
157 attrs.setTitle("AppWindow");
Garfield Tane8d84ab2019-10-11 09:49:40 -0700158 final WindowTestUtils.TestWindowState appWindow = createWindowState(attrs, mActivity);
159 mActivity.addWindow(appWindow);
Andrii Kulian4ede3e02017-01-12 11:52:31 -0800160
161 // Set initial orientation and update.
Garfield Tane8d84ab2019-10-11 09:49:40 -0700162 mActivity.setOrientation(SCREEN_ORIENTATION_LANDSCAPE);
Riddle Hsuccf09402019-08-13 00:33:06 +0800163 mDisplayContent.updateOrientation(
Garfield Tan90b04282018-12-11 14:04:42 -0800164 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.
Garfield Tane8d84ab2019-10-11 09:49:40 -0700170 mActivity.setOrientation(SCREEN_ORIENTATION_REVERSE_LANDSCAPE);
Riddle Hsuccf09402019-08-13 00:33:06 +0800171 mDisplayContent.updateOrientation(
Garfield Tan90b04282018-12-11 14:04:42 -0800172 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() {
Riddle Hsuccf09402019-08-13 00:33:06 +0800184 // This instance has been spied in {@link TestActivityDisplay}.
Wale Ogunwale8a1860a2019-06-05 08:57:19 -0700185 final DisplayRotation displayRotation = mDisplayContent.getDisplayRotation();
Riddle Hsu5ce4bb32018-07-18 16:11:30 +0800186
Andrii Kulian4ede3e02017-01-12 11:52:31 -0800187 final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(
188 TYPE_BASE_APPLICATION);
Wale Ogunwale8a1860a2019-06-05 08:57:19 -0700189 attrs.setTitle("RotationByPolicy");
Garfield Tane8d84ab2019-10-11 09:49:40 -0700190 final WindowTestUtils.TestWindowState appWindow = createWindowState(attrs, mActivity);
191 mActivity.addWindow(appWindow);
Andrii Kulian4ede3e02017-01-12 11:52:31 -0800192
193 // Set initial orientation and update.
Wale Ogunwale8a1860a2019-06-05 08:57:19 -0700194 performRotation(displayRotation, Surface.ROTATION_90);
Tadashi G. Takaokabf0d57b2018-11-19 16:09:58 +0900195 appWindow.mResizeReported = false;
Andrii Kulian4ede3e02017-01-12 11:52:31 -0800196
197 // Update the rotation to perform 180 degree rotation and check that resize was reported.
Wale Ogunwale8a1860a2019-06-05 08:57:19 -0700198 performRotation(displayRotation, Surface.ROTATION_270);
Tadashi G. Takaokabf0d57b2018-11-19 16:09:58 +0900199 assertTrue(appWindow.mResizeReported);
Riddle Hsu5ce4bb32018-07-18 16:11:30 +0800200
Wale Ogunwale1666e312016-12-16 11:27:18 -0800201 appWindow.removeImmediately();
Andrii Kulian4ede3e02017-01-12 11:52:31 -0800202 }
Bryce Lee310de9e2017-03-15 10:18:21 -0700203
Riddle Hsu5ce4bb32018-07-18 16:11:30 +0800204 private void performRotation(DisplayRotation spiedRotation, int rotationToReport) {
205 doReturn(rotationToReport).when(spiedRotation).rotationForOrientation(anyInt(), anyInt());
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700206 mWm.updateRotation(false, false);
Bryce Lee310de9e2017-03-15 10:18:21 -0700207 }
Wale Ogunwale5e5a68d2017-03-24 17:36:38 -0700208
209 @Test
Riddle Hsub398da32019-01-21 21:48:16 +0800210 public void testSizeCompatBounds() {
Wale Ogunwalec17418e2019-10-13 23:00:40 +0200211 // Disable the real configuration resolving because we only simulate partial flow.
212 // TODO: Have test use full flow.
Louis Changcdec0802019-11-11 11:45:07 +0800213 doNothing().when(mTask).computeConfigResourceOverrides(any(), any());
Garfield Tane8d84ab2019-10-11 09:49:40 -0700214 final Rect fixedBounds = mActivity.getRequestedOverrideConfiguration().windowConfiguration
Riddle Hsub398da32019-01-21 21:48:16 +0800215 .getBounds();
216 fixedBounds.set(0, 0, 1200, 1600);
Garfield Tane8d84ab2019-10-11 09:49:40 -0700217 mActivity.getRequestedOverrideConfiguration().windowConfiguration.setAppBounds(fixedBounds);
Riddle Hsub398da32019-01-21 21:48:16 +0800218 final Configuration newParentConfig = mTask.getConfiguration();
219
220 // Change the size of the container to two times smaller with insets.
221 newParentConfig.windowConfiguration.setAppBounds(200, 0, 800, 800);
222 final Rect containerAppBounds = newParentConfig.windowConfiguration.getAppBounds();
223 final Rect containerBounds = newParentConfig.windowConfiguration.getBounds();
224 containerBounds.set(0, 0, 600, 800);
Garfield Tane8d84ab2019-10-11 09:49:40 -0700225 mActivity.onConfigurationChanged(newParentConfig);
Riddle Hsub398da32019-01-21 21:48:16 +0800226
Garfield Tane8d84ab2019-10-11 09:49:40 -0700227 assertTrue(mActivity.hasSizeCompatBounds());
228 assertEquals(containerAppBounds, mActivity.getBounds());
Riddle Hsub398da32019-01-21 21:48:16 +0800229 assertEquals((float) containerAppBounds.width() / fixedBounds.width(),
Garfield Tane8d84ab2019-10-11 09:49:40 -0700230 mActivity.getSizeCompatScale(), 0.0001f /* delta */);
Riddle Hsub398da32019-01-21 21:48:16 +0800231
232 // Change the width of the container to two times bigger.
233 containerAppBounds.set(0, 0, 2400, 1600);
234 containerBounds.set(containerAppBounds);
Garfield Tane8d84ab2019-10-11 09:49:40 -0700235 mActivity.onConfigurationChanged(newParentConfig);
Riddle Hsub398da32019-01-21 21:48:16 +0800236
Garfield Tane8d84ab2019-10-11 09:49:40 -0700237 assertTrue(mActivity.hasSizeCompatBounds());
Riddle Hsub398da32019-01-21 21:48:16 +0800238 // Don't scale up, so the bounds keep the same as the fixed width.
Garfield Tane8d84ab2019-10-11 09:49:40 -0700239 assertEquals(fixedBounds.width(), mActivity.getBounds().width());
Riddle Hsub398da32019-01-21 21:48:16 +0800240 // Assert the position is horizontal center.
241 assertEquals((containerAppBounds.width() - fixedBounds.width()) / 2,
Garfield Tane8d84ab2019-10-11 09:49:40 -0700242 mActivity.getBounds().left);
243 assertEquals(1f, mActivity.getSizeCompatScale(), 0.0001f /* delta */);
Riddle Hsub398da32019-01-21 21:48:16 +0800244
245 // Change the width of the container to fit the fixed bounds.
246 containerBounds.set(0, 0, 1200, 2000);
Garfield Tane8d84ab2019-10-11 09:49:40 -0700247 mActivity.onConfigurationChanged(newParentConfig);
Riddle Hsub398da32019-01-21 21:48:16 +0800248 // Assert don't use fixed bounds because the region is enough.
Garfield Tane8d84ab2019-10-11 09:49:40 -0700249 assertFalse(mActivity.hasSizeCompatBounds());
Riddle Hsub398da32019-01-21 21:48:16 +0800250 }
251
252 @Test
Andrii Kulian6b3a3712017-11-02 11:06:47 -0700253 @Presubmit
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700254 public void testGetOrientation() {
Issei Suzuki7b9e2572019-11-14 16:19:54 +0100255 mActivity.setHidden(false);
Wale Ogunwalec17418e2019-10-13 23:00:40 +0200256
Garfield Tane8d84ab2019-10-11 09:49:40 -0700257 mActivity.setOrientation(SCREEN_ORIENTATION_LANDSCAPE);
Wale Ogunwale5e5a68d2017-03-24 17:36:38 -0700258
Garfield Tane8d84ab2019-10-11 09:49:40 -0700259 mActivity.setOccludesParent(false);
Wale Ogunwale83b8a6b2019-06-27 20:15:15 -0700260 // Can specify orientation if app doesn't occludes parent.
Garfield Tane8d84ab2019-10-11 09:49:40 -0700261 assertEquals(SCREEN_ORIENTATION_LANDSCAPE, mActivity.getOrientation());
Wale Ogunwale5e5a68d2017-03-24 17:36:38 -0700262
Garfield Tane8d84ab2019-10-11 09:49:40 -0700263 mActivity.setOccludesParent(true);
Issei Suzuki7b9e2572019-11-14 16:19:54 +0100264 mActivity.setHidden(true);
Wale Ogunwale83b8a6b2019-06-27 20:15:15 -0700265 // Can not specify orientation if app isn't visible even though it occludes parent.
Garfield Tane8d84ab2019-10-11 09:49:40 -0700266 assertEquals(SCREEN_ORIENTATION_UNSET, mActivity.getOrientation());
Wale Ogunwale5e5a68d2017-03-24 17:36:38 -0700267 // Can specify orientation if the current orientation candidate is orientation behind.
Tadashi G. Takaokabf0d57b2018-11-19 16:09:58 +0900268 assertEquals(SCREEN_ORIENTATION_LANDSCAPE,
Garfield Tane8d84ab2019-10-11 09:49:40 -0700269 mActivity.getOrientation(SCREEN_ORIENTATION_BEHIND));
Wale Ogunwale5e5a68d2017-03-24 17:36:38 -0700270 }
Bryce Lee081554b2017-05-25 07:52:12 -0700271
272 @Test
Andrii Kulian6b3a3712017-11-02 11:06:47 -0700273 @Presubmit
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700274 public void testKeyguardFlagsDuringRelaunch() {
Bryce Lee081554b2017-05-25 07:52:12 -0700275 final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(
276 TYPE_BASE_APPLICATION);
277 attrs.flags |= FLAG_SHOW_WHEN_LOCKED | FLAG_DISMISS_KEYGUARD;
278 attrs.setTitle("AppWindow");
Garfield Tane8d84ab2019-10-11 09:49:40 -0700279 final WindowTestUtils.TestWindowState appWindow = createWindowState(attrs, mActivity);
Bryce Lee081554b2017-05-25 07:52:12 -0700280
281 // Add window with show when locked flag
Garfield Tane8d84ab2019-10-11 09:49:40 -0700282 mActivity.addWindow(appWindow);
283 assertTrue(mActivity.containsShowWhenLockedWindow() && mActivity.containsDismissKeyguardWindow());
Bryce Lee081554b2017-05-25 07:52:12 -0700284
285 // Start relaunching
Garfield Tane8d84ab2019-10-11 09:49:40 -0700286 mActivity.startRelaunching();
287 assertTrue(mActivity.containsShowWhenLockedWindow() && mActivity.containsDismissKeyguardWindow());
Bryce Lee081554b2017-05-25 07:52:12 -0700288
289 // Remove window and make sure that we still report back flag
Garfield Tane8d84ab2019-10-11 09:49:40 -0700290 mActivity.removeChild(appWindow);
291 assertTrue(mActivity.containsShowWhenLockedWindow() && mActivity.containsDismissKeyguardWindow());
Bryce Lee081554b2017-05-25 07:52:12 -0700292
293 // Finish relaunching and ensure flag is now not reported
Garfield Tane8d84ab2019-10-11 09:49:40 -0700294 mActivity.finishRelaunching();
Tadashi G. Takaokabf0d57b2018-11-19 16:09:58 +0900295 assertFalse(
Garfield Tane8d84ab2019-10-11 09:49:40 -0700296 mActivity.containsShowWhenLockedWindow() || mActivity.containsDismissKeyguardWindow());
Bryce Lee081554b2017-05-25 07:52:12 -0700297 }
Jorim Jaggiab9fcb22018-03-15 23:46:12 +0100298
299 @Test
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700300 public void testStuckExitingWindow() {
Jorim Jaggiab9fcb22018-03-15 23:46:12 +0100301 final WindowState closingWindow = createWindow(null, FIRST_APPLICATION_WINDOW,
302 "closingWindow");
303 closingWindow.mAnimatingExit = true;
304 closingWindow.mRemoveOnExit = true;
Garfield Tane8d84ab2019-10-11 09:49:40 -0700305 closingWindow.mActivityRecord.commitVisibility(null, false /* visible */, TRANSIT_UNSET,
Jorim Jaggiab9fcb22018-03-15 23:46:12 +0100306 true /* performLayout */, false /* isVoiceInteraction */);
307
308 // We pretended that we were running an exit animation, but that should have been cleared up
Garfield Tane8d84ab2019-10-11 09:49:40 -0700309 // by changing visibility of ActivityRecord
Jorim Jaggiab9fcb22018-03-15 23:46:12 +0100310 closingWindow.removeIfPossible();
311 assertTrue(closingWindow.mRemoved);
312 }
Riddle Hsua118b3a2018-10-11 22:05:06 +0800313
314 @Test
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800315 public void testSetOrientation() {
Issei Suzuki7b9e2572019-11-14 16:19:54 +0100316 mActivity.setHidden(false);
Wale Ogunwalec17418e2019-10-13 23:00:40 +0200317
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800318 // Assert orientation is unspecified to start.
Garfield Tane8d84ab2019-10-11 09:49:40 -0700319 assertEquals(SCREEN_ORIENTATION_UNSPECIFIED, mActivity.getOrientation());
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800320
Garfield Tane8d84ab2019-10-11 09:49:40 -0700321 mActivity.setOrientation(SCREEN_ORIENTATION_LANDSCAPE);
322 assertEquals(SCREEN_ORIENTATION_LANDSCAPE, mActivity.getOrientation());
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800323
Garfield Tane8d84ab2019-10-11 09:49:40 -0700324 mDisplayContent.removeAppToken(mActivity.token);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800325 // Assert orientation is unset to after container is removed.
Garfield Tane8d84ab2019-10-11 09:49:40 -0700326 assertEquals(SCREEN_ORIENTATION_UNSET, mActivity.getOrientation());
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800327
328 // Reset display frozen state
329 mWm.mDisplayFrozen = false;
330 }
331
332 @Test
Wale Ogunwaleda8b8272018-11-29 19:37:37 -0800333 public void testReportOrientationChange() {
Garfield Tane8d84ab2019-10-11 09:49:40 -0700334 mActivity.setOrientation(SCREEN_ORIENTATION_LANDSCAPE);
Garfield Tanb6776602019-02-20 14:44:26 -0800335
Riddle Hsu73f53572019-09-23 23:13:01 +0800336 mDisplayContent.getDisplayRotation().setFixedToUserRotation(
337 DisplayRotation.FIXED_TO_USER_ROTATION_ENABLED);
Wale Ogunwale2322bed2019-10-10 17:24:19 +0200338 reset(mTask);
Garfield Tane8d84ab2019-10-11 09:49:40 -0700339 mActivity.reportDescendantOrientationChangeIfNeeded();
Wale Ogunwale2322bed2019-10-10 17:24:19 +0200340 verify(mTask).onConfigurationChanged(any(Configuration.class));
Garfield Tanb6776602019-02-20 14:44:26 -0800341 }
342
343 @Test
Jeff Chang3b19efb2019-05-14 19:21:00 +0800344 @FlakyTest(bugId = 131176283)
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800345 public void testCreateRemoveStartingWindow() {
Garfield Tane8d84ab2019-10-11 09:49:40 -0700346 mActivity.addStartingWindow(mPackageName,
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800347 android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false, true,
348 false, false);
349 waitUntilHandlersIdle();
Garfield Tane8d84ab2019-10-11 09:49:40 -0700350 assertHasStartingWindow(mActivity);
351 mActivity.removeStartingWindow();
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800352 waitUntilHandlersIdle();
Garfield Tane8d84ab2019-10-11 09:49:40 -0700353 assertNoStartingWindow(mActivity);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800354 }
355
356 @Test
Yunfan Chenc1caf6b2019-04-12 13:58:51 +0900357 @FlakyTest(bugId = 130392471)
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800358 public void testAddRemoveRace() {
359 // There was once a race condition between adding and removing starting windows
360 for (int i = 0; i < 1000; i++) {
Garfield Tane8d84ab2019-10-11 09:49:40 -0700361 final ActivityRecord appToken = createIsolatedTestActivityRecord();
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800362
363 appToken.addStartingWindow(mPackageName,
364 android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false, true,
365 false, false);
366 appToken.removeStartingWindow();
367 waitUntilHandlersIdle();
368 assertNoStartingWindow(appToken);
369
370 appToken.getParent().getParent().removeImmediately();
371 }
372 }
373
374 @Test
375 public void testTransferStartingWindow() {
Garfield Tane8d84ab2019-10-11 09:49:40 -0700376 final ActivityRecord activity1 = createIsolatedTestActivityRecord();
377 final ActivityRecord activity2 = createIsolatedTestActivityRecord();
378 activity1.addStartingWindow(mPackageName,
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800379 android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false, true,
380 false, false);
381 waitUntilHandlersIdle();
Garfield Tane8d84ab2019-10-11 09:49:40 -0700382 activity2.addStartingWindow(mPackageName,
383 android.R.style.Theme, null, "Test", 0, 0, 0, 0, activity1.appToken.asBinder(),
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800384 true, true, false, true, false, false);
385 waitUntilHandlersIdle();
Garfield Tane8d84ab2019-10-11 09:49:40 -0700386 assertNoStartingWindow(activity1);
387 assertHasStartingWindow(activity2);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800388 }
389
390 @Test
391 public void testTransferStartingWindowWhileCreating() {
Garfield Tane8d84ab2019-10-11 09:49:40 -0700392 final ActivityRecord activity1 = createIsolatedTestActivityRecord();
393 final ActivityRecord activity2 = createIsolatedTestActivityRecord();
394 ((TestWindowManagerPolicy) activity1.mWmService.mPolicy).setRunnableWhenAddingSplashScreen(
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800395 () -> {
396 // Surprise, ...! Transfer window in the middle of the creation flow.
Garfield Tane8d84ab2019-10-11 09:49:40 -0700397 activity2.addStartingWindow(mPackageName,
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800398 android.R.style.Theme, null, "Test", 0, 0, 0, 0,
Garfield Tane8d84ab2019-10-11 09:49:40 -0700399 activity1.appToken.asBinder(), true, true, false,
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800400 true, false, false);
401 });
Garfield Tane8d84ab2019-10-11 09:49:40 -0700402 activity1.addStartingWindow(mPackageName,
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800403 android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false, true,
404 false, false);
405 waitUntilHandlersIdle();
Garfield Tane8d84ab2019-10-11 09:49:40 -0700406 assertNoStartingWindow(activity1);
407 assertHasStartingWindow(activity2);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800408 }
409
Garfield Tane8d84ab2019-10-11 09:49:40 -0700410 private ActivityRecord createIsolatedTestActivityRecord() {
Wale Ogunwalebebd8cd2019-10-28 15:53:31 -0700411 final ActivityStack taskStack = createTaskStackOnDisplay(mDisplayContent);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800412 final Task task = createTaskInStack(taskStack, 0 /* userId */);
Garfield Tane8d84ab2019-10-11 09:49:40 -0700413 return createTestActivityRecordForGivenTask(task);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800414 }
415
Garfield Tane8d84ab2019-10-11 09:49:40 -0700416 private ActivityRecord createTestActivityRecordForGivenTask(Task task) {
417 final ActivityRecord activity =
418 WindowTestUtils.createTestActivityRecord(mDisplayContent);
419 task.addChild(activity, 0);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800420 waitUntilHandlersIdle();
Garfield Tane8d84ab2019-10-11 09:49:40 -0700421 return activity;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800422 }
423
424 @Test
425 public void testTryTransferStartingWindowFromHiddenAboveToken() {
426 // Add two tasks on top of each other.
Garfield Tane8d84ab2019-10-11 09:49:40 -0700427 final ActivityRecord activityTop = createIsolatedTestActivityRecord();
428 final ActivityRecord activityBottom =
429 createTestActivityRecordForGivenTask(activityTop.getTask());
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800430
431 // Add a starting window.
Garfield Tane8d84ab2019-10-11 09:49:40 -0700432 activityTop.addStartingWindow(mPackageName,
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800433 android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false, true,
434 false, false);
435 waitUntilHandlersIdle();
436
437 // Make the top one invisible, and try transferring the starting window from the top to the
438 // bottom one.
Garfield Tane8d84ab2019-10-11 09:49:40 -0700439 activityTop.setVisibility(false, false);
440 activityBottom.transferStartingWindowFromHiddenAboveTokenIfNeeded();
Yunfan Chendcb1fcf2019-02-07 19:08:41 +0900441 waitUntilHandlersIdle();
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800442
443 // Assert that the bottom window now has the starting window.
Garfield Tane8d84ab2019-10-11 09:49:40 -0700444 assertNoStartingWindow(activityTop);
445 assertHasStartingWindow(activityBottom);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800446 }
447
Evan Rosky641daea2019-04-24 14:45:24 -0700448 @Test
449 public void testTransitionAnimationBounds() {
Wale Ogunwale2322bed2019-10-10 17:24:19 +0200450 removeGlobalMinSizeRestriction();
Evan Rosky641daea2019-04-24 14:45:24 -0700451 final Rect stackBounds = new Rect(0, 0, 1000, 600);
452 final Rect taskBounds = new Rect(100, 400, 600, 800);
453 mStack.setBounds(stackBounds);
454 mTask.setBounds(taskBounds);
455
456 // Check that anim bounds for freeform window match task bounds
457 mTask.setWindowingMode(WINDOWING_MODE_FREEFORM);
Wale Ogunwale2322bed2019-10-10 17:24:19 +0200458 assertEquals(mTask.getBounds(), mActivity.getAnimationBounds(STACK_CLIP_NONE));
Evan Rosky641daea2019-04-24 14:45:24 -0700459
460 // STACK_CLIP_AFTER_ANIM should use task bounds since they will be clipped by
461 // bounds animation layer.
462 mTask.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
Wale Ogunwale2322bed2019-10-10 17:24:19 +0200463 assertEquals(mTask.getBounds(), mActivity.getAnimationBounds(STACK_CLIP_AFTER_ANIM));
Evan Rosky641daea2019-04-24 14:45:24 -0700464
465 // STACK_CLIP_BEFORE_ANIM should use stack bounds since it won't be clipped later.
466 mTask.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
Wale Ogunwale2322bed2019-10-10 17:24:19 +0200467 assertEquals(mStack.getBounds(), mActivity.getAnimationBounds(STACK_CLIP_BEFORE_ANIM));
Evan Rosky641daea2019-04-24 14:45:24 -0700468 }
469
Tarandeep Singh69ab1042019-07-30 13:30:03 -0700470 @Test
471 public void testHasStartingWindow() {
472 final WindowManager.LayoutParams attrs =
473 new WindowManager.LayoutParams(TYPE_APPLICATION_STARTING);
Garfield Tane8d84ab2019-10-11 09:49:40 -0700474 final WindowTestUtils.TestWindowState startingWindow = createWindowState(attrs, mActivity);
475 mActivity.startingDisplayed = true;
476 mActivity.addWindow(startingWindow);
477 assertTrue("Starting window should be present", mActivity.hasStartingWindow());
478 mActivity.startingDisplayed = false;
479 assertTrue("Starting window should be present", mActivity.hasStartingWindow());
Tarandeep Singh69ab1042019-07-30 13:30:03 -0700480
Garfield Tane8d84ab2019-10-11 09:49:40 -0700481 mActivity.removeChild(startingWindow);
482 assertFalse("Starting window should not be present", mActivity.hasStartingWindow());
Tarandeep Singh69ab1042019-07-30 13:30:03 -0700483 }
484
Garfield Tane8d84ab2019-10-11 09:49:40 -0700485 private void assertHasStartingWindow(ActivityRecord atoken) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800486 assertNotNull(atoken.startingSurface);
chaviwa8f07a72019-05-01 16:25:39 -0700487 assertNotNull(atoken.mStartingData);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800488 assertNotNull(atoken.startingWindow);
489 }
490
Garfield Tane8d84ab2019-10-11 09:49:40 -0700491 private void assertNoStartingWindow(ActivityRecord atoken) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800492 assertNull(atoken.startingSurface);
493 assertNull(atoken.startingWindow);
chaviwa8f07a72019-05-01 16:25:39 -0700494 assertNull(atoken.mStartingData);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800495 atoken.forAllWindows(windowState -> {
496 assertFalse(windowState.getBaseType() == TYPE_APPLICATION_STARTING);
497 }, true);
498 }
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700499}