// 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 "chrome/browser/browsing_data_quota_helper_impl.h" #include #include #include "base/bind.h" #include "base/logging.h" #include "chrome/browser/profiles/profile.h" #include "webkit/quota/quota_manager.h" using content::BrowserThread; // static BrowsingDataQuotaHelper* BrowsingDataQuotaHelper::Create(Profile* profile) { return new BrowsingDataQuotaHelperImpl( BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI), BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO), profile->GetQuotaManager()); } void BrowsingDataQuotaHelperImpl::StartFetching( const FetchResultCallback& callback) { DCHECK_EQ(false, callback.is_null()); DCHECK(callback_.is_null()); DCHECK(!is_fetching_); callback_ = callback; quota_info_.clear(); is_fetching_ = true; FetchQuotaInfo(); } void BrowsingDataQuotaHelperImpl::CancelNotification() { callback_.Reset(); } void BrowsingDataQuotaHelperImpl::RevokeHostQuota(const std::string& host) { if (!io_thread_->BelongsToCurrentThread()) { io_thread_->PostTask( FROM_HERE, base::Bind(&BrowsingDataQuotaHelperImpl::RevokeHostQuota, this, host)); return; } quota_manager_->SetPersistentHostQuota( host, 0, base::Bind(&BrowsingDataQuotaHelperImpl::DidRevokeHostQuota, weak_factory_.GetWeakPtr())); } BrowsingDataQuotaHelperImpl::BrowsingDataQuotaHelperImpl( base::MessageLoopProxy* ui_thread, base::MessageLoopProxy* io_thread, quota::QuotaManager* quota_manager) : BrowsingDataQuotaHelper(io_thread), quota_manager_(quota_manager), is_fetching_(false), ui_thread_(ui_thread), io_thread_(io_thread), weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { DCHECK(quota_manager); } BrowsingDataQuotaHelperImpl::~BrowsingDataQuotaHelperImpl() {} void BrowsingDataQuotaHelperImpl::FetchQuotaInfo() { if (!io_thread_->BelongsToCurrentThread()) { io_thread_->PostTask( FROM_HERE, base::Bind(&BrowsingDataQuotaHelperImpl::FetchQuotaInfo, this)); return; } quota_manager_->GetOriginsModifiedSince( quota::kStorageTypeTemporary, base::Time(), base::Bind(&BrowsingDataQuotaHelperImpl::GotOrigins, weak_factory_.GetWeakPtr())); } void BrowsingDataQuotaHelperImpl::GotOrigins( const std::set& origins, quota::StorageType type) { for (std::set::const_iterator itr = origins.begin(); itr != origins.end(); ++itr) pending_hosts_.insert(std::make_pair(itr->host(), type)); DCHECK(type == quota::kStorageTypeTemporary || type == quota::kStorageTypePersistent); if (type == quota::kStorageTypeTemporary) { quota_manager_->GetOriginsModifiedSince( quota::kStorageTypePersistent, base::Time(), base::Bind(&BrowsingDataQuotaHelperImpl::GotOrigins, weak_factory_.GetWeakPtr())); } else { // type == quota::kStorageTypePersistent ProcessPendingHosts(); } } void BrowsingDataQuotaHelperImpl::ProcessPendingHosts() { if (pending_hosts_.empty()) { OnComplete(); return; } PendingHosts::iterator itr = pending_hosts_.begin(); std::string host = itr->first; quota::StorageType type = itr->second; pending_hosts_.erase(itr); GetHostUsage(host, type); } void BrowsingDataQuotaHelperImpl::GetHostUsage(const std::string& host, quota::StorageType type) { DCHECK(quota_manager_.get()); quota_manager_->GetHostUsage( host, type, base::Bind(&BrowsingDataQuotaHelperImpl::GotHostUsage, weak_factory_.GetWeakPtr())); } void BrowsingDataQuotaHelperImpl::GotHostUsage(const std::string& host, quota::StorageType type, int64 usage) { switch (type) { case quota::kStorageTypeTemporary: quota_info_[host].temporary_usage = usage; break; case quota::kStorageTypePersistent: quota_info_[host].persistent_usage = usage; break; default: NOTREACHED(); } ProcessPendingHosts(); } void BrowsingDataQuotaHelperImpl::OnComplete() { // Check if CancelNotification was called if (callback_.is_null()) return; if (!ui_thread_->BelongsToCurrentThread()) { ui_thread_->PostTask( FROM_HERE, base::Bind(&BrowsingDataQuotaHelperImpl::OnComplete, this)); return; } is_fetching_ = false; QuotaInfoArray result; for (std::map::iterator itr = quota_info_.begin(); itr != quota_info_.end(); ++itr) { QuotaInfo* info = &itr->second; // Skip unused entries if (info->temporary_usage <= 0 && info->persistent_usage <= 0) continue; info->host = itr->first; result.push_back(*info); } callback_.Run(result); callback_.Reset(); } void BrowsingDataQuotaHelperImpl::DidRevokeHostQuota( quota::QuotaStatusCode status_unused, const std::string& host_unused, quota::StorageType type_unused, int64 quota_unused) { }