blob: 5c3a2b4e08c523ec01b9fdb04949715bdddddb6f [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;
40import static org.mockito.Mockito.mock;
41import static org.mockito.Mockito.times;
42import static org.mockito.Mockito.verify;
Bryce Lee840c5662017-04-13 10:02:51 -070043
Bryce Leeb0f993f2018-03-02 15:38:01 -080044import android.app.servertransaction.DestroyActivityItem;
Bryce Lee3345c4e2017-04-25 07:40:41 -070045import android.content.pm.ActivityInfo;
Bryce Lee9f6affd2017-09-01 09:18:35 -070046import android.os.UserHandle;
Bryce Lee840c5662017-04-13 10:02:51 -070047import android.platform.test.annotations.Presubmit;
48import android.support.test.filters.SmallTest;
49import android.support.test.runner.AndroidJUnit4;
50
51import org.junit.runner.RunWith;
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070052import org.junit.Before;
Bryce Lee840c5662017-04-13 10:02:51 -070053import org.junit.Test;
54
55/**
56 * Tests for the {@link ActivityStack} class.
57 *
58 * Build/Install/Run:
Wale Ogunwalebb285872018-03-01 13:05:30 -080059 * atest FrameworksServicesTests:com.android.server.am.ActivityStackTests
Bryce Lee840c5662017-04-13 10:02:51 -070060 */
61@SmallTest
62@Presubmit
63@RunWith(AndroidJUnit4.class)
64public class ActivityStackTests extends ActivityTestsBase {
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070065 private ActivityManagerService mService;
66 private ActivityStackSupervisor mSupervisor;
67 private ActivityStack mStack;
68 private TaskRecord mTask;
69
70 @Before
71 @Override
72 public void setUp() throws Exception {
73 super.setUp();
74
75 mService = createActivityManagerService();
76 mSupervisor = mService.mStackSupervisor;
77 mStack = mService.mStackSupervisor.getDefaultDisplay().createStack(
78 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
Bryce Lee18d51592017-10-25 10:22:19 -070079 mTask = new TaskBuilder(mSupervisor).setStack(mStack).build();
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070080 }
81
Bryce Lee840c5662017-04-13 10:02:51 -070082 @Test
83 public void testEmptyTaskCleanupOnRemove() throws Exception {
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070084 assertNotNull(mTask.getWindowContainerController());
85 mStack.removeTask(mTask, "testEmptyTaskCleanupOnRemove", REMOVE_TASK_MODE_DESTROYING);
86 assertNull(mTask.getWindowContainerController());
Bryce Lee840c5662017-04-13 10:02:51 -070087 }
Bryce Lee5daa3122017-04-19 10:40:42 -070088
Bryce Lee840c5662017-04-13 10:02:51 -070089 @Test
90 public void testOccupiedTaskCleanupOnRemove() throws Exception {
Bryce Lee18d51592017-10-25 10:22:19 -070091 final ActivityRecord r = new ActivityBuilder(mService).setTask(mTask).build();
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070092 assertNotNull(mTask.getWindowContainerController());
93 mStack.removeTask(mTask, "testOccupiedTaskCleanupOnRemove", REMOVE_TASK_MODE_DESTROYING);
94 assertNotNull(mTask.getWindowContainerController());
Bryce Lee840c5662017-04-13 10:02:51 -070095 }
Bryce Lee5daa3122017-04-19 10:40:42 -070096
97 @Test
98 public void testNoPauseDuringResumeTopActivity() throws Exception {
Bryce Lee18d51592017-10-25 10:22:19 -070099 final ActivityRecord r = new ActivityBuilder(mService).setTask(mTask).build();
Bryce Lee5daa3122017-04-19 10:40:42 -0700100
101 // Simulate the a resumed activity set during
102 // {@link ActivityStack#resumeTopActivityUncheckedLocked}.
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700103 mSupervisor.inResumeTopActivity = true;
Bryce Leec4ab62a2018-03-05 14:19:26 -0800104 r.setState(RESUMED, "testNoPauseDuringResumeTopActivity");
Bryce Lee5daa3122017-04-19 10:40:42 -0700105
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700106 final boolean waiting = mStack.goToSleepIfPossible(false);
Bryce Lee5daa3122017-04-19 10:40:42 -0700107
108 // Ensure we report not being ready for sleep.
David Stevens18abd0e2017-08-17 14:55:47 -0700109 assertFalse(waiting);
Bryce Lee5daa3122017-04-19 10:40:42 -0700110
111 // Make sure the resumed activity is untouched.
Bryce Leec4ab62a2018-03-05 14:19:26 -0800112 assertEquals(mStack.getResumedActivity(), r);
113 }
114
115 @Test
116 public void testResumedActivity() throws Exception {
117 final ActivityRecord r = new ActivityBuilder(mService).setTask(mTask).build();
118 assertEquals(mStack.getResumedActivity(), null);
119 r.setState(RESUMED, "testResumedActivity");
120 assertEquals(mStack.getResumedActivity(), r);
121 r.setState(PAUSING, "testResumedActivity");
122 assertEquals(mStack.getResumedActivity(), null);
123
Bryce Lee5daa3122017-04-19 10:40:42 -0700124 }
Bryce Lee3345c4e2017-04-25 07:40:41 -0700125
126 @Test
Bryce Lee8cab4a02018-01-05 09:00:49 -0800127 public void testPrimarySplitScreenToFullscreenWhenMovedToBack() throws Exception {
128 // Create primary splitscreen stack. This will create secondary stacks and places the
129 // existing fullscreen stack on the bottom.
130 final ActivityStack primarySplitScreen = mService.mStackSupervisor.getDefaultDisplay()
131 .createStack(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD,
132 true /* onTop */);
133
134 // Assert windowing mode.
135 assertEquals(primarySplitScreen.getWindowingMode(), WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
136
137 // Move primary to back.
138 primarySplitScreen.moveToBack("testPrimarySplitScreenToFullscreenWhenMovedToBack",
139 null /* task */);
140
141 // Assert that stack is at the bottom.
142 assertEquals(mService.mStackSupervisor.getDefaultDisplay().getIndexOf(primarySplitScreen),
143 0);
144
145 // Ensure no longer in splitscreen.
146 assertEquals(primarySplitScreen.getWindowingMode(), WINDOWING_MODE_FULLSCREEN);
147 }
148
149 @Test
Bryce Lee3345c4e2017-04-25 07:40:41 -0700150 public void testStopActivityWhenActivityDestroyed() throws Exception {
Bryce Lee18d51592017-10-25 10:22:19 -0700151 final ActivityRecord r = new ActivityBuilder(mService).setTask(mTask).build();
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700152 r.info.flags |= ActivityInfo.FLAG_NO_HISTORY;
153 mSupervisor.setFocusStackUnchecked("testStopActivityWithDestroy", mStack);
154 mStack.stopActivityLocked(r);
155 // Mostly testing to make sure there is a crash in the call part, so if we get here we are
156 // good-to-go!
Bryce Lee3345c4e2017-04-25 07:40:41 -0700157 }
Bryce Lee9f6affd2017-09-01 09:18:35 -0700158
159 @Test
160 public void testFindTaskWithOverlay() throws Exception {
Bryce Lee18d51592017-10-25 10:22:19 -0700161 final ActivityRecord r = new ActivityBuilder(mService)
162 .setCreateTask(true)
163 .setStack(mStack)
164 .setUid(0)
165 .build();
166 final TaskRecord task = r.getTask();
Bryce Lee9f6affd2017-09-01 09:18:35 -0700167 // Overlay must be for a different user to prevent recognizing a matching top activity
Bryce Lee18d51592017-10-25 10:22:19 -0700168 final ActivityRecord taskOverlay = new ActivityBuilder(mService).setTask(task)
169 .setUid(UserHandle.PER_USER_RANGE * 2).build();
Bryce Lee9f6affd2017-09-01 09:18:35 -0700170 taskOverlay.mTaskOverlay = true;
171
Bryce Lee9f6affd2017-09-01 09:18:35 -0700172 final ActivityStackSupervisor.FindTaskResult result =
173 new ActivityStackSupervisor.FindTaskResult();
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700174 mStack.findTaskLocked(r, result);
Bryce Lee9f6affd2017-09-01 09:18:35 -0700175
Bryce Lee18d51592017-10-25 10:22:19 -0700176 assertEquals(task.getTopActivity(false /* includeOverlays */), r);
177 assertEquals(task.getTopActivity(true /* includeOverlays */), taskOverlay);
Bryce Lee9f6affd2017-09-01 09:18:35 -0700178 assertNotNull(result.r);
179 }
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700180
181 @Test
182 public void testShouldBeVisible_Fullscreen() throws Exception {
183 final ActivityDisplay display = mService.mStackSupervisor.getDefaultDisplay();
184 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(display,
185 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
186 final ActivityStack pinnedStack = createStackForShouldBeVisibleTest(display,
187 WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, true /* onTop */);
188
189 assertTrue(homeStack.shouldBeVisible(null /* starting */));
190 assertTrue(pinnedStack.shouldBeVisible(null /* starting */));
191
192 final TestActivityStack fullscreenStack = createStackForShouldBeVisibleTest(display,
193 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
194 // Home stack shouldn't be visible behind an opaque fullscreen stack, but pinned stack
195 // should be visible since it is always on-top.
196 fullscreenStack.setIsTranslucent(false);
197 assertFalse(homeStack.shouldBeVisible(null /* starting */));
198 assertTrue(pinnedStack.shouldBeVisible(null /* starting */));
199 assertTrue(fullscreenStack.shouldBeVisible(null /* starting */));
200
201 // Home stack should be visible behind a translucent fullscreen stack.
202 fullscreenStack.setIsTranslucent(true);
203 assertTrue(homeStack.shouldBeVisible(null /* starting */));
204 assertTrue(pinnedStack.shouldBeVisible(null /* starting */));
205 }
206
207 @Test
208 public void testShouldBeVisible_SplitScreen() throws Exception {
209 final ActivityDisplay display = mService.mStackSupervisor.getDefaultDisplay();
210 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(display,
211 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
Wale Ogunwale30e441d2017-11-09 08:28:45 -0800212 // Home stack should always be fullscreen for this test.
213 homeStack.setSupportsSplitScreen(false);
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700214 final TestActivityStack splitScreenPrimary = createStackForShouldBeVisibleTest(display,
215 WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD, true /* onTop */);
216 final TestActivityStack splitScreenSecondary = createStackForShouldBeVisibleTest(display,
217 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD, true /* onTop */);
218
219 // Home stack shouldn't be visible if both halves of split-screen are opaque.
220 splitScreenPrimary.setIsTranslucent(false);
221 splitScreenSecondary.setIsTranslucent(false);
222 assertFalse(homeStack.shouldBeVisible(null /* starting */));
223 assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */));
224 assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
225
226 // Home stack should be visible if one of the halves of split-screen is translucent.
227 splitScreenPrimary.setIsTranslucent(true);
228 assertTrue(homeStack.shouldBeVisible(null /* starting */));
229 assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */));
230 assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
231
232 final TestActivityStack splitScreenSecondary2 = createStackForShouldBeVisibleTest(display,
233 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD, true /* onTop */);
234 // First split-screen secondary shouldn't be visible behind another opaque split-split
235 // secondary.
236 splitScreenSecondary2.setIsTranslucent(false);
237 assertFalse(splitScreenSecondary.shouldBeVisible(null /* starting */));
238 assertTrue(splitScreenSecondary2.shouldBeVisible(null /* starting */));
239
240 // First split-screen secondary should be visible behind another translucent split-split
241 // secondary.
242 splitScreenSecondary2.setIsTranslucent(true);
243 assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
244 assertTrue(splitScreenSecondary2.shouldBeVisible(null /* starting */));
245
246 final TestActivityStack assistantStack = createStackForShouldBeVisibleTest(display,
247 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_ASSISTANT, true /* onTop */);
248
249 // Split-screen stacks shouldn't be visible behind an opaque fullscreen stack.
250 assistantStack.setIsTranslucent(false);
251 assertTrue(assistantStack.shouldBeVisible(null /* starting */));
252 assertFalse(splitScreenPrimary.shouldBeVisible(null /* starting */));
253 assertFalse(splitScreenSecondary.shouldBeVisible(null /* starting */));
254 assertFalse(splitScreenSecondary2.shouldBeVisible(null /* starting */));
255
256 // Split-screen stacks should be visible behind a translucent fullscreen stack.
257 assistantStack.setIsTranslucent(true);
258 assertTrue(assistantStack.shouldBeVisible(null /* starting */));
259 assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */));
260 assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
261 assertTrue(splitScreenSecondary2.shouldBeVisible(null /* starting */));
262 }
263
264 @Test
265 public void testShouldBeVisible_Finishing() throws Exception {
266 final ActivityDisplay display = mService.mStackSupervisor.getDefaultDisplay();
267 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(display,
268 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
269 final TestActivityStack translucentStack = createStackForShouldBeVisibleTest(display,
270 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
271 translucentStack.setIsTranslucent(true);
272
273 assertTrue(homeStack.shouldBeVisible(null /* starting */));
274 assertTrue(translucentStack.shouldBeVisible(null /* starting */));
275
276 final ActivityRecord topRunningHomeActivity = homeStack.topRunningActivityLocked();
277 topRunningHomeActivity.finishing = true;
278 final ActivityRecord topRunningTranslucentActivity =
279 translucentStack.topRunningActivityLocked();
280 topRunningTranslucentActivity.finishing = true;
281
282 // Home shouldn't be visible since its activity is marked as finishing and it isn't the top
283 // of the stack list.
284 assertFalse(homeStack.shouldBeVisible(null /* starting */));
285 // Home should be visible if we are starting an activity within it.
286 assertTrue(homeStack.shouldBeVisible(topRunningHomeActivity /* starting */));
287 // The translucent stack should be visible since it is the top of the stack list even though
288 // it has its activity marked as finishing.
289 assertTrue(translucentStack.shouldBeVisible(null /* starting */));
290 }
291
Winson Chungd922b6b2018-02-16 16:41:50 -0800292 @Test
293 public void testMoveHomeStackBehindBottomMostVisibleStack_NoMoveHomeBehindFullscreen() {
294 final ActivityDisplay display = mService.mStackSupervisor.getDefaultDisplay();
295 display.removeChild(mStack);
296
297 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(display,
298 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
299 final TestActivityStack fullscreenStack = createStackForShouldBeVisibleTest(display,
300 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
301
302 homeStack.setIsTranslucent(false);
303 fullscreenStack.setIsTranslucent(false);
304
305 // Ensure that we don't move the home stack if it is already behind the top fullscreen stack
306 int homeStackIndex = display.getIndexOf(homeStack);
307 assertTrue(display.getStackAboveHome() == fullscreenStack);
308 display.moveHomeStackBehindBottomMostVisibleStack();
309 assertTrue(display.getIndexOf(homeStack) == homeStackIndex);
310 }
311
312 @Test
313 public void testMoveHomeStackBehindBottomMostVisibleStack_NoMoveHomeBehindTranslucent() {
314 final ActivityDisplay display = mService.mStackSupervisor.getDefaultDisplay();
315 display.removeChild(mStack);
316
317 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(display,
318 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
319 final TestActivityStack fullscreenStack = createStackForShouldBeVisibleTest(display,
320 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
321
322 homeStack.setIsTranslucent(false);
323 fullscreenStack.setIsTranslucent(true);
324
325 // Ensure that we don't move the home stack if it is already behind the top fullscreen stack
326 int homeStackIndex = display.getIndexOf(homeStack);
327 assertTrue(display.getStackAboveHome() == fullscreenStack);
328 display.moveHomeStackBehindBottomMostVisibleStack();
329 assertTrue(display.getIndexOf(homeStack) == homeStackIndex);
330 }
331
332 @Test
333 public void testMoveHomeStackBehindBottomMostVisibleStack_NoMoveHomeOnTop() {
334 final ActivityDisplay display = mService.mStackSupervisor.getDefaultDisplay();
335 display.removeChild(mStack);
336
337 final TestActivityStack fullscreenStack = createStackForShouldBeVisibleTest(display,
338 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
339 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(display,
340 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
341
342 homeStack.setIsTranslucent(false);
343 fullscreenStack.setIsTranslucent(false);
344
345 // Ensure we don't move the home stack if it is already on top
346 int homeStackIndex = display.getIndexOf(homeStack);
347 assertTrue(display.getStackAboveHome() == null);
348 display.moveHomeStackBehindBottomMostVisibleStack();
349 assertTrue(display.getIndexOf(homeStack) == homeStackIndex);
350 }
351
352 @Test
353 public void testMoveHomeStackBehindBottomMostVisibleStack_MoveHomeBehindFullscreen() {
354 final ActivityDisplay display = mService.mStackSupervisor.getDefaultDisplay();
355 display.removeChild(mStack);
356
357 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(display,
358 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
359 final TestActivityStack fullscreenStack1 = createStackForShouldBeVisibleTest(display,
360 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
361 final TestActivityStack fullscreenStack2 = createStackForShouldBeVisibleTest(display,
362 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
363 final TestActivityStack pinnedStack = createStackForShouldBeVisibleTest(display,
364 WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, true /* onTop */);
365
366 homeStack.setIsTranslucent(false);
367 fullscreenStack1.setIsTranslucent(false);
368 fullscreenStack2.setIsTranslucent(false);
369
370 // Ensure that we move the home stack behind the bottom most fullscreen stack, ignoring the
371 // pinned stack
372 assertTrue(display.getStackAboveHome() == fullscreenStack1);
373 display.moveHomeStackBehindBottomMostVisibleStack();
374 assertTrue(display.getStackAboveHome() == fullscreenStack2);
375 }
376
377 @Test
378 public void testMoveHomeStackBehindBottomMostVisibleStack_MoveHomeBehindFullscreenAndTranslucent() {
379 final ActivityDisplay display = mService.mStackSupervisor.getDefaultDisplay();
380 display.removeChild(mStack);
381
382 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(display,
383 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
384 final TestActivityStack fullscreenStack1 = createStackForShouldBeVisibleTest(display,
385 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
386 final TestActivityStack fullscreenStack2 = createStackForShouldBeVisibleTest(display,
387 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
388
389 homeStack.setIsTranslucent(false);
390 fullscreenStack1.setIsTranslucent(false);
391 fullscreenStack2.setIsTranslucent(true);
392
393 // Ensure that we move the home stack behind the bottom most non-translucent fullscreen
394 // stack
395 assertTrue(display.getStackAboveHome() == fullscreenStack1);
396 display.moveHomeStackBehindBottomMostVisibleStack();
397 assertTrue(display.getStackAboveHome() == fullscreenStack1);
398 }
399
400 @Test
401 public void testMoveHomeStackBehindStack_BehindHomeStack() {
402 final ActivityDisplay display = mService.mStackSupervisor.getDefaultDisplay();
403 display.removeChild(mStack);
404
405 final TestActivityStack fullscreenStack1 = createStackForShouldBeVisibleTest(display,
406 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
407 final TestActivityStack fullscreenStack2 = createStackForShouldBeVisibleTest(display,
408 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
409 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(display,
410 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
411
412 homeStack.setIsTranslucent(false);
413 fullscreenStack1.setIsTranslucent(false);
414 fullscreenStack2.setIsTranslucent(false);
415
416 // Ensure we don't move the home stack behind itself
417 int homeStackIndex = display.getIndexOf(homeStack);
418 display.moveHomeStackBehindStack(homeStack);
419 assertTrue(display.getIndexOf(homeStack) == homeStackIndex);
420 }
421
422 @Test
423 public void testMoveHomeStackBehindStack() {
424 final ActivityDisplay display = mService.mStackSupervisor.getDefaultDisplay();
425 display.removeChild(mStack);
426
427 final TestActivityStack fullscreenStack1 = createStackForShouldBeVisibleTest(display,
428 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
429 final TestActivityStack fullscreenStack2 = createStackForShouldBeVisibleTest(display,
430 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
Winson Chung123e07a2018-02-27 11:47:16 -0800431 final TestActivityStack fullscreenStack3 = createStackForShouldBeVisibleTest(display,
432 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
433 final TestActivityStack fullscreenStack4 = createStackForShouldBeVisibleTest(display,
434 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
Winson Chungd922b6b2018-02-16 16:41:50 -0800435 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(display,
436 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
437
438 display.moveHomeStackBehindStack(fullscreenStack1);
439 assertTrue(display.getStackAboveHome() == fullscreenStack1);
440 display.moveHomeStackBehindStack(fullscreenStack2);
441 assertTrue(display.getStackAboveHome() == fullscreenStack2);
Winson Chung123e07a2018-02-27 11:47:16 -0800442 display.moveHomeStackBehindStack(fullscreenStack4);
443 assertTrue(display.getStackAboveHome() == fullscreenStack4);
444 display.moveHomeStackBehindStack(fullscreenStack2);
445 assertTrue(display.getStackAboveHome() == fullscreenStack2);
Winson Chungd922b6b2018-02-16 16:41:50 -0800446 }
447
Wale Ogunwalebb285872018-03-01 13:05:30 -0800448 @Test
449 public void testSplitScreenMoveToFront() throws Exception {
450 final ActivityDisplay display = mService.mStackSupervisor.getDefaultDisplay();
451 final TestActivityStack splitScreenPrimary = createStackForShouldBeVisibleTest(display,
452 WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD, true /* onTop */);
453 final TestActivityStack splitScreenSecondary = createStackForShouldBeVisibleTest(display,
454 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD, true /* onTop */);
455 final TestActivityStack assistantStack = createStackForShouldBeVisibleTest(display,
456 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_ASSISTANT, true /* onTop */);
457
458 splitScreenPrimary.setIsTranslucent(false);
459 splitScreenSecondary.setIsTranslucent(false);
460 assistantStack.setIsTranslucent(false);
461
462 assertFalse(splitScreenPrimary.shouldBeVisible(null /* starting */));
463 assertFalse(splitScreenSecondary.shouldBeVisible(null /* starting */));
464 assertTrue(assistantStack.shouldBeVisible(null /* starting */));
465
466 splitScreenSecondary.moveToFront("testSplitScreenMoveToFront");
467
468 assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */));
469 assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
470 assertFalse(assistantStack.shouldBeVisible(null /* starting */));
471 }
472
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700473 private <T extends ActivityStack> T createStackForShouldBeVisibleTest(
474 ActivityDisplay display, int windowingMode, int activityType, boolean onTop) {
475 final T stack = display.createStack(windowingMode, activityType, onTop);
Bryce Lee18d51592017-10-25 10:22:19 -0700476 final ActivityRecord r = new ActivityBuilder(mService).setUid(0).setStack(stack)
477 .setCreateTask(true).build();
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700478 return stack;
479 }
Bryce Leeb0f993f2018-03-02 15:38:01 -0800480
481 @Test
482 public void testSuppressMultipleDestroy() throws Exception {
483 final ActivityRecord r = new ActivityBuilder(mService).setTask(mTask).build();
484 final ClientLifecycleManager lifecycleManager = mock(ClientLifecycleManager.class);
485 final ProcessRecord app = r.app;
486
487 // The mocked lifecycle manager must be set on the ActivityStackSupervisor's reference to
488 // the service rather than mService as mService is a spy and setting the value will not
489 // propagate as ActivityManagerService hands its own reference to the
490 // ActivityStackSupervisor during construction.
491 ((TestActivityManagerService) mSupervisor.mService).setLifecycleManager(lifecycleManager);
492
493 mStack.destroyActivityLocked(r, true, "first invocation");
494 verify(lifecycleManager, times(1)).scheduleTransaction(eq(app.thread),
495 eq(r.appToken), any(DestroyActivityItem.class));
496 assertTrue(r.isState(DESTROYED, DESTROYING));
497
498 mStack.destroyActivityLocked(r, true, "second invocation");
499 verify(lifecycleManager, times(1)).scheduleTransaction(eq(app.thread),
500 eq(r.appToken), any(DestroyActivityItem.class));
501 }
Bryce Lee840c5662017-04-13 10:02:51 -0700502}