blob: 8f18f648f8f0ab9dbde7929e525850a249eee8a5 [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;
wilsonshihca274ed2020-05-05 17:32:21 +080034import static android.view.WindowManager.TRANSIT_ACTIVITY_OPEN;
Brett Chabota26eda92018-07-23 13:08:30 -070035
Yunfan Chen1ee84ea2018-11-13 16:03:37 -080036import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
37
Tadashi G. Takaokabf0d57b2018-11-19 16:09:58 +090038import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
wilsonshihca274ed2020-05-05 17:32:21 +080039import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
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;
Garfield Tana3f19032019-11-19 18:04:50 -080057import android.view.IWindowManager;
Brett Chabota26eda92018-07-23 13:08:30 -070058import android.view.Surface;
59import android.view.WindowManager;
60
Yunfan Chenc1caf6b2019-04-12 13:58:51 +090061import androidx.test.filters.FlakyTest;
Brett Chabota26eda92018-07-23 13:08:30 -070062import androidx.test.filters.SmallTest;
Brett Chabota26eda92018-07-23 13:08:30 -070063
wilsonshihca274ed2020-05-05 17:32:21 +080064import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback;
65
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -070066import org.junit.Before;
Brett Chabota26eda92018-07-23 13:08:30 -070067import org.junit.Test;
Riddle Hsu73f53572019-09-23 23:13:01 +080068import org.junit.runner.RunWith;
Brett Chabota26eda92018-07-23 13:08:30 -070069
Wale Ogunwaled1c37912016-08-16 03:19:39 -070070/**
Garfield Tane8d84ab2019-10-11 09:49:40 -070071 * Tests for the {@link ActivityRecord} class.
Wale Ogunwaled1c37912016-08-16 03:19:39 -070072 *
Wale Ogunwale07bcab72016-10-14 15:30:09 -070073 * Build/Install/Run:
Vishnu Naire6e2b0f2019-02-21 10:41:00 -080074 * atest WmTests:AppWindowTokenTests
Wale Ogunwaled1c37912016-08-16 03:19:39 -070075 */
76@SmallTest
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -070077@Presubmit
Riddle Hsu73f53572019-09-23 23:13:01 +080078@RunWith(WindowTestRunner.class)
Wale Ogunwale44fbdf52016-11-16 10:18:45 -080079public class AppWindowTokenTests extends WindowTestsBase {
Wale Ogunwaled1c37912016-08-16 03:19:39 -070080
Wale Ogunwalebebd8cd2019-10-28 15:53:31 -070081 ActivityStack mStack;
Robert Carrb1579c82017-09-05 14:54:47 -070082 Task mTask;
Garfield Tane8d84ab2019-10-11 09:49:40 -070083 ActivityRecord mActivity;
Robert Carrb1579c82017-09-05 14:54:47 -070084
Yunfan Chen1ee84ea2018-11-13 16:03:37 -080085 private final String mPackageName = getInstrumentation().getTargetContext().getPackageName();
86
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -070087 @Before
Robert Carrb1579c82017-09-05 14:54:47 -070088 public void setUp() throws Exception {
Robert Carrb1579c82017-09-05 14:54:47 -070089 mStack = createTaskStackOnDisplay(mDisplayContent);
90 mTask = createTaskInStack(mStack, 0 /* userId */);
Garfield Tane8d84ab2019-10-11 09:49:40 -070091 mActivity = WindowTestUtils.createTestActivityRecord(mDisplayContent);
Robert Carrb1579c82017-09-05 14:54:47 -070092
Garfield Tane8d84ab2019-10-11 09:49:40 -070093 mTask.addChild(mActivity, 0);
Robert Carrb1579c82017-09-05 14:54:47 -070094 }
95
Wale Ogunwalea7e3b642016-08-29 10:15:34 -070096 @Test
Andrii Kulian6b3a3712017-11-02 11:06:47 -070097 @Presubmit
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -070098 public void testAddWindow_Order() {
Garfield Tane8d84ab2019-10-11 09:49:40 -070099 assertEquals(0, mActivity.getChildCount());
Wale Ogunwale07bcab72016-10-14 15:30:09 -0700100
Garfield Tane8d84ab2019-10-11 09:49:40 -0700101 final WindowState win1 = createWindow(null, TYPE_APPLICATION, mActivity, "win1");
102 final WindowState startingWin = createWindow(null, TYPE_APPLICATION_STARTING, mActivity,
Wale Ogunwale44fbdf52016-11-16 10:18:45 -0800103 "startingWin");
Garfield Tane8d84ab2019-10-11 09:49:40 -0700104 final WindowState baseWin = createWindow(null, TYPE_BASE_APPLICATION, mActivity, "baseWin");
105 final WindowState win4 = createWindow(null, TYPE_APPLICATION, mActivity, "win4");
Wale Ogunwale07bcab72016-10-14 15:30:09 -0700106
Wale Ogunwale07bcab72016-10-14 15:30:09 -0700107 // Should not contain the windows that were added above.
Garfield Tane8d84ab2019-10-11 09:49:40 -0700108 assertEquals(4, mActivity.getChildCount());
109 assertTrue(mActivity.mChildren.contains(win1));
110 assertTrue(mActivity.mChildren.contains(startingWin));
111 assertTrue(mActivity.mChildren.contains(baseWin));
112 assertTrue(mActivity.mChildren.contains(win4));
Wale Ogunwale07bcab72016-10-14 15:30:09 -0700113
114 // The starting window should be on-top of all other windows.
Garfield Tane8d84ab2019-10-11 09:49:40 -0700115 assertEquals(startingWin, mActivity.mChildren.peekLast());
Wale Ogunwale07bcab72016-10-14 15:30:09 -0700116
117 // The base application window should be below all other windows.
Garfield Tane8d84ab2019-10-11 09:49:40 -0700118 assertEquals(baseWin, mActivity.mChildren.peekFirst());
119 mActivity.removeImmediately();
Wale Ogunwale07bcab72016-10-14 15:30:09 -0700120 }
121
122 @Test
Andrii Kulian6b3a3712017-11-02 11:06:47 -0700123 @Presubmit
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700124 public void testFindMainWindow() {
Garfield Tane8d84ab2019-10-11 09:49:40 -0700125 assertNull(mActivity.findMainWindow());
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700126
Garfield Tane8d84ab2019-10-11 09:49:40 -0700127 final WindowState window1 = createWindow(null, TYPE_BASE_APPLICATION, mActivity, "window1");
128 final WindowState window11 = createWindow(window1, FIRST_SUB_WINDOW, mActivity, "window11");
129 final WindowState window12 = createWindow(window1, FIRST_SUB_WINDOW, mActivity, "window12");
130 assertEquals(window1, mActivity.findMainWindow());
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700131 window1.mAnimatingExit = true;
Garfield Tane8d84ab2019-10-11 09:49:40 -0700132 assertEquals(window1, mActivity.findMainWindow());
133 final WindowState window2 = createWindow(null, TYPE_APPLICATION_STARTING, mActivity,
Tadashi G. Takaokabf0d57b2018-11-19 16:09:58 +0900134 "window2");
Garfield Tane8d84ab2019-10-11 09:49:40 -0700135 assertEquals(window2, mActivity.findMainWindow());
136 mActivity.removeImmediately();
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700137 }
Andrii Kulian4ede3e02017-01-12 11:52:31 -0800138
139 @Test
Andrii Kulian6b3a3712017-11-02 11:06:47 -0700140 @Presubmit
Riddle Hsu84bc3d72019-12-19 19:24:07 +0800141 public void testGetTopFullscreenOpaqueWindow() {
142 assertNull(mActivity.getTopFullscreenOpaqueWindow());
Jorim Jaggi87fdbcb2017-08-17 13:41:11 +0200143
Garfield Tane8d84ab2019-10-11 09:49:40 -0700144 final WindowState window1 = createWindow(null, TYPE_BASE_APPLICATION, mActivity, "window1");
145 final WindowState window11 = createWindow(null, TYPE_APPLICATION, mActivity, "window11");
146 final WindowState window12 = createWindow(null, TYPE_APPLICATION, mActivity, "window12");
Riddle Hsu84bc3d72019-12-19 19:24:07 +0800147 assertEquals(window12, mActivity.getTopFullscreenOpaqueWindow());
Jorim Jaggi87fdbcb2017-08-17 13:41:11 +0200148 window12.mAttrs.width = 500;
Riddle Hsu84bc3d72019-12-19 19:24:07 +0800149 assertEquals(window11, mActivity.getTopFullscreenOpaqueWindow());
Jorim Jaggi87fdbcb2017-08-17 13:41:11 +0200150 window11.mAttrs.width = 500;
Riddle Hsu84bc3d72019-12-19 19:24:07 +0800151 assertEquals(window1, mActivity.getTopFullscreenOpaqueWindow());
152 window1.mAttrs.alpha = 0f;
153 assertNull(mActivity.getTopFullscreenOpaqueWindow());
Garfield Tane8d84ab2019-10-11 09:49:40 -0700154 mActivity.removeImmediately();
Jorim Jaggi87fdbcb2017-08-17 13:41:11 +0200155 }
156
157 @Test
Wale Ogunwale815c7cb2019-05-02 08:04:01 -0700158 @FlakyTest(bugId = 131005232)
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700159 public void testLandscapeSeascapeRotationByApp() {
Andrii Kulian4ede3e02017-01-12 11:52:31 -0800160 final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(
161 TYPE_BASE_APPLICATION);
162 attrs.setTitle("AppWindow");
Garfield Tane8d84ab2019-10-11 09:49:40 -0700163 final WindowTestUtils.TestWindowState appWindow = createWindowState(attrs, mActivity);
164 mActivity.addWindow(appWindow);
Andrii Kulian4ede3e02017-01-12 11:52:31 -0800165
166 // Set initial orientation and update.
Garfield Tane8d84ab2019-10-11 09:49:40 -0700167 mActivity.setOrientation(SCREEN_ORIENTATION_LANDSCAPE);
Riddle Hsuccf09402019-08-13 00:33:06 +0800168 mDisplayContent.updateOrientation(
Garfield Tan90b04282018-12-11 14:04:42 -0800169 mDisplayContent.getRequestedOverrideConfiguration(),
170 null /* freezeThisOneIfNeeded */, false /* forceUpdate */);
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700171 assertEquals(SCREEN_ORIENTATION_LANDSCAPE, mDisplayContent.getLastOrientation());
Tadashi G. Takaokabf0d57b2018-11-19 16:09:58 +0900172 appWindow.mResizeReported = false;
Andrii Kulian4ede3e02017-01-12 11:52:31 -0800173
174 // Update the orientation to perform 180 degree rotation and check that resize was reported.
Garfield Tane8d84ab2019-10-11 09:49:40 -0700175 mActivity.setOrientation(SCREEN_ORIENTATION_REVERSE_LANDSCAPE);
Riddle Hsuccf09402019-08-13 00:33:06 +0800176 mDisplayContent.updateOrientation(
Garfield Tan90b04282018-12-11 14:04:42 -0800177 mDisplayContent.getRequestedOverrideConfiguration(),
178 null /* freezeThisOneIfNeeded */, false /* forceUpdate */);
Yunfan Chen0530fe72019-02-12 15:05:49 +0900179 // In this test, DC will not get config update. Set the waiting flag to false.
180 mDisplayContent.mWaitingForConfig = false;
Riddle Hsu72d6dc32020-03-25 22:58:00 +0800181 mWm.mRoot.performSurfacePlacement();
Wale Ogunwale11cc5162017-04-25 20:29:13 -0700182 assertEquals(SCREEN_ORIENTATION_REVERSE_LANDSCAPE, mDisplayContent.getLastOrientation());
Tadashi G. Takaokabf0d57b2018-11-19 16:09:58 +0900183 assertTrue(appWindow.mResizeReported);
Wale Ogunwale1666e312016-12-16 11:27:18 -0800184 appWindow.removeImmediately();
Andrii Kulian4ede3e02017-01-12 11:52:31 -0800185 }
186
187 @Test
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700188 public void testLandscapeSeascapeRotationByPolicy() {
Louis Chang677921f2019-12-06 16:44:24 +0800189 // This instance has been spied in {@link TestDisplayContent}.
Wale Ogunwale8a1860a2019-06-05 08:57:19 -0700190 final DisplayRotation displayRotation = mDisplayContent.getDisplayRotation();
Riddle Hsu5ce4bb32018-07-18 16:11:30 +0800191
Andrii Kulian4ede3e02017-01-12 11:52:31 -0800192 final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(
193 TYPE_BASE_APPLICATION);
Wale Ogunwale8a1860a2019-06-05 08:57:19 -0700194 attrs.setTitle("RotationByPolicy");
Garfield Tane8d84ab2019-10-11 09:49:40 -0700195 final WindowTestUtils.TestWindowState appWindow = createWindowState(attrs, mActivity);
196 mActivity.addWindow(appWindow);
Andrii Kulian4ede3e02017-01-12 11:52:31 -0800197
198 // Set initial orientation and update.
Wale Ogunwale8a1860a2019-06-05 08:57:19 -0700199 performRotation(displayRotation, Surface.ROTATION_90);
Tadashi G. Takaokabf0d57b2018-11-19 16:09:58 +0900200 appWindow.mResizeReported = false;
Andrii Kulian4ede3e02017-01-12 11:52:31 -0800201
202 // Update the rotation to perform 180 degree rotation and check that resize was reported.
Wale Ogunwale8a1860a2019-06-05 08:57:19 -0700203 performRotation(displayRotation, Surface.ROTATION_270);
Tadashi G. Takaokabf0d57b2018-11-19 16:09:58 +0900204 assertTrue(appWindow.mResizeReported);
Riddle Hsu5ce4bb32018-07-18 16:11:30 +0800205
Wale Ogunwale1666e312016-12-16 11:27:18 -0800206 appWindow.removeImmediately();
Andrii Kulian4ede3e02017-01-12 11:52:31 -0800207 }
Bryce Lee310de9e2017-03-15 10:18:21 -0700208
Riddle Hsu5ce4bb32018-07-18 16:11:30 +0800209 private void performRotation(DisplayRotation spiedRotation, int rotationToReport) {
210 doReturn(rotationToReport).when(spiedRotation).rotationForOrientation(anyInt(), anyInt());
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700211 mWm.updateRotation(false, false);
Bryce Lee310de9e2017-03-15 10:18:21 -0700212 }
Wale Ogunwale5e5a68d2017-03-24 17:36:38 -0700213
214 @Test
Andrii Kulian6b3a3712017-11-02 11:06:47 -0700215 @Presubmit
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700216 public void testGetOrientation() {
Issei Suzukif2f6c912019-11-08 11:24:18 +0100217 mActivity.setVisible(true);
Wale Ogunwalec17418e2019-10-13 23:00:40 +0200218
Garfield Tane8d84ab2019-10-11 09:49:40 -0700219 mActivity.setOrientation(SCREEN_ORIENTATION_LANDSCAPE);
Wale Ogunwale5e5a68d2017-03-24 17:36:38 -0700220
Garfield Tane8d84ab2019-10-11 09:49:40 -0700221 mActivity.setOccludesParent(false);
Wale Ogunwale83b8a6b2019-06-27 20:15:15 -0700222 // Can specify orientation if app doesn't occludes parent.
Garfield Tane8d84ab2019-10-11 09:49:40 -0700223 assertEquals(SCREEN_ORIENTATION_LANDSCAPE, mActivity.getOrientation());
Wale Ogunwale5e5a68d2017-03-24 17:36:38 -0700224
Garfield Tane8d84ab2019-10-11 09:49:40 -0700225 mActivity.setOccludesParent(true);
Issei Suzukif2f6c912019-11-08 11:24:18 +0100226 mActivity.setVisible(false);
Wale Ogunwale83b8a6b2019-06-27 20:15:15 -0700227 // Can not specify orientation if app isn't visible even though it occludes parent.
Garfield Tane8d84ab2019-10-11 09:49:40 -0700228 assertEquals(SCREEN_ORIENTATION_UNSET, mActivity.getOrientation());
Wale Ogunwale5e5a68d2017-03-24 17:36:38 -0700229 // Can specify orientation if the current orientation candidate is orientation behind.
Tadashi G. Takaokabf0d57b2018-11-19 16:09:58 +0900230 assertEquals(SCREEN_ORIENTATION_LANDSCAPE,
Garfield Tane8d84ab2019-10-11 09:49:40 -0700231 mActivity.getOrientation(SCREEN_ORIENTATION_BEHIND));
Wale Ogunwale5e5a68d2017-03-24 17:36:38 -0700232 }
Bryce Lee081554b2017-05-25 07:52:12 -0700233
234 @Test
Andrii Kulian6b3a3712017-11-02 11:06:47 -0700235 @Presubmit
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700236 public void testKeyguardFlagsDuringRelaunch() {
Bryce Lee081554b2017-05-25 07:52:12 -0700237 final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(
238 TYPE_BASE_APPLICATION);
239 attrs.flags |= FLAG_SHOW_WHEN_LOCKED | FLAG_DISMISS_KEYGUARD;
240 attrs.setTitle("AppWindow");
Garfield Tane8d84ab2019-10-11 09:49:40 -0700241 final WindowTestUtils.TestWindowState appWindow = createWindowState(attrs, mActivity);
Bryce Lee081554b2017-05-25 07:52:12 -0700242
243 // Add window with show when locked flag
Garfield Tane8d84ab2019-10-11 09:49:40 -0700244 mActivity.addWindow(appWindow);
245 assertTrue(mActivity.containsShowWhenLockedWindow() && mActivity.containsDismissKeyguardWindow());
Bryce Lee081554b2017-05-25 07:52:12 -0700246
247 // Start relaunching
Garfield Tane8d84ab2019-10-11 09:49:40 -0700248 mActivity.startRelaunching();
249 assertTrue(mActivity.containsShowWhenLockedWindow() && mActivity.containsDismissKeyguardWindow());
Bryce Lee081554b2017-05-25 07:52:12 -0700250
251 // Remove window and make sure that we still report back flag
Garfield Tane8d84ab2019-10-11 09:49:40 -0700252 mActivity.removeChild(appWindow);
253 assertTrue(mActivity.containsShowWhenLockedWindow() && mActivity.containsDismissKeyguardWindow());
Bryce Lee081554b2017-05-25 07:52:12 -0700254
255 // Finish relaunching and ensure flag is now not reported
Garfield Tane8d84ab2019-10-11 09:49:40 -0700256 mActivity.finishRelaunching();
Tadashi G. Takaokabf0d57b2018-11-19 16:09:58 +0900257 assertFalse(
Garfield Tane8d84ab2019-10-11 09:49:40 -0700258 mActivity.containsShowWhenLockedWindow() || mActivity.containsDismissKeyguardWindow());
Bryce Lee081554b2017-05-25 07:52:12 -0700259 }
Jorim Jaggiab9fcb22018-03-15 23:46:12 +0100260
261 @Test
Tadashi G. Takaokab6e148c2018-11-03 02:59:06 -0700262 public void testStuckExitingWindow() {
Jorim Jaggiab9fcb22018-03-15 23:46:12 +0100263 final WindowState closingWindow = createWindow(null, FIRST_APPLICATION_WINDOW,
264 "closingWindow");
265 closingWindow.mAnimatingExit = true;
266 closingWindow.mRemoveOnExit = true;
Issei Suzuki2bcbd682019-11-08 13:20:14 +0100267 closingWindow.mActivityRecord.commitVisibility(
268 false /* visible */, true /* performLayout */);
Jorim Jaggiab9fcb22018-03-15 23:46:12 +0100269
270 // We pretended that we were running an exit animation, but that should have been cleared up
Garfield Tane8d84ab2019-10-11 09:49:40 -0700271 // by changing visibility of ActivityRecord
Jorim Jaggiab9fcb22018-03-15 23:46:12 +0100272 closingWindow.removeIfPossible();
273 assertTrue(closingWindow.mRemoved);
274 }
Riddle Hsua118b3a2018-10-11 22:05:06 +0800275
276 @Test
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800277 public void testSetOrientation() {
Issei Suzukif2f6c912019-11-08 11:24:18 +0100278 mActivity.setVisible(true);
Wale Ogunwalec17418e2019-10-13 23:00:40 +0200279
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800280 // Assert orientation is unspecified to start.
Garfield Tane8d84ab2019-10-11 09:49:40 -0700281 assertEquals(SCREEN_ORIENTATION_UNSPECIFIED, mActivity.getOrientation());
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800282
Garfield Tane8d84ab2019-10-11 09:49:40 -0700283 mActivity.setOrientation(SCREEN_ORIENTATION_LANDSCAPE);
284 assertEquals(SCREEN_ORIENTATION_LANDSCAPE, mActivity.getOrientation());
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800285
Garfield Tane8d84ab2019-10-11 09:49:40 -0700286 mDisplayContent.removeAppToken(mActivity.token);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800287 // Assert orientation is unset to after container is removed.
Garfield Tane8d84ab2019-10-11 09:49:40 -0700288 assertEquals(SCREEN_ORIENTATION_UNSET, mActivity.getOrientation());
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800289
290 // Reset display frozen state
291 mWm.mDisplayFrozen = false;
292 }
293
294 @Test
Wale Ogunwaleda8b8272018-11-29 19:37:37 -0800295 public void testReportOrientationChange() {
Garfield Tane8d84ab2019-10-11 09:49:40 -0700296 mActivity.setOrientation(SCREEN_ORIENTATION_LANDSCAPE);
Garfield Tanb6776602019-02-20 14:44:26 -0800297
Riddle Hsu73f53572019-09-23 23:13:01 +0800298 mDisplayContent.getDisplayRotation().setFixedToUserRotation(
Garfield Tana3f19032019-11-19 18:04:50 -0800299 IWindowManager.FIXED_TO_USER_ROTATION_ENABLED);
Wale Ogunwale2322bed2019-10-10 17:24:19 +0200300 reset(mTask);
Garfield Tane8d84ab2019-10-11 09:49:40 -0700301 mActivity.reportDescendantOrientationChangeIfNeeded();
Wale Ogunwale2322bed2019-10-10 17:24:19 +0200302 verify(mTask).onConfigurationChanged(any(Configuration.class));
Garfield Tanb6776602019-02-20 14:44:26 -0800303 }
304
305 @Test
Jeff Chang3b19efb2019-05-14 19:21:00 +0800306 @FlakyTest(bugId = 131176283)
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800307 public void testCreateRemoveStartingWindow() {
Garfield Tane8d84ab2019-10-11 09:49:40 -0700308 mActivity.addStartingWindow(mPackageName,
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800309 android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false, true,
Riddle Hsueae6ef3e2020-05-13 01:07:33 +0800310 false);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800311 waitUntilHandlersIdle();
Garfield Tane8d84ab2019-10-11 09:49:40 -0700312 assertHasStartingWindow(mActivity);
313 mActivity.removeStartingWindow();
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800314 waitUntilHandlersIdle();
Garfield Tane8d84ab2019-10-11 09:49:40 -0700315 assertNoStartingWindow(mActivity);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800316 }
317
318 @Test
319 public void testAddRemoveRace() {
320 // There was once a race condition between adding and removing starting windows
Yunfan Chen4c6a8fc2020-05-13 14:47:38 +0900321 final ActivityRecord appToken = mAppWindow.mActivityRecord;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800322 for (int i = 0; i < 1000; i++) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800323 appToken.addStartingWindow(mPackageName,
324 android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false, true,
Riddle Hsueae6ef3e2020-05-13 01:07:33 +0800325 false);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800326 appToken.removeStartingWindow();
327 waitUntilHandlersIdle();
328 assertNoStartingWindow(appToken);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800329 }
330 }
331
332 @Test
333 public void testTransferStartingWindow() {
Garfield Tane8d84ab2019-10-11 09:49:40 -0700334 final ActivityRecord activity1 = createIsolatedTestActivityRecord();
335 final ActivityRecord activity2 = createIsolatedTestActivityRecord();
336 activity1.addStartingWindow(mPackageName,
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800337 android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false, true,
Riddle Hsueae6ef3e2020-05-13 01:07:33 +0800338 false);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800339 waitUntilHandlersIdle();
Garfield Tane8d84ab2019-10-11 09:49:40 -0700340 activity2.addStartingWindow(mPackageName,
341 android.R.style.Theme, null, "Test", 0, 0, 0, 0, activity1.appToken.asBinder(),
Riddle Hsueae6ef3e2020-05-13 01:07:33 +0800342 true, true, false, true, false);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800343 waitUntilHandlersIdle();
Garfield Tane8d84ab2019-10-11 09:49:40 -0700344 assertNoStartingWindow(activity1);
345 assertHasStartingWindow(activity2);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800346 }
347
348 @Test
349 public void testTransferStartingWindowWhileCreating() {
Garfield Tane8d84ab2019-10-11 09:49:40 -0700350 final ActivityRecord activity1 = createIsolatedTestActivityRecord();
351 final ActivityRecord activity2 = createIsolatedTestActivityRecord();
352 ((TestWindowManagerPolicy) activity1.mWmService.mPolicy).setRunnableWhenAddingSplashScreen(
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800353 () -> {
354 // Surprise, ...! Transfer window in the middle of the creation flow.
Garfield Tane8d84ab2019-10-11 09:49:40 -0700355 activity2.addStartingWindow(mPackageName,
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800356 android.R.style.Theme, null, "Test", 0, 0, 0, 0,
Garfield Tane8d84ab2019-10-11 09:49:40 -0700357 activity1.appToken.asBinder(), true, true, false,
Riddle Hsueae6ef3e2020-05-13 01:07:33 +0800358 true, false);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800359 });
Garfield Tane8d84ab2019-10-11 09:49:40 -0700360 activity1.addStartingWindow(mPackageName,
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800361 android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false, true,
Riddle Hsueae6ef3e2020-05-13 01:07:33 +0800362 false);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800363 waitUntilHandlersIdle();
Garfield Tane8d84ab2019-10-11 09:49:40 -0700364 assertNoStartingWindow(activity1);
365 assertHasStartingWindow(activity2);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800366 }
367
wilsonshihca274ed2020-05-05 17:32:21 +0800368 @Test
369 public void testTransferStartingWindowCanAnimate() {
370 final ActivityRecord activity1 = createIsolatedTestActivityRecord();
371 final ActivityRecord activity2 = createIsolatedTestActivityRecord();
372 activity1.addStartingWindow(mPackageName,
373 android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false, true,
Riddle Hsueae6ef3e2020-05-13 01:07:33 +0800374 false);
wilsonshihca274ed2020-05-05 17:32:21 +0800375 waitUntilHandlersIdle();
376 activity2.addStartingWindow(mPackageName,
377 android.R.style.Theme, null, "Test", 0, 0, 0, 0, activity1.appToken.asBinder(),
Riddle Hsueae6ef3e2020-05-13 01:07:33 +0800378 true, true, false, true, false);
wilsonshihca274ed2020-05-05 17:32:21 +0800379 waitUntilHandlersIdle();
380 assertNoStartingWindow(activity1);
381 assertHasStartingWindow(activity2);
382
383 // Assert that bottom activity is allowed to do animation.
384 doReturn(true).when(activity2).okToAnimate();
385 doReturn(true).when(activity2).isAnimating();
386 final OnAnimationFinishedCallback onAnimationFinishedCallback =
387 mock(OnAnimationFinishedCallback.class);
388 assertTrue(activity2.applyAnimation(null, TRANSIT_ACTIVITY_OPEN, true, false,
389 onAnimationFinishedCallback));
390 }
391
Garfield Tane8d84ab2019-10-11 09:49:40 -0700392 private ActivityRecord createIsolatedTestActivityRecord() {
Wale Ogunwalebebd8cd2019-10-28 15:53:31 -0700393 final ActivityStack taskStack = createTaskStackOnDisplay(mDisplayContent);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800394 final Task task = createTaskInStack(taskStack, 0 /* userId */);
Garfield Tane8d84ab2019-10-11 09:49:40 -0700395 return createTestActivityRecordForGivenTask(task);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800396 }
397
Garfield Tane8d84ab2019-10-11 09:49:40 -0700398 private ActivityRecord createTestActivityRecordForGivenTask(Task task) {
399 final ActivityRecord activity =
400 WindowTestUtils.createTestActivityRecord(mDisplayContent);
401 task.addChild(activity, 0);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800402 waitUntilHandlersIdle();
Garfield Tane8d84ab2019-10-11 09:49:40 -0700403 return activity;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800404 }
405
406 @Test
407 public void testTryTransferStartingWindowFromHiddenAboveToken() {
408 // Add two tasks on top of each other.
Garfield Tane8d84ab2019-10-11 09:49:40 -0700409 final ActivityRecord activityTop = createIsolatedTestActivityRecord();
410 final ActivityRecord activityBottom =
411 createTestActivityRecordForGivenTask(activityTop.getTask());
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800412
413 // Add a starting window.
Garfield Tane8d84ab2019-10-11 09:49:40 -0700414 activityTop.addStartingWindow(mPackageName,
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800415 android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false, true,
Riddle Hsueae6ef3e2020-05-13 01:07:33 +0800416 false);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800417 waitUntilHandlersIdle();
418
419 // Make the top one invisible, and try transferring the starting window from the top to the
420 // bottom one.
Garfield Tane8d84ab2019-10-11 09:49:40 -0700421 activityTop.setVisibility(false, false);
422 activityBottom.transferStartingWindowFromHiddenAboveTokenIfNeeded();
Yunfan Chendcb1fcf2019-02-07 19:08:41 +0900423 waitUntilHandlersIdle();
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800424
425 // Assert that the bottom window now has the starting window.
Garfield Tane8d84ab2019-10-11 09:49:40 -0700426 assertNoStartingWindow(activityTop);
427 assertHasStartingWindow(activityBottom);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800428 }
429
Evan Rosky641daea2019-04-24 14:45:24 -0700430 @Test
431 public void testTransitionAnimationBounds() {
Wale Ogunwale2322bed2019-10-10 17:24:19 +0200432 removeGlobalMinSizeRestriction();
Evan Rosky641daea2019-04-24 14:45:24 -0700433 final Rect stackBounds = new Rect(0, 0, 1000, 600);
434 final Rect taskBounds = new Rect(100, 400, 600, 800);
435 mStack.setBounds(stackBounds);
436 mTask.setBounds(taskBounds);
437
438 // Check that anim bounds for freeform window match task bounds
439 mTask.setWindowingMode(WINDOWING_MODE_FREEFORM);
Wale Ogunwale2322bed2019-10-10 17:24:19 +0200440 assertEquals(mTask.getBounds(), mActivity.getAnimationBounds(STACK_CLIP_NONE));
Evan Rosky641daea2019-04-24 14:45:24 -0700441
442 // STACK_CLIP_AFTER_ANIM should use task bounds since they will be clipped by
443 // bounds animation layer.
444 mTask.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
Wale Ogunwale2322bed2019-10-10 17:24:19 +0200445 assertEquals(mTask.getBounds(), mActivity.getAnimationBounds(STACK_CLIP_AFTER_ANIM));
Evan Rosky641daea2019-04-24 14:45:24 -0700446
447 // STACK_CLIP_BEFORE_ANIM should use stack bounds since it won't be clipped later.
448 mTask.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
Wale Ogunwale2322bed2019-10-10 17:24:19 +0200449 assertEquals(mStack.getBounds(), mActivity.getAnimationBounds(STACK_CLIP_BEFORE_ANIM));
Evan Rosky641daea2019-04-24 14:45:24 -0700450 }
451
Tarandeep Singh69ab1042019-07-30 13:30:03 -0700452 @Test
453 public void testHasStartingWindow() {
454 final WindowManager.LayoutParams attrs =
455 new WindowManager.LayoutParams(TYPE_APPLICATION_STARTING);
Garfield Tane8d84ab2019-10-11 09:49:40 -0700456 final WindowTestUtils.TestWindowState startingWindow = createWindowState(attrs, mActivity);
457 mActivity.startingDisplayed = true;
458 mActivity.addWindow(startingWindow);
459 assertTrue("Starting window should be present", mActivity.hasStartingWindow());
460 mActivity.startingDisplayed = false;
461 assertTrue("Starting window should be present", mActivity.hasStartingWindow());
Tarandeep Singh69ab1042019-07-30 13:30:03 -0700462
Garfield Tane8d84ab2019-10-11 09:49:40 -0700463 mActivity.removeChild(startingWindow);
464 assertFalse("Starting window should not be present", mActivity.hasStartingWindow());
Tarandeep Singh69ab1042019-07-30 13:30:03 -0700465 }
466
Garfield Tane8d84ab2019-10-11 09:49:40 -0700467 private void assertHasStartingWindow(ActivityRecord atoken) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800468 assertNotNull(atoken.startingSurface);
chaviwa8f07a72019-05-01 16:25:39 -0700469 assertNotNull(atoken.mStartingData);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800470 assertNotNull(atoken.startingWindow);
471 }
472
Garfield Tane8d84ab2019-10-11 09:49:40 -0700473 private void assertNoStartingWindow(ActivityRecord atoken) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800474 assertNull(atoken.startingSurface);
475 assertNull(atoken.startingWindow);
chaviwa8f07a72019-05-01 16:25:39 -0700476 assertNull(atoken.mStartingData);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800477 atoken.forAllWindows(windowState -> {
478 assertFalse(windowState.getBaseType() == TYPE_APPLICATION_STARTING);
479 }, true);
480 }
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700481}