Hook up ContentViewCore.add/removeJavascriptInterface()

The entry point to the Java Bridge is JavaBridgeDispatcherHostManager. This is
not part of the content API so is available only on WebContentsImpl, not
WebContents. We therefore modify ContentViewCoreImpl to store and use
WebContentsImpl*, rather than WebContents*. It's safe for ContentViewCoreImpl
to cast the WebContents* it receives in its constructor to WebContentsImpl*
because WebContentsImpl is the only concrete implementation of the WebContents
interface.

BUG=110637

Committed: https://src.chromium.org/viewvc/chrome?view=rev&revision=148945

Review URL: https://chromiumcodereview.appspot.com/9192008

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@148951 0039d316-1c4b-4281-b951-d872f2087c98
parent c1965eac
...@@ -10,6 +10,8 @@ ...@@ -10,6 +10,8 @@
#include "base/android/scoped_java_ref.h" #include "base/android/scoped_java_ref.h"
#include "content/browser/android/content_view_client.h" #include "content/browser/android/content_view_client.h"
#include "content/browser/android/touch_point.h" #include "content/browser/android/touch_point.h"
#include "content/browser/renderer_host/java/java_bound_object.h"
#include "content/browser/renderer_host/java/java_bridge_dispatcher_host_manager.h"
#include "content/browser/renderer_host/render_view_host_impl.h" #include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_impl.h" #include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_view_android.h" #include "content/browser/renderer_host/render_widget_host_view_android.h"
...@@ -18,11 +20,13 @@ ...@@ -18,11 +20,13 @@
#include "content/public/browser/interstitial_page.h" #include "content/public/browser/interstitial_page.h"
#include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents.h"
#include "jni/ContentViewCore_jni.h" #include "jni/ContentViewCore_jni.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebBindings.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/android/WebInputEventFactory.h" #include "third_party/WebKit/Source/WebKit/chromium/public/android/WebInputEventFactory.h"
#include "webkit/glue/webmenuitem.h" #include "webkit/glue/webmenuitem.h"
using base::android::AttachCurrentThread; using base::android::AttachCurrentThread;
using base::android::ConvertJavaStringToUTF16;
using base::android::ConvertUTF16ToJavaString; using base::android::ConvertUTF16ToJavaString;
using base::android::ConvertUTF8ToJavaString; using base::android::ConvertUTF8ToJavaString;
using base::android::GetClass; using base::android::GetClass;
...@@ -72,7 +76,7 @@ ContentViewCore* ContentViewCore::GetNativeContentViewCore(JNIEnv* env, ...@@ -72,7 +76,7 @@ ContentViewCore* ContentViewCore::GetNativeContentViewCore(JNIEnv* env,
ContentViewCoreImpl::ContentViewCoreImpl(JNIEnv* env, jobject obj, ContentViewCoreImpl::ContentViewCoreImpl(JNIEnv* env, jobject obj,
WebContents* web_contents) WebContents* web_contents)
: web_contents_(web_contents), : web_contents_(static_cast<WebContentsImpl*>(web_contents)),
tab_crashed_(false) { tab_crashed_(false) {
DCHECK(web_contents) << DCHECK(web_contents) <<
"A ContentViewCoreImpl should be created with a valid WebContents."; "A ContentViewCoreImpl should be created with a valid WebContents.";
...@@ -313,6 +317,29 @@ void ContentViewCoreImpl::SetClient(JNIEnv* env, jobject obj, jobject jclient) { ...@@ -313,6 +317,29 @@ void ContentViewCoreImpl::SetClient(JNIEnv* env, jobject obj, jobject jclient) {
content_view_client_.swap(client); content_view_client_.swap(client);
} }
void ContentViewCoreImpl::AddJavascriptInterface(
JNIEnv* env,
jobject /* obj */,
jobject object,
jstring name,
jboolean allow_inherited_methods) {
ScopedJavaLocalRef<jobject> scoped_object(env, object);
// JavaBoundObject creates the NPObject with a ref count of 1, and
// JavaBridgeDispatcherHostManager takes its own ref.
NPObject* bound_object = JavaBoundObject::Create(scoped_object,
allow_inherited_methods);
web_contents_->java_bridge_dispatcher_host_manager()->AddNamedObject(
ConvertJavaStringToUTF16(env, name), bound_object);
WebKit::WebBindings::releaseObject(bound_object);
}
void ContentViewCoreImpl::RemoveJavascriptInterface(JNIEnv* env,
jobject /* obj */,
jstring name) {
web_contents_->java_bridge_dispatcher_host_manager()->RemoveNamedObject(
ConvertJavaStringToUTF16(env, name));
}
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
// Methods called from native code // Methods called from native code
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include "base/memory/scoped_ptr.h" #include "base/memory/scoped_ptr.h"
#include "base/process.h" #include "base/process.h"
#include "content/browser/renderer_host/render_widget_host_view_android.h" #include "content/browser/renderer_host/render_widget_host_view_android.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/android/content_view_core.h" #include "content/public/browser/android/content_view_core.h"
#include "content/public/browser/notification_observer.h" #include "content/public/browser/notification_observer.h"
#include "googleurl/src/gurl.h" #include "googleurl/src/gurl.h"
...@@ -33,6 +34,8 @@ class ContentViewCoreImpl : public ContentViewCore, ...@@ -33,6 +34,8 @@ class ContentViewCoreImpl : public ContentViewCore,
ContentViewCoreImpl(JNIEnv* env, ContentViewCoreImpl(JNIEnv* env,
jobject obj, jobject obj,
WebContents* web_contents); WebContents* web_contents);
// ContentViewCore overrides
virtual void Destroy(JNIEnv* env, jobject obj) OVERRIDE; virtual void Destroy(JNIEnv* env, jobject obj) OVERRIDE;
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
...@@ -108,6 +111,12 @@ class ContentViewCoreImpl : public ContentViewCore, ...@@ -108,6 +111,12 @@ class ContentViewCoreImpl : public ContentViewCore,
jboolean NeedsReload(JNIEnv* env, jobject obj); jboolean NeedsReload(JNIEnv* env, jobject obj);
void ClearHistory(JNIEnv* env, jobject obj); void ClearHistory(JNIEnv* env, jobject obj);
void SetClient(JNIEnv* env, jobject obj, jobject jclient); void SetClient(JNIEnv* env, jobject obj, jobject jclient);
void AddJavascriptInterface(JNIEnv* env,
jobject obj,
jobject object,
jstring name,
jboolean allow_inherited_methods);
void RemoveJavascriptInterface(JNIEnv* env, jobject obj, jstring name);
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
// Public methods that call to Java via JNI // Public methods that call to Java via JNI
...@@ -186,7 +195,7 @@ class ContentViewCoreImpl : public ContentViewCore, ...@@ -186,7 +195,7 @@ class ContentViewCoreImpl : public ContentViewCore,
// Reference to the current WebContents used to determine how and what to // Reference to the current WebContents used to determine how and what to
// display in the ContentViewCore. // display in the ContentViewCore.
WebContents* web_contents_; WebContentsImpl* web_contents_;
// We only set this to be the delegate of the web_contents if we own it. // We only set this to be the delegate of the web_contents if we own it.
scoped_ptr<ContentViewClient> content_view_client_; scoped_ptr<ContentViewClient> content_view_client_;
......
...@@ -130,7 +130,7 @@ public class ContentViewCore implements MotionEventDelegate { ...@@ -130,7 +130,7 @@ public class ContentViewCore implements MotionEventDelegate {
private ContentSettings mContentSettings; private ContentSettings mContentSettings;
// Native pointer to C++ ContentView object which will be set by nativeInit() // Native pointer to C++ ContentViewCoreImpl object which will be set by nativeInit().
private int mNativeContentViewCore = 0; private int mNativeContentViewCore = 0;
private ContentViewGestureHandler mContentViewGestureHandler; private ContentViewGestureHandler mContentViewGestureHandler;
...@@ -854,6 +854,58 @@ public class ContentViewCore implements MotionEventDelegate { ...@@ -854,6 +854,58 @@ public class ContentViewCore implements MotionEventDelegate {
return mZoomManager.getZoomControlsViewForTest(); return mZoomManager.getZoomControlsViewForTest();
} }
/**
* This method injects the supplied Java object into the ContentViewCore.
* The object is injected into the JavaScript context of the main frame,
* using the supplied name. This allows the Java object to be accessed from
* JavaScript. Note that that injected objects will not appear in
* JavaScript until the page is next (re)loaded. For example:
* <pre> view.addJavascriptInterface(new Object(), "injectedObject");
* view.loadData("<!DOCTYPE html><title></title>", "text/html", null);
* view.loadUrl("javascript:alert(injectedObject.toString())");</pre>
* <p><strong>IMPORTANT:</strong>
* <ul>
* <li> addJavascriptInterface() can be used to allow JavaScript to control
* the host application. This is a powerful feature, but also presents a
* security risk. Use of this method in a ContentViewCore containing
* untrusted content could allow an attacker to manipulate the host
* application in unintended ways, executing Java code with the permissions
* of the host application. Use extreme care when using this method in a
* ContentViewCore which could contain untrusted content. Particular care
* should be taken to avoid unintentional access to inherited methods, such
* as {@link Object#getClass()}. To prevent access to inherited methods,
* set {@code allowInheritedMethods} to {@code false}. In addition, ensure
* that the injected object's public methods return only objects designed
* to be used by untrusted code, and never return a raw Object instance.
* <li> JavaScript interacts with Java objects on a private, background
* thread of the ContentViewCore. Care is therefore required to maintain
* thread safety.</li>
* </ul></p>
*
* @param object The Java object to inject into the ContentViewCore's
* JavaScript context. Null values are ignored.
* @param name The name used to expose the instance in JavaScript.
* @param allowInheritedMethods Whether or not inherited methods may be
* called from JavaScript.
*/
public void addJavascriptInterface(Object object, String name, boolean allowInheritedMethods) {
if (mNativeContentViewCore != 0 && object != null) {
nativeAddJavascriptInterface(mNativeContentViewCore, object, name,
allowInheritedMethods);
}
}
/**
* Removes a previously added JavaScript interface with the given name.
*
* @param name The name of the interface to remove.
*/
public void removeJavascriptInterface(String name) {
if (mNativeContentViewCore != 0) {
nativeRemoveJavascriptInterface(mNativeContentViewCore, name);
}
}
@CalledByNative @CalledByNative
private void startContentIntent(String contentUrl) { private void startContentIntent(String contentUrl) {
getContentViewClient().onStartContentIntent(getContext(), contentUrl); getContentViewClient().onStartContentIntent(getContext(), contentUrl);
...@@ -948,4 +1000,9 @@ public class ContentViewCore implements MotionEventDelegate { ...@@ -948,4 +1000,9 @@ public class ContentViewCore implements MotionEventDelegate {
private native boolean nativeNeedsReload(int nativeContentViewCoreImpl); private native boolean nativeNeedsReload(int nativeContentViewCoreImpl);
private native void nativeClearHistory(int nativeContentViewCoreImpl); private native void nativeClearHistory(int nativeContentViewCoreImpl);
private native void nativeAddJavascriptInterface(int nativeContentViewCoreImpl, Object object,
String name, boolean allowInheritedMethods);
private native void nativeRemoveJavascriptInterface(int nativeContentViewCoreImpl, String name);
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment