Skip to content
This repository has been archived by the owner on Nov 8, 2023. It is now read-only.

Commit

Permalink
Make JavascriptInterface annotation public.
Browse files Browse the repository at this point in the history
Bug: 7073422

This change makes @JavascriptInterface public and it requires
using this annotation to allow javascript access to public java
methods for API level JELLY_BEAN_MR1 and above. The behavior
does not change for API levels JELLY_BEAN and below.

Change-Id: I4108b17cf71b9ac273d7b61b1c8f7f5581e922ee
  • Loading branch information
Selim Gurun committed Sep 12, 2012
1 parent 0bb4d07 commit e91d5be
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 12 deletions.
3 changes: 3 additions & 0 deletions api/current.txt
Expand Up @@ -26943,6 +26943,9 @@ package android.webkit {
method public boolean useHttpAuthUsernamePassword();
}

public abstract class JavascriptInterface implements java.lang.annotation.Annotation {
}

public class JsPromptResult extends android.webkit.JsResult {
method public void confirm(java.lang.String);
}
Expand Down
3 changes: 1 addition & 2 deletions core/java/android/webkit/JavascriptInterface.java
Expand Up @@ -25,9 +25,8 @@
* 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.
* {@link android.webkit.WebView#addJavascriptInterface} for more information about it.
*
* @hide
*/
@SuppressWarnings("javadoc")
@Retention(RetentionPolicy.RUNTIME)
Expand Down
25 changes: 17 additions & 8 deletions core/java/android/webkit/WebView.java
Expand Up @@ -26,7 +26,6 @@
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;
Expand Down Expand Up @@ -1479,18 +1478,30 @@ public void setPictureListener(PictureListener listener) {
/**
* Injects the supplied Java object into this WebView. The object is
* injected into the JavaScript context of the main frame, using the
* supplied name. This allows the Java object's public methods to be
* accessed from JavaScript. Note that that injected objects will not
* supplied name. This allows the Java object's methods to be
* accessed from JavaScript. For API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1}
* and above, only public methods that are annotated with
* {@link android.webkit.JavascriptInterface} can be accessed from JavaScript.
* For API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN} or below,
* all public methods (including the inherited ones) can be accessed, see the
* important security note below for implications. Note that injected objects will not
* appear in JavaScript until the page is next (re)loaded. For example:
* <pre> webView.addJavascriptInterface(new Object(), "injectedObject");
* <pre>
* class JsObject {
* {@literal @}JavascriptInterface
* public String toString() { return "injectedObject"; }
* }
* webView.addJavascriptInterface(new JsObject(), "injectedObject");
* webView.loadData("<!DOCTYPE html><title></title>", "text/html", null);
* webView.loadUrl("javascript:alert(injectedObject.toString())");</pre>
* <p>
* <strong>IMPORTANT:</strong>
* <ul>
* <li> This method can be used to allow JavaScript to control the host
* application. This is a powerful feature, but also presents a security
* risk, particularly as JavaScript could use reflection to access an
* risk for applications targeting API level
* {@link android.os.Build.VERSION_CODES#JELLY_BEAN} or below, because
* JavaScript could use reflection to access an
* injected object's public fields. Use of this method in a WebView
* containing untrusted content could allow an attacker to manipulate the
* host application in unintended ways, executing Java code with the
Expand All @@ -1499,6 +1510,7 @@ public void setPictureListener(PictureListener listener) {
* <li> JavaScript interacts with Java object on a private, background
* thread of this WebView. Care is therefore required to maintain thread
* safety.</li>
* <li> The Java object's fields are not accessible.</li>
* </ul>
*
* @param object the Java object to inject into this WebView's JavaScript
Expand All @@ -1508,9 +1520,6 @@ public void setPictureListener(PictureListener listener) {
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.
}

/**
Expand Down
12 changes: 10 additions & 2 deletions core/java/android/webkit/WebViewClassic.java
Expand Up @@ -55,6 +55,7 @@
import android.net.Uri;
import android.net.http.SslCertificate;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
Expand Down Expand Up @@ -4119,10 +4120,17 @@ public void addJavascriptInterface(Object object, String name) {
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;

// starting with JELLY_BEAN_MR1, annotations are mandatory for enabling access to
// methods that are accessible from JS.
if (mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
arg.mRequireAnnotation = true;
} else {
arg.mRequireAnnotation = false;
}
mWebViewCore.sendMessage(EventHub.ADD_JS_INTERFACE, arg);
}

Expand Down

0 comments on commit e91d5be

Please sign in to comment.