blob: a6c0cf17bd057529175df0bae6027583ef266d8f [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
Andrii Kulian94e82d9b02017-07-13 15:33:06 -070019import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
Bryce Leeaf691c02017-03-20 14:20:22 -070020import static org.mockito.Mockito.mock;
Bryce Lee04ab3462017-04-10 15:06:33 -070021import static org.mockito.Mockito.doReturn;
22import static org.mockito.Mockito.any;
23import static org.mockito.Mockito.doAnswer;
24
25import org.mockito.invocation.InvocationOnMock;
Bryce Leeaf691c02017-03-20 14:20:22 -070026
Bryce Lee840c5662017-04-13 10:02:51 -070027import android.app.ActivityManager;
Bryce Leeaf691c02017-03-20 14:20:22 -070028import android.content.ComponentName;
29import android.content.Context;
30import android.content.Intent;
31import android.content.pm.ActivityInfo;
32import android.content.pm.ApplicationInfo;
33import android.content.res.Configuration;
34import android.graphics.Rect;
Bryce Lee3115bdf2017-04-05 08:39:40 -070035import android.os.HandlerThread;
Bryce Leeaf691c02017-03-20 14:20:22 -070036import android.os.Looper;
37import android.support.test.InstrumentationRegistry;
38import com.android.server.AttributeCache;
39import com.android.server.wm.AppWindowContainerController;
40import com.android.server.wm.StackWindowController;
41
Bryce Lee04ab3462017-04-10 15:06:33 -070042import com.android.server.wm.TaskWindowContainerController;
Bryce Leeaf691c02017-03-20 14:20:22 -070043import com.android.server.wm.WindowManagerService;
44import com.android.server.wm.WindowTestUtils;
Bryce Lee3115bdf2017-04-05 08:39:40 -070045import org.junit.After;
Bryce Leeaf691c02017-03-20 14:20:22 -070046import org.junit.Before;
47import org.mockito.MockitoAnnotations;
48
49/**
50 * A base class to handle common operations in activity related unit tests.
51 */
52public class ActivityTestsBase {
53 private final Context mContext = InstrumentationRegistry.getContext();
Bryce Lee3115bdf2017-04-05 08:39:40 -070054 private HandlerThread mHandlerThread;
Bryce Leeaf691c02017-03-20 14:20:22 -070055
56 // Grabbing an instance of {@link WindowManagerService} creates it if not present so this must
57 // be called at before any tests.
58 private final WindowManagerService mWms = WindowTestUtils.getWindowManagerService(mContext);
59
60 @Before
61 public void setUp() throws Exception {
62 MockitoAnnotations.initMocks(this);
Bryce Lee3115bdf2017-04-05 08:39:40 -070063 mHandlerThread = new HandlerThread("ActivityTestsBaseThread");
64 mHandlerThread.start();
65 }
Bryce Leeaf691c02017-03-20 14:20:22 -070066
Bryce Lee3115bdf2017-04-05 08:39:40 -070067 @After
68 public void tearDown() {
69 mHandlerThread.quitSafely();
Bryce Leeaf691c02017-03-20 14:20:22 -070070 }
71
72 protected ActivityManagerService createActivityManagerService() {
Bryce Lee840c5662017-04-13 10:02:51 -070073 final ActivityManagerService service = new TestActivityManagerService(mContext);
Bryce Lee04ab3462017-04-10 15:06:33 -070074 service.mWindowManager = WindowTestUtils.getMockWindowManagerService();
Bryce Lee840c5662017-04-13 10:02:51 -070075 return service;
Bryce Leeaf691c02017-03-20 14:20:22 -070076 }
77
Bryce Lee04ab3462017-04-10 15:06:33 -070078 protected static ActivityStack createActivityStack(ActivityManagerService service,
Bryce Leeaf691c02017-03-20 14:20:22 -070079 int stackId, int displayId, boolean onTop) {
80 if (service.mStackSupervisor instanceof TestActivityStackSupervisor) {
Bryce Lee04ab3462017-04-10 15:06:33 -070081 return ((TestActivityStackSupervisor) service.mStackSupervisor)
Andrii Kulian94e82d9b02017-07-13 15:33:06 -070082 .createTestStack(stackId, onTop);
Bryce Leeaf691c02017-03-20 14:20:22 -070083 }
84
85 return null;
86 }
87
88 protected static ActivityRecord createActivity(ActivityManagerService service,
89 ComponentName component, TaskRecord task) {
Bryce Lee9f6affd2017-09-01 09:18:35 -070090 return createActivity(service, component, task, 0 /* userId */);
91 }
92
93 protected static ActivityRecord createActivity(ActivityManagerService service,
94 ComponentName component, TaskRecord task, int uid) {
Bryce Leeaf691c02017-03-20 14:20:22 -070095 Intent intent = new Intent();
96 intent.setComponent(component);
97 final ActivityInfo aInfo = new ActivityInfo();
98 aInfo.applicationInfo = new ApplicationInfo();
99 aInfo.applicationInfo.packageName = component.getPackageName();
Bryce Lee9f6affd2017-09-01 09:18:35 -0700100 aInfo.applicationInfo.uid = uid;
Bryce Leeaf691c02017-03-20 14:20:22 -0700101 AttributeCache.init(service.mContext);
102 final ActivityRecord activity = new ActivityRecord(service, null /* caller */,
103 0 /* launchedFromPid */, 0, null, intent, null,
104 aInfo /*aInfo*/, new Configuration(), null /* resultTo */, null /* resultWho */,
105 0 /* reqCode */, false /*componentSpecified*/, false /* rootVoiceInteraction */,
Andrii Kulian94e82d9b02017-07-13 15:33:06 -0700106 service.mStackSupervisor, null /* options */, null /* sourceRecord */);
Bryce Leeaf691c02017-03-20 14:20:22 -0700107 activity.mWindowContainerController = mock(AppWindowContainerController.class);
108
109 if (task != null) {
110 task.addActivityToTop(activity);
111 }
112
113 return activity;
114 }
115
116 protected static TaskRecord createTask(ActivityManagerService service,
Bryce Lee04ab3462017-04-10 15:06:33 -0700117 ComponentName component, int stackId) {
Bryce Leeaf691c02017-03-20 14:20:22 -0700118 final ActivityInfo aInfo = new ActivityInfo();
119 aInfo.applicationInfo = new ApplicationInfo();
120 aInfo.applicationInfo.packageName = component.getPackageName();
121
122 Intent intent = new Intent();
123 intent.setComponent(component);
124
125 final TaskRecord task = new TaskRecord(service, 0, aInfo, intent /*intent*/,
Bryce Lee840c5662017-04-13 10:02:51 -0700126 null /*_taskDescription*/, new ActivityManager.TaskThumbnailInfo());
Bryce Lee04ab3462017-04-10 15:06:33 -0700127 final ActivityStack stack = service.mStackSupervisor.getStack(stackId,
128 true /*createStaticStackIfNeeded*/, true /*onTop*/);
Andrii Kulian3a1619d2017-07-07 14:38:09 -0700129 service.mStackSupervisor.setFocusStackUnchecked("test", stack);
Bryce Leeaf691c02017-03-20 14:20:22 -0700130 stack.addTask(task, true, "creating test task");
131 task.setStack(stack);
Bryce Lee04ab3462017-04-10 15:06:33 -0700132 task.setWindowContainerController(mock(TaskWindowContainerController.class));
Bryce Leeaf691c02017-03-20 14:20:22 -0700133
134 return task;
135 }
136
Bryce Lee04ab3462017-04-10 15:06:33 -0700137
Bryce Leeaf691c02017-03-20 14:20:22 -0700138 /**
139 * An {@link ActivityManagerService} subclass which provides a test
140 * {@link ActivityStackSupervisor}.
141 */
142 protected static class TestActivityManagerService extends ActivityManagerService {
143 public TestActivityManagerService(Context context) {
144 super(context);
Bryce Lee04ab3462017-04-10 15:06:33 -0700145 mSupportsMultiWindow = true;
146 mSupportsMultiDisplay = true;
147 mWindowManager = WindowTestUtils.getWindowManagerService(context);
Bryce Leeaf691c02017-03-20 14:20:22 -0700148 }
149
150 @Override
151 protected ActivityStackSupervisor createStackSupervisor() {
Bryce Lee3115bdf2017-04-05 08:39:40 -0700152 return new TestActivityStackSupervisor(this, mHandlerThread.getLooper());
Bryce Leeaf691c02017-03-20 14:20:22 -0700153 }
Bryce Lee29a649d2017-08-18 13:52:31 -0700154
155 @Override
156 void updateUsageStats(ActivityRecord component, boolean resumed) {
157 }
Bryce Leeaf691c02017-03-20 14:20:22 -0700158 }
159
160 /**
161 * An {@link ActivityStackSupervisor} which stubs out certain methods that depend on
162 * setup not available in the test environment. Also specifies an injector for
163 */
164 protected static class TestActivityStackSupervisor extends ActivityStackSupervisor {
Bryce Lee943ebe72017-05-04 10:19:07 -0700165 private final ActivityDisplay mDisplay;
166
Bryce Leeaf691c02017-03-20 14:20:22 -0700167 public TestActivityStackSupervisor(ActivityManagerService service, Looper looper) {
168 super(service, looper);
Bryce Lee04ab3462017-04-10 15:06:33 -0700169 mWindowManager = prepareMockWindowManager();
Bryce Lee943ebe72017-05-04 10:19:07 -0700170 mDisplay = new ActivityDisplay();
Bryce Lee04ab3462017-04-10 15:06:33 -0700171 }
172
173 // No home stack is set.
174 @Override
175 void moveHomeStackToFront(String reason) {
Bryce Leeaf691c02017-03-20 14:20:22 -0700176 }
177
Bryce Lee3345c4e2017-04-25 07:40:41 -0700178 @Override
179 boolean moveHomeStackTaskToTop(String reason) {
180 return true;
181 }
182
Bryce Leeaf691c02017-03-20 14:20:22 -0700183 // Invoked during {@link ActivityStack} creation.
184 @Override
185 void updateUIDsPresentOnDisplay() {
186 }
187
Bryce Lee04ab3462017-04-10 15:06:33 -0700188 // Just return the current front task.
189 @Override
190 ActivityStack getNextFocusableStackLocked(ActivityStack currentFocus) {
191 return mFocusedStack;
192 }
193
194 // Called when moving activity to pinned stack.
195 @Override
196 void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges,
197 boolean preserveWindows) {
198 }
199
Andrii Kulian94e82d9b02017-07-13 15:33:06 -0700200 <T extends ActivityStack> T createTestStack(int stackId, boolean onTop) {
201 return (T) createStack(stackId, mDisplay, onTop);
202 }
203
204 @Override
205 ActivityStack createStack(int stackId, ActivityDisplay display, boolean onTop) {
206 final RecentTasks recents =
207 new RecentTasks(mService, mService.mStackSupervisor);
208 if (stackId == PINNED_STACK_ID) {
209 return new PinnedActivityStack(display, stackId, this, recents, onTop) {
210 @Override
211 Rect getDefaultPictureInPictureBounds(float aspectRatio) {
212 return new Rect(50, 50, 100, 100);
213 }
214 };
215 } else {
216 return new TestActivityStack(display, stackId, this, recents, onTop);
217 }
Bryce Lee04ab3462017-04-10 15:06:33 -0700218 }
219
220 @Override
221 protected <T extends ActivityStack> T getStack(int stackId,
222 boolean createStaticStackIfNeeded, boolean createOnTop) {
223 final T stack = super.getStack(stackId, createStaticStackIfNeeded, createOnTop);
224
225 if (stack != null || !createStaticStackIfNeeded) {
226 return stack;
227 }
228
Andrii Kulian94e82d9b02017-07-13 15:33:06 -0700229 return createTestStack(stackId, createOnTop);
Bryce Leeaf691c02017-03-20 14:20:22 -0700230 }
David Stevensf62360c2017-03-16 19:00:20 -0700231
232 // Always keep things awake
233 @Override
234 boolean hasAwakeDisplay() {
235 return true;
236 }
Bryce Leeaf691c02017-03-20 14:20:22 -0700237 }
238
Bryce Lee04ab3462017-04-10 15:06:33 -0700239 private static WindowManagerService prepareMockWindowManager() {
240 final WindowManagerService service = mock(WindowManagerService.class);
241
242 doAnswer((InvocationOnMock invocationOnMock) -> {
243 final Runnable runnable = invocationOnMock.<Runnable>getArgument(0);
244 if (runnable != null) {
245 runnable.run();
246 }
247 return null;
248 }).when(service).inSurfaceTransaction(any());
249
250 return service;
251 }
252
253 protected interface ActivityStackReporter {
254 int onActivityRemovedFromStackInvocationCount();
255 }
256
Bryce Leeaf691c02017-03-20 14:20:22 -0700257 /**
258 * Override of {@link ActivityStack} that tracks test metrics, such as the number of times a
259 * method is called. Note that its functionality depends on the implementations of the
260 * construction arguments.
261 */
262 protected static class TestActivityStack<T extends StackWindowController>
Bryce Lee04ab3462017-04-10 15:06:33 -0700263 extends ActivityStack<T> implements ActivityStackReporter {
Bryce Leeaf691c02017-03-20 14:20:22 -0700264 private int mOnActivityRemovedFromStackCount = 0;
265 private T mContainerController;
Andrii Kulian94e82d9b02017-07-13 15:33:06 -0700266 TestActivityStack(ActivityStackSupervisor.ActivityDisplay display, int stackId,
267 ActivityStackSupervisor supervisor, RecentTasks recentTasks, boolean onTop) {
268 super(display, stackId, supervisor, recentTasks, onTop);
Bryce Leeaf691c02017-03-20 14:20:22 -0700269 }
270
271 @Override
272 void onActivityRemovedFromStack(ActivityRecord r) {
273 mOnActivityRemovedFromStackCount++;
274 super.onActivityRemovedFromStack(r);
275 }
276
277 // Returns the number of times {@link #onActivityRemovedFromStack} has been called
Bryce Lee04ab3462017-04-10 15:06:33 -0700278 @Override
Bryce Leeaf691c02017-03-20 14:20:22 -0700279 public int onActivityRemovedFromStackInvocationCount() {
280 return mOnActivityRemovedFromStackCount;
281 }
282
283 @Override
284 protected T createStackWindowController(int displayId, boolean onTop,
285 Rect outBounds) {
286 mContainerController = (T) WindowTestUtils.createMockStackWindowContainerController();
287 return mContainerController;
288 }
289
290 @Override
291 T getWindowContainerController() {
292 return mContainerController;
293 }
294 }
295
Bryce Lee04ab3462017-04-10 15:06:33 -0700296
Bryce Leeaf691c02017-03-20 14:20:22 -0700297 protected static class ActivityStackBuilder {
298 private boolean mOnTop = true;
299 private int mStackId = 0;
300 private int mDisplayId = 1;
301
302 private final ActivityManagerService mService;
303
304 public ActivityStackBuilder(ActivityManagerService ams) {
305 mService = ams;
306 }
307
308 public ActivityStackBuilder setOnTop(boolean onTop) {
309 mOnTop = onTop;
310 return this;
311 }
312
313 public ActivityStackBuilder setStackId(int id) {
314 mStackId = id;
315 return this;
316 }
317
318 public ActivityStackBuilder setDisplayId(int id) {
319 mDisplayId = id;
320 return this;
321 }
322
Bryce Lee04ab3462017-04-10 15:06:33 -0700323 public ActivityStack build() {
Bryce Leeaf691c02017-03-20 14:20:22 -0700324 return createActivityStack(mService, mStackId, mDisplayId, mOnTop);
325 }
326 }
327}