1 /* 2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License 15 */ 16 17 package com.android.server.wm; 18 19 import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; 20 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; 21 import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; 22 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; 23 import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW; 24 import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; 25 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; 26 import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE; 27 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; 28 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_NOSENSOR; 29 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; 30 import static android.content.res.Configuration.ORIENTATION_LANDSCAPE; 31 import static android.util.DisplayMetrics.DENSITY_DEFAULT; 32 import static android.view.Display.DEFAULT_DISPLAY; 33 import static android.window.DisplayAreaOrganizer.FEATURE_RUNTIME_TASK_CONTAINER_FIRST; 34 35 import static com.android.server.wm.ActivityStarter.Request; 36 import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.PHASE_BOUNDS; 37 import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.RESULT_CONTINUE; 38 import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.RESULT_SKIP; 39 40 import static org.junit.Assert.assertEquals; 41 import static org.junit.Assert.assertTrue; 42 import static org.mockito.Mockito.doReturn; 43 import static org.mockito.Mockito.mock; 44 import static org.mockito.Mockito.when; 45 46 import android.app.ActivityOptions; 47 import android.content.pm.ActivityInfo; 48 import android.content.pm.ApplicationInfo; 49 import android.content.res.Configuration; 50 import android.graphics.Rect; 51 import android.os.Build; 52 import android.platform.test.annotations.Presubmit; 53 import android.view.Gravity; 54 import android.view.InsetsSource; 55 import android.view.InsetsState; 56 import android.view.WindowInsets; 57 58 import androidx.test.filters.SmallTest; 59 60 import com.android.server.wm.LaunchParamsController.LaunchParams; 61 import com.android.server.wm.LaunchParamsController.LaunchParamsModifier.Result; 62 63 import org.junit.Before; 64 import org.junit.Test; 65 import org.junit.runner.RunWith; 66 67 import java.util.ArrayList; 68 import java.util.List; 69 import java.util.Locale; 70 71 /** 72 * Tests for default task bounds. 73 * 74 * Build/Install/Run: 75 * atest WmTests:TaskLaunchParamsModifierTests 76 */ 77 @SmallTest 78 @Presubmit 79 @RunWith(WindowTestRunner.class) 80 public class TaskLaunchParamsModifierTests extends WindowTestsBase { 81 private static final Rect DISPLAY_BOUNDS = new Rect(/* left */ 0, /* top */ 0, 82 /* right */ 1920, /* bottom */ 1080); 83 private static final Rect DISPLAY_STABLE_BOUNDS = new Rect(/* left */ 100, 84 /* top */ 200, /* right */ 1620, /* bottom */ 680); 85 86 private static final Rect SMALL_DISPLAY_BOUNDS = new Rect(/* left */ 0, /* top */ 0, 87 /* right */ 1000, /* bottom */ 500); 88 private static final Rect SMALL_DISPLAY_STABLE_BOUNDS = new Rect(/* left */ 100, 89 /* top */ 50, /* right */ 900, /* bottom */ 450); 90 91 private ActivityRecord mActivity; 92 93 private TaskLaunchParamsModifier mTarget; 94 95 private LaunchParams mCurrent; 96 private LaunchParams mResult; 97 98 @Before setUp()99 public void setUp() throws Exception { 100 mActivity = new ActivityBuilder(mAtm).build(); 101 mActivity.info.applicationInfo.targetSdkVersion = Build.VERSION_CODES.N_MR1; 102 mActivity.info.applicationInfo.flags |= ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES; 103 104 mTarget = new TaskLaunchParamsModifier(mSupervisor); 105 106 mCurrent = new LaunchParams(); 107 mCurrent.reset(); 108 mResult = new LaunchParams(); 109 mResult.reset(); 110 } 111 112 @Test testReturnsSkipWithEmptyActivity()113 public void testReturnsSkipWithEmptyActivity() { 114 final Task task = new TaskBuilder(mSupervisor).build(); 115 assertEquals(RESULT_SKIP, new CalculateRequestBuilder().setActivity(null).calculate()); 116 } 117 118 // ======================= 119 // Display Related Tests 120 // ======================= 121 @Test testDefaultToPrimaryDisplayArea()122 public void testDefaultToPrimaryDisplayArea() { 123 createNewDisplayContent(WINDOWING_MODE_FREEFORM); 124 125 assertEquals(RESULT_CONTINUE, new CalculateRequestBuilder().calculate()); 126 127 assertEquals(mRootWindowContainer.getDefaultTaskDisplayArea(), 128 mResult.mPreferredTaskDisplayArea); 129 } 130 131 @Test testUsesPreviousDisplayAreaIfSet()132 public void testUsesPreviousDisplayAreaIfSet() { 133 createNewDisplayContent(WINDOWING_MODE_FREEFORM); 134 final TestDisplayContent display = createNewDisplayContent(WINDOWING_MODE_FULLSCREEN); 135 136 mCurrent.mPreferredTaskDisplayArea = display.getDefaultTaskDisplayArea(); 137 138 assertEquals(RESULT_CONTINUE, new CalculateRequestBuilder().calculate()); 139 140 assertEquals(display.getDefaultTaskDisplayArea(), mResult.mPreferredTaskDisplayArea); 141 } 142 143 @Test testUsesSourcesDisplayAreaIfSet()144 public void testUsesSourcesDisplayAreaIfSet() { 145 final TestDisplayContent freeformDisplay = createNewDisplayContent( 146 WINDOWING_MODE_FREEFORM); 147 final TestDisplayContent fullscreenDisplay = createNewDisplayContent( 148 WINDOWING_MODE_FULLSCREEN); 149 150 mCurrent.mPreferredTaskDisplayArea = freeformDisplay.getDefaultTaskDisplayArea(); 151 152 ActivityRecord source = createSourceActivity(fullscreenDisplay); 153 154 assertEquals(RESULT_CONTINUE, new CalculateRequestBuilder().setSource(source).calculate()); 155 156 assertEquals(fullscreenDisplay.getDefaultTaskDisplayArea(), 157 mResult.mPreferredTaskDisplayArea); 158 } 159 160 @Test testUsesOptionsDisplayIdIfSet()161 public void testUsesOptionsDisplayIdIfSet() { 162 final TestDisplayContent freeformDisplay = createNewDisplayContent( 163 WINDOWING_MODE_FREEFORM); 164 final TestDisplayContent fullscreenDisplay = createNewDisplayContent( 165 WINDOWING_MODE_FULLSCREEN); 166 167 mCurrent.mPreferredTaskDisplayArea = freeformDisplay.getDefaultTaskDisplayArea(); 168 ActivityRecord source = createSourceActivity(freeformDisplay); 169 170 ActivityOptions options = ActivityOptions.makeBasic(); 171 options.setLaunchDisplayId(fullscreenDisplay.mDisplayId); 172 173 assertEquals(RESULT_CONTINUE, 174 new CalculateRequestBuilder().setSource(source).setOptions(options).calculate()); 175 176 assertEquals(fullscreenDisplay.getDefaultTaskDisplayArea(), 177 mResult.mPreferredTaskDisplayArea); 178 } 179 180 @Test testUsesOptionsDisplayAreaTokenIfSet()181 public void testUsesOptionsDisplayAreaTokenIfSet() { 182 final TestDisplayContent freeformDisplay = createNewDisplayContent( 183 WINDOWING_MODE_FREEFORM); 184 final TestDisplayContent fullscreenDisplay = createNewDisplayContent( 185 WINDOWING_MODE_FULLSCREEN); 186 187 mCurrent.mPreferredTaskDisplayArea = freeformDisplay.getDefaultTaskDisplayArea(); 188 ActivityRecord source = createSourceActivity(freeformDisplay); 189 190 ActivityOptions options = ActivityOptions.makeBasic(); 191 options.setLaunchTaskDisplayArea(fullscreenDisplay.getDefaultTaskDisplayArea() 192 .mRemoteToken.toWindowContainerToken()); 193 194 assertEquals(RESULT_CONTINUE, 195 new CalculateRequestBuilder().setSource(source).setOptions(options).calculate()); 196 197 assertEquals(fullscreenDisplay.getDefaultTaskDisplayArea(), 198 mResult.mPreferredTaskDisplayArea); 199 } 200 201 @Test testUsesOptionsDisplayAreaFeatureIdIfSet()202 public void testUsesOptionsDisplayAreaFeatureIdIfSet() { 203 final TestDisplayContent freeformDisplay = createNewDisplayContent( 204 WINDOWING_MODE_FREEFORM); 205 final TestDisplayContent fullscreenDisplay = createNewDisplayContent( 206 WINDOWING_MODE_FULLSCREEN); 207 208 mCurrent.mPreferredTaskDisplayArea = freeformDisplay.getDefaultTaskDisplayArea(); 209 ActivityRecord source = createSourceActivity(freeformDisplay); 210 211 ActivityOptions options = ActivityOptions.makeBasic(); 212 options.setLaunchDisplayId(fullscreenDisplay.mDisplayId); 213 options.setLaunchTaskDisplayAreaFeatureId( 214 fullscreenDisplay.getDefaultTaskDisplayArea().mFeatureId); 215 216 assertEquals(RESULT_CONTINUE, 217 new CalculateRequestBuilder().setSource(source).setOptions(options).calculate()); 218 219 assertEquals(fullscreenDisplay.getDefaultTaskDisplayArea(), 220 mResult.mPreferredTaskDisplayArea); 221 } 222 223 @Test testUsesSourcesDisplayAreaIdPriorToTaskIfSet()224 public void testUsesSourcesDisplayAreaIdPriorToTaskIfSet() { 225 final TestDisplayContent freeformDisplay = createNewDisplayContent( 226 WINDOWING_MODE_FREEFORM); 227 final TestDisplayContent fullscreenDisplay = createNewDisplayContent( 228 WINDOWING_MODE_FULLSCREEN); 229 230 mCurrent.mPreferredTaskDisplayArea = freeformDisplay.getDefaultTaskDisplayArea(); 231 ActivityRecord reusableActivity = createSourceActivity(fullscreenDisplay); 232 ActivityRecord source = createSourceActivity(freeformDisplay); 233 234 assertEquals(RESULT_CONTINUE, 235 new CalculateRequestBuilder() 236 .setTask(reusableActivity.getTask()) 237 .setSource(source) 238 .calculate()); 239 240 assertEquals(freeformDisplay.getDefaultTaskDisplayArea(), 241 mResult.mPreferredTaskDisplayArea); 242 } 243 244 @Test testUsesTaskDisplayAreaIdIfSet()245 public void testUsesTaskDisplayAreaIdIfSet() { 246 final TestDisplayContent freeformDisplay = createNewDisplayContent( 247 WINDOWING_MODE_FREEFORM); 248 ActivityRecord source = createSourceActivity(freeformDisplay); 249 250 assertEquals(RESULT_CONTINUE, 251 new CalculateRequestBuilder() 252 .setTask(source.getTask()) 253 .calculate()); 254 255 assertEquals(freeformDisplay.getDefaultTaskDisplayArea(), 256 mResult.mPreferredTaskDisplayArea); 257 } 258 259 @Test testUsesNoDisplaySourceHandoverDisplayIdIfSet()260 public void testUsesNoDisplaySourceHandoverDisplayIdIfSet() { 261 final TestDisplayContent freeformDisplay = createNewDisplayContent( 262 WINDOWING_MODE_FREEFORM); 263 final TestDisplayContent fullscreenDisplay = createNewDisplayContent( 264 WINDOWING_MODE_FULLSCREEN); 265 266 mCurrent.mPreferredTaskDisplayArea = fullscreenDisplay.getDefaultTaskDisplayArea(); 267 ActivityRecord reusableActivity = createSourceActivity(fullscreenDisplay); 268 ActivityRecord source = createSourceActivity(freeformDisplay); 269 source.mHandoverLaunchDisplayId = freeformDisplay.mDisplayId; 270 source.noDisplay = true; 271 272 assertEquals(RESULT_CONTINUE, 273 new CalculateRequestBuilder() 274 .setTask(reusableActivity.getTask()) 275 .setSource(source) 276 .calculate()); 277 278 assertEquals(freeformDisplay.getDefaultTaskDisplayArea(), 279 mResult.mPreferredTaskDisplayArea); 280 } 281 282 @Test testUsesNoDisplaySourceHandoverDisplayAreaIdIfSet()283 public void testUsesNoDisplaySourceHandoverDisplayAreaIdIfSet() { 284 final TestDisplayContent freeformDisplay = createNewDisplayContent( 285 WINDOWING_MODE_FREEFORM); 286 final TestDisplayContent fullscreenDisplay = createNewDisplayContent( 287 WINDOWING_MODE_FULLSCREEN); 288 289 mCurrent.mPreferredTaskDisplayArea = fullscreenDisplay.getDefaultTaskDisplayArea(); 290 ActivityRecord reusableActivity = createSourceActivity(fullscreenDisplay); 291 ActivityRecord source = createSourceActivity(freeformDisplay); 292 source.mHandoverTaskDisplayArea = freeformDisplay.getDefaultTaskDisplayArea(); 293 source.noDisplay = true; 294 295 assertEquals(RESULT_CONTINUE, 296 new CalculateRequestBuilder() 297 .setTask(reusableActivity.getTask()) 298 .setSource(source) 299 .calculate()); 300 301 assertEquals(freeformDisplay.getDefaultTaskDisplayArea(), 302 mResult.mPreferredTaskDisplayArea); 303 } 304 305 @Test testUsesDisplayAreaFromTopMostActivityInApplicationIfAvailable()306 public void testUsesDisplayAreaFromTopMostActivityInApplicationIfAvailable() { 307 final String processName = "processName"; 308 final int uid = 124214; 309 final TestDisplayContent secondScreen = createNewDisplayContent(WINDOWING_MODE_FULLSCREEN); 310 final TaskDisplayArea expectedDisplayArea = secondScreen.getDefaultTaskDisplayArea(); 311 final WindowProcessController controller = mock(WindowProcessController.class); 312 313 when(controller.getTopActivityDisplayArea()).thenReturn(expectedDisplayArea); 314 315 when(mActivity.getProcessName()).thenReturn(processName); 316 when(mActivity.getUid()).thenReturn(uid); 317 doReturn(controller) 318 .when(mAtm) 319 .getProcessController(processName, uid); 320 321 assertEquals(RESULT_CONTINUE, new CalculateRequestBuilder().calculate()); 322 323 assertEquals(expectedDisplayArea, mResult.mPreferredTaskDisplayArea); 324 } 325 326 @Test testUsesDisplayAreaFromLaunchingActivityIfApplicationLaunching()327 public void testUsesDisplayAreaFromLaunchingActivityIfApplicationLaunching() { 328 final String processName = "processName"; 329 final int uid = 124214; 330 final TestDisplayContent secondScreen = createNewDisplayContent(WINDOWING_MODE_FULLSCREEN); 331 final TaskDisplayArea expectedTaskDisplayArea = secondScreen.getDefaultTaskDisplayArea(); 332 final WindowProcessController controller = mock(WindowProcessController.class); 333 334 when(controller.getTopActivityDisplayArea()).thenReturn(expectedTaskDisplayArea); 335 336 when(mActivity.getProcessName()).thenReturn(processName); 337 when(mActivity.getUid()).thenReturn(uid); 338 doReturn(null) 339 .when(mAtm) 340 .getProcessController(processName, uid); 341 342 doReturn(controller) 343 .when(mAtm) 344 .getProcessController(mActivity.launchedFromPid, mActivity.launchedFromUid); 345 346 assertEquals(RESULT_CONTINUE, new CalculateRequestBuilder().calculate()); 347 348 assertEquals(expectedTaskDisplayArea, mResult.mPreferredTaskDisplayArea); 349 } 350 351 @Test testDisplayAreaFromLaunchingActivityTakesPrecedence()352 public void testDisplayAreaFromLaunchingActivityTakesPrecedence() { 353 final String processName = "processName"; 354 final int uid = 124214; 355 final TestDisplayContent firstScreen = createNewDisplayContent(WINDOWING_MODE_FULLSCREEN); 356 final TestDisplayContent secondScreen = createNewDisplayContent(WINDOWING_MODE_FULLSCREEN); 357 final TaskDisplayArea firstTaskDisplayArea = firstScreen.getDefaultTaskDisplayArea(); 358 final TaskDisplayArea expectedTaskDisplayArea = secondScreen.getDefaultTaskDisplayArea(); 359 final WindowProcessController controllerForLaunching = mock(WindowProcessController.class); 360 final WindowProcessController controllerForApplication = 361 mock(WindowProcessController.class); 362 363 when(mActivity.getProcessName()).thenReturn(processName); 364 when(mActivity.getUid()).thenReturn(uid); 365 366 when(controllerForApplication.getTopActivityDisplayArea()).thenReturn(firstTaskDisplayArea); 367 when(controllerForLaunching.getTopActivityDisplayArea()) 368 .thenReturn(expectedTaskDisplayArea); 369 370 doReturn(controllerForApplication) 371 .when(mAtm) 372 .getProcessController(processName, uid); 373 doReturn(controllerForLaunching) 374 .when(mAtm) 375 .getProcessController(mActivity.launchedFromPid, mActivity.launchedFromUid); 376 377 assertEquals(RESULT_CONTINUE, new CalculateRequestBuilder().calculate()); 378 379 assertEquals(expectedTaskDisplayArea, mResult.mPreferredTaskDisplayArea); 380 } 381 382 @Test testUsesDisplayAreaOriginalProcessAsLastResort()383 public void testUsesDisplayAreaOriginalProcessAsLastResort() { 384 final TestDisplayContent firstScreen = createNewDisplayContent(WINDOWING_MODE_FULLSCREEN); 385 final TestDisplayContent secondScreen = createNewDisplayContent(WINDOWING_MODE_FULLSCREEN); 386 final TaskDisplayArea expectedTaskDisplayArea = secondScreen.getDefaultTaskDisplayArea(); 387 final Request request = new Request(); 388 request.realCallingPid = 12412413; 389 request.realCallingUid = 235424; 390 391 final WindowProcessController controller = mock(WindowProcessController.class); 392 393 when(controller.getTopActivityDisplayArea()).thenReturn(expectedTaskDisplayArea); 394 395 doReturn(null) 396 .when(mAtm) 397 .getProcessController(mActivity.processName, mActivity.info.applicationInfo.uid); 398 399 doReturn(null) 400 .when(mAtm) 401 .getProcessController(mActivity.launchedFromPid, mActivity.launchedFromUid); 402 403 doReturn(controller) 404 .when(mAtm) 405 .getProcessController(request.realCallingPid, request.realCallingUid); 406 407 assertEquals(RESULT_CONTINUE, 408 new CalculateRequestBuilder().setRequest(request).calculate()); 409 410 assertEquals(expectedTaskDisplayArea, mResult.mPreferredTaskDisplayArea); 411 } 412 413 @Test testUsesDefaultDisplayAreaIfWindowProcessControllerIsNotPresent()414 public void testUsesDefaultDisplayAreaIfWindowProcessControllerIsNotPresent() { 415 doReturn(null) 416 .when(mAtm) 417 .getProcessController(mActivity.processName, mActivity.info.applicationInfo.uid); 418 419 doReturn(null) 420 .when(mAtm) 421 .getProcessController(mActivity.launchedFromPid, mActivity.launchedFromUid); 422 423 assertEquals(RESULT_CONTINUE, new CalculateRequestBuilder().calculate()); 424 425 assertEquals(DEFAULT_DISPLAY, mResult.mPreferredTaskDisplayArea.getDisplayId()); 426 } 427 428 @Test testOverridesDisplayAreaWithStandardTypeAndFullscreenMode()429 public void testOverridesDisplayAreaWithStandardTypeAndFullscreenMode() { 430 final TaskDisplayArea secondaryDisplayArea = createTaskDisplayArea(mDefaultDisplay, 431 mWm, "SecondaryDisplayArea", FEATURE_RUNTIME_TASK_CONTAINER_FIRST); 432 final Task launchRoot = createTask(secondaryDisplayArea, WINDOWING_MODE_FULLSCREEN, 433 ACTIVITY_TYPE_STANDARD); 434 launchRoot.mCreatedByOrganizer = true; 435 436 secondaryDisplayArea.setLaunchRootTask(launchRoot, new int[] { WINDOWING_MODE_FULLSCREEN }, 437 new int[] { ACTIVITY_TYPE_STANDARD }); 438 439 assertEquals(RESULT_CONTINUE, new CalculateRequestBuilder().calculate()); 440 441 assertEquals(secondaryDisplayArea, mResult.mPreferredTaskDisplayArea); 442 } 443 444 @Test testOverridesDisplayAreaWithHomeTypeAndFullscreenMode()445 public void testOverridesDisplayAreaWithHomeTypeAndFullscreenMode() { 446 final TaskDisplayArea secondaryDisplayArea = createTaskDisplayArea(mDefaultDisplay, 447 mWm, "SecondaryDisplayArea", FEATURE_RUNTIME_TASK_CONTAINER_FIRST); 448 final Task launchRoot = createTask(secondaryDisplayArea, WINDOWING_MODE_FULLSCREEN, 449 ACTIVITY_TYPE_STANDARD); 450 launchRoot.mCreatedByOrganizer = true; 451 452 mActivity.setActivityType(ACTIVITY_TYPE_HOME); 453 secondaryDisplayArea.setLaunchRootTask(launchRoot, new int[] { WINDOWING_MODE_FULLSCREEN }, 454 new int[] { ACTIVITY_TYPE_HOME }); 455 456 assertEquals(RESULT_CONTINUE, new CalculateRequestBuilder().calculate()); 457 458 assertEquals(secondaryDisplayArea, mResult.mPreferredTaskDisplayArea); 459 } 460 461 @Test testOverridesDisplayAreaWithStandardTypeAndFreeformMode()462 public void testOverridesDisplayAreaWithStandardTypeAndFreeformMode() { 463 final TestDisplayContent freeformDisplay = createNewDisplayContent( 464 WINDOWING_MODE_FREEFORM); 465 final TaskDisplayArea secondaryDisplayArea = createTaskDisplayArea(freeformDisplay, 466 mWm, "SecondaryDisplayArea", FEATURE_RUNTIME_TASK_CONTAINER_FIRST); 467 final Task launchRoot = createTask(secondaryDisplayArea, WINDOWING_MODE_FULLSCREEN, 468 ACTIVITY_TYPE_STANDARD); 469 launchRoot.mCreatedByOrganizer = true; 470 471 secondaryDisplayArea.setLaunchRootTask(launchRoot, new int[] { WINDOWING_MODE_FREEFORM }, 472 new int[] { ACTIVITY_TYPE_STANDARD }); 473 474 mCurrent.mPreferredTaskDisplayArea = freeformDisplay.getDefaultTaskDisplayArea(); 475 assertEquals(RESULT_CONTINUE, new CalculateRequestBuilder().calculate()); 476 477 assertEquals(secondaryDisplayArea, mResult.mPreferredTaskDisplayArea); 478 } 479 480 @Test testNotOverrideDisplayAreaWhenActivityOptionsHasDisplayAreaToken()481 public void testNotOverrideDisplayAreaWhenActivityOptionsHasDisplayAreaToken() { 482 final TaskDisplayArea secondaryDisplayArea = createTaskDisplayArea(mDefaultDisplay, 483 mWm, "SecondaryDisplayArea", FEATURE_RUNTIME_TASK_CONTAINER_FIRST); 484 final Task launchRoot = createTask(secondaryDisplayArea, WINDOWING_MODE_FULLSCREEN, 485 ACTIVITY_TYPE_STANDARD); 486 launchRoot.mCreatedByOrganizer = true; 487 488 secondaryDisplayArea.setLaunchRootTask(launchRoot, new int[] { WINDOWING_MODE_FULLSCREEN }, 489 new int[] { ACTIVITY_TYPE_STANDARD }); 490 491 ActivityOptions options = ActivityOptions.makeBasic(); 492 options.setLaunchTaskDisplayArea( 493 mDefaultDisplay.getDefaultTaskDisplayArea().mRemoteToken.toWindowContainerToken()); 494 495 assertEquals(RESULT_CONTINUE, 496 new CalculateRequestBuilder().setOptions(options).calculate()); 497 498 assertEquals( 499 mDefaultDisplay.getDefaultTaskDisplayArea(), mResult.mPreferredTaskDisplayArea); 500 } 501 502 @Test testNotOverrideDisplayAreaWhenActivityOptionsHasDisplayAreaFeatureId()503 public void testNotOverrideDisplayAreaWhenActivityOptionsHasDisplayAreaFeatureId() { 504 final TaskDisplayArea secondaryDisplayArea = createTaskDisplayArea(mDefaultDisplay, 505 mWm, "SecondaryDisplayArea", FEATURE_RUNTIME_TASK_CONTAINER_FIRST); 506 final Task launchRoot = createTask(secondaryDisplayArea, WINDOWING_MODE_FULLSCREEN, 507 ACTIVITY_TYPE_STANDARD); 508 launchRoot.mCreatedByOrganizer = true; 509 510 secondaryDisplayArea.setLaunchRootTask(launchRoot, new int[] { WINDOWING_MODE_FULLSCREEN }, 511 new int[] { ACTIVITY_TYPE_STANDARD }); 512 513 ActivityOptions options = ActivityOptions.makeBasic(); 514 options.setLaunchTaskDisplayAreaFeatureId( 515 mDefaultDisplay.getDefaultTaskDisplayArea().mFeatureId); 516 517 assertEquals(RESULT_CONTINUE, 518 new CalculateRequestBuilder().setOptions(options).calculate()); 519 520 assertEquals( 521 mDefaultDisplay.getDefaultTaskDisplayArea(), mResult.mPreferredTaskDisplayArea); 522 } 523 524 @Test testUsesOptionsDisplayAreaFeatureIdDisplayIdNotSet()525 public void testUsesOptionsDisplayAreaFeatureIdDisplayIdNotSet() { 526 final TestDisplayContent secondaryDisplay = createNewDisplayContent( 527 WINDOWING_MODE_FULLSCREEN); 528 final TaskDisplayArea tdaOnSecondaryDisplay = createTaskDisplayArea(secondaryDisplay, 529 mWm, "TestTaskDisplayArea", FEATURE_RUNTIME_TASK_CONTAINER_FIRST); 530 531 final TaskDisplayArea tdaOnDefaultDisplay = createTaskDisplayArea(mDefaultDisplay, 532 mWm, "TestTaskDisplayArea", FEATURE_RUNTIME_TASK_CONTAINER_FIRST); 533 534 mCurrent.mPreferredTaskDisplayArea = tdaOnSecondaryDisplay; 535 ActivityRecord source = createSourceActivity(tdaOnSecondaryDisplay, 536 WINDOWING_MODE_FULLSCREEN); 537 538 ActivityOptions options = ActivityOptions.makeBasic(); 539 options.setLaunchTaskDisplayAreaFeatureId(tdaOnSecondaryDisplay.mFeatureId); 540 541 assertEquals(RESULT_CONTINUE, 542 new CalculateRequestBuilder().setSource(source).setOptions(options).calculate()); 543 // Display id wasn't specified in ActivityOptions - the activity should be placed on the 544 // default display, into the TaskDisplayArea with the same feature id. 545 assertEquals(tdaOnDefaultDisplay, mResult.mPreferredTaskDisplayArea); 546 } 547 548 @Test testRecalculateFreeformInitialBoundsWithOverrideDisplayArea()549 public void testRecalculateFreeformInitialBoundsWithOverrideDisplayArea() { 550 final TestDisplayContent freeformDisplay = createNewDisplayContent( 551 WINDOWING_MODE_FREEFORM); 552 final TaskDisplayArea secondaryDisplayArea = createTaskDisplayArea(freeformDisplay, 553 mWm, "SecondaryDisplayArea", FEATURE_RUNTIME_TASK_CONTAINER_FIRST); 554 secondaryDisplayArea.setBounds(DISPLAY_BOUNDS.width() / 2, 0, 555 DISPLAY_BOUNDS.width(), DISPLAY_BOUNDS.height()); 556 final Task launchRoot = createTask(secondaryDisplayArea, WINDOWING_MODE_FULLSCREEN, 557 ACTIVITY_TYPE_STANDARD); 558 launchRoot.mCreatedByOrganizer = true; 559 secondaryDisplayArea.setLaunchRootTask(launchRoot, new int[] { WINDOWING_MODE_FREEFORM }, 560 new int[] { ACTIVITY_TYPE_STANDARD }); 561 final Rect secondaryDAStableBounds = new Rect(); 562 secondaryDisplayArea.getStableRect(secondaryDAStableBounds); 563 564 // Specify the display and provide a layout so that it will be set to freeform bounds. 565 final ActivityOptions options = ActivityOptions.makeBasic() 566 .setLaunchDisplayId(freeformDisplay.getDisplayId()); 567 final ActivityInfo.WindowLayout layout = new WindowLayoutBuilder() 568 .setGravity(Gravity.LEFT).build(); 569 570 assertEquals(RESULT_CONTINUE, 571 new CalculateRequestBuilder().setOptions(options).setLayout(layout).calculate()); 572 573 assertEquals(secondaryDisplayArea, mResult.mPreferredTaskDisplayArea); 574 assertTrue(secondaryDAStableBounds.contains(mResult.mBounds)); 575 } 576 577 @Test testRecalculateFreeformInitialBoundsWithOverrideDisplayArea_unresizableApp()578 public void testRecalculateFreeformInitialBoundsWithOverrideDisplayArea_unresizableApp() { 579 mAtm.mDevEnableNonResizableMultiWindow = true; 580 581 final TestDisplayContent freeformDisplay = createNewDisplayContent( 582 WINDOWING_MODE_FREEFORM); 583 final TaskDisplayArea secondaryDisplayArea = createTaskDisplayArea(freeformDisplay, 584 mWm, "SecondaryDisplayArea", FEATURE_RUNTIME_TASK_CONTAINER_FIRST); 585 secondaryDisplayArea.setBounds(DISPLAY_BOUNDS.width() / 2, 0, 586 DISPLAY_BOUNDS.width(), DISPLAY_BOUNDS.height()); 587 final Task launchRoot = createTask(secondaryDisplayArea, WINDOWING_MODE_FULLSCREEN, 588 ACTIVITY_TYPE_STANDARD); 589 launchRoot.mCreatedByOrganizer = true; 590 secondaryDisplayArea.setLaunchRootTask(launchRoot, new int[] { WINDOWING_MODE_FREEFORM }, 591 new int[] { ACTIVITY_TYPE_STANDARD }); 592 final Rect secondaryDAStableBounds = new Rect(); 593 secondaryDisplayArea.getStableRect(secondaryDAStableBounds); 594 595 // The bounds will get updated for unresizable with opposite orientation on freeform display 596 final Rect displayBounds = new Rect(freeformDisplay.getBounds()); 597 mActivity.info.resizeMode = RESIZE_MODE_UNRESIZEABLE; 598 mActivity.info.screenOrientation = displayBounds.width() > displayBounds.height() 599 ? SCREEN_ORIENTATION_PORTRAIT : SCREEN_ORIENTATION_LANDSCAPE; 600 final ActivityOptions options = ActivityOptions.makeBasic() 601 .setLaunchDisplayId(freeformDisplay.getDisplayId()); 602 603 assertEquals(RESULT_CONTINUE, 604 new CalculateRequestBuilder().setOptions(options).calculate()); 605 606 assertEquals(secondaryDisplayArea, mResult.mPreferredTaskDisplayArea); 607 assertTrue(secondaryDAStableBounds.contains(mResult.mBounds)); 608 } 609 610 // ===================================== 611 // Launch Windowing Mode Related Tests 612 // ===================================== 613 @Test testBoundsInOptionsInfersFreeformOnFreeformDisplay()614 public void testBoundsInOptionsInfersFreeformOnFreeformDisplay() { 615 final TestDisplayContent freeformDisplay = createNewDisplayContent( 616 WINDOWING_MODE_FREEFORM); 617 618 final ActivityOptions options = ActivityOptions.makeBasic(); 619 options.setLaunchBounds(new Rect(0, 0, 100, 100)); 620 621 mCurrent.mPreferredTaskDisplayArea = freeformDisplay.getDefaultTaskDisplayArea(); 622 623 assertEquals(RESULT_CONTINUE, 624 new CalculateRequestBuilder().setOptions(options).calculate()); 625 626 assertEquivalentWindowingMode(WINDOWING_MODE_FREEFORM, mResult.mWindowingMode, 627 WINDOWING_MODE_FREEFORM); 628 } 629 630 @Test testBoundsInOptionsInfersFreeformWithResizeableActivity()631 public void testBoundsInOptionsInfersFreeformWithResizeableActivity() { 632 final ActivityOptions options = ActivityOptions.makeBasic(); 633 options.setLaunchBounds(new Rect(0, 0, 100, 100)); 634 635 mCurrent.mPreferredTaskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea(); 636 637 assertEquals(RESULT_CONTINUE, 638 new CalculateRequestBuilder().setOptions(options).calculate()); 639 640 assertEquivalentWindowingMode(WINDOWING_MODE_FULLSCREEN, mResult.mWindowingMode, 641 WINDOWING_MODE_FULLSCREEN); 642 } 643 644 @Test testBoundsInOptionsInfersFullscreenWithBoundsOnFreeformSupportFullscreenDisplay()645 public void testBoundsInOptionsInfersFullscreenWithBoundsOnFreeformSupportFullscreenDisplay() { 646 final TestDisplayContent fullscreenDisplay = createNewDisplayContent( 647 WINDOWING_MODE_FULLSCREEN); 648 mAtm.mTaskSupervisor.mService.mSupportsFreeformWindowManagement = true; 649 650 final ActivityOptions options = ActivityOptions.makeBasic(); 651 final Rect expectedBounds = new Rect(0, 0, 100, 100); 652 options.setLaunchBounds(expectedBounds); 653 654 mCurrent.mPreferredTaskDisplayArea = fullscreenDisplay.getDefaultTaskDisplayArea(); 655 656 assertEquals(RESULT_CONTINUE, 657 new CalculateRequestBuilder().setOptions(options).calculate()); 658 659 // Setting bounds shouldn't lead to freeform windowing mode on fullscreen display by 660 // default (even with freeform support), but we need to check here if the bounds is set even 661 // with fullscreen windowing mode in case it's restored later. 662 assertEquivalentWindowingMode(WINDOWING_MODE_FULLSCREEN, mResult.mWindowingMode, 663 WINDOWING_MODE_FULLSCREEN); 664 assertEquals(expectedBounds, mResult.mBounds); 665 } 666 667 @Test testInheritsFreeformModeFromSourceOnFullscreenDisplay()668 public void testInheritsFreeformModeFromSourceOnFullscreenDisplay() { 669 final TestDisplayContent fullscreenDisplay = createNewDisplayContent( 670 WINDOWING_MODE_FULLSCREEN); 671 final ActivityRecord source = createSourceActivity(fullscreenDisplay); 672 source.getTask().setWindowingMode(WINDOWING_MODE_FREEFORM); 673 674 assertEquals(RESULT_CONTINUE, 675 new CalculateRequestBuilder().setSource(source).calculate()); 676 677 assertEquivalentWindowingMode(WINDOWING_MODE_FREEFORM, mResult.mWindowingMode, 678 WINDOWING_MODE_FULLSCREEN); 679 } 680 681 @Test testInheritsSourceTaskWindowingModeWhenActivityIsInDifferentWindowingMode()682 public void testInheritsSourceTaskWindowingModeWhenActivityIsInDifferentWindowingMode() { 683 final TestDisplayContent fullscreenDisplay = createNewDisplayContent( 684 WINDOWING_MODE_FULLSCREEN); 685 final ActivityRecord source = createSourceActivity(fullscreenDisplay); 686 source.setWindowingMode(WINDOWING_MODE_PINNED); 687 source.getTask().setWindowingMode(WINDOWING_MODE_FREEFORM); 688 689 assertEquals(RESULT_CONTINUE, 690 new CalculateRequestBuilder().setSource(source).calculate()); 691 692 assertEquivalentWindowingMode(WINDOWING_MODE_FREEFORM, mResult.mWindowingMode, 693 WINDOWING_MODE_FULLSCREEN); 694 } 695 696 @Test testDoesNotInheritsSourceTaskWindowingModeWhenActivityIsInFreeformWindowingMode()697 public void testDoesNotInheritsSourceTaskWindowingModeWhenActivityIsInFreeformWindowingMode() { 698 // The activity could end up in different windowing mode state after calling finish() 699 // while the task would still hold the WINDOWING_MODE_PINNED state, or in other words 700 // be still in the Picture in Picture mode. 701 final TestDisplayContent fullscreenDisplay = createNewDisplayContent( 702 WINDOWING_MODE_FULLSCREEN); 703 final ActivityRecord source = createSourceActivity(fullscreenDisplay); 704 source.setWindowingMode(WINDOWING_MODE_FREEFORM); 705 source.getTask().setWindowingMode(WINDOWING_MODE_PINNED); 706 707 assertEquals(RESULT_CONTINUE, 708 new CalculateRequestBuilder().setSource(source).calculate()); 709 710 assertEquivalentWindowingMode(WINDOWING_MODE_FULLSCREEN, mResult.mWindowingMode, 711 WINDOWING_MODE_FULLSCREEN); 712 } 713 714 715 @Test testKeepsPictureInPictureLaunchModeInOptions()716 public void testKeepsPictureInPictureLaunchModeInOptions() { 717 final TestDisplayContent freeformDisplay = createNewDisplayContent( 718 WINDOWING_MODE_FREEFORM); 719 720 final ActivityOptions options = ActivityOptions.makeBasic(); 721 options.setLaunchWindowingMode(WINDOWING_MODE_PINNED); 722 723 mCurrent.mPreferredTaskDisplayArea = freeformDisplay.getDefaultTaskDisplayArea(); 724 725 assertEquals(RESULT_CONTINUE, 726 new CalculateRequestBuilder().setOptions(options).calculate()); 727 728 assertEquivalentWindowingMode(WINDOWING_MODE_PINNED, mResult.mWindowingMode, 729 WINDOWING_MODE_FREEFORM); 730 } 731 732 @Test testKeepsPictureInPictureLaunchModeWithBoundsInOptions()733 public void testKeepsPictureInPictureLaunchModeWithBoundsInOptions() { 734 final TestDisplayContent freeformDisplay = createNewDisplayContent( 735 WINDOWING_MODE_FREEFORM); 736 737 final ActivityOptions options = ActivityOptions.makeBasic(); 738 options.setLaunchWindowingMode(WINDOWING_MODE_PINNED); 739 options.setLaunchBounds(new Rect(0, 0, 100, 100)); 740 741 mCurrent.mPreferredTaskDisplayArea = freeformDisplay.getDefaultTaskDisplayArea(); 742 743 assertEquals(RESULT_CONTINUE, 744 new CalculateRequestBuilder().setOptions(options).calculate()); 745 746 assertEquivalentWindowingMode(WINDOWING_MODE_PINNED, mResult.mWindowingMode, 747 WINDOWING_MODE_FREEFORM); 748 } 749 750 @Test testKeepsFullscreenLaunchModeInOptionsOnNonFreeformDisplay()751 public void testKeepsFullscreenLaunchModeInOptionsOnNonFreeformDisplay() { 752 final ActivityOptions options = ActivityOptions.makeBasic(); 753 options.setLaunchWindowingMode(WINDOWING_MODE_FULLSCREEN); 754 755 mCurrent.mPreferredTaskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea(); 756 757 assertEquals(RESULT_CONTINUE, 758 new CalculateRequestBuilder().setOptions(options).calculate()); 759 760 assertEquivalentWindowingMode(WINDOWING_MODE_FULLSCREEN, mResult.mWindowingMode, 761 WINDOWING_MODE_FULLSCREEN); 762 } 763 764 @Test testNonEmptyLayoutInfersFreeformOnFreeformDisplay()765 public void testNonEmptyLayoutInfersFreeformOnFreeformDisplay() { 766 final TestDisplayContent freeformDisplay = createNewDisplayContent( 767 WINDOWING_MODE_FREEFORM); 768 769 mCurrent.mPreferredTaskDisplayArea = freeformDisplay.getDefaultTaskDisplayArea(); 770 771 final ActivityInfo.WindowLayout layout = new WindowLayoutBuilder() 772 .setWidth(120).setHeight(80).build(); 773 774 assertEquals(RESULT_CONTINUE, 775 new CalculateRequestBuilder().setLayout(layout).calculate()); 776 777 assertEquivalentWindowingMode(WINDOWING_MODE_FREEFORM, mResult.mWindowingMode, 778 WINDOWING_MODE_FREEFORM); 779 } 780 781 @Test testLayoutWithGravityAndEmptySizeInfersFreeformAndRespectsCurrentSize()782 public void testLayoutWithGravityAndEmptySizeInfersFreeformAndRespectsCurrentSize() { 783 final TestDisplayContent freeformDisplay = createNewDisplayContent( 784 WINDOWING_MODE_FREEFORM); 785 786 final Rect expectedLaunchBounds = new Rect(0, 0, 200, 100); 787 788 mCurrent.mPreferredTaskDisplayArea = freeformDisplay.getDefaultTaskDisplayArea(); 789 mCurrent.mBounds.set(expectedLaunchBounds); 790 791 final ActivityInfo.WindowLayout layout = new WindowLayoutBuilder() 792 .setGravity(Gravity.LEFT).build(); 793 794 assertEquals(RESULT_CONTINUE, 795 new CalculateRequestBuilder().setLayout(layout).calculate()); 796 797 assertEquals(expectedLaunchBounds.width(), mResult.mBounds.width()); 798 assertEquals(expectedLaunchBounds.height(), mResult.mBounds.height()); 799 800 assertEquivalentWindowingMode(WINDOWING_MODE_FREEFORM, mResult.mWindowingMode, 801 WINDOWING_MODE_FREEFORM); 802 } 803 804 @Test testNonEmptyLayoutUsesFullscreenWithResizeableActivity()805 public void testNonEmptyLayoutUsesFullscreenWithResizeableActivity() { 806 final ActivityInfo.WindowLayout layout = new WindowLayoutBuilder() 807 .setWidth(120).setHeight(80).build(); 808 809 mCurrent.mPreferredTaskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea(); 810 811 assertEquals(RESULT_CONTINUE, 812 new CalculateRequestBuilder().setLayout(layout).calculate()); 813 814 assertEquivalentWindowingMode(WINDOWING_MODE_FULLSCREEN, mResult.mWindowingMode, 815 WINDOWING_MODE_FULLSCREEN); 816 } 817 818 @Test testLaunchesFullscreenOnFullscreenDisplayWithFreeformHistory()819 public void testLaunchesFullscreenOnFullscreenDisplayWithFreeformHistory() { 820 mCurrent.mPreferredTaskDisplayArea = null; 821 mCurrent.mWindowingMode = WINDOWING_MODE_FREEFORM; 822 mCurrent.mBounds.set(0, 0, 200, 100); 823 824 assertEquals(RESULT_CONTINUE, new CalculateRequestBuilder().calculate()); 825 826 assertEquivalentWindowingMode(WINDOWING_MODE_FULLSCREEN, mResult.mWindowingMode, 827 WINDOWING_MODE_FULLSCREEN); 828 } 829 830 @Test testRespectsFullyResolvedCurrentParam_Fullscreen()831 public void testRespectsFullyResolvedCurrentParam_Fullscreen() { 832 final TestDisplayContent freeformDisplay = createNewDisplayContent( 833 WINDOWING_MODE_FREEFORM); 834 835 mCurrent.mPreferredTaskDisplayArea = freeformDisplay.getDefaultTaskDisplayArea(); 836 mCurrent.mWindowingMode = WINDOWING_MODE_FULLSCREEN; 837 838 assertEquals(RESULT_CONTINUE, new CalculateRequestBuilder().calculate()); 839 840 assertEquivalentWindowingMode(WINDOWING_MODE_FULLSCREEN, mResult.mWindowingMode, 841 WINDOWING_MODE_FREEFORM); 842 } 843 844 @Test testRespectsModeFromFullyResolvedCurrentParam_NonEmptyBounds()845 public void testRespectsModeFromFullyResolvedCurrentParam_NonEmptyBounds() { 846 final TestDisplayContent freeformDisplay = createNewDisplayContent( 847 WINDOWING_MODE_FREEFORM); 848 849 mCurrent.mPreferredTaskDisplayArea = freeformDisplay.getDefaultTaskDisplayArea(); 850 mCurrent.mWindowingMode = WINDOWING_MODE_FREEFORM; 851 mCurrent.mBounds.set(0, 0, 200, 100); 852 853 assertEquals(RESULT_CONTINUE, new CalculateRequestBuilder().calculate()); 854 855 assertEquivalentWindowingMode(WINDOWING_MODE_FREEFORM, mResult.mWindowingMode, 856 WINDOWING_MODE_FREEFORM); 857 } 858 859 @Test testForceMaximizesUnresizeableApp()860 public void testForceMaximizesUnresizeableApp() { 861 mAtm.mDevEnableNonResizableMultiWindow = false; 862 final TestDisplayContent freeformDisplay = createNewDisplayContent( 863 WINDOWING_MODE_FREEFORM); 864 865 final ActivityOptions options = ActivityOptions.makeBasic(); 866 options.setLaunchWindowingMode(WINDOWING_MODE_FREEFORM); 867 options.setLaunchBounds(new Rect(0, 0, 200, 100)); 868 869 mCurrent.mPreferredTaskDisplayArea = freeformDisplay.getDefaultTaskDisplayArea(); 870 mCurrent.mWindowingMode = WINDOWING_MODE_FREEFORM; 871 mCurrent.mBounds.set(0, 0, 200, 100); 872 873 mActivity.info.resizeMode = RESIZE_MODE_UNRESIZEABLE; 874 875 assertEquals(RESULT_CONTINUE, 876 new CalculateRequestBuilder().setOptions(options).calculate()); 877 878 assertEquivalentWindowingMode(WINDOWING_MODE_FULLSCREEN, mResult.mWindowingMode, 879 WINDOWING_MODE_FREEFORM); 880 } 881 882 @Test testLaunchesPortraitSizeCompatOnFreeformLandscapeDisplayWithFreeformSizeCompat()883 public void testLaunchesPortraitSizeCompatOnFreeformLandscapeDisplayWithFreeformSizeCompat() { 884 mAtm.mDevEnableNonResizableMultiWindow = true; 885 final TestDisplayContent freeformDisplay = createNewDisplayContent( 886 WINDOWING_MODE_FREEFORM); 887 888 Rect expectedLaunchBounds = new Rect(0, 0, 100, 200); 889 890 final ActivityOptions options = ActivityOptions.makeBasic(); 891 options.setLaunchWindowingMode(WINDOWING_MODE_FREEFORM); 892 options.setLaunchBounds(expectedLaunchBounds); 893 894 mCurrent.mPreferredTaskDisplayArea = freeformDisplay.getDefaultTaskDisplayArea(); 895 mCurrent.mWindowingMode = WINDOWING_MODE_FREEFORM; 896 mCurrent.mBounds.set(expectedLaunchBounds); 897 898 mActivity.info.resizeMode = RESIZE_MODE_UNRESIZEABLE; 899 mActivity.info.screenOrientation = SCREEN_ORIENTATION_PORTRAIT; 900 901 assertEquals(RESULT_CONTINUE, 902 new CalculateRequestBuilder().setOptions(options).calculate()); 903 904 assertEquals(expectedLaunchBounds, mResult.mBounds); 905 906 assertEquivalentWindowingMode(WINDOWING_MODE_FREEFORM, mResult.mWindowingMode, 907 WINDOWING_MODE_FREEFORM); 908 } 909 910 @Test testLaunchesLandscapeSizeCompatOnFreeformLandscapeDisplayWithFreeformSizeCompat()911 public void testLaunchesLandscapeSizeCompatOnFreeformLandscapeDisplayWithFreeformSizeCompat() { 912 mAtm.mDevEnableNonResizableMultiWindow = true; 913 final TestDisplayContent freeformDisplay = createNewDisplayContent( 914 WINDOWING_MODE_FREEFORM); 915 final ActivityOptions options = ActivityOptions.makeBasic(); 916 mCurrent.mPreferredTaskDisplayArea = freeformDisplay.getDefaultTaskDisplayArea(); 917 mActivity.info.resizeMode = RESIZE_MODE_UNRESIZEABLE; 918 mActivity.info.screenOrientation = SCREEN_ORIENTATION_LANDSCAPE; 919 assertEquals(RESULT_CONTINUE, 920 new CalculateRequestBuilder().setOptions(options).calculate()); 921 922 assertEquivalentWindowingMode(WINDOWING_MODE_FULLSCREEN, mResult.mWindowingMode, 923 WINDOWING_MODE_FREEFORM); 924 } 925 926 @Test testLaunchesPortraitUnresizableOnFreeformDisplayWithFreeformSizeCompat()927 public void testLaunchesPortraitUnresizableOnFreeformDisplayWithFreeformSizeCompat() { 928 mAtm.mDevEnableNonResizableMultiWindow = true; 929 final TestDisplayContent freeformDisplay = createNewDisplayContent( 930 WINDOWING_MODE_FREEFORM); 931 final ActivityOptions options = ActivityOptions.makeBasic(); 932 mCurrent.mPreferredTaskDisplayArea = freeformDisplay.getDefaultTaskDisplayArea(); 933 mActivity.info.resizeMode = RESIZE_MODE_UNRESIZEABLE; 934 mActivity.info.screenOrientation = SCREEN_ORIENTATION_PORTRAIT; 935 assertEquals(RESULT_CONTINUE, 936 new CalculateRequestBuilder().setOptions(options).calculate()); 937 938 assertEquivalentWindowingMode(WINDOWING_MODE_FREEFORM, mResult.mWindowingMode, 939 WINDOWING_MODE_FREEFORM); 940 } 941 942 @Test testSkipsForceMaximizingAppsOnNonFreeformDisplay()943 public void testSkipsForceMaximizingAppsOnNonFreeformDisplay() { 944 final ActivityOptions options = ActivityOptions.makeBasic(); 945 options.setLaunchWindowingMode(WINDOWING_MODE_FREEFORM); 946 options.setLaunchBounds(new Rect(0, 0, 200, 100)); 947 948 mCurrent.mPreferredTaskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea(); 949 mCurrent.mWindowingMode = WINDOWING_MODE_FREEFORM; 950 mCurrent.mBounds.set(0, 0, 200, 100); 951 952 mActivity.info.resizeMode = RESIZE_MODE_UNRESIZEABLE; 953 954 assertEquals(RESULT_CONTINUE, 955 new CalculateRequestBuilder().setOptions(options).calculate()); 956 957 assertEquivalentWindowingMode(WINDOWING_MODE_FREEFORM, mResult.mWindowingMode, 958 WINDOWING_MODE_FULLSCREEN); 959 } 960 961 @Test testUsesFullscreenOnNonFreeformDisplay()962 public void testUsesFullscreenOnNonFreeformDisplay() { 963 final ActivityOptions options = ActivityOptions.makeBasic(); 964 options.setLaunchDisplayId(DEFAULT_DISPLAY); 965 966 assertEquals(RESULT_CONTINUE, 967 new CalculateRequestBuilder().setOptions(options).calculate()); 968 969 assertEquivalentWindowingMode(WINDOWING_MODE_FULLSCREEN, mResult.mWindowingMode, 970 WINDOWING_MODE_FULLSCREEN); 971 } 972 973 @Test testUsesFullscreenWhenRequestedOnFreeformDisplay()974 public void testUsesFullscreenWhenRequestedOnFreeformDisplay() { 975 final TestDisplayContent freeformDisplay = createNewDisplayContent( 976 WINDOWING_MODE_FREEFORM); 977 978 final ActivityOptions options = ActivityOptions.makeBasic(); 979 options.setLaunchDisplayId(freeformDisplay.mDisplayId); 980 options.setLaunchWindowingMode(WINDOWING_MODE_FULLSCREEN); 981 982 assertEquals(RESULT_CONTINUE, 983 new CalculateRequestBuilder().setOptions(options).calculate()); 984 985 assertEquivalentWindowingMode(WINDOWING_MODE_FULLSCREEN, mResult.mWindowingMode, 986 WINDOWING_MODE_FREEFORM); 987 } 988 989 @Test testUsesFreeformByDefaultForPostNApp()990 public void testUsesFreeformByDefaultForPostNApp() { 991 final TestDisplayContent freeformDisplay = createNewDisplayContent( 992 WINDOWING_MODE_FREEFORM); 993 994 final ActivityOptions options = ActivityOptions.makeBasic(); 995 options.setLaunchDisplayId(freeformDisplay.mDisplayId); 996 997 assertEquals(RESULT_CONTINUE, 998 new CalculateRequestBuilder().setOptions(options).calculate()); 999 1000 assertEquivalentWindowingMode(WINDOWING_MODE_FREEFORM, mResult.mWindowingMode, 1001 WINDOWING_MODE_FREEFORM); 1002 } 1003 1004 @Test testUsesFreeformByDefaultForPreNResizeableAppWithoutOrientationRequest()1005 public void testUsesFreeformByDefaultForPreNResizeableAppWithoutOrientationRequest() { 1006 final TestDisplayContent freeformDisplay = createNewDisplayContent( 1007 WINDOWING_MODE_FREEFORM); 1008 1009 final ActivityOptions options = ActivityOptions.makeBasic(); 1010 options.setLaunchDisplayId(freeformDisplay.mDisplayId); 1011 1012 mActivity.info.applicationInfo.targetSdkVersion = Build.VERSION_CODES.LOLLIPOP; 1013 1014 assertEquals(RESULT_CONTINUE, 1015 new CalculateRequestBuilder().setOptions(options).calculate()); 1016 1017 assertEquivalentWindowingMode(WINDOWING_MODE_FREEFORM, mResult.mWindowingMode, 1018 WINDOWING_MODE_FREEFORM); 1019 } 1020 1021 @Test testSkipsFreeformForPreNResizeableAppOnNonFullscreenDisplay()1022 public void testSkipsFreeformForPreNResizeableAppOnNonFullscreenDisplay() { 1023 final ActivityOptions options = ActivityOptions.makeBasic(); 1024 options.setLaunchDisplayId(DEFAULT_DISPLAY); 1025 1026 mActivity.info.applicationInfo.targetSdkVersion = Build.VERSION_CODES.LOLLIPOP; 1027 1028 assertEquals(RESULT_CONTINUE, 1029 new CalculateRequestBuilder().setOptions(options).calculate()); 1030 1031 assertEquivalentWindowingMode(WINDOWING_MODE_FULLSCREEN, mResult.mWindowingMode, 1032 WINDOWING_MODE_FULLSCREEN); 1033 } 1034 1035 // ================================ 1036 // Launching Bounds Related Tests 1037 // =============================== 1038 @Test testKeepsBoundsWithPictureInPictureLaunchModeInOptions()1039 public void testKeepsBoundsWithPictureInPictureLaunchModeInOptions() { 1040 final TestDisplayContent freeformDisplay = createNewDisplayContent( 1041 WINDOWING_MODE_FREEFORM); 1042 1043 final ActivityOptions options = ActivityOptions.makeBasic(); 1044 options.setLaunchWindowingMode(WINDOWING_MODE_PINNED); 1045 1046 final Rect expected = new Rect(0, 0, 100, 100); 1047 options.setLaunchBounds(expected); 1048 1049 mCurrent.mPreferredTaskDisplayArea = freeformDisplay.getDefaultTaskDisplayArea(); 1050 1051 assertEquals(RESULT_CONTINUE, 1052 new CalculateRequestBuilder().setOptions(options).calculate()); 1053 1054 assertEquals(expected, mResult.mBounds); 1055 } 1056 1057 @Test testKeepsBoundsForMultiWindowModeInOptions()1058 public void testKeepsBoundsForMultiWindowModeInOptions() { 1059 final TestDisplayContent freeformDisplay = createNewDisplayContent( 1060 WINDOWING_MODE_FULLSCREEN); 1061 1062 final ActivityOptions options = ActivityOptions.makeBasic(); 1063 options.setLaunchWindowingMode(WINDOWING_MODE_MULTI_WINDOW); 1064 1065 final Rect expected = new Rect(0, 0, 100, 100); 1066 options.setLaunchBounds(expected); 1067 1068 mCurrent.mPreferredTaskDisplayArea = freeformDisplay.getDefaultTaskDisplayArea(); 1069 1070 assertEquals(RESULT_CONTINUE, 1071 new CalculateRequestBuilder().setOptions(options).calculate()); 1072 1073 assertEquals(expected, mResult.mBounds); 1074 } 1075 1076 @Test testRespectsLaunchBoundsWithFreeformSourceOnFullscreenDisplay()1077 public void testRespectsLaunchBoundsWithFreeformSourceOnFullscreenDisplay() { 1078 final TestDisplayContent fullscreenDisplay = createNewDisplayContent( 1079 WINDOWING_MODE_FULLSCREEN); 1080 final ActivityRecord source = createSourceActivity(fullscreenDisplay); 1081 source.getTask().setWindowingMode(WINDOWING_MODE_FREEFORM); 1082 // Set some bounds to avoid conflict with the other activity. 1083 source.setBounds(100, 100, 200, 200); 1084 1085 final ActivityOptions options = ActivityOptions.makeBasic(); 1086 final Rect expected = new Rect(0, 0, 150, 150); 1087 options.setLaunchBounds(expected); 1088 1089 assertEquals(RESULT_CONTINUE, 1090 new CalculateRequestBuilder().setSource(source).setOptions(options).calculate()); 1091 1092 assertEquals(expected, mResult.mBounds); 1093 } 1094 1095 @Test testNonEmptyLayoutBoundsRespectsGravityWithEmptySize_LeftGravity()1096 public void testNonEmptyLayoutBoundsRespectsGravityWithEmptySize_LeftGravity() { 1097 final TestDisplayContent freeformDisplay = createNewDisplayContent( 1098 WINDOWING_MODE_FREEFORM); 1099 1100 mCurrent.mPreferredTaskDisplayArea = freeformDisplay.getDefaultTaskDisplayArea(); 1101 1102 final ActivityInfo.WindowLayout layout = new WindowLayoutBuilder() 1103 .setGravity(Gravity.LEFT).build(); 1104 1105 assertEquals(RESULT_CONTINUE, 1106 new CalculateRequestBuilder().setLayout(layout).calculate()); 1107 1108 assertEquals(DISPLAY_STABLE_BOUNDS.left, mResult.mBounds.left); 1109 } 1110 1111 @Test testNonEmptyLayoutBoundsRespectsGravityWithEmptySize_TopGravity()1112 public void testNonEmptyLayoutBoundsRespectsGravityWithEmptySize_TopGravity() { 1113 final TestDisplayContent freeformDisplay = createNewDisplayContent( 1114 WINDOWING_MODE_FREEFORM); 1115 1116 mCurrent.mPreferredTaskDisplayArea = freeformDisplay.getDefaultTaskDisplayArea(); 1117 1118 final ActivityInfo.WindowLayout layout = new WindowLayoutBuilder() 1119 .setGravity(Gravity.TOP).build(); 1120 1121 assertEquals(RESULT_CONTINUE, 1122 new CalculateRequestBuilder().setLayout(layout).calculate()); 1123 1124 assertEquals(DISPLAY_STABLE_BOUNDS.top, mResult.mBounds.top); 1125 } 1126 1127 @Test testNonEmptyLayoutBoundsRespectsGravityWithEmptySize_TopLeftGravity()1128 public void testNonEmptyLayoutBoundsRespectsGravityWithEmptySize_TopLeftGravity() { 1129 final TestDisplayContent freeformDisplay = createNewDisplayContent( 1130 WINDOWING_MODE_FREEFORM); 1131 1132 mCurrent.mPreferredTaskDisplayArea = freeformDisplay.getDefaultTaskDisplayArea(); 1133 1134 final ActivityInfo.WindowLayout layout = new WindowLayoutBuilder() 1135 .setGravity(Gravity.TOP | Gravity.LEFT).build(); 1136 1137 assertEquals(RESULT_CONTINUE, 1138 new CalculateRequestBuilder().setLayout(layout).calculate()); 1139 1140 assertEquals(DISPLAY_STABLE_BOUNDS.left, mResult.mBounds.left); 1141 assertEquals(DISPLAY_STABLE_BOUNDS.top, mResult.mBounds.top); 1142 } 1143 1144 @Test testNonEmptyLayoutBoundsRespectsGravityWithEmptySize_RightGravity()1145 public void testNonEmptyLayoutBoundsRespectsGravityWithEmptySize_RightGravity() { 1146 final TestDisplayContent freeformDisplay = createNewDisplayContent( 1147 WINDOWING_MODE_FREEFORM); 1148 1149 mCurrent.mPreferredTaskDisplayArea = freeformDisplay.getDefaultTaskDisplayArea(); 1150 1151 final ActivityInfo.WindowLayout layout = new WindowLayoutBuilder() 1152 .setGravity(Gravity.RIGHT).build(); 1153 1154 assertEquals(RESULT_CONTINUE, 1155 new CalculateRequestBuilder().setLayout(layout).calculate()); 1156 1157 assertEquals(DISPLAY_STABLE_BOUNDS.right, mResult.mBounds.right); 1158 } 1159 1160 @Test testNonEmptyLayoutBoundsRespectsGravityWithEmptySize_BottomGravity()1161 public void testNonEmptyLayoutBoundsRespectsGravityWithEmptySize_BottomGravity() { 1162 final TestDisplayContent freeformDisplay = createNewDisplayContent( 1163 WINDOWING_MODE_FREEFORM); 1164 1165 mCurrent.mPreferredTaskDisplayArea = freeformDisplay.getDefaultTaskDisplayArea(); 1166 1167 final ActivityInfo.WindowLayout layout = new WindowLayoutBuilder() 1168 .setGravity(Gravity.BOTTOM).build(); 1169 1170 assertEquals(RESULT_CONTINUE, 1171 new CalculateRequestBuilder().setLayout(layout).calculate()); 1172 1173 assertEquals(DISPLAY_STABLE_BOUNDS.bottom, mResult.mBounds.bottom); 1174 } 1175 1176 @Test testNonEmptyLayoutBoundsRespectsGravityWithEmptySize_BottomRightGravity()1177 public void testNonEmptyLayoutBoundsRespectsGravityWithEmptySize_BottomRightGravity() { 1178 final TestDisplayContent freeformDisplay = createNewDisplayContent( 1179 WINDOWING_MODE_FREEFORM); 1180 1181 mCurrent.mPreferredTaskDisplayArea = freeformDisplay.getDefaultTaskDisplayArea(); 1182 1183 final ActivityInfo.WindowLayout layout = new WindowLayoutBuilder() 1184 .setGravity(Gravity.BOTTOM | Gravity.RIGHT).build(); 1185 1186 assertEquals(RESULT_CONTINUE, 1187 new CalculateRequestBuilder().setLayout(layout).calculate()); 1188 1189 assertEquals(DISPLAY_STABLE_BOUNDS.right, mResult.mBounds.right); 1190 assertEquals(DISPLAY_STABLE_BOUNDS.bottom, mResult.mBounds.bottom); 1191 } 1192 1193 @Test testNonEmptyLayoutBoundsOnFreeformDisplay_CenterToDisplay()1194 public void testNonEmptyLayoutBoundsOnFreeformDisplay_CenterToDisplay() { 1195 final TestDisplayContent freeformDisplay = createNewDisplayContent( 1196 WINDOWING_MODE_FREEFORM); 1197 1198 mCurrent.mPreferredTaskDisplayArea = freeformDisplay.getDefaultTaskDisplayArea(); 1199 1200 final ActivityInfo.WindowLayout layout = new WindowLayoutBuilder() 1201 .setWidth(120).setHeight(80).build(); 1202 1203 assertEquals(RESULT_CONTINUE, 1204 new CalculateRequestBuilder().setLayout(layout).calculate()); 1205 1206 assertEquals(new Rect(800, 400, 920, 480), mResult.mBounds); 1207 } 1208 1209 @Test testNonEmptyLayoutBoundsOnFreeformDisplay_LeftGravity()1210 public void testNonEmptyLayoutBoundsOnFreeformDisplay_LeftGravity() { 1211 final TestDisplayContent freeformDisplay = createNewDisplayContent( 1212 WINDOWING_MODE_FREEFORM); 1213 1214 mCurrent.mPreferredTaskDisplayArea = freeformDisplay.getDefaultTaskDisplayArea(); 1215 1216 final ActivityInfo.WindowLayout layout = new WindowLayoutBuilder() 1217 .setWidth(120).setHeight(80).setGravity(Gravity.LEFT).build(); 1218 1219 assertEquals(RESULT_CONTINUE, 1220 new CalculateRequestBuilder().setLayout(layout).calculate()); 1221 1222 assertEquals(new Rect(100, 400, 220, 480), mResult.mBounds); 1223 } 1224 1225 @Test testNonEmptyLayoutBoundsOnFreeformDisplay_TopGravity()1226 public void testNonEmptyLayoutBoundsOnFreeformDisplay_TopGravity() { 1227 final TestDisplayContent freeformDisplay = createNewDisplayContent( 1228 WINDOWING_MODE_FREEFORM); 1229 1230 mCurrent.mPreferredTaskDisplayArea = freeformDisplay.getDefaultTaskDisplayArea(); 1231 1232 final ActivityInfo.WindowLayout layout = new WindowLayoutBuilder() 1233 .setWidth(120).setHeight(80).setGravity(Gravity.TOP).build(); 1234 1235 assertEquals(RESULT_CONTINUE, 1236 new CalculateRequestBuilder().setLayout(layout).calculate()); 1237 1238 assertEquals(new Rect(800, 200, 920, 280), mResult.mBounds); 1239 } 1240 1241 @Test testNonEmptyLayoutBoundsOnFreeformDisplay_TopLeftGravity()1242 public void testNonEmptyLayoutBoundsOnFreeformDisplay_TopLeftGravity() { 1243 final TestDisplayContent freeformDisplay = createNewDisplayContent( 1244 WINDOWING_MODE_FREEFORM); 1245 1246 mCurrent.mPreferredTaskDisplayArea = freeformDisplay.getDefaultTaskDisplayArea(); 1247 1248 final ActivityInfo.WindowLayout layout = new WindowLayoutBuilder() 1249 .setWidth(120).setHeight(80).setGravity(Gravity.TOP | Gravity.LEFT).build(); 1250 1251 assertEquals(RESULT_CONTINUE, 1252 new CalculateRequestBuilder().setLayout(layout).calculate()); 1253 1254 assertEquals(new Rect(100, 200, 220, 280), mResult.mBounds); 1255 } 1256 1257 @Test testNonEmptyLayoutBoundsOnFreeformDisplay_RightGravity()1258 public void testNonEmptyLayoutBoundsOnFreeformDisplay_RightGravity() { 1259 final TestDisplayContent freeformDisplay = createNewDisplayContent( 1260 WINDOWING_MODE_FREEFORM); 1261 1262 mCurrent.mPreferredTaskDisplayArea = freeformDisplay.getDefaultTaskDisplayArea(); 1263 1264 final ActivityInfo.WindowLayout layout = new WindowLayoutBuilder() 1265 .setWidth(120).setHeight(80).setGravity(Gravity.RIGHT).build(); 1266 1267 assertEquals(RESULT_CONTINUE, 1268 new CalculateRequestBuilder().setLayout(layout).calculate()); 1269 1270 assertEquals(new Rect(1500, 400, 1620, 480), mResult.mBounds); 1271 } 1272 1273 @Test testNonEmptyLayoutBoundsOnFreeformDisplay_BottomGravity()1274 public void testNonEmptyLayoutBoundsOnFreeformDisplay_BottomGravity() { 1275 final TestDisplayContent freeformDisplay = createNewDisplayContent( 1276 WINDOWING_MODE_FREEFORM); 1277 1278 mCurrent.mPreferredTaskDisplayArea = freeformDisplay.getDefaultTaskDisplayArea(); 1279 1280 final ActivityInfo.WindowLayout layout = new WindowLayoutBuilder() 1281 .setWidth(120).setHeight(80).setGravity(Gravity.BOTTOM).build(); 1282 1283 assertEquals(RESULT_CONTINUE, 1284 new CalculateRequestBuilder().setLayout(layout).calculate()); 1285 1286 assertEquals(new Rect(800, 600, 920, 680), mResult.mBounds); 1287 } 1288 1289 @Test testNonEmptyLayoutBoundsOnFreeformDisplay_RightBottomGravity()1290 public void testNonEmptyLayoutBoundsOnFreeformDisplay_RightBottomGravity() { 1291 final TestDisplayContent freeformDisplay = createNewDisplayContent( 1292 WINDOWING_MODE_FREEFORM); 1293 1294 mCurrent.mPreferredTaskDisplayArea = freeformDisplay.getDefaultTaskDisplayArea(); 1295 1296 final ActivityInfo.WindowLayout layout = new WindowLayoutBuilder() 1297 .setWidth(120).setHeight(80).setGravity(Gravity.BOTTOM | Gravity.RIGHT).build(); 1298 1299 assertEquals(RESULT_CONTINUE, 1300 new CalculateRequestBuilder().setLayout(layout).calculate()); 1301 1302 assertEquals(new Rect(1500, 600, 1620, 680), mResult.mBounds); 1303 } 1304 1305 @Test testNonEmptyLayoutFractionBoundsOnFreeformDisplay()1306 public void testNonEmptyLayoutFractionBoundsOnFreeformDisplay() { 1307 final TestDisplayContent freeformDisplay = createNewDisplayContent( 1308 WINDOWING_MODE_FREEFORM); 1309 1310 mCurrent.mPreferredTaskDisplayArea = freeformDisplay.getDefaultTaskDisplayArea(); 1311 1312 final ActivityInfo.WindowLayout layout = new WindowLayoutBuilder() 1313 .setWidthFraction(0.125f).setHeightFraction(0.1f).build(); 1314 1315 assertEquals(RESULT_CONTINUE, 1316 new CalculateRequestBuilder().setLayout(layout).calculate()); 1317 1318 assertEquals(new Rect(765, 416, 955, 464), mResult.mBounds); 1319 } 1320 1321 @Test testRespectBoundsFromFullyResolvedCurrentParam_NonEmptyBounds()1322 public void testRespectBoundsFromFullyResolvedCurrentParam_NonEmptyBounds() { 1323 final TestDisplayContent freeformDisplay = createNewDisplayContent( 1324 WINDOWING_MODE_FREEFORM); 1325 1326 mCurrent.mPreferredTaskDisplayArea = freeformDisplay.getDefaultTaskDisplayArea(); 1327 mCurrent.mWindowingMode = WINDOWING_MODE_FREEFORM; 1328 mCurrent.mBounds.set(0, 0, 200, 100); 1329 1330 assertEquals(RESULT_CONTINUE, new CalculateRequestBuilder().calculate()); 1331 1332 assertEquals(new Rect(0, 0, 200, 100), mResult.mBounds); 1333 } 1334 1335 @Test testReturnBoundsForFullscreenWindowingMode()1336 public void testReturnBoundsForFullscreenWindowingMode() { 1337 final TestDisplayContent freeformDisplay = createNewDisplayContent( 1338 WINDOWING_MODE_FREEFORM); 1339 1340 mCurrent.mPreferredTaskDisplayArea = freeformDisplay.getDefaultTaskDisplayArea(); 1341 mCurrent.mWindowingMode = WINDOWING_MODE_FULLSCREEN; 1342 mCurrent.mBounds.set(0, 0, 200, 100); 1343 1344 assertEquals(RESULT_CONTINUE, new CalculateRequestBuilder().calculate()); 1345 1346 assertEquals(new Rect(0, 0, 200, 100), mResult.mBounds); 1347 } 1348 1349 @Test testUsesDisplayOrientationForNoSensorOrientation()1350 public void testUsesDisplayOrientationForNoSensorOrientation() { 1351 final TestDisplayContent freeformDisplay = createNewDisplayContent( 1352 WINDOWING_MODE_FREEFORM); 1353 1354 final ActivityOptions options = ActivityOptions.makeBasic(); 1355 options.setLaunchDisplayId(freeformDisplay.mDisplayId); 1356 options.setLaunchWindowingMode(WINDOWING_MODE_FREEFORM); 1357 1358 mActivity.info.screenOrientation = SCREEN_ORIENTATION_NOSENSOR; 1359 1360 assertEquals(RESULT_CONTINUE, 1361 new CalculateRequestBuilder().setOptions(options).calculate()); 1362 1363 final int orientationForDisplay = orientationFromBounds(freeformDisplay.getBounds()); 1364 final int orientationForTask = orientationFromBounds(mResult.mBounds); 1365 assertEquals("Launch bounds orientation should be the same as the display, but" 1366 + " display orientation is " 1367 + ActivityInfo.screenOrientationToString(orientationForDisplay) 1368 + " launch bounds orientation is " 1369 + ActivityInfo.screenOrientationToString(orientationForTask), 1370 orientationForDisplay, orientationForTask); 1371 } 1372 1373 @Test testRespectsAppRequestedOrientation_Landscape()1374 public void testRespectsAppRequestedOrientation_Landscape() { 1375 final TestDisplayContent freeformDisplay = createNewDisplayContent( 1376 WINDOWING_MODE_FREEFORM); 1377 1378 final ActivityOptions options = ActivityOptions.makeBasic(); 1379 options.setLaunchDisplayId(freeformDisplay.mDisplayId); 1380 options.setLaunchWindowingMode(WINDOWING_MODE_FREEFORM); 1381 1382 mActivity.info.screenOrientation = SCREEN_ORIENTATION_LANDSCAPE; 1383 1384 assertEquals(RESULT_CONTINUE, 1385 new CalculateRequestBuilder().setOptions(options).calculate()); 1386 1387 assertEquals(SCREEN_ORIENTATION_LANDSCAPE, orientationFromBounds(mResult.mBounds)); 1388 } 1389 1390 @Test testRespectsAppRequestedOrientation_Portrait()1391 public void testRespectsAppRequestedOrientation_Portrait() { 1392 final TestDisplayContent freeformDisplay = createNewDisplayContent( 1393 WINDOWING_MODE_FREEFORM); 1394 1395 final ActivityOptions options = ActivityOptions.makeBasic(); 1396 options.setLaunchDisplayId(freeformDisplay.mDisplayId); 1397 options.setLaunchWindowingMode(WINDOWING_MODE_FREEFORM); 1398 1399 mActivity.info.screenOrientation = SCREEN_ORIENTATION_PORTRAIT; 1400 1401 assertEquals(RESULT_CONTINUE, 1402 new CalculateRequestBuilder().setOptions(options).calculate()); 1403 1404 assertEquals(SCREEN_ORIENTATION_PORTRAIT, orientationFromBounds(mResult.mBounds)); 1405 } 1406 1407 @Test testDefaultSizeSmallerThanBigScreen()1408 public void testDefaultSizeSmallerThanBigScreen() { 1409 final TestDisplayContent freeformDisplay = createNewDisplayContent( 1410 WINDOWING_MODE_FREEFORM); 1411 1412 final ActivityOptions options = ActivityOptions.makeBasic(); 1413 options.setLaunchDisplayId(freeformDisplay.mDisplayId); 1414 1415 mActivity.info.applicationInfo.targetSdkVersion = Build.VERSION_CODES.LOLLIPOP; 1416 1417 assertEquals(RESULT_CONTINUE, 1418 new CalculateRequestBuilder().setOptions(options).calculate()); 1419 1420 final int resultWidth = mResult.mBounds.width(); 1421 final int displayWidth = freeformDisplay.getBounds().width(); 1422 assertTrue("Result width " + resultWidth + " is not smaller than " + displayWidth, 1423 resultWidth < displayWidth); 1424 1425 final int resultHeight = mResult.mBounds.height(); 1426 final int displayHeight = freeformDisplay.getBounds().height(); 1427 assertTrue("Result width " + resultHeight + " is not smaller than " 1428 + displayHeight, resultHeight < displayHeight); 1429 } 1430 1431 @Test testDefaultFreeformSizeCenteredToDisplay()1432 public void testDefaultFreeformSizeCenteredToDisplay() { 1433 final TestDisplayContent freeformDisplay = createNewDisplayContent( 1434 WINDOWING_MODE_FREEFORM); 1435 1436 final ActivityOptions options = ActivityOptions.makeBasic(); 1437 options.setLaunchDisplayId(freeformDisplay.mDisplayId); 1438 1439 mActivity.info.applicationInfo.targetSdkVersion = Build.VERSION_CODES.LOLLIPOP; 1440 1441 assertEquals(RESULT_CONTINUE, 1442 new CalculateRequestBuilder().setOptions(options).calculate()); 1443 1444 assertEquals("Distance to left and right should be equal.", 1445 mResult.mBounds.left - DISPLAY_STABLE_BOUNDS.left, 1446 DISPLAY_STABLE_BOUNDS.right - mResult.mBounds.right, /* delta */ 1); 1447 assertEquals("Distance to top and bottom should be equal.", 1448 mResult.mBounds.top - DISPLAY_STABLE_BOUNDS.top, 1449 DISPLAY_STABLE_BOUNDS.bottom - mResult.mBounds.bottom, /* delta */ 1); 1450 } 1451 1452 @Test testDefaultFreeformSizeShrinksOnSmallDisplay()1453 public void testDefaultFreeformSizeShrinksOnSmallDisplay() { 1454 final TestDisplayContent freeformDisplay = createNewDisplayContent( 1455 WINDOWING_MODE_FREEFORM, SMALL_DISPLAY_BOUNDS, SMALL_DISPLAY_STABLE_BOUNDS); 1456 1457 final ActivityOptions options = ActivityOptions.makeBasic(); 1458 options.setLaunchDisplayId(freeformDisplay.mDisplayId); 1459 1460 assertEquals(RESULT_CONTINUE, new CalculateRequestBuilder().setOptions(options) 1461 .calculate()); 1462 1463 assertEquals(new Rect(414, 77, 587, 423), mResult.mBounds); 1464 } 1465 1466 @Test testDefaultFreeformSizeRespectsMinAspectRatio()1467 public void testDefaultFreeformSizeRespectsMinAspectRatio() { 1468 final TestDisplayContent freeformDisplay = createNewDisplayContent( 1469 WINDOWING_MODE_FREEFORM); 1470 1471 final ActivityOptions options = ActivityOptions.makeBasic(); 1472 options.setLaunchDisplayId(freeformDisplay.mDisplayId); 1473 1474 mActivity.info.applicationInfo.targetSdkVersion = Build.VERSION_CODES.LOLLIPOP; 1475 mActivity.info.setMinAspectRatio(5f); 1476 1477 assertEquals(RESULT_CONTINUE, 1478 new CalculateRequestBuilder() 1479 .setOptions(options).calculate()); 1480 1481 final float aspectRatio = 1482 (float) Math.max(mResult.mBounds.width(), mResult.mBounds.height()) 1483 / (float) Math.min(mResult.mBounds.width(), mResult.mBounds.height()); 1484 assertTrue("Bounds aspect ratio should be at least 5.0, but was " + aspectRatio, 1485 aspectRatio >= 5f); 1486 } 1487 1488 @Test testDefaultFreeformSizeRespectsMaxAspectRatio()1489 public void testDefaultFreeformSizeRespectsMaxAspectRatio() { 1490 final TestDisplayContent freeformDisplay = createNewDisplayContent( 1491 WINDOWING_MODE_FREEFORM); 1492 1493 final ActivityOptions options = ActivityOptions.makeBasic(); 1494 options.setLaunchDisplayId(freeformDisplay.mDisplayId); 1495 1496 mActivity.info.applicationInfo.targetSdkVersion = Build.VERSION_CODES.LOLLIPOP; 1497 mActivity.info.setMaxAspectRatio(1.5f); 1498 1499 assertEquals(RESULT_CONTINUE, 1500 new CalculateRequestBuilder() 1501 .setOptions(options).calculate()); 1502 1503 final float aspectRatio = 1504 (float) Math.max(mResult.mBounds.width(), mResult.mBounds.height()) 1505 / (float) Math.min(mResult.mBounds.width(), mResult.mBounds.height()); 1506 assertTrue("Bounds aspect ratio should be at most 1.5, but was " + aspectRatio, 1507 aspectRatio <= 1.5f); 1508 } 1509 1510 @Test testCascadesToSourceSizeForFreeform()1511 public void testCascadesToSourceSizeForFreeform() { 1512 final TestDisplayContent freeformDisplay = createNewDisplayContent( 1513 WINDOWING_MODE_FREEFORM); 1514 1515 final ActivityOptions options = ActivityOptions.makeBasic(); 1516 options.setLaunchDisplayId(freeformDisplay.mDisplayId); 1517 1518 final ActivityRecord source = createSourceActivity(freeformDisplay); 1519 source.setBounds(0, 0, 412, 732); 1520 1521 mActivity.info.applicationInfo.targetSdkVersion = Build.VERSION_CODES.LOLLIPOP; 1522 1523 assertEquals(RESULT_CONTINUE, 1524 new CalculateRequestBuilder().setSource(source).setOptions(options).calculate()); 1525 1526 final Rect displayBounds = freeformDisplay.getBounds(); 1527 assertTrue("Left bounds should be larger than 0.", mResult.mBounds.left > 0); 1528 assertTrue("Top bounds should be larger than 0.", mResult.mBounds.top > 0); 1529 assertTrue("Bounds should be centered at somewhere in the left half, but it's " 1530 + "centerX is " + mResult.mBounds.centerX(), 1531 mResult.mBounds.centerX() < displayBounds.centerX()); 1532 assertTrue("Bounds should be centered at somewhere in the top half, but it's " 1533 + "centerY is " + mResult.mBounds.centerY(), 1534 mResult.mBounds.centerY() < displayBounds.centerY()); 1535 } 1536 1537 @Test testCascadesToSourceSizeForFreeformRespectingMinAspectRatio()1538 public void testCascadesToSourceSizeForFreeformRespectingMinAspectRatio() { 1539 final TestDisplayContent freeformDisplay = createNewDisplayContent( 1540 WINDOWING_MODE_FREEFORM); 1541 1542 final ActivityOptions options = ActivityOptions.makeBasic(); 1543 options.setLaunchDisplayId(freeformDisplay.mDisplayId); 1544 1545 final ActivityRecord source = createSourceActivity(freeformDisplay); 1546 source.setBounds(0, 0, 412, 732); 1547 1548 mActivity.info.applicationInfo.targetSdkVersion = Build.VERSION_CODES.LOLLIPOP; 1549 mActivity.info.setMinAspectRatio(5f); 1550 1551 assertEquals(RESULT_CONTINUE, 1552 new CalculateRequestBuilder().setSource(source).setOptions(options).calculate()); 1553 1554 final Rect displayBounds = freeformDisplay.getBounds(); 1555 assertTrue("Left bounds should be larger than 0.", mResult.mBounds.left > 0); 1556 assertTrue("Top bounds should be larger than 0.", mResult.mBounds.top > 0); 1557 assertTrue("Bounds should be centered at somewhere in the left half, but it's " 1558 + "centerX is " + mResult.mBounds.centerX(), 1559 mResult.mBounds.centerX() < displayBounds.centerX()); 1560 assertTrue("Bounds should be centered at somewhere in the top half, but it's " 1561 + "centerY is " + mResult.mBounds.centerY(), 1562 mResult.mBounds.centerY() < displayBounds.centerY()); 1563 final float aspectRatio = 1564 (float) Math.max(mResult.mBounds.width(), mResult.mBounds.height()) 1565 / (float) Math.min(mResult.mBounds.width(), mResult.mBounds.height()); 1566 assertTrue("Bounds aspect ratio should be at least 5.0, but was " + aspectRatio, 1567 aspectRatio >= 5f); 1568 } 1569 1570 @Test testCascadesToSourceSizeForFreeformRespectingMaxAspectRatio()1571 public void testCascadesToSourceSizeForFreeformRespectingMaxAspectRatio() { 1572 final TestDisplayContent freeformDisplay = createNewDisplayContent( 1573 WINDOWING_MODE_FREEFORM); 1574 1575 final ActivityOptions options = ActivityOptions.makeBasic(); 1576 options.setLaunchDisplayId(freeformDisplay.mDisplayId); 1577 1578 final ActivityRecord source = createSourceActivity(freeformDisplay); 1579 source.setBounds(0, 0, 412, 732); 1580 1581 mActivity.info.applicationInfo.targetSdkVersion = Build.VERSION_CODES.LOLLIPOP; 1582 mActivity.info.setMaxAspectRatio(1.5f); 1583 1584 assertEquals(RESULT_CONTINUE, 1585 new CalculateRequestBuilder().setSource(source).setOptions(options).calculate()); 1586 1587 final Rect displayBounds = freeformDisplay.getBounds(); 1588 assertTrue("Left bounds should be larger than 0.", mResult.mBounds.left > 0); 1589 assertTrue("Top bounds should be larger than 0.", mResult.mBounds.top > 0); 1590 assertTrue("Bounds should be centered at somewhere in the left half, but it's " 1591 + "centerX is " + mResult.mBounds.centerX(), 1592 mResult.mBounds.centerX() < displayBounds.centerX()); 1593 assertTrue("Bounds should be centered at somewhere in the top half, but it's " 1594 + "centerY is " + mResult.mBounds.centerY(), 1595 mResult.mBounds.centerY() < displayBounds.centerY()); 1596 final float aspectRatio = 1597 (float) Math.max(mResult.mBounds.width(), mResult.mBounds.height()) 1598 / (float) Math.min(mResult.mBounds.width(), mResult.mBounds.height()); 1599 assertTrue("Bounds aspect ratio should be at most 1.5, but was " + aspectRatio, 1600 aspectRatio <= 1.5f); 1601 } 1602 1603 @Test testAdjustBoundsToFitDisplay_TopLeftOutOfDisplay()1604 public void testAdjustBoundsToFitDisplay_TopLeftOutOfDisplay() { 1605 final TestDisplayContent freeformDisplay = createNewDisplayContent( 1606 WINDOWING_MODE_FREEFORM); 1607 1608 final ActivityOptions options = ActivityOptions.makeBasic(); 1609 options.setLaunchDisplayId(freeformDisplay.mDisplayId); 1610 1611 final ActivityRecord source = createSourceActivity(freeformDisplay); 1612 source.setBounds(0, 0, 200, 400); 1613 1614 mActivity.info.applicationInfo.targetSdkVersion = Build.VERSION_CODES.LOLLIPOP; 1615 1616 assertEquals(RESULT_CONTINUE, 1617 new CalculateRequestBuilder().setSource(source).setOptions(options).calculate()); 1618 1619 final Rect displayBounds = freeformDisplay.getBounds(); 1620 assertTrue("display bounds doesn't contain result. display bounds: " 1621 + displayBounds + " result: " + mResult.mBounds, 1622 displayBounds.contains(mResult.mBounds)); 1623 } 1624 1625 @Test testAdjustBoundsToFitDisplay_BottomRightOutOfDisplay()1626 public void testAdjustBoundsToFitDisplay_BottomRightOutOfDisplay() { 1627 final TestDisplayContent freeformDisplay = createNewDisplayContent( 1628 WINDOWING_MODE_FREEFORM); 1629 1630 final ActivityOptions options = ActivityOptions.makeBasic(); 1631 options.setLaunchDisplayId(freeformDisplay.mDisplayId); 1632 1633 final ActivityRecord source = createSourceActivity(freeformDisplay); 1634 source.setBounds(1720, 680, 1920, 1080); 1635 1636 mActivity.info.applicationInfo.targetSdkVersion = Build.VERSION_CODES.LOLLIPOP; 1637 1638 assertEquals(RESULT_CONTINUE, 1639 new CalculateRequestBuilder().setSource(source).setOptions(options).calculate()); 1640 1641 final Rect displayBounds = freeformDisplay.getBounds(); 1642 assertTrue("display bounds doesn't contain result. display bounds: " 1643 + displayBounds + " result: " + mResult.mBounds, 1644 displayBounds.contains(mResult.mBounds)); 1645 } 1646 1647 @Test testAdjustBoundsToFitNewDisplay_LargerThanDisplay()1648 public void testAdjustBoundsToFitNewDisplay_LargerThanDisplay() { 1649 final TestDisplayContent freeformDisplay = createNewDisplayContent( 1650 WINDOWING_MODE_FREEFORM); 1651 1652 final ActivityOptions options = ActivityOptions.makeBasic(); 1653 options.setLaunchDisplayId(freeformDisplay.mDisplayId); 1654 1655 mCurrent.mWindowingMode = WINDOWING_MODE_FREEFORM; 1656 mCurrent.mBounds.set(0, 0, 3000, 2000); 1657 1658 mActivity.info.applicationInfo.targetSdkVersion = Build.VERSION_CODES.LOLLIPOP; 1659 1660 assertEquals(RESULT_CONTINUE, 1661 new CalculateRequestBuilder().setOptions(options).calculate()); 1662 1663 // Must shrink to fit the display while reserving aspect ratio. 1664 assertEquals(new Rect(127, 227, 766, 653), mResult.mBounds); 1665 } 1666 1667 @Test testAdjustBoundsToFitNewDisplay_LargerThanDisplay_RTL()1668 public void testAdjustBoundsToFitNewDisplay_LargerThanDisplay_RTL() { 1669 final Configuration overrideConfig = 1670 mRootWindowContainer.getRequestedOverrideConfiguration(); 1671 // Egyptian Arabic is a RTL language. 1672 overrideConfig.setLayoutDirection(new Locale("ar", "EG")); 1673 mRootWindowContainer.onRequestedOverrideConfigurationChanged(overrideConfig); 1674 1675 final TestDisplayContent freeformDisplay = createNewDisplayContent( 1676 WINDOWING_MODE_FREEFORM); 1677 1678 final ActivityOptions options = ActivityOptions.makeBasic(); 1679 options.setLaunchDisplayId(freeformDisplay.mDisplayId); 1680 final ActivityInfo.WindowLayout layout = new WindowLayoutBuilder() 1681 .setMinWidth(500).setMinHeight(500).build(); 1682 1683 mCurrent.mWindowingMode = WINDOWING_MODE_FREEFORM; 1684 mCurrent.mBounds.set(0, 0, 2000, 3000); 1685 1686 mActivity.info.applicationInfo.targetSdkVersion = Build.VERSION_CODES.LOLLIPOP; 1687 1688 assertEquals(RESULT_CONTINUE, 1689 new CalculateRequestBuilder().setOptions(options).setLayout(layout).calculate()); 1690 1691 // Must shrink to fit the display while reserving aspect ratio. 1692 assertEquals(new Rect(1093, 227, 1593, 727), mResult.mBounds); 1693 } 1694 1695 @Test testRespectsLayoutMinDimensions()1696 public void testRespectsLayoutMinDimensions() { 1697 final TestDisplayContent freeformDisplay = createNewDisplayContent( 1698 WINDOWING_MODE_FREEFORM); 1699 1700 // This test case requires a relatively big app bounds to ensure the default size calculated 1701 // by letterbox won't be too small to hold the minimum width/height. 1702 configInsetsState( 1703 freeformDisplay.getInsetsStateController().getRawInsetsState(), freeformDisplay, 1704 new Rect(10, 10, 1910, 1070)); 1705 1706 final ActivityOptions options = ActivityOptions.makeBasic(); 1707 options.setLaunchDisplayId(freeformDisplay.mDisplayId); 1708 1709 final ActivityInfo.WindowLayout layout = new WindowLayoutBuilder() 1710 .setMinWidth(500).setMinHeight(800).build(); 1711 1712 mActivity.info.applicationInfo.targetSdkVersion = Build.VERSION_CODES.LOLLIPOP; 1713 1714 assertEquals(RESULT_CONTINUE, 1715 new CalculateRequestBuilder().setLayout(layout).setOptions(options).calculate()); 1716 1717 assertEquals(500, mResult.mBounds.width()); 1718 assertEquals(800, mResult.mBounds.height()); 1719 } 1720 1721 @Test testRotatesInPlaceInitialBoundsMismatchOrientation()1722 public void testRotatesInPlaceInitialBoundsMismatchOrientation() { 1723 final TestDisplayContent freeformDisplay = createNewDisplayContent( 1724 WINDOWING_MODE_FREEFORM); 1725 1726 final ActivityOptions options = ActivityOptions.makeBasic(); 1727 options.setLaunchDisplayId(freeformDisplay.mDisplayId); 1728 options.setLaunchBounds(new Rect(100, 100, 500, 300)); 1729 1730 mActivity.info.screenOrientation = SCREEN_ORIENTATION_PORTRAIT; 1731 1732 assertEquals(RESULT_CONTINUE, 1733 new CalculateRequestBuilder().setOptions(options).calculate()); 1734 1735 assertEquals(new Rect(200, 0, 400, 400), mResult.mBounds); 1736 } 1737 1738 @Test testShiftsToRightForCloseToLeftBoundsWhenConflict()1739 public void testShiftsToRightForCloseToLeftBoundsWhenConflict() { 1740 final TestDisplayContent freeformDisplay = createNewDisplayContent( 1741 WINDOWING_MODE_FREEFORM); 1742 1743 addFreeformTaskTo(freeformDisplay, new Rect(50, 50, 100, 150)); 1744 1745 final ActivityOptions options = ActivityOptions.makeBasic(); 1746 options.setLaunchDisplayId(freeformDisplay.mDisplayId); 1747 options.setLaunchBounds(new Rect(50, 50, 500, 300)); 1748 1749 assertEquals(RESULT_CONTINUE, 1750 new CalculateRequestBuilder().setOptions(options).calculate()); 1751 1752 assertEquals(new Rect(170, 50, 620, 300), mResult.mBounds); 1753 } 1754 1755 @Test testShiftsToLeftForCloseToRightBoundsWhenConflict()1756 public void testShiftsToLeftForCloseToRightBoundsWhenConflict() { 1757 final TestDisplayContent freeformDisplay = createNewDisplayContent( 1758 WINDOWING_MODE_FREEFORM); 1759 1760 addFreeformTaskTo(freeformDisplay, new Rect(1720, 50, 1830, 150)); 1761 1762 final ActivityOptions options = ActivityOptions.makeBasic(); 1763 options.setLaunchDisplayId(freeformDisplay.mDisplayId); 1764 options.setLaunchBounds(new Rect(1720, 50, 1850, 300)); 1765 1766 assertEquals(RESULT_CONTINUE, 1767 new CalculateRequestBuilder().setOptions(options).calculate()); 1768 1769 assertEquals(new Rect(1600, 50, 1730, 300), mResult.mBounds); 1770 } 1771 1772 @Test testShiftsToRightFirstForHorizontallyCenteredAndCloseToTopWhenConflict()1773 public void testShiftsToRightFirstForHorizontallyCenteredAndCloseToTopWhenConflict() { 1774 final TestDisplayContent freeformDisplay = createNewDisplayContent( 1775 WINDOWING_MODE_FREEFORM); 1776 1777 addFreeformTaskTo(freeformDisplay, new Rect(0, 0, 100, 300)); 1778 1779 final ActivityOptions options = ActivityOptions.makeBasic(); 1780 options.setLaunchDisplayId(freeformDisplay.mDisplayId); 1781 options.setLaunchBounds(new Rect(0, 0, 1800, 200)); 1782 1783 assertEquals(RESULT_CONTINUE, 1784 new CalculateRequestBuilder().setOptions(options).calculate()); 1785 1786 assertEquals(new Rect(120, 0, 1920, 200), mResult.mBounds); 1787 } 1788 1789 @Test testShiftsToLeftNoSpaceOnRightForHorizontallyCenteredAndCloseToTopWhenConflict()1790 public void testShiftsToLeftNoSpaceOnRightForHorizontallyCenteredAndCloseToTopWhenConflict() { 1791 final TestDisplayContent freeformDisplay = createNewDisplayContent( 1792 WINDOWING_MODE_FREEFORM); 1793 1794 addFreeformTaskTo(freeformDisplay, new Rect(120, 0, 240, 300)); 1795 1796 final ActivityOptions options = ActivityOptions.makeBasic(); 1797 options.setLaunchDisplayId(freeformDisplay.mDisplayId); 1798 options.setLaunchBounds(new Rect(120, 0, 1860, 200)); 1799 1800 assertEquals(RESULT_CONTINUE, 1801 new CalculateRequestBuilder().setOptions(options).calculate()); 1802 1803 assertEquals(new Rect(0, 0, 1740, 200), mResult.mBounds); 1804 } 1805 1806 @Test testShiftsToBottomRightFirstForCenteredBoundsWhenConflict()1807 public void testShiftsToBottomRightFirstForCenteredBoundsWhenConflict() { 1808 final TestDisplayContent freeformDisplay = createNewDisplayContent( 1809 WINDOWING_MODE_FREEFORM); 1810 1811 addFreeformTaskTo(freeformDisplay, new Rect(120, 0, 240, 100)); 1812 1813 final ActivityOptions options = ActivityOptions.makeBasic(); 1814 options.setLaunchDisplayId(freeformDisplay.mDisplayId); 1815 options.setLaunchBounds(new Rect(120, 0, 1800, 1013)); 1816 1817 assertEquals(RESULT_CONTINUE, 1818 new CalculateRequestBuilder().setOptions(options).calculate()); 1819 1820 assertEquals(new Rect(240, 67, 1920, 1080), mResult.mBounds); 1821 } 1822 1823 @Test testShiftsToTopLeftIfNoSpaceOnBottomRightForCenteredBoundsWhenConflict()1824 public void testShiftsToTopLeftIfNoSpaceOnBottomRightForCenteredBoundsWhenConflict() { 1825 final TestDisplayContent freeformDisplay = createNewDisplayContent( 1826 WINDOWING_MODE_FREEFORM); 1827 1828 addFreeformTaskTo(freeformDisplay, new Rect(120, 67, 240, 100)); 1829 1830 final ActivityOptions options = ActivityOptions.makeBasic(); 1831 options.setLaunchDisplayId(freeformDisplay.mDisplayId); 1832 options.setLaunchBounds(new Rect(120, 67, 1800, 1020)); 1833 1834 assertEquals(RESULT_CONTINUE, 1835 new CalculateRequestBuilder().setOptions(options).calculate()); 1836 1837 assertEquals(new Rect(0, 0, 1680, 953), mResult.mBounds); 1838 } 1839 1840 @Test returnsNonFullscreenBoundsOnFullscreenDisplayWithFreeformHistory()1841 public void returnsNonFullscreenBoundsOnFullscreenDisplayWithFreeformHistory() { 1842 mCurrent.mPreferredTaskDisplayArea = null; 1843 mCurrent.mWindowingMode = WINDOWING_MODE_FREEFORM; 1844 mCurrent.mBounds.set(0, 0, 200, 100); 1845 1846 assertEquals(RESULT_CONTINUE, new CalculateRequestBuilder().calculate()); 1847 1848 // Returned bounds with in fullscreen mode will be set to last non-fullscreen bounds. 1849 assertEquals(new Rect(0, 0, 200, 100), mResult.mBounds); 1850 } 1851 1852 @Test testAdjustsBoundsToFitInDisplayFullyResolvedBounds()1853 public void testAdjustsBoundsToFitInDisplayFullyResolvedBounds() { 1854 final TestDisplayContent freeformDisplay = createNewDisplayContent( 1855 WINDOWING_MODE_FREEFORM); 1856 1857 mCurrent.mPreferredTaskDisplayArea = null; 1858 mCurrent.mWindowingMode = WINDOWING_MODE_FREEFORM; 1859 mCurrent.mBounds.set(-100, -200, 200, 100); 1860 1861 final ActivityOptions options = ActivityOptions.makeBasic(); 1862 options.setLaunchDisplayId(freeformDisplay.mDisplayId); 1863 1864 assertEquals(RESULT_CONTINUE, 1865 new CalculateRequestBuilder().setOptions(options).calculate()); 1866 1867 assertEquals(new Rect(127, 227, 427, 527), mResult.mBounds); 1868 } 1869 1870 @Test testAdjustsBoundsToAvoidConflictFullyResolvedBounds()1871 public void testAdjustsBoundsToAvoidConflictFullyResolvedBounds() { 1872 final TestDisplayContent freeformDisplay = createNewDisplayContent( 1873 WINDOWING_MODE_FREEFORM); 1874 1875 addFreeformTaskTo(freeformDisplay, new Rect(0, 0, 200, 100)); 1876 1877 mCurrent.mPreferredTaskDisplayArea = freeformDisplay.getDefaultTaskDisplayArea(); 1878 mCurrent.mWindowingMode = WINDOWING_MODE_FREEFORM; 1879 mCurrent.mBounds.set(0, 0, 200, 100); 1880 1881 assertEquals(RESULT_CONTINUE, new CalculateRequestBuilder().calculate()); 1882 1883 assertEquals(new Rect(120, 0, 320, 100), mResult.mBounds); 1884 } 1885 1886 @Test testAdjustBoundsToAvoidConflictAlwaysExits()1887 public void testAdjustBoundsToAvoidConflictAlwaysExits() { 1888 Rect displayBounds = new Rect(0, 0, 40, 40); 1889 List<Rect> existingTaskBounds = new ArrayList<>(); 1890 for (int i = 0; i < 9; i++) { 1891 for (int j = 0; j < 9; j++) { 1892 int left = i * 5; 1893 int top = j * 5; 1894 existingTaskBounds.add(new Rect(left, top, left + 20, top + 20)); 1895 } 1896 } 1897 Rect startingBounds = new Rect(0, 0, 20, 20); 1898 Rect adjustedBounds = new Rect(startingBounds); 1899 mTarget.adjustBoundsToAvoidConflict(displayBounds, existingTaskBounds, adjustedBounds); 1900 assertEquals(startingBounds, adjustedBounds); 1901 } 1902 1903 @Test testNoMultiDisplaySupports()1904 public void testNoMultiDisplaySupports() { 1905 final boolean orgValue = mAtm.mSupportsMultiDisplay; 1906 final TestDisplayContent display = createNewDisplayContent(WINDOWING_MODE_FULLSCREEN); 1907 mCurrent.mPreferredTaskDisplayArea = display.getDefaultTaskDisplayArea(); 1908 1909 try { 1910 mAtm.mSupportsMultiDisplay = false; 1911 assertEquals(RESULT_CONTINUE, new CalculateRequestBuilder().calculate()); 1912 assertEquals(mRootWindowContainer.getDefaultTaskDisplayArea(), 1913 mResult.mPreferredTaskDisplayArea); 1914 } finally { 1915 mAtm.mSupportsMultiDisplay = orgValue; 1916 } 1917 } 1918 createNewDisplayContent(int windowingMode)1919 private TestDisplayContent createNewDisplayContent(int windowingMode) { 1920 return createNewDisplayContent(windowingMode, DISPLAY_BOUNDS, DISPLAY_STABLE_BOUNDS); 1921 } 1922 createNewDisplayContent(int windowingMode, Rect displayBounds, Rect displayStableBounds)1923 private TestDisplayContent createNewDisplayContent(int windowingMode, Rect displayBounds, 1924 Rect displayStableBounds) { 1925 final TestDisplayContent display = addNewDisplayContentAt(DisplayContent.POSITION_TOP); 1926 display.getDefaultTaskDisplayArea().setWindowingMode(windowingMode); 1927 display.setBounds(displayBounds); 1928 display.getConfiguration().densityDpi = DENSITY_DEFAULT; 1929 display.getConfiguration().orientation = ORIENTATION_LANDSCAPE; 1930 configInsetsState(display.getInsetsStateController().getRawInsetsState(), display, 1931 displayStableBounds); 1932 return display; 1933 } 1934 1935 /** 1936 * Creates insets sources so that we can get the expected stable frame. 1937 */ configInsetsState(InsetsState state, DisplayContent display, Rect stableFrame)1938 private static void configInsetsState(InsetsState state, DisplayContent display, 1939 Rect stableFrame) { 1940 final Rect displayFrame = display.getBounds(); 1941 final int dl = displayFrame.left; 1942 final int dt = displayFrame.top; 1943 final int dr = displayFrame.right; 1944 final int db = displayFrame.bottom; 1945 final int sl = stableFrame.left; 1946 final int st = stableFrame.top; 1947 final int sr = stableFrame.right; 1948 final int sb = stableFrame.bottom; 1949 final @WindowInsets.Type.InsetsType int statusBarType = WindowInsets.Type.statusBars(); 1950 final @WindowInsets.Type.InsetsType int navBarType = WindowInsets.Type.navigationBars(); 1951 1952 state.setDisplayFrame(displayFrame); 1953 if (sl > dl) { 1954 state.getOrCreateSource(InsetsSource.createId(null, 0, statusBarType), statusBarType) 1955 .setFrame(dl, dt, sl, db); 1956 } 1957 if (st > dt) { 1958 state.getOrCreateSource(InsetsSource.createId(null, 1, statusBarType), statusBarType) 1959 .setFrame(dl, dt, dr, st); 1960 } 1961 if (sr < dr) { 1962 state.getOrCreateSource(InsetsSource.createId(null, 0, navBarType), navBarType) 1963 .setFrame(sr, dt, dr, db); 1964 } 1965 if (sb < db) { 1966 state.getOrCreateSource(InsetsSource.createId(null, 1, navBarType), navBarType) 1967 .setFrame(dl, sb, dr, db); 1968 } 1969 // Recompute config and push to children. 1970 display.onRequestedOverrideConfigurationChanged(display.getConfiguration()); 1971 } 1972 createSourceActivity(TestDisplayContent display)1973 private ActivityRecord createSourceActivity(TestDisplayContent display) { 1974 final Task rootTask = display.getDefaultTaskDisplayArea() 1975 .createRootTask(display.getWindowingMode(), ACTIVITY_TYPE_STANDARD, true); 1976 return new ActivityBuilder(mAtm).setTask(rootTask).build(); 1977 } 1978 createSourceActivity(TaskDisplayArea taskDisplayArea, int windowingMode)1979 private ActivityRecord createSourceActivity(TaskDisplayArea taskDisplayArea, 1980 int windowingMode) { 1981 final Task rootTask = taskDisplayArea.createRootTask(windowingMode, ACTIVITY_TYPE_STANDARD, 1982 true); 1983 return new ActivityBuilder(mAtm).setTask(rootTask).build(); 1984 } 1985 addFreeformTaskTo(TestDisplayContent display, Rect bounds)1986 private void addFreeformTaskTo(TestDisplayContent display, Rect bounds) { 1987 final Task rootTask = display.getDefaultTaskDisplayArea() 1988 .createRootTask(display.getWindowingMode(), ACTIVITY_TYPE_STANDARD, true); 1989 rootTask.setWindowingMode(WINDOWING_MODE_FREEFORM); 1990 final Task task = new TaskBuilder(mSupervisor).setParentTask(rootTask).build(); 1991 // Just work around the unnecessary adjustments for bounds. 1992 task.getWindowConfiguration().setBounds(bounds); 1993 } 1994 assertEquivalentWindowingMode(int expected, int actual, int parentWindowingMode)1995 private void assertEquivalentWindowingMode(int expected, int actual, int parentWindowingMode) { 1996 if (expected != parentWindowingMode) { 1997 assertEquals(expected, actual); 1998 } else { 1999 assertEquals(WINDOWING_MODE_UNDEFINED, actual); 2000 } 2001 } 2002 orientationFromBounds(Rect bounds)2003 private int orientationFromBounds(Rect bounds) { 2004 return bounds.width() > bounds.height() ? SCREEN_ORIENTATION_LANDSCAPE 2005 : SCREEN_ORIENTATION_PORTRAIT; 2006 } 2007 2008 private class CalculateRequestBuilder { 2009 private Task mTask; 2010 private ActivityInfo.WindowLayout mLayout; 2011 private ActivityRecord mActivity = TaskLaunchParamsModifierTests.this.mActivity; 2012 private ActivityRecord mSource; 2013 private ActivityOptions mOptions; 2014 private Request mRequest; 2015 private int mPhase = PHASE_BOUNDS; 2016 private LaunchParams mCurrentParams = mCurrent; 2017 private LaunchParams mOutParams = mResult; 2018 setTask(Task task)2019 private CalculateRequestBuilder setTask(Task task) { 2020 mTask = task; 2021 return this; 2022 } 2023 setLayout(ActivityInfo.WindowLayout layout)2024 private CalculateRequestBuilder setLayout(ActivityInfo.WindowLayout layout) { 2025 mLayout = layout; 2026 return this; 2027 } 2028 setActivity(ActivityRecord activity)2029 private CalculateRequestBuilder setActivity(ActivityRecord activity) { 2030 mActivity = activity; 2031 return this; 2032 } 2033 setSource(ActivityRecord source)2034 private CalculateRequestBuilder setSource(ActivityRecord source) { 2035 mSource = source; 2036 return this; 2037 } 2038 setOptions(ActivityOptions options)2039 private CalculateRequestBuilder setOptions(ActivityOptions options) { 2040 mOptions = options; 2041 return this; 2042 } 2043 setRequest(Request request)2044 private CalculateRequestBuilder setRequest(Request request) { 2045 mRequest = request; 2046 return this; 2047 } 2048 calculate()2049 private @Result int calculate() { 2050 return mTarget.onCalculate(mTask, mLayout, mActivity, mSource, mOptions, mRequest, 2051 mPhase, mCurrentParams, mOutParams); 2052 } 2053 } 2054 2055 private static class WindowLayoutBuilder { 2056 private int mWidth = -1; 2057 private int mHeight = -1; 2058 private float mWidthFraction = -1f; 2059 private float mHeightFraction = -1f; 2060 private int mGravity = Gravity.NO_GRAVITY; 2061 private int mMinWidth = -1; 2062 private int mMinHeight = -1; 2063 setWidth(int width)2064 private WindowLayoutBuilder setWidth(int width) { 2065 mWidth = width; 2066 return this; 2067 } 2068 setHeight(int height)2069 private WindowLayoutBuilder setHeight(int height) { 2070 mHeight = height; 2071 return this; 2072 } 2073 setWidthFraction(float widthFraction)2074 private WindowLayoutBuilder setWidthFraction(float widthFraction) { 2075 mWidthFraction = widthFraction; 2076 return this; 2077 } 2078 setHeightFraction(float heightFraction)2079 private WindowLayoutBuilder setHeightFraction(float heightFraction) { 2080 mHeightFraction = heightFraction; 2081 return this; 2082 } 2083 setGravity(int gravity)2084 private WindowLayoutBuilder setGravity(int gravity) { 2085 mGravity = gravity; 2086 return this; 2087 } 2088 setMinWidth(int minWidth)2089 private WindowLayoutBuilder setMinWidth(int minWidth) { 2090 mMinWidth = minWidth; 2091 return this; 2092 } 2093 setMinHeight(int minHeight)2094 private WindowLayoutBuilder setMinHeight(int minHeight) { 2095 mMinHeight = minHeight; 2096 return this; 2097 } 2098 build()2099 private ActivityInfo.WindowLayout build() { 2100 return new ActivityInfo.WindowLayout(mWidth, mWidthFraction, mHeight, mHeightFraction, 2101 mGravity, mMinWidth, mMinHeight); 2102 } 2103 } 2104 } 2105