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