1 /*
2  * Copyright (C) 2020 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 package com.android.settings.tests.perf;
17 
18 import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
19 
20 import static junit.framework.TestCase.fail;
21 
22 import android.app.Instrumentation;
23 import android.os.Bundle;
24 import android.support.test.uiautomator.By;
25 import android.support.test.uiautomator.UiDevice;
26 import android.support.test.uiautomator.Until;
27 
28 import androidx.test.InstrumentationRegistry;
29 import androidx.test.runner.AndroidJUnit4;
30 
31 import org.junit.After;
32 import org.junit.Before;
33 import org.junit.Test;
34 import org.junit.runner.RunWith;
35 
36 import java.util.ArrayList;
37 import java.util.Collections;
38 import java.util.LinkedHashMap;
39 import java.util.Map;
40 import java.util.regex.Matcher;
41 import java.util.regex.Pattern;
42 
43 @RunWith(AndroidJUnit4.class)
44 public class LaunchSettingsTest {
45     private static class Page {
46         String action;
47         String displayName;
48         String title;
49 
Page(String action, String displayName, String title)50         Page(String action, String displayName, String title) {
51             this.action = action;
52             this.displayName = displayName;
53             this.title = title;
54         }
55     }
56 
57     private static final int TIME_OUT = 5000;
58     private static final int TEST_TIME = 10;
59     private static final Pattern PATTERN = Pattern.compile("TotalTime:\\s[0-9]*");
60     private static final Page[] PAGES;
61 
62     static {
63         PAGES = new Page[]{
64                 new Page("android.settings.SETTINGS", "Search settings", "Settings"),
65                 new Page("android.settings.WIFI_SETTINGS", "Use Wi‑Fi", "Wi-Fi"),
66                 new Page("android.settings.BLUETOOTH_SETTINGS", "Connected devices", "BlueTooth"),
67                 new Page("android.settings.APPLICATION_SETTINGS", "App info", "Application"),
68                 new Page("android.intent.action.POWER_USAGE_SUMMARY", "Battery", "Battery")
69         };
70     }
71 
72     private Bundle mBundle;
73     private UiDevice mDevice;
74     private Instrumentation mInstrumentation;
75     private Map<String, ArrayList<Integer>> mResult;
76 
77     @Before
setUp()78     public void setUp() throws Exception {
79         mBundle = new Bundle();
80         mDevice = UiDevice.getInstance(getInstrumentation());
81         mInstrumentation = InstrumentationRegistry.getInstrumentation();
82         mResult = new LinkedHashMap<>();
83         mDevice.pressHome();
84         mDevice.waitForIdle(TIME_OUT);
85 
86         for (Page page : PAGES) {
87             mResult.put(page.title, new ArrayList<Integer>());
88         }
89     }
90 
91     @After
tearDown()92     public void tearDown() throws Exception {
93         putResultToBundle();
94         mInstrumentation.sendStatus(0, mBundle);
95     }
96 
97     @Test
settingsPerformanceTest()98     public void settingsPerformanceTest() throws Exception {
99         for (int i = 0; i < TEST_TIME; i++) {
100             for (Page page : PAGES) {
101                 executePreformanceTest(page.action, page.displayName, page.title);
102             }
103         }
104     }
105 
executePreformanceTest(String action, String displayName, String title)106     private void executePreformanceTest(String action, String displayName, String title)
107             throws Exception {
108         final String mString = mDevice.executeShellCommand("am start -W -a" + action);
109         mDevice.wait(Until.findObject(By.text(displayName)), TIME_OUT);
110         handleLaunchResult(title, mString);
111         closeApp();
112         mDevice.waitForIdle(TIME_OUT);
113     }
114 
handleLaunchResult(String title, String s)115     private void handleLaunchResult(String title, String s) {
116         Matcher mMatcher = PATTERN.matcher(s);
117         if (mMatcher.find()) {
118             mResult.get(title).add(Integer.valueOf(mMatcher.group().split("\\s")[1]));
119         } else {
120             fail("Some pages can't be found");
121         }
122     }
123 
closeApp()124     private void closeApp() throws Exception {
125         mDevice.executeShellCommand("am force-stop com.android.settings");
126         Thread.sleep(1000);
127     }
128 
putResultToBundle()129     private void putResultToBundle() {
130         for (String string : mResult.keySet()) {
131             mBundle.putString(String.format("LaunchSettingsTest_%s_%s", string, "max"),
132                     getMax(mResult.get(string)));
133             mBundle.putString(String.format("LaunchSettingsTest_%s_%s", string, "min"),
134                     getMin(mResult.get(string)));
135             mBundle.putString(String.format("LaunchSettingsTest_%s_%s", string, "avg"),
136                     getAvg(mResult.get(string)));
137         }
138     }
139 
getMax(ArrayList<Integer> launchResult)140     private String getMax(ArrayList<Integer> launchResult) {
141         return String.format("%s", launchResult.isEmpty() ? "null" : Collections.max(launchResult));
142     }
143 
getMin(ArrayList<Integer> launchResult)144     private String getMin(ArrayList<Integer> launchResult) {
145         return String.format("%s", launchResult.isEmpty() ? "null" : Collections.min(launchResult));
146     }
147 
getAvg(ArrayList<Integer> launchResult)148     private String getAvg(ArrayList<Integer> launchResult) {
149         return String.valueOf((int) launchResult.stream().mapToInt(i -> i).average().orElse(0));
150     }
151 }