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 com.android.wearable.sysapp.janktests; 18 19 import android.app.Instrumentation; 20 import android.content.ComponentName; 21 import android.content.Intent; 22 import android.os.SystemClock; 23 import android.support.test.uiautomator.By; 24 import android.support.test.uiautomator.UiDevice; 25 import android.support.test.uiautomator.UiObject; 26 import android.support.test.uiautomator.UiObject2; 27 import android.support.test.uiautomator.UiSelector; 28 import android.support.test.uiautomator.Until; 29 import android.util.Log; 30 import android.view.KeyEvent; 31 32 import junit.framework.Assert; 33 34 /** 35 * Helper for all the system apps jank tests 36 */ 37 public class SysAppTestHelper { 38 39 public static final int EXPECTED_FRAMES_CARDS_TEST = 20; 40 public static final int EXPECTED_FRAMES_WATCHFACE_PICKER_TEST = 20; 41 public static final int EXPECTED_FRAMES = 100; 42 public static final int LONG_TIMEOUT = 5000; 43 public static final int SHORT_TIMEOUT = 500; 44 public static final int FLING_SPEED = 5000; 45 private static final String LOG_TAG = SysAppTestHelper.class.getSimpleName(); 46 private static final long NEW_CARD_TIMEOUT_MS = 5 * 1000; // 5s 47 private static final String RELOAD_NOTIFICATION_CARD_INTENT = "com.google.android.wearable." 48 + "support.wearnotificationgenerator.SHOW_NOTIFICATION"; 49 private static final String HOME_INDICATOR = "charging_icon"; 50 private static final String LAUNCHER_VIEW_NAME = "launcher_view"; 51 private static final String CARD_VIEW_NAME = "activity_view"; 52 private static final String QUICKSETTING_VIEW_NAME = "settings_icon"; 53 private static final String WATCHFACE_PREVIEW_NAME = "preview_image"; 54 55 // Demo card selectors 56 private static final UiSelector CARD_SELECTOR = new UiSelector() 57 .resourceId("com.google.android.wearable.app:id/snippet"); 58 private static final UiSelector TITLE_SELECTOR = new UiSelector() 59 .resourceId("com.google.android.wearable.app:id/title"); 60 private static final UiSelector CLOCK_SELECTOR = new UiSelector() 61 .resourceId("com.google.android.wearable.app:id/clock_bar"); 62 private static final UiSelector ICON_SELECTOR = new UiSelector() 63 .resourceId("com.google.android.wearable.app:id/icon"); 64 private static final UiSelector TEXT_SELECTOR = new UiSelector() 65 .resourceId("com.google.android.wearable.app:id/text"); 66 private static final UiSelector STATUS_BAR_SELECTOR = new UiSelector() 67 .resourceId("com.google.android.wearable.app:id/status_bar_icons"); 68 private static SysAppTestHelper sysAppTestHelperInstance; 69 private UiDevice mDevice = null; 70 private Instrumentation instrumentation = null; 71 private UiObject mCard = null; 72 private UiObject mTitle = null; 73 private UiObject mIcon = null; 74 private UiObject mText = null; 75 private Intent mIntent = null; 76 77 /** 78 * @param mDevice Instance to represent the current device. 79 * @param instrumentation Instance for instrumentation. 80 */ 81 private SysAppTestHelper(UiDevice mDevice, Instrumentation instrumentation) { 82 super(); 83 this.mDevice = mDevice; 84 this.instrumentation = instrumentation; 85 mIntent = new Intent(); 86 mCard = mDevice.findObject(CARD_SELECTOR); 87 mTitle = mDevice.findObject(TITLE_SELECTOR); 88 mIcon = mDevice.findObject(ICON_SELECTOR); 89 mText = mDevice.findObject(TEXT_SELECTOR); 90 } 91 92 public static SysAppTestHelper getInstance(UiDevice device, Instrumentation instrumentation) { 93 if (sysAppTestHelperInstance == null) { 94 sysAppTestHelperInstance = new SysAppTestHelper(device, instrumentation); 95 } 96 return sysAppTestHelperInstance; 97 } 98 99 // TODO: Cleanup confusion between swipe and fling. 100 public void swipeRight() { 101 mDevice.swipe(50, 102 mDevice.getDisplayHeight() / 2, mDevice.getDisplayWidth() - 25, 103 mDevice.getDisplayHeight() / 2, 30); // slow speed 104 SystemClock.sleep(SHORT_TIMEOUT); 105 } 106 107 public void swipeLeft() { 108 mDevice.swipe(mDevice.getDisplayWidth() - 50, mDevice.getDisplayHeight() / 2, 50, 109 mDevice.getDisplayHeight() / 2, 30); // slow speed 110 SystemClock.sleep(SHORT_TIMEOUT); 111 } 112 113 public void swipeUp() { 114 mDevice.swipe(mDevice.getDisplayWidth() / 2, mDevice.getDisplayHeight() / 2 + 50, 115 mDevice.getDisplayWidth() / 2, 0, 30); // slow speed 116 SystemClock.sleep(SHORT_TIMEOUT); 117 } 118 119 public void swipeDown() { 120 mDevice.swipe(mDevice.getDisplayWidth() / 2, 0, mDevice.getDisplayWidth() / 2, 121 mDevice.getDisplayHeight() / 2 + 50, 30); // slow speed 122 SystemClock.sleep(SHORT_TIMEOUT); 123 } 124 125 // TODO: Cleanup confusion between swipe and fling. 126 public void flingLeft() { 127 mDevice.swipe(mDevice.getDisplayWidth() - 50, mDevice.getDisplayHeight() / 2, 128 50, mDevice.getDisplayHeight() / 2, 5); // fast speed 129 SystemClock.sleep(SHORT_TIMEOUT); 130 } 131 132 public void flingRight() { 133 mDevice.swipe(50, mDevice.getDisplayHeight() / 2, 134 mDevice.getDisplayWidth() - 50, mDevice.getDisplayHeight() / 2, 5); // fast speed 135 SystemClock.sleep(SHORT_TIMEOUT); 136 } 137 138 public void flingUp() { 139 mDevice.swipe(mDevice.getDisplayWidth() / 2, mDevice.getDisplayHeight() / 2 + 50, 140 mDevice.getDisplayWidth() / 2, 0, 5); // fast speed 141 SystemClock.sleep(SHORT_TIMEOUT); 142 } 143 144 public void flingDown() { 145 mDevice.swipe(mDevice.getDisplayWidth() / 2, 0, mDevice.getDisplayWidth() / 2, 146 mDevice.getDisplayHeight() / 2 + 50, 5); // fast speed 147 SystemClock.sleep(SHORT_TIMEOUT); 148 } 149 150 // Helper method to go back to home screen 151 public void goBackHome() { 152 int count = 0; 153 do { 154 UiObject2 homeScreen = waitForSysAppUiObject2(HOME_INDICATOR); 155 if (homeScreen != null) { 156 break; 157 } 158 mDevice.pressBack(); 159 count++; 160 } while (count < 5); 161 162 // TODO (yuanlang@) Delete the following hacky codes after charging icon issue fixed 163 // Make sure we're not in the launcher 164 if (waitForSysAppUiObject2(LAUNCHER_VIEW_NAME) != null) { 165 mDevice.pressBack(); 166 } 167 // Make sure we're not in cards view 168 if (waitForSysAppUiObject2(CARD_VIEW_NAME) != null) { 169 mDevice.pressBack(); 170 } 171 // Make sure we're not in the quick settings 172 if (waitForSysAppUiObject2(QUICKSETTING_VIEW_NAME) != null) { 173 mDevice.pressBack(); 174 } 175 // Make sure we're not in watch face picker 176 if (waitForSysAppUiObject2(WATCHFACE_PREVIEW_NAME) != null) { 177 mDevice.pressBack(); 178 } 179 SystemClock.sleep(LONG_TIMEOUT); 180 } 181 182 // Helper method to verify if there are any Demo cards. 183 184 // TODO: Allow user to pass in how many cards are expected to find cause some tests may require 185 // more than one card. 186 public void hasDemoCards() { 187 // Device should be pre-loaded with demo cards. 188 189 goBackHome(); // Start by going to Home. 190 191 if (!mTitle.waitForExists(NEW_CARD_TIMEOUT_MS)) { 192 Log.d(LOG_TAG, "Card previews not available, swiping up"); 193 swipeUp(); 194 // For few devices, demo card preview is hidden by default. So swipe once to bring up 195 // the card. 196 } 197 198 // First card from the pre-loaded demo cards could be either in peek view 199 // or in full view(e.g Dory) or no peek view(Sturgeon). Ensure to check for demo cards 200 // existence in both cases. 201 if (!(mCard.waitForExists(NEW_CARD_TIMEOUT_MS) 202 || mTitle.waitForExists(NEW_CARD_TIMEOUT_MS) 203 || mIcon.waitForExists(NEW_CARD_TIMEOUT_MS) 204 || mText.waitForExists(NEW_CARD_TIMEOUT_MS))) { 205 Log.d(LOG_TAG, "Demo cards not found, going to reload the cards"); 206 // If there are no Demo cards, reload them. 207 reloadDemoCards(); 208 if (!mTitle.waitForExists(NEW_CARD_TIMEOUT_MS)) { 209 swipeUp(); // For few devices, demo card preview is hidden by 210 // default. So swipe once to bring up the card. 211 } 212 } 213 Assert.assertTrue("no cards available for testing", 214 (mTitle.waitForExists(NEW_CARD_TIMEOUT_MS) 215 || mIcon.waitForExists(NEW_CARD_TIMEOUT_MS) 216 || mText.waitForExists(NEW_CARD_TIMEOUT_MS))); 217 } 218 219 // This will ensure to reload notification cards by launching NotificationsGeneratorWear app 220 // when there are insufficient cards. 221 private void reloadDemoCards() { 222 mIntent.setAction(RELOAD_NOTIFICATION_CARD_INTENT); 223 instrumentation.getContext().sendBroadcast(mIntent); 224 SystemClock.sleep(LONG_TIMEOUT); 225 } 226 227 public void launchActivity(String appPackage, String activityToLaunch) { 228 mIntent.setAction("android.intent.action.MAIN"); 229 mIntent.setComponent(new ComponentName(appPackage, activityToLaunch)); 230 mIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 231 instrumentation.getContext().startActivity(mIntent); 232 } 233 234 // Helper method to goto app launcher and verifies you are there. 235 public void gotoAppLauncher() { 236 goBackHome(); 237 mDevice.pressKeyCode(KeyEvent.KEYCODE_BACK); 238 UiObject2 appLauncher = mDevice.wait(Until.findObject(By.text("Agenda")), 239 SysAppTestHelper.LONG_TIMEOUT); 240 Assert.assertNotNull("App launcher not launched", appLauncher); 241 } 242 243 public UiObject2 waitForSysAppUiObject2(String resourceId) { 244 String launcherPackageName = mDevice.getLauncherPackageName(); 245 return mDevice.wait( 246 Until.findObject(By.res(launcherPackageName, resourceId)), 247 SHORT_TIMEOUT); 248 } 249 } 250