| Index: chrome/browser/extensions/extension_message_service.h
|
| diff --git a/chrome/browser/extensions/extension_message_service.h b/chrome/browser/extensions/extension_message_service.h
|
| index 77970bce089f7060c6366584c9587ffa121d299a..c7262f6fd8a9757a7a199f83faee84b55e1b47ce 100644
|
| --- a/chrome/browser/extensions/extension_message_service.h
|
| +++ b/chrome/browser/extensions/extension_message_service.h
|
| @@ -11,36 +11,40 @@
|
|
|
| #include "base/linked_ptr.h"
|
| #include "base/lock.h"
|
| +#include "base/ref_counted.h"
|
| #include "chrome/common/ipc_message.h"
|
| #include "chrome/common/notification_registrar.h"
|
|
|
| class MessageLoop;
|
| +class Profile;
|
| class RenderProcessHost;
|
| class ResourceMessageFilter;
|
| class URLRequestContext;
|
|
|
| // This class manages message and event passing between renderer processes.
|
| -// It maintains a list of processes that are listening to events (including
|
| -// messaging events), as well as a set of open channels.
|
| -//
|
| +// It maintains a list of processes that are listening to events and a set of
|
| +// open channels.
|
| +//
|
| // Messaging works this way:
|
| // - An extension-owned script context (like a toolstrip or a content script)
|
| -// adds an event listener to the "onConnect" event. We keep track here of a
|
| -// list of "listeners" that registered interest in receiving extension
|
| -// messages.
|
| -// - Another context calls "connect()" to open a channel to every listener
|
| -// owned by the same extension. This is a broadcast event, so every listener
|
| -// will get notified.
|
| +// adds an event listener to the "onConnect" event.
|
| +// - Another context calls "extension.connect()" to open a channel to the
|
| +// extension process, or an extension context calls "tabs.connect(tabId)" to
|
| +// open a channel to the content scripts for the given tab. The EMS notifies
|
| +// the target process/tab, which then calls the onConnect event in every
|
| +// context owned by the connecting extension in that process/tab.
|
| // - Once the channel is established, either side can call postMessage to send
|
| // a message to the opposite side of the channel, which may have multiple
|
| // listeners.
|
| //
|
| // Terminology:
|
| -// channel: connection between two ports (one side of which can have multiple
|
| -// listeners)
|
| -// port: one or more IPC::Message::Sender interfaces through which we
|
| -// communicate to process(es). These are generally RenderProcessHosts.
|
| -class ExtensionMessageService : public NotificationObserver {
|
| +// channel: connection between two ports
|
| +// port: an IPC::Message::Sender interface and an optional routing_id (in the
|
| +// case that the port is a tab). The Sender is usually either a
|
| +// RenderProcessHost or a RenderViewHost.
|
| +class ExtensionMessageService :
|
| + public base::RefCountedThreadSafe<ExtensionMessageService>,
|
| + public NotificationObserver {
|
| public:
|
| // Javascript function name constants.
|
| static const char kDispatchOnConnect[];
|
| @@ -49,16 +53,18 @@ class ExtensionMessageService : public NotificationObserver {
|
| static const char kDispatchEvent[];
|
| static const char kDispatchError[];
|
|
|
| - // Returns the message service for the given context. Messages can only
|
| - // be sent within a single context.
|
| - static ExtensionMessageService* GetInstance(URLRequestContext* context);
|
| -
|
| - ExtensionMessageService();
|
| + // A messaging channel. Note that the opening port can be the same as the
|
| + // receiver, if an extension toolstrip wants to talk to its tab (for example).
|
| + struct MessageChannel;
|
| + struct MessagePort;
|
|
|
| // --- UI thread only:
|
|
|
| - // UI-thread specific initialization. Does nothing if called more than once.
|
| - void Init();
|
| + ExtensionMessageService(Profile* profile);
|
| + ~ExtensionMessageService();
|
| +
|
| + // Notification that our owning profile is going away.
|
| + void ProfileDestroyed() { profile_ = NULL; }
|
|
|
| // Add or remove |render_process_pid| as a listener for |event_name|.
|
| void AddEventListener(std::string event_name, int render_process_id);
|
| @@ -83,11 +89,6 @@ class ExtensionMessageService : public NotificationObserver {
|
| const std::string& extension_id,
|
| IPC::Message::Sender* source);
|
|
|
| - // NotificationObserver interface.
|
| - void Observe(NotificationType type,
|
| - const NotificationSource& source,
|
| - const NotificationDetails& details);
|
| -
|
| // --- IO thread only:
|
|
|
| // Given an extension's ID, opens a channel between the given renderer "port"
|
| @@ -99,18 +100,16 @@ class ExtensionMessageService : public NotificationObserver {
|
| int OpenChannelToExtension(int routing_id, const std::string& extension_id,
|
| const std::string& channel_name,
|
| ResourceMessageFilter* source);
|
| -
|
| - private:
|
| - // A messaging channel. Since messages are broadcast, the channel can have
|
| - // multiple processes listening for messages. Note that the opening port
|
| - // can also be among the receivers, if an extension toolstrip wants to talk
|
| - // to its tab (for example).
|
| - struct MessageChannel {
|
| - typedef std::set<IPC::Message::Sender*> Ports;
|
| - Ports opener; // only 1 opener, but we use a set to simplify logic
|
| - Ports receivers;
|
| - };
|
|
|
| + // Same as above, but opens a channel to the tab with the given ID. Messages
|
| + // are restricted to that tab, so if there are multiple tabs in that process,
|
| + // only the targeted tab will receive messages.
|
| + int OpenChannelToTab(int routing_id, int tab_id,
|
| + const std::string& extension_id,
|
| + const std::string& channel_name,
|
| + ResourceMessageFilter* source);
|
| +
|
| + private:
|
| // A map of channel ID to its channel object.
|
| typedef std::map<int, linked_ptr<MessageChannel> > MessageChannelMap;
|
|
|
| @@ -127,15 +126,30 @@ class ExtensionMessageService : public NotificationObserver {
|
|
|
| // Handles channel creation and notifies the destinations that a channel was
|
| // opened.
|
| - void OpenChannelOnUIThread(int source_routing_id,
|
| - int source_port_id, int source_process_id,
|
| - const std::string& extension_id, const std::string& channel_name);
|
| + void OpenChannelToExtensionOnUIThread(
|
| + int source_process_id, int source_routing_id, int receiver_port_id,
|
| + const std::string& extension_id, const std::string& channel_name);
|
| +
|
| + void OpenChannelToTabOnUIThread(
|
| + int source_process_id, int source_routing_id, int receiver_port_id,
|
| + int tab_id, const std::string& extension_id,
|
| + const std::string& channel_name);
|
|
|
| // Common between OpenChannelOnUIThread and OpenAutomationChannelToExtension.
|
| void OpenChannelOnUIThreadImpl(
|
| - int source_routing_id, int source_port_id, int source_process_id,
|
| - IPC::Message::Sender* source, const std::string& extension_id,
|
| - const std::string& channel_name);
|
| + IPC::Message::Sender* source, int source_process_id, int source_routing_id,
|
| + const MessagePort& receiver, int receiver_port_id,
|
| + const std::string& extension_id, const std::string& channel_name);
|
| +
|
| + // NotificationObserver interface.
|
| + void Observe(NotificationType type,
|
| + const NotificationSource& source,
|
| + const NotificationDetails& details);
|
| +
|
| + // An IPC sender that might be in our list of channels has closed.
|
| + void OnSenderClosed(IPC::Message::Sender* sender);
|
| +
|
| + Profile* profile_;
|
|
|
| NotificationRegistrar registrar_;
|
|
|
| @@ -148,9 +162,6 @@ class ExtensionMessageService : public NotificationObserver {
|
|
|
| // --- UI or IO thread:
|
|
|
| - // True if Init has been called.
|
| - bool initialized_;
|
| -
|
| // For generating unique channel IDs.
|
| int next_port_id_;
|
|
|
|
|