| 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..9003447f9f1f003d8868b8724c3026f5184de49b 100644
|
| --- a/chrome/common/extensions/manifest_handlers/automation.cc
|
| +++ b/chrome/common/extensions/manifest_handlers/automation.cc
|
| @@ -4,14 +4,21 @@
|
|
|
| #include "chrome/common/extensions/manifest_handlers/automation.h"
|
|
|
| -#include "base/strings/string_number_conversions.h"
|
| #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 "ipc/ipc_message_utils.h"
|
| +#include "ui/base/l10n/l10n_util.h"
|
|
|
| namespace extensions {
|
|
|
| @@ -30,6 +37,126 @@ namespace errors = manifest_errors;
|
| namespace keys = extensions::manifest_keys;
|
| using api::manifest_types::Automation;
|
|
|
| +class AutomationManifestPermission : public ManifestPermission {
|
| + 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* 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 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;
|
| + }
|
| +
|
| + private:
|
| + scoped_ptr<const AutomationInfo> automation_info_;
|
| +};
|
| +
|
| AutomationHandler::AutomationHandler() {
|
| }
|
|
|
| @@ -58,6 +185,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 +205,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 +225,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 +249,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 +260,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 +274,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, specified_matches));
|
| + return make_scoped_ptr(new AutomationInfo(desktop, matches, interact));
|
| }
|
|
|
| -AutomationInfo::AutomationInfo()
|
| - : desktop(false), interact(false), specified_matches(false) {
|
| +// static
|
| +scoped_ptr<base::Value> AutomationInfo::ToValue(const AutomationInfo& info) {
|
| + return AsManifestType(info)->ToValue().Pass();
|
| +}
|
| +
|
| +// 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();
|
| }
|
| +
|
| +// static
|
| +scoped_ptr<const AutomationInfo> AutomationInfo::Clone(
|
| + const AutomationInfo& info) {
|
| + const AutomationInfo* result =
|
| + new AutomationInfo(info.desktop, info.matches, info.interact);
|
| + return make_scoped_ptr(result);
|
| +}
|
| +
|
| +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() {
|
|
|