blob: 4fa759f550d05f63f82f89126782bac9499434dd [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;
Evan Rosky10475742018-09-05 19:02:48 -070027import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
Bryce Lee18d51592017-10-25 10:22:19 -070028
Riddle Hsue10cea52018-10-16 23:33:23 +080029import static com.android.server.am.ActivityStack.ActivityState.DESTROYING;
30import static com.android.server.am.ActivityStack.ActivityState.FINISHING;
31import static com.android.server.am.ActivityStack.ActivityState.PAUSED;
Bryce Leec4ab62a2018-03-05 14:19:26 -080032import static com.android.server.am.ActivityStack.ActivityState.PAUSING;
33import static com.android.server.am.ActivityStack.ActivityState.RESUMED;
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070034import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_DESTROYING;
Bryce Lee18d51592017-10-25 10:22:19 -070035
Bryce Lee5daa3122017-04-19 10:40:42 -070036import static org.junit.Assert.assertEquals;
David Stevens18abd0e2017-08-17 14:55:47 -070037import static org.junit.Assert.assertFalse;
Bryce Lee840c5662017-04-13 10:02:51 -070038import static org.junit.Assert.assertNotNull;
39import static org.junit.Assert.assertNull;
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -070040import static org.junit.Assert.assertTrue;
Riddle Hsu138ef932018-10-26 17:12:06 +080041import static org.mockito.ArgumentMatchers.any;
Riddle Hsue10cea52018-10-16 23:33:23 +080042import static org.mockito.ArgumentMatchers.anyBoolean;
43import static org.mockito.ArgumentMatchers.anyInt;
Riddle Hsue10cea52018-10-16 23:33:23 +080044import static org.mockito.ArgumentMatchers.eq;
Bryce Lee271617a2018-03-15 10:39:12 -070045import static org.mockito.Mockito.doReturn;
Bryce Leeb0f993f2018-03-02 15:38:01 -080046import static org.mockito.Mockito.mock;
Tiger Huang1e5b10a2018-07-30 20:19:51 +080047import static org.mockito.Mockito.spy;
Riddle Hsue10cea52018-10-16 23:33:23 +080048import static org.mockito.Mockito.verify;
Bryce Lee840c5662017-04-13 10:02:51 -070049
Bryce Lee3345c4e2017-04-25 07:40:41 -070050import android.content.pm.ActivityInfo;
Bryce Lee9f6affd2017-09-01 09:18:35 -070051import android.os.UserHandle;
Bryce Lee840c5662017-04-13 10:02:51 -070052import android.platform.test.annotations.Presubmit;
Bryce Lee840c5662017-04-13 10:02:51 -070053
Brett Chabota26eda92018-07-23 13:08:30 -070054import androidx.test.filters.SmallTest;
55import androidx.test.runner.AndroidJUnit4;
56
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070057import org.junit.Before;
Bryce Lee840c5662017-04-13 10:02:51 -070058import org.junit.Test;
Brett Chabota26eda92018-07-23 13:08:30 -070059import org.junit.runner.RunWith;
Bryce Lee840c5662017-04-13 10:02:51 -070060
61/**
62 * Tests for the {@link ActivityStack} class.
63 *
64 * Build/Install/Run:
John Reck3d294e72018-09-21 20:26:48 +000065 * atest FrameworksServicesTests:com.android.server.am.ActivityStackTests
Bryce Lee840c5662017-04-13 10:02:51 -070066 */
67@SmallTest
68@Presubmit
69@RunWith(AndroidJUnit4.class)
70public class ActivityStackTests extends ActivityTestsBase {
Winson Chung3e2980e2018-03-29 17:28:57 -070071 private ActivityDisplay mDefaultDisplay;
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070072 private ActivityStack mStack;
73 private TaskRecord mTask;
74
75 @Before
76 @Override
77 public void setUp() throws Exception {
78 super.setUp();
79
Riddle Hsub70b36d2018-09-11 21:20:02 +080080 setupActivityTaskManagerService();
81 mDefaultDisplay = mSupervisor.getDefaultDisplay();
Tiger Huang1e5b10a2018-07-30 20:19:51 +080082 mStack = spy(mDefaultDisplay.createStack(WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD,
83 true /* onTop */));
Bryce Lee18d51592017-10-25 10:22:19 -070084 mTask = new TaskBuilder(mSupervisor).setStack(mStack).build();
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070085 }
86
Bryce Lee840c5662017-04-13 10:02:51 -070087 @Test
88 public void testEmptyTaskCleanupOnRemove() throws Exception {
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070089 assertNotNull(mTask.getWindowContainerController());
90 mStack.removeTask(mTask, "testEmptyTaskCleanupOnRemove", REMOVE_TASK_MODE_DESTROYING);
91 assertNull(mTask.getWindowContainerController());
Bryce Lee840c5662017-04-13 10:02:51 -070092 }
Bryce Lee5daa3122017-04-19 10:40:42 -070093
Bryce Lee840c5662017-04-13 10:02:51 -070094 @Test
95 public void testOccupiedTaskCleanupOnRemove() throws Exception {
Bryce Lee18d51592017-10-25 10:22:19 -070096 final ActivityRecord r = new ActivityBuilder(mService).setTask(mTask).build();
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070097 assertNotNull(mTask.getWindowContainerController());
98 mStack.removeTask(mTask, "testOccupiedTaskCleanupOnRemove", REMOVE_TASK_MODE_DESTROYING);
99 assertNotNull(mTask.getWindowContainerController());
Bryce Lee840c5662017-04-13 10:02:51 -0700100 }
Bryce Lee5daa3122017-04-19 10:40:42 -0700101
102 @Test
Bryce Leec4ab62a2018-03-05 14:19:26 -0800103 public void testResumedActivity() throws Exception {
104 final ActivityRecord r = new ActivityBuilder(mService).setTask(mTask).build();
105 assertEquals(mStack.getResumedActivity(), null);
106 r.setState(RESUMED, "testResumedActivity");
107 assertEquals(mStack.getResumedActivity(), r);
108 r.setState(PAUSING, "testResumedActivity");
109 assertEquals(mStack.getResumedActivity(), null);
Bryce Lee84730a02018-04-03 14:10:04 -0700110 }
Bryce Leec4ab62a2018-03-05 14:19:26 -0800111
Bryce Lee84730a02018-04-03 14:10:04 -0700112 @Test
113 public void testResumedActivityFromTaskReparenting() {
114 final ActivityRecord r = new ActivityBuilder(mService).setTask(mTask).build();
115 // Ensure moving task between two stacks updates resumed activity
116 r.setState(RESUMED, "testResumedActivityFromTaskReparenting");
117 assertEquals(mStack.getResumedActivity(), r);
118
119 final ActivityStack destStack = mService.mStackSupervisor.getDefaultDisplay().createStack(
120 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
121
122 mTask.reparent(destStack, true /* toTop */, TaskRecord.REPARENT_KEEP_STACK_AT_FRONT,
123 false /* animate */, true /* deferResume*/,
124 "testResumedActivityFromTaskReparenting");
125
126 assertEquals(mStack.getResumedActivity(), null);
127 assertEquals(destStack.getResumedActivity(), r);
128 }
129
130 @Test
131 public void testResumedActivityFromActivityReparenting() {
132 final ActivityRecord r = new ActivityBuilder(mService).setTask(mTask).build();
133 // Ensure moving task between two stacks updates resumed activity
134 r.setState(RESUMED, "testResumedActivityFromActivityReparenting");
135 assertEquals(mStack.getResumedActivity(), r);
136
137 final ActivityStack destStack = mService.mStackSupervisor.getDefaultDisplay().createStack(
138 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
139 final TaskRecord destTask = new TaskBuilder(mSupervisor).setStack(destStack).build();
140
141 mTask.removeActivity(r);
142 destTask.addActivityToTop(r);
143
144 assertEquals(mStack.getResumedActivity(), null);
145 assertEquals(destStack.getResumedActivity(), r);
Bryce Lee5daa3122017-04-19 10:40:42 -0700146 }
Bryce Lee3345c4e2017-04-25 07:40:41 -0700147
148 @Test
Evan Rosky10475742018-09-05 19:02:48 -0700149 public void testPrimarySplitScreenRestoresWhenMovedToBack() throws Exception {
Bryce Lee8cab4a02018-01-05 09:00:49 -0800150 // Create primary splitscreen stack. This will create secondary stacks and places the
151 // existing fullscreen stack on the bottom.
Winson Chung3e2980e2018-03-29 17:28:57 -0700152 final ActivityStack primarySplitScreen = mDefaultDisplay.createStack(
153 WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD, true /* onTop */);
Bryce Lee8cab4a02018-01-05 09:00:49 -0800154
155 // Assert windowing mode.
156 assertEquals(primarySplitScreen.getWindowingMode(), WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
157
158 // Move primary to back.
159 primarySplitScreen.moveToBack("testPrimarySplitScreenToFullscreenWhenMovedToBack",
160 null /* task */);
161
162 // Assert that stack is at the bottom.
Winson Chung3e2980e2018-03-29 17:28:57 -0700163 assertEquals(mDefaultDisplay.getIndexOf(primarySplitScreen), 0);
Bryce Lee8cab4a02018-01-05 09:00:49 -0800164
165 // Ensure no longer in splitscreen.
166 assertEquals(primarySplitScreen.getWindowingMode(), WINDOWING_MODE_FULLSCREEN);
Evan Rosky10475742018-09-05 19:02:48 -0700167
168 // Ensure that the override mode is restored to undefined
169 assertEquals(primarySplitScreen.getOverrideWindowingMode(), WINDOWING_MODE_UNDEFINED);
170 }
171
172 @Test
173 public void testPrimarySplitScreenRestoresPreviousWhenMovedToBack() throws Exception {
174 // This time, start with a fullscreen activitystack
175 final ActivityStack primarySplitScreen = mDefaultDisplay.createStack(
176 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
177
178 primarySplitScreen.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
179
180 // Assert windowing mode.
181 assertEquals(primarySplitScreen.getWindowingMode(), WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
182
183 // Move primary to back.
184 primarySplitScreen.moveToBack("testPrimarySplitScreenToFullscreenWhenMovedToBack",
185 null /* task */);
186
187 // Assert that stack is at the bottom.
188 assertEquals(mDefaultDisplay.getIndexOf(primarySplitScreen), 0);
189
190 // Ensure that the override mode is restored to what it was (fullscreen)
191 assertEquals(primarySplitScreen.getOverrideWindowingMode(), WINDOWING_MODE_FULLSCREEN);
192 }
193
194 @Test
195 public void testStackInheritsDisplayWindowingMode() throws Exception {
196 final ActivityStack primarySplitScreen = mDefaultDisplay.createStack(
197 WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD, true /* onTop */);
198
199 assertEquals(WINDOWING_MODE_FULLSCREEN, primarySplitScreen.getWindowingMode());
200 assertEquals(WINDOWING_MODE_UNDEFINED, primarySplitScreen.getOverrideWindowingMode());
201
202 mDefaultDisplay.setWindowingMode(WINDOWING_MODE_FREEFORM);
203 assertEquals(WINDOWING_MODE_FREEFORM, primarySplitScreen.getWindowingMode());
204 assertEquals(WINDOWING_MODE_UNDEFINED, primarySplitScreen.getOverrideWindowingMode());
205 }
206
207 @Test
208 public void testStackOverridesDisplayWindowingMode() throws Exception {
209 final ActivityStack primarySplitScreen = mDefaultDisplay.createStack(
210 WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD, true /* onTop */);
211
212 assertEquals(WINDOWING_MODE_FULLSCREEN, primarySplitScreen.getWindowingMode());
213 assertEquals(WINDOWING_MODE_UNDEFINED, primarySplitScreen.getOverrideWindowingMode());
214
215 primarySplitScreen.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
216 // setting windowing mode should still work even though resolved mode is already fullscreen
217 assertEquals(WINDOWING_MODE_FULLSCREEN, primarySplitScreen.getOverrideWindowingMode());
218
219 mDefaultDisplay.setWindowingMode(WINDOWING_MODE_FREEFORM);
220 assertEquals(WINDOWING_MODE_FULLSCREEN, primarySplitScreen.getWindowingMode());
Bryce Lee8cab4a02018-01-05 09:00:49 -0800221 }
222
223 @Test
Bryce Lee3345c4e2017-04-25 07:40:41 -0700224 public void testStopActivityWhenActivityDestroyed() throws Exception {
Bryce Lee18d51592017-10-25 10:22:19 -0700225 final ActivityRecord r = new ActivityBuilder(mService).setTask(mTask).build();
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700226 r.info.flags |= ActivityInfo.FLAG_NO_HISTORY;
Andrii Kulian6a6c4f12018-07-16 21:23:33 -0700227 mStack.moveToFront("testStopActivityWithDestroy");
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700228 mStack.stopActivityLocked(r);
229 // Mostly testing to make sure there is a crash in the call part, so if we get here we are
230 // good-to-go!
Bryce Lee3345c4e2017-04-25 07:40:41 -0700231 }
Bryce Lee9f6affd2017-09-01 09:18:35 -0700232
233 @Test
234 public void testFindTaskWithOverlay() throws Exception {
Bryce Lee18d51592017-10-25 10:22:19 -0700235 final ActivityRecord r = new ActivityBuilder(mService)
236 .setCreateTask(true)
237 .setStack(mStack)
238 .setUid(0)
239 .build();
240 final TaskRecord task = r.getTask();
Bryce Lee9f6affd2017-09-01 09:18:35 -0700241 // Overlay must be for a different user to prevent recognizing a matching top activity
Bryce Lee18d51592017-10-25 10:22:19 -0700242 final ActivityRecord taskOverlay = new ActivityBuilder(mService).setTask(task)
243 .setUid(UserHandle.PER_USER_RANGE * 2).build();
Bryce Lee9f6affd2017-09-01 09:18:35 -0700244 taskOverlay.mTaskOverlay = true;
245
Bryce Lee9f6affd2017-09-01 09:18:35 -0700246 final ActivityStackSupervisor.FindTaskResult result =
247 new ActivityStackSupervisor.FindTaskResult();
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700248 mStack.findTaskLocked(r, result);
Bryce Lee9f6affd2017-09-01 09:18:35 -0700249
Bryce Lee18d51592017-10-25 10:22:19 -0700250 assertEquals(task.getTopActivity(false /* includeOverlays */), r);
251 assertEquals(task.getTopActivity(true /* includeOverlays */), taskOverlay);
Louis Changc85b1a32018-08-14 16:40:53 +0800252 assertNotNull(result.mRecord);
Bryce Lee9f6affd2017-09-01 09:18:35 -0700253 }
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700254
255 @Test
Riddle Hsu138ef932018-10-26 17:12:06 +0800256 public void testMoveStackToBackIncludingParent() {
257 final ActivityDisplay display = addNewActivityDisplayAt(ActivityDisplay.POSITION_TOP);
258 final ActivityStack stack1 = createStackForShouldBeVisibleTest(display,
259 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
260 final ActivityStack stack2 = createStackForShouldBeVisibleTest(display,
261 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
262
263 // Do not move display to back because there is still another stack.
264 stack2.moveToBack("testMoveStackToBackIncludingParent", stack2.topTask());
265 verify(stack2.getWindowContainerController()).positionChildAtBottom(any(),
266 eq(false) /* includingParents */);
267
268 // Also move display to back because there is only one stack left.
269 display.removeChild(stack1);
270 stack2.moveToBack("testMoveStackToBackIncludingParent", stack2.topTask());
271 verify(stack2.getWindowContainerController()).positionChildAtBottom(any(),
272 eq(true) /* includingParents */);
273 }
274
275 @Test
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700276 public void testShouldBeVisible_Fullscreen() throws Exception {
Winson Chung3e2980e2018-03-29 17:28:57 -0700277 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700278 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
Winson Chung3e2980e2018-03-29 17:28:57 -0700279 final ActivityStack pinnedStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700280 WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, true /* onTop */);
281
282 assertTrue(homeStack.shouldBeVisible(null /* starting */));
283 assertTrue(pinnedStack.shouldBeVisible(null /* starting */));
284
Winson Chung3e2980e2018-03-29 17:28:57 -0700285 final TestActivityStack fullscreenStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700286 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
287 // Home stack shouldn't be visible behind an opaque fullscreen stack, but pinned stack
288 // should be visible since it is always on-top.
289 fullscreenStack.setIsTranslucent(false);
290 assertFalse(homeStack.shouldBeVisible(null /* starting */));
291 assertTrue(pinnedStack.shouldBeVisible(null /* starting */));
292 assertTrue(fullscreenStack.shouldBeVisible(null /* starting */));
293
294 // Home stack should be visible behind a translucent fullscreen stack.
295 fullscreenStack.setIsTranslucent(true);
296 assertTrue(homeStack.shouldBeVisible(null /* starting */));
297 assertTrue(pinnedStack.shouldBeVisible(null /* starting */));
298 }
299
300 @Test
301 public void testShouldBeVisible_SplitScreen() throws Exception {
Winson Chung3e2980e2018-03-29 17:28:57 -0700302 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700303 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
Wale Ogunwale30e441d2017-11-09 08:28:45 -0800304 // Home stack should always be fullscreen for this test.
305 homeStack.setSupportsSplitScreen(false);
Winson Chung3e2980e2018-03-29 17:28:57 -0700306 final TestActivityStack splitScreenPrimary = createStackForShouldBeVisibleTest(mDefaultDisplay,
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700307 WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD, true /* onTop */);
Winson Chung3e2980e2018-03-29 17:28:57 -0700308 final TestActivityStack splitScreenSecondary = createStackForShouldBeVisibleTest(mDefaultDisplay,
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700309 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD, true /* onTop */);
310
311 // Home stack shouldn't be visible if both halves of split-screen are opaque.
312 splitScreenPrimary.setIsTranslucent(false);
313 splitScreenSecondary.setIsTranslucent(false);
314 assertFalse(homeStack.shouldBeVisible(null /* starting */));
315 assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */));
316 assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
317
318 // Home stack should be visible if one of the halves of split-screen is translucent.
319 splitScreenPrimary.setIsTranslucent(true);
320 assertTrue(homeStack.shouldBeVisible(null /* starting */));
321 assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */));
322 assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
323
Winson Chung3e2980e2018-03-29 17:28:57 -0700324 final TestActivityStack splitScreenSecondary2 = createStackForShouldBeVisibleTest(mDefaultDisplay,
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700325 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD, true /* onTop */);
326 // First split-screen secondary shouldn't be visible behind another opaque split-split
327 // secondary.
328 splitScreenSecondary2.setIsTranslucent(false);
329 assertFalse(splitScreenSecondary.shouldBeVisible(null /* starting */));
330 assertTrue(splitScreenSecondary2.shouldBeVisible(null /* starting */));
331
Wale Ogunwale8e923af2018-03-23 08:48:11 -0700332 // First split-screen secondary should be visible behind another translucent split-screen
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700333 // secondary.
334 splitScreenSecondary2.setIsTranslucent(true);
335 assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
336 assertTrue(splitScreenSecondary2.shouldBeVisible(null /* starting */));
337
Winson Chung3e2980e2018-03-29 17:28:57 -0700338 final TestActivityStack assistantStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700339 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_ASSISTANT, true /* onTop */);
340
341 // Split-screen stacks shouldn't be visible behind an opaque fullscreen stack.
342 assistantStack.setIsTranslucent(false);
343 assertTrue(assistantStack.shouldBeVisible(null /* starting */));
344 assertFalse(splitScreenPrimary.shouldBeVisible(null /* starting */));
345 assertFalse(splitScreenSecondary.shouldBeVisible(null /* starting */));
346 assertFalse(splitScreenSecondary2.shouldBeVisible(null /* starting */));
347
348 // Split-screen stacks should be visible behind a translucent fullscreen stack.
349 assistantStack.setIsTranslucent(true);
350 assertTrue(assistantStack.shouldBeVisible(null /* starting */));
351 assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */));
352 assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
353 assertTrue(splitScreenSecondary2.shouldBeVisible(null /* starting */));
Wale Ogunwale8e923af2018-03-23 08:48:11 -0700354
355 // Assistant stack shouldn't be visible behind translucent split-screen stack
356 assistantStack.setIsTranslucent(false);
357 splitScreenPrimary.setIsTranslucent(true);
358 splitScreenSecondary2.setIsTranslucent(true);
359 splitScreenSecondary2.moveToFront("testShouldBeVisible_SplitScreen");
360 splitScreenPrimary.moveToFront("testShouldBeVisible_SplitScreen");
361 assertFalse(assistantStack.shouldBeVisible(null /* starting */));
362 assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */));
363 assertTrue(splitScreenSecondary2.shouldBeVisible(null /* starting */));
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700364 }
365
366 @Test
367 public void testShouldBeVisible_Finishing() throws Exception {
Winson Chung3e2980e2018-03-29 17:28:57 -0700368 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700369 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
Winson Chung3e2980e2018-03-29 17:28:57 -0700370 final TestActivityStack translucentStack = createStackForShouldBeVisibleTest(
371 mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
372 true /* onTop */);
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700373 translucentStack.setIsTranslucent(true);
374
375 assertTrue(homeStack.shouldBeVisible(null /* starting */));
376 assertTrue(translucentStack.shouldBeVisible(null /* starting */));
377
378 final ActivityRecord topRunningHomeActivity = homeStack.topRunningActivityLocked();
379 topRunningHomeActivity.finishing = true;
380 final ActivityRecord topRunningTranslucentActivity =
381 translucentStack.topRunningActivityLocked();
382 topRunningTranslucentActivity.finishing = true;
383
384 // Home shouldn't be visible since its activity is marked as finishing and it isn't the top
385 // of the stack list.
386 assertFalse(homeStack.shouldBeVisible(null /* starting */));
387 // Home should be visible if we are starting an activity within it.
388 assertTrue(homeStack.shouldBeVisible(topRunningHomeActivity /* starting */));
389 // The translucent stack should be visible since it is the top of the stack list even though
390 // it has its activity marked as finishing.
391 assertTrue(translucentStack.shouldBeVisible(null /* starting */));
392 }
393
Winson Chungd922b6b2018-02-16 16:41:50 -0800394 @Test
395 public void testMoveHomeStackBehindBottomMostVisibleStack_NoMoveHomeBehindFullscreen() {
Winson Chung3e2980e2018-03-29 17:28:57 -0700396 mDefaultDisplay.removeChild(mStack);
Winson Chungd922b6b2018-02-16 16:41:50 -0800397
Winson Chung3e2980e2018-03-29 17:28:57 -0700398 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Winson Chungd922b6b2018-02-16 16:41:50 -0800399 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
Winson Chung3e2980e2018-03-29 17:28:57 -0700400 final TestActivityStack fullscreenStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Winson Chungd922b6b2018-02-16 16:41:50 -0800401 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
402
403 homeStack.setIsTranslucent(false);
404 fullscreenStack.setIsTranslucent(false);
405
406 // 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 -0700407 int homeStackIndex = mDefaultDisplay.getIndexOf(homeStack);
408 assertTrue(mDefaultDisplay.getStackAbove(homeStack) == fullscreenStack);
409 mDefaultDisplay.moveStackBehindBottomMostVisibleStack(homeStack);
410 assertTrue(mDefaultDisplay.getIndexOf(homeStack) == homeStackIndex);
Winson Chungd922b6b2018-02-16 16:41:50 -0800411 }
412
413 @Test
414 public void testMoveHomeStackBehindBottomMostVisibleStack_NoMoveHomeBehindTranslucent() {
Winson Chung3e2980e2018-03-29 17:28:57 -0700415 mDefaultDisplay.removeChild(mStack);
Winson Chungd922b6b2018-02-16 16:41:50 -0800416
Winson Chung3e2980e2018-03-29 17:28:57 -0700417 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Winson Chungd922b6b2018-02-16 16:41:50 -0800418 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
Winson Chung3e2980e2018-03-29 17:28:57 -0700419 final TestActivityStack fullscreenStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Winson Chungd922b6b2018-02-16 16:41:50 -0800420 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
421
422 homeStack.setIsTranslucent(false);
423 fullscreenStack.setIsTranslucent(true);
424
425 // 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 -0700426 int homeStackIndex = mDefaultDisplay.getIndexOf(homeStack);
427 assertTrue(mDefaultDisplay.getStackAbove(homeStack) == fullscreenStack);
428 mDefaultDisplay.moveStackBehindBottomMostVisibleStack(homeStack);
429 assertTrue(mDefaultDisplay.getIndexOf(homeStack) == homeStackIndex);
Winson Chungd922b6b2018-02-16 16:41:50 -0800430 }
431
432 @Test
433 public void testMoveHomeStackBehindBottomMostVisibleStack_NoMoveHomeOnTop() {
Winson Chung3e2980e2018-03-29 17:28:57 -0700434 mDefaultDisplay.removeChild(mStack);
Winson Chungd922b6b2018-02-16 16:41:50 -0800435
Winson Chung3e2980e2018-03-29 17:28:57 -0700436 final TestActivityStack fullscreenStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Winson Chungd922b6b2018-02-16 16:41:50 -0800437 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
Winson Chung3e2980e2018-03-29 17:28:57 -0700438 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Winson Chungd922b6b2018-02-16 16:41:50 -0800439 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
440
441 homeStack.setIsTranslucent(false);
442 fullscreenStack.setIsTranslucent(false);
443
444 // Ensure we don't move the home stack if it is already on top
Winson Chung3e2980e2018-03-29 17:28:57 -0700445 int homeStackIndex = mDefaultDisplay.getIndexOf(homeStack);
446 assertTrue(mDefaultDisplay.getStackAbove(homeStack) == null);
447 mDefaultDisplay.moveStackBehindBottomMostVisibleStack(homeStack);
448 assertTrue(mDefaultDisplay.getIndexOf(homeStack) == homeStackIndex);
Winson Chungd922b6b2018-02-16 16:41:50 -0800449 }
450
451 @Test
452 public void testMoveHomeStackBehindBottomMostVisibleStack_MoveHomeBehindFullscreen() {
Winson Chung3e2980e2018-03-29 17:28:57 -0700453 mDefaultDisplay.removeChild(mStack);
Winson Chungd922b6b2018-02-16 16:41:50 -0800454
Winson Chung3e2980e2018-03-29 17:28:57 -0700455 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Winson Chungd922b6b2018-02-16 16:41:50 -0800456 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
Winson Chung3e2980e2018-03-29 17:28:57 -0700457 final TestActivityStack fullscreenStack1 = createStackForShouldBeVisibleTest(
458 mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
459 true /* onTop */);
460 final TestActivityStack fullscreenStack2 = createStackForShouldBeVisibleTest(
461 mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
462 true /* onTop */);
463 final TestActivityStack pinnedStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Winson Chungd922b6b2018-02-16 16:41:50 -0800464 WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, true /* onTop */);
465
466 homeStack.setIsTranslucent(false);
467 fullscreenStack1.setIsTranslucent(false);
468 fullscreenStack2.setIsTranslucent(false);
469
470 // Ensure that we move the home stack behind the bottom most fullscreen stack, ignoring the
471 // pinned stack
Winson Chung3e2980e2018-03-29 17:28:57 -0700472 assertTrue(mDefaultDisplay.getStackAbove(homeStack) == fullscreenStack1);
473 mDefaultDisplay.moveStackBehindBottomMostVisibleStack(homeStack);
474 assertTrue(mDefaultDisplay.getStackAbove(homeStack) == fullscreenStack2);
Winson Chungd922b6b2018-02-16 16:41:50 -0800475 }
476
477 @Test
478 public void testMoveHomeStackBehindBottomMostVisibleStack_MoveHomeBehindFullscreenAndTranslucent() {
Winson Chung3e2980e2018-03-29 17:28:57 -0700479 mDefaultDisplay.removeChild(mStack);
Winson Chungd922b6b2018-02-16 16:41:50 -0800480
Winson Chung3e2980e2018-03-29 17:28:57 -0700481 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Winson Chungd922b6b2018-02-16 16:41:50 -0800482 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
Winson Chung3e2980e2018-03-29 17:28:57 -0700483 final TestActivityStack fullscreenStack1 = createStackForShouldBeVisibleTest(
484 mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
485 true /* onTop */);
486 final TestActivityStack fullscreenStack2 = createStackForShouldBeVisibleTest(
487 mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
488 true /* onTop */);
Winson Chungd922b6b2018-02-16 16:41:50 -0800489
490 homeStack.setIsTranslucent(false);
491 fullscreenStack1.setIsTranslucent(false);
492 fullscreenStack2.setIsTranslucent(true);
493
494 // Ensure that we move the home stack behind the bottom most non-translucent fullscreen
495 // stack
Winson Chung3e2980e2018-03-29 17:28:57 -0700496 assertTrue(mDefaultDisplay.getStackAbove(homeStack) == fullscreenStack1);
497 mDefaultDisplay.moveStackBehindBottomMostVisibleStack(homeStack);
498 assertTrue(mDefaultDisplay.getStackAbove(homeStack) == fullscreenStack1);
Winson Chungd922b6b2018-02-16 16:41:50 -0800499 }
500
501 @Test
502 public void testMoveHomeStackBehindStack_BehindHomeStack() {
Winson Chung3e2980e2018-03-29 17:28:57 -0700503 mDefaultDisplay.removeChild(mStack);
Winson Chungd922b6b2018-02-16 16:41:50 -0800504
Winson Chung3e2980e2018-03-29 17:28:57 -0700505 final TestActivityStack fullscreenStack1 = createStackForShouldBeVisibleTest(
506 mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
507 true /* onTop */);
508 final TestActivityStack fullscreenStack2 = createStackForShouldBeVisibleTest(
509 mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
510 true /* onTop */);
511 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Winson Chungd922b6b2018-02-16 16:41:50 -0800512 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
513
514 homeStack.setIsTranslucent(false);
515 fullscreenStack1.setIsTranslucent(false);
516 fullscreenStack2.setIsTranslucent(false);
517
518 // Ensure we don't move the home stack behind itself
Winson Chung3e2980e2018-03-29 17:28:57 -0700519 int homeStackIndex = mDefaultDisplay.getIndexOf(homeStack);
520 mDefaultDisplay.moveStackBehindStack(homeStack, homeStack);
521 assertTrue(mDefaultDisplay.getIndexOf(homeStack) == homeStackIndex);
Winson Chungd922b6b2018-02-16 16:41:50 -0800522 }
523
524 @Test
525 public void testMoveHomeStackBehindStack() {
Winson Chung3e2980e2018-03-29 17:28:57 -0700526 mDefaultDisplay.removeChild(mStack);
Winson Chungd922b6b2018-02-16 16:41:50 -0800527
Winson Chung3e2980e2018-03-29 17:28:57 -0700528 final TestActivityStack fullscreenStack1 = createStackForShouldBeVisibleTest(
529 mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
530 true /* onTop */);
531 final TestActivityStack fullscreenStack2 = createStackForShouldBeVisibleTest(
532 mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
533 true /* onTop */);
534 final TestActivityStack fullscreenStack3 = createStackForShouldBeVisibleTest(
535 mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
536 true /* onTop */);
537 final TestActivityStack fullscreenStack4 = createStackForShouldBeVisibleTest(
538 mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
539 true /* onTop */);
540 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Winson Chungd922b6b2018-02-16 16:41:50 -0800541 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
542
Winson Chung3e2980e2018-03-29 17:28:57 -0700543 mDefaultDisplay.moveStackBehindStack(homeStack, fullscreenStack1);
544 assertTrue(mDefaultDisplay.getStackAbove(homeStack) == fullscreenStack1);
545 mDefaultDisplay.moveStackBehindStack(homeStack, fullscreenStack2);
546 assertTrue(mDefaultDisplay.getStackAbove(homeStack) == fullscreenStack2);
547 mDefaultDisplay.moveStackBehindStack(homeStack, fullscreenStack4);
548 assertTrue(mDefaultDisplay.getStackAbove(homeStack) == fullscreenStack4);
549 mDefaultDisplay.moveStackBehindStack(homeStack, fullscreenStack2);
550 assertTrue(mDefaultDisplay.getStackAbove(homeStack) == fullscreenStack2);
Winson Chungd922b6b2018-02-16 16:41:50 -0800551 }
552
Wale Ogunwalebb285872018-03-01 13:05:30 -0800553 @Test
Kazuki Takisef85197b2018-06-18 18:18:36 +0900554 public void testSetAlwaysOnTop() {
555 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
556 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
557 final ActivityStack pinnedStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
558 WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, true /* onTop */);
559 assertTrue(mDefaultDisplay.getStackAbove(homeStack) == pinnedStack);
560
561 final TestActivityStack alwaysOnTopStack = createStackForShouldBeVisibleTest(
562 mDefaultDisplay, WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD,
563 true /* onTop */);
564 alwaysOnTopStack.setAlwaysOnTop(true);
565 assertTrue(alwaysOnTopStack.isAlwaysOnTop());
566 // Ensure (non-pinned) always on top stack is put below pinned stack.
567 assertTrue(mDefaultDisplay.getStackAbove(alwaysOnTopStack) == pinnedStack);
568
569 final TestActivityStack nonAlwaysOnTopStack = createStackForShouldBeVisibleTest(
570 mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
571 true /* onTop */);
572 // Ensure non always on top stack is put below always on top stacks.
573 assertTrue(mDefaultDisplay.getStackAbove(nonAlwaysOnTopStack) == alwaysOnTopStack);
574
575 final TestActivityStack alwaysOnTopStack2 = createStackForShouldBeVisibleTest(
576 mDefaultDisplay, WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD,
577 true /* onTop */);
578 alwaysOnTopStack2.setAlwaysOnTop(true);
579 assertTrue(alwaysOnTopStack2.isAlwaysOnTop());
580 // Ensure newly created always on top stack is placed above other all always on top stacks.
581 assertTrue(mDefaultDisplay.getStackAbove(alwaysOnTopStack2) == pinnedStack);
582
583 alwaysOnTopStack2.setAlwaysOnTop(false);
584 // Ensure, when always on top is turned off for a stack, the stack is put just below all
585 // other always on top stacks.
586 assertTrue(mDefaultDisplay.getStackAbove(alwaysOnTopStack2) == alwaysOnTopStack);
Kazuki Takise048e2662018-06-27 17:05:11 +0900587 alwaysOnTopStack2.setAlwaysOnTop(true);
588
589 // Ensure always on top state changes properly when windowing mode changes.
590 alwaysOnTopStack2.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
591 assertFalse(alwaysOnTopStack2.isAlwaysOnTop());
592 assertTrue(mDefaultDisplay.getStackAbove(alwaysOnTopStack2) == alwaysOnTopStack);
593 alwaysOnTopStack2.setWindowingMode(WINDOWING_MODE_FREEFORM);
594 assertTrue(alwaysOnTopStack2.isAlwaysOnTop());
595 assertTrue(mDefaultDisplay.getStackAbove(alwaysOnTopStack2) == pinnedStack);
Kazuki Takisef85197b2018-06-18 18:18:36 +0900596 }
597
598 @Test
Wale Ogunwalebb285872018-03-01 13:05:30 -0800599 public void testSplitScreenMoveToFront() throws Exception {
Winson Chung3e2980e2018-03-29 17:28:57 -0700600 final TestActivityStack splitScreenPrimary = createStackForShouldBeVisibleTest(
601 mDefaultDisplay, WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD,
602 true /* onTop */);
603 final TestActivityStack splitScreenSecondary = createStackForShouldBeVisibleTest(
604 mDefaultDisplay, WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD,
605 true /* onTop */);
606 final TestActivityStack assistantStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Wale Ogunwalebb285872018-03-01 13:05:30 -0800607 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_ASSISTANT, true /* onTop */);
608
609 splitScreenPrimary.setIsTranslucent(false);
610 splitScreenSecondary.setIsTranslucent(false);
611 assistantStack.setIsTranslucent(false);
612
613 assertFalse(splitScreenPrimary.shouldBeVisible(null /* starting */));
614 assertFalse(splitScreenSecondary.shouldBeVisible(null /* starting */));
615 assertTrue(assistantStack.shouldBeVisible(null /* starting */));
616
617 splitScreenSecondary.moveToFront("testSplitScreenMoveToFront");
618
619 assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */));
620 assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
621 assertFalse(assistantStack.shouldBeVisible(null /* starting */));
622 }
623
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700624 private <T extends ActivityStack> T createStackForShouldBeVisibleTest(
625 ActivityDisplay display, int windowingMode, int activityType, boolean onTop) {
Andrii Kulian6a6c4f12018-07-16 21:23:33 -0700626 final T stack;
627 if (activityType == ACTIVITY_TYPE_HOME) {
628 // Home stack and activity are created in ActivityTestsBase#setupActivityManagerService
629 stack = mDefaultDisplay.getStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME);
630 if (onTop) {
Riddle Hsu57831b52018-07-27 00:31:48 +0800631 mDefaultDisplay.positionChildAtTop(stack, false /* includingParents */);
Andrii Kulian6a6c4f12018-07-16 21:23:33 -0700632 } else {
633 mDefaultDisplay.positionChildAtBottom(stack);
634 }
635 } else {
636 stack = display.createStack(windowingMode, activityType, onTop);
637 final ActivityRecord r = new ActivityBuilder(mService).setUid(0).setStack(stack)
638 .setCreateTask(true).build();
639 }
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700640 return stack;
641 }
Bryce Leeb0f993f2018-03-02 15:38:01 -0800642
643 @Test
Bryce Leefbd263b42018-03-07 10:33:55 -0800644 public void testFinishDisabledPackageActivities() throws Exception {
645 final ActivityRecord firstActivity = new ActivityBuilder(mService).setTask(mTask).build();
646 final ActivityRecord secondActivity = new ActivityBuilder(mService).setTask(mTask).build();
647
648 // Making the second activity a task overlay without an app means it will be removed from
649 // the task's activities as well once first activity is removed.
650 secondActivity.mTaskOverlay = true;
651 secondActivity.app = null;
652
653 assertEquals(mTask.mActivities.size(), 2);
654
655 mStack.finishDisabledPackageActivitiesLocked(firstActivity.packageName, null,
656 true /* doit */, true /* evenPersistent */, UserHandle.USER_ALL);
657
658 assertTrue(mTask.mActivities.isEmpty());
659 assertTrue(mStack.getAllTasks().isEmpty());
660 }
661
662 @Test
663 public void testHandleAppDied() throws Exception {
664 final ActivityRecord firstActivity = new ActivityBuilder(mService).setTask(mTask).build();
665 final ActivityRecord secondActivity = new ActivityBuilder(mService).setTask(mTask).build();
666
667 // Making the first activity a task overlay means it will be removed from the task's
668 // activities as well once second activity is removed as handleAppDied processes the
669 // activity list in reverse.
670 firstActivity.mTaskOverlay = true;
671 firstActivity.app = null;
672
673 // second activity will be immediately removed as it has no state.
674 secondActivity.haveState = false;
675
676 assertEquals(mTask.mActivities.size(), 2);
677
678 mStack.handleAppDiedLocked(secondActivity.app);
679
680 assertTrue(mTask.mActivities.isEmpty());
681 assertTrue(mStack.getAllTasks().isEmpty());
682 }
Bryce Lee271617a2018-03-15 10:39:12 -0700683
684 @Test
Riddle Hsue10cea52018-10-16 23:33:23 +0800685 public void testFinishCurrentActivity() {
686 // Create 2 activities on a new display.
687 final ActivityDisplay display = addNewActivityDisplayAt(ActivityDisplay.POSITION_TOP);
688 final ActivityStack stack1 = createStackForShouldBeVisibleTest(display,
689 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
690 final ActivityStack stack2 = createStackForShouldBeVisibleTest(display,
691 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
692
693 // There is still an activity1 in stack1 so the activity2 should be added to finishing list
694 // that will be destroyed until idle.
695 final ActivityRecord activity2 = finishCurrentActivity(stack2);
696 assertEquals(FINISHING, activity2.getState());
697 assertTrue(mSupervisor.mFinishingActivities.contains(activity2));
698
699 // The display becomes empty. Since there is no next activity to be idle, the activity
700 // should be destroyed immediately with updating configuration to restore original state.
701 final ActivityRecord activity1 = finishCurrentActivity(stack1);
702 assertEquals(DESTROYING, activity1.getState());
703 verify(mSupervisor).ensureVisibilityAndConfig(eq(null) /* starting */,
704 eq(display.mDisplayId), anyBoolean(), anyBoolean());
705 }
706
707 private ActivityRecord finishCurrentActivity(ActivityStack stack) {
708 final ActivityRecord activity = stack.topRunningActivityLocked();
709 assertNotNull(activity);
710 activity.setState(PAUSED, "finishCurrentActivity");
711 activity.makeFinishingLocked();
712 stack.finishCurrentActivityLocked(activity, ActivityStack.FINISH_AFTER_VISIBLE,
713 false /* oomAdj */, "finishCurrentActivity");
714 return activity;
715 }
716
717 @Test
Bryce Lee271617a2018-03-15 10:39:12 -0700718 public void testShouldSleepActivities() throws Exception {
719 // When focused activity and keyguard is going away, we should not sleep regardless
720 // of the display state
721 verifyShouldSleepActivities(true /* focusedStack */, true /*keyguardGoingAway*/,
722 true /* displaySleeping */, false /* expected*/);
723
724 // When not the focused stack, defer to display sleeping state.
725 verifyShouldSleepActivities(false /* focusedStack */, true /*keyguardGoingAway*/,
726 true /* displaySleeping */, true /* expected*/);
727
728 // If keyguard is going away, defer to the display sleeping state.
729 verifyShouldSleepActivities(true /* focusedStack */, false /*keyguardGoingAway*/,
730 true /* displaySleeping */, true /* expected*/);
731 verifyShouldSleepActivities(true /* focusedStack */, false /*keyguardGoingAway*/,
732 false /* displaySleeping */, false /* expected*/);
733 }
734
Winson Chung0f7ec962018-05-03 18:03:15 -0700735 @Test
736 public void testStackOrderChangedOnRemoveStack() throws Exception {
737 StackOrderChangedListener listener = new StackOrderChangedListener();
738 mDefaultDisplay.registerStackOrderChangedListener(listener);
739 try {
740 mDefaultDisplay.removeChild(mStack);
741 } finally {
742 mDefaultDisplay.unregisterStackOrderChangedListener(listener);
743 }
744 assertTrue(listener.changed);
745 }
746
747 @Test
748 public void testStackOrderChangedOnAddPositionStack() throws Exception {
749 mDefaultDisplay.removeChild(mStack);
750
751 StackOrderChangedListener listener = new StackOrderChangedListener();
752 mDefaultDisplay.registerStackOrderChangedListener(listener);
753 try {
754 mDefaultDisplay.addChild(mStack, 0);
755 } finally {
756 mDefaultDisplay.unregisterStackOrderChangedListener(listener);
757 }
758 assertTrue(listener.changed);
759 }
760
761 @Test
762 public void testStackOrderChangedOnPositionStack() throws Exception {
763 StackOrderChangedListener listener = new StackOrderChangedListener();
764 try {
765 final TestActivityStack fullscreenStack1 = createStackForShouldBeVisibleTest(
766 mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
767 true /* onTop */);
768 mDefaultDisplay.registerStackOrderChangedListener(listener);
769 mDefaultDisplay.positionChildAtBottom(fullscreenStack1);
770 } finally {
771 mDefaultDisplay.unregisterStackOrderChangedListener(listener);
772 }
773 assertTrue(listener.changed);
774 }
775
Bryce Lee271617a2018-03-15 10:39:12 -0700776 private void verifyShouldSleepActivities(boolean focusedStack,
777 boolean keyguardGoingAway, boolean displaySleeping, boolean expected) {
Bryce Lee271617a2018-03-15 10:39:12 -0700778 final ActivityDisplay display = mock(ActivityDisplay.class);
779 final KeyguardController keyguardController = mSupervisor.getKeyguardController();
780
781 doReturn(display).when(mSupervisor).getActivityDisplay(anyInt());
782 doReturn(keyguardGoingAway).when(keyguardController).isKeyguardGoingAway();
783 doReturn(displaySleeping).when(display).isSleeping();
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800784 doReturn(focusedStack).when(mStack).isFocusedStackOnDisplay();
Bryce Lee271617a2018-03-15 10:39:12 -0700785
786 assertEquals(expected, mStack.shouldSleepActivities());
787 }
Winson Chung0f7ec962018-05-03 18:03:15 -0700788
789 private class StackOrderChangedListener implements ActivityDisplay.OnStackOrderChangedListener {
790 boolean changed = false;
791
792 @Override
793 public void onStackOrderChanged() {
794 changed = true;
795 }
796 }
Bryce Lee840c5662017-04-13 10:02:51 -0700797}