blob: ab60f21a610ba7851b1dea609db97d9a3cea1f73 [file] [log] [blame]
Kenny Root15a4d2f2010-03-11 18:20:12 -08001/*
2 * Copyright (C) 2009 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
Xia Wang7c6efa12009-09-02 17:52:24 -070017package com.android.browserpowertest;
18
19import android.app.Activity;
20import android.app.ActivityThread;
21import android.graphics.Bitmap;
22import android.os.Bundle;
23import android.os.Handler;
Kristian Monsen0a303282013-01-18 14:50:07 -080024import android.os.Looper;
Xia Wang7c6efa12009-09-02 17:52:24 -070025import android.os.Message;
26import android.util.Log;
27import android.view.ViewGroup;
28import android.webkit.WebChromeClient;
29import android.webkit.WebView;
30import android.webkit.WebViewClient;
31import android.webkit.WebSettings.LayoutAlgorithm;
32import android.widget.LinearLayout;
33import android.widget.LinearLayout.LayoutParams;
34
35public class PowerTestActivity extends Activity {
36
37 public static final String LOGTAG = "PowerTestActivity";
38 public static final String PARAM_URL = "URL";
39 public static final String PARAM_TIMEOUT = "Timeout";
40 public static final int RESULT_TIMEOUT = 0xDEAD;
41 public static final int MSG_TIMEOUT = 0xC001;
42 public static final int MSG_NAVIGATE = 0xC002;
43 public static final String MSG_NAV_URL = "url";
44 public static final String MSG_NAV_LOGTIME = "logtime";
45
46 private WebView webView;
47 private SimpleWebViewClient webViewClient;
48 private SimpleChromeClient chromeClient;
49 private Handler handler;
50 private boolean timeoutFlag;
51 private boolean logTime;
52 private boolean pageDone;
53 private Object pageDoneLock;
54 private int pageStartCount;
55 private int manualDelay;
56 private long startTime;
57 private long pageLoadTime;
58 private PageDoneRunner pageDoneRunner = new PageDoneRunner();
59
60 public PowerTestActivity() {
61 }
62
63 @Override
64 protected void onCreate(Bundle savedInstanceState) {
65 super.onCreate(savedInstanceState);
66
67 Log.v(LOGTAG, "onCreate, inst=" + Integer.toHexString(hashCode()));
68
69 LinearLayout contentView = new LinearLayout(this);
70 contentView.setOrientation(LinearLayout.VERTICAL);
71 setContentView(contentView);
72 setTitle("Idle");
73
74 webView = new WebView(this);
75 webView.getSettings().setJavaScriptEnabled(true);
76 webView.getSettings().setJavaScriptCanOpenWindowsAutomatically(false);
77 webView.getSettings().setLayoutAlgorithm(LayoutAlgorithm.NORMAL);
78
79 webViewClient = new SimpleWebViewClient();
80 chromeClient = new SimpleChromeClient();
81 webView.setWebViewClient(webViewClient);
82 webView.setWebChromeClient(chromeClient);
83
84 contentView.addView(webView, new LayoutParams(
Romain Guy980a9382010-01-08 15:06:28 -080085 ViewGroup.LayoutParams.MATCH_PARENT,
86 ViewGroup.LayoutParams.MATCH_PARENT, 0.0f));
Xia Wang7c6efa12009-09-02 17:52:24 -070087
88 handler = new Handler() {
89 @Override
90 public void handleMessage(Message msg) {
91 switch (msg.what) {
92 case MSG_TIMEOUT:
93 handleTimeout();
94 return;
95 case MSG_NAVIGATE:
96 manualDelay = msg.arg2;
97 navigate(msg.getData().getString(MSG_NAV_URL), msg.arg1);
98 logTime = msg.getData().getBoolean(MSG_NAV_LOGTIME);
99 return;
100 }
101 }
102 };
103
104 pageDoneLock = new Object();
105 }
106
107 public void reset() {
108 synchronized (pageDoneLock) {
109 pageDone = false;
110 }
111 timeoutFlag = false;
112 pageStartCount = 0;
113 chromeClient.resetJsTimeout();
114 }
115
116 private void navigate(String url, int timeout) {
117 if(url == null) {
118 Log.v(LOGTAG, "URL is null, cancelling...");
119 finish();
120 }
121 webView.stopLoading();
122 if(logTime) {
123 webView.clearCache(true);
124 }
125 startTime = System.currentTimeMillis();
126 Log.v(LOGTAG, "Navigating to URL: " + url);
127 webView.loadUrl(url);
128
129 if(timeout != 0) {
130 //set a timer with specified timeout (in ms)
131 handler.sendMessageDelayed(handler.obtainMessage(MSG_TIMEOUT),
132 timeout);
133 }
134 }
135
136 @Override
137 protected void onDestroy() {
138 super.onDestroy();
139 Log.v(LOGTAG, "onDestroy, inst=" + Integer.toHexString(hashCode()));
140 webView.clearCache(true);
141 webView.destroy();
142 }
143
144 private boolean isPageDone() {
145 synchronized (pageDoneLock) {
146 return pageDone;
147 }
148 }
149
150 private void setPageDone(boolean pageDone) {
151 synchronized (pageDoneLock) {
152 this.pageDone = pageDone;
153 pageDoneLock.notifyAll();
154 }
155 }
156
157 private void handleTimeout() {
158 int progress = webView.getProgress();
159 webView.stopLoading();
160 Log.v(LOGTAG, "Page timeout triggered, progress = " + progress);
161 timeoutFlag = true;
162 handler.postDelayed(pageDoneRunner, manualDelay);
163 }
164
165 public boolean waitUntilDone() {
166 validateNotAppThread();
167 synchronized (pageDoneLock) {
168 while(!isPageDone()) {
169 try {
170 pageDoneLock.wait();
171 } catch (InterruptedException ie) {
172 //no-op
173 }
174 }
175 }
176 return timeoutFlag;
177 }
178
179 public Handler getHandler() {
180 return handler;
181 }
182
183 private final void validateNotAppThread() {
Kristian Monsen0a303282013-01-18 14:50:07 -0800184 if (Looper.myLooper() == Looper.getMainLooper()) {
Xia Wang7c6efa12009-09-02 17:52:24 -0700185 throw new RuntimeException(
186 "This method can not be called from the main application thread");
187 }
188 }
189
190 public long getPageLoadTime() {
191 return pageLoadTime;
192 }
193
194 public boolean getPageError() {
195 return webViewClient.getPageErrorFlag();
196 }
197
198 class SimpleWebViewClient extends WebViewClient {
199
200 private boolean pageErrorFlag = false;
201
202 @Override
203 public void onReceivedError(WebView view, int errorCode, String description,
204 String failingUrl) {
205 pageErrorFlag = true;
206 Log.v(LOGTAG, "WebCore error: code=" + errorCode
207 + ", description=" + description
208 + ", url=" + failingUrl);
209 }
210
211 @Override
212 public void onPageStarted(WebView view, String url, Bitmap favicon) {
213 pageStartCount++;
214 Log.v(LOGTAG, "onPageStarted: " + url);
215 }
216
217 @Override
218 public void onPageFinished(WebView view, String url) {
219 Log.v(LOGTAG, "onPageFinished: " + url);
220 // let handleTimeout take care of finishing the page
221 if(!timeoutFlag)
222 handler.postDelayed(new WebViewStatusChecker(), 500);
223 }
224
225 // return true if the URL is not available or the page is down
226 public boolean getPageErrorFlag() {
227 return pageErrorFlag;
228 }
229 }
230
231 class SimpleChromeClient extends WebChromeClient {
232
233 private int timeoutCounter = 0;
234
235 public void resetJsTimeout() {
236 timeoutCounter = 0;
237 }
238
239 @Override
240 public void onReceivedTitle(WebView view, String title) {
241 PowerTestActivity.this.setTitle(title);
242 }
243 }
244
245 class WebViewStatusChecker implements Runnable {
246
247 private int initialStartCount;
248
249 public WebViewStatusChecker() {
250 initialStartCount = pageStartCount;
251 }
252
253 public void run() {
254 if (initialStartCount == pageStartCount && !isPageDone()) {
255 handler.removeMessages(MSG_TIMEOUT);
256 webView.stopLoading();
257 handler.postDelayed(pageDoneRunner, manualDelay);
258 }
259 }
260 }
261
262 class PageDoneRunner implements Runnable {
263
264 public void run() {
265 Log.v(LOGTAG, "Finishing URL: " + webView.getUrl());
266 pageLoadTime = System.currentTimeMillis() - startTime;
267 setPageDone(true);
268 }
269 }
270}