Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(335)

Side by Side Diff: chrome/test/chromedriver/devtools_client_impl.cc

Issue 12321057: [chromedriver] Implement reconnection to DevTools. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix nits. Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 "chrome/test/chromedriver/devtools_client_impl.h" 5 #include "chrome/test/chromedriver/devtools_client_impl.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/logging.h" 10 #include "base/logging.h"
(...skipping 30 matching lines...) Expand all
41 InspectorEvent::~InspectorEvent() {} 41 InspectorEvent::~InspectorEvent() {}
42 42
43 InspectorCommandResponse::InspectorCommandResponse() {} 43 InspectorCommandResponse::InspectorCommandResponse() {}
44 44
45 InspectorCommandResponse::~InspectorCommandResponse() {} 45 InspectorCommandResponse::~InspectorCommandResponse() {}
46 46
47 } // namespace internal 47 } // namespace internal
48 48
49 DevToolsClientImpl::DevToolsClientImpl( 49 DevToolsClientImpl::DevToolsClientImpl(
50 const SyncWebSocketFactory& factory, 50 const SyncWebSocketFactory& factory,
51 const std::string& url) 51 const std::string& url,
52 const FrontendCloserFunc& frontend_closer_func)
52 : socket_(factory.Run().Pass()), 53 : socket_(factory.Run().Pass()),
53 url_(url), 54 url_(url),
55 frontend_closer_func_(frontend_closer_func),
54 parser_func_(base::Bind(&internal::ParseInspectorMessage)), 56 parser_func_(base::Bind(&internal::ParseInspectorMessage)),
55 connected_(false),
56 next_id_(1) {} 57 next_id_(1) {}
57 58
58 DevToolsClientImpl::DevToolsClientImpl( 59 DevToolsClientImpl::DevToolsClientImpl(
59 const SyncWebSocketFactory& factory, 60 const SyncWebSocketFactory& factory,
60 const std::string& url, 61 const std::string& url,
62 const FrontendCloserFunc& frontend_closer_func,
61 const ParserFunc& parser_func) 63 const ParserFunc& parser_func)
62 : socket_(factory.Run().Pass()), 64 : socket_(factory.Run().Pass()),
63 url_(url), 65 url_(url),
66 frontend_closer_func_(frontend_closer_func),
64 parser_func_(parser_func), 67 parser_func_(parser_func),
65 connected_(false),
66 next_id_(1) {} 68 next_id_(1) {}
67 69
68 DevToolsClientImpl::~DevToolsClientImpl() { 70 DevToolsClientImpl::~DevToolsClientImpl() {
69 for (ResponseMap::iterator iter = cmd_response_map_.begin(); 71 for (ResponseMap::iterator iter = cmd_response_map_.begin();
70 iter != cmd_response_map_.end(); ++iter) { 72 iter != cmd_response_map_.end(); ++iter) {
71 LOG(WARNING) << "Finished with no response for command " << iter->first; 73 LOG(WARNING) << "Finished with no response for command " << iter->first;
72 delete iter->second; 74 delete iter->second;
73 } 75 }
74 } 76 }
75 77
76 void DevToolsClientImpl::SetParserFuncForTesting( 78 void DevToolsClientImpl::SetParserFuncForTesting(
77 const ParserFunc& parser_func) { 79 const ParserFunc& parser_func) {
78 parser_func_ = parser_func; 80 parser_func_ = parser_func;
79 } 81 }
80 82
83 Status DevToolsClientImpl::EnsureConnected() {
84 if (!socket_->IsConnected()) {
85 // Try to close devtools frontend and then reconnect.
86 Status status = frontend_closer_func_.Run();
kkania 2013/03/04 23:33:57 do we want to try to connect before closing all th
chrisgao (Use stgao instead) 2013/03/05 06:58:17 Done.
87 if (status.IsError())
88 return status;
89 if (!socket_->Connect(url_))
90 return Status(kDisconnected, "unable to connect to renderer");
91
92 // OnConnected notification will be sent out in method ReceiveNextMessage.
93 listeners_for_on_connected_ = listeners_;
94 }
95 return Status(kOk);
96 }
97
81 Status DevToolsClientImpl::SendCommand( 98 Status DevToolsClientImpl::SendCommand(
82 const std::string& method, 99 const std::string& method,
83 const base::DictionaryValue& params) { 100 const base::DictionaryValue& params) {
84 scoped_ptr<base::DictionaryValue> result; 101 scoped_ptr<base::DictionaryValue> result;
85 return SendCommandInternal(method, params, &result); 102 return SendCommandInternal(method, params, &result);
86 } 103 }
87 104
88 Status DevToolsClientImpl::SendCommandAndGetResult( 105 Status DevToolsClientImpl::SendCommandAndGetResult(
89 const std::string& method, 106 const std::string& method,
90 const base::DictionaryValue& params, 107 const base::DictionaryValue& params,
(...skipping 24 matching lines...) Expand all
115 if (status.IsError()) 132 if (status.IsError())
116 return status; 133 return status;
117 } 134 }
118 return Status(kOk); 135 return Status(kOk);
119 } 136 }
120 137
121 Status DevToolsClientImpl::SendCommandInternal( 138 Status DevToolsClientImpl::SendCommandInternal(
122 const std::string& method, 139 const std::string& method,
123 const base::DictionaryValue& params, 140 const base::DictionaryValue& params,
124 scoped_ptr<base::DictionaryValue>* result) { 141 scoped_ptr<base::DictionaryValue>* result) {
125 if (!connected_) { 142 if (!socket_->IsConnected())
126 if (!socket_->Connect(url_)) 143 return Status(kDisconnected, "unable to connect to renderer");
127 return Status(kDisconnected, "unable to connect to renderer");
128 connected_ = true;
129
130 // OnConnected notification will be sent out in method ReceiveNextMessage.
131 listeners_for_on_connected_ = listeners_;
132 }
133 144
134 int command_id = next_id_++; 145 int command_id = next_id_++;
135 base::DictionaryValue command; 146 base::DictionaryValue command;
136 command.SetInteger("id", command_id); 147 command.SetInteger("id", command_id);
137 command.SetString("method", method); 148 command.SetString("method", method);
138 command.Set("params", params.DeepCopy()); 149 command.Set("params", params.DeepCopy());
139 std::string message; 150 std::string message;
140 base::JSONWriter::Write(&command, &message); 151 base::JSONWriter::Write(&command, &message);
141 if (!socket_->Send(message)) { 152 if (!socket_->Send(message))
142 connected_ = false;
143 return Status(kDisconnected, "unable to send message to renderer"); 153 return Status(kDisconnected, "unable to send message to renderer");
144 }
145 return ReceiveCommandResponse(command_id, result); 154 return ReceiveCommandResponse(command_id, result);
146 } 155 }
147 156
148 Status DevToolsClientImpl::ReceiveCommandResponse( 157 Status DevToolsClientImpl::ReceiveCommandResponse(
149 int command_id, 158 int command_id,
150 scoped_ptr<base::DictionaryValue>* result) { 159 scoped_ptr<base::DictionaryValue>* result) {
151 internal::InspectorMessageType type; 160 internal::InspectorMessageType type;
152 internal::InspectorEvent event; 161 internal::InspectorEvent event;
153 internal::InspectorCommandResponse response; 162 internal::InspectorCommandResponse response;
154 cmd_response_map_[command_id] = NULL; 163 cmd_response_map_[command_id] = NULL;
(...skipping 18 matching lines...) Expand all
173 Status status = listener->OnConnected(); 182 Status status = listener->OnConnected();
174 if (status.IsError()) 183 if (status.IsError())
175 return status; 184 return status;
176 } 185 }
177 // The message might be received already when processing other commands sent 186 // The message might be received already when processing other commands sent
178 // from DevToolsEventListener::OnConnected. 187 // from DevToolsEventListener::OnConnected.
179 if (HasReceivedCommandResponse(expected_id)) 188 if (HasReceivedCommandResponse(expected_id))
180 return Status(kOk); 189 return Status(kOk);
181 190
182 std::string message; 191 std::string message;
183 if (!socket_->ReceiveNextMessage(&message)) { 192 if (!socket_->ReceiveNextMessage(&message))
184 connected_ = false; 193 return Status(kDisconnected, "unable to receive message from renderer");
185 return Status(kDisconnected,
186 "unable to receive message from renderer");
187 }
188 if (!parser_func_.Run(message, expected_id, type, event, response)) 194 if (!parser_func_.Run(message, expected_id, type, event, response))
189 return Status(kUnknownError, "bad inspector message: " + message); 195 return Status(kUnknownError, "bad inspector message: " + message);
190 if (*type == internal::kEventMessageType) 196 if (*type == internal::kEventMessageType)
191 return NotifyEventListeners(event->method, *event->params); 197 return NotifyEventListeners(event->method, *event->params);
192 if (*type == internal::kCommandResponseMessageType) { 198 if (*type == internal::kCommandResponseMessageType) {
193 if (cmd_response_map_.count(response->id) == 0) { 199 if (cmd_response_map_.count(response->id) == 0) {
194 return Status(kUnknownError, "unexpected command message"); 200 return Status(kUnknownError, "unexpected command message");
195 } else if (response->result) { 201 } else if (response->result) {
196 cmd_response_map_[response->id] = response->result.release(); 202 cmd_response_map_[response->id] = response->result.release();
197 } else { 203 } else {
198 cmd_response_map_.erase(response->id); 204 cmd_response_map_.erase(response->id);
199 return ParseInspectorError(response->error); 205 return ParseInspectorError(response->error);
200 } 206 }
201 } 207 }
202 return Status(kOk); 208 return Status(kOk);
203 } 209 }
204 210
205 bool DevToolsClientImpl::HasReceivedCommandResponse(int cmd_id) { 211 bool DevToolsClientImpl::HasReceivedCommandResponse(int cmd_id) {
206 return cmd_response_map_.find(cmd_id) != cmd_response_map_.end() 212 return cmd_response_map_.find(cmd_id) != cmd_response_map_.end()
207 && cmd_response_map_[cmd_id] != NULL; 213 && cmd_response_map_[cmd_id] != NULL;
208 } 214 }
209 215
210 Status DevToolsClientImpl::NotifyEventListeners( 216 Status DevToolsClientImpl::NotifyEventListeners(
211 const std::string& method, 217 const std::string& method,
212 const base::DictionaryValue& params) { 218 const base::DictionaryValue& params) {
213 for (std::list<DevToolsEventListener*>::iterator iter = listeners_.begin(); 219 for (std::list<DevToolsEventListener*>::iterator iter = listeners_.begin();
214 iter != listeners_.end(); ++iter) { 220 iter != listeners_.end(); ++iter) {
215 (*iter)->OnEvent(method, params); 221 (*iter)->OnEvent(method, params);
216 } 222 }
217 if (method == "Inspector.detached") { 223 if (method == "Inspector.detached")
218 connected_ = false;
219 return Status(kDisconnected, "received Inspector.detached event"); 224 return Status(kDisconnected, "received Inspector.detached event");
220 }
221 return Status(kOk); 225 return Status(kOk);
222 } 226 }
223 227
224 namespace internal { 228 namespace internal {
225 229
226 bool ParseInspectorMessage( 230 bool ParseInspectorMessage(
227 const std::string& message, 231 const std::string& message,
228 int expected_id, 232 int expected_id,
229 InspectorMessageType* type, 233 InspectorMessageType* type,
230 InspectorEvent* event, 234 InspectorEvent* event,
(...skipping 30 matching lines...) Expand all
261 if (unscoped_result) 265 if (unscoped_result)
262 command_response->result.reset(unscoped_result->DeepCopy()); 266 command_response->result.reset(unscoped_result->DeepCopy());
263 else 267 else
264 base::JSONWriter::Write(unscoped_error, &command_response->error); 268 base::JSONWriter::Write(unscoped_error, &command_response->error);
265 return true; 269 return true;
266 } 270 }
267 return false; 271 return false;
268 } 272 }
269 273
270 } // namespace internal 274 } // namespace internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698