blob: e5a060b1913b98f67a7caa8d47d0a39095457af3 [file] [log] [blame]
[email protected]0b9de032014-03-15 05:47:011// Copyright 2014 The Chromium Authors. All rights reserved.
[email protected]703e807a2009-03-28 19:56:512// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]0b9de032014-03-15 05:47:015#ifndef EXTENSIONS_BROWSER_EXTENSION_FUNCTION_DISPATCHER_H_
6#define EXTENSIONS_BROWSER_EXTENSION_FUNCTION_DISPATCHER_H_
[email protected]703e807a2009-03-28 19:56:517
[email protected]35548ab2013-05-15 08:59:478#include <map>
[email protected]703e807a2009-03-28 19:56:519#include <string>
10#include <vector>
11
[email protected]55ce330712011-05-24 19:04:2712#include "base/memory/weak_ptr.h"
[email protected]14c3571a2013-11-13 00:18:4413#include "extensions/browser/extension_function.h"
[email protected]b44f8ad2012-06-15 20:52:5814#include "ipc/ipc_sender.h"
[email protected]703e807a2009-03-28 19:56:5115
[email protected]f82d57b52011-04-27 19:13:1716struct ExtensionHostMsg_Request_Params;
[email protected]703e807a2009-03-28 19:56:5117
[email protected]ea049a02011-12-25 21:37:0918namespace content {
[email protected]96e6a1032013-11-28 06:58:0319class BrowserContext;
[email protected]6dd625e2013-12-20 17:03:0720class RenderFrameHost;
[email protected]ea049a02011-12-25 21:37:0921class WebContents;
22}
23
[email protected]6f371442011-11-09 06:45:4624namespace extensions {
[email protected]1a0436892014-04-01 00:38:2525
[email protected]1c321ee52012-05-21 03:02:3426class Extension;
[email protected]5bc248a2012-04-04 23:38:1127class ExtensionAPI;
[email protected]6f371442011-11-09 06:45:4628class ProcessMap;
[email protected]44f4b132012-07-17 20:36:5729class WindowController;
[email protected]6f371442011-11-09 06:45:4630
[email protected]703e807a2009-03-28 19:56:5131// ExtensionFunctionDispatcher receives requests to execute functions from
rdevlin.cronin92503ba2015-06-12 17:00:5632// Chrome extensions running in a RenderFrameHost and dispatches them to the
[email protected]703e807a2009-03-28 19:56:5133// appropriate handler. It lives entirely on the UI thread.
[email protected]c5dbef02011-05-13 05:06:0934//
35// ExtensionFunctionDispatcher should be a member of some class that hosts
rdevlin.cronin92503ba2015-06-12 17:00:5636// RenderFrameHosts and wants them to be able to display extension content.
[email protected]c5dbef02011-05-13 05:06:0937// 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]0932b30c2012-04-17 13:25:1041// we can gracefully handle cases like WebContents, where the RVH, extension,
[email protected]c5dbef02011-05-13 05:06:0942// and URL can all change over the lifetime of the tab. Instead, these items
43// are all passed into each request.
[email protected]55ce330712011-05-24 19:04:2744class ExtensionFunctionDispatcher
45 : public base::SupportsWeakPtr<ExtensionFunctionDispatcher> {
[email protected]703e807a2009-03-28 19:56:5146 public:
[email protected]7eecaed52009-05-07 21:44:1247 class Delegate {
48 public:
[email protected]1a0436892014-04-01 00:38:2549 // 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]a95631cb2009-12-10 01:59:1152
[email protected]45c75e62012-03-21 19:56:3553 // Asks the delegate for any relevant WebContents associated with this
[email protected]1ce88e82013-06-28 05:17:1054 // context. For example, the WebContents in which an infobar or
[email protected]9aa2eaa2010-04-15 19:05:0755 // 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]d72d3a62012-05-10 03:45:0857 virtual content::WebContents* GetAssociatedWebContents() const;
[email protected]9aa2eaa2010-04-15 19:05:0758
[email protected]1ce88e82013-06-28 05:17:1059 // 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]135fd3b62009-12-16 01:07:0864 protected:
65 virtual ~Delegate() {}
[email protected]7eecaed52009-05-07 21:44:1266 };
67
[email protected]c5dbef02011-05-13 05:06:0968 // Public constructor. Callers must ensure that:
rdevlin.cronin92503ba2015-06-12 17:00:5669 // - This object outlives any RenderFrameHost's passed to created
[email protected]c5dbef02011-05-13 05:06:0970 // ExtensionFunctions.
rdevlin.cronincb2ec659a2015-06-10 23:32:4171 explicit ExtensionFunctionDispatcher(
72 content::BrowserContext* browser_context);
[email protected]32dda362009-06-05 19:07:0173 ~ExtensionFunctionDispatcher();
[email protected]703e807a2009-03-28 19:56:5174
[email protected]c5dbef02011-05-13 05:06:0975 // Message handlers.
[email protected]35548ab2013-05-15 08:59:4776 // The response is sent to the corresponding render view in an
77 // ExtensionMsg_Response message.
[email protected]c5dbef02011-05-13 05:06:0978 void Dispatch(const ExtensionHostMsg_Request_Params& params,
lazyboyee4adef2016-05-24 00:55:1679 content::RenderFrameHost* render_frame_host,
80 int render_process_id);
[email protected]703e807a2009-03-28 19:56:5181
[email protected]720ad1312012-02-27 23:07:3682 // Called when an ExtensionFunction is done executing, after it has sent
83 // a response (if any) to the extension.
lazyboy4c82177a2016-10-18 00:04:0984 void OnExtensionFunctionCompleted(const Extension* extension,
David Bertoni3e1e9fa2018-08-29 20:39:3085 bool is_from_service_worker,
86 const char* name);
[email protected]720ad1312012-02-27 23:07:3687
rdevlin.cronincb2ec659a2015-06-10 23:32:4188 // 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]86376022013-12-03 18:18:0595 // The BrowserContext that this dispatcher is associated with.
96 content::BrowserContext* browser_context() { return browser_context_; }
[email protected]811bfe372009-07-01 08:46:2597
rdevlin.cronincb2ec659a2015-06-10 23:32:4198 void set_delegate(Delegate* delegate) { delegate_ = delegate; }
99
[email protected]703e807a2009-03-28 19:56:51100 private:
David Bertoniac5892eb2020-01-03 00:36:44101 // For a given RenderFrameHost instance, ResponseCallbackWrapper
[email protected]35548ab2013-05-15 08:59:47102 // creates ExtensionFunction::ResponseCallback instances which send responses
103 // to the corresponding render view in ExtensionMsg_Response messages.
rdevlin.cronin92503ba2015-06-12 17:00:56104 // This class tracks the lifespan of the RenderFrameHost instance, and will be
[email protected]35548ab2013-05-15 08:59:47105 // destroyed automatically when it goes away.
David Bertoniac5892eb2020-01-03 00:36:44106 class ResponseCallbackWrapper;
[email protected]35548ab2013-05-15 08:59:47107
David Bertoniac5892eb2020-01-03 00:36:44108 // Same as ResponseCallbackWrapper above, but applies to an extension
lazyboyee4adef2016-05-24 00:55:16109 // function from an extension Service Worker.
David Bertoniac5892eb2020-01-03 00:36:44110 class WorkerResponseCallbackWrapper;
lazyboyee4adef2016-05-24 00:55:16111
David Bertoniac5892eb2020-01-03 00:36:44112 // Key used to store WorkerResponseCallbackWrapper in the map
113 // |response_callback_wrappers_for_worker_|.
lazyboyee4adef2016-05-24 00:55:16114 struct WorkerResponseCallbackMapKey;
115
[email protected]d2fe22ff2012-10-03 00:40:07116 // Helper to check whether an ExtensionFunction has the required permissions.
117 // This should be called after the function is fully initialized.
[email protected]35548ab2013-05-15 08:59:47118 // 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]d2fe22ff2012-10-03 00:40:07120 static bool CheckPermissions(
121 ExtensionFunction* function,
[email protected]d2fe22ff2012-10-03 00:40:07122 const ExtensionHostMsg_Request_Params& params,
[email protected]35548ab2013-05-15 08:59:47123 const ExtensionFunction::ResponseCallback& callback);
[email protected]d2fe22ff2012-10-03 00:40:07124
[email protected]c357acb42011-06-09 20:52:42125 // 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 Dentonef83a622019-08-30 02:07:00128 static scoped_refptr<ExtensionFunction> CreateExtensionFunction(
[email protected]c357acb42011-06-09 20:52:42129 const ExtensionHostMsg_Request_Params& params,
[email protected]1a0436892014-04-01 00:38:25130 const Extension* extension,
[email protected]6f371442011-11-09 06:45:46131 int requesting_process_id,
Giovanni Ortuño Urquidi7b657232020-03-01 12:08:46132 const GURL* rfh_url,
[email protected]1a0436892014-04-01 00:38:25133 const ProcessMap& process_map,
134 ExtensionAPI* api,
135 void* profile_id,
[email protected]35548ab2013-05-15 08:59:47136 const ExtensionFunction::ResponseCallback& callback);
[email protected]c357acb42011-06-09 20:52:42137
[email protected]35548ab2013-05-15 08:59:47138 // Helper to run the response callback with an access denied error. Can be
[email protected]c357acb42011-06-09 20:52:42139 // called on any thread.
[email protected]35548ab2013-05-15 08:59:47140 static void SendAccessDenied(
Istiaque Ahmed926fad82019-07-15 21:42:04141 const ExtensionFunction::ResponseCallback& callback);
[email protected]a91afcb2010-03-25 21:15:02142
[email protected]6dd625e2013-12-20 17:03:07143 void DispatchWithCallbackInternal(
144 const ExtensionHostMsg_Request_Params& params,
[email protected]6dd625e2013-12-20 17:03:07145 content::RenderFrameHost* render_frame_host,
lazyboyee4adef2016-05-24 00:55:16146 int render_process_id,
[email protected]6dd625e2013-12-20 17:03:07147 const ExtensionFunction::ResponseCallback& callback);
148
lazyboyee4adef2016-05-24 00:55:16149 void RemoveWorkerCallbacksForProcess(int render_process_id);
150
[email protected]86376022013-12-03 18:18:05151 content::BrowserContext* browser_context_;
[email protected]68f07912010-03-05 18:33:58152
[email protected]7eecaed52009-05-07 21:44:12153 Delegate* delegate_;
[email protected]35548ab2013-05-15 08:59:47154
rdevlin.cronin92503ba2015-06-12 17:00:56155 // This map doesn't own either the keys or the values. When a RenderFrameHost
[email protected]35548ab2013-05-15 08:59:47156 // instance goes away, the corresponding entry in this map (if exists) will be
157 // removed.
apisarevfbaad662017-04-28 08:36:52158 typedef std::map<content::RenderFrameHost*,
David Bertoniac5892eb2020-01-03 00:36:44159 std::unique_ptr<ResponseCallbackWrapper>>
160 ResponseCallbackWrapperMap;
161 ResponseCallbackWrapperMap response_callback_wrappers_;
lazyboyee4adef2016-05-24 00:55:16162
David Bertoniac5892eb2020-01-03 00:36:44163 using WorkerResponseCallbackWrapperMap =
lazyboyee4adef2016-05-24 00:55:16164 std::map<WorkerResponseCallbackMapKey,
David Bertoniac5892eb2020-01-03 00:36:44165 std::unique_ptr<WorkerResponseCallbackWrapper>>;
lazyboyee4adef2016-05-24 00:55:16166 // TODO(lazyboy): The map entries are cleared upon RenderProcessHost shutown,
167 // we should really be clearing it on service worker shutdown.
David Bertoniac5892eb2020-01-03 00:36:44168 WorkerResponseCallbackWrapperMap response_callback_wrappers_for_worker_;
[email protected]703e807a2009-03-28 19:56:51169};
170
[email protected]1a0436892014-04-01 00:38:25171} // namespace extensions
172
[email protected]0b9de032014-03-15 05:47:01173#endif // EXTENSIONS_BROWSER_EXTENSION_FUNCTION_DISPATCHER_H_