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