Home | History | Annotate | Download | only in browsing_data
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "chrome/browser/browsing_data/browsing_data_quota_helper_impl.h"
      6 
      7 #include <map>
      8 #include <set>
      9 
     10 #include "base/bind.h"
     11 #include "base/logging.h"
     12 #include "chrome/browser/browsing_data/browsing_data_helper.h"
     13 #include "chrome/browser/profiles/profile.h"
     14 #include "chrome/common/url_constants.h"
     15 #include "content/public/browser/browser_context.h"
     16 #include "content/public/browser/browser_thread.h"
     17 #include "content/public/browser/storage_partition.h"
     18 #include "storage/browser/quota/quota_manager.h"
     19 
     20 using content::BrowserThread;
     21 using content::BrowserContext;
     22 
     23 // static
     24 BrowsingDataQuotaHelper* BrowsingDataQuotaHelper::Create(Profile* profile) {
     25   return new BrowsingDataQuotaHelperImpl(
     26       BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI).get(),
     27       BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO).get(),
     28       BrowserContext::GetDefaultStoragePartition(profile)->GetQuotaManager());
     29 }
     30 
     31 void BrowsingDataQuotaHelperImpl::StartFetching(
     32     const FetchResultCallback& callback) {
     33   DCHECK(!callback.is_null());
     34   DCHECK(callback_.is_null());
     35   DCHECK(!is_fetching_);
     36   callback_ = callback;
     37   quota_info_.clear();
     38   is_fetching_ = true;
     39 
     40   FetchQuotaInfo();
     41 }
     42 
     43 void BrowsingDataQuotaHelperImpl::RevokeHostQuota(const std::string& host) {
     44   if (!io_thread_->BelongsToCurrentThread()) {
     45     io_thread_->PostTask(
     46         FROM_HERE,
     47         base::Bind(&BrowsingDataQuotaHelperImpl::RevokeHostQuota, this, host));
     48     return;
     49   }
     50 
     51   quota_manager_->SetPersistentHostQuota(
     52       host, 0,
     53       base::Bind(&BrowsingDataQuotaHelperImpl::DidRevokeHostQuota,
     54                  weak_factory_.GetWeakPtr()));
     55 }
     56 
     57 BrowsingDataQuotaHelperImpl::BrowsingDataQuotaHelperImpl(
     58     base::MessageLoopProxy* ui_thread,
     59     base::MessageLoopProxy* io_thread,
     60     storage::QuotaManager* quota_manager)
     61     : BrowsingDataQuotaHelper(io_thread),
     62       quota_manager_(quota_manager),
     63       is_fetching_(false),
     64       ui_thread_(ui_thread),
     65       io_thread_(io_thread),
     66       weak_factory_(this) {
     67   DCHECK(quota_manager);
     68 }
     69 
     70 BrowsingDataQuotaHelperImpl::~BrowsingDataQuotaHelperImpl() {}
     71 
     72 void BrowsingDataQuotaHelperImpl::FetchQuotaInfo() {
     73   if (!io_thread_->BelongsToCurrentThread()) {
     74     io_thread_->PostTask(
     75         FROM_HERE,
     76         base::Bind(&BrowsingDataQuotaHelperImpl::FetchQuotaInfo, this));
     77     return;
     78   }
     79 
     80   quota_manager_->GetOriginsModifiedSince(
     81       storage::kStorageTypeTemporary,
     82       base::Time(),
     83       base::Bind(&BrowsingDataQuotaHelperImpl::GotOrigins,
     84                  weak_factory_.GetWeakPtr()));
     85 }
     86 
     87 void BrowsingDataQuotaHelperImpl::GotOrigins(const std::set<GURL>& origins,
     88                                              storage::StorageType type) {
     89   for (std::set<GURL>::const_iterator itr = origins.begin();
     90        itr != origins.end();
     91        ++itr)
     92     if (BrowsingDataHelper::HasWebScheme(*itr))
     93       pending_hosts_.insert(std::make_pair(itr->host(), type));
     94 
     95   DCHECK(type == storage::kStorageTypeTemporary ||
     96          type == storage::kStorageTypePersistent ||
     97          type == storage::kStorageTypeSyncable);
     98 
     99   // Calling GetOriginsModifiedSince() for all types by chaining callbacks.
    100   if (type == storage::kStorageTypeTemporary) {
    101     quota_manager_->GetOriginsModifiedSince(
    102         storage::kStorageTypePersistent,
    103         base::Time(),
    104         base::Bind(&BrowsingDataQuotaHelperImpl::GotOrigins,
    105                    weak_factory_.GetWeakPtr()));
    106   } else if (type == storage::kStorageTypePersistent) {
    107     quota_manager_->GetOriginsModifiedSince(
    108         storage::kStorageTypeSyncable,
    109         base::Time(),
    110         base::Bind(&BrowsingDataQuotaHelperImpl::GotOrigins,
    111                    weak_factory_.GetWeakPtr()));
    112   } else {
    113     DCHECK(type == storage::kStorageTypeSyncable);
    114     ProcessPendingHosts();
    115   }
    116 }
    117 
    118 void BrowsingDataQuotaHelperImpl::ProcessPendingHosts() {
    119   if (pending_hosts_.empty()) {
    120     OnComplete();
    121     return;
    122   }
    123 
    124   PendingHosts::iterator itr = pending_hosts_.begin();
    125   std::string host = itr->first;
    126   storage::StorageType type = itr->second;
    127   pending_hosts_.erase(itr);
    128   GetHostUsage(host, type);
    129 }
    130 
    131 void BrowsingDataQuotaHelperImpl::GetHostUsage(const std::string& host,
    132                                                storage::StorageType type) {
    133   DCHECK(quota_manager_.get());
    134   quota_manager_->GetHostUsage(
    135       host, type,
    136       base::Bind(&BrowsingDataQuotaHelperImpl::GotHostUsage,
    137                  weak_factory_.GetWeakPtr(), host, type));
    138 }
    139 
    140 void BrowsingDataQuotaHelperImpl::GotHostUsage(const std::string& host,
    141                                                storage::StorageType type,
    142                                                int64 usage) {
    143   switch (type) {
    144     case storage::kStorageTypeTemporary:
    145       quota_info_[host].temporary_usage = usage;
    146       break;
    147     case storage::kStorageTypePersistent:
    148       quota_info_[host].persistent_usage = usage;
    149       break;
    150     case storage::kStorageTypeSyncable:
    151       quota_info_[host].syncable_usage = usage;
    152       break;
    153     default:
    154       NOTREACHED();
    155   }
    156   ProcessPendingHosts();
    157 }
    158 
    159 void BrowsingDataQuotaHelperImpl::OnComplete() {
    160   if (!ui_thread_->BelongsToCurrentThread()) {
    161     ui_thread_->PostTask(
    162         FROM_HERE,
    163         base::Bind(&BrowsingDataQuotaHelperImpl::OnComplete, this));
    164     return;
    165   }
    166 
    167   is_fetching_ = false;
    168 
    169   QuotaInfoArray result;
    170 
    171   for (std::map<std::string, QuotaInfo>::iterator itr = quota_info_.begin();
    172        itr != quota_info_.end();
    173        ++itr) {
    174     QuotaInfo* info = &itr->second;
    175     // Skip unused entries
    176     if (info->temporary_usage <= 0 &&
    177         info->persistent_usage <= 0 &&
    178         info->syncable_usage <= 0)
    179       continue;
    180 
    181     info->host = itr->first;
    182     result.push_back(*info);
    183   }
    184 
    185   callback_.Run(result);
    186   callback_.Reset();
    187 }
    188 
    189 void BrowsingDataQuotaHelperImpl::DidRevokeHostQuota(
    190     storage::QuotaStatusCode status_unused,
    191     int64 quota_unused) {
    192 }
    193