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