Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit befab9e6 authored by Selim Gurun's avatar Selim Gurun Committed by Android (Google) Code Review
Browse files

Merge "Control access to inherited methods of jsinterface objects" into jb-mr1-dev

parents eeabf942 94740e6c
Loading
Loading
Loading
Loading
+42 −12
Original line number Diff line number Diff line
@@ -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();

+36 −0
Original line number Diff line number Diff line
/*
 * 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
+4 −0
Original line number Diff line number Diff line
@@ -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.
    }

    /**
+3 −0
Original line number Diff line number Diff line
@@ -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);
    }

+2 −1
Original line number Diff line number Diff line
@@ -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: