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