| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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/browser/extensions/extension_message_service.h" | 5 #include "chrome/browser/extensions/extension_message_service.h" |
| 6 | 6 |
| 7 #include "base/json_writer.h" | 7 #include "base/json_writer.h" |
| 8 #include "base/singleton.h" | 8 #include "base/singleton.h" |
| 9 #include "base/stl_util-inl.h" | 9 #include "base/stl_util-inl.h" |
| 10 #include "base/values.h" | 10 #include "base/values.h" |
| (...skipping 25 matching lines...) Expand all Loading... |
| 36 typedef std::map<URLRequestContext*, ExtensionMessageService*> InstanceMap; | 36 typedef std::map<URLRequestContext*, ExtensionMessageService*> InstanceMap; |
| 37 struct SingletonData { | 37 struct SingletonData { |
| 38 ~SingletonData() { | 38 ~SingletonData() { |
| 39 STLDeleteContainerPairSecondPointers(map.begin(), map.end()); | 39 STLDeleteContainerPairSecondPointers(map.begin(), map.end()); |
| 40 } | 40 } |
| 41 Lock lock; | 41 Lock lock; |
| 42 InstanceMap map; | 42 InstanceMap map; |
| 43 }; | 43 }; |
| 44 | 44 |
| 45 static void DispatchOnConnect(IPC::Message::Sender* channel, int source_port_id, | 45 static void DispatchOnConnect(IPC::Message::Sender* channel, int source_port_id, |
| 46 const std::string& tab_json) { | 46 const std::string& tab_json, |
| 47 const std::string& extension_id) { |
| 47 ListValue args; | 48 ListValue args; |
| 48 args.Set(0, Value::CreateIntegerValue(source_port_id)); | 49 args.Set(0, Value::CreateIntegerValue(source_port_id)); |
| 49 args.Set(1, Value::CreateStringValue(tab_json)); | 50 args.Set(1, Value::CreateStringValue(tab_json)); |
| 51 args.Set(2, Value::CreateStringValue(extension_id)); |
| 50 channel->Send(new ViewMsg_ExtensionMessageInvoke( | 52 channel->Send(new ViewMsg_ExtensionMessageInvoke( |
| 51 ExtensionMessageService::kDispatchOnConnect, args)); | 53 ExtensionMessageService::kDispatchOnConnect, args)); |
| 52 } | 54 } |
| 53 | 55 |
| 54 static void DispatchOnDisconnect(IPC::Message::Sender* channel, | 56 static void DispatchOnDisconnect(IPC::Message::Sender* channel, |
| 55 int source_port_id) { | 57 int source_port_id) { |
| 56 ListValue args; | 58 ListValue args; |
| 57 args.Set(0, Value::CreateIntegerValue(source_port_id)); | 59 args.Set(0, Value::CreateIntegerValue(source_port_id)); |
| 58 channel->Send(new ViewMsg_ExtensionMessageInvoke( | 60 channel->Send(new ViewMsg_ExtensionMessageInvoke( |
| 59 ExtensionMessageService::kDispatchOnDisconnect, args)); | 61 ExtensionMessageService::kDispatchOnDisconnect, args)); |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 214 | 216 |
| 215 DCHECK(initialized_); | 217 DCHECK(initialized_); |
| 216 | 218 |
| 217 // Create a channel ID for both sides of the channel. | 219 // Create a channel ID for both sides of the channel. |
| 218 int port1_id = -1; | 220 int port1_id = -1; |
| 219 int port2_id = -1; | 221 int port2_id = -1; |
| 220 AllocatePortIdPair(&port1_id, &port2_id); | 222 AllocatePortIdPair(&port1_id, &port2_id); |
| 221 | 223 |
| 222 ui_loop_->PostTask(FROM_HERE, | 224 ui_loop_->PostTask(FROM_HERE, |
| 223 NewRunnableMethod(this, &ExtensionMessageService::OpenChannelOnUIThread, | 225 NewRunnableMethod(this, &ExtensionMessageService::OpenChannelOnUIThread, |
| 224 routing_id, port1_id, source->GetProcessId(), port2_id, process_id)); | 226 routing_id, port1_id, source->GetProcessId(), port2_id, process_id, |
| 227 extension_id)); |
| 225 | 228 |
| 226 return port2_id; | 229 return port2_id; |
| 227 } | 230 } |
| 228 | 231 |
| 229 void ExtensionMessageService::OpenChannelOnUIThread( | 232 void ExtensionMessageService::OpenChannelOnUIThread( |
| 230 int source_routing_id, int source_port_id, int source_process_id, | 233 int source_routing_id, int source_port_id, int source_process_id, |
| 231 int dest_port_id, int dest_process_id) { | 234 int dest_port_id, int dest_process_id, const std::string& extension_id) { |
| 232 RenderProcessHost* source = RenderProcessHost::FromID(source_process_id); | 235 RenderProcessHost* source = RenderProcessHost::FromID(source_process_id); |
| 233 OpenChannelOnUIThreadImpl(source_routing_id, source_port_id, | 236 OpenChannelOnUIThreadImpl(source_routing_id, source_port_id, |
| 234 source, dest_port_id, dest_process_id, | 237 source_process_id, source, dest_port_id, |
| 235 source_process_id); | 238 dest_process_id, extension_id); |
| 236 } | 239 } |
| 237 | 240 |
| 238 void ExtensionMessageService::OpenChannelOnUIThreadImpl( | 241 void ExtensionMessageService::OpenChannelOnUIThreadImpl( |
| 239 int source_routing_id, int source_port_id, IPC::Message::Sender* source, | 242 int source_routing_id, int source_port_id, int source_process_id, |
| 240 int dest_port_id, int dest_process_id, int source_process_id) { | 243 IPC::Message::Sender* source, int dest_port_id, int dest_process_id, |
| 244 const std::string& extension_id) { |
| 241 DCHECK_EQ(MessageLoop::current()->type(), MessageLoop::TYPE_UI); | 245 DCHECK_EQ(MessageLoop::current()->type(), MessageLoop::TYPE_UI); |
| 242 | 246 |
| 243 MessageChannel channel; | 247 MessageChannel channel; |
| 244 channel.port1 = source; | 248 channel.port1 = source; |
| 245 channel.port2 = RenderProcessHost::FromID(dest_process_id); | 249 channel.port2 = RenderProcessHost::FromID(dest_process_id); |
| 246 if (!channel.port1 || !channel.port2) { | 250 if (!channel.port1 || !channel.port2) { |
| 247 // One of the processes could have been closed while posting this task. | 251 // One of the processes could have been closed while posting this task. |
| 248 return; | 252 return; |
| 249 } | 253 } |
| 250 | 254 |
| 251 channels_[GET_CHANNEL_ID(source_port_id)] = channel; | 255 channels_[GET_CHANNEL_ID(source_port_id)] = channel; |
| 252 | 256 |
| 253 std::string tab_json = "null"; | 257 std::string tab_json = "null"; |
| 254 TabContents* contents = tab_util::GetTabContentsByID(source_process_id, | 258 TabContents* contents = tab_util::GetTabContentsByID(source_process_id, |
| 255 source_routing_id); | 259 source_routing_id); |
| 256 if (contents) { | 260 if (contents) { |
| 257 DictionaryValue* tab_value = ExtensionTabUtil::CreateTabValue(contents); | 261 DictionaryValue* tab_value = ExtensionTabUtil::CreateTabValue(contents); |
| 258 JSONWriter::Write(tab_value, false, &tab_json); | 262 JSONWriter::Write(tab_value, false, &tab_json); |
| 259 } | 263 } |
| 260 | 264 |
| 261 // Send the process the id for the opposite port. | 265 // Send the process the id for the opposite port. |
| 262 DispatchOnConnect(channel.port2, source_port_id, tab_json); | 266 DispatchOnConnect(channel.port2, source_port_id, tab_json, extension_id); |
| 263 } | 267 } |
| 264 | 268 |
| 265 int ExtensionMessageService::OpenAutomationChannelToExtension( | 269 int ExtensionMessageService::OpenAutomationChannelToExtension( |
| 266 int source_process_id, int routing_id, const std::string& extension_id, | 270 int source_process_id, int routing_id, const std::string& extension_id, |
| 267 IPC::Message::Sender* source) { | 271 IPC::Message::Sender* source) { |
| 268 DCHECK_EQ(MessageLoop::current()->type(), MessageLoop::TYPE_UI); | 272 DCHECK_EQ(MessageLoop::current()->type(), MessageLoop::TYPE_UI); |
| 269 | 273 |
| 270 // Lookup the targeted extension process. | 274 // Lookup the targeted extension process. |
| 271 int process_id = GetProcessIdForExtension(extension_id); | 275 int process_id = GetProcessIdForExtension(extension_id); |
| 272 if (process_id == -1) | 276 if (process_id == -1) |
| 273 return -1; | 277 return -1; |
| 274 | 278 |
| 275 DCHECK(initialized_); | 279 DCHECK(initialized_); |
| 276 | 280 |
| 277 int port1_id = -1; | 281 int port1_id = -1; |
| 278 int port2_id = -1; | 282 int port2_id = -1; |
| 279 // Create a channel ID for both sides of the channel. | 283 // Create a channel ID for both sides of the channel. |
| 280 AllocatePortIdPair(&port1_id, &port2_id); | 284 AllocatePortIdPair(&port1_id, &port2_id); |
| 281 | 285 |
| 282 // TODO(siggi): The source process- and routing ids are used to | 286 // TODO(siggi): The source process- and routing ids are used to |
| 283 // describe the originating tab to the target extension. | 287 // describe the originating tab to the target extension. |
| 284 // This isn't really appropriate here, the originating tab | 288 // This isn't really appropriate here, the originating tab |
| 285 // information should be supplied by the caller for | 289 // information should be supplied by the caller for |
| 286 // automation-initiated ports. | 290 // automation-initiated ports. |
| 287 OpenChannelOnUIThreadImpl(routing_id, port1_id, source, port2_id, | 291 OpenChannelOnUIThreadImpl(routing_id, port1_id, source_process_id, |
| 288 process_id, source_process_id); | 292 source, port2_id, process_id, extension_id); |
| 289 | 293 |
| 290 return port2_id; | 294 return port2_id; |
| 291 } | 295 } |
| 292 | 296 |
| 293 void ExtensionMessageService::CloseChannel(int port_id) { | 297 void ExtensionMessageService::CloseChannel(int port_id) { |
| 294 DCHECK_EQ(MessageLoop::current()->type(), MessageLoop::TYPE_UI); | 298 DCHECK_EQ(MessageLoop::current()->type(), MessageLoop::TYPE_UI); |
| 295 | 299 |
| 296 // Note: The channel might be gone already, if the other side closed first. | 300 // Note: The channel might be gone already, if the other side closed first. |
| 297 MessageChannelMap::iterator it = channels_.find(GET_CHANNEL_ID(port_id)); | 301 MessageChannelMap::iterator it = channels_.find(GET_CHANNEL_ID(port_id)); |
| 298 if (it != channels_.end()) | 302 if (it != channels_.end()) |
| 299 CloseChannelImpl(it, port_id); | 303 CloseChannelImpl(it, port_id); |
| 300 } | 304 } |
| 301 | 305 |
| 302 void ExtensionMessageService::CloseChannelImpl( | 306 void ExtensionMessageService::CloseChannelImpl( |
| 303 MessageChannelMap::iterator channel_iter, int port_id) { | 307 MessageChannelMap::iterator channel_iter, int port_id) { |
| 304 DCHECK_EQ(MessageLoop::current()->type(), MessageLoop::TYPE_UI); | 308 DCHECK_EQ(MessageLoop::current()->type(), MessageLoop::TYPE_UI); |
| 305 | 309 |
| 306 // Notify the other side. | 310 // Notify the other side. |
| 307 if (port_id == GET_CHANNEL_PORT1(channel_iter->first)) { | 311 if (port_id == GET_CHANNEL_PORT1(channel_iter->first)) { |
| 308 DispatchOnDisconnect(channel_iter->second.port2, port_id); | 312 DispatchOnDisconnect(channel_iter->second.port2, |
| 313 GET_OPPOSITE_PORT_ID(port_id)); |
| 309 } else { | 314 } else { |
| 310 DCHECK_EQ(port_id, GET_CHANNEL_PORT2(channel_iter->first)); | 315 DCHECK_EQ(port_id, GET_CHANNEL_PORT2(channel_iter->first)); |
| 311 DispatchOnDisconnect(channel_iter->second.port1, port_id); | 316 DispatchOnDisconnect(channel_iter->second.port1, |
| 317 GET_OPPOSITE_PORT_ID(port_id)); |
| 312 } | 318 } |
| 313 | 319 |
| 314 channels_.erase(channel_iter); | 320 channels_.erase(channel_iter); |
| 315 } | 321 } |
| 316 | 322 |
| 317 void ExtensionMessageService::PostMessageFromRenderer( | 323 void ExtensionMessageService::PostMessageFromRenderer( |
| 318 int port_id, const std::string& message) { | 324 int port_id, const std::string& message) { |
| 319 DCHECK_EQ(MessageLoop::current()->type(), MessageLoop::TYPE_UI); | 325 DCHECK_EQ(MessageLoop::current()->type(), MessageLoop::TYPE_UI); |
| 320 | 326 |
| 321 MessageChannelMap::iterator iter = | 327 MessageChannelMap::iterator iter = |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 379 for (MessageChannelMap::iterator it = channels_.begin(); | 385 for (MessageChannelMap::iterator it = channels_.begin(); |
| 380 it != channels_.end(); ) { | 386 it != channels_.end(); ) { |
| 381 MessageChannelMap::iterator current = it++; | 387 MessageChannelMap::iterator current = it++; |
| 382 if (current->second.port1 == renderer) { | 388 if (current->second.port1 == renderer) { |
| 383 CloseChannelImpl(current, GET_CHANNEL_PORT1(current->first)); | 389 CloseChannelImpl(current, GET_CHANNEL_PORT1(current->first)); |
| 384 } else if (current->second.port2 == renderer) { | 390 } else if (current->second.port2 == renderer) { |
| 385 CloseChannelImpl(current, GET_CHANNEL_PORT2(current->first)); | 391 CloseChannelImpl(current, GET_CHANNEL_PORT2(current->first)); |
| 386 } | 392 } |
| 387 } | 393 } |
| 388 } | 394 } |
| OLD | NEW |