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