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