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.
5 #include "android_webview/native/aw_quota_manager_bridge_impl.h"
9 #include "android_webview/browser/aw_browser_context.h"
10 #include "android_webview/browser/aw_content_browser_client.h"
11 #include "base/android/jni_array.h"
12 #include "base/android/jni_string.h"
13 #include "base/synchronization/waitable_event.h"
14 #include "content/public/browser/browser_thread.h"
15 #include "content/public/browser/storage_partition.h"
16 #include "content/public/common/content_client.h"
17 #include "jni/AwQuotaManagerBridge_jni.h"
19 #include "webkit/browser/quota/quota_manager.h"
20 #include "webkit/common/quota/quota_types.h"
22 using base::android::AttachCurrentThread
;
23 using content::BrowserThread
;
24 using content::StoragePartition
;
25 using quota::QuotaClient
;
26 using quota::QuotaManager
;
28 namespace android_webview
{
32 // This object lives on UI and IO threads. Care need to be taken to make sure
33 // there are no concurrent accesses to instance variables. Also this object
34 // is refcounted in the various callbacks, and is destroyed when all callbacks
35 // are destroyed at the end of DoneOnUIThread.
36 class GetOriginsTask
: public base::RefCountedThreadSafe
<GetOriginsTask
> {
39 const AwQuotaManagerBridgeImpl::GetOriginsCallback
& callback
,
40 QuotaManager
* quota_manager
);
45 friend class base::RefCountedThreadSafe
<GetOriginsTask
>;
48 void OnOriginsObtained(const std::set
<GURL
>& origins
,
49 quota::StorageType type
);
51 void OnUsageAndQuotaObtained(const GURL
& origin
,
52 quota::QuotaStatusCode status_code
,
57 void DoneOnUIThread();
59 AwQuotaManagerBridgeImpl::GetOriginsCallback ui_callback_
;
60 scoped_refptr
<QuotaManager
> quota_manager_
;
62 std::vector
<std::string
> origin_
;
63 std::vector
<int64
> usage_
;
64 std::vector
<int64
> quota_
;
66 size_t num_callbacks_to_wait_
;
67 size_t num_callbacks_received_
;
69 DISALLOW_COPY_AND_ASSIGN(GetOriginsTask
);
72 GetOriginsTask::GetOriginsTask(
73 const AwQuotaManagerBridgeImpl::GetOriginsCallback
& callback
,
74 QuotaManager
* quota_manager
)
75 : ui_callback_(callback
),
76 quota_manager_(quota_manager
) {
77 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
80 GetOriginsTask::~GetOriginsTask() {}
82 void GetOriginsTask::Run() {
83 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
84 BrowserThread::PostTask(
87 base::Bind(&QuotaManager::GetOriginsModifiedSince
,
89 quota::kStorageTypeTemporary
,
90 base::Time() /* Since beginning of time. */,
91 base::Bind(&GetOriginsTask::OnOriginsObtained
, this)));
94 void GetOriginsTask::OnOriginsObtained(
95 const std::set
<GURL
>& origins
, quota::StorageType type
) {
96 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
97 num_callbacks_to_wait_
= origins
.size();
98 num_callbacks_received_
= 0u;
100 for (std::set
<GURL
>::const_iterator origin
= origins
.begin();
101 origin
!= origins
.end();
103 quota_manager_
->GetUsageAndQuota(
106 base::Bind(&GetOriginsTask::OnUsageAndQuotaObtained
, this, *origin
));
112 void GetOriginsTask::OnUsageAndQuotaObtained(const GURL
& origin
,
113 quota::QuotaStatusCode status_code
,
116 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
117 if (status_code
== quota::kQuotaStatusOk
) {
118 origin_
.push_back(origin
.spec());
119 usage_
.push_back(usage
);
120 quota_
.push_back(quota
);
123 ++num_callbacks_received_
;
127 void GetOriginsTask::CheckDone() {
128 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
129 if (num_callbacks_received_
== num_callbacks_to_wait_
) {
130 BrowserThread::PostTask(
133 base::Bind(&GetOriginsTask::DoneOnUIThread
, this));
134 } else if (num_callbacks_received_
> num_callbacks_to_wait_
) {
139 // This method is to avoid copying the 3 vector arguments into a bound callback.
140 void GetOriginsTask::DoneOnUIThread() {
141 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
142 ui_callback_
.Run(origin_
, usage_
, quota_
);
145 void RunOnUIThread(const base::Closure
& task
) {
146 if (BrowserThread::CurrentlyOn(BrowserThread::UI
)) {
149 BrowserThread::PostTask(BrowserThread::UI
, FROM_HERE
, task
);
157 jlong
GetDefaultNativeAwQuotaManagerBridge(JNIEnv
* env
, jclass clazz
) {
158 AwBrowserContext
* browser_context
=
159 AwContentBrowserClient::GetAwBrowserContext();
161 AwQuotaManagerBridgeImpl
* bridge
= static_cast<AwQuotaManagerBridgeImpl
*>(
162 browser_context
->GetQuotaManagerBridge());
164 return reinterpret_cast<intptr_t>(bridge
);
168 scoped_refptr
<AwQuotaManagerBridge
> AwQuotaManagerBridgeImpl::Create(
169 AwBrowserContext
* browser_context
) {
170 return new AwQuotaManagerBridgeImpl(browser_context
);
173 AwQuotaManagerBridgeImpl::AwQuotaManagerBridgeImpl(
174 AwBrowserContext
* browser_context
)
175 : weak_factory_(this),
176 browser_context_(browser_context
) {
179 AwQuotaManagerBridgeImpl::~AwQuotaManagerBridgeImpl() {}
181 void AwQuotaManagerBridgeImpl::Init(JNIEnv
* env
, jobject object
) {
182 java_ref_
= JavaObjectWeakGlobalRef(env
, object
);
185 StoragePartition
* AwQuotaManagerBridgeImpl::GetStoragePartition() const {
186 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
188 // AndroidWebview does not use per-site storage partitions.
189 StoragePartition
* storage_partition
=
190 content::BrowserContext::GetDefaultStoragePartition(browser_context_
);
191 DCHECK(storage_partition
);
192 return storage_partition
;
195 QuotaManager
* AwQuotaManagerBridgeImpl::GetQuotaManager() const {
196 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
198 QuotaManager
* quota_manager
= GetStoragePartition()->GetQuotaManager();
199 DCHECK(quota_manager
);
200 return quota_manager
;
203 void AwQuotaManagerBridgeImpl::DeleteAllData(JNIEnv
* env
, jobject object
) {
204 RunOnUIThread(base::Bind(&AwQuotaManagerBridgeImpl::DeleteAllDataOnUiThread
,
208 void AwQuotaManagerBridgeImpl::DeleteAllDataOnUiThread() {
209 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
210 GetStoragePartition()->ClearData(
211 // Clear all web storage data except cookies.
212 StoragePartition::REMOVE_DATA_MASK_APPCACHE
|
213 StoragePartition::REMOVE_DATA_MASK_FILE_SYSTEMS
|
214 StoragePartition::REMOVE_DATA_MASK_INDEXEDDB
|
215 StoragePartition::REMOVE_DATA_MASK_LOCAL_STORAGE
|
216 StoragePartition::REMOVE_DATA_MASK_WEBSQL
,
217 StoragePartition::QUOTA_MANAGED_STORAGE_MASK_TEMPORARY
,
218 GURL(), StoragePartition::OriginMatcherFunction(),
219 base::Time(), base::Time::Max(), base::Bind(&base::DoNothing
));
222 void AwQuotaManagerBridgeImpl::DeleteOrigin(
223 JNIEnv
* env
, jobject object
, jstring origin
) {
224 base::string16
origin_string(
225 base::android::ConvertJavaStringToUTF16(env
, origin
));
226 RunOnUIThread(base::Bind(&AwQuotaManagerBridgeImpl::DeleteOriginOnUiThread
,
231 void AwQuotaManagerBridgeImpl::DeleteOriginOnUiThread(
232 const base::string16
& origin
) {
233 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
234 StoragePartition
* storage_partition
= GetStoragePartition();
235 storage_partition
->ClearDataForOrigin(
236 // All (temporary) QuotaClient types.
237 StoragePartition::REMOVE_DATA_MASK_APPCACHE
|
238 StoragePartition::REMOVE_DATA_MASK_FILE_SYSTEMS
|
239 StoragePartition::REMOVE_DATA_MASK_INDEXEDDB
|
240 StoragePartition::REMOVE_DATA_MASK_WEBSQL
,
241 StoragePartition::QUOTA_MANAGED_STORAGE_MASK_TEMPORARY
,
243 storage_partition
->GetURLRequestContext());
246 void AwQuotaManagerBridgeImpl::GetOrigins(
247 JNIEnv
* env
, jobject object
, jint callback_id
) {
248 RunOnUIThread(base::Bind(&AwQuotaManagerBridgeImpl::GetOriginsOnUiThread
,
253 void AwQuotaManagerBridgeImpl::GetOriginsOnUiThread(jint callback_id
) {
254 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
256 const GetOriginsCallback ui_callback
= base::Bind(
257 &AwQuotaManagerBridgeImpl::GetOriginsCallbackImpl
,
258 weak_factory_
.GetWeakPtr(),
261 (new GetOriginsTask(ui_callback
, GetQuotaManager()))->Run();
264 void AwQuotaManagerBridgeImpl::GetOriginsCallbackImpl(
266 const std::vector
<std::string
>& origin
,
267 const std::vector
<int64
>& usage
,
268 const std::vector
<int64
>& quota
) {
269 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
270 JNIEnv
* env
= AttachCurrentThread();
271 ScopedJavaLocalRef
<jobject
> obj
= java_ref_
.get(env
);
275 Java_AwQuotaManagerBridge_onGetOriginsCallback(
279 base::android::ToJavaArrayOfStrings(env
, origin
).obj(),
280 base::android::ToJavaLongArray(env
, usage
).obj(),
281 base::android::ToJavaLongArray(env
, quota
).obj());
286 void OnUsageAndQuotaObtained(
287 const AwQuotaManagerBridgeImpl::QuotaUsageCallback
& ui_callback
,
288 quota::QuotaStatusCode status_code
,
291 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
292 if (status_code
!= quota::kQuotaStatusOk
) {
296 BrowserThread::PostTask(
299 base::Bind(ui_callback
, usage
, quota
));
304 void AwQuotaManagerBridgeImpl::GetUsageAndQuotaForOrigin(
305 JNIEnv
* env
, jobject object
,
309 base::string16
origin_string(
310 base::android::ConvertJavaStringToUTF16(env
, origin
));
311 RunOnUIThread(base::Bind(
312 &AwQuotaManagerBridgeImpl::GetUsageAndQuotaForOriginOnUiThread
,
319 void AwQuotaManagerBridgeImpl::GetUsageAndQuotaForOriginOnUiThread(
320 const base::string16
& origin
,
323 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
324 const QuotaUsageCallback ui_callback
= base::Bind(
325 &AwQuotaManagerBridgeImpl::QuotaUsageCallbackImpl
,
326 weak_factory_
.GetWeakPtr(),
330 BrowserThread::PostTask(
333 base::Bind(&QuotaManager::GetUsageAndQuota
,
336 quota::kStorageTypeTemporary
,
337 base::Bind(&OnUsageAndQuotaObtained
, ui_callback
)));
340 void AwQuotaManagerBridgeImpl::QuotaUsageCallbackImpl(
341 int jcallback_id
, bool is_quota
, int64 usage
, int64 quota
) {
342 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
343 JNIEnv
* env
= AttachCurrentThread();
344 ScopedJavaLocalRef
<jobject
> obj
= java_ref_
.get(env
);
348 Java_AwQuotaManagerBridge_onGetUsageAndQuotaForOriginCallback(
349 env
, obj
.obj(), jcallback_id
, is_quota
, usage
, quota
);
352 bool RegisterAwQuotaManagerBridge(JNIEnv
* env
) {
353 return RegisterNativesImpl(env
);
356 } // namespace android_webview