Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(455)

Side by Side Diff: android_webview/native/aw_quota_manager_bridge.cc

Issue 12253057: Implement WebStorage API methods (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Implementation mostly done. Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "android_webview/native/aw_quota_manager_bridge.h"
6
7 #include "android_webview/browser/aw_browser_context.h"
8 #include "android_webview/browser/aw_content_browser_client.h"
9 #include "base/android/jni_array.h"
10 #include "base/android/jni_string.h"
11 #include "content/public/browser/browser_thread.h"
12 #include "content/public/browser/storage_partition.h"
13 #include "content/public/common/content_client.h"
14 #include "googleurl/src/gurl.h"
15 #include "jni/AwQuotaManagerBridge_jni.h"
16 #include "webkit/quota/quota_manager.h"
17
18 using base::android::AttachCurrentThread;
19 using base::WeakPtr;
20 using content::BrowserThread;
21 using content::StoragePartition;
22 using quota::QuotaManager;
23
24 namespace android_webview {
25
26 namespace {
27
28 void IgnoreStatus(quota::QuotaStatusCode status_code) {}
29
30 class GetOriginsIOThreadSwitcher
mkosiba (inactive) 2013/02/19 11:37:13 this seems more like an OriginsUsageAndQuotaGetter
boliu 2013/02/20 00:53:50 Renamed to GetOriginsTask.
31 : public base::RefCountedThreadSafe<GetOriginsIOThreadSwitcher> {
32 public:
33 GetOriginsIOThreadSwitcher(
34 const base::WeakPtr<AwQuotaManagerBridge>& bridge,
mkosiba (inactive) 2013/02/19 11:37:13 IMO this dude should take a on_results_obtained ba
boliu 2013/02/20 00:53:50 Did the bind jcallbakc_id into Callback thing.
35 int jcallback_id);
36
37 void GetOriginsOnIOThread();
mkosiba (inactive) 2013/02/19 11:37:13 this should be an internal detail.
boliu 2013/02/20 00:53:50 Renamed this to Run.
38
39 private:
40 friend class base::RefCountedThreadSafe<GetOriginsIOThreadSwitcher>;
41 ~GetOriginsIOThreadSwitcher();
42
43 void GetOriginsCallback(const std::set<GURL>& origins,
44 quota::StorageType type);
45
46 void AddToData(const GURL& origin,
47 quota::QuotaStatusCode status_code,
48 int64 usage,
49 int64 quota);
50
51 void CheckDone();
52 void DoneOnUIThread();
53
54 base::WeakPtr<AwQuotaManagerBridge> bridge_;
55 int jcallback_id_;
56 quota::QuotaManager* quota_manager_;
57 std::vector<std::string> origin_;
58 std::vector<int64> quota_;
59 std::vector<int64> usage_;
60
61 size_t num_callbacks_to_wait_;
62 size_t num_callbacks_received_;
63
64 DISALLOW_COPY_AND_ASSIGN(GetOriginsIOThreadSwitcher);
65 };
66
67 GetOriginsIOThreadSwitcher::GetOriginsIOThreadSwitcher(
68 const base::WeakPtr<AwQuotaManagerBridge>& bridge,
69 int jcallback_id)
70 : bridge_(bridge),
71 jcallback_id_(jcallback_id),
72 quota_manager_(bridge->GetQuotaManager()) {
73 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
74 AddRef(); // Matched in DoneOnUIThread.
mkosiba (inactive) 2013/02/19 11:37:13 this calls for the "The more you know" meme, but d
boliu 2013/02/19 17:03:21 I knew that...I just have to convince myself this
boliu 2013/02/20 00:53:50 I'm convinced. Done :)
75 }
76
77 void GetOriginsIOThreadSwitcher::GetOriginsOnIOThread() {
78 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
79 quota_manager_->GetOriginsModifiedSince(
80 quota::kStorageTypeTemporary,
81 base::Time() /* Since beginning of time. */,
82 base::Bind(&GetOriginsIOThreadSwitcher::GetOriginsCallback,
mkosiba (inactive) 2013/02/19 11:37:13 nit: OnOriginsObtained ?
boliu 2013/02/20 00:53:50 Done.
83 this));
84 }
85
86 void GetOriginsIOThreadSwitcher::GetOriginsCallback(
87 const std::set<GURL>& origins, quota::StorageType type) {
88 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
89 num_callbacks_to_wait_ = origins.size();
90 num_callbacks_received_ = 0u;
91
92 for (std::set<GURL>::const_iterator origin = origins.begin();
93 origin != origins.end();
94 ++origin) {
95 quota_manager_->GetUsageAndQuota(
96 *origin,
97 type,
98 base::Bind(&GetOriginsIOThreadSwitcher::AddToData,
mkosiba (inactive) 2013/02/19 11:37:13 OnUsageAndQuotaObtained?
boliu 2013/02/20 00:53:50 Done.
99 this,
100 *origin));
101 }
102
103 CheckDone();
104 }
105
106 void GetOriginsIOThreadSwitcher::AddToData(const GURL& origin,
107 quota::QuotaStatusCode status_code,
108 int64 usage,
109 int64 quota) {
110 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
111 if (status_code == quota::kQuotaStatusOk) {
112 origin_.push_back(origin.spec());
113 quota_.push_back(quota);
114 usage_.push_back(usage);
115 }
116
117 ++num_callbacks_received_;
118 CheckDone();
119 }
120
121 void GetOriginsIOThreadSwitcher::CheckDone() {
122 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
123 if (num_callbacks_received_ == num_callbacks_to_wait_) {
124 BrowserThread::PostTask(
125 BrowserThread::UI,
126 FROM_HERE,
127 base::Bind(
128 &GetOriginsIOThreadSwitcher::DoneOnUIThread,
129 this));
130 } else if (num_callbacks_received_ > num_callbacks_to_wait_) {
131 NOTREACHED();
132 }
133 }
134
135 void GetOriginsIOThreadSwitcher::DoneOnUIThread() {
136 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
137 if (bridge_)
138 bridge_->GetOriginsCallback(jcallback_id_, origin_, quota_, usage_);
139 Release(); // Matched by constructor.
140 }
141
142 GetOriginsIOThreadSwitcher::~GetOriginsIOThreadSwitcher() {}
143
144 } // namespace
145
146 namespace internal {
147
148 IOThreadSwitcher::IOThreadSwitcher(const WeakPtr<AwQuotaManagerBridge>& bridge)
149 : bridge_(bridge),
150 quota_manager_(bridge->GetQuotaManager()) {
151 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
152 }
153
154 IOThreadSwitcher::~IOThreadSwitcher() {}
155
156 void IOThreadSwitcher::DeleteAllDataOnIOThread() {
mkosiba (inactive) 2013/02/19 11:37:13 DeleteAllOriginData...?
157 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
158 quota_manager_->GetOriginsModifiedSince(
159 quota::kStorageTypeTemporary,
160 base::Time() /* Since beginning of time. */,
161 base::Bind(&IOThreadSwitcher::DeleteOrigins, this));
162 }
163
164 void IOThreadSwitcher::DeleteOriginOnIOThread(const GURL& origin) {
mkosiba (inactive) 2013/02/19 11:37:13 DeleteOriginData... ?
165 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
166 quota_manager_->DeleteOriginData(
167 origin,
168 quota::kStorageTypeTemporary /* ignored due to mask below */,
169 quota::QuotaClient::kAllClientsMask,
170 base::Bind(&IgnoreStatus));
171 }
172
173 void IOThreadSwitcher::GetQuotaForOriginOnIOThread(
174 const GURL& origin, int jcallback_id) {
175 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
176 quota_manager_->GetUsageAndQuota(
177 origin,
178 quota::kStorageTypeTemporary,
179 base::Bind(&IOThreadSwitcher::GetQuotaForOriginCallback,
mkosiba (inactive) 2013/02/19 11:37:13 OnQuotaObtained?
180 this,
181 jcallback_id));
182 }
183
184 void IOThreadSwitcher::GetUsageForOriginOnIOThread(
185 const GURL& origin, int jcallback_id) {
186 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
187 quota_manager_->GetUsageAndQuota(
188 origin,
189 quota::kStorageTypeTemporary,
190 base::Bind(&IOThreadSwitcher::GetUsageForOriginCallback,
mkosiba (inactive) 2013/02/19 11:37:13 OnUsageObtained?
191 this,
192 jcallback_id));
193 }
194
195 void IOThreadSwitcher::DeleteOrigins(
mkosiba (inactive) 2013/02/19 11:37:13 DeleteOriginDataOnIOThread ?
196 const std::set<GURL>& origins, quota::StorageType type) {
197 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
198 // TODO(boliu): Maybe not spam the db thread?
199 for (std::set<GURL>::const_iterator origin = origins.begin();
200 origin != origins.end();
201 ++origin) {
202 quota_manager_->DeleteOriginData(*origin,
203 type,
204 quota::QuotaClient::kAllClientsMask,
205 base::Bind(&IgnoreStatus));
206 }
207 }
208
209 void IOThreadSwitcher::GetQuotaForOriginCallback(
210 int jcallback_id,
211 quota::QuotaStatusCode status_code,
212 int64 usage,
213 int64 quota) {
214 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
215 if (status_code != quota::kQuotaStatusOk) {
216 // Indicate error. TODO(boliu): Check this does not mean infinite.
217 quota = -1;
218 }
219 BrowserThread::PostTask(
220 BrowserThread::UI,
221 FROM_HERE,
222 base::Bind(
223 &internal::IOThreadSwitcher::GetQuotaForOriginCallbackOnUiThread,
224 this,
225 jcallback_id,
226 quota));
227 }
228
229 void IOThreadSwitcher::GetUsageForOriginCallback(
mkosiba (inactive) 2013/02/19 11:37:13 seems like you might be better off to have one pat
boliu 2013/02/20 00:53:50 Done.
230 int jcallback_id,
231 quota::QuotaStatusCode status_code,
232 int64 usage,
233 int64 quota) {
234 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
235 if (status_code != quota::kQuotaStatusOk) {
236 // Indicate error. TODO(boliu): Check this does not mean infinite.
237 usage = -1;
238 }
239 BrowserThread::PostTask(
240 BrowserThread::UI,
241 FROM_HERE,
242 base::Bind(
243 &internal::IOThreadSwitcher::GetUsageForOriginCallbackOnUiThread,
244 this,
245 jcallback_id,
246 quota));
mkosiba (inactive) 2013/02/19 11:37:13 s/usage/quota/ see? you really do need to merge t
boliu 2013/02/20 00:53:50 Since both are int64, so it's still easy to mess t
247 }
248
249 void IOThreadSwitcher::GetQuotaForOriginCallbackOnUiThread(
250 int jcallback_id, int64 quota) {
251 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
252 if (bridge_)
253 bridge_->GetQuotaForOriginCallback(jcallback_id, quota);
254 }
255
256 void IOThreadSwitcher::GetUsageForOriginCallbackOnUiThread(
257 int jcallback_id, int64 usage) {
258 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
259 if (bridge_)
260 bridge_->GetUsageForOriginCallback(jcallback_id, usage);
261 }
262
263 } // namespace internal
264
265 // static
266 jint GetDefaultNativeAwQuotaManagerBridge(JNIEnv* env, jclass clazz) {
267 content::ContentBrowserClient* cbc = content::GetContentClient()->browser();
mkosiba (inactive) 2013/02/19 11:37:13 uh.. maybe just browserClient?
boliu 2013/02/20 00:53:50 Done.
268 DCHECK(cbc);
269
270 AwContentBrowserClient* acbc =
mkosiba (inactive) 2013/02/19 11:37:13 awBrowserClient?
boliu 2013/02/20 00:53:50 Done.
271 AwContentBrowserClient::FromContentBrowserClient(cbc);
272 AwBrowserContext* browser_context = acbc->GetAwBrowserContext();
273 DCHECK(browser_context);
274
275 AwQuotaManagerBridge* bridge = browser_context->GetQuotaManagerBridge();
276 DCHECK(bridge);
277 return reinterpret_cast<jint>(bridge);
278 }
279
280 // static
281 AwQuotaManagerBridge* AwQuotaManagerBridge::Create(
282 AwBrowserContext* browser_context) {
283 return new AwQuotaManagerBridge(browser_context);
284 }
285
286 AwQuotaManagerBridge::AwQuotaManagerBridge(AwBrowserContext* browser_context)
287 : browser_context_(browser_context),
288 io_thread_switcher_(new internal::IOThreadSwitcher(AsWeakPtr())) {
289 }
290
291 void AwQuotaManagerBridge::Init(JNIEnv* env, jobject object) {
292 java_ref_ = JavaObjectWeakGlobalRef(env, object);
293 }
294
295 QuotaManager* AwQuotaManagerBridge::GetQuotaManager() const {
296 // AndroidWebview does not use per-site storage partitions.
297 // TODO(boliu): Get @ajwong to review this before submit.
298 StoragePartition* storage_partition =
299 content::BrowserContext::GetStoragePartitionForSite(
300 browser_context_, GURL());
301 DCHECK(storage_partition);
302
303 QuotaManager* quota_manager = storage_partition->GetQuotaManager();
304 DCHECK(quota_manager);
305 return quota_manager;
306 }
307
308 void AwQuotaManagerBridge::DeleteAllData(JNIEnv* env, jobject object) {
309 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
310 BrowserThread::PostTask(
mkosiba (inactive) 2013/02/19 11:37:13 IMO this means that the encapsulation provided by
boliu 2013/02/20 00:53:50 The old IOThreadSwitcher was never meant to encaps
311 BrowserThread::IO,
312 FROM_HERE,
313 base::Bind(&internal::IOThreadSwitcher::DeleteAllDataOnIOThread,
314 io_thread_switcher_.get()));
315 }
316
317 void AwQuotaManagerBridge::DeleteOrigin(
318 JNIEnv* env, jobject object, jstring origin) {
319 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
320 BrowserThread::PostTask(
321 BrowserThread::IO,
322 FROM_HERE,
323 base::Bind(&internal::IOThreadSwitcher::DeleteOriginOnIOThread,
324 io_thread_switcher_.get(),
325 GURL(base::android::ConvertJavaStringToUTF16(env, origin))));
326 }
327
328 void AwQuotaManagerBridge::GetOrigins(
329 JNIEnv* env, jobject object, jint callback_id) {
330 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
331 BrowserThread::PostTask(
332 BrowserThread::IO,
333 FROM_HERE,
334 base::Bind(&GetOriginsIOThreadSwitcher::GetOriginsOnIOThread,
335 new GetOriginsIOThreadSwitcher(AsWeakPtr(), callback_id)));
336 }
337
338 void AwQuotaManagerBridge::GetQuotaForOrigin(
339 JNIEnv* env, jobject object, jstring origin, jint callback_id) {
340 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
341 BrowserThread::PostTask(
342 BrowserThread::IO,
343 FROM_HERE,
344 base::Bind(&internal::IOThreadSwitcher::GetQuotaForOriginOnIOThread,
345 io_thread_switcher_.get(),
346 GURL(base::android::ConvertJavaStringToUTF16(env, origin)),
347 callback_id));
348 }
349
350 void AwQuotaManagerBridge::GetUsageForOrigin(
351 JNIEnv* env, jobject object, jstring origin, jint callback_id) {
352 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
353 BrowserThread::PostTask(
354 BrowserThread::IO,
355 FROM_HERE,
356 base::Bind(&internal::IOThreadSwitcher::GetUsageForOriginOnIOThread,
357 io_thread_switcher_.get(),
358 GURL(base::android::ConvertJavaStringToUTF16(env, origin)),
359 callback_id));
360 }
361
362 void AwQuotaManagerBridge::GetOriginsCallback(
363 int jcallback_id,
364 const std::vector<std::string>& origin,
365 const std::vector<int64>& quota,
366 const std::vector<int64>& usage) {
367 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
368 JNIEnv* env = AttachCurrentThread();
369 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
370 if (obj.is_null())
371 return;
372
373 Java_AwQuotaManagerBridge_onGetOriginsCallback(
374 env,
375 obj.obj(),
376 jcallback_id,
377 base::android::ToJavaArrayOfStrings(env, origin).obj(),
378 base::android::ToJavaLongArray(env, quota.begin(), quota.size()).obj(),
379 base::android::ToJavaLongArray(env, usage.begin(), usage.size()).obj());
380 }
381
382 void AwQuotaManagerBridge::GetQuotaForOriginCallback(
383 int jcallback_id, int64 quota) {
384 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
385 JNIEnv* env = AttachCurrentThread();
386 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
387 if (obj.is_null())
388 return;
389
390 android_webview::Java_AwQuotaManagerBridge_onGetQuotaForOriginCallback(
391 AttachCurrentThread(),
392 obj.obj(),
393 jcallback_id,
394 quota);
395
396 }
397
398 void AwQuotaManagerBridge::GetUsageForOriginCallback(
399 int jcallback_id, int64 usage) {
400 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
401 JNIEnv* env = AttachCurrentThread();
402 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
403 if (obj.is_null())
404 return;
405
406 android_webview::Java_AwQuotaManagerBridge_onGetUsageForOriginCallback(
407 AttachCurrentThread(),
408 obj.obj(),
409 jcallback_id,
410 usage);
411 }
412
413 bool RegisterAwQuotaManagerBridge(JNIEnv* env) {
414 return RegisterNativesImpl(env) >= 0;
415 }
416
417 } // namespace android_webview
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698