1 /* 2 * Copyright (C) 2016 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.AppOpsManager.OP_NONE; 20 import static android.app.WindowConfiguration.ACTIVITY_TYPE_DREAM; 21 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; 22 import static android.app.WindowConfiguration.ROTATION_UNDEFINED; 23 import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; 24 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; 25 import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW; 26 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; 27 import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE; 28 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 29 import static android.content.res.Configuration.ORIENTATION_LANDSCAPE; 30 import static android.os.Process.SYSTEM_UID; 31 import static android.view.View.VISIBLE; 32 import static android.view.WindowManager.DISPLAY_IME_POLICY_FALLBACK_DISPLAY; 33 import static android.view.WindowManager.DISPLAY_IME_POLICY_LOCAL; 34 import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW; 35 import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; 36 import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW; 37 import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS; 38 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG; 39 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY; 40 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING; 41 import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION; 42 import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER; 43 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD; 44 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG; 45 import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR; 46 import static android.view.WindowManager.LayoutParams.TYPE_NOTIFICATION_SHADE; 47 import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR; 48 import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER; 49 50 import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation; 51 52 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer; 53 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing; 54 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; 55 import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; 56 import static com.android.server.wm.WindowContainer.POSITION_BOTTOM; 57 import static com.android.server.wm.WindowContainer.POSITION_TOP; 58 import static com.android.server.wm.WindowStateAnimator.HAS_DRAWN; 59 60 import static org.junit.Assert.assertEquals; 61 import static org.junit.Assert.assertFalse; 62 import static org.mockito.ArgumentMatchers.any; 63 import static org.mockito.ArgumentMatchers.anyBoolean; 64 import static org.mockito.ArgumentMatchers.anyInt; 65 import static org.mockito.Mockito.mock; 66 67 import android.annotation.IntDef; 68 import android.annotation.NonNull; 69 import android.annotation.Nullable; 70 import android.app.ActivityOptions; 71 import android.content.ComponentName; 72 import android.content.ContentResolver; 73 import android.content.Context; 74 import android.content.Intent; 75 import android.content.pm.ActivityInfo; 76 import android.content.pm.ApplicationInfo; 77 import android.content.res.Configuration; 78 import android.graphics.Insets; 79 import android.graphics.Rect; 80 import android.hardware.HardwareBuffer; 81 import android.hardware.display.DisplayManager; 82 import android.os.Binder; 83 import android.os.Build; 84 import android.os.Bundle; 85 import android.os.Handler; 86 import android.os.IBinder; 87 import android.os.RemoteException; 88 import android.os.UserHandle; 89 import android.provider.Settings; 90 import android.service.voice.IVoiceInteractionSession; 91 import android.util.MergedConfiguration; 92 import android.util.SparseArray; 93 import android.view.Display; 94 import android.view.DisplayInfo; 95 import android.view.Gravity; 96 import android.view.IDisplayWindowInsetsController; 97 import android.view.IWindow; 98 import android.view.IWindowSessionCallback; 99 import android.view.InsetsFrameProvider; 100 import android.view.InsetsSourceControl; 101 import android.view.InsetsState; 102 import android.view.Surface; 103 import android.view.SurfaceControl; 104 import android.view.SurfaceControl.Transaction; 105 import android.view.View; 106 import android.view.WindowInsets; 107 import android.view.WindowManager; 108 import android.view.WindowManager.DisplayImePolicy; 109 import android.view.inputmethod.ImeTracker; 110 import android.window.ActivityWindowInfo; 111 import android.window.ClientWindowFrames; 112 import android.window.ITaskFragmentOrganizer; 113 import android.window.ITransitionPlayer; 114 import android.window.ScreenCapture; 115 import android.window.StartingWindowInfo; 116 import android.window.StartingWindowRemovalInfo; 117 import android.window.TaskFragmentOrganizer; 118 import android.window.TransitionInfo; 119 import android.window.TransitionRequestInfo; 120 import android.window.WindowContainerTransaction; 121 122 import com.android.internal.policy.AttributeCache; 123 import com.android.internal.util.ArrayUtils; 124 import com.android.internal.util.test.FakeSettingsProvider; 125 import com.android.server.wallpaper.WallpaperCropper.WallpaperCropUtils; 126 import com.android.server.wm.DisplayWindowSettings.SettingsProvider.SettingsEntry; 127 128 import org.junit.After; 129 import org.junit.Before; 130 import org.junit.BeforeClass; 131 import org.junit.runner.Description; 132 import org.mockito.Mockito; 133 134 import java.lang.annotation.Annotation; 135 import java.lang.annotation.ElementType; 136 import java.lang.annotation.Retention; 137 import java.lang.annotation.RetentionPolicy; 138 import java.lang.annotation.Target; 139 import java.util.ArrayList; 140 import java.util.HashMap; 141 import java.util.List; 142 143 /** Common base class for window manager unit test classes. */ 144 class WindowTestsBase extends SystemServiceTestsBase { 145 final Context mContext = getInstrumentation().getTargetContext(); 146 147 // Default package name 148 static final String DEFAULT_COMPONENT_PACKAGE_NAME = "com.foo"; 149 150 static final int DEFAULT_TASK_FRAGMENT_ORGANIZER_UID = 10000; 151 static final String DEFAULT_TASK_FRAGMENT_ORGANIZER_PROCESS_NAME = "Test:TaskFragmentOrganizer"; 152 153 // Default base activity name 154 private static final String DEFAULT_COMPONENT_CLASS_NAME = ".BarActivity"; 155 156 // An id appended to the end of the component name to make it unique 157 static int sCurrentActivityId = 0; 158 159 ActivityTaskManagerService mAtm; 160 RootWindowContainer mRootWindowContainer; 161 ActivityTaskSupervisor mSupervisor; 162 ClientLifecycleManager mClientLifecycleManager; 163 WindowManagerService mWm; 164 private final IWindow mIWindow = new TestIWindow(); 165 private Session mTestSession; 166 private boolean mUseFakeSettingsProvider; 167 168 DisplayInfo mDisplayInfo = new DisplayInfo(); 169 DisplayContent mDefaultDisplay; 170 171 static final int STATUS_BAR_HEIGHT = 10; 172 static final int NAV_BAR_HEIGHT = 15; 173 174 /** 175 * It is {@link #mDefaultDisplay} by default. If the test class or method is annotated with 176 * {@link UseTestDisplay}, it will be an additional display. 177 */ 178 DisplayContent mDisplayContent; 179 180 // The following fields are only available depending on the usage of annotation UseTestDisplay 181 // and UseCommonWindows. 182 WindowState mWallpaperWindow; 183 WindowState mImeWindow; 184 WindowState mImeDialogWindow; 185 WindowState mStatusBarWindow; 186 WindowState mNotificationShadeWindow; 187 WindowState mDockedDividerWindow; 188 WindowState mNavBarWindow; 189 WindowState mAppWindow; 190 WindowState mChildAppWindowAbove; 191 WindowState mChildAppWindowBelow; 192 193 /** 194 * Spied {@link Transaction} class than can be used to verify calls. 195 */ 196 Transaction mTransaction; 197 198 /** 199 * Whether device-specific global overrides have already been checked in 200 * {@link WindowTestsBase#setUpBase()}. 201 */ 202 private static boolean sGlobalOverridesChecked; 203 /** 204 * Whether device-specific overrides have already been checked in 205 * {@link WindowTestsBase#setUpBase()} when the default display is used. 206 */ 207 private static boolean sOverridesCheckedDefaultDisplay; 208 /** 209 * Whether device-specific overrides have already been checked in 210 * {@link WindowTestsBase#setUpBase()} when a {@link TestDisplayContent} is used. 211 */ 212 private static boolean sOverridesCheckedTestDisplay; 213 214 private boolean mOriginalPerDisplayFocusEnabled; 215 216 @BeforeClass setUpOnceBase()217 public static void setUpOnceBase() { 218 AttributeCache.init(getInstrumentation().getTargetContext()); 219 } 220 221 @Before setUpBase()222 public void setUpBase() { 223 mAtm = mSystemServicesTestRule.getActivityTaskManagerService(); 224 mSupervisor = mAtm.mTaskSupervisor; 225 mRootWindowContainer = mAtm.mRootWindowContainer; 226 mClientLifecycleManager = mAtm.getLifecycleManager(); 227 mWm = mSystemServicesTestRule.getWindowManagerService(); 228 mOriginalPerDisplayFocusEnabled = mWm.mPerDisplayFocusEnabled; 229 SystemServicesTestRule.checkHoldsLock(mWm.mGlobalLock); 230 231 mDefaultDisplay = mWm.mRoot.getDefaultDisplay(); 232 // Update the display policy to make the screen fully turned on so animation is allowed 233 final DisplayPolicy displayPolicy = mDefaultDisplay.getDisplayPolicy(); 234 displayPolicy.screenTurningOn(null /* screenOnListener */); 235 displayPolicy.finishKeyguardDrawn(); 236 displayPolicy.finishWindowsDrawn(); 237 displayPolicy.finishScreenTurningOn(); 238 239 final InsetsPolicy insetsPolicy = mDefaultDisplay.getInsetsPolicy(); 240 suppressInsetsAnimation(insetsPolicy.getTransientControlTarget()); 241 suppressInsetsAnimation(insetsPolicy.getPermanentControlTarget()); 242 243 mTransaction = mSystemServicesTestRule.mTransaction; 244 245 mContext.getSystemService(DisplayManager.class) 246 .getDisplay(Display.DEFAULT_DISPLAY).getDisplayInfo(mDisplayInfo); 247 248 // Only create an additional test display for annotated test class/method because it may 249 // significantly increase the execution time. 250 final Description description = mSystemServicesTestRule.getDescription(); 251 final UseTestDisplay useTestDisplay = getAnnotation(description, UseTestDisplay.class); 252 if (useTestDisplay != null) { 253 createTestDisplay(useTestDisplay); 254 } else { 255 mDisplayContent = mDefaultDisplay; 256 final SetupWindows setupWindows = getAnnotation(description, SetupWindows.class); 257 if (setupWindows != null) { 258 addCommonWindows(setupWindows.addAllCommonWindows(), setupWindows.addWindows()); 259 } 260 } 261 262 // Ensure letterbox aspect ratio is not overridden on any device target. 263 // {@link com.android.internal.R.dimen.config_fixedOrientationLetterboxAspectRatio}, is set 264 // on some device form factors. 265 mAtm.mWindowManager.mLetterboxConfiguration.setFixedOrientationLetterboxAspectRatio(0); 266 // Ensure letterbox horizontal position multiplier is not overridden on any device target. 267 // {@link com.android.internal.R.dimen.config_letterboxHorizontalPositionMultiplier}, 268 // may be set on some device form factors. 269 mAtm.mWindowManager.mLetterboxConfiguration.setLetterboxHorizontalPositionMultiplier(0.5f); 270 // Ensure letterbox vertical position multiplier is not overridden on any device target. 271 // {@link com.android.internal.R.dimen.config_letterboxHorizontalPositionMultiplier}, 272 // may be set on some device form factors. 273 mAtm.mWindowManager.mLetterboxConfiguration.setLetterboxVerticalPositionMultiplier(0.0f); 274 // Ensure letterbox horizontal reachability treatment isn't overridden on any device target. 275 // {@link com.android.internal.R.bool.config_letterboxIsHorizontalReachabilityEnabled}, 276 // may be set on some device form factors. 277 mAtm.mWindowManager.mLetterboxConfiguration.setIsHorizontalReachabilityEnabled(false); 278 // Ensure letterbox vertical reachability treatment isn't overridden on any device target. 279 // {@link com.android.internal.R.bool.config_letterboxIsVerticalReachabilityEnabled}, 280 // may be set on some device form factors. 281 mAtm.mWindowManager.mLetterboxConfiguration.setIsVerticalReachabilityEnabled(false); 282 // Ensure aspect ratio for unresizable apps isn't overridden on any device target. 283 // {@link com.android.internal.R.bool 284 // .config_letterboxIsSplitScreenAspectRatioForUnresizableAppsEnabled}, may be set on some 285 // device form factors. 286 mAtm.mWindowManager.mLetterboxConfiguration 287 .setIsSplitScreenAspectRatioForUnresizableAppsEnabled(false); 288 // Ensure aspect ratio for al apps isn't overridden on any device target. 289 // {@link com.android.internal.R.bool 290 // .config_letterboxIsDisplayAspectRatioForFixedOrientationLetterboxEnabled}, may be set on 291 // some device form factors. 292 mAtm.mWindowManager.mLetterboxConfiguration 293 .setIsDisplayAspectRatioEnabledForFixedOrientationLetterbox(false); 294 295 // Setup WallpaperController crop utils with a simple center-align strategy 296 WallpaperCropUtils cropUtils = (displaySize, bitmapSize, suggestedCrops, rtl) -> { 297 Rect crop = new Rect(0, 0, displaySize.x, displaySize.y); 298 crop.scale(Math.min( 299 ((float) bitmapSize.x) / displaySize.x, 300 ((float) bitmapSize.y) / displaySize.y)); 301 crop.offset((bitmapSize.x - crop.width()) / 2, (bitmapSize.y - crop.height()) / 2); 302 return crop; 303 }; 304 mDisplayContent.mWallpaperController.setWallpaperCropUtils(cropUtils); 305 mDefaultDisplay.mWallpaperController.setWallpaperCropUtils(cropUtils); 306 307 checkDeviceSpecificOverridesNotApplied(); 308 } 309 310 /** 311 * The test doesn't create real SurfaceControls, but mocked ones. This prevents the target from 312 * controlling them, or it will cause {@link NullPointerException}. 313 */ suppressInsetsAnimation(InsetsControlTarget target)314 static void suppressInsetsAnimation(InsetsControlTarget target) { 315 spyOn(target); 316 Mockito.doNothing().when(target).notifyInsetsControlChanged(anyInt()); 317 } 318 319 @After tearDown()320 public void tearDown() throws Exception { 321 if (mUseFakeSettingsProvider) { 322 FakeSettingsProvider.clearSettingsProvider(); 323 } 324 mWm.mPerDisplayFocusEnabled = mOriginalPerDisplayFocusEnabled; 325 } 326 327 /** 328 * Check that device-specific overrides are not applied. Only need to check once during entire 329 * test run for each case: global overrides, default display, and test display. 330 */ checkDeviceSpecificOverridesNotApplied()331 private void checkDeviceSpecificOverridesNotApplied() { 332 // Check global overrides 333 if (!sGlobalOverridesChecked) { 334 assertEquals(0, mWm.mLetterboxConfiguration.getFixedOrientationLetterboxAspectRatio(), 335 0 /* delta */); 336 sGlobalOverridesChecked = true; 337 } 338 // Check display-specific overrides 339 if (!sOverridesCheckedDefaultDisplay && mDisplayContent == mDefaultDisplay) { 340 assertFalse(mDisplayContent.getIgnoreOrientationRequest()); 341 sOverridesCheckedDefaultDisplay = true; 342 } else if (!sOverridesCheckedTestDisplay && mDisplayContent instanceof TestDisplayContent) { 343 assertFalse(mDisplayContent.getIgnoreOrientationRequest()); 344 sOverridesCheckedTestDisplay = true; 345 } 346 } 347 createTestDisplay(UseTestDisplay annotation)348 private void createTestDisplay(UseTestDisplay annotation) { 349 beforeCreateTestDisplay(); 350 mDisplayContent = createNewDisplayWithImeSupport(DISPLAY_IME_POLICY_LOCAL); 351 addCommonWindows(annotation.addAllCommonWindows(), annotation.addWindows()); 352 mDisplayContent.getDisplayPolicy().setRemoteInsetsControllerControlsSystemBars(false); 353 354 // Adding a display will cause freezing the display. Make sure to wait until it's 355 // unfrozen to not run into race conditions with the tests. 356 waitUntilHandlersIdle(); 357 } 358 addCommonWindows(boolean addAll, @CommonTypes int[] requestedWindows)359 private void addCommonWindows(boolean addAll, @CommonTypes int[] requestedWindows) { 360 if (addAll || ArrayUtils.contains(requestedWindows, W_WALLPAPER)) { 361 mWallpaperWindow = createCommonWindow(null, TYPE_WALLPAPER, "wallpaperWindow"); 362 } 363 if (addAll || ArrayUtils.contains(requestedWindows, W_INPUT_METHOD)) { 364 mImeWindow = createCommonWindow(null, TYPE_INPUT_METHOD, "mImeWindow"); 365 mDisplayContent.mInputMethodWindow = mImeWindow; 366 } 367 if (addAll || ArrayUtils.contains(requestedWindows, W_INPUT_METHOD_DIALOG)) { 368 mImeDialogWindow = createCommonWindow(null, TYPE_INPUT_METHOD_DIALOG, 369 "mImeDialogWindow"); 370 } 371 if (addAll || ArrayUtils.contains(requestedWindows, W_STATUS_BAR)) { 372 mStatusBarWindow = createCommonWindow(null, TYPE_STATUS_BAR, "mStatusBarWindow"); 373 mStatusBarWindow.mAttrs.height = STATUS_BAR_HEIGHT; 374 mStatusBarWindow.mAttrs.gravity = Gravity.TOP; 375 mStatusBarWindow.mAttrs.layoutInDisplayCutoutMode = 376 LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS; 377 mStatusBarWindow.mAttrs.setFitInsetsTypes(0); 378 final IBinder owner = new Binder(); 379 mStatusBarWindow.mAttrs.providedInsets = new InsetsFrameProvider[] { 380 new InsetsFrameProvider(owner, 0, WindowInsets.Type.statusBars()), 381 new InsetsFrameProvider(owner, 0, WindowInsets.Type.tappableElement()), 382 new InsetsFrameProvider(owner, 0, WindowInsets.Type.mandatorySystemGestures()) 383 }; 384 } 385 if (addAll || ArrayUtils.contains(requestedWindows, W_NOTIFICATION_SHADE)) { 386 mNotificationShadeWindow = createCommonWindow(null, TYPE_NOTIFICATION_SHADE, 387 "mNotificationShadeWindow"); 388 } 389 if (addAll || ArrayUtils.contains(requestedWindows, W_NAVIGATION_BAR)) { 390 mNavBarWindow = createCommonWindow(null, TYPE_NAVIGATION_BAR, "mNavBarWindow"); 391 mNavBarWindow.mAttrs.height = NAV_BAR_HEIGHT; 392 mNavBarWindow.mAttrs.gravity = Gravity.BOTTOM; 393 mNavBarWindow.mAttrs.paramsForRotation = new WindowManager.LayoutParams[4]; 394 mNavBarWindow.mAttrs.setFitInsetsTypes(0); 395 mNavBarWindow.mAttrs.layoutInDisplayCutoutMode = 396 LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS; 397 mNavBarWindow.mAttrs.privateFlags |= 398 WindowManager.LayoutParams.PRIVATE_FLAG_LAYOUT_SIZE_EXTENDED_BY_CUTOUT; 399 final IBinder owner = new Binder(); 400 mNavBarWindow.mAttrs.providedInsets = new InsetsFrameProvider[] { 401 new InsetsFrameProvider(owner, 0, WindowInsets.Type.navigationBars()), 402 new InsetsFrameProvider(owner, 0, WindowInsets.Type.tappableElement()), 403 new InsetsFrameProvider(owner, 0, WindowInsets.Type.mandatorySystemGestures()) 404 }; 405 // If the navigation bar cannot move then it is always at the bottom. 406 if (mDisplayContent.getDisplayPolicy().navigationBarCanMove()) { 407 for (int rot = Surface.ROTATION_0; rot <= Surface.ROTATION_270; rot++) { 408 mNavBarWindow.mAttrs.paramsForRotation[rot] = 409 getNavBarLayoutParamsForRotation(rot, owner); 410 } 411 } 412 } 413 if (addAll || ArrayUtils.contains(requestedWindows, W_DOCK_DIVIDER)) { 414 mDockedDividerWindow = createCommonWindow(null, TYPE_DOCK_DIVIDER, 415 "mDockedDividerWindow"); 416 } 417 final boolean addAboveApp = ArrayUtils.contains(requestedWindows, W_ABOVE_ACTIVITY); 418 final boolean addBelowApp = ArrayUtils.contains(requestedWindows, W_BELOW_ACTIVITY); 419 if (addAll || addAboveApp || addBelowApp 420 || ArrayUtils.contains(requestedWindows, W_ACTIVITY)) { 421 mAppWindow = createCommonWindow(null, TYPE_BASE_APPLICATION, "mAppWindow"); 422 } 423 if (addAll || addAboveApp) { 424 mChildAppWindowAbove = createCommonWindow(mAppWindow, TYPE_APPLICATION_ATTACHED_DIALOG, 425 "mChildAppWindowAbove"); 426 } 427 if (addAll || addBelowApp) { 428 mChildAppWindowBelow = createCommonWindow(mAppWindow, TYPE_APPLICATION_MEDIA_OVERLAY, 429 "mChildAppWindowBelow"); 430 } 431 } 432 getNavBarLayoutParamsForRotation( int rotation, IBinder owner)433 private WindowManager.LayoutParams getNavBarLayoutParamsForRotation( 434 int rotation, IBinder owner) { 435 int width = WindowManager.LayoutParams.MATCH_PARENT; 436 int height = WindowManager.LayoutParams.MATCH_PARENT; 437 int gravity = Gravity.BOTTOM; 438 switch (rotation) { 439 case ROTATION_UNDEFINED: 440 case Surface.ROTATION_0: 441 case Surface.ROTATION_180: 442 height = NAV_BAR_HEIGHT; 443 break; 444 case Surface.ROTATION_90: 445 gravity = Gravity.RIGHT; 446 width = NAV_BAR_HEIGHT; 447 break; 448 case Surface.ROTATION_270: 449 gravity = Gravity.LEFT; 450 width = NAV_BAR_HEIGHT; 451 break; 452 } 453 WindowManager.LayoutParams lp = new WindowManager.LayoutParams( 454 WindowManager.LayoutParams.TYPE_NAVIGATION_BAR); 455 lp.width = width; 456 lp.height = height; 457 lp.gravity = gravity; 458 lp.setFitInsetsTypes(0); 459 lp.privateFlags |= 460 WindowManager.LayoutParams.PRIVATE_FLAG_LAYOUT_SIZE_EXTENDED_BY_CUTOUT; 461 lp.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS; 462 lp.providedInsets = new InsetsFrameProvider[] { 463 new InsetsFrameProvider(owner, 0, WindowInsets.Type.navigationBars()), 464 new InsetsFrameProvider(owner, 0, WindowInsets.Type.tappableElement()), 465 new InsetsFrameProvider(owner, 0, WindowInsets.Type.mandatorySystemGestures()) 466 }; 467 return lp; 468 } 469 beforeCreateTestDisplay()470 void beforeCreateTestDisplay() { 471 // Called before display is created. 472 } 473 474 /** Avoid writing values to real Settings. */ useFakeSettingsProvider()475 ContentResolver useFakeSettingsProvider() { 476 mUseFakeSettingsProvider = true; 477 FakeSettingsProvider.clearSettingsProvider(); 478 final FakeSettingsProvider provider = new FakeSettingsProvider(); 479 // SystemServicesTestRule#setUpSystemCore has called spyOn for the ContentResolver. 480 final ContentResolver resolver = mContext.getContentResolver(); 481 doReturn(provider.getIContentProvider()).when(resolver).acquireProvider(Settings.AUTHORITY); 482 return resolver; 483 } 484 createCommonWindow(WindowState parent, int type, String name)485 private WindowState createCommonWindow(WindowState parent, int type, String name) { 486 final WindowState win = createWindow(parent, type, name); 487 // Prevent common windows from been IME targets. 488 win.mAttrs.flags |= FLAG_NOT_FOCUSABLE; 489 return win; 490 } 491 createWindowToken( DisplayContent dc, int windowingMode, int activityType, int type)492 private WindowToken createWindowToken( 493 DisplayContent dc, int windowingMode, int activityType, int type) { 494 if (type == TYPE_WALLPAPER) { 495 return createWallpaperToken(dc); 496 } 497 if (type < FIRST_APPLICATION_WINDOW || type > LAST_APPLICATION_WINDOW) { 498 return createTestWindowToken(type, dc); 499 } 500 501 return createActivityRecord(dc, windowingMode, activityType); 502 } 503 createWallpaperToken(DisplayContent dc)504 private WindowToken createWallpaperToken(DisplayContent dc) { 505 return new WallpaperWindowToken(mWm, mock(IBinder.class), true /* explicit */, dc, 506 true /* ownerCanManageAppTokens */); 507 } 508 createNavBarWithProvidedInsets(DisplayContent dc)509 WindowState createNavBarWithProvidedInsets(DisplayContent dc) { 510 final WindowState navbar = createWindow(null, TYPE_NAVIGATION_BAR, dc, "navbar"); 511 final Binder owner = new Binder(); 512 navbar.mAttrs.providedInsets = new InsetsFrameProvider[] { 513 new InsetsFrameProvider(owner, 0, WindowInsets.Type.navigationBars()) 514 .setInsetsSize(Insets.of(0, 0, 0, NAV_BAR_HEIGHT)) 515 }; 516 dc.getDisplayPolicy().addWindowLw(navbar, navbar.mAttrs); 517 return navbar; 518 } 519 createStatusBarWithProvidedInsets(DisplayContent dc)520 WindowState createStatusBarWithProvidedInsets(DisplayContent dc) { 521 final WindowState statusBar = createWindow(null, TYPE_STATUS_BAR, dc, "statusBar"); 522 final Binder owner = new Binder(); 523 statusBar.mAttrs.providedInsets = new InsetsFrameProvider[] { 524 new InsetsFrameProvider(owner, 0, WindowInsets.Type.statusBars()) 525 .setInsetsSize(Insets.of(0, STATUS_BAR_HEIGHT, 0, 0)) 526 }; 527 statusBar.mAttrs.setFitInsetsTypes(0); 528 dc.getDisplayPolicy().addWindowLw(statusBar, statusBar.mAttrs); 529 return statusBar; 530 } 531 getTestSession()532 Session getTestSession() { 533 if (mTestSession != null) { 534 return mTestSession; 535 } 536 mTestSession = createTestSession(mAtm); 537 return mTestSession; 538 } 539 getTestSession(WindowToken token)540 private Session getTestSession(WindowToken token) { 541 final ActivityRecord r = token.asActivityRecord(); 542 if (r == null || r.app == null) { 543 return getTestSession(); 544 } 545 // If the activity has a process, let the window session belonging to activity use the 546 // process of the activity. 547 int pid = r.app.getPid(); 548 if (pid == 0) { 549 // See SystemServicesTestRule#addProcess, pid 0 isn't added to the map. So generate 550 // a non-zero pid to initialize it. 551 final int numPid = mAtm.mProcessMap.getPidMap().size(); 552 pid = numPid > 0 ? mAtm.mProcessMap.getPidMap().keyAt(numPid - 1) + 1 : 1; 553 r.app.setPid(pid); 554 mAtm.mProcessMap.put(pid, r.app); 555 } else { 556 final WindowState win = mRootWindowContainer.getWindow(w -> w.getProcess() == r.app); 557 if (win != null) { 558 // Reuse the same Session if there is a window uses the same process. 559 return win.mSession; 560 } 561 } 562 return createTestSession(mAtm, pid, r.getUid()); 563 } 564 createTestSession(ActivityTaskManagerService atms)565 static Session createTestSession(ActivityTaskManagerService atms) { 566 return createTestSession(atms, WindowManagerService.MY_PID, WindowManagerService.MY_UID); 567 } 568 createTestSession(ActivityTaskManagerService atms, int pid, int uid)569 static Session createTestSession(ActivityTaskManagerService atms, int pid, int uid) { 570 if (atms.mProcessMap.getProcess(pid) == null) { 571 SystemServicesTestRule.addProcess(atms, "testPkg", "testProc", pid, uid); 572 } 573 return new Session(atms.mWindowManager, new IWindowSessionCallback.Stub() { 574 @Override 575 public void onAnimatorScaleChanged(float scale) { 576 } 577 }, pid, uid); 578 } 579 createAppWindow(Task task, int type, String name)580 WindowState createAppWindow(Task task, int type, String name) { 581 final ActivityRecord activity = createNonAttachedActivityRecord(task.getDisplayContent()); 582 task.addChild(activity, 0); 583 return createWindow(null, type, activity, name); 584 } 585 createDreamWindow(WindowState parent, int type, String name)586 WindowState createDreamWindow(WindowState parent, int type, String name) { 587 final WindowToken token = createWindowToken( 588 mDisplayContent, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_DREAM, type); 589 return createWindow(parent, type, token, name); 590 } 591 592 // TODO: Move these calls to a builder? createWindow(WindowState parent, int type, DisplayContent dc, String name, IWindow iwindow)593 WindowState createWindow(WindowState parent, int type, DisplayContent dc, String name, 594 IWindow iwindow) { 595 final WindowToken token = createWindowToken( 596 dc, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, type); 597 return createWindow(parent, type, token, name, 0 /* ownerId */, 598 false /* ownerCanAddInternalSystemWindow */, iwindow); 599 } 600 createWindow(WindowState parent, int type, String name)601 WindowState createWindow(WindowState parent, int type, String name) { 602 return (parent == null) 603 ? createWindow(parent, type, mDisplayContent, name) 604 : createWindow(parent, type, parent.mToken, name); 605 } 606 createWindow(WindowState parent, int type, String name, int ownerId)607 WindowState createWindow(WindowState parent, int type, String name, int ownerId) { 608 return (parent == null) 609 ? createWindow(parent, type, mDisplayContent, name, ownerId) 610 : createWindow(parent, type, parent.mToken, name, ownerId); 611 } 612 createWindow(WindowState parent, int windowingMode, int activityType, int type, DisplayContent dc, String name)613 WindowState createWindow(WindowState parent, int windowingMode, int activityType, 614 int type, DisplayContent dc, String name) { 615 final WindowToken token = createWindowToken(dc, windowingMode, activityType, type); 616 return createWindow(parent, type, token, name); 617 } 618 createWindow(WindowState parent, int type, DisplayContent dc, String name)619 WindowState createWindow(WindowState parent, int type, DisplayContent dc, String name) { 620 return createWindow( 621 parent, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, type, dc, name); 622 } 623 createWindow(WindowState parent, int type, DisplayContent dc, String name, int ownerId)624 WindowState createWindow(WindowState parent, int type, DisplayContent dc, String name, 625 int ownerId) { 626 final WindowToken token = createWindowToken( 627 dc, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, type); 628 return createWindow(parent, type, token, name, ownerId); 629 } 630 createWindow(WindowState parent, int type, DisplayContent dc, String name, boolean ownerCanAddInternalSystemWindow)631 WindowState createWindow(WindowState parent, int type, DisplayContent dc, String name, 632 boolean ownerCanAddInternalSystemWindow) { 633 final WindowToken token = createWindowToken( 634 dc, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, type); 635 return createWindow(parent, type, token, name, 0 /* ownerId */, 636 ownerCanAddInternalSystemWindow); 637 } 638 createWindow(WindowState parent, int type, WindowToken token, String name)639 WindowState createWindow(WindowState parent, int type, WindowToken token, String name) { 640 return createWindow(parent, type, token, name, 0 /* ownerId */, 641 false /* ownerCanAddInternalSystemWindow */); 642 } 643 createWindow(WindowState parent, int type, WindowToken token, String name, int ownerId)644 WindowState createWindow(WindowState parent, int type, WindowToken token, String name, 645 int ownerId) { 646 return createWindow(parent, type, token, name, ownerId, 647 false /* ownerCanAddInternalSystemWindow */); 648 } 649 createWindow(WindowState parent, int type, WindowToken token, String name, int ownerId, boolean ownerCanAddInternalSystemWindow)650 WindowState createWindow(WindowState parent, int type, WindowToken token, String name, 651 int ownerId, boolean ownerCanAddInternalSystemWindow) { 652 return createWindow(parent, type, token, name, ownerId, ownerCanAddInternalSystemWindow, 653 mIWindow); 654 } 655 createWindow(WindowState parent, int type, WindowToken token, String name, int ownerId, boolean ownerCanAddInternalSystemWindow, IWindow iwindow)656 WindowState createWindow(WindowState parent, int type, WindowToken token, String name, 657 int ownerId, boolean ownerCanAddInternalSystemWindow, IWindow iwindow) { 658 return createWindow(parent, type, token, name, ownerId, UserHandle.getUserId(ownerId), 659 ownerCanAddInternalSystemWindow, mWm, getTestSession(token), iwindow); 660 } 661 createWindow(WindowState parent, int type, WindowToken token, String name, int ownerId, int userId, boolean ownerCanAddInternalSystemWindow, WindowManagerService service, Session session, IWindow iWindow)662 static WindowState createWindow(WindowState parent, int type, WindowToken token, 663 String name, int ownerId, int userId, boolean ownerCanAddInternalSystemWindow, 664 WindowManagerService service, Session session, IWindow iWindow) { 665 SystemServicesTestRule.checkHoldsLock(service.mGlobalLock); 666 667 final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(type); 668 attrs.setTitle(name); 669 attrs.packageName = "test"; 670 671 final WindowState w = new WindowState(service, session, iWindow, token, parent, 672 OP_NONE, attrs, VISIBLE, ownerId, userId, ownerCanAddInternalSystemWindow); 673 // TODO: Probably better to make this call in the WindowState ctor to avoid errors with 674 // adding it to the token... 675 token.addWindow(w); 676 return w; 677 } 678 makeWindowVisible(WindowState... windows)679 static void makeWindowVisible(WindowState... windows) { 680 for (WindowState win : windows) { 681 win.mViewVisibility = View.VISIBLE; 682 win.mRelayoutCalled = true; 683 win.mHasSurface = true; 684 win.mHidden = false; 685 win.show(false /* doAnimation */, false /* requestAnim */); 686 } 687 } 688 makeWindowVisibleAndDrawn(WindowState... windows)689 static void makeWindowVisibleAndDrawn(WindowState... windows) { 690 makeWindowVisible(windows); 691 for (WindowState win : windows) { 692 win.mWinAnimator.mDrawState = HAS_DRAWN; 693 } 694 } 695 makeLastConfigReportedToClient(WindowState w, boolean visible)696 static void makeLastConfigReportedToClient(WindowState w, boolean visible) { 697 w.fillClientWindowFramesAndConfiguration(new ClientWindowFrames(), 698 new MergedConfiguration(), new ActivityWindowInfo(), true /* useLatestConfig */, 699 visible); 700 } 701 702 /** 703 * Gets the order of the given {@link Task} as its z-order in the hierarchy below this TDA. 704 * The Task can be a direct child of a child TaskDisplayArea. {@code -1} if not found. 705 */ getTaskIndexOf(TaskDisplayArea taskDisplayArea, Task task)706 static int getTaskIndexOf(TaskDisplayArea taskDisplayArea, Task task) { 707 int index = 0; 708 final int childCount = taskDisplayArea.getChildCount(); 709 for (int i = 0; i < childCount; i++) { 710 final WindowContainer wc = taskDisplayArea.getChildAt(i); 711 if (wc.asTask() != null) { 712 if (wc.asTask() == task) { 713 return index; 714 } 715 index++; 716 } else { 717 final TaskDisplayArea tda = wc.asTaskDisplayArea(); 718 final int subIndex = getTaskIndexOf(tda, task); 719 if (subIndex > -1) { 720 return index + subIndex; 721 } else { 722 index += tda.getRootTaskCount(); 723 } 724 } 725 } 726 return -1; 727 } 728 729 /** Creates a {@link TaskDisplayArea} right above the default one. */ createTaskDisplayArea(DisplayContent displayContent, WindowManagerService service, String name, int displayAreaFeature)730 static TaskDisplayArea createTaskDisplayArea(DisplayContent displayContent, 731 WindowManagerService service, String name, int displayAreaFeature) { 732 final TaskDisplayArea newTaskDisplayArea = new TaskDisplayArea( 733 displayContent, service, name, displayAreaFeature); 734 final TaskDisplayArea defaultTaskDisplayArea = displayContent.getDefaultTaskDisplayArea(); 735 736 // Insert the new TDA to the correct position. 737 defaultTaskDisplayArea.getParent().addChild(newTaskDisplayArea, 738 defaultTaskDisplayArea.getParent().mChildren.indexOf(defaultTaskDisplayArea) 739 + 1); 740 return newTaskDisplayArea; 741 } 742 743 /** 744 * Creates a {@link Task} with a simple {@link ActivityRecord} and adds to the given 745 * {@link TaskDisplayArea}. 746 */ createTaskWithActivity(TaskDisplayArea taskDisplayArea, int windowingMode, int activityType, boolean onTop, boolean twoLevelTask)747 Task createTaskWithActivity(TaskDisplayArea taskDisplayArea, 748 int windowingMode, int activityType, boolean onTop, boolean twoLevelTask) { 749 return createTask(taskDisplayArea, windowingMode, activityType, 750 onTop, true /* createActivity */, twoLevelTask); 751 } 752 753 /** Creates a {@link Task} and adds to the given {@link DisplayContent}. */ createTask(DisplayContent dc)754 Task createTask(DisplayContent dc) { 755 return createTask(dc.getDefaultTaskDisplayArea(), 756 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD); 757 } 758 createTask(DisplayContent dc, int windowingMode, int activityType)759 Task createTask(DisplayContent dc, int windowingMode, int activityType) { 760 return createTask(dc.getDefaultTaskDisplayArea(), windowingMode, activityType); 761 } 762 createTask(TaskDisplayArea taskDisplayArea, int windowingMode, int activityType)763 Task createTask(TaskDisplayArea taskDisplayArea, int windowingMode, int activityType) { 764 return createTask(taskDisplayArea, windowingMode, activityType, 765 true /* onTop */, false /* createActivity */, false /* twoLevelTask */); 766 } 767 768 /** Creates a {@link Task} and adds to the given {@link TaskDisplayArea}. */ createTask(TaskDisplayArea taskDisplayArea, int windowingMode, int activityType, boolean onTop, boolean createActivity, boolean twoLevelTask)769 Task createTask(TaskDisplayArea taskDisplayArea, int windowingMode, int activityType, 770 boolean onTop, boolean createActivity, boolean twoLevelTask) { 771 final TaskBuilder builder = new TaskBuilder(mSupervisor) 772 .setTaskDisplayArea(taskDisplayArea) 773 .setWindowingMode(windowingMode) 774 .setActivityType(activityType) 775 .setOnTop(onTop) 776 .setCreateActivity(createActivity); 777 if (twoLevelTask) { 778 return builder 779 .setCreateParentTask(true) 780 .build() 781 .getRootTask(); 782 } else { 783 return builder.build(); 784 } 785 } 786 787 /** Creates a {@link Task} and adds to the given root {@link Task}. */ createTaskInRootTask(Task rootTask, int userId)788 Task createTaskInRootTask(Task rootTask, int userId) { 789 final Task task = new TaskBuilder(rootTask.mTaskSupervisor) 790 .setUserId(userId) 791 .setParentTask(rootTask) 792 .build(); 793 return task; 794 } 795 796 /** Creates an {@link ActivityRecord}. */ createNonAttachedActivityRecord(DisplayContent dc)797 static ActivityRecord createNonAttachedActivityRecord(DisplayContent dc) { 798 final ActivityRecord activity = new ActivityBuilder(dc.mWmService.mAtmService) 799 .setOnTop(true) 800 .build(); 801 postCreateActivitySetup(activity, dc); 802 return activity; 803 } 804 805 /** 806 * Creates an {@link ActivityRecord} and adds it to a new created {@link Task}. 807 * [Task] - [ActivityRecord] 808 */ createActivityRecord(DisplayContent dc)809 ActivityRecord createActivityRecord(DisplayContent dc) { 810 return createActivityRecord(dc, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD); 811 } 812 813 /** 814 * Creates an {@link ActivityRecord} and adds it to a new created {@link Task}. 815 * [Task] - [ActivityRecord] 816 */ createActivityRecord(DisplayContent dc, int windowingMode, int activityType)817 ActivityRecord createActivityRecord(DisplayContent dc, int windowingMode, 818 int activityType) { 819 final Task task = createTask(dc, windowingMode, activityType); 820 return createActivityRecord(dc, task); 821 } 822 823 /** 824 * Creates an {@link ActivityRecord} and adds it to the specified {@link Task}. 825 * [Task] - [ActivityRecord] 826 */ createActivityRecord(Task task)827 static ActivityRecord createActivityRecord(Task task) { 828 return createActivityRecord(task.getDisplayContent(), task); 829 } 830 831 /** 832 * Creates an {@link ActivityRecord} and adds it to the specified {@link Task}. 833 * [Task] - [ActivityRecord] 834 */ createActivityRecord(DisplayContent dc, Task task)835 static ActivityRecord createActivityRecord(DisplayContent dc, Task task) { 836 final ActivityRecord activity = new ActivityBuilder(dc.mWmService.mAtmService) 837 .setTask(task) 838 .setOnTop(true) 839 .build(); 840 postCreateActivitySetup(activity, dc); 841 return activity; 842 } 843 844 /** 845 * Creates an {@link ActivityRecord} and adds it to a new created {@link Task}. 846 * Then adds the new created {@link Task} to a new created parent {@link Task} 847 * [Task1] - [Task2] - [ActivityRecord] 848 */ createActivityRecordWithParentTask(DisplayContent dc, int windowingMode, int activityType)849 ActivityRecord createActivityRecordWithParentTask(DisplayContent dc, int windowingMode, 850 int activityType) { 851 final Task task = createTask(dc, windowingMode, activityType); 852 return createActivityRecordWithParentTask(task); 853 } 854 855 /** 856 * Creates an {@link ActivityRecord} and adds it to a new created {@link Task}. 857 * Then adds the new created {@link Task} to the specified parent {@link Task} 858 * [Task1] - [Task2] - [ActivityRecord] 859 */ createActivityRecordWithParentTask(Task parentTask)860 static ActivityRecord createActivityRecordWithParentTask(Task parentTask) { 861 final ActivityRecord activity = new ActivityBuilder(parentTask.mAtmService) 862 .setParentTask(parentTask) 863 .setCreateTask(true) 864 .setOnTop(true) 865 .build(); 866 postCreateActivitySetup(activity, parentTask.getDisplayContent()); 867 return activity; 868 } 869 postCreateActivitySetup(ActivityRecord activity, DisplayContent dc)870 private static void postCreateActivitySetup(ActivityRecord activity, DisplayContent dc) { 871 activity.onDisplayChanged(dc); 872 activity.setOccludesParent(true); 873 activity.setVisible(true); 874 activity.setVisibleRequested(true); 875 } 876 877 /** 878 * Creates a {@link TaskFragment} with {@link ActivityRecord}, and attaches it to the 879 * {@code parentTask}. 880 * 881 * @param parentTask the {@link Task} this {@link TaskFragment} is going to be attached. 882 * @return the created {@link TaskFragment} 883 */ createTaskFragmentWithActivity(@onNull Task parentTask)884 static TaskFragment createTaskFragmentWithActivity(@NonNull Task parentTask) { 885 return new TaskFragmentBuilder(parentTask.mAtmService) 886 .setParentTask(parentTask) 887 .createActivityCount(1) 888 .build(); 889 } 890 891 /** 892 * Creates an embedded {@link TaskFragment} organized by {@code organizer} with 893 * {@link ActivityRecord}, and attaches it to the {@code parentTask}. 894 * 895 * @param parentTask the {@link Task} this {@link TaskFragment} is going to be attached. 896 * @param organizer the {@link TaskFragmentOrganizer} this {@link TaskFragment} is going to be 897 * organized by. 898 * @return the created {@link TaskFragment} 899 */ createTaskFragmentWithEmbeddedActivity(@onNull Task parentTask, @NonNull TaskFragmentOrganizer organizer)900 static TaskFragment createTaskFragmentWithEmbeddedActivity(@NonNull Task parentTask, 901 @NonNull TaskFragmentOrganizer organizer) { 902 final IBinder fragmentToken = new Binder(); 903 final TaskFragment taskFragment = new TaskFragmentBuilder(parentTask.mAtmService) 904 .setParentTask(parentTask) 905 .createActivityCount(1) 906 .setOrganizer(organizer) 907 .setFragmentToken(fragmentToken) 908 .build(); 909 parentTask.mAtmService.mWindowOrganizerController.mLaunchTaskFragments 910 .put(fragmentToken, taskFragment); 911 return taskFragment; 912 } 913 914 /** @see TaskFragmentOrganizerController#registerOrganizer */ registerTaskFragmentOrganizer(@onNull ITaskFragmentOrganizer organizer)915 void registerTaskFragmentOrganizer(@NonNull ITaskFragmentOrganizer organizer) { 916 registerTaskFragmentOrganizer(organizer, false /* isSystemOrganizer */); 917 } 918 919 /** @see TaskFragmentOrganizerController#registerOrganizer */ registerTaskFragmentOrganizer(@onNull ITaskFragmentOrganizer organizer, boolean isSystemOrganizer)920 void registerTaskFragmentOrganizer(@NonNull ITaskFragmentOrganizer organizer, 921 boolean isSystemOrganizer) { 922 // Ensure there is an IApplicationThread to dispatch TaskFragmentTransaction. 923 if (mAtm.mProcessMap.getProcess(WindowManagerService.MY_PID) == null) { 924 mSystemServicesTestRule.addProcess("pkgName", "procName", 925 WindowManagerService.MY_PID, WindowManagerService.MY_UID); 926 } 927 mAtm.mTaskFragmentOrganizerController.registerOrganizer(organizer, isSystemOrganizer); 928 } 929 930 /** Creates a {@link DisplayContent} that supports IME and adds it to the system. */ createNewDisplay()931 DisplayContent createNewDisplay() { 932 return createNewDisplayWithImeSupport(DISPLAY_IME_POLICY_LOCAL); 933 } 934 935 /** Creates a {@link DisplayContent} and adds it to the system. */ createNewDisplayWithImeSupport(@isplayImePolicy int imePolicy)936 private DisplayContent createNewDisplayWithImeSupport(@DisplayImePolicy int imePolicy) { 937 return createNewDisplay(mDisplayInfo, imePolicy, /* overrideSettings */ null); 938 } 939 940 /** Creates a {@link DisplayContent} that supports IME and adds it to the system. */ createNewDisplay(DisplayInfo info)941 DisplayContent createNewDisplay(DisplayInfo info) { 942 return createNewDisplay(info, DISPLAY_IME_POLICY_LOCAL, /* overrideSettings */ null); 943 } 944 945 /** Creates a {@link DisplayContent} and adds it to the system. */ createNewDisplay(DisplayInfo info, @DisplayImePolicy int imePolicy, @Nullable SettingsEntry overrideSettings)946 private DisplayContent createNewDisplay(DisplayInfo info, @DisplayImePolicy int imePolicy, 947 @Nullable SettingsEntry overrideSettings) { 948 final DisplayContent display = 949 new TestDisplayContent.Builder(mAtm, info) 950 .setOverrideSettings(overrideSettings) 951 .build(); 952 final DisplayContent dc = display.mDisplayContent; 953 // this display can show IME. 954 dc.mWmService.mDisplayWindowSettings.setDisplayImePolicy(dc, imePolicy); 955 return dc; 956 } 957 958 /** 959 * Creates a {@link DisplayContent} with given display state and adds it to the system. 960 * 961 * @param displayState For initializing the state of the display. See 962 * {@link Display#getState()}. 963 */ createNewDisplay(int displayState)964 DisplayContent createNewDisplay(int displayState) { 965 // Leverage main display info & initialize it with display state for given displayId. 966 DisplayInfo displayInfo = new DisplayInfo(); 967 displayInfo.copyFrom(mDisplayInfo); 968 displayInfo.state = displayState; 969 return createNewDisplay(displayInfo, DISPLAY_IME_POLICY_LOCAL, /* overrideSettings */ null); 970 } 971 972 /** Creates a {@link TestWindowState} */ createWindowState(WindowManager.LayoutParams attrs, WindowToken token)973 TestWindowState createWindowState(WindowManager.LayoutParams attrs, WindowToken token) { 974 SystemServicesTestRule.checkHoldsLock(mWm.mGlobalLock); 975 976 return new TestWindowState(mWm, getTestSession(), mIWindow, attrs, token); 977 } 978 979 /** Creates a {@link DisplayContent} as parts of simulate display info for test. */ createMockSimulatedDisplay()980 DisplayContent createMockSimulatedDisplay() { 981 return createMockSimulatedDisplay(/* overrideSettings */ null); 982 } 983 createMockSimulatedDisplay(@ullable SettingsEntry overrideSettings)984 DisplayContent createMockSimulatedDisplay(@Nullable SettingsEntry overrideSettings) { 985 DisplayInfo displayInfo = new DisplayInfo(); 986 displayInfo.copyFrom(mDisplayInfo); 987 displayInfo.type = Display.TYPE_VIRTUAL; 988 displayInfo.state = Display.STATE_ON; 989 displayInfo.ownerUid = SYSTEM_UID; 990 return createNewDisplay(displayInfo, DISPLAY_IME_POLICY_FALLBACK_DISPLAY, overrideSettings); 991 } 992 createDisplayWindowInsetsController()993 IDisplayWindowInsetsController createDisplayWindowInsetsController() { 994 return new IDisplayWindowInsetsController.Stub() { 995 996 @Override 997 public void insetsChanged(InsetsState insetsState) throws RemoteException { 998 } 999 1000 @Override 1001 public void insetsControlChanged(InsetsState insetsState, 1002 InsetsSourceControl[] insetsSourceControls) throws RemoteException { 1003 } 1004 1005 @Override 1006 public void showInsets(int i, boolean b, @Nullable ImeTracker.Token t) 1007 throws RemoteException { 1008 } 1009 1010 @Override 1011 public void hideInsets(int i, boolean b, @Nullable ImeTracker.Token t) 1012 throws RemoteException { 1013 } 1014 1015 @Override 1016 public void topFocusedWindowChanged(ComponentName component, 1017 int requestedVisibleTypes) { 1018 } 1019 1020 @Override 1021 public void setImeInputTargetRequestedVisibility(boolean visible) { 1022 } 1023 }; 1024 } 1025 createTestBLASTSyncEngine()1026 BLASTSyncEngine createTestBLASTSyncEngine() { 1027 return createTestBLASTSyncEngine(mWm.mH); 1028 } 1029 createTestBLASTSyncEngine(Handler handler)1030 BLASTSyncEngine createTestBLASTSyncEngine(Handler handler) { 1031 return new BLASTSyncEngine(mWm, handler) { 1032 @Override 1033 void scheduleTimeout(SyncGroup s, long timeoutMs) { 1034 // Disable timeout. 1035 } 1036 }; 1037 } 1038 1039 /** Sets up a simple implementation of transition player for shell transitions. */ registerTestTransitionPlayer()1040 TestTransitionPlayer registerTestTransitionPlayer() { 1041 final TestTransitionPlayer testPlayer = new TestTransitionPlayer( 1042 mAtm.getTransitionController(), mAtm.mWindowOrganizerController); 1043 testPlayer.mController.registerTransitionPlayer(testPlayer, null /* playerProc */); 1044 return testPlayer; 1045 } 1046 1047 /** Overrides the behavior of config_reverseDefaultRotation for the given display. */ setReverseDefaultRotation(DisplayContent dc, boolean reverse)1048 void setReverseDefaultRotation(DisplayContent dc, boolean reverse) { 1049 final DisplayRotation displayRotation = dc.getDisplayRotation(); 1050 if (!Mockito.mockingDetails(displayRotation).isSpy()) { 1051 spyOn(displayRotation); 1052 } 1053 doAnswer(invocation -> { 1054 invocation.callRealMethod(); 1055 final int w = invocation.getArgument(0); 1056 final int h = invocation.getArgument(1); 1057 if (w > h) { 1058 if (reverse) { 1059 displayRotation.mPortraitRotation = Surface.ROTATION_90; 1060 displayRotation.mUpsideDownRotation = Surface.ROTATION_270; 1061 } else { 1062 displayRotation.mPortraitRotation = Surface.ROTATION_270; 1063 displayRotation.mUpsideDownRotation = Surface.ROTATION_90; 1064 } 1065 } else { 1066 if (reverse) { 1067 displayRotation.mLandscapeRotation = Surface.ROTATION_270; 1068 displayRotation.mSeascapeRotation = Surface.ROTATION_90; 1069 } else { 1070 displayRotation.mLandscapeRotation = Surface.ROTATION_90; 1071 displayRotation.mSeascapeRotation = Surface.ROTATION_270; 1072 } 1073 } 1074 return null; 1075 }).when(displayRotation).configure(anyInt(), anyInt()); 1076 displayRotation.configure(dc.mBaseDisplayWidth, dc.mBaseDisplayHeight); 1077 } 1078 1079 /** 1080 * Performs surface placement and waits for WindowAnimator to complete the frame. It is used 1081 * to execute the callbacks if the surface placement is expected to add some callbacks via 1082 * {@link WindowAnimator#addAfterPrepareSurfacesRunnable}. 1083 */ performSurfacePlacementAndWaitForWindowAnimator()1084 void performSurfacePlacementAndWaitForWindowAnimator() { 1085 mWm.mAnimator.ready(); 1086 if (!mWm.mWindowPlacerLocked.isTraversalScheduled()) { 1087 mRootWindowContainer.performSurfacePlacement(); 1088 } else { 1089 waitHandlerIdle(mWm.mAnimationHandler); 1090 } 1091 waitUntilWindowAnimatorIdle(); 1092 } 1093 1094 /** 1095 * Avoids rotating screen disturbed by some conditions. It is usually used for the default 1096 * display that is not the instance of {@link TestDisplayContent} (it bypasses the conditions). 1097 * 1098 * @see DisplayRotation#updateRotationUnchecked 1099 */ unblockDisplayRotation(DisplayContent dc)1100 void unblockDisplayRotation(DisplayContent dc) { 1101 dc.mOpeningApps.clear(); 1102 mWm.mAppsFreezingScreen = 0; 1103 mWm.stopFreezingDisplayLocked(); 1104 // The rotation animation won't actually play, it needs to be cleared manually. 1105 dc.setRotationAnimation(null); 1106 } 1107 resizeDisplay(DisplayContent displayContent, int width, int height)1108 static void resizeDisplay(DisplayContent displayContent, int width, int height) { 1109 displayContent.updateBaseDisplayMetrics(width, height, displayContent.mBaseDisplayDensity, 1110 displayContent.mBaseDisplayPhysicalXDpi, displayContent.mBaseDisplayPhysicalYDpi); 1111 displayContent.getDisplayRotation().configure(width, height); 1112 final Configuration c = new Configuration(); 1113 displayContent.computeScreenConfiguration(c); 1114 displayContent.onRequestedOverrideConfigurationChanged(c); 1115 } 1116 1117 /** Used for the tests that assume the display is portrait by default. */ makeDisplayPortrait(DisplayContent displayContent)1118 static void makeDisplayPortrait(DisplayContent displayContent) { 1119 if (displayContent.mBaseDisplayHeight <= displayContent.mBaseDisplayWidth) { 1120 resizeDisplay(displayContent, 500, 1000); 1121 } 1122 } 1123 1124 // The window definition for UseTestDisplay#addWindows. The test can declare to add only 1125 // necessary windows, that avoids adding unnecessary overhead of unused windows. 1126 static final int W_NOTIFICATION_SHADE = TYPE_NOTIFICATION_SHADE; 1127 static final int W_STATUS_BAR = TYPE_STATUS_BAR; 1128 static final int W_NAVIGATION_BAR = TYPE_NAVIGATION_BAR; 1129 static final int W_INPUT_METHOD_DIALOG = TYPE_INPUT_METHOD_DIALOG; 1130 static final int W_INPUT_METHOD = TYPE_INPUT_METHOD; 1131 static final int W_DOCK_DIVIDER = TYPE_DOCK_DIVIDER; 1132 static final int W_ABOVE_ACTIVITY = TYPE_APPLICATION_ATTACHED_DIALOG; 1133 static final int W_ACTIVITY = TYPE_BASE_APPLICATION; 1134 static final int W_BELOW_ACTIVITY = TYPE_APPLICATION_MEDIA_OVERLAY; 1135 static final int W_WALLPAPER = TYPE_WALLPAPER; 1136 1137 /** The common window types supported by {@link UseTestDisplay}. */ 1138 @Retention(RetentionPolicy.RUNTIME) 1139 @IntDef(value = { 1140 W_NOTIFICATION_SHADE, 1141 W_STATUS_BAR, 1142 W_NAVIGATION_BAR, 1143 W_INPUT_METHOD_DIALOG, 1144 W_INPUT_METHOD, 1145 W_DOCK_DIVIDER, 1146 W_ABOVE_ACTIVITY, 1147 W_ACTIVITY, 1148 W_BELOW_ACTIVITY, 1149 W_WALLPAPER, 1150 }) 1151 @interface CommonTypes { 1152 } 1153 1154 /** 1155 * The annotation to provide common windows on default display. This is mutually exclusive 1156 * with {@link UseTestDisplay}. 1157 */ 1158 @Target({ ElementType.METHOD, ElementType.TYPE }) 1159 @Retention(RetentionPolicy.RUNTIME) 1160 @interface SetupWindows { addAllCommonWindows()1161 boolean addAllCommonWindows() default false; addWindows()1162 @CommonTypes int[] addWindows() default {}; 1163 } 1164 1165 /** 1166 * The annotation for class and method (higher priority) to create a non-default display that 1167 * will be assigned to {@link #mDisplayContent}. It is used if the test needs 1168 * <ul> 1169 * <li>Pure empty display.</li> 1170 * <li>Independent and customizable orientation.</li> 1171 * <li>Cross display operation.</li> 1172 * </ul> 1173 * 1174 * @see TestDisplayContent 1175 * @see #createTestDisplay 1176 **/ 1177 @Target({ ElementType.METHOD, ElementType.TYPE }) 1178 @Retention(RetentionPolicy.RUNTIME) 1179 @interface UseTestDisplay { addAllCommonWindows()1180 boolean addAllCommonWindows() default false; addWindows()1181 @CommonTypes int[] addWindows() default {}; 1182 } 1183 getAnnotation(Description desc, Class<T> type)1184 static <T extends Annotation> T getAnnotation(Description desc, Class<T> type) { 1185 final T annotation = desc.getAnnotation(type); 1186 if (annotation != null) return annotation; 1187 return desc.getTestClass().getAnnotation(type); 1188 } 1189 1190 /** Creates and adds a {@link TestDisplayContent} to supervisor at the given position. */ addNewDisplayContentAt(int position)1191 TestDisplayContent addNewDisplayContentAt(int position) { 1192 return new TestDisplayContent.Builder(mAtm, 1000, 1500).setPosition(position).build(); 1193 } 1194 1195 /** Sets the default minimum task size to 1 so that tests can use small task sizes */ removeGlobalMinSizeRestriction()1196 public void removeGlobalMinSizeRestriction() { 1197 mAtm.mRootWindowContainer.forAllDisplays( 1198 displayContent -> displayContent.mMinSizeOfResizeableTaskDp = 1); 1199 } 1200 1201 /** Mocks the behavior of taking a snapshot. */ mockSurfaceFreezerSnapshot(SurfaceFreezer surfaceFreezer)1202 void mockSurfaceFreezerSnapshot(SurfaceFreezer surfaceFreezer) { 1203 final ScreenCapture.ScreenshotHardwareBuffer screenshotBuffer = 1204 mock(ScreenCapture.ScreenshotHardwareBuffer.class); 1205 final HardwareBuffer hardwareBuffer = mock(HardwareBuffer.class); 1206 spyOn(surfaceFreezer); 1207 doReturn(screenshotBuffer).when(surfaceFreezer) 1208 .createSnapshotBufferInner(any(), any()); 1209 doReturn(null).when(surfaceFreezer) 1210 .createFromHardwareBufferInner(any()); 1211 doReturn(hardwareBuffer).when(screenshotBuffer).getHardwareBuffer(); 1212 doReturn(100).when(hardwareBuffer).getWidth(); 1213 doReturn(100).when(hardwareBuffer).getHeight(); 1214 } 1215 getUniqueComponentName()1216 static ComponentName getUniqueComponentName() { 1217 return ComponentName.createRelative(DEFAULT_COMPONENT_PACKAGE_NAME, 1218 DEFAULT_COMPONENT_CLASS_NAME + sCurrentActivityId++); 1219 } 1220 1221 /** 1222 * Builder for creating new activities. 1223 */ 1224 protected static class ActivityBuilder { 1225 static final int DEFAULT_FAKE_UID = 12345; 1226 static final String DEFAULT_PROCESS_NAME = "procName"; 1227 static int sProcNameSeq; 1228 1229 private final ActivityTaskManagerService mService; 1230 1231 private ComponentName mComponent; 1232 private String mTargetActivity; 1233 private Task mTask; 1234 private String mProcessName = DEFAULT_PROCESS_NAME; 1235 private String mAffinity; 1236 private int mUid = DEFAULT_FAKE_UID; 1237 private boolean mCreateTask = false; 1238 private Task mParentTask; 1239 private int mActivityFlags; 1240 private int mActivityTheme; 1241 private int mLaunchMode; 1242 private int mResizeMode = RESIZE_MODE_RESIZEABLE; 1243 private float mMaxAspectRatio; 1244 private float mMinAspectRatio; 1245 private boolean mSupportsSizeChanges; 1246 private int mScreenOrientation = SCREEN_ORIENTATION_UNSPECIFIED; 1247 private boolean mLaunchTaskBehind = false; 1248 private int mConfigChanges; 1249 private int mLaunchedFromPid; 1250 private int mLaunchedFromUid; 1251 private String mLaunchedFromPackage; 1252 private WindowProcessController mWpc; 1253 private Bundle mIntentExtras; 1254 private boolean mOnTop = false; 1255 private ActivityInfo.WindowLayout mWindowLayout; 1256 private boolean mVisible = true; 1257 private String mRequiredDisplayCategory; 1258 private ActivityOptions mActivityOpts; 1259 ActivityBuilder(ActivityTaskManagerService service)1260 ActivityBuilder(ActivityTaskManagerService service) { 1261 mService = service; 1262 } 1263 setComponent(ComponentName component)1264 ActivityBuilder setComponent(ComponentName component) { 1265 mComponent = component; 1266 return this; 1267 } 1268 setTargetActivity(String targetActivity)1269 ActivityBuilder setTargetActivity(String targetActivity) { 1270 mTargetActivity = targetActivity; 1271 return this; 1272 } 1273 setIntentExtras(Bundle extras)1274 ActivityBuilder setIntentExtras(Bundle extras) { 1275 mIntentExtras = extras; 1276 return this; 1277 } 1278 getDefaultComponent()1279 static ComponentName getDefaultComponent() { 1280 return ComponentName.createRelative(DEFAULT_COMPONENT_PACKAGE_NAME, 1281 DEFAULT_COMPONENT_PACKAGE_NAME); 1282 } 1283 setTask(Task task)1284 ActivityBuilder setTask(Task task) { 1285 mTask = task; 1286 return this; 1287 } 1288 setActivityTheme(int theme)1289 ActivityBuilder setActivityTheme(int theme) { 1290 mActivityTheme = theme; 1291 // Use the real package of test so it can get a valid context for theme. 1292 mComponent = ComponentName.createRelative(mService.mContext.getPackageName(), 1293 DEFAULT_COMPONENT_CLASS_NAME + sCurrentActivityId++); 1294 return this; 1295 } 1296 setActivityFlags(int flags)1297 ActivityBuilder setActivityFlags(int flags) { 1298 mActivityFlags = flags; 1299 return this; 1300 } 1301 setLaunchMode(int launchMode)1302 ActivityBuilder setLaunchMode(int launchMode) { 1303 mLaunchMode = launchMode; 1304 return this; 1305 } 1306 setParentTask(Task parentTask)1307 ActivityBuilder setParentTask(Task parentTask) { 1308 mParentTask = parentTask; 1309 return this; 1310 } 1311 setCreateTask(boolean createTask)1312 ActivityBuilder setCreateTask(boolean createTask) { 1313 mCreateTask = createTask; 1314 return this; 1315 } 1316 setProcessName(String name)1317 ActivityBuilder setProcessName(String name) { 1318 mProcessName = name; 1319 return this; 1320 } 1321 setUid(int uid)1322 ActivityBuilder setUid(int uid) { 1323 mUid = uid; 1324 return this; 1325 } 1326 setResizeMode(int resizeMode)1327 ActivityBuilder setResizeMode(int resizeMode) { 1328 mResizeMode = resizeMode; 1329 return this; 1330 } 1331 setMaxAspectRatio(float maxAspectRatio)1332 ActivityBuilder setMaxAspectRatio(float maxAspectRatio) { 1333 mMaxAspectRatio = maxAspectRatio; 1334 return this; 1335 } 1336 setMinAspectRatio(float minAspectRatio)1337 ActivityBuilder setMinAspectRatio(float minAspectRatio) { 1338 mMinAspectRatio = minAspectRatio; 1339 return this; 1340 } 1341 setSupportsSizeChanges(boolean supportsSizeChanges)1342 ActivityBuilder setSupportsSizeChanges(boolean supportsSizeChanges) { 1343 mSupportsSizeChanges = supportsSizeChanges; 1344 return this; 1345 } 1346 setScreenOrientation(int screenOrientation)1347 ActivityBuilder setScreenOrientation(int screenOrientation) { 1348 mScreenOrientation = screenOrientation; 1349 return this; 1350 } 1351 setLaunchTaskBehind(boolean launchTaskBehind)1352 ActivityBuilder setLaunchTaskBehind(boolean launchTaskBehind) { 1353 mLaunchTaskBehind = launchTaskBehind; 1354 return this; 1355 } 1356 setConfigChanges(int configChanges)1357 ActivityBuilder setConfigChanges(int configChanges) { 1358 mConfigChanges = configChanges; 1359 return this; 1360 } 1361 setLaunchedFromPid(int pid)1362 ActivityBuilder setLaunchedFromPid(int pid) { 1363 mLaunchedFromPid = pid; 1364 return this; 1365 } 1366 setLaunchedFromUid(int uid)1367 ActivityBuilder setLaunchedFromUid(int uid) { 1368 mLaunchedFromUid = uid; 1369 return this; 1370 } 1371 setLaunchedFromPackage(String packageName)1372 ActivityBuilder setLaunchedFromPackage(String packageName) { 1373 mLaunchedFromPackage = packageName; 1374 return this; 1375 } 1376 setUseProcess(WindowProcessController wpc)1377 ActivityBuilder setUseProcess(WindowProcessController wpc) { 1378 mWpc = wpc; 1379 return this; 1380 } 1381 setAffinity(String affinity)1382 ActivityBuilder setAffinity(String affinity) { 1383 mAffinity = affinity; 1384 return this; 1385 } 1386 setOnTop(boolean onTop)1387 ActivityBuilder setOnTop(boolean onTop) { 1388 mOnTop = onTop; 1389 return this; 1390 } 1391 setWindowLayout(ActivityInfo.WindowLayout windowLayout)1392 ActivityBuilder setWindowLayout(ActivityInfo.WindowLayout windowLayout) { 1393 mWindowLayout = windowLayout; 1394 return this; 1395 } 1396 setVisible(boolean visible)1397 ActivityBuilder setVisible(boolean visible) { 1398 mVisible = visible; 1399 return this; 1400 } 1401 setActivityOptions(ActivityOptions opts)1402 ActivityBuilder setActivityOptions(ActivityOptions opts) { 1403 mActivityOpts = opts; 1404 return this; 1405 } 1406 setRequiredDisplayCategory(String requiredDisplayCategory)1407 ActivityBuilder setRequiredDisplayCategory(String requiredDisplayCategory) { 1408 mRequiredDisplayCategory = requiredDisplayCategory; 1409 return this; 1410 } 1411 build()1412 ActivityRecord build() { 1413 SystemServicesTestRule.checkHoldsLock(mService.mGlobalLock); 1414 try { 1415 mService.deferWindowLayout(); 1416 return buildInner(); 1417 } finally { 1418 mService.continueWindowLayout(); 1419 } 1420 } 1421 buildInner()1422 ActivityRecord buildInner() { 1423 if (mComponent == null) { 1424 mComponent = getUniqueComponentName(); 1425 } 1426 1427 Intent intent = new Intent(); 1428 intent.setComponent(mComponent); 1429 if (mIntentExtras != null) { 1430 intent.putExtras(mIntentExtras); 1431 } 1432 final ActivityInfo aInfo = new ActivityInfo(); 1433 aInfo.applicationInfo = new ApplicationInfo(); 1434 aInfo.applicationInfo.targetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT; 1435 aInfo.applicationInfo.packageName = mComponent.getPackageName(); 1436 aInfo.applicationInfo.uid = mUid; 1437 if (DEFAULT_PROCESS_NAME.equals(mProcessName)) { 1438 mProcessName += ++sProcNameSeq; 1439 } 1440 aInfo.processName = mProcessName; 1441 aInfo.packageName = mComponent.getPackageName(); 1442 aInfo.name = mComponent.getClassName(); 1443 if (mTargetActivity != null) { 1444 aInfo.targetActivity = mTargetActivity; 1445 } 1446 if (mActivityTheme != 0) { 1447 aInfo.theme = mActivityTheme; 1448 } 1449 aInfo.flags |= mActivityFlags; 1450 aInfo.launchMode = mLaunchMode; 1451 aInfo.resizeMode = mResizeMode; 1452 aInfo.setMaxAspectRatio(mMaxAspectRatio); 1453 aInfo.setMinAspectRatio(mMinAspectRatio); 1454 aInfo.supportsSizeChanges = mSupportsSizeChanges; 1455 aInfo.screenOrientation = mScreenOrientation; 1456 aInfo.configChanges |= mConfigChanges; 1457 aInfo.taskAffinity = mAffinity; 1458 aInfo.windowLayout = mWindowLayout; 1459 if (mRequiredDisplayCategory != null) { 1460 aInfo.requiredDisplayCategory = mRequiredDisplayCategory; 1461 } 1462 1463 if (mCreateTask) { 1464 mTask = new TaskBuilder(mService.mTaskSupervisor) 1465 .setComponent(mComponent) 1466 // Apply the root activity info and intent 1467 .setActivityInfo(aInfo) 1468 .setIntent(intent) 1469 .setParentTask(mParentTask).build(); 1470 } else if (mTask == null && mParentTask != null && DisplayContent.alwaysCreateRootTask( 1471 mParentTask.getWindowingMode(), mParentTask.getActivityType())) { 1472 // The parent task can be the task root. 1473 mTask = mParentTask; 1474 } 1475 1476 ActivityOptions options = null; 1477 if (mActivityOpts != null) { 1478 options = mActivityOpts; 1479 } else if (mLaunchTaskBehind) { 1480 options = ActivityOptions.makeTaskLaunchBehind(); 1481 } 1482 final ActivityRecord activity = new ActivityRecord.Builder(mService) 1483 .setLaunchedFromPid(mLaunchedFromPid) 1484 .setLaunchedFromUid(mLaunchedFromUid) 1485 .setLaunchedFromPackage(mLaunchedFromPackage) 1486 .setIntent(intent) 1487 .setActivityInfo(aInfo) 1488 .setActivityOptions(options) 1489 .build(); 1490 1491 spyOn(activity); 1492 if (mTask != null) { 1493 mTask.addChild(activity); 1494 if (mOnTop) { 1495 // Move the task to front after activity is added. 1496 // Or {@link TaskDisplayArea#mPreferredTopFocusableRootTask} could be other 1497 // root tasks (e.g. home root task). 1498 mTask.moveToFront("createActivity"); 1499 } 1500 if (mVisible) { 1501 activity.setVisibleRequested(true); 1502 activity.setVisible(true); 1503 } 1504 } 1505 1506 final WindowProcessController wpc; 1507 if (mWpc != null) { 1508 wpc = mWpc; 1509 } else { 1510 final WindowProcessController p = mService.getProcessController(mProcessName, mUid); 1511 wpc = p != null ? p : SystemServicesTestRule.addProcess( 1512 mService, aInfo.applicationInfo, mProcessName, 0 /* pid */); 1513 } 1514 activity.setProcess(wpc); 1515 1516 // Resume top activities to make sure all other signals in the system are connected. 1517 mService.mRootWindowContainer.resumeFocusedTasksTopActivities(); 1518 return activity; 1519 } 1520 } 1521 1522 static class TaskFragmentBuilder { 1523 private final ActivityTaskManagerService mAtm; 1524 private Task mParentTask; 1525 private boolean mCreateParentTask; 1526 private int mCreateActivityCount = 0; 1527 @Nullable 1528 private TaskFragmentOrganizer mOrganizer; 1529 private IBinder mFragmentToken; 1530 private Rect mBounds; 1531 TaskFragmentBuilder(ActivityTaskManagerService service)1532 TaskFragmentBuilder(ActivityTaskManagerService service) { 1533 mAtm = service; 1534 } 1535 setCreateParentTask()1536 TaskFragmentBuilder setCreateParentTask() { 1537 mCreateParentTask = true; 1538 return this; 1539 } 1540 setParentTask(Task task)1541 TaskFragmentBuilder setParentTask(Task task) { 1542 mParentTask = task; 1543 return this; 1544 } 1545 createActivityCount(int count)1546 TaskFragmentBuilder createActivityCount(int count) { 1547 mCreateActivityCount = count; 1548 return this; 1549 } 1550 setOrganizer(@ullable TaskFragmentOrganizer organizer)1551 TaskFragmentBuilder setOrganizer(@Nullable TaskFragmentOrganizer organizer) { 1552 mOrganizer = organizer; 1553 return this; 1554 } 1555 setFragmentToken(@ullable IBinder fragmentToken)1556 TaskFragmentBuilder setFragmentToken(@Nullable IBinder fragmentToken) { 1557 mFragmentToken = fragmentToken; 1558 return this; 1559 } 1560 setBounds(@ullable Rect bounds)1561 TaskFragmentBuilder setBounds(@Nullable Rect bounds) { 1562 mBounds = bounds; 1563 return this; 1564 } 1565 build()1566 TaskFragment build() { 1567 SystemServicesTestRule.checkHoldsLock(mAtm.mGlobalLock); 1568 1569 final TaskFragment taskFragment = new TaskFragment(mAtm, mFragmentToken, 1570 mOrganizer != null); 1571 if (mParentTask == null && mCreateParentTask) { 1572 mParentTask = new TaskBuilder(mAtm.mTaskSupervisor).build(); 1573 } 1574 if (mParentTask != null) { 1575 mParentTask.addChild(taskFragment, POSITION_TOP); 1576 } 1577 while (mCreateActivityCount > 0) { 1578 final ActivityRecord activity = new ActivityBuilder(mAtm).build(); 1579 taskFragment.addChild(activity); 1580 mCreateActivityCount--; 1581 } 1582 if (mOrganizer != null) { 1583 taskFragment.setTaskFragmentOrganizer( 1584 mOrganizer.getOrganizerToken(), DEFAULT_TASK_FRAGMENT_ORGANIZER_UID, 1585 DEFAULT_TASK_FRAGMENT_ORGANIZER_PROCESS_NAME); 1586 } 1587 if (mBounds != null && !mBounds.isEmpty()) { 1588 taskFragment.setBounds(mBounds); 1589 } 1590 spyOn(taskFragment); 1591 return taskFragment; 1592 } 1593 } 1594 1595 /** 1596 * Builder for creating new tasks. 1597 */ 1598 protected static class TaskBuilder { 1599 private final ActivityTaskSupervisor mSupervisor; 1600 1601 private TaskDisplayArea mTaskDisplayArea; 1602 private ComponentName mComponent; 1603 private String mPackage; 1604 private int mFlags = 0; 1605 private int mTaskId = -1; 1606 private int mUserId = 0; 1607 private int mWindowingMode = WINDOWING_MODE_UNDEFINED; 1608 private int mActivityType = ACTIVITY_TYPE_STANDARD; 1609 private ActivityInfo mActivityInfo; 1610 private Intent mIntent; 1611 private boolean mOnTop = true; 1612 private IVoiceInteractionSession mVoiceSession; 1613 1614 private boolean mCreateParentTask = false; 1615 private Task mParentTask; 1616 1617 private boolean mCreateActivity = false; 1618 private boolean mCreatedByOrganizer = false; 1619 TaskBuilder(ActivityTaskSupervisor supervisor)1620 TaskBuilder(ActivityTaskSupervisor supervisor) { 1621 mSupervisor = supervisor; 1622 mTaskDisplayArea = mSupervisor.mRootWindowContainer.getDefaultTaskDisplayArea(); 1623 } 1624 1625 /** 1626 * Set the parent {@link DisplayContent} and use the default task display area. Overrides 1627 * the task display area, if was set before. 1628 */ setDisplay(DisplayContent display)1629 TaskBuilder setDisplay(DisplayContent display) { 1630 mTaskDisplayArea = display.getDefaultTaskDisplayArea(); 1631 return this; 1632 } 1633 1634 /** Set the parent {@link TaskDisplayArea}. Overrides the display, if was set before. */ setTaskDisplayArea(TaskDisplayArea taskDisplayArea)1635 TaskBuilder setTaskDisplayArea(TaskDisplayArea taskDisplayArea) { 1636 mTaskDisplayArea = taskDisplayArea; 1637 return this; 1638 } 1639 setComponent(ComponentName component)1640 TaskBuilder setComponent(ComponentName component) { 1641 mComponent = component; 1642 return this; 1643 } 1644 setPackage(String packageName)1645 TaskBuilder setPackage(String packageName) { 1646 mPackage = packageName; 1647 return this; 1648 } 1649 setFlags(int flags)1650 TaskBuilder setFlags(int flags) { 1651 mFlags = flags; 1652 return this; 1653 } 1654 setTaskId(int taskId)1655 TaskBuilder setTaskId(int taskId) { 1656 mTaskId = taskId; 1657 return this; 1658 } 1659 setUserId(int userId)1660 TaskBuilder setUserId(int userId) { 1661 mUserId = userId; 1662 return this; 1663 } 1664 setWindowingMode(int windowingMode)1665 TaskBuilder setWindowingMode(int windowingMode) { 1666 mWindowingMode = windowingMode; 1667 return this; 1668 } 1669 setActivityType(int activityType)1670 TaskBuilder setActivityType(int activityType) { 1671 mActivityType = activityType; 1672 return this; 1673 } 1674 setActivityInfo(ActivityInfo info)1675 TaskBuilder setActivityInfo(ActivityInfo info) { 1676 mActivityInfo = info; 1677 return this; 1678 } 1679 setIntent(Intent intent)1680 TaskBuilder setIntent(Intent intent) { 1681 mIntent = intent; 1682 return this; 1683 } 1684 setOnTop(boolean onTop)1685 TaskBuilder setOnTop(boolean onTop) { 1686 mOnTop = onTop; 1687 return this; 1688 } 1689 setVoiceSession(IVoiceInteractionSession session)1690 TaskBuilder setVoiceSession(IVoiceInteractionSession session) { 1691 mVoiceSession = session; 1692 return this; 1693 } 1694 setCreateParentTask(boolean createParentTask)1695 TaskBuilder setCreateParentTask(boolean createParentTask) { 1696 mCreateParentTask = createParentTask; 1697 return this; 1698 } 1699 setParentTask(Task parentTask)1700 TaskBuilder setParentTask(Task parentTask) { 1701 mParentTask = parentTask; 1702 return this; 1703 } 1704 setCreateActivity(boolean createActivity)1705 TaskBuilder setCreateActivity(boolean createActivity) { 1706 mCreateActivity = createActivity; 1707 return this; 1708 } 1709 setCreatedByOrganizer(boolean createdByOrganizer)1710 TaskBuilder setCreatedByOrganizer(boolean createdByOrganizer) { 1711 mCreatedByOrganizer = createdByOrganizer; 1712 return this; 1713 } 1714 build()1715 Task build() { 1716 SystemServicesTestRule.checkHoldsLock(mSupervisor.mService.mGlobalLock); 1717 1718 // Create parent task. 1719 if (mParentTask == null && mCreateParentTask) { 1720 mParentTask = mTaskDisplayArea.createRootTask( 1721 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); 1722 } 1723 if (mParentTask != null && !Mockito.mockingDetails(mParentTask).isSpy()) { 1724 spyOn(mParentTask); 1725 } 1726 1727 // Create task. 1728 if (mActivityInfo == null) { 1729 mActivityInfo = new ActivityInfo(); 1730 mActivityInfo.applicationInfo = new ApplicationInfo(); 1731 mActivityInfo.applicationInfo.packageName = mPackage; 1732 } 1733 1734 if (mIntent == null) { 1735 mIntent = new Intent(); 1736 if (mComponent == null) { 1737 mComponent = getUniqueComponentName(); 1738 } 1739 mIntent.setComponent(mComponent); 1740 mIntent.setFlags(mFlags); 1741 } 1742 1743 final Task.Builder builder = new Task.Builder(mSupervisor.mService) 1744 .setTaskId(mTaskId >= 0 ? mTaskId : mTaskDisplayArea.getNextRootTaskId()) 1745 .setWindowingMode(mWindowingMode) 1746 .setActivityInfo(mActivityInfo) 1747 .setIntent(mIntent) 1748 .setOnTop(mOnTop) 1749 .setVoiceSession(mVoiceSession) 1750 .setCreatedByOrganizer(mCreatedByOrganizer); 1751 final Task task; 1752 if (mParentTask == null) { 1753 task = builder.setActivityType(mActivityType) 1754 .setParent(mTaskDisplayArea) 1755 .build(); 1756 } else { 1757 task = builder.setParent(mParentTask).build(); 1758 mParentTask.moveToFront("build-task"); 1759 } 1760 spyOn(task); 1761 task.mUserId = mUserId; 1762 final Task rootTask = task.getRootTask(); 1763 if (task != rootTask && !Mockito.mockingDetails(rootTask).isSpy()) { 1764 spyOn(rootTask); 1765 } 1766 doNothing().when(rootTask).startActivityLocked( 1767 any(), any(), anyBoolean(), anyBoolean(), any(), any()); 1768 1769 // Create child activity. 1770 if (mCreateActivity) { 1771 new ActivityBuilder(mSupervisor.mService) 1772 .setTask(task) 1773 .setComponent(mComponent) 1774 .build(); 1775 if (mOnTop) { 1776 // We move the task to front again in order to regain focus after activity 1777 // is added. Or {@link TaskDisplayArea#mPreferredTopFocusableRootTask} could be 1778 // other root tasks (e.g. home root task). 1779 task.moveToFront("createActivityTask"); 1780 } else { 1781 task.moveToBack("createActivityTask", null); 1782 } 1783 } 1784 1785 return task; 1786 } 1787 } 1788 1789 static class TestStartingWindowOrganizer extends WindowOrganizerTests.StubOrganizer { 1790 private final ActivityTaskManagerService mAtm; 1791 private final WindowManagerService mWMService; 1792 private final SparseArray<IBinder> mTaskAppMap = new SparseArray<>(); 1793 private final HashMap<IBinder, WindowState> mAppWindowMap = new HashMap<>(); 1794 TestStartingWindowOrganizer(ActivityTaskManagerService service)1795 TestStartingWindowOrganizer(ActivityTaskManagerService service) { 1796 mAtm = service; 1797 mWMService = mAtm.mWindowManager; 1798 mAtm.mTaskOrganizerController.registerTaskOrganizer(this); 1799 } 1800 1801 @Override addStartingWindow(StartingWindowInfo info)1802 public void addStartingWindow(StartingWindowInfo info) { 1803 synchronized (mWMService.mGlobalLock) { 1804 final ActivityRecord activity = ActivityRecord.forTokenLocked(info.appToken); 1805 IWindow iWindow = mock(IWindow.class); 1806 doReturn(mock(IBinder.class)).when(iWindow).asBinder(); 1807 final WindowState window = WindowTestsBase.createWindow(null, 1808 TYPE_APPLICATION_STARTING, activity, 1809 "Starting window", 0 /* ownerId */, 0 /* userId*/, 1810 false /* internalWindows */, mWMService, createTestSession(mAtm), iWindow); 1811 activity.mStartingWindow = window; 1812 mAppWindowMap.put(info.appToken, window); 1813 mTaskAppMap.put(info.taskInfo.taskId, info.appToken); 1814 } 1815 } 1816 @Override removeStartingWindow(StartingWindowRemovalInfo removalInfo)1817 public void removeStartingWindow(StartingWindowRemovalInfo removalInfo) { 1818 synchronized (mWMService.mGlobalLock) { 1819 final IBinder appToken = mTaskAppMap.get(removalInfo.taskId); 1820 if (appToken != null) { 1821 mTaskAppMap.remove(removalInfo.taskId); 1822 final ActivityRecord activity = ActivityRecord.forTokenLocked(appToken); 1823 WindowState win = mAppWindowMap.remove(appToken); 1824 activity.removeChild(win); 1825 activity.mStartingWindow = null; 1826 } 1827 } 1828 } 1829 } 1830 1831 static class TestSplitOrganizer extends WindowOrganizerTests.StubOrganizer { 1832 final ActivityTaskManagerService mService; 1833 final TaskDisplayArea mDefaultTDA; 1834 Task mPrimary; 1835 Task mSecondary; 1836 int mDisplayId; 1837 TestSplitOrganizer(ActivityTaskManagerService service, DisplayContent display)1838 TestSplitOrganizer(ActivityTaskManagerService service, DisplayContent display) { 1839 mService = service; 1840 mDefaultTDA = display.getDefaultTaskDisplayArea(); 1841 mDisplayId = display.mDisplayId; 1842 mService.mTaskOrganizerController.registerTaskOrganizer(this); 1843 mPrimary = mService.mTaskOrganizerController.createRootTask( 1844 display, WINDOWING_MODE_MULTI_WINDOW, null); 1845 mSecondary = mService.mTaskOrganizerController.createRootTask( 1846 display, WINDOWING_MODE_MULTI_WINDOW, null); 1847 1848 mPrimary.setAdjacentTaskFragment(mSecondary); 1849 display.getDefaultTaskDisplayArea().setLaunchAdjacentFlagRootTask(mSecondary); 1850 1851 final Rect primaryBounds = new Rect(); 1852 final Rect secondaryBounds = new Rect(); 1853 if (display.getConfiguration().orientation == ORIENTATION_LANDSCAPE) { 1854 display.getBounds().splitVertically(primaryBounds, secondaryBounds); 1855 } else { 1856 display.getBounds().splitHorizontally(primaryBounds, secondaryBounds); 1857 } 1858 mPrimary.setBounds(primaryBounds); 1859 mSecondary.setBounds(secondaryBounds); 1860 1861 spyOn(mPrimary); 1862 spyOn(mSecondary); 1863 } 1864 TestSplitOrganizer(ActivityTaskManagerService service)1865 TestSplitOrganizer(ActivityTaskManagerService service) { 1866 this(service, service.mTaskSupervisor.mRootWindowContainer.getDefaultDisplay()); 1867 } 1868 createTaskToPrimary(boolean onTop)1869 public Task createTaskToPrimary(boolean onTop) { 1870 final Task primaryTask = mDefaultTDA.createRootTask( 1871 WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD, onTop); 1872 putTaskToPrimary(primaryTask, onTop); 1873 return primaryTask; 1874 } 1875 createTaskToSecondary(boolean onTop)1876 public Task createTaskToSecondary(boolean onTop) { 1877 final Task secondaryTask = mDefaultTDA.createRootTask( 1878 WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD, onTop); 1879 putTaskToSecondary(secondaryTask, onTop); 1880 return secondaryTask; 1881 } 1882 putTaskToPrimary(Task task, boolean onTop)1883 public void putTaskToPrimary(Task task, boolean onTop) { 1884 task.reparent(mPrimary, onTop ? POSITION_TOP : POSITION_BOTTOM); 1885 } 1886 putTaskToSecondary(Task task, boolean onTop)1887 public void putTaskToSecondary(Task task, boolean onTop) { 1888 task.reparent(mSecondary, onTop ? POSITION_TOP : POSITION_BOTTOM); 1889 } 1890 } 1891 1892 static class TestDesktopOrganizer extends WindowOrganizerTests.StubOrganizer { 1893 final int mDesktopModeDefaultWidthDp = 840; 1894 final int mDesktopModeDefaultHeightDp = 630; 1895 final int mDesktopDensity = 284; 1896 final int mOverrideDensity = 285; 1897 1898 final ActivityTaskManagerService mService; 1899 final TaskDisplayArea mDefaultTDA; 1900 List<Task> mTasks; 1901 final DisplayContent mDisplay; 1902 Rect mStableBounds; 1903 Task mHomeTask; 1904 TestDesktopOrganizer(ActivityTaskManagerService service, DisplayContent display)1905 TestDesktopOrganizer(ActivityTaskManagerService service, DisplayContent display) { 1906 mService = service; 1907 mDefaultTDA = display.getDefaultTaskDisplayArea(); 1908 mDisplay = display; 1909 mService.mTaskOrganizerController.registerTaskOrganizer(this); 1910 mTasks = new ArrayList<>(); 1911 mStableBounds = display.getBounds(); 1912 mHomeTask = mDefaultTDA.getRootHomeTask(); 1913 } TestDesktopOrganizer(ActivityTaskManagerService service)1914 TestDesktopOrganizer(ActivityTaskManagerService service) { 1915 this(service, service.mTaskSupervisor.mRootWindowContainer.getDefaultDisplay()); 1916 } 1917 createTask(Rect bounds)1918 public Task createTask(Rect bounds) { 1919 Task task = mService.mTaskOrganizerController.createRootTask( 1920 mDisplay, WINDOWING_MODE_FREEFORM, null); 1921 task.setBounds(bounds); 1922 mTasks.add(task); 1923 spyOn(task); 1924 return task; 1925 } 1926 getDefaultDesktopTaskBounds()1927 public Rect getDefaultDesktopTaskBounds() { 1928 int width = (int) (mDesktopModeDefaultWidthDp 1929 * (mOverrideDensity / mDesktopDensity) + 0.5f); 1930 int height = (int) (mDesktopModeDefaultHeightDp 1931 * (mOverrideDensity / mDesktopDensity) + 0.5f); 1932 Rect outBounds = new Rect(); 1933 1934 outBounds.set(0, 0, width, height); 1935 // Center the task in stable bounds 1936 outBounds.offset( 1937 mStableBounds.centerX() - outBounds.centerX(), 1938 mStableBounds.centerY() - outBounds.centerY() 1939 ); 1940 return outBounds; 1941 } 1942 createFreeformTasksWithActivities(TestDesktopOrganizer desktopOrganizer, List<ActivityRecord> activityRecords, int numberOfTasks)1943 public void createFreeformTasksWithActivities(TestDesktopOrganizer desktopOrganizer, 1944 List<ActivityRecord> activityRecords, int numberOfTasks) { 1945 for (int i = 0; i < numberOfTasks; i++) { 1946 Rect bounds = new Rect(desktopOrganizer.getDefaultDesktopTaskBounds()); 1947 bounds.offset(20 * i, 20 * i); 1948 desktopOrganizer.createTask(bounds); 1949 } 1950 1951 for (int i = 0; i < numberOfTasks; i++) { 1952 activityRecords.add(new TaskBuilder(mService.mTaskSupervisor) 1953 .setParentTask(desktopOrganizer.mTasks.get(i)) 1954 .setCreateActivity(true) 1955 .build() 1956 .getTopMostActivity()); 1957 } 1958 1959 for (int i = 0; i < numberOfTasks; i++) { 1960 activityRecords.get(i).setVisibleRequested(true); 1961 } 1962 1963 for (int i = 0; i < numberOfTasks; i++) { 1964 assertEquals(desktopOrganizer.mTasks.get(i), activityRecords.get(i).getRootTask()); 1965 } 1966 } 1967 bringHomeToFront()1968 public void bringHomeToFront() { 1969 WindowContainerTransaction wct = new WindowContainerTransaction(); 1970 wct.reorder(mHomeTask.getTaskInfo().token, true /* onTop */); 1971 applyTransaction(wct); 1972 } 1973 bringDesktopTasksToFront(WindowContainerTransaction wct)1974 public void bringDesktopTasksToFront(WindowContainerTransaction wct) { 1975 for (Task task: mTasks) { 1976 wct.reorder(task.getTaskInfo().token, true /* onTop */); 1977 } 1978 } 1979 addMoveToDesktopChanges(WindowContainerTransaction wct, Task task, boolean overrideDensity)1980 public void addMoveToDesktopChanges(WindowContainerTransaction wct, Task task, 1981 boolean overrideDensity) { 1982 wct.setWindowingMode(task.getTaskInfo().token, WINDOWING_MODE_FREEFORM); 1983 wct.reorder(task.getTaskInfo().token, true /* onTop */); 1984 if (overrideDensity) { 1985 wct.setDensityDpi(task.getTaskInfo().token, mOverrideDensity); 1986 } 1987 } 1988 addMoveToFullscreen(WindowContainerTransaction wct, Task task, boolean overrideDensity)1989 public void addMoveToFullscreen(WindowContainerTransaction wct, Task task, 1990 boolean overrideDensity) { 1991 wct.setWindowingMode(task.getTaskInfo().token, WINDOWING_MODE_FULLSCREEN); 1992 wct.setBounds(task.getTaskInfo().token, new Rect()); 1993 if (overrideDensity) { 1994 wct.setDensityDpi(task.getTaskInfo().token, mOverrideDensity); 1995 } 1996 } 1997 applyTransaction(@ndroidx.annotation.NonNull WindowContainerTransaction wct)1998 private void applyTransaction(@androidx.annotation.NonNull WindowContainerTransaction wct) { 1999 if (!wct.isEmpty()) { 2000 mService.mWindowOrganizerController.applyTransaction(wct); 2001 } 2002 } 2003 } 2004 2005 createTestWindowToken(int type, DisplayContent dc)2006 static TestWindowToken createTestWindowToken(int type, DisplayContent dc) { 2007 return createTestWindowToken(type, dc, false /* persistOnEmpty */); 2008 } 2009 createTestWindowToken(int type, DisplayContent dc, boolean persistOnEmpty)2010 static TestWindowToken createTestWindowToken(int type, DisplayContent dc, 2011 boolean persistOnEmpty) { 2012 SystemServicesTestRule.checkHoldsLock(dc.mWmService.mGlobalLock); 2013 2014 return new TestWindowToken(type, dc, persistOnEmpty); 2015 } 2016 2017 /** Used so we can gain access to some protected members of the {@link WindowToken} class */ 2018 static class TestWindowToken extends WindowToken { 2019 TestWindowToken(int type, DisplayContent dc, boolean persistOnEmpty)2020 private TestWindowToken(int type, DisplayContent dc, boolean persistOnEmpty) { 2021 super(dc.mWmService, mock(IBinder.class), type, persistOnEmpty, dc, 2022 false /* ownerCanManageAppTokens */); 2023 } 2024 getWindowsCount()2025 int getWindowsCount() { 2026 return mChildren.size(); 2027 } 2028 hasWindow(WindowState w)2029 boolean hasWindow(WindowState w) { 2030 return mChildren.contains(w); 2031 } 2032 } 2033 2034 /** Used to track resize reports. */ 2035 static class TestWindowState extends WindowState { 2036 boolean mResizeReported; 2037 TestWindowState(WindowManagerService service, Session session, IWindow window, WindowManager.LayoutParams attrs, WindowToken token)2038 TestWindowState(WindowManagerService service, Session session, IWindow window, 2039 WindowManager.LayoutParams attrs, WindowToken token) { 2040 super(service, session, window, token, null, OP_NONE, attrs, 0, 0, 0, 2041 false /* ownerCanAddInternalSystemWindow */); 2042 } 2043 2044 @Override reportResized()2045 void reportResized() { 2046 super.reportResized(); 2047 mResizeReported = true; 2048 } 2049 2050 @Override isGoneForLayout()2051 public boolean isGoneForLayout() { 2052 return false; 2053 } 2054 2055 @Override updateResizingWindowIfNeeded()2056 void updateResizingWindowIfNeeded() { 2057 // Used in AppWindowTokenTests#testLandscapeSeascapeRotationRelayout to deceive 2058 // the system that it can actually update the window. 2059 boolean hadSurface = mHasSurface; 2060 mHasSurface = true; 2061 2062 super.updateResizingWindowIfNeeded(); 2063 2064 mHasSurface = hadSurface; 2065 } 2066 } 2067 2068 static class TestTransitionController extends TransitionController { TestTransitionController(ActivityTaskManagerService atms)2069 TestTransitionController(ActivityTaskManagerService atms) { 2070 super(atms); 2071 doReturn(this).when(atms).getTransitionController(); 2072 mSnapshotController = mock(SnapshotController.class); 2073 mTransitionTracer = mock(TransitionTracer.class); 2074 } 2075 } 2076 2077 static class TestTransitionPlayer extends ITransitionPlayer.Stub { 2078 final TransitionController mController; 2079 final WindowOrganizerController mOrganizer; 2080 Transition mLastTransit = null; 2081 TransitionRequestInfo mLastRequest = null; 2082 TransitionInfo mLastReady = null; 2083 TestTransitionPlayer(@onNull TransitionController controller, @NonNull WindowOrganizerController organizer)2084 TestTransitionPlayer(@NonNull TransitionController controller, 2085 @NonNull WindowOrganizerController organizer) { 2086 mController = controller; 2087 mOrganizer = organizer; 2088 } 2089 clear()2090 void clear() { 2091 mLastTransit = null; 2092 mLastReady = null; 2093 mLastRequest = null; 2094 } 2095 2096 @Override onTransitionReady(IBinder transitToken, TransitionInfo transitionInfo, SurfaceControl.Transaction transaction, SurfaceControl.Transaction finishT)2097 public void onTransitionReady(IBinder transitToken, TransitionInfo transitionInfo, 2098 SurfaceControl.Transaction transaction, SurfaceControl.Transaction finishT) 2099 throws RemoteException { 2100 mLastTransit = Transition.fromBinder(transitToken); 2101 mLastReady = transitionInfo; 2102 } 2103 2104 @Override requestStartTransition(IBinder transitToken, TransitionRequestInfo request)2105 public void requestStartTransition(IBinder transitToken, 2106 TransitionRequestInfo request) throws RemoteException { 2107 mLastTransit = Transition.fromBinder(transitToken); 2108 mLastRequest = request; 2109 } 2110 startTransition()2111 void startTransition() { 2112 mOrganizer.startTransition(mLastTransit.getToken(), null); 2113 } 2114 onTransactionReady(SurfaceControl.Transaction t)2115 void onTransactionReady(SurfaceControl.Transaction t) { 2116 mLastTransit.onTransactionReady(mLastTransit.getSyncId(), t); 2117 } 2118 start()2119 void start() { 2120 startTransition(); 2121 onTransactionReady(mock(SurfaceControl.Transaction.class)); 2122 } 2123 finish()2124 public void finish() { 2125 mController.finishTransition(mLastTransit); 2126 } 2127 } 2128 } 2129