Index: chrome/common/extensions/background_info.cc |
diff --git a/chrome/common/extensions/background_info.cc b/chrome/common/extensions/background_info.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..9dab0c60177c3c61caf754f2077fa9c5866ebe78 |
--- /dev/null |
+++ b/chrome/common/extensions/background_info.cc |
@@ -0,0 +1,260 @@ |
+// Copyright (c) 2013 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "chrome/common/extensions/background_info.h" |
+ |
+#include "base/command_line.h" |
+#include "base/lazy_instance.h" |
+#include "base/memory/scoped_ptr.h" |
+#include "base/string_number_conversions.h" |
+#include "base/utf_string_conversions.h" |
+#include "chrome/common/chrome_switches.h" |
+#include "chrome/common/extensions/extension_constants.h" |
+#include "chrome/common/extensions/extension_manifest_constants.h" |
+#include "chrome/common/extensions/permissions/api_permission_set.h" |
+#include "extensions/common/error_utils.h" |
+ |
+using base::DictionaryValue; |
+namespace keys = extension_manifest_keys; |
+namespace values = extension_manifest_values; |
+namespace errors = extension_manifest_errors; |
+ |
+namespace extensions { |
+ |
+namespace { |
+ |
+const char kBackground[] = "background"; |
+ |
+static base::LazyInstance<BackgroundInfo> g_empty_background_info = |
+ LAZY_INSTANCE_INITIALIZER; |
+ |
+const BackgroundInfo& GetBackgroundInfo(const Extension* extension) { |
+ BackgroundInfo* info = static_cast<BackgroundInfo*>( |
+ extension->GetManifestData(kBackground)); |
+ if (!info) |
+ return g_empty_background_info.Get(); |
+ return *info; |
+} |
+ |
+bool LoadBackgroundScripts(const Extension* extension, |
+ const std::string& key, |
+ string16* error, |
+ BackgroundInfo* info) { |
+ const Value* background_scripts_value = NULL; |
+ if (!extension->manifest()->Get(key, &background_scripts_value)) |
+ return true; |
+ |
+ CHECK(background_scripts_value); |
+ if (background_scripts_value->GetType() != Value::TYPE_LIST) { |
+ *error = ASCIIToUTF16(errors::kInvalidBackgroundScripts); |
+ return false; |
+ } |
+ |
+ const ListValue* background_scripts = NULL; |
+ background_scripts_value->GetAsList(&background_scripts); |
+ for (size_t i = 0; i < background_scripts->GetSize(); ++i) { |
+ std::string script; |
+ if (!background_scripts->GetString(i, &script)) { |
+ *error = ErrorUtils::FormatErrorMessageUTF16( |
+ errors::kInvalidBackgroundScript, base::IntToString(i)); |
+ return false; |
+ } |
+ info->background_scripts.push_back(script); |
+ } |
+ |
+ return true; |
+} |
+ |
+bool LoadBackgroundPage(Extension* extension, |
+ const std::string& key, |
+ string16* error, |
+ BackgroundInfo* info) { |
+ const base::Value* background_page_value = NULL; |
+ if (!extension->manifest()->Get(key, &background_page_value)) |
+ return true; |
+ |
+ if (!info->background_scripts.empty()) { |
+ *error = ASCIIToUTF16(errors::kInvalidBackgroundCombination); |
+ return false; |
+ } |
+ |
+ std::string background_str; |
+ if (!background_page_value->GetAsString(&background_str)) { |
+ *error = ASCIIToUTF16(errors::kInvalidBackground); |
+ return false; |
+ } |
+ |
+ if (extension->is_hosted_app()) { |
+ info->background_url = GURL(background_str); |
+ |
+ if (!extension->initial_api_permissions()->count( |
+ APIPermission::kBackground)) { |
+ *error = ASCIIToUTF16(errors::kBackgroundPermissionNeeded); |
+ return false; |
+ } |
+ // Hosted apps require an absolute URL. |
+ if (!info->background_url.is_valid()) { |
+ *error = ASCIIToUTF16(errors::kInvalidBackgroundInHostedApp); |
+ return false; |
+ } |
+ |
+ if (!(info->background_url.SchemeIs("https") || |
+ (CommandLine::ForCurrentProcess()->HasSwitch( |
+ switches::kAllowHTTPBackgroundPage) && |
+ info->background_url.SchemeIs("http")))) { |
+ *error = ASCIIToUTF16(errors::kInvalidBackgroundInHostedApp); |
+ return false; |
+ } |
+ } else { |
+ info->background_url = extension->GetResourceURL(background_str); |
+ } |
+ |
+ return true; |
+} |
+ |
+bool LoadBackgroundPage(Extension* extension, |
+ string16* error, |
+ BackgroundInfo* info) { |
+ if (extension->is_platform_app()) { |
+ return LoadBackgroundPage( |
+ extension, keys::kPlatformAppBackgroundPage, error, info); |
+ } |
+ |
+ if (!LoadBackgroundPage( |
+ extension, keys::kBackgroundPage, error, info)) { |
+ return false; |
+ } |
+ if (info->background_url.is_empty()) { |
+ return LoadBackgroundPage( |
+ extension, keys::kBackgroundPageLegacy, error, info); |
+ } |
+ return true; |
+} |
+ |
+bool LoadBackgroundPersistent(const Extension* extension, |
+ string16* error, |
+ BackgroundInfo* info) { |
+ if (extension->is_platform_app()) { |
+ info->is_persistent = false; |
+ return true; |
+ } |
+ |
+ const Value* background_persistent = NULL; |
+ if (!extension->manifest()->Get(keys::kBackgroundPersistent, |
+ &background_persistent)) |
+ return true; |
+ |
+ if (!background_persistent->GetAsBoolean(&info->is_persistent)) { |
+ *error = ASCIIToUTF16(errors::kInvalidBackgroundPersistent); |
+ return false; |
+ } |
+ |
+ if (!info->has_background_page()) { |
+ *error = ASCIIToUTF16(errors::kInvalidBackgroundPersistentNoPage); |
+ return false; |
+ } |
+ |
+ return true; |
+} |
+ |
+bool LoadBackgroundAllowJSAccess(const Extension* extension, |
+ string16* error, |
+ BackgroundInfo* info) { |
+ const Value* allow_js_access = NULL; |
+ if (!extension->manifest()->Get(keys::kBackgroundAllowJsAccess, |
+ &allow_js_access)) |
+ return true; |
+ |
+ if (!allow_js_access->IsType(Value::TYPE_BOOLEAN) || |
+ !allow_js_access->GetAsBoolean(&info->allow_js_access)) { |
+ *error = ASCIIToUTF16(errors::kInvalidBackgroundAllowJsAccess); |
+ return false; |
+ } |
+ |
+ return true; |
+} |
+ |
+} // namespace |
+ |
+BackgroundInfo::BackgroundInfo() |
+ : is_persistent(true), |
+ allow_js_access(true) { |
+} |
+ |
+BackgroundInfo::~BackgroundInfo() { |
+} |
+ |
+// static |
+GURL BackgroundInfo::GetBackgroundURL(const Extension* extension) { |
+ const BackgroundInfo& info = GetBackgroundInfo(extension); |
+ if (info.background_scripts.empty()) |
+ return info.background_url; |
+ return extension->GetResourceURL( |
+ extension_filenames::kGeneratedBackgroundPageFilename); |
+} |
+ |
+// static |
+const std::vector<std::string>& BackgroundInfo::GetBackgroundScripts( |
+ const Extension* extension) { |
+ return GetBackgroundInfo(extension).background_scripts; |
+} |
+ |
+// static |
+bool BackgroundInfo::HasBackgroundPage(const Extension* extension) { |
+ return GetBackgroundInfo(extension).has_background_page(); |
+} |
+ |
+// static |
+bool BackgroundInfo::AllowJSAccess(const Extension* extension) { |
+ return GetBackgroundInfo(extension).allow_js_access; |
+} |
+ |
+// static |
+bool BackgroundInfo::HasPersistentBackgroundPage(const Extension* extension) { |
+ const BackgroundInfo& info = GetBackgroundInfo(extension); |
+ return info.has_background_page() && info.is_persistent; |
+} |
+ |
+// static |
+bool BackgroundInfo::HasLazyBackgroundPage(const Extension* extension) { |
+ const BackgroundInfo& info = GetBackgroundInfo(extension); |
+ return info.has_background_page() && !info.is_persistent; |
+} |
+ |
+BackgroundManifestHandler::BackgroundManifestHandler() { |
+} |
+ |
+BackgroundManifestHandler::~BackgroundManifestHandler() { |
+} |
+ |
+bool BackgroundManifestHandler::Parse(Extension* extension, string16* error) { |
+ scoped_ptr<BackgroundInfo> info(new BackgroundInfo); |
+ const std::string& bg_scripts_key = extension->is_platform_app() ? |
+ keys::kPlatformAppBackgroundScripts : keys::kBackgroundScripts; |
+ if (!LoadBackgroundScripts(extension, bg_scripts_key, error, info.get()) || |
+ !LoadBackgroundPage(extension, error, info.get()) || |
+ !LoadBackgroundPersistent(extension, error, info.get()) || |
+ !LoadBackgroundAllowJSAccess(extension, error, info.get())) { |
+ return false; |
+ } |
+ |
+ extension->SetManifestData(kBackground, info.release()); |
+ return true; |
+} |
+ |
+// static |
+const std::vector<std::string> BackgroundManifestHandler::keys() { |
+ static const char* keys[] = { |
+ keys::kBackgroundAllowJsAccess, |
+ keys::kBackgroundPage, |
+ keys::kBackgroundPageLegacy, |
+ keys::kBackgroundPersistent, |
+ keys::kBackgroundScripts, |
+ keys::kPlatformAppBackgroundPage, |
+ keys::kPlatformAppBackgroundScripts |
+ }; |
+ return std::vector<std::string>(keys, keys + arraysize(keys)); |
+} |
+ |
+} // extensions |