summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/java/android/webkit/BrowserFrame.java54
-rw-r--r--core/java/android/webkit/JavascriptInterface.java36
-rw-r--r--core/java/android/webkit/WebView.java4
-rw-r--r--core/java/android/webkit/WebViewClassic.java3
-rw-r--r--core/java/android/webkit/WebViewCore.java3
5 files changed, 87 insertions, 13 deletions
diff --git a/core/java/android/webkit/BrowserFrame.java b/core/java/android/webkit/BrowserFrame.java
index 6074a0c..9e4ec3c 100644
--- a/core/java/android/webkit/BrowserFrame.java
+++ b/core/java/android/webkit/BrowserFrame.java
@@ -89,8 +89,19 @@ class BrowserFrame extends Handler {
// Is this frame the main frame?
private boolean mIsMainFrame;
+ // Javascript interface object
+ private class JSObject {
+ Object object;
+ boolean requireAnnotation;
+
+ public JSObject(Object object, boolean requireAnnotation) {
+ this.object = object;
+ this.requireAnnotation = requireAnnotation;
+ }
+ }
+
// Attached Javascript interfaces
- private Map<String, Object> mJavaScriptObjects;
+ private Map<String, JSObject> mJavaScriptObjects;
private Set<Object> mRemovedJavaScriptObjects;
// Key store handler when Chromium HTTP stack is used.
@@ -234,10 +245,8 @@ class BrowserFrame extends Handler {
}
sConfigCallback.addHandler(this);
- mJavaScriptObjects = javascriptInterfaces;
- if (mJavaScriptObjects == null) {
- mJavaScriptObjects = new HashMap<String, Object>();
- }
+ mJavaScriptObjects = new HashMap<String, JSObject>();
+ addJavaScriptObjects(javascriptInterfaces);
mRemovedJavaScriptObjects = new HashSet<Object>();
mSettings = settings;
@@ -590,15 +599,36 @@ class BrowserFrame extends Handler {
Iterator<String> iter = mJavaScriptObjects.keySet().iterator();
while (iter.hasNext()) {
String interfaceName = iter.next();
- Object object = mJavaScriptObjects.get(interfaceName);
- if (object != null) {
+ JSObject jsobject = mJavaScriptObjects.get(interfaceName);
+ if (jsobject != null && jsobject.object != null) {
nativeAddJavascriptInterface(nativeFramePointer,
- mJavaScriptObjects.get(interfaceName), interfaceName);
+ jsobject.object, interfaceName, jsobject.requireAnnotation);
}
}
mRemovedJavaScriptObjects.clear();
}
+ /*
+ * Add javascript objects to the internal list of objects. The default behavior
+ * is to allow access to inherited methods (no annotation needed). This is only
+ * used when js objects are passed through a constructor (via a hidden constructor).
+ *
+ * @TODO change the default behavior to be compatible with the public addjavascriptinterface
+ */
+ private void addJavaScriptObjects(Map<String, Object> javascriptInterfaces) {
+
+ // TODO in a separate CL provide logic to enable annotations for API level JB_MR1 and above.
+ if (javascriptInterfaces == null) return;
+ Iterator<String> iter = javascriptInterfaces.keySet().iterator();
+ while (iter.hasNext()) {
+ String interfaceName = iter.next();
+ Object object = javascriptInterfaces.get(interfaceName);
+ if (object != null) {
+ mJavaScriptObjects.put(interfaceName, new JSObject(object, false));
+ }
+ }
+ }
+
/**
* This method is called by WebCore to check whether application
* wants to hijack url loading
@@ -616,11 +646,11 @@ class BrowserFrame extends Handler {
}
}
- public void addJavascriptInterface(Object obj, String interfaceName) {
+ public void addJavascriptInterface(Object obj, String interfaceName,
+ boolean requireAnnotation) {
assert obj != null;
removeJavascriptInterface(interfaceName);
-
- mJavaScriptObjects.put(interfaceName, obj);
+ mJavaScriptObjects.put(interfaceName, new JSObject(obj, requireAnnotation));
}
public void removeJavascriptInterface(String interfaceName) {
@@ -1245,7 +1275,7 @@ class BrowserFrame extends Handler {
* Add a javascript interface to the main frame.
*/
private native void nativeAddJavascriptInterface(int nativeFramePointer,
- Object obj, String interfaceName);
+ Object obj, String interfaceName, boolean requireAnnotation);
public native void clearCache();
diff --git a/core/java/android/webkit/JavascriptInterface.java b/core/java/android/webkit/JavascriptInterface.java
new file mode 100644
index 0000000..3f1ed12
--- /dev/null
+++ b/core/java/android/webkit/JavascriptInterface.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.webkit;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Annotation that allows exposing methods to JavaScript. Starting from API level
+ * {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1} and above, only methods explicitly
+ * marked with this annotation are available to the Javascript code. See
+ * {@link android.webkit.Webview#addJavaScriptInterface} for more information about it.
+ *
+ * @hide
+ */
+@SuppressWarnings("javadoc")
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.METHOD})
+public @interface JavascriptInterface {
+} \ No newline at end of file
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 82635d7..9d6d929 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -26,6 +26,7 @@ import android.graphics.Picture;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.net.http.SslCertificate;
+import android.os.Build;
import android.os.Bundle;
import android.os.Looper;
import android.os.Message;
@@ -1507,6 +1508,9 @@ public class WebView extends AbsoluteLayout
public void addJavascriptInterface(Object object, String name) {
checkThread();
mProvider.addJavascriptInterface(object, name);
+ // TODO in a separate CL provide logic to enable annotations for API level JB_MR1 and above. Don't forget to
+ // update the doc, set a link to annotation and unhide the annotation.
+ // also describe that fields of java objects are not accessible from JS.
}
/**
diff --git a/core/java/android/webkit/WebViewClassic.java b/core/java/android/webkit/WebViewClassic.java
index 494a28c..351c4f3 100644
--- a/core/java/android/webkit/WebViewClassic.java
+++ b/core/java/android/webkit/WebViewClassic.java
@@ -4114,12 +4114,15 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
*/
@Override
public void addJavascriptInterface(Object object, String name) {
+
if (object == null) {
return;
}
WebViewCore.JSInterfaceData arg = new WebViewCore.JSInterfaceData();
+ // TODO in a separate CL provide logic to enable annotations for API level JB_MR1 and above.
arg.mObject = object;
arg.mInterfaceName = name;
+ arg.mRequireAnnotation = false;
mWebViewCore.sendMessage(EventHub.ADD_JS_INTERFACE, arg);
}
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index 59036e7..2d834ff 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -824,6 +824,7 @@ public final class WebViewCore {
static class JSInterfaceData {
Object mObject;
String mInterfaceName;
+ boolean mRequireAnnotation;
}
static class JSKeyData {
@@ -1489,7 +1490,7 @@ public final class WebViewCore {
case ADD_JS_INTERFACE:
JSInterfaceData jsData = (JSInterfaceData) msg.obj;
mBrowserFrame.addJavascriptInterface(jsData.mObject,
- jsData.mInterfaceName);
+ jsData.mInterfaceName, jsData.mRequireAnnotation);
break;
case REMOVE_JS_INTERFACE: