Avi Drissman | 60039d4 | 2022-09-13 21:49:05 | [diff] [blame] | 1 | // Copyright 2014 The Chromium Authors |
[email protected] | 3fd3cf7 | 2012-05-14 05:51:56 | [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 | |
limasdf | d70dc5ae | 2014-09-13 00:02:22 | [diff] [blame] | 5 | #ifndef EXTENSIONS_BROWSER_SCRIPT_EXECUTOR_H_ |
| 6 | #define EXTENSIONS_BROWSER_SCRIPT_EXECUTOR_H_ |
[email protected] | 3fd3cf7 | 2012-05-14 05:51:56 | [diff] [blame] | 7 | |
Trent Apted | 8f733b9 | 2018-10-04 00:54:45 | [diff] [blame] | 8 | #include <map> |
| 9 | #include <set> |
| 10 | #include <string> |
Devlin Cronin | 5331a45e | 2020-11-18 21:04:32 | [diff] [blame] | 11 | #include <vector> |
Trent Apted | 8f733b9 | 2018-10-04 00:54:45 | [diff] [blame] | 12 | |
| 13 | #include "base/callback.h" |
Keishi Hattori | 0e45c02 | 2021-11-27 09:25:52 | [diff] [blame] | 14 | #include "base/memory/raw_ptr.h" |
Lei Zhang | 7c1d96f | 2021-04-30 09:04:36 | [diff] [blame] | 15 | #include "base/values.h" |
Dave Tapuska | 753dd65 | 2022-03-17 20:16:04 | [diff] [blame] | 16 | #include "extensions/browser/extension_api_frame_id_map.h" |
Manish Jethani | 9494d72 | 2018-01-20 00:28:47 | [diff] [blame] | 17 | #include "extensions/common/constants.h" |
Devlin Cronin | 5c3c9d9 | 2021-06-14 20:51:00 | [diff] [blame] | 18 | #include "extensions/common/mojom/code_injection.mojom.h" |
Julie Jeongeun Kim | 0d0ac49 | 2021-03-04 01:43:22 | [diff] [blame] | 19 | #include "extensions/common/mojom/css_origin.mojom-shared.h" |
Julie Jeongeun Kim | 30f6463 | 2021-03-10 01:10:02 | [diff] [blame] | 20 | #include "extensions/common/mojom/host_id.mojom-forward.h" |
Julie Jeongeun Kim | 378db14d | 2021-03-05 01:53:00 | [diff] [blame] | 21 | #include "extensions/common/mojom/run_location.mojom-shared.h" |
[email protected] | 49d9b14 | 2013-07-19 08:50:27 | [diff] [blame] | 22 | #include "extensions/common/user_script.h" |
[email protected] | 3fd3cf7 | 2012-05-14 05:51:56 | [diff] [blame] | 23 | |
[email protected] | 7f3b91e | 2012-08-07 08:05:03 | [diff] [blame] | 24 | class GURL; |
| 25 | |
[email protected] | 3fd3cf7 | 2012-05-14 05:51:56 | [diff] [blame] | 26 | namespace content { |
| 27 | class WebContents; |
| 28 | } |
| 29 | |
| 30 | namespace extensions { |
Trent Apted | 8f733b9 | 2018-10-04 00:54:45 | [diff] [blame] | 31 | |
| 32 | // Contains all extensions that are executing scripts, mapped to the paths for |
| 33 | // those scripts. The paths may be an empty set if the script has no path |
| 34 | // associated with it (e.g. in the case of tabs.executeScript), but there will |
| 35 | // still be an entry for the extension. |
| 36 | using ExecutingScriptsMap = std::map<std::string, std::set<std::string>>; |
| 37 | |
| 38 | // Callback that ScriptExecutor uses to notify when content scripts and/or |
| 39 | // tabs.executeScript calls run on a page. |
| 40 | using ScriptsExecutedNotification = base::RepeatingCallback< |
Lucas Furukawa Gadani | e1c5dfda | 2018-11-29 17:57:41 | [diff] [blame] | 41 | void(content::WebContents*, const ExecutingScriptsMap&, const GURL&)>; |
[email protected] | 3fd3cf7 | 2012-05-14 05:51:56 | [diff] [blame] | 42 | |
| 43 | // Interface for executing extension content scripts (e.g. executeScript) as |
Julie Jeongeun Kim | 04fb7624 | 2021-03-11 04:16:27 | [diff] [blame] | 44 | // described by the mojom::ExecuteCodeParams IPC, and notifying the |
Julie Jeongeun Kim | 1a604ad | 2021-03-18 10:27:28 | [diff] [blame] | 45 | // caller when responded with ExecuteCodeCallback. |
[email protected] | 3fd3cf7 | 2012-05-14 05:51:56 | [diff] [blame] | 46 | class ScriptExecutor { |
| 47 | public: |
Trent Apted | 8f733b9 | 2018-10-04 00:54:45 | [diff] [blame] | 48 | explicit ScriptExecutor(content::WebContents* web_contents); |
Peter Boström | 951cf77e | 2021-09-22 00:02:59 | [diff] [blame] | 49 | |
| 50 | ScriptExecutor(const ScriptExecutor&) = delete; |
| 51 | ScriptExecutor& operator=(const ScriptExecutor&) = delete; |
| 52 | |
[email protected] | af78a80 | 2012-07-10 23:47:02 | [diff] [blame] | 53 | ~ScriptExecutor(); |
[email protected] | 3fd3cf7 | 2012-05-14 05:51:56 | [diff] [blame] | 54 | |
[email protected] | 3fd3cf7 | 2012-05-14 05:51:56 | [diff] [blame] | 55 | // The scope of the script injection across the frames. |
| 56 | enum FrameScope { |
Devlin Cronin | 5331a45e | 2020-11-18 21:04:32 | [diff] [blame] | 57 | SPECIFIED_FRAMES, |
rob | 52277c8 | 2016-02-07 17:28:57 | [diff] [blame] | 58 | INCLUDE_SUB_FRAMES, |
[email protected] | 3fd3cf7 | 2012-05-14 05:51:56 | [diff] [blame] | 59 | }; |
| 60 | |
[email protected] | ae26b28 | 2014-05-15 16:40:16 | [diff] [blame] | 61 | // Whether to insert the script in about: frames when its origin matches |
| 62 | // the extension's host permissions. |
| 63 | enum MatchAboutBlank { |
| 64 | DONT_MATCH_ABOUT_BLANK, |
| 65 | MATCH_ABOUT_BLANK, |
| 66 | }; |
| 67 | |
[email protected] | 88c6f5c | 2013-08-28 04:08:41 | [diff] [blame] | 68 | // The type of process the target is. |
| 69 | enum ProcessType { |
| 70 | DEFAULT_PROCESS, |
| 71 | WEB_VIEW_PROCESS, |
| 72 | }; |
| 73 | |
Devlin Cronin | 7fdd38c | 2021-01-27 03:01:49 | [diff] [blame] | 74 | struct FrameResult { |
| 75 | FrameResult(); |
| 76 | FrameResult(FrameResult&&); |
| 77 | FrameResult& operator=(FrameResult&&); |
| 78 | |
Takashi Toyoshima | ec7d45e | 2022-07-15 06:02:02 | [diff] [blame] | 79 | // The ID of the frame of the injection. This is not consistent while |
| 80 | // executing content script, and the value represents the one that was set |
| 81 | // at the script injection was triggered. |
Devlin Cronin | 7fdd38c | 2021-01-27 03:01:49 | [diff] [blame] | 82 | int frame_id = -1; |
Takashi Toyoshima | ec7d45e | 2022-07-15 06:02:02 | [diff] [blame] | 83 | // The document ID of the frame of the injection. This can be stale if the |
| 84 | // frame navigates and another document is created for the frame. |
Dave Tapuska | 753dd65 | 2022-03-17 20:16:04 | [diff] [blame] | 85 | ExtensionApiFrameIdMap::DocumentId document_id; |
Devlin Cronin | 7fdd38c | 2021-01-27 03:01:49 | [diff] [blame] | 86 | // The error associated with the injection, if any. Empty if the injection |
| 87 | // succeeded. |
| 88 | std::string error; |
| 89 | // The URL of the frame from the injection. Only set if the frame exists. |
| 90 | GURL url; |
| 91 | // The result value from the injection, or null if the injection failed (or |
| 92 | // had no result). |
| 93 | base::Value value; |
| 94 | // Whether the frame responded to the attempted injection (which can fail if |
| 95 | // the frame was removed or never existed). Note this doesn't necessarily |
| 96 | // mean the injection succeeded, since it could fail due to other reasons |
| 97 | // (like permissions). |
| 98 | bool frame_responded = false; |
| 99 | }; |
| 100 | |
| 101 | using ScriptFinishedCallback = |
| 102 | base::OnceCallback<void(std::vector<FrameResult> frame_results)>; |
[email protected] | 3fd3cf7 | 2012-05-14 05:51:56 | [diff] [blame] | 103 | |
Devlin Cronin | 5c3c9d9 | 2021-06-14 20:51:00 | [diff] [blame] | 104 | // Generates an injection key based on the host ID and either the file URL, if |
| 105 | // available, or the code string. The format of the key is |
| 106 | // "<type><host_id><digest>", where <type> is one of "F" (file) and "C" |
| 107 | // (code), <host_id> is the host ID, and <digest> is an unspecified hash |
| 108 | // digest of the file URL or the code string, respectively. |
| 109 | static std::string GenerateInjectionKey(const mojom::HostID& host_id, |
| 110 | const GURL& script_url, |
| 111 | const std::string& code); |
| 112 | |
Julie Jeongeun Kim | 04fb7624 | 2021-03-11 04:16:27 | [diff] [blame] | 113 | // Executes a script. The arguments match mojom::ExecuteCodeParams in |
| 114 | // frame.mojom (request_id is populated automatically). |
[email protected] | 3fd3cf7 | 2012-05-14 05:51:56 | [diff] [blame] | 115 | // |
Devlin Cronin | 5331a45e | 2020-11-18 21:04:32 | [diff] [blame] | 116 | // The script will be executed in the frames identified by |frame_ids| (which |
| 117 | // are extension API frame IDs). If |frame_scope| is INCLUDE_SUB_FRAMES, |
| 118 | // then the script will also be executed in all descendants of the specified |
| 119 | // frames. |
rob | 52277c8 | 2016-02-07 17:28:57 | [diff] [blame] | 120 | // |
[email protected] | 3fd3cf7 | 2012-05-14 05:51:56 | [diff] [blame] | 121 | // |callback| will always be called even if the IPC'd renderer is destroyed |
| 122 | // before a response is received (in this case the callback will be with a |
| 123 | // failure and appropriate error message). |
Julie Jeongeun Kim | 30f6463 | 2021-03-10 01:10:02 | [diff] [blame] | 124 | void ExecuteScript(const mojom::HostID& host_id, |
Devlin Cronin | 5c3c9d9 | 2021-06-14 20:51:00 | [diff] [blame] | 125 | mojom::CodeInjectionPtr injection, |
[email protected] | af78a80 | 2012-07-10 23:47:02 | [diff] [blame] | 126 | FrameScope frame_scope, |
Devlin Cronin | c84d0e5 | 2021-03-23 01:16:15 | [diff] [blame] | 127 | const std::set<int>& frame_ids, |
[email protected] | ae26b28 | 2014-05-15 16:40:16 | [diff] [blame] | 128 | MatchAboutBlank match_about_blank, |
Julie Jeongeun Kim | 378db14d | 2021-03-05 01:53:00 | [diff] [blame] | 129 | mojom::RunLocation run_at, |
[email protected] | 88c6f5c | 2013-08-28 04:08:41 | [diff] [blame] | 130 | ProcessType process_type, |
[email protected] | 6f451a4 | 2014-04-10 17:12:47 | [diff] [blame] | 131 | const GURL& webview_src, |
Istiaque Ahmed | e643f56 | 2020-04-18 09:56:39 | [diff] [blame] | 132 | ScriptFinishedCallback callback); |
Trent Apted | 8f733b9 | 2018-10-04 00:54:45 | [diff] [blame] | 133 | |
| 134 | // Set the observer for ScriptsExecutedNotification callbacks. |
| 135 | void set_observer(ScriptsExecutedNotification observer) { |
| 136 | observer_ = std::move(observer); |
| 137 | } |
[email protected] | af78a80 | 2012-07-10 23:47:02 | [diff] [blame] | 138 | |
[email protected] | af78a80 | 2012-07-10 23:47:02 | [diff] [blame] | 139 | private: |
Keishi Hattori | 0e45c02 | 2021-11-27 09:25:52 | [diff] [blame] | 140 | raw_ptr<content::WebContents> web_contents_; |
[email protected] | af78a80 | 2012-07-10 23:47:02 | [diff] [blame] | 141 | |
Trent Apted | 8f733b9 | 2018-10-04 00:54:45 | [diff] [blame] | 142 | ScriptsExecutedNotification observer_; |
[email protected] | 3fd3cf7 | 2012-05-14 05:51:56 | [diff] [blame] | 143 | }; |
| 144 | |
| 145 | } // namespace extensions |
| 146 | |
limasdf | d70dc5ae | 2014-09-13 00:02:22 | [diff] [blame] | 147 | #endif // EXTENSIONS_BROWSER_SCRIPT_EXECUTOR_H_ |