| // Copyright (c) 2011 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 "webkit/fileapi/file_system_quota_client.h" |
| |
| #include <algorithm> |
| #include <set> |
| |
| #include "base/file_path.h" |
| #include "base/file_util.h" |
| #include "base/logging.h" |
| #include "base/memory/scoped_ptr.h" |
| #include "base/message_loop_proxy.h" |
| #include "base/task.h" |
| #include "googleurl/src/gurl.h" |
| #include "net/base/net_util.h" |
| #include "webkit/fileapi/file_system_context.h" |
| #include "webkit/fileapi/file_system_path_manager.h" |
| #include "webkit/fileapi/file_system_quota_util.h" |
| #include "webkit/fileapi/file_system_usage_cache.h" |
| #include "webkit/fileapi/file_system_util.h" |
| |
| using base::MessageLoopProxy; |
| using quota::QuotaThreadTask; |
| using quota::StorageType; |
| |
| namespace fileapi { |
| |
| class FileSystemQuotaClient::GetOriginUsageTask : public QuotaThreadTask { |
| public: |
| GetOriginUsageTask( |
| FileSystemQuotaClient* quota_client, |
| scoped_refptr<MessageLoopProxy> file_message_loop, |
| const GURL& origin_url, |
| FileSystemType type) |
| : QuotaThreadTask(quota_client, file_message_loop), |
| quota_client_(quota_client), |
| origin_url_(origin_url), |
| type_(type), |
| fs_usage_(0) { |
| DCHECK(quota_client_); |
| file_system_context_ = quota_client_->file_system_context_; |
| } |
| |
| virtual ~GetOriginUsageTask() {} |
| |
| protected: |
| virtual void RunOnTargetThread() OVERRIDE { |
| FileSystemQuotaUtil* quota_util = file_system_context_->GetQuotaUtil(type_); |
| if (quota_util) |
| fs_usage_ = quota_util->GetOriginUsageOnFileThread(origin_url_, type_); |
| } |
| |
| virtual void Completed() OVERRIDE { |
| quota_client_->DidGetOriginUsage(type_, origin_url_, fs_usage_); |
| } |
| |
| FileSystemQuotaClient* quota_client_; |
| scoped_refptr<FileSystemContext> file_system_context_; |
| GURL origin_url_; |
| FileSystemType type_; |
| int64 fs_usage_; |
| }; |
| |
| class FileSystemQuotaClient::GetOriginsForTypeTask : public QuotaThreadTask { |
| public: |
| GetOriginsForTypeTask( |
| FileSystemQuotaClient* quota_client, |
| scoped_refptr<MessageLoopProxy> file_message_loop, |
| FileSystemType type) |
| : QuotaThreadTask(quota_client, file_message_loop), |
| quota_client_(quota_client), |
| type_(type) { |
| DCHECK(quota_client_); |
| file_system_context_ = quota_client_->file_system_context_; |
| } |
| virtual ~GetOriginsForTypeTask() {} |
| |
| protected: |
| virtual void RunOnTargetThread() OVERRIDE { |
| FileSystemQuotaUtil* quota_util = file_system_context_->GetQuotaUtil(type_); |
| if (quota_util) |
| quota_util->GetOriginsForTypeOnFileThread(type_, &origins_); |
| } |
| |
| virtual void Completed() OVERRIDE { |
| quota_client_->DidGetOriginsForType(type_, origins_); |
| } |
| |
| private: |
| FileSystemQuotaClient* quota_client_; |
| scoped_refptr<FileSystemContext> file_system_context_; |
| std::set<GURL> origins_; |
| FileSystemType type_; |
| }; |
| |
| class FileSystemQuotaClient::GetOriginsForHostTask : public QuotaThreadTask { |
| public: |
| GetOriginsForHostTask( |
| FileSystemQuotaClient* quota_client, |
| scoped_refptr<MessageLoopProxy> file_message_loop, |
| FileSystemType type, |
| const std::string& host) |
| : QuotaThreadTask(quota_client, file_message_loop), |
| quota_client_(quota_client), |
| type_(type), |
| host_(host) { |
| DCHECK(quota_client_); |
| file_system_context_ = quota_client_->file_system_context_; |
| } |
| virtual ~GetOriginsForHostTask() {} |
| |
| protected: |
| virtual void RunOnTargetThread() OVERRIDE { |
| FileSystemQuotaUtil* quota_util = file_system_context_->GetQuotaUtil(type_); |
| if (quota_util) |
| quota_util->GetOriginsForHostOnFileThread(type_, host_, &origins_); |
| } |
| |
| virtual void Completed() OVERRIDE { |
| quota_client_->DidGetOriginsForHost(std::make_pair(type_, host_), origins_); |
| } |
| |
| private: |
| FileSystemQuotaClient* quota_client_; |
| scoped_refptr<FileSystemContext> file_system_context_; |
| std::set<GURL> origins_; |
| FileSystemType type_; |
| std::string host_; |
| }; |
| |
| class FileSystemQuotaClient::DeleteOriginTask |
| : public QuotaThreadTask { |
| public: |
| DeleteOriginTask( |
| FileSystemQuotaClient* quota_client, |
| scoped_refptr<MessageLoopProxy> file_message_loop, |
| const GURL& origin, |
| FileSystemType type, |
| const DeletionCallback& callback) |
| : QuotaThreadTask(quota_client, file_message_loop), |
| file_system_context_(quota_client->file_system_context_), |
| origin_(origin), |
| type_(type), |
| status_(quota::kQuotaStatusUnknown), |
| callback_(callback) { |
| } |
| |
| virtual ~DeleteOriginTask() {} |
| |
| virtual void RunOnTargetThread() OVERRIDE { |
| if (file_system_context_->DeleteDataForOriginAndTypeOnFileThread( |
| origin_, type_)) |
| status_ = quota::kQuotaStatusOk; |
| else |
| status_ = quota::kQuotaErrorInvalidModification; |
| } |
| |
| virtual void Completed() OVERRIDE { |
| callback_.Run(status_); |
| } |
| private: |
| FileSystemContext* file_system_context_; |
| GURL origin_; |
| FileSystemType type_; |
| quota::QuotaStatusCode status_; |
| DeletionCallback callback_; |
| }; |
| |
| FileSystemQuotaClient::FileSystemQuotaClient( |
| scoped_refptr<base::MessageLoopProxy> file_message_loop, |
| FileSystemContext* file_system_context, |
| bool is_incognito) |
| : file_message_loop_(file_message_loop), |
| file_system_context_(file_system_context), |
| is_incognito_(is_incognito) { |
| DCHECK(file_message_loop); |
| } |
| |
| FileSystemQuotaClient::~FileSystemQuotaClient() { |
| } |
| |
| quota::QuotaClient::ID FileSystemQuotaClient::id() const { |
| return quota::QuotaClient::kFileSystem; |
| } |
| |
| void FileSystemQuotaClient::OnQuotaManagerDestroyed() { |
| delete this; |
| } |
| |
| void FileSystemQuotaClient::GetOriginUsage( |
| const GURL& origin_url, |
| StorageType storage_type, |
| const GetUsageCallback& callback) { |
| DCHECK(!callback.is_null()); |
| |
| if (is_incognito_) { |
| // We don't support FileSystem in incognito mode yet. |
| callback.Run(0); |
| return; |
| } |
| |
| FileSystemType type = QuotaStorageTypeToFileSystemType(storage_type); |
| DCHECK(type != kFileSystemTypeUnknown); |
| |
| if (pending_usage_callbacks_.Add( |
| std::make_pair(type, origin_url.spec()), callback)) { |
| scoped_refptr<GetOriginUsageTask> task( |
| new GetOriginUsageTask(this, file_message_loop_, origin_url, type)); |
| task->Start(); |
| } |
| } |
| |
| void FileSystemQuotaClient::GetOriginsForType( |
| StorageType storage_type, |
| const GetOriginsCallback& callback) { |
| DCHECK(!callback.is_null()); |
| |
| std::set<GURL> origins; |
| if (is_incognito_) { |
| // We don't support FileSystem in incognito mode yet. |
| callback.Run(origins, storage_type); |
| return; |
| } |
| |
| FileSystemType type = QuotaStorageTypeToFileSystemType(storage_type); |
| DCHECK(type != kFileSystemTypeUnknown); |
| |
| if (pending_origins_for_type_callbacks_.Add(type, callback)) { |
| scoped_refptr<GetOriginsForTypeTask> task( |
| new GetOriginsForTypeTask(this, file_message_loop_, type)); |
| task->Start(); |
| } |
| } |
| |
| void FileSystemQuotaClient::GetOriginsForHost( |
| StorageType storage_type, |
| const std::string& host, |
| const GetOriginsCallback& callback) { |
| DCHECK(!callback.is_null()); |
| |
| std::set<GURL> origins; |
| if (is_incognito_) { |
| // We don't support FileSystem in incognito mode yet. |
| callback.Run(origins, storage_type); |
| return; |
| } |
| |
| FileSystemType type = QuotaStorageTypeToFileSystemType(storage_type); |
| DCHECK(type != kFileSystemTypeUnknown); |
| |
| if (pending_origins_for_host_callbacks_.Add( |
| std::make_pair(type, host), callback)) { |
| scoped_refptr<GetOriginsForHostTask> task( |
| new GetOriginsForHostTask(this, file_message_loop_, |
| type, host)); |
| task->Start(); |
| } |
| } |
| |
| void FileSystemQuotaClient::DeleteOriginData(const GURL& origin, |
| StorageType type, |
| const DeletionCallback& callback) { |
| FileSystemType fs_type = QuotaStorageTypeToFileSystemType(type); |
| DCHECK(fs_type != kFileSystemTypeUnknown); |
| scoped_refptr<DeleteOriginTask> task( |
| new DeleteOriginTask(this, file_message_loop_, |
| origin, fs_type, callback)); |
| task->Start(); |
| } |
| |
| void FileSystemQuotaClient::DidGetOriginUsage( |
| FileSystemType type, const GURL& origin_url, int64 usage) { |
| TypeAndHostOrOrigin type_and_origin(std::make_pair( |
| type, origin_url.spec())); |
| DCHECK(pending_usage_callbacks_.HasCallbacks(type_and_origin)); |
| pending_usage_callbacks_.Run(type_and_origin, usage); |
| } |
| |
| void FileSystemQuotaClient::DidGetOriginsForType( |
| FileSystemType type, const std::set<GURL>& origins) { |
| DCHECK(pending_origins_for_type_callbacks_.HasCallbacks(type)); |
| pending_origins_for_type_callbacks_.Run(type, origins, |
| FileSystemTypeToQuotaStorageType(type)); |
| } |
| |
| void FileSystemQuotaClient::DidGetOriginsForHost( |
| const TypeAndHostOrOrigin& type_and_host, const std::set<GURL>& origins) { |
| DCHECK(pending_origins_for_host_callbacks_.HasCallbacks(type_and_host)); |
| pending_origins_for_host_callbacks_.Run(type_and_host, origins, |
| FileSystemTypeToQuotaStorageType(type_and_host.first)); |
| } |
| |
| } // namespace fileapi |