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