1 /* 2 * Copyright (C) 2016 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 android.system.helpers; 18 19 import android.content.Context; 20 import android.content.Intent; 21 import android.os.RemoteException; 22 import android.util.Log; 23 import android.view.KeyEvent; 24 25 import androidx.test.InstrumentationRegistry; 26 import androidx.test.uiautomator.By; 27 import androidx.test.uiautomator.UiDevice; 28 import androidx.test.uiautomator.UiScrollable; 29 import androidx.test.uiautomator.UiSelector; 30 import androidx.test.uiautomator.Until; 31 32 import junit.framework.Assert; 33 34 import java.util.regex.Matcher; 35 import java.util.regex.Pattern; 36 37 /** 38 * Implement common helper methods for activities. 39 */ 40 public class ActivityHelper { 41 private static final String TAG = ActivityHelper.class.getSimpleName(); 42 43 public static final String SYSTEMUI_PACKAGE = "com.android.systemui"; 44 public static final int FULLSCREEN = 1; 45 public static final int SPLITSCREEN = 3; 46 public static final int ONE_SECOND = 1000; 47 public static final int INVALID_TASK_ID = -1; 48 private static final String NEXUS_LAUNCHER = "com.google.android.apps.nexuslauncher"; 49 50 private static ActivityHelper sInstance = null; 51 private Context mContext = null; 52 private UiDevice mDevice = null; 53 ActivityHelper()54 public ActivityHelper() { 55 mContext = InstrumentationRegistry.getTargetContext(); 56 mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()); 57 } 58 getInstance()59 public static ActivityHelper getInstance() { 60 if (sInstance == null) { 61 sInstance = new ActivityHelper(); 62 } 63 return sInstance; 64 } 65 66 /** 67 * Gets task id for an activity 68 * 69 * @param pkgName 70 * @param activityName 71 * @return taskId or -1 when no activity is found 72 */ getTaskIdForActivity(String pkgName, String activityName)73 public int getTaskIdForActivity(String pkgName, String activityName) { 74 int taskId = INVALID_TASK_ID; 75 // Find task id for given package and activity 76 final Pattern TASK_REGEX = Pattern.compile( 77 String.format("taskId=(\\d+): %s/%s", pkgName, activityName)); 78 Matcher matcher = TASK_REGEX.matcher(CommandsHelper.execute("am stack list")); 79 if (matcher.find()) { 80 taskId = Integer.parseInt(matcher.group(1)); 81 Log.i(TAG, String.format("TaskId found: %d for %s/%s", 82 taskId, pkgName, activityName)); 83 } 84 Assert.assertTrue("Taskid hasn't been found", taskId != -1); 85 return taskId; 86 } 87 88 /** 89 * Helper to change window mode between fullscreen and splitscreen for a given task 90 * 91 * @param taskId 92 * @param mode 93 * @throws InterruptedException 94 */ changeWindowMode(int taskId, int mode)95 public void changeWindowMode(int taskId, int mode) throws InterruptedException { 96 CommandsHelper.execute( 97 String.format("am stack move-task %d %d true", taskId, mode)); 98 Thread.sleep(ONE_SECOND); 99 } 100 101 /** 102 * Clears apps in overview/recents 103 * 104 * @throws InterruptedException 105 * @throws RemoteException 106 */ clearRecents()107 public void clearRecents() throws InterruptedException, RemoteException { 108 // Launch recents if it's not already 109 int retry = 5; 110 while (!mDevice.wait(Until.hasObject(By.res(SYSTEMUI_PACKAGE, "recents_view")), 111 ONE_SECOND * 5) && --retry > 0) { 112 mDevice.pressRecentApps(); 113 Thread.sleep(ONE_SECOND); 114 } 115 // Return if there is no apps in recents 116 if (mDevice.wait(Until.hasObject(By.text("No recent items")), ONE_SECOND * 5)) { 117 return; 118 } else { 119 Assert.assertTrue("Device expects recent items", mDevice.wait(Until.hasObject( 120 By.res(SYSTEMUI_PACKAGE, "recents_view")), ONE_SECOND * 5)); 121 } 122 // Get recents items 123 int recents = mDevice.wait(Until.findObjects( 124 By.res(SYSTEMUI_PACKAGE, "task_view_thumbnail")), ONE_SECOND * 5).size(); 125 // Clear recents 126 for (int i = 0; i < recents; ++i) { 127 mDevice.pressKeyCode(KeyEvent.KEYCODE_APP_SWITCH); 128 Thread.sleep(ONE_SECOND); 129 mDevice.pressKeyCode(KeyEvent.KEYCODE_DEL); 130 Thread.sleep(ONE_SECOND); 131 } 132 } 133 134 /** 135 * Clear recent apps by click 'CLEAR ALL' button in the recents view. 136 * 137 * @param maxScroll max number of scroll in recents view. 138 * @throws Exception 139 */ clearRecentsByClearAll(int maxScroll)140 public void clearRecentsByClearAll(int maxScroll) throws Exception { 141 int retry = 5; 142 while (!mDevice.wait(Until.hasObject(By.res(NEXUS_LAUNCHER, "overview_panel")), 143 ONE_SECOND * 5) && --retry > 0) { 144 mDevice.pressRecentApps(); 145 Thread.sleep(ONE_SECOND); 146 } 147 while (mDevice.findObject(By.res(NEXUS_LAUNCHER, "overview_panel")) 148 .isScrollable() && maxScroll-- >= 0) { 149 UiScrollable thumbnailScrollable = new UiScrollable(new UiSelector().resourceId( 150 NEXUS_LAUNCHER + ":id/overview_panel")); 151 thumbnailScrollable.setAsHorizontalList(); 152 thumbnailScrollable.scrollBackward(); 153 if (!mDevice.wait(Until.hasObject(By.text( 154 Pattern.compile("CLEAR ALL", Pattern.CASE_INSENSITIVE))), ONE_SECOND * 2)) { 155 continue; 156 } else { 157 int tries = 3; 158 while (mDevice.hasObject(By.text( 159 Pattern.compile("CLEAR ALL", Pattern.CASE_INSENSITIVE))) && tries-- > 0) { 160 mDevice.findObject(By.text( 161 Pattern.compile("CLEAR ALL", Pattern.CASE_INSENSITIVE))).click(); 162 Thread.sleep(ONE_SECOND * 2); 163 } 164 break; 165 } 166 } 167 } 168 169 /** 170 * Clear recents apps by click 'CLEAR ALL' button in recents view, default max scroll 20. 171 * 172 * @throws Exception 173 */ clearRecentsByClearAll()174 public void clearRecentsByClearAll() throws Exception { 175 clearRecentsByClearAll(20); 176 } 177 178 /** 179 * Enable/disable bmgr service 180 * 181 * @param enable true to enable, false to disable 182 */ enableBmgr(boolean enable)183 public void enableBmgr(boolean enable) { 184 String output = CommandsHelper.execute("bmgr enable " + Boolean.toString(enable)); 185 if (enable) { 186 Assert.assertTrue("Bmgr not enabled", 187 output.indexOf("Backup Manager now enabled") >= 0); 188 } else { 189 Assert.assertTrue("Bmgr not disabled", 190 output.indexOf("Backup Manager now disabled") >= 0); 191 } 192 } 193 194 /** 195 * Launch an intent when intent is of string type 196 * 197 * @param intentName 198 * @throws InterruptedException 199 */ launchIntent(String intentName)200 public void launchIntent(String intentName) throws InterruptedException { 201 mDevice.pressHome(); 202 Intent intent = new Intent(intentName); 203 launchIntent(intent); 204 } 205 206 /** 207 * Find intent of a package and launch 208 * 209 * @param pkgName 210 * @throws InterruptedException 211 */ launchPackage(String pkgName)212 public void launchPackage(String pkgName) throws InterruptedException { 213 Intent pkgIntent = mContext.getPackageManager() 214 .getLaunchIntentForPackage(pkgName); 215 launchIntent(pkgIntent); 216 } 217 218 /** 219 * launch an intent when intent is of Intent type 220 * 221 * @param intent 222 * @throws InterruptedException 223 */ launchIntent(Intent intent)224 public void launchIntent(Intent intent) throws InterruptedException { 225 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 226 mContext.startActivity(intent); 227 Thread.sleep(ONE_SECOND * 5); 228 } 229 } 230