summaryrefslogtreecommitdiffstats
path: root/chrome/browser/extensions
diff options
context:
space:
mode:
authorjam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-04-08 17:38:14 +0000
committerjam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-04-08 17:38:14 +0000
commitff1e913c6d63f3b5b12b4d0cb0b960bcb2e682af (patch)
treed92f1e8949d181069e0defe685d8e4b65c42619e /chrome/browser/extensions
parentafc4ce91f94bc0cb976884e1c1c785a9e75f127a (diff)
downloadchromium_src-ff1e913c6d63f3b5b12b4d0cb0b960bcb2e682af.zip
chromium_src-ff1e913c6d63f3b5b12b4d0cb0b960bcb2e682af.tar.gz
chromium_src-ff1e913c6d63f3b5b12b4d0cb0b960bcb2e682af.tar.bz2
Revert 80938 - Add a new RenderViewHostObserver interface for filtering IPCs send to RenderViewHost. This is needed because with TabContentsObserver, an observer might not know which RenderViewHost a message came from duing a pending navigation. A side-benefit is that we only have to add these observers once, instead of remembering/knowing all the delegates that might want to filter these messages.BUG=78629Review URL: http://codereview.chromium.org/6812030
TBR=jam@chromium.org git-svn-id: svn://svn.chromium.org/chrome/trunk/src@80956 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/extensions')
-rw-r--r--chrome/browser/extensions/extension_host.cc38
-rw-r--r--chrome/browser/extensions/extension_host.h18
-rw-r--r--chrome/browser/extensions/extension_message_handler.cc81
-rw-r--r--chrome/browser/extensions/extension_message_handler.h51
4 files changed, 157 insertions, 31 deletions
diff --git a/chrome/browser/extensions/extension_host.cc b/chrome/browser/extensions/extension_host.cc
index 3969d12f..a3e2bb0 100644
--- a/chrome/browser/extensions/extension_host.cc
+++ b/chrome/browser/extensions/extension_host.cc
@@ -12,6 +12,10 @@
#include "base/string_util.h"
#include "chrome/browser/browser_shutdown.h"
#include "chrome/browser/browser_window.h"
+#include "chrome/browser/debugger/devtools_handler.h"
+#include "chrome/browser/debugger/devtools_manager.h"
+#include "chrome/browser/desktop_notification_handler.h"
+#include "chrome/browser/extensions/extension_message_handler.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_tabs_module.h"
#include "chrome/browser/file_select_helper.h"
@@ -151,6 +155,12 @@ ExtensionHost::ExtensionHost(const Extension* extension,
// be the same extension that this points to.
registrar_.Add(this, NotificationType::EXTENSION_UNLOADED,
Source<Profile>(profile_));
+
+ desktop_notification_handler_.reset(
+ new DesktopNotificationHandler(NULL, render_process_host()));
+ dev_tools_handler_.reset(new DevToolsHandler(NULL, render_view_host_));
+ extension_message_handler_.reset(new ExtensionMessageHandler(
+ render_process_host()->id(), render_view_host_, profile_));
}
ExtensionHost::~ExtensionHost() {
@@ -327,7 +337,7 @@ void ExtensionHost::DidNavigate(RenderViewHost* render_view_host,
return;
if (!params.url.SchemeIs(chrome::kExtensionScheme)) {
- extension_function_dispatcher_.reset(NULL);
+ SetExtensionFunctionDispatcher(NULL);
url_ = params.url;
return;
}
@@ -342,12 +352,12 @@ void ExtensionHost::DidNavigate(RenderViewHost* render_view_host,
// it's better than the alternative.
// TODO(erikkay) Perhaps we should display errors in developer mode.
if (params.url.host() != extension_->id()) {
- extension_function_dispatcher_.reset(NULL);
+ SetExtensionFunctionDispatcher(NULL);
return;
}
url_ = params.url;
- extension_function_dispatcher_.reset(
+ SetExtensionFunctionDispatcher(
ExtensionFunctionDispatcher::Create(render_view_host_, this, url_));
}
@@ -547,13 +557,6 @@ WebPreferences ExtensionHost::GetWebkitPrefs() {
return webkit_prefs;
}
-void ExtensionHost::ProcessWebUIMessage(
- const ExtensionHostMsg_DomMessage_Params& params) {
- if (extension_function_dispatcher_.get()) {
- extension_function_dispatcher_->HandleRequest(params);
- }
-}
-
RenderViewHostDelegate::View* ExtensionHost::GetViewDelegate() {
return this;
}
@@ -787,6 +790,13 @@ bool ExtensionHost::OnMessageReceived(const IPC::Message& message) {
IPC_MESSAGE_HANDLER(ViewHostMsg_RunFileChooser, OnRunFileChooser)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
+
+ if (!handled)
+ handled = desktop_notification_handler_->OnMessageReceived(message);
+ if (!handled)
+ handled = dev_tools_handler_->OnMessageReceived(message);
+ if (!handled)
+ handled = extension_message_handler_->OnMessageReceived(message);
return handled;
}
@@ -802,7 +812,7 @@ void ExtensionHost::RenderViewCreated(RenderViewHost* render_view_host) {
// we'll create 2 EFDs for the first navigation. We should try to find a
// better way to unify them.
// See http://code.google.com/p/chromium/issues/detail?id=18240
- extension_function_dispatcher_.reset(
+ SetExtensionFunctionDispatcher(
ExtensionFunctionDispatcher::Create(render_view_host, this, url_));
if (extension_host_type_ == ViewType::EXTENSION_POPUP ||
@@ -836,3 +846,9 @@ void ExtensionHost::OnRunFileChooser(
file_select_helper_.reset(new FileSelectHelper(profile()));
file_select_helper_->RunFileChooser(render_view_host_, params);
}
+
+void ExtensionHost::SetExtensionFunctionDispatcher(
+ ExtensionFunctionDispatcher* efd) {
+ extension_function_dispatcher_.reset(efd);
+ extension_message_handler_->set_extension_function_dispatcher(efd);
+}
diff --git a/chrome/browser/extensions/extension_host.h b/chrome/browser/extensions/extension_host.h
index 63adef8..9dcfb7f 100644
--- a/chrome/browser/extensions/extension_host.h
+++ b/chrome/browser/extensions/extension_host.h
@@ -26,7 +26,10 @@
#endif
class Browser;
+class DesktopNotificationHandler;
+class DevToolsHandler;
class Extension;
+class ExtensionMessageHandler;
class FileSelectHelper;
class RenderProcessHost;
class RenderWidgetHostView;
@@ -128,8 +131,6 @@ class ExtensionHost : public RenderViewHostDelegate,
// RenderViewHostDelegate implementation.
virtual RenderViewHostDelegate::View* GetViewDelegate();
virtual WebPreferences GetWebkitPrefs();
- virtual void ProcessWebUIMessage(
- const ExtensionHostMsg_DomMessage_Params& params);
virtual void RunJavaScriptMessage(const std::wstring& message,
const std::wstring& default_prompt,
const GURL& frame_url,
@@ -236,6 +237,10 @@ class ExtensionHost : public RenderViewHostDelegate,
// event in platform specific way.
virtual void UnhandledKeyboardEvent(const NativeWebKeyboardEvent& event) {}
+ // Updates extension_function_dispatcher_. Call this instead of modifying it
+ // directly.
+ void SetExtensionFunctionDispatcher(ExtensionFunctionDispatcher* efd);
+
// Returns true if we're hosting a background page.
// This isn't valid until CreateRenderView is called.
bool is_background_page() const { return !view(); }
@@ -287,6 +292,15 @@ class ExtensionHost : public RenderViewHostDelegate,
// FileSelectHelper, lazily created.
scoped_ptr<FileSelectHelper> file_select_helper_;
+ // Handles desktop notification IPCs.
+ scoped_ptr<DesktopNotificationHandler> desktop_notification_handler_;
+
+ // Filters dev tools IPCs.
+ scoped_ptr<DevToolsHandler> dev_tools_handler_;
+
+ // Handles extension IPCs.
+ scoped_ptr<ExtensionMessageHandler> extension_message_handler_;
+
// The time that the last javascript message was dismissed.
base::TimeTicks last_javascript_message_dismissal_;
diff --git a/chrome/browser/extensions/extension_message_handler.cc b/chrome/browser/extensions/extension_message_handler.cc
index 52517cb..9b872d0 100644
--- a/chrome/browser/extensions/extension_message_handler.cc
+++ b/chrome/browser/extensions/extension_message_handler.cc
@@ -4,6 +4,7 @@
#include "chrome/browser/extensions/extension_message_handler.h"
+#include "chrome/browser/extensions/extension_function_dispatcher.h"
#include "chrome/browser/extensions/extension_message_service.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/extensions/extension_messages.h"
@@ -11,10 +12,15 @@
#include "content/browser/renderer_host/render_process_host.h"
#include "content/browser/renderer_host/render_view_host.h"
#include "content/browser/renderer_host/render_view_host_delegate.h"
+#include "content/browser/tab_contents/tab_contents.h"
+#include "content/common/notification_service.h"
ExtensionMessageHandler::ExtensionMessageHandler(
- RenderViewHost* render_view_host)
- : RenderViewHostObserver(render_view_host) {
+ int child_id, IPC::Message::Sender* sender, Profile* profile)
+ : child_id_(child_id),
+ sender_(sender),
+ extension_function_dispatcher_(NULL),
+ profile_(profile) {
}
ExtensionMessageHandler::~ExtensionMessageHandler() {
@@ -31,26 +37,75 @@ bool ExtensionMessageHandler::OnMessageReceived(
return handled;
}
+bool ExtensionMessageHandler::CanDispatchRequest(
+ int child_id,
+ int routing_id,
+ const ExtensionHostMsg_DomMessage_Params& params) {
+ if (!ChildProcessSecurityPolicy::GetInstance()->
+ HasExtensionBindings(child_id)) {
+ // This can happen if someone uses window.open() to open an extension URL
+ // from a non-extension context.
+ sender_->Send(new ExtensionMsg_Response(
+ routing_id, params.request_id, false, std::string(),
+ "Access to extension API denied."));
+ return false;
+ }
+
+ return true;
+}
+
void ExtensionMessageHandler::OnPostMessage(int port_id,
const std::string& message) {
- Profile* profile = render_view_host()->process()->profile();
- if (profile->GetExtensionMessageService()) {
- profile->GetExtensionMessageService()->PostMessageFromRenderer(
+ if (profile_->GetExtensionMessageService()) {
+ profile_->GetExtensionMessageService()->PostMessageFromRenderer(
port_id, message);
}
}
void ExtensionMessageHandler::OnRequest(
+ const IPC::Message& message,
const ExtensionHostMsg_DomMessage_Params& params) {
- if (!ChildProcessSecurityPolicy::GetInstance()->
- HasExtensionBindings(render_view_host()->process()->id())) {
- // This can happen if someone uses window.open() to open an extension URL
- // from a non-extension context.
- Send(new ExtensionMsg_Response(
- routing_id(), params.request_id, false, std::string(),
- "Access to extension API denied."));
+ DCHECK(child_id_);
+ if (!extension_function_dispatcher_ ||
+ !CanDispatchRequest(child_id_, message.routing_id(), params)) {
+ return;
+ }
+
+ extension_function_dispatcher_->HandleRequest(params);
+}
+
+ExtensionMessageObserver::ExtensionMessageObserver(TabContents* tab_contents)
+ : TabContentsObserver(tab_contents),
+ ALLOW_THIS_IN_INITIALIZER_LIST(
+ handler_(0, this, tab_contents->profile())) {
+ // We don't pass in a child_id to handler_ since for TabContents that can
+ // change later.
+}
+
+ExtensionMessageObserver::~ExtensionMessageObserver() {
+}
+
+bool ExtensionMessageObserver::OnMessageReceived(const IPC::Message& message) {
+ bool handled = true;
+ IPC_BEGIN_MESSAGE_MAP(ExtensionMessageObserver, message)
+ IPC_MESSAGE_HANDLER(ExtensionHostMsg_Request, OnRequest)
+ IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_END_MESSAGE_MAP()
+
+ if (!handled)
+ handled = handler_.OnMessageReceived(message);
+ return handled;
+}
+
+void ExtensionMessageObserver::OnRequest(
+ const IPC::Message& message,
+ const ExtensionHostMsg_DomMessage_Params& params) {
+ if (!handler_.CanDispatchRequest(
+ tab_contents()->render_view_host()->process()->id(),
+ message.routing_id(),
+ params)) {
return;
}
- render_view_host()->delegate()->ProcessWebUIMessage(params);
+ tab_contents()->render_view_host()->delegate()->ProcessWebUIMessage(params);
}
diff --git a/chrome/browser/extensions/extension_message_handler.h b/chrome/browser/extensions/extension_message_handler.h
index d134d09..3cd8d3c 100644
--- a/chrome/browser/extensions/extension_message_handler.h
+++ b/chrome/browser/extensions/extension_message_handler.h
@@ -6,8 +6,10 @@
#define CHROME_BROWSER_EXTENSIONS_EXTENSION_MESSAGE_HANDLER_H_
#pragma once
-#include "content/browser/renderer_host/render_view_host_observer.h"
+#include "content/browser/tab_contents/tab_contents_observer.h"
+#include "ipc/ipc_channel.h"
+class ExtensionFunctionDispatcher;
class Profile;
struct ExtensionHostMsg_DomMessage_Params;
@@ -15,21 +17,60 @@ struct ExtensionHostMsg_DomMessage_Params;
// renderer/extension processes. This object is created for renderers and also
// ExtensionHost/BackgroundContents. Contrast this with ExtensionTabHelper,
// which is only created for TabContents.
-class ExtensionMessageHandler : public RenderViewHostObserver {
+class ExtensionMessageHandler : public IPC::Channel::Listener {
public:
// |sender| is guaranteed to outlive this object.
- explicit ExtensionMessageHandler(RenderViewHost* render_view_host);
+ ExtensionMessageHandler(int child_id,
+ IPC::Message::Sender* sender,
+ Profile* profile);
virtual ~ExtensionMessageHandler();
- // RenderViewHostObserver overrides.
+ // IPC::Channel::Listener overrides.
virtual bool OnMessageReceived(const IPC::Message& message);
+ // Returns true iff the message can be dispatched.
+ bool CanDispatchRequest(int child_id,
+ int routing_id,
+ const ExtensionHostMsg_DomMessage_Params& params);
+
+ void set_extension_function_dispatcher(ExtensionFunctionDispatcher* e) {
+ extension_function_dispatcher_ = e;
+ }
+
private:
// Message handlers.
void OnPostMessage(int port_id, const std::string& message);
- void OnRequest(const ExtensionHostMsg_DomMessage_Params& params);
+ void OnRequest(const IPC::Message& message,
+ const ExtensionHostMsg_DomMessage_Params& params);
+
+ // The child id of the corresponding process. Can be 0.
+ int child_id_;
+
+ // Guaranteed to outlive this object.
+ IPC::Message::Sender* sender_;
+ ExtensionFunctionDispatcher* extension_function_dispatcher_;
+
+ Profile* profile_;
DISALLOW_COPY_AND_ASSIGN(ExtensionMessageHandler);
};
+// A TabContentsObserver that forwards IPCs to ExtensionMessageHandler.
+class ExtensionMessageObserver : public TabContentsObserver {
+ public:
+ explicit ExtensionMessageObserver(TabContents* tab_contents);
+ ~ExtensionMessageObserver();
+
+ private:
+ // TabContentsObserver overrides.
+ virtual bool OnMessageReceived(const IPC::Message& message);
+
+ void OnRequest(const IPC::Message& message,
+ const ExtensionHostMsg_DomMessage_Params& params);
+
+ ExtensionMessageHandler handler_;
+
+ DISALLOW_COPY_AND_ASSIGN(ExtensionMessageObserver);
+};
+
#endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_MESSAGE_HANDLER_H_