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

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

Powered by Google App Engine
This is Rietveld 408576698