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

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: 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"
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 11 matching lines...) Expand all
73 virtual void Revert(const std::string& extension_id, 81 virtual void Revert(const std::string& extension_id,
74 const base::Time& extension_install_time, 82 const base::Time& extension_install_time,
75 ApplyInfo* apply_info) const OVERRIDE { 83 ApplyInfo* apply_info) const OVERRIDE {
76 if (ExtensionAction* action = 84 if (ExtensionAction* action =
77 GetPageAction(apply_info->profile, extension_id)) { 85 GetPageAction(apply_info->profile, extension_id)) {
78 action->UndoDeclarativeShow(ExtensionTabUtil::GetTabId(apply_info->tab)); 86 action->UndoDeclarativeShow(ExtensionTabUtil::GetTabId(apply_info->tab));
79 ExtensionActionAPI::Get(apply_info->profile)->NotifyChange( 87 ExtensionActionAPI::Get(apply_info->profile)->NotifyChange(
80 action, apply_info->tab); 88 action, apply_info->tab);
81 } 89 }
82 } 90 }
91 virtual void Reapply(const std::string& extension_id,
92 const base::Time& extension_install_time,
93 ApplyInfo* apply_info) const OVERRIDE {
94 }
83 95
84 private: 96 private:
85 static ExtensionAction* GetPageAction(Profile* profile, 97 static ExtensionAction* GetPageAction(Profile* profile,
86 const std::string& extension_id) { 98 const std::string& extension_id) {
87 const Extension* extension = 99 const Extension* extension =
88 ExtensionRegistry::Get(profile) 100 ExtensionRegistry::Get(profile)
89 ->GetExtensionById(extension_id, ExtensionRegistry::EVERYTHING); 101 ->GetExtensionById(extension_id, ExtensionRegistry::EVERYTHING);
90 if (!extension) 102 if (!extension)
91 return NULL; 103 return NULL;
92 return ExtensionActionManager::Get(profile)->GetPageAction(*extension); 104 return ExtensionActionManager::Get(profile)->GetPageAction(*extension);
93 } 105 }
94 virtual ~ShowPageAction() {} 106 virtual ~ShowPageAction() {}
95 107
96 DISALLOW_COPY_AND_ASSIGN(ShowPageAction); 108 DISALLOW_COPY_AND_ASSIGN(ShowPageAction);
97 }; 109 };
98 110
99 // Action that injects a content script. 111 // Action that injects a content script.
100 class RequestContentScript : public ContentAction { 112 class RequestContentScript : public ContentAction {
101 public: 113 public:
102 RequestContentScript(const std::vector<std::string>& css_file_names, 114 static scoped_refptr<ContentAction> Create(Profile* profile,
103 const std::vector<std::string>& js_file_names, 115 const Extension* extension,
104 bool all_frames,
105 bool match_about_blank)
106 : css_file_names_(css_file_names),
107 js_file_names_(js_file_names),
108 all_frames_(all_frames),
109 match_about_blank_(match_about_blank) {}
110
111 static scoped_refptr<ContentAction> Create(const Extension* extension,
112 const base::DictionaryValue* dict, 116 const base::DictionaryValue* dict,
113 std::string* error, 117 std::string* error,
114 bool* bad_message); 118 bool* bad_message);
115 119
120 RequestContentScript(Profile* profile,
121 const Extension* extension,
122 const std::vector<std::string>& css_file_names,
123 const std::vector<std::string>& js_file_names,
124 bool all_frames,
125 bool match_about_blank);
126
116 // Implementation of ContentAction: 127 // Implementation of ContentAction:
117 virtual Type GetType() const OVERRIDE { 128 virtual Type GetType() const OVERRIDE {
118 return ACTION_REQUEST_CONTENT_SCRIPT; 129 return ACTION_REQUEST_CONTENT_SCRIPT;
119 } 130 }
120 131
121 virtual void Apply(const std::string& extension_id, 132 virtual void Apply(const std::string& extension_id,
122 const base::Time& extension_install_time, 133 const base::Time& extension_install_time,
123 ApplyInfo* apply_info) const OVERRIDE { 134 ApplyInfo* apply_info) const OVERRIDE {
124 // TODO(markdittmer): Invoke UserScriptMaster declarative script loader: 135 InstructRenderProcessToInject(apply_info->tab, extension_id);
125 // load new user script.
126 } 136 }
127 137
128 virtual void Revert(const std::string& extension_id, 138 virtual void Revert(const std::string& extension_id,
129 const base::Time& extension_install_time, 139 const base::Time& extension_install_time,
130 ApplyInfo* apply_info) const OVERRIDE { 140 ApplyInfo* apply_info) const OVERRIDE {
131 // TODO(markdittmer): Invoke UserScriptMaster declarative script loader: 141 }
132 // do not load user script if Apply() runs again on the same page. 142 virtual void Reapply(const std::string& extension_id,
143 const base::Time& extension_install_time,
144 ApplyInfo* apply_info) const OVERRIDE {
145 InstructRenderProcessToInject(apply_info->tab, extension_id);
133 } 146 }
134 147
135 private: 148 private:
136 virtual ~RequestContentScript() {} 149 virtual ~RequestContentScript() {
150 DCHECK(master_);
151 master_->RemoveScript(script_);
152 }
137 153
138 std::vector<std::string> css_file_names_; 154 void InstructRenderProcessToInject(content::WebContents* contents,
139 std::vector<std::string> js_file_names_; 155 const std::string& extension_id) const;
140 bool all_frames_; 156
141 bool match_about_blank_; 157 UserScript script_;
158 DeclarativeUserScriptMaster* master_;
142 159
143 DISALLOW_COPY_AND_ASSIGN(RequestContentScript); 160 DISALLOW_COPY_AND_ASSIGN(RequestContentScript);
144 }; 161 };
145 162
146 // Helper for getting JS collections into C++. 163 // Helper for getting JS collections into C++.
147 static bool AppendJSStringsToCPPStrings(const base::ListValue& append_strings, 164 static bool AppendJSStringsToCPPStrings(const base::ListValue& append_strings,
148 std::vector<std::string>* append_to) { 165 std::vector<std::string>* append_to) {
149 for (base::ListValue::const_iterator it = append_strings.begin(); 166 for (base::ListValue::const_iterator it = append_strings.begin();
150 it != append_strings.end(); 167 it != append_strings.end();
151 ++it) { 168 ++it) {
152 std::string value; 169 std::string value;
153 if ((*it)->GetAsString(&value)) { 170 if ((*it)->GetAsString(&value)) {
154 append_to->push_back(value); 171 append_to->push_back(value);
155 } else { 172 } else {
156 return false; 173 return false;
157 } 174 }
158 } 175 }
159 176
160 return true; 177 return true;
161 } 178 }
162 179
163 // static 180 // static
164 scoped_refptr<ContentAction> RequestContentScript::Create( 181 scoped_refptr<ContentAction> RequestContentScript::Create(
182 Profile* profile,
165 const Extension* extension, 183 const Extension* extension,
166 const base::DictionaryValue* dict, 184 const base::DictionaryValue* dict,
167 std::string* error, 185 std::string* error,
168 bool* bad_message) { 186 bool* bad_message) {
169 std::vector<std::string> css_file_names; 187 std::vector<std::string> css_file_names;
170 std::vector<std::string> js_file_names; 188 std::vector<std::string> js_file_names;
171 bool all_frames = false; 189 bool all_frames = false;
172 bool match_about_blank = false; 190 bool match_about_blank = false;
173 const base::ListValue* list_value; 191 const base::ListValue* list_value;
174 192
(...skipping 13 matching lines...) Expand all
188 } 206 }
189 if (dict->HasKey(keys::kAllFrames)) { 207 if (dict->HasKey(keys::kAllFrames)) {
190 INPUT_FORMAT_VALIDATE(dict->GetBoolean(keys::kAllFrames, &all_frames)); 208 INPUT_FORMAT_VALIDATE(dict->GetBoolean(keys::kAllFrames, &all_frames));
191 } 209 }
192 if (dict->HasKey(keys::kMatchAboutBlank)) { 210 if (dict->HasKey(keys::kMatchAboutBlank)) {
193 INPUT_FORMAT_VALIDATE( 211 INPUT_FORMAT_VALIDATE(
194 dict->GetBoolean(keys::kMatchAboutBlank, &match_about_blank)); 212 dict->GetBoolean(keys::kMatchAboutBlank, &match_about_blank));
195 } 213 }
196 214
197 return scoped_refptr<ContentAction>(new RequestContentScript( 215 return scoped_refptr<ContentAction>(new RequestContentScript(
198 css_file_names, js_file_names, all_frames, match_about_blank)); 216 profile,
217 extension,
218 css_file_names,
219 js_file_names,
220 all_frames,
221 match_about_blank));
222 }
223
224 RequestContentScript::RequestContentScript(
225 Profile* profile,
226 const Extension* extension,
227 const std::vector<std::string>& css_file_names,
228 const std::vector<std::string>& js_file_names,
229 bool all_frames,
230 bool match_about_blank) {
231 script_.set_id(ContentScriptsHandler::GetNextUserScriptID());
232 script_.set_extension_id(extension->id());
233 script_.set_run_location(UserScript::BROWSER_DRIVEN);
234 script_.set_match_all_frames(all_frames);
235 script_.set_match_about_blank(match_about_blank);
236 for (std::vector<std::string>::const_iterator it = css_file_names.begin();
237 it != css_file_names.end(); ++it) {
238 GURL url = extension->GetResourceURL(*it);
239 ExtensionResource resource = extension->GetResource(*it);
240 script_.css_scripts().push_back(UserScript::File(
241 resource.extension_root(), resource.relative_path(), url));
242 }
243 for (std::vector<std::string>::const_iterator it = js_file_names.begin();
244 it != js_file_names.end(); ++it) {
245 GURL url = extension->GetResourceURL(*it);
246 ExtensionResource resource = extension->GetResource(*it);
247 script_.js_scripts().push_back(UserScript::File(
248 resource.extension_root(), resource.relative_path(), url));
249 }
250
251 master_ =
252 ExtensionSystem::Get(profile)->GetDeclarativeUserScriptMasterByExtension(
253 extension->id());
254 DCHECK(master_);
255 master_->AddScript(script_);
256 }
257
258 void RequestContentScript::InstructRenderProcessToInject(
259 content::WebContents* contents,
260 const std::string& extension_id) const {
261 // TODO(markdittmer): Send ExtensionMsg to renderer.
199 } 262 }
200 263
201 struct ContentActionFactory { 264 struct ContentActionFactory {
202 // Factory methods for ContentAction instances. |extension| is the extension 265 // Factory methods for ContentAction instances. |extension| is the extension
203 // for which the action is being created. |dict| contains the json dictionary 266 // for which the action is being created. |dict| contains the json dictionary
204 // that describes the action. |error| is used to return error messages in case 267 // that describes the action. |error| is used to return error messages in case
205 // the extension passed an action that was syntactically correct but 268 // the extension passed an action that was syntactically correct but
206 // semantically incorrect. |bad_message| is set to true in case |dict| does 269 // semantically incorrect. |bad_message| is set to true in case |dict| does
207 // not confirm to the validated JSON specification. 270 // not confirm to the validated JSON specification.
208 typedef scoped_refptr<ContentAction>(*FactoryMethod)( 271 typedef scoped_refptr<ContentAction>(*FactoryMethod)(
272 Profile* /* profile */,
209 const Extension* /* extension */, 273 const Extension* /* extension */,
210 const base::DictionaryValue* /* dict */, 274 const base::DictionaryValue* /* dict */,
211 std::string* /* error */, 275 std::string* /* error */,
212 bool* /* bad_message */); 276 bool* /* bad_message */);
213 // Maps the name of a declarativeContent action type to the factory 277 // Maps the name of a declarativeContent action type to the factory
214 // function creating it. 278 // function creating it.
215 std::map<std::string, FactoryMethod> factory_methods; 279 std::map<std::string, FactoryMethod> factory_methods;
216 280
217 ContentActionFactory() { 281 ContentActionFactory() {
218 factory_methods[keys::kShowPageAction] = 282 factory_methods[keys::kShowPageAction] =
(...skipping 11 matching lines...) Expand all
230 // 294 //
231 // ContentAction 295 // ContentAction
232 // 296 //
233 297
234 ContentAction::ContentAction() {} 298 ContentAction::ContentAction() {}
235 299
236 ContentAction::~ContentAction() {} 300 ContentAction::~ContentAction() {}
237 301
238 // static 302 // static
239 scoped_refptr<ContentAction> ContentAction::Create( 303 scoped_refptr<ContentAction> ContentAction::Create(
304 Profile* profile,
240 const Extension* extension, 305 const Extension* extension,
241 const base::Value& json_action, 306 const base::Value& json_action,
242 std::string* error, 307 std::string* error,
243 bool* bad_message) { 308 bool* bad_message) {
244 *error = ""; 309 *error = "";
245 *bad_message = false; 310 *bad_message = false;
246 311
247 const base::DictionaryValue* action_dict = NULL; 312 const base::DictionaryValue* action_dict = NULL;
248 INPUT_FORMAT_VALIDATE(json_action.GetAsDictionary(&action_dict)); 313 INPUT_FORMAT_VALIDATE(json_action.GetAsDictionary(&action_dict));
249 314
250 std::string instance_type; 315 std::string instance_type;
251 INPUT_FORMAT_VALIDATE( 316 INPUT_FORMAT_VALIDATE(
252 action_dict->GetString(keys::kInstanceType, &instance_type)); 317 action_dict->GetString(keys::kInstanceType, &instance_type));
253 318
254 ContentActionFactory& factory = g_content_action_factory.Get(); 319 ContentActionFactory& factory = g_content_action_factory.Get();
255 std::map<std::string, ContentActionFactory::FactoryMethod>::iterator 320 std::map<std::string, ContentActionFactory::FactoryMethod>::iterator
256 factory_method_iter = factory.factory_methods.find(instance_type); 321 factory_method_iter = factory.factory_methods.find(instance_type);
257 if (factory_method_iter != factory.factory_methods.end()) 322 if (factory_method_iter != factory.factory_methods.end())
258 return (*factory_method_iter->second)( 323 return (*factory_method_iter->second)(
259 extension, action_dict, error, bad_message); 324 profile, extension, action_dict, error, bad_message);
260 325
261 *error = base::StringPrintf(kInvalidInstanceTypeError, instance_type.c_str()); 326 *error = base::StringPrintf(kInvalidInstanceTypeError, instance_type.c_str());
262 return scoped_refptr<ContentAction>(); 327 return scoped_refptr<ContentAction>();
263 } 328 }
264 329
265 } // namespace extensions 330 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698