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