| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "content/browser/devtools/devtools_http_handler_impl.h" | 5 #include "content/browser/devtools/devtools_http_handler_impl.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| 11 #include "base/compiler_specific.h" | 11 #include "base/compiler_specific.h" |
| 12 #include "base/file_util.h" | 12 #include "base/file_util.h" |
| 13 #include "base/json/json_writer.h" | 13 #include "base/json/json_writer.h" |
| 14 #include "base/logging.h" | 14 #include "base/logging.h" |
| 15 #include "base/message_loop/message_loop_proxy.h" | 15 #include "base/message_loop/message_loop_proxy.h" |
| 16 #include "base/stl_util.h" | 16 #include "base/stl_util.h" |
| 17 #include "base/strings/string_number_conversions.h" | 17 #include "base/strings/string_number_conversions.h" |
| 18 #include "base/threading/thread.h" | 18 #include "base/threading/thread.h" |
| 19 #include "base/values.h" | 19 #include "base/values.h" |
| 20 #include "content/browser/devtools/devtools_browser_target.h" | 20 #include "content/browser/devtools/devtools_browser_target.h" |
| 21 #include "content/browser/devtools/devtools_protocol.h" | 21 #include "content/browser/devtools/devtools_protocol.h" |
| 22 #include "content/browser/devtools/devtools_protocol_constants.h" | 22 #include "content/browser/devtools/devtools_protocol_constants.h" |
| 23 #include "content/browser/devtools/devtools_system_info_handler.h" | 23 #include "content/browser/devtools/devtools_system_info_handler.h" |
| 24 #include "content/browser/devtools/devtools_tracing_handler.h" | 24 #include "content/browser/devtools/devtools_tracing_handler.h" |
| 25 #include "content/browser/devtools/tethering_handler.h" | 25 #include "content/browser/devtools/tethering_handler.h" |
| 26 #include "content/common/devtools_messages.h" | 26 #include "content/common/devtools_messages.h" |
| 27 #include "content/public/browser/browser_thread.h" | 27 #include "content/public/browser/browser_thread.h" |
| 28 #include "content/public/browser/devtools_agent_host.h" | 28 #include "content/public/browser/devtools_agent_host.h" |
| 29 #include "content/public/browser/devtools_client_host.h" | |
| 30 #include "content/public/browser/devtools_http_handler_delegate.h" | 29 #include "content/public/browser/devtools_http_handler_delegate.h" |
| 31 #include "content/public/browser/devtools_manager.h" | |
| 32 #include "content/public/browser/devtools_target.h" | 30 #include "content/public/browser/devtools_target.h" |
| 33 #include "content/public/common/content_client.h" | 31 #include "content/public/common/content_client.h" |
| 34 #include "content/public/common/url_constants.h" | 32 #include "content/public/common/url_constants.h" |
| 35 #include "content/public/common/user_agent.h" | 33 #include "content/public/common/user_agent.h" |
| 36 #include "content/public/common/user_agent.h" | 34 #include "content/public/common/user_agent.h" |
| 37 #include "grit/devtools_resources_map.h" | 35 #include "grit/devtools_resources_map.h" |
| 38 #include "net/base/escape.h" | 36 #include "net/base/escape.h" |
| 39 #include "net/base/io_buffer.h" | 37 #include "net/base/io_buffer.h" |
| 40 #include "net/base/ip_endpoint.h" | 38 #include "net/base/ip_endpoint.h" |
| 41 #include "net/base/net_errors.h" | 39 #include "net/base/net_errors.h" |
| (...skipping 20 matching lines...) Expand all Loading... |
| 62 const char kTargetParentIdField[] = "parentId"; | 60 const char kTargetParentIdField[] = "parentId"; |
| 63 const char kTargetTypeField[] = "type"; | 61 const char kTargetTypeField[] = "type"; |
| 64 const char kTargetTitleField[] = "title"; | 62 const char kTargetTitleField[] = "title"; |
| 65 const char kTargetDescriptionField[] = "description"; | 63 const char kTargetDescriptionField[] = "description"; |
| 66 const char kTargetUrlField[] = "url"; | 64 const char kTargetUrlField[] = "url"; |
| 67 const char kTargetThumbnailUrlField[] = "thumbnailUrl"; | 65 const char kTargetThumbnailUrlField[] = "thumbnailUrl"; |
| 68 const char kTargetFaviconUrlField[] = "faviconUrl"; | 66 const char kTargetFaviconUrlField[] = "faviconUrl"; |
| 69 const char kTargetWebSocketDebuggerUrlField[] = "webSocketDebuggerUrl"; | 67 const char kTargetWebSocketDebuggerUrlField[] = "webSocketDebuggerUrl"; |
| 70 const char kTargetDevtoolsFrontendUrlField[] = "devtoolsFrontendUrl"; | 68 const char kTargetDevtoolsFrontendUrlField[] = "devtoolsFrontendUrl"; |
| 71 | 69 |
| 72 // An internal implementation of DevToolsClientHost that delegates | 70 // An internal implementation of DevToolsAgentHost::Client that delegates |
| 73 // messages sent for DevToolsClient to a DebuggerShell instance. | 71 // messages sent to a DebuggerShell instance. |
| 74 class DevToolsClientHostImpl : public DevToolsClientHost { | 72 class DevToolsAgentHostClientImpl : public DevToolsAgentHost::Client { |
| 75 public: | 73 public: |
| 76 DevToolsClientHostImpl(base::MessageLoop* message_loop, | 74 DevToolsAgentHostClientImpl(base::MessageLoop* message_loop, |
| 77 net::HttpServer* server, | 75 net::HttpServer* server, |
| 78 int connection_id) | 76 int connection_id, |
| 77 DevToolsAgentHost* agent_host) |
| 79 : message_loop_(message_loop), | 78 : message_loop_(message_loop), |
| 80 server_(server), | 79 server_(server), |
| 81 connection_id_(connection_id), | 80 connection_id_(connection_id), |
| 82 is_closed_(false), | 81 agent_host_(agent_host) { |
| 83 detach_reason_("target_closed") {} | 82 agent_host_->AttachClient(this); |
| 83 } |
| 84 | 84 |
| 85 virtual ~DevToolsClientHostImpl() {} | 85 virtual ~DevToolsAgentHostClientImpl() { |
| 86 if (agent_host_) |
| 87 agent_host_->DetachClient(); |
| 88 } |
| 86 | 89 |
| 87 // DevToolsClientHost interface | 90 virtual void AgentHostClosed( |
| 88 virtual void InspectedContentsClosing() OVERRIDE { | 91 DevToolsAgentHost* agent_host, |
| 89 if (is_closed_) | 92 bool replaced_with_another_client) OVERRIDE { |
| 90 return; | 93 DCHECK(agent_host == agent_host_.get()); |
| 91 is_closed_ = true; | 94 agent_host_ = NULL; |
| 92 | 95 |
| 93 base::DictionaryValue notification; | 96 base::DictionaryValue notification; |
| 94 notification.SetString( | 97 notification.SetString( |
| 95 devtools::Inspector::detached::kParamReason, detach_reason_); | 98 devtools::Inspector::detached::kParamReason, |
| 99 replaced_with_another_client ? |
| 100 "replaced_with_devtools" : "target_closed"); |
| 96 std::string response = DevToolsProtocol::CreateNotification( | 101 std::string response = DevToolsProtocol::CreateNotification( |
| 97 devtools::Inspector::detached::kName, | 102 devtools::Inspector::detached::kName, |
| 98 notification.DeepCopy())->Serialize(); | 103 notification.DeepCopy())->Serialize(); |
| 99 message_loop_->PostTask( | 104 message_loop_->PostTask( |
| 100 FROM_HERE, | 105 FROM_HERE, |
| 101 base::Bind(&net::HttpServer::SendOverWebSocket, | 106 base::Bind(&net::HttpServer::SendOverWebSocket, |
| 102 server_, | 107 server_, |
| 103 connection_id_, | 108 connection_id_, |
| 104 response)); | 109 response)); |
| 105 | 110 |
| 106 message_loop_->PostTask( | 111 message_loop_->PostTask( |
| 107 FROM_HERE, | 112 FROM_HERE, |
| 108 base::Bind(&net::HttpServer::Close, server_, connection_id_)); | 113 base::Bind(&net::HttpServer::Close, server_, connection_id_)); |
| 109 } | 114 } |
| 110 | 115 |
| 111 virtual void DispatchOnInspectorFrontend(const std::string& data) OVERRIDE { | 116 virtual void DispatchProtocolMessage( |
| 117 DevToolsAgentHost* agent_host, const std::string& message) OVERRIDE { |
| 118 DCHECK(agent_host == agent_host_.get()); |
| 112 message_loop_->PostTask( | 119 message_loop_->PostTask( |
| 113 FROM_HERE, | 120 FROM_HERE, |
| 114 base::Bind(&net::HttpServer::SendOverWebSocket, | 121 base::Bind(&net::HttpServer::SendOverWebSocket, |
| 115 server_, | 122 server_, |
| 116 connection_id_, | 123 connection_id_, |
| 117 data)); | 124 message)); |
| 118 } | 125 } |
| 119 | 126 |
| 120 virtual void ReplacedWithAnotherClient() OVERRIDE { | 127 void OnMessage(const std::string& message) { |
| 121 detach_reason_ = "replaced_with_devtools"; | 128 if (agent_host_) |
| 129 agent_host_->DispatchOnInspectorBackend(message); |
| 122 } | 130 } |
| 123 | 131 |
| 124 private: | 132 private: |
| 125 base::MessageLoop* message_loop_; | 133 base::MessageLoop* message_loop_; |
| 126 net::HttpServer* server_; | 134 net::HttpServer* server_; |
| 127 int connection_id_; | 135 int connection_id_; |
| 128 bool is_closed_; | 136 scoped_refptr<DevToolsAgentHost> agent_host_; |
| 129 std::string detach_reason_; | |
| 130 }; | 137 }; |
| 131 | 138 |
| 132 static bool TimeComparator(const DevToolsTarget* target1, | 139 static bool TimeComparator(const DevToolsTarget* target1, |
| 133 const DevToolsTarget* target2) { | 140 const DevToolsTarget* target2) { |
| 134 return target1->GetLastActivityTime() > target2->GetLastActivityTime(); | 141 return target1->GetLastActivityTime() > target2->GetLastActivityTime(); |
| 135 } | 142 } |
| 136 | 143 |
| 137 } // namespace | 144 } // namespace |
| 138 | 145 |
| 139 // static | 146 // static |
| (...skipping 465 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 605 Send500(connection_id, "No such target id: " + page_id); | 612 Send500(connection_id, "No such target id: " + page_id); |
| 606 return; | 613 return; |
| 607 } | 614 } |
| 608 | 615 |
| 609 if (agent->IsAttached()) { | 616 if (agent->IsAttached()) { |
| 610 Send500(connection_id, | 617 Send500(connection_id, |
| 611 "Target with given id is being inspected: " + page_id); | 618 "Target with given id is being inspected: " + page_id); |
| 612 return; | 619 return; |
| 613 } | 620 } |
| 614 | 621 |
| 615 DevToolsClientHostImpl* client_host = new DevToolsClientHostImpl( | 622 DevToolsAgentHostClientImpl * client_host = new DevToolsAgentHostClientImpl( |
| 616 thread_->message_loop(), server_.get(), connection_id); | 623 thread_->message_loop(), server_.get(), connection_id, agent); |
| 617 connection_to_client_host_ui_[connection_id] = client_host; | 624 connection_to_client_ui_[connection_id] = client_host; |
| 618 | |
| 619 DevToolsManager::GetInstance()-> | |
| 620 RegisterDevToolsClientHostFor(agent, client_host); | |
| 621 | 625 |
| 622 AcceptWebSocket(connection_id, request); | 626 AcceptWebSocket(connection_id, request); |
| 623 } | 627 } |
| 624 | 628 |
| 625 void DevToolsHttpHandlerImpl::OnWebSocketMessageUI( | 629 void DevToolsHttpHandlerImpl::OnWebSocketMessageUI( |
| 626 int connection_id, | 630 int connection_id, |
| 627 const std::string& data) { | 631 const std::string& data) { |
| 628 ConnectionToClientHostMap::iterator it = | 632 ConnectionToClientMap::iterator it = |
| 629 connection_to_client_host_ui_.find(connection_id); | 633 connection_to_client_ui_.find(connection_id); |
| 630 if (it == connection_to_client_host_ui_.end()) | 634 if (it == connection_to_client_ui_.end()) |
| 631 return; | 635 return; |
| 632 | 636 |
| 633 DevToolsManager* manager = DevToolsManager::GetInstance(); | 637 DevToolsAgentHostClientImpl* client = |
| 634 manager->DispatchOnInspectorBackend(it->second, data); | 638 static_cast<DevToolsAgentHostClientImpl*>(it->second); |
| 639 client->OnMessage(data); |
| 635 } | 640 } |
| 636 | 641 |
| 637 void DevToolsHttpHandlerImpl::OnCloseUI(int connection_id) { | 642 void DevToolsHttpHandlerImpl::OnCloseUI(int connection_id) { |
| 638 ConnectionToClientHostMap::iterator it = | 643 ConnectionToClientMap::iterator it = |
| 639 connection_to_client_host_ui_.find(connection_id); | 644 connection_to_client_ui_.find(connection_id); |
| 640 if (it != connection_to_client_host_ui_.end()) { | 645 if (it != connection_to_client_ui_.end()) { |
| 641 DevToolsClientHostImpl* client_host = | 646 DevToolsAgentHostClientImpl* client = |
| 642 static_cast<DevToolsClientHostImpl*>(it->second); | 647 static_cast<DevToolsAgentHostClientImpl*>(it->second); |
| 643 DevToolsManager::GetInstance()->ClientHostClosing(client_host); | 648 delete client; |
| 644 delete client_host; | 649 connection_to_client_ui_.erase(connection_id); |
| 645 connection_to_client_host_ui_.erase(connection_id); | |
| 646 } | 650 } |
| 647 } | 651 } |
| 648 | 652 |
| 649 DevToolsHttpHandlerImpl::DevToolsHttpHandlerImpl( | 653 DevToolsHttpHandlerImpl::DevToolsHttpHandlerImpl( |
| 650 const net::StreamListenSocketFactory* socket_factory, | 654 const net::StreamListenSocketFactory* socket_factory, |
| 651 const std::string& frontend_url, | 655 const std::string& frontend_url, |
| 652 DevToolsHttpHandlerDelegate* delegate, | 656 DevToolsHttpHandlerDelegate* delegate, |
| 653 const base::FilePath& active_port_output_directory) | 657 const base::FilePath& active_port_output_directory) |
| 654 : frontend_url_(frontend_url), | 658 : frontend_url_(frontend_url), |
| 655 socket_factory_(socket_factory), | 659 socket_factory_(socket_factory), |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 814 id.c_str(), | 818 id.c_str(), |
| 815 host); | 819 host); |
| 816 dictionary->SetString( | 820 dictionary->SetString( |
| 817 kTargetDevtoolsFrontendUrlField, devtools_frontend_url); | 821 kTargetDevtoolsFrontendUrlField, devtools_frontend_url); |
| 818 } | 822 } |
| 819 | 823 |
| 820 return dictionary; | 824 return dictionary; |
| 821 } | 825 } |
| 822 | 826 |
| 823 } // namespace content | 827 } // namespace content |
| OLD | NEW |