blob: a9165854bec497b557112fce5a1f68432e5b4f87 [file] [log] [blame]
Bryce Leeaf691c02017-03-20 14:20:22 -07001/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License
15 */
16
17package com.android.server.am;
18
Bryce Lee18d51592017-10-25 10:22:19 -070019import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
20import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070021import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
Bryce Leef3c6a472017-11-14 14:53:06 -080022import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
Wale Ogunwale9dcf9462017-09-19 15:13:01 -070023import static android.view.Display.DEFAULT_DISPLAY;
Bryce Leeaf691c02017-03-20 14:20:22 -070024import static org.mockito.Mockito.mock;
Bryce Lee2a3cc462017-10-27 10:57:35 -070025import static org.mockito.Mockito.doNothing;
Bryce Lee04ab3462017-04-10 15:06:33 -070026import static org.mockito.Mockito.doReturn;
27import static org.mockito.Mockito.any;
Bryce Lee2a3cc462017-10-27 10:57:35 -070028import static org.mockito.Mockito.anyBoolean;
29import static org.mockito.Mockito.anyInt;
Bryce Lee04ab3462017-04-10 15:06:33 -070030import static org.mockito.Mockito.doAnswer;
Bryce Lee4e4a3ec2017-09-27 08:25:03 -070031import static org.mockito.Mockito.spy;
Bryce Lee04ab3462017-04-10 15:06:33 -070032
Winson Chung59a47ded2018-01-25 17:46:06 +000033import com.android.server.wm.DisplayWindowController;
Bryce Lee04ab3462017-04-10 15:06:33 -070034import org.mockito.invocation.InvocationOnMock;
Bryce Leeaf691c02017-03-20 14:20:22 -070035
Bryce Lee0bd8d422018-01-09 09:45:57 -080036import android.app.IApplicationThread;
Bryce Leeaf691c02017-03-20 14:20:22 -070037import android.content.ComponentName;
38import android.content.Context;
39import android.content.Intent;
40import android.content.pm.ActivityInfo;
41import android.content.pm.ApplicationInfo;
Bryce Leeba8f4422017-11-20 12:35:57 -080042import android.content.pm.IPackageManager;
Bryce Leeaf691c02017-03-20 14:20:22 -070043import android.content.res.Configuration;
44import android.graphics.Rect;
Wale Ogunwale9dcf9462017-09-19 15:13:01 -070045import android.hardware.display.DisplayManager;
Bryce Lee3115bdf2017-04-05 08:39:40 -070046import android.os.HandlerThread;
Bryce Leeaf691c02017-03-20 14:20:22 -070047import android.os.Looper;
Bryce Lee93e7f792017-10-25 15:54:55 -070048import android.service.voice.IVoiceInteractionSession;
Bryce Leeaf691c02017-03-20 14:20:22 -070049import android.support.test.InstrumentationRegistry;
50import com.android.server.AttributeCache;
51import com.android.server.wm.AppWindowContainerController;
Bryce Lee4e4a3ec2017-09-27 08:25:03 -070052import com.android.server.wm.PinnedStackWindowController;
Bryce Leeaf691c02017-03-20 14:20:22 -070053import com.android.server.wm.StackWindowController;
Bryce Lee04ab3462017-04-10 15:06:33 -070054import com.android.server.wm.TaskWindowContainerController;
Bryce Leeaf691c02017-03-20 14:20:22 -070055import com.android.server.wm.WindowManagerService;
56import com.android.server.wm.WindowTestUtils;
Bryce Lee3115bdf2017-04-05 08:39:40 -070057import org.junit.After;
Bryce Leeaf691c02017-03-20 14:20:22 -070058import org.junit.Before;
59import org.mockito.MockitoAnnotations;
60
61/**
62 * A base class to handle common operations in activity related unit tests.
63 */
64public class ActivityTestsBase {
Bryce Lee939a9a32017-10-23 10:01:21 -070065 private static boolean sOneTimeSetupDone = false;
66
Bryce Leeaf691c02017-03-20 14:20:22 -070067 private final Context mContext = InstrumentationRegistry.getContext();
Bryce Lee3115bdf2017-04-05 08:39:40 -070068 private HandlerThread mHandlerThread;
Bryce Leeaf691c02017-03-20 14:20:22 -070069
Bryce Leefbd263b42018-03-07 10:33:55 -080070 // Default package name
71 static final String DEFAULT_COMPONENT_PACKAGE_NAME = "com.foo";
72
73 // Default base activity name
74 private static final String DEFAULT_COMPONENT_CLASS_NAME = ".BarActivity";
75
Bryce Leeaf691c02017-03-20 14:20:22 -070076 @Before
77 public void setUp() throws Exception {
Bryce Lee939a9a32017-10-23 10:01:21 -070078 if (!sOneTimeSetupDone) {
79 sOneTimeSetupDone = true;
80
81 // Allows to mock package local classes and methods
82 System.setProperty("dexmaker.share_classloader", "true");
83 MockitoAnnotations.initMocks(this);
84 }
Bryce Lee3115bdf2017-04-05 08:39:40 -070085 mHandlerThread = new HandlerThread("ActivityTestsBaseThread");
86 mHandlerThread.start();
87 }
Bryce Leeaf691c02017-03-20 14:20:22 -070088
Bryce Lee3115bdf2017-04-05 08:39:40 -070089 @After
90 public void tearDown() {
91 mHandlerThread.quitSafely();
Bryce Leeaf691c02017-03-20 14:20:22 -070092 }
93
94 protected ActivityManagerService createActivityManagerService() {
Bryce Lee93e7f792017-10-25 15:54:55 -070095 final ActivityManagerService service =
96 setupActivityManagerService(new TestActivityManagerService(mContext));
97 AttributeCache.init(mContext);
98 return service;
Winson Chung3f0e59a2017-10-25 10:19:05 -070099 }
100
101 protected ActivityManagerService setupActivityManagerService(ActivityManagerService service) {
102 service = spy(service);
Bryce Leeba8f4422017-11-20 12:35:57 -0800103 doReturn(mock(IPackageManager.class)).when(service).getPackageManager();
Bryce Leead5b8322018-03-08 14:28:52 -0800104 doNothing().when(service).grantEphemeralAccessLocked(anyInt(), any(), anyInt(), anyInt());
Bryce Lee4e4a3ec2017-09-27 08:25:03 -0700105 service.mWindowManager = prepareMockWindowManager();
Bryce Lee840c5662017-04-13 10:02:51 -0700106 return service;
Bryce Leeaf691c02017-03-20 14:20:22 -0700107 }
108
Bryce Lee18d51592017-10-25 10:22:19 -0700109 /**
110 * Builder for creating new activities.
111 */
112 protected static class ActivityBuilder {
113 // An id appended to the end of the component name to make it unique
114 private static int sCurrentActivityId = 0;
Bryce Lee9f6affd2017-09-01 09:18:35 -0700115
Bryce Leeaf691c02017-03-20 14:20:22 -0700116
Bryce Lee18d51592017-10-25 10:22:19 -0700117
118 private final ActivityManagerService mService;
119
120 private ComponentName mComponent;
121 private TaskRecord mTaskRecord;
122 private int mUid;
123 private boolean mCreateTask;
124 private ActivityStack mStack;
125
126 ActivityBuilder(ActivityManagerService service) {
127 mService = service;
Bryce Leeaf691c02017-03-20 14:20:22 -0700128 }
129
Bryce Lee18d51592017-10-25 10:22:19 -0700130 ActivityBuilder setComponent(ComponentName component) {
131 mComponent = component;
132 return this;
133 }
134
Bryce Leead5b8322018-03-08 14:28:52 -0800135 static ComponentName getDefaultComponent() {
136 return ComponentName.createRelative(DEFAULT_COMPONENT_PACKAGE_NAME,
137 DEFAULT_COMPONENT_PACKAGE_NAME);
138 }
139
Bryce Lee18d51592017-10-25 10:22:19 -0700140 ActivityBuilder setTask(TaskRecord task) {
141 mTaskRecord = task;
142 return this;
143 }
144
145 ActivityBuilder setStack(ActivityStack stack) {
146 mStack = stack;
147 return this;
148 }
149
150 ActivityBuilder setCreateTask(boolean createTask) {
151 mCreateTask = createTask;
152 return this;
153 }
154
155 ActivityBuilder setUid(int uid) {
156 mUid = uid;
157 return this;
158 }
159
160 ActivityRecord build() {
161 if (mComponent == null) {
162 final int id = sCurrentActivityId++;
Bryce Leefbd263b42018-03-07 10:33:55 -0800163 mComponent = ComponentName.createRelative(DEFAULT_COMPONENT_PACKAGE_NAME,
164 DEFAULT_COMPONENT_CLASS_NAME + id);
Bryce Lee18d51592017-10-25 10:22:19 -0700165 }
166
167 if (mCreateTask) {
168 mTaskRecord = new TaskBuilder(mService.mStackSupervisor)
169 .setComponent(mComponent)
170 .setStack(mStack).build();
171 }
172
173 Intent intent = new Intent();
174 intent.setComponent(mComponent);
175 final ActivityInfo aInfo = new ActivityInfo();
176 aInfo.applicationInfo = new ApplicationInfo();
177 aInfo.applicationInfo.packageName = mComponent.getPackageName();
178 aInfo.applicationInfo.uid = mUid;
Bryce Lee18d51592017-10-25 10:22:19 -0700179 final ActivityRecord activity = new ActivityRecord(mService, null /* caller */,
180 0 /* launchedFromPid */, 0, null, intent, null,
181 aInfo /*aInfo*/, new Configuration(), null /* resultTo */, null /* resultWho */,
182 0 /* reqCode */, false /*componentSpecified*/, false /* rootVoiceInteraction */,
183 mService.mStackSupervisor, null /* options */, null /* sourceRecord */);
184 activity.mWindowContainerController = mock(AppWindowContainerController.class);
185
186 if (mTaskRecord != null) {
187 mTaskRecord.addActivityToTop(activity);
188 }
189
Bryce Lee0bd8d422018-01-09 09:45:57 -0800190 activity.setProcess(new ProcessRecord(null, mService.mContext.getApplicationInfo(),
191 "name", 12345));
192 activity.app.thread = mock(IApplicationThread.class);
193
Bryce Lee18d51592017-10-25 10:22:19 -0700194 return activity;
195 }
Bryce Leeaf691c02017-03-20 14:20:22 -0700196 }
197
Bryce Lee18d51592017-10-25 10:22:19 -0700198 /**
199 * Builder for creating new tasks.
200 */
201 protected static class TaskBuilder {
Bryce Leefbd263b42018-03-07 10:33:55 -0800202 // Default package name
203 static final String DEFAULT_PACKAGE = "com.bar";
204
Bryce Lee18d51592017-10-25 10:22:19 -0700205 private final ActivityStackSupervisor mSupervisor;
Winson Chung1dbc8112017-09-28 18:05:31 -0700206
Bryce Lee18d51592017-10-25 10:22:19 -0700207 private ComponentName mComponent;
208 private String mPackage;
209 private int mFlags = 0;
210 private int mTaskId = 0;
Winson Chung0ec2a352017-10-26 11:38:30 -0700211 private int mUserId = 0;
Bryce Lee93e7f792017-10-25 15:54:55 -0700212 private IVoiceInteractionSession mVoiceSession;
Bryce Leeaf691c02017-03-20 14:20:22 -0700213
Bryce Lee18d51592017-10-25 10:22:19 -0700214 private ActivityStack mStack;
Bryce Leeaf691c02017-03-20 14:20:22 -0700215
Bryce Lee18d51592017-10-25 10:22:19 -0700216 TaskBuilder(ActivityStackSupervisor supervisor) {
217 mSupervisor = supervisor;
218 }
Bryce Leeaf691c02017-03-20 14:20:22 -0700219
Bryce Lee18d51592017-10-25 10:22:19 -0700220 TaskBuilder setComponent(ComponentName component) {
221 mComponent = component;
222 return this;
223 }
224
225 TaskBuilder setPackage(String packageName) {
226 mPackage = packageName;
227 return this;
228 }
229
Bryce Lee93e7f792017-10-25 15:54:55 -0700230 TaskBuilder setVoiceSession(IVoiceInteractionSession session) {
231 mVoiceSession = session;
232 return this;
233 }
234
Bryce Lee18d51592017-10-25 10:22:19 -0700235 TaskBuilder setFlags(int flags) {
236 mFlags = flags;
237 return this;
238 }
239
240 TaskBuilder setTaskId(int taskId) {
241 mTaskId = taskId;
242 return this;
243 }
244
Winson Chung0ec2a352017-10-26 11:38:30 -0700245 TaskBuilder setUserId(int userId) {
246 mUserId = userId;
247 return this;
248 }
249
Bryce Lee18d51592017-10-25 10:22:19 -0700250 TaskBuilder setStack(ActivityStack stack) {
251 mStack = stack;
252 return this;
253 }
254
255 TaskRecord build() {
256 if (mStack == null) {
257 mStack = mSupervisor.getDefaultDisplay().createStack(
258 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
259 }
260
261 final ActivityInfo aInfo = new ActivityInfo();
262 aInfo.applicationInfo = new ApplicationInfo();
263 aInfo.applicationInfo.packageName = mPackage;
264
265 Intent intent = new Intent();
Bryce Leefbd263b42018-03-07 10:33:55 -0800266 if (mComponent == null) {
267 mComponent = ComponentName.createRelative(DEFAULT_COMPONENT_PACKAGE_NAME,
268 DEFAULT_COMPONENT_CLASS_NAME);
269 }
270
Bryce Lee18d51592017-10-25 10:22:19 -0700271 intent.setComponent(mComponent);
272 intent.setFlags(mFlags);
273
274 final TaskRecord task = new TaskRecord(mSupervisor.mService, mTaskId, aInfo,
Bryce Lee93e7f792017-10-25 15:54:55 -0700275 intent /*intent*/, mVoiceSession, null /*_voiceInteractor*/);
Winson Chung0ec2a352017-10-26 11:38:30 -0700276 task.userId = mUserId;
Bryce Lee18d51592017-10-25 10:22:19 -0700277 mSupervisor.setFocusStackUnchecked("test", mStack);
278 mStack.addTask(task, true, "creating test task");
279 task.setStack(mStack);
280 task.setWindowContainerController(mock(TaskWindowContainerController.class));
Winson Chung0ec2a352017-10-26 11:38:30 -0700281 task.touchActiveTime();
Bryce Lee18d51592017-10-25 10:22:19 -0700282
283 return task;
284 }
Bryce Leeaf691c02017-03-20 14:20:22 -0700285 }
286
287 /**
288 * An {@link ActivityManagerService} subclass which provides a test
289 * {@link ActivityStackSupervisor}.
290 */
291 protected static class TestActivityManagerService extends ActivityManagerService {
Bryce Leeb0f993f2018-03-02 15:38:01 -0800292 private ClientLifecycleManager mLifecycleManager;
293
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700294 TestActivityManagerService(Context context) {
Bryce Leeaf691c02017-03-20 14:20:22 -0700295 super(context);
Bryce Lee04ab3462017-04-10 15:06:33 -0700296 mSupportsMultiWindow = true;
297 mSupportsMultiDisplay = true;
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700298 mSupportsSplitScreenMultiWindow = true;
299 mSupportsFreeformWindowManagement = true;
300 mSupportsPictureInPicture = true;
Bryce Lee6a0754a2017-10-10 17:53:50 -0700301 mWindowManager = WindowTestUtils.getMockWindowManagerService();
Bryce Leeaf691c02017-03-20 14:20:22 -0700302 }
303
304 @Override
Bryce Leeb0f993f2018-03-02 15:38:01 -0800305 public ClientLifecycleManager getLifecycleManager() {
306 if (mLifecycleManager == null) {
307 return super.getLifecycleManager();
308 }
309 return mLifecycleManager;
310 }
311
312 void setLifecycleManager(ClientLifecycleManager manager) {
313 mLifecycleManager = manager;
314 }
315
316 @Override
Bryce Lee2a3cc462017-10-27 10:57:35 -0700317 final protected ActivityStackSupervisor createStackSupervisor() {
318 final ActivityStackSupervisor supervisor = spy(createTestSupervisor());
319
320 // No home stack is set.
321 doNothing().when(supervisor).moveHomeStackToFront(any());
322 doReturn(true).when(supervisor).moveHomeStackTaskToTop(any());
323 // Invoked during {@link ActivityStack} creation.
324 doNothing().when(supervisor).updateUIDsPresentOnDisplay();
325 // Always keep things awake.
326 doReturn(true).when(supervisor).hasAwakeDisplay();
327 // Called when moving activity to pinned stack.
328 doNothing().when(supervisor).ensureActivitiesVisibleLocked(any(), anyInt(), anyBoolean());
329 // Do not schedule idle timeouts
330 doNothing().when(supervisor).scheduleIdleTimeoutLocked(any());
Bryce Leefbd263b42018-03-07 10:33:55 -0800331 // unit test version does not handle launch wake lock
332 doNothing().when(supervisor).acquireLaunchWakelock();
Bryce Lee2a3cc462017-10-27 10:57:35 -0700333
334 supervisor.initialize();
335
336 return supervisor;
337 }
338
339 protected ActivityStackSupervisor createTestSupervisor() {
Bryce Lee3115bdf2017-04-05 08:39:40 -0700340 return new TestActivityStackSupervisor(this, mHandlerThread.getLooper());
Bryce Leeaf691c02017-03-20 14:20:22 -0700341 }
Bryce Lee29a649d2017-08-18 13:52:31 -0700342
343 @Override
344 void updateUsageStats(ActivityRecord component, boolean resumed) {
345 }
Bryce Leeaf691c02017-03-20 14:20:22 -0700346 }
347
348 /**
349 * An {@link ActivityStackSupervisor} which stubs out certain methods that depend on
350 * setup not available in the test environment. Also specifies an injector for
351 */
352 protected static class TestActivityStackSupervisor extends ActivityStackSupervisor {
Bryce Lee2a3cc462017-10-27 10:57:35 -0700353 private ActivityDisplay mDisplay;
Bryce Lee943ebe72017-05-04 10:19:07 -0700354
Bryce Leeaf691c02017-03-20 14:20:22 -0700355 public TestActivityStackSupervisor(ActivityManagerService service, Looper looper) {
356 super(service, looper);
Wale Ogunwale9dcf9462017-09-19 15:13:01 -0700357 mDisplayManager =
358 (DisplayManager) mService.mContext.getSystemService(Context.DISPLAY_SERVICE);
Bryce Lee04ab3462017-04-10 15:06:33 -0700359 mWindowManager = prepareMockWindowManager();
Bryce Lee2a3cc462017-10-27 10:57:35 -0700360 }
361
362 @Override
363 public void initialize() {
364 super.initialize();
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700365 mDisplay = new TestActivityDisplay(this, DEFAULT_DISPLAY);
Wale Ogunwale9dcf9462017-09-19 15:13:01 -0700366 attachDisplay(mDisplay);
Bryce Lee04ab3462017-04-10 15:06:33 -0700367 }
368
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700369 @Override
370 ActivityDisplay getDefaultDisplay() {
371 return mDisplay;
372 }
373
Bryce Lee2a3cc462017-10-27 10:57:35 -0700374 // Just return the current front task. This is called internally so we cannot use spy to mock this out.
Bryce Lee04ab3462017-04-10 15:06:33 -0700375 @Override
376 ActivityStack getNextFocusableStackLocked(ActivityStack currentFocus) {
377 return mFocusedStack;
378 }
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700379 }
380
Winson Chung59a47ded2018-01-25 17:46:06 +0000381 protected static class TestActivityDisplay extends ActivityDisplay {
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700382
383 private final ActivityStackSupervisor mSupervisor;
384 TestActivityDisplay(ActivityStackSupervisor supervisor, int displayId) {
385 super(supervisor, displayId);
386 mSupervisor = supervisor;
Andrii Kulianb1cdb102017-07-13 15:33:06 -0700387 }
388
389 @Override
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700390 <T extends ActivityStack> T createStackUnchecked(int windowingMode, int activityType,
391 int stackId, boolean onTop) {
392 if (windowingMode == WINDOWING_MODE_PINNED) {
393 return (T) new PinnedActivityStack(this, stackId, mSupervisor, onTop) {
Andrii Kulianb1cdb102017-07-13 15:33:06 -0700394 @Override
395 Rect getDefaultPictureInPictureBounds(float aspectRatio) {
396 return new Rect(50, 50, 100, 100);
397 }
Bryce Lee4e4a3ec2017-09-27 08:25:03 -0700398
399 @Override
400 PinnedStackWindowController createStackWindowController(int displayId,
401 boolean onTop, Rect outBounds) {
402 return mock(PinnedStackWindowController.class);
403 }
Andrii Kulianb1cdb102017-07-13 15:33:06 -0700404 };
405 } else {
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700406 return (T) new TestActivityStack(
407 this, stackId, mSupervisor, windowingMode, activityType, onTop);
Andrii Kulianb1cdb102017-07-13 15:33:06 -0700408 }
Bryce Lee04ab3462017-04-10 15:06:33 -0700409 }
Winson Chung59a47ded2018-01-25 17:46:06 +0000410
411 @Override
412 protected DisplayWindowController createWindowContainerController() {
413 return mock(DisplayWindowController.class);
414 }
Bryce Leeaf691c02017-03-20 14:20:22 -0700415 }
416
Bryce Lee04ab3462017-04-10 15:06:33 -0700417 private static WindowManagerService prepareMockWindowManager() {
Bryce Lee4e4a3ec2017-09-27 08:25:03 -0700418 final WindowManagerService service = WindowTestUtils.getMockWindowManagerService();
Bryce Lee04ab3462017-04-10 15:06:33 -0700419
420 doAnswer((InvocationOnMock invocationOnMock) -> {
421 final Runnable runnable = invocationOnMock.<Runnable>getArgument(0);
422 if (runnable != null) {
423 runnable.run();
424 }
425 return null;
426 }).when(service).inSurfaceTransaction(any());
427
428 return service;
429 }
430
Bryce Leeaf691c02017-03-20 14:20:22 -0700431 /**
Bryce Lee4e4a3ec2017-09-27 08:25:03 -0700432 * Overrided of {@link ActivityStack} that tracks test metrics, such as the number of times a
Bryce Leeaf691c02017-03-20 14:20:22 -0700433 * method is called. Note that its functionality depends on the implementations of the
434 * construction arguments.
435 */
436 protected static class TestActivityStack<T extends StackWindowController>
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700437 extends ActivityStack<T> {
Bryce Leeaf691c02017-03-20 14:20:22 -0700438 private int mOnActivityRemovedFromStackCount = 0;
439 private T mContainerController;
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700440
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700441 static final int IS_TRANSLUCENT_UNSET = 0;
442 static final int IS_TRANSLUCENT_FALSE = 1;
443 static final int IS_TRANSLUCENT_TRUE = 2;
444 private int mIsTranslucent = IS_TRANSLUCENT_UNSET;
445
Wale Ogunwale30e441d2017-11-09 08:28:45 -0800446 static final int SUPPORTS_SPLIT_SCREEN_UNSET = 0;
447 static final int SUPPORTS_SPLIT_SCREEN_FALSE = 1;
448 static final int SUPPORTS_SPLIT_SCREEN_TRUE = 2;
449 private int mSupportsSplitScreen = SUPPORTS_SPLIT_SCREEN_UNSET;
450
Wale Ogunwale9dcf9462017-09-19 15:13:01 -0700451 TestActivityStack(ActivityDisplay display, int stackId, ActivityStackSupervisor supervisor,
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700452 int windowingMode, int activityType, boolean onTop) {
453 super(display, stackId, supervisor, windowingMode, activityType, onTop);
Bryce Leeaf691c02017-03-20 14:20:22 -0700454 }
455
456 @Override
457 void onActivityRemovedFromStack(ActivityRecord r) {
458 mOnActivityRemovedFromStackCount++;
459 super.onActivityRemovedFromStack(r);
460 }
461
462 // Returns the number of times {@link #onActivityRemovedFromStack} has been called
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700463 int onActivityRemovedFromStackInvocationCount() {
Bryce Leeaf691c02017-03-20 14:20:22 -0700464 return mOnActivityRemovedFromStackCount;
465 }
466
467 @Override
Wale Ogunwale034a8ec2017-09-02 17:14:40 -0700468 protected T createStackWindowController(int displayId, boolean onTop, Rect outBounds) {
Bryce Leeaf691c02017-03-20 14:20:22 -0700469 mContainerController = (T) WindowTestUtils.createMockStackWindowContainerController();
Bryce Leef3c6a472017-11-14 14:53:06 -0800470
471 // Primary pinned stacks require a non-empty out bounds to be set or else all tasks
472 // will be moved to the full screen stack.
473 if (getWindowingMode() == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
474 outBounds.set(0, 0, 100, 100);
475 }
Bryce Leeaf691c02017-03-20 14:20:22 -0700476 return mContainerController;
477 }
478
479 @Override
480 T getWindowContainerController() {
481 return mContainerController;
482 }
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700483
484 void setIsTranslucent(boolean isTranslucent) {
485 mIsTranslucent = isTranslucent ? IS_TRANSLUCENT_TRUE : IS_TRANSLUCENT_FALSE;
486 }
487
488 @Override
Wale Ogunwale66e16852017-10-19 13:35:52 -0700489 boolean isStackTranslucent(ActivityRecord starting) {
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700490 switch (mIsTranslucent) {
491 case IS_TRANSLUCENT_TRUE:
492 return true;
493 case IS_TRANSLUCENT_FALSE:
494 return false;
495 case IS_TRANSLUCENT_UNSET:
496 default:
Wale Ogunwale66e16852017-10-19 13:35:52 -0700497 return super.isStackTranslucent(starting);
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700498 }
499 }
Wale Ogunwale30e441d2017-11-09 08:28:45 -0800500
501 void setSupportsSplitScreen(boolean supportsSplitScreen) {
502 mSupportsSplitScreen = supportsSplitScreen
503 ? SUPPORTS_SPLIT_SCREEN_TRUE : SUPPORTS_SPLIT_SCREEN_FALSE;
504 }
505
506 @Override
507 public boolean supportsSplitScreenWindowingMode() {
508 switch (mSupportsSplitScreen) {
509 case SUPPORTS_SPLIT_SCREEN_TRUE:
510 return true;
511 case SUPPORTS_SPLIT_SCREEN_FALSE:
512 return false;
513 case SUPPORTS_SPLIT_SCREEN_UNSET:
514 default:
515 return super.supportsSplitScreenWindowingMode();
516 }
517 }
Bryce Leeaf691c02017-03-20 14:20:22 -0700518 }
Bryce Leeaf691c02017-03-20 14:20:22 -0700519}