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

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

Powered by Google App Engine
This is Rietveld 408576698