Add some instrumentation for jank in URLRequest::Start.
[chromium-blink-merge.git] / extensions / renderer / programmatic_script_injector.cc
blobf13fa654b7b09556e0c4f99c7d27176cc8250314
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.
5 #include "extensions/renderer/programmatic_script_injector.h"
7 #include <vector>
9 #include "base/values.h"
10 #include "content/public/common/url_constants.h"
11 #include "content/public/renderer/render_view.h"
12 #include "extensions/common/error_utils.h"
13 #include "extensions/common/extension_messages.h"
14 #include "extensions/common/manifest_constants.h"
15 #include "extensions/common/permissions/permissions_data.h"
16 #include "extensions/renderer/injection_host.h"
17 #include "extensions/renderer/script_context.h"
18 #include "third_party/WebKit/public/platform/WebString.h"
19 #include "third_party/WebKit/public/web/WebDocument.h"
20 #include "third_party/WebKit/public/web/WebFrame.h"
21 #include "third_party/WebKit/public/web/WebScriptSource.h"
23 namespace extensions {
25 ProgrammaticScriptInjector::ProgrammaticScriptInjector(
26 const ExtensionMsg_ExecuteCode_Params& params,
27 blink::WebFrame* web_frame)
28 : params_(new ExtensionMsg_ExecuteCode_Params(params)),
29 url_(ScriptContext::GetDataSourceURLForFrame(web_frame)),
30 render_view_(content::RenderView::FromWebView(web_frame->view())),
31 results_(new base::ListValue()),
32 finished_(false) {
33 effective_url_ = ScriptContext::GetEffectiveDocumentURL(
34 web_frame, url_, params.match_about_blank);
37 ProgrammaticScriptInjector::~ProgrammaticScriptInjector() {
40 UserScript::InjectionType ProgrammaticScriptInjector::script_type()
41 const {
42 return UserScript::PROGRAMMATIC_SCRIPT;
45 bool ProgrammaticScriptInjector::ShouldExecuteInChildFrames() const {
46 return params_->all_frames;
49 bool ProgrammaticScriptInjector::ShouldExecuteInMainWorld() const {
50 return params_->in_main_world;
53 bool ProgrammaticScriptInjector::IsUserGesture() const {
54 return params_->user_gesture;
57 bool ProgrammaticScriptInjector::ExpectsResults() const {
58 return params_->wants_result;
61 bool ProgrammaticScriptInjector::ShouldInjectJs(
62 UserScript::RunLocation run_location) const {
63 return GetRunLocation() == run_location && params_->is_javascript;
66 bool ProgrammaticScriptInjector::ShouldInjectCss(
67 UserScript::RunLocation run_location) const {
68 return GetRunLocation() == run_location && !params_->is_javascript;
71 PermissionsData::AccessType ProgrammaticScriptInjector::CanExecuteOnFrame(
72 const InjectionHost* injection_host,
73 blink::WebFrame* frame,
74 int tab_id,
75 const GURL& top_url) const {
76 // It doesn't make sense to inject a script into a remote frame or a frame
77 // with a null document.
78 if (frame->isWebRemoteFrame() || frame->document().isNull())
79 return PermissionsData::ACCESS_DENIED;
80 GURL effective_document_url = ScriptContext::GetEffectiveDocumentURL(
81 frame, frame->document().url(), params_->match_about_blank);
82 if (params_->is_web_view) {
83 if (frame->parent()) {
84 // This is a subframe inside <webview>, so allow it.
85 return PermissionsData::ACCESS_ALLOWED;
88 return effective_document_url == params_->webview_src
89 ? PermissionsData::ACCESS_ALLOWED
90 : PermissionsData::ACCESS_DENIED;
92 DCHECK_EQ(injection_host->id().type(), HostID::EXTENSIONS);
94 return injection_host->CanExecuteOnFrame(
95 effective_document_url, top_url, tab_id, true /* is_declarative */);
98 std::vector<blink::WebScriptSource> ProgrammaticScriptInjector::GetJsSources(
99 UserScript::RunLocation run_location) const {
100 DCHECK_EQ(GetRunLocation(), run_location);
101 DCHECK(params_->is_javascript);
103 return std::vector<blink::WebScriptSource>(
105 blink::WebScriptSource(
106 blink::WebString::fromUTF8(params_->code), params_->file_url));
109 std::vector<std::string> ProgrammaticScriptInjector::GetCssSources(
110 UserScript::RunLocation run_location) const {
111 DCHECK_EQ(GetRunLocation(), run_location);
112 DCHECK(!params_->is_javascript);
114 return std::vector<std::string>(1, params_->code);
117 void ProgrammaticScriptInjector::GetRunInfo(
118 ScriptsRunInfo* scripts_run_info,
119 UserScript::RunLocation run_location) const {
122 void ProgrammaticScriptInjector::OnInjectionComplete(
123 scoped_ptr<base::ListValue> execution_results,
124 UserScript::RunLocation run_location) {
125 results_ = execution_results.Pass();
126 Finish(std::string());
129 void ProgrammaticScriptInjector::OnWillNotInject(InjectFailureReason reason) {
130 std::string error;
131 switch (reason) {
132 case NOT_ALLOWED:
133 if (url_.SchemeIs(url::kAboutScheme)) {
134 error = ErrorUtils::FormatErrorMessage(
135 manifest_errors::kCannotAccessAboutUrl, url_.spec(),
136 effective_url_.GetOrigin().spec());
137 } else {
138 error = ErrorUtils::FormatErrorMessage(
139 manifest_errors::kCannotAccessPage, url_.spec());
141 break;
142 case EXTENSION_REMOVED: // no special error here.
143 case WONT_INJECT:
144 break;
146 Finish(error);
149 UserScript::RunLocation ProgrammaticScriptInjector::GetRunLocation() const {
150 return static_cast<UserScript::RunLocation>(params_->run_at);
153 void ProgrammaticScriptInjector::Finish(const std::string& error) {
154 DCHECK(!finished_);
155 finished_ = true;
157 render_view_->Send(new ExtensionHostMsg_ExecuteCodeFinished(
158 render_view_->GetRoutingID(),
159 params_->request_id,
160 error,
161 url_,
162 *results_));
165 } // namespace extensions