diff options
Diffstat (limited to 'chromium/extensions/browser/extension_function_dispatcher.h')
-rw-r--r-- | chromium/extensions/browser/extension_function_dispatcher.h | 171 |
1 files changed, 171 insertions, 0 deletions
diff --git a/chromium/extensions/browser/extension_function_dispatcher.h b/chromium/extensions/browser/extension_function_dispatcher.h new file mode 100644 index 00000000000..be8132e970e --- /dev/null +++ b/chromium/extensions/browser/extension_function_dispatcher.h @@ -0,0 +1,171 @@ +// Copyright 2014 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. + +#ifndef EXTENSIONS_BROWSER_EXTENSION_FUNCTION_DISPATCHER_H_ +#define EXTENSIONS_BROWSER_EXTENSION_FUNCTION_DISPATCHER_H_ + +#include <map> +#include <string> +#include <vector> + +#include "base/memory/weak_ptr.h" +#include "extensions/browser/extension_function.h" +#include "ipc/ipc_sender.h" + +struct ExtensionHostMsg_Request_Params; + +namespace content { +class BrowserContext; +class RenderFrameHost; +class WebContents; +} + +namespace extensions { + +class Extension; +class ExtensionAPI; +class InfoMap; +class IOThreadExtensionMessageFilter; +class ProcessMap; +class WindowController; + +// A factory function for creating new ExtensionFunction instances. +typedef ExtensionFunction* (*ExtensionFunctionFactory)(); + +// ExtensionFunctionDispatcher receives requests to execute functions from +// Chrome extensions running in a RenderFrameHost and dispatches them to the +// appropriate handler. It lives entirely on the UI thread. +// +// ExtensionFunctionDispatcher should be a member of some class that hosts +// RenderFrameHosts and wants them to be able to display extension content. +// This class should also implement ExtensionFunctionDispatcher::Delegate. +// +// Note that a single ExtensionFunctionDispatcher does *not* correspond to a +// single RVH, a single extension, or a single URL. This is by design so that +// we can gracefully handle cases like WebContents, where the RVH, extension, +// and URL can all change over the lifetime of the tab. Instead, these items +// are all passed into each request. +class ExtensionFunctionDispatcher + : public base::SupportsWeakPtr<ExtensionFunctionDispatcher> { + public: + class Delegate { + public: + // Returns the WindowController associated with this delegate, or NULL if no + // window is associated with the delegate. + virtual WindowController* GetExtensionWindowController() const; + + // Asks the delegate for any relevant WebContents associated with this + // context. For example, the WebContents in which an infobar or + // chrome-extension://<id> URL are being shown. Callers must check for a + // NULL return value (as in the case of a background page). + virtual content::WebContents* GetAssociatedWebContents() const; + + // If the associated web contents is not null, returns that. Otherwise, + // returns the next most relevant visible web contents. Callers must check + // for a NULL return value (as in the case of a background page). + virtual content::WebContents* GetVisibleWebContents() const; + + protected: + virtual ~Delegate() {} + }; + + // Override a previously registered function. Returns true if successful, + // false if no such function was registered. + static bool OverrideFunction(const std::string& name, + ExtensionFunctionFactory factory); + + // Dispatches an IO-thread extension function. Only used for specific + // functions that must be handled on the IO-thread. + static void DispatchOnIOThread( + InfoMap* extension_info_map, + void* profile_id, + int render_process_id, + base::WeakPtr<IOThreadExtensionMessageFilter> ipc_sender, + int routing_id, + const ExtensionHostMsg_Request_Params& params); + + // Public constructor. Callers must ensure that: + // - This object outlives any RenderFrameHost's passed to created + // ExtensionFunctions. + explicit ExtensionFunctionDispatcher( + content::BrowserContext* browser_context); + ~ExtensionFunctionDispatcher(); + + // Message handlers. + // The response is sent to the corresponding render view in an + // ExtensionMsg_Response message. + void Dispatch(const ExtensionHostMsg_Request_Params& params, + content::RenderFrameHost* render_frame_host); + + // Called when an ExtensionFunction is done executing, after it has sent + // a response (if any) to the extension. + void OnExtensionFunctionCompleted(const Extension* extension); + + // See the Delegate class for documentation on these methods. + // TODO(devlin): None of these belong here. We should kill + // ExtensionFunctionDispatcher::Delegate. + WindowController* GetExtensionWindowController() const; + content::WebContents* GetAssociatedWebContents() const; + content::WebContents* GetVisibleWebContents() const; + + // The BrowserContext that this dispatcher is associated with. + content::BrowserContext* browser_context() { return browser_context_; } + + void set_delegate(Delegate* delegate) { delegate_ = delegate; } + + private: + // For a given RenderFrameHost instance, UIThreadResponseCallbackWrapper + // creates ExtensionFunction::ResponseCallback instances which send responses + // to the corresponding render view in ExtensionMsg_Response messages. + // This class tracks the lifespan of the RenderFrameHost instance, and will be + // destroyed automatically when it goes away. + class UIThreadResponseCallbackWrapper; + + // Helper to check whether an ExtensionFunction has the required permissions. + // This should be called after the function is fully initialized. + // If the check fails, |callback| is run with an access-denied error and false + // is returned. |function| must not be run in that case. + static bool CheckPermissions( + ExtensionFunction* function, + const ExtensionHostMsg_Request_Params& params, + const ExtensionFunction::ResponseCallback& callback); + + // Helper to create an ExtensionFunction to handle the function given by + // |params|. Can be called on any thread. + // Does not set subclass properties, or include_incognito. + static ExtensionFunction* CreateExtensionFunction( + const ExtensionHostMsg_Request_Params& params, + const Extension* extension, + int requesting_process_id, + const ProcessMap& process_map, + ExtensionAPI* api, + void* profile_id, + const ExtensionFunction::ResponseCallback& callback); + + // Helper to run the response callback with an access denied error. Can be + // called on any thread. + static void SendAccessDenied( + const ExtensionFunction::ResponseCallback& callback, + functions::HistogramValue histogram_value); + + void DispatchWithCallbackInternal( + const ExtensionHostMsg_Request_Params& params, + content::RenderFrameHost* render_frame_host, + const ExtensionFunction::ResponseCallback& callback); + + content::BrowserContext* browser_context_; + + Delegate* delegate_; + + // This map doesn't own either the keys or the values. When a RenderFrameHost + // instance goes away, the corresponding entry in this map (if exists) will be + // removed. + typedef std::map<content::RenderFrameHost*, UIThreadResponseCallbackWrapper*> + UIThreadResponseCallbackWrapperMap; + UIThreadResponseCallbackWrapperMap ui_thread_response_callback_wrappers_; +}; + +} // namespace extensions + +#endif // EXTENSIONS_BROWSER_EXTENSION_FUNCTION_DISPATCHER_H_ |