diff options
Diffstat (limited to 'chrome/browser/extensions')
-rw-r--r-- | chrome/browser/extensions/extension_host.cc | 38 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_host.h | 18 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_message_handler.cc | 81 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_message_handler.h | 51 |
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_ |