blob: 40af8c042ea0119c3b0b987607ec46de13a8a5ae [file] [log] [blame]
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -07001/*
2 * Copyright (C) 2007 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.android.dumprendertree;
18
Guang Zhu6bf18ba2009-09-15 23:47:20 -070019import com.android.dumprendertree.forwarder.ForwardService;
20
Guang Zhu1871fe02009-04-29 14:49:03 -070021import android.app.Activity;
Guang Zhuf92bd422009-06-29 10:40:55 -070022import android.app.AlertDialog;
Andrei Popescu4950b2b2009-09-03 13:56:07 +010023import android.content.Context;
Guang Zhuf92bd422009-06-29 10:40:55 -070024import android.content.DialogInterface;
Guang Zhu1871fe02009-04-29 14:49:03 -070025import android.content.Intent;
Guang Zhuf92bd422009-06-29 10:40:55 -070026import android.content.DialogInterface.OnClickListener;
Guang Zhu1871fe02009-04-29 14:49:03 -070027import android.graphics.Bitmap;
Guang Zhu5dc4f212009-10-29 18:24:54 -070028import android.graphics.Canvas;
29import android.graphics.Bitmap.CompressFormat;
30import android.graphics.Bitmap.Config;
Guang Zhu1871fe02009-04-29 14:49:03 -070031import android.net.http.SslError;
32import android.os.Bundle;
Christian Mehlmauer8b85dce2010-07-19 20:11:27 +020033import android.os.Environment;
Guang Zhu1871fe02009-04-29 14:49:03 -070034import android.os.Handler;
35import android.os.Message;
36import android.util.Log;
37import android.view.ViewGroup;
Ben Murdoch9b815d02010-06-01 18:45:10 +010038import android.view.Window;
Guang Zhu6c15f602010-05-03 11:49:04 -070039import android.webkit.ConsoleMessage;
Steve Blockdad347c2009-08-19 18:46:34 +010040import android.webkit.GeolocationPermissions;
Guang Zhu1871fe02009-04-29 14:49:03 -070041import android.webkit.HttpAuthHandler;
42import android.webkit.JsPromptResult;
43import android.webkit.JsResult;
44import android.webkit.SslErrorHandler;
45import android.webkit.WebChromeClient;
46import android.webkit.WebSettings;
Ben Murdoche6f3e452009-04-22 16:02:31 +010047import android.webkit.WebStorage;
Guang Zhu1871fe02009-04-29 14:49:03 -070048import android.webkit.WebView;
49import android.webkit.WebViewClient;
50import android.widget.LinearLayout;
51
Guang Zhuf92bd422009-06-29 10:40:55 -070052import java.io.BufferedReader;
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -070053import java.io.File;
54import java.io.FileOutputStream;
Guang Zhuf92bd422009-06-29 10:40:55 -070055import java.io.FileReader;
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -070056import java.io.IOException;
Ben Murdoche6f3e452009-04-22 16:02:31 +010057import java.net.MalformedURLException;
58import java.net.URL;
Andrei Popescu4950b2b2009-09-03 13:56:07 +010059import java.util.HashMap;
Steve Blockf0f30c62010-08-18 15:15:42 +010060import java.util.Iterator;
Andrei Popescu4950b2b2009-09-03 13:56:07 +010061import java.util.Map;
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -070062import java.util.Vector;
63
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -070064public class TestShellActivity extends Activity implements LayoutTestController {
Guang Zhuf92bd422009-06-29 10:40:55 -070065
Guang Zhu1871fe02009-04-29 14:49:03 -070066 static enum DumpDataType {DUMP_AS_TEXT, EXT_REPR, NO_OP}
Guang Zhuf92bd422009-06-29 10:40:55 -070067
Steve Blockfb0de342010-03-19 18:48:35 +000068 // String constants for use with layoutTestController.overridePreferences
69 private final String WEBKIT_OFFLINE_WEB_APPLICATION_CACHE_ENABLED = "WebKitOfflineWebApplicationCacheEnabled";
70
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -070071 public class AsyncHandler extends Handler {
72 @Override
73 public void handleMessage(Message msg) {
74 if (msg.what == MSG_TIMEOUT) {
75 mTimedOut = true;
Guang Zhu56a36932009-09-28 09:53:48 -070076 if (mCallback != null)
Guang Zhuf92bd422009-06-29 10:40:55 -070077 mCallback.timedOut(mWebView.getUrl());
Guang Zhu56a36932009-09-28 09:53:48 -070078 if (!mRequestedWebKitData) {
Guang Zhu72160472009-09-25 17:34:12 -070079 requestWebKitData();
80 } else {
81 // if timed out and webkit data has been dumped before
82 // finish directly
83 finished();
84 }
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -070085 return;
86 } else if (msg.what == MSG_WEBKIT_DATA) {
87 TestShellActivity.this.dump(mTimedOut, (String)msg.obj);
88 return;
89 }
90
91 super.handleMessage(msg);
92 }
93 }
94
95 public void requestWebKitData() {
96 Message callback = mHandler.obtainMessage(MSG_WEBKIT_DATA);
Guang Zhuf92bd422009-06-29 10:40:55 -070097
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -070098 if (mRequestedWebKitData)
99 throw new AssertionError("Requested webkit data twice: " + mWebView.getUrl());
Guang Zhuf92bd422009-06-29 10:40:55 -0700100
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700101 mRequestedWebKitData = true;
Guang Zhu72160472009-09-25 17:34:12 -0700102 Log.v(LOGTAG, "message sent to WebView to dump text.");
Guang Zhu1871fe02009-04-29 14:49:03 -0700103 switch (mDumpDataType) {
104 case DUMP_AS_TEXT:
Shimeng (Simon) Wangad456862010-06-16 17:32:24 -0700105 callback.arg1 = mDumpTopFrameAsText ? 1 : 0;
106 callback.arg2 = mDumpChildFramesAsText ? 1 : 0;
Guang Zhu1871fe02009-04-29 14:49:03 -0700107 mWebView.documentAsText(callback);
108 break;
109 case EXT_REPR:
110 mWebView.externalRepresentation(callback);
111 break;
112 default:
113 finished();
114 break;
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700115 }
Guang Zhuf92bd422009-06-29 10:40:55 -0700116 }
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700117
Guang Zhu889181d2009-07-09 12:55:15 -0700118 public void clearCache() {
Guang Zhuf56e1a12009-07-20 11:16:28 -0700119 mWebView.freeMemory();
Guang Zhu889181d2009-07-09 12:55:15 -0700120 }
121
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700122 @Override
123 protected void onCreate(Bundle icicle) {
124 super.onCreate(icicle);
Ben Murdoch9b815d02010-06-01 18:45:10 +0100125 requestWindowFeature(Window.FEATURE_PROGRESS);
Guang Zhuf92bd422009-06-29 10:40:55 -0700126
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700127 LinearLayout contentView = new LinearLayout(this);
128 contentView.setOrientation(LinearLayout.VERTICAL);
129 setContentView(contentView);
130
131 mWebView = new WebView(this);
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700132 mEventSender = new WebViewEventSender(mWebView);
133 mCallbackProxy = new CallbackProxy(mEventSender, this);
134
Andrei Popescu4950b2b2009-09-03 13:56:07 +0100135 mWebView.addJavascriptInterface(mCallbackProxy, "layoutTestController");
136 mWebView.addJavascriptInterface(mCallbackProxy, "eventSender");
Ben Murdoche6f3e452009-04-22 16:02:31 +0100137 setupWebViewForLayoutTests(mWebView, mCallbackProxy);
138
Romain Guy980a9382010-01-08 15:06:28 -0800139 contentView.addView(mWebView, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT, 0.0f));
Guang Zhuf92bd422009-06-29 10:40:55 -0700140
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700141 mWebView.getSettings().setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NORMAL);
Guang Zhuf92bd422009-06-29 10:40:55 -0700142
Feng Qian28909202009-08-13 14:54:56 -0700143 // Expose window.gc function to JavaScript. JSC build exposes
144 // this function by default, but V8 requires the flag to turn it on.
145 // WebView::setJsFlags is noop in JSC build.
146 mWebView.setJsFlags("--expose_gc");
147
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700148 mHandler = new AsyncHandler();
Guang Zhuf92bd422009-06-29 10:40:55 -0700149
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700150 Intent intent = getIntent();
151 if (intent != null) {
152 executeIntent(intent);
153 }
Steve Block68dede32010-08-04 10:28:46 +0100154
155 // This is asynchronous, but it gets processed by WebCore before it starts loading pages.
156 mWebView.useMockDeviceOrientation();
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700157 }
Guang Zhuf92bd422009-06-29 10:40:55 -0700158
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700159 @Override
160 protected void onNewIntent(Intent intent) {
161 super.onNewIntent(intent);
162 executeIntent(intent);
163 }
Guang Zhuf92bd422009-06-29 10:40:55 -0700164
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700165 private void executeIntent(Intent intent) {
166 resetTestStatus();
167 if (!Intent.ACTION_VIEW.equals(intent.getAction())) {
168 return;
169 }
Guang Zhuf92bd422009-06-29 10:40:55 -0700170
Ben Murdoch9b815d02010-06-01 18:45:10 +0100171 mTotalTestCount = intent.getIntExtra(TOTAL_TEST_COUNT, mTotalTestCount);
172 mCurrentTestNumber = intent.getIntExtra(CURRENT_TEST_NUMBER, mCurrentTestNumber);
173
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700174 mTestUrl = intent.getStringExtra(TEST_URL);
Guang Zhuf92bd422009-06-29 10:40:55 -0700175 if (mTestUrl == null) {
176 mUiAutoTestPath = intent.getStringExtra(UI_AUTO_TEST);
177 if(mUiAutoTestPath != null) {
178 beginUiAutoTest();
179 }
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700180 return;
Guang Zhuf92bd422009-06-29 10:40:55 -0700181 }
182
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700183 mResultFile = intent.getStringExtra(RESULT_FILE);
184 mTimeoutInMillis = intent.getIntExtra(TIMEOUT_IN_MILLIS, 0);
Guang Zhu5dc4f212009-10-29 18:24:54 -0700185 mGetDrawtime = intent.getBooleanExtra(GET_DRAW_TIME, false);
186 mSaveImagePath = intent.getStringExtra(SAVE_IMAGE);
Guang Zhu5d53c192010-07-14 17:17:54 -0700187 mStopOnRefError = intent.getBooleanExtra(STOP_ON_REF_ERROR, false);
Ben Murdoch9b815d02010-06-01 18:45:10 +0100188 setTitle("Test " + mCurrentTestNumber + " of " + mTotalTestCount);
189 float ratio = (float)mCurrentTestNumber / mTotalTestCount;
190 int progress = (int)(ratio * Window.PROGRESS_END);
191 getWindow().setFeatureInt(Window.FEATURE_PROGRESS, progress);
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700192
193 Log.v(LOGTAG, " Loading " + mTestUrl);
194 mWebView.loadUrl(mTestUrl);
Guang Zhuf92bd422009-06-29 10:40:55 -0700195
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700196 if (mTimeoutInMillis > 0) {
197 // Create a timeout timer
198 Message m = mHandler.obtainMessage(MSG_TIMEOUT);
199 mHandler.sendMessageDelayed(m, mTimeoutInMillis);
200 }
201 }
Guang Zhuf92bd422009-06-29 10:40:55 -0700202
203 private void beginUiAutoTest() {
204 try {
205 mTestListReader = new BufferedReader(
206 new FileReader(mUiAutoTestPath));
207 } catch (IOException ioe) {
208 Log.e(LOGTAG, "Failed to open test list for read.", ioe);
209 finishUiAutoTest();
210 return;
211 }
212 moveToNextTest();
213 }
214
215 private void finishUiAutoTest() {
216 try {
217 if(mTestListReader != null)
218 mTestListReader.close();
219 } catch (IOException ioe) {
220 Log.w(LOGTAG, "Failed to close test list file.", ioe);
221 }
Guang Zhu6bf18ba2009-09-15 23:47:20 -0700222 ForwardService.getForwardService().stopForwardService();
Guang Zhuf92bd422009-06-29 10:40:55 -0700223 finished();
224 }
225
226 private void moveToNextTest() {
227 String url = null;
228 try {
229 url = mTestListReader.readLine();
230 } catch (IOException ioe) {
231 Log.e(LOGTAG, "Failed to read next test.", ioe);
232 finishUiAutoTest();
233 return;
234 }
235 if (url == null) {
236 mUiAutoTestPath = null;
237 finishUiAutoTest();
238 AlertDialog.Builder builder = new AlertDialog.Builder(this);
239 builder.setMessage("All tests finished. Exit?")
240 .setCancelable(false)
241 .setPositiveButton("Yes", new OnClickListener(){
242 public void onClick(DialogInterface dialog, int which) {
243 TestShellActivity.this.finish();
244 }
245 })
246 .setNegativeButton("No", new OnClickListener(){
247 public void onClick(DialogInterface dialog, int which) {
248 dialog.cancel();
249 }
250 });
251 builder.create().show();
252 return;
253 }
Guang Zhuf92bd422009-06-29 10:40:55 -0700254 Intent intent = new Intent(Intent.ACTION_VIEW);
255 intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
Guang Zhu6bf18ba2009-09-15 23:47:20 -0700256 intent.putExtra(TestShellActivity.TEST_URL, FsUtils.getTestUrl(url));
Ben Murdoch9b815d02010-06-01 18:45:10 +0100257 intent.putExtra(TestShellActivity.CURRENT_TEST_NUMBER, ++mCurrentTestNumber);
Guang Zhuf92bd422009-06-29 10:40:55 -0700258 intent.putExtra(TIMEOUT_IN_MILLIS, 10000);
259 executeIntent(intent);
260 }
261
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700262 @Override
263 protected void onStop() {
264 super.onStop();
265 mWebView.stopLoading();
266 }
Guang Zhuf92bd422009-06-29 10:40:55 -0700267
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700268 @Override
269 protected void onDestroy() {
270 super.onDestroy();
271 mWebView.destroy();
272 mWebView = null;
273 }
Guang Zhuf92bd422009-06-29 10:40:55 -0700274
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700275 @Override
276 public void onLowMemory() {
277 super.onLowMemory();
Feng Qian0aeed6a2009-07-16 20:53:31 -0700278 Log.e(LOGTAG, "Low memory, clearing caches");
279 mWebView.freeMemory();
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700280 }
281
282 // Dump the page
283 public void dump(boolean timeout, String webkitData) {
Ben Murdoch2eea5f32009-09-23 15:28:57 +0100284 mDumpWebKitData = true;
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700285 if (mResultFile == null || mResultFile.length() == 0) {
286 finished();
287 return;
288 }
Guang Zhuf92bd422009-06-29 10:40:55 -0700289
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700290 try {
291 File parentDir = new File(mResultFile).getParentFile();
292 if (!parentDir.exists()) {
293 parentDir.mkdirs();
294 }
Guang Zhuf92bd422009-06-29 10:40:55 -0700295
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700296 FileOutputStream os = new FileOutputStream(mResultFile);
297 if (timeout) {
298 Log.w("Layout test: Timeout", mResultFile);
299 os.write(TIMEOUT_STR.getBytes());
300 os.write('\n');
301 }
302 if (mDumpTitleChanges)
303 os.write(mTitleChanges.toString().getBytes());
304 if (mDialogStrings != null)
305 os.write(mDialogStrings.toString().getBytes());
306 mDialogStrings = null;
Ben Murdoche6f3e452009-04-22 16:02:31 +0100307 if (mDatabaseCallbackStrings != null)
308 os.write(mDatabaseCallbackStrings.toString().getBytes());
309 mDatabaseCallbackStrings = null;
310 if (mConsoleMessages != null)
311 os.write(mConsoleMessages.toString().getBytes());
312 mConsoleMessages = null;
Feng Qianbe42388b2009-04-16 10:05:38 -0700313 if (webkitData != null)
314 os.write(webkitData.getBytes());
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700315 os.flush();
316 os.close();
317 } catch (IOException ex) {
Guang Zhuf92bd422009-06-29 10:40:55 -0700318 Log.e(LOGTAG, "Cannot write to " + mResultFile + ", " + ex.getMessage());
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700319 }
320
321 finished();
322 }
Guang Zhuf92bd422009-06-29 10:40:55 -0700323
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700324 public void setCallback(TestShellCallback callback) {
325 mCallback = callback;
326 }
Guang Zhuf92bd422009-06-29 10:40:55 -0700327
Ben Murdoch2eea5f32009-09-23 15:28:57 +0100328 public boolean finished() {
329 if (canMoveToNextTest()) {
330 mHandler.removeMessages(MSG_TIMEOUT);
Ben Murdoch977f7692009-09-16 20:13:07 +0100331 if (mUiAutoTestPath != null) {
332 //don't really finish here
333 moveToNextTest();
334 } else {
335 if (mCallback != null) {
336 mCallback.finished();
337 }
Guang Zhuf92bd422009-06-29 10:40:55 -0700338 }
Ben Murdoch2eea5f32009-09-23 15:28:57 +0100339 return true;
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700340 }
Ben Murdoch2eea5f32009-09-23 15:28:57 +0100341 return false;
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700342 }
Guang Zhuf92bd422009-06-29 10:40:55 -0700343
Guang Zhu1871fe02009-04-29 14:49:03 -0700344 public void setDefaultDumpDataType(DumpDataType defaultDumpDataType) {
345 mDefaultDumpDataType = defaultDumpDataType;
346 }
347
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700348 // .......................................
349 // LayoutTestController Functions
Ben Murdoch357d2802010-07-23 16:18:58 +0100350 public void dumpAsText(boolean enablePixelTests) {
351 // Added after webkit update to r63859. See trac.webkit.org/changeset/63730.
352 if (enablePixelTests) {
353 Log.v(LOGTAG, "dumpAsText(enablePixelTests == true) not implemented on Android!");
354 }
355
Guang Zhu1871fe02009-04-29 14:49:03 -0700356 mDumpDataType = DumpDataType.DUMP_AS_TEXT;
Shimeng (Simon) Wangad456862010-06-16 17:32:24 -0700357 mDumpTopFrameAsText = true;
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700358 if (mWebView != null) {
359 String url = mWebView.getUrl();
360 Log.v(LOGTAG, "dumpAsText called: "+url);
361 }
362 }
363
Shimeng (Simon) Wangad456862010-06-16 17:32:24 -0700364 public void dumpChildFramesAsText() {
365 mDumpDataType = DumpDataType.DUMP_AS_TEXT;
366 mDumpChildFramesAsText = true;
367 if (mWebView != null) {
368 String url = mWebView.getUrl();
369 Log.v(LOGTAG, "dumpChildFramesAsText called: "+url);
370 }
371 }
372
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700373 public void waitUntilDone() {
374 mWaitUntilDone = true;
375 String url = mWebView.getUrl();
376 Log.v(LOGTAG, "waitUntilDone called: " + url);
377 }
Guang Zhuf92bd422009-06-29 10:40:55 -0700378
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700379 public void notifyDone() {
380 String url = mWebView.getUrl();
381 Log.v(LOGTAG, "notifyDone called: " + url);
382 if (mWaitUntilDone) {
383 mWaitUntilDone = false;
Ben Murdoch1620bcd2010-06-03 11:51:54 +0100384 if (!mRequestedWebKitData && !mTimedOut && !finished()) {
385 requestWebKitData();
386 }
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700387 }
388 }
Guang Zhuf92bd422009-06-29 10:40:55 -0700389
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700390 public void display() {
391 mWebView.invalidate();
392 }
393
394 public void clearBackForwardList() {
395 mWebView.clearHistory();
396
397 }
398
399 public void dumpBackForwardList() {
400 //printf("\n============== Back Forward List ==============\n");
401 // mWebHistory
402 //printf("===============================================\n");
403
404 }
405
406 public void dumpChildFrameScrollPositions() {
407 // TODO Auto-generated method stub
408
409 }
410
411 public void dumpEditingCallbacks() {
412 // TODO Auto-generated method stub
413
414 }
415
416 public void dumpSelectionRect() {
417 // TODO Auto-generated method stub
418
419 }
420
421 public void dumpTitleChanges() {
422 if (!mDumpTitleChanges) {
423 mTitleChanges = new StringBuffer();
424 }
425 mDumpTitleChanges = true;
426 }
427
428 public void keepWebHistory() {
429 if (!mKeepWebHistory) {
430 mWebHistory = new Vector();
431 }
432 mKeepWebHistory = true;
433 }
434
435 public void queueBackNavigation(int howfar) {
436 // TODO Auto-generated method stub
437
438 }
439
440 public void queueForwardNavigation(int howfar) {
441 // TODO Auto-generated method stub
442
443 }
444
445 public void queueLoad(String Url, String frameTarget) {
446 // TODO Auto-generated method stub
447
448 }
449
450 public void queueReload() {
451 mWebView.reload();
452 }
453
454 public void queueScript(String scriptToRunInCurrentContext) {
Guang Zhuf92bd422009-06-29 10:40:55 -0700455 mWebView.loadUrl("javascript:"+scriptToRunInCurrentContext);
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700456 }
457
458 public void repaintSweepHorizontally() {
459 // TODO Auto-generated method stub
460
461 }
462
463 public void setAcceptsEditing(boolean b) {
464 // TODO Auto-generated method stub
465
466 }
467
468 public void setMainFrameIsFirstResponder(boolean b) {
469 // TODO Auto-generated method stub
470
471 }
472
473 public void setWindowIsKey(boolean b) {
474 // This is meant to show/hide the window. The best I can find
475 // is setEnabled()
476 mWebView.setEnabled(b);
477 }
478
479 public void testRepaint() {
480 mWebView.invalidate();
481 }
Ben Murdoche6f3e452009-04-22 16:02:31 +0100482
483 public void dumpDatabaseCallbacks() {
484 Log.v(LOGTAG, "dumpDatabaseCallbacks called.");
485 mDumpDatabaseCallbacks = true;
486 }
487
488 public void setCanOpenWindows() {
489 Log.v(LOGTAG, "setCanOpenWindows called.");
490 mCanOpenWindows = true;
491 }
492
Steve Blockdad347c2009-08-19 18:46:34 +0100493 /**
494 * Sets the Geolocation permission state to be used for all future requests.
495 */
496 public void setGeolocationPermission(boolean allow) {
Steve Blockf0f30c62010-08-18 15:15:42 +0100497 mIsGeolocationPermissionSet = true;
Steve Blockdad347c2009-08-19 18:46:34 +0100498 mGeolocationPermission = allow;
Steve Blockf0f30c62010-08-18 15:15:42 +0100499
500 if (mPendingGeolocationPermissionCallbacks != null) {
501 Iterator iter = mPendingGeolocationPermissionCallbacks.keySet().iterator();
502 while (iter.hasNext()) {
503 GeolocationPermissions.Callback callback =
504 (GeolocationPermissions.Callback) iter.next();
505 String origin = (String) mPendingGeolocationPermissionCallbacks.get(callback);
506 callback.invoke(origin, mGeolocationPermission, false);
507 }
508 mPendingGeolocationPermissionCallbacks = null;
509 }
Steve Blockdad347c2009-08-19 18:46:34 +0100510 }
511
Steve Block68dede32010-08-04 10:28:46 +0100512 public void setMockDeviceOrientation(boolean canProvideAlpha, double alpha,
513 boolean canProvideBeta, double beta, boolean canProvideGamma, double gamma) {
514 mWebView.setMockDeviceOrientation(canProvideAlpha, alpha, canProvideBeta, beta,
515 canProvideGamma, gamma);
516 }
517
Steve Blockfb0de342010-03-19 18:48:35 +0000518 public void overridePreference(String key, boolean value) {
519 // TODO: We should look up the correct WebView for the frame which
520 // called the layoutTestController method. Currently, we just use the
521 // WebView for the main frame. EventSender suffers from the same
522 // problem.
523 if (key.equals(WEBKIT_OFFLINE_WEB_APPLICATION_CACHE_ENABLED)) {
524 mWebView.getSettings().setAppCacheEnabled(value);
525 }
526 }
527
Elliott Slaughter5dc0c822010-06-22 11:31:54 -0700528 public void setXSSAuditorEnabled (boolean flag) {
529 mWebView.getSettings().setXSSAuditorEnabled(flag);
530 }
531
Ben Murdoche6f3e452009-04-22 16:02:31 +0100532 private final WebViewClient mViewClient = new WebViewClient(){
533 @Override
534 public void onPageFinished(WebView view, String url) {
535 Log.v(LOGTAG, "onPageFinished, url=" + url);
Ben Murdoch2eea5f32009-09-23 15:28:57 +0100536 mPageFinished = true;
Guang Zhu5dc4f212009-10-29 18:24:54 -0700537 // get page draw time
538 if (FsUtils.isTestPageUrl(url)) {
539 if (mGetDrawtime) {
540 long[] times = new long[DRAW_RUNS];
541 times = getDrawWebViewTime(mWebView, DRAW_RUNS);
542 FsUtils.writeDrawTime(DRAW_TIME_LOG, url, times);
543 }
544 if (mSaveImagePath != null) {
545 String name = FsUtils.getLastSegmentInPath(url);
546 drawPageToFile(mSaveImagePath + "/" + name + ".png", mWebView);
547 }
548 }
Ben Murdoch1620bcd2010-06-03 11:51:54 +0100549
Ben Murdoch2eea5f32009-09-23 15:28:57 +0100550 // Calling finished() will check if we've met all the conditions for completing
Ben Murdoch1620bcd2010-06-03 11:51:54 +0100551 // this test and move to the next one if we are ready. Otherwise we ask WebCore to
552 // dump the page.
Ben Murdoch2eea5f32009-09-23 15:28:57 +0100553 if (finished()) {
554 return;
555 }
Ben Murdoch1620bcd2010-06-03 11:51:54 +0100556
557 if (!mWaitUntilDone && !mRequestedWebKitData && !mTimedOut) {
558 requestWebKitData();
559 } else {
560 if (mWaitUntilDone) {
561 Log.v(LOGTAG, "page finished loading but waiting for notifyDone to be called: " + url);
562 }
563
564 if (mRequestedWebKitData) {
565 Log.v(LOGTAG, "page finished loading but webkit data has already been requested: " + url);
566 }
567
568 if (mTimedOut) {
569 Log.v(LOGTAG, "page finished loading but already timed out: " + url);
570 }
571 }
572
Ben Murdoche6f3e452009-04-22 16:02:31 +0100573 super.onPageFinished(view, url);
574 }
575
576 @Override
577 public void onPageStarted(WebView view, String url, Bitmap favicon) {
578 Log.v(LOGTAG, "onPageStarted, url=" + url);
Ben Murdoch2eea5f32009-09-23 15:28:57 +0100579 mPageFinished = false;
Ben Murdoche6f3e452009-04-22 16:02:31 +0100580 super.onPageStarted(view, url, favicon);
581 }
582
583 @Override
584 public void onReceivedError(WebView view, int errorCode, String description,
585 String failingUrl) {
586 Log.v(LOGTAG, "onReceivedError, errorCode=" + errorCode
587 + ", desc=" + description + ", url=" + failingUrl);
588 super.onReceivedError(view, errorCode, description, failingUrl);
589 }
590
591 @Override
592 public void onReceivedHttpAuthRequest(WebView view, HttpAuthHandler handler,
593 String host, String realm) {
Steve Block2bb25532010-03-25 14:48:13 +0000594 if (handler.useHttpAuthUsernamePassword() && view != null) {
595 String[] credentials = view.getHttpAuthUsernamePassword(host, realm);
596 if (credentials != null && credentials.length == 2) {
597 handler.proceed(credentials[0], credentials[1]);
598 return;
599 }
600 }
Ben Murdoche6f3e452009-04-22 16:02:31 +0100601 handler.cancel();
602 }
603
604 @Override
605 public void onReceivedSslError(WebView view, SslErrorHandler handler,
606 SslError error) {
607 handler.proceed();
608 }
609 };
610
611
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700612 private final WebChromeClient mChromeClient = new WebChromeClient() {
613 @Override
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700614 public void onReceivedTitle(WebView view, String title) {
Ben Murdoch9b815d02010-06-01 18:45:10 +0100615 setTitle("Test " + mCurrentTestNumber + " of " + mTotalTestCount + ": "+ title);
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700616 if (mDumpTitleChanges) {
617 mTitleChanges.append("TITLE CHANGED: ");
618 mTitleChanges.append(title);
619 mTitleChanges.append("\n");
620 }
621 }
622
623 @Override
624 public boolean onJsAlert(WebView view, String url, String message,
625 JsResult result) {
626 if (mDialogStrings == null) {
627 mDialogStrings = new StringBuffer();
628 }
629 mDialogStrings.append("ALERT: ");
630 mDialogStrings.append(message);
631 mDialogStrings.append('\n');
632 result.confirm();
633 return true;
634 }
Guang Zhuf92bd422009-06-29 10:40:55 -0700635
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700636 @Override
637 public boolean onJsConfirm(WebView view, String url, String message,
638 JsResult result) {
639 if (mDialogStrings == null) {
640 mDialogStrings = new StringBuffer();
641 }
642 mDialogStrings.append("CONFIRM: ");
643 mDialogStrings.append(message);
644 mDialogStrings.append('\n');
645 result.confirm();
646 return true;
647 }
Guang Zhuf92bd422009-06-29 10:40:55 -0700648
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700649 @Override
650 public boolean onJsPrompt(WebView view, String url, String message,
651 String defaultValue, JsPromptResult result) {
652 if (mDialogStrings == null) {
653 mDialogStrings = new StringBuffer();
654 }
655 mDialogStrings.append("PROMPT: ");
656 mDialogStrings.append(message);
657 mDialogStrings.append(", default text: ");
658 mDialogStrings.append(defaultValue);
659 mDialogStrings.append('\n');
660 result.confirm();
661 return true;
662 }
Ben Murdoche6f3e452009-04-22 16:02:31 +0100663
664 @Override
Guang Zhuf4bf5522009-07-23 14:19:35 -0700665 public boolean onJsTimeout() {
666 Log.v(LOGTAG, "JavaScript timeout");
667 return false;
668 }
669
670 @Override
Ben Murdoche6f3e452009-04-22 16:02:31 +0100671 public void onExceededDatabaseQuota(String url_str,
Ben Murdochd497d872009-08-25 19:32:54 +0100672 String databaseIdentifier, long currentQuota,
673 long estimatedSize, long totalUsedQuota,
Ben Murdoche6f3e452009-04-22 16:02:31 +0100674 WebStorage.QuotaUpdater callback) {
675 if (mDumpDatabaseCallbacks) {
676 if (mDatabaseCallbackStrings == null) {
677 mDatabaseCallbackStrings = new StringBuffer();
678 }
679
680 String protocol = "";
681 String host = "";
682 int port = 0;
683
684 try {
685 URL url = new URL(url_str);
686 protocol = url.getProtocol();
687 host = url.getHost();
688 if (url.getPort() > -1) {
689 port = url.getPort();
690 }
691 } catch (MalformedURLException e) {}
692
693 String databaseCallbackString =
694 "UI DELEGATE DATABASE CALLBACK: " +
695 "exceededDatabaseQuotaForSecurityOrigin:{" + protocol +
696 ", " + host + ", " + port + "} database:" +
697 databaseIdentifier + "\n";
698 Log.v(LOGTAG, "LOG: "+databaseCallbackString);
699 mDatabaseCallbackStrings.append(databaseCallbackString);
700 }
701 // Give 5MB more quota.
702 callback.updateQuota(currentQuota + 1024 * 1024 * 5);
703 }
704
Steve Blockdad347c2009-08-19 18:46:34 +0100705 /**
706 * Instructs the client to show a prompt to ask the user to set the
707 * Geolocation permission state for the specified origin.
708 */
709 @Override
710 public void onGeolocationPermissionsShowPrompt(String origin,
711 GeolocationPermissions.Callback callback) {
Steve Blockf0f30c62010-08-18 15:15:42 +0100712 if (mIsGeolocationPermissionSet) {
Steve Blockdad347c2009-08-19 18:46:34 +0100713 callback.invoke(origin, mGeolocationPermission, false);
Steve Blockf0f30c62010-08-18 15:15:42 +0100714 return;
Steve Blockdad347c2009-08-19 18:46:34 +0100715 }
Steve Blockf0f30c62010-08-18 15:15:42 +0100716 if (mPendingGeolocationPermissionCallbacks == null) {
717 mPendingGeolocationPermissionCallbacks =
718 new HashMap<GeolocationPermissions.Callback, String>();
719 }
720 mPendingGeolocationPermissionCallbacks.put(callback, origin);
Steve Blockdad347c2009-08-19 18:46:34 +0100721 }
722
Ben Murdoche6f3e452009-04-22 16:02:31 +0100723 @Override
Guang Zhu6c15f602010-05-03 11:49:04 -0700724 public boolean onConsoleMessage(ConsoleMessage consoleMessage) {
725 String msg = "CONSOLE MESSAGE: line " + consoleMessage.lineNumber() + ": "
726 + consoleMessage.message() + "\n";
Ben Murdoche6f3e452009-04-22 16:02:31 +0100727 if (mConsoleMessages == null) {
728 mConsoleMessages = new StringBuffer();
729 }
Guang Zhu6c15f602010-05-03 11:49:04 -0700730 mConsoleMessages.append(msg);
731 Log.v(LOGTAG, "LOG: " + msg);
732 // the rationale here is that if there's an error of either type, and the test was
733 // waiting for "notifyDone" signal to finish, then there's no point in waiting
734 // anymore because the JS execution is already terminated at this point and a
735 // "notifyDone" will never come out so it's just wasting time till timeout kicks in
Guang Zhu5d53c192010-07-14 17:17:54 -0700736 if ((msg.contains("Uncaught ReferenceError:") || msg.contains("Uncaught TypeError:"))
737 && mWaitUntilDone && mStopOnRefError) {
Guang Zhu6c15f602010-05-03 11:49:04 -0700738 Log.w(LOGTAG, "Terminating test case on uncaught ReferenceError or TypeError.");
739 mHandler.postDelayed(new Runnable() {
740 public void run() {
741 notifyDone();
742 }
743 }, 500);
744 }
745 return true;
Ben Murdoche6f3e452009-04-22 16:02:31 +0100746 }
747
748 @Override
749 public boolean onCreateWindow(WebView view, boolean dialog,
750 boolean userGesture, Message resultMsg) {
751 if (!mCanOpenWindows) {
Ben Murdochfc4a69e2010-02-04 16:35:10 +0000752 // We can't open windows, so just send null back.
753 WebView.WebViewTransport transport =
754 (WebView.WebViewTransport) resultMsg.obj;
755 transport.setWebView(null);
756 resultMsg.sendToTarget();
757 return true;
Ben Murdoche6f3e452009-04-22 16:02:31 +0100758 }
759
760 // We never display the new window, just create the view and
761 // allow it's content to execute and be recorded by the test
762 // runner.
763
Andrei Popescu4950b2b2009-09-03 13:56:07 +0100764 HashMap<String, Object> jsIfaces = new HashMap<String, Object>();
765 jsIfaces.put("layoutTestController", mCallbackProxy);
766 jsIfaces.put("eventSender", mCallbackProxy);
767 WebView newWindowView = new NewWindowWebView(TestShellActivity.this, jsIfaces);
Ben Murdoche6f3e452009-04-22 16:02:31 +0100768 setupWebViewForLayoutTests(newWindowView, mCallbackProxy);
769 WebView.WebViewTransport transport =
770 (WebView.WebViewTransport) resultMsg.obj;
771 transport.setWebView(newWindowView);
772 resultMsg.sendToTarget();
773 return true;
774 }
Ben Murdochfc4a69e2010-02-04 16:35:10 +0000775
776 @Override
777 public void onCloseWindow(WebView view) {
778 view.destroy();
779 }
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700780 };
Guang Zhuf92bd422009-06-29 10:40:55 -0700781
Andrei Popescu4950b2b2009-09-03 13:56:07 +0100782 private static class NewWindowWebView extends WebView {
783 public NewWindowWebView(Context context, Map<String, Object> jsIfaces) {
Elliott Slaughterf21d2e32010-07-14 18:08:54 -0700784 super(context, null, 0, jsIfaces, false);
Andrei Popescu4950b2b2009-09-03 13:56:07 +0100785 }
786 }
787
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700788 private void resetTestStatus() {
789 mWaitUntilDone = false;
Guang Zhu1871fe02009-04-29 14:49:03 -0700790 mDumpDataType = mDefaultDumpDataType;
Shimeng (Simon) Wangad456862010-06-16 17:32:24 -0700791 mDumpTopFrameAsText = false;
792 mDumpChildFramesAsText = false;
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700793 mTimedOut = false;
794 mDumpTitleChanges = false;
795 mRequestedWebKitData = false;
Ben Murdoche6f3e452009-04-22 16:02:31 +0100796 mDumpDatabaseCallbacks = false;
797 mCanOpenWindows = false;
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700798 mEventSender.resetMouse();
Ben Murdochecbc65c2010-01-13 10:54:56 +0000799 mEventSender.clearTouchPoints();
Ben Murdoch8a032a32010-02-02 18:20:11 +0000800 mEventSender.clearTouchMetaState();
Ben Murdoch2eea5f32009-09-23 15:28:57 +0100801 mPageFinished = false;
Ben Murdoch2eea5f32009-09-23 15:28:57 +0100802 mDumpWebKitData = false;
Guang Zhu5dc4f212009-10-29 18:24:54 -0700803 mGetDrawtime = false;
804 mSaveImagePath = null;
Ben Murdocha8b97682010-04-15 12:20:48 -0700805 setDefaultWebSettings(mWebView);
Steve Blockf0f30c62010-08-18 15:15:42 +0100806 mIsGeolocationPermissionSet = false;
807 mPendingGeolocationPermissionCallbacks = null;
Guang Zhu5dc4f212009-10-29 18:24:54 -0700808 }
809
810 private long[] getDrawWebViewTime(WebView view, int count) {
811 if (count == 0)
812 return null;
813 long[] ret = new long[count];
814 long start;
815 Canvas canvas = new Canvas();
816 Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Config.ARGB_8888);
817 canvas.setBitmap(bitmap);
818 for (int i = 0; i < count; i++) {
819 start = System.currentTimeMillis();
820 view.draw(canvas);
821 ret[i] = System.currentTimeMillis() - start;
822 }
823 return ret;
824 }
825
826 private void drawPageToFile(String fileName, WebView view) {
827 Canvas canvas = new Canvas();
828 Bitmap bitmap = Bitmap.createBitmap(view.getContentWidth(), view.getContentHeight(),
829 Config.ARGB_8888);
830 canvas.setBitmap(bitmap);
831 view.drawPage(canvas);
832 try {
833 FileOutputStream fos = new FileOutputStream(fileName);
834 if(!bitmap.compress(CompressFormat.PNG, 90, fos)) {
835 Log.w(LOGTAG, "Failed to compress and save image.");
836 }
837 } catch (IOException ioe) {
838 Log.e(LOGTAG, "", ioe);
839 }
840 bitmap.recycle();
Ben Murdoch2eea5f32009-09-23 15:28:57 +0100841 }
842
843 private boolean canMoveToNextTest() {
Ben Murdoch1620bcd2010-06-03 11:51:54 +0100844 return (mDumpWebKitData && mPageFinished && !mWaitUntilDone) || mTimedOut;
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700845 }
Ben Murdoche6f3e452009-04-22 16:02:31 +0100846
847 private void setupWebViewForLayoutTests(WebView webview, CallbackProxy callbackProxy) {
848 if (webview == null) {
849 return;
850 }
851
Ben Murdocha8b97682010-04-15 12:20:48 -0700852 setDefaultWebSettings(webview);
853
854 webview.setWebChromeClient(mChromeClient);
855 webview.setWebViewClient(mViewClient);
856 // Setting a touch interval of -1 effectively disables the optimisation in WebView
857 // that stops repeated touch events flooding WebCore. The Event Sender only sends a
858 // single event rather than a stream of events (like what would generally happen in
859 // a real use of touch events in a WebView) and so if the WebView drops the event,
860 // the test will fail as the test expects one callback for every touch it synthesizes.
861 webview.setTouchInterval(-1);
862 }
863
864 public void setDefaultWebSettings(WebView webview) {
Ben Murdoche6f3e452009-04-22 16:02:31 +0100865 WebSettings settings = webview.getSettings();
Guang Zhuf4bf5522009-07-23 14:19:35 -0700866 settings.setAppCacheEnabled(true);
867 settings.setAppCachePath(getApplicationContext().getCacheDir().getPath());
868 settings.setAppCacheMaxSize(Long.MAX_VALUE);
Ben Murdoche6f3e452009-04-22 16:02:31 +0100869 settings.setJavaScriptEnabled(true);
870 settings.setJavaScriptCanOpenWindowsAutomatically(true);
871 settings.setSupportMultipleWindows(true);
872 settings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NORMAL);
873 settings.setDatabaseEnabled(true);
874 settings.setDatabasePath(getDir("databases",0).getAbsolutePath());
875 settings.setDomStorageEnabled(true);
Guang Zhub028f922009-08-11 14:27:32 -0700876 settings.setWorkersEnabled(false);
Elliott Slaughterbe1304f2010-06-23 11:29:02 -0700877 settings.setXSSAuditorEnabled(false);
Ben Murdoche6f3e452009-04-22 16:02:31 +0100878 }
879
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700880 private WebView mWebView;
881 private WebViewEventSender mEventSender;
882 private AsyncHandler mHandler;
883 private TestShellCallback mCallback;
884
885 private CallbackProxy mCallbackProxy;
Guang Zhuf92bd422009-06-29 10:40:55 -0700886
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700887 private String mTestUrl;
888 private String mResultFile;
889 private int mTimeoutInMillis;
Guang Zhuf92bd422009-06-29 10:40:55 -0700890 private String mUiAutoTestPath;
Guang Zhu5dc4f212009-10-29 18:24:54 -0700891 private String mSaveImagePath;
Guang Zhuf92bd422009-06-29 10:40:55 -0700892 private BufferedReader mTestListReader;
Guang Zhu5dc4f212009-10-29 18:24:54 -0700893 private boolean mGetDrawtime;
Ben Murdoch9b815d02010-06-01 18:45:10 +0100894 private int mTotalTestCount;
895 private int mCurrentTestNumber;
Guang Zhu5d53c192010-07-14 17:17:54 -0700896 private boolean mStopOnRefError;
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700897
898 // States
899 private boolean mTimedOut;
900 private boolean mRequestedWebKitData;
901 private boolean mFinishedRunning;
902
903 // Layout test controller variables.
Guang Zhu1871fe02009-04-29 14:49:03 -0700904 private DumpDataType mDumpDataType;
905 private DumpDataType mDefaultDumpDataType = DumpDataType.EXT_REPR;
Shimeng (Simon) Wangad456862010-06-16 17:32:24 -0700906 private boolean mDumpTopFrameAsText;
907 private boolean mDumpChildFramesAsText;
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700908 private boolean mWaitUntilDone;
909 private boolean mDumpTitleChanges;
910 private StringBuffer mTitleChanges;
911 private StringBuffer mDialogStrings;
912 private boolean mKeepWebHistory;
913 private Vector mWebHistory;
Ben Murdoche6f3e452009-04-22 16:02:31 +0100914 private boolean mDumpDatabaseCallbacks;
915 private StringBuffer mDatabaseCallbackStrings;
916 private StringBuffer mConsoleMessages;
917 private boolean mCanOpenWindows;
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700918
Ben Murdoch2eea5f32009-09-23 15:28:57 +0100919 private boolean mPageFinished = false;
920 private boolean mDumpWebKitData = false;
Ben Murdoch977f7692009-09-16 20:13:07 +0100921
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700922 static final String TIMEOUT_STR = "**Test timeout";
Guang Zhuf92bd422009-06-29 10:40:55 -0700923
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700924 static final int MSG_TIMEOUT = 0;
925 static final int MSG_WEBKIT_DATA = 1;
926
927 static final String LOGTAG="TestShell";
Guang Zhuf92bd422009-06-29 10:40:55 -0700928
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700929 static final String TEST_URL = "TestUrl";
930 static final String RESULT_FILE = "ResultFile";
931 static final String TIMEOUT_IN_MILLIS = "TimeoutInMillis";
Guang Zhuf92bd422009-06-29 10:40:55 -0700932 static final String UI_AUTO_TEST = "UiAutoTest";
Guang Zhu5dc4f212009-10-29 18:24:54 -0700933 static final String GET_DRAW_TIME = "GetDrawTime";
934 static final String SAVE_IMAGE = "SaveImage";
Ben Murdoch9b815d02010-06-01 18:45:10 +0100935 static final String TOTAL_TEST_COUNT = "TestCount";
936 static final String CURRENT_TEST_NUMBER = "TestNumber";
Guang Zhu5d53c192010-07-14 17:17:54 -0700937 static final String STOP_ON_REF_ERROR = "StopOnReferenceError";
Guang Zhu5dc4f212009-10-29 18:24:54 -0700938
939 static final int DRAW_RUNS = 5;
Christian Mehlmauer8b85dce2010-07-19 20:11:27 +0200940 static final String DRAW_TIME_LOG = Environment.getExternalStorageDirectory() +
941 "/android/page_draw_time.txt";
Steve Blockdad347c2009-08-19 18:46:34 +0100942
Steve Blockf0f30c62010-08-18 15:15:42 +0100943 private boolean mIsGeolocationPermissionSet;
Steve Blockdad347c2009-08-19 18:46:34 +0100944 private boolean mGeolocationPermission;
Steve Blockf0f30c62010-08-18 15:15:42 +0100945 private Map mPendingGeolocationPermissionCallbacks;
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700946}