summaryrefslogtreecommitdiffstats
path: root/tests/DumpRenderTree
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2008-12-17 18:05:43 -0800
committerThe Android Open Source Project <initial-contribution@android.com>2008-12-17 18:05:43 -0800
commitf013e1afd1e68af5e3b868c26a653bbfb39538f8 (patch)
tree7ad6c8fd9c7b55f4b4017171dec1cb760bbd26bf /tests/DumpRenderTree
parente70cfafe580c6f2994c4827cd8a534aabf3eb05c (diff)
downloadframeworks_base-f013e1afd1e68af5e3b868c26a653bbfb39538f8.zip
frameworks_base-f013e1afd1e68af5e3b868c26a653bbfb39538f8.tar.gz
frameworks_base-f013e1afd1e68af5e3b868c26a653bbfb39538f8.tar.bz2
Code drop from //branches/cupcake/...@124589
Diffstat (limited to 'tests/DumpRenderTree')
-rw-r--r--tests/DumpRenderTree/Android.mk12
-rw-r--r--tests/DumpRenderTree/AndroidManifest.xml34
-rw-r--r--tests/DumpRenderTree/src/com/android/dumprendertree/CallbackProxy.java328
-rw-r--r--tests/DumpRenderTree/src/com/android/dumprendertree/EventSender.java29
-rw-r--r--tests/DumpRenderTree/src/com/android/dumprendertree/FileFilter.java242
-rw-r--r--tests/DumpRenderTree/src/com/android/dumprendertree/FileList.java160
-rw-r--r--tests/DumpRenderTree/src/com/android/dumprendertree/HTMLHostActivity.java607
-rw-r--r--tests/DumpRenderTree/src/com/android/dumprendertree/HTMLHostApp.java33
-rw-r--r--tests/DumpRenderTree/src/com/android/dumprendertree/HTMLHostCallbackInterface.java21
-rw-r--r--tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestController.java62
-rwxr-xr-xtests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoRunner.java48
-rw-r--r--tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoTest.java157
-rw-r--r--tests/DumpRenderTree/src/com/android/dumprendertree/Menu.java53
-rw-r--r--tests/DumpRenderTree/src/com/android/dumprendertree/WebViewEventSender.java194
14 files changed, 1980 insertions, 0 deletions
diff --git a/tests/DumpRenderTree/Android.mk b/tests/DumpRenderTree/Android.mk
new file mode 100644
index 0000000..505a436
--- /dev/null
+++ b/tests/DumpRenderTree/Android.mk
@@ -0,0 +1,12 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_JAVA_LIBRARIES := android.test.runner
+
+LOCAL_PACKAGE_NAME := DumpRenderTree
+
+include $(BUILD_PACKAGE)
diff --git a/tests/DumpRenderTree/AndroidManifest.xml b/tests/DumpRenderTree/AndroidManifest.xml
new file mode 100644
index 0000000..8e06cc8
--- /dev/null
+++ b/tests/DumpRenderTree/AndroidManifest.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.dumprendertree">
+ <application android:name="HTMLHostApp">
+ <uses-library android:name="android.test.runner" />
+ <activity android:name="Menu" android:label="1 Dump Render Tree">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.TEST" />
+ </intent-filter>
+ </activity>
+ <activity android:name="HTMLHostActivity">
+ </activity>
+ </application>
+
+ <instrumentation android:name=".LayoutTestsAutoRunner"
+ android:targetPackage="com.android.dumprendertree"
+ android:label="Layout test automation runner"
+ />
+</manifest>
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/CallbackProxy.java b/tests/DumpRenderTree/src/com/android/dumprendertree/CallbackProxy.java
new file mode 100644
index 0000000..a389461
--- /dev/null
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/CallbackProxy.java
@@ -0,0 +1,328 @@
+/*
+ * 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 android.os.Handler;
+import android.os.Message;
+
+import java.util.HashMap;
+
+public class CallbackProxy extends Handler implements EventSender, LayoutTestController {
+
+ private EventSender mEventSender;
+ private LayoutTestController mLayoutTestController;
+
+ private static final int EVENT_DOM_LOG = 1;
+ private static final int EVENT_FIRE_KBD = 2;
+ private static final int EVENT_KEY_DOWN_1 = 3;
+ private static final int EVENT_KEY_DOWN_2 = 4;
+ private static final int EVENT_LEAP = 5;
+ private static final int EVENT_MOUSE_CLICK = 6;
+ private static final int EVENT_MOUSE_DOWN = 7;
+ private static final int EVENT_MOUSE_MOVE = 8;
+ private static final int EVENT_MOUSE_UP = 9;
+
+ private static final int LAYOUT_CLEAR_LIST = 20;
+ private static final int LAYOUT_DISPLAY = 21;
+ private static final int LAYOUT_DUMP_TEXT = 22;
+ private static final int LAYOUT_DUMP_HISTORY = 23;
+ private static final int LAYOUT_DUMP_CHILD_SCROLL = 24;
+ private static final int LAYOUT_DUMP_EDIT_CB = 25;
+ private static final int LAYOUT_DUMP_SEL_RECT = 26;
+ private static final int LAYOUT_DUMP_TITLE_CHANGES = 27;
+ private static final int LAYOUT_KEEP_WEB_HISTORY = 28;
+ private static final int LAYOUT_NOTIFY_DONE = 29;
+ private static final int LAYOUT_QUEUE_BACK_NAV = 30;
+ private static final int LAYOUT_QUEUE_FWD_NAV = 31;
+ private static final int LAYOUT_QUEUE_LOAD = 32;
+ private static final int LAYOUT_QUEUE_RELOAD = 33;
+ private static final int LAYOUT_QUEUE_SCRIPT = 34;
+ private static final int LAYOUT_REPAINT_HORZ = 35;
+ private static final int LAYOUT_SET_ACCEPT_EDIT = 36;
+ private static final int LAYOUT_MAIN_FIRST_RESP = 37;
+ private static final int LAYOUT_SET_WINDOW_KEY = 38;
+ private static final int LAYOUT_TEST_REPAINT = 39;
+ private static final int LAYOUT_WAIT_UNTIL_DONE = 40;
+
+ CallbackProxy(EventSender eventSender,
+ LayoutTestController layoutTestController) {
+ mEventSender = eventSender;
+ mLayoutTestController = layoutTestController;
+ }
+
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case EVENT_DOM_LOG:
+ mEventSender.enableDOMUIEventLogging(msg.arg1);
+ break;
+ case EVENT_FIRE_KBD:
+ mEventSender.fireKeyboardEventsToElement(msg.arg1);
+ break;
+ case EVENT_KEY_DOWN_1:
+ HashMap map = (HashMap) msg.obj;
+ mEventSender.keyDown((String) map.get("character"),
+ (String[]) map.get("withModifiers"));
+ break;
+
+ case EVENT_KEY_DOWN_2:
+ mEventSender.keyDown((String)msg.obj);
+ break;
+
+ case EVENT_LEAP:
+ mEventSender.leapForward(msg.arg1);
+ break;
+
+ case EVENT_MOUSE_CLICK:
+ mEventSender.mouseClick();
+ break;
+
+ case EVENT_MOUSE_DOWN:
+ mEventSender.mouseDown();
+ break;
+
+ case EVENT_MOUSE_MOVE:
+ mEventSender.mouseMoveTo(msg.arg1, msg.arg2);
+ break;
+
+ case EVENT_MOUSE_UP:
+ mEventSender.mouseUp();
+ break;
+
+ case LAYOUT_CLEAR_LIST:
+ mLayoutTestController.clearBackForwardList();
+ break;
+
+ case LAYOUT_DISPLAY:
+ mLayoutTestController.display();
+ break;
+
+ case LAYOUT_DUMP_TEXT:
+ mLayoutTestController.dumpAsText();
+ break;
+
+ case LAYOUT_DUMP_HISTORY:
+ mLayoutTestController.dumpBackForwardList();
+ break;
+
+ case LAYOUT_DUMP_CHILD_SCROLL:
+ mLayoutTestController.dumpChildFrameScrollPositions();
+ break;
+
+ case LAYOUT_DUMP_EDIT_CB:
+ mLayoutTestController.dumpEditingCallbacks();
+ break;
+
+ case LAYOUT_DUMP_SEL_RECT:
+ mLayoutTestController.dumpSelectionRect();
+ break;
+
+ case LAYOUT_DUMP_TITLE_CHANGES:
+ mLayoutTestController.dumpTitleChanges();
+ break;
+
+ case LAYOUT_KEEP_WEB_HISTORY:
+ mLayoutTestController.keepWebHistory();
+ break;
+
+ case LAYOUT_NOTIFY_DONE:
+ mLayoutTestController.notifyDone();
+ break;
+
+ case LAYOUT_QUEUE_BACK_NAV:
+ mLayoutTestController.queueBackNavigation(msg.arg1);
+ break;
+
+ case LAYOUT_QUEUE_FWD_NAV:
+ mLayoutTestController.queueForwardNavigation(msg.arg1);
+ break;
+
+ case LAYOUT_QUEUE_LOAD:
+ HashMap<String, String> loadMap =
+ (HashMap<String, String>) msg.obj;
+ mLayoutTestController.queueLoad(loadMap.get("Url"),
+ loadMap.get("frameTarget"));
+ break;
+
+ case LAYOUT_QUEUE_RELOAD:
+ mLayoutTestController.queueReload();
+ break;
+
+ case LAYOUT_QUEUE_SCRIPT:
+ mLayoutTestController.queueScript((String)msg.obj);
+ break;
+
+ case LAYOUT_REPAINT_HORZ:
+ mLayoutTestController.repaintSweepHorizontally();
+ break;
+
+ case LAYOUT_SET_ACCEPT_EDIT:
+ mLayoutTestController.setAcceptsEditing(
+ msg.arg1 == 1 ? true : false);
+ break;
+ case LAYOUT_MAIN_FIRST_RESP:
+ mLayoutTestController.setMainFrameIsFirstResponder(
+ msg.arg1 == 1 ? true : false);
+ break;
+
+ case LAYOUT_SET_WINDOW_KEY:
+ mLayoutTestController.setWindowIsKey(
+ msg.arg1 == 1 ? true : false);
+ break;
+
+ case LAYOUT_TEST_REPAINT:
+ mLayoutTestController.testRepaint();
+ break;
+
+ case LAYOUT_WAIT_UNTIL_DONE:
+ mLayoutTestController.waitUntilDone();
+ break;
+ }
+ }
+
+ // EventSender Methods
+
+ public void enableDOMUIEventLogging(int DOMNode) {
+ obtainMessage(EVENT_DOM_LOG, DOMNode, 0).sendToTarget();
+ }
+
+ public void fireKeyboardEventsToElement(int DOMNode) {
+ obtainMessage(EVENT_FIRE_KBD, DOMNode, 0).sendToTarget();
+ }
+
+ public void keyDown(String character, String[] withModifiers) {
+ // TODO Auto-generated method stub
+ HashMap map = new HashMap();
+ map.put("character", character);
+ map.put("withModifiers", withModifiers);
+ obtainMessage(EVENT_KEY_DOWN_1, map).sendToTarget();
+ }
+
+ public void keyDown(String character) {
+ obtainMessage(EVENT_KEY_DOWN_2, character).sendToTarget();
+ }
+
+ public void leapForward(int milliseconds) {
+ obtainMessage(EVENT_LEAP, milliseconds, 0).sendToTarget();
+ }
+
+ public void mouseClick() {
+ obtainMessage(EVENT_MOUSE_CLICK).sendToTarget();
+ }
+
+ public void mouseDown() {
+ obtainMessage(EVENT_MOUSE_DOWN).sendToTarget();
+ }
+
+ public void mouseMoveTo(int X, int Y) {
+ obtainMessage(EVENT_MOUSE_MOVE, X, Y).sendToTarget();
+ }
+
+ public void mouseUp() {
+ obtainMessage(EVENT_MOUSE_UP).sendToTarget();
+ }
+
+ // LayoutTestController Methods
+
+ public void clearBackForwardList() {
+ obtainMessage(LAYOUT_CLEAR_LIST).sendToTarget();
+ }
+
+ public void display() {
+ obtainMessage(LAYOUT_DISPLAY).sendToTarget();
+ }
+
+ public void dumpAsText() {
+ obtainMessage(LAYOUT_DUMP_TEXT).sendToTarget();
+ }
+
+ public void dumpBackForwardList() {
+ obtainMessage(LAYOUT_DUMP_HISTORY).sendToTarget();
+ }
+
+ public void dumpChildFrameScrollPositions() {
+ obtainMessage(LAYOUT_DUMP_CHILD_SCROLL).sendToTarget();
+ }
+
+ public void dumpEditingCallbacks() {
+ obtainMessage(LAYOUT_DUMP_EDIT_CB).sendToTarget();
+ }
+
+ public void dumpSelectionRect() {
+ obtainMessage(LAYOUT_DUMP_SEL_RECT).sendToTarget();
+ }
+
+ public void dumpTitleChanges() {
+ obtainMessage(LAYOUT_DUMP_TITLE_CHANGES).sendToTarget();
+ }
+
+ public void keepWebHistory() {
+ obtainMessage(LAYOUT_KEEP_WEB_HISTORY).sendToTarget();
+ }
+
+ public void notifyDone() {
+ obtainMessage(LAYOUT_NOTIFY_DONE).sendToTarget();
+ }
+
+ public void queueBackNavigation(int howfar) {
+ obtainMessage(LAYOUT_QUEUE_BACK_NAV, howfar, 0).sendToTarget();
+ }
+
+ public void queueForwardNavigation(int howfar) {
+ obtainMessage(LAYOUT_QUEUE_FWD_NAV, howfar, 0).sendToTarget();
+ }
+
+ public void queueLoad(String Url, String frameTarget) {
+ HashMap <String, String>map = new HashMap<String, String>();
+ map.put("Url", Url);
+ map.put("frameTarget", frameTarget);
+ obtainMessage(LAYOUT_QUEUE_LOAD, map).sendToTarget();
+ }
+
+ public void queueReload() {
+ obtainMessage(LAYOUT_QUEUE_RELOAD).sendToTarget();
+ }
+
+ public void queueScript(String scriptToRunInCurrentContext) {
+ obtainMessage(LAYOUT_QUEUE_SCRIPT,
+ scriptToRunInCurrentContext).sendToTarget();
+ }
+
+ public void repaintSweepHorizontally() {
+ obtainMessage(LAYOUT_REPAINT_HORZ).sendToTarget();
+ }
+
+ public void setAcceptsEditing(boolean b) {
+ obtainMessage(LAYOUT_SET_ACCEPT_EDIT, b ? 1 : 0, 0).sendToTarget();
+ }
+
+ public void setMainFrameIsFirstResponder(boolean b) {
+ obtainMessage(LAYOUT_MAIN_FIRST_RESP, b ? 1 : 0, 0).sendToTarget();
+ }
+
+ public void setWindowIsKey(boolean b) {
+ obtainMessage(LAYOUT_SET_WINDOW_KEY,b ? 1 : 0, 0).sendToTarget();
+ }
+
+ public void testRepaint() {
+ obtainMessage(LAYOUT_TEST_REPAINT).sendToTarget();
+ }
+
+ public void waitUntilDone() {
+ obtainMessage(LAYOUT_WAIT_UNTIL_DONE).sendToTarget();
+ }
+
+}
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/EventSender.java b/tests/DumpRenderTree/src/com/android/dumprendertree/EventSender.java
new file mode 100644
index 0000000..82fd8d8
--- /dev/null
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/EventSender.java
@@ -0,0 +1,29 @@
+/*
+ * 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;
+
+public interface EventSender {
+ public void mouseDown();
+ public void mouseUp();
+ public void mouseClick();
+ public void mouseMoveTo(int X, int Y);
+ public void leapForward(int milliseconds);
+ public void keyDown (String character, String[] withModifiers);
+ public void keyDown (String character);
+ public void enableDOMUIEventLogging(int DOMNode);
+ public void fireKeyboardEventsToElement(int DOMNode);
+}
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/FileFilter.java b/tests/DumpRenderTree/src/com/android/dumprendertree/FileFilter.java
new file mode 100644
index 0000000..5a73759
--- /dev/null
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/FileFilter.java
@@ -0,0 +1,242 @@
+/*
+ * 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.util.HashSet;
+import java.util.Hashtable;
+import android.util.*;
+
+public class FileFilter {
+
+ public static boolean ignoreTest(String file) {
+ // treat files like directories for the time being.
+ int size = ignoreTestList.length;
+ for (int i = 0; i < size; i ++) {
+ if (file.startsWith(ignoreTestList[i])) {
+ Log.e("FileFilter", "File path in IgnoreTest: " + file);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static boolean ignoreResults(String file) {
+ int index = file.indexOf("fast");
+ if (index != -1) {
+ String sub = file.substring(index);
+ if (ignoreResultList.contains(sub))
+ return true;
+ }
+ return false;
+
+ }
+
+ public static String isKnownBug(String file) {
+ int index = file.indexOf("fast");
+ if (index != -1) {
+ String sub = file.substring(index);
+ // Log.e("FileFilter", "Looking for:"+sub);
+ if (bugList.containsKey(sub))
+ return bugList.get(sub);
+ }
+ return null;
+ }
+
+ final static HashSet<String> ignoreResultList = new HashSet<String>();
+ final static Hashtable<String, String> bugList =
+ new Hashtable<String, String>();
+
+ static {
+ fillIgnoreResultSet();
+ fillBugTable();
+ }
+
+ static final String [] ignoreTestList = {
+ ".", // ignore hidden directories and files
+ "resources", // ignore resource directories
+ "AppleScript", // AppleScript not supported
+ "xpath", // xpath requires libxml2, not supported
+ "xsl", //xsl requires libxml2 & libxslt, not sup.
+ "kde", // don't run kde tests.
+ ".svn", // don't run anything under .svn folder
+ "gradients", //known crash
+ "toString-stack-overflow.html", // Crashes #606688
+ "frame-limit.html", // generates too many GREFs
+ "css-insert-import-rule.html", // Crashes, #717414
+ "input-text-enter.html", // Crashes. #735088
+ "text-shadow-extreme-value.html", // Crashes #571671
+ "001.html",
+ "reflection-masks.html",
+ "frame-creation-removal.html",
+ "large-expressions.html",
+ "null-page-show-modal-dialog-crash.html",
+ "font-face-implicit-local-font.html",
+ "font-face-locally-installed.html",
+ "beforeSelectorOnCodeElement.html",
+ "cssTarget-crash.html"
+ };
+
+ static void fillIgnoreResultSet() {
+ // need test plugin
+ ignoreResultList.add("fast/dom/Window/Plug-ins.html");
+ // pixel depth
+ ignoreResultList.add("fast/dom/Window/window-screen-properties.html");
+ // missing space in textrun, ok as text is wrapped. ignore. #714933
+ ignoreResultList.add("fast/events/onload-webkit-before-webcore.html");
+ // missing support for textInputController.makeAttributedString()
+ ignoreResultList.add("fast/forms/attributed-strings.html");
+ // charset convert. #516936 ignore, won't fix
+ ignoreResultList.add("fast/forms/form-data-encoding-2.html");
+ // charset convert. #516936 ignore, won't fix
+ ignoreResultList.add("fast/forms/form-data-encoding.html");
+ // execCommand "insertText" not supported
+ ignoreResultList.add("fast/forms/input-appearance-maxlength.html");
+ // Copy&Paste commands not supported
+ ignoreResultList.add("fast/forms/input-truncate-newline.html");
+ ignoreResultList.add("fast/forms/textarea-paste-newline.html");
+ // requires eventSender.mouseMoveTo, mouseDown & mouseUp and
+ // abs. position of mouse to select a word. ignore, won't fix #716583
+ ignoreResultList.add("fast/forms/onselect-textarea.html");
+ // requires eventSender.mouseMoveTo, mouseDown & mouseUp and
+ // abs. position of mouse to select a word. ignore, won't fix #716583
+ ignoreResultList.add("fast/forms/onselect-textfield.html");
+ // not implemented queryCommandEnabled:BackColor, Undo & Redo
+ ignoreResultList.add("fast/forms/plaintext-mode-1.html");
+ // Our text areas are a little thinner than Apples. Also RTL test failes
+ ignoreResultList.add("fast/forms/textarea-appearance-wrap.html");
+ // Our text areas are a little thinner than Apples
+ ignoreResultList.add("fast/forms/textarea-hard-linewrap.html");
+ // screen width&height are different
+ ignoreResultList.add("fast/frames/frameElement-widthheight.html");
+ ignoreResultList.add("fast/frames/frame-js-url-clientWidth.html");
+ // requires JS test API, textInputController
+ ignoreResultList.add("fast/text/attributed-substring-from-range.html");
+ ignoreResultList.add("fast/text/attributed-substring-from-range-001.html");
+ // will not fix #619707
+ ignoreResultList.add("fast/css/case-transform.html");
+ // different platform defaults for font and different screen size
+ ignoreResultList.add("fast/css/computed-style.html");
+ // different screen size result in extra spaces in Apple compared to us
+ ignoreResultList.add("fast/dom/Element/offsetLeft-offsetTop-body-quirk.html");
+ // xslt and xpath elements missing from property list
+ ignoreResultList.add("fast/dom/Window/window-properties.html");
+ // requires textInputController.characterIndexForPoint
+ ignoreResultList.add("fast/dom/character-index-for-point.html");
+ // requires xpath support
+ ignoreResultList.add("fast/dom/gc-9.html");
+ // requires xslt and xpath support
+ ignoreResultList.add("fast/dom/global-constructors.html");
+ // dynamic plugins not supported
+ ignoreResultList.add("fast/dom/object-embed-plugin-scripting.html");
+ ignoreResultList.add("fast/js/navigator-mimeTypes-length.html");
+ // there is extra spacing in the file due to multiple input boxes
+ // fitting on one line on Apple, ours are wrapped. Space at line ends
+ // are stripped.
+ ignoreResultList.add("fast/dom/tabindex-clamp.html");
+
+ // requires eventSender.mouseDown(),mouseUp()
+ ignoreResultList.add("fast/dom/Window/window-xy-properties.html");
+ ignoreResultList.add("fast/events/window-events-bubble.html");
+ ignoreResultList.add("fast/events/window-events-bubble2.html");
+ ignoreResultList.add("fast/events/window-events-capture.html");
+ ignoreResultList.add("fast/forms/select-empty-list.html");
+ ignoreResultList.add("fast/replaced/image-map.html");
+ ignoreResultList.add("fast/events/capture-on-target.html");
+ ignoreResultList.add("fast/events/dblclick-addEventListener.html");
+ ignoreResultList.add("fast/events/drag-in-frames.html");
+ ignoreResultList.add("fast/events/drag-outside-window.html");
+ ignoreResultList.add("fast/events/event-sender-mouse-click.html");
+ ignoreResultList.add("fast/events/event-view-toString.html");
+ ignoreResultList.add("fast/events/frame-click-focus.html");
+ ignoreResultList.add("fast/events/input-image-scrolled-x-y.html");
+ ignoreResultList.add("fast/events/anchor-image-scrolled-x-y.html");
+ ignoreResultList.add("fast/events/mouseclick-target-and-positioning.html");
+ ignoreResultList.add("fast/events/mouseover-mouseout.html");
+ ignoreResultList.add("fast/events/mouseover-mouseout2.html");
+ ignoreResultList.add("fast/events/mouseup-outside-button.html");
+ ignoreResultList.add("fast/events/mouseup-outside-document.html");
+ ignoreResultList.add("fast/events/onclick-list-marker.html");
+ ignoreResultList.add("fast/events/ondragenter.html");
+ ignoreResultList.add("fast/forms/drag-into-textarea.html");
+ ignoreResultList.add("fast/forms/input-select-on-click.html");
+ ignoreResultList.add("fast/forms/listbox-onchange.html");
+ ignoreResultList.add("fast/forms/search-cancel-button-mouseup.html");
+ ignoreResultList.add("fast/forms/textarea-scrolled-endline-caret.html");
+
+ // there is extra spacing in the file due to multiple frame boxes
+ // fitting on one line on Apple, ours are wrapped. Space at line ends
+ // are stripped.
+ ignoreResultList.add("fast/events/iframe-object-onload.html");
+ // eventSender.mouseDown(), mouseUp() and objc API missing
+ ignoreResultList.add("fast/events/mouseup-outside-document.html");
+ ignoreResultList.add("fast/events/objc-keyboard-event-creation.html");
+ ignoreResultList.add("fast/events/objc-event-api.html");
+ // not capturing the console messages
+ ignoreResultList.add("fast/forms/selected-index-assert.html");
+ ignoreResultList.add("fast/parser/script-tag-with-trailing-slash.html");
+ // there is extra spacing as the text areas and input boxes fit next
+ // to each other on Apple, but are wrapped on our screen.
+ ignoreResultList.add("fast/forms/selection-functions.html");
+ // Text selection done differently on our platform. When a inputbox
+ // gets focus, the entire block is selected.
+ ignoreResultList.add("fast/forms/textarea-initial-caret-position.html");
+ ignoreResultList.add("fast/forms/textarea-no-scroll-on-blur.html");
+ // Requires LayoutTests to exist at /tmp/LayoutTests
+ ignoreResultList.add("fast/loader/local-JavaScript-from-local.html");
+ ignoreResultList.add("fast/loader/local-iFrame-source-from-local.html");
+ // extra spacing because iFrames rendered next to each other on Apple
+ ignoreResultList.add("fast/loader/opaque-base-url.html");
+ ignoreResultList.add("fast/text/plain-text-line-breaks.html");
+
+
+ }
+
+ static void fillBugTable() {
+ bugList.put("fast/forms/check-box-enter-key.html", "716715");
+ bugList.put("fast/forms/focus-control-to-page.html", "716638");
+ bugList.put("fast/html/tab-order.html", "719289");
+ bugList.put("fast/dom/attribute-namespaces-get-set.html", "733229");
+ bugList.put("fast/dom/location-hash.html", "733822");
+ bugList.put("fast/dom/set-innerHTML.html", "733823");
+ bugList.put("fast/dom/xmlhttprequest-get.html", "733846");
+ bugList.put("fast/encoding/css-charset-default.html", "733856");
+ bugList.put("fast/encoding/default-xhtml-encoding.html", "733882");
+ bugList.put("fast/encoding/meta-in-xhtml.html", "733882");
+ bugList.put("fast/events/frame-tab-focus.html", "734308");
+ bugList.put("fast/events/keydown-keypress-focus-change.html", "653224");
+ bugList.put("fast/events/keypress-focus-change.html", "653224");
+ bugList.put("fast/events/option-tab.html", "734308");
+ bugList.put("fast/forms/focus2.html", "735111");
+ bugList.put("fast/forms/listbox-selection.html", "735116");
+ bugList.put("fast/forms/search-event-delay.html", "735120");
+ bugList.put("fast/frames/iframe-window-focus.html", "735140");
+ bugList.put("fast/innerHTML/004.html", "733882");
+ bugList.put("fast/js/date-DST-time-cusps.html", "735144");
+ bugList.put("fast/js/string-capitalization.html", "516936");
+ bugList.put("fast/js/string-concatenate-outofmemory.html","735152");
+ bugList.put("fast/parser/external-entities.html", "735176");
+ bugList.put("fast/events/div-focus.html", "735185");
+ bugList.put("fast/overflow/scroll-vertical-not-horizontal.html", "735196");
+ bugList.put("fast/events/arrow-navigation.html", "735233");
+ bugList.put("fast/forms/select-type-ahead-non-latin.html", "735244");
+ bugList.put("fast/events/js-keyboard-event-creation.html", "735255");
+
+ }
+
+
+
+}
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/FileList.java b/tests/DumpRenderTree/src/com/android/dumprendertree/FileList.java
new file mode 100644
index 0000000..8b33d16
--- /dev/null
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/FileList.java
@@ -0,0 +1,160 @@
+/*
+ * 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.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.io.File;
+
+import android.app.ListActivity;
+import android.view.KeyEvent;
+import android.view.View;
+import android.widget.ListView;
+import android.widget.SimpleAdapter;
+import android.os.Bundle;
+
+
+public abstract class FileList extends ListActivity
+{
+ public boolean onKeyDown(int keyCode, KeyEvent event) {
+ switch (keyCode)
+ {
+ case KeyEvent.KEYCODE_DPAD_LEFT:
+ if (mPath.length() > mBaseLength) {
+ File f = new File(mPath);
+ mFocusFile = f.getName();
+ mFocusIndex = 0;
+ f = f.getParentFile();
+ mPath = f.getPath();
+ updateList();
+ return true;
+ }
+ break;
+
+ case KeyEvent.KEYCODE_DPAD_RIGHT:
+ {
+ Map map = (Map) getListView().getItemAtPosition(getListView().getSelectedItemPosition());
+ String path = (String)map.get("path");
+ if ((new File(path)).isDirectory()) {
+ mPath = path;
+ mFocusFile = null;
+ updateList();
+ } else {
+ processFile(path, false);
+ }
+ return true;
+ }
+
+ default:
+ break;
+ }
+ return super.onKeyDown(keyCode, event);
+ }
+
+ public void onCreate(Bundle icicle)
+ {
+ super.onCreate(icicle);
+ setupPath();
+ updateList();
+ }
+
+ protected List getData()
+ {
+ List myData = new ArrayList<HashMap>();
+
+ File f = new File(mPath);
+ if (!f.exists()) {
+ addItem(myData, "!LayoutTests path missing!", "");
+ return myData;
+ }
+ String[] files = f.list();
+
+ for (int i = 0; i < files.length; i++) {
+ StringBuilder sb = new StringBuilder(mPath);
+ sb.append(File.separatorChar);
+ sb.append(files[i]);
+ String path = sb.toString();
+ File c = new File(path);
+ if (fileFilter(c)) {
+ if (c.isDirectory()) {
+ addItem(myData, "<"+files[i]+">", path);
+ if (mFocusFile != null && mFocusFile.equals(files[i]))
+ mFocusIndex = myData.size()-1;
+ }
+ else
+ addItem(myData, files[i], path);
+ }
+ }
+
+ return myData;
+ }
+
+ protected void addItem(List<Map> data, String name, String path)
+ {
+ HashMap temp = new HashMap();
+ temp.put("title", name);
+ temp.put("path", path);
+ data.add(temp);
+ }
+
+ protected void onListItemClick(ListView l, View v, int position, long id)
+ {
+ Map map = (Map) l.getItemAtPosition(position);
+ String path = (String)map.get("path");
+ if (path.length() > 0)
+ processFile(path, true);
+
+ }
+
+ /*
+ * This function is called when the user has selected a file in the
+ * file list. The selected file could be a file or a directory.
+ * The flag indicates if this was from a selection or not.
+ */
+ abstract void processFile(String filename, boolean selection);
+
+ /*
+ * This function is called when the file list is being built. Return
+ * true if the file is to be added to the file list.
+ */
+ abstract boolean fileFilter(File f);
+
+ protected void updateList() {
+ setListAdapter(new SimpleAdapter(this,
+ getData(),
+ android.R.layout.simple_list_item_1,
+ new String[] {"title"},
+ new int[] {android.R.id.text1}));
+ String title = mPath; //.substring(mBaseLength-11); // show the word LayoutTests
+ setTitle(title);
+ getListView().setSelection(mFocusIndex);
+ }
+
+ protected void setupPath()
+ {
+ mPath = "/sdcard";
+ mBaseLength = mPath.length();
+ }
+
+ protected String mPath;
+ protected int mBaseLength;
+ protected String mFocusFile;
+ protected int mFocusIndex;
+
+}
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/HTMLHostActivity.java b/tests/DumpRenderTree/src/com/android/dumprendertree/HTMLHostActivity.java
new file mode 100644
index 0000000..9521f80
--- /dev/null
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/HTMLHostActivity.java
@@ -0,0 +1,607 @@
+/*
+ * 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.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.BufferedOutputStream;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.Vector;
+import java.util.Stack;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.KeyEvent;
+import android.view.ViewGroup;
+import android.webkit.JsPromptResult;
+import android.webkit.JsResult;
+import android.webkit.WebChromeClient;
+import android.webkit.WebSettings;
+import android.webkit.WebView;
+import android.widget.LinearLayout;
+import android.os.*;
+import android.test.TestRecorder;
+
+// SQLite3 in android has a bunch of bugs which
+// is causing TestRecorder to not record the results
+// properly. This class is a wrapper around it and records
+// results in a file as well.
+class TestRecorderV2 extends TestRecorder {
+ @Override
+ public void passed(String layout_file) {
+ try {
+ mBufferedOutputPassedStream.write(layout_file.getBytes());
+ mBufferedOutputPassedStream.write('\n');
+ mBufferedOutputPassedStream.flush();
+ } catch(Exception e) {
+ e.printStackTrace();
+ }
+ super.passed(layout_file);
+ }
+
+ @Override
+ public void failed(String layout_file, String reason) {
+ try {
+ mBufferedOutputFailedStream.write(layout_file.getBytes());
+ mBufferedOutputFailedStream.write('\n');
+ mBufferedOutputFailedStream.flush();
+ } catch(Exception e) {
+ e.printStackTrace();
+ }
+ super.failed(layout_file, reason);
+ }
+
+ public TestRecorderV2() {
+ super();
+ try {
+ File resultsPassedFile = new File("/sdcard/layout_test_presults.txt");
+ File resultsFailedFile = new File("/sdcard/layout_test_fresults.txt");
+
+ mBufferedOutputPassedStream =
+ new BufferedOutputStream(new FileOutputStream(resultsPassedFile, true));
+ mBufferedOutputFailedStream =
+ new BufferedOutputStream(new FileOutputStream(resultsFailedFile, true));
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ protected void finalize() throws Throwable {
+ mBufferedOutputPassedStream.flush();
+ mBufferedOutputFailedStream.flush();
+ mBufferedOutputPassedStream.close();
+ mBufferedOutputFailedStream.close();
+ }
+
+ private static BufferedOutputStream mBufferedOutputPassedStream;
+ private static BufferedOutputStream mBufferedOutputFailedStream;
+}
+
+public class HTMLHostActivity extends Activity
+ implements LayoutTestController {
+
+ private TestRecorderV2 mResultRecorder = new TestRecorderV2();
+ private HTMLHostCallbackInterface mCallback = null;
+ private CallbackProxy mCallbackProxy;
+
+ public class FileEntry {
+ public FileEntry(String path, int index) {
+ mPath = path; mIndex=index;
+ }
+ String mPath;
+ int mIndex;
+ }
+
+ public class AsyncHandler extends Handler {
+ @Override
+ public void handleMessage(Message msg) {
+ if (msg.what == MSG_DUMP) {
+ this.removeMessages(MSG_TIMEOUT);
+ mTimedOut = false;
+ requestWebKitData();
+ return;
+ } else if (msg.what == MSG_TIMEOUT) {
+ mTimedOut = true;
+ requestWebKitData();
+ return;
+ } else if (msg.what == MSG_WEBKIT_DATA) {
+ HTMLHostActivity.this.dump(mTimedOut, (String)msg.obj);
+ return;
+ }
+
+ super.handleMessage(msg);
+ }
+
+ void requestWebKitData() {
+ Message callback = obtainMessage(MSG_WEBKIT_DATA);
+ if (dumpAsText) {
+ mWebView.documentAsText(callback);
+ } else {
+ mWebView.externalRepresentation(callback);
+ }
+ }
+
+ }
+
+ // Activity methods
+ public 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);
+ eventSender = new WebViewEventSender(mWebView);
+ mCallbackProxy = new CallbackProxy(eventSender, 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));
+
+ mHandler = new AsyncHandler();
+ }
+
+ @Override
+ protected void onRestoreInstanceState(Bundle savedInstanceState) {
+ super.onRestoreInstanceState(savedInstanceState);
+ }
+
+ protected void onResume() {
+ super.onResume();
+ if (mProcessStack == null || mProcessStack.isEmpty() ) {
+ mOutstandingLoads = 0;
+ dumpAsText = false;
+ pageComplete = false;
+
+ mWebView.getSettings().setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NORMAL);
+
+ mFinishedStack = new Stack();
+
+ Intent intent = getIntent();
+ if (intent.getData() != null) {
+ File f = new File(intent.getData().toString());
+
+ if (f.isDirectory()) {
+ mProcessStack = new Vector();
+ mProcessStack.add(new FileEntry(intent.getData().toString(), 0));
+ Log.v(LOGTAG, "Initial dir: "+intent.getData().toString());
+ loadNextPage();
+ } else {
+ mCurrentFile = intent.getData().toString();
+ mWebView.loadUrl("file://"+intent.getData().toString());
+ }
+
+ }
+ else
+ mWebView.loadUrl("about:");
+ }
+ }
+
+ protected void onStop() {
+ super.onStop();
+ mWebView.stopLoading();
+ }
+
+ protected void onDestroy() {
+ super.onDestroy();
+ mWebView.destroy();
+ mWebView = null;
+ }
+
+ public boolean dispatchKeyEvent(KeyEvent event) {
+ // Log key strokes as they don't seem to be matched
+ //Log.e(LOGTAG, "Event: "+event);
+ return super.dispatchKeyEvent(event);
+ }
+
+ // Functions
+
+ protected void loadNextPage() {
+ dumpAsText = false;
+ pageComplete = false;
+ dumpTitleChanges = false;
+ eventSender.resetMouse();
+ while (!mProcessStack.isEmpty()) {
+ FileEntry fe = (FileEntry)mProcessStack.remove(0);
+ if (fe.mIndex == 0) {
+ System.out.println();
+ System.out.print(fe.mPath);
+ }
+ Log.v(LOGTAG, "Processing dir: "+fe.mPath+" size: "+mProcessStack.size());
+ File f = new File(fe.mPath);
+ String [] files = f.list();
+ for (int i = fe.mIndex; i < files.length; i++) {
+ if (FileFilter.ignoreTest(files[i])) {
+ continue;
+ }
+ File c = new File(f.getPath(), files[i]);
+ if (c.isDirectory()) {
+ Log.v(LOGTAG, "Adding dir: "+fe.mPath+"/"+files[i]);
+ mProcessStack.add(new FileEntry(fe.mPath+"/"+files[i], 0));
+ } else if (files[i].toLowerCase().endsWith("ml")) {
+ mProcessStack.add(0, new FileEntry(fe.mPath, i+1));
+ mCurrentFile = fe.mPath+"/"+files[i];
+ Log.e(LOGTAG, "Processing: "+mCurrentFile);
+ mWebView.loadUrl("file://"+mCurrentFile);
+
+ // Create a timeout timer
+ Message m = mHandler.obtainMessage(MSG_TIMEOUT);
+ // Some tests can take up to 5secs to run.
+ mHandler.sendMessageDelayed(m, 6000);
+ return;
+ }
+ }
+ Log.v(LOGTAG, "Finished dir: "+fe.mPath+" size: "+mProcessStack.size());
+ }
+ // If we got to here, then we must have finished completely
+ finished();
+ }
+
+ public void scheduleDump() {
+ // Only schedule if we really are ready
+ if (waitToDump || mOutstandingLoads > 0 || mDumpRequested) {
+ return;
+ }
+ mDumpRequested = true;
+ mHandler.obtainMessage(MSG_DUMP).sendToTarget();
+ }
+
+ // Dump the page
+ public void dump(boolean timeout, String webkitData) {
+ mDumpRequested = false;
+ System.out.print('.');
+
+ // remove the extension
+ String resultFile = mCurrentFile.substring(0, mCurrentFile.lastIndexOf('.'));
+
+ // store the finished file on the stack so that we can do a diff at the end.
+ mFinishedStack.push(resultFile);
+
+ // dumpAsText version can be directly compared to expected results
+ if (dumpAsText) {
+ resultFile += "-results.txt";
+ } else {
+ resultFile += "-android-results.txt";
+ }
+ try {
+ FileOutputStream os = new FileOutputStream(resultFile);
+ if (timeout) {
+ Log.i("Layout test: Timeout", resultFile);
+ os.write("**Test timeout\n".getBytes());
+ }
+ if (dumpTitleChanges)
+ os.write(mTitleChanges.toString().getBytes());
+ if (mDialogStrings != null)
+ os.write(mDialogStrings.toString().getBytes());
+ mDialogStrings = null;
+ os.write(webkitData.getBytes());
+ os.flush();
+ os.close();
+ } catch (FileNotFoundException ex) {
+ ex.printStackTrace();
+ } catch (IOException ex) {
+ ex.printStackTrace();
+ }
+
+ if (mProcessStack != null)
+ loadNextPage();
+ else
+ finished();
+ }
+
+ // Wrap up
+ public void failedCase(String file, String reason) {
+ Log.i("Layout test:", file + " failed" + reason);
+ mResultRecorder.failed(file, reason);
+
+ file = file + ".html";
+ String bugNumber = FileFilter.isKnownBug(file);
+ if (bugNumber != null) {
+ System.out.println("FAIL known:"+bugNumber+ " "+file+reason);
+ return;
+ }
+ if (FileFilter.ignoreResults(file)) {
+ return;
+ }
+ System.out.println("FAIL: "+file+reason);
+ }
+
+ public void passedCase(String file) {
+ // Add the result to the sqlite database
+ Log.i("Layout test:", file + " passed");
+ mResultRecorder.passed(file);
+
+ file = file + ".html";
+ String bugNumber = FileFilter.isKnownBug(file);
+ if (bugNumber != null) {
+ System.out.println("Bug Fixed: "+bugNumber+ " "+file);
+ return;
+ }
+
+ if (FileFilter.ignoreResults(file)) {
+ System.out.println("Ignored test passed: "+file);
+ return;
+ }
+ }
+
+ public void setCallback(HTMLHostCallbackInterface callback) {
+ mCallback = callback;
+ }
+
+ public void finished() {
+ int passed = 0;
+ while (!mFinishedStack.empty()) {
+ Log.v(LOGTAG, "Comparing dump and reference");
+ String file = (String)mFinishedStack.pop();
+
+ // Only check results that we can check, ie dumpAsText results
+ String dumpFile = file + "-results.txt";
+ File f = new File(dumpFile);
+ if (f.exists()) {
+ try {
+ FileInputStream fr = new FileInputStream(file+"-results.txt");
+ FileInputStream fe = new FileInputStream(file+"-expected.txt");
+
+ mResultRecorder.started(file);
+
+ // If the length is different then they are different
+ int diff = fe.available() - fr.available();
+ if (diff > 1 || diff < 0) {
+ failedCase(file, " different length");
+ fr.close();
+ fe.close();
+
+ mResultRecorder.finished(file);
+ continue;
+ }
+ byte[] br = new byte[fr.available()];
+ byte[] be = new byte[fe.available()];
+ fr.read(br);
+ fe.read(be);
+ boolean fail = false;
+ for (int i = 0; i < br.length; i++) {
+ if (br[i] != be[i]) {
+ failedCase(file, " @offset: "+i);
+ fail = true;
+ break;
+ }
+ }
+ if (br.length != be.length && be[be.length-1] == '\n') {
+ Log.d(LOGTAG, "Extra new line being ignore:" + file);
+ }
+ fr.close();
+ fe.close();
+ if (!fail) {
+ passed++;
+ passedCase(file);
+ }
+ } catch (FileNotFoundException ex) {
+ // TODO do something here
+ } catch (IOException ex) {
+ // Failed on available() or read()
+ }
+ mResultRecorder.finished(file);
+ }
+ }
+
+ if (mCallback != null) {
+ mCallback.waitForFinish();
+ }
+
+ finish();
+ }
+
+ // LayoutTestController Functions
+ public void dumpAsText() {
+ dumpAsText = true;
+ String url = mWebView.getUrl();
+ Log.v(LOGTAG, "dumpAsText called:"+url);
+ if (url.length() > 60)
+ url = url.substring(60);
+ }
+
+ public void waitUntilDone() {
+ waitToDump = true;
+ }
+ public void notifyDone() {
+ waitToDump = 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 (!dumpTitleChanges) {
+ mTitleChanges = new StringBuffer();
+ }
+ dumpTitleChanges = true;
+ }
+
+ public void keepWebHistory() {
+ if (!keepWebHistory) {
+ mWebHistory = new Vector();
+ }
+ keepWebHistory = 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();
+ }
+
+ // Instrumentation calls this to find
+ // if the activity has finished running the layout tests
+ public boolean hasFinishedRunning() {
+ if( mProcessStack == null || mFinishedStack == null)
+ return false;
+
+ if (mProcessStack.isEmpty() && mFinishedStack.empty()) {
+ return true;
+ }
+
+ return false;
+ }
+
+ private final WebChromeClient mChromeClient = new WebChromeClient() {
+ @Override
+ public void onProgressChanged(WebView view, int newProgress) {
+ if (newProgress == 100) {
+ pageComplete = true;
+ String url = mWebView.getUrl();
+ if (url != null) {
+ Log.v(LOGTAG, "Finished: "+ url);
+ if (url.length() > 60)
+ url = url.substring(60);
+ scheduleDump();
+ }
+ }
+ }
+
+ @Override
+ public void onReceivedTitle(WebView view, String title) {
+ if (title.length() > 30)
+ title = "..."+title.substring(title.length()-30);
+ setTitle(title);
+ if (dumpTitleChanges) {
+ 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');
+ return false;
+ }
+ };
+
+ private WebView mWebView;
+ private WebViewEventSender eventSender;
+ private Vector mProcessStack;
+ private Stack mFinishedStack;
+ static final String LOGTAG="DumpRenderTree";
+ private String mCurrentFile;
+ private int mOutstandingLoads;
+ private AsyncHandler mHandler;
+ private boolean mDumpRequested;
+
+ private boolean dumpAsText;
+ private boolean waitToDump;
+ private boolean pageComplete;
+
+ private boolean dumpTitleChanges;
+ private StringBuffer mTitleChanges;
+
+ private StringBuffer mDialogStrings;
+
+ private boolean keepWebHistory;
+ private Vector mWebHistory;
+
+ private boolean mTimedOut;
+
+ static final int MSG_DUMP = 0;
+ static final int MSG_TIMEOUT = 1;
+ static final int MSG_WEBKIT_DATA = 2;
+
+}
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/HTMLHostApp.java b/tests/DumpRenderTree/src/com/android/dumprendertree/HTMLHostApp.java
new file mode 100644
index 0000000..f610f5a
--- /dev/null
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/HTMLHostApp.java
@@ -0,0 +1,33 @@
+/*
+ * 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 android.app.Application;
+
+public class HTMLHostApp extends Application {
+
+ public HTMLHostApp() {
+ }
+
+ public void onCreate() {
+ }
+
+ public void onTerminate() {
+ }
+
+}
+
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/HTMLHostCallbackInterface.java b/tests/DumpRenderTree/src/com/android/dumprendertree/HTMLHostCallbackInterface.java
new file mode 100644
index 0000000..60a2915
--- /dev/null
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/HTMLHostCallbackInterface.java
@@ -0,0 +1,21 @@
+/*
+ * 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;
+
+public interface HTMLHostCallbackInterface {
+ public void waitForFinish();
+}
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestController.java b/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestController.java
new file mode 100644
index 0000000..6166dd0
--- /dev/null
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestController.java
@@ -0,0 +1,62 @@
+/*
+ * 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;
+
+public interface LayoutTestController {
+
+ public void dumpAsText();
+ public void waitUntilDone();
+ public void notifyDone();
+
+ // Force a redraw of the page
+ public void display();
+ // Used with pixel dumps of content
+ public void testRepaint();
+
+ // If the page title changes, add the information to the output.
+ public void dumpTitleChanges();
+ public void dumpBackForwardList();
+ public void dumpChildFrameScrollPositions();
+ public void dumpEditingCallbacks();
+
+ // Show/Hide window for window.onBlur() testing
+ public void setWindowIsKey(boolean b);
+ // Mac function, used to disable events going to the window
+ public void setMainFrameIsFirstResponder(boolean b);
+
+ public void dumpSelectionRect();
+
+ // invalidate and draw one line at a time of the web view.
+ public void repaintSweepHorizontally();
+
+ // History testing functions
+ public void keepWebHistory();
+ public void clearBackForwardList();
+ // navigate after page load has finished
+ public void queueBackNavigation(int howfar);
+ public void queueForwardNavigation(int howfar);
+
+ // Reload when the page load has finished
+ public void queueReload();
+ // Execute the provided script in current context when page load has finished.
+ public void queueScript(String scriptToRunInCurrentContext);
+ // Load the provided URL into the provided frame
+ public void queueLoad(String Url, String frameTarget);
+
+ public void setAcceptsEditing(boolean b);
+
+}
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoRunner.java b/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoRunner.java
new file mode 100755
index 0000000..e0e535e
--- /dev/null
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoRunner.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2008 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 junit.framework.TestSuite;
+import com.android.dumprendertree.LayoutTestsAutoTest;
+
+import android.test.InstrumentationTestRunner;
+import android.test.InstrumentationTestSuite;
+
+
+/**
+ * Instrumentation Test Runner for all MediaPlayer tests.
+ *
+ * Running all tests:
+ *
+ * adb shell am instrument \
+ * -w com.android.dumprendertree.LayoutTestsAutoRunner
+ */
+
+public class LayoutTestsAutoRunner extends InstrumentationTestRunner {
+ @Override
+ public TestSuite getAllTests() {
+ TestSuite suite = new InstrumentationTestSuite(this);
+ suite.addTestSuite(LayoutTestsAutoTest.class);
+ return suite;
+ }
+
+ @Override
+ public ClassLoader getLoader() {
+ return LayoutTestsAutoRunner.class.getClassLoader();
+ }
+}
+
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoTest.java b/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoTest.java
new file mode 100644
index 0000000..f46b263
--- /dev/null
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoTest.java
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2008 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 android.app.Instrumentation;
+import android.app.Instrumentation.ActivityMonitor;
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.util.Log;
+import android.view.KeyEvent;
+
+import android.test.ActivityInstrumentationTestCase;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import com.android.dumprendertree.HTMLHostActivity;
+
+public class LayoutTestsAutoTest extends ActivityInstrumentationTestCase<Menu> {
+
+ private final static String LOGTAG = "LayoutTests";
+ private final static String LAYOUT_TESTS_ROOT = "/sdcard/android/layout_tests/";
+
+ public LayoutTestsAutoTest() {
+ super("com.android.dumprendertree", Menu.class);
+ }
+
+ // Invokes running of layout tests
+ // and waits till it has finished running.
+ public void executeLayoutTests(String folder) {
+ Instrumentation inst = getInstrumentation();
+ getActivity().processFile(folder, true);
+
+ ActivityMonitor htmlHostActivityMonitor =
+ inst.addMonitor("com.android.dumprendertree.HTMLHostActivity", null, false);
+ HTMLHostActivity activity =
+ (HTMLHostActivity) htmlHostActivityMonitor.waitForActivityWithTimeout(6000);
+
+ while (!activity.hasFinishedRunning()) {
+ // Poll every 5 seconds to determine if the layout
+ // tests have finished running
+ try {Thread.sleep(5000); } catch(Exception e){}
+ }
+
+ // Wait few more seconds so that results are
+ // flushed to the /sdcard
+ try {Thread.sleep(5000); } catch(Exception e){}
+
+ return ;
+ }
+
+ // Running all the layout tests at once sometimes
+ // causes the dumprendertree to run out of memory.
+ // So, additional tests are added to run the tests
+ // in chunks.
+ @LargeTest
+ public void testAllLayoutTests() {
+ executeLayoutTests(LAYOUT_TESTS_ROOT + "fast");
+ }
+
+ @LargeTest
+ public void testLayoutSubset1() {
+ executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/backgrounds");
+ executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/borders");
+ executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/box-shadow");
+ executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/box-sizing");
+ executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/canvas");
+ }
+
+ @LargeTest
+ public void testLayoutSubset2() {
+ executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/clip");
+ executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/compact");
+ executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/cookies");
+ executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/css");
+ executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/css-generated-content");
+ executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/doctypes");
+ }
+
+ @LargeTest
+ public void testLayoutSubset3() {
+ executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/dom");
+ executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/dynamic");
+ executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/encoding");
+ executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/events");
+ executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/flexbox");
+ }
+
+ @LargeTest
+ public void testLayoutSubset4() {
+ executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/forms");
+ executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/frames");
+ executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/gradients");
+ executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/history");
+ executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/html");
+ }
+
+ @LargeTest
+ public void testLayoutSubset5() {
+ executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/images");
+ executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/inline");
+ executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/inline-block");
+ executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/innerHTML");
+ executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/invalid");
+ }
+
+ @LargeTest
+ public void testLayoutSubset6() {
+ executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/js");
+ executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/layers");
+ executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/leaks");
+ executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/lists");
+ executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/loader");
+ executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/media");
+ }
+
+ @LargeTest
+ public void testLayoutSubset7() {
+ executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/multicol");
+ executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/overflow");
+ executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/parser");
+ executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/profiler");
+ executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/reflections");
+ executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/regex");
+ }
+
+ @LargeTest
+ public void testLayoutSubset8() {
+ executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/repaint");
+ executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/replaced");
+ executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/runin");
+ executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/selectors");
+ executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/table");
+ executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/text");
+ }
+
+ @LargeTest
+ public void testLayoutSubset9() {
+ executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/tokenizer");
+ executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/transforms");
+ executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/xpath");
+ executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/xsl");
+ }
+}
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/Menu.java b/tests/DumpRenderTree/src/com/android/dumprendertree/Menu.java
new file mode 100644
index 0000000..2def8f3
--- /dev/null
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/Menu.java
@@ -0,0 +1,53 @@
+/*
+ * 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 android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+
+import java.io.File;
+
+public class Menu extends FileList {
+
+ public void onCreate(Bundle icicle)
+ {
+ super.onCreate(icicle);
+ }
+
+ boolean fileFilter(File f) {
+ if (f.getName().startsWith("."))
+ return false;
+ if (f.getName().equalsIgnoreCase("resources"))
+ return false;
+ if (f.isDirectory())
+ return true;
+ if (f.getPath().toLowerCase().endsWith("ml"))
+ return true;
+ return false;
+ }
+
+ void processFile(String filename, boolean selection)
+ {
+ Intent result = new Intent(null, Uri.parse(filename));
+ result.setClass(this, HTMLHostActivity.class);
+ result.putExtra("ReturnWhenFinished", selection);
+ startActivity(result);
+ }
+
+}
+
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/WebViewEventSender.java b/tests/DumpRenderTree/src/com/android/dumprendertree/WebViewEventSender.java
new file mode 100644
index 0000000..eea6346
--- /dev/null
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/WebViewEventSender.java
@@ -0,0 +1,194 @@
+/*
+ * 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 android.webkit.WebView;
+import android.view.KeyEvent;
+import android.util.*;
+
+import java.util.Arrays;
+
+public class WebViewEventSender implements EventSender {
+
+ WebViewEventSender(WebView webView) {
+ mWebView = webView;
+ }
+
+ public void resetMouse() {
+ mouseX = mouseY = 0;
+ }
+
+ public void enableDOMUIEventLogging(int DOMNode) {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void fireKeyboardEventsToElement(int DOMNode) {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void keyDown(String character, String[] withModifiers) {
+ Log.e("EventSender", "KeyDown: " + character + "("
+ + character.getBytes()[0] + ") Modifiers: "
+ + Arrays.toString(withModifiers));
+ KeyEvent modifier = null;
+ if (withModifiers != null && withModifiers.length > 0) {
+ for (int i = 0; i < withModifiers.length; i++) {
+ int keyCode = modifierMapper(withModifiers[i]);
+ modifier = new KeyEvent(KeyEvent.ACTION_DOWN, keyCode);
+ mWebView.onKeyDown(modifier.getKeyCode(), modifier);
+ }
+ }
+ int keyCode = keyMapper(character.toLowerCase().toCharArray()[0]);
+ KeyEvent event = new KeyEvent(KeyEvent.ACTION_DOWN, keyCode);
+ mWebView.onKeyDown(event.getKeyCode(), event);
+
+ }
+
+ public void keyDown(String character) {
+ keyDown(character, null);
+ }
+
+ public void leapForward(int milliseconds) {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void mouseClick() {
+ mouseDown();
+ mouseUp();
+ }
+
+ public void mouseDown() {
+ /* KeyEvent event = new KeyEvent(
+ KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_CENTER);
+ mWebView.onKeyDown(event.getKeyCode(), event); */
+ }
+
+ public void mouseMoveTo(int X, int Y) {
+ if (X > mouseX) {
+ KeyEvent event = new KeyEvent(
+ KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_RIGHT);
+ mWebView.onKeyDown(event.getKeyCode(), event);
+ mWebView.onKeyUp(event.getKeyCode(), event);
+ } else if ( X < mouseX ) {
+ KeyEvent event = new KeyEvent(
+ KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_LEFT);
+ mWebView.onKeyDown(event.getKeyCode(), event);
+ mWebView.onKeyUp(event.getKeyCode(), event);
+ }
+ if (Y > mouseY) {
+ KeyEvent event = new KeyEvent(
+ KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_DOWN);
+ mWebView.onKeyDown(event.getKeyCode(), event);
+ mWebView.onKeyUp(event.getKeyCode(), event);
+ } else if (Y < mouseY ) {
+ KeyEvent event = new KeyEvent(
+ KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_UP);
+ mWebView.onKeyDown(event.getKeyCode(), event);
+ mWebView.onKeyUp(event.getKeyCode(), event);
+ }
+ mouseX= X;
+ mouseY= Y;
+
+ }
+
+ public void mouseUp() {
+ /* KeyEvent event = new KeyEvent(
+ KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DPAD_CENTER);
+ mWebView.onKeyDown(event.getKeyCode(), event);*/
+
+ }
+
+ // Assumes lowercase chars, case needs to be
+ // handled by calling function.
+ static int keyMapper(char c) {
+ // handle numbers
+ if (c >= '0' && c<= '9') {
+ int offset = c - '0';
+ return KeyEvent.KEYCODE_0 + offset;
+ }
+
+ // handle characters
+ if (c >= 'a' && c <= 'z') {
+ int offset = c - 'a';
+ return KeyEvent.KEYCODE_A + offset;
+ }
+
+ // handle all others
+ switch (c) {
+ case '*':
+ return KeyEvent.KEYCODE_STAR;
+ case '#':
+ return KeyEvent.KEYCODE_POUND;
+ case ',':
+ return KeyEvent.KEYCODE_COMMA;
+ case '.':
+ return KeyEvent.KEYCODE_PERIOD;
+ case '\t':
+ return KeyEvent.KEYCODE_TAB;
+ case ' ':
+ return KeyEvent.KEYCODE_SPACE;
+ case '\n':
+ return KeyEvent.KEYCODE_ENTER;
+ case '\b':
+ case 0x7F:
+ return KeyEvent.KEYCODE_DEL;
+ case '~':
+ return KeyEvent.KEYCODE_GRAVE;
+ case '-':
+ return KeyEvent.KEYCODE_MINUS;
+ case '=':
+ return KeyEvent.KEYCODE_EQUALS;
+ case '(':
+ return KeyEvent.KEYCODE_LEFT_BRACKET;
+ case ')':
+ return KeyEvent.KEYCODE_RIGHT_BRACKET;
+ case '\\':
+ return KeyEvent.KEYCODE_BACKSLASH;
+ case ';':
+ return KeyEvent.KEYCODE_SEMICOLON;
+ case '\'':
+ return KeyEvent.KEYCODE_APOSTROPHE;
+ case '/':
+ return KeyEvent.KEYCODE_SLASH;
+ default:
+ break;
+ }
+
+ return c;
+ }
+
+ static int modifierMapper(String modifier) {
+ if (modifier.equals("ctrlKey")) {
+ return KeyEvent.KEYCODE_ALT_LEFT;
+ } else if (modifier.equals("shiftKey")) {
+ return KeyEvent.KEYCODE_SHIFT_LEFT;
+ } else if (modifier.equals("altKey")) {
+ return KeyEvent.KEYCODE_SYM;
+ } else if (modifier.equals("metaKey")) {
+ return KeyEvent.KEYCODE_UNKNOWN;
+ }
+ return KeyEvent.KEYCODE_UNKNOWN;
+ }
+
+ private WebView mWebView = null;
+ private int mouseX;
+ private int mouseY;
+
+}