Home | History | Annotate | Download | only in quota_internals
      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/ui/webui/quota_internals/quota_internals_proxy.h"
      6 
      7 #include <set>
      8 #include <string>
      9 
     10 #include "base/bind.h"
     11 #include "chrome/browser/ui/webui/quota_internals/quota_internals_handler.h"
     12 #include "chrome/browser/ui/webui/quota_internals/quota_internals_types.h"
     13 #include "net/base/net_util.h"
     14 
     15 using content::BrowserThread;
     16 
     17 namespace quota_internals {
     18 
     19 QuotaInternalsProxy::QuotaInternalsProxy(QuotaInternalsHandler* handler)
     20     : handler_(handler),
     21       weak_factory_(this) {
     22 }
     23 
     24 void QuotaInternalsProxy::RequestInfo(
     25     scoped_refptr<quota::QuotaManager> quota_manager) {
     26   DCHECK(quota_manager.get());
     27   if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
     28     BrowserThread::PostTask(
     29         BrowserThread::IO, FROM_HERE,
     30         base::Bind(&QuotaInternalsProxy::RequestInfo, this, quota_manager));
     31     return;
     32   }
     33 
     34   quota_manager_ = quota_manager;
     35   quota_manager_->GetAvailableSpace(
     36       base::Bind(&QuotaInternalsProxy::DidGetAvailableSpace,
     37                  weak_factory_.GetWeakPtr()));
     38 
     39   quota_manager_->GetTemporaryGlobalQuota(
     40       base::Bind(&QuotaInternalsProxy::DidGetGlobalQuota,
     41                  weak_factory_.GetWeakPtr(), quota::kStorageTypeTemporary));
     42 
     43   quota_manager_->GetGlobalUsage(
     44       quota::kStorageTypeTemporary,
     45       base::Bind(&QuotaInternalsProxy::DidGetGlobalUsage,
     46                  weak_factory_.GetWeakPtr(),
     47                  quota::kStorageTypeTemporary));
     48 
     49   quota_manager_->GetGlobalUsage(
     50       quota::kStorageTypePersistent,
     51       base::Bind(&QuotaInternalsProxy::DidGetGlobalUsage,
     52                  weak_factory_.GetWeakPtr(),
     53                  quota::kStorageTypePersistent));
     54 
     55   quota_manager_->GetGlobalUsage(
     56       quota::kStorageTypeSyncable,
     57       base::Bind(&QuotaInternalsProxy::DidGetGlobalUsage,
     58                  weak_factory_.GetWeakPtr(),
     59                  quota::kStorageTypeSyncable));
     60 
     61   quota_manager_->DumpQuotaTable(
     62       base::Bind(&QuotaInternalsProxy::DidDumpQuotaTable,
     63                  weak_factory_.GetWeakPtr()));
     64 
     65   quota_manager_->DumpOriginInfoTable(
     66       base::Bind(&QuotaInternalsProxy::DidDumpOriginInfoTable,
     67                  weak_factory_.GetWeakPtr()));
     68 
     69   std::map<std::string, std::string> stats;
     70   quota_manager_->GetStatistics(&stats);
     71   ReportStatistics(stats);
     72 }
     73 
     74 QuotaInternalsProxy::~QuotaInternalsProxy() {}
     75 
     76 #define RELAY_TO_HANDLER(func, arg_t) \
     77   void QuotaInternalsProxy::func(arg_t arg) {                 \
     78     if (!handler_)                                            \
     79       return;                                                 \
     80     if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {     \
     81       BrowserThread::PostTask(                                \
     82           BrowserThread::UI, FROM_HERE,                       \
     83           base::Bind(&QuotaInternalsProxy::func, this, arg)); \
     84       return;                                                 \
     85     }                                                         \
     86                                                               \
     87     handler_->func(arg);                                      \
     88   }
     89 
     90 RELAY_TO_HANDLER(ReportAvailableSpace, int64)
     91 RELAY_TO_HANDLER(ReportGlobalInfo, const GlobalStorageInfo&)
     92 RELAY_TO_HANDLER(ReportPerHostInfo, const std::vector<PerHostStorageInfo>&)
     93 RELAY_TO_HANDLER(ReportPerOriginInfo, const std::vector<PerOriginStorageInfo>&)
     94 RELAY_TO_HANDLER(ReportStatistics, const Statistics&)
     95 
     96 #undef RELAY_TO_HANDLER
     97 
     98 void QuotaInternalsProxy::DidGetAvailableSpace(quota::QuotaStatusCode status,
     99                                                int64 space) {
    100   if (status == quota::kQuotaStatusOk)
    101     ReportAvailableSpace(space);
    102 }
    103 
    104 void QuotaInternalsProxy::DidGetGlobalQuota(quota::StorageType type,
    105                                             quota::QuotaStatusCode status,
    106                                             int64 quota) {
    107   if (status == quota::kQuotaStatusOk) {
    108     GlobalStorageInfo info(type);
    109     info.set_quota(quota);
    110     ReportGlobalInfo(info);
    111   }
    112 }
    113 
    114 void QuotaInternalsProxy::DidGetGlobalUsage(quota::StorageType type,
    115                                             int64 usage,
    116                                             int64 unlimited_usage) {
    117   GlobalStorageInfo info(type);
    118   info.set_usage(usage);
    119   info.set_unlimited_usage(unlimited_usage);
    120 
    121   ReportGlobalInfo(info);
    122   RequestPerOriginInfo(type);
    123 }
    124 
    125 void QuotaInternalsProxy::DidDumpQuotaTable(const QuotaTableEntries& entries) {
    126   std::vector<PerHostStorageInfo> host_info;
    127   host_info.reserve(entries.size());
    128 
    129   typedef QuotaTableEntries::const_iterator iterator;
    130   for (iterator itr(entries.begin()); itr != entries.end(); ++itr) {
    131     PerHostStorageInfo info(itr->host, itr->type);
    132     info.set_quota(itr->quota);
    133     host_info.push_back(info);
    134   }
    135 
    136   ReportPerHostInfo(host_info);
    137 }
    138 
    139 void QuotaInternalsProxy::DidDumpOriginInfoTable(
    140     const OriginInfoTableEntries& entries) {
    141   std::vector<PerOriginStorageInfo> origin_info;
    142   origin_info.reserve(entries.size());
    143 
    144   typedef OriginInfoTableEntries::const_iterator iterator;
    145   for (iterator itr(entries.begin()); itr != entries.end(); ++itr) {
    146     PerOriginStorageInfo info(itr->origin, itr->type);
    147     info.set_used_count(itr->used_count);
    148     info.set_last_access_time(itr->last_access_time);
    149     info.set_last_modified_time(itr->last_modified_time);
    150 
    151     origin_info.push_back(info);
    152   }
    153 
    154   ReportPerOriginInfo(origin_info);
    155 }
    156 
    157 void QuotaInternalsProxy::DidGetHostUsage(const std::string& host,
    158                                           quota::StorageType type,
    159                                           int64 usage) {
    160   DCHECK(type == quota::kStorageTypeTemporary ||
    161          type == quota::kStorageTypePersistent ||
    162          type == quota::kStorageTypeSyncable);
    163 
    164   PerHostStorageInfo info(host, type);
    165   info.set_usage(usage);
    166 
    167   report_pending_.push_back(info);
    168   hosts_pending_.erase(make_pair(host, type));
    169   if (report_pending_.size() >= 10 || hosts_pending_.empty()) {
    170     ReportPerHostInfo(report_pending_);
    171     report_pending_.clear();
    172   }
    173 
    174   if (!hosts_pending_.empty())
    175     GetHostUsage(hosts_pending_.begin()->first,
    176                  hosts_pending_.begin()->second);
    177 }
    178 
    179 void QuotaInternalsProxy::RequestPerOriginInfo(quota::StorageType type) {
    180   DCHECK(quota_manager_.get());
    181 
    182   std::set<GURL> origins;
    183   quota_manager_->GetCachedOrigins(type, &origins);
    184 
    185   std::vector<PerOriginStorageInfo> origin_info;
    186   origin_info.reserve(origins.size());
    187 
    188   std::set<std::string> hosts;
    189   std::vector<PerHostStorageInfo> host_info;
    190 
    191   for (std::set<GURL>::iterator itr(origins.begin());
    192        itr != origins.end(); ++itr) {
    193     PerOriginStorageInfo info(*itr, type);
    194     info.set_in_use(quota_manager_->IsOriginInUse(*itr));
    195     origin_info.push_back(info);
    196 
    197     std::string host(net::GetHostOrSpecFromURL(*itr));
    198     if (hosts.insert(host).second) {
    199       PerHostStorageInfo info(host, type);
    200       host_info.push_back(info);
    201       VisitHost(host, type);
    202     }
    203   }
    204   ReportPerOriginInfo(origin_info);
    205   ReportPerHostInfo(host_info);
    206 }
    207 
    208 void QuotaInternalsProxy::VisitHost(const std::string& host,
    209                                     quota::StorageType type) {
    210   if (hosts_visited_.insert(std::make_pair(host, type)).second) {
    211     hosts_pending_.insert(std::make_pair(host, type));
    212     if (hosts_pending_.size() == 1) {
    213       GetHostUsage(host, type);
    214     }
    215   }
    216 }
    217 
    218 void QuotaInternalsProxy::GetHostUsage(const std::string& host,
    219                                        quota::StorageType type) {
    220   DCHECK(quota_manager_.get());
    221   quota_manager_->GetHostUsage(host,
    222                                type,
    223                                base::Bind(&QuotaInternalsProxy::DidGetHostUsage,
    224                                           weak_factory_.GetWeakPtr(),
    225                                           host,
    226                                           type));
    227 }
    228 
    229 }  // namespace quota_internals
    230