Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(394)

Side by Side Diff: extensions/browser/script_executor.cc

Issue 1628423002: Add frameId to chrome.tabs.executeScript/insertCSS (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@permissiondata-remove-process_id
Patch Set: Remove RenderFrameHost::ForEachChildFrame Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "extensions/browser/script_executor.h" 5 #include "extensions/browser/script_executor.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/callback.h" 8 #include "base/callback.h"
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/macros.h" 10 #include "base/macros.h"
11 #include "base/pickle.h" 11 #include "base/pickle.h"
12 #include "content/public/browser/render_frame_host.h" 12 #include "content/public/browser/render_frame_host.h"
13 #include "content/public/browser/render_view_host.h" 13 #include "content/public/browser/render_view_host.h"
14 #include "content/public/browser/web_contents.h" 14 #include "content/public/browser/web_contents.h"
15 #include "content/public/browser/web_contents_observer.h" 15 #include "content/public/browser/web_contents_observer.h"
16 #include "extensions/browser/extension_api_frame_id_map.h"
16 #include "extensions/browser/extension_registry.h" 17 #include "extensions/browser/extension_registry.h"
17 #include "extensions/browser/script_execution_observer.h" 18 #include "extensions/browser/script_execution_observer.h"
18 #include "extensions/common/extension_messages.h" 19 #include "extensions/common/extension_messages.h"
19 #include "ipc/ipc_message.h" 20 #include "ipc/ipc_message.h"
20 #include "ipc/ipc_message_macros.h" 21 #include "ipc/ipc_message_macros.h"
21 22
22 namespace base { 23 namespace base {
23 class ListValue; 24 class ListValue;
24 } // namespace base 25 } // namespace base
25 26
26 namespace extensions { 27 namespace extensions {
27 28
28 namespace { 29 namespace {
29 30
30 const char* kRendererDestroyed = "The tab was closed."; 31 const char* kRendererDestroyed = "The tab was closed.";
32 const char* kFrameRemoved = "The frame was removed.";
31 33
32 // A handler for a single injection request. On creation this will send the 34 // A handler for a single injection request. On creation this will send the
33 // injection request to the renderer, and it will be destroyed after either the 35 // injection request to the renderer, and it will be destroyed after either the
34 // corresponding response comes from the renderer, or the renderer is destroyed. 36 // corresponding response comes from the renderer, or the renderer is destroyed.
35 class Handler : public content::WebContentsObserver { 37 class Handler : public content::WebContentsObserver {
36 public: 38 public:
37 Handler(base::ObserverList<ScriptExecutionObserver>* script_observers, 39 Handler(base::ObserverList<ScriptExecutionObserver>* script_observers,
38 content::WebContents* web_contents, 40 content::WebContents* web_contents,
39 const ExtensionMsg_ExecuteCode_Params& params, 41 const ExtensionMsg_ExecuteCode_Params& params,
40 ScriptExecutor::FrameScope scope, 42 ScriptExecutor::FrameScope scope,
43 int frame_id,
41 const ScriptExecutor::ExecuteScriptCallback& callback) 44 const ScriptExecutor::ExecuteScriptCallback& callback)
42 : content::WebContentsObserver(web_contents), 45 : content::WebContentsObserver(web_contents),
43 script_observers_(AsWeakPtr(script_observers)), 46 script_observers_(AsWeakPtr(script_observers)),
44 host_id_(params.host_id), 47 host_id_(params.host_id),
45 request_id_(params.request_id), 48 request_id_(params.request_id),
49 include_sub_frames_(scope == ScriptExecutor::INCLUDE_SUB_FRAMES),
50 root_rfh_(ExtensionApiFrameIdMap::GetRenderFrameHostById(web_contents,
51 frame_id)),
52 root_is_main_frame_(root_rfh_ ? !root_rfh_->GetParent() : false),
46 callback_(callback) { 53 callback_(callback) {
47 if (scope == ScriptExecutor::ALL_FRAMES) { 54 if (root_rfh_) {
48 web_contents->ForEachFrame(base::Bind(&Handler::SendExecuteCode, 55 if (include_sub_frames_) {
49 base::Unretained(this), params)); 56 web_contents->ForEachFrame(base::Bind(&Handler::SendExecuteCode,
50 } else { 57 base::Unretained(this), params));
51 SendExecuteCode(params, web_contents->GetMainFrame()); 58 } else {
59 SendExecuteCode(params, root_rfh_);
60 }
52 } 61 }
62
63 if (pending_render_frames_.empty())
64 Finish();
53 } 65 }
54 66
55 private: 67 private:
56 // This class manages its own lifetime. 68 // This class manages its own lifetime.
57 ~Handler() override {} 69 ~Handler() override {}
58 70
59 // content::WebContentsObserver: 71 // content::WebContentsObserver:
60 void WebContentsDestroyed() override { Finish(); } 72 void WebContentsDestroyed() override { Finish(); }
61 73
62 bool OnMessageReceived(const IPC::Message& message, 74 bool OnMessageReceived(const IPC::Message& message,
(...skipping 22 matching lines...) Expand all
85 if (pending_render_frames_.erase(render_frame_host) == 1 && 97 if (pending_render_frames_.erase(render_frame_host) == 1 &&
86 pending_render_frames_.empty()) { 98 pending_render_frames_.empty()) {
87 Finish(); 99 Finish();
88 } 100 }
89 } 101 }
90 102
91 // Sends an ExecuteCode message to the given frame host, and increments 103 // Sends an ExecuteCode message to the given frame host, and increments
92 // the number of pending messages. 104 // the number of pending messages.
93 void SendExecuteCode(const ExtensionMsg_ExecuteCode_Params& params, 105 void SendExecuteCode(const ExtensionMsg_ExecuteCode_Params& params,
94 content::RenderFrameHost* frame) { 106 content::RenderFrameHost* frame) {
107 if (!frame->IsRenderFrameLive())
108 return;
109 if (root_is_main_frame_)
110 DCHECK(ShouldIncludeFrame(frame));
Devlin 2016/02/01 19:04:07 Ah, DCHECKS. So, I get worried when we have if st
robwu 2016/02/01 23:17:44 The current construct is an optimization. In most
Devlin 2016/02/01 23:28:13 I don't think the performance is all that signific
robwu 2016/02/02 15:28:18 Done. It's not a bottleneck, but all small bits ad
111 else if (!ShouldIncludeFrame(frame))
112 return;
95 pending_render_frames_.insert(frame); 113 pending_render_frames_.insert(frame);
96 frame->Send(new ExtensionMsg_ExecuteCode(frame->GetRoutingID(), params)); 114 frame->Send(new ExtensionMsg_ExecuteCode(frame->GetRoutingID(), params));
97 } 115 }
98 116
117 // Returns whether a frame is the root frame or a descendant of it.
118 bool ShouldIncludeFrame(content::RenderFrameHost* frame) {
119 while (frame) {
120 if (frame == root_rfh_)
121 return true;
122 frame = frame->GetParent();
123 }
124 return false;
125 }
126
99 // Handles the ExecuteCodeFinished message. 127 // Handles the ExecuteCodeFinished message.
100 void OnExecuteCodeFinished(content::RenderFrameHost* render_frame_host, 128 void OnExecuteCodeFinished(content::RenderFrameHost* render_frame_host,
101 int request_id, 129 int request_id,
102 const std::string& error, 130 const std::string& error,
103 const GURL& on_url, 131 const GURL& on_url,
104 const base::ListValue& result_list) { 132 const base::ListValue& result_list) {
105 DCHECK_EQ(request_id_, request_id); 133 DCHECK_EQ(request_id_, request_id);
106 DCHECK(!pending_render_frames_.empty()); 134 DCHECK(!pending_render_frames_.empty());
107 bool erased = pending_render_frames_.erase(render_frame_host) == 1; 135 bool erased = pending_render_frames_.erase(render_frame_host) == 1;
108 DCHECK(erased); 136 DCHECK(erased);
109 bool is_main_frame = web_contents()->GetMainFrame() == render_frame_host; 137 bool is_root_frame = root_rfh_ == render_frame_host;
110 138
111 // Set the result, if there is one. 139 // Set the result, if there is one.
112 const base::Value* script_value = nullptr; 140 const base::Value* script_value = nullptr;
113 if (result_list.Get(0u, &script_value)) { 141 if (result_list.Get(0u, &script_value)) {
114 // If this is the main result, we put it at index 0. Otherwise, we just 142 // If this is the main result, we put it at index 0. Otherwise, we just
115 // append it at the end. 143 // append it at the end.
116 if (is_main_frame && !results_.empty()) 144 if (is_root_frame && !results_.empty())
117 CHECK(results_.Insert(0u, script_value->DeepCopy())); 145 CHECK(results_.Insert(0u, script_value->DeepCopy()));
118 else 146 else
119 results_.Append(script_value->DeepCopy()); 147 results_.Append(script_value->DeepCopy());
120 } 148 }
121 149
122 if (is_main_frame) { // Only use the main frame's error and url. 150 if (is_root_frame) { // Only use the root frame's error and url.
123 main_frame_error_ = error; 151 root_frame_error_ = error;
124 main_frame_url_ = on_url; 152 root_frame_url_ = on_url;
125 } 153 }
126 154
127 // Wait until the final request finishes before reporting back. 155 // Wait until the final request finishes before reporting back.
128 if (pending_render_frames_.empty()) 156 if (pending_render_frames_.empty())
129 Finish(); 157 Finish();
130 } 158 }
131 159
132 void Finish() { 160 void Finish() {
133 if (main_frame_url_.is_empty()) { 161 if (root_frame_url_.is_empty()) {
134 // We never finished the main frame injection. 162 // We never finished the root frame injection.
135 main_frame_error_ = kRendererDestroyed; 163 root_frame_error_ =
164 root_is_main_frame_ ? kRendererDestroyed : kFrameRemoved;
136 results_.Clear(); 165 results_.Clear();
137 } 166 }
138 167
139 if (script_observers_.get() && main_frame_error_.empty() && 168 if (script_observers_.get() && root_frame_error_.empty() &&
140 host_id_.type() == HostID::EXTENSIONS) { 169 host_id_.type() == HostID::EXTENSIONS) {
141 ScriptExecutionObserver::ExecutingScriptsMap id_map; 170 ScriptExecutionObserver::ExecutingScriptsMap id_map;
142 id_map[host_id_.id()] = std::set<std::string>(); 171 id_map[host_id_.id()] = std::set<std::string>();
143 FOR_EACH_OBSERVER( 172 FOR_EACH_OBSERVER(
144 ScriptExecutionObserver, *script_observers_, 173 ScriptExecutionObserver, *script_observers_,
145 OnScriptsExecuted(web_contents(), id_map, main_frame_url_)); 174 OnScriptsExecuted(web_contents(), id_map, root_frame_url_));
146 } 175 }
147 176
148 if (!callback_.is_null()) 177 if (!callback_.is_null())
149 callback_.Run(main_frame_error_, main_frame_url_, results_); 178 callback_.Run(root_frame_error_, root_frame_url_, results_);
150 delete this; 179 delete this;
151 } 180 }
152 181
153 base::WeakPtr<base::ObserverList<ScriptExecutionObserver>> script_observers_; 182 base::WeakPtr<base::ObserverList<ScriptExecutionObserver>> script_observers_;
154 183
155 // The id of the host (the extension or the webui) doing the injection. 184 // The id of the host (the extension or the webui) doing the injection.
156 HostID host_id_; 185 HostID host_id_;
157 186
158 // The request id of the injection. 187 // The request id of the injection.
159 int request_id_; 188 int request_id_;
160 189
190 // Whether to inject in |root_rfh_| and all of its descendant frames.
191 bool include_sub_frames_;
192
193 // The frame (and optionally its descendant frames) where the injection will
194 // occur.
195 content::RenderFrameHost* root_rfh_;
196
197 // Whether |root_rfh_| is the main frame of a tab.
198 bool root_is_main_frame_;
199
161 // The hosts of the still-running injections. 200 // The hosts of the still-running injections.
162 std::set<content::RenderFrameHost*> pending_render_frames_; 201 std::set<content::RenderFrameHost*> pending_render_frames_;
163 202
164 // The results of the injection. 203 // The results of the injection.
165 base::ListValue results_; 204 base::ListValue results_;
166 205
167 // The error from injecting into the main frame. 206 // The error from injecting into the root frame.
168 std::string main_frame_error_; 207 std::string root_frame_error_;
169 208
170 // The url of the main frame. 209 // The url of the root frame.
171 GURL main_frame_url_; 210 GURL root_frame_url_;
172 211
173 // The callback to run after all injections complete. 212 // The callback to run after all injections complete.
174 ScriptExecutor::ExecuteScriptCallback callback_; 213 ScriptExecutor::ExecuteScriptCallback callback_;
175 214
176 DISALLOW_COPY_AND_ASSIGN(Handler); 215 DISALLOW_COPY_AND_ASSIGN(Handler);
177 }; 216 };
178 217
179 } // namespace 218 } // namespace
180 219
181 ScriptExecutionObserver::~ScriptExecutionObserver() { 220 ScriptExecutionObserver::~ScriptExecutionObserver() {
182 } 221 }
183 222
184 ScriptExecutor::ScriptExecutor( 223 ScriptExecutor::ScriptExecutor(
185 content::WebContents* web_contents, 224 content::WebContents* web_contents,
186 base::ObserverList<ScriptExecutionObserver>* script_observers) 225 base::ObserverList<ScriptExecutionObserver>* script_observers)
187 : next_request_id_(0), 226 : next_request_id_(0),
188 web_contents_(web_contents), 227 web_contents_(web_contents),
189 script_observers_(script_observers) { 228 script_observers_(script_observers) {
190 CHECK(web_contents_); 229 CHECK(web_contents_);
191 } 230 }
192 231
193 ScriptExecutor::~ScriptExecutor() { 232 ScriptExecutor::~ScriptExecutor() {
194 } 233 }
195 234
196 void ScriptExecutor::ExecuteScript(const HostID& host_id, 235 void ScriptExecutor::ExecuteScript(const HostID& host_id,
197 ScriptExecutor::ScriptType script_type, 236 ScriptExecutor::ScriptType script_type,
198 const std::string& code, 237 const std::string& code,
199 ScriptExecutor::FrameScope frame_scope, 238 ScriptExecutor::FrameScope frame_scope,
239 int frame_id,
200 ScriptExecutor::MatchAboutBlank about_blank, 240 ScriptExecutor::MatchAboutBlank about_blank,
201 UserScript::RunLocation run_at, 241 UserScript::RunLocation run_at,
202 ScriptExecutor::WorldType world_type, 242 ScriptExecutor::WorldType world_type,
203 ScriptExecutor::ProcessType process_type, 243 ScriptExecutor::ProcessType process_type,
204 const GURL& webview_src, 244 const GURL& webview_src,
205 const GURL& file_url, 245 const GURL& file_url,
206 bool user_gesture, 246 bool user_gesture,
207 ScriptExecutor::ResultType result_type, 247 ScriptExecutor::ResultType result_type,
208 const ExecuteScriptCallback& callback) { 248 const ExecuteScriptCallback& callback) {
209 if (host_id.type() == HostID::EXTENSIONS) { 249 if (host_id.type() == HostID::EXTENSIONS) {
(...skipping 15 matching lines...) Expand all
225 params.match_about_blank = (about_blank == MATCH_ABOUT_BLANK); 265 params.match_about_blank = (about_blank == MATCH_ABOUT_BLANK);
226 params.run_at = static_cast<int>(run_at); 266 params.run_at = static_cast<int>(run_at);
227 params.in_main_world = (world_type == MAIN_WORLD); 267 params.in_main_world = (world_type == MAIN_WORLD);
228 params.is_web_view = (process_type == WEB_VIEW_PROCESS); 268 params.is_web_view = (process_type == WEB_VIEW_PROCESS);
229 params.webview_src = webview_src; 269 params.webview_src = webview_src;
230 params.file_url = file_url; 270 params.file_url = file_url;
231 params.wants_result = (result_type == JSON_SERIALIZED_RESULT); 271 params.wants_result = (result_type == JSON_SERIALIZED_RESULT);
232 params.user_gesture = user_gesture; 272 params.user_gesture = user_gesture;
233 273
234 // Handler handles IPCs and deletes itself on completion. 274 // Handler handles IPCs and deletes itself on completion.
235 new Handler(script_observers_, web_contents_, params, frame_scope, callback); 275 new Handler(script_observers_, web_contents_, params, frame_scope, frame_id,
276 callback);
236 } 277 }
237 278
238 } // namespace extensions 279 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698