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