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.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT; 20 import static android.app.WindowConfiguration.ACTIVITY_TYPE_DREAM; 21 import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; 22 import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS; 23 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; 24 import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; 25 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; 26 import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW; 27 import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; 28 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; 29 import static android.content.Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT; 30 import static android.content.pm.ActivityInfo.FLAG_ALWAYS_FOCUSABLE; 31 import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE; 32 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LOCKED; 33 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_NOSENSOR; 34 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; 35 import static android.window.DisplayAreaOrganizer.FEATURE_VENDOR_FIRST; 36 37 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; 38 import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; 39 import static com.android.server.wm.ActivityRecord.State.RESUMED; 40 import static com.android.server.wm.ActivityTaskSupervisor.ON_TOP; 41 import static com.android.server.wm.WindowContainer.POSITION_TOP; 42 43 import static com.google.common.truth.Truth.assertThat; 44 45 import static org.junit.Assert.assertEquals; 46 import static org.junit.Assert.assertFalse; 47 import static org.junit.Assert.assertNotNull; 48 import static org.junit.Assert.assertNull; 49 import static org.junit.Assert.assertSame; 50 import static org.junit.Assert.assertTrue; 51 import static org.mockito.ArgumentMatchers.anyInt; 52 import static org.mockito.ArgumentMatchers.eq; 53 import static org.mockito.Mockito.never; 54 import static org.mockito.Mockito.verify; 55 56 import android.app.ActivityOptions; 57 import android.platform.test.annotations.Presubmit; 58 59 import androidx.test.filters.SmallTest; 60 61 import com.android.server.wm.LaunchParamsController.LaunchParams; 62 63 import org.junit.Test; 64 import org.junit.runner.RunWith; 65 66 import java.util.List; 67 68 /** 69 * Tests for the {@link TaskDisplayArea} container. 70 * 71 * Build/Install/Run: 72 * atest WmTests:TaskDisplayAreaTests 73 */ 74 @SmallTest 75 @Presubmit 76 @RunWith(WindowTestRunner.class) 77 public class TaskDisplayAreaTests extends WindowTestsBase { 78 79 @Test getLaunchRootTask_checksLaunchAdjacentFlagRoot()80 public void getLaunchRootTask_checksLaunchAdjacentFlagRoot() { 81 final Task rootTask = createTask( 82 mDisplayContent, WINDOWING_MODE_MULTI_WINDOW, ACTIVITY_TYPE_STANDARD); 83 rootTask.mCreatedByOrganizer = true; 84 final Task adjacentRootTask = createTask( 85 mDisplayContent, WINDOWING_MODE_MULTI_WINDOW, ACTIVITY_TYPE_STANDARD); 86 adjacentRootTask.mCreatedByOrganizer = true; 87 final TaskDisplayArea taskDisplayArea = rootTask.getDisplayArea(); 88 adjacentRootTask.setAdjacentTaskFragment(rootTask); 89 90 taskDisplayArea.setLaunchAdjacentFlagRootTask(adjacentRootTask); 91 Task actualRootTask = taskDisplayArea.getLaunchRootTask( 92 WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD, null /* options */, 93 null /* sourceTask */, FLAG_ACTIVITY_LAUNCH_ADJACENT); 94 assertSame(adjacentRootTask, actualRootTask.getRootTask()); 95 96 taskDisplayArea.setLaunchAdjacentFlagRootTask(null); 97 actualRootTask = taskDisplayArea.getLaunchRootTask(WINDOWING_MODE_UNDEFINED, 98 ACTIVITY_TYPE_STANDARD, null /* options */, null /* sourceTask */, 99 FLAG_ACTIVITY_LAUNCH_ADJACENT); 100 assertNull(actualRootTask); 101 } 102 103 @Test getLaunchRootTask_checksFocusedRootTask()104 public void getLaunchRootTask_checksFocusedRootTask() { 105 final TaskDisplayArea taskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea(); 106 final Task rootTask = createTaskWithActivity( 107 taskDisplayArea, 108 WINDOWING_MODE_MULTI_WINDOW, ACTIVITY_TYPE_STANDARD, ON_TOP, true); 109 rootTask.mCreatedByOrganizer = true; 110 111 final Task adjacentRootTask = createTask( 112 mDisplayContent, WINDOWING_MODE_MULTI_WINDOW, ACTIVITY_TYPE_STANDARD); 113 adjacentRootTask.mCreatedByOrganizer = true; 114 adjacentRootTask.setAdjacentTaskFragment(rootTask); 115 116 taskDisplayArea.setLaunchRootTask(rootTask, 117 new int[]{WINDOWING_MODE_MULTI_WINDOW}, new int[]{ACTIVITY_TYPE_STANDARD}); 118 119 Task actualRootTask = taskDisplayArea.getLaunchRootTask( 120 WINDOWING_MODE_MULTI_WINDOW, ACTIVITY_TYPE_STANDARD, null /* options */, 121 null /* sourceTask */, 0 /*launchFlags*/); 122 assertTrue(actualRootTask.isFocusedRootTaskOnDisplay()); 123 } 124 125 @Test getLaunchRootTask_fromLaunchAdjacentFlagRoot_checksAdjacentRoot()126 public void getLaunchRootTask_fromLaunchAdjacentFlagRoot_checksAdjacentRoot() { 127 final ActivityRecord activity = createNonAttachedActivityRecord(mDisplayContent); 128 final Task rootTask = createTask( 129 mDisplayContent, WINDOWING_MODE_MULTI_WINDOW, ACTIVITY_TYPE_STANDARD); 130 rootTask.mCreatedByOrganizer = true; 131 final Task adjacentRootTask = createTask( 132 mDisplayContent, WINDOWING_MODE_MULTI_WINDOW, ACTIVITY_TYPE_STANDARD); 133 adjacentRootTask.mCreatedByOrganizer = true; 134 final TaskDisplayArea taskDisplayArea = rootTask.getDisplayArea(); 135 adjacentRootTask.setAdjacentTaskFragment(rootTask); 136 137 taskDisplayArea.setLaunchAdjacentFlagRootTask(adjacentRootTask); 138 final Task actualRootTask = taskDisplayArea.getLaunchRootTask( 139 WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD, null /* options */, 140 adjacentRootTask /* sourceTask */, FLAG_ACTIVITY_LAUNCH_ADJACENT); 141 142 assertSame(rootTask, actualRootTask.getRootTask()); 143 } 144 145 @Test getOrCreateLaunchRootRespectsResolvedWindowingMode()146 public void getOrCreateLaunchRootRespectsResolvedWindowingMode() { 147 final Task rootTask = createTask( 148 mDisplayContent, WINDOWING_MODE_MULTI_WINDOW, ACTIVITY_TYPE_STANDARD); 149 rootTask.mCreatedByOrganizer = true; 150 final TaskDisplayArea taskDisplayArea = rootTask.getDisplayArea(); 151 taskDisplayArea.setLaunchRootTask( 152 rootTask, new int[]{WINDOWING_MODE_FREEFORM}, new int[]{ACTIVITY_TYPE_STANDARD}); 153 154 final Task candidateRootTask = createTask( 155 mDisplayContent, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD); 156 final ActivityRecord activity = createNonAttachedActivityRecord(mDisplayContent); 157 final LaunchParams launchParams = new LaunchParams(); 158 launchParams.mWindowingMode = WINDOWING_MODE_FREEFORM; 159 160 final Task actualRootTask = taskDisplayArea.getOrCreateRootTask( 161 activity, null /* options */, candidateRootTask, null /* sourceTask */, 162 launchParams, 0 /* launchFlags */, ACTIVITY_TYPE_STANDARD, true /* onTop */); 163 assertSame(rootTask, actualRootTask.getRootTask()); 164 } 165 166 @Test getOrCreateLaunchRootUsesActivityOptionsWindowingMode()167 public void getOrCreateLaunchRootUsesActivityOptionsWindowingMode() { 168 final Task rootTask = createTask( 169 mDisplayContent, WINDOWING_MODE_MULTI_WINDOW, ACTIVITY_TYPE_STANDARD); 170 rootTask.mCreatedByOrganizer = true; 171 final TaskDisplayArea taskDisplayArea = rootTask.getDisplayArea(); 172 taskDisplayArea.setLaunchRootTask( 173 rootTask, new int[]{WINDOWING_MODE_FREEFORM}, new int[]{ACTIVITY_TYPE_STANDARD}); 174 175 final Task candidateRootTask = createTask( 176 mDisplayContent, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD); 177 final ActivityRecord activity = createNonAttachedActivityRecord(mDisplayContent); 178 final ActivityOptions options = ActivityOptions.makeBasic(); 179 options.setLaunchWindowingMode(WINDOWING_MODE_FREEFORM); 180 181 final Task actualRootTask = taskDisplayArea.getOrCreateRootTask( 182 activity, options, candidateRootTask, null /* sourceTask */, 183 null /* launchParams */, 0 /* launchFlags */, ACTIVITY_TYPE_STANDARD, 184 true /* onTop */); 185 assertSame(rootTask, actualRootTask.getRootTask()); 186 } 187 188 @Test testActivityWithZBoost_taskDisplayAreaDoesNotMoveUp()189 public void testActivityWithZBoost_taskDisplayAreaDoesNotMoveUp() { 190 final Task rootTask = createTask(mDisplayContent); 191 final Task task = createTaskInRootTask(rootTask, 0 /* userId */); 192 final ActivityRecord activity = createNonAttachedActivityRecord(mDisplayContent); 193 task.addChild(activity, 0 /* addPos */); 194 final TaskDisplayArea taskDisplayArea = activity.getDisplayArea(); 195 activity.mNeedsAnimationBoundsLayer = true; 196 activity.mNeedsZBoost = true; 197 spyOn(taskDisplayArea.mSurfaceAnimator); 198 199 mDisplayContent.assignChildLayers(mTransaction); 200 201 assertThat(activity.needsZBoost()).isTrue(); 202 assertThat(taskDisplayArea.needsZBoost()).isFalse(); 203 verify(taskDisplayArea.mSurfaceAnimator, never()).setLayer(eq(mTransaction), anyInt()); 204 } 205 206 @Test testRootTaskPositionChildAt()207 public void testRootTaskPositionChildAt() { 208 Task pinnedTask = createTask( 209 mDisplayContent, WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD); 210 // Root task should contain visible app window to be considered visible. 211 assertFalse(pinnedTask.isVisible()); 212 final ActivityRecord pinnedApp = createNonAttachedActivityRecord(mDisplayContent); 213 pinnedTask.addChild(pinnedApp, 0 /* addPos */); 214 assertTrue(pinnedTask.isVisible()); 215 216 // Test that always-on-top root task can't be moved to position other than top. 217 final Task rootTask1 = createTask(mDisplayContent); 218 final Task rootTask2 = createTask(mDisplayContent); 219 220 final WindowContainer taskContainer = rootTask1.getParent(); 221 222 final int rootTask1Pos = taskContainer.mChildren.indexOf(rootTask1); 223 final int rootTask2Pos = taskContainer.mChildren.indexOf(rootTask2); 224 final int pinnedTaskPos = taskContainer.mChildren.indexOf(pinnedTask); 225 assertThat(pinnedTaskPos).isGreaterThan(rootTask2Pos); 226 assertThat(rootTask2Pos).isGreaterThan(rootTask1Pos); 227 228 taskContainer.positionChildAt(WindowContainer.POSITION_BOTTOM, pinnedTask, false); 229 assertEquals(taskContainer.mChildren.get(rootTask1Pos), rootTask1); 230 assertEquals(taskContainer.mChildren.get(rootTask2Pos), rootTask2); 231 assertEquals(taskContainer.mChildren.get(pinnedTaskPos), pinnedTask); 232 233 taskContainer.positionChildAt(1, pinnedTask, false); 234 assertEquals(taskContainer.mChildren.get(rootTask1Pos), rootTask1); 235 assertEquals(taskContainer.mChildren.get(rootTask2Pos), rootTask2); 236 assertEquals(taskContainer.mChildren.get(pinnedTaskPos), pinnedTask); 237 } 238 239 @Test testRootTaskPositionBelowPinnedRootTask()240 public void testRootTaskPositionBelowPinnedRootTask() { 241 Task pinnedTask = createTask( 242 mDisplayContent, WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD); 243 // Root task should contain visible app window to be considered visible. 244 assertFalse(pinnedTask.isVisible()); 245 final ActivityRecord pinnedApp = createNonAttachedActivityRecord(mDisplayContent); 246 pinnedTask.addChild(pinnedApp, 0 /* addPos */); 247 assertTrue(pinnedTask.isVisible()); 248 249 // Test that no root task can be above pinned root task. 250 final Task rootTask1 = createTask(mDisplayContent); 251 252 final WindowContainer taskContainer = rootTask1.getParent(); 253 254 final int rootTaskPos = taskContainer.mChildren.indexOf(rootTask1); 255 final int pinnedTaskPos = taskContainer.mChildren.indexOf(pinnedTask); 256 assertThat(pinnedTaskPos).isGreaterThan(rootTaskPos); 257 258 taskContainer.positionChildAt(WindowContainer.POSITION_TOP, rootTask1, false); 259 assertEquals(taskContainer.mChildren.get(rootTaskPos), rootTask1); 260 assertEquals(taskContainer.mChildren.get(pinnedTaskPos), pinnedTask); 261 262 taskContainer.positionChildAt(taskContainer.mChildren.size() - 1, rootTask1, false); 263 assertEquals(taskContainer.mChildren.get(rootTaskPos), rootTask1); 264 assertEquals(taskContainer.mChildren.get(pinnedTaskPos), pinnedTask); 265 } 266 267 @Test testDisplayPositionWithPinnedRootTask()268 public void testDisplayPositionWithPinnedRootTask() { 269 // Make sure the display is trusted display which capable to move the root task to top. 270 spyOn(mDisplayContent); 271 doReturn(true).when(mDisplayContent).isTrusted(); 272 273 // Allow child root task to move to top. 274 mDisplayContent.mDontMoveToTop = false; 275 276 // The display contains pinned root task that was added in {@link #setUp}. 277 final Task rootTask = createTask(mDisplayContent); 278 final Task task = createTaskInRootTask(rootTask, 0 /* userId */); 279 280 // Add another display at top. 281 mWm.mRoot.positionChildAt(WindowContainer.POSITION_TOP, createNewDisplay(), 282 false /* includingParents */); 283 284 // Move the task of {@code mDisplayContent} to top. 285 rootTask.positionChildAt(WindowContainer.POSITION_TOP, task, true /* includingParents */); 286 final int indexOfDisplayWithPinnedRootTask = mWm.mRoot.mChildren.indexOf(mDisplayContent); 287 288 assertEquals("The testing DisplayContent should be moved to top with task", 289 mWm.mRoot.getChildCount() - 1, indexOfDisplayWithPinnedRootTask); 290 } 291 292 @Test testMovingChildTaskOnTop()293 public void testMovingChildTaskOnTop() { 294 // Make sure the display is trusted display which capable to move the root task to top. 295 spyOn(mDisplayContent); 296 doReturn(true).when(mDisplayContent).isTrusted(); 297 298 // Allow child root task to move to top. 299 mDisplayContent.mDontMoveToTop = false; 300 301 // The display contains pinned root task that was added in {@link #setUp}. 302 Task rootTask = createTask(mDisplayContent); 303 Task task = createTaskInRootTask(rootTask, 0 /* userId */); 304 305 // Add another display at top. 306 mWm.mRoot.positionChildAt(WindowContainer.POSITION_TOP, createNewDisplay(), 307 false /* includingParents */); 308 309 // Ensure that original display ({@code mDisplayContent}) is not on top. 310 assertEquals("Testing DisplayContent should not be on the top", 311 mWm.mRoot.getChildCount() - 2, mWm.mRoot.mChildren.indexOf(mDisplayContent)); 312 313 // Move the task of {@code mDisplayContent} to top. 314 rootTask.positionChildAt(WindowContainer.POSITION_TOP, task, true /* includingParents */); 315 316 // Ensure that original display ({@code mDisplayContent}) is now on the top. 317 assertEquals("The testing DisplayContent should be moved to top with task", 318 mWm.mRoot.getChildCount() - 1, mWm.mRoot.mChildren.indexOf(mDisplayContent)); 319 } 320 321 @Test testDontMovingChildTaskOnTop()322 public void testDontMovingChildTaskOnTop() { 323 // Make sure the display is trusted display which capable to move the root task to top. 324 spyOn(mDisplayContent); 325 doReturn(true).when(mDisplayContent).isTrusted(); 326 327 // Allow child root task to move to top. 328 mDisplayContent.mDontMoveToTop = true; 329 330 // The display contains pinned root task that was added in {@link #setUp}. 331 Task rootTask = createTask(mDisplayContent); 332 Task task = createTaskInRootTask(rootTask, 0 /* userId */); 333 334 // Add another display at top. 335 mWm.mRoot.positionChildAt(WindowContainer.POSITION_TOP, createNewDisplay(), 336 false /* includingParents */); 337 338 // Ensure that original display ({@code mDisplayContent}) is not on top. 339 assertEquals("Testing DisplayContent should not be on the top", 340 mWm.mRoot.getChildCount() - 2, mWm.mRoot.mChildren.indexOf(mDisplayContent)); 341 342 // Try moving the task of {@code mDisplayContent} to top. 343 rootTask.positionChildAt(WindowContainer.POSITION_TOP, task, true /* includingParents */); 344 345 // Ensure that original display ({@code mDisplayContent}) hasn't moved and is not 346 // on the top. 347 assertEquals("The testing DisplayContent should not be moved to top with task", 348 mWm.mRoot.getChildCount() - 2, mWm.mRoot.mChildren.indexOf(mDisplayContent)); 349 } 350 351 @Test testReuseTaskAsRootTask()352 public void testReuseTaskAsRootTask() { 353 final Task candidateTask = createTask(mDisplayContent); 354 List<Integer> activityTypesWithReusableRootTask = List.of(ACTIVITY_TYPE_STANDARD, 355 ACTIVITY_TYPE_RECENTS); 356 for (Integer type : activityTypesWithReusableRootTask) { 357 assertGetOrCreateRootTask(WINDOWING_MODE_FULLSCREEN, type, candidateTask, 358 true /* reuseCandidate */); 359 assertGetOrCreateRootTask(WINDOWING_MODE_UNDEFINED, type, candidateTask, 360 true /* reuseCandidate */); 361 assertGetOrCreateRootTask(WINDOWING_MODE_FREEFORM, type, candidateTask, 362 true /* reuseCandidate */); 363 assertGetOrCreateRootTask(WINDOWING_MODE_MULTI_WINDOW, type, candidateTask, 364 true /* reuseCandidate */); 365 assertGetOrCreateRootTask(WINDOWING_MODE_PINNED, type, candidateTask, 366 true /* reuseCandidate */); 367 } 368 369 final int windowingMode = WINDOWING_MODE_FULLSCREEN; 370 assertGetOrCreateRootTask(windowingMode, ACTIVITY_TYPE_HOME, candidateTask, 371 false /* reuseCandidate */); 372 assertGetOrCreateRootTask(windowingMode, ACTIVITY_TYPE_ASSISTANT, candidateTask, 373 false /* reuseCandidate */); 374 assertGetOrCreateRootTask(windowingMode, ACTIVITY_TYPE_DREAM, candidateTask, 375 false /* reuseCandidate */); 376 } 377 378 @Test testGetOrientation_nonResizableHomeTaskWithHomeActivityPendingVisibilityChange()379 public void testGetOrientation_nonResizableHomeTaskWithHomeActivityPendingVisibilityChange() { 380 final RootWindowContainer rootWindowContainer = mWm.mAtmService.mRootWindowContainer; 381 final TaskDisplayArea defaultTaskDisplayArea = 382 rootWindowContainer.getDefaultTaskDisplayArea(); 383 384 final Task rootHomeTask = defaultTaskDisplayArea.getRootHomeTask(); 385 rootHomeTask.mResizeMode = RESIZE_MODE_UNRESIZEABLE; 386 387 final Task primarySplitTask = new TaskBuilder(mSupervisor) 388 .setTaskDisplayArea(defaultTaskDisplayArea) 389 .setWindowingMode(WINDOWING_MODE_MULTI_WINDOW) 390 .setActivityType(ACTIVITY_TYPE_STANDARD) 391 .setOnTop(true) 392 .setCreateActivity(true) 393 .build(); 394 ActivityRecord primarySplitActivity = primarySplitTask.getTopNonFinishingActivity(); 395 assertNotNull(primarySplitActivity); 396 primarySplitActivity.setState(RESUMED, 397 "testGetOrientation_nonResizableHomeTaskWithHomeActivityPendingVisibilityChange"); 398 399 ActivityRecord homeActivity = rootHomeTask.getTopNonFinishingActivity(); 400 if (homeActivity == null) { 401 homeActivity = new ActivityBuilder(mWm.mAtmService) 402 .setParentTask(rootHomeTask).setCreateTask(true).build(); 403 } 404 homeActivity.setVisible(false); 405 homeActivity.setVisibleRequested(true); 406 assertFalse(rootHomeTask.isVisible()); 407 408 assertEquals(defaultTaskDisplayArea.getOrientation(), rootHomeTask.getOrientation()); 409 } 410 411 @Test testIsLastFocused()412 public void testIsLastFocused() { 413 final TaskDisplayArea firstTaskDisplayArea = mDisplayContent.getDefaultTaskDisplayArea(); 414 final TaskDisplayArea secondTaskDisplayArea = createTaskDisplayArea( 415 mDisplayContent, mRootWindowContainer.mWmService, "TestTaskDisplayArea", 416 FEATURE_VENDOR_FIRST); 417 final Task firstRootTask = firstTaskDisplayArea.createRootTask( 418 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */); 419 final Task secondRootTask = secondTaskDisplayArea.createRootTask( 420 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */); 421 final ActivityRecord firstActivity = new ActivityBuilder(mAtm) 422 .setTask(firstRootTask).build(); 423 final ActivityRecord secondActivity = new ActivityBuilder(mAtm) 424 .setTask(secondRootTask).build(); 425 426 // Activity on TDA1 is focused 427 mDisplayContent.setFocusedApp(firstActivity); 428 429 final int testOrientation = SCREEN_ORIENTATION_PORTRAIT; 430 431 assertThat(firstTaskDisplayArea.canSpecifyOrientation(testOrientation)).isTrue(); 432 assertThat(secondTaskDisplayArea.canSpecifyOrientation(testOrientation)).isFalse(); 433 434 // No focused app, TDA1 is still recorded as last focused. 435 mDisplayContent.setFocusedApp(null); 436 437 assertThat(firstTaskDisplayArea.canSpecifyOrientation(testOrientation)).isTrue(); 438 assertThat(secondTaskDisplayArea.canSpecifyOrientation(testOrientation)).isFalse(); 439 440 // Activity on TDA2 is focused 441 mDisplayContent.setFocusedApp(secondActivity); 442 443 assertThat(firstTaskDisplayArea.canSpecifyOrientation(testOrientation)).isFalse(); 444 assertThat(secondTaskDisplayArea.canSpecifyOrientation(testOrientation)).isTrue(); 445 } 446 447 @Test testCanSpecifyOrientation()448 public void testCanSpecifyOrientation() { 449 final TaskDisplayArea firstTaskDisplayArea = mDisplayContent.getDefaultTaskDisplayArea(); 450 final TaskDisplayArea secondTaskDisplayArea = createTaskDisplayArea( 451 mDisplayContent, mRootWindowContainer.mWmService, "TestTaskDisplayArea", 452 FEATURE_VENDOR_FIRST); 453 final Task firstRootTask = firstTaskDisplayArea.createRootTask( 454 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */); 455 final Task secondRootTask = secondTaskDisplayArea.createRootTask( 456 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */); 457 final ActivityRecord firstActivity = new ActivityBuilder(mAtm) 458 .setTask(firstRootTask).build(); 459 final ActivityRecord secondActivity = new ActivityBuilder(mAtm) 460 .setTask(secondRootTask).build(); 461 firstTaskDisplayArea.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */); 462 secondTaskDisplayArea.setIgnoreOrientationRequest(false /* ignoreOrientationRequest */); 463 464 final int testOrientation = SCREEN_ORIENTATION_PORTRAIT; 465 466 // Activity on TDA1 is focused, but TDA1 cannot specify orientation because 467 // ignoreOrientationRequest is true 468 // Activity on TDA2 has ignoreOrientationRequest false but it doesn't have focus so it 469 // cannot specify orientation 470 mDisplayContent.setFocusedApp(firstActivity); 471 472 assertThat(firstTaskDisplayArea.canSpecifyOrientation(testOrientation)).isFalse(); 473 assertThat(secondTaskDisplayArea.canSpecifyOrientation(testOrientation)).isFalse(); 474 475 // Activity on TDA1 is not focused, and so it cannot specify orientation 476 // Activity on TDA2 is focused, and it can specify orientation because 477 // ignoreOrientationRequest is false 478 mDisplayContent.setFocusedApp(secondActivity); 479 480 assertThat(firstTaskDisplayArea.canSpecifyOrientation(testOrientation)).isFalse(); 481 assertThat(secondTaskDisplayArea.canSpecifyOrientation(testOrientation)).isTrue(); 482 } 483 484 @Test testCanSpecifyOrientationNoSensor()485 public void testCanSpecifyOrientationNoSensor() { 486 final TaskDisplayArea firstTaskDisplayArea = mDisplayContent.getDefaultTaskDisplayArea(); 487 final TaskDisplayArea secondTaskDisplayArea = createTaskDisplayArea( 488 mDisplayContent, mRootWindowContainer.mWmService, "TestTaskDisplayArea", 489 FEATURE_VENDOR_FIRST); 490 final Task firstRootTask = firstTaskDisplayArea.createRootTask( 491 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */); 492 final Task secondRootTask = secondTaskDisplayArea.createRootTask( 493 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */); 494 final ActivityRecord firstActivity = new ActivityBuilder(mAtm) 495 .setTask(firstRootTask).build(); 496 final ActivityRecord secondActivity = new ActivityBuilder(mAtm) 497 .setTask(secondRootTask).build(); 498 firstTaskDisplayArea.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */); 499 secondTaskDisplayArea.setIgnoreOrientationRequest(false /* ignoreOrientationRequest */); 500 501 final int testOrientation = SCREEN_ORIENTATION_NOSENSOR; 502 503 // ignoreOrientationRequest is always false for SCREEN_ORIENTATION_NOSENSOR so 504 // only the TDAs with focus can specify orientations 505 mDisplayContent.setFocusedApp(firstActivity); 506 507 assertThat(firstTaskDisplayArea.canSpecifyOrientation(testOrientation)).isTrue(); 508 assertThat(secondTaskDisplayArea.canSpecifyOrientation(testOrientation)).isFalse(); 509 510 mDisplayContent.setFocusedApp(secondActivity); 511 512 assertThat(firstTaskDisplayArea.canSpecifyOrientation(testOrientation)).isFalse(); 513 assertThat(secondTaskDisplayArea.canSpecifyOrientation(testOrientation)).isTrue(); 514 } 515 516 @Test testCanSpecifyOrientationLocked()517 public void testCanSpecifyOrientationLocked() { 518 final TaskDisplayArea firstTaskDisplayArea = mDisplayContent.getDefaultTaskDisplayArea(); 519 final TaskDisplayArea secondTaskDisplayArea = createTaskDisplayArea( 520 mDisplayContent, mRootWindowContainer.mWmService, "TestTaskDisplayArea", 521 FEATURE_VENDOR_FIRST); 522 final Task firstRootTask = firstTaskDisplayArea.createRootTask( 523 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */); 524 final Task secondRootTask = secondTaskDisplayArea.createRootTask( 525 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */); 526 final ActivityRecord firstActivity = new ActivityBuilder(mAtm) 527 .setTask(firstRootTask).build(); 528 final ActivityRecord secondActivity = new ActivityBuilder(mAtm) 529 .setTask(secondRootTask).build(); 530 firstTaskDisplayArea.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */); 531 secondTaskDisplayArea.setIgnoreOrientationRequest(false /* ignoreOrientationRequest */); 532 533 final int testOrientation = SCREEN_ORIENTATION_LOCKED; 534 535 // ignoreOrientationRequest is always false for SCREEN_ORIENTATION_NOSENSOR so 536 // only the TDAs with focus can specify orientations 537 mDisplayContent.setFocusedApp(firstActivity); 538 539 assertThat(firstTaskDisplayArea.canSpecifyOrientation(testOrientation)).isTrue(); 540 assertThat(secondTaskDisplayArea.canSpecifyOrientation(testOrientation)).isFalse(); 541 542 mDisplayContent.setFocusedApp(secondActivity); 543 544 assertThat(firstTaskDisplayArea.canSpecifyOrientation(testOrientation)).isFalse(); 545 assertThat(secondTaskDisplayArea.canSpecifyOrientation(testOrientation)).isTrue(); 546 } 547 548 @Test 549 @UseTestDisplay testRemove_reparentToDefault()550 public void testRemove_reparentToDefault() { 551 final Task task = createTask(mDisplayContent); 552 final TaskDisplayArea displayArea = task.getDisplayArea(); 553 displayArea.remove(); 554 assertTrue(displayArea.isRemoved()); 555 assertFalse(displayArea.hasChild()); 556 557 final RootWindowContainer rootWindowContainer = mWm.mAtmService.mRootWindowContainer; 558 final TaskDisplayArea defaultTaskDisplayArea = 559 rootWindowContainer.getDefaultTaskDisplayArea(); 560 assertTrue(defaultTaskDisplayArea.mChildren.contains(task)); 561 } 562 563 @Test 564 @UseTestDisplay testRemove_rootTaskCreatedByOrganizer()565 public void testRemove_rootTaskCreatedByOrganizer() { 566 final Task task = createTask(mDisplayContent); 567 task.mCreatedByOrganizer = true; 568 final TaskDisplayArea displayArea = task.getDisplayArea(); 569 displayArea.remove(); 570 assertTrue(displayArea.isRemoved()); 571 assertFalse(displayArea.hasChild()); 572 573 final RootWindowContainer rootWindowContainer = mWm.mAtmService.mRootWindowContainer; 574 final TaskDisplayArea defaultTaskDisplayArea = 575 rootWindowContainer.getDefaultTaskDisplayArea(); 576 assertFalse(defaultTaskDisplayArea.mChildren.contains(task)); 577 } 578 assertGetOrCreateRootTask(int windowingMode, int activityType, Task candidateTask, boolean reuseCandidate)579 private void assertGetOrCreateRootTask(int windowingMode, int activityType, Task candidateTask, 580 boolean reuseCandidate) { 581 final TaskDisplayArea taskDisplayArea = candidateTask.getDisplayArea(); 582 final Task rootTask = taskDisplayArea.getOrCreateRootTask(windowingMode, activityType, 583 false /* onTop */, candidateTask /* candidateTask */, null /* sourceTask */, 584 null /* activityOptions */, 0 /* launchFlags */); 585 assertEquals(reuseCandidate, rootTask == candidateTask); 586 } 587 588 @Test testGetOrCreateRootHomeTask_defaultDisplay()589 public void testGetOrCreateRootHomeTask_defaultDisplay() { 590 TaskDisplayArea defaultTaskDisplayArea = mWm.mRoot.getDefaultTaskDisplayArea(); 591 592 // Remove the current home root task if it exists so a new one can be created below. 593 Task homeTask = defaultTaskDisplayArea.getRootHomeTask(); 594 if (homeTask != null) { 595 defaultTaskDisplayArea.removeChild(homeTask); 596 } 597 assertNull(defaultTaskDisplayArea.getRootHomeTask()); 598 599 assertNotNull(defaultTaskDisplayArea.getOrCreateRootHomeTask()); 600 } 601 602 @Test testGetOrCreateRootHomeTask_supportedSecondaryDisplay()603 public void testGetOrCreateRootHomeTask_supportedSecondaryDisplay() { 604 DisplayContent display = createNewDisplay(); 605 doReturn(true).when(display).supportsSystemDecorations(); 606 607 // Remove the current home root task if it exists so a new one can be created below. 608 TaskDisplayArea taskDisplayArea = display.getDefaultTaskDisplayArea(); 609 Task homeTask = taskDisplayArea.getRootHomeTask(); 610 if (homeTask != null) { 611 taskDisplayArea.removeChild(homeTask); 612 } 613 assertNull(taskDisplayArea.getRootHomeTask()); 614 615 assertNotNull(taskDisplayArea.getOrCreateRootHomeTask()); 616 } 617 618 @Test testGetOrCreateRootHomeTask_unsupportedSystemDecorations()619 public void testGetOrCreateRootHomeTask_unsupportedSystemDecorations() { 620 DisplayContent display = createNewDisplay(); 621 TaskDisplayArea taskDisplayArea = display.getDefaultTaskDisplayArea(); 622 doReturn(false).when(display).supportsSystemDecorations(); 623 624 assertNull(taskDisplayArea.getRootHomeTask()); 625 assertNull(taskDisplayArea.getOrCreateRootHomeTask()); 626 } 627 628 @Test testGetOrCreateRootHomeTask_untrustedDisplay()629 public void testGetOrCreateRootHomeTask_untrustedDisplay() { 630 DisplayContent display = createNewDisplay(); 631 TaskDisplayArea taskDisplayArea = display.getDefaultTaskDisplayArea(); 632 doReturn(false).when(display).isTrusted(); 633 634 assertNull(taskDisplayArea.getRootHomeTask()); 635 assertNull(taskDisplayArea.getOrCreateRootHomeTask()); 636 } 637 638 @Test testGetOrCreateRootHomeTask_dontMoveToTop()639 public void testGetOrCreateRootHomeTask_dontMoveToTop() { 640 DisplayContent display = createNewDisplay(); 641 display.mDontMoveToTop = true; 642 TaskDisplayArea taskDisplayArea = display.getDefaultTaskDisplayArea(); 643 644 assertNull(taskDisplayArea.getRootHomeTask()); 645 assertNull(taskDisplayArea.getOrCreateRootHomeTask()); 646 } 647 648 @Test testLastFocusedRootTaskIsUpdatedWhenMovingRootTask()649 public void testLastFocusedRootTaskIsUpdatedWhenMovingRootTask() { 650 // Create a root task at bottom. 651 final TaskDisplayArea taskDisplayAreas = 652 mRootWindowContainer.getDefaultDisplay().getDefaultTaskDisplayArea(); 653 final Task rootTask = 654 new TaskBuilder(mSupervisor).setOnTop(!ON_TOP).setCreateActivity(true).build(); 655 final Task prevFocusedRootTask = taskDisplayAreas.getFocusedRootTask(); 656 657 rootTask.moveToFront("moveRootTaskToFront"); 658 // After moving the root task to front, the previous focused should be the last focused. 659 assertTrue(rootTask.isFocusedRootTaskOnDisplay()); 660 assertEquals(prevFocusedRootTask, taskDisplayAreas.getLastFocusedRootTask()); 661 662 rootTask.moveToBack("moveRootTaskToBack", null /* task */); 663 // After moving the root task to back, the root task should be the last focused. 664 assertEquals(rootTask, taskDisplayAreas.getLastFocusedRootTask()); 665 } 666 667 /** 668 * This test simulates the picture-in-picture menu activity launches an activity to fullscreen 669 * root task. The fullscreen root task should be the top focused for resuming correctly. 670 */ 671 @Test testFullscreenRootTaskCanBeFocusedWhenFocusablePinnedRootTaskExists()672 public void testFullscreenRootTaskCanBeFocusedWhenFocusablePinnedRootTaskExists() { 673 // Create a pinned root task and move to front. 674 final Task pinnedRootTask = mRootWindowContainer.getDefaultTaskDisplayArea() 675 .createRootTask(WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, ON_TOP); 676 final Task pinnedTask = new TaskBuilder(mAtm.mTaskSupervisor) 677 .setParentTask(pinnedRootTask).build(); 678 new ActivityBuilder(mAtm).setActivityFlags(FLAG_ALWAYS_FOCUSABLE) 679 .setTask(pinnedTask).build(); 680 pinnedRootTask.moveToFront("movePinnedRootTaskToFront"); 681 682 // The focused root task should be the pinned root task. 683 assertTrue(pinnedRootTask.isFocusedRootTaskOnDisplay()); 684 685 // Create a fullscreen root task and move to front. 686 final Task fullscreenRootTask = createTaskWithActivity( 687 mRootWindowContainer.getDefaultTaskDisplayArea(), 688 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, ON_TOP, true); 689 fullscreenRootTask.moveToFront("moveFullscreenRootTaskToFront"); 690 691 // The focused root task should be the fullscreen root task. 692 assertTrue(fullscreenRootTask.isFocusedRootTaskOnDisplay()); 693 } 694 695 /** 696 * Test {@link TaskDisplayArea#mPreferredTopFocusableRootTask} will be cleared when 697 * the root task is removed or moved to back, and the focused root task will be according to 698 * z-order. 699 */ 700 @Test testRootTaskShouldNotBeFocusedAfterMovingToBackOrRemoving()701 public void testRootTaskShouldNotBeFocusedAfterMovingToBackOrRemoving() { 702 // Create a display which only contains 2 root task. 703 final DisplayContent display = addNewDisplayContentAt(POSITION_TOP); 704 final Task rootTask1 = createTaskWithActivity(display.getDefaultTaskDisplayArea(), 705 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, ON_TOP, true /* twoLevelTask */); 706 final Task rootTask2 = createTaskWithActivity(display.getDefaultTaskDisplayArea(), 707 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, ON_TOP, true /* twoLevelTask */); 708 709 // Put rootTask1 and rootTask2 on top. 710 rootTask1.moveToFront("moveRootTask1ToFront"); 711 rootTask2.moveToFront("moveRootTask2ToFront"); 712 assertTrue(rootTask2.isFocusedRootTaskOnDisplay()); 713 714 // rootTask1 should be focused after moving rootTask2 to back. 715 rootTask2.moveToBack("moveRootTask2ToBack", null /* task */); 716 assertTrue(rootTask1.isFocusedRootTaskOnDisplay()); 717 718 // rootTask2 should be focused after removing rootTask1. 719 rootTask1.getDisplayArea().removeRootTask(rootTask1); 720 assertTrue(rootTask2.isFocusedRootTaskOnDisplay()); 721 } 722 723 /** 724 * This test enforces that alwaysOnTop root task is placed at proper position. 725 */ 726 @Test testAlwaysOnTopRootTaskLocation()727 public void testAlwaysOnTopRootTaskLocation() { 728 final TaskDisplayArea taskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea(); 729 final Task alwaysOnTopRootTask = taskDisplayArea.createRootTask(WINDOWING_MODE_FREEFORM, 730 ACTIVITY_TYPE_STANDARD, true /* onTop */); 731 final ActivityRecord activity = new ActivityBuilder(mAtm) 732 .setTask(alwaysOnTopRootTask).build(); 733 alwaysOnTopRootTask.setAlwaysOnTop(true); 734 taskDisplayArea.positionChildAt(POSITION_TOP, alwaysOnTopRootTask, 735 false /* includingParents */); 736 assertTrue(alwaysOnTopRootTask.isAlwaysOnTop()); 737 assertEquals(alwaysOnTopRootTask, taskDisplayArea.getTopRootTask()); 738 739 final Task pinnedRootTask = taskDisplayArea.createRootTask( 740 WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, true /* onTop */); 741 assertEquals(pinnedRootTask, taskDisplayArea.getRootPinnedTask()); 742 assertEquals(pinnedRootTask, taskDisplayArea.getTopRootTask()); 743 744 final Task anotherAlwaysOnTopRootTask = taskDisplayArea.createRootTask( 745 WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD, true /* onTop */); 746 anotherAlwaysOnTopRootTask.setAlwaysOnTop(true); 747 taskDisplayArea.positionChildAt(POSITION_TOP, anotherAlwaysOnTopRootTask, 748 false /* includingParents */); 749 assertTrue(anotherAlwaysOnTopRootTask.isAlwaysOnTop()); 750 int topPosition = taskDisplayArea.getRootTaskCount() - 1; 751 // Ensure the new alwaysOnTop root task is put below the pinned root task, but on top of the 752 // existing alwaysOnTop root task. 753 assertEquals(topPosition - 1, getTaskIndexOf(taskDisplayArea, anotherAlwaysOnTopRootTask)); 754 755 final Task nonAlwaysOnTopRootTask = taskDisplayArea.createRootTask( 756 WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD, true /* onTop */); 757 assertEquals(taskDisplayArea, nonAlwaysOnTopRootTask.getDisplayArea()); 758 topPosition = taskDisplayArea.getRootTaskCount() - 1; 759 // Ensure the non-alwaysOnTop root task is put below the three alwaysOnTop root tasks, but 760 // above the existing other non-alwaysOnTop root tasks. 761 assertEquals(topPosition - 3, getTaskIndexOf(taskDisplayArea, nonAlwaysOnTopRootTask)); 762 763 anotherAlwaysOnTopRootTask.setAlwaysOnTop(false); 764 taskDisplayArea.positionChildAt(POSITION_TOP, anotherAlwaysOnTopRootTask, 765 false /* includingParents */); 766 assertFalse(anotherAlwaysOnTopRootTask.isAlwaysOnTop()); 767 // Ensure, when always on top is turned off for a root task, the root task is put just below 768 // all other always on top root tasks. 769 assertEquals(topPosition - 2, getTaskIndexOf(taskDisplayArea, anotherAlwaysOnTopRootTask)); 770 anotherAlwaysOnTopRootTask.setAlwaysOnTop(true); 771 772 // Ensure always on top state changes properly when windowing mode changes. 773 anotherAlwaysOnTopRootTask.setWindowingMode(WINDOWING_MODE_FULLSCREEN); 774 assertFalse(anotherAlwaysOnTopRootTask.isAlwaysOnTop()); 775 assertEquals(topPosition - 2, getTaskIndexOf(taskDisplayArea, anotherAlwaysOnTopRootTask)); 776 anotherAlwaysOnTopRootTask.setWindowingMode(WINDOWING_MODE_FREEFORM); 777 assertTrue(anotherAlwaysOnTopRootTask.isAlwaysOnTop()); 778 assertEquals(topPosition - 1, getTaskIndexOf(taskDisplayArea, anotherAlwaysOnTopRootTask)); 779 780 final Task dreamRootTask = taskDisplayArea.createRootTask( 781 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_DREAM, true /* onTop */); 782 assertEquals(taskDisplayArea, dreamRootTask.getDisplayArea()); 783 assertTrue(dreamRootTask.isAlwaysOnTop()); 784 topPosition = taskDisplayArea.getRootTaskCount() - 1; 785 // Ensure dream shows above all activities, including PiP 786 assertEquals(dreamRootTask, taskDisplayArea.getTopRootTask()); 787 assertEquals(topPosition - 1, getTaskIndexOf(taskDisplayArea, pinnedRootTask)); 788 789 final Task assistRootTask = taskDisplayArea.createRootTask( 790 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_ASSISTANT, true /* onTop */); 791 assertEquals(taskDisplayArea, assistRootTask.getDisplayArea()); 792 assertFalse(assistRootTask.isAlwaysOnTop()); 793 topPosition = taskDisplayArea.getRootTaskCount() - 1; 794 795 // Ensure Assistant shows as a non-always-on-top activity when config_assistantOnTopOfDream 796 // is false and on top of everything when true. 797 final boolean isAssistantOnTop = mContext.getResources() 798 .getBoolean(com.android.internal.R.bool.config_assistantOnTopOfDream); 799 assertEquals(isAssistantOnTop ? topPosition : topPosition - 4, 800 getTaskIndexOf(taskDisplayArea, assistRootTask)); 801 } 802 803 /** 804 * This test verifies proper launch root based on source and candidate task for split screen. 805 * If a task is launching from a created-by-organizer task, it should be launched into the 806 * same created-by-organizer task as well. Unless, the candidate task is already positioned in 807 * the split. 808 */ 809 @Test getLaunchRootTaskInSplit()810 public void getLaunchRootTaskInSplit() { 811 final Task rootTask = createTask( 812 mDisplayContent, WINDOWING_MODE_MULTI_WINDOW, ACTIVITY_TYPE_STANDARD); 813 rootTask.mCreatedByOrganizer = true; 814 final Task adjacentRootTask = createTask( 815 mDisplayContent, WINDOWING_MODE_MULTI_WINDOW, ACTIVITY_TYPE_STANDARD); 816 adjacentRootTask.mCreatedByOrganizer = true; 817 final Task candidateTask = createTaskInRootTask(rootTask, 0 /* userId*/); 818 final TaskDisplayArea taskDisplayArea = rootTask.getDisplayArea(); 819 adjacentRootTask.setAdjacentTaskFragment(rootTask); 820 821 // Verify the launch root with candidate task 822 Task actualRootTask = taskDisplayArea.getLaunchRootTask(WINDOWING_MODE_UNDEFINED, 823 ACTIVITY_TYPE_STANDARD, null /* options */, adjacentRootTask /* sourceTask */, 824 0 /* launchFlags */, candidateTask); 825 assertSame(rootTask, actualRootTask); 826 827 // Verify the launch root task without candidate task 828 actualRootTask = taskDisplayArea.getLaunchRootTask(WINDOWING_MODE_UNDEFINED, 829 ACTIVITY_TYPE_STANDARD, null /* options */, adjacentRootTask /* sourceTask */, 830 0 /* launchFlags */); 831 assertSame(adjacentRootTask, actualRootTask); 832 833 final Task pinnedTask = createTask( 834 mDisplayContent, WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD); 835 // Verify not adjusting launch target for pinned candidate task 836 actualRootTask = taskDisplayArea.getLaunchRootTask(WINDOWING_MODE_UNDEFINED, 837 ACTIVITY_TYPE_STANDARD, null /* options */, adjacentRootTask /* sourceTask */, 838 0 /* launchFlags */, pinnedTask /* candidateTask */); 839 assertNull(actualRootTask); 840 } 841 } 842