| 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/browser/extensions/api/messaging/message_service.h" | 5 #include "chrome/browser/extensions/api/messaging/message_service.h" |
| 6 | 6 |
| 7 #include "base/atomic_sequence_num.h" | 7 #include "base/atomic_sequence_num.h" |
| 8 #include "base/bind.h" | 8 #include "base/bind.h" |
| 9 #include "base/callback.h" | 9 #include "base/callback.h" |
| 10 #include "base/json/json_writer.h" | 10 #include "base/json/json_writer.h" |
| (...skipping 14 matching lines...) Expand all Loading... |
| 25 #include "chrome/common/extensions/background_info.h" | 25 #include "chrome/common/extensions/background_info.h" |
| 26 #include "chrome/common/extensions/extension.h" | 26 #include "chrome/common/extensions/extension.h" |
| 27 #include "chrome/common/extensions/extension_messages.h" | 27 #include "chrome/common/extensions/extension_messages.h" |
| 28 #include "chrome/common/extensions/incognito_handler.h" | 28 #include "chrome/common/extensions/incognito_handler.h" |
| 29 #include "content/public/browser/browser_thread.h" | 29 #include "content/public/browser/browser_thread.h" |
| 30 #include "content/public/browser/notification_service.h" | 30 #include "content/public/browser/notification_service.h" |
| 31 #include "content/public/browser/render_process_host.h" | 31 #include "content/public/browser/render_process_host.h" |
| 32 #include "content/public/browser/render_view_host.h" | 32 #include "content/public/browser/render_view_host.h" |
| 33 #include "content/public/browser/site_instance.h" | 33 #include "content/public/browser/site_instance.h" |
| 34 #include "content/public/browser/web_contents.h" | 34 #include "content/public/browser/web_contents.h" |
| 35 #include "googleurl/src/gurl.h" |
| 35 | 36 |
| 36 using content::SiteInstance; | 37 using content::SiteInstance; |
| 37 using content::WebContents; | 38 using content::WebContents; |
| 38 | 39 |
| 39 // Since we have 2 ports for every channel, we just index channels by half the | 40 // Since we have 2 ports for every channel, we just index channels by half the |
| 40 // port ID. | 41 // port ID. |
| 41 #define GET_CHANNEL_ID(port_id) ((port_id) / 2) | 42 #define GET_CHANNEL_ID(port_id) ((port_id) / 2) |
| 42 #define GET_CHANNEL_OPENER_ID(channel_id) ((channel_id) * 2) | 43 #define GET_CHANNEL_OPENER_ID(channel_id) ((channel_id) * 2) |
| 43 #define GET_CHANNEL_RECEIVERS_ID(channel_id) ((channel_id) * 2 + 1) | 44 #define GET_CHANNEL_RECEIVERS_ID(channel_id) ((channel_id) * 2 + 1) |
| 44 | 45 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 59 "Native Messaging is not supported on this platform."; | 60 "Native Messaging is not supported on this platform."; |
| 60 } | 61 } |
| 61 | 62 |
| 62 struct MessageService::MessageChannel { | 63 struct MessageService::MessageChannel { |
| 63 scoped_ptr<MessagePort> opener; | 64 scoped_ptr<MessagePort> opener; |
| 64 scoped_ptr<MessagePort> receiver; | 65 scoped_ptr<MessagePort> receiver; |
| 65 }; | 66 }; |
| 66 | 67 |
| 67 struct MessageService::OpenChannelParams { | 68 struct MessageService::OpenChannelParams { |
| 68 content::RenderProcessHost* source; | 69 content::RenderProcessHost* source; |
| 69 std::string tab_json; | 70 DictionaryValue source_tab; |
| 70 scoped_ptr<MessagePort> receiver; | 71 scoped_ptr<MessagePort> receiver; |
| 71 int receiver_port_id; | 72 int receiver_port_id; |
| 72 std::string source_extension_id; | 73 std::string source_extension_id; |
| 73 std::string target_extension_id; | 74 std::string target_extension_id; |
| 75 GURL source_url; |
| 74 std::string channel_name; | 76 std::string channel_name; |
| 75 | 77 |
| 76 // Takes ownership of receiver. | 78 // Takes ownership of receiver. |
| 77 OpenChannelParams(content::RenderProcessHost* source, | 79 OpenChannelParams(content::RenderProcessHost* source, |
| 78 const std::string& tab_json, | 80 scoped_ptr<DictionaryValue> source_tab, |
| 79 MessagePort* receiver, | 81 MessagePort* receiver, |
| 80 int receiver_port_id, | 82 int receiver_port_id, |
| 81 const std::string& source_extension_id, | 83 const std::string& source_extension_id, |
| 82 const std::string& target_extension_id, | 84 const std::string& target_extension_id, |
| 85 const GURL& source_url, |
| 83 const std::string& channel_name) | 86 const std::string& channel_name) |
| 84 : source(source), | 87 : source(source), |
| 85 tab_json(tab_json), | |
| 86 receiver(receiver), | 88 receiver(receiver), |
| 87 receiver_port_id(receiver_port_id), | 89 receiver_port_id(receiver_port_id), |
| 88 source_extension_id(source_extension_id), | 90 source_extension_id(source_extension_id), |
| 89 target_extension_id(target_extension_id), | 91 target_extension_id(target_extension_id), |
| 90 channel_name(channel_name) {} | 92 source_url(source_url), |
| 93 channel_name(channel_name) { |
| 94 if (source_tab) |
| 95 this->source_tab.Swap(source_tab.get()); |
| 96 } |
| 97 |
| 98 private: |
| 99 DISALLOW_COPY_AND_ASSIGN(OpenChannelParams); |
| 91 }; | 100 }; |
| 92 | 101 |
| 93 namespace { | 102 namespace { |
| 94 | 103 |
| 95 static base::StaticAtomicSequenceNumber g_next_channel_id; | 104 static base::StaticAtomicSequenceNumber g_next_channel_id; |
| 96 | 105 |
| 97 static content::RenderProcessHost* GetExtensionProcess( | 106 static content::RenderProcessHost* GetExtensionProcess( |
| 98 Profile* profile, const std::string& extension_id) { | 107 Profile* profile, const std::string& extension_id) { |
| 99 SiteInstance* site_instance = | 108 SiteInstance* site_instance = |
| 100 extensions::ExtensionSystem::Get(profile)->process_manager()-> | 109 extensions::ExtensionSystem::Get(profile)->process_manager()-> |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 145 | 154 |
| 146 MessageService::~MessageService() { | 155 MessageService::~MessageService() { |
| 147 STLDeleteContainerPairSecondPointers(channels_.begin(), channels_.end()); | 156 STLDeleteContainerPairSecondPointers(channels_.begin(), channels_.end()); |
| 148 channels_.clear(); | 157 channels_.clear(); |
| 149 } | 158 } |
| 150 | 159 |
| 151 void MessageService::OpenChannelToExtension( | 160 void MessageService::OpenChannelToExtension( |
| 152 int source_process_id, int source_routing_id, int receiver_port_id, | 161 int source_process_id, int source_routing_id, int receiver_port_id, |
| 153 const std::string& source_extension_id, | 162 const std::string& source_extension_id, |
| 154 const std::string& target_extension_id, | 163 const std::string& target_extension_id, |
| 164 const GURL& source_url, |
| 155 const std::string& channel_name) { | 165 const std::string& channel_name) { |
| 156 content::RenderProcessHost* source = | 166 content::RenderProcessHost* source = |
| 157 content::RenderProcessHost::FromID(source_process_id); | 167 content::RenderProcessHost::FromID(source_process_id); |
| 158 if (!source) | 168 if (!source) |
| 159 return; | 169 return; |
| 160 Profile* profile = Profile::FromBrowserContext(source->GetBrowserContext()); | 170 Profile* profile = Profile::FromBrowserContext(source->GetBrowserContext()); |
| 161 | 171 |
| 172 const Extension* target_extension = ExtensionSystem::Get(profile)-> |
| 173 extension_service()->extensions()->GetByID(target_extension_id); |
| 174 if (!target_extension) { |
| 175 // Treat it as a disconnect. |
| 176 ExtensionMessagePort port(source, MSG_ROUTING_CONTROL, std::string()); |
| 177 port.DispatchOnDisconnect(GET_OPPOSITE_PORT_ID(receiver_port_id), |
| 178 kReceivingEndDoesntExistError); |
| 179 return; |
| 180 } |
| 181 |
| 162 // Note: we use the source's profile here. If the source is an incognito | 182 // Note: we use the source's profile here. If the source is an incognito |
| 163 // process, we will use the incognito EPM to find the right extension process, | 183 // process, we will use the incognito EPM to find the right extension process, |
| 164 // which depends on whether the extension uses spanning or split mode. | 184 // which depends on whether the extension uses spanning or split mode. |
| 165 MessagePort* receiver = new ExtensionMessagePort( | 185 MessagePort* receiver = new ExtensionMessagePort( |
| 166 GetExtensionProcess(profile, target_extension_id), MSG_ROUTING_CONTROL, | 186 GetExtensionProcess(profile, target_extension_id), MSG_ROUTING_CONTROL, |
| 167 target_extension_id); | 187 target_extension_id); |
| 168 WebContents* source_contents = tab_util::GetWebContentsByID( | 188 WebContents* source_contents = tab_util::GetWebContentsByID( |
| 169 source_process_id, source_routing_id); | 189 source_process_id, source_routing_id); |
| 170 | 190 |
| 171 // Include info about the opener's tab (if it was a tab). | 191 // Include info about the opener's tab (if it was a tab). |
| 172 std::string tab_json = "null"; | 192 scoped_ptr<DictionaryValue> source_tab; |
| 173 if (source_contents) { | 193 GURL source_url_for_tab; |
| 174 scoped_ptr<DictionaryValue> tab_value(ExtensionTabUtil::CreateTabValue( | 194 |
| 175 source_contents)); | 195 if (source_contents && ExtensionTabUtil::GetTabId(source_contents) >= 0) { |
| 176 base::JSONWriter::Write(tab_value.get(), &tab_json); | 196 // Platform apps can be sent messages, but don't have a Tab concept. |
| 197 if (!target_extension->is_platform_app()) |
| 198 source_tab.reset(ExtensionTabUtil::CreateTabValue(source_contents)); |
| 199 source_url_for_tab = source_url; |
| 177 } | 200 } |
| 178 | 201 |
| 179 OpenChannelParams* params = new OpenChannelParams(source, tab_json, receiver, | 202 OpenChannelParams* params = new OpenChannelParams(source, |
| 203 source_tab.Pass(), |
| 204 receiver, |
| 180 receiver_port_id, | 205 receiver_port_id, |
| 181 source_extension_id, | 206 source_extension_id, |
| 182 target_extension_id, | 207 target_extension_id, |
| 208 source_url_for_tab, |
| 183 channel_name); | 209 channel_name); |
| 184 | 210 |
| 185 // The target might be a lazy background page. In that case, we have to check | 211 // The target might be a lazy background page. In that case, we have to check |
| 186 // if it is loaded and ready, and if not, queue up the task and load the | 212 // if it is loaded and ready, and if not, queue up the task and load the |
| 187 // page. | 213 // page. |
| 188 if (MaybeAddPendingOpenChannelTask(profile, params)) { | 214 if (MaybeAddPendingOpenChannelTask(profile, target_extension, params)) { |
| 189 return; | 215 return; |
| 190 } | 216 } |
| 191 | 217 |
| 192 OpenChannelImpl(scoped_ptr<OpenChannelParams>(params)); | 218 OpenChannelImpl(make_scoped_ptr(params)); |
| 193 } | 219 } |
| 194 | 220 |
| 195 void MessageService::OpenChannelToNativeApp( | 221 void MessageService::OpenChannelToNativeApp( |
| 196 int source_process_id, | 222 int source_process_id, |
| 197 int source_routing_id, | 223 int source_routing_id, |
| 198 int receiver_port_id, | 224 int receiver_port_id, |
| 199 const std::string& source_extension_id, | 225 const std::string& source_extension_id, |
| 200 const std::string& native_app_name) { | 226 const std::string& native_app_name) { |
| 201 content::RenderProcessHost* source = | 227 content::RenderProcessHost* source = |
| 202 content::RenderProcessHost::FromID(source_process_id); | 228 content::RenderProcessHost::FromID(source_process_id); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 215 APIPermission::kNativeMessaging); | 241 APIPermission::kNativeMessaging); |
| 216 } | 242 } |
| 217 | 243 |
| 218 if (!has_permission) { | 244 if (!has_permission) { |
| 219 ExtensionMessagePort port(source, MSG_ROUTING_CONTROL, std::string()); | 245 ExtensionMessagePort port(source, MSG_ROUTING_CONTROL, std::string()); |
| 220 port.DispatchOnDisconnect(GET_OPPOSITE_PORT_ID(receiver_port_id), | 246 port.DispatchOnDisconnect(GET_OPPOSITE_PORT_ID(receiver_port_id), |
| 221 kMissingPermissionError); | 247 kMissingPermissionError); |
| 222 return; | 248 return; |
| 223 } | 249 } |
| 224 | 250 |
| 225 WebContents* source_contents = tab_util::GetWebContentsByID( | |
| 226 source_process_id, source_routing_id); | |
| 227 | |
| 228 // Include info about the opener's tab (if it was a tab). | |
| 229 std::string tab_json = "null"; | |
| 230 if (source_contents) { | |
| 231 scoped_ptr<DictionaryValue> tab_value(ExtensionTabUtil::CreateTabValue( | |
| 232 source_contents)); | |
| 233 base::JSONWriter::Write(tab_value.get(), &tab_json); | |
| 234 } | |
| 235 | |
| 236 scoped_ptr<MessageChannel> channel(new MessageChannel()); | 251 scoped_ptr<MessageChannel> channel(new MessageChannel()); |
| 237 channel->opener.reset(new ExtensionMessagePort(source, MSG_ROUTING_CONTROL, | 252 channel->opener.reset(new ExtensionMessagePort(source, MSG_ROUTING_CONTROL, |
| 238 source_extension_id)); | 253 source_extension_id)); |
| 239 | 254 |
| 240 scoped_ptr<NativeMessageProcessHost> native_process = | 255 scoped_ptr<NativeMessageProcessHost> native_process = |
| 241 NativeMessageProcessHost::Create( | 256 NativeMessageProcessHost::Create( |
| 242 base::WeakPtr<NativeMessageProcessHost::Client>( | 257 base::WeakPtr<NativeMessageProcessHost::Client>( |
| 243 weak_factory_.GetWeakPtr()), | 258 weak_factory_.GetWeakPtr()), |
| 244 source_extension_id, native_app_name, receiver_port_id); | 259 source_extension_id, native_app_name, receiver_port_id); |
| 245 | 260 |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 287 | 302 |
| 288 if (contents && contents->GetController().NeedsReload()) { | 303 if (contents && contents->GetController().NeedsReload()) { |
| 289 // The tab isn't loaded yet. Don't attempt to connect. Treat this as a | 304 // The tab isn't loaded yet. Don't attempt to connect. Treat this as a |
| 290 // disconnect. | 305 // disconnect. |
| 291 ExtensionMessagePort port(source, MSG_ROUTING_CONTROL, extension_id); | 306 ExtensionMessagePort port(source, MSG_ROUTING_CONTROL, extension_id); |
| 292 port.DispatchOnDisconnect(GET_OPPOSITE_PORT_ID(receiver_port_id), | 307 port.DispatchOnDisconnect(GET_OPPOSITE_PORT_ID(receiver_port_id), |
| 293 kReceivingEndDoesntExistError); | 308 kReceivingEndDoesntExistError); |
| 294 return; | 309 return; |
| 295 } | 310 } |
| 296 | 311 |
| 297 WebContents* source_contents = tab_util::GetWebContentsByID( | 312 scoped_ptr<OpenChannelParams> params(new OpenChannelParams( |
| 298 source_process_id, source_routing_id); | 313 source, |
| 299 | 314 scoped_ptr<DictionaryValue>(), // Source tab doesn't make sense for |
| 300 // Include info about the opener's tab (if it was a tab). | 315 // opening to tabs. |
| 301 std::string tab_json = "null"; | 316 receiver.release(), |
| 302 if (source_contents) { | 317 receiver_port_id, |
| 303 scoped_ptr<DictionaryValue> tab_value(ExtensionTabUtil::CreateTabValue( | 318 extension_id, |
| 304 source_contents)); | 319 extension_id, |
| 305 base::JSONWriter::Write(tab_value.get(), &tab_json); | 320 GURL(), // Source URL doesn't make sense for opening to tabs. |
| 306 } | 321 channel_name)); |
| 307 | |
| 308 scoped_ptr<OpenChannelParams> params(new OpenChannelParams(source, tab_json, | |
| 309 receiver.release(), | |
| 310 receiver_port_id, | |
| 311 extension_id, | |
| 312 extension_id, | |
| 313 channel_name)); | |
| 314 OpenChannelImpl(params.Pass()); | 322 OpenChannelImpl(params.Pass()); |
| 315 } | 323 } |
| 316 | 324 |
| 317 bool MessageService::OpenChannelImpl(scoped_ptr<OpenChannelParams> params) { | 325 bool MessageService::OpenChannelImpl(scoped_ptr<OpenChannelParams> params) { |
| 318 if (!params->source) | 326 if (!params->source) |
| 319 return false; // Closed while in flight. | 327 return false; // Closed while in flight. |
| 320 | 328 |
| 321 if (!params->receiver.get() || !params->receiver->GetRenderProcessHost()) { | 329 if (!params->receiver || !params->receiver->GetRenderProcessHost()) { |
| 322 // Treat it as a disconnect. | 330 // Treat it as a disconnect. |
| 323 ExtensionMessagePort port( | 331 ExtensionMessagePort port( |
| 324 params->source, MSG_ROUTING_CONTROL, std::string()); | 332 params->source, MSG_ROUTING_CONTROL, std::string()); |
| 325 port.DispatchOnDisconnect(GET_OPPOSITE_PORT_ID(params->receiver_port_id), | 333 port.DispatchOnDisconnect(GET_OPPOSITE_PORT_ID(params->receiver_port_id), |
| 326 kReceivingEndDoesntExistError); | 334 kReceivingEndDoesntExistError); |
| 327 return false; | 335 return false; |
| 328 } | 336 } |
| 329 | 337 |
| 330 // Add extra paranoid CHECKs, since we have crash reports of this being NULL. | 338 // Add extra paranoid CHECKs, since we have crash reports of this being NULL. |
| 331 // http://code.google.com/p/chromium/issues/detail?id=19067 | 339 // http://code.google.com/p/chromium/issues/detail?id=19067 |
| 332 CHECK(params->receiver->GetRenderProcessHost()); | 340 CHECK(params->receiver->GetRenderProcessHost()); |
| 333 | 341 |
| 334 MessageChannel* channel(new MessageChannel); | 342 MessageChannel* channel(new MessageChannel); |
| 335 channel->opener.reset(new ExtensionMessagePort(params->source, | 343 channel->opener.reset(new ExtensionMessagePort(params->source, |
| 336 MSG_ROUTING_CONTROL, | 344 MSG_ROUTING_CONTROL, |
| 337 params->source_extension_id)); | 345 params->source_extension_id)); |
| 338 channel->receiver.reset(params->receiver.release()); | 346 channel->receiver.reset(params->receiver.release()); |
| 339 | 347 |
| 340 CHECK(channel->receiver->GetRenderProcessHost()); | 348 CHECK(channel->receiver->GetRenderProcessHost()); |
| 341 | 349 |
| 342 AddChannel(channel, params->receiver_port_id); | 350 AddChannel(channel, params->receiver_port_id); |
| 343 | 351 |
| 344 CHECK(channel->receiver->GetRenderProcessHost()); | 352 CHECK(channel->receiver->GetRenderProcessHost()); |
| 345 | 353 |
| 346 // Send the connect event to the receiver. Give it the opener's port ID (the | 354 // Send the connect event to the receiver. Give it the opener's port ID (the |
| 347 // opener has the opposite port ID). | 355 // opener has the opposite port ID). |
| 348 channel->receiver->DispatchOnConnect(params->receiver_port_id, | 356 channel->receiver->DispatchOnConnect(params->receiver_port_id, |
| 349 params->channel_name, params->tab_json, | 357 params->channel_name, |
| 358 params->source_tab, |
| 350 params->source_extension_id, | 359 params->source_extension_id, |
| 351 params->target_extension_id); | 360 params->target_extension_id, |
| 361 params->source_url); |
| 352 | 362 |
| 353 // Keep both ends of the channel alive until the channel is closed. | 363 // Keep both ends of the channel alive until the channel is closed. |
| 354 channel->opener->IncrementLazyKeepaliveCount(); | 364 channel->opener->IncrementLazyKeepaliveCount(); |
| 355 channel->receiver->IncrementLazyKeepaliveCount(); | 365 channel->receiver->IncrementLazyKeepaliveCount(); |
| 356 return true; | 366 return true; |
| 357 } | 367 } |
| 358 | 368 |
| 359 void MessageService::AddChannel(MessageChannel* channel, int receiver_port_id) { | 369 void MessageService::AddChannel(MessageChannel* channel, int receiver_port_id) { |
| 360 int channel_id = GET_CHANNEL_ID(receiver_port_id); | 370 int channel_id = GET_CHANNEL_ID(receiver_port_id); |
| 361 CHECK(channels_.find(channel_id) == channels_.end()); | 371 CHECK(channels_.find(channel_id) == channels_.end()); |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 472 std::string(), notify_other_port); | 482 std::string(), notify_other_port); |
| 473 } else if (receiver_process == process) { | 483 } else if (receiver_process == process) { |
| 474 CloseChannelImpl(current, GET_CHANNEL_RECEIVERS_ID(current->first), | 484 CloseChannelImpl(current, GET_CHANNEL_RECEIVERS_ID(current->first), |
| 475 std::string(), notify_other_port); | 485 std::string(), notify_other_port); |
| 476 } | 486 } |
| 477 } | 487 } |
| 478 } | 488 } |
| 479 | 489 |
| 480 bool MessageService::MaybeAddPendingOpenChannelTask( | 490 bool MessageService::MaybeAddPendingOpenChannelTask( |
| 481 Profile* profile, | 491 Profile* profile, |
| 492 const Extension* extension, |
| 482 OpenChannelParams* params) { | 493 OpenChannelParams* params) { |
| 483 ExtensionService* service = profile->GetExtensionService(); | 494 if (!BackgroundInfo::HasLazyBackgroundPage(extension)) |
| 484 const std::string& extension_id = params->target_extension_id; | 495 return false; |
| 485 const Extension* extension = service->extensions()->GetByID(extension_id); | |
| 486 if (extension && BackgroundInfo::HasLazyBackgroundPage(extension)) { | |
| 487 // If the extension uses spanning incognito mode, make sure we're always | |
| 488 // using the original profile since that is what the extension process | |
| 489 // will use. | |
| 490 if (!IncognitoInfo::IsSplitMode(extension)) | |
| 491 profile = profile->GetOriginalProfile(); | |
| 492 | 496 |
| 493 if (lazy_background_task_queue_->ShouldEnqueueTask(profile, extension)) { | 497 // If the extension uses spanning incognito mode, make sure we're always |
| 494 pending_channels_[GET_CHANNEL_ID(params->receiver_port_id)] = | 498 // using the original profile since that is what the extension process |
| 495 PendingChannel(profile, extension_id); | 499 // will use. |
| 496 scoped_ptr<OpenChannelParams> scoped_params(params); | 500 if (!IncognitoInfo::IsSplitMode(extension)) |
| 497 lazy_background_task_queue_->AddPendingTask(profile, extension_id, | 501 profile = profile->GetOriginalProfile(); |
| 498 base::Bind(&MessageService::PendingOpenChannel, | |
| 499 weak_factory_.GetWeakPtr(), base::Passed(&scoped_params), | |
| 500 params->source->GetID())); | |
| 501 return true; | |
| 502 } | |
| 503 } | |
| 504 | 502 |
| 505 return false; | 503 if (!lazy_background_task_queue_->ShouldEnqueueTask(profile, extension)) |
| 504 return false; |
| 505 |
| 506 pending_channels_[GET_CHANNEL_ID(params->receiver_port_id)] = |
| 507 PendingChannel(profile, extension->id()); |
| 508 scoped_ptr<OpenChannelParams> scoped_params(params); |
| 509 lazy_background_task_queue_->AddPendingTask(profile, extension->id(), |
| 510 base::Bind(&MessageService::PendingOpenChannel, |
| 511 weak_factory_.GetWeakPtr(), base::Passed(&scoped_params), |
| 512 params->source->GetID())); |
| 513 return true; |
| 506 } | 514 } |
| 507 | 515 |
| 508 void MessageService::PendingOpenChannel(scoped_ptr<OpenChannelParams> params, | 516 void MessageService::PendingOpenChannel(scoped_ptr<OpenChannelParams> params, |
| 509 int source_process_id, | 517 int source_process_id, |
| 510 ExtensionHost* host) { | 518 ExtensionHost* host) { |
| 511 if (!host) | 519 if (!host) |
| 512 return; // TODO(mpcomplete): notify source of disconnect? | 520 return; // TODO(mpcomplete): notify source of disconnect? |
| 513 | 521 |
| 514 // Re-lookup the source process since it may no longer be valid. | 522 // Re-lookup the source process since it may no longer be valid. |
| 515 content::RenderProcessHost* source = | 523 content::RenderProcessHost* source = |
| 516 content::RenderProcessHost::FromID(source_process_id); | 524 content::RenderProcessHost::FromID(source_process_id); |
| 517 if (!source) | 525 if (!source) |
| 518 return; | 526 return; |
| 519 | 527 |
| 520 params->source = source; | 528 params->source = source; |
| 521 params->receiver.reset(new ExtensionMessagePort(host->render_process_host(), | 529 params->receiver.reset(new ExtensionMessagePort(host->render_process_host(), |
| 522 MSG_ROUTING_CONTROL, | 530 MSG_ROUTING_CONTROL, |
| 523 params->target_extension_id)); | 531 params->target_extension_id)); |
| 524 OpenChannelImpl(params.Pass()); | 532 OpenChannelImpl(params.Pass()); |
| 525 } | 533 } |
| 526 | 534 |
| 527 } // namespace extensions | 535 } // namespace extensions |
| OLD | NEW |