OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2011 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_handler.h" |
| 6 |
| 7 #include <algorithm> |
| 8 #include <set> |
| 9 #include <string> |
| 10 |
| 11 #include "base/values.h" |
| 12 #include "chrome/browser/profiles/profile.h" |
| 13 #include "chrome/common/url_constants.h" |
| 14 #include "content/browser/tab_contents/tab_contents.h" |
| 15 #include "grit/quota_internals_resources.h" |
| 16 #include "net/base/net_util.h" |
| 17 #include "ui/base/resource/resource_bundle.h" |
| 18 |
| 19 namespace { |
| 20 |
| 21 std::string StorageTypeToString(quota::StorageType type) { |
| 22 switch (type) { |
| 23 case quota::kStorageTypeTemporary: |
| 24 return "temporary"; |
| 25 case quota::kStorageTypePersistent: |
| 26 return "persistent"; |
| 27 default: |
| 28 return "unknown"; |
| 29 } |
| 30 } |
| 31 |
| 32 } // anonymous namespace |
| 33 |
| 34 namespace quota_internals { |
| 35 |
| 36 GlobalData::GlobalData(quota::StorageType type, |
| 37 int64 usage, |
| 38 int64 unlimited_usage, |
| 39 int64 quota) |
| 40 : type_(type), |
| 41 usage_(usage), |
| 42 unlimited_usage_(unlimited_usage), |
| 43 quota_(quota) { |
| 44 } |
| 45 |
| 46 Value* GlobalData::NewValue() const { |
| 47 scoped_ptr<DictionaryValue> dict(new DictionaryValue); |
| 48 dict->SetString("type", StorageTypeToString(type_)); |
| 49 if (usage_ >= 0) |
| 50 dict->SetDouble("usage", static_cast<double>(usage_)); |
| 51 if (unlimited_usage_ >= 0) |
| 52 dict->SetDouble("unlimitedUsage", static_cast<double>(unlimited_usage_)); |
| 53 if (quota_ >= 0) |
| 54 dict->SetDouble("quota", static_cast<double>(quota_)); |
| 55 return dict.release(); |
| 56 } |
| 57 |
| 58 HostData::HostData(const std::string& host, |
| 59 quota::StorageType type, |
| 60 int64 usage, |
| 61 int64 quota) |
| 62 : host_(host), |
| 63 type_(type), |
| 64 usage_(usage), |
| 65 quota_(quota) { |
| 66 } |
| 67 |
| 68 Value* HostData::NewValue() const { |
| 69 scoped_ptr<DictionaryValue> dict(new DictionaryValue); |
| 70 DCHECK(!host_.empty()); |
| 71 dict->SetString("host", host_); |
| 72 dict->SetString("type", StorageTypeToString(type_)); |
| 73 if (usage_ >= 0) |
| 74 dict->SetDouble("usage", static_cast<double>(usage_)); |
| 75 if (quota_ >= 0) |
| 76 dict->SetDouble("quota", static_cast<double>(quota_)); |
| 77 return dict.release(); |
| 78 } |
| 79 |
| 80 OriginData::OriginData(const GURL& origin, |
| 81 quota::StorageType type, |
| 82 int in_use, |
| 83 int used_count, |
| 84 base::Time last_access_time, |
| 85 base::Time last_modified_time) |
| 86 : origin_(origin), |
| 87 type_(type), |
| 88 host_(net::GetHostOrSpecFromURL(origin)), |
| 89 in_use_(in_use), |
| 90 used_count_(used_count), |
| 91 last_access_time_(last_access_time), |
| 92 last_modified_time_(last_modified_time) { |
| 93 } |
| 94 |
| 95 Value* OriginData::NewValue() const { |
| 96 scoped_ptr<DictionaryValue> dict(new DictionaryValue); |
| 97 DCHECK(!origin_.is_empty()); |
| 98 DCHECK(!host_.empty()); |
| 99 dict->SetString("origin", origin_.spec()); |
| 100 dict->SetString("type", StorageTypeToString(type_)); |
| 101 dict->SetString("host", host_); |
| 102 if (in_use_ >= 0) |
| 103 dict->SetBoolean("inUse", in_use_ ? true : false); |
| 104 if (used_count_ >= 0) |
| 105 dict->SetInteger("usedCount", used_count_); |
| 106 if (!last_access_time_.is_null()) |
| 107 dict->SetDouble("lastAccessTime", last_access_time_.ToDoubleT() * 1000.0); |
| 108 if (!last_modified_time_.is_null()) |
| 109 dict->SetDouble("lastModifiedTime", |
| 110 last_modified_time_.ToDoubleT() * 1000.0); |
| 111 return dict.release(); |
| 112 } |
| 113 |
| 114 QuotaInternalsHandler::QuotaInternalsHandler() {} |
| 115 |
| 116 QuotaInternalsHandler::~QuotaInternalsHandler() { |
| 117 if (proxy_) |
| 118 proxy_->handler_ = NULL; |
| 119 } |
| 120 |
| 121 void QuotaInternalsHandler::RegisterMessages() OVERRIDE { |
| 122 DCHECK(web_ui_); |
| 123 web_ui_->RegisterMessageCallback( |
| 124 "requestData", |
| 125 NewCallback(this, &QuotaInternalsHandler::OnRequestData)); |
| 126 } |
| 127 |
| 128 void QuotaInternalsHandler::ReportAvailableSpace(int64 available_space) { |
| 129 scoped_ptr<Value> avail( |
| 130 Value::CreateDoubleValue(static_cast<double>(available_space))); |
| 131 SendMessage("AvailableSpaceUpdated", *avail.get()); |
| 132 } |
| 133 |
| 134 void QuotaInternalsHandler::ReportGlobalData(const GlobalData& data) { |
| 135 scoped_ptr<Value> value(data.NewValue()); |
| 136 SendMessage("GlobalDataUpdated", *value); |
| 137 } |
| 138 |
| 139 void QuotaInternalsHandler::ReportHostData(const std::vector<HostData>& hosts) { |
| 140 ListValue values; |
| 141 typedef std::vector<HostData>::const_iterator iterator; |
| 142 for (iterator itr(hosts.begin()); itr != hosts.end(); ++itr) { |
| 143 values.Append(itr->NewValue()); |
| 144 } |
| 145 |
| 146 SendMessage("HostDataUpdated", values); |
| 147 } |
| 148 |
| 149 void QuotaInternalsHandler::ReportOriginData( |
| 150 const std::vector<OriginData>& origins) { |
| 151 ListValue origins_value; |
| 152 typedef std::vector<OriginData>::const_iterator iterator; |
| 153 for (iterator itr(origins.begin()); itr != origins.end(); ++itr) { |
| 154 origins_value.Append(itr->NewValue()); |
| 155 } |
| 156 |
| 157 SendMessage("OriginDataUpdated", origins_value); |
| 158 } |
| 159 |
| 160 void QuotaInternalsHandler::ReportStatistics(const Statistics& stats) { |
| 161 DictionaryValue dict; |
| 162 typedef Statistics::const_iterator iterator; |
| 163 for (iterator itr(stats.begin()); itr != stats.end(); ++itr) { |
| 164 dict.SetString(itr->first, itr->second); |
| 165 } |
| 166 |
| 167 SendMessage("StatisticsUpdated", dict); |
| 168 } |
| 169 |
| 170 void QuotaInternalsHandler::SendMessage(const std::string& message, |
| 171 const Value& value) { |
| 172 scoped_ptr<Value> message_data(Value::CreateStringValue(message)); |
| 173 web_ui_->CallJavascriptFunction("cr.quota.messageHandler", |
| 174 *message_data, |
| 175 value); |
| 176 } |
| 177 |
| 178 void QuotaInternalsHandler::OnRequestData(const ListValue*) { |
| 179 if (!proxy_) |
| 180 proxy_ = new QuotaInternalsProxy(this); |
| 181 proxy_->RequestData(web_ui_->GetProfile()->GetQuotaManager()); |
| 182 } |
| 183 |
| 184 QuotaInternalsProxy::QuotaInternalsProxy(QuotaInternalsHandler* handler) |
| 185 : handler_(handler), |
| 186 callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { |
| 187 } |
| 188 |
| 189 void QuotaInternalsProxy::ReportAvailableSpace(int64 available_space) { |
| 190 BrowserThread::PostTask( |
| 191 BrowserThread::UI, FROM_HERE, |
| 192 NewRunnableMethod( |
| 193 this, &QuotaInternalsProxy::RunReportAvailableSpaceOnUIThread, |
| 194 available_space)); |
| 195 } |
| 196 |
| 197 void QuotaInternalsProxy::ReportGlobalData(const GlobalData& data) { |
| 198 BrowserThread::PostTask( |
| 199 BrowserThread::UI, FROM_HERE, |
| 200 NewRunnableMethod( |
| 201 this, &QuotaInternalsProxy::RunReportGlobalDataOnUIThread, |
| 202 data)); |
| 203 } |
| 204 |
| 205 void QuotaInternalsProxy::ReportHostData(const std::vector<HostData>& hosts) { |
| 206 BrowserThread::PostTask( |
| 207 BrowserThread::UI, FROM_HERE, |
| 208 NewRunnableMethod( |
| 209 this, &QuotaInternalsProxy::RunReportHostDataOnUIThread, |
| 210 hosts)); |
| 211 } |
| 212 |
| 213 void QuotaInternalsProxy::ReportOriginData( |
| 214 const std::vector<OriginData>& origins) { |
| 215 BrowserThread::PostTask( |
| 216 BrowserThread::UI, FROM_HERE, |
| 217 NewRunnableMethod( |
| 218 this, &QuotaInternalsProxy::RunReportOriginDataOnUIThread, |
| 219 origins)); |
| 220 } |
| 221 |
| 222 void QuotaInternalsProxy::ReportStatistics(const Statistics& stats) { |
| 223 BrowserThread::PostTask( |
| 224 BrowserThread::UI, FROM_HERE, |
| 225 NewRunnableMethod( |
| 226 this, &QuotaInternalsProxy::RunReportStatisticsOnUIThread, |
| 227 stats)); |
| 228 } |
| 229 |
| 230 void QuotaInternalsProxy::RequestData(quota::QuotaManager* quota_manager) { |
| 231 DCHECK(quota_manager); |
| 232 quota_manager_ = quota_manager; |
| 233 BrowserThread::PostTask( |
| 234 BrowserThread::IO, FROM_HERE, |
| 235 NewRunnableMethod(this, &QuotaInternalsProxy::RunRequestDataOnIOThread)); |
| 236 } |
| 237 |
| 238 void QuotaInternalsProxy::RunReportAvailableSpaceOnUIThread( |
| 239 int64 available_space) { |
| 240 if (handler_) |
| 241 handler_->ReportAvailableSpace(available_space); |
| 242 } |
| 243 |
| 244 void QuotaInternalsProxy::RunReportGlobalDataOnUIThread( |
| 245 const GlobalData& data) { |
| 246 if (handler_) |
| 247 handler_->ReportGlobalData(data); |
| 248 } |
| 249 |
| 250 void QuotaInternalsProxy::RunReportHostDataOnUIThread( |
| 251 const std::vector<HostData>& hosts) { |
| 252 if (handler_) |
| 253 handler_->ReportHostData(hosts); |
| 254 } |
| 255 |
| 256 void QuotaInternalsProxy::RunReportOriginDataOnUIThread( |
| 257 const std::vector<OriginData>& origins) { |
| 258 if (handler_) |
| 259 handler_->ReportOriginData(origins); |
| 260 } |
| 261 |
| 262 void QuotaInternalsProxy::RunReportStatisticsOnUIThread( |
| 263 const Statistics& stats) { |
| 264 if (handler_) |
| 265 handler_->ReportStatistics(stats); |
| 266 } |
| 267 |
| 268 void QuotaInternalsProxy::RunRequestDataOnIOThread() { |
| 269 DCHECK(quota_manager_); |
| 270 quota_manager_->GetAvailableSpace( |
| 271 callback_factory_.NewCallback( |
| 272 &QuotaInternalsProxy::DidGetAvailableSpace)); |
| 273 |
| 274 quota_manager_->GetTemporaryGlobalQuota( |
| 275 callback_factory_.NewCallback( |
| 276 &QuotaInternalsProxy::DidGetGlobalQuota)); |
| 277 |
| 278 quota_manager_->GetGlobalUsage( |
| 279 quota::kStorageTypeTemporary, |
| 280 callback_factory_.NewCallback( |
| 281 &QuotaInternalsProxy::DidGetGlobalUsage)); |
| 282 |
| 283 quota_manager_->GetGlobalUsage( |
| 284 quota::kStorageTypePersistent, |
| 285 callback_factory_.NewCallback( |
| 286 &QuotaInternalsProxy::DidGetGlobalUsage)); |
| 287 |
| 288 quota_manager_->DumpQuotaTable( |
| 289 callback_factory_.NewCallback( |
| 290 &QuotaInternalsProxy::DidDumpQuotaTable)); |
| 291 |
| 292 quota_manager_->DumpOriginInfoTable( |
| 293 callback_factory_.NewCallback( |
| 294 &QuotaInternalsProxy::DidDumpOriginInfoTable)); |
| 295 |
| 296 std::map<std::string, std::string> stats; |
| 297 quota_manager_->GetStatistics(&stats); |
| 298 ReportStatistics(stats); |
| 299 } |
| 300 |
| 301 void QuotaInternalsProxy::DidGetAvailableSpace(quota::QuotaStatusCode status, |
| 302 int64 space) { |
| 303 if (status == quota::kQuotaStatusOk) |
| 304 ReportAvailableSpace(space); |
| 305 } |
| 306 |
| 307 void QuotaInternalsProxy::DidGetGlobalQuota(quota::QuotaStatusCode status, |
| 308 quota::StorageType type, |
| 309 int64 quota) { |
| 310 if (status == quota::kQuotaStatusOk) |
| 311 ReportGlobalData(GlobalData(type, -1, -1, quota)); |
| 312 } |
| 313 |
| 314 void QuotaInternalsProxy::DidGetGlobalUsage(quota::StorageType type, |
| 315 int64 usage, |
| 316 int64 unlimited_usage) { |
| 317 ReportGlobalData(GlobalData(type, usage, unlimited_usage, -1)); |
| 318 RequestPerOriginData(type); |
| 319 } |
| 320 |
| 321 void QuotaInternalsProxy::DidDumpQuotaTable(const QuotaTableEntries& entries) { |
| 322 std::vector<HostData> host_data; |
| 323 host_data.reserve(entries.size()); |
| 324 |
| 325 typedef QuotaTableEntries::const_iterator iterator; |
| 326 for (iterator itr(entries.begin()); itr != entries.end(); ++itr) { |
| 327 host_data.push_back(HostData(itr->host, itr->type, -1, itr->quota)); |
| 328 } |
| 329 |
| 330 ReportHostData(host_data); |
| 331 } |
| 332 |
| 333 void QuotaInternalsProxy::DidDumpOriginInfoTable( |
| 334 const OriginInfoTableEntries& entries) { |
| 335 std::vector<OriginData> origin_data; |
| 336 origin_data.reserve(entries.size()); |
| 337 |
| 338 typedef OriginInfoTableEntries::const_iterator iterator; |
| 339 for (iterator itr(entries.begin()); itr != entries.end(); ++itr) { |
| 340 origin_data.push_back( |
| 341 OriginData(itr->origin, itr->type, |
| 342 -1, itr->used_count, |
| 343 itr->last_access_time, |
| 344 itr->last_modified_time)); |
| 345 } |
| 346 |
| 347 ReportOriginData(origin_data); |
| 348 } |
| 349 |
| 350 void QuotaInternalsProxy::DidGetHostUsage(const std::string& host, |
| 351 quota::StorageType type, |
| 352 int64 usage) { |
| 353 DCHECK(type == quota::kStorageTypeTemporary || |
| 354 type == quota::kStorageTypePersistent); |
| 355 |
| 356 report_pending_.push_back(HostData(host, type, usage, -1)); |
| 357 hosts_pending_.erase(make_pair(host, type)); |
| 358 if (report_pending_.size() >= 10 || hosts_pending_.empty()) { |
| 359 ReportHostData(report_pending_); |
| 360 report_pending_.clear(); |
| 361 } |
| 362 |
| 363 if (!hosts_pending_.empty()) |
| 364 GetHostUsage(hosts_pending_.begin()->first, |
| 365 hosts_pending_.begin()->second); |
| 366 } |
| 367 |
| 368 void QuotaInternalsProxy::VisitHost(const std::string& host, |
| 369 quota::StorageType type) { |
| 370 if (hosts_visited_.insert(std::make_pair(host, type)).second) { |
| 371 hosts_pending_.insert(std::make_pair(host, type)); |
| 372 if (hosts_pending_.size() == 1) { |
| 373 GetHostUsage(host, type); |
| 374 } |
| 375 } |
| 376 } |
| 377 |
| 378 void QuotaInternalsProxy::GetHostUsage(const std::string& host, |
| 379 quota::StorageType type) { |
| 380 DCHECK(quota_manager_); |
| 381 quota_manager_->GetHostUsage( |
| 382 host, type, |
| 383 callback_factory_.NewCallback( |
| 384 &QuotaInternalsProxy::DidGetHostUsage)); |
| 385 } |
| 386 |
| 387 void QuotaInternalsProxy::RequestPerOriginData(quota::StorageType type) { |
| 388 DCHECK(quota_manager_); |
| 389 |
| 390 std::set<GURL> origins; |
| 391 quota_manager_->GetCachedOrigins(type, &origins); |
| 392 |
| 393 std::vector<OriginData> origin_data; |
| 394 origin_data.reserve(origins.size()); |
| 395 |
| 396 std::set<std::string> hosts; |
| 397 std::vector<HostData> host_data; |
| 398 |
| 399 for (std::set<GURL>::iterator itr(origins.begin()); |
| 400 itr != origins.end(); ++itr) { |
| 401 origin_data.push_back( |
| 402 OriginData(*itr, type, |
| 403 quota_manager_->IsOriginInUse(*itr) ? 1 : 0, -1, |
| 404 base::Time(), |
| 405 base::Time())); |
| 406 |
| 407 std::string host(net::GetHostOrSpecFromURL(*itr)); |
| 408 if (hosts.insert(host).second) { |
| 409 host_data.push_back(HostData(host, type, -1, -1)); |
| 410 VisitHost(host, type); |
| 411 } |
| 412 } |
| 413 ReportOriginData(origin_data); |
| 414 ReportHostData(host_data); |
| 415 } |
| 416 |
| 417 } // namespace quota_internals |
OLD | NEW |