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.quickstep; 18 19 import static com.android.launcher3.util.rule.TestStabilityRule.LOCAL; 20 import static com.android.launcher3.util.rule.TestStabilityRule.PLATFORM_POSTSUBMIT; 21 import static com.android.quickstep.TaskbarModeSwitchRule.Mode.TRANSIENT; 22 23 import static org.junit.Assert.assertEquals; 24 import static org.junit.Assert.assertFalse; 25 import static org.junit.Assert.assertNotNull; 26 import static org.junit.Assert.assertTrue; 27 import static org.junit.Assume.assumeFalse; 28 import static org.junit.Assume.assumeTrue; 29 30 import android.content.Intent; 31 import android.content.res.Configuration; 32 33 import androidx.test.filters.LargeTest; 34 import androidx.test.platform.app.InstrumentationRegistry; 35 import androidx.test.runner.AndroidJUnit4; 36 import androidx.test.uiautomator.By; 37 import androidx.test.uiautomator.Until; 38 39 import com.android.launcher3.Launcher; 40 import com.android.launcher3.LauncherState; 41 import com.android.launcher3.tapl.BaseOverview; 42 import com.android.launcher3.tapl.LaunchedAppState; 43 import com.android.launcher3.tapl.LauncherInstrumentation.NavigationModel; 44 import com.android.launcher3.tapl.Overview; 45 import com.android.launcher3.tapl.OverviewActions; 46 import com.android.launcher3.tapl.OverviewTask; 47 import com.android.launcher3.tapl.SelectModeButtons; 48 import com.android.launcher3.tapl.Workspace; 49 import com.android.launcher3.ui.PortraitLandscapeRunner.PortraitLandscape; 50 import com.android.launcher3.util.Wait; 51 import com.android.launcher3.util.rule.ScreenRecordRule.ScreenRecord; 52 import com.android.launcher3.util.rule.TestStabilityRule; 53 import com.android.quickstep.NavigationModeSwitchRule.NavigationModeSwitch; 54 import com.android.quickstep.TaskbarModeSwitchRule.TaskbarModeSwitch; 55 import com.android.quickstep.views.RecentsView; 56 57 import org.junit.After; 58 import org.junit.Before; 59 import org.junit.Ignore; 60 import org.junit.Test; 61 import org.junit.runner.RunWith; 62 63 @LargeTest 64 @RunWith(AndroidJUnit4.class) 65 public class TaplTestsQuickstep extends AbstractQuickStepTest { 66 67 private static final String CALCULATOR_APP_PACKAGE = 68 resolveSystemApp(Intent.CATEGORY_APP_CALCULATOR); 69 private static final String READ_DEVICE_CONFIG_PERMISSION = 70 "android.permission.READ_DEVICE_CONFIG"; 71 72 @Before setUp()73 public void setUp() throws Exception { 74 super.setUp(); 75 executeOnLauncher(launcher -> { 76 RecentsView recentsView = launcher.getOverviewPanel(); 77 recentsView.getPagedViewOrientedState().forceAllowRotationForTesting(true); 78 }); 79 } 80 81 @After tearDown()82 public void tearDown() { 83 executeOnLauncherInTearDown(launcher -> { 84 RecentsView recentsView = launcher.getOverviewPanel(); 85 recentsView.getPagedViewOrientedState().forceAllowRotationForTesting(false); 86 }); 87 } 88 startTestApps()89 public static void startTestApps() throws Exception { 90 startAppFast(getAppPackageName()); 91 startAppFast(CALCULATOR_APP_PACKAGE); 92 startTestActivity(2); 93 } 94 startTestAppsWithCheck()95 private void startTestAppsWithCheck() throws Exception { 96 startTestApps(); 97 executeOnLauncher(launcher -> assertTrue( 98 "Launcher activity is the top activity; expecting another activity to be the top " 99 + "one", 100 isInLaunchedApp(launcher))); 101 } 102 103 @Test 104 @NavigationModeSwitch 105 @PortraitLandscape testWorkspaceSwitchToAllApps()106 public void testWorkspaceSwitchToAllApps() { 107 assertNotNull("switchToAllApps() returned null", 108 mLauncher.getWorkspace().switchToAllApps()); 109 assertTrue("Launcher internal state is not All Apps", 110 isInState(() -> LauncherState.ALL_APPS)); 111 } 112 113 @Test 114 @PortraitLandscape testOverview()115 public void testOverview() throws Exception { 116 startTestAppsWithCheck(); 117 // mLauncher.pressHome() also tests an important case of pressing home while in background. 118 Overview overview = mLauncher.goHome().switchToOverview(); 119 assertTrue("Launcher internal state didn't switch to Overview", 120 isInState(() -> LauncherState.OVERVIEW)); 121 executeOnLauncher( 122 launcher -> assertTrue("Don't have at least 3 tasks", getTaskCount(launcher) >= 3)); 123 124 // Test flinging forward and backward. 125 executeOnLauncher(launcher -> assertEquals("Current task in Overview is not 0", 126 0, getCurrentOverviewPage(launcher))); 127 128 overview.flingForward(); 129 assertTrue("Launcher internal state is not Overview", 130 isInState(() -> LauncherState.OVERVIEW)); 131 final Integer currentTaskAfterFlingForward = getFromLauncher( 132 launcher -> getCurrentOverviewPage(launcher)); 133 executeOnLauncher(launcher -> assertTrue("Current task in Overview is still 0", 134 currentTaskAfterFlingForward > 0)); 135 136 overview.flingBackward(); 137 assertTrue("Launcher internal state is not Overview", 138 isInState(() -> LauncherState.OVERVIEW)); 139 executeOnLauncher(launcher -> assertTrue("Flinging back in Overview did nothing", 140 getCurrentOverviewPage(launcher) < currentTaskAfterFlingForward)); 141 142 // Test opening a task. 143 OverviewTask task = mLauncher.goHome().switchToOverview().getCurrentTask(); 144 assertNotNull("overview.getCurrentTask() returned null (1)", task); 145 assertNotNull("OverviewTask.open returned null", task.open()); 146 assertTrue("Test activity didn't open from Overview", mDevice.wait(Until.hasObject( 147 By.pkg(getAppPackageName()).text("TestActivity2")), 148 DEFAULT_UI_TIMEOUT)); 149 executeOnLauncher(launcher -> assertTrue( 150 "Launcher activity is the top activity; expecting another activity to be the top " 151 + "one", 152 isInLaunchedApp(launcher))); 153 154 // Test dismissing a task. 155 overview = mLauncher.goHome().switchToOverview(); 156 assertTrue("Launcher internal state didn't switch to Overview", 157 isInState(() -> LauncherState.OVERVIEW)); 158 final Integer numTasks = getFromLauncher(launcher -> getTaskCount(launcher)); 159 task = overview.getCurrentTask(); 160 assertNotNull("overview.getCurrentTask() returned null (2)", task); 161 task.dismiss(); 162 executeOnLauncher( 163 launcher -> assertEquals("Dismissing a task didn't remove 1 task from Overview", 164 numTasks - 1, getTaskCount(launcher))); 165 166 // Test dismissing all tasks. 167 mLauncher.goHome().switchToOverview().dismissAllTasks(); 168 assertTrue("Launcher internal state is not Home", 169 isInState(() -> LauncherState.NORMAL)); 170 executeOnLauncher( 171 launcher -> assertEquals("Still have tasks after dismissing all", 172 0, getTaskCount(launcher))); 173 } 174 175 /** 176 * Smoke test for action buttons: Presses all the buttons and makes sure no crashes occur. 177 */ 178 @Test 179 @NavigationModeSwitch 180 @PortraitLandscape testOverviewActions()181 public void testOverviewActions() throws Exception { 182 assumeFalse("Skipping Overview Actions tests for grid only overview", 183 mLauncher.isTablet() && mLauncher.isGridOnlyOverviewEnabled()); 184 startTestAppsWithCheck(); 185 OverviewActions actionsView = 186 mLauncher.goHome().switchToOverview().getOverviewActions(); 187 actionsView.clickAndDismissScreenshot(); 188 } 189 190 @Test testDismissOverviewWithEscKey()191 public void testDismissOverviewWithEscKey() throws Exception { 192 startTestAppsWithCheck(); 193 final Overview overview = mLauncher.goHome().switchToOverview(); 194 assertTrue("Launcher internal state is not Overview", 195 isInState(() -> LauncherState.OVERVIEW)); 196 197 overview.dismissByEscKey(); 198 assertTrue("Launcher internal state is not Home", 199 isInState(() -> LauncherState.NORMAL)); 200 } 201 202 @Test testDismissModalTaskAndOverviewWithEscKey()203 public void testDismissModalTaskAndOverviewWithEscKey() throws Exception { 204 startTestAppsWithCheck(); 205 final Overview overview = mLauncher.goHome().switchToOverview(); 206 207 final SelectModeButtons selectModeButtons; 208 209 if (mLauncher.isTablet() && mLauncher.isGridOnlyOverviewEnabled()) { 210 selectModeButtons = overview.getCurrentTask().tapMenu().tapSelectMenuItem(); 211 } else { 212 selectModeButtons = overview.getOverviewActions().clickSelect(); 213 } 214 215 assertTrue("Launcher internal state is not Overview Modal Task", 216 isInState(() -> LauncherState.OVERVIEW_MODAL_TASK)); 217 218 selectModeButtons.dismissByEscKey(); 219 220 assertTrue("Launcher internal state is not Overview", 221 isInState(() -> LauncherState.OVERVIEW)); 222 overview.dismissByEscKey(); 223 assertTrue("Launcher internal state is not Home", 224 isInState(() -> LauncherState.NORMAL)); 225 } 226 227 @Test testOpenOverviewWithActionPlusTabKeys()228 public void testOpenOverviewWithActionPlusTabKeys() throws Exception { 229 startTestAppsWithCheck(); 230 startAppFast(CALCULATOR_APP_PACKAGE); // Ensure Calculator is last opened app. 231 Workspace home = mLauncher.goHome(); 232 assertTrue("Launcher state is not Home", isInState(() -> LauncherState.NORMAL)); 233 234 Overview overview = home.openOverviewFromActionPlusTabKeyboardShortcut(); 235 236 assertTrue("Launcher state is not Overview", isInState(() -> LauncherState.OVERVIEW)); 237 overview.launchFocusedTaskByEnterKey(CALCULATOR_APP_PACKAGE); // Assert app is focused. 238 } 239 240 @Test testOpenOverviewWithRecentsKey()241 public void testOpenOverviewWithRecentsKey() throws Exception { 242 startTestAppsWithCheck(); 243 startAppFast(CALCULATOR_APP_PACKAGE); // Ensure Calculator is last opened app. 244 Workspace home = mLauncher.goHome(); 245 assertTrue("Launcher state is not Home", isInState(() -> LauncherState.NORMAL)); 246 247 Overview overview = home.openOverviewFromRecentsKeyboardShortcut(); 248 249 assertTrue("Launcher state is not Overview", isInState(() -> LauncherState.OVERVIEW)); 250 overview.launchFocusedTaskByEnterKey(CALCULATOR_APP_PACKAGE); // Assert app is focused. 251 } 252 getCurrentOverviewPage(Launcher launcher)253 private int getCurrentOverviewPage(Launcher launcher) { 254 return launcher.<RecentsView>getOverviewPanel().getCurrentPage(); 255 } 256 getTaskCount(Launcher launcher)257 private int getTaskCount(Launcher launcher) { 258 return launcher.<RecentsView>getOverviewPanel().getTaskViewCount(); 259 } 260 getTopRowTaskCountForTablet(Launcher launcher)261 private int getTopRowTaskCountForTablet(Launcher launcher) { 262 return launcher.<RecentsView>getOverviewPanel().getTopRowTaskCountForTablet(); 263 } 264 getBottomRowTaskCountForTablet(Launcher launcher)265 private int getBottomRowTaskCountForTablet(Launcher launcher) { 266 return launcher.<RecentsView>getOverviewPanel().getBottomRowTaskCountForTablet(); 267 } 268 269 // Staging; will be promoted to presubmit if stable 270 @TestStabilityRule.Stability(flavors = LOCAL | PLATFORM_POSTSUBMIT) 271 272 @Test 273 @NavigationModeSwitch 274 @PortraitLandscape testSwitchToOverview()275 public void testSwitchToOverview() throws Exception { 276 startTestAppsWithCheck(); 277 assertNotNull("Workspace.switchToOverview() returned null", 278 mLauncher.goHome().switchToOverview()); 279 assertTrue("Launcher internal state didn't switch to Overview", 280 isInState(() -> LauncherState.OVERVIEW)); 281 } 282 283 @Test 284 @TaskbarModeSwitch(mode = TRANSIENT) testSwitchToOverviewWithStashedTaskbar()285 public void testSwitchToOverviewWithStashedTaskbar() throws Exception { 286 try { 287 startTestAppsWithCheck(); 288 // Set ignoreTaskbarVisibility, as transient taskbar will be stashed after app launch. 289 mLauncher.setIgnoreTaskbarVisibility(true); 290 mLauncher.getLaunchedAppState().switchToOverview(); 291 } finally { 292 mLauncher.setIgnoreTaskbarVisibility(false); 293 } 294 } 295 296 // Staging; will be promoted to presubmit if stable 297 @TestStabilityRule.Stability(flavors = LOCAL | PLATFORM_POSTSUBMIT) 298 299 @Test 300 @NavigationModeSwitch 301 @PortraitLandscape testBackground()302 public void testBackground() throws Exception { 303 startAppFast(CALCULATOR_APP_PACKAGE); 304 final LaunchedAppState launchedAppState = getAndAssertLaunchedApp(); 305 306 assertNotNull("Background.switchToOverview() returned null", 307 launchedAppState.switchToOverview()); 308 assertTrue("Launcher internal state didn't switch to Overview", 309 isInState(() -> LauncherState.OVERVIEW)); 310 } 311 quickSwitchToPreviousAppAndAssert(boolean toRight)312 private void quickSwitchToPreviousAppAndAssert(boolean toRight) { 313 final LaunchedAppState launchedAppState = getAndAssertLaunchedApp(); 314 if (toRight) { 315 launchedAppState.quickSwitchToPreviousApp(); 316 } else { 317 launchedAppState.quickSwitchToPreviousAppSwipeLeft(); 318 } 319 320 // While enable shell transition, Launcher can be resumed due to transient launch. 321 waitForLauncherCondition("Launcher shouldn't stay in resume forever", 322 this::isInLaunchedApp, 3000 /* timeout */); 323 } 324 325 @Test 326 @NavigationModeSwitch 327 @PortraitLandscape 328 @ScreenRecord // b/313464374 329 @TestStabilityRule.Stability(flavors = LOCAL | PLATFORM_POSTSUBMIT) // b/325659406 testQuickSwitchFromApp()330 public void testQuickSwitchFromApp() throws Exception { 331 startTestActivity(2); 332 startTestActivity(3); 333 startTestActivity(4); 334 335 quickSwitchToPreviousAppAndAssert(true /* toRight */); 336 assertTestActivityIsRunning(3, 337 "The first app we should have quick switched to is not running"); 338 339 quickSwitchToPreviousAppAndAssert(true /* toRight */); 340 if (mLauncher.getNavigationModel() == NavigationModel.THREE_BUTTON) { 341 // 3-button mode toggles between 2 apps, rather than going back further. 342 assertTestActivityIsRunning(4, 343 "Second quick switch should have returned to the first app."); 344 } else { 345 assertTestActivityIsRunning(2, 346 "The second app we should have quick switched to is not running"); 347 } 348 349 quickSwitchToPreviousAppAndAssert(false /* toRight */); 350 assertTestActivityIsRunning(3, 351 "The 2nd app we should have quick switched to is not running"); 352 353 final LaunchedAppState launchedAppState = getAndAssertLaunchedApp(); 354 launchedAppState.switchToOverview(); 355 } 356 357 @Test 358 @TaskbarModeSwitch testQuickSwitchToPreviousAppForTablet()359 public void testQuickSwitchToPreviousAppForTablet() throws Exception { 360 assumeTrue(mLauncher.isTablet()); 361 startTestActivity(2); 362 startImeTestActivity(); 363 364 // Set ignoreTaskbarVisibility to true to verify the task bar visibility explicitly. 365 mLauncher.setIgnoreTaskbarVisibility(true); 366 367 368 try { 369 boolean isTransientTaskbar = mLauncher.isTransientTaskbar(); 370 // Expect task bar invisible when the launched app was the IME activity. 371 LaunchedAppState launchedAppState = getAndAssertLaunchedApp(); 372 if (!isTransientTaskbar && isHardwareKeyboard() && !mLauncher.isImeDocked()) { 373 launchedAppState.assertTaskbarVisible(); 374 } else { 375 launchedAppState.assertTaskbarHidden(); 376 } 377 378 // Quick-switch to the test app with swiping to right. 379 quickSwitchToPreviousAppAndAssert(true /* toRight */); 380 381 assertTestActivityIsRunning(2, 382 "The first app we should have quick switched to is not running"); 383 launchedAppState = getAndAssertLaunchedApp(); 384 if (isTransientTaskbar) { 385 launchedAppState.assertTaskbarHidden(); 386 } else { 387 // Expect taskbar visible when the launched app was the test activity. 388 launchedAppState.assertTaskbarVisible(); 389 } 390 } finally { 391 // Reset ignoreTaskbarVisibility to ensure other tests still verify it. 392 mLauncher.setIgnoreTaskbarVisibility(false); 393 } 394 } 395 isHardwareKeyboard()396 private boolean isHardwareKeyboard() { 397 return Configuration.KEYBOARD_QWERTY 398 == mTargetContext.getResources().getConfiguration().keyboard; 399 } 400 401 @Test 402 @NavigationModeSwitch 403 @PortraitLandscape testQuickSwitchFromHome()404 public void testQuickSwitchFromHome() throws Exception { 405 startTestActivity(2); 406 mLauncher.goHome().quickSwitchToPreviousApp(); 407 assertTestActivityIsRunning(2, 408 "The most recent task is not running after quick switching from home"); 409 getAndAssertLaunchedApp(); 410 } 411 412 @Test 413 @PortraitLandscape 414 @NavigationModeSwitch testPressBack()415 public void testPressBack() throws Exception { 416 InstrumentationRegistry.getInstrumentation().getUiAutomation().adoptShellPermissionIdentity( 417 READ_DEVICE_CONFIG_PERMISSION); 418 // Debug if we need to goHome to prevent wrong previous state b/315525621 419 mLauncher.goHome(); 420 mLauncher.getWorkspace().switchToAllApps().pressBackToWorkspace(); 421 waitForState("Launcher internal state didn't switch to Home", () -> LauncherState.NORMAL); 422 423 startAppFast(CALCULATOR_APP_PACKAGE); 424 mLauncher.getLaunchedAppState().pressBackToWorkspace(); 425 waitForState("Launcher internal state didn't switch to Home", () -> LauncherState.NORMAL); 426 } 427 428 @Test 429 @PortraitLandscape 430 @TaskbarModeSwitch() 431 @Ignore("b/315376057") testOverviewForTablet()432 public void testOverviewForTablet() throws Exception { 433 assumeTrue(mLauncher.isTablet()); 434 435 for (int i = 2; i <= 14; i++) { 436 startTestActivity(i); 437 } 438 439 Overview overview = mLauncher.goHome().switchToOverview(); 440 executeOnLauncher( 441 launcher -> assertTrue("Don't have at least 13 tasks", 442 getTaskCount(launcher) >= 13)); 443 444 // Test scroll the first task off screen 445 overview.scrollCurrentTaskOffScreen(); 446 assertTrue("Launcher internal state is not Overview", 447 isInState(() -> LauncherState.OVERVIEW)); 448 executeOnLauncher(launcher -> assertTrue("Current task in Overview is still 0", 449 getCurrentOverviewPage(launcher) > 0)); 450 451 // Test opening the task. 452 overview.getCurrentTask().open(); 453 assertTrue("Test activity didn't open from Overview", 454 mDevice.wait(Until.hasObject(By.pkg(getAppPackageName()).text( 455 mLauncher.isGridOnlyOverviewEnabled() ? "TestActivity12" 456 : "TestActivity13")), 457 DEFAULT_UI_TIMEOUT)); 458 459 // Scroll the task offscreen as it is now first 460 overview = mLauncher.goHome().switchToOverview(); 461 overview.scrollCurrentTaskOffScreen(); 462 assertTrue("Launcher internal state is not Overview", 463 isInState(() -> LauncherState.OVERVIEW)); 464 executeOnLauncher(launcher -> assertTrue("Current task in Overview is still 0", 465 getCurrentOverviewPage(launcher) > 0)); 466 467 // Test dismissing the later task. 468 final Integer numTasks = getFromLauncher(this::getTaskCount); 469 overview.getCurrentTask().dismiss(); 470 executeOnLauncher( 471 launcher -> assertEquals("Dismissing a task didn't remove 1 task from Overview", 472 numTasks - 1, getTaskCount(launcher))); 473 executeOnLauncher(launcher -> assertTrue("Grid did not rebalance after dismissal", 474 (Math.abs(getTopRowTaskCountForTablet(launcher) - getBottomRowTaskCountForTablet( 475 launcher)) <= 1))); 476 477 // TODO(b/308841019): Re-enable after fixing Overview jank when dismiss 478 // // Test dismissing more tasks. 479 // assertTrue("Launcher internal state didn't remain in Overview", 480 // isInState(() -> LauncherState.OVERVIEW)); 481 // overview.getCurrentTask().dismiss(); 482 // assertTrue("Launcher internal state didn't remain in Overview", 483 // isInState(() -> LauncherState.OVERVIEW)); 484 // overview.getCurrentTask().dismiss(); 485 // executeOnLauncher(launcher -> assertTrue("Grid did not rebalance after multiple dismissals", 486 // (Math.abs(getTopRowTaskCountForTablet(launcher) - getBottomRowTaskCountForTablet( 487 // launcher)) <= 1))); 488 489 // Test dismissing all tasks. 490 mLauncher.goHome().switchToOverview().dismissAllTasks(); 491 assertTrue("Launcher internal state is not Home", 492 isInState(() -> LauncherState.NORMAL)); 493 executeOnLauncher( 494 launcher -> assertEquals("Still have tasks after dismissing all", 495 0, getTaskCount(launcher))); 496 } 497 498 @Test 499 @PortraitLandscape testOverviewDeadzones()500 public void testOverviewDeadzones() throws Exception { 501 startTestAppsWithCheck(); 502 503 Overview overview = mLauncher.goHome().switchToOverview(); 504 assertTrue("Launcher internal state should be Overview", 505 isInState(() -> LauncherState.OVERVIEW)); 506 executeOnLauncher( 507 launcher -> assertTrue("Should have at least 3 tasks", 508 getTaskCount(launcher) >= 3)); 509 510 // It should not dismiss overview when tapping between tasks 511 overview.touchBetweenTasks(); 512 overview = mLauncher.getOverview(); 513 assertTrue("Launcher internal state should be Overview", 514 isInState(() -> LauncherState.OVERVIEW)); 515 516 // Dismiss when tapping to the right of the focused task 517 overview.touchOutsideFirstTask(); 518 assertTrue("Launcher internal state should be Home", 519 isInState(() -> LauncherState.NORMAL)); 520 } 521 522 @Test 523 @PortraitLandscape 524 @TaskbarModeSwitch testTaskbarDeadzonesForTablet()525 public void testTaskbarDeadzonesForTablet() throws Exception { 526 assumeTrue(mLauncher.isTablet()); 527 528 startTestAppsWithCheck(); 529 530 Overview overview = mLauncher.goHome().switchToOverview(); 531 assertTrue("Launcher internal state should be Overview", 532 isInState(() -> LauncherState.OVERVIEW)); 533 executeOnLauncher( 534 launcher -> assertTrue("Should have at least 3 tasks", 535 getTaskCount(launcher) >= 3)); 536 537 if (mLauncher.isTransientTaskbar()) { 538 // On transient taskbar, it should dismiss when tapping outside taskbar bounds. 539 overview.touchTaskbarBottomCorner(/* tapRight= */ false); 540 assertTrue("Launcher internal state should be Normal", 541 isInState(() -> LauncherState.NORMAL)); 542 543 overview = mLauncher.getWorkspace().switchToOverview(); 544 545 // On transient taskbar, it should dismiss when tapping outside taskbar bounds. 546 overview.touchTaskbarBottomCorner(/* tapRight= */ true); 547 assertTrue("Launcher internal state should be Normal", 548 isInState(() -> LauncherState.NORMAL)); 549 } else { 550 // On persistent taskbar, it should not dismiss when tapping the taskbar 551 overview.touchTaskbarBottomCorner(/* tapRight= */ false); 552 assertTrue("Launcher internal state should be Overview", 553 isInState(() -> LauncherState.OVERVIEW)); 554 555 // On persistent taskbar, it should not dismiss when tapping the taskbar 556 overview.touchTaskbarBottomCorner(/* tapRight= */ true); 557 assertTrue("Launcher internal state should be Overview", 558 isInState(() -> LauncherState.OVERVIEW)); 559 } 560 } 561 562 @Test testDisableRotationCheckForPhone()563 public void testDisableRotationCheckForPhone() throws Exception { 564 assumeFalse(mLauncher.isTablet()); 565 try { 566 mLauncher.setExpectedRotationCheckEnabled(false); 567 mLauncher.setEnableRotation(false); 568 mLauncher.getDevice().setOrientationLeft(); 569 startTestActivity(7); 570 Wait.atMost("Device should not be in natural orientation", 571 () -> !mDevice.isNaturalOrientation(), DEFAULT_UI_TIMEOUT, mLauncher); 572 mLauncher.goHome(); 573 } finally { 574 mLauncher.setExpectedRotationCheckEnabled(true); 575 mLauncher.setEnableRotation(true); 576 mLauncher.getDevice().setOrientationNatural(); 577 } 578 } 579 580 @Test testExcludeFromRecents()581 public void testExcludeFromRecents() throws Exception { 582 startExcludeFromRecentsTestActivity(); 583 OverviewTask currentTask = getAndAssertLaunchedApp().switchToOverview().getCurrentTask(); 584 // TODO(b/326565120): the expected content description shouldn't be null but for now there 585 // is a bug that causes it to sometimes be for excludeForRecents tasks. 586 assertTrue("Can't find ExcludeFromRecentsTestActivity after entering Overview from it", 587 currentTask.containsContentDescription("ExcludeFromRecents") 588 || currentTask.containsContentDescription(null)); 589 // Going home should clear out the excludeFromRecents task. 590 BaseOverview overview = mLauncher.goHome().switchToOverview(); 591 if (overview.hasTasks()) { 592 currentTask = overview.getCurrentTask(); 593 assertFalse("Found ExcludeFromRecentsTestActivity after entering Overview from Home", 594 currentTask.containsContentDescription("ExcludeFromRecents") 595 || currentTask.containsContentDescription(null)); 596 } else { 597 // Presumably the test started with 0 tasks and remains that way after going home. 598 } 599 } 600 } 601