blob: e2b7c063714aac08b7b94191b6a0bd8a715725cd [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 Leec4ab62a2018-03-05 14:19:26 -080027import static com.android.server.am.ActivityStack.ActivityState.PAUSING;
28import static com.android.server.am.ActivityStack.ActivityState.RESUMED;
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;
Tadashi G. Takaoka18c909c2018-10-11 07:51:35 +000036import static org.mockito.ArgumentMatchers.any;
37import static org.mockito.ArgumentMatchers.eq;
Bryce Lee271617a2018-03-15 10:39:12 -070038import static org.mockito.Mockito.anyInt;
39import static org.mockito.Mockito.doReturn;
Bryce Leeb0f993f2018-03-02 15:38:01 -080040import static org.mockito.Mockito.mock;
Tadashi G. Takaoka18c909c2018-10-11 07:51:35 +000041import static org.mockito.Mockito.times;
42import static org.mockito.Mockito.verify;
Bryce Lee840c5662017-04-13 10:02:51 -070043
Bryce Lee3345c4e2017-04-25 07:40:41 -070044import android.content.pm.ActivityInfo;
Bryce Lee9f6affd2017-09-01 09:18:35 -070045import android.os.UserHandle;
Bryce Lee840c5662017-04-13 10:02:51 -070046import android.platform.test.annotations.Presubmit;
47import android.support.test.filters.SmallTest;
48import android.support.test.runner.AndroidJUnit4;
49
Tadashi G. Takaoka18c909c2018-10-11 07:51:35 +000050import org.junit.runner.RunWith;
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070051import org.junit.Before;
Bryce Lee840c5662017-04-13 10:02:51 -070052import org.junit.Test;
53
54/**
55 * Tests for the {@link ActivityStack} class.
56 *
57 * Build/Install/Run:
Tadashi G. Takaoka18c909c2018-10-11 07:51:35 +000058 * atest FrameworksServicesTests:com.android.server.am.ActivityStackTests
Bryce Lee840c5662017-04-13 10:02:51 -070059 */
60@SmallTest
61@Presubmit
62@RunWith(AndroidJUnit4.class)
63public class ActivityStackTests extends ActivityTestsBase {
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070064 private ActivityManagerService mService;
65 private ActivityStackSupervisor mSupervisor;
Winson Chung3e2980e2018-03-29 17:28:57 -070066 private ActivityDisplay mDefaultDisplay;
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070067 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;
Winson Chung3e2980e2018-03-29 17:28:57 -070077 mDefaultDisplay = mService.mStackSupervisor.getDefaultDisplay();
78 mStack = mDefaultDisplay.createStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
79 true /* onTop */);
Bryce Lee18d51592017-10-25 10:22:19 -070080 mTask = new TaskBuilder(mSupervisor).setStack(mStack).build();
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070081 }
82
Bryce Lee840c5662017-04-13 10:02:51 -070083 @Test
84 public void testEmptyTaskCleanupOnRemove() throws Exception {
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070085 assertNotNull(mTask.getWindowContainerController());
86 mStack.removeTask(mTask, "testEmptyTaskCleanupOnRemove", REMOVE_TASK_MODE_DESTROYING);
87 assertNull(mTask.getWindowContainerController());
Bryce Lee840c5662017-04-13 10:02:51 -070088 }
Bryce Lee5daa3122017-04-19 10:40:42 -070089
Bryce Lee840c5662017-04-13 10:02:51 -070090 @Test
91 public void testOccupiedTaskCleanupOnRemove() throws Exception {
Bryce Lee18d51592017-10-25 10:22:19 -070092 final ActivityRecord r = new ActivityBuilder(mService).setTask(mTask).build();
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070093 assertNotNull(mTask.getWindowContainerController());
94 mStack.removeTask(mTask, "testOccupiedTaskCleanupOnRemove", REMOVE_TASK_MODE_DESTROYING);
95 assertNotNull(mTask.getWindowContainerController());
Bryce Lee840c5662017-04-13 10:02:51 -070096 }
Bryce Lee5daa3122017-04-19 10:40:42 -070097
98 @Test
Bryce Leec4ab62a2018-03-05 14:19:26 -080099 public void testResumedActivity() throws Exception {
100 final ActivityRecord r = new ActivityBuilder(mService).setTask(mTask).build();
101 assertEquals(mStack.getResumedActivity(), null);
102 r.setState(RESUMED, "testResumedActivity");
103 assertEquals(mStack.getResumedActivity(), r);
104 r.setState(PAUSING, "testResumedActivity");
105 assertEquals(mStack.getResumedActivity(), null);
Bryce Lee84730a02018-04-03 14:10:04 -0700106 }
Bryce Leec4ab62a2018-03-05 14:19:26 -0800107
Bryce Lee84730a02018-04-03 14:10:04 -0700108 @Test
109 public void testResumedActivityFromTaskReparenting() {
110 final ActivityRecord r = new ActivityBuilder(mService).setTask(mTask).build();
111 // Ensure moving task between two stacks updates resumed activity
112 r.setState(RESUMED, "testResumedActivityFromTaskReparenting");
113 assertEquals(mStack.getResumedActivity(), r);
114
115 final ActivityStack destStack = mService.mStackSupervisor.getDefaultDisplay().createStack(
116 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
117
118 mTask.reparent(destStack, true /* toTop */, TaskRecord.REPARENT_KEEP_STACK_AT_FRONT,
119 false /* animate */, true /* deferResume*/,
120 "testResumedActivityFromTaskReparenting");
121
122 assertEquals(mStack.getResumedActivity(), null);
123 assertEquals(destStack.getResumedActivity(), r);
124 }
125
126 @Test
127 public void testResumedActivityFromActivityReparenting() {
128 final ActivityRecord r = new ActivityBuilder(mService).setTask(mTask).build();
129 // Ensure moving task between two stacks updates resumed activity
130 r.setState(RESUMED, "testResumedActivityFromActivityReparenting");
131 assertEquals(mStack.getResumedActivity(), r);
132
133 final ActivityStack destStack = mService.mStackSupervisor.getDefaultDisplay().createStack(
134 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
135 final TaskRecord destTask = new TaskBuilder(mSupervisor).setStack(destStack).build();
136
137 mTask.removeActivity(r);
138 destTask.addActivityToTop(r);
139
140 assertEquals(mStack.getResumedActivity(), null);
141 assertEquals(destStack.getResumedActivity(), r);
Bryce Lee5daa3122017-04-19 10:40:42 -0700142 }
Bryce Lee3345c4e2017-04-25 07:40:41 -0700143
144 @Test
Bryce Lee8cab4a02018-01-05 09:00:49 -0800145 public void testPrimarySplitScreenToFullscreenWhenMovedToBack() throws Exception {
146 // Create primary splitscreen stack. This will create secondary stacks and places the
147 // existing fullscreen stack on the bottom.
Winson Chung3e2980e2018-03-29 17:28:57 -0700148 final ActivityStack primarySplitScreen = mDefaultDisplay.createStack(
149 WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD, true /* onTop */);
Bryce Lee8cab4a02018-01-05 09:00:49 -0800150
151 // Assert windowing mode.
152 assertEquals(primarySplitScreen.getWindowingMode(), WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
153
154 // Move primary to back.
155 primarySplitScreen.moveToBack("testPrimarySplitScreenToFullscreenWhenMovedToBack",
156 null /* task */);
157
158 // Assert that stack is at the bottom.
Winson Chung3e2980e2018-03-29 17:28:57 -0700159 assertEquals(mDefaultDisplay.getIndexOf(primarySplitScreen), 0);
Bryce Lee8cab4a02018-01-05 09:00:49 -0800160
161 // Ensure no longer in splitscreen.
162 assertEquals(primarySplitScreen.getWindowingMode(), WINDOWING_MODE_FULLSCREEN);
163 }
164
165 @Test
Bryce Lee3345c4e2017-04-25 07:40:41 -0700166 public void testStopActivityWhenActivityDestroyed() throws Exception {
Bryce Lee18d51592017-10-25 10:22:19 -0700167 final ActivityRecord r = new ActivityBuilder(mService).setTask(mTask).build();
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700168 r.info.flags |= ActivityInfo.FLAG_NO_HISTORY;
169 mSupervisor.setFocusStackUnchecked("testStopActivityWithDestroy", mStack);
170 mStack.stopActivityLocked(r);
171 // Mostly testing to make sure there is a crash in the call part, so if we get here we are
172 // good-to-go!
Bryce Lee3345c4e2017-04-25 07:40:41 -0700173 }
Bryce Lee9f6affd2017-09-01 09:18:35 -0700174
175 @Test
176 public void testFindTaskWithOverlay() throws Exception {
Bryce Lee18d51592017-10-25 10:22:19 -0700177 final ActivityRecord r = new ActivityBuilder(mService)
178 .setCreateTask(true)
179 .setStack(mStack)
180 .setUid(0)
181 .build();
182 final TaskRecord task = r.getTask();
Bryce Lee9f6affd2017-09-01 09:18:35 -0700183 // Overlay must be for a different user to prevent recognizing a matching top activity
Bryce Lee18d51592017-10-25 10:22:19 -0700184 final ActivityRecord taskOverlay = new ActivityBuilder(mService).setTask(task)
185 .setUid(UserHandle.PER_USER_RANGE * 2).build();
Bryce Lee9f6affd2017-09-01 09:18:35 -0700186 taskOverlay.mTaskOverlay = true;
187
Bryce Lee9f6affd2017-09-01 09:18:35 -0700188 final ActivityStackSupervisor.FindTaskResult result =
189 new ActivityStackSupervisor.FindTaskResult();
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700190 mStack.findTaskLocked(r, result);
Bryce Lee9f6affd2017-09-01 09:18:35 -0700191
Bryce Lee18d51592017-10-25 10:22:19 -0700192 assertEquals(task.getTopActivity(false /* includeOverlays */), r);
193 assertEquals(task.getTopActivity(true /* includeOverlays */), taskOverlay);
Bryce Lee9f6affd2017-09-01 09:18:35 -0700194 assertNotNull(result.r);
195 }
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700196
197 @Test
198 public void testShouldBeVisible_Fullscreen() throws Exception {
Winson Chung3e2980e2018-03-29 17:28:57 -0700199 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700200 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
Winson Chung3e2980e2018-03-29 17:28:57 -0700201 final ActivityStack pinnedStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700202 WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, true /* onTop */);
203
204 assertTrue(homeStack.shouldBeVisible(null /* starting */));
205 assertTrue(pinnedStack.shouldBeVisible(null /* starting */));
206
Winson Chung3e2980e2018-03-29 17:28:57 -0700207 final TestActivityStack fullscreenStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700208 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
209 // Home stack shouldn't be visible behind an opaque fullscreen stack, but pinned stack
210 // should be visible since it is always on-top.
211 fullscreenStack.setIsTranslucent(false);
212 assertFalse(homeStack.shouldBeVisible(null /* starting */));
213 assertTrue(pinnedStack.shouldBeVisible(null /* starting */));
214 assertTrue(fullscreenStack.shouldBeVisible(null /* starting */));
215
216 // Home stack should be visible behind a translucent fullscreen stack.
217 fullscreenStack.setIsTranslucent(true);
218 assertTrue(homeStack.shouldBeVisible(null /* starting */));
219 assertTrue(pinnedStack.shouldBeVisible(null /* starting */));
220 }
221
222 @Test
223 public void testShouldBeVisible_SplitScreen() throws Exception {
Winson Chung3e2980e2018-03-29 17:28:57 -0700224 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700225 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
Wale Ogunwale30e441d2017-11-09 08:28:45 -0800226 // Home stack should always be fullscreen for this test.
227 homeStack.setSupportsSplitScreen(false);
Winson Chung3e2980e2018-03-29 17:28:57 -0700228 final TestActivityStack splitScreenPrimary = createStackForShouldBeVisibleTest(mDefaultDisplay,
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700229 WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD, true /* onTop */);
Winson Chung3e2980e2018-03-29 17:28:57 -0700230 final TestActivityStack splitScreenSecondary = createStackForShouldBeVisibleTest(mDefaultDisplay,
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700231 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD, true /* onTop */);
232
233 // Home stack shouldn't be visible if both halves of split-screen are opaque.
234 splitScreenPrimary.setIsTranslucent(false);
235 splitScreenSecondary.setIsTranslucent(false);
236 assertFalse(homeStack.shouldBeVisible(null /* starting */));
237 assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */));
238 assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
239
240 // Home stack should be visible if one of the halves of split-screen is translucent.
241 splitScreenPrimary.setIsTranslucent(true);
242 assertTrue(homeStack.shouldBeVisible(null /* starting */));
243 assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */));
244 assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
245
Winson Chung3e2980e2018-03-29 17:28:57 -0700246 final TestActivityStack splitScreenSecondary2 = createStackForShouldBeVisibleTest(mDefaultDisplay,
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700247 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD, true /* onTop */);
248 // First split-screen secondary shouldn't be visible behind another opaque split-split
249 // secondary.
250 splitScreenSecondary2.setIsTranslucent(false);
251 assertFalse(splitScreenSecondary.shouldBeVisible(null /* starting */));
252 assertTrue(splitScreenSecondary2.shouldBeVisible(null /* starting */));
253
Wale Ogunwale8e923af2018-03-23 08:48:11 -0700254 // First split-screen secondary should be visible behind another translucent split-screen
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700255 // secondary.
256 splitScreenSecondary2.setIsTranslucent(true);
257 assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
258 assertTrue(splitScreenSecondary2.shouldBeVisible(null /* starting */));
259
Winson Chung3e2980e2018-03-29 17:28:57 -0700260 final TestActivityStack assistantStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700261 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_ASSISTANT, true /* onTop */);
262
263 // Split-screen stacks shouldn't be visible behind an opaque fullscreen stack.
264 assistantStack.setIsTranslucent(false);
265 assertTrue(assistantStack.shouldBeVisible(null /* starting */));
266 assertFalse(splitScreenPrimary.shouldBeVisible(null /* starting */));
267 assertFalse(splitScreenSecondary.shouldBeVisible(null /* starting */));
268 assertFalse(splitScreenSecondary2.shouldBeVisible(null /* starting */));
269
270 // Split-screen stacks should be visible behind a translucent fullscreen stack.
271 assistantStack.setIsTranslucent(true);
272 assertTrue(assistantStack.shouldBeVisible(null /* starting */));
273 assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */));
274 assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
275 assertTrue(splitScreenSecondary2.shouldBeVisible(null /* starting */));
Wale Ogunwale8e923af2018-03-23 08:48:11 -0700276
277 // Assistant stack shouldn't be visible behind translucent split-screen stack
278 assistantStack.setIsTranslucent(false);
279 splitScreenPrimary.setIsTranslucent(true);
280 splitScreenSecondary2.setIsTranslucent(true);
281 splitScreenSecondary2.moveToFront("testShouldBeVisible_SplitScreen");
282 splitScreenPrimary.moveToFront("testShouldBeVisible_SplitScreen");
283 assertFalse(assistantStack.shouldBeVisible(null /* starting */));
284 assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */));
285 assertTrue(splitScreenSecondary2.shouldBeVisible(null /* starting */));
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700286 }
287
288 @Test
289 public void testShouldBeVisible_Finishing() throws Exception {
Winson Chung3e2980e2018-03-29 17:28:57 -0700290 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700291 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
Winson Chung3e2980e2018-03-29 17:28:57 -0700292 final TestActivityStack translucentStack = createStackForShouldBeVisibleTest(
293 mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
294 true /* onTop */);
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700295 translucentStack.setIsTranslucent(true);
296
297 assertTrue(homeStack.shouldBeVisible(null /* starting */));
298 assertTrue(translucentStack.shouldBeVisible(null /* starting */));
299
300 final ActivityRecord topRunningHomeActivity = homeStack.topRunningActivityLocked();
301 topRunningHomeActivity.finishing = true;
302 final ActivityRecord topRunningTranslucentActivity =
303 translucentStack.topRunningActivityLocked();
304 topRunningTranslucentActivity.finishing = true;
305
306 // Home shouldn't be visible since its activity is marked as finishing and it isn't the top
307 // of the stack list.
308 assertFalse(homeStack.shouldBeVisible(null /* starting */));
309 // Home should be visible if we are starting an activity within it.
310 assertTrue(homeStack.shouldBeVisible(topRunningHomeActivity /* starting */));
311 // The translucent stack should be visible since it is the top of the stack list even though
312 // it has its activity marked as finishing.
313 assertTrue(translucentStack.shouldBeVisible(null /* starting */));
314 }
315
Winson Chungd922b6b2018-02-16 16:41:50 -0800316 @Test
317 public void testMoveHomeStackBehindBottomMostVisibleStack_NoMoveHomeBehindFullscreen() {
Winson Chung3e2980e2018-03-29 17:28:57 -0700318 mDefaultDisplay.removeChild(mStack);
Winson Chungd922b6b2018-02-16 16:41:50 -0800319
Winson Chung3e2980e2018-03-29 17:28:57 -0700320 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Winson Chungd922b6b2018-02-16 16:41:50 -0800321 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
Winson Chung3e2980e2018-03-29 17:28:57 -0700322 final TestActivityStack fullscreenStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Winson Chungd922b6b2018-02-16 16:41:50 -0800323 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
324
325 homeStack.setIsTranslucent(false);
326 fullscreenStack.setIsTranslucent(false);
327
328 // Ensure that we don't move the home stack if it is already behind the top fullscreen stack
Winson Chung3e2980e2018-03-29 17:28:57 -0700329 int homeStackIndex = mDefaultDisplay.getIndexOf(homeStack);
330 assertTrue(mDefaultDisplay.getStackAbove(homeStack) == fullscreenStack);
331 mDefaultDisplay.moveStackBehindBottomMostVisibleStack(homeStack);
332 assertTrue(mDefaultDisplay.getIndexOf(homeStack) == homeStackIndex);
Winson Chungd922b6b2018-02-16 16:41:50 -0800333 }
334
335 @Test
336 public void testMoveHomeStackBehindBottomMostVisibleStack_NoMoveHomeBehindTranslucent() {
Winson Chung3e2980e2018-03-29 17:28:57 -0700337 mDefaultDisplay.removeChild(mStack);
Winson Chungd922b6b2018-02-16 16:41:50 -0800338
Winson Chung3e2980e2018-03-29 17:28:57 -0700339 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Winson Chungd922b6b2018-02-16 16:41:50 -0800340 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
Winson Chung3e2980e2018-03-29 17:28:57 -0700341 final TestActivityStack fullscreenStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Winson Chungd922b6b2018-02-16 16:41:50 -0800342 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
343
344 homeStack.setIsTranslucent(false);
345 fullscreenStack.setIsTranslucent(true);
346
347 // Ensure that we don't move the home stack if it is already behind the top fullscreen stack
Winson Chung3e2980e2018-03-29 17:28:57 -0700348 int homeStackIndex = mDefaultDisplay.getIndexOf(homeStack);
349 assertTrue(mDefaultDisplay.getStackAbove(homeStack) == fullscreenStack);
350 mDefaultDisplay.moveStackBehindBottomMostVisibleStack(homeStack);
351 assertTrue(mDefaultDisplay.getIndexOf(homeStack) == homeStackIndex);
Winson Chungd922b6b2018-02-16 16:41:50 -0800352 }
353
354 @Test
355 public void testMoveHomeStackBehindBottomMostVisibleStack_NoMoveHomeOnTop() {
Winson Chung3e2980e2018-03-29 17:28:57 -0700356 mDefaultDisplay.removeChild(mStack);
Winson Chungd922b6b2018-02-16 16:41:50 -0800357
Winson Chung3e2980e2018-03-29 17:28:57 -0700358 final TestActivityStack fullscreenStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Winson Chungd922b6b2018-02-16 16:41:50 -0800359 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
Winson Chung3e2980e2018-03-29 17:28:57 -0700360 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Winson Chungd922b6b2018-02-16 16:41:50 -0800361 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
362
363 homeStack.setIsTranslucent(false);
364 fullscreenStack.setIsTranslucent(false);
365
366 // Ensure we don't move the home stack if it is already on top
Winson Chung3e2980e2018-03-29 17:28:57 -0700367 int homeStackIndex = mDefaultDisplay.getIndexOf(homeStack);
368 assertTrue(mDefaultDisplay.getStackAbove(homeStack) == null);
369 mDefaultDisplay.moveStackBehindBottomMostVisibleStack(homeStack);
370 assertTrue(mDefaultDisplay.getIndexOf(homeStack) == homeStackIndex);
Winson Chungd922b6b2018-02-16 16:41:50 -0800371 }
372
373 @Test
374 public void testMoveHomeStackBehindBottomMostVisibleStack_MoveHomeBehindFullscreen() {
Winson Chung3e2980e2018-03-29 17:28:57 -0700375 mDefaultDisplay.removeChild(mStack);
Winson Chungd922b6b2018-02-16 16:41:50 -0800376
Winson Chung3e2980e2018-03-29 17:28:57 -0700377 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Winson Chungd922b6b2018-02-16 16:41:50 -0800378 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
Winson Chung3e2980e2018-03-29 17:28:57 -0700379 final TestActivityStack fullscreenStack1 = createStackForShouldBeVisibleTest(
380 mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
381 true /* onTop */);
382 final TestActivityStack fullscreenStack2 = createStackForShouldBeVisibleTest(
383 mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
384 true /* onTop */);
Alan Stokes6e4ceb12018-11-07 16:38:59 +0000385 final ActivityStack pinnedStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Winson Chungd922b6b2018-02-16 16:41:50 -0800386 WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, true /* onTop */);
387
388 homeStack.setIsTranslucent(false);
389 fullscreenStack1.setIsTranslucent(false);
390 fullscreenStack2.setIsTranslucent(false);
391
392 // Ensure that we move the home stack behind the bottom most fullscreen stack, ignoring the
393 // pinned stack
Winson Chung3e2980e2018-03-29 17:28:57 -0700394 assertTrue(mDefaultDisplay.getStackAbove(homeStack) == fullscreenStack1);
395 mDefaultDisplay.moveStackBehindBottomMostVisibleStack(homeStack);
396 assertTrue(mDefaultDisplay.getStackAbove(homeStack) == fullscreenStack2);
Winson Chungd922b6b2018-02-16 16:41:50 -0800397 }
398
399 @Test
400 public void testMoveHomeStackBehindBottomMostVisibleStack_MoveHomeBehindFullscreenAndTranslucent() {
Winson Chung3e2980e2018-03-29 17:28:57 -0700401 mDefaultDisplay.removeChild(mStack);
Winson Chungd922b6b2018-02-16 16:41:50 -0800402
Winson Chung3e2980e2018-03-29 17:28:57 -0700403 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Winson Chungd922b6b2018-02-16 16:41:50 -0800404 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
Winson Chung3e2980e2018-03-29 17:28:57 -0700405 final TestActivityStack fullscreenStack1 = createStackForShouldBeVisibleTest(
406 mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
407 true /* onTop */);
408 final TestActivityStack fullscreenStack2 = createStackForShouldBeVisibleTest(
409 mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
410 true /* onTop */);
Winson Chungd922b6b2018-02-16 16:41:50 -0800411
412 homeStack.setIsTranslucent(false);
413 fullscreenStack1.setIsTranslucent(false);
414 fullscreenStack2.setIsTranslucent(true);
415
416 // Ensure that we move the home stack behind the bottom most non-translucent fullscreen
417 // stack
Winson Chung3e2980e2018-03-29 17:28:57 -0700418 assertTrue(mDefaultDisplay.getStackAbove(homeStack) == fullscreenStack1);
419 mDefaultDisplay.moveStackBehindBottomMostVisibleStack(homeStack);
420 assertTrue(mDefaultDisplay.getStackAbove(homeStack) == fullscreenStack1);
Winson Chungd922b6b2018-02-16 16:41:50 -0800421 }
422
423 @Test
424 public void testMoveHomeStackBehindStack_BehindHomeStack() {
Winson Chung3e2980e2018-03-29 17:28:57 -0700425 mDefaultDisplay.removeChild(mStack);
Winson Chungd922b6b2018-02-16 16:41:50 -0800426
Winson Chung3e2980e2018-03-29 17:28:57 -0700427 final TestActivityStack fullscreenStack1 = createStackForShouldBeVisibleTest(
428 mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
429 true /* onTop */);
430 final TestActivityStack fullscreenStack2 = createStackForShouldBeVisibleTest(
431 mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
432 true /* onTop */);
433 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Winson Chungd922b6b2018-02-16 16:41:50 -0800434 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
435
436 homeStack.setIsTranslucent(false);
437 fullscreenStack1.setIsTranslucent(false);
438 fullscreenStack2.setIsTranslucent(false);
439
440 // Ensure we don't move the home stack behind itself
Winson Chung3e2980e2018-03-29 17:28:57 -0700441 int homeStackIndex = mDefaultDisplay.getIndexOf(homeStack);
442 mDefaultDisplay.moveStackBehindStack(homeStack, homeStack);
443 assertTrue(mDefaultDisplay.getIndexOf(homeStack) == homeStackIndex);
Winson Chungd922b6b2018-02-16 16:41:50 -0800444 }
445
446 @Test
447 public void testMoveHomeStackBehindStack() {
Winson Chung3e2980e2018-03-29 17:28:57 -0700448 mDefaultDisplay.removeChild(mStack);
Winson Chungd922b6b2018-02-16 16:41:50 -0800449
Winson Chung3e2980e2018-03-29 17:28:57 -0700450 final TestActivityStack fullscreenStack1 = createStackForShouldBeVisibleTest(
451 mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
452 true /* onTop */);
453 final TestActivityStack fullscreenStack2 = createStackForShouldBeVisibleTest(
454 mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
455 true /* onTop */);
456 final TestActivityStack fullscreenStack3 = createStackForShouldBeVisibleTest(
457 mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
458 true /* onTop */);
459 final TestActivityStack fullscreenStack4 = createStackForShouldBeVisibleTest(
460 mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
461 true /* onTop */);
462 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Winson Chungd922b6b2018-02-16 16:41:50 -0800463 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
464
Winson Chung3e2980e2018-03-29 17:28:57 -0700465 mDefaultDisplay.moveStackBehindStack(homeStack, fullscreenStack1);
466 assertTrue(mDefaultDisplay.getStackAbove(homeStack) == fullscreenStack1);
467 mDefaultDisplay.moveStackBehindStack(homeStack, fullscreenStack2);
468 assertTrue(mDefaultDisplay.getStackAbove(homeStack) == fullscreenStack2);
469 mDefaultDisplay.moveStackBehindStack(homeStack, fullscreenStack4);
470 assertTrue(mDefaultDisplay.getStackAbove(homeStack) == fullscreenStack4);
471 mDefaultDisplay.moveStackBehindStack(homeStack, fullscreenStack2);
472 assertTrue(mDefaultDisplay.getStackAbove(homeStack) == fullscreenStack2);
Winson Chungd922b6b2018-02-16 16:41:50 -0800473 }
474
Wale Ogunwalebb285872018-03-01 13:05:30 -0800475 @Test
476 public void testSplitScreenMoveToFront() throws Exception {
Winson Chung3e2980e2018-03-29 17:28:57 -0700477 final TestActivityStack splitScreenPrimary = createStackForShouldBeVisibleTest(
478 mDefaultDisplay, WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD,
479 true /* onTop */);
480 final TestActivityStack splitScreenSecondary = createStackForShouldBeVisibleTest(
481 mDefaultDisplay, WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD,
482 true /* onTop */);
483 final TestActivityStack assistantStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Wale Ogunwalebb285872018-03-01 13:05:30 -0800484 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_ASSISTANT, true /* onTop */);
485
486 splitScreenPrimary.setIsTranslucent(false);
487 splitScreenSecondary.setIsTranslucent(false);
488 assistantStack.setIsTranslucent(false);
489
490 assertFalse(splitScreenPrimary.shouldBeVisible(null /* starting */));
491 assertFalse(splitScreenSecondary.shouldBeVisible(null /* starting */));
492 assertTrue(assistantStack.shouldBeVisible(null /* starting */));
493
494 splitScreenSecondary.moveToFront("testSplitScreenMoveToFront");
495
496 assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */));
497 assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
498 assertFalse(assistantStack.shouldBeVisible(null /* starting */));
499 }
500
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700501 private <T extends ActivityStack> T createStackForShouldBeVisibleTest(
502 ActivityDisplay display, int windowingMode, int activityType, boolean onTop) {
503 final T stack = display.createStack(windowingMode, activityType, onTop);
Bryce Lee18d51592017-10-25 10:22:19 -0700504 final ActivityRecord r = new ActivityBuilder(mService).setUid(0).setStack(stack)
505 .setCreateTask(true).build();
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700506 return stack;
507 }
Bryce Leeb0f993f2018-03-02 15:38:01 -0800508
509 @Test
Bryce Leefbd263b42018-03-07 10:33:55 -0800510 public void testFinishDisabledPackageActivities() 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 second activity a task overlay without an app means it will be removed from
515 // the task's activities as well once first activity is removed.
516 secondActivity.mTaskOverlay = true;
517 secondActivity.app = null;
518
519 assertEquals(mTask.mActivities.size(), 2);
520
521 mStack.finishDisabledPackageActivitiesLocked(firstActivity.packageName, null,
522 true /* doit */, true /* evenPersistent */, UserHandle.USER_ALL);
523
524 assertTrue(mTask.mActivities.isEmpty());
525 assertTrue(mStack.getAllTasks().isEmpty());
526 }
527
528 @Test
529 public void testHandleAppDied() throws Exception {
530 final ActivityRecord firstActivity = new ActivityBuilder(mService).setTask(mTask).build();
531 final ActivityRecord secondActivity = new ActivityBuilder(mService).setTask(mTask).build();
532
533 // Making the first activity a task overlay means it will be removed from the task's
534 // activities as well once second activity is removed as handleAppDied processes the
535 // activity list in reverse.
536 firstActivity.mTaskOverlay = true;
537 firstActivity.app = null;
538
539 // second activity will be immediately removed as it has no state.
540 secondActivity.haveState = false;
541
542 assertEquals(mTask.mActivities.size(), 2);
543
544 mStack.handleAppDiedLocked(secondActivity.app);
545
546 assertTrue(mTask.mActivities.isEmpty());
547 assertTrue(mStack.getAllTasks().isEmpty());
548 }
Bryce Lee271617a2018-03-15 10:39:12 -0700549
550 @Test
551 public void testShouldSleepActivities() throws Exception {
552 // When focused activity and keyguard is going away, we should not sleep regardless
553 // of the display state
554 verifyShouldSleepActivities(true /* focusedStack */, true /*keyguardGoingAway*/,
555 true /* displaySleeping */, false /* expected*/);
556
557 // When not the focused stack, defer to display sleeping state.
558 verifyShouldSleepActivities(false /* focusedStack */, true /*keyguardGoingAway*/,
559 true /* displaySleeping */, true /* expected*/);
560
561 // If keyguard is going away, defer to the display sleeping state.
562 verifyShouldSleepActivities(true /* focusedStack */, false /*keyguardGoingAway*/,
563 true /* displaySleeping */, true /* expected*/);
564 verifyShouldSleepActivities(true /* focusedStack */, false /*keyguardGoingAway*/,
565 false /* displaySleeping */, false /* expected*/);
566 }
567
Winson Chung0f7ec962018-05-03 18:03:15 -0700568 @Test
569 public void testStackOrderChangedOnRemoveStack() throws Exception {
570 StackOrderChangedListener listener = new StackOrderChangedListener();
571 mDefaultDisplay.registerStackOrderChangedListener(listener);
572 try {
573 mDefaultDisplay.removeChild(mStack);
574 } finally {
575 mDefaultDisplay.unregisterStackOrderChangedListener(listener);
576 }
577 assertTrue(listener.changed);
578 }
579
580 @Test
581 public void testStackOrderChangedOnAddPositionStack() throws Exception {
582 mDefaultDisplay.removeChild(mStack);
583
584 StackOrderChangedListener listener = new StackOrderChangedListener();
585 mDefaultDisplay.registerStackOrderChangedListener(listener);
586 try {
587 mDefaultDisplay.addChild(mStack, 0);
588 } finally {
589 mDefaultDisplay.unregisterStackOrderChangedListener(listener);
590 }
591 assertTrue(listener.changed);
592 }
593
594 @Test
595 public void testStackOrderChangedOnPositionStack() throws Exception {
596 StackOrderChangedListener listener = new StackOrderChangedListener();
597 try {
598 final TestActivityStack fullscreenStack1 = createStackForShouldBeVisibleTest(
599 mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
600 true /* onTop */);
601 mDefaultDisplay.registerStackOrderChangedListener(listener);
602 mDefaultDisplay.positionChildAtBottom(fullscreenStack1);
603 } finally {
604 mDefaultDisplay.unregisterStackOrderChangedListener(listener);
605 }
606 assertTrue(listener.changed);
607 }
608
Bryce Lee271617a2018-03-15 10:39:12 -0700609 private void verifyShouldSleepActivities(boolean focusedStack,
610 boolean keyguardGoingAway, boolean displaySleeping, boolean expected) {
611 mSupervisor.mFocusedStack = focusedStack ? mStack : null;
612
613 final ActivityDisplay display = mock(ActivityDisplay.class);
614 final KeyguardController keyguardController = mSupervisor.getKeyguardController();
615
616 doReturn(display).when(mSupervisor).getActivityDisplay(anyInt());
617 doReturn(keyguardGoingAway).when(keyguardController).isKeyguardGoingAway();
618 doReturn(displaySleeping).when(display).isSleeping();
619
620 assertEquals(expected, mStack.shouldSleepActivities());
621 }
Winson Chung0f7ec962018-05-03 18:03:15 -0700622
623 private class StackOrderChangedListener implements ActivityDisplay.OnStackOrderChangedListener {
624 boolean changed = false;
625
626 @Override
627 public void onStackOrderChanged() {
628 changed = true;
629 }
630 }
Bryce Lee840c5662017-04-13 10:02:51 -0700631}