• 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 android.content.Context;
20 import android.os.CountDownTimer;
21 import android.util.AttributeSet;
22 import android.util.Log;
23 import android.webkit.WebView;
24 
25 import com.test.tilebenchmark.ProfileActivity.ProfileCallback;
26 import com.test.tilebenchmark.RunData.TileData;
27 
28 public class ProfiledWebView extends WebView {
29     private int mSpeed;
30 
31     private boolean mIsTesting = false;
32     private boolean mIsScrolling = false;
33     private ProfileCallback mCallback;
34     private long mContentInvalMillis;
35     private boolean mHadToBeForced = false;
36     private int mTestCount = 0;
37     private static final int LOAD_STALL_MILLIS = 5000; // nr of millis after load,
38                                                        // before test is forced
39 
ProfiledWebView(Context context)40     public ProfiledWebView(Context context) {
41         super(context);
42     }
43 
ProfiledWebView(Context context, AttributeSet attrs)44     public ProfiledWebView(Context context, AttributeSet attrs) {
45         super(context, attrs);
46     }
47 
ProfiledWebView(Context context, AttributeSet attrs, int defStyle)48     public ProfiledWebView(Context context, AttributeSet attrs, int defStyle) {
49         super(context, attrs, defStyle);
50     }
51 
ProfiledWebView(Context context, AttributeSet attrs, int defStyle, boolean privateBrowsing)52     public ProfiledWebView(Context context, AttributeSet attrs, int defStyle,
53             boolean privateBrowsing) {
54         super(context, attrs, defStyle, privateBrowsing);
55     }
56 
57     @Override
onDraw(android.graphics.Canvas canvas)58     protected void onDraw(android.graphics.Canvas canvas) {
59         if (mIsTesting && mIsScrolling) {
60             if (canScrollVertically(1)) {
61                 scrollBy(0, mSpeed);
62             } else {
63                 stopScrollTest();
64                 mIsScrolling = false;
65             }
66         }
67         super.onDraw(canvas);
68     }
69 
70     /*
71      * Called once the page is loaded to start scrolling for evaluating tiles.
72      * If autoScrolling isn't set, stop must be called manually. Before
73      * scrolling, invalidate all content and redraw it, measuring time taken.
74      */
startScrollTest(ProfileCallback callback, boolean autoScrolling)75     public void startScrollTest(ProfileCallback callback, boolean autoScrolling) {
76         mIsScrolling = autoScrolling;
77         mCallback = callback;
78         mIsTesting = false;
79         mContentInvalMillis = System.currentTimeMillis();
80         registerPageSwapCallback();
81         contentInvalidateAll();
82         invalidate();
83 
84         mTestCount++;
85         final int testCount = mTestCount;
86 
87         if (autoScrolling) {
88             // after a while, force it to start even if the pages haven't swapped
89             new CountDownTimer(LOAD_STALL_MILLIS, LOAD_STALL_MILLIS) {
90                 @Override
91                 public void onTick(long millisUntilFinished) {
92                 }
93 
94                 @Override
95                 public void onFinish() {
96                     if (testCount == mTestCount && !mIsTesting) {
97                         mHadToBeForced = true;
98                         Log.d("ProfiledWebView", "num " + testCount
99                                 + " forcing a page swap with a scroll...");
100                         scrollBy(0, 1);
101                         invalidate(); // ensure a redraw so that auto-scrolling can occur
102                     }
103                 }
104             }.start();
105         }
106     }
107 
108     /*
109      * Called after the manual contentInvalidateAll, after the tiles have all
110      * been redrawn.
111      */
112     @Override
pageSwapCallback()113     protected void pageSwapCallback() {
114         mContentInvalMillis = System.currentTimeMillis() - mContentInvalMillis;
115         super.pageSwapCallback();
116         Log.d("ProfiledWebView", "REDRAW TOOK " + mContentInvalMillis
117                 + "millis");
118         mIsTesting = true;
119         invalidate(); // ensure a redraw so that auto-scrolling can occur
120         tileProfilingStart();
121     }
122 
123     /*
124      * Called once the page has stopped scrolling
125      */
stopScrollTest()126     public void stopScrollTest() {
127         tileProfilingStop();
128         mIsTesting = false;
129 
130         if (mCallback == null) {
131             tileProfilingClear();
132             return;
133         }
134 
135         RunData data = new RunData(super.tileProfilingNumFrames());
136         // record the time spent (before scrolling) rendering the page
137         data.singleStats.put(getResources().getString(R.string.render_millis),
138                 (double)mContentInvalMillis);
139         // record if the page render timed out
140         Log.d("ProfiledWebView", "hadtobeforced = " + mHadToBeForced);
141         data.singleStats.put(getResources().getString(R.string.render_stalls),
142                              mHadToBeForced ? 1.0 : 0.0);
143         mHadToBeForced = false;
144 
145         for (int frame = 0; frame < data.frames.length; frame++) {
146             data.frames[frame] = new TileData[
147                     tileProfilingNumTilesInFrame(frame)];
148             for (int tile = 0; tile < data.frames[frame].length; tile++) {
149                 int left = tileProfilingGetInt(frame, tile, "left");
150                 int top = tileProfilingGetInt(frame, tile, "top");
151                 int right = tileProfilingGetInt(frame, tile, "right");
152                 int bottom = tileProfilingGetInt(frame, tile, "bottom");
153 
154                 boolean isReady = super.tileProfilingGetInt(
155                         frame, tile, "isReady") == 1;
156                 int level = tileProfilingGetInt(frame, tile, "level");
157 
158                 float scale = tileProfilingGetFloat(frame, tile, "scale");
159 
160                 data.frames[frame][tile] = data.new TileData(left, top, right, bottom,
161                         isReady, level, scale);
162             }
163         }
164         tileProfilingClear();
165 
166         mCallback.profileCallback(data);
167     }
168 
169     @Override
loadUrl(String url)170     public void loadUrl(String url) {
171         if (!url.startsWith("http://") && !url.startsWith("file://")) {
172             url = "http://" + url;
173         }
174         super.loadUrl(url);
175     }
176 
setAutoScrollSpeed(int speedInt)177     public void setAutoScrollSpeed(int speedInt) {
178         mSpeed = speedInt;
179     }
180 }
181