| 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 #include "chrome/browser/extensions/extension_message_service.h" | 5 #include "chrome/browser/extensions/extension_message_service.h" |
| 6 | 6 |
| 7 #include "base/atomic_sequence_num.h" | 7 #include "base/atomic_sequence_num.h" |
| 8 #include "base/json/json_writer.h" | 8 #include "base/json/json_writer.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 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 197 const std::string& event_name) { | 197 const std::string& event_name) { |
| 198 return (listeners_.find(event_name) != listeners_.end() && | 198 return (listeners_.find(event_name) != listeners_.end() && |
| 199 !listeners_[event_name].empty()); | 199 !listeners_[event_name].empty()); |
| 200 } | 200 } |
| 201 | 201 |
| 202 void ExtensionMessageService::OpenChannelToExtension( | 202 void ExtensionMessageService::OpenChannelToExtension( |
| 203 int source_process_id, int source_routing_id, int receiver_port_id, | 203 int source_process_id, int source_routing_id, int receiver_port_id, |
| 204 const std::string& source_extension_id, | 204 const std::string& source_extension_id, |
| 205 const std::string& target_extension_id, | 205 const std::string& target_extension_id, |
| 206 const std::string& channel_name) { | 206 const std::string& channel_name) { |
| 207 if (!profile_) | |
| 208 return; | |
| 209 | |
| 210 RenderProcessHost* source = RenderProcessHost::FromID(source_process_id); | 207 RenderProcessHost* source = RenderProcessHost::FromID(source_process_id); |
| 211 if (!source) | 208 if (!source) |
| 212 return; | 209 return; |
| 213 | 210 |
| 211 // Note: we use the source's profile here. If the source is an incognito |
| 212 // process, we will use the incognito EPM to find the right extension process, |
| 213 // which depends on whether the extension uses spanning or split mode. |
| 214 MessagePort receiver( | 214 MessagePort receiver( |
| 215 profile_->GetExtensionProcessManager()->GetExtensionProcess( | 215 source->profile()->GetExtensionProcessManager()->GetExtensionProcess( |
| 216 target_extension_id), | 216 target_extension_id), |
| 217 MSG_ROUTING_CONTROL); | 217 MSG_ROUTING_CONTROL); |
| 218 TabContents* source_contents = tab_util::GetTabContentsByID( | 218 TabContents* source_contents = tab_util::GetTabContentsByID( |
| 219 source_process_id, source_routing_id); | 219 source_process_id, source_routing_id); |
| 220 | 220 |
| 221 // Include info about the opener's tab (if it was a tab). | 221 // Include info about the opener's tab (if it was a tab). |
| 222 std::string tab_json = "null"; | 222 std::string tab_json = "null"; |
| 223 if (source_contents) { | 223 if (source_contents) { |
| 224 scoped_ptr<DictionaryValue> tab_value( | 224 scoped_ptr<DictionaryValue> tab_value( |
| 225 ExtensionTabUtil::CreateTabValue(source_contents)); | 225 ExtensionTabUtil::CreateTabValue(source_contents)); |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 314 const std::string& extension_id, const std::string& channel_name, | 314 const std::string& extension_id, const std::string& channel_name, |
| 315 const std::string& tab_json, IPC::Message::Sender* source) { | 315 const std::string& tab_json, IPC::Message::Sender* source) { |
| 316 DCHECK(profile_); | 316 DCHECK(profile_); |
| 317 | 317 |
| 318 int port1_id = -1; | 318 int port1_id = -1; |
| 319 int port2_id = -1; | 319 int port2_id = -1; |
| 320 // Create a channel ID for both sides of the channel. | 320 // Create a channel ID for both sides of the channel. |
| 321 AllocatePortIdPair(&port1_id, &port2_id); | 321 AllocatePortIdPair(&port1_id, &port2_id); |
| 322 | 322 |
| 323 MessagePort receiver( | 323 MessagePort receiver( |
| 324 profile_->GetExtensionProcessManager()-> | 324 profile_->GetExtensionProcessManager()->GetExtensionProcess(extension_id), |
| 325 GetExtensionProcess(extension_id), | |
| 326 MSG_ROUTING_CONTROL); | 325 MSG_ROUTING_CONTROL); |
| 327 if (!OpenChannelImpl(source, tab_json, receiver, port2_id, | 326 if (!OpenChannelImpl(source, tab_json, receiver, port2_id, |
| 328 extension_id, extension_id, channel_name)) | 327 extension_id, extension_id, channel_name)) |
| 329 return -1; | 328 return -1; |
| 330 | 329 |
| 331 return port1_id; | 330 return port1_id; |
| 332 } | 331 } |
| 333 | 332 |
| 334 int ExtensionMessageService::OpenSpecialChannelToTab( | 333 int ExtensionMessageService::OpenSpecialChannelToTab( |
| 335 const std::string& extension_id, const std::string& channel_name, | 334 const std::string& extension_id, const std::string& channel_name, |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 386 // Figure out which port the ID corresponds to. | 385 // Figure out which port the ID corresponds to. |
| 387 int dest_port_id = GET_OPPOSITE_PORT_ID(source_port_id); | 386 int dest_port_id = GET_OPPOSITE_PORT_ID(source_port_id); |
| 388 const MessagePort& port = IS_OPENER_PORT_ID(dest_port_id) ? | 387 const MessagePort& port = IS_OPENER_PORT_ID(dest_port_id) ? |
| 389 iter->second->opener : iter->second->receiver; | 388 iter->second->opener : iter->second->receiver; |
| 390 | 389 |
| 391 DispatchOnMessage(port, message, dest_port_id); | 390 DispatchOnMessage(port, message, dest_port_id); |
| 392 } | 391 } |
| 393 | 392 |
| 394 void ExtensionMessageService::DispatchEventToRenderers( | 393 void ExtensionMessageService::DispatchEventToRenderers( |
| 395 const std::string& event_name, const std::string& event_args, | 394 const std::string& event_name, const std::string& event_args, |
| 396 bool has_incognito_data, const GURL& event_url) { | 395 Profile* source_profile, const GURL& event_url) { |
| 396 if (!profile_) |
| 397 return; |
| 398 |
| 399 // We don't expect to get events from a completely different profile. |
| 400 DCHECK(!source_profile || profile_->IsSameProfile(source_profile)); |
| 401 |
| 397 ListenerMap::iterator it = listeners_.find(event_name); | 402 ListenerMap::iterator it = listeners_.find(event_name); |
| 398 if (it == listeners_.end()) | 403 if (it == listeners_.end()) |
| 399 return; | 404 return; |
| 400 | 405 |
| 401 std::set<int>& pids = it->second; | 406 std::set<int>& pids = it->second; |
| 402 | 407 |
| 403 // Send the event only to renderers that are listening for it. | 408 // Send the event only to renderers that are listening for it. |
| 404 for (std::set<int>::iterator pid = pids.begin(); pid != pids.end(); ++pid) { | 409 for (std::set<int>::iterator pid = pids.begin(); pid != pids.end(); ++pid) { |
| 405 RenderProcessHost* renderer = RenderProcessHost::FromID(*pid); | 410 RenderProcessHost* renderer = RenderProcessHost::FromID(*pid); |
| 406 if (!renderer) | 411 if (!renderer) |
| 407 continue; | 412 continue; |
| 408 if (!ChildProcessSecurityPolicy::GetInstance()-> | 413 if (!ChildProcessSecurityPolicy::GetInstance()-> |
| 409 HasExtensionBindings(*pid)) { | 414 HasExtensionBindings(*pid)) { |
| 410 // Don't send browser-level events to unprivileged processes. | 415 // Don't send browser-level events to unprivileged processes. |
| 411 continue; | 416 continue; |
| 412 } | 417 } |
| 413 | 418 |
| 414 DispatchEvent( | 419 // Is this event from a different profile than the renderer (ie, an |
| 415 renderer, event_name, event_args, has_incognito_data, event_url); | 420 // incognito tab event sent to a normal process, or vice versa). |
| 421 bool cross_profile = |
| 422 source_profile && renderer->profile() != source_profile; |
| 423 DispatchEvent(renderer, event_name, event_args, cross_profile, event_url); |
| 416 } | 424 } |
| 417 } | 425 } |
| 418 | 426 |
| 419 void ExtensionMessageService::DispatchEventToExtension( | 427 void ExtensionMessageService::DispatchEventToExtension( |
| 420 const std::string& extension_id, | 428 const std::string& extension_id, |
| 421 const std::string& event_name, const std::string& event_args, | 429 const std::string& event_name, const std::string& event_args, |
| 422 bool has_incognito_data, const GURL& event_url) { | 430 Profile* source_profile, const GURL& event_url) { |
| 423 DispatchEventToRenderers(GetPerExtensionEventName(event_name, extension_id), | 431 DispatchEventToRenderers(GetPerExtensionEventName(event_name, extension_id), |
| 424 event_args, has_incognito_data, event_url); | 432 event_args, source_profile, event_url); |
| 425 } | 433 } |
| 426 | 434 |
| 427 void ExtensionMessageService::Observe(NotificationType type, | 435 void ExtensionMessageService::Observe(NotificationType type, |
| 428 const NotificationSource& source, | 436 const NotificationSource& source, |
| 429 const NotificationDetails& details) { | 437 const NotificationDetails& details) { |
| 430 switch (type.value) { | 438 switch (type.value) { |
| 431 case NotificationType::RENDERER_PROCESS_TERMINATED: | 439 case NotificationType::RENDERER_PROCESS_TERMINATED: |
| 432 case NotificationType::RENDERER_PROCESS_CLOSED: { | 440 case NotificationType::RENDERER_PROCESS_CLOSED: { |
| 433 RenderProcessHost* renderer = Source<RenderProcessHost>(source).ptr(); | 441 RenderProcessHost* renderer = Source<RenderProcessHost>(source).ptr(); |
| 434 OnSenderClosed(renderer); | 442 OnSenderClosed(renderer); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 464 | 472 |
| 465 if (current->second->opener.sender == sender) { | 473 if (current->second->opener.sender == sender) { |
| 466 CloseChannelImpl(current, GET_CHANNEL_OPENER_ID(current->first), | 474 CloseChannelImpl(current, GET_CHANNEL_OPENER_ID(current->first), |
| 467 notify_other_port); | 475 notify_other_port); |
| 468 } else if (current->second->receiver.sender == sender) { | 476 } else if (current->second->receiver.sender == sender) { |
| 469 CloseChannelImpl(current, GET_CHANNEL_RECEIVERS_ID(current->first), | 477 CloseChannelImpl(current, GET_CHANNEL_RECEIVERS_ID(current->first), |
| 470 notify_other_port); | 478 notify_other_port); |
| 471 } | 479 } |
| 472 } | 480 } |
| 473 } | 481 } |
| OLD | NEW |