ActivityTestsBase.java revision 840c566d13b8c84ad5edb37006176d6731bad250
1/* 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 21import android.app.ActivityManager; 22import 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; 29import android.os.HandlerThread; 30import 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; 38import org.junit.After; 39import 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(); 47 private HandlerThread mHandlerThread; 48 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); 56 mHandlerThread = new HandlerThread("ActivityTestsBaseThread"); 57 mHandlerThread.start(); 58 } 59 60 @After 61 public void tearDown() { 62 mHandlerThread.quitSafely(); 63 } 64 65 protected ActivityManagerService createActivityManagerService() { 66 final ActivityManagerService service = new TestActivityManagerService(mContext); 67 service.mWindowManager = WindowTestUtils.getWindowManagerService(mContext); 68 return service; 69 } 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) 75 .createTestStack(service, stackId, onTop); 76 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*/, 115 null /*_taskDescription*/, new ActivityManager.TaskThumbnailInfo()); 116 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() { 134 return new TestActivityStackSupervisor(this, mHandlerThread.getLooper()); 135 } 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 152 public TestActivityStack createTestStack(ActivityManagerService service, int stackId, 153 boolean onTop) { 154 final ActivityDisplay display = new ActivityDisplay(); 155 final TestActivityContainer container = 156 new TestActivityContainer(service, stackId, display, onTop); 157 return container.getStack(); 158 } 159 160 private class TestActivityContainer extends ActivityContainer { 161 private ActivityManagerService mService; 162 private TestActivityStack mStack; 163 private boolean mOnTop; 164 165 TestActivityContainer(ActivityManagerService service, int stackId, 166 ActivityDisplay activityDisplay, boolean onTop) { 167 super(stackId, activityDisplay, onTop); 168 mService = service; 169 } 170 171 @Override 172 protected void createStack(int stackId, boolean onTop) { 173 // 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; 177 } 178 179 public TestActivityStack getStack() { 180 if (mStack == null) { 181 mStack = new TestActivityStack(this, 182 new RecentTasks(mService, mService.mStackSupervisor), mOnTop); 183 } 184 185 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} 259