blob: b4bfa621a37e7f8bf811b76629b4bafbf8f00f41 [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;
25
26import org.mockito.invocation.InvocationOnMock;
Bryce Leeaf691c02017-03-20 14:20:22 -070027
28import 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;
Wale Ogunwale9dcf9462017-09-19 15:13:01 -070035import android.hardware.display.DisplayManager;
Bryce Lee3115bdf2017-04-05 08:39:40 -070036import android.os.HandlerThread;
Bryce Leeaf691c02017-03-20 14:20:22 -070037import android.os.Looper;
38import android.support.test.InstrumentationRegistry;
39import com.android.server.AttributeCache;
40import com.android.server.wm.AppWindowContainerController;
41import com.android.server.wm.StackWindowController;
42
Bryce Lee04ab3462017-04-10 15:06:33 -070043import com.android.server.wm.TaskWindowContainerController;
Bryce Leeaf691c02017-03-20 14:20:22 -070044import com.android.server.wm.WindowManagerService;
45import com.android.server.wm.WindowTestUtils;
Bryce Lee3115bdf2017-04-05 08:39:40 -070046import org.junit.After;
Bryce Leeaf691c02017-03-20 14:20:22 -070047import org.junit.Before;
48import org.mockito.MockitoAnnotations;
49
50/**
51 * A base class to handle common operations in activity related unit tests.
52 */
53public class ActivityTestsBase {
54 private final Context mContext = InstrumentationRegistry.getContext();
Bryce Lee3115bdf2017-04-05 08:39:40 -070055 private HandlerThread mHandlerThread;
Bryce Leeaf691c02017-03-20 14:20:22 -070056
57 // Grabbing an instance of {@link WindowManagerService} creates it if not present so this must
58 // be called at before any tests.
59 private final WindowManagerService mWms = WindowTestUtils.getWindowManagerService(mContext);
60
61 @Before
62 public void setUp() throws Exception {
63 MockitoAnnotations.initMocks(this);
Bryce Lee3115bdf2017-04-05 08:39:40 -070064 mHandlerThread = new HandlerThread("ActivityTestsBaseThread");
65 mHandlerThread.start();
66 }
Bryce Leeaf691c02017-03-20 14:20:22 -070067
Bryce Lee3115bdf2017-04-05 08:39:40 -070068 @After
69 public void tearDown() {
70 mHandlerThread.quitSafely();
Bryce Leeaf691c02017-03-20 14:20:22 -070071 }
72
73 protected ActivityManagerService createActivityManagerService() {
Bryce Lee840c5662017-04-13 10:02:51 -070074 final ActivityManagerService service = new TestActivityManagerService(mContext);
Bryce Lee04ab3462017-04-10 15:06:33 -070075 service.mWindowManager = WindowTestUtils.getMockWindowManagerService();
Bryce Lee840c5662017-04-13 10:02:51 -070076 return service;
Bryce Leeaf691c02017-03-20 14:20:22 -070077 }
78
Bryce Leeaf691c02017-03-20 14:20:22 -070079 protected static ActivityRecord createActivity(ActivityManagerService service,
80 ComponentName component, TaskRecord task) {
Bryce Lee9f6affd2017-09-01 09:18:35 -070081 return createActivity(service, component, task, 0 /* userId */);
82 }
83
84 protected static ActivityRecord createActivity(ActivityManagerService service,
85 ComponentName component, TaskRecord task, int uid) {
Bryce Leeaf691c02017-03-20 14:20:22 -070086 Intent intent = new Intent();
87 intent.setComponent(component);
88 final ActivityInfo aInfo = new ActivityInfo();
89 aInfo.applicationInfo = new ApplicationInfo();
90 aInfo.applicationInfo.packageName = component.getPackageName();
Bryce Lee9f6affd2017-09-01 09:18:35 -070091 aInfo.applicationInfo.uid = uid;
Bryce Leeaf691c02017-03-20 14:20:22 -070092 AttributeCache.init(service.mContext);
93 final ActivityRecord activity = new ActivityRecord(service, null /* caller */,
94 0 /* launchedFromPid */, 0, null, intent, null,
95 aInfo /*aInfo*/, new Configuration(), null /* resultTo */, null /* resultWho */,
96 0 /* reqCode */, false /*componentSpecified*/, false /* rootVoiceInteraction */,
Andrii Kulianb1cdb102017-07-13 15:33:06 -070097 service.mStackSupervisor, null /* options */, null /* sourceRecord */);
Bryce Leeaf691c02017-03-20 14:20:22 -070098 activity.mWindowContainerController = mock(AppWindowContainerController.class);
99
100 if (task != null) {
101 task.addActivityToTop(activity);
102 }
103
104 return activity;
105 }
106
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700107 protected static TaskRecord createTask(ActivityStackSupervisor supervisor,
108 ComponentName component, ActivityStack stack) {
Bryce Leeaf691c02017-03-20 14:20:22 -0700109 final ActivityInfo aInfo = new ActivityInfo();
110 aInfo.applicationInfo = new ApplicationInfo();
111 aInfo.applicationInfo.packageName = component.getPackageName();
112
113 Intent intent = new Intent();
114 intent.setComponent(component);
115
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700116 final TaskRecord task = new TaskRecord(supervisor.mService, 0, aInfo, intent /*intent*/,
Jorim Jaggie7d2b852017-08-28 17:55:15 +0200117 null /*_taskDescription*/);
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700118 supervisor.setFocusStackUnchecked("test", stack);
Bryce Leeaf691c02017-03-20 14:20:22 -0700119 stack.addTask(task, true, "creating test task");
120 task.setStack(stack);
Bryce Lee04ab3462017-04-10 15:06:33 -0700121 task.setWindowContainerController(mock(TaskWindowContainerController.class));
Bryce Leeaf691c02017-03-20 14:20:22 -0700122
123 return task;
124 }
125
126 /**
127 * An {@link ActivityManagerService} subclass which provides a test
128 * {@link ActivityStackSupervisor}.
129 */
130 protected static class TestActivityManagerService extends ActivityManagerService {
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700131 TestActivityManagerService(Context context) {
Bryce Leeaf691c02017-03-20 14:20:22 -0700132 super(context);
Bryce Lee04ab3462017-04-10 15:06:33 -0700133 mSupportsMultiWindow = true;
134 mSupportsMultiDisplay = true;
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700135 mSupportsSplitScreenMultiWindow = true;
136 mSupportsFreeformWindowManagement = true;
137 mSupportsPictureInPicture = true;
Bryce Lee04ab3462017-04-10 15:06:33 -0700138 mWindowManager = WindowTestUtils.getWindowManagerService(context);
Bryce Leeaf691c02017-03-20 14:20:22 -0700139 }
140
141 @Override
142 protected ActivityStackSupervisor createStackSupervisor() {
Bryce Lee3115bdf2017-04-05 08:39:40 -0700143 return new TestActivityStackSupervisor(this, mHandlerThread.getLooper());
Bryce Leeaf691c02017-03-20 14:20:22 -0700144 }
Bryce Lee29a649d2017-08-18 13:52:31 -0700145
146 @Override
147 void updateUsageStats(ActivityRecord component, boolean resumed) {
148 }
Bryce Leeaf691c02017-03-20 14:20:22 -0700149 }
150
151 /**
152 * An {@link ActivityStackSupervisor} which stubs out certain methods that depend on
153 * setup not available in the test environment. Also specifies an injector for
154 */
155 protected static class TestActivityStackSupervisor extends ActivityStackSupervisor {
Bryce Lee943ebe72017-05-04 10:19:07 -0700156 private final ActivityDisplay mDisplay;
Bryce Lee1533b2b2017-09-14 17:06:41 -0700157 private boolean mLastResizeable;
Bryce Lee943ebe72017-05-04 10:19:07 -0700158
Bryce Leeaf691c02017-03-20 14:20:22 -0700159 public TestActivityStackSupervisor(ActivityManagerService service, Looper looper) {
160 super(service, looper);
Wale Ogunwale9dcf9462017-09-19 15:13:01 -0700161 mDisplayManager =
162 (DisplayManager) mService.mContext.getSystemService(Context.DISPLAY_SERVICE);
Bryce Lee04ab3462017-04-10 15:06:33 -0700163 mWindowManager = prepareMockWindowManager();
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700164 mDisplay = new TestActivityDisplay(this, DEFAULT_DISPLAY);
Wale Ogunwale9dcf9462017-09-19 15:13:01 -0700165 attachDisplay(mDisplay);
Bryce Lee04ab3462017-04-10 15:06:33 -0700166 }
167
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700168 @Override
169 ActivityDisplay getDefaultDisplay() {
170 return mDisplay;
171 }
172
Bryce Lee1533b2b2017-09-14 17:06:41 -0700173 // TODO: Use Mockito spy instead. Currently not possible due to TestActivityStackSupervisor
174 // access to ActivityDisplay
175 @Override
176 boolean canPlaceEntityOnDisplay(int displayId, boolean resizeable, int callingPid,
177 int callingUid, ActivityInfo activityInfo) {
178 mLastResizeable = resizeable;
179 return super.canPlaceEntityOnDisplay(displayId, resizeable, callingPid, callingUid,
180 activityInfo);
181 }
182
183 // TODO: remove and use Mockito verify once {@link #canPlaceEntityOnDisplay} override is
184 // removed.
185 public boolean getLastResizeableFromCanPlaceEntityOnDisplay() {
186 return mLastResizeable;
187 }
188
Bryce Lee04ab3462017-04-10 15:06:33 -0700189 // No home stack is set.
190 @Override
191 void moveHomeStackToFront(String reason) {
Bryce Leeaf691c02017-03-20 14:20:22 -0700192 }
193
Bryce Lee3345c4e2017-04-25 07:40:41 -0700194 @Override
195 boolean moveHomeStackTaskToTop(String reason) {
196 return true;
197 }
198
Bryce Leeaf691c02017-03-20 14:20:22 -0700199 // Invoked during {@link ActivityStack} creation.
200 @Override
201 void updateUIDsPresentOnDisplay() {
202 }
203
Bryce Lee04ab3462017-04-10 15:06:33 -0700204 // Just return the current front task.
205 @Override
206 ActivityStack getNextFocusableStackLocked(ActivityStack currentFocus) {
207 return mFocusedStack;
208 }
209
210 // Called when moving activity to pinned stack.
211 @Override
212 void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges,
213 boolean preserveWindows) {
214 }
215
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700216 // Always keep things awake
217 @Override
218 boolean hasAwakeDisplay() {
219 return true;
220 }
221 }
222
223 private static class TestActivityDisplay extends ActivityDisplay {
224
225 private final ActivityStackSupervisor mSupervisor;
226 TestActivityDisplay(ActivityStackSupervisor supervisor, int displayId) {
227 super(supervisor, displayId);
228 mSupervisor = supervisor;
Andrii Kulianb1cdb102017-07-13 15:33:06 -0700229 }
230
231 @Override
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700232 <T extends ActivityStack> T createStackUnchecked(int windowingMode, int activityType,
233 int stackId, boolean onTop) {
234 if (windowingMode == WINDOWING_MODE_PINNED) {
235 return (T) new PinnedActivityStack(this, stackId, mSupervisor, onTop) {
Andrii Kulianb1cdb102017-07-13 15:33:06 -0700236 @Override
237 Rect getDefaultPictureInPictureBounds(float aspectRatio) {
238 return new Rect(50, 50, 100, 100);
239 }
240 };
241 } else {
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700242 return (T) new TestActivityStack(
243 this, stackId, mSupervisor, windowingMode, activityType, onTop);
Andrii Kulianb1cdb102017-07-13 15:33:06 -0700244 }
Bryce Lee04ab3462017-04-10 15:06:33 -0700245 }
Bryce Leeaf691c02017-03-20 14:20:22 -0700246 }
247
Bryce Lee04ab3462017-04-10 15:06:33 -0700248 private static WindowManagerService prepareMockWindowManager() {
249 final WindowManagerService service = mock(WindowManagerService.class);
250
251 doAnswer((InvocationOnMock invocationOnMock) -> {
252 final Runnable runnable = invocationOnMock.<Runnable>getArgument(0);
253 if (runnable != null) {
254 runnable.run();
255 }
256 return null;
257 }).when(service).inSurfaceTransaction(any());
258
259 return service;
260 }
261
262 protected interface ActivityStackReporter {
263 int onActivityRemovedFromStackInvocationCount();
264 }
265
Bryce Leeaf691c02017-03-20 14:20:22 -0700266 /**
267 * Override of {@link ActivityStack} that tracks test metrics, such as the number of times a
268 * method is called. Note that its functionality depends on the implementations of the
269 * construction arguments.
270 */
271 protected static class TestActivityStack<T extends StackWindowController>
Bryce Lee04ab3462017-04-10 15:06:33 -0700272 extends ActivityStack<T> implements ActivityStackReporter {
Bryce Leeaf691c02017-03-20 14:20:22 -0700273 private int mOnActivityRemovedFromStackCount = 0;
274 private T mContainerController;
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700275
Wale Ogunwale9dcf9462017-09-19 15:13:01 -0700276 TestActivityStack(ActivityDisplay display, int stackId, ActivityStackSupervisor supervisor,
Wale Ogunwale04a05ac2017-09-17 21:35:02 -0700277 int windowingMode, int activityType, boolean onTop) {
278 super(display, stackId, supervisor, windowingMode, activityType, onTop);
Bryce Leeaf691c02017-03-20 14:20:22 -0700279 }
280
281 @Override
282 void onActivityRemovedFromStack(ActivityRecord r) {
283 mOnActivityRemovedFromStackCount++;
284 super.onActivityRemovedFromStack(r);
285 }
286
287 // Returns the number of times {@link #onActivityRemovedFromStack} has been called
Bryce Lee04ab3462017-04-10 15:06:33 -0700288 @Override
Bryce Leeaf691c02017-03-20 14:20:22 -0700289 public int onActivityRemovedFromStackInvocationCount() {
290 return mOnActivityRemovedFromStackCount;
291 }
292
293 @Override
Wale Ogunwale034a8ec2017-09-02 17:14:40 -0700294 protected T createStackWindowController(int displayId, boolean onTop, Rect outBounds) {
Bryce Leeaf691c02017-03-20 14:20:22 -0700295 mContainerController = (T) WindowTestUtils.createMockStackWindowContainerController();
296 return mContainerController;
297 }
298
299 @Override
300 T getWindowContainerController() {
301 return mContainerController;
302 }
303 }
Bryce Leeaf691c02017-03-20 14:20:22 -0700304}