1 /*
2  * Copyright (C) 2023 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 package com.android.launcher3.allapps;
17 
18 import static com.android.launcher3.util.TestUtil.expectFail;
19 
20 import static org.junit.Assert.assertEquals;
21 import static org.junit.Assert.assertNotNull;
22 import static org.junit.Assert.assertTrue;
23 import static org.junit.Assume.assumeTrue;
24 
25 import android.content.Intent;
26 import android.platform.test.annotations.PlatinumTest;
27 
28 import androidx.test.filters.FlakyTest;
29 import androidx.test.platform.app.InstrumentationRegistry;
30 
31 import com.android.launcher3.Launcher;
32 import com.android.launcher3.LauncherState;
33 import com.android.launcher3.tapl.AllApps;
34 import com.android.launcher3.ui.AbstractLauncherUiTest;
35 import com.android.launcher3.ui.PortraitLandscapeRunner.PortraitLandscape;
36 import com.android.launcher3.util.rule.ScreenRecordRule;
37 
38 import org.junit.Test;
39 
40 /**
41  * Test that we can open and close the all apps in multiple situations.
42  * The test runs in Out of process (Oop) and in process.
43  */
44 public class TaplOpenCloseAllAppsTest extends AbstractLauncherUiTest<Launcher> {
45 
46     public static final String READ_DEVICE_CONFIG_PERMISSION =
47             "android.permission.READ_DEVICE_CONFIG";
48 
49     /**
50      * Make sure we can go home after pressing the context menu on an Icon on the AllApps.
51      */
52     @Test
testPressHomeOnAllAppsContextMenu()53     public void testPressHomeOnAllAppsContextMenu() {
54         final AllApps allApps = mLauncher.getWorkspace().switchToAllApps();
55         allApps.freeze();
56         try {
57             allApps.getAppIcon("TestActivity7").openMenu();
58         } finally {
59             allApps.unfreeze();
60         }
61         mLauncher.goHome();
62     }
63 
64     /**
65      * Make sure we can open AllApps from the Workspace.
66      */
67     @Test
68     @PortraitLandscape
testWorkspaceSwitchToAllApps()69     public void testWorkspaceSwitchToAllApps() {
70         assertNotNull("switchToAllApps() returned null",
71                 mLauncher.getWorkspace().switchToAllApps());
72         assertTrue("Launcher internal state is not All Apps",
73                 isInState(() -> LauncherState.ALL_APPS));
74     }
75 
76     /**
77      * Make sure we can go to Workspace from AllApps
78      */
79     @Test
80     @PortraitLandscape
testAllAppsSwitchToWorkspace()81     public void testAllAppsSwitchToWorkspace() {
82         assertNotNull("switchToWorkspace() returned null",
83                 mLauncher.getWorkspace().switchToAllApps()
84                         .switchToWorkspace(/* swipeDown= */ true));
85         assertTrue("Launcher internal state is not Workspace",
86                 isInState(() -> LauncherState.NORMAL));
87     }
88 
89     /**
90      * Make sure the swipe up gesture can take us back to the workspace from AllApps
91      */
92     @PlatinumTest(focusArea = "launcher")
93     @Test
94     @PortraitLandscape
testAllAppsSwipeUpToWorkspace()95     public void testAllAppsSwipeUpToWorkspace() {
96         assertNotNull("testAllAppsSwipeUpToWorkspace() returned null",
97                 mLauncher.getWorkspace().switchToAllApps()
98                         .switchToWorkspace(/* swipeDown= */ false));
99         assertTrue("Launcher internal state is not Workspace",
100                 isInState(() -> LauncherState.NORMAL));
101     }
102 
103     /**
104      * Make sure we can go to the Workspace from AllApps on tablets by tapping on the background.
105      */
106     @Test
107     @PortraitLandscape
testAllAppsDeadzoneForTablet()108     public void testAllAppsDeadzoneForTablet() {
109         assumeTrue(mLauncher.isTablet());
110 
111         mLauncher.getWorkspace().switchToAllApps().dismissByTappingOutsideForTablet(
112                 true /* tapRight */);
113         mLauncher.getWorkspace().switchToAllApps().dismissByTappingOutsideForTablet(
114                 false /* tapRight */);
115     }
116 
117     /**
118      * Make sure that AllApps closes when pressing the home button
119      */
120     @Test
121     @PortraitLandscape
122     @PlatinumTest(focusArea = "launcher")
testAllAppsFromHome()123     public void testAllAppsFromHome() {
124         // Test opening all apps
125         assertNotNull("switchToAllApps() returned null",
126                 mLauncher.getWorkspace().switchToAllApps());
127 
128         runAllAppsTest(mLauncher.getAllApps());
129 
130         // Testing pressHome.
131         assertTrue("Launcher internal state is not All Apps",
132                 isInState(() -> LauncherState.ALL_APPS));
133         assertNotNull("pressHome returned null", mLauncher.goHome());
134         assertTrue("Launcher internal state is not Home",
135                 isInState(() -> LauncherState.NORMAL));
136         assertNotNull("getHome returned null", mLauncher.getWorkspace());
137     }
138 
139     /**
140      * Makes sure the state of AllApps is correct.
141      */
runAllAppsTest(AllApps allApps)142     public void runAllAppsTest(AllApps allApps) {
143         allApps.freeze();
144         try {
145             assertNotNull("allApps parameter is null", allApps);
146 
147             assertTrue(
148                     "Launcher internal state is not All Apps",
149                     isInState(() -> LauncherState.ALL_APPS));
150 
151             // Test flinging forward and backward.
152             executeOnLauncher(launcher -> assertEquals(
153                     "All Apps started in already scrolled state", 0,
154                     getAllAppsScroll(launcher)));
155 
156             allApps.flingForward();
157             assertTrue("Launcher internal state is not All Apps",
158                     isInState(() -> LauncherState.ALL_APPS));
159             final Integer flingForwardY = getFromLauncher(
160                     launcher -> getAllAppsScroll(launcher));
161             executeOnLauncher(
162                     launcher -> assertTrue("flingForward() didn't scroll App Apps",
163                             flingForwardY > 0));
164 
165             allApps.flingBackward();
166             assertTrue(
167                     "Launcher internal state is not All Apps",
168                     isInState(() -> LauncherState.ALL_APPS));
169             final Integer flingBackwardY = getFromLauncher(
170                     launcher -> getAllAppsScroll(launcher));
171             executeOnLauncher(launcher -> assertTrue("flingBackward() didn't scroll App Apps",
172                     flingBackwardY < flingForwardY));
173 
174             // Test scrolling down to the end of the app list.
175             assertNotNull("All apps: can't find YouTube", allApps.getAppIcon("ZZZ"));
176             // Test scrolling up to the beginning oof the app list.
177             assertNotNull("All apps: can't find Camera", allApps.getAppIcon("AAA"));
178             // Test failing to find a non-existing app.
179             final AllApps allAppsFinal = allApps;
180             expectFail("All apps: could find a non-existing app",
181                     () -> allAppsFinal.getAppIcon("NO APP"));
182 
183             assertTrue(
184                     "Launcher internal state is not All Apps",
185                     isInState(() -> LauncherState.ALL_APPS));
186         } finally {
187             allApps.unfreeze();
188         }
189     }
190 
191     /**
192      * Makes sure that when pressing back when AllApps is open we go back to the Home screen.
193      */
194     @FlakyTest(bugId = 256615483)
195     @Test
196     @PortraitLandscape
testPressBackFromAllAppsToHome()197     public void testPressBackFromAllAppsToHome() {
198         InstrumentationRegistry.getInstrumentation().getUiAutomation().adoptShellPermissionIdentity(
199                 READ_DEVICE_CONFIG_PERMISSION);
200         mLauncher
201                 .getWorkspace()
202                 .switchToAllApps()
203                 .pressBackToWorkspace();
204         waitForState("Launcher internal state didn't switch to Home", () -> LauncherState.NORMAL);
205         startAppFast(resolveSystemApp(Intent.CATEGORY_APP_CALCULATOR));
206         mLauncher.getLaunchedAppState().pressBackToWorkspace();
207         waitForState("Launcher internal state didn't switch to Home", () -> LauncherState.NORMAL);
208     }
209 
210     @Test
testDismissAllAppsWithEscKey()211     public void testDismissAllAppsWithEscKey() {
212         mLauncher.goHome().switchToAllApps().dismissByEscKey();
213         waitForState("Launcher internal state didn't switch to Home", () -> LauncherState.NORMAL);
214     }
215 }
216