• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2019 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.launcher3.ui;
18 
19 import static androidx.test.InstrumentationRegistry.getInstrumentation;
20 
21 import static org.junit.Assert.assertEquals;
22 import static org.junit.Assert.assertFalse;
23 import static org.junit.Assert.assertNotNull;
24 import static org.junit.Assert.assertNull;
25 import static org.junit.Assert.assertTrue;
26 
27 import androidx.test.filters.LargeTest;
28 import androidx.test.runner.AndroidJUnit4;
29 
30 import com.android.launcher3.Launcher;
31 import com.android.launcher3.LauncherState;
32 import com.android.launcher3.popup.ArrowPopup;
33 import com.android.launcher3.tapl.AllApps;
34 import com.android.launcher3.tapl.AppIcon;
35 import com.android.launcher3.tapl.AppIconMenu;
36 import com.android.launcher3.tapl.AppIconMenuItem;
37 import com.android.launcher3.tapl.TestHelpers;
38 import com.android.launcher3.tapl.Widgets;
39 import com.android.launcher3.tapl.Workspace;
40 import com.android.launcher3.views.OptionsPopupView;
41 import com.android.launcher3.widget.WidgetsFullSheet;
42 import com.android.launcher3.widget.WidgetsRecyclerView;
43 
44 import org.junit.Before;
45 import org.junit.Ignore;
46 import org.junit.Test;
47 import org.junit.runner.RunWith;
48 
49 @LargeTest
50 @RunWith(AndroidJUnit4.class)
51 public class TaplTestsLauncher3 extends AbstractLauncherUiTest {
52     private static final String APP_NAME = "LauncherTestApp";
53 
54     @Before
setUp()55     public void setUp() throws Exception {
56         super.setUp();
57         initialize(this);
58     }
59 
initialize(AbstractLauncherUiTest test)60     public static void initialize(AbstractLauncherUiTest test) throws Exception {
61         test.clearLauncherData();
62         test.mDevice.pressHome();
63         test.waitForLauncherCondition("Launcher didn't start", launcher -> launcher != null);
64         test.waitForState("Launcher internal state didn't switch to Home", LauncherState.NORMAL);
65         test.waitForResumed("Launcher internal state is still Background");
66         // Check that we switched to home.
67         test.mLauncher.getWorkspace();
68     }
69 
70     // Please don't add negative test cases for methods that fail only after a long wait.
expectFail(String message, Runnable action)71     public static void expectFail(String message, Runnable action) {
72         boolean failed = false;
73         try {
74             action.run();
75         } catch (AssertionError e) {
76             failed = true;
77         }
78         assertTrue(message, failed);
79     }
80 
isWorkspaceScrollable(Launcher launcher)81     private boolean isWorkspaceScrollable(Launcher launcher) {
82         return launcher.getWorkspace().getPageCount() > 1;
83     }
84 
getCurrentWorkspacePage(Launcher launcher)85     private int getCurrentWorkspacePage(Launcher launcher) {
86         return launcher.getWorkspace().getCurrentPage();
87     }
88 
getWidgetsView(Launcher launcher)89     private WidgetsRecyclerView getWidgetsView(Launcher launcher) {
90         return WidgetsFullSheet.getWidgetsView(launcher);
91     }
92 
93     @Test
testDevicePressMenu()94     public void testDevicePressMenu() throws Exception {
95         mDevice.pressMenu();
96         mDevice.waitForIdle();
97         executeOnLauncher(
98                 launcher -> assertTrue("Launcher internal state didn't switch to Showing Menu",
99                         OptionsPopupView.getOptionsPopup(launcher) != null));
100         // Check that pressHome works when the menu is shown.
101         mLauncher.pressHome();
102     }
103 
104     @Test
105     @Ignore
testPressHomeOnAllAppsContextMenu()106     public void testPressHomeOnAllAppsContextMenu() throws Exception {
107         final AllApps allApps = mLauncher.getWorkspace().switchToAllApps();
108         allApps.freeze();
109         try {
110             allApps.getAppIcon("TestActivity7").openMenu();
111         } finally {
112             allApps.unfreeze();
113         }
114         mLauncher.pressHome();
115     }
116 
runAllAppsTest(AbstractLauncherUiTest test, AllApps allApps)117     public static void runAllAppsTest(AbstractLauncherUiTest test, AllApps allApps) {
118         allApps.freeze();
119         try {
120             assertNotNull("allApps parameter is null", allApps);
121 
122             assertTrue(
123                     "Launcher internal state is not All Apps",
124                     test.isInState(LauncherState.ALL_APPS));
125 
126             // Test flinging forward and backward.
127             test.executeOnLauncher(launcher -> assertEquals(
128                     "All Apps started in already scrolled state", 0,
129                     test.getAllAppsScroll(launcher)));
130 
131             allApps.flingForward();
132             assertTrue("Launcher internal state is not All Apps",
133                     test.isInState(LauncherState.ALL_APPS));
134             final Integer flingForwardY = test.getFromLauncher(
135                     launcher -> test.getAllAppsScroll(launcher));
136             test.executeOnLauncher(
137                     launcher -> assertTrue("flingForward() didn't scroll App Apps",
138                             flingForwardY > 0));
139 
140             allApps.flingBackward();
141             assertTrue(
142                     "Launcher internal state is not All Apps",
143                     test.isInState(LauncherState.ALL_APPS));
144             final Integer flingBackwardY = test.getFromLauncher(
145                     launcher -> test.getAllAppsScroll(launcher));
146             test.executeOnLauncher(launcher -> assertTrue("flingBackward() didn't scroll App Apps",
147                     flingBackwardY < flingForwardY));
148 
149             // Test scrolling down to YouTube.
150             assertNotNull("All apps: can't fine YouTube", allApps.getAppIcon("YouTube"));
151             // Test scrolling up to Camera.
152             assertNotNull("All apps: can't fine Camera", allApps.getAppIcon("Camera"));
153             // Test failing to find a non-existing app.
154             final AllApps allAppsFinal = allApps;
155             expectFail("All apps: could find a non-existing app",
156                     () -> allAppsFinal.getAppIcon("NO APP"));
157 
158             assertTrue(
159                     "Launcher internal state is not All Apps",
160                     test.isInState(LauncherState.ALL_APPS));
161         } finally {
162             allApps.unfreeze();
163         }
164     }
165 
166     @Test
167     @PortraitLandscape
testWorkspaceSwitchToAllApps()168     public void testWorkspaceSwitchToAllApps() {
169         assertNotNull("switchToAllApps() returned null",
170                 mLauncher.getWorkspace().switchToAllApps());
171         assertTrue("Launcher internal state is not All Apps", isInState(LauncherState.ALL_APPS));
172     }
173 
174     @Test
testWorkspace()175     public void testWorkspace() throws Exception {
176         final Workspace workspace = mLauncher.getWorkspace();
177 
178         // Test that ensureWorkspaceIsScrollable adds a page by dragging an icon there.
179         executeOnLauncher(launcher -> assertFalse("Initial workspace state is scrollable",
180                 isWorkspaceScrollable(launcher)));
181         assertNull("Chrome app was found on empty workspace",
182                 workspace.tryGetWorkspaceAppIcon("Chrome"));
183 
184         workspace.ensureWorkspaceIsScrollable();
185 
186         executeOnLauncher(
187                 launcher -> assertEquals("Ensuring workspace scrollable didn't switch to page #1",
188                         1, getCurrentWorkspacePage(launcher)));
189         executeOnLauncher(
190                 launcher -> assertTrue("ensureScrollable didn't make workspace scrollable",
191                         isWorkspaceScrollable(launcher)));
192         assertNotNull("ensureScrollable didn't add Chrome app",
193                 workspace.tryGetWorkspaceAppIcon("Chrome"));
194 
195         // Test flinging workspace.
196         workspace.flingBackward();
197         assertTrue("Launcher internal state is not Home", isInState(LauncherState.NORMAL));
198         executeOnLauncher(
199                 launcher -> assertEquals("Flinging back didn't switch workspace to page #0",
200                         0, getCurrentWorkspacePage(launcher)));
201 
202         workspace.flingForward();
203         executeOnLauncher(
204                 launcher -> assertEquals("Flinging forward didn't switch workspace to page #1",
205                         1, getCurrentWorkspacePage(launcher)));
206         assertTrue("Launcher internal state is not Home", isInState(LauncherState.NORMAL));
207 
208         // Test starting a workspace app.
209         final AppIcon app = workspace.tryGetWorkspaceAppIcon("Chrome");
210         assertNotNull("No Chrome app in workspace", app);
211     }
212 
runIconLaunchFromAllAppsTest(AbstractLauncherUiTest test, AllApps allApps)213     public static void runIconLaunchFromAllAppsTest(AbstractLauncherUiTest test, AllApps allApps) {
214         allApps.freeze();
215         try {
216             final AppIcon app = allApps.getAppIcon("TestActivity7");
217             assertNotNull("AppIcon.launch returned null", app.launch(getAppPackageName()));
218             test.executeOnLauncher(launcher -> assertTrue(
219                     "Launcher activity is the top activity; expecting another activity to be the top "
220                             + "one",
221                     test.isInBackground(launcher)));
222         } finally {
223             allApps.unfreeze();
224         }
225     }
226 
227     @Test
228     @PortraitLandscape
testAppIconLaunchFromAllAppsFromHome()229     public void testAppIconLaunchFromAllAppsFromHome() throws Exception {
230         final AllApps allApps = mLauncher.getWorkspace().switchToAllApps();
231         assertTrue("Launcher internal state is not All Apps", isInState(LauncherState.ALL_APPS));
232 
233         runIconLaunchFromAllAppsTest(this, allApps);
234     }
235 
236     @Test
237     @PortraitLandscape
testWidgets()238     public void testWidgets() throws Exception {
239         // Test opening widgets.
240         executeOnLauncher(launcher ->
241                 assertTrue("Widgets is initially opened", getWidgetsView(launcher) == null));
242         Widgets widgets = mLauncher.getWorkspace().openAllWidgets();
243         assertNotNull("openAllWidgets() returned null", widgets);
244         widgets = mLauncher.getAllWidgets();
245         assertNotNull("getAllWidgets() returned null", widgets);
246         executeOnLauncher(launcher ->
247                 assertTrue("Widgets is not shown", getWidgetsView(launcher).isShown()));
248         executeOnLauncher(launcher -> assertEquals("Widgets is scrolled upon opening",
249                 0, getWidgetsScroll(launcher)));
250 
251         // Test flinging widgets.
252         widgets.flingForward();
253         Integer flingForwardY = getFromLauncher(launcher -> getWidgetsScroll(launcher));
254         executeOnLauncher(launcher -> assertTrue("Flinging forward didn't scroll widgets",
255                 flingForwardY > 0));
256 
257         widgets.flingBackward();
258         executeOnLauncher(launcher -> assertTrue("Flinging backward didn't scroll widgets",
259                 getWidgetsScroll(launcher) < flingForwardY));
260 
261         mLauncher.pressHome();
262         waitForLauncherCondition("Widgets were not closed",
263                 launcher -> getWidgetsView(launcher) == null);
264     }
265 
getWidgetsScroll(Launcher launcher)266     private int getWidgetsScroll(Launcher launcher) {
267         return getWidgetsView(launcher).getCurrentScrollY();
268     }
269 
isOptionsPopupVisible(Launcher launcher)270     private boolean isOptionsPopupVisible(Launcher launcher) {
271         final ArrowPopup popup = OptionsPopupView.getOptionsPopup(launcher);
272         return popup != null && popup.isShown();
273     }
274 
275     @Test
276     @PortraitLandscape
testLaunchMenuItem()277     public void testLaunchMenuItem() throws Exception {
278         final AllApps allApps = mLauncher.
279                 getWorkspace().
280                 switchToAllApps();
281         allApps.freeze();
282         try {
283             final AppIconMenu menu = allApps.
284                     getAppIcon(APP_NAME).
285                     openMenu();
286 
287             executeOnLauncher(
288                     launcher -> assertTrue("Launcher internal state didn't switch to Showing Menu",
289                             isOptionsPopupVisible(launcher)));
290 
291             menu.getMenuItem(1).launch(getAppPackageName());
292         } finally {
293             allApps.unfreeze();
294         }
295     }
296 
297     @Test
298     @PortraitLandscape
testDragAppIcon()299     public void testDragAppIcon() throws Throwable {
300         // 1. Open all apps and wait for load complete.
301         // 2. Drag icon to homescreen.
302         // 3. Verify that the icon works on homescreen.
303         final AllApps allApps = mLauncher.getWorkspace().
304                 switchToAllApps();
305         allApps.freeze();
306         try {
307             allApps.
308                     getAppIcon(APP_NAME).
309                     dragToWorkspace().
310                     getWorkspaceAppIcon(APP_NAME).
311                     launch(getAppPackageName());
312         } finally {
313             allApps.unfreeze();
314         }
315         executeOnLauncher(launcher -> assertTrue(
316                 "Launcher activity is the top activity; expecting another activity to be the top "
317                         + "one",
318                 isInBackground(launcher)));
319     }
320 
321     @Test
322     @PortraitLandscape
testDragShortcut()323     public void testDragShortcut() throws Throwable {
324         // 1. Open all apps and wait for load complete.
325         // 2. Find the app and long press it to show shortcuts.
326         // 3. Press icon center until shortcuts appear
327         final AllApps allApps = mLauncher.
328                 getWorkspace().
329                 switchToAllApps();
330         allApps.freeze();
331         try {
332             final AppIconMenuItem menuItem = allApps.
333                     getAppIcon(APP_NAME).
334                     openMenu().
335                     getMenuItem(0);
336             final String shortcutName = menuItem.getText();
337 
338             // 4. Drag the first shortcut to the home screen.
339             // 5. Verify that the shortcut works on home screen
340             //    (the app opens and has the same text as the shortcut).
341             menuItem.
342                     dragToWorkspace().
343                     getWorkspaceAppIcon(shortcutName).
344                     launch(getAppPackageName());
345         } finally {
346             allApps.unfreeze();
347         }
348     }
349 
getAppPackageName()350     public static String getAppPackageName() {
351         return getInstrumentation().getContext().getPackageName();
352     }
353 }
354