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