blob: d9a346b6c589a3339e95b9add81b93993133fc2c [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;
Tadashi G. Takaokadee5a4d2018-09-19 11:59:40 +090024
Bryce Lee04ab3462017-04-10 15:06:33 -070025import static org.mockito.Mockito.any;
Bryce Lee2a3cc462017-10-27 10:57:35 -070026import static org.mockito.Mockito.anyBoolean;
27import static org.mockito.Mockito.anyInt;
Bryce Lee04ab3462017-04-10 15:06:33 -070028import static org.mockito.Mockito.doAnswer;
Tadashi G. Takaokadee5a4d2018-09-19 11:59:40 +090029import static org.mockito.Mockito.doNothing;
30import static org.mockito.Mockito.doReturn;
31import static org.mockito.Mockito.mock;
Bryce Lee4e4a3ec2017-09-27 08:25:03 -070032import static org.mockito.Mockito.spy;
Bryce Lee04ab3462017-04-10 15:06:33 -070033
Bryce Lee2b8e0372018-04-05 17:01:37 -070034import android.app.ActivityOptions;
Bryce Lee0bd8d422018-01-09 09:45:57 -080035import android.app.IApplicationThread;
Bryce Leeaf691c02017-03-20 14:20:22 -070036import android.content.ComponentName;
37import android.content.Context;
38import android.content.Intent;
39import android.content.pm.ActivityInfo;
40import android.content.pm.ApplicationInfo;
Bryce Leeba8f4422017-11-20 12:35:57 -080041import android.content.pm.IPackageManager;
Bryce Leeaf691c02017-03-20 14:20:22 -070042import android.content.res.Configuration;
43import android.graphics.Rect;
Wale Ogunwale9dcf9462017-09-19 15:13:01 -070044import android.hardware.display.DisplayManager;
Bryce Lee3115bdf2017-04-05 08:39:40 -070045import android.os.HandlerThread;
Bryce Leeaf691c02017-03-20 14:20:22 -070046import android.os.Looper;
Bryce Lee93e7f792017-10-25 15:54:55 -070047import android.service.voice.IVoiceInteractionSession;
Bryce Leeaf691c02017-03-20 14:20:22 -070048import android.support.test.InstrumentationRegistry;
Adrian Roos3150dbf2018-03-28 18:06:52 +020049import android.testing.DexmakerShareClassLoaderRule;
50
Bryce Lee2b8e0372018-04-05 17:01:37 -070051import com.android.internal.app.IVoiceInteractor;
Bryce Leeaf691c02017-03-20 14:20:22 -070052import com.android.server.AttributeCache;
53import com.android.server.wm.AppWindowContainerController;
Tadashi G. Takaokadee5a4d2018-09-19 11:59:40 +090054import com.android.server.wm.DisplayWindowController;
Bryce Lee4e4a3ec2017-09-27 08:25:03 -070055import com.android.server.wm.PinnedStackWindowController;
Bryce Leeaf691c02017-03-20 14:20:22 -070056import com.android.server.wm.StackWindowController;
Bryce Lee04ab3462017-04-10 15:06:33 -070057import com.android.server.wm.TaskWindowContainerController;
Bryce Leeaf691c02017-03-20 14:20:22 -070058import com.android.server.wm.WindowManagerService;
59import com.android.server.wm.WindowTestUtils;
Tadashi G. Takaokadee5a4d2018-09-19 11:59:40 +090060
Bryce Lee3115bdf2017-04-05 08:39:40 -070061import org.junit.After;
Bryce Leeaf691c02017-03-20 14:20:22 -070062import org.junit.Before;
Tadashi G. Takaokadee5a4d2018-09-19 11:59:40 +090063import org.junit.Rule;
Bryce Leeaf691c02017-03-20 14:20:22 -070064import org.mockito.MockitoAnnotations;
Tadashi G. Takaokadee5a4d2018-09-19 11:59:40 +090065import org.mockito.invocation.InvocationOnMock;
Bryce Lee2b8e0372018-04-05 17:01:37 -070066
Bryce Leeaf691c02017-03-20 14:20:22 -070067/**
68 * A base class to handle common operations in activity related unit tests.
69 */
70public class ActivityTestsBase {
Bryce Lee939a9a32017-10-23 10:01:21 -070071 private static boolean sOneTimeSetupDone = false;
72
Adrian Roos3150dbf2018-03-28 18:06:52 +020073 @Rule
74 public final DexmakerShareClassLoaderRule mDexmakerShareClassLoaderRule =
75 new DexmakerShareClassLoaderRule();
76
Bryce Leeaf691c02017-03-20 14:20:22 -070077 private final Context mContext = InstrumentationRegistry.getContext();
Bryce Lee3115bdf2017-04-05 08:39:40 -070078 private HandlerThread mHandlerThread;
Bryce Leeaf691c02017-03-20 14:20:22 -070079
Bryce Leefbd263b42018-03-07 10:33:55 -080080 // Default package name
81 static final String DEFAULT_COMPONENT_PACKAGE_NAME = "com.foo";
82
83 // Default base activity name
84 private static final String DEFAULT_COMPONENT_CLASS_NAME = ".BarActivity";
85
Bryce Leeaf691c02017-03-20 14:20:22 -070086 @Before
87 public void setUp() throws Exception {
Bryce Lee939a9a32017-10-23 10:01:21 -070088 if (!sOneTimeSetupDone) {
89 sOneTimeSetupDone = true;
Bryce Lee939a9a32017-10-23 10:01:21 -070090 MockitoAnnotations.initMocks(this);
91 }
Bryce Lee3115bdf2017-04-05 08:39:40 -070092 mHandlerThread = new HandlerThread("ActivityTestsBaseThread");
93 mHandlerThread.start();
94 }
Bryce Leeaf691c02017-03-20 14:20:22 -070095
Bryce Lee3115bdf2017-04-05 08:39:40 -070096 @After
97 public void tearDown() {
98 mHandlerThread.quitSafely();
Bryce Leeaf691c02017-03-20 14:20:22 -070099 }
100
101 protected ActivityManagerService createActivityManagerService() {
Bryce Lee93e7f792017-10-25 15:54:55 -0700102 final ActivityManagerService service =
103 setupActivityManagerService(new TestActivityManagerService(mContext));
104 AttributeCache.init(mContext);
105 return service;
Winson Chung3f0e59a2017-10-25 10:19:05 -0700106 }
107
108 protected ActivityManagerService setupActivityManagerService(ActivityManagerService service) {
109 service = spy(service);
Bryce Leeba8f4422017-11-20 12:35:57 -0800110 doReturn(mock(IPackageManager.class)).when(service).getPackageManager();
Bryce Leead5b8322018-03-08 14:28:52 -0800111 doNothing().when(service).grantEphemeralAccessLocked(anyInt(), any(), anyInt(), anyInt());
Bryce Lee4e4a3ec2017-09-27 08:25:03 -0700112 service.mWindowManager = prepareMockWindowManager();
Bryce Lee840c5662017-04-13 10:02:51 -0700113 return service;
Bryce Leeaf691c02017-03-20 14:20:22 -0700114 }
115
Bryce Lee18d51592017-10-25 10:22:19 -0700116 /**
117 * Builder for creating new activities.
118 */
119 protected static class ActivityBuilder {
120 // An id appended to the end of the component name to make it unique
121 private static int sCurrentActivityId = 0;
Bryce Lee9f6affd2017-09-01 09:18:35 -0700122
Bryce Leeaf691c02017-03-20 14:20:22 -0700123
Bryce Lee18d51592017-10-25 10:22:19 -0700124
125 private final ActivityManagerService mService;
126
127 private ComponentName mComponent;
128 private TaskRecord mTaskRecord;
129 private int mUid;
130 private boolean mCreateTask;
131 private ActivityStack mStack;
Bryce Leec961e0a2018-04-13 17:58:02 -0700132 private int mActivityFlags;
Bryce Lee18d51592017-10-25 10:22:19 -0700133
134 ActivityBuilder(ActivityManagerService service) {
135 mService = service;
Bryce Leeaf691c02017-03-20 14:20:22 -0700136 }
137
Bryce Lee18d51592017-10-25 10:22:19 -0700138 ActivityBuilder setComponent(ComponentName component) {
139 mComponent = component;
140 return this;
141 }
142
Bryce Leead5b8322018-03-08 14:28:52 -0800143 static ComponentName getDefaultComponent() {
144 return ComponentName.createRelative(DEFAULT_COMPONENT_PACKAGE_NAME,
145 DEFAULT_COMPONENT_PACKAGE_NAME);
146 }
147
Bryce Lee18d51592017-10-25 10:22:19 -0700148 ActivityBuilder setTask(TaskRecord task) {
149 mTaskRecord = task;
150 return this;
151 }
152
Bryce Leec961e0a2018-04-13 17:58:02 -0700153 ActivityBuilder setActivityFlags(int flags) {
154 mActivityFlags = flags;
155 return this;
156 }
157
Bryce Lee18d51592017-10-25 10:22:19 -0700158 ActivityBuilder setStack(ActivityStack stack) {
159 mStack = stack;
160 return this;
161 }
162
163 ActivityBuilder setCreateTask(boolean createTask) {
164 mCreateTask = createTask;
165 return this;
166 }
167
168 ActivityBuilder setUid(int uid) {
169 mUid = uid;
170 return this;
171 }
172
173 ActivityRecord build() {
174 if (mComponent == null) {
175 final int id = sCurrentActivityId++;
Bryce Leefbd263b42018-03-07 10:33:55 -0800176 mComponent = ComponentName.createRelative(DEFAULT_COMPONENT_PACKAGE_NAME,
177 DEFAULT_COMPONENT_CLASS_NAME + id);
Bryce Lee18d51592017-10-25 10:22:19 -0700178 }
179
180 if (mCreateTask) {
181 mTaskRecord = new TaskBuilder(mService.mStackSupervisor)
182 .setComponent(mComponent)
183 .setStack(mStack).build();
184 }
185
186 Intent intent = new Intent();
187 intent.setComponent(mComponent);
188 final ActivityInfo aInfo = new ActivityInfo();
189 aInfo.applicationInfo = new ApplicationInfo();
190 aInfo.applicationInfo.packageName = mComponent.getPackageName();
191 aInfo.applicationInfo.uid = mUid;
Bryce Leec961e0a2018-04-13 17:58:02 -0700192 aInfo.flags |= mActivityFlags;
193
Bryce Lee18d51592017-10-25 10:22:19 -0700194 final ActivityRecord activity = new ActivityRecord(mService, null /* caller */,
195 0 /* launchedFromPid */, 0, null, intent, null,
196 aInfo /*aInfo*/, new Configuration(), null /* resultTo */, null /* resultWho */,
197 0 /* reqCode */, false /*componentSpecified*/, false /* rootVoiceInteraction */,
198 mService.mStackSupervisor, null /* options */, null /* sourceRecord */);
199 activity.mWindowContainerController = mock(AppWindowContainerController.class);
200
201 if (mTaskRecord != null) {
202 mTaskRecord.addActivityToTop(activity);
203 }
204
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -0700205 activity.setProcess(new ProcessRecord(null, null,
206 mService.mContext.getApplicationInfo(), "name", 12345));
Bryce Lee0bd8d422018-01-09 09:45:57 -0800207 activity.app.thread = mock(IApplicationThread.class);
208
Bryce Lee18d51592017-10-25 10:22:19 -0700209 return activity;
210 }
Bryce Leeaf691c02017-03-20 14:20:22 -0700211 }
212
Bryce Lee18d51592017-10-25 10:22:19 -0700213 /**
214 * Builder for creating new tasks.
215 */
216 protected static class TaskBuilder {
Bryce Leefbd263b42018-03-07 10:33:55 -0800217 // Default package name
218 static final String DEFAULT_PACKAGE = "com.bar";
219
Bryce Lee18d51592017-10-25 10:22:19 -0700220 private final ActivityStackSupervisor mSupervisor;
Winson Chung1dbc8112017-09-28 18:05:31 -0700221
Bryce Lee18d51592017-10-25 10:22:19 -0700222 private ComponentName mComponent;
223 private String mPackage;
224 private int mFlags = 0;
225 private int mTaskId = 0;
Winson Chung0ec2a352017-10-26 11:38:30 -0700226 private int mUserId = 0;
Bryce Lee93e7f792017-10-25 15:54:55 -0700227 private IVoiceInteractionSession mVoiceSession;
Bryce Lee2b8e0372018-04-05 17:01:37 -0700228 private boolean mCreateStack = true;
Bryce Leeaf691c02017-03-20 14:20:22 -0700229
Bryce Lee18d51592017-10-25 10:22:19 -0700230 private ActivityStack mStack;
Bryce Leeaf691c02017-03-20 14:20:22 -0700231
Bryce Lee18d51592017-10-25 10:22:19 -0700232 TaskBuilder(ActivityStackSupervisor supervisor) {
233 mSupervisor = supervisor;
234 }
Bryce Leeaf691c02017-03-20 14:20:22 -0700235
Bryce Lee18d51592017-10-25 10:22:19 -0700236 TaskBuilder setComponent(ComponentName component) {
237 mComponent = component;
238 return this;
239 }
240
241 TaskBuilder setPackage(String packageName) {
242 mPackage = packageName;
243 return this;
244 }
245
Bryce Lee2b8e0372018-04-05 17:01:37 -0700246 /**
247 * Set to {@code true} by default, set to {@code false} to prevent the task from
248 * automatically creating a parent stack.
249 */
250 TaskBuilder setCreateStack(boolean createStack) {
251 mCreateStack = createStack;
252 return this;
253 }
254
Bryce Lee93e7f792017-10-25 15:54:55 -0700255 TaskBuilder setVoiceSession(IVoiceInteractionSession session) {
256 mVoiceSession = session;
257 return this;
258 }
259
Bryce Lee18d51592017-10-25 10:22:19 -0700260 TaskBuilder setFlags(int flags) {
261 mFlags = flags;
262 return this;
263 }
264
265 TaskBuilder setTaskId(int taskId) {
266 mTaskId = taskId;
267 return this;
268 }
269
Winson Chung0ec2a352017-10-26 11:38:30 -0700270 TaskBuilder setUserId(int userId) {
271 mUserId = userId;
272 return this;
273 }
274
Bryce Lee18d51592017-10-25 10:22:19 -0700275 TaskBuilder setStack(ActivityStack stack) {
276 mStack = stack;
277 return this;
278 }
279
280 TaskRecord build() {
Bryce Lee2b8e0372018-04-05 17:01:37 -0700281 if (mStack == null && mCreateStack) {
Bryce Lee18d51592017-10-25 10:22:19 -0700282 mStack = mSupervisor.getDefaultDisplay().createStack(
283 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
284 }
285
286 final ActivityInfo aInfo = new ActivityInfo();
287 aInfo.applicationInfo = new ApplicationInfo();
288 aInfo.applicationInfo.packageName = mPackage;
289
290 Intent intent = new Intent();
Bryce Leefbd263b42018-03-07 10:33:55 -0800291 if (mComponent == null) {
292 mComponent = ComponentName.createRelative(DEFAULT_COMPONENT_PACKAGE_NAME,
293 DEFAULT_COMPONENT_CLASS_NAME);
294 }
295
Bryce Lee18d51592017-10-25 10:22:19 -0700296 intent.setComponent(mComponent);
297 intent.setFlags(mFlags);
298
Bryce Lee2b8e0372018-04-05 17:01:37 -0700299 final TestTaskRecord task = new TestTaskRecord(mSupervisor.mService, mTaskId, aInfo,
Bryce Lee93e7f792017-10-25 15:54:55 -0700300 intent /*intent*/, mVoiceSession, null /*_voiceInteractor*/);
Winson Chung0ec2a352017-10-26 11:38:30 -0700301 task.userId = mUserId;
Bryce Lee2b8e0372018-04-05 17:01:37 -0700302
303 if (mStack != null) {
304 mSupervisor.setFocusStackUnchecked("test", mStack);
305 mStack.addTask(task, true, "creating test task");
306 task.setStack(mStack);
307 task.setWindowContainerController();
308 }
309
Winson Chung0ec2a352017-10-26 11:38:30 -0700310 task.touchActiveTime();
Bryce Lee18d51592017-10-25 10:22:19 -0700311
312 return task;
313 }
Bryce Lee2b8e0372018-04-05 17:01:37 -0700314
315 private static class TestTaskRecord extends TaskRecord {
316 TestTaskRecord(ActivityManagerService service, int _taskId, ActivityInfo info,
317 Intent _intent, IVoiceInteractionSession _voiceSession,
318 IVoiceInteractor _voiceInteractor) {
319 super(service, _taskId, info, _intent, _voiceSession, _voiceInteractor);
320 }
321
322 @Override
323 void createWindowContainer(boolean onTop, boolean showForAllUsers) {
324 setWindowContainerController();
325 }
326
327 private void setWindowContainerController() {
328 setWindowContainerController(mock(TaskWindowContainerController.class));
329 }
330 }
Bryce Leeaf691c02017-03-20 14:20:22 -0700331 }
332
333 /**
334 * An {@link ActivityManagerService} subclass which provides a test
335 * {@link ActivityStackSupervisor}.
336 */
337 protected static class TestActivityManagerService extends ActivityManagerService {
Bryce Leeb0f993f2018-03-02 15:38:01 -0800338 private ClientLifecycleManager mLifecycleManager;
Bryce Lee2b8e0372018-04-05 17:01:37 -0700339 private LockTaskController mLockTaskController;
Bryce Leeb0f993f2018-03-02 15:38:01 -0800340
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700341 TestActivityManagerService(Context context) {
Bryce Leeaf691c02017-03-20 14:20:22 -0700342 super(context);
Bryce Lee04ab3462017-04-10 15:06:33 -0700343 mSupportsMultiWindow = true;
344 mSupportsMultiDisplay = true;
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700345 mSupportsSplitScreenMultiWindow = true;
346 mSupportsFreeformWindowManagement = true;
347 mSupportsPictureInPicture = true;
Bryce Lee6a0754a2017-10-10 17:53:50 -0700348 mWindowManager = WindowTestUtils.getMockWindowManagerService();
Bryce Leeaf691c02017-03-20 14:20:22 -0700349 }
350
351 @Override
Bryce Leeb0f993f2018-03-02 15:38:01 -0800352 public ClientLifecycleManager getLifecycleManager() {
353 if (mLifecycleManager == null) {
354 return super.getLifecycleManager();
355 }
356 return mLifecycleManager;
357 }
358
Bryce Lee2b8e0372018-04-05 17:01:37 -0700359 public LockTaskController getLockTaskController() {
360 if (mLockTaskController == null) {
361 mLockTaskController = spy(super.getLockTaskController());
362 }
363
364 return mLockTaskController;
365 }
366
Bryce Leeb0f993f2018-03-02 15:38:01 -0800367 void setLifecycleManager(ClientLifecycleManager manager) {
368 mLifecycleManager = manager;
369 }
370
371 @Override
Bryce Lee2a3cc462017-10-27 10:57:35 -0700372 final protected ActivityStackSupervisor createStackSupervisor() {
373 final ActivityStackSupervisor supervisor = spy(createTestSupervisor());
Bryce Lee271617a2018-03-15 10:39:12 -0700374 final KeyguardController keyguardController = mock(KeyguardController.class);
Bryce Lee2a3cc462017-10-27 10:57:35 -0700375
376 // No home stack is set.
377 doNothing().when(supervisor).moveHomeStackToFront(any());
378 doReturn(true).when(supervisor).moveHomeStackTaskToTop(any());
379 // Invoked during {@link ActivityStack} creation.
380 doNothing().when(supervisor).updateUIDsPresentOnDisplay();
381 // Always keep things awake.
382 doReturn(true).when(supervisor).hasAwakeDisplay();
383 // Called when moving activity to pinned stack.
384 doNothing().when(supervisor).ensureActivitiesVisibleLocked(any(), anyInt(), anyBoolean());
385 // Do not schedule idle timeouts
386 doNothing().when(supervisor).scheduleIdleTimeoutLocked(any());
Bryce Leefbd263b42018-03-07 10:33:55 -0800387 // unit test version does not handle launch wake lock
388 doNothing().when(supervisor).acquireLaunchWakelock();
Bryce Lee271617a2018-03-15 10:39:12 -0700389 doReturn(keyguardController).when(supervisor).getKeyguardController();
Bryce Lee2a3cc462017-10-27 10:57:35 -0700390
391 supervisor.initialize();
392
393 return supervisor;
394 }
395
396 protected ActivityStackSupervisor createTestSupervisor() {
Bryce Lee3115bdf2017-04-05 08:39:40 -0700397 return new TestActivityStackSupervisor(this, mHandlerThread.getLooper());
Bryce Leeaf691c02017-03-20 14:20:22 -0700398 }
Bryce Lee29a649d2017-08-18 13:52:31 -0700399
400 @Override
401 void updateUsageStats(ActivityRecord component, boolean resumed) {
402 }
Bryce Leeaf691c02017-03-20 14:20:22 -0700403 }
404
405 /**
406 * An {@link ActivityStackSupervisor} which stubs out certain methods that depend on
407 * setup not available in the test environment. Also specifies an injector for
408 */
409 protected static class TestActivityStackSupervisor extends ActivityStackSupervisor {
Bryce Lee2a3cc462017-10-27 10:57:35 -0700410 private ActivityDisplay mDisplay;
Bryce Lee459c0622018-03-19 11:04:01 -0700411 private KeyguardController mKeyguardController;
Bryce Lee943ebe72017-05-04 10:19:07 -0700412
Bryce Leeaf691c02017-03-20 14:20:22 -0700413 public TestActivityStackSupervisor(ActivityManagerService service, Looper looper) {
414 super(service, looper);
Wale Ogunwale9dcf9462017-09-19 15:13:01 -0700415 mDisplayManager =
416 (DisplayManager) mService.mContext.getSystemService(Context.DISPLAY_SERVICE);
Bryce Lee04ab3462017-04-10 15:06:33 -0700417 mWindowManager = prepareMockWindowManager();
Bryce Lee459c0622018-03-19 11:04:01 -0700418 mKeyguardController = mock(KeyguardController.class);
Bryce Lee2a3cc462017-10-27 10:57:35 -0700419 }
420
421 @Override
422 public void initialize() {
423 super.initialize();
Bryce Lee459c0622018-03-19 11:04:01 -0700424 mDisplay = spy(new TestActivityDisplay(this, DEFAULT_DISPLAY));
Wale Ogunwale9dcf9462017-09-19 15:13:01 -0700425 attachDisplay(mDisplay);
Bryce Lee04ab3462017-04-10 15:06:33 -0700426 }
427
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700428 @Override
Bryce Lee459c0622018-03-19 11:04:01 -0700429 public KeyguardController getKeyguardController() {
430 return mKeyguardController;
431 }
432
433 @Override
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700434 ActivityDisplay getDefaultDisplay() {
435 return mDisplay;
436 }
437
Bryce Lee2a3cc462017-10-27 10:57:35 -0700438 // 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 -0700439 @Override
Wale Ogunwalee1f68ce2018-03-09 08:58:54 -0800440 ActivityStack getNextFocusableStackLocked(ActivityStack currentFocus,
441 boolean ignoreCurrent) {
Bryce Lee04ab3462017-04-10 15:06:33 -0700442 return mFocusedStack;
443 }
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700444 }
445
Winson Chung59a47ded2018-01-25 17:46:06 +0000446 protected static class TestActivityDisplay extends ActivityDisplay {
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700447
448 private final ActivityStackSupervisor mSupervisor;
449 TestActivityDisplay(ActivityStackSupervisor supervisor, int displayId) {
450 super(supervisor, displayId);
451 mSupervisor = supervisor;
Andrii Kulianb1cdb102017-07-13 15:33:06 -0700452 }
453
454 @Override
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700455 <T extends ActivityStack> T createStackUnchecked(int windowingMode, int activityType,
456 int stackId, boolean onTop) {
457 if (windowingMode == WINDOWING_MODE_PINNED) {
458 return (T) new PinnedActivityStack(this, stackId, mSupervisor, onTop) {
Andrii Kulianb1cdb102017-07-13 15:33:06 -0700459 @Override
460 Rect getDefaultPictureInPictureBounds(float aspectRatio) {
461 return new Rect(50, 50, 100, 100);
462 }
Bryce Lee4e4a3ec2017-09-27 08:25:03 -0700463
464 @Override
465 PinnedStackWindowController createStackWindowController(int displayId,
466 boolean onTop, Rect outBounds) {
467 return mock(PinnedStackWindowController.class);
468 }
Andrii Kulianb1cdb102017-07-13 15:33:06 -0700469 };
470 } else {
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700471 return (T) new TestActivityStack(
472 this, stackId, mSupervisor, windowingMode, activityType, onTop);
Andrii Kulianb1cdb102017-07-13 15:33:06 -0700473 }
Bryce Lee04ab3462017-04-10 15:06:33 -0700474 }
Winson Chung59a47ded2018-01-25 17:46:06 +0000475
476 @Override
477 protected DisplayWindowController createWindowContainerController() {
478 return mock(DisplayWindowController.class);
479 }
Bryce Leeaf691c02017-03-20 14:20:22 -0700480 }
481
Bryce Lee04ab3462017-04-10 15:06:33 -0700482 private static WindowManagerService prepareMockWindowManager() {
Bryce Lee4e4a3ec2017-09-27 08:25:03 -0700483 final WindowManagerService service = WindowTestUtils.getMockWindowManagerService();
Bryce Lee04ab3462017-04-10 15:06:33 -0700484
485 doAnswer((InvocationOnMock invocationOnMock) -> {
486 final Runnable runnable = invocationOnMock.<Runnable>getArgument(0);
487 if (runnable != null) {
488 runnable.run();
489 }
490 return null;
491 }).when(service).inSurfaceTransaction(any());
492
493 return service;
494 }
495
Bryce Leeaf691c02017-03-20 14:20:22 -0700496 /**
Bryce Lee2b8e0372018-04-05 17:01:37 -0700497 * Overridden {@link ActivityStack} that tracks test metrics, such as the number of times a
Bryce Leeaf691c02017-03-20 14:20:22 -0700498 * method is called. Note that its functionality depends on the implementations of the
499 * construction arguments.
500 */
501 protected static class TestActivityStack<T extends StackWindowController>
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700502 extends ActivityStack<T> {
Bryce Leeaf691c02017-03-20 14:20:22 -0700503 private int mOnActivityRemovedFromStackCount = 0;
504 private T mContainerController;
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700505
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700506 static final int IS_TRANSLUCENT_UNSET = 0;
507 static final int IS_TRANSLUCENT_FALSE = 1;
508 static final int IS_TRANSLUCENT_TRUE = 2;
509 private int mIsTranslucent = IS_TRANSLUCENT_UNSET;
510
Wale Ogunwale30e441d2017-11-09 08:28:45 -0800511 static final int SUPPORTS_SPLIT_SCREEN_UNSET = 0;
512 static final int SUPPORTS_SPLIT_SCREEN_FALSE = 1;
513 static final int SUPPORTS_SPLIT_SCREEN_TRUE = 2;
514 private int mSupportsSplitScreen = SUPPORTS_SPLIT_SCREEN_UNSET;
515
Wale Ogunwale9dcf9462017-09-19 15:13:01 -0700516 TestActivityStack(ActivityDisplay display, int stackId, ActivityStackSupervisor supervisor,
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700517 int windowingMode, int activityType, boolean onTop) {
518 super(display, stackId, supervisor, windowingMode, activityType, onTop);
Bryce Leeaf691c02017-03-20 14:20:22 -0700519 }
520
521 @Override
522 void onActivityRemovedFromStack(ActivityRecord r) {
523 mOnActivityRemovedFromStackCount++;
524 super.onActivityRemovedFromStack(r);
525 }
526
527 // Returns the number of times {@link #onActivityRemovedFromStack} has been called
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700528 int onActivityRemovedFromStackInvocationCount() {
Bryce Leeaf691c02017-03-20 14:20:22 -0700529 return mOnActivityRemovedFromStackCount;
530 }
531
532 @Override
Wale Ogunwale034a8ec2017-09-02 17:14:40 -0700533 protected T createStackWindowController(int displayId, boolean onTop, Rect outBounds) {
Bryce Leeaf691c02017-03-20 14:20:22 -0700534 mContainerController = (T) WindowTestUtils.createMockStackWindowContainerController();
Bryce Leef3c6a472017-11-14 14:53:06 -0800535
536 // Primary pinned stacks require a non-empty out bounds to be set or else all tasks
537 // will be moved to the full screen stack.
538 if (getWindowingMode() == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
539 outBounds.set(0, 0, 100, 100);
540 }
Bryce Leeaf691c02017-03-20 14:20:22 -0700541 return mContainerController;
542 }
543
544 @Override
545 T getWindowContainerController() {
546 return mContainerController;
547 }
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700548
549 void setIsTranslucent(boolean isTranslucent) {
550 mIsTranslucent = isTranslucent ? IS_TRANSLUCENT_TRUE : IS_TRANSLUCENT_FALSE;
551 }
552
553 @Override
Wale Ogunwale66e16852017-10-19 13:35:52 -0700554 boolean isStackTranslucent(ActivityRecord starting) {
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700555 switch (mIsTranslucent) {
556 case IS_TRANSLUCENT_TRUE:
557 return true;
558 case IS_TRANSLUCENT_FALSE:
559 return false;
560 case IS_TRANSLUCENT_UNSET:
561 default:
Wale Ogunwale66e16852017-10-19 13:35:52 -0700562 return super.isStackTranslucent(starting);
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700563 }
564 }
Wale Ogunwale30e441d2017-11-09 08:28:45 -0800565
566 void setSupportsSplitScreen(boolean supportsSplitScreen) {
567 mSupportsSplitScreen = supportsSplitScreen
568 ? SUPPORTS_SPLIT_SCREEN_TRUE : SUPPORTS_SPLIT_SCREEN_FALSE;
569 }
570
571 @Override
572 public boolean supportsSplitScreenWindowingMode() {
573 switch (mSupportsSplitScreen) {
574 case SUPPORTS_SPLIT_SCREEN_TRUE:
575 return true;
576 case SUPPORTS_SPLIT_SCREEN_FALSE:
577 return false;
578 case SUPPORTS_SPLIT_SCREEN_UNSET:
579 default:
580 return super.supportsSplitScreenWindowingMode();
581 }
582 }
Bryce Lee2b8e0372018-04-05 17:01:37 -0700583
584 @Override
585 void startActivityLocked(ActivityRecord r, ActivityRecord focusedTopActivity,
586 boolean newTask, boolean keepCurTransition,
587 ActivityOptions options) {
588 }
Bryce Leeaf691c02017-03-20 14:20:22 -0700589 }
Bryce Leeaf691c02017-03-20 14:20:22 -0700590}