Chromium Code Reviews| Index: chrome/common/extensions/manifest_handlers/automation.cc |
| diff --git a/chrome/common/extensions/manifest_handlers/automation.cc b/chrome/common/extensions/manifest_handlers/automation.cc |
| index 0338cd69bdebcfdb9f4d5fe79424695ea83e7505..8bc558dc788301d994d6feedde88047e6b89f057 100644 |
| --- a/chrome/common/extensions/manifest_handlers/automation.cc |
| +++ b/chrome/common/extensions/manifest_handlers/automation.cc |
| @@ -8,10 +8,17 @@ |
| #include "base/strings/utf_string_conversions.h" |
| #include "chrome/common/extensions/api/manifest_types.h" |
| #include "extensions/common/error_utils.h" |
| +#include "extensions/common/extensions_client.h" |
| #include "extensions/common/manifest_constants.h" |
| #include "extensions/common/permissions/api_permission_set.h" |
| +#include "extensions/common/permissions/manifest_permission.h" |
| +#include "extensions/common/permissions/permission_message.h" |
| +#include "extensions/common/permissions/permission_message_util.h" |
| #include "extensions/common/permissions/permissions_data.h" |
| #include "extensions/common/url_pattern.h" |
| +#include "grit/generated_resources.h" |
| +#include "ipc/ipc_message.h" |
| +#include "ui/base/l10n/l10n_util.h" |
| namespace extensions { |
| @@ -30,6 +37,159 @@ namespace errors = manifest_errors; |
| namespace keys = extensions::manifest_keys; |
| using api::manifest_types::Automation; |
| +class AutomationManifestPermission : public ManifestPermission { |
|
David Tseng
2014/07/08 18:37:39
I personally would prefer if this class lived in i
aboxhall
2014/07/18 15:55:15
Yeah, I'm in two minds about this, and there are e
|
| + public: |
| + explicit AutomationManifestPermission( |
| + scoped_ptr<const AutomationInfo> automation_info) |
| + : automation_info_(automation_info.Pass()) {} |
| + |
| + // extensions::ManifestPermission overrides. |
| + virtual std::string name() const OVERRIDE { return keys::kAutomation; } |
| + |
| + virtual std::string id() const OVERRIDE { return keys::kAutomation; } |
| + |
| + virtual bool HasMessages() const OVERRIDE { return GetMessages().size() > 0; } |
| + |
| + virtual PermissionMessages GetMessages() const OVERRIDE { |
| + PermissionMessages messages; |
| + if (automation_info_->desktop) { |
| + messages.push_back(PermissionMessage( |
| + PermissionMessage::kFullAccess, |
| + l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_FULL_ACCESS))); |
| + } else if (automation_info_->matches.MatchesAllURLs()) { |
| + messages.push_back(PermissionMessage( |
| + PermissionMessage::kHostsAll, |
| + l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_ALL_HOSTS))); |
| + } else { |
| + URLPatternSet regular_hosts; |
| + std::set<PermissionMessage> message_set; |
| + ExtensionsClient::Get()->FilterHostPermissions( |
| + automation_info_->matches, ®ular_hosts, &message_set); |
| + messages.insert(messages.end(), message_set.begin(), message_set.end()); |
| + |
| + std::set<std::string> hosts = |
| + permission_message_util::GetDistinctHosts(regular_hosts, true, true); |
| + if (!hosts.empty()) |
| + messages.push_back(permission_message_util::CreateFromHostList(hosts)); |
| + } |
| + |
| + return messages; |
| + } |
| + |
| + virtual bool FromValue(const base::Value* value) OVERRIDE { |
| + base::string16 error; |
| + automation_info_.reset( |
| + AutomationInfo::FromValue(*value, NULL /* install_warnings */, &error) |
| + .release()); |
| + return error.empty(); |
| + } |
| + |
| + virtual scoped_ptr<base::Value> ToValue() const OVERRIDE { |
| + return AutomationInfo::ToValue(*automation_info_).Pass(); |
| + } |
| + |
| + virtual ManifestPermission* Clone() const OVERRIDE { |
| + scoped_ptr<const AutomationInfo> info( |
| + AutomationInfo::Clone(*automation_info_.get())); |
| + return new AutomationManifestPermission(info.Pass()); |
| + } |
| + |
| + virtual ManifestPermission* Diff( |
| + const ManifestPermission* rhs) const OVERRIDE { |
| + const AutomationManifestPermission* other = |
| + static_cast<const AutomationManifestPermission*>(rhs); |
| + |
| + bool desktop = |
| + automation_info_->desktop && !other->automation_info_->desktop; |
| + bool interact = |
| + automation_info_->interact && !other->automation_info_->interact; |
| + URLPatternSet matches; |
| + URLPatternSet::CreateDifference( |
| + automation_info_->matches, other->automation_info_->matches, &matches); |
| + scoped_ptr<const AutomationInfo> info( |
| + new AutomationInfo(desktop, matches, interact)); |
| + return new AutomationManifestPermission(info.Pass()); |
| + } |
| + |
| + virtual ManifestPermission* Union( |
| + const ManifestPermission* rhs) const OVERRIDE { |
| + const AutomationManifestPermission* other = |
| + static_cast<const AutomationManifestPermission*>(rhs); |
| + |
| + bool desktop = |
| + automation_info_->desktop || other->automation_info_->desktop; |
| + bool interact = |
| + automation_info_->interact || other->automation_info_->interact; |
| + URLPatternSet matches; |
| + URLPatternSet::CreateUnion( |
| + automation_info_->matches, other->automation_info_->matches, &matches); |
| + scoped_ptr<const AutomationInfo> info( |
| + new AutomationInfo(desktop, matches, interact)); |
| + return new AutomationManifestPermission(info.Pass()); |
| + } |
| + |
| + virtual ManifestPermission* Intersect( |
| + const ManifestPermission* rhs) const OVERRIDE { |
| + const AutomationManifestPermission* other = |
| + static_cast<const AutomationManifestPermission*>(rhs); |
| + |
| + bool desktop = |
| + automation_info_->desktop && other->automation_info_->desktop; |
| + bool interact = |
| + automation_info_->interact && other->automation_info_->interact; |
| + URLPatternSet matches; |
| + URLPatternSet::CreateIntersection( |
| + automation_info_->matches, other->automation_info_->matches, &matches); |
| + scoped_ptr<const AutomationInfo> info( |
| + new AutomationInfo(desktop, matches, interact)); |
| + return new AutomationManifestPermission(info.Pass()); |
| + } |
| + |
| + virtual bool Contains(const ManifestPermission* rhs) const OVERRIDE { |
| + const AutomationManifestPermission* other = |
| + static_cast<const AutomationManifestPermission*>(rhs); |
| + |
| + bool contains_desktop = |
| + automation_info_->desktop || !other->automation_info_->desktop; |
| + bool contains_interact = |
| + automation_info_->interact || !other->automation_info_->interact; |
| + bool contains_matches = |
| + automation_info_->matches.Contains(other->automation_info_->matches); |
| + |
| + return contains_desktop && contains_interact && contains_matches; |
| + } |
| + |
| + virtual bool Equal(const ManifestPermission* rhs) const OVERRIDE { |
| + const AutomationManifestPermission* other = |
| + static_cast<const AutomationManifestPermission*>(rhs); |
| + |
| + bool same_desktop = |
| + automation_info_->desktop == other->automation_info_->desktop; |
| + bool same_interact = |
| + automation_info_->interact == other->automation_info_->interact; |
| + bool same_matches = |
| + automation_info_->matches == other->automation_info_->matches; |
| + |
| + return same_desktop && same_interact && same_matches; |
| + } |
| + |
| + virtual void Write(IPC::Message* m) const OVERRIDE { |
| + // IPC::WriteParam(m); |
| + } |
| + |
| + virtual bool Read(const IPC::Message* m, PickleIterator* iter) OVERRIDE { |
| + // return IPC::ReadParam(m, iter, &override_bookmarks_ui_permission_); |
| + return false; |
| + } |
| + |
| + virtual void Log(std::string* log) const OVERRIDE { |
| + // IPC::LogParam(override_bookmarks_ui_permission_, log); |
| + } |
| + |
| + private: |
| + scoped_ptr<const AutomationInfo> automation_info_; |
| +}; |
| + |
| AutomationHandler::AutomationHandler() { |
| } |
| @@ -58,6 +218,19 @@ const std::vector<std::string> AutomationHandler::Keys() const { |
| return SingleKey(keys::kAutomation); |
| } |
| +ManifestPermission* AutomationHandler::CreatePermission() { |
| + scoped_ptr<const AutomationInfo> info(new AutomationInfo); |
| + return new AutomationManifestPermission(info.Pass()); |
| +} |
| + |
| +ManifestPermission* AutomationHandler::CreateInitialRequiredPermission( |
| + const Extension* extension) { |
| + const AutomationInfo* info = AutomationInfo::Get(extension); |
| + if (info) |
| + return new AutomationManifestPermission(AutomationInfo::Clone(*info)); |
| + return NULL; |
| +} |
| + |
| // static |
| const AutomationInfo* AutomationInfo::Get(const Extension* extension) { |
| return static_cast<AutomationInfo*>( |
| @@ -65,6 +238,13 @@ const AutomationInfo* AutomationInfo::Get(const Extension* extension) { |
| } |
| // static |
| +scoped_ptr<AutomationInfo> AutomationInfo::FromValue(const base::Value& value) { |
| + std::vector<InstallWarning> install_warnings; |
| + base::string16 error; |
| + return AutomationInfo::FromValue(value, &install_warnings, &error); |
| +} |
| + |
| +// static |
| scoped_ptr<AutomationInfo> AutomationInfo::FromValue( |
| const base::Value& value, |
| std::vector<InstallWarning>* install_warnings, |
| @@ -78,7 +258,7 @@ scoped_ptr<AutomationInfo> AutomationInfo::FromValue( |
| return make_scoped_ptr(new AutomationInfo()); |
| return scoped_ptr<AutomationInfo>(); |
| } |
| - const Automation::Object& automation_object = *automation->as_object; |
| + Automation::Object& automation_object = *automation->as_object; |
| bool desktop = false; |
| bool interact = false; |
| @@ -102,6 +282,7 @@ scoped_ptr<AutomationInfo> AutomationInfo::FromValue( |
| InstallWarning(automation_errors::kErrorDesktopTrueMatchesSpecified)); |
| } else { |
| specified_matches = true; |
| + |
| for (std::vector<std::string>::iterator it = |
| automation_object.matches->begin(); |
| it != automation_object.matches->end(); |
| @@ -112,6 +293,7 @@ scoped_ptr<AutomationInfo> AutomationInfo::FromValue( |
| URLPattern pattern(URLPattern::SCHEME_ALL & |
| ~URLPattern::SCHEME_CHROMEUI); |
| URLPattern::ParseResult parse_result = pattern.Parse(*it); |
| + |
| if (parse_result != URLPattern::PARSE_SUCCESS) { |
| install_warnings->push_back( |
| InstallWarning(ErrorUtils::FormatErrorMessage( |
| @@ -125,25 +307,53 @@ scoped_ptr<AutomationInfo> AutomationInfo::FromValue( |
| } |
| } |
| } |
| - if (specified_matches && matches.is_empty()) |
| + if (specified_matches && matches.is_empty()) { |
| install_warnings->push_back( |
| InstallWarning(automation_errors::kErrorNoMatchesProvided)); |
| + } |
| + |
| + return make_scoped_ptr(new AutomationInfo(desktop, matches, interact)); |
| +} |
| + |
| +// static |
| +scoped_ptr<base::Value> AutomationInfo::ToValue(const AutomationInfo& info) { |
| + return AsManifestType(info)->ToValue().Pass(); |
| +} |
| - return make_scoped_ptr( |
| - new AutomationInfo(desktop, matches, interact, specified_matches)); |
| +// static |
| +scoped_ptr<Automation> AutomationInfo::AsManifestType( |
| + const AutomationInfo& info) { |
| + Automation* automation = new Automation; |
| + if (!info.desktop && !info.interact && info.matches.size() == 0) { |
| + automation->as_boolean.reset(new bool(true)); |
| + return make_scoped_ptr(automation).Pass(); |
| + } |
| + |
| + Automation::Object* as_object = new Automation::Object; |
| + as_object->desktop.reset(new bool(info.desktop)); |
| + as_object->interact.reset(new bool(info.interact)); |
| + if (info.matches.size() > 0) { |
| + as_object->matches.reset(info.matches.ToStringVector().release()); |
| + } |
| + automation->as_object.reset(as_object); |
| + return make_scoped_ptr(automation).Pass(); |
| } |
| -AutomationInfo::AutomationInfo() |
| - : desktop(false), interact(false), specified_matches(false) { |
| +// static |
| +scoped_ptr<const AutomationInfo> AutomationInfo::Clone( |
| + const AutomationInfo& info) { |
| + scoped_ptr<base::Value> value = AutomationInfo::ToValue(info); |
| + scoped_ptr<const AutomationInfo> result(AutomationInfo::FromValue(*value)); |
| + return result.Pass(); |
| +} |
| + |
| +AutomationInfo::AutomationInfo() : desktop(false), interact(false) { |
| } |
| + |
| AutomationInfo::AutomationInfo(bool desktop, |
| - const URLPatternSet& matches, |
| - bool interact, |
| - bool specified_matches) |
| - : desktop(desktop), |
| - matches(matches), |
| - interact(interact), |
| - specified_matches(specified_matches) { |
| + const URLPatternSet matches, |
| + bool interact) |
| + : desktop(desktop), matches(matches), interact(interact) { |
| } |
| AutomationInfo::~AutomationInfo() { |