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

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: Call callbacks ASAP, only use cache for GetFrameIdOnIO Created 4 years, 11 months 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::GetFrameId(rfh);
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::GetRenderFrameHostById(contents, frame_id);
527 DispatchOnDisconnect( 508 if (!receiver_rfh) {
528 source, receiver_port_id, kReceivingEndDoesntExistError); 509 DispatchOnDisconnect(
529 return; 510 source, receiver_port_id, kReceivingEndDoesntExistError);
530 } 511 return;
531 receiver_routing_id = frame_id;
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 } 512 }
543 receiver.reset(new ExtensionMessagePort(contents->GetRenderProcessHost(), 513 receiver.reset(
544 receiver_routing_id, extension_id)); 514 new ExtensionMessagePort(weak_factory_.GetWeakPtr(),
515 receiver_port_id, extension_id, receiver_rfh,
516 include_child_frames));
545 517
546 const Extension* extension = nullptr; 518 const Extension* extension = nullptr;
547 if (!extension_id.empty()) { 519 if (!extension_id.empty()) {
548 // Source extension == target extension so the extension must exist, or 520 // Source extension == target extension so the extension must exist, or
549 // where did the IPC come from? 521 // where did the IPC come from?
550 extension = ExtensionRegistry::Get(profile)->enabled_extensions().GetByID( 522 extension = ExtensionRegistry::Get(profile)->enabled_extensions().GetByID(
551 extension_id); 523 extension_id);
552 DCHECK(extension); 524 DCHECK(extension);
553 } 525 }
554 526
555 scoped_ptr<OpenChannelParams> params(new OpenChannelParams( 527 scoped_ptr<OpenChannelParams> params(new OpenChannelParams(
556 source_process_id, 528 source_process_id,
529 source_routing_id,
557 scoped_ptr<base::DictionaryValue>(), // Source tab doesn't make sense 530 scoped_ptr<base::DictionaryValue>(), // Source tab doesn't make sense
558 // for opening to tabs. 531 // for opening to tabs.
559 -1, // If there is no tab, then there is no frame either. 532 -1, // If there is no tab, then there is no frame either.
560 tab_id, frame_id, receiver.release(), receiver_port_id, extension_id, 533 receiver.release(), receiver_port_id, extension_id, extension_id,
561 extension_id,
562 GURL(), // Source URL doesn't make sense for opening to tabs. 534 GURL(), // Source URL doesn't make sense for opening to tabs.
563 channel_name, 535 channel_name,
564 false, // Connections to tabs don't get TLS channel IDs. 536 false, // Connections to tabs don't get TLS channel IDs.
565 false)); // Connections to tabs aren't webview guests. 537 false)); // Connections to tabs aren't webview guests.
566 OpenChannelImpl(contents->GetBrowserContext(), params.Pass(), extension, 538 OpenChannelImpl(contents->GetBrowserContext(), params.Pass(), extension,
567 false /* did_enqueue */); 539 false /* did_enqueue */);
568 } 540 }
569 541
570 void MessageService::OpenChannelImpl(BrowserContext* browser_context, 542 void MessageService::OpenChannelImpl(BrowserContext* browser_context,
571 scoped_ptr<OpenChannelParams> params, 543 scoped_ptr<OpenChannelParams> params,
572 const Extension* target_extension, 544 const Extension* target_extension,
573 bool did_enqueue) { 545 bool did_enqueue) {
574 DCHECK_CURRENTLY_ON(BrowserThread::UI); 546 DCHECK_CURRENTLY_ON(BrowserThread::UI);
575 DCHECK_EQ(target_extension != nullptr, !params->target_extension_id.empty()); 547 DCHECK_EQ(target_extension != nullptr, !params->target_extension_id.empty());
576 548
577 content::RenderProcessHost* source = 549 content::RenderFrameHost* source =
578 content::RenderProcessHost::FromID(params->source_process_id); 550 content::RenderFrameHost::FromID(params->source_process_id,
551 params->source_routing_id);
579 if (!source) 552 if (!source)
580 return; // Closed while in flight. 553 return; // Closed while in flight.
581 554
582 if (!params->receiver || !params->receiver->GetRenderProcessHost()) { 555 if (!params->receiver || !params->receiver->IsValidPort()) {
583 DispatchOnDisconnect(source, params->receiver_port_id, 556 DispatchOnDisconnect(source, params->receiver_port_id,
584 kReceivingEndDoesntExistError); 557 kReceivingEndDoesntExistError);
585 return; 558 return;
586 } 559 }
587 560
588 MessageChannel* channel(new MessageChannel); 561 MessageChannel* channel(new MessageChannel);
589 channel->opener.reset(new ExtensionMessagePort(source, MSG_ROUTING_CONTROL, 562 channel->opener.reset(
590 params->source_extension_id)); 563 new ExtensionMessagePort(weak_factory_.GetWeakPtr(),
564 GET_OPPOSITE_PORT_ID(params->receiver_port_id),
565 params->source_extension_id, source, false));
591 channel->receiver.reset(params->receiver.release()); 566 channel->receiver.reset(params->receiver.release());
592 AddChannel(channel, params->receiver_port_id); 567 AddChannel(channel, params->receiver_port_id);
593 568
569 // TODO(robwu): Could |guest_process_id| and |guest_render_frame_routing_id|
570 // be removed? In the past extension message routing was process-based, but
571 // now that extensions are routed from a specific RFH, the special casing for
572 // guest views seems no longer necessary, because the ExtensionMessagePort can
573 // simply obtain the source process & frame ID directly from the RFH.
594 int guest_process_id = content::ChildProcessHost::kInvalidUniqueID; 574 int guest_process_id = content::ChildProcessHost::kInvalidUniqueID;
595 int guest_render_frame_routing_id = MSG_ROUTING_NONE; 575 int guest_render_frame_routing_id = MSG_ROUTING_NONE;
596 if (params->include_guest_process_info) { 576 if (params->include_guest_process_info) {
597 guest_process_id = params->source_process_id; 577 guest_process_id = params->source_process_id;
598 guest_render_frame_routing_id = params->source_frame_id; 578 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 579
604 DCHECK(guest_rfh == nullptr || 580 DCHECK(WebViewGuest::FromWebContents(
605 WebViewGuest::FromWebContents( 581 WebContents::FromRenderFrameHost(source)));
606 WebContents::FromRenderFrameHost(guest_rfh)) != nullptr);
607 } 582 }
608 583
609 // Send the connect event to the receiver. Give it the opener's port ID (the 584 // Send the connect event to the receiver. Give it the opener's port ID (the
610 // opener has the opposite port ID). 585 // opener has the opposite port ID).
611 channel->receiver->DispatchOnConnect( 586 channel->receiver->DispatchOnConnect(
612 params->receiver_port_id, params->channel_name, params->source_tab.Pass(), 587 params->channel_name, std::move(params->source_tab),
613 params->source_frame_id, params->target_tab_id, params->target_frame_id, 588 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, 589 params->source_extension_id, params->target_extension_id,
616 params->source_url, params->tls_channel_id); 590 params->source_url, params->tls_channel_id);
617 591
618 // Report the event to the event router, if the target is an extension. 592 // Report the event to the event router, if the target is an extension.
619 // 593 //
620 // First, determine what event this will be (runtime.onConnect vs 594 // First, determine what event this will be (runtime.onConnect vs
621 // runtime.onMessage etc), and what the event target is (view vs background 595 // runtime.onMessage etc), and what the event target is (view vs background
622 // page etc). 596 // page etc).
623 // 597 //
624 // Yes - even though this is opening a channel, they may actually be 598 // Yes - even though this is opening a channel, they may actually be
(...skipping 28 matching lines...) Expand all
653 627
654 void MessageService::AddChannel(MessageChannel* channel, int receiver_port_id) { 628 void MessageService::AddChannel(MessageChannel* channel, int receiver_port_id) {
655 DCHECK_CURRENTLY_ON(BrowserThread::UI); 629 DCHECK_CURRENTLY_ON(BrowserThread::UI);
656 630
657 int channel_id = GET_CHANNEL_ID(receiver_port_id); 631 int channel_id = GET_CHANNEL_ID(receiver_port_id);
658 CHECK(channels_.find(channel_id) == channels_.end()); 632 CHECK(channels_.find(channel_id) == channels_.end());
659 channels_[channel_id] = channel; 633 channels_[channel_id] = channel;
660 pending_lazy_background_page_channels_.erase(channel_id); 634 pending_lazy_background_page_channels_.erase(channel_id);
661 } 635 }
662 636
637 void MessageService::OpenPort(int port_id, int process_id, int routing_id) {
638 DCHECK_CURRENTLY_ON(BrowserThread::UI);
639 DCHECK(!IS_OPENER_PORT_ID(port_id));
640
641 int channel_id = GET_CHANNEL_ID(port_id);
642 MessageChannelMap::iterator it = channels_.find(channel_id);
643 if (it == channels_.end())
644 return;
645
646 it->second->receiver->OpenPort(process_id, routing_id);
647 }
648
649 void MessageService::ClosePort(
650 int port_id, int process_id, int routing_id, bool force_close) {
651 DCHECK_CURRENTLY_ON(BrowserThread::UI);
652 ClosePortImpl(port_id, process_id, routing_id, force_close, std::string());
653 }
654
663 void MessageService::CloseChannel(int port_id, 655 void MessageService::CloseChannel(int port_id,
664 const std::string& error_message) { 656 const std::string& error_message) {
665 DCHECK_CURRENTLY_ON(BrowserThread::UI); 657 DCHECK_CURRENTLY_ON(BrowserThread::UI);
658 ClosePortImpl(port_id, content::ChildProcessHost::kInvalidUniqueID,
659 MSG_ROUTING_NONE, true, error_message);
660 }
666 661
662 void MessageService::ClosePortImpl(int port_id,
663 int process_id,
664 int routing_id,
665 bool force_close,
666 const std::string& error_message) {
667 // Note: The channel might be gone already, if the other side closed first. 667 // Note: The channel might be gone already, if the other side closed first.
668 int channel_id = GET_CHANNEL_ID(port_id); 668 int channel_id = GET_CHANNEL_ID(port_id);
669 MessageChannelMap::iterator it = channels_.find(channel_id); 669 MessageChannelMap::iterator it = channels_.find(channel_id);
670 if (it == channels_.end()) { 670 if (it == channels_.end()) {
671 PendingLazyBackgroundPageChannelMap::iterator pending = 671 PendingLazyBackgroundPageChannelMap::iterator pending =
672 pending_lazy_background_page_channels_.find(channel_id); 672 pending_lazy_background_page_channels_.find(channel_id);
673 if (pending != pending_lazy_background_page_channels_.end()) { 673 if (pending != pending_lazy_background_page_channels_.end()) {
674 lazy_background_task_queue_->AddPendingTask( 674 lazy_background_task_queue_->AddPendingTask(
675 pending->second.first, pending->second.second, 675 pending->second.first, pending->second.second,
676 base::Bind(&MessageService::PendingLazyBackgroundPageCloseChannel, 676 base::Bind(&MessageService::PendingLazyBackgroundPageClosePort,
677 weak_factory_.GetWeakPtr(), port_id, error_message)); 677 weak_factory_.GetWeakPtr(), port_id, process_id,
678 routing_id, force_close, error_message));
678 } 679 }
679 return; 680 return;
680 } 681 }
681 CloseChannelImpl(it, port_id, error_message, true); 682
683 // The difference between closing a channel and port is that closing a port
684 // does not necessarily have to destroy the channel if there are multiple
685 // receivers, whereas closing a channel always forces all ports to be closed.
686 if (force_close) {
687 CloseChannelImpl(it, port_id, error_message, true);
688 } else if (IS_OPENER_PORT_ID(port_id)) {
689 it->second->opener->ClosePort(process_id, routing_id);
690 } else {
691 it->second->receiver->ClosePort(process_id, routing_id);
692 }
682 } 693 }
683 694
684 void MessageService::CloseChannelImpl( 695 void MessageService::CloseChannelImpl(
685 MessageChannelMap::iterator channel_iter, 696 MessageChannelMap::iterator channel_iter,
686 int closing_port_id, 697 int closing_port_id,
687 const std::string& error_message, 698 const std::string& error_message,
688 bool notify_other_port) { 699 bool notify_other_port) {
689 DCHECK_CURRENTLY_ON(BrowserThread::UI); 700 DCHECK_CURRENTLY_ON(BrowserThread::UI);
690 701
691 MessageChannel* channel = channel_iter->second; 702 MessageChannel* channel = channel_iter->second;
692 703
693 // Notify the other side. 704 // Notify the other side.
694 if (notify_other_port) { 705 if (notify_other_port) {
695 MessagePort* port = IS_OPENER_PORT_ID(closing_port_id) ? 706 MessagePort* port = IS_OPENER_PORT_ID(closing_port_id) ?
696 channel->receiver.get() : channel->opener.get(); 707 channel->receiver.get() : channel->opener.get();
697 port->DispatchOnDisconnect(GET_OPPOSITE_PORT_ID(closing_port_id), 708 port->DispatchOnDisconnect(error_message);
698 error_message);
699 } 709 }
700 710
701 // Balance the IncrementLazyKeepaliveCount() in OpenChannelImpl. 711 // Balance the IncrementLazyKeepaliveCount() in OpenChannelImpl.
702 channel->opener->DecrementLazyKeepaliveCount(); 712 channel->opener->DecrementLazyKeepaliveCount();
703 channel->receiver->DecrementLazyKeepaliveCount(); 713 channel->receiver->DecrementLazyKeepaliveCount();
704 714
705 delete channel_iter->second; 715 delete channel_iter->second;
706 channels_.erase(channel_iter); 716 channels_.erase(channel_iter);
707 } 717 }
708 718
709 void MessageService::PostMessage(int source_port_id, const Message& message) { 719 void MessageService::PostMessage(int source_port_id, const Message& message) {
710 DCHECK_CURRENTLY_ON(BrowserThread::UI); 720 DCHECK_CURRENTLY_ON(BrowserThread::UI);
711 721
712 int channel_id = GET_CHANNEL_ID(source_port_id); 722 int channel_id = GET_CHANNEL_ID(source_port_id);
713 MessageChannelMap::iterator iter = channels_.find(channel_id); 723 MessageChannelMap::iterator iter = channels_.find(channel_id);
714 if (iter == channels_.end()) { 724 if (iter == channels_.end()) {
715 // If this channel is pending, queue up the PostMessage to run once 725 // If this channel is pending, queue up the PostMessage to run once
716 // the channel opens. 726 // the channel opens.
717 EnqueuePendingMessage(source_port_id, channel_id, message); 727 EnqueuePendingMessage(source_port_id, channel_id, message);
718 return; 728 return;
719 } 729 }
720 730
721 DispatchMessage(source_port_id, iter->second, message); 731 DispatchMessage(source_port_id, iter->second, message);
722 } 732 }
723 733
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, 734 void MessageService::EnqueuePendingMessage(int source_port_id,
772 int channel_id, 735 int channel_id,
773 const Message& message) { 736 const Message& message) {
774 DCHECK_CURRENTLY_ON(BrowserThread::UI); 737 DCHECK_CURRENTLY_ON(BrowserThread::UI);
775 738
776 PendingChannelMap::iterator pending_for_incognito = 739 PendingChannelMap::iterator pending_for_incognito =
777 pending_incognito_channels_.find(channel_id); 740 pending_incognito_channels_.find(channel_id);
778 if (pending_for_incognito != pending_incognito_channels_.end()) { 741 if (pending_for_incognito != pending_incognito_channels_.end()) {
779 pending_for_incognito->second.push_back( 742 pending_for_incognito->second.push_back(
780 PendingMessage(source_port_id, message)); 743 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, 781 void MessageService::DispatchMessage(int source_port_id,
819 MessageChannel* channel, 782 MessageChannel* channel,
820 const Message& message) { 783 const Message& message) {
821 DCHECK_CURRENTLY_ON(BrowserThread::UI); 784 DCHECK_CURRENTLY_ON(BrowserThread::UI);
822 785
823 // Figure out which port the ID corresponds to. 786 // Figure out which port the ID corresponds to.
824 int dest_port_id = GET_OPPOSITE_PORT_ID(source_port_id); 787 int dest_port_id = GET_OPPOSITE_PORT_ID(source_port_id);
825 MessagePort* port = IS_OPENER_PORT_ID(dest_port_id) ? 788 MessagePort* port = IS_OPENER_PORT_ID(dest_port_id) ?
826 channel->opener.get() : channel->receiver.get(); 789 channel->opener.get() : channel->receiver.get();
827 790
828 port->DispatchOnMessage(message, dest_port_id); 791 port->DispatchOnMessage(message);
829 } 792 }
830 793
831 bool MessageService::MaybeAddPendingLazyBackgroundPageOpenChannelTask( 794 bool MessageService::MaybeAddPendingLazyBackgroundPageOpenChannelTask(
832 BrowserContext* context, 795 BrowserContext* context,
833 const Extension* extension, 796 const Extension* extension,
834 scoped_ptr<OpenChannelParams>* params, 797 scoped_ptr<OpenChannelParams>* params,
835 const PendingMessagesQueue& pending_messages) { 798 const PendingMessagesQueue& pending_messages) {
836 DCHECK_CURRENTLY_ON(BrowserThread::UI); 799 DCHECK_CURRENTLY_ON(BrowserThread::UI);
837 800
838 if (!BackgroundInfo::HasLazyBackgroundPage(extension)) 801 if (!BackgroundInfo::HasLazyBackgroundPage(extension))
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
873 pending_incognito_channels_.find(channel_id); 836 pending_incognito_channels_.find(channel_id);
874 if (pending_for_incognito == pending_incognito_channels_.end()) { 837 if (pending_for_incognito == pending_incognito_channels_.end()) {
875 NOTREACHED(); 838 NOTREACHED();
876 return; 839 return;
877 } 840 }
878 PendingMessagesQueue pending_messages; 841 PendingMessagesQueue pending_messages;
879 pending_messages.swap(pending_for_incognito->second); 842 pending_messages.swap(pending_for_incognito->second);
880 pending_incognito_channels_.erase(pending_for_incognito); 843 pending_incognito_channels_.erase(pending_for_incognito);
881 844
882 // Re-lookup the source process since it may no longer be valid. 845 // Re-lookup the source process since it may no longer be valid.
883 content::RenderProcessHost* source = 846 content::RenderFrameHost* source =
884 content::RenderProcessHost::FromID(params->source_process_id); 847 content::RenderFrameHost::FromID(params->source_process_id,
848 params->source_routing_id);
885 if (!source) { 849 if (!source) {
886 return; 850 return;
887 } 851 }
888 852
889 if (!allowed) { 853 if (!allowed) {
890 DispatchOnDisconnect(source, params->receiver_port_id, 854 DispatchOnDisconnect(source, params->receiver_port_id,
891 kReceivingEndDoesntExistError); 855 kReceivingEndDoesntExistError);
892 return; 856 return;
893 } 857 }
894 858
895 BrowserContext* context = source->GetBrowserContext(); 859 BrowserContext* context = source->GetProcess()->GetBrowserContext();
896 860
897 // Note: we use the source's profile here. If the source is an incognito 861 // 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, 862 // 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. 863 // which depends on whether the extension uses spanning or split mode.
900 params->receiver.reset(new ExtensionMessagePort( 864 if (content::RenderProcessHost* extension_process =
901 GetExtensionProcess(context, params->target_extension_id), 865 GetExtensionProcess(context, params->target_extension_id)) {
902 MSG_ROUTING_CONTROL, params->target_extension_id)); 866 params->receiver.reset(
867 new ExtensionMessagePort(
868 weak_factory_.GetWeakPtr(), params->receiver_port_id,
869 params->target_extension_id, extension_process));
870 } else {
871 params->receiver.reset();
872 }
903 873
904 // If the target requests the TLS channel id, begin the lookup for it. 874 // 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 875 // The target might also be a lazy background page, checked next, but the
906 // loading of lazy background pages continues asynchronously, so enqueue 876 // loading of lazy background pages continues asynchronously, so enqueue
907 // messages awaiting TLS channel ID first. 877 // messages awaiting TLS channel ID first.
908 if (params->include_tls_channel_id) { 878 if (params->include_tls_channel_id) {
909 // Transfer pending messages to the next pending channel list. 879 // Transfer pending messages to the next pending channel list.
910 pending_tls_channel_id_channels_[channel_id].swap(pending_messages); 880 pending_tls_channel_id_channels_[channel_id].swap(pending_messages);
911 // Capture this reference before params is invalidated by base::Passed(). 881 // Capture this reference before params is invalidated by base::Passed().
912 const GURL& source_url = params->source_url; 882 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); 918 pending_tls_channel_id_channels_.find(channel_id);
949 if (pending_for_tls_channel_id == pending_tls_channel_id_channels_.end()) { 919 if (pending_for_tls_channel_id == pending_tls_channel_id_channels_.end()) {
950 NOTREACHED(); 920 NOTREACHED();
951 return; 921 return;
952 } 922 }
953 PendingMessagesQueue pending_messages; 923 PendingMessagesQueue pending_messages;
954 pending_messages.swap(pending_for_tls_channel_id->second); 924 pending_messages.swap(pending_for_tls_channel_id->second);
955 pending_tls_channel_id_channels_.erase(pending_for_tls_channel_id); 925 pending_tls_channel_id_channels_.erase(pending_for_tls_channel_id);
956 926
957 // Re-lookup the source process since it may no longer be valid. 927 // Re-lookup the source process since it may no longer be valid.
958 content::RenderProcessHost* source = 928 content::RenderFrameHost* source =
959 content::RenderProcessHost::FromID(params->source_process_id); 929 content::RenderFrameHost::FromID(params->source_process_id,
930 params->source_routing_id);
960 if (!source) { 931 if (!source) {
961 return; 932 return;
962 } 933 }
963 934
964 BrowserContext* context = source->GetBrowserContext(); 935 BrowserContext* context = source->GetProcess()->GetBrowserContext();
965 ExtensionRegistry* registry = ExtensionRegistry::Get(context); 936 ExtensionRegistry* registry = ExtensionRegistry::Get(context);
966 const Extension* target_extension = 937 const Extension* target_extension =
967 registry->enabled_extensions().GetByID(params->target_extension_id); 938 registry->enabled_extensions().GetByID(params->target_extension_id);
968 if (!target_extension) { 939 if (!target_extension) {
969 DispatchOnDisconnect(source, params->receiver_port_id, 940 DispatchOnDisconnect(source, params->receiver_port_id,
970 kReceivingEndDoesntExistError); 941 kReceivingEndDoesntExistError);
971 return; 942 return;
972 } 943 }
973 944
974 if (!MaybeAddPendingLazyBackgroundPageOpenChannelTask( 945 if (!MaybeAddPendingLazyBackgroundPageOpenChannelTask(
975 context, target_extension, &params, pending_messages)) { 946 context, target_extension, &params, pending_messages)) {
976 OpenChannelImpl(context, params.Pass(), target_extension, 947 OpenChannelImpl(context, params.Pass(), target_extension,
977 false /* did_enqueue */); 948 false /* did_enqueue */);
978 DispatchPendingMessages(pending_messages, channel_id); 949 DispatchPendingMessages(pending_messages, channel_id);
979 } 950 }
980 } 951 }
981 952
982 void MessageService::PendingLazyBackgroundPageOpenChannel( 953 void MessageService::PendingLazyBackgroundPageOpenChannel(
983 scoped_ptr<OpenChannelParams> params, 954 scoped_ptr<OpenChannelParams> params,
984 int source_process_id, 955 int source_process_id,
985 ExtensionHost* host) { 956 ExtensionHost* host) {
986 DCHECK_CURRENTLY_ON(BrowserThread::UI); 957 DCHECK_CURRENTLY_ON(BrowserThread::UI);
987 958
988 if (!host) 959 if (!host)
989 return; // TODO(mpcomplete): notify source of disconnect? 960 return; // TODO(mpcomplete): notify source of disconnect?
990 961
991 params->receiver.reset(new ExtensionMessagePort(host->render_process_host(), 962 params->receiver.reset(
992 MSG_ROUTING_CONTROL, 963 new ExtensionMessagePort(
993 params->target_extension_id)); 964 weak_factory_.GetWeakPtr(), params->receiver_port_id,
965 params->target_extension_id, host->render_process_host()));
994 OpenChannelImpl(host->browser_context(), params.Pass(), host->extension(), 966 OpenChannelImpl(host->browser_context(), params.Pass(), host->extension(),
995 true /* did_enqueue */); 967 true /* did_enqueue */);
996 } 968 }
997 969
998 void MessageService::DispatchOnDisconnect(content::RenderProcessHost* source, 970 void MessageService::DispatchOnDisconnect(content::RenderFrameHost* source,
999 int port_id, 971 int port_id,
1000 const std::string& error_message) { 972 const std::string& error_message) {
1001 DCHECK_CURRENTLY_ON(BrowserThread::UI); 973 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1002 974
1003 ExtensionMessagePort port(source, MSG_ROUTING_CONTROL, ""); 975 ExtensionMessagePort port(weak_factory_.GetWeakPtr(),
1004 port.DispatchOnDisconnect(GET_OPPOSITE_PORT_ID(port_id), error_message); 976 GET_OPPOSITE_PORT_ID(port_id), "", source, false);
977 port.DispatchOnDisconnect(error_message);
1005 } 978 }
1006 979
1007 void MessageService::DispatchPendingMessages(const PendingMessagesQueue& queue, 980 void MessageService::DispatchPendingMessages(const PendingMessagesQueue& queue,
1008 int channel_id) { 981 int channel_id) {
1009 DCHECK_CURRENTLY_ON(BrowserThread::UI); 982 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1010 983
1011 MessageChannelMap::iterator channel_iter = channels_.find(channel_id); 984 MessageChannelMap::iterator channel_iter = channels_.find(channel_id);
1012 if (channel_iter != channels_.end()) { 985 if (channel_iter != channels_.end()) {
1013 for (const PendingMessage& message : queue) { 986 for (const PendingMessage& message : queue) {
1014 DispatchMessage(message.first, channel_iter->second, message.second); 987 DispatchMessage(message.first, channel_iter->second, message.second);
1015 } 988 }
1016 } 989 }
1017 } 990 }
1018 991
1019 } // namespace extensions 992 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698