• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2019 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.uibench.microbenchmark;
18 
19 import android.app.Instrumentation;
20 import android.content.ComponentName;
21 import android.content.Context;
22 import android.content.Intent;
23 import android.os.Bundle;
24 import android.os.SystemClock;
25 import android.platform.helpers.AbstractStandardAppHelper;
26 import android.support.test.uiautomator.By;
27 import android.support.test.uiautomator.Direction;
28 import android.support.test.uiautomator.UiObject2;
29 import android.support.test.uiautomator.Until;
30 import android.util.DisplayMetrics;
31 import android.view.KeyEvent;
32 import android.widget.EditText;
33 import android.widget.ListView;
34 
35 import junit.framework.Assert;
36 
37 public class UiBenchJankHelper extends AbstractStandardAppHelper implements IUiBenchJankHelper {
38     public static final int LONG_TIMEOUT = 5000;
39     public static final int FULL_TEST_DURATION = 25000;
40     public static final int FIND_OBJECT_TIMEOUT = 250;
41     public static final int SHORT_TIMEOUT = 2000;
42     public static final int EXPECTED_FRAMES = 100;
43     public static final int KEY_DELAY = 1000;
44     public static final String EXTRA_BITMAP_UPLOAD = "extra_bitmap_upload";
45     public static final String EXTRA_SHOW_FAST_LANE = "extra_show_fast_lane";
46 
47     /**
48      * Only to be used for initial-fling tests, or similar cases where perf during brief experience
49      * is important.
50      */
51     public static final int SHORT_EXPECTED_FRAMES = 30;
52 
53     public static final String PACKAGE_NAME = "com.android.test.uibench";
54 
55     public static final String APP_LAUNCHER_NAME = "UiBench";
56 
57     private static final int SLOW_FLING_SPEED = 3000; // compare to UiObject2#DEFAULT_FLING_SPEED
58 
59     // Main UiObject2 exercised by the test.
60     private UiObject2 mContents, mNavigation;
61 
UiBenchJankHelper(Instrumentation instr)62     public UiBenchJankHelper(Instrumentation instr) {
63         super(instr);
64     }
65 
66     /** {@inheritDoc} */
67     @Override
getPackage()68     public String getPackage() {
69         return PACKAGE_NAME;
70     }
71 
72     /** {@inheritDoc} */
73     @Override
getLauncherName()74     public String getLauncherName() {
75         return APP_LAUNCHER_NAME;
76     }
77 
78     /** {@inheritDoc} */
79     @Override
dismissInitialDialogs()80     public void dismissInitialDialogs() {}
81 
82     /** Launch activity using intent */
launchActivity(String activityName, Bundle extras, String verifyText)83     void launchActivity(String activityName, Bundle extras, String verifyText) {
84         ComponentName cn =
85                 new ComponentName(PACKAGE_NAME, String.format("%s.%s", PACKAGE_NAME, activityName));
86         Intent intent = new Intent(Intent.ACTION_MAIN);
87         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
88         intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
89         if (extras != null) {
90             intent.putExtras(extras);
91         }
92         intent.setComponent(cn);
93         // Launch the activity
94         mInstrumentation.getContext().startActivity(intent);
95         UiObject2 expectedTextCmp =
96                 mDevice.wait(Until.findObject(By.text(verifyText)), LONG_TIMEOUT);
97         Assert.assertNotNull(String.format("Issue in opening %s", activityName), expectedTextCmp);
98     }
99 
launchActivity(String activityName, String verifyText)100     void launchActivity(String activityName, String verifyText) {
101         launchActivity(activityName, null, verifyText);
102     }
103 
launchActivityAndAssert(String activityName, String verifyText)104     void launchActivityAndAssert(String activityName, String verifyText) {
105         launchActivity(activityName, verifyText);
106         mContents =
107                 mDevice.wait(Until.findObject(By.res("android", "content")), FIND_OBJECT_TIMEOUT);
108         Assert.assertNotNull(activityName + " isn't found", mContents);
109     }
110 
getEdgeSensitivity()111     int getEdgeSensitivity() {
112         int resId =
113                 mInstrumentation
114                         .getContext()
115                         .getResources()
116                         .getIdentifier("config_backGestureInset", "dimen", "android");
117         return mInstrumentation.getContext().getResources().getDimensionPixelSize(resId) + 1;
118     }
119 
120     /** To perform the fling down and up on given content for flingCount number of times */
121     @Override
flingUpDown(int flingCount)122     public void flingUpDown(int flingCount) {
123         flingUpDown(flingCount, false);
124     }
125 
126     @Override
flingDownUp(int flingCount)127     public void flingDownUp(int flingCount) {
128         flingUpDown(flingCount, true);
129     }
130 
flingUpDown(int flingCount, boolean reverse)131     void flingUpDown(int flingCount, boolean reverse) {
132         mContents.setGestureMargin(getEdgeSensitivity());
133         for (int count = 0; count < flingCount; count++) {
134             SystemClock.sleep(SHORT_TIMEOUT);
135             mContents.fling(reverse ? Direction.UP : Direction.DOWN);
136             SystemClock.sleep(SHORT_TIMEOUT);
137             mContents.fling(reverse ? Direction.DOWN : Direction.UP);
138         }
139     }
140 
141     /** To perform the swipe right and left on given content for swipeCount number of times */
142     @Override
swipeRightLeft(int swipeCount)143     public void swipeRightLeft(int swipeCount) {
144         mNavigation =
145                 mDevice.wait(
146                         Until.findObject(By.desc("Open navigation drawer")), FIND_OBJECT_TIMEOUT);
147         mContents.setGestureMargin(getEdgeSensitivity());
148         for (int count = 0; count < swipeCount; count++) {
149             SystemClock.sleep(SHORT_TIMEOUT);
150             mNavigation.click();
151             SystemClock.sleep(SHORT_TIMEOUT);
152             mContents.swipe(Direction.LEFT, 1);
153         }
154     }
155 
156     @Override
slowSingleFlingDown()157     public void slowSingleFlingDown() {
158         SystemClock.sleep(SHORT_TIMEOUT);
159         Context context = mInstrumentation.getContext();
160         DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
161         mContents.setGestureMargin(getEdgeSensitivity());
162         mContents.fling(Direction.DOWN, (int) (SLOW_FLING_SPEED * displayMetrics.density));
163         mDevice.waitForIdle();
164     }
165 
166     @Override
openDialogList()167     public void openDialogList() {
168         launchActivity("DialogListActivity", "Dialog");
169         mContents = mDevice.wait(Until.findObject(By.clazz(ListView.class)), FIND_OBJECT_TIMEOUT);
170         Assert.assertNotNull("Dialog List View isn't found", mContents);
171     }
172 
173     @Override
openFullscreenOverdraw()174     public void openFullscreenOverdraw() {
175         launchActivity("FullscreenOverdrawActivity", "General/Fullscreen Overdraw");
176     }
177 
178     @Override
openGLTextureView()179     public void openGLTextureView() {
180         launchActivity("GlTextureViewActivity", "General/GL TextureView");
181     }
182 
183     @Override
openInvalidate()184     public void openInvalidate() {
185         launchActivity("InvalidateActivity", "General/Invalidate");
186     }
187 
188     @Override
openInvalidateTree()189     public void openInvalidateTree() {
190         launchActivity("InvalidateTreeActivity", "General/Invalidate Tree");
191     }
192 
193     @Override
openTrivialAnimation()194     public void openTrivialAnimation() {
195         launchActivity("TrivialAnimationActivity", "General/Trivial Animation");
196     }
197 
198     @Override
openTrivialListView()199     public void openTrivialListView() {
200         launchActivityAndAssert("TrivialListActivity", "General/Trivial ListView");
201     }
202 
203     @Override
openFadingEdgeListView()204     public void openFadingEdgeListView() {
205         launchActivityAndAssert("FadingEdgeListActivity", "General/Fading Edge ListView");
206     }
207 
208     @Override
openSaveLayerInterleaveActivity()209     public void openSaveLayerInterleaveActivity() {
210         launchActivityAndAssert("SaveLayerInterleaveActivity", "General/SaveLayer Animation");
211     }
212 
213     @Override
openTrivialRecyclerView()214     public void openTrivialRecyclerView() {
215         launchActivityAndAssert("TrivialRecyclerViewActivity", "General/Trivial RecyclerView");
216     }
217 
218     @Override
openSlowBindRecyclerView()219     public void openSlowBindRecyclerView() {
220         launchActivityAndAssert("SlowBindRecyclerViewActivity", "General/Slow Bind RecyclerView");
221     }
222 
223     @Override
openSlowNestedRecyclerView()224     public void openSlowNestedRecyclerView() {
225         launchActivityAndAssert(
226                 "SlowNestedRecyclerViewActivity", "General/Slow Nested RecyclerView");
227     }
228 
229     @Override
openInflatingListView()230     public void openInflatingListView() {
231         launchActivityAndAssert("InflatingListActivity", "Inflation/Inflating ListView");
232     }
233 
234     @Override
openInflatingEmojiListView()235     public void openInflatingEmojiListView() {
236         launchActivityAndAssert(
237                 "InflatingEmojiListActivity", "Inflation/Inflating ListView with Emoji");
238     }
239 
240     @Override
openInflatingHanListView()241     public void openInflatingHanListView() {
242         launchActivityAndAssert(
243                 "InflatingHanListActivity", "Inflation/Inflating ListView with Han Characters");
244     }
245 
246     @Override
openInflatingLongStringListView()247     public void openInflatingLongStringListView() {
248         launchActivityAndAssert(
249                 "InflatingLongStringListActivity", "Inflation/Inflating ListView with long string");
250     }
251 
252     @Override
openNavigationDrawerActivity()253     public void openNavigationDrawerActivity() {
254         launchActivityAndAssert("NavigationDrawerActivity", "Navigation Drawer Activity");
255         mContents.setGestureMargins(0, 0, 10, 0);
256     }
257 
258     @Override
openNotificationShade()259     public void openNotificationShade() {
260         launchActivityAndAssert("NotificationShadeActivity", "Notification Shade");
261     }
262 
263     @Override
openResizeHWLayer()264     public void openResizeHWLayer() {
265         launchActivity("ResizeHWLayerActivity", "General/Resize HW Layer");
266     }
267 
268     @Override
openClippedListView()269     public void openClippedListView() {
270         launchActivityAndAssert("ClippedListActivity", "General/Clipped ListView");
271     }
272 
273     @Override
openLeanbackActivity( boolean extraBitmapUpload, boolean extraShowFastLane, String activityName, String expectedText)274     public void openLeanbackActivity(
275             boolean extraBitmapUpload,
276             boolean extraShowFastLane,
277             String activityName,
278             String expectedText) {
279         Bundle extrasBundle = new Bundle();
280         extrasBundle.putBoolean(EXTRA_BITMAP_UPLOAD, extraBitmapUpload);
281         extrasBundle.putBoolean(EXTRA_SHOW_FAST_LANE, extraShowFastLane);
282         launchActivity(activityName, extrasBundle, expectedText);
283     }
284 
pressKeyCode(int keyCode)285     void pressKeyCode(int keyCode) {
286         SystemClock.sleep(KEY_DELAY);
287         mDevice.pressKeyCode(keyCode);
288     }
289 
290     @Override
scrollDownAndUp(int count)291     public void scrollDownAndUp(int count) {
292         for (int i = 0; i < count; i++) {
293             pressKeyCode(KeyEvent.KEYCODE_DPAD_DOWN);
294         }
295         for (int i = 0; i < count; i++) {
296             pressKeyCode(KeyEvent.KEYCODE_DPAD_UP);
297         }
298     }
299 
300     // Open Bitmap Upload
301     @Override
openBitmapUpload()302     public void openBitmapUpload() {
303         launchActivity("BitmapUploadActivity", "Rendering/Bitmap Upload");
304     }
305 
306     // Open Shadow Grid
307     @Override
openRenderingList()308     public void openRenderingList() {
309         launchActivity("ShadowGridActivity", "Rendering/Shadow Grid");
310         mContents = mDevice.wait(Until.findObject(By.clazz(ListView.class)), FIND_OBJECT_TIMEOUT);
311         Assert.assertNotNull("Shadow Grid list isn't found", mContents);
312     }
313 
314     // Open EditText Typing
315     @Override
openEditTextTyping()316     public void openEditTextTyping() {
317         launchActivity("EditTextTypeActivity", "Text/EditText Typing");
318         mContents = mDevice.wait(Until.findObject(By.clazz(EditText.class)), FIND_OBJECT_TIMEOUT);
319     }
320 
321     // Open Layout Cache High Hitrate
322     @Override
openLayoutCacheHighHitrate()323     public void openLayoutCacheHighHitrate() {
324         launchActivity("TextCacheHighHitrateActivity", "Text/Layout Cache High Hitrate");
325         mContents = mDevice.wait(Until.findObject(By.clazz(ListView.class)), FIND_OBJECT_TIMEOUT);
326         Assert.assertNotNull("LayoutCacheHighHitrateContents isn't found", mContents);
327     }
328 
329     // Open Layout Cache Low Hitrate
330     @Override
openLayoutCacheLowHitrate()331     public void openLayoutCacheLowHitrate() {
332         launchActivity("TextCacheLowHitrateActivity", "Text/Layout Cache Low Hitrate");
333         mContents = mDevice.wait(Until.findObject(By.clazz(ListView.class)), FIND_OBJECT_TIMEOUT);
334         Assert.assertNotNull("LayoutCacheLowHitrateContents isn't found", mContents);
335     }
336 
337     // Open Transitions
338     @Override
openActivityTransition()339     public void openActivityTransition() {
340         launchActivity("ActivityTransition", "Transitions/Activity Transition");
341     }
342 
343     @Override
openWindowInsetsController()344     public void openWindowInsetsController() {
345         launchActivityAndAssert("WindowInsetsControllerActivity", "WindowInsetsControllerActivity");
346     }
347 
348     // Get the image to click
349     @Override
clickImage(String imageName)350     public void clickImage(String imageName) {
351         UiObject2 image =
352                 mDevice.wait(
353                         Until.findObject(By.res(PACKAGE_NAME, imageName)), FIND_OBJECT_TIMEOUT);
354         Assert.assertNotNull(imageName + "Image not found", image);
355         image.clickAndWait(Until.newWindow(), FIND_OBJECT_TIMEOUT);
356         mDevice.pressBack();
357     }
358 
359     // Open Scrollable WebView from WebView test
360     @Override
openScrollableWebView()361     public void openScrollableWebView() {
362         launchActivity("ScrollableWebViewActivity", "WebView/Scrollable WebView");
363         mContents =
364                 mDevice.wait(Until.findObject(By.res("android", "content")), FIND_OBJECT_TIMEOUT);
365     }
366 }
367