TestShellActivity.java revision fc4a69e9c13d7233876a0f507ebca2eec25a4215
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 // We can't open windows, so just send null back. 674 WebView.WebViewTransport transport = 675 (WebView.WebViewTransport) resultMsg.obj; 676 transport.setWebView(null); 677 resultMsg.sendToTarget(); 678 return true; 679 } 680 681 // We never display the new window, just create the view and 682 // allow it's content to execute and be recorded by the test 683 // runner. 684 685 HashMap<String, Object> jsIfaces = new HashMap<String, Object>(); 686 jsIfaces.put("layoutTestController", mCallbackProxy); 687 jsIfaces.put("eventSender", mCallbackProxy); 688 WebView newWindowView = new NewWindowWebView(TestShellActivity.this, jsIfaces); 689 setupWebViewForLayoutTests(newWindowView, mCallbackProxy); 690 WebView.WebViewTransport transport = 691 (WebView.WebViewTransport) resultMsg.obj; 692 transport.setWebView(newWindowView); 693 resultMsg.sendToTarget(); 694 return true; 695 } 696 697 @Override 698 public void onCloseWindow(WebView view) { 699 view.destroy(); 700 } 701 }; 702 703 private static class NewWindowWebView extends WebView { 704 public NewWindowWebView(Context context, Map<String, Object> jsIfaces) { 705 super(context, null, 0, jsIfaces); 706 } 707 } 708 709 private void resetTestStatus() { 710 mWaitUntilDone = false; 711 mDumpDataType = mDefaultDumpDataType; 712 mTimedOut = false; 713 mDumpTitleChanges = false; 714 mRequestedWebKitData = false; 715 mDumpDatabaseCallbacks = false; 716 mCanOpenWindows = false; 717 mEventSender.resetMouse(); 718 mEventSender.clearTouchPoints(); 719 mPageFinished = false; 720 mOneHundredPercentComplete = false; 721 mDumpWebKitData = false; 722 mGetDrawtime = false; 723 mSaveImagePath = null; 724 } 725 726 private long[] getDrawWebViewTime(WebView view, int count) { 727 if (count == 0) 728 return null; 729 long[] ret = new long[count]; 730 long start; 731 Canvas canvas = new Canvas(); 732 Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Config.ARGB_8888); 733 canvas.setBitmap(bitmap); 734 for (int i = 0; i < count; i++) { 735 start = System.currentTimeMillis(); 736 view.draw(canvas); 737 ret[i] = System.currentTimeMillis() - start; 738 } 739 return ret; 740 } 741 742 private void drawPageToFile(String fileName, WebView view) { 743 Canvas canvas = new Canvas(); 744 Bitmap bitmap = Bitmap.createBitmap(view.getContentWidth(), view.getContentHeight(), 745 Config.ARGB_8888); 746 canvas.setBitmap(bitmap); 747 view.drawPage(canvas); 748 try { 749 FileOutputStream fos = new FileOutputStream(fileName); 750 if(!bitmap.compress(CompressFormat.PNG, 90, fos)) { 751 Log.w(LOGTAG, "Failed to compress and save image."); 752 } 753 } catch (IOException ioe) { 754 Log.e(LOGTAG, "", ioe); 755 } 756 bitmap.recycle(); 757 } 758 759 private boolean canMoveToNextTest() { 760 return (mDumpWebKitData && mOneHundredPercentComplete && mPageFinished && !mWaitUntilDone) || mTimedOut; 761 } 762 763 private void setupWebViewForLayoutTests(WebView webview, CallbackProxy callbackProxy) { 764 if (webview == null) { 765 return; 766 } 767 768 WebSettings settings = webview.getSettings(); 769 settings.setAppCacheEnabled(true); 770 settings.setAppCachePath(getApplicationContext().getCacheDir().getPath()); 771 settings.setAppCacheMaxSize(Long.MAX_VALUE); 772 settings.setJavaScriptEnabled(true); 773 settings.setJavaScriptCanOpenWindowsAutomatically(true); 774 settings.setSupportMultipleWindows(true); 775 settings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NORMAL); 776 settings.setDatabaseEnabled(true); 777 settings.setDatabasePath(getDir("databases",0).getAbsolutePath()); 778 settings.setDomStorageEnabled(true); 779 settings.setWorkersEnabled(false); 780 781 webview.setWebChromeClient(mChromeClient); 782 webview.setWebViewClient(mViewClient); 783 // Setting a touch interval of -1 effectively disables the optimisation in WebView 784 // that stops repeated touch events flooding WebCore. The Event Sender only sends a 785 // single event rather than a stream of events (like what would generally happen in 786 // a real use of touch events in a WebView) and so if the WebView drops the event, 787 // the test will fail as the test expects one callback for every touch it synthesizes. 788 webview.setTouchInterval(-1); 789 } 790 791 private WebView mWebView; 792 private WebViewEventSender mEventSender; 793 private AsyncHandler mHandler; 794 private TestShellCallback mCallback; 795 796 private CallbackProxy mCallbackProxy; 797 798 private String mTestUrl; 799 private String mResultFile; 800 private int mTimeoutInMillis; 801 private String mUiAutoTestPath; 802 private String mSaveImagePath; 803 private BufferedReader mTestListReader; 804 private boolean mGetDrawtime; 805 806 // States 807 private boolean mTimedOut; 808 private boolean mRequestedWebKitData; 809 private boolean mFinishedRunning; 810 811 // Layout test controller variables. 812 private DumpDataType mDumpDataType; 813 private DumpDataType mDefaultDumpDataType = DumpDataType.EXT_REPR; 814 private boolean mWaitUntilDone; 815 private boolean mDumpTitleChanges; 816 private StringBuffer mTitleChanges; 817 private StringBuffer mDialogStrings; 818 private boolean mKeepWebHistory; 819 private Vector mWebHistory; 820 private boolean mDumpDatabaseCallbacks; 821 private StringBuffer mDatabaseCallbackStrings; 822 private StringBuffer mConsoleMessages; 823 private boolean mCanOpenWindows; 824 825 private boolean mPageFinished = false; 826 private boolean mDumpWebKitData = false; 827 private boolean mOneHundredPercentComplete = false; 828 829 static final String TIMEOUT_STR = "**Test timeout"; 830 831 static final int MSG_TIMEOUT = 0; 832 static final int MSG_WEBKIT_DATA = 1; 833 834 static final String LOGTAG="TestShell"; 835 836 static final String TEST_URL = "TestUrl"; 837 static final String RESULT_FILE = "ResultFile"; 838 static final String TIMEOUT_IN_MILLIS = "TimeoutInMillis"; 839 static final String UI_AUTO_TEST = "UiAutoTest"; 840 static final String GET_DRAW_TIME = "GetDrawTime"; 841 static final String SAVE_IMAGE = "SaveImage"; 842 843 static final int DRAW_RUNS = 5; 844 static final String DRAW_TIME_LOG = "/sdcard/android/page_draw_time.txt"; 845 846 private boolean mGeolocationPermissionSet; 847 private boolean mGeolocationPermission; 848} 849