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
3 // found in the LICENSE file.
5 #include "content/browser/devtools/devtools_manager_impl.h"
10 #include "base/message_loop/message_loop.h"
11 #include "content/browser/devtools/devtools_netlog_observer.h"
12 #include "content/browser/devtools/render_view_devtools_agent_host.h"
13 #include "content/browser/renderer_host/render_view_host_impl.h"
14 #include "content/browser/web_contents/web_contents_impl.h"
15 #include "content/public/browser/browser_thread.h"
16 #include "content/public/browser/devtools_client_host.h"
21 DevToolsManager* DevToolsManager::GetInstance() {
22 return DevToolsManagerImpl::GetInstance();
26 DevToolsManagerImpl* DevToolsManagerImpl::GetInstance() {
27 return Singleton<DevToolsManagerImpl>::get();
30 DevToolsManagerImpl::DevToolsManagerImpl() {
33 DevToolsManagerImpl::~DevToolsManagerImpl() {
34 DCHECK(agent_to_client_host_.empty());
35 DCHECK(client_to_agent_host_.empty());
38 DevToolsClientHost* DevToolsManagerImpl::GetDevToolsClientHostFor(
39 DevToolsAgentHostImpl* agent_host_impl) {
40 AgentToClientHostMap::iterator it =
41 agent_to_client_host_.find(agent_host_impl);
42 if (it != agent_to_client_host_.end())
47 DevToolsAgentHost* DevToolsManagerImpl::GetDevToolsAgentHostFor(
48 DevToolsClientHost* client_host) {
49 ClientToAgentHostMap::iterator it = client_to_agent_host_.find(client_host);
50 if (it != client_to_agent_host_.end())
51 return it->second.get();
55 void DevToolsManagerImpl::RegisterDevToolsClientHostFor(
56 DevToolsAgentHost* agent_host,
57 DevToolsClientHost* client_host) {
58 DevToolsAgentHostImpl* agent_host_impl =
59 static_cast<DevToolsAgentHostImpl*>(agent_host);
60 DevToolsClientHost* old_client_host =
61 GetDevToolsClientHostFor(agent_host_impl);
62 if (old_client_host) {
63 old_client_host->ReplacedWithAnotherClient();
64 UnregisterDevToolsClientHostFor(agent_host_impl);
66 BindClientHost(agent_host_impl, client_host);
67 agent_host_impl->Attach();
70 bool DevToolsManagerImpl::DispatchOnInspectorBackend(
71 DevToolsClientHost* from,
72 const std::string& message) {
73 DevToolsAgentHost* agent_host = GetDevToolsAgentHostFor(from);
76 DevToolsAgentHostImpl* agent_host_impl =
77 static_cast<DevToolsAgentHostImpl*>(agent_host);
78 agent_host_impl->DispatchOnInspectorBackend(message);
82 void DevToolsManagerImpl::DispatchOnInspectorFrontend(
83 DevToolsAgentHost* agent_host,
84 const std::string& message) {
85 DevToolsAgentHostImpl* agent_host_impl =
86 static_cast<DevToolsAgentHostImpl*>(agent_host);
87 DevToolsClientHost* client_host = GetDevToolsClientHostFor(agent_host_impl);
89 // Client window was closed while there were messages
93 client_host->DispatchOnInspectorFrontend(message);
96 void DevToolsManagerImpl::ClientHostClosing(DevToolsClientHost* client_host) {
97 DevToolsAgentHost* agent_host = GetDevToolsAgentHostFor(client_host);
100 DevToolsAgentHostImpl* agent_host_impl =
101 static_cast<DevToolsAgentHostImpl*>(agent_host);
102 UnbindClientHost(agent_host_impl, client_host);
105 void DevToolsManagerImpl::AgentHostClosing(DevToolsAgentHostImpl* agent_host) {
106 UnregisterDevToolsClientHostFor(agent_host);
109 void DevToolsManagerImpl::UnregisterDevToolsClientHostFor(
110 DevToolsAgentHostImpl* agent_host_impl) {
111 DevToolsClientHost* client_host = GetDevToolsClientHostFor(agent_host_impl);
114 UnbindClientHost(agent_host_impl, client_host);
115 client_host->InspectedContentsClosing();
118 void DevToolsManagerImpl::BindClientHost(
119 DevToolsAgentHostImpl* agent_host,
120 DevToolsClientHost* client_host) {
121 DCHECK(agent_to_client_host_.find(agent_host) ==
122 agent_to_client_host_.end());
123 DCHECK(client_to_agent_host_.find(client_host) ==
124 client_to_agent_host_.end());
126 if (client_to_agent_host_.empty()) {
127 BrowserThread::PostTask(
130 base::Bind(&DevToolsNetLogObserver::Attach));
132 agent_to_client_host_[agent_host] = client_host;
133 client_to_agent_host_[client_host] = agent_host;
134 agent_host->set_close_listener(this);
137 void DevToolsManagerImpl::UnbindClientHost(DevToolsAgentHostImpl* agent_host,
138 DevToolsClientHost* client_host) {
140 scoped_refptr<DevToolsAgentHostImpl> protect(agent_host);
141 DCHECK(agent_to_client_host_.find(agent_host)->second ==
143 DCHECK(client_to_agent_host_.find(client_host)->second.get() == agent_host);
144 agent_host->set_close_listener(NULL);
146 agent_to_client_host_.erase(agent_host);
147 client_to_agent_host_.erase(client_host);
149 if (client_to_agent_host_.empty()) {
150 BrowserThread::PostTask(
153 base::Bind(&DevToolsNetLogObserver::Detach));
155 // Lazy agent hosts can be deleted from within detach.
156 // Do not access agent_host below this line.
157 agent_host->Detach();
160 void DevToolsManagerImpl::CloseAllClientHosts() {
161 std::vector<DevToolsAgentHostImpl*> agents;
162 for (AgentToClientHostMap::iterator it =
163 agent_to_client_host_.begin();
164 it != agent_to_client_host_.end(); ++it) {
165 agents.push_back(it->first);
167 for (std::vector<DevToolsAgentHostImpl*>::iterator it = agents.begin();
168 it != agents.end(); ++it) {
169 UnregisterDevToolsClientHostFor(*it);
173 void DevToolsManagerImpl::AddAgentStateCallback(const Callback& callback) {
174 callbacks_.push_back(&callback);
177 void DevToolsManagerImpl::RemoveAgentStateCallback(const Callback& callback) {
178 CallbackContainer::iterator it =
179 std::find(callbacks_.begin(), callbacks_.end(), &callback);
180 DCHECK(it != callbacks_.end());
181 callbacks_.erase(it);
184 void DevToolsManagerImpl::NotifyObservers(DevToolsAgentHost* agent_host,
186 CallbackContainer copy(callbacks_);
187 for (CallbackContainer::iterator it = copy.begin(); it != copy.end(); ++it)
188 (*it)->Run(agent_host, attached);
191 } // namespace content