Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(82)

Side by Side Diff: content/public/android/javatests/src/org/chromium/content/browser/JavaBridgeBasicsTest.java

Issue 2766393004: Convert most of the rest of instrumentation tests in content (Closed)
Patch Set: Keep @CommenLineFlags Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 static org.chromium.base.test.util.ScalableTimeout.scaleTimeout; 7 import static org.chromium.base.test.util.ScalableTimeout.scaleTimeout;
8 8
9 import android.support.test.InstrumentationRegistry;
9 import android.support.test.filters.SmallTest; 10 import android.support.test.filters.SmallTest;
10 11
11 import junit.framework.Assert; 12 import org.junit.Assert;
13 import org.junit.Before;
14 import org.junit.Rule;
15 import org.junit.Test;
16 import org.junit.runner.RunWith;
12 17
13 import org.chromium.base.annotations.SuppressFBWarnings; 18 import org.chromium.base.annotations.SuppressFBWarnings;
19 import org.chromium.base.test.BaseJUnit4ClassRunner;
14 import org.chromium.base.test.util.CommandLineFlags; 20 import org.chromium.base.test.util.CommandLineFlags;
15 import org.chromium.base.test.util.Feature; 21 import org.chromium.base.test.util.Feature;
16 import org.chromium.content.browser.JavaBridgeTestCommon.Controller; 22 import org.chromium.content.browser.JavaBridgeTestCommon.Controller;
17 import org.chromium.content.browser.test.util.TestCallbackHelperContainer; 23 import org.chromium.content.browser.test.util.TestCallbackHelperContainer;
18 import org.chromium.content_public.browser.LoadUrlParams; 24 import org.chromium.content_public.browser.LoadUrlParams;
19 25
20 import java.lang.annotation.ElementType; 26 import java.lang.annotation.ElementType;
21 import java.lang.annotation.Retention; 27 import java.lang.annotation.Retention;
22 import java.lang.annotation.RetentionPolicy; 28 import java.lang.annotation.RetentionPolicy;
23 import java.lang.annotation.Target; 29 import java.lang.annotation.Target;
24 import java.lang.ref.WeakReference; 30 import java.lang.ref.WeakReference;
25 import java.util.concurrent.CountDownLatch; 31 import java.util.concurrent.CountDownLatch;
26 32
27 /** 33 /**
28 * Part of the test suite for the Java Bridge. Tests a number of features includ ing ... 34 * Part of the test suite for the Java Bridge. Tests a number of features includ ing ...
29 * - The type of injected objects 35 * - The type of injected objects
30 * - The type of their methods 36 * - The type of their methods
31 * - Replacing objects 37 * - Replacing objects
32 * - Removing objects 38 * - Removing objects
33 * - Access control 39 * - Access control
34 * - Calling methods on returned objects 40 * - Calling methods on returned objects
35 * - Multiply injected objects 41 * - Multiply injected objects
36 * - Threading 42 * - Threading
37 * - Inheritance 43 * - Inheritance
38 */ 44 */
45 @RunWith(BaseJUnit4ClassRunner.class)
39 @SuppressFBWarnings( 46 @SuppressFBWarnings(
40 {"UMAC_UNCALLABLE_METHOD_OF_ANONYMOUS_CLASS", "URF_UNREAD_PUBLIC_OR_PROT ECTED_FIELD"}) 47 {"UMAC_UNCALLABLE_METHOD_OF_ANONYMOUS_CLASS", "URF_UNREAD_PUBLIC_OR_PROT ECTED_FIELD"})
41 public class JavaBridgeBasicsTest extends JavaBridgeTestBase { 48 public class JavaBridgeBasicsTest {
49 @Rule
50 public JavaBridgeActivityTestRule mActivityTestRule = new JavaBridgeActivity TestRule(false);
51
42 @SuppressFBWarnings("CHROMIUM_SYNCHRONIZED_METHOD") 52 @SuppressFBWarnings("CHROMIUM_SYNCHRONIZED_METHOD")
43 private static class TestController extends Controller { 53 private static class TestController extends Controller {
44 private int mIntValue; 54 private int mIntValue;
45 private long mLongValue; 55 private long mLongValue;
46 private String mStringValue; 56 private String mStringValue;
47 private boolean mBooleanValue; 57 private boolean mBooleanValue;
48 58
49 public synchronized void setIntValue(int x) { 59 public synchronized void setIntValue(int x) {
50 mIntValue = x; 60 mIntValue = x;
51 notifyResultIsReady(); 61 notifyResultIsReady();
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
86 } 96 }
87 97
88 private static class ObjectWithStaticMethod { 98 private static class ObjectWithStaticMethod {
89 public static String staticMethod() { 99 public static String staticMethod() {
90 return "foo"; 100 return "foo";
91 } 101 }
92 } 102 }
93 103
94 TestController mTestController; 104 TestController mTestController;
95 105
96 @Override 106 @Before
97 protected void setUp() throws Exception { 107 public void setUp() throws Exception {
98 super.setUp(); 108 mActivityTestRule.setUpContentView();
99 mTestController = new TestController(); 109 mTestController = new TestController();
100 injectObjectAndReload(mTestController, "testController"); 110 mActivityTestRule.injectObjectAndReload(mTestController, "testController ");
101 } 111 }
102 112
103 // Note that this requires that we can pass a JavaScript string to Java. 113 // Note that this requires that we can pass a JavaScript string to Java.
104 protected String executeJavaScriptAndGetStringResult(String script) throws T hrowable { 114 protected String executeJavaScriptAndGetStringResult(String script) throws T hrowable {
105 executeJavaScript("testController.setStringValue(" + script + ");"); 115 mActivityTestRule.executeJavaScript("testController.setStringValue(" + s cript + ");");
106 return mTestController.waitForStringValue(); 116 return mTestController.waitForStringValue();
107 } 117 }
108 118
109 // Note that this requires that we can pass a JavaScript boolean to Java. 119 // Note that this requires that we can pass a JavaScript boolean to Java.
110 private void executeAndSetIfException(String script) throws Throwable { 120 private void executeAndSetIfException(String script) throws Throwable {
111 executeJavaScript("try {" 121 mActivityTestRule.executeJavaScript("try {" + script + ";"
112 + script + ";"
113 + " testController.setBooleanValue(false);" 122 + " testController.setBooleanValue(false);"
114 + "} catch (exception) {" 123 + "} catch (exception) {"
115 + " testController.setBooleanValue(true);" 124 + " testController.setBooleanValue(true);"
116 + "}"); 125 + "}");
117 } 126 }
118 127
119 private void assertRaisesException(String script) throws Throwable { 128 private void assertRaisesException(String script) throws Throwable {
120 executeAndSetIfException(script); 129 executeAndSetIfException(script);
121 assertTrue(mTestController.waitForBooleanValue()); 130 Assert.assertTrue(mTestController.waitForBooleanValue());
122 } 131 }
123 132
124 private void assertNoRaisedException(String script) throws Throwable { 133 private void assertNoRaisedException(String script) throws Throwable {
125 executeAndSetIfException(script); 134 executeAndSetIfException(script);
126 assertFalse(mTestController.waitForBooleanValue()); 135 Assert.assertFalse(mTestController.waitForBooleanValue());
127 } 136 }
128 137
138 @Test
129 @SmallTest 139 @SmallTest
130 @Feature({"AndroidWebView", "Android-JavaBridge"}) 140 @Feature({"AndroidWebView", "Android-JavaBridge"})
131 public void testTypeOfInjectedObject() throws Throwable { 141 public void testTypeOfInjectedObject() throws Throwable {
132 assertEquals("object", executeJavaScriptAndGetStringResult("typeof testC ontroller")); 142 Assert.assertEquals("object", executeJavaScriptAndGetStringResult("typeo f testController"));
133 } 143 }
134 144
145 @Test
135 @SmallTest 146 @SmallTest
136 @Feature({"AndroidWebView", "Android-JavaBridge"}) 147 @Feature({"AndroidWebView", "Android-JavaBridge"})
137 public void testAdditionNotReflectedUntilReload() throws Throwable { 148 public void testAdditionNotReflectedUntilReload() throws Throwable {
138 assertEquals("undefined", executeJavaScriptAndGetStringResult("typeof te stObject")); 149 Assert.assertEquals("undefined", executeJavaScriptAndGetStringResult("ty peof testObject"));
139 runTestOnUiThread(new Runnable() { 150 InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable( ) {
140 @Override 151 @Override
141 public void run() { 152 public void run() {
142 getContentViewCore().addPossiblyUnsafeJavascriptInterface( 153 mActivityTestRule.getContentViewCore().addPossiblyUnsafeJavascri ptInterface(
143 new Object(), "testObject", null); 154 new Object(), "testObject", null);
144 } 155 }
145 }); 156 });
146 assertEquals("undefined", executeJavaScriptAndGetStringResult("typeof te stObject")); 157 Assert.assertEquals("undefined", executeJavaScriptAndGetStringResult("ty peof testObject"));
147 synchronousPageReload(); 158 mActivityTestRule.synchronousPageReload();
148 assertEquals("object", executeJavaScriptAndGetStringResult("typeof testO bject")); 159 Assert.assertEquals("object", executeJavaScriptAndGetStringResult("typeo f testObject"));
149 } 160 }
150 161
162 @Test
151 @SmallTest 163 @SmallTest
152 @Feature({"AndroidWebView", "Android-JavaBridge"}) 164 @Feature({"AndroidWebView", "Android-JavaBridge"})
153 public void testRemovalNotReflectedUntilReload() throws Throwable { 165 public void testRemovalNotReflectedUntilReload() throws Throwable {
154 injectObjectAndReload(new Object() { 166 mActivityTestRule.injectObjectAndReload(new Object() {
155 public void method() { 167 public void method() {
156 mTestController.setStringValue("I'm here"); 168 mTestController.setStringValue("I'm here");
157 } 169 }
158 }, "testObject"); 170 }, "testObject");
159 assertEquals("object", executeJavaScriptAndGetStringResult("typeof testO bject")); 171 Assert.assertEquals("object", executeJavaScriptAndGetStringResult("typeo f testObject"));
160 executeJavaScript("testObject.method()"); 172 mActivityTestRule.executeJavaScript("testObject.method()");
161 assertEquals("I'm here", mTestController.waitForStringValue()); 173 Assert.assertEquals("I'm here", mTestController.waitForStringValue());
162 runTestOnUiThread(new Runnable() { 174 InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable( ) {
163 @Override 175 @Override
164 public void run() { 176 public void run() {
165 getContentViewCore().removeJavascriptInterface("testObject"); 177 mActivityTestRule.getContentViewCore().removeJavascriptInterface ("testObject");
166 } 178 }
167 }); 179 });
168 // Check that the Java object is being held by the Java bridge, thus it' s not 180 // Check that the Java object is being held by the Java bridge, thus it' s not
169 // collected. Note that despite that what JavaDoc says about invoking "g c()", both Dalvik 181 // collected. Note that despite that what JavaDoc says about invoking "g c()", both Dalvik
170 // and ART actually run the collector if called via Runtime. 182 // and ART actually run the collector if called via Runtime.
171 Runtime.getRuntime().gc(); 183 Runtime.getRuntime().gc();
172 assertEquals("object", executeJavaScriptAndGetStringResult("typeof testO bject")); 184 Assert.assertEquals("object", executeJavaScriptAndGetStringResult("typeo f testObject"));
173 executeJavaScript("testObject.method()"); 185 mActivityTestRule.executeJavaScript("testObject.method()");
174 assertEquals("I'm here", mTestController.waitForStringValue()); 186 Assert.assertEquals("I'm here", mTestController.waitForStringValue());
175 synchronousPageReload(); 187 mActivityTestRule.synchronousPageReload();
176 assertEquals("undefined", executeJavaScriptAndGetStringResult("typeof te stObject")); 188 Assert.assertEquals("undefined", executeJavaScriptAndGetStringResult("ty peof testObject"));
177 } 189 }
178 190
191 @Test
179 @SmallTest 192 @SmallTest
180 @Feature({"AndroidWebView", "Android-JavaBridge"}) 193 @Feature({"AndroidWebView", "Android-JavaBridge"})
181 public void testRemoveObjectNotAdded() throws Throwable { 194 public void testRemoveObjectNotAdded() throws Throwable {
182 TestCallbackHelperContainer.OnPageFinishedHelper onPageFinishedHelper = 195 TestCallbackHelperContainer.OnPageFinishedHelper onPageFinishedHelper =
183 getTestCallBackHelperContainer().getOnPageFinishedHelper(); 196 mActivityTestRule.getTestCallBackHelperContainer().getOnPageFini shedHelper();
184 int currentCallCount = onPageFinishedHelper.getCallCount(); 197 int currentCallCount = onPageFinishedHelper.getCallCount();
185 runTestOnUiThread(new Runnable() { 198 InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable( ) {
186 @Override 199 @Override
187 public void run() { 200 public void run() {
188 getContentViewCore().removeJavascriptInterface("foo"); 201 mActivityTestRule.getContentViewCore().removeJavascriptInterface ("foo");
189 getContentViewCore().getWebContents().getNavigationController(). reload(true); 202 mActivityTestRule.getContentViewCore()
203 .getWebContents()
204 .getNavigationController()
205 .reload(true);
190 } 206 }
191 }); 207 });
192 onPageFinishedHelper.waitForCallback(currentCallCount); 208 onPageFinishedHelper.waitForCallback(currentCallCount);
193 assertEquals("undefined", executeJavaScriptAndGetStringResult("typeof fo o")); 209 Assert.assertEquals("undefined", executeJavaScriptAndGetStringResult("ty peof foo"));
194 } 210 }
195 211
212 @Test
196 @SmallTest 213 @SmallTest
197 @Feature({"AndroidWebView", "Android-JavaBridge"}) 214 @Feature({"AndroidWebView", "Android-JavaBridge"})
198 public void testTypeOfMethod() throws Throwable { 215 public void testTypeOfMethod() throws Throwable {
199 assertEquals("function", 216 Assert.assertEquals("function",
200 executeJavaScriptAndGetStringResult("typeof testController.setSt ringValue")); 217 executeJavaScriptAndGetStringResult("typeof testController.setSt ringValue"));
201 } 218 }
202 219
220 @Test
203 @SmallTest 221 @SmallTest
204 @Feature({"AndroidWebView", "Android-JavaBridge"}) 222 @Feature({"AndroidWebView", "Android-JavaBridge"})
205 public void testTypeOfInvalidMethod() throws Throwable { 223 public void testTypeOfInvalidMethod() throws Throwable {
206 assertEquals("undefined", executeJavaScriptAndGetStringResult("typeof te stController.foo")); 224 Assert.assertEquals(
225 "undefined", executeJavaScriptAndGetStringResult("typeof testCon troller.foo"));
207 } 226 }
208 227
228 @Test
209 @SmallTest 229 @SmallTest
210 @Feature({"AndroidWebView", "Android-JavaBridge"}) 230 @Feature({"AndroidWebView", "Android-JavaBridge"})
211 public void testCallingInvalidMethodRaisesException() throws Throwable { 231 public void testCallingInvalidMethodRaisesException() throws Throwable {
212 assertRaisesException("testController.foo()"); 232 assertRaisesException("testController.foo()");
213 } 233 }
214 234
235 @Test
215 @SmallTest 236 @SmallTest
216 @Feature({"AndroidWebView", "Android-JavaBridge"}) 237 @Feature({"AndroidWebView", "Android-JavaBridge"})
217 public void testUncaughtJavaExceptionRaisesJavaScriptException() throws Thro wable { 238 public void testUncaughtJavaExceptionRaisesJavaScriptException() throws Thro wable {
218 injectObjectAndReload(new Object() { 239 mActivityTestRule.injectObjectAndReload(new Object() {
219 public void method() { 240 public void method() {
220 throw new RuntimeException("foo"); 241 throw new RuntimeException("foo");
221 } 242 }
222 }, "testObject"); 243 }, "testObject");
223 assertRaisesException("testObject.method()"); 244 assertRaisesException("testObject.method()");
224 } 245 }
225 246
247 @Test
226 @SmallTest 248 @SmallTest
227 @Feature({"AndroidWebView", "Android-JavaBridge"}) 249 @Feature({"AndroidWebView", "Android-JavaBridge"})
228 public void testCallingAsConstructorRaisesException() throws Throwable { 250 public void testCallingAsConstructorRaisesException() throws Throwable {
229 assertRaisesException("new testController.setStringValue('foo')"); 251 assertRaisesException("new testController.setStringValue('foo')");
230 } 252 }
231 253
254 @Test
232 @SmallTest 255 @SmallTest
233 @Feature({"AndroidWebView", "Android-JavaBridge"}) 256 @Feature({"AndroidWebView", "Android-JavaBridge"})
234 public void testCallingOnNonInjectedObjectRaisesException() throws Throwable { 257 public void testCallingOnNonInjectedObjectRaisesException() throws Throwable {
235 assertRaisesException("testController.setStringValue.call({}, 'foo')"); 258 assertRaisesException("testController.setStringValue.call({}, 'foo')");
236 } 259 }
237 260
261 @Test
238 @SmallTest 262 @SmallTest
239 @Feature({"AndroidWebView", "Android-JavaBridge"}) 263 @Feature({"AndroidWebView", "Android-JavaBridge"})
240 public void testCallingOnInstanceOfOtherClassRaisesException() throws Throwa ble { 264 public void testCallingOnInstanceOfOtherClassRaisesException() throws Throwa ble {
241 injectObjectAndReload(new Object(), "testObject"); 265 mActivityTestRule.injectObjectAndReload(new Object(), "testObject");
242 assertEquals("object", executeJavaScriptAndGetStringResult("typeof testO bject")); 266 Assert.assertEquals("object", executeJavaScriptAndGetStringResult("typeo f testObject"));
243 assertEquals("object", executeJavaScriptAndGetStringResult("typeof testC ontroller")); 267 Assert.assertEquals("object", executeJavaScriptAndGetStringResult("typeo f testController"));
244 assertEquals("function", 268 Assert.assertEquals("function",
245 executeJavaScriptAndGetStringResult("typeof testController.setSt ringValue")); 269 executeJavaScriptAndGetStringResult("typeof testController.setSt ringValue"));
246 assertRaisesException("testController.setStringValue.call(testObject, 'f oo')"); 270 assertRaisesException("testController.setStringValue.call(testObject, 'f oo')");
247 } 271 }
248 272
249 // Note that this requires that we can pass a JavaScript string to Java. 273 // Note that this requires that we can pass a JavaScript string to Java.
274 @Test
250 @SmallTest 275 @SmallTest
251 @Feature({"AndroidWebView", "Android-JavaBridge"}) 276 @Feature({"AndroidWebView", "Android-JavaBridge"})
252 public void testTypeOfStaticMethod() throws Throwable { 277 public void testTypeOfStaticMethod() throws Throwable {
253 injectObjectAndReload(new ObjectWithStaticMethod(), "testObject"); 278 mActivityTestRule.injectObjectAndReload(new ObjectWithStaticMethod(), "t estObject");
254 executeJavaScript("testController.setStringValue(typeof testObject.stati cMethod)"); 279 mActivityTestRule.executeJavaScript(
255 assertEquals("function", mTestController.waitForStringValue()); 280 "testController.setStringValue(typeof testObject.staticMethod)") ;
281 Assert.assertEquals("function", mTestController.waitForStringValue());
256 } 282 }
257 283
258 // Note that this requires that we can pass a JavaScript string to Java. 284 // Note that this requires that we can pass a JavaScript string to Java.
285 @Test
259 @SmallTest 286 @SmallTest
260 @Feature({"AndroidWebView", "Android-JavaBridge"}) 287 @Feature({"AndroidWebView", "Android-JavaBridge"})
261 public void testCallStaticMethod() throws Throwable { 288 public void testCallStaticMethod() throws Throwable {
262 injectObjectAndReload(new ObjectWithStaticMethod(), "testObject"); 289 mActivityTestRule.injectObjectAndReload(new ObjectWithStaticMethod(), "t estObject");
263 executeJavaScript("testController.setStringValue(testObject.staticMethod ())"); 290 mActivityTestRule.executeJavaScript(
264 assertEquals("foo", mTestController.waitForStringValue()); 291 "testController.setStringValue(testObject.staticMethod())");
292 Assert.assertEquals("foo", mTestController.waitForStringValue());
265 } 293 }
266 294
295 @Test
267 @SmallTest 296 @SmallTest
268 @Feature({"AndroidWebView", "Android-JavaBridge"}) 297 @Feature({"AndroidWebView", "Android-JavaBridge"})
269 public void testPrivateMethodNotExposed() throws Throwable { 298 public void testPrivateMethodNotExposed() throws Throwable {
270 injectObjectAndReload(new Object() { 299 mActivityTestRule.injectObjectAndReload(new Object() {
271 private void method() {} 300 private void method() {}
272 protected void method2() {} 301 protected void method2() {}
273 }, "testObject"); 302 }, "testObject");
274 assertEquals("undefined", 303 Assert.assertEquals(
275 executeJavaScriptAndGetStringResult("typeof testObject.method")) ; 304 "undefined", executeJavaScriptAndGetStringResult("typeof testObj ect.method"));
276 assertEquals("undefined", 305 Assert.assertEquals(
277 executeJavaScriptAndGetStringResult("typeof testObject.method2") ); 306 "undefined", executeJavaScriptAndGetStringResult("typeof testObj ect.method2"));
278 } 307 }
279 308
309 @Test
280 @SmallTest 310 @SmallTest
281 @Feature({"AndroidWebView", "Android-JavaBridge"}) 311 @Feature({"AndroidWebView", "Android-JavaBridge"})
282 public void testReplaceInjectedObject() throws Throwable { 312 public void testReplaceInjectedObject() throws Throwable {
283 injectObjectAndReload(new Object() { 313 mActivityTestRule.injectObjectAndReload(new Object() {
284 public void method() { 314 public void method() {
285 mTestController.setStringValue("object 1"); 315 mTestController.setStringValue("object 1");
286 } 316 }
287 }, "testObject"); 317 }, "testObject");
288 executeJavaScript("testObject.method()"); 318 mActivityTestRule.executeJavaScript("testObject.method()");
289 assertEquals("object 1", mTestController.waitForStringValue()); 319 Assert.assertEquals("object 1", mTestController.waitForStringValue());
290 320
291 injectObjectAndReload(new Object() { 321 mActivityTestRule.injectObjectAndReload(new Object() {
292 public void method() { 322 public void method() {
293 mTestController.setStringValue("object 2"); 323 mTestController.setStringValue("object 2");
294 } 324 }
295 }, "testObject"); 325 }, "testObject");
296 executeJavaScript("testObject.method()"); 326 mActivityTestRule.executeJavaScript("testObject.method()");
297 assertEquals("object 2", mTestController.waitForStringValue()); 327 Assert.assertEquals("object 2", mTestController.waitForStringValue());
298 } 328 }
299 329
330 @Test
300 @SmallTest 331 @SmallTest
301 @Feature({"AndroidWebView", "Android-JavaBridge"}) 332 @Feature({"AndroidWebView", "Android-JavaBridge"})
302 public void testInjectNullObjectIsIgnored() throws Throwable { 333 public void testInjectNullObjectIsIgnored() throws Throwable {
303 injectObjectAndReload(null, "testObject"); 334 mActivityTestRule.injectObjectAndReload(null, "testObject");
304 assertEquals("undefined", executeJavaScriptAndGetStringResult("typeof te stObject")); 335 Assert.assertEquals("undefined", executeJavaScriptAndGetStringResult("ty peof testObject"));
305 } 336 }
306 337
338 @Test
307 @SmallTest 339 @SmallTest
308 @Feature({"AndroidWebView", "Android-JavaBridge"}) 340 @Feature({"AndroidWebView", "Android-JavaBridge"})
309 public void testReplaceInjectedObjectWithNullObjectIsIgnored() throws Throwa ble { 341 public void testReplaceInjectedObjectWithNullObjectIsIgnored() throws Throwa ble {
310 injectObjectAndReload(new Object(), "testObject"); 342 mActivityTestRule.injectObjectAndReload(new Object(), "testObject");
311 assertEquals("object", executeJavaScriptAndGetStringResult("typeof testO bject")); 343 Assert.assertEquals("object", executeJavaScriptAndGetStringResult("typeo f testObject"));
312 injectObjectAndReload(null, "testObject"); 344 mActivityTestRule.injectObjectAndReload(null, "testObject");
313 assertEquals("object", executeJavaScriptAndGetStringResult("typeof testO bject")); 345 Assert.assertEquals("object", executeJavaScriptAndGetStringResult("typeo f testObject"));
314 } 346 }
315 347
348 @Test
316 @SmallTest 349 @SmallTest
317 @Feature({"AndroidWebView", "Android-JavaBridge"}) 350 @Feature({"AndroidWebView", "Android-JavaBridge"})
318 public void testCallOverloadedMethodWithDifferentNumberOfArguments() throws Throwable { 351 public void testCallOverloadedMethodWithDifferentNumberOfArguments() throws Throwable {
319 injectObjectAndReload(new Object() { 352 mActivityTestRule.injectObjectAndReload(new Object() {
320 public void method() { 353 public void method() {
321 mTestController.setStringValue("0 args"); 354 mTestController.setStringValue("0 args");
322 } 355 }
323 356
324 public void method(int x) { 357 public void method(int x) {
325 mTestController.setStringValue("1 arg"); 358 mTestController.setStringValue("1 arg");
326 } 359 }
327 360
328 public void method(int x, int y) { 361 public void method(int x, int y) {
329 mTestController.setStringValue("2 args"); 362 mTestController.setStringValue("2 args");
330 } 363 }
331 }, "testObject"); 364 }, "testObject");
332 executeJavaScript("testObject.method()"); 365 mActivityTestRule.executeJavaScript("testObject.method()");
333 assertEquals("0 args", mTestController.waitForStringValue()); 366 Assert.assertEquals("0 args", mTestController.waitForStringValue());
334 executeJavaScript("testObject.method(42)"); 367 mActivityTestRule.executeJavaScript("testObject.method(42)");
335 assertEquals("1 arg", mTestController.waitForStringValue()); 368 Assert.assertEquals("1 arg", mTestController.waitForStringValue());
336 executeJavaScript("testObject.method(null)"); 369 mActivityTestRule.executeJavaScript("testObject.method(null)");
337 assertEquals("1 arg", mTestController.waitForStringValue()); 370 Assert.assertEquals("1 arg", mTestController.waitForStringValue());
338 executeJavaScript("testObject.method(undefined)"); 371 mActivityTestRule.executeJavaScript("testObject.method(undefined)");
339 assertEquals("1 arg", mTestController.waitForStringValue()); 372 Assert.assertEquals("1 arg", mTestController.waitForStringValue());
340 executeJavaScript("testObject.method(42, 42)"); 373 mActivityTestRule.executeJavaScript("testObject.method(42, 42)");
341 assertEquals("2 args", mTestController.waitForStringValue()); 374 Assert.assertEquals("2 args", mTestController.waitForStringValue());
342 } 375 }
343 376
377 @Test
344 @SmallTest 378 @SmallTest
345 @Feature({"AndroidWebView", "Android-JavaBridge"}) 379 @Feature({"AndroidWebView", "Android-JavaBridge"})
346 public void testCallMethodWithWrongNumberOfArgumentsRaisesException() throws Throwable { 380 public void testCallMethodWithWrongNumberOfArgumentsRaisesException() throws Throwable {
347 assertRaisesException("testController.setIntValue()"); 381 assertRaisesException("testController.setIntValue()");
348 assertRaisesException("testController.setIntValue(42, 42)"); 382 assertRaisesException("testController.setIntValue(42, 42)");
349 } 383 }
350 384
385 @Test
351 @SmallTest 386 @SmallTest
352 @Feature({"AndroidWebView", "Android-JavaBridge"}) 387 @Feature({"AndroidWebView", "Android-JavaBridge"})
353 public void testObjectPersistsAcrossPageLoads() throws Throwable { 388 public void testObjectPersistsAcrossPageLoads() throws Throwable {
354 assertEquals("object", executeJavaScriptAndGetStringResult("typeof testC ontroller")); 389 Assert.assertEquals("object", executeJavaScriptAndGetStringResult("typeo f testController"));
355 synchronousPageReload(); 390 mActivityTestRule.synchronousPageReload();
356 assertEquals("object", executeJavaScriptAndGetStringResult("typeof testC ontroller")); 391 Assert.assertEquals("object", executeJavaScriptAndGetStringResult("typeo f testController"));
357 } 392 }
358 393
394 @Test
359 @SmallTest 395 @SmallTest
360 @Feature({"AndroidWebView", "Android-JavaBridge"}) 396 @Feature({"AndroidWebView", "Android-JavaBridge"})
361 public void testCustomPropertiesCleanedUpOnPageReloads() throws Throwable { 397 public void testCustomPropertiesCleanedUpOnPageReloads() throws Throwable {
362 assertEquals("object", executeJavaScriptAndGetStringResult("typeof testC ontroller")); 398 Assert.assertEquals("object", executeJavaScriptAndGetStringResult("typeo f testController"));
363 executeJavaScript("testController.myProperty = 42;"); 399 mActivityTestRule.executeJavaScript("testController.myProperty = 42;");
364 assertEquals("42", executeJavaScriptAndGetStringResult("testController.m yProperty")); 400 Assert.assertEquals("42", executeJavaScriptAndGetStringResult("testContr oller.myProperty"));
365 synchronousPageReload(); 401 mActivityTestRule.synchronousPageReload();
366 assertEquals("object", executeJavaScriptAndGetStringResult("typeof testC ontroller")); 402 Assert.assertEquals("object", executeJavaScriptAndGetStringResult("typeo f testController"));
367 assertEquals("undefined", executeJavaScriptAndGetStringResult("testContr oller.myProperty")); 403 Assert.assertEquals(
404 "undefined", executeJavaScriptAndGetStringResult("testController .myProperty"));
368 } 405 }
369 406
407 @Test
370 @SmallTest 408 @SmallTest
371 @Feature({"AndroidWebView", "Android-JavaBridge"}) 409 @Feature({"AndroidWebView", "Android-JavaBridge"})
372 public void testSameObjectInjectedMultipleTimes() throws Throwable { 410 public void testSameObjectInjectedMultipleTimes() throws Throwable {
373 class TestObject { 411 class TestObject {
374 private int mNumMethodInvocations; 412 private int mNumMethodInvocations;
375 413
376 public void method() { 414 public void method() {
377 mTestController.setIntValue(++mNumMethodInvocations); 415 mTestController.setIntValue(++mNumMethodInvocations);
378 } 416 }
379 } 417 }
380 final TestObject testObject = new TestObject(); 418 final TestObject testObject = new TestObject();
381 injectObjectsAndReload(testObject, "testObject1", testObject, "testObjec t2", null); 419 mActivityTestRule.injectObjectsAndReload(
382 executeJavaScript("testObject1.method()"); 420 testObject, "testObject1", testObject, "testObject2", null);
383 assertEquals(1, mTestController.waitForIntValue()); 421 mActivityTestRule.executeJavaScript("testObject1.method()");
384 executeJavaScript("testObject2.method()"); 422 Assert.assertEquals(1, mTestController.waitForIntValue());
385 assertEquals(2, mTestController.waitForIntValue()); 423 mActivityTestRule.executeJavaScript("testObject2.method()");
424 Assert.assertEquals(2, mTestController.waitForIntValue());
386 } 425 }
387 426
427 @Test
388 @SmallTest 428 @SmallTest
389 @Feature({"AndroidWebView", "Android-JavaBridge"}) 429 @Feature({"AndroidWebView", "Android-JavaBridge"})
390 public void testCallMethodOnReturnedObject() throws Throwable { 430 public void testCallMethodOnReturnedObject() throws Throwable {
391 injectObjectAndReload(new Object() { 431 mActivityTestRule.injectObjectAndReload(new Object() {
392 public Object getInnerObject() { 432 public Object getInnerObject() {
393 return new Object() { 433 return new Object() {
394 public void method(int x) { 434 public void method(int x) {
395 mTestController.setIntValue(x); 435 mTestController.setIntValue(x);
396 } 436 }
397 }; 437 };
398 } 438 }
399 }, "testObject"); 439 }, "testObject");
400 executeJavaScript("testObject.getInnerObject().method(42)"); 440 mActivityTestRule.executeJavaScript("testObject.getInnerObject().method( 42)");
401 assertEquals(42, mTestController.waitForIntValue()); 441 Assert.assertEquals(42, mTestController.waitForIntValue());
402 } 442 }
403 443
444 @Test
404 @SmallTest 445 @SmallTest
405 @Feature({"AndroidWebView", "Android-JavaBridge"}) 446 @Feature({"AndroidWebView", "Android-JavaBridge"})
406 public void testReturnedObjectInjectedElsewhere() throws Throwable { 447 public void testReturnedObjectInjectedElsewhere() throws Throwable {
407 class InnerObject { 448 class InnerObject {
408 private int mNumMethodInvocations; 449 private int mNumMethodInvocations;
409 450
410 public void method() { 451 public void method() {
411 mTestController.setIntValue(++mNumMethodInvocations); 452 mTestController.setIntValue(++mNumMethodInvocations);
412 } 453 }
413 } 454 }
414 final InnerObject innerObject = new InnerObject(); 455 final InnerObject innerObject = new InnerObject();
415 final Object object = new Object() { 456 final Object object = new Object() {
416 public InnerObject getInnerObject() { 457 public InnerObject getInnerObject() {
417 return innerObject; 458 return innerObject;
418 } 459 }
419 }; 460 };
420 injectObjectsAndReload(object, "testObject", innerObject, "innerObject", null); 461 mActivityTestRule.injectObjectsAndReload(
421 executeJavaScript("testObject.getInnerObject().method()"); 462 object, "testObject", innerObject, "innerObject", null);
422 assertEquals(1, mTestController.waitForIntValue()); 463 mActivityTestRule.executeJavaScript("testObject.getInnerObject().method( )");
423 executeJavaScript("innerObject.method()"); 464 Assert.assertEquals(1, mTestController.waitForIntValue());
424 assertEquals(2, mTestController.waitForIntValue()); 465 mActivityTestRule.executeJavaScript("innerObject.method()");
466 Assert.assertEquals(2, mTestController.waitForIntValue());
425 } 467 }
426 468
427 // Verify that Java objects returned from bridge object methods are derefere nced 469 // Verify that Java objects returned from bridge object methods are derefere nced
428 // on the Java side once they have been fully dereferenced on the JS side. 470 // on the Java side once they have been fully dereferenced on the JS side.
429 // Failing this test would mean that methods returning objects effectively c reate a memory 471 // Failing this test would mean that methods returning objects effectively c reate a memory
430 // leak. 472 // leak.
473 @Test
431 @SmallTest 474 @SmallTest
432 @Feature({"AndroidWebView", "Android-JavaBridge"}) 475 @Feature({"AndroidWebView", "Android-JavaBridge"})
433 @CommandLineFlags.Add("js-flags=--expose-gc") 476 @CommandLineFlags.Add("js-flags=--expose-gc")
434 public void testReturnedObjectIsGarbageCollected() throws Throwable { 477 public void testReturnedObjectIsGarbageCollected() throws Throwable {
435 // Make sure V8 exposes "gc" property on the global object (enabled with --expose-gc flag) 478 Assert.assertEquals("function", executeJavaScriptAndGetStringResult("typ eof gc"));
436 assertEquals("function", executeJavaScriptAndGetStringResult("typeof gc" ));
437 class InnerObject { 479 class InnerObject {
438 } 480 }
439 class TestObject { 481 class TestObject {
440 public InnerObject getInnerObject() { 482 public InnerObject getInnerObject() {
441 InnerObject inner = new InnerObject(); 483 InnerObject inner = new InnerObject();
442 mWeakRefForInner = new WeakReference<InnerObject>(inner); 484 mWeakRefForInner = new WeakReference<InnerObject>(inner);
443 return inner; 485 return inner;
444 } 486 }
445 // A weak reference is used to check InnerObject instance reachabili ty. 487 // A weak reference is used to check InnerObject instance reachabili ty.
446 WeakReference<InnerObject> mWeakRefForInner; 488 WeakReference<InnerObject> mWeakRefForInner;
447 } 489 }
448 TestObject object = new TestObject(); 490 TestObject object = new TestObject();
449 injectObjectAndReload(object, "testObject"); 491 mActivityTestRule.injectObjectAndReload(object, "testObject");
450 // Initially, store a reference to the inner object in JS to make sure i t's not 492 // Initially, store a reference to the inner object in JS to make sure i t's not
451 // garbage-collected prematurely. 493 // garbage-collected prematurely.
452 assertEquals("object", executeJavaScriptAndGetStringResult( 494 Assert.assertEquals("object",
453 "(function() { " 495 executeJavaScriptAndGetStringResult("(function() { "
454 + "globalInner = testObject.getInnerObject(); return typ eof globalInner; " 496 + "globalInner = testObject.getInnerObject(); return typ eof globalInner; "
455 + "})()")); 497 + "})()"));
456 assertTrue(object.mWeakRefForInner.get() != null); 498 Assert.assertTrue(object.mWeakRefForInner.get() != null);
457 // Check that returned Java object is being held by the Java bridge, thu s it's not 499 // Check that returned Java object is being held by the Java bridge, thu s it's not
458 // collected. Note that despite that what JavaDoc says about invoking " gc()", both Dalvik 500 // collected. Note that despite that what JavaDoc says about invoking " gc()", both Dalvik
459 // and ART actually run the collector. 501 // and ART actually run the collector.
460 Runtime.getRuntime().gc(); 502 Runtime.getRuntime().gc();
461 assertTrue(object.mWeakRefForInner.get() != null); 503 Assert.assertTrue(object.mWeakRefForInner.get() != null);
462 // Now dereference the inner object in JS and run GC to collect the inte rface object. 504 // Now dereference the inner object in JS and run GC to collect the inte rface object.
463 assertEquals("true", executeJavaScriptAndGetStringResult( 505 Assert.assertEquals("true",
464 "(function() { " 506 executeJavaScriptAndGetStringResult("(function() { "
465 + "delete globalInner; gc(); return (typeof globalInner == 'undefined'); " 507 + "delete globalInner; gc(); return (typeof globalInner == 'undefined'); "
466 + "})()")); 508 + "})()"));
467 // Force GC on the Java side again. The bridge had to release the inner object, so it must 509 // Force GC on the Java side again. The bridge had to release the inner object, so it must
468 // be collected this time. 510 // be collected this time.
469 Runtime.getRuntime().gc(); 511 Runtime.getRuntime().gc();
470 assertEquals(null, object.mWeakRefForInner.get()); 512 Assert.assertEquals(null, object.mWeakRefForInner.get());
471 } 513 }
472 514
515 @Test
473 @SmallTest 516 @SmallTest
474 @Feature({"AndroidWebView", "Android-JavaBridge"}) 517 @Feature({"AndroidWebView", "Android-JavaBridge"})
475 public void testSameReturnedObjectUsesSameWrapper() throws Throwable { 518 public void testSameReturnedObjectUsesSameWrapper() throws Throwable {
476 class InnerObject { 519 class InnerObject {
477 } 520 }
478 final InnerObject innerObject = new InnerObject(); 521 final InnerObject innerObject = new InnerObject();
479 final Object injectedTestObject = new Object() { 522 final Object injectedTestObject = new Object() {
480 public InnerObject getInnerObject() { 523 public InnerObject getInnerObject() {
481 return innerObject; 524 return innerObject;
482 } 525 }
483 }; 526 };
484 injectObjectAndReload(injectedTestObject, "injectedTestObject"); 527 mActivityTestRule.injectObjectAndReload(injectedTestObject, "injectedTes tObject");
485 executeJavaScript("inner1 = injectedTestObject.getInnerObject()"); 528 mActivityTestRule.executeJavaScript("inner1 = injectedTestObject.getInne rObject()");
486 executeJavaScript("inner2 = injectedTestObject.getInnerObject()"); 529 mActivityTestRule.executeJavaScript("inner2 = injectedTestObject.getInne rObject()");
487 assertEquals("object", executeJavaScriptAndGetStringResult("typeof inner 1")); 530 Assert.assertEquals("object", executeJavaScriptAndGetStringResult("typeo f inner1"));
488 assertEquals("object", executeJavaScriptAndGetStringResult("typeof inner 2")); 531 Assert.assertEquals("object", executeJavaScriptAndGetStringResult("typeo f inner2"));
489 assertEquals("true", executeJavaScriptAndGetStringResult("inner1 === inn er2")); 532 Assert.assertEquals("true", executeJavaScriptAndGetStringResult("inner1 === inner2"));
490 } 533 }
491 534
535 @Test
492 @SmallTest 536 @SmallTest
493 @Feature({"AndroidWebView", "Android-JavaBridge"}) 537 @Feature({"AndroidWebView", "Android-JavaBridge"})
494 public void testMethodInvokedOnBackgroundThread() throws Throwable { 538 public void testMethodInvokedOnBackgroundThread() throws Throwable {
495 injectObjectAndReload(new Object() { 539 mActivityTestRule.injectObjectAndReload(new Object() {
496 public void captureThreadId() { 540 public void captureThreadId() {
497 mTestController.setLongValue(Thread.currentThread().getId()); 541 mTestController.setLongValue(Thread.currentThread().getId());
498 } 542 }
499 }, "testObject"); 543 }, "testObject");
500 executeJavaScript("testObject.captureThreadId()"); 544 mActivityTestRule.executeJavaScript("testObject.captureThreadId()");
501 final long threadId = mTestController.waitForLongValue(); 545 final long threadId = mTestController.waitForLongValue();
502 assertFalse(threadId == Thread.currentThread().getId()); 546 Assert.assertFalse(threadId == Thread.currentThread().getId());
503 runTestOnUiThread(new Runnable() { 547 InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable( ) {
504 @Override 548 @Override
505 public void run() { 549 public void run() {
506 assertFalse(threadId == Thread.currentThread().getId()); 550 Assert.assertFalse(threadId == Thread.currentThread().getId());
507 } 551 }
508 }); 552 });
509 } 553 }
510 554
555 @Test
511 @SmallTest 556 @SmallTest
512 @Feature({"AndroidWebView", "Android-JavaBridge"}) 557 @Feature({"AndroidWebView", "Android-JavaBridge"})
513 public void testBlockingUiThreadDoesNotBlockCallsFromJs() throws Throwable { 558 public void testBlockingUiThreadDoesNotBlockCallsFromJs() throws Throwable {
514 class TestObject { 559 class TestObject {
515 private CountDownLatch mLatch; 560 private CountDownLatch mLatch;
516 public TestObject() { 561 public TestObject() {
517 mLatch = new CountDownLatch(1); 562 mLatch = new CountDownLatch(1);
518 } 563 }
519 public boolean waitOnTheLatch() throws Exception { 564 public boolean waitOnTheLatch() throws Exception {
520 return mLatch.await(scaleTimeout(10000), 565 return mLatch.await(scaleTimeout(10000),
521 java.util.concurrent.TimeUnit.MILLISECONDS); 566 java.util.concurrent.TimeUnit.MILLISECONDS);
522 } 567 }
523 public void unlockTheLatch() throws Exception { 568 public void unlockTheLatch() throws Exception {
524 mTestController.setStringValue("unlocked"); 569 mTestController.setStringValue("unlocked");
525 mLatch.countDown(); 570 mLatch.countDown();
526 } 571 }
527 } 572 }
528 final TestObject testObject = new TestObject(); 573 final TestObject testObject = new TestObject();
529 injectObjectAndReload(testObject, "testObject"); 574 mActivityTestRule.injectObjectAndReload(testObject, "testObject");
530 runTestOnUiThread(new Runnable() { 575 InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable( ) {
531 @Override 576 @Override
532 public void run() { 577 public void run() {
533 // loadUrl is asynchronous, the JS code will start running on th e renderer 578 // loadUrl is asynchronous, the JS code will start running on th e renderer
534 // thread. As soon as we exit loadUrl, the browser UI thread wil l be stuck waiting 579 // thread. As soon as we exit loadUrl, the browser UI thread wil l be stuck waiting
535 // on the latch. If blocking the browser thread blocks Java Brid ge, then the call 580 // on the latch. If blocking the browser thread blocks Java Brid ge, then the call
536 // to "unlockTheLatch()" will be executed after the waiting time out, thus the 581 // to "unlockTheLatch()" will be executed after the waiting time out, thus the
537 // string value will not yet be updated by the injected object. 582 // string value will not yet be updated by the injected object.
538 mTestController.setStringValue("locked"); 583 mTestController.setStringValue("locked");
539 getWebContents().getNavigationController().loadUrl(new LoadUrlPa rams( 584 mActivityTestRule.getWebContents().getNavigationController().loa dUrl(
540 "javascript:(function() { testObject.unlockTheLatch() }) ()")); 585 new LoadUrlParams(
586 "javascript:(function() { testObject.unlockTheLa tch() })()"));
541 try { 587 try {
542 assertTrue(testObject.waitOnTheLatch()); 588 Assert.assertTrue(testObject.waitOnTheLatch());
543 } catch (Exception e) { 589 } catch (Exception e) {
544 android.util.Log.e("JavaBridgeBasicsTest", "Wait exception", e); 590 android.util.Log.e("JavaBridgeBasicsTest", "Wait exception", e);
545 Assert.fail("Wait exception"); 591 Assert.fail("Wait exception");
546 } 592 }
547 assertEquals("unlocked", mTestController.getStringValue()); 593 Assert.assertEquals("unlocked", mTestController.getStringValue() );
548 } 594 }
549 }); 595 });
550 } 596 }
551 597
598 @Test
552 @SmallTest 599 @SmallTest
553 @Feature({"AndroidWebView", "Android-JavaBridge"}) 600 @Feature({"AndroidWebView", "Android-JavaBridge"})
554 public void testPublicInheritedMethod() throws Throwable { 601 public void testPublicInheritedMethod() throws Throwable {
555 class Base { 602 class Base {
556 public void method(int x) { 603 public void method(int x) {
557 mTestController.setIntValue(x); 604 mTestController.setIntValue(x);
558 } 605 }
559 } 606 }
560 class Derived extends Base { 607 class Derived extends Base {
561 } 608 }
562 injectObjectAndReload(new Derived(), "testObject"); 609 mActivityTestRule.injectObjectAndReload(new Derived(), "testObject");
563 assertEquals("function", executeJavaScriptAndGetStringResult("typeof tes tObject.method")); 610 Assert.assertEquals(
564 executeJavaScript("testObject.method(42)"); 611 "function", executeJavaScriptAndGetStringResult("typeof testObje ct.method"));
565 assertEquals(42, mTestController.waitForIntValue()); 612 mActivityTestRule.executeJavaScript("testObject.method(42)");
613 Assert.assertEquals(42, mTestController.waitForIntValue());
566 } 614 }
567 615
616 @Test
568 @SmallTest 617 @SmallTest
569 @Feature({"AndroidWebView", "Android-JavaBridge"}) 618 @Feature({"AndroidWebView", "Android-JavaBridge"})
570 public void testPrivateInheritedMethod() throws Throwable { 619 public void testPrivateInheritedMethod() throws Throwable {
571 class Base { 620 class Base {
572 private void method() {} 621 private void method() {}
573 } 622 }
574 class Derived extends Base { 623 class Derived extends Base {
575 } 624 }
576 injectObjectAndReload(new Derived(), "testObject"); 625 mActivityTestRule.injectObjectAndReload(new Derived(), "testObject");
577 assertEquals("undefined", executeJavaScriptAndGetStringResult("typeof te stObject.method")); 626 Assert.assertEquals(
627 "undefined", executeJavaScriptAndGetStringResult("typeof testObj ect.method"));
578 } 628 }
579 629
630 @Test
580 @SmallTest 631 @SmallTest
581 @Feature({"AndroidWebView", "Android-JavaBridge"}) 632 @Feature({"AndroidWebView", "Android-JavaBridge"})
582 public void testOverriddenMethod() throws Throwable { 633 public void testOverriddenMethod() throws Throwable {
583 class Base { 634 class Base {
584 public void method() { 635 public void method() {
585 mTestController.setStringValue("base"); 636 mTestController.setStringValue("base");
586 } 637 }
587 } 638 }
588 class Derived extends Base { 639 class Derived extends Base {
589 @Override 640 @Override
590 public void method() { 641 public void method() {
591 mTestController.setStringValue("derived"); 642 mTestController.setStringValue("derived");
592 } 643 }
593 } 644 }
594 injectObjectAndReload(new Derived(), "testObject"); 645 mActivityTestRule.injectObjectAndReload(new Derived(), "testObject");
595 executeJavaScript("testObject.method()"); 646 mActivityTestRule.executeJavaScript("testObject.method()");
596 assertEquals("derived", mTestController.waitForStringValue()); 647 Assert.assertEquals("derived", mTestController.waitForStringValue());
597 } 648 }
598 649
650 @Test
599 @SmallTest 651 @SmallTest
600 @Feature({"AndroidWebView", "Android-JavaBridge"}) 652 @Feature({"AndroidWebView", "Android-JavaBridge"})
601 public void testEnumerateMembers() throws Throwable { 653 public void testEnumerateMembers() throws Throwable {
602 injectObjectAndReload(new Object() { 654 mActivityTestRule.injectObjectAndReload(new Object() {
603 public void method() {} 655 public void method() {}
604 private void privateMethod() {} 656 private void privateMethod() {}
605 @SuppressFBWarnings("UUF_UNUSED") 657 @SuppressFBWarnings("UUF_UNUSED")
606 public int field; 658 public int field;
607 @SuppressFBWarnings("UUF_UNUSED") 659 @SuppressFBWarnings("UUF_UNUSED")
608 private int mPrivateField; 660 private int mPrivateField;
609 }, "testObject"); 661 }, "testObject");
610 executeJavaScript( 662 mActivityTestRule.executeJavaScript("var result = \"\"; "
611 "var result = \"\"; "
612 + "for (x in testObject) { result += \" \" + x } " 663 + "for (x in testObject) { result += \" \" + x } "
613 + "testController.setStringValue(result);"); 664 + "testController.setStringValue(result);");
614 assertEquals(" equals getClass hashCode method notify notifyAll toString wait", 665 Assert.assertEquals(" equals getClass hashCode method notify notifyAll t oString wait",
615 mTestController.waitForStringValue()); 666 mTestController.waitForStringValue());
616 } 667 }
617 668
669 @Test
618 @SmallTest 670 @SmallTest
619 @Feature({"AndroidWebView", "Android-JavaBridge"}) 671 @Feature({"AndroidWebView", "Android-JavaBridge"})
620 public void testReflectPublicMethod() throws Throwable { 672 public void testReflectPublicMethod() throws Throwable {
621 injectObjectAndReload(new Object() { 673 mActivityTestRule.injectObjectAndReload(new Object() {
622 public Class<?> myGetClass() { 674 public Class<?> myGetClass() {
623 return getClass(); 675 return getClass();
624 } 676 }
625 677
626 public String method() { 678 public String method() {
627 return "foo"; 679 return "foo";
628 } 680 }
629 }, "testObject"); 681 }, "testObject");
630 assertEquals("foo", executeJavaScriptAndGetStringResult( 682 Assert.assertEquals("foo",
631 "testObject.myGetClass().getMethod('method', null).invoke(testOb ject, null)" 683 executeJavaScriptAndGetStringResult(
632 + ".toString()")); 684 "testObject.myGetClass().getMethod('method', null).invok e(testObject, null)"
685 + ".toString()"));
633 } 686 }
634 687
688 @Test
635 @SmallTest 689 @SmallTest
636 @Feature({"AndroidWebView", "Android-JavaBridge"}) 690 @Feature({"AndroidWebView", "Android-JavaBridge"})
637 public void testReflectPublicField() throws Throwable { 691 public void testReflectPublicField() throws Throwable {
638 injectObjectAndReload(new Object() { 692 mActivityTestRule.injectObjectAndReload(new Object() {
639 public Class<?> myGetClass() { 693 public Class<?> myGetClass() {
640 return getClass(); 694 return getClass();
641 } 695 }
642 696
643 public String field = "foo"; 697 public String field = "foo";
644 }, "testObject"); 698 }, "testObject");
645 assertEquals("foo", executeJavaScriptAndGetStringResult( 699 Assert.assertEquals("foo",
646 "testObject.myGetClass().getField('field').get(testObject).toStr ing()")); 700 executeJavaScriptAndGetStringResult(
701 "testObject.myGetClass().getField('field').get(testObjec t).toString()"));
647 } 702 }
648 703
704 @Test
649 @SmallTest 705 @SmallTest
650 @Feature({"AndroidWebView", "Android-JavaBridge"}) 706 @Feature({"AndroidWebView", "Android-JavaBridge"})
651 public void testReflectPrivateMethodRaisesException() throws Throwable { 707 public void testReflectPrivateMethodRaisesException() throws Throwable {
652 injectObjectAndReload(new Object() { 708 mActivityTestRule.injectObjectAndReload(new Object() {
653 public Class<?> myGetClass() { 709 public Class<?> myGetClass() {
654 return getClass(); 710 return getClass();
655 } 711 }
656 712
657 private void method() {}; 713 private void method() {};
658 }, "testObject"); 714 }, "testObject");
659 assertRaisesException("testObject.myGetClass().getMethod('method', null) "); 715 assertRaisesException("testObject.myGetClass().getMethod('method', null) ");
660 // getDeclaredMethod() is able to access a private method, but invoke() 716 // getDeclaredMethod() is able to access a private method, but invoke()
661 // throws a Java exception. 717 // throws a Java exception.
662 assertRaisesException( 718 assertRaisesException(
663 "testObject.myGetClass().getDeclaredMethod('method', null)." 719 "testObject.myGetClass().getDeclaredMethod('method', null)."
664 + "invoke(testObject, null)"); 720 + "invoke(testObject, null)");
665 } 721 }
666 722
723 @Test
667 @SmallTest 724 @SmallTest
668 @Feature({"AndroidWebView", "Android-JavaBridge"}) 725 @Feature({"AndroidWebView", "Android-JavaBridge"})
669 public void testReflectPrivateFieldRaisesException() throws Throwable { 726 public void testReflectPrivateFieldRaisesException() throws Throwable {
670 injectObjectAndReload(new Object() { 727 mActivityTestRule.injectObjectAndReload(new Object() {
671 public Class<?> myGetClass() { 728 public Class<?> myGetClass() {
672 return getClass(); 729 return getClass();
673 } 730 }
674 731
675 @SuppressFBWarnings("UUF_UNUSED") 732 @SuppressFBWarnings("UUF_UNUSED")
676 private int mField; 733 private int mField;
677 }, "testObject"); 734 }, "testObject");
678 String fieldName = "mField"; 735 String fieldName = "mField";
679 assertRaisesException("testObject.myGetClass().getField('" + fieldName + "')"); 736 assertRaisesException("testObject.myGetClass().getField('" + fieldName + "')");
680 // getDeclaredField() is able to access a private field, but getInt() 737 // getDeclaredField() is able to access a private field, but getInt()
681 // throws a Java exception. 738 // throws a Java exception.
682 assertNoRaisedException("testObject.myGetClass().getDeclaredField('" + f ieldName + "')"); 739 assertNoRaisedException("testObject.myGetClass().getDeclaredField('" + f ieldName + "')");
683 assertRaisesException( 740 assertRaisesException(
684 "testObject.myGetClass().getDeclaredField('" + fieldName + "').g etInt(testObject)"); 741 "testObject.myGetClass().getDeclaredField('" + fieldName + "').g etInt(testObject)");
685 } 742 }
686 743
744 @Test
687 @SmallTest 745 @SmallTest
688 @Feature({"AndroidWebView", "Android-JavaBridge"}) 746 @Feature({"AndroidWebView", "Android-JavaBridge"})
689 public void testAllowNonAnnotatedMethods() throws Throwable { 747 public void testAllowNonAnnotatedMethods() throws Throwable {
690 injectObjectAndReload(new Object() { 748 mActivityTestRule.injectObjectAndReload(new Object() {
691 public String allowed() { 749 public String allowed() {
692 return "foo"; 750 return "foo";
693 } 751 }
694 }, "testObject", null); 752 }, "testObject", null);
695 753
696 // Test calling a method of an explicitly inherited class (Base#allowed( )). 754 // Test calling a method of an explicitly inherited class (Base#allowed( )).
697 assertEquals("foo", executeJavaScriptAndGetStringResult("testObject.allo wed()")); 755 Assert.assertEquals("foo", executeJavaScriptAndGetStringResult("testObje ct.allowed()"));
698 756
699 // Test calling a method of an implicitly inherited class (Object#toStri ng()). 757 // Test calling a method of an implicitly inherited class (Object#toStri ng()).
700 assertEquals("string", executeJavaScriptAndGetStringResult("typeof testO bject.toString()")); 758 Assert.assertEquals(
759 "string", executeJavaScriptAndGetStringResult("typeof testObject .toString()"));
701 } 760 }
702 761
762 @Test
703 @SmallTest 763 @SmallTest
704 @Feature({"AndroidWebView", "Android-JavaBridge"}) 764 @Feature({"AndroidWebView", "Android-JavaBridge"})
705 public void testAllowOnlyAnnotatedMethods() throws Throwable { 765 public void testAllowOnlyAnnotatedMethods() throws Throwable {
706 injectObjectAndReload(new Object() { 766 mActivityTestRule.injectObjectAndReload(new Object() {
707 @JavascriptInterface 767 @JavascriptInterface
708 public String allowed() { 768 public String allowed() {
709 return "foo"; 769 return "foo";
710 } 770 }
711 771
712 public String disallowed() { 772 public String disallowed() {
713 return "bar"; 773 return "bar";
714 } 774 }
715 }, "testObject", JavascriptInterface.class); 775 }, "testObject", JavascriptInterface.class);
716 776
717 // getClass() is an Object method and does not have the @JavascriptInter face annotation and 777 // getClass() is an Object method and does not have the @JavascriptInter face annotation and
718 // should not be able to be called. 778 // should not be able to be called.
719 assertRaisesException("testObject.getClass()"); 779 assertRaisesException("testObject.getClass()");
720 assertEquals("undefined", executeJavaScriptAndGetStringResult( 780 Assert.assertEquals(
721 "typeof testObject.getClass")); 781 "undefined", executeJavaScriptAndGetStringResult("typeof testObj ect.getClass"));
722 782
723 // allowed() is marked with the @JavascriptInterface annotation and shou ld be allowed to be 783 // allowed() is marked with the @JavascriptInterface annotation and shou ld be allowed to be
724 // called. 784 // called.
725 assertEquals("foo", executeJavaScriptAndGetStringResult("testObject.allo wed()")); 785 Assert.assertEquals("foo", executeJavaScriptAndGetStringResult("testObje ct.allowed()"));
726 786
727 // disallowed() is not marked with the @JavascriptInterface annotation a nd should not be 787 // disallowed() is not marked with the @JavascriptInterface annotation a nd should not be
728 // able to be called. 788 // able to be called.
729 assertRaisesException("testObject.disallowed()"); 789 assertRaisesException("testObject.disallowed()");
730 assertEquals("undefined", executeJavaScriptAndGetStringResult( 790 Assert.assertEquals(
731 "typeof testObject.disallowed")); 791 "undefined", executeJavaScriptAndGetStringResult("typeof testObj ect.disallowed"));
732 } 792 }
733 793
794 @Test
734 @SmallTest 795 @SmallTest
735 @Feature({"AndroidWebView", "Android-JavaBridge"}) 796 @Feature({"AndroidWebView", "Android-JavaBridge"})
736 public void testAnnotationRequirementRetainsPropertyAcrossObjects() throws T hrowable { 797 public void testAnnotationRequirementRetainsPropertyAcrossObjects() throws T hrowable {
737 class Test { 798 class Test {
738 @JavascriptInterface 799 @JavascriptInterface
739 public String safe() { 800 public String safe() {
740 return "foo"; 801 return "foo";
741 } 802 }
742 803
743 public String unsafe() { 804 public String unsafe() {
744 return "bar"; 805 return "bar";
745 } 806 }
746 } 807 }
747 808
748 class TestReturner { 809 class TestReturner {
749 @JavascriptInterface 810 @JavascriptInterface
750 public Test getTest() { 811 public Test getTest() {
751 return new Test(); 812 return new Test();
752 } 813 }
753 } 814 }
754 815
755 // First test with safe mode off. 816 // First test with safe mode off.
756 injectObjectAndReload(new TestReturner(), "unsafeTestObject", null); 817 mActivityTestRule.injectObjectAndReload(new TestReturner(), "unsafeTestO bject", null);
757 818
758 // safe() should be able to be called regardless of whether or not we ar e in safe mode. 819 // safe() should be able to be called regardless of whether or not we ar e in safe mode.
759 assertEquals("foo", executeJavaScriptAndGetStringResult( 820 Assert.assertEquals(
760 "unsafeTestObject.getTest().safe()")); 821 "foo", executeJavaScriptAndGetStringResult("unsafeTestObject.get Test().safe()"));
761 // unsafe() should be able to be called because we are not in safe mode. 822 // unsafe() should be able to be called because we are not in safe mode.
762 assertEquals("bar", executeJavaScriptAndGetStringResult( 823 Assert.assertEquals(
763 "unsafeTestObject.getTest().unsafe()")); 824 "bar", executeJavaScriptAndGetStringResult("unsafeTestObject.get Test().unsafe()"));
764 825
765 // Now test with safe mode on. 826 // Now test with safe mode on.
766 injectObjectAndReload(new TestReturner(), "safeTestObject", JavascriptIn terface.class); 827 mActivityTestRule.injectObjectAndReload(
828 new TestReturner(), "safeTestObject", JavascriptInterface.class) ;
767 829
768 // safe() should be able to be called regardless of whether or not we ar e in safe mode. 830 // safe() should be able to be called regardless of whether or not we ar e in safe mode.
769 assertEquals("foo", executeJavaScriptAndGetStringResult( 831 Assert.assertEquals(
770 "safeTestObject.getTest().safe()")); 832 "foo", executeJavaScriptAndGetStringResult("safeTestObject.getTe st().safe()"));
771 // unsafe() should not be able to be called because we are in safe mode. 833 // unsafe() should not be able to be called because we are in safe mode.
772 assertRaisesException("safeTestObject.getTest().unsafe()"); 834 assertRaisesException("safeTestObject.getTest().unsafe()");
773 assertEquals("undefined", executeJavaScriptAndGetStringResult( 835 Assert.assertEquals("undefined",
774 "typeof safeTestObject.getTest().unsafe")); 836 executeJavaScriptAndGetStringResult("typeof safeTestObject.getTe st().unsafe"));
775 // getClass() is an Object method and does not have the @JavascriptInter face annotation and 837 // getClass() is an Object method and does not have the @JavascriptInter face annotation and
776 // should not be able to be called. 838 // should not be able to be called.
777 assertRaisesException("safeTestObject.getTest().getClass()"); 839 assertRaisesException("safeTestObject.getTest().getClass()");
778 assertEquals("undefined", executeJavaScriptAndGetStringResult( 840 Assert.assertEquals("undefined",
779 "typeof safeTestObject.getTest().getClass")); 841 executeJavaScriptAndGetStringResult("typeof safeTestObject.getTe st().getClass"));
780 } 842 }
781 843
844 @Test
782 @SmallTest 845 @SmallTest
783 @Feature({"AndroidWebView", "Android-JavaBridge"}) 846 @Feature({"AndroidWebView", "Android-JavaBridge"})
784 public void testAnnotationDoesNotGetInherited() throws Throwable { 847 public void testAnnotationDoesNotGetInherited() throws Throwable {
785 class Base { 848 class Base {
786 @JavascriptInterface 849 @JavascriptInterface
787 public void base() { } 850 public void base() { }
788 } 851 }
789 852
790 class Child extends Base { 853 class Child extends Base {
791 @Override 854 @Override
792 public void base() { } 855 public void base() { }
793 } 856 }
794 857
795 injectObjectAndReload(new Child(), "testObject", JavascriptInterface.cla ss); 858 mActivityTestRule.injectObjectAndReload(
859 new Child(), "testObject", JavascriptInterface.class);
796 860
797 // base() is inherited. The inherited method does not have the @Javascr iptInterface 861 // base() is inherited. The inherited method does not have the @Javascr iptInterface
798 // annotation and should not be able to be called. 862 // annotation and should not be able to be called.
799 assertRaisesException("testObject.base()"); 863 assertRaisesException("testObject.base()");
800 assertEquals("undefined", executeJavaScriptAndGetStringResult( 864 Assert.assertEquals(
801 "typeof testObject.base")); 865 "undefined", executeJavaScriptAndGetStringResult("typeof testObj ect.base"));
802 } 866 }
803 867
804 @SuppressWarnings("javadoc") 868 @SuppressWarnings("javadoc")
805 @Retention(RetentionPolicy.RUNTIME) 869 @Retention(RetentionPolicy.RUNTIME)
806 @Target({ElementType.METHOD}) 870 @Target({ElementType.METHOD})
807 @interface TestAnnotation { 871 @interface TestAnnotation {
808 } 872 }
809 873
874 @Test
810 @SmallTest 875 @SmallTest
811 @Feature({"AndroidWebView", "Android-JavaBridge"}) 876 @Feature({"AndroidWebView", "Android-JavaBridge"})
812 public void testCustomAnnotationRestriction() throws Throwable { 877 public void testCustomAnnotationRestriction() throws Throwable {
813 class Test { 878 class Test {
814 @TestAnnotation 879 @TestAnnotation
815 public String checkTestAnnotationFoo() { 880 public String checkTestAnnotationFoo() {
816 return "bar"; 881 return "bar";
817 } 882 }
818 883
819 @JavascriptInterface 884 @JavascriptInterface
820 public String checkJavascriptInterfaceFoo() { 885 public String checkJavascriptInterfaceFoo() {
821 return "bar"; 886 return "bar";
822 } 887 }
823 } 888 }
824 889
825 // Inject javascriptInterfaceObj and require the JavascriptInterface ann otation. 890 // Inject javascriptInterfaceObj and require the JavascriptInterface ann otation.
826 injectObjectAndReload(new Test(), "javascriptInterfaceObj", JavascriptIn terface.class); 891 mActivityTestRule.injectObjectAndReload(
892 new Test(), "javascriptInterfaceObj", JavascriptInterface.class) ;
827 893
828 // Test#testAnnotationFoo() should fail, as it isn't annotated with Java scriptInterface. 894 // Test#testAnnotationFoo() should fail, as it isn't annotated with Java scriptInterface.
829 assertRaisesException("javascriptInterfaceObj.checkTestAnnotationFoo()") ; 895 assertRaisesException("javascriptInterfaceObj.checkTestAnnotationFoo()") ;
830 assertEquals("undefined", executeJavaScriptAndGetStringResult( 896 Assert.assertEquals("undefined",
831 "typeof javascriptInterfaceObj.checkTestAnnotationFoo")); 897 executeJavaScriptAndGetStringResult(
898 "typeof javascriptInterfaceObj.checkTestAnnotationFoo")) ;
832 899
833 // Test#javascriptInterfaceFoo() should pass, as it is annotated with Ja vascriptInterface. 900 // Test#javascriptInterfaceFoo() should pass, as it is annotated with Ja vascriptInterface.
834 assertEquals("bar", executeJavaScriptAndGetStringResult( 901 Assert.assertEquals("bar",
835 "javascriptInterfaceObj.checkJavascriptInterfaceFoo()")); 902 executeJavaScriptAndGetStringResult(
903 "javascriptInterfaceObj.checkJavascriptInterfaceFoo()")) ;
836 904
837 // Inject testAnnotationObj and require the TestAnnotation annotation. 905 // Inject testAnnotationObj and require the TestAnnotation annotation.
838 injectObjectAndReload(new Test(), "testAnnotationObj", TestAnnotation.cl ass); 906 mActivityTestRule.injectObjectAndReload(
907 new Test(), "testAnnotationObj", TestAnnotation.class);
839 908
840 // Test#testAnnotationFoo() should pass, as it is annotated with TestAnn otation. 909 // Test#testAnnotationFoo() should pass, as it is annotated with TestAnn otation.
841 assertEquals("bar", executeJavaScriptAndGetStringResult( 910 Assert.assertEquals("bar",
842 "testAnnotationObj.checkTestAnnotationFoo()")); 911 executeJavaScriptAndGetStringResult("testAnnotationObj.checkTest AnnotationFoo()"));
843 912
844 // Test#javascriptInterfaceFoo() should fail, as it isn't annotated with TestAnnotation. 913 // Test#javascriptInterfaceFoo() should fail, as it isn't annotated with TestAnnotation.
845 assertRaisesException("testAnnotationObj.checkJavascriptInterfaceFoo()") ; 914 assertRaisesException("testAnnotationObj.checkJavascriptInterfaceFoo()") ;
846 assertEquals("undefined", executeJavaScriptAndGetStringResult( 915 Assert.assertEquals("undefined",
847 "typeof testAnnotationObj.checkJavascriptInterfaceFoo")); 916 executeJavaScriptAndGetStringResult(
917 "typeof testAnnotationObj.checkJavascriptInterfaceFoo")) ;
848 } 918 }
849 919
920 @Test
850 @SmallTest 921 @SmallTest
851 @Feature({"AndroidWebView", "Android-JavaBridge"}) 922 @Feature({"AndroidWebView", "Android-JavaBridge"})
852 public void testAddJavascriptInterfaceIsSafeByDefault() throws Throwable { 923 public void testAddJavascriptInterfaceIsSafeByDefault() throws Throwable {
853 class Test { 924 class Test {
854 public String blocked() { 925 public String blocked() {
855 return "bar"; 926 return "bar";
856 } 927 }
857 928
858 @JavascriptInterface 929 @JavascriptInterface
859 public String allowed() { 930 public String allowed() {
860 return "bar"; 931 return "bar";
861 } 932 }
862 } 933 }
863 934
864 // Manually inject the Test object, making sure to use the 935 // Manually inject the Test object, making sure to use the
865 // ContentViewCore#addJavascriptInterface, not the possibly unsafe versi on. 936 // ContentViewCore#addJavascriptInterface, not the possibly unsafe versi on.
866 TestCallbackHelperContainer.OnPageFinishedHelper onPageFinishedHelper = 937 TestCallbackHelperContainer.OnPageFinishedHelper onPageFinishedHelper =
867 getTestCallBackHelperContainer().getOnPageFinishedHelper(); 938 mActivityTestRule.getTestCallBackHelperContainer().getOnPageFini shedHelper();
868 int currentCallCount = onPageFinishedHelper.getCallCount(); 939 int currentCallCount = onPageFinishedHelper.getCallCount();
869 runTestOnUiThread(new Runnable() { 940 InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable( ) {
870 @Override 941 @Override
871 public void run() { 942 public void run() {
872 getContentViewCore().addJavascriptInterface(new Test(), 943 mActivityTestRule.getContentViewCore().addJavascriptInterface(
873 "testObject"); 944 new Test(), "testObject");
874 getContentViewCore().getWebContents().getNavigationController(). reload(true); 945 mActivityTestRule.getContentViewCore()
946 .getWebContents()
947 .getNavigationController()
948 .reload(true);
875 } 949 }
876 }); 950 });
877 onPageFinishedHelper.waitForCallback(currentCallCount); 951 onPageFinishedHelper.waitForCallback(currentCallCount);
878 952
879 // Test#allowed() should pass, as it is annotated with JavascriptInterfa ce. 953 // Test#allowed() should pass, as it is annotated with JavascriptInterfa ce.
880 assertEquals("bar", executeJavaScriptAndGetStringResult( 954 Assert.assertEquals("bar", executeJavaScriptAndGetStringResult("testObje ct.allowed()"));
881 "testObject.allowed()"));
882 955
883 // Test#blocked() should fail, as it isn't annotated with JavascriptInte rface. 956 // Test#blocked() should fail, as it isn't annotated with JavascriptInte rface.
884 assertRaisesException("testObject.blocked()"); 957 assertRaisesException("testObject.blocked()");
885 assertEquals("undefined", executeJavaScriptAndGetStringResult( 958 Assert.assertEquals(
886 "typeof testObject.blocked")); 959 "undefined", executeJavaScriptAndGetStringResult("typeof testObj ect.blocked"));
887 } 960 }
888 961
962 @Test
889 @SmallTest 963 @SmallTest
890 @Feature({"AndroidWebView", "Android-JavaBridge"}) 964 @Feature({"AndroidWebView", "Android-JavaBridge"})
891 public void testObjectsInspection() throws Throwable { 965 public void testObjectsInspection() throws Throwable {
892 class Test { 966 class Test {
893 @JavascriptInterface 967 @JavascriptInterface
894 public String m1() { 968 public String m1() {
895 return "foo"; 969 return "foo";
896 } 970 }
897 971
898 @JavascriptInterface 972 @JavascriptInterface
899 public String m2() { 973 public String m2() {
900 return "bar"; 974 return "bar";
901 } 975 }
902 976
903 @JavascriptInterface 977 @JavascriptInterface
904 public String m2(int x) { 978 public String m2(int x) {
905 return "bar " + x; 979 return "bar " + x;
906 } 980 }
907 } 981 }
908 982
909 final String jsObjectKeysTestTemplate = "Object.keys(%s).toString()"; 983 final String jsObjectKeysTestTemplate = "Object.keys(%s).toString()";
910 final String jsForInTestTemplate = 984 final String jsForInTestTemplate =
911 "(function(){" 985 "(function(){"
912 + " var s=[]; for(var m in %s) s.push(m); return s.join(\",\")" 986 + " var s=[]; for(var m in %s) s.push(m); return s.join(\",\")"
913 + "})()"; 987 + "})()";
914 final String inspectableObjectName = "testObj1"; 988 final String inspectableObjectName = "testObj1";
915 final String nonInspectableObjectName = "testObj2"; 989 final String nonInspectableObjectName = "testObj2";
916 990
917 // Inspection is enabled by default. 991 // Inspection is enabled by default.
918 injectObjectAndReload(new Test(), inspectableObjectName, JavascriptInter face.class); 992 mActivityTestRule.injectObjectAndReload(
993 new Test(), inspectableObjectName, JavascriptInterface.class);
919 994
920 assertEquals("m1,m2", executeJavaScriptAndGetStringResult( 995 Assert.assertEquals("m1,m2",
996 executeJavaScriptAndGetStringResult(
921 String.format(jsObjectKeysTestTemplate, inspectableObjec tName))); 997 String.format(jsObjectKeysTestTemplate, inspectableObjec tName)));
922 assertEquals("m1,m2", executeJavaScriptAndGetStringResult( 998 Assert.assertEquals("m1,m2",
999 executeJavaScriptAndGetStringResult(
923 String.format(jsForInTestTemplate, inspectableObjectName ))); 1000 String.format(jsForInTestTemplate, inspectableObjectName )));
924 1001
925 runTestOnUiThread(new Runnable() { 1002 InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable( ) {
926 @Override 1003 @Override
927 public void run() { 1004 public void run() {
928 getContentViewCore().setAllowJavascriptInterfacesInspection(fals e); 1005 mActivityTestRule.getContentViewCore().setAllowJavascriptInterfa cesInspection(
1006 false);
929 } 1007 }
930 }); 1008 });
931 1009
932 injectObjectAndReload(new Test(), nonInspectableObjectName, JavascriptIn terface.class); 1010 mActivityTestRule.injectObjectAndReload(
1011 new Test(), nonInspectableObjectName, JavascriptInterface.class) ;
933 1012
934 assertEquals("", executeJavaScriptAndGetStringResult( 1013 Assert.assertEquals("",
1014 executeJavaScriptAndGetStringResult(
935 String.format(jsObjectKeysTestTemplate, nonInspectableOb jectName))); 1015 String.format(jsObjectKeysTestTemplate, nonInspectableOb jectName)));
936 assertEquals("", executeJavaScriptAndGetStringResult( 1016 Assert.assertEquals("",
1017 executeJavaScriptAndGetStringResult(
937 String.format(jsForInTestTemplate, nonInspectableObjectN ame))); 1018 String.format(jsForInTestTemplate, nonInspectableObjectN ame)));
938 } 1019 }
939 1020
1021 @Test
940 @SmallTest 1022 @SmallTest
941 @Feature({"AndroidWebView", "Android-JavaBridge"}) 1023 @Feature({"AndroidWebView", "Android-JavaBridge"})
942 public void testAccessToObjectGetClassIsBlocked() throws Throwable { 1024 public void testAccessToObjectGetClassIsBlocked() throws Throwable {
943 injectObjectAndReload(new Object(), "testObject"); 1025 mActivityTestRule.injectObjectAndReload(new Object(), "testObject");
944 assertEquals("function", executeJavaScriptAndGetStringResult("typeof tes tObject.getClass")); 1026 Assert.assertEquals(
1027 "function", executeJavaScriptAndGetStringResult("typeof testObje ct.getClass"));
945 assertRaisesException("testObject.getClass()"); 1028 assertRaisesException("testObject.getClass()");
946 } 1029 }
947 1030
1031 @Test
948 @SmallTest 1032 @SmallTest
949 @Feature({"AndroidWebView", "Android-JavaBridge"}) 1033 @Feature({"AndroidWebView", "Android-JavaBridge"})
950 public void testReplaceJavascriptInterface() throws Throwable { 1034 public void testReplaceJavascriptInterface() throws Throwable {
951 class Test { 1035 class Test {
952 public Test(int value) { 1036 public Test(int value) {
953 mValue = value; 1037 mValue = value;
954 } 1038 }
955 @JavascriptInterface 1039 @JavascriptInterface
956 public int getValue() { 1040 public int getValue() {
957 return mValue; 1041 return mValue;
958 } 1042 }
959 private int mValue; 1043 private int mValue;
960 } 1044 }
961 injectObjectAndReload(new Test(13), "testObject"); 1045 mActivityTestRule.injectObjectAndReload(new Test(13), "testObject");
962 assertEquals("13", executeJavaScriptAndGetStringResult("testObject.getVa lue()")); 1046 Assert.assertEquals("13", executeJavaScriptAndGetStringResult("testObjec t.getValue()"));
963 // The documentation doesn't specify, what happens if the embedder is tr ying 1047 // The documentation doesn't specify, what happens if the embedder is tr ying
964 // to inject a different object under the same name. The current impleme ntation 1048 // to inject a different object under the same name. The current impleme ntation
965 // simply replaces the old object with the new one. 1049 // simply replaces the old object with the new one.
966 injectObjectAndReload(new Test(42), "testObject"); 1050 mActivityTestRule.injectObjectAndReload(new Test(42), "testObject");
967 assertEquals("42", executeJavaScriptAndGetStringResult("testObject.getVa lue()")); 1051 Assert.assertEquals("42", executeJavaScriptAndGetStringResult("testObjec t.getValue()"));
968 } 1052 }
969 1053
1054 @Test
970 @SmallTest 1055 @SmallTest
971 @Feature({"AndroidWebView", "Android-JavaBridge"}) 1056 @Feature({"AndroidWebView", "Android-JavaBridge"})
972 public void testMethodCalledOnAnotherInstance() throws Throwable { 1057 public void testMethodCalledOnAnotherInstance() throws Throwable {
973 class TestObject { 1058 class TestObject {
974 private int mIndex; 1059 private int mIndex;
975 TestObject(int index) { 1060 TestObject(int index) {
976 mIndex = index; 1061 mIndex = index;
977 } 1062 }
978 public void method() { 1063 public void method() {
979 mTestController.setIntValue(mIndex); 1064 mTestController.setIntValue(mIndex);
980 } 1065 }
981 } 1066 }
982 final TestObject testObject1 = new TestObject(1); 1067 final TestObject testObject1 = new TestObject(1);
983 final TestObject testObject2 = new TestObject(2); 1068 final TestObject testObject2 = new TestObject(2);
984 injectObjectsAndReload(testObject1, "testObject1", testObject2, "testObj ect2", null); 1069 mActivityTestRule.injectObjectsAndReload(
985 executeJavaScript("testObject1.method()"); 1070 testObject1, "testObject1", testObject2, "testObject2", null);
986 assertEquals(1, mTestController.waitForIntValue()); 1071 mActivityTestRule.executeJavaScript("testObject1.method()");
987 executeJavaScript("testObject2.method()"); 1072 Assert.assertEquals(1, mTestController.waitForIntValue());
988 assertEquals(2, mTestController.waitForIntValue()); 1073 mActivityTestRule.executeJavaScript("testObject2.method()");
989 executeJavaScript("testObject1.method.call(testObject2)"); 1074 Assert.assertEquals(2, mTestController.waitForIntValue());
990 assertEquals(2, mTestController.waitForIntValue()); 1075 mActivityTestRule.executeJavaScript("testObject1.method.call(testObject2 )");
991 executeJavaScript("testObject2.method.call(testObject1)"); 1076 Assert.assertEquals(2, mTestController.waitForIntValue());
992 assertEquals(1, mTestController.waitForIntValue()); 1077 mActivityTestRule.executeJavaScript("testObject2.method.call(testObject1 )");
1078 Assert.assertEquals(1, mTestController.waitForIntValue());
993 } 1079 }
994 } 1080 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698