diff options
author | mnaganov <mnaganov@chromium.org> | 2015-05-15 11:14:33 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-05-15 18:15:49 +0000 |
commit | c4e3f83f536d12fce6e01343af548fa50a4b7c25 (patch) | |
tree | 8822905fe6ea0376d1d652741a60c44f10e10ab0 /content/public | |
parent | 80f69ca9b991b71adb8c13d759195722b080e0a1 (diff) | |
download | chromium_src-c4e3f83f536d12fce6e01343af548fa50a4b7c25.zip chromium_src-c4e3f83f536d12fce6e01343af548fa50a4b7c25.tar.gz chromium_src-c4e3f83f536d12fce6e01343af548fa50a4b7c25.tar.bz2 |
[Android] Add a regression test for the JB RemoveHolderAndAdvanceLocked issue
This is a re-land of https://codereview.chromium.org/1134543002/ with
a workaround for http://crbug.com/486262, which was causing the initial
test instability.
The test reproduces the condition which was triggering an infinite loop
inside GinJavaBridgeDispatcherHost::RenderFrameDeleted.
Verified that the test indeed hangs up and timeouts if the fix is removed.
BUG=484927,486262
TBR=sgurun@chromium.org,tedchoc@chromium.org
Review URL: https://codereview.chromium.org/1134793005
Cr-Commit-Position: refs/heads/master@{#330135}
Diffstat (limited to 'content/public')
-rw-r--r-- | content/public/android/javatests/src/org/chromium/content/browser/JavaBridgeChildFrameTest.java | 61 |
1 files changed, 61 insertions, 0 deletions
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 2d494d0..40ea4ae 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 @@ -13,6 +13,10 @@ import org.chromium.content_public.browser.LoadUrlParams; import org.chromium.content_public.browser.NavigationController; import org.chromium.content_public.browser.WebContents; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + /** * Part of the test suite for the WebView's Java Bridge. * @@ -105,6 +109,63 @@ public class JavaBridgeChildFrameTest extends JavaBridgeTestBase { "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. + @SmallTest + @Feature({"AndroidWebView", "Android-JavaBridge"}) + public void testRemovingTransientObjectHolders() throws Throwable { + class Test { + private Object mInner = new Object(); + // Expecting the inner object to be retrieved twice. + private CountDownLatch mLatch = new CountDownLatch(2); + @JavascriptInterface + public Object getInner() { + mLatch.countDown(); + return mInner; + } + public void waitForInjection() throws Throwable { + if (!mLatch.await(5, TimeUnit.SECONDS)) { + throw new TimeoutException(); + } + } + } + final Test testObject = new Test(); + + // Due to crbug.com/486262, Java objects are sometimes not injected + // into newly added frames. To work around this, we load the page first, so + // 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(), + "<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"); + 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")); + // 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("{}", + executeJavaScriptAndGetResult(getWebContents(), + "(function(){ " + + "var f = document.getElementById('frame');" + + "f.parentNode.removeChild(f); return f; })()")); + // Just in case, check that the remaining wrapper is still accessible. + assertEquals("\"object\"", + executeJavaScriptAndGetResult(getWebContents(), + "typeof inner_ref")); + } + private String executeJavaScriptAndGetResult(final WebContents webContents, final String script) throws Throwable { final String[] result = new String[1]; |