1 /* 2 * Copyright (C) 2017 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 android.server.wm; 18 19 import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT; 20 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; 21 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; 22 import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; 23 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; 24 import static android.server.wm.CliIntentExtra.extraString; 25 import static android.server.wm.ComponentNameUtils.getActivityName; 26 import static android.server.wm.UiDeviceUtils.pressHomeButton; 27 import static android.server.wm.WindowManagerState.STATE_RESUMED; 28 import static android.server.wm.app.Components.ANIMATION_TEST_ACTIVITY; 29 import static android.server.wm.app.Components.ASSISTANT_ACTIVITY; 30 import static android.server.wm.app.Components.ASSISTANT_VOICE_INTERACTION_SERVICE; 31 import static android.server.wm.app.Components.AssistantActivity.EXTRA_ASSISTANT_DISPLAY_ID; 32 import static android.server.wm.app.Components.AssistantActivity.EXTRA_ASSISTANT_ENTER_PIP; 33 import static android.server.wm.app.Components.AssistantActivity.EXTRA_ASSISTANT_FINISH_SELF; 34 import static android.server.wm.app.Components.AssistantActivity.EXTRA_ASSISTANT_LAUNCH_NEW_TASK; 35 import static android.server.wm.app.Components.DOCKED_ACTIVITY; 36 import static android.server.wm.app.Components.LAUNCH_ASSISTANT_ACTIVITY_FROM_SESSION; 37 import static android.server.wm.app.Components.LAUNCH_ASSISTANT_ACTIVITY_INTO_STACK; 38 import static android.server.wm.app.Components.LaunchAssistantActivityIntoAssistantStack.EXTRA_ASSISTANT_IS_TRANSLUCENT; 39 import static android.server.wm.app.Components.PIP_ACTIVITY; 40 import static android.server.wm.app.Components.PipActivity.EXTRA_ENTER_PIP; 41 import static android.server.wm.app.Components.TEST_ACTIVITY; 42 import static android.server.wm.app.Components.TRANSLUCENT_ASSISTANT_ACTIVITY; 43 import static android.server.wm.app.Components.TestActivity.TEST_ACTIVITY_ACTION_FINISH_SELF; 44 import static android.view.Display.DEFAULT_DISPLAY; 45 46 import static org.hamcrest.Matchers.hasSize; 47 import static org.hamcrest.Matchers.lessThanOrEqualTo; 48 import static org.junit.Assert.assertEquals; 49 import static org.junit.Assert.assertThat; 50 import static org.junit.Assert.assertTrue; 51 import static org.junit.Assume.assumeTrue; 52 53 import android.content.ComponentName; 54 import android.platform.test.annotations.Presubmit; 55 import android.provider.Settings; 56 import android.server.wm.settings.SettingsSession; 57 58 import org.junit.Ignore; 59 import org.junit.Test; 60 61 /** 62 * Build/Install/Run: 63 * atest CtsWindowManagerDeviceTestCases:AssistantStackTests 64 */ 65 @Presubmit 66 public class AssistantStackTests extends ActivityManagerTestBase { 67 68 private int mAssistantDisplayId = DEFAULT_DISPLAY; 69 setUp()70 public void setUp() throws Exception { 71 super.setUp(); 72 try (final AssistantSession assistantSession = new AssistantSession()) { 73 assistantSession.setVoiceInteractionService(ASSISTANT_VOICE_INTERACTION_SERVICE); 74 launchActivityNoWait(LAUNCH_ASSISTANT_ACTIVITY_INTO_STACK); 75 waitForValidStateWithActivityType(ASSISTANT_ACTIVITY, ACTIVITY_TYPE_ASSISTANT); 76 WindowManagerState.Task assistantStack = 77 mWmState.getRootTaskByActivityType(ACTIVITY_TYPE_ASSISTANT); 78 mAssistantDisplayId = assistantStack.mDisplayId; 79 } 80 } 81 82 @Test testLaunchingAssistantActivityIntoAssistantStack()83 public void testLaunchingAssistantActivityIntoAssistantStack() throws Exception { 84 // Enable the assistant and launch an assistant activity 85 try (final AssistantSession assistantSession = new AssistantSession()) { 86 assistantSession.setVoiceInteractionService(ASSISTANT_VOICE_INTERACTION_SERVICE); 87 88 launchActivityNoWait(LAUNCH_ASSISTANT_ACTIVITY_FROM_SESSION); 89 waitForValidStateWithActivityType(ASSISTANT_ACTIVITY, ACTIVITY_TYPE_ASSISTANT); 90 91 // Ensure that the activity launched in the fullscreen assistant stack 92 assertAssistantStackExists(); 93 // In a multi-window environment the assistant might not be fullscreen 94 assumeTrue(getDefaultDisplayWindowingMode() == WINDOWING_MODE_FULLSCREEN); 95 assertTrue("Expected assistant stack to be fullscreen", 96 mWmState.getRootTaskByActivityType( 97 ACTIVITY_TYPE_ASSISTANT).isFullscreen()); 98 } 99 } 100 101 @Test testAssistantStackZOrder()102 public void testAssistantStackZOrder() throws Exception { 103 assumeTrue(assistantRunsOnPrimaryDisplay()); 104 assumeTrue(supportsPip()); 105 assumeTrue(supportsSplitScreenMultiWindow()); 106 107 // Launch a pinned stack task 108 launchActivity(PIP_ACTIVITY, extraString(EXTRA_ENTER_PIP, "true")); 109 waitForValidStateWithActivityTypeAndWindowingMode( 110 PIP_ACTIVITY, ACTIVITY_TYPE_STANDARD, WINDOWING_MODE_PINNED); 111 mWmState.assertContainsStack("Must contain pinned stack.", 112 WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD); 113 114 // Dock a task 115 launchActivitiesInSplitScreen( 116 getLaunchActivityBuilder().setTargetActivity(DOCKED_ACTIVITY), 117 getLaunchActivityBuilder().setTargetActivity(TEST_ACTIVITY)); 118 119 // Enable the assistant and launch an assistant activity, ensure it is on top 120 try (final AssistantSession assistantSession = new AssistantSession()) { 121 assistantSession.setVoiceInteractionService(ASSISTANT_VOICE_INTERACTION_SERVICE); 122 123 launchActivityNoWait(LAUNCH_ASSISTANT_ACTIVITY_FROM_SESSION); 124 waitForValidStateWithActivityType(ASSISTANT_ACTIVITY, ACTIVITY_TYPE_ASSISTANT); 125 assertAssistantStackExists(); 126 127 mWmState.assertFrontStack("Pinned stack should be on top.", 128 WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD); 129 mWmState.assertFocusedRootTask("Assistant stack should be focused.", 130 WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_ASSISTANT); 131 } 132 } 133 134 @Test testAssistantStackLaunchNewTask()135 public void testAssistantStackLaunchNewTask() throws Exception { 136 assertAssistantStackCanLaunchAndReturnFromNewTask(); 137 } 138 139 @Test 140 @Ignore("b/77272253#comment10") testAssistantStackLaunchNewTaskWithDockedStack()141 public void testAssistantStackLaunchNewTaskWithDockedStack() throws Exception { 142 assumeTrue(assistantRunsOnPrimaryDisplay()); 143 assumeTrue(supportsSplitScreenMultiWindow()); 144 145 // Dock a task 146 launchActivitiesInSplitScreen( 147 getLaunchActivityBuilder().setTargetActivity(DOCKED_ACTIVITY), 148 getLaunchActivityBuilder().setTargetActivity(TEST_ACTIVITY)); 149 150 //assertAssistantStackCanLaunchAndReturnFromNewTask(WINDOWING_MODE_SPLIT_SCREEN_SECONDARY); 151 } 152 assertAssistantStackCanLaunchAndReturnFromNewTask()153 private void assertAssistantStackCanLaunchAndReturnFromNewTask() 154 throws Exception { 155 // Enable the assistant and launch an assistant activity which will launch a new task 156 try (final AssistantSession assistantSession = new AssistantSession()) { 157 assistantSession.setVoiceInteractionService(ASSISTANT_VOICE_INTERACTION_SERVICE); 158 159 launchActivityOnDisplayNoWait(LAUNCH_ASSISTANT_ACTIVITY_INTO_STACK, mAssistantDisplayId, 160 extraString(EXTRA_ASSISTANT_LAUNCH_NEW_TASK, getActivityName(TEST_ACTIVITY)), 161 extraString(EXTRA_ASSISTANT_DISPLAY_ID, Integer.toString(mAssistantDisplayId))); 162 // Ensure that the fullscreen stack is on top and the test activity is now visible 163 waitForValidStateWithActivityType(TEST_ACTIVITY, ACTIVITY_TYPE_STANDARD); 164 } 165 166 if (isAssistantOnTopOfDream()) { 167 // If the assistant is configured to be always-on-top, then the new task should have 168 // been started behind it and the assistant stack should still be on top. 169 mWmState.assertFocusedActivity( 170 "AssistantActivity should be focused", ASSISTANT_ACTIVITY); 171 mWmState.assertFrontStackActivityType( 172 "Assistant stack should be on top.", ACTIVITY_TYPE_ASSISTANT); 173 mWmState.assertFocusedRootTask("Assistant stack should be focused.", 174 WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_ASSISTANT); 175 } else { 176 mWmState.assertFocusedActivity("TestActivity should be resumed", TEST_ACTIVITY); 177 mWmState.assertFrontStack("TestActivity stack should be on top.", 178 WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD); 179 mWmState.assertFocusedRootTask("TestActivity stack should be focused.", 180 WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD); 181 } 182 183 // Now, tell it to finish itself and ensure that the assistant stack is brought back forward 184 mBroadcastActionTrigger.doAction(TEST_ACTIVITY_ACTION_FINISH_SELF); 185 mWmState.waitForFocusedStack(WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_ASSISTANT); 186 mWmState.assertFrontStackActivityType( 187 "Assistant stack should be on top.", ACTIVITY_TYPE_ASSISTANT); 188 mWmState.assertFocusedRootTask("Assistant stack should be focused.", 189 WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_ASSISTANT); 190 } 191 192 @Test testAssistantStackFinishToPreviousApp()193 public void testAssistantStackFinishToPreviousApp() throws Exception { 194 // If the Assistant is configured to be always-on-top, then the assistant activity 195 // started in setUp() will not allow any other activities to start. Therefore we should 196 // remove it before launching a fullscreen activity. 197 if (isAssistantOnTopOfDream()) { 198 removeRootTasksWithActivityTypes(ACTIVITY_TYPE_ASSISTANT); 199 } 200 201 // Launch an assistant activity on top of an existing activity, and ensure that the activity 202 // is still visible and on top after the assistant activity finishes 203 launchActivityOnDisplay(TEST_ACTIVITY, mAssistantDisplayId); 204 try (final AssistantSession assistantSession = new AssistantSession()) { 205 assistantSession.setVoiceInteractionService(ASSISTANT_VOICE_INTERACTION_SERVICE); 206 207 launchActivityNoWait(LAUNCH_ASSISTANT_ACTIVITY_INTO_STACK, 208 extraString(EXTRA_ASSISTANT_FINISH_SELF, "true")); 209 mWmState.waitFor((amState) -> !amState.containsActivity(ASSISTANT_ACTIVITY), 210 getActivityName(ASSISTANT_ACTIVITY) + " finished"); 211 } 212 waitForValidStateWithActivityType(TEST_ACTIVITY, ACTIVITY_TYPE_STANDARD); 213 waitAndAssertTopResumedActivity(TEST_ACTIVITY, mAssistantDisplayId, 214 "TestActivity should be resumed"); 215 mWmState.assertFocusedActivity("TestActivity should be focused", TEST_ACTIVITY); 216 217 mWmState.assertFrontStack("TestActivity stack should be on top.", 218 WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD); 219 mWmState.assertFocusedRootTask("TestActivity stack should be focused.", 220 WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD); 221 } 222 223 @Test testDisallowEnterPiPFromAssistantStack()224 public void testDisallowEnterPiPFromAssistantStack() throws Exception { 225 try (final AssistantSession assistantSession = new AssistantSession()) { 226 assistantSession.setVoiceInteractionService(ASSISTANT_VOICE_INTERACTION_SERVICE); 227 228 launchActivityNoWait(LAUNCH_ASSISTANT_ACTIVITY_INTO_STACK, 229 extraString(EXTRA_ASSISTANT_ENTER_PIP, "true")); 230 } 231 waitForValidStateWithActivityType(ASSISTANT_ACTIVITY, ACTIVITY_TYPE_ASSISTANT); 232 mWmState.assertDoesNotContainStack("Must not contain pinned stack.", 233 WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD); 234 } 235 236 @Test testTranslucentAssistantActivityStackVisibility()237 public void testTranslucentAssistantActivityStackVisibility() throws Exception { 238 try (final AssistantSession assistantSession = new AssistantSession()) { 239 assistantSession.setVoiceInteractionService(ASSISTANT_VOICE_INTERACTION_SERVICE); 240 241 // Go home, launch the assistant and check to see that home is visible 242 removeRootTasksInWindowingModes(WINDOWING_MODE_FULLSCREEN); 243 pressHomeButton(); 244 resumeAppSwitches(); 245 launchActivityNoWait(LAUNCH_ASSISTANT_ACTIVITY_INTO_STACK, 246 extraString(EXTRA_ASSISTANT_IS_TRANSLUCENT, "true")); 247 waitForValidStateWithActivityType( 248 TRANSLUCENT_ASSISTANT_ACTIVITY, ACTIVITY_TYPE_ASSISTANT); 249 assertAssistantStackExists(); 250 mWmState.waitForHomeActivityVisible(); 251 if (hasHomeScreen()) { 252 mWmState.assertHomeActivityVisible(true); 253 } 254 255 // Launch a fullscreen app and then launch the assistant and check to see that it is 256 // also visible 257 removeRootTasksWithActivityTypes(ACTIVITY_TYPE_ASSISTANT); 258 launchActivityOnDisplay(TEST_ACTIVITY, WINDOWING_MODE_FULLSCREEN, mAssistantDisplayId); 259 launchActivityNoWait(LAUNCH_ASSISTANT_ACTIVITY_INTO_STACK, 260 extraString(EXTRA_ASSISTANT_IS_TRANSLUCENT, "true")); 261 waitForValidStateWithActivityType( 262 TRANSLUCENT_ASSISTANT_ACTIVITY, ACTIVITY_TYPE_ASSISTANT); 263 assertAssistantStackExists(); 264 mWmState.assertVisibility(TEST_ACTIVITY, true); 265 266 // Go home, launch assistant, launch app into fullscreen with activity present, and go 267 // back.Ensure home is visible. 268 removeRootTasksWithActivityTypes(ACTIVITY_TYPE_ASSISTANT); 269 pressHomeButton(); 270 resumeAppSwitches(); 271 launchActivityNoWait(LAUNCH_ASSISTANT_ACTIVITY_INTO_STACK, 272 extraString(EXTRA_ASSISTANT_IS_TRANSLUCENT, "true"), 273 extraString(EXTRA_ASSISTANT_LAUNCH_NEW_TASK, getActivityName(TEST_ACTIVITY))); 274 waitForValidStateWithActivityType(TEST_ACTIVITY, ACTIVITY_TYPE_STANDARD); 275 276 final ComponentName homeActivity = mWmState.getHomeActivityName(); 277 int windowingMode = mWmState.getFocusedRootTaskWindowingMode(); 278 // In a multi-window environment the home activity might not be fully covered 279 assumeTrue(windowingMode == WINDOWING_MODE_FULLSCREEN); 280 281 // A WM Shell can implement a policy where there are more than one default 282 // Task Display Areas. 283 // If there are two task display areas, for example, left and right. 284 // When an activity is organized in left task display area it is still running in 285 // WINDOWING_MODE_FULLSCREEN. Having said that, home activity in default task display 286 // area is not fully covered. Thus, home activity is still resumed and visible. 287 // More than that, in the current AOSP 11 implementation, visibility and activity 288 // lifecycle work differently if activities are in the same task display area or in 289 // different task display areas. 290 // For example, if two task display areas have the exact same bounds, 291 // for the user, an activity running in the top task display area covers the activity 292 // running in the bottom task display area. However, because they are in separate 293 // display areas they will be both resumed. 294 // There can be cases where the bounds match but because tasks are in different 295 // task display area they are both resumed. 296 // So we check the activity bounds for two activities to confirm if task display 297 // areas are the same. If not the same, we will skip the visibility asserting test. 298 if (compareActivityBounds(homeActivity, 299 ComponentName.unflattenFromString(mWmState.getFocusedActivity()))) { 300 mWmState.waitAndAssertVisibilityGone(homeActivity); 301 } 302 303 mBroadcastActionTrigger.doAction(TEST_ACTIVITY_ACTION_FINISH_SELF); 304 mWmState.waitForFocusedStack(WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_ASSISTANT); 305 assertAssistantStackExists(); 306 mWmState.waitForHomeActivityVisible(); 307 if (hasHomeScreen()) { 308 mWmState.assertHomeActivityVisible(true); 309 } 310 311 // Launch a fullscreen and docked app and then launch the assistant and check to see 312 // that it 313 // is also visible 314 if (supportsSplitScreenMultiWindow() && assistantRunsOnPrimaryDisplay()) { 315 removeRootTasksWithActivityTypes(ACTIVITY_TYPE_ASSISTANT); 316 launchActivitiesInSplitScreen( 317 getLaunchActivityBuilder().setTargetActivity(DOCKED_ACTIVITY), 318 getLaunchActivityBuilder().setTargetActivity(TEST_ACTIVITY)); 319 launchActivityNoWait(LAUNCH_ASSISTANT_ACTIVITY_INTO_STACK, 320 extraString(EXTRA_ASSISTANT_IS_TRANSLUCENT, "true")); 321 waitForValidStateWithActivityType( 322 TRANSLUCENT_ASSISTANT_ACTIVITY, ACTIVITY_TYPE_ASSISTANT); 323 assertAssistantStackExists(); 324 mWmState.assertVisibility(DOCKED_ACTIVITY, true); 325 mWmState.assertVisibility(TEST_ACTIVITY, true); 326 } 327 } 328 } 329 330 @Test testLaunchIntoSameTask()331 public void testLaunchIntoSameTask() throws Exception { 332 try (final AssistantSession assistantSession = new AssistantSession()) { 333 assistantSession.setVoiceInteractionService(ASSISTANT_VOICE_INTERACTION_SERVICE); 334 335 // Launch the assistant 336 launchActivityOnDisplayNoWait(LAUNCH_ASSISTANT_ACTIVITY_FROM_SESSION, 337 mAssistantDisplayId); 338 waitForValidStateWithActivityType(ASSISTANT_ACTIVITY, ACTIVITY_TYPE_ASSISTANT); 339 assertAssistantStackExists(); 340 mWmState.assertVisibility(ASSISTANT_ACTIVITY, true); 341 mWmState.assertFocusedRootTask("Expected assistant stack focused", 342 WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_ASSISTANT); 343 final WindowManagerState amState = mWmState; 344 // If activity is hosted by created-by-organizer root task, the root task captured by 345 // WindowManagerState will have 0 child task. Otherwise, root task contains 1 child 346 // task. 347 assertThat(amState.getRootTaskByActivityType(ACTIVITY_TYPE_ASSISTANT).getTasks(), 348 hasSize(lessThanOrEqualTo(1))); 349 final int taskId = mWmState.getTaskByActivity(ASSISTANT_ACTIVITY) 350 .mTaskId; 351 352 // Launch a new fullscreen activity 353 // Using Animation Test Activity because it is opaque on all devices. 354 int launchTDAId = mWmState.getTaskDisplayAreaFeatureId(ASSISTANT_ACTIVITY); 355 launchActivityOnTaskDisplayArea(ANIMATION_TEST_ACTIVITY, WINDOWING_MODE_FULLSCREEN, 356 launchTDAId, mAssistantDisplayId); 357 // If the activity is not launched in same TDA, ASSISTANT_ACTIVITY will be visible. 358 assumeTrue("Should launch in same TDA", 359 mWmState.getTaskDisplayArea(ASSISTANT_ACTIVITY) 360 == mWmState.getTaskDisplayArea(ANIMATION_TEST_ACTIVITY) 361 ); 362 // Wait for animation finished. 363 mWmState.waitForActivityState(ANIMATION_TEST_ACTIVITY, STATE_RESUMED); 364 365 if (isAssistantOnTopOfDream()) { 366 mWmState.assertVisibility(ASSISTANT_ACTIVITY, true); 367 } else { 368 mWmState.waitAndAssertVisibilityGone(ASSISTANT_ACTIVITY); 369 } 370 371 // Launch the assistant again and ensure that it goes into the same task 372 launchActivityOnDisplayNoWait(LAUNCH_ASSISTANT_ACTIVITY_FROM_SESSION, 373 mAssistantDisplayId); 374 waitForValidStateWithActivityType(ASSISTANT_ACTIVITY, ACTIVITY_TYPE_ASSISTANT); 375 assertAssistantStackExists(); 376 mWmState.assertVisibility(ASSISTANT_ACTIVITY, true); 377 mWmState.assertFocusedRootTask("Expected assistant stack focused", 378 WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_ASSISTANT); 379 // If activity is hosted by created-by-organizer root task, the root task captured by 380 // WindowManagerState will have 0 child task. Otherwise, root task contains 1 child 381 // task. 382 assertThat(amState.getRootTaskByActivityType(ACTIVITY_TYPE_ASSISTANT).getTasks(), 383 hasSize(lessThanOrEqualTo(1))); 384 assertEquals(taskId, 385 mWmState.getTaskByActivity(ASSISTANT_ACTIVITY).mTaskId); 386 387 } 388 } 389 390 @Test testPinnedStackWithAssistant()391 public void testPinnedStackWithAssistant() throws Exception { 392 assumeTrue(supportsPip()); 393 assumeTrue(supportsSplitScreenMultiWindow()); 394 395 try (final AssistantSession assistantSession = new AssistantSession()) { 396 assistantSession.setVoiceInteractionService(ASSISTANT_VOICE_INTERACTION_SERVICE); 397 398 // Launch a fullscreen activity and a PIP activity, then launch the assistant, and 399 // ensure that the test activity is still visible 400 launchActivity(TEST_ACTIVITY, WINDOWING_MODE_FULLSCREEN); 401 launchActivity(PIP_ACTIVITY, extraString(EXTRA_ENTER_PIP, "true")); 402 launchActivityNoWait(LAUNCH_ASSISTANT_ACTIVITY_INTO_STACK, 403 extraString(EXTRA_ASSISTANT_IS_TRANSLUCENT, String.valueOf(true))); 404 waitForValidStateWithActivityType( 405 TRANSLUCENT_ASSISTANT_ACTIVITY, ACTIVITY_TYPE_ASSISTANT); 406 assertAssistantStackExists(); 407 mWmState.assertVisibility(TRANSLUCENT_ASSISTANT_ACTIVITY, true); 408 mWmState.assertVisibility(PIP_ACTIVITY, true); 409 mWmState.assertVisibility(TEST_ACTIVITY, true); 410 411 } 412 } 413 waitForValidStateWithActivityType(ComponentName activityName, int activityType)414 private void waitForValidStateWithActivityType(ComponentName activityName, int activityType) 415 throws Exception { 416 mWmState.waitForValidState(new WaitForValidActivityState.Builder(activityName) 417 .setActivityType(activityType) 418 .build()); 419 } 420 waitForValidStateWithActivityTypeAndWindowingMode(ComponentName activityName, int activityType, int windowingMode)421 private void waitForValidStateWithActivityTypeAndWindowingMode(ComponentName activityName, 422 int activityType, int windowingMode) throws Exception { 423 mWmState.waitForValidState(new WaitForValidActivityState.Builder(activityName) 424 .setActivityType(activityType) 425 .setWindowingMode(windowingMode) 426 .build()); 427 } 428 429 /** 430 * Asserts that the assistant stack exists. 431 */ assertAssistantStackExists()432 private void assertAssistantStackExists() throws Exception { 433 mWmState.assertContainsStack("Must contain assistant stack.", 434 WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_ASSISTANT); 435 } 436 437 // Any 2D Activity in VR mode is run on a special VR virtual display, so check if the Assistant 438 // is going to run on the same display as other tasks. assistantRunsOnPrimaryDisplay()439 protected boolean assistantRunsOnPrimaryDisplay() { 440 return mAssistantDisplayId == DEFAULT_DISPLAY; 441 } 442 443 /** 444 * @return Windowing Mode from the default display 445 */ getDefaultDisplayWindowingMode()446 private int getDefaultDisplayWindowingMode() { 447 mWmState.computeState(); 448 return mWmState.getDisplay(DEFAULT_DISPLAY).getWindowingMode(); 449 } 450 451 /** Helper class to save, set, and restore 452 * {@link Settings.Secure#VOICE_INTERACTION_SERVICE} system preference. 453 */ 454 private static class AssistantSession extends SettingsSession<String> { AssistantSession()455 AssistantSession() { 456 super(Settings.Secure.getUriFor(Settings.Secure.VOICE_INTERACTION_SERVICE), 457 Settings.Secure::getString, Settings.Secure::putString); 458 } 459 setVoiceInteractionService(ComponentName assistantName)460 void setVoiceInteractionService(ComponentName assistantName) throws Exception { 461 super.set(getActivityName(assistantName)); 462 } 463 } 464 465 /** 466 * Compare if bounds were the same between activities 467 */ compareActivityBounds(ComponentName activityName1, ComponentName activityName2)468 private boolean compareActivityBounds(ComponentName activityName1, 469 ComponentName activityName2) { 470 if (mWmState.getTaskByActivity(activityName1).getBounds() 471 .equals(mWmState.getTaskByActivity(activityName2).getBounds())) { 472 return true; 473 } 474 return false; 475 } 476 } 477