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.ui.TaplTestsLauncher3.getAppPackageName; 20 21 import static org.junit.Assert.assertEquals; 22 import static org.junit.Assert.assertNotNull; 23 import static org.junit.Assert.assertTrue; 24 25 import android.content.Intent; 26 27 import androidx.test.filters.LargeTest; 28 import androidx.test.runner.AndroidJUnit4; 29 import androidx.test.uiautomator.By; 30 import androidx.test.uiautomator.Until; 31 32 import com.android.launcher3.Launcher; 33 import com.android.launcher3.LauncherState; 34 import com.android.launcher3.tapl.AllApps; 35 import com.android.launcher3.tapl.AllAppsFromOverview; 36 import com.android.launcher3.tapl.Background; 37 import com.android.launcher3.tapl.LauncherInstrumentation.NavigationModel; 38 import com.android.launcher3.tapl.Overview; 39 import com.android.launcher3.tapl.OverviewTask; 40 import com.android.launcher3.tapl.TestHelpers; 41 import com.android.launcher3.ui.TaplTestsLauncher3; 42 import com.android.quickstep.NavigationModeSwitchRule.NavigationModeSwitch; 43 import com.android.quickstep.views.RecentsView; 44 45 import org.junit.After; 46 import org.junit.Before; 47 import org.junit.Test; 48 import org.junit.runner.RunWith; 49 50 @LargeTest 51 @RunWith(AndroidJUnit4.class) 52 public class TaplTestsQuickstep extends AbstractQuickStepTest { 53 @Before setUp()54 public void setUp() throws Exception { 55 super.setUp(); 56 TaplTestsLauncher3.initialize(this); 57 executeOnLauncher(launcher -> { 58 RecentsView recentsView = launcher.getOverviewPanel(); 59 recentsView.getPagedViewOrientedState().forceAllowRotationForTesting(true); 60 }); 61 } 62 63 @After tearDown()64 public void tearDown() { 65 executeOnLauncher(launcher -> { 66 RecentsView recentsView = launcher.getOverviewPanel(); 67 recentsView.getPagedViewOrientedState().forceAllowRotationForTesting(false); 68 }); 69 } 70 startTestApps()71 private void startTestApps() throws Exception { 72 startAppFast(getAppPackageName()); 73 startAppFast(resolveSystemApp(Intent.CATEGORY_APP_CALCULATOR)); 74 startTestActivity(2); 75 76 executeOnLauncher(launcher -> assertTrue( 77 "Launcher activity is the top activity; expecting another activity to be the top " 78 + "one", 79 isInBackground(launcher))); 80 } 81 82 @Test 83 @NavigationModeSwitch 84 @PortraitLandscape testWorkspaceSwitchToAllApps()85 public void testWorkspaceSwitchToAllApps() { 86 assertNotNull("switchToAllApps() returned null", 87 mLauncher.getWorkspace().switchToAllApps()); 88 assertTrue("Launcher internal state is not All Apps", 89 isInState(() -> LauncherState.ALL_APPS)); 90 } 91 92 @Test testAllAppsFromOverview()93 public void testAllAppsFromOverview() throws Exception { 94 if (!mLauncher.hasAllAppsInOverview()) { 95 return; 96 } 97 98 // Test opening all apps from Overview. 99 assertNotNull("switchToAllApps() returned null", 100 mLauncher.getWorkspace().switchToOverview().switchToAllApps()); 101 102 TaplTestsLauncher3.runAllAppsTest(this, mLauncher.getAllAppsFromOverview()); 103 } 104 105 @Test 106 @PortraitLandscape testOverview()107 public void testOverview() throws Exception { 108 startTestApps(); 109 // mLauncher.pressHome() also tests an important case of pressing home while in background. 110 Overview overview = mLauncher.pressHome().switchToOverview(); 111 assertTrue("Launcher internal state didn't switch to Overview", 112 isInState(() -> LauncherState.OVERVIEW)); 113 executeOnLauncher( 114 launcher -> assertTrue("Don't have at least 3 tasks", getTaskCount(launcher) >= 3)); 115 116 // Test flinging forward and backward. 117 executeOnLauncher(launcher -> assertEquals("Current task in Overview is not 0", 118 0, getCurrentOverviewPage(launcher))); 119 120 overview.flingForward(); 121 assertTrue("Launcher internal state is not Overview", 122 isInState(() -> LauncherState.OVERVIEW)); 123 final Integer currentTaskAfterFlingForward = getFromLauncher( 124 launcher -> getCurrentOverviewPage(launcher)); 125 executeOnLauncher(launcher -> assertTrue("Current task in Overview is still 0", 126 currentTaskAfterFlingForward > 0)); 127 128 overview.flingBackward(); 129 assertTrue("Launcher internal state is not Overview", 130 isInState(() -> LauncherState.OVERVIEW)); 131 executeOnLauncher(launcher -> assertTrue("Flinging back in Overview did nothing", 132 getCurrentOverviewPage(launcher) < currentTaskAfterFlingForward)); 133 134 // Test opening a task. 135 OverviewTask task = mLauncher.pressHome().switchToOverview().getCurrentTask(); 136 assertNotNull("overview.getCurrentTask() returned null (1)", task); 137 assertNotNull("OverviewTask.open returned null", task.open()); 138 assertTrue("Test activity didn't open from Overview", mDevice.wait(Until.hasObject( 139 By.pkg(getAppPackageName()).text("TestActivity2")), 140 DEFAULT_UI_TIMEOUT)); 141 executeOnLauncher(launcher -> assertTrue( 142 "Launcher activity is the top activity; expecting another activity to be the top " 143 + "one", 144 isInBackground(launcher))); 145 146 // Test dismissing a task. 147 overview = mLauncher.pressHome().switchToOverview(); 148 assertTrue("Launcher internal state didn't switch to Overview", 149 isInState(() -> LauncherState.OVERVIEW)); 150 final Integer numTasks = getFromLauncher(launcher -> getTaskCount(launcher)); 151 task = overview.getCurrentTask(); 152 assertNotNull("overview.getCurrentTask() returned null (2)", task); 153 task.dismiss(); 154 executeOnLauncher( 155 launcher -> assertEquals("Dismissing a task didn't remove 1 task from Overview", 156 numTasks - 1, getTaskCount(launcher))); 157 158 if (mLauncher.hasAllAppsInOverview() && (!TestHelpers.isInLauncherProcess() 159 || getFromLauncher(launcher -> !launcher.getDeviceProfile().isLandscape))) { 160 // Test switching to all apps and back. 161 final AllAppsFromOverview allApps = overview.switchToAllApps(); 162 assertNotNull("overview.switchToAllApps() returned null (1)", allApps); 163 assertTrue("Launcher internal state is not All Apps (1)", 164 isInState(() -> LauncherState.ALL_APPS)); 165 166 overview = allApps.switchBackToOverview(); 167 assertNotNull("allApps.switchBackToOverview() returned null", overview); 168 assertTrue("Launcher internal state didn't switch to Overview", 169 isInState(() -> LauncherState.OVERVIEW)); 170 171 // Test UIDevice.pressBack() 172 overview.switchToAllApps(); 173 assertNotNull("overview.switchToAllApps() returned null (2)", allApps); 174 assertTrue("Launcher internal state is not All Apps (2)", 175 isInState(() -> LauncherState.ALL_APPS)); 176 mDevice.pressBack(); 177 mLauncher.getOverview(); 178 } 179 180 // Test UIDevice.pressHome, once we are in AllApps. 181 mDevice.pressHome(); 182 waitForState("Launcher internal state didn't switch to Home", () -> LauncherState.NORMAL); 183 184 // Test dismissing all tasks. 185 mLauncher.getWorkspace().switchToOverview().dismissAllTasks(); 186 waitForState("Launcher internal state didn't switch to Home", () -> LauncherState.NORMAL); 187 executeOnLauncher( 188 launcher -> assertEquals("Still have tasks after dismissing all", 189 0, getTaskCount(launcher))); 190 } 191 getCurrentOverviewPage(Launcher launcher)192 private int getCurrentOverviewPage(Launcher launcher) { 193 return launcher.<RecentsView>getOverviewPanel().getCurrentPage(); 194 } 195 getTaskCount(Launcher launcher)196 private int getTaskCount(Launcher launcher) { 197 return launcher.<RecentsView>getOverviewPanel().getTaskViewCount(); 198 } 199 200 @Test testAppIconLaunchFromAllAppsFromOverview()201 public void testAppIconLaunchFromAllAppsFromOverview() throws Exception { 202 if (!mLauncher.hasAllAppsInOverview()) { 203 return; 204 } 205 206 final AllApps allApps = 207 mLauncher.getWorkspace().switchToOverview().switchToAllApps(); 208 assertTrue("Launcher internal state is not All Apps", 209 isInState(() -> LauncherState.ALL_APPS)); 210 211 TaplTestsLauncher3.runIconLaunchFromAllAppsTest(this, allApps); 212 } 213 214 @Test 215 @NavigationModeSwitch 216 @PortraitLandscape testSwitchToOverview()217 public void testSwitchToOverview() throws Exception { 218 assertNotNull("Workspace.switchToOverview() returned null", 219 mLauncher.pressHome().switchToOverview()); 220 assertTrue("Launcher internal state didn't switch to Overview", 221 isInState(() -> LauncherState.OVERVIEW)); 222 } 223 224 @Test 225 @NavigationModeSwitch 226 @PortraitLandscape testBackground()227 public void testBackground() throws Exception { 228 startAppFast(resolveSystemApp(Intent.CATEGORY_APP_CALCULATOR)); 229 final Background background = getAndAssertBackground(); 230 231 assertNotNull("Background.switchToOverview() returned null", background.switchToOverview()); 232 assertTrue("Launcher internal state didn't switch to Overview", 233 isInState(() -> LauncherState.OVERVIEW)); 234 } 235 getAndAssertBackground()236 private Background getAndAssertBackground() { 237 final Background background = mLauncher.getBackground(); 238 assertNotNull("Launcher.getBackground() returned null", background); 239 executeOnLauncher(launcher -> assertTrue( 240 "Launcher activity is the top activity; expecting another activity to be the top " 241 + "one", 242 isInBackground(launcher))); 243 return background; 244 } 245 246 @Test 247 @PortraitLandscape testAllAppsFromHome()248 public void testAllAppsFromHome() throws Exception { 249 // Test opening all apps 250 assertNotNull("switchToAllApps() returned null", 251 mLauncher.getWorkspace().switchToAllApps()); 252 253 TaplTestsLauncher3.runAllAppsTest(this, mLauncher.getAllApps()); 254 255 // Testing pressHome. 256 assertTrue("Launcher internal state is not All Apps", 257 isInState(() -> LauncherState.ALL_APPS)); 258 assertNotNull("pressHome returned null", mLauncher.pressHome()); 259 assertTrue("Launcher internal state is not Home", 260 isInState(() -> LauncherState.NORMAL)); 261 assertNotNull("getHome returned null", mLauncher.getWorkspace()); 262 } 263 264 @Test 265 @NavigationModeSwitch 266 @PortraitLandscape testQuickSwitchFromApp()267 public void testQuickSwitchFromApp() throws Exception { 268 startTestActivity(2); 269 startTestActivity(3); 270 startTestActivity(4); 271 272 Background background = getAndAssertBackground(); 273 background.quickSwitchToPreviousApp(); 274 assertTrue("The first app we should have quick switched to is not running", 275 isTestActivityRunning(3)); 276 277 background = getAndAssertBackground(); 278 background.quickSwitchToPreviousApp(); 279 if (mLauncher.getNavigationModel() == NavigationModel.THREE_BUTTON) { 280 // 3-button mode toggles between 2 apps, rather than going back further. 281 assertTrue("Second quick switch should have returned to the first app.", 282 isTestActivityRunning(4)); 283 } else { 284 assertTrue("The second app we should have quick switched to is not running", 285 isTestActivityRunning(2)); 286 } 287 getAndAssertBackground(); 288 } 289 isTestActivityRunning(int activityNumber)290 private boolean isTestActivityRunning(int activityNumber) { 291 return mDevice.wait(Until.hasObject(By.pkg(getAppPackageName()) 292 .text("TestActivity" + activityNumber)), 293 DEFAULT_UI_TIMEOUT); 294 } 295 296 @Test 297 @NavigationModeSwitch 298 @PortraitLandscape testQuickSwitchFromHome()299 public void testQuickSwitchFromHome() throws Exception { 300 startTestActivity(2); 301 mLauncher.pressHome().quickSwitchToPreviousApp(); 302 assertTrue("The most recent task is not running after quick switching from home", 303 isTestActivityRunning(2)); 304 getAndAssertBackground(); 305 } 306 } 307