[email protected] | 0b9de03 | 2014-03-15 05:47:01 | [diff] [blame] | 1 | // Copyright 2014 The Chromium Authors. All rights reserved. |
[email protected] | 703e807a | 2009-03-28 19:56:51 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
[email protected] | 0b9de03 | 2014-03-15 05:47:01 | [diff] [blame] | 5 | #ifndef EXTENSIONS_BROWSER_EXTENSION_FUNCTION_DISPATCHER_H_ |
| 6 | #define EXTENSIONS_BROWSER_EXTENSION_FUNCTION_DISPATCHER_H_ |
[email protected] | 703e807a | 2009-03-28 19:56:51 | [diff] [blame] | 7 | |
[email protected] | 35548ab | 2013-05-15 08:59:47 | [diff] [blame] | 8 | #include <map> |
[email protected] | 703e807a | 2009-03-28 19:56:51 | [diff] [blame] | 9 | #include <string> |
| 10 | #include <vector> |
| 11 | |
[email protected] | 55ce33071 | 2011-05-24 19:04:27 | [diff] [blame] | 12 | #include "base/memory/weak_ptr.h" |
[email protected] | 14c3571a | 2013-11-13 00:18:44 | [diff] [blame] | 13 | #include "extensions/browser/extension_function.h" |
[email protected] | b44f8ad | 2012-06-15 20:52:58 | [diff] [blame] | 14 | #include "ipc/ipc_sender.h" |
[email protected] | 703e807a | 2009-03-28 19:56:51 | [diff] [blame] | 15 | |
[email protected] | f82d57b5 | 2011-04-27 19:13:17 | [diff] [blame] | 16 | struct ExtensionHostMsg_Request_Params; |
[email protected] | 703e807a | 2009-03-28 19:56:51 | [diff] [blame] | 17 | |
[email protected] | ea049a0 | 2011-12-25 21:37:09 | [diff] [blame] | 18 | namespace content { |
[email protected] | 96e6a103 | 2013-11-28 06:58:03 | [diff] [blame] | 19 | class BrowserContext; |
[email protected] | 6dd625e | 2013-12-20 17:03:07 | [diff] [blame] | 20 | class RenderFrameHost; |
[email protected] | ea049a0 | 2011-12-25 21:37:09 | [diff] [blame] | 21 | class WebContents; |
| 22 | } |
| 23 | |
[email protected] | 6f37144 | 2011-11-09 06:45:46 | [diff] [blame] | 24 | namespace extensions { |
[email protected] | 1a043689 | 2014-04-01 00:38:25 | [diff] [blame] | 25 | |
[email protected] | 1c321ee5 | 2012-05-21 03:02:34 | [diff] [blame] | 26 | class Extension; |
[email protected] | 5bc248a | 2012-04-04 23:38:11 | [diff] [blame] | 27 | class ExtensionAPI; |
[email protected] | 6f37144 | 2011-11-09 06:45:46 | [diff] [blame] | 28 | class ProcessMap; |
[email protected] | 44f4b13 | 2012-07-17 20:36:57 | [diff] [blame] | 29 | class WindowController; |
[email protected] | 6f37144 | 2011-11-09 06:45:46 | [diff] [blame] | 30 | |
[email protected] | 703e807a | 2009-03-28 19:56:51 | [diff] [blame] | 31 | // ExtensionFunctionDispatcher receives requests to execute functions from |
rdevlin.cronin | 92503ba | 2015-06-12 17:00:56 | [diff] [blame] | 32 | // Chrome extensions running in a RenderFrameHost and dispatches them to the |
[email protected] | 703e807a | 2009-03-28 19:56:51 | [diff] [blame] | 33 | // appropriate handler. It lives entirely on the UI thread. |
[email protected] | c5dbef0 | 2011-05-13 05:06:09 | [diff] [blame] | 34 | // |
| 35 | // ExtensionFunctionDispatcher should be a member of some class that hosts |
rdevlin.cronin | 92503ba | 2015-06-12 17:00:56 | [diff] [blame] | 36 | // RenderFrameHosts and wants them to be able to display extension content. |
[email protected] | c5dbef0 | 2011-05-13 05:06:09 | [diff] [blame] | 37 | // This class should also implement ExtensionFunctionDispatcher::Delegate. |
| 38 | // |
| 39 | // Note that a single ExtensionFunctionDispatcher does *not* correspond to a |
| 40 | // single RVH, a single extension, or a single URL. This is by design so that |
[email protected] | 0932b30c | 2012-04-17 13:25:10 | [diff] [blame] | 41 | // we can gracefully handle cases like WebContents, where the RVH, extension, |
[email protected] | c5dbef0 | 2011-05-13 05:06:09 | [diff] [blame] | 42 | // and URL can all change over the lifetime of the tab. Instead, these items |
| 43 | // are all passed into each request. |
[email protected] | 55ce33071 | 2011-05-24 19:04:27 | [diff] [blame] | 44 | class ExtensionFunctionDispatcher |
| 45 | : public base::SupportsWeakPtr<ExtensionFunctionDispatcher> { |
[email protected] | 703e807a | 2009-03-28 19:56:51 | [diff] [blame] | 46 | public: |
[email protected] | 7eecaed5 | 2009-05-07 21:44:12 | [diff] [blame] | 47 | class Delegate { |
| 48 | public: |
[email protected] | 1a043689 | 2014-04-01 00:38:25 | [diff] [blame] | 49 | // Returns the WindowController associated with this delegate, or NULL if no |
| 50 | // window is associated with the delegate. |
| 51 | virtual WindowController* GetExtensionWindowController() const; |
[email protected] | a95631cb | 2009-12-10 01:59:11 | [diff] [blame] | 52 | |
[email protected] | 45c75e6 | 2012-03-21 19:56:35 | [diff] [blame] | 53 | // Asks the delegate for any relevant WebContents associated with this |
[email protected] | 1ce88e8 | 2013-06-28 05:17:10 | [diff] [blame] | 54 | // context. For example, the WebContents in which an infobar or |
[email protected] | 9aa2eaa | 2010-04-15 19:05:07 | [diff] [blame] | 55 | // chrome-extension://<id> URL are being shown. Callers must check for a |
| 56 | // NULL return value (as in the case of a background page). |
[email protected] | d72d3a6 | 2012-05-10 03:45:08 | [diff] [blame] | 57 | virtual content::WebContents* GetAssociatedWebContents() const; |
[email protected] | 9aa2eaa | 2010-04-15 19:05:07 | [diff] [blame] | 58 | |
[email protected] | 1ce88e8 | 2013-06-28 05:17:10 | [diff] [blame] | 59 | // If the associated web contents is not null, returns that. Otherwise, |
| 60 | // returns the next most relevant visible web contents. Callers must check |
| 61 | // for a NULL return value (as in the case of a background page). |
| 62 | virtual content::WebContents* GetVisibleWebContents() const; |
| 63 | |
[email protected] | 135fd3b6 | 2009-12-16 01:07:08 | [diff] [blame] | 64 | protected: |
| 65 | virtual ~Delegate() {} |
[email protected] | 7eecaed5 | 2009-05-07 21:44:12 | [diff] [blame] | 66 | }; |
| 67 | |
[email protected] | c5dbef0 | 2011-05-13 05:06:09 | [diff] [blame] | 68 | // Public constructor. Callers must ensure that: |
rdevlin.cronin | 92503ba | 2015-06-12 17:00:56 | [diff] [blame] | 69 | // - This object outlives any RenderFrameHost's passed to created |
[email protected] | c5dbef0 | 2011-05-13 05:06:09 | [diff] [blame] | 70 | // ExtensionFunctions. |
rdevlin.cronin | cb2ec659a | 2015-06-10 23:32:41 | [diff] [blame] | 71 | explicit ExtensionFunctionDispatcher( |
| 72 | content::BrowserContext* browser_context); |
[email protected] | 32dda36 | 2009-06-05 19:07:01 | [diff] [blame] | 73 | ~ExtensionFunctionDispatcher(); |
[email protected] | 703e807a | 2009-03-28 19:56:51 | [diff] [blame] | 74 | |
[email protected] | c5dbef0 | 2011-05-13 05:06:09 | [diff] [blame] | 75 | // Message handlers. |
[email protected] | 35548ab | 2013-05-15 08:59:47 | [diff] [blame] | 76 | // The response is sent to the corresponding render view in an |
| 77 | // ExtensionMsg_Response message. |
[email protected] | c5dbef0 | 2011-05-13 05:06:09 | [diff] [blame] | 78 | void Dispatch(const ExtensionHostMsg_Request_Params& params, |
lazyboy | ee4adef | 2016-05-24 00:55:16 | [diff] [blame] | 79 | content::RenderFrameHost* render_frame_host, |
| 80 | int render_process_id); |
[email protected] | 703e807a | 2009-03-28 19:56:51 | [diff] [blame] | 81 | |
[email protected] | 720ad131 | 2012-02-27 23:07:36 | [diff] [blame] | 82 | // Called when an ExtensionFunction is done executing, after it has sent |
| 83 | // a response (if any) to the extension. |
lazyboy | 4c82177a | 2016-10-18 00:04:09 | [diff] [blame] | 84 | void OnExtensionFunctionCompleted(const Extension* extension, |
David Bertoni | 3e1e9fa | 2018-08-29 20:39:30 | [diff] [blame] | 85 | bool is_from_service_worker, |
| 86 | const char* name); |
[email protected] | 720ad131 | 2012-02-27 23:07:36 | [diff] [blame] | 87 | |
rdevlin.cronin | cb2ec659a | 2015-06-10 23:32:41 | [diff] [blame] | 88 | // See the Delegate class for documentation on these methods. |
| 89 | // TODO(devlin): None of these belong here. We should kill |
| 90 | // ExtensionFunctionDispatcher::Delegate. |
| 91 | WindowController* GetExtensionWindowController() const; |
| 92 | content::WebContents* GetAssociatedWebContents() const; |
| 93 | content::WebContents* GetVisibleWebContents() const; |
| 94 | |
[email protected] | 8637602 | 2013-12-03 18:18:05 | [diff] [blame] | 95 | // The BrowserContext that this dispatcher is associated with. |
| 96 | content::BrowserContext* browser_context() { return browser_context_; } |
[email protected] | 811bfe37 | 2009-07-01 08:46:25 | [diff] [blame] | 97 | |
rdevlin.cronin | cb2ec659a | 2015-06-10 23:32:41 | [diff] [blame] | 98 | void set_delegate(Delegate* delegate) { delegate_ = delegate; } |
| 99 | |
[email protected] | 703e807a | 2009-03-28 19:56:51 | [diff] [blame] | 100 | private: |
David Bertoni | ac5892eb | 2020-01-03 00:36:44 | [diff] [blame] | 101 | // For a given RenderFrameHost instance, ResponseCallbackWrapper |
[email protected] | 35548ab | 2013-05-15 08:59:47 | [diff] [blame] | 102 | // creates ExtensionFunction::ResponseCallback instances which send responses |
| 103 | // to the corresponding render view in ExtensionMsg_Response messages. |
rdevlin.cronin | 92503ba | 2015-06-12 17:00:56 | [diff] [blame] | 104 | // This class tracks the lifespan of the RenderFrameHost instance, and will be |
[email protected] | 35548ab | 2013-05-15 08:59:47 | [diff] [blame] | 105 | // destroyed automatically when it goes away. |
David Bertoni | ac5892eb | 2020-01-03 00:36:44 | [diff] [blame] | 106 | class ResponseCallbackWrapper; |
[email protected] | 35548ab | 2013-05-15 08:59:47 | [diff] [blame] | 107 | |
David Bertoni | ac5892eb | 2020-01-03 00:36:44 | [diff] [blame] | 108 | // Same as ResponseCallbackWrapper above, but applies to an extension |
lazyboy | ee4adef | 2016-05-24 00:55:16 | [diff] [blame] | 109 | // function from an extension Service Worker. |
David Bertoni | ac5892eb | 2020-01-03 00:36:44 | [diff] [blame] | 110 | class WorkerResponseCallbackWrapper; |
lazyboy | ee4adef | 2016-05-24 00:55:16 | [diff] [blame] | 111 | |
David Bertoni | ac5892eb | 2020-01-03 00:36:44 | [diff] [blame] | 112 | // Key used to store WorkerResponseCallbackWrapper in the map |
| 113 | // |response_callback_wrappers_for_worker_|. |
lazyboy | ee4adef | 2016-05-24 00:55:16 | [diff] [blame] | 114 | struct WorkerResponseCallbackMapKey; |
| 115 | |
[email protected] | d2fe22ff | 2012-10-03 00:40:07 | [diff] [blame] | 116 | // Helper to check whether an ExtensionFunction has the required permissions. |
| 117 | // This should be called after the function is fully initialized. |
[email protected] | 35548ab | 2013-05-15 08:59:47 | [diff] [blame] | 118 | // If the check fails, |callback| is run with an access-denied error and false |
| 119 | // is returned. |function| must not be run in that case. |
[email protected] | d2fe22ff | 2012-10-03 00:40:07 | [diff] [blame] | 120 | static bool CheckPermissions( |
| 121 | ExtensionFunction* function, |
[email protected] | d2fe22ff | 2012-10-03 00:40:07 | [diff] [blame] | 122 | const ExtensionHostMsg_Request_Params& params, |
[email protected] | 35548ab | 2013-05-15 08:59:47 | [diff] [blame] | 123 | const ExtensionFunction::ResponseCallback& callback); |
[email protected] | d2fe22ff | 2012-10-03 00:40:07 | [diff] [blame] | 124 | |
[email protected] | c357acb4 | 2011-06-09 20:52:42 | [diff] [blame] | 125 | // Helper to create an ExtensionFunction to handle the function given by |
| 126 | // |params|. Can be called on any thread. |
| 127 | // Does not set subclass properties, or include_incognito. |
Matthew Denton | ef83a62 | 2019-08-30 02:07:00 | [diff] [blame] | 128 | static scoped_refptr<ExtensionFunction> CreateExtensionFunction( |
[email protected] | c357acb4 | 2011-06-09 20:52:42 | [diff] [blame] | 129 | const ExtensionHostMsg_Request_Params& params, |
[email protected] | 1a043689 | 2014-04-01 00:38:25 | [diff] [blame] | 130 | const Extension* extension, |
[email protected] | 6f37144 | 2011-11-09 06:45:46 | [diff] [blame] | 131 | int requesting_process_id, |
Giovanni Ortuño Urquidi | 7b65723 | 2020-03-01 12:08:46 | [diff] [blame] | 132 | const GURL* rfh_url, |
[email protected] | 1a043689 | 2014-04-01 00:38:25 | [diff] [blame] | 133 | const ProcessMap& process_map, |
| 134 | ExtensionAPI* api, |
| 135 | void* profile_id, |
[email protected] | 35548ab | 2013-05-15 08:59:47 | [diff] [blame] | 136 | const ExtensionFunction::ResponseCallback& callback); |
[email protected] | c357acb4 | 2011-06-09 20:52:42 | [diff] [blame] | 137 | |
[email protected] | 35548ab | 2013-05-15 08:59:47 | [diff] [blame] | 138 | // Helper to run the response callback with an access denied error. Can be |
[email protected] | c357acb4 | 2011-06-09 20:52:42 | [diff] [blame] | 139 | // called on any thread. |
[email protected] | 35548ab | 2013-05-15 08:59:47 | [diff] [blame] | 140 | static void SendAccessDenied( |
Istiaque Ahmed | 926fad8 | 2019-07-15 21:42:04 | [diff] [blame] | 141 | const ExtensionFunction::ResponseCallback& callback); |
[email protected] | a91afcb | 2010-03-25 21:15:02 | [diff] [blame] | 142 | |
[email protected] | 6dd625e | 2013-12-20 17:03:07 | [diff] [blame] | 143 | void DispatchWithCallbackInternal( |
| 144 | const ExtensionHostMsg_Request_Params& params, |
[email protected] | 6dd625e | 2013-12-20 17:03:07 | [diff] [blame] | 145 | content::RenderFrameHost* render_frame_host, |
lazyboy | ee4adef | 2016-05-24 00:55:16 | [diff] [blame] | 146 | int render_process_id, |
[email protected] | 6dd625e | 2013-12-20 17:03:07 | [diff] [blame] | 147 | const ExtensionFunction::ResponseCallback& callback); |
| 148 | |
lazyboy | ee4adef | 2016-05-24 00:55:16 | [diff] [blame] | 149 | void RemoveWorkerCallbacksForProcess(int render_process_id); |
| 150 | |
[email protected] | 8637602 | 2013-12-03 18:18:05 | [diff] [blame] | 151 | content::BrowserContext* browser_context_; |
[email protected] | 68f0791 | 2010-03-05 18:33:58 | [diff] [blame] | 152 | |
[email protected] | 7eecaed5 | 2009-05-07 21:44:12 | [diff] [blame] | 153 | Delegate* delegate_; |
[email protected] | 35548ab | 2013-05-15 08:59:47 | [diff] [blame] | 154 | |
rdevlin.cronin | 92503ba | 2015-06-12 17:00:56 | [diff] [blame] | 155 | // This map doesn't own either the keys or the values. When a RenderFrameHost |
[email protected] | 35548ab | 2013-05-15 08:59:47 | [diff] [blame] | 156 | // instance goes away, the corresponding entry in this map (if exists) will be |
| 157 | // removed. |
apisarev | fbaad66 | 2017-04-28 08:36:52 | [diff] [blame] | 158 | typedef std::map<content::RenderFrameHost*, |
David Bertoni | ac5892eb | 2020-01-03 00:36:44 | [diff] [blame] | 159 | std::unique_ptr<ResponseCallbackWrapper>> |
| 160 | ResponseCallbackWrapperMap; |
| 161 | ResponseCallbackWrapperMap response_callback_wrappers_; |
lazyboy | ee4adef | 2016-05-24 00:55:16 | [diff] [blame] | 162 | |
David Bertoni | ac5892eb | 2020-01-03 00:36:44 | [diff] [blame] | 163 | using WorkerResponseCallbackWrapperMap = |
lazyboy | ee4adef | 2016-05-24 00:55:16 | [diff] [blame] | 164 | std::map<WorkerResponseCallbackMapKey, |
David Bertoni | ac5892eb | 2020-01-03 00:36:44 | [diff] [blame] | 165 | std::unique_ptr<WorkerResponseCallbackWrapper>>; |
lazyboy | ee4adef | 2016-05-24 00:55:16 | [diff] [blame] | 166 | // TODO(lazyboy): The map entries are cleared upon RenderProcessHost shutown, |
| 167 | // we should really be clearing it on service worker shutdown. |
David Bertoni | ac5892eb | 2020-01-03 00:36:44 | [diff] [blame] | 168 | WorkerResponseCallbackWrapperMap response_callback_wrappers_for_worker_; |
[email protected] | 703e807a | 2009-03-28 19:56:51 | [diff] [blame] | 169 | }; |
| 170 | |
[email protected] | 1a043689 | 2014-04-01 00:38:25 | [diff] [blame] | 171 | } // namespace extensions |
| 172 | |
[email protected] | 0b9de03 | 2014-03-15 05:47:01 | [diff] [blame] | 173 | #endif // EXTENSIONS_BROWSER_EXTENSION_FUNCTION_DISPATCHER_H_ |