The first test causes NullPointerException in DumpRenderTree because dumpAsText could return a null string.
428 lines
13 KiB
Java
428 lines
13 KiB
Java
/*
|
|
* 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 java.io.File;
|
|
import java.io.FileOutputStream;
|
|
import java.io.IOException;
|
|
import java.util.Vector;
|
|
|
|
import android.app.Activity;
|
|
import android.content.Intent;
|
|
import android.util.Log;
|
|
import android.webkit.JsPromptResult;
|
|
import android.webkit.JsResult;
|
|
import android.view.ViewGroup;
|
|
import android.webkit.WebChromeClient;
|
|
import android.webkit.WebSettings;
|
|
import android.webkit.WebView;
|
|
import android.widget.LinearLayout;
|
|
import android.os.*;
|
|
|
|
public class TestShellActivity extends Activity implements LayoutTestController {
|
|
public class AsyncHandler extends Handler {
|
|
@Override
|
|
public void handleMessage(Message msg) {
|
|
if (msg.what == MSG_TIMEOUT) {
|
|
mTimedOut = true;
|
|
requestWebKitData();
|
|
return;
|
|
} else if (msg.what == MSG_WEBKIT_DATA) {
|
|
TestShellActivity.this.dump(mTimedOut, (String)msg.obj);
|
|
return;
|
|
}
|
|
|
|
super.handleMessage(msg);
|
|
}
|
|
}
|
|
|
|
public void requestWebKitData() {
|
|
Message callback = mHandler.obtainMessage(MSG_WEBKIT_DATA);
|
|
|
|
if (mRequestedWebKitData)
|
|
throw new AssertionError("Requested webkit data twice: " + mWebView.getUrl());
|
|
|
|
mRequestedWebKitData = true;
|
|
if (mDumpAsText) {
|
|
mWebView.documentAsText(callback);
|
|
} else {
|
|
mWebView.externalRepresentation(callback);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
protected void onCreate(Bundle icicle) {
|
|
super.onCreate(icicle);
|
|
|
|
LinearLayout contentView = new LinearLayout(this);
|
|
contentView.setOrientation(LinearLayout.VERTICAL);
|
|
setContentView(contentView);
|
|
|
|
mWebView = new WebView(this);
|
|
mWebView.getSettings().setJavaScriptEnabled(true);
|
|
mWebView.setWebChromeClient(mChromeClient);
|
|
mEventSender = new WebViewEventSender(mWebView);
|
|
mCallbackProxy = new CallbackProxy(mEventSender, this);
|
|
|
|
mWebView.addJavascriptInterface(mCallbackProxy, "layoutTestController");
|
|
mWebView.addJavascriptInterface(mCallbackProxy, "eventSender");
|
|
contentView.addView(mWebView, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT, 0.0f));
|
|
|
|
mWebView.getSettings().setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NORMAL);
|
|
|
|
mHandler = new AsyncHandler();
|
|
|
|
Intent intent = getIntent();
|
|
if (intent != null) {
|
|
executeIntent(intent);
|
|
}
|
|
}
|
|
|
|
@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;
|
|
}
|
|
|
|
mTestUrl = intent.getStringExtra(TEST_URL);
|
|
if (mTestUrl == null)
|
|
return;
|
|
|
|
mResultFile = intent.getStringExtra(RESULT_FILE);
|
|
mTimeoutInMillis = intent.getIntExtra(TIMEOUT_IN_MILLIS, 0);
|
|
|
|
Log.v(LOGTAG, " Loading " + mTestUrl);
|
|
mWebView.loadUrl(mTestUrl);
|
|
|
|
if (mTimeoutInMillis > 0) {
|
|
// Create a timeout timer
|
|
Message m = mHandler.obtainMessage(MSG_TIMEOUT);
|
|
mHandler.sendMessageDelayed(m, mTimeoutInMillis);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
protected void onStop() {
|
|
super.onStop();
|
|
mWebView.stopLoading();
|
|
}
|
|
|
|
@Override
|
|
protected void onDestroy() {
|
|
super.onDestroy();
|
|
mWebView.destroy();
|
|
mWebView = null;
|
|
}
|
|
|
|
@Override
|
|
public void onLowMemory() {
|
|
super.onLowMemory();
|
|
Log.e(LOGTAG, "Low memory, kill self");
|
|
System.exit(1);
|
|
}
|
|
|
|
// Dump the page
|
|
public void dump(boolean timeout, String webkitData) {
|
|
if (mResultFile == null || mResultFile.length() == 0) {
|
|
finished();
|
|
return;
|
|
}
|
|
|
|
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 (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 void finished() {
|
|
if (mCallback != null) {
|
|
mCallback.finished();
|
|
}
|
|
}
|
|
|
|
// .......................................
|
|
// LayoutTestController Functions
|
|
public void dumpAsText() {
|
|
mDumpAsText = true;
|
|
if (mWebView != null) {
|
|
String url = mWebView.getUrl();
|
|
Log.v(LOGTAG, "dumpAsText called: "+url);
|
|
}
|
|
}
|
|
|
|
public void waitUntilDone() {
|
|
mWaitUntilDone = true;
|
|
String url = mWebView.getUrl();
|
|
Log.v(LOGTAG, "waitUntilDone called: " + url);
|
|
}
|
|
|
|
public void notifyDone() {
|
|
String url = mWebView.getUrl();
|
|
Log.v(LOGTAG, "notifyDone called: " + url);
|
|
if (mWaitUntilDone) {
|
|
mWaitUntilDone = false;
|
|
mChromeClient.onProgressChanged(mWebView, 100);
|
|
}
|
|
}
|
|
|
|
public void display() {
|
|
mWebView.invalidate();
|
|
}
|
|
|
|
public void clearBackForwardList() {
|
|
mWebView.clearHistory();
|
|
|
|
}
|
|
|
|
public void dumpBackForwardList() {
|
|
//printf("\n============== Back Forward List ==============\n");
|
|
// mWebHistory
|
|
//printf("===============================================\n");
|
|
|
|
}
|
|
|
|
public void dumpChildFrameScrollPositions() {
|
|
// TODO Auto-generated method stub
|
|
|
|
}
|
|
|
|
public void dumpEditingCallbacks() {
|
|
// TODO Auto-generated method stub
|
|
|
|
}
|
|
|
|
public void dumpSelectionRect() {
|
|
// TODO Auto-generated method stub
|
|
|
|
}
|
|
|
|
public void dumpTitleChanges() {
|
|
if (!mDumpTitleChanges) {
|
|
mTitleChanges = new StringBuffer();
|
|
}
|
|
mDumpTitleChanges = true;
|
|
}
|
|
|
|
public void keepWebHistory() {
|
|
if (!mKeepWebHistory) {
|
|
mWebHistory = new Vector();
|
|
}
|
|
mKeepWebHistory = true;
|
|
}
|
|
|
|
public void queueBackNavigation(int howfar) {
|
|
// TODO Auto-generated method stub
|
|
|
|
}
|
|
|
|
public void queueForwardNavigation(int howfar) {
|
|
// TODO Auto-generated method stub
|
|
|
|
}
|
|
|
|
public void queueLoad(String Url, String frameTarget) {
|
|
// TODO Auto-generated method stub
|
|
|
|
}
|
|
|
|
public void queueReload() {
|
|
mWebView.reload();
|
|
}
|
|
|
|
public void queueScript(String scriptToRunInCurrentContext) {
|
|
mWebView.loadUrl("javascript:"+scriptToRunInCurrentContext);
|
|
}
|
|
|
|
public void repaintSweepHorizontally() {
|
|
// TODO Auto-generated method stub
|
|
|
|
}
|
|
|
|
public void setAcceptsEditing(boolean b) {
|
|
// TODO Auto-generated method stub
|
|
|
|
}
|
|
|
|
public void setMainFrameIsFirstResponder(boolean b) {
|
|
// TODO Auto-generated method stub
|
|
|
|
}
|
|
|
|
public void setWindowIsKey(boolean b) {
|
|
// This is meant to show/hide the window. The best I can find
|
|
// is setEnabled()
|
|
mWebView.setEnabled(b);
|
|
}
|
|
|
|
public void testRepaint() {
|
|
mWebView.invalidate();
|
|
}
|
|
|
|
private final WebChromeClient mChromeClient = new WebChromeClient() {
|
|
@Override
|
|
public void onProgressChanged(WebView view, int newProgress) {
|
|
if (newProgress == 100) {
|
|
if (!mTimedOut && !mWaitUntilDone && !mRequestedWebKitData) {
|
|
String url = mWebView.getUrl();
|
|
Log.v(LOGTAG, "Finished: "+ url);
|
|
mHandler.removeMessages(MSG_TIMEOUT);
|
|
requestWebKitData();
|
|
} else {
|
|
String url = mWebView.getUrl();
|
|
if (mTimedOut) {
|
|
Log.v(LOGTAG, "Timed out before finishing: " + url);
|
|
} else if (mWaitUntilDone) {
|
|
Log.v(LOGTAG, "Waiting for notifyDone: " + url);
|
|
} else if (mRequestedWebKitData) {
|
|
Log.v(LOGTAG, "Requested webkit data ready: " + url);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void onReceivedTitle(WebView view, String title) {
|
|
if (title.length() > 30)
|
|
title = "..."+title.substring(title.length()-30);
|
|
setTitle(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;
|
|
}
|
|
};
|
|
|
|
private void resetTestStatus() {
|
|
mWaitUntilDone = false;
|
|
mDumpAsText = false;
|
|
mTimedOut = false;
|
|
mDumpTitleChanges = false;
|
|
mRequestedWebKitData = false;
|
|
mEventSender.resetMouse();
|
|
}
|
|
|
|
private WebView mWebView;
|
|
private WebViewEventSender mEventSender;
|
|
private AsyncHandler mHandler;
|
|
private TestShellCallback mCallback;
|
|
|
|
private CallbackProxy mCallbackProxy;
|
|
|
|
private String mTestUrl;
|
|
private String mResultFile;
|
|
private int mTimeoutInMillis;
|
|
|
|
// States
|
|
private boolean mTimedOut;
|
|
private boolean mRequestedWebKitData;
|
|
private boolean mFinishedRunning;
|
|
|
|
// Layout test controller variables.
|
|
private boolean mDumpAsText;
|
|
private boolean mWaitUntilDone;
|
|
private boolean mDumpTitleChanges;
|
|
private StringBuffer mTitleChanges;
|
|
private StringBuffer mDialogStrings;
|
|
private boolean mKeepWebHistory;
|
|
private Vector mWebHistory;
|
|
|
|
static final String TIMEOUT_STR = "**Test timeout";
|
|
|
|
static final int MSG_TIMEOUT = 0;
|
|
static final int MSG_WEBKIT_DATA = 1;
|
|
|
|
static final String LOGTAG="TestShell";
|
|
|
|
static final String TEST_URL = "TestUrl";
|
|
static final String RESULT_FILE = "ResultFile";
|
|
static final String TIMEOUT_IN_MILLIS = "TimeoutInMillis";
|
|
}
|