blob: 986943aaf1460f00e2b0082e50a3c16bae7141cf [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;
Riddle Hsuaaef7312019-01-24 19:00:58 +080037import static com.android.server.wm.ActivityStack.ActivityState.STOPPED;
Wale Ogunwale59507092018-10-29 09:00:30 -070038import static com.android.server.wm.ActivityStack.ActivityState.STOPPING;
39import static com.android.server.wm.ActivityStack.REMOVE_TASK_MODE_DESTROYING;
Garfield Tanf6cc5c92019-01-15 13:54:12 -080040import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_FREE_RESIZE;
41import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_WINDOWING_MODE_RESIZE;
Bryce Lee18d51592017-10-25 10:22:19 -070042
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +090043import static com.google.common.truth.Truth.assertThat;
44
Bryce Lee5daa3122017-04-19 10:40:42 -070045import static org.junit.Assert.assertEquals;
David Stevens18abd0e2017-08-17 14:55:47 -070046import static org.junit.Assert.assertFalse;
Bryce Lee840c5662017-04-13 10:02:51 -070047import static org.junit.Assert.assertNotNull;
48import static org.junit.Assert.assertNull;
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -070049import static org.junit.Assert.assertTrue;
Riddle Hsu138ef932018-10-26 17:12:06 +080050import static org.mockito.ArgumentMatchers.any;
Riddle Hsue10cea52018-10-16 23:33:23 +080051import static org.mockito.ArgumentMatchers.anyBoolean;
52import static org.mockito.ArgumentMatchers.anyInt;
Riddle Hsue10cea52018-10-16 23:33:23 +080053import static org.mockito.ArgumentMatchers.eq;
Bryce Lee840c5662017-04-13 10:02:51 -070054
Riddle Hsuaaef7312019-01-24 19:00:58 +080055import android.content.ComponentName;
Bryce Lee3345c4e2017-04-25 07:40:41 -070056import android.content.pm.ActivityInfo;
Bryce Lee9f6affd2017-09-01 09:18:35 -070057import android.os.UserHandle;
Bryce Lee840c5662017-04-13 10:02:51 -070058import android.platform.test.annotations.Presubmit;
Bryce Lee840c5662017-04-13 10:02:51 -070059
Brett Chabota26eda92018-07-23 13:08:30 -070060import androidx.test.filters.SmallTest;
Brett Chabota26eda92018-07-23 13:08:30 -070061
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070062import org.junit.Before;
Bryce Lee840c5662017-04-13 10:02:51 -070063import org.junit.Test;
64
65/**
66 * Tests for the {@link ActivityStack} class.
67 *
68 * Build/Install/Run:
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +090069 * atest WmTests:ActivityStackTests
Bryce Lee840c5662017-04-13 10:02:51 -070070 */
71@SmallTest
72@Presubmit
Bryce Lee840c5662017-04-13 10:02:51 -070073public class ActivityStackTests extends ActivityTestsBase {
Winson Chung3e2980e2018-03-29 17:28:57 -070074 private ActivityDisplay mDefaultDisplay;
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070075 private ActivityStack mStack;
76 private TaskRecord mTask;
77
78 @Before
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070079 public void setUp() throws Exception {
Wale Ogunwaled32da472018-11-16 07:19:28 -080080 mDefaultDisplay = mRootActivityContainer.getDefaultDisplay();
Tiger Huang1e5b10a2018-07-30 20:19:51 +080081 mStack = spy(mDefaultDisplay.createStack(WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD,
82 true /* onTop */));
Bryce Lee18d51592017-10-25 10:22:19 -070083 mTask = new TaskBuilder(mSupervisor).setStack(mStack).build();
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070084 }
85
Bryce Lee840c5662017-04-13 10:02:51 -070086 @Test
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +090087 public void testEmptyTaskCleanupOnRemove() {
Yunfan Chen0e7aff92018-12-05 16:35:32 -080088 assertNotNull(mTask.getTask());
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070089 mStack.removeTask(mTask, "testEmptyTaskCleanupOnRemove", REMOVE_TASK_MODE_DESTROYING);
Yunfan Chen0e7aff92018-12-05 16:35:32 -080090 assertNull(mTask.getTask());
Bryce Lee840c5662017-04-13 10:02:51 -070091 }
Bryce Lee5daa3122017-04-19 10:40:42 -070092
Bryce Lee840c5662017-04-13 10:02:51 -070093 @Test
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +090094 public void testOccupiedTaskCleanupOnRemove() {
Bryce Lee18d51592017-10-25 10:22:19 -070095 final ActivityRecord r = new ActivityBuilder(mService).setTask(mTask).build();
Yunfan Chen0e7aff92018-12-05 16:35:32 -080096 assertNotNull(mTask.getTask());
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070097 mStack.removeTask(mTask, "testOccupiedTaskCleanupOnRemove", REMOVE_TASK_MODE_DESTROYING);
Yunfan Chen0e7aff92018-12-05 16:35:32 -080098 assertNotNull(mTask.getTask());
Bryce Lee840c5662017-04-13 10:02:51 -070099 }
Bryce Lee5daa3122017-04-19 10:40:42 -0700100
101 @Test
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900102 public void testResumedActivity() {
Bryce Leec4ab62a2018-03-05 14:19:26 -0800103 final ActivityRecord r = new ActivityBuilder(mService).setTask(mTask).build();
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900104 assertNull(mStack.getResumedActivity());
Bryce Leec4ab62a2018-03-05 14:19:26 -0800105 r.setState(RESUMED, "testResumedActivity");
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900106 assertEquals(r, mStack.getResumedActivity());
Bryce Leec4ab62a2018-03-05 14:19:26 -0800107 r.setState(PAUSING, "testResumedActivity");
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900108 assertNull(mStack.getResumedActivity());
Bryce Lee84730a02018-04-03 14:10:04 -0700109 }
Bryce Leec4ab62a2018-03-05 14:19:26 -0800110
Bryce Lee84730a02018-04-03 14:10:04 -0700111 @Test
112 public void testResumedActivityFromTaskReparenting() {
113 final ActivityRecord r = new ActivityBuilder(mService).setTask(mTask).build();
114 // Ensure moving task between two stacks updates resumed activity
115 r.setState(RESUMED, "testResumedActivityFromTaskReparenting");
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900116 assertEquals(r, mStack.getResumedActivity());
Bryce Lee84730a02018-04-03 14:10:04 -0700117
Wale Ogunwaled32da472018-11-16 07:19:28 -0800118 final ActivityStack destStack = mRootActivityContainer.getDefaultDisplay().createStack(
Bryce Lee84730a02018-04-03 14:10:04 -0700119 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
120
121 mTask.reparent(destStack, true /* toTop */, TaskRecord.REPARENT_KEEP_STACK_AT_FRONT,
122 false /* animate */, true /* deferResume*/,
123 "testResumedActivityFromTaskReparenting");
124
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900125 assertNull(mStack.getResumedActivity());
126 assertEquals(r, destStack.getResumedActivity());
Bryce Lee84730a02018-04-03 14:10:04 -0700127 }
128
129 @Test
130 public void testResumedActivityFromActivityReparenting() {
131 final ActivityRecord r = new ActivityBuilder(mService).setTask(mTask).build();
132 // Ensure moving task between two stacks updates resumed activity
133 r.setState(RESUMED, "testResumedActivityFromActivityReparenting");
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900134 assertEquals(r, mStack.getResumedActivity());
Bryce Lee84730a02018-04-03 14:10:04 -0700135
Wale Ogunwaled32da472018-11-16 07:19:28 -0800136 final ActivityStack destStack = mRootActivityContainer.getDefaultDisplay().createStack(
Bryce Lee84730a02018-04-03 14:10:04 -0700137 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
138 final TaskRecord destTask = new TaskBuilder(mSupervisor).setStack(destStack).build();
139
140 mTask.removeActivity(r);
141 destTask.addActivityToTop(r);
142
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900143 assertNull(mStack.getResumedActivity());
144 assertEquals(r, destStack.getResumedActivity());
Bryce Lee5daa3122017-04-19 10:40:42 -0700145 }
Bryce Lee3345c4e2017-04-25 07:40:41 -0700146
147 @Test
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900148 public void testPrimarySplitScreenRestoresWhenMovedToBack() {
Bryce Lee8cab4a02018-01-05 09:00:49 -0800149 // Create primary splitscreen stack. This will create secondary stacks and places the
150 // existing fullscreen stack on the bottom.
Winson Chung3e2980e2018-03-29 17:28:57 -0700151 final ActivityStack primarySplitScreen = mDefaultDisplay.createStack(
152 WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD, true /* onTop */);
Bryce Lee8cab4a02018-01-05 09:00:49 -0800153
154 // Assert windowing mode.
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900155 assertEquals(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, primarySplitScreen.getWindowingMode());
Bryce Lee8cab4a02018-01-05 09:00:49 -0800156
157 // Move primary to back.
158 primarySplitScreen.moveToBack("testPrimarySplitScreenToFullscreenWhenMovedToBack",
159 null /* task */);
160
161 // Assert that stack is at the bottom.
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900162 assertEquals(0, mDefaultDisplay.getIndexOf(primarySplitScreen));
Bryce Lee8cab4a02018-01-05 09:00:49 -0800163
164 // Ensure no longer in splitscreen.
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900165 assertEquals(WINDOWING_MODE_FULLSCREEN, primarySplitScreen.getWindowingMode());
Evan Rosky10475742018-09-05 19:02:48 -0700166
167 // Ensure that the override mode is restored to undefined
Evan Roskydfe3da72018-10-26 17:21:06 -0700168 assertEquals(WINDOWING_MODE_UNDEFINED,
169 primarySplitScreen.getRequestedOverrideWindowingMode());
Evan Rosky10475742018-09-05 19:02:48 -0700170 }
171
172 @Test
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900173 public void testPrimarySplitScreenRestoresPreviousWhenMovedToBack() {
Evan Rosky10475742018-09-05 19:02:48 -0700174 // This time, start with a fullscreen activitystack
175 final ActivityStack primarySplitScreen = mDefaultDisplay.createStack(
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900176 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
Evan Rosky10475742018-09-05 19:02:48 -0700177
178 primarySplitScreen.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
179
180 // Assert windowing mode.
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900181 assertEquals(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, primarySplitScreen.getWindowingMode());
Evan Rosky10475742018-09-05 19:02:48 -0700182
183 // Move primary to back.
184 primarySplitScreen.moveToBack("testPrimarySplitScreenToFullscreenWhenMovedToBack",
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900185 null /* task */);
Evan Rosky10475742018-09-05 19:02:48 -0700186
187 // Assert that stack is at the bottom.
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900188 assertEquals(0, mDefaultDisplay.getIndexOf(primarySplitScreen));
Evan Rosky10475742018-09-05 19:02:48 -0700189
190 // Ensure that the override mode is restored to what it was (fullscreen)
Evan Roskydfe3da72018-10-26 17:21:06 -0700191 assertEquals(WINDOWING_MODE_FULLSCREEN,
192 primarySplitScreen.getRequestedOverrideWindowingMode());
Evan Rosky10475742018-09-05 19:02:48 -0700193 }
194
195 @Test
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900196 public void testStackInheritsDisplayWindowingMode() {
Evan Rosky10475742018-09-05 19:02:48 -0700197 final ActivityStack primarySplitScreen = mDefaultDisplay.createStack(
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900198 WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD, true /* onTop */);
Evan Rosky10475742018-09-05 19:02:48 -0700199
200 assertEquals(WINDOWING_MODE_FULLSCREEN, primarySplitScreen.getWindowingMode());
Evan Roskydfe3da72018-10-26 17:21:06 -0700201 assertEquals(WINDOWING_MODE_UNDEFINED,
202 primarySplitScreen.getRequestedOverrideWindowingMode());
Evan Rosky10475742018-09-05 19:02:48 -0700203
204 mDefaultDisplay.setWindowingMode(WINDOWING_MODE_FREEFORM);
205 assertEquals(WINDOWING_MODE_FREEFORM, primarySplitScreen.getWindowingMode());
Evan Roskydfe3da72018-10-26 17:21:06 -0700206 assertEquals(WINDOWING_MODE_UNDEFINED,
207 primarySplitScreen.getRequestedOverrideWindowingMode());
Evan Rosky10475742018-09-05 19:02:48 -0700208 }
209
210 @Test
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900211 public void testStackOverridesDisplayWindowingMode() {
Evan Rosky10475742018-09-05 19:02:48 -0700212 final ActivityStack primarySplitScreen = mDefaultDisplay.createStack(
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900213 WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD, true /* onTop */);
Evan Rosky10475742018-09-05 19:02:48 -0700214
215 assertEquals(WINDOWING_MODE_FULLSCREEN, primarySplitScreen.getWindowingMode());
Evan Roskydfe3da72018-10-26 17:21:06 -0700216 assertEquals(WINDOWING_MODE_UNDEFINED,
217 primarySplitScreen.getRequestedOverrideWindowingMode());
Evan Rosky10475742018-09-05 19:02:48 -0700218
219 primarySplitScreen.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
220 // setting windowing mode should still work even though resolved mode is already fullscreen
Evan Roskydfe3da72018-10-26 17:21:06 -0700221 assertEquals(WINDOWING_MODE_FULLSCREEN,
222 primarySplitScreen.getRequestedOverrideWindowingMode());
Evan Rosky10475742018-09-05 19:02:48 -0700223
224 mDefaultDisplay.setWindowingMode(WINDOWING_MODE_FREEFORM);
225 assertEquals(WINDOWING_MODE_FULLSCREEN, primarySplitScreen.getWindowingMode());
Bryce Lee8cab4a02018-01-05 09:00:49 -0800226 }
227
228 @Test
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900229 public void testStopActivityWhenActivityDestroyed() {
Bryce Lee18d51592017-10-25 10:22:19 -0700230 final ActivityRecord r = new ActivityBuilder(mService).setTask(mTask).build();
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700231 r.info.flags |= ActivityInfo.FLAG_NO_HISTORY;
Andrii Kulian6a6c4f12018-07-16 21:23:33 -0700232 mStack.moveToFront("testStopActivityWithDestroy");
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700233 mStack.stopActivityLocked(r);
234 // Mostly testing to make sure there is a crash in the call part, so if we get here we are
235 // good-to-go!
Bryce Lee3345c4e2017-04-25 07:40:41 -0700236 }
Bryce Lee9f6affd2017-09-01 09:18:35 -0700237
238 @Test
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900239 public void testFindTaskWithOverlay() {
Bryce Lee18d51592017-10-25 10:22:19 -0700240 final ActivityRecord r = new ActivityBuilder(mService)
241 .setCreateTask(true)
242 .setStack(mStack)
243 .setUid(0)
244 .build();
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800245 final TaskRecord task = r.getTaskRecord();
Bryce Lee9f6affd2017-09-01 09:18:35 -0700246 // Overlay must be for a different user to prevent recognizing a matching top activity
Bryce Lee18d51592017-10-25 10:22:19 -0700247 final ActivityRecord taskOverlay = new ActivityBuilder(mService).setTask(task)
248 .setUid(UserHandle.PER_USER_RANGE * 2).build();
Bryce Lee9f6affd2017-09-01 09:18:35 -0700249 taskOverlay.mTaskOverlay = true;
250
Wale Ogunwaled32da472018-11-16 07:19:28 -0800251 final RootActivityContainer.FindTaskResult result =
252 new RootActivityContainer.FindTaskResult();
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700253 mStack.findTaskLocked(r, result);
Bryce Lee9f6affd2017-09-01 09:18:35 -0700254
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900255 assertEquals(r, task.getTopActivity(false /* includeOverlays */));
256 assertEquals(taskOverlay, task.getTopActivity(true /* includeOverlays */));
Louis Changc85b1a32018-08-14 16:40:53 +0800257 assertNotNull(result.mRecord);
Bryce Lee9f6affd2017-09-01 09:18:35 -0700258 }
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700259
260 @Test
Riddle Hsu138ef932018-10-26 17:12:06 +0800261 public void testMoveStackToBackIncludingParent() {
262 final ActivityDisplay display = addNewActivityDisplayAt(ActivityDisplay.POSITION_TOP);
263 final ActivityStack stack1 = createStackForShouldBeVisibleTest(display,
264 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
265 final ActivityStack stack2 = createStackForShouldBeVisibleTest(display,
266 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
267
268 // Do not move display to back because there is still another stack.
269 stack2.moveToBack("testMoveStackToBackIncludingParent", stack2.topTask());
Yunfan Chen279f5582018-12-12 15:24:50 -0800270 verify(stack2.getTaskStack()).positionChildAtBottom(any(),
Riddle Hsu138ef932018-10-26 17:12:06 +0800271 eq(false) /* includingParents */);
272
273 // Also move display to back because there is only one stack left.
274 display.removeChild(stack1);
275 stack2.moveToBack("testMoveStackToBackIncludingParent", stack2.topTask());
Yunfan Chen279f5582018-12-12 15:24:50 -0800276 verify(stack2.getTaskStack()).positionChildAtBottom(any(),
Riddle Hsu138ef932018-10-26 17:12:06 +0800277 eq(true) /* includingParents */);
278 }
279
280 @Test
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900281 public void testShouldBeVisible_Fullscreen() {
Winson Chung3e2980e2018-03-29 17:28:57 -0700282 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700283 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
Winson Chung3e2980e2018-03-29 17:28:57 -0700284 final ActivityStack pinnedStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700285 WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, true /* onTop */);
286
287 assertTrue(homeStack.shouldBeVisible(null /* starting */));
288 assertTrue(pinnedStack.shouldBeVisible(null /* starting */));
289
Winson Chung3e2980e2018-03-29 17:28:57 -0700290 final TestActivityStack fullscreenStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700291 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
292 // Home stack shouldn't be visible behind an opaque fullscreen stack, but pinned stack
293 // should be visible since it is always on-top.
294 fullscreenStack.setIsTranslucent(false);
295 assertFalse(homeStack.shouldBeVisible(null /* starting */));
296 assertTrue(pinnedStack.shouldBeVisible(null /* starting */));
297 assertTrue(fullscreenStack.shouldBeVisible(null /* starting */));
298
299 // Home stack should be visible behind a translucent fullscreen stack.
300 fullscreenStack.setIsTranslucent(true);
301 assertTrue(homeStack.shouldBeVisible(null /* starting */));
302 assertTrue(pinnedStack.shouldBeVisible(null /* starting */));
303 }
304
305 @Test
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900306 public void testShouldBeVisible_SplitScreen() {
Winson Chung3e2980e2018-03-29 17:28:57 -0700307 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700308 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
Wale Ogunwale30e441d2017-11-09 08:28:45 -0800309 // Home stack should always be fullscreen for this test.
310 homeStack.setSupportsSplitScreen(false);
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900311 final TestActivityStack splitScreenPrimary =
312 createStackForShouldBeVisibleTest(mDefaultDisplay,
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700313 WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD, true /* onTop */);
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900314 final TestActivityStack splitScreenSecondary =
315 createStackForShouldBeVisibleTest(mDefaultDisplay,
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700316 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD, true /* onTop */);
317
318 // Home stack shouldn't be visible if both halves of split-screen are opaque.
319 splitScreenPrimary.setIsTranslucent(false);
320 splitScreenSecondary.setIsTranslucent(false);
321 assertFalse(homeStack.shouldBeVisible(null /* starting */));
322 assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */));
323 assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
324
325 // Home stack should be visible if one of the halves of split-screen is translucent.
326 splitScreenPrimary.setIsTranslucent(true);
327 assertTrue(homeStack.shouldBeVisible(null /* starting */));
328 assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */));
329 assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
330
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900331 final TestActivityStack splitScreenSecondary2 =
332 createStackForShouldBeVisibleTest(mDefaultDisplay,
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700333 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD, true /* onTop */);
334 // First split-screen secondary shouldn't be visible behind another opaque split-split
335 // secondary.
336 splitScreenSecondary2.setIsTranslucent(false);
337 assertFalse(splitScreenSecondary.shouldBeVisible(null /* starting */));
338 assertTrue(splitScreenSecondary2.shouldBeVisible(null /* starting */));
339
Wale Ogunwale8e923af2018-03-23 08:48:11 -0700340 // First split-screen secondary should be visible behind another translucent split-screen
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700341 // secondary.
342 splitScreenSecondary2.setIsTranslucent(true);
343 assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
344 assertTrue(splitScreenSecondary2.shouldBeVisible(null /* starting */));
345
Winson Chung3e2980e2018-03-29 17:28:57 -0700346 final TestActivityStack assistantStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700347 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_ASSISTANT, true /* onTop */);
348
349 // Split-screen stacks shouldn't be visible behind an opaque fullscreen stack.
350 assistantStack.setIsTranslucent(false);
351 assertTrue(assistantStack.shouldBeVisible(null /* starting */));
352 assertFalse(splitScreenPrimary.shouldBeVisible(null /* starting */));
353 assertFalse(splitScreenSecondary.shouldBeVisible(null /* starting */));
354 assertFalse(splitScreenSecondary2.shouldBeVisible(null /* starting */));
355
356 // Split-screen stacks should be visible behind a translucent fullscreen stack.
357 assistantStack.setIsTranslucent(true);
358 assertTrue(assistantStack.shouldBeVisible(null /* starting */));
359 assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */));
360 assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
361 assertTrue(splitScreenSecondary2.shouldBeVisible(null /* starting */));
Wale Ogunwale8e923af2018-03-23 08:48:11 -0700362
363 // Assistant stack shouldn't be visible behind translucent split-screen stack
364 assistantStack.setIsTranslucent(false);
365 splitScreenPrimary.setIsTranslucent(true);
366 splitScreenSecondary2.setIsTranslucent(true);
367 splitScreenSecondary2.moveToFront("testShouldBeVisible_SplitScreen");
368 splitScreenPrimary.moveToFront("testShouldBeVisible_SplitScreen");
369 assertFalse(assistantStack.shouldBeVisible(null /* starting */));
370 assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */));
371 assertTrue(splitScreenSecondary2.shouldBeVisible(null /* starting */));
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700372 }
373
374 @Test
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900375 public void testShouldBeVisible_Finishing() {
Winson Chung3e2980e2018-03-29 17:28:57 -0700376 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700377 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
Winson Chung3e2980e2018-03-29 17:28:57 -0700378 final TestActivityStack translucentStack = createStackForShouldBeVisibleTest(
379 mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
380 true /* onTop */);
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700381 translucentStack.setIsTranslucent(true);
382
383 assertTrue(homeStack.shouldBeVisible(null /* starting */));
384 assertTrue(translucentStack.shouldBeVisible(null /* starting */));
385
386 final ActivityRecord topRunningHomeActivity = homeStack.topRunningActivityLocked();
387 topRunningHomeActivity.finishing = true;
388 final ActivityRecord topRunningTranslucentActivity =
389 translucentStack.topRunningActivityLocked();
390 topRunningTranslucentActivity.finishing = true;
391
Louis Changf2835df2018-10-17 15:14:45 +0800392 // Home stack should be visible even there are no running activities.
393 assertTrue(homeStack.shouldBeVisible(null /* starting */));
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700394 // Home should be visible if we are starting an activity within it.
395 assertTrue(homeStack.shouldBeVisible(topRunningHomeActivity /* starting */));
Louis Changf2835df2018-10-17 15:14:45 +0800396 // The translucent stack shouldn't be visible since its activity marked as finishing.
397 assertFalse(translucentStack.shouldBeVisible(null /* starting */));
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700398 }
399
Winson Chungd922b6b2018-02-16 16:41:50 -0800400 @Test
401 public void testMoveHomeStackBehindBottomMostVisibleStack_NoMoveHomeBehindFullscreen() {
Winson Chung3e2980e2018-03-29 17:28:57 -0700402 mDefaultDisplay.removeChild(mStack);
Winson Chungd922b6b2018-02-16 16:41:50 -0800403
Winson Chung3e2980e2018-03-29 17:28:57 -0700404 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Winson Chungd922b6b2018-02-16 16:41:50 -0800405 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
Winson Chung3e2980e2018-03-29 17:28:57 -0700406 final TestActivityStack fullscreenStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Winson Chungd922b6b2018-02-16 16:41:50 -0800407 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
408
409 homeStack.setIsTranslucent(false);
410 fullscreenStack.setIsTranslucent(false);
411
412 // 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 -0700413 int homeStackIndex = mDefaultDisplay.getIndexOf(homeStack);
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900414 assertEquals(fullscreenStack, mDefaultDisplay.getStackAbove(homeStack));
Winson Chung3e2980e2018-03-29 17:28:57 -0700415 mDefaultDisplay.moveStackBehindBottomMostVisibleStack(homeStack);
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900416 assertEquals(homeStackIndex, mDefaultDisplay.getIndexOf(homeStack));
Winson Chungd922b6b2018-02-16 16:41:50 -0800417 }
418
419 @Test
420 public void testMoveHomeStackBehindBottomMostVisibleStack_NoMoveHomeBehindTranslucent() {
Winson Chung3e2980e2018-03-29 17:28:57 -0700421 mDefaultDisplay.removeChild(mStack);
Winson Chungd922b6b2018-02-16 16:41:50 -0800422
Winson Chung3e2980e2018-03-29 17:28:57 -0700423 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Winson Chungd922b6b2018-02-16 16:41:50 -0800424 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
Winson Chung3e2980e2018-03-29 17:28:57 -0700425 final TestActivityStack fullscreenStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Winson Chungd922b6b2018-02-16 16:41:50 -0800426 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
427
428 homeStack.setIsTranslucent(false);
429 fullscreenStack.setIsTranslucent(true);
430
431 // 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 -0700432 int homeStackIndex = mDefaultDisplay.getIndexOf(homeStack);
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900433 assertEquals(fullscreenStack, mDefaultDisplay.getStackAbove(homeStack));
Winson Chung3e2980e2018-03-29 17:28:57 -0700434 mDefaultDisplay.moveStackBehindBottomMostVisibleStack(homeStack);
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900435 assertEquals(homeStackIndex, mDefaultDisplay.getIndexOf(homeStack));
Winson Chungd922b6b2018-02-16 16:41:50 -0800436 }
437
438 @Test
439 public void testMoveHomeStackBehindBottomMostVisibleStack_NoMoveHomeOnTop() {
Winson Chung3e2980e2018-03-29 17:28:57 -0700440 mDefaultDisplay.removeChild(mStack);
Winson Chungd922b6b2018-02-16 16:41:50 -0800441
Winson Chung3e2980e2018-03-29 17:28:57 -0700442 final TestActivityStack fullscreenStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Winson Chungd922b6b2018-02-16 16:41:50 -0800443 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
Winson Chung3e2980e2018-03-29 17:28:57 -0700444 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Winson Chungd922b6b2018-02-16 16:41:50 -0800445 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
446
447 homeStack.setIsTranslucent(false);
448 fullscreenStack.setIsTranslucent(false);
449
450 // Ensure we don't move the home stack if it is already on top
Winson Chung3e2980e2018-03-29 17:28:57 -0700451 int homeStackIndex = mDefaultDisplay.getIndexOf(homeStack);
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900452 assertNull(mDefaultDisplay.getStackAbove(homeStack));
Winson Chung3e2980e2018-03-29 17:28:57 -0700453 mDefaultDisplay.moveStackBehindBottomMostVisibleStack(homeStack);
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900454 assertEquals(homeStackIndex, mDefaultDisplay.getIndexOf(homeStack));
Winson Chungd922b6b2018-02-16 16:41:50 -0800455 }
456
457 @Test
458 public void testMoveHomeStackBehindBottomMostVisibleStack_MoveHomeBehindFullscreen() {
Winson Chung3e2980e2018-03-29 17:28:57 -0700459 mDefaultDisplay.removeChild(mStack);
Winson Chungd922b6b2018-02-16 16:41:50 -0800460
Winson Chung3e2980e2018-03-29 17:28:57 -0700461 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Winson Chungd922b6b2018-02-16 16:41:50 -0800462 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
Winson Chung3e2980e2018-03-29 17:28:57 -0700463 final TestActivityStack fullscreenStack1 = createStackForShouldBeVisibleTest(
464 mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
465 true /* onTop */);
466 final TestActivityStack fullscreenStack2 = createStackForShouldBeVisibleTest(
467 mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
468 true /* onTop */);
Wale Ogunwale24116192018-11-07 07:46:56 -0800469 final ActivityStack pinnedStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Winson Chungd922b6b2018-02-16 16:41:50 -0800470 WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, true /* onTop */);
471
472 homeStack.setIsTranslucent(false);
473 fullscreenStack1.setIsTranslucent(false);
474 fullscreenStack2.setIsTranslucent(false);
475
476 // Ensure that we move the home stack behind the bottom most fullscreen stack, ignoring the
477 // pinned stack
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900478 assertEquals(fullscreenStack1, mDefaultDisplay.getStackAbove(homeStack));
Winson Chung3e2980e2018-03-29 17:28:57 -0700479 mDefaultDisplay.moveStackBehindBottomMostVisibleStack(homeStack);
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900480 assertEquals(fullscreenStack2, mDefaultDisplay.getStackAbove(homeStack));
Winson Chungd922b6b2018-02-16 16:41:50 -0800481 }
482
483 @Test
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900484 public void
485 testMoveHomeStackBehindBottomMostVisibleStack_MoveHomeBehindFullscreenAndTranslucent() {
Winson Chung3e2980e2018-03-29 17:28:57 -0700486 mDefaultDisplay.removeChild(mStack);
Winson Chungd922b6b2018-02-16 16:41:50 -0800487
Winson Chung3e2980e2018-03-29 17:28:57 -0700488 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Winson Chungd922b6b2018-02-16 16:41:50 -0800489 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
Winson Chung3e2980e2018-03-29 17:28:57 -0700490 final TestActivityStack fullscreenStack1 = createStackForShouldBeVisibleTest(
491 mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
492 true /* onTop */);
493 final TestActivityStack fullscreenStack2 = createStackForShouldBeVisibleTest(
494 mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
495 true /* onTop */);
Winson Chungd922b6b2018-02-16 16:41:50 -0800496
497 homeStack.setIsTranslucent(false);
498 fullscreenStack1.setIsTranslucent(false);
499 fullscreenStack2.setIsTranslucent(true);
500
501 // Ensure that we move the home stack behind the bottom most non-translucent fullscreen
502 // stack
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900503 assertEquals(fullscreenStack1, mDefaultDisplay.getStackAbove(homeStack));
Winson Chung3e2980e2018-03-29 17:28:57 -0700504 mDefaultDisplay.moveStackBehindBottomMostVisibleStack(homeStack);
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900505 assertEquals(fullscreenStack1, mDefaultDisplay.getStackAbove(homeStack));
Winson Chungd922b6b2018-02-16 16:41:50 -0800506 }
507
508 @Test
509 public void testMoveHomeStackBehindStack_BehindHomeStack() {
Winson Chung3e2980e2018-03-29 17:28:57 -0700510 mDefaultDisplay.removeChild(mStack);
Winson Chungd922b6b2018-02-16 16:41:50 -0800511
Winson Chung3e2980e2018-03-29 17:28:57 -0700512 final TestActivityStack fullscreenStack1 = createStackForShouldBeVisibleTest(
513 mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
514 true /* onTop */);
515 final TestActivityStack fullscreenStack2 = createStackForShouldBeVisibleTest(
516 mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
517 true /* onTop */);
518 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Winson Chungd922b6b2018-02-16 16:41:50 -0800519 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
520
521 homeStack.setIsTranslucent(false);
522 fullscreenStack1.setIsTranslucent(false);
523 fullscreenStack2.setIsTranslucent(false);
524
525 // Ensure we don't move the home stack behind itself
Winson Chung3e2980e2018-03-29 17:28:57 -0700526 int homeStackIndex = mDefaultDisplay.getIndexOf(homeStack);
527 mDefaultDisplay.moveStackBehindStack(homeStack, homeStack);
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900528 assertEquals(homeStackIndex, mDefaultDisplay.getIndexOf(homeStack));
Winson Chungd922b6b2018-02-16 16:41:50 -0800529 }
530
531 @Test
532 public void testMoveHomeStackBehindStack() {
Winson Chung3e2980e2018-03-29 17:28:57 -0700533 mDefaultDisplay.removeChild(mStack);
Winson Chungd922b6b2018-02-16 16:41:50 -0800534
Winson Chung3e2980e2018-03-29 17:28:57 -0700535 final TestActivityStack fullscreenStack1 = createStackForShouldBeVisibleTest(
536 mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
537 true /* onTop */);
538 final TestActivityStack fullscreenStack2 = createStackForShouldBeVisibleTest(
539 mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
540 true /* onTop */);
541 final TestActivityStack fullscreenStack3 = createStackForShouldBeVisibleTest(
542 mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
543 true /* onTop */);
544 final TestActivityStack fullscreenStack4 = createStackForShouldBeVisibleTest(
545 mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
546 true /* onTop */);
547 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Winson Chungd922b6b2018-02-16 16:41:50 -0800548 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
549
Winson Chung3e2980e2018-03-29 17:28:57 -0700550 mDefaultDisplay.moveStackBehindStack(homeStack, fullscreenStack1);
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900551 assertEquals(fullscreenStack1, mDefaultDisplay.getStackAbove(homeStack));
Winson Chung3e2980e2018-03-29 17:28:57 -0700552 mDefaultDisplay.moveStackBehindStack(homeStack, fullscreenStack2);
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900553 assertEquals(fullscreenStack2, mDefaultDisplay.getStackAbove(homeStack));
Winson Chung3e2980e2018-03-29 17:28:57 -0700554 mDefaultDisplay.moveStackBehindStack(homeStack, fullscreenStack4);
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900555 assertEquals(fullscreenStack4, mDefaultDisplay.getStackAbove(homeStack));
Winson Chung3e2980e2018-03-29 17:28:57 -0700556 mDefaultDisplay.moveStackBehindStack(homeStack, fullscreenStack2);
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900557 assertEquals(fullscreenStack2, mDefaultDisplay.getStackAbove(homeStack));
Winson Chungd922b6b2018-02-16 16:41:50 -0800558 }
559
Wale Ogunwalebb285872018-03-01 13:05:30 -0800560 @Test
Kazuki Takisef85197b2018-06-18 18:18:36 +0900561 public void testSetAlwaysOnTop() {
562 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
563 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
564 final ActivityStack pinnedStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
565 WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, true /* onTop */);
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900566 assertEquals(pinnedStack, mDefaultDisplay.getStackAbove(homeStack));
Kazuki Takisef85197b2018-06-18 18:18:36 +0900567
568 final TestActivityStack alwaysOnTopStack = createStackForShouldBeVisibleTest(
569 mDefaultDisplay, WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD,
570 true /* onTop */);
571 alwaysOnTopStack.setAlwaysOnTop(true);
572 assertTrue(alwaysOnTopStack.isAlwaysOnTop());
573 // Ensure (non-pinned) always on top stack is put below pinned stack.
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900574 assertEquals(pinnedStack, mDefaultDisplay.getStackAbove(alwaysOnTopStack));
Kazuki Takisef85197b2018-06-18 18:18:36 +0900575
576 final TestActivityStack nonAlwaysOnTopStack = createStackForShouldBeVisibleTest(
577 mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
578 true /* onTop */);
579 // Ensure non always on top stack is put below always on top stacks.
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900580 assertEquals(alwaysOnTopStack, mDefaultDisplay.getStackAbove(nonAlwaysOnTopStack));
Kazuki Takisef85197b2018-06-18 18:18:36 +0900581
582 final TestActivityStack alwaysOnTopStack2 = createStackForShouldBeVisibleTest(
583 mDefaultDisplay, WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD,
584 true /* onTop */);
585 alwaysOnTopStack2.setAlwaysOnTop(true);
586 assertTrue(alwaysOnTopStack2.isAlwaysOnTop());
587 // Ensure newly created always on top stack is placed above other all always on top stacks.
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900588 assertEquals(pinnedStack, mDefaultDisplay.getStackAbove(alwaysOnTopStack2));
Kazuki Takisef85197b2018-06-18 18:18:36 +0900589
590 alwaysOnTopStack2.setAlwaysOnTop(false);
591 // Ensure, when always on top is turned off for a stack, the stack is put just below all
592 // other always on top stacks.
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900593 assertEquals(alwaysOnTopStack, mDefaultDisplay.getStackAbove(alwaysOnTopStack2));
Kazuki Takise048e2662018-06-27 17:05:11 +0900594 alwaysOnTopStack2.setAlwaysOnTop(true);
595
596 // Ensure always on top state changes properly when windowing mode changes.
597 alwaysOnTopStack2.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
598 assertFalse(alwaysOnTopStack2.isAlwaysOnTop());
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900599 assertEquals(alwaysOnTopStack, mDefaultDisplay.getStackAbove(alwaysOnTopStack2));
Kazuki Takise048e2662018-06-27 17:05:11 +0900600 alwaysOnTopStack2.setWindowingMode(WINDOWING_MODE_FREEFORM);
601 assertTrue(alwaysOnTopStack2.isAlwaysOnTop());
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900602 assertEquals(pinnedStack, mDefaultDisplay.getStackAbove(alwaysOnTopStack2));
Kazuki Takisef85197b2018-06-18 18:18:36 +0900603 }
604
605 @Test
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900606 public void testSplitScreenMoveToFront() {
Winson Chung3e2980e2018-03-29 17:28:57 -0700607 final TestActivityStack splitScreenPrimary = createStackForShouldBeVisibleTest(
608 mDefaultDisplay, WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD,
609 true /* onTop */);
610 final TestActivityStack splitScreenSecondary = createStackForShouldBeVisibleTest(
611 mDefaultDisplay, WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD,
612 true /* onTop */);
613 final TestActivityStack assistantStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Wale Ogunwalebb285872018-03-01 13:05:30 -0800614 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_ASSISTANT, true /* onTop */);
615
616 splitScreenPrimary.setIsTranslucent(false);
617 splitScreenSecondary.setIsTranslucent(false);
618 assistantStack.setIsTranslucent(false);
619
620 assertFalse(splitScreenPrimary.shouldBeVisible(null /* starting */));
621 assertFalse(splitScreenSecondary.shouldBeVisible(null /* starting */));
622 assertTrue(assistantStack.shouldBeVisible(null /* starting */));
623
624 splitScreenSecondary.moveToFront("testSplitScreenMoveToFront");
625
626 assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */));
627 assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
628 assertFalse(assistantStack.shouldBeVisible(null /* starting */));
629 }
630
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900631 @SuppressWarnings("TypeParameterUnusedInFormals")
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700632 private <T extends ActivityStack> T createStackForShouldBeVisibleTest(
633 ActivityDisplay display, int windowingMode, int activityType, boolean onTop) {
Andrii Kulian6a6c4f12018-07-16 21:23:33 -0700634 final T stack;
635 if (activityType == ACTIVITY_TYPE_HOME) {
636 // Home stack and activity are created in ActivityTestsBase#setupActivityManagerService
637 stack = mDefaultDisplay.getStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME);
638 if (onTop) {
Riddle Hsu57831b52018-07-27 00:31:48 +0800639 mDefaultDisplay.positionChildAtTop(stack, false /* includingParents */);
Andrii Kulian6a6c4f12018-07-16 21:23:33 -0700640 } else {
641 mDefaultDisplay.positionChildAtBottom(stack);
642 }
643 } else {
644 stack = display.createStack(windowingMode, activityType, onTop);
645 final ActivityRecord r = new ActivityBuilder(mService).setUid(0).setStack(stack)
646 .setCreateTask(true).build();
647 }
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700648 return stack;
649 }
Bryce Leeb0f993f2018-03-02 15:38:01 -0800650
651 @Test
Riddle Hsuaaef7312019-01-24 19:00:58 +0800652 public void testFinishDisabledPackageActivities_FinishAliveActivities() {
Bryce Leefbd263b42018-03-07 10:33:55 -0800653 final ActivityRecord firstActivity = new ActivityBuilder(mService).setTask(mTask).build();
654 final ActivityRecord secondActivity = new ActivityBuilder(mService).setTask(mTask).build();
Riddle Hsuaaef7312019-01-24 19:00:58 +0800655 firstActivity.setState(STOPPED, "testFinishDisabledPackageActivities");
656 secondActivity.setState(RESUMED, "testFinishDisabledPackageActivities");
657 mStack.mResumedActivity = secondActivity;
Bryce Leefbd263b42018-03-07 10:33:55 -0800658
Riddle Hsuaaef7312019-01-24 19:00:58 +0800659 // Note the activities have non-null ActivityRecord.app, so it won't remove directly.
660 mStack.finishDisabledPackageActivitiesLocked(firstActivity.packageName,
661 null /* filterByClasses */, true /* doit */, true /* evenPersistent */,
662 UserHandle.USER_ALL);
663
664 // If the activity is disabled with {@link android.content.pm.PackageManager#DONT_KILL_APP}
665 // the activity should still follow the normal flow to finish and destroy.
666 assertThat(firstActivity.getState()).isEqualTo(DESTROYING);
667 assertThat(secondActivity.getState()).isEqualTo(PAUSING);
668 assertTrue(secondActivity.finishing);
669 }
670
671 @Test
672 public void testFinishDisabledPackageActivities_RemoveNonAliveActivities() {
673 final ActivityRecord activity = new ActivityBuilder(mService).setTask(mTask).build();
674
675 // The overlay activity is not in the disabled package but it is in the same task.
676 final ActivityRecord overlayActivity = new ActivityBuilder(mService).setTask(mTask)
677 .setComponent(new ComponentName("package.overlay", ".OverlayActivity")).build();
678 // If the task only remains overlay activity, the task should also be removed.
679 // See {@link ActivityStack#removeActivityFromHistoryLocked}.
680 overlayActivity.mTaskOverlay = true;
681
682 // The activity without an app means it will be removed immediately.
683 // See {@link ActivityStack#destroyActivityLocked}.
684 activity.app = null;
685 overlayActivity.app = null;
Bryce Leefbd263b42018-03-07 10:33:55 -0800686
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900687 assertEquals(2, mTask.mActivities.size());
Bryce Leefbd263b42018-03-07 10:33:55 -0800688
Riddle Hsuaaef7312019-01-24 19:00:58 +0800689 mStack.finishDisabledPackageActivitiesLocked(activity.packageName,
690 null /* filterByClasses */, true /* doit */, true /* evenPersistent */,
691 UserHandle.USER_ALL);
Bryce Leefbd263b42018-03-07 10:33:55 -0800692
Riddle Hsuaaef7312019-01-24 19:00:58 +0800693 // Although the overlay activity is in another package, the non-overlay activities are
694 // removed from the task. Since the overlay activity should be removed as well, the task
695 // should be empty.
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900696 assertThat(mTask.mActivities).isEmpty();
697 assertThat(mStack.getAllTasks()).isEmpty();
Bryce Leefbd263b42018-03-07 10:33:55 -0800698 }
699
700 @Test
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900701 public void testHandleAppDied() {
Bryce Leefbd263b42018-03-07 10:33:55 -0800702 final ActivityRecord firstActivity = new ActivityBuilder(mService).setTask(mTask).build();
703 final ActivityRecord secondActivity = new ActivityBuilder(mService).setTask(mTask).build();
704
705 // Making the first activity a task overlay means it will be removed from the task's
706 // activities as well once second activity is removed as handleAppDied processes the
707 // activity list in reverse.
708 firstActivity.mTaskOverlay = true;
709 firstActivity.app = null;
710
711 // second activity will be immediately removed as it has no state.
712 secondActivity.haveState = false;
713
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900714 assertEquals(2, mTask.mActivities.size());
Bryce Leefbd263b42018-03-07 10:33:55 -0800715
716 mStack.handleAppDiedLocked(secondActivity.app);
717
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900718 assertThat(mTask.mActivities).isEmpty();
719 assertThat(mStack.getAllTasks()).isEmpty();
Bryce Leefbd263b42018-03-07 10:33:55 -0800720 }
Bryce Lee271617a2018-03-15 10:39:12 -0700721
722 @Test
Garfield Tanf6cc5c92019-01-15 13:54:12 -0800723 public void testHandleAppDied_RelaunchesAfterCrashDuringWindowingModeResize() {
724 final ActivityRecord activity = new ActivityBuilder(mService).setTask(mTask).build();
725
726 activity.mRelaunchReason = RELAUNCH_REASON_WINDOWING_MODE_RESIZE;
727 activity.launchCount = 1;
728 activity.haveState = false;
729
730 mStack.handleAppDiedLocked(activity.app);
731
732 assertEquals(1, mTask.mActivities.size());
733 assertEquals(1, mStack.getAllTasks().size());
734 }
735
736 @Test
737 public void testHandleAppDied_NotRelaunchAfterThreeCrashesDuringWindowingModeResize() {
738 final ActivityRecord activity = new ActivityBuilder(mService).setTask(mTask).build();
739
740 activity.mRelaunchReason = RELAUNCH_REASON_WINDOWING_MODE_RESIZE;
741 activity.launchCount = 3;
742 activity.haveState = false;
743
744 mStack.handleAppDiedLocked(activity.app);
745
746 assertThat(mTask.mActivities).isEmpty();
747 assertThat(mStack.getAllTasks()).isEmpty();
748 }
749
750 @Test
751 public void testHandleAppDied_RelaunchesAfterCrashDuringFreeResize() {
752 final ActivityRecord activity = new ActivityBuilder(mService).setTask(mTask).build();
753
754 activity.mRelaunchReason = RELAUNCH_REASON_FREE_RESIZE;
755 activity.launchCount = 1;
756 activity.haveState = false;
757
758 mStack.handleAppDiedLocked(activity.app);
759
760 assertEquals(1, mTask.mActivities.size());
761 assertEquals(1, mStack.getAllTasks().size());
762 }
763
764 @Test
765 public void testHandleAppDied_NotRelaunchAfterThreeCrashesDuringFreeResize() {
766 final ActivityRecord activity = new ActivityBuilder(mService).setTask(mTask).build();
767
768 activity.mRelaunchReason = RELAUNCH_REASON_FREE_RESIZE;
769 activity.launchCount = 3;
770 activity.haveState = false;
771
772 mStack.handleAppDiedLocked(activity.app);
773
774 assertThat(mTask.mActivities).isEmpty();
775 assertThat(mStack.getAllTasks()).isEmpty();
776 }
777
778 @Test
Riddle Hsue10cea52018-10-16 23:33:23 +0800779 public void testFinishCurrentActivity() {
780 // Create 2 activities on a new display.
781 final ActivityDisplay display = addNewActivityDisplayAt(ActivityDisplay.POSITION_TOP);
782 final ActivityStack stack1 = createStackForShouldBeVisibleTest(display,
783 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
784 final ActivityStack stack2 = createStackForShouldBeVisibleTest(display,
785 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
786
787 // There is still an activity1 in stack1 so the activity2 should be added to finishing list
788 // that will be destroyed until idle.
Louis Changf2835df2018-10-17 15:14:45 +0800789 stack2.getTopActivity().visible = true;
Riddle Hsue10cea52018-10-16 23:33:23 +0800790 final ActivityRecord activity2 = finishCurrentActivity(stack2);
Louis Changf2835df2018-10-17 15:14:45 +0800791 assertEquals(STOPPING, activity2.getState());
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900792 assertThat(mSupervisor.mStoppingActivities).contains(activity2);
Riddle Hsue10cea52018-10-16 23:33:23 +0800793
794 // The display becomes empty. Since there is no next activity to be idle, the activity
795 // should be destroyed immediately with updating configuration to restore original state.
796 final ActivityRecord activity1 = finishCurrentActivity(stack1);
797 assertEquals(DESTROYING, activity1.getState());
Wale Ogunwaled32da472018-11-16 07:19:28 -0800798 verify(mRootActivityContainer).ensureVisibilityAndConfig(eq(null) /* starting */,
Riddle Hsue10cea52018-10-16 23:33:23 +0800799 eq(display.mDisplayId), anyBoolean(), anyBoolean());
800 }
801
802 private ActivityRecord finishCurrentActivity(ActivityStack stack) {
803 final ActivityRecord activity = stack.topRunningActivityLocked();
804 assertNotNull(activity);
805 activity.setState(PAUSED, "finishCurrentActivity");
806 activity.makeFinishingLocked();
807 stack.finishCurrentActivityLocked(activity, ActivityStack.FINISH_AFTER_VISIBLE,
808 false /* oomAdj */, "finishCurrentActivity");
809 return activity;
810 }
811
812 @Test
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900813 public void testShouldSleepActivities() {
Bryce Lee271617a2018-03-15 10:39:12 -0700814 // When focused activity and keyguard is going away, we should not sleep regardless
815 // of the display state
816 verifyShouldSleepActivities(true /* focusedStack */, true /*keyguardGoingAway*/,
817 true /* displaySleeping */, false /* expected*/);
818
819 // When not the focused stack, defer to display sleeping state.
820 verifyShouldSleepActivities(false /* focusedStack */, true /*keyguardGoingAway*/,
821 true /* displaySleeping */, true /* expected*/);
822
823 // If keyguard is going away, defer to the display sleeping state.
824 verifyShouldSleepActivities(true /* focusedStack */, false /*keyguardGoingAway*/,
825 true /* displaySleeping */, true /* expected*/);
826 verifyShouldSleepActivities(true /* focusedStack */, false /*keyguardGoingAway*/,
827 false /* displaySleeping */, false /* expected*/);
828 }
829
Winson Chung0f7ec962018-05-03 18:03:15 -0700830 @Test
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900831 public void testStackOrderChangedOnRemoveStack() {
Winson Chung0f7ec962018-05-03 18:03:15 -0700832 StackOrderChangedListener listener = new StackOrderChangedListener();
833 mDefaultDisplay.registerStackOrderChangedListener(listener);
834 try {
835 mDefaultDisplay.removeChild(mStack);
836 } finally {
837 mDefaultDisplay.unregisterStackOrderChangedListener(listener);
838 }
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900839 assertTrue(listener.mChanged);
Winson Chung0f7ec962018-05-03 18:03:15 -0700840 }
841
842 @Test
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900843 public void testStackOrderChangedOnAddPositionStack() {
Winson Chung0f7ec962018-05-03 18:03:15 -0700844 mDefaultDisplay.removeChild(mStack);
845
846 StackOrderChangedListener listener = new StackOrderChangedListener();
847 mDefaultDisplay.registerStackOrderChangedListener(listener);
848 try {
849 mDefaultDisplay.addChild(mStack, 0);
850 } finally {
851 mDefaultDisplay.unregisterStackOrderChangedListener(listener);
852 }
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900853 assertTrue(listener.mChanged);
Winson Chung0f7ec962018-05-03 18:03:15 -0700854 }
855
856 @Test
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900857 public void testStackOrderChangedOnPositionStack() {
Winson Chung0f7ec962018-05-03 18:03:15 -0700858 StackOrderChangedListener listener = new StackOrderChangedListener();
859 try {
860 final TestActivityStack fullscreenStack1 = createStackForShouldBeVisibleTest(
861 mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
862 true /* onTop */);
863 mDefaultDisplay.registerStackOrderChangedListener(listener);
864 mDefaultDisplay.positionChildAtBottom(fullscreenStack1);
865 } finally {
866 mDefaultDisplay.unregisterStackOrderChangedListener(listener);
867 }
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900868 assertTrue(listener.mChanged);
Winson Chung0f7ec962018-05-03 18:03:15 -0700869 }
870
Bryce Lee271617a2018-03-15 10:39:12 -0700871 private void verifyShouldSleepActivities(boolean focusedStack,
872 boolean keyguardGoingAway, boolean displaySleeping, boolean expected) {
Bryce Lee271617a2018-03-15 10:39:12 -0700873 final ActivityDisplay display = mock(ActivityDisplay.class);
874 final KeyguardController keyguardController = mSupervisor.getKeyguardController();
875
Wale Ogunwaled32da472018-11-16 07:19:28 -0800876 doReturn(display).when(mRootActivityContainer).getActivityDisplay(anyInt());
Bryce Lee271617a2018-03-15 10:39:12 -0700877 doReturn(keyguardGoingAway).when(keyguardController).isKeyguardGoingAway();
878 doReturn(displaySleeping).when(display).isSleeping();
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800879 doReturn(focusedStack).when(mStack).isFocusedStackOnDisplay();
Bryce Lee271617a2018-03-15 10:39:12 -0700880
881 assertEquals(expected, mStack.shouldSleepActivities());
882 }
Winson Chung0f7ec962018-05-03 18:03:15 -0700883
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900884 private static class StackOrderChangedListener
885 implements ActivityDisplay.OnStackOrderChangedListener {
886 public boolean mChanged = false;
Winson Chung0f7ec962018-05-03 18:03:15 -0700887
888 @Override
Winson Chung65d66d32018-12-13 17:48:39 -0800889 public void onStackOrderChanged(ActivityStack stack) {
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900890 mChanged = true;
Winson Chung0f7ec962018-05-03 18:03:15 -0700891 }
892 }
Bryce Lee840c5662017-04-13 10:02:51 -0700893}