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_browser_target.h"
8 #include "base/location.h"
9 #include "base/logging.h"
10 #include "base/message_loop/message_loop_proxy.h"
11 #include "base/values.h"
12 #include "content/public/browser/browser_thread.h"
13 #include "net/server/http_server.h"
17 DevToolsBrowserTarget::DevToolsBrowserTarget(
18 base::MessageLoopProxy
* message_loop_proxy
,
19 net::HttpServer
* http_server
,
21 : message_loop_proxy_(message_loop_proxy
),
22 http_server_(http_server
),
23 connection_id_(connection_id
),
24 handlers_deleter_(&handlers_
),
28 void DevToolsBrowserTarget::RegisterDomainHandler(
29 const std::string
& domain
,
30 DevToolsProtocol::Handler
* handler
,
31 bool handle_on_ui_thread
) {
32 DCHECK(handlers_
.find(domain
) == handlers_
.end());
33 handlers_
[domain
] = handler
;
34 if (handle_on_ui_thread
) {
35 handle_on_ui_thread_
.insert(domain
);
36 handler
->SetNotifier(base::Bind(&DevToolsBrowserTarget::RespondFromUIThread
,
37 weak_factory_
.GetWeakPtr()));
39 handler
->SetNotifier(base::Bind(&DevToolsBrowserTarget::Respond
,
40 base::Unretained(this)));
44 void DevToolsBrowserTarget::HandleMessage(const std::string
& data
) {
45 std::string error_response
;
46 scoped_refptr
<DevToolsProtocol::Command
> command
=
47 DevToolsProtocol::ParseCommand(data
, &error_response
);
49 Respond(error_response
);
53 DomainHandlerMap::iterator it
= handlers_
.find(command
->domain());
54 if (it
== handlers_
.end()) {
55 Respond(command
->NoSuchMethodErrorResponse()->Serialize());
59 DevToolsProtocol::Handler
* handler
= it
->second
;
60 bool handle_directly
= handle_on_ui_thread_
.find(command
->domain()) ==
61 handle_on_ui_thread_
.end();
62 if (handle_directly
) {
63 scoped_refptr
<DevToolsProtocol::Response
> response
=
64 handler
->HandleCommand(command
);
65 if (response
&& response
->is_async_promise())
68 Respond(response
->Serialize());
70 Respond(command
->NoSuchMethodErrorResponse()->Serialize());
74 BrowserThread::PostTask(
77 base::Bind(&DevToolsBrowserTarget::HandleCommandOnUIThread
,
83 void DevToolsBrowserTarget::Detach() {
84 message_loop_proxy_
= NULL
;
87 std::vector
<DevToolsProtocol::Handler
*> ui_handlers
;
88 for (std::set
<std::string
>::iterator domain_it
= handle_on_ui_thread_
.begin();
89 domain_it
!= handle_on_ui_thread_
.end();
91 DomainHandlerMap::iterator handler_it
= handlers_
.find(*domain_it
);
92 CHECK(handler_it
!= handlers_
.end());
93 ui_handlers
.push_back(handler_it
->second
);
94 handlers_
.erase(handler_it
);
97 BrowserThread::PostTask(
100 base::Bind(&DevToolsBrowserTarget::DeleteHandlersOnUIThread
,
105 DevToolsBrowserTarget::~DevToolsBrowserTarget() {
108 void DevToolsBrowserTarget::HandleCommandOnUIThread(
109 DevToolsProtocol::Handler
* handler
,
110 scoped_refptr
<DevToolsProtocol::Command
> command
) {
111 scoped_refptr
<DevToolsProtocol::Response
> response
=
112 handler
->HandleCommand(command
);
113 if (response
&& response
->is_async_promise())
117 RespondFromUIThread(response
->Serialize());
119 RespondFromUIThread(command
->NoSuchMethodErrorResponse()->Serialize());
122 void DevToolsBrowserTarget::DeleteHandlersOnUIThread(
123 std::vector
<DevToolsProtocol::Handler
*> handlers
) {
124 STLDeleteElements(&handlers
);
127 void DevToolsBrowserTarget::Respond(const std::string
& message
) {
130 http_server_
->SendOverWebSocket(connection_id_
, message
);
133 void DevToolsBrowserTarget::RespondFromUIThread(const std::string
& message
) {
134 if (!message_loop_proxy_
)
136 message_loop_proxy_
->PostTask(
138 base::Bind(&DevToolsBrowserTarget::Respond
, this, message
));
141 } // namespace content