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 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
131 @Override | 131 @Override |
132 public void run() { | 132 public void run() { |
133 getContentViewCore().getWebContents().getNavigationController().
reload(true); | 133 getContentViewCore().getWebContents().getNavigationController().
reload(true); |
134 } | 134 } |
135 }); | 135 }); |
136 onPageFinishedHelper.waitForCallback(currentCallCount); | 136 onPageFinishedHelper.waitForCallback(currentCallCount); |
137 } | 137 } |
138 | 138 |
139 // Note that this requires that we can pass a JavaScript boolean to Java. | 139 // Note that this requires that we can pass a JavaScript boolean to Java. |
140 private void assertRaisesException(String script) throws Throwable { | 140 private void assertRaisesException(String script) throws Throwable { |
141 executeJavaScript("try {" + | 141 executeJavaScript("try {" |
142 script + ";" + | 142 + script + ";" |
143 " testController.setBooleanValue(false);" + | 143 + " testController.setBooleanValue(false);" |
144 "} catch (exception) {" + | 144 + "} catch (exception) {" |
145 " testController.setBooleanValue(true);" + | 145 + " testController.setBooleanValue(true);" |
146 "}"); | 146 + "}"); |
147 assertTrue(mTestController.waitForBooleanValue()); | 147 assertTrue(mTestController.waitForBooleanValue()); |
148 } | 148 } |
149 | 149 |
150 @SmallTest | 150 @SmallTest |
151 @Feature({"AndroidWebView", "Android-JavaBridge"}) | 151 @Feature({"AndroidWebView", "Android-JavaBridge"}) |
152 public void testTypeOfInjectedObject() throws Throwable { | 152 public void testTypeOfInjectedObject() throws Throwable { |
153 assertEquals("object", executeJavaScriptAndGetStringResult("typeof testC
ontroller")); | 153 assertEquals("object", executeJavaScriptAndGetStringResult("typeof testC
ontroller")); |
154 } | 154 } |
155 | 155 |
156 @SmallTest | 156 @SmallTest |
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
454 return inner; | 454 return inner; |
455 } | 455 } |
456 // A weak reference is used to check InnerObject instance reachabili
ty. | 456 // A weak reference is used to check InnerObject instance reachabili
ty. |
457 WeakReference<InnerObject> mWeakRefForInner; | 457 WeakReference<InnerObject> mWeakRefForInner; |
458 } | 458 } |
459 TestObject object = new TestObject(); | 459 TestObject object = new TestObject(); |
460 injectObjectAndReload(object, "testObject"); | 460 injectObjectAndReload(object, "testObject"); |
461 // Initially, store a reference to the inner object in JS to make sure i
t's not | 461 // Initially, store a reference to the inner object in JS to make sure i
t's not |
462 // garbage-collected prematurely. | 462 // garbage-collected prematurely. |
463 assertEquals("object", executeJavaScriptAndGetStringResult( | 463 assertEquals("object", executeJavaScriptAndGetStringResult( |
464 "(function() { " + | 464 "(function() { " |
465 "globalInner = testObject.getInnerObject(); return typeo
f globalInner; " + | 465 + "globalInner = testObject.getInnerObject(); return typ
eof globalInner; " |
466 "})()")); | 466 + "})()")); |
467 assertTrue(object.mWeakRefForInner.get() != null); | 467 assertTrue(object.mWeakRefForInner.get() != null); |
468 // Check that returned Java object is being held by the Java bridge, thu
s it's not | 468 // Check that returned Java object is being held by the Java bridge, thu
s it's not |
469 // collected. Note that despite that what JavaDoc says about invoking "
gc()", both Dalvik | 469 // collected. Note that despite that what JavaDoc says about invoking "
gc()", both Dalvik |
470 // and ART actually run the collector. | 470 // and ART actually run the collector. |
471 Runtime.getRuntime().gc(); | 471 Runtime.getRuntime().gc(); |
472 assertTrue(object.mWeakRefForInner.get() != null); | 472 assertTrue(object.mWeakRefForInner.get() != null); |
473 // Now dereference the inner object in JS and run GC to collect the inte
rface object. | 473 // Now dereference the inner object in JS and run GC to collect the inte
rface object. |
474 assertEquals("true", executeJavaScriptAndGetStringResult( | 474 assertEquals("true", executeJavaScriptAndGetStringResult( |
475 "(function() { " + | 475 "(function() { " |
476 "delete globalInner; gc(); return (typeof globalInner ==
'undefined'); " + | 476 + "delete globalInner; gc(); return (typeof globalInner
== 'undefined'); " |
477 "})()")); | 477 + "})()")); |
478 // Force GC on the Java side again. The bridge had to release the inner
object, so it must | 478 // Force GC on the Java side again. The bridge had to release the inner
object, so it must |
479 // be collected this time. | 479 // be collected this time. |
480 Runtime.getRuntime().gc(); | 480 Runtime.getRuntime().gc(); |
481 assertEquals(null, object.mWeakRefForInner.get()); | 481 assertEquals(null, object.mWeakRefForInner.get()); |
482 } | 482 } |
483 | 483 |
484 @SmallTest | 484 @SmallTest |
485 @Feature({"AndroidWebView", "Android-JavaBridge"}) | 485 @Feature({"AndroidWebView", "Android-JavaBridge"}) |
486 public void testSameReturnedObjectUsesSameWrapper() throws Throwable { | 486 public void testSameReturnedObjectUsesSameWrapper() throws Throwable { |
487 class InnerObject { | 487 class InnerObject { |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
569 @SmallTest | 569 @SmallTest |
570 @Feature({"AndroidWebView", "Android-JavaBridge"}) | 570 @Feature({"AndroidWebView", "Android-JavaBridge"}) |
571 public void testEnumerateMembers() throws Throwable { | 571 public void testEnumerateMembers() throws Throwable { |
572 injectObjectAndReload(new Object() { | 572 injectObjectAndReload(new Object() { |
573 public void method() {} | 573 public void method() {} |
574 private void privateMethod() {} | 574 private void privateMethod() {} |
575 public int field; | 575 public int field; |
576 private int mPrivateField; | 576 private int mPrivateField; |
577 }, "testObject"); | 577 }, "testObject"); |
578 executeJavaScript( | 578 executeJavaScript( |
579 "var result = \"\"; " + | 579 "var result = \"\"; " |
580 "for (x in testObject) { result += \" \" + x } " + | 580 + "for (x in testObject) { result += \" \" + x } " |
581 "testController.setStringValue(result);"); | 581 + "testController.setStringValue(result);"); |
582 assertEquals(" equals getClass hashCode method notify notifyAll toString
wait", | 582 assertEquals(" equals getClass hashCode method notify notifyAll toString
wait", |
583 mTestController.waitForStringValue()); | 583 mTestController.waitForStringValue()); |
584 } | 584 } |
585 | 585 |
586 @SmallTest | 586 @SmallTest |
587 @Feature({"AndroidWebView", "Android-JavaBridge"}) | 587 @Feature({"AndroidWebView", "Android-JavaBridge"}) |
588 public void testReflectPublicMethod() throws Throwable { | 588 public void testReflectPublicMethod() throws Throwable { |
589 injectObjectAndReload(new Object() { | 589 injectObjectAndReload(new Object() { |
590 public Class<?> myGetClass() { | 590 public Class<?> myGetClass() { |
591 return getClass(); | 591 return getClass(); |
592 } | 592 } |
593 | 593 |
594 public String method() { | 594 public String method() { |
595 return "foo"; | 595 return "foo"; |
596 } | 596 } |
597 }, "testObject"); | 597 }, "testObject"); |
598 assertEquals("foo", executeJavaScriptAndGetStringResult( | 598 assertEquals("foo", executeJavaScriptAndGetStringResult( |
599 "testObject.myGetClass().getMethod('method', null).invoke(testOb
ject, null)" + | 599 "testObject.myGetClass().getMethod('method', null).invoke(testOb
ject, null)" |
600 ".toString()")); | 600 + ".toString()")); |
601 } | 601 } |
602 | 602 |
603 @SmallTest | 603 @SmallTest |
604 @Feature({"AndroidWebView", "Android-JavaBridge"}) | 604 @Feature({"AndroidWebView", "Android-JavaBridge"}) |
605 public void testReflectPublicField() throws Throwable { | 605 public void testReflectPublicField() throws Throwable { |
606 injectObjectAndReload(new Object() { | 606 injectObjectAndReload(new Object() { |
607 public Class<?> myGetClass() { | 607 public Class<?> myGetClass() { |
608 return getClass(); | 608 return getClass(); |
609 } | 609 } |
610 | 610 |
(...skipping 10 matching lines...) Expand all Loading... |
621 public Class<?> myGetClass() { | 621 public Class<?> myGetClass() { |
622 return getClass(); | 622 return getClass(); |
623 } | 623 } |
624 | 624 |
625 private void method() {}; | 625 private void method() {}; |
626 }, "testObject"); | 626 }, "testObject"); |
627 assertRaisesException("testObject.myGetClass().getMethod('method', null)
"); | 627 assertRaisesException("testObject.myGetClass().getMethod('method', null)
"); |
628 // getDeclaredMethod() is able to access a private method, but invoke() | 628 // getDeclaredMethod() is able to access a private method, but invoke() |
629 // throws a Java exception. | 629 // throws a Java exception. |
630 assertRaisesException( | 630 assertRaisesException( |
631 "testObject.myGetClass().getDeclaredMethod('method', null)." + | 631 "testObject.myGetClass().getDeclaredMethod('method', null)." |
632 "invoke(testObject, null)"); | 632 + "invoke(testObject, null)"); |
633 } | 633 } |
634 | 634 |
635 @SmallTest | 635 @SmallTest |
636 @Feature({"AndroidWebView", "Android-JavaBridge"}) | 636 @Feature({"AndroidWebView", "Android-JavaBridge"}) |
637 public void testReflectPrivateFieldRaisesException() throws Throwable { | 637 public void testReflectPrivateFieldRaisesException() throws Throwable { |
638 injectObjectAndReload(new Object() { | 638 injectObjectAndReload(new Object() { |
639 public Class<?> myGetClass() { | 639 public Class<?> myGetClass() { |
640 return getClass(); | 640 return getClass(); |
641 } | 641 } |
642 | 642 |
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
866 } | 866 } |
867 | 867 |
868 @JavascriptInterface | 868 @JavascriptInterface |
869 public String m2(int x) { | 869 public String m2(int x) { |
870 return "bar " + x; | 870 return "bar " + x; |
871 } | 871 } |
872 } | 872 } |
873 | 873 |
874 final String jsObjectKeysTestTemplate = "Object.keys(%s).toString()"; | 874 final String jsObjectKeysTestTemplate = "Object.keys(%s).toString()"; |
875 final String jsForInTestTemplate = | 875 final String jsForInTestTemplate = |
876 "(function(){" + | 876 "(function(){" |
877 " 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(\",\")" |
878 "})()"; | 878 + "})()"; |
879 final String inspectableObjectName = "testObj1"; | 879 final String inspectableObjectName = "testObj1"; |
880 final String nonInspectableObjectName = "testObj2"; | 880 final String nonInspectableObjectName = "testObj2"; |
881 | 881 |
882 // Inspection is enabled by default. | 882 // Inspection is enabled by default. |
883 injectObjectAndReload(new Test(), inspectableObjectName, JavascriptInter
face.class); | 883 injectObjectAndReload(new Test(), inspectableObjectName, JavascriptInter
face.class); |
884 | 884 |
885 assertEquals("m1,m2", executeJavaScriptAndGetStringResult( | 885 assertEquals("m1,m2", executeJavaScriptAndGetStringResult( |
886 String.format(jsObjectKeysTestTemplate, inspectableObjec
tName))); | 886 String.format(jsObjectKeysTestTemplate, inspectableObjec
tName))); |
887 assertEquals("m1,m2", executeJavaScriptAndGetStringResult( | 887 assertEquals("m1,m2", executeJavaScriptAndGetStringResult( |
888 String.format(jsForInTestTemplate, inspectableObjectName
))); | 888 String.format(jsForInTestTemplate, inspectableObjectName
))); |
(...skipping 13 matching lines...) Expand all Loading... |
902 String.format(jsForInTestTemplate, nonInspectableObjectN
ame))); | 902 String.format(jsForInTestTemplate, nonInspectableObjectN
ame))); |
903 } | 903 } |
904 | 904 |
905 @SmallTest | 905 @SmallTest |
906 @Feature({"AndroidWebView", "Android-JavaBridge"}) | 906 @Feature({"AndroidWebView", "Android-JavaBridge"}) |
907 public void testAccessToObjectGetClassIsBlocked() throws Throwable { | 907 public void testAccessToObjectGetClassIsBlocked() throws Throwable { |
908 injectObjectAndReload(new Object(), "testObject"); | 908 injectObjectAndReload(new Object(), "testObject"); |
909 assertEquals("function", executeJavaScriptAndGetStringResult("typeof tes
tObject.getClass")); | 909 assertEquals("function", executeJavaScriptAndGetStringResult("typeof tes
tObject.getClass")); |
910 assertRaisesException("testObject.getClass()"); | 910 assertRaisesException("testObject.getClass()"); |
911 } | 911 } |
| 912 |
| 913 @SmallTest |
| 914 @Feature({"AndroidWebView", "Android-JavaBridge"}) |
| 915 public void testReplaceJavascriptInterface() throws Throwable { |
| 916 class Test { |
| 917 public Test(int value) { |
| 918 mValue = value; |
| 919 } |
| 920 @JavascriptInterface |
| 921 public int getValue() { |
| 922 return mValue; |
| 923 } |
| 924 private int mValue; |
| 925 } |
| 926 injectObjectAndReload(new Test(13), "testObject"); |
| 927 assertEquals("13", executeJavaScriptAndGetStringResult("testObject.getVa
lue()")); |
| 928 // The documentation doesn't specify, what happens if the embedder is tr
ying |
| 929 // to inject a different object under the same name. The current impleme
ntation |
| 930 // simply replaces the old object with the new one. |
| 931 injectObjectAndReload(new Test(42), "testObject"); |
| 932 assertEquals("42", executeJavaScriptAndGetStringResult("testObject.getVa
lue()")); |
| 933 } |
912 } | 934 } |
OLD | NEW |