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.ui.workspace;
17 
18 import static com.android.launcher3.util.TestConstants.AppNames.CHROME_APP_NAME;
19 
20 import static org.junit.Assert.assertEquals;
21 import static org.junit.Assert.assertFalse;
22 import static org.junit.Assert.assertNotNull;
23 import static org.junit.Assert.assertTrue;
24 
25 import com.android.launcher3.Launcher;
26 import com.android.launcher3.LauncherState;
27 import com.android.launcher3.tapl.HomeAppIcon;
28 import com.android.launcher3.tapl.Workspace;
29 import com.android.launcher3.ui.AbstractLauncherUiTest;
30 import com.android.launcher3.util.LauncherLayoutBuilder;
31 import com.android.launcher3.util.TestUtil;
32 import com.android.launcher3.util.rule.ScreenRecordRule.ScreenRecord;
33 
34 import org.junit.After;
35 import org.junit.Test;
36 
37 /**
38  * Test the basic interactions of the Workspace, adding pages, moving the pages and removing pages.
39  */
40 public class TaplWorkspaceTest extends AbstractLauncherUiTest<Launcher> {
41 
42     private AutoCloseable mLauncherLayout;
43 
isWorkspaceScrollable(Launcher launcher)44     private static boolean isWorkspaceScrollable(Launcher launcher) {
45         return launcher.getWorkspace().getPageCount() > launcher.getWorkspace().getPanelCount();
46     }
47 
getCurrentWorkspacePage(Launcher launcher)48     private int getCurrentWorkspacePage(Launcher launcher) {
49         return launcher.getWorkspace().getCurrentPage();
50     }
51 
52     @After
tearDown()53     public void tearDown() throws Exception {
54         if (mLauncherLayout != null) {
55             mLauncherLayout.close();
56         }
57     }
58 
59     /**
60      * Add an icon and add a page to ensure the Workspace is scrollable and also make sure we can
61      * move between workspaces. After, make sure we can launch an app from the Workspace.
62      * @throws Exception if we can't set the defaults icons that will appear at the beginning.
63      */
64     @ScreenRecord // b/331261431
65     @Test
testWorkspace()66     public void testWorkspace() throws Exception {
67         // Set workspace  that includes the chrome Activity app icon on the hotseat.
68         LauncherLayoutBuilder builder = new LauncherLayoutBuilder()
69                 .atHotseat(0).putApp("com.android.chrome", "com.google.android.apps.chrome.Main");
70         mLauncherLayout = TestUtil.setLauncherDefaultLayout(mTargetContext, builder);
71         reinitializeLauncherData();
72 
73         final Workspace workspace = mLauncher.getWorkspace();
74 
75         // Test that ensureWorkspaceIsScrollable adds a page by dragging an icon there.
76         executeOnLauncher(launcher -> assertFalse("Initial workspace state is scrollable",
77                 isWorkspaceScrollable(launcher)));
78         assertEquals("Initial workspace doesn't have the correct page", workspace.pagesPerScreen(),
79                 workspace.getPageCount());
80         workspace.verifyWorkspaceAppIconIsGone("Chrome app was found on empty workspace",
81                 CHROME_APP_NAME);
82         workspace.ensureWorkspaceIsScrollable();
83 
84         executeOnLauncher(
85                 launcher -> assertEquals(
86                         "Ensuring workspace scrollable didn't switch to next screen",
87                         workspace.pagesPerScreen(), getCurrentWorkspacePage(launcher)));
88         executeOnLauncher(
89                 launcher -> assertTrue("ensureScrollable didn't make workspace scrollable",
90                         isWorkspaceScrollable(launcher)));
91         assertNotNull("ensureScrollable didn't add Chrome app",
92                 workspace.getWorkspaceAppIcon(CHROME_APP_NAME));
93 
94         // Test flinging workspace.
95         workspace.flingBackward();
96         assertTrue("Launcher internal state is not Home", isInState(() -> LauncherState.NORMAL));
97         executeOnLauncher(
98                 launcher -> assertEquals("Flinging back didn't switch workspace to page #0",
99                         0, getCurrentWorkspacePage(launcher)));
100 
101         workspace.flingForward();
102         executeOnLauncher(
103                 launcher -> assertEquals("Flinging forward didn't switch workspace to next screen",
104                         workspace.pagesPerScreen(), getCurrentWorkspacePage(launcher)));
105         assertTrue("Launcher internal state is not Home", isInState(() -> LauncherState.NORMAL));
106 
107         // Test starting a workspace app.
108         final HomeAppIcon app = workspace.getWorkspaceAppIcon(CHROME_APP_NAME);
109         assertNotNull("No Chrome app in workspace", app);
110     }
111 
112 
113     /**
114      * Similar to {@link TaplWorkspaceTest#testWorkspace} but here we also make sure we can delete
115      * the pages.
116      */
117     @Test
testAddAndDeletePageAndFling()118     public void testAddAndDeletePageAndFling() {
119         Workspace workspace = mLauncher.getWorkspace();
120         // Get the first app from the hotseat
121         HomeAppIcon hotSeatIcon = workspace.getHotseatAppIcon(0);
122         String appName = hotSeatIcon.getIconName();
123 
124         // Add one page by dragging app to page 1.
125         workspace.dragIcon(hotSeatIcon, workspace.pagesPerScreen());
126         assertEquals("Incorrect Page count Number",
127                 workspace.pagesPerScreen() * 2,
128                 workspace.getPageCount());
129 
130         // Delete one page by dragging app to hot seat.
131         workspace.getWorkspaceAppIcon(appName).dragToHotseat(0);
132 
133         // Refresh workspace to avoid using stale container error.
134         workspace = mLauncher.getWorkspace();
135         assertEquals("Incorrect Page count Number",
136                 workspace.pagesPerScreen(),
137                 workspace.getPageCount());
138     }
139 }
140