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