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

Unified Diff: chrome/browser/extensions/message_service.cc

Issue 10818013: Native Messaging! (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Everything is Different! Merged with MessageService Created 8 years, 4 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/extensions/message_service.cc
diff --git a/chrome/browser/extensions/message_service.cc b/chrome/browser/extensions/message_service.cc
index 8758c13df577ec0dfbe168b1b215a1abc3c2b2fc..eae3d72104a9ec9610c63a2801cf6fd406c1fdd1 100644
--- a/chrome/browser/extensions/message_service.cc
+++ b/chrome/browser/extensions/message_service.cc
@@ -16,6 +16,7 @@
#include "chrome/browser/extensions/extension_system.h"
#include "chrome/browser/extensions/extension_tab_util.h"
#include "chrome/browser/extensions/lazy_background_task_queue.h"
+#include "chrome/browser/extensions/native_message_process.h"
#include "chrome/browser/extensions/process_map.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/tab_contents/tab_util.h"
@@ -24,6 +25,7 @@
#include "chrome/common/extensions/extension.h"
#include "chrome/common/extensions/extension_messages.h"
#include "chrome/common/view_type.h"
+#include "content/public/browser/browser_thread.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
@@ -52,18 +54,23 @@ struct MessageService::MessagePort {
int routing_id;
std::string extension_id;
void* background_host_ptr; // used in IncrementLazyKeepaliveCount
+ // HACK(eriq)
+ bool is_native;
+ linked_ptr<NativeMessageProcess> native_process;
Aaron Boodman 2012/08/09 18:36:12 linked_ptr here is unfortunate, as it makes the li
eaugusti 2012/08/13 23:22:34 Will now be a raw pointer.
MessagePort()
: process(NULL),
routing_id(MSG_ROUTING_CONTROL),
- background_host_ptr(NULL) {}
+ background_host_ptr(NULL),
+ is_native(false) {}
MessagePort(content::RenderProcessHost* process,
int routing_id,
const std::string& extension_id)
: process(process),
routing_id(routing_id),
extension_id(extension_id),
- background_host_ptr(NULL) {}
+ background_host_ptr(NULL),
+ is_native(false) {}
};
struct MessageService::MessageChannel {
@@ -121,8 +128,12 @@ static void DispatchOnDisconnect(const MessageService::MessagePort& port,
static void DispatchOnMessage(const MessageService::MessagePort& port,
const std::string& message,
int target_port_id) {
- port.process->Send(new ExtensionMsg_DeliverMessage(
- port.routing_id, target_port_id, message));
+ if (port.is_native) {
+ port.native_process->Send(message);
+ } else {
+ port.process->Send(new ExtensionMsg_DeliverMessage(
+ port.routing_id, target_port_id, message));
+ }
}
static content::RenderProcessHost* GetExtensionProcess(
@@ -237,6 +248,93 @@ void MessageService::OpenChannelToExtension(
OpenChannelImpl(params);
}
+void MessageService::OpenChannelToNativeApp(
+ int source_process_id,
+ int source_routing_id,
+ int receiver_port_id,
+ const std::string& source_extension_id,
+ const std::string& native_app_name,
+ const std::string& channel_name,
+ const std::string& connect_message) {
+ content::RenderProcessHost* source =
+ content::RenderProcessHost::FromID(source_process_id);
+ if (!source)
+ return;
+ Profile* profile = Profile::FromBrowserContext(source->GetBrowserContext());
+
+ // Note: we use the source's profile here. If the source is an incognito
+ // process, we will use the incognito EPM to find the right extension process,
+ // which depends on whether the extension uses spanning or split mode.
+ MessagePort receiver(GetExtensionProcess(profile, source_extension_id),
Matt Perry 2012/08/09 02:13:00 The receiver is the target of the connect event -
eaugusti 2012/08/13 23:22:34 Done.
+ MSG_ROUTING_CONTROL,
+ "native");
+ WebContents* source_contents = tab_util::GetWebContentsByID(
+ source_process_id, source_routing_id);
+
+ // Include info about the opener's tab (if it was a tab).
+ std::string tab_json = "null";
+ if (source_contents) {
+ scoped_ptr<DictionaryValue> tab_value(
+ ExtensionTabUtil::CreateTabValue(source_contents));
+ base::JSONWriter::Write(tab_value.get(), &tab_json);
+ }
+
+ MessageChannel* channel(new MessageChannel);
+ channel->opener = MessagePort(source, MSG_ROUTING_CONTROL,
+ source_extension_id);
+ channel->receiver = receiver;
+
+ content::BrowserThread::PostTask(
+ content::BrowserThread::FILE,
+ FROM_HERE,
+ base::Bind(&MessageService::OpenChannelToNativeAppOnFileThread,
+ base::Unretained(this),
+ receiver_port_id,
+ native_app_name,
+ channel_name,
+ connect_message,
+ channel,
+ tab_json));
+
+ // TODO(eriq): This should actually be called after the channel is opened
+ // successfully.
+ IncrementLazyKeepaliveCount(&channel->opener);
+}
+
+void MessageService::OpenChannelToNativeAppOnFileThread(
Matt Perry 2012/08/09 02:13:00 This class is not threadsafe. Same goes for |chann
eaugusti 2012/08/13 23:22:34 Done.
+ int receiver_port_id,
+ const std::string& native_app_name,
+ const std::string& channel_name,
+ const std::string& connect_message,
+ MessageChannel* channel,
+ const std::string& tab_json) {
+ DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
+
+ NativeMessageProcess::MessageType type = NativeMessageProcess::TYPE_CONNECT;
+ if (channel_name == "chrome.extension.sendNativeMessage")
+ type = NativeMessageProcess::TYPE_SEND_MESSAGE_REQUEST;
+
+ NativeMessageProcess* native_process = NativeMessageProcess::Create(
+ native_app_name, connect_message, this, receiver_port_id, type);
Matt Perry 2012/08/09 02:13:00 What if an extension opens 2 channels to the same
Aaron Boodman 2012/08/09 18:36:12 I think we should just create two. The extension s
eaugusti 2012/08/13 23:22:34 I agree with spawning multiple processes, the nati
+ if (!native_process) {
+ LOG(ERROR) << "Failed to create native process.";
+ return;
+ }
+ channel->receiver.is_native = true;
+ channel->receiver.native_process.reset(native_process);
+
+ int channel_id = GET_CHANNEL_ID(receiver_port_id);
+ CHECK(channels_.find(channel_id) == channels_.end());
+ channels_[channel_id] = channel;
+ pending_channels_.erase(channel_id);
+
+ // Send the connect event to the receiver. Give it the opener's port ID (the
+ // opener has the opposite port ID).
+ DispatchOnConnect(channel->receiver, receiver_port_id,
Matt Perry 2012/08/09 02:13:00 I don't think this call makes sense. You're dispat
eaugusti 2012/08/13 23:22:34 You're right, it doesn't make sense.
+ channel_name, tab_json,
+ channel->opener.extension_id, "native");
+}
+
void MessageService::OpenChannelToTab(
int source_process_id, int source_routing_id, int receiver_port_id,
int tab_id, const std::string& extension_id,
@@ -348,13 +446,19 @@ void MessageService::CloseChannelImpl(
if (notify_other_port) {
const MessagePort& port = IS_OPENER_PORT_ID(closing_port_id) ?
channel->receiver : channel->opener;
- DispatchOnDisconnect(port, GET_OPPOSITE_PORT_ID(closing_port_id),
- connection_error);
+
+ if (!port.is_native) {
+ DispatchOnDisconnect(port, GET_OPPOSITE_PORT_ID(closing_port_id),
+ connection_error);
+ }
}
// Balance the addrefs in OpenChannelImpl.
DecrementLazyKeepaliveCount(&channel->opener);
- DecrementLazyKeepaliveCount(&channel->receiver);
+ // The reciever may be native.
+ if (!channel->receiver.is_native) {
+ DecrementLazyKeepaliveCount(&channel->receiver);
+ }
delete channel_iter->second;
channels_.erase(channel_iter);

Powered by Google App Engine
This is Rietveld 408576698