Cherrypick: [Android] Switch to Gin Java Bridge implementation
Original description:
> What this patch does:
>
> -- plumbs in GinJavaBridge... instead of JavaBridge... classes on
> browser and renderer sides;
>
> -- fixes the issue with adding JavaScript interfaces to popup windows
> created via WebChromeClient.onCreatePopup;
>
> -- updates JavaBridge tests to match the behaviour of the new
> implementation.
>
> BUG=355644
>
> Review URL: https://codereview.chromium.org/353163002
>
> git-svn-id: svn://svn.chromium.org/chrome/trunk/src@282004 0039d316-1c4b-4281-b951-d872f2087c98
Bug: 13238305
Change-Id: I3c42dea96c28aa439b53e6efaab70d24150f1536
diff --git a/android_webview/java/src/org/chromium/android_webview/AwContents.java b/android_webview/java/src/org/chromium/android_webview/AwContents.java
index df19d57..2b3d278 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwContents.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwContents.java
@@ -23,6 +23,7 @@
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;
+import android.util.Pair;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
@@ -645,6 +646,13 @@
if (wasAttached) onDetachedFromWindow();
if (!wasPaused) onPause();
+ // Save injected JavaScript interfaces.
+ Map<String, Pair<Object, Class>> javascriptInterfaces =
+ new HashMap<String, Pair<Object, Class>>();
+ if (mContentViewCore != null) {
+ javascriptInterfaces.putAll(mContentViewCore.getJavascriptInterfaces());
+ }
+
setNewAwContents(popupNativeAwContents);
// Finally refresh all view state for mContentViewCore and mNativeAwContents.
@@ -658,6 +666,14 @@
if (wasViewVisible) setViewVisibilityInternal(true);
if (wasWindowFocused) onWindowFocusChanged(wasWindowFocused);
if (wasFocused) onFocusChanged(true, 0, null);
+
+ // Restore injected JavaScript interfaces.
+ for (Map.Entry<String, Pair<Object, Class>> entry : javascriptInterfaces.entrySet()) {
+ mContentViewCore.addPossiblyUnsafeJavascriptInterface(
+ entry.getValue().first,
+ entry.getKey(),
+ entry.getValue().second);
+ }
}
/**
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwSettingsTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwSettingsTest.java
index d6ac546..188fccf 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/AwSettingsTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwSettingsTest.java
@@ -1940,7 +1940,7 @@
createAwTestContainerViewOnMainSync(contentClient);
final AwContents awContents = testContainer.getAwContents();
final AwSettings awSettings = getAwSettingsOnUiThread(awContents);
- CallbackHelper callback = new CallbackHelper();
+ final CallbackHelper callback = new CallbackHelper();
awSettings.setJavaScriptEnabled(true);
TestWebServer webServer = null;
@@ -1956,8 +1956,13 @@
"onerror=\"AudioEvent.onError();\" /> </body></html>";
// Actual test. Blocking should trigger onerror handler.
awSettings.setBlockNetworkLoads(true);
- awContents.addPossiblyUnsafeJavascriptInterface(
- new AudioEvent(callback), "AudioEvent", null);
+ runTestOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ awContents.addPossiblyUnsafeJavascriptInterface(
+ new AudioEvent(callback), "AudioEvent", null);
+ }
+ });
int count = callback.getCallCount();
loadDataSync(awContents, contentClient.getOnPageFinishedHelper(), pageHtml,
"text/html", false);
diff --git a/content/browser/android/content_view_core_impl.cc b/content/browser/android/content_view_core_impl.cc
index 6e533fc..1992f7d 100644
--- a/content/browser/android/content_view_core_impl.cc
+++ b/content/browser/android/content_view_core_impl.cc
@@ -19,8 +19,7 @@
#include "cc/output/begin_frame_args.h"
#include "content/browser/android/gesture_event_type.h"
#include "content/browser/android/interstitial_page_delegate_android.h"
-#include "content/browser/android/java/java_bound_object.h"
-#include "content/browser/android/java/java_bridge_dispatcher_host_manager.h"
+#include "content/browser/android/java/gin_java_bridge_dispatcher_host.h"
#include "content/browser/android/load_url_params.h"
#include "content/browser/frame_host/interstitial_page_impl.h"
#include "content/browser/frame_host/navigation_controller_impl.h"
@@ -52,7 +51,6 @@
#include "content/public/common/page_transition_types.h"
#include "content/public/common/user_agent.h"
#include "jni/ContentViewCore_jni.h"
-#include "third_party/WebKit/public/web/WebBindings.h"
#include "third_party/WebKit/public/web/WebInputEvent.h"
#include "ui/base/android/view_android.h"
#include "ui/base/android/window_android.h"
@@ -244,9 +242,9 @@
BuildUserAgentFromOSAndProduct(kLinuxInfoStr, product);
web_contents->SetUserAgentOverride(spoofed_ua);
- java_bridge_dispatcher_host_manager_.reset(
- new JavaBridgeDispatcherHostManager(web_contents,
- java_bridge_retained_object_set));
+ java_bridge_dispatcher_host_.reset(
+ new GinJavaBridgeDispatcherHost(web_contents,
+ java_bridge_retained_object_set));
InitWebContents();
}
@@ -1222,7 +1220,7 @@
JNIEnv* env,
jobject obj,
jboolean allow) {
- java_bridge_dispatcher_host_manager_->SetAllowObjectContentsInspection(allow);
+ java_bridge_dispatcher_host_->SetAllowObjectContentsInspection(allow);
}
void ContentViewCoreImpl::AddJavascriptInterface(
@@ -1233,24 +1231,15 @@
jclass safe_annotation_clazz) {
ScopedJavaLocalRef<jobject> scoped_object(env, object);
ScopedJavaLocalRef<jclass> scoped_clazz(env, safe_annotation_clazz);
-
- // JavaBoundObject creates the NPObject with a ref count of 1, and
- // JavaBridgeDispatcherHostManager takes its own ref.
- NPObject* bound_object = JavaBoundObject::Create(
- scoped_object,
- scoped_clazz,
- java_bridge_dispatcher_host_manager_->AsWeakPtr(),
- java_bridge_dispatcher_host_manager_->GetAllowObjectContentsInspection());
- java_bridge_dispatcher_host_manager_->AddNamedObject(
- ConvertJavaStringToUTF16(env, name), bound_object);
- blink::WebBindings::releaseObject(bound_object);
+ java_bridge_dispatcher_host_->AddNamedObject(
+ ConvertJavaStringToUTF8(env, name), scoped_object, scoped_clazz);
}
void ContentViewCoreImpl::RemoveJavascriptInterface(JNIEnv* env,
jobject /* obj */,
jstring name) {
- java_bridge_dispatcher_host_manager_->RemoveNamedObject(
- ConvertJavaStringToUTF16(env, name));
+ java_bridge_dispatcher_host_->RemoveNamedObject(
+ ConvertJavaStringToUTF8(env, name));
}
void ContentViewCoreImpl::WasResized(JNIEnv* env, jobject obj) {
diff --git a/content/browser/android/content_view_core_impl.h b/content/browser/android/content_view_core_impl.h
index 3bb1291..62ed68b 100644
--- a/content/browser/android/content_view_core_impl.h
+++ b/content/browser/android/content_view_core_impl.h
@@ -28,7 +28,7 @@
}
namespace content {
-class JavaBridgeDispatcherHostManager;
+class GinJavaBridgeDispatcherHost;
class RenderWidgetHostViewAndroid;
struct MenuItem;
@@ -380,8 +380,8 @@
bool accessibility_enabled_;
// Manages injecting Java objects.
- scoped_ptr<JavaBridgeDispatcherHostManager>
- java_bridge_dispatcher_host_manager_;
+ scoped_ptr<GinJavaBridgeDispatcherHost>
+ java_bridge_dispatcher_host_;
DISALLOW_COPY_AND_ASSIGN(ContentViewCoreImpl);
};
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 a60310d..6526381 100644
--- a/content/browser/android/java/gin_java_bridge_dispatcher_host.cc
+++ b/content/browser/android/java/gin_java_bridge_dispatcher_host.cc
@@ -18,6 +18,7 @@
#include "content/common/gin_java_bridge_messages.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_frame_host.h"
+#include "content/public/browser/web_contents.h"
#include "ipc/ipc_message_utils.h"
#if !defined(OS_ANDROID)
@@ -59,7 +60,6 @@
void GinJavaBridgeDispatcherHost::RenderFrameCreated(
RenderFrameHost* render_frame_host) {
- renderers_.insert(render_frame_host);
for (NamedObjectMap::const_iterator iter = named_objects_.begin();
iter != named_objects_.end();
++iter) {
@@ -70,7 +70,6 @@
void GinJavaBridgeDispatcherHost::RenderFrameDeleted(
RenderFrameHost* render_frame_host) {
- renderers_.erase(render_frame_host);
RemoveHolder(render_frame_host,
GinJavaBoundObject::ObjectMap::iterator(&objects_),
objects_.size());
@@ -182,11 +181,8 @@
}
named_objects_[name] = object_id;
- for (RendererSet::iterator iter = renderers_.begin();
- iter != renderers_.end(); ++iter) {
- (*iter)->Send(new GinJavaBridgeMsg_AddNamedObject(
- (*iter)->GetRoutingID(), name, object_id));
- }
+ web_contents()->SendToAllFrames(
+ new GinJavaBridgeMsg_AddNamedObject(MSG_ROUTING_NONE, name, object_id));
}
void GinJavaBridgeDispatcherHost::RemoveNamedObject(
@@ -213,11 +209,8 @@
}
}
- for (RendererSet::iterator iter = renderers_.begin();
- iter != renderers_.end(); ++iter) {
- (*iter)->Send(new GinJavaBridgeMsg_RemoveNamedObject(
- (*iter)->GetRoutingID(), name));
- }
+ web_contents()->SendToAllFrames(
+ new GinJavaBridgeMsg_RemoveNamedObject(MSG_ROUTING_NONE, name));
}
void GinJavaBridgeDispatcherHost::SetAllowObjectContentsInspection(bool allow) {
@@ -319,11 +312,47 @@
return handled;
}
+namespace {
+
+class IsValidRenderFrameHostHelper
+ : public base::RefCounted<IsValidRenderFrameHostHelper> {
+ public:
+ explicit IsValidRenderFrameHostHelper(RenderFrameHost* rfh_to_match)
+ : rfh_to_match_(rfh_to_match), rfh_found_(false) {}
+
+ bool rfh_found() { return rfh_found_; }
+
+ void OnFrame(RenderFrameHost* rfh) {
+ if (rfh_to_match_ == rfh) rfh_found_ = true;
+ }
+
+ private:
+ friend class base::RefCounted<IsValidRenderFrameHostHelper>;
+
+ ~IsValidRenderFrameHostHelper() {}
+
+ RenderFrameHost* rfh_to_match_;
+ bool rfh_found_;
+
+ DISALLOW_COPY_AND_ASSIGN(IsValidRenderFrameHostHelper);
+};
+
+} // namespace
+
+bool GinJavaBridgeDispatcherHost::IsValidRenderFrameHost(
+ RenderFrameHost* render_frame_host) {
+ scoped_refptr<IsValidRenderFrameHostHelper> helper =
+ new IsValidRenderFrameHostHelper(render_frame_host);
+ web_contents()->ForEachFrame(
+ base::Bind(&IsValidRenderFrameHostHelper::OnFrame, helper));
+ return helper->rfh_found();
+}
+
void GinJavaBridgeDispatcherHost::SendReply(
RenderFrameHost* render_frame_host,
IPC::Message* reply_msg) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- if (renderers_.find(render_frame_host) != renderers_.end()) {
+ if (IsValidRenderFrameHost(render_frame_host)) {
render_frame_host->Send(reply_msg);
} else {
delete reply_msg;
@@ -455,7 +484,7 @@
IPC::Message* reply_msg,
scoped_refptr<GinJavaMethodInvocationHelper> result) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- if (renderers_.find(render_frame_host) == renderers_.end()) {
+ if (!IsValidRenderFrameHost(render_frame_host)) {
delete reply_msg;
return;
}
diff --git a/content/browser/android/java/gin_java_bridge_dispatcher_host.h b/content/browser/android/java/gin_java_bridge_dispatcher_host.h
index 3ccd46f..615c2b0 100644
--- a/content/browser/android/java/gin_java_bridge_dispatcher_host.h
+++ b/content/browser/android/java/gin_java_bridge_dispatcher_host.h
@@ -72,10 +72,10 @@
IPC::Message* reply_msg);
private:
- typedef std::set<RenderFrameHost*> RendererSet;
void OnObjectWrapperDeleted(RenderFrameHost* render_frame_host,
GinJavaBoundObject::ObjectID object_id);
+ bool IsValidRenderFrameHost(RenderFrameHost* render_frame_host);
void SendReply(RenderFrameHost* render_frame_host, IPC::Message* reply_msg);
void SendMethods(RenderFrameHost* render_frame_host,
IPC::Message* reply_msg,
@@ -110,7 +110,6 @@
// roots that would prevent ContentViewCore from being garbage collected.
JavaObjectWeakGlobalRef retained_object_set_;
bool allow_object_contents_inspection_;
- RendererSet renderers_;
GinJavaBoundObject::ObjectMap objects_;
typedef std::map<std::string, GinJavaBoundObject::ObjectID> NamedObjectMap;
NamedObjectMap named_objects_;
diff --git a/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java b/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java
index 7f6d364..0d13332 100644
--- a/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java
+++ b/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java
@@ -29,6 +29,7 @@
import android.text.Selection;
import android.text.TextUtils;
import android.util.Log;
+import android.util.Pair;
import android.view.ActionMode;
import android.view.HapticFeedbackConstants;
import android.view.InputDevice;
@@ -117,9 +118,12 @@
// native side. However we still need a strong reference on the Java side to
// prevent garbage collection if the embedder doesn't maintain their own ref to the
// interface object - the Java side ref won't create a new GC root.
- // This map stores those refernces. We put into the map on addJavaScriptInterface()
- // and remove from it in removeJavaScriptInterface().
- private final Map<String, Object> mJavaScriptInterfaces = new HashMap<String, Object>();
+ // This map stores those references. We put into the map on addJavaScriptInterface()
+ // and remove from it in removeJavaScriptInterface(). The annotation class is stored for
+ // the purpose of migrating injected objects from one instance of CVC to another, which
+ // is used by Android WebView to support WebChromeClient.onCreateWindow scenario.
+ private final Map<String, Pair<Object, Class>> mJavaScriptInterfaces =
+ new HashMap<String, Pair<Object, Class>>();
// Additionally, we keep track of all Java bound JS objects that are in use on the
// current page to ensure that they are not garbage collected until the page is
@@ -2615,6 +2619,16 @@
}
/**
+ * Returns JavaScript interface objects previously injected via
+ * {@link #addJavascriptInterface(Object, String)}.
+ *
+ * @return the mapping of names to interface objects and corresponding annotation classes
+ */
+ public Map<String, Pair<Object, Class>> getJavascriptInterfaces() {
+ return mJavaScriptInterfaces;
+ }
+
+ /**
* This will mimic {@link #addPossiblyUnsafeJavascriptInterface(Object, String, Class)}
* and automatically pass in {@link JavascriptInterface} as the required annotation.
*
@@ -2671,7 +2685,7 @@
public void addPossiblyUnsafeJavascriptInterface(Object object, String name,
Class<? extends Annotation> requiredAnnotation) {
if (mNativeContentViewCore != 0 && object != null) {
- mJavaScriptInterfaces.put(name, object);
+ mJavaScriptInterfaces.put(name, new Pair<Object, Class>(object, requiredAnnotation));
nativeAddJavascriptInterface(mNativeContentViewCore, object, name, requiredAnnotation);
}
}
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/JavaBridgeArrayCoercionTest.java b/content/public/android/javatests/src/org/chromium/content/browser/JavaBridgeArrayCoercionTest.java
index 2525a58..bf5823b 100644
--- a/content/public/android/javatests/src/org/chromium/content/browser/JavaBridgeArrayCoercionTest.java
+++ b/content/public/android/javatests/src/org/chromium/content/browser/JavaBridgeArrayCoercionTest.java
@@ -169,9 +169,8 @@
executeJavaScript("testObject.setByteArray([42]);");
assertEquals(42, mTestObject.waitForByteArray()[0]);
- // LIVECONNECT_COMPLIANCE: Should convert to numeric char value.
executeJavaScript("testObject.setCharArray([42]);");
- assertEquals('\u0000', mTestObject.waitForCharArray()[0]);
+ assertEquals(42, mTestObject.waitForCharArray()[0]);
executeJavaScript("testObject.setShortArray([42]);");
assertEquals(42, mTestObject.waitForShortArray()[0]);
@@ -643,7 +642,7 @@
assertEquals(42, mTestObject.waitForByteArray()[0]);
executeJavaScript("testObject.setCharArray(int8_array);");
- assertEquals('\u0000', mTestObject.waitForCharArray()[0]);
+ assertEquals(42, mTestObject.waitForCharArray()[0]);
executeJavaScript("testObject.setShortArray(int8_array);");
assertEquals(42, mTestObject.waitForShortArray()[0]);
@@ -685,7 +684,7 @@
assertEquals(42, mTestObject.waitForByteArray()[0]);
executeJavaScript("testObject.setCharArray(uint8_array);");
- assertEquals('\u0000', mTestObject.waitForCharArray()[0]);
+ assertEquals(42, mTestObject.waitForCharArray()[0]);
executeJavaScript("testObject.setShortArray(uint8_array);");
assertEquals(42, mTestObject.waitForShortArray()[0]);
@@ -727,7 +726,7 @@
assertEquals(42, mTestObject.waitForByteArray()[0]);
executeJavaScript("testObject.setCharArray(int16_array);");
- assertEquals('\u0000', mTestObject.waitForCharArray()[0]);
+ assertEquals(42, mTestObject.waitForCharArray()[0]);
executeJavaScript("testObject.setShortArray(int16_array);");
assertEquals(42, mTestObject.waitForShortArray()[0]);
@@ -769,7 +768,7 @@
assertEquals(42, mTestObject.waitForByteArray()[0]);
executeJavaScript("testObject.setCharArray(uint16_array);");
- assertEquals('\u0000', mTestObject.waitForCharArray()[0]);
+ assertEquals(42, mTestObject.waitForCharArray()[0]);
executeJavaScript("testObject.setShortArray(uint16_array);");
assertEquals(42, mTestObject.waitForShortArray()[0]);
@@ -811,7 +810,7 @@
assertEquals(42, mTestObject.waitForByteArray()[0]);
executeJavaScript("testObject.setCharArray(int32_array);");
- assertEquals('\u0000', mTestObject.waitForCharArray()[0]);
+ assertEquals(42, mTestObject.waitForCharArray()[0]);
executeJavaScript("testObject.setShortArray(int32_array);");
assertEquals(42, mTestObject.waitForShortArray()[0]);
@@ -853,7 +852,7 @@
assertEquals(42, mTestObject.waitForByteArray()[0]);
executeJavaScript("testObject.setCharArray(uint32_array);");
- assertEquals('\u0000', mTestObject.waitForCharArray()[0]);
+ assertEquals(42, mTestObject.waitForCharArray()[0]);
executeJavaScript("testObject.setShortArray(uint32_array);");
assertEquals(42, mTestObject.waitForShortArray()[0]);
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 3ce9a2c..ae58a1d 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
@@ -4,11 +4,8 @@
package org.chromium.content.browser;
-import android.os.Handler;
-import android.os.Looper;
import android.test.suitebuilder.annotation.SmallTest;
-import org.chromium.base.test.util.DisabledTest;
import org.chromium.base.test.util.Feature;
import org.chromium.content.browser.test.util.TestCallbackHelperContainer;
import org.chromium.content_shell_apk.ContentShellActivity;
@@ -462,19 +459,8 @@
assertEquals(null, object.weakRefForInner.get());
}
- /*
- * The current Java bridge implementation doesn't reuse JS wrappers when returning
- * the same object from a method. That looks wrong. For example, in the case of DOM,
- * wrappers are reused, which allows JS code to attach custom properties to interface
- * objects and use them regardless of the way the reference has been obtained:
- * via copying a JS reference or by calling the method one more time (assuming that
- * the method is supposed to return a reference to the same object each time).
- * TODO(mnaganov): Fix this in the new implementation.
- *
- * @SmallTest
- * @Feature({"AndroidWebView", "Android-JavaBridge"})
- */
- @DisabledTest
+ @SmallTest
+ @Feature({"AndroidWebView", "Android-JavaBridge"})
public void testSameReturnedObjectUsesSameWrapper() throws Throwable {
class InnerObject {
}
@@ -853,60 +839,6 @@
public void testAccessToObjectGetClassIsBlocked() throws Throwable {
injectObjectAndReload(new Object(), "testObject");
assertEquals("function", executeJavaScriptAndGetStringResult("typeof testObject.getClass"));
- boolean securityExceptionThrown = false;
- try {
- final String result = executeJavaScriptAndWaitForExceptionSynchronously(
- "typeof testObject.getClass()");
- fail("A call to java.lang.Object.getClass has been allowed, result: '" + result + "'");
- } catch (SecurityException exception) {
- securityExceptionThrown = true;
- }
- assertTrue(securityExceptionThrown);
- }
-
- // Unlike executeJavaScriptAndGetStringResult, this method is sitting on the UI thread
- // until a non-null result is obtained or a Java exception has been thrown. This method is
- // capable of catching Java RuntimeExceptions happening on the UI thread asynchronously.
- private String executeJavaScriptAndWaitForExceptionSynchronously(final String script)
- throws Throwable {
- class ExitLoopException extends RuntimeException {
- }
- mTestController.setStringValue(null);
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- getContentViewCore().loadUrl(new LoadUrlParams("javascript:(function() { " +
- "testController.setStringValue(" + script + ") })()"));
- do {
- final Boolean[] deactivateExitLoopTask = new Boolean[1];
- deactivateExitLoopTask[0] = false;
- // We can't use Loop.quit(), as this is the main looper, so we throw
- // an exception to bail out from the loop.
- new Handler(Looper.myLooper()).post(new Runnable() {
- @Override
- public void run() {
- if (!deactivateExitLoopTask[0]) {
- throw new ExitLoopException();
- }
- }
- });
- try {
- Looper.loop();
- } catch (ExitLoopException e) {
- // Intentionally empty.
- } catch (RuntimeException e) {
- // Prevent the task that throws the ExitLoopException from exploding
- // on the main loop outside of this function.
- deactivateExitLoopTask[0] = true;
- throw e;
- }
- } while (mTestController.getStringValue() == null ||
- // When an exception in an injected method happens, the function returns
- // null. We ignore this and wait until the exception on the browser side
- // will be thrown.
- mTestController.getStringValue().equals("null"));
- }
- });
- return mTestController.getStringValue();
+ assertRaisesException("testObject.getClass()");
}
}
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/JavaBridgeCoercionTest.java b/content/public/android/javatests/src/org/chromium/content/browser/JavaBridgeCoercionTest.java
index c344416..472b253 100644
--- a/content/public/android/javatests/src/org/chromium/content/browser/JavaBridgeCoercionTest.java
+++ b/content/public/android/javatests/src/org/chromium/content/browser/JavaBridgeCoercionTest.java
@@ -172,9 +172,8 @@
executeJavaScript("testObject.setByteValue(" + Byte.MAX_VALUE + " + 42);");
assertEquals(Byte.MIN_VALUE + 42 - 1, mTestObject.waitForByteValue());
- // LIVECONNECT_COMPLIANCE: Should convert to numeric char value.
executeJavaScript("testObject.setCharValue(42);");
- assertEquals('\u0000', mTestObject.waitForCharValue());
+ assertEquals(42, mTestObject.waitForCharValue());
executeJavaScript("testObject.setShortValue(42);");
assertEquals(42, mTestObject.waitForShortValue());
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index 335bd75..1c7a96f 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -59,7 +59,6 @@
#include "content/renderer/image_loading_helper.h"
#include "content/renderer/ime_event_guard.h"
#include "content/renderer/internal_document_state_data.h"
-#include "content/renderer/java/java_bridge_dispatcher.h"
#include "content/renderer/media/audio_renderer_mixer_manager.h"
#include "content/renderer/media/media_stream_dispatcher.h"
#include "content/renderer/media/media_stream_impl.h"
@@ -128,6 +127,7 @@
#include "content/common/gpu/client/context_provider_command_buffer.h"
#include "content/renderer/android/synchronous_compositor_factory.h"
+#include "content/renderer/java/gin_java_bridge_dispatcher.h"
#include "content/renderer/media/android/renderer_media_player_manager.h"
#include "content/renderer/media/android/stream_texture_factory_impl.h"
#include "content/renderer/media/android/webmediaplayer_android.h"
@@ -417,7 +417,7 @@
render_view_->RegisterRenderFrame(this);
#if defined(OS_ANDROID)
- new JavaBridgeDispatcher(this);
+ new GinJavaBridgeDispatcher(this);
#endif
#if defined(ENABLE_NOTIFICATIONS)