OLD | NEW |
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" |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
55 // The following are concrete actions. | 55 // The following are concrete actions. |
56 // | 56 // |
57 | 57 |
58 // Action that instructs to show an extension's page action. | 58 // Action that instructs to show an extension's page action. |
59 class ShowPageAction : public ContentAction { | 59 class ShowPageAction : public ContentAction { |
60 public: | 60 public: |
61 ShowPageAction() {} | 61 ShowPageAction() {} |
62 | 62 |
63 static scoped_refptr<ContentAction> Create( | 63 static scoped_refptr<ContentAction> Create( |
64 content::BrowserContext* browser_context, | 64 content::BrowserContext* browser_context, |
| 65 const HostID& host_id, |
65 const Extension* extension, | 66 const Extension* extension, |
66 const base::DictionaryValue* dict, | 67 const base::DictionaryValue* dict, |
67 std::string* error, | 68 std::string* error, |
68 bool* bad_message) { | 69 bool* bad_message) { |
69 // We can't show a page action if the extension doesn't have one. | 70 // We can't show a page action if the extension doesn't have one. |
70 if (ActionInfo::GetPageActionInfo(extension) == NULL) { | 71 if (ActionInfo::GetPageActionInfo(extension) == NULL) { |
71 *error = kNoPageAction; | 72 *error = kNoPageAction; |
72 return scoped_refptr<ContentAction>(); | 73 return scoped_refptr<ContentAction>(); |
73 } | 74 } |
74 return scoped_refptr<ContentAction>(new ShowPageAction); | 75 return scoped_refptr<ContentAction>(new ShowPageAction); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
118 }; | 119 }; |
119 | 120 |
120 // Action that sets an extension's action icon. | 121 // Action that sets an extension's action icon. |
121 class SetIcon : public ContentAction { | 122 class SetIcon : public ContentAction { |
122 public: | 123 public: |
123 SetIcon(const gfx::Image& icon, ActionInfo::Type action_type) | 124 SetIcon(const gfx::Image& icon, ActionInfo::Type action_type) |
124 : icon_(icon), action_type_(action_type) {} | 125 : icon_(icon), action_type_(action_type) {} |
125 | 126 |
126 static scoped_refptr<ContentAction> Create( | 127 static scoped_refptr<ContentAction> Create( |
127 content::BrowserContext* browser_context, | 128 content::BrowserContext* browser_context, |
| 129 const HostID& host_id, |
128 const Extension* extension, | 130 const Extension* extension, |
129 const base::DictionaryValue* dict, | 131 const base::DictionaryValue* dict, |
130 std::string* error, | 132 std::string* error, |
131 bool* bad_message); | 133 bool* bad_message); |
132 | 134 |
133 // Implementation of ContentAction: | 135 // Implementation of ContentAction: |
134 Type GetType() const override { return ACTION_SET_ICON; } | 136 Type GetType() const override { return ACTION_SET_ICON; } |
135 void Apply(const std::string& extension_id, | 137 void Apply(const std::string& extension_id, |
136 const base::Time& extension_install_time, | 138 const base::Time& extension_install_time, |
137 ApplyInfo* apply_info) const override { | 139 ApplyInfo* apply_info) const override { |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
211 | 213 |
212 struct ContentActionFactory { | 214 struct ContentActionFactory { |
213 // Factory methods for ContentAction instances. |extension| is the extension | 215 // Factory methods for ContentAction instances. |extension| is the extension |
214 // for which the action is being created. |dict| contains the json dictionary | 216 // 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 | 217 // that describes the action. |error| is used to return error messages in case |
216 // the extension passed an action that was syntactically correct but | 218 // the extension passed an action that was syntactically correct but |
217 // semantically incorrect. |bad_message| is set to true in case |dict| does | 219 // semantically incorrect. |bad_message| is set to true in case |dict| does |
218 // not confirm to the validated JSON specification. | 220 // not confirm to the validated JSON specification. |
219 typedef scoped_refptr<ContentAction>(*FactoryMethod)( | 221 typedef scoped_refptr<ContentAction>(*FactoryMethod)( |
220 content::BrowserContext* /* browser_context */, | 222 content::BrowserContext* /* browser_context */, |
| 223 const HostID& host_id /* host id */, |
221 const Extension* /* extension */, | 224 const Extension* /* extension */, |
222 const base::DictionaryValue* /* dict */, | 225 const base::DictionaryValue* /* dict */, |
223 std::string* /* error */, | 226 std::string* /* error */, |
224 bool* /* bad_message */); | 227 bool* /* bad_message */); |
225 // Maps the name of a declarativeContent action type to the factory | 228 // Maps the name of a declarativeContent action type to the factory |
226 // function creating it. | 229 // function creating it. |
227 std::map<std::string, FactoryMethod> factory_methods; | 230 std::map<std::string, FactoryMethod> factory_methods; |
228 | 231 |
229 ContentActionFactory() { | 232 ContentActionFactory() { |
230 factory_methods[keys::kShowPageAction] = | 233 factory_methods[keys::kShowPageAction] = |
(...skipping 25 matching lines...) Expand all Loading... |
256 }; | 259 }; |
257 | 260 |
258 RequestContentScript::ScriptData::ScriptData() | 261 RequestContentScript::ScriptData::ScriptData() |
259 : all_frames(false), | 262 : all_frames(false), |
260 match_about_blank(false) {} | 263 match_about_blank(false) {} |
261 RequestContentScript::ScriptData::~ScriptData() {} | 264 RequestContentScript::ScriptData::~ScriptData() {} |
262 | 265 |
263 // static | 266 // static |
264 scoped_refptr<ContentAction> RequestContentScript::Create( | 267 scoped_refptr<ContentAction> RequestContentScript::Create( |
265 content::BrowserContext* browser_context, | 268 content::BrowserContext* browser_context, |
| 269 const HostID& host_id, |
266 const Extension* extension, | 270 const Extension* extension, |
267 const base::DictionaryValue* dict, | 271 const base::DictionaryValue* dict, |
268 std::string* error, | 272 std::string* error, |
269 bool* bad_message) { | 273 bool* bad_message) { |
270 ScriptData script_data; | 274 ScriptData script_data; |
271 if (!InitScriptData(dict, error, bad_message, &script_data)) | 275 if (!InitScriptData(dict, error, bad_message, &script_data)) |
272 return scoped_refptr<ContentAction>(); | 276 return scoped_refptr<ContentAction>(); |
273 | 277 |
274 return scoped_refptr<ContentAction>(new RequestContentScript( | 278 return scoped_refptr<ContentAction>(new RequestContentScript( |
275 browser_context, | 279 browser_context, |
| 280 host_id, |
276 extension, | 281 extension, |
277 script_data)); | 282 script_data)); |
278 } | 283 } |
279 | 284 |
280 // static | 285 // static |
281 scoped_refptr<ContentAction> RequestContentScript::CreateForTest( | 286 scoped_refptr<ContentAction> RequestContentScript::CreateForTest( |
282 DeclarativeUserScriptMaster* master, | 287 DeclarativeUserScriptMaster* master, |
| 288 const HostID& host_id, |
283 const Extension* extension, | 289 const Extension* extension, |
284 const base::Value& json_action, | 290 const base::Value& json_action, |
285 std::string* error, | 291 std::string* error, |
286 bool* bad_message) { | 292 bool* bad_message) { |
287 // Simulate ContentAction-level initialization. Check that instance type is | 293 // Simulate ContentAction-level initialization. Check that instance type is |
288 // RequestContentScript. | 294 // RequestContentScript. |
289 ContentAction::ResetErrorData(error, bad_message); | 295 ContentAction::ResetErrorData(error, bad_message); |
290 const base::DictionaryValue* action_dict = NULL; | 296 const base::DictionaryValue* action_dict = NULL; |
291 std::string instance_type; | 297 std::string instance_type; |
292 if (!ContentAction::Validate( | 298 if (!ContentAction::Validate( |
293 json_action, | 299 json_action, |
294 error, | 300 error, |
295 bad_message, | 301 bad_message, |
296 &action_dict, | 302 &action_dict, |
297 &instance_type) || | 303 &instance_type) || |
298 instance_type != std::string(keys::kRequestContentScript)) | 304 instance_type != std::string(keys::kRequestContentScript)) |
299 return scoped_refptr<ContentAction>(); | 305 return scoped_refptr<ContentAction>(); |
300 | 306 |
301 // Normal RequestContentScript data initialization. | 307 // Normal RequestContentScript data initialization. |
302 ScriptData script_data; | 308 ScriptData script_data; |
303 if (!InitScriptData(action_dict, error, bad_message, &script_data)) | 309 if (!InitScriptData(action_dict, error, bad_message, &script_data)) |
304 return scoped_refptr<ContentAction>(); | 310 return scoped_refptr<ContentAction>(); |
305 | 311 |
306 // Inject provided DeclarativeUserScriptMaster, rather than looking it up | 312 // Inject provided DeclarativeUserScriptMaster, rather than looking it up |
307 // using a BrowserContext. | 313 // using a BrowserContext. |
308 return scoped_refptr<ContentAction>(new RequestContentScript( | 314 return scoped_refptr<ContentAction>(new RequestContentScript( |
309 master, | 315 master, |
| 316 host_id, |
310 extension, | 317 extension, |
311 script_data)); | 318 script_data)); |
312 } | 319 } |
313 | 320 |
314 // static | 321 // static |
315 bool RequestContentScript::InitScriptData(const base::DictionaryValue* dict, | 322 bool RequestContentScript::InitScriptData(const base::DictionaryValue* dict, |
316 std::string* error, | 323 std::string* error, |
317 bool* bad_message, | 324 bool* bad_message, |
318 ScriptData* script_data) { | 325 ScriptData* script_data) { |
319 const base::ListValue* list_value = NULL; | 326 const base::ListValue* list_value = NULL; |
(...skipping 21 matching lines...) Expand all Loading... |
341 dict->GetBoolean( | 348 dict->GetBoolean( |
342 keys::kMatchAboutBlank, | 349 keys::kMatchAboutBlank, |
343 &script_data->match_about_blank)); | 350 &script_data->match_about_blank)); |
344 } | 351 } |
345 | 352 |
346 return true; | 353 return true; |
347 } | 354 } |
348 | 355 |
349 RequestContentScript::RequestContentScript( | 356 RequestContentScript::RequestContentScript( |
350 content::BrowserContext* browser_context, | 357 content::BrowserContext* browser_context, |
| 358 const HostID& host_id, |
351 const Extension* extension, | 359 const Extension* extension, |
352 const ScriptData& script_data) { | 360 const ScriptData& script_data) { |
353 InitScript(extension, script_data); | 361 InitScript(host_id, extension, script_data); |
354 | 362 |
355 master_ = ExtensionSystem::Get(browser_context) | 363 master_ = ExtensionSystem::Get(browser_context) |
356 ->declarative_user_script_manager() | 364 ->declarative_user_script_manager() |
357 ->GetDeclarativeUserScriptMasterByID(extension->id()); | 365 ->GetDeclarativeUserScriptMasterByID(host_id); |
358 AddScript(); | 366 AddScript(); |
359 } | 367 } |
360 | 368 |
361 RequestContentScript::RequestContentScript( | 369 RequestContentScript::RequestContentScript( |
362 DeclarativeUserScriptMaster* master, | 370 DeclarativeUserScriptMaster* master, |
| 371 const HostID& host_id, |
363 const Extension* extension, | 372 const Extension* extension, |
364 const ScriptData& script_data) { | 373 const ScriptData& script_data) { |
365 InitScript(extension, script_data); | 374 InitScript(host_id, extension, script_data); |
366 | 375 |
367 master_ = master; | 376 master_ = master; |
368 AddScript(); | 377 AddScript(); |
369 } | 378 } |
370 | 379 |
371 RequestContentScript::~RequestContentScript() { | 380 RequestContentScript::~RequestContentScript() { |
372 DCHECK(master_); | 381 DCHECK(master_); |
373 master_->RemoveScript(script_); | 382 master_->RemoveScript(script_); |
374 } | 383 } |
375 | 384 |
376 void RequestContentScript::InitScript(const Extension* extension, | 385 void RequestContentScript::InitScript(const HostID& host_id, |
| 386 const Extension* extension, |
377 const ScriptData& script_data) { | 387 const ScriptData& script_data) { |
378 script_.set_id(UserScript::GenerateUserScriptID()); | 388 script_.set_id(UserScript::GenerateUserScriptID()); |
379 script_.set_extension_id(extension->id()); | 389 script_.set_host_id(host_id); |
380 script_.set_run_location(UserScript::BROWSER_DRIVEN); | 390 script_.set_run_location(UserScript::BROWSER_DRIVEN); |
381 script_.set_match_all_frames(script_data.all_frames); | 391 script_.set_match_all_frames(script_data.all_frames); |
382 script_.set_match_about_blank(script_data.match_about_blank); | 392 script_.set_match_about_blank(script_data.match_about_blank); |
383 for (std::vector<std::string>::const_iterator it = | 393 for (std::vector<std::string>::const_iterator it = |
384 script_data.css_file_names.begin(); | 394 script_data.css_file_names.begin(); |
385 it != script_data.css_file_names.end(); ++it) { | 395 it != script_data.css_file_names.end(); ++it) { |
386 GURL url = extension->GetResourceURL(*it); | 396 GURL url = extension->GetResourceURL(*it); |
387 ExtensionResource resource = extension->GetResource(*it); | 397 ExtensionResource resource = extension->GetResource(*it); |
388 script_.css_scripts().push_back(UserScript::File( | 398 script_.css_scripts().push_back(UserScript::File( |
389 resource.extension_root(), resource.relative_path(), url)); | 399 resource.extension_root(), resource.relative_path(), url)); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
426 render_view_host->GetRoutingID(), | 436 render_view_host->GetRoutingID(), |
427 SessionTabHelper::IdForTab(contents), | 437 SessionTabHelper::IdForTab(contents), |
428 extension_id, | 438 extension_id, |
429 script_.id(), | 439 script_.id(), |
430 contents->GetLastCommittedURL())); | 440 contents->GetLastCommittedURL())); |
431 } | 441 } |
432 | 442 |
433 // static | 443 // static |
434 scoped_refptr<ContentAction> SetIcon::Create( | 444 scoped_refptr<ContentAction> SetIcon::Create( |
435 content::BrowserContext* browser_context, | 445 content::BrowserContext* browser_context, |
| 446 const HostID& host_id, |
436 const Extension* extension, | 447 const Extension* extension, |
437 const base::DictionaryValue* dict, | 448 const base::DictionaryValue* dict, |
438 std::string* error, | 449 std::string* error, |
439 bool* bad_message) { | 450 bool* bad_message) { |
440 // We can't set a page or action's icon if the extension doesn't have one. | 451 // We can't set a page or action's icon if the extension doesn't have one. |
441 ActionInfo::Type type; | 452 ActionInfo::Type type; |
442 if (ActionInfo::GetPageActionInfo(extension) != NULL) { | 453 if (ActionInfo::GetPageActionInfo(extension) != NULL) { |
443 type = ActionInfo::TYPE_PAGE; | 454 type = ActionInfo::TYPE_PAGE; |
444 } else if (ActionInfo::GetBrowserActionInfo(extension) != NULL) { | 455 } else if (ActionInfo::GetBrowserActionInfo(extension) != NULL) { |
445 type = ActionInfo::TYPE_BROWSER; | 456 type = ActionInfo::TYPE_BROWSER; |
(...skipping 17 matching lines...) Expand all Loading... |
463 // ContentAction | 474 // ContentAction |
464 // | 475 // |
465 | 476 |
466 ContentAction::ContentAction() {} | 477 ContentAction::ContentAction() {} |
467 | 478 |
468 ContentAction::~ContentAction() {} | 479 ContentAction::~ContentAction() {} |
469 | 480 |
470 // static | 481 // static |
471 scoped_refptr<ContentAction> ContentAction::Create( | 482 scoped_refptr<ContentAction> ContentAction::Create( |
472 content::BrowserContext* browser_context, | 483 content::BrowserContext* browser_context, |
| 484 const HostID& host_id, |
473 const Extension* extension, | 485 const Extension* extension, |
474 const base::Value& json_action, | 486 const base::Value& json_action, |
475 std::string* error, | 487 std::string* error, |
476 bool* bad_message) { | 488 bool* bad_message) { |
477 ResetErrorData(error, bad_message); | 489 ResetErrorData(error, bad_message); |
478 const base::DictionaryValue* action_dict = NULL; | 490 const base::DictionaryValue* action_dict = NULL; |
479 std::string instance_type; | 491 std::string instance_type; |
480 if (!Validate(json_action, error, bad_message, &action_dict, &instance_type)) | 492 if (!Validate(json_action, error, bad_message, &action_dict, &instance_type)) |
481 return scoped_refptr<ContentAction>(); | 493 return scoped_refptr<ContentAction>(); |
482 | 494 |
483 ContentActionFactory& factory = g_content_action_factory.Get(); | 495 ContentActionFactory& factory = g_content_action_factory.Get(); |
484 std::map<std::string, ContentActionFactory::FactoryMethod>::iterator | 496 std::map<std::string, ContentActionFactory::FactoryMethod>::iterator |
485 factory_method_iter = factory.factory_methods.find(instance_type); | 497 factory_method_iter = factory.factory_methods.find(instance_type); |
486 if (factory_method_iter != factory.factory_methods.end()) | 498 if (factory_method_iter != factory.factory_methods.end()) |
487 return (*factory_method_iter->second)( | 499 return (*factory_method_iter->second)( |
488 browser_context, extension, action_dict, error, bad_message); | 500 browser_context, host_id, extension, action_dict, error, bad_message); |
489 | 501 |
490 *error = base::StringPrintf(kInvalidInstanceTypeError, instance_type.c_str()); | 502 *error = base::StringPrintf(kInvalidInstanceTypeError, instance_type.c_str()); |
491 return scoped_refptr<ContentAction>(); | 503 return scoped_refptr<ContentAction>(); |
492 } | 504 } |
493 | 505 |
494 bool ContentAction::Validate(const base::Value& json_action, | 506 bool ContentAction::Validate(const base::Value& json_action, |
495 std::string* error, | 507 std::string* error, |
496 bool* bad_message, | 508 bool* bad_message, |
497 const base::DictionaryValue** action_dict, | 509 const base::DictionaryValue** action_dict, |
498 std::string* instance_type) { | 510 std::string* instance_type) { |
499 INPUT_FORMAT_VALIDATE(json_action.GetAsDictionary(action_dict)); | 511 INPUT_FORMAT_VALIDATE(json_action.GetAsDictionary(action_dict)); |
500 INPUT_FORMAT_VALIDATE( | 512 INPUT_FORMAT_VALIDATE( |
501 (*action_dict)->GetString(keys::kInstanceType, instance_type)); | 513 (*action_dict)->GetString(keys::kInstanceType, instance_type)); |
502 return true; | 514 return true; |
503 } | 515 } |
504 | 516 |
505 } // namespace extensions | 517 } // namespace extensions |
OLD | NEW |