blob: 1a95fdd0b62c6e4b86c14323ec86d144ad4b3433 [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
101 public void testNoPauseDuringResumeTopActivity() throws Exception {
Bryce Lee18d51592017-10-25 10:22:19 -0700102 final ActivityRecord r = new ActivityBuilder(mService).setTask(mTask).build();
Bryce Lee5daa3122017-04-19 10:40:42 -0700103
104 // Simulate the a resumed activity set during
105 // {@link ActivityStack#resumeTopActivityUncheckedLocked}.
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700106 mSupervisor.inResumeTopActivity = true;
Bryce Leec4ab62a2018-03-05 14:19:26 -0800107 r.setState(RESUMED, "testNoPauseDuringResumeTopActivity");
Bryce Lee5daa3122017-04-19 10:40:42 -0700108
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700109 final boolean waiting = mStack.goToSleepIfPossible(false);
Bryce Lee5daa3122017-04-19 10:40:42 -0700110
111 // Ensure we report not being ready for sleep.
David Stevens18abd0e2017-08-17 14:55:47 -0700112 assertFalse(waiting);
Bryce Lee5daa3122017-04-19 10:40:42 -0700113
114 // Make sure the resumed activity is untouched.
Bryce Leec4ab62a2018-03-05 14:19:26 -0800115 assertEquals(mStack.getResumedActivity(), r);
116 }
117
118 @Test
119 public void testResumedActivity() throws Exception {
120 final ActivityRecord r = new ActivityBuilder(mService).setTask(mTask).build();
121 assertEquals(mStack.getResumedActivity(), null);
122 r.setState(RESUMED, "testResumedActivity");
123 assertEquals(mStack.getResumedActivity(), r);
124 r.setState(PAUSING, "testResumedActivity");
125 assertEquals(mStack.getResumedActivity(), null);
126
Bryce Lee5daa3122017-04-19 10:40:42 -0700127 }
Bryce Lee3345c4e2017-04-25 07:40:41 -0700128
129 @Test
Bryce Lee8cab4a02018-01-05 09:00:49 -0800130 public void testPrimarySplitScreenToFullscreenWhenMovedToBack() throws Exception {
131 // Create primary splitscreen stack. This will create secondary stacks and places the
132 // existing fullscreen stack on the bottom.
133 final ActivityStack primarySplitScreen = mService.mStackSupervisor.getDefaultDisplay()
134 .createStack(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD,
135 true /* onTop */);
136
137 // Assert windowing mode.
138 assertEquals(primarySplitScreen.getWindowingMode(), WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
139
140 // Move primary to back.
141 primarySplitScreen.moveToBack("testPrimarySplitScreenToFullscreenWhenMovedToBack",
142 null /* task */);
143
144 // Assert that stack is at the bottom.
145 assertEquals(mService.mStackSupervisor.getDefaultDisplay().getIndexOf(primarySplitScreen),
146 0);
147
148 // Ensure no longer in splitscreen.
149 assertEquals(primarySplitScreen.getWindowingMode(), WINDOWING_MODE_FULLSCREEN);
150 }
151
152 @Test
Bryce Lee3345c4e2017-04-25 07:40:41 -0700153 public void testStopActivityWhenActivityDestroyed() throws Exception {
Bryce Lee18d51592017-10-25 10:22:19 -0700154 final ActivityRecord r = new ActivityBuilder(mService).setTask(mTask).build();
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700155 r.info.flags |= ActivityInfo.FLAG_NO_HISTORY;
156 mSupervisor.setFocusStackUnchecked("testStopActivityWithDestroy", mStack);
157 mStack.stopActivityLocked(r);
158 // Mostly testing to make sure there is a crash in the call part, so if we get here we are
159 // good-to-go!
Bryce Lee3345c4e2017-04-25 07:40:41 -0700160 }
Bryce Lee9f6affd2017-09-01 09:18:35 -0700161
162 @Test
163 public void testFindTaskWithOverlay() throws Exception {
Bryce Lee18d51592017-10-25 10:22:19 -0700164 final ActivityRecord r = new ActivityBuilder(mService)
165 .setCreateTask(true)
166 .setStack(mStack)
167 .setUid(0)
168 .build();
169 final TaskRecord task = r.getTask();
Bryce Lee9f6affd2017-09-01 09:18:35 -0700170 // Overlay must be for a different user to prevent recognizing a matching top activity
Bryce Lee18d51592017-10-25 10:22:19 -0700171 final ActivityRecord taskOverlay = new ActivityBuilder(mService).setTask(task)
172 .setUid(UserHandle.PER_USER_RANGE * 2).build();
Bryce Lee9f6affd2017-09-01 09:18:35 -0700173 taskOverlay.mTaskOverlay = true;
174
Bryce Lee9f6affd2017-09-01 09:18:35 -0700175 final ActivityStackSupervisor.FindTaskResult result =
176 new ActivityStackSupervisor.FindTaskResult();
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700177 mStack.findTaskLocked(r, result);
Bryce Lee9f6affd2017-09-01 09:18:35 -0700178
Bryce Lee18d51592017-10-25 10:22:19 -0700179 assertEquals(task.getTopActivity(false /* includeOverlays */), r);
180 assertEquals(task.getTopActivity(true /* includeOverlays */), taskOverlay);
Bryce Lee9f6affd2017-09-01 09:18:35 -0700181 assertNotNull(result.r);
182 }
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700183
184 @Test
185 public void testShouldBeVisible_Fullscreen() throws Exception {
186 final ActivityDisplay display = mService.mStackSupervisor.getDefaultDisplay();
187 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(display,
188 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
189 final ActivityStack pinnedStack = createStackForShouldBeVisibleTest(display,
190 WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, true /* onTop */);
191
192 assertTrue(homeStack.shouldBeVisible(null /* starting */));
193 assertTrue(pinnedStack.shouldBeVisible(null /* starting */));
194
195 final TestActivityStack fullscreenStack = createStackForShouldBeVisibleTest(display,
196 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
197 // Home stack shouldn't be visible behind an opaque fullscreen stack, but pinned stack
198 // should be visible since it is always on-top.
199 fullscreenStack.setIsTranslucent(false);
200 assertFalse(homeStack.shouldBeVisible(null /* starting */));
201 assertTrue(pinnedStack.shouldBeVisible(null /* starting */));
202 assertTrue(fullscreenStack.shouldBeVisible(null /* starting */));
203
204 // Home stack should be visible behind a translucent fullscreen stack.
205 fullscreenStack.setIsTranslucent(true);
206 assertTrue(homeStack.shouldBeVisible(null /* starting */));
207 assertTrue(pinnedStack.shouldBeVisible(null /* starting */));
208 }
209
210 @Test
211 public void testShouldBeVisible_SplitScreen() throws Exception {
212 final ActivityDisplay display = mService.mStackSupervisor.getDefaultDisplay();
213 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(display,
214 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
Wale Ogunwale30e441d2017-11-09 08:28:45 -0800215 // Home stack should always be fullscreen for this test.
216 homeStack.setSupportsSplitScreen(false);
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700217 final TestActivityStack splitScreenPrimary = createStackForShouldBeVisibleTest(display,
218 WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD, true /* onTop */);
219 final TestActivityStack splitScreenSecondary = createStackForShouldBeVisibleTest(display,
220 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD, true /* onTop */);
221
222 // Home stack shouldn't be visible if both halves of split-screen are opaque.
223 splitScreenPrimary.setIsTranslucent(false);
224 splitScreenSecondary.setIsTranslucent(false);
225 assertFalse(homeStack.shouldBeVisible(null /* starting */));
226 assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */));
227 assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
228
229 // Home stack should be visible if one of the halves of split-screen is translucent.
230 splitScreenPrimary.setIsTranslucent(true);
231 assertTrue(homeStack.shouldBeVisible(null /* starting */));
232 assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */));
233 assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
234
235 final TestActivityStack splitScreenSecondary2 = createStackForShouldBeVisibleTest(display,
236 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD, true /* onTop */);
237 // First split-screen secondary shouldn't be visible behind another opaque split-split
238 // secondary.
239 splitScreenSecondary2.setIsTranslucent(false);
240 assertFalse(splitScreenSecondary.shouldBeVisible(null /* starting */));
241 assertTrue(splitScreenSecondary2.shouldBeVisible(null /* starting */));
242
243 // First split-screen secondary should be visible behind another translucent split-split
244 // secondary.
245 splitScreenSecondary2.setIsTranslucent(true);
246 assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
247 assertTrue(splitScreenSecondary2.shouldBeVisible(null /* starting */));
248
249 final TestActivityStack assistantStack = createStackForShouldBeVisibleTest(display,
250 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_ASSISTANT, true /* onTop */);
251
252 // Split-screen stacks shouldn't be visible behind an opaque fullscreen stack.
253 assistantStack.setIsTranslucent(false);
254 assertTrue(assistantStack.shouldBeVisible(null /* starting */));
255 assertFalse(splitScreenPrimary.shouldBeVisible(null /* starting */));
256 assertFalse(splitScreenSecondary.shouldBeVisible(null /* starting */));
257 assertFalse(splitScreenSecondary2.shouldBeVisible(null /* starting */));
258
259 // Split-screen stacks should be visible behind a translucent fullscreen stack.
260 assistantStack.setIsTranslucent(true);
261 assertTrue(assistantStack.shouldBeVisible(null /* starting */));
262 assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */));
263 assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
264 assertTrue(splitScreenSecondary2.shouldBeVisible(null /* starting */));
265 }
266
267 @Test
268 public void testShouldBeVisible_Finishing() throws Exception {
269 final ActivityDisplay display = mService.mStackSupervisor.getDefaultDisplay();
270 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(display,
271 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
272 final TestActivityStack translucentStack = createStackForShouldBeVisibleTest(display,
273 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
274 translucentStack.setIsTranslucent(true);
275
276 assertTrue(homeStack.shouldBeVisible(null /* starting */));
277 assertTrue(translucentStack.shouldBeVisible(null /* starting */));
278
279 final ActivityRecord topRunningHomeActivity = homeStack.topRunningActivityLocked();
280 topRunningHomeActivity.finishing = true;
281 final ActivityRecord topRunningTranslucentActivity =
282 translucentStack.topRunningActivityLocked();
283 topRunningTranslucentActivity.finishing = true;
284
285 // Home shouldn't be visible since its activity is marked as finishing and it isn't the top
286 // of the stack list.
287 assertFalse(homeStack.shouldBeVisible(null /* starting */));
288 // Home should be visible if we are starting an activity within it.
289 assertTrue(homeStack.shouldBeVisible(topRunningHomeActivity /* starting */));
290 // The translucent stack should be visible since it is the top of the stack list even though
291 // it has its activity marked as finishing.
292 assertTrue(translucentStack.shouldBeVisible(null /* starting */));
293 }
294
Winson Chungd922b6b2018-02-16 16:41:50 -0800295 @Test
296 public void testMoveHomeStackBehindBottomMostVisibleStack_NoMoveHomeBehindFullscreen() {
297 final ActivityDisplay display = mService.mStackSupervisor.getDefaultDisplay();
298 display.removeChild(mStack);
299
300 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(display,
301 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
302 final TestActivityStack fullscreenStack = createStackForShouldBeVisibleTest(display,
303 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
304
305 homeStack.setIsTranslucent(false);
306 fullscreenStack.setIsTranslucent(false);
307
308 // Ensure that we don't move the home stack if it is already behind the top fullscreen stack
309 int homeStackIndex = display.getIndexOf(homeStack);
310 assertTrue(display.getStackAboveHome() == fullscreenStack);
311 display.moveHomeStackBehindBottomMostVisibleStack();
312 assertTrue(display.getIndexOf(homeStack) == homeStackIndex);
313 }
314
315 @Test
316 public void testMoveHomeStackBehindBottomMostVisibleStack_NoMoveHomeBehindTranslucent() {
317 final ActivityDisplay display = mService.mStackSupervisor.getDefaultDisplay();
318 display.removeChild(mStack);
319
320 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(display,
321 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
322 final TestActivityStack fullscreenStack = createStackForShouldBeVisibleTest(display,
323 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
324
325 homeStack.setIsTranslucent(false);
326 fullscreenStack.setIsTranslucent(true);
327
328 // Ensure that we don't move the home stack if it is already behind the top fullscreen stack
329 int homeStackIndex = display.getIndexOf(homeStack);
330 assertTrue(display.getStackAboveHome() == fullscreenStack);
331 display.moveHomeStackBehindBottomMostVisibleStack();
332 assertTrue(display.getIndexOf(homeStack) == homeStackIndex);
333 }
334
335 @Test
336 public void testMoveHomeStackBehindBottomMostVisibleStack_NoMoveHomeOnTop() {
337 final ActivityDisplay display = mService.mStackSupervisor.getDefaultDisplay();
338 display.removeChild(mStack);
339
340 final TestActivityStack fullscreenStack = createStackForShouldBeVisibleTest(display,
341 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
342 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(display,
343 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
344
345 homeStack.setIsTranslucent(false);
346 fullscreenStack.setIsTranslucent(false);
347
348 // Ensure we don't move the home stack if it is already on top
349 int homeStackIndex = display.getIndexOf(homeStack);
350 assertTrue(display.getStackAboveHome() == null);
351 display.moveHomeStackBehindBottomMostVisibleStack();
352 assertTrue(display.getIndexOf(homeStack) == homeStackIndex);
353 }
354
355 @Test
356 public void testMoveHomeStackBehindBottomMostVisibleStack_MoveHomeBehindFullscreen() {
357 final ActivityDisplay display = mService.mStackSupervisor.getDefaultDisplay();
358 display.removeChild(mStack);
359
360 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(display,
361 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
362 final TestActivityStack fullscreenStack1 = createStackForShouldBeVisibleTest(display,
363 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
364 final TestActivityStack fullscreenStack2 = createStackForShouldBeVisibleTest(display,
365 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
366 final TestActivityStack pinnedStack = createStackForShouldBeVisibleTest(display,
367 WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, true /* onTop */);
368
369 homeStack.setIsTranslucent(false);
370 fullscreenStack1.setIsTranslucent(false);
371 fullscreenStack2.setIsTranslucent(false);
372
373 // Ensure that we move the home stack behind the bottom most fullscreen stack, ignoring the
374 // pinned stack
375 assertTrue(display.getStackAboveHome() == fullscreenStack1);
376 display.moveHomeStackBehindBottomMostVisibleStack();
377 assertTrue(display.getStackAboveHome() == fullscreenStack2);
378 }
379
380 @Test
381 public void testMoveHomeStackBehindBottomMostVisibleStack_MoveHomeBehindFullscreenAndTranslucent() {
382 final ActivityDisplay display = mService.mStackSupervisor.getDefaultDisplay();
383 display.removeChild(mStack);
384
385 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(display,
386 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
387 final TestActivityStack fullscreenStack1 = createStackForShouldBeVisibleTest(display,
388 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
389 final TestActivityStack fullscreenStack2 = createStackForShouldBeVisibleTest(display,
390 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
391
392 homeStack.setIsTranslucent(false);
393 fullscreenStack1.setIsTranslucent(false);
394 fullscreenStack2.setIsTranslucent(true);
395
396 // Ensure that we move the home stack behind the bottom most non-translucent fullscreen
397 // stack
398 assertTrue(display.getStackAboveHome() == fullscreenStack1);
399 display.moveHomeStackBehindBottomMostVisibleStack();
400 assertTrue(display.getStackAboveHome() == fullscreenStack1);
401 }
402
403 @Test
404 public void testMoveHomeStackBehindStack_BehindHomeStack() {
405 final ActivityDisplay display = mService.mStackSupervisor.getDefaultDisplay();
406 display.removeChild(mStack);
407
408 final TestActivityStack fullscreenStack1 = createStackForShouldBeVisibleTest(display,
409 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
410 final TestActivityStack fullscreenStack2 = createStackForShouldBeVisibleTest(display,
411 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
412 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(display,
413 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
414
415 homeStack.setIsTranslucent(false);
416 fullscreenStack1.setIsTranslucent(false);
417 fullscreenStack2.setIsTranslucent(false);
418
419 // Ensure we don't move the home stack behind itself
420 int homeStackIndex = display.getIndexOf(homeStack);
421 display.moveHomeStackBehindStack(homeStack);
422 assertTrue(display.getIndexOf(homeStack) == homeStackIndex);
423 }
424
425 @Test
426 public void testMoveHomeStackBehindStack() {
427 final ActivityDisplay display = mService.mStackSupervisor.getDefaultDisplay();
428 display.removeChild(mStack);
429
430 final TestActivityStack fullscreenStack1 = createStackForShouldBeVisibleTest(display,
431 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
432 final TestActivityStack fullscreenStack2 = createStackForShouldBeVisibleTest(display,
433 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
Winson Chung123e07a2018-02-27 11:47:16 -0800434 final TestActivityStack fullscreenStack3 = createStackForShouldBeVisibleTest(display,
435 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
436 final TestActivityStack fullscreenStack4 = createStackForShouldBeVisibleTest(display,
437 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
Winson Chungd922b6b2018-02-16 16:41:50 -0800438 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(display,
439 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
440
441 display.moveHomeStackBehindStack(fullscreenStack1);
442 assertTrue(display.getStackAboveHome() == fullscreenStack1);
443 display.moveHomeStackBehindStack(fullscreenStack2);
444 assertTrue(display.getStackAboveHome() == fullscreenStack2);
Winson Chung123e07a2018-02-27 11:47:16 -0800445 display.moveHomeStackBehindStack(fullscreenStack4);
446 assertTrue(display.getStackAboveHome() == fullscreenStack4);
447 display.moveHomeStackBehindStack(fullscreenStack2);
448 assertTrue(display.getStackAboveHome() == fullscreenStack2);
Winson Chungd922b6b2018-02-16 16:41:50 -0800449 }
450
Wale Ogunwalebb285872018-03-01 13:05:30 -0800451 @Test
452 public void testSplitScreenMoveToFront() throws Exception {
453 final ActivityDisplay display = mService.mStackSupervisor.getDefaultDisplay();
454 final TestActivityStack splitScreenPrimary = createStackForShouldBeVisibleTest(display,
455 WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD, true /* onTop */);
456 final TestActivityStack splitScreenSecondary = createStackForShouldBeVisibleTest(display,
457 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD, true /* onTop */);
458 final TestActivityStack assistantStack = createStackForShouldBeVisibleTest(display,
459 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_ASSISTANT, true /* onTop */);
460
461 splitScreenPrimary.setIsTranslucent(false);
462 splitScreenSecondary.setIsTranslucent(false);
463 assistantStack.setIsTranslucent(false);
464
465 assertFalse(splitScreenPrimary.shouldBeVisible(null /* starting */));
466 assertFalse(splitScreenSecondary.shouldBeVisible(null /* starting */));
467 assertTrue(assistantStack.shouldBeVisible(null /* starting */));
468
469 splitScreenSecondary.moveToFront("testSplitScreenMoveToFront");
470
471 assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */));
472 assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
473 assertFalse(assistantStack.shouldBeVisible(null /* starting */));
474 }
475
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700476 private <T extends ActivityStack> T createStackForShouldBeVisibleTest(
477 ActivityDisplay display, int windowingMode, int activityType, boolean onTop) {
478 final T stack = display.createStack(windowingMode, activityType, onTop);
Bryce Lee18d51592017-10-25 10:22:19 -0700479 final ActivityRecord r = new ActivityBuilder(mService).setUid(0).setStack(stack)
480 .setCreateTask(true).build();
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700481 return stack;
482 }
Bryce Leeb0f993f2018-03-02 15:38:01 -0800483
484 @Test
Bryce Leefbd263b42018-03-07 10:33:55 -0800485 public void testFinishDisabledPackageActivities() throws Exception {
486 final ActivityRecord firstActivity = new ActivityBuilder(mService).setTask(mTask).build();
487 final ActivityRecord secondActivity = new ActivityBuilder(mService).setTask(mTask).build();
488
489 // Making the second activity a task overlay without an app means it will be removed from
490 // the task's activities as well once first activity is removed.
491 secondActivity.mTaskOverlay = true;
492 secondActivity.app = null;
493
494 assertEquals(mTask.mActivities.size(), 2);
495
496 mStack.finishDisabledPackageActivitiesLocked(firstActivity.packageName, null,
497 true /* doit */, true /* evenPersistent */, UserHandle.USER_ALL);
498
499 assertTrue(mTask.mActivities.isEmpty());
500 assertTrue(mStack.getAllTasks().isEmpty());
501 }
502
503 @Test
504 public void testHandleAppDied() throws Exception {
505 final ActivityRecord firstActivity = new ActivityBuilder(mService).setTask(mTask).build();
506 final ActivityRecord secondActivity = new ActivityBuilder(mService).setTask(mTask).build();
507
508 // Making the first activity a task overlay means it will be removed from the task's
509 // activities as well once second activity is removed as handleAppDied processes the
510 // activity list in reverse.
511 firstActivity.mTaskOverlay = true;
512 firstActivity.app = null;
513
514 // second activity will be immediately removed as it has no state.
515 secondActivity.haveState = false;
516
517 assertEquals(mTask.mActivities.size(), 2);
518
519 mStack.handleAppDiedLocked(secondActivity.app);
520
521 assertTrue(mTask.mActivities.isEmpty());
522 assertTrue(mStack.getAllTasks().isEmpty());
523 }
Bryce Lee271617a2018-03-15 10:39:12 -0700524
525 @Test
526 public void testShouldSleepActivities() throws Exception {
527 // When focused activity and keyguard is going away, we should not sleep regardless
528 // of the display state
529 verifyShouldSleepActivities(true /* focusedStack */, true /*keyguardGoingAway*/,
530 true /* displaySleeping */, false /* expected*/);
531
532 // When not the focused stack, defer to display sleeping state.
533 verifyShouldSleepActivities(false /* focusedStack */, true /*keyguardGoingAway*/,
534 true /* displaySleeping */, true /* expected*/);
535
536 // If keyguard is going away, defer to the display sleeping state.
537 verifyShouldSleepActivities(true /* focusedStack */, false /*keyguardGoingAway*/,
538 true /* displaySleeping */, true /* expected*/);
539 verifyShouldSleepActivities(true /* focusedStack */, false /*keyguardGoingAway*/,
540 false /* displaySleeping */, false /* expected*/);
541 }
542
543 private void verifyShouldSleepActivities(boolean focusedStack,
544 boolean keyguardGoingAway, boolean displaySleeping, boolean expected) {
545 mSupervisor.mFocusedStack = focusedStack ? mStack : null;
546
547 final ActivityDisplay display = mock(ActivityDisplay.class);
548 final KeyguardController keyguardController = mSupervisor.getKeyguardController();
549
550 doReturn(display).when(mSupervisor).getActivityDisplay(anyInt());
551 doReturn(keyguardGoingAway).when(keyguardController).isKeyguardGoingAway();
552 doReturn(displaySleeping).when(display).isSleeping();
553
554 assertEquals(expected, mStack.shouldSleepActivities());
555 }
556
Bryce Lee840c5662017-04-13 10:02:51 -0700557}