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