| OLD | NEW |
| 1 // Copyright 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 package org.chromium.content.browser; | 5 package org.chromium.content.browser; |
| 6 | 6 |
| 7 import android.test.suitebuilder.annotation.SmallTest; | 7 import android.test.suitebuilder.annotation.SmallTest; |
| 8 | 8 |
| 9 import org.chromium.base.test.util.Feature; | 9 import org.chromium.base.test.util.Feature; |
| 10 import org.chromium.content.browser.test.util.TestCallbackHelperContainer; | 10 import org.chromium.content.browser.test.util.TestCallbackHelperContainer; |
| (...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 218 @SmallTest | 218 @SmallTest |
| 219 @Feature({"AndroidWebView", "Android-JavaBridge"}) | 219 @Feature({"AndroidWebView", "Android-JavaBridge"}) |
| 220 public void testCallingInvalidMethodRaisesException() throws Throwable { | 220 public void testCallingInvalidMethodRaisesException() throws Throwable { |
| 221 assertRaisesException("testController.foo()"); | 221 assertRaisesException("testController.foo()"); |
| 222 } | 222 } |
| 223 | 223 |
| 224 @SmallTest | 224 @SmallTest |
| 225 @Feature({"AndroidWebView", "Android-JavaBridge"}) | 225 @Feature({"AndroidWebView", "Android-JavaBridge"}) |
| 226 public void testUncaughtJavaExceptionRaisesJavaScriptException() throws Thro
wable { | 226 public void testUncaughtJavaExceptionRaisesJavaScriptException() throws Thro
wable { |
| 227 injectObjectAndReload(new Object() { | 227 injectObjectAndReload(new Object() { |
| 228 public void method() { throw new RuntimeException("foo"); } | 228 public void method() { |
| 229 throw new RuntimeException("foo"); |
| 230 } |
| 229 }, "testObject"); | 231 }, "testObject"); |
| 230 assertRaisesException("testObject.method()"); | 232 assertRaisesException("testObject.method()"); |
| 231 } | 233 } |
| 232 | 234 |
| 233 // Note that this requires that we can pass a JavaScript string to Java. | 235 // Note that this requires that we can pass a JavaScript string to Java. |
| 234 @SmallTest | 236 @SmallTest |
| 235 @Feature({"AndroidWebView", "Android-JavaBridge"}) | 237 @Feature({"AndroidWebView", "Android-JavaBridge"}) |
| 236 public void testTypeOfStaticMethod() throws Throwable { | 238 public void testTypeOfStaticMethod() throws Throwable { |
| 237 injectObjectAndReload(new ObjectWithStaticMethod(), "testObject"); | 239 injectObjectAndReload(new ObjectWithStaticMethod(), "testObject"); |
| 238 executeJavaScript("testController.setStringValue(typeof testObject.stati
cMethod)"); | 240 executeJavaScript("testController.setStringValue(typeof testObject.stati
cMethod)"); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 258 assertEquals("undefined", | 260 assertEquals("undefined", |
| 259 executeJavaScriptAndGetStringResult("typeof testObject.method"))
; | 261 executeJavaScriptAndGetStringResult("typeof testObject.method"))
; |
| 260 assertEquals("undefined", | 262 assertEquals("undefined", |
| 261 executeJavaScriptAndGetStringResult("typeof testObject.method2")
); | 263 executeJavaScriptAndGetStringResult("typeof testObject.method2")
); |
| 262 } | 264 } |
| 263 | 265 |
| 264 @SmallTest | 266 @SmallTest |
| 265 @Feature({"AndroidWebView", "Android-JavaBridge"}) | 267 @Feature({"AndroidWebView", "Android-JavaBridge"}) |
| 266 public void testReplaceInjectedObject() throws Throwable { | 268 public void testReplaceInjectedObject() throws Throwable { |
| 267 injectObjectAndReload(new Object() { | 269 injectObjectAndReload(new Object() { |
| 268 public void method() { mTestController.setStringValue("object 1"); } | 270 public void method() { |
| 271 mTestController.setStringValue("object 1"); |
| 272 } |
| 269 }, "testObject"); | 273 }, "testObject"); |
| 270 executeJavaScript("testObject.method()"); | 274 executeJavaScript("testObject.method()"); |
| 271 assertEquals("object 1", mTestController.waitForStringValue()); | 275 assertEquals("object 1", mTestController.waitForStringValue()); |
| 272 | 276 |
| 273 injectObjectAndReload(new Object() { | 277 injectObjectAndReload(new Object() { |
| 274 public void method() { mTestController.setStringValue("object 2"); } | 278 public void method() { |
| 279 mTestController.setStringValue("object 2"); |
| 280 } |
| 275 }, "testObject"); | 281 }, "testObject"); |
| 276 executeJavaScript("testObject.method()"); | 282 executeJavaScript("testObject.method()"); |
| 277 assertEquals("object 2", mTestController.waitForStringValue()); | 283 assertEquals("object 2", mTestController.waitForStringValue()); |
| 278 } | 284 } |
| 279 | 285 |
| 280 @SmallTest | 286 @SmallTest |
| 281 @Feature({"AndroidWebView", "Android-JavaBridge"}) | 287 @Feature({"AndroidWebView", "Android-JavaBridge"}) |
| 282 public void testInjectNullObjectIsIgnored() throws Throwable { | 288 public void testInjectNullObjectIsIgnored() throws Throwable { |
| 283 injectObjectAndReload(null, "testObject"); | 289 injectObjectAndReload(null, "testObject"); |
| 284 assertEquals("undefined", executeJavaScriptAndGetStringResult("typeof te
stObject")); | 290 assertEquals("undefined", executeJavaScriptAndGetStringResult("typeof te
stObject")); |
| 285 } | 291 } |
| 286 | 292 |
| 287 @SmallTest | 293 @SmallTest |
| 288 @Feature({"AndroidWebView", "Android-JavaBridge"}) | 294 @Feature({"AndroidWebView", "Android-JavaBridge"}) |
| 289 public void testReplaceInjectedObjectWithNullObjectIsIgnored() throws Throwa
ble { | 295 public void testReplaceInjectedObjectWithNullObjectIsIgnored() throws Throwa
ble { |
| 290 injectObjectAndReload(new Object(), "testObject"); | 296 injectObjectAndReload(new Object(), "testObject"); |
| 291 assertEquals("object", executeJavaScriptAndGetStringResult("typeof testO
bject")); | 297 assertEquals("object", executeJavaScriptAndGetStringResult("typeof testO
bject")); |
| 292 injectObjectAndReload(null, "testObject"); | 298 injectObjectAndReload(null, "testObject"); |
| 293 assertEquals("object", executeJavaScriptAndGetStringResult("typeof testO
bject")); | 299 assertEquals("object", executeJavaScriptAndGetStringResult("typeof testO
bject")); |
| 294 } | 300 } |
| 295 | 301 |
| 296 @SmallTest | 302 @SmallTest |
| 297 @Feature({"AndroidWebView", "Android-JavaBridge"}) | 303 @Feature({"AndroidWebView", "Android-JavaBridge"}) |
| 298 public void testCallOverloadedMethodWithDifferentNumberOfArguments() throws
Throwable { | 304 public void testCallOverloadedMethodWithDifferentNumberOfArguments() throws
Throwable { |
| 299 injectObjectAndReload(new Object() { | 305 injectObjectAndReload(new Object() { |
| 300 public void method() { mTestController.setStringValue("0 args"); } | 306 public void method() { |
| 301 public void method(int x) { mTestController.setStringValue("1 arg");
} | 307 mTestController.setStringValue("0 args"); |
| 302 public void method(int x, int y) { mTestController.setStringValue("2
args"); } | 308 } |
| 309 |
| 310 public void method(int x) { |
| 311 mTestController.setStringValue("1 arg"); |
| 312 } |
| 313 |
| 314 public void method(int x, int y) { |
| 315 mTestController.setStringValue("2 args"); |
| 316 } |
| 303 }, "testObject"); | 317 }, "testObject"); |
| 304 executeJavaScript("testObject.method()"); | 318 executeJavaScript("testObject.method()"); |
| 305 assertEquals("0 args", mTestController.waitForStringValue()); | 319 assertEquals("0 args", mTestController.waitForStringValue()); |
| 306 executeJavaScript("testObject.method(42)"); | 320 executeJavaScript("testObject.method(42)"); |
| 307 assertEquals("1 arg", mTestController.waitForStringValue()); | 321 assertEquals("1 arg", mTestController.waitForStringValue()); |
| 308 executeJavaScript("testObject.method(null)"); | 322 executeJavaScript("testObject.method(null)"); |
| 309 assertEquals("1 arg", mTestController.waitForStringValue()); | 323 assertEquals("1 arg", mTestController.waitForStringValue()); |
| 310 executeJavaScript("testObject.method(undefined)"); | 324 executeJavaScript("testObject.method(undefined)"); |
| 311 assertEquals("1 arg", mTestController.waitForStringValue()); | 325 assertEquals("1 arg", mTestController.waitForStringValue()); |
| 312 executeJavaScript("testObject.method(42, 42)"); | 326 executeJavaScript("testObject.method(42, 42)"); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 337 synchronousPageReload(); | 351 synchronousPageReload(); |
| 338 assertEquals("object", executeJavaScriptAndGetStringResult("typeof testC
ontroller")); | 352 assertEquals("object", executeJavaScriptAndGetStringResult("typeof testC
ontroller")); |
| 339 assertEquals("undefined", executeJavaScriptAndGetStringResult("testContr
oller.myProperty")); | 353 assertEquals("undefined", executeJavaScriptAndGetStringResult("testContr
oller.myProperty")); |
| 340 } | 354 } |
| 341 | 355 |
| 342 @SmallTest | 356 @SmallTest |
| 343 @Feature({"AndroidWebView", "Android-JavaBridge"}) | 357 @Feature({"AndroidWebView", "Android-JavaBridge"}) |
| 344 public void testSameObjectInjectedMultipleTimes() throws Throwable { | 358 public void testSameObjectInjectedMultipleTimes() throws Throwable { |
| 345 class TestObject { | 359 class TestObject { |
| 346 private int mNumMethodInvocations; | 360 private int mNumMethodInvocations; |
| 347 public void method() { mTestController.setIntValue(++mNumMethodInvoc
ations); } | 361 |
| 362 public void method() { |
| 363 mTestController.setIntValue(++mNumMethodInvocations); |
| 364 } |
| 348 } | 365 } |
| 349 final TestObject testObject = new TestObject(); | 366 final TestObject testObject = new TestObject(); |
| 350 TestCallbackHelperContainer.OnPageFinishedHelper onPageFinishedHelper = | 367 TestCallbackHelperContainer.OnPageFinishedHelper onPageFinishedHelper = |
| 351 mTestCallbackHelperContainer.getOnPageFinishedHelper(); | 368 mTestCallbackHelperContainer.getOnPageFinishedHelper(); |
| 352 int currentCallCount = onPageFinishedHelper.getCallCount(); | 369 int currentCallCount = onPageFinishedHelper.getCallCount(); |
| 353 runTestOnUiThread(new Runnable() { | 370 runTestOnUiThread(new Runnable() { |
| 354 @Override | 371 @Override |
| 355 public void run() { | 372 public void run() { |
| 356 getContentViewCore().addPossiblyUnsafeJavascriptInterface( | 373 getContentViewCore().addPossiblyUnsafeJavascriptInterface( |
| 357 testObject, "testObject1", null); | 374 testObject, "testObject1", null); |
| 358 getContentViewCore().addPossiblyUnsafeJavascriptInterface( | 375 getContentViewCore().addPossiblyUnsafeJavascriptInterface( |
| 359 testObject, "testObject2", null); | 376 testObject, "testObject2", null); |
| 360 getContentViewCore().getWebContents().getNavigationController().
reload(true); | 377 getContentViewCore().getWebContents().getNavigationController().
reload(true); |
| 361 } | 378 } |
| 362 }); | 379 }); |
| 363 onPageFinishedHelper.waitForCallback(currentCallCount); | 380 onPageFinishedHelper.waitForCallback(currentCallCount); |
| 364 executeJavaScript("testObject1.method()"); | 381 executeJavaScript("testObject1.method()"); |
| 365 assertEquals(1, mTestController.waitForIntValue()); | 382 assertEquals(1, mTestController.waitForIntValue()); |
| 366 executeJavaScript("testObject2.method()"); | 383 executeJavaScript("testObject2.method()"); |
| 367 assertEquals(2, mTestController.waitForIntValue()); | 384 assertEquals(2, mTestController.waitForIntValue()); |
| 368 } | 385 } |
| 369 | 386 |
| 370 @SmallTest | 387 @SmallTest |
| 371 @Feature({"AndroidWebView", "Android-JavaBridge"}) | 388 @Feature({"AndroidWebView", "Android-JavaBridge"}) |
| 372 public void testCallMethodOnReturnedObject() throws Throwable { | 389 public void testCallMethodOnReturnedObject() throws Throwable { |
| 373 injectObjectAndReload(new Object() { | 390 injectObjectAndReload(new Object() { |
| 374 public Object getInnerObject() { | 391 public Object getInnerObject() { |
| 375 return new Object() { | 392 return new Object() { |
| 376 public void method(int x) { mTestController.setIntValue(x);
} | 393 public void method(int x) { |
| 394 mTestController.setIntValue(x); |
| 395 } |
| 377 }; | 396 }; |
| 378 } | 397 } |
| 379 }, "testObject"); | 398 }, "testObject"); |
| 380 executeJavaScript("testObject.getInnerObject().method(42)"); | 399 executeJavaScript("testObject.getInnerObject().method(42)"); |
| 381 assertEquals(42, mTestController.waitForIntValue()); | 400 assertEquals(42, mTestController.waitForIntValue()); |
| 382 } | 401 } |
| 383 | 402 |
| 384 @SmallTest | 403 @SmallTest |
| 385 @Feature({"AndroidWebView", "Android-JavaBridge"}) | 404 @Feature({"AndroidWebView", "Android-JavaBridge"}) |
| 386 public void testReturnedObjectInjectedElsewhere() throws Throwable { | 405 public void testReturnedObjectInjectedElsewhere() throws Throwable { |
| 387 class InnerObject { | 406 class InnerObject { |
| 388 private int mNumMethodInvocations; | 407 private int mNumMethodInvocations; |
| 389 public void method() { mTestController.setIntValue(++mNumMethodInvoc
ations); } | 408 |
| 409 public void method() { |
| 410 mTestController.setIntValue(++mNumMethodInvocations); |
| 411 } |
| 390 } | 412 } |
| 391 final InnerObject innerObject = new InnerObject(); | 413 final InnerObject innerObject = new InnerObject(); |
| 392 final Object object = new Object() { | 414 final Object object = new Object() { |
| 393 public InnerObject getInnerObject() { | 415 public InnerObject getInnerObject() { |
| 394 return innerObject; | 416 return innerObject; |
| 395 } | 417 } |
| 396 }; | 418 }; |
| 397 TestCallbackHelperContainer.OnPageFinishedHelper onPageFinishedHelper = | 419 TestCallbackHelperContainer.OnPageFinishedHelper onPageFinishedHelper = |
| 398 mTestCallbackHelperContainer.getOnPageFinishedHelper(); | 420 mTestCallbackHelperContainer.getOnPageFinishedHelper(); |
| 399 int currentCallCount = onPageFinishedHelper.getCallCount(); | 421 int currentCallCount = onPageFinishedHelper.getCallCount(); |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 494 public void run() { | 516 public void run() { |
| 495 assertFalse(threadId == Thread.currentThread().getId()); | 517 assertFalse(threadId == Thread.currentThread().getId()); |
| 496 } | 518 } |
| 497 }); | 519 }); |
| 498 } | 520 } |
| 499 | 521 |
| 500 @SmallTest | 522 @SmallTest |
| 501 @Feature({"AndroidWebView", "Android-JavaBridge"}) | 523 @Feature({"AndroidWebView", "Android-JavaBridge"}) |
| 502 public void testPublicInheritedMethod() throws Throwable { | 524 public void testPublicInheritedMethod() throws Throwable { |
| 503 class Base { | 525 class Base { |
| 504 public void method(int x) { mTestController.setIntValue(x); } | 526 public void method(int x) { |
| 527 mTestController.setIntValue(x); |
| 528 } |
| 505 } | 529 } |
| 506 class Derived extends Base { | 530 class Derived extends Base { |
| 507 } | 531 } |
| 508 injectObjectAndReload(new Derived(), "testObject"); | 532 injectObjectAndReload(new Derived(), "testObject"); |
| 509 assertEquals("function", executeJavaScriptAndGetStringResult("typeof tes
tObject.method")); | 533 assertEquals("function", executeJavaScriptAndGetStringResult("typeof tes
tObject.method")); |
| 510 executeJavaScript("testObject.method(42)"); | 534 executeJavaScript("testObject.method(42)"); |
| 511 assertEquals(42, mTestController.waitForIntValue()); | 535 assertEquals(42, mTestController.waitForIntValue()); |
| 512 } | 536 } |
| 513 | 537 |
| 514 @SmallTest | 538 @SmallTest |
| 515 @Feature({"AndroidWebView", "Android-JavaBridge"}) | 539 @Feature({"AndroidWebView", "Android-JavaBridge"}) |
| 516 public void testPrivateInheritedMethod() throws Throwable { | 540 public void testPrivateInheritedMethod() throws Throwable { |
| 517 class Base { | 541 class Base { |
| 518 private void method() {} | 542 private void method() {} |
| 519 } | 543 } |
| 520 class Derived extends Base { | 544 class Derived extends Base { |
| 521 } | 545 } |
| 522 injectObjectAndReload(new Derived(), "testObject"); | 546 injectObjectAndReload(new Derived(), "testObject"); |
| 523 assertEquals("undefined", executeJavaScriptAndGetStringResult("typeof te
stObject.method")); | 547 assertEquals("undefined", executeJavaScriptAndGetStringResult("typeof te
stObject.method")); |
| 524 } | 548 } |
| 525 | 549 |
| 526 @SmallTest | 550 @SmallTest |
| 527 @Feature({"AndroidWebView", "Android-JavaBridge"}) | 551 @Feature({"AndroidWebView", "Android-JavaBridge"}) |
| 528 public void testOverriddenMethod() throws Throwable { | 552 public void testOverriddenMethod() throws Throwable { |
| 529 class Base { | 553 class Base { |
| 530 public void method() { mTestController.setStringValue("base"); } | 554 public void method() { |
| 555 mTestController.setStringValue("base"); |
| 556 } |
| 531 } | 557 } |
| 532 class Derived extends Base { | 558 class Derived extends Base { |
| 533 @Override | 559 @Override |
| 534 public void method() { mTestController.setStringValue("derived"); } | 560 public void method() { |
| 561 mTestController.setStringValue("derived"); |
| 562 } |
| 535 } | 563 } |
| 536 injectObjectAndReload(new Derived(), "testObject"); | 564 injectObjectAndReload(new Derived(), "testObject"); |
| 537 executeJavaScript("testObject.method()"); | 565 executeJavaScript("testObject.method()"); |
| 538 assertEquals("derived", mTestController.waitForStringValue()); | 566 assertEquals("derived", mTestController.waitForStringValue()); |
| 539 } | 567 } |
| 540 | 568 |
| 541 @SmallTest | 569 @SmallTest |
| 542 @Feature({"AndroidWebView", "Android-JavaBridge"}) | 570 @Feature({"AndroidWebView", "Android-JavaBridge"}) |
| 543 public void testEnumerateMembers() throws Throwable { | 571 public void testEnumerateMembers() throws Throwable { |
| 544 injectObjectAndReload(new Object() { | 572 injectObjectAndReload(new Object() { |
| 545 public void method() {} | 573 public void method() {} |
| 546 private void privateMethod() {} | 574 private void privateMethod() {} |
| 547 public int field; | 575 public int field; |
| 548 private int mPrivateField; | 576 private int mPrivateField; |
| 549 }, "testObject"); | 577 }, "testObject"); |
| 550 executeJavaScript( | 578 executeJavaScript( |
| 551 "var result = \"\"; " + | 579 "var result = \"\"; " + |
| 552 "for (x in testObject) { result += \" \" + x } " + | 580 "for (x in testObject) { result += \" \" + x } " + |
| 553 "testController.setStringValue(result);"); | 581 "testController.setStringValue(result);"); |
| 554 assertEquals(" equals getClass hashCode method notify notifyAll toString
wait", | 582 assertEquals(" equals getClass hashCode method notify notifyAll toString
wait", |
| 555 mTestController.waitForStringValue()); | 583 mTestController.waitForStringValue()); |
| 556 } | 584 } |
| 557 | 585 |
| 558 @SmallTest | 586 @SmallTest |
| 559 @Feature({"AndroidWebView", "Android-JavaBridge"}) | 587 @Feature({"AndroidWebView", "Android-JavaBridge"}) |
| 560 public void testReflectPublicMethod() throws Throwable { | 588 public void testReflectPublicMethod() throws Throwable { |
| 561 injectObjectAndReload(new Object() { | 589 injectObjectAndReload(new Object() { |
| 562 public Class<?> myGetClass() { return getClass(); } | 590 public Class<?> myGetClass() { |
| 563 public String method() { return "foo"; } | 591 return getClass(); |
| 592 } |
| 593 |
| 594 public String method() { |
| 595 return "foo"; |
| 596 } |
| 564 }, "testObject"); | 597 }, "testObject"); |
| 565 assertEquals("foo", executeJavaScriptAndGetStringResult( | 598 assertEquals("foo", executeJavaScriptAndGetStringResult( |
| 566 "testObject.myGetClass().getMethod('method', null).invoke(testOb
ject, null)" + | 599 "testObject.myGetClass().getMethod('method', null).invoke(testOb
ject, null)" + |
| 567 ".toString()")); | 600 ".toString()")); |
| 568 } | 601 } |
| 569 | 602 |
| 570 @SmallTest | 603 @SmallTest |
| 571 @Feature({"AndroidWebView", "Android-JavaBridge"}) | 604 @Feature({"AndroidWebView", "Android-JavaBridge"}) |
| 572 public void testReflectPublicField() throws Throwable { | 605 public void testReflectPublicField() throws Throwable { |
| 573 injectObjectAndReload(new Object() { | 606 injectObjectAndReload(new Object() { |
| 574 public Class<?> myGetClass() { return getClass(); } | 607 public Class<?> myGetClass() { |
| 608 return getClass(); |
| 609 } |
| 610 |
| 575 public String field = "foo"; | 611 public String field = "foo"; |
| 576 }, "testObject"); | 612 }, "testObject"); |
| 577 assertEquals("foo", executeJavaScriptAndGetStringResult( | 613 assertEquals("foo", executeJavaScriptAndGetStringResult( |
| 578 "testObject.myGetClass().getField('field').get(testObject).toStr
ing()")); | 614 "testObject.myGetClass().getField('field').get(testObject).toStr
ing()")); |
| 579 } | 615 } |
| 580 | 616 |
| 581 @SmallTest | 617 @SmallTest |
| 582 @Feature({"AndroidWebView", "Android-JavaBridge"}) | 618 @Feature({"AndroidWebView", "Android-JavaBridge"}) |
| 583 public void testReflectPrivateMethodRaisesException() throws Throwable { | 619 public void testReflectPrivateMethodRaisesException() throws Throwable { |
| 584 injectObjectAndReload(new Object() { | 620 injectObjectAndReload(new Object() { |
| 585 public Class<?> myGetClass() { return getClass(); } | 621 public Class<?> myGetClass() { |
| 622 return getClass(); |
| 623 } |
| 624 |
| 586 private void method() {}; | 625 private void method() {}; |
| 587 }, "testObject"); | 626 }, "testObject"); |
| 588 assertRaisesException("testObject.myGetClass().getMethod('method', null)
"); | 627 assertRaisesException("testObject.myGetClass().getMethod('method', null)
"); |
| 589 // getDeclaredMethod() is able to access a private method, but invoke() | 628 // getDeclaredMethod() is able to access a private method, but invoke() |
| 590 // throws a Java exception. | 629 // throws a Java exception. |
| 591 assertRaisesException( | 630 assertRaisesException( |
| 592 "testObject.myGetClass().getDeclaredMethod('method', null)." + | 631 "testObject.myGetClass().getDeclaredMethod('method', null)." + |
| 593 "invoke(testObject, null)"); | 632 "invoke(testObject, null)"); |
| 594 } | 633 } |
| 595 | 634 |
| 596 @SmallTest | 635 @SmallTest |
| 597 @Feature({"AndroidWebView", "Android-JavaBridge"}) | 636 @Feature({"AndroidWebView", "Android-JavaBridge"}) |
| 598 public void testReflectPrivateFieldRaisesException() throws Throwable { | 637 public void testReflectPrivateFieldRaisesException() throws Throwable { |
| 599 injectObjectAndReload(new Object() { | 638 injectObjectAndReload(new Object() { |
| 600 public Class<?> myGetClass() { return getClass(); } | 639 public Class<?> myGetClass() { |
| 640 return getClass(); |
| 641 } |
| 642 |
| 601 private int mField; | 643 private int mField; |
| 602 }, "testObject"); | 644 }, "testObject"); |
| 603 assertRaisesException("testObject.myGetClass().getField('field')"); | 645 assertRaisesException("testObject.myGetClass().getField('field')"); |
| 604 // getDeclaredField() is able to access a private field, but getInt() | 646 // getDeclaredField() is able to access a private field, but getInt() |
| 605 // throws a Java exception. | 647 // throws a Java exception. |
| 606 assertRaisesException( | 648 assertRaisesException( |
| 607 "testObject.myGetClass().getDeclaredField('field').getInt(testOb
ject)"); | 649 "testObject.myGetClass().getDeclaredField('field').getInt(testOb
ject)"); |
| 608 } | 650 } |
| 609 | 651 |
| 610 @SmallTest | 652 @SmallTest |
| 611 @Feature({"AndroidWebView", "Android-JavaBridge"}) | 653 @Feature({"AndroidWebView", "Android-JavaBridge"}) |
| 612 public void testAllowNonAnnotatedMethods() throws Throwable { | 654 public void testAllowNonAnnotatedMethods() throws Throwable { |
| 613 injectObjectAndReload(new Object() { | 655 injectObjectAndReload(new Object() { |
| 614 public String allowed() { return "foo"; } | 656 public String allowed() { |
| 657 return "foo"; |
| 658 } |
| 615 }, "testObject", null); | 659 }, "testObject", null); |
| 616 | 660 |
| 617 // Test calling a method of an explicitly inherited class (Base#allowed(
)). | 661 // Test calling a method of an explicitly inherited class (Base#allowed(
)). |
| 618 assertEquals("foo", executeJavaScriptAndGetStringResult("testObject.allo
wed()")); | 662 assertEquals("foo", executeJavaScriptAndGetStringResult("testObject.allo
wed()")); |
| 619 | 663 |
| 620 // Test calling a method of an implicitly inherited class (Object#toStri
ng()). | 664 // Test calling a method of an implicitly inherited class (Object#toStri
ng()). |
| 621 assertEquals("string", executeJavaScriptAndGetStringResult("typeof testO
bject.toString()")); | 665 assertEquals("string", executeJavaScriptAndGetStringResult("typeof testO
bject.toString()")); |
| 622 } | 666 } |
| 623 | 667 |
| 624 @SmallTest | 668 @SmallTest |
| 625 @Feature({"AndroidWebView", "Android-JavaBridge"}) | 669 @Feature({"AndroidWebView", "Android-JavaBridge"}) |
| 626 public void testAllowOnlyAnnotatedMethods() throws Throwable { | 670 public void testAllowOnlyAnnotatedMethods() throws Throwable { |
| 627 injectObjectAndReload(new Object() { | 671 injectObjectAndReload(new Object() { |
| 628 @JavascriptInterface | 672 @JavascriptInterface |
| 629 public String allowed() { return "foo"; } | 673 public String allowed() { |
| 674 return "foo"; |
| 675 } |
| 630 | 676 |
| 631 public String disallowed() { return "bar"; } | 677 public String disallowed() { |
| 678 return "bar"; |
| 679 } |
| 632 }, "testObject", JavascriptInterface.class); | 680 }, "testObject", JavascriptInterface.class); |
| 633 | 681 |
| 634 // getClass() is an Object method and does not have the @JavascriptInter
face annotation and | 682 // getClass() is an Object method and does not have the @JavascriptInter
face annotation and |
| 635 // should not be able to be called. | 683 // should not be able to be called. |
| 636 assertRaisesException("testObject.getClass()"); | 684 assertRaisesException("testObject.getClass()"); |
| 637 assertEquals("undefined", executeJavaScriptAndGetStringResult( | 685 assertEquals("undefined", executeJavaScriptAndGetStringResult( |
| 638 "typeof testObject.getClass")); | 686 "typeof testObject.getClass")); |
| 639 | 687 |
| 640 // allowed() is marked with the @JavascriptInterface annotation and shou
ld be allowed to be | 688 // allowed() is marked with the @JavascriptInterface annotation and shou
ld be allowed to be |
| 641 // called. | 689 // called. |
| 642 assertEquals("foo", executeJavaScriptAndGetStringResult("testObject.allo
wed()")); | 690 assertEquals("foo", executeJavaScriptAndGetStringResult("testObject.allo
wed()")); |
| 643 | 691 |
| 644 // disallowed() is not marked with the @JavascriptInterface annotation a
nd should not be | 692 // disallowed() is not marked with the @JavascriptInterface annotation a
nd should not be |
| 645 // able to be called. | 693 // able to be called. |
| 646 assertRaisesException("testObject.disallowed()"); | 694 assertRaisesException("testObject.disallowed()"); |
| 647 assertEquals("undefined", executeJavaScriptAndGetStringResult( | 695 assertEquals("undefined", executeJavaScriptAndGetStringResult( |
| 648 "typeof testObject.disallowed")); | 696 "typeof testObject.disallowed")); |
| 649 } | 697 } |
| 650 | 698 |
| 651 @SmallTest | 699 @SmallTest |
| 652 @Feature({"AndroidWebView", "Android-JavaBridge"}) | 700 @Feature({"AndroidWebView", "Android-JavaBridge"}) |
| 653 public void testAnnotationRequirementRetainsPropertyAcrossObjects() throws T
hrowable { | 701 public void testAnnotationRequirementRetainsPropertyAcrossObjects() throws T
hrowable { |
| 654 class Test { | 702 class Test { |
| 655 @JavascriptInterface | 703 @JavascriptInterface |
| 656 public String safe() { return "foo"; } | 704 public String safe() { |
| 705 return "foo"; |
| 706 } |
| 657 | 707 |
| 658 public String unsafe() { return "bar"; } | 708 public String unsafe() { |
| 709 return "bar"; |
| 710 } |
| 659 } | 711 } |
| 660 | 712 |
| 661 class TestReturner { | 713 class TestReturner { |
| 662 @JavascriptInterface | 714 @JavascriptInterface |
| 663 public Test getTest() { return new Test(); } | 715 public Test getTest() { |
| 716 return new Test(); |
| 717 } |
| 664 } | 718 } |
| 665 | 719 |
| 666 // First test with safe mode off. | 720 // First test with safe mode off. |
| 667 injectObjectAndReload(new TestReturner(), "unsafeTestObject", null); | 721 injectObjectAndReload(new TestReturner(), "unsafeTestObject", null); |
| 668 | 722 |
| 669 // safe() should be able to be called regardless of whether or not we ar
e in safe mode. | 723 // safe() should be able to be called regardless of whether or not we ar
e in safe mode. |
| 670 assertEquals("foo", executeJavaScriptAndGetStringResult( | 724 assertEquals("foo", executeJavaScriptAndGetStringResult( |
| 671 "unsafeTestObject.getTest().safe()")); | 725 "unsafeTestObject.getTest().safe()")); |
| 672 // unsafe() should be able to be called because we are not in safe mode. | 726 // unsafe() should be able to be called because we are not in safe mode. |
| 673 assertEquals("bar", executeJavaScriptAndGetStringResult( | 727 assertEquals("bar", executeJavaScriptAndGetStringResult( |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 716 @Retention(RetentionPolicy.RUNTIME) | 770 @Retention(RetentionPolicy.RUNTIME) |
| 717 @Target({ElementType.METHOD}) | 771 @Target({ElementType.METHOD}) |
| 718 @interface TestAnnotation { | 772 @interface TestAnnotation { |
| 719 } | 773 } |
| 720 | 774 |
| 721 @SmallTest | 775 @SmallTest |
| 722 @Feature({"AndroidWebView", "Android-JavaBridge"}) | 776 @Feature({"AndroidWebView", "Android-JavaBridge"}) |
| 723 public void testCustomAnnotationRestriction() throws Throwable { | 777 public void testCustomAnnotationRestriction() throws Throwable { |
| 724 class Test { | 778 class Test { |
| 725 @TestAnnotation | 779 @TestAnnotation |
| 726 public String checkTestAnnotationFoo() { return "bar"; } | 780 public String checkTestAnnotationFoo() { |
| 781 return "bar"; |
| 782 } |
| 727 | 783 |
| 728 @JavascriptInterface | 784 @JavascriptInterface |
| 729 public String checkJavascriptInterfaceFoo() { return "bar"; } | 785 public String checkJavascriptInterfaceFoo() { |
| 786 return "bar"; |
| 787 } |
| 730 } | 788 } |
| 731 | 789 |
| 732 // Inject javascriptInterfaceObj and require the JavascriptInterface ann
otation. | 790 // Inject javascriptInterfaceObj and require the JavascriptInterface ann
otation. |
| 733 injectObjectAndReload(new Test(), "javascriptInterfaceObj", JavascriptIn
terface.class); | 791 injectObjectAndReload(new Test(), "javascriptInterfaceObj", JavascriptIn
terface.class); |
| 734 | 792 |
| 735 // Test#testAnnotationFoo() should fail, as it isn't annotated with Java
scriptInterface. | 793 // Test#testAnnotationFoo() should fail, as it isn't annotated with Java
scriptInterface. |
| 736 assertRaisesException("javascriptInterfaceObj.checkTestAnnotationFoo()")
; | 794 assertRaisesException("javascriptInterfaceObj.checkTestAnnotationFoo()")
; |
| 737 assertEquals("undefined", executeJavaScriptAndGetStringResult( | 795 assertEquals("undefined", executeJavaScriptAndGetStringResult( |
| 738 "typeof javascriptInterfaceObj.checkTestAnnotationFoo")); | 796 "typeof javascriptInterfaceObj.checkTestAnnotationFoo")); |
| 739 | 797 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 751 // Test#javascriptInterfaceFoo() should fail, as it isn't annotated with
TestAnnotation. | 809 // Test#javascriptInterfaceFoo() should fail, as it isn't annotated with
TestAnnotation. |
| 752 assertRaisesException("testAnnotationObj.checkJavascriptInterfaceFoo()")
; | 810 assertRaisesException("testAnnotationObj.checkJavascriptInterfaceFoo()")
; |
| 753 assertEquals("undefined", executeJavaScriptAndGetStringResult( | 811 assertEquals("undefined", executeJavaScriptAndGetStringResult( |
| 754 "typeof testAnnotationObj.checkJavascriptInterfaceFoo")); | 812 "typeof testAnnotationObj.checkJavascriptInterfaceFoo")); |
| 755 } | 813 } |
| 756 | 814 |
| 757 @SmallTest | 815 @SmallTest |
| 758 @Feature({"AndroidWebView", "Android-JavaBridge"}) | 816 @Feature({"AndroidWebView", "Android-JavaBridge"}) |
| 759 public void testAddJavascriptInterfaceIsSafeByDefault() throws Throwable { | 817 public void testAddJavascriptInterfaceIsSafeByDefault() throws Throwable { |
| 760 class Test { | 818 class Test { |
| 761 public String blocked() { return "bar"; } | 819 public String blocked() { |
| 820 return "bar"; |
| 821 } |
| 762 | 822 |
| 763 @JavascriptInterface | 823 @JavascriptInterface |
| 764 public String allowed() { return "bar"; } | 824 public String allowed() { |
| 825 return "bar"; |
| 826 } |
| 765 } | 827 } |
| 766 | 828 |
| 767 // Manually inject the Test object, making sure to use the | 829 // Manually inject the Test object, making sure to use the |
| 768 // ContentViewCore#addJavascriptInterface, not the possibly unsafe versi
on. | 830 // ContentViewCore#addJavascriptInterface, not the possibly unsafe versi
on. |
| 769 TestCallbackHelperContainer.OnPageFinishedHelper onPageFinishedHelper = | 831 TestCallbackHelperContainer.OnPageFinishedHelper onPageFinishedHelper = |
| 770 mTestCallbackHelperContainer.getOnPageFinishedHelper(); | 832 mTestCallbackHelperContainer.getOnPageFinishedHelper(); |
| 771 int currentCallCount = onPageFinishedHelper.getCallCount(); | 833 int currentCallCount = onPageFinishedHelper.getCallCount(); |
| 772 runTestOnUiThread(new Runnable() { | 834 runTestOnUiThread(new Runnable() { |
| 773 @Override | 835 @Override |
| 774 public void run() { | 836 public void run() { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 787 assertRaisesException("testObject.blocked()"); | 849 assertRaisesException("testObject.blocked()"); |
| 788 assertEquals("undefined", executeJavaScriptAndGetStringResult( | 850 assertEquals("undefined", executeJavaScriptAndGetStringResult( |
| 789 "typeof testObject.blocked")); | 851 "typeof testObject.blocked")); |
| 790 } | 852 } |
| 791 | 853 |
| 792 @SmallTest | 854 @SmallTest |
| 793 @Feature({"AndroidWebView", "Android-JavaBridge"}) | 855 @Feature({"AndroidWebView", "Android-JavaBridge"}) |
| 794 public void testObjectsInspection() throws Throwable { | 856 public void testObjectsInspection() throws Throwable { |
| 795 class Test { | 857 class Test { |
| 796 @JavascriptInterface | 858 @JavascriptInterface |
| 797 public String m1() { return "foo"; } | 859 public String m1() { |
| 860 return "foo"; |
| 861 } |
| 798 | 862 |
| 799 @JavascriptInterface | 863 @JavascriptInterface |
| 800 public String m2() { return "bar"; } | 864 public String m2() { |
| 865 return "bar"; |
| 866 } |
| 801 | 867 |
| 802 @JavascriptInterface | 868 @JavascriptInterface |
| 803 public String m2(int x) { return "bar " + x; } | 869 public String m2(int x) { |
| 870 return "bar " + x; |
| 871 } |
| 804 } | 872 } |
| 805 | 873 |
| 806 final String jsObjectKeysTestTemplate = "Object.keys(%s).toString()"; | 874 final String jsObjectKeysTestTemplate = "Object.keys(%s).toString()"; |
| 807 final String jsForInTestTemplate = | 875 final String jsForInTestTemplate = |
| 808 "(function(){" + | 876 "(function(){" + |
| 809 " var s=[]; for(var m in %s) s.push(m); return s.join(\",\")" + | 877 " var s=[]; for(var m in %s) s.push(m); return s.join(\",\")" + |
| 810 "})()"; | 878 "})()"; |
| 811 final String inspectableObjectName = "testObj1"; | 879 final String inspectableObjectName = "testObj1"; |
| 812 final String nonInspectableObjectName = "testObj2"; | 880 final String nonInspectableObjectName = "testObj2"; |
| 813 | 881 |
| (...skipping 21 matching lines...) Expand all Loading... |
| 835 } | 903 } |
| 836 | 904 |
| 837 @SmallTest | 905 @SmallTest |
| 838 @Feature({"AndroidWebView", "Android-JavaBridge"}) | 906 @Feature({"AndroidWebView", "Android-JavaBridge"}) |
| 839 public void testAccessToObjectGetClassIsBlocked() throws Throwable { | 907 public void testAccessToObjectGetClassIsBlocked() throws Throwable { |
| 840 injectObjectAndReload(new Object(), "testObject"); | 908 injectObjectAndReload(new Object(), "testObject"); |
| 841 assertEquals("function", executeJavaScriptAndGetStringResult("typeof tes
tObject.getClass")); | 909 assertEquals("function", executeJavaScriptAndGetStringResult("typeof tes
tObject.getClass")); |
| 842 assertRaisesException("testObject.getClass()"); | 910 assertRaisesException("testObject.getClass()"); |
| 843 } | 911 } |
| 844 } | 912 } |
| OLD | NEW |