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