OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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/dom_ui/net_internals_ui.h" | 5 #include "chrome/browser/dom_ui/net_internals_ui.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <string> | 8 #include <string> |
9 #include <utility> | 9 #include <utility> |
10 #include <vector> | 10 #include <vector> |
(...skipping 12 matching lines...) Expand all Loading... |
23 #include "chrome/browser/browser_process.h" | 23 #include "chrome/browser/browser_process.h" |
24 #include "chrome/browser/browser_thread.h" | 24 #include "chrome/browser/browser_thread.h" |
25 #include "chrome/browser/dom_ui/chrome_url_data_manager.h" | 25 #include "chrome/browser/dom_ui/chrome_url_data_manager.h" |
26 #include "chrome/browser/io_thread.h" | 26 #include "chrome/browser/io_thread.h" |
27 #include "chrome/browser/net/chrome_net_log.h" | 27 #include "chrome/browser/net/chrome_net_log.h" |
28 #include "chrome/browser/net/connection_tester.h" | 28 #include "chrome/browser/net/connection_tester.h" |
29 #include "chrome/browser/net/passive_log_collector.h" | 29 #include "chrome/browser/net/passive_log_collector.h" |
30 #include "chrome/browser/net/url_fixer_upper.h" | 30 #include "chrome/browser/net/url_fixer_upper.h" |
31 #include "chrome/browser/platform_util.h" | 31 #include "chrome/browser/platform_util.h" |
32 #include "chrome/browser/profiles/profile.h" | 32 #include "chrome/browser/profiles/profile.h" |
| 33 #include "chrome/browser/shell_dialogs.h" |
| 34 #include "chrome/browser/tab_contents/tab_contents.h" |
| 35 #include "chrome/browser/tab_contents/tab_contents_view.h" |
33 #include "chrome/common/chrome_paths.h" | 36 #include "chrome/common/chrome_paths.h" |
34 #include "chrome/common/chrome_version_info.h" | 37 #include "chrome/common/chrome_version_info.h" |
35 #include "chrome/common/jstemplate_builder.h" | 38 #include "chrome/common/jstemplate_builder.h" |
36 #include "chrome/common/net/url_request_context_getter.h" | 39 #include "chrome/common/net/url_request_context_getter.h" |
37 #include "chrome/common/url_constants.h" | 40 #include "chrome/common/url_constants.h" |
38 #include "grit/generated_resources.h" | 41 #include "grit/generated_resources.h" |
39 #include "grit/net_internals_resources.h" | 42 #include "grit/net_internals_resources.h" |
40 #include "net/base/escape.h" | 43 #include "net/base/escape.h" |
41 #include "net/base/host_resolver_impl.h" | 44 #include "net/base/host_resolver_impl.h" |
42 #include "net/base/net_errors.h" | 45 #include "net/base/net_errors.h" |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
127 // Note that the DOMUI infrastructure runs on the UI thread, therefore all of | 130 // Note that the DOMUI infrastructure runs on the UI thread, therefore all of |
128 // this class's methods are expected to run on the UI thread. | 131 // this class's methods are expected to run on the UI thread. |
129 // | 132 // |
130 // Since the network code we want to run lives on the IO thread, we proxy | 133 // Since the network code we want to run lives on the IO thread, we proxy |
131 // everything over to NetInternalsMessageHandler::IOThreadImpl, which runs | 134 // everything over to NetInternalsMessageHandler::IOThreadImpl, which runs |
132 // on the IO thread. | 135 // on the IO thread. |
133 // | 136 // |
134 // TODO(eroman): Can we start on the IO thread to begin with? | 137 // TODO(eroman): Can we start on the IO thread to begin with? |
135 class NetInternalsMessageHandler | 138 class NetInternalsMessageHandler |
136 : public DOMMessageHandler, | 139 : public DOMMessageHandler, |
| 140 public SelectFileDialog::Listener, |
137 public base::SupportsWeakPtr<NetInternalsMessageHandler> { | 141 public base::SupportsWeakPtr<NetInternalsMessageHandler> { |
138 public: | 142 public: |
139 NetInternalsMessageHandler(); | 143 NetInternalsMessageHandler(); |
140 virtual ~NetInternalsMessageHandler(); | 144 virtual ~NetInternalsMessageHandler(); |
141 | 145 |
142 // DOMMessageHandler implementation. | 146 // DOMMessageHandler implementation. |
143 virtual DOMMessageHandler* Attach(DOMUI* dom_ui); | 147 virtual DOMMessageHandler* Attach(DOMUI* dom_ui); |
144 virtual void RegisterMessages(); | 148 virtual void RegisterMessages(); |
145 | 149 |
146 // Executes the javascript function |function_name| in the renderer, passing | 150 // Executes the javascript function |function_name| in the renderer, passing |
147 // it the argument |value|. | 151 // it the argument |value|. |
148 void CallJavascriptFunction(const std::wstring& function_name, | 152 void CallJavascriptFunction(const std::wstring& function_name, |
149 const Value* value); | 153 const Value* value); |
150 | 154 |
| 155 // SelectFileDialog::Listener implementation |
| 156 virtual void FileSelected(const FilePath& path, int index, void* params); |
| 157 virtual void FileSelectionCanceled(void* params); |
| 158 |
| 159 // The only callback handled on the UI thread. As it needs to access fields |
| 160 // from |dom_ui_|, it can't be called on the IO thread. |
| 161 void OnLoadLogFile(const ListValue* list); |
| 162 |
151 private: | 163 private: |
152 class IOThreadImpl; | 164 class IOThreadImpl; |
153 | 165 |
| 166 // Task run on the FILE thread to read the contents of a log file. The result |
| 167 // is then passed to IOThreadImpl's CallJavascriptFunction, which sends it |
| 168 // back to the web page. IOThreadImpl is used instead of the |
| 169 // NetInternalsMessageHandler directly because it checks if the message |
| 170 // handler has been destroyed in the meantime. |
| 171 class ReadLogFileTask : public Task { |
| 172 public: |
| 173 ReadLogFileTask(IOThreadImpl* proxy, const FilePath& path); |
| 174 |
| 175 virtual void Run(); |
| 176 |
| 177 private: |
| 178 // IOThreadImpl implements existence checks already. Simpler to reused them |
| 179 // then to reimplement them. |
| 180 scoped_refptr<IOThreadImpl> proxy_; |
| 181 |
| 182 // Path of the file to open. |
| 183 const FilePath path_; |
| 184 }; |
| 185 |
154 // This is the "real" message handler, which lives on the IO thread. | 186 // This is the "real" message handler, which lives on the IO thread. |
155 scoped_refptr<IOThreadImpl> proxy_; | 187 scoped_refptr<IOThreadImpl> proxy_; |
156 | 188 |
| 189 // Used for loading log files. |
| 190 scoped_refptr<SelectFileDialog> select_log_file_dialog_; |
| 191 |
157 DISALLOW_COPY_AND_ASSIGN(NetInternalsMessageHandler); | 192 DISALLOW_COPY_AND_ASSIGN(NetInternalsMessageHandler); |
158 }; | 193 }; |
159 | 194 |
160 // This class is the "real" message handler. It is allocated and destroyed on | 195 // This class is the "real" message handler. It is allocated and destroyed on |
161 // the UI thread. With the exception of OnAddEntry, OnDOMUIDeleted, and | 196 // the UI thread. With the exception of OnAddEntry, OnDOMUIDeleted, and |
162 // CallJavascriptFunction, its methods are all expected to be called from the IO | 197 // CallJavascriptFunction, its methods are all expected to be called from the IO |
163 // thread. OnAddEntry and CallJavascriptFunction can be called from any thread, | 198 // thread. OnAddEntry and CallJavascriptFunction can be called from any thread, |
164 // and OnDOMUIDeleted can only be called from the UI thread. | 199 // and OnDOMUIDeleted can only be called from the UI thread. |
165 class NetInternalsMessageHandler::IOThreadImpl | 200 class NetInternalsMessageHandler::IOThreadImpl |
166 : public base::RefCountedThreadSafe< | 201 : public base::RefCountedThreadSafe< |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
234 | 269 |
235 // ConnectionTester::Delegate implementation: | 270 // ConnectionTester::Delegate implementation: |
236 virtual void OnStartConnectionTestSuite(); | 271 virtual void OnStartConnectionTestSuite(); |
237 virtual void OnStartConnectionTestExperiment( | 272 virtual void OnStartConnectionTestExperiment( |
238 const ConnectionTester::Experiment& experiment); | 273 const ConnectionTester::Experiment& experiment); |
239 virtual void OnCompletedConnectionTestExperiment( | 274 virtual void OnCompletedConnectionTestExperiment( |
240 const ConnectionTester::Experiment& experiment, | 275 const ConnectionTester::Experiment& experiment, |
241 int result); | 276 int result); |
242 virtual void OnCompletedConnectionTestSuite(); | 277 virtual void OnCompletedConnectionTestSuite(); |
243 | 278 |
| 279 // Helper that executes |function_name| in the attached renderer. |
| 280 // The function takes ownership of |arg|. Note that this can be called from |
| 281 // any thread. |
| 282 void CallJavascriptFunction(const std::wstring& function_name, Value* arg); |
| 283 |
244 private: | 284 private: |
245 class CallbackHelper; | 285 class CallbackHelper; |
246 | 286 |
247 // Helper that runs |method| with |arg|, and deletes |arg| on completion. | 287 // Helper that runs |method| with |arg|, and deletes |arg| on completion. |
248 void DispatchToMessageHandler(ListValue* arg, MessageHandler method); | 288 void DispatchToMessageHandler(ListValue* arg, MessageHandler method); |
249 | 289 |
250 // Helper that executes |function_name| in the attached renderer. | |
251 // The function takes ownership of |arg|. Note that this can be called from | |
252 // any thread. | |
253 void CallJavascriptFunction(const std::wstring& function_name, Value* arg); | |
254 | |
255 // Adds |entry| to the queue of pending log entries to be sent to the page via | 290 // Adds |entry| to the queue of pending log entries to be sent to the page via |
256 // Javascript. Must be called on the IO Thread. Also creates a delayed task | 291 // Javascript. Must be called on the IO Thread. Also creates a delayed task |
257 // that will call PostPendingEntries, if there isn't one already. | 292 // that will call PostPendingEntries, if there isn't one already. |
258 void AddEntryToQueue(Value* entry); | 293 void AddEntryToQueue(Value* entry); |
259 | 294 |
260 // Sends all pending entries to the page via Javascript, and clears the list | 295 // Sends all pending entries to the page via Javascript, and clears the list |
261 // of pending entries. Sending multiple entries at once results in a | 296 // of pending entries. Sending multiple entries at once results in a |
262 // significant reduction of CPU usage when a lot of events are happening. | 297 // significant reduction of CPU usage when a lot of events are happening. |
263 // Must be called on the IO Thread. | 298 // Must be called on the IO Thread. |
264 void PostPendingEntries(); | 299 void PostPendingEntries(); |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
389 | 424 |
390 NetInternalsMessageHandler::NetInternalsMessageHandler() {} | 425 NetInternalsMessageHandler::NetInternalsMessageHandler() {} |
391 | 426 |
392 NetInternalsMessageHandler::~NetInternalsMessageHandler() { | 427 NetInternalsMessageHandler::~NetInternalsMessageHandler() { |
393 if (proxy_) { | 428 if (proxy_) { |
394 proxy_.get()->OnDOMUIDeleted(); | 429 proxy_.get()->OnDOMUIDeleted(); |
395 // Notify the handler on the IO thread that the renderer is gone. | 430 // Notify the handler on the IO thread that the renderer is gone. |
396 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, | 431 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, |
397 NewRunnableMethod(proxy_.get(), &IOThreadImpl::Detach)); | 432 NewRunnableMethod(proxy_.get(), &IOThreadImpl::Detach)); |
398 } | 433 } |
| 434 if (select_log_file_dialog_) |
| 435 select_log_file_dialog_->ListenerDestroyed(); |
399 } | 436 } |
400 | 437 |
401 DOMMessageHandler* NetInternalsMessageHandler::Attach(DOMUI* dom_ui) { | 438 DOMMessageHandler* NetInternalsMessageHandler::Attach(DOMUI* dom_ui) { |
402 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 439 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
403 proxy_ = new IOThreadImpl(this->AsWeakPtr(), g_browser_process->io_thread(), | 440 proxy_ = new IOThreadImpl(this->AsWeakPtr(), g_browser_process->io_thread(), |
404 dom_ui->GetProfile()->GetRequestContext()); | 441 dom_ui->GetProfile()->GetRequestContext()); |
405 DOMMessageHandler* result = DOMMessageHandler::Attach(dom_ui); | 442 DOMMessageHandler* result = DOMMessageHandler::Attach(dom_ui); |
406 return result; | 443 return result; |
407 } | 444 } |
408 | 445 |
| 446 void NetInternalsMessageHandler::FileSelected( |
| 447 const FilePath& path, int index, void* params) { |
| 448 select_log_file_dialog_.release(); |
| 449 BrowserThread::PostTask( |
| 450 BrowserThread::FILE, FROM_HERE, |
| 451 new ReadLogFileTask(proxy_.get(), path)); |
| 452 } |
| 453 |
| 454 void NetInternalsMessageHandler::FileSelectionCanceled(void* params) { |
| 455 select_log_file_dialog_.release(); |
| 456 } |
| 457 |
| 458 void NetInternalsMessageHandler::OnLoadLogFile(const ListValue* list) { |
| 459 // Only allow a single dialog at a time. |
| 460 if (select_log_file_dialog_.get()) |
| 461 return; |
| 462 select_log_file_dialog_ = SelectFileDialog::Create(this); |
| 463 select_log_file_dialog_->SelectFile( |
| 464 SelectFileDialog::SELECT_OPEN_FILE, string16(), FilePath(), NULL, 0, |
| 465 FILE_PATH_LITERAL(""), |
| 466 dom_ui_->tab_contents()->view()->GetTopLevelNativeWindow(), NULL); |
| 467 } |
| 468 |
409 void NetInternalsMessageHandler::RegisterMessages() { | 469 void NetInternalsMessageHandler::RegisterMessages() { |
410 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 470 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 471 // Only callback handled on UI thread. |
| 472 dom_ui_->RegisterMessageCallback("loadLogFile", |
| 473 NewCallback(this, &NetInternalsMessageHandler::OnLoadLogFile)); |
411 | 474 |
412 dom_ui_->RegisterMessageCallback( | 475 dom_ui_->RegisterMessageCallback( |
413 "notifyReady", | 476 "notifyReady", |
414 proxy_->CreateCallback(&IOThreadImpl::OnRendererReady)); | 477 proxy_->CreateCallback(&IOThreadImpl::OnRendererReady)); |
415 dom_ui_->RegisterMessageCallback( | 478 dom_ui_->RegisterMessageCallback( |
416 "getProxySettings", | 479 "getProxySettings", |
417 proxy_->CreateCallback(&IOThreadImpl::OnGetProxySettings)); | 480 proxy_->CreateCallback(&IOThreadImpl::OnGetProxySettings)); |
418 dom_ui_->RegisterMessageCallback( | 481 dom_ui_->RegisterMessageCallback( |
419 "reloadProxySettings", | 482 "reloadProxySettings", |
420 proxy_->CreateCallback(&IOThreadImpl::OnReloadProxySettings)); | 483 proxy_->CreateCallback(&IOThreadImpl::OnReloadProxySettings)); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
462 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 525 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
463 if (value) { | 526 if (value) { |
464 dom_ui_->CallJavascriptFunction(function_name, *value); | 527 dom_ui_->CallJavascriptFunction(function_name, *value); |
465 } else { | 528 } else { |
466 dom_ui_->CallJavascriptFunction(function_name); | 529 dom_ui_->CallJavascriptFunction(function_name); |
467 } | 530 } |
468 } | 531 } |
469 | 532 |
470 //////////////////////////////////////////////////////////////////////////////// | 533 //////////////////////////////////////////////////////////////////////////////// |
471 // | 534 // |
| 535 // NetInternalsMessageHandler::ReadLogFileTask |
| 536 // |
| 537 //////////////////////////////////////////////////////////////////////////////// |
| 538 |
| 539 NetInternalsMessageHandler::ReadLogFileTask::ReadLogFileTask( |
| 540 IOThreadImpl* proxy, const FilePath& path) |
| 541 : proxy_(proxy), path_(path) { |
| 542 } |
| 543 |
| 544 void NetInternalsMessageHandler::ReadLogFileTask::Run() { |
| 545 std::string file_contents; |
| 546 if (!file_util::ReadFileToString(path_, &file_contents)) |
| 547 return; |
| 548 proxy_->CallJavascriptFunction(L"g_browser.loadedLogFile", |
| 549 new StringValue(file_contents)); |
| 550 } |
| 551 |
| 552 //////////////////////////////////////////////////////////////////////////////// |
| 553 // |
472 // NetInternalsMessageHandler::IOThreadImpl | 554 // NetInternalsMessageHandler::IOThreadImpl |
473 // | 555 // |
474 //////////////////////////////////////////////////////////////////////////////// | 556 //////////////////////////////////////////////////////////////////////////////// |
475 | 557 |
476 NetInternalsMessageHandler::IOThreadImpl::IOThreadImpl( | 558 NetInternalsMessageHandler::IOThreadImpl::IOThreadImpl( |
477 const base::WeakPtr<NetInternalsMessageHandler>& handler, | 559 const base::WeakPtr<NetInternalsMessageHandler>& handler, |
478 IOThread* io_thread, | 560 IOThread* io_thread, |
479 URLRequestContextGetter* context_getter) | 561 URLRequestContextGetter* context_getter) |
480 : ThreadSafeObserver(net::NetLog::LOG_ALL_BUT_BYTES), | 562 : ThreadSafeObserver(net::NetLog::LOG_ALL_BUT_BYTES), |
481 handler_(handler), | 563 handler_(handler), |
(...skipping 595 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1077 NetInternalsHTMLSource* html_source = new NetInternalsHTMLSource(); | 1159 NetInternalsHTMLSource* html_source = new NetInternalsHTMLSource(); |
1078 | 1160 |
1079 // Set up the chrome://net-internals/ source. | 1161 // Set up the chrome://net-internals/ source. |
1080 BrowserThread::PostTask( | 1162 BrowserThread::PostTask( |
1081 BrowserThread::IO, FROM_HERE, | 1163 BrowserThread::IO, FROM_HERE, |
1082 NewRunnableMethod( | 1164 NewRunnableMethod( |
1083 ChromeURLDataManager::GetInstance(), | 1165 ChromeURLDataManager::GetInstance(), |
1084 &ChromeURLDataManager::AddDataSource, | 1166 &ChromeURLDataManager::AddDataSource, |
1085 make_scoped_refptr(html_source))); | 1167 make_scoped_refptr(html_source))); |
1086 } | 1168 } |
OLD | NEW |