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.sysapp.janktests;
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.os.Bundle;
25 import android.os.Environment;
26 import android.os.RemoteException;
27 import android.os.SystemClock;
28 import android.support.test.jank.GfxMonitor;
29 import android.support.test.jank.JankTest;
30 import android.support.test.jank.JankTestBase;
31 import android.support.test.uiautomator.By;
32 import android.support.test.uiautomator.Direction;
33 import android.support.test.uiautomator.UiDevice;
34 import android.support.test.uiautomator.UiObject2;
35 import android.support.test.uiautomator.UiObjectNotFoundException;
36 import android.support.test.uiautomator.Until;
37 import android.widget.Button;
38 import android.widget.ProgressBar;
39 import junit.framework.Assert;
40 import android.support.test.timeresulthelper.TimeResultLogger;
41 
42 /**
43  * Jank test for Books app recommendation page fling
44  */
45 
46 public class BooksJankTests extends JankTestBase {
47     private static final int LONG_TIMEOUT = 1000;
48     private static final int SHORT_TIMEOUT = 1000;
49     private static final int INNER_LOOP = 5;
50     private static final int EXPECTED_FRAMES = 100;
51     private static final String PACKAGE_NAME = "com.google.android.apps.books";
52     private UiDevice mDevice;
53     private static final File TIMESTAMP_FILE = new File(Environment.getExternalStorageDirectory()
54             .getAbsolutePath(), "autotester.log");
55     private static final File RESULTS_FILE = new File(Environment.getExternalStorageDirectory()
56             .getAbsolutePath(), "results.log");
57 
58     @Override
setUp()59     public void setUp() throws Exception {
60         super.setUp();
61         mDevice = UiDevice.getInstance(getInstrumentation());
62         try {
63             mDevice.setOrientationNatural();
64         } catch (RemoteException e) {
65             throw new RuntimeException("failed to freeze device orientaion", e);
66         }
67     }
68 
69     @Override
tearDown()70     protected void tearDown() throws Exception {
71         mDevice.unfreezeRotation();
72         super.tearDown();
73     }
74 
launchApp(String packageName)75     public void launchApp(String packageName) throws UiObjectNotFoundException{
76         PackageManager pm = getInstrumentation().getContext().getPackageManager();
77         Intent appIntent = pm.getLaunchIntentForPackage(packageName);
78         appIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
79         getInstrumentation().getContext().startActivity(appIntent);
80         SystemClock.sleep(SHORT_TIMEOUT);
81     }
82 
launchBooks()83     public void launchBooks () throws UiObjectNotFoundException, IOException {
84         launchApp(PACKAGE_NAME);
85         dismissClings();
86         openMyLibrary();
87         Assert.assertTrue("Books haven't loaded yet", getNumberOfVisibleBooks() > 3);
88         TimeResultLogger.writeTimeStampLogStart(String.format("%s-%s",
89                 getClass().getSimpleName(), getName()), TIMESTAMP_FILE);
90     }
91 
afterTestBooksRecommendationPageFling(Bundle metrics)92     public void afterTestBooksRecommendationPageFling(Bundle metrics) throws IOException {
93         TimeResultLogger.writeTimeStampLogEnd(String.format("%s-%s",
94                 getClass().getSimpleName(), getName()), TIMESTAMP_FILE);
95         TimeResultLogger.writeResultToFile(String.format("%s-%s",
96                 getClass().getSimpleName(), getName()), RESULTS_FILE, metrics);
97         super.afterTest(metrics);
98     }
99 
100     // Measures jank while fling books mylibrary
101     @JankTest(beforeTest="launchBooks", expectedFrames=EXPECTED_FRAMES,
102             afterTest="afterTestBooksRecommendationPageFling")
103     @GfxMonitor(processName=PACKAGE_NAME)
104     // Books is not a system app anymore
doNotRun_BooksRecommendationPageFling()105     public void doNotRun_BooksRecommendationPageFling() {
106         UiObject2 container = mDevice.wait(Until.findObject(
107                 By.res(PACKAGE_NAME, "content_container")), LONG_TIMEOUT);
108         for (int i = 0; i < INNER_LOOP; i++) {
109           container.scroll(Direction.DOWN, 1.0f);
110           SystemClock.sleep(SHORT_TIMEOUT);
111           container.scroll(Direction.UP, 1.0f);
112         }
113     }
114 
115     // All helper methods are at bottom
116     // with the assumptions is that these will have their own library
dismissClings()117     private void dismissClings() {
118         // Dismiss confidentiality warning. It's okay to timeout here.
119         UiObject2 warning = mDevice.wait(
120                 Until.findObject(By.clazz(".Button").text("OK")), LONG_TIMEOUT);
121         if (warning != null) {
122             warning. click();
123         }
124         // Close the drawer.
125         UiObject2 close = mDevice.wait(
126                 Until.findObject(By.desc("Hide navigation drawer")), LONG_TIMEOUT);
127         if (close != null) {
128             close.click();
129         }
130         // Turn sync off
131         UiObject2 syncoff = mDevice.wait(Until.findObject(
132                 By.clazz(Button.class).text("Keep sync off")), LONG_TIMEOUT);
133         if (syncoff != null) {
134             syncoff.click();
135         }
136     }
137 
openNavigationDrawer()138     public void openNavigationDrawer() {
139       if (!mDevice.hasObject(By.res(PACKAGE_NAME, "play_drawer_container"))) {
140           mDevice.findObject(By.desc("Show navigation drawer")).click();
141           Assert.assertTrue("Failed to open navigation drawer", mDevice.wait(
142               Until.hasObject(By.res(PACKAGE_NAME, "play_drawer_list")), LONG_TIMEOUT));
143 
144           // Extra sleep to wait for the drawer to finish sliding in
145           SystemClock.sleep(500);
146       }
147   }
148 
openMyLibrary()149     public void openMyLibrary() {
150         openNavigationDrawer();
151         UiObject2 library = mDevice.wait(
152             Until.findObject(By.text("My Library").res("")), LONG_TIMEOUT);
153         Assert.assertNotNull("Could not find 'My Library' button", library);
154         library.click();
155     }
156 
getNumberOfVisibleBooks()157     public int getNumberOfVisibleBooks() {
158       UiObject2 list = mDevice.wait(
159               Until.findObject(By.res(PACKAGE_NAME, "cards_grid")), LONG_TIMEOUT);
160       Assert.assertNotNull("Failed to locate 'cards_grid'", list);
161       return list.getChildCount();
162     }
163 }
164