| 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 |