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