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

Unified Diff: chrome/browser/extensions/api/declarative_content/content_action.cc

Issue 492133002: Renderer changes for wiring up shared memory with declarative injection (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix final nits 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/extensions/api/declarative_content/content_action.cc
diff --git a/chrome/browser/extensions/api/declarative_content/content_action.cc b/chrome/browser/extensions/api/declarative_content/content_action.cc
index 3271fdde23b568cc9803fa7668947954dd966eea..b97a29f61237b89cd6bf84b47a790074587ba718 100644
--- a/chrome/browser/extensions/api/declarative_content/content_action.cc
+++ b/chrome/browser/extensions/api/declarative_content/content_action.cc
@@ -11,16 +11,18 @@
#include "base/values.h"
#include "chrome/browser/extensions/api/declarative_content/content_constants.h"
#include "chrome/browser/extensions/api/extension_action/extension_action_api.h"
-#include "chrome/browser/extensions/declarative_user_script_master.h"
#include "chrome/browser/extensions/extension_action.h"
#include "chrome/browser/extensions/extension_action_manager.h"
#include "chrome/browser/extensions/extension_tab_util.h"
#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/sessions/session_tab_helper.h"
#include "content/public/browser/invalidate_type.h"
+#include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/extension_system.h"
#include "extensions/common/extension.h"
+#include "extensions/common/extension_messages.h"
namespace extensions {
@@ -37,7 +39,7 @@ const char kMissingParameter[] = "Missing parameter is required: %s";
#define INPUT_FORMAT_VALIDATE(test) do { \
if (!(test)) { \
*bad_message = true; \
- return scoped_refptr<ContentAction>(NULL); \
+ return false; \
} \
} while (0)
@@ -104,60 +106,6 @@ class ShowPageAction : public ContentAction {
DISALLOW_COPY_AND_ASSIGN(ShowPageAction);
};
-// Action that injects a content script.
-class RequestContentScript : public ContentAction {
- public:
- RequestContentScript(content::BrowserContext* browser_context,
- const Extension* extension,
- const std::vector<std::string>& css_file_names,
- const std::vector<std::string>& js_file_names,
- bool all_frames,
- bool match_about_blank);
-
- static scoped_refptr<ContentAction> Create(
- content::BrowserContext* browser_context,
- const Extension* extension,
- const base::DictionaryValue* dict,
- std::string* error,
- bool* bad_message);
-
- // Implementation of ContentAction:
- virtual Type GetType() const OVERRIDE {
- return ACTION_REQUEST_CONTENT_SCRIPT;
- }
-
- virtual void Apply(const std::string& extension_id,
- const base::Time& extension_install_time,
- ApplyInfo* apply_info) const OVERRIDE {
- InstructRenderProcessToInject(apply_info->tab, extension_id);
- }
-
- virtual void Reapply(const std::string& extension_id,
- const base::Time& extension_install_time,
- ApplyInfo* apply_info) const OVERRIDE {
- InstructRenderProcessToInject(apply_info->tab, extension_id);
- }
-
- virtual void Revert(const std::string& extension_id,
- const base::Time& extension_install_time,
- ApplyInfo* apply_info) const OVERRIDE {
- }
-
- private:
- virtual ~RequestContentScript() {
- DCHECK(master_);
- master_->RemoveScript(script_);
- }
-
- void InstructRenderProcessToInject(content::WebContents* contents,
- const std::string& extension_id) const;
-
- UserScript script_;
- DeclarativeUserScriptMaster* master_;
-
- DISALLOW_COPY_AND_ASSIGN(RequestContentScript);
-};
-
// Helper for getting JS collections into C++.
static bool AppendJSStringsToCPPStrings(const base::ListValue& append_strings,
std::vector<std::string>* append_to) {
@@ -175,6 +123,43 @@ static bool AppendJSStringsToCPPStrings(const base::ListValue& append_strings,
return true;
}
+struct ContentActionFactory {
+ // Factory methods for ContentAction instances. |extension| is the extension
+ // for which the action is being created. |dict| contains the json dictionary
+ // that describes the action. |error| is used to return error messages in case
+ // the extension passed an action that was syntactically correct but
+ // semantically incorrect. |bad_message| is set to true in case |dict| does
+ // not confirm to the validated JSON specification.
+ typedef scoped_refptr<ContentAction>(*FactoryMethod)(
+ content::BrowserContext* /* browser_context */,
+ const Extension* /* extension */,
+ const base::DictionaryValue* /* dict */,
+ std::string* /* error */,
+ bool* /* bad_message */);
+ // Maps the name of a declarativeContent action type to the factory
+ // function creating it.
+ std::map<std::string, FactoryMethod> factory_methods;
+
+ ContentActionFactory() {
+ factory_methods[keys::kShowPageAction] =
+ &ShowPageAction::Create;
+ factory_methods[keys::kRequestContentScript] =
+ &RequestContentScript::Create;
+ }
+};
+
+base::LazyInstance<ContentActionFactory>::Leaky
+ g_content_action_factory = LAZY_INSTANCE_INITIALIZER;
+
+} // namespace
+
+//
+// RequestContentScript
+//
+
+RequestContentScript::ScriptData::ScriptData() {}
+RequestContentScript::ScriptData::~ScriptData() {}
+
// static
scoped_refptr<ContentAction> RequestContentScript::Create(
content::BrowserContext* browser_context,
@@ -182,112 +167,168 @@ scoped_refptr<ContentAction> RequestContentScript::Create(
const base::DictionaryValue* dict,
std::string* error,
bool* bad_message) {
- std::vector<std::string> css_file_names;
- std::vector<std::string> js_file_names;
- bool all_frames = false;
- bool match_about_blank = false;
- const base::ListValue* list_value;
+ ScriptData script_data;
+ if (!InitScriptData(dict, error, bad_message, &script_data))
+ return scoped_refptr<ContentAction>();
+
+ return scoped_refptr<ContentAction>(new RequestContentScript(
+ browser_context,
+ extension,
+ script_data));
+}
+
+// static
+scoped_refptr<ContentAction> RequestContentScript::CreateForTest(
+ DeclarativeUserScriptMaster* master,
+ const Extension* extension,
+ const base::Value& json_action,
+ std::string* error,
+ bool* bad_message) {
+ // Simulate ContentAction-level initialization. Check that instance type is
+ // RequestContentScript.
+ ContentAction::ResetErrorData(error, bad_message);
+ const base::DictionaryValue* action_dict = NULL;
+ std::string instance_type;
+ if (!ContentAction::Validate(
+ json_action,
+ error,
+ bad_message,
+ &action_dict,
+ &instance_type) ||
+ instance_type != std::string(keys::kRequestContentScript))
+ return scoped_refptr<ContentAction>();
+
+ // Normal RequestContentScript data initialization.
+ ScriptData script_data;
+ if (!InitScriptData(action_dict, error, bad_message, &script_data))
+ return scoped_refptr<ContentAction>();
+
+ // Inject provided DeclarativeUserScriptMaster, rather than looking it up
+ // using a BrowserContext.
+ return scoped_refptr<ContentAction>(new RequestContentScript(
+ master,
+ extension,
+ script_data));
+}
+
+// static
+bool RequestContentScript::InitScriptData(const base::DictionaryValue* dict,
+ std::string* error,
+ bool* bad_message,
+ ScriptData* script_data) {
+ const base::ListValue* list_value = NULL;
if (!dict->HasKey(keys::kCss) && !dict->HasKey(keys::kJs)) {
*error = base::StringPrintf(kMissingParameter, "css or js");
- return scoped_refptr<ContentAction>();
+ return false;
}
if (dict->HasKey(keys::kCss)) {
INPUT_FORMAT_VALIDATE(dict->GetList(keys::kCss, &list_value));
INPUT_FORMAT_VALIDATE(
- AppendJSStringsToCPPStrings(*list_value, &css_file_names));
+ AppendJSStringsToCPPStrings(*list_value, &script_data->css_file_names));
}
if (dict->HasKey(keys::kJs)) {
INPUT_FORMAT_VALIDATE(dict->GetList(keys::kJs, &list_value));
INPUT_FORMAT_VALIDATE(
- AppendJSStringsToCPPStrings(*list_value, &js_file_names));
+ AppendJSStringsToCPPStrings(*list_value, &script_data->js_file_names));
}
if (dict->HasKey(keys::kAllFrames)) {
- INPUT_FORMAT_VALIDATE(dict->GetBoolean(keys::kAllFrames, &all_frames));
+ INPUT_FORMAT_VALIDATE(
+ dict->GetBoolean(keys::kAllFrames, &script_data->all_frames));
}
if (dict->HasKey(keys::kMatchAboutBlank)) {
INPUT_FORMAT_VALIDATE(
- dict->GetBoolean(keys::kMatchAboutBlank, &match_about_blank));
+ dict->GetBoolean(
+ keys::kMatchAboutBlank,
+ &script_data->match_about_blank));
}
- return scoped_refptr<ContentAction>(new RequestContentScript(
- browser_context,
- extension,
- css_file_names,
- js_file_names,
- all_frames,
- match_about_blank));
+ return true;
}
RequestContentScript::RequestContentScript(
content::BrowserContext* browser_context,
const Extension* extension,
- const std::vector<std::string>& css_file_names,
- const std::vector<std::string>& js_file_names,
- bool all_frames,
- bool match_about_blank) {
+ const ScriptData& script_data) {
+ InitScript(extension, script_data);
+
+ master_ =
+ ExtensionSystem::Get(browser_context)->
+ GetDeclarativeUserScriptMasterByExtension(extension->id());
+ AddScript();
+}
+
+RequestContentScript::RequestContentScript(
+ DeclarativeUserScriptMaster* master,
+ const Extension* extension,
+ const ScriptData& script_data) {
+ InitScript(extension, script_data);
+
+ master_ = master;
+ AddScript();
+}
+
+RequestContentScript::~RequestContentScript() {
+ DCHECK(master_);
+ master_->RemoveScript(script_);
+}
+
+void RequestContentScript::InitScript(const Extension* extension,
+ const ScriptData& script_data) {
script_.set_id(UserScript::GenerateUserScriptID());
script_.set_extension_id(extension->id());
script_.set_run_location(UserScript::BROWSER_DRIVEN);
- script_.set_match_all_frames(all_frames);
- script_.set_match_about_blank(match_about_blank);
- for (std::vector<std::string>::const_iterator it = css_file_names.begin();
- it != css_file_names.end(); ++it) {
+ script_.set_match_all_frames(script_data.all_frames);
+ script_.set_match_about_blank(script_data.match_about_blank);
+ for (std::vector<std::string>::const_iterator it =
+ script_data.css_file_names.begin();
+ it != script_data.css_file_names.end(); ++it) {
GURL url = extension->GetResourceURL(*it);
ExtensionResource resource = extension->GetResource(*it);
script_.css_scripts().push_back(UserScript::File(
resource.extension_root(), resource.relative_path(), url));
}
- for (std::vector<std::string>::const_iterator it = js_file_names.begin();
- it != js_file_names.end(); ++it) {
+ for (std::vector<std::string>::const_iterator it =
+ script_data.js_file_names.begin();
+ it != script_data.js_file_names.end(); ++it) {
GURL url = extension->GetResourceURL(*it);
ExtensionResource resource = extension->GetResource(*it);
script_.js_scripts().push_back(UserScript::File(
resource.extension_root(), resource.relative_path(), url));
}
-
- master_ =
- ExtensionSystem::Get(browser_context)->
- GetDeclarativeUserScriptMasterByExtension(extension->id());
- DCHECK(master_);
- master_->AddScript(script_);
}
-void RequestContentScript::InstructRenderProcessToInject(
- content::WebContents* contents,
- const std::string& extension_id) const {
- // TODO(markdittmer): Send ExtensionMsg to renderer.
+ContentAction::Type RequestContentScript::GetType() const {
+ return ACTION_REQUEST_CONTENT_SCRIPT;
}
-struct ContentActionFactory {
- // Factory methods for ContentAction instances. |extension| is the extension
- // for which the action is being created. |dict| contains the json dictionary
- // that describes the action. |error| is used to return error messages in case
- // the extension passed an action that was syntactically correct but
- // semantically incorrect. |bad_message| is set to true in case |dict| does
- // not confirm to the validated JSON specification.
- typedef scoped_refptr<ContentAction>(*FactoryMethod)(
- content::BrowserContext* /* browser_context */,
- const Extension* /* extension */,
- const base::DictionaryValue* /* dict */,
- std::string* /* error */,
- bool* /* bad_message */);
- // Maps the name of a declarativeContent action type to the factory
- // function creating it.
- std::map<std::string, FactoryMethod> factory_methods;
+void RequestContentScript::Apply(const std::string& extension_id,
+ const base::Time& extension_install_time,
+ ApplyInfo* apply_info) const {
+ InstructRenderProcessToInject(apply_info->tab, extension_id);
+}
- ContentActionFactory() {
- factory_methods[keys::kShowPageAction] =
- &ShowPageAction::Create;
- factory_methods[keys::kRequestContentScript] =
- &RequestContentScript::Create;
- }
-};
+void RequestContentScript::Reapply(const std::string& extension_id,
+ const base::Time& extension_install_time,
+ ApplyInfo* apply_info) const {
+ InstructRenderProcessToInject(apply_info->tab, extension_id);
+}
-base::LazyInstance<ContentActionFactory>::Leaky
- g_content_action_factory = LAZY_INSTANCE_INITIALIZER;
+void RequestContentScript::Revert(const std::string& extension_id,
+ const base::Time& extension_install_time,
+ ApplyInfo* apply_info) const {}
-} // namespace
+void RequestContentScript::InstructRenderProcessToInject(
+ content::WebContents* contents,
+ const std::string& extension_id) const {
+ content::RenderViewHost* render_view_host = contents->GetRenderViewHost();
+ render_view_host->Send(new ExtensionMsg_ExecuteDeclarativeScript(
+ render_view_host->GetRoutingID(),
+ SessionTabHelper::IdForTab(contents),
+ extension_id,
+ script_.id(),
+ contents->GetLastCommittedURL()));
+}
//
// ContentAction
@@ -304,15 +345,11 @@ scoped_refptr<ContentAction> ContentAction::Create(
const base::Value& json_action,
std::string* error,
bool* bad_message) {
- *error = "";
- *bad_message = false;
-
+ ResetErrorData(error, bad_message);
const base::DictionaryValue* action_dict = NULL;
- INPUT_FORMAT_VALIDATE(json_action.GetAsDictionary(&action_dict));
-
std::string instance_type;
- INPUT_FORMAT_VALIDATE(
- action_dict->GetString(keys::kInstanceType, &instance_type));
+ if (!Validate(json_action, error, bad_message, &action_dict, &instance_type))
+ return scoped_refptr<ContentAction>();
ContentActionFactory& factory = g_content_action_factory.Get();
std::map<std::string, ContentActionFactory::FactoryMethod>::iterator
@@ -325,4 +362,15 @@ scoped_refptr<ContentAction> ContentAction::Create(
return scoped_refptr<ContentAction>();
}
+bool ContentAction::Validate(const base::Value& json_action,
+ std::string* error,
+ bool* bad_message,
+ const base::DictionaryValue** action_dict,
+ std::string* instance_type) {
+ INPUT_FORMAT_VALIDATE(json_action.GetAsDictionary(action_dict));
+ INPUT_FORMAT_VALIDATE(
+ (*action_dict)->GetString(keys::kInstanceType, instance_type));
+ return true;
+}
+
} // namespace extensions

Powered by Google App Engine
This is Rietveld 408576698