OSDN Git Service

original
[gb-231r1-is01/Gingerbread_2.3.3_r1_IS01.git] / frameworks / base / core / java / android / webkit / GeolocationPermissions.java
1 /*
2  * Copyright (C) 2009 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package android.webkit;
18
19 import android.os.Handler;
20 import android.os.Message;
21 import android.util.Log;
22 import java.util.HashMap;
23 import java.util.HashSet;
24 import java.util.Map;
25 import java.util.Set;
26 import java.util.Vector;
27
28
29 /**
30  * This class is used to get Geolocation permissions from, and set them on the
31  * WebView. For example, it could be used to allow a user to manage Geolocation
32  * permissions from a browser's UI.
33  *
34  * Permissions are managed on a per-origin basis, as required by the
35  * Geolocation spec - http://dev.w3.org/geo/api/spec-source.html. An origin
36  * specifies the scheme, host and port of particular frame. An origin is
37  * represented here as a string, using the output of
38  * WebCore::SecurityOrigin::toString.
39  *
40  * This class is the Java counterpart of the WebKit C++ GeolocationPermissions
41  * class. It simply marshalls calls from the UI thread to the WebKit thread.
42  *
43  * Within WebKit, Geolocation permissions may be applied either temporarily
44  * (for the duration of the page) or permanently. This class deals only with
45  * permanent permissions.
46  */
47 public final class GeolocationPermissions {
48     /**
49      * Callback interface used by the browser to report a Geolocation permission
50      * state set by the user in response to a permissions prompt.
51      */
52     public interface Callback {
53         public void invoke(String origin, boolean allow, boolean remember);
54     };
55
56     // Log tag
57     private static final String TAG = "geolocationPermissions";
58
59     // Global instance
60     private static GeolocationPermissions sInstance;
61
62     private Handler mHandler;
63     private Handler mUIHandler;
64
65     // A queue to store messages until the handler is ready.
66     private Vector<Message> mQueuedMessages;
67
68     // Message ids
69     static final int GET_ORIGINS = 0;
70     static final int GET_ALLOWED = 1;
71     static final int CLEAR = 2;
72     static final int ALLOW = 3;
73     static final int CLEAR_ALL = 4;
74
75     // Message ids on the UI thread
76     static final int RETURN_ORIGINS = 0;
77     static final int RETURN_ALLOWED = 1;
78
79     private static final String ORIGINS = "origins";
80     private static final String ORIGIN = "origin";
81     private static final String CALLBACK = "callback";
82     private static final String ALLOWED = "allowed";
83
84     /**
85      * Gets the singleton instance of the class.
86      */
87     public static GeolocationPermissions getInstance() {
88       if (sInstance == null) {
89           sInstance = new GeolocationPermissions();
90       }
91       return sInstance;
92     }
93
94     /**
95      * Creates the UI message handler. Must be called on the UI thread.
96      * @hide
97      */
98     public void createUIHandler() {
99         if (mUIHandler == null) {
100             mUIHandler = new Handler() {
101                 @Override
102                 public void handleMessage(Message msg) {
103                     // Runs on the UI thread.
104                     switch (msg.what) {
105                         case RETURN_ORIGINS: {
106                             Map values = (Map) msg.obj;
107                             Set<String> origins = (Set<String>) values.get(ORIGINS);
108                             ValueCallback<Set<String> > callback = (ValueCallback<Set<String> >) values.get(CALLBACK);
109                             callback.onReceiveValue(origins);
110                         } break;
111                         case RETURN_ALLOWED: {
112                             Map values = (Map) msg.obj;
113                             Boolean allowed = (Boolean) values.get(ALLOWED);
114                             ValueCallback<Boolean> callback = (ValueCallback<Boolean>) values.get(CALLBACK);
115                             callback.onReceiveValue(allowed);
116                         } break;
117                     }
118                 }
119             };
120         }
121     }
122
123     /**
124      * Creates the message handler. Must be called on the WebKit thread.
125      * @hide
126      */
127     public synchronized void createHandler() {
128         if (mHandler == null) {
129             mHandler = new Handler() {
130                 @Override
131                 public void handleMessage(Message msg) {
132                     // Runs on the WebKit thread.
133                     switch (msg.what) {
134                         case GET_ORIGINS: {
135                             Set origins = nativeGetOrigins();
136                             ValueCallback callback = (ValueCallback) msg.obj;
137                             Map values = new HashMap<String, Object>();
138                             values.put(CALLBACK, callback);
139                             values.put(ORIGINS, origins);
140                             postUIMessage(Message.obtain(null, RETURN_ORIGINS, values));
141                             } break;
142                         case GET_ALLOWED: {
143                             Map values = (Map) msg.obj;
144                             String origin = (String) values.get(ORIGIN);
145                             ValueCallback callback = (ValueCallback) values.get(CALLBACK);
146                             boolean allowed = nativeGetAllowed(origin);
147                             Map retValues = new HashMap<String, Object>();
148                             retValues.put(CALLBACK, callback);
149                             retValues.put(ALLOWED, new Boolean(allowed));
150                             postUIMessage(Message.obtain(null, RETURN_ALLOWED, retValues));
151                             } break;
152                         case CLEAR:
153                             nativeClear((String) msg.obj);
154                             break;
155                         case ALLOW:
156                             nativeAllow((String) msg.obj);
157                             break;
158                         case CLEAR_ALL:
159                             nativeClearAll();
160                             break;
161                     }
162                 }
163             };
164
165             // Handle the queued messages
166             if (mQueuedMessages != null) {
167                 while (!mQueuedMessages.isEmpty()) {
168                     mHandler.sendMessage(mQueuedMessages.remove(0));
169                 }
170                 mQueuedMessages = null;
171             }
172         }
173     }
174
175     /**
176      * Utility function to send a message to our handler.
177      */
178     private synchronized void postMessage(Message msg) {
179         if (mHandler == null) {
180             if (mQueuedMessages == null) {
181                 mQueuedMessages = new Vector<Message>();
182             }
183             mQueuedMessages.add(msg);
184         } else {
185             mHandler.sendMessage(msg);
186         }
187     }
188
189     /**
190      * Utility function to send a message to the handler on the UI thread
191      */
192     private void postUIMessage(Message msg) {
193         if (mUIHandler != null) {
194             mUIHandler.sendMessage(msg);
195         }
196     }
197
198     /**
199      * Gets the set of origins for which Geolocation permissions are stored.
200      * Note that we represent the origins as strings. These are created using
201      * WebCore::SecurityOrigin::toString(). As long as all 'HTML 5 modules'
202      * (Database, Geolocation etc) do so, it's safe to match up origins based
203      * on this string.
204      *
205      * Callback is a ValueCallback object whose onReceiveValue method will be
206      * called asynchronously with the set of origins.
207      */
208     public void getOrigins(ValueCallback<Set<String> > callback) {
209         if (callback != null) {
210             if (WebViewCore.THREAD_NAME.equals(Thread.currentThread().getName())) {
211                 Set origins = nativeGetOrigins();
212                 callback.onReceiveValue(origins);
213             } else {
214                 postMessage(Message.obtain(null, GET_ORIGINS, callback));
215             }
216         }
217     }
218
219     /**
220      * Gets the permission state for the specified origin.
221      *
222      * Callback is a ValueCallback object whose onReceiveValue method will be
223      * called asynchronously with the permission state for the origin.
224      */
225     public void getAllowed(String origin, ValueCallback<Boolean> callback) {
226         if (callback == null) {
227             return;
228         }
229         if (origin == null) {
230             callback.onReceiveValue(null);
231             return;
232         }
233         if (WebViewCore.THREAD_NAME.equals(Thread.currentThread().getName())) {
234             boolean allowed = nativeGetAllowed(origin);
235             callback.onReceiveValue(new Boolean(allowed));
236         } else {
237             Map values = new HashMap<String, Object>();
238             values.put(ORIGIN, origin);
239             values.put(CALLBACK, callback);
240             postMessage(Message.obtain(null, GET_ALLOWED, values));
241         }
242     }
243
244     /**
245      * Clears the permission state for the specified origin. This method may be
246      * called before the WebKit thread has intialized the message handler.
247      * Messages will be queued until this time.
248      */
249     public void clear(String origin) {
250         // Called on the UI thread.
251         postMessage(Message.obtain(null, CLEAR, origin));
252     }
253
254     /**
255      * Allows the specified origin. This method may be called before the WebKit
256      * thread has intialized the message handler. Messages will be queued until
257      * this time.
258      */
259     public void allow(String origin) {
260         // Called on the UI thread.
261         postMessage(Message.obtain(null, ALLOW, origin));
262     }
263
264     /**
265      * Clears the permission state for all origins.
266      */
267     public void clearAll() {
268         // Called on the UI thread.
269         postMessage(Message.obtain(null, CLEAR_ALL));
270     }
271
272     // Native functions, run on the WebKit thread.
273     private static native Set nativeGetOrigins();
274     private static native boolean nativeGetAllowed(String origin);
275     private static native void nativeClear(String origin);
276     private static native void nativeAllow(String origin);
277     private static native void nativeClearAll();
278 }