diff options
author | Mikhail Naganov <mnaganov@google.com> | 2014-12-02 17:43:15 +0000 |
---|---|---|
committer | Mikhail Naganov <mnaganov@google.com> | 2014-12-09 13:46:37 +0000 |
commit | 83eff5096b2d7faaad5ebabc0a49f34aeb850acd (patch) | |
tree | 49a550e9d72961cd7494cfa811742e58571d2a9b | |
parent | da3325133c7b4c33bde752ab853a50db8016e1b5 (diff) | |
download | chromium_org-83eff5096b2d7faaad5ebabc0a49f34aeb850acd.tar.gz |
Cherry-pick: [Android] Fix a subtle issue in Java Bridge regarding interfaces removal
Required for the main patch fixing b/18520475.
Bug: 18520475
Original description:
commit 4d4182c4af0a11a1ad5acae88f9abe2b76853fe1
Author: mnaganov <mnaganov@chromium.org>
Date: Mon Dec 01 11:59:14 2014
[Android] Fix a subtle issue in Java Bridge regarding interfaces removal
Update JavaBridgeBasicsTest.testRemovalNotReflectedUntilReload to actually
call Java GC after removing the interface, and verify that the Java object
is still callable from the page side. Fix the code to make the test pass.
BUG=437761
Review URL: https://codereview.chromium.org/767453003
Cr-Commit-Position: refs/heads/master@{#306176}
Change-Id: If12d53e3aad721e5822d8e12c85f1240e1aac5e6
-rw-r--r-- | content/browser/android/java/gin_java_bridge_dispatcher_host.cc | 16 | ||||
-rw-r--r-- | content/public/android/javatests/src/org/chromium/content/browser/JavaBridgeBasicsTest.java | 14 |
2 files changed, 17 insertions, 13 deletions
diff --git a/content/browser/android/java/gin_java_bridge_dispatcher_host.cc b/content/browser/android/java/gin_java_bridge_dispatcher_host.cc index ca63276b5b..81f49c13e4 100644 --- a/content/browser/android/java/gin_java_bridge_dispatcher_host.cc +++ b/content/browser/android/java/gin_java_bridge_dispatcher_host.cc @@ -210,18 +210,10 @@ void GinJavaBridgeDispatcherHost::RemoveNamedObject( named_objects_.erase(iter); object->RemoveName(); - // Not erasing from the objects map, as we can still receive method - // invocation requests for this object, and they should work until the - // java object is gone. - if (!object->IsNamed()) { - JNIEnv* env = base::android::AttachCurrentThread(); - base::android::ScopedJavaLocalRef<jobject> retained_object_set = - retained_object_set_.get(env); - if (!retained_object_set.is_null()) { - JNI_Java_HashSet_remove( - env, retained_object_set, object->GetLocalRef(env)); - } - } + // As the object isn't going to be removed from the JavaScript side until the + // next page reload, calls to it must still work, thus we should continue to + // hold it. All the transient objects and removed named objects will be purged + // during the cleansing caused by DocumentAvailableInMainFrame event. web_contents()->SendToAllFrames( new GinJavaBridgeMsg_RemoveNamedObject(MSG_ROUTING_NONE, copied_name)); diff --git a/content/public/android/javatests/src/org/chromium/content/browser/JavaBridgeBasicsTest.java b/content/public/android/javatests/src/org/chromium/content/browser/JavaBridgeBasicsTest.java index a2d5ad81d1..b19a6b2748 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/JavaBridgeBasicsTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/JavaBridgeBasicsTest.java @@ -172,15 +172,27 @@ public class JavaBridgeBasicsTest extends JavaBridgeTestBase { @SmallTest @Feature({"AndroidWebView", "Android-JavaBridge"}) public void testRemovalNotReflectedUntilReload() throws Throwable { - injectObjectAndReload(new Object(), "testObject"); + injectObjectAndReload(new Object() { + public void method() { + mTestController.setStringValue("I'm here"); + } + }, "testObject"); assertEquals("object", executeJavaScriptAndGetStringResult("typeof testObject")); + executeJavaScript("testObject.method()"); + assertEquals("I'm here", mTestController.waitForStringValue()); runTestOnUiThread(new Runnable() { @Override public void run() { getContentViewCore().removeJavascriptInterface("testObject"); } }); + // Check that the 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 if called via Runtime. + Runtime.getRuntime().gc(); assertEquals("object", executeJavaScriptAndGetStringResult("typeof testObject")); + executeJavaScript("testObject.method()"); + assertEquals("I'm here", mTestController.waitForStringValue()); synchronousPageReload(); assertEquals("undefined", executeJavaScriptAndGetStringResult("typeof testObject")); } |