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