• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/programmatic_script_injector.h"
6 
7 #include <vector>
8 
9 #include "base/values.h"
10 #include "content/public/renderer/render_view.h"
11 #include "extensions/common/error_utils.h"
12 #include "extensions/common/extension.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/script_context.h"
17 #include "third_party/WebKit/public/platform/WebString.h"
18 #include "third_party/WebKit/public/web/WebDocument.h"
19 #include "third_party/WebKit/public/web/WebFrame.h"
20 #include "third_party/WebKit/public/web/WebScriptSource.h"
21 
22 namespace extensions {
23 
ProgrammaticScriptInjector(const ExtensionMsg_ExecuteCode_Params & params,blink::WebFrame * web_frame)24 ProgrammaticScriptInjector::ProgrammaticScriptInjector(
25     const ExtensionMsg_ExecuteCode_Params& params,
26     blink::WebFrame* web_frame)
27     : params_(new ExtensionMsg_ExecuteCode_Params(params)),
28       url_(ScriptContext::GetDataSourceURLForFrame(web_frame)),
29       render_view_(content::RenderView::FromWebView(web_frame->view())),
30       results_(new base::ListValue()),
31       finished_(false) {
32 }
33 
~ProgrammaticScriptInjector()34 ProgrammaticScriptInjector::~ProgrammaticScriptInjector() {
35 }
36 
script_type() const37 UserScript::InjectionType ProgrammaticScriptInjector::script_type()
38     const {
39   return UserScript::PROGRAMMATIC_SCRIPT;
40 }
41 
ShouldExecuteInChildFrames() const42 bool ProgrammaticScriptInjector::ShouldExecuteInChildFrames() const {
43   return params_->all_frames;
44 }
45 
ShouldExecuteInMainWorld() const46 bool ProgrammaticScriptInjector::ShouldExecuteInMainWorld() const {
47   return params_->in_main_world;
48 }
49 
IsUserGesture() const50 bool ProgrammaticScriptInjector::IsUserGesture() const {
51   return params_->user_gesture;
52 }
53 
ExpectsResults() const54 bool ProgrammaticScriptInjector::ExpectsResults() const {
55   return params_->wants_result;
56 }
57 
ShouldInjectJs(UserScript::RunLocation run_location) const58 bool ProgrammaticScriptInjector::ShouldInjectJs(
59     UserScript::RunLocation run_location) const {
60   return GetRunLocation() == run_location && params_->is_javascript;
61 }
62 
ShouldInjectCss(UserScript::RunLocation run_location) const63 bool ProgrammaticScriptInjector::ShouldInjectCss(
64     UserScript::RunLocation run_location) const {
65   return GetRunLocation() == run_location && !params_->is_javascript;
66 }
67 
CanExecuteOnFrame(const Extension * extension,blink::WebFrame * frame,int tab_id,const GURL & top_url) const68 PermissionsData::AccessType ProgrammaticScriptInjector::CanExecuteOnFrame(
69     const Extension* extension,
70     blink::WebFrame* frame,
71     int tab_id,
72     const GURL& top_url) const {
73   GURL effective_document_url = ScriptContext::GetEffectiveDocumentURL(
74       frame, frame->document().url(), params_->match_about_blank);
75   if (params_->is_web_view) {
76     return effective_document_url == params_->webview_src
77                ? PermissionsData::ACCESS_ALLOWED
78                : PermissionsData::ACCESS_DENIED;
79   }
80 
81   return extension->permissions_data()->GetPageAccess(extension,
82                                                       effective_document_url,
83                                                       top_url,
84                                                       tab_id,
85                                                       -1,  // no process ID.
86                                                       NULL /* ignore error */);
87 }
88 
GetJsSources(UserScript::RunLocation run_location) const89 std::vector<blink::WebScriptSource> ProgrammaticScriptInjector::GetJsSources(
90     UserScript::RunLocation run_location) const {
91   DCHECK_EQ(GetRunLocation(), run_location);
92   DCHECK(params_->is_javascript);
93 
94   return std::vector<blink::WebScriptSource>(
95       1,
96       blink::WebScriptSource(
97           blink::WebString::fromUTF8(params_->code), params_->file_url));
98 }
99 
GetCssSources(UserScript::RunLocation run_location) const100 std::vector<std::string> ProgrammaticScriptInjector::GetCssSources(
101     UserScript::RunLocation run_location) const {
102   DCHECK_EQ(GetRunLocation(), run_location);
103   DCHECK(!params_->is_javascript);
104 
105   return std::vector<std::string>(1, params_->code);
106 }
107 
OnInjectionComplete(scoped_ptr<base::ListValue> execution_results,ScriptsRunInfo * scripts_run_info,UserScript::RunLocation run_location)108 void ProgrammaticScriptInjector::OnInjectionComplete(
109     scoped_ptr<base::ListValue> execution_results,
110     ScriptsRunInfo* scripts_run_info,
111     UserScript::RunLocation run_location) {
112   results_ = execution_results.Pass();
113   Finish(std::string());
114 }
115 
OnWillNotInject(InjectFailureReason reason)116 void ProgrammaticScriptInjector::OnWillNotInject(InjectFailureReason reason) {
117   std::string error;
118   switch (reason) {
119     case NOT_ALLOWED:
120       error = ErrorUtils::FormatErrorMessage(manifest_errors::kCannotAccessPage,
121                                              url_.spec());
122       break;
123     case EXTENSION_REMOVED:  // no special error here.
124     case WONT_INJECT:
125       break;
126   }
127   Finish(error);
128 }
129 
GetRunLocation() const130 UserScript::RunLocation ProgrammaticScriptInjector::GetRunLocation() const {
131   return static_cast<UserScript::RunLocation>(params_->run_at);
132 }
133 
Finish(const std::string & error)134 void ProgrammaticScriptInjector::Finish(const std::string& error) {
135   DCHECK(!finished_);
136   finished_ = true;
137 
138   render_view_->Send(new ExtensionHostMsg_ExecuteCodeFinished(
139       render_view_->GetRoutingID(),
140       params_->request_id,
141       error,
142       url_,
143       *results_));
144 }
145 
146 }  // namespace extensions
147