GeolocationPermissions.java revision 7351adf76a97b07bb2d777c56e78752cb7834bb0
10ac031b3d29c6de90895c875991585812dc7388fSteve Block/*
20ac031b3d29c6de90895c875991585812dc7388fSteve Block * Copyright (C) 2009 The Android Open Source Project
30ac031b3d29c6de90895c875991585812dc7388fSteve Block *
40ac031b3d29c6de90895c875991585812dc7388fSteve Block * Licensed under the Apache License, Version 2.0 (the "License");
50ac031b3d29c6de90895c875991585812dc7388fSteve Block * you may not use this file except in compliance with the License.
60ac031b3d29c6de90895c875991585812dc7388fSteve Block * You may obtain a copy of the License at
70ac031b3d29c6de90895c875991585812dc7388fSteve Block *
80ac031b3d29c6de90895c875991585812dc7388fSteve Block *      http://www.apache.org/licenses/LICENSE-2.0
90ac031b3d29c6de90895c875991585812dc7388fSteve Block *
100ac031b3d29c6de90895c875991585812dc7388fSteve Block * Unless required by applicable law or agreed to in writing, software
110ac031b3d29c6de90895c875991585812dc7388fSteve Block * distributed under the License is distributed on an "AS IS" BASIS,
120ac031b3d29c6de90895c875991585812dc7388fSteve Block * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130ac031b3d29c6de90895c875991585812dc7388fSteve Block * See the License for the specific language governing permissions and
140ac031b3d29c6de90895c875991585812dc7388fSteve Block * limitations under the License.
150ac031b3d29c6de90895c875991585812dc7388fSteve Block */
160ac031b3d29c6de90895c875991585812dc7388fSteve Block
170ac031b3d29c6de90895c875991585812dc7388fSteve Blockpackage android.webkit;
180ac031b3d29c6de90895c875991585812dc7388fSteve Block
190ac031b3d29c6de90895c875991585812dc7388fSteve Blockimport android.os.Handler;
200ac031b3d29c6de90895c875991585812dc7388fSteve Blockimport android.os.Message;
210ac031b3d29c6de90895c875991585812dc7388fSteve Blockimport android.util.Log;
226c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roardimport java.util.HashMap;
23d875ce6dac3c2e9a671c121c80b40d2536cbb2afSteve Blockimport java.util.HashSet;
246c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roardimport java.util.Map;
250ac031b3d29c6de90895c875991585812dc7388fSteve Blockimport java.util.Set;
2601228fcff613e2f30773130dd31acd3ba7d62bacSteve Blockimport java.util.Vector;
270ac031b3d29c6de90895c875991585812dc7388fSteve Block
280ac031b3d29c6de90895c875991585812dc7388fSteve Block
290ac031b3d29c6de90895c875991585812dc7388fSteve Block/**
307351adf76a97b07bb2d777c56e78752cb7834bb0Steve Block * This class is used to manage permissions for the WebView's Geolocation
317351adf76a97b07bb2d777c56e78752cb7834bb0Steve Block * JavaScript API.
3257534f1b9f52cea094e8197d1ca40f0d2f68cc66Steve Block *
337351adf76a97b07bb2d777c56e78752cb7834bb0Steve Block * Geolocation permissions are applied to an origin, which consists of the
347351adf76a97b07bb2d777c56e78752cb7834bb0Steve Block * host, scheme and port of a URI. In order for web content to use the
357351adf76a97b07bb2d777c56e78752cb7834bb0Steve Block * Geolocation API, permission must be granted for that content's origin.
3657534f1b9f52cea094e8197d1ca40f0d2f68cc66Steve Block *
377351adf76a97b07bb2d777c56e78752cb7834bb0Steve Block * This class stores Geolocation permissions. An origin's permission state can
387351adf76a97b07bb2d777c56e78752cb7834bb0Steve Block * be either allowed or denied. This class uses Strings to represent
397351adf76a97b07bb2d777c56e78752cb7834bb0Steve Block * an origin.
4057534f1b9f52cea094e8197d1ca40f0d2f68cc66Steve Block *
417351adf76a97b07bb2d777c56e78752cb7834bb0Steve Block * When an origin attempts to use the Geolocation API, but no permission state
427351adf76a97b07bb2d777c56e78752cb7834bb0Steve Block * is currently set for that origin,
437351adf76a97b07bb2d777c56e78752cb7834bb0Steve Block * {@link WebChromeClient#onGeolocationPermissionsShowPrompt(String,GeolocationPermissions.Callback) WebChromeClient.onGeolocationPermissionsShowPrompt()}
447351adf76a97b07bb2d777c56e78752cb7834bb0Steve Block * is called. This allows the permission state to be set for that origin.
457351adf76a97b07bb2d777c56e78752cb7834bb0Steve Block *
467351adf76a97b07bb2d777c56e78752cb7834bb0Steve Block * The methods of this class can be used to modify and interrogate the stored
477351adf76a97b07bb2d777c56e78752cb7834bb0Steve Block * Geolocation permissions at any time.
480ac031b3d29c6de90895c875991585812dc7388fSteve Block */
497351adf76a97b07bb2d777c56e78752cb7834bb0Steve Block// This class is the Java counterpart of the WebKit C++ GeolocationPermissions
507351adf76a97b07bb2d777c56e78752cb7834bb0Steve Block// class. It simply marshalls calls from the UI thread to the WebKit thread.
517351adf76a97b07bb2d777c56e78752cb7834bb0Steve Block//
527351adf76a97b07bb2d777c56e78752cb7834bb0Steve Block// Within WebKit, Geolocation permissions may be applied either temporarily
537351adf76a97b07bb2d777c56e78752cb7834bb0Steve Block// (for the duration of the page) or permanently. This class deals only with
547351adf76a97b07bb2d777c56e78752cb7834bb0Steve Block// permanent permissions.
550ac031b3d29c6de90895c875991585812dc7388fSteve Blockpublic final class GeolocationPermissions {
564faee09c422a70439129e9fb40dd82f03d42c98dSteve Block    /**
577351adf76a97b07bb2d777c56e78752cb7834bb0Steve Block     * A callback interface used by the host application to set the Geolocation
587351adf76a97b07bb2d777c56e78752cb7834bb0Steve Block     * permission state for an origin.
594faee09c422a70439129e9fb40dd82f03d42c98dSteve Block     */
604faee09c422a70439129e9fb40dd82f03d42c98dSteve Block    public interface Callback {
617351adf76a97b07bb2d777c56e78752cb7834bb0Steve Block        /**
627351adf76a97b07bb2d777c56e78752cb7834bb0Steve Block         * Set the Geolocation permission state for the supplied origin.
637351adf76a97b07bb2d777c56e78752cb7834bb0Steve Block         * @param origin The origin for which permissions are set.
647351adf76a97b07bb2d777c56e78752cb7834bb0Steve Block         * @param allow Whether or not the origin should be allowed to use the
657351adf76a97b07bb2d777c56e78752cb7834bb0Steve Block         *              Geolocation API.
667351adf76a97b07bb2d777c56e78752cb7834bb0Steve Block         * @param retain Whether the permission should be retained beyond the
677351adf76a97b07bb2d777c56e78752cb7834bb0Steve Block         *               lifetime of a page currently being displayed by a
687351adf76a97b07bb2d777c56e78752cb7834bb0Steve Block         *               WebView.
697351adf76a97b07bb2d777c56e78752cb7834bb0Steve Block         */
707351adf76a97b07bb2d777c56e78752cb7834bb0Steve Block        public void invoke(String origin, boolean allow, boolean retain);
714faee09c422a70439129e9fb40dd82f03d42c98dSteve Block    };
724faee09c422a70439129e9fb40dd82f03d42c98dSteve Block
730ac031b3d29c6de90895c875991585812dc7388fSteve Block    // Log tag
740ac031b3d29c6de90895c875991585812dc7388fSteve Block    private static final String TAG = "geolocationPermissions";
750ac031b3d29c6de90895c875991585812dc7388fSteve Block
760ac031b3d29c6de90895c875991585812dc7388fSteve Block    // Global instance
770ac031b3d29c6de90895c875991585812dc7388fSteve Block    private static GeolocationPermissions sInstance;
780ac031b3d29c6de90895c875991585812dc7388fSteve Block
790ac031b3d29c6de90895c875991585812dc7388fSteve Block    private Handler mHandler;
806c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard    private Handler mUIHandler;
810ac031b3d29c6de90895c875991585812dc7388fSteve Block
8201228fcff613e2f30773130dd31acd3ba7d62bacSteve Block    // A queue to store messages until the handler is ready.
8301228fcff613e2f30773130dd31acd3ba7d62bacSteve Block    private Vector<Message> mQueuedMessages;
840ac031b3d29c6de90895c875991585812dc7388fSteve Block
850ac031b3d29c6de90895c875991585812dc7388fSteve Block    // Message ids
860ac031b3d29c6de90895c875991585812dc7388fSteve Block    static final int GET_ORIGINS = 0;
870ac031b3d29c6de90895c875991585812dc7388fSteve Block    static final int GET_ALLOWED = 1;
880ac031b3d29c6de90895c875991585812dc7388fSteve Block    static final int CLEAR = 2;
89d875ce6dac3c2e9a671c121c80b40d2536cbb2afSteve Block    static final int ALLOW = 3;
90d875ce6dac3c2e9a671c121c80b40d2536cbb2afSteve Block    static final int CLEAR_ALL = 4;
910ac031b3d29c6de90895c875991585812dc7388fSteve Block
926c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard    // Message ids on the UI thread
936c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard    static final int RETURN_ORIGINS = 0;
946c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard    static final int RETURN_ALLOWED = 1;
956c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard
966c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard    private static final String ORIGINS = "origins";
976c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard    private static final String ORIGIN = "origin";
986c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard    private static final String CALLBACK = "callback";
996c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard    private static final String ALLOWED = "allowed";
1006c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard
1010ac031b3d29c6de90895c875991585812dc7388fSteve Block    /**
1027351adf76a97b07bb2d777c56e78752cb7834bb0Steve Block     * Get the singleton instance of this class.
1037351adf76a97b07bb2d777c56e78752cb7834bb0Steve Block     * @return The singleton {@link GeolocationPermissions} instance.
1040ac031b3d29c6de90895c875991585812dc7388fSteve Block     */
1050ac031b3d29c6de90895c875991585812dc7388fSteve Block    public static GeolocationPermissions getInstance() {
1060ac031b3d29c6de90895c875991585812dc7388fSteve Block      if (sInstance == null) {
1070ac031b3d29c6de90895c875991585812dc7388fSteve Block          sInstance = new GeolocationPermissions();
1080ac031b3d29c6de90895c875991585812dc7388fSteve Block      }
1090ac031b3d29c6de90895c875991585812dc7388fSteve Block      return sInstance;
1100ac031b3d29c6de90895c875991585812dc7388fSteve Block    }
1110ac031b3d29c6de90895c875991585812dc7388fSteve Block
1120ac031b3d29c6de90895c875991585812dc7388fSteve Block    /**
1136c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard     * Creates the UI message handler. Must be called on the UI thread.
1142e4dbe70e7c0fe003dab0837fd1dba2703bdd6e2Mike LeBeau     * @hide
1156c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard     */
1166c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard    public void createUIHandler() {
1176c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard        if (mUIHandler == null) {
1186c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard            mUIHandler = new Handler() {
1196c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard                @Override
1206c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard                public void handleMessage(Message msg) {
1216c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard                    // Runs on the UI thread.
1226c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard                    switch (msg.what) {
1236c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard                        case RETURN_ORIGINS: {
1246c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard                            Map values = (Map) msg.obj;
12557534f1b9f52cea094e8197d1ca40f0d2f68cc66Steve Block                            Set<String> origins = (Set<String>) values.get(ORIGINS);
12657534f1b9f52cea094e8197d1ca40f0d2f68cc66Steve Block                            ValueCallback<Set<String> > callback = (ValueCallback<Set<String> >) values.get(CALLBACK);
1276c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard                            callback.onReceiveValue(origins);
1286c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard                        } break;
1296c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard                        case RETURN_ALLOWED: {
1306c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard                            Map values = (Map) msg.obj;
1316c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard                            Boolean allowed = (Boolean) values.get(ALLOWED);
1326c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard                            ValueCallback<Boolean> callback = (ValueCallback<Boolean>) values.get(CALLBACK);
1336c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard                            callback.onReceiveValue(allowed);
1346c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard                        } break;
1356c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard                    }
1366c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard                }
1376c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard            };
1386c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard        }
1396c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard    }
1406c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard
1416c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard    /**
1420ac031b3d29c6de90895c875991585812dc7388fSteve Block     * Creates the message handler. Must be called on the WebKit thread.
1432e4dbe70e7c0fe003dab0837fd1dba2703bdd6e2Mike LeBeau     * @hide
1440ac031b3d29c6de90895c875991585812dc7388fSteve Block     */
145e4b2d4dc7db426052d1dfebc40f6b64a001b6d73Steve Block    public synchronized void createHandler() {
1460ac031b3d29c6de90895c875991585812dc7388fSteve Block        if (mHandler == null) {
1470ac031b3d29c6de90895c875991585812dc7388fSteve Block            mHandler = new Handler() {
1480ac031b3d29c6de90895c875991585812dc7388fSteve Block                @Override
1490ac031b3d29c6de90895c875991585812dc7388fSteve Block                public void handleMessage(Message msg) {
1500ac031b3d29c6de90895c875991585812dc7388fSteve Block                    // Runs on the WebKit thread.
1510ac031b3d29c6de90895c875991585812dc7388fSteve Block                    switch (msg.what) {
1526c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard                        case GET_ORIGINS: {
15301228fcff613e2f30773130dd31acd3ba7d62bacSteve Block                            Set origins = nativeGetOrigins();
1546c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard                            ValueCallback callback = (ValueCallback) msg.obj;
1556c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard                            Map values = new HashMap<String, Object>();
1566c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard                            values.put(CALLBACK, callback);
15701228fcff613e2f30773130dd31acd3ba7d62bacSteve Block                            values.put(ORIGINS, origins);
1586c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard                            postUIMessage(Message.obtain(null, RETURN_ORIGINS, values));
1596c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard                            } break;
1606c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard                        case GET_ALLOWED: {
1616c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard                            Map values = (Map) msg.obj;
1626c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard                            String origin = (String) values.get(ORIGIN);
1636c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard                            ValueCallback callback = (ValueCallback) values.get(CALLBACK);
16401228fcff613e2f30773130dd31acd3ba7d62bacSteve Block                            boolean allowed = nativeGetAllowed(origin);
1656c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard                            Map retValues = new HashMap<String, Object>();
1666c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard                            retValues.put(CALLBACK, callback);
16769e2eff270be8c61fc902fcb337097e86c601295Kenny Root                            retValues.put(ALLOWED, Boolean.valueOf(allowed));
1686c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard                            postUIMessage(Message.obtain(null, RETURN_ALLOWED, retValues));
1696c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard                            } break;
1700ac031b3d29c6de90895c875991585812dc7388fSteve Block                        case CLEAR:
1710ac031b3d29c6de90895c875991585812dc7388fSteve Block                            nativeClear((String) msg.obj);
1720ac031b3d29c6de90895c875991585812dc7388fSteve Block                            break;
173d875ce6dac3c2e9a671c121c80b40d2536cbb2afSteve Block                        case ALLOW:
174d875ce6dac3c2e9a671c121c80b40d2536cbb2afSteve Block                            nativeAllow((String) msg.obj);
175d875ce6dac3c2e9a671c121c80b40d2536cbb2afSteve Block                            break;
1760ac031b3d29c6de90895c875991585812dc7388fSteve Block                        case CLEAR_ALL:
1770ac031b3d29c6de90895c875991585812dc7388fSteve Block                            nativeClearAll();
1780ac031b3d29c6de90895c875991585812dc7388fSteve Block                            break;
1790ac031b3d29c6de90895c875991585812dc7388fSteve Block                    }
1800ac031b3d29c6de90895c875991585812dc7388fSteve Block                }
1810ac031b3d29c6de90895c875991585812dc7388fSteve Block            };
182d875ce6dac3c2e9a671c121c80b40d2536cbb2afSteve Block
18301228fcff613e2f30773130dd31acd3ba7d62bacSteve Block            // Handle the queued messages
18401228fcff613e2f30773130dd31acd3ba7d62bacSteve Block            if (mQueuedMessages != null) {
18501228fcff613e2f30773130dd31acd3ba7d62bacSteve Block                while (!mQueuedMessages.isEmpty()) {
18601228fcff613e2f30773130dd31acd3ba7d62bacSteve Block                    mHandler.sendMessage(mQueuedMessages.remove(0));
187d875ce6dac3c2e9a671c121c80b40d2536cbb2afSteve Block                }
18801228fcff613e2f30773130dd31acd3ba7d62bacSteve Block                mQueuedMessages = null;
189d875ce6dac3c2e9a671c121c80b40d2536cbb2afSteve Block            }
1900ac031b3d29c6de90895c875991585812dc7388fSteve Block        }
1910ac031b3d29c6de90895c875991585812dc7388fSteve Block    }
1920ac031b3d29c6de90895c875991585812dc7388fSteve Block
1930ac031b3d29c6de90895c875991585812dc7388fSteve Block    /**
1940ac031b3d29c6de90895c875991585812dc7388fSteve Block     * Utility function to send a message to our handler.
1950ac031b3d29c6de90895c875991585812dc7388fSteve Block     */
196e4b2d4dc7db426052d1dfebc40f6b64a001b6d73Steve Block    private synchronized void postMessage(Message msg) {
19701228fcff613e2f30773130dd31acd3ba7d62bacSteve Block        if (mHandler == null) {
19801228fcff613e2f30773130dd31acd3ba7d62bacSteve Block            if (mQueuedMessages == null) {
19901228fcff613e2f30773130dd31acd3ba7d62bacSteve Block                mQueuedMessages = new Vector<Message>();
20001228fcff613e2f30773130dd31acd3ba7d62bacSteve Block            }
20101228fcff613e2f30773130dd31acd3ba7d62bacSteve Block            mQueuedMessages.add(msg);
20201228fcff613e2f30773130dd31acd3ba7d62bacSteve Block        } else {
20301228fcff613e2f30773130dd31acd3ba7d62bacSteve Block            mHandler.sendMessage(msg);
20401228fcff613e2f30773130dd31acd3ba7d62bacSteve Block        }
2050ac031b3d29c6de90895c875991585812dc7388fSteve Block    }
2060ac031b3d29c6de90895c875991585812dc7388fSteve Block
2070ac031b3d29c6de90895c875991585812dc7388fSteve Block    /**
2086c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard     * Utility function to send a message to the handler on the UI thread
2096c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard     */
2106c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard    private void postUIMessage(Message msg) {
2116c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard        if (mUIHandler != null) {
2126c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard            mUIHandler.sendMessage(msg);
2136c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard        }
2146c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard    }
2156c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard
2166c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard    /**
2177351adf76a97b07bb2d777c56e78752cb7834bb0Steve Block     * Get the set of origins for which Geolocation permissions are stored.
2187351adf76a97b07bb2d777c56e78752cb7834bb0Steve Block     * @param callback A {@link ValueCallback} to receive the result of this
2197351adf76a97b07bb2d777c56e78752cb7834bb0Steve Block     *                 request. This object's
2207351adf76a97b07bb2d777c56e78752cb7834bb0Steve Block     *                 {@link ValueCallback#onReceiveValue(T) onReceiveValue()}
2217351adf76a97b07bb2d777c56e78752cb7834bb0Steve Block     *                 method will be invoked asynchronously with a set of
2227351adf76a97b07bb2d777c56e78752cb7834bb0Steve Block     *                 Strings containing the origins for which Geolocation
2237351adf76a97b07bb2d777c56e78752cb7834bb0Steve Block     *                 permissions are stored.
2240ac031b3d29c6de90895c875991585812dc7388fSteve Block     */
2257351adf76a97b07bb2d777c56e78752cb7834bb0Steve Block    // Note that we represent the origins as strings. These are created using
2267351adf76a97b07bb2d777c56e78752cb7834bb0Steve Block    // WebCore::SecurityOrigin::toString(). As long as all 'HTML 5 modules'
2277351adf76a97b07bb2d777c56e78752cb7834bb0Steve Block    // (Database, Geolocation etc) do so, it's safe to match up origins based
2287351adf76a97b07bb2d777c56e78752cb7834bb0Steve Block    // on this string.
22957534f1b9f52cea094e8197d1ca40f0d2f68cc66Steve Block    public void getOrigins(ValueCallback<Set<String> > callback) {
2306c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard        if (callback != null) {
2316c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard            if (WebViewCore.THREAD_NAME.equals(Thread.currentThread().getName())) {
23201228fcff613e2f30773130dd31acd3ba7d62bacSteve Block                Set origins = nativeGetOrigins();
23301228fcff613e2f30773130dd31acd3ba7d62bacSteve Block                callback.onReceiveValue(origins);
2346c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard            } else {
2356c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard                postMessage(Message.obtain(null, GET_ORIGINS, callback));
2360ac031b3d29c6de90895c875991585812dc7388fSteve Block            }
2370ac031b3d29c6de90895c875991585812dc7388fSteve Block        }
2380ac031b3d29c6de90895c875991585812dc7388fSteve Block    }
2390ac031b3d29c6de90895c875991585812dc7388fSteve Block
2400ac031b3d29c6de90895c875991585812dc7388fSteve Block    /**
2417351adf76a97b07bb2d777c56e78752cb7834bb0Steve Block     * Get the Geolocation permission state for the specified origin.
2427351adf76a97b07bb2d777c56e78752cb7834bb0Steve Block     * @param origin The origin for which Geolocation permission is requested.
2437351adf76a97b07bb2d777c56e78752cb7834bb0Steve Block     * @param callback A {@link ValueCallback} to receive the result of this
2447351adf76a97b07bb2d777c56e78752cb7834bb0Steve Block     *                 request. This object's
2457351adf76a97b07bb2d777c56e78752cb7834bb0Steve Block     *                 {@link ValueCallback#onReceiveValue(T) onReceiveValue()}
2467351adf76a97b07bb2d777c56e78752cb7834bb0Steve Block     *                 method will be invoked asynchronously with a boolean
2477351adf76a97b07bb2d777c56e78752cb7834bb0Steve Block     *                 indicating whether or not the origin can use the
2487351adf76a97b07bb2d777c56e78752cb7834bb0Steve Block     *                 Geolocation API.
2490ac031b3d29c6de90895c875991585812dc7388fSteve Block     */
2506c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard    public void getAllowed(String origin, ValueCallback<Boolean> callback) {
2516c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard        if (callback == null) {
2526c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard            return;
2536c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard        }
2546c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard        if (origin == null) {
2556c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard            callback.onReceiveValue(null);
2566c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard            return;
2576c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard        }
2586c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard        if (WebViewCore.THREAD_NAME.equals(Thread.currentThread().getName())) {
25901228fcff613e2f30773130dd31acd3ba7d62bacSteve Block            boolean allowed = nativeGetAllowed(origin);
26001228fcff613e2f30773130dd31acd3ba7d62bacSteve Block            callback.onReceiveValue(new Boolean(allowed));
2616c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard        } else {
2626c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard            Map values = new HashMap<String, Object>();
2636c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard            values.put(ORIGIN, origin);
2646c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard            values.put(CALLBACK, callback);
2656c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard            postMessage(Message.obtain(null, GET_ALLOWED, values));
2660ac031b3d29c6de90895c875991585812dc7388fSteve Block        }
2670ac031b3d29c6de90895c875991585812dc7388fSteve Block    }
2680ac031b3d29c6de90895c875991585812dc7388fSteve Block
2690ac031b3d29c6de90895c875991585812dc7388fSteve Block    /**
2707351adf76a97b07bb2d777c56e78752cb7834bb0Steve Block     * Clear the Geolocation permission state for the specified origin.
2717351adf76a97b07bb2d777c56e78752cb7834bb0Steve Block     * @param origin The origin for which Geolocation permissions are cleared.
2720ac031b3d29c6de90895c875991585812dc7388fSteve Block     */
2737351adf76a97b07bb2d777c56e78752cb7834bb0Steve Block    // This method may be called before the WebKit
2747351adf76a97b07bb2d777c56e78752cb7834bb0Steve Block    // thread has intialized the message handler. Messages will be queued until
2757351adf76a97b07bb2d777c56e78752cb7834bb0Steve Block    // this time.
2760ac031b3d29c6de90895c875991585812dc7388fSteve Block    public void clear(String origin) {
2770ac031b3d29c6de90895c875991585812dc7388fSteve Block        // Called on the UI thread.
27801228fcff613e2f30773130dd31acd3ba7d62bacSteve Block        postMessage(Message.obtain(null, CLEAR, origin));
279d875ce6dac3c2e9a671c121c80b40d2536cbb2afSteve Block    }
280d875ce6dac3c2e9a671c121c80b40d2536cbb2afSteve Block
281d875ce6dac3c2e9a671c121c80b40d2536cbb2afSteve Block    /**
2827351adf76a97b07bb2d777c56e78752cb7834bb0Steve Block     * Allow the specified origin to use the Geolocation API.
2837351adf76a97b07bb2d777c56e78752cb7834bb0Steve Block     * @param origin The origin for which Geolocation API use is allowed.
284d875ce6dac3c2e9a671c121c80b40d2536cbb2afSteve Block     */
2857351adf76a97b07bb2d777c56e78752cb7834bb0Steve Block    // This method may be called before the WebKit
2867351adf76a97b07bb2d777c56e78752cb7834bb0Steve Block    // thread has intialized the message handler. Messages will be queued until
2877351adf76a97b07bb2d777c56e78752cb7834bb0Steve Block    // this time.
288d875ce6dac3c2e9a671c121c80b40d2536cbb2afSteve Block    public void allow(String origin) {
289d875ce6dac3c2e9a671c121c80b40d2536cbb2afSteve Block        // Called on the UI thread.
29001228fcff613e2f30773130dd31acd3ba7d62bacSteve Block        postMessage(Message.obtain(null, ALLOW, origin));
2910ac031b3d29c6de90895c875991585812dc7388fSteve Block    }
2920ac031b3d29c6de90895c875991585812dc7388fSteve Block
2930ac031b3d29c6de90895c875991585812dc7388fSteve Block    /**
2947351adf76a97b07bb2d777c56e78752cb7834bb0Steve Block     * Clear the Geolocation permission state for all origins.
2950ac031b3d29c6de90895c875991585812dc7388fSteve Block     */
2960ac031b3d29c6de90895c875991585812dc7388fSteve Block    public void clearAll() {
2970ac031b3d29c6de90895c875991585812dc7388fSteve Block        // Called on the UI thread.
2980ac031b3d29c6de90895c875991585812dc7388fSteve Block        postMessage(Message.obtain(null, CLEAR_ALL));
2990ac031b3d29c6de90895c875991585812dc7388fSteve Block    }
3000ac031b3d29c6de90895c875991585812dc7388fSteve Block
3010ac031b3d29c6de90895c875991585812dc7388fSteve Block    // Native functions, run on the WebKit thread.
3020ac031b3d29c6de90895c875991585812dc7388fSteve Block    private static native Set nativeGetOrigins();
3030ac031b3d29c6de90895c875991585812dc7388fSteve Block    private static native boolean nativeGetAllowed(String origin);
3040ac031b3d29c6de90895c875991585812dc7388fSteve Block    private static native void nativeClear(String origin);
305d875ce6dac3c2e9a671c121c80b40d2536cbb2afSteve Block    private static native void nativeAllow(String origin);
3060ac031b3d29c6de90895c875991585812dc7388fSteve Block    private static native void nativeClearAll();
3070ac031b3d29c6de90895c875991585812dc7388fSteve Block}
308