diff options
| -rw-r--r-- | core/java/android/webkit/BrowserFrame.java | 54 | ||||
| -rw-r--r-- | core/java/android/webkit/JavascriptInterface.java | 36 | ||||
| -rw-r--r-- | core/java/android/webkit/WebView.java | 4 | ||||
| -rw-r--r-- | core/java/android/webkit/WebViewClassic.java | 3 | ||||
| -rw-r--r-- | core/java/android/webkit/WebViewCore.java | 3 |
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: |
