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 |