• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
~Delegate()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 
delegate()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.
browser_context()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