blob: 42d6457ec0d91fca659c244403e0b528126a8edc [file] [log] [blame]
/*
* Copyright (C) 2007 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.dumprendertree;
import com.android.dumprendertree.forwarder.ForwardService;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.http.SslError;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.ViewGroup;
import android.view.Window;
import android.webkit.ConsoleMessage;
import android.webkit.CookieManager;
import android.webkit.GeolocationPermissions;
import android.webkit.HttpAuthHandler;
import android.webkit.JsPromptResult;
import android.webkit.JsResult;
import android.webkit.SslErrorHandler;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebSettingsClassic;
import android.webkit.WebStorage;
import android.webkit.WebView;
import android.webkit.WebViewClassic;
import android.webkit.WebViewClient;
import android.widget.LinearLayout;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Vector;
public class TestShellActivity extends Activity implements LayoutTestController {
static enum DumpDataType {DUMP_AS_TEXT, EXT_REPR, NO_OP}
// String constants for use with layoutTestController.overridePreferences
private final String WEBKIT_OFFLINE_WEB_APPLICATION_CACHE_ENABLED =
"WebKitOfflineWebApplicationCacheEnabled";
private final String WEBKIT_USES_PAGE_CACHE_PREFERENCE_KEY = "WebKitUsesPageCachePreferenceKey";
public class AsyncHandler extends Handler {
@Override
public void handleMessage(Message msg) {
if (msg.what == MSG_TIMEOUT) {
mTimedOut = true;
mWebView.stopLoading();
if (mCallback != null)
mCallback.timedOut(mWebView.getUrl());
if (!mRequestedWebKitData) {
requestWebKitData();
} else {
// if timed out and webkit data has been dumped before
// finish directly
finished();
}
return;
} else if (msg.what == MSG_WEBKIT_DATA) {
Log.v(LOGTAG, "Received WebView dump data");
mHandler.removeMessages(MSG_DUMP_TIMEOUT);
TestShellActivity.this.dump(mTimedOut, (String)msg.obj);
return;
} else if (msg.what == MSG_DUMP_TIMEOUT) {
throw new RuntimeException("WebView dump timeout, is it pegged?");
}
super.handleMessage(msg);
}
}
public void requestWebKitData() {
setDumpTimeout(DUMP_TIMEOUT_MS);
Message callback = mHandler.obtainMessage(MSG_WEBKIT_DATA);
if (mRequestedWebKitData)
throw new AssertionError("Requested webkit data twice: " + mWebView.getUrl());
mRequestedWebKitData = true;
Log.v(LOGTAG, "message sent to WebView to dump text.");
switch (mDumpDataType) {
case DUMP_AS_TEXT:
callback.arg1 = mDumpTopFrameAsText ? 1 : 0;
callback.arg2 = mDumpChildFramesAsText ? 1 : 0;
mWebViewClassic.documentAsText(callback);
break;
case EXT_REPR:
mWebViewClassic.externalRepresentation(callback);
break;
default:
finished();
break;
}
}
private void setDumpTimeout(long timeout) {
Log.v(LOGTAG, "setting dump timeout at " + timeout);
Message msg = mHandler.obtainMessage(MSG_DUMP_TIMEOUT);
mHandler.sendMessageDelayed(msg, timeout);
}
public void clearCache() {
mWebView.freeMemory();
}
@Override
protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
requestWindowFeature(Window.FEATURE_PROGRESS);
LinearLayout contentView = new LinearLayout(this);
contentView.setOrientation(LinearLayout.VERTICAL);
setContentView(contentView);
CookieManager.setAcceptFileSchemeCookies(true);
mWebView = new WebView(this);
mWebViewClassic = WebViewClassic.fromWebView(mWebView);
mEventSender = new WebViewEventSender(mWebView);
mCallbackProxy = new CallbackProxy(mEventSender, this);
mWebView.addJavascriptInterface(mCallbackProxy, "layoutTestController");
mWebView.addJavascriptInterface(mCallbackProxy, "eventSender");
setupWebViewForLayoutTests(mWebView, mCallbackProxy);
contentView.addView(mWebView, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT, 0.0f));
mWebView.getSettings().setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NORMAL);
// Expose window.gc function to JavaScript. JSC build exposes
// this function by default, but V8 requires the flag to turn it on.
// WebView::setJsFlags is noop in JSC build.
mWebViewClassic.setJsFlags("--expose_gc");
mHandler = new AsyncHandler();
Intent intent = getIntent();
if (intent != null) {
executeIntent(intent);
}
// This is asynchronous, but it gets processed by WebCore before it starts loading pages.
mWebViewClassic.setUseMockDeviceOrientation();
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
executeIntent(intent);
}
private void executeIntent(Intent intent) {
resetTestStatus();
if (!Intent.ACTION_VIEW.equals(intent.getAction())) {
return;
}
mTotalTestCount = intent.getIntExtra(TOTAL_TEST_COUNT, mTotalTestCount);
mCurrentTestNumber = intent.getIntExtra(CURRENT_TEST_NUMBER, mCurrentTestNumber);
mTestUrl = intent.getStringExtra(TEST_URL);
if (mTestUrl == null) {
mUiAutoTestPath = intent.getStringExtra(UI_AUTO_TEST);
if(mUiAutoTestPath != null) {
beginUiAutoTest();
}
return;
}
mResultFile = intent.getStringExtra(RESULT_FILE);
mTimeoutInMillis = intent.getIntExtra(TIMEOUT_IN_MILLIS, 0);
mStopOnRefError = intent.getBooleanExtra(STOP_ON_REF_ERROR, false);
setTitle("Test " + mCurrentTestNumber + " of " + mTotalTestCount);
float ratio = (float)mCurrentTestNumber / mTotalTestCount;
int progress = (int)(ratio * Window.PROGRESS_END);
getWindow().setFeatureInt(Window.FEATURE_PROGRESS, progress);
Log.v(LOGTAG, " Loading " + mTestUrl);
if (mTestUrl.contains("/dumpAsText/")) {
dumpAsText(false);
}
mWebView.loadUrl(mTestUrl);
if (mTimeoutInMillis > 0) {
// Create a timeout timer
Message m = mHandler.obtainMessage(MSG_TIMEOUT);
mHandler.sendMessageDelayed(m, mTimeoutInMillis);
}
}
private void beginUiAutoTest() {
try {
mTestListReader = new BufferedReader(
new FileReader(mUiAutoTestPath));
} catch (IOException ioe) {
Log.e(LOGTAG, "Failed to open test list for read.", ioe);
finishUiAutoTest();
return;
}
moveToNextTest();
}
private void finishUiAutoTest() {
try {
if(mTestListReader != null)
mTestListReader.close();
} catch (IOException ioe) {
Log.w(LOGTAG, "Failed to close test list file.", ioe);
}
ForwardService.getForwardService().stopForwardService();
finished();
}
private void moveToNextTest() {
String url = null;
try {
url = mTestListReader.readLine();
} catch (IOException ioe) {
Log.e(LOGTAG, "Failed to read next test.", ioe);
finishUiAutoTest();
return;
}
if (url == null) {
mUiAutoTestPath = null;
finishUiAutoTest();
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("All tests finished. Exit?")
.setCancelable(false)
.setPositiveButton("Yes", new OnClickListener(){
@Override
public void onClick(DialogInterface dialog, int which) {
TestShellActivity.this.finish();
}
})
.setNegativeButton("No", new OnClickListener(){
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
builder.create().show();
return;
}
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
intent.putExtra(TestShellActivity.TEST_URL, FsUtils.getTestUrl(url));
intent.putExtra(TestShellActivity.CURRENT_TEST_NUMBER, ++mCurrentTestNumber);
intent.putExtra(TIMEOUT_IN_MILLIS, 10000);
executeIntent(intent);
}
@Override
protected void onStop() {
super.onStop();
mWebView.stopLoading();
}
@Override
protected void onDestroy() {
super.onDestroy();
mWebView.destroy();
mWebView = null;
mWebViewClassic = null;
}
@Override
public void onLowMemory() {
super.onLowMemory();
Log.e(LOGTAG, "Low memory, clearing caches");
mWebView.freeMemory();
}
// Dump the page
public void dump(boolean timeout, String webkitData) {
mDumpWebKitData = true;
if (mResultFile == null || mResultFile.length() == 0) {
finished();
return;
}
if (mCallback != null) {
mCallback.dumpResult(webkitData);
}
try {
File parentDir = new File(mResultFile).getParentFile();
if (!parentDir.exists()) {
parentDir.mkdirs();
}
FileOutputStream os = new FileOutputStream(mResultFile);
if (timeout) {
Log.w("Layout test: Timeout", mResultFile);
os.write(TIMEOUT_STR.getBytes());
os.write('\n');
}
if (mDumpTitleChanges)
os.write(mTitleChanges.toString().getBytes());
if (mDialogStrings != null)
os.write(mDialogStrings.toString().getBytes());
mDialogStrings = null;
if (mDatabaseCallbackStrings != null)
os.write(mDatabaseCallbackStrings.toString().getBytes());
mDatabaseCallbackStrings = null;
if (mConsoleMessages != null)
os.write(mConsoleMessages.toString().getBytes());
mConsoleMessages = null;
if (webkitData != null)
os.write(webkitData.getBytes());
os.flush();
os.close();
} catch (IOException ex) {
Log.e(LOGTAG, "Cannot write to " + mResultFile + ", " + ex.getMessage());
}
finished();
}
public void setCallback(TestShellCallback callback) {
mCallback = callback;
}
public boolean finished() {
if (canMoveToNextTest()) {
mHandler.removeMessages(MSG_TIMEOUT);
if (mUiAutoTestPath != null) {
//don't really finish here
moveToNextTest();
} else {
if (mCallback != null) {
mCallback.finished();
}
}
return true;
}
return false;
}
public void setDefaultDumpDataType(DumpDataType defaultDumpDataType) {
mDefaultDumpDataType = defaultDumpDataType;
}
// .......................................
// LayoutTestController Functions
@Override
public void dumpAsText(boolean enablePixelTests) {
// Added after webkit update to r63859. See trac.webkit.org/changeset/63730.
if (enablePixelTests) {
Log.v(LOGTAG, "dumpAsText(enablePixelTests == true) not implemented on Android!");
}
mDumpDataType = DumpDataType.DUMP_AS_TEXT;
mDumpTopFrameAsText = true;
if (mWebView != null) {
String url = mWebView.getUrl();
Log.v(LOGTAG, "dumpAsText called: "+url);
}
}
@Override
public void dumpChildFramesAsText() {
mDumpDataType = DumpDataType.DUMP_AS_TEXT;
mDumpChildFramesAsText = true;
if (mWebView != null) {
String url = mWebView.getUrl();
Log.v(LOGTAG, "dumpChildFramesAsText called: "+url);
}
}
@Override
public void waitUntilDone() {
mWaitUntilDone = true;
String url = mWebView.getUrl();
Log.v(LOGTAG, "waitUntilDone called: " + url);
}
@Override
public void notifyDone() {
String url = mWebView.getUrl();
Log.v(LOGTAG, "notifyDone called: " + url);
if (mWaitUntilDone) {
mWaitUntilDone = false;
if (!mRequestedWebKitData && !mTimedOut && !finished()) {
requestWebKitData();
}
}
}
@Override
public void display() {
mWebView.invalidate();
}
@Override
public void clearBackForwardList() {
mWebView.clearHistory();
}
@Override
public void dumpBackForwardList() {
//printf("\n============== Back Forward List ==============\n");
// mWebHistory
//printf("===============================================\n");
}
@Override
public void dumpChildFrameScrollPositions() {
// TODO Auto-generated method stub
}
@Override
public void dumpEditingCallbacks() {
// TODO Auto-generated method stub
}
@Override
public void dumpSelectionRect() {
// TODO Auto-generated method stub
}
@Override
public void dumpTitleChanges() {
if (!mDumpTitleChanges) {
mTitleChanges = new StringBuffer();
}
mDumpTitleChanges = true;
}
@Override
public void keepWebHistory() {
if (!mKeepWebHistory) {
mWebHistory = new Vector();
}
mKeepWebHistory = true;
}
@Override
public void queueBackNavigation(int howfar) {
// TODO Auto-generated method stub
}
@Override
public void queueForwardNavigation(int howfar) {
// TODO Auto-generated method stub
}
@Override
public void queueLoad(String Url, String frameTarget) {
// TODO Auto-generated method stub
}
@Override
public void queueReload() {
mWebView.reload();
}
@Override
public void queueScript(String scriptToRunInCurrentContext) {
mWebView.loadUrl("javascript:"+scriptToRunInCurrentContext);
}
@Override
public void repaintSweepHorizontally() {
// TODO Auto-generated method stub
}
@Override
public void setAcceptsEditing(boolean b) {
// TODO Auto-generated method stub
}
@Override
public void setMainFrameIsFirstResponder(boolean b) {
// TODO Auto-generated method stub
}
@Override
public void setWindowIsKey(boolean b) {
// This is meant to show/hide the window. The best I can find
// is setEnabled()
mWebView.setEnabled(b);
}
@Override
public void testRepaint() {
mWebView.invalidate();
}
@Override
public void dumpDatabaseCallbacks() {
Log.v(LOGTAG, "dumpDatabaseCallbacks called.");
mDumpDatabaseCallbacks = true;
}
@Override
public void setCanOpenWindows() {
Log.v(LOGTAG, "setCanOpenWindows called.");
mCanOpenWindows = true;
}
@Override
public void setMockGeolocationPosition(double latitude, double longitude, double accuracy) {
WebViewClassic.fromWebView(mWebView).setMockGeolocationPosition(latitude, longitude,
accuracy);
}
@Override
public void setMockGeolocationError(int code, String message) {
WebViewClassic.fromWebView(mWebView).setMockGeolocationError(code, message);
}
@Override
public void setGeolocationPermission(boolean allow) {
Log.v(LOGTAG, "setGeolocationPermission() allow=" + allow);
WebViewClassic.fromWebView(mWebView).setMockGeolocationPermission(allow);
}
@Override
public void setMockDeviceOrientation(boolean canProvideAlpha, double alpha,
boolean canProvideBeta, double beta, boolean canProvideGamma, double gamma) {
WebViewClassic.fromWebView(mWebView).setMockDeviceOrientation(canProvideAlpha, alpha,
canProvideBeta, beta, canProvideGamma, gamma);
}
@Override
public void overridePreference(String key, boolean value) {
// TODO: We should look up the correct WebView for the frame which
// called the layoutTestController method. Currently, we just use the
// WebView for the main frame. EventSender suffers from the same
// problem.
if (WEBKIT_OFFLINE_WEB_APPLICATION_CACHE_ENABLED.equals(key)) {
mWebViewClassic.getSettings().setAppCacheEnabled(value);
} else if (WEBKIT_USES_PAGE_CACHE_PREFERENCE_KEY.equals(key)) {
// Cache the maximum possible number of pages.
mWebViewClassic.getSettings().setPageCacheCapacity(Integer.MAX_VALUE);
} else {
Log.w(LOGTAG, "LayoutTestController.overridePreference(): " +
"Unsupported preference '" + key + "'");
}
}
@Override
public void setXSSAuditorEnabled (boolean flag) {
mWebViewClassic.getSettings().setXSSAuditorEnabled(flag);
}
private final WebViewClient mViewClient = new WebViewClient(){
@Override
public void onPageFinished(WebView view, String url) {
Log.v(LOGTAG, "onPageFinished, url=" + url);
mPageFinished = true;
// Calling finished() will check if we've met all the conditions for completing
// this test and move to the next one if we are ready. Otherwise we ask WebCore to
// dump the page.
if (finished()) {
return;
}
if (!mWaitUntilDone && !mRequestedWebKitData && !mTimedOut) {
requestWebKitData();
} else {
if (mWaitUntilDone) {
Log.v(LOGTAG, "page finished loading but waiting for notifyDone to be called: " + url);
}
if (mRequestedWebKitData) {
Log.v(LOGTAG, "page finished loading but webkit data has already been requested: " + url);
}
if (mTimedOut) {
Log.v(LOGTAG, "page finished loading but already timed out: " + url);
}
}
super.onPageFinished(view, url);
}
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
Log.v(LOGTAG, "onPageStarted, url=" + url);
mPageFinished = false;
super.onPageStarted(view, url, favicon);
}
@Override
public void onReceivedError(WebView view, int errorCode, String description,
String failingUrl) {
Log.v(LOGTAG, "onReceivedError, errorCode=" + errorCode
+ ", desc=" + description + ", url=" + failingUrl);
super.onReceivedError(view, errorCode, description, failingUrl);
}
@Override
public void onReceivedHttpAuthRequest(WebView view, HttpAuthHandler handler,
String host, String realm) {
if (handler.useHttpAuthUsernamePassword() && view != null) {
String[] credentials = view.getHttpAuthUsernamePassword(host, realm);
if (credentials != null && credentials.length == 2) {
handler.proceed(credentials[0], credentials[1]);
return;
}
}
handler.cancel();
}
@Override
public void onReceivedSslError(WebView view, SslErrorHandler handler,
SslError error) {
handler.proceed();
}
};
private final WebChromeClient mChromeClient = new WebChromeClient() {
@Override
public void onReceivedTitle(WebView view, String title) {
setTitle("Test " + mCurrentTestNumber + " of " + mTotalTestCount + ": "+ title);
if (mDumpTitleChanges) {
mTitleChanges.append("TITLE CHANGED: ");
mTitleChanges.append(title);
mTitleChanges.append("\n");
}
}
@Override
public boolean onJsAlert(WebView view, String url, String message,
JsResult result) {
if (mDialogStrings == null) {
mDialogStrings = new StringBuffer();
}
mDialogStrings.append("ALERT: ");
mDialogStrings.append(message);
mDialogStrings.append('\n');
result.confirm();
return true;
}
@Override
public boolean onJsConfirm(WebView view, String url, String message,
JsResult result) {
if (mDialogStrings == null) {
mDialogStrings = new StringBuffer();
}
mDialogStrings.append("CONFIRM: ");
mDialogStrings.append(message);
mDialogStrings.append('\n');
result.confirm();
return true;
}
@Override
public boolean onJsPrompt(WebView view, String url, String message,
String defaultValue, JsPromptResult result) {
if (mDialogStrings == null) {
mDialogStrings = new StringBuffer();
}
mDialogStrings.append("PROMPT: ");
mDialogStrings.append(message);
mDialogStrings.append(", default text: ");
mDialogStrings.append(defaultValue);
mDialogStrings.append('\n');
result.confirm();
return true;
}
@Override
public boolean onJsTimeout() {
Log.v(LOGTAG, "JavaScript timeout");
return false;
}
@Override
public void onExceededDatabaseQuota(String url_str,
String databaseIdentifier, long currentQuota,
long estimatedSize, long totalUsedQuota,
WebStorage.QuotaUpdater callback) {
if (mDumpDatabaseCallbacks) {
if (mDatabaseCallbackStrings == null) {
mDatabaseCallbackStrings = new StringBuffer();
}
String protocol = "";
String host = "";
int port = 0;
try {
URL url = new URL(url_str);
protocol = url.getProtocol();
host = url.getHost();
if (url.getPort() > -1) {
port = url.getPort();
}
} catch (MalformedURLException e) {}
String databaseCallbackString =
"UI DELEGATE DATABASE CALLBACK: " +
"exceededDatabaseQuotaForSecurityOrigin:{" + protocol +
", " + host + ", " + port + "} database:" +
databaseIdentifier + "\n";
Log.v(LOGTAG, "LOG: "+databaseCallbackString);
mDatabaseCallbackStrings.append(databaseCallbackString);
}
// Give 5MB more quota.
callback.updateQuota(currentQuota + 1024 * 1024 * 5);
}
@Override
public void onGeolocationPermissionsShowPrompt(String origin,
GeolocationPermissions.Callback callback) {
throw new RuntimeException(
"The WebCore mock used by DRT should bypass the usual permissions flow.");
}
@Override
public boolean onConsoleMessage(ConsoleMessage consoleMessage) {
String msg = "CONSOLE MESSAGE: line " + consoleMessage.lineNumber() + ": "
+ consoleMessage.message() + "\n";
if (mConsoleMessages == null) {
mConsoleMessages = new StringBuffer();
}
mConsoleMessages.append(msg);
Log.v(LOGTAG, "LOG: " + msg);
// the rationale here is that if there's an error of either type, and the test was
// waiting for "notifyDone" signal to finish, then there's no point in waiting
// anymore because the JS execution is already terminated at this point and a
// "notifyDone" will never come out so it's just wasting time till timeout kicks in
if ((msg.contains("Uncaught ReferenceError:") || msg.contains("Uncaught TypeError:"))
&& mWaitUntilDone && mStopOnRefError) {
Log.w(LOGTAG, "Terminating test case on uncaught ReferenceError or TypeError.");
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
notifyDone();
}
}, 500);
}
return true;
}
@Override
public boolean onCreateWindow(WebView view, boolean dialog,
boolean userGesture, Message resultMsg) {
if (!mCanOpenWindows) {
// We can't open windows, so just send null back.
WebView.WebViewTransport transport =
(WebView.WebViewTransport) resultMsg.obj;
transport.setWebView(null);
resultMsg.sendToTarget();
return true;
}
// We never display the new window, just create the view and
// allow it's content to execute and be recorded by the test
// runner.
HashMap<String, Object> jsIfaces = new HashMap<String, Object>();
jsIfaces.put("layoutTestController", mCallbackProxy);
jsIfaces.put("eventSender", mCallbackProxy);
WebView newWindowView = new NewWindowWebView(TestShellActivity.this, jsIfaces);
setupWebViewForLayoutTests(newWindowView, mCallbackProxy);
WebView.WebViewTransport transport =
(WebView.WebViewTransport) resultMsg.obj;
transport.setWebView(newWindowView);
resultMsg.sendToTarget();
return true;
}
@Override
public void onCloseWindow(WebView view) {
view.destroy();
}
};
private static class NewWindowWebView extends WebView {
public NewWindowWebView(Context context, Map<String, Object> jsIfaces) {
super(context, null, 0, jsIfaces, false);
}
}
private void resetTestStatus() {
mWaitUntilDone = false;
mDumpDataType = mDefaultDumpDataType;
mDumpTopFrameAsText = false;
mDumpChildFramesAsText = false;
mTimedOut = false;
mDumpTitleChanges = false;
mRequestedWebKitData = false;
mDumpDatabaseCallbacks = false;
mCanOpenWindows = false;
mEventSender.resetMouse();
mEventSender.clearTouchPoints();
mEventSender.clearTouchMetaState();
mPageFinished = false;
mDumpWebKitData = false;
setDefaultWebSettings(mWebView);
CookieManager.getInstance().removeAllCookie();
mWebViewClassic.setUseMockGeolocation();
}
private boolean canMoveToNextTest() {
return (mDumpWebKitData && mPageFinished && !mWaitUntilDone) || mTimedOut;
}
private void setupWebViewForLayoutTests(WebView webview, CallbackProxy callbackProxy) {
if (webview == null) {
return;
}
setDefaultWebSettings(webview);
webview.setWebChromeClient(mChromeClient);
webview.setWebViewClient(mViewClient);
// Setting a touch interval of -1 effectively disables the optimisation in WebView
// that stops repeated touch events flooding WebCore. The Event Sender only sends a
// single event rather than a stream of events (like what would generally happen in
// a real use of touch events in a WebView) and so if the WebView drops the event,
// the test will fail as the test expects one callback for every touch it synthesizes.
WebViewClassic.fromWebView(webview).setTouchInterval(-1);
}
public void setDefaultWebSettings(WebView webview) {
WebSettingsClassic settings = WebViewClassic.fromWebView(webview).getSettings();
settings.setAppCacheEnabled(true);
settings.setAppCachePath(getApplicationContext().getCacheDir().getPath());
settings.setAppCacheMaxSize(Long.MAX_VALUE);
settings.setJavaScriptEnabled(true);
settings.setJavaScriptCanOpenWindowsAutomatically(true);
settings.setSupportMultipleWindows(true);
settings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NORMAL);
settings.setDatabaseEnabled(true);
settings.setDatabasePath(getDir("databases",0).getAbsolutePath());
settings.setDomStorageEnabled(true);
settings.setWorkersEnabled(false);
settings.setXSSAuditorEnabled(false);
settings.setPageCacheCapacity(0);
settings.setProperty("use_minimal_memory", "false");
settings.setAllowUniversalAccessFromFileURLs(true);
settings.setAllowFileAccessFromFileURLs(true);
}
private WebViewClassic mWebViewClassic;
private WebView mWebView;
private WebViewEventSender mEventSender;
private AsyncHandler mHandler;
private TestShellCallback mCallback;
private CallbackProxy mCallbackProxy;
private String mTestUrl;
private String mResultFile;
private int mTimeoutInMillis;
private String mUiAutoTestPath;
private BufferedReader mTestListReader;
private int mTotalTestCount;
private int mCurrentTestNumber;
private boolean mStopOnRefError;
// States
private boolean mTimedOut;
private boolean mRequestedWebKitData;
private boolean mFinishedRunning;
// Layout test controller variables.
private DumpDataType mDumpDataType;
private DumpDataType mDefaultDumpDataType = DumpDataType.EXT_REPR;
private boolean mDumpTopFrameAsText;
private boolean mDumpChildFramesAsText;
private boolean mWaitUntilDone;
private boolean mDumpTitleChanges;
private StringBuffer mTitleChanges;
private StringBuffer mDialogStrings;
private boolean mKeepWebHistory;
private Vector mWebHistory;
private boolean mDumpDatabaseCallbacks;
private StringBuffer mDatabaseCallbackStrings;
private StringBuffer mConsoleMessages;
private boolean mCanOpenWindows;
private boolean mPageFinished = false;
private boolean mDumpWebKitData = false;
static final String TIMEOUT_STR = "**Test timeout";
static final long DUMP_TIMEOUT_MS = 100000; // 100s timeout for dumping webview content
static final int MSG_TIMEOUT = 0;
static final int MSG_WEBKIT_DATA = 1;
static final int MSG_DUMP_TIMEOUT = 2;
static final String LOGTAG="TestShell";
static final String TEST_URL = "TestUrl";
static final String RESULT_FILE = "ResultFile";
static final String TIMEOUT_IN_MILLIS = "TimeoutInMillis";
static final String UI_AUTO_TEST = "UiAutoTest";
static final String GET_DRAW_TIME = "GetDrawTime";
static final String SAVE_IMAGE = "SaveImage";
static final String TOTAL_TEST_COUNT = "TestCount";
static final String CURRENT_TEST_NUMBER = "TestNumber";
static final String STOP_ON_REF_ERROR = "StopOnReferenceError";
static final int DRAW_RUNS = 5;
static final String DRAW_TIME_LOG = Environment.getExternalStorageDirectory() +
"/android/page_draw_time.txt";
}