| 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_browser_target.h" | 5 #include "content/browser/devtools/devtools_browser_target.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/json/json_reader.h" | 8 #include "base/json/json_reader.h" |
| 9 #include "base/json/json_writer.h" | 9 #include "base/json/json_writer.h" |
| 10 #include "base/location.h" | 10 #include "base/location.h" |
| 11 #include "base/logging.h" | 11 #include "base/logging.h" |
| 12 #include "base/memory/scoped_ptr.h" | 12 #include "base/memory/scoped_ptr.h" |
| 13 #include "base/message_loop_proxy.h" | 13 #include "base/message_loop_proxy.h" |
| 14 #include "base/values.h" | 14 #include "base/values.h" |
| 15 #include "net/server/http_server.h" | 15 #include "net/server/http_server.h" |
| 16 | 16 |
| 17 namespace content { | |
| 18 | |
| 19 namespace { | 17 namespace { |
| 20 | 18 |
| 21 class NotifierImpl : public DevToolsBrowserTarget::Notifier { | 19 base::Value* CreateErrorObject(int error_code, const std::string& message) { |
| 22 public: | 20 base::DictionaryValue* error_object = new base::DictionaryValue(); |
| 23 NotifierImpl( | 21 error_object->SetInteger("code", error_code); |
| 24 base::MessageLoopProxy* message_loop_proxy, | 22 error_object->SetString("message", message); |
| 25 net::HttpServer* http_server, | 23 return error_object; |
| 26 int connection_id) | 24 } |
| 27 : message_loop_proxy_(message_loop_proxy), | |
| 28 server_(http_server), | |
| 29 connection_id_(connection_id) { | |
| 30 } | |
| 31 | |
| 32 virtual ~NotifierImpl() {} | |
| 33 | |
| 34 // DevToolsBrowserTarget::Notifier | |
| 35 virtual void Notify(const std::string& data) OVERRIDE { | |
| 36 message_loop_proxy_->PostTask( | |
| 37 FROM_HERE, | |
| 38 base::Bind(&net::HttpServer::SendOverWebSocket, | |
| 39 server_, | |
| 40 connection_id_, | |
| 41 data)); | |
| 42 } | |
| 43 | |
| 44 private: | |
| 45 base::MessageLoopProxy* const message_loop_proxy_; | |
| 46 net::HttpServer* const server_; | |
| 47 const int connection_id_; | |
| 48 | |
| 49 DISALLOW_COPY_AND_ASSIGN(NotifierImpl); | |
| 50 }; | |
| 51 | 25 |
| 52 } // namespace | 26 } // namespace |
| 53 | 27 |
| 54 DevToolsBrowserTarget::Handler::Handler() | 28 namespace content { |
| 55 : notifier_(NULL) { | 29 |
| 30 DevToolsBrowserTarget::DomainHandler::~DomainHandler() { |
| 56 } | 31 } |
| 57 | 32 |
| 58 DevToolsBrowserTarget::Handler::~Handler() { | 33 void DevToolsBrowserTarget::DomainHandler::RegisterCommandHandler( |
| 34 const std::string& command, |
| 35 CommandHandler handler) { |
| 36 command_handlers_[command] = handler; |
| 59 } | 37 } |
| 60 | 38 |
| 61 void DevToolsBrowserTarget::Handler::set_notifier( | 39 DevToolsBrowserTarget::DomainHandler::DomainHandler(const std::string& domain) |
| 62 DevToolsBrowserTarget::Notifier* notifier) { | 40 : domain_(domain) { |
| 63 notifier_ = notifier; | |
| 64 } | 41 } |
| 65 | 42 |
| 66 DevToolsBrowserTarget::Notifier* DevToolsBrowserTarget::Handler::notifier() | 43 base::DictionaryValue* DevToolsBrowserTarget::DomainHandler::HandleCommand( |
| 67 const { | 44 const std::string& command, |
| 68 return notifier_; | 45 const base::DictionaryValue* params, |
| 46 base::Value** error_out) { |
| 47 CommandHandlers::iterator it = command_handlers_.find(command); |
| 48 if (it == command_handlers_.end()) { |
| 49 *error_out = CreateErrorObject(-1, "Invalid method"); |
| 50 return NULL; |
| 51 } |
| 52 return (it->second).Run(params, error_out); |
| 53 } |
| 54 |
| 55 void DevToolsBrowserTarget::DomainHandler::SendNotification( |
| 56 const std::string& method, |
| 57 base::DictionaryValue* params, |
| 58 base::Value* error) { |
| 59 notifier_.Run(method, params, error); |
| 69 } | 60 } |
| 70 | 61 |
| 71 DevToolsBrowserTarget::DevToolsBrowserTarget( | 62 DevToolsBrowserTarget::DevToolsBrowserTarget( |
| 72 base::MessageLoopProxy* message_loop_proxy, | 63 base::MessageLoopProxy* message_loop_proxy, |
| 73 net::HttpServer* http_server, | 64 net::HttpServer* http_server, |
| 74 int connection_id) | 65 int connection_id) |
| 75 : notifier_( | 66 : message_loop_proxy_(message_loop_proxy), |
| 76 new NotifierImpl(message_loop_proxy, http_server, connection_id)), | 67 http_server_(http_server), |
| 77 connection_id_(connection_id) { | 68 connection_id_(connection_id), |
| 69 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) { |
| 78 } | 70 } |
| 79 | 71 |
| 80 DevToolsBrowserTarget::~DevToolsBrowserTarget() { | 72 DevToolsBrowserTarget::~DevToolsBrowserTarget() { |
| 81 for (HandlersMap::iterator i = handlers_.begin(); i != handlers_.end(); ++i) | 73 for (DomainHandlerMap::iterator i = handlers_.begin(); i != handlers_.end(); |
| 74 ++i) |
| 82 delete i->second; | 75 delete i->second; |
| 83 } | 76 } |
| 84 | 77 |
| 85 void DevToolsBrowserTarget::RegisterHandler(Handler* handler) { | 78 void DevToolsBrowserTarget::RegisterDomainHandler(DomainHandler* handler) { |
| 86 std::string domain = handler->Domain(); | 79 std::string domain = handler->domain(); |
| 87 DCHECK(handlers_.find(domain) == handlers_.end()); | 80 DCHECK(handlers_.find(domain) == handlers_.end()); |
| 88 handlers_[domain] = handler; | 81 handlers_[domain] = handler; |
| 89 handler->set_notifier(notifier_.get()); | 82 handler->set_notifier(Bind(&DevToolsBrowserTarget::SendNotification, |
| 83 weak_factory_.GetWeakPtr())); |
| 90 } | 84 } |
| 91 | 85 |
| 92 std::string DevToolsBrowserTarget::HandleMessage(const std::string& data) { | 86 std::string DevToolsBrowserTarget::HandleMessage(const std::string& data) { |
| 93 int error_code; | 87 int error_code; |
| 94 std::string error_message; | 88 std::string error_message; |
| 95 scoped_ptr<base::Value> command( | 89 scoped_ptr<base::Value> command( |
| 96 base::JSONReader::ReadAndReturnError( | 90 base::JSONReader::ReadAndReturnError( |
| 97 data, 0, &error_code, &error_message)); | 91 data, 0, &error_code, &error_message)); |
| 98 | 92 |
| 99 if (!command || !command->IsType(base::Value::TYPE_DICTIONARY)) | 93 if (!command || !command->IsType(base::Value::TYPE_DICTIONARY)) |
| (...skipping 19 matching lines...) Expand all Loading... |
| 119 if (pos == std::string::npos) | 113 if (pos == std::string::npos) |
| 120 return SerializeErrorResponse( | 114 return SerializeErrorResponse( |
| 121 request_id, CreateErrorObject(-1, "Method unsupported")); | 115 request_id, CreateErrorObject(-1, "Method unsupported")); |
| 122 | 116 |
| 123 domain = method.substr(0, pos); | 117 domain = method.substr(0, pos); |
| 124 if (domain.empty() || handlers_.find(domain) == handlers_.end()) | 118 if (domain.empty() || handlers_.find(domain) == handlers_.end()) |
| 125 return SerializeErrorResponse( | 119 return SerializeErrorResponse( |
| 126 request_id, CreateErrorObject(-1, "Domain unsupported")); | 120 request_id, CreateErrorObject(-1, "Domain unsupported")); |
| 127 | 121 |
| 128 base::Value* error_object = NULL; | 122 base::Value* error_object = NULL; |
| 129 base::Value* domain_result = handlers_[domain]->OnProtocolCommand( | 123 base::DictionaryValue* domain_result = handlers_[domain]->HandleCommand( |
| 130 method, params, &error_object); | 124 method, params, &error_object); |
| 131 | 125 |
| 132 if (error_object) | 126 if (error_object) |
| 133 return SerializeErrorResponse(request_id, error_object); | 127 return SerializeErrorResponse(request_id, error_object); |
| 134 | 128 |
| 135 if (!domain_result) | 129 return SerializeResponse(request_id, domain_result); |
| 136 return SerializeErrorResponse( | 130 } |
| 137 request_id, CreateErrorObject(-1, "Invalid call")); | |
| 138 | 131 |
| 139 DictionaryValue* response = new DictionaryValue(); | 132 void DevToolsBrowserTarget::SendNotification(const std::string& method, |
| 140 response->Set("result", domain_result); | 133 DictionaryValue* params, |
| 141 return SerializeResponse(request_id, response); | 134 Value* error) { |
| 135 scoped_ptr<base::DictionaryValue> response(new base::DictionaryValue()); |
| 136 response->SetString("method", method); |
| 137 if (error) |
| 138 response->Set("error", error); |
| 139 else if (params) |
| 140 response->Set("params", params); |
| 141 |
| 142 // Serialize response. |
| 143 std::string json_response; |
| 144 base::JSONWriter::Write(response.get(), &json_response); |
| 145 |
| 146 message_loop_proxy_->PostTask( |
| 147 FROM_HERE, |
| 148 base::Bind(&net::HttpServer::SendOverWebSocket, |
| 149 http_server_, |
| 150 connection_id_, |
| 151 json_response)); |
| 142 } | 152 } |
| 143 | 153 |
| 144 std::string DevToolsBrowserTarget::SerializeErrorResponse( | 154 std::string DevToolsBrowserTarget::SerializeErrorResponse( |
| 145 int request_id, base::Value* error_object) { | 155 int request_id, base::Value* error_object) { |
| 146 scoped_ptr<base::DictionaryValue> error_response(new base::DictionaryValue()); | 156 scoped_ptr<base::DictionaryValue> error_response(new base::DictionaryValue()); |
| 147 error_response->SetInteger("id", request_id); | 157 error_response->SetInteger("id", request_id); |
| 148 error_response->Set("error", error_object); | 158 error_response->Set("error", error_object); |
| 149 // Serialize response. | 159 // Serialize response. |
| 150 std::string json_response; | 160 std::string json_response; |
| 151 base::JSONWriter::Write(error_response.get(), &json_response); | 161 base::JSONWriter::Write(error_response.get(), &json_response); |
| 152 return json_response; | 162 return json_response; |
| 153 } | 163 } |
| 154 | 164 |
| 155 base::Value* DevToolsBrowserTarget::CreateErrorObject( | |
| 156 int error_code, const std::string& message) { | |
| 157 base::DictionaryValue* error_object = new base::DictionaryValue(); | |
| 158 error_object->SetInteger("code", error_code); | |
| 159 error_object->SetString("message", message); | |
| 160 return error_object; | |
| 161 } | |
| 162 | |
| 163 std::string DevToolsBrowserTarget::SerializeResponse( | 165 std::string DevToolsBrowserTarget::SerializeResponse( |
| 164 int request_id, base::Value* response) { | 166 int request_id, base::DictionaryValue* result) { |
| 165 scoped_ptr<base::DictionaryValue> ret(new base::DictionaryValue()); | 167 scoped_ptr<base::DictionaryValue> response(new base::DictionaryValue()); |
| 166 ret->SetInteger("id", request_id); | 168 response->SetInteger("id", request_id); |
| 167 ret->Set("response", response); | 169 if (result) |
| 170 response->Set("result", result); |
| 168 | 171 |
| 169 // Serialize response. | 172 // Serialize response. |
| 170 std::string json_response; | 173 std::string json_response; |
| 171 base::JSONWriter::Write(ret.get(), &json_response); | 174 base::JSONWriter::Write(response.get(), &json_response); |
| 172 return json_response; | 175 return json_response; |
| 173 } | 176 } |
| 174 | 177 |
| 175 } // namespace content | 178 } // namespace content |
| OLD | NEW |