1 /* 2 * Copyright (C) 2015 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.jankmicrobenchmark.janktests; 18 19 import android.content.Intent; 20 import android.os.Bundle; 21 import android.os.RemoteException; 22 import android.os.SystemClock; 23 import android.support.test.jank.GfxMonitor; 24 import android.support.test.jank.JankTest; 25 import android.support.test.jank.JankTestBase; 26 import android.support.test.uiautomator.By; 27 import android.support.test.uiautomator.Direction; 28 import android.support.test.uiautomator.UiDevice; 29 import android.support.test.uiautomator.UiObject2; 30 import android.support.test.uiautomator.UiObjectNotFoundException; 31 import android.support.test.uiautomator.Until; 32 import android.widget.Button; 33 34 import junit.framework.Assert; 35 36 /** 37 * Jank micro benchmark tests 38 * App : ApiDemos 39 */ 40 41 public class ApiDemoJankTests extends JankTestBase { 42 private static final int LONG_TIMEOUT = 5000; 43 private static final int SHORT_TIMEOUT = 500; 44 private static final int INNER_LOOP = 5; 45 private static final int EXPECTED_FRAMES = 100; 46 private static final String PACKAGE_NAME = "com.example.android.apis"; 47 private static final String RES_PACKAGE_NAME = "android"; 48 private static final String LEANBACK_LAUNCHER = "com.google.android.leanbacklauncher"; 49 private UiDevice mDevice; 50 private UiObject2 mListView; 51 52 @Override setUp()53 public void setUp() throws Exception { 54 super.setUp(); 55 mDevice = UiDevice.getInstance(getInstrumentation()); 56 mDevice.setOrientationNatural(); 57 } 58 59 @Override tearDown()60 protected void tearDown() throws Exception { 61 mDevice.unfreezeRotation(); 62 super.tearDown(); 63 } 64 65 // This method distinguishes between home screen for handheld devices 66 // and home screen for Android TV, both of whom have different Home elements. getHomeScreen()67 public UiObject2 getHomeScreen() throws UiObjectNotFoundException { 68 if (mDevice.getProductName().equals("fugu")) { 69 return mDevice.wait(Until.findObject(By.res(LEANBACK_LAUNCHER, "main_list_view")), 70 LONG_TIMEOUT); 71 } 72 else { 73 String launcherPackage = mDevice.getLauncherPackageName(); 74 return mDevice.wait(Until.findObject(By.res(launcherPackage,"workspace")), 75 LONG_TIMEOUT); 76 } 77 } 78 launchApiDemos()79 public void launchApiDemos() throws UiObjectNotFoundException { 80 UiObject2 homeScreen = getHomeScreen(); 81 if (homeScreen == null) 82 navigateToHome(); 83 Intent intent = getInstrumentation().getContext().getPackageManager() 84 .getLaunchIntentForPackage(PACKAGE_NAME); 85 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 86 getInstrumentation().getContext().startActivity(intent); 87 mDevice.waitForIdle(); 88 } 89 selectAnimation(String optionName)90 public void selectAnimation(String optionName) throws UiObjectNotFoundException { 91 launchApiDemos(); 92 UiObject2 animation = mDevice.wait(Until.findObject( 93 By.res(RES_PACKAGE_NAME, "text1").text("Animation")), LONG_TIMEOUT); 94 Assert.assertNotNull("Animation isn't found in ApiDemos", animation); 95 animation.click(); 96 UiObject2 option = mDevice.wait(Until.findObject( 97 By.res(RES_PACKAGE_NAME, "text1").text(optionName)), LONG_TIMEOUT); 98 int maxAttempt = 3; 99 while (option == null && maxAttempt > 0) { 100 mDevice.wait(Until.findObject(By.res(RES_PACKAGE_NAME, "content")), LONG_TIMEOUT) 101 .scroll(Direction.DOWN, 1.0f); 102 option = mDevice.wait(Until.findObject(By.res(RES_PACKAGE_NAME, "text1") 103 .text(optionName)), LONG_TIMEOUT); 104 --maxAttempt; 105 } 106 Assert.assertNotNull("Target option in APiDemos animation for test isn't found", option); 107 option.click(); 108 } 109 110 // Since afterTest only runs when the test has passed, there's no way of going 111 // back to the Home Screen if a test fails. This method is a workaround. A feature 112 // request has been filed to have a per test tearDown method - b/25673300 navigateToHome()113 public void navigateToHome() throws UiObjectNotFoundException { 114 UiObject2 homeScreen = getHomeScreen(); 115 int count = 0; 116 while (homeScreen == null && count <= 10) { 117 mDevice.pressBack(); 118 homeScreen = getHomeScreen(); 119 count++; 120 } 121 Assert.assertNotNull("Hit maximum retries and couldn't find Home Screen", homeScreen); 122 } 123 124 // Since the app doesn't start at the first page when reloaded after the first time, 125 // ensuring that we head back to the first screen before going Home so we're always 126 // on screen one. goBackHome(Bundle metrics)127 public void goBackHome(Bundle metrics) throws UiObjectNotFoundException { 128 navigateToHome(); 129 super.afterTest(metrics); 130 } 131 132 // Loads the 'activity transition' animation selectActivityTransitionAnimation()133 public void selectActivityTransitionAnimation() throws UiObjectNotFoundException { 134 selectAnimation("Activity Transition"); 135 } 136 137 // Measures jank for activity transition animation 138 @JankTest(beforeTest="selectActivityTransitionAnimation", afterTest="goBackHome", 139 expectedFrames=EXPECTED_FRAMES) 140 @GfxMonitor(processName=PACKAGE_NAME) testActivityTransitionAnimation()141 public void testActivityTransitionAnimation() { 142 for (int i = 0; i < INNER_LOOP; i++) { 143 UiObject2 redBallTile = mDevice.wait(Until.findObject(By.res(PACKAGE_NAME, "ball")), 144 LONG_TIMEOUT); 145 redBallTile.click(); 146 SystemClock.sleep(LONG_TIMEOUT); 147 mDevice.pressBack(); 148 } 149 } 150 151 // Loads the 'view flip' animation selectViewFlipAnimation()152 public void selectViewFlipAnimation() throws UiObjectNotFoundException { 153 selectAnimation("View Flip"); 154 } 155 156 // Measures jank for view flip animation 157 @JankTest(beforeTest="selectViewFlipAnimation", afterTest="goBackHome", 158 expectedFrames=EXPECTED_FRAMES) 159 @GfxMonitor(processName=PACKAGE_NAME) testViewFlipAnimation()160 public void testViewFlipAnimation() { 161 for (int i = 0; i < INNER_LOOP; i++) { 162 UiObject2 flipButton = mDevice.findObject(By.res(PACKAGE_NAME, "button")); 163 flipButton.click(); 164 SystemClock.sleep(LONG_TIMEOUT); 165 } 166 } 167 168 // Loads the 'cloning' animation selectCloningAnimation()169 public void selectCloningAnimation() throws UiObjectNotFoundException { 170 selectAnimation("Cloning"); 171 } 172 173 // Measures jank for cloning animation 174 @JankTest(beforeTest="selectCloningAnimation", afterTest="goBackHome", 175 expectedFrames=EXPECTED_FRAMES) 176 @GfxMonitor(processName=PACKAGE_NAME) testCloningAnimation()177 public void testCloningAnimation() { 178 for (int i = 0; i < INNER_LOOP; i++) { 179 UiObject2 runCloningButton = mDevice.findObject(By.res(PACKAGE_NAME, "startButton")); 180 runCloningButton.click(); 181 SystemClock.sleep(LONG_TIMEOUT); 182 } 183 } 184 185 // Loads the 'loading' animation selectLoadingOption()186 public void selectLoadingOption() throws UiObjectNotFoundException { 187 selectAnimation("Loading"); 188 } 189 190 // Measures jank for 'loading' animation 191 @JankTest(beforeTest="selectLoadingOption", afterTest="goBackHome", 192 expectedFrames=EXPECTED_FRAMES) 193 @GfxMonitor(processName=PACKAGE_NAME) testLoadingJank()194 public void testLoadingJank() { 195 UiObject2 runButton = mDevice.wait(Until.findObject( 196 By.res(PACKAGE_NAME, "startButton").text("RUN")), LONG_TIMEOUT); 197 Assert.assertNotNull("Run button is null", runButton); 198 for (int i = 0; i < INNER_LOOP; i++) { 199 runButton.click(); 200 SystemClock.sleep(SHORT_TIMEOUT * 2); 201 } 202 } 203 204 // Loads the 'simple transition' animation selectSimpleTransitionOption()205 public void selectSimpleTransitionOption() throws UiObjectNotFoundException { 206 selectAnimation("Simple Transitions"); 207 } 208 209 // Measures jank for 'simple transition' animation 210 @JankTest(beforeTest="selectSimpleTransitionOption", afterTest="goBackHome", 211 expectedFrames=EXPECTED_FRAMES) 212 @GfxMonitor(processName=PACKAGE_NAME) testSimpleTransitionJank()213 public void testSimpleTransitionJank() { 214 for (int i = 0; i < INNER_LOOP; i++) { 215 UiObject2 scene2 = mDevice.wait(Until.findObject( 216 By.res(PACKAGE_NAME, "scene2")), LONG_TIMEOUT); 217 Assert.assertNotNull("Scene2 button can't be found", scene2); 218 scene2.click(); 219 SystemClock.sleep(SHORT_TIMEOUT); 220 221 UiObject2 scene1 = mDevice.wait(Until.findObject( 222 By.res(PACKAGE_NAME, "scene1")), LONG_TIMEOUT); 223 Assert.assertNotNull("Scene1 button can't be found", scene1); 224 scene1.click(); 225 SystemClock.sleep(SHORT_TIMEOUT); 226 } 227 } 228 229 // Loads the 'hide/show' animation selectHideShowAnimationOption()230 public void selectHideShowAnimationOption() throws UiObjectNotFoundException { 231 selectAnimation("Hide-Show Animations"); 232 } 233 234 // Measures jank for 'hide/show' animation 235 @JankTest(beforeTest="selectHideShowAnimationOption", afterTest="goBackHome", 236 expectedFrames=EXPECTED_FRAMES) 237 @GfxMonitor(processName=PACKAGE_NAME) testHideShowAnimationJank()238 public void testHideShowAnimationJank() { 239 for (int i = 0; i < INNER_LOOP; i++) { 240 UiObject2 showButton = mDevice.wait(Until.findObject(By.res( 241 PACKAGE_NAME, "addNewButton").text("SHOW BUTTONS")), LONG_TIMEOUT); 242 Assert.assertNotNull("'Show Buttons' button can't be found", showButton); 243 showButton.click(); 244 SystemClock.sleep(SHORT_TIMEOUT); 245 246 UiObject2 button0 = mDevice.wait(Until.findObject( 247 By.clazz(Button.class).text("0")), LONG_TIMEOUT); 248 Assert.assertNotNull("Button0 isn't found", button0); 249 button0.click(); 250 SystemClock.sleep(SHORT_TIMEOUT); 251 252 UiObject2 button1 = mDevice.wait(Until.findObject( 253 By.clazz(Button.class).text("1")), LONG_TIMEOUT); 254 Assert.assertNotNull("Button1 isn't found", button1); 255 button1.click(); 256 SystemClock.sleep(SHORT_TIMEOUT); 257 258 UiObject2 button2 = mDevice.wait(Until.findObject( 259 By.clazz(Button.class).text("2")), LONG_TIMEOUT); 260 Assert.assertNotNull("Button2 isn't found", button2); 261 button2.click(); 262 SystemClock.sleep(SHORT_TIMEOUT); 263 264 UiObject2 button3 = mDevice.wait(Until.findObject( 265 By.clazz(Button.class).text("3")), LONG_TIMEOUT); 266 Assert.assertNotNull("Button3 isn't found", button3); 267 button3.click(); 268 SystemClock.sleep(SHORT_TIMEOUT); 269 } 270 } 271 selectViews(String optionName)272 public void selectViews(String optionName) throws UiObjectNotFoundException { 273 launchApiDemos(); 274 UiObject2 views = null; 275 short maxAttempt = 4; 276 while (views == null && maxAttempt > 0) { 277 views = mDevice.wait(Until.findObject(By.res(RES_PACKAGE_NAME, "text1") 278 .text("Views")), LONG_TIMEOUT); 279 if (views == null) { 280 mDevice.wait(Until.findObject(By.res(RES_PACKAGE_NAME, "content")), LONG_TIMEOUT) 281 .scroll(Direction.DOWN, 1.0f); 282 } 283 --maxAttempt; 284 } 285 Assert.assertNotNull("Views item can't be found", views); 286 views.click(); 287 // Opens selective view (provided as param) from different 'ApiDemos Views' options 288 UiObject2 option = null; 289 maxAttempt = 4; 290 while (option == null && maxAttempt > 0) { 291 option = mDevice.wait(Until.findObject(By.res(RES_PACKAGE_NAME, "text1") 292 .text(optionName)), LONG_TIMEOUT); 293 if (option == null) { 294 mDevice.wait(Until.findObject(By.res(RES_PACKAGE_NAME, "content")), LONG_TIMEOUT) 295 .scroll(Direction.DOWN, 1.0f); 296 } 297 --maxAttempt; 298 } 299 Assert.assertNotNull("Target option to be tested in ApiDemos Views can't be found", option); 300 option.click(); 301 } 302 303 // Loads simple listview selectListsArray()304 public void selectListsArray() throws UiObjectNotFoundException { 305 selectViews("Lists"); 306 UiObject2 array = mDevice.wait(Until.findObject( 307 By.res(RES_PACKAGE_NAME, "text1").text("01. Array")), LONG_TIMEOUT); 308 Assert.assertNotNull("Array listview can't be found", array); 309 array.click(); 310 mListView = mDevice.wait(Until.findObject(By.res( 311 RES_PACKAGE_NAME, "content")), LONG_TIMEOUT); 312 Assert.assertNotNull("Content pane isn't found to move up", mListView); 313 } 314 315 // Measures jank for simple listview fling 316 @JankTest(beforeTest="selectListsArray", afterTest="goBackHome", 317 expectedFrames=EXPECTED_FRAMES) 318 @GfxMonitor(processName=PACKAGE_NAME) testListViewJank()319 public void testListViewJank() { 320 for (int i = 0; i < INNER_LOOP; i++) { 321 mListView.fling(Direction.DOWN); 322 SystemClock.sleep(SHORT_TIMEOUT); 323 mListView.fling(Direction.UP); 324 SystemClock.sleep(SHORT_TIMEOUT); 325 } 326 } 327 328 // Loads simple expandable list view selectExpandableListsSimpleAdapter()329 public void selectExpandableListsSimpleAdapter() throws UiObjectNotFoundException { 330 selectViews("Expandable Lists"); 331 UiObject2 simpleAdapter = mDevice.wait(Until.findObject( 332 By.res(RES_PACKAGE_NAME, "text1").text("3. Simple Adapter")), LONG_TIMEOUT); 333 Assert.assertNotNull("Simple adapter can't be found", simpleAdapter); 334 simpleAdapter.click(); 335 } 336 337 // Measures jank for simple expandable list view expansion 338 // Expansion group1, group3 and group4 arbitrarily selected 339 @JankTest(beforeTest="selectExpandableListsSimpleAdapter", afterTest="goBackHome", 340 expectedFrames=EXPECTED_FRAMES) 341 @GfxMonitor(processName=PACKAGE_NAME) testExapandableListViewJank()342 public void testExapandableListViewJank() { 343 for (int i = 0; i < INNER_LOOP; i++) { 344 UiObject2 group1 = mDevice.wait(Until.findObject(By.res( 345 RES_PACKAGE_NAME, "text1").text("Group 1")), LONG_TIMEOUT); 346 Assert.assertNotNull("Group 1 isn't found to be expanded", group1); 347 group1.click(); 348 SystemClock.sleep(SHORT_TIMEOUT); 349 group1.click(); 350 SystemClock.sleep(SHORT_TIMEOUT); 351 UiObject2 group3 = mDevice.wait(Until.findObject(By.res( 352 RES_PACKAGE_NAME, "text1").text("Group 3")), LONG_TIMEOUT); 353 Assert.assertNotNull("Group 3 isn't found to be expanded", group3); 354 group3.click(); 355 SystemClock.sleep(SHORT_TIMEOUT); 356 group3.click(); 357 SystemClock.sleep(SHORT_TIMEOUT); 358 UiObject2 group4 = mDevice.wait(Until.findObject(By.res( 359 RES_PACKAGE_NAME, "text1").text("Group 4")), LONG_TIMEOUT); 360 Assert.assertNotNull("Group 4 isn't found to be expanded", group4); 361 group4.click(); 362 SystemClock.sleep(SHORT_TIMEOUT); 363 group4.click(); 364 SystemClock.sleep(SHORT_TIMEOUT); 365 UiObject2 content = mDevice.wait(Until.findObject(By.res( 366 RES_PACKAGE_NAME, "content")), LONG_TIMEOUT); 367 Assert.assertNotNull("Content pane isn't found to move up", content); 368 content.fling(Direction.UP); 369 SystemClock.sleep(SHORT_TIMEOUT); 370 } 371 } 372 } 373