blob: 08158ec9c84465a1733c4fc986b2dcf69a81cc8d [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;
Bryce Leec4ab62a2018-03-05 14:19:26 -080029import static com.android.server.am.ActivityStack.ActivityState.PAUSING;
30import static com.android.server.am.ActivityStack.ActivityState.RESUMED;
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070031import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_DESTROYING;
Bryce Lee18d51592017-10-25 10:22:19 -070032
Bryce Lee5daa3122017-04-19 10:40:42 -070033import static org.junit.Assert.assertEquals;
David Stevens18abd0e2017-08-17 14:55:47 -070034import static org.junit.Assert.assertFalse;
Bryce Lee840c5662017-04-13 10:02:51 -070035import static org.junit.Assert.assertNotNull;
36import static org.junit.Assert.assertNull;
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -070037import static org.junit.Assert.assertTrue;
Bryce Leeb0f993f2018-03-02 15:38:01 -080038import static org.mockito.ArgumentMatchers.any;
39import static org.mockito.ArgumentMatchers.eq;
Bryce Lee271617a2018-03-15 10:39:12 -070040import static org.mockito.Mockito.anyInt;
41import static org.mockito.Mockito.doReturn;
Bryce Leeb0f993f2018-03-02 15:38:01 -080042import static org.mockito.Mockito.mock;
43import static org.mockito.Mockito.times;
44import static org.mockito.Mockito.verify;
Bryce Lee840c5662017-04-13 10:02:51 -070045
Bryce Leeb0f993f2018-03-02 15:38:01 -080046import android.app.servertransaction.DestroyActivityItem;
Bryce Lee3345c4e2017-04-25 07:40:41 -070047import android.content.pm.ActivityInfo;
Bryce Lee271617a2018-03-15 10:39:12 -070048import android.os.Debug;
Bryce Lee9f6affd2017-09-01 09:18:35 -070049import android.os.UserHandle;
Bryce Lee840c5662017-04-13 10:02:51 -070050import android.platform.test.annotations.Presubmit;
51import android.support.test.filters.SmallTest;
52import android.support.test.runner.AndroidJUnit4;
53
54import org.junit.runner.RunWith;
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070055import org.junit.Before;
Bryce Lee840c5662017-04-13 10:02:51 -070056import org.junit.Test;
57
58/**
59 * Tests for the {@link ActivityStack} class.
60 *
61 * Build/Install/Run:
Wale Ogunwalebb285872018-03-01 13:05:30 -080062 * atest FrameworksServicesTests:com.android.server.am.ActivityStackTests
Bryce Lee840c5662017-04-13 10:02:51 -070063 */
64@SmallTest
65@Presubmit
66@RunWith(AndroidJUnit4.class)
67public class ActivityStackTests extends ActivityTestsBase {
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070068 private ActivityManagerService mService;
69 private ActivityStackSupervisor mSupervisor;
70 private ActivityStack mStack;
71 private TaskRecord mTask;
72
73 @Before
74 @Override
75 public void setUp() throws Exception {
76 super.setUp();
77
78 mService = createActivityManagerService();
79 mSupervisor = mService.mStackSupervisor;
80 mStack = mService.mStackSupervisor.getDefaultDisplay().createStack(
81 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
Bryce Lee18d51592017-10-25 10:22:19 -070082 mTask = new TaskBuilder(mSupervisor).setStack(mStack).build();
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070083 }
84
Bryce Lee840c5662017-04-13 10:02:51 -070085 @Test
86 public void testEmptyTaskCleanupOnRemove() throws Exception {
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070087 assertNotNull(mTask.getWindowContainerController());
88 mStack.removeTask(mTask, "testEmptyTaskCleanupOnRemove", REMOVE_TASK_MODE_DESTROYING);
89 assertNull(mTask.getWindowContainerController());
Bryce Lee840c5662017-04-13 10:02:51 -070090 }
Bryce Lee5daa3122017-04-19 10:40:42 -070091
Bryce Lee840c5662017-04-13 10:02:51 -070092 @Test
93 public void testOccupiedTaskCleanupOnRemove() throws Exception {
Bryce Lee18d51592017-10-25 10:22:19 -070094 final ActivityRecord r = new ActivityBuilder(mService).setTask(mTask).build();
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070095 assertNotNull(mTask.getWindowContainerController());
96 mStack.removeTask(mTask, "testOccupiedTaskCleanupOnRemove", REMOVE_TASK_MODE_DESTROYING);
97 assertNotNull(mTask.getWindowContainerController());
Bryce Lee840c5662017-04-13 10:02:51 -070098 }
Bryce Lee5daa3122017-04-19 10:40:42 -070099
100 @Test
Bryce Leec4ab62a2018-03-05 14:19:26 -0800101 public void testResumedActivity() throws Exception {
102 final ActivityRecord r = new ActivityBuilder(mService).setTask(mTask).build();
103 assertEquals(mStack.getResumedActivity(), null);
104 r.setState(RESUMED, "testResumedActivity");
105 assertEquals(mStack.getResumedActivity(), r);
106 r.setState(PAUSING, "testResumedActivity");
107 assertEquals(mStack.getResumedActivity(), null);
108
Bryce Lee5daa3122017-04-19 10:40:42 -0700109 }
Bryce Lee3345c4e2017-04-25 07:40:41 -0700110
111 @Test
Bryce Lee8cab4a02018-01-05 09:00:49 -0800112 public void testPrimarySplitScreenToFullscreenWhenMovedToBack() throws Exception {
113 // Create primary splitscreen stack. This will create secondary stacks and places the
114 // existing fullscreen stack on the bottom.
115 final ActivityStack primarySplitScreen = mService.mStackSupervisor.getDefaultDisplay()
116 .createStack(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD,
117 true /* onTop */);
118
119 // Assert windowing mode.
120 assertEquals(primarySplitScreen.getWindowingMode(), WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
121
122 // Move primary to back.
123 primarySplitScreen.moveToBack("testPrimarySplitScreenToFullscreenWhenMovedToBack",
124 null /* task */);
125
126 // Assert that stack is at the bottom.
127 assertEquals(mService.mStackSupervisor.getDefaultDisplay().getIndexOf(primarySplitScreen),
128 0);
129
130 // Ensure no longer in splitscreen.
131 assertEquals(primarySplitScreen.getWindowingMode(), WINDOWING_MODE_FULLSCREEN);
132 }
133
134 @Test
Bryce Lee3345c4e2017-04-25 07:40:41 -0700135 public void testStopActivityWhenActivityDestroyed() throws Exception {
Bryce Lee18d51592017-10-25 10:22:19 -0700136 final ActivityRecord r = new ActivityBuilder(mService).setTask(mTask).build();
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700137 r.info.flags |= ActivityInfo.FLAG_NO_HISTORY;
138 mSupervisor.setFocusStackUnchecked("testStopActivityWithDestroy", mStack);
139 mStack.stopActivityLocked(r);
140 // Mostly testing to make sure there is a crash in the call part, so if we get here we are
141 // good-to-go!
Bryce Lee3345c4e2017-04-25 07:40:41 -0700142 }
Bryce Lee9f6affd2017-09-01 09:18:35 -0700143
144 @Test
145 public void testFindTaskWithOverlay() throws Exception {
Bryce Lee18d51592017-10-25 10:22:19 -0700146 final ActivityRecord r = new ActivityBuilder(mService)
147 .setCreateTask(true)
148 .setStack(mStack)
149 .setUid(0)
150 .build();
151 final TaskRecord task = r.getTask();
Bryce Lee9f6affd2017-09-01 09:18:35 -0700152 // Overlay must be for a different user to prevent recognizing a matching top activity
Bryce Lee18d51592017-10-25 10:22:19 -0700153 final ActivityRecord taskOverlay = new ActivityBuilder(mService).setTask(task)
154 .setUid(UserHandle.PER_USER_RANGE * 2).build();
Bryce Lee9f6affd2017-09-01 09:18:35 -0700155 taskOverlay.mTaskOverlay = true;
156
Bryce Lee9f6affd2017-09-01 09:18:35 -0700157 final ActivityStackSupervisor.FindTaskResult result =
158 new ActivityStackSupervisor.FindTaskResult();
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700159 mStack.findTaskLocked(r, result);
Bryce Lee9f6affd2017-09-01 09:18:35 -0700160
Bryce Lee18d51592017-10-25 10:22:19 -0700161 assertEquals(task.getTopActivity(false /* includeOverlays */), r);
162 assertEquals(task.getTopActivity(true /* includeOverlays */), taskOverlay);
Bryce Lee9f6affd2017-09-01 09:18:35 -0700163 assertNotNull(result.r);
164 }
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700165
166 @Test
167 public void testShouldBeVisible_Fullscreen() throws Exception {
168 final ActivityDisplay display = mService.mStackSupervisor.getDefaultDisplay();
169 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(display,
170 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
171 final ActivityStack pinnedStack = createStackForShouldBeVisibleTest(display,
172 WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, true /* onTop */);
173
174 assertTrue(homeStack.shouldBeVisible(null /* starting */));
175 assertTrue(pinnedStack.shouldBeVisible(null /* starting */));
176
177 final TestActivityStack fullscreenStack = createStackForShouldBeVisibleTest(display,
178 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
179 // Home stack shouldn't be visible behind an opaque fullscreen stack, but pinned stack
180 // should be visible since it is always on-top.
181 fullscreenStack.setIsTranslucent(false);
182 assertFalse(homeStack.shouldBeVisible(null /* starting */));
183 assertTrue(pinnedStack.shouldBeVisible(null /* starting */));
184 assertTrue(fullscreenStack.shouldBeVisible(null /* starting */));
185
186 // Home stack should be visible behind a translucent fullscreen stack.
187 fullscreenStack.setIsTranslucent(true);
188 assertTrue(homeStack.shouldBeVisible(null /* starting */));
189 assertTrue(pinnedStack.shouldBeVisible(null /* starting */));
190 }
191
192 @Test
193 public void testShouldBeVisible_SplitScreen() throws Exception {
194 final ActivityDisplay display = mService.mStackSupervisor.getDefaultDisplay();
195 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(display,
196 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
Wale Ogunwale30e441d2017-11-09 08:28:45 -0800197 // Home stack should always be fullscreen for this test.
198 homeStack.setSupportsSplitScreen(false);
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700199 final TestActivityStack splitScreenPrimary = createStackForShouldBeVisibleTest(display,
200 WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD, true /* onTop */);
201 final TestActivityStack splitScreenSecondary = createStackForShouldBeVisibleTest(display,
202 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD, true /* onTop */);
203
204 // Home stack shouldn't be visible if both halves of split-screen are opaque.
205 splitScreenPrimary.setIsTranslucent(false);
206 splitScreenSecondary.setIsTranslucent(false);
207 assertFalse(homeStack.shouldBeVisible(null /* starting */));
208 assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */));
209 assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
210
211 // Home stack should be visible if one of the halves of split-screen is translucent.
212 splitScreenPrimary.setIsTranslucent(true);
213 assertTrue(homeStack.shouldBeVisible(null /* starting */));
214 assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */));
215 assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
216
217 final TestActivityStack splitScreenSecondary2 = createStackForShouldBeVisibleTest(display,
218 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD, true /* onTop */);
219 // First split-screen secondary shouldn't be visible behind another opaque split-split
220 // secondary.
221 splitScreenSecondary2.setIsTranslucent(false);
222 assertFalse(splitScreenSecondary.shouldBeVisible(null /* starting */));
223 assertTrue(splitScreenSecondary2.shouldBeVisible(null /* starting */));
224
225 // First split-screen secondary should be visible behind another translucent split-split
226 // secondary.
227 splitScreenSecondary2.setIsTranslucent(true);
228 assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
229 assertTrue(splitScreenSecondary2.shouldBeVisible(null /* starting */));
230
231 final TestActivityStack assistantStack = createStackForShouldBeVisibleTest(display,
232 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_ASSISTANT, true /* onTop */);
233
234 // Split-screen stacks shouldn't be visible behind an opaque fullscreen stack.
235 assistantStack.setIsTranslucent(false);
236 assertTrue(assistantStack.shouldBeVisible(null /* starting */));
237 assertFalse(splitScreenPrimary.shouldBeVisible(null /* starting */));
238 assertFalse(splitScreenSecondary.shouldBeVisible(null /* starting */));
239 assertFalse(splitScreenSecondary2.shouldBeVisible(null /* starting */));
240
241 // Split-screen stacks should be visible behind a translucent fullscreen stack.
242 assistantStack.setIsTranslucent(true);
243 assertTrue(assistantStack.shouldBeVisible(null /* starting */));
244 assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */));
245 assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
246 assertTrue(splitScreenSecondary2.shouldBeVisible(null /* starting */));
247 }
248
249 @Test
250 public void testShouldBeVisible_Finishing() throws Exception {
251 final ActivityDisplay display = mService.mStackSupervisor.getDefaultDisplay();
252 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(display,
253 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
254 final TestActivityStack translucentStack = createStackForShouldBeVisibleTest(display,
255 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
256 translucentStack.setIsTranslucent(true);
257
258 assertTrue(homeStack.shouldBeVisible(null /* starting */));
259 assertTrue(translucentStack.shouldBeVisible(null /* starting */));
260
261 final ActivityRecord topRunningHomeActivity = homeStack.topRunningActivityLocked();
262 topRunningHomeActivity.finishing = true;
263 final ActivityRecord topRunningTranslucentActivity =
264 translucentStack.topRunningActivityLocked();
265 topRunningTranslucentActivity.finishing = true;
266
267 // Home shouldn't be visible since its activity is marked as finishing and it isn't the top
268 // of the stack list.
269 assertFalse(homeStack.shouldBeVisible(null /* starting */));
270 // Home should be visible if we are starting an activity within it.
271 assertTrue(homeStack.shouldBeVisible(topRunningHomeActivity /* starting */));
272 // The translucent stack should be visible since it is the top of the stack list even though
273 // it has its activity marked as finishing.
274 assertTrue(translucentStack.shouldBeVisible(null /* starting */));
275 }
276
Winson Chungd922b6b2018-02-16 16:41:50 -0800277 @Test
278 public void testMoveHomeStackBehindBottomMostVisibleStack_NoMoveHomeBehindFullscreen() {
279 final ActivityDisplay display = mService.mStackSupervisor.getDefaultDisplay();
280 display.removeChild(mStack);
281
282 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(display,
283 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
284 final TestActivityStack fullscreenStack = createStackForShouldBeVisibleTest(display,
285 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
286
287 homeStack.setIsTranslucent(false);
288 fullscreenStack.setIsTranslucent(false);
289
290 // Ensure that we don't move the home stack if it is already behind the top fullscreen stack
291 int homeStackIndex = display.getIndexOf(homeStack);
292 assertTrue(display.getStackAboveHome() == fullscreenStack);
293 display.moveHomeStackBehindBottomMostVisibleStack();
294 assertTrue(display.getIndexOf(homeStack) == homeStackIndex);
295 }
296
297 @Test
298 public void testMoveHomeStackBehindBottomMostVisibleStack_NoMoveHomeBehindTranslucent() {
299 final ActivityDisplay display = mService.mStackSupervisor.getDefaultDisplay();
300 display.removeChild(mStack);
301
302 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(display,
303 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
304 final TestActivityStack fullscreenStack = createStackForShouldBeVisibleTest(display,
305 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
306
307 homeStack.setIsTranslucent(false);
308 fullscreenStack.setIsTranslucent(true);
309
310 // Ensure that we don't move the home stack if it is already behind the top fullscreen stack
311 int homeStackIndex = display.getIndexOf(homeStack);
312 assertTrue(display.getStackAboveHome() == fullscreenStack);
313 display.moveHomeStackBehindBottomMostVisibleStack();
314 assertTrue(display.getIndexOf(homeStack) == homeStackIndex);
315 }
316
317 @Test
318 public void testMoveHomeStackBehindBottomMostVisibleStack_NoMoveHomeOnTop() {
319 final ActivityDisplay display = mService.mStackSupervisor.getDefaultDisplay();
320 display.removeChild(mStack);
321
322 final TestActivityStack fullscreenStack = createStackForShouldBeVisibleTest(display,
323 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
324 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(display,
325 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
326
327 homeStack.setIsTranslucent(false);
328 fullscreenStack.setIsTranslucent(false);
329
330 // Ensure we don't move the home stack if it is already on top
331 int homeStackIndex = display.getIndexOf(homeStack);
332 assertTrue(display.getStackAboveHome() == null);
333 display.moveHomeStackBehindBottomMostVisibleStack();
334 assertTrue(display.getIndexOf(homeStack) == homeStackIndex);
335 }
336
337 @Test
338 public void testMoveHomeStackBehindBottomMostVisibleStack_MoveHomeBehindFullscreen() {
339 final ActivityDisplay display = mService.mStackSupervisor.getDefaultDisplay();
340 display.removeChild(mStack);
341
342 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(display,
343 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
344 final TestActivityStack fullscreenStack1 = createStackForShouldBeVisibleTest(display,
345 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
346 final TestActivityStack fullscreenStack2 = createStackForShouldBeVisibleTest(display,
347 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
348 final TestActivityStack pinnedStack = createStackForShouldBeVisibleTest(display,
349 WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, true /* onTop */);
350
351 homeStack.setIsTranslucent(false);
352 fullscreenStack1.setIsTranslucent(false);
353 fullscreenStack2.setIsTranslucent(false);
354
355 // Ensure that we move the home stack behind the bottom most fullscreen stack, ignoring the
356 // pinned stack
357 assertTrue(display.getStackAboveHome() == fullscreenStack1);
358 display.moveHomeStackBehindBottomMostVisibleStack();
359 assertTrue(display.getStackAboveHome() == fullscreenStack2);
360 }
361
362 @Test
363 public void testMoveHomeStackBehindBottomMostVisibleStack_MoveHomeBehindFullscreenAndTranslucent() {
364 final ActivityDisplay display = mService.mStackSupervisor.getDefaultDisplay();
365 display.removeChild(mStack);
366
367 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(display,
368 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
369 final TestActivityStack fullscreenStack1 = createStackForShouldBeVisibleTest(display,
370 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
371 final TestActivityStack fullscreenStack2 = createStackForShouldBeVisibleTest(display,
372 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
373
374 homeStack.setIsTranslucent(false);
375 fullscreenStack1.setIsTranslucent(false);
376 fullscreenStack2.setIsTranslucent(true);
377
378 // Ensure that we move the home stack behind the bottom most non-translucent fullscreen
379 // stack
380 assertTrue(display.getStackAboveHome() == fullscreenStack1);
381 display.moveHomeStackBehindBottomMostVisibleStack();
382 assertTrue(display.getStackAboveHome() == fullscreenStack1);
383 }
384
385 @Test
386 public void testMoveHomeStackBehindStack_BehindHomeStack() {
387 final ActivityDisplay display = mService.mStackSupervisor.getDefaultDisplay();
388 display.removeChild(mStack);
389
390 final TestActivityStack fullscreenStack1 = createStackForShouldBeVisibleTest(display,
391 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
392 final TestActivityStack fullscreenStack2 = createStackForShouldBeVisibleTest(display,
393 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
394 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(display,
395 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
396
397 homeStack.setIsTranslucent(false);
398 fullscreenStack1.setIsTranslucent(false);
399 fullscreenStack2.setIsTranslucent(false);
400
401 // Ensure we don't move the home stack behind itself
402 int homeStackIndex = display.getIndexOf(homeStack);
403 display.moveHomeStackBehindStack(homeStack);
404 assertTrue(display.getIndexOf(homeStack) == homeStackIndex);
405 }
406
407 @Test
408 public void testMoveHomeStackBehindStack() {
409 final ActivityDisplay display = mService.mStackSupervisor.getDefaultDisplay();
410 display.removeChild(mStack);
411
412 final TestActivityStack fullscreenStack1 = createStackForShouldBeVisibleTest(display,
413 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
414 final TestActivityStack fullscreenStack2 = createStackForShouldBeVisibleTest(display,
415 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
Winson Chung123e07a2018-02-27 11:47:16 -0800416 final TestActivityStack fullscreenStack3 = createStackForShouldBeVisibleTest(display,
417 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
418 final TestActivityStack fullscreenStack4 = createStackForShouldBeVisibleTest(display,
419 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
Winson Chungd922b6b2018-02-16 16:41:50 -0800420 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(display,
421 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
422
423 display.moveHomeStackBehindStack(fullscreenStack1);
424 assertTrue(display.getStackAboveHome() == fullscreenStack1);
425 display.moveHomeStackBehindStack(fullscreenStack2);
426 assertTrue(display.getStackAboveHome() == fullscreenStack2);
Winson Chung123e07a2018-02-27 11:47:16 -0800427 display.moveHomeStackBehindStack(fullscreenStack4);
428 assertTrue(display.getStackAboveHome() == fullscreenStack4);
429 display.moveHomeStackBehindStack(fullscreenStack2);
430 assertTrue(display.getStackAboveHome() == fullscreenStack2);
Winson Chungd922b6b2018-02-16 16:41:50 -0800431 }
432
Wale Ogunwalebb285872018-03-01 13:05:30 -0800433 @Test
434 public void testSplitScreenMoveToFront() throws Exception {
435 final ActivityDisplay display = mService.mStackSupervisor.getDefaultDisplay();
436 final TestActivityStack splitScreenPrimary = createStackForShouldBeVisibleTest(display,
437 WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD, true /* onTop */);
438 final TestActivityStack splitScreenSecondary = createStackForShouldBeVisibleTest(display,
439 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD, true /* onTop */);
440 final TestActivityStack assistantStack = createStackForShouldBeVisibleTest(display,
441 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_ASSISTANT, true /* onTop */);
442
443 splitScreenPrimary.setIsTranslucent(false);
444 splitScreenSecondary.setIsTranslucent(false);
445 assistantStack.setIsTranslucent(false);
446
447 assertFalse(splitScreenPrimary.shouldBeVisible(null /* starting */));
448 assertFalse(splitScreenSecondary.shouldBeVisible(null /* starting */));
449 assertTrue(assistantStack.shouldBeVisible(null /* starting */));
450
451 splitScreenSecondary.moveToFront("testSplitScreenMoveToFront");
452
453 assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */));
454 assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
455 assertFalse(assistantStack.shouldBeVisible(null /* starting */));
456 }
457
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700458 private <T extends ActivityStack> T createStackForShouldBeVisibleTest(
459 ActivityDisplay display, int windowingMode, int activityType, boolean onTop) {
460 final T stack = display.createStack(windowingMode, activityType, onTop);
Bryce Lee18d51592017-10-25 10:22:19 -0700461 final ActivityRecord r = new ActivityBuilder(mService).setUid(0).setStack(stack)
462 .setCreateTask(true).build();
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700463 return stack;
464 }
Bryce Leeb0f993f2018-03-02 15:38:01 -0800465
466 @Test
Bryce Leefbd263b42018-03-07 10:33:55 -0800467 public void testFinishDisabledPackageActivities() throws Exception {
468 final ActivityRecord firstActivity = new ActivityBuilder(mService).setTask(mTask).build();
469 final ActivityRecord secondActivity = new ActivityBuilder(mService).setTask(mTask).build();
470
471 // Making the second activity a task overlay without an app means it will be removed from
472 // the task's activities as well once first activity is removed.
473 secondActivity.mTaskOverlay = true;
474 secondActivity.app = null;
475
476 assertEquals(mTask.mActivities.size(), 2);
477
478 mStack.finishDisabledPackageActivitiesLocked(firstActivity.packageName, null,
479 true /* doit */, true /* evenPersistent */, UserHandle.USER_ALL);
480
481 assertTrue(mTask.mActivities.isEmpty());
482 assertTrue(mStack.getAllTasks().isEmpty());
483 }
484
485 @Test
486 public void testHandleAppDied() throws Exception {
487 final ActivityRecord firstActivity = new ActivityBuilder(mService).setTask(mTask).build();
488 final ActivityRecord secondActivity = new ActivityBuilder(mService).setTask(mTask).build();
489
490 // Making the first activity a task overlay means it will be removed from the task's
491 // activities as well once second activity is removed as handleAppDied processes the
492 // activity list in reverse.
493 firstActivity.mTaskOverlay = true;
494 firstActivity.app = null;
495
496 // second activity will be immediately removed as it has no state.
497 secondActivity.haveState = false;
498
499 assertEquals(mTask.mActivities.size(), 2);
500
501 mStack.handleAppDiedLocked(secondActivity.app);
502
503 assertTrue(mTask.mActivities.isEmpty());
504 assertTrue(mStack.getAllTasks().isEmpty());
505 }
Bryce Lee271617a2018-03-15 10:39:12 -0700506
507 @Test
508 public void testShouldSleepActivities() throws Exception {
509 // When focused activity and keyguard is going away, we should not sleep regardless
510 // of the display state
511 verifyShouldSleepActivities(true /* focusedStack */, true /*keyguardGoingAway*/,
512 true /* displaySleeping */, false /* expected*/);
513
514 // When not the focused stack, defer to display sleeping state.
515 verifyShouldSleepActivities(false /* focusedStack */, true /*keyguardGoingAway*/,
516 true /* displaySleeping */, true /* expected*/);
517
518 // If keyguard is going away, defer to the display sleeping state.
519 verifyShouldSleepActivities(true /* focusedStack */, false /*keyguardGoingAway*/,
520 true /* displaySleeping */, true /* expected*/);
521 verifyShouldSleepActivities(true /* focusedStack */, false /*keyguardGoingAway*/,
522 false /* displaySleeping */, false /* expected*/);
523 }
524
525 private void verifyShouldSleepActivities(boolean focusedStack,
526 boolean keyguardGoingAway, boolean displaySleeping, boolean expected) {
527 mSupervisor.mFocusedStack = focusedStack ? mStack : null;
528
529 final ActivityDisplay display = mock(ActivityDisplay.class);
530 final KeyguardController keyguardController = mSupervisor.getKeyguardController();
531
532 doReturn(display).when(mSupervisor).getActivityDisplay(anyInt());
533 doReturn(keyguardGoingAway).when(keyguardController).isKeyguardGoingAway();
534 doReturn(displaySleeping).when(display).isSleeping();
535
536 assertEquals(expected, mStack.shouldSleepActivities());
537 }
538
Bryce Lee840c5662017-04-13 10:02:51 -0700539}