blob: bcbf40e191e69ba816a69fd36cc72aa938bbb39b [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
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070027import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_DESTROYING;
Bryce Lee18d51592017-10-25 10:22:19 -070028
Bryce Lee5daa3122017-04-19 10:40:42 -070029import static org.junit.Assert.assertEquals;
David Stevens18abd0e2017-08-17 14:55:47 -070030import static org.junit.Assert.assertFalse;
Bryce Lee840c5662017-04-13 10:02:51 -070031import static org.junit.Assert.assertNotNull;
32import static org.junit.Assert.assertNull;
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -070033import static org.junit.Assert.assertTrue;
Bryce Lee840c5662017-04-13 10:02:51 -070034
35import android.content.ComponentName;
Bryce Lee3345c4e2017-04-25 07:40:41 -070036import android.content.pm.ActivityInfo;
Bryce Lee9f6affd2017-09-01 09:18:35 -070037import android.os.UserHandle;
Bryce Lee840c5662017-04-13 10:02:51 -070038import android.platform.test.annotations.Presubmit;
39import android.support.test.filters.SmallTest;
40import android.support.test.runner.AndroidJUnit4;
41
42import org.junit.runner.RunWith;
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070043import org.junit.Before;
Bryce Lee840c5662017-04-13 10:02:51 -070044import org.junit.Test;
45
46/**
47 * Tests for the {@link ActivityStack} class.
48 *
49 * Build/Install/Run:
Bryce Lee8cab4a02018-01-05 09:00:49 -080050 * atest ActivityStackTests
Bryce Lee840c5662017-04-13 10:02:51 -070051 */
52@SmallTest
53@Presubmit
54@RunWith(AndroidJUnit4.class)
55public class ActivityStackTests extends ActivityTestsBase {
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070056 private ActivityManagerService mService;
57 private ActivityStackSupervisor mSupervisor;
58 private ActivityStack mStack;
59 private TaskRecord mTask;
60
61 @Before
62 @Override
63 public void setUp() throws Exception {
64 super.setUp();
65
66 mService = createActivityManagerService();
67 mSupervisor = mService.mStackSupervisor;
68 mStack = mService.mStackSupervisor.getDefaultDisplay().createStack(
69 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
Bryce Lee18d51592017-10-25 10:22:19 -070070 mTask = new TaskBuilder(mSupervisor).setStack(mStack).build();
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070071 }
72
Bryce Lee840c5662017-04-13 10:02:51 -070073 @Test
74 public void testEmptyTaskCleanupOnRemove() throws Exception {
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070075 assertNotNull(mTask.getWindowContainerController());
76 mStack.removeTask(mTask, "testEmptyTaskCleanupOnRemove", REMOVE_TASK_MODE_DESTROYING);
77 assertNull(mTask.getWindowContainerController());
Bryce Lee840c5662017-04-13 10:02:51 -070078 }
Bryce Lee5daa3122017-04-19 10:40:42 -070079
Bryce Lee840c5662017-04-13 10:02:51 -070080 @Test
81 public void testOccupiedTaskCleanupOnRemove() throws Exception {
Bryce Lee18d51592017-10-25 10:22:19 -070082 final ActivityRecord r = new ActivityBuilder(mService).setTask(mTask).build();
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070083 assertNotNull(mTask.getWindowContainerController());
84 mStack.removeTask(mTask, "testOccupiedTaskCleanupOnRemove", REMOVE_TASK_MODE_DESTROYING);
85 assertNotNull(mTask.getWindowContainerController());
Bryce Lee840c5662017-04-13 10:02:51 -070086 }
Bryce Lee5daa3122017-04-19 10:40:42 -070087
88 @Test
89 public void testNoPauseDuringResumeTopActivity() throws Exception {
Bryce Lee18d51592017-10-25 10:22:19 -070090 final ActivityRecord r = new ActivityBuilder(mService).setTask(mTask).build();
Bryce Lee5daa3122017-04-19 10:40:42 -070091
92 // Simulate the a resumed activity set during
93 // {@link ActivityStack#resumeTopActivityUncheckedLocked}.
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070094 mSupervisor.inResumeTopActivity = true;
95 mStack.mResumedActivity = r;
Bryce Lee5daa3122017-04-19 10:40:42 -070096
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070097 final boolean waiting = mStack.goToSleepIfPossible(false);
Bryce Lee5daa3122017-04-19 10:40:42 -070098
99 // Ensure we report not being ready for sleep.
David Stevens18abd0e2017-08-17 14:55:47 -0700100 assertFalse(waiting);
Bryce Lee5daa3122017-04-19 10:40:42 -0700101
102 // Make sure the resumed activity is untouched.
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700103 assertEquals(mStack.mResumedActivity, r);
Bryce Lee5daa3122017-04-19 10:40:42 -0700104 }
Bryce Lee3345c4e2017-04-25 07:40:41 -0700105
106 @Test
Bryce Lee8cab4a02018-01-05 09:00:49 -0800107 public void testPrimarySplitScreenToFullscreenWhenMovedToBack() throws Exception {
108 // Create primary splitscreen stack. This will create secondary stacks and places the
109 // existing fullscreen stack on the bottom.
110 final ActivityStack primarySplitScreen = mService.mStackSupervisor.getDefaultDisplay()
111 .createStack(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD,
112 true /* onTop */);
113
114 // Assert windowing mode.
115 assertEquals(primarySplitScreen.getWindowingMode(), WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
116
117 // Move primary to back.
118 primarySplitScreen.moveToBack("testPrimarySplitScreenToFullscreenWhenMovedToBack",
119 null /* task */);
120
121 // Assert that stack is at the bottom.
122 assertEquals(mService.mStackSupervisor.getDefaultDisplay().getIndexOf(primarySplitScreen),
123 0);
124
125 // Ensure no longer in splitscreen.
126 assertEquals(primarySplitScreen.getWindowingMode(), WINDOWING_MODE_FULLSCREEN);
127 }
128
129 @Test
Bryce Lee3345c4e2017-04-25 07:40:41 -0700130 public void testStopActivityWhenActivityDestroyed() throws Exception {
Bryce Lee18d51592017-10-25 10:22:19 -0700131 final ActivityRecord r = new ActivityBuilder(mService).setTask(mTask).build();
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700132 r.info.flags |= ActivityInfo.FLAG_NO_HISTORY;
133 mSupervisor.setFocusStackUnchecked("testStopActivityWithDestroy", mStack);
134 mStack.stopActivityLocked(r);
135 // Mostly testing to make sure there is a crash in the call part, so if we get here we are
136 // good-to-go!
Bryce Lee3345c4e2017-04-25 07:40:41 -0700137 }
Bryce Lee9f6affd2017-09-01 09:18:35 -0700138
139 @Test
140 public void testFindTaskWithOverlay() throws Exception {
Bryce Lee18d51592017-10-25 10:22:19 -0700141 final ActivityRecord r = new ActivityBuilder(mService)
142 .setCreateTask(true)
143 .setStack(mStack)
144 .setUid(0)
145 .build();
146 final TaskRecord task = r.getTask();
Bryce Lee9f6affd2017-09-01 09:18:35 -0700147 // Overlay must be for a different user to prevent recognizing a matching top activity
Bryce Lee18d51592017-10-25 10:22:19 -0700148 final ActivityRecord taskOverlay = new ActivityBuilder(mService).setTask(task)
149 .setUid(UserHandle.PER_USER_RANGE * 2).build();
Bryce Lee9f6affd2017-09-01 09:18:35 -0700150 taskOverlay.mTaskOverlay = true;
151
Bryce Lee9f6affd2017-09-01 09:18:35 -0700152 final ActivityStackSupervisor.FindTaskResult result =
153 new ActivityStackSupervisor.FindTaskResult();
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700154 mStack.findTaskLocked(r, result);
Bryce Lee9f6affd2017-09-01 09:18:35 -0700155
Bryce Lee18d51592017-10-25 10:22:19 -0700156 assertEquals(task.getTopActivity(false /* includeOverlays */), r);
157 assertEquals(task.getTopActivity(true /* includeOverlays */), taskOverlay);
Bryce Lee9f6affd2017-09-01 09:18:35 -0700158 assertNotNull(result.r);
159 }
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700160
161 @Test
162 public void testShouldBeVisible_Fullscreen() throws Exception {
163 final ActivityDisplay display = mService.mStackSupervisor.getDefaultDisplay();
164 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(display,
165 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
166 final ActivityStack pinnedStack = createStackForShouldBeVisibleTest(display,
167 WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, true /* onTop */);
168
169 assertTrue(homeStack.shouldBeVisible(null /* starting */));
170 assertTrue(pinnedStack.shouldBeVisible(null /* starting */));
171
172 final TestActivityStack fullscreenStack = createStackForShouldBeVisibleTest(display,
173 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
174 // Home stack shouldn't be visible behind an opaque fullscreen stack, but pinned stack
175 // should be visible since it is always on-top.
176 fullscreenStack.setIsTranslucent(false);
177 assertFalse(homeStack.shouldBeVisible(null /* starting */));
178 assertTrue(pinnedStack.shouldBeVisible(null /* starting */));
179 assertTrue(fullscreenStack.shouldBeVisible(null /* starting */));
180
181 // Home stack should be visible behind a translucent fullscreen stack.
182 fullscreenStack.setIsTranslucent(true);
183 assertTrue(homeStack.shouldBeVisible(null /* starting */));
184 assertTrue(pinnedStack.shouldBeVisible(null /* starting */));
185 }
186
187 @Test
188 public void testShouldBeVisible_SplitScreen() throws Exception {
189 final ActivityDisplay display = mService.mStackSupervisor.getDefaultDisplay();
190 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(display,
191 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
Wale Ogunwale30e441d2017-11-09 08:28:45 -0800192 // Home stack should always be fullscreen for this test.
193 homeStack.setSupportsSplitScreen(false);
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700194 final TestActivityStack splitScreenPrimary = createStackForShouldBeVisibleTest(display,
195 WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD, true /* onTop */);
196 final TestActivityStack splitScreenSecondary = createStackForShouldBeVisibleTest(display,
197 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD, true /* onTop */);
198
199 // Home stack shouldn't be visible if both halves of split-screen are opaque.
200 splitScreenPrimary.setIsTranslucent(false);
201 splitScreenSecondary.setIsTranslucent(false);
202 assertFalse(homeStack.shouldBeVisible(null /* starting */));
203 assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */));
204 assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
205
206 // Home stack should be visible if one of the halves of split-screen is translucent.
207 splitScreenPrimary.setIsTranslucent(true);
208 assertTrue(homeStack.shouldBeVisible(null /* starting */));
209 assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */));
210 assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
211
212 final TestActivityStack splitScreenSecondary2 = createStackForShouldBeVisibleTest(display,
213 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD, true /* onTop */);
214 // First split-screen secondary shouldn't be visible behind another opaque split-split
215 // secondary.
216 splitScreenSecondary2.setIsTranslucent(false);
217 assertFalse(splitScreenSecondary.shouldBeVisible(null /* starting */));
218 assertTrue(splitScreenSecondary2.shouldBeVisible(null /* starting */));
219
220 // First split-screen secondary should be visible behind another translucent split-split
221 // secondary.
222 splitScreenSecondary2.setIsTranslucent(true);
223 assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
224 assertTrue(splitScreenSecondary2.shouldBeVisible(null /* starting */));
225
226 final TestActivityStack assistantStack = createStackForShouldBeVisibleTest(display,
227 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_ASSISTANT, true /* onTop */);
228
229 // Split-screen stacks shouldn't be visible behind an opaque fullscreen stack.
230 assistantStack.setIsTranslucent(false);
231 assertTrue(assistantStack.shouldBeVisible(null /* starting */));
232 assertFalse(splitScreenPrimary.shouldBeVisible(null /* starting */));
233 assertFalse(splitScreenSecondary.shouldBeVisible(null /* starting */));
234 assertFalse(splitScreenSecondary2.shouldBeVisible(null /* starting */));
235
236 // Split-screen stacks should be visible behind a translucent fullscreen stack.
237 assistantStack.setIsTranslucent(true);
238 assertTrue(assistantStack.shouldBeVisible(null /* starting */));
239 assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */));
240 assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
241 assertTrue(splitScreenSecondary2.shouldBeVisible(null /* starting */));
242 }
243
244 @Test
245 public void testShouldBeVisible_Finishing() throws Exception {
246 final ActivityDisplay display = mService.mStackSupervisor.getDefaultDisplay();
247 final TestActivityStack homeStack = createStackForShouldBeVisibleTest(display,
248 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
249 final TestActivityStack translucentStack = createStackForShouldBeVisibleTest(display,
250 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
251 translucentStack.setIsTranslucent(true);
252
253 assertTrue(homeStack.shouldBeVisible(null /* starting */));
254 assertTrue(translucentStack.shouldBeVisible(null /* starting */));
255
256 final ActivityRecord topRunningHomeActivity = homeStack.topRunningActivityLocked();
257 topRunningHomeActivity.finishing = true;
258 final ActivityRecord topRunningTranslucentActivity =
259 translucentStack.topRunningActivityLocked();
260 topRunningTranslucentActivity.finishing = true;
261
262 // Home shouldn't be visible since its activity is marked as finishing and it isn't the top
263 // of the stack list.
264 assertFalse(homeStack.shouldBeVisible(null /* starting */));
265 // Home should be visible if we are starting an activity within it.
266 assertTrue(homeStack.shouldBeVisible(topRunningHomeActivity /* starting */));
267 // The translucent stack should be visible since it is the top of the stack list even though
268 // it has its activity marked as finishing.
269 assertTrue(translucentStack.shouldBeVisible(null /* starting */));
270 }
271
272 private <T extends ActivityStack> T createStackForShouldBeVisibleTest(
273 ActivityDisplay display, int windowingMode, int activityType, boolean onTop) {
274 final T stack = display.createStack(windowingMode, activityType, onTop);
Bryce Lee18d51592017-10-25 10:22:19 -0700275 final ActivityRecord r = new ActivityBuilder(mService).setUid(0).setStack(stack)
276 .setCreateTask(true).build();
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700277 return stack;
278 }
Bryce Lee840c5662017-04-13 10:02:51 -0700279}