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.util.TestConstants.AppNames.GMAIL_APP_NAME; 19 import static com.android.launcher3.util.TestConstants.AppNames.MAPS_APP_NAME; 20 import static com.android.launcher3.util.TestConstants.AppNames.PHOTOS_APP_NAME; 21 import static com.android.launcher3.util.TestConstants.AppNames.STORE_APP_NAME; 22 import static com.android.launcher3.util.TestConstants.AppNames.TEST_APP_NAME; 23 24 import static org.junit.Assert.assertEquals; 25 import static org.junit.Assert.assertNotNull; 26 import static org.junit.Assert.assertTrue; 27 28 import android.graphics.Point; 29 import android.os.SystemClock; 30 import android.platform.test.annotations.PlatinumTest; 31 import android.util.Log; 32 33 import com.android.launcher3.Launcher; 34 import com.android.launcher3.tapl.Folder; 35 import com.android.launcher3.tapl.FolderIcon; 36 import com.android.launcher3.tapl.HomeAllApps; 37 import com.android.launcher3.tapl.HomeAppIcon; 38 import com.android.launcher3.tapl.HomeAppIconMenuItem; 39 import com.android.launcher3.tapl.Workspace; 40 import com.android.launcher3.ui.AbstractLauncherUiTest; 41 import com.android.launcher3.ui.PortraitLandscapeRunner.PortraitLandscape; 42 import com.android.launcher3.util.TestUtil; 43 import com.android.launcher3.util.rule.ScreenRecordRule; 44 45 import org.junit.Test; 46 47 /** 48 * This test run in both Out of process (Oop) and in-process (Ipc). 49 * Tests multiple facets of the drag interaction in the Launcher: 50 * * Can create a folder by dragging items. 51 * * Can create a shortcut by dragging it to Workspace. 52 * * Can create shortcuts in multiple spaces in the Workspace. 53 * * Can cancel a drag icon to workspace by dragging outside of the Workspace. 54 * * Can drag an icon from AllApps into the workspace 55 * * Can drag an icon on the Workspace to other positions of the Workspace. 56 */ 57 public class TaplDragTest extends AbstractLauncherUiTest<Launcher> { 58 59 /** 60 * Adds two icons to the Workspace and combines them into a folder, then makes sure the icons 61 * are no longer in the Workspace then adds a third one to test adding an icon to an existing 62 * folder instead of creating one and drags it to the folder. 63 */ 64 @Test 65 @PortraitLandscape 66 @PlatinumTest(focusArea = "launcher") 67 @ScreenRecordRule.ScreenRecord // b/383917141 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().getWorkspaceIconPosition(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().getWorkspaceIconPosition(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 testDragAppIcon()198 public void testDragAppIcon() { 199 200 final HomeAllApps allApps = mLauncher.getWorkspace().switchToAllApps(); 201 allApps.freeze(); 202 try { 203 allApps.getAppIcon(TEST_APP_NAME).dragToWorkspace(false, false); 204 mLauncher.getWorkspace().getWorkspaceAppIcon(TEST_APP_NAME).launch(getAppPackageName()); 205 } finally { 206 allApps.unfreeze(); 207 } 208 executeOnLauncher(launcher -> assertTrue( 209 "Launcher activity is the top activity; expecting another activity to be the top " 210 + "one", 211 isInLaunchedApp(launcher))); 212 } 213 214 /** 215 * Similar start to testDragAppIcon but after dragging the icon to the workspace, it drags the 216 * icon inside of the workspace to different positions. 217 * @throws Exception 218 */ 219 @Test 220 @PortraitLandscape 221 @PlatinumTest(focusArea = "launcher") testDragAppIconToMultipleWorkspaceCells()222 public void testDragAppIconToMultipleWorkspaceCells() throws Exception { 223 long startTime, endTime, elapsedTime; 224 Point[] targets = TestUtil.getCornersAndCenterPositions(mLauncher); 225 reinitializeLauncherData(true); 226 // test to move a shortcut to other cell. 227 final HomeAppIcon launcherTestAppIcon = createShortcutInCenterIfNotExist(TEST_APP_NAME); 228 for (Point target : targets) { 229 startTime = SystemClock.uptimeMillis(); 230 launcherTestAppIcon.dragToWorkspace(target.x, target.y); 231 endTime = SystemClock.uptimeMillis(); 232 elapsedTime = endTime - startTime; 233 Log.d("testDragAppIconToWorkspaceCellTime", 234 "Milliseconds taken to move shortcut to other cell: " + elapsedTime); 235 } 236 } 237 } 238