| // Copyright (c) 2012 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 "storage/browser/fileapi/file_system_quota_client.h" |
| |
| #include <algorithm> |
| #include <memory> |
| |
| #include "base/bind.h" |
| #include "base/files/file_util.h" |
| #include "base/location.h" |
| #include "base/logging.h" |
| #include "base/sequenced_task_runner.h" |
| #include "base/single_thread_task_runner.h" |
| #include "base/task_runner_util.h" |
| #include "storage/browser/fileapi/file_system_context.h" |
| #include "storage/browser/fileapi/file_system_usage_cache.h" |
| #include "storage/browser/fileapi/sandbox_file_system_backend.h" |
| #include "storage/common/fileapi/file_system_util.h" |
| #include "third_party/blink/public/mojom/quota/quota_types.mojom.h" |
| #include "url/gurl.h" |
| |
| using blink::mojom::StorageType; |
| |
| namespace storage { |
| |
| namespace { |
| |
| void GetOriginsForTypeOnFileTaskRunner(FileSystemContext* context, |
| StorageType storage_type, |
| std::set<url::Origin>* origins_ptr) { |
| FileSystemType type = QuotaStorageTypeToFileSystemType(storage_type); |
| DCHECK(type != kFileSystemTypeUnknown); |
| |
| FileSystemQuotaUtil* quota_util = context->GetQuotaUtil(type); |
| if (!quota_util) |
| return; |
| std::set<GURL> origins; |
| quota_util->GetOriginsForTypeOnFileTaskRunner(type, &origins); |
| for (auto origin : origins) |
| origins_ptr->insert(url::Origin::Create(origin)); |
| } |
| |
| void GetOriginsForHostOnFileTaskRunner(FileSystemContext* context, |
| StorageType storage_type, |
| const std::string& host, |
| std::set<url::Origin>* origins_ptr) { |
| FileSystemType type = QuotaStorageTypeToFileSystemType(storage_type); |
| DCHECK(type != kFileSystemTypeUnknown); |
| |
| FileSystemQuotaUtil* quota_util = context->GetQuotaUtil(type); |
| if (!quota_util) |
| return; |
| std::set<GURL> origins; |
| quota_util->GetOriginsForHostOnFileTaskRunner(type, host, &origins); |
| for (auto origin : origins) |
| origins_ptr->insert(url::Origin::Create(origin)); |
| } |
| |
| void DidGetFileSystemQuotaClientOrigins( |
| storage::QuotaClient::GetOriginsCallback callback, |
| std::set<url::Origin>* origins_ptr) { |
| std::move(callback).Run(*origins_ptr); |
| } |
| |
| blink::mojom::QuotaStatusCode DeleteOriginOnFileTaskRunner( |
| FileSystemContext* context, |
| const url::Origin& origin, |
| FileSystemType type) { |
| FileSystemBackend* provider = context->GetFileSystemBackend(type); |
| if (!provider || !provider->GetQuotaUtil()) |
| return blink::mojom::QuotaStatusCode::kErrorNotSupported; |
| base::File::Error result = |
| provider->GetQuotaUtil()->DeleteOriginDataOnFileTaskRunner( |
| context, context->quota_manager_proxy(), origin.GetURL(), type); |
| if (result == base::File::FILE_OK) |
| return blink::mojom::QuotaStatusCode::kOk; |
| return blink::mojom::QuotaStatusCode::kErrorInvalidModification; |
| } |
| |
| void PerformStorageCleanupOnFileTaskRunner(FileSystemContext* context, |
| FileSystemType type) { |
| FileSystemBackend* provider = context->GetFileSystemBackend(type); |
| if (!provider || !provider->GetQuotaUtil()) |
| return; |
| provider->GetQuotaUtil()->PerformStorageCleanupOnFileTaskRunner( |
| context, context->quota_manager_proxy(), type); |
| } |
| |
| } // namespace |
| |
| FileSystemQuotaClient::FileSystemQuotaClient( |
| FileSystemContext* file_system_context) |
| : file_system_context_(file_system_context) {} |
| |
| FileSystemQuotaClient::~FileSystemQuotaClient() = default; |
| |
| storage::QuotaClient::ID FileSystemQuotaClient::id() const { |
| return storage::QuotaClient::kFileSystem; |
| } |
| |
| void FileSystemQuotaClient::OnQuotaManagerDestroyed() { |
| delete this; |
| } |
| |
| void FileSystemQuotaClient::GetOriginUsage(const url::Origin& origin, |
| StorageType storage_type, |
| GetUsageCallback callback) { |
| DCHECK(!callback.is_null()); |
| |
| FileSystemType type = QuotaStorageTypeToFileSystemType(storage_type); |
| DCHECK(type != kFileSystemTypeUnknown); |
| |
| FileSystemQuotaUtil* quota_util = file_system_context_->GetQuotaUtil(type); |
| if (!quota_util) { |
| std::move(callback).Run(0); |
| return; |
| } |
| |
| base::PostTaskAndReplyWithResult( |
| file_task_runner(), FROM_HERE, |
| // It is safe to pass Unretained(quota_util) since context owns it. |
| base::BindOnce(&FileSystemQuotaUtil::GetOriginUsageOnFileTaskRunner, |
| base::Unretained(quota_util), |
| base::RetainedRef(file_system_context_), origin.GetURL(), |
| type), |
| std::move(callback)); |
| } |
| |
| void FileSystemQuotaClient::GetOriginsForType(StorageType storage_type, |
| GetOriginsCallback callback) { |
| DCHECK(!callback.is_null()); |
| |
| std::set<url::Origin>* origins_ptr = new std::set<url::Origin>(); |
| file_task_runner()->PostTaskAndReply( |
| FROM_HERE, |
| base::BindOnce(&GetOriginsForTypeOnFileTaskRunner, |
| base::RetainedRef(file_system_context_), storage_type, |
| base::Unretained(origins_ptr)), |
| base::BindOnce(&DidGetFileSystemQuotaClientOrigins, std::move(callback), |
| base::Owned(origins_ptr))); |
| } |
| |
| void FileSystemQuotaClient::GetOriginsForHost(StorageType storage_type, |
| const std::string& host, |
| GetOriginsCallback callback) { |
| DCHECK(!callback.is_null()); |
| |
| std::set<url::Origin>* origins_ptr = new std::set<url::Origin>(); |
| file_task_runner()->PostTaskAndReply( |
| FROM_HERE, |
| base::BindOnce(&GetOriginsForHostOnFileTaskRunner, |
| base::RetainedRef(file_system_context_), storage_type, |
| host, base::Unretained(origins_ptr)), |
| base::BindOnce(&DidGetFileSystemQuotaClientOrigins, std::move(callback), |
| base::Owned(origins_ptr))); |
| } |
| |
| void FileSystemQuotaClient::DeleteOriginData(const url::Origin& origin, |
| StorageType type, |
| DeletionCallback callback) { |
| FileSystemType fs_type = QuotaStorageTypeToFileSystemType(type); |
| DCHECK(fs_type != kFileSystemTypeUnknown); |
| |
| base::PostTaskAndReplyWithResult( |
| file_task_runner(), FROM_HERE, |
| base::BindOnce(&DeleteOriginOnFileTaskRunner, |
| base::RetainedRef(file_system_context_), origin, fs_type), |
| std::move(callback)); |
| } |
| |
| void FileSystemQuotaClient::PerformStorageCleanup(StorageType type, |
| base::OnceClosure callback) { |
| FileSystemType fs_type = QuotaStorageTypeToFileSystemType(type); |
| DCHECK(fs_type != kFileSystemTypeUnknown); |
| file_task_runner()->PostTaskAndReply( |
| FROM_HERE, |
| base::BindOnce(&PerformStorageCleanupOnFileTaskRunner, |
| base::RetainedRef(file_system_context_), fs_type), |
| std::move(callback)); |
| } |
| |
| bool FileSystemQuotaClient::DoesSupport(StorageType storage_type) const { |
| FileSystemType type = QuotaStorageTypeToFileSystemType(storage_type); |
| DCHECK(type != kFileSystemTypeUnknown); |
| return file_system_context_->IsSandboxFileSystem(type); |
| } |
| |
| base::SequencedTaskRunner* FileSystemQuotaClient::file_task_runner() const { |
| return file_system_context_->default_file_task_runner(); |
| } |
| |
| } // namespace storage |