blob: 1023bc1e3b0c360f6b52d38c9638835801a6416d [file] [log] [blame]
Bryce Lee840c5662017-04-13 10:02:51 -07001/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License
15 */
16
17package com.android.server.am;
18
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;
Bryce Lee18d51592017-10-25 10:22:19 -070027
Bryce Leec4ab62a2018-03-05 14:19:26 -080028import static com.android.server.am.ActivityStack.ActivityState.PAUSING;
29import static com.android.server.am.ActivityStack.ActivityState.RESUMED;
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070030import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_DESTROYING;
Bryce Lee18d51592017-10-25 10:22:19 -070031
Bryce Lee5daa3122017-04-19 10:40:42 -070032import static org.junit.Assert.assertEquals;
David Stevens18abd0e2017-08-17 14:55:47 -070033import static org.junit.Assert.assertFalse;
Bryce Lee840c5662017-04-13 10:02:51 -070034import static org.junit.Assert.assertNotNull;
35import static org.junit.Assert.assertNull;
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -070036import static org.junit.Assert.assertTrue;
Bryce Lee271617a2018-03-15 10:39:12 -070037import static org.mockito.Mockito.anyInt;
38import static org.mockito.Mockito.doReturn;
Bryce Leeb0f993f2018-03-02 15:38:01 -080039import static org.mockito.Mockito.mock;
Bryce Lee840c5662017-04-13 10:02:51 -070040
Bryce Lee3345c4e2017-04-25 07:40:41 -070041import android.content.pm.ActivityInfo;
Bryce Lee9f6affd2017-09-01 09:18:35 -070042import android.os.UserHandle;
Bryce Lee840c5662017-04-13 10:02:51 -070043import android.platform.test.annotations.Presubmit;
Bryce Lee840c5662017-04-13 10:02:51 -070044
Brett Chabota26eda92018-07-23 13:08:30 -070045import androidx.test.filters.SmallTest;
46import androidx.test.runner.AndroidJUnit4;
47
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070048import org.junit.Before;
Bryce Lee840c5662017-04-13 10:02:51 -070049import org.junit.Test;
Brett Chabota26eda92018-07-23 13:08:30 -070050import org.junit.runner.RunWith;
Bryce Lee840c5662017-04-13 10:02:51 -070051
52/**
53 * Tests for the {@link ActivityStack} class.
54 *
55 * Build/Install/Run:
Wale Ogunwalebb285872018-03-01 13:05:30 -080056 * atest FrameworksServicesTests:com.android.server.am.ActivityStackTests
Bryce Lee840c5662017-04-13 10:02:51 -070057 */
58@SmallTest
59@Presubmit
60@RunWith(AndroidJUnit4.class)
61public class ActivityStackTests extends ActivityTestsBase {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -070062 private ActivityTaskManagerService mService;
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070063 private ActivityStackSupervisor mSupervisor;
Winson Chung3e2980e2018-03-29 17:28:57 -070064 private ActivityDisplay mDefaultDisplay;
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070065 private ActivityStack mStack;
66 private TaskRecord mTask;
67
68 @Before
69 @Override
70 public void setUp() throws Exception {
71 super.setUp();
72
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -070073 mService = createActivityTaskManagerService();
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070074 mSupervisor = mService.mStackSupervisor;
Winson Chung3e2980e2018-03-29 17:28:57 -070075 mDefaultDisplay = mService.mStackSupervisor.getDefaultDisplay();
76 mStack = mDefaultDisplay.createStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
77 true /* onTop */);
Bryce Lee18d51592017-10-25 10:22:19 -070078 mTask = new TaskBuilder(mSupervisor).setStack(mStack).build();
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070079 }
80
Bryce Lee840c5662017-04-13 10:02:51 -070081 @Test
82 public void testEmptyTaskCleanupOnRemove() throws Exception {
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070083 assertNotNull(mTask.getWindowContainerController());
84 mStack.removeTask(mTask, "testEmptyTaskCleanupOnRemove", REMOVE_TASK_MODE_DESTROYING);
85 assertNull(mTask.getWindowContainerController());
Bryce Lee840c5662017-04-13 10:02:51 -070086 }
Bryce Lee5daa3122017-04-19 10:40:42 -070087
Bryce Lee840c5662017-04-13 10:02:51 -070088 @Test
89 public void testOccupiedTaskCleanupOnRemove() throws Exception {
Bryce Lee18d51592017-10-25 10:22:19 -070090 final ActivityRecord r = new ActivityBuilder(mService).setTask(mTask).build();
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070091 assertNotNull(mTask.getWindowContainerController());
92 mStack.removeTask(mTask, "testOccupiedTaskCleanupOnRemove", REMOVE_TASK_MODE_DESTROYING);
93 assertNotNull(mTask.getWindowContainerController());
Bryce Lee840c5662017-04-13 10:02:51 -070094 }
Bryce Lee5daa3122017-04-19 10:40:42 -070095
96 @Test
Bryce Leec4ab62a2018-03-05 14:19:26 -080097 public void testResumedActivity() throws Exception {
98 final ActivityRecord r = new ActivityBuilder(mService).setTask(mTask).build();
99 assertEquals(mStack.getResumedActivity(), null);
100 r.setState(RESUMED, "testResumedActivity");
101 assertEquals(mStack.getResumedActivity(), r);
102 r.setState(PAUSING, "testResumedActivity");
103 assertEquals(mStack.getResumedActivity(), null);
Bryce Lee84730a02018-04-03 14:10:04 -0700104 }
Bryce Leec4ab62a2018-03-05 14:19:26 -0800105
Bryce Lee84730a02018-04-03 14:10:04 -0700106 @Test
107 public void testResumedActivityFromTaskReparenting() {
108 final ActivityRecord r = new ActivityBuilder(mService).setTask(mTask).build();
109 // Ensure moving task between two stacks updates resumed activity
110 r.setState(RESUMED, "testResumedActivityFromTaskReparenting");
111 assertEquals(mStack.getResumedActivity(), r);
112
113 final ActivityStack destStack = mService.mStackSupervisor.getDefaultDisplay().createStack(
114 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
115
116 mTask.reparent(destStack, true /* toTop */, TaskRecord.REPARENT_KEEP_STACK_AT_FRONT,
117 false /* animate */, true /* deferResume*/,
118 "testResumedActivityFromTaskReparenting");
119
120 assertEquals(mStack.getResumedActivity(), null);
121 assertEquals(destStack.getResumedActivity(), r);
122 }
123
124 @Test
125 public void testResumedActivityFromActivityReparenting() {
126 final ActivityRecord r = new ActivityBuilder(mService).setTask(mTask).build();
127 // Ensure moving task between two stacks updates resumed activity
128 r.setState(RESUMED, "testResumedActivityFromActivityReparenting");
129 assertEquals(mStack.getResumedActivity(), r);
130
131 final ActivityStack destStack = mService.mStackSupervisor.getDefaultDisplay().createStack(
132 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
133 final TaskRecord destTask = new TaskBuilder(mSupervisor).setStack(destStack).build();
134
135 mTask.removeActivity(r);
136 destTask.addActivityToTop(r);
137
138 assertEquals(mStack.getResumedActivity(), null);
139 assertEquals(destStack.getResumedActivity(), r);
Bryce Lee5daa3122017-04-19 10:40:42 -0700140 }
Bryce Lee3345c4e2017-04-25 07:40:41 -0700141
142 @Test
Bryce Lee8cab4a02018-01-05 09:00:49 -0800143 public void testPrimarySplitScreenToFullscreenWhenMovedToBack() throws Exception {
144 // Create primary splitscreen stack. This will create secondary stacks and places the
145 // existing fullscreen stack on the bottom.
Winson Chung3e2980e2018-03-29 17:28:57 -0700146 final ActivityStack primarySplitScreen = mDefaultDisplay.createStack(
147 WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD, true /* onTop */);
Bryce Lee8cab4a02018-01-05 09:00:49 -0800148
149 // Assert windowing mode.
150 assertEquals(primarySplitScreen.getWindowingMode(), WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
151
152 // Move primary to back.
153 primarySplitScreen.moveToBack("testPrimarySplitScreenToFullscreenWhenMovedToBack",
154 null /* task */);
155
156 // Assert that stack is at the bottom.
Winson Chung3e2980e2018-03-29 17:28:57 -0700157 assertEquals(mDefaultDisplay.getIndexOf(primarySplitScreen), 0);
Bryce Lee8cab4a02018-01-05 09:00:49 -0800158
159 // Ensure no longer in splitscreen.
160 assertEquals(primarySplitScreen.getWindowingMode(), WINDOWING_MODE_FULLSCREEN);
161 }
162
163 @Test
Bryce Lee3345c4e2017-04-25 07:40:41 -0700164 public void testStopActivityWhenActivityDestroyed() throws Exception {
Bryce Lee18d51592017-10-25 10:22:19 -0700165 final ActivityRecord r = new ActivityBuilder(mService).setTask(mTask).build();
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700166 r.info.flags |= ActivityInfo.FLAG_NO_HISTORY;
Andrii Kulian6a6c4f12018-07-16 21:23:33 -0700167 mStack.moveToFront("testStopActivityWithDestroy");
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700168 mStack.stopActivityLocked(r);
169 // Mostly testing to make sure there is a crash in the call part, so if we get here we are
170 // good-to-go!
Bryce Lee3345c4e2017-04-25 07:40:41 -0700171 }
Bryce Lee9f6affd2017-09-01 09:18:35 -0700172
173 @Test
174 public void testFindTaskWithOverlay() throws Exception {
Bryce Lee18d51592017-10-25 10:22:19 -0700175 final ActivityRecord r = new ActivityBuilder(mService)
176 .setCreateTask(true)
177 .setStack(mStack)
178 .setUid(0)
179 .build();
180 final TaskRecord task = r.getTask();
Bryce Lee9f6affd2017-09-01 09:18:35 -0700181 // Overlay must be for a different user to prevent recognizing a matching top activity
Bryce Lee18d51592017-10-25 10:22:19 -0700182 final ActivityRecord taskOverlay = new ActivityBuilder(mService).setTask(task)
183 .setUid(UserHandle.PER_USER_RANGE * 2).build();
Bryce Lee9f6affd2017-09-01 09:18:35 -0700184 taskOverlay.mTaskOverlay = true;
185
Bryce Lee9f6affd2017-09-01 09:18:35 -0700186 final ActivityStackSupervisor.FindTaskResult result =
187 new ActivityStackSupervisor.FindTaskResult();
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700188 mStack.findTaskLocked(r, result);
Bryce Lee9f6affd2017-09-01 09:18:35 -0700189
Bryce Lee18d51592017-10-25 10:22:19 -0700190 assertEquals(task.getTopActivity(false /* includeOverlays */), r);
191 assertEquals(task.getTopActivity(true /* includeOverlays */), taskOverlay);
Louis Changc85b1a32018-08-14 16:40:53 +0800192 assertNotNull(result.mRecord);
Bryce Lee9f6affd2017-09-01 09:18:35 -0700193 }
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700194
195 @Test
196 public void testShouldBeVisible_Fullscreen() throws Exception {
Winson Chung3e2980e2018-03-29 17:28:57 -0700197 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700198 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
Winson Chung3e2980e2018-03-29 17:28:57 -0700199 final ActivityStack pinnedStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700200 WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, true /* onTop */);
201
202 assertTrue(homeStack.shouldBeVisible(null /* starting */));
203 assertTrue(pinnedStack.shouldBeVisible(null /* starting */));
204
Winson Chung3e2980e2018-03-29 17:28:57 -0700205 final TestActivityStack fullscreenStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700206 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
207 // Home stack shouldn't be visible behind an opaque fullscreen stack, but pinned stack
208 // should be visible since it is always on-top.
209 fullscreenStack.setIsTranslucent(false);
210 assertFalse(homeStack.shouldBeVisible(null /* starting */));
211 assertTrue(pinnedStack.shouldBeVisible(null /* starting */));
212 assertTrue(fullscreenStack.shouldBeVisible(null /* starting */));
213
214 // Home stack should be visible behind a translucent fullscreen stack.
215 fullscreenStack.setIsTranslucent(true);
216 assertTrue(homeStack.shouldBeVisible(null /* starting */));
217 assertTrue(pinnedStack.shouldBeVisible(null /* starting */));
218 }
219
220 @Test
221 public void testShouldBeVisible_SplitScreen() throws Exception {
Winson Chung3e2980e2018-03-29 17:28:57 -0700222 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700223 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
Wale Ogunwale30e441d2017-11-09 08:28:45 -0800224 // Home stack should always be fullscreen for this test.
225 homeStack.setSupportsSplitScreen(false);
Winson Chung3e2980e2018-03-29 17:28:57 -0700226 final TestActivityStack splitScreenPrimary = createStackForShouldBeVisibleTest(mDefaultDisplay,
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700227 WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD, true /* onTop */);
Winson Chung3e2980e2018-03-29 17:28:57 -0700228 final TestActivityStack splitScreenSecondary = createStackForShouldBeVisibleTest(mDefaultDisplay,
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700229 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD, true /* onTop */);
230
231 // Home stack shouldn't be visible if both halves of split-screen are opaque.
232 splitScreenPrimary.setIsTranslucent(false);
233 splitScreenSecondary.setIsTranslucent(false);
234 assertFalse(homeStack.shouldBeVisible(null /* starting */));
235 assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */));
236 assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
237
238 // Home stack should be visible if one of the halves of split-screen is translucent.
239 splitScreenPrimary.setIsTranslucent(true);
240 assertTrue(homeStack.shouldBeVisible(null /* starting */));
241 assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */));
242 assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
243
Winson Chung3e2980e2018-03-29 17:28:57 -0700244 final TestActivityStack splitScreenSecondary2 = createStackForShouldBeVisibleTest(mDefaultDisplay,
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700245 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD, true /* onTop */);
246 // First split-screen secondary shouldn't be visible behind another opaque split-split
247 // secondary.
248 splitScreenSecondary2.setIsTranslucent(false);
249 assertFalse(splitScreenSecondary.shouldBeVisible(null /* starting */));
250 assertTrue(splitScreenSecondary2.shouldBeVisible(null /* starting */));
251
Wale Ogunwale8e923af2018-03-23 08:48:11 -0700252 // First split-screen secondary should be visible behind another translucent split-screen
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700253 // secondary.
254 splitScreenSecondary2.setIsTranslucent(true);
255 assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
256 assertTrue(splitScreenSecondary2.shouldBeVisible(null /* starting */));
257
Winson Chung3e2980e2018-03-29 17:28:57 -0700258 final TestActivityStack assistantStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700259 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_ASSISTANT, true /* onTop */);
260
261 // Split-screen stacks shouldn't be visible behind an opaque fullscreen stack.
262 assistantStack.setIsTranslucent(false);
263 assertTrue(assistantStack.shouldBeVisible(null /* starting */));
264 assertFalse(splitScreenPrimary.shouldBeVisible(null /* starting */));
265 assertFalse(splitScreenSecondary.shouldBeVisible(null /* starting */));
266 assertFalse(splitScreenSecondary2.shouldBeVisible(null /* starting */));
267
268 // Split-screen stacks should be visible behind a translucent fullscreen stack.
269 assistantStack.setIsTranslucent(true);
270 assertTrue(assistantStack.shouldBeVisible(null /* starting */));
271 assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */));
272 assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
273 assertTrue(splitScreenSecondary2.shouldBeVisible(null /* starting */));
Wale Ogunwale8e923af2018-03-23 08:48:11 -0700274
275 // Assistant stack shouldn't be visible behind translucent split-screen stack
276 assistantStack.setIsTranslucent(false);
277 splitScreenPrimary.setIsTranslucent(true);
278 splitScreenSecondary2.setIsTranslucent(true);
279 splitScreenSecondary2.moveToFront("testShouldBeVisible_SplitScreen");
280 splitScreenPrimary.moveToFront("testShouldBeVisible_SplitScreen");
281 assertFalse(assistantStack.shouldBeVisible(null /* starting */));
282 assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */));
283 assertTrue(splitScreenSecondary2.shouldBeVisible(null /* starting */));
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700284 }
285
286 @Test
287 public void testShouldBeVisible_Finishing() throws Exception {
Winson Chung3e2980e2018-03-29 17:28:57 -0700288 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700289 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
Winson Chung3e2980e2018-03-29 17:28:57 -0700290 final TestActivityStack translucentStack = createStackForShouldBeVisibleTest(
291 mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
292 true /* onTop */);
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700293 translucentStack.setIsTranslucent(true);
294
295 assertTrue(homeStack.shouldBeVisible(null /* starting */));
296 assertTrue(translucentStack.shouldBeVisible(null /* starting */));
297
298 final ActivityRecord topRunningHomeActivity = homeStack.topRunningActivityLocked();
299 topRunningHomeActivity.finishing = true;
300 final ActivityRecord topRunningTranslucentActivity =
301 translucentStack.topRunningActivityLocked();
302 topRunningTranslucentActivity.finishing = true;
303
304 // Home shouldn't be visible since its activity is marked as finishing and it isn't the top
305 // of the stack list.
306 assertFalse(homeStack.shouldBeVisible(null /* starting */));
307 // Home should be visible if we are starting an activity within it.
308 assertTrue(homeStack.shouldBeVisible(topRunningHomeActivity /* starting */));
309 // The translucent stack should be visible since it is the top of the stack list even though
310 // it has its activity marked as finishing.
311 assertTrue(translucentStack.shouldBeVisible(null /* starting */));
312 }
313
Winson Chungd922b6b2018-02-16 16:41:50 -0800314 @Test
315 public void testMoveHomeStackBehindBottomMostVisibleStack_NoMoveHomeBehindFullscreen() {
Winson Chung3e2980e2018-03-29 17:28:57 -0700316 mDefaultDisplay.removeChild(mStack);
Winson Chungd922b6b2018-02-16 16:41:50 -0800317
Winson Chung3e2980e2018-03-29 17:28:57 -0700318 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Winson Chungd922b6b2018-02-16 16:41:50 -0800319 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
Winson Chung3e2980e2018-03-29 17:28:57 -0700320 final TestActivityStack fullscreenStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Winson Chungd922b6b2018-02-16 16:41:50 -0800321 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
322
323 homeStack.setIsTranslucent(false);
324 fullscreenStack.setIsTranslucent(false);
325
326 // 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 -0700327 int homeStackIndex = mDefaultDisplay.getIndexOf(homeStack);
328 assertTrue(mDefaultDisplay.getStackAbove(homeStack) == fullscreenStack);
329 mDefaultDisplay.moveStackBehindBottomMostVisibleStack(homeStack);
330 assertTrue(mDefaultDisplay.getIndexOf(homeStack) == homeStackIndex);
Winson Chungd922b6b2018-02-16 16:41:50 -0800331 }
332
333 @Test
334 public void testMoveHomeStackBehindBottomMostVisibleStack_NoMoveHomeBehindTranslucent() {
Winson Chung3e2980e2018-03-29 17:28:57 -0700335 mDefaultDisplay.removeChild(mStack);
Winson Chungd922b6b2018-02-16 16:41:50 -0800336
Winson Chung3e2980e2018-03-29 17:28:57 -0700337 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Winson Chungd922b6b2018-02-16 16:41:50 -0800338 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
Winson Chung3e2980e2018-03-29 17:28:57 -0700339 final TestActivityStack fullscreenStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Winson Chungd922b6b2018-02-16 16:41:50 -0800340 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
341
342 homeStack.setIsTranslucent(false);
343 fullscreenStack.setIsTranslucent(true);
344
345 // 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 -0700346 int homeStackIndex = mDefaultDisplay.getIndexOf(homeStack);
347 assertTrue(mDefaultDisplay.getStackAbove(homeStack) == fullscreenStack);
348 mDefaultDisplay.moveStackBehindBottomMostVisibleStack(homeStack);
349 assertTrue(mDefaultDisplay.getIndexOf(homeStack) == homeStackIndex);
Winson Chungd922b6b2018-02-16 16:41:50 -0800350 }
351
352 @Test
353 public void testMoveHomeStackBehindBottomMostVisibleStack_NoMoveHomeOnTop() {
Winson Chung3e2980e2018-03-29 17:28:57 -0700354 mDefaultDisplay.removeChild(mStack);
Winson Chungd922b6b2018-02-16 16:41:50 -0800355
Winson Chung3e2980e2018-03-29 17:28:57 -0700356 final TestActivityStack fullscreenStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Winson Chungd922b6b2018-02-16 16:41:50 -0800357 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
Winson Chung3e2980e2018-03-29 17:28:57 -0700358 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Winson Chungd922b6b2018-02-16 16:41:50 -0800359 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
360
361 homeStack.setIsTranslucent(false);
362 fullscreenStack.setIsTranslucent(false);
363
364 // Ensure we don't move the home stack if it is already on top
Winson Chung3e2980e2018-03-29 17:28:57 -0700365 int homeStackIndex = mDefaultDisplay.getIndexOf(homeStack);
366 assertTrue(mDefaultDisplay.getStackAbove(homeStack) == null);
367 mDefaultDisplay.moveStackBehindBottomMostVisibleStack(homeStack);
368 assertTrue(mDefaultDisplay.getIndexOf(homeStack) == homeStackIndex);
Winson Chungd922b6b2018-02-16 16:41:50 -0800369 }
370
371 @Test
372 public void testMoveHomeStackBehindBottomMostVisibleStack_MoveHomeBehindFullscreen() {
Winson Chung3e2980e2018-03-29 17:28:57 -0700373 mDefaultDisplay.removeChild(mStack);
Winson Chungd922b6b2018-02-16 16:41:50 -0800374
Winson Chung3e2980e2018-03-29 17:28:57 -0700375 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Winson Chungd922b6b2018-02-16 16:41:50 -0800376 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
Winson Chung3e2980e2018-03-29 17:28:57 -0700377 final TestActivityStack fullscreenStack1 = createStackForShouldBeVisibleTest(
378 mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
379 true /* onTop */);
380 final TestActivityStack fullscreenStack2 = createStackForShouldBeVisibleTest(
381 mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
382 true /* onTop */);
383 final TestActivityStack pinnedStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Winson Chungd922b6b2018-02-16 16:41:50 -0800384 WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, true /* onTop */);
385
386 homeStack.setIsTranslucent(false);
387 fullscreenStack1.setIsTranslucent(false);
388 fullscreenStack2.setIsTranslucent(false);
389
390 // Ensure that we move the home stack behind the bottom most fullscreen stack, ignoring the
391 // pinned stack
Winson Chung3e2980e2018-03-29 17:28:57 -0700392 assertTrue(mDefaultDisplay.getStackAbove(homeStack) == fullscreenStack1);
393 mDefaultDisplay.moveStackBehindBottomMostVisibleStack(homeStack);
394 assertTrue(mDefaultDisplay.getStackAbove(homeStack) == fullscreenStack2);
Winson Chungd922b6b2018-02-16 16:41:50 -0800395 }
396
397 @Test
398 public void testMoveHomeStackBehindBottomMostVisibleStack_MoveHomeBehindFullscreenAndTranslucent() {
Winson Chung3e2980e2018-03-29 17:28:57 -0700399 mDefaultDisplay.removeChild(mStack);
Winson Chungd922b6b2018-02-16 16:41:50 -0800400
Winson Chung3e2980e2018-03-29 17:28:57 -0700401 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Winson Chungd922b6b2018-02-16 16:41:50 -0800402 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
Winson Chung3e2980e2018-03-29 17:28:57 -0700403 final TestActivityStack fullscreenStack1 = createStackForShouldBeVisibleTest(
404 mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
405 true /* onTop */);
406 final TestActivityStack fullscreenStack2 = createStackForShouldBeVisibleTest(
407 mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
408 true /* onTop */);
Winson Chungd922b6b2018-02-16 16:41:50 -0800409
410 homeStack.setIsTranslucent(false);
411 fullscreenStack1.setIsTranslucent(false);
412 fullscreenStack2.setIsTranslucent(true);
413
414 // Ensure that we move the home stack behind the bottom most non-translucent fullscreen
415 // stack
Winson Chung3e2980e2018-03-29 17:28:57 -0700416 assertTrue(mDefaultDisplay.getStackAbove(homeStack) == fullscreenStack1);
417 mDefaultDisplay.moveStackBehindBottomMostVisibleStack(homeStack);
418 assertTrue(mDefaultDisplay.getStackAbove(homeStack) == fullscreenStack1);
Winson Chungd922b6b2018-02-16 16:41:50 -0800419 }
420
421 @Test
422 public void testMoveHomeStackBehindStack_BehindHomeStack() {
Winson Chung3e2980e2018-03-29 17:28:57 -0700423 mDefaultDisplay.removeChild(mStack);
Winson Chungd922b6b2018-02-16 16:41:50 -0800424
Winson Chung3e2980e2018-03-29 17:28:57 -0700425 final TestActivityStack fullscreenStack1 = createStackForShouldBeVisibleTest(
426 mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
427 true /* onTop */);
428 final TestActivityStack fullscreenStack2 = createStackForShouldBeVisibleTest(
429 mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
430 true /* onTop */);
431 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Winson Chungd922b6b2018-02-16 16:41:50 -0800432 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
433
434 homeStack.setIsTranslucent(false);
435 fullscreenStack1.setIsTranslucent(false);
436 fullscreenStack2.setIsTranslucent(false);
437
438 // Ensure we don't move the home stack behind itself
Winson Chung3e2980e2018-03-29 17:28:57 -0700439 int homeStackIndex = mDefaultDisplay.getIndexOf(homeStack);
440 mDefaultDisplay.moveStackBehindStack(homeStack, homeStack);
441 assertTrue(mDefaultDisplay.getIndexOf(homeStack) == homeStackIndex);
Winson Chungd922b6b2018-02-16 16:41:50 -0800442 }
443
444 @Test
445 public void testMoveHomeStackBehindStack() {
Winson Chung3e2980e2018-03-29 17:28:57 -0700446 mDefaultDisplay.removeChild(mStack);
Winson Chungd922b6b2018-02-16 16:41:50 -0800447
Winson Chung3e2980e2018-03-29 17:28:57 -0700448 final TestActivityStack fullscreenStack1 = createStackForShouldBeVisibleTest(
449 mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
450 true /* onTop */);
451 final TestActivityStack fullscreenStack2 = createStackForShouldBeVisibleTest(
452 mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
453 true /* onTop */);
454 final TestActivityStack fullscreenStack3 = createStackForShouldBeVisibleTest(
455 mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
456 true /* onTop */);
457 final TestActivityStack fullscreenStack4 = createStackForShouldBeVisibleTest(
458 mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
459 true /* onTop */);
460 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Winson Chungd922b6b2018-02-16 16:41:50 -0800461 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
462
Winson Chung3e2980e2018-03-29 17:28:57 -0700463 mDefaultDisplay.moveStackBehindStack(homeStack, fullscreenStack1);
464 assertTrue(mDefaultDisplay.getStackAbove(homeStack) == fullscreenStack1);
465 mDefaultDisplay.moveStackBehindStack(homeStack, fullscreenStack2);
466 assertTrue(mDefaultDisplay.getStackAbove(homeStack) == fullscreenStack2);
467 mDefaultDisplay.moveStackBehindStack(homeStack, fullscreenStack4);
468 assertTrue(mDefaultDisplay.getStackAbove(homeStack) == fullscreenStack4);
469 mDefaultDisplay.moveStackBehindStack(homeStack, fullscreenStack2);
470 assertTrue(mDefaultDisplay.getStackAbove(homeStack) == fullscreenStack2);
Winson Chungd922b6b2018-02-16 16:41:50 -0800471 }
472
Wale Ogunwalebb285872018-03-01 13:05:30 -0800473 @Test
Kazuki Takisef85197b2018-06-18 18:18:36 +0900474 public void testSetAlwaysOnTop() {
475 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
476 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
477 final ActivityStack pinnedStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
478 WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, true /* onTop */);
479 assertTrue(mDefaultDisplay.getStackAbove(homeStack) == pinnedStack);
480
481 final TestActivityStack alwaysOnTopStack = createStackForShouldBeVisibleTest(
482 mDefaultDisplay, WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD,
483 true /* onTop */);
484 alwaysOnTopStack.setAlwaysOnTop(true);
485 assertTrue(alwaysOnTopStack.isAlwaysOnTop());
486 // Ensure (non-pinned) always on top stack is put below pinned stack.
487 assertTrue(mDefaultDisplay.getStackAbove(alwaysOnTopStack) == pinnedStack);
488
489 final TestActivityStack nonAlwaysOnTopStack = createStackForShouldBeVisibleTest(
490 mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
491 true /* onTop */);
492 // Ensure non always on top stack is put below always on top stacks.
493 assertTrue(mDefaultDisplay.getStackAbove(nonAlwaysOnTopStack) == alwaysOnTopStack);
494
495 final TestActivityStack alwaysOnTopStack2 = createStackForShouldBeVisibleTest(
496 mDefaultDisplay, WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD,
497 true /* onTop */);
498 alwaysOnTopStack2.setAlwaysOnTop(true);
499 assertTrue(alwaysOnTopStack2.isAlwaysOnTop());
500 // Ensure newly created always on top stack is placed above other all always on top stacks.
501 assertTrue(mDefaultDisplay.getStackAbove(alwaysOnTopStack2) == pinnedStack);
502
503 alwaysOnTopStack2.setAlwaysOnTop(false);
504 // Ensure, when always on top is turned off for a stack, the stack is put just below all
505 // other always on top stacks.
506 assertTrue(mDefaultDisplay.getStackAbove(alwaysOnTopStack2) == alwaysOnTopStack);
Kazuki Takise048e2662018-06-27 17:05:11 +0900507 alwaysOnTopStack2.setAlwaysOnTop(true);
508
509 // Ensure always on top state changes properly when windowing mode changes.
510 alwaysOnTopStack2.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
511 assertFalse(alwaysOnTopStack2.isAlwaysOnTop());
512 assertTrue(mDefaultDisplay.getStackAbove(alwaysOnTopStack2) == alwaysOnTopStack);
513 alwaysOnTopStack2.setWindowingMode(WINDOWING_MODE_FREEFORM);
514 assertTrue(alwaysOnTopStack2.isAlwaysOnTop());
515 assertTrue(mDefaultDisplay.getStackAbove(alwaysOnTopStack2) == pinnedStack);
Kazuki Takisef85197b2018-06-18 18:18:36 +0900516 }
517
518 @Test
Wale Ogunwalebb285872018-03-01 13:05:30 -0800519 public void testSplitScreenMoveToFront() throws Exception {
Winson Chung3e2980e2018-03-29 17:28:57 -0700520 final TestActivityStack splitScreenPrimary = createStackForShouldBeVisibleTest(
521 mDefaultDisplay, WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD,
522 true /* onTop */);
523 final TestActivityStack splitScreenSecondary = createStackForShouldBeVisibleTest(
524 mDefaultDisplay, WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD,
525 true /* onTop */);
526 final TestActivityStack assistantStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Wale Ogunwalebb285872018-03-01 13:05:30 -0800527 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_ASSISTANT, true /* onTop */);
528
529 splitScreenPrimary.setIsTranslucent(false);
530 splitScreenSecondary.setIsTranslucent(false);
531 assistantStack.setIsTranslucent(false);
532
533 assertFalse(splitScreenPrimary.shouldBeVisible(null /* starting */));
534 assertFalse(splitScreenSecondary.shouldBeVisible(null /* starting */));
535 assertTrue(assistantStack.shouldBeVisible(null /* starting */));
536
537 splitScreenSecondary.moveToFront("testSplitScreenMoveToFront");
538
539 assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */));
540 assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
541 assertFalse(assistantStack.shouldBeVisible(null /* starting */));
542 }
543
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700544 private <T extends ActivityStack> T createStackForShouldBeVisibleTest(
545 ActivityDisplay display, int windowingMode, int activityType, boolean onTop) {
Andrii Kulian6a6c4f12018-07-16 21:23:33 -0700546 final T stack;
547 if (activityType == ACTIVITY_TYPE_HOME) {
548 // Home stack and activity are created in ActivityTestsBase#setupActivityManagerService
549 stack = mDefaultDisplay.getStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME);
550 if (onTop) {
Riddle Hsu57831b52018-07-27 00:31:48 +0800551 mDefaultDisplay.positionChildAtTop(stack, false /* includingParents */);
Andrii Kulian6a6c4f12018-07-16 21:23:33 -0700552 } else {
553 mDefaultDisplay.positionChildAtBottom(stack);
554 }
555 } else {
556 stack = display.createStack(windowingMode, activityType, onTop);
557 final ActivityRecord r = new ActivityBuilder(mService).setUid(0).setStack(stack)
558 .setCreateTask(true).build();
559 }
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700560 return stack;
561 }
Bryce Leeb0f993f2018-03-02 15:38:01 -0800562
563 @Test
Bryce Leefbd263b42018-03-07 10:33:55 -0800564 public void testFinishDisabledPackageActivities() throws Exception {
565 final ActivityRecord firstActivity = new ActivityBuilder(mService).setTask(mTask).build();
566 final ActivityRecord secondActivity = new ActivityBuilder(mService).setTask(mTask).build();
567
568 // Making the second activity a task overlay without an app means it will be removed from
569 // the task's activities as well once first activity is removed.
570 secondActivity.mTaskOverlay = true;
571 secondActivity.app = null;
572
573 assertEquals(mTask.mActivities.size(), 2);
574
575 mStack.finishDisabledPackageActivitiesLocked(firstActivity.packageName, null,
576 true /* doit */, true /* evenPersistent */, UserHandle.USER_ALL);
577
578 assertTrue(mTask.mActivities.isEmpty());
579 assertTrue(mStack.getAllTasks().isEmpty());
580 }
581
582 @Test
583 public void testHandleAppDied() throws Exception {
584 final ActivityRecord firstActivity = new ActivityBuilder(mService).setTask(mTask).build();
585 final ActivityRecord secondActivity = new ActivityBuilder(mService).setTask(mTask).build();
586
587 // Making the first activity a task overlay means it will be removed from the task's
588 // activities as well once second activity is removed as handleAppDied processes the
589 // activity list in reverse.
590 firstActivity.mTaskOverlay = true;
591 firstActivity.app = null;
592
593 // second activity will be immediately removed as it has no state.
594 secondActivity.haveState = false;
595
596 assertEquals(mTask.mActivities.size(), 2);
597
598 mStack.handleAppDiedLocked(secondActivity.app);
599
600 assertTrue(mTask.mActivities.isEmpty());
601 assertTrue(mStack.getAllTasks().isEmpty());
602 }
Bryce Lee271617a2018-03-15 10:39:12 -0700603
604 @Test
605 public void testShouldSleepActivities() throws Exception {
606 // When focused activity and keyguard is going away, we should not sleep regardless
607 // of the display state
608 verifyShouldSleepActivities(true /* focusedStack */, true /*keyguardGoingAway*/,
609 true /* displaySleeping */, false /* expected*/);
610
611 // When not the focused stack, defer to display sleeping state.
612 verifyShouldSleepActivities(false /* focusedStack */, true /*keyguardGoingAway*/,
613 true /* displaySleeping */, true /* expected*/);
614
615 // If keyguard is going away, defer to the display sleeping state.
616 verifyShouldSleepActivities(true /* focusedStack */, false /*keyguardGoingAway*/,
617 true /* displaySleeping */, true /* expected*/);
618 verifyShouldSleepActivities(true /* focusedStack */, false /*keyguardGoingAway*/,
619 false /* displaySleeping */, false /* expected*/);
620 }
621
Winson Chung0f7ec962018-05-03 18:03:15 -0700622 @Test
623 public void testStackOrderChangedOnRemoveStack() throws Exception {
624 StackOrderChangedListener listener = new StackOrderChangedListener();
625 mDefaultDisplay.registerStackOrderChangedListener(listener);
626 try {
627 mDefaultDisplay.removeChild(mStack);
628 } finally {
629 mDefaultDisplay.unregisterStackOrderChangedListener(listener);
630 }
631 assertTrue(listener.changed);
632 }
633
634 @Test
635 public void testStackOrderChangedOnAddPositionStack() throws Exception {
636 mDefaultDisplay.removeChild(mStack);
637
638 StackOrderChangedListener listener = new StackOrderChangedListener();
639 mDefaultDisplay.registerStackOrderChangedListener(listener);
640 try {
641 mDefaultDisplay.addChild(mStack, 0);
642 } finally {
643 mDefaultDisplay.unregisterStackOrderChangedListener(listener);
644 }
645 assertTrue(listener.changed);
646 }
647
648 @Test
649 public void testStackOrderChangedOnPositionStack() throws Exception {
650 StackOrderChangedListener listener = new StackOrderChangedListener();
651 try {
652 final TestActivityStack fullscreenStack1 = createStackForShouldBeVisibleTest(
653 mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
654 true /* onTop */);
655 mDefaultDisplay.registerStackOrderChangedListener(listener);
656 mDefaultDisplay.positionChildAtBottom(fullscreenStack1);
657 } finally {
658 mDefaultDisplay.unregisterStackOrderChangedListener(listener);
659 }
660 assertTrue(listener.changed);
661 }
662
Bryce Lee271617a2018-03-15 10:39:12 -0700663 private void verifyShouldSleepActivities(boolean focusedStack,
664 boolean keyguardGoingAway, boolean displaySleeping, boolean expected) {
Bryce Lee271617a2018-03-15 10:39:12 -0700665 final ActivityDisplay display = mock(ActivityDisplay.class);
666 final KeyguardController keyguardController = mSupervisor.getKeyguardController();
667
668 doReturn(display).when(mSupervisor).getActivityDisplay(anyInt());
669 doReturn(keyguardGoingAway).when(keyguardController).isKeyguardGoingAway();
670 doReturn(displaySleeping).when(display).isSleeping();
Andrii Kulian6a6c4f12018-07-16 21:23:33 -0700671 doReturn(focusedStack ? mStack : null).when(mSupervisor).getTopDisplayFocusedStack();
Bryce Lee271617a2018-03-15 10:39:12 -0700672
673 assertEquals(expected, mStack.shouldSleepActivities());
674 }
Winson Chung0f7ec962018-05-03 18:03:15 -0700675
676 private class StackOrderChangedListener implements ActivityDisplay.OnStackOrderChangedListener {
677 boolean changed = false;
678
679 @Override
680 public void onStackOrderChanged() {
681 changed = true;
682 }
683 }
Bryce Lee840c5662017-04-13 10:02:51 -0700684}