Home | History | Annotate | Download | only in browser
      1 // Copyright 2014 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef EXTENSIONS_BROWSER_EXTENSION_FUNCTION_DISPATCHER_H_
      6 #define EXTENSIONS_BROWSER_EXTENSION_FUNCTION_DISPATCHER_H_
      7 
      8 #include <map>
      9 #include <string>
     10 #include <vector>
     11 
     12 #include "base/memory/weak_ptr.h"
     13 #include "extensions/browser/extension_function.h"
     14 #include "ipc/ipc_sender.h"
     15 
     16 struct ExtensionHostMsg_Request_Params;
     17 
     18 namespace content {
     19 class BrowserContext;
     20 class RenderFrameHost;
     21 class RenderViewHost;
     22 class WebContents;
     23 }
     24 
     25 namespace extensions {
     26 
     27 class Extension;
     28 class ExtensionAPI;
     29 class ExtensionMessageFilter;
     30 class InfoMap;
     31 class ProcessMap;
     32 class WindowController;
     33 
     34 // A factory function for creating new ExtensionFunction instances.
     35 typedef ExtensionFunction* (*ExtensionFunctionFactory)();
     36 
     37 // ExtensionFunctionDispatcher receives requests to execute functions from
     38 // Chrome extensions running in a RenderViewHost and dispatches them to the
     39 // appropriate handler. It lives entirely on the UI thread.
     40 //
     41 // ExtensionFunctionDispatcher should be a member of some class that hosts
     42 // RenderViewHosts and wants them to be able to display extension content.
     43 // This class should also implement ExtensionFunctionDispatcher::Delegate.
     44 //
     45 // Note that a single ExtensionFunctionDispatcher does *not* correspond to a
     46 // single RVH, a single extension, or a single URL. This is by design so that
     47 // we can gracefully handle cases like WebContents, where the RVH, extension,
     48 // and URL can all change over the lifetime of the tab. Instead, these items
     49 // are all passed into each request.
     50 class ExtensionFunctionDispatcher
     51     : public base::SupportsWeakPtr<ExtensionFunctionDispatcher> {
     52  public:
     53   class Delegate {
     54    public:
     55     // Returns the WindowController associated with this delegate, or NULL if no
     56     // window is associated with the delegate.
     57     virtual WindowController* GetExtensionWindowController() const;
     58 
     59     // Asks the delegate for any relevant WebContents associated with this
     60     // context. For example, the WebContents in which an infobar or
     61     // chrome-extension://<id> URL are being shown. Callers must check for a
     62     // NULL return value (as in the case of a background page).
     63     virtual content::WebContents* GetAssociatedWebContents() const;
     64 
     65     // If the associated web contents is not null, returns that. Otherwise,
     66     // returns the next most relevant visible web contents. Callers must check
     67     // for a NULL return value (as in the case of a background page).
     68     virtual content::WebContents* GetVisibleWebContents() const;
     69 
     70    protected:
     71     virtual ~Delegate() {}
     72   };
     73 
     74   // Gets a list of all known extension function names.
     75   static void GetAllFunctionNames(std::vector<std::string>* names);
     76 
     77   // Override a previously registered function. Returns true if successful,
     78   // false if no such function was registered.
     79   static bool OverrideFunction(const std::string& name,
     80                                ExtensionFunctionFactory factory);
     81 
     82   // Dispatches an IO-thread extension function. Only used for specific
     83   // functions that must be handled on the IO-thread.
     84   static void DispatchOnIOThread(
     85       InfoMap* extension_info_map,
     86       void* profile_id,
     87       int render_process_id,
     88       base::WeakPtr<ExtensionMessageFilter> ipc_sender,
     89       int routing_id,
     90       const ExtensionHostMsg_Request_Params& params);
     91 
     92   // Public constructor. Callers must ensure that:
     93   // - |delegate| outlives this object.
     94   // - This object outlives any RenderViewHost's passed to created
     95   //   ExtensionFunctions.
     96   ExtensionFunctionDispatcher(content::BrowserContext* browser_context,
     97                               Delegate* delegate);
     98 
     99   ~ExtensionFunctionDispatcher();
    100 
    101   Delegate* delegate() { return delegate_; }
    102 
    103   // Message handlers.
    104   // The response is sent to the corresponding render view in an
    105   // ExtensionMsg_Response message.
    106   // TODO (jam): convert all callers to use RenderFrameHost.
    107   void Dispatch(const ExtensionHostMsg_Request_Params& params,
    108                 content::RenderViewHost* render_view_host);
    109   // Dispatch an extension function and calls |callback| when the execution
    110   // completes.
    111   void DispatchWithCallback(
    112       const ExtensionHostMsg_Request_Params& params,
    113       content::RenderFrameHost* render_frame_host,
    114       const ExtensionFunction::ResponseCallback& callback);
    115 
    116   // Called when an ExtensionFunction is done executing, after it has sent
    117   // a response (if any) to the extension.
    118   void OnExtensionFunctionCompleted(const Extension* extension);
    119 
    120   // The BrowserContext that this dispatcher is associated with.
    121   content::BrowserContext* browser_context() { return browser_context_; }
    122 
    123  private:
    124   // For a given RenderViewHost instance, UIThreadResponseCallbackWrapper
    125   // creates ExtensionFunction::ResponseCallback instances which send responses
    126   // to the corresponding render view in ExtensionMsg_Response messages.
    127   // This class tracks the lifespan of the RenderViewHost instance, and will be
    128   // destroyed automatically when it goes away.
    129   class UIThreadResponseCallbackWrapper;
    130 
    131   // Helper to check whether an ExtensionFunction has the required permissions.
    132   // This should be called after the function is fully initialized.
    133   // If the check fails, |callback| is run with an access-denied error and false
    134   // is returned. |function| must not be run in that case.
    135   static bool CheckPermissions(
    136       ExtensionFunction* function,
    137       const Extension* extension,
    138       const ExtensionHostMsg_Request_Params& params,
    139       const ExtensionFunction::ResponseCallback& callback);
    140 
    141   // Helper to create an ExtensionFunction to handle the function given by
    142   // |params|. Can be called on any thread.
    143   // Does not set subclass properties, or include_incognito.
    144   static ExtensionFunction* CreateExtensionFunction(
    145       const ExtensionHostMsg_Request_Params& params,
    146       const Extension* extension,
    147       int requesting_process_id,
    148       const ProcessMap& process_map,
    149       ExtensionAPI* api,
    150       void* profile_id,
    151       const ExtensionFunction::ResponseCallback& callback);
    152 
    153   // Helper to run the response callback with an access denied error. Can be
    154   // called on any thread.
    155   static void SendAccessDenied(
    156       const ExtensionFunction::ResponseCallback& callback);
    157 
    158   void DispatchWithCallbackInternal(
    159       const ExtensionHostMsg_Request_Params& params,
    160       content::RenderViewHost* render_view_host,
    161       content::RenderFrameHost* render_frame_host,
    162       const ExtensionFunction::ResponseCallback& callback);
    163 
    164   content::BrowserContext* browser_context_;
    165 
    166   Delegate* delegate_;
    167 
    168   // This map doesn't own either the keys or the values. When a RenderViewHost
    169   // instance goes away, the corresponding entry in this map (if exists) will be
    170   // removed.
    171   typedef std::map<content::RenderViewHost*, UIThreadResponseCallbackWrapper*>
    172       UIThreadResponseCallbackWrapperMap;
    173   UIThreadResponseCallbackWrapperMap ui_thread_response_callback_wrappers_;
    174 };
    175 
    176 }  // namespace extensions
    177 
    178 #endif  // EXTENSIONS_BROWSER_EXTENSION_FUNCTION_DISPATCHER_H_
    179