• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2011 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.test.tilebenchmark;
18 
19 import com.test.tilebenchmark.ProfileActivity.ProfileCallback;
20 
21 import java.io.File;
22 import java.util.HashMap;
23 import java.util.Map;
24 
25 import android.content.res.Resources;
26 import android.os.Bundle;
27 import android.os.Environment;
28 import android.test.ActivityInstrumentationTestCase2;
29 import android.util.Log;
30 import android.webkit.WebSettings;
31 import android.widget.Spinner;
32 
33 public class PerformanceTest extends
34         ActivityInstrumentationTestCase2<ProfileActivity> {
35 
36     public static class AnimStat {
37         double aggVal = 0;
38         double aggSqrVal = 0;
39         double count = 0;
40     }
41 
42     private class StatAggregator extends PlaybackGraphs {
43         private HashMap<String, Double> mDataMap = new HashMap<String, Double>();
44         private HashMap<String, AnimStat> mAnimDataMap = new HashMap<String, AnimStat>();
45         private int mCount = 0;
46 
47 
aggregate()48         public void aggregate() {
49             boolean inAnimTests = mAnimTests != null;
50             Resources resources = mWeb.getResources();
51             String animFramerateString = resources.getString(R.string.animation_framerate);
52             for (Map.Entry<String, Double> e : mSingleStats.entrySet()) {
53                 String name = e.getKey();
54                 if (inAnimTests) {
55                     if (name.equals(animFramerateString)) {
56                         // in animation testing phase, record animation framerate and aggregate
57                         // stats, differentiating on values of mAnimTestNr and mDoubleBuffering
58                         String fullName = ANIM_TEST_NAMES[mAnimTestNr] + " " + name;
59                         fullName += mDoubleBuffering ? " tiled" : " webkit";
60 
61                         if (!mAnimDataMap.containsKey(fullName)) {
62                             mAnimDataMap.put(fullName, new AnimStat());
63                         }
64                         AnimStat statVals = mAnimDataMap.get(fullName);
65                         statVals.aggVal += e.getValue();
66                         statVals.aggSqrVal += e.getValue() * e.getValue();
67                         statVals.count += 1;
68                     }
69                 } else {
70                     double aggVal = mDataMap.containsKey(name)
71                             ? mDataMap.get(name) : 0;
72                     mDataMap.put(name, aggVal + e.getValue());
73                 }
74             }
75 
76             if (inAnimTests) {
77                 return;
78             }
79 
80             mCount++;
81             for (int metricIndex = 0; metricIndex < Metrics.length; metricIndex++) {
82                 for (int statIndex = 0; statIndex < Stats.length; statIndex++) {
83                     String metricLabel = resources.getString(
84                             Metrics[metricIndex].getLabelId());
85                     String statLabel = resources.getString(
86                             Stats[statIndex].getLabelId());
87 
88                     String label = metricLabel + " " + statLabel;
89                     double aggVal = mDataMap.containsKey(label) ? mDataMap
90                             .get(label) : 0;
91 
92                     aggVal += mStats[metricIndex][statIndex];
93                     mDataMap.put(label, aggVal);
94                 }
95             }
96 
97         }
98 
99         // build the final bundle of results
getBundle()100         public Bundle getBundle() {
101             Bundle b = new Bundle();
102             int count = (0 == mCount) ? Integer.MAX_VALUE : mCount;
103             for (Map.Entry<String, Double> e : mDataMap.entrySet()) {
104                 b.putDouble(e.getKey(), e.getValue() / count);
105             }
106 
107             for (Map.Entry<String, AnimStat> e : mAnimDataMap.entrySet()) {
108                 String statName = e.getKey();
109                 AnimStat statVals = e.getValue();
110 
111                 double avg = statVals.aggVal/statVals.count;
112                 double stdDev = Math.sqrt((statVals.aggSqrVal / statVals.count) - avg * avg);
113 
114                 b.putDouble(statName, avg);
115                 b.putDouble(statName + " STD DEV", stdDev);
116             }
117 
118             return b;
119         }
120     }
121 
122     ProfileActivity mActivity;
123     ProfiledWebView mWeb;
124     Spinner mMovementSpinner;
125     StatAggregator mStats;
126 
127     private static final String LOGTAG = "PerformanceTest";
128     private static final String TEST_LOCATION = "webkit/page_cycler";
129     private static final String URL_PREFIX = "file://";
130     private static final String URL_POSTFIX = "/index.html?skip=true";
131     private static final int MAX_ITERATIONS = 4;
132     private static final String SCROLL_TEST_DIRS[] = {
133         "alexa25_2011"
134     };
135     private static final String ANIM_TEST_DIRS[] = {
136         "dhtml"
137     };
138 
PerformanceTest()139     public PerformanceTest() {
140         super(ProfileActivity.class);
141     }
142 
143     @Override
setUp()144     protected void setUp() throws Exception {
145         super.setUp();
146         mActivity = getActivity();
147         mWeb = (ProfiledWebView) mActivity.findViewById(R.id.web);
148         mMovementSpinner = (Spinner) mActivity.findViewById(R.id.movement);
149         mStats = new StatAggregator();
150 
151         // use mStats as a condition variable between the UI thread and
152         // this(the testing) thread
153         mActivity.setCallback(new ProfileCallback() {
154             @Override
155             public void profileCallback(RunData data) {
156                 mStats.setData(data);
157                 synchronized (mStats) {
158                     mStats.notify();
159                 }
160             }
161         });
162 
163     }
164 
loadUrl(final String url)165     private boolean loadUrl(final String url) {
166         try {
167             Log.d(LOGTAG, "test starting for url " + url);
168             mActivity.runOnUiThread(new Runnable() {
169                 @Override
170                 public void run() {
171                     mWeb.loadUrl(url);
172                 }
173             });
174             synchronized (mStats) {
175                 mStats.wait();
176             }
177 
178             mStats.aggregate();
179         } catch (InterruptedException e) {
180             e.printStackTrace();
181             return false;
182         }
183         return true;
184     }
185 
validTest(String nextTest)186     private boolean validTest(String nextTest) {
187         // if testing animations, test must be in mAnimTests
188         if (mAnimTests == null)
189             return true;
190 
191         for (String test : mAnimTests) {
192             if (test.equals(nextTest)) {
193                 return true;
194             }
195         }
196         return false;
197     }
198 
runIteration(String[] testDirs)199     private boolean runIteration(String[] testDirs) {
200         File sdFile = Environment.getExternalStorageDirectory();
201         for (String testDirName : testDirs) {
202             File testDir = new File(sdFile, TEST_LOCATION + "/" + testDirName);
203             Log.d(LOGTAG, "Testing dir: '" + testDir.getAbsolutePath()
204                     + "', exists=" + testDir.exists());
205 
206             for (File siteDir : testDir.listFiles()) {
207                 if (!siteDir.isDirectory() || !validTest(siteDir.getName())) {
208                     continue;
209                 }
210 
211                 if (!loadUrl(URL_PREFIX + siteDir.getAbsolutePath()
212                         + URL_POSTFIX)) {
213                     return false;
214                 }
215             }
216         }
217         return true;
218     }
219 
runTestDirs(String[] testDirs)220     private boolean  runTestDirs(String[] testDirs) {
221         for (int i = 0; i < MAX_ITERATIONS; i++)
222             if (!runIteration(testDirs)) {
223                 return false;
224             }
225         return true;
226     }
227 
pushDoubleBuffering()228     private void pushDoubleBuffering() {
229         getInstrumentation().runOnMainSync(new Runnable() {
230             public void run() {
231                 mWeb.setDoubleBuffering(mDoubleBuffering);
232             }
233         });
234     }
235 
setScrollingTestingMode(final boolean scrolled)236     private void setScrollingTestingMode(final boolean scrolled) {
237         getInstrumentation().runOnMainSync(new Runnable() {
238             public void run() {
239                 mMovementSpinner.setSelection(scrolled ? 0 : 2);
240             }
241         });
242     }
243 
244 
245     private String[] mAnimTests = null;
246     private int mAnimTestNr = -1;
247     private boolean mDoubleBuffering = true;
248     private static final String[] ANIM_TEST_NAMES = {
249         "slow", "fast"
250     };
251     private static final String[][] ANIM_TESTS = {
252         {"scrolling", "replaceimages", "layers5", "layers1"},
253         {"slidingballs", "meter", "slidein", "fadespacing", "colorfade",
254                 "mozilla", "movingtext", "diagball", "zoom", "imageslide"},
255     };
256 
checkMedia()257     private boolean checkMedia() {
258         String state = Environment.getExternalStorageState();
259 
260         if (!Environment.MEDIA_MOUNTED.equals(state)
261                 && !Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
262             Log.d(LOGTAG, "ARG Can't access sd card!");
263             // Can't read the SD card, fail and die!
264             getInstrumentation().sendStatus(1, null);
265             return false;
266         }
267         return true;
268     }
269 
testMetrics()270     public void testMetrics() {
271         setScrollingTestingMode(true);
272         if (checkMedia() && runTestDirs(SCROLL_TEST_DIRS)) {
273             getInstrumentation().sendStatus(0, mStats.getBundle());
274         } else {
275             getInstrumentation().sendStatus(1, null);
276         }
277     }
278 
testMetricsMinimalMemory()279     public void testMetricsMinimalMemory() {
280         mActivity.runOnUiThread(new Runnable() {
281             @Override
282             public void run() {
283                 mWeb.setUseMinimalMemory(true);
284             }
285         });
286 
287         setScrollingTestingMode(true);
288         if (checkMedia() && runTestDirs(SCROLL_TEST_DIRS)) {
289             getInstrumentation().sendStatus(0, mStats.getBundle());
290         } else {
291             getInstrumentation().sendStatus(1, null);
292         }
293     }
294 
runAnimationTests()295     private boolean runAnimationTests() {
296         for (int doubleBuffer = 0; doubleBuffer <= 1; doubleBuffer++) {
297             mDoubleBuffering = doubleBuffer == 1;
298             pushDoubleBuffering();
299             for (mAnimTestNr = 0; mAnimTestNr < ANIM_TESTS.length; mAnimTestNr++) {
300                 mAnimTests = ANIM_TESTS[mAnimTestNr];
301                 if (!runTestDirs(ANIM_TEST_DIRS)) {
302                     return false;
303                 }
304             }
305         }
306         return true;
307     }
308 
testAnimations()309     public void testAnimations() {
310         // instead of autoscrolling, load each page until either an timer fires,
311         // or the animation signals complete via javascript
312         setScrollingTestingMode(false);
313 
314         if (checkMedia() && runAnimationTests()) {
315             getInstrumentation().sendStatus(0, mStats.getBundle());
316         } else {
317             getInstrumentation().sendStatus(1, null);
318         }
319     }
320 }
321