1 /* 2 * Copyright (C) 2019 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 17 package com.android.server.wm; 18 19 import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; 20 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; 21 import static android.testing.DexmakerShareClassLoaderRule.runWithDexmakerShareClassLoader; 22 import static android.view.Display.DEFAULT_DISPLAY; 23 24 import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation; 25 26 import static com.android.dx.mockito.inline.extended.ExtendedMockito.any; 27 import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyBoolean; 28 import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyInt; 29 import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyString; 30 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing; 31 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; 32 import static com.android.dx.mockito.inline.extended.ExtendedMockito.eq; 33 import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock; 34 import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession; 35 import static com.android.dx.mockito.inline.extended.ExtendedMockito.nullable; 36 import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy; 37 import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; 38 39 import android.app.ActivityManagerInternal; 40 import android.app.AppOpsManager; 41 import android.app.usage.UsageStatsManagerInternal; 42 import android.content.BroadcastReceiver; 43 import android.content.ComponentName; 44 import android.content.ContentResolver; 45 import android.content.Context; 46 import android.content.IntentFilter; 47 import android.content.pm.IPackageManager; 48 import android.content.pm.PackageManagerInternal; 49 import android.database.ContentObserver; 50 import android.hardware.display.DisplayManager; 51 import android.hardware.display.DisplayManagerInternal; 52 import android.net.Uri; 53 import android.os.Handler; 54 import android.os.Looper; 55 import android.os.PowerManager; 56 import android.os.PowerManagerInternal; 57 import android.os.PowerSaveState; 58 import android.os.StrictMode; 59 import android.os.UserHandle; 60 import android.util.Log; 61 import android.view.InputChannel; 62 import android.view.Surface; 63 import android.view.SurfaceControl; 64 65 import com.android.dx.mockito.inline.extended.StaticMockitoSession; 66 import com.android.server.AnimationThread; 67 import com.android.server.DisplayThread; 68 import com.android.server.LocalServices; 69 import com.android.server.LockGuard; 70 import com.android.server.UiThread; 71 import com.android.server.Watchdog; 72 import com.android.server.am.ActivityManagerService; 73 import com.android.server.appop.AppOpsService; 74 import com.android.server.display.color.ColorDisplayService; 75 import com.android.server.firewall.IntentFirewall; 76 import com.android.server.input.InputManagerService; 77 import com.android.server.pm.UserManagerService; 78 import com.android.server.policy.PermissionPolicyInternal; 79 import com.android.server.policy.WindowManagerPolicy; 80 import com.android.server.statusbar.StatusBarManagerInternal; 81 import com.android.server.uri.UriGrantsManagerInternal; 82 83 import org.junit.rules.TestRule; 84 import org.junit.runner.Description; 85 import org.junit.runners.model.Statement; 86 import org.mockito.Mockito; 87 import org.mockito.quality.Strictness; 88 89 import java.io.File; 90 import java.util.concurrent.atomic.AtomicBoolean; 91 import java.util.function.Supplier; 92 93 /** 94 * JUnit test rule to correctly setting up system services like {@link WindowManagerService} 95 * and {@link ActivityTaskManagerService} for tests. 96 */ 97 public class SystemServicesTestRule implements TestRule { 98 99 private static final String TAG = SystemServicesTestRule.class.getSimpleName(); 100 101 static int sNextDisplayId = DEFAULT_DISPLAY + 100; 102 static int sNextTaskId = 100; 103 104 private static final int[] TEST_USER_PROFILE_IDS = {}; 105 106 private Description mDescription; 107 private Context mContext; 108 private StaticMockitoSession mMockitoSession; 109 private ActivityManagerService mAmService; 110 private ActivityTaskManagerService mAtmService; 111 private WindowManagerService mWmService; 112 private TestWindowManagerPolicy mWMPolicy; 113 private TestDisplayWindowSettingsProvider mTestDisplayWindowSettingsProvider; 114 private WindowState.PowerManagerWrapper mPowerManagerWrapper; 115 private InputManagerService mImService; 116 private InputChannel mInputChannel; 117 private Supplier<Surface> mSurfaceFactory = () -> mock(Surface.class); 118 /** 119 * Spied {@link SurfaceControl.Transaction} class than can be used to verify calls. 120 */ 121 SurfaceControl.Transaction mTransaction; 122 123 @Override apply(Statement base, Description description)124 public Statement apply(Statement base, Description description) { 125 return new Statement() { 126 @Override 127 public void evaluate() throws Throwable { 128 mDescription = description; 129 Throwable throwable = null; 130 try { 131 runWithDexmakerShareClassLoader(SystemServicesTestRule.this::setUp); 132 base.evaluate(); 133 } catch (Throwable t) { 134 throwable = t; 135 } finally { 136 try { 137 tearDown(); 138 } catch (Throwable t) { 139 if (throwable != null) { 140 Log.e("SystemServicesTestRule", "Suppressed: ", throwable); 141 t.addSuppressed(throwable); 142 } 143 throw t; 144 } 145 if (throwable != null) throw throwable; 146 } 147 } 148 }; 149 } 150 151 private void setUp() { 152 mMockitoSession = mockitoSession() 153 .spyStatic(LocalServices.class) 154 .mockStatic(LockGuard.class) 155 .mockStatic(Watchdog.class) 156 .strictness(Strictness.LENIENT) 157 .startMocking(); 158 159 setUpSystemCore(); 160 setUpLocalServices(); 161 setUpActivityTaskManagerService(); 162 setUpWindowManagerService(); 163 } 164 165 private void setUpSystemCore() { 166 doReturn(mock(Watchdog.class)).when(Watchdog::getInstance); 167 168 mContext = getInstrumentation().getTargetContext(); 169 spyOn(mContext); 170 171 doReturn(null).when(mContext) 172 .registerReceiver(nullable(BroadcastReceiver.class), any(IntentFilter.class)); 173 doReturn(null).when(mContext) 174 .registerReceiverAsUser(any(BroadcastReceiver.class), any(UserHandle.class), 175 any(IntentFilter.class), nullable(String.class), nullable(Handler.class)); 176 177 final ContentResolver contentResolver = mContext.getContentResolver(); 178 spyOn(contentResolver); 179 doNothing().when(contentResolver) 180 .registerContentObserver(any(Uri.class), anyBoolean(), any(ContentObserver.class), 181 anyInt()); 182 } 183 184 private void setUpLocalServices() { 185 // Tear down any local services just in case. 186 tearDownLocalServices(); 187 188 // UriGrantsManagerInternal 189 final UriGrantsManagerInternal ugmi = mock(UriGrantsManagerInternal.class); 190 LocalServices.addService(UriGrantsManagerInternal.class, ugmi); 191 192 // AppOpsManager 193 final AppOpsManager aom = mock(AppOpsManager.class); 194 doReturn(aom).when(mContext).getSystemService(eq(Context.APP_OPS_SERVICE)); 195 196 // Prevent "WakeLock finalized while still held: SCREEN_FROZEN". 197 final PowerManager pm = mock(PowerManager.class); 198 doReturn(pm).when(mContext).getSystemService(eq(Context.POWER_SERVICE)); 199 doReturn(mock(PowerManager.WakeLock.class)).when(pm).newWakeLock(anyInt(), anyString()); 200 201 // DisplayManagerInternal 202 final DisplayManagerInternal dmi = mock(DisplayManagerInternal.class); 203 doReturn(dmi).when(() -> LocalServices.getService(eq(DisplayManagerInternal.class))); 204 205 // ColorDisplayServiceInternal 206 final ColorDisplayService.ColorDisplayServiceInternal cds = 207 mock(ColorDisplayService.ColorDisplayServiceInternal.class); 208 doReturn(cds).when(() -> LocalServices.getService( 209 eq(ColorDisplayService.ColorDisplayServiceInternal.class))); 210 211 final UsageStatsManagerInternal usmi = mock(UsageStatsManagerInternal.class); 212 LocalServices.addService(UsageStatsManagerInternal.class, usmi); 213 214 // PackageManagerInternal 215 final PackageManagerInternal packageManagerInternal = mock(PackageManagerInternal.class); 216 LocalServices.addService(PackageManagerInternal.class, packageManagerInternal); 217 doReturn(false).when(packageManagerInternal).isPermissionsReviewRequired( 218 anyString(), anyInt()); 219 doReturn(null).when(packageManagerInternal).getDefaultHomeActivity(anyInt()); 220 221 ComponentName systemServiceComponent = new ComponentName("android.test.system.service", ""); 222 doReturn(systemServiceComponent).when(packageManagerInternal).getSystemUiServiceComponent(); 223 224 // PowerManagerInternal 225 final PowerManagerInternal pmi = mock(PowerManagerInternal.class); 226 final PowerSaveState state = new PowerSaveState.Builder().build(); 227 doReturn(state).when(pmi).getLowPowerState(anyInt()); 228 doReturn(pmi).when(() -> LocalServices.getService(eq(PowerManagerInternal.class))); 229 230 // PermissionPolicyInternal 231 final PermissionPolicyInternal ppi = mock(PermissionPolicyInternal.class); 232 LocalServices.addService(PermissionPolicyInternal.class, ppi); 233 doReturn(true).when(ppi).checkStartActivity(any(), anyInt(), any()); 234 235 // InputManagerService 236 mImService = mock(InputManagerService.class); 237 // InputChannel cannot be mocked because it may pass to InputEventReceiver. 238 final InputChannel[] inputChannels = InputChannel.openInputChannelPair(TAG); 239 inputChannels[0].dispose(); 240 mInputChannel = inputChannels[1]; 241 doReturn(mInputChannel).when(mImService).monitorInput(anyString(), anyInt()); 242 doReturn(mInputChannel).when(mImService).createInputChannel(anyString()); 243 244 // StatusBarManagerInternal 245 final StatusBarManagerInternal sbmi = mock(StatusBarManagerInternal.class); 246 doReturn(sbmi).when(() -> LocalServices.getService(eq(StatusBarManagerInternal.class))); 247 } 248 249 private void setUpActivityTaskManagerService() { 250 // ActivityManagerService 251 mAmService = new ActivityManagerService(new AMTestInjector(mContext), null /* thread */); 252 spyOn(mAmService); 253 doReturn(mock(IPackageManager.class)).when(mAmService).getPackageManager(); 254 doNothing().when(mAmService).grantImplicitAccess( 255 anyInt(), any(), anyInt(), anyInt()); 256 257 // ActivityManagerInternal 258 final ActivityManagerInternal amInternal = mAmService.mInternal; 259 spyOn(amInternal); 260 doNothing().when(amInternal).trimApplications(); 261 doNothing().when(amInternal).scheduleAppGcs(); 262 doNothing().when(amInternal).updateCpuStats(); 263 doNothing().when(amInternal).updateOomAdj(); 264 doNothing().when(amInternal).updateBatteryStats(any(), anyInt(), anyInt(), anyBoolean()); 265 doNothing().when(amInternal).updateActivityUsageStats( 266 any(), anyInt(), anyInt(), any(), any()); 267 doNothing().when(amInternal).startProcess( 268 any(), any(), anyBoolean(), anyBoolean(), any(), any()); 269 doNothing().when(amInternal).updateOomLevelsForDisplay(anyInt()); 270 doNothing().when(amInternal).broadcastGlobalConfigurationChanged(anyInt(), anyBoolean()); 271 doNothing().when(amInternal).cleanUpServices(anyInt(), any(), any()); 272 doReturn(UserHandle.USER_SYSTEM).when(amInternal).getCurrentUserId(); 273 doReturn(TEST_USER_PROFILE_IDS).when(amInternal).getCurrentProfileIds(); 274 doReturn(true).when(amInternal).isUserRunning(anyInt(), anyInt()); 275 doReturn(true).when(amInternal).hasStartedUserState(anyInt()); 276 doReturn(false).when(amInternal).shouldConfirmCredentials(anyInt()); 277 doReturn(false).when(amInternal).isActivityStartsLoggingEnabled(); 278 LocalServices.addService(ActivityManagerInternal.class, amInternal); 279 280 mAtmService = new TestActivityTaskManagerService(mContext, mAmService); 281 LocalServices.addService(ActivityTaskManagerInternal.class, mAtmService.getAtmInternal()); 282 } 283 284 private void setUpWindowManagerService() { 285 mPowerManagerWrapper = mock(WindowState.PowerManagerWrapper.class); 286 mWMPolicy = new TestWindowManagerPolicy(this::getWindowManagerService, 287 mPowerManagerWrapper); 288 mTestDisplayWindowSettingsProvider = new TestDisplayWindowSettingsProvider(); 289 // Suppress StrictMode violation (DisplayWindowSettings) to avoid log flood. 290 DisplayThread.getHandler().post(StrictMode::allowThreadDiskWritesMask); 291 mWmService = WindowManagerService.main( 292 mContext, mImService, false, false, mWMPolicy, mAtmService, 293 mTestDisplayWindowSettingsProvider, StubTransaction::new, 294 () -> mSurfaceFactory.get(), (unused) -> new MockSurfaceControlBuilder()); 295 spyOn(mWmService); 296 spyOn(mWmService.mRoot); 297 // Invoked during {@link ActivityStack} creation. 298 doNothing().when(mWmService.mRoot).updateUIDsPresentOnDisplay(); 299 // Always keep things awake. 300 doReturn(true).when(mWmService.mRoot).hasAwakeDisplay(); 301 // Called when moving activity to pinned stack. 302 doNothing().when(mWmService.mRoot).ensureActivitiesVisible(any(), 303 anyInt(), anyBoolean(), anyBoolean()); 304 spyOn(mWmService.mDisplayWindowSettings); 305 spyOn(mWmService.mDisplayWindowSettingsProvider); 306 307 // Setup factory classes to prevent calls to native code. 308 mTransaction = spy(StubTransaction.class); 309 // Return a spied Transaction class than can be used to verify calls. 310 mWmService.mTransactionFactory = () -> mTransaction; 311 mWmService.mSurfaceAnimationRunner = new SurfaceAnimationRunner( 312 null, null, mTransaction, mWmService.mPowerManagerInternal); 313 314 mWmService.onInitReady(); 315 mAmService.setWindowManager(mWmService); 316 mWmService.mDisplayEnabled = true; 317 mWmService.mDisplayReady = true; 318 // Set configuration for default display 319 mWmService.getDefaultDisplayContentLocked().reconfigureDisplayLocked(); 320 321 // Mock default display, and home stack. 322 final DisplayContent display = mAtmService.mRootWindowContainer.getDefaultDisplay(); 323 // Set default display to be in fullscreen mode. Devices with PC feature may start their 324 // default display in freeform mode but some of tests in WmTests have implicit assumption on 325 // that the default display is in fullscreen mode. 326 display.setDisplayWindowingMode(WINDOWING_MODE_FULLSCREEN); 327 spyOn(display); 328 final TaskDisplayArea taskDisplayArea = display.getDefaultTaskDisplayArea(); 329 330 // Set the default focused TDA. 331 display.onLastFocusedTaskDisplayAreaChanged(taskDisplayArea); 332 spyOn(taskDisplayArea); 333 final Task homeStack = taskDisplayArea.getRootTask( 334 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME); 335 spyOn(homeStack); 336 } 337 338 private void tearDown() { 339 mWmService.mRoot.forAllDisplayPolicies(DisplayPolicy::release); 340 341 // Unregister display listener from root to avoid issues with subsequent tests. 342 mContext.getSystemService(DisplayManager.class) 343 .unregisterDisplayListener(mAtmService.mRootWindowContainer); 344 // The constructor of WindowManagerService registers WindowManagerConstants and 345 // HighRefreshRateBlacklist with DeviceConfig. We need to undo that here to avoid 346 // leaking mWmService. 347 mWmService.mConstants.dispose(); 348 mWmService.mHighRefreshRateDenylist.dispose(); 349 350 // This makes sure the posted messages without delay are processed, e.g. 351 // DisplayPolicy#release, WindowManagerService#setAnimationScale. 352 waitUntilWindowManagerHandlersIdle(); 353 // Clear all posted messages with delay, so they don't be executed at unexpected times. 354 cleanupWindowManagerHandlers(); 355 // Needs to explicitly dispose current static threads because there could be messages 356 // scheduled at a later time, and all mocks are invalid when it's executed. 357 DisplayThread.dispose(); 358 // Dispose SurfaceAnimationThread before AnimationThread does, so it won't create a new 359 // AnimationThread after AnimationThread disposed, see {@link 360 // AnimatorListenerAdapter#onAnimationEnd()} 361 SurfaceAnimationThread.dispose(); 362 AnimationThread.dispose(); 363 UiThread.dispose(); 364 mInputChannel.dispose(); 365 366 tearDownLocalServices(); 367 // Reset priority booster because animation thread has been changed. 368 WindowManagerService.sThreadPriorityBooster = new WindowManagerThreadPriorityBooster(); 369 370 mMockitoSession.finishMocking(); 371 Mockito.framework().clearInlineMocks(); 372 } 373 374 private static void tearDownLocalServices() { 375 LocalServices.removeServiceForTest(DisplayManagerInternal.class); 376 LocalServices.removeServiceForTest(PowerManagerInternal.class); 377 LocalServices.removeServiceForTest(ActivityManagerInternal.class); 378 LocalServices.removeServiceForTest(ActivityTaskManagerInternal.class); 379 LocalServices.removeServiceForTest(WindowManagerInternal.class); 380 LocalServices.removeServiceForTest(WindowManagerPolicy.class); 381 LocalServices.removeServiceForTest(PackageManagerInternal.class); 382 LocalServices.removeServiceForTest(UriGrantsManagerInternal.class); 383 LocalServices.removeServiceForTest(PermissionPolicyInternal.class); 384 LocalServices.removeServiceForTest(ColorDisplayService.ColorDisplayServiceInternal.class); 385 LocalServices.removeServiceForTest(UsageStatsManagerInternal.class); 386 LocalServices.removeServiceForTest(StatusBarManagerInternal.class); 387 } 388 389 Description getDescription() { 390 return mDescription; 391 } 392 393 WindowManagerService getWindowManagerService() { 394 return mWmService; 395 } 396 397 ActivityTaskManagerService getActivityTaskManagerService() { 398 return mAtmService; 399 } 400 401 WindowState.PowerManagerWrapper getPowerManagerWrapper() { 402 return mPowerManagerWrapper; 403 } 404 405 void setSurfaceFactory(Supplier<Surface> factory) { 406 mSurfaceFactory = factory; 407 } 408 409 void cleanupWindowManagerHandlers() { 410 final WindowManagerService wm = getWindowManagerService(); 411 if (wm == null) { 412 return; 413 } 414 wm.mH.removeCallbacksAndMessages(null); 415 wm.mAnimationHandler.removeCallbacksAndMessages(null); 416 // This is a different handler object than the wm.mAnimationHandler above. 417 AnimationThread.getHandler().removeCallbacksAndMessages(null); 418 SurfaceAnimationThread.getHandler().removeCallbacksAndMessages(null); 419 } 420 421 void waitUntilWindowManagerHandlersIdle() { 422 final WindowManagerService wm = getWindowManagerService(); 423 if (wm == null) { 424 return; 425 } 426 waitHandlerIdle(wm.mH); 427 waitHandlerIdle(wm.mAnimationHandler); 428 // This is a different handler object than the wm.mAnimationHandler above. 429 waitHandlerIdle(AnimationThread.getHandler()); 430 waitHandlerIdle(SurfaceAnimationThread.getHandler()); 431 } 432 433 static void waitHandlerIdle(Handler handler) { 434 handler.runWithScissors(() -> { }, 0 /* timeout */); 435 } 436 437 void waitUntilWindowAnimatorIdle() { 438 final WindowManagerService wm = getWindowManagerService(); 439 if (wm == null) { 440 return; 441 } 442 // Add a message to the handler queue and make sure it is fully processed before we move on. 443 // This makes sure all previous messages in the handler are fully processed vs. just popping 444 // them from the message queue. 445 final AtomicBoolean currentMessagesProcessed = new AtomicBoolean(false); 446 wm.mAnimator.getChoreographer().postFrameCallback(time -> { 447 synchronized (currentMessagesProcessed) { 448 currentMessagesProcessed.set(true); 449 currentMessagesProcessed.notifyAll(); 450 } 451 }); 452 while (!currentMessagesProcessed.get()) { 453 synchronized (currentMessagesProcessed) { 454 try { 455 currentMessagesProcessed.wait(); 456 } catch (InterruptedException e) { 457 } 458 } 459 } 460 } 461 462 /** 463 * Throws if caller doesn't hold the given lock. 464 * @param lock the lock 465 */ 466 static void checkHoldsLock(Object lock) { 467 if (!Thread.holdsLock(lock)) { 468 throw new IllegalStateException("Caller doesn't hold global lock."); 469 } 470 } 471 472 protected class TestActivityTaskManagerService extends ActivityTaskManagerService { 473 // ActivityTaskSupervisor may be created more than once while setting up AMS and ATMS. 474 // We keep the reference in order to prevent creating it twice. 475 ActivityTaskSupervisor mTestTaskSupervisor; 476 477 TestActivityTaskManagerService(Context context, ActivityManagerService ams) { 478 super(context); 479 spyOn(this); 480 481 mSupportsMultiWindow = true; 482 mSupportsMultiDisplay = true; 483 mSupportsSplitScreenMultiWindow = true; 484 mSupportsFreeformWindowManagement = true; 485 mSupportsPictureInPicture = true; 486 mDevEnableNonResizableMultiWindow = false; 487 mMinPercentageMultiWindowSupportHeight = 0.3f; 488 mMinPercentageMultiWindowSupportWidth = 0.5f; 489 mLargeScreenSmallestScreenWidthDp = 600; 490 mSupportsNonResizableMultiWindow = 0; 491 mRespectsActivityMinWidthHeightMultiWindow = 0; 492 mForceResizableActivities = false; 493 494 doReturn(mock(IPackageManager.class)).when(this).getPackageManager(); 495 // allow background activity starts by default 496 doReturn(true).when(this).isBackgroundActivityStartsEnabled(); 497 doNothing().when(this).updateCpuStats(); 498 499 // AppOpsService 500 final AppOpsManager aos = mock(AppOpsManager.class); 501 doReturn(aos).when(this).getAppOpsManager(); 502 // Make sure permission checks aren't overridden. 503 doReturn(AppOpsManager.MODE_DEFAULT).when(aos).noteOpNoThrow(anyInt(), anyInt(), 504 anyString(), nullable(String.class), nullable(String.class)); 505 506 // UserManagerService 507 final UserManagerService ums = mock(UserManagerService.class); 508 doReturn(ums).when(this).getUserManager(); 509 doReturn(TEST_USER_PROFILE_IDS).when(ums).getProfileIds(anyInt(), eq(true)); 510 511 setUsageStatsManager(LocalServices.getService(UsageStatsManagerInternal.class)); 512 ams.mActivityTaskManager = this; 513 ams.mAtmInternal = mInternal; 514 onActivityManagerInternalAdded(); 515 516 final IntentFirewall intentFirewall = mock(IntentFirewall.class); 517 doReturn(true).when(intentFirewall).checkStartActivity( 518 any(), anyInt(), anyInt(), nullable(String.class), any()); 519 initialize(intentFirewall, null /* intentController */, 520 DisplayThread.getHandler().getLooper()); 521 spyOn(getLifecycleManager()); 522 spyOn(getLockTaskController()); 523 spyOn(getTaskChangeNotificationController()); 524 525 AppWarnings appWarnings = getAppWarningsLocked(); 526 spyOn(appWarnings); 527 doNothing().when(appWarnings).onStartActivity(any()); 528 } 529 530 @Override 531 int handleIncomingUser(int callingPid, int callingUid, int userId, String name) { 532 return userId; 533 } 534 535 @Override 536 protected ActivityTaskSupervisor createTaskSupervisor() { 537 if (mTestTaskSupervisor == null) { 538 mTestTaskSupervisor = new TestActivityTaskSupervisor(this, mH.getLooper()); 539 } 540 return mTestTaskSupervisor; 541 } 542 } 543 544 /** 545 * An {@link ActivityTaskSupervisor} which stubs out certain methods that depend on 546 * setup not available in the test environment. Also specifies an injector for 547 */ 548 protected class TestActivityTaskSupervisor extends ActivityTaskSupervisor { 549 550 TestActivityTaskSupervisor(ActivityTaskManagerService service, Looper looper) { 551 super(service, looper); 552 spyOn(this); 553 554 // Do not schedule idle that may touch methods outside the scope of the test. 555 doNothing().when(this).scheduleIdle(); 556 doNothing().when(this).scheduleIdleTimeout(any()); 557 // unit test version does not handle launch wake lock 558 doNothing().when(this).acquireLaunchWakelock(); 559 560 mLaunchingActivityWakeLock = mock(PowerManager.WakeLock.class); 561 562 initialize(); 563 564 final KeyguardController controller = getKeyguardController(); 565 spyOn(controller); 566 doReturn(true).when(controller).checkKeyguardVisibility(any()); 567 } 568 } 569 570 // TODO: Can we just mock this? 571 private static class AMTestInjector extends ActivityManagerService.Injector { 572 573 AMTestInjector(Context context) { 574 super(context); 575 } 576 577 @Override 578 public Context getContext() { 579 return getInstrumentation().getTargetContext(); 580 } 581 582 @Override 583 public AppOpsService getAppOpsService(File file, Handler handler) { 584 return null; 585 } 586 587 @Override 588 public Handler getUiHandler(ActivityManagerService service) { 589 return UiThread.getHandler(); 590 } 591 592 @Override 593 public boolean isNetworkRestrictedForUid(int uid) { 594 return false; 595 } 596 } 597 } 598