diff options
Diffstat (limited to 'webkit/quota/quota_manager.cc')
-rw-r--r-- | webkit/quota/quota_manager.cc | 300 |
1 files changed, 265 insertions, 35 deletions
diff --git a/webkit/quota/quota_manager.cc b/webkit/quota/quota_manager.cc index 16b44ef..2e2db35 100644 --- a/webkit/quota/quota_manager.cc +++ b/webkit/quota/quota_manager.cc @@ -84,12 +84,16 @@ class QuotaManager::UsageAndQuotaDispatcherTask : public QuotaTask { CheckCompleted(); } - void DidGetGlobalQuota(int64 quota) { + void DidGetGlobalQuota(QuotaStatusCode status, int64 quota) { + quota_status_ = status; quota_ = quota; CheckCompleted(); } - void DidGetHostQuota(const std::string& host_unused, int64 quota) { + void DidGetHostQuota(QuotaStatusCode status, + const std::string& host_unused, + int64 quota) { + quota_status_ = status; quota_ = quota; CheckCompleted(); } @@ -105,6 +109,7 @@ class QuotaManager::UsageAndQuotaDispatcherTask : public QuotaTask { quota_(-1), global_usage_(-1), host_usage_(-1), + quota_status_(kQuotaStatusUnknown), callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {} virtual ~UsageAndQuotaDispatcherTask() { @@ -136,6 +141,7 @@ class QuotaManager::UsageAndQuotaDispatcherTask : public QuotaTask { int64 quota() const { return quota_; } int64 global_usage() const { return global_usage_; } int64 host_usage() const { return host_usage_; } + QuotaStatusCode status() const { return quota_status_; } UsageCallback* NewGlobalUsageCallback() { return callback_factory_.NewCallback( @@ -182,6 +188,7 @@ class QuotaManager::UsageAndQuotaDispatcherTask : public QuotaTask { int64 quota_; int64 global_usage_; int64 host_usage_; + QuotaStatusCode quota_status_; CallbackList callbacks_; ScopedCallbackFactory<UsageAndQuotaDispatcherTask> callback_factory_; @@ -213,7 +220,7 @@ class QuotaManager::UsageAndQuotaDispatcherTaskForTemporary // to return {usage, quota - nonevictable_usage} once eviction is // supported. int64 other_usage = global_usage() - host_usage(); - callback->Run(kQuotaStatusOk, host_usage(), quota() - other_usage); + callback->Run(status(), host_usage(), quota() - other_usage); } }; @@ -237,7 +244,7 @@ class QuotaManager::UsageAndQuotaDispatcherTaskForPersistent } virtual void DispatchCallback(GetUsageAndQuotaCallback* callback) OVERRIDE { - callback->Run(kQuotaStatusOk, host_usage(), quota()); + callback->Run(status(), host_usage(), quota()); } }; @@ -292,10 +299,10 @@ class QuotaManager::InitializeTask : public QuotaThreadTask { virtual void Completed() OVERRIDE { DCHECK(manager_); - if (manager_->temporary_global_quota_ < 0) - manager_->DidGetTemporaryGlobalQuota(temporary_storage_quota_); manager_->db_initialized_ = !db_disabled_; manager_->db_disabled_ = db_disabled_; + if (manager_->temporary_global_quota_ < 0) + manager_->DidGetTemporaryGlobalQuota(temporary_storage_quota_); } private: @@ -306,36 +313,122 @@ class QuotaManager::InitializeTask : public QuotaThreadTask { bool db_disabled_; }; -class QuotaManager::TemporaryGlobalQuotaUpdateTask : public QuotaThreadTask { +class QuotaManager::TemporaryGlobalQuotaUpdateTask + : public QuotaThreadTask { public: TemporaryGlobalQuotaUpdateTask( QuotaManager* manager, QuotaDatabase* database, scoped_refptr<base::MessageLoopProxy> db_message_loop, - int64 new_quota) + int64 new_quota, + QuotaCallback* callback) : QuotaThreadTask(manager, db_message_loop), manager_(manager), database_(database), new_quota_(new_quota), + callback_(callback), db_disabled_(false) { DCHECK(database_); + DCHECK(new_quota >=0); } protected: virtual void RunOnTargetThread() OVERRIDE { - if (!database_->SetGlobalQuota(kStorageTypeTemporary, new_quota_)) + if (!database_->SetGlobalQuota(kStorageTypeTemporary, new_quota_)) { db_disabled_ = true; + new_quota_ = 0; + } } virtual void Completed() OVERRIDE { DCHECK(manager_); manager_->db_disabled_ = db_disabled_; + callback_->Run(db_disabled_ ? kQuotaErrorInvalidAccess : kQuotaStatusOk, + new_quota_); + } + + private: + QuotaManager* manager_; + QuotaDatabase* database_; + int64 new_quota_; + scoped_ptr<QuotaCallback> callback_; + bool db_disabled_; +}; + +class QuotaManager::PersistentHostQuotaQueryTask : public QuotaThreadTask { + public: + PersistentHostQuotaQueryTask( + QuotaManager* manager, + QuotaDatabase* database, + scoped_refptr<base::MessageLoopProxy> db_message_loop, + const std::string& host, + HostQuotaCallback* callback) + : QuotaThreadTask(manager, db_message_loop), + manager_(manager), + database_(database), + host_(host), + quota_(-1), + callback_(callback) { + DCHECK(manager_); + DCHECK(database_); + DCHECK(!host_.empty()); + } + protected: + virtual void RunOnTargetThread() OVERRIDE { + if (!database_->GetHostQuota(host_, kStorageTypePersistent, "a_)) + quota_ = 0; + } + virtual void Completed() OVERRIDE { + callback_->Run(kQuotaStatusOk, host_, quota_); + } + private: + QuotaManager* manager_; + QuotaDatabase* database_; + std::string host_; + int64 quota_; + scoped_ptr<HostQuotaCallback> callback_; +}; + +class QuotaManager::PersistentHostQuotaUpdateTask : public QuotaThreadTask { + public: + PersistentHostQuotaUpdateTask( + QuotaManager* manager, + QuotaDatabase* database, + scoped_refptr<base::MessageLoopProxy> db_message_loop, + const std::string& host, + int new_quota, + HostQuotaCallback* callback) + : QuotaThreadTask(manager, db_message_loop), + manager_(manager), + database_(database), + host_(host), + new_quota_(new_quota), + callback_(callback), + db_disabled_(false) { + DCHECK(manager_); + DCHECK(database_); + DCHECK(!host_.empty()); + DCHECK(new_quota_ >= 0); + } + protected: + virtual void RunOnTargetThread() OVERRIDE { + if (!database_->SetHostQuota(host_, kStorageTypePersistent, new_quota_)) { + db_disabled_ = true; + new_quota_ = 0; + } } + virtual void Completed() OVERRIDE { + manager_->db_disabled_ = db_disabled_; + callback_->Run(db_disabled_ ? kQuotaErrorInvalidAccess : kQuotaStatusOk, + host_, new_quota_); + } private: QuotaManager* manager_; QuotaDatabase* database_; + std::string host_; int64 new_quota_; + scoped_ptr<HostQuotaCallback> callback_; bool db_disabled_; }; @@ -411,7 +504,7 @@ void QuotaManager::GetTemporaryGlobalQuota(QuotaCallback* callback) { if (temporary_global_quota_ >= 0) { // TODO(kinuko): The in-memory quota value should be periodically // updated not to exceed the current available space in the hard drive. - callback->Run(temporary_global_quota_); + callback->Run(kQuotaStatusOk, temporary_global_quota_); delete callback; return; } @@ -419,39 +512,56 @@ void QuotaManager::GetTemporaryGlobalQuota(QuotaCallback* callback) { temporary_global_quota_callbacks_.Add(callback); } -void QuotaManager::SetTemporaryGlobalQuota(int64 new_quota) { +void QuotaManager::SetTemporaryGlobalQuota(int64 new_quota, + QuotaCallback* callback) { LazyInitialize(); - DCHECK(new_quota >= 0); + if (new_quota < 0) { + callback->Run(kQuotaErrorInvalidModification, -1); + delete callback; + return; + } + DidGetTemporaryGlobalQuota(new_quota); if (!db_disabled_) { scoped_refptr<TemporaryGlobalQuotaUpdateTask> task( new TemporaryGlobalQuotaUpdateTask( - this, database_.get(), db_thread_, new_quota)); + this, database_.get(), db_thread_, new_quota, callback)); task->Start(); + } else { + callback->Run(kQuotaErrorInvalidAccess, -1); + delete callback; } } void QuotaManager::GetPersistentHostQuota(const std::string& host, HostQuotaCallback* callback) { LazyInitialize(); - std::map<std::string, int64>::iterator found = - persistent_host_quota_.find(host); - if (found != persistent_host_quota_.end()) { - callback->Run(host, found->second); - delete callback; - return; - } - if (persistent_host_quota_callbacks_.Add(host, callback)) { - // This is the first call for this host. - // TODO(kinuko): Dispatch a task to get the host quota for the host - // once QuotaDatabase is updated to accept hosts instead of origins. - } + + scoped_refptr<PersistentHostQuotaQueryTask> task( + new PersistentHostQuotaQueryTask( + this, database_.get(), db_thread_, host, callback)); + task->Start(); } void QuotaManager::SetPersistentHostQuota(const std::string& host, - int64 new_quota) { + int64 new_quota, + HostQuotaCallback* callback) { LazyInitialize(); - // TODO(kinuko): Implement once QuotaDatabase is updated. + if (new_quota < 0) { + callback->Run(kQuotaErrorInvalidModification, host, -1); + delete callback; + return; + } + + if (!db_disabled_) { + scoped_refptr<PersistentHostQuotaUpdateTask> task( + new PersistentHostQuotaUpdateTask( + this, database_.get(), db_thread_, host, new_quota, callback)); + task->Start(); + } else { + callback->Run(kQuotaErrorInvalidAccess, host, -1); + delete callback; + } } void QuotaManager::LazyInitialize() { @@ -505,14 +615,9 @@ UsageTracker* QuotaManager::GetUsageTracker(StorageType type) const { void QuotaManager::DidGetTemporaryGlobalQuota(int64 quota) { temporary_global_quota_ = quota; - temporary_global_quota_callbacks_.Run(quota); -} - -void QuotaManager::DidGetPersistentHostQuota(const std::string& host, - int64 quota) { - DCHECK(persistent_host_quota_.find(host) == persistent_host_quota_.end()); - persistent_host_quota_[host] = quota; - persistent_host_quota_callbacks_.Run(host, host, quota); + temporary_global_quota_callbacks_.Run( + db_disabled_ ? kQuotaErrorInvalidAccess : kQuotaStatusOk, + quota); } void QuotaManager::DeleteOnCorrectThread() const { @@ -523,6 +628,131 @@ void QuotaManager::DeleteOnCorrectThread() const { delete this; } +class QuotaManager::GlobalUsageQueryTask : public QuotaTask { + public: + GlobalUsageQueryTask(QuotaManager* manager, + StorageType type, + UsageCallback* callback) + : QuotaTask(manager), + manager_(manager), + callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), + type_(type), + usage_(0), + callback_(callback) {} + + protected: + virtual void Run() OVERRIDE { + UsageTracker* tracker = NULL; + + switch (type_) { + case kStorageTypeTemporary: + tracker = manager_->temporary_usage_tracker_.get(); + break; + case kStorageTypePersistent: + tracker = manager_->persistent_usage_tracker_.get(); + break; + default: + NOTREACHED(); + } + + DCHECK(tracker); + tracker->GetGlobalUsage( + callback_factory_.NewCallback( + &GlobalUsageQueryTask::DidGetGlobalUsage)); + } + + virtual void Aborted() OVERRIDE { + delete this; + } + + virtual void Completed() OVERRIDE { + callback_->Run(usage_); + delete this; + } + private: + QuotaManager* manager_; + ScopedCallbackFactory<GlobalUsageQueryTask> callback_factory_; + StorageType type_; + int64 usage_; + UsageCallback* callback_; + + void DidGetGlobalUsage(int64 usage) { + usage_ += usage; + CallCompleted(); + } +}; + +class QuotaManager::HostUsageQueryTask : public QuotaTask { + public: + HostUsageQueryTask(QuotaManager* manager, + const std::string& host, + StorageType type, + HostUsageCallback* callback) + : QuotaTask(manager), + manager_(manager), + callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), + usage_(0), + host_(host), + type_(type), + callback_(callback) {} + + protected: + virtual void Run() OVERRIDE { + UsageTracker* tracker = NULL; + switch (type_) { + case kStorageTypeTemporary: + tracker = manager_->temporary_usage_tracker_.get(); + break; + case kStorageTypePersistent: + tracker = manager_->persistent_usage_tracker_.get(); + break; + default: + NOTREACHED(); + } + + DCHECK(tracker); + tracker->GetHostUsage( + host_, + callback_factory_.NewCallback( + &HostUsageQueryTask::DidGetHostUsage)); + } + + virtual void Aborted() OVERRIDE { + delete this; + } + + virtual void Completed() OVERRIDE { + callback_->Run(host_, usage_); + delete this; + } + private: + QuotaManager* manager_; + ScopedCallbackFactory<HostUsageQueryTask> callback_factory_; + int task_count_; + int64 usage_; + std::string host_; + StorageType type_; + HostUsageCallback* callback_; + + void DidGetHostUsage(const std::string&, int64 usage) { + usage_ = usage; + CallCompleted(); + } +}; + +void QuotaManager::GetGlobalUsage(StorageType type, UsageCallback* callback){ + LazyInitialize(); + QuotaTask* task = new GlobalUsageQueryTask(this, type, callback); + task->Start(); +} + +void QuotaManager::GetHostUsage(const std::string& host, StorageType type, + HostUsageCallback* callback) { + LazyInitialize(); + QuotaTask* task = new HostUsageQueryTask(this, host, type, callback); + task->Start(); +} + // QuotaManagerProxy ---------------------------------------------------------- void QuotaManagerProxy::GetUsageAndQuota( |