OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 // Implementation of the ExtensionPortsRemoteService. | 5 // Implementation of the ExtensionPortsRemoteService. |
6 | 6 |
7 // Inspired significantly from debugger_remote_service | 7 // Inspired significantly from debugger_remote_service |
8 // and ../automation/extension_port_container. | 8 // and ../automation/extension_port_container. |
9 | 9 |
10 #include "chrome/browser/debugger/extension_ports_remote_service.h" | 10 #include "chrome/browser/debugger/extension_ports_remote_service.h" |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
67 // "result": 0, (Always 0) | 67 // "result": 0, (Always 0) |
68 // "data": <message body - arbitrary JSON> | 68 // "data": <message body - arbitrary JSON> |
69 // } | 69 // } |
70 // | 70 // |
71 // The "disconnect" command from the external client, and | 71 // The "disconnect" command from the external client, and |
72 // "onDisconnect" notification from the ExtensionMessageService, are | 72 // "onDisconnect" notification from the ExtensionMessageService, are |
73 // similar: with the message port ID in the destination field, but no | 73 // similar: with the message port ID in the destination field, but no |
74 // "data" field in this case. | 74 // "data" field in this case. |
75 | 75 |
76 // Commands: | 76 // Commands: |
77 static const std::string kConnect = "connect"; | 77 const char kConnect[] = "connect"; |
78 static const std::string kDisconnect = "disconnect"; | 78 const char kDisconnect[] = "disconnect"; |
79 static const std::string kPostMessage = "postMessage"; | 79 const char kPostMessage[] = "postMessage"; |
80 // Events: | 80 // Events: |
81 static const std::string kOnMessage = "onMessage"; | 81 const char kOnMessage[] = "onMessage"; |
82 static const std::string kOnDisconnect = "onDisconnect"; | 82 const char kOnDisconnect[] = "onDisconnect"; |
83 | 83 |
84 // Constants for the JSON message fields. | 84 // Constants for the JSON message fields. |
85 // The type is wstring because the constant is used to get a | 85 // The type is wstring because the constant is used to get a |
86 // DictionaryValue field (which requires a wide string). | 86 // DictionaryValue field (which requires a wide string). |
87 | 87 |
88 // Mandatory. | 88 // Mandatory. |
89 static const std::wstring kCommandWide = L"command"; | 89 const char kCommandKey[] = "command"; |
90 | 90 |
91 // Always present in messages sent to the external client. | 91 // Always present in messages sent to the external client. |
92 static const std::wstring kResultWide = L"result"; | 92 const char kResultKey[] = "result"; |
93 | 93 |
94 // Field for command-specific parameters. Not strictly necessary, but | 94 // Field for command-specific parameters. Not strictly necessary, but |
95 // makes it more similar to the remote debugger protocol, which should | 95 // makes it more similar to the remote debugger protocol, which should |
96 // allow easier reuse of client code. | 96 // allow easier reuse of client code. |
97 static const std::wstring kDataWide = L"data"; | 97 const char kDataKey[] = "data"; |
98 | 98 |
99 // Fields within the "data" dictionary: | 99 // Fields within the "data" dictionary: |
100 | 100 |
101 // Required for "connect": | 101 // Required for "connect": |
102 static const std::wstring kExtensionIdWide = L"extensionId"; | 102 const char kExtensionIdKey[] = "extensionId"; |
103 // Optional in "connect": | 103 // Optional in "connect": |
104 static const std::wstring kChannelNameWide = L"channelName"; | 104 const char kChannelNameKey[] = "channelName"; |
105 static const std::wstring kTabIdWide = L"tabId"; | 105 const char kTabIdKey[] = "tabId"; |
106 | 106 |
107 // Present under "data" in replies to a successful "connect" . | 107 // Present under "data" in replies to a successful "connect" . |
108 static const std::wstring kPortIdWide = L"portId"; | 108 const char kPortIdKey[] = "portId"; |
109 | 109 |
110 } // namespace | 110 } // namespace |
111 | 111 |
112 const std::string ExtensionPortsRemoteService::kToolName = "ExtensionPorts"; | 112 const std::string ExtensionPortsRemoteService::kToolName = "ExtensionPorts"; |
113 | 113 |
114 ExtensionPortsRemoteService::ExtensionPortsRemoteService( | 114 ExtensionPortsRemoteService::ExtensionPortsRemoteService( |
115 DevToolsProtocolHandler* delegate) | 115 DevToolsProtocolHandler* delegate) |
116 : delegate_(delegate), service_(NULL) { | 116 : delegate_(delegate), service_(NULL) { |
117 // We need an ExtensionMessageService instance. It hangs off of | 117 // We need an ExtensionMessageService instance. It hangs off of |
118 // |profile|. But we do not have a particular tab or RenderViewHost | 118 // |profile|. But we do not have a particular tab or RenderViewHost |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
152 // Bad JSON | 152 // Bad JSON |
153 NOTREACHED(); | 153 NOTREACHED(); |
154 return; | 154 return; |
155 } | 155 } |
156 DictionaryValue* content; | 156 DictionaryValue* content; |
157 if (!request->IsType(Value::TYPE_DICTIONARY)) { | 157 if (!request->IsType(Value::TYPE_DICTIONARY)) { |
158 NOTREACHED(); // Broken protocol :( | 158 NOTREACHED(); // Broken protocol :( |
159 return; | 159 return; |
160 } | 160 } |
161 content = static_cast<DictionaryValue*>(request.get()); | 161 content = static_cast<DictionaryValue*>(request.get()); |
162 if (!content->HasKey(kCommandWide)) { | 162 if (!content->HasKey(kCommandKey)) { |
163 NOTREACHED(); // Broken protocol :( | 163 NOTREACHED(); // Broken protocol :( |
164 return; | 164 return; |
165 } | 165 } |
166 std::string command; | 166 std::string command; |
167 DictionaryValue response; | 167 DictionaryValue response; |
168 | 168 |
169 content->GetString(kCommandWide, &command); | 169 content->GetString(kCommandKey, &command); |
170 response.SetString(kCommandWide, command); | 170 response.SetString(kCommandKey, command); |
171 | 171 |
172 if (!service_) { | 172 if (!service_) { |
173 // This happens if we failed to obtain an ExtensionMessageService | 173 // This happens if we failed to obtain an ExtensionMessageService |
174 // during initialization. | 174 // during initialization. |
175 NOTREACHED(); | 175 NOTREACHED(); |
176 response.SetInteger(kResultWide, RESULT_NO_SERVICE); | 176 response.SetInteger(kResultKey, RESULT_NO_SERVICE); |
177 SendResponse(response, message.tool(), message.destination()); | 177 SendResponse(response, message.tool(), message.destination()); |
178 return; | 178 return; |
179 } | 179 } |
180 | 180 |
181 int destination = -1; | 181 int destination = -1; |
182 if (destinationString.size() != 0) | 182 if (destinationString.size() != 0) |
183 base::StringToInt(destinationString, &destination); | 183 base::StringToInt(destinationString, &destination); |
184 | 184 |
185 if (command == kConnect) { | 185 if (command == kConnect) { |
186 if (destination != -1) // destination should be empty for this command. | 186 if (destination != -1) // destination should be empty for this command. |
187 response.SetInteger(kResultWide, RESULT_UNKNOWN_COMMAND); | 187 response.SetInteger(kResultKey, RESULT_UNKNOWN_COMMAND); |
188 else | 188 else |
189 ConnectCommand(content, &response); | 189 ConnectCommand(content, &response); |
190 } else if (command == kDisconnect) { | 190 } else if (command == kDisconnect) { |
191 if (destination == -1) // Destination required for this command. | 191 if (destination == -1) // Destination required for this command. |
192 response.SetInteger(kResultWide, RESULT_UNKNOWN_COMMAND); | 192 response.SetInteger(kResultKey, RESULT_UNKNOWN_COMMAND); |
193 else | 193 else |
194 DisconnectCommand(destination, &response); | 194 DisconnectCommand(destination, &response); |
195 } else if (command == kPostMessage) { | 195 } else if (command == kPostMessage) { |
196 if (destination == -1) // Destination required for this command. | 196 if (destination == -1) // Destination required for this command. |
197 response.SetInteger(kResultWide, RESULT_UNKNOWN_COMMAND); | 197 response.SetInteger(kResultKey, RESULT_UNKNOWN_COMMAND); |
198 else | 198 else |
199 PostMessageCommand(destination, content, &response); | 199 PostMessageCommand(destination, content, &response); |
200 } else { | 200 } else { |
201 // Unknown command | 201 // Unknown command |
202 NOTREACHED(); | 202 NOTREACHED(); |
203 response.SetInteger(kResultWide, RESULT_UNKNOWN_COMMAND); | 203 response.SetInteger(kResultKey, RESULT_UNKNOWN_COMMAND); |
204 } | 204 } |
205 SendResponse(response, message.tool(), message.destination()); | 205 SendResponse(response, message.tool(), message.destination()); |
206 } | 206 } |
207 | 207 |
208 void ExtensionPortsRemoteService::OnConnectionLost() { | 208 void ExtensionPortsRemoteService::OnConnectionLost() { |
209 LOG(INFO) << "OnConnectionLost"; | 209 LOG(INFO) << "OnConnectionLost"; |
210 DCHECK_EQ(MessageLoop::current()->type(), MessageLoop::TYPE_UI); | 210 DCHECK_EQ(MessageLoop::current()->type(), MessageLoop::TYPE_UI); |
211 DCHECK(service_); | 211 DCHECK(service_); |
212 for (PortIdSet::iterator it = openPortIds_.begin(); | 212 for (PortIdSet::iterator it = openPortIds_.begin(); |
213 it != openPortIds_.end(); | 213 it != openPortIds_.end(); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
264 NOTREACHED() << function_name << " shouldn't be called."; | 264 NOTREACHED() << function_name << " shouldn't be called."; |
265 } | 265 } |
266 } | 266 } |
267 | 267 |
268 void ExtensionPortsRemoteService::OnExtensionMessage( | 268 void ExtensionPortsRemoteService::OnExtensionMessage( |
269 const std::string& message, int port_id) { | 269 const std::string& message, int port_id) { |
270 LOG(INFO) << "Message event: from port " << port_id | 270 LOG(INFO) << "Message event: from port " << port_id |
271 << ", < " << message << ">"; | 271 << ", < " << message << ">"; |
272 // Transpose the information into a JSON message for the external client. | 272 // Transpose the information into a JSON message for the external client. |
273 DictionaryValue content; | 273 DictionaryValue content; |
274 content.SetString(kCommandWide, kOnMessage); | 274 content.SetString(kCommandKey, kOnMessage); |
275 content.SetInteger(kResultWide, RESULT_OK); | 275 content.SetInteger(kResultKey, RESULT_OK); |
276 // Turn the stringified message body back into JSON. | 276 // Turn the stringified message body back into JSON. |
277 Value* data = base::JSONReader::Read(message, false); | 277 Value* data = base::JSONReader::Read(message, false); |
278 if (!data) { | 278 if (!data) { |
279 NOTREACHED(); | 279 NOTREACHED(); |
280 return; | 280 return; |
281 } | 281 } |
282 content.Set(kDataWide, data); | 282 content.Set(kDataKey, data); |
283 SendResponse(content, kToolName, base::IntToString(port_id)); | 283 SendResponse(content, kToolName, base::IntToString(port_id)); |
284 } | 284 } |
285 | 285 |
286 void ExtensionPortsRemoteService::OnExtensionPortDisconnected(int port_id) { | 286 void ExtensionPortsRemoteService::OnExtensionPortDisconnected(int port_id) { |
287 LOG(INFO) << "Disconnect event for port " << port_id; | 287 LOG(INFO) << "Disconnect event for port " << port_id; |
288 openPortIds_.erase(port_id); | 288 openPortIds_.erase(port_id); |
289 DictionaryValue content; | 289 DictionaryValue content; |
290 content.SetString(kCommandWide, kOnDisconnect); | 290 content.SetString(kCommandKey, kOnDisconnect); |
291 content.SetInteger(kResultWide, RESULT_OK); | 291 content.SetInteger(kResultKey, RESULT_OK); |
292 SendResponse(content, kToolName, base::IntToString(port_id)); | 292 SendResponse(content, kToolName, base::IntToString(port_id)); |
293 } | 293 } |
294 | 294 |
295 void ExtensionPortsRemoteService::ConnectCommand( | 295 void ExtensionPortsRemoteService::ConnectCommand( |
296 DictionaryValue* content, DictionaryValue* response) { | 296 DictionaryValue* content, DictionaryValue* response) { |
297 // Parse out the parameters. | 297 // Parse out the parameters. |
298 DictionaryValue* data; | 298 DictionaryValue* data; |
299 if (!content->GetDictionary(kDataWide, &data)) { | 299 if (!content->GetDictionary(kDataKey, &data)) { |
300 response->SetInteger(kResultWide, RESULT_PARAMETER_ERROR); | 300 response->SetInteger(kResultKey, RESULT_PARAMETER_ERROR); |
301 return; | 301 return; |
302 } | 302 } |
303 std::string extension_id; | 303 std::string extension_id; |
304 if (!data->GetString(kExtensionIdWide, &extension_id)) { | 304 if (!data->GetString(kExtensionIdKey, &extension_id)) { |
305 response->SetInteger(kResultWide, RESULT_PARAMETER_ERROR); | 305 response->SetInteger(kResultKey, RESULT_PARAMETER_ERROR); |
306 return; | 306 return; |
307 } | 307 } |
308 std::string channel_name = ""; | 308 std::string channel_name = ""; |
309 data->GetString(kChannelNameWide, &channel_name); // optional. | 309 data->GetString(kChannelNameKey, &channel_name); // optional. |
310 int tab_id = -1; | 310 int tab_id = -1; |
311 data->GetInteger(kTabIdWide, &tab_id); // optional. | 311 data->GetInteger(kTabIdKey, &tab_id); // optional. |
312 int port_id; | 312 int port_id; |
313 if (tab_id != -1) { // Resolve the tab ID. | 313 if (tab_id != -1) { // Resolve the tab ID. |
314 const InspectableTabProxy::ControllersMap& navcon_map = | 314 const InspectableTabProxy::ControllersMap& navcon_map = |
315 delegate_->inspectable_tab_proxy()->controllers_map(); | 315 delegate_->inspectable_tab_proxy()->controllers_map(); |
316 InspectableTabProxy::ControllersMap::const_iterator it = | 316 InspectableTabProxy::ControllersMap::const_iterator it = |
317 navcon_map.find(tab_id); | 317 navcon_map.find(tab_id); |
318 TabContents* tab_contents = NULL; | 318 TabContents* tab_contents = NULL; |
319 if (it != navcon_map.end()) | 319 if (it != navcon_map.end()) |
320 tab_contents = it->second->tab_contents(); | 320 tab_contents = it->second->tab_contents(); |
321 if (!tab_contents) { | 321 if (!tab_contents) { |
322 LOG(INFO) << "tab not found: " << tab_id; | 322 LOG(INFO) << "tab not found: " << tab_id; |
323 response->SetInteger(kResultWide, RESULT_TAB_NOT_FOUND); | 323 response->SetInteger(kResultKey, RESULT_TAB_NOT_FOUND); |
324 return; | 324 return; |
325 } | 325 } |
326 // Ask the ExtensionMessageService to open the channel. | 326 // Ask the ExtensionMessageService to open the channel. |
327 LOG(INFO) << "Connect: extension_id <" << extension_id | 327 LOG(INFO) << "Connect: extension_id <" << extension_id |
328 << ">, channel_name <" << channel_name << ">" | 328 << ">, channel_name <" << channel_name << ">" |
329 << ", tab " << tab_id; | 329 << ", tab " << tab_id; |
330 DCHECK(service_); | 330 DCHECK(service_); |
331 port_id = service_->OpenSpecialChannelToTab( | 331 port_id = service_->OpenSpecialChannelToTab( |
332 extension_id, channel_name, tab_contents, this); | 332 extension_id, channel_name, tab_contents, this); |
333 } else { // no tab: channel to an extension' background page / toolstrip. | 333 } else { // no tab: channel to an extension' background page / toolstrip. |
334 // Ask the ExtensionMessageService to open the channel. | 334 // Ask the ExtensionMessageService to open the channel. |
335 LOG(INFO) << "Connect: extension_id <" << extension_id | 335 LOG(INFO) << "Connect: extension_id <" << extension_id |
336 << ">, channel_name <" << channel_name << ">"; | 336 << ">, channel_name <" << channel_name << ">"; |
337 DCHECK(service_); | 337 DCHECK(service_); |
338 port_id = service_->OpenSpecialChannelToExtension( | 338 port_id = service_->OpenSpecialChannelToExtension( |
339 extension_id, channel_name, "null", this); | 339 extension_id, channel_name, "null", this); |
340 } | 340 } |
341 if (port_id == -1) { | 341 if (port_id == -1) { |
342 // Failure: probably the extension ID doesn't exist. | 342 // Failure: probably the extension ID doesn't exist. |
343 LOG(INFO) << "Connect failed"; | 343 LOG(INFO) << "Connect failed"; |
344 response->SetInteger(kResultWide, RESULT_CONNECT_FAILED); | 344 response->SetInteger(kResultKey, RESULT_CONNECT_FAILED); |
345 return; | 345 return; |
346 } | 346 } |
347 LOG(INFO) << "Connected: port " << port_id; | 347 LOG(INFO) << "Connected: port " << port_id; |
348 openPortIds_.insert(port_id); | 348 openPortIds_.insert(port_id); |
349 // Reply to external client with the port ID assigned to the new channel. | 349 // Reply to external client with the port ID assigned to the new channel. |
350 DictionaryValue* reply_data = new DictionaryValue(); | 350 DictionaryValue* reply_data = new DictionaryValue(); |
351 reply_data->SetInteger(kPortIdWide, port_id); | 351 reply_data->SetInteger(kPortIdKey, port_id); |
352 response->Set(kDataWide, reply_data); | 352 response->Set(kDataKey, reply_data); |
353 response->SetInteger(kResultWide, RESULT_OK); | 353 response->SetInteger(kResultKey, RESULT_OK); |
354 } | 354 } |
355 | 355 |
356 void ExtensionPortsRemoteService::DisconnectCommand( | 356 void ExtensionPortsRemoteService::DisconnectCommand( |
357 int port_id, DictionaryValue* response) { | 357 int port_id, DictionaryValue* response) { |
358 LOG(INFO) << "Disconnect port " << port_id; | 358 LOG(INFO) << "Disconnect port " << port_id; |
359 PortIdSet::iterator portEntry = openPortIds_.find(port_id); | 359 PortIdSet::iterator portEntry = openPortIds_.find(port_id); |
360 if (portEntry == openPortIds_.end()) { // unknown port ID. | 360 if (portEntry == openPortIds_.end()) { // unknown port ID. |
361 LOG(INFO) << "unknown port: " << port_id; | 361 LOG(INFO) << "unknown port: " << port_id; |
362 response->SetInteger(kResultWide, RESULT_UNKNOWN_PORT); | 362 response->SetInteger(kResultKey, RESULT_UNKNOWN_PORT); |
363 return; | 363 return; |
364 } | 364 } |
365 DCHECK(service_); | 365 DCHECK(service_); |
366 service_->CloseChannel(port_id); | 366 service_->CloseChannel(port_id); |
367 openPortIds_.erase(portEntry); | 367 openPortIds_.erase(portEntry); |
368 response->SetInteger(kResultWide, RESULT_OK); | 368 response->SetInteger(kResultKey, RESULT_OK); |
369 } | 369 } |
370 | 370 |
371 void ExtensionPortsRemoteService::PostMessageCommand( | 371 void ExtensionPortsRemoteService::PostMessageCommand( |
372 int port_id, DictionaryValue* content, DictionaryValue* response) { | 372 int port_id, DictionaryValue* content, DictionaryValue* response) { |
373 Value* data; | 373 Value* data; |
374 if (!content->Get(kDataWide, &data)) { | 374 if (!content->Get(kDataKey, &data)) { |
375 response->SetInteger(kResultWide, RESULT_PARAMETER_ERROR); | 375 response->SetInteger(kResultKey, RESULT_PARAMETER_ERROR); |
376 return; | 376 return; |
377 } | 377 } |
378 std::string message; | 378 std::string message; |
379 // Stringified the JSON message body. | 379 // Stringified the JSON message body. |
380 base::JSONWriter::Write(data, false, &message); | 380 base::JSONWriter::Write(data, false, &message); |
381 LOG(INFO) << "postMessage: port " << port_id | 381 LOG(INFO) << "postMessage: port " << port_id |
382 << ", message: <" << message << ">"; | 382 << ", message: <" << message << ">"; |
383 PortIdSet::iterator portEntry = openPortIds_.find(port_id); | 383 PortIdSet::iterator portEntry = openPortIds_.find(port_id); |
384 if (portEntry == openPortIds_.end()) { // Unknown port ID. | 384 if (portEntry == openPortIds_.end()) { // Unknown port ID. |
385 LOG(INFO) << "unknown port: " << port_id; | 385 LOG(INFO) << "unknown port: " << port_id; |
386 response->SetInteger(kResultWide, RESULT_UNKNOWN_PORT); | 386 response->SetInteger(kResultKey, RESULT_UNKNOWN_PORT); |
387 return; | 387 return; |
388 } | 388 } |
389 // Post the message through the ExtensionMessageService. | 389 // Post the message through the ExtensionMessageService. |
390 DCHECK(service_); | 390 DCHECK(service_); |
391 service_->PostMessageFromRenderer(port_id, message); | 391 service_->PostMessageFromRenderer(port_id, message); |
392 // Confirm to the external client that we sent its message. | 392 // Confirm to the external client that we sent its message. |
393 response->SetInteger(kResultWide, RESULT_OK); | 393 response->SetInteger(kResultKey, RESULT_OK); |
394 } | 394 } |
OLD | NEW |