blob: 5227f3c885bafca1345db86ede72812b1791b52f [file] [log] [blame]
Bryce Lee840c5662017-04-13 10:02:51 -07001/*
Wale Ogunwale59507092018-10-29 09:00:30 -07002 * Copyright (C) 2018 The Android Open Source Project
Bryce Lee840c5662017-04-13 10:02:51 -07003 *
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
Wale Ogunwale59507092018-10-29 09:00:30 -070014 * limitations under the License
Bryce Lee840c5662017-04-13 10:02:51 -070015 */
16
Wale Ogunwale59507092018-10-29 09:00:30 -070017package com.android.server.wm;
Bryce Lee840c5662017-04-13 10:02:51 -070018
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;
Wale Ogunwale0db64ac2020-04-11 10:00:42 -070022import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
Kazuki Takisef85197b2018-06-18 18:18:36 +090023import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070024import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -070025import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
26import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
27import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
Evan Rosky10475742018-09-05 19:02:48 -070028import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
Louis Chang7b03ad92019-08-21 12:32:33 +080029import static android.content.pm.ActivityInfo.FLAG_RESUME_WHILE_PAUSING;
Bryce Lee18d51592017-10-25 10:22:19 -070030
Louis Chang99d6f0e2020-02-21 12:14:32 +080031import static com.android.dx.mockito.inline.extended.ExtendedMockito.doCallRealMethod;
Louis Changcfe46212019-07-30 10:34:18 +080032import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
Tadashi G. Takaokaa7a66952018-11-16 15:04:21 +090033import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
34import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
Wale Ogunwale8a1860a2019-06-05 08:57:19 -070035import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
Tadashi G. Takaokaa7a66952018-11-16 15:04:21 +090036import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
Wale Ogunwale59507092018-10-29 09:00:30 -070037import static com.android.server.wm.ActivityStack.ActivityState.DESTROYING;
wilsonshih8824a8a2019-03-12 17:21:35 +080038import static com.android.server.wm.ActivityStack.ActivityState.FINISHING;
Wale Ogunwale59507092018-10-29 09:00:30 -070039import static com.android.server.wm.ActivityStack.ActivityState.PAUSING;
40import static com.android.server.wm.ActivityStack.ActivityState.RESUMED;
Riddle Hsuaaef7312019-01-24 19:00:58 +080041import static com.android.server.wm.ActivityStack.ActivityState.STOPPED;
Wale Ogunwale59507092018-10-29 09:00:30 -070042import static com.android.server.wm.ActivityStack.ActivityState.STOPPING;
Andrii Kulian0c869cc2019-02-06 19:50:32 -080043import static com.android.server.wm.ActivityStack.STACK_VISIBILITY_INVISIBLE;
44import static com.android.server.wm.ActivityStack.STACK_VISIBILITY_VISIBLE;
45import static com.android.server.wm.ActivityStack.STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT;
Garfield Tanf6cc5c92019-01-15 13:54:12 -080046import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_FREE_RESIZE;
47import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_WINDOWING_MODE_RESIZE;
Wale Ogunwale0db64ac2020-04-11 10:00:42 -070048import static com.android.server.wm.Task.FLAG_FORCE_HIDDEN_FOR_TASK_ORG;
Louis Changcdec0802019-11-11 11:45:07 +080049import static com.android.server.wm.Task.REPARENT_MOVE_STACK_TO_FRONT;
Andrii Kulian86d676c2020-03-27 19:34:54 -070050import static com.android.server.wm.TaskDisplayArea.getStackAbove;
Evan Rosky36b06cd2020-04-02 19:32:22 -070051import static com.android.server.wm.WindowContainer.POSITION_TOP;
Bryce Lee18d51592017-10-25 10:22:19 -070052
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +090053import static com.google.common.truth.Truth.assertThat;
54
Bryce Lee5daa3122017-04-19 10:40:42 -070055import static org.junit.Assert.assertEquals;
David Stevens18abd0e2017-08-17 14:55:47 -070056import static org.junit.Assert.assertFalse;
Bryce Lee840c5662017-04-13 10:02:51 -070057import static org.junit.Assert.assertNotNull;
58import static org.junit.Assert.assertNull;
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -070059import static org.junit.Assert.assertTrue;
Riddle Hsu138ef932018-10-26 17:12:06 +080060import static org.mockito.ArgumentMatchers.any;
Riddle Hsue10cea52018-10-16 23:33:23 +080061import static org.mockito.ArgumentMatchers.anyBoolean;
Riddle Hsu8e5f6d22020-02-07 00:15:57 +080062import static org.mockito.ArgumentMatchers.anyString;
Riddle Hsue10cea52018-10-16 23:33:23 +080063import static org.mockito.ArgumentMatchers.eq;
Bryce Lee840c5662017-04-13 10:02:51 -070064
Riddle Hsu8e5f6d22020-02-07 00:15:57 +080065import android.app.ActivityManager;
66import android.app.IApplicationThread;
Riddle Hsuaaef7312019-01-24 19:00:58 +080067import android.content.ComponentName;
Bryce Lee3345c4e2017-04-25 07:40:41 -070068import android.content.pm.ActivityInfo;
Bryce Lee9f6affd2017-09-01 09:18:35 -070069import android.os.UserHandle;
Bryce Lee840c5662017-04-13 10:02:51 -070070import android.platform.test.annotations.Presubmit;
Bryce Lee840c5662017-04-13 10:02:51 -070071
Brett Chabota26eda92018-07-23 13:08:30 -070072import androidx.test.filters.SmallTest;
Brett Chabota26eda92018-07-23 13:08:30 -070073
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070074import org.junit.Before;
Bryce Lee840c5662017-04-13 10:02:51 -070075import org.junit.Test;
Riddle Hsu73f53572019-09-23 23:13:01 +080076import org.junit.runner.RunWith;
Bryce Lee840c5662017-04-13 10:02:51 -070077
78/**
79 * Tests for the {@link ActivityStack} class.
80 *
81 * Build/Install/Run:
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +090082 * atest WmTests:ActivityStackTests
Bryce Lee840c5662017-04-13 10:02:51 -070083 */
84@SmallTest
85@Presubmit
Riddle Hsu73f53572019-09-23 23:13:01 +080086@RunWith(WindowTestRunner.class)
Bryce Lee840c5662017-04-13 10:02:51 -070087public class ActivityStackTests extends ActivityTestsBase {
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -070088 private TaskDisplayArea mDefaultTaskDisplayArea;
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070089 private ActivityStack mStack;
Louis Changcdec0802019-11-11 11:45:07 +080090 private Task mTask;
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070091
92 @Before
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070093 public void setUp() throws Exception {
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -070094 mDefaultTaskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea();
95 mStack = mDefaultTaskDisplayArea.createStack(WINDOWING_MODE_UNDEFINED,
96 ACTIVITY_TYPE_STANDARD, true /* onTop */);
Wale Ogunwale8a1860a2019-06-05 08:57:19 -070097 spyOn(mStack);
Bryce Lee18d51592017-10-25 10:22:19 -070098 mTask = new TaskBuilder(mSupervisor).setStack(mStack).build();
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070099 }
100
Bryce Lee840c5662017-04-13 10:02:51 -0700101 @Test
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900102 public void testResumedActivity() {
Bryce Leec4ab62a2018-03-05 14:19:26 -0800103 final ActivityRecord r = new ActivityBuilder(mService).setTask(mTask).build();
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900104 assertNull(mStack.getResumedActivity());
Bryce Leec4ab62a2018-03-05 14:19:26 -0800105 r.setState(RESUMED, "testResumedActivity");
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900106 assertEquals(r, mStack.getResumedActivity());
Bryce Leec4ab62a2018-03-05 14:19:26 -0800107 r.setState(PAUSING, "testResumedActivity");
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900108 assertNull(mStack.getResumedActivity());
Bryce Lee84730a02018-04-03 14:10:04 -0700109 }
Bryce Leec4ab62a2018-03-05 14:19:26 -0800110
Bryce Lee84730a02018-04-03 14:10:04 -0700111 @Test
112 public void testResumedActivityFromTaskReparenting() {
113 final ActivityRecord r = new ActivityBuilder(mService).setTask(mTask).build();
114 // Ensure moving task between two stacks updates resumed activity
115 r.setState(RESUMED, "testResumedActivityFromTaskReparenting");
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900116 assertEquals(r, mStack.getResumedActivity());
Bryce Lee84730a02018-04-03 14:10:04 -0700117
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -0700118 final ActivityStack destStack = mDefaultTaskDisplayArea.createStack(
Bryce Lee84730a02018-04-03 14:10:04 -0700119 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
120
Louis Changcdec0802019-11-11 11:45:07 +0800121 mTask.reparent(destStack, true /* toTop */, Task.REPARENT_KEEP_STACK_AT_FRONT,
Bryce Lee84730a02018-04-03 14:10:04 -0700122 false /* animate */, true /* deferResume*/,
123 "testResumedActivityFromTaskReparenting");
124
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900125 assertNull(mStack.getResumedActivity());
126 assertEquals(r, destStack.getResumedActivity());
Bryce Lee84730a02018-04-03 14:10:04 -0700127 }
128
129 @Test
130 public void testResumedActivityFromActivityReparenting() {
131 final ActivityRecord r = new ActivityBuilder(mService).setTask(mTask).build();
132 // Ensure moving task between two stacks updates resumed activity
133 r.setState(RESUMED, "testResumedActivityFromActivityReparenting");
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900134 assertEquals(r, mStack.getResumedActivity());
Bryce Lee84730a02018-04-03 14:10:04 -0700135
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -0700136 final ActivityStack destStack = mDefaultTaskDisplayArea.createStack(
Bryce Lee84730a02018-04-03 14:10:04 -0700137 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
Wale Ogunwale8a1860a2019-06-05 08:57:19 -0700138 mTask.reparent(destStack, true /*toTop*/, REPARENT_MOVE_STACK_TO_FRONT, false, false,
139 "testResumedActivityFromActivityReparenting");
Bryce Lee84730a02018-04-03 14:10:04 -0700140
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900141 assertNull(mStack.getResumedActivity());
142 assertEquals(r, destStack.getResumedActivity());
Bryce Lee5daa3122017-04-19 10:40:42 -0700143 }
Bryce Lee3345c4e2017-04-25 07:40:41 -0700144
145 @Test
Evan Rosky36b06cd2020-04-02 19:32:22 -0700146 public void testPrimarySplitScreenMoveToBack() {
147 TestSplitOrganizer organizer = new TestSplitOrganizer(mService);
148 // We're testing an edge case here where we have primary + fullscreen rather than secondary.
149 organizer.setMoveToSecondaryOnEnter(false);
150
151 // Create primary splitscreen stack.
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -0700152 final ActivityStack primarySplitScreen = mDefaultTaskDisplayArea.createStack(
Winson Chung3e2980e2018-03-29 17:28:57 -0700153 WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD, true /* onTop */);
Bryce Lee8cab4a02018-01-05 09:00:49 -0800154
155 // Assert windowing mode.
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900156 assertEquals(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, primarySplitScreen.getWindowingMode());
Bryce Lee8cab4a02018-01-05 09:00:49 -0800157
158 // Move primary to back.
159 primarySplitScreen.moveToBack("testPrimarySplitScreenToFullscreenWhenMovedToBack",
160 null /* task */);
161
162 // Assert that stack is at the bottom.
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -0700163 assertEquals(0, mDefaultTaskDisplayArea.getIndexOf(primarySplitScreen));
Bryce Lee8cab4a02018-01-05 09:00:49 -0800164
165 // Ensure no longer in splitscreen.
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900166 assertEquals(WINDOWING_MODE_FULLSCREEN, primarySplitScreen.getWindowingMode());
Evan Rosky10475742018-09-05 19:02:48 -0700167
168 // Ensure that the override mode is restored to undefined
Evan Roskydfe3da72018-10-26 17:21:06 -0700169 assertEquals(WINDOWING_MODE_UNDEFINED,
170 primarySplitScreen.getRequestedOverrideWindowingMode());
Evan Rosky10475742018-09-05 19:02:48 -0700171 }
172
173 @Test
Evan Rosky36b06cd2020-04-02 19:32:22 -0700174 public void testMoveToPrimarySplitScreenThenMoveToBack() {
175 TestSplitOrganizer organizer = new TestSplitOrganizer(mService);
Evan Rosky10475742018-09-05 19:02:48 -0700176 // This time, start with a fullscreen activitystack
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -0700177 final ActivityStack primarySplitScreen = mDefaultTaskDisplayArea.createStack(
Evan Rosky36b06cd2020-04-02 19:32:22 -0700178 WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD, true /* onTop */);
Evan Rosky10475742018-09-05 19:02:48 -0700179
Evan Rosky36b06cd2020-04-02 19:32:22 -0700180 primarySplitScreen.reparent((ActivityStack) organizer.mPrimary, POSITION_TOP,
181 false /*moveParents*/, "test");
Evan Rosky10475742018-09-05 19:02:48 -0700182
183 // Assert windowing mode.
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900184 assertEquals(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, primarySplitScreen.getWindowingMode());
Evan Rosky10475742018-09-05 19:02:48 -0700185
186 // Move primary to back.
187 primarySplitScreen.moveToBack("testPrimarySplitScreenToFullscreenWhenMovedToBack",
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900188 null /* task */);
Evan Rosky10475742018-09-05 19:02:48 -0700189
190 // Assert that stack is at the bottom.
Evan Rosky36b06cd2020-04-02 19:32:22 -0700191 assertEquals(primarySplitScreen, organizer.mSecondary.getChildAt(0));
Evan Rosky10475742018-09-05 19:02:48 -0700192
193 // Ensure that the override mode is restored to what it was (fullscreen)
Evan Rosky36b06cd2020-04-02 19:32:22 -0700194 assertEquals(WINDOWING_MODE_UNDEFINED,
Evan Roskydfe3da72018-10-26 17:21:06 -0700195 primarySplitScreen.getRequestedOverrideWindowingMode());
Evan Rosky10475742018-09-05 19:02:48 -0700196 }
197
198 @Test
Evan Rosky36b06cd2020-04-02 19:32:22 -0700199 public void testSplitScreenMoveToBack() {
200 TestSplitOrganizer organizer = new TestSplitOrganizer(mService);
201 // Set up split-screen with primary on top and secondary containing the home task below
202 // another stack.
203 final ActivityStack primaryTask = mDefaultTaskDisplayArea.createStack(
204 WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD, true /* onTop */);
205 final ActivityStack homeRoot = mDefaultTaskDisplayArea.getStack(
206 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME);
207 final ActivityStack secondaryTask = mDefaultTaskDisplayArea.createStack(
208 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD, true /* onTop */);
209 mDefaultTaskDisplayArea.positionStackAtTop((ActivityStack) organizer.mPrimary,
210 false /* includingParents */);
211
212 // Move primary to back.
213 primaryTask.moveToBack("test", null /* task */);
214
215 // Assert that the primaryTask is now below home in its parent but primary is left alone.
216 assertEquals(0, organizer.mPrimary.getChildCount());
217 assertEquals(primaryTask, organizer.mSecondary.getChildAt(0));
218 assertEquals(1, organizer.mPrimary.compareTo(organizer.mSecondary));
219 assertEquals(1, homeRoot.compareTo(primaryTask));
220 assertEquals(homeRoot.getParent(), primaryTask.getParent());
221
222 // Make sure windowing modes are correct
223 assertEquals(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, organizer.mPrimary.getWindowingMode());
224 assertEquals(WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, primaryTask.getWindowingMode());
225
226 // Move secondary to back via parent (should be equivalent)
227 ((ActivityStack) organizer.mSecondary).moveToBack("test", secondaryTask);
228
229 // Assert that it is now in back but still in secondary split
230 assertEquals(1, homeRoot.compareTo(primaryTask));
231 assertEquals(secondaryTask, organizer.mSecondary.getChildAt(0));
232 assertEquals(1, primaryTask.compareTo(secondaryTask));
233 assertEquals(homeRoot.getParent(), secondaryTask.getParent());
234 }
235
236 @Test
Riddle Hsu9adc55f2020-04-28 17:07:33 +0800237 public void testRemoveOrganizedTask_UpdateStackReference() {
238 final ActivityStack rootHomeTask = mDefaultTaskDisplayArea.getRootHomeTask();
239 final ActivityRecord homeActivity = new ActivityBuilder(mService)
240 .setStack(rootHomeTask)
241 .setCreateTask(true)
242 .build();
243 final ActivityStack secondaryStack = (ActivityStack) WindowContainer.fromBinder(
244 mService.mTaskOrganizerController.createRootTask(rootHomeTask.getDisplayId(),
245 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY).token.asBinder());
246
247 rootHomeTask.reparent(secondaryStack, POSITION_TOP);
248 assertEquals(secondaryStack, rootHomeTask.getParent());
249
250 // This should call to {@link TaskDisplayArea#removeStackReferenceIfNeeded}.
251 homeActivity.removeImmediately();
252 assertNull(mDefaultTaskDisplayArea.getRootHomeTask());
253 }
254
255 @Test
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900256 public void testStackInheritsDisplayWindowingMode() {
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -0700257 final ActivityStack primarySplitScreen = mDefaultTaskDisplayArea.createStack(
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900258 WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD, true /* onTop */);
Evan Rosky10475742018-09-05 19:02:48 -0700259
260 assertEquals(WINDOWING_MODE_FULLSCREEN, primarySplitScreen.getWindowingMode());
Evan Roskydfe3da72018-10-26 17:21:06 -0700261 assertEquals(WINDOWING_MODE_UNDEFINED,
262 primarySplitScreen.getRequestedOverrideWindowingMode());
Evan Rosky10475742018-09-05 19:02:48 -0700263
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -0700264 mDefaultTaskDisplayArea.setWindowingMode(WINDOWING_MODE_FREEFORM);
Evan Rosky10475742018-09-05 19:02:48 -0700265 assertEquals(WINDOWING_MODE_FREEFORM, primarySplitScreen.getWindowingMode());
Evan Roskydfe3da72018-10-26 17:21:06 -0700266 assertEquals(WINDOWING_MODE_UNDEFINED,
267 primarySplitScreen.getRequestedOverrideWindowingMode());
Evan Rosky10475742018-09-05 19:02:48 -0700268 }
269
270 @Test
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900271 public void testStackOverridesDisplayWindowingMode() {
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -0700272 final ActivityStack primarySplitScreen = mDefaultTaskDisplayArea.createStack(
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900273 WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD, true /* onTop */);
Evan Rosky10475742018-09-05 19:02:48 -0700274
275 assertEquals(WINDOWING_MODE_FULLSCREEN, primarySplitScreen.getWindowingMode());
Evan Roskydfe3da72018-10-26 17:21:06 -0700276 assertEquals(WINDOWING_MODE_UNDEFINED,
277 primarySplitScreen.getRequestedOverrideWindowingMode());
Evan Rosky10475742018-09-05 19:02:48 -0700278
279 primarySplitScreen.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
280 // setting windowing mode should still work even though resolved mode is already fullscreen
Evan Roskydfe3da72018-10-26 17:21:06 -0700281 assertEquals(WINDOWING_MODE_FULLSCREEN,
282 primarySplitScreen.getRequestedOverrideWindowingMode());
Evan Rosky10475742018-09-05 19:02:48 -0700283
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -0700284 mDefaultTaskDisplayArea.setWindowingMode(WINDOWING_MODE_FREEFORM);
Evan Rosky10475742018-09-05 19:02:48 -0700285 assertEquals(WINDOWING_MODE_FULLSCREEN, primarySplitScreen.getWindowingMode());
Bryce Lee8cab4a02018-01-05 09:00:49 -0800286 }
287
288 @Test
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900289 public void testStopActivityWhenActivityDestroyed() {
Bryce Lee18d51592017-10-25 10:22:19 -0700290 final ActivityRecord r = new ActivityBuilder(mService).setTask(mTask).build();
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700291 r.info.flags |= ActivityInfo.FLAG_NO_HISTORY;
Andrii Kulian6a6c4f12018-07-16 21:23:33 -0700292 mStack.moveToFront("testStopActivityWithDestroy");
Andrii Kulian79d67982019-08-19 11:56:16 -0700293 r.stopIfPossible();
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700294 // Mostly testing to make sure there is a crash in the call part, so if we get here we are
295 // good-to-go!
Bryce Lee3345c4e2017-04-25 07:40:41 -0700296 }
Bryce Lee9f6affd2017-09-01 09:18:35 -0700297
298 @Test
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900299 public void testFindTaskWithOverlay() {
Bryce Lee18d51592017-10-25 10:22:19 -0700300 final ActivityRecord r = new ActivityBuilder(mService)
301 .setCreateTask(true)
302 .setStack(mStack)
303 .setUid(0)
304 .build();
Louis Changcdec0802019-11-11 11:45:07 +0800305 final Task task = r.getTask();
Bryce Lee9f6affd2017-09-01 09:18:35 -0700306 // Overlay must be for a different user to prevent recognizing a matching top activity
Bryce Lee18d51592017-10-25 10:22:19 -0700307 final ActivityRecord taskOverlay = new ActivityBuilder(mService).setTask(task)
308 .setUid(UserHandle.PER_USER_RANGE * 2).build();
Wale Ogunwale0b3d2922019-12-30 08:55:07 -0800309 taskOverlay.setTaskOverlay(true);
Bryce Lee9f6affd2017-09-01 09:18:35 -0700310
Louis Chang149d5c82019-12-30 09:47:39 +0800311 final RootWindowContainer.FindTaskResult result =
312 new RootWindowContainer.FindTaskResult();
Wale Ogunwalea38654f2019-11-17 20:37:15 -0800313 result.process(r, mStack);
Bryce Lee9f6affd2017-09-01 09:18:35 -0700314
Wale Ogunwale21e06482019-11-18 05:14:15 -0800315 assertEquals(r, task.getTopNonFinishingActivity(false /* includeOverlays */));
316 assertEquals(taskOverlay, task.getTopNonFinishingActivity(true /* includeOverlays */));
Louis Changc85b1a32018-08-14 16:40:53 +0800317 assertNotNull(result.mRecord);
Bryce Lee9f6affd2017-09-01 09:18:35 -0700318 }
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700319
320 @Test
Louis Changb05c8d82019-06-25 11:56:55 +0800321 public void testFindTaskAlias() {
322 final String targetActivity = "target.activity";
323 final String aliasActivity = "alias.activity";
324 final ComponentName target = new ComponentName(DEFAULT_COMPONENT_PACKAGE_NAME,
325 targetActivity);
326 final ComponentName alias = new ComponentName(DEFAULT_COMPONENT_PACKAGE_NAME,
327 aliasActivity);
Louis Changcdec0802019-11-11 11:45:07 +0800328 final Task task = new TaskBuilder(mService.mStackSupervisor).setStack(mStack).build();
Louis Changb05c8d82019-06-25 11:56:55 +0800329 task.origActivity = alias;
330 task.realActivity = target;
331 new ActivityBuilder(mService).setComponent(target).setTask(task).setTargetActivity(
332 targetActivity).build();
333
334 // Using target activity to find task.
335 final ActivityRecord r1 = new ActivityBuilder(mService).setComponent(
336 target).setTargetActivity(targetActivity).build();
Louis Chang149d5c82019-12-30 09:47:39 +0800337 RootWindowContainer.FindTaskResult result = new RootWindowContainer.FindTaskResult();
Wale Ogunwalea38654f2019-11-17 20:37:15 -0800338 result.process(r1, mStack);
Louis Changb05c8d82019-06-25 11:56:55 +0800339 assertThat(result.mRecord).isNotNull();
340
341 // Using alias activity to find task.
342 final ActivityRecord r2 = new ActivityBuilder(mService).setComponent(
343 alias).setTargetActivity(targetActivity).build();
Louis Chang149d5c82019-12-30 09:47:39 +0800344 result = new RootWindowContainer.FindTaskResult();
Wale Ogunwalea38654f2019-11-17 20:37:15 -0800345 result.process(r2, mStack);
Louis Changb05c8d82019-06-25 11:56:55 +0800346 assertThat(result.mRecord).isNotNull();
347 }
348
349 @Test
Riddle Hsu138ef932018-10-26 17:12:06 +0800350 public void testMoveStackToBackIncludingParent() {
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -0700351 final TaskDisplayArea taskDisplayArea = addNewDisplayContentAt(DisplayContent.POSITION_TOP)
352 .getDefaultTaskDisplayArea();
353 final ActivityStack stack1 = createStackForShouldBeVisibleTest(taskDisplayArea,
Riddle Hsu138ef932018-10-26 17:12:06 +0800354 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -0700355 final ActivityStack stack2 = createStackForShouldBeVisibleTest(taskDisplayArea,
Riddle Hsu138ef932018-10-26 17:12:06 +0800356 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
357
358 // Do not move display to back because there is still another stack.
Wale Ogunwale85fb19a2019-12-05 10:41:05 +0900359 stack2.moveToBack("testMoveStackToBackIncludingParent", stack2.getTopMostTask());
Wale Ogunwalebebd8cd2019-10-28 15:53:31 -0700360 verify(stack2).positionChildAtBottom(any(), eq(false) /* includingParents */);
Riddle Hsu138ef932018-10-26 17:12:06 +0800361
362 // Also move display to back because there is only one stack left.
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -0700363 taskDisplayArea.removeStack(stack1);
Wale Ogunwale85fb19a2019-12-05 10:41:05 +0900364 stack2.moveToBack("testMoveStackToBackIncludingParent", stack2.getTopMostTask());
Wale Ogunwalebebd8cd2019-10-28 15:53:31 -0700365 verify(stack2).positionChildAtBottom(any(), eq(true) /* includingParents */);
Riddle Hsu138ef932018-10-26 17:12:06 +0800366 }
367
368 @Test
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900369 public void testShouldBeVisible_Fullscreen() {
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -0700370 final ActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea,
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700371 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -0700372 final ActivityStack pinnedStack = createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea,
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700373 WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, true /* onTop */);
Wale Ogunwale8a1860a2019-06-05 08:57:19 -0700374 // Add an activity to the pinned stack so it isn't considered empty for visibility check.
375 final ActivityRecord pinnedActivity = new ActivityBuilder(mService)
376 .setCreateTask(true)
377 .setStack(pinnedStack)
378 .build();
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700379
380 assertTrue(homeStack.shouldBeVisible(null /* starting */));
381 assertTrue(pinnedStack.shouldBeVisible(null /* starting */));
382
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -0700383 final ActivityStack fullscreenStack = createStackForShouldBeVisibleTest(
384 mDefaultTaskDisplayArea, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
385 true /* onTop */);
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700386 // Home stack shouldn't be visible behind an opaque fullscreen stack, but pinned stack
387 // should be visible since it is always on-top.
Wale Ogunwale8f93b642019-12-26 12:10:52 -0800388 doReturn(false).when(fullscreenStack).isTranslucent(any());
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700389 assertFalse(homeStack.shouldBeVisible(null /* starting */));
390 assertTrue(pinnedStack.shouldBeVisible(null /* starting */));
391 assertTrue(fullscreenStack.shouldBeVisible(null /* starting */));
392
393 // Home stack should be visible behind a translucent fullscreen stack.
Wale Ogunwale8f93b642019-12-26 12:10:52 -0800394 doReturn(true).when(fullscreenStack).isTranslucent(any());
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700395 assertTrue(homeStack.shouldBeVisible(null /* starting */));
396 assertTrue(pinnedStack.shouldBeVisible(null /* starting */));
397 }
398
399 @Test
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900400 public void testShouldBeVisible_SplitScreen() {
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -0700401 final ActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea,
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700402 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
Wale Ogunwale30e441d2017-11-09 08:28:45 -0800403 // Home stack should always be fullscreen for this test.
Wale Ogunwale8a1860a2019-06-05 08:57:19 -0700404 doReturn(false).when(homeStack).supportsSplitScreenWindowingMode();
405 final ActivityStack splitScreenPrimary =
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -0700406 createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea,
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700407 WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD, true /* onTop */);
Wale Ogunwale8a1860a2019-06-05 08:57:19 -0700408 final ActivityStack splitScreenSecondary =
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -0700409 createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea,
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700410 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD, true /* onTop */);
411
412 // Home stack shouldn't be visible if both halves of split-screen are opaque.
Wale Ogunwale8f93b642019-12-26 12:10:52 -0800413 doReturn(false).when(splitScreenPrimary).isTranslucent(any());
414 doReturn(false).when(splitScreenSecondary).isTranslucent(any());
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700415 assertFalse(homeStack.shouldBeVisible(null /* starting */));
416 assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */));
417 assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
Andrii Kulian0c869cc2019-02-06 19:50:32 -0800418 assertEquals(STACK_VISIBILITY_INVISIBLE, homeStack.getVisibility(null /* starting */));
419 assertEquals(STACK_VISIBILITY_VISIBLE,
420 splitScreenPrimary.getVisibility(null /* starting */));
421 assertEquals(STACK_VISIBILITY_VISIBLE,
422 splitScreenSecondary.getVisibility(null /* starting */));
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700423
424 // Home stack should be visible if one of the halves of split-screen is translucent.
Wale Ogunwale8f93b642019-12-26 12:10:52 -0800425 doReturn(true).when(splitScreenPrimary).isTranslucent(any());
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700426 assertTrue(homeStack.shouldBeVisible(null /* starting */));
427 assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */));
428 assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
Andrii Kulian0c869cc2019-02-06 19:50:32 -0800429 assertEquals(STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT,
430 homeStack.getVisibility(null /* starting */));
431 assertEquals(STACK_VISIBILITY_VISIBLE,
432 splitScreenPrimary.getVisibility(null /* starting */));
433 assertEquals(STACK_VISIBILITY_VISIBLE,
434 splitScreenSecondary.getVisibility(null /* starting */));
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700435
Wale Ogunwale8a1860a2019-06-05 08:57:19 -0700436 final ActivityStack splitScreenSecondary2 =
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -0700437 createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea,
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700438 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD, true /* onTop */);
439 // First split-screen secondary shouldn't be visible behind another opaque split-split
440 // secondary.
Wale Ogunwale8f93b642019-12-26 12:10:52 -0800441 doReturn(false).when(splitScreenSecondary2).isTranslucent(any());
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700442 assertFalse(splitScreenSecondary.shouldBeVisible(null /* starting */));
443 assertTrue(splitScreenSecondary2.shouldBeVisible(null /* starting */));
Andrii Kulian0c869cc2019-02-06 19:50:32 -0800444 assertEquals(STACK_VISIBILITY_INVISIBLE,
445 splitScreenSecondary.getVisibility(null /* starting */));
446 assertEquals(STACK_VISIBILITY_VISIBLE,
447 splitScreenSecondary2.getVisibility(null /* starting */));
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700448
Wale Ogunwale8e923af2018-03-23 08:48:11 -0700449 // First split-screen secondary should be visible behind another translucent split-screen
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700450 // secondary.
Wale Ogunwale8f93b642019-12-26 12:10:52 -0800451 doReturn(true).when(splitScreenSecondary2).isTranslucent(any());
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700452 assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
453 assertTrue(splitScreenSecondary2.shouldBeVisible(null /* starting */));
Andrii Kulian0c869cc2019-02-06 19:50:32 -0800454 assertEquals(STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT,
455 splitScreenSecondary.getVisibility(null /* starting */));
456 assertEquals(STACK_VISIBILITY_VISIBLE,
457 splitScreenSecondary2.getVisibility(null /* starting */));
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700458
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -0700459 final ActivityStack assistantStack = createStackForShouldBeVisibleTest(
460 mDefaultTaskDisplayArea, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_ASSISTANT,
461 true /* onTop */);
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700462
463 // Split-screen stacks shouldn't be visible behind an opaque fullscreen stack.
Wale Ogunwale8f93b642019-12-26 12:10:52 -0800464 doReturn(false).when(assistantStack).isTranslucent(any());
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700465 assertTrue(assistantStack.shouldBeVisible(null /* starting */));
466 assertFalse(splitScreenPrimary.shouldBeVisible(null /* starting */));
467 assertFalse(splitScreenSecondary.shouldBeVisible(null /* starting */));
468 assertFalse(splitScreenSecondary2.shouldBeVisible(null /* starting */));
Andrii Kulian0c869cc2019-02-06 19:50:32 -0800469 assertEquals(STACK_VISIBILITY_VISIBLE,
470 assistantStack.getVisibility(null /* starting */));
471 assertEquals(STACK_VISIBILITY_INVISIBLE,
472 splitScreenPrimary.getVisibility(null /* starting */));
473 assertEquals(STACK_VISIBILITY_INVISIBLE,
474 splitScreenSecondary.getVisibility(null /* starting */));
475 assertEquals(STACK_VISIBILITY_INVISIBLE,
476 splitScreenSecondary2.getVisibility(null /* starting */));
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700477
478 // Split-screen stacks should be visible behind a translucent fullscreen stack.
Wale Ogunwale8f93b642019-12-26 12:10:52 -0800479 doReturn(true).when(assistantStack).isTranslucent(any());
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700480 assertTrue(assistantStack.shouldBeVisible(null /* starting */));
481 assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */));
482 assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
483 assertTrue(splitScreenSecondary2.shouldBeVisible(null /* starting */));
Andrii Kulian0c869cc2019-02-06 19:50:32 -0800484 assertEquals(STACK_VISIBILITY_VISIBLE,
485 assistantStack.getVisibility(null /* starting */));
486 assertEquals(STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT,
487 splitScreenPrimary.getVisibility(null /* starting */));
488 assertEquals(STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT,
489 splitScreenSecondary.getVisibility(null /* starting */));
490 assertEquals(STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT,
491 splitScreenSecondary2.getVisibility(null /* starting */));
Wale Ogunwale8e923af2018-03-23 08:48:11 -0700492
Galia Peycheva7ecd6ef2020-03-26 19:59:40 +0100493 // Assistant stack shouldn't be visible behind translucent split-screen stack,
494 // unless it is configured to show on top of everything.
Wale Ogunwale8f93b642019-12-26 12:10:52 -0800495 doReturn(false).when(assistantStack).isTranslucent(any());
496 doReturn(true).when(splitScreenPrimary).isTranslucent(any());
497 doReturn(true).when(splitScreenSecondary2).isTranslucent(any());
Wale Ogunwale8e923af2018-03-23 08:48:11 -0700498 splitScreenSecondary2.moveToFront("testShouldBeVisible_SplitScreen");
499 splitScreenPrimary.moveToFront("testShouldBeVisible_SplitScreen");
Galia Peycheva7ecd6ef2020-03-26 19:59:40 +0100500
501 if (isAssistantOnTop()) {
502 assertTrue(assistantStack.shouldBeVisible(null /* starting */));
503 assertFalse(splitScreenPrimary.shouldBeVisible(null /* starting */));
504 assertFalse(splitScreenSecondary2.shouldBeVisible(null /* starting */));
505 assertEquals(STACK_VISIBILITY_VISIBLE,
506 assistantStack.getVisibility(null /* starting */));
507 assertEquals(STACK_VISIBILITY_INVISIBLE,
508 splitScreenPrimary.getVisibility(null /* starting */));
509 assertEquals(STACK_VISIBILITY_INVISIBLE,
510 splitScreenSecondary.getVisibility(null /* starting */));
511 assertEquals(STACK_VISIBILITY_INVISIBLE,
512 splitScreenSecondary2.getVisibility(null /* starting */));
513 } else {
514 assertFalse(assistantStack.shouldBeVisible(null /* starting */));
515 assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */));
516 assertTrue(splitScreenSecondary2.shouldBeVisible(null /* starting */));
517 assertEquals(STACK_VISIBILITY_INVISIBLE,
518 assistantStack.getVisibility(null /* starting */));
519 assertEquals(STACK_VISIBILITY_VISIBLE,
520 splitScreenPrimary.getVisibility(null /* starting */));
521 assertEquals(STACK_VISIBILITY_INVISIBLE,
522 splitScreenSecondary.getVisibility(null /* starting */));
523 assertEquals(STACK_VISIBILITY_VISIBLE,
524 splitScreenSecondary2.getVisibility(null /* starting */));
525 }
Andrii Kulian0c869cc2019-02-06 19:50:32 -0800526 }
527
528 @Test
Wale Ogunwale0db64ac2020-04-11 10:00:42 -0700529 public void testGetVisibility_MultiLevel() {
530 final ActivityStack homeStack = createStackForShouldBeVisibleTest(
531 mDefaultTaskDisplayArea, WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_HOME,
532 true /* onTop */);
533 final ActivityStack splitPrimary = createStackForShouldBeVisibleTest(
534 mDefaultTaskDisplayArea, WINDOWING_MODE_SPLIT_SCREEN_PRIMARY,
535 ACTIVITY_TYPE_UNDEFINED, true /* onTop */);
536 final ActivityStack splitSecondary = createStackForShouldBeVisibleTest(
537 mDefaultTaskDisplayArea, WINDOWING_MODE_SPLIT_SCREEN_SECONDARY,
538 ACTIVITY_TYPE_UNDEFINED, true /* onTop */);
539
540 doReturn(false).when(homeStack).isTranslucent(any());
541 doReturn(false).when(splitPrimary).isTranslucent(any());
542 doReturn(false).when(splitSecondary).isTranslucent(any());
543
544
545 // Re-parent home to split secondary.
546 homeStack.reparent(splitSecondary, POSITION_TOP);
547 // Current tasks should be visible.
548 assertEquals(STACK_VISIBILITY_VISIBLE, splitPrimary.getVisibility(null /* starting */));
549 assertEquals(STACK_VISIBILITY_VISIBLE, splitSecondary.getVisibility(null /* starting */));
550 // Home task should still be visible even though it is a child of another visible task.
551 assertEquals(STACK_VISIBILITY_VISIBLE, homeStack.getVisibility(null /* starting */));
552
553
554 // Add fullscreen translucent task that partially occludes split tasks
555 final ActivityStack translucentStack = createStandardStackForVisibilityTest(
556 WINDOWING_MODE_FULLSCREEN, true /* translucent */);
557 // Fullscreen translucent task should be visible
558 assertEquals(STACK_VISIBILITY_VISIBLE, translucentStack.getVisibility(null /* starting */));
559 // Split tasks should be visible behind translucent
560 assertEquals(STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT,
561 splitPrimary.getVisibility(null /* starting */));
562 assertEquals(STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT,
563 splitSecondary.getVisibility(null /* starting */));
564 // Home task should be visible behind translucent since its parent is visible behind
565 // translucent.
566 assertEquals(STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT,
567 homeStack.getVisibility(null /* starting */));
568
569
570 // Hide split-secondary
571 splitSecondary.setForceHidden(FLAG_FORCE_HIDDEN_FOR_TASK_ORG, true /* set */);
572 // Home split secondary and home task should be invisible.
573 assertEquals(STACK_VISIBILITY_INVISIBLE, splitSecondary.getVisibility(null /* starting */));
574 assertEquals(STACK_VISIBILITY_INVISIBLE, homeStack.getVisibility(null /* starting */));
575 }
576
577 @Test
Andrii Kulian0c869cc2019-02-06 19:50:32 -0800578 public void testGetVisibility_FullscreenBehindTranslucent() {
Wale Ogunwale8a1860a2019-06-05 08:57:19 -0700579 final ActivityStack bottomStack =
Andrii Kulian0c869cc2019-02-06 19:50:32 -0800580 createStandardStackForVisibilityTest(WINDOWING_MODE_FULLSCREEN,
581 false /* translucent */);
Wale Ogunwale8a1860a2019-06-05 08:57:19 -0700582 final ActivityStack translucentStack =
Andrii Kulian0c869cc2019-02-06 19:50:32 -0800583 createStandardStackForVisibilityTest(WINDOWING_MODE_FULLSCREEN,
584 true /* translucent */);
585
586 assertEquals(STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT,
587 bottomStack.getVisibility(null /* starting */));
588 assertEquals(STACK_VISIBILITY_VISIBLE,
589 translucentStack.getVisibility(null /* starting */));
590 }
591
592 @Test
593 public void testGetVisibility_FullscreenBehindTranslucentAndOpaque() {
Wale Ogunwale8a1860a2019-06-05 08:57:19 -0700594 final ActivityStack bottomStack =
Andrii Kulian0c869cc2019-02-06 19:50:32 -0800595 createStandardStackForVisibilityTest(WINDOWING_MODE_FULLSCREEN,
596 false /* translucent */);
Wale Ogunwale8a1860a2019-06-05 08:57:19 -0700597 final ActivityStack translucentStack =
Andrii Kulian0c869cc2019-02-06 19:50:32 -0800598 createStandardStackForVisibilityTest(WINDOWING_MODE_FULLSCREEN,
599 true /* translucent */);
Wale Ogunwale8a1860a2019-06-05 08:57:19 -0700600 final ActivityStack opaqueStack =
Andrii Kulian0c869cc2019-02-06 19:50:32 -0800601 createStandardStackForVisibilityTest(WINDOWING_MODE_FULLSCREEN,
602 false /* translucent */);
603
604 assertEquals(STACK_VISIBILITY_INVISIBLE, bottomStack.getVisibility(null /* starting */));
605 assertEquals(STACK_VISIBILITY_INVISIBLE,
606 translucentStack.getVisibility(null /* starting */));
607 assertEquals(STACK_VISIBILITY_VISIBLE, opaqueStack.getVisibility(null /* starting */));
608 }
609
610 @Test
611 public void testGetVisibility_FullscreenBehindOpaqueAndTranslucent() {
Wale Ogunwale8a1860a2019-06-05 08:57:19 -0700612 final ActivityStack bottomStack =
Andrii Kulian0c869cc2019-02-06 19:50:32 -0800613 createStandardStackForVisibilityTest(WINDOWING_MODE_FULLSCREEN,
614 false /* translucent */);
Wale Ogunwale8a1860a2019-06-05 08:57:19 -0700615 final ActivityStack opaqueStack =
Andrii Kulian0c869cc2019-02-06 19:50:32 -0800616 createStandardStackForVisibilityTest(WINDOWING_MODE_FULLSCREEN,
617 false /* translucent */);
Wale Ogunwale8a1860a2019-06-05 08:57:19 -0700618 final ActivityStack translucentStack =
Andrii Kulian0c869cc2019-02-06 19:50:32 -0800619 createStandardStackForVisibilityTest(WINDOWING_MODE_FULLSCREEN,
620 true /* translucent */);
621
622 assertEquals(STACK_VISIBILITY_INVISIBLE, bottomStack.getVisibility(null /* starting */));
623 assertEquals(STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT,
624 opaqueStack.getVisibility(null /* starting */));
625 assertEquals(STACK_VISIBILITY_VISIBLE,
626 translucentStack.getVisibility(null /* starting */));
627 }
628
629 @Test
630 public void testGetVisibility_FullscreenTranslucentBehindTranslucent() {
Wale Ogunwale8a1860a2019-06-05 08:57:19 -0700631 final ActivityStack bottomTranslucentStack =
Andrii Kulian0c869cc2019-02-06 19:50:32 -0800632 createStandardStackForVisibilityTest(WINDOWING_MODE_FULLSCREEN,
633 true /* translucent */);
Wale Ogunwale8a1860a2019-06-05 08:57:19 -0700634 final ActivityStack translucentStack =
Andrii Kulian0c869cc2019-02-06 19:50:32 -0800635 createStandardStackForVisibilityTest(WINDOWING_MODE_FULLSCREEN,
636 true /* translucent */);
637
638 assertEquals(STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT,
639 bottomTranslucentStack.getVisibility(null /* starting */));
640 assertEquals(STACK_VISIBILITY_VISIBLE,
641 translucentStack.getVisibility(null /* starting */));
642 }
643
644 @Test
645 public void testGetVisibility_FullscreenTranslucentBehindOpaque() {
Wale Ogunwale8a1860a2019-06-05 08:57:19 -0700646 final ActivityStack bottomTranslucentStack =
Andrii Kulian0c869cc2019-02-06 19:50:32 -0800647 createStandardStackForVisibilityTest(WINDOWING_MODE_FULLSCREEN,
648 true /* translucent */);
Wale Ogunwale8a1860a2019-06-05 08:57:19 -0700649 final ActivityStack opaqueStack =
Andrii Kulian0c869cc2019-02-06 19:50:32 -0800650 createStandardStackForVisibilityTest(WINDOWING_MODE_FULLSCREEN,
651 false /* translucent */);
652
653 assertEquals(STACK_VISIBILITY_INVISIBLE,
654 bottomTranslucentStack.getVisibility(null /* starting */));
655 assertEquals(STACK_VISIBILITY_VISIBLE, opaqueStack.getVisibility(null /* starting */));
656 }
657
658 @Test
659 public void testGetVisibility_FullscreenBehindTranslucentAndPip() {
Wale Ogunwale8a1860a2019-06-05 08:57:19 -0700660 final ActivityStack bottomStack =
Andrii Kulian0c869cc2019-02-06 19:50:32 -0800661 createStandardStackForVisibilityTest(WINDOWING_MODE_FULLSCREEN,
662 false /* translucent */);
Wale Ogunwale8a1860a2019-06-05 08:57:19 -0700663 final ActivityStack translucentStack =
Andrii Kulian0c869cc2019-02-06 19:50:32 -0800664 createStandardStackForVisibilityTest(WINDOWING_MODE_FULLSCREEN,
665 true /* translucent */);
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -0700666 final ActivityStack pinnedStack = createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea,
Andrii Kulian0c869cc2019-02-06 19:50:32 -0800667 WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, true /* onTop */);
668
669 assertEquals(STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT,
670 bottomStack.getVisibility(null /* starting */));
671 assertEquals(STACK_VISIBILITY_VISIBLE,
672 translucentStack.getVisibility(null /* starting */));
Wale Ogunwale8a1860a2019-06-05 08:57:19 -0700673 // Add an activity to the pinned stack so it isn't considered empty for visibility check.
674 final ActivityRecord pinnedActivity = new ActivityBuilder(mService)
675 .setCreateTask(true)
676 .setStack(pinnedStack)
677 .build();
Andrii Kulian0c869cc2019-02-06 19:50:32 -0800678 assertEquals(STACK_VISIBILITY_VISIBLE, pinnedStack.getVisibility(null /* starting */));
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700679 }
680
681 @Test
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900682 public void testShouldBeVisible_Finishing() {
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -0700683 final ActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea,
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700684 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
Wale Ogunwale85fb19a2019-12-05 10:41:05 +0900685 ActivityRecord topRunningHomeActivity = homeStack.topRunningActivity();
Wale Ogunwale8a1860a2019-06-05 08:57:19 -0700686 if (topRunningHomeActivity == null) {
687 topRunningHomeActivity = new ActivityBuilder(mService)
688 .setStack(homeStack)
689 .setCreateTask(true)
690 .build();
691 }
692
693 final ActivityStack translucentStack = createStackForShouldBeVisibleTest(
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -0700694 mDefaultTaskDisplayArea, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
Winson Chung3e2980e2018-03-29 17:28:57 -0700695 true /* onTop */);
Wale Ogunwale8f93b642019-12-26 12:10:52 -0800696 doReturn(true).when(translucentStack).isTranslucent(any());
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700697
698 assertTrue(homeStack.shouldBeVisible(null /* starting */));
699 assertTrue(translucentStack.shouldBeVisible(null /* starting */));
700
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700701 topRunningHomeActivity.finishing = true;
702 final ActivityRecord topRunningTranslucentActivity =
Wale Ogunwale85fb19a2019-12-05 10:41:05 +0900703 translucentStack.topRunningActivity();
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700704 topRunningTranslucentActivity.finishing = true;
705
Louis Changf2835df2018-10-17 15:14:45 +0800706 // Home stack should be visible even there are no running activities.
707 assertTrue(homeStack.shouldBeVisible(null /* starting */));
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700708 // Home should be visible if we are starting an activity within it.
709 assertTrue(homeStack.shouldBeVisible(topRunningHomeActivity /* starting */));
Louis Changf2835df2018-10-17 15:14:45 +0800710 // The translucent stack shouldn't be visible since its activity marked as finishing.
711 assertFalse(translucentStack.shouldBeVisible(null /* starting */));
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700712 }
713
Winson Chungd922b6b2018-02-16 16:41:50 -0800714 @Test
Jeff Chang24b0bf62019-12-19 19:15:07 +0800715 public void testShouldBeVisible_FullscreenBehindTranslucentInHomeStack() {
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -0700716 final ActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea,
Jeff Chang24b0bf62019-12-19 19:15:07 +0800717 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
718
719 final ActivityRecord firstActivity = new ActivityBuilder(mService)
720 .setStack(homeStack)
721 .setCreateTask(true)
722 .build();
723 final Task task = firstActivity.getTask();
724 final ActivityRecord secondActivity = new ActivityBuilder(mService)
725 .setTask(task)
726 .build();
727
728 doReturn(false).when(secondActivity).occludesParent();
729 homeStack.ensureActivitiesVisible(null /* starting */, 0 /* configChanges */,
730 false /* preserveWindows */);
731
732 assertTrue(firstActivity.shouldBeVisible());
733 }
734
735 @Test
Winson Chungd922b6b2018-02-16 16:41:50 -0800736 public void testMoveHomeStackBehindBottomMostVisibleStack_NoMoveHomeBehindFullscreen() {
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -0700737 mDefaultTaskDisplayArea.removeStack(mStack);
Winson Chungd922b6b2018-02-16 16:41:50 -0800738
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -0700739 final ActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea,
Winson Chungd922b6b2018-02-16 16:41:50 -0800740 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -0700741 final ActivityStack fullscreenStack = createStackForShouldBeVisibleTest(
742 mDefaultTaskDisplayArea, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
743 true /* onTop */);
Winson Chungd922b6b2018-02-16 16:41:50 -0800744
Wale Ogunwale8f93b642019-12-26 12:10:52 -0800745 doReturn(false).when(homeStack).isTranslucent(any());
746 doReturn(false).when(fullscreenStack).isTranslucent(any());
Winson Chungd922b6b2018-02-16 16:41:50 -0800747
748 // Ensure that we don't move the home stack if it is already behind the top fullscreen stack
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -0700749 int homeStackIndex = mDefaultTaskDisplayArea.getIndexOf(homeStack);
Andrii Kulian86d676c2020-03-27 19:34:54 -0700750 assertEquals(fullscreenStack, getStackAbove(homeStack));
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -0700751 mDefaultTaskDisplayArea.moveStackBehindBottomMostVisibleStack(homeStack);
752 assertEquals(homeStackIndex, mDefaultTaskDisplayArea.getIndexOf(homeStack));
Winson Chungd922b6b2018-02-16 16:41:50 -0800753 }
754
755 @Test
756 public void testMoveHomeStackBehindBottomMostVisibleStack_NoMoveHomeBehindTranslucent() {
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -0700757 mDefaultTaskDisplayArea.removeStack(mStack);
Winson Chungd922b6b2018-02-16 16:41:50 -0800758
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -0700759 final ActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea,
Winson Chungd922b6b2018-02-16 16:41:50 -0800760 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -0700761 final ActivityStack fullscreenStack = createStackForShouldBeVisibleTest(
762 mDefaultTaskDisplayArea,
Winson Chungd922b6b2018-02-16 16:41:50 -0800763 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
764
Wale Ogunwale8f93b642019-12-26 12:10:52 -0800765 doReturn(false).when(homeStack).isTranslucent(any());
766 doReturn(true).when(fullscreenStack).isTranslucent(any());
Winson Chungd922b6b2018-02-16 16:41:50 -0800767
768 // Ensure that we don't move the home stack if it is already behind the top fullscreen stack
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -0700769 int homeStackIndex = mDefaultTaskDisplayArea.getIndexOf(homeStack);
Andrii Kulian86d676c2020-03-27 19:34:54 -0700770 assertEquals(fullscreenStack, getStackAbove(homeStack));
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -0700771 mDefaultTaskDisplayArea.moveStackBehindBottomMostVisibleStack(homeStack);
772 assertEquals(homeStackIndex, mDefaultTaskDisplayArea.getIndexOf(homeStack));
Winson Chungd922b6b2018-02-16 16:41:50 -0800773 }
774
775 @Test
776 public void testMoveHomeStackBehindBottomMostVisibleStack_NoMoveHomeOnTop() {
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -0700777 mDefaultTaskDisplayArea.removeStack(mStack);
Winson Chungd922b6b2018-02-16 16:41:50 -0800778
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -0700779 final ActivityStack fullscreenStack = createStackForShouldBeVisibleTest(
780 mDefaultTaskDisplayArea, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
781 true /* onTop */);
782 final ActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea,
Winson Chungd922b6b2018-02-16 16:41:50 -0800783 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
784
Wale Ogunwale8f93b642019-12-26 12:10:52 -0800785 doReturn(false).when(homeStack).isTranslucent(any());
786 doReturn(false).when(fullscreenStack).isTranslucent(any());
Winson Chungd922b6b2018-02-16 16:41:50 -0800787
788 // Ensure we don't move the home stack if it is already on top
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -0700789 int homeStackIndex = mDefaultTaskDisplayArea.getIndexOf(homeStack);
Andrii Kulian86d676c2020-03-27 19:34:54 -0700790 assertNull(getStackAbove(homeStack));
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -0700791 mDefaultTaskDisplayArea.moveStackBehindBottomMostVisibleStack(homeStack);
792 assertEquals(homeStackIndex, mDefaultTaskDisplayArea.getIndexOf(homeStack));
Winson Chungd922b6b2018-02-16 16:41:50 -0800793 }
794
795 @Test
796 public void testMoveHomeStackBehindBottomMostVisibleStack_MoveHomeBehindFullscreen() {
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -0700797 mDefaultTaskDisplayArea.removeStack(mStack);
Winson Chungd922b6b2018-02-16 16:41:50 -0800798
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -0700799 final ActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea,
Winson Chungd922b6b2018-02-16 16:41:50 -0800800 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
Wale Ogunwale8a1860a2019-06-05 08:57:19 -0700801 final ActivityStack fullscreenStack1 = createStackForShouldBeVisibleTest(
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -0700802 mDefaultTaskDisplayArea, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
Winson Chung3e2980e2018-03-29 17:28:57 -0700803 true /* onTop */);
Wale Ogunwale8a1860a2019-06-05 08:57:19 -0700804 final ActivityStack fullscreenStack2 = createStackForShouldBeVisibleTest(
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -0700805 mDefaultTaskDisplayArea, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
Winson Chung3e2980e2018-03-29 17:28:57 -0700806 true /* onTop */);
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -0700807 final ActivityStack pinnedStack = createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea,
Winson Chungd922b6b2018-02-16 16:41:50 -0800808 WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, true /* onTop */);
809
Wale Ogunwale8f93b642019-12-26 12:10:52 -0800810 doReturn(false).when(homeStack).isTranslucent(any());
811 doReturn(false).when(fullscreenStack1).isTranslucent(any());
812 doReturn(false).when(fullscreenStack2).isTranslucent(any());
Winson Chungd922b6b2018-02-16 16:41:50 -0800813
814 // Ensure that we move the home stack behind the bottom most fullscreen stack, ignoring the
815 // pinned stack
Andrii Kulian86d676c2020-03-27 19:34:54 -0700816 assertEquals(fullscreenStack1, getStackAbove(homeStack));
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -0700817 mDefaultTaskDisplayArea.moveStackBehindBottomMostVisibleStack(homeStack);
Andrii Kulian86d676c2020-03-27 19:34:54 -0700818 assertEquals(fullscreenStack2, getStackAbove(homeStack));
Winson Chungd922b6b2018-02-16 16:41:50 -0800819 }
820
821 @Test
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900822 public void
823 testMoveHomeStackBehindBottomMostVisibleStack_MoveHomeBehindFullscreenAndTranslucent() {
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -0700824 mDefaultTaskDisplayArea.removeStack(mStack);
Winson Chungd922b6b2018-02-16 16:41:50 -0800825
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -0700826 final ActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea,
Winson Chungd922b6b2018-02-16 16:41:50 -0800827 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
Wale Ogunwale8a1860a2019-06-05 08:57:19 -0700828 final ActivityStack fullscreenStack1 = createStackForShouldBeVisibleTest(
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -0700829 mDefaultTaskDisplayArea, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
Winson Chung3e2980e2018-03-29 17:28:57 -0700830 true /* onTop */);
Wale Ogunwale8a1860a2019-06-05 08:57:19 -0700831 final ActivityStack fullscreenStack2 = createStackForShouldBeVisibleTest(
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -0700832 mDefaultTaskDisplayArea, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
Winson Chung3e2980e2018-03-29 17:28:57 -0700833 true /* onTop */);
Winson Chungd922b6b2018-02-16 16:41:50 -0800834
Wale Ogunwale8f93b642019-12-26 12:10:52 -0800835 doReturn(false).when(homeStack).isTranslucent(any());
836 doReturn(false).when(fullscreenStack1).isTranslucent(any());
837 doReturn(true).when(fullscreenStack2).isTranslucent(any());
Winson Chungd922b6b2018-02-16 16:41:50 -0800838
839 // Ensure that we move the home stack behind the bottom most non-translucent fullscreen
840 // stack
Andrii Kulian86d676c2020-03-27 19:34:54 -0700841 assertEquals(fullscreenStack1, getStackAbove(homeStack));
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -0700842 mDefaultTaskDisplayArea.moveStackBehindBottomMostVisibleStack(homeStack);
Andrii Kulian86d676c2020-03-27 19:34:54 -0700843 assertEquals(fullscreenStack1, getStackAbove(homeStack));
Winson Chungd922b6b2018-02-16 16:41:50 -0800844 }
845
846 @Test
847 public void testMoveHomeStackBehindStack_BehindHomeStack() {
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -0700848 mDefaultTaskDisplayArea.removeStack(mStack);
Winson Chungd922b6b2018-02-16 16:41:50 -0800849
Wale Ogunwale8a1860a2019-06-05 08:57:19 -0700850 final ActivityStack fullscreenStack1 = createStackForShouldBeVisibleTest(
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -0700851 mDefaultTaskDisplayArea, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
Winson Chung3e2980e2018-03-29 17:28:57 -0700852 true /* onTop */);
Wale Ogunwale8a1860a2019-06-05 08:57:19 -0700853 final ActivityStack fullscreenStack2 = createStackForShouldBeVisibleTest(
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -0700854 mDefaultTaskDisplayArea, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
Winson Chung3e2980e2018-03-29 17:28:57 -0700855 true /* onTop */);
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -0700856 final ActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea,
Winson Chungd922b6b2018-02-16 16:41:50 -0800857 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
858
Wale Ogunwale8f93b642019-12-26 12:10:52 -0800859 doReturn(false).when(homeStack).isTranslucent(any());
860 doReturn(false).when(fullscreenStack1).isTranslucent(any());
861 doReturn(false).when(fullscreenStack2).isTranslucent(any());
Winson Chungd922b6b2018-02-16 16:41:50 -0800862
863 // Ensure we don't move the home stack behind itself
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -0700864 int homeStackIndex = mDefaultTaskDisplayArea.getIndexOf(homeStack);
865 mDefaultTaskDisplayArea.moveStackBehindStack(homeStack, homeStack);
866 assertEquals(homeStackIndex, mDefaultTaskDisplayArea.getIndexOf(homeStack));
Winson Chungd922b6b2018-02-16 16:41:50 -0800867 }
868
869 @Test
870 public void testMoveHomeStackBehindStack() {
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -0700871 mDefaultTaskDisplayArea.removeStack(mStack);
Winson Chungd922b6b2018-02-16 16:41:50 -0800872
Wale Ogunwale8a1860a2019-06-05 08:57:19 -0700873 final ActivityStack fullscreenStack1 = createStackForShouldBeVisibleTest(
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -0700874 mDefaultTaskDisplayArea, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
Winson Chung3e2980e2018-03-29 17:28:57 -0700875 true /* onTop */);
Wale Ogunwale8a1860a2019-06-05 08:57:19 -0700876 final ActivityStack fullscreenStack2 = createStackForShouldBeVisibleTest(
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -0700877 mDefaultTaskDisplayArea, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
Winson Chung3e2980e2018-03-29 17:28:57 -0700878 true /* onTop */);
Wale Ogunwale8a1860a2019-06-05 08:57:19 -0700879 final ActivityStack fullscreenStack3 = createStackForShouldBeVisibleTest(
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -0700880 mDefaultTaskDisplayArea, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
Winson Chung3e2980e2018-03-29 17:28:57 -0700881 true /* onTop */);
Wale Ogunwale8a1860a2019-06-05 08:57:19 -0700882 final ActivityStack fullscreenStack4 = createStackForShouldBeVisibleTest(
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -0700883 mDefaultTaskDisplayArea, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
Winson Chung3e2980e2018-03-29 17:28:57 -0700884 true /* onTop */);
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -0700885 final ActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea,
Winson Chungd922b6b2018-02-16 16:41:50 -0800886 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
887
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -0700888 mDefaultTaskDisplayArea.moveStackBehindStack(homeStack, fullscreenStack1);
Andrii Kulian86d676c2020-03-27 19:34:54 -0700889 assertEquals(fullscreenStack1, getStackAbove(homeStack));
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -0700890 mDefaultTaskDisplayArea.moveStackBehindStack(homeStack, fullscreenStack2);
Andrii Kulian86d676c2020-03-27 19:34:54 -0700891 assertEquals(fullscreenStack2, getStackAbove(homeStack));
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -0700892 mDefaultTaskDisplayArea.moveStackBehindStack(homeStack, fullscreenStack4);
Andrii Kulian86d676c2020-03-27 19:34:54 -0700893 assertEquals(fullscreenStack4, getStackAbove(homeStack));
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -0700894 mDefaultTaskDisplayArea.moveStackBehindStack(homeStack, fullscreenStack2);
Andrii Kulian86d676c2020-03-27 19:34:54 -0700895 assertEquals(fullscreenStack2, getStackAbove(homeStack));
Winson Chungd922b6b2018-02-16 16:41:50 -0800896 }
897
Wale Ogunwalebb285872018-03-01 13:05:30 -0800898 @Test
Kazuki Takisef85197b2018-06-18 18:18:36 +0900899 public void testSetAlwaysOnTop() {
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -0700900 final ActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea,
Kazuki Takisef85197b2018-06-18 18:18:36 +0900901 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -0700902 final ActivityStack pinnedStack = createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea,
Kazuki Takisef85197b2018-06-18 18:18:36 +0900903 WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, true /* onTop */);
Andrii Kulian86d676c2020-03-27 19:34:54 -0700904 assertEquals(pinnedStack, getStackAbove(homeStack));
Kazuki Takisef85197b2018-06-18 18:18:36 +0900905
Wale Ogunwale8a1860a2019-06-05 08:57:19 -0700906 final ActivityStack alwaysOnTopStack = createStackForShouldBeVisibleTest(
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -0700907 mDefaultTaskDisplayArea, WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD,
Kazuki Takisef85197b2018-06-18 18:18:36 +0900908 true /* onTop */);
909 alwaysOnTopStack.setAlwaysOnTop(true);
910 assertTrue(alwaysOnTopStack.isAlwaysOnTop());
911 // Ensure (non-pinned) always on top stack is put below pinned stack.
Andrii Kulian86d676c2020-03-27 19:34:54 -0700912 assertEquals(pinnedStack, getStackAbove(alwaysOnTopStack));
Kazuki Takisef85197b2018-06-18 18:18:36 +0900913
Wale Ogunwale8a1860a2019-06-05 08:57:19 -0700914 final ActivityStack nonAlwaysOnTopStack = createStackForShouldBeVisibleTest(
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -0700915 mDefaultTaskDisplayArea, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
Kazuki Takisef85197b2018-06-18 18:18:36 +0900916 true /* onTop */);
917 // Ensure non always on top stack is put below always on top stacks.
Andrii Kulian86d676c2020-03-27 19:34:54 -0700918 assertEquals(alwaysOnTopStack, getStackAbove(nonAlwaysOnTopStack));
Kazuki Takisef85197b2018-06-18 18:18:36 +0900919
Wale Ogunwale8a1860a2019-06-05 08:57:19 -0700920 final ActivityStack alwaysOnTopStack2 = createStackForShouldBeVisibleTest(
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -0700921 mDefaultTaskDisplayArea, WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD,
Kazuki Takisef85197b2018-06-18 18:18:36 +0900922 true /* onTop */);
923 alwaysOnTopStack2.setAlwaysOnTop(true);
924 assertTrue(alwaysOnTopStack2.isAlwaysOnTop());
925 // Ensure newly created always on top stack is placed above other all always on top stacks.
Andrii Kulian86d676c2020-03-27 19:34:54 -0700926 assertEquals(pinnedStack, getStackAbove(alwaysOnTopStack2));
Kazuki Takisef85197b2018-06-18 18:18:36 +0900927
928 alwaysOnTopStack2.setAlwaysOnTop(false);
929 // Ensure, when always on top is turned off for a stack, the stack is put just below all
930 // other always on top stacks.
Andrii Kulian86d676c2020-03-27 19:34:54 -0700931 assertEquals(alwaysOnTopStack, getStackAbove(alwaysOnTopStack2));
Kazuki Takise048e2662018-06-27 17:05:11 +0900932 alwaysOnTopStack2.setAlwaysOnTop(true);
933
934 // Ensure always on top state changes properly when windowing mode changes.
935 alwaysOnTopStack2.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
936 assertFalse(alwaysOnTopStack2.isAlwaysOnTop());
Andrii Kulian86d676c2020-03-27 19:34:54 -0700937 assertEquals(alwaysOnTopStack, getStackAbove(alwaysOnTopStack2));
Kazuki Takise048e2662018-06-27 17:05:11 +0900938 alwaysOnTopStack2.setWindowingMode(WINDOWING_MODE_FREEFORM);
939 assertTrue(alwaysOnTopStack2.isAlwaysOnTop());
Andrii Kulian86d676c2020-03-27 19:34:54 -0700940 assertEquals(pinnedStack, getStackAbove(alwaysOnTopStack2));
Kazuki Takisef85197b2018-06-18 18:18:36 +0900941 }
942
943 @Test
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900944 public void testSplitScreenMoveToFront() {
Wale Ogunwale8a1860a2019-06-05 08:57:19 -0700945 final ActivityStack splitScreenPrimary = createStackForShouldBeVisibleTest(
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -0700946 mDefaultTaskDisplayArea, WINDOWING_MODE_SPLIT_SCREEN_PRIMARY,
947 ACTIVITY_TYPE_STANDARD, true /* onTop */);
Wale Ogunwale8a1860a2019-06-05 08:57:19 -0700948 final ActivityStack splitScreenSecondary = createStackForShouldBeVisibleTest(
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -0700949 mDefaultTaskDisplayArea, WINDOWING_MODE_SPLIT_SCREEN_SECONDARY,
950 ACTIVITY_TYPE_STANDARD, true /* onTop */);
951 final ActivityStack assistantStack = createStackForShouldBeVisibleTest(
952 mDefaultTaskDisplayArea, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_ASSISTANT,
Winson Chung3e2980e2018-03-29 17:28:57 -0700953 true /* onTop */);
Wale Ogunwalebb285872018-03-01 13:05:30 -0800954
Wale Ogunwale8f93b642019-12-26 12:10:52 -0800955 doReturn(false).when(splitScreenPrimary).isTranslucent(any());
956 doReturn(false).when(splitScreenSecondary).isTranslucent(any());
957 doReturn(false).when(assistantStack).isTranslucent(any());
Wale Ogunwalebb285872018-03-01 13:05:30 -0800958
959 assertFalse(splitScreenPrimary.shouldBeVisible(null /* starting */));
960 assertFalse(splitScreenSecondary.shouldBeVisible(null /* starting */));
961 assertTrue(assistantStack.shouldBeVisible(null /* starting */));
962
963 splitScreenSecondary.moveToFront("testSplitScreenMoveToFront");
964
Galia Peycheva7ecd6ef2020-03-26 19:59:40 +0100965 if (isAssistantOnTop()) {
966 assertFalse(splitScreenPrimary.shouldBeVisible(null /* starting */));
967 assertFalse(splitScreenSecondary.shouldBeVisible(null /* starting */));
968 assertTrue(assistantStack.shouldBeVisible(null /* starting */));
969 } else {
970 assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */));
971 assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
972 assertFalse(assistantStack.shouldBeVisible(null /* starting */));
973 }
Wale Ogunwalebb285872018-03-01 13:05:30 -0800974 }
975
Wale Ogunwale8a1860a2019-06-05 08:57:19 -0700976 private ActivityStack createStandardStackForVisibilityTest(int windowingMode,
Andrii Kulian0c869cc2019-02-06 19:50:32 -0800977 boolean translucent) {
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -0700978 final ActivityStack stack = createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea,
Andrii Kulian0c869cc2019-02-06 19:50:32 -0800979 windowingMode, ACTIVITY_TYPE_STANDARD, true /* onTop */);
Wale Ogunwale8f93b642019-12-26 12:10:52 -0800980 doReturn(translucent).when(stack).isTranslucent(any());
Andrii Kulian0c869cc2019-02-06 19:50:32 -0800981 return stack;
982 }
983
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900984 @SuppressWarnings("TypeParameterUnusedInFormals")
Louis Chang2453d062019-11-19 22:30:48 +0800985 private ActivityStack createStackForShouldBeVisibleTest(
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -0700986 TaskDisplayArea taskDisplayArea, int windowingMode, int activityType, boolean onTop) {
Wale Ogunwale8a1860a2019-06-05 08:57:19 -0700987 final ActivityStack stack;
Andrii Kulian6a6c4f12018-07-16 21:23:33 -0700988 if (activityType == ACTIVITY_TYPE_HOME) {
989 // Home stack and activity are created in ActivityTestsBase#setupActivityManagerService
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -0700990 stack = mDefaultTaskDisplayArea.getStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME);
Andrii Kulian6a6c4f12018-07-16 21:23:33 -0700991 if (onTop) {
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -0700992 mDefaultTaskDisplayArea.positionStackAtTop(stack,
Andrii Kulian9ea12da2020-03-27 17:16:38 -0700993 false /* includingParents */);
Andrii Kulian6a6c4f12018-07-16 21:23:33 -0700994 } else {
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -0700995 mDefaultTaskDisplayArea.positionStackAtBottom(stack);
Andrii Kulian6a6c4f12018-07-16 21:23:33 -0700996 }
997 } else {
Louis Chang149d5c82019-12-30 09:47:39 +0800998 stack = new StackBuilder(mRootWindowContainer)
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -0700999 .setTaskDisplayArea(taskDisplayArea)
Wale Ogunwale8a1860a2019-06-05 08:57:19 -07001000 .setWindowingMode(windowingMode)
1001 .setActivityType(activityType)
1002 .setOnTop(onTop)
1003 .setCreateActivity(true)
1004 .build();
Andrii Kulian6a6c4f12018-07-16 21:23:33 -07001005 }
Louis Chang2453d062019-11-19 22:30:48 +08001006 return stack;
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -07001007 }
Bryce Leeb0f993f2018-03-02 15:38:01 -08001008
1009 @Test
Riddle Hsuaaef7312019-01-24 19:00:58 +08001010 public void testFinishDisabledPackageActivities_FinishAliveActivities() {
Bryce Leefbd263b42018-03-07 10:33:55 -08001011 final ActivityRecord firstActivity = new ActivityBuilder(mService).setTask(mTask).build();
1012 final ActivityRecord secondActivity = new ActivityBuilder(mService).setTask(mTask).build();
Riddle Hsuaaef7312019-01-24 19:00:58 +08001013 firstActivity.setState(STOPPED, "testFinishDisabledPackageActivities");
1014 secondActivity.setState(RESUMED, "testFinishDisabledPackageActivities");
1015 mStack.mResumedActivity = secondActivity;
Bryce Leefbd263b42018-03-07 10:33:55 -08001016
Riddle Hsuaaef7312019-01-24 19:00:58 +08001017 // Note the activities have non-null ActivityRecord.app, so it won't remove directly.
Louis Chang149d5c82019-12-30 09:47:39 +08001018 mRootWindowContainer.mFinishDisabledPackageActivitiesHelper.process(
Wale Ogunwalea38654f2019-11-17 20:37:15 -08001019 firstActivity.packageName, null /* filterByClasses */, true /* doit */,
1020 true /* evenPersistent */, UserHandle.USER_ALL);
Riddle Hsuaaef7312019-01-24 19:00:58 +08001021
1022 // If the activity is disabled with {@link android.content.pm.PackageManager#DONT_KILL_APP}
1023 // the activity should still follow the normal flow to finish and destroy.
1024 assertThat(firstActivity.getState()).isEqualTo(DESTROYING);
1025 assertThat(secondActivity.getState()).isEqualTo(PAUSING);
1026 assertTrue(secondActivity.finishing);
1027 }
1028
1029 @Test
1030 public void testFinishDisabledPackageActivities_RemoveNonAliveActivities() {
1031 final ActivityRecord activity = new ActivityBuilder(mService).setTask(mTask).build();
1032
1033 // The overlay activity is not in the disabled package but it is in the same task.
1034 final ActivityRecord overlayActivity = new ActivityBuilder(mService).setTask(mTask)
1035 .setComponent(new ComponentName("package.overlay", ".OverlayActivity")).build();
1036 // If the task only remains overlay activity, the task should also be removed.
Andrii Kulian79d67982019-08-19 11:56:16 -07001037 // See {@link ActivityStack#removeFromHistory}.
Wale Ogunwale0b3d2922019-12-30 08:55:07 -08001038 overlayActivity.setTaskOverlay(true);
Riddle Hsuaaef7312019-01-24 19:00:58 +08001039
1040 // The activity without an app means it will be removed immediately.
1041 // See {@link ActivityStack#destroyActivityLocked}.
1042 activity.app = null;
1043 overlayActivity.app = null;
Bryce Leefbd263b42018-03-07 10:33:55 -08001044
Wale Ogunwale1a06f152019-10-11 11:26:30 +02001045 assertEquals(2, mTask.getChildCount());
Bryce Leefbd263b42018-03-07 10:33:55 -08001046
Louis Chang149d5c82019-12-30 09:47:39 +08001047 mRootWindowContainer.mFinishDisabledPackageActivitiesHelper.process(
Wale Ogunwalea38654f2019-11-17 20:37:15 -08001048 activity.packageName, null /* filterByClasses */, true /* doit */,
1049 true /* evenPersistent */, UserHandle.USER_ALL);
Bryce Leefbd263b42018-03-07 10:33:55 -08001050
Riddle Hsuaaef7312019-01-24 19:00:58 +08001051 // Although the overlay activity is in another package, the non-overlay activities are
1052 // removed from the task. Since the overlay activity should be removed as well, the task
1053 // should be empty.
Wale Ogunwale1a06f152019-10-11 11:26:30 +02001054 assertFalse(mTask.hasChild());
Wale Ogunwale85fb19a2019-12-05 10:41:05 +09001055 assertFalse(mStack.hasChild());
Bryce Leefbd263b42018-03-07 10:33:55 -08001056 }
1057
1058 @Test
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +09001059 public void testHandleAppDied() {
Bryce Leefbd263b42018-03-07 10:33:55 -08001060 final ActivityRecord firstActivity = new ActivityBuilder(mService).setTask(mTask).build();
1061 final ActivityRecord secondActivity = new ActivityBuilder(mService).setTask(mTask).build();
1062
1063 // Making the first activity a task overlay means it will be removed from the task's
1064 // activities as well once second activity is removed as handleAppDied processes the
1065 // activity list in reverse.
Wale Ogunwale0b3d2922019-12-30 08:55:07 -08001066 firstActivity.setTaskOverlay(true);
Bryce Leefbd263b42018-03-07 10:33:55 -08001067 firstActivity.app = null;
1068
1069 // second activity will be immediately removed as it has no state.
Andrii Kulian06b8dcb2019-07-10 21:09:38 -07001070 secondActivity.setSavedState(null /* savedState */);
Bryce Leefbd263b42018-03-07 10:33:55 -08001071
Wale Ogunwale1a06f152019-10-11 11:26:30 +02001072 assertEquals(2, mTask.getChildCount());
Bryce Leefbd263b42018-03-07 10:33:55 -08001073
Louis Chang149d5c82019-12-30 09:47:39 +08001074 mRootWindowContainer.handleAppDied(secondActivity.app);
Bryce Leefbd263b42018-03-07 10:33:55 -08001075
Wale Ogunwale1a06f152019-10-11 11:26:30 +02001076 assertFalse(mTask.hasChild());
Wale Ogunwale85fb19a2019-12-05 10:41:05 +09001077 assertFalse(mStack.hasChild());
Bryce Leefbd263b42018-03-07 10:33:55 -08001078 }
Bryce Lee271617a2018-03-15 10:39:12 -07001079
1080 @Test
Garfield Tanf6cc5c92019-01-15 13:54:12 -08001081 public void testHandleAppDied_RelaunchesAfterCrashDuringWindowingModeResize() {
1082 final ActivityRecord activity = new ActivityBuilder(mService).setTask(mTask).build();
1083
1084 activity.mRelaunchReason = RELAUNCH_REASON_WINDOWING_MODE_RESIZE;
1085 activity.launchCount = 1;
Andrii Kulian06b8dcb2019-07-10 21:09:38 -07001086 activity.setSavedState(null /* savedState */);
Garfield Tanf6cc5c92019-01-15 13:54:12 -08001087
Louis Chang149d5c82019-12-30 09:47:39 +08001088 mRootWindowContainer.handleAppDied(activity.app);
Garfield Tanf6cc5c92019-01-15 13:54:12 -08001089
Wale Ogunwale1a06f152019-10-11 11:26:30 +02001090 assertEquals(1, mTask.getChildCount());
Wale Ogunwale85fb19a2019-12-05 10:41:05 +09001091 assertEquals(1, mStack.getChildCount());
Garfield Tanf6cc5c92019-01-15 13:54:12 -08001092 }
1093
1094 @Test
1095 public void testHandleAppDied_NotRelaunchAfterThreeCrashesDuringWindowingModeResize() {
1096 final ActivityRecord activity = new ActivityBuilder(mService).setTask(mTask).build();
1097
1098 activity.mRelaunchReason = RELAUNCH_REASON_WINDOWING_MODE_RESIZE;
1099 activity.launchCount = 3;
Andrii Kulian06b8dcb2019-07-10 21:09:38 -07001100 activity.setSavedState(null /* savedState */);
Garfield Tanf6cc5c92019-01-15 13:54:12 -08001101
Louis Chang149d5c82019-12-30 09:47:39 +08001102 mRootWindowContainer.handleAppDied(activity.app);
Garfield Tanf6cc5c92019-01-15 13:54:12 -08001103
Wale Ogunwale1a06f152019-10-11 11:26:30 +02001104 assertFalse(mTask.hasChild());
Wale Ogunwale85fb19a2019-12-05 10:41:05 +09001105 assertFalse(mStack.hasChild());
Garfield Tanf6cc5c92019-01-15 13:54:12 -08001106 }
1107
1108 @Test
1109 public void testHandleAppDied_RelaunchesAfterCrashDuringFreeResize() {
1110 final ActivityRecord activity = new ActivityBuilder(mService).setTask(mTask).build();
1111
1112 activity.mRelaunchReason = RELAUNCH_REASON_FREE_RESIZE;
1113 activity.launchCount = 1;
Andrii Kulian06b8dcb2019-07-10 21:09:38 -07001114 activity.setSavedState(null /* savedState */);
Garfield Tanf6cc5c92019-01-15 13:54:12 -08001115
Louis Chang149d5c82019-12-30 09:47:39 +08001116 mRootWindowContainer.handleAppDied(activity.app);
Garfield Tanf6cc5c92019-01-15 13:54:12 -08001117
Wale Ogunwale1a06f152019-10-11 11:26:30 +02001118 assertEquals(1, mTask.getChildCount());
Wale Ogunwale85fb19a2019-12-05 10:41:05 +09001119 assertEquals(1, mStack.getChildCount());
Garfield Tanf6cc5c92019-01-15 13:54:12 -08001120 }
1121
1122 @Test
1123 public void testHandleAppDied_NotRelaunchAfterThreeCrashesDuringFreeResize() {
1124 final ActivityRecord activity = new ActivityBuilder(mService).setTask(mTask).build();
1125
1126 activity.mRelaunchReason = RELAUNCH_REASON_FREE_RESIZE;
1127 activity.launchCount = 3;
Andrii Kulian06b8dcb2019-07-10 21:09:38 -07001128 activity.setSavedState(null /* savedState */);
Garfield Tanf6cc5c92019-01-15 13:54:12 -08001129
Louis Chang149d5c82019-12-30 09:47:39 +08001130 mRootWindowContainer.handleAppDied(activity.app);
Garfield Tanf6cc5c92019-01-15 13:54:12 -08001131
Wale Ogunwale1a06f152019-10-11 11:26:30 +02001132 assertFalse(mTask.hasChild());
Wale Ogunwale85fb19a2019-12-05 10:41:05 +09001133 assertFalse(mStack.hasChild());
Garfield Tanf6cc5c92019-01-15 13:54:12 -08001134 }
1135
1136 @Test
Louis Chang7b03ad92019-08-21 12:32:33 +08001137 public void testCompletePauseOnResumeWhilePausingActivity() {
1138 final ActivityRecord bottomActivity = new ActivityBuilder(mService).setTask(mTask).build();
1139 doReturn(true).when(bottomActivity).attachedToProcess();
1140 mStack.mPausingActivity = null;
1141 mStack.mResumedActivity = bottomActivity;
1142 final ActivityRecord topActivity = new ActivityBuilder(mService).setTask(mTask).build();
1143 topActivity.info.flags |= FLAG_RESUME_WHILE_PAUSING;
1144
1145 mStack.startPausingLocked(false /* userLeaving */, false /* uiSleeping */, topActivity);
1146 verify(mStack).completePauseLocked(anyBoolean(), eq(topActivity));
1147 }
1148
1149 @Test
wilsonshih8824a8a2019-03-12 17:21:35 +08001150 public void testWontFinishHomeStackImmediately() {
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -07001151 final ActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea,
wilsonshih8824a8a2019-03-12 17:21:35 +08001152 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
1153
Wale Ogunwale85fb19a2019-12-05 10:41:05 +09001154 ActivityRecord activity = homeStack.topRunningActivity();
Wale Ogunwale8a1860a2019-06-05 08:57:19 -07001155 if (activity == null) {
1156 activity = new ActivityBuilder(mService)
1157 .setStack(homeStack)
1158 .setCreateTask(true)
1159 .build();
1160 }
1161
wilsonshih8824a8a2019-03-12 17:21:35 +08001162 // Home stack should not be destroyed immediately.
Andrii Kulian7dd39bb2019-07-22 13:11:10 -07001163 final ActivityRecord activity1 = finishTopActivity(homeStack);
wilsonshih8824a8a2019-03-12 17:21:35 +08001164 assertEquals(FINISHING, activity1.getState());
1165 }
1166
1167 @Test
Riddle Hsue10cea52018-10-16 23:33:23 +08001168 public void testFinishCurrentActivity() {
1169 // Create 2 activities on a new display.
Louis Chang677921f2019-12-06 16:44:24 +08001170 final DisplayContent display = addNewDisplayContentAt(DisplayContent.POSITION_TOP);
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -07001171 final ActivityStack stack1 = createStackForShouldBeVisibleTest(
1172 display.getDefaultTaskDisplayArea(),
Riddle Hsue10cea52018-10-16 23:33:23 +08001173 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -07001174 final ActivityStack stack2 = createStackForShouldBeVisibleTest(
1175 display.getDefaultTaskDisplayArea(),
Riddle Hsue10cea52018-10-16 23:33:23 +08001176 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
1177
1178 // There is still an activity1 in stack1 so the activity2 should be added to finishing list
1179 // that will be destroyed until idle.
Issei Suzuki1669ea42019-11-06 14:20:59 +01001180 stack2.getTopNonFinishingActivity().mVisibleRequested = true;
Andrii Kulian7dd39bb2019-07-22 13:11:10 -07001181 final ActivityRecord activity2 = finishTopActivity(stack2);
Louis Changf2835df2018-10-17 15:14:45 +08001182 assertEquals(STOPPING, activity2.getState());
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +09001183 assertThat(mSupervisor.mStoppingActivities).contains(activity2);
Riddle Hsue10cea52018-10-16 23:33:23 +08001184
1185 // The display becomes empty. Since there is no next activity to be idle, the activity
1186 // should be destroyed immediately with updating configuration to restore original state.
Andrii Kulian7dd39bb2019-07-22 13:11:10 -07001187 final ActivityRecord activity1 = finishTopActivity(stack1);
Riddle Hsue10cea52018-10-16 23:33:23 +08001188 assertEquals(DESTROYING, activity1.getState());
Louis Chang149d5c82019-12-30 09:47:39 +08001189 verify(mRootWindowContainer).ensureVisibilityAndConfig(eq(null) /* starting */,
Riddle Hsue10cea52018-10-16 23:33:23 +08001190 eq(display.mDisplayId), anyBoolean(), anyBoolean());
1191 }
1192
Andrii Kulian7dd39bb2019-07-22 13:11:10 -07001193 private ActivityRecord finishTopActivity(ActivityStack stack) {
Wale Ogunwale85fb19a2019-12-05 10:41:05 +09001194 final ActivityRecord activity = stack.topRunningActivity();
Riddle Hsue10cea52018-10-16 23:33:23 +08001195 assertNotNull(activity);
Andrii Kulian7dd39bb2019-07-22 13:11:10 -07001196 activity.setState(STOPPED, "finishTopActivity");
Riddle Hsue10cea52018-10-16 23:33:23 +08001197 activity.makeFinishingLocked();
Andrii Kulian7dd39bb2019-07-22 13:11:10 -07001198 activity.completeFinishing("finishTopActivity");
Riddle Hsue10cea52018-10-16 23:33:23 +08001199 return activity;
1200 }
1201
1202 @Test
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +09001203 public void testShouldSleepActivities() {
Bryce Lee271617a2018-03-15 10:39:12 -07001204 // When focused activity and keyguard is going away, we should not sleep regardless
1205 // of the display state
1206 verifyShouldSleepActivities(true /* focusedStack */, true /*keyguardGoingAway*/,
1207 true /* displaySleeping */, false /* expected*/);
1208
1209 // When not the focused stack, defer to display sleeping state.
1210 verifyShouldSleepActivities(false /* focusedStack */, true /*keyguardGoingAway*/,
1211 true /* displaySleeping */, true /* expected*/);
1212
1213 // If keyguard is going away, defer to the display sleeping state.
1214 verifyShouldSleepActivities(true /* focusedStack */, false /*keyguardGoingAway*/,
1215 true /* displaySleeping */, true /* expected*/);
1216 verifyShouldSleepActivities(true /* focusedStack */, false /*keyguardGoingAway*/,
1217 false /* displaySleeping */, false /* expected*/);
1218 }
1219
Winson Chung0f7ec962018-05-03 18:03:15 -07001220 @Test
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +09001221 public void testStackOrderChangedOnRemoveStack() {
Winson Chung0f7ec962018-05-03 18:03:15 -07001222 StackOrderChangedListener listener = new StackOrderChangedListener();
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -07001223 mDefaultTaskDisplayArea.registerStackOrderChangedListener(listener);
Winson Chung0f7ec962018-05-03 18:03:15 -07001224 try {
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -07001225 mDefaultTaskDisplayArea.removeStack(mStack);
Winson Chung0f7ec962018-05-03 18:03:15 -07001226 } finally {
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -07001227 mDefaultTaskDisplayArea.unregisterStackOrderChangedListener(listener);
Winson Chung0f7ec962018-05-03 18:03:15 -07001228 }
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +09001229 assertTrue(listener.mChanged);
Winson Chung0f7ec962018-05-03 18:03:15 -07001230 }
1231
1232 @Test
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +09001233 public void testStackOrderChangedOnAddPositionStack() {
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -07001234 mDefaultTaskDisplayArea.removeStack(mStack);
Winson Chung0f7ec962018-05-03 18:03:15 -07001235
1236 StackOrderChangedListener listener = new StackOrderChangedListener();
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -07001237 mDefaultTaskDisplayArea.registerStackOrderChangedListener(listener);
Winson Chung0f7ec962018-05-03 18:03:15 -07001238 try {
Louis Chang677921f2019-12-06 16:44:24 +08001239 mStack.mReparenting = true;
Vishnu Nair7c8a2472020-04-17 16:08:29 -07001240 mDefaultTaskDisplayArea.addChild(mStack, 0);
Winson Chung0f7ec962018-05-03 18:03:15 -07001241 } finally {
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -07001242 mDefaultTaskDisplayArea.unregisterStackOrderChangedListener(listener);
Winson Chung0f7ec962018-05-03 18:03:15 -07001243 }
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +09001244 assertTrue(listener.mChanged);
Winson Chung0f7ec962018-05-03 18:03:15 -07001245 }
1246
1247 @Test
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +09001248 public void testStackOrderChangedOnPositionStack() {
Winson Chung0f7ec962018-05-03 18:03:15 -07001249 StackOrderChangedListener listener = new StackOrderChangedListener();
1250 try {
Wale Ogunwale8a1860a2019-06-05 08:57:19 -07001251 final ActivityStack fullscreenStack1 = createStackForShouldBeVisibleTest(
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -07001252 mDefaultTaskDisplayArea, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
Winson Chung0f7ec962018-05-03 18:03:15 -07001253 true /* onTop */);
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -07001254 mDefaultTaskDisplayArea.registerStackOrderChangedListener(listener);
1255 mDefaultTaskDisplayArea.positionStackAtBottom(fullscreenStack1);
Winson Chung0f7ec962018-05-03 18:03:15 -07001256 } finally {
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -07001257 mDefaultTaskDisplayArea.unregisterStackOrderChangedListener(listener);
Winson Chung0f7ec962018-05-03 18:03:15 -07001258 }
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +09001259 assertTrue(listener.mChanged);
Winson Chung0f7ec962018-05-03 18:03:15 -07001260 }
1261
Louis Changf7f7f9c2019-06-18 16:47:51 +08001262 @Test
Riddle Hsu8e5f6d22020-02-07 00:15:57 +08001263 public void testNavigateUpTo() {
1264 final ActivityStartController controller = mock(ActivityStartController.class);
1265 final ActivityStarter starter = new ActivityStarter(controller,
1266 mService, mService.mStackSupervisor, mock(ActivityStartInterceptor.class));
1267 doReturn(controller).when(mService).getActivityStartController();
1268 spyOn(starter);
1269 doReturn(ActivityManager.START_SUCCESS).when(starter).execute();
1270
1271 final ActivityRecord firstActivity = new ActivityBuilder(mService).setTask(mTask).build();
1272 final ActivityRecord secondActivity = new ActivityBuilder(mService).setTask(mTask)
1273 .setUid(firstActivity.getUid() + 1).build();
1274 doReturn(starter).when(controller).obtainStarter(eq(firstActivity.intent), anyString());
1275
1276 final IApplicationThread thread = secondActivity.app.getThread();
1277 secondActivity.app.setThread(null);
1278 // This should do nothing from a non-attached caller.
1279 assertFalse(mStack.navigateUpTo(secondActivity /* source record */,
1280 firstActivity.intent /* destIntent */, 0 /* resultCode */, null /* resultData */));
1281
1282 secondActivity.app.setThread(thread);
1283 assertTrue(mStack.navigateUpTo(secondActivity /* source record */,
1284 firstActivity.intent /* destIntent */, 0 /* resultCode */, null /* resultData */));
1285 // The firstActivity uses default launch mode, so the activities between it and itself will
1286 // be finished.
1287 assertTrue(secondActivity.finishing);
1288 assertTrue(firstActivity.finishing);
1289 // The caller uid of the new activity should be the current real caller.
1290 assertEquals(starter.mRequest.callingUid, secondActivity.getUid());
1291 }
1292
1293 @Test
Louis Changf7f7f9c2019-06-18 16:47:51 +08001294 public void testResetTaskWithFinishingActivities() {
1295 final ActivityRecord taskTop =
1296 new ActivityBuilder(mService).setStack(mStack).setCreateTask(true).build();
Louis Changcdec0802019-11-11 11:45:07 +08001297 // Make all activities in the task are finishing to simulate Task#getTopActivity
Louis Changf7f7f9c2019-06-18 16:47:51 +08001298 // returns null.
1299 taskTop.finishing = true;
1300
1301 final ActivityRecord newR = new ActivityBuilder(mService).build();
Wale Ogunwaledfbeed72019-11-20 08:57:39 -08001302 final ActivityRecord result = mStack.resetTaskIfNeeded(taskTop, newR);
Louis Changf7f7f9c2019-06-18 16:47:51 +08001303 assertThat(result).isEqualTo(taskTop);
1304 }
1305
Louis Changcfe46212019-07-30 10:34:18 +08001306 @Test
Louis Chang99d6f0e2020-02-21 12:14:32 +08001307 public void testCheckBehindFullscreenActivity() {
1308 final ActivityRecord bottomActivity =
1309 new ActivityBuilder(mService).setStack(mStack).setTask(mTask).build();
1310 final ActivityRecord topActivity =
1311 new ActivityBuilder(mService).setStack(mStack).setTask(mTask).build();
1312 doReturn(true).when(mStack).shouldBeVisible(any());
1313 assertTrue(mStack.checkBehindFullscreenActivity(bottomActivity,
1314 null /* handleBehindFullscreenActivity */));
1315 assertFalse(mStack.checkBehindFullscreenActivity(topActivity,
1316 null /* handleBehindFullscreenActivity */));
1317
1318 doReturn(false).when(topActivity).occludesParent();
1319 assertFalse(mStack.checkBehindFullscreenActivity(bottomActivity,
1320 null /* handleBehindFullscreenActivity */));
1321 assertFalse(mStack.checkBehindFullscreenActivity(topActivity,
1322 null /* handleBehindFullscreenActivity */));
1323
1324 final ActivityRecord finishingActivity =
1325 new ActivityBuilder(mService).setStack(mStack).setTask(mTask).build();
1326 finishingActivity.finishing = true;
1327 doCallRealMethod().when(finishingActivity).occludesParent();
1328 assertFalse(mStack.checkBehindFullscreenActivity(bottomActivity,
1329 null /* handleBehindFullscreenActivity */));
1330 assertFalse(mStack.checkBehindFullscreenActivity(topActivity,
1331 null /* handleBehindFullscreenActivity */));
1332 }
1333
1334 @Test
Riddle Hsu13c27ae2019-10-05 23:10:15 +08001335 public void testClearUnknownAppVisibilityBehindFullscreenActivity() {
1336 final UnknownAppVisibilityController unknownAppVisibilityController =
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -07001337 mDefaultTaskDisplayArea.mDisplayContent.mUnknownAppVisibilityController;
Riddle Hsu13c27ae2019-10-05 23:10:15 +08001338 final KeyguardController keyguardController = mSupervisor.getKeyguardController();
1339 doReturn(true).when(keyguardController).isKeyguardLocked();
1340
1341 // Start 2 activities that their processes have not yet started.
1342 final ActivityRecord[] activities = new ActivityRecord[2];
1343 mSupervisor.beginDeferResume();
1344 for (int i = 0; i < activities.length; i++) {
1345 final ActivityRecord r = new ActivityBuilder(mService).setTask(mTask).build();
1346 activities[i] = r;
1347 doReturn(null).when(mService).getProcessController(
1348 eq(r.processName), eq(r.info.applicationInfo.uid));
1349 r.setState(ActivityStack.ActivityState.INITIALIZING, "test");
1350 // Ensure precondition that the activity is opaque.
1351 assertTrue(r.occludesParent());
Wale Ogunwale076c3b12019-11-20 12:17:22 -08001352 mSupervisor.startSpecificActivity(r, false /* andResume */,
Riddle Hsu13c27ae2019-10-05 23:10:15 +08001353 false /* checkConfig */);
1354 }
1355 mSupervisor.endDeferResume();
1356
1357 doReturn(false).when(mService).isBooting();
1358 doReturn(true).when(mService).isBooted();
1359 // 2 activities are started while keyguard is locked, so they are waiting to be resolved.
1360 assertFalse(unknownAppVisibilityController.allResolved());
1361
1362 // Assume the top activity is going to resume and
Louis Chang149d5c82019-12-30 09:47:39 +08001363 // {@link RootWindowContainer#cancelInitializingActivities} should clear the unknown
Riddle Hsu13c27ae2019-10-05 23:10:15 +08001364 // visibility records that are occluded.
1365 mStack.resumeTopActivityUncheckedLocked(null /* prev */, null /* options */);
1366 // Assume the top activity relayouted, just remove it directly.
1367 unknownAppVisibilityController.appRemovedOrHidden(activities[1]);
1368 // All unresolved records should be removed.
1369 assertTrue(unknownAppVisibilityController.allResolved());
1370 }
1371
1372 @Test
Louis Changcfe46212019-07-30 10:34:18 +08001373 public void testNonTopVisibleActivityNotResume() {
1374 final ActivityRecord nonTopVisibleActivity =
1375 new ActivityBuilder(mService).setTask(mTask).build();
1376 new ActivityBuilder(mService).setTask(mTask).build();
1377 doReturn(false).when(nonTopVisibleActivity).attachedToProcess();
Riddle Hsu13c27ae2019-10-05 23:10:15 +08001378 doReturn(true).when(nonTopVisibleActivity).shouldBeVisible(anyBoolean(), anyBoolean());
Wale Ogunwale076c3b12019-11-20 12:17:22 -08001379 doNothing().when(mSupervisor).startSpecificActivity(any(), anyBoolean(),
Louis Changcfe46212019-07-30 10:34:18 +08001380 anyBoolean());
1381
Wale Ogunwale076c3b12019-11-20 12:17:22 -08001382 mStack.ensureActivitiesVisible(null /* starting */, 0 /* configChanges */,
Louis Changcfe46212019-07-30 10:34:18 +08001383 false /* preserveWindows */);
Wale Ogunwale076c3b12019-11-20 12:17:22 -08001384 verify(mSupervisor).startSpecificActivity(any(), eq(false) /* andResume */,
Louis Changcfe46212019-07-30 10:34:18 +08001385 anyBoolean());
1386 }
1387
Galia Peycheva7ecd6ef2020-03-26 19:59:40 +01001388 private boolean isAssistantOnTop() {
1389 return mContext.getResources().getBoolean(
1390 com.android.internal.R.bool.config_assistantOnTopOfDream);
1391 }
1392
Bryce Lee271617a2018-03-15 10:39:12 -07001393 private void verifyShouldSleepActivities(boolean focusedStack,
1394 boolean keyguardGoingAway, boolean displaySleeping, boolean expected) {
Louis Chang677921f2019-12-06 16:44:24 +08001395 final DisplayContent display = mock(DisplayContent.class);
Bryce Lee271617a2018-03-15 10:39:12 -07001396 final KeyguardController keyguardController = mSupervisor.getKeyguardController();
1397
Louis Chang677921f2019-12-06 16:44:24 +08001398 doReturn(display).when(mStack).getDisplay();
Bryce Lee271617a2018-03-15 10:39:12 -07001399 doReturn(keyguardGoingAway).when(keyguardController).isKeyguardGoingAway();
1400 doReturn(displaySleeping).when(display).isSleeping();
Tiger Huang1e5b10a2018-07-30 20:19:51 +08001401 doReturn(focusedStack).when(mStack).isFocusedStackOnDisplay();
Bryce Lee271617a2018-03-15 10:39:12 -07001402
1403 assertEquals(expected, mStack.shouldSleepActivities());
1404 }
Winson Chung0f7ec962018-05-03 18:03:15 -07001405
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +09001406 private static class StackOrderChangedListener
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -07001407 implements TaskDisplayArea.OnStackOrderChangedListener {
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +09001408 public boolean mChanged = false;
Winson Chung0f7ec962018-05-03 18:03:15 -07001409
1410 @Override
Winson Chung65d66d32018-12-13 17:48:39 -08001411 public void onStackOrderChanged(ActivityStack stack) {
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +09001412 mChanged = true;
Winson Chung0f7ec962018-05-03 18:03:15 -07001413 }
1414 }
Bryce Lee840c5662017-04-13 10:02:51 -07001415}