GeolocationPermissions.java revision 4faee09c422a70439129e9fb40dd82f03d42c98d
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;
220ac031b3d29c6de90895c875991585812dc7388fSteve Blockimport java.util.concurrent.locks.Condition;
230ac031b3d29c6de90895c875991585812dc7388fSteve Blockimport java.util.concurrent.locks.Lock;
240ac031b3d29c6de90895c875991585812dc7388fSteve Blockimport java.util.concurrent.locks.ReentrantLock;
250ac031b3d29c6de90895c875991585812dc7388fSteve Blockimport java.util.Set;
260ac031b3d29c6de90895c875991585812dc7388fSteve Block
270ac031b3d29c6de90895c875991585812dc7388fSteve Block
280ac031b3d29c6de90895c875991585812dc7388fSteve Block/**
290ac031b3d29c6de90895c875991585812dc7388fSteve Block * Implements the Java side of GeolocationPermissions. Simply marshalls calls
300ac031b3d29c6de90895c875991585812dc7388fSteve Block * from the UI thread to the WebKit thread.
310ac031b3d29c6de90895c875991585812dc7388fSteve Block * @hide
320ac031b3d29c6de90895c875991585812dc7388fSteve Block */
330ac031b3d29c6de90895c875991585812dc7388fSteve Blockpublic final class GeolocationPermissions {
344faee09c422a70439129e9fb40dd82f03d42c98dSteve Block    /**
354faee09c422a70439129e9fb40dd82f03d42c98dSteve Block     * Callback interface used by the browser to report a Geolocation permission
364faee09c422a70439129e9fb40dd82f03d42c98dSteve Block     * state set by the user in response to a permissions prompt.
374faee09c422a70439129e9fb40dd82f03d42c98dSteve Block     */
384faee09c422a70439129e9fb40dd82f03d42c98dSteve Block    public interface Callback {
394faee09c422a70439129e9fb40dd82f03d42c98dSteve Block        public void invoke(String origin, boolean allow, boolean remember);
404faee09c422a70439129e9fb40dd82f03d42c98dSteve Block    };
414faee09c422a70439129e9fb40dd82f03d42c98dSteve Block
420ac031b3d29c6de90895c875991585812dc7388fSteve Block    // Log tag
430ac031b3d29c6de90895c875991585812dc7388fSteve Block    private static final String TAG = "geolocationPermissions";
440ac031b3d29c6de90895c875991585812dc7388fSteve Block
450ac031b3d29c6de90895c875991585812dc7388fSteve Block    // Global instance
460ac031b3d29c6de90895c875991585812dc7388fSteve Block    private static GeolocationPermissions sInstance;
470ac031b3d29c6de90895c875991585812dc7388fSteve Block
480ac031b3d29c6de90895c875991585812dc7388fSteve Block    private Handler mHandler;
490ac031b3d29c6de90895c875991585812dc7388fSteve Block
500ac031b3d29c6de90895c875991585812dc7388fSteve Block    // Members used to transfer the origins and permissions between threads.
510ac031b3d29c6de90895c875991585812dc7388fSteve Block    private Set<String> mOrigins;
520ac031b3d29c6de90895c875991585812dc7388fSteve Block    private boolean mAllowed;
530ac031b3d29c6de90895c875991585812dc7388fSteve Block    private static Lock mLock = new ReentrantLock();
540ac031b3d29c6de90895c875991585812dc7388fSteve Block    private static boolean mUpdated;
550ac031b3d29c6de90895c875991585812dc7388fSteve Block    private static Condition mUpdatedCondition = mLock.newCondition();
560ac031b3d29c6de90895c875991585812dc7388fSteve Block
570ac031b3d29c6de90895c875991585812dc7388fSteve Block    // Message ids
580ac031b3d29c6de90895c875991585812dc7388fSteve Block    static final int GET_ORIGINS = 0;
590ac031b3d29c6de90895c875991585812dc7388fSteve Block    static final int GET_ALLOWED = 1;
600ac031b3d29c6de90895c875991585812dc7388fSteve Block    static final int CLEAR = 2;
610ac031b3d29c6de90895c875991585812dc7388fSteve Block    static final int CLEAR_ALL = 3;
620ac031b3d29c6de90895c875991585812dc7388fSteve Block
630ac031b3d29c6de90895c875991585812dc7388fSteve Block    /**
640ac031b3d29c6de90895c875991585812dc7388fSteve Block     * Gets the singleton instance of the class.
650ac031b3d29c6de90895c875991585812dc7388fSteve Block     */
660ac031b3d29c6de90895c875991585812dc7388fSteve Block    public static GeolocationPermissions getInstance() {
670ac031b3d29c6de90895c875991585812dc7388fSteve Block      if (sInstance == null) {
680ac031b3d29c6de90895c875991585812dc7388fSteve Block          sInstance = new GeolocationPermissions();
690ac031b3d29c6de90895c875991585812dc7388fSteve Block      }
700ac031b3d29c6de90895c875991585812dc7388fSteve Block      return sInstance;
710ac031b3d29c6de90895c875991585812dc7388fSteve Block    }
720ac031b3d29c6de90895c875991585812dc7388fSteve Block
730ac031b3d29c6de90895c875991585812dc7388fSteve Block    /**
740ac031b3d29c6de90895c875991585812dc7388fSteve Block     * Creates the message handler. Must be called on the WebKit thread.
750ac031b3d29c6de90895c875991585812dc7388fSteve Block     */
760ac031b3d29c6de90895c875991585812dc7388fSteve Block    public void createHandler() {
770ac031b3d29c6de90895c875991585812dc7388fSteve Block        if (mHandler == null) {
780ac031b3d29c6de90895c875991585812dc7388fSteve Block            mHandler = new Handler() {
790ac031b3d29c6de90895c875991585812dc7388fSteve Block                @Override
800ac031b3d29c6de90895c875991585812dc7388fSteve Block                public void handleMessage(Message msg) {
810ac031b3d29c6de90895c875991585812dc7388fSteve Block                    // Runs on the WebKit thread.
820ac031b3d29c6de90895c875991585812dc7388fSteve Block                    switch (msg.what) {
830ac031b3d29c6de90895c875991585812dc7388fSteve Block                        case GET_ORIGINS:
840ac031b3d29c6de90895c875991585812dc7388fSteve Block                            getOriginsImpl();
850ac031b3d29c6de90895c875991585812dc7388fSteve Block                            break;
860ac031b3d29c6de90895c875991585812dc7388fSteve Block                        case GET_ALLOWED:
870ac031b3d29c6de90895c875991585812dc7388fSteve Block                            getAllowedImpl((String) msg.obj);
880ac031b3d29c6de90895c875991585812dc7388fSteve Block                            break;
890ac031b3d29c6de90895c875991585812dc7388fSteve Block                        case CLEAR:
900ac031b3d29c6de90895c875991585812dc7388fSteve Block                            nativeClear((String) msg.obj);
910ac031b3d29c6de90895c875991585812dc7388fSteve Block                            break;
920ac031b3d29c6de90895c875991585812dc7388fSteve Block                        case CLEAR_ALL:
930ac031b3d29c6de90895c875991585812dc7388fSteve Block                            nativeClearAll();
940ac031b3d29c6de90895c875991585812dc7388fSteve Block                            break;
950ac031b3d29c6de90895c875991585812dc7388fSteve Block                    }
960ac031b3d29c6de90895c875991585812dc7388fSteve Block                }
970ac031b3d29c6de90895c875991585812dc7388fSteve Block            };
980ac031b3d29c6de90895c875991585812dc7388fSteve Block        }
990ac031b3d29c6de90895c875991585812dc7388fSteve Block    }
1000ac031b3d29c6de90895c875991585812dc7388fSteve Block
1010ac031b3d29c6de90895c875991585812dc7388fSteve Block    /**
1020ac031b3d29c6de90895c875991585812dc7388fSteve Block     * Utility function to send a message to our handler.
1030ac031b3d29c6de90895c875991585812dc7388fSteve Block     */
1040ac031b3d29c6de90895c875991585812dc7388fSteve Block    private void postMessage(Message msg) {
1050ac031b3d29c6de90895c875991585812dc7388fSteve Block        assert(mHandler != null);
1060ac031b3d29c6de90895c875991585812dc7388fSteve Block        mHandler.sendMessage(msg);
1070ac031b3d29c6de90895c875991585812dc7388fSteve Block    }
1080ac031b3d29c6de90895c875991585812dc7388fSteve Block
1090ac031b3d29c6de90895c875991585812dc7388fSteve Block    /**
1100ac031b3d29c6de90895c875991585812dc7388fSteve Block     * Gets the set of origins for which Geolocation permissions are stored.
1110ac031b3d29c6de90895c875991585812dc7388fSteve Block     * Note that we represent the origins as strings. These are created using
1120ac031b3d29c6de90895c875991585812dc7388fSteve Block     * WebCore::SecurityOrigin::toString(). As long as all 'HTML 5 modules'
1130ac031b3d29c6de90895c875991585812dc7388fSteve Block     * (Database, Geolocation etc) do so, it's safe to match up origins for the
1140ac031b3d29c6de90895c875991585812dc7388fSteve Block     * purposes of displaying UI.
1150ac031b3d29c6de90895c875991585812dc7388fSteve Block     */
1160ac031b3d29c6de90895c875991585812dc7388fSteve Block    public Set getOrigins() {
1170ac031b3d29c6de90895c875991585812dc7388fSteve Block        // Called on the UI thread.
1180ac031b3d29c6de90895c875991585812dc7388fSteve Block        Set origins = null;
1190ac031b3d29c6de90895c875991585812dc7388fSteve Block        mLock.lock();
1200ac031b3d29c6de90895c875991585812dc7388fSteve Block        try {
1210ac031b3d29c6de90895c875991585812dc7388fSteve Block            mUpdated = false;
1220ac031b3d29c6de90895c875991585812dc7388fSteve Block            postMessage(Message.obtain(null, GET_ORIGINS));
1230ac031b3d29c6de90895c875991585812dc7388fSteve Block            while (!mUpdated) {
1240ac031b3d29c6de90895c875991585812dc7388fSteve Block                mUpdatedCondition.await();
1250ac031b3d29c6de90895c875991585812dc7388fSteve Block            }
1260ac031b3d29c6de90895c875991585812dc7388fSteve Block            origins = mOrigins;
1270ac031b3d29c6de90895c875991585812dc7388fSteve Block        } catch (InterruptedException e) {
1280ac031b3d29c6de90895c875991585812dc7388fSteve Block            Log.e(TAG, "Exception while waiting for update", e);
1290ac031b3d29c6de90895c875991585812dc7388fSteve Block        } finally {
1300ac031b3d29c6de90895c875991585812dc7388fSteve Block            mLock.unlock();
1310ac031b3d29c6de90895c875991585812dc7388fSteve Block        }
1320ac031b3d29c6de90895c875991585812dc7388fSteve Block        return origins;
1330ac031b3d29c6de90895c875991585812dc7388fSteve Block    }
1340ac031b3d29c6de90895c875991585812dc7388fSteve Block
1350ac031b3d29c6de90895c875991585812dc7388fSteve Block    /**
1360ac031b3d29c6de90895c875991585812dc7388fSteve Block     * Helper method to get the set of origins.
1370ac031b3d29c6de90895c875991585812dc7388fSteve Block     */
1380ac031b3d29c6de90895c875991585812dc7388fSteve Block    private void getOriginsImpl() {
1390ac031b3d29c6de90895c875991585812dc7388fSteve Block        // Called on the WebKit thread.
1400ac031b3d29c6de90895c875991585812dc7388fSteve Block        mLock.lock();
1410ac031b3d29c6de90895c875991585812dc7388fSteve Block        mOrigins = nativeGetOrigins();
1420ac031b3d29c6de90895c875991585812dc7388fSteve Block        mUpdated = true;
1430ac031b3d29c6de90895c875991585812dc7388fSteve Block        mUpdatedCondition.signal();
1440ac031b3d29c6de90895c875991585812dc7388fSteve Block        mLock.unlock();
1450ac031b3d29c6de90895c875991585812dc7388fSteve Block    }
1460ac031b3d29c6de90895c875991585812dc7388fSteve Block
1470ac031b3d29c6de90895c875991585812dc7388fSteve Block    /**
1480ac031b3d29c6de90895c875991585812dc7388fSteve Block     * Gets the permission state for the specified origin.
1490ac031b3d29c6de90895c875991585812dc7388fSteve Block     */
1500ac031b3d29c6de90895c875991585812dc7388fSteve Block    public boolean getAllowed(String origin) {
1510ac031b3d29c6de90895c875991585812dc7388fSteve Block        // Called on the UI thread.
1520ac031b3d29c6de90895c875991585812dc7388fSteve Block        boolean allowed = false;
1530ac031b3d29c6de90895c875991585812dc7388fSteve Block        mLock.lock();
1540ac031b3d29c6de90895c875991585812dc7388fSteve Block        try {
1550ac031b3d29c6de90895c875991585812dc7388fSteve Block            mUpdated = false;
1560ac031b3d29c6de90895c875991585812dc7388fSteve Block            postMessage(Message.obtain(null, GET_ALLOWED, origin));
1570ac031b3d29c6de90895c875991585812dc7388fSteve Block            while (!mUpdated) {
1580ac031b3d29c6de90895c875991585812dc7388fSteve Block                mUpdatedCondition.await();
1590ac031b3d29c6de90895c875991585812dc7388fSteve Block            }
1600ac031b3d29c6de90895c875991585812dc7388fSteve Block            allowed = mAllowed;
1610ac031b3d29c6de90895c875991585812dc7388fSteve Block        } catch (InterruptedException e) {
1620ac031b3d29c6de90895c875991585812dc7388fSteve Block            Log.e(TAG, "Exception while waiting for update", e);
1630ac031b3d29c6de90895c875991585812dc7388fSteve Block        } finally {
1640ac031b3d29c6de90895c875991585812dc7388fSteve Block            mLock.unlock();
1650ac031b3d29c6de90895c875991585812dc7388fSteve Block        }
1660ac031b3d29c6de90895c875991585812dc7388fSteve Block        return allowed;
1670ac031b3d29c6de90895c875991585812dc7388fSteve Block    }
1680ac031b3d29c6de90895c875991585812dc7388fSteve Block
1690ac031b3d29c6de90895c875991585812dc7388fSteve Block    /**
1700ac031b3d29c6de90895c875991585812dc7388fSteve Block     * Helper method to get the permission state.
1710ac031b3d29c6de90895c875991585812dc7388fSteve Block     */
1720ac031b3d29c6de90895c875991585812dc7388fSteve Block    private void getAllowedImpl(String origin) {
1730ac031b3d29c6de90895c875991585812dc7388fSteve Block        // Called on the WebKit thread.
1740ac031b3d29c6de90895c875991585812dc7388fSteve Block        mLock.lock();
1750ac031b3d29c6de90895c875991585812dc7388fSteve Block        mAllowed = nativeGetAllowed(origin);
1760ac031b3d29c6de90895c875991585812dc7388fSteve Block        mUpdated = true;
1770ac031b3d29c6de90895c875991585812dc7388fSteve Block        mUpdatedCondition.signal();
1780ac031b3d29c6de90895c875991585812dc7388fSteve Block        mLock.unlock();
1790ac031b3d29c6de90895c875991585812dc7388fSteve Block    }
1800ac031b3d29c6de90895c875991585812dc7388fSteve Block
1810ac031b3d29c6de90895c875991585812dc7388fSteve Block    /**
1820ac031b3d29c6de90895c875991585812dc7388fSteve Block     * Clears the permission state for the specified origin.
1830ac031b3d29c6de90895c875991585812dc7388fSteve Block     */
1840ac031b3d29c6de90895c875991585812dc7388fSteve Block    public void clear(String origin) {
1850ac031b3d29c6de90895c875991585812dc7388fSteve Block        // Called on the UI thread.
1860ac031b3d29c6de90895c875991585812dc7388fSteve Block        postMessage(Message.obtain(null, CLEAR, origin));
1870ac031b3d29c6de90895c875991585812dc7388fSteve Block    }
1880ac031b3d29c6de90895c875991585812dc7388fSteve Block
1890ac031b3d29c6de90895c875991585812dc7388fSteve Block    /**
1900ac031b3d29c6de90895c875991585812dc7388fSteve Block     * Clears the permission state for all origins.
1910ac031b3d29c6de90895c875991585812dc7388fSteve Block     */
1920ac031b3d29c6de90895c875991585812dc7388fSteve Block    public void clearAll() {
1930ac031b3d29c6de90895c875991585812dc7388fSteve Block        // Called on the UI thread.
1940ac031b3d29c6de90895c875991585812dc7388fSteve Block        postMessage(Message.obtain(null, CLEAR_ALL));
1950ac031b3d29c6de90895c875991585812dc7388fSteve Block    }
1960ac031b3d29c6de90895c875991585812dc7388fSteve Block
1970ac031b3d29c6de90895c875991585812dc7388fSteve Block    // Native functions, run on the WebKit thread.
1980ac031b3d29c6de90895c875991585812dc7388fSteve Block    private static native Set nativeGetOrigins();
1990ac031b3d29c6de90895c875991585812dc7388fSteve Block    private static native boolean nativeGetAllowed(String origin);
2000ac031b3d29c6de90895c875991585812dc7388fSteve Block    private static native void nativeClear(String origin);
2010ac031b3d29c6de90895c875991585812dc7388fSteve Block    private static native void nativeClearAll();
2020ac031b3d29c6de90895c875991585812dc7388fSteve Block}
203