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
, jclass clazz
) {
159 AwBrowserContext
* browser_context
=
160 AwContentBrowserClient::GetAwBrowserContext();
162 AwQuotaManagerBridgeImpl
* bridge
= static_cast<AwQuotaManagerBridgeImpl
*>(
163 browser_context
->GetQuotaManagerBridge());
165 return reinterpret_cast<intptr_t>(bridge
);
169 scoped_refptr
<AwQuotaManagerBridge
> AwQuotaManagerBridgeImpl::Create(
170 AwBrowserContext
* browser_context
) {
171 return new AwQuotaManagerBridgeImpl(browser_context
);
174 AwQuotaManagerBridgeImpl::AwQuotaManagerBridgeImpl(
175 AwBrowserContext
* browser_context
)
176 : browser_context_(browser_context
),
177 weak_factory_(this) {
180 AwQuotaManagerBridgeImpl::~AwQuotaManagerBridgeImpl() {}
182 void AwQuotaManagerBridgeImpl::Init(JNIEnv
* env
, jobject object
) {
183 java_ref_
= JavaObjectWeakGlobalRef(env
, object
);
186 StoragePartition
* AwQuotaManagerBridgeImpl::GetStoragePartition() const {
187 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
189 // AndroidWebview does not use per-site storage partitions.
190 StoragePartition
* storage_partition
=
191 content::BrowserContext::GetDefaultStoragePartition(browser_context_
);
192 DCHECK(storage_partition
);
193 return storage_partition
;
196 QuotaManager
* AwQuotaManagerBridgeImpl::GetQuotaManager() const {
197 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
199 QuotaManager
* quota_manager
= GetStoragePartition()->GetQuotaManager();
200 DCHECK(quota_manager
);
201 return quota_manager
;
204 void AwQuotaManagerBridgeImpl::DeleteAllData(JNIEnv
* env
, jobject object
) {
205 RunOnUIThread(base::Bind(&AwQuotaManagerBridgeImpl::DeleteAllDataOnUiThread
,
209 void AwQuotaManagerBridgeImpl::DeleteAllDataOnUiThread() {
210 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
211 GetStoragePartition()->ClearData(
212 // Clear all web storage data except cookies.
213 StoragePartition::REMOVE_DATA_MASK_APPCACHE
|
214 StoragePartition::REMOVE_DATA_MASK_FILE_SYSTEMS
|
215 StoragePartition::REMOVE_DATA_MASK_INDEXEDDB
|
216 StoragePartition::REMOVE_DATA_MASK_LOCAL_STORAGE
|
217 StoragePartition::REMOVE_DATA_MASK_WEBSQL
,
218 StoragePartition::QUOTA_MANAGED_STORAGE_MASK_TEMPORARY
,
219 GURL(), StoragePartition::OriginMatcherFunction(),
220 base::Time(), base::Time::Max(), base::Bind(&base::DoNothing
));
223 void AwQuotaManagerBridgeImpl::DeleteOrigin(
224 JNIEnv
* env
, jobject object
, jstring origin
) {
225 base::string16
origin_string(
226 base::android::ConvertJavaStringToUTF16(env
, origin
));
227 RunOnUIThread(base::Bind(&AwQuotaManagerBridgeImpl::DeleteOriginOnUiThread
,
232 void AwQuotaManagerBridgeImpl::DeleteOriginOnUiThread(
233 const base::string16
& origin
) {
234 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
235 StoragePartition
* storage_partition
= GetStoragePartition();
236 storage_partition
->ClearDataForOrigin(
237 // All (temporary) QuotaClient types.
238 StoragePartition::REMOVE_DATA_MASK_APPCACHE
|
239 StoragePartition::REMOVE_DATA_MASK_FILE_SYSTEMS
|
240 StoragePartition::REMOVE_DATA_MASK_INDEXEDDB
|
241 StoragePartition::REMOVE_DATA_MASK_WEBSQL
,
242 StoragePartition::QUOTA_MANAGED_STORAGE_MASK_TEMPORARY
,
244 storage_partition
->GetURLRequestContext(),
245 base::Bind(&base::DoNothing
));
248 void AwQuotaManagerBridgeImpl::GetOrigins(
249 JNIEnv
* env
, jobject object
, jint callback_id
) {
250 RunOnUIThread(base::Bind(&AwQuotaManagerBridgeImpl::GetOriginsOnUiThread
,
255 void AwQuotaManagerBridgeImpl::GetOriginsOnUiThread(jint callback_id
) {
256 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
258 const GetOriginsCallback ui_callback
= base::Bind(
259 &AwQuotaManagerBridgeImpl::GetOriginsCallbackImpl
,
260 weak_factory_
.GetWeakPtr(),
263 (new GetOriginsTask(ui_callback
, GetQuotaManager()))->Run();
266 void AwQuotaManagerBridgeImpl::GetOriginsCallbackImpl(
268 const std::vector
<std::string
>& origin
,
269 const std::vector
<int64
>& usage
,
270 const std::vector
<int64
>& quota
) {
271 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
272 JNIEnv
* env
= AttachCurrentThread();
273 ScopedJavaLocalRef
<jobject
> obj
= java_ref_
.get(env
);
277 Java_AwQuotaManagerBridge_onGetOriginsCallback(
281 base::android::ToJavaArrayOfStrings(env
, origin
).obj(),
282 base::android::ToJavaLongArray(env
, usage
).obj(),
283 base::android::ToJavaLongArray(env
, quota
).obj());
288 void OnUsageAndQuotaObtained(
289 const AwQuotaManagerBridgeImpl::QuotaUsageCallback
& ui_callback
,
290 storage::QuotaStatusCode status_code
,
293 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
294 if (status_code
!= storage::kQuotaStatusOk
) {
298 BrowserThread::PostTask(
301 base::Bind(ui_callback
, usage
, quota
));
306 void AwQuotaManagerBridgeImpl::GetUsageAndQuotaForOrigin(
307 JNIEnv
* env
, jobject object
,
311 base::string16
origin_string(
312 base::android::ConvertJavaStringToUTF16(env
, origin
));
313 RunOnUIThread(base::Bind(
314 &AwQuotaManagerBridgeImpl::GetUsageAndQuotaForOriginOnUiThread
,
321 void AwQuotaManagerBridgeImpl::GetUsageAndQuotaForOriginOnUiThread(
322 const base::string16
& origin
,
325 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
326 const QuotaUsageCallback ui_callback
= base::Bind(
327 &AwQuotaManagerBridgeImpl::QuotaUsageCallbackImpl
,
328 weak_factory_
.GetWeakPtr(),
332 BrowserThread::PostTask(
335 base::Bind(&QuotaManager::GetUsageAndQuota
,
338 storage::kStorageTypeTemporary
,
339 base::Bind(&OnUsageAndQuotaObtained
, ui_callback
)));
342 void AwQuotaManagerBridgeImpl::QuotaUsageCallbackImpl(
343 int jcallback_id
, bool is_quota
, int64 usage
, int64 quota
) {
344 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
345 JNIEnv
* env
= AttachCurrentThread();
346 ScopedJavaLocalRef
<jobject
> obj
= java_ref_
.get(env
);
350 Java_AwQuotaManagerBridge_onGetUsageAndQuotaForOriginCallback(
351 env
, obj
.obj(), jcallback_id
, is_quota
, usage
, quota
);
354 bool RegisterAwQuotaManagerBridge(JNIEnv
* env
) {
355 return RegisterNativesImpl(env
);
358 } // namespace android_webview