TestShellActivity.java revision 980a938c1c9a6a5791a8240e5a1e6638ab28dc77
1/* 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 19import com.android.dumprendertree.forwarder.ForwardService; 20 21import android.app.Activity; 22import android.app.AlertDialog; 23import android.content.Context; 24import android.content.DialogInterface; 25import android.content.Intent; 26import android.content.DialogInterface.OnClickListener; 27import android.graphics.Bitmap; 28import android.graphics.Canvas; 29import android.graphics.Bitmap.CompressFormat; 30import android.graphics.Bitmap.Config; 31import android.net.http.SslError; 32import android.os.Bundle; 33import android.os.Handler; 34import android.os.Message; 35import android.util.Log; 36import android.view.ViewGroup; 37import android.webkit.GeolocationPermissions; 38import android.webkit.HttpAuthHandler; 39import android.webkit.JsPromptResult; 40import android.webkit.JsResult; 41import android.webkit.SslErrorHandler; 42import android.webkit.WebChromeClient; 43import android.webkit.WebSettings; 44import android.webkit.WebStorage; 45import android.webkit.WebView; 46import android.webkit.WebViewClient; 47import android.widget.LinearLayout; 48 49import java.io.BufferedReader; 50import java.io.File; 51import java.io.FileOutputStream; 52import java.io.FileReader; 53import java.io.IOException; 54import java.net.MalformedURLException; 55import java.net.URL; 56import java.util.HashMap; 57import java.util.Map; 58import java.util.Vector; 59 60public class TestShellActivity extends Activity implements LayoutTestController { 61 62 static enum DumpDataType {DUMP_AS_TEXT, EXT_REPR, NO_OP} 63 64 public class AsyncHandler extends Handler { 65 @Override 66 public void handleMessage(Message msg) { 67 if (msg.what == MSG_TIMEOUT) { 68 mTimedOut = true; 69 if (mCallback != null) 70 mCallback.timedOut(mWebView.getUrl()); 71 if (!mRequestedWebKitData) { 72 requestWebKitData(); 73 } else { 74 // if timed out and webkit data has been dumped before 75 // finish directly 76 finished(); 77 } 78 return; 79 } else if (msg.what == MSG_WEBKIT_DATA) { 80 TestShellActivity.this.dump(mTimedOut, (String)msg.obj); 81 return; 82 } 83 84 super.handleMessage(msg); 85 } 86 } 87 88 public void requestWebKitData() { 89 Message callback = mHandler.obtainMessage(MSG_WEBKIT_DATA); 90 91 if (mRequestedWebKitData) 92 throw new AssertionError("Requested webkit data twice: " + mWebView.getUrl()); 93 94 mRequestedWebKitData = true; 95 Log.v(LOGTAG, "message sent to WebView to dump text."); 96 switch (mDumpDataType) { 97 case DUMP_AS_TEXT: 98 mWebView.documentAsText(callback); 99 break; 100 case EXT_REPR: 101 mWebView.externalRepresentation(callback); 102 break; 103 default: 104 finished(); 105 break; 106 } 107 } 108 109 public void clearCache() { 110 mWebView.freeMemory(); 111 } 112 113 @Override 114 protected void onCreate(Bundle icicle) { 115 super.onCreate(icicle); 116 117 LinearLayout contentView = new LinearLayout(this); 118 contentView.setOrientation(LinearLayout.VERTICAL); 119 setContentView(contentView); 120 121 mWebView = new WebView(this); 122 mEventSender = new WebViewEventSender(mWebView); 123 mCallbackProxy = new CallbackProxy(mEventSender, this); 124 125 mWebView.addJavascriptInterface(mCallbackProxy, "layoutTestController"); 126 mWebView.addJavascriptInterface(mCallbackProxy, "eventSender"); 127 setupWebViewForLayoutTests(mWebView, mCallbackProxy); 128 129 contentView.addView(mWebView, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT, 0.0f)); 130 131 mWebView.getSettings().setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NORMAL); 132 133 // Expose window.gc function to JavaScript. JSC build exposes 134 // this function by default, but V8 requires the flag to turn it on. 135 // WebView::setJsFlags is noop in JSC build. 136 mWebView.setJsFlags("--expose_gc"); 137 138 mHandler = new AsyncHandler(); 139 140 Intent intent = getIntent(); 141 if (intent != null) { 142 executeIntent(intent); 143 } 144 } 145 146 @Override 147 protected void onNewIntent(Intent intent) { 148 super.onNewIntent(intent); 149 executeIntent(intent); 150 } 151 152 private void executeIntent(Intent intent) { 153 resetTestStatus(); 154 if (!Intent.ACTION_VIEW.equals(intent.getAction())) { 155 return; 156 } 157 158 mTestUrl = intent.getStringExtra(TEST_URL); 159 if (mTestUrl == null) { 160 mUiAutoTestPath = intent.getStringExtra(UI_AUTO_TEST); 161 if(mUiAutoTestPath != null) { 162 beginUiAutoTest(); 163 } 164 return; 165 } 166 167 mResultFile = intent.getStringExtra(RESULT_FILE); 168 mTimeoutInMillis = intent.getIntExtra(TIMEOUT_IN_MILLIS, 0); 169 mGetDrawtime = intent.getBooleanExtra(GET_DRAW_TIME, false); 170 mSaveImagePath = intent.getStringExtra(SAVE_IMAGE); 171 172 Log.v(LOGTAG, " Loading " + mTestUrl); 173 mWebView.loadUrl(mTestUrl); 174 175 if (mTimeoutInMillis > 0) { 176 // Create a timeout timer 177 Message m = mHandler.obtainMessage(MSG_TIMEOUT); 178 mHandler.sendMessageDelayed(m, mTimeoutInMillis); 179 } 180 } 181 182 private void beginUiAutoTest() { 183 try { 184 mTestListReader = new BufferedReader( 185 new FileReader(mUiAutoTestPath)); 186 } catch (IOException ioe) { 187 Log.e(LOGTAG, "Failed to open test list for read.", ioe); 188 finishUiAutoTest(); 189 return; 190 } 191 moveToNextTest(); 192 } 193 194 private void finishUiAutoTest() { 195 try { 196 if(mTestListReader != null) 197 mTestListReader.close(); 198 } catch (IOException ioe) { 199 Log.w(LOGTAG, "Failed to close test list file.", ioe); 200 } 201 ForwardService.getForwardService().stopForwardService(); 202 finished(); 203 } 204 205 private void moveToNextTest() { 206 String url = null; 207 try { 208 url = mTestListReader.readLine(); 209 } catch (IOException ioe) { 210 Log.e(LOGTAG, "Failed to read next test.", ioe); 211 finishUiAutoTest(); 212 return; 213 } 214 if (url == null) { 215 mUiAutoTestPath = null; 216 finishUiAutoTest(); 217 AlertDialog.Builder builder = new AlertDialog.Builder(this); 218 builder.setMessage("All tests finished. Exit?") 219 .setCancelable(false) 220 .setPositiveButton("Yes", new OnClickListener(){ 221 public void onClick(DialogInterface dialog, int which) { 222 TestShellActivity.this.finish(); 223 } 224 }) 225 .setNegativeButton("No", new OnClickListener(){ 226 public void onClick(DialogInterface dialog, int which) { 227 dialog.cancel(); 228 } 229 }); 230 builder.create().show(); 231 return; 232 } 233 Intent intent = new Intent(Intent.ACTION_VIEW); 234 intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); 235 intent.putExtra(TestShellActivity.TEST_URL, FsUtils.getTestUrl(url)); 236 intent.putExtra(TIMEOUT_IN_MILLIS, 10000); 237 executeIntent(intent); 238 } 239 240 @Override 241 protected void onStop() { 242 super.onStop(); 243 mWebView.stopLoading(); 244 } 245 246 @Override 247 protected void onDestroy() { 248 super.onDestroy(); 249 mWebView.destroy(); 250 mWebView = null; 251 } 252 253 @Override 254 public void onLowMemory() { 255 super.onLowMemory(); 256 Log.e(LOGTAG, "Low memory, clearing caches"); 257 mWebView.freeMemory(); 258 } 259 260 // Dump the page 261 public void dump(boolean timeout, String webkitData) { 262 mDumpWebKitData = true; 263 if (mResultFile == null || mResultFile.length() == 0) { 264 finished(); 265 return; 266 } 267 268 try { 269 File parentDir = new File(mResultFile).getParentFile(); 270 if (!parentDir.exists()) { 271 parentDir.mkdirs(); 272 } 273 274 FileOutputStream os = new FileOutputStream(mResultFile); 275 if (timeout) { 276 Log.w("Layout test: Timeout", mResultFile); 277 os.write(TIMEOUT_STR.getBytes()); 278 os.write('\n'); 279 } 280 if (mDumpTitleChanges) 281 os.write(mTitleChanges.toString().getBytes()); 282 if (mDialogStrings != null) 283 os.write(mDialogStrings.toString().getBytes()); 284 mDialogStrings = null; 285 if (mDatabaseCallbackStrings != null) 286 os.write(mDatabaseCallbackStrings.toString().getBytes()); 287 mDatabaseCallbackStrings = null; 288 if (mConsoleMessages != null) 289 os.write(mConsoleMessages.toString().getBytes()); 290 mConsoleMessages = null; 291 if (webkitData != null) 292 os.write(webkitData.getBytes()); 293 os.flush(); 294 os.close(); 295 } catch (IOException ex) { 296 Log.e(LOGTAG, "Cannot write to " + mResultFile + ", " + ex.getMessage()); 297 } 298 299 finished(); 300 } 301 302 public void setCallback(TestShellCallback callback) { 303 mCallback = callback; 304 } 305 306 public boolean finished() { 307 if (canMoveToNextTest()) { 308 mHandler.removeMessages(MSG_TIMEOUT); 309 if (mUiAutoTestPath != null) { 310 //don't really finish here 311 moveToNextTest(); 312 } else { 313 if (mCallback != null) { 314 mCallback.finished(); 315 } 316 } 317 return true; 318 } 319 return false; 320 } 321 322 public void setDefaultDumpDataType(DumpDataType defaultDumpDataType) { 323 mDefaultDumpDataType = defaultDumpDataType; 324 } 325 326 // ....................................... 327 // LayoutTestController Functions 328 public void dumpAsText() { 329 mDumpDataType = DumpDataType.DUMP_AS_TEXT; 330 if (mWebView != null) { 331 String url = mWebView.getUrl(); 332 Log.v(LOGTAG, "dumpAsText called: "+url); 333 } 334 } 335 336 public void waitUntilDone() { 337 mWaitUntilDone = true; 338 String url = mWebView.getUrl(); 339 Log.v(LOGTAG, "waitUntilDone called: " + url); 340 } 341 342 public void notifyDone() { 343 String url = mWebView.getUrl(); 344 Log.v(LOGTAG, "notifyDone called: " + url); 345 if (mWaitUntilDone) { 346 mWaitUntilDone = false; 347 mChromeClient.onProgressChanged(mWebView, 101); 348 } 349 } 350 351 public void display() { 352 mWebView.invalidate(); 353 } 354 355 public void clearBackForwardList() { 356 mWebView.clearHistory(); 357 358 } 359 360 public void dumpBackForwardList() { 361 //printf("\n============== Back Forward List ==============\n"); 362 // mWebHistory 363 //printf("===============================================\n"); 364 365 } 366 367 public void dumpChildFrameScrollPositions() { 368 // TODO Auto-generated method stub 369 370 } 371 372 public void dumpEditingCallbacks() { 373 // TODO Auto-generated method stub 374 375 } 376 377 public void dumpSelectionRect() { 378 // TODO Auto-generated method stub 379 380 } 381 382 public void dumpTitleChanges() { 383 if (!mDumpTitleChanges) { 384 mTitleChanges = new StringBuffer(); 385 } 386 mDumpTitleChanges = true; 387 } 388 389 public void keepWebHistory() { 390 if (!mKeepWebHistory) { 391 mWebHistory = new Vector(); 392 } 393 mKeepWebHistory = true; 394 } 395 396 public void queueBackNavigation(int howfar) { 397 // TODO Auto-generated method stub 398 399 } 400 401 public void queueForwardNavigation(int howfar) { 402 // TODO Auto-generated method stub 403 404 } 405 406 public void queueLoad(String Url, String frameTarget) { 407 // TODO Auto-generated method stub 408 409 } 410 411 public void queueReload() { 412 mWebView.reload(); 413 } 414 415 public void queueScript(String scriptToRunInCurrentContext) { 416 mWebView.loadUrl("javascript:"+scriptToRunInCurrentContext); 417 } 418 419 public void repaintSweepHorizontally() { 420 // TODO Auto-generated method stub 421 422 } 423 424 public void setAcceptsEditing(boolean b) { 425 // TODO Auto-generated method stub 426 427 } 428 429 public void setMainFrameIsFirstResponder(boolean b) { 430 // TODO Auto-generated method stub 431 432 } 433 434 public void setWindowIsKey(boolean b) { 435 // This is meant to show/hide the window. The best I can find 436 // is setEnabled() 437 mWebView.setEnabled(b); 438 } 439 440 public void testRepaint() { 441 mWebView.invalidate(); 442 } 443 444 public void dumpDatabaseCallbacks() { 445 Log.v(LOGTAG, "dumpDatabaseCallbacks called."); 446 mDumpDatabaseCallbacks = true; 447 } 448 449 public void setCanOpenWindows() { 450 Log.v(LOGTAG, "setCanOpenWindows called."); 451 mCanOpenWindows = true; 452 } 453 454 /** 455 * Sets the Geolocation permission state to be used for all future requests. 456 */ 457 public void setGeolocationPermission(boolean allow) { 458 mGeolocationPermissionSet = true; 459 mGeolocationPermission = allow; 460 } 461 462 private final WebViewClient mViewClient = new WebViewClient(){ 463 @Override 464 public void onPageFinished(WebView view, String url) { 465 Log.v(LOGTAG, "onPageFinished, url=" + url); 466 mPageFinished = true; 467 // get page draw time 468 if (FsUtils.isTestPageUrl(url)) { 469 if (mGetDrawtime) { 470 long[] times = new long[DRAW_RUNS]; 471 times = getDrawWebViewTime(mWebView, DRAW_RUNS); 472 FsUtils.writeDrawTime(DRAW_TIME_LOG, url, times); 473 } 474 if (mSaveImagePath != null) { 475 String name = FsUtils.getLastSegmentInPath(url); 476 drawPageToFile(mSaveImagePath + "/" + name + ".png", mWebView); 477 } 478 } 479 // Calling finished() will check if we've met all the conditions for completing 480 // this test and move to the next one if we are ready. 481 if (finished()) { 482 return; 483 } 484 super.onPageFinished(view, url); 485 } 486 487 @Override 488 public void onPageStarted(WebView view, String url, Bitmap favicon) { 489 Log.v(LOGTAG, "onPageStarted, url=" + url); 490 mPageFinished = false; 491 super.onPageStarted(view, url, favicon); 492 } 493 494 @Override 495 public void onReceivedError(WebView view, int errorCode, String description, 496 String failingUrl) { 497 Log.v(LOGTAG, "onReceivedError, errorCode=" + errorCode 498 + ", desc=" + description + ", url=" + failingUrl); 499 super.onReceivedError(view, errorCode, description, failingUrl); 500 } 501 502 @Override 503 public void onReceivedHttpAuthRequest(WebView view, HttpAuthHandler handler, 504 String host, String realm) { 505 handler.cancel(); 506 } 507 508 @Override 509 public void onReceivedSslError(WebView view, SslErrorHandler handler, 510 SslError error) { 511 handler.proceed(); 512 } 513 }; 514 515 516 private final WebChromeClient mChromeClient = new WebChromeClient() { 517 @Override 518 public void onProgressChanged(WebView view, int newProgress) { 519 520 // notifyDone calls this with 101%. We only want to update this flag if this 521 // is the real call from WebCore. 522 if (newProgress == 100) { 523 mOneHundredPercentComplete = true; 524 } 525 526 // With the flag updated, we can now proceed as normal whether the progress update came from 527 // WebCore or notifyDone. 528 if (newProgress >= 100) { 529 // finished() will check if we are ready to move to the next test and do so if we are. 530 if (finished()) { 531 return; 532 } 533 534 if (!mTimedOut && !mWaitUntilDone && !mRequestedWebKitData) { 535 String url = mWebView.getUrl(); 536 Log.v(LOGTAG, "Finished: "+ url); 537 requestWebKitData(); 538 } else { 539 String url = mWebView.getUrl(); 540 if (mTimedOut) { 541 Log.v(LOGTAG, "Timed out before finishing: " + url); 542 } else if (mWaitUntilDone) { 543 Log.v(LOGTAG, "Waiting for notifyDone: " + url); 544 } else if (mRequestedWebKitData) { 545 Log.v(LOGTAG, "Requested webkit data ready: " + url); 546 } 547 } 548 } 549 } 550 551 @Override 552 public void onReceivedTitle(WebView view, String title) { 553 if (title.length() > 30) 554 title = "..."+title.substring(title.length()-30); 555 setTitle(title); 556 if (mDumpTitleChanges) { 557 mTitleChanges.append("TITLE CHANGED: "); 558 mTitleChanges.append(title); 559 mTitleChanges.append("\n"); 560 } 561 } 562 563 @Override 564 public boolean onJsAlert(WebView view, String url, String message, 565 JsResult result) { 566 if (mDialogStrings == null) { 567 mDialogStrings = new StringBuffer(); 568 } 569 mDialogStrings.append("ALERT: "); 570 mDialogStrings.append(message); 571 mDialogStrings.append('\n'); 572 result.confirm(); 573 return true; 574 } 575 576 @Override 577 public boolean onJsConfirm(WebView view, String url, String message, 578 JsResult result) { 579 if (mDialogStrings == null) { 580 mDialogStrings = new StringBuffer(); 581 } 582 mDialogStrings.append("CONFIRM: "); 583 mDialogStrings.append(message); 584 mDialogStrings.append('\n'); 585 result.confirm(); 586 return true; 587 } 588 589 @Override 590 public boolean onJsPrompt(WebView view, String url, String message, 591 String defaultValue, JsPromptResult result) { 592 if (mDialogStrings == null) { 593 mDialogStrings = new StringBuffer(); 594 } 595 mDialogStrings.append("PROMPT: "); 596 mDialogStrings.append(message); 597 mDialogStrings.append(", default text: "); 598 mDialogStrings.append(defaultValue); 599 mDialogStrings.append('\n'); 600 result.confirm(); 601 return true; 602 } 603 604 @Override 605 public boolean onJsTimeout() { 606 Log.v(LOGTAG, "JavaScript timeout"); 607 return false; 608 } 609 610 @Override 611 public void onExceededDatabaseQuota(String url_str, 612 String databaseIdentifier, long currentQuota, 613 long estimatedSize, long totalUsedQuota, 614 WebStorage.QuotaUpdater callback) { 615 if (mDumpDatabaseCallbacks) { 616 if (mDatabaseCallbackStrings == null) { 617 mDatabaseCallbackStrings = new StringBuffer(); 618 } 619 620 String protocol = ""; 621 String host = ""; 622 int port = 0; 623 624 try { 625 URL url = new URL(url_str); 626 protocol = url.getProtocol(); 627 host = url.getHost(); 628 if (url.getPort() > -1) { 629 port = url.getPort(); 630 } 631 } catch (MalformedURLException e) {} 632 633 String databaseCallbackString = 634 "UI DELEGATE DATABASE CALLBACK: " + 635 "exceededDatabaseQuotaForSecurityOrigin:{" + protocol + 636 ", " + host + ", " + port + "} database:" + 637 databaseIdentifier + "\n"; 638 Log.v(LOGTAG, "LOG: "+databaseCallbackString); 639 mDatabaseCallbackStrings.append(databaseCallbackString); 640 } 641 // Give 5MB more quota. 642 callback.updateQuota(currentQuota + 1024 * 1024 * 5); 643 } 644 645 /** 646 * Instructs the client to show a prompt to ask the user to set the 647 * Geolocation permission state for the specified origin. 648 */ 649 @Override 650 public void onGeolocationPermissionsShowPrompt(String origin, 651 GeolocationPermissions.Callback callback) { 652 if (mGeolocationPermissionSet) { 653 callback.invoke(origin, mGeolocationPermission, false); 654 } 655 } 656 657 @Override 658 public void onConsoleMessage(String message, int lineNumber, 659 String sourceID) { 660 if (mConsoleMessages == null) { 661 mConsoleMessages = new StringBuffer(); 662 } 663 String consoleMessage = "CONSOLE MESSAGE: line " 664 + lineNumber +": "+ message +"\n"; 665 mConsoleMessages.append(consoleMessage); 666 Log.v(LOGTAG, "LOG: "+consoleMessage); 667 } 668 669 @Override 670 public boolean onCreateWindow(WebView view, boolean dialog, 671 boolean userGesture, Message resultMsg) { 672 if (!mCanOpenWindows) { 673 return false; 674 } 675 676 // We never display the new window, just create the view and 677 // allow it's content to execute and be recorded by the test 678 // runner. 679 680 HashMap<String, Object> jsIfaces = new HashMap<String, Object>(); 681 jsIfaces.put("layoutTestController", mCallbackProxy); 682 jsIfaces.put("eventSender", mCallbackProxy); 683 WebView newWindowView = new NewWindowWebView(TestShellActivity.this, jsIfaces); 684 setupWebViewForLayoutTests(newWindowView, mCallbackProxy); 685 WebView.WebViewTransport transport = 686 (WebView.WebViewTransport) resultMsg.obj; 687 transport.setWebView(newWindowView); 688 resultMsg.sendToTarget(); 689 return true; 690 } 691 }; 692 693 private static class NewWindowWebView extends WebView { 694 public NewWindowWebView(Context context, Map<String, Object> jsIfaces) { 695 super(context, null, 0, jsIfaces); 696 } 697 } 698 699 private void resetTestStatus() { 700 mWaitUntilDone = false; 701 mDumpDataType = mDefaultDumpDataType; 702 mTimedOut = false; 703 mDumpTitleChanges = false; 704 mRequestedWebKitData = false; 705 mDumpDatabaseCallbacks = false; 706 mCanOpenWindows = false; 707 mEventSender.resetMouse(); 708 mPageFinished = false; 709 mOneHundredPercentComplete = false; 710 mDumpWebKitData = false; 711 mGetDrawtime = false; 712 mSaveImagePath = null; 713 } 714 715 private long[] getDrawWebViewTime(WebView view, int count) { 716 if (count == 0) 717 return null; 718 long[] ret = new long[count]; 719 long start; 720 Canvas canvas = new Canvas(); 721 Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Config.ARGB_8888); 722 canvas.setBitmap(bitmap); 723 for (int i = 0; i < count; i++) { 724 start = System.currentTimeMillis(); 725 view.draw(canvas); 726 ret[i] = System.currentTimeMillis() - start; 727 } 728 return ret; 729 } 730 731 private void drawPageToFile(String fileName, WebView view) { 732 Canvas canvas = new Canvas(); 733 Bitmap bitmap = Bitmap.createBitmap(view.getContentWidth(), view.getContentHeight(), 734 Config.ARGB_8888); 735 canvas.setBitmap(bitmap); 736 view.drawPage(canvas); 737 try { 738 FileOutputStream fos = new FileOutputStream(fileName); 739 if(!bitmap.compress(CompressFormat.PNG, 90, fos)) { 740 Log.w(LOGTAG, "Failed to compress and save image."); 741 } 742 } catch (IOException ioe) { 743 Log.e(LOGTAG, "", ioe); 744 } 745 bitmap.recycle(); 746 } 747 748 private boolean canMoveToNextTest() { 749 return (mDumpWebKitData && mOneHundredPercentComplete && mPageFinished && !mWaitUntilDone) || mTimedOut; 750 } 751 752 private void setupWebViewForLayoutTests(WebView webview, CallbackProxy callbackProxy) { 753 if (webview == null) { 754 return; 755 } 756 757 WebSettings settings = webview.getSettings(); 758 settings.setAppCacheEnabled(true); 759 settings.setAppCachePath(getApplicationContext().getCacheDir().getPath()); 760 settings.setAppCacheMaxSize(Long.MAX_VALUE); 761 settings.setJavaScriptEnabled(true); 762 settings.setJavaScriptCanOpenWindowsAutomatically(true); 763 settings.setSupportMultipleWindows(true); 764 settings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NORMAL); 765 settings.setDatabaseEnabled(true); 766 settings.setDatabasePath(getDir("databases",0).getAbsolutePath()); 767 settings.setDomStorageEnabled(true); 768 settings.setWorkersEnabled(false); 769 770 webview.setWebChromeClient(mChromeClient); 771 webview.setWebViewClient(mViewClient); 772 } 773 774 private WebView mWebView; 775 private WebViewEventSender mEventSender; 776 private AsyncHandler mHandler; 777 private TestShellCallback mCallback; 778 779 private CallbackProxy mCallbackProxy; 780 781 private String mTestUrl; 782 private String mResultFile; 783 private int mTimeoutInMillis; 784 private String mUiAutoTestPath; 785 private String mSaveImagePath; 786 private BufferedReader mTestListReader; 787 private boolean mGetDrawtime; 788 789 // States 790 private boolean mTimedOut; 791 private boolean mRequestedWebKitData; 792 private boolean mFinishedRunning; 793 794 // Layout test controller variables. 795 private DumpDataType mDumpDataType; 796 private DumpDataType mDefaultDumpDataType = DumpDataType.EXT_REPR; 797 private boolean mWaitUntilDone; 798 private boolean mDumpTitleChanges; 799 private StringBuffer mTitleChanges; 800 private StringBuffer mDialogStrings; 801 private boolean mKeepWebHistory; 802 private Vector mWebHistory; 803 private boolean mDumpDatabaseCallbacks; 804 private StringBuffer mDatabaseCallbackStrings; 805 private StringBuffer mConsoleMessages; 806 private boolean mCanOpenWindows; 807 808 private boolean mPageFinished = false; 809 private boolean mDumpWebKitData = false; 810 private boolean mOneHundredPercentComplete = false; 811 812 static final String TIMEOUT_STR = "**Test timeout"; 813 814 static final int MSG_TIMEOUT = 0; 815 static final int MSG_WEBKIT_DATA = 1; 816 817 static final String LOGTAG="TestShell"; 818 819 static final String TEST_URL = "TestUrl"; 820 static final String RESULT_FILE = "ResultFile"; 821 static final String TIMEOUT_IN_MILLIS = "TimeoutInMillis"; 822 static final String UI_AUTO_TEST = "UiAutoTest"; 823 static final String GET_DRAW_TIME = "GetDrawTime"; 824 static final String SAVE_IMAGE = "SaveImage"; 825 826 static final int DRAW_RUNS = 5; 827 static final String DRAW_TIME_LOG = "/sdcard/android/page_draw_time.txt"; 828 829 private boolean mGeolocationPermissionSet; 830 private boolean mGeolocationPermission; 831} 832