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