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

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

Issue 145463002: Extensions: Send the tab id to platform apps. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 6 years, 10 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/extensions/api/messaging/message_service.h" 5 #include "chrome/browser/extensions/api/messaging/message_service.h"
6 6
7 #include "base/atomic_sequence_num.h" 7 #include "base/atomic_sequence_num.h"
8 #include "base/bind.h" 8 #include "base/bind.h"
9 #include "base/callback.h" 9 #include "base/callback.h"
10 #include "base/json/json_writer.h" 10 #include "base/json/json_writer.h"
11 #include "base/lazy_instance.h" 11 #include "base/lazy_instance.h"
12 #include "base/metrics/histogram.h" 12 #include "base/metrics/histogram.h"
13 #include "base/stl_util.h" 13 #include "base/stl_util.h"
14 #include "base/values.h" 14 #include "base/values.h"
15 #include "chrome/browser/chrome_notification_types.h" 15 #include "chrome/browser/chrome_notification_types.h"
16 #include "chrome/browser/extensions/api/messaging/extension_message_port.h" 16 #include "chrome/browser/extensions/api/messaging/extension_message_port.h"
17 #include "chrome/browser/extensions/api/messaging/incognito_connectability.h" 17 #include "chrome/browser/extensions/api/messaging/incognito_connectability.h"
18 #include "chrome/browser/extensions/api/messaging/native_message_port.h" 18 #include "chrome/browser/extensions/api/messaging/native_message_port.h"
19 #include "chrome/browser/extensions/api/tabs/tabs_constants.h"
19 #include "chrome/browser/extensions/extension_host.h" 20 #include "chrome/browser/extensions/extension_host.h"
20 #include "chrome/browser/extensions/extension_service.h" 21 #include "chrome/browser/extensions/extension_service.h"
21 #include "chrome/browser/extensions/extension_system.h" 22 #include "chrome/browser/extensions/extension_system.h"
22 #include "chrome/browser/extensions/extension_tab_util.h" 23 #include "chrome/browser/extensions/extension_tab_util.h"
23 #include "chrome/browser/extensions/extension_util.h" 24 #include "chrome/browser/extensions/extension_util.h"
24 #include "chrome/browser/profiles/profile.h" 25 #include "chrome/browser/profiles/profile.h"
25 #include "chrome/browser/tab_contents/tab_util.h" 26 #include "chrome/browser/tab_contents/tab_util.h"
26 #include "chrome/common/extensions/extension_messages.h" 27 #include "chrome/common/extensions/extension_messages.h"
27 #include "chrome/common/extensions/manifest_handlers/externally_connectable.h" 28 #include "chrome/common/extensions/manifest_handlers/externally_connectable.h"
28 #include "content/public/browser/notification_service.h" 29 #include "content/public/browser/notification_service.h"
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
73 scoped_ptr<MessagePort> receiver; 74 scoped_ptr<MessagePort> receiver;
74 }; 75 };
75 76
76 struct MessageService::OpenChannelParams { 77 struct MessageService::OpenChannelParams {
77 content::RenderProcessHost* source; 78 content::RenderProcessHost* source;
78 base::DictionaryValue source_tab; 79 base::DictionaryValue source_tab;
79 scoped_ptr<MessagePort> receiver; 80 scoped_ptr<MessagePort> receiver;
80 int receiver_port_id; 81 int receiver_port_id;
81 std::string source_extension_id; 82 std::string source_extension_id;
82 std::string target_extension_id; 83 std::string target_extension_id;
83 GURL source_url;
84 std::string channel_name; 84 std::string channel_name;
85 bool include_tls_channel_id; 85 bool include_tls_channel_id;
86 std::string tls_channel_id; 86 std::string tls_channel_id;
87 87
88 // Takes ownership of receiver. 88 // Takes ownership of receiver.
89 OpenChannelParams(content::RenderProcessHost* source, 89 OpenChannelParams(content::RenderProcessHost* source,
90 scoped_ptr<base::DictionaryValue> source_tab, 90 scoped_ptr<base::DictionaryValue> source_tab,
91 MessagePort* receiver, 91 MessagePort* receiver,
92 int receiver_port_id, 92 int receiver_port_id,
93 const std::string& source_extension_id, 93 const std::string& source_extension_id,
94 const std::string& target_extension_id, 94 const std::string& target_extension_id,
95 const GURL& source_url,
96 const std::string& channel_name, 95 const std::string& channel_name,
97 bool include_tls_channel_id) 96 bool include_tls_channel_id)
98 : source(source), 97 : source(source),
99 receiver(receiver), 98 receiver(receiver),
100 receiver_port_id(receiver_port_id), 99 receiver_port_id(receiver_port_id),
101 source_extension_id(source_extension_id), 100 source_extension_id(source_extension_id),
102 target_extension_id(target_extension_id), 101 target_extension_id(target_extension_id),
103 source_url(source_url),
104 channel_name(channel_name), 102 channel_name(channel_name),
105 include_tls_channel_id(include_tls_channel_id) { 103 include_tls_channel_id(include_tls_channel_id) {
106 if (source_tab) 104 if (source_tab)
107 this->source_tab.Swap(source_tab.get()); 105 this->source_tab.Swap(source_tab.get());
108 } 106 }
109 107
110 private: 108 private:
111 DISALLOW_COPY_AND_ASSIGN(OpenChannelParams); 109 DISALLOW_COPY_AND_ASSIGN(OpenChannelParams);
112 }; 110 };
113 111
114 namespace { 112 namespace {
115 113
116 static base::StaticAtomicSequenceNumber g_next_channel_id; 114 static base::StaticAtomicSequenceNumber g_next_channel_id;
117 static base::StaticAtomicSequenceNumber g_channel_id_overflow_count; 115 static base::StaticAtomicSequenceNumber g_channel_id_overflow_count;
118 116
119 static content::RenderProcessHost* GetExtensionProcess( 117 static content::RenderProcessHost* GetExtensionProcess(
120 Profile* profile, const std::string& extension_id) { 118 Profile* profile, const std::string& extension_id) {
121 SiteInstance* site_instance = 119 SiteInstance* site_instance =
122 ExtensionSystem::Get(profile)->process_manager()-> 120 ExtensionSystem::Get(profile)->process_manager()->GetSiteInstanceForURL(
123 GetSiteInstanceForURL( 121 Extension::GetBaseURLFromExtensionId(extension_id));
124 Extension::GetBaseURLFromExtensionId(extension_id)); 122 return site_instance->HasProcess() ? site_instance->GetProcess() : NULL;
125
126 if (!site_instance->HasProcess())
127 return NULL;
128
129 return site_instance->GetProcess();
130 } 123 }
131 124
132 } // namespace 125 } // namespace
133 126
134 content::RenderProcessHost* 127 content::RenderProcessHost*
135 MessageService::MessagePort::GetRenderProcessHost() { 128 MessageService::MessagePort::GetRenderProcessHost() {
136 return NULL; 129 return NULL;
137 } 130 }
138 131
139 // static 132 // static
140 void MessageService::AllocatePortIdPair(int* port1, int* port2) { 133 void MessageService::AllocatePortIdPair(int* port1, int* port2) {
141 unsigned channel_id = 134 unsigned channel_id =
142 static_cast<unsigned>(g_next_channel_id.GetNext()) % (kint32max/2); 135 static_cast<unsigned>(g_next_channel_id.GetNext()) % (kint32max/2);
143 136
144 if (channel_id == 0) { 137 if (channel_id == 0) {
145 int overflow_count = g_channel_id_overflow_count.GetNext(); 138 int overflow_count = g_channel_id_overflow_count.GetNext();
146 if (overflow_count > 0) 139 if (overflow_count > 0)
147 UMA_HISTOGRAM_BOOLEAN("Extensions.AllocatePortIdPairOverflow", true); 140 UMA_HISTOGRAM_BOOLEAN("Extensions.AllocatePortIdPairOverflow", true);
148 } 141 }
149 142
150 unsigned port1_id = channel_id * 2; 143 unsigned port1_id = channel_id * 2;
151 unsigned port2_id = channel_id * 2 + 1; 144 unsigned port2_id = channel_id * 2 + 1;
152 145
153 // Sanity checks to make sure our channel<->port converters are correct. 146 // Sanity checks to make sure our channel<->port converters are correct.
154 DCHECK(IS_OPENER_PORT_ID(port1_id)); 147 DCHECK(IS_OPENER_PORT_ID(port1_id));
155 DCHECK(GET_OPPOSITE_PORT_ID(port1_id) == port2_id); 148 DCHECK_EQ(GET_OPPOSITE_PORT_ID(port1_id), port2_id);
156 DCHECK(GET_OPPOSITE_PORT_ID(port2_id) == port1_id); 149 DCHECK_EQ(GET_OPPOSITE_PORT_ID(port2_id), port1_id);
157 DCHECK(GET_CHANNEL_ID(port1_id) == GET_CHANNEL_ID(port2_id)); 150 DCHECK_EQ(GET_CHANNEL_ID(port1_id), GET_CHANNEL_ID(port2_id));
158 DCHECK(GET_CHANNEL_ID(port1_id) == channel_id); 151 DCHECK_EQ(GET_CHANNEL_ID(port1_id), channel_id);
159 DCHECK(GET_CHANNEL_OPENER_ID(channel_id) == port1_id); 152 DCHECK_EQ(GET_CHANNEL_OPENER_ID(channel_id), port1_id);
160 DCHECK(GET_CHANNEL_RECEIVERS_ID(channel_id) == port2_id); 153 DCHECK_EQ(GET_CHANNEL_RECEIVERS_ID(channel_id), port2_id);
161 154
162 *port1 = port1_id; 155 *port1 = port1_id;
163 *port2 = port2_id; 156 *port2 = port2_id;
164 } 157 }
165 158
166 MessageService::MessageService(Profile* profile) 159 MessageService::MessageService(Profile* profile)
167 : lazy_background_task_queue_( 160 : lazy_background_task_queue_(
168 ExtensionSystem::Get(profile)->lazy_background_task_queue()), 161 ExtensionSystem::Get(profile)->lazy_background_task_queue()),
169 weak_factory_(this) { 162 weak_factory_(this) {
170 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_TERMINATED, 163 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_TERMINATED,
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
292 285
293 // Note: we use the source's profile here. If the source is an incognito 286 // Note: we use the source's profile here. If the source is an incognito
294 // process, we will use the incognito EPM to find the right extension process, 287 // process, we will use the incognito EPM to find the right extension process,
295 // which depends on whether the extension uses spanning or split mode. 288 // which depends on whether the extension uses spanning or split mode.
296 MessagePort* receiver = new ExtensionMessagePort( 289 MessagePort* receiver = new ExtensionMessagePort(
297 GetExtensionProcess(profile, target_extension_id), MSG_ROUTING_CONTROL, 290 GetExtensionProcess(profile, target_extension_id), MSG_ROUTING_CONTROL,
298 target_extension_id); 291 target_extension_id);
299 292
300 // Include info about the opener's tab (if it was a tab). 293 // Include info about the opener's tab (if it was a tab).
301 scoped_ptr<base::DictionaryValue> source_tab; 294 scoped_ptr<base::DictionaryValue> source_tab;
302 GURL source_url_for_tab;
303
304 if (source_contents && ExtensionTabUtil::GetTabId(source_contents) >= 0) { 295 if (source_contents && ExtensionTabUtil::GetTabId(source_contents) >= 0) {
305 // Platform apps can be sent messages, but don't have a Tab concept. 296 // Platform apps can be sent messages, but don't have a Tab concept.
306 if (!target_extension->is_platform_app()) 297 // Only the tab id is useful to platform apps for internal use. The
307 source_tab.reset(ExtensionTabUtil::CreateTabValue(source_contents)); 298 // unnecessary bits will be stripped out in
308 source_url_for_tab = source_url; 299 // MessagingBindings::DispatchOnConnect().
300 source_tab.reset(ExtensionTabUtil::CreateTabValue(source_contents));
309 } 301 }
310 302
311 OpenChannelParams* params = new OpenChannelParams(source, 303 OpenChannelParams* params = new OpenChannelParams(source,
312 source_tab.Pass(), 304 source_tab.Pass(),
313 receiver, 305 receiver,
314 receiver_port_id, 306 receiver_port_id,
315 source_extension_id, 307 source_extension_id,
316 target_extension_id, 308 target_extension_id,
317 source_url_for_tab,
318 channel_name, 309 channel_name,
319 include_tls_channel_id); 310 include_tls_channel_id);
320 311
321 // If the target requests the TLS channel id, begin the lookup for it. 312 // If the target requests the TLS channel id, begin the lookup for it.
322 // The target might also be a lazy background page, checked next, but the 313 // The target might also be a lazy background page, checked next, but the
323 // loading of lazy background pages continues asynchronously, so enqueue 314 // loading of lazy background pages continues asynchronously, so enqueue
324 // messages awaiting TLS channel ID first. 315 // messages awaiting TLS channel ID first.
325 if (include_tls_channel_id) { 316 if (include_tls_channel_id) {
326 pending_tls_channel_id_channels_[GET_CHANNEL_ID(params->receiver_port_id)] 317 pending_tls_channel_id_channels_[GET_CHANNEL_ID(params->receiver_port_id)]
327 = PendingMessagesQueue(); 318 = PendingMessagesQueue();
328 property_provider_.GetDomainBoundCert(profile, params->source_url, 319 property_provider_.GetDomainBoundCert(
320 profile,
321 source_url,
329 base::Bind(&MessageService::GotDomainBoundCert, 322 base::Bind(&MessageService::GotDomainBoundCert,
330 weak_factory_.GetWeakPtr(), 323 weak_factory_.GetWeakPtr(),
331 base::Passed(make_scoped_ptr(params)))); 324 base::Passed(make_scoped_ptr(params))));
332 return; 325 return;
333 } 326 }
334 327
335 // The target might be a lazy background page. In that case, we have to check 328 // The target might be a lazy background page. In that case, we have to check
336 // if it is loaded and ready, and if not, queue up the task and load the 329 // if it is loaded and ready, and if not, queue up the task and load the
337 // page. 330 // page.
338 if (MaybeAddPendingLazyBackgroundPageOpenChannelTask(profile, 331 if (MaybeAddPendingLazyBackgroundPageOpenChannelTask(profile,
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
444 } 437 }
445 438
446 scoped_ptr<OpenChannelParams> params(new OpenChannelParams( 439 scoped_ptr<OpenChannelParams> params(new OpenChannelParams(
447 source, 440 source,
448 scoped_ptr<base::DictionaryValue>(), // Source tab doesn't make sense 441 scoped_ptr<base::DictionaryValue>(), // Source tab doesn't make sense
449 // for opening to tabs. 442 // for opening to tabs.
450 receiver.release(), 443 receiver.release(),
451 receiver_port_id, 444 receiver_port_id,
452 extension_id, 445 extension_id,
453 extension_id, 446 extension_id,
454 GURL(), // Source URL doesn't make sense for opening to tabs.
455 channel_name, 447 channel_name,
456 false)); // Connections to tabs don't get TLS channel IDs. 448 false)); // Connections to tabs don't get TLS channel IDs.
457 OpenChannelImpl(params.Pass()); 449 OpenChannelImpl(params.Pass());
458 } 450 }
459 451
460 bool MessageService::OpenChannelImpl(scoped_ptr<OpenChannelParams> params) { 452 bool MessageService::OpenChannelImpl(scoped_ptr<OpenChannelParams> params) {
461 if (!params->source) 453 if (!params->source)
462 return false; // Closed while in flight. 454 return false; // Closed while in flight.
463 455
464 if (!params->receiver || !params->receiver->GetRenderProcessHost()) { 456 if (!params->receiver || !params->receiver->GetRenderProcessHost()) {
(...skipping 14 matching lines...) Expand all
479 channel->receiver.reset(params->receiver.release()); 471 channel->receiver.reset(params->receiver.release());
480 472
481 CHECK(channel->receiver->GetRenderProcessHost()); 473 CHECK(channel->receiver->GetRenderProcessHost());
482 474
483 AddChannel(channel, params->receiver_port_id); 475 AddChannel(channel, params->receiver_port_id);
484 476
485 CHECK(channel->receiver->GetRenderProcessHost()); 477 CHECK(channel->receiver->GetRenderProcessHost());
486 478
487 // Send the connect event to the receiver. Give it the opener's port ID (the 479 // Send the connect event to the receiver. Give it the opener's port ID (the
488 // opener has the opposite port ID). 480 // opener has the opposite port ID).
481 // TODO(thestig) It is likely possible to get rid of |source_url| here and
482 // pull it out of |params| further down the call path.
483 std::string source_url;
484 params->source_tab.GetString(tabs_constants::kUrlKey, &source_url);
489 channel->receiver->DispatchOnConnect(params->receiver_port_id, 485 channel->receiver->DispatchOnConnect(params->receiver_port_id,
490 params->channel_name, 486 params->channel_name,
491 params->source_tab, 487 params->source_tab,
492 params->source_extension_id, 488 params->source_extension_id,
493 params->target_extension_id, 489 params->target_extension_id,
494 params->source_url, 490 GURL(source_url),
495 params->tls_channel_id); 491 params->tls_channel_id);
496 492
497 // Keep both ends of the channel alive until the channel is closed. 493 // Keep both ends of the channel alive until the channel is closed.
498 channel->opener->IncrementLazyKeepaliveCount(); 494 channel->opener->IncrementLazyKeepaliveCount();
499 channel->receiver->IncrementLazyKeepaliveCount(); 495 channel->receiver->IncrementLazyKeepaliveCount();
500 return true; 496 return true;
501 } 497 }
502 498
503 void MessageService::AddChannel(MessageChannel* channel, int receiver_port_id) { 499 void MessageService::AddChannel(MessageChannel* channel, int receiver_port_id) {
504 int channel_id = GET_CHANNEL_ID(receiver_port_id); 500 int channel_id = GET_CHANNEL_ID(receiver_port_id);
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
542 } 538 }
543 539
544 // Balance the IncrementLazyKeepaliveCount() in OpenChannelImpl. 540 // Balance the IncrementLazyKeepaliveCount() in OpenChannelImpl.
545 channel->opener->DecrementLazyKeepaliveCount(); 541 channel->opener->DecrementLazyKeepaliveCount();
546 channel->receiver->DecrementLazyKeepaliveCount(); 542 channel->receiver->DecrementLazyKeepaliveCount();
547 543
548 delete channel_iter->second; 544 delete channel_iter->second;
549 channels_.erase(channel_iter); 545 channels_.erase(channel_iter);
550 } 546 }
551 547
552 void MessageService::PostMessage( 548 void MessageService::PostMessage(int source_port_id, const Message& message) {
553 int source_port_id, const Message& message) {
554 int channel_id = GET_CHANNEL_ID(source_port_id); 549 int channel_id = GET_CHANNEL_ID(source_port_id);
555 MessageChannelMap::iterator iter = channels_.find(channel_id); 550 MessageChannelMap::iterator iter = channels_.find(channel_id);
556 if (iter == channels_.end()) { 551 if (iter == channels_.end()) {
557 // If this channel is pending, queue up the PostMessage to run once 552 // If this channel is pending, queue up the PostMessage to run once
558 // the channel opens. 553 // the channel opens.
559 EnqueuePendingMessage(source_port_id, channel_id, message); 554 EnqueuePendingMessage(source_port_id, channel_id, message);
560 return; 555 return;
561 } 556 }
562 557
563 DispatchMessage(source_port_id, iter->second, message); 558 DispatchMessage(source_port_id, iter->second, message);
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
754 } 749 }
755 750
756 void MessageService::DispatchOnDisconnect(content::RenderProcessHost* source, 751 void MessageService::DispatchOnDisconnect(content::RenderProcessHost* source,
757 int port_id, 752 int port_id,
758 const std::string& error_message) { 753 const std::string& error_message) {
759 ExtensionMessagePort port(source, MSG_ROUTING_CONTROL, ""); 754 ExtensionMessagePort port(source, MSG_ROUTING_CONTROL, "");
760 port.DispatchOnDisconnect(GET_OPPOSITE_PORT_ID(port_id), error_message); 755 port.DispatchOnDisconnect(GET_OPPOSITE_PORT_ID(port_id), error_message);
761 } 756 }
762 757
763 } // namespace extensions 758 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698