summaryrefslogtreecommitdiffstats
path: root/content/public
diff options
context:
space:
mode:
authormnaganov <mnaganov@chromium.org>2015-05-15 11:14:33 -0700
committerCommit bot <commit-bot@chromium.org>2015-05-15 18:15:49 +0000
commitc4e3f83f536d12fce6e01343af548fa50a4b7c25 (patch)
tree8822905fe6ea0376d1d652741a60c44f10e10ab0 /content/public
parent80f69ca9b991b71adb8c13d759195722b080e0a1 (diff)
downloadchromium_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.java61
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];