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