Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/ui/webui/quota_internals_ui.h" | 5 #include "chrome/browser/ui/webui/quota_internals_ui.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <string> | 8 #include <string> |
| 9 | 9 |
| 10 #include "base/values.h" | |
| 10 #include "chrome/browser/profiles/profile.h" | 11 #include "chrome/browser/profiles/profile.h" |
| 11 #include "chrome/common/url_constants.h" | 12 #include "chrome/common/url_constants.h" |
| 12 #include "content/browser/tab_contents/tab_contents.h" | 13 #include "content/browser/tab_contents/tab_contents.h" |
| 13 #include "grit/quota_internals_resources.h" | 14 #include "grit/quota_internals_resources.h" |
| 15 #include "net/base/net_util.h" | |
| 14 #include "ui/base/resource/resource_bundle.h" | 16 #include "ui/base/resource/resource_bundle.h" |
| 15 | 17 |
| 18 namespace { | |
| 19 template<typename T> | |
| 20 std::string toString(const T& v) { | |
|
kinuko
2011/05/30 10:18:00
style-nit: please start function names with capita
tzik
2011/05/31 04:53:00
Done.
| |
| 21 std::ostringstream out; | |
| 22 out << v; | |
| 23 return out.str(); | |
| 24 } | |
| 25 | |
| 26 std::string storageTypeToString(quota::StorageType type) { | |
|
kinuko
2011/05/30 10:18:00
ditto
tzik
2011/05/31 04:53:00
Done.
| |
| 27 switch (type) { | |
| 28 case quota::kStorageTypeTemporary: | |
| 29 return "temporary"; | |
| 30 case quota::kStorageTypePersistent: | |
| 31 return "persistent"; | |
| 32 default: | |
| 33 return "unknown"; | |
| 34 } | |
| 35 } | |
| 36 } | |
|
kinuko
2011/05/30 10:18:00
style-nit: can you add a comment?
} // anonymous
tzik
2011/05/31 04:53:00
Done.
| |
| 37 | |
| 16 QuotaInternalsUI::QuotaInternalsUI(TabContents* contents) | 38 QuotaInternalsUI::QuotaInternalsUI(TabContents* contents) |
| 17 : WebUI(contents) { | 39 : WebUI(contents) { |
| 18 // TODO(tzik): implement and attach message handler | 40 WebUIMessageHandler* handler = |
| 41 new quota_internals::QuotaInternalsMessageHandler; | |
| 42 AddMessageHandler(handler->Attach(this)); | |
| 19 contents->profile()->GetChromeURLDataManager()-> | 43 contents->profile()->GetChromeURLDataManager()-> |
| 20 AddDataSource(new quota_internals::QuotaInternalsHTMLSource); | 44 AddDataSource(new quota_internals::QuotaInternalsHTMLSource); |
| 21 } | 45 } |
| 22 | 46 |
| 23 namespace quota_internals { | 47 namespace quota_internals { |
| 24 | 48 |
| 25 QuotaInternalsHTMLSource::QuotaInternalsHTMLSource() | 49 QuotaInternalsHTMLSource::QuotaInternalsHTMLSource() |
| 26 : DataSource(chrome::kChromeUIQuotaInternalsHost, | 50 : DataSource(chrome::kChromeUIQuotaInternalsHost, |
| 27 MessageLoop::current()) { | 51 MessageLoop::current()) { |
| 28 } | 52 } |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 39 std::copy(html.data(), html.data() + html.size(), html_bytes->data.begin()); | 63 std::copy(html.data(), html.data() + html.size(), html_bytes->data.begin()); |
| 40 SendResponse(request_id, html_bytes); | 64 SendResponse(request_id, html_bytes); |
| 41 return; | 65 return; |
| 42 } | 66 } |
| 43 | 67 |
| 44 std::string QuotaInternalsHTMLSource::GetMimeType( | 68 std::string QuotaInternalsHTMLSource::GetMimeType( |
| 45 const std::string& path_unused) const { | 69 const std::string& path_unused) const { |
| 46 return "text/html"; | 70 return "text/html"; |
| 47 } | 71 } |
| 48 | 72 |
| 73 QuotaInternalsMessageHandler::QuotaInternalsMessageHandler() { | |
| 74 } | |
| 75 | |
| 76 QuotaInternalsMessageHandler::~QuotaInternalsMessageHandler() { | |
| 77 if (proxy_) | |
| 78 proxy_->handler_ = NULL; | |
| 79 } | |
| 80 | |
| 81 WebUIMessageHandler* QuotaInternalsMessageHandler::Attach(WebUI* web_ui) { | |
| 82 return WebUIMessageHandler::Attach(web_ui); | |
| 83 } | |
| 84 | |
| 85 void QuotaInternalsMessageHandler::RegisterMessages() { | |
| 86 DCHECK(web_ui_); | |
| 87 web_ui_->RegisterMessageCallback( | |
| 88 "requestData", | |
| 89 NewCallback(this, &QuotaInternalsMessageHandler::OnRequestData)); | |
| 90 } | |
| 91 | |
| 92 void QuotaInternalsMessageHandler::ReportAvailableSpace( | |
| 93 int64 available_space) { | |
| 94 scoped_ptr<Value> avail( | |
| 95 Value::CreateStringValue(toString(available_space))); | |
| 96 SendMessage("AvailableSpaceUpdated", *avail.get()); | |
| 97 } | |
| 98 | |
| 99 void QuotaInternalsMessageHandler::ReportGlobalData(const GlobalData& data) { | |
| 100 DictionaryValue dict; | |
| 101 if (data.type != quota::kStorageTypeUnknown) | |
| 102 dict.SetString("type", storageTypeToString(data.type)); | |
| 103 if (data.usage >= 0) | |
| 104 dict.SetString("usage", toString(data.usage)); | |
| 105 if (data.usage >= 0) | |
|
kinuko
2011/05/30 10:18:00
data.unlimited_usage ?
tzik
2011/05/31 04:53:00
Done.
| |
| 106 dict.SetString("unlimited_usage", toString(data.unlimited_usage)); | |
| 107 if (data.quota >= 0) | |
| 108 dict.SetString("quota", toString(data.quota)); | |
|
kinuko
2011/05/30 10:18:00
Can we show these values even if they are < 0?
Hm
| |
| 109 SendMessage("GlobalDataUpdated", dict); | |
| 110 } | |
| 111 | |
| 112 void QuotaInternalsMessageHandler::ReportHostData( | |
| 113 const std::vector<HostData>& hosts) { | |
| 114 ListValue hosts_value; | |
| 115 typedef std::vector<HostData>::const_iterator iterator; | |
| 116 for (iterator itr(hosts.begin()), end(hosts.end()); | |
| 117 itr != end; ++itr) { | |
| 118 scoped_ptr<DictionaryValue> dict(new DictionaryValue); | |
| 119 if (!itr->host.empty()) | |
| 120 dict->SetString("host", itr->host); | |
| 121 if (itr->type != quota::kStorageTypeUnknown) | |
| 122 dict->SetString("type", storageTypeToString(itr->type)); | |
|
kinuko
2011/05/30 10:18:00
could we simply show "unknown" for unknown types?
tzik
2011/05/31 04:53:00
Done.
| |
| 123 if (itr->usage >= 0) | |
| 124 dict->SetString("usage", toString(itr->usage)); | |
| 125 if (itr->quota >= 0) | |
| 126 dict->SetString("quota", toString(itr->quota)); | |
| 127 hosts_value.Append(dict.release()); | |
| 128 } | |
| 129 | |
| 130 SendMessage("HostDataUpdated", hosts_value); | |
| 131 } | |
| 132 | |
| 133 void QuotaInternalsMessageHandler::ReportOriginData( | |
| 134 const std::vector<OriginData>& origins) { | |
| 135 ListValue origins_value; | |
| 136 typedef std::vector<OriginData>::const_iterator iterator; | |
| 137 for (iterator itr(origins.begin()), end(origins.end()); | |
| 138 itr != end; ++itr) { | |
| 139 scoped_ptr<DictionaryValue> dict(new DictionaryValue); | |
| 140 if (!itr->origin.is_empty()) | |
| 141 dict->SetString("origin", itr->origin.spec()); | |
| 142 if (itr->type != quota::kStorageTypeUnknown) | |
| 143 dict->SetString("type", storageTypeToString(itr->type)); | |
|
kinuko
2011/05/30 10:18:00
ditto
tzik
2011/05/31 04:53:00
Done.
| |
| 144 if (!itr->host.empty()) | |
| 145 dict->SetString("host", toString(itr->host)); | |
| 146 if (itr->in_use >= 0) | |
| 147 dict->SetBoolean("in_use", itr->in_use ? true : false); | |
| 148 if (itr->used_count >= 0) | |
| 149 dict->SetInteger("used_count", itr->used_count); | |
| 150 if (!itr->last_access_time.is_null()) | |
| 151 dict->SetDouble("last_access_time", itr->last_access_time.ToDoubleT()); | |
| 152 origins_value.Append(dict.release()); | |
| 153 } | |
| 154 | |
| 155 SendMessage("OriginDataUpdated", origins_value); | |
| 156 } | |
| 157 | |
| 158 void QuotaInternalsMessageHandler::OnRequestData(const ListValue* list) { | |
| 159 if (!proxy_) | |
| 160 proxy_ = new QuotaInternalsProxy(this); | |
| 161 proxy_->RequestData(web_ui_->GetProfile()->GetQuotaManager()); | |
| 162 } | |
| 163 | |
| 164 void QuotaInternalsMessageHandler::SendMessage(const std::string& message, | |
| 165 const Value& value) { | |
| 166 scoped_ptr<Value> message_data(Value::CreateStringValue(message)); | |
| 167 web_ui_->CallJavascriptFunction("cr.quota.messageHandler_", | |
| 168 *message_data.get(), | |
| 169 value); | |
| 170 } | |
| 171 | |
| 172 void QuotaInternalsProxy::RequestData(quota::QuotaManager* quota_manager) { | |
| 173 io_thread_->PostTask( | |
| 174 FROM_HERE, | |
| 175 NewRunnableMethod(this, &QuotaInternalsProxy::RunRequestData, | |
| 176 make_scoped_refptr(quota_manager))); | |
| 177 } | |
| 178 | |
| 179 void QuotaInternalsProxy::Destruct(const QuotaInternalsProxy* proxy) { | |
| 180 if (proxy->io_thread_->BelongsToCurrentThread()) | |
| 181 proxy->io_thread_->DeleteSoon(FROM_HERE, proxy); | |
| 182 else | |
| 183 delete proxy; | |
| 184 } | |
| 185 | |
| 186 void QuotaInternalsProxy::RunRequestData( | |
|
kinuko
2011/05/30 10:18:00
For better readability can we rename this to Reque
tzik
2011/05/31 04:53:00
Done.
| |
| 187 scoped_refptr<quota::QuotaManager> quota_manager) { | |
| 188 quota_manager_ = quota_manager->AsWeakPtr(); | |
| 189 | |
| 190 quota_manager->GetAvailableSpace( | |
| 191 callback_factory_.NewCallback( | |
| 192 &QuotaInternalsProxy::DidGetAvailableSpace)); | |
| 193 | |
| 194 quota_manager->GetTemporaryGlobalQuota( | |
| 195 callback_factory_.NewCallback( | |
| 196 &QuotaInternalsProxy::DidGetGlobalQuota)); | |
| 197 | |
| 198 quota_manager->GetGlobalUsage( | |
| 199 quota::kStorageTypeTemporary, | |
| 200 callback_factory_.NewCallback( | |
| 201 &QuotaInternalsProxy::DidGetGlobalUsage)); | |
| 202 | |
| 203 quota_manager->GetGlobalUsage( | |
| 204 quota::kStorageTypePersistent, | |
| 205 callback_factory_.NewCallback( | |
| 206 &QuotaInternalsProxy::DidGetGlobalUsage)); | |
| 207 | |
| 208 quota_manager->DumpQuotaTable( | |
| 209 callback_factory_.NewCallback( | |
| 210 &QuotaInternalsProxy::DidDumpQuotaTable)); | |
| 211 | |
| 212 quota_manager->DumpLastAccessTimeTable( | |
| 213 callback_factory_.NewCallback( | |
| 214 &QuotaInternalsProxy::DidDumpLastAccessTimeTable)); | |
| 215 } | |
| 216 | |
| 217 QuotaInternalsProxy::QuotaInternalsProxy( | |
| 218 QuotaInternalsMessageHandler* handler) | |
| 219 : io_thread_( | |
| 220 BrowserThread::GetMessageLoopProxyForThread( | |
| 221 BrowserThread::IO)), | |
| 222 ui_thread_( | |
| 223 BrowserThread::GetMessageLoopProxyForThread( | |
| 224 BrowserThread::UI)), | |
|
kinuko
2011/05/30 10:18:00
You could use BrowserThread::PostTask(BrowserThrea
tzik
2011/05/31 04:53:00
Done.
| |
| 225 handler_(handler), | |
| 226 callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { | |
| 227 } | |
| 228 | |
| 229 void QuotaInternalsProxy::ReportAvailableSpace(int64 available_space) { | |
| 230 ui_thread_->PostTask( | |
| 231 FROM_HERE, | |
| 232 NewRunnableMethod( | |
| 233 this, &QuotaInternalsProxy::RunReportAvailableSpace, | |
| 234 available_space)); | |
| 235 } | |
| 236 | |
| 237 void QuotaInternalsProxy::RunReportAvailableSpace(int64 available_space) { | |
| 238 if (handler_) | |
| 239 handler_->ReportAvailableSpace(available_space); | |
| 240 } | |
| 241 | |
| 242 void QuotaInternalsProxy::ReportGlobalData(const GlobalData& data) { | |
| 243 ui_thread_->PostTask( | |
| 244 FROM_HERE, | |
| 245 NewRunnableMethod( | |
| 246 this, &QuotaInternalsProxy::RunReportGlobalData, | |
| 247 data)); | |
| 248 } | |
| 249 | |
| 250 void QuotaInternalsProxy::RunReportGlobalData(const GlobalData& data) { | |
| 251 if (handler_) | |
| 252 handler_->ReportGlobalData(data); | |
| 253 } | |
| 254 | |
| 255 void QuotaInternalsProxy::ReportHostData( | |
| 256 const std::vector<HostData>& hosts) { | |
| 257 ui_thread_->PostTask( | |
| 258 FROM_HERE, | |
| 259 NewRunnableMethod( | |
| 260 this, &QuotaInternalsProxy::RunReportHostData, | |
| 261 hosts)); | |
| 262 } | |
| 263 | |
| 264 void QuotaInternalsProxy::RunReportHostData( | |
|
kinuko
2011/05/30 10:18:00
For better readability can we rename this to Repor
tzik
2011/05/31 04:53:00
Done.
| |
| 265 const std::vector<HostData>& hosts) { | |
| 266 if (handler_) | |
| 267 handler_->ReportHostData(hosts); | |
| 268 } | |
| 269 | |
| 270 void QuotaInternalsProxy::ReportOriginData( | |
| 271 const std::vector<OriginData>& origins) { | |
| 272 ui_thread_->PostTask( | |
| 273 FROM_HERE, | |
| 274 NewRunnableMethod( | |
| 275 this, &QuotaInternalsProxy::RunReportOriginData, | |
| 276 origins)); | |
| 277 } | |
| 278 | |
| 279 void QuotaInternalsProxy::RunReportOriginData( | |
|
kinuko
2011/05/30 10:18:00
For better readability can we rename this to Repor
tzik
2011/05/31 04:53:00
Done.
| |
| 280 const std::vector<OriginData>& origins) { | |
| 281 if (handler_) | |
| 282 handler_->ReportOriginData(origins); | |
| 283 } | |
| 284 | |
| 285 void QuotaInternalsProxy::DidGetAvailableSpace(quota::QuotaStatusCode status, | |
| 286 int64 space) { | |
| 287 if (status == quota::kQuotaStatusOk) | |
| 288 ReportAvailableSpace(space); | |
| 289 } | |
| 290 | |
| 291 void QuotaInternalsProxy::DidGetGlobalQuota( | |
| 292 quota::QuotaStatusCode status, | |
| 293 quota::StorageType type, | |
| 294 int64 quota) { | |
| 295 if (status == quota::kQuotaStatusOk) | |
| 296 ReportGlobalData((GlobalData) {type, -1, -1, quota}); | |
|
kinuko
2011/05/30 10:18:00
I might make this a constructor.
qq: do they need
tzik
2011/05/31 04:53:00
Done.
| |
| 297 } | |
| 298 | |
| 299 void QuotaInternalsProxy::DidGetGlobalUsage(quota::StorageType type, | |
| 300 int64 usage, | |
| 301 int64 unlimited_usage) { | |
| 302 ReportGlobalData((GlobalData) {type, usage, unlimited_usage, -1}); | |
| 303 RequestPerOriginData(type); | |
| 304 } | |
| 305 | |
| 306 void QuotaInternalsProxy::RequestPerOriginData(quota::StorageType type) { | |
| 307 if (!quota_manager_) | |
| 308 return; | |
| 309 | |
| 310 std::set<GURL> origins; | |
| 311 quota_manager_->GetCachedOrigins(type, &origins); | |
| 312 | |
| 313 std::vector<OriginData> origin_data; | |
| 314 origin_data.reserve(origins.size()); | |
| 315 | |
| 316 std::set<std::string> hosts; | |
| 317 std::vector<HostData> host_data; | |
| 318 | |
| 319 for (std::set<GURL>::iterator itr(origins.begin()), end(origins.end()); | |
| 320 itr != end; ++itr) { | |
| 321 std::string host = net::GetHostOrSpecFromURL(*itr); | |
| 322 origin_data.push_back( | |
| 323 (OriginData) { | |
| 324 *itr, | |
| 325 type, | |
| 326 host, | |
| 327 quota_manager_->IsOriginInUse(*itr) ? 1 : 0, | |
| 328 -1, | |
| 329 base::Time(), | |
| 330 }); | |
| 331 if (hosts.insert(host).second) { | |
| 332 host_data.push_back( | |
| 333 (HostData) {host, type, -1, -1}); | |
| 334 VisitHost(host, type); | |
| 335 } | |
| 336 } | |
| 337 ReportOriginData(origin_data); | |
| 338 ReportHostData(host_data); | |
| 339 } | |
| 340 | |
| 341 void QuotaInternalsProxy::VisitHost(const std::string& host, | |
| 342 quota::StorageType type) { | |
| 343 if (hosts_visited_.insert(std::make_pair(host, type)).second) { | |
| 344 hosts_pending_.insert(std::make_pair(host, type)); | |
| 345 if (hosts_pending_.size() == 1) { | |
| 346 GetHostUsage(host, type); | |
| 347 } | |
| 348 } | |
| 349 } | |
| 350 | |
| 351 void QuotaInternalsProxy::GetHostUsage(const std::string& host, | |
| 352 quota::StorageType type) { | |
| 353 if (quota_manager_) | |
| 354 quota_manager_->GetHostUsage( | |
| 355 host, type, | |
| 356 callback_factory_.NewCallback( | |
| 357 &QuotaInternalsProxy::DidGetHostUsage)); | |
| 358 } | |
| 359 | |
| 360 | |
| 361 void QuotaInternalsProxy::DidDumpQuotaTable( | |
| 362 const QuotaTableEntries& entries) { | |
| 363 std::vector<HostData> host_data; | |
| 364 host_data.reserve(entries.size()); | |
| 365 | |
| 366 typedef QuotaTableEntries::const_iterator iterator; | |
| 367 for (iterator itr(entries.begin()), end(entries.end()); | |
| 368 itr != end; ++itr) { | |
| 369 host_data.push_back( | |
| 370 (HostData) { | |
| 371 itr->host, | |
| 372 itr->type, | |
| 373 -1, | |
| 374 itr->quota, | |
| 375 }); | |
| 376 } | |
| 377 ReportHostData(host_data); | |
| 378 } | |
| 379 | |
| 380 void QuotaInternalsProxy::DidDumpLastAccessTimeTable( | |
| 381 const LastAccessTimeTableEntries& entries) { | |
| 382 std::vector<OriginData> origin_data; | |
| 383 origin_data.reserve(entries.size()); | |
| 384 | |
| 385 typedef LastAccessTimeTableEntries::const_iterator iterator; | |
| 386 for (iterator itr(entries.begin()), end(entries.end()); | |
| 387 itr != end; ++itr) { | |
| 388 origin_data.push_back( | |
| 389 (OriginData) { | |
| 390 itr->origin, | |
| 391 itr->type, | |
| 392 std::string(), | |
| 393 -1, | |
| 394 itr->used_count, | |
| 395 itr->last_access_time, | |
| 396 }); | |
| 397 } | |
| 398 ReportOriginData(origin_data); | |
| 399 } | |
| 400 | |
| 401 void QuotaInternalsProxy::DidGetHostUsage( | |
| 402 const std::string& host, quota::StorageType type, int64 usage) { | |
| 403 DCHECK(type == quota::kStorageTypeTemporary || | |
| 404 type == quota::kStorageTypePersistent); | |
| 405 | |
| 406 report_pending_.push_back( | |
| 407 (HostData) {host, type, usage, -1}); | |
| 408 hosts_pending_.erase(make_pair(host, type)); | |
| 409 if (report_pending_.size() >= 10 || hosts_pending_.empty()) { | |
| 410 ReportHostData(report_pending_); | |
| 411 report_pending_.clear(); | |
| 412 } | |
| 413 | |
| 414 if (!hosts_pending_.empty()) | |
| 415 GetHostUsage(hosts_pending_.begin()->first, | |
| 416 hosts_pending_.begin()->second); | |
| 417 } | |
| 49 } // namespace quota_internals | 418 } // namespace quota_internals |
| OLD | NEW |