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