Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / chrome / common / extensions / manifest_handlers / automation.cc
index 0338cd6..b0b795f 100644 (file)
@@ -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 "chrome/grit/generated_resources.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 "ipc/ipc_message.h"
+#include "ipc/ipc_message_utils.h"
+#include "ui/base/l10n/l10n_util.h"
 
 namespace extensions {
 
@@ -30,6 +37,133 @@ 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;
+
+  virtual std::string id() const OVERRIDE;
+
+  virtual bool HasMessages() const OVERRIDE;
+
+  virtual PermissionMessages GetMessages() const OVERRIDE;
+
+  virtual bool FromValue(const base::Value* value) OVERRIDE;
+
+  virtual scoped_ptr<base::Value> ToValue() const OVERRIDE;
+
+  virtual ManifestPermission* Diff(
+      const ManifestPermission* rhs) const OVERRIDE;
+
+  virtual ManifestPermission* Union(
+      const ManifestPermission* rhs) const OVERRIDE;
+
+  virtual ManifestPermission* Intersect(
+      const ManifestPermission* rhs) const OVERRIDE;
+
+ private:
+  scoped_ptr<const AutomationInfo> automation_info_;
+};
+
+std::string AutomationManifestPermission::name() const {
+  return keys::kAutomation;
+}
+
+std::string AutomationManifestPermission::id() const {
+  return keys::kAutomation;
+}
+
+bool AutomationManifestPermission::HasMessages() const {
+  return GetMessages().size() > 0;
+}
+
+PermissionMessages AutomationManifestPermission::GetMessages() const {
+  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, &regular_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;
+}
+
+bool AutomationManifestPermission::FromValue(const base::Value* value) {
+  base::string16 error;
+  automation_info_.reset(AutomationInfo::FromValue(*value,
+                                                   NULL /* install_warnings */,
+                                                   &error).release());
+  return error.empty();
+}
+
+scoped_ptr<base::Value> AutomationManifestPermission::ToValue() const {
+  return AutomationInfo::ToValue(*automation_info_).Pass();
+}
+
+ManifestPermission* AutomationManifestPermission::Diff(
+    const ManifestPermission* rhs) const {
+  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)));
+}
+
+ManifestPermission* AutomationManifestPermission::Union(
+    const ManifestPermission* rhs) const {
+  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)));
+}
+
+ManifestPermission* AutomationManifestPermission::Intersect(
+    const ManifestPermission* rhs) const {
+  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)));
+}
+
 AutomationHandler::AutomationHandler() {
 }
 
@@ -58,6 +192,22 @@ const std::vector<std::string> AutomationHandler::Keys() const {
   return SingleKey(keys::kAutomation);
 }
 
+ManifestPermission* AutomationHandler::CreatePermission() {
+  return new AutomationManifestPermission(
+      make_scoped_ptr(new const AutomationInfo));
+}
+
+ManifestPermission* AutomationHandler::CreateInitialRequiredPermission(
+    const Extension* extension) {
+  const AutomationInfo* info = AutomationInfo::Get(extension);
+  if (info) {
+    return new AutomationManifestPermission(
+        make_scoped_ptr(new const AutomationInfo(
+            info->desktop, info->matches, info->interact)));
+  }
+  return NULL;
+}
+
 // static
 const AutomationInfo* AutomationInfo::Get(const Extension* extension) {
   return static_cast<AutomationInfo*>(
@@ -102,6 +252,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 +263,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 +277,45 @@ 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) {
+  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();
 }
 
-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() {