[email protected] | ac2f8937 | 2014-06-23 21:44:25 | [diff] [blame] | 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 | #include "extensions/renderer/script_injection_manager.h" |
| 6 | |
| 7 | #include "base/bind.h" |
| 8 | #include "base/memory/weak_ptr.h" |
[email protected] | ac2f8937 | 2014-06-23 21:44:25 | [diff] [blame] | 9 | #include "base/values.h" |
| 10 | #include "content/public/renderer/render_view.h" |
| 11 | #include "content/public/renderer/render_view_observer.h" |
| 12 | #include "extensions/common/extension.h" |
| 13 | #include "extensions/common/extension_messages.h" |
| 14 | #include "extensions/common/extension_set.h" |
| 15 | #include "extensions/renderer/extension_helper.h" |
[email protected] | c11e659 | 2014-06-27 17:07:34 | [diff] [blame] | 16 | #include "extensions/renderer/programmatic_script_injector.h" |
| 17 | #include "extensions/renderer/script_injection.h" |
| 18 | #include "extensions/renderer/scripts_run_info.h" |
[email protected] | ac2f8937 | 2014-06-23 21:44:25 | [diff] [blame] | 19 | #include "ipc/ipc_message_macros.h" |
markdittmer | 9ea140f | 2014-08-29 02:46:15 | [diff] [blame] | 20 | #include "third_party/WebKit/public/web/WebDocument.h" |
[email protected] | ac2f8937 | 2014-06-23 21:44:25 | [diff] [blame] | 21 | #include "third_party/WebKit/public/web/WebFrame.h" |
| 22 | #include "third_party/WebKit/public/web/WebLocalFrame.h" |
| 23 | #include "third_party/WebKit/public/web/WebView.h" |
| 24 | #include "url/gurl.h" |
| 25 | |
| 26 | namespace extensions { |
| 27 | |
| 28 | namespace { |
| 29 | |
| 30 | // The length of time to wait after the DOM is complete to try and run user |
| 31 | // scripts. |
| 32 | const int kScriptIdleTimeoutInMs = 200; |
| 33 | |
[email protected] | ac2f8937 | 2014-06-23 21:44:25 | [diff] [blame] | 34 | } // namespace |
| 35 | |
| 36 | class ScriptInjectionManager::RVOHelper : public content::RenderViewObserver { |
| 37 | public: |
| 38 | RVOHelper(content::RenderView* render_view, ScriptInjectionManager* manager); |
dcheng | 9168b2f | 2014-10-21 12:38:24 | [diff] [blame] | 39 | ~RVOHelper() override; |
[email protected] | ac2f8937 | 2014-06-23 21:44:25 | [diff] [blame] | 40 | |
| 41 | private: |
| 42 | // RenderViewObserver implementation. |
dcheng | 9168b2f | 2014-10-21 12:38:24 | [diff] [blame] | 43 | bool OnMessageReceived(const IPC::Message& message) override; |
rob | 5ef11ff | 2014-11-17 23:56:20 | [diff] [blame^] | 44 | void DidCreateNewDocument(blink::WebLocalFrame* frame) override; |
dcheng | 9168b2f | 2014-10-21 12:38:24 | [diff] [blame] | 45 | void DidCreateDocumentElement(blink::WebLocalFrame* frame) override; |
| 46 | void DidFinishDocumentLoad(blink::WebLocalFrame* frame) override; |
| 47 | void DidFinishLoad(blink::WebLocalFrame* frame) override; |
dcheng | 9168b2f | 2014-10-21 12:38:24 | [diff] [blame] | 48 | void FrameDetached(blink::WebFrame* frame) override; |
| 49 | void OnDestruct() override; |
[email protected] | ac2f8937 | 2014-06-23 21:44:25 | [diff] [blame] | 50 | |
| 51 | virtual void OnExecuteCode(const ExtensionMsg_ExecuteCode_Params& params); |
markdittmer | 9ea140f | 2014-08-29 02:46:15 | [diff] [blame] | 52 | virtual void OnExecuteDeclarativeScript(int tab_id, |
| 53 | const ExtensionId& extension_id, |
| 54 | int script_id, |
| 55 | const GURL& url); |
[email protected] | ac2f8937 | 2014-06-23 21:44:25 | [diff] [blame] | 56 | virtual void OnPermitScriptInjection(int64 request_id); |
| 57 | |
| 58 | // Tells the ScriptInjectionManager to run tasks associated with |
| 59 | // document_idle. |
| 60 | void RunIdle(blink::WebFrame* frame); |
| 61 | |
[email protected] | 5672620d | 2014-07-30 10:07:17 | [diff] [blame] | 62 | // Indicate that the given |frame| is no longer valid because it is starting |
| 63 | // a new load or closing. |
| 64 | void InvalidateFrame(blink::WebFrame* frame); |
| 65 | |
| 66 | // The owning ScriptInjectionManager. |
[email protected] | ac2f8937 | 2014-06-23 21:44:25 | [diff] [blame] | 67 | ScriptInjectionManager* manager_; |
[email protected] | 5672620d | 2014-07-30 10:07:17 | [diff] [blame] | 68 | |
| 69 | // The set of frames that we are about to notify for DOCUMENT_IDLE. We keep |
| 70 | // a set of those that are valid, so we don't notify that an invalid frame |
| 71 | // became idle. |
| 72 | std::set<blink::WebFrame*> pending_idle_frames_; |
| 73 | |
[email protected] | ac2f8937 | 2014-06-23 21:44:25 | [diff] [blame] | 74 | base::WeakPtrFactory<RVOHelper> weak_factory_; |
| 75 | }; |
| 76 | |
| 77 | ScriptInjectionManager::RVOHelper::RVOHelper( |
| 78 | content::RenderView* render_view, |
| 79 | ScriptInjectionManager* manager) |
| 80 | : content::RenderViewObserver(render_view), |
| 81 | manager_(manager), |
| 82 | weak_factory_(this) { |
| 83 | } |
| 84 | |
| 85 | ScriptInjectionManager::RVOHelper::~RVOHelper() { |
| 86 | } |
| 87 | |
| 88 | bool ScriptInjectionManager::RVOHelper::OnMessageReceived( |
| 89 | const IPC::Message& message) { |
| 90 | bool handled = true; |
| 91 | IPC_BEGIN_MESSAGE_MAP(ScriptInjectionManager::RVOHelper, message) |
| 92 | IPC_MESSAGE_HANDLER(ExtensionMsg_ExecuteCode, OnExecuteCode) |
| 93 | IPC_MESSAGE_HANDLER(ExtensionMsg_PermitScriptInjection, |
| 94 | OnPermitScriptInjection) |
markdittmer | 9ea140f | 2014-08-29 02:46:15 | [diff] [blame] | 95 | IPC_MESSAGE_HANDLER(ExtensionMsg_ExecuteDeclarativeScript, |
| 96 | OnExecuteDeclarativeScript) |
[email protected] | ac2f8937 | 2014-06-23 21:44:25 | [diff] [blame] | 97 | IPC_MESSAGE_UNHANDLED(handled = false) |
| 98 | IPC_END_MESSAGE_MAP() |
| 99 | return handled; |
| 100 | } |
| 101 | |
rob | 5ef11ff | 2014-11-17 23:56:20 | [diff] [blame^] | 102 | void ScriptInjectionManager::RVOHelper::DidCreateNewDocument( |
| 103 | blink::WebLocalFrame* frame) { |
| 104 | // A new document is going to be shown, so invalidate the old document state. |
| 105 | // Check that the frame's state is known before invalidating the frame, |
| 106 | // because it is possible that a script injection was scheduled before the |
| 107 | // page was loaded, e.g. by navigating to a javascript: URL before the page |
| 108 | // has loaded. |
| 109 | if (manager_->frame_statuses_.find(frame) != manager_->frame_statuses_.end()) |
| 110 | InvalidateFrame(frame); |
| 111 | } |
| 112 | |
[email protected] | ac2f8937 | 2014-06-23 21:44:25 | [diff] [blame] | 113 | void ScriptInjectionManager::RVOHelper::DidCreateDocumentElement( |
| 114 | blink::WebLocalFrame* frame) { |
| 115 | manager_->InjectScripts(frame, UserScript::DOCUMENT_START); |
| 116 | } |
| 117 | |
| 118 | void ScriptInjectionManager::RVOHelper::DidFinishDocumentLoad( |
| 119 | blink::WebLocalFrame* frame) { |
| 120 | manager_->InjectScripts(frame, UserScript::DOCUMENT_END); |
[email protected] | 5672620d | 2014-07-30 10:07:17 | [diff] [blame] | 121 | pending_idle_frames_.insert(frame); |
| 122 | // We try to run idle in two places: here and DidFinishLoad. |
| 123 | // DidFinishDocumentLoad() corresponds to completing the document's load, |
| 124 | // whereas DidFinishLoad corresponds to completing the document and all |
| 125 | // subresources' load. We don't want to hold up script injection for a |
| 126 | // particularly slow subresource, so we set a delayed task from here - but if |
| 127 | // we finish everything before that point (i.e., DidFinishLoad() is |
| 128 | // triggered), then there's no reason to keep waiting. |
[email protected] | ac2f8937 | 2014-06-23 21:44:25 | [diff] [blame] | 129 | base::MessageLoop::current()->PostDelayedTask( |
| 130 | FROM_HERE, |
| 131 | base::Bind(&ScriptInjectionManager::RVOHelper::RunIdle, |
| 132 | weak_factory_.GetWeakPtr(), |
| 133 | frame), |
| 134 | base::TimeDelta::FromMilliseconds(kScriptIdleTimeoutInMs)); |
| 135 | } |
| 136 | |
| 137 | void ScriptInjectionManager::RVOHelper::DidFinishLoad( |
| 138 | blink::WebLocalFrame* frame) { |
[email protected] | 5672620d | 2014-07-30 10:07:17 | [diff] [blame] | 139 | // Ensure that we don't block any UI progress by running scripts. |
| 140 | // We *don't* add the frame to |pending_idle_frames_| here because |
| 141 | // DidFinishDocumentLoad should strictly come before DidFinishLoad, so the |
| 142 | // first posted task to RunIdle() pops it out of the set. This ensures we |
| 143 | // don't try to run idle twice. |
[email protected] | ac2f8937 | 2014-06-23 21:44:25 | [diff] [blame] | 144 | base::MessageLoop::current()->PostTask( |
| 145 | FROM_HERE, |
| 146 | base::Bind(&ScriptInjectionManager::RVOHelper::RunIdle, |
| 147 | weak_factory_.GetWeakPtr(), |
| 148 | frame)); |
| 149 | } |
| 150 | |
[email protected] | ac2f8937 | 2014-06-23 21:44:25 | [diff] [blame] | 151 | void ScriptInjectionManager::RVOHelper::FrameDetached(blink::WebFrame* frame) { |
[email protected] | 5672620d | 2014-07-30 10:07:17 | [diff] [blame] | 152 | // The frame is closing - invalidate. |
| 153 | InvalidateFrame(frame); |
[email protected] | ac2f8937 | 2014-06-23 21:44:25 | [diff] [blame] | 154 | } |
| 155 | |
| 156 | void ScriptInjectionManager::RVOHelper::OnDestruct() { |
| 157 | manager_->RemoveObserver(this); |
| 158 | } |
| 159 | |
| 160 | void ScriptInjectionManager::RVOHelper::OnExecuteCode( |
| 161 | const ExtensionMsg_ExecuteCode_Params& params) { |
| 162 | manager_->HandleExecuteCode(params, render_view()); |
| 163 | } |
| 164 | |
markdittmer | 9ea140f | 2014-08-29 02:46:15 | [diff] [blame] | 165 | void ScriptInjectionManager::RVOHelper::OnExecuteDeclarativeScript( |
| 166 | int tab_id, |
| 167 | const ExtensionId& extension_id, |
| 168 | int script_id, |
| 169 | const GURL& url) { |
| 170 | blink::WebFrame* main_frame = render_view()->GetWebView()->mainFrame(); |
| 171 | CHECK(main_frame); |
| 172 | |
| 173 | // TODO(markdittmer): This would be cleaner if we compared page_ids instead. |
| 174 | // Begin script injeciton workflow only if the current URL is identical to |
| 175 | // the one that matched declarative conditions in the browser. |
| 176 | if (main_frame->top()->document().url() == url) { |
| 177 | manager_->HandleExecuteDeclarativeScript(main_frame, |
| 178 | tab_id, |
| 179 | extension_id, |
| 180 | script_id, |
| 181 | url); |
| 182 | } |
| 183 | } |
| 184 | |
[email protected] | ac2f8937 | 2014-06-23 21:44:25 | [diff] [blame] | 185 | void ScriptInjectionManager::RVOHelper::OnPermitScriptInjection( |
| 186 | int64 request_id) { |
| 187 | manager_->HandlePermitScriptInjection(request_id); |
| 188 | } |
| 189 | |
| 190 | void ScriptInjectionManager::RVOHelper::RunIdle(blink::WebFrame* frame) { |
[email protected] | 5672620d | 2014-07-30 10:07:17 | [diff] [blame] | 191 | // Only notify the manager if the frame hasn't either been removed or already |
| 192 | // had idle run since the task to RunIdle() was posted. |
| 193 | if (pending_idle_frames_.count(frame) > 0) { |
| 194 | manager_->InjectScripts(frame, UserScript::DOCUMENT_IDLE); |
| 195 | pending_idle_frames_.erase(frame); |
| 196 | } |
| 197 | } |
| 198 | |
| 199 | void ScriptInjectionManager::RVOHelper::InvalidateFrame( |
| 200 | blink::WebFrame* frame) { |
| 201 | pending_idle_frames_.erase(frame); |
| 202 | manager_->InvalidateForFrame(frame); |
[email protected] | ac2f8937 | 2014-06-23 21:44:25 | [diff] [blame] | 203 | } |
| 204 | |
| 205 | ScriptInjectionManager::ScriptInjectionManager( |
| 206 | const ExtensionSet* extensions, |
[email protected] | 4c35690 | 2014-07-30 09:52:02 | [diff] [blame] | 207 | UserScriptSetManager* user_script_set_manager) |
[email protected] | ac2f8937 | 2014-06-23 21:44:25 | [diff] [blame] | 208 | : extensions_(extensions), |
[email protected] | 4c35690 | 2014-07-30 09:52:02 | [diff] [blame] | 209 | user_script_set_manager_(user_script_set_manager), |
| 210 | user_script_set_manager_observer_(this) { |
| 211 | user_script_set_manager_observer_.Add(user_script_set_manager_); |
[email protected] | ac2f8937 | 2014-06-23 21:44:25 | [diff] [blame] | 212 | } |
| 213 | |
| 214 | ScriptInjectionManager::~ScriptInjectionManager() { |
| 215 | } |
| 216 | |
| 217 | void ScriptInjectionManager::OnRenderViewCreated( |
| 218 | content::RenderView* render_view) { |
| 219 | rvo_helpers_.push_back(new RVOHelper(render_view, this)); |
| 220 | } |
| 221 | |
| 222 | void ScriptInjectionManager::OnUserScriptsUpdated( |
| 223 | const std::set<std::string>& changed_extensions, |
| 224 | const std::vector<UserScript*>& scripts) { |
| 225 | for (ScopedVector<ScriptInjection>::iterator iter = |
| 226 | pending_injections_.begin(); |
| 227 | iter != pending_injections_.end();) { |
| 228 | if (changed_extensions.count((*iter)->extension_id()) > 0) |
| 229 | iter = pending_injections_.erase(iter); |
| 230 | else |
| 231 | ++iter; |
| 232 | } |
| 233 | } |
| 234 | |
| 235 | void ScriptInjectionManager::RemoveObserver(RVOHelper* helper) { |
| 236 | for (ScopedVector<RVOHelper>::iterator iter = rvo_helpers_.begin(); |
| 237 | iter != rvo_helpers_.end(); |
| 238 | ++iter) { |
| 239 | if (*iter == helper) { |
| 240 | rvo_helpers_.erase(iter); |
| 241 | break; |
| 242 | } |
| 243 | } |
| 244 | } |
| 245 | |
| 246 | void ScriptInjectionManager::InvalidateForFrame(blink::WebFrame* frame) { |
| 247 | for (ScopedVector<ScriptInjection>::iterator iter = |
| 248 | pending_injections_.begin(); |
| 249 | iter != pending_injections_.end();) { |
| 250 | if ((*iter)->web_frame() == frame) |
| 251 | iter = pending_injections_.erase(iter); |
| 252 | else |
| 253 | ++iter; |
| 254 | } |
| 255 | |
| 256 | frame_statuses_.erase(frame); |
| 257 | } |
| 258 | |
| 259 | void ScriptInjectionManager::InjectScripts( |
| 260 | blink::WebFrame* frame, UserScript::RunLocation run_location) { |
| 261 | FrameStatusMap::iterator iter = frame_statuses_.find(frame); |
[email protected] | 5672620d | 2014-07-30 10:07:17 | [diff] [blame] | 262 | // We also don't execute if we detect that the run location is somehow out of |
| 263 | // order. This can happen if: |
| 264 | // - The first run location reported for the frame isn't DOCUMENT_START, or |
| 265 | // - The run location reported doesn't immediately follow the previous |
| 266 | // reported run location. |
| 267 | // We don't want to run because extensions may have requirements that scripts |
| 268 | // running in an earlier run location have run by the time a later script |
| 269 | // runs. Better to just not run. |
| 270 | if ((iter == frame_statuses_.end() && |
| 271 | run_location != UserScript::DOCUMENT_START) || |
| 272 | (iter != frame_statuses_.end() && run_location - iter->second > 1)) { |
| 273 | // We also invalidate the frame, because the run order of pending injections |
| 274 | // may also be bad. |
| 275 | InvalidateForFrame(frame); |
| 276 | return; |
| 277 | } else if (iter != frame_statuses_.end() && iter->second > run_location) { |
| 278 | // Certain run location signals (like DidCreateDocumentElement) can happen |
| 279 | // multiple times. Ignore the subsequent signals. |
| 280 | return; |
[email protected] | ac2f8937 | 2014-06-23 21:44:25 | [diff] [blame] | 281 | } |
| 282 | |
[email protected] | 5672620d | 2014-07-30 10:07:17 | [diff] [blame] | 283 | // Otherwise, all is right in the world, and we can get on with the |
| 284 | // injections! |
| 285 | |
| 286 | frame_statuses_[frame] = run_location; |
| 287 | |
[email protected] | ac2f8937 | 2014-06-23 21:44:25 | [diff] [blame] | 288 | // Inject any scripts that were waiting for the right run location. |
[email protected] | c11e659 | 2014-06-27 17:07:34 | [diff] [blame] | 289 | ScriptsRunInfo scripts_run_info; |
[email protected] | ac2f8937 | 2014-06-23 21:44:25 | [diff] [blame] | 290 | for (ScopedVector<ScriptInjection>::iterator iter = |
| 291 | pending_injections_.begin(); |
| 292 | iter != pending_injections_.end();) { |
| 293 | if ((*iter)->web_frame() == frame && |
| 294 | (*iter)->TryToInject(run_location, |
| 295 | extensions_->GetByID((*iter)->extension_id()), |
| 296 | &scripts_run_info)) { |
| 297 | iter = pending_injections_.erase(iter); |
| 298 | } else { |
| 299 | ++iter; |
| 300 | } |
| 301 | } |
| 302 | |
| 303 | // Try to inject any user scripts that should run for this location. If they |
| 304 | // don't complete their injection (for example, waiting for a permission |
| 305 | // response) then they will be added to |pending_injections_|. |
| 306 | ScopedVector<ScriptInjection> user_script_injections; |
| 307 | int tab_id = ExtensionHelper::Get(content::RenderView::FromWebView( |
| 308 | frame->top()->view()))->tab_id(); |
[email protected] | 4c35690 | 2014-07-30 09:52:02 | [diff] [blame] | 309 | user_script_set_manager_->GetAllInjections( |
[email protected] | ac2f8937 | 2014-06-23 21:44:25 | [diff] [blame] | 310 | &user_script_injections, frame, tab_id, run_location); |
| 311 | for (ScopedVector<ScriptInjection>::iterator iter = |
| 312 | user_script_injections.begin(); |
| 313 | iter != user_script_injections.end();) { |
| 314 | scoped_ptr<ScriptInjection> injection(*iter); |
| 315 | iter = user_script_injections.weak_erase(iter); |
| 316 | if (!injection->TryToInject(run_location, |
| 317 | extensions_->GetByID(injection->extension_id()), |
| 318 | &scripts_run_info)) { |
| 319 | pending_injections_.push_back(injection.release()); |
| 320 | } |
| 321 | } |
| 322 | |
[email protected] | c11e659 | 2014-06-27 17:07:34 | [diff] [blame] | 323 | scripts_run_info.LogRun(frame, run_location); |
[email protected] | ac2f8937 | 2014-06-23 21:44:25 | [diff] [blame] | 324 | } |
| 325 | |
| 326 | void ScriptInjectionManager::HandleExecuteCode( |
| 327 | const ExtensionMsg_ExecuteCode_Params& params, |
| 328 | content::RenderView* render_view) { |
dcheng | 2e44917 | 2014-09-24 04:30:56 | [diff] [blame] | 329 | // TODO(dcheng): Not sure how this can happen today. In an OOPI world, it |
| 330 | // would indicate a logic error--the browser must direct this request to the |
| 331 | // right renderer process to begin with. |
| 332 | blink::WebLocalFrame* main_frame = |
| 333 | render_view->GetWebView()->mainFrame()->toWebLocalFrame(); |
[email protected] | ac2f8937 | 2014-06-23 21:44:25 | [diff] [blame] | 334 | if (!main_frame) { |
| 335 | render_view->Send( |
| 336 | new ExtensionHostMsg_ExecuteCodeFinished(render_view->GetRoutingID(), |
| 337 | params.request_id, |
| 338 | "No main frame", |
[email protected] | ac2f8937 | 2014-06-23 21:44:25 | [diff] [blame] | 339 | GURL(std::string()), |
| 340 | base::ListValue())); |
| 341 | return; |
| 342 | } |
| 343 | |
[email protected] | c11e659 | 2014-06-27 17:07:34 | [diff] [blame] | 344 | scoped_ptr<ScriptInjection> injection(new ScriptInjection( |
| 345 | scoped_ptr<ScriptInjector>( |
| 346 | new ProgrammaticScriptInjector(params, main_frame)), |
| 347 | main_frame, |
| 348 | params.extension_id, |
| 349 | static_cast<UserScript::RunLocation>(params.run_at), |
| 350 | ExtensionHelper::Get(render_view)->tab_id())); |
[email protected] | ac2f8937 | 2014-06-23 21:44:25 | [diff] [blame] | 351 | |
[email protected] | c11e659 | 2014-06-27 17:07:34 | [diff] [blame] | 352 | ScriptsRunInfo scripts_run_info; |
[email protected] | ac2f8937 | 2014-06-23 21:44:25 | [diff] [blame] | 353 | FrameStatusMap::const_iterator iter = frame_statuses_.find(main_frame); |
| 354 | if (!injection->TryToInject( |
| 355 | iter == frame_statuses_.end() ? UserScript::UNDEFINED : iter->second, |
| 356 | extensions_->GetByID(injection->extension_id()), |
| 357 | &scripts_run_info)) { |
| 358 | pending_injections_.push_back(injection.release()); |
| 359 | } |
| 360 | } |
| 361 | |
markdittmer | 9ea140f | 2014-08-29 02:46:15 | [diff] [blame] | 362 | void ScriptInjectionManager::HandleExecuteDeclarativeScript( |
| 363 | blink::WebFrame* web_frame, |
| 364 | int tab_id, |
| 365 | const ExtensionId& extension_id, |
| 366 | int script_id, |
| 367 | const GURL& url) { |
| 368 | const Extension* extension = extensions_->GetByID(extension_id); |
dcheng | 2e44917 | 2014-09-24 04:30:56 | [diff] [blame] | 369 | // TODO(dcheng): This function signature should really be a WebLocalFrame, |
| 370 | // rather than trying to coerce it here. |
markdittmer | 9ea140f | 2014-08-29 02:46:15 | [diff] [blame] | 371 | scoped_ptr<ScriptInjection> injection = |
| 372 | user_script_set_manager_->GetInjectionForDeclarativeScript( |
| 373 | script_id, |
dcheng | 2e44917 | 2014-09-24 04:30:56 | [diff] [blame] | 374 | web_frame->toWebLocalFrame(), |
markdittmer | 9ea140f | 2014-08-29 02:46:15 | [diff] [blame] | 375 | tab_id, |
| 376 | url, |
| 377 | extension); |
| 378 | if (injection.get()) { |
| 379 | ScriptsRunInfo scripts_run_info; |
| 380 | // TODO(markdittmer): Use return value of TryToInject for error handling. |
| 381 | injection->TryToInject(UserScript::BROWSER_DRIVEN, |
| 382 | extension, |
| 383 | &scripts_run_info); |
| 384 | scripts_run_info.LogRun(web_frame, UserScript::BROWSER_DRIVEN); |
| 385 | } |
| 386 | } |
| 387 | |
[email protected] | d205600 | 2014-07-03 06:18:06 | [diff] [blame] | 388 | void ScriptInjectionManager::HandlePermitScriptInjection(int64 request_id) { |
[email protected] | ac2f8937 | 2014-06-23 21:44:25 | [diff] [blame] | 389 | ScopedVector<ScriptInjection>::iterator iter = |
| 390 | pending_injections_.begin(); |
| 391 | for (; iter != pending_injections_.end(); ++iter) { |
| 392 | if ((*iter)->request_id() == request_id) |
| 393 | break; |
| 394 | } |
| 395 | if (iter == pending_injections_.end()) |
| 396 | return; |
| 397 | |
[email protected] | d205600 | 2014-07-03 06:18:06 | [diff] [blame] | 398 | // At this point, because the request is present in pending_injections_, we |
| 399 | // know that this is the same page that issued the request (otherwise, |
| 400 | // RVOHelper's DidStartProvisionalLoad callback would have caused it to be |
| 401 | // cleared out). |
| 402 | |
[email protected] | ac2f8937 | 2014-06-23 21:44:25 | [diff] [blame] | 403 | scoped_ptr<ScriptInjection> injection(*iter); |
| 404 | pending_injections_.weak_erase(iter); |
| 405 | |
[email protected] | c11e659 | 2014-06-27 17:07:34 | [diff] [blame] | 406 | ScriptsRunInfo scripts_run_info; |
[email protected] | ac2f8937 | 2014-06-23 21:44:25 | [diff] [blame] | 407 | if (injection->OnPermissionGranted(extensions_->GetByID( |
| 408 | injection->extension_id()), |
| 409 | &scripts_run_info)) { |
[email protected] | c11e659 | 2014-06-27 17:07:34 | [diff] [blame] | 410 | scripts_run_info.LogRun(injection->web_frame(), UserScript::RUN_DEFERRED); |
[email protected] | ac2f8937 | 2014-06-23 21:44:25 | [diff] [blame] | 411 | } |
| 412 | } |
| 413 | |
| 414 | } // namespace extensions |