1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 /** 18 * Part of the test suite for the WebView's Java Bridge. This class tests the 19 * general use of arrays. 20 * 21 * The conversions should follow 22 * http://jdk6.java.net/plugin2/liveconnect/#JS_JAVA_CONVERSIONS. Places in 23 * which the implementation differs from the spec are marked with 24 * LIVECONNECT_COMPLIANCE. 25 * FIXME: Consider making our implementation more compliant, if it will not 26 * break backwards-compatibility. See b/4408210. 27 * 28 * To run this test ... 29 * adb shell am instrument -w -e class com.android.webviewtests.JavaBridgeArrayTest \ 30 * com.android.webviewtests/android.test.InstrumentationTestRunner 31 */ 32 33 package com.android.webviewtests; 34 35 public class JavaBridgeArrayTest extends JavaBridgeTestBase { 36 private class TestObject extends Controller { 37 private boolean mBooleanValue; 38 private int mIntValue; 39 private String mStringValue; 40 41 private int[] mIntArray; 42 private int[][] mIntIntArray; 43 44 private boolean mWasArrayMethodCalled; 45 setBooleanValue(boolean x)46 public synchronized void setBooleanValue(boolean x) { 47 mBooleanValue = x; 48 notifyResultIsReady(); 49 } setIntValue(int x)50 public synchronized void setIntValue(int x) { 51 mIntValue = x; 52 notifyResultIsReady(); 53 } setStringValue(String x)54 public synchronized void setStringValue(String x) { 55 mStringValue = x; 56 notifyResultIsReady(); 57 } 58 waitForBooleanValue()59 public synchronized boolean waitForBooleanValue() { 60 waitForResult(); 61 return mBooleanValue; 62 } waitForIntValue()63 public synchronized int waitForIntValue() { 64 waitForResult(); 65 return mIntValue; 66 } waitForStringValue()67 public synchronized String waitForStringValue() { 68 waitForResult(); 69 return mStringValue; 70 } 71 setIntArray(int[] x)72 public synchronized void setIntArray(int[] x) { 73 mIntArray = x; 74 notifyResultIsReady(); 75 } setIntIntArray(int[][] x)76 public synchronized void setIntIntArray(int[][] x) { 77 mIntIntArray = x; 78 notifyResultIsReady(); 79 } 80 waitForIntArray()81 public synchronized int[] waitForIntArray() { 82 waitForResult(); 83 return mIntArray; 84 } waitForIntIntArray()85 public synchronized int[][] waitForIntIntArray() { 86 waitForResult(); 87 return mIntIntArray; 88 } 89 arrayMethod()90 public synchronized int[] arrayMethod() { 91 mWasArrayMethodCalled = true; 92 return new int[] {42, 43, 44}; 93 } 94 wasArrayMethodCalled()95 public synchronized boolean wasArrayMethodCalled() { 96 return mWasArrayMethodCalled; 97 } 98 } 99 100 private TestObject mTestObject; 101 102 @Override setUp()103 protected void setUp() throws Exception { 104 super.setUp(); 105 mTestObject = new TestObject(); 106 setUpWebView(mTestObject, "testObject"); 107 } 108 testArrayLength()109 public void testArrayLength() throws Throwable { 110 executeJavaScript("testObject.setIntArray([42, 43, 44]);"); 111 int[] result = mTestObject.waitForIntArray(); 112 assertEquals(3, result.length); 113 assertEquals(42, result[0]); 114 assertEquals(43, result[1]); 115 assertEquals(44, result[2]); 116 } 117 testPassNull()118 public void testPassNull() throws Throwable { 119 executeJavaScript("testObject.setIntArray(null);"); 120 assertNull(mTestObject.waitForIntArray()); 121 } 122 testPassUndefined()123 public void testPassUndefined() throws Throwable { 124 executeJavaScript("testObject.setIntArray(undefined);"); 125 assertNull(mTestObject.waitForIntArray()); 126 } 127 testPassEmptyArray()128 public void testPassEmptyArray() throws Throwable { 129 executeJavaScript("testObject.setIntArray([]);"); 130 assertEquals(0, mTestObject.waitForIntArray().length); 131 } 132 133 // Note that this requires being able to pass a string from JavaScript to 134 // Java. testPassArrayToStringMethod()135 public void testPassArrayToStringMethod() throws Throwable { 136 // LIVECONNECT_COMPLIANCE: Should call toString() on array. 137 executeJavaScript("testObject.setStringValue([42, 42, 42]);"); 138 assertEquals("undefined", mTestObject.waitForStringValue()); 139 } 140 141 // Note that this requires being able to pass an integer from JavaScript to 142 // Java. testPassArrayToNonStringNonArrayMethod()143 public void testPassArrayToNonStringNonArrayMethod() throws Throwable { 144 // LIVECONNECT_COMPLIANCE: Should raise JavaScript exception. 145 executeJavaScript("testObject.setIntValue([42, 42, 42]);"); 146 assertEquals(0, mTestObject.waitForIntValue()); 147 } 148 testPassNonArrayToArrayMethod()149 public void testPassNonArrayToArrayMethod() throws Throwable { 150 // LIVECONNECT_COMPLIANCE: Should raise JavaScript exception. 151 executeJavaScript("testObject.setIntArray(42);"); 152 assertNull(mTestObject.waitForIntArray()); 153 } 154 testObjectWithLengthProperty()155 public void testObjectWithLengthProperty() throws Throwable { 156 executeJavaScript("testObject.setIntArray({length: 3, 1: 42});"); 157 int[] result = mTestObject.waitForIntArray(); 158 assertEquals(3, result.length); 159 assertEquals(0, result[0]); 160 assertEquals(42, result[1]); 161 assertEquals(0, result[2]); 162 } 163 testNonNumericLengthProperty()164 public void testNonNumericLengthProperty() throws Throwable { 165 // LIVECONNECT_COMPLIANCE: This should not count as an array, so we 166 // should raise a JavaScript exception. 167 executeJavaScript("testObject.setIntArray({length: \"foo\"});"); 168 assertNull(mTestObject.waitForIntArray()); 169 } 170 testLengthOutOfBounds()171 public void testLengthOutOfBounds() throws Throwable { 172 // LIVECONNECT_COMPLIANCE: This should not count as an array, so we 173 // should raise a JavaScript exception. 174 executeJavaScript("testObject.setIntArray({length: -1});"); 175 assertNull(mTestObject.waitForIntArray()); 176 177 // LIVECONNECT_COMPLIANCE: This should not count as an array, so we 178 // should raise a JavaScript exception. 179 long length = (long)Integer.MAX_VALUE + 1L; 180 executeJavaScript("testObject.setIntArray({length: " + length + "});"); 181 assertNull(mTestObject.waitForIntArray()); 182 183 // LIVECONNECT_COMPLIANCE: This should not count as an array, so we 184 // should raise a JavaScript exception. 185 length = (long)Integer.MAX_VALUE + 1L - (long)Integer.MIN_VALUE + 1L; 186 executeJavaScript("testObject.setIntArray({length: " + length + "});"); 187 assertNull(mTestObject.waitForIntArray()); 188 } 189 testSparseArray()190 public void testSparseArray() throws Throwable { 191 executeJavaScript("var x = [42, 43]; x[3] = 45; testObject.setIntArray(x);"); 192 int[] result = mTestObject.waitForIntArray(); 193 assertEquals(4, result.length); 194 assertEquals(42, result[0]); 195 assertEquals(43, result[1]); 196 assertEquals(0, result[2]); 197 assertEquals(45, result[3]); 198 } 199 200 // Note that this requires being able to pass a boolean from JavaScript to 201 // Java. testMethodReturningArrayNotCalled()202 public void testMethodReturningArrayNotCalled() throws Throwable { 203 // We don't invoke methods which return arrays, but note that no 204 // exception is raised. 205 // LIVECONNECT_COMPLIANCE: Should call method and convert result to 206 // JavaScript array. 207 executeJavaScript("testObject.setBooleanValue(undefined === testObject.arrayMethod())"); 208 assertTrue(mTestObject.waitForBooleanValue()); 209 assertFalse(mTestObject.wasArrayMethodCalled()); 210 } 211 testMultiDimensionalArrayMethod()212 public void testMultiDimensionalArrayMethod() throws Throwable { 213 // LIVECONNECT_COMPLIANCE: Should handle multi-dimensional arrays. 214 executeJavaScript("testObject.setIntIntArray([ [42, 43], [44, 45] ]);"); 215 assertNull(mTestObject.waitForIntIntArray()); 216 } 217 testPassMultiDimensionalArray()218 public void testPassMultiDimensionalArray() throws Throwable { 219 // LIVECONNECT_COMPLIANCE: Should handle multi-dimensional arrays. 220 executeJavaScript("testObject.setIntArray([ [42, 43], [44, 45] ]);"); 221 int[] result = mTestObject.waitForIntArray(); 222 assertEquals(2, result.length); 223 assertEquals(0, result[0]); 224 assertEquals(0, result[1]); 225 } 226 } 227