• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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