ActivityTestsBase.java revision 3115bdf15af01ea43c28e1251657c7154e9acc91
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.content.ComponentName; 22import android.content.Context; 23import android.content.Intent; 24import android.content.pm.ActivityInfo; 25import android.content.pm.ApplicationInfo; 26import android.content.res.Configuration; 27import android.graphics.Rect; 28import android.os.HandlerThread; 29import android.os.Looper; 30import android.support.test.InstrumentationRegistry; 31import com.android.server.AttributeCache; 32import com.android.server.wm.AppWindowContainerController; 33import com.android.server.wm.StackWindowController; 34 35import com.android.server.wm.WindowManagerService; 36import com.android.server.wm.WindowTestUtils; 37import org.junit.After; 38import org.junit.Before; 39import org.mockito.MockitoAnnotations; 40 41/** 42 * A base class to handle common operations in activity related unit tests. 43 */ 44public class ActivityTestsBase { 45 private final Context mContext = InstrumentationRegistry.getContext(); 46 private HandlerThread mHandlerThread; 47 48 // Grabbing an instance of {@link WindowManagerService} creates it if not present so this must 49 // be called at before any tests. 50 private final WindowManagerService mWms = WindowTestUtils.getWindowManagerService(mContext); 51 52 @Before 53 public void setUp() throws Exception { 54 MockitoAnnotations.initMocks(this); 55 mHandlerThread = new HandlerThread("ActivityTestsBaseThread"); 56 mHandlerThread.start(); 57 } 58 59 @After 60 public void tearDown() { 61 mHandlerThread.quitSafely(); 62 } 63 64 protected ActivityManagerService createActivityManagerService() { 65 return new TestActivityManagerService(mContext); 66 } 67 68 protected static TestActivityStack createActivityStack(ActivityManagerService service, 69 int stackId, int displayId, boolean onTop) { 70 if (service.mStackSupervisor instanceof TestActivityStackSupervisor) { 71 final TestActivityStack stack = ((TestActivityStackSupervisor) service.mStackSupervisor) 72 .createTestStack(stackId, onTop); 73 return stack; 74 } 75 76 return null; 77 } 78 79 protected static ActivityRecord createActivity(ActivityManagerService service, 80 ComponentName component, TaskRecord task) { 81 Intent intent = new Intent(); 82 intent.setComponent(component); 83 final ActivityInfo aInfo = new ActivityInfo(); 84 aInfo.applicationInfo = new ApplicationInfo(); 85 aInfo.applicationInfo.packageName = component.getPackageName(); 86 AttributeCache.init(service.mContext); 87 final ActivityRecord activity = new ActivityRecord(service, null /* caller */, 88 0 /* launchedFromPid */, 0, null, intent, null, 89 aInfo /*aInfo*/, new Configuration(), null /* resultTo */, null /* resultWho */, 90 0 /* reqCode */, false /*componentSpecified*/, false /* rootVoiceInteraction */, 91 service.mStackSupervisor, null /* container */, null /* options */, 92 null /* sourceRecord */); 93 activity.mWindowContainerController = mock(AppWindowContainerController.class); 94 95 if (task != null) { 96 task.addActivityToTop(activity); 97 } 98 99 return activity; 100 } 101 102 protected static TaskRecord createTask(ActivityManagerService service, 103 ComponentName component, ActivityStack stack) { 104 final ActivityInfo aInfo = new ActivityInfo(); 105 aInfo.applicationInfo = new ApplicationInfo(); 106 aInfo.applicationInfo.packageName = component.getPackageName(); 107 108 Intent intent = new Intent(); 109 intent.setComponent(component); 110 111 final TaskRecord task = new TaskRecord(service, 0, aInfo, intent /*intent*/, 112 null /*_taskDescription*/, null /*thumbnailInfo*/); 113 stack.addTask(task, true, "creating test task"); 114 task.setStack(stack); 115 task.createWindowContainer(true, true); 116 117 return task; 118 } 119 120 /** 121 * An {@link ActivityManagerService} subclass which provides a test 122 * {@link ActivityStackSupervisor}. 123 */ 124 protected static class TestActivityManagerService extends ActivityManagerService { 125 public TestActivityManagerService(Context context) { 126 super(context); 127 } 128 129 @Override 130 protected ActivityStackSupervisor createStackSupervisor() { 131 return new TestActivityStackSupervisor(this, mHandlerThread.getLooper()); 132 } 133 } 134 135 /** 136 * An {@link ActivityStackSupervisor} which stubs out certain methods that depend on 137 * setup not available in the test environment. Also specifies an injector for 138 */ 139 protected static class TestActivityStackSupervisor extends ActivityStackSupervisor { 140 public TestActivityStackSupervisor(ActivityManagerService service, Looper looper) { 141 super(service, looper); 142 } 143 144 // Invoked during {@link ActivityStack} creation. 145 @Override 146 void updateUIDsPresentOnDisplay() { 147 } 148 149 public TestActivityStack createTestStack(int stackId, boolean onTop) { 150 final ActivityDisplay display = new ActivityDisplay(); 151 final TestActivityContainer container = 152 new TestActivityContainer(stackId, display, onTop); 153 return container.getStack(); 154 } 155 156 private class TestActivityContainer extends ActivityContainer { 157 private TestActivityStack mStack; 158 TestActivityContainer(int stackId, ActivityDisplay activityDisplay, boolean onTop) { 159 super(stackId, activityDisplay, onTop); 160 } 161 162 @Override 163 protected void createStack(int stackId, boolean onTop) { 164 mStack = new TestActivityStack(this, null /*recentTasks*/, onTop); 165 } 166 167 public TestActivityStack getStack() { 168 return mStack; 169 } 170 } 171 } 172 173 /** 174 * Override of {@link ActivityStack} that tracks test metrics, such as the number of times a 175 * method is called. Note that its functionality depends on the implementations of the 176 * construction arguments. 177 */ 178 protected static class TestActivityStack<T extends StackWindowController> 179 extends ActivityStack<T> { 180 private int mOnActivityRemovedFromStackCount = 0; 181 private T mContainerController; 182 TestActivityStack(ActivityStackSupervisor.ActivityContainer activityContainer, 183 RecentTasks recentTasks, boolean onTop) { 184 super(activityContainer, recentTasks, onTop); 185 } 186 187 @Override 188 void onActivityRemovedFromStack(ActivityRecord r) { 189 mOnActivityRemovedFromStackCount++; 190 super.onActivityRemovedFromStack(r); 191 } 192 193 // Returns the number of times {@link #onActivityRemovedFromStack} has been called 194 public int onActivityRemovedFromStackInvocationCount() { 195 return mOnActivityRemovedFromStackCount; 196 } 197 198 @Override 199 protected T createStackWindowController(int displayId, boolean onTop, 200 Rect outBounds) { 201 mContainerController = (T) WindowTestUtils.createMockStackWindowContainerController(); 202 return mContainerController; 203 } 204 205 @Override 206 T getWindowContainerController() { 207 return mContainerController; 208 } 209 } 210 211 protected static class ActivityStackBuilder { 212 private boolean mOnTop = true; 213 private int mStackId = 0; 214 private int mDisplayId = 1; 215 216 private final ActivityManagerService mService; 217 218 public ActivityStackBuilder(ActivityManagerService ams) { 219 mService = ams; 220 } 221 222 public ActivityStackBuilder setOnTop(boolean onTop) { 223 mOnTop = onTop; 224 return this; 225 } 226 227 public ActivityStackBuilder setStackId(int id) { 228 mStackId = id; 229 return this; 230 } 231 232 public ActivityStackBuilder setDisplayId(int id) { 233 mDisplayId = id; 234 return this; 235 } 236 237 public TestActivityStack build() { 238 return createActivityStack(mService, mStackId, mDisplayId, mOnTop); 239 } 240 } 241} 242