blob: 5c21853b1f598ebc534d249c1061669c9323ddcb [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,
310 false, false);
311 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
Yunfan Chenc1caf6b2019-04-12 13:58:51 +0900319 @FlakyTest(bugId = 130392471)
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800320 public void testAddRemoveRace() {
321 // There was once a race condition between adding and removing starting windows
322 for (int i = 0; i < 1000; i++) {
Garfield Tane8d84ab2019-10-11 09:49:40 -0700323 final ActivityRecord appToken = createIsolatedTestActivityRecord();
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800324
325 appToken.addStartingWindow(mPackageName,
326 android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false, true,
327 false, false);
328 appToken.removeStartingWindow();
329 waitUntilHandlersIdle();
330 assertNoStartingWindow(appToken);
331
332 appToken.getParent().getParent().removeImmediately();
333 }
334 }
335
336 @Test
337 public void testTransferStartingWindow() {
Garfield Tane8d84ab2019-10-11 09:49:40 -0700338 final ActivityRecord activity1 = createIsolatedTestActivityRecord();
339 final ActivityRecord activity2 = createIsolatedTestActivityRecord();
340 activity1.addStartingWindow(mPackageName,
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800341 android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false, true,
342 false, false);
343 waitUntilHandlersIdle();
Garfield Tane8d84ab2019-10-11 09:49:40 -0700344 activity2.addStartingWindow(mPackageName,
345 android.R.style.Theme, null, "Test", 0, 0, 0, 0, activity1.appToken.asBinder(),
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800346 true, true, false, true, false, false);
347 waitUntilHandlersIdle();
Garfield Tane8d84ab2019-10-11 09:49:40 -0700348 assertNoStartingWindow(activity1);
349 assertHasStartingWindow(activity2);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800350 }
351
352 @Test
353 public void testTransferStartingWindowWhileCreating() {
Garfield Tane8d84ab2019-10-11 09:49:40 -0700354 final ActivityRecord activity1 = createIsolatedTestActivityRecord();
355 final ActivityRecord activity2 = createIsolatedTestActivityRecord();
356 ((TestWindowManagerPolicy) activity1.mWmService.mPolicy).setRunnableWhenAddingSplashScreen(
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800357 () -> {
358 // Surprise, ...! Transfer window in the middle of the creation flow.
Garfield Tane8d84ab2019-10-11 09:49:40 -0700359 activity2.addStartingWindow(mPackageName,
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800360 android.R.style.Theme, null, "Test", 0, 0, 0, 0,
Garfield Tane8d84ab2019-10-11 09:49:40 -0700361 activity1.appToken.asBinder(), true, true, false,
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800362 true, false, false);
363 });
Garfield Tane8d84ab2019-10-11 09:49:40 -0700364 activity1.addStartingWindow(mPackageName,
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800365 android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false, true,
366 false, false);
367 waitUntilHandlersIdle();
Garfield Tane8d84ab2019-10-11 09:49:40 -0700368 assertNoStartingWindow(activity1);
369 assertHasStartingWindow(activity2);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800370 }
371
wilsonshihca274ed2020-05-05 17:32:21 +0800372 @Test
373 public void testTransferStartingWindowCanAnimate() {
374 final ActivityRecord activity1 = createIsolatedTestActivityRecord();
375 final ActivityRecord activity2 = createIsolatedTestActivityRecord();
376 activity1.addStartingWindow(mPackageName,
377 android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false, true,
378 false, false);
379 waitUntilHandlersIdle();
380 activity2.addStartingWindow(mPackageName,
381 android.R.style.Theme, null, "Test", 0, 0, 0, 0, activity1.appToken.asBinder(),
382 true, true, false, true, false, false);
383 waitUntilHandlersIdle();
384 assertNoStartingWindow(activity1);
385 assertHasStartingWindow(activity2);
386
387 // Assert that bottom activity is allowed to do animation.
388 doReturn(true).when(activity2).okToAnimate();
389 doReturn(true).when(activity2).isAnimating();
390 final OnAnimationFinishedCallback onAnimationFinishedCallback =
391 mock(OnAnimationFinishedCallback.class);
392 assertTrue(activity2.applyAnimation(null, TRANSIT_ACTIVITY_OPEN, true, false,
393 onAnimationFinishedCallback));
394 }
395
Garfield Tane8d84ab2019-10-11 09:49:40 -0700396 private ActivityRecord createIsolatedTestActivityRecord() {
Wale Ogunwalebebd8cd2019-10-28 15:53:31 -0700397 final ActivityStack taskStack = createTaskStackOnDisplay(mDisplayContent);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800398 final Task task = createTaskInStack(taskStack, 0 /* userId */);
Garfield Tane8d84ab2019-10-11 09:49:40 -0700399 return createTestActivityRecordForGivenTask(task);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800400 }
401
Garfield Tane8d84ab2019-10-11 09:49:40 -0700402 private ActivityRecord createTestActivityRecordForGivenTask(Task task) {
403 final ActivityRecord activity =
404 WindowTestUtils.createTestActivityRecord(mDisplayContent);
405 task.addChild(activity, 0);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800406 waitUntilHandlersIdle();
Garfield Tane8d84ab2019-10-11 09:49:40 -0700407 return activity;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800408 }
409
410 @Test
411 public void testTryTransferStartingWindowFromHiddenAboveToken() {
412 // Add two tasks on top of each other.
Garfield Tane8d84ab2019-10-11 09:49:40 -0700413 final ActivityRecord activityTop = createIsolatedTestActivityRecord();
414 final ActivityRecord activityBottom =
415 createTestActivityRecordForGivenTask(activityTop.getTask());
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800416
417 // Add a starting window.
Garfield Tane8d84ab2019-10-11 09:49:40 -0700418 activityTop.addStartingWindow(mPackageName,
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800419 android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false, true,
420 false, false);
421 waitUntilHandlersIdle();
422
423 // Make the top one invisible, and try transferring the starting window from the top to the
424 // bottom one.
Garfield Tane8d84ab2019-10-11 09:49:40 -0700425 activityTop.setVisibility(false, false);
426 activityBottom.transferStartingWindowFromHiddenAboveTokenIfNeeded();
Yunfan Chendcb1fcf2019-02-07 19:08:41 +0900427 waitUntilHandlersIdle();
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800428
429 // Assert that the bottom window now has the starting window.
Garfield Tane8d84ab2019-10-11 09:49:40 -0700430 assertNoStartingWindow(activityTop);
431 assertHasStartingWindow(activityBottom);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800432 }
433
Evan Rosky641daea2019-04-24 14:45:24 -0700434 @Test
435 public void testTransitionAnimationBounds() {
Wale Ogunwale2322bed2019-10-10 17:24:19 +0200436 removeGlobalMinSizeRestriction();
Evan Rosky641daea2019-04-24 14:45:24 -0700437 final Rect stackBounds = new Rect(0, 0, 1000, 600);
438 final Rect taskBounds = new Rect(100, 400, 600, 800);
439 mStack.setBounds(stackBounds);
440 mTask.setBounds(taskBounds);
441
442 // Check that anim bounds for freeform window match task bounds
443 mTask.setWindowingMode(WINDOWING_MODE_FREEFORM);
Wale Ogunwale2322bed2019-10-10 17:24:19 +0200444 assertEquals(mTask.getBounds(), mActivity.getAnimationBounds(STACK_CLIP_NONE));
Evan Rosky641daea2019-04-24 14:45:24 -0700445
446 // STACK_CLIP_AFTER_ANIM should use task bounds since they will be clipped by
447 // bounds animation layer.
448 mTask.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
Wale Ogunwale2322bed2019-10-10 17:24:19 +0200449 assertEquals(mTask.getBounds(), mActivity.getAnimationBounds(STACK_CLIP_AFTER_ANIM));
Evan Rosky641daea2019-04-24 14:45:24 -0700450
451 // STACK_CLIP_BEFORE_ANIM should use stack bounds since it won't be clipped later.
452 mTask.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
Wale Ogunwale2322bed2019-10-10 17:24:19 +0200453 assertEquals(mStack.getBounds(), mActivity.getAnimationBounds(STACK_CLIP_BEFORE_ANIM));
Evan Rosky641daea2019-04-24 14:45:24 -0700454 }
455
Tarandeep Singh69ab1042019-07-30 13:30:03 -0700456 @Test
457 public void testHasStartingWindow() {
458 final WindowManager.LayoutParams attrs =
459 new WindowManager.LayoutParams(TYPE_APPLICATION_STARTING);
Garfield Tane8d84ab2019-10-11 09:49:40 -0700460 final WindowTestUtils.TestWindowState startingWindow = createWindowState(attrs, mActivity);
461 mActivity.startingDisplayed = true;
462 mActivity.addWindow(startingWindow);
463 assertTrue("Starting window should be present", mActivity.hasStartingWindow());
464 mActivity.startingDisplayed = false;
465 assertTrue("Starting window should be present", mActivity.hasStartingWindow());
Tarandeep Singh69ab1042019-07-30 13:30:03 -0700466
Garfield Tane8d84ab2019-10-11 09:49:40 -0700467 mActivity.removeChild(startingWindow);
468 assertFalse("Starting window should not be present", mActivity.hasStartingWindow());
Tarandeep Singh69ab1042019-07-30 13:30:03 -0700469 }
470
Garfield Tane8d84ab2019-10-11 09:49:40 -0700471 private void assertHasStartingWindow(ActivityRecord atoken) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800472 assertNotNull(atoken.startingSurface);
chaviwa8f07a72019-05-01 16:25:39 -0700473 assertNotNull(atoken.mStartingData);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800474 assertNotNull(atoken.startingWindow);
475 }
476
Garfield Tane8d84ab2019-10-11 09:49:40 -0700477 private void assertNoStartingWindow(ActivityRecord atoken) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800478 assertNull(atoken.startingSurface);
479 assertNull(atoken.startingWindow);
chaviwa8f07a72019-05-01 16:25:39 -0700480 assertNull(atoken.mStartingData);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800481 atoken.forAllWindows(windowState -> {
482 assertFalse(windowState.getBaseType() == TYPE_APPLICATION_STARTING);
483 }, true);
484 }
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700485}