blob: 84bdecb868261b60398ce532dc2c5ab8dfa10159 [file] [log] [blame]
Bryce Leeaf691c02017-03-20 14:20:22 -07001/*
Wale Ogunwale59507092018-10-29 09:00:30 -07002 * Copyright (C) 2018 The Android Open Source Project
Bryce Leeaf691c02017-03-20 14:20:22 -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 Leeaf691c02017-03-20 14:20:22 -070015 */
16
Wale Ogunwale59507092018-10-29 09:00:30 -070017package com.android.server.wm;
Bryce Leeaf691c02017-03-20 14:20:22 -070018
Andrii Kulian6a6c4f12018-07-16 21:23:33 -070019import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
Bryce Lee18d51592017-10-25 10:22:19 -070020import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
21import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070022import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
Bryce Leef3c6a472017-11-14 14:53:06 -080023import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
Wale Ogunwale9dcf9462017-09-19 15:13:01 -070024import static android.view.Display.DEFAULT_DISPLAY;
Riddle Hsub70b36d2018-09-11 21:20:02 +080025import static android.view.DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS;
Andrii Kulian6a6c4f12018-07-16 21:23:33 -070026
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +090027import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
28
Tadashi G. Takaokaa7a66952018-11-16 15:04:21 +090029import static com.android.dx.mockito.inline.extended.ExtendedMockito.any;
30import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyBoolean;
31import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyInt;
32import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyString;
33import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer;
Evan Rosky730f6e82018-12-03 17:40:11 -080034import static com.android.dx.mockito.inline.extended.ExtendedMockito.doCallRealMethod;
Tadashi G. Takaokaa7a66952018-11-16 15:04:21 +090035import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
36import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
37import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
Riddle Hsu43233b72019-04-24 23:55:11 +080038import static com.android.dx.mockito.inline.extended.ExtendedMockito.reset;
Wale Ogunwaleb73f3962018-11-20 07:58:22 -080039import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
Wale Ogunwale59507092018-10-29 09:00:30 -070040import static com.android.server.wm.ActivityStack.REMOVE_TASK_MODE_DESTROYING;
41import static com.android.server.wm.ActivityStackSupervisor.ON_TOP;
Andrii Kulian6a6c4f12018-07-16 21:23:33 -070042
Nicholas Sauerd6b44522019-09-10 20:23:41 -070043import static org.mockito.ArgumentMatchers.eq;
44
Wale Ogunwale906f9c62018-07-23 11:23:44 -070045import android.app.ActivityManagerInternal;
Bryce Lee2b8e0372018-04-05 17:01:37 -070046import android.app.ActivityOptions;
Michal Karpinski15486842019-04-25 17:33:42 +010047import android.app.AppOpsManager;
Bryce Lee0bd8d422018-01-09 09:45:57 -080048import android.app.IApplicationThread;
Bryce Leeaf691c02017-03-20 14:20:22 -070049import android.content.ComponentName;
50import android.content.Context;
51import android.content.Intent;
52import android.content.pm.ActivityInfo;
53import android.content.pm.ApplicationInfo;
Bryce Leeba8f4422017-11-20 12:35:57 -080054import android.content.pm.IPackageManager;
Louis Changf2835df2018-10-17 15:14:45 +080055import android.content.pm.PackageManagerInternal;
Bryce Leeaf691c02017-03-20 14:20:22 -070056import android.content.res.Configuration;
57import android.graphics.Rect;
Wale Ogunwale9dcf9462017-09-19 15:13:01 -070058import android.hardware.display.DisplayManager;
Riddle Hsub70b36d2018-09-11 21:20:02 +080059import android.hardware.display.DisplayManagerGlobal;
Riddle Hsu1abb56b2018-10-18 11:51:17 +080060import android.os.Handler;
Bryce Leeaf691c02017-03-20 14:20:22 -070061import android.os.Looper;
Andrii Kulian6b321512019-01-23 06:37:00 +000062import android.os.PowerManager;
Riddle Hsu1abb56b2018-10-18 11:51:17 +080063import android.os.Process;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -070064import android.os.UserHandle;
Bryce Lee93e7f792017-10-25 15:54:55 -070065import android.service.voice.IVoiceInteractionSession;
Adrian Roos3150dbf2018-03-28 18:06:52 +020066import android.testing.DexmakerShareClassLoaderRule;
Riddle Hsub70b36d2018-09-11 21:20:02 +080067import android.view.Display;
68import android.view.DisplayInfo;
Adrian Roos3150dbf2018-03-28 18:06:52 +020069
Bryce Lee2b8e0372018-04-05 17:01:37 -070070import com.android.internal.app.IVoiceInteractor;
Bryce Leeaf691c02017-03-20 14:20:22 -070071import com.android.server.AttributeCache;
Riddle Hsu1abb56b2018-10-18 11:51:17 +080072import com.android.server.ServiceThread;
Wale Ogunwale59507092018-10-29 09:00:30 -070073import com.android.server.am.ActivityManagerService;
Wale Ogunwaleb73f3962018-11-20 07:58:22 -080074import com.android.server.am.PendingIntentController;
Yunfan Chen279f5582018-12-12 15:24:50 -080075import com.android.server.appop.AppOpsService;
Wale Ogunwaleb73f3962018-11-20 07:58:22 -080076import com.android.server.firewall.IntentFirewall;
Nicholas Sauerd6b44522019-09-10 20:23:41 -070077import com.android.server.pm.UserManagerService;
Hai Zhangf4da9be2019-05-01 13:46:06 +080078import com.android.server.policy.PermissionPolicyInternal;
Louis Changf2835df2018-10-17 15:14:45 +080079import com.android.server.uri.UriGrantsManagerInternal;
Riddle Hsuff9e8282019-04-24 23:55:11 +080080import com.android.server.wm.TaskRecord.TaskRecordFactory;
Garfield Tan26835f02019-02-07 14:38:38 -080081import com.android.server.wm.utils.MockTracker;
Brett Chabota26eda92018-07-23 13:08:30 -070082
Bryce Lee3115bdf2017-04-05 08:39:40 -070083import org.junit.After;
Bryce Leeaf691c02017-03-20 14:20:22 -070084import org.junit.Before;
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +090085import org.junit.BeforeClass;
Louis Changf2835df2018-10-17 15:14:45 +080086import org.junit.Rule;
Louis Changf2835df2018-10-17 15:14:45 +080087import org.mockito.invocation.InvocationOnMock;
Bryce Leeaf691c02017-03-20 14:20:22 -070088
Riddle Hsu1abb56b2018-10-18 11:51:17 +080089import java.io.File;
Andrii Kulian6a6c4f12018-07-16 21:23:33 -070090import java.util.List;
Riddle Hsu609a8e22019-06-27 16:46:29 -060091import java.util.function.Consumer;
Andrii Kulian6a6c4f12018-07-16 21:23:33 -070092
Bryce Leeaf691c02017-03-20 14:20:22 -070093/**
94 * A base class to handle common operations in activity related unit tests.
95 */
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +090096class ActivityTestsBase {
Riddle Hsub70b36d2018-09-11 21:20:02 +080097 private static int sNextDisplayId = DEFAULT_DISPLAY + 1;
Nicholas Sauerd6b44522019-09-10 20:23:41 -070098 private static final int[] TEST_USER_PROFILE_IDS = {};
Riddle Hsub70b36d2018-09-11 21:20:02 +080099
Adrian Roos3150dbf2018-03-28 18:06:52 +0200100 @Rule
101 public final DexmakerShareClassLoaderRule mDexmakerShareClassLoaderRule =
102 new DexmakerShareClassLoaderRule();
103
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900104 final Context mContext = getInstrumentation().getTargetContext();
Riddle Hsu1abb56b2018-10-18 11:51:17 +0800105 final TestInjector mTestInjector = new TestInjector();
Bryce Leeaf691c02017-03-20 14:20:22 -0700106
Riddle Hsub70b36d2018-09-11 21:20:02 +0800107 ActivityTaskManagerService mService;
Wale Ogunwaled32da472018-11-16 07:19:28 -0800108 RootActivityContainer mRootActivityContainer;
Riddle Hsub70b36d2018-09-11 21:20:02 +0800109 ActivityStackSupervisor mSupervisor;
110
Tadashi G. Takaokad7aa79a2019-02-08 17:42:37 +0900111 private MockTracker mMockTracker;
112
Bryce Leefbd263b42018-03-07 10:33:55 -0800113 // Default package name
114 static final String DEFAULT_COMPONENT_PACKAGE_NAME = "com.foo";
115
116 // Default base activity name
117 private static final String DEFAULT_COMPONENT_CLASS_NAME = ".BarActivity";
118
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900119 @BeforeClass
120 public static void setUpOnceBase() {
121 AttributeCache.init(getInstrumentation().getTargetContext());
122 }
123
Bryce Leeaf691c02017-03-20 14:20:22 -0700124 @Before
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900125 public void setUpBase() {
Tadashi G. Takaokad7aa79a2019-02-08 17:42:37 +0900126 mMockTracker = new MockTracker();
127
Riddle Hsu1abb56b2018-10-18 11:51:17 +0800128 mTestInjector.setUp();
Wale Ogunwale976ca472019-01-17 09:55:38 -0800129
130 mService = new TestActivityTaskManagerService(mContext);
131 mSupervisor = mService.mStackSupervisor;
132 mRootActivityContainer = mService.mRootActivityContainer;
Bryce Lee3115bdf2017-04-05 08:39:40 -0700133 }
Bryce Leeaf691c02017-03-20 14:20:22 -0700134
Bryce Lee3115bdf2017-04-05 08:39:40 -0700135 @After
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900136 public void tearDownBase() {
Riddle Hsu1abb56b2018-10-18 11:51:17 +0800137 mTestInjector.tearDown();
Tadashi G. Takaoka5a108b82018-12-13 17:09:12 +0900138 if (mService != null) {
139 mService.setWindowManager(null);
140 mService = null;
141 }
Riddle Hsu43233b72019-04-24 23:55:11 +0800142 if (sMockWindowManagerService != null) {
143 reset(sMockWindowManagerService);
144 }
Tadashi G. Takaokad7aa79a2019-02-08 17:42:37 +0900145
146 mMockTracker.close();
147 mMockTracker = null;
Bryce Leeaf691c02017-03-20 14:20:22 -0700148 }
149
Riddle Hsub70b36d2018-09-11 21:20:02 +0800150 /** Creates a {@link TestActivityDisplay}. */
151 TestActivityDisplay createNewActivityDisplay() {
152 return TestActivityDisplay.create(mSupervisor, sNextDisplayId++);
153 }
154
Garfield Tan891146c2018-10-09 12:14:00 -0700155 TestActivityDisplay createNewActivityDisplay(DisplayInfo info) {
156 return TestActivityDisplay.create(mSupervisor, sNextDisplayId++, info);
157 }
158
Riddle Hsub70b36d2018-09-11 21:20:02 +0800159 /** Creates and adds a {@link TestActivityDisplay} to supervisor at the given position. */
160 TestActivityDisplay addNewActivityDisplayAt(int position) {
161 final TestActivityDisplay display = createNewActivityDisplay();
Wale Ogunwaled32da472018-11-16 07:19:28 -0800162 mRootActivityContainer.addChild(display, position);
Riddle Hsub70b36d2018-09-11 21:20:02 +0800163 return display;
164 }
165
Evan Rosky730f6e82018-12-03 17:40:11 -0800166 /** Creates and adds a {@link TestActivityDisplay} to supervisor at the given position. */
167 TestActivityDisplay addNewActivityDisplayAt(DisplayInfo info, int position) {
168 final TestActivityDisplay display = createNewActivityDisplay(info);
169 mRootActivityContainer.addChild(display, position);
170 return display;
171 }
172
Bryce Lee18d51592017-10-25 10:22:19 -0700173 /**
Riddle Hsuff9e8282019-04-24 23:55:11 +0800174 * Delegates task creation to {@link #TaskBuilder} to avoid the dependency of window hierarchy
175 * when starting activity in unit tests.
176 */
Riddle Hsu609a8e22019-06-27 16:46:29 -0600177 void mockTaskRecordFactory(Consumer<TaskBuilder> taskBuilderSetup) {
178 final TaskBuilder taskBuilder = new TaskBuilder(mSupervisor).setCreateStack(false);
179 if (taskBuilderSetup != null) {
180 taskBuilderSetup.accept(taskBuilder);
181 }
182 final TaskRecord task = taskBuilder.build();
Riddle Hsuff9e8282019-04-24 23:55:11 +0800183 final TaskRecordFactory factory = mock(TaskRecordFactory.class);
184 TaskRecord.setTaskRecordFactory(factory);
185 doReturn(task).when(factory).create(any() /* service */, anyInt() /* taskId */,
186 any() /* info */, any() /* intent */, any() /* voiceSession */,
187 any() /* voiceInteractor */);
188 }
189
Riddle Hsu609a8e22019-06-27 16:46:29 -0600190 void mockTaskRecordFactory() {
191 mockTaskRecordFactory(null /* taskBuilderSetup */);
192 }
193
Riddle Hsuff9e8282019-04-24 23:55:11 +0800194 /**
Bryce Lee18d51592017-10-25 10:22:19 -0700195 * Builder for creating new activities.
196 */
197 protected static class ActivityBuilder {
198 // An id appended to the end of the component name to make it unique
199 private static int sCurrentActivityId = 0;
Bryce Lee9f6affd2017-09-01 09:18:35 -0700200
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700201 private final ActivityTaskManagerService mService;
Bryce Lee18d51592017-10-25 10:22:19 -0700202
203 private ComponentName mComponent;
Louis Chang23df1a62019-01-09 15:10:49 +0800204 private String mTargetActivity;
Bryce Lee18d51592017-10-25 10:22:19 -0700205 private TaskRecord mTaskRecord;
206 private int mUid;
207 private boolean mCreateTask;
208 private ActivityStack mStack;
Bryce Leec961e0a2018-04-13 17:58:02 -0700209 private int mActivityFlags;
Riddle Hsub70b36d2018-09-11 21:20:02 +0800210 private int mLaunchMode;
lumarkaf0629a2019-09-14 19:25:21 +0800211 private int mLaunchedFromPid;
212 private int mLaunchedFromUid;
Bryce Lee18d51592017-10-25 10:22:19 -0700213
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700214 ActivityBuilder(ActivityTaskManagerService service) {
Bryce Lee18d51592017-10-25 10:22:19 -0700215 mService = service;
Bryce Leeaf691c02017-03-20 14:20:22 -0700216 }
217
Bryce Lee18d51592017-10-25 10:22:19 -0700218 ActivityBuilder setComponent(ComponentName component) {
219 mComponent = component;
220 return this;
221 }
222
Louis Chang23df1a62019-01-09 15:10:49 +0800223 ActivityBuilder setTargetActivity(String targetActivity) {
224 mTargetActivity = targetActivity;
225 return this;
226 }
227
Bryce Leead5b8322018-03-08 14:28:52 -0800228 static ComponentName getDefaultComponent() {
229 return ComponentName.createRelative(DEFAULT_COMPONENT_PACKAGE_NAME,
230 DEFAULT_COMPONENT_PACKAGE_NAME);
231 }
232
Bryce Lee18d51592017-10-25 10:22:19 -0700233 ActivityBuilder setTask(TaskRecord task) {
234 mTaskRecord = task;
235 return this;
236 }
237
Bryce Leec961e0a2018-04-13 17:58:02 -0700238 ActivityBuilder setActivityFlags(int flags) {
239 mActivityFlags = flags;
240 return this;
241 }
242
Riddle Hsub70b36d2018-09-11 21:20:02 +0800243 ActivityBuilder setLaunchMode(int launchMode) {
244 mLaunchMode = launchMode;
245 return this;
246 }
247
Bryce Lee18d51592017-10-25 10:22:19 -0700248 ActivityBuilder setStack(ActivityStack stack) {
249 mStack = stack;
250 return this;
251 }
252
253 ActivityBuilder setCreateTask(boolean createTask) {
254 mCreateTask = createTask;
255 return this;
256 }
257
258 ActivityBuilder setUid(int uid) {
259 mUid = uid;
260 return this;
261 }
262
lumarkaf0629a2019-09-14 19:25:21 +0800263 ActivityBuilder setLaunchedFromPid(int pid) {
264 mLaunchedFromPid = pid;
265 return this;
266 }
267
268 ActivityBuilder setLaunchedFromUid(int uid) {
269 mLaunchedFromUid = uid;
270 return this;
271 }
272
Bryce Lee18d51592017-10-25 10:22:19 -0700273 ActivityRecord build() {
274 if (mComponent == null) {
275 final int id = sCurrentActivityId++;
Bryce Leefbd263b42018-03-07 10:33:55 -0800276 mComponent = ComponentName.createRelative(DEFAULT_COMPONENT_PACKAGE_NAME,
277 DEFAULT_COMPONENT_CLASS_NAME + id);
Bryce Lee18d51592017-10-25 10:22:19 -0700278 }
279
280 if (mCreateTask) {
281 mTaskRecord = new TaskBuilder(mService.mStackSupervisor)
282 .setComponent(mComponent)
283 .setStack(mStack).build();
284 }
285
286 Intent intent = new Intent();
287 intent.setComponent(mComponent);
288 final ActivityInfo aInfo = new ActivityInfo();
289 aInfo.applicationInfo = new ApplicationInfo();
290 aInfo.applicationInfo.packageName = mComponent.getPackageName();
291 aInfo.applicationInfo.uid = mUid;
Louis Chang23df1a62019-01-09 15:10:49 +0800292 aInfo.packageName = mComponent.getPackageName();
293 if (mTargetActivity != null) {
294 aInfo.targetActivity = mTargetActivity;
295 }
Bryce Leec961e0a2018-04-13 17:58:02 -0700296 aInfo.flags |= mActivityFlags;
Riddle Hsub70b36d2018-09-11 21:20:02 +0800297 aInfo.launchMode = mLaunchMode;
Bryce Leec961e0a2018-04-13 17:58:02 -0700298
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700299 final ActivityRecord activity = new ActivityRecord(mService, null /* caller */,
lumarkaf0629a2019-09-14 19:25:21 +0800300 mLaunchedFromPid /* launchedFromPid */, mLaunchedFromUid /* launchedFromUid */,
301 null, intent, null, aInfo /*aInfo*/, new Configuration(), null /* resultTo */,
302 null /* resultWho */, 0 /* reqCode */, false /*componentSpecified*/,
303 false /* rootVoiceInteraction */, mService.mStackSupervisor,
304 null /* options */, null /* sourceRecord */);
Yunfan Chend4ef3012018-11-28 21:14:32 -0800305 spyOn(activity);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800306 activity.mAppWindowToken = mock(AppWindowToken.class);
Evan Rosky730f6e82018-12-03 17:40:11 -0800307 doCallRealMethod().when(activity.mAppWindowToken).getOrientationIgnoreVisibility();
308 doCallRealMethod().when(activity.mAppWindowToken)
309 .setOrientation(anyInt(), any(), any());
310 doCallRealMethod().when(activity.mAppWindowToken).setOrientation(anyInt());
Yunfan Chend4ef3012018-11-28 21:14:32 -0800311 doNothing().when(activity).removeWindowContainer();
Garfield Tan0443b372019-01-04 15:00:13 -0800312 doReturn(mock(Configuration.class)).when(activity.mAppWindowToken)
313 .getRequestedOverrideConfiguration();
Bryce Lee18d51592017-10-25 10:22:19 -0700314
315 if (mTaskRecord != null) {
316 mTaskRecord.addActivityToTop(activity);
317 }
318
Andrii Kulianbeadacc2019-05-20 12:18:01 +0000319 final WindowProcessController wpc = new WindowProcessController(mService,
320 mService.mContext.getApplicationInfo(), "name", 12345,
321 UserHandle.getUserId(12345), mock(Object.class),
322 mock(WindowProcessListener.class));
323 wpc.setThread(mock(IApplicationThread.class));
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700324 activity.setProcess(wpc);
Bryce Lee18d51592017-10-25 10:22:19 -0700325 return activity;
326 }
Bryce Leeaf691c02017-03-20 14:20:22 -0700327 }
328
Bryce Lee18d51592017-10-25 10:22:19 -0700329 /**
330 * Builder for creating new tasks.
331 */
332 protected static class TaskBuilder {
Bryce Leefbd263b42018-03-07 10:33:55 -0800333 // Default package name
334 static final String DEFAULT_PACKAGE = "com.bar";
335
Bryce Lee18d51592017-10-25 10:22:19 -0700336 private final ActivityStackSupervisor mSupervisor;
Winson Chung1dbc8112017-09-28 18:05:31 -0700337
Bryce Lee18d51592017-10-25 10:22:19 -0700338 private ComponentName mComponent;
339 private String mPackage;
340 private int mFlags = 0;
Kazuki Takisec2e17bf2018-07-17 17:46:38 +0900341 // Task id 0 is reserved in ARC for the home app.
342 private int mTaskId = 1;
Winson Chung0ec2a352017-10-26 11:38:30 -0700343 private int mUserId = 0;
Bryce Lee93e7f792017-10-25 15:54:55 -0700344 private IVoiceInteractionSession mVoiceSession;
Bryce Lee2b8e0372018-04-05 17:01:37 -0700345 private boolean mCreateStack = true;
Bryce Leeaf691c02017-03-20 14:20:22 -0700346
Bryce Lee18d51592017-10-25 10:22:19 -0700347 private ActivityStack mStack;
Bryce Leeaf691c02017-03-20 14:20:22 -0700348
Bryce Lee18d51592017-10-25 10:22:19 -0700349 TaskBuilder(ActivityStackSupervisor supervisor) {
350 mSupervisor = supervisor;
351 }
Bryce Leeaf691c02017-03-20 14:20:22 -0700352
Bryce Lee18d51592017-10-25 10:22:19 -0700353 TaskBuilder setComponent(ComponentName component) {
354 mComponent = component;
355 return this;
356 }
357
358 TaskBuilder setPackage(String packageName) {
359 mPackage = packageName;
360 return this;
361 }
362
Bryce Lee2b8e0372018-04-05 17:01:37 -0700363 /**
364 * Set to {@code true} by default, set to {@code false} to prevent the task from
365 * automatically creating a parent stack.
366 */
367 TaskBuilder setCreateStack(boolean createStack) {
368 mCreateStack = createStack;
369 return this;
370 }
371
Bryce Lee93e7f792017-10-25 15:54:55 -0700372 TaskBuilder setVoiceSession(IVoiceInteractionSession session) {
373 mVoiceSession = session;
374 return this;
375 }
376
Bryce Lee18d51592017-10-25 10:22:19 -0700377 TaskBuilder setFlags(int flags) {
378 mFlags = flags;
379 return this;
380 }
381
382 TaskBuilder setTaskId(int taskId) {
383 mTaskId = taskId;
384 return this;
385 }
386
Winson Chung0ec2a352017-10-26 11:38:30 -0700387 TaskBuilder setUserId(int userId) {
388 mUserId = userId;
389 return this;
390 }
391
Bryce Lee18d51592017-10-25 10:22:19 -0700392 TaskBuilder setStack(ActivityStack stack) {
393 mStack = stack;
394 return this;
395 }
396
397 TaskRecord build() {
Bryce Lee2b8e0372018-04-05 17:01:37 -0700398 if (mStack == null && mCreateStack) {
Wale Ogunwaled32da472018-11-16 07:19:28 -0800399 mStack = mSupervisor.mRootActivityContainer.getDefaultDisplay().createStack(
Bryce Lee18d51592017-10-25 10:22:19 -0700400 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
401 }
402
403 final ActivityInfo aInfo = new ActivityInfo();
404 aInfo.applicationInfo = new ApplicationInfo();
405 aInfo.applicationInfo.packageName = mPackage;
406
407 Intent intent = new Intent();
Bryce Leefbd263b42018-03-07 10:33:55 -0800408 if (mComponent == null) {
409 mComponent = ComponentName.createRelative(DEFAULT_COMPONENT_PACKAGE_NAME,
410 DEFAULT_COMPONENT_CLASS_NAME);
411 }
412
Bryce Lee18d51592017-10-25 10:22:19 -0700413 intent.setComponent(mComponent);
414 intent.setFlags(mFlags);
415
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700416 final TestTaskRecord task = new TestTaskRecord(mSupervisor.mService, mTaskId, aInfo,
Bryce Lee93e7f792017-10-25 15:54:55 -0700417 intent /*intent*/, mVoiceSession, null /*_voiceInteractor*/);
Winson Chung0ec2a352017-10-26 11:38:30 -0700418 task.userId = mUserId;
Bryce Lee2b8e0372018-04-05 17:01:37 -0700419
420 if (mStack != null) {
Andrii Kulian6a6c4f12018-07-16 21:23:33 -0700421 mStack.moveToFront("test");
Bryce Lee2b8e0372018-04-05 17:01:37 -0700422 mStack.addTask(task, true, "creating test task");
423 task.setStack(mStack);
Yunfan Chen0e7aff92018-12-05 16:35:32 -0800424 task.setTask();
Yunfan Chen279f5582018-12-12 15:24:50 -0800425 mStack.getTaskStack().addChild(task.mTask, 0);
Bryce Lee2b8e0372018-04-05 17:01:37 -0700426 }
427
Winson Chung0ec2a352017-10-26 11:38:30 -0700428 task.touchActiveTime();
Bryce Lee18d51592017-10-25 10:22:19 -0700429
430 return task;
431 }
Bryce Lee2b8e0372018-04-05 17:01:37 -0700432
433 private static class TestTaskRecord extends TaskRecord {
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900434 TestTaskRecord(ActivityTaskManagerService service, int taskId, ActivityInfo info,
435 Intent intent, IVoiceInteractionSession voiceSession,
436 IVoiceInteractor voiceInteractor) {
437 super(service, taskId, info, intent, voiceSession, voiceInteractor);
Bryce Lee2b8e0372018-04-05 17:01:37 -0700438 }
439
440 @Override
Yunfan Chen0e7aff92018-12-05 16:35:32 -0800441 void createTask(boolean onTop, boolean showForAllUsers) {
442 setTask();
Bryce Lee2b8e0372018-04-05 17:01:37 -0700443 }
444
Evan Rosky730f6e82018-12-03 17:40:11 -0800445 void setTask() {
446 Task mockTask = mock(Task.class);
447 mockTask.mTaskRecord = this;
448 doCallRealMethod().when(mockTask).onDescendantOrientationChanged(any(), any());
Yunfan Chen0e7aff92018-12-05 16:35:32 -0800449 setTask(mock(Task.class));
Bryce Lee2b8e0372018-04-05 17:01:37 -0700450 }
451 }
Bryce Leeaf691c02017-03-20 14:20:22 -0700452 }
453
Wale Ogunwaleb73f3962018-11-20 07:58:22 -0800454 protected class TestActivityTaskManagerService extends ActivityTaskManagerService {
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700455 private PackageManagerInternal mPmInternal;
Hai Zhangf4da9be2019-05-01 13:46:06 +0800456 private PermissionPolicyInternal mPermissionPolicyInternal;
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700457
Louis Chang89f43fc2018-10-05 10:59:14 +0800458 // ActivityStackSupervisor may be created more than once while setting up AMS and ATMS.
459 // We keep the reference in order to prevent creating it twice.
Wale Ogunwaleb73f3962018-11-20 07:58:22 -0800460 ActivityStackSupervisor mTestStackSupervisor;
Louis Chang89f43fc2018-10-05 10:59:14 +0800461
Wale Ogunwaled32da472018-11-16 07:19:28 -0800462 ActivityDisplay mDefaultDisplay;
Michal Karpinski15486842019-04-25 17:33:42 +0100463 AppOpsService mAppOpsService;
Wale Ogunwaled32da472018-11-16 07:19:28 -0800464
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700465 TestActivityTaskManagerService(Context context) {
466 super(context);
Wale Ogunwaleb73f3962018-11-20 07:58:22 -0800467 spyOn(this);
468
469 mUgmInternal = mock(UriGrantsManagerInternal.class);
Michal Karpinski15486842019-04-25 17:33:42 +0100470 mAppOpsService = mock(AppOpsService.class);
471
472 // Make sure permission checks aren't overridden.
473 doReturn(AppOpsManager.MODE_DEFAULT)
474 .when(mAppOpsService).noteOperation(anyInt(), anyInt(), anyString());
Wale Ogunwaleb73f3962018-11-20 07:58:22 -0800475
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700476 mSupportsMultiWindow = true;
477 mSupportsMultiDisplay = true;
478 mSupportsSplitScreenMultiWindow = true;
479 mSupportsFreeformWindowManagement = true;
480 mSupportsPictureInPicture = true;
Wale Ogunwaleb73f3962018-11-20 07:58:22 -0800481
482 final TestActivityManagerService am =
483 new TestActivityManagerService(mTestInjector, this);
484
Wale Ogunwaleb73f3962018-11-20 07:58:22 -0800485 spyOn(getLifecycleManager());
486 spyOn(getLockTaskController());
487 doReturn(mock(IPackageManager.class)).when(this).getPackageManager();
Michal Karpinski8596ded2018-11-14 14:43:48 +0000488 // allow background activity starts by default
489 doReturn(true).when(this).isBackgroundActivityStartsEnabled();
Andrii Kulian6b321512019-01-23 06:37:00 +0000490 doNothing().when(this).updateCpuStats();
Nicholas Sauerd6b44522019-09-10 20:23:41 -0700491
492 // UserManager
493 final UserManagerService ums = mock(UserManagerService.class);
494 doReturn(ums).when(this).getUserManager();
495 doReturn(TEST_USER_PROFILE_IDS).when(ums).getProfileIds(anyInt(), eq(true));
Wale Ogunwaleb73f3962018-11-20 07:58:22 -0800496 }
497
Riddle Hsud93a6c42018-11-29 21:50:06 +0800498 void setup(IntentFirewall intentFirewall, PendingIntentController intentController,
499 ActivityManagerInternal amInternal, WindowManagerService wm, Looper looper) {
Wale Ogunwaleb73f3962018-11-20 07:58:22 -0800500 mAmInternal = amInternal;
Riddle Hsud93a6c42018-11-29 21:50:06 +0800501 initialize(intentFirewall, intentController, looper);
Wale Ogunwaled32da472018-11-16 07:19:28 -0800502 initRootActivityContainerMocks(wm);
Wale Ogunwaleb73f3962018-11-20 07:58:22 -0800503 setWindowManager(wm);
Wale Ogunwale3a256e62018-12-06 14:41:18 -0800504 createDefaultDisplay();
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700505 }
506
Wale Ogunwaled32da472018-11-16 07:19:28 -0800507 void initRootActivityContainerMocks(WindowManagerService wm) {
508 spyOn(mRootActivityContainer);
Wale Ogunwale31acb3f2018-11-20 15:23:55 -0800509 mRootActivityContainer.setWindowContainer(mock(RootWindowContainer.class));
Wale Ogunwaled32da472018-11-16 07:19:28 -0800510 mRootActivityContainer.mWindowManager = wm;
511 mRootActivityContainer.mDisplayManager =
512 (DisplayManager) mContext.getSystemService(Context.DISPLAY_SERVICE);
513 doNothing().when(mRootActivityContainer).setWindowManager(any());
514 // Invoked during {@link ActivityStack} creation.
515 doNothing().when(mRootActivityContainer).updateUIDsPresentOnDisplay();
516 // Always keep things awake.
517 doReturn(true).when(mRootActivityContainer).hasAwakeDisplay();
518 // Called when moving activity to pinned stack.
519 doNothing().when(mRootActivityContainer).ensureActivitiesVisible(any(), anyInt(),
520 anyBoolean());
Wale Ogunwale3a256e62018-12-06 14:41:18 -0800521 }
Wale Ogunwaled32da472018-11-16 07:19:28 -0800522
Wale Ogunwale3a256e62018-12-06 14:41:18 -0800523 void createDefaultDisplay() {
Wale Ogunwaled32da472018-11-16 07:19:28 -0800524 // Create a default display and put a home stack on it so that we'll always have
525 // something focusable.
526 mDefaultDisplay = TestActivityDisplay.create(mStackSupervisor, DEFAULT_DISPLAY);
527 spyOn(mDefaultDisplay);
528 mRootActivityContainer.addChild(mDefaultDisplay, ActivityDisplay.POSITION_TOP);
529 mDefaultDisplay.createStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, ON_TOP);
530 final TaskRecord task = new TaskBuilder(mStackSupervisor)
531 .setStack(mDefaultDisplay.getHomeStack()).build();
532 new ActivityBuilder(this).setTask(task).build();
533
534 doReturn(mDefaultDisplay).when(mRootActivityContainer).getDefaultDisplay();
535 }
536
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700537 @Override
538 int handleIncomingUser(int callingPid, int callingUid, int userId, String name) {
539 return userId;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700540 }
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700541
542 @Override
Michal Karpinski15486842019-04-25 17:33:42 +0100543 AppOpsService getAppOpsService() {
544 return mAppOpsService;
545 }
546
547 @Override
Riddle Hsuaaef7312019-01-24 19:00:58 +0800548 void updateCpuStats() {
549 }
550
551 @Override
Hui Yu03d12402018-12-06 18:00:37 -0800552 void updateBatteryStats(ActivityRecord component, boolean resumed) {
553 }
554
555 @Override
556 void updateActivityUsageStats(ActivityRecord activity, int event) {
Wale Ogunwale53783742018-09-16 10:21:51 -0700557 }
558
559 @Override
Wale Ogunwaleb73f3962018-11-20 07:58:22 -0800560 protected ActivityStackSupervisor createStackSupervisor() {
Louis Chang89f43fc2018-10-05 10:59:14 +0800561 if (mTestStackSupervisor == null) {
Wale Ogunwaleb73f3962018-11-20 07:58:22 -0800562 mTestStackSupervisor = new TestActivityStackSupervisor(this, mH.getLooper());
Louis Chang89f43fc2018-10-05 10:59:14 +0800563 }
564 return mTestStackSupervisor;
Bryce Lee2a3cc462017-10-27 10:57:35 -0700565 }
566
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900567 @Override
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700568 PackageManagerInternal getPackageManagerInternalLocked() {
569 if (mPmInternal == null) {
570 mPmInternal = mock(PackageManagerInternal.class);
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900571 doReturn(false)
572 .when(mPmInternal)
573 .isPermissionsReviewRequired(anyString(), anyInt());
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700574 }
575 return mPmInternal;
576 }
Hai Zhangf4da9be2019-05-01 13:46:06 +0800577
578 @Override
579 PermissionPolicyInternal getPermissionPolicyInternal() {
580 if (mPermissionPolicyInternal == null) {
581 mPermissionPolicyInternal = mock(PermissionPolicyInternal.class);
582 doReturn(true).when(mPermissionPolicyInternal).checkStartActivity(any(), anyInt(),
583 any());
584 }
585 return mPermissionPolicyInternal;
586 }
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700587 }
588
Riddle Hsu1abb56b2018-10-18 11:51:17 +0800589 private static class TestInjector extends ActivityManagerService.Injector {
590 private ServiceThread mHandlerThread;
591
592 @Override
593 public Context getContext() {
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900594 return getInstrumentation().getTargetContext();
Riddle Hsu1abb56b2018-10-18 11:51:17 +0800595 }
596
597 @Override
598 public AppOpsService getAppOpsService(File file, Handler handler) {
599 return null;
600 }
601
602 @Override
603 public Handler getUiHandler(ActivityManagerService service) {
604 return mHandlerThread.getThreadHandler();
605 }
606
607 @Override
608 public boolean isNetworkRestrictedForUid(int uid) {
609 return false;
610 }
611
612 void setUp() {
613 mHandlerThread = new ServiceThread("ActivityTestsThread",
614 Process.THREAD_PRIORITY_DEFAULT, true /* allowIo */);
615 mHandlerThread.start();
616 }
617
618 void tearDown() {
Riddle Hsue2e5ee12019-06-11 23:44:39 +0800619 // Make sure there are no running messages and then quit the thread so the next test
620 // won't be affected.
621 mHandlerThread.getThreadHandler().runWithScissors(mHandlerThread::quit,
622 0 /* timeout */);
Riddle Hsu1abb56b2018-10-18 11:51:17 +0800623 }
624 }
625
Wale Ogunwaleb73f3962018-11-20 07:58:22 -0800626 // TODO: Replace this with a mock object since we are no longer in AMS package.
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700627 /**
628 * An {@link ActivityManagerService} subclass which provides a test
629 * {@link ActivityStackSupervisor}.
630 */
Wale Ogunwaleb73f3962018-11-20 07:58:22 -0800631 class TestActivityManagerService extends ActivityManagerService {
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700632
Wale Ogunwaleb73f3962018-11-20 07:58:22 -0800633 TestActivityManagerService(TestInjector testInjector, TestActivityTaskManagerService atm) {
Riddle Hsu1abb56b2018-10-18 11:51:17 +0800634 super(testInjector, testInjector.mHandlerThread);
Wale Ogunwaleb73f3962018-11-20 07:58:22 -0800635 spyOn(this);
Bryce Lee29a649d2017-08-18 13:52:31 -0700636
Wale Ogunwaleb73f3962018-11-20 07:58:22 -0800637 mWindowManager = prepareMockWindowManager();
638 mUgmInternal = mock(UriGrantsManagerInternal.class);
639
Riddle Hsud93a6c42018-11-29 21:50:06 +0800640 atm.setup(mIntentFirewall, mPendingIntentController, new LocalService(), mWindowManager,
641 testInjector.mHandlerThread.getLooper());
Wale Ogunwaleb73f3962018-11-20 07:58:22 -0800642
643 mActivityTaskManager = atm;
644 mAtmInternal = atm.mInternal;
645
646 doReturn(mock(IPackageManager.class)).when(this).getPackageManager();
647 PackageManagerInternal mockPackageManager = mock(PackageManagerInternal.class);
648 doReturn(mockPackageManager).when(this).getPackageManagerInternalLocked();
649 doReturn(null).when(mockPackageManager).getDefaultHomeActivity(anyInt());
650 doNothing().when(this).grantEphemeralAccessLocked(anyInt(), any(), anyInt(), anyInt());
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700651 }
Bryce Leeaf691c02017-03-20 14:20:22 -0700652 }
653
654 /**
655 * An {@link ActivityStackSupervisor} which stubs out certain methods that depend on
656 * setup not available in the test environment. Also specifies an injector for
657 */
Wale Ogunwaleb73f3962018-11-20 07:58:22 -0800658 protected class TestActivityStackSupervisor extends ActivityStackSupervisor {
Bryce Lee459c0622018-03-19 11:04:01 -0700659 private KeyguardController mKeyguardController;
Bryce Lee943ebe72017-05-04 10:19:07 -0700660
Wale Ogunwaleb73f3962018-11-20 07:58:22 -0800661 TestActivityStackSupervisor(ActivityTaskManagerService service, Looper looper) {
Bryce Leeaf691c02017-03-20 14:20:22 -0700662 super(service, looper);
Wale Ogunwaleb73f3962018-11-20 07:58:22 -0800663 spyOn(this);
Bryce Lee04ab3462017-04-10 15:06:33 -0700664 mWindowManager = prepareMockWindowManager();
Bryce Lee459c0622018-03-19 11:04:01 -0700665 mKeyguardController = mock(KeyguardController.class);
Wale Ogunwaleb73f3962018-11-20 07:58:22 -0800666
Riddle Hsue2e5ee12019-06-11 23:44:39 +0800667 // Do not schedule idle that may touch methods outside the scope of the test.
668 doNothing().when(this).scheduleIdleLocked();
Wale Ogunwaleb73f3962018-11-20 07:58:22 -0800669 doNothing().when(this).scheduleIdleTimeoutLocked(any());
670 // unit test version does not handle launch wake lock
671 doNothing().when(this).acquireLaunchWakelock();
672 doReturn(mKeyguardController).when(this).getKeyguardController();
673
Andrii Kulianc598b2d2019-02-07 17:16:38 -0800674 mLaunchingActivityWakeLock = mock(PowerManager.WakeLock.class);
Andrii Kulian6b321512019-01-23 06:37:00 +0000675
Wale Ogunwaleb73f3962018-11-20 07:58:22 -0800676 initialize();
Bryce Lee2a3cc462017-10-27 10:57:35 -0700677 }
678
679 @Override
Bryce Lee459c0622018-03-19 11:04:01 -0700680 public KeyguardController getKeyguardController() {
681 return mKeyguardController;
682 }
683
684 @Override
Wale Ogunwale31913b52018-10-13 08:29:31 -0700685 void setWindowManager(WindowManagerService wm) {
686 mWindowManager = wm;
687 }
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700688 }
689
Winson Chung59a47ded2018-01-25 17:46:06 +0000690 protected static class TestActivityDisplay extends ActivityDisplay {
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700691 private final ActivityStackSupervisor mSupervisor;
Riddle Hsub70b36d2018-09-11 21:20:02 +0800692
693 static TestActivityDisplay create(ActivityStackSupervisor supervisor, int displayId) {
Garfield Tan891146c2018-10-09 12:14:00 -0700694 return create(supervisor, displayId, new DisplayInfo());
695 }
696
697 static TestActivityDisplay create(ActivityStackSupervisor supervisor, int displayId,
698 DisplayInfo info) {
Riddle Hsub70b36d2018-09-11 21:20:02 +0800699 if (displayId == DEFAULT_DISPLAY) {
700 return new TestActivityDisplay(supervisor,
Wale Ogunwaled32da472018-11-16 07:19:28 -0800701 supervisor.mRootActivityContainer.mDisplayManager.getDisplay(displayId));
Riddle Hsub70b36d2018-09-11 21:20:02 +0800702 }
703 final Display display = new Display(DisplayManagerGlobal.getInstance(), displayId,
Garfield Tan891146c2018-10-09 12:14:00 -0700704 info, DEFAULT_DISPLAY_ADJUSTMENTS);
Riddle Hsub70b36d2018-09-11 21:20:02 +0800705 return new TestActivityDisplay(supervisor, display);
706 }
707
708 TestActivityDisplay(ActivityStackSupervisor supervisor, Display display) {
Wale Ogunwaled32da472018-11-16 07:19:28 -0800709 super(supervisor.mService.mRootActivityContainer, display);
Evan Rosky10475742018-09-05 19:02:48 -0700710 // Normally this comes from display-properties as exposed by WM. Without that, just
711 // hard-code to FULLSCREEN for tests.
712 setWindowingMode(WINDOWING_MODE_FULLSCREEN);
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700713 mSupervisor = supervisor;
Andrii Kulianb1cdb102017-07-13 15:33:06 -0700714 }
715
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900716 @SuppressWarnings("TypeParameterUnusedInFormals")
Andrii Kulianb1cdb102017-07-13 15:33:06 -0700717 @Override
Yunfan Chen279f5582018-12-12 15:24:50 -0800718 ActivityStack createStackUnchecked(int windowingMode, int activityType,
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700719 int stackId, boolean onTop) {
Wale Ogunwaled32da472018-11-16 07:19:28 -0800720 return new StackBuilder(mSupervisor.mRootActivityContainer).setDisplay(this)
Louis Changf2835df2018-10-17 15:14:45 +0800721 .setWindowingMode(windowingMode).setActivityType(activityType)
722 .setStackId(stackId).setOnTop(onTop).setCreateActivity(false).build();
Bryce Lee04ab3462017-04-10 15:06:33 -0700723 }
Winson Chung59a47ded2018-01-25 17:46:06 +0000724
725 @Override
Wale Ogunwale3a256e62018-12-06 14:41:18 -0800726 protected DisplayContent createDisplayContent() {
Tadashi G. Takaokad7aa79a2019-02-08 17:42:37 +0900727 final DisplayContent displayContent = mock(DisplayContent.class);
728 DockedStackDividerController divider = mock(DockedStackDividerController.class);
729 doReturn(divider).when(displayContent).getDockedDividerController();
730 return displayContent;
Winson Chung59a47ded2018-01-25 17:46:06 +0000731 }
Andrii Kulian6a6c4f12018-07-16 21:23:33 -0700732
733 void removeAllTasks() {
734 for (int i = 0; i < getChildCount(); i++) {
735 final ActivityStack stack = getChildAt(i);
736 for (TaskRecord task : (List<TaskRecord>) stack.getAllTasks()) {
737 stack.removeTask(task, "removeAllTasks", REMOVE_TASK_MODE_DESTROYING);
738 }
739 }
740 }
Bryce Leeaf691c02017-03-20 14:20:22 -0700741 }
742
Tadashi G. Takaoka5a108b82018-12-13 17:09:12 +0900743 private static WindowManagerService sMockWindowManagerService;
744
Bryce Lee04ab3462017-04-10 15:06:33 -0700745 private static WindowManagerService prepareMockWindowManager() {
Garfield Tan26835f02019-02-07 14:38:38 -0800746 if (sMockWindowManagerService == null) {
747 sMockWindowManagerService = mock(WindowManagerService.class);
Tadashi G. Takaoka5a108b82018-12-13 17:09:12 +0900748 }
749
Garfield Tan26835f02019-02-07 14:38:38 -0800750 sMockWindowManagerService.mRoot = mock(RootWindowContainer.class);
Bryce Lee04ab3462017-04-10 15:06:33 -0700751
752 doAnswer((InvocationOnMock invocationOnMock) -> {
753 final Runnable runnable = invocationOnMock.<Runnable>getArgument(0);
754 if (runnable != null) {
755 runnable.run();
756 }
757 return null;
Garfield Tan26835f02019-02-07 14:38:38 -0800758 }).when(sMockWindowManagerService).inSurfaceTransaction(any());
Bryce Lee04ab3462017-04-10 15:06:33 -0700759
Garfield Tan26835f02019-02-07 14:38:38 -0800760 return sMockWindowManagerService;
Bryce Lee04ab3462017-04-10 15:06:33 -0700761 }
762
Bryce Leeaf691c02017-03-20 14:20:22 -0700763 /**
Bryce Lee2b8e0372018-04-05 17:01:37 -0700764 * Overridden {@link ActivityStack} that tracks test metrics, such as the number of times a
Bryce Leeaf691c02017-03-20 14:20:22 -0700765 * method is called. Note that its functionality depends on the implementations of the
766 * construction arguments.
767 */
Yunfan Chen279f5582018-12-12 15:24:50 -0800768 protected static class TestActivityStack
769 extends ActivityStack {
Bryce Leeaf691c02017-03-20 14:20:22 -0700770 private int mOnActivityRemovedFromStackCount = 0;
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700771
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700772 static final int IS_TRANSLUCENT_UNSET = 0;
773 static final int IS_TRANSLUCENT_FALSE = 1;
774 static final int IS_TRANSLUCENT_TRUE = 2;
775 private int mIsTranslucent = IS_TRANSLUCENT_UNSET;
776
Wale Ogunwale30e441d2017-11-09 08:28:45 -0800777 static final int SUPPORTS_SPLIT_SCREEN_UNSET = 0;
778 static final int SUPPORTS_SPLIT_SCREEN_FALSE = 1;
779 static final int SUPPORTS_SPLIT_SCREEN_TRUE = 2;
780 private int mSupportsSplitScreen = SUPPORTS_SPLIT_SCREEN_UNSET;
781
Wale Ogunwale9dcf9462017-09-19 15:13:01 -0700782 TestActivityStack(ActivityDisplay display, int stackId, ActivityStackSupervisor supervisor,
Louis Changf2835df2018-10-17 15:14:45 +0800783 int windowingMode, int activityType, boolean onTop, boolean createActivity) {
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700784 super(display, stackId, supervisor, windowingMode, activityType, onTop);
Louis Changf2835df2018-10-17 15:14:45 +0800785 if (createActivity) {
786 new ActivityBuilder(mService).setCreateTask(true).setStack(this).build();
787 if (onTop) {
788 // We move the task to front again in order to regain focus after activity
789 // added to the stack. Or {@link ActivityDisplay#mPreferredTopFocusableStack}
790 // could be other stacks (e.g. home stack).
791 moveToFront("createActivityStack");
792 } else {
793 moveToBack("createActivityStack", null);
794 }
795 }
Bryce Leeaf691c02017-03-20 14:20:22 -0700796 }
797
798 @Override
799 void onActivityRemovedFromStack(ActivityRecord r) {
800 mOnActivityRemovedFromStackCount++;
801 super.onActivityRemovedFromStack(r);
802 }
803
804 // Returns the number of times {@link #onActivityRemovedFromStack} has been called
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700805 int onActivityRemovedFromStackInvocationCount() {
Bryce Leeaf691c02017-03-20 14:20:22 -0700806 return mOnActivityRemovedFromStackCount;
807 }
808
809 @Override
Yunfan Chen279f5582018-12-12 15:24:50 -0800810 protected void createTaskStack(int displayId, boolean onTop, Rect outBounds) {
Tadashi G. Takaokad7aa79a2019-02-08 17:42:37 +0900811 mTaskStack = mock(TaskStack.class);
Bryce Leef3c6a472017-11-14 14:53:06 -0800812
813 // Primary pinned stacks require a non-empty out bounds to be set or else all tasks
814 // will be moved to the full screen stack.
815 if (getWindowingMode() == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
816 outBounds.set(0, 0, 100, 100);
817 }
Bryce Leeaf691c02017-03-20 14:20:22 -0700818 }
819
820 @Override
Yunfan Chen279f5582018-12-12 15:24:50 -0800821 TaskStack getTaskStack() {
822 return mTaskStack;
Bryce Leeaf691c02017-03-20 14:20:22 -0700823 }
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700824
825 void setIsTranslucent(boolean isTranslucent) {
826 mIsTranslucent = isTranslucent ? IS_TRANSLUCENT_TRUE : IS_TRANSLUCENT_FALSE;
827 }
828
829 @Override
Wale Ogunwale66e16852017-10-19 13:35:52 -0700830 boolean isStackTranslucent(ActivityRecord starting) {
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700831 switch (mIsTranslucent) {
832 case IS_TRANSLUCENT_TRUE:
833 return true;
834 case IS_TRANSLUCENT_FALSE:
835 return false;
836 case IS_TRANSLUCENT_UNSET:
837 default:
Wale Ogunwale66e16852017-10-19 13:35:52 -0700838 return super.isStackTranslucent(starting);
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700839 }
840 }
Wale Ogunwale30e441d2017-11-09 08:28:45 -0800841
842 void setSupportsSplitScreen(boolean supportsSplitScreen) {
843 mSupportsSplitScreen = supportsSplitScreen
844 ? SUPPORTS_SPLIT_SCREEN_TRUE : SUPPORTS_SPLIT_SCREEN_FALSE;
845 }
846
847 @Override
848 public boolean supportsSplitScreenWindowingMode() {
849 switch (mSupportsSplitScreen) {
850 case SUPPORTS_SPLIT_SCREEN_TRUE:
851 return true;
852 case SUPPORTS_SPLIT_SCREEN_FALSE:
853 return false;
854 case SUPPORTS_SPLIT_SCREEN_UNSET:
855 default:
856 return super.supportsSplitScreenWindowingMode();
857 }
858 }
Bryce Lee2b8e0372018-04-05 17:01:37 -0700859
860 @Override
861 void startActivityLocked(ActivityRecord r, ActivityRecord focusedTopActivity,
862 boolean newTask, boolean keepCurTransition,
863 ActivityOptions options) {
864 }
Bryce Leeaf691c02017-03-20 14:20:22 -0700865 }
Louis Changf2835df2018-10-17 15:14:45 +0800866
Wale Ogunwaled32da472018-11-16 07:19:28 -0800867 static class StackBuilder {
868 private final RootActivityContainer mRootActivityContainer;
Louis Changf2835df2018-10-17 15:14:45 +0800869 private ActivityDisplay mDisplay;
870 private int mStackId = -1;
871 private int mWindowingMode = WINDOWING_MODE_FULLSCREEN;
872 private int mActivityType = ACTIVITY_TYPE_STANDARD;
873 private boolean mOnTop = true;
874 private boolean mCreateActivity = true;
875
Wale Ogunwaled32da472018-11-16 07:19:28 -0800876 StackBuilder(RootActivityContainer root) {
877 mRootActivityContainer = root;
878 mDisplay = mRootActivityContainer.getDefaultDisplay();
Louis Changf2835df2018-10-17 15:14:45 +0800879 }
880
881 StackBuilder setWindowingMode(int windowingMode) {
882 mWindowingMode = windowingMode;
883 return this;
884 }
885
886 StackBuilder setActivityType(int activityType) {
887 mActivityType = activityType;
888 return this;
889 }
890
891 StackBuilder setStackId(int stackId) {
892 mStackId = stackId;
893 return this;
894 }
895
896 StackBuilder setDisplay(ActivityDisplay display) {
897 mDisplay = display;
898 return this;
899 }
900
901 StackBuilder setOnTop(boolean onTop) {
902 mOnTop = onTop;
903 return this;
904 }
905
906 StackBuilder setCreateActivity(boolean createActivity) {
907 mCreateActivity = createActivity;
908 return this;
909 }
910
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900911 @SuppressWarnings("TypeParameterUnusedInFormals")
Yunfan Chen279f5582018-12-12 15:24:50 -0800912 ActivityStack build() {
Louis Changf2835df2018-10-17 15:14:45 +0800913 final int stackId = mStackId >= 0 ? mStackId : mDisplay.getNextStackId();
914 if (mWindowingMode == WINDOWING_MODE_PINNED) {
Yunfan Chen279f5582018-12-12 15:24:50 -0800915 return new ActivityStack(mDisplay, stackId, mRootActivityContainer.mStackSupervisor,
916 mWindowingMode, ACTIVITY_TYPE_STANDARD, mOnTop) {
Louis Changf2835df2018-10-17 15:14:45 +0800917 @Override
918 Rect getDefaultPictureInPictureBounds(float aspectRatio) {
919 return new Rect(50, 50, 100, 100);
920 }
921
922 @Override
Yunfan Chen279f5582018-12-12 15:24:50 -0800923 void createTaskStack(int displayId, boolean onTop, Rect outBounds) {
924 mTaskStack = mock(TaskStack.class);
Louis Changf2835df2018-10-17 15:14:45 +0800925 }
926 };
927 } else {
Yunfan Chen279f5582018-12-12 15:24:50 -0800928 return new TestActivityStack(mDisplay, stackId,
Wale Ogunwaled32da472018-11-16 07:19:28 -0800929 mRootActivityContainer.mStackSupervisor, mWindowingMode,
Louis Changf2835df2018-10-17 15:14:45 +0800930 mActivityType, mOnTop, mCreateActivity);
931 }
932 }
933
934 }
Bryce Leeaf691c02017-03-20 14:20:22 -0700935}