| Index: content/public/android/javatests/src/org/chromium/content/browser/JavaBridgeChildFrameTest.java
|
| diff --git a/content/public/android/javatests/src/org/chromium/content/browser/JavaBridgeChildFrameTest.java b/content/public/android/javatests/src/org/chromium/content/browser/JavaBridgeChildFrameTest.java
|
| index cbad6a1d428c169ab6a19678cdb5241496040b8e..5fb8ef19ac127ddf7532bdfd56526f8fbeac8b1b 100644
|
| --- a/content/public/android/javatests/src/org/chromium/content/browser/JavaBridgeChildFrameTest.java
|
| +++ b/content/public/android/javatests/src/org/chromium/content/browser/JavaBridgeChildFrameTest.java
|
| @@ -4,9 +4,17 @@
|
|
|
| package org.chromium.content.browser;
|
|
|
| +import android.support.test.InstrumentationRegistry;
|
| import android.support.test.filters.SmallTest;
|
|
|
| +import org.junit.Assert;
|
| +import org.junit.Before;
|
| +import org.junit.Rule;
|
| +import org.junit.Test;
|
| +import org.junit.runner.RunWith;
|
| +
|
| import org.chromium.base.annotations.SuppressFBWarnings;
|
| +import org.chromium.base.test.BaseJUnit4ClassRunner;
|
| import org.chromium.base.test.util.CommandLineFlags;
|
| import org.chromium.base.test.util.DisabledTest;
|
| import org.chromium.base.test.util.Feature;
|
| @@ -28,8 +36,12 @@ import java.util.concurrent.TimeoutException;
|
| * Ensures that injected objects are exposed to child frames as well as the
|
| * main frame.
|
| */
|
| +@RunWith(BaseJUnit4ClassRunner.class)
|
| @SuppressFBWarnings("UMAC_UNCALLABLE_METHOD_OF_ANONYMOUS_CLASS")
|
| -public class JavaBridgeChildFrameTest extends JavaBridgeTestBase {
|
| +public class JavaBridgeChildFrameTest {
|
| + @Rule
|
| + public JavaBridgeActivityTestRule mActivityTestRule = new JavaBridgeActivityTestRule();
|
| +
|
| @SuppressFBWarnings("CHROMIUM_SYNCHRONIZED_METHOD")
|
| private static class TestController extends Controller {
|
| private String mStringValue;
|
| @@ -48,33 +60,35 @@ public class JavaBridgeChildFrameTest extends JavaBridgeTestBase {
|
|
|
| TestController mTestController;
|
|
|
| - @Override
|
| - protected void setUp() throws Exception {
|
| - super.setUp();
|
| + @Before
|
| + public void setUp() throws Exception {
|
| mTestController = new TestController();
|
| - injectObjectAndReload(mTestController, "testController");
|
| + mActivityTestRule.injectObjectAndReload(mTestController, "testController");
|
| }
|
|
|
| + @Test
|
| @SmallTest
|
| @Feature({"AndroidWebView", "Android-JavaBridge"})
|
| public void testInjectedObjectPresentInChildFrame() throws Throwable {
|
| - loadDataSync(getWebContents().getNavigationController(),
|
| + loadDataSync(mActivityTestRule.getWebContents().getNavigationController(),
|
| "<html><body><iframe></iframe></body></html>", "text/html", false);
|
| // We are not executing this code as a part of page loading routine to avoid races
|
| // with internal Blink events that notify Java Bridge about window object updates.
|
| - assertEquals("\"object\"", executeJavaScriptAndGetResult(
|
| - getWebContents(), "typeof window.frames[0].testController"));
|
| - executeJavaScriptAndGetResult(
|
| - getWebContents(), "window.frames[0].testController.setStringValue('PASS')");
|
| - assertEquals("PASS", mTestController.waitForStringValue());
|
| + Assert.assertEquals("\"object\"",
|
| + executeJavaScriptAndGetResult(mActivityTestRule.getWebContents(),
|
| + "typeof window.frames[0].testController"));
|
| + executeJavaScriptAndGetResult(mActivityTestRule.getWebContents(),
|
| + "window.frames[0].testController.setStringValue('PASS')");
|
| + Assert.assertEquals("PASS", mTestController.waitForStringValue());
|
| }
|
|
|
| // Verify that loading an iframe doesn't ruin JS wrapper of the main page.
|
| // This is a regression test for the problem described in b/15572824.
|
| + @Test
|
| @SmallTest
|
| @Feature({"AndroidWebView", "Android-JavaBridge"})
|
| public void testMainPageWrapperIsNotBrokenByChildFrame() throws Throwable {
|
| - loadDataSync(getWebContents().getNavigationController(),
|
| + loadDataSync(mActivityTestRule.getWebContents().getNavigationController(),
|
| "<html><body><iframe></iframe></body></html>", "text/html", false);
|
| // In case there is anything wrong with the JS wrapper, an attempt
|
| // to look up its properties will result in an exception being thrown.
|
| @@ -83,22 +97,23 @@ public class JavaBridgeChildFrameTest extends JavaBridgeTestBase {
|
| + "} catch (e) {"
|
| + " return e.toString();"
|
| + "} })()";
|
| - assertEquals("\"function\"",
|
| - executeJavaScriptAndGetResult(getWebContents(), script));
|
| + Assert.assertEquals("\"function\"",
|
| + executeJavaScriptAndGetResult(mActivityTestRule.getWebContents(), script));
|
| // Make sure calling a method also works.
|
| - executeJavaScriptAndGetResult(getWebContents(),
|
| - "testController.setStringValue('PASS');");
|
| - assertEquals("PASS", mTestController.waitForStringValue());
|
| + executeJavaScriptAndGetResult(
|
| + mActivityTestRule.getWebContents(), "testController.setStringValue('PASS');");
|
| + Assert.assertEquals("PASS", mTestController.waitForStringValue());
|
| }
|
|
|
| // Verify that parent page and child frame each has own JS wrapper object.
|
| // Failing to do so exposes parent's context to the child.
|
| + @Test
|
| @SmallTest
|
| @Feature({"AndroidWebView", "Android-JavaBridge"})
|
| public void testWrapperIsNotSharedWithChildFrame() throws Throwable {
|
| // Test by setting a custom property on the parent page's injected
|
| // object and then checking that child frame doesn't see the property.
|
| - loadDataSync(getWebContents().getNavigationController(),
|
| + loadDataSync(mActivityTestRule.getWebContents().getNavigationController(),
|
| "<html><head>"
|
| + "<script>"
|
| + " window.wProperty = 42;"
|
| @@ -107,17 +122,20 @@ public class JavaBridgeChildFrameTest extends JavaBridgeTestBase {
|
| + " return w.wProperty + ' / ' + w.testController.tcProperty;"
|
| + " }"
|
| + "</script>"
|
| - + "</head><body><iframe></iframe></body></html>", "text/html", false);
|
| - assertEquals("\"42 / 42\"",
|
| - executeJavaScriptAndGetResult(getWebContents(), "queryProperties(window)"));
|
| - assertEquals("\"undefined / undefined\"",
|
| - executeJavaScriptAndGetResult(getWebContents(),
|
| - "queryProperties(window.frames[0])"));
|
| + + "</head><body><iframe></iframe></body></html>",
|
| + "text/html", false);
|
| + Assert.assertEquals("\"42 / 42\"",
|
| + executeJavaScriptAndGetResult(
|
| + mActivityTestRule.getWebContents(), "queryProperties(window)"));
|
| + Assert.assertEquals("\"undefined / undefined\"",
|
| + executeJavaScriptAndGetResult(
|
| + mActivityTestRule.getWebContents(), "queryProperties(window.frames[0])"));
|
| }
|
|
|
| // Regression test for crbug.com/484927 -- make sure that existence of transient
|
| // objects held by multiple RenderFrames doesn't cause an infinite loop when one
|
| // of them gets removed.
|
| + @Test
|
| @SmallTest
|
| @Feature({"AndroidWebView", "Android-JavaBridge"})
|
| @DisabledTest(message = "https://crbug.com/677182")
|
| @@ -144,38 +162,41 @@ public class JavaBridgeChildFrameTest extends JavaBridgeTestBase {
|
| // all the frames got created, then inject the object.
|
| // Thus, the script code fails on the first execution (as no Java object is
|
| // injected yet), but then works just fine after reload.
|
| - loadDataSync(getWebContents().getNavigationController(),
|
| + loadDataSync(mActivityTestRule.getWebContents().getNavigationController(),
|
| "<html>"
|
| - + "<head><script>window.inner_ref = test.getInner()</script></head>"
|
| - + "<body>"
|
| - + " <iframe id='frame' "
|
| - + " srcdoc='<script>window.inner_ref = test.getInner()</script>'>"
|
| - + " </iframe>"
|
| - + "</body></html>", "text/html", false);
|
| - injectObjectAndReload(testObject, "test");
|
| + + "<head><script>window.inner_ref = test.getInner()</script></head>"
|
| + + "<body>"
|
| + + " <iframe id='frame' "
|
| + + " srcdoc='<script>window.inner_ref = test.getInner()</script>'>"
|
| + + " </iframe>"
|
| + + "</body></html>",
|
| + "text/html", false);
|
| + mActivityTestRule.injectObjectAndReload(testObject, "test");
|
| testObject.waitForInjection();
|
| // Just in case, check that the object wrappers are in place.
|
| - assertEquals("\"object\"",
|
| - executeJavaScriptAndGetResult(getWebContents(), "typeof inner_ref"));
|
| - assertEquals("\"object\"",
|
| - executeJavaScriptAndGetResult(getWebContents(),
|
| - "typeof window.frames[0].inner_ref"));
|
| + Assert.assertEquals("\"object\"",
|
| + executeJavaScriptAndGetResult(
|
| + mActivityTestRule.getWebContents(), "typeof inner_ref"));
|
| + Assert.assertEquals("\"object\"",
|
| + executeJavaScriptAndGetResult(
|
| + mActivityTestRule.getWebContents(), "typeof window.frames[0].inner_ref"));
|
| // Remove the iframe, this will trigger a removal of RenderFrame, which was causing
|
| // the bug condition, as the transient object still has a holder -- the main window.
|
| - assertEquals("\"object\"",
|
| - executeJavaScriptAndGetResult(getWebContents(),
|
| + Assert.assertEquals("\"object\"",
|
| + executeJavaScriptAndGetResult(mActivityTestRule.getWebContents(),
|
| "(function(){ "
|
| - + "var f = document.getElementById('frame');"
|
| - + "f.parentNode.removeChild(f); return typeof f; })()"));
|
| + + "var f = document.getElementById('frame');"
|
| + + "f.parentNode.removeChild(f); return typeof f; })()"));
|
| // Just in case, check that the remaining wrapper is still accessible.
|
| - assertEquals("\"object\"",
|
| - executeJavaScriptAndGetResult(getWebContents(),
|
| - "typeof inner_ref"));
|
| + Assert.assertEquals("\"object\"",
|
| + executeJavaScriptAndGetResult(
|
| + mActivityTestRule.getWebContents(), "typeof inner_ref"));
|
| }
|
|
|
| // Regression test for crbug.com/486245 -- assign ownership of a transient object
|
| // to one frame with a code running in the second frame. Deletion of the second
|
| // frame should not affect the injected object.
|
| + @Test
|
| @SmallTest
|
| @Feature({"AndroidWebView", "Android-JavaBridge"})
|
| @CommandLineFlags.Add("js-flags=--expose-gc")
|
| @@ -200,55 +221,59 @@ public class JavaBridgeChildFrameTest extends JavaBridgeTestBase {
|
| }
|
| final Test testObject = new Test();
|
|
|
| - assertEquals("\"function\"", executeJavaScriptAndGetResult(getWebContents(), "typeof gc"));
|
| + Assert.assertEquals("\"function\"",
|
| + executeJavaScriptAndGetResult(mActivityTestRule.getWebContents(), "typeof gc"));
|
| // The page executes in the second frame code which creates a wrapper for a transient
|
| // injected object, but makes the first frame the owner of the object.
|
| - loadDataSync(getWebContents().getNavigationController(),
|
| + loadDataSync(mActivityTestRule.getWebContents().getNavigationController(),
|
| "<html>"
|
| - + "<head></head>"
|
| - + "<body>"
|
| - + " <iframe id='frame1' "
|
| - + " srcdoc='<body>I am the Inner object owner!</body>'>"
|
| - + " </iframe>"
|
| - + " <iframe id='frame2' "
|
| - + " srcdoc='<script>"
|
| - + " window.parent.frames[0].inner_ref = test.getInner()"
|
| - + " </script>'>"
|
| - + " </iframe>"
|
| - + "</body></html>", "text/html", false);
|
| - injectObjectAndReload(testObject, "test");
|
| + + "<head></head>"
|
| + + "<body>"
|
| + + " <iframe id='frame1' "
|
| + + " srcdoc='<body>I am the Inner object owner!</body>'>"
|
| + + " </iframe>"
|
| + + " <iframe id='frame2' "
|
| + + " srcdoc='<script>"
|
| + + " window.parent.frames[0].inner_ref = test.getInner()"
|
| + + " </script>'>"
|
| + + " </iframe>"
|
| + + "</body></html>",
|
| + "text/html", false);
|
| + mActivityTestRule.injectObjectAndReload(testObject, "test");
|
| testObject.waitForInjection();
|
| // Check that the object wrappers are in place.
|
| - assertTrue(testObject.mWeakRefForInner.get() != null);
|
| - assertEquals("\"object\"",
|
| - executeJavaScriptAndGetResult(getWebContents(),
|
| - "typeof window.frames[0].inner_ref"));
|
| + Assert.assertTrue(testObject.mWeakRefForInner.get() != null);
|
| + Assert.assertEquals("\"object\"",
|
| + executeJavaScriptAndGetResult(
|
| + mActivityTestRule.getWebContents(), "typeof window.frames[0].inner_ref"));
|
| // Remove the second frame. This must not toggle the deletion of the inner
|
| // object.
|
| - assertEquals("\"object\"",
|
| - executeJavaScriptAndGetResult(getWebContents(),
|
| + Assert.assertEquals("\"object\"",
|
| + executeJavaScriptAndGetResult(mActivityTestRule.getWebContents(),
|
| "(function(){ "
|
| - + "var f = document.getElementById('frame2');"
|
| - + "f.parentNode.removeChild(f); return typeof f; })()"));
|
| + + "var f = document.getElementById('frame2');"
|
| + + "f.parentNode.removeChild(f); return typeof f; })()"));
|
| // Perform two major GCs at the end to flush out all wrappers
|
| // and other Blink (Oilpan) objects.
|
| - executeJavaScriptAndGetResult(getWebContents(), "for (var i = 0; i < 2; ++i) gc();");
|
| + executeJavaScriptAndGetResult(
|
| + mActivityTestRule.getWebContents(), "for (var i = 0; i < 2; ++i) gc();");
|
| // Check that returned Java object is being held by the Java bridge, thus it's not
|
| // collected. Note that despite that what JavaDoc says about invoking "gc()", both Dalvik
|
| // and ART actually run the collector.
|
| Runtime.getRuntime().gc();
|
| - assertNotNull(testObject.mWeakRefForInner.get());
|
| + Assert.assertNotNull(testObject.mWeakRefForInner.get());
|
| // Now, remove the first frame and GC. As it was the only holder of the
|
| // inner object's wrapper, the wrapper must be collected. Then, the death
|
| // of the wrapper must cause removal of the inner object.
|
| - assertEquals("\"object\"",
|
| - executeJavaScriptAndGetResult(getWebContents(),
|
| + Assert.assertEquals("\"object\"",
|
| + executeJavaScriptAndGetResult(mActivityTestRule.getWebContents(),
|
| "(function(){ "
|
| - + "var f = document.getElementById('frame1');"
|
| - + "f.parentNode.removeChild(f); return typeof f; })()"));
|
| - executeJavaScriptAndGetResult(getWebContents(), "for (var i = 0; i < 2; ++i) gc();");
|
| + + "var f = document.getElementById('frame1');"
|
| + + "f.parentNode.removeChild(f); return typeof f; })()"));
|
| + executeJavaScriptAndGetResult(
|
| + mActivityTestRule.getWebContents(), "for (var i = 0; i < 2; ++i) gc();");
|
| Runtime.getRuntime().gc();
|
| - assertNull(testObject.mWeakRefForInner.get());
|
| + Assert.assertNull(testObject.mWeakRefForInner.get());
|
| }
|
|
|
| private String executeJavaScriptAndGetResult(final WebContents webContents,
|
| @@ -262,7 +287,7 @@ public class JavaBridgeChildFrameTest extends JavaBridgeTestBase {
|
| }
|
| }
|
| final ResultCallback resultCallback = new ResultCallback();
|
| - runTestOnUiThread(new Runnable() {
|
| + InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
|
| @Override
|
| public void run() {
|
| webContents.evaluateJavaScriptForTests(script, resultCallback);
|
| @@ -277,7 +302,8 @@ public class JavaBridgeChildFrameTest extends JavaBridgeTestBase {
|
| */
|
| private void loadDataSync(final NavigationController navigationController, final String data,
|
| final String mimeType, final boolean isBase64Encoded) throws Throwable {
|
| - loadUrl(navigationController, getTestCallBackHelperContainer(),
|
| + mActivityTestRule.loadUrl(navigationController,
|
| + mActivityTestRule.getTestCallBackHelperContainer(),
|
| LoadUrlParams.createLoadDataParams(data, mimeType, isBase64Encoded));
|
| }
|
| }
|
|
|