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 "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 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
119 } | 119 } |
120 | 120 |
121 Status DevToolsClientImpl::SendCommandInternal( | 121 Status DevToolsClientImpl::SendCommandInternal( |
122 const std::string& method, | 122 const std::string& method, |
123 const base::DictionaryValue& params, | 123 const base::DictionaryValue& params, |
124 scoped_ptr<base::DictionaryValue>* result) { | 124 scoped_ptr<base::DictionaryValue>* result) { |
125 if (!connected_) { | 125 if (!connected_) { |
126 if (!socket_->Connect(url_)) | 126 if (!socket_->Connect(url_)) |
127 return Status(kDisconnected, "unable to connect to renderer"); | 127 return Status(kDisconnected, "unable to connect to renderer"); |
128 connected_ = true; | 128 connected_ = true; |
129 for (std::list<DevToolsEventListener*>::iterator iter = listeners_.begin(); | 129 |
130 iter != listeners_.end(); ++iter) { | 130 // OnConnected notification will be sent out in method ReceiveNextMessage. |
131 Status status = (*iter)->OnConnected(); | 131 listeners_for_on_connected_ = listeners_; |
132 if (status.IsError()) | |
133 return status; | |
134 } | |
135 } | 132 } |
136 | 133 |
137 int command_id = next_id_++; | 134 int command_id = next_id_++; |
138 base::DictionaryValue command; | 135 base::DictionaryValue command; |
139 command.SetInteger("id", command_id); | 136 command.SetInteger("id", command_id); |
140 command.SetString("method", method); | 137 command.SetString("method", method); |
141 command.Set("params", params.DeepCopy()); | 138 command.Set("params", params.DeepCopy()); |
142 std::string message; | 139 std::string message; |
143 base::JSONWriter::Write(&command, &message); | 140 base::JSONWriter::Write(&command, &message); |
144 if (!socket_->Send(message)) { | 141 if (!socket_->Send(message)) { |
145 connected_ = false; | 142 connected_ = false; |
146 return Status(kDisconnected, "unable to send message to renderer"); | 143 return Status(kDisconnected, "unable to send message to renderer"); |
147 } | 144 } |
148 return ReceiveCommandResponse(command_id, result); | 145 return ReceiveCommandResponse(command_id, result); |
149 } | 146 } |
150 | 147 |
151 Status DevToolsClientImpl::ReceiveCommandResponse( | 148 Status DevToolsClientImpl::ReceiveCommandResponse( |
152 int command_id, | 149 int command_id, |
153 scoped_ptr<base::DictionaryValue>* result) { | 150 scoped_ptr<base::DictionaryValue>* result) { |
154 internal::InspectorMessageType type; | 151 internal::InspectorMessageType type; |
155 internal::InspectorEvent event; | 152 internal::InspectorEvent event; |
156 internal::InspectorCommandResponse response; | 153 internal::InspectorCommandResponse response; |
157 cmd_response_map_[command_id] = NULL; | 154 cmd_response_map_[command_id] = NULL; |
158 while (cmd_response_map_[command_id] == NULL) { | 155 while (!HasReceivedCommandResponse(command_id)) { |
159 Status status = ReceiveNextMessage(command_id, &type, &event, &response); | 156 Status status = ReceiveNextMessage(command_id, &type, &event, &response); |
160 if (status.IsError()) | 157 if (status.IsError()) |
161 return status; | 158 return status; |
162 } | 159 } |
163 result->reset(cmd_response_map_[command_id]); | 160 result->reset(cmd_response_map_[command_id]); |
164 cmd_response_map_.erase(command_id); | 161 cmd_response_map_.erase(command_id); |
165 return Status(kOk); | 162 return Status(kOk); |
166 } | 163 } |
167 | 164 |
168 Status DevToolsClientImpl::ReceiveNextMessage( | 165 Status DevToolsClientImpl::ReceiveNextMessage( |
169 int expected_id, | 166 int expected_id, |
170 internal::InspectorMessageType* type, | 167 internal::InspectorMessageType* type, |
171 internal::InspectorEvent* event, | 168 internal::InspectorEvent* event, |
172 internal::InspectorCommandResponse* response) { | 169 internal::InspectorCommandResponse* response) { |
| 170 while (!listeners_for_on_connected_.empty()) { |
| 171 DevToolsEventListener* listener = listeners_for_on_connected_.front(); |
| 172 listeners_for_on_connected_.pop_front(); |
| 173 Status status = listener->OnConnected(); |
| 174 if (status.IsError()) |
| 175 return status; |
| 176 } |
| 177 // The message might be received already when processing other commands sent |
| 178 // from DevToolsEventListener::OnConnected. |
| 179 if (HasReceivedCommandResponse(expected_id)) |
| 180 return Status(kOk); |
| 181 |
173 std::string message; | 182 std::string message; |
174 if (!socket_->ReceiveNextMessage(&message)) { | 183 if (!socket_->ReceiveNextMessage(&message)) { |
175 connected_ = false; | 184 connected_ = false; |
176 return Status(kDisconnected, | 185 return Status(kDisconnected, |
177 "unable to receive message from renderer"); | 186 "unable to receive message from renderer"); |
178 } | 187 } |
179 if (!parser_func_.Run(message, expected_id, type, event, response)) | 188 if (!parser_func_.Run(message, expected_id, type, event, response)) |
180 return Status(kUnknownError, "bad inspector message: " + message); | 189 return Status(kUnknownError, "bad inspector message: " + message); |
181 if (*type == internal::kEventMessageType) | 190 if (*type == internal::kEventMessageType) |
182 return NotifyEventListeners(event->method, *event->params); | 191 return NotifyEventListeners(event->method, *event->params); |
183 if (*type == internal::kCommandResponseMessageType) { | 192 if (*type == internal::kCommandResponseMessageType) { |
184 if (cmd_response_map_.count(response->id) == 0) { | 193 if (cmd_response_map_.count(response->id) == 0) { |
185 return Status(kUnknownError, "unexpected command message"); | 194 return Status(kUnknownError, "unexpected command message"); |
186 } else if (response->result) { | 195 } else if (response->result) { |
187 cmd_response_map_[response->id] = response->result.release(); | 196 cmd_response_map_[response->id] = response->result.release(); |
188 } else { | 197 } else { |
189 cmd_response_map_.erase(response->id); | 198 cmd_response_map_.erase(response->id); |
190 return ParseInspectorError(response->error); | 199 return ParseInspectorError(response->error); |
191 } | 200 } |
192 } | 201 } |
193 return Status(kOk); | 202 return Status(kOk); |
194 } | 203 } |
195 | 204 |
| 205 bool DevToolsClientImpl::HasReceivedCommandResponse(int cmd_id) { |
| 206 return cmd_response_map_.find(cmd_id) != cmd_response_map_.end() |
| 207 && cmd_response_map_[cmd_id] != NULL; |
| 208 } |
| 209 |
196 Status DevToolsClientImpl::NotifyEventListeners( | 210 Status DevToolsClientImpl::NotifyEventListeners( |
197 const std::string& method, | 211 const std::string& method, |
198 const base::DictionaryValue& params) { | 212 const base::DictionaryValue& params) { |
199 for (std::list<DevToolsEventListener*>::iterator iter = listeners_.begin(); | 213 for (std::list<DevToolsEventListener*>::iterator iter = listeners_.begin(); |
200 iter != listeners_.end(); ++iter) { | 214 iter != listeners_.end(); ++iter) { |
201 (*iter)->OnEvent(method, params); | 215 (*iter)->OnEvent(method, params); |
202 } | 216 } |
203 if (method == "Inspector.detached") { | 217 if (method == "Inspector.detached") { |
204 connected_ = false; | 218 connected_ = false; |
205 return Status(kDisconnected, "received Inspector.detached event"); | 219 return Status(kDisconnected, "received Inspector.detached event"); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
247 if (unscoped_result) | 261 if (unscoped_result) |
248 command_response->result.reset(unscoped_result->DeepCopy()); | 262 command_response->result.reset(unscoped_result->DeepCopy()); |
249 else | 263 else |
250 base::JSONWriter::Write(unscoped_error, &command_response->error); | 264 base::JSONWriter::Write(unscoped_error, &command_response->error); |
251 return true; | 265 return true; |
252 } | 266 } |
253 return false; | 267 return false; |
254 } | 268 } |
255 | 269 |
256 } // namespace internal | 270 } // namespace internal |
OLD | NEW |