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" |
11 #include "base/lazy_instance.h" | 11 #include "base/lazy_instance.h" |
12 #include "base/metrics/histogram.h" | 12 #include "base/metrics/histogram.h" |
13 #include "base/prefs/pref_service.h" | 13 #include "base/prefs/pref_service.h" |
14 #include "base/stl_util.h" | 14 #include "base/stl_util.h" |
15 #include "chrome/browser/chrome_notification_types.h" | |
16 #include "chrome/browser/extensions/api/messaging/extension_message_port.h" | 15 #include "chrome/browser/extensions/api/messaging/extension_message_port.h" |
17 #include "chrome/browser/extensions/api/messaging/incognito_connectability.h" | 16 #include "chrome/browser/extensions/api/messaging/incognito_connectability.h" |
18 #include "chrome/browser/extensions/api/messaging/native_message_port.h" | 17 #include "chrome/browser/extensions/api/messaging/native_message_port.h" |
19 #include "chrome/browser/extensions/api/tabs/tabs_constants.h" | 18 #include "chrome/browser/extensions/api/tabs/tabs_constants.h" |
20 #include "chrome/browser/extensions/extension_service.h" | 19 #include "chrome/browser/extensions/extension_service.h" |
21 #include "chrome/browser/extensions/extension_tab_util.h" | 20 #include "chrome/browser/extensions/extension_tab_util.h" |
22 #include "chrome/browser/extensions/extension_util.h" | 21 #include "chrome/browser/extensions/extension_util.h" |
23 #include "chrome/browser/profiles/profile.h" | 22 #include "chrome/browser/profiles/profile.h" |
24 #include "chrome/browser/tab_contents/tab_util.h" | 23 #include "chrome/browser/tab_contents/tab_util.h" |
25 #include "components/guest_view/common/guest_view_constants.h" | 24 #include "components/guest_view/common/guest_view_constants.h" |
26 #include "content/public/browser/browser_thread.h" | 25 #include "content/public/browser/browser_thread.h" |
27 #include "content/public/browser/notification_service.h" | |
28 #include "content/public/browser/render_frame_host.h" | 26 #include "content/public/browser/render_frame_host.h" |
29 #include "content/public/browser/render_process_host.h" | 27 #include "content/public/browser/render_process_host.h" |
30 #include "content/public/browser/render_view_host.h" | 28 #include "content/public/browser/render_view_host.h" |
31 #include "content/public/browser/render_widget_host.h" | 29 #include "content/public/browser/render_widget_host.h" |
32 #include "content/public/browser/render_widget_host_view.h" | 30 #include "content/public/browser/render_widget_host_view.h" |
33 #include "content/public/browser/site_instance.h" | 31 #include "content/public/browser/site_instance.h" |
34 #include "content/public/browser/web_contents.h" | 32 #include "content/public/browser/web_contents.h" |
35 #include "content/public/common/child_process_host.h" | 33 #include "content/public/common/child_process_host.h" |
36 #include "extensions/browser/event_router.h" | 34 #include "extensions/browser/event_router.h" |
35 #include "extensions/browser/extension_api_frame_id_map.h" | |
37 #include "extensions/browser/extension_host.h" | 36 #include "extensions/browser/extension_host.h" |
38 #include "extensions/browser/extension_registry.h" | 37 #include "extensions/browser/extension_registry.h" |
39 #include "extensions/browser/extension_system.h" | 38 #include "extensions/browser/extension_system.h" |
40 #include "extensions/browser/extension_util.h" | 39 #include "extensions/browser/extension_util.h" |
41 #include "extensions/browser/extensions_browser_client.h" | 40 #include "extensions/browser/extensions_browser_client.h" |
42 #include "extensions/browser/guest_view/web_view/web_view_guest.h" | 41 #include "extensions/browser/guest_view/web_view/web_view_guest.h" |
43 #include "extensions/browser/lazy_background_task_queue.h" | 42 #include "extensions/browser/lazy_background_task_queue.h" |
44 #include "extensions/browser/pref_names.h" | 43 #include "extensions/browser/pref_names.h" |
45 #include "extensions/browser/process_manager.h" | 44 #include "extensions/browser/process_manager.h" |
46 #include "extensions/common/extension.h" | 45 #include "extensions/common/extension.h" |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
121 "administrator."; | 120 "administrator."; |
122 #endif | 121 #endif |
123 | 122 |
124 struct MessageService::MessageChannel { | 123 struct MessageService::MessageChannel { |
125 scoped_ptr<MessagePort> opener; | 124 scoped_ptr<MessagePort> opener; |
126 scoped_ptr<MessagePort> receiver; | 125 scoped_ptr<MessagePort> receiver; |
127 }; | 126 }; |
128 | 127 |
129 struct MessageService::OpenChannelParams { | 128 struct MessageService::OpenChannelParams { |
130 int source_process_id; | 129 int source_process_id; |
130 int source_routing_id; | |
131 scoped_ptr<base::DictionaryValue> source_tab; | 131 scoped_ptr<base::DictionaryValue> source_tab; |
132 int source_frame_id; | 132 int source_frame_id; |
133 int target_tab_id; | |
134 int target_frame_id; | |
135 scoped_ptr<MessagePort> receiver; | 133 scoped_ptr<MessagePort> receiver; |
136 int receiver_port_id; | 134 int receiver_port_id; |
137 std::string source_extension_id; | 135 std::string source_extension_id; |
138 std::string target_extension_id; | 136 std::string target_extension_id; |
139 GURL source_url; | 137 GURL source_url; |
140 std::string channel_name; | 138 std::string channel_name; |
141 bool include_tls_channel_id; | 139 bool include_tls_channel_id; |
142 std::string tls_channel_id; | 140 std::string tls_channel_id; |
143 bool include_guest_process_info; | 141 bool include_guest_process_info; |
144 | 142 |
145 // Takes ownership of receiver. | 143 // Takes ownership of receiver. |
146 OpenChannelParams(int source_process_id, | 144 OpenChannelParams(int source_process_id, |
145 int source_routing_id, | |
147 scoped_ptr<base::DictionaryValue> source_tab, | 146 scoped_ptr<base::DictionaryValue> source_tab, |
148 int source_frame_id, | 147 int source_frame_id, |
149 int target_tab_id, | |
150 int target_frame_id, | |
151 MessagePort* receiver, | 148 MessagePort* receiver, |
152 int receiver_port_id, | 149 int receiver_port_id, |
153 const std::string& source_extension_id, | 150 const std::string& source_extension_id, |
154 const std::string& target_extension_id, | 151 const std::string& target_extension_id, |
155 const GURL& source_url, | 152 const GURL& source_url, |
156 const std::string& channel_name, | 153 const std::string& channel_name, |
157 bool include_tls_channel_id, | 154 bool include_tls_channel_id, |
158 bool include_guest_process_info) | 155 bool include_guest_process_info) |
159 : source_process_id(source_process_id), | 156 : source_process_id(source_process_id), |
157 source_routing_id(source_routing_id), | |
160 source_frame_id(source_frame_id), | 158 source_frame_id(source_frame_id), |
161 target_tab_id(target_tab_id), | |
162 target_frame_id(target_frame_id), | |
163 receiver(receiver), | 159 receiver(receiver), |
164 receiver_port_id(receiver_port_id), | 160 receiver_port_id(receiver_port_id), |
165 source_extension_id(source_extension_id), | 161 source_extension_id(source_extension_id), |
166 target_extension_id(target_extension_id), | 162 target_extension_id(target_extension_id), |
167 source_url(source_url), | 163 source_url(source_url), |
168 channel_name(channel_name), | 164 channel_name(channel_name), |
169 include_tls_channel_id(include_tls_channel_id), | 165 include_tls_channel_id(include_tls_channel_id), |
170 include_guest_process_info(include_guest_process_info) { | 166 include_guest_process_info(include_guest_process_info) { |
171 if (source_tab) | 167 if (source_tab) |
172 this->source_tab = source_tab.Pass(); | 168 this->source_tab = source_tab.Pass(); |
(...skipping 11 matching lines...) Expand all Loading... | |
184 BrowserContext* context, | 180 BrowserContext* context, |
185 const std::string& extension_id) { | 181 const std::string& extension_id) { |
186 scoped_refptr<SiteInstance> site_instance = | 182 scoped_refptr<SiteInstance> site_instance = |
187 ProcessManager::Get(context)->GetSiteInstanceForURL( | 183 ProcessManager::Get(context)->GetSiteInstanceForURL( |
188 Extension::GetBaseURLFromExtensionId(extension_id)); | 184 Extension::GetBaseURLFromExtensionId(extension_id)); |
189 return site_instance->HasProcess() ? site_instance->GetProcess() : NULL; | 185 return site_instance->HasProcess() ? site_instance->GetProcess() : NULL; |
190 } | 186 } |
191 | 187 |
192 } // namespace | 188 } // namespace |
193 | 189 |
194 content::RenderProcessHost* | |
195 MessageService::MessagePort::GetRenderProcessHost() { | |
196 return NULL; | |
197 } | |
198 | |
199 // static | 190 // static |
200 void MessageService::AllocatePortIdPair(int* port1, int* port2) { | 191 void MessageService::AllocatePortIdPair(int* port1, int* port2) { |
201 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 192 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
202 | 193 |
203 unsigned channel_id = | 194 unsigned channel_id = |
204 static_cast<unsigned>(g_next_channel_id.GetNext()) % (kint32max/2); | 195 static_cast<unsigned>(g_next_channel_id.GetNext()) % (kint32max/2); |
205 unsigned port1_id = channel_id * 2; | 196 unsigned port1_id = channel_id * 2; |
206 unsigned port2_id = channel_id * 2 + 1; | 197 unsigned port2_id = channel_id * 2 + 1; |
207 | 198 |
208 // Sanity checks to make sure our channel<->port converters are correct. | 199 // Sanity checks to make sure our channel<->port converters are correct. |
209 DCHECK(IS_OPENER_PORT_ID(port1_id)); | 200 DCHECK(IS_OPENER_PORT_ID(port1_id)); |
210 DCHECK_EQ(GET_OPPOSITE_PORT_ID(port1_id), port2_id); | 201 DCHECK_EQ(GET_OPPOSITE_PORT_ID(port1_id), port2_id); |
211 DCHECK_EQ(GET_OPPOSITE_PORT_ID(port2_id), port1_id); | 202 DCHECK_EQ(GET_OPPOSITE_PORT_ID(port2_id), port1_id); |
212 DCHECK_EQ(GET_CHANNEL_ID(port1_id), GET_CHANNEL_ID(port2_id)); | 203 DCHECK_EQ(GET_CHANNEL_ID(port1_id), GET_CHANNEL_ID(port2_id)); |
213 DCHECK_EQ(GET_CHANNEL_ID(port1_id), channel_id); | 204 DCHECK_EQ(GET_CHANNEL_ID(port1_id), channel_id); |
214 DCHECK_EQ(GET_CHANNEL_OPENER_ID(channel_id), port1_id); | 205 DCHECK_EQ(GET_CHANNEL_OPENER_ID(channel_id), port1_id); |
215 DCHECK_EQ(GET_CHANNEL_RECEIVERS_ID(channel_id), port2_id); | 206 DCHECK_EQ(GET_CHANNEL_RECEIVERS_ID(channel_id), port2_id); |
216 | 207 |
217 *port1 = port1_id; | 208 *port1 = port1_id; |
218 *port2 = port2_id; | 209 *port2 = port2_id; |
219 } | 210 } |
220 | 211 |
221 MessageService::MessageService(BrowserContext* context) | 212 MessageService::MessageService(BrowserContext* context) |
222 : lazy_background_task_queue_( | 213 : lazy_background_task_queue_( |
223 LazyBackgroundTaskQueue::Get(context)), | 214 LazyBackgroundTaskQueue::Get(context)), |
224 weak_factory_(this) { | 215 weak_factory_(this) { |
225 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 216 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
226 | |
227 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_TERMINATED, | |
228 content::NotificationService::AllBrowserContextsAndSources()); | |
229 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED, | |
230 content::NotificationService::AllBrowserContextsAndSources()); | |
231 } | 217 } |
232 | 218 |
233 MessageService::~MessageService() { | 219 MessageService::~MessageService() { |
234 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 220 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
235 | 221 |
236 STLDeleteContainerPairSecondPointers(channels_.begin(), channels_.end()); | 222 STLDeleteContainerPairSecondPointers(channels_.begin(), channels_.end()); |
237 channels_.clear(); | 223 channels_.clear(); |
238 } | 224 } |
239 | 225 |
240 static base::LazyInstance<BrowserContextKeyedAPIFactory<MessageService> > | 226 static base::LazyInstance<BrowserContextKeyedAPIFactory<MessageService> > |
(...skipping 12 matching lines...) Expand all Loading... | |
253 | 239 |
254 void MessageService::OpenChannelToExtension( | 240 void MessageService::OpenChannelToExtension( |
255 int source_process_id, int source_routing_id, int receiver_port_id, | 241 int source_process_id, int source_routing_id, int receiver_port_id, |
256 const std::string& source_extension_id, | 242 const std::string& source_extension_id, |
257 const std::string& target_extension_id, | 243 const std::string& target_extension_id, |
258 const GURL& source_url, | 244 const GURL& source_url, |
259 const std::string& channel_name, | 245 const std::string& channel_name, |
260 bool include_tls_channel_id) { | 246 bool include_tls_channel_id) { |
261 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 247 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
262 | 248 |
263 content::RenderProcessHost* source = | 249 content::RenderFrameHost* source = |
264 content::RenderProcessHost::FromID(source_process_id); | 250 content::RenderFrameHost::FromID(source_process_id, source_routing_id); |
265 if (!source) | 251 if (!source) |
266 return; | 252 return; |
267 BrowserContext* context = source->GetBrowserContext(); | 253 BrowserContext* context = source->GetProcess()->GetBrowserContext(); |
268 | 254 |
269 ExtensionRegistry* registry = ExtensionRegistry::Get(context); | 255 ExtensionRegistry* registry = ExtensionRegistry::Get(context); |
270 const Extension* target_extension = | 256 const Extension* target_extension = |
271 registry->enabled_extensions().GetByID(target_extension_id); | 257 registry->enabled_extensions().GetByID(target_extension_id); |
272 if (!target_extension) { | 258 if (!target_extension) { |
273 DispatchOnDisconnect( | 259 DispatchOnDisconnect( |
274 source, receiver_port_id, kReceivingEndDoesntExistError); | 260 source, receiver_port_id, kReceivingEndDoesntExistError); |
275 return; | 261 return; |
276 } | 262 } |
277 | 263 |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
328 scoped_ptr<base::DictionaryValue> source_tab; | 314 scoped_ptr<base::DictionaryValue> source_tab; |
329 int source_frame_id = -1; | 315 int source_frame_id = -1; |
330 if (source_contents && ExtensionTabUtil::GetTabId(source_contents) >= 0) { | 316 if (source_contents && ExtensionTabUtil::GetTabId(source_contents) >= 0) { |
331 // Only the tab id is useful to platform apps for internal use. The | 317 // Only the tab id is useful to platform apps for internal use. The |
332 // unnecessary bits will be stripped out in | 318 // unnecessary bits will be stripped out in |
333 // MessagingBindings::DispatchOnConnect(). | 319 // MessagingBindings::DispatchOnConnect(). |
334 source_tab.reset(ExtensionTabUtil::CreateTabValue(source_contents)); | 320 source_tab.reset(ExtensionTabUtil::CreateTabValue(source_contents)); |
335 | 321 |
336 content::RenderFrameHost* rfh = | 322 content::RenderFrameHost* rfh = |
337 content::RenderFrameHost::FromID(source_process_id, source_routing_id); | 323 content::RenderFrameHost::FromID(source_process_id, source_routing_id); |
338 // Main frame's frameId is 0. | |
339 if (rfh) | 324 if (rfh) |
340 source_frame_id = !rfh->GetParent() ? 0 : source_routing_id; | 325 source_frame_id = ExtensionApiFrameIdMap::GetFrameId(rfh).frame_id; |
341 } else { | 326 } else { |
342 // Check to see if it was a WebView making the request. | 327 // Check to see if it was a WebView making the request. |
343 // Sending messages from WebViews to extensions breaks webview isolation, | 328 // Sending messages from WebViews to extensions breaks webview isolation, |
344 // so only allow component extensions to receive messages from WebViews. | 329 // so only allow component extensions to receive messages from WebViews. |
345 bool is_web_view = !!WebViewGuest::FromWebContents(source_contents); | 330 bool is_web_view = !!WebViewGuest::FromWebContents(source_contents); |
346 if (is_web_view && extensions::Manifest::IsComponentLocation( | 331 if (is_web_view && extensions::Manifest::IsComponentLocation( |
347 target_extension->location())) { | 332 target_extension->location())) { |
348 include_guest_process_info = true; | 333 include_guest_process_info = true; |
349 auto* rfh = content::RenderFrameHost::FromID(source_process_id, | |
350 source_routing_id); | |
351 // Include |source_frame_id| so that we can retrieve the guest's frame | |
352 // routing id in OpenChannelImpl. | |
353 if (rfh) | |
354 source_frame_id = source_routing_id; | |
355 } | 334 } |
356 } | 335 } |
357 | 336 |
358 scoped_ptr<OpenChannelParams> params(new OpenChannelParams( | 337 scoped_ptr<OpenChannelParams> params(new OpenChannelParams( |
359 source_process_id, source_tab.Pass(), source_frame_id, -1, | 338 source_process_id, source_routing_id, source_tab.Pass(), source_frame_id, |
360 -1, // no target_tab_id/target_frame_id for connections to extensions | |
361 nullptr, receiver_port_id, source_extension_id, target_extension_id, | 339 nullptr, receiver_port_id, source_extension_id, target_extension_id, |
362 source_url, channel_name, include_tls_channel_id, | 340 source_url, channel_name, include_tls_channel_id, |
363 include_guest_process_info)); | 341 include_guest_process_info)); |
364 | 342 |
365 pending_incognito_channels_[GET_CHANNEL_ID(params->receiver_port_id)] = | 343 pending_incognito_channels_[GET_CHANNEL_ID(params->receiver_port_id)] = |
366 PendingMessagesQueue(); | 344 PendingMessagesQueue(); |
367 if (context->IsOffTheRecord() && | 345 if (context->IsOffTheRecord() && |
368 !util::IsIncognitoEnabled(target_extension_id, context)) { | 346 !util::IsIncognitoEnabled(target_extension_id, context)) { |
369 // Give the user a chance to accept an incognito connection from the web if | 347 // Give the user a chance to accept an incognito connection from the web if |
370 // they haven't already, with the conditions: | 348 // they haven't already, with the conditions: |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
410 } | 388 } |
411 | 389 |
412 void MessageService::OpenChannelToNativeApp( | 390 void MessageService::OpenChannelToNativeApp( |
413 int source_process_id, | 391 int source_process_id, |
414 int source_routing_id, | 392 int source_routing_id, |
415 int receiver_port_id, | 393 int receiver_port_id, |
416 const std::string& source_extension_id, | 394 const std::string& source_extension_id, |
417 const std::string& native_app_name) { | 395 const std::string& native_app_name) { |
418 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 396 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
419 | 397 |
420 content::RenderProcessHost* source = | 398 content::RenderFrameHost* source = |
421 content::RenderProcessHost::FromID(source_process_id); | 399 content::RenderFrameHost::FromID(source_process_id, source_routing_id); |
422 if (!source) | 400 if (!source) |
423 return; | 401 return; |
424 | 402 |
425 #if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_LINUX) | 403 #if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_LINUX) |
426 Profile* profile = Profile::FromBrowserContext(source->GetBrowserContext()); | 404 Profile* profile = |
405 Profile::FromBrowserContext(source->GetProcess()->GetBrowserContext()); | |
427 ExtensionService* extension_service = | 406 ExtensionService* extension_service = |
428 ExtensionSystem::Get(profile)->extension_service(); | 407 ExtensionSystem::Get(profile)->extension_service(); |
429 bool has_permission = false; | 408 bool has_permission = false; |
430 if (extension_service) { | 409 if (extension_service) { |
431 const Extension* extension = | 410 const Extension* extension = |
432 extension_service->GetExtensionById(source_extension_id, false); | 411 extension_service->GetExtensionById(source_extension_id, false); |
433 has_permission = extension && | 412 has_permission = extension && |
434 extension->permissions_data()->HasAPIPermission( | 413 extension->permissions_data()->HasAPIPermission( |
435 APIPermission::kNativeMessaging); | 414 APIPermission::kNativeMessaging); |
436 } | 415 } |
437 | 416 |
438 if (!has_permission) { | 417 if (!has_permission) { |
439 DispatchOnDisconnect(source, receiver_port_id, kMissingPermissionError); | 418 DispatchOnDisconnect(source, receiver_port_id, kMissingPermissionError); |
440 return; | 419 return; |
441 } | 420 } |
442 | 421 |
443 PrefService* pref_service = profile->GetPrefs(); | 422 PrefService* pref_service = profile->GetPrefs(); |
444 | 423 |
445 // Verify that the host is not blocked by policies. | 424 // Verify that the host is not blocked by policies. |
446 PolicyPermission policy_permission = | 425 PolicyPermission policy_permission = |
447 IsNativeMessagingHostAllowed(pref_service, native_app_name); | 426 IsNativeMessagingHostAllowed(pref_service, native_app_name); |
448 if (policy_permission == DISALLOW) { | 427 if (policy_permission == DISALLOW) { |
449 DispatchOnDisconnect(source, receiver_port_id, kProhibitedByPoliciesError); | 428 DispatchOnDisconnect(source, receiver_port_id, kProhibitedByPoliciesError); |
450 return; | 429 return; |
451 } | 430 } |
452 | 431 |
453 scoped_ptr<MessageChannel> channel(new MessageChannel()); | 432 scoped_ptr<MessageChannel> channel(new MessageChannel()); |
454 channel->opener.reset(new ExtensionMessagePort(source, MSG_ROUTING_CONTROL, | 433 channel->opener.reset( |
455 source_extension_id)); | 434 new ExtensionMessagePort(weak_factory_.GetWeakPtr(), |
435 GET_OPPOSITE_PORT_ID(receiver_port_id), | |
436 source_extension_id, source, false)); | |
456 | 437 |
457 // Get handle of the native view and pass it to the native messaging host. | 438 // Get handle of the native view and pass it to the native messaging host. |
458 content::RenderFrameHost* render_frame_host = | 439 gfx::NativeView native_view = source ? source->GetNativeView() : nullptr; |
459 content::RenderFrameHost::FromID(source_process_id, source_routing_id); | |
460 gfx::NativeView native_view = | |
461 render_frame_host ? render_frame_host->GetNativeView() : nullptr; | |
462 | 440 |
463 std::string error = kReceivingEndDoesntExistError; | 441 std::string error = kReceivingEndDoesntExistError; |
464 scoped_ptr<NativeMessageHost> native_host = NativeMessageHost::Create( | 442 scoped_ptr<NativeMessageHost> native_host = NativeMessageHost::Create( |
465 native_view, | 443 native_view, |
466 source_extension_id, | 444 source_extension_id, |
467 native_app_name, | 445 native_app_name, |
468 policy_permission == ALLOW_ALL, | 446 policy_permission == ALLOW_ALL, |
469 &error); | 447 &error); |
470 | 448 |
471 // Abandon the channel. | 449 // Abandon the channel. |
(...skipping 11 matching lines...) Expand all Loading... | |
483 AddChannel(channel.release(), receiver_port_id); | 461 AddChannel(channel.release(), receiver_port_id); |
484 #else // !(defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_LINUX)) | 462 #else // !(defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_LINUX)) |
485 const char kNativeMessagingNotSupportedError[] = | 463 const char kNativeMessagingNotSupportedError[] = |
486 "Native Messaging is not supported on this platform."; | 464 "Native Messaging is not supported on this platform."; |
487 DispatchOnDisconnect( | 465 DispatchOnDisconnect( |
488 source, receiver_port_id, kNativeMessagingNotSupportedError); | 466 source, receiver_port_id, kNativeMessagingNotSupportedError); |
489 #endif // !(defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_LINUX)) | 467 #endif // !(defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_LINUX)) |
490 } | 468 } |
491 | 469 |
492 void MessageService::OpenChannelToTab(int source_process_id, | 470 void MessageService::OpenChannelToTab(int source_process_id, |
471 int source_routing_id, | |
493 int receiver_port_id, | 472 int receiver_port_id, |
494 int tab_id, | 473 int tab_id, |
495 int frame_id, | 474 int frame_id, |
496 const std::string& extension_id, | 475 const std::string& extension_id, |
497 const std::string& channel_name) { | 476 const std::string& channel_name) { |
498 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 477 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
478 DCHECK_GE(frame_id, -1); | |
499 | 479 |
500 content::RenderProcessHost* source = | 480 content::RenderFrameHost* source = |
501 content::RenderProcessHost::FromID(source_process_id); | 481 content::RenderFrameHost::FromID(source_process_id, source_routing_id); |
502 if (!source) | 482 if (!source) |
503 return; | 483 return; |
504 Profile* profile = Profile::FromBrowserContext(source->GetBrowserContext()); | 484 Profile* profile = |
485 Profile::FromBrowserContext(source->GetProcess()->GetBrowserContext()); | |
505 | 486 |
506 WebContents* contents = NULL; | 487 WebContents* contents = NULL; |
507 scoped_ptr<MessagePort> receiver; | 488 scoped_ptr<MessagePort> receiver; |
508 if (!ExtensionTabUtil::GetTabById(tab_id, profile, true, NULL, NULL, | 489 if (!ExtensionTabUtil::GetTabById(tab_id, profile, true, NULL, NULL, |
509 &contents, NULL) || | 490 &contents, NULL) || |
510 contents->GetController().NeedsReload()) { | 491 contents->GetController().NeedsReload()) { |
511 // The tab isn't loaded yet. Don't attempt to connect. | 492 // The tab isn't loaded yet. Don't attempt to connect. |
512 DispatchOnDisconnect( | 493 DispatchOnDisconnect( |
513 source, receiver_port_id, kReceivingEndDoesntExistError); | 494 source, receiver_port_id, kReceivingEndDoesntExistError); |
514 return; | 495 return; |
515 } | 496 } |
516 | 497 |
517 int receiver_routing_id; | 498 // Frame ID -1 is every frame in the tab. |
518 if (frame_id > 0) { | 499 bool include_child_frames = frame_id == -1; |
519 // Positive frame ID is child frame. | 500 content::RenderFrameHost* receiver_rfh = |
520 int receiver_process_id = contents->GetRenderProcessHost()->GetID(); | 501 include_child_frames |
521 if (!content::RenderFrameHost::FromID(receiver_process_id, frame_id)) { | 502 ? contents->GetMainFrame() |
522 // Frame does not exist. | 503 : ExtensionApiFrameIdMap::GetRenderFrameHostById(contents, frame_id); |
523 DispatchOnDisconnect( | 504 if (!receiver_rfh) { |
524 source, receiver_port_id, kReceivingEndDoesntExistError); | 505 DispatchOnDisconnect( |
525 return; | 506 source, receiver_port_id, kReceivingEndDoesntExistError); |
526 } | 507 return; |
527 receiver_routing_id = frame_id; | |
528 } else if (frame_id == 0) { | |
529 // Frame ID 0 is main frame. | |
530 receiver_routing_id = contents->GetMainFrame()->GetRoutingID(); | |
531 } else { | |
532 DCHECK_EQ(-1, frame_id); | |
533 // If the frame ID is not set (i.e. -1), then the channel has to be opened | |
534 // in every frame. | |
535 // TODO(robwu): Update logic so that frames that are not hosted in the main | |
536 // frame's process can also receive the port. | |
537 receiver_routing_id = MSG_ROUTING_CONTROL; | |
538 } | 508 } |
539 receiver.reset(new ExtensionMessagePort(contents->GetRenderProcessHost(), | 509 receiver.reset( |
540 receiver_routing_id, extension_id)); | 510 new ExtensionMessagePort(weak_factory_.GetWeakPtr(), |
511 receiver_port_id, extension_id, receiver_rfh, | |
512 include_child_frames)); | |
541 | 513 |
542 const Extension* extension = nullptr; | 514 const Extension* extension = nullptr; |
543 if (!extension_id.empty()) { | 515 if (!extension_id.empty()) { |
544 // Source extension == target extension so the extension must exist, or | 516 // Source extension == target extension so the extension must exist, or |
545 // where did the IPC come from? | 517 // where did the IPC come from? |
546 extension = ExtensionRegistry::Get(profile)->enabled_extensions().GetByID( | 518 extension = ExtensionRegistry::Get(profile)->enabled_extensions().GetByID( |
547 extension_id); | 519 extension_id); |
548 DCHECK(extension); | 520 DCHECK(extension); |
549 } | 521 } |
550 | 522 |
551 scoped_ptr<OpenChannelParams> params(new OpenChannelParams( | 523 scoped_ptr<OpenChannelParams> params(new OpenChannelParams( |
552 source_process_id, | 524 source_process_id, |
525 source_routing_id, | |
553 scoped_ptr<base::DictionaryValue>(), // Source tab doesn't make sense | 526 scoped_ptr<base::DictionaryValue>(), // Source tab doesn't make sense |
554 // for opening to tabs. | 527 // for opening to tabs. |
555 -1, // If there is no tab, then there is no frame either. | 528 -1, // If there is no tab, then there is no frame either. |
556 tab_id, frame_id, receiver.release(), receiver_port_id, extension_id, | 529 receiver.release(), receiver_port_id, extension_id, extension_id, |
557 extension_id, | |
558 GURL(), // Source URL doesn't make sense for opening to tabs. | 530 GURL(), // Source URL doesn't make sense for opening to tabs. |
559 channel_name, | 531 channel_name, |
560 false, // Connections to tabs don't get TLS channel IDs. | 532 false, // Connections to tabs don't get TLS channel IDs. |
561 false)); // Connections to tabs aren't webview guests. | 533 false)); // Connections to tabs aren't webview guests. |
562 OpenChannelImpl(contents->GetBrowserContext(), params.Pass(), extension, | 534 OpenChannelImpl(contents->GetBrowserContext(), params.Pass(), extension, |
563 false /* did_enqueue */); | 535 false /* did_enqueue */); |
564 } | 536 } |
565 | 537 |
566 void MessageService::OpenChannelImpl(BrowserContext* browser_context, | 538 void MessageService::OpenChannelImpl(BrowserContext* browser_context, |
567 scoped_ptr<OpenChannelParams> params, | 539 scoped_ptr<OpenChannelParams> params, |
568 const Extension* target_extension, | 540 const Extension* target_extension, |
569 bool did_enqueue) { | 541 bool did_enqueue) { |
570 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 542 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
571 DCHECK_EQ(target_extension != nullptr, !params->target_extension_id.empty()); | 543 DCHECK_EQ(target_extension != nullptr, !params->target_extension_id.empty()); |
572 | 544 |
573 content::RenderProcessHost* source = | 545 content::RenderFrameHost* source = |
574 content::RenderProcessHost::FromID(params->source_process_id); | 546 content::RenderFrameHost::FromID(params->source_process_id, |
547 params->source_routing_id); | |
575 if (!source) | 548 if (!source) |
576 return; // Closed while in flight. | 549 return; // Closed while in flight. |
577 | 550 |
578 if (!params->receiver || !params->receiver->GetRenderProcessHost()) { | 551 if (!params->receiver || !params->receiver->IsValidPort()) { |
579 DispatchOnDisconnect(source, params->receiver_port_id, | 552 DispatchOnDisconnect(source, params->receiver_port_id, |
580 kReceivingEndDoesntExistError); | 553 kReceivingEndDoesntExistError); |
581 return; | 554 return; |
582 } | 555 } |
583 | 556 |
584 MessageChannel* channel(new MessageChannel); | 557 MessageChannel* channel(new MessageChannel); |
585 channel->opener.reset(new ExtensionMessagePort(source, MSG_ROUTING_CONTROL, | 558 channel->opener.reset( |
586 params->source_extension_id)); | 559 new ExtensionMessagePort(weak_factory_.GetWeakPtr(), |
560 GET_OPPOSITE_PORT_ID(params->receiver_port_id), | |
561 params->source_extension_id, source, false)); | |
587 channel->receiver.reset(params->receiver.release()); | 562 channel->receiver.reset(params->receiver.release()); |
588 AddChannel(channel, params->receiver_port_id); | 563 AddChannel(channel, params->receiver_port_id); |
589 | 564 |
565 // TODO(robwu): Could |guest_process_id| and |guest_render_frame_routing_id| | |
Devlin
2015/12/10 21:53:06
I think they can, yes (but let's save it for anoth
| |
566 // be removed? In the past extension message routing was process-based, but | |
567 // now that extensions are routed from a specific RFH, the special casing for | |
568 // guest views seems no longer necessary, because the ExtensionMessagePort can | |
569 // simply obtain the source process & frame ID directly from the RFH. | |
590 int guest_process_id = content::ChildProcessHost::kInvalidUniqueID; | 570 int guest_process_id = content::ChildProcessHost::kInvalidUniqueID; |
591 int guest_render_frame_routing_id = MSG_ROUTING_NONE; | 571 int guest_render_frame_routing_id = MSG_ROUTING_NONE; |
592 if (params->include_guest_process_info) { | 572 if (params->include_guest_process_info) { |
593 guest_process_id = params->source_process_id; | 573 guest_process_id = params->source_process_id; |
594 guest_render_frame_routing_id = params->source_frame_id; | 574 guest_render_frame_routing_id = params->source_routing_id; |
595 auto* guest_rfh = content::RenderFrameHost::FromID( | |
596 guest_process_id, guest_render_frame_routing_id); | |
597 // Reset the |source_frame_id| parameter. | |
598 params->source_frame_id = -1; | |
599 | 575 |
600 DCHECK(guest_rfh == nullptr || | 576 DCHECK(WebViewGuest::FromWebContents( |
601 WebViewGuest::FromWebContents( | 577 WebContents::FromRenderFrameHost(source))); |
602 WebContents::FromRenderFrameHost(guest_rfh)) != nullptr); | |
603 } | 578 } |
604 | 579 |
605 // Send the connect event to the receiver. Give it the opener's port ID (the | 580 // Send the connect event to the receiver. Give it the opener's port ID (the |
606 // opener has the opposite port ID). | 581 // opener has the opposite port ID). |
607 channel->receiver->DispatchOnConnect( | 582 channel->receiver->DispatchOnConnect( |
608 params->receiver_port_id, params->channel_name, params->source_tab.Pass(), | 583 params->channel_name, params->source_tab.Pass(), params->source_frame_id, |
609 params->source_frame_id, params->target_tab_id, params->target_frame_id, | |
610 guest_process_id, guest_render_frame_routing_id, | 584 guest_process_id, guest_render_frame_routing_id, |
611 params->source_extension_id, params->target_extension_id, | 585 params->source_extension_id, params->target_extension_id, |
612 params->source_url, params->tls_channel_id); | 586 params->source_url, params->tls_channel_id); |
613 | 587 |
614 // Report the event to the event router, if the target is an extension. | 588 // Report the event to the event router, if the target is an extension. |
615 // | 589 // |
616 // First, determine what event this will be (runtime.onConnect vs | 590 // First, determine what event this will be (runtime.onConnect vs |
617 // runtime.onMessage etc), and what the event target is (view vs background | 591 // runtime.onMessage etc), and what the event target is (view vs background |
618 // page etc). | 592 // page etc). |
619 // | 593 // |
(...skipping 29 matching lines...) Expand all Loading... | |
649 | 623 |
650 void MessageService::AddChannel(MessageChannel* channel, int receiver_port_id) { | 624 void MessageService::AddChannel(MessageChannel* channel, int receiver_port_id) { |
651 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 625 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
652 | 626 |
653 int channel_id = GET_CHANNEL_ID(receiver_port_id); | 627 int channel_id = GET_CHANNEL_ID(receiver_port_id); |
654 CHECK(channels_.find(channel_id) == channels_.end()); | 628 CHECK(channels_.find(channel_id) == channels_.end()); |
655 channels_[channel_id] = channel; | 629 channels_[channel_id] = channel; |
656 pending_lazy_background_page_channels_.erase(channel_id); | 630 pending_lazy_background_page_channels_.erase(channel_id); |
657 } | 631 } |
658 | 632 |
633 void MessageService::OpenPort(int port_id, int process_id, int routing_id) { | |
634 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
635 DCHECK(!IS_OPENER_PORT_ID(port_id)); | |
636 | |
637 int channel_id = GET_CHANNEL_ID(port_id); | |
638 MessageChannelMap::iterator it = channels_.find(channel_id); | |
639 if (it == channels_.end()) | |
640 return; | |
641 | |
642 it->second->receiver->OpenPort(process_id, routing_id); | |
643 } | |
644 | |
645 void MessageService::ClosePort( | |
646 int port_id, int process_id, int routing_id, bool force_close) { | |
647 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
648 ClosePortImpl(port_id, process_id, routing_id, force_close, std::string()); | |
649 } | |
650 | |
659 void MessageService::CloseChannel(int port_id, | 651 void MessageService::CloseChannel(int port_id, |
660 const std::string& error_message) { | 652 const std::string& error_message) { |
661 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 653 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
654 ClosePortImpl(port_id, content::ChildProcessHost::kInvalidUniqueID, | |
655 MSG_ROUTING_NONE, true, error_message); | |
656 } | |
662 | 657 |
658 void MessageService::ClosePortImpl(int port_id, | |
659 int process_id, | |
660 int routing_id, | |
661 bool force_close, | |
662 const std::string& error_message) { | |
663 // Note: The channel might be gone already, if the other side closed first. | 663 // Note: The channel might be gone already, if the other side closed first. |
664 int channel_id = GET_CHANNEL_ID(port_id); | 664 int channel_id = GET_CHANNEL_ID(port_id); |
665 MessageChannelMap::iterator it = channels_.find(channel_id); | 665 MessageChannelMap::iterator it = channels_.find(channel_id); |
666 if (it == channels_.end()) { | 666 if (it == channels_.end()) { |
667 PendingLazyBackgroundPageChannelMap::iterator pending = | 667 PendingLazyBackgroundPageChannelMap::iterator pending = |
668 pending_lazy_background_page_channels_.find(channel_id); | 668 pending_lazy_background_page_channels_.find(channel_id); |
669 if (pending != pending_lazy_background_page_channels_.end()) { | 669 if (pending != pending_lazy_background_page_channels_.end()) { |
670 lazy_background_task_queue_->AddPendingTask( | 670 lazy_background_task_queue_->AddPendingTask( |
671 pending->second.first, pending->second.second, | 671 pending->second.first, pending->second.second, |
672 base::Bind(&MessageService::PendingLazyBackgroundPageCloseChannel, | 672 base::Bind(&MessageService::PendingLazyBackgroundPageClosePort, |
673 weak_factory_.GetWeakPtr(), port_id, error_message)); | 673 weak_factory_.GetWeakPtr(), port_id, process_id, |
674 routing_id, force_close, error_message)); | |
674 } | 675 } |
675 return; | 676 return; |
676 } | 677 } |
677 CloseChannelImpl(it, port_id, error_message, true); | 678 |
679 // The difference between closing a channel and port is that closing a port | |
680 // does not necessarily have to destroy the channel if there are multiple | |
681 // receivers, whereas closing a channel always forces all ports to be closed. | |
682 if (force_close) { | |
683 CloseChannelImpl(it, port_id, error_message, true); | |
684 } else if (IS_OPENER_PORT_ID(port_id)) { | |
685 it->second->opener->ClosePort(process_id, routing_id); | |
686 } else { | |
687 it->second->receiver->ClosePort(process_id, routing_id); | |
688 } | |
678 } | 689 } |
679 | 690 |
680 void MessageService::CloseChannelImpl( | 691 void MessageService::CloseChannelImpl( |
681 MessageChannelMap::iterator channel_iter, | 692 MessageChannelMap::iterator channel_iter, |
682 int closing_port_id, | 693 int closing_port_id, |
683 const std::string& error_message, | 694 const std::string& error_message, |
684 bool notify_other_port) { | 695 bool notify_other_port) { |
685 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 696 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
686 | 697 |
687 MessageChannel* channel = channel_iter->second; | 698 MessageChannel* channel = channel_iter->second; |
688 | 699 |
689 // Notify the other side. | 700 // Notify the other side. |
690 if (notify_other_port) { | 701 if (notify_other_port) { |
691 MessagePort* port = IS_OPENER_PORT_ID(closing_port_id) ? | 702 MessagePort* port = IS_OPENER_PORT_ID(closing_port_id) ? |
692 channel->receiver.get() : channel->opener.get(); | 703 channel->receiver.get() : channel->opener.get(); |
693 port->DispatchOnDisconnect(GET_OPPOSITE_PORT_ID(closing_port_id), | 704 port->DispatchOnDisconnect(error_message); |
694 error_message); | |
695 } | 705 } |
696 | 706 |
697 // Balance the IncrementLazyKeepaliveCount() in OpenChannelImpl. | 707 // Balance the IncrementLazyKeepaliveCount() in OpenChannelImpl. |
698 channel->opener->DecrementLazyKeepaliveCount(); | 708 channel->opener->DecrementLazyKeepaliveCount(); |
699 channel->receiver->DecrementLazyKeepaliveCount(); | 709 channel->receiver->DecrementLazyKeepaliveCount(); |
700 | 710 |
701 delete channel_iter->second; | 711 delete channel_iter->second; |
702 channels_.erase(channel_iter); | 712 channels_.erase(channel_iter); |
703 } | 713 } |
704 | 714 |
705 void MessageService::PostMessage(int source_port_id, const Message& message) { | 715 void MessageService::PostMessage(int source_port_id, const Message& message) { |
706 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 716 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
707 | 717 |
708 int channel_id = GET_CHANNEL_ID(source_port_id); | 718 int channel_id = GET_CHANNEL_ID(source_port_id); |
709 MessageChannelMap::iterator iter = channels_.find(channel_id); | 719 MessageChannelMap::iterator iter = channels_.find(channel_id); |
710 if (iter == channels_.end()) { | 720 if (iter == channels_.end()) { |
711 // If this channel is pending, queue up the PostMessage to run once | 721 // If this channel is pending, queue up the PostMessage to run once |
712 // the channel opens. | 722 // the channel opens. |
713 EnqueuePendingMessage(source_port_id, channel_id, message); | 723 EnqueuePendingMessage(source_port_id, channel_id, message); |
714 return; | 724 return; |
715 } | 725 } |
716 | 726 |
717 DispatchMessage(source_port_id, iter->second, message); | 727 DispatchMessage(source_port_id, iter->second, message); |
718 } | 728 } |
719 | 729 |
720 void MessageService::Observe(int type, | |
721 const content::NotificationSource& source, | |
722 const content::NotificationDetails& details) { | |
723 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
724 | |
725 switch (type) { | |
726 case content::NOTIFICATION_RENDERER_PROCESS_TERMINATED: | |
727 case content::NOTIFICATION_RENDERER_PROCESS_CLOSED: { | |
728 content::RenderProcessHost* renderer = | |
729 content::Source<content::RenderProcessHost>(source).ptr(); | |
730 OnProcessClosed(renderer); | |
731 break; | |
732 } | |
733 default: | |
734 NOTREACHED(); | |
735 return; | |
736 } | |
737 } | |
738 | |
739 void MessageService::OnProcessClosed(content::RenderProcessHost* process) { | |
740 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
741 | |
742 // Close any channels that share this renderer. We notify the opposite | |
743 // port that its pair has closed. | |
744 for (MessageChannelMap::iterator it = channels_.begin(); | |
745 it != channels_.end(); ) { | |
746 MessageChannelMap::iterator current = it++; | |
747 | |
748 content::RenderProcessHost* opener_process = | |
749 current->second->opener->GetRenderProcessHost(); | |
750 content::RenderProcessHost* receiver_process = | |
751 current->second->receiver->GetRenderProcessHost(); | |
752 | |
753 // Only notify the other side if it has a different porocess host. | |
754 bool notify_other_port = opener_process && receiver_process && | |
755 opener_process != receiver_process; | |
756 | |
757 if (opener_process == process) { | |
758 CloseChannelImpl(current, GET_CHANNEL_OPENER_ID(current->first), | |
759 std::string(), notify_other_port); | |
760 } else if (receiver_process == process) { | |
761 CloseChannelImpl(current, GET_CHANNEL_RECEIVERS_ID(current->first), | |
762 std::string(), notify_other_port); | |
763 } | |
764 } | |
765 } | |
766 | |
767 void MessageService::EnqueuePendingMessage(int source_port_id, | 730 void MessageService::EnqueuePendingMessage(int source_port_id, |
768 int channel_id, | 731 int channel_id, |
769 const Message& message) { | 732 const Message& message) { |
770 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 733 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
771 | 734 |
772 PendingChannelMap::iterator pending_for_incognito = | 735 PendingChannelMap::iterator pending_for_incognito = |
773 pending_incognito_channels_.find(channel_id); | 736 pending_incognito_channels_.find(channel_id); |
774 if (pending_for_incognito != pending_incognito_channels_.end()) { | 737 if (pending_for_incognito != pending_incognito_channels_.end()) { |
775 pending_for_incognito->second.push_back( | 738 pending_for_incognito->second.push_back( |
776 PendingMessage(source_port_id, message)); | 739 PendingMessage(source_port_id, message)); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
814 void MessageService::DispatchMessage(int source_port_id, | 777 void MessageService::DispatchMessage(int source_port_id, |
815 MessageChannel* channel, | 778 MessageChannel* channel, |
816 const Message& message) { | 779 const Message& message) { |
817 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 780 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
818 | 781 |
819 // Figure out which port the ID corresponds to. | 782 // Figure out which port the ID corresponds to. |
820 int dest_port_id = GET_OPPOSITE_PORT_ID(source_port_id); | 783 int dest_port_id = GET_OPPOSITE_PORT_ID(source_port_id); |
821 MessagePort* port = IS_OPENER_PORT_ID(dest_port_id) ? | 784 MessagePort* port = IS_OPENER_PORT_ID(dest_port_id) ? |
822 channel->opener.get() : channel->receiver.get(); | 785 channel->opener.get() : channel->receiver.get(); |
823 | 786 |
824 port->DispatchOnMessage(message, dest_port_id); | 787 port->DispatchOnMessage(message); |
825 } | 788 } |
826 | 789 |
827 bool MessageService::MaybeAddPendingLazyBackgroundPageOpenChannelTask( | 790 bool MessageService::MaybeAddPendingLazyBackgroundPageOpenChannelTask( |
828 BrowserContext* context, | 791 BrowserContext* context, |
829 const Extension* extension, | 792 const Extension* extension, |
830 scoped_ptr<OpenChannelParams>* params, | 793 scoped_ptr<OpenChannelParams>* params, |
831 const PendingMessagesQueue& pending_messages) { | 794 const PendingMessagesQueue& pending_messages) { |
832 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 795 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
833 | 796 |
834 if (!BackgroundInfo::HasLazyBackgroundPage(extension)) | 797 if (!BackgroundInfo::HasLazyBackgroundPage(extension)) |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
869 pending_incognito_channels_.find(channel_id); | 832 pending_incognito_channels_.find(channel_id); |
870 if (pending_for_incognito == pending_incognito_channels_.end()) { | 833 if (pending_for_incognito == pending_incognito_channels_.end()) { |
871 NOTREACHED(); | 834 NOTREACHED(); |
872 return; | 835 return; |
873 } | 836 } |
874 PendingMessagesQueue pending_messages; | 837 PendingMessagesQueue pending_messages; |
875 pending_messages.swap(pending_for_incognito->second); | 838 pending_messages.swap(pending_for_incognito->second); |
876 pending_incognito_channels_.erase(pending_for_incognito); | 839 pending_incognito_channels_.erase(pending_for_incognito); |
877 | 840 |
878 // Re-lookup the source process since it may no longer be valid. | 841 // Re-lookup the source process since it may no longer be valid. |
879 content::RenderProcessHost* source = | 842 content::RenderFrameHost* source = |
880 content::RenderProcessHost::FromID(params->source_process_id); | 843 content::RenderFrameHost::FromID(params->source_process_id, |
844 params->source_routing_id); | |
881 if (!source) { | 845 if (!source) { |
882 return; | 846 return; |
883 } | 847 } |
884 | 848 |
885 if (!allowed) { | 849 if (!allowed) { |
886 DispatchOnDisconnect(source, params->receiver_port_id, | 850 DispatchOnDisconnect(source, params->receiver_port_id, |
887 kReceivingEndDoesntExistError); | 851 kReceivingEndDoesntExistError); |
888 return; | 852 return; |
889 } | 853 } |
890 | 854 |
891 BrowserContext* context = source->GetBrowserContext(); | 855 BrowserContext* context = source->GetProcess()->GetBrowserContext(); |
892 | 856 |
893 // Note: we use the source's profile here. If the source is an incognito | 857 // Note: we use the source's profile here. If the source is an incognito |
894 // process, we will use the incognito EPM to find the right extension process, | 858 // process, we will use the incognito EPM to find the right extension process, |
895 // which depends on whether the extension uses spanning or split mode. | 859 // which depends on whether the extension uses spanning or split mode. |
896 params->receiver.reset(new ExtensionMessagePort( | 860 if (content::RenderProcessHost* extension_process = |
897 GetExtensionProcess(context, params->target_extension_id), | 861 GetExtensionProcess(context, params->target_extension_id)) { |
898 MSG_ROUTING_CONTROL, params->target_extension_id)); | 862 params->receiver.reset( |
863 new ExtensionMessagePort( | |
864 weak_factory_.GetWeakPtr(), params->receiver_port_id, | |
865 params->target_extension_id, extension_process)); | |
866 } else { | |
867 params->receiver.reset(); | |
868 } | |
899 | 869 |
900 // If the target requests the TLS channel id, begin the lookup for it. | 870 // If the target requests the TLS channel id, begin the lookup for it. |
901 // The target might also be a lazy background page, checked next, but the | 871 // The target might also be a lazy background page, checked next, but the |
902 // loading of lazy background pages continues asynchronously, so enqueue | 872 // loading of lazy background pages continues asynchronously, so enqueue |
903 // messages awaiting TLS channel ID first. | 873 // messages awaiting TLS channel ID first. |
904 if (params->include_tls_channel_id) { | 874 if (params->include_tls_channel_id) { |
905 // Transfer pending messages to the next pending channel list. | 875 // Transfer pending messages to the next pending channel list. |
906 pending_tls_channel_id_channels_[channel_id].swap(pending_messages); | 876 pending_tls_channel_id_channels_[channel_id].swap(pending_messages); |
907 // Capture this reference before params is invalidated by base::Passed(). | 877 // Capture this reference before params is invalidated by base::Passed(). |
908 const GURL& source_url = params->source_url; | 878 const GURL& source_url = params->source_url; |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
944 pending_tls_channel_id_channels_.find(channel_id); | 914 pending_tls_channel_id_channels_.find(channel_id); |
945 if (pending_for_tls_channel_id == pending_tls_channel_id_channels_.end()) { | 915 if (pending_for_tls_channel_id == pending_tls_channel_id_channels_.end()) { |
946 NOTREACHED(); | 916 NOTREACHED(); |
947 return; | 917 return; |
948 } | 918 } |
949 PendingMessagesQueue pending_messages; | 919 PendingMessagesQueue pending_messages; |
950 pending_messages.swap(pending_for_tls_channel_id->second); | 920 pending_messages.swap(pending_for_tls_channel_id->second); |
951 pending_tls_channel_id_channels_.erase(pending_for_tls_channel_id); | 921 pending_tls_channel_id_channels_.erase(pending_for_tls_channel_id); |
952 | 922 |
953 // Re-lookup the source process since it may no longer be valid. | 923 // Re-lookup the source process since it may no longer be valid. |
954 content::RenderProcessHost* source = | 924 content::RenderFrameHost* source = |
955 content::RenderProcessHost::FromID(params->source_process_id); | 925 content::RenderFrameHost::FromID(params->source_process_id, |
926 params->source_routing_id); | |
956 if (!source) { | 927 if (!source) { |
957 return; | 928 return; |
958 } | 929 } |
959 | 930 |
960 BrowserContext* context = source->GetBrowserContext(); | 931 BrowserContext* context = source->GetProcess()->GetBrowserContext(); |
961 ExtensionRegistry* registry = ExtensionRegistry::Get(context); | 932 ExtensionRegistry* registry = ExtensionRegistry::Get(context); |
962 const Extension* target_extension = | 933 const Extension* target_extension = |
963 registry->enabled_extensions().GetByID(params->target_extension_id); | 934 registry->enabled_extensions().GetByID(params->target_extension_id); |
964 if (!target_extension) { | 935 if (!target_extension) { |
965 DispatchOnDisconnect(source, params->receiver_port_id, | 936 DispatchOnDisconnect(source, params->receiver_port_id, |
966 kReceivingEndDoesntExistError); | 937 kReceivingEndDoesntExistError); |
967 return; | 938 return; |
968 } | 939 } |
969 | 940 |
970 if (!MaybeAddPendingLazyBackgroundPageOpenChannelTask( | 941 if (!MaybeAddPendingLazyBackgroundPageOpenChannelTask( |
971 context, target_extension, ¶ms, pending_messages)) { | 942 context, target_extension, ¶ms, pending_messages)) { |
972 OpenChannelImpl(context, params.Pass(), target_extension, | 943 OpenChannelImpl(context, params.Pass(), target_extension, |
973 false /* did_enqueue */); | 944 false /* did_enqueue */); |
974 DispatchPendingMessages(pending_messages, channel_id); | 945 DispatchPendingMessages(pending_messages, channel_id); |
975 } | 946 } |
976 } | 947 } |
977 | 948 |
978 void MessageService::PendingLazyBackgroundPageOpenChannel( | 949 void MessageService::PendingLazyBackgroundPageOpenChannel( |
979 scoped_ptr<OpenChannelParams> params, | 950 scoped_ptr<OpenChannelParams> params, |
980 int source_process_id, | 951 int source_process_id, |
981 ExtensionHost* host) { | 952 ExtensionHost* host) { |
982 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 953 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
983 | 954 |
984 if (!host) | 955 if (!host) |
985 return; // TODO(mpcomplete): notify source of disconnect? | 956 return; // TODO(mpcomplete): notify source of disconnect? |
986 | 957 |
987 params->receiver.reset(new ExtensionMessagePort(host->render_process_host(), | 958 params->receiver.reset( |
988 MSG_ROUTING_CONTROL, | 959 new ExtensionMessagePort( |
989 params->target_extension_id)); | 960 weak_factory_.GetWeakPtr(), params->receiver_port_id, |
961 params->target_extension_id, host->render_process_host())); | |
990 OpenChannelImpl(host->browser_context(), params.Pass(), host->extension(), | 962 OpenChannelImpl(host->browser_context(), params.Pass(), host->extension(), |
991 true /* did_enqueue */); | 963 true /* did_enqueue */); |
992 } | 964 } |
993 | 965 |
994 void MessageService::DispatchOnDisconnect(content::RenderProcessHost* source, | 966 void MessageService::DispatchOnDisconnect(content::RenderFrameHost* source, |
995 int port_id, | 967 int port_id, |
996 const std::string& error_message) { | 968 const std::string& error_message) { |
997 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 969 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
998 | 970 |
999 ExtensionMessagePort port(source, MSG_ROUTING_CONTROL, ""); | 971 ExtensionMessagePort port(weak_factory_.GetWeakPtr(), |
1000 port.DispatchOnDisconnect(GET_OPPOSITE_PORT_ID(port_id), error_message); | 972 GET_OPPOSITE_PORT_ID(port_id), "", source, false); |
973 port.DispatchOnDisconnect(error_message); | |
1001 } | 974 } |
1002 | 975 |
1003 void MessageService::DispatchPendingMessages(const PendingMessagesQueue& queue, | 976 void MessageService::DispatchPendingMessages(const PendingMessagesQueue& queue, |
1004 int channel_id) { | 977 int channel_id) { |
1005 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 978 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
1006 | 979 |
1007 MessageChannelMap::iterator channel_iter = channels_.find(channel_id); | 980 MessageChannelMap::iterator channel_iter = channels_.find(channel_id); |
1008 if (channel_iter != channels_.end()) { | 981 if (channel_iter != channels_.end()) { |
1009 for (const PendingMessage& message : queue) { | 982 for (const PendingMessage& message : queue) { |
1010 DispatchMessage(message.first, channel_iter->second, message.second); | 983 DispatchMessage(message.first, channel_iter->second, message.second); |
1011 } | 984 } |
1012 } | 985 } |
1013 } | 986 } |
1014 | 987 |
1015 } // namespace extensions | 988 } // namespace extensions |
OLD | NEW |