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

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

Issue 10787002: Moved ExtensionMessage* into extensions namespace (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Latest master for cq Created 8 years, 5 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
« no previous file with comments | « chrome/browser/extensions/extension_message_service.h ('k') | chrome/browser/extensions/extension_system.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/extensions/extension_message_service.cc
diff --git a/chrome/browser/extensions/extension_message_service.cc b/chrome/browser/extensions/extension_message_service.cc
deleted file mode 100644
index d9f547740f78cec3fe2a58643b9dd7100dd4cce0..0000000000000000000000000000000000000000
--- a/chrome/browser/extensions/extension_message_service.cc
+++ /dev/null
@@ -1,472 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/extensions/extension_message_service.h"
-
-#include "base/atomic_sequence_num.h"
-#include "base/bind.h"
-#include "base/callback.h"
-#include "base/json/json_writer.h"
-#include "base/stl_util.h"
-#include "base/values.h"
-#include "chrome/browser/extensions/extension_host.h"
-#include "chrome/browser/extensions/extension_process_manager.h"
-#include "chrome/browser/extensions/extension_service.h"
-#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/process_map.h"
-#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/tab_contents/tab_util.h"
-#include "chrome/browser/ui/tab_contents/tab_contents.h"
-#include "chrome/common/chrome_notification_types.h"
-#include "chrome/common/extensions/extension.h"
-#include "chrome/common/extensions/extension_messages.h"
-#include "chrome/common/view_type.h"
-#include "content/public/browser/notification_service.h"
-#include "content/public/browser/render_process_host.h"
-#include "content/public/browser/render_view_host.h"
-#include "content/public/browser/site_instance.h"
-#include "content/public/browser/web_contents.h"
-
-using content::SiteInstance;
-using content::WebContents;
-
-// Since we have 2 ports for every channel, we just index channels by half the
-// port ID.
-#define GET_CHANNEL_ID(port_id) ((port_id) / 2)
-#define GET_CHANNEL_OPENER_ID(channel_id) ((channel_id) * 2)
-#define GET_CHANNEL_RECEIVERS_ID(channel_id) ((channel_id) * 2 + 1)
-
-// Port1 is always even, port2 is always odd.
-#define IS_OPENER_PORT_ID(port_id) (((port_id) & 1) == 0)
-
-// Change even to odd and vice versa, to get the other side of a given channel.
-#define GET_OPPOSITE_PORT_ID(source_port_id) ((source_port_id) ^ 1)
-
-struct ExtensionMessageService::MessagePort {
- content::RenderProcessHost* process;
- int routing_id;
- std::string extension_id;
- void* background_host_ptr; // used in IncrementLazyKeepaliveCount
-
- MessagePort()
- : process(NULL),
- routing_id(MSG_ROUTING_CONTROL),
- background_host_ptr(NULL) {}
- 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) {}
-};
-
-struct ExtensionMessageService::MessageChannel {
- ExtensionMessageService::MessagePort opener;
- ExtensionMessageService::MessagePort receiver;
-};
-
-struct ExtensionMessageService::OpenChannelParams {
- content::RenderProcessHost* source;
- std::string tab_json;
- MessagePort receiver;
- int receiver_port_id;
- std::string source_extension_id;
- std::string target_extension_id;
- std::string channel_name;
-
- OpenChannelParams(content::RenderProcessHost* source,
- const std::string& tab_json,
- const MessagePort& receiver,
- int receiver_port_id,
- const std::string& source_extension_id,
- const std::string& target_extension_id,
- const std::string& channel_name)
- : source(source),
- tab_json(tab_json),
- receiver(receiver),
- receiver_port_id(receiver_port_id),
- source_extension_id(source_extension_id),
- target_extension_id(target_extension_id),
- channel_name(channel_name) {}
-};
-
-namespace {
-
-static base::StaticAtomicSequenceNumber g_next_channel_id;
-
-static void DispatchOnConnect(const ExtensionMessageService::MessagePort& port,
- int dest_port_id,
- const std::string& channel_name,
- const std::string& tab_json,
- const std::string& source_extension_id,
- const std::string& target_extension_id) {
- port.process->Send(new ExtensionMsg_DispatchOnConnect(
- port.routing_id, dest_port_id, channel_name,
- tab_json, source_extension_id, target_extension_id));
-}
-
-static void DispatchOnDisconnect(
- const ExtensionMessageService::MessagePort& port, int source_port_id,
- bool connection_error) {
- port.process->Send(new ExtensionMsg_DispatchOnDisconnect(
- port.routing_id, source_port_id, connection_error));
-}
-
-static void DispatchOnMessage(const ExtensionMessageService::MessagePort& port,
- const std::string& message, int target_port_id) {
- port.process->Send(new ExtensionMsg_DeliverMessage(
- port.routing_id, target_port_id, message));
-}
-
-static content::RenderProcessHost* GetExtensionProcess(
- Profile* profile, const std::string& extension_id) {
- SiteInstance* site_instance =
- profile->GetExtensionProcessManager()->GetSiteInstanceForURL(
- extensions::Extension::GetBaseURLFromExtensionId(extension_id));
-
- if (!site_instance->HasProcess())
- return NULL;
-
- return site_instance->GetProcess();
-}
-
-static void IncrementLazyKeepaliveCount(
- ExtensionMessageService::MessagePort* port) {
- Profile* profile =
- Profile::FromBrowserContext(port->process->GetBrowserContext());
- ExtensionProcessManager* pm =
- extensions::ExtensionSystem::Get(profile)->process_manager();
- ExtensionHost* host = pm->GetBackgroundHostForExtension(port->extension_id);
- if (host && host->extension()->has_lazy_background_page())
- pm->IncrementLazyKeepaliveCount(host->extension());
-
- // Keep track of the background host, so when we decrement, we only do so if
- // the host hasn't reloaded.
- port->background_host_ptr = host;
-}
-
-static void DecrementLazyKeepaliveCount(
- ExtensionMessageService::MessagePort* port) {
- Profile* profile =
- Profile::FromBrowserContext(port->process->GetBrowserContext());
- ExtensionProcessManager* pm =
- extensions::ExtensionSystem::Get(profile)->process_manager();
- ExtensionHost* host = pm->GetBackgroundHostForExtension(port->extension_id);
- if (host && host == port->background_host_ptr)
- pm->DecrementLazyKeepaliveCount(host->extension());
-}
-
-} // namespace
-
-// static
-void ExtensionMessageService::AllocatePortIdPair(int* port1, int* port2) {
- int channel_id = g_next_channel_id.GetNext();
- int port1_id = channel_id * 2;
- int port2_id = channel_id * 2 + 1;
-
- // Sanity checks to make sure our channel<->port converters are correct.
- DCHECK(IS_OPENER_PORT_ID(port1_id));
- DCHECK(GET_OPPOSITE_PORT_ID(port1_id) == port2_id);
- DCHECK(GET_OPPOSITE_PORT_ID(port2_id) == port1_id);
- DCHECK(GET_CHANNEL_ID(port1_id) == GET_CHANNEL_ID(port2_id));
- DCHECK(GET_CHANNEL_ID(port1_id) == channel_id);
- DCHECK(GET_CHANNEL_OPENER_ID(channel_id) == port1_id);
- DCHECK(GET_CHANNEL_RECEIVERS_ID(channel_id) == port2_id);
-
- *port1 = port1_id;
- *port2 = port2_id;
-}
-
-ExtensionMessageService::ExtensionMessageService(
- extensions::LazyBackgroundTaskQueue* queue)
- : lazy_background_task_queue_(queue) {
- registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_TERMINATED,
- content::NotificationService::AllBrowserContextsAndSources());
- registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED,
- content::NotificationService::AllBrowserContextsAndSources());
-}
-
-ExtensionMessageService::~ExtensionMessageService() {
- STLDeleteContainerPairSecondPointers(channels_.begin(), channels_.end());
- channels_.clear();
-}
-
-void ExtensionMessageService::OpenChannelToExtension(
- int source_process_id, int source_routing_id, int receiver_port_id,
- const std::string& source_extension_id,
- const std::string& target_extension_id,
- const std::string& channel_name) {
- 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, target_extension_id),
- MSG_ROUTING_CONTROL,
- target_extension_id);
- 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);
- }
-
- OpenChannelParams params(source, tab_json, receiver, receiver_port_id,
- source_extension_id, target_extension_id,
- channel_name);
-
- // The target might be a lazy background page. In that case, we have to check
- // if it is loaded and ready, and if not, queue up the task and load the
- // page.
- if (MaybeAddPendingOpenChannelTask(profile, params))
- return;
-
- OpenChannelImpl(params);
-}
-
-void ExtensionMessageService::OpenChannelToTab(
- 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) {
- content::RenderProcessHost* source =
- content::RenderProcessHost::FromID(source_process_id);
- if (!source)
- return;
- Profile* profile = Profile::FromBrowserContext(source->GetBrowserContext());
-
- TabContents* contents = NULL;
- MessagePort receiver;
- if (ExtensionTabUtil::GetTabById(tab_id, profile, true,
- NULL, NULL, &contents, NULL)) {
- receiver.process = contents->web_contents()->GetRenderProcessHost();
- receiver.routing_id =
- contents->web_contents()->GetRenderViewHost()->GetRoutingID();
- receiver.extension_id = extension_id;
- }
-
- if (contents && contents->web_contents()->GetController().NeedsReload()) {
- // The tab isn't loaded yet. Don't attempt to connect. Treat this as a
- // disconnect.
- DispatchOnDisconnect(MessagePort(source, MSG_ROUTING_CONTROL, extension_id),
- GET_OPPOSITE_PORT_ID(receiver_port_id), true);
- return;
- }
-
- 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);
- }
-
- OpenChannelParams params(source, tab_json, receiver, receiver_port_id,
- extension_id, extension_id, channel_name);
- OpenChannelImpl(params);
-}
-
-bool ExtensionMessageService::OpenChannelImpl(const OpenChannelParams& params) {
- if (!params.source)
- return false; // Closed while in flight.
-
- if (!params.receiver.process) {
- // Treat it as a disconnect.
- DispatchOnDisconnect(MessagePort(params.source, MSG_ROUTING_CONTROL, ""),
- GET_OPPOSITE_PORT_ID(params.receiver_port_id), true);
- return false;
- }
-
- // Add extra paranoid CHECKs, since we have crash reports of this being NULL.
- // http://code.google.com/p/chromium/issues/detail?id=19067
- CHECK(params.receiver.process);
-
- MessageChannel* channel(new MessageChannel);
- channel->opener = MessagePort(params.source, MSG_ROUTING_CONTROL,
- params.source_extension_id);
- channel->receiver = params.receiver;
-
- CHECK(params.receiver.process);
-
- int channel_id = GET_CHANNEL_ID(params.receiver_port_id);
- CHECK(channels_.find(channel_id) == channels_.end());
- channels_[channel_id] = channel;
- pending_channels_.erase(channel_id);
-
- CHECK(params.receiver.process);
-
- // Send the connect event to the receiver. Give it the opener's port ID (the
- // opener has the opposite port ID).
- DispatchOnConnect(params.receiver, params.receiver_port_id,
- params.channel_name, params.tab_json,
- params.source_extension_id, params.target_extension_id);
-
- // Keep both ends of the channel alive until the channel is closed.
- IncrementLazyKeepaliveCount(&channel->opener);
- IncrementLazyKeepaliveCount(&channel->receiver);
- return true;
-}
-
-void ExtensionMessageService::CloseChannel(int port_id, bool connection_error) {
- // Note: The channel might be gone already, if the other side closed first.
- int channel_id = GET_CHANNEL_ID(port_id);
- MessageChannelMap::iterator it = channels_.find(channel_id);
- if (it == channels_.end()) {
- PendingChannelMap::iterator pending = pending_channels_.find(channel_id);
- if (pending != pending_channels_.end()) {
- lazy_background_task_queue_->AddPendingTask(
- pending->second.first, pending->second.second,
- base::Bind(&ExtensionMessageService::PendingCloseChannel,
- base::Unretained(this), port_id, connection_error));
- }
- return;
- }
- CloseChannelImpl(it, port_id, connection_error, true);
-}
-
-void ExtensionMessageService::CloseChannelImpl(
- MessageChannelMap::iterator channel_iter, int closing_port_id,
- bool connection_error, bool notify_other_port) {
- MessageChannel* channel = channel_iter->second;
-
- // Notify the other side.
- 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);
- }
-
- // Balance the addrefs in OpenChannelImpl.
- DecrementLazyKeepaliveCount(&channel->opener);
- DecrementLazyKeepaliveCount(&channel->receiver);
-
- delete channel_iter->second;
- channels_.erase(channel_iter);
-}
-
-void ExtensionMessageService::PostMessageFromRenderer(
- int source_port_id, const std::string& message) {
- int channel_id = GET_CHANNEL_ID(source_port_id);
- MessageChannelMap::iterator iter = channels_.find(channel_id);
- if (iter == channels_.end()) {
- // If this channel is pending, queue up the PostMessage to run once
- // the channel opens.
- PendingChannelMap::iterator pending = pending_channels_.find(channel_id);
- if (pending != pending_channels_.end()) {
- lazy_background_task_queue_->AddPendingTask(
- pending->second.first, pending->second.second,
- base::Bind(&ExtensionMessageService::PendingPostMessage,
- base::Unretained(this), source_port_id, message));
- }
- return;
- }
-
- // Figure out which port the ID corresponds to.
- int dest_port_id = GET_OPPOSITE_PORT_ID(source_port_id);
- const MessagePort& port = IS_OPENER_PORT_ID(dest_port_id) ?
- iter->second->opener : iter->second->receiver;
-
- DispatchOnMessage(port, message, dest_port_id);
-}
-
-void ExtensionMessageService::Observe(
- int type,
- const content::NotificationSource& source,
- const content::NotificationDetails& details) {
- switch (type) {
- case content::NOTIFICATION_RENDERER_PROCESS_TERMINATED:
- case content::NOTIFICATION_RENDERER_PROCESS_CLOSED: {
- content::RenderProcessHost* renderer =
- content::Source<content::RenderProcessHost>(source).ptr();
- OnProcessClosed(renderer);
- break;
- }
- default:
- NOTREACHED();
- return;
- }
-}
-
-void ExtensionMessageService::OnProcessClosed(
- content::RenderProcessHost* process) {
- // Close any channels that share this renderer. We notify the opposite
- // port that his pair has closed.
- for (MessageChannelMap::iterator it = channels_.begin();
- it != channels_.end(); ) {
- MessageChannelMap::iterator current = it++;
- // If both sides are the same renderer, and it is closing, there is no
- // "other" port, so there's no need to notify it.
- bool notify_other_port =
- current->second->opener.process != current->second->receiver.process;
-
- if (current->second->opener.process == process) {
- CloseChannelImpl(current, GET_CHANNEL_OPENER_ID(current->first),
- false, notify_other_port);
- } else if (current->second->receiver.process == process) {
- CloseChannelImpl(current, GET_CHANNEL_RECEIVERS_ID(current->first),
- false, notify_other_port);
- }
- }
-}
-
-bool ExtensionMessageService::MaybeAddPendingOpenChannelTask(
- Profile* profile,
- const OpenChannelParams& params) {
- ExtensionService* service = profile->GetExtensionService();
- const std::string& extension_id = params.target_extension_id;
- const extensions::Extension* extension = service->extensions()->GetByID(
- extension_id);
- if (extension && extension->has_lazy_background_page()) {
- // If the extension uses spanning incognito mode, make sure we're always
- // using the original profile since that is what the extension process
- // will use.
- if (!extension->incognito_split_mode())
- profile = profile->GetOriginalProfile();
-
- if (lazy_background_task_queue_->ShouldEnqueueTask(profile, extension)) {
- lazy_background_task_queue_->AddPendingTask(profile, extension_id,
- base::Bind(&ExtensionMessageService::PendingOpenChannel,
- base::Unretained(this), params, params.source->GetID()));
- pending_channels_[GET_CHANNEL_ID(params.receiver_port_id)] =
- PendingChannel(profile, extension_id);
- return true;
- }
- }
-
- return false;
-}
-
-void ExtensionMessageService::PendingOpenChannel(
- const OpenChannelParams& params_in,
- int source_process_id,
- ExtensionHost* host) {
- if (!host)
- return; // TODO(mpcomplete): notify source of disconnect?
-
- // Re-lookup the source process since it may no longer be valid.
- OpenChannelParams params = params_in;
- params.source = content::RenderProcessHost::FromID(source_process_id);
- if (!params.source)
- return;
-
- params.receiver = MessagePort(host->render_process_host(),
- MSG_ROUTING_CONTROL,
- params.target_extension_id);
- OpenChannelImpl(params);
-}
« no previous file with comments | « chrome/browser/extensions/extension_message_service.h ('k') | chrome/browser/extensions/extension_system.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698