blob: b4db4a3a679ddb40fb7eebaf35c1702e6f61b4a3 [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
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070019import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
Wale Ogunwale9dcf9462017-09-19 15:13:01 -070020import static android.view.Display.DEFAULT_DISPLAY;
Bryce Leeaf691c02017-03-20 14:20:22 -070021import static org.mockito.Mockito.mock;
Bryce Lee04ab3462017-04-10 15:06:33 -070022import static org.mockito.Mockito.doReturn;
23import static org.mockito.Mockito.any;
24import static org.mockito.Mockito.doAnswer;
Bryce Lee4e4a3ec2017-09-27 08:25:03 -070025import static org.mockito.Mockito.spy;
Bryce Lee04ab3462017-04-10 15:06:33 -070026
27import org.mockito.invocation.InvocationOnMock;
Bryce Leeaf691c02017-03-20 14:20:22 -070028
29import android.content.ComponentName;
30import android.content.Context;
31import android.content.Intent;
32import android.content.pm.ActivityInfo;
33import android.content.pm.ApplicationInfo;
34import android.content.res.Configuration;
35import android.graphics.Rect;
Wale Ogunwale9dcf9462017-09-19 15:13:01 -070036import android.hardware.display.DisplayManager;
Bryce Lee3115bdf2017-04-05 08:39:40 -070037import android.os.HandlerThread;
Bryce Leeaf691c02017-03-20 14:20:22 -070038import android.os.Looper;
39import android.support.test.InstrumentationRegistry;
40import com.android.server.AttributeCache;
41import com.android.server.wm.AppWindowContainerController;
Bryce Lee4e4a3ec2017-09-27 08:25:03 -070042import com.android.server.wm.PinnedStackWindowController;
Bryce Leeaf691c02017-03-20 14:20:22 -070043import com.android.server.wm.StackWindowController;
Bryce Lee04ab3462017-04-10 15:06:33 -070044import com.android.server.wm.TaskWindowContainerController;
Bryce Leeaf691c02017-03-20 14:20:22 -070045import com.android.server.wm.WindowManagerService;
46import com.android.server.wm.WindowTestUtils;
Bryce Lee3115bdf2017-04-05 08:39:40 -070047import org.junit.After;
Bryce Leeaf691c02017-03-20 14:20:22 -070048import org.junit.Before;
49import org.mockito.MockitoAnnotations;
50
51/**
52 * A base class to handle common operations in activity related unit tests.
53 */
54public class ActivityTestsBase {
55 private final Context mContext = InstrumentationRegistry.getContext();
Bryce Lee3115bdf2017-04-05 08:39:40 -070056 private HandlerThread mHandlerThread;
Bryce Leeaf691c02017-03-20 14:20:22 -070057
Bryce Leeaf691c02017-03-20 14:20:22 -070058 @Before
59 public void setUp() throws Exception {
60 MockitoAnnotations.initMocks(this);
Bryce Lee3115bdf2017-04-05 08:39:40 -070061 mHandlerThread = new HandlerThread("ActivityTestsBaseThread");
62 mHandlerThread.start();
63 }
Bryce Leeaf691c02017-03-20 14:20:22 -070064
Bryce Lee3115bdf2017-04-05 08:39:40 -070065 @After
66 public void tearDown() {
67 mHandlerThread.quitSafely();
Bryce Leeaf691c02017-03-20 14:20:22 -070068 }
69
70 protected ActivityManagerService createActivityManagerService() {
Bryce Lee4e4a3ec2017-09-27 08:25:03 -070071 final ActivityManagerService service = spy(new TestActivityManagerService(mContext));
72 service.mWindowManager = prepareMockWindowManager();
Bryce Lee840c5662017-04-13 10:02:51 -070073 return service;
Bryce Leeaf691c02017-03-20 14:20:22 -070074 }
75
Bryce Leeaf691c02017-03-20 14:20:22 -070076 protected static ActivityRecord createActivity(ActivityManagerService service,
77 ComponentName component, TaskRecord task) {
Bryce Lee9f6affd2017-09-01 09:18:35 -070078 return createActivity(service, component, task, 0 /* userId */);
79 }
80
81 protected static ActivityRecord createActivity(ActivityManagerService service,
82 ComponentName component, TaskRecord task, int uid) {
Bryce Leeaf691c02017-03-20 14:20:22 -070083 Intent intent = new Intent();
84 intent.setComponent(component);
85 final ActivityInfo aInfo = new ActivityInfo();
86 aInfo.applicationInfo = new ApplicationInfo();
87 aInfo.applicationInfo.packageName = component.getPackageName();
Bryce Lee9f6affd2017-09-01 09:18:35 -070088 aInfo.applicationInfo.uid = uid;
Bryce Leeaf691c02017-03-20 14:20:22 -070089 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 */,
Andrii Kulianb1cdb102017-07-13 15:33:06 -070094 service.mStackSupervisor, null /* options */, null /* sourceRecord */);
Bryce Leeaf691c02017-03-20 14:20:22 -070095 activity.mWindowContainerController = mock(AppWindowContainerController.class);
96
97 if (task != null) {
98 task.addActivityToTop(activity);
99 }
100
101 return activity;
102 }
103
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700104 protected static TaskRecord createTask(ActivityStackSupervisor supervisor,
105 ComponentName component, ActivityStack stack) {
Winson Chung1dbc8112017-09-28 18:05:31 -0700106 return createTask(supervisor, component, 0 /* flags */, stack);
107 }
108
109 protected static TaskRecord createTask(ActivityStackSupervisor supervisor,
110 ComponentName component, int flags, ActivityStack stack) {
Bryce Leeaf691c02017-03-20 14:20:22 -0700111 final ActivityInfo aInfo = new ActivityInfo();
112 aInfo.applicationInfo = new ApplicationInfo();
113 aInfo.applicationInfo.packageName = component.getPackageName();
114
115 Intent intent = new Intent();
116 intent.setComponent(component);
Winson Chung1dbc8112017-09-28 18:05:31 -0700117 intent.setFlags(flags);
Bryce Leeaf691c02017-03-20 14:20:22 -0700118
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700119 final TaskRecord task = new TaskRecord(supervisor.mService, 0, aInfo, intent /*intent*/,
Jorim Jaggie7d2b852017-08-28 17:55:15 +0200120 null /*_taskDescription*/);
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700121 supervisor.setFocusStackUnchecked("test", stack);
Bryce Leeaf691c02017-03-20 14:20:22 -0700122 stack.addTask(task, true, "creating test task");
123 task.setStack(stack);
Bryce Lee04ab3462017-04-10 15:06:33 -0700124 task.setWindowContainerController(mock(TaskWindowContainerController.class));
Bryce Leeaf691c02017-03-20 14:20:22 -0700125
126 return task;
127 }
128
129 /**
130 * An {@link ActivityManagerService} subclass which provides a test
131 * {@link ActivityStackSupervisor}.
132 */
133 protected static class TestActivityManagerService extends ActivityManagerService {
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700134 TestActivityManagerService(Context context) {
Bryce Leeaf691c02017-03-20 14:20:22 -0700135 super(context);
Bryce Lee04ab3462017-04-10 15:06:33 -0700136 mSupportsMultiWindow = true;
137 mSupportsMultiDisplay = true;
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700138 mSupportsSplitScreenMultiWindow = true;
139 mSupportsFreeformWindowManagement = true;
140 mSupportsPictureInPicture = true;
Bryce Lee6a0754a2017-10-10 17:53:50 -0700141 mWindowManager = WindowTestUtils.getMockWindowManagerService();
Bryce Leeaf691c02017-03-20 14:20:22 -0700142 }
143
144 @Override
145 protected ActivityStackSupervisor createStackSupervisor() {
Bryce Lee3115bdf2017-04-05 08:39:40 -0700146 return new TestActivityStackSupervisor(this, mHandlerThread.getLooper());
Bryce Leeaf691c02017-03-20 14:20:22 -0700147 }
Bryce Lee29a649d2017-08-18 13:52:31 -0700148
149 @Override
150 void updateUsageStats(ActivityRecord component, boolean resumed) {
151 }
Bryce Leeaf691c02017-03-20 14:20:22 -0700152 }
153
154 /**
155 * An {@link ActivityStackSupervisor} which stubs out certain methods that depend on
156 * setup not available in the test environment. Also specifies an injector for
157 */
158 protected static class TestActivityStackSupervisor extends ActivityStackSupervisor {
Bryce Lee943ebe72017-05-04 10:19:07 -0700159 private final ActivityDisplay mDisplay;
Bryce Lee1533b2b2017-09-14 17:06:41 -0700160 private boolean mLastResizeable;
Bryce Lee943ebe72017-05-04 10:19:07 -0700161
Bryce Leeaf691c02017-03-20 14:20:22 -0700162 public TestActivityStackSupervisor(ActivityManagerService service, Looper looper) {
163 super(service, looper);
Wale Ogunwale9dcf9462017-09-19 15:13:01 -0700164 mDisplayManager =
165 (DisplayManager) mService.mContext.getSystemService(Context.DISPLAY_SERVICE);
Bryce Lee04ab3462017-04-10 15:06:33 -0700166 mWindowManager = prepareMockWindowManager();
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700167 mDisplay = new TestActivityDisplay(this, DEFAULT_DISPLAY);
Wale Ogunwale9dcf9462017-09-19 15:13:01 -0700168 attachDisplay(mDisplay);
Bryce Lee04ab3462017-04-10 15:06:33 -0700169 }
170
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700171 @Override
172 ActivityDisplay getDefaultDisplay() {
173 return mDisplay;
174 }
175
Bryce Lee1533b2b2017-09-14 17:06:41 -0700176 // TODO: Use Mockito spy instead. Currently not possible due to TestActivityStackSupervisor
177 // access to ActivityDisplay
178 @Override
179 boolean canPlaceEntityOnDisplay(int displayId, boolean resizeable, int callingPid,
180 int callingUid, ActivityInfo activityInfo) {
181 mLastResizeable = resizeable;
182 return super.canPlaceEntityOnDisplay(displayId, resizeable, callingPid, callingUid,
183 activityInfo);
184 }
185
186 // TODO: remove and use Mockito verify once {@link #canPlaceEntityOnDisplay} override is
187 // removed.
188 public boolean getLastResizeableFromCanPlaceEntityOnDisplay() {
189 return mLastResizeable;
190 }
191
Bryce Lee04ab3462017-04-10 15:06:33 -0700192 // No home stack is set.
193 @Override
194 void moveHomeStackToFront(String reason) {
Bryce Leeaf691c02017-03-20 14:20:22 -0700195 }
196
Bryce Lee3345c4e2017-04-25 07:40:41 -0700197 @Override
198 boolean moveHomeStackTaskToTop(String reason) {
199 return true;
200 }
201
Bryce Leeaf691c02017-03-20 14:20:22 -0700202 // Invoked during {@link ActivityStack} creation.
203 @Override
204 void updateUIDsPresentOnDisplay() {
205 }
206
Bryce Lee04ab3462017-04-10 15:06:33 -0700207 // Just return the current front task.
208 @Override
209 ActivityStack getNextFocusableStackLocked(ActivityStack currentFocus) {
210 return mFocusedStack;
211 }
212
213 // Called when moving activity to pinned stack.
214 @Override
215 void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges,
216 boolean preserveWindows) {
217 }
218
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700219 // Always keep things awake
220 @Override
221 boolean hasAwakeDisplay() {
222 return true;
223 }
224 }
225
226 private static class TestActivityDisplay extends ActivityDisplay {
227
228 private final ActivityStackSupervisor mSupervisor;
229 TestActivityDisplay(ActivityStackSupervisor supervisor, int displayId) {
230 super(supervisor, displayId);
231 mSupervisor = supervisor;
Andrii Kulianb1cdb102017-07-13 15:33:06 -0700232 }
233
234 @Override
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700235 <T extends ActivityStack> T createStackUnchecked(int windowingMode, int activityType,
236 int stackId, boolean onTop) {
237 if (windowingMode == WINDOWING_MODE_PINNED) {
238 return (T) new PinnedActivityStack(this, stackId, mSupervisor, onTop) {
Andrii Kulianb1cdb102017-07-13 15:33:06 -0700239 @Override
240 Rect getDefaultPictureInPictureBounds(float aspectRatio) {
241 return new Rect(50, 50, 100, 100);
242 }
Bryce Lee4e4a3ec2017-09-27 08:25:03 -0700243
244 @Override
245 PinnedStackWindowController createStackWindowController(int displayId,
246 boolean onTop, Rect outBounds) {
247 return mock(PinnedStackWindowController.class);
248 }
Andrii Kulianb1cdb102017-07-13 15:33:06 -0700249 };
250 } else {
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700251 return (T) new TestActivityStack(
252 this, stackId, mSupervisor, windowingMode, activityType, onTop);
Andrii Kulianb1cdb102017-07-13 15:33:06 -0700253 }
Bryce Lee04ab3462017-04-10 15:06:33 -0700254 }
Bryce Leeaf691c02017-03-20 14:20:22 -0700255 }
256
Bryce Lee04ab3462017-04-10 15:06:33 -0700257 private static WindowManagerService prepareMockWindowManager() {
Bryce Lee4e4a3ec2017-09-27 08:25:03 -0700258 final WindowManagerService service = WindowTestUtils.getMockWindowManagerService();
Bryce Lee04ab3462017-04-10 15:06:33 -0700259
260 doAnswer((InvocationOnMock invocationOnMock) -> {
261 final Runnable runnable = invocationOnMock.<Runnable>getArgument(0);
262 if (runnable != null) {
263 runnable.run();
264 }
265 return null;
266 }).when(service).inSurfaceTransaction(any());
267
268 return service;
269 }
270
271 protected interface ActivityStackReporter {
272 int onActivityRemovedFromStackInvocationCount();
273 }
274
Bryce Leeaf691c02017-03-20 14:20:22 -0700275 /**
Bryce Lee4e4a3ec2017-09-27 08:25:03 -0700276 * Overrided of {@link ActivityStack} that tracks test metrics, such as the number of times a
Bryce Leeaf691c02017-03-20 14:20:22 -0700277 * method is called. Note that its functionality depends on the implementations of the
278 * construction arguments.
279 */
280 protected static class TestActivityStack<T extends StackWindowController>
Bryce Lee04ab3462017-04-10 15:06:33 -0700281 extends ActivityStack<T> implements ActivityStackReporter {
Bryce Leeaf691c02017-03-20 14:20:22 -0700282 private int mOnActivityRemovedFromStackCount = 0;
283 private T mContainerController;
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700284
Wale Ogunwale9dcf9462017-09-19 15:13:01 -0700285 TestActivityStack(ActivityDisplay display, int stackId, ActivityStackSupervisor supervisor,
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700286 int windowingMode, int activityType, boolean onTop) {
287 super(display, stackId, supervisor, windowingMode, activityType, onTop);
Bryce Leeaf691c02017-03-20 14:20:22 -0700288 }
289
290 @Override
291 void onActivityRemovedFromStack(ActivityRecord r) {
292 mOnActivityRemovedFromStackCount++;
293 super.onActivityRemovedFromStack(r);
294 }
295
296 // Returns the number of times {@link #onActivityRemovedFromStack} has been called
Bryce Lee04ab3462017-04-10 15:06:33 -0700297 @Override
Bryce Leeaf691c02017-03-20 14:20:22 -0700298 public int onActivityRemovedFromStackInvocationCount() {
299 return mOnActivityRemovedFromStackCount;
300 }
301
302 @Override
Wale Ogunwale034a8ec2017-09-02 17:14:40 -0700303 protected T createStackWindowController(int displayId, boolean onTop, Rect outBounds) {
Bryce Leeaf691c02017-03-20 14:20:22 -0700304 mContainerController = (T) WindowTestUtils.createMockStackWindowContainerController();
305 return mContainerController;
306 }
307
308 @Override
309 T getWindowContainerController() {
310 return mContainerController;
311 }
312 }
Bryce Leeaf691c02017-03-20 14:20:22 -0700313}