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