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.shared.TestProtocol.TEST_DRAG_APP_ICON_TO_MULTIPLE_WORKSPACES_FAILURE; 20 21 import android.util.Log; 22 import android.widget.TextView; 23 24 import androidx.annotation.NonNull; 25 import androidx.test.uiautomator.By; 26 import androidx.test.uiautomator.BySelector; 27 import androidx.test.uiautomator.UiObject2; 28 29 import com.android.launcher3.testing.shared.TestProtocol; 30 31 import java.util.regex.Pattern; 32 33 /** 34 * App icon, whether in all apps, workspace or the taskbar. 35 */ 36 public abstract class AppIcon extends Launchable { 37 AppIcon(LauncherInstrumentation launcher, UiObject2 icon)38 AppIcon(LauncherInstrumentation launcher, UiObject2 icon) { 39 super(launcher, icon); 40 } 41 42 /** 43 * Find an app icon with the given name. 44 * 45 * @param appName app icon to look for 46 */ getAppIconSelector(String appName)47 static BySelector getAppIconSelector(String appName) { 48 // focusable=true to avoid matching folder labels 49 return By.clazz(TextView.class).text(makeMultilinePattern(appName)).focusable(true); 50 } 51 52 /** 53 * Find an app icon with the given name. 54 * 55 * @param appName app icon to look for 56 * @param launcher (optional) - only match ui elements from Launcher's package 57 */ getAppIconSelector(String appName, LauncherInstrumentation launcher)58 static BySelector getAppIconSelector(String appName, LauncherInstrumentation launcher) { 59 return getAppIconSelector(appName).pkg(launcher.getLauncherPackageName()); 60 } 61 getMenuItemSelector(String text, LauncherInstrumentation launcher)62 static BySelector getMenuItemSelector(String text, LauncherInstrumentation launcher) { 63 return By.clazz(TextView.class).text(text).pkg(launcher.getLauncherPackageName()); 64 } 65 getAnyAppIconSelector()66 static BySelector getAnyAppIconSelector() { 67 return By.clazz(TextView.class); 68 } 69 getLongClickEvent()70 protected abstract Pattern getLongClickEvent(); 71 72 /** 73 * Long-clicks the icon to open its menu. 74 */ openMenu()75 public AppIconMenu openMenu() { 76 try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck()) { 77 return createMenu(mLauncher.clickAndGet( 78 mObject, /* resName= */ "popup_container", getLongClickEvent())); 79 } 80 } 81 82 /** 83 * Long-clicks the icon to open its menu, and looks at the deep shortcuts container only. 84 */ openDeepShortcutMenu()85 public AppIconMenu openDeepShortcutMenu() { 86 try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck()) { 87 return createMenu(mLauncher.clickAndGet( 88 mObject, /* resName= */ "deep_shortcuts_container", getLongClickEvent())); 89 } 90 } 91 createMenu(UiObject2 menu)92 protected abstract AppIconMenu createMenu(UiObject2 menu); 93 94 @Override addExpectedEventsForLongClick()95 protected void addExpectedEventsForLongClick() { 96 mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN, getLongClickEvent()); 97 } 98 99 @Override waitForLongPressConfirmation()100 protected void waitForLongPressConfirmation() { 101 Log.d(TEST_DRAG_APP_ICON_TO_MULTIPLE_WORKSPACES_FAILURE, 102 "AppIcon.waitForLongPressConfirmation, resName: popupContainer"); 103 mLauncher.waitForLauncherObject("popup_container"); 104 } 105 106 @Override expectActivityStartEvents()107 protected void expectActivityStartEvents() { 108 mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN, LauncherInstrumentation.EVENT_START); 109 } 110 111 @Override launchableType()112 protected String launchableType() { 113 return "app icon"; 114 } 115 116 /** Return the app name of a icon */ 117 @NonNull getIconName()118 public String getIconName() { 119 return getObject().getText(); 120 } 121 122 /** 123 * Return the app name of a icon by the content description. This should be used when trying to 124 * get the name of an app where the text of it is multiline. 125 */ 126 @NonNull getAppName()127 String getAppName() { 128 return getObject().getContentDescription(); 129 } 130 131 /** 132 * Create a regular expression pattern that matches strings containing all of the non-whitespace 133 * characters of the app name, with any amount of whitespace added between characters (e.g. 134 * newline for multiline app labels). 135 */ makeMultilinePattern(String appName)136 static Pattern makeMultilinePattern(String appName) { 137 // Remove any existing whitespace. 138 appName = appName.replaceAll("\\s", ""); 139 // Allow whitespace between characters, e.g. newline for 2 line app label. 140 StringBuilder regexBuldier = new StringBuilder("\\s*"); 141 appName.chars().forEach(letter -> regexBuldier.append((char) letter).append("\\s*")); 142 return Pattern.compile(regexBuldier.toString()); 143 } 144 } 145