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