JavaBridgeCoercionTest.java revision a02191e04bc25c4935f804f2c080ae28663d096d
1// Copyright 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5package org.chromium.content.browser;
6
7import android.test.suitebuilder.annotation.SmallTest;
8
9import org.chromium.base.test.util.Feature;
10
11/**
12 * Part of the test suite for the Java Bridge. This class tests that
13 * we correctly convert JavaScript values to Java values when passing them to
14 * the methods of injected Java objects.
15 *
16 * The conversions should follow
17 * http://jdk6.java.net/plugin2/liveconnect/#JS_JAVA_CONVERSIONS. Places in
18 * which the implementation differs from the spec are marked with
19 * LIVECONNECT_COMPLIANCE.
20 * FIXME: Consider making our implementation more compliant, if it will not
21 * break backwards-compatibility. See b/4408210.
22 */
23public class JavaBridgeCoercionTest extends JavaBridgeTestBase {
24    private class TestObject extends Controller {
25        private Object objectInstance;
26        private CustomType customTypeInstance;
27        private CustomType2 customType2Instance;
28
29        private boolean mBooleanValue;
30        private byte mByteValue;
31        private char mCharValue;
32        private short mShortValue;
33        private int mIntValue;
34        private long mLongValue;
35        private float mFloatValue;
36        private double mDoubleValue;
37        private String mStringValue;
38        private Object mObjectValue;
39        private CustomType mCustomTypeValue;
40
41        public TestObject() {
42            objectInstance = new Object();
43            customTypeInstance = new CustomType();
44            customType2Instance = new CustomType2();
45        }
46
47        public Object getObjectInstance() {
48            return objectInstance;
49        }
50        public CustomType getCustomTypeInstance() {
51            return customTypeInstance;
52        }
53        public CustomType2 getCustomType2Instance() {
54            return customType2Instance;
55        }
56
57        public synchronized void setBooleanValue(boolean x) {
58            mBooleanValue = x;
59            notifyResultIsReady();
60        }
61        public synchronized void setByteValue(byte x) {
62            mByteValue = x;
63            notifyResultIsReady();
64        }
65        public synchronized void setCharValue(char x) {
66            mCharValue = x;
67            notifyResultIsReady();
68        }
69        public synchronized void setShortValue(short x) {
70            mShortValue = x;
71            notifyResultIsReady();
72        }
73        public synchronized void setIntValue(int x) {
74            mIntValue = x;
75            notifyResultIsReady();
76        }
77        public synchronized void setLongValue(long x) {
78            mLongValue = x;
79            notifyResultIsReady();
80        }
81        public synchronized void setFloatValue(float x) {
82            mFloatValue = x;
83            notifyResultIsReady();
84        }
85        public synchronized void setDoubleValue(double x) {
86            mDoubleValue = x;
87            notifyResultIsReady();
88        }
89        public synchronized void setStringValue(String x) {
90            mStringValue = x;
91            notifyResultIsReady();
92        }
93        public synchronized void setObjectValue(Object x) {
94            mObjectValue = x;
95            notifyResultIsReady();
96        }
97        public synchronized void setCustomTypeValue(CustomType x) {
98            mCustomTypeValue = x;
99            notifyResultIsReady();
100        }
101
102        public synchronized boolean waitForBooleanValue() {
103            waitForResult();
104            return mBooleanValue;
105        }
106        public synchronized byte waitForByteValue() {
107            waitForResult();
108            return mByteValue;
109        }
110        public synchronized char waitForCharValue() {
111            waitForResult();
112            return mCharValue;
113        }
114        public synchronized short waitForShortValue() {
115            waitForResult();
116            return mShortValue;
117        }
118        public synchronized int waitForIntValue() {
119            waitForResult();
120            return mIntValue;
121        }
122        public synchronized long waitForLongValue() {
123            waitForResult();
124            return mLongValue;
125        }
126        public synchronized float waitForFloatValue() {
127            waitForResult();
128            return mFloatValue;
129        }
130        public synchronized double waitForDoubleValue() {
131            waitForResult();
132            return mDoubleValue;
133        }
134        public synchronized String waitForStringValue() {
135            waitForResult();
136            return mStringValue;
137        }
138        public synchronized Object waitForObjectValue() {
139            waitForResult();
140            return mObjectValue;
141        }
142        public synchronized CustomType waitForCustomTypeValue() {
143            waitForResult();
144            return mCustomTypeValue;
145        }
146    }
147
148    // Two custom types used when testing passing objects.
149    private static class CustomType {
150    }
151    private static class CustomType2 {
152    }
153
154    private TestObject mTestObject;
155
156    @Override
157    protected void setUp() throws Exception {
158        super.setUp();
159        mTestObject = new TestObject();
160        setUpContentView(mTestObject, "testObject");
161    }
162
163    // Test passing a 32-bit integer JavaScript number to a method of an
164    // injected object. Note that JavaScript may choose to represent these
165    // values as either 32-bit integers or doubles, though this should not
166    // affect the result.
167    @SmallTest
168    @Feature({"AndroidWebView", "Android-JavaBridge"})
169    public void testPassNumberInt32() throws Throwable {
170        executeJavaScript("testObject.setByteValue(42);");
171        assertEquals(42, mTestObject.waitForByteValue());
172        executeJavaScript("testObject.setByteValue(" + Byte.MAX_VALUE + " + 42);");
173        assertEquals(Byte.MIN_VALUE + 42 - 1, mTestObject.waitForByteValue());
174
175        // LIVECONNECT_COMPLIANCE: Should convert to numeric char value.
176        executeJavaScript("testObject.setCharValue(42);");
177        assertEquals('\u0000', mTestObject.waitForCharValue());
178
179        executeJavaScript("testObject.setShortValue(42);");
180        assertEquals(42, mTestObject.waitForShortValue());
181        executeJavaScript("testObject.setShortValue(" + Short.MAX_VALUE + " + 42);");
182        assertEquals(Short.MIN_VALUE + 42 - 1, mTestObject.waitForShortValue());
183
184        executeJavaScript("testObject.setIntValue(42);");
185        assertEquals(42, mTestObject.waitForIntValue());
186
187        executeJavaScript("testObject.setLongValue(42);");
188        assertEquals(42L, mTestObject.waitForLongValue());
189
190        executeJavaScript("testObject.setFloatValue(42);");
191        assertEquals(42.0f, mTestObject.waitForFloatValue());
192
193        executeJavaScript("testObject.setDoubleValue(42);");
194        assertEquals(42.0, mTestObject.waitForDoubleValue());
195
196        // LIVECONNECT_COMPLIANCE: Should create an instance of java.lang.Number.
197        executeJavaScript("testObject.setObjectValue(42);");
198        assertNull(mTestObject.waitForObjectValue());
199
200        // The spec allows the JS engine flexibility in how to format the number.
201        executeJavaScript("testObject.setStringValue(42);");
202        String str = mTestObject.waitForStringValue();
203        assertTrue("42".equals(str) || "42.0".equals(str));
204
205        executeJavaScript("testObject.setBooleanValue(0);");
206        assertFalse(mTestObject.waitForBooleanValue());
207        // LIVECONNECT_COMPLIANCE: Should be true;
208        executeJavaScript("testObject.setBooleanValue(42);");
209        assertFalse(mTestObject.waitForBooleanValue());
210
211        // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception.
212        executeJavaScript("testObject.setCustomTypeValue(42);");
213        assertNull(mTestObject.waitForCustomTypeValue());
214    }
215
216    // Test passing a floating-point JavaScript number to a method of an
217    // injected object. JavaScript represents these values as doubles.
218    @SmallTest
219    @Feature({"AndroidWebView", "Android-JavaBridge"})
220    public void testPassNumberDouble() throws Throwable {
221        executeJavaScript("testObject.setByteValue(42.1);");
222        assertEquals(42, mTestObject.waitForByteValue());
223        executeJavaScript("testObject.setByteValue(" + Byte.MAX_VALUE + " + 42.1);");
224        assertEquals(Byte.MIN_VALUE + 42 - 1, mTestObject.waitForByteValue());
225        executeJavaScript("testObject.setByteValue(" + Byte.MIN_VALUE + " - 42.1);");
226        assertEquals(Byte.MAX_VALUE - 42 + 1, mTestObject.waitForByteValue());
227        executeJavaScript("testObject.setByteValue(" + Integer.MAX_VALUE + " + 42.1);");
228        assertEquals(-1, mTestObject.waitForByteValue());
229        executeJavaScript("testObject.setByteValue(" + Integer.MIN_VALUE + " - 42.1);");
230        assertEquals(0, mTestObject.waitForByteValue());
231
232        // LIVECONNECT_COMPLIANCE: Should convert to numeric char value.
233        executeJavaScript("testObject.setCharValue(42.1);");
234        assertEquals('\u0000', mTestObject.waitForCharValue());
235
236        executeJavaScript("testObject.setShortValue(42.1);");
237        assertEquals(42, mTestObject.waitForShortValue());
238        executeJavaScript("testObject.setShortValue(" + Short.MAX_VALUE + " + 42.1);");
239        assertEquals(Short.MIN_VALUE + 42 - 1, mTestObject.waitForShortValue());
240        executeJavaScript("testObject.setShortValue(" + Short.MIN_VALUE + " - 42.1);");
241        assertEquals(Short.MAX_VALUE - 42 + 1, mTestObject.waitForShortValue());
242        executeJavaScript("testObject.setShortValue(" + Integer.MAX_VALUE + " + 42.1);");
243        assertEquals(-1, mTestObject.waitForShortValue());
244        executeJavaScript("testObject.setShortValue(" + Integer.MIN_VALUE + " - 42.1);");
245        assertEquals(0, mTestObject.waitForShortValue());
246
247        executeJavaScript("testObject.setIntValue(42.1);");
248        assertEquals(42, mTestObject.waitForIntValue());
249        executeJavaScript("testObject.setIntValue(" + Integer.MAX_VALUE + " + 42.1);");
250        assertEquals(Integer.MAX_VALUE, mTestObject.waitForIntValue());
251        executeJavaScript("testObject.setIntValue(" + Integer.MIN_VALUE + " - 42.1);");
252        assertEquals(Integer.MIN_VALUE, mTestObject.waitForIntValue());
253
254        executeJavaScript("testObject.setLongValue(42.1);");
255        assertEquals(42L, mTestObject.waitForLongValue());
256        executeJavaScript("testObject.setLongValue(" + Long.MAX_VALUE + " + 42.1);");
257        assertEquals(Long.MAX_VALUE, mTestObject.waitForLongValue());
258        executeJavaScript("testObject.setLongValue(" + Long.MIN_VALUE + " - 42.1);");
259        assertEquals(Long.MIN_VALUE, mTestObject.waitForLongValue());
260
261        executeJavaScript("testObject.setFloatValue(42.1);");
262        assertEquals(42.1f, mTestObject.waitForFloatValue());
263
264        executeJavaScript("testObject.setDoubleValue(42.1);");
265        assertEquals(42.1, mTestObject.waitForDoubleValue());
266
267        // LIVECONNECT_COMPLIANCE: Should create an instance of java.lang.Number.
268        executeJavaScript("testObject.setObjectValue(42.1);");
269        assertNull(mTestObject.waitForObjectValue());
270
271        executeJavaScript("testObject.setStringValue(42.1);");
272        assertEquals("42.1", mTestObject.waitForStringValue());
273
274        executeJavaScript("testObject.setBooleanValue(0.0);");
275        assertFalse(mTestObject.waitForBooleanValue());
276        // LIVECONNECT_COMPLIANCE: Should be true.
277        executeJavaScript("testObject.setBooleanValue(42.1);");
278        assertFalse(mTestObject.waitForBooleanValue());
279
280        // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception.
281        executeJavaScript("testObject.setCustomTypeValue(42.1);");
282        assertNull(mTestObject.waitForCustomTypeValue());
283    }
284
285    // Test passing JavaScript NaN to a method of an injected object.
286    @SmallTest
287    @Feature({"AndroidWebView", "Android-JavaBridge"})
288    public void testPassNumberNaN() throws Throwable {
289        executeJavaScript("testObject.setByteValue(Number.NaN);");
290        assertEquals(0, mTestObject.waitForByteValue());
291
292        executeJavaScript("testObject.setCharValue(Number.NaN);");
293        assertEquals('\u0000', mTestObject.waitForCharValue());
294
295        executeJavaScript("testObject.setShortValue(Number.NaN);");
296        assertEquals(0, mTestObject.waitForShortValue());
297
298        executeJavaScript("testObject.setIntValue(Number.NaN);");
299        assertEquals(0, mTestObject.waitForIntValue());
300
301        executeJavaScript("testObject.setLongValue(Number.NaN);");
302        assertEquals(0L, mTestObject.waitForLongValue());
303
304        executeJavaScript("testObject.setFloatValue(Number.NaN);");
305        assertEquals(Float.NaN, mTestObject.waitForFloatValue());
306
307        executeJavaScript("testObject.setDoubleValue(Number.NaN);");
308        assertEquals(Double.NaN, mTestObject.waitForDoubleValue());
309
310        // LIVECONNECT_COMPLIANCE: Should create an instance of java.lang.Number.
311        executeJavaScript("testObject.setObjectValue(Number.NaN);");
312        assertNull(mTestObject.waitForObjectValue());
313
314        executeJavaScript("testObject.setStringValue(Number.NaN);");
315        assertEquals("NaN", mTestObject.waitForStringValue());
316
317        executeJavaScript("testObject.setBooleanValue(Number.NaN);");
318        assertFalse(mTestObject.waitForBooleanValue());
319
320        // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception.
321        executeJavaScript("testObject.setCustomTypeValue(Number.NaN);");
322        assertNull(mTestObject.waitForCustomTypeValue());
323    }
324
325    // Test passing JavaScript infinity to a method of an injected object.
326    @SmallTest
327    @Feature({"AndroidWebView", "Android-JavaBridge"})
328    public void testPassNumberInfinity() throws Throwable {
329        executeJavaScript("testObject.setByteValue(Infinity);");
330        assertEquals(-1, mTestObject.waitForByteValue());
331
332        // LIVECONNECT_COMPLIANCE: Should convert to maximum numeric char value.
333        executeJavaScript("testObject.setCharValue(Infinity);");
334        assertEquals('\u0000', mTestObject.waitForCharValue());
335
336        executeJavaScript("testObject.setShortValue(Infinity);");
337        assertEquals(-1, mTestObject.waitForShortValue());
338
339        executeJavaScript("testObject.setIntValue(Infinity);");
340        assertEquals(Integer.MAX_VALUE, mTestObject.waitForIntValue());
341
342        executeJavaScript("testObject.setLongValue(Infinity);");
343        assertEquals(Long.MAX_VALUE, mTestObject.waitForLongValue());
344
345        executeJavaScript("testObject.setFloatValue(Infinity);");
346        assertEquals(Float.POSITIVE_INFINITY, mTestObject.waitForFloatValue());
347
348        executeJavaScript("testObject.setDoubleValue(Infinity);");
349        assertEquals(Double.POSITIVE_INFINITY, mTestObject.waitForDoubleValue());
350
351        // LIVECONNECT_COMPLIANCE: Should create an instance of java.lang.Number.
352        executeJavaScript("testObject.setObjectValue(Infinity);");
353        assertNull(mTestObject.waitForObjectValue());
354
355        executeJavaScript("testObject.setStringValue(Infinity);");
356        assertEquals("Inf", mTestObject.waitForStringValue());
357
358        executeJavaScript("testObject.setBooleanValue(Infinity);");
359        assertFalse(mTestObject.waitForBooleanValue());
360
361        // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception.
362        executeJavaScript("testObject.setCustomTypeValue(Infinity);");
363        assertNull(mTestObject.waitForCustomTypeValue());
364    }
365
366    // Test passing a JavaScript boolean to a method of an injected object.
367    @SmallTest
368    @Feature({"AndroidWebView", "Android-JavaBridge"})
369    public void testPassBoolean() throws Throwable {
370        executeJavaScript("testObject.setBooleanValue(true);");
371        assertTrue(mTestObject.waitForBooleanValue());
372        executeJavaScript("testObject.setBooleanValue(false);");
373        assertFalse(mTestObject.waitForBooleanValue());
374
375        // LIVECONNECT_COMPLIANCE: Should create an instance of java.lang.Boolean.
376        executeJavaScript("testObject.setObjectValue(true);");
377        assertNull(mTestObject.waitForObjectValue());
378
379        executeJavaScript("testObject.setStringValue(false);");
380        assertEquals("false", mTestObject.waitForStringValue());
381        executeJavaScript("testObject.setStringValue(true);");
382        assertEquals("true", mTestObject.waitForStringValue());
383
384        // LIVECONNECT_COMPLIANCE: Should be 1.
385        executeJavaScript("testObject.setByteValue(true);");
386        assertEquals(0, mTestObject.waitForByteValue());
387        executeJavaScript("testObject.setByteValue(false);");
388        assertEquals(0, mTestObject.waitForByteValue());
389
390        // LIVECONNECT_COMPLIANCE: Should convert to numeric char value 1.
391        executeJavaScript("testObject.setCharValue(true);");
392        assertEquals('\u0000', mTestObject.waitForCharValue());
393        executeJavaScript("testObject.setCharValue(false);");
394        assertEquals('\u0000', mTestObject.waitForCharValue());
395
396        // LIVECONNECT_COMPLIANCE: Should be 1.
397        executeJavaScript("testObject.setShortValue(true);");
398        assertEquals(0, mTestObject.waitForShortValue());
399        executeJavaScript("testObject.setShortValue(false);");
400        assertEquals(0, mTestObject.waitForShortValue());
401
402        // LIVECONNECT_COMPLIANCE: Should be 1.
403        executeJavaScript("testObject.setIntValue(true);");
404        assertEquals(0, mTestObject.waitForIntValue());
405        executeJavaScript("testObject.setIntValue(false);");
406        assertEquals(0, mTestObject.waitForIntValue());
407
408        // LIVECONNECT_COMPLIANCE: Should be 1.
409        executeJavaScript("testObject.setLongValue(true);");
410        assertEquals(0L, mTestObject.waitForLongValue());
411        executeJavaScript("testObject.setLongValue(false);");
412        assertEquals(0L, mTestObject.waitForLongValue());
413
414        // LIVECONNECT_COMPLIANCE: Should be 1.0.
415        executeJavaScript("testObject.setFloatValue(true);");
416        assertEquals(0.0f, mTestObject.waitForFloatValue());
417        executeJavaScript("testObject.setFloatValue(false);");
418        assertEquals(0.0f, mTestObject.waitForFloatValue());
419
420        // LIVECONNECT_COMPLIANCE: Should be 1.0.
421        executeJavaScript("testObject.setDoubleValue(true);");
422        assertEquals(0.0, mTestObject.waitForDoubleValue());
423        executeJavaScript("testObject.setDoubleValue(false);");
424        assertEquals(0.0, mTestObject.waitForDoubleValue());
425
426        // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception.
427        executeJavaScript("testObject.setCustomTypeValue(true);");
428        assertNull(mTestObject.waitForCustomTypeValue());
429    }
430
431    // Test passing a JavaScript string to a method of an injected object.
432    @SmallTest
433    @Feature({"AndroidWebView", "Android-JavaBridge"})
434    public void testPassString() throws Throwable {
435        executeJavaScript("testObject.setStringValue(\"+042.10\");");
436        assertEquals("+042.10", mTestObject.waitForStringValue());
437
438        // Make sure that we distinguish between the empty string and NULL.
439        executeJavaScript("testObject.setStringValue(\"\");");
440        assertEquals("", mTestObject.waitForStringValue());
441
442        // LIVECONNECT_COMPLIANCE: Should create an instance of java.lang.String.
443        executeJavaScript("testObject.setObjectValue(\"+042.10\");");
444        assertNull(mTestObject.waitForObjectValue());
445
446        // LIVECONNECT_COMPLIANCE: Should use valueOf() of appropriate type.
447        executeJavaScript("testObject.setByteValue(\"+042.10\");");
448        assertEquals(0, mTestObject.waitForByteValue());
449
450        // LIVECONNECT_COMPLIANCE: Should use valueOf() of appropriate type.
451        executeJavaScript("testObject.setShortValue(\"+042.10\");");
452        assertEquals(0, mTestObject.waitForShortValue());
453
454        // LIVECONNECT_COMPLIANCE: Should use valueOf() of appropriate type.
455        executeJavaScript("testObject.setIntValue(\"+042.10\");");
456        assertEquals(0, mTestObject.waitForIntValue());
457
458        // LIVECONNECT_COMPLIANCE: Should use valueOf() of appropriate type.
459        executeJavaScript("testObject.setLongValue(\"+042.10\");");
460        assertEquals(0L, mTestObject.waitForLongValue());
461
462        // LIVECONNECT_COMPLIANCE: Should use valueOf() of appropriate type.
463        executeJavaScript("testObject.setFloatValue(\"+042.10\");");
464        assertEquals(0.0f, mTestObject.waitForFloatValue());
465
466        // LIVECONNECT_COMPLIANCE: Should use valueOf() of appropriate type.
467        executeJavaScript("testObject.setDoubleValue(\"+042.10\");");
468        assertEquals(0.0, mTestObject.waitForDoubleValue());
469
470        // LIVECONNECT_COMPLIANCE: Should decode and convert to numeric char value.
471        executeJavaScript("testObject.setCharValue(\"+042.10\");");
472        assertEquals('\u0000', mTestObject.waitForCharValue());
473
474        // LIVECONNECT_COMPLIANCE: Non-empty string should convert to true.
475        executeJavaScript("testObject.setBooleanValue(\"+042.10\");");
476        assertFalse(mTestObject.waitForBooleanValue());
477
478        // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception.
479        executeJavaScript("testObject.setCustomTypeValue(\"+042.10\");");
480        assertNull(mTestObject.waitForCustomTypeValue());
481    }
482
483    // Test passing a JavaScript object to a method of an injected object.
484    @SmallTest
485    @Feature({"AndroidWebView", "Android-JavaBridge"})
486    public void testPassJavaScriptObject() throws Throwable {
487        // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception.
488        executeJavaScript("testObject.setObjectValue({foo: 42});");
489        assertNull(mTestObject.waitForObjectValue());
490
491        // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception.
492        executeJavaScript("testObject.setCustomTypeValue({foo: 42});");
493        assertNull(mTestObject.waitForCustomTypeValue());
494
495        // LIVECONNECT_COMPLIANCE: Should call toString() on object.
496        executeJavaScript("testObject.setStringValue({foo: 42});");
497        assertEquals("undefined", mTestObject.waitForStringValue());
498
499        // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception.
500        executeJavaScript("testObject.setByteValue({foo: 42});");
501        assertEquals(0, mTestObject.waitForByteValue());
502
503        // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception.
504        executeJavaScript("testObject.setCharValue({foo: 42});");
505        assertEquals('\u0000', mTestObject.waitForCharValue());
506
507        // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception.
508        executeJavaScript("testObject.setShortValue({foo: 42});");
509        assertEquals(0, mTestObject.waitForShortValue());
510
511        // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception.
512        executeJavaScript("testObject.setIntValue({foo: 42});");
513        assertEquals(0, mTestObject.waitForIntValue());
514
515        // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception.
516        executeJavaScript("testObject.setLongValue({foo: 42});");
517        assertEquals(0L, mTestObject.waitForLongValue());
518
519        // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception.
520        executeJavaScript("testObject.setFloatValue({foo: 42});");
521        assertEquals(0.0f, mTestObject.waitForFloatValue());
522
523        // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception.
524        executeJavaScript("testObject.setDoubleValue({foo: 42});");
525        assertEquals(0.0, mTestObject.waitForDoubleValue());
526
527        // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception.
528        executeJavaScript("testObject.setBooleanValue({foo: 42});");
529        assertFalse(mTestObject.waitForBooleanValue());
530    }
531
532    // Test passing a Java object to a method of an injected object. Note that
533    // this test requires being able to return objects from the methods of
534    // injected objects. This is tested elsewhere.
535    @SmallTest
536    @Feature({"AndroidWebView", "Android-JavaBridge"})
537    public void testPassJavaObject() throws Throwable {
538        executeJavaScript("testObject.setObjectValue(testObject.getObjectInstance());");
539        assertTrue(mTestObject.getObjectInstance() == mTestObject.waitForObjectValue());
540        executeJavaScript("testObject.setObjectValue(testObject.getCustomTypeInstance());");
541        assertTrue(mTestObject.getCustomTypeInstance() == mTestObject.waitForObjectValue());
542
543        executeJavaScript("testObject.setCustomTypeValue(testObject.getObjectInstance());");
544        assertTrue(mTestObject.getObjectInstance() == mTestObject.waitForCustomTypeValue());
545        executeJavaScript("testObject.setCustomTypeValue(testObject.getCustomTypeInstance());");
546        assertTrue(mTestObject.getCustomTypeInstance() == mTestObject.waitForCustomTypeValue());
547        // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception, as the types are unrelated.
548        executeJavaScript("testObject.setCustomTypeValue(testObject.getCustomType2Instance());");
549        assertTrue(mTestObject.getCustomType2Instance() ==
550                (Object)mTestObject.waitForCustomTypeValue());
551
552        // LIVECONNECT_COMPLIANCE: Should call toString() on object.
553        executeJavaScript("testObject.setStringValue(testObject.getObjectInstance());");
554        assertEquals("undefined", mTestObject.waitForStringValue());
555
556        // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception.
557        executeJavaScript("testObject.setByteValue(testObject.getObjectInstance());");
558        assertEquals(0, mTestObject.waitForByteValue());
559
560        // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception.
561        executeJavaScript("testObject.setCharValue(testObject.getObjectInstance());");
562        assertEquals('\u0000', mTestObject.waitForCharValue());
563
564        // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception.
565        executeJavaScript("testObject.setShortValue(testObject.getObjectInstance());");
566        assertEquals(0, mTestObject.waitForShortValue());
567
568        // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception.
569        executeJavaScript("testObject.setIntValue(testObject.getObjectInstance());");
570        assertEquals(0, mTestObject.waitForIntValue());
571
572        // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception.
573        executeJavaScript("testObject.setLongValue(testObject.getObjectInstance());");
574        assertEquals(0L, mTestObject.waitForLongValue());
575
576        // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception.
577        executeJavaScript("testObject.setFloatValue(testObject.getObjectInstance());");
578        assertEquals(0.0f, mTestObject.waitForFloatValue());
579
580        // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception.
581        executeJavaScript("testObject.setDoubleValue(testObject.getObjectInstance());");
582        assertEquals(0.0, mTestObject.waitForDoubleValue());
583
584        // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception.
585        executeJavaScript("testObject.setBooleanValue(testObject.getObjectInstance());");
586        assertFalse(mTestObject.waitForBooleanValue());
587    }
588
589    // Test passing JavaScript null to a method of an injected object.
590    @SmallTest
591    @Feature({"AndroidWebView", "Android-JavaBridge"})
592    public void testPassNull() throws Throwable {
593        executeJavaScript("testObject.setObjectValue(null);");
594        assertNull(mTestObject.waitForObjectValue());
595
596        executeJavaScript("testObject.setCustomTypeValue(null);");
597        assertNull(mTestObject.waitForCustomTypeValue());
598
599        executeJavaScript("testObject.setStringValue(null);");
600        assertNull(mTestObject.waitForStringValue());
601
602        executeJavaScript("testObject.setByteValue(null);");
603        assertEquals(0, mTestObject.waitForByteValue());
604
605        executeJavaScript("testObject.setCharValue(null);");
606        assertEquals('\u0000', mTestObject.waitForCharValue());
607
608        executeJavaScript("testObject.setShortValue(null);");
609        assertEquals(0, mTestObject.waitForShortValue());
610
611        executeJavaScript("testObject.setIntValue(null);");
612        assertEquals(0, mTestObject.waitForIntValue());
613
614        executeJavaScript("testObject.setLongValue(null);");
615        assertEquals(0L, mTestObject.waitForLongValue());
616
617        executeJavaScript("testObject.setFloatValue(null);");
618        assertEquals(0.0f, mTestObject.waitForFloatValue());
619
620        executeJavaScript("testObject.setDoubleValue(null);");
621        assertEquals(0.0, mTestObject.waitForDoubleValue());
622
623        executeJavaScript("testObject.setBooleanValue(null);");
624        assertFalse(mTestObject.waitForBooleanValue());
625    }
626
627    // Test passing JavaScript undefined to a method of an injected object.
628    @SmallTest
629    @Feature({"AndroidWebView", "Android-JavaBridge"})
630    public void testPassUndefined() throws Throwable {
631        executeJavaScript("testObject.setObjectValue(undefined);");
632        assertNull(mTestObject.waitForObjectValue());
633
634        executeJavaScript("testObject.setCustomTypeValue(undefined);");
635        assertNull(mTestObject.waitForCustomTypeValue());
636
637        // LIVECONNECT_COMPLIANCE: Should be NULL.
638        executeJavaScript("testObject.setStringValue(undefined);");
639        assertEquals("undefined", mTestObject.waitForStringValue());
640
641        executeJavaScript("testObject.setByteValue(undefined);");
642        assertEquals(0, mTestObject.waitForByteValue());
643
644        executeJavaScript("testObject.setCharValue(undefined);");
645        assertEquals('\u0000', mTestObject.waitForCharValue());
646
647        executeJavaScript("testObject.setShortValue(undefined);");
648        assertEquals(0, mTestObject.waitForShortValue());
649
650        executeJavaScript("testObject.setIntValue(undefined);");
651        assertEquals(0, mTestObject.waitForIntValue());
652
653        executeJavaScript("testObject.setLongValue(undefined);");
654        assertEquals(0L, mTestObject.waitForLongValue());
655
656        executeJavaScript("testObject.setFloatValue(undefined);");
657        assertEquals(0.0f, mTestObject.waitForFloatValue());
658
659        executeJavaScript("testObject.setDoubleValue(undefined);");
660        assertEquals(0.0, mTestObject.waitForDoubleValue());
661
662        executeJavaScript("testObject.setBooleanValue(undefined);");
663        assertFalse(mTestObject.waitForBooleanValue());
664    }
665
666    // Verify that ArrayBuffers are not converted into objects or strings when passed
667    // to Java. Basically, ArrayBuffers are treated as generic JavaScript objects.
668    @SmallTest
669    @Feature({"AndroidWebView", "Android-JavaBridge"})
670    public void testPassArrayBuffer() throws Throwable {
671        executeJavaScript("buffer = new ArrayBuffer(16);");
672
673        executeJavaScript("testObject.setObjectValue(buffer);");
674        assertNull(mTestObject.waitForObjectValue());
675
676        executeJavaScript("testObject.setStringValue(buffer);");
677        assertEquals("undefined", mTestObject.waitForStringValue());
678    }
679
680    // Verify that ArrayBufferViewss are not converted into objects or strings when passed
681    // to Java. Basically, ArrayBufferViews are treated as generic JavaScript objects.
682    // Here, a DataView is used as an ArrayBufferView instance (since the latter is
683    // an interface and can't be instantiated directly).
684    @SmallTest
685    @Feature({"AndroidWebView", "Android-JavaBridge"})
686    public void testPassDataView() throws Throwable {
687        executeJavaScript("buffer = new ArrayBuffer(16);");
688
689        executeJavaScript("testObject.setObjectValue(new DataView(buffer));");
690        assertNull(mTestObject.waitForObjectValue());
691
692        executeJavaScript("testObject.setStringValue(new DataView(buffer));");
693        assertEquals("undefined", mTestObject.waitForStringValue());
694    }
695}
696