diff --git a/tests/assets/bindings_test.html b/tests/assets/bindings_test.html
new file mode 100755
index 0000000..93dbff1
--- /dev/null
+++ b/tests/assets/bindings_test.html
@@ -0,0 +1,231 @@
+<html>
+<head>
+<script type="text/javascript">
+
+function testPrimitiveTypes() {
+  return JNIBindingsTest.testPrimitiveTypes(100, 'c', 123.34567890, 456.789, 1234567, 1234567890, 6000, true);
+}
+
+function testObjectTypes() {
+  return JNIBindingsTest.testObjectTypes("Foo", "", {"foo":"bar"}, {});
+}
+
+function testArray() {
+  return JNIBindingsTest.testArray([1,2,3], ['d', 'o', 'g'], [1.2, 2.3, 3.4], [4.5,5.6,6.7], [1,2,3], [4,5,6], [7,8,9], [true, false]);
+}
+
+function testObjectArray() {
+  return JNIBindingsTest.testObjectArray(['Hello', 'World', '!'], [], [{"foo":"bar"}]);
+}
+
+function testObjectMembers() {
+  var foo = {"bool":true,
+             "byte":101,
+             "char":'d',
+             "double":123.456,
+             "float":456.789,
+             "int":102,
+             "long":103,
+             "short":104,
+             "string":"Hello World",
+             "array": [1,2,3],
+             "objArray":["foo", "bar", "baz"],
+             "object": {"foo":1}
+  };
+  return JNIBindingsTest.testObjectMembers(foo.bool, foo.byte, foo.char, foo.double, foo.float, foo.int, foo.long, foo.short, foo.string, foo.array, foo.objArray, foo.object);
+}
+
+function testJSPrimitivesToStringsInJava() {
+    return JNIBindingsTest.testJSPrimitivesToStringsInJava(123, null, 456.789, true, 'd', undefined);
+}
+
+function testJavaReturnTypes() {
+  var expectedBoolReturn = true;
+  var expectedByteReturn = 1;
+  var expectedCharReturn = 98; // 'b'; Currently bindings in JSC and V8 return chars as their ASCII equivalent.
+  var expectedDoubleReturn = 123.456;
+  var expectedFloatReturn = 456.789;
+  var expectedIntReturn = 123;
+  var expectedLongReturn = 1234;
+  var expectedShortReturn = 12345;
+  var expectedStringReturn = "Hello World!";
+
+  var returned = JNIBindingsTest.returnBool();
+  if (returned != expectedBoolReturn) {
+    appendLog("returnBool() failed: expected "+ expectedBoolReturn +", got " + returned);
+    return false;
+  }
+
+  returned = JNIBindingsTest.returnByte();
+  if (returned != expectedByteReturn) {
+    appendLog("returnByte() failed: expected "+ expectedByteReturn +", got " + returned);
+    return false;
+  }
+
+  returned = JNIBindingsTest.returnChar();
+  if (returned != expectedCharReturn) {
+    appendLog("returnChar() failed: expected "+ expectedCharReturn +", got " + returned);
+    return false;
+  }
+
+  returned = JNIBindingsTest.returnDouble();
+  if (returned != expectedDoubleReturn) {
+    appendLog("returnDouble() failed: expected "+ expectedDoubleReturn +", got " + returned);
+    return false;
+  }
+
+  returned = JNIBindingsTest.returnFloat();
+  if (Math.abs(returned - expectedFloatReturn) > 0.001) {
+    appendLog("returnFloat() failed: expected "+ expectedFloatReturn +", got " + returned);
+    return false;
+  }
+
+  returned = JNIBindingsTest.returnInt();
+  if (returned != expectedIntReturn) {
+    appendLog("returnInt() failed: expected "+ expectedIntReturn +", got " + returned);
+    return false;
+  }
+
+  returned = JNIBindingsTest.returnLong();
+  if (returned != expectedLongReturn) {
+    appendLog("returnLong() failed: expected "+ expectedLongReturn +", got " + returned);
+    return false;
+  }
+
+  returned = JNIBindingsTest.returnShort();
+  if (returned != expectedShortReturn) {
+    appendLog("returnShort() failed: expected "+ expectedShortReturn +", got " + returned);
+    return false;
+  }
+
+  returned = JNIBindingsTest.returnString();
+  if (returned != expectedStringReturn) {
+    appendLog("returnString() failed: expected "+ expectedStringReturn +", got " + returned);
+    return false;
+  }
+
+  returned = JNIBindingsTest.returnObject();
+  if (returned == null) {
+    appendLog("returnObject() failed: expected non-null, got " + returned);
+    return false;
+  } else if (returned.x != 0) {
+    // EMULATE_JSC_BINDINGS
+    // Note: the Java sets the x property to 123. JSC and V8 do not support object
+    // members in the bindings though.
+    appendLog("returnObject() failed: expected 'x' property 0, got " + returned.x)
+    return false;
+  } else if (returned.s != undefined) {
+    // EMULATE_JSC_BINDINGS
+    // Note that the java class returned has s set to Hello World. JSC and V8 do not support
+    // getting properties.
+    appendLog("returnObject() failed: expected 's' property undefined, got " + returned.s);
+    return false;
+  } else if (!returned.aMethod()) {
+    appendLog("returnObject() failed: expected 'aMethod' method to return true, got " + returned.aMethod());
+    return false;
+  } else if (returned.anotherMethod() != "Hello World") {
+    appendLog("returnObject() failed: expected 'anotherMethod' to return 'Hello World' got "+ returned.anotherMethod());
+    return false;
+  }
+
+  returned = JNIBindingsTest.returnArray();
+  if (returned != null) {
+    appendLog("returnArray() failed: expected null, got " + returned);
+    return false;
+  }
+
+  returned = JNIBindingsTest.returnVoid();
+  if (returned != null) {
+    appendLog("returnVoid() failed: expected null, got " + returned);
+    return false;
+  }
+
+  return true;
+}
+
+function getIfaceProperties() {
+  if (JNIBindingsTest.mInt != 0) {
+    // EMULATE_JSC_BINDINGS
+    // Note: the Java sets the mInt property to 123. JSC and V8 do not support object
+    // members in the bindings though.
+    appendLog("getIfaceProperties() failed: expected mInt = 0, got " + JNIBindingsTest.mInt);
+    return false;
+  }
+
+  if (JNIBindingsTest.mString != undefined) {
+    // EMULATE_JSC_BINDINGS
+    // Note that the java class returned has s set to Hello World. JSC and V8 do not support
+    // getting properties.
+    appendLog("getIfaceProperties() failed: expected mString = 'Hello World', got " + JNIBindingsTest.mString);
+    return false;
+  }
+
+  return true;
+}
+
+function appendLog(msg) {
+  var log = document.getElementById("status");
+  log.innerHTML += "<br/>" + msg;
+}
+
+function runTests() {
+
+  // Assume that if the test isn't done after 10s that we failed.
+  window.setTimeout(function() { JNIBindingsTest.testComplete(); }, 10000);
+
+  if (testPrimitiveTypes()) {
+    appendLog("testPrimitiveTypes passed!");
+  } else {
+    appendLog("testPrimtiveTypes failed!");
+  }
+
+  if (testObjectTypes()) {
+    appendLog("testObjectTypes passed!");
+  } else {
+    appendLog("testObjectTypes failed!");
+  }
+
+  if (testArray()) {
+    appendLog("testArray passed!");
+  } else {
+    appendLog("testArray failed!");
+  }
+
+  if (testObjectArray()) {
+    appendLog("testObjectArray passed!");
+  } else {
+    appendLog("testObjectArray failed!");
+  }
+
+  if (testObjectMembers()) {
+    appendLog("testObjectMembers passed!");
+  } else {
+    appendLog("<br/>testObjectMembers failed!");
+  }
+
+  if (testJSPrimitivesToStringsInJava()) {
+    appendLog("testJSPrimitivesToStringsInJava passed!");
+  } else {
+    appendLog("testJSPrimitivesToStringsInJava failed!");
+  }
+
+  if (testJavaReturnTypes()) {
+    appendLog("testJavaReturnTypes passed!");
+  } else {
+    appendLog("testJavaReturnTypes failed!");
+  }
+
+  if (getIfaceProperties()) {
+    appendLog("getIfaceProperties passed!");
+  } else {
+    appendLog("getIfaceProperties failed!");
+  }
+
+  JNIBindingsTest.testComplete();
+}
+</script>
+
+<body onload="runTests();">
+<p id="status">Running JNI Bindings test...</p>
+</body>
+</html>
diff --git a/tests/src/com/android/browser/JNIBindingsTest.java b/tests/src/com/android/browser/JNIBindingsTest.java
new file mode 100644
index 0000000..d2220f6
--- /dev/null
+++ b/tests/src/com/android/browser/JNIBindingsTest.java
@@ -0,0 +1,267 @@
+/*
+ * Copyright (C) 2010 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.browser;
+
+import android.test.AndroidTestCase;
+import android.util.Log;
+
+import java.util.Arrays;
+import junit.framework.AssertionFailedError;
+
+public class JNIBindingsTest extends AndroidTestCase {
+
+    private final static String LOGTAG = "JNIBindingsTest";
+    private JNIBindingsTestApp mTestApp;
+
+    public int mInt = 123;
+    public String mString = "Hello World";
+
+    public JNIBindingsTest(JNIBindingsTestApp testApp) {
+        mTestApp = testApp;
+    }
+
+    public void testComplete() {
+        Log.v(LOGTAG, "Completing the test.");
+        mTestApp.testComplete();
+    }
+
+    public void printAssertionFailed(AssertionFailedError e) {
+        Log.e(LOGTAG, "");
+        Log.e(LOGTAG, "*** ASSERTION FAILED: " + e.getMessage());
+        Log.e(LOGTAG, "*** Stack trace:");
+        StackTraceElement[] trace = e.getStackTrace();
+        for(StackTraceElement elem : trace) {
+            Log.e(LOGTAG, "***\t" + elem.toString());
+        }
+        Log.e(LOGTAG, "");
+    }
+
+    public boolean testPrimitiveTypes(byte byteParam, char charParam, double doubleParam,
+            float floatParam, int intParam, long longParam, short shortParam,
+            boolean booleanParam) {
+        byte expectedByteParam = 100;
+        char expectedCharParam = 'c';
+        double expectedDoubleParam = 123.34567890;
+        float expectedFloatParam = 456.789f;
+        int expectedIntParam = 1234567;
+        long expectedLongParam = 1234567890L;
+        short expectedShortParam = 6000;
+        boolean expectedBooleanParam = true;
+
+        try {
+            assertEquals(expectedByteParam, byteParam);
+
+            // EMULATE_JSC_BINDINGS: JSC does not pass chars correctly
+            // assertEquals(expectedCharParam, charParam);
+
+            assertEquals(expectedDoubleParam, doubleParam);
+            assertEquals(expectedFloatParam, floatParam);
+            assertEquals(expectedIntParam, intParam);
+            assertEquals(expectedLongParam, longParam);
+            assertEquals(expectedShortParam, shortParam);
+            assertEquals(expectedBooleanParam, booleanParam);
+        } catch (AssertionFailedError e) {
+            printAssertionFailed(e);
+           return false;
+        }
+        return true;
+    }
+
+    public boolean testObjectTypes(String stringParam, String emptyString, Object objectParam,
+            Object emptyObject) {
+        String expectedString = "Foo";
+        String expectedEmptyString = "";
+
+        try {
+            assertNotNull(stringParam);
+            assertNotNull(emptyString);
+            assertEquals(expectedString, stringParam);
+            assertEquals(expectedEmptyString, emptyString);
+            assertNull(objectParam);
+            assertNull(emptyObject);
+        } catch (AssertionFailedError e) {
+            printAssertionFailed(e);
+            return false;
+        }
+        return true;
+    }
+
+    public boolean testArray(byte[] byteArray, char[] charArray, double[] doubleArray,
+            float[] floatArray, int[] intArray, long[] longArray, short[] shortArray,
+            boolean[] booleanArray) {
+        byte[] expectedByteArray = { 1,2,3};
+        char[] expectedCharArray = {'d', 'o', 'g'};
+        double[] expectedDoubleArray = {1.2,2.3,3.4};
+        float[] expectedFloatArray = {4.5F,5.6F,6.7F};
+        int[] expectedIntArray = {1,2,3};
+        long[] expectedLongArray = {4L,5L,6L};
+        short[] expectedShortArray = {7,8,9};
+        boolean[] expectedBooleanArray = {true, false};
+
+        try {
+            assertNotNull(byteArray);
+            assertNotNull(charArray);
+            assertNotNull(doubleArray);
+            assertNotNull(floatArray);
+            assertNotNull(intArray);
+            assertNotNull(longArray);
+            assertNotNull(shortArray);
+            assertNotNull(booleanArray);
+            assertEquals(Arrays.toString(expectedByteArray), Arrays.toString(byteArray));
+            assertEquals(Arrays.toString(expectedCharArray), Arrays.toString(charArray));
+            assertEquals(Arrays.toString(expectedDoubleArray), Arrays.toString(doubleArray));
+            assertEquals(Arrays.toString(expectedFloatArray), Arrays.toString(floatArray));
+            assertEquals(Arrays.toString(expectedIntArray), Arrays.toString(intArray));
+            assertEquals(Arrays.toString(expectedLongArray), Arrays.toString(longArray));
+            assertEquals(Arrays.toString(expectedShortArray), Arrays.toString(shortArray));
+            assertEquals(Arrays.toString(expectedBooleanArray), Arrays.toString(booleanArray));
+        } catch (AssertionFailedError e) {
+            printAssertionFailed(e);
+            return false;
+        }
+        return true;
+    }
+
+    public boolean testObjectArray(String[] stringArray, Object[] emptyArray,
+            Object[] objectArray) {
+        String[] expectedStringArray = {"Hello", "World", "!"};
+        Object[] expectedObjectArray = {};
+
+        try {
+            assertNotNull(stringArray);
+
+            // EMULATE_JSC_BINDINGS JSC pass null for object arrays that are not strings.
+            // Should be an empty array?
+            assertNull(emptyArray);
+            assertNull(objectArray);
+
+            assertEquals(Arrays.toString(expectedStringArray), Arrays.toString(stringArray));
+
+            // EMULATE_JSC_BINDINGS
+            // assertEquals(Arrays.toString(expectedObjectArray), Arrays.toString(emptyArray));
+            // assertEquals(Arrays.toString(expectedObjectArray), Arrays.toString(objectArray));
+
+        } catch (AssertionFailedError e) {
+            printAssertionFailed(e);
+            return false;
+        }
+        return true;
+    }
+
+    public boolean testObjectMembers(boolean boolParam, byte byteParam, char charParam,
+            double doubleParam, float floatParam, int intParam, long longParam, short shortParam,
+            String stringParam, int[] intArrayParam, String[] stringArrayParam,
+            Object objectParam) {
+        boolean expectedBoolParam = true;
+        byte expectedByteParam = 101;
+        char expectedCharParam = 'd';
+        double expectedDoubleParam = 123.456;
+        float expectedFloatParam = 456.789F;
+        int expectedIntParam = 102;
+        long expectedLongParam = 103L;
+        short expectedShortParam = 104;
+        String expectedStringParam = "Hello World";
+        int[] expectedIntArray = {1,2,3};
+        String[] expectedStringArrayParam = {"foo", "bar", "baz"};
+
+        try {
+            assertEquals(expectedBoolParam, boolParam);
+            assertEquals(expectedByteParam, byteParam);
+
+            // EMULATE_JSC_BINDINGS: JSC does not pass chars correctly. (chars are strings in JS)
+            // assertEquals(expectedCharParam, charParam);
+
+            assertEquals(expectedDoubleParam, doubleParam);
+            assertEquals(expectedFloatParam, floatParam);
+            assertEquals(expectedIntParam, intParam);
+            assertEquals(expectedLongParam, longParam);
+            assertEquals(expectedShortParam, shortParam);
+            assertEquals(expectedStringParam, stringParam);
+            assertEquals(Arrays.toString(expectedIntArray), Arrays.toString(intArrayParam));
+            assertEquals(Arrays.toString(expectedStringArrayParam),
+                    Arrays.toString(stringArrayParam));
+            assertNull(objectParam);
+        } catch (AssertionFailedError e) {
+            printAssertionFailed(e);
+            return false;
+        }
+        return true;
+    }
+
+    public boolean testJSPrimitivesToStringsInJava(String intParam, String nullParam,
+            String doubleParam, String booleanParam, String charParam,
+            String undefinedParam) {
+        String expectedIntParam = "123";
+        String expectedDoubleParam = "456.789";
+        String expectedBooleanParam = "true";
+        String expectedCharParam = "d";
+
+        // EMULATE_JSC_BINDINGS JSC passes "undefined" for undefined types. Should be null?
+        String expectedUndefinedParam = "undefined";
+
+        try {
+            assertNotNull(intParam);
+            assertNull(nullParam);
+            assertNotNull(doubleParam);
+            assertNotNull(booleanParam);
+            assertNotNull(charParam);
+
+            // EMULATE_JSC_BINDINGS JSC passes "undefined" for undefined types.
+            assertNotNull(undefinedParam);
+
+            assertEquals(expectedIntParam, intParam);
+            assertEquals(expectedDoubleParam, doubleParam);
+            assertEquals(expectedBooleanParam, booleanParam);
+            assertEquals(expectedCharParam, charParam);;
+
+            // EMULATE_JSC_BINDINGS  JSC passes "undefined" for undefined types.
+            assertEquals(expectedUndefinedParam, undefinedParam);
+
+        } catch (AssertionFailedError e) {
+            printAssertionFailed(e);
+            return false;
+        }
+        return true;
+    }
+
+    public boolean returnBool() { return true; }
+    public byte returnByte() { return 1; }
+    public char returnChar() { return 'b'; }
+    public double returnDouble() { return 123.456; }
+    public float returnFloat() { return 456.789F; }
+    public int returnInt() { return 123; }
+    public long returnLong() { return 1234L; }
+    public short returnShort() { return 12345; }
+    public String returnString() { return "Hello World!"; }
+
+    public class TestObject {
+        public int x = 123;
+        public String s = "Hello World!";
+
+        public boolean aMethod() { return true; }
+        public String anotherMethod() { return "Hello World"; }
+    }
+
+    public TestObject returnObject() { return new TestObject(); }
+
+    public int[] returnArray() {
+        int[] array = {1,2,3,4,5};
+        return array;
+    }
+
+    public void returnVoid() { }
+}
diff --git a/tests/src/com/android/browser/JNIBindingsTestApp.java b/tests/src/com/android/browser/JNIBindingsTestApp.java
new file mode 100644
index 0000000..cb38cbc
--- /dev/null
+++ b/tests/src/com/android/browser/JNIBindingsTestApp.java
@@ -0,0 +1,222 @@
+/*
+ * Copyright (C) 2010 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.browser;
+
+import android.app.Instrumentation;
+import android.net.http.SslError;
+import android.os.Environment;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.test.ActivityInstrumentationTestCase2;
+import android.util.Log;
+import android.webkit.JsPromptResult;
+import android.webkit.JsResult;
+import android.webkit.SslErrorHandler;
+import android.webkit.WebView;
+
+/**
+ * Adds a JavaScript interface to the webview and calls functions on it to verify variables
+ * are passed from JS to Java correctly.
+ */
+public class JNIBindingsTestApp extends ActivityInstrumentationTestCase2<BrowserActivity> {
+
+    private final static String TAG = "JNIBindingsTest";
+
+    private static final int MSG_WEBKIT_DATA_READY = 101;
+
+    private BrowserActivity mActivity = null;
+    private Instrumentation mInst = null;
+
+    private boolean mTestDone = false;
+    private String mWebKitResult;
+
+    private String mExpectedWebKitResult = "Running JNI Bindings test...\n" +
+            "testPrimitiveTypes passed!\n" +
+            "testObjectTypes passed!\n" +
+            "testArray passed!\n" +
+            "testObjectArray passed!\n" +
+            "testObjectMembers passed!\n" +
+            "testJSPrimitivesToStringsInJava passed!\n" +
+            "testJavaReturnTypes passed!\n" +
+            "getIfaceProperties passed!\n";
+
+
+    private class GetWebKitDataThread extends Thread {
+        private JNIBindingsTestApp mTestApp;
+        private WebView mWebView;
+        private Handler mHandler;
+
+        GetWebKitDataThread(JNIBindingsTestApp testApp, WebView webView) {
+            mTestApp = testApp;
+            mWebView = webView;
+        }
+
+        public void run() {
+            Looper.prepare();
+            mHandler = new Handler() {
+                public void handleMessage(Message msg) {
+                    switch (msg.what) {
+                        case MSG_WEBKIT_DATA_READY: {
+                            mTestApp.setWebKitResult((String)msg.obj);
+                            Looper.myLooper().quit();
+                        }
+                        default: super.handleMessage(msg); break;
+                    }
+                }
+            };
+            mWebView.documentAsText(mHandler.obtainMessage(MSG_WEBKIT_DATA_READY));
+            Looper.loop();
+        }
+    }
+
+    public synchronized void setWebKitResult(String result) {
+       mWebKitResult = result;
+       notify();
+    }
+
+    public JNIBindingsTestApp() {
+        super(BrowserActivity.class);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        mActivity = getActivity();
+        mInst = getInstrumentation();
+        mInst.waitForIdleSync();
+
+    }
+
+    /**
+     * Gets the browser ready for testing by starting the application
+     * and wrapping the WebView's helper clients.
+     */
+    void setUpBrowser() {
+        Tab tab = mActivity.getTabControl().getCurrentTab();
+        WebView webView = tab.getWebView();
+        webView.addJavascriptInterface(new JNIBindingsTest(this), "JNIBindingsTest");
+
+        webView.setWebChromeClient(new TestWebChromeClient(webView.getWebChromeClient()) {
+
+            /**
+             * Dismisses and logs Javascript alerts.
+             */
+            @Override
+            public boolean onJsAlert(WebView view, String url, String message,
+                    JsResult result) {
+                String logMsg = String.format("JS Alert '%s' received from %s", message, url);
+                Log.w(TAG, logMsg);
+                result.confirm();
+
+                return true;
+            }
+
+            /**
+             * Confirms and logs Javascript alerts.
+             */
+            @Override
+            public boolean onJsConfirm(WebView view, String url, String message,
+                    JsResult result) {
+                String logMsg = String.format("JS Confirmation '%s' received from %s",
+                        message, url);
+                Log.w(TAG, logMsg);
+                result.confirm();
+
+                return true;
+            }
+
+            /**
+             * Confirms and logs Javascript alerts, providing the default value.
+             */
+            @Override
+            public boolean onJsPrompt(WebView view, String url, String message,
+                    String defaultValue, JsPromptResult result) {
+                String logMsg = String.format("JS Prompt '%s' received from %s; " +
+                        "Giving default value '%s'", message, url, defaultValue);
+                Log.w(TAG, logMsg);
+                result.confirm(defaultValue);
+
+                return true;
+            }
+        });
+
+        webView.setWebViewClient(new TestWebViewClient(webView.getWebViewClient()) {
+
+            /**
+             * Bypasses and logs errors.
+             */
+            @Override
+            public void onReceivedError(WebView view, int errorCode,
+                    String description, String failingUrl) {
+                String message = String.format("Error '%s' (%d) loading url: %s",
+                        description, errorCode, failingUrl);
+                Log.w(TAG, message);
+            }
+
+            /**
+             * Ignores and logs SSL errors.
+             */
+            @Override
+            public void onReceivedSslError(WebView view, SslErrorHandler handler,
+                    SslError error) {
+                Log.w(TAG, "SSL error: " + error);
+                handler.proceed();
+            }
+
+        });
+    }
+
+    public synchronized void testComplete() {
+        mTestDone = true;
+        notify();
+    }
+
+    public void testJNIBindings() {
+        setUpBrowser();
+
+        Tab tab = mActivity.getTabControl().getCurrentTab();
+        WebView webView = tab.getWebView();
+        webView.loadUrl("file:///sdcard/bindings_test.html");
+        synchronized(this) {
+            while(!mTestDone) {
+                try {
+                    wait();
+                } catch (InterruptedException e) {}
+            }
+        }
+
+        // Now the tests are complete grab the DOM content and compare to the reference.
+        GetWebKitDataThread getWKData = new GetWebKitDataThread(this, webView);
+        mWebKitResult = null;
+        getWKData.start();
+
+        synchronized(this) {
+            while(mWebKitResult == null) {
+                try {
+                    wait();
+                } catch (InterruptedException e) {}
+            }
+        }
+
+        Log.v(TAG, "WebKit result:");
+        Log.v(TAG, mWebKitResult);
+        assertEquals("Bindings test failed! See logcat for more details!", mExpectedWebKitResult,
+                mWebKitResult);
+    }
+}
