• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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