blob: d60623d2e0959632da0695d00eb73e02b43aae53 [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;
22import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -070023import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
24import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
25import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
Bryce Lee18d51592017-10-25 10:22:19 -070026
Bryce Leeb0f993f2018-03-02 15:38:01 -080027import static com.android.server.am.ActivityStack.ActivityState.DESTROYED;
28import static com.android.server.am.ActivityStack.ActivityState.DESTROYING;
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070029import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_DESTROYING;
Bryce Lee18d51592017-10-25 10:22:19 -070030
Bryce Lee5daa3122017-04-19 10:40:42 -070031import static org.junit.Assert.assertEquals;
David Stevens18abd0e2017-08-17 14:55:47 -070032import static org.junit.Assert.assertFalse;
Bryce Lee840c5662017-04-13 10:02:51 -070033import static org.junit.Assert.assertNotNull;
34import static org.junit.Assert.assertNull;
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -070035import static org.junit.Assert.assertTrue;
Bryce Leeb0f993f2018-03-02 15:38:01 -080036import static org.mockito.ArgumentMatchers.any;
37import static org.mockito.ArgumentMatchers.eq;
38import static org.mockito.Mockito.mock;
39import static org.mockito.Mockito.times;
40import static org.mockito.Mockito.verify;
Bryce Lee840c5662017-04-13 10:02:51 -070041
Bryce Leeb0f993f2018-03-02 15:38:01 -080042import android.app.servertransaction.DestroyActivityItem;
Bryce Lee3345c4e2017-04-25 07:40:41 -070043import android.content.pm.ActivityInfo;
Bryce Lee9f6affd2017-09-01 09:18:35 -070044import android.os.UserHandle;
Bryce Lee840c5662017-04-13 10:02:51 -070045import android.platform.test.annotations.Presubmit;
46import android.support.test.filters.SmallTest;
47import android.support.test.runner.AndroidJUnit4;
48
49import org.junit.runner.RunWith;
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070050import org.junit.Before;
Bryce Lee840c5662017-04-13 10:02:51 -070051import org.junit.Test;
52
53/**
54 * Tests for the {@link ActivityStack} class.
55 *
56 * Build/Install/Run:
Wale Ogunwalebb285872018-03-01 13:05:30 -080057 * atest FrameworksServicesTests:com.android.server.am.ActivityStackTests
Bryce Lee840c5662017-04-13 10:02:51 -070058 */
59@SmallTest
60@Presubmit
61@RunWith(AndroidJUnit4.class)
62public class ActivityStackTests extends ActivityTestsBase {
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070063 private ActivityManagerService mService;
64 private ActivityStackSupervisor mSupervisor;
65 private ActivityStack mStack;
66 private TaskRecord mTask;
67
68 @Before
69 @Override
70 public void setUp() throws Exception {
71 super.setUp();
72
73 mService = createActivityManagerService();
74 mSupervisor = mService.mStackSupervisor;
75 mStack = mService.mStackSupervisor.getDefaultDisplay().createStack(
76 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
Bryce Lee18d51592017-10-25 10:22:19 -070077 mTask = new TaskBuilder(mSupervisor).setStack(mStack).build();
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070078 }
79
Bryce Lee840c5662017-04-13 10:02:51 -070080 @Test
81 public void testEmptyTaskCleanupOnRemove() throws Exception {
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070082 assertNotNull(mTask.getWindowContainerController());
83 mStack.removeTask(mTask, "testEmptyTaskCleanupOnRemove", REMOVE_TASK_MODE_DESTROYING);
84 assertNull(mTask.getWindowContainerController());
Bryce Lee840c5662017-04-13 10:02:51 -070085 }
Bryce Lee5daa3122017-04-19 10:40:42 -070086
Bryce Lee840c5662017-04-13 10:02:51 -070087 @Test
88 public void testOccupiedTaskCleanupOnRemove() throws Exception {
Bryce Lee18d51592017-10-25 10:22:19 -070089 final ActivityRecord r = new ActivityBuilder(mService).setTask(mTask).build();
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070090 assertNotNull(mTask.getWindowContainerController());
91 mStack.removeTask(mTask, "testOccupiedTaskCleanupOnRemove", REMOVE_TASK_MODE_DESTROYING);
92 assertNotNull(mTask.getWindowContainerController());
Bryce Lee840c5662017-04-13 10:02:51 -070093 }
Bryce Lee5daa3122017-04-19 10:40:42 -070094
95 @Test
96 public void testNoPauseDuringResumeTopActivity() throws Exception {
Bryce Lee18d51592017-10-25 10:22:19 -070097 final ActivityRecord r = new ActivityBuilder(mService).setTask(mTask).build();
Bryce Lee5daa3122017-04-19 10:40:42 -070098
99 // Simulate the a resumed activity set during
100 // {@link ActivityStack#resumeTopActivityUncheckedLocked}.
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700101 mSupervisor.inResumeTopActivity = true;
102 mStack.mResumedActivity = r;
Bryce Lee5daa3122017-04-19 10:40:42 -0700103
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700104 final boolean waiting = mStack.goToSleepIfPossible(false);
Bryce Lee5daa3122017-04-19 10:40:42 -0700105
106 // Ensure we report not being ready for sleep.
David Stevens18abd0e2017-08-17 14:55:47 -0700107 assertFalse(waiting);
Bryce Lee5daa3122017-04-19 10:40:42 -0700108
109 // Make sure the resumed activity is untouched.
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700110 assertEquals(mStack.mResumedActivity, r);
Bryce Lee5daa3122017-04-19 10:40:42 -0700111 }
Bryce Lee3345c4e2017-04-25 07:40:41 -0700112
113 @Test
Bryce Lee8cab4a02018-01-05 09:00:49 -0800114 public void testPrimarySplitScreenToFullscreenWhenMovedToBack() throws Exception {
115 // Create primary splitscreen stack. This will create secondary stacks and places the
116 // existing fullscreen stack on the bottom.
117 final ActivityStack primarySplitScreen = mService.mStackSupervisor.getDefaultDisplay()
118 .createStack(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD,
119 true /* onTop */);
120
121 // Assert windowing mode.
122 assertEquals(primarySplitScreen.getWindowingMode(), WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
123
124 // Move primary to back.
125 primarySplitScreen.moveToBack("testPrimarySplitScreenToFullscreenWhenMovedToBack",
126 null /* task */);
127
128 // Assert that stack is at the bottom.
129 assertEquals(mService.mStackSupervisor.getDefaultDisplay().getIndexOf(primarySplitScreen),
130 0);
131
132 // Ensure no longer in splitscreen.
133 assertEquals(primarySplitScreen.getWindowingMode(), WINDOWING_MODE_FULLSCREEN);
134 }
135
136 @Test
Bryce Lee3345c4e2017-04-25 07:40:41 -0700137 public void testStopActivityWhenActivityDestroyed() throws Exception {
Bryce Lee18d51592017-10-25 10:22:19 -0700138 final ActivityRecord r = new ActivityBuilder(mService).setTask(mTask).build();
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700139 r.info.flags |= ActivityInfo.FLAG_NO_HISTORY;
140 mSupervisor.setFocusStackUnchecked("testStopActivityWithDestroy", mStack);
141 mStack.stopActivityLocked(r);
142 // Mostly testing to make sure there is a crash in the call part, so if we get here we are
143 // good-to-go!
Bryce Lee3345c4e2017-04-25 07:40:41 -0700144 }
Bryce Lee9f6affd2017-09-01 09:18:35 -0700145
146 @Test
147 public void testFindTaskWithOverlay() throws Exception {
Bryce Lee18d51592017-10-25 10:22:19 -0700148 final ActivityRecord r = new ActivityBuilder(mService)
149 .setCreateTask(true)
150 .setStack(mStack)
151 .setUid(0)
152 .build();
153 final TaskRecord task = r.getTask();
Bryce Lee9f6affd2017-09-01 09:18:35 -0700154 // Overlay must be for a different user to prevent recognizing a matching top activity
Bryce Lee18d51592017-10-25 10:22:19 -0700155 final ActivityRecord taskOverlay = new ActivityBuilder(mService).setTask(task)
156 .setUid(UserHandle.PER_USER_RANGE * 2).build();
Bryce Lee9f6affd2017-09-01 09:18:35 -0700157 taskOverlay.mTaskOverlay = true;
158
Bryce Lee9f6affd2017-09-01 09:18:35 -0700159 final ActivityStackSupervisor.FindTaskResult result =
160 new ActivityStackSupervisor.FindTaskResult();
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700161 mStack.findTaskLocked(r, result);
Bryce Lee9f6affd2017-09-01 09:18:35 -0700162
Bryce Lee18d51592017-10-25 10:22:19 -0700163 assertEquals(task.getTopActivity(false /* includeOverlays */), r);
164 assertEquals(task.getTopActivity(true /* includeOverlays */), taskOverlay);
Bryce Lee9f6affd2017-09-01 09:18:35 -0700165 assertNotNull(result.r);
166 }
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700167
168 @Test
169 public void testShouldBeVisible_Fullscreen() throws Exception {
170 final ActivityDisplay display = mService.mStackSupervisor.getDefaultDisplay();
171 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(display,
172 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
173 final ActivityStack pinnedStack = createStackForShouldBeVisibleTest(display,
174 WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, true /* onTop */);
175
176 assertTrue(homeStack.shouldBeVisible(null /* starting */));
177 assertTrue(pinnedStack.shouldBeVisible(null /* starting */));
178
179 final TestActivityStack fullscreenStack = createStackForShouldBeVisibleTest(display,
180 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
181 // Home stack shouldn't be visible behind an opaque fullscreen stack, but pinned stack
182 // should be visible since it is always on-top.
183 fullscreenStack.setIsTranslucent(false);
184 assertFalse(homeStack.shouldBeVisible(null /* starting */));
185 assertTrue(pinnedStack.shouldBeVisible(null /* starting */));
186 assertTrue(fullscreenStack.shouldBeVisible(null /* starting */));
187
188 // Home stack should be visible behind a translucent fullscreen stack.
189 fullscreenStack.setIsTranslucent(true);
190 assertTrue(homeStack.shouldBeVisible(null /* starting */));
191 assertTrue(pinnedStack.shouldBeVisible(null /* starting */));
192 }
193
194 @Test
195 public void testShouldBeVisible_SplitScreen() throws Exception {
196 final ActivityDisplay display = mService.mStackSupervisor.getDefaultDisplay();
197 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(display,
198 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
Wale Ogunwale30e441d2017-11-09 08:28:45 -0800199 // Home stack should always be fullscreen for this test.
200 homeStack.setSupportsSplitScreen(false);
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700201 final TestActivityStack splitScreenPrimary = createStackForShouldBeVisibleTest(display,
202 WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD, true /* onTop */);
203 final TestActivityStack splitScreenSecondary = createStackForShouldBeVisibleTest(display,
204 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD, true /* onTop */);
205
206 // Home stack shouldn't be visible if both halves of split-screen are opaque.
207 splitScreenPrimary.setIsTranslucent(false);
208 splitScreenSecondary.setIsTranslucent(false);
209 assertFalse(homeStack.shouldBeVisible(null /* starting */));
210 assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */));
211 assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
212
213 // Home stack should be visible if one of the halves of split-screen is translucent.
214 splitScreenPrimary.setIsTranslucent(true);
215 assertTrue(homeStack.shouldBeVisible(null /* starting */));
216 assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */));
217 assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
218
219 final TestActivityStack splitScreenSecondary2 = createStackForShouldBeVisibleTest(display,
220 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD, true /* onTop */);
221 // First split-screen secondary shouldn't be visible behind another opaque split-split
222 // secondary.
223 splitScreenSecondary2.setIsTranslucent(false);
224 assertFalse(splitScreenSecondary.shouldBeVisible(null /* starting */));
225 assertTrue(splitScreenSecondary2.shouldBeVisible(null /* starting */));
226
227 // First split-screen secondary should be visible behind another translucent split-split
228 // secondary.
229 splitScreenSecondary2.setIsTranslucent(true);
230 assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
231 assertTrue(splitScreenSecondary2.shouldBeVisible(null /* starting */));
232
233 final TestActivityStack assistantStack = createStackForShouldBeVisibleTest(display,
234 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_ASSISTANT, true /* onTop */);
235
236 // Split-screen stacks shouldn't be visible behind an opaque fullscreen stack.
237 assistantStack.setIsTranslucent(false);
238 assertTrue(assistantStack.shouldBeVisible(null /* starting */));
239 assertFalse(splitScreenPrimary.shouldBeVisible(null /* starting */));
240 assertFalse(splitScreenSecondary.shouldBeVisible(null /* starting */));
241 assertFalse(splitScreenSecondary2.shouldBeVisible(null /* starting */));
242
243 // Split-screen stacks should be visible behind a translucent fullscreen stack.
244 assistantStack.setIsTranslucent(true);
245 assertTrue(assistantStack.shouldBeVisible(null /* starting */));
246 assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */));
247 assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
248 assertTrue(splitScreenSecondary2.shouldBeVisible(null /* starting */));
249 }
250
251 @Test
252 public void testShouldBeVisible_Finishing() throws Exception {
253 final ActivityDisplay display = mService.mStackSupervisor.getDefaultDisplay();
254 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(display,
255 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
256 final TestActivityStack translucentStack = createStackForShouldBeVisibleTest(display,
257 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
258 translucentStack.setIsTranslucent(true);
259
260 assertTrue(homeStack.shouldBeVisible(null /* starting */));
261 assertTrue(translucentStack.shouldBeVisible(null /* starting */));
262
263 final ActivityRecord topRunningHomeActivity = homeStack.topRunningActivityLocked();
264 topRunningHomeActivity.finishing = true;
265 final ActivityRecord topRunningTranslucentActivity =
266 translucentStack.topRunningActivityLocked();
267 topRunningTranslucentActivity.finishing = true;
268
269 // Home shouldn't be visible since its activity is marked as finishing and it isn't the top
270 // of the stack list.
271 assertFalse(homeStack.shouldBeVisible(null /* starting */));
272 // Home should be visible if we are starting an activity within it.
273 assertTrue(homeStack.shouldBeVisible(topRunningHomeActivity /* starting */));
274 // The translucent stack should be visible since it is the top of the stack list even though
275 // it has its activity marked as finishing.
276 assertTrue(translucentStack.shouldBeVisible(null /* starting */));
277 }
278
Winson Chungd922b6b2018-02-16 16:41:50 -0800279 @Test
280 public void testMoveHomeStackBehindBottomMostVisibleStack_NoMoveHomeBehindFullscreen() {
281 final ActivityDisplay display = mService.mStackSupervisor.getDefaultDisplay();
282 display.removeChild(mStack);
283
284 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(display,
285 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
286 final TestActivityStack fullscreenStack = createStackForShouldBeVisibleTest(display,
287 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
288
289 homeStack.setIsTranslucent(false);
290 fullscreenStack.setIsTranslucent(false);
291
292 // Ensure that we don't move the home stack if it is already behind the top fullscreen stack
293 int homeStackIndex = display.getIndexOf(homeStack);
294 assertTrue(display.getStackAboveHome() == fullscreenStack);
295 display.moveHomeStackBehindBottomMostVisibleStack();
296 assertTrue(display.getIndexOf(homeStack) == homeStackIndex);
297 }
298
299 @Test
300 public void testMoveHomeStackBehindBottomMostVisibleStack_NoMoveHomeBehindTranslucent() {
301 final ActivityDisplay display = mService.mStackSupervisor.getDefaultDisplay();
302 display.removeChild(mStack);
303
304 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(display,
305 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
306 final TestActivityStack fullscreenStack = createStackForShouldBeVisibleTest(display,
307 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
308
309 homeStack.setIsTranslucent(false);
310 fullscreenStack.setIsTranslucent(true);
311
312 // Ensure that we don't move the home stack if it is already behind the top fullscreen stack
313 int homeStackIndex = display.getIndexOf(homeStack);
314 assertTrue(display.getStackAboveHome() == fullscreenStack);
315 display.moveHomeStackBehindBottomMostVisibleStack();
316 assertTrue(display.getIndexOf(homeStack) == homeStackIndex);
317 }
318
319 @Test
320 public void testMoveHomeStackBehindBottomMostVisibleStack_NoMoveHomeOnTop() {
321 final ActivityDisplay display = mService.mStackSupervisor.getDefaultDisplay();
322 display.removeChild(mStack);
323
324 final TestActivityStack fullscreenStack = createStackForShouldBeVisibleTest(display,
325 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
326 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(display,
327 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
328
329 homeStack.setIsTranslucent(false);
330 fullscreenStack.setIsTranslucent(false);
331
332 // Ensure we don't move the home stack if it is already on top
333 int homeStackIndex = display.getIndexOf(homeStack);
334 assertTrue(display.getStackAboveHome() == null);
335 display.moveHomeStackBehindBottomMostVisibleStack();
336 assertTrue(display.getIndexOf(homeStack) == homeStackIndex);
337 }
338
339 @Test
340 public void testMoveHomeStackBehindBottomMostVisibleStack_MoveHomeBehindFullscreen() {
341 final ActivityDisplay display = mService.mStackSupervisor.getDefaultDisplay();
342 display.removeChild(mStack);
343
344 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(display,
345 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
346 final TestActivityStack fullscreenStack1 = createStackForShouldBeVisibleTest(display,
347 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
348 final TestActivityStack fullscreenStack2 = createStackForShouldBeVisibleTest(display,
349 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
350 final TestActivityStack pinnedStack = createStackForShouldBeVisibleTest(display,
351 WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, true /* onTop */);
352
353 homeStack.setIsTranslucent(false);
354 fullscreenStack1.setIsTranslucent(false);
355 fullscreenStack2.setIsTranslucent(false);
356
357 // Ensure that we move the home stack behind the bottom most fullscreen stack, ignoring the
358 // pinned stack
359 assertTrue(display.getStackAboveHome() == fullscreenStack1);
360 display.moveHomeStackBehindBottomMostVisibleStack();
361 assertTrue(display.getStackAboveHome() == fullscreenStack2);
362 }
363
364 @Test
365 public void testMoveHomeStackBehindBottomMostVisibleStack_MoveHomeBehindFullscreenAndTranslucent() {
366 final ActivityDisplay display = mService.mStackSupervisor.getDefaultDisplay();
367 display.removeChild(mStack);
368
369 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(display,
370 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
371 final TestActivityStack fullscreenStack1 = createStackForShouldBeVisibleTest(display,
372 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
373 final TestActivityStack fullscreenStack2 = createStackForShouldBeVisibleTest(display,
374 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
375
376 homeStack.setIsTranslucent(false);
377 fullscreenStack1.setIsTranslucent(false);
378 fullscreenStack2.setIsTranslucent(true);
379
380 // Ensure that we move the home stack behind the bottom most non-translucent fullscreen
381 // stack
382 assertTrue(display.getStackAboveHome() == fullscreenStack1);
383 display.moveHomeStackBehindBottomMostVisibleStack();
384 assertTrue(display.getStackAboveHome() == fullscreenStack1);
385 }
386
387 @Test
388 public void testMoveHomeStackBehindStack_BehindHomeStack() {
389 final ActivityDisplay display = mService.mStackSupervisor.getDefaultDisplay();
390 display.removeChild(mStack);
391
392 final TestActivityStack fullscreenStack1 = createStackForShouldBeVisibleTest(display,
393 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
394 final TestActivityStack fullscreenStack2 = createStackForShouldBeVisibleTest(display,
395 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
396 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(display,
397 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
398
399 homeStack.setIsTranslucent(false);
400 fullscreenStack1.setIsTranslucent(false);
401 fullscreenStack2.setIsTranslucent(false);
402
403 // Ensure we don't move the home stack behind itself
404 int homeStackIndex = display.getIndexOf(homeStack);
405 display.moveHomeStackBehindStack(homeStack);
406 assertTrue(display.getIndexOf(homeStack) == homeStackIndex);
407 }
408
409 @Test
410 public void testMoveHomeStackBehindStack() {
411 final ActivityDisplay display = mService.mStackSupervisor.getDefaultDisplay();
412 display.removeChild(mStack);
413
414 final TestActivityStack fullscreenStack1 = createStackForShouldBeVisibleTest(display,
415 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
416 final TestActivityStack fullscreenStack2 = createStackForShouldBeVisibleTest(display,
417 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
Winson Chung123e07a2018-02-27 11:47:16 -0800418 final TestActivityStack fullscreenStack3 = createStackForShouldBeVisibleTest(display,
419 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
420 final TestActivityStack fullscreenStack4 = createStackForShouldBeVisibleTest(display,
421 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
Winson Chungd922b6b2018-02-16 16:41:50 -0800422 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(display,
423 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
424
425 display.moveHomeStackBehindStack(fullscreenStack1);
426 assertTrue(display.getStackAboveHome() == fullscreenStack1);
427 display.moveHomeStackBehindStack(fullscreenStack2);
428 assertTrue(display.getStackAboveHome() == fullscreenStack2);
Winson Chung123e07a2018-02-27 11:47:16 -0800429 display.moveHomeStackBehindStack(fullscreenStack4);
430 assertTrue(display.getStackAboveHome() == fullscreenStack4);
431 display.moveHomeStackBehindStack(fullscreenStack2);
432 assertTrue(display.getStackAboveHome() == fullscreenStack2);
Winson Chungd922b6b2018-02-16 16:41:50 -0800433 }
434
Wale Ogunwalebb285872018-03-01 13:05:30 -0800435 @Test
436 public void testSplitScreenMoveToFront() throws Exception {
437 final ActivityDisplay display = mService.mStackSupervisor.getDefaultDisplay();
438 final TestActivityStack splitScreenPrimary = createStackForShouldBeVisibleTest(display,
439 WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD, true /* onTop */);
440 final TestActivityStack splitScreenSecondary = createStackForShouldBeVisibleTest(display,
441 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD, true /* onTop */);
442 final TestActivityStack assistantStack = createStackForShouldBeVisibleTest(display,
443 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_ASSISTANT, true /* onTop */);
444
445 splitScreenPrimary.setIsTranslucent(false);
446 splitScreenSecondary.setIsTranslucent(false);
447 assistantStack.setIsTranslucent(false);
448
449 assertFalse(splitScreenPrimary.shouldBeVisible(null /* starting */));
450 assertFalse(splitScreenSecondary.shouldBeVisible(null /* starting */));
451 assertTrue(assistantStack.shouldBeVisible(null /* starting */));
452
453 splitScreenSecondary.moveToFront("testSplitScreenMoveToFront");
454
455 assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */));
456 assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
457 assertFalse(assistantStack.shouldBeVisible(null /* starting */));
458 }
459
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700460 private <T extends ActivityStack> T createStackForShouldBeVisibleTest(
461 ActivityDisplay display, int windowingMode, int activityType, boolean onTop) {
462 final T stack = display.createStack(windowingMode, activityType, onTop);
Bryce Lee18d51592017-10-25 10:22:19 -0700463 final ActivityRecord r = new ActivityBuilder(mService).setUid(0).setStack(stack)
464 .setCreateTask(true).build();
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700465 return stack;
466 }
Bryce Leeb0f993f2018-03-02 15:38:01 -0800467
468 @Test
469 public void testSuppressMultipleDestroy() throws Exception {
470 final ActivityRecord r = new ActivityBuilder(mService).setTask(mTask).build();
471 final ClientLifecycleManager lifecycleManager = mock(ClientLifecycleManager.class);
472 final ProcessRecord app = r.app;
473
474 // The mocked lifecycle manager must be set on the ActivityStackSupervisor's reference to
475 // the service rather than mService as mService is a spy and setting the value will not
476 // propagate as ActivityManagerService hands its own reference to the
477 // ActivityStackSupervisor during construction.
478 ((TestActivityManagerService) mSupervisor.mService).setLifecycleManager(lifecycleManager);
479
480 mStack.destroyActivityLocked(r, true, "first invocation");
481 verify(lifecycleManager, times(1)).scheduleTransaction(eq(app.thread),
482 eq(r.appToken), any(DestroyActivityItem.class));
483 assertTrue(r.isState(DESTROYED, DESTROYING));
484
485 mStack.destroyActivityLocked(r, true, "second invocation");
486 verify(lifecycleManager, times(1)).scheduleTransaction(eq(app.thread),
487 eq(r.appToken), any(DestroyActivityItem.class));
488 }
Bryce Leefbd263b42018-03-07 10:33:55 -0800489
490 @Test
491 public void testFinishDisabledPackageActivities() throws Exception {
492 final ActivityRecord firstActivity = new ActivityBuilder(mService).setTask(mTask).build();
493 final ActivityRecord secondActivity = new ActivityBuilder(mService).setTask(mTask).build();
494
495 // Making the second activity a task overlay without an app means it will be removed from
496 // the task's activities as well once first activity is removed.
497 secondActivity.mTaskOverlay = true;
498 secondActivity.app = null;
499
500 assertEquals(mTask.mActivities.size(), 2);
501
502 mStack.finishDisabledPackageActivitiesLocked(firstActivity.packageName, null,
503 true /* doit */, true /* evenPersistent */, UserHandle.USER_ALL);
504
505 assertTrue(mTask.mActivities.isEmpty());
506 assertTrue(mStack.getAllTasks().isEmpty());
507 }
508
509 @Test
510 public void testHandleAppDied() throws Exception {
511 final ActivityRecord firstActivity = new ActivityBuilder(mService).setTask(mTask).build();
512 final ActivityRecord secondActivity = new ActivityBuilder(mService).setTask(mTask).build();
513
514 // Making the first activity a task overlay means it will be removed from the task's
515 // activities as well once second activity is removed as handleAppDied processes the
516 // activity list in reverse.
517 firstActivity.mTaskOverlay = true;
518 firstActivity.app = null;
519
520 // second activity will be immediately removed as it has no state.
521 secondActivity.haveState = false;
522
523 assertEquals(mTask.mActivities.size(), 2);
524
525 mStack.handleAppDiedLocked(secondActivity.app);
526
527 assertTrue(mTask.mActivities.isEmpty());
528 assertTrue(mStack.getAllTasks().isEmpty());
529 }
Bryce Lee840c5662017-04-13 10:02:51 -0700530}