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.os.SystemClock; 25 import android.view.KeyEvent; 26 import android.view.MotionEvent; 27 28 import androidx.annotation.NonNull; 29 import androidx.annotation.Nullable; 30 import androidx.test.uiautomator.By; 31 import androidx.test.uiautomator.Direction; 32 import androidx.test.uiautomator.UiObject2; 33 34 import com.android.launcher3.testing.TestProtocol; 35 36 /** 37 * Operations on the workspace screen. 38 */ 39 public final class Workspace extends Home { 40 private static final float FLING_SPEED = 41 LauncherInstrumentation.isAvd() ? 1500.0F : 3500.0F; 42 private static final int DRAG_DURACTION = 2000; 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.getTestInfo(TestProtocol.REQUEST_ENABLE_DEBUG_TRACING); 71 mLauncher.swipeToState( 72 start.x, 73 start.y, 74 start.x, 75 start.y - swipeHeight - mLauncher.getTouchSlop(), 76 60, 77 ALL_APPS_STATE_ORDINAL); 78 mLauncher.getTestInfo(TestProtocol.REQUEST_DISABLE_DEBUG_TRACING); 79 80 try (LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer( 81 "swiped to all apps")) { 82 return new AllApps(mLauncher); 83 } 84 } 85 } 86 87 /** 88 * Returns an icon for the app, if currently visible. 89 * 90 * @param appName name of the app 91 * @return app icon, if found, null otherwise. 92 */ 93 @Nullable tryGetWorkspaceAppIcon(String appName)94 public AppIcon tryGetWorkspaceAppIcon(String appName) { 95 try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer( 96 "want to get a workspace icon")) { 97 final UiObject2 workspace = verifyActiveContainer(); 98 final UiObject2 icon = workspace.findObject( 99 AppIcon.getAppIconSelector(appName, mLauncher)); 100 return icon != null ? new AppIcon(mLauncher, icon) : null; 101 } 102 } 103 104 105 /** 106 * Returns an icon for the app; fails if the icon doesn't exist. 107 * 108 * @param appName name of the app 109 * @return app icon. 110 */ 111 @NonNull getWorkspaceAppIcon(String appName)112 public AppIcon getWorkspaceAppIcon(String appName) { 113 return new AppIcon(mLauncher, 114 mLauncher.getObjectInContainer( 115 verifyActiveContainer(), 116 AppIcon.getAppIconSelector(appName, mLauncher))); 117 } 118 119 /** 120 * Ensures that workspace is scrollable. If it's not, drags an icon icons from hotseat to the 121 * second screen. 122 */ ensureWorkspaceIsScrollable()123 public void ensureWorkspaceIsScrollable() { 124 final UiObject2 workspace = verifyActiveContainer(); 125 if (!isWorkspaceScrollable(workspace)) { 126 try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer( 127 "dragging icon to a second page of workspace to make it scrollable")) { 128 dragIconToWorkspace( 129 mLauncher, 130 getHotseatAppIcon("Chrome"), 131 new Point(mLauncher.getDevice().getDisplayWidth(), 132 workspace.getVisibleBounds().centerY()), 133 "deep_shortcuts_container"); 134 verifyActiveContainer(); 135 } 136 } 137 assertTrue("Home screen workspace didn't become scrollable", 138 isWorkspaceScrollable(workspace)); 139 } 140 isWorkspaceScrollable(UiObject2 workspace)141 private boolean isWorkspaceScrollable(UiObject2 workspace) { 142 return workspace.isScrollable(); 143 } 144 145 @NonNull getHotseatAppIcon(String appName)146 public AppIcon getHotseatAppIcon(String appName) { 147 return new AppIcon(mLauncher, mLauncher.getObjectInContainer( 148 mHotseat, AppIcon.getAppIconSelector(appName, mLauncher))); 149 } 150 151 @NonNull getHotseatFolder(String appName)152 public Folder getHotseatFolder(String appName) { 153 return new Folder(mLauncher, mLauncher.getObjectInContainer( 154 mHotseat, Folder.getSelector(appName, mLauncher))); 155 } 156 dragIconToWorkspace( LauncherInstrumentation launcher, Launchable launchable, Point dest, String longPressIndicator)157 static void dragIconToWorkspace( 158 LauncherInstrumentation launcher, Launchable launchable, Point dest, 159 String longPressIndicator) { 160 launcher.getTestInfo(TestProtocol.REQUEST_ENABLE_DEBUG_TRACING); 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 launcher.getTestInfo(TestProtocol.REQUEST_DISABLE_DEBUG_TRACING); 176 } 177 178 /** 179 * Flings to get to screens on the right. Waits for scrolling and a possible overscroll 180 * recoil to complete. 181 */ flingForward()182 public void flingForward() { 183 final UiObject2 workspace = verifyActiveContainer(); 184 workspace.setGestureMargins(0, 0, mLauncher.getEdgeSensitivityWidth(), 0); 185 workspace.fling(Direction.RIGHT, (int) (FLING_SPEED * mLauncher.getDisplayDensity())); 186 mLauncher.waitForIdle(); 187 verifyActiveContainer(); 188 } 189 190 /** 191 * Flings to get to screens on the left. Waits for scrolling and a possible overscroll 192 * recoil to complete. 193 */ flingBackward()194 public void flingBackward() { 195 final UiObject2 workspace = verifyActiveContainer(); 196 workspace.setGestureMargins(mLauncher.getEdgeSensitivityWidth(), 0, 0, 0); 197 workspace.fling(Direction.LEFT, (int) (FLING_SPEED * mLauncher.getDisplayDensity())); 198 mLauncher.waitForIdle(); 199 verifyActiveContainer(); 200 } 201 202 /** 203 * Opens widgets container by pressing Ctrl+W. 204 * 205 * @return the widgets container. 206 */ 207 @NonNull openAllWidgets()208 public Widgets openAllWidgets() { 209 verifyActiveContainer(); 210 mLauncher.getDevice().pressKeyCode(KeyEvent.KEYCODE_W, KeyEvent.META_CTRL_ON); 211 try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer("pressed Ctrl+W")) { 212 return new Widgets(mLauncher); 213 } 214 } 215 216 @Override getSwipeHeightRequestName()217 protected String getSwipeHeightRequestName() { 218 return TestProtocol.REQUEST_HOME_TO_OVERVIEW_SWIPE_HEIGHT; 219 } 220 221 @Override getSwipeStartY()222 protected int getSwipeStartY() { 223 return mLauncher.getRealDisplaySize().y - 1; 224 } 225 226 @Nullable tryGetWidget(String label, long timeout)227 public Widget tryGetWidget(String label, long timeout) { 228 final UiObject2 widget = mLauncher.tryWaitForLauncherObject( 229 By.clazz("com.android.launcher3.widget.LauncherAppWidgetHostView").desc(label), 230 timeout); 231 return widget != null ? new Widget(mLauncher, widget) : null; 232 } 233 234 @Nullable tryGetPendingWidget(long timeout)235 public Widget tryGetPendingWidget(long timeout) { 236 final UiObject2 widget = mLauncher.tryWaitForLauncherObject( 237 By.clazz("com.android.launcher3.widget.PendingAppWidgetHostView"), timeout); 238 return widget != null ? new Widget(mLauncher, widget) : null; 239 } 240 }