123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284 |
- // Copyright (c) 2013 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "android_webview/browser/aw_quota_manager_bridge.h"
- #include <set>
- #include "android_webview/browser/aw_browser_context.h"
- #include "android_webview/browser/aw_content_browser_client.h"
- #include "android_webview/browser_jni_headers/AwQuotaManagerBridge_jni.h"
- #include "base/android/callback_android.h"
- #include "base/android/jni_array.h"
- #include "base/android/jni_string.h"
- #include "base/bind.h"
- #include "base/callback_helpers.h"
- #include "base/memory/scoped_refptr.h"
- #include "base/synchronization/waitable_event.h"
- #include "content/public/browser/browser_task_traits.h"
- #include "content/public/browser/browser_thread.h"
- #include "content/public/browser/storage_partition.h"
- #include "content/public/common/content_client.h"
- #include "storage/browser/quota/quota_manager.h"
- #include "third_party/blink/public/common/storage_key/storage_key.h"
- #include "third_party/blink/public/mojom/quota/quota_types.mojom.h"
- #include "url/gurl.h"
- #include "url/origin.h"
- using base::android::AttachCurrentThread;
- using base::android::JavaParamRef;
- using base::android::JavaRef;
- using base::android::ScopedJavaGlobalRef;
- using content::BrowserThread;
- using content::StoragePartition;
- using storage::QuotaManager;
- namespace android_webview {
- namespace {
- // This object lives on UI and IO threads. Care need to be taken to make sure
- // there are no concurrent accesses to instance variables. Also this object
- // is refcounted in the various callbacks, and is destroyed when all callbacks
- // are destroyed at the end of DoneOnUIThread.
- class GetStorageKeysTask
- : public base::RefCountedThreadSafe<GetStorageKeysTask> {
- public:
- GetStorageKeysTask(AwQuotaManagerBridge::GetOriginsCallback callback,
- QuotaManager* quota_manager);
- GetStorageKeysTask(const GetStorageKeysTask&) = delete;
- GetStorageKeysTask& operator=(const GetStorageKeysTask&) = delete;
- void Run();
- private:
- friend class base::RefCountedThreadSafe<GetStorageKeysTask>;
- ~GetStorageKeysTask();
- void OnStorageKeysObtained(blink::mojom::StorageType type,
- const std::set<blink::StorageKey>& storage_keys);
- void OnUsageAndQuotaObtained(const blink::StorageKey& storage_key,
- blink::mojom::QuotaStatusCode status_code,
- int64_t usage,
- int64_t quota);
- void CheckDone();
- void DoneOnUIThread();
- AwQuotaManagerBridge::GetOriginsCallback ui_callback_;
- scoped_refptr<QuotaManager> quota_manager_;
- std::vector<std::string> origin_;
- std::vector<int64_t> usage_;
- std::vector<int64_t> quota_;
- size_t num_callbacks_to_wait_;
- size_t num_callbacks_received_;
- };
- GetStorageKeysTask::GetStorageKeysTask(
- AwQuotaManagerBridge::GetOriginsCallback callback,
- QuotaManager* quota_manager)
- : ui_callback_(std::move(callback)), quota_manager_(quota_manager) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- }
- GetStorageKeysTask::~GetStorageKeysTask() {}
- void GetStorageKeysTask::Run() {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- content::GetIOThreadTaskRunner({})->PostTask(
- FROM_HERE,
- base::BindOnce(
- &QuotaManager::GetStorageKeysForType, quota_manager_,
- blink::mojom::StorageType::kTemporary,
- base::BindOnce(&GetStorageKeysTask::OnStorageKeysObtained, this,
- blink::mojom::StorageType::kTemporary)));
- }
- void GetStorageKeysTask::OnStorageKeysObtained(
- blink::mojom::StorageType type,
- const std::set<blink::StorageKey>& storage_keys) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- num_callbacks_to_wait_ = storage_keys.size();
- num_callbacks_received_ = 0u;
- for (const blink::StorageKey& storage_key : storage_keys) {
- quota_manager_->GetUsageAndQuota(
- storage_key, type,
- base::BindOnce(&GetStorageKeysTask::OnUsageAndQuotaObtained, this,
- storage_key));
- }
- CheckDone();
- }
- void GetStorageKeysTask::OnUsageAndQuotaObtained(
- const blink::StorageKey& storage_key,
- blink::mojom::QuotaStatusCode status_code,
- int64_t usage,
- int64_t quota) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (status_code == blink::mojom::QuotaStatusCode::kOk) {
- origin_.push_back(storage_key.origin().GetURL().spec());
- usage_.push_back(usage);
- quota_.push_back(quota);
- }
- ++num_callbacks_received_;
- CheckDone();
- }
- void GetStorageKeysTask::CheckDone() {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (num_callbacks_received_ == num_callbacks_to_wait_) {
- content::GetUIThreadTaskRunner({})->PostTask(
- FROM_HERE, base::BindOnce(&GetStorageKeysTask::DoneOnUIThread, this));
- } else if (num_callbacks_received_ > num_callbacks_to_wait_) {
- NOTREACHED();
- }
- }
- // This method is to avoid copying the 3 vector arguments into a bound callback.
- void GetStorageKeysTask::DoneOnUIThread() {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- std::move(ui_callback_).Run(origin_, usage_, quota_);
- }
- } // namespace
- // static
- scoped_refptr<AwQuotaManagerBridge> AwQuotaManagerBridge::Create(
- AwBrowserContext* browser_context) {
- return new AwQuotaManagerBridge(browser_context);
- }
- AwQuotaManagerBridge::AwQuotaManagerBridge(AwBrowserContext* browser_context)
- : browser_context_(browser_context) {}
- AwQuotaManagerBridge::~AwQuotaManagerBridge() {}
- void AwQuotaManagerBridge::Init(JNIEnv* env,
- const JavaParamRef<jobject>& object) {
- java_ref_ = JavaObjectWeakGlobalRef(env, object);
- }
- StoragePartition* AwQuotaManagerBridge::GetStoragePartition() const {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- // AndroidWebview does not use per-site storage partitions.
- StoragePartition* storage_partition =
- browser_context_->GetDefaultStoragePartition();
- DCHECK(storage_partition);
- return storage_partition;
- }
- QuotaManager* AwQuotaManagerBridge::GetQuotaManager() const {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- QuotaManager* quota_manager = GetStoragePartition()->GetQuotaManager();
- DCHECK(quota_manager);
- return quota_manager;
- }
- void AwQuotaManagerBridge::DeleteAllData(JNIEnv* env,
- const JavaParamRef<jobject>& object) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- GetStoragePartition()->ClearData(
- // Clear all web storage data except cookies.
- StoragePartition::REMOVE_DATA_MASK_FILE_SYSTEMS |
- StoragePartition::REMOVE_DATA_MASK_INDEXEDDB |
- StoragePartition::REMOVE_DATA_MASK_LOCAL_STORAGE |
- StoragePartition::REMOVE_DATA_MASK_WEBSQL,
- StoragePartition::QUOTA_MANAGED_STORAGE_MASK_TEMPORARY,
- blink::StorageKey(), base::Time(), base::Time::Max(), base::DoNothing());
- }
- void AwQuotaManagerBridge::DeleteOrigin(JNIEnv* env,
- const JavaParamRef<jobject>& object,
- const JavaParamRef<jstring>& origin) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- std::u16string origin_string(
- base::android::ConvertJavaStringToUTF16(env, origin));
- StoragePartition* storage_partition = GetStoragePartition();
- storage_partition->ClearDataForOrigin(
- // All (temporary) QuotaClient types.
- StoragePartition::REMOVE_DATA_MASK_FILE_SYSTEMS |
- StoragePartition::REMOVE_DATA_MASK_INDEXEDDB |
- StoragePartition::REMOVE_DATA_MASK_WEBSQL,
- StoragePartition::QUOTA_MANAGED_STORAGE_MASK_TEMPORARY,
- GURL(origin_string), base::DoNothing());
- }
- void AwQuotaManagerBridge::GetOrigins(JNIEnv* env,
- const JavaParamRef<jobject>& object,
- const JavaParamRef<jobject>& callback) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- GetOriginsCallback ui_callback = base::BindOnce(
- [](const JavaRef<jobject>& obj, const JavaRef<jobject>& callback,
- const std::vector<std::string>& origin,
- const std::vector<int64_t>& usage, const std::vector<int64_t>& quota) {
- JNIEnv* env = AttachCurrentThread();
- Java_AwQuotaManagerBridge_onGetOriginsCallback(
- env, obj, callback,
- base::android::ToJavaArrayOfStrings(env, origin),
- base::android::ToJavaLongArray(env, usage),
- base::android::ToJavaLongArray(env, quota));
- },
- ScopedJavaGlobalRef<jobject>(env, object),
- ScopedJavaGlobalRef<jobject>(env, callback));
- base::MakeRefCounted<GetStorageKeysTask>(std::move(ui_callback),
- GetQuotaManager())
- ->Run();
- }
- namespace {
- void OnUsageAndQuotaObtained(
- AwQuotaManagerBridge::QuotaUsageCallback ui_callback,
- blink::mojom::QuotaStatusCode status_code,
- int64_t usage,
- int64_t quota) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (status_code != blink::mojom::QuotaStatusCode::kOk) {
- usage = 0;
- quota = 0;
- }
- content::GetUIThreadTaskRunner({})->PostTask(
- FROM_HERE, base::BindOnce(std::move(ui_callback), usage, quota));
- }
- } // namespace
- void AwQuotaManagerBridge::GetUsageAndQuotaForOrigin(
- JNIEnv* env,
- const JavaParamRef<jobject>& object,
- const JavaParamRef<jstring>& origin,
- const JavaParamRef<jobject>& callback,
- bool is_quota) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- std::u16string origin_string(
- base::android::ConvertJavaStringToUTF16(env, origin));
- QuotaUsageCallback ui_callback = base::BindOnce(
- [](const JavaRef<jobject>& callback, bool is_quota, int64_t usage,
- int64_t quota) {
- base::android::RunLongCallbackAndroid(callback,
- (is_quota ? quota : usage));
- },
- ScopedJavaGlobalRef<jobject>(env, callback), is_quota);
- // TODO(crbug.com/889590): Use helper for url::Origin creation from string.
- content::GetIOThreadTaskRunner({})->PostTask(
- FROM_HERE,
- base::BindOnce(
- &QuotaManager::GetUsageAndQuota, GetQuotaManager(),
- blink::StorageKey(url::Origin::Create(GURL(origin_string))),
- blink::mojom::StorageType::kTemporary,
- base::BindOnce(&OnUsageAndQuotaObtained, std::move(ui_callback))));
- }
- } // namespace android_webview
|