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