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

Side by Side Diff: extensions/renderer/user_script_injector.cc

Issue 959413003: Implement <webview>.addContentScript/removeContentScript API [1] (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Delvin's comments. Created 5 years, 8 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/renderer/user_script_injector.h" 5 #include "extensions/renderer/user_script_injector.h"
6 6
7 #include <vector> 7 #include <vector>
8 8
9 #include "base/lazy_instance.h" 9 #include "base/lazy_instance.h"
10 #include "content/public/common/url_constants.h" 10 #include "content/public/common/url_constants.h"
11 #include "content/public/renderer/render_thread.h"
11 #include "content/public/renderer/render_view.h" 12 #include "content/public/renderer/render_view.h"
12 #include "extensions/common/extension.h" 13 #include "extensions/common/extension.h"
14 #include "extensions/common/guest_view/guest_view_messages.h"
13 #include "extensions/common/permissions/permissions_data.h" 15 #include "extensions/common/permissions/permissions_data.h"
14 #include "extensions/renderer/injection_host.h" 16 #include "extensions/renderer/injection_host.h"
15 #include "extensions/renderer/script_context.h" 17 #include "extensions/renderer/script_context.h"
16 #include "extensions/renderer/scripts_run_info.h" 18 #include "extensions/renderer/scripts_run_info.h"
17 #include "grit/extensions_renderer_resources.h" 19 #include "grit/extensions_renderer_resources.h"
18 #include "third_party/WebKit/public/web/WebDocument.h" 20 #include "third_party/WebKit/public/web/WebDocument.h"
19 #include "third_party/WebKit/public/web/WebFrame.h" 21 #include "third_party/WebKit/public/web/WebFrame.h"
20 #include "third_party/WebKit/public/web/WebScriptSource.h" 22 #include "third_party/WebKit/public/web/WebScriptSource.h"
21 #include "ui/base/resource/resource_bundle.h" 23 #include "ui/base/resource/resource_bundle.h"
22 #include "url/gurl.h" 24 #include "url/gurl.h"
23 25
24 namespace extensions { 26 namespace extensions {
25 27
26 namespace { 28 namespace {
27 29
30 struct RoutingInfoKey {
31 int routing_id;
32 int script_id;
33
34 RoutingInfoKey(int routing_id, int script_id)
35 : routing_id(routing_id), script_id(script_id) {}
36
37 bool operator<(const RoutingInfoKey& other) const {
38 if (routing_id != other.routing_id)
39 return routing_id < other.routing_id;
40
41 if (script_id != other.script_id)
42 return script_id < other.script_id;
43 return false; // keys are equal.
44 }
45 };
46
47 using RoutingInfoMap = std::map<RoutingInfoKey, bool>;
48
28 // These two strings are injected before and after the Greasemonkey API and 49 // These two strings are injected before and after the Greasemonkey API and
29 // user script to wrap it in an anonymous scope. 50 // user script to wrap it in an anonymous scope.
30 const char kUserScriptHead[] = "(function (unsafeWindow) {\n"; 51 const char kUserScriptHead[] = "(function (unsafeWindow) {\n";
31 const char kUserScriptTail[] = "\n})(window);"; 52 const char kUserScriptTail[] = "\n})(window);";
32 53
54 // A map records whether a given |script_id| from a webview-added user script
55 // is allowed to inject on the render of given |routing_id|.
56 // Once a script is added, the decision of whether or not allowed to inject
57 // won't be changed.
58 // Even if the script is removed by the webview, the user scipt will be removed
59 // from the render as well. Therefore, there won't be any query from this
60 // removed |script_id| and |routing_id| pair.
61 base::LazyInstance<RoutingInfoMap> g_routing_info_map =
62 LAZY_INSTANCE_INITIALIZER;
63
33 // Greasemonkey API source that is injected with the scripts. 64 // Greasemonkey API source that is injected with the scripts.
34 struct GreasemonkeyApiJsString { 65 struct GreasemonkeyApiJsString {
35 GreasemonkeyApiJsString(); 66 GreasemonkeyApiJsString();
36 blink::WebScriptSource GetSource() const; 67 blink::WebScriptSource GetSource() const;
37 68
38 private: 69 private:
39 std::string source_; 70 std::string source_;
40 }; 71 };
41 72
42 // The below constructor, monstrous as it is, just makes a WebScriptSource from 73 // The below constructor, monstrous as it is, just makes a WebScriptSource from
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
124 155
125 PermissionsData::AccessType UserScriptInjector::CanExecuteOnFrame( 156 PermissionsData::AccessType UserScriptInjector::CanExecuteOnFrame(
126 const InjectionHost* injection_host, 157 const InjectionHost* injection_host,
127 blink::WebFrame* web_frame, 158 blink::WebFrame* web_frame,
128 int tab_id, 159 int tab_id,
129 const GURL& top_url) const { 160 const GURL& top_url) const {
130 GURL effective_document_url = ScriptContext::GetEffectiveDocumentURL( 161 GURL effective_document_url = ScriptContext::GetEffectiveDocumentURL(
131 web_frame, web_frame->document().url(), script_->match_about_blank()); 162 web_frame, web_frame->document().url(), script_->match_about_blank());
132 PermissionsData::AccessType can_execute = injection_host->CanExecuteOnFrame( 163 PermissionsData::AccessType can_execute = injection_host->CanExecuteOnFrame(
133 effective_document_url, top_url, tab_id, is_declarative_); 164 effective_document_url, top_url, tab_id, is_declarative_);
134
135 if (script_->consumer_instance_type() != 165 if (script_->consumer_instance_type() !=
136 UserScript::ConsumerInstanceType::WEBVIEW || 166 UserScript::ConsumerInstanceType::WEBVIEW ||
137 can_execute == PermissionsData::ACCESS_DENIED) 167 can_execute == PermissionsData::ACCESS_DENIED)
138 return can_execute; 168 return can_execute;
139 169
140 int routing_id = content::RenderView::FromWebView(web_frame->top()->view()) 170 int routing_id = content::RenderView::FromWebView(web_frame->top()->view())
141 ->GetRoutingID(); 171 ->GetRoutingID();
142 return script_->routing_info().render_view_id == routing_id 172
143 ? PermissionsData::ACCESS_ALLOWED 173 RoutingInfoKey key(routing_id, script_->id());
144 : PermissionsData::ACCESS_DENIED; 174
175 RoutingInfoMap& map = g_routing_info_map.Get();
176 auto iter = map.find(key);
177
178 bool allowed = false;
179 if (iter != map.end()) {
180 allowed = iter->second;
181 } else {
182 // Send a SYNC IPC message to the browser to check if this is allowed. This
183 // is not ideal, but is mitigated by the fact that this is only done for
184 // webviews, and then only once per host.
185 // TODO(hanxi): Find a more efficient way to do this.
186 content::RenderThread::Get()->Send(
187 new GuestViewHostMsg_CanExecuteContentScriptSync(
188 routing_id, script_->id(), &allowed));
189 map.insert(std::pair<RoutingInfoKey, bool>(key, allowed));
190 }
191
192 return allowed ? PermissionsData::ACCESS_ALLOWED
193 : PermissionsData::ACCESS_DENIED;
145 } 194 }
146 195
147 std::vector<blink::WebScriptSource> UserScriptInjector::GetJsSources( 196 std::vector<blink::WebScriptSource> UserScriptInjector::GetJsSources(
148 UserScript::RunLocation run_location) const { 197 UserScript::RunLocation run_location) const {
149 DCHECK_EQ(script_->run_location(), run_location); 198 DCHECK_EQ(script_->run_location(), run_location);
150 199
151 std::vector<blink::WebScriptSource> sources; 200 std::vector<blink::WebScriptSource> sources;
152 const UserScript::FileList& js_scripts = script_->js_scripts(); 201 const UserScript::FileList& js_scripts = script_->js_scripts();
153 bool is_standalone_or_emulate_greasemonkey = 202 bool is_standalone_or_emulate_greasemonkey =
154 script_->is_standalone() || script_->emulate_greasemonkey(); 203 script_->is_standalone() || script_->emulate_greasemonkey();
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
212 261
213 void UserScriptInjector::OnInjectionComplete( 262 void UserScriptInjector::OnInjectionComplete(
214 scoped_ptr<base::ListValue> execution_results, 263 scoped_ptr<base::ListValue> execution_results,
215 UserScript::RunLocation run_location) { 264 UserScript::RunLocation run_location) {
216 } 265 }
217 266
218 void UserScriptInjector::OnWillNotInject(InjectFailureReason reason) { 267 void UserScriptInjector::OnWillNotInject(InjectFailureReason reason) {
219 } 268 }
220 269
221 } // namespace extensions 270 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698