| 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_agent_host_impl.h" | 5 #include "content/browser/devtools/devtools_agent_host_impl.h" |
| 6 | 6 |
| 7 #include <map> | 7 #include <map> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/bind.h" |
| 10 #include "base/json/json_writer.h" | 11 #include "base/json/json_writer.h" |
| 11 #include "base/lazy_instance.h" | 12 #include "base/lazy_instance.h" |
| 13 #include "base/message_loop/message_loop.h" |
| 14 #include "base/observer_list.h" |
| 12 #include "content/browser/devtools/devtools_manager.h" | 15 #include "content/browser/devtools/devtools_manager.h" |
| 13 #include "content/browser/devtools/forwarding_agent_host.h" | 16 #include "content/browser/devtools/forwarding_agent_host.h" |
| 14 #include "content/browser/devtools/protocol/devtools_protocol_dispatcher.h" | 17 #include "content/browser/devtools/protocol/devtools_protocol_dispatcher.h" |
| 15 #include "content/browser/devtools/render_frame_devtools_agent_host.h" | 18 #include "content/browser/devtools/render_frame_devtools_agent_host.h" |
| 16 #include "content/browser/devtools/service_worker_devtools_agent_host.h" | 19 #include "content/browser/devtools/service_worker_devtools_agent_host.h" |
| 17 #include "content/browser/devtools/service_worker_devtools_manager.h" | 20 #include "content/browser/devtools/service_worker_devtools_manager.h" |
| 18 #include "content/browser/devtools/shared_worker_devtools_agent_host.h" | 21 #include "content/browser/devtools/shared_worker_devtools_agent_host.h" |
| 19 #include "content/browser/devtools/shared_worker_devtools_manager.h" | 22 #include "content/browser/devtools/shared_worker_devtools_manager.h" |
| 23 #include "content/browser/loader/netlog_observer.h" |
| 20 #include "content/public/browser/browser_thread.h" | 24 #include "content/public/browser/browser_thread.h" |
| 25 #include "content/public/browser/content_browser_client.h" |
| 21 | 26 |
| 22 namespace content { | 27 namespace content { |
| 23 | 28 |
| 24 namespace { | 29 namespace { |
| 25 typedef std::map<std::string, DevToolsAgentHostImpl*> Instances; | 30 typedef std::map<std::string, DevToolsAgentHostImpl*> Instances; |
| 26 base::LazyInstance<Instances>::Leaky g_instances = LAZY_INSTANCE_INITIALIZER; | 31 base::LazyInstance<Instances>::Leaky g_instances = LAZY_INSTANCE_INITIALIZER; |
| 27 | 32 |
| 28 using AgentStateCallbacks = | 33 base::LazyInstance<base::ObserverList<DevToolsAgentHostObserver>>::Leaky |
| 29 std::vector<const DevToolsAgentHost::AgentStateCallback*>; | 34 g_observers = LAZY_INSTANCE_INITIALIZER; |
| 30 base::LazyInstance<AgentStateCallbacks>::Leaky g_callbacks = | |
| 31 LAZY_INSTANCE_INITIALIZER; | |
| 32 using DiscoveryCallbacks = | |
| 33 std::vector<DevToolsAgentHost::DiscoveryCallback>; | |
| 34 } // namespace | 35 } // namespace |
| 35 | 36 |
| 36 char DevToolsAgentHost::kTypePage[] = "page"; | 37 char DevToolsAgentHost::kTypePage[] = "page"; |
| 37 char DevToolsAgentHost::kTypeFrame[] = "iframe"; | 38 char DevToolsAgentHost::kTypeFrame[] = "iframe"; |
| 38 char DevToolsAgentHost::kTypeSharedWorker[] = "shared_worker"; | 39 char DevToolsAgentHost::kTypeSharedWorker[] = "shared_worker"; |
| 39 char DevToolsAgentHost::kTypeServiceWorker[] = "service_worker"; | 40 char DevToolsAgentHost::kTypeServiceWorker[] = "service_worker"; |
| 40 char DevToolsAgentHost::kTypeExternal[] = "external"; | 41 char DevToolsAgentHost::kTypeExternal[] = "external"; |
| 41 char DevToolsAgentHost::kTypeBrowser[] = "browser"; | 42 char DevToolsAgentHost::kTypeBrowser[] = "browser"; |
| 42 char DevToolsAgentHost::kTypeOther[] = "other"; | 43 char DevToolsAgentHost::kTypeOther[] = "other"; |
| 44 int DevToolsAgentHostImpl::s_attached_count_ = 0; |
| 43 | 45 |
| 44 // static | 46 // static |
| 45 std::string DevToolsAgentHost::GetProtocolVersion() { | 47 std::string DevToolsAgentHost::GetProtocolVersion() { |
| 46 return std::string(devtools::kProtocolVersion); | 48 return std::string(devtools::kProtocolVersion); |
| 47 } | 49 } |
| 48 | 50 |
| 49 // static | 51 // static |
| 50 bool DevToolsAgentHost::IsSupportedProtocolVersion(const std::string& version) { | 52 bool DevToolsAgentHost::IsSupportedProtocolVersion(const std::string& version) { |
| 51 return devtools::IsSupportedProtocolVersion(version); | 53 return devtools::IsSupportedProtocolVersion(version); |
| 52 } | 54 } |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 131 return false; | 133 return false; |
| 132 | 134 |
| 133 scoped_refptr<DevToolsAgentHostImpl> protect(this); | 135 scoped_refptr<DevToolsAgentHostImpl> protect(this); |
| 134 ++session_id_; | 136 ++session_id_; |
| 135 if (client_) { | 137 if (client_) { |
| 136 client_->AgentHostClosed(this, true); | 138 client_->AgentHostClosed(this, true); |
| 137 InnerDetach(); | 139 InnerDetach(); |
| 138 } | 140 } |
| 139 client_ = client; | 141 client_ = client; |
| 140 Attach(); | 142 Attach(); |
| 143 NotifyAttached(); |
| 141 return true; | 144 return true; |
| 142 } | 145 } |
| 143 | 146 |
| 144 bool DevToolsAgentHostImpl::AttachClient(DevToolsAgentHostClient* client) { | 147 bool DevToolsAgentHostImpl::AttachClient(DevToolsAgentHostClient* client) { |
| 145 return InnerAttach(client, false); | 148 return InnerAttach(client, false); |
| 146 } | 149 } |
| 147 | 150 |
| 148 void DevToolsAgentHostImpl::ForceAttachClient(DevToolsAgentHostClient* client) { | 151 void DevToolsAgentHostImpl::ForceAttachClient(DevToolsAgentHostClient* client) { |
| 149 InnerAttach(client, true); | 152 InnerAttach(client, true); |
| 150 } | 153 } |
| (...skipping 12 matching lines...) Expand all Loading... |
| 163 DevToolsAgentHostClient* client, | 166 DevToolsAgentHostClient* client, |
| 164 const std::string& message) { | 167 const std::string& message) { |
| 165 if (!client_ || client_ != client) | 168 if (!client_ || client_ != client) |
| 166 return false; | 169 return false; |
| 167 return DispatchProtocolMessage(message); | 170 return DispatchProtocolMessage(message); |
| 168 } | 171 } |
| 169 | 172 |
| 170 void DevToolsAgentHostImpl::InnerDetach() { | 173 void DevToolsAgentHostImpl::InnerDetach() { |
| 171 Detach(); | 174 Detach(); |
| 172 io_context_.DiscardAllStreams(); | 175 io_context_.DiscardAllStreams(); |
| 176 NotifyDetached(); |
| 173 } | 177 } |
| 174 | 178 |
| 175 bool DevToolsAgentHostImpl::IsAttached() { | 179 bool DevToolsAgentHostImpl::IsAttached() { |
| 176 return !!client_; | 180 return !!client_; |
| 177 } | 181 } |
| 178 | 182 |
| 179 void DevToolsAgentHostImpl::InspectElement( | 183 void DevToolsAgentHostImpl::InspectElement( |
| 180 DevToolsAgentHostClient* client, | 184 DevToolsAgentHostClient* client, |
| 181 int x, | 185 int x, |
| 182 int y) { | 186 int y) { |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 244 | 248 |
| 245 void DevToolsAgentHostImpl::HostClosed() { | 249 void DevToolsAgentHostImpl::HostClosed() { |
| 246 if (!client_) | 250 if (!client_) |
| 247 return; | 251 return; |
| 248 | 252 |
| 249 scoped_refptr<DevToolsAgentHostImpl> protect(this); | 253 scoped_refptr<DevToolsAgentHostImpl> protect(this); |
| 250 // Clear |client_| before notifying it. | 254 // Clear |client_| before notifying it. |
| 251 DevToolsAgentHostClient* client = client_; | 255 DevToolsAgentHostClient* client = client_; |
| 252 client_ = NULL; | 256 client_ = NULL; |
| 253 client->AgentHostClosed(this, false); | 257 client->AgentHostClosed(this, false); |
| 258 NotifyDetached(); |
| 254 } | 259 } |
| 255 | 260 |
| 256 void DevToolsAgentHostImpl::InspectElement(int x, int y) { | 261 void DevToolsAgentHostImpl::InspectElement(int x, int y) { |
| 257 } | 262 } |
| 258 | 263 |
| 259 void DevToolsAgentHostImpl::SendMessageToClient(int session_id, | 264 void DevToolsAgentHostImpl::SendMessageToClient(int session_id, |
| 260 const std::string& message) { | 265 const std::string& message) { |
| 261 if (!client_) | 266 if (!client_) |
| 262 return; | 267 return; |
| 263 // Filter any messages from previous sessions. | 268 // Filter any messages from previous sessions. |
| (...skipping 17 matching lines...) Expand all Loading... |
| 281 // Clear |client_| before notifying it. | 286 // Clear |client_| before notifying it. |
| 282 DevToolsAgentHostClient* client = agent_host->client_; | 287 DevToolsAgentHostClient* client = agent_host->client_; |
| 283 agent_host->client_ = NULL; | 288 agent_host->client_ = NULL; |
| 284 client->AgentHostClosed(agent_host, true); | 289 client->AgentHostClosed(agent_host, true); |
| 285 agent_host->InnerDetach(); | 290 agent_host->InnerDetach(); |
| 286 } | 291 } |
| 287 } | 292 } |
| 288 } | 293 } |
| 289 | 294 |
| 290 // static | 295 // static |
| 291 void DevToolsAgentHost::AddAgentStateCallback( | 296 void DevToolsAgentHost::AddObserver(DevToolsAgentHostObserver* observer) { |
| 292 const AgentStateCallback& callback) { | 297 g_observers.Get().AddObserver(observer); |
| 293 g_callbacks.Get().push_back(&callback); | |
| 294 } | 298 } |
| 295 | 299 |
| 296 // static | 300 // static |
| 297 void DevToolsAgentHost::RemoveAgentStateCallback( | 301 void DevToolsAgentHost::RemoveObserver(DevToolsAgentHostObserver* observer) { |
| 298 const AgentStateCallback& callback) { | 302 g_observers.Get().RemoveObserver(observer); |
| 299 if (g_callbacks == NULL) | |
| 300 return; | |
| 301 | |
| 302 AgentStateCallbacks* callbacks_ = g_callbacks.Pointer(); | |
| 303 AgentStateCallbacks::iterator it = | |
| 304 std::find(callbacks_->begin(), callbacks_->end(), &callback); | |
| 305 DCHECK(it != callbacks_->end()); | |
| 306 callbacks_->erase(it); | |
| 307 } | 303 } |
| 308 | 304 |
| 309 // static | 305 void DevToolsAgentHostImpl::NotifyAttached() { |
| 310 void DevToolsAgentHostImpl::NotifyCallbacks( | 306 if (!s_attached_count_) { |
| 311 DevToolsAgentHostImpl* agent_host, bool attached) { | 307 BrowserThread::PostTask( |
| 312 AgentStateCallbacks copy(g_callbacks.Get()); | 308 BrowserThread::IO, |
| 313 DevToolsManager* manager = DevToolsManager::GetInstance(); | 309 FROM_HERE, |
| 314 manager->AgentHostStateChanged(agent_host, attached); | 310 base::Bind(&NetLogObserver::Attach, |
| 315 if (manager->delegate()) | 311 GetContentClient()->browser()->GetNetLog())); |
| 316 manager->delegate()->DevToolsAgentStateChanged(agent_host, attached); | 312 } |
| 317 for (AgentStateCallbacks::iterator it = copy.begin(); it != copy.end(); ++it) | 313 ++s_attached_count_; |
| 318 (*it)->Run(agent_host, attached); | 314 |
| 315 for (auto& observer : g_observers.Get()) |
| 316 observer.DevToolsAgentHostAttached(this); |
| 317 } |
| 318 |
| 319 void DevToolsAgentHostImpl::NotifyDetached() { |
| 320 --s_attached_count_; |
| 321 if (!s_attached_count_) { |
| 322 BrowserThread::PostTask( |
| 323 BrowserThread::IO, |
| 324 FROM_HERE, |
| 325 base::Bind(&NetLogObserver::Detach)); |
| 326 } |
| 327 |
| 328 for (auto& observer : g_observers.Get()) |
| 329 observer.DevToolsAgentHostDetached(this); |
| 319 } | 330 } |
| 320 | 331 |
| 321 // DevToolsMessageChunkProcessor ----------------------------------------------- | 332 // DevToolsMessageChunkProcessor ----------------------------------------------- |
| 322 | 333 |
| 323 DevToolsMessageChunkProcessor::DevToolsMessageChunkProcessor( | 334 DevToolsMessageChunkProcessor::DevToolsMessageChunkProcessor( |
| 324 const SendMessageCallback& callback) | 335 const SendMessageCallback& callback) |
| 325 : callback_(callback), | 336 : callback_(callback), |
| 326 message_buffer_size_(0), | 337 message_buffer_size_(0), |
| 327 last_call_id_(0) { | 338 last_call_id_(0) { |
| 328 } | 339 } |
| (...skipping 29 matching lines...) Expand all Loading... |
| 358 if (message_buffer_.size() != message_buffer_size_) | 369 if (message_buffer_.size() != message_buffer_size_) |
| 359 return false; | 370 return false; |
| 360 callback_.Run(chunk.session_id, message_buffer_); | 371 callback_.Run(chunk.session_id, message_buffer_); |
| 361 message_buffer_ = std::string(); | 372 message_buffer_ = std::string(); |
| 362 message_buffer_size_ = 0; | 373 message_buffer_size_ = 0; |
| 363 } | 374 } |
| 364 return true; | 375 return true; |
| 365 } | 376 } |
| 366 | 377 |
| 367 } // namespace content | 378 } // namespace content |
| OLD | NEW |