summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMikhail Naganov <mnaganov@google.com>2014-12-02 17:43:15 +0000
committerMikhail Naganov <mnaganov@google.com>2014-12-09 13:46:37 +0000
commit83eff5096b2d7faaad5ebabc0a49f34aeb850acd (patch)
tree49a550e9d72961cd7494cfa811742e58571d2a9b
parentda3325133c7b4c33bde752ab853a50db8016e1b5 (diff)
downloadchromium_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.cc16
-rw-r--r--content/public/android/javatests/src/org/chromium/content/browser/JavaBridgeBasicsTest.java14
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"));
}