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

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

Powered by Google App Engine
This is Rietveld 408576698