Revert 268405 "Make sure that ScratchBuffer::Allocate() always r..."
[chromium-blink-merge.git] / content / browser / devtools / devtools_browser_target.cc
blob1d83728c678e485ad48ae1b2c1a167c64061b41c
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"
7 #include "base/bind.h"
8 #include "base/location.h"
9 #include "base/logging.h"
10 #include "base/message_loop/message_loop_proxy.h"
11 #include "base/stl_util.h"
12 #include "base/values.h"
13 #include "content/public/browser/browser_thread.h"
14 #include "net/server/http_server.h"
16 namespace content {
18 DevToolsBrowserTarget::DevToolsBrowserTarget(
19 net::HttpServer* http_server,
20 int connection_id)
21 : message_loop_proxy_(base::MessageLoopProxy::current()),
22 http_server_(http_server),
23 connection_id_(connection_id),
24 weak_factory_(this) {
27 void DevToolsBrowserTarget::RegisterDomainHandler(
28 const std::string& domain,
29 DevToolsProtocol::Handler* handler,
30 bool handle_on_ui_thread) {
31 DCHECK_EQ(message_loop_proxy_, base::MessageLoopProxy::current());
33 DCHECK(handlers_.find(domain) == handlers_.end());
34 handlers_[domain] = handler;
35 if (handle_on_ui_thread) {
36 handle_on_ui_thread_.insert(domain);
37 handler->SetNotifier(base::Bind(&DevToolsBrowserTarget::RespondFromUIThread,
38 weak_factory_.GetWeakPtr()));
39 } else {
40 handler->SetNotifier(base::Bind(&DevToolsBrowserTarget::Respond,
41 base::Unretained(this)));
45 void DevToolsBrowserTarget::HandleMessage(const std::string& data) {
46 DCHECK_EQ(message_loop_proxy_, base::MessageLoopProxy::current());
48 std::string error_response;
49 scoped_refptr<DevToolsProtocol::Command> command =
50 DevToolsProtocol::ParseCommand(data, &error_response);
51 if (!command) {
52 Respond(error_response);
53 return;
56 DomainHandlerMap::iterator it = handlers_.find(command->domain());
57 if (it == handlers_.end()) {
58 Respond(command->NoSuchMethodErrorResponse()->Serialize());
59 return;
62 DevToolsProtocol::Handler* handler = it->second;
63 bool handle_directly = handle_on_ui_thread_.find(command->domain()) ==
64 handle_on_ui_thread_.end();
65 if (handle_directly) {
66 scoped_refptr<DevToolsProtocol::Response> response =
67 handler->HandleCommand(command);
68 if (response && response->is_async_promise())
69 return;
70 if (response)
71 Respond(response->Serialize());
72 else
73 Respond(command->NoSuchMethodErrorResponse()->Serialize());
74 return;
77 BrowserThread::PostTask(
78 BrowserThread::UI,
79 FROM_HERE,
80 base::Bind(&DevToolsBrowserTarget::HandleCommandOnUIThread,
81 this,
82 handler,
83 command));
86 void DevToolsBrowserTarget::Detach() {
87 DCHECK_EQ(message_loop_proxy_, base::MessageLoopProxy::current());
88 DCHECK(http_server_);
90 http_server_ = NULL;
92 std::vector<DevToolsProtocol::Handler*> ui_handlers;
93 for (std::set<std::string>::iterator domain_it = handle_on_ui_thread_.begin();
94 domain_it != handle_on_ui_thread_.end();
95 ++domain_it) {
96 DomainHandlerMap::iterator handler_it = handlers_.find(*domain_it);
97 CHECK(handler_it != handlers_.end());
98 ui_handlers.push_back(handler_it->second);
99 handlers_.erase(handler_it);
102 STLDeleteValues(&handlers_);
104 BrowserThread::PostTask(
105 BrowserThread::UI,
106 FROM_HERE,
107 base::Bind(&DevToolsBrowserTarget::DeleteHandlersOnUIThread,
108 this,
109 ui_handlers));
112 DevToolsBrowserTarget::~DevToolsBrowserTarget() {
113 // DCHECK that Detach has been called or no handler has ever been registered.
114 DCHECK(handlers_.empty());
117 void DevToolsBrowserTarget::HandleCommandOnUIThread(
118 DevToolsProtocol::Handler* handler,
119 scoped_refptr<DevToolsProtocol::Command> command) {
120 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
121 scoped_refptr<DevToolsProtocol::Response> response =
122 handler->HandleCommand(command);
123 if (response && response->is_async_promise())
124 return;
126 if (response)
127 RespondFromUIThread(response->Serialize());
128 else
129 RespondFromUIThread(command->NoSuchMethodErrorResponse()->Serialize());
132 void DevToolsBrowserTarget::DeleteHandlersOnUIThread(
133 std::vector<DevToolsProtocol::Handler*> handlers) {
134 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
135 STLDeleteElements(&handlers);
138 void DevToolsBrowserTarget::Respond(const std::string& message) {
139 DCHECK_EQ(message_loop_proxy_, base::MessageLoopProxy::current());
140 if (!http_server_)
141 return;
142 http_server_->SendOverWebSocket(connection_id_, message);
145 void DevToolsBrowserTarget::RespondFromUIThread(const std::string& message) {
146 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
147 message_loop_proxy_->PostTask(
148 FROM_HERE,
149 base::Bind(&DevToolsBrowserTarget::Respond, this, message));
152 } // namespace content