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..4abea3663b63912c668c014b63f8a022385b5467 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,109 @@ 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); |
+ return new AutomationManifestPermission( |
+ make_scoped_ptr(new const AutomationInfo(desktop, matches, interact))); |
+ } |
+ |
+ 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); |
+ return new AutomationManifestPermission( |
+ make_scoped_ptr(new const AutomationInfo(desktop, matches, interact))); |
+ } |
+ |
+ 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); |
+ return new AutomationManifestPermission( |
+ make_scoped_ptr(new const AutomationInfo(desktop, matches, interact))); |
+ } |
+ |
+ private: |
+ scoped_ptr<const AutomationInfo> automation_info_; |
+}; |
+ |
AutomationHandler::AutomationHandler() { |
} |
@@ -58,6 +168,19 @@ const std::vector<std::string> AutomationHandler::Keys() const { |
return SingleKey(keys::kAutomation); |
} |
+ManifestPermission* AutomationHandler::CreatePermission() { |
+ scoped_ptr<const AutomationInfo> info(new AutomationInfo); |
Devlin
2014/07/21 19:45:35
inline |info|
aboxhall
2014/07/21 22:44:11
Done.
|
+ 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 +188,13 @@ const AutomationInfo* AutomationInfo::Get(const Extension* extension) { |
} |
// static |
+scoped_ptr<AutomationInfo> AutomationInfo::FromValue(const base::Value& value) { |
Devlin
2014/07/21 19:45:35
Is this used?
aboxhall
2014/07/21 22:44:11
Not any more! Removed.
|
+ 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 +208,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 +232,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 +243,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 +257,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(); |
Devlin
2014/07/21 19:45:35
Are you anticipating using AsManifestType more lat
aboxhall
2014/07/21 22:44:11
I'm unlikely to use it again, but I think it's mor
Devlin
2014/07/21 23:43:53
Not worried about performance; just like to keep t
|
+} |
+ |
+// static |
+scoped_ptr<Automation> AutomationInfo::AsManifestType( |
+ const AutomationInfo& info) { |
+ scoped_ptr<Automation> automation(new Automation); |
+ if (!info.desktop && !info.interact && info.matches.size() == 0) { |
+ automation->as_boolean.reset(new bool(true)); |
+ return 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 automation.Pass(); |
+} |
- return make_scoped_ptr( |
- new AutomationInfo(desktop, matches, interact, specified_matches)); |
+// static |
+scoped_ptr<const AutomationInfo> AutomationInfo::Clone( |
Devlin
2014/07/21 19:45:35
If you don't plan on using Clone() elsewhere, can
aboxhall
2014/07/21 22:44:11
Done.
|
+ const AutomationInfo& info) { |
+ const AutomationInfo* result = |
+ new AutomationInfo(info.desktop, info.matches, info.interact); |
+ return make_scoped_ptr(result); |
Devlin
2014/07/21 19:45:35
inline?
aboxhall
2014/07/21 22:44:11
Acknowledged.
|
} |
-AutomationInfo::AutomationInfo() |
- : desktop(false), interact(false), specified_matches(false) { |
+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() { |