Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(85)

Side by Side Diff: chrome/browser/extensions/api/messaging/message_service.cc

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

Powered by Google App Engine
This is Rietveld 408576698