blob: 9d5f687b83a797bf796b466cccb2d70fd47b1ea3 [file] [log] [blame]
Bryce Lee840c5662017-04-13 10:02:51 -07001/*
Wale Ogunwale59507092018-10-29 09:00:30 -07002 * Copyright (C) 2018 The Android Open Source Project
Bryce Lee840c5662017-04-13 10:02:51 -07003 *
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
Wale Ogunwale59507092018-10-29 09:00:30 -070014 * limitations under the License
Bryce Lee840c5662017-04-13 10:02:51 -070015 */
16
Wale Ogunwale59507092018-10-29 09:00:30 -070017package com.android.server.wm;
Bryce Lee840c5662017-04-13 10:02:51 -070018
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -070019import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
20import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070021import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
Kazuki Takisef85197b2018-06-18 18:18:36 +090022import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070023import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -070024import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
25import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
26import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
Evan Rosky10475742018-09-05 19:02:48 -070027import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
Bryce Lee18d51592017-10-25 10:22:19 -070028
Tadashi G. Takaokaa7a66952018-11-16 15:04:21 +090029import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
30import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
31import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy;
32import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
Wale Ogunwale59507092018-10-29 09:00:30 -070033import static com.android.server.wm.ActivityStack.ActivityState.DESTROYING;
34import static com.android.server.wm.ActivityStack.ActivityState.PAUSED;
35import static com.android.server.wm.ActivityStack.ActivityState.PAUSING;
36import static com.android.server.wm.ActivityStack.ActivityState.RESUMED;
37import static com.android.server.wm.ActivityStack.ActivityState.STOPPING;
38import static com.android.server.wm.ActivityStack.REMOVE_TASK_MODE_DESTROYING;
Garfield Tanf6cc5c92019-01-15 13:54:12 -080039import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_FREE_RESIZE;
40import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_WINDOWING_MODE_RESIZE;
Bryce Lee18d51592017-10-25 10:22:19 -070041
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +090042import static com.google.common.truth.Truth.assertThat;
43
Bryce Lee5daa3122017-04-19 10:40:42 -070044import static org.junit.Assert.assertEquals;
David Stevens18abd0e2017-08-17 14:55:47 -070045import static org.junit.Assert.assertFalse;
Bryce Lee840c5662017-04-13 10:02:51 -070046import static org.junit.Assert.assertNotNull;
47import static org.junit.Assert.assertNull;
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -070048import static org.junit.Assert.assertTrue;
Riddle Hsu138ef932018-10-26 17:12:06 +080049import static org.mockito.ArgumentMatchers.any;
Riddle Hsue10cea52018-10-16 23:33:23 +080050import static org.mockito.ArgumentMatchers.anyBoolean;
51import static org.mockito.ArgumentMatchers.anyInt;
Riddle Hsue10cea52018-10-16 23:33:23 +080052import static org.mockito.ArgumentMatchers.eq;
Bryce Lee840c5662017-04-13 10:02:51 -070053
Bryce Lee3345c4e2017-04-25 07:40:41 -070054import android.content.pm.ActivityInfo;
Bryce Lee9f6affd2017-09-01 09:18:35 -070055import android.os.UserHandle;
Bryce Lee840c5662017-04-13 10:02:51 -070056import android.platform.test.annotations.Presubmit;
Bryce Lee840c5662017-04-13 10:02:51 -070057
Brett Chabota26eda92018-07-23 13:08:30 -070058import androidx.test.filters.SmallTest;
Brett Chabota26eda92018-07-23 13:08:30 -070059
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070060import org.junit.Before;
Bryce Lee840c5662017-04-13 10:02:51 -070061import org.junit.Test;
62
63/**
64 * Tests for the {@link ActivityStack} class.
65 *
66 * Build/Install/Run:
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +090067 * atest WmTests:ActivityStackTests
Bryce Lee840c5662017-04-13 10:02:51 -070068 */
69@SmallTest
70@Presubmit
Bryce Lee840c5662017-04-13 10:02:51 -070071public class ActivityStackTests extends ActivityTestsBase {
Winson Chung3e2980e2018-03-29 17:28:57 -070072 private ActivityDisplay mDefaultDisplay;
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070073 private ActivityStack mStack;
74 private TaskRecord mTask;
75
76 @Before
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070077 public void setUp() throws Exception {
Riddle Hsub70b36d2018-09-11 21:20:02 +080078 setupActivityTaskManagerService();
Wale Ogunwaled32da472018-11-16 07:19:28 -080079 mDefaultDisplay = mRootActivityContainer.getDefaultDisplay();
Tiger Huang1e5b10a2018-07-30 20:19:51 +080080 mStack = spy(mDefaultDisplay.createStack(WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD,
81 true /* onTop */));
Bryce Lee18d51592017-10-25 10:22:19 -070082 mTask = new TaskBuilder(mSupervisor).setStack(mStack).build();
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070083 }
84
Bryce Lee840c5662017-04-13 10:02:51 -070085 @Test
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +090086 public void testEmptyTaskCleanupOnRemove() {
Yunfan Chen0e7aff92018-12-05 16:35:32 -080087 assertNotNull(mTask.getTask());
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070088 mStack.removeTask(mTask, "testEmptyTaskCleanupOnRemove", REMOVE_TASK_MODE_DESTROYING);
Yunfan Chen0e7aff92018-12-05 16:35:32 -080089 assertNull(mTask.getTask());
Bryce Lee840c5662017-04-13 10:02:51 -070090 }
Bryce Lee5daa3122017-04-19 10:40:42 -070091
Bryce Lee840c5662017-04-13 10:02:51 -070092 @Test
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +090093 public void testOccupiedTaskCleanupOnRemove() {
Bryce Lee18d51592017-10-25 10:22:19 -070094 final ActivityRecord r = new ActivityBuilder(mService).setTask(mTask).build();
Yunfan Chen0e7aff92018-12-05 16:35:32 -080095 assertNotNull(mTask.getTask());
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070096 mStack.removeTask(mTask, "testOccupiedTaskCleanupOnRemove", REMOVE_TASK_MODE_DESTROYING);
Yunfan Chen0e7aff92018-12-05 16:35:32 -080097 assertNotNull(mTask.getTask());
Bryce Lee840c5662017-04-13 10:02:51 -070098 }
Bryce Lee5daa3122017-04-19 10:40:42 -070099
100 @Test
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900101 public void testResumedActivity() {
Bryce Leec4ab62a2018-03-05 14:19:26 -0800102 final ActivityRecord r = new ActivityBuilder(mService).setTask(mTask).build();
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900103 assertNull(mStack.getResumedActivity());
Bryce Leec4ab62a2018-03-05 14:19:26 -0800104 r.setState(RESUMED, "testResumedActivity");
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900105 assertEquals(r, mStack.getResumedActivity());
Bryce Leec4ab62a2018-03-05 14:19:26 -0800106 r.setState(PAUSING, "testResumedActivity");
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900107 assertNull(mStack.getResumedActivity());
Bryce Lee84730a02018-04-03 14:10:04 -0700108 }
Bryce Leec4ab62a2018-03-05 14:19:26 -0800109
Bryce Lee84730a02018-04-03 14:10:04 -0700110 @Test
111 public void testResumedActivityFromTaskReparenting() {
112 final ActivityRecord r = new ActivityBuilder(mService).setTask(mTask).build();
113 // Ensure moving task between two stacks updates resumed activity
114 r.setState(RESUMED, "testResumedActivityFromTaskReparenting");
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900115 assertEquals(r, mStack.getResumedActivity());
Bryce Lee84730a02018-04-03 14:10:04 -0700116
Wale Ogunwaled32da472018-11-16 07:19:28 -0800117 final ActivityStack destStack = mRootActivityContainer.getDefaultDisplay().createStack(
Bryce Lee84730a02018-04-03 14:10:04 -0700118 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
119
120 mTask.reparent(destStack, true /* toTop */, TaskRecord.REPARENT_KEEP_STACK_AT_FRONT,
121 false /* animate */, true /* deferResume*/,
122 "testResumedActivityFromTaskReparenting");
123
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900124 assertNull(mStack.getResumedActivity());
125 assertEquals(r, destStack.getResumedActivity());
Bryce Lee84730a02018-04-03 14:10:04 -0700126 }
127
128 @Test
129 public void testResumedActivityFromActivityReparenting() {
130 final ActivityRecord r = new ActivityBuilder(mService).setTask(mTask).build();
131 // Ensure moving task between two stacks updates resumed activity
132 r.setState(RESUMED, "testResumedActivityFromActivityReparenting");
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900133 assertEquals(r, mStack.getResumedActivity());
Bryce Lee84730a02018-04-03 14:10:04 -0700134
Wale Ogunwaled32da472018-11-16 07:19:28 -0800135 final ActivityStack destStack = mRootActivityContainer.getDefaultDisplay().createStack(
Bryce Lee84730a02018-04-03 14:10:04 -0700136 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
137 final TaskRecord destTask = new TaskBuilder(mSupervisor).setStack(destStack).build();
138
139 mTask.removeActivity(r);
140 destTask.addActivityToTop(r);
141
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900142 assertNull(mStack.getResumedActivity());
143 assertEquals(r, destStack.getResumedActivity());
Bryce Lee5daa3122017-04-19 10:40:42 -0700144 }
Bryce Lee3345c4e2017-04-25 07:40:41 -0700145
146 @Test
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900147 public void testPrimarySplitScreenRestoresWhenMovedToBack() {
Bryce Lee8cab4a02018-01-05 09:00:49 -0800148 // Create primary splitscreen stack. This will create secondary stacks and places the
149 // existing fullscreen stack on the bottom.
Winson Chung3e2980e2018-03-29 17:28:57 -0700150 final ActivityStack primarySplitScreen = mDefaultDisplay.createStack(
151 WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD, true /* onTop */);
Bryce Lee8cab4a02018-01-05 09:00:49 -0800152
153 // Assert windowing mode.
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900154 assertEquals(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, primarySplitScreen.getWindowingMode());
Bryce Lee8cab4a02018-01-05 09:00:49 -0800155
156 // Move primary to back.
157 primarySplitScreen.moveToBack("testPrimarySplitScreenToFullscreenWhenMovedToBack",
158 null /* task */);
159
160 // Assert that stack is at the bottom.
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900161 assertEquals(0, mDefaultDisplay.getIndexOf(primarySplitScreen));
Bryce Lee8cab4a02018-01-05 09:00:49 -0800162
163 // Ensure no longer in splitscreen.
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900164 assertEquals(WINDOWING_MODE_FULLSCREEN, primarySplitScreen.getWindowingMode());
Evan Rosky10475742018-09-05 19:02:48 -0700165
166 // Ensure that the override mode is restored to undefined
Evan Roskydfe3da72018-10-26 17:21:06 -0700167 assertEquals(WINDOWING_MODE_UNDEFINED,
168 primarySplitScreen.getRequestedOverrideWindowingMode());
Evan Rosky10475742018-09-05 19:02:48 -0700169 }
170
171 @Test
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900172 public void testPrimarySplitScreenRestoresPreviousWhenMovedToBack() {
Evan Rosky10475742018-09-05 19:02:48 -0700173 // This time, start with a fullscreen activitystack
174 final ActivityStack primarySplitScreen = mDefaultDisplay.createStack(
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900175 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
Evan Rosky10475742018-09-05 19:02:48 -0700176
177 primarySplitScreen.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
178
179 // Assert windowing mode.
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900180 assertEquals(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, primarySplitScreen.getWindowingMode());
Evan Rosky10475742018-09-05 19:02:48 -0700181
182 // Move primary to back.
183 primarySplitScreen.moveToBack("testPrimarySplitScreenToFullscreenWhenMovedToBack",
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900184 null /* task */);
Evan Rosky10475742018-09-05 19:02:48 -0700185
186 // Assert that stack is at the bottom.
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900187 assertEquals(0, mDefaultDisplay.getIndexOf(primarySplitScreen));
Evan Rosky10475742018-09-05 19:02:48 -0700188
189 // Ensure that the override mode is restored to what it was (fullscreen)
Evan Roskydfe3da72018-10-26 17:21:06 -0700190 assertEquals(WINDOWING_MODE_FULLSCREEN,
191 primarySplitScreen.getRequestedOverrideWindowingMode());
Evan Rosky10475742018-09-05 19:02:48 -0700192 }
193
194 @Test
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900195 public void testStackInheritsDisplayWindowingMode() {
Evan Rosky10475742018-09-05 19:02:48 -0700196 final ActivityStack primarySplitScreen = mDefaultDisplay.createStack(
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900197 WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD, true /* onTop */);
Evan Rosky10475742018-09-05 19:02:48 -0700198
199 assertEquals(WINDOWING_MODE_FULLSCREEN, primarySplitScreen.getWindowingMode());
Evan Roskydfe3da72018-10-26 17:21:06 -0700200 assertEquals(WINDOWING_MODE_UNDEFINED,
201 primarySplitScreen.getRequestedOverrideWindowingMode());
Evan Rosky10475742018-09-05 19:02:48 -0700202
203 mDefaultDisplay.setWindowingMode(WINDOWING_MODE_FREEFORM);
204 assertEquals(WINDOWING_MODE_FREEFORM, primarySplitScreen.getWindowingMode());
Evan Roskydfe3da72018-10-26 17:21:06 -0700205 assertEquals(WINDOWING_MODE_UNDEFINED,
206 primarySplitScreen.getRequestedOverrideWindowingMode());
Evan Rosky10475742018-09-05 19:02:48 -0700207 }
208
209 @Test
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900210 public void testStackOverridesDisplayWindowingMode() {
Evan Rosky10475742018-09-05 19:02:48 -0700211 final ActivityStack primarySplitScreen = mDefaultDisplay.createStack(
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900212 WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD, true /* onTop */);
Evan Rosky10475742018-09-05 19:02:48 -0700213
214 assertEquals(WINDOWING_MODE_FULLSCREEN, primarySplitScreen.getWindowingMode());
Evan Roskydfe3da72018-10-26 17:21:06 -0700215 assertEquals(WINDOWING_MODE_UNDEFINED,
216 primarySplitScreen.getRequestedOverrideWindowingMode());
Evan Rosky10475742018-09-05 19:02:48 -0700217
218 primarySplitScreen.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
219 // setting windowing mode should still work even though resolved mode is already fullscreen
Evan Roskydfe3da72018-10-26 17:21:06 -0700220 assertEquals(WINDOWING_MODE_FULLSCREEN,
221 primarySplitScreen.getRequestedOverrideWindowingMode());
Evan Rosky10475742018-09-05 19:02:48 -0700222
223 mDefaultDisplay.setWindowingMode(WINDOWING_MODE_FREEFORM);
224 assertEquals(WINDOWING_MODE_FULLSCREEN, primarySplitScreen.getWindowingMode());
Bryce Lee8cab4a02018-01-05 09:00:49 -0800225 }
226
227 @Test
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900228 public void testStopActivityWhenActivityDestroyed() {
Bryce Lee18d51592017-10-25 10:22:19 -0700229 final ActivityRecord r = new ActivityBuilder(mService).setTask(mTask).build();
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700230 r.info.flags |= ActivityInfo.FLAG_NO_HISTORY;
Andrii Kulian6a6c4f12018-07-16 21:23:33 -0700231 mStack.moveToFront("testStopActivityWithDestroy");
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700232 mStack.stopActivityLocked(r);
233 // Mostly testing to make sure there is a crash in the call part, so if we get here we are
234 // good-to-go!
Bryce Lee3345c4e2017-04-25 07:40:41 -0700235 }
Bryce Lee9f6affd2017-09-01 09:18:35 -0700236
237 @Test
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900238 public void testFindTaskWithOverlay() {
Bryce Lee18d51592017-10-25 10:22:19 -0700239 final ActivityRecord r = new ActivityBuilder(mService)
240 .setCreateTask(true)
241 .setStack(mStack)
242 .setUid(0)
243 .build();
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800244 final TaskRecord task = r.getTaskRecord();
Bryce Lee9f6affd2017-09-01 09:18:35 -0700245 // Overlay must be for a different user to prevent recognizing a matching top activity
Bryce Lee18d51592017-10-25 10:22:19 -0700246 final ActivityRecord taskOverlay = new ActivityBuilder(mService).setTask(task)
247 .setUid(UserHandle.PER_USER_RANGE * 2).build();
Bryce Lee9f6affd2017-09-01 09:18:35 -0700248 taskOverlay.mTaskOverlay = true;
249
Wale Ogunwaled32da472018-11-16 07:19:28 -0800250 final RootActivityContainer.FindTaskResult result =
251 new RootActivityContainer.FindTaskResult();
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700252 mStack.findTaskLocked(r, result);
Bryce Lee9f6affd2017-09-01 09:18:35 -0700253
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900254 assertEquals(r, task.getTopActivity(false /* includeOverlays */));
255 assertEquals(taskOverlay, task.getTopActivity(true /* includeOverlays */));
Louis Changc85b1a32018-08-14 16:40:53 +0800256 assertNotNull(result.mRecord);
Bryce Lee9f6affd2017-09-01 09:18:35 -0700257 }
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700258
259 @Test
Riddle Hsu138ef932018-10-26 17:12:06 +0800260 public void testMoveStackToBackIncludingParent() {
261 final ActivityDisplay display = addNewActivityDisplayAt(ActivityDisplay.POSITION_TOP);
262 final ActivityStack stack1 = createStackForShouldBeVisibleTest(display,
263 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
264 final ActivityStack stack2 = createStackForShouldBeVisibleTest(display,
265 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
266
267 // Do not move display to back because there is still another stack.
268 stack2.moveToBack("testMoveStackToBackIncludingParent", stack2.topTask());
269 verify(stack2.getWindowContainerController()).positionChildAtBottom(any(),
270 eq(false) /* includingParents */);
271
272 // Also move display to back because there is only one stack left.
273 display.removeChild(stack1);
274 stack2.moveToBack("testMoveStackToBackIncludingParent", stack2.topTask());
275 verify(stack2.getWindowContainerController()).positionChildAtBottom(any(),
276 eq(true) /* includingParents */);
277 }
278
279 @Test
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900280 public void testShouldBeVisible_Fullscreen() {
Winson Chung3e2980e2018-03-29 17:28:57 -0700281 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700282 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
Winson Chung3e2980e2018-03-29 17:28:57 -0700283 final ActivityStack pinnedStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700284 WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, true /* onTop */);
285
286 assertTrue(homeStack.shouldBeVisible(null /* starting */));
287 assertTrue(pinnedStack.shouldBeVisible(null /* starting */));
288
Winson Chung3e2980e2018-03-29 17:28:57 -0700289 final TestActivityStack fullscreenStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700290 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
291 // Home stack shouldn't be visible behind an opaque fullscreen stack, but pinned stack
292 // should be visible since it is always on-top.
293 fullscreenStack.setIsTranslucent(false);
294 assertFalse(homeStack.shouldBeVisible(null /* starting */));
295 assertTrue(pinnedStack.shouldBeVisible(null /* starting */));
296 assertTrue(fullscreenStack.shouldBeVisible(null /* starting */));
297
298 // Home stack should be visible behind a translucent fullscreen stack.
299 fullscreenStack.setIsTranslucent(true);
300 assertTrue(homeStack.shouldBeVisible(null /* starting */));
301 assertTrue(pinnedStack.shouldBeVisible(null /* starting */));
302 }
303
304 @Test
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900305 public void testShouldBeVisible_SplitScreen() {
Winson Chung3e2980e2018-03-29 17:28:57 -0700306 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700307 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
Wale Ogunwale30e441d2017-11-09 08:28:45 -0800308 // Home stack should always be fullscreen for this test.
309 homeStack.setSupportsSplitScreen(false);
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900310 final TestActivityStack splitScreenPrimary =
311 createStackForShouldBeVisibleTest(mDefaultDisplay,
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700312 WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD, true /* onTop */);
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900313 final TestActivityStack splitScreenSecondary =
314 createStackForShouldBeVisibleTest(mDefaultDisplay,
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700315 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD, true /* onTop */);
316
317 // Home stack shouldn't be visible if both halves of split-screen are opaque.
318 splitScreenPrimary.setIsTranslucent(false);
319 splitScreenSecondary.setIsTranslucent(false);
320 assertFalse(homeStack.shouldBeVisible(null /* starting */));
321 assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */));
322 assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
323
324 // Home stack should be visible if one of the halves of split-screen is translucent.
325 splitScreenPrimary.setIsTranslucent(true);
326 assertTrue(homeStack.shouldBeVisible(null /* starting */));
327 assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */));
328 assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
329
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900330 final TestActivityStack splitScreenSecondary2 =
331 createStackForShouldBeVisibleTest(mDefaultDisplay,
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700332 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD, true /* onTop */);
333 // First split-screen secondary shouldn't be visible behind another opaque split-split
334 // secondary.
335 splitScreenSecondary2.setIsTranslucent(false);
336 assertFalse(splitScreenSecondary.shouldBeVisible(null /* starting */));
337 assertTrue(splitScreenSecondary2.shouldBeVisible(null /* starting */));
338
Wale Ogunwale8e923af2018-03-23 08:48:11 -0700339 // First split-screen secondary should be visible behind another translucent split-screen
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700340 // secondary.
341 splitScreenSecondary2.setIsTranslucent(true);
342 assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
343 assertTrue(splitScreenSecondary2.shouldBeVisible(null /* starting */));
344
Winson Chung3e2980e2018-03-29 17:28:57 -0700345 final TestActivityStack assistantStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700346 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_ASSISTANT, true /* onTop */);
347
348 // Split-screen stacks shouldn't be visible behind an opaque fullscreen stack.
349 assistantStack.setIsTranslucent(false);
350 assertTrue(assistantStack.shouldBeVisible(null /* starting */));
351 assertFalse(splitScreenPrimary.shouldBeVisible(null /* starting */));
352 assertFalse(splitScreenSecondary.shouldBeVisible(null /* starting */));
353 assertFalse(splitScreenSecondary2.shouldBeVisible(null /* starting */));
354
355 // Split-screen stacks should be visible behind a translucent fullscreen stack.
356 assistantStack.setIsTranslucent(true);
357 assertTrue(assistantStack.shouldBeVisible(null /* starting */));
358 assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */));
359 assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
360 assertTrue(splitScreenSecondary2.shouldBeVisible(null /* starting */));
Wale Ogunwale8e923af2018-03-23 08:48:11 -0700361
362 // Assistant stack shouldn't be visible behind translucent split-screen stack
363 assistantStack.setIsTranslucent(false);
364 splitScreenPrimary.setIsTranslucent(true);
365 splitScreenSecondary2.setIsTranslucent(true);
366 splitScreenSecondary2.moveToFront("testShouldBeVisible_SplitScreen");
367 splitScreenPrimary.moveToFront("testShouldBeVisible_SplitScreen");
368 assertFalse(assistantStack.shouldBeVisible(null /* starting */));
369 assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */));
370 assertTrue(splitScreenSecondary2.shouldBeVisible(null /* starting */));
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700371 }
372
373 @Test
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900374 public void testShouldBeVisible_Finishing() {
Winson Chung3e2980e2018-03-29 17:28:57 -0700375 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700376 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
Winson Chung3e2980e2018-03-29 17:28:57 -0700377 final TestActivityStack translucentStack = createStackForShouldBeVisibleTest(
378 mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
379 true /* onTop */);
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700380 translucentStack.setIsTranslucent(true);
381
382 assertTrue(homeStack.shouldBeVisible(null /* starting */));
383 assertTrue(translucentStack.shouldBeVisible(null /* starting */));
384
385 final ActivityRecord topRunningHomeActivity = homeStack.topRunningActivityLocked();
386 topRunningHomeActivity.finishing = true;
387 final ActivityRecord topRunningTranslucentActivity =
388 translucentStack.topRunningActivityLocked();
389 topRunningTranslucentActivity.finishing = true;
390
Louis Changf2835df2018-10-17 15:14:45 +0800391 // Home stack should be visible even there are no running activities.
392 assertTrue(homeStack.shouldBeVisible(null /* starting */));
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700393 // Home should be visible if we are starting an activity within it.
394 assertTrue(homeStack.shouldBeVisible(topRunningHomeActivity /* starting */));
Louis Changf2835df2018-10-17 15:14:45 +0800395 // The translucent stack shouldn't be visible since its activity marked as finishing.
396 assertFalse(translucentStack.shouldBeVisible(null /* starting */));
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700397 }
398
Winson Chungd922b6b2018-02-16 16:41:50 -0800399 @Test
400 public void testMoveHomeStackBehindBottomMostVisibleStack_NoMoveHomeBehindFullscreen() {
Winson Chung3e2980e2018-03-29 17:28:57 -0700401 mDefaultDisplay.removeChild(mStack);
Winson Chungd922b6b2018-02-16 16:41:50 -0800402
Winson Chung3e2980e2018-03-29 17:28:57 -0700403 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Winson Chungd922b6b2018-02-16 16:41:50 -0800404 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
Winson Chung3e2980e2018-03-29 17:28:57 -0700405 final TestActivityStack fullscreenStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Winson Chungd922b6b2018-02-16 16:41:50 -0800406 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
407
408 homeStack.setIsTranslucent(false);
409 fullscreenStack.setIsTranslucent(false);
410
411 // Ensure that we don't move the home stack if it is already behind the top fullscreen stack
Winson Chung3e2980e2018-03-29 17:28:57 -0700412 int homeStackIndex = mDefaultDisplay.getIndexOf(homeStack);
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900413 assertEquals(fullscreenStack, mDefaultDisplay.getStackAbove(homeStack));
Winson Chung3e2980e2018-03-29 17:28:57 -0700414 mDefaultDisplay.moveStackBehindBottomMostVisibleStack(homeStack);
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900415 assertEquals(homeStackIndex, mDefaultDisplay.getIndexOf(homeStack));
Winson Chungd922b6b2018-02-16 16:41:50 -0800416 }
417
418 @Test
419 public void testMoveHomeStackBehindBottomMostVisibleStack_NoMoveHomeBehindTranslucent() {
Winson Chung3e2980e2018-03-29 17:28:57 -0700420 mDefaultDisplay.removeChild(mStack);
Winson Chungd922b6b2018-02-16 16:41:50 -0800421
Winson Chung3e2980e2018-03-29 17:28:57 -0700422 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Winson Chungd922b6b2018-02-16 16:41:50 -0800423 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
Winson Chung3e2980e2018-03-29 17:28:57 -0700424 final TestActivityStack fullscreenStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Winson Chungd922b6b2018-02-16 16:41:50 -0800425 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
426
427 homeStack.setIsTranslucent(false);
428 fullscreenStack.setIsTranslucent(true);
429
430 // Ensure that we don't move the home stack if it is already behind the top fullscreen stack
Winson Chung3e2980e2018-03-29 17:28:57 -0700431 int homeStackIndex = mDefaultDisplay.getIndexOf(homeStack);
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900432 assertEquals(fullscreenStack, mDefaultDisplay.getStackAbove(homeStack));
Winson Chung3e2980e2018-03-29 17:28:57 -0700433 mDefaultDisplay.moveStackBehindBottomMostVisibleStack(homeStack);
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900434 assertEquals(homeStackIndex, mDefaultDisplay.getIndexOf(homeStack));
Winson Chungd922b6b2018-02-16 16:41:50 -0800435 }
436
437 @Test
438 public void testMoveHomeStackBehindBottomMostVisibleStack_NoMoveHomeOnTop() {
Winson Chung3e2980e2018-03-29 17:28:57 -0700439 mDefaultDisplay.removeChild(mStack);
Winson Chungd922b6b2018-02-16 16:41:50 -0800440
Winson Chung3e2980e2018-03-29 17:28:57 -0700441 final TestActivityStack fullscreenStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Winson Chungd922b6b2018-02-16 16:41:50 -0800442 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
Winson Chung3e2980e2018-03-29 17:28:57 -0700443 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Winson Chungd922b6b2018-02-16 16:41:50 -0800444 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
445
446 homeStack.setIsTranslucent(false);
447 fullscreenStack.setIsTranslucent(false);
448
449 // Ensure we don't move the home stack if it is already on top
Winson Chung3e2980e2018-03-29 17:28:57 -0700450 int homeStackIndex = mDefaultDisplay.getIndexOf(homeStack);
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900451 assertNull(mDefaultDisplay.getStackAbove(homeStack));
Winson Chung3e2980e2018-03-29 17:28:57 -0700452 mDefaultDisplay.moveStackBehindBottomMostVisibleStack(homeStack);
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900453 assertEquals(homeStackIndex, mDefaultDisplay.getIndexOf(homeStack));
Winson Chungd922b6b2018-02-16 16:41:50 -0800454 }
455
456 @Test
457 public void testMoveHomeStackBehindBottomMostVisibleStack_MoveHomeBehindFullscreen() {
Winson Chung3e2980e2018-03-29 17:28:57 -0700458 mDefaultDisplay.removeChild(mStack);
Winson Chungd922b6b2018-02-16 16:41:50 -0800459
Winson Chung3e2980e2018-03-29 17:28:57 -0700460 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Winson Chungd922b6b2018-02-16 16:41:50 -0800461 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
Winson Chung3e2980e2018-03-29 17:28:57 -0700462 final TestActivityStack fullscreenStack1 = createStackForShouldBeVisibleTest(
463 mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
464 true /* onTop */);
465 final TestActivityStack fullscreenStack2 = createStackForShouldBeVisibleTest(
466 mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
467 true /* onTop */);
Wale Ogunwale24116192018-11-07 07:46:56 -0800468 final ActivityStack pinnedStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Winson Chungd922b6b2018-02-16 16:41:50 -0800469 WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, true /* onTop */);
470
471 homeStack.setIsTranslucent(false);
472 fullscreenStack1.setIsTranslucent(false);
473 fullscreenStack2.setIsTranslucent(false);
474
475 // Ensure that we move the home stack behind the bottom most fullscreen stack, ignoring the
476 // pinned stack
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900477 assertEquals(fullscreenStack1, mDefaultDisplay.getStackAbove(homeStack));
Winson Chung3e2980e2018-03-29 17:28:57 -0700478 mDefaultDisplay.moveStackBehindBottomMostVisibleStack(homeStack);
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900479 assertEquals(fullscreenStack2, mDefaultDisplay.getStackAbove(homeStack));
Winson Chungd922b6b2018-02-16 16:41:50 -0800480 }
481
482 @Test
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900483 public void
484 testMoveHomeStackBehindBottomMostVisibleStack_MoveHomeBehindFullscreenAndTranslucent() {
Winson Chung3e2980e2018-03-29 17:28:57 -0700485 mDefaultDisplay.removeChild(mStack);
Winson Chungd922b6b2018-02-16 16:41:50 -0800486
Winson Chung3e2980e2018-03-29 17:28:57 -0700487 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Winson Chungd922b6b2018-02-16 16:41:50 -0800488 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
Winson Chung3e2980e2018-03-29 17:28:57 -0700489 final TestActivityStack fullscreenStack1 = createStackForShouldBeVisibleTest(
490 mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
491 true /* onTop */);
492 final TestActivityStack fullscreenStack2 = createStackForShouldBeVisibleTest(
493 mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
494 true /* onTop */);
Winson Chungd922b6b2018-02-16 16:41:50 -0800495
496 homeStack.setIsTranslucent(false);
497 fullscreenStack1.setIsTranslucent(false);
498 fullscreenStack2.setIsTranslucent(true);
499
500 // Ensure that we move the home stack behind the bottom most non-translucent fullscreen
501 // stack
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900502 assertEquals(fullscreenStack1, mDefaultDisplay.getStackAbove(homeStack));
Winson Chung3e2980e2018-03-29 17:28:57 -0700503 mDefaultDisplay.moveStackBehindBottomMostVisibleStack(homeStack);
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900504 assertEquals(fullscreenStack1, mDefaultDisplay.getStackAbove(homeStack));
Winson Chungd922b6b2018-02-16 16:41:50 -0800505 }
506
507 @Test
508 public void testMoveHomeStackBehindStack_BehindHomeStack() {
Winson Chung3e2980e2018-03-29 17:28:57 -0700509 mDefaultDisplay.removeChild(mStack);
Winson Chungd922b6b2018-02-16 16:41:50 -0800510
Winson Chung3e2980e2018-03-29 17:28:57 -0700511 final TestActivityStack fullscreenStack1 = createStackForShouldBeVisibleTest(
512 mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
513 true /* onTop */);
514 final TestActivityStack fullscreenStack2 = createStackForShouldBeVisibleTest(
515 mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
516 true /* onTop */);
517 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Winson Chungd922b6b2018-02-16 16:41:50 -0800518 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
519
520 homeStack.setIsTranslucent(false);
521 fullscreenStack1.setIsTranslucent(false);
522 fullscreenStack2.setIsTranslucent(false);
523
524 // Ensure we don't move the home stack behind itself
Winson Chung3e2980e2018-03-29 17:28:57 -0700525 int homeStackIndex = mDefaultDisplay.getIndexOf(homeStack);
526 mDefaultDisplay.moveStackBehindStack(homeStack, homeStack);
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900527 assertEquals(homeStackIndex, mDefaultDisplay.getIndexOf(homeStack));
Winson Chungd922b6b2018-02-16 16:41:50 -0800528 }
529
530 @Test
531 public void testMoveHomeStackBehindStack() {
Winson Chung3e2980e2018-03-29 17:28:57 -0700532 mDefaultDisplay.removeChild(mStack);
Winson Chungd922b6b2018-02-16 16:41:50 -0800533
Winson Chung3e2980e2018-03-29 17:28:57 -0700534 final TestActivityStack fullscreenStack1 = createStackForShouldBeVisibleTest(
535 mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
536 true /* onTop */);
537 final TestActivityStack fullscreenStack2 = createStackForShouldBeVisibleTest(
538 mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
539 true /* onTop */);
540 final TestActivityStack fullscreenStack3 = createStackForShouldBeVisibleTest(
541 mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
542 true /* onTop */);
543 final TestActivityStack fullscreenStack4 = createStackForShouldBeVisibleTest(
544 mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
545 true /* onTop */);
546 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Winson Chungd922b6b2018-02-16 16:41:50 -0800547 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
548
Winson Chung3e2980e2018-03-29 17:28:57 -0700549 mDefaultDisplay.moveStackBehindStack(homeStack, fullscreenStack1);
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900550 assertEquals(fullscreenStack1, mDefaultDisplay.getStackAbove(homeStack));
Winson Chung3e2980e2018-03-29 17:28:57 -0700551 mDefaultDisplay.moveStackBehindStack(homeStack, fullscreenStack2);
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900552 assertEquals(fullscreenStack2, mDefaultDisplay.getStackAbove(homeStack));
Winson Chung3e2980e2018-03-29 17:28:57 -0700553 mDefaultDisplay.moveStackBehindStack(homeStack, fullscreenStack4);
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900554 assertEquals(fullscreenStack4, mDefaultDisplay.getStackAbove(homeStack));
Winson Chung3e2980e2018-03-29 17:28:57 -0700555 mDefaultDisplay.moveStackBehindStack(homeStack, fullscreenStack2);
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900556 assertEquals(fullscreenStack2, mDefaultDisplay.getStackAbove(homeStack));
Winson Chungd922b6b2018-02-16 16:41:50 -0800557 }
558
Wale Ogunwalebb285872018-03-01 13:05:30 -0800559 @Test
Kazuki Takisef85197b2018-06-18 18:18:36 +0900560 public void testSetAlwaysOnTop() {
561 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
562 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
563 final ActivityStack pinnedStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
564 WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, true /* onTop */);
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900565 assertEquals(pinnedStack, mDefaultDisplay.getStackAbove(homeStack));
Kazuki Takisef85197b2018-06-18 18:18:36 +0900566
567 final TestActivityStack alwaysOnTopStack = createStackForShouldBeVisibleTest(
568 mDefaultDisplay, WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD,
569 true /* onTop */);
570 alwaysOnTopStack.setAlwaysOnTop(true);
571 assertTrue(alwaysOnTopStack.isAlwaysOnTop());
572 // Ensure (non-pinned) always on top stack is put below pinned stack.
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900573 assertEquals(pinnedStack, mDefaultDisplay.getStackAbove(alwaysOnTopStack));
Kazuki Takisef85197b2018-06-18 18:18:36 +0900574
575 final TestActivityStack nonAlwaysOnTopStack = createStackForShouldBeVisibleTest(
576 mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
577 true /* onTop */);
578 // Ensure non always on top stack is put below always on top stacks.
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900579 assertEquals(alwaysOnTopStack, mDefaultDisplay.getStackAbove(nonAlwaysOnTopStack));
Kazuki Takisef85197b2018-06-18 18:18:36 +0900580
581 final TestActivityStack alwaysOnTopStack2 = createStackForShouldBeVisibleTest(
582 mDefaultDisplay, WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD,
583 true /* onTop */);
584 alwaysOnTopStack2.setAlwaysOnTop(true);
585 assertTrue(alwaysOnTopStack2.isAlwaysOnTop());
586 // Ensure newly created always on top stack is placed above other all always on top stacks.
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900587 assertEquals(pinnedStack, mDefaultDisplay.getStackAbove(alwaysOnTopStack2));
Kazuki Takisef85197b2018-06-18 18:18:36 +0900588
589 alwaysOnTopStack2.setAlwaysOnTop(false);
590 // Ensure, when always on top is turned off for a stack, the stack is put just below all
591 // other always on top stacks.
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900592 assertEquals(alwaysOnTopStack, mDefaultDisplay.getStackAbove(alwaysOnTopStack2));
Kazuki Takise048e2662018-06-27 17:05:11 +0900593 alwaysOnTopStack2.setAlwaysOnTop(true);
594
595 // Ensure always on top state changes properly when windowing mode changes.
596 alwaysOnTopStack2.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
597 assertFalse(alwaysOnTopStack2.isAlwaysOnTop());
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900598 assertEquals(alwaysOnTopStack, mDefaultDisplay.getStackAbove(alwaysOnTopStack2));
Kazuki Takise048e2662018-06-27 17:05:11 +0900599 alwaysOnTopStack2.setWindowingMode(WINDOWING_MODE_FREEFORM);
600 assertTrue(alwaysOnTopStack2.isAlwaysOnTop());
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900601 assertEquals(pinnedStack, mDefaultDisplay.getStackAbove(alwaysOnTopStack2));
Kazuki Takisef85197b2018-06-18 18:18:36 +0900602 }
603
604 @Test
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900605 public void testSplitScreenMoveToFront() {
Winson Chung3e2980e2018-03-29 17:28:57 -0700606 final TestActivityStack splitScreenPrimary = createStackForShouldBeVisibleTest(
607 mDefaultDisplay, WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD,
608 true /* onTop */);
609 final TestActivityStack splitScreenSecondary = createStackForShouldBeVisibleTest(
610 mDefaultDisplay, WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD,
611 true /* onTop */);
612 final TestActivityStack assistantStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Wale Ogunwalebb285872018-03-01 13:05:30 -0800613 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_ASSISTANT, true /* onTop */);
614
615 splitScreenPrimary.setIsTranslucent(false);
616 splitScreenSecondary.setIsTranslucent(false);
617 assistantStack.setIsTranslucent(false);
618
619 assertFalse(splitScreenPrimary.shouldBeVisible(null /* starting */));
620 assertFalse(splitScreenSecondary.shouldBeVisible(null /* starting */));
621 assertTrue(assistantStack.shouldBeVisible(null /* starting */));
622
623 splitScreenSecondary.moveToFront("testSplitScreenMoveToFront");
624
625 assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */));
626 assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
627 assertFalse(assistantStack.shouldBeVisible(null /* starting */));
628 }
629
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900630 @SuppressWarnings("TypeParameterUnusedInFormals")
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700631 private <T extends ActivityStack> T createStackForShouldBeVisibleTest(
632 ActivityDisplay display, int windowingMode, int activityType, boolean onTop) {
Andrii Kulian6a6c4f12018-07-16 21:23:33 -0700633 final T stack;
634 if (activityType == ACTIVITY_TYPE_HOME) {
635 // Home stack and activity are created in ActivityTestsBase#setupActivityManagerService
636 stack = mDefaultDisplay.getStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME);
637 if (onTop) {
Riddle Hsu57831b52018-07-27 00:31:48 +0800638 mDefaultDisplay.positionChildAtTop(stack, false /* includingParents */);
Andrii Kulian6a6c4f12018-07-16 21:23:33 -0700639 } else {
640 mDefaultDisplay.positionChildAtBottom(stack);
641 }
642 } else {
643 stack = display.createStack(windowingMode, activityType, onTop);
644 final ActivityRecord r = new ActivityBuilder(mService).setUid(0).setStack(stack)
645 .setCreateTask(true).build();
646 }
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700647 return stack;
648 }
Bryce Leeb0f993f2018-03-02 15:38:01 -0800649
650 @Test
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900651 public void testFinishDisabledPackageActivities() {
Bryce Leefbd263b42018-03-07 10:33:55 -0800652 final ActivityRecord firstActivity = new ActivityBuilder(mService).setTask(mTask).build();
653 final ActivityRecord secondActivity = new ActivityBuilder(mService).setTask(mTask).build();
654
655 // Making the second activity a task overlay without an app means it will be removed from
656 // the task's activities as well once first activity is removed.
657 secondActivity.mTaskOverlay = true;
658 secondActivity.app = null;
659
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900660 assertEquals(2, mTask.mActivities.size());
Bryce Leefbd263b42018-03-07 10:33:55 -0800661
662 mStack.finishDisabledPackageActivitiesLocked(firstActivity.packageName, null,
663 true /* doit */, true /* evenPersistent */, UserHandle.USER_ALL);
664
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900665 assertThat(mTask.mActivities).isEmpty();
666 assertThat(mStack.getAllTasks()).isEmpty();
Bryce Leefbd263b42018-03-07 10:33:55 -0800667 }
668
669 @Test
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900670 public void testHandleAppDied() {
Bryce Leefbd263b42018-03-07 10:33:55 -0800671 final ActivityRecord firstActivity = new ActivityBuilder(mService).setTask(mTask).build();
672 final ActivityRecord secondActivity = new ActivityBuilder(mService).setTask(mTask).build();
673
674 // Making the first activity a task overlay means it will be removed from the task's
675 // activities as well once second activity is removed as handleAppDied processes the
676 // activity list in reverse.
677 firstActivity.mTaskOverlay = true;
678 firstActivity.app = null;
679
680 // second activity will be immediately removed as it has no state.
681 secondActivity.haveState = false;
682
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900683 assertEquals(2, mTask.mActivities.size());
Bryce Leefbd263b42018-03-07 10:33:55 -0800684
685 mStack.handleAppDiedLocked(secondActivity.app);
686
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900687 assertThat(mTask.mActivities).isEmpty();
688 assertThat(mStack.getAllTasks()).isEmpty();
Bryce Leefbd263b42018-03-07 10:33:55 -0800689 }
Bryce Lee271617a2018-03-15 10:39:12 -0700690
691 @Test
Garfield Tanf6cc5c92019-01-15 13:54:12 -0800692 public void testHandleAppDied_RelaunchesAfterCrashDuringWindowingModeResize() {
693 final ActivityRecord activity = new ActivityBuilder(mService).setTask(mTask).build();
694
695 activity.mRelaunchReason = RELAUNCH_REASON_WINDOWING_MODE_RESIZE;
696 activity.launchCount = 1;
697 activity.haveState = false;
698
699 mStack.handleAppDiedLocked(activity.app);
700
701 assertEquals(1, mTask.mActivities.size());
702 assertEquals(1, mStack.getAllTasks().size());
703 }
704
705 @Test
706 public void testHandleAppDied_NotRelaunchAfterThreeCrashesDuringWindowingModeResize() {
707 final ActivityRecord activity = new ActivityBuilder(mService).setTask(mTask).build();
708
709 activity.mRelaunchReason = RELAUNCH_REASON_WINDOWING_MODE_RESIZE;
710 activity.launchCount = 3;
711 activity.haveState = false;
712
713 mStack.handleAppDiedLocked(activity.app);
714
715 assertThat(mTask.mActivities).isEmpty();
716 assertThat(mStack.getAllTasks()).isEmpty();
717 }
718
719 @Test
720 public void testHandleAppDied_RelaunchesAfterCrashDuringFreeResize() {
721 final ActivityRecord activity = new ActivityBuilder(mService).setTask(mTask).build();
722
723 activity.mRelaunchReason = RELAUNCH_REASON_FREE_RESIZE;
724 activity.launchCount = 1;
725 activity.haveState = false;
726
727 mStack.handleAppDiedLocked(activity.app);
728
729 assertEquals(1, mTask.mActivities.size());
730 assertEquals(1, mStack.getAllTasks().size());
731 }
732
733 @Test
734 public void testHandleAppDied_NotRelaunchAfterThreeCrashesDuringFreeResize() {
735 final ActivityRecord activity = new ActivityBuilder(mService).setTask(mTask).build();
736
737 activity.mRelaunchReason = RELAUNCH_REASON_FREE_RESIZE;
738 activity.launchCount = 3;
739 activity.haveState = false;
740
741 mStack.handleAppDiedLocked(activity.app);
742
743 assertThat(mTask.mActivities).isEmpty();
744 assertThat(mStack.getAllTasks()).isEmpty();
745 }
746
747 @Test
Riddle Hsue10cea52018-10-16 23:33:23 +0800748 public void testFinishCurrentActivity() {
749 // Create 2 activities on a new display.
750 final ActivityDisplay display = addNewActivityDisplayAt(ActivityDisplay.POSITION_TOP);
751 final ActivityStack stack1 = createStackForShouldBeVisibleTest(display,
752 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
753 final ActivityStack stack2 = createStackForShouldBeVisibleTest(display,
754 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
755
756 // There is still an activity1 in stack1 so the activity2 should be added to finishing list
757 // that will be destroyed until idle.
Louis Changf2835df2018-10-17 15:14:45 +0800758 stack2.getTopActivity().visible = true;
Riddle Hsue10cea52018-10-16 23:33:23 +0800759 final ActivityRecord activity2 = finishCurrentActivity(stack2);
Louis Changf2835df2018-10-17 15:14:45 +0800760 assertEquals(STOPPING, activity2.getState());
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900761 assertThat(mSupervisor.mStoppingActivities).contains(activity2);
Riddle Hsue10cea52018-10-16 23:33:23 +0800762
763 // The display becomes empty. Since there is no next activity to be idle, the activity
764 // should be destroyed immediately with updating configuration to restore original state.
765 final ActivityRecord activity1 = finishCurrentActivity(stack1);
766 assertEquals(DESTROYING, activity1.getState());
Wale Ogunwaled32da472018-11-16 07:19:28 -0800767 verify(mRootActivityContainer).ensureVisibilityAndConfig(eq(null) /* starting */,
Riddle Hsue10cea52018-10-16 23:33:23 +0800768 eq(display.mDisplayId), anyBoolean(), anyBoolean());
769 }
770
771 private ActivityRecord finishCurrentActivity(ActivityStack stack) {
772 final ActivityRecord activity = stack.topRunningActivityLocked();
773 assertNotNull(activity);
774 activity.setState(PAUSED, "finishCurrentActivity");
775 activity.makeFinishingLocked();
776 stack.finishCurrentActivityLocked(activity, ActivityStack.FINISH_AFTER_VISIBLE,
777 false /* oomAdj */, "finishCurrentActivity");
778 return activity;
779 }
780
781 @Test
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900782 public void testShouldSleepActivities() {
Bryce Lee271617a2018-03-15 10:39:12 -0700783 // When focused activity and keyguard is going away, we should not sleep regardless
784 // of the display state
785 verifyShouldSleepActivities(true /* focusedStack */, true /*keyguardGoingAway*/,
786 true /* displaySleeping */, false /* expected*/);
787
788 // When not the focused stack, defer to display sleeping state.
789 verifyShouldSleepActivities(false /* focusedStack */, true /*keyguardGoingAway*/,
790 true /* displaySleeping */, true /* expected*/);
791
792 // If keyguard is going away, defer to the display sleeping state.
793 verifyShouldSleepActivities(true /* focusedStack */, false /*keyguardGoingAway*/,
794 true /* displaySleeping */, true /* expected*/);
795 verifyShouldSleepActivities(true /* focusedStack */, false /*keyguardGoingAway*/,
796 false /* displaySleeping */, false /* expected*/);
797 }
798
Winson Chung0f7ec962018-05-03 18:03:15 -0700799 @Test
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900800 public void testStackOrderChangedOnRemoveStack() {
Winson Chung0f7ec962018-05-03 18:03:15 -0700801 StackOrderChangedListener listener = new StackOrderChangedListener();
802 mDefaultDisplay.registerStackOrderChangedListener(listener);
803 try {
804 mDefaultDisplay.removeChild(mStack);
805 } finally {
806 mDefaultDisplay.unregisterStackOrderChangedListener(listener);
807 }
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900808 assertTrue(listener.mChanged);
Winson Chung0f7ec962018-05-03 18:03:15 -0700809 }
810
811 @Test
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900812 public void testStackOrderChangedOnAddPositionStack() {
Winson Chung0f7ec962018-05-03 18:03:15 -0700813 mDefaultDisplay.removeChild(mStack);
814
815 StackOrderChangedListener listener = new StackOrderChangedListener();
816 mDefaultDisplay.registerStackOrderChangedListener(listener);
817 try {
818 mDefaultDisplay.addChild(mStack, 0);
819 } finally {
820 mDefaultDisplay.unregisterStackOrderChangedListener(listener);
821 }
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900822 assertTrue(listener.mChanged);
Winson Chung0f7ec962018-05-03 18:03:15 -0700823 }
824
825 @Test
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900826 public void testStackOrderChangedOnPositionStack() {
Winson Chung0f7ec962018-05-03 18:03:15 -0700827 StackOrderChangedListener listener = new StackOrderChangedListener();
828 try {
829 final TestActivityStack fullscreenStack1 = createStackForShouldBeVisibleTest(
830 mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
831 true /* onTop */);
832 mDefaultDisplay.registerStackOrderChangedListener(listener);
833 mDefaultDisplay.positionChildAtBottom(fullscreenStack1);
834 } finally {
835 mDefaultDisplay.unregisterStackOrderChangedListener(listener);
836 }
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900837 assertTrue(listener.mChanged);
Winson Chung0f7ec962018-05-03 18:03:15 -0700838 }
839
Bryce Lee271617a2018-03-15 10:39:12 -0700840 private void verifyShouldSleepActivities(boolean focusedStack,
841 boolean keyguardGoingAway, boolean displaySleeping, boolean expected) {
Bryce Lee271617a2018-03-15 10:39:12 -0700842 final ActivityDisplay display = mock(ActivityDisplay.class);
843 final KeyguardController keyguardController = mSupervisor.getKeyguardController();
844
Wale Ogunwaled32da472018-11-16 07:19:28 -0800845 doReturn(display).when(mRootActivityContainer).getActivityDisplay(anyInt());
Bryce Lee271617a2018-03-15 10:39:12 -0700846 doReturn(keyguardGoingAway).when(keyguardController).isKeyguardGoingAway();
847 doReturn(displaySleeping).when(display).isSleeping();
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800848 doReturn(focusedStack).when(mStack).isFocusedStackOnDisplay();
Bryce Lee271617a2018-03-15 10:39:12 -0700849
850 assertEquals(expected, mStack.shouldSleepActivities());
851 }
Winson Chung0f7ec962018-05-03 18:03:15 -0700852
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900853 private static class StackOrderChangedListener
854 implements ActivityDisplay.OnStackOrderChangedListener {
855 public boolean mChanged = false;
Winson Chung0f7ec962018-05-03 18:03:15 -0700856
857 @Override
Winson Chung65d66d32018-12-13 17:48:39 -0800858 public void onStackOrderChanged(ActivityStack stack) {
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900859 mChanged = true;
Winson Chung0f7ec962018-05-03 18:03:15 -0700860 }
861 }
Bryce Lee840c5662017-04-13 10:02:51 -0700862}