blob: 53f67afb629ebc78bcdb576a0549f0cea48eae84 [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;
Kazuki Takisef85197b2018-06-18 18:18:36 +090022import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070023import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -070024import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
25import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
26import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
Evan Rosky10475742018-09-05 19:02:48 -070027import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
Bryce Lee18d51592017-10-25 10:22:19 -070028
Riddle Hsue10cea52018-10-16 23:33:23 +080029import static com.android.server.am.ActivityStack.ActivityState.DESTROYING;
30import static com.android.server.am.ActivityStack.ActivityState.FINISHING;
31import static com.android.server.am.ActivityStack.ActivityState.PAUSED;
Bryce Leec4ab62a2018-03-05 14:19:26 -080032import static com.android.server.am.ActivityStack.ActivityState.PAUSING;
33import static com.android.server.am.ActivityStack.ActivityState.RESUMED;
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070034import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_DESTROYING;
Bryce Lee18d51592017-10-25 10:22:19 -070035
Bryce Lee5daa3122017-04-19 10:40:42 -070036import static org.junit.Assert.assertEquals;
David Stevens18abd0e2017-08-17 14:55:47 -070037import static org.junit.Assert.assertFalse;
Bryce Lee840c5662017-04-13 10:02:51 -070038import static org.junit.Assert.assertNotNull;
39import static org.junit.Assert.assertNull;
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -070040import static org.junit.Assert.assertTrue;
Riddle Hsue10cea52018-10-16 23:33:23 +080041import static org.mockito.ArgumentMatchers.anyBoolean;
42import static org.mockito.ArgumentMatchers.anyInt;
43import static org.mockito.ArgumentMatchers.anyString;
44import static org.mockito.ArgumentMatchers.eq;
Bryce Lee271617a2018-03-15 10:39:12 -070045import static org.mockito.Mockito.doReturn;
Bryce Leeb0f993f2018-03-02 15:38:01 -080046import static org.mockito.Mockito.mock;
Tiger Huang1e5b10a2018-07-30 20:19:51 +080047import static org.mockito.Mockito.spy;
Riddle Hsue10cea52018-10-16 23:33:23 +080048import static org.mockito.Mockito.verify;
Bryce Lee840c5662017-04-13 10:02:51 -070049
Bryce Lee3345c4e2017-04-25 07:40:41 -070050import android.content.pm.ActivityInfo;
Bryce Lee9f6affd2017-09-01 09:18:35 -070051import android.os.UserHandle;
Bryce Lee840c5662017-04-13 10:02:51 -070052import android.platform.test.annotations.Presubmit;
Bryce Lee840c5662017-04-13 10:02:51 -070053
Brett Chabota26eda92018-07-23 13:08:30 -070054import androidx.test.filters.SmallTest;
55import androidx.test.runner.AndroidJUnit4;
56
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070057import org.junit.Before;
Bryce Lee840c5662017-04-13 10:02:51 -070058import org.junit.Test;
Brett Chabota26eda92018-07-23 13:08:30 -070059import org.junit.runner.RunWith;
Bryce Lee840c5662017-04-13 10:02:51 -070060
61/**
62 * Tests for the {@link ActivityStack} class.
63 *
64 * Build/Install/Run:
John Reck3d294e72018-09-21 20:26:48 +000065 * atest FrameworksServicesTests:com.android.server.am.ActivityStackTests
Bryce Lee840c5662017-04-13 10:02:51 -070066 */
67@SmallTest
68@Presubmit
69@RunWith(AndroidJUnit4.class)
70public class ActivityStackTests extends ActivityTestsBase {
Winson Chung3e2980e2018-03-29 17:28:57 -070071 private ActivityDisplay mDefaultDisplay;
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070072 private ActivityStack mStack;
73 private TaskRecord mTask;
74
75 @Before
76 @Override
77 public void setUp() throws Exception {
78 super.setUp();
79
Riddle Hsub70b36d2018-09-11 21:20:02 +080080 setupActivityTaskManagerService();
81 mDefaultDisplay = mSupervisor.getDefaultDisplay();
Tiger Huang1e5b10a2018-07-30 20:19:51 +080082 mStack = spy(mDefaultDisplay.createStack(WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD,
83 true /* onTop */));
Bryce Lee18d51592017-10-25 10:22:19 -070084 mTask = new TaskBuilder(mSupervisor).setStack(mStack).build();
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070085 }
86
Bryce Lee840c5662017-04-13 10:02:51 -070087 @Test
88 public void testEmptyTaskCleanupOnRemove() throws Exception {
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070089 assertNotNull(mTask.getWindowContainerController());
90 mStack.removeTask(mTask, "testEmptyTaskCleanupOnRemove", REMOVE_TASK_MODE_DESTROYING);
91 assertNull(mTask.getWindowContainerController());
Bryce Lee840c5662017-04-13 10:02:51 -070092 }
Bryce Lee5daa3122017-04-19 10:40:42 -070093
Bryce Lee840c5662017-04-13 10:02:51 -070094 @Test
95 public void testOccupiedTaskCleanupOnRemove() throws Exception {
Bryce Lee18d51592017-10-25 10:22:19 -070096 final ActivityRecord r = new ActivityBuilder(mService).setTask(mTask).build();
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070097 assertNotNull(mTask.getWindowContainerController());
98 mStack.removeTask(mTask, "testOccupiedTaskCleanupOnRemove", REMOVE_TASK_MODE_DESTROYING);
99 assertNotNull(mTask.getWindowContainerController());
Bryce Lee840c5662017-04-13 10:02:51 -0700100 }
Bryce Lee5daa3122017-04-19 10:40:42 -0700101
102 @Test
Bryce Leec4ab62a2018-03-05 14:19:26 -0800103 public void testResumedActivity() throws Exception {
104 final ActivityRecord r = new ActivityBuilder(mService).setTask(mTask).build();
105 assertEquals(mStack.getResumedActivity(), null);
106 r.setState(RESUMED, "testResumedActivity");
107 assertEquals(mStack.getResumedActivity(), r);
108 r.setState(PAUSING, "testResumedActivity");
109 assertEquals(mStack.getResumedActivity(), null);
Bryce Lee84730a02018-04-03 14:10:04 -0700110 }
Bryce Leec4ab62a2018-03-05 14:19:26 -0800111
Bryce Lee84730a02018-04-03 14:10:04 -0700112 @Test
113 public void testResumedActivityFromTaskReparenting() {
114 final ActivityRecord r = new ActivityBuilder(mService).setTask(mTask).build();
115 // Ensure moving task between two stacks updates resumed activity
116 r.setState(RESUMED, "testResumedActivityFromTaskReparenting");
117 assertEquals(mStack.getResumedActivity(), r);
118
119 final ActivityStack destStack = mService.mStackSupervisor.getDefaultDisplay().createStack(
120 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
121
122 mTask.reparent(destStack, true /* toTop */, TaskRecord.REPARENT_KEEP_STACK_AT_FRONT,
123 false /* animate */, true /* deferResume*/,
124 "testResumedActivityFromTaskReparenting");
125
126 assertEquals(mStack.getResumedActivity(), null);
127 assertEquals(destStack.getResumedActivity(), r);
128 }
129
130 @Test
131 public void testResumedActivityFromActivityReparenting() {
132 final ActivityRecord r = new ActivityBuilder(mService).setTask(mTask).build();
133 // Ensure moving task between two stacks updates resumed activity
134 r.setState(RESUMED, "testResumedActivityFromActivityReparenting");
135 assertEquals(mStack.getResumedActivity(), r);
136
137 final ActivityStack destStack = mService.mStackSupervisor.getDefaultDisplay().createStack(
138 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
139 final TaskRecord destTask = new TaskBuilder(mSupervisor).setStack(destStack).build();
140
141 mTask.removeActivity(r);
142 destTask.addActivityToTop(r);
143
144 assertEquals(mStack.getResumedActivity(), null);
145 assertEquals(destStack.getResumedActivity(), r);
Bryce Lee5daa3122017-04-19 10:40:42 -0700146 }
Bryce Lee3345c4e2017-04-25 07:40:41 -0700147
148 @Test
Evan Rosky10475742018-09-05 19:02:48 -0700149 public void testPrimarySplitScreenRestoresWhenMovedToBack() throws Exception {
Bryce Lee8cab4a02018-01-05 09:00:49 -0800150 // Create primary splitscreen stack. This will create secondary stacks and places the
151 // existing fullscreen stack on the bottom.
Winson Chung3e2980e2018-03-29 17:28:57 -0700152 final ActivityStack primarySplitScreen = mDefaultDisplay.createStack(
153 WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD, true /* onTop */);
Bryce Lee8cab4a02018-01-05 09:00:49 -0800154
155 // Assert windowing mode.
156 assertEquals(primarySplitScreen.getWindowingMode(), WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
157
158 // Move primary to back.
159 primarySplitScreen.moveToBack("testPrimarySplitScreenToFullscreenWhenMovedToBack",
160 null /* task */);
161
162 // Assert that stack is at the bottom.
Winson Chung3e2980e2018-03-29 17:28:57 -0700163 assertEquals(mDefaultDisplay.getIndexOf(primarySplitScreen), 0);
Bryce Lee8cab4a02018-01-05 09:00:49 -0800164
165 // Ensure no longer in splitscreen.
166 assertEquals(primarySplitScreen.getWindowingMode(), WINDOWING_MODE_FULLSCREEN);
Evan Rosky10475742018-09-05 19:02:48 -0700167
168 // Ensure that the override mode is restored to undefined
169 assertEquals(primarySplitScreen.getOverrideWindowingMode(), WINDOWING_MODE_UNDEFINED);
170 }
171
172 @Test
173 public void testPrimarySplitScreenRestoresPreviousWhenMovedToBack() throws Exception {
174 // This time, start with a fullscreen activitystack
175 final ActivityStack primarySplitScreen = mDefaultDisplay.createStack(
176 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
177
178 primarySplitScreen.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
179
180 // Assert windowing mode.
181 assertEquals(primarySplitScreen.getWindowingMode(), WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
182
183 // Move primary to back.
184 primarySplitScreen.moveToBack("testPrimarySplitScreenToFullscreenWhenMovedToBack",
185 null /* task */);
186
187 // Assert that stack is at the bottom.
188 assertEquals(mDefaultDisplay.getIndexOf(primarySplitScreen), 0);
189
190 // Ensure that the override mode is restored to what it was (fullscreen)
191 assertEquals(primarySplitScreen.getOverrideWindowingMode(), WINDOWING_MODE_FULLSCREEN);
192 }
193
194 @Test
195 public void testStackInheritsDisplayWindowingMode() throws Exception {
196 final ActivityStack primarySplitScreen = mDefaultDisplay.createStack(
197 WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD, true /* onTop */);
198
199 assertEquals(WINDOWING_MODE_FULLSCREEN, primarySplitScreen.getWindowingMode());
200 assertEquals(WINDOWING_MODE_UNDEFINED, primarySplitScreen.getOverrideWindowingMode());
201
202 mDefaultDisplay.setWindowingMode(WINDOWING_MODE_FREEFORM);
203 assertEquals(WINDOWING_MODE_FREEFORM, primarySplitScreen.getWindowingMode());
204 assertEquals(WINDOWING_MODE_UNDEFINED, primarySplitScreen.getOverrideWindowingMode());
205 }
206
207 @Test
208 public void testStackOverridesDisplayWindowingMode() throws Exception {
209 final ActivityStack primarySplitScreen = mDefaultDisplay.createStack(
210 WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD, true /* onTop */);
211
212 assertEquals(WINDOWING_MODE_FULLSCREEN, primarySplitScreen.getWindowingMode());
213 assertEquals(WINDOWING_MODE_UNDEFINED, primarySplitScreen.getOverrideWindowingMode());
214
215 primarySplitScreen.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
216 // setting windowing mode should still work even though resolved mode is already fullscreen
217 assertEquals(WINDOWING_MODE_FULLSCREEN, primarySplitScreen.getOverrideWindowingMode());
218
219 mDefaultDisplay.setWindowingMode(WINDOWING_MODE_FREEFORM);
220 assertEquals(WINDOWING_MODE_FULLSCREEN, primarySplitScreen.getWindowingMode());
Bryce Lee8cab4a02018-01-05 09:00:49 -0800221 }
222
223 @Test
Bryce Lee3345c4e2017-04-25 07:40:41 -0700224 public void testStopActivityWhenActivityDestroyed() throws Exception {
Bryce Lee18d51592017-10-25 10:22:19 -0700225 final ActivityRecord r = new ActivityBuilder(mService).setTask(mTask).build();
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700226 r.info.flags |= ActivityInfo.FLAG_NO_HISTORY;
Andrii Kulian6a6c4f12018-07-16 21:23:33 -0700227 mStack.moveToFront("testStopActivityWithDestroy");
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700228 mStack.stopActivityLocked(r);
229 // Mostly testing to make sure there is a crash in the call part, so if we get here we are
230 // good-to-go!
Bryce Lee3345c4e2017-04-25 07:40:41 -0700231 }
Bryce Lee9f6affd2017-09-01 09:18:35 -0700232
233 @Test
234 public void testFindTaskWithOverlay() throws Exception {
Bryce Lee18d51592017-10-25 10:22:19 -0700235 final ActivityRecord r = new ActivityBuilder(mService)
236 .setCreateTask(true)
237 .setStack(mStack)
238 .setUid(0)
239 .build();
240 final TaskRecord task = r.getTask();
Bryce Lee9f6affd2017-09-01 09:18:35 -0700241 // Overlay must be for a different user to prevent recognizing a matching top activity
Bryce Lee18d51592017-10-25 10:22:19 -0700242 final ActivityRecord taskOverlay = new ActivityBuilder(mService).setTask(task)
243 .setUid(UserHandle.PER_USER_RANGE * 2).build();
Bryce Lee9f6affd2017-09-01 09:18:35 -0700244 taskOverlay.mTaskOverlay = true;
245
Bryce Lee9f6affd2017-09-01 09:18:35 -0700246 final ActivityStackSupervisor.FindTaskResult result =
247 new ActivityStackSupervisor.FindTaskResult();
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700248 mStack.findTaskLocked(r, result);
Bryce Lee9f6affd2017-09-01 09:18:35 -0700249
Bryce Lee18d51592017-10-25 10:22:19 -0700250 assertEquals(task.getTopActivity(false /* includeOverlays */), r);
251 assertEquals(task.getTopActivity(true /* includeOverlays */), taskOverlay);
Louis Changc85b1a32018-08-14 16:40:53 +0800252 assertNotNull(result.mRecord);
Bryce Lee9f6affd2017-09-01 09:18:35 -0700253 }
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700254
255 @Test
256 public void testShouldBeVisible_Fullscreen() throws Exception {
Winson Chung3e2980e2018-03-29 17:28:57 -0700257 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700258 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
Winson Chung3e2980e2018-03-29 17:28:57 -0700259 final ActivityStack pinnedStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700260 WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, true /* onTop */);
261
262 assertTrue(homeStack.shouldBeVisible(null /* starting */));
263 assertTrue(pinnedStack.shouldBeVisible(null /* starting */));
264
Winson Chung3e2980e2018-03-29 17:28:57 -0700265 final TestActivityStack fullscreenStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700266 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
267 // Home stack shouldn't be visible behind an opaque fullscreen stack, but pinned stack
268 // should be visible since it is always on-top.
269 fullscreenStack.setIsTranslucent(false);
270 assertFalse(homeStack.shouldBeVisible(null /* starting */));
271 assertTrue(pinnedStack.shouldBeVisible(null /* starting */));
272 assertTrue(fullscreenStack.shouldBeVisible(null /* starting */));
273
274 // Home stack should be visible behind a translucent fullscreen stack.
275 fullscreenStack.setIsTranslucent(true);
276 assertTrue(homeStack.shouldBeVisible(null /* starting */));
277 assertTrue(pinnedStack.shouldBeVisible(null /* starting */));
278 }
279
280 @Test
281 public void testShouldBeVisible_SplitScreen() throws Exception {
Winson Chung3e2980e2018-03-29 17:28:57 -0700282 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700283 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
Wale Ogunwale30e441d2017-11-09 08:28:45 -0800284 // Home stack should always be fullscreen for this test.
285 homeStack.setSupportsSplitScreen(false);
Winson Chung3e2980e2018-03-29 17:28:57 -0700286 final TestActivityStack splitScreenPrimary = createStackForShouldBeVisibleTest(mDefaultDisplay,
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700287 WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD, true /* onTop */);
Winson Chung3e2980e2018-03-29 17:28:57 -0700288 final TestActivityStack splitScreenSecondary = createStackForShouldBeVisibleTest(mDefaultDisplay,
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700289 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD, true /* onTop */);
290
291 // Home stack shouldn't be visible if both halves of split-screen are opaque.
292 splitScreenPrimary.setIsTranslucent(false);
293 splitScreenSecondary.setIsTranslucent(false);
294 assertFalse(homeStack.shouldBeVisible(null /* starting */));
295 assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */));
296 assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
297
298 // Home stack should be visible if one of the halves of split-screen is translucent.
299 splitScreenPrimary.setIsTranslucent(true);
300 assertTrue(homeStack.shouldBeVisible(null /* starting */));
301 assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */));
302 assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
303
Winson Chung3e2980e2018-03-29 17:28:57 -0700304 final TestActivityStack splitScreenSecondary2 = createStackForShouldBeVisibleTest(mDefaultDisplay,
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700305 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD, true /* onTop */);
306 // First split-screen secondary shouldn't be visible behind another opaque split-split
307 // secondary.
308 splitScreenSecondary2.setIsTranslucent(false);
309 assertFalse(splitScreenSecondary.shouldBeVisible(null /* starting */));
310 assertTrue(splitScreenSecondary2.shouldBeVisible(null /* starting */));
311
Wale Ogunwale8e923af2018-03-23 08:48:11 -0700312 // First split-screen secondary should be visible behind another translucent split-screen
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700313 // secondary.
314 splitScreenSecondary2.setIsTranslucent(true);
315 assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
316 assertTrue(splitScreenSecondary2.shouldBeVisible(null /* starting */));
317
Winson Chung3e2980e2018-03-29 17:28:57 -0700318 final TestActivityStack assistantStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700319 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_ASSISTANT, true /* onTop */);
320
321 // Split-screen stacks shouldn't be visible behind an opaque fullscreen stack.
322 assistantStack.setIsTranslucent(false);
323 assertTrue(assistantStack.shouldBeVisible(null /* starting */));
324 assertFalse(splitScreenPrimary.shouldBeVisible(null /* starting */));
325 assertFalse(splitScreenSecondary.shouldBeVisible(null /* starting */));
326 assertFalse(splitScreenSecondary2.shouldBeVisible(null /* starting */));
327
328 // Split-screen stacks should be visible behind a translucent fullscreen stack.
329 assistantStack.setIsTranslucent(true);
330 assertTrue(assistantStack.shouldBeVisible(null /* starting */));
331 assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */));
332 assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
333 assertTrue(splitScreenSecondary2.shouldBeVisible(null /* starting */));
Wale Ogunwale8e923af2018-03-23 08:48:11 -0700334
335 // Assistant stack shouldn't be visible behind translucent split-screen stack
336 assistantStack.setIsTranslucent(false);
337 splitScreenPrimary.setIsTranslucent(true);
338 splitScreenSecondary2.setIsTranslucent(true);
339 splitScreenSecondary2.moveToFront("testShouldBeVisible_SplitScreen");
340 splitScreenPrimary.moveToFront("testShouldBeVisible_SplitScreen");
341 assertFalse(assistantStack.shouldBeVisible(null /* starting */));
342 assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */));
343 assertTrue(splitScreenSecondary2.shouldBeVisible(null /* starting */));
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700344 }
345
346 @Test
347 public void testShouldBeVisible_Finishing() throws Exception {
Winson Chung3e2980e2018-03-29 17:28:57 -0700348 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700349 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
Winson Chung3e2980e2018-03-29 17:28:57 -0700350 final TestActivityStack translucentStack = createStackForShouldBeVisibleTest(
351 mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
352 true /* onTop */);
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700353 translucentStack.setIsTranslucent(true);
354
355 assertTrue(homeStack.shouldBeVisible(null /* starting */));
356 assertTrue(translucentStack.shouldBeVisible(null /* starting */));
357
358 final ActivityRecord topRunningHomeActivity = homeStack.topRunningActivityLocked();
359 topRunningHomeActivity.finishing = true;
360 final ActivityRecord topRunningTranslucentActivity =
361 translucentStack.topRunningActivityLocked();
362 topRunningTranslucentActivity.finishing = true;
363
364 // Home shouldn't be visible since its activity is marked as finishing and it isn't the top
365 // of the stack list.
366 assertFalse(homeStack.shouldBeVisible(null /* starting */));
367 // Home should be visible if we are starting an activity within it.
368 assertTrue(homeStack.shouldBeVisible(topRunningHomeActivity /* starting */));
369 // The translucent stack should be visible since it is the top of the stack list even though
370 // it has its activity marked as finishing.
371 assertTrue(translucentStack.shouldBeVisible(null /* starting */));
372 }
373
Winson Chungd922b6b2018-02-16 16:41:50 -0800374 @Test
375 public void testMoveHomeStackBehindBottomMostVisibleStack_NoMoveHomeBehindFullscreen() {
Winson Chung3e2980e2018-03-29 17:28:57 -0700376 mDefaultDisplay.removeChild(mStack);
Winson Chungd922b6b2018-02-16 16:41:50 -0800377
Winson Chung3e2980e2018-03-29 17:28:57 -0700378 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Winson Chungd922b6b2018-02-16 16:41:50 -0800379 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
Winson Chung3e2980e2018-03-29 17:28:57 -0700380 final TestActivityStack fullscreenStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Winson Chungd922b6b2018-02-16 16:41:50 -0800381 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
382
383 homeStack.setIsTranslucent(false);
384 fullscreenStack.setIsTranslucent(false);
385
386 // 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 -0700387 int homeStackIndex = mDefaultDisplay.getIndexOf(homeStack);
388 assertTrue(mDefaultDisplay.getStackAbove(homeStack) == fullscreenStack);
389 mDefaultDisplay.moveStackBehindBottomMostVisibleStack(homeStack);
390 assertTrue(mDefaultDisplay.getIndexOf(homeStack) == homeStackIndex);
Winson Chungd922b6b2018-02-16 16:41:50 -0800391 }
392
393 @Test
394 public void testMoveHomeStackBehindBottomMostVisibleStack_NoMoveHomeBehindTranslucent() {
Winson Chung3e2980e2018-03-29 17:28:57 -0700395 mDefaultDisplay.removeChild(mStack);
Winson Chungd922b6b2018-02-16 16:41:50 -0800396
Winson Chung3e2980e2018-03-29 17:28:57 -0700397 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Winson Chungd922b6b2018-02-16 16:41:50 -0800398 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
Winson Chung3e2980e2018-03-29 17:28:57 -0700399 final TestActivityStack fullscreenStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Winson Chungd922b6b2018-02-16 16:41:50 -0800400 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
401
402 homeStack.setIsTranslucent(false);
403 fullscreenStack.setIsTranslucent(true);
404
405 // 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 -0700406 int homeStackIndex = mDefaultDisplay.getIndexOf(homeStack);
407 assertTrue(mDefaultDisplay.getStackAbove(homeStack) == fullscreenStack);
408 mDefaultDisplay.moveStackBehindBottomMostVisibleStack(homeStack);
409 assertTrue(mDefaultDisplay.getIndexOf(homeStack) == homeStackIndex);
Winson Chungd922b6b2018-02-16 16:41:50 -0800410 }
411
412 @Test
413 public void testMoveHomeStackBehindBottomMostVisibleStack_NoMoveHomeOnTop() {
Winson Chung3e2980e2018-03-29 17:28:57 -0700414 mDefaultDisplay.removeChild(mStack);
Winson Chungd922b6b2018-02-16 16:41:50 -0800415
Winson Chung3e2980e2018-03-29 17:28:57 -0700416 final TestActivityStack fullscreenStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Winson Chungd922b6b2018-02-16 16:41:50 -0800417 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
Winson Chung3e2980e2018-03-29 17:28:57 -0700418 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Winson Chungd922b6b2018-02-16 16:41:50 -0800419 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
420
421 homeStack.setIsTranslucent(false);
422 fullscreenStack.setIsTranslucent(false);
423
424 // Ensure we don't move the home stack if it is already on top
Winson Chung3e2980e2018-03-29 17:28:57 -0700425 int homeStackIndex = mDefaultDisplay.getIndexOf(homeStack);
426 assertTrue(mDefaultDisplay.getStackAbove(homeStack) == null);
427 mDefaultDisplay.moveStackBehindBottomMostVisibleStack(homeStack);
428 assertTrue(mDefaultDisplay.getIndexOf(homeStack) == homeStackIndex);
Winson Chungd922b6b2018-02-16 16:41:50 -0800429 }
430
431 @Test
432 public void testMoveHomeStackBehindBottomMostVisibleStack_MoveHomeBehindFullscreen() {
Winson Chung3e2980e2018-03-29 17:28:57 -0700433 mDefaultDisplay.removeChild(mStack);
Winson Chungd922b6b2018-02-16 16:41:50 -0800434
Winson Chung3e2980e2018-03-29 17:28:57 -0700435 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Winson Chungd922b6b2018-02-16 16:41:50 -0800436 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
Winson Chung3e2980e2018-03-29 17:28:57 -0700437 final TestActivityStack fullscreenStack1 = createStackForShouldBeVisibleTest(
438 mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
439 true /* onTop */);
440 final TestActivityStack fullscreenStack2 = createStackForShouldBeVisibleTest(
441 mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
442 true /* onTop */);
443 final TestActivityStack pinnedStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Winson Chungd922b6b2018-02-16 16:41:50 -0800444 WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, true /* onTop */);
445
446 homeStack.setIsTranslucent(false);
447 fullscreenStack1.setIsTranslucent(false);
448 fullscreenStack2.setIsTranslucent(false);
449
450 // Ensure that we move the home stack behind the bottom most fullscreen stack, ignoring the
451 // pinned stack
Winson Chung3e2980e2018-03-29 17:28:57 -0700452 assertTrue(mDefaultDisplay.getStackAbove(homeStack) == fullscreenStack1);
453 mDefaultDisplay.moveStackBehindBottomMostVisibleStack(homeStack);
454 assertTrue(mDefaultDisplay.getStackAbove(homeStack) == fullscreenStack2);
Winson Chungd922b6b2018-02-16 16:41:50 -0800455 }
456
457 @Test
458 public void testMoveHomeStackBehindBottomMostVisibleStack_MoveHomeBehindFullscreenAndTranslucent() {
Winson Chung3e2980e2018-03-29 17:28:57 -0700459 mDefaultDisplay.removeChild(mStack);
Winson Chungd922b6b2018-02-16 16:41:50 -0800460
Winson Chung3e2980e2018-03-29 17:28:57 -0700461 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Winson Chungd922b6b2018-02-16 16:41:50 -0800462 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
Winson Chung3e2980e2018-03-29 17:28:57 -0700463 final TestActivityStack fullscreenStack1 = createStackForShouldBeVisibleTest(
464 mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
465 true /* onTop */);
466 final TestActivityStack fullscreenStack2 = createStackForShouldBeVisibleTest(
467 mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
468 true /* onTop */);
Winson Chungd922b6b2018-02-16 16:41:50 -0800469
470 homeStack.setIsTranslucent(false);
471 fullscreenStack1.setIsTranslucent(false);
472 fullscreenStack2.setIsTranslucent(true);
473
474 // Ensure that we move the home stack behind the bottom most non-translucent fullscreen
475 // stack
Winson Chung3e2980e2018-03-29 17:28:57 -0700476 assertTrue(mDefaultDisplay.getStackAbove(homeStack) == fullscreenStack1);
477 mDefaultDisplay.moveStackBehindBottomMostVisibleStack(homeStack);
478 assertTrue(mDefaultDisplay.getStackAbove(homeStack) == fullscreenStack1);
Winson Chungd922b6b2018-02-16 16:41:50 -0800479 }
480
481 @Test
482 public void testMoveHomeStackBehindStack_BehindHomeStack() {
Winson Chung3e2980e2018-03-29 17:28:57 -0700483 mDefaultDisplay.removeChild(mStack);
Winson Chungd922b6b2018-02-16 16:41:50 -0800484
Winson Chung3e2980e2018-03-29 17:28:57 -0700485 final TestActivityStack fullscreenStack1 = createStackForShouldBeVisibleTest(
486 mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
487 true /* onTop */);
488 final TestActivityStack fullscreenStack2 = createStackForShouldBeVisibleTest(
489 mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
490 true /* onTop */);
491 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Winson Chungd922b6b2018-02-16 16:41:50 -0800492 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
493
494 homeStack.setIsTranslucent(false);
495 fullscreenStack1.setIsTranslucent(false);
496 fullscreenStack2.setIsTranslucent(false);
497
498 // Ensure we don't move the home stack behind itself
Winson Chung3e2980e2018-03-29 17:28:57 -0700499 int homeStackIndex = mDefaultDisplay.getIndexOf(homeStack);
500 mDefaultDisplay.moveStackBehindStack(homeStack, homeStack);
501 assertTrue(mDefaultDisplay.getIndexOf(homeStack) == homeStackIndex);
Winson Chungd922b6b2018-02-16 16:41:50 -0800502 }
503
504 @Test
505 public void testMoveHomeStackBehindStack() {
Winson Chung3e2980e2018-03-29 17:28:57 -0700506 mDefaultDisplay.removeChild(mStack);
Winson Chungd922b6b2018-02-16 16:41:50 -0800507
Winson Chung3e2980e2018-03-29 17:28:57 -0700508 final TestActivityStack fullscreenStack1 = createStackForShouldBeVisibleTest(
509 mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
510 true /* onTop */);
511 final TestActivityStack fullscreenStack2 = createStackForShouldBeVisibleTest(
512 mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
513 true /* onTop */);
514 final TestActivityStack fullscreenStack3 = createStackForShouldBeVisibleTest(
515 mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
516 true /* onTop */);
517 final TestActivityStack fullscreenStack4 = createStackForShouldBeVisibleTest(
518 mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
519 true /* onTop */);
520 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Winson Chungd922b6b2018-02-16 16:41:50 -0800521 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
522
Winson Chung3e2980e2018-03-29 17:28:57 -0700523 mDefaultDisplay.moveStackBehindStack(homeStack, fullscreenStack1);
524 assertTrue(mDefaultDisplay.getStackAbove(homeStack) == fullscreenStack1);
525 mDefaultDisplay.moveStackBehindStack(homeStack, fullscreenStack2);
526 assertTrue(mDefaultDisplay.getStackAbove(homeStack) == fullscreenStack2);
527 mDefaultDisplay.moveStackBehindStack(homeStack, fullscreenStack4);
528 assertTrue(mDefaultDisplay.getStackAbove(homeStack) == fullscreenStack4);
529 mDefaultDisplay.moveStackBehindStack(homeStack, fullscreenStack2);
530 assertTrue(mDefaultDisplay.getStackAbove(homeStack) == fullscreenStack2);
Winson Chungd922b6b2018-02-16 16:41:50 -0800531 }
532
Wale Ogunwalebb285872018-03-01 13:05:30 -0800533 @Test
Kazuki Takisef85197b2018-06-18 18:18:36 +0900534 public void testSetAlwaysOnTop() {
535 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
536 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
537 final ActivityStack pinnedStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
538 WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, true /* onTop */);
539 assertTrue(mDefaultDisplay.getStackAbove(homeStack) == pinnedStack);
540
541 final TestActivityStack alwaysOnTopStack = createStackForShouldBeVisibleTest(
542 mDefaultDisplay, WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD,
543 true /* onTop */);
544 alwaysOnTopStack.setAlwaysOnTop(true);
545 assertTrue(alwaysOnTopStack.isAlwaysOnTop());
546 // Ensure (non-pinned) always on top stack is put below pinned stack.
547 assertTrue(mDefaultDisplay.getStackAbove(alwaysOnTopStack) == pinnedStack);
548
549 final TestActivityStack nonAlwaysOnTopStack = createStackForShouldBeVisibleTest(
550 mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
551 true /* onTop */);
552 // Ensure non always on top stack is put below always on top stacks.
553 assertTrue(mDefaultDisplay.getStackAbove(nonAlwaysOnTopStack) == alwaysOnTopStack);
554
555 final TestActivityStack alwaysOnTopStack2 = createStackForShouldBeVisibleTest(
556 mDefaultDisplay, WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD,
557 true /* onTop */);
558 alwaysOnTopStack2.setAlwaysOnTop(true);
559 assertTrue(alwaysOnTopStack2.isAlwaysOnTop());
560 // Ensure newly created always on top stack is placed above other all always on top stacks.
561 assertTrue(mDefaultDisplay.getStackAbove(alwaysOnTopStack2) == pinnedStack);
562
563 alwaysOnTopStack2.setAlwaysOnTop(false);
564 // Ensure, when always on top is turned off for a stack, the stack is put just below all
565 // other always on top stacks.
566 assertTrue(mDefaultDisplay.getStackAbove(alwaysOnTopStack2) == alwaysOnTopStack);
Kazuki Takise048e2662018-06-27 17:05:11 +0900567 alwaysOnTopStack2.setAlwaysOnTop(true);
568
569 // Ensure always on top state changes properly when windowing mode changes.
570 alwaysOnTopStack2.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
571 assertFalse(alwaysOnTopStack2.isAlwaysOnTop());
572 assertTrue(mDefaultDisplay.getStackAbove(alwaysOnTopStack2) == alwaysOnTopStack);
573 alwaysOnTopStack2.setWindowingMode(WINDOWING_MODE_FREEFORM);
574 assertTrue(alwaysOnTopStack2.isAlwaysOnTop());
575 assertTrue(mDefaultDisplay.getStackAbove(alwaysOnTopStack2) == pinnedStack);
Kazuki Takisef85197b2018-06-18 18:18:36 +0900576 }
577
578 @Test
Wale Ogunwalebb285872018-03-01 13:05:30 -0800579 public void testSplitScreenMoveToFront() throws Exception {
Winson Chung3e2980e2018-03-29 17:28:57 -0700580 final TestActivityStack splitScreenPrimary = createStackForShouldBeVisibleTest(
581 mDefaultDisplay, WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD,
582 true /* onTop */);
583 final TestActivityStack splitScreenSecondary = createStackForShouldBeVisibleTest(
584 mDefaultDisplay, WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD,
585 true /* onTop */);
586 final TestActivityStack assistantStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
Wale Ogunwalebb285872018-03-01 13:05:30 -0800587 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_ASSISTANT, true /* onTop */);
588
589 splitScreenPrimary.setIsTranslucent(false);
590 splitScreenSecondary.setIsTranslucent(false);
591 assistantStack.setIsTranslucent(false);
592
593 assertFalse(splitScreenPrimary.shouldBeVisible(null /* starting */));
594 assertFalse(splitScreenSecondary.shouldBeVisible(null /* starting */));
595 assertTrue(assistantStack.shouldBeVisible(null /* starting */));
596
597 splitScreenSecondary.moveToFront("testSplitScreenMoveToFront");
598
599 assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */));
600 assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
601 assertFalse(assistantStack.shouldBeVisible(null /* starting */));
602 }
603
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700604 private <T extends ActivityStack> T createStackForShouldBeVisibleTest(
605 ActivityDisplay display, int windowingMode, int activityType, boolean onTop) {
Andrii Kulian6a6c4f12018-07-16 21:23:33 -0700606 final T stack;
607 if (activityType == ACTIVITY_TYPE_HOME) {
608 // Home stack and activity are created in ActivityTestsBase#setupActivityManagerService
609 stack = mDefaultDisplay.getStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME);
610 if (onTop) {
Riddle Hsu57831b52018-07-27 00:31:48 +0800611 mDefaultDisplay.positionChildAtTop(stack, false /* includingParents */);
Andrii Kulian6a6c4f12018-07-16 21:23:33 -0700612 } else {
613 mDefaultDisplay.positionChildAtBottom(stack);
614 }
615 } else {
616 stack = display.createStack(windowingMode, activityType, onTop);
617 final ActivityRecord r = new ActivityBuilder(mService).setUid(0).setStack(stack)
618 .setCreateTask(true).build();
619 }
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700620 return stack;
621 }
Bryce Leeb0f993f2018-03-02 15:38:01 -0800622
623 @Test
Bryce Leefbd263b42018-03-07 10:33:55 -0800624 public void testFinishDisabledPackageActivities() throws Exception {
625 final ActivityRecord firstActivity = new ActivityBuilder(mService).setTask(mTask).build();
626 final ActivityRecord secondActivity = new ActivityBuilder(mService).setTask(mTask).build();
627
628 // Making the second activity a task overlay without an app means it will be removed from
629 // the task's activities as well once first activity is removed.
630 secondActivity.mTaskOverlay = true;
631 secondActivity.app = null;
632
633 assertEquals(mTask.mActivities.size(), 2);
634
635 mStack.finishDisabledPackageActivitiesLocked(firstActivity.packageName, null,
636 true /* doit */, true /* evenPersistent */, UserHandle.USER_ALL);
637
638 assertTrue(mTask.mActivities.isEmpty());
639 assertTrue(mStack.getAllTasks().isEmpty());
640 }
641
642 @Test
643 public void testHandleAppDied() throws Exception {
644 final ActivityRecord firstActivity = new ActivityBuilder(mService).setTask(mTask).build();
645 final ActivityRecord secondActivity = new ActivityBuilder(mService).setTask(mTask).build();
646
647 // Making the first activity a task overlay means it will be removed from the task's
648 // activities as well once second activity is removed as handleAppDied processes the
649 // activity list in reverse.
650 firstActivity.mTaskOverlay = true;
651 firstActivity.app = null;
652
653 // second activity will be immediately removed as it has no state.
654 secondActivity.haveState = false;
655
656 assertEquals(mTask.mActivities.size(), 2);
657
658 mStack.handleAppDiedLocked(secondActivity.app);
659
660 assertTrue(mTask.mActivities.isEmpty());
661 assertTrue(mStack.getAllTasks().isEmpty());
662 }
Bryce Lee271617a2018-03-15 10:39:12 -0700663
664 @Test
Riddle Hsue10cea52018-10-16 23:33:23 +0800665 public void testFinishCurrentActivity() {
666 // Create 2 activities on a new display.
667 final ActivityDisplay display = addNewActivityDisplayAt(ActivityDisplay.POSITION_TOP);
668 final ActivityStack stack1 = createStackForShouldBeVisibleTest(display,
669 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
670 final ActivityStack stack2 = createStackForShouldBeVisibleTest(display,
671 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
672
673 // There is still an activity1 in stack1 so the activity2 should be added to finishing list
674 // that will be destroyed until idle.
675 final ActivityRecord activity2 = finishCurrentActivity(stack2);
676 assertEquals(FINISHING, activity2.getState());
677 assertTrue(mSupervisor.mFinishingActivities.contains(activity2));
678
679 // The display becomes empty. Since there is no next activity to be idle, the activity
680 // should be destroyed immediately with updating configuration to restore original state.
681 final ActivityRecord activity1 = finishCurrentActivity(stack1);
682 assertEquals(DESTROYING, activity1.getState());
683 verify(mSupervisor).ensureVisibilityAndConfig(eq(null) /* starting */,
684 eq(display.mDisplayId), anyBoolean(), anyBoolean());
685 }
686
687 private ActivityRecord finishCurrentActivity(ActivityStack stack) {
688 final ActivityRecord activity = stack.topRunningActivityLocked();
689 assertNotNull(activity);
690 activity.setState(PAUSED, "finishCurrentActivity");
691 activity.makeFinishingLocked();
692 stack.finishCurrentActivityLocked(activity, ActivityStack.FINISH_AFTER_VISIBLE,
693 false /* oomAdj */, "finishCurrentActivity");
694 return activity;
695 }
696
697 @Test
Bryce Lee271617a2018-03-15 10:39:12 -0700698 public void testShouldSleepActivities() throws Exception {
699 // When focused activity and keyguard is going away, we should not sleep regardless
700 // of the display state
701 verifyShouldSleepActivities(true /* focusedStack */, true /*keyguardGoingAway*/,
702 true /* displaySleeping */, false /* expected*/);
703
704 // When not the focused stack, defer to display sleeping state.
705 verifyShouldSleepActivities(false /* focusedStack */, true /*keyguardGoingAway*/,
706 true /* displaySleeping */, true /* expected*/);
707
708 // If keyguard is going away, defer to the display sleeping state.
709 verifyShouldSleepActivities(true /* focusedStack */, false /*keyguardGoingAway*/,
710 true /* displaySleeping */, true /* expected*/);
711 verifyShouldSleepActivities(true /* focusedStack */, false /*keyguardGoingAway*/,
712 false /* displaySleeping */, false /* expected*/);
713 }
714
Winson Chung0f7ec962018-05-03 18:03:15 -0700715 @Test
716 public void testStackOrderChangedOnRemoveStack() throws Exception {
717 StackOrderChangedListener listener = new StackOrderChangedListener();
718 mDefaultDisplay.registerStackOrderChangedListener(listener);
719 try {
720 mDefaultDisplay.removeChild(mStack);
721 } finally {
722 mDefaultDisplay.unregisterStackOrderChangedListener(listener);
723 }
724 assertTrue(listener.changed);
725 }
726
727 @Test
728 public void testStackOrderChangedOnAddPositionStack() throws Exception {
729 mDefaultDisplay.removeChild(mStack);
730
731 StackOrderChangedListener listener = new StackOrderChangedListener();
732 mDefaultDisplay.registerStackOrderChangedListener(listener);
733 try {
734 mDefaultDisplay.addChild(mStack, 0);
735 } finally {
736 mDefaultDisplay.unregisterStackOrderChangedListener(listener);
737 }
738 assertTrue(listener.changed);
739 }
740
741 @Test
742 public void testStackOrderChangedOnPositionStack() throws Exception {
743 StackOrderChangedListener listener = new StackOrderChangedListener();
744 try {
745 final TestActivityStack fullscreenStack1 = createStackForShouldBeVisibleTest(
746 mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
747 true /* onTop */);
748 mDefaultDisplay.registerStackOrderChangedListener(listener);
749 mDefaultDisplay.positionChildAtBottom(fullscreenStack1);
750 } finally {
751 mDefaultDisplay.unregisterStackOrderChangedListener(listener);
752 }
753 assertTrue(listener.changed);
754 }
755
Bryce Lee271617a2018-03-15 10:39:12 -0700756 private void verifyShouldSleepActivities(boolean focusedStack,
757 boolean keyguardGoingAway, boolean displaySleeping, boolean expected) {
Bryce Lee271617a2018-03-15 10:39:12 -0700758 final ActivityDisplay display = mock(ActivityDisplay.class);
759 final KeyguardController keyguardController = mSupervisor.getKeyguardController();
760
761 doReturn(display).when(mSupervisor).getActivityDisplay(anyInt());
762 doReturn(keyguardGoingAway).when(keyguardController).isKeyguardGoingAway();
763 doReturn(displaySleeping).when(display).isSleeping();
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800764 doReturn(focusedStack).when(mStack).isFocusedStackOnDisplay();
Bryce Lee271617a2018-03-15 10:39:12 -0700765
766 assertEquals(expected, mStack.shouldSleepActivities());
767 }
Winson Chung0f7ec962018-05-03 18:03:15 -0700768
769 private class StackOrderChangedListener implements ActivityDisplay.OnStackOrderChangedListener {
770 boolean changed = false;
771
772 @Override
773 public void onStackOrderChanged() {
774 changed = true;
775 }
776 }
Bryce Lee840c5662017-04-13 10:02:51 -0700777}