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<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 75QuotaInternalsProxy::~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 91RELAY_TO_HANDLER(ReportAvailableSpace, int64) 92RELAY_TO_HANDLER(ReportGlobalInfo, const GlobalStorageInfo&) 93RELAY_TO_HANDLER(ReportPerHostInfo, const std::vector<PerHostStorageInfo>&) 94RELAY_TO_HANDLER(ReportPerOriginInfo, const std::vector<PerOriginStorageInfo>&) 95RELAY_TO_HANDLER(ReportStatistics, const Statistics&) 96 97#undef RELAY_TO_HANDLER 98 99void QuotaInternalsProxy::DidGetAvailableSpace(storage::QuotaStatusCode status, 100 int64 space) { 101 if (status == storage::kQuotaStatusOk) 102 ReportAvailableSpace(space); 103} 104 105void 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 115void 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 126void 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 140void 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 158void 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 180void 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 209void 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 219void 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