blob: ecf3acd32d4f9106a2544ea063fdb22521bd94d7 [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
Wale Ogunwale906f9c62018-07-23 11:23:44 -070043import android.app.ActivityManagerInternal;
Bryce Lee2b8e0372018-04-05 17:01:37 -070044import android.app.ActivityOptions;
Michal Karpinski15486842019-04-25 17:33:42 +010045import android.app.AppOpsManager;
Bryce Lee0bd8d422018-01-09 09:45:57 -080046import android.app.IApplicationThread;
Bryce Leeaf691c02017-03-20 14:20:22 -070047import android.content.ComponentName;
48import android.content.Context;
49import android.content.Intent;
50import android.content.pm.ActivityInfo;
51import android.content.pm.ApplicationInfo;
Bryce Leeba8f4422017-11-20 12:35:57 -080052import android.content.pm.IPackageManager;
Louis Changf2835df2018-10-17 15:14:45 +080053import android.content.pm.PackageManagerInternal;
Bryce Leeaf691c02017-03-20 14:20:22 -070054import android.content.res.Configuration;
55import android.graphics.Rect;
Wale Ogunwale9dcf9462017-09-19 15:13:01 -070056import android.hardware.display.DisplayManager;
Riddle Hsub70b36d2018-09-11 21:20:02 +080057import android.hardware.display.DisplayManagerGlobal;
Riddle Hsu1abb56b2018-10-18 11:51:17 +080058import android.os.Handler;
Bryce Leeaf691c02017-03-20 14:20:22 -070059import android.os.Looper;
Andrii Kulian6b321512019-01-23 06:37:00 +000060import android.os.PowerManager;
Riddle Hsu1abb56b2018-10-18 11:51:17 +080061import android.os.Process;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -070062import android.os.UserHandle;
Bryce Lee93e7f792017-10-25 15:54:55 -070063import android.service.voice.IVoiceInteractionSession;
Adrian Roos3150dbf2018-03-28 18:06:52 +020064import android.testing.DexmakerShareClassLoaderRule;
Riddle Hsub70b36d2018-09-11 21:20:02 +080065import android.view.Display;
66import android.view.DisplayInfo;
Adrian Roos3150dbf2018-03-28 18:06:52 +020067
Bryce Lee2b8e0372018-04-05 17:01:37 -070068import com.android.internal.app.IVoiceInteractor;
Bryce Leeaf691c02017-03-20 14:20:22 -070069import com.android.server.AttributeCache;
Riddle Hsu1abb56b2018-10-18 11:51:17 +080070import com.android.server.ServiceThread;
Wale Ogunwale59507092018-10-29 09:00:30 -070071import com.android.server.am.ActivityManagerService;
Wale Ogunwaleb73f3962018-11-20 07:58:22 -080072import com.android.server.am.PendingIntentController;
Yunfan Chen279f5582018-12-12 15:24:50 -080073import com.android.server.appop.AppOpsService;
Wale Ogunwaleb73f3962018-11-20 07:58:22 -080074import com.android.server.firewall.IntentFirewall;
Hai Zhangf4da9be2019-05-01 13:46:06 +080075import com.android.server.policy.PermissionPolicyInternal;
Louis Changf2835df2018-10-17 15:14:45 +080076import com.android.server.uri.UriGrantsManagerInternal;
Riddle Hsuff9e8282019-04-24 23:55:11 +080077import com.android.server.wm.TaskRecord.TaskRecordFactory;
Garfield Tan26835f02019-02-07 14:38:38 -080078import com.android.server.wm.utils.MockTracker;
Brett Chabota26eda92018-07-23 13:08:30 -070079
Bryce Lee3115bdf2017-04-05 08:39:40 -070080import org.junit.After;
Bryce Leeaf691c02017-03-20 14:20:22 -070081import org.junit.Before;
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +090082import org.junit.BeforeClass;
Louis Changf2835df2018-10-17 15:14:45 +080083import org.junit.Rule;
Louis Changf2835df2018-10-17 15:14:45 +080084import org.mockito.invocation.InvocationOnMock;
Bryce Leeaf691c02017-03-20 14:20:22 -070085
Riddle Hsu1abb56b2018-10-18 11:51:17 +080086import java.io.File;
Andrii Kulian6a6c4f12018-07-16 21:23:33 -070087import java.util.List;
Riddle Hsu609a8e22019-06-27 16:46:29 -060088import java.util.function.Consumer;
Andrii Kulian6a6c4f12018-07-16 21:23:33 -070089
Bryce Leeaf691c02017-03-20 14:20:22 -070090/**
91 * A base class to handle common operations in activity related unit tests.
92 */
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +090093class ActivityTestsBase {
Riddle Hsub70b36d2018-09-11 21:20:02 +080094 private static int sNextDisplayId = DEFAULT_DISPLAY + 1;
95
Adrian Roos3150dbf2018-03-28 18:06:52 +020096 @Rule
97 public final DexmakerShareClassLoaderRule mDexmakerShareClassLoaderRule =
98 new DexmakerShareClassLoaderRule();
99
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900100 final Context mContext = getInstrumentation().getTargetContext();
Riddle Hsu1abb56b2018-10-18 11:51:17 +0800101 final TestInjector mTestInjector = new TestInjector();
Bryce Leeaf691c02017-03-20 14:20:22 -0700102
Riddle Hsub70b36d2018-09-11 21:20:02 +0800103 ActivityTaskManagerService mService;
Wale Ogunwaled32da472018-11-16 07:19:28 -0800104 RootActivityContainer mRootActivityContainer;
Riddle Hsub70b36d2018-09-11 21:20:02 +0800105 ActivityStackSupervisor mSupervisor;
106
Tadashi G. Takaokad7aa79a2019-02-08 17:42:37 +0900107 private MockTracker mMockTracker;
108
Bryce Leefbd263b42018-03-07 10:33:55 -0800109 // Default package name
110 static final String DEFAULT_COMPONENT_PACKAGE_NAME = "com.foo";
111
112 // Default base activity name
113 private static final String DEFAULT_COMPONENT_CLASS_NAME = ".BarActivity";
114
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900115 @BeforeClass
116 public static void setUpOnceBase() {
117 AttributeCache.init(getInstrumentation().getTargetContext());
118 }
119
Bryce Leeaf691c02017-03-20 14:20:22 -0700120 @Before
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900121 public void setUpBase() {
Tadashi G. Takaokad7aa79a2019-02-08 17:42:37 +0900122 mMockTracker = new MockTracker();
123
Riddle Hsu1abb56b2018-10-18 11:51:17 +0800124 mTestInjector.setUp();
Wale Ogunwale976ca472019-01-17 09:55:38 -0800125
126 mService = new TestActivityTaskManagerService(mContext);
127 mSupervisor = mService.mStackSupervisor;
128 mRootActivityContainer = mService.mRootActivityContainer;
Bryce Lee3115bdf2017-04-05 08:39:40 -0700129 }
Bryce Leeaf691c02017-03-20 14:20:22 -0700130
Bryce Lee3115bdf2017-04-05 08:39:40 -0700131 @After
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900132 public void tearDownBase() {
Riddle Hsu1abb56b2018-10-18 11:51:17 +0800133 mTestInjector.tearDown();
Tadashi G. Takaoka5a108b82018-12-13 17:09:12 +0900134 if (mService != null) {
135 mService.setWindowManager(null);
136 mService = null;
137 }
Riddle Hsu43233b72019-04-24 23:55:11 +0800138 if (sMockWindowManagerService != null) {
139 reset(sMockWindowManagerService);
140 }
Tadashi G. Takaokad7aa79a2019-02-08 17:42:37 +0900141
142 mMockTracker.close();
143 mMockTracker = null;
Bryce Leeaf691c02017-03-20 14:20:22 -0700144 }
145
Riddle Hsub70b36d2018-09-11 21:20:02 +0800146 /** Creates a {@link TestActivityDisplay}. */
147 TestActivityDisplay createNewActivityDisplay() {
148 return TestActivityDisplay.create(mSupervisor, sNextDisplayId++);
149 }
150
Garfield Tan891146c2018-10-09 12:14:00 -0700151 TestActivityDisplay createNewActivityDisplay(DisplayInfo info) {
152 return TestActivityDisplay.create(mSupervisor, sNextDisplayId++, info);
153 }
154
Riddle Hsub70b36d2018-09-11 21:20:02 +0800155 /** Creates and adds a {@link TestActivityDisplay} to supervisor at the given position. */
156 TestActivityDisplay addNewActivityDisplayAt(int position) {
157 final TestActivityDisplay display = createNewActivityDisplay();
Wale Ogunwaled32da472018-11-16 07:19:28 -0800158 mRootActivityContainer.addChild(display, position);
Riddle Hsub70b36d2018-09-11 21:20:02 +0800159 return display;
160 }
161
Evan Rosky730f6e82018-12-03 17:40:11 -0800162 /** Creates and adds a {@link TestActivityDisplay} to supervisor at the given position. */
163 TestActivityDisplay addNewActivityDisplayAt(DisplayInfo info, int position) {
164 final TestActivityDisplay display = createNewActivityDisplay(info);
165 mRootActivityContainer.addChild(display, position);
166 return display;
167 }
168
Bryce Lee18d51592017-10-25 10:22:19 -0700169 /**
Riddle Hsuff9e8282019-04-24 23:55:11 +0800170 * Delegates task creation to {@link #TaskBuilder} to avoid the dependency of window hierarchy
171 * when starting activity in unit tests.
172 */
Riddle Hsu609a8e22019-06-27 16:46:29 -0600173 void mockTaskRecordFactory(Consumer<TaskBuilder> taskBuilderSetup) {
174 final TaskBuilder taskBuilder = new TaskBuilder(mSupervisor).setCreateStack(false);
175 if (taskBuilderSetup != null) {
176 taskBuilderSetup.accept(taskBuilder);
177 }
178 final TaskRecord task = taskBuilder.build();
Riddle Hsuff9e8282019-04-24 23:55:11 +0800179 final TaskRecordFactory factory = mock(TaskRecordFactory.class);
180 TaskRecord.setTaskRecordFactory(factory);
181 doReturn(task).when(factory).create(any() /* service */, anyInt() /* taskId */,
182 any() /* info */, any() /* intent */, any() /* voiceSession */,
183 any() /* voiceInteractor */);
184 }
185
Riddle Hsu609a8e22019-06-27 16:46:29 -0600186 void mockTaskRecordFactory() {
187 mockTaskRecordFactory(null /* taskBuilderSetup */);
188 }
189
Riddle Hsuff9e8282019-04-24 23:55:11 +0800190 /**
Bryce Lee18d51592017-10-25 10:22:19 -0700191 * Builder for creating new activities.
192 */
193 protected static class ActivityBuilder {
194 // An id appended to the end of the component name to make it unique
195 private static int sCurrentActivityId = 0;
Bryce Lee9f6affd2017-09-01 09:18:35 -0700196
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700197 private final ActivityTaskManagerService mService;
Bryce Lee18d51592017-10-25 10:22:19 -0700198
199 private ComponentName mComponent;
Louis Chang23df1a62019-01-09 15:10:49 +0800200 private String mTargetActivity;
Bryce Lee18d51592017-10-25 10:22:19 -0700201 private TaskRecord mTaskRecord;
202 private int mUid;
203 private boolean mCreateTask;
204 private ActivityStack mStack;
Bryce Leec961e0a2018-04-13 17:58:02 -0700205 private int mActivityFlags;
Riddle Hsub70b36d2018-09-11 21:20:02 +0800206 private int mLaunchMode;
Bryce Lee18d51592017-10-25 10:22:19 -0700207
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700208 ActivityBuilder(ActivityTaskManagerService service) {
Bryce Lee18d51592017-10-25 10:22:19 -0700209 mService = service;
Bryce Leeaf691c02017-03-20 14:20:22 -0700210 }
211
Bryce Lee18d51592017-10-25 10:22:19 -0700212 ActivityBuilder setComponent(ComponentName component) {
213 mComponent = component;
214 return this;
215 }
216
Louis Chang23df1a62019-01-09 15:10:49 +0800217 ActivityBuilder setTargetActivity(String targetActivity) {
218 mTargetActivity = targetActivity;
219 return this;
220 }
221
Bryce Leead5b8322018-03-08 14:28:52 -0800222 static ComponentName getDefaultComponent() {
223 return ComponentName.createRelative(DEFAULT_COMPONENT_PACKAGE_NAME,
224 DEFAULT_COMPONENT_PACKAGE_NAME);
225 }
226
Bryce Lee18d51592017-10-25 10:22:19 -0700227 ActivityBuilder setTask(TaskRecord task) {
228 mTaskRecord = task;
229 return this;
230 }
231
Bryce Leec961e0a2018-04-13 17:58:02 -0700232 ActivityBuilder setActivityFlags(int flags) {
233 mActivityFlags = flags;
234 return this;
235 }
236
Riddle Hsub70b36d2018-09-11 21:20:02 +0800237 ActivityBuilder setLaunchMode(int launchMode) {
238 mLaunchMode = launchMode;
239 return this;
240 }
241
Bryce Lee18d51592017-10-25 10:22:19 -0700242 ActivityBuilder setStack(ActivityStack stack) {
243 mStack = stack;
244 return this;
245 }
246
247 ActivityBuilder setCreateTask(boolean createTask) {
248 mCreateTask = createTask;
249 return this;
250 }
251
252 ActivityBuilder setUid(int uid) {
253 mUid = uid;
254 return this;
255 }
256
257 ActivityRecord build() {
258 if (mComponent == null) {
259 final int id = sCurrentActivityId++;
Bryce Leefbd263b42018-03-07 10:33:55 -0800260 mComponent = ComponentName.createRelative(DEFAULT_COMPONENT_PACKAGE_NAME,
261 DEFAULT_COMPONENT_CLASS_NAME + id);
Bryce Lee18d51592017-10-25 10:22:19 -0700262 }
263
264 if (mCreateTask) {
265 mTaskRecord = new TaskBuilder(mService.mStackSupervisor)
266 .setComponent(mComponent)
267 .setStack(mStack).build();
268 }
269
270 Intent intent = new Intent();
271 intent.setComponent(mComponent);
272 final ActivityInfo aInfo = new ActivityInfo();
273 aInfo.applicationInfo = new ApplicationInfo();
274 aInfo.applicationInfo.packageName = mComponent.getPackageName();
275 aInfo.applicationInfo.uid = mUid;
Louis Chang23df1a62019-01-09 15:10:49 +0800276 aInfo.packageName = mComponent.getPackageName();
277 if (mTargetActivity != null) {
278 aInfo.targetActivity = mTargetActivity;
279 }
Bryce Leec961e0a2018-04-13 17:58:02 -0700280 aInfo.flags |= mActivityFlags;
Riddle Hsub70b36d2018-09-11 21:20:02 +0800281 aInfo.launchMode = mLaunchMode;
Bryce Leec961e0a2018-04-13 17:58:02 -0700282
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700283 final ActivityRecord activity = new ActivityRecord(mService, null /* caller */,
Bryce Lee18d51592017-10-25 10:22:19 -0700284 0 /* launchedFromPid */, 0, null, intent, null,
285 aInfo /*aInfo*/, new Configuration(), null /* resultTo */, null /* resultWho */,
286 0 /* reqCode */, false /*componentSpecified*/, false /* rootVoiceInteraction */,
287 mService.mStackSupervisor, null /* options */, null /* sourceRecord */);
Yunfan Chend4ef3012018-11-28 21:14:32 -0800288 spyOn(activity);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800289 activity.mAppWindowToken = mock(AppWindowToken.class);
Evan Rosky730f6e82018-12-03 17:40:11 -0800290 doCallRealMethod().when(activity.mAppWindowToken).getOrientationIgnoreVisibility();
291 doCallRealMethod().when(activity.mAppWindowToken)
292 .setOrientation(anyInt(), any(), any());
293 doCallRealMethod().when(activity.mAppWindowToken).setOrientation(anyInt());
Yunfan Chend4ef3012018-11-28 21:14:32 -0800294 doNothing().when(activity).removeWindowContainer();
Garfield Tan0443b372019-01-04 15:00:13 -0800295 doReturn(mock(Configuration.class)).when(activity.mAppWindowToken)
296 .getRequestedOverrideConfiguration();
Bryce Lee18d51592017-10-25 10:22:19 -0700297
298 if (mTaskRecord != null) {
299 mTaskRecord.addActivityToTop(activity);
300 }
301
Andrii Kulianbeadacc2019-05-20 12:18:01 +0000302 final WindowProcessController wpc = new WindowProcessController(mService,
303 mService.mContext.getApplicationInfo(), "name", 12345,
304 UserHandle.getUserId(12345), mock(Object.class),
305 mock(WindowProcessListener.class));
306 wpc.setThread(mock(IApplicationThread.class));
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700307 activity.setProcess(wpc);
Bryce Lee18d51592017-10-25 10:22:19 -0700308 return activity;
309 }
Bryce Leeaf691c02017-03-20 14:20:22 -0700310 }
311
Bryce Lee18d51592017-10-25 10:22:19 -0700312 /**
313 * Builder for creating new tasks.
314 */
315 protected static class TaskBuilder {
Bryce Leefbd263b42018-03-07 10:33:55 -0800316 // Default package name
317 static final String DEFAULT_PACKAGE = "com.bar";
318
Bryce Lee18d51592017-10-25 10:22:19 -0700319 private final ActivityStackSupervisor mSupervisor;
Winson Chung1dbc8112017-09-28 18:05:31 -0700320
Bryce Lee18d51592017-10-25 10:22:19 -0700321 private ComponentName mComponent;
322 private String mPackage;
323 private int mFlags = 0;
Kazuki Takisec2e17bf2018-07-17 17:46:38 +0900324 // Task id 0 is reserved in ARC for the home app.
325 private int mTaskId = 1;
Winson Chung0ec2a352017-10-26 11:38:30 -0700326 private int mUserId = 0;
Bryce Lee93e7f792017-10-25 15:54:55 -0700327 private IVoiceInteractionSession mVoiceSession;
Bryce Lee2b8e0372018-04-05 17:01:37 -0700328 private boolean mCreateStack = true;
Bryce Leeaf691c02017-03-20 14:20:22 -0700329
Bryce Lee18d51592017-10-25 10:22:19 -0700330 private ActivityStack mStack;
Bryce Leeaf691c02017-03-20 14:20:22 -0700331
Bryce Lee18d51592017-10-25 10:22:19 -0700332 TaskBuilder(ActivityStackSupervisor supervisor) {
333 mSupervisor = supervisor;
334 }
Bryce Leeaf691c02017-03-20 14:20:22 -0700335
Bryce Lee18d51592017-10-25 10:22:19 -0700336 TaskBuilder setComponent(ComponentName component) {
337 mComponent = component;
338 return this;
339 }
340
341 TaskBuilder setPackage(String packageName) {
342 mPackage = packageName;
343 return this;
344 }
345
Bryce Lee2b8e0372018-04-05 17:01:37 -0700346 /**
347 * Set to {@code true} by default, set to {@code false} to prevent the task from
348 * automatically creating a parent stack.
349 */
350 TaskBuilder setCreateStack(boolean createStack) {
351 mCreateStack = createStack;
352 return this;
353 }
354
Bryce Lee93e7f792017-10-25 15:54:55 -0700355 TaskBuilder setVoiceSession(IVoiceInteractionSession session) {
356 mVoiceSession = session;
357 return this;
358 }
359
Bryce Lee18d51592017-10-25 10:22:19 -0700360 TaskBuilder setFlags(int flags) {
361 mFlags = flags;
362 return this;
363 }
364
365 TaskBuilder setTaskId(int taskId) {
366 mTaskId = taskId;
367 return this;
368 }
369
Winson Chung0ec2a352017-10-26 11:38:30 -0700370 TaskBuilder setUserId(int userId) {
371 mUserId = userId;
372 return this;
373 }
374
Bryce Lee18d51592017-10-25 10:22:19 -0700375 TaskBuilder setStack(ActivityStack stack) {
376 mStack = stack;
377 return this;
378 }
379
380 TaskRecord build() {
Bryce Lee2b8e0372018-04-05 17:01:37 -0700381 if (mStack == null && mCreateStack) {
Wale Ogunwaled32da472018-11-16 07:19:28 -0800382 mStack = mSupervisor.mRootActivityContainer.getDefaultDisplay().createStack(
Bryce Lee18d51592017-10-25 10:22:19 -0700383 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
384 }
385
386 final ActivityInfo aInfo = new ActivityInfo();
387 aInfo.applicationInfo = new ApplicationInfo();
388 aInfo.applicationInfo.packageName = mPackage;
389
390 Intent intent = new Intent();
Bryce Leefbd263b42018-03-07 10:33:55 -0800391 if (mComponent == null) {
392 mComponent = ComponentName.createRelative(DEFAULT_COMPONENT_PACKAGE_NAME,
393 DEFAULT_COMPONENT_CLASS_NAME);
394 }
395
Bryce Lee18d51592017-10-25 10:22:19 -0700396 intent.setComponent(mComponent);
397 intent.setFlags(mFlags);
398
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700399 final TestTaskRecord task = new TestTaskRecord(mSupervisor.mService, mTaskId, aInfo,
Bryce Lee93e7f792017-10-25 15:54:55 -0700400 intent /*intent*/, mVoiceSession, null /*_voiceInteractor*/);
Winson Chung0ec2a352017-10-26 11:38:30 -0700401 task.userId = mUserId;
Bryce Lee2b8e0372018-04-05 17:01:37 -0700402
403 if (mStack != null) {
Andrii Kulian6a6c4f12018-07-16 21:23:33 -0700404 mStack.moveToFront("test");
Bryce Lee2b8e0372018-04-05 17:01:37 -0700405 mStack.addTask(task, true, "creating test task");
406 task.setStack(mStack);
Yunfan Chen0e7aff92018-12-05 16:35:32 -0800407 task.setTask();
Yunfan Chen279f5582018-12-12 15:24:50 -0800408 mStack.getTaskStack().addChild(task.mTask, 0);
Bryce Lee2b8e0372018-04-05 17:01:37 -0700409 }
410
Winson Chung0ec2a352017-10-26 11:38:30 -0700411 task.touchActiveTime();
Bryce Lee18d51592017-10-25 10:22:19 -0700412
413 return task;
414 }
Bryce Lee2b8e0372018-04-05 17:01:37 -0700415
416 private static class TestTaskRecord extends TaskRecord {
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900417 TestTaskRecord(ActivityTaskManagerService service, int taskId, ActivityInfo info,
418 Intent intent, IVoiceInteractionSession voiceSession,
419 IVoiceInteractor voiceInteractor) {
420 super(service, taskId, info, intent, voiceSession, voiceInteractor);
Bryce Lee2b8e0372018-04-05 17:01:37 -0700421 }
422
423 @Override
Yunfan Chen0e7aff92018-12-05 16:35:32 -0800424 void createTask(boolean onTop, boolean showForAllUsers) {
425 setTask();
Bryce Lee2b8e0372018-04-05 17:01:37 -0700426 }
427
Evan Rosky730f6e82018-12-03 17:40:11 -0800428 void setTask() {
429 Task mockTask = mock(Task.class);
430 mockTask.mTaskRecord = this;
431 doCallRealMethod().when(mockTask).onDescendantOrientationChanged(any(), any());
Yunfan Chen0e7aff92018-12-05 16:35:32 -0800432 setTask(mock(Task.class));
Bryce Lee2b8e0372018-04-05 17:01:37 -0700433 }
434 }
Bryce Leeaf691c02017-03-20 14:20:22 -0700435 }
436
Wale Ogunwaleb73f3962018-11-20 07:58:22 -0800437 protected class TestActivityTaskManagerService extends ActivityTaskManagerService {
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700438 private PackageManagerInternal mPmInternal;
Hai Zhangf4da9be2019-05-01 13:46:06 +0800439 private PermissionPolicyInternal mPermissionPolicyInternal;
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700440
Louis Chang89f43fc2018-10-05 10:59:14 +0800441 // ActivityStackSupervisor may be created more than once while setting up AMS and ATMS.
442 // We keep the reference in order to prevent creating it twice.
Wale Ogunwaleb73f3962018-11-20 07:58:22 -0800443 ActivityStackSupervisor mTestStackSupervisor;
Louis Chang89f43fc2018-10-05 10:59:14 +0800444
Wale Ogunwaled32da472018-11-16 07:19:28 -0800445 ActivityDisplay mDefaultDisplay;
Michal Karpinski15486842019-04-25 17:33:42 +0100446 AppOpsService mAppOpsService;
Wale Ogunwaled32da472018-11-16 07:19:28 -0800447
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700448 TestActivityTaskManagerService(Context context) {
449 super(context);
Wale Ogunwaleb73f3962018-11-20 07:58:22 -0800450 spyOn(this);
451
452 mUgmInternal = mock(UriGrantsManagerInternal.class);
Michal Karpinski15486842019-04-25 17:33:42 +0100453 mAppOpsService = mock(AppOpsService.class);
454
455 // Make sure permission checks aren't overridden.
456 doReturn(AppOpsManager.MODE_DEFAULT)
457 .when(mAppOpsService).noteOperation(anyInt(), anyInt(), anyString());
Wale Ogunwaleb73f3962018-11-20 07:58:22 -0800458
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700459 mSupportsMultiWindow = true;
460 mSupportsMultiDisplay = true;
461 mSupportsSplitScreenMultiWindow = true;
462 mSupportsFreeformWindowManagement = true;
463 mSupportsPictureInPicture = true;
Wale Ogunwaleb73f3962018-11-20 07:58:22 -0800464
465 final TestActivityManagerService am =
466 new TestActivityManagerService(mTestInjector, this);
467
Wale Ogunwaleb73f3962018-11-20 07:58:22 -0800468 spyOn(getLifecycleManager());
469 spyOn(getLockTaskController());
470 doReturn(mock(IPackageManager.class)).when(this).getPackageManager();
Michal Karpinski8596ded2018-11-14 14:43:48 +0000471 // allow background activity starts by default
472 doReturn(true).when(this).isBackgroundActivityStartsEnabled();
Andrii Kulian6b321512019-01-23 06:37:00 +0000473 doNothing().when(this).updateCpuStats();
Wale Ogunwaleb73f3962018-11-20 07:58:22 -0800474 }
475
Riddle Hsud93a6c42018-11-29 21:50:06 +0800476 void setup(IntentFirewall intentFirewall, PendingIntentController intentController,
477 ActivityManagerInternal amInternal, WindowManagerService wm, Looper looper) {
Wale Ogunwaleb73f3962018-11-20 07:58:22 -0800478 mAmInternal = amInternal;
Riddle Hsud93a6c42018-11-29 21:50:06 +0800479 initialize(intentFirewall, intentController, looper);
Wale Ogunwaled32da472018-11-16 07:19:28 -0800480 initRootActivityContainerMocks(wm);
Wale Ogunwaleb73f3962018-11-20 07:58:22 -0800481 setWindowManager(wm);
Wale Ogunwale3a256e62018-12-06 14:41:18 -0800482 createDefaultDisplay();
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700483 }
484
Wale Ogunwaled32da472018-11-16 07:19:28 -0800485 void initRootActivityContainerMocks(WindowManagerService wm) {
486 spyOn(mRootActivityContainer);
Wale Ogunwale31acb3f2018-11-20 15:23:55 -0800487 mRootActivityContainer.setWindowContainer(mock(RootWindowContainer.class));
Wale Ogunwaled32da472018-11-16 07:19:28 -0800488 mRootActivityContainer.mWindowManager = wm;
489 mRootActivityContainer.mDisplayManager =
490 (DisplayManager) mContext.getSystemService(Context.DISPLAY_SERVICE);
491 doNothing().when(mRootActivityContainer).setWindowManager(any());
492 // Invoked during {@link ActivityStack} creation.
493 doNothing().when(mRootActivityContainer).updateUIDsPresentOnDisplay();
494 // Always keep things awake.
495 doReturn(true).when(mRootActivityContainer).hasAwakeDisplay();
496 // Called when moving activity to pinned stack.
497 doNothing().when(mRootActivityContainer).ensureActivitiesVisible(any(), anyInt(),
498 anyBoolean());
Wale Ogunwale3a256e62018-12-06 14:41:18 -0800499 }
Wale Ogunwaled32da472018-11-16 07:19:28 -0800500
Wale Ogunwale3a256e62018-12-06 14:41:18 -0800501 void createDefaultDisplay() {
Wale Ogunwaled32da472018-11-16 07:19:28 -0800502 // Create a default display and put a home stack on it so that we'll always have
503 // something focusable.
504 mDefaultDisplay = TestActivityDisplay.create(mStackSupervisor, DEFAULT_DISPLAY);
505 spyOn(mDefaultDisplay);
506 mRootActivityContainer.addChild(mDefaultDisplay, ActivityDisplay.POSITION_TOP);
507 mDefaultDisplay.createStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, ON_TOP);
508 final TaskRecord task = new TaskBuilder(mStackSupervisor)
509 .setStack(mDefaultDisplay.getHomeStack()).build();
510 new ActivityBuilder(this).setTask(task).build();
511
512 doReturn(mDefaultDisplay).when(mRootActivityContainer).getDefaultDisplay();
513 }
514
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700515 @Override
516 int handleIncomingUser(int callingPid, int callingUid, int userId, String name) {
517 return userId;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700518 }
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700519
520 @Override
Michal Karpinski15486842019-04-25 17:33:42 +0100521 AppOpsService getAppOpsService() {
522 return mAppOpsService;
523 }
524
525 @Override
Riddle Hsuaaef7312019-01-24 19:00:58 +0800526 void updateCpuStats() {
527 }
528
529 @Override
Hui Yu03d12402018-12-06 18:00:37 -0800530 void updateBatteryStats(ActivityRecord component, boolean resumed) {
531 }
532
533 @Override
534 void updateActivityUsageStats(ActivityRecord activity, int event) {
Wale Ogunwale53783742018-09-16 10:21:51 -0700535 }
536
537 @Override
Wale Ogunwaleb73f3962018-11-20 07:58:22 -0800538 protected ActivityStackSupervisor createStackSupervisor() {
Louis Chang89f43fc2018-10-05 10:59:14 +0800539 if (mTestStackSupervisor == null) {
Wale Ogunwaleb73f3962018-11-20 07:58:22 -0800540 mTestStackSupervisor = new TestActivityStackSupervisor(this, mH.getLooper());
Louis Chang89f43fc2018-10-05 10:59:14 +0800541 }
542 return mTestStackSupervisor;
Bryce Lee2a3cc462017-10-27 10:57:35 -0700543 }
544
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900545 @Override
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700546 PackageManagerInternal getPackageManagerInternalLocked() {
547 if (mPmInternal == null) {
548 mPmInternal = mock(PackageManagerInternal.class);
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900549 doReturn(false)
550 .when(mPmInternal)
551 .isPermissionsReviewRequired(anyString(), anyInt());
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700552 }
553 return mPmInternal;
554 }
Hai Zhangf4da9be2019-05-01 13:46:06 +0800555
556 @Override
557 PermissionPolicyInternal getPermissionPolicyInternal() {
558 if (mPermissionPolicyInternal == null) {
559 mPermissionPolicyInternal = mock(PermissionPolicyInternal.class);
560 doReturn(true).when(mPermissionPolicyInternal).checkStartActivity(any(), anyInt(),
561 any());
562 }
563 return mPermissionPolicyInternal;
564 }
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700565 }
566
Riddle Hsu1abb56b2018-10-18 11:51:17 +0800567 private static class TestInjector extends ActivityManagerService.Injector {
568 private ServiceThread mHandlerThread;
569
570 @Override
571 public Context getContext() {
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900572 return getInstrumentation().getTargetContext();
Riddle Hsu1abb56b2018-10-18 11:51:17 +0800573 }
574
575 @Override
576 public AppOpsService getAppOpsService(File file, Handler handler) {
577 return null;
578 }
579
580 @Override
581 public Handler getUiHandler(ActivityManagerService service) {
582 return mHandlerThread.getThreadHandler();
583 }
584
585 @Override
586 public boolean isNetworkRestrictedForUid(int uid) {
587 return false;
588 }
589
590 void setUp() {
591 mHandlerThread = new ServiceThread("ActivityTestsThread",
592 Process.THREAD_PRIORITY_DEFAULT, true /* allowIo */);
593 mHandlerThread.start();
594 }
595
596 void tearDown() {
Riddle Hsue2e5ee12019-06-11 23:44:39 +0800597 // Make sure there are no running messages and then quit the thread so the next test
598 // won't be affected.
599 mHandlerThread.getThreadHandler().runWithScissors(mHandlerThread::quit,
600 0 /* timeout */);
Riddle Hsu1abb56b2018-10-18 11:51:17 +0800601 }
602 }
603
Wale Ogunwaleb73f3962018-11-20 07:58:22 -0800604 // TODO: Replace this with a mock object since we are no longer in AMS package.
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700605 /**
606 * An {@link ActivityManagerService} subclass which provides a test
607 * {@link ActivityStackSupervisor}.
608 */
Wale Ogunwaleb73f3962018-11-20 07:58:22 -0800609 class TestActivityManagerService extends ActivityManagerService {
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700610
Wale Ogunwaleb73f3962018-11-20 07:58:22 -0800611 TestActivityManagerService(TestInjector testInjector, TestActivityTaskManagerService atm) {
Riddle Hsu1abb56b2018-10-18 11:51:17 +0800612 super(testInjector, testInjector.mHandlerThread);
Wale Ogunwaleb73f3962018-11-20 07:58:22 -0800613 spyOn(this);
Bryce Lee29a649d2017-08-18 13:52:31 -0700614
Wale Ogunwaleb73f3962018-11-20 07:58:22 -0800615 mWindowManager = prepareMockWindowManager();
616 mUgmInternal = mock(UriGrantsManagerInternal.class);
617
Riddle Hsud93a6c42018-11-29 21:50:06 +0800618 atm.setup(mIntentFirewall, mPendingIntentController, new LocalService(), mWindowManager,
619 testInjector.mHandlerThread.getLooper());
Wale Ogunwaleb73f3962018-11-20 07:58:22 -0800620
621 mActivityTaskManager = atm;
622 mAtmInternal = atm.mInternal;
623
624 doReturn(mock(IPackageManager.class)).when(this).getPackageManager();
625 PackageManagerInternal mockPackageManager = mock(PackageManagerInternal.class);
626 doReturn(mockPackageManager).when(this).getPackageManagerInternalLocked();
627 doReturn(null).when(mockPackageManager).getDefaultHomeActivity(anyInt());
628 doNothing().when(this).grantEphemeralAccessLocked(anyInt(), any(), anyInt(), anyInt());
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700629 }
Bryce Leeaf691c02017-03-20 14:20:22 -0700630 }
631
632 /**
633 * An {@link ActivityStackSupervisor} which stubs out certain methods that depend on
634 * setup not available in the test environment. Also specifies an injector for
635 */
Wale Ogunwaleb73f3962018-11-20 07:58:22 -0800636 protected class TestActivityStackSupervisor extends ActivityStackSupervisor {
Bryce Lee459c0622018-03-19 11:04:01 -0700637 private KeyguardController mKeyguardController;
Bryce Lee943ebe72017-05-04 10:19:07 -0700638
Wale Ogunwaleb73f3962018-11-20 07:58:22 -0800639 TestActivityStackSupervisor(ActivityTaskManagerService service, Looper looper) {
Bryce Leeaf691c02017-03-20 14:20:22 -0700640 super(service, looper);
Wale Ogunwaleb73f3962018-11-20 07:58:22 -0800641 spyOn(this);
Bryce Lee04ab3462017-04-10 15:06:33 -0700642 mWindowManager = prepareMockWindowManager();
Bryce Lee459c0622018-03-19 11:04:01 -0700643 mKeyguardController = mock(KeyguardController.class);
Wale Ogunwaleb73f3962018-11-20 07:58:22 -0800644
Riddle Hsue2e5ee12019-06-11 23:44:39 +0800645 // Do not schedule idle that may touch methods outside the scope of the test.
646 doNothing().when(this).scheduleIdleLocked();
Wale Ogunwaleb73f3962018-11-20 07:58:22 -0800647 doNothing().when(this).scheduleIdleTimeoutLocked(any());
648 // unit test version does not handle launch wake lock
649 doNothing().when(this).acquireLaunchWakelock();
650 doReturn(mKeyguardController).when(this).getKeyguardController();
651
Andrii Kulianc598b2d2019-02-07 17:16:38 -0800652 mLaunchingActivityWakeLock = mock(PowerManager.WakeLock.class);
Andrii Kulian6b321512019-01-23 06:37:00 +0000653
Wale Ogunwaleb73f3962018-11-20 07:58:22 -0800654 initialize();
Bryce Lee2a3cc462017-10-27 10:57:35 -0700655 }
656
657 @Override
Bryce Lee459c0622018-03-19 11:04:01 -0700658 public KeyguardController getKeyguardController() {
659 return mKeyguardController;
660 }
661
662 @Override
Wale Ogunwale31913b52018-10-13 08:29:31 -0700663 void setWindowManager(WindowManagerService wm) {
664 mWindowManager = wm;
665 }
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700666 }
667
Winson Chung59a47ded2018-01-25 17:46:06 +0000668 protected static class TestActivityDisplay extends ActivityDisplay {
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700669 private final ActivityStackSupervisor mSupervisor;
Riddle Hsub70b36d2018-09-11 21:20:02 +0800670
671 static TestActivityDisplay create(ActivityStackSupervisor supervisor, int displayId) {
Garfield Tan891146c2018-10-09 12:14:00 -0700672 return create(supervisor, displayId, new DisplayInfo());
673 }
674
675 static TestActivityDisplay create(ActivityStackSupervisor supervisor, int displayId,
676 DisplayInfo info) {
Riddle Hsub70b36d2018-09-11 21:20:02 +0800677 if (displayId == DEFAULT_DISPLAY) {
678 return new TestActivityDisplay(supervisor,
Wale Ogunwaled32da472018-11-16 07:19:28 -0800679 supervisor.mRootActivityContainer.mDisplayManager.getDisplay(displayId));
Riddle Hsub70b36d2018-09-11 21:20:02 +0800680 }
681 final Display display = new Display(DisplayManagerGlobal.getInstance(), displayId,
Garfield Tan891146c2018-10-09 12:14:00 -0700682 info, DEFAULT_DISPLAY_ADJUSTMENTS);
Riddle Hsub70b36d2018-09-11 21:20:02 +0800683 return new TestActivityDisplay(supervisor, display);
684 }
685
686 TestActivityDisplay(ActivityStackSupervisor supervisor, Display display) {
Wale Ogunwaled32da472018-11-16 07:19:28 -0800687 super(supervisor.mService.mRootActivityContainer, display);
Evan Rosky10475742018-09-05 19:02:48 -0700688 // Normally this comes from display-properties as exposed by WM. Without that, just
689 // hard-code to FULLSCREEN for tests.
690 setWindowingMode(WINDOWING_MODE_FULLSCREEN);
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700691 mSupervisor = supervisor;
Andrii Kulianb1cdb102017-07-13 15:33:06 -0700692 }
693
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900694 @SuppressWarnings("TypeParameterUnusedInFormals")
Andrii Kulianb1cdb102017-07-13 15:33:06 -0700695 @Override
Yunfan Chen279f5582018-12-12 15:24:50 -0800696 ActivityStack createStackUnchecked(int windowingMode, int activityType,
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700697 int stackId, boolean onTop) {
Wale Ogunwaled32da472018-11-16 07:19:28 -0800698 return new StackBuilder(mSupervisor.mRootActivityContainer).setDisplay(this)
Louis Changf2835df2018-10-17 15:14:45 +0800699 .setWindowingMode(windowingMode).setActivityType(activityType)
700 .setStackId(stackId).setOnTop(onTop).setCreateActivity(false).build();
Bryce Lee04ab3462017-04-10 15:06:33 -0700701 }
Winson Chung59a47ded2018-01-25 17:46:06 +0000702
703 @Override
Wale Ogunwale3a256e62018-12-06 14:41:18 -0800704 protected DisplayContent createDisplayContent() {
Tadashi G. Takaokad7aa79a2019-02-08 17:42:37 +0900705 final DisplayContent displayContent = mock(DisplayContent.class);
706 DockedStackDividerController divider = mock(DockedStackDividerController.class);
707 doReturn(divider).when(displayContent).getDockedDividerController();
708 return displayContent;
Winson Chung59a47ded2018-01-25 17:46:06 +0000709 }
Andrii Kulian6a6c4f12018-07-16 21:23:33 -0700710
711 void removeAllTasks() {
712 for (int i = 0; i < getChildCount(); i++) {
713 final ActivityStack stack = getChildAt(i);
714 for (TaskRecord task : (List<TaskRecord>) stack.getAllTasks()) {
715 stack.removeTask(task, "removeAllTasks", REMOVE_TASK_MODE_DESTROYING);
716 }
717 }
718 }
Bryce Leeaf691c02017-03-20 14:20:22 -0700719 }
720
Tadashi G. Takaoka5a108b82018-12-13 17:09:12 +0900721 private static WindowManagerService sMockWindowManagerService;
722
Bryce Lee04ab3462017-04-10 15:06:33 -0700723 private static WindowManagerService prepareMockWindowManager() {
Garfield Tan26835f02019-02-07 14:38:38 -0800724 if (sMockWindowManagerService == null) {
725 sMockWindowManagerService = mock(WindowManagerService.class);
Tadashi G. Takaoka5a108b82018-12-13 17:09:12 +0900726 }
727
Garfield Tan26835f02019-02-07 14:38:38 -0800728 sMockWindowManagerService.mRoot = mock(RootWindowContainer.class);
Bryce Lee04ab3462017-04-10 15:06:33 -0700729
730 doAnswer((InvocationOnMock invocationOnMock) -> {
731 final Runnable runnable = invocationOnMock.<Runnable>getArgument(0);
732 if (runnable != null) {
733 runnable.run();
734 }
735 return null;
Garfield Tan26835f02019-02-07 14:38:38 -0800736 }).when(sMockWindowManagerService).inSurfaceTransaction(any());
Bryce Lee04ab3462017-04-10 15:06:33 -0700737
Garfield Tan26835f02019-02-07 14:38:38 -0800738 return sMockWindowManagerService;
Bryce Lee04ab3462017-04-10 15:06:33 -0700739 }
740
Bryce Leeaf691c02017-03-20 14:20:22 -0700741 /**
Bryce Lee2b8e0372018-04-05 17:01:37 -0700742 * Overridden {@link ActivityStack} that tracks test metrics, such as the number of times a
Bryce Leeaf691c02017-03-20 14:20:22 -0700743 * method is called. Note that its functionality depends on the implementations of the
744 * construction arguments.
745 */
Yunfan Chen279f5582018-12-12 15:24:50 -0800746 protected static class TestActivityStack
747 extends ActivityStack {
Bryce Leeaf691c02017-03-20 14:20:22 -0700748 private int mOnActivityRemovedFromStackCount = 0;
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700749
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700750 static final int IS_TRANSLUCENT_UNSET = 0;
751 static final int IS_TRANSLUCENT_FALSE = 1;
752 static final int IS_TRANSLUCENT_TRUE = 2;
753 private int mIsTranslucent = IS_TRANSLUCENT_UNSET;
754
Wale Ogunwale30e441d2017-11-09 08:28:45 -0800755 static final int SUPPORTS_SPLIT_SCREEN_UNSET = 0;
756 static final int SUPPORTS_SPLIT_SCREEN_FALSE = 1;
757 static final int SUPPORTS_SPLIT_SCREEN_TRUE = 2;
758 private int mSupportsSplitScreen = SUPPORTS_SPLIT_SCREEN_UNSET;
759
Wale Ogunwale9dcf9462017-09-19 15:13:01 -0700760 TestActivityStack(ActivityDisplay display, int stackId, ActivityStackSupervisor supervisor,
Louis Changf2835df2018-10-17 15:14:45 +0800761 int windowingMode, int activityType, boolean onTop, boolean createActivity) {
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700762 super(display, stackId, supervisor, windowingMode, activityType, onTop);
Louis Changf2835df2018-10-17 15:14:45 +0800763 if (createActivity) {
764 new ActivityBuilder(mService).setCreateTask(true).setStack(this).build();
765 if (onTop) {
766 // We move the task to front again in order to regain focus after activity
767 // added to the stack. Or {@link ActivityDisplay#mPreferredTopFocusableStack}
768 // could be other stacks (e.g. home stack).
769 moveToFront("createActivityStack");
770 } else {
771 moveToBack("createActivityStack", null);
772 }
773 }
Bryce Leeaf691c02017-03-20 14:20:22 -0700774 }
775
776 @Override
777 void onActivityRemovedFromStack(ActivityRecord r) {
778 mOnActivityRemovedFromStackCount++;
779 super.onActivityRemovedFromStack(r);
780 }
781
782 // Returns the number of times {@link #onActivityRemovedFromStack} has been called
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700783 int onActivityRemovedFromStackInvocationCount() {
Bryce Leeaf691c02017-03-20 14:20:22 -0700784 return mOnActivityRemovedFromStackCount;
785 }
786
787 @Override
Yunfan Chen279f5582018-12-12 15:24:50 -0800788 protected void createTaskStack(int displayId, boolean onTop, Rect outBounds) {
Tadashi G. Takaokad7aa79a2019-02-08 17:42:37 +0900789 mTaskStack = mock(TaskStack.class);
Bryce Leef3c6a472017-11-14 14:53:06 -0800790
791 // Primary pinned stacks require a non-empty out bounds to be set or else all tasks
792 // will be moved to the full screen stack.
793 if (getWindowingMode() == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
794 outBounds.set(0, 0, 100, 100);
795 }
Bryce Leeaf691c02017-03-20 14:20:22 -0700796 }
797
798 @Override
Yunfan Chen279f5582018-12-12 15:24:50 -0800799 TaskStack getTaskStack() {
800 return mTaskStack;
Bryce Leeaf691c02017-03-20 14:20:22 -0700801 }
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700802
803 void setIsTranslucent(boolean isTranslucent) {
804 mIsTranslucent = isTranslucent ? IS_TRANSLUCENT_TRUE : IS_TRANSLUCENT_FALSE;
805 }
806
807 @Override
Wale Ogunwale66e16852017-10-19 13:35:52 -0700808 boolean isStackTranslucent(ActivityRecord starting) {
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700809 switch (mIsTranslucent) {
810 case IS_TRANSLUCENT_TRUE:
811 return true;
812 case IS_TRANSLUCENT_FALSE:
813 return false;
814 case IS_TRANSLUCENT_UNSET:
815 default:
Wale Ogunwale66e16852017-10-19 13:35:52 -0700816 return super.isStackTranslucent(starting);
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700817 }
818 }
Wale Ogunwale30e441d2017-11-09 08:28:45 -0800819
820 void setSupportsSplitScreen(boolean supportsSplitScreen) {
821 mSupportsSplitScreen = supportsSplitScreen
822 ? SUPPORTS_SPLIT_SCREEN_TRUE : SUPPORTS_SPLIT_SCREEN_FALSE;
823 }
824
825 @Override
826 public boolean supportsSplitScreenWindowingMode() {
827 switch (mSupportsSplitScreen) {
828 case SUPPORTS_SPLIT_SCREEN_TRUE:
829 return true;
830 case SUPPORTS_SPLIT_SCREEN_FALSE:
831 return false;
832 case SUPPORTS_SPLIT_SCREEN_UNSET:
833 default:
834 return super.supportsSplitScreenWindowingMode();
835 }
836 }
Bryce Lee2b8e0372018-04-05 17:01:37 -0700837
838 @Override
839 void startActivityLocked(ActivityRecord r, ActivityRecord focusedTopActivity,
840 boolean newTask, boolean keepCurTransition,
841 ActivityOptions options) {
842 }
Bryce Leeaf691c02017-03-20 14:20:22 -0700843 }
Louis Changf2835df2018-10-17 15:14:45 +0800844
Wale Ogunwaled32da472018-11-16 07:19:28 -0800845 static class StackBuilder {
846 private final RootActivityContainer mRootActivityContainer;
Louis Changf2835df2018-10-17 15:14:45 +0800847 private ActivityDisplay mDisplay;
848 private int mStackId = -1;
849 private int mWindowingMode = WINDOWING_MODE_FULLSCREEN;
850 private int mActivityType = ACTIVITY_TYPE_STANDARD;
851 private boolean mOnTop = true;
852 private boolean mCreateActivity = true;
853
Wale Ogunwaled32da472018-11-16 07:19:28 -0800854 StackBuilder(RootActivityContainer root) {
855 mRootActivityContainer = root;
856 mDisplay = mRootActivityContainer.getDefaultDisplay();
Louis Changf2835df2018-10-17 15:14:45 +0800857 }
858
859 StackBuilder setWindowingMode(int windowingMode) {
860 mWindowingMode = windowingMode;
861 return this;
862 }
863
864 StackBuilder setActivityType(int activityType) {
865 mActivityType = activityType;
866 return this;
867 }
868
869 StackBuilder setStackId(int stackId) {
870 mStackId = stackId;
871 return this;
872 }
873
874 StackBuilder setDisplay(ActivityDisplay display) {
875 mDisplay = display;
876 return this;
877 }
878
879 StackBuilder setOnTop(boolean onTop) {
880 mOnTop = onTop;
881 return this;
882 }
883
884 StackBuilder setCreateActivity(boolean createActivity) {
885 mCreateActivity = createActivity;
886 return this;
887 }
888
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900889 @SuppressWarnings("TypeParameterUnusedInFormals")
Yunfan Chen279f5582018-12-12 15:24:50 -0800890 ActivityStack build() {
Louis Changf2835df2018-10-17 15:14:45 +0800891 final int stackId = mStackId >= 0 ? mStackId : mDisplay.getNextStackId();
892 if (mWindowingMode == WINDOWING_MODE_PINNED) {
Yunfan Chen279f5582018-12-12 15:24:50 -0800893 return new ActivityStack(mDisplay, stackId, mRootActivityContainer.mStackSupervisor,
894 mWindowingMode, ACTIVITY_TYPE_STANDARD, mOnTop) {
Louis Changf2835df2018-10-17 15:14:45 +0800895 @Override
896 Rect getDefaultPictureInPictureBounds(float aspectRatio) {
897 return new Rect(50, 50, 100, 100);
898 }
899
900 @Override
Yunfan Chen279f5582018-12-12 15:24:50 -0800901 void createTaskStack(int displayId, boolean onTop, Rect outBounds) {
902 mTaskStack = mock(TaskStack.class);
Louis Changf2835df2018-10-17 15:14:45 +0800903 }
904 };
905 } else {
Yunfan Chen279f5582018-12-12 15:24:50 -0800906 return new TestActivityStack(mDisplay, stackId,
Wale Ogunwaled32da472018-11-16 07:19:28 -0800907 mRootActivityContainer.mStackSupervisor, mWindowingMode,
Louis Changf2835df2018-10-17 15:14:45 +0800908 mActivityType, mOnTop, mCreateActivity);
909 }
910 }
911
912 }
Bryce Leeaf691c02017-03-20 14:20:22 -0700913}