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"
18 #include "storage/browser/quota/quota_manager.h"
19 #include "storage/common/quota/quota_types.h"
22 using base::android::AttachCurrentThread
;
23 using content::BrowserThread
;
24 using content::StoragePartition
;
25 using storage::QuotaClient
;
26 using storage::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 storage::StorageType type
);
51 void OnUsageAndQuotaObtained(const GURL
& origin
,
52 storage::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_CURRENTLY_ON(BrowserThread::UI
);
80 GetOriginsTask::~GetOriginsTask() {}
82 void GetOriginsTask::Run() {
83 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
84 BrowserThread::PostTask(
87 base::Bind(&QuotaManager::GetOriginsModifiedSince
,
89 storage::kStorageTypeTemporary
,
90 base::Time() /* Since beginning of time. */,
91 base::Bind(&GetOriginsTask::OnOriginsObtained
, this)));
94 void GetOriginsTask::OnOriginsObtained(const std::set
<GURL
>& origins
,
95 storage::StorageType type
) {
96 DCHECK_CURRENTLY_ON(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(
114 storage::QuotaStatusCode status_code
,
117 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
118 if (status_code
== storage::kQuotaStatusOk
) {
119 origin_
.push_back(origin
.spec());
120 usage_
.push_back(usage
);
121 quota_
.push_back(quota
);
124 ++num_callbacks_received_
;
128 void GetOriginsTask::CheckDone() {
129 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
130 if (num_callbacks_received_
== num_callbacks_to_wait_
) {
131 BrowserThread::PostTask(
134 base::Bind(&GetOriginsTask::DoneOnUIThread
, this));
135 } else if (num_callbacks_received_
> num_callbacks_to_wait_
) {
140 // This method is to avoid copying the 3 vector arguments into a bound callback.
141 void GetOriginsTask::DoneOnUIThread() {
142 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
143 ui_callback_
.Run(origin_
, usage_
, quota_
);
146 void RunOnUIThread(const base::Closure
& task
) {
147 if (BrowserThread::CurrentlyOn(BrowserThread::UI
)) {
150 BrowserThread::PostTask(BrowserThread::UI
, FROM_HERE
, task
);
158 jlong
GetDefaultNativeAwQuotaManagerBridge(JNIEnv
* env
,
159 const JavaParamRef
<jclass
>& clazz
) {
160 AwBrowserContext
* browser_context
=
161 AwContentBrowserClient::GetAwBrowserContext();
163 AwQuotaManagerBridgeImpl
* bridge
= static_cast<AwQuotaManagerBridgeImpl
*>(
164 browser_context
->GetQuotaManagerBridge());
166 return reinterpret_cast<intptr_t>(bridge
);
170 scoped_refptr
<AwQuotaManagerBridge
> AwQuotaManagerBridgeImpl::Create(
171 AwBrowserContext
* browser_context
) {
172 return new AwQuotaManagerBridgeImpl(browser_context
);
175 AwQuotaManagerBridgeImpl::AwQuotaManagerBridgeImpl(
176 AwBrowserContext
* browser_context
)
177 : browser_context_(browser_context
),
178 weak_factory_(this) {
181 AwQuotaManagerBridgeImpl::~AwQuotaManagerBridgeImpl() {}
183 void AwQuotaManagerBridgeImpl::Init(JNIEnv
* env
, jobject object
) {
184 java_ref_
= JavaObjectWeakGlobalRef(env
, object
);
187 StoragePartition
* AwQuotaManagerBridgeImpl::GetStoragePartition() const {
188 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
190 // AndroidWebview does not use per-site storage partitions.
191 StoragePartition
* storage_partition
=
192 content::BrowserContext::GetDefaultStoragePartition(browser_context_
);
193 DCHECK(storage_partition
);
194 return storage_partition
;
197 QuotaManager
* AwQuotaManagerBridgeImpl::GetQuotaManager() const {
198 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
200 QuotaManager
* quota_manager
= GetStoragePartition()->GetQuotaManager();
201 DCHECK(quota_manager
);
202 return quota_manager
;
205 void AwQuotaManagerBridgeImpl::DeleteAllData(JNIEnv
* env
, jobject object
) {
206 RunOnUIThread(base::Bind(&AwQuotaManagerBridgeImpl::DeleteAllDataOnUiThread
,
210 void AwQuotaManagerBridgeImpl::DeleteAllDataOnUiThread() {
211 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
212 GetStoragePartition()->ClearData(
213 // Clear all web storage data except cookies.
214 StoragePartition::REMOVE_DATA_MASK_APPCACHE
|
215 StoragePartition::REMOVE_DATA_MASK_FILE_SYSTEMS
|
216 StoragePartition::REMOVE_DATA_MASK_INDEXEDDB
|
217 StoragePartition::REMOVE_DATA_MASK_LOCAL_STORAGE
|
218 StoragePartition::REMOVE_DATA_MASK_WEBSQL
,
219 StoragePartition::QUOTA_MANAGED_STORAGE_MASK_TEMPORARY
,
220 GURL(), StoragePartition::OriginMatcherFunction(),
221 base::Time(), base::Time::Max(), base::Bind(&base::DoNothing
));
224 void AwQuotaManagerBridgeImpl::DeleteOrigin(
225 JNIEnv
* env
, jobject object
, jstring origin
) {
226 base::string16
origin_string(
227 base::android::ConvertJavaStringToUTF16(env
, origin
));
228 RunOnUIThread(base::Bind(&AwQuotaManagerBridgeImpl::DeleteOriginOnUiThread
,
233 void AwQuotaManagerBridgeImpl::DeleteOriginOnUiThread(
234 const base::string16
& origin
) {
235 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
236 StoragePartition
* storage_partition
= GetStoragePartition();
237 storage_partition
->ClearDataForOrigin(
238 // All (temporary) QuotaClient types.
239 StoragePartition::REMOVE_DATA_MASK_APPCACHE
|
240 StoragePartition::REMOVE_DATA_MASK_FILE_SYSTEMS
|
241 StoragePartition::REMOVE_DATA_MASK_INDEXEDDB
|
242 StoragePartition::REMOVE_DATA_MASK_WEBSQL
,
243 StoragePartition::QUOTA_MANAGED_STORAGE_MASK_TEMPORARY
,
245 storage_partition
->GetURLRequestContext(),
246 base::Bind(&base::DoNothing
));
249 void AwQuotaManagerBridgeImpl::GetOrigins(
250 JNIEnv
* env
, jobject object
, jint callback_id
) {
251 RunOnUIThread(base::Bind(&AwQuotaManagerBridgeImpl::GetOriginsOnUiThread
,
256 void AwQuotaManagerBridgeImpl::GetOriginsOnUiThread(jint callback_id
) {
257 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
259 const GetOriginsCallback ui_callback
= base::Bind(
260 &AwQuotaManagerBridgeImpl::GetOriginsCallbackImpl
,
261 weak_factory_
.GetWeakPtr(),
264 (new GetOriginsTask(ui_callback
, GetQuotaManager()))->Run();
267 void AwQuotaManagerBridgeImpl::GetOriginsCallbackImpl(
269 const std::vector
<std::string
>& origin
,
270 const std::vector
<int64
>& usage
,
271 const std::vector
<int64
>& quota
) {
272 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
273 JNIEnv
* env
= AttachCurrentThread();
274 ScopedJavaLocalRef
<jobject
> obj
= java_ref_
.get(env
);
278 Java_AwQuotaManagerBridge_onGetOriginsCallback(
282 base::android::ToJavaArrayOfStrings(env
, origin
).obj(),
283 base::android::ToJavaLongArray(env
, usage
).obj(),
284 base::android::ToJavaLongArray(env
, quota
).obj());
289 void OnUsageAndQuotaObtained(
290 const AwQuotaManagerBridgeImpl::QuotaUsageCallback
& ui_callback
,
291 storage::QuotaStatusCode status_code
,
294 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
295 if (status_code
!= storage::kQuotaStatusOk
) {
299 BrowserThread::PostTask(
302 base::Bind(ui_callback
, usage
, quota
));
307 void AwQuotaManagerBridgeImpl::GetUsageAndQuotaForOrigin(
308 JNIEnv
* env
, jobject object
,
312 base::string16
origin_string(
313 base::android::ConvertJavaStringToUTF16(env
, origin
));
314 RunOnUIThread(base::Bind(
315 &AwQuotaManagerBridgeImpl::GetUsageAndQuotaForOriginOnUiThread
,
322 void AwQuotaManagerBridgeImpl::GetUsageAndQuotaForOriginOnUiThread(
323 const base::string16
& origin
,
326 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
327 const QuotaUsageCallback ui_callback
= base::Bind(
328 &AwQuotaManagerBridgeImpl::QuotaUsageCallbackImpl
,
329 weak_factory_
.GetWeakPtr(),
333 BrowserThread::PostTask(
336 base::Bind(&QuotaManager::GetUsageAndQuota
,
339 storage::kStorageTypeTemporary
,
340 base::Bind(&OnUsageAndQuotaObtained
, ui_callback
)));
343 void AwQuotaManagerBridgeImpl::QuotaUsageCallbackImpl(
344 int jcallback_id
, bool is_quota
, int64 usage
, int64 quota
) {
345 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
346 JNIEnv
* env
= AttachCurrentThread();
347 ScopedJavaLocalRef
<jobject
> obj
= java_ref_
.get(env
);
351 Java_AwQuotaManagerBridge_onGetUsageAndQuotaForOriginCallback(
352 env
, obj
.obj(), jcallback_id
, is_quota
, usage
, quota
);
355 bool RegisterAwQuotaManagerBridge(JNIEnv
* env
) {
356 return RegisterNativesImpl(env
);
359 } // namespace android_webview