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

Side by Side Diff: chrome/browser/extensions/api/declarative_content/content_action.cc

Issue 493633003: Browser changes for wiring up RequestContentScript API to shared memory (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: ditto Created 6 years, 4 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 (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "chrome/browser/extensions/api/declarative_content/content_action.h" 5 #include "chrome/browser/extensions/api/declarative_content/content_action.h"
6 6
7 #include <map> 7 #include <map>
8 8
9 #include "base/lazy_instance.h" 9 #include "base/lazy_instance.h"
10 #include "base/strings/stringprintf.h" 10 #include "base/strings/stringprintf.h"
11 #include "base/values.h" 11 #include "base/values.h"
12 #include "chrome/browser/extensions/api/declarative_content/content_constants.h" 12 #include "chrome/browser/extensions/api/declarative_content/content_constants.h"
13 #include "chrome/browser/extensions/api/extension_action/extension_action_api.h" 13 #include "chrome/browser/extensions/api/extension_action/extension_action_api.h"
14 #include "chrome/browser/extensions/declarative_user_script_master.h"
14 #include "chrome/browser/extensions/extension_action.h" 15 #include "chrome/browser/extensions/extension_action.h"
15 #include "chrome/browser/extensions/extension_action_manager.h" 16 #include "chrome/browser/extensions/extension_action_manager.h"
16 #include "chrome/browser/extensions/extension_tab_util.h" 17 #include "chrome/browser/extensions/extension_tab_util.h"
17 #include "chrome/browser/profiles/profile.h" 18 #include "chrome/browser/profiles/profile.h"
19 #include "chrome/browser/sessions/session_tab_helper.h"
Jeffrey Yasskin 2014/08/22 01:12:24 Double-check which headers you still need.
Mark Dittmer 2014/08/22 19:59:19 Done.
20 #include "chrome/common/extensions/manifest_handlers/content_scripts_handler.h"
18 #include "content/public/browser/invalidate_type.h" 21 #include "content/public/browser/invalidate_type.h"
22 #include "content/public/browser/render_process_host.h"
23 #include "content/public/browser/render_view_host.h"
19 #include "content/public/browser/web_contents.h" 24 #include "content/public/browser/web_contents.h"
20 #include "extensions/browser/extension_registry.h" 25 #include "extensions/browser/extension_registry.h"
26 #include "extensions/browser/extension_system.h"
21 #include "extensions/common/extension.h" 27 #include "extensions/common/extension.h"
28 #include "extensions/common/extension_messages.h"
22 29
23 namespace extensions { 30 namespace extensions {
24 31
25 namespace keys = declarative_content_constants; 32 namespace keys = declarative_content_constants;
26 33
27 namespace { 34 namespace {
28 // Error messages. 35 // Error messages.
29 const char kInvalidInstanceTypeError[] = 36 const char kInvalidInstanceTypeError[] =
30 "An action has an invalid instanceType: %s"; 37 "An action has an invalid instanceType: %s";
31 const char kNoPageAction[] = 38 const char kNoPageAction[] =
32 "Can't use declarativeContent.ShowPageAction without a page action"; 39 "Can't use declarativeContent.ShowPageAction without a page action";
33 const char kMissingParameter[] = "Missing parameter is required: %s"; 40 const char kMissingParameter[] = "Missing parameter is required: %s";
34 41
35 #define INPUT_FORMAT_VALIDATE(test) do { \ 42 #define INPUT_FORMAT_VALIDATE(test) do { \
36 if (!(test)) { \ 43 if (!(test)) { \
37 *bad_message = true; \ 44 *bad_message = true; \
38 return scoped_refptr<ContentAction>(NULL); \ 45 return scoped_refptr<ContentAction>(NULL); \
39 } \ 46 } \
40 } while (0) 47 } while (0)
41 48
42 // 49 //
43 // The following are concrete actions. 50 // The following are concrete actions.
44 // 51 //
45 52
46 // Action that instructs to show an extension's page action. 53 // Action that instructs to show an extension's page action.
47 class ShowPageAction : public ContentAction { 54 class ShowPageAction : public ContentAction {
48 public: 55 public:
49 ShowPageAction() {} 56 ShowPageAction() {}
50 57
51 static scoped_refptr<ContentAction> Create(const Extension* extension, 58 static scoped_refptr<ContentAction> Create(Profile* profile,
59 const Extension* extension,
52 const base::DictionaryValue* dict, 60 const base::DictionaryValue* dict,
53 std::string* error, 61 std::string* error,
54 bool* bad_message) { 62 bool* bad_message) {
55 // We can't show a page action if the extension doesn't have one. 63 // We can't show a page action if the extension doesn't have one.
56 if (ActionInfo::GetPageActionInfo(extension) == NULL) { 64 if (ActionInfo::GetPageActionInfo(extension) == NULL) {
57 *error = kNoPageAction; 65 *error = kNoPageAction;
58 return scoped_refptr<ContentAction>(); 66 return scoped_refptr<ContentAction>();
59 } 67 }
60 return scoped_refptr<ContentAction>(new ShowPageAction); 68 return scoped_refptr<ContentAction>(new ShowPageAction);
61 } 69 }
(...skipping 15 matching lines...) Expand all
77 virtual void Revert(const std::string& extension_id, 85 virtual void Revert(const std::string& extension_id,
78 const base::Time& extension_install_time, 86 const base::Time& extension_install_time,
79 ApplyInfo* apply_info) const OVERRIDE { 87 ApplyInfo* apply_info) const OVERRIDE {
80 if (ExtensionAction* action = 88 if (ExtensionAction* action =
81 GetPageAction(apply_info->profile, extension_id)) { 89 GetPageAction(apply_info->profile, extension_id)) {
82 action->UndoDeclarativeShow(ExtensionTabUtil::GetTabId(apply_info->tab)); 90 action->UndoDeclarativeShow(ExtensionTabUtil::GetTabId(apply_info->tab));
83 ExtensionActionAPI::Get(apply_info->profile)->NotifyChange( 91 ExtensionActionAPI::Get(apply_info->profile)->NotifyChange(
84 action, apply_info->tab, apply_info->profile); 92 action, apply_info->tab, apply_info->profile);
85 } 93 }
86 } 94 }
95 virtual void Reapply(const std::string& extension_id,
96 const base::Time& extension_install_time,
97 ApplyInfo* apply_info) const OVERRIDE {
98 }
87 99
88 private: 100 private:
89 static ExtensionAction* GetPageAction(Profile* profile, 101 static ExtensionAction* GetPageAction(Profile* profile,
90 const std::string& extension_id) { 102 const std::string& extension_id) {
91 const Extension* extension = 103 const Extension* extension =
92 ExtensionRegistry::Get(profile) 104 ExtensionRegistry::Get(profile)
93 ->GetExtensionById(extension_id, ExtensionRegistry::EVERYTHING); 105 ->GetExtensionById(extension_id, ExtensionRegistry::EVERYTHING);
94 if (!extension) 106 if (!extension)
95 return NULL; 107 return NULL;
96 return ExtensionActionManager::Get(profile)->GetPageAction(*extension); 108 return ExtensionActionManager::Get(profile)->GetPageAction(*extension);
97 } 109 }
98 virtual ~ShowPageAction() {} 110 virtual ~ShowPageAction() {}
99 111
100 DISALLOW_COPY_AND_ASSIGN(ShowPageAction); 112 DISALLOW_COPY_AND_ASSIGN(ShowPageAction);
101 }; 113 };
102 114
103 // Action that injects a content script. 115 // Action that injects a content script.
104 class RequestContentScript : public ContentAction { 116 class RequestContentScript : public ContentAction {
105 public: 117 public:
106 RequestContentScript(const std::vector<std::string>& css_file_names, 118 static scoped_refptr<ContentAction> Create(Profile* profile,
107 const std::vector<std::string>& js_file_names, 119 const Extension* extension,
108 bool all_frames,
109 bool match_about_blank)
110 : css_file_names_(css_file_names),
111 js_file_names_(js_file_names),
112 all_frames_(all_frames),
113 match_about_blank_(match_about_blank) {}
114
115 static scoped_refptr<ContentAction> Create(const Extension* extension,
116 const base::DictionaryValue* dict, 120 const base::DictionaryValue* dict,
117 std::string* error, 121 std::string* error,
118 bool* bad_message); 122 bool* bad_message);
119 123
124 RequestContentScript(Profile* profile,
Jeffrey Yasskin 2014/08/22 01:12:24 Try not to reorder blocks unnecessarily.
Mark Dittmer 2014/08/22 19:59:18 Done.
125 const Extension* extension,
126 const std::vector<std::string>& css_file_names,
127 const std::vector<std::string>& js_file_names,
128 bool all_frames,
129 bool match_about_blank);
130
120 // Implementation of ContentAction: 131 // Implementation of ContentAction:
121 virtual Type GetType() const OVERRIDE { 132 virtual Type GetType() const OVERRIDE {
122 return ACTION_REQUEST_CONTENT_SCRIPT; 133 return ACTION_REQUEST_CONTENT_SCRIPT;
123 } 134 }
124 135
125 virtual void Apply(const std::string& extension_id, 136 virtual void Apply(const std::string& extension_id,
126 const base::Time& extension_install_time, 137 const base::Time& extension_install_time,
127 ApplyInfo* apply_info) const OVERRIDE { 138 ApplyInfo* apply_info) const OVERRIDE {
128 // TODO(markdittmer): Invoke UserScriptMaster declarative script loader: 139 InstructRenderProcessToInject(apply_info->tab, extension_id);
129 // load new user script.
130 } 140 }
131 141
132 virtual void Reapply(const std::string& extension_id, 142 virtual void Reapply(const std::string& extension_id,
133 const base::Time& extension_install_time, 143 const base::Time& extension_install_time,
134 ApplyInfo* apply_info) const OVERRIDE { 144 ApplyInfo* apply_info) const OVERRIDE {
135 // TODO(markdittmer): Invoke UserScriptMaster declarative script loader: 145 // TODO(markdittmer): Invoke UserScriptMaster declarative script loader:
136 // load new user script. 146 // load new user script.
137 } 147 }
138 148
139 virtual void Revert(const std::string& extension_id, 149 virtual void Revert(const std::string& extension_id,
140 const base::Time& extension_install_time, 150 const base::Time& extension_install_time,
141 ApplyInfo* apply_info) const OVERRIDE { 151 ApplyInfo* apply_info) const OVERRIDE {
142 // TODO(markdittmer): Invoke UserScriptMaster declarative script loader: 152 }
143 // do not load user script if Apply() runs again on the same page. 153 virtual void Reapply(const std::string& extension_id,
154 const base::Time& extension_install_time,
155 ApplyInfo* apply_info) const OVERRIDE {
156 InstructRenderProcessToInject(apply_info->tab, extension_id);
144 } 157 }
145 158
146 private: 159 private:
147 virtual ~RequestContentScript() {} 160 virtual ~RequestContentScript() {
161 DCHECK(master_);
162 master_->RemoveScript(script_);
163 }
148 164
149 std::vector<std::string> css_file_names_; 165 void InstructRenderProcessToInject(content::WebContents* contents,
150 std::vector<std::string> js_file_names_; 166 const std::string& extension_id) const;
151 bool all_frames_; 167
152 bool match_about_blank_; 168 UserScript script_;
169 DeclarativeUserScriptMaster* master_;
153 170
154 DISALLOW_COPY_AND_ASSIGN(RequestContentScript); 171 DISALLOW_COPY_AND_ASSIGN(RequestContentScript);
155 }; 172 };
156 173
157 // Helper for getting JS collections into C++. 174 // Helper for getting JS collections into C++.
158 static bool AppendJSStringsToCPPStrings(const base::ListValue& append_strings, 175 static bool AppendJSStringsToCPPStrings(const base::ListValue& append_strings,
159 std::vector<std::string>* append_to) { 176 std::vector<std::string>* append_to) {
160 for (base::ListValue::const_iterator it = append_strings.begin(); 177 for (base::ListValue::const_iterator it = append_strings.begin();
161 it != append_strings.end(); 178 it != append_strings.end();
162 ++it) { 179 ++it) {
163 std::string value; 180 std::string value;
164 if ((*it)->GetAsString(&value)) { 181 if ((*it)->GetAsString(&value)) {
165 append_to->push_back(value); 182 append_to->push_back(value);
166 } else { 183 } else {
167 return false; 184 return false;
168 } 185 }
169 } 186 }
170 187
171 return true; 188 return true;
172 } 189 }
173 190
174 // static 191 // static
175 scoped_refptr<ContentAction> RequestContentScript::Create( 192 scoped_refptr<ContentAction> RequestContentScript::Create(
193 Profile* profile,
176 const Extension* extension, 194 const Extension* extension,
177 const base::DictionaryValue* dict, 195 const base::DictionaryValue* dict,
178 std::string* error, 196 std::string* error,
179 bool* bad_message) { 197 bool* bad_message) {
180 std::vector<std::string> css_file_names; 198 std::vector<std::string> css_file_names;
181 std::vector<std::string> js_file_names; 199 std::vector<std::string> js_file_names;
182 bool all_frames = false; 200 bool all_frames = false;
183 bool match_about_blank = false; 201 bool match_about_blank = false;
184 const base::ListValue* list_value; 202 const base::ListValue* list_value;
185 203
(...skipping 13 matching lines...) Expand all
199 } 217 }
200 if (dict->HasKey(keys::kAllFrames)) { 218 if (dict->HasKey(keys::kAllFrames)) {
201 INPUT_FORMAT_VALIDATE(dict->GetBoolean(keys::kAllFrames, &all_frames)); 219 INPUT_FORMAT_VALIDATE(dict->GetBoolean(keys::kAllFrames, &all_frames));
202 } 220 }
203 if (dict->HasKey(keys::kMatchAboutBlank)) { 221 if (dict->HasKey(keys::kMatchAboutBlank)) {
204 INPUT_FORMAT_VALIDATE( 222 INPUT_FORMAT_VALIDATE(
205 dict->GetBoolean(keys::kMatchAboutBlank, &match_about_blank)); 223 dict->GetBoolean(keys::kMatchAboutBlank, &match_about_blank));
206 } 224 }
207 225
208 return scoped_refptr<ContentAction>(new RequestContentScript( 226 return scoped_refptr<ContentAction>(new RequestContentScript(
209 css_file_names, js_file_names, all_frames, match_about_blank)); 227 profile,
228 extension,
229 css_file_names,
230 js_file_names,
231 all_frames,
232 match_about_blank));
233 }
234
235 RequestContentScript::RequestContentScript(
236 Profile* profile,
237 const Extension* extension,
238 const std::vector<std::string>& css_file_names,
239 const std::vector<std::string>& js_file_names,
240 bool all_frames,
241 bool match_about_blank) {
242 script_.set_id(ContentScriptsHandler::GetNextUserScriptID());
243 script_.set_extension_id(extension->id());
244 script_.set_run_location(UserScript::BROWSER_DRIVEN);
245 script_.set_match_all_frames(all_frames);
246 script_.set_match_about_blank(match_about_blank);
247 for (std::vector<std::string>::const_iterator it = css_file_names.begin();
248 it != css_file_names.end(); ++it) {
249 GURL url = extension->GetResourceURL(*it);
250 ExtensionResource resource = extension->GetResource(*it);
251 script_.css_scripts().push_back(UserScript::File(
252 resource.extension_root(), resource.relative_path(), url));
253 }
254 for (std::vector<std::string>::const_iterator it = js_file_names.begin();
255 it != js_file_names.end(); ++it) {
256 GURL url = extension->GetResourceURL(*it);
257 ExtensionResource resource = extension->GetResource(*it);
258 script_.js_scripts().push_back(UserScript::File(
259 resource.extension_root(), resource.relative_path(), url));
260 }
261
262 master_ =
263 ExtensionSystem::Get(profile)->GetDeclarativeUserScriptMasterByExtension(
Jeffrey Yasskin 2014/08/22 01:12:24 Can you point to the code that shows that master_
Devlin 2014/08/22 19:25:45 Jumping in, since Mark was chatting with me about
264 extension->id());
265 DCHECK(master_);
266 master_->AddScript(script_);
267 }
268
269 void RequestContentScript::InstructRenderProcessToInject(
270 content::WebContents* contents,
271 const std::string& extension_id) const {
272 // TODO(markdittmer): Send ExtensionMsg to renderer.
210 } 273 }
211 274
212 struct ContentActionFactory { 275 struct ContentActionFactory {
213 // Factory methods for ContentAction instances. |extension| is the extension 276 // Factory methods for ContentAction instances. |extension| is the extension
214 // for which the action is being created. |dict| contains the json dictionary 277 // for which the action is being created. |dict| contains the json dictionary
215 // that describes the action. |error| is used to return error messages in case 278 // that describes the action. |error| is used to return error messages in case
216 // the extension passed an action that was syntactically correct but 279 // the extension passed an action that was syntactically correct but
217 // semantically incorrect. |bad_message| is set to true in case |dict| does 280 // semantically incorrect. |bad_message| is set to true in case |dict| does
218 // not confirm to the validated JSON specification. 281 // not confirm to the validated JSON specification.
219 typedef scoped_refptr<ContentAction>(*FactoryMethod)( 282 typedef scoped_refptr<ContentAction>(*FactoryMethod)(
283 Profile* /* profile */,
220 const Extension* /* extension */, 284 const Extension* /* extension */,
221 const base::DictionaryValue* /* dict */, 285 const base::DictionaryValue* /* dict */,
222 std::string* /* error */, 286 std::string* /* error */,
223 bool* /* bad_message */); 287 bool* /* bad_message */);
224 // Maps the name of a declarativeContent action type to the factory 288 // Maps the name of a declarativeContent action type to the factory
225 // function creating it. 289 // function creating it.
226 std::map<std::string, FactoryMethod> factory_methods; 290 std::map<std::string, FactoryMethod> factory_methods;
227 291
228 ContentActionFactory() { 292 ContentActionFactory() {
229 factory_methods[keys::kShowPageAction] = 293 factory_methods[keys::kShowPageAction] =
(...skipping 11 matching lines...) Expand all
241 // 305 //
242 // ContentAction 306 // ContentAction
243 // 307 //
244 308
245 ContentAction::ContentAction() {} 309 ContentAction::ContentAction() {}
246 310
247 ContentAction::~ContentAction() {} 311 ContentAction::~ContentAction() {}
248 312
249 // static 313 // static
250 scoped_refptr<ContentAction> ContentAction::Create( 314 scoped_refptr<ContentAction> ContentAction::Create(
315 Profile* profile,
251 const Extension* extension, 316 const Extension* extension,
252 const base::Value& json_action, 317 const base::Value& json_action,
253 std::string* error, 318 std::string* error,
254 bool* bad_message) { 319 bool* bad_message) {
255 *error = ""; 320 *error = "";
256 *bad_message = false; 321 *bad_message = false;
257 322
258 const base::DictionaryValue* action_dict = NULL; 323 const base::DictionaryValue* action_dict = NULL;
259 INPUT_FORMAT_VALIDATE(json_action.GetAsDictionary(&action_dict)); 324 INPUT_FORMAT_VALIDATE(json_action.GetAsDictionary(&action_dict));
260 325
261 std::string instance_type; 326 std::string instance_type;
262 INPUT_FORMAT_VALIDATE( 327 INPUT_FORMAT_VALIDATE(
263 action_dict->GetString(keys::kInstanceType, &instance_type)); 328 action_dict->GetString(keys::kInstanceType, &instance_type));
264 329
265 ContentActionFactory& factory = g_content_action_factory.Get(); 330 ContentActionFactory& factory = g_content_action_factory.Get();
266 std::map<std::string, ContentActionFactory::FactoryMethod>::iterator 331 std::map<std::string, ContentActionFactory::FactoryMethod>::iterator
267 factory_method_iter = factory.factory_methods.find(instance_type); 332 factory_method_iter = factory.factory_methods.find(instance_type);
268 if (factory_method_iter != factory.factory_methods.end()) 333 if (factory_method_iter != factory.factory_methods.end())
269 return (*factory_method_iter->second)( 334 return (*factory_method_iter->second)(
270 extension, action_dict, error, bad_message); 335 profile, extension, action_dict, error, bad_message);
271 336
272 *error = base::StringPrintf(kInvalidInstanceTypeError, instance_type.c_str()); 337 *error = base::StringPrintf(kInvalidInstanceTypeError, instance_type.c_str());
273 return scoped_refptr<ContentAction>(); 338 return scoped_refptr<ContentAction>();
274 } 339 }
275 340
276 } // namespace extensions 341 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698