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 UiDevice mDevice; 49 50 @Override setUp()51 public void setUp() throws Exception { 52 super.setUp(); 53 mDevice = UiDevice.getInstance(getInstrumentation()); 54 mDevice.setOrientationNatural(); 55 } 56 57 @Override tearDown()58 protected void tearDown() throws Exception { 59 mDevice.unfreezeRotation(); 60 super.tearDown(); 61 } 62 launchApiDemos()63 public void launchApiDemos() { 64 Intent intent = getInstrumentation().getContext().getPackageManager() 65 .getLaunchIntentForPackage(PACKAGE_NAME); 66 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 67 getInstrumentation().getContext().startActivity(intent); 68 mDevice.waitForIdle(); 69 } selectAnimation(String optionName)70 public void selectAnimation(String optionName) { 71 launchApiDemos(); 72 UiObject2 animation = mDevice.wait(Until.findObject( 73 By.res(RES_PACKAGE_NAME, "text1").text("Animation")), LONG_TIMEOUT); 74 Assert.assertNotNull("Animation isn't found in ApiDemos", animation); 75 animation.click(); 76 UiObject2 option = mDevice.wait(Until.findObject( 77 By.res(RES_PACKAGE_NAME, "text1").text(optionName)), LONG_TIMEOUT); 78 int maxAttempt = 3; 79 while (option == null && maxAttempt > 0) { 80 mDevice.wait(Until.findObject(By.res(RES_PACKAGE_NAME, "content")), LONG_TIMEOUT) 81 .scroll(Direction.DOWN, 1.0f); 82 option = mDevice.wait(Until.findObject(By.res(RES_PACKAGE_NAME, "text1") 83 .text(optionName)), LONG_TIMEOUT); 84 --maxAttempt; 85 } 86 Assert.assertNotNull("Target option in APiDemos animation for test isn't found", option); 87 option.click(); 88 } 89 90 // Since the app doesn't start at the first page when reloaded after the first time, 91 // ensuring that we head back to the first screen before going Home so we're always 92 // on screen one. goBackHome(Bundle metrics)93 public void goBackHome(Bundle metrics) throws UiObjectNotFoundException { 94 String launcherPackage = mDevice.getLauncherPackageName(); 95 UiObject2 homeScreen = mDevice.findObject(By.res(launcherPackage,"workspace")); 96 while (homeScreen == null) { 97 mDevice.pressBack(); 98 homeScreen = mDevice.findObject(By.res(launcherPackage,"workspace")); 99 } 100 super.afterTest(metrics); 101 } 102 103 // Loads the 'activity transition' animation selectActivityTransitionAnimation()104 public void selectActivityTransitionAnimation() throws UiObjectNotFoundException { 105 selectAnimation("Activity Transition"); 106 } 107 108 // Measures jank for activity transition animation 109 @JankTest(beforeTest="selectActivityTransitionAnimation", afterTest="goBackHome", 110 expectedFrames=EXPECTED_FRAMES) 111 @GfxMonitor(processName=PACKAGE_NAME) testActivityTransitionAnimation()112 public void testActivityTransitionAnimation() { 113 for (int i = 0; i < INNER_LOOP; i++) { 114 UiObject2 redBallTile = mDevice.findObject(By.res(PACKAGE_NAME, "ball")); 115 redBallTile.click(); 116 SystemClock.sleep(LONG_TIMEOUT); 117 mDevice.pressBack(); 118 } 119 } 120 121 // Loads the 'view flip' animation selectViewFlipAnimation()122 public void selectViewFlipAnimation() throws UiObjectNotFoundException { 123 selectAnimation("View Flip"); 124 } 125 126 // Measures jank for view flip animation 127 @JankTest(beforeTest="selectViewFlipAnimation", afterTest="goBackHome", 128 expectedFrames=EXPECTED_FRAMES) 129 @GfxMonitor(processName=PACKAGE_NAME) testViewFlipAnimation()130 public void testViewFlipAnimation() { 131 for (int i = 0; i < INNER_LOOP; i++) { 132 UiObject2 flipButton = mDevice.findObject(By.res(PACKAGE_NAME, "button")); 133 flipButton.click(); 134 SystemClock.sleep(LONG_TIMEOUT); 135 } 136 } 137 138 // Loads the 'cloning' animation selectCloningAnimation()139 public void selectCloningAnimation() throws UiObjectNotFoundException { 140 selectAnimation("Cloning"); 141 } 142 143 // Measures jank for cloning animation 144 @JankTest(beforeTest="selectCloningAnimation", afterTest="goBackHome", 145 expectedFrames=EXPECTED_FRAMES) 146 @GfxMonitor(processName=PACKAGE_NAME) testCloningAnimation()147 public void testCloningAnimation() { 148 for (int i = 0; i < INNER_LOOP; i++) { 149 UiObject2 runCloningButton = mDevice.findObject(By.res(PACKAGE_NAME, "startButton")); 150 runCloningButton.click(); 151 SystemClock.sleep(LONG_TIMEOUT); 152 } 153 } 154 155 // Loads the 'loading' animation selectLoadingOption()156 public void selectLoadingOption() throws UiObjectNotFoundException { 157 selectAnimation("Loading"); 158 } 159 160 // Measures jank for 'loading' animation 161 @JankTest(beforeTest="selectLoadingOption", afterTest="goBackHome", 162 expectedFrames=EXPECTED_FRAMES) 163 @GfxMonitor(processName=PACKAGE_NAME) testLoadingJank()164 public void testLoadingJank() { 165 UiObject2 runButton = mDevice.wait(Until.findObject( 166 By.res(PACKAGE_NAME, "startButton").text("Run")), LONG_TIMEOUT); 167 Assert.assertNotNull("Run button is null", runButton); 168 for (int i = 0; i < INNER_LOOP; i++) { 169 runButton.click(); 170 SystemClock.sleep(SHORT_TIMEOUT * 2); 171 } 172 } 173 174 // Loads the 'simple transition' animation selectSimpleTransitionOption()175 public void selectSimpleTransitionOption() throws UiObjectNotFoundException { 176 selectAnimation("Simple Transitions"); 177 } 178 179 // Measures jank for 'simple transition' animation 180 @JankTest(beforeTest="selectSimpleTransitionOption", afterTest="goBackHome", 181 expectedFrames=EXPECTED_FRAMES) 182 @GfxMonitor(processName=PACKAGE_NAME) testSimpleTransitionJank()183 public void testSimpleTransitionJank() { 184 for (int i = 0; i < INNER_LOOP; i++) { 185 UiObject2 scene2 = mDevice.wait(Until.findObject( 186 By.res(PACKAGE_NAME, "scene2")), LONG_TIMEOUT); 187 Assert.assertNotNull("Scene2 button can't be found", scene2); 188 scene2.click(); 189 SystemClock.sleep(SHORT_TIMEOUT); 190 191 UiObject2 scene1 = mDevice.wait(Until.findObject( 192 By.res(PACKAGE_NAME, "scene1")), LONG_TIMEOUT); 193 Assert.assertNotNull("Scene1 button can't be found", scene1); 194 scene1.click(); 195 SystemClock.sleep(SHORT_TIMEOUT); 196 } 197 } 198 199 // Loads the 'hide/show' animation selectHideShowAnimationOption()200 public void selectHideShowAnimationOption() throws UiObjectNotFoundException { 201 selectAnimation("Hide-Show Animations"); 202 } 203 204 // Measures jank for 'hide/show' animation 205 @JankTest(beforeTest="selectHideShowAnimationOption", afterTest="goBackHome", 206 expectedFrames=EXPECTED_FRAMES) 207 @GfxMonitor(processName=PACKAGE_NAME) testHideShowAnimationJank()208 public void testHideShowAnimationJank() { 209 for (int i = 0; i < INNER_LOOP; i++) { 210 UiObject2 showButton = mDevice.wait(Until.findObject(By.res( 211 PACKAGE_NAME, "addNewButton").text("Show Buttons")), LONG_TIMEOUT); 212 Assert.assertNotNull("'Show Buttons' button can't be found", showButton); 213 showButton.click(); 214 SystemClock.sleep(SHORT_TIMEOUT); 215 216 UiObject2 button0 = mDevice.wait(Until.findObject( 217 By.clazz(Button.class).text("0")), LONG_TIMEOUT); 218 Assert.assertNotNull("Button0 isn't found", button0); 219 button0.click(); 220 SystemClock.sleep(SHORT_TIMEOUT); 221 222 UiObject2 button1 = mDevice.wait(Until.findObject( 223 By.clazz(Button.class).text("1")), LONG_TIMEOUT); 224 Assert.assertNotNull("Button1 isn't found", button1); 225 button1.click(); 226 SystemClock.sleep(SHORT_TIMEOUT); 227 228 UiObject2 button2 = mDevice.wait(Until.findObject( 229 By.clazz(Button.class).text("2")), LONG_TIMEOUT); 230 Assert.assertNotNull("Button2 isn't found", button2); 231 button2.click(); 232 SystemClock.sleep(SHORT_TIMEOUT); 233 234 UiObject2 button3 = mDevice.wait(Until.findObject( 235 By.clazz(Button.class).text("3")), LONG_TIMEOUT); 236 Assert.assertNotNull("Button3 isn't found", button3); 237 button3.click(); 238 SystemClock.sleep(SHORT_TIMEOUT); 239 } 240 } 241 selectViews(String optionName)242 public void selectViews(String optionName) { 243 launchApiDemos(); 244 UiObject2 views = null; 245 short maxAttempt = 4; 246 while (views == null && maxAttempt > 0) { 247 views = mDevice.wait(Until.findObject(By.res(RES_PACKAGE_NAME, "text1") 248 .text("Views")), LONG_TIMEOUT); 249 if (views == null) { 250 mDevice.wait(Until.findObject(By.res(RES_PACKAGE_NAME, "content")), LONG_TIMEOUT) 251 .scroll(Direction.DOWN, 1.0f); 252 } 253 --maxAttempt; 254 } 255 Assert.assertNotNull("Views item can't be found", views); 256 views.click(); 257 // Opens selective view (provided as param) from different 'ApiDemos Views' options 258 UiObject2 option = null; 259 maxAttempt = 4; 260 while (option == null && maxAttempt > 0) { 261 option = mDevice.wait(Until.findObject(By.res(RES_PACKAGE_NAME, "text1") 262 .text(optionName)), LONG_TIMEOUT); 263 if (option == null) { 264 mDevice.wait(Until.findObject(By.res(RES_PACKAGE_NAME, "content")), LONG_TIMEOUT) 265 .scroll(Direction.DOWN, 1.0f); 266 } 267 --maxAttempt; 268 } 269 Assert.assertNotNull("Target option to be tested in ApiDemos Views can't be found", option); 270 option.click(); 271 } 272 273 // Loads simple listview selectListsArray()274 public void selectListsArray() throws UiObjectNotFoundException { 275 selectViews("Lists"); 276 UiObject2 array = mDevice.wait(Until.findObject( 277 By.res(RES_PACKAGE_NAME, "text1").text("01. Array")), LONG_TIMEOUT); 278 Assert.assertNotNull("Array listview can't be found", array); 279 array.click(); 280 } 281 282 // Measures jank for simple listview fling 283 @JankTest(beforeTest="selectListsArray", afterTest="goBackHome", 284 expectedFrames=EXPECTED_FRAMES) 285 @GfxMonitor(processName=PACKAGE_NAME) testListViewJank()286 public void testListViewJank() { 287 for (int i = 0; i < INNER_LOOP; i++) { 288 UiObject2 listView = mDevice.wait(Until.findObject(By.res( 289 RES_PACKAGE_NAME, "content")), LONG_TIMEOUT); 290 Assert.assertNotNull("Content pane isn't found to move up", listView); 291 listView.fling(Direction.DOWN); 292 SystemClock.sleep(SHORT_TIMEOUT); 293 listView.fling(Direction.UP); 294 SystemClock.sleep(SHORT_TIMEOUT); 295 } 296 } 297 298 // Loads simple expandable list view selectExpandableListsSimpleAdapter()299 public void selectExpandableListsSimpleAdapter() throws UiObjectNotFoundException { 300 selectViews("Expandable Lists"); 301 UiObject2 simpleAdapter = mDevice.wait(Until.findObject( 302 By.res(RES_PACKAGE_NAME, "text1").text("3. Simple Adapter")), LONG_TIMEOUT); 303 Assert.assertNotNull("Simple adapter can't be found", simpleAdapter); 304 simpleAdapter.click(); 305 } 306 307 // Measures jank for simple expandable list view expansion 308 // Expansion group1, group3 and group4 arbitrarily selected 309 @JankTest(beforeTest="selectExpandableListsSimpleAdapter", afterTest="goBackHome", 310 expectedFrames=EXPECTED_FRAMES) 311 @GfxMonitor(processName=PACKAGE_NAME) testExapandableListViewJank()312 public void testExapandableListViewJank() { 313 for (int i = 0; i < INNER_LOOP; i++) { 314 UiObject2 group1 = mDevice.wait(Until.findObject(By.res( 315 RES_PACKAGE_NAME, "text1").text("Group 1")), LONG_TIMEOUT); 316 Assert.assertNotNull("Group 1 isn't found to be expanded", group1); 317 group1.click(); 318 SystemClock.sleep(SHORT_TIMEOUT); 319 group1.click(); 320 SystemClock.sleep(SHORT_TIMEOUT); 321 UiObject2 group3 = mDevice.wait(Until.findObject(By.res( 322 RES_PACKAGE_NAME, "text1").text("Group 3")), LONG_TIMEOUT); 323 Assert.assertNotNull("Group 3 isn't found to be expanded", group3); 324 group3.click(); 325 SystemClock.sleep(SHORT_TIMEOUT); 326 group3.click(); 327 SystemClock.sleep(SHORT_TIMEOUT); 328 UiObject2 group4 = mDevice.wait(Until.findObject(By.res( 329 RES_PACKAGE_NAME, "text1").text("Group 4")), LONG_TIMEOUT); 330 Assert.assertNotNull("Group 4 isn't found to be expanded", group4); 331 group4.click(); 332 SystemClock.sleep(SHORT_TIMEOUT); 333 group4.click(); 334 SystemClock.sleep(SHORT_TIMEOUT); 335 UiObject2 content = mDevice.wait(Until.findObject(By.res( 336 RES_PACKAGE_NAME, "content")), LONG_TIMEOUT); 337 Assert.assertNotNull("Content pane isn't found to move up", content); 338 content.fling(Direction.UP); 339 SystemClock.sleep(SHORT_TIMEOUT); 340 } 341 } 342 } 343