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

Commit 47bc8476 authored by Jonathan Dixon's avatar Jonathan Dixon Committed by Android (Google) Code Review
Browse files

Merge "Seperate interface and implementation of 4 WebView classes"

parents 03c63ebe d3101b1d
Loading
Loading
Loading
Loading
+29 −111
Original line number Diff line number Diff line
@@ -16,27 +16,20 @@

package android.webkit;

import android.net.ParseException;
import android.net.WebAddress;
import android.os.AsyncTask;
import android.util.Log;


/**
 * Manages the cookies used by an application's {@link WebView} instances.
 * Cookies are manipulated according to RFC2109.
 */
public class CookieManager {

    private static CookieManager sRef;

    private static final String LOGTAG = "webkit";

    private int mPendingCookieOperations = 0;

    private CookieManager() {
    /**
     * @hide Only for use by WebViewProvider implementations
     */
    protected CookieManager() {
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        throw new CloneNotSupportedException("doesn't implement Cloneable");
    }
@@ -50,10 +43,7 @@ public class CookieManager {
     * @return The singleton CookieManager instance
     */
    public static synchronized CookieManager getInstance() {
        if (sRef == null) {
            sRef = new CookieManager();
        }
        return sRef;
        return WebViewFactory.getProvider().getCookieManager();
    }

    /**
@@ -63,7 +53,7 @@ public class CookieManager {
     *               cookies
     */
    public synchronized void setAcceptCookie(boolean accept) {
        nativeSetAcceptCookie(accept);
        throw new MustOverrideException();
    }

    /**
@@ -72,7 +62,7 @@ public class CookieManager {
     * @return True if {@link WebView} instances send and accept cookies
     */
    public synchronized boolean acceptCookie() {
        return nativeAcceptCookie();
        throw new MustOverrideException();
    }

     /**
@@ -81,30 +71,11 @@ public class CookieManager {
     * must not have expired and must not be a session cookie, otherwise it
     * will be ignored.
     * @param url The URL for which the cookie is set
     * @param value The cookie as a string, using the format of the
     *              'Set-Cookie' HTTP response header
     * @param value The cookie as a string, using the format of the 'Set-Cookie'
     *              HTTP response header
     */
    public void setCookie(String url, String value) {
        setCookie(url, value, false);
    }

    /**
     * See {@link setCookie(String, String)}
     * @param url The URL for which the cookie is set
     * @param value The value of the cookie, as a string, using the format of
     *              the 'Set-Cookie' HTTP response header
     * @param privateBrowsing Whether to use the private browsing cookie jar
     */
    void setCookie(String url, String value, boolean privateBrowsing) {
        WebAddress uri;
        try {
            uri = new WebAddress(url);
        } catch (ParseException ex) {
            Log.e(LOGTAG, "Bad address: " + url);
            return;
        }

        nativeSetCookie(uri.toString(), value, privateBrowsing);
        throw new MustOverrideException();
    }

    /**
@@ -114,11 +85,11 @@ public class CookieManager {
     *               HTTP request header
     */
    public String getCookie(String url) {
        return getCookie(url, false);
        throw new MustOverrideException();
    }

    /**
     * See {@link getCookie(String)}
     * See {@link #getCookie(String)}
     * @param url The URL for which the cookies are requested
     * @param privateBrowsing Whether to use the private browsing cookie jar
     * @return value The cookies as a string, using the format of the 'Cookie'
@@ -126,15 +97,7 @@ public class CookieManager {
     * @hide Used by Browser, no intention to publish.
     */
    public String getCookie(String url, boolean privateBrowsing) {
        WebAddress uri;
        try {
            uri = new WebAddress(url);
        } catch (ParseException ex) {
            Log.e(LOGTAG, "Bad address: " + url);
            return null;
        }

        return nativeGetCookie(uri.toString(), privateBrowsing);
        throw new MustOverrideException();
    }

    /**
@@ -146,32 +109,7 @@ public class CookieManager {
     * @hide Used by RequestHandle, no intention to publish.
     */
    public synchronized String getCookie(WebAddress uri) {
        return nativeGetCookie(uri.toString(), false);
    }

    /**
     * Waits for pending operations to completed.
     */
    void waitForCookieOperationsToComplete() {
        // Note that this function is applicable for both the java
        // and native http stacks, and works correctly with either.
        synchronized (this) {
            while (mPendingCookieOperations > 0) {
                try {
                    wait();
                } catch (InterruptedException e) { }
            }
        }
    }

    private synchronized void signalCookieOperationsComplete() {
        mPendingCookieOperations--;
        assert mPendingCookieOperations > -1;
        notify();
    }

    private synchronized void signalCookieOperationsStart() {
        mPendingCookieOperations++;
        throw new MustOverrideException();
    }

    /**
@@ -179,21 +117,14 @@ public class CookieManager {
     * date.
     */
    public void removeSessionCookie() {
        signalCookieOperationsStart();
        new AsyncTask<Void, Void, Void>() {
            protected Void doInBackground(Void... none) {
                nativeRemoveSessionCookie();
                signalCookieOperationsComplete();
                return null;
            }
        }.execute();
        throw new MustOverrideException();
    }

    /**
     * Removes all cookies.
     */
    public void removeAllCookie() {
        nativeRemoveAllCookie();
        throw new MustOverrideException();
    }

    /**
@@ -201,32 +132,32 @@ public class CookieManager {
     * @return True if there are stored cookies.
     */
    public synchronized boolean hasCookies() {
        return hasCookies(false);
        throw new MustOverrideException();
    }

    /**
     * See {@link hasCookies()}.
     * See {@link #hasCookies()}.
     * @param privateBrowsing Whether to use the private browsing cookie jar
     * @hide Used by Browser, no intention to publish.
     */
    public synchronized boolean hasCookies(boolean privateBrowsing) {
        return nativeHasCookies(privateBrowsing);
        throw new MustOverrideException();
    }

    /**
     * Removes all expired cookies.
     */
    public void removeExpiredCookie() {
        nativeRemoveExpiredCookie();
        throw new MustOverrideException();
    }

    /**
     * Package level api, called from CookieSyncManager
     *
     * Flush all cookies managed by the Chrome HTTP stack to flash.
     *
     * @hide Package level api, called from CookieSyncManager
     */
    void flushCookieStore() {
        nativeFlushCookieStore();
    protected void flushCookieStore() {
        throw new MustOverrideException();
    }

    /**
@@ -236,7 +167,7 @@ public class CookieManager {
     *         file scheme URLs
     */
    public static boolean allowFileSchemeCookies() {
        return nativeAcceptFileSchemeCookies();
        throw new MustOverrideException();
    }

    /**
@@ -250,19 +181,6 @@ public class CookieManager {
     * {@link WebView} or CookieManager instance has been created.
     */
    public static void setAcceptFileSchemeCookies(boolean accept) {
        nativeSetAcceptFileSchemeCookies(accept);
        throw new MustOverrideException();
    }

    // Native functions
    private static native boolean nativeAcceptCookie();
    private static native String nativeGetCookie(String url, boolean privateBrowsing);
    private static native boolean nativeHasCookies(boolean privateBrowsing);
    private static native void nativeRemoveAllCookie();
    private static native void nativeRemoveExpiredCookie();
    private static native void nativeRemoveSessionCookie();
    private static native void nativeSetAcceptCookie(boolean accept);
    private static native void nativeSetCookie(String url, String value, boolean privateBrowsing);
    private static native void nativeFlushCookieStore();
    private static native boolean nativeAcceptFileSchemeCookies();
    private static native void nativeSetAcceptFileSchemeCookies(boolean accept);
}
+198 −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 android.net.ParseException;
import android.net.WebAddress;
import android.os.AsyncTask;
import android.util.Log;

class CookieManagerClassic extends CookieManager {

    private static CookieManagerClassic sRef;

    private static final String LOGTAG = "webkit";

    private int mPendingCookieOperations = 0;

    private CookieManagerClassic() {
    }

    public static synchronized CookieManagerClassic getInstance() {
        if (sRef == null) {
            sRef = new CookieManagerClassic();
        }
        return sRef;
    }

    @Override
    public synchronized void setAcceptCookie(boolean accept) {
        nativeSetAcceptCookie(accept);
    }

    @Override
    public synchronized boolean acceptCookie() {
        return nativeAcceptCookie();
    }

    @Override
    public void setCookie(String url, String value) {
        setCookie(url, value, false);
    }

    /**
     * See {@link #setCookie(String, String)}
     * @param url The URL for which the cookie is set
     * @param value The value of the cookie, as a string, using the format of
     *              the 'Set-Cookie' HTTP response header
     * @param privateBrowsing Whether to use the private browsing cookie jar
     */
    void setCookie(String url, String value, boolean privateBrowsing) {
        WebAddress uri;
        try {
            uri = new WebAddress(url);
        } catch (ParseException ex) {
            Log.e(LOGTAG, "Bad address: " + url);
            return;
        }

        nativeSetCookie(uri.toString(), value, privateBrowsing);
    }

    @Override
    public String getCookie(String url) {
        return getCookie(url, false);
    }

    @Override
    public String getCookie(String url, boolean privateBrowsing) {
        WebAddress uri;
        try {
            uri = new WebAddress(url);
        } catch (ParseException ex) {
            Log.e(LOGTAG, "Bad address: " + url);
            return null;
        }

        return nativeGetCookie(uri.toString(), privateBrowsing);
    }

    @Override
    public synchronized String getCookie(WebAddress uri) {
        return nativeGetCookie(uri.toString(), false);
    }

    /**
     * Waits for pending operations to completed.
     */
    void waitForCookieOperationsToComplete() {
        // Note that this function is applicable for both the java
        // and native http stacks, and works correctly with either.
        synchronized (this) {
            while (mPendingCookieOperations > 0) {
                try {
                    wait();
                } catch (InterruptedException e) { }
            }
        }
    }

    private synchronized void signalCookieOperationsComplete() {
        mPendingCookieOperations--;
        assert mPendingCookieOperations > -1;
        notify();
    }

    private synchronized void signalCookieOperationsStart() {
        mPendingCookieOperations++;
    }

    @Override
    public void removeSessionCookie() {
        signalCookieOperationsStart();
        new AsyncTask<Void, Void, Void>() {
            @Override
            protected Void doInBackground(Void... none) {
                nativeRemoveSessionCookie();
                signalCookieOperationsComplete();
                return null;
            }
        }.execute();
    }

    @Override
    public void removeAllCookie() {
        nativeRemoveAllCookie();
    }

    @Override
    public synchronized boolean hasCookies() {
        return hasCookies(false);
    }

    @Override
    public synchronized boolean hasCookies(boolean privateBrowsing) {
        return nativeHasCookies(privateBrowsing);
    }

    @Override
    public void removeExpiredCookie() {
        nativeRemoveExpiredCookie();
    }

    @Override
    protected void flushCookieStore() {
        nativeFlushCookieStore();
    }

    /**
     * Gets whether the application's {@link WebView} instances send and accept
     * cookies for file scheme URLs.
     * @return True if {@link WebView} instances send and accept cookies for
     *         file scheme URLs
     */
    public static boolean allowFileSchemeCookies() {
        return nativeAcceptFileSchemeCookies();
    }

    /**
     * Sets whether the application's {@link WebView} instances should send and
     * accept cookies for file scheme URLs.
     * Use of cookies with file scheme URLs is potentially insecure. Do not use
     * this feature unless you can be sure that no unintentional sharing of
     * cookie data can take place.
     * <p>
     * Note that calls to this method will have no effect if made after a
     * {@link WebView} or CookieManager instance has been created.
     */
    public static void setAcceptFileSchemeCookies(boolean accept) {
        nativeSetAcceptFileSchemeCookies(accept);
    }

    // Native functions
    private static native boolean nativeAcceptCookie();
    private static native String nativeGetCookie(String url, boolean privateBrowsing);
    private static native boolean nativeHasCookies(boolean privateBrowsing);
    private static native void nativeRemoveAllCookie();
    private static native void nativeRemoveExpiredCookie();
    private static native void nativeRemoveSessionCookie();
    private static native void nativeSetAcceptCookie(boolean accept);
    private static native void nativeSetCookie(String url, String value, boolean privateBrowsing);
    private static native void nativeFlushCookieStore();
    private static native boolean nativeAcceptFileSchemeCookies();
    private static native void nativeSetAcceptFileSchemeCookies(boolean accept);
}
+7 −186
Original line number Diff line number Diff line
@@ -16,13 +16,7 @@

package android.webkit;

import android.os.Handler;
import android.os.Message;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.Vector;

/**
 * This class is used to manage permissions for the WebView's Geolocation
@@ -44,9 +38,6 @@ import java.util.Vector;
 * The methods of this class can be used to modify and interrogate the stored
 * Geolocation permissions at any time.
 */
// This class is the Java counterpart of the WebKit C++ GeolocationPermissions
// class. It simply marshals calls from the UI thread to the WebKit thread.
//
// Within WebKit, Geolocation permissions may be applied either temporarily
// (for the duration of the page) or permanently. This class deals only with
// permanent permissions.
@@ -68,144 +59,12 @@ public class GeolocationPermissions {
        public void invoke(String origin, boolean allow, boolean retain);
    };

    // Global instance
    private static GeolocationPermissions sInstance;

    private Handler mHandler;
    private Handler mUIHandler;

    // A queue to store messages until the handler is ready.
    private Vector<Message> mQueuedMessages;

    // Message ids
    static final int GET_ORIGINS = 0;
    static final int GET_ALLOWED = 1;
    static final int CLEAR = 2;
    static final int ALLOW = 3;
    static final int CLEAR_ALL = 4;

    // Message ids on the UI thread
    static final int RETURN_ORIGINS = 0;
    static final int RETURN_ALLOWED = 1;

    private static final String ORIGINS = "origins";
    private static final String ORIGIN = "origin";
    private static final String CALLBACK = "callback";
    private static final String ALLOWED = "allowed";

    /**
     * Get the singleton instance of this class.
     * @return The singleton {@link GeolocationPermissions} instance.
     */
    public static GeolocationPermissions getInstance() {
      if (sInstance == null) {
          sInstance = new GeolocationPermissions();
      }
      return sInstance;
    }

    /**
     * Creates the UI message handler. Must be called on the UI thread.
     * @hide
     */
    public void createUIHandler() {
        if (mUIHandler == null) {
            mUIHandler = new Handler() {
                @Override
                public void handleMessage(Message msg) {
                    // Runs on the UI thread.
                    switch (msg.what) {
                        case RETURN_ORIGINS: {
                            Map values = (Map) msg.obj;
                            Set<String> origins = (Set<String>) values.get(ORIGINS);
                            ValueCallback<Set<String> > callback = (ValueCallback<Set<String> >) values.get(CALLBACK);
                            callback.onReceiveValue(origins);
                        } break;
                        case RETURN_ALLOWED: {
                            Map values = (Map) msg.obj;
                            Boolean allowed = (Boolean) values.get(ALLOWED);
                            ValueCallback<Boolean> callback = (ValueCallback<Boolean>) values.get(CALLBACK);
                            callback.onReceiveValue(allowed);
                        } break;
                    }
                }
            };
        }
    }

    /**
     * Creates the message handler. Must be called on the WebKit thread.
     * @hide
     */
    public synchronized void createHandler() {
        if (mHandler == null) {
            mHandler = new Handler() {
                @Override
                public void handleMessage(Message msg) {
                    // Runs on the WebKit thread.
                    switch (msg.what) {
                        case GET_ORIGINS: {
                            Set origins = nativeGetOrigins();
                            ValueCallback callback = (ValueCallback) msg.obj;
                            Map values = new HashMap<String, Object>();
                            values.put(CALLBACK, callback);
                            values.put(ORIGINS, origins);
                            postUIMessage(Message.obtain(null, RETURN_ORIGINS, values));
                            } break;
                        case GET_ALLOWED: {
                            Map values = (Map) msg.obj;
                            String origin = (String) values.get(ORIGIN);
                            ValueCallback callback = (ValueCallback) values.get(CALLBACK);
                            boolean allowed = nativeGetAllowed(origin);
                            Map retValues = new HashMap<String, Object>();
                            retValues.put(CALLBACK, callback);
                            retValues.put(ALLOWED, Boolean.valueOf(allowed));
                            postUIMessage(Message.obtain(null, RETURN_ALLOWED, retValues));
                            } break;
                        case CLEAR:
                            nativeClear((String) msg.obj);
                            break;
                        case ALLOW:
                            nativeAllow((String) msg.obj);
                            break;
                        case CLEAR_ALL:
                            nativeClearAll();
                            break;
                    }
                }
            };

            // Handle the queued messages
            if (mQueuedMessages != null) {
                while (!mQueuedMessages.isEmpty()) {
                    mHandler.sendMessage(mQueuedMessages.remove(0));
                }
                mQueuedMessages = null;
            }
        }
    }

    /**
     * Utility function to send a message to our handler.
     */
    private synchronized void postMessage(Message msg) {
        if (mHandler == null) {
            if (mQueuedMessages == null) {
                mQueuedMessages = new Vector<Message>();
            }
            mQueuedMessages.add(msg);
        } else {
            mHandler.sendMessage(msg);
        }
    }

    /**
     * Utility function to send a message to the handler on the UI thread
     */
    private void postUIMessage(Message msg) {
        if (mUIHandler != null) {
            mUIHandler.sendMessage(msg);
        }
      return WebViewFactory.getProvider().getGeolocationPermissions();
    }

    /**
@@ -222,14 +81,7 @@ public class GeolocationPermissions {
    // (Database, Geolocation etc) do so, it's safe to match up origins based
    // on this string.
    public void getOrigins(ValueCallback<Set<String> > callback) {
        if (callback != null) {
            if (WebViewCore.THREAD_NAME.equals(Thread.currentThread().getName())) {
                Set origins = nativeGetOrigins();
                callback.onReceiveValue(origins);
            } else {
                postMessage(Message.obtain(null, GET_ORIGINS, callback));
            }
        }
        // Must be a no-op for backward compatibility: see the hidden constructor for reason.
    }

    /**
@@ -243,54 +95,30 @@ public class GeolocationPermissions {
     *                 Geolocation API.
     */
    public void getAllowed(String origin, ValueCallback<Boolean> callback) {
        if (callback == null) {
            return;
        }
        if (origin == null) {
            callback.onReceiveValue(null);
            return;
        }
        if (WebViewCore.THREAD_NAME.equals(Thread.currentThread().getName())) {
            boolean allowed = nativeGetAllowed(origin);
            callback.onReceiveValue(Boolean.valueOf(allowed));
        } else {
            Map values = new HashMap<String, Object>();
            values.put(ORIGIN, origin);
            values.put(CALLBACK, callback);
            postMessage(Message.obtain(null, GET_ALLOWED, values));
        }
        // Must be a no-op for backward compatibility: see the hidden constructor for reason.
    }

    /**
     * Clear the Geolocation permission state for the specified origin.
     * @param origin The origin for which Geolocation permissions are cleared.
     */
    // This method may be called before the WebKit
    // thread has intialized the message handler. Messages will be queued until
    // this time.
    public void clear(String origin) {
        // Called on the UI thread.
        postMessage(Message.obtain(null, CLEAR, origin));
        // Must be a no-op for backward compatibility: see the hidden constructor for reason.
    }

    /**
     * Allow the specified origin to use the Geolocation API.
     * @param origin The origin for which Geolocation API use is allowed.
     */
    // This method may be called before the WebKit
    // thread has intialized the message handler. Messages will be queued until
    // this time.
    public void allow(String origin) {
        // Called on the UI thread.
        postMessage(Message.obtain(null, ALLOW, origin));
        // Must be a no-op for backward compatibility: see the hidden constructor for reason.
    }

    /**
     * Clear the Geolocation permission state for all origins.
     */
    public void clearAll() {
        // Called on the UI thread.
        postMessage(Message.obtain(null, CLEAR_ALL));
        // Must be a no-op for backward compatibility: see the hidden constructor for reason.
    }

    /**
@@ -299,14 +127,7 @@ public class GeolocationPermissions {
     * Note this constructor was erroneously public and published in SDK levels prior to 16, but
     * applications using it would receive a non-functional instance of this class (there was no
     * way to call createHandler() and createUIHandler(), so it would not work).
     * @hide
     * @hide Only for use by WebViewProvider implementations
     */
    public GeolocationPermissions() {}

    // Native functions, run on the WebKit thread.
    private static native Set nativeGetOrigins();
    private static native boolean nativeGetAllowed(String origin);
    private static native void nativeClear(String origin);
    private static native void nativeAllow(String origin);
    private static native void nativeClearAll();
}
+234 −0

File added.

Preview size limit exceeded, changes collapsed.

+25 −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;

// TODO: Remove MustOverrideException and make all methods throwing it abstract instead;
// needs API file update.
class MustOverrideException extends RuntimeException {
    MustOverrideException() {
        super("abstract function called: must be overriden!");
    }
}
 No newline at end of file
Loading