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 android.platform.systemui.tests.jank;
18 
19 import java.io.File;
20 import java.io.IOException;
21 
22 import android.content.Intent;
23 import android.content.pm.PackageManager;
24 import android.graphics.Point;
25 import android.graphics.Rect;
26 import android.os.Environment;
27 import android.os.RemoteException;
28 import android.os.SystemClock;
29 import android.support.test.jank.GfxMonitor;
30 import android.support.test.jank.JankTest;
31 import android.support.test.jank.JankTestBase;
32 import android.support.test.jank.WindowAnimationFrameStatsMonitor;
33 import android.support.test.launcherhelper.ILauncherStrategy;
34 import android.support.test.launcherhelper.LauncherStrategyFactory;
35 import android.support.test.uiautomator.By;
36 import android.support.test.uiautomator.Direction;
37 import android.support.test.uiautomator.UiDevice;
38 import android.support.test.uiautomator.UiObject2;
39 import android.support.test.uiautomator.UiObjectNotFoundException;
40 import android.support.test.timeresulthelper.TimeResultLogger;
41 import android.os.Bundle;
42 
43 /*
44  * LauncherTwoJankTests cover the old launcher, and
45  * LauncherJankTests cover the new GEL Launcher.
46  */
47 public class LauncherJankTests extends JankTestBase {
48 
49     private static final int TIMEOUT = 5000;
50     // short transitions should be repeated within the test function, otherwise frame stats
51     // captured are not really meaningful in a statistical sense
52     private static final int INNER_LOOP = 3;
53     private static final int FLING_SPEED = 12000;
54     private UiDevice mDevice;
55     private PackageManager pm;
56     private ILauncherStrategy mLauncherStrategy = null;
57     private static final File TIMESTAMP_FILE = new File(Environment.getExternalStorageDirectory()
58             .getAbsolutePath(),"autotester.log");
59     private static final File RESULTS_FILE = new File(Environment.getExternalStorageDirectory()
60             .getAbsolutePath(),"results.log");
61 
62     @Override
setUp()63     public void setUp() {
64         mDevice = UiDevice.getInstance(getInstrumentation());
65         pm = getInstrumentation().getContext().getPackageManager();
66         try {
67             mDevice.setOrientationNatural();
68         } catch (RemoteException e) {
69             throw new RuntimeException("failed to freeze device orientaion", e);
70         }
71         mLauncherStrategy = LauncherStrategyFactory.getInstance(mDevice).getLauncherStrategy();
72     }
73 
getLauncherPackage()74     public String getLauncherPackage() {
75         return mDevice.getLauncherPackageName();
76     }
77 
78     @Override
tearDown()79     protected void tearDown() throws Exception {
80         mDevice.unfreezeRotation();
81         super.tearDown();
82     }
83 
goHome()84     public void goHome() throws UiObjectNotFoundException {
85         mLauncherStrategy.open();
86     }
87 
resetAllApps()88     public void resetAllApps() throws UiObjectNotFoundException {
89         mLauncherStrategy.openAllApps(true);
90         mLauncherStrategy.open();
91     }
92 
prepareOpenAllAppsContainer()93     public void prepareOpenAllAppsContainer() throws IOException {
94         TimeResultLogger.writeTimeStampLogStart(String.format("%s-%s",
95                 getClass().getSimpleName(), getName()), TIMESTAMP_FILE);
96     }
97 
afterTestOpenAllAppsContainer(Bundle metrics)98     public void afterTestOpenAllAppsContainer(Bundle metrics) throws IOException {
99         TimeResultLogger.writeTimeStampLogEnd(String.format("%s-%s",
100                 getClass().getSimpleName(), getName()), TIMESTAMP_FILE);
101         TimeResultLogger.writeResultToFile(String.format("%s-%s",
102                 getClass().getSimpleName(), getName()), RESULTS_FILE, metrics);
103         super.afterTest(metrics);
104     }
105 
106     /** Starts from the home screen, and measures jank while opening the all apps container. */
107     @JankTest(expectedFrames=100, beforeTest="prepareOpenAllAppsContainer",
108             beforeLoop="resetAllApps", afterTest="afterTestOpenAllAppsContainer")
109     @GfxMonitor(processName="#getLauncherPackage")
testOpenAllAppsContainer()110     public void testOpenAllAppsContainer() throws UiObjectNotFoundException {
111         for (int i = 0; i < INNER_LOOP * 2; i++) {
112             mLauncherStrategy.openAllApps(false);
113             mDevice.waitForIdle();
114             mLauncherStrategy.open();
115             mDevice.waitForIdle();
116         }
117     }
118 
openAllApps()119     public void openAllApps() throws UiObjectNotFoundException, IOException {
120         mLauncherStrategy.openAllApps(true);
121         TimeResultLogger.writeTimeStampLogStart(String.format("%s-%s",
122                 getClass().getSimpleName(), getName()), TIMESTAMP_FILE);
123     }
124 
afterTestAllAppsContainerSwipe(Bundle metrics)125     public void afterTestAllAppsContainerSwipe(Bundle metrics) throws IOException {
126         TimeResultLogger.writeTimeStampLogEnd(String.format("%s-%s",
127                 getClass().getSimpleName(), getName()), TIMESTAMP_FILE);
128         TimeResultLogger.writeResultToFile(String.format("%s-%s",
129                 getClass().getSimpleName(), getName()), RESULTS_FILE, metrics);
130         super.afterTest(metrics);
131     }
132 
133     /** Starts from the all apps container, and measures jank while swiping between pages */
134     @JankTest(beforeTest="openAllApps", afterTest="afterTestAllAppsContainerSwipe",
135             expectedFrames=100)
136     @GfxMonitor(processName="#getLauncherPackage")
testAllAppsContainerSwipe()137     public void testAllAppsContainerSwipe() {
138         UiObject2 allApps = mDevice.findObject(mLauncherStrategy.getAllAppsSelector());
139         Direction dir = mLauncherStrategy.getAllAppsScrollDirection();
140         for (int i = 0; i < INNER_LOOP * 2; i++) {
141             allApps.fling(dir, FLING_SPEED);
142             allApps.fling(Direction.reverse(dir), FLING_SPEED);
143         }
144     }
145 
makeHomeScrollable()146     public void makeHomeScrollable() throws UiObjectNotFoundException, IOException {
147         mLauncherStrategy.open();
148         UiObject2 homeScreen = mDevice.findObject(mLauncherStrategy.getWorkspaceSelector());
149         Rect r = homeScreen.getVisibleBounds();
150         if (!homeScreen.isScrollable()) {
151             // Add the Chrome icon to the first launcher screen.
152             // This is specifically for Bullhead, where you can't add an icon
153             // to the second launcher screen without one on the first.
154             UiObject2 chrome = mDevice.findObject(By.text("Chrome"));
155             Point dest = new Point(mDevice.getDisplayWidth()/2, r.centerY());
156             chrome.drag(dest, 2000);
157             // Drag Camera icon to next screen
158             UiObject2 camera = mDevice.findObject(By.text("Camera"));
159             dest = new Point(mDevice.getDisplayWidth(), r.centerY());
160             camera.drag(dest, 2000);
161         }
162         mDevice.waitForIdle();
163         assertTrue("home screen workspace still not scrollable", homeScreen.isScrollable());
164         TimeResultLogger.writeTimeStampLogStart(String.format("%s-%s",
165                 getClass().getSimpleName(), getName()), TIMESTAMP_FILE);
166     }
167 
afterTestHomeScreenSwipe(Bundle metrics)168     public void afterTestHomeScreenSwipe(Bundle metrics) throws IOException {
169         TimeResultLogger.writeTimeStampLogEnd(String.format("%s-%s",
170                 getClass().getSimpleName(), getName()), TIMESTAMP_FILE);
171         TimeResultLogger.writeResultToFile(String.format("%s-%s",
172                 getClass().getSimpleName(), getName()), RESULTS_FILE, metrics);
173         super.afterTest(metrics);
174     }
175 
176     /** Starts from the home screen, and measures jank while swiping between pages */
177     @JankTest(beforeTest="makeHomeScrollable", afterTest="afterTestHomeScreenSwipe",
178               expectedFrames=100)
179     @GfxMonitor(processName="#getLauncherPackage")
testHomeScreenSwipe()180     public void testHomeScreenSwipe() {
181         UiObject2 workspace = mDevice.findObject(mLauncherStrategy.getWorkspaceSelector());
182         Direction dir = mLauncherStrategy.getWorkspaceScrollDirection();
183         for (int i = 0; i < INNER_LOOP * 2; i++) {
184             workspace.fling(dir);
185             workspace.fling(Direction.reverse(dir));
186         }
187     }
188 
openAllWidgets()189     public void openAllWidgets() throws UiObjectNotFoundException, IOException {
190         mLauncherStrategy.openAllWidgets(true);
191         TimeResultLogger.writeTimeStampLogStart(String.format("%s-%s",
192                 getClass().getSimpleName(), getName()), TIMESTAMP_FILE);
193     }
194 
afterTestWidgetsContainerFling(Bundle metrics)195     public void afterTestWidgetsContainerFling(Bundle metrics) throws IOException {
196         TimeResultLogger.writeTimeStampLogEnd(String.format("%s-%s",
197                 getClass().getSimpleName(), getName()), TIMESTAMP_FILE);
198         TimeResultLogger.writeResultToFile(String.format("%s-%s",
199                 getClass().getSimpleName(), getName()), RESULTS_FILE, metrics);
200         super.afterTest(metrics);
201     }
202 
203     /** Starts from the widgets container, and measures jank while swiping between pages */
204     @JankTest(beforeTest="openAllWidgets", afterTest="afterTestWidgetsContainerFling",
205               expectedFrames=100)
206     @GfxMonitor(processName="#getLauncherPackage")
testWidgetsContainerFling()207     public void testWidgetsContainerFling() {
208         UiObject2 allWidgets = mDevice.findObject(mLauncherStrategy.getAllWidgetsSelector());
209         Direction dir = mLauncherStrategy.getAllWidgetsScrollDirection();
210         for (int i = 0; i < INNER_LOOP; i++) {
211             allWidgets.fling(dir, FLING_SPEED);
212             allWidgets.fling(Direction.reverse(dir), FLING_SPEED);
213         }
214     }
215 
launchChrome()216     public void launchChrome() {
217         Intent chromeIntent = pm.getLaunchIntentForPackage("com.android.chrome");
218         chromeIntent.addCategory(Intent.CATEGORY_LAUNCHER);
219         chromeIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
220         getInstrumentation().getContext().startActivity(chromeIntent);
221         SystemClock.sleep(TIMEOUT);
222     }
223 
224     /** Measures jank while navigating from Chrome to Home */
225     @JankTest(beforeTest="goHome", expectedFrames=100)
226     @WindowAnimationFrameStatsMonitor
testAppSwitchChrometoHome()227     public void testAppSwitchChrometoHome() throws UiObjectNotFoundException {
228         for (int i = 0; i < INNER_LOOP; i++) {
229             launchChrome();
230             goHome();
231         }
232     }
233 
launchPhotos()234     public void launchPhotos() {
235         Intent photosIntent = pm.getLaunchIntentForPackage("com.google.android.apps.photos");
236         photosIntent.addCategory(Intent.CATEGORY_LAUNCHER);
237         photosIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
238         getInstrumentation().getContext().startActivity(photosIntent);
239         SystemClock.sleep(TIMEOUT);
240     }
241 
242     /** Measures jank while navigating from Photos to Home */
243     @JankTest(beforeTest="goHome", expectedFrames=100)
244     @WindowAnimationFrameStatsMonitor
testAppSwitchPhotostoHome()245     public void testAppSwitchPhotostoHome() throws UiObjectNotFoundException {
246         for (int i = 0; i < INNER_LOOP; i++) {
247             launchPhotos();
248             goHome();
249         }
250     }
251 
launchGMail()252     public void launchGMail() {
253         Intent gmailIntent = pm.getLaunchIntentForPackage("com.google.android.gm");
254         gmailIntent.addCategory(Intent.CATEGORY_LAUNCHER);
255         gmailIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
256         getInstrumentation().getContext().startActivity(gmailIntent);
257         SystemClock.sleep(TIMEOUT);
258     }
259 
260     /** Measures jank while navigating from GMail to Home */
261     @JankTest(beforeTest="goHome", expectedFrames=100)
262     @WindowAnimationFrameStatsMonitor
testAppSwitchGMailtoHome()263     public void testAppSwitchGMailtoHome() throws UiObjectNotFoundException {
264         for (int i = 0; i < INNER_LOOP; i++) {
265             launchPhotos();
266             goHome();
267         }
268     }
269 }
270