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.dragging; 17 18 import static com.android.launcher3.testing.shared.TestProtocol.TEST_DRAG_APP_ICON_TO_MULTIPLE_WORKSPACES_FAILURE; 19 import static com.android.launcher3.util.TestConstants.AppNames.GMAIL_APP_NAME; 20 import static com.android.launcher3.util.TestConstants.AppNames.MAPS_APP_NAME; 21 import static com.android.launcher3.util.TestConstants.AppNames.PHOTOS_APP_NAME; 22 import static com.android.launcher3.util.TestConstants.AppNames.STORE_APP_NAME; 23 import static com.android.launcher3.util.TestConstants.AppNames.TEST_APP_NAME; 24 25 import static org.junit.Assert.assertEquals; 26 import static org.junit.Assert.assertNotNull; 27 import static org.junit.Assert.assertTrue; 28 29 import android.graphics.Point; 30 import android.os.SystemClock; 31 import android.platform.test.annotations.PlatinumTest; 32 import android.util.Log; 33 34 import com.android.launcher3.Launcher; 35 import com.android.launcher3.tapl.Folder; 36 import com.android.launcher3.tapl.FolderIcon; 37 import com.android.launcher3.tapl.HomeAllApps; 38 import com.android.launcher3.tapl.HomeAppIcon; 39 import com.android.launcher3.tapl.HomeAppIconMenuItem; 40 import com.android.launcher3.tapl.Workspace; 41 import com.android.launcher3.ui.AbstractLauncherUiTest; 42 import com.android.launcher3.ui.PortraitLandscapeRunner.PortraitLandscape; 43 import com.android.launcher3.util.TestUtil; 44 import com.android.launcher3.util.rule.ScreenRecordRule; 45 46 import org.junit.Test; 47 48 /** 49 * This test run in both Out of process (Oop) and in-process (Ipc). 50 * Tests multiple facets of the drag interaction in the Launcher: 51 * * Can create a folder by dragging items. 52 * * Can create a shortcut by dragging it to Workspace. 53 * * Can create shortcuts in multiple spaces in the Workspace. 54 * * Can cancel a drag icon to workspace by dragging outside of the Workspace. 55 * * Can drag an icon from AllApps into the workspace 56 * * Can drag an icon on the Workspace to other positions of the Workspace. 57 */ 58 public class TaplDragTest extends AbstractLauncherUiTest<Launcher> { 59 60 /** 61 * Adds two icons to the Workspace and combines them into a folder, then makes sure the icons 62 * are no longer in the Workspace then adds a third one to test adding an icon to an existing 63 * folder instead of creating one and drags it to the folder. 64 */ 65 @Test 66 @PortraitLandscape 67 @PlatinumTest(focusArea = "launcher") testDragToFolder()68 public void testDragToFolder() { 69 // TODO: add the use case to drag an icon to an existing folder. Currently it either fails 70 // on tablets or phones due to difference in resolution. 71 final HomeAppIcon playStoreIcon = createShortcutIfNotExist(STORE_APP_NAME, 0, 1); 72 final HomeAppIcon photosIcon = createShortcutInCenterIfNotExist(PHOTOS_APP_NAME); 73 74 FolderIcon folderIcon = photosIcon.dragToIcon(playStoreIcon); 75 Folder folder = folderIcon.open(); 76 folder.getAppIcon(STORE_APP_NAME); 77 folder.getAppIcon(PHOTOS_APP_NAME); 78 Workspace workspace = folder.close(); 79 80 workspace.verifyWorkspaceAppIconIsGone(STORE_APP_NAME + " should be moved to a folder.", 81 STORE_APP_NAME); 82 workspace.verifyWorkspaceAppIconIsGone(PHOTOS_APP_NAME + " should be moved to a folder.", 83 PHOTOS_APP_NAME); 84 85 final HomeAppIcon mapIcon = createShortcutInCenterIfNotExist(MAPS_APP_NAME); 86 folder = mapIcon.dragToFolder(folderIcon); 87 folder.getAppIcon(MAPS_APP_NAME); 88 workspace = folder.close(); 89 90 workspace.verifyWorkspaceAppIconIsGone(MAPS_APP_NAME + " should be moved to a folder.", 91 MAPS_APP_NAME); 92 } 93 94 /** 95 * Adds two icons to the Workspace and combines them into a folder, then makes sure we are able 96 * to remove an icon from the folder and that the folder ceases to exist since it only has one 97 * icon left. 98 */ 99 @Test testDragOutOfFolder()100 public void testDragOutOfFolder() { 101 final HomeAppIcon playStoreIcon = createShortcutIfNotExist(STORE_APP_NAME, 0, 1); 102 final HomeAppIcon photosIcon = createShortcutInCenterIfNotExist(PHOTOS_APP_NAME); 103 FolderIcon folderIcon = photosIcon.dragToIcon(playStoreIcon); 104 Folder folder = folderIcon.open(); 105 folder.getAppIcon(STORE_APP_NAME).internalDragToWorkspace(false, false); 106 assertNotNull(mLauncher.getWorkspace().tryGetWorkspaceAppIcon(STORE_APP_NAME)); 107 assertNotNull(mLauncher.getWorkspace().tryGetWorkspaceAppIcon(PHOTOS_APP_NAME)); 108 } 109 110 /** Drags a shortcut from a long press menu into the workspace. 111 * 1. Open all apps and wait for load complete. 112 * 2. Find the app and long press it to show shortcuts. 113 * 3. Press icon center until shortcuts appear 114 * 4. Drags shortcut to any free space in the Workspace. 115 */ 116 @Test 117 @PortraitLandscape 118 @PlatinumTest(focusArea = "launcher") testDragShortcut()119 public void testDragShortcut() { 120 121 final HomeAllApps allApps = mLauncher 122 .getWorkspace() 123 .switchToAllApps(); 124 allApps.freeze(); 125 try { 126 final HomeAppIconMenuItem menuItem = allApps 127 .getAppIcon(TEST_APP_NAME) 128 .openDeepShortcutMenu() 129 .getMenuItem(0); 130 final String actualShortcutName = menuItem.getText(); 131 final String expectedShortcutName = "Shortcut 1"; 132 133 assertEquals(expectedShortcutName, actualShortcutName); 134 menuItem.dragToWorkspace(false, false); 135 mLauncher.getWorkspace().getWorkspaceAppIcon(expectedShortcutName) 136 .launch(getAppPackageName()); 137 } finally { 138 allApps.unfreeze(); 139 } 140 } 141 142 /** 143 * Similar to testDragShortcut but it adds shortcuts to multiple positions of the Workspace 144 * namely the corners and the center. 145 */ 146 @Test 147 @PortraitLandscape 148 @PlatinumTest(focusArea = "launcher") testDragShortcutToMultipleWorkspaceCells()149 public void testDragShortcutToMultipleWorkspaceCells() { 150 Point[] targets = TestUtil.getCornersAndCenterPositions(mLauncher); 151 152 for (Point target : targets) { 153 final HomeAllApps allApps = mLauncher.getWorkspace().switchToAllApps(); 154 allApps.freeze(); 155 try { 156 allApps.getAppIcon(TEST_APP_NAME) 157 .openDeepShortcutMenu() 158 .getMenuItem(0) 159 .dragToWorkspace(target.x, target.y); 160 } finally { 161 allApps.unfreeze(); 162 } 163 } 164 } 165 166 /** 167 * Drags an icon to the workspace but instead of submitting it, it gets dragged outside of the 168 * Workspace to cancel it. 169 */ 170 171 @Test 172 @PortraitLandscape 173 @PlatinumTest(focusArea = "launcher") testDragAndCancelAppIcon()174 public void testDragAndCancelAppIcon() { 175 final HomeAppIcon homeAppIcon = createShortcutInCenterIfNotExist(GMAIL_APP_NAME); 176 Point positionBeforeDrag = 177 mLauncher.getWorkspace().getWorkspaceIconsPositions().get(GMAIL_APP_NAME); 178 assertNotNull("App not found in Workspace before dragging.", positionBeforeDrag); 179 180 mLauncher.getWorkspace().dragAndCancelAppIcon(homeAppIcon); 181 182 Point positionAfterDrag = 183 mLauncher.getWorkspace().getWorkspaceIconsPositions().get(GMAIL_APP_NAME); 184 assertNotNull("App not found in Workspace after dragging.", positionAfterDrag); 185 assertEquals("App not returned to same position in Workspace after drag & cancel", 186 positionBeforeDrag, positionAfterDrag); 187 } 188 189 /** 190 * Drags app icon from AllApps into the Workspace. 191 * 1. Open all apps and wait for load complete. 192 * 2. Drag icon to homescreen. 193 * 3. Verify that the icon works on homescreen. 194 */ 195 @PlatinumTest(focusArea = "launcher") 196 @Test 197 @PortraitLandscape 198 @ScreenRecordRule.ScreenRecord // b/343953783 testDragAppIcon()199 public void testDragAppIcon() { 200 201 final HomeAllApps allApps = mLauncher.getWorkspace().switchToAllApps(); 202 allApps.freeze(); 203 try { 204 allApps.getAppIcon(TEST_APP_NAME).dragToWorkspace(false, false); 205 mLauncher.getWorkspace().getWorkspaceAppIcon(TEST_APP_NAME).launch(getAppPackageName()); 206 } finally { 207 allApps.unfreeze(); 208 } 209 executeOnLauncher(launcher -> assertTrue( 210 "Launcher activity is the top activity; expecting another activity to be the top " 211 + "one", 212 isInLaunchedApp(launcher))); 213 } 214 215 /** 216 * Similar start to testDragAppIcon but after dragging the icon to the workspace, it drags the 217 * icon inside of the workspace to different positions. 218 * @throws Exception 219 */ 220 @Test 221 @PortraitLandscape 222 @PlatinumTest(focusArea = "launcher") testDragAppIconToMultipleWorkspaceCells()223 public void testDragAppIconToMultipleWorkspaceCells() throws Exception { 224 long startTime, endTime, elapsedTime; 225 Point[] targets = TestUtil.getCornersAndCenterPositions(mLauncher); 226 reinitializeLauncherData(true); 227 // test to move a shortcut to other cell. 228 final HomeAppIcon launcherTestAppIcon = createShortcutInCenterIfNotExist(TEST_APP_NAME); 229 for (Point target : targets) { 230 startTime = SystemClock.uptimeMillis(); 231 Log.d(TEST_DRAG_APP_ICON_TO_MULTIPLE_WORKSPACES_FAILURE, 232 "TaplDragTest.java.testDragAppIconToMultipleWorkspaceCells: shortcut name: " 233 + launcherTestAppIcon.getIconName() 234 + " | target cell coordinates: (" + target.x + ", " + target.y 235 + ") | start time: " + startTime); 236 launcherTestAppIcon.dragToWorkspace(target.x, target.y); 237 endTime = SystemClock.uptimeMillis(); 238 elapsedTime = endTime - startTime; 239 Log.d("testDragAppIconToWorkspaceCellTime", 240 "Milliseconds taken to move shortcut to other cell: " + elapsedTime); 241 } 242 } 243 } 244