1 /* 2 * Copyright (C) 2018 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.tapl; 18 19 import static com.android.launcher3.testing.TestProtocol.ALL_APPS_STATE_ORDINAL; 20 21 import static junit.framework.TestCase.assertTrue; 22 23 import android.graphics.Point; 24 import android.graphics.Rect; 25 import android.os.SystemClock; 26 import android.view.KeyEvent; 27 import android.view.MotionEvent; 28 29 import androidx.annotation.NonNull; 30 import androidx.annotation.Nullable; 31 import androidx.test.uiautomator.By; 32 import androidx.test.uiautomator.Direction; 33 import androidx.test.uiautomator.UiObject2; 34 35 import com.android.launcher3.testing.TestProtocol; 36 37 /** 38 * Operations on the workspace screen. 39 */ 40 public final class Workspace extends Home { 41 private static final int DRAG_DURACTION = 2000; 42 private static final int FLING_STEPS = 10; 43 private final UiObject2 mHotseat; 44 Workspace(LauncherInstrumentation launcher)45 Workspace(LauncherInstrumentation launcher) { 46 super(launcher); 47 mHotseat = launcher.waitForLauncherObject("hotseat"); 48 } 49 50 /** 51 * Swipes up to All Apps. 52 * 53 * @return the App Apps object. 54 */ 55 @NonNull switchToAllApps()56 public AllApps switchToAllApps() { 57 try (LauncherInstrumentation.Closable c = 58 mLauncher.addContextLayer("want to switch from workspace to all apps")) { 59 verifyActiveContainer(); 60 final UiObject2 hotseat = mHotseat; 61 final Point start = hotseat.getVisibleCenter(); 62 start.y = hotseat.getVisibleBounds().bottom - 1; 63 final int swipeHeight = mLauncher.getTestInfo( 64 TestProtocol.REQUEST_HOME_TO_ALL_APPS_SWIPE_HEIGHT). 65 getInt(TestProtocol.TEST_INFO_RESPONSE_FIELD); 66 LauncherInstrumentation.log( 67 "switchToAllApps: swipeHeight = " + swipeHeight + ", slop = " 68 + mLauncher.getTouchSlop()); 69 70 mLauncher.swipeToState( 71 start.x, 72 start.y, 73 start.x, 74 start.y - swipeHeight - mLauncher.getTouchSlop(), 75 60, 76 ALL_APPS_STATE_ORDINAL); 77 78 try (LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer( 79 "swiped to all apps")) { 80 return new AllApps(mLauncher); 81 } 82 } 83 } 84 85 /** 86 * Returns an icon for the app, if currently visible. 87 * 88 * @param appName name of the app 89 * @return app icon, if found, null otherwise. 90 */ 91 @Nullable tryGetWorkspaceAppIcon(String appName)92 public AppIcon tryGetWorkspaceAppIcon(String appName) { 93 try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer( 94 "want to get a workspace icon")) { 95 final UiObject2 workspace = verifyActiveContainer(); 96 final UiObject2 icon = workspace.findObject( 97 AppIcon.getAppIconSelector(appName, mLauncher)); 98 return icon != null ? new AppIcon(mLauncher, icon) : null; 99 } 100 } 101 102 103 /** 104 * Returns an icon for the app; fails if the icon doesn't exist. 105 * 106 * @param appName name of the app 107 * @return app icon. 108 */ 109 @NonNull getWorkspaceAppIcon(String appName)110 public AppIcon getWorkspaceAppIcon(String appName) { 111 try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer( 112 "want to get a workspace icon")) { 113 return new AppIcon(mLauncher, 114 mLauncher.waitForObjectInContainer( 115 verifyActiveContainer(), 116 AppIcon.getAppIconSelector(appName, mLauncher))); 117 } 118 } 119 120 /** 121 * Ensures that workspace is scrollable. If it's not, drags an icon icons from hotseat to the 122 * second screen. 123 */ ensureWorkspaceIsScrollable()124 public void ensureWorkspaceIsScrollable() { 125 final UiObject2 workspace = verifyActiveContainer(); 126 if (!isWorkspaceScrollable(workspace)) { 127 try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer( 128 "dragging icon to a second page of workspace to make it scrollable")) { 129 dragIconToWorkspace( 130 mLauncher, 131 getHotseatAppIcon("Chrome"), 132 new Point(mLauncher.getDevice().getDisplayWidth(), 133 workspace.getVisibleBounds().centerY()), 134 "deep_shortcuts_container"); 135 verifyActiveContainer(); 136 } 137 } 138 assertTrue("Home screen workspace didn't become scrollable", 139 isWorkspaceScrollable(workspace)); 140 } 141 isWorkspaceScrollable(UiObject2 workspace)142 private boolean isWorkspaceScrollable(UiObject2 workspace) { 143 return workspace.getChildCount() > 1; 144 } 145 146 @NonNull getHotseatAppIcon(String appName)147 public AppIcon getHotseatAppIcon(String appName) { 148 return new AppIcon(mLauncher, mLauncher.waitForObjectInContainer( 149 mHotseat, AppIcon.getAppIconSelector(appName, mLauncher))); 150 } 151 152 @NonNull getHotseatFolder(String appName)153 public Folder getHotseatFolder(String appName) { 154 return new Folder(mLauncher, mLauncher.waitForObjectInContainer( 155 mHotseat, Folder.getSelector(appName, mLauncher))); 156 } 157 dragIconToWorkspace( LauncherInstrumentation launcher, Launchable launchable, Point dest, String longPressIndicator)158 static void dragIconToWorkspace( 159 LauncherInstrumentation launcher, Launchable launchable, Point dest, 160 String longPressIndicator) { 161 LauncherInstrumentation.log("dragIconToWorkspace: begin"); 162 final Point launchableCenter = launchable.getObject().getVisibleCenter(); 163 final long downTime = SystemClock.uptimeMillis(); 164 launcher.sendPointer(downTime, downTime, MotionEvent.ACTION_DOWN, launchableCenter); 165 LauncherInstrumentation.log("dragIconToWorkspace: sent down"); 166 launcher.waitForLauncherObject(longPressIndicator); 167 LauncherInstrumentation.log("dragIconToWorkspace: indicator"); 168 launcher.movePointer( 169 downTime, SystemClock.uptimeMillis(), DRAG_DURACTION, launchableCenter, dest); 170 LauncherInstrumentation.log("dragIconToWorkspace: moved pointer"); 171 launcher.sendPointer( 172 downTime, SystemClock.uptimeMillis(), MotionEvent.ACTION_UP, dest); 173 LauncherInstrumentation.log("dragIconToWorkspace: end"); 174 launcher.waitUntilGone("drop_target_bar"); 175 } 176 177 /** 178 * Flings to get to screens on the right. Waits for scrolling and a possible overscroll 179 * recoil to complete. 180 */ flingForward()181 public void flingForward() { 182 final UiObject2 workspace = verifyActiveContainer(); 183 mLauncher.scroll(workspace, Direction.RIGHT, 184 new Rect(0, 0, mLauncher.getEdgeSensitivityWidth(), 0), 185 FLING_STEPS); 186 verifyActiveContainer(); 187 } 188 189 /** 190 * Flings to get to screens on the left. Waits for scrolling and a possible overscroll 191 * recoil to complete. 192 */ flingBackward()193 public void flingBackward() { 194 final UiObject2 workspace = verifyActiveContainer(); 195 mLauncher.scroll(workspace, Direction.LEFT, 196 new Rect(mLauncher.getEdgeSensitivityWidth(), 0, 0, 0), 197 FLING_STEPS); 198 verifyActiveContainer(); 199 } 200 201 /** 202 * Opens widgets container by pressing Ctrl+W. 203 * 204 * @return the widgets container. 205 */ 206 @NonNull openAllWidgets()207 public Widgets openAllWidgets() { 208 verifyActiveContainer(); 209 mLauncher.getDevice().pressKeyCode(KeyEvent.KEYCODE_W, KeyEvent.META_CTRL_ON); 210 try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer("pressed Ctrl+W")) { 211 return new Widgets(mLauncher); 212 } 213 } 214 215 @Override getSwipeHeightRequestName()216 protected String getSwipeHeightRequestName() { 217 return TestProtocol.REQUEST_HOME_TO_OVERVIEW_SWIPE_HEIGHT; 218 } 219 220 @Override getSwipeStartY()221 protected int getSwipeStartY() { 222 return mLauncher.getRealDisplaySize().y - 1; 223 } 224 225 @Nullable tryGetWidget(String label, long timeout)226 public Widget tryGetWidget(String label, long timeout) { 227 final UiObject2 widget = mLauncher.tryWaitForLauncherObject( 228 By.clazz("com.android.launcher3.widget.LauncherAppWidgetHostView").desc(label), 229 timeout); 230 return widget != null ? new Widget(mLauncher, widget) : null; 231 } 232 233 @Nullable tryGetPendingWidget(long timeout)234 public Widget tryGetPendingWidget(long timeout) { 235 final UiObject2 widget = mLauncher.tryWaitForLauncherObject( 236 By.clazz("com.android.launcher3.widget.PendingAppWidgetHostView"), timeout); 237 return widget != null ? new Widget(mLauncher, widget) : null; 238 } 239 }