blob: 3bf0e5ff86aa0bfdaee5274490ff41d28645c743 [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
19import static org.mockito.Mockito.mock;
20
Bryce Lee840c5662017-04-13 10:02:51 -070021import android.app.ActivityManager;
Bryce Leeaf691c02017-03-20 14:20:22 -070022import android.content.ComponentName;
23import android.content.Context;
24import android.content.Intent;
25import android.content.pm.ActivityInfo;
26import android.content.pm.ApplicationInfo;
27import android.content.res.Configuration;
28import android.graphics.Rect;
Bryce Lee3115bdf2017-04-05 08:39:40 -070029import android.os.HandlerThread;
Bryce Leeaf691c02017-03-20 14:20:22 -070030import android.os.Looper;
31import android.support.test.InstrumentationRegistry;
32import com.android.server.AttributeCache;
33import com.android.server.wm.AppWindowContainerController;
34import com.android.server.wm.StackWindowController;
35
36import com.android.server.wm.WindowManagerService;
37import com.android.server.wm.WindowTestUtils;
Bryce Lee3115bdf2017-04-05 08:39:40 -070038import org.junit.After;
Bryce Leeaf691c02017-03-20 14:20:22 -070039import org.junit.Before;
40import org.mockito.MockitoAnnotations;
41
42/**
43 * A base class to handle common operations in activity related unit tests.
44 */
45public class ActivityTestsBase {
46 private final Context mContext = InstrumentationRegistry.getContext();
Bryce Lee3115bdf2017-04-05 08:39:40 -070047 private HandlerThread mHandlerThread;
Bryce Leeaf691c02017-03-20 14:20:22 -070048
49 // Grabbing an instance of {@link WindowManagerService} creates it if not present so this must
50 // be called at before any tests.
51 private final WindowManagerService mWms = WindowTestUtils.getWindowManagerService(mContext);
52
53 @Before
54 public void setUp() throws Exception {
55 MockitoAnnotations.initMocks(this);
Bryce Lee3115bdf2017-04-05 08:39:40 -070056 mHandlerThread = new HandlerThread("ActivityTestsBaseThread");
57 mHandlerThread.start();
58 }
Bryce Leeaf691c02017-03-20 14:20:22 -070059
Bryce Lee3115bdf2017-04-05 08:39:40 -070060 @After
61 public void tearDown() {
62 mHandlerThread.quitSafely();
Bryce Leeaf691c02017-03-20 14:20:22 -070063 }
64
65 protected ActivityManagerService createActivityManagerService() {
Bryce Lee840c5662017-04-13 10:02:51 -070066 final ActivityManagerService service = new TestActivityManagerService(mContext);
67 service.mWindowManager = WindowTestUtils.getWindowManagerService(mContext);
68 return service;
Bryce Leeaf691c02017-03-20 14:20:22 -070069 }
70
71 protected static TestActivityStack createActivityStack(ActivityManagerService service,
72 int stackId, int displayId, boolean onTop) {
73 if (service.mStackSupervisor instanceof TestActivityStackSupervisor) {
74 final TestActivityStack stack = ((TestActivityStackSupervisor) service.mStackSupervisor)
Bryce Lee840c5662017-04-13 10:02:51 -070075 .createTestStack(service, stackId, onTop);
Bryce Leeaf691c02017-03-20 14:20:22 -070076 return stack;
77 }
78
79 return null;
80 }
81
82 protected static ActivityRecord createActivity(ActivityManagerService service,
83 ComponentName component, TaskRecord task) {
84 Intent intent = new Intent();
85 intent.setComponent(component);
86 final ActivityInfo aInfo = new ActivityInfo();
87 aInfo.applicationInfo = new ApplicationInfo();
88 aInfo.applicationInfo.packageName = component.getPackageName();
89 AttributeCache.init(service.mContext);
90 final ActivityRecord activity = new ActivityRecord(service, null /* caller */,
91 0 /* launchedFromPid */, 0, null, intent, null,
92 aInfo /*aInfo*/, new Configuration(), null /* resultTo */, null /* resultWho */,
93 0 /* reqCode */, false /*componentSpecified*/, false /* rootVoiceInteraction */,
94 service.mStackSupervisor, null /* container */, null /* options */,
95 null /* sourceRecord */);
96 activity.mWindowContainerController = mock(AppWindowContainerController.class);
97
98 if (task != null) {
99 task.addActivityToTop(activity);
100 }
101
102 return activity;
103 }
104
105 protected static TaskRecord createTask(ActivityManagerService service,
106 ComponentName component, ActivityStack stack) {
107 final ActivityInfo aInfo = new ActivityInfo();
108 aInfo.applicationInfo = new ApplicationInfo();
109 aInfo.applicationInfo.packageName = component.getPackageName();
110
111 Intent intent = new Intent();
112 intent.setComponent(component);
113
114 final TaskRecord task = new TaskRecord(service, 0, aInfo, intent /*intent*/,
Bryce Lee840c5662017-04-13 10:02:51 -0700115 null /*_taskDescription*/, new ActivityManager.TaskThumbnailInfo());
Bryce Leeaf691c02017-03-20 14:20:22 -0700116 stack.addTask(task, true, "creating test task");
117 task.setStack(stack);
118 task.createWindowContainer(true, true);
119
120 return task;
121 }
122
123 /**
124 * An {@link ActivityManagerService} subclass which provides a test
125 * {@link ActivityStackSupervisor}.
126 */
127 protected static class TestActivityManagerService extends ActivityManagerService {
128 public TestActivityManagerService(Context context) {
129 super(context);
130 }
131
132 @Override
133 protected ActivityStackSupervisor createStackSupervisor() {
Bryce Lee3115bdf2017-04-05 08:39:40 -0700134 return new TestActivityStackSupervisor(this, mHandlerThread.getLooper());
Bryce Leeaf691c02017-03-20 14:20:22 -0700135 }
136 }
137
138 /**
139 * An {@link ActivityStackSupervisor} which stubs out certain methods that depend on
140 * setup not available in the test environment. Also specifies an injector for
141 */
142 protected static class TestActivityStackSupervisor extends ActivityStackSupervisor {
143 public TestActivityStackSupervisor(ActivityManagerService service, Looper looper) {
144 super(service, looper);
145 }
146
147 // Invoked during {@link ActivityStack} creation.
148 @Override
149 void updateUIDsPresentOnDisplay() {
150 }
151
Bryce Lee840c5662017-04-13 10:02:51 -0700152 public TestActivityStack createTestStack(ActivityManagerService service, int stackId,
153 boolean onTop) {
Bryce Leeaf691c02017-03-20 14:20:22 -0700154 final ActivityDisplay display = new ActivityDisplay();
155 final TestActivityContainer container =
Bryce Lee840c5662017-04-13 10:02:51 -0700156 new TestActivityContainer(service, stackId, display, onTop);
Bryce Leeaf691c02017-03-20 14:20:22 -0700157 return container.getStack();
158 }
159
160 private class TestActivityContainer extends ActivityContainer {
Bryce Lee840c5662017-04-13 10:02:51 -0700161 private ActivityManagerService mService;
Bryce Leeaf691c02017-03-20 14:20:22 -0700162 private TestActivityStack mStack;
Bryce Lee840c5662017-04-13 10:02:51 -0700163 private boolean mOnTop;
164
165 TestActivityContainer(ActivityManagerService service, int stackId,
166 ActivityDisplay activityDisplay, boolean onTop) {
Bryce Leeaf691c02017-03-20 14:20:22 -0700167 super(stackId, activityDisplay, onTop);
Bryce Lee840c5662017-04-13 10:02:51 -0700168 mService = service;
Bryce Leeaf691c02017-03-20 14:20:22 -0700169 }
170
171 @Override
172 protected void createStack(int stackId, boolean onTop) {
Bryce Lee840c5662017-04-13 10:02:51 -0700173 // normally stack creation is done here. However we need to do it on demand since
174 // we cannot set {@link mService} by the time the super constructor calling this
175 // method is invoked.
176 mOnTop = onTop;
Bryce Leeaf691c02017-03-20 14:20:22 -0700177 }
178
179 public TestActivityStack getStack() {
Bryce Lee840c5662017-04-13 10:02:51 -0700180 if (mStack == null) {
181 mStack = new TestActivityStack(this,
182 new RecentTasks(mService, mService.mStackSupervisor), mOnTop);
183 }
184
Bryce Leeaf691c02017-03-20 14:20:22 -0700185 return mStack;
186 }
187 }
188 }
189
190 /**
191 * Override of {@link ActivityStack} that tracks test metrics, such as the number of times a
192 * method is called. Note that its functionality depends on the implementations of the
193 * construction arguments.
194 */
195 protected static class TestActivityStack<T extends StackWindowController>
196 extends ActivityStack<T> {
197 private int mOnActivityRemovedFromStackCount = 0;
198 private T mContainerController;
199 TestActivityStack(ActivityStackSupervisor.ActivityContainer activityContainer,
200 RecentTasks recentTasks, boolean onTop) {
201 super(activityContainer, recentTasks, onTop);
202 }
203
204 @Override
205 void onActivityRemovedFromStack(ActivityRecord r) {
206 mOnActivityRemovedFromStackCount++;
207 super.onActivityRemovedFromStack(r);
208 }
209
210 // Returns the number of times {@link #onActivityRemovedFromStack} has been called
211 public int onActivityRemovedFromStackInvocationCount() {
212 return mOnActivityRemovedFromStackCount;
213 }
214
215 @Override
216 protected T createStackWindowController(int displayId, boolean onTop,
217 Rect outBounds) {
218 mContainerController = (T) WindowTestUtils.createMockStackWindowContainerController();
219 return mContainerController;
220 }
221
222 @Override
223 T getWindowContainerController() {
224 return mContainerController;
225 }
226 }
227
228 protected static class ActivityStackBuilder {
229 private boolean mOnTop = true;
230 private int mStackId = 0;
231 private int mDisplayId = 1;
232
233 private final ActivityManagerService mService;
234
235 public ActivityStackBuilder(ActivityManagerService ams) {
236 mService = ams;
237 }
238
239 public ActivityStackBuilder setOnTop(boolean onTop) {
240 mOnTop = onTop;
241 return this;
242 }
243
244 public ActivityStackBuilder setStackId(int id) {
245 mStackId = id;
246 return this;
247 }
248
249 public ActivityStackBuilder setDisplayId(int id) {
250 mDisplayId = id;
251 return this;
252 }
253
254 public TestActivityStack build() {
255 return createActivityStack(mService, mStackId, mDisplayId, mOnTop);
256 }
257 }
258}