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 15using content::BrowserThread; 16 17namespace quota_internals { 18 19QuotaInternalsProxy::QuotaInternalsProxy(QuotaInternalsHandler* handler) 20 : handler_(handler), 21 weak_factory_(this) { 22} 23 24void 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 74QuotaInternalsProxy::~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 90RELAY_TO_HANDLER(ReportAvailableSpace, int64) 91RELAY_TO_HANDLER(ReportGlobalInfo, const GlobalStorageInfo&) 92RELAY_TO_HANDLER(ReportPerHostInfo, const std::vector<PerHostStorageInfo>&) 93RELAY_TO_HANDLER(ReportPerOriginInfo, const std::vector<PerOriginStorageInfo>&) 94RELAY_TO_HANDLER(ReportStatistics, const Statistics&) 95 96#undef RELAY_TO_HANDLER 97 98void QuotaInternalsProxy::DidGetAvailableSpace(quota::QuotaStatusCode status, 99 int64 space) { 100 if (status == quota::kQuotaStatusOk) 101 ReportAvailableSpace(space); 102} 103 104void 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 114void 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 125void 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 139void 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 157void 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 179void 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 208void 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 218void 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