1d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon/*
2d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon * Copyright (C) 2012 The Android Open Source Project
3d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon *
4d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon * Licensed under the Apache License, Version 2.0 (the "License");
5d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon * you may not use this file except in compliance with the License.
6d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon * You may obtain a copy of the License at
7d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon *
8d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon *      http://www.apache.org/licenses/LICENSE-2.0
9d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon *
10d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon * Unless required by applicable law or agreed to in writing, software
11d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon * distributed under the License is distributed on an "AS IS" BASIS,
12d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon * See the License for the specific language governing permissions and
14d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon * limitations under the License.
15d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon */
16d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon
17d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixonpackage android.webkit;
18d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon
19d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixonimport android.os.Handler;
20d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixonimport android.os.Message;
21d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon
22d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixonimport java.util.Collection;
23d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixonimport java.util.HashMap;
24d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixonimport java.util.Map;
25d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixonimport java.util.Set;
26d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon
27d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon/** @hide */
28d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixonpublic class WebStorageClassic extends WebStorage {
29d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon    // Global instance of a WebStorage
30d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon    private static WebStorageClassic sWebStorage;
31d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon
32d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon    // Message ids
33d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon    static final int UPDATE = 0;
34d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon    static final int SET_QUOTA_ORIGIN = 1;
35d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon    static final int DELETE_ORIGIN = 2;
36d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon    static final int DELETE_ALL = 3;
37d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon    static final int GET_ORIGINS = 4;
38d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon    static final int GET_USAGE_ORIGIN = 5;
39d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon    static final int GET_QUOTA_ORIGIN = 6;
40d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon
41d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon    // Message ids on the UI thread
42d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon    static final int RETURN_ORIGINS = 0;
43d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon    static final int RETURN_USAGE_ORIGIN = 1;
44d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon    static final int RETURN_QUOTA_ORIGIN = 2;
45d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon
46d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon    private static final String ORIGINS = "origins";
47d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon    private static final String ORIGIN = "origin";
48d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon    private static final String CALLBACK = "callback";
49d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon    private static final String USAGE = "usage";
50d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon    private static final String QUOTA = "quota";
51d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon
52d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon    private Map <String, Origin> mOrigins;
53d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon
54d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon    private Handler mHandler = null;
55d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon    private Handler mUIHandler = null;
56d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon
57d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon    /**
58d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon     * @hide
59d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon     * Message handler, UI side
60d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon     * @hide
61d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon     */
62d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon    public void createUIHandler() {
63d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon        if (mUIHandler == null) {
64d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon            mUIHandler = new Handler() {
65d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                @Override
66d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                public void handleMessage(Message msg) {
67d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                    switch (msg.what) {
68d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                        case RETURN_ORIGINS: {
69d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                            Map values = (Map) msg.obj;
70d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                            Map origins = (Map) values.get(ORIGINS);
71d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                            ValueCallback<Map> callback = (ValueCallback<Map>) values.get(CALLBACK);
72d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                            callback.onReceiveValue(origins);
73d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                            } break;
74d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon
75d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                        case RETURN_USAGE_ORIGIN: {
76d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                            Map values = (Map) msg.obj;
77d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                            ValueCallback<Long> callback = (ValueCallback<Long>) values.get(CALLBACK);
78d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                            callback.onReceiveValue((Long)values.get(USAGE));
79d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                            } break;
80d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon
81d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                        case RETURN_QUOTA_ORIGIN: {
82d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                            Map values = (Map) msg.obj;
83d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                            ValueCallback<Long> callback = (ValueCallback<Long>) values.get(CALLBACK);
84d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                            callback.onReceiveValue((Long)values.get(QUOTA));
85d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                            } break;
86d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                    }
87d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                }
88d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon            };
89d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon        }
90d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon    }
91d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon
92d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon    /**
93d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon     * Message handler, WebCore side
94d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon     * @hide
95d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon     */
96d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon    public synchronized void createHandler() {
97d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon        if (mHandler == null) {
98d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon            mHandler = new Handler() {
99d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                @Override
100d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                public void handleMessage(Message msg) {
101d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                    switch (msg.what) {
102d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                        case SET_QUOTA_ORIGIN: {
103d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                            Origin website = (Origin) msg.obj;
104d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                            nativeSetQuotaForOrigin(website.getOrigin(),
105d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                                                    website.getQuota());
106d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                            } break;
107d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon
108d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                        case DELETE_ORIGIN: {
109d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                            Origin website = (Origin) msg.obj;
110d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                            nativeDeleteOrigin(website.getOrigin());
111d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                            } break;
112d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon
113d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                        case DELETE_ALL:
114d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                            nativeDeleteAllData();
115d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                            break;
116d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon
117d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                        case GET_ORIGINS: {
118d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                            syncValues();
119d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                            ValueCallback callback = (ValueCallback) msg.obj;
120d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                            Map origins = new HashMap(mOrigins);
121d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                            Map values = new HashMap<String, Object>();
122d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                            values.put(CALLBACK, callback);
123d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                            values.put(ORIGINS, origins);
124d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                            postUIMessage(Message.obtain(null, RETURN_ORIGINS, values));
125d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                            } break;
126d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon
127d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                        case GET_USAGE_ORIGIN: {
128d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                            syncValues();
129d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                            Map values = (Map) msg.obj;
130d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                            String origin = (String) values.get(ORIGIN);
131d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                            ValueCallback callback = (ValueCallback) values.get(CALLBACK);
132d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                            Origin website = mOrigins.get(origin);
133d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                            Map retValues = new HashMap<String, Object>();
134d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                            retValues.put(CALLBACK, callback);
135d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                            if (website != null) {
136d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                                long usage = website.getUsage();
137d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                                retValues.put(USAGE, new Long(usage));
138d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                            }
139d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                            postUIMessage(Message.obtain(null, RETURN_USAGE_ORIGIN, retValues));
140d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                            } break;
141d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon
142d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                        case GET_QUOTA_ORIGIN: {
143d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                            syncValues();
144d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                            Map values = (Map) msg.obj;
145d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                            String origin = (String) values.get(ORIGIN);
146d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                            ValueCallback callback = (ValueCallback) values.get(CALLBACK);
147d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                            Origin website = mOrigins.get(origin);
148d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                            Map retValues = new HashMap<String, Object>();
149d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                            retValues.put(CALLBACK, callback);
150d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                            if (website != null) {
151d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                                long quota = website.getQuota();
152d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                                retValues.put(QUOTA, new Long(quota));
153d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                            }
154d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                            postUIMessage(Message.obtain(null, RETURN_QUOTA_ORIGIN, retValues));
155d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                            } break;
156d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon
157d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                        case UPDATE:
158d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                            syncValues();
159d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                            break;
160d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                    }
161d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                }
162d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon            };
163d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon        }
164d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon    }
165d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon
166d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon    /*
167d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon     * When calling getOrigins(), getUsageForOrigin() and getQuotaForOrigin(),
168d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon     * we need to get the values from WebCore, but we cannot block while doing so
169d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon     * as we used to do, as this could result in a full deadlock (other WebCore
170d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon     * messages received while we are still blocked here, see http://b/2127737).
171d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon     *
172d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon     * We have to do everything asynchronously, by providing a callback function.
173d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon     * We post a message on the WebCore thread (mHandler) that will get the result
174d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon     * from WebCore, and we post it back on the UI thread (using mUIHandler).
175d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon     * We can then use the callback function to return the value.
176d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon     */
177d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon
178d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon    @Override
179d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon    public void getOrigins(ValueCallback<Map> callback) {
180d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon        if (callback != null) {
181d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon            if (WebViewCore.THREAD_NAME.equals(Thread.currentThread().getName())) {
182d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                syncValues();
183d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                callback.onReceiveValue(mOrigins);
184d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon            } else {
185d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                postMessage(Message.obtain(null, GET_ORIGINS, callback));
186d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon            }
187d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon        }
188d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon    }
189d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon
190d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon    /**
191d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon     * Returns a list of origins having a database
192d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon     * should only be called from WebViewCore.
193d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon     */
194d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon    Collection<Origin> getOriginsSync() {
195d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon        if (WebViewCore.THREAD_NAME.equals(Thread.currentThread().getName())) {
196d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon            update();
197d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon            return mOrigins.values();
198d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon        }
199d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon        return null;
200d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon    }
201d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon
202d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon    @Override
203d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon    public void getUsageForOrigin(String origin, ValueCallback<Long> callback) {
204d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon        if (callback == null) {
205d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon            return;
206d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon        }
207d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon        if (origin == null) {
208d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon            callback.onReceiveValue(null);
209d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon            return;
210d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon        }
211d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon        if (WebViewCore.THREAD_NAME.equals(Thread.currentThread().getName())) {
212d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon            syncValues();
213d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon            Origin website = mOrigins.get(origin);
214d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon            callback.onReceiveValue(new Long(website.getUsage()));
215d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon        } else {
216d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon            HashMap values = new HashMap<String, Object>();
217d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon            values.put(ORIGIN, origin);
218d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon            values.put(CALLBACK, callback);
219d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon            postMessage(Message.obtain(null, GET_USAGE_ORIGIN, values));
220d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon        }
221d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon    }
222d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon
223d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon    @Override
224d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon    public void getQuotaForOrigin(String origin, ValueCallback<Long> callback) {
225d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon        if (callback == null) {
226d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon            return;
227d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon        }
228d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon        if (origin == null) {
229d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon            callback.onReceiveValue(null);
230d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon            return;
231d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon        }
232d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon        if (WebViewCore.THREAD_NAME.equals(Thread.currentThread().getName())) {
233d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon            syncValues();
234d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon            Origin website = mOrigins.get(origin);
235d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon            callback.onReceiveValue(new Long(website.getUsage()));
236d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon        } else {
237d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon            HashMap values = new HashMap<String, Object>();
238d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon            values.put(ORIGIN, origin);
239d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon            values.put(CALLBACK, callback);
240d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon            postMessage(Message.obtain(null, GET_QUOTA_ORIGIN, values));
241d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon        }
242d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon    }
243d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon
244d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon    @Override
245d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon    public void setQuotaForOrigin(String origin, long quota) {
246d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon        if (origin != null) {
247d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon            if (WebViewCore.THREAD_NAME.equals(Thread.currentThread().getName())) {
248d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                nativeSetQuotaForOrigin(origin, quota);
249d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon            } else {
250d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                postMessage(Message.obtain(null, SET_QUOTA_ORIGIN,
251d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                    new Origin(origin, quota)));
252d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon            }
253d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon        }
254d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon    }
255d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon
256d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon    @Override
257d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon    public void deleteOrigin(String origin) {
258d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon        if (origin != null) {
259d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon            if (WebViewCore.THREAD_NAME.equals(Thread.currentThread().getName())) {
260d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                nativeDeleteOrigin(origin);
261d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon            } else {
262d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                postMessage(Message.obtain(null, DELETE_ORIGIN,
263d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                    new Origin(origin)));
264d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon            }
265d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon        }
266d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon    }
267d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon
268d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon    @Override
269d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon    public void deleteAllData() {
270d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon        if (WebViewCore.THREAD_NAME.equals(Thread.currentThread().getName())) {
271d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon            nativeDeleteAllData();
272d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon        } else {
273d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon            postMessage(Message.obtain(null, DELETE_ALL));
274d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon        }
275d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon    }
276d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon
277d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon    /**
278d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon     * Sets the maximum size of the ApplicationCache.
279d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon     * This should only ever be called on the WebKit thread.
280d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon     * Not part of the base-class API: this is only used by dump render tree.
281d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon     */
282d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon    public void setAppCacheMaximumSize(long size) {
283d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon        nativeSetAppCacheMaximumSize(size);
284d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon    }
285d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon
286d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon    /**
287d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon     * Utility function to send a message to our handler
288d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon     */
289d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon    private synchronized void postMessage(Message msg) {
290d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon        if (mHandler != null) {
291d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon            mHandler.sendMessage(msg);
292d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon        }
293d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon    }
294d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon
295d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon    /**
296d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon     * Utility function to send a message to the handler on the UI thread
297d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon     */
298d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon    private void postUIMessage(Message msg) {
299d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon        if (mUIHandler != null) {
300d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon            mUIHandler.sendMessage(msg);
301d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon        }
302d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon    }
303d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon
304d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon    /**
305d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon     * Get the singleton instance of this class.
306d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon     * @return The singleton {@link WebStorage} instance.
307d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon     */
308d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon    public static WebStorageClassic getInstance() {
309d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon      if (sWebStorage == null) {
310d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon          sWebStorage = new WebStorageClassic();
311d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon      }
312d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon      return sWebStorage;
313d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon    }
314d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon
315d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon    /**
316d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon     * @hide
317d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon     * Post a Sync request
318d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon     */
319d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon    public void update() {
320d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon        if (WebViewCore.THREAD_NAME.equals(Thread.currentThread().getName())) {
321d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon            syncValues();
322d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon        } else {
323d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon            postMessage(Message.obtain(null, UPDATE));
324d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon        }
325d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon    }
326d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon
327d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon    /**
328d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon     * Run on the WebCore thread
329d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon     * set the local values with the current ones
330d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon     */
331d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon    private void syncValues() {
332d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon        Set<String> tmp = nativeGetOrigins();
333d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon        mOrigins = new HashMap<String, Origin>();
334d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon        for (String origin : tmp) {
335d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon            Origin website = new Origin(origin,
336d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                                 nativeGetQuotaForOrigin(origin),
337d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon                                 nativeGetUsageForOrigin(origin));
338d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon            mOrigins.put(origin, website);
339d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon        }
340d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon    }
341d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon
342d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon    WebStorageClassic() {}
343d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon
344d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon    // Native functions
345d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon    private static native Set nativeGetOrigins();
346d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon    private static native long nativeGetUsageForOrigin(String origin);
347d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon    private static native long nativeGetQuotaForOrigin(String origin);
348d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon    private static native void nativeSetQuotaForOrigin(String origin, long quota);
349d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon    private static native void nativeDeleteOrigin(String origin);
350d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon    private static native void nativeDeleteAllData();
351d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon    private static native void nativeSetAppCacheMaximumSize(long size);
352d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon}
353