summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--content/browser/android/content_view_core_impl.cc29
-rw-r--r--content/browser/android/content_view_core_impl.h11
-rw-r--r--content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java59
3 files changed, 96 insertions, 3 deletions
diff --git a/content/browser/android/content_view_core_impl.cc b/content/browser/android/content_view_core_impl.cc
index 21d3bd7..fd1ab9b 100644
--- a/content/browser/android/content_view_core_impl.cc
+++ b/content/browser/android/content_view_core_impl.cc
@@ -10,6 +10,8 @@
#include "base/android/scoped_java_ref.h"
#include "content/browser/android/content_view_client.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_widget_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_view_android.h"
@@ -18,11 +20,13 @@
#include "content/public/browser/interstitial_page.h"
#include "content/public/browser/web_contents.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/android/WebInputEventFactory.h"
#include "webkit/glue/webmenuitem.h"
using base::android::AttachCurrentThread;
+using base::android::ConvertJavaStringToUTF16;
using base::android::ConvertUTF16ToJavaString;
using base::android::ConvertUTF8ToJavaString;
using base::android::GetClass;
@@ -72,7 +76,7 @@ ContentViewCore* ContentViewCore::GetNativeContentViewCore(JNIEnv* env,
ContentViewCoreImpl::ContentViewCoreImpl(JNIEnv* env, jobject obj,
WebContents* web_contents)
- : web_contents_(web_contents),
+ : web_contents_(static_cast<WebContentsImpl*>(web_contents)),
tab_crashed_(false) {
DCHECK(web_contents) <<
"A ContentViewCoreImpl should be created with a valid WebContents.";
@@ -313,6 +317,29 @@ void ContentViewCoreImpl::SetClient(JNIEnv* env, jobject obj, jobject jclient) {
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
// --------------------------------------------------------------------------
diff --git a/content/browser/android/content_view_core_impl.h b/content/browser/android/content_view_core_impl.h
index 796c148..704725a 100644
--- a/content/browser/android/content_view_core_impl.h
+++ b/content/browser/android/content_view_core_impl.h
@@ -14,6 +14,7 @@
#include "base/memory/scoped_ptr.h"
#include "base/process.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/notification_observer.h"
#include "googleurl/src/gurl.h"
@@ -33,6 +34,8 @@ class ContentViewCoreImpl : public ContentViewCore,
ContentViewCoreImpl(JNIEnv* env,
jobject obj,
WebContents* web_contents);
+
+ // ContentViewCore overrides
virtual void Destroy(JNIEnv* env, jobject obj) OVERRIDE;
// --------------------------------------------------------------------------
@@ -108,6 +111,12 @@ class ContentViewCoreImpl : public ContentViewCore,
jboolean NeedsReload(JNIEnv* env, jobject obj);
void ClearHistory(JNIEnv* env, jobject obj);
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
@@ -186,7 +195,7 @@ class ContentViewCoreImpl : public ContentViewCore,
// Reference to the current WebContents used to determine how and what to
// 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.
scoped_ptr<ContentViewClient> content_view_client_;
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 ee08d3a..1d6364b 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
@@ -130,7 +130,7 @@ public class ContentViewCore implements MotionEventDelegate {
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 ContentViewGestureHandler mContentViewGestureHandler;
@@ -854,6 +854,58 @@ public class ContentViewCore implements MotionEventDelegate {
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
private void startContentIntent(String contentUrl) {
getContentViewClient().onStartContentIntent(getContext(), contentUrl);
@@ -948,4 +1000,9 @@ public class ContentViewCore implements MotionEventDelegate {
private native boolean nativeNeedsReload(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);
}