summaryrefslogtreecommitdiffstats
path: root/extensions/common
diff options
context:
space:
mode:
authorjamescook@chromium.org <jamescook@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-11-09 01:25:51 +0000
committerjamescook@chromium.org <jamescook@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-11-09 01:25:51 +0000
commit558878cc8ce3b66dce25a0b576893432ff95095a (patch)
tree13c1d747d42f6baf7d1e926e2011cda00d25e9d4 /extensions/common
parentd190bfa6ab7b02ca01150b30f65d082ee56514bb (diff)
downloadchromium_src-558878cc8ce3b66dce25a0b576893432ff95095a.zip
chromium_src-558878cc8ce3b66dce25a0b576893432ff95095a.tar.gz
chromium_src-558878cc8ce3b66dce25a0b576893432ff95095a.tar.bz2
Move chrome/common/extensions/background_info.h to src/extensions
This is part of a refactor to extract extensions code from Chrome. To allow the move: * Extract extensions::file_util from extension_file_util.h/cc * Move switches::kAllowHTTPBackgroundPage to extensions/common/switches.h BUG=316218 TEST=compiles, unit_tests TBR=ben@chromium.org for mechanical header file renames across chrome/browser Review URL: https://codereview.chromium.org/65123002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@234065 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'extensions/common')
-rw-r--r--extensions/common/DEPS5
-rw-r--r--extensions/common/file_util.cc61
-rw-r--r--extensions/common/file_util.h28
-rw-r--r--extensions/common/file_util_unittest.cc121
-rw-r--r--extensions/common/manifest_handlers/background_info.cc318
-rw-r--r--extensions/common/manifest_handlers/background_info.h99
-rw-r--r--extensions/common/switches.cc3
-rw-r--r--extensions/common/switches.h1
8 files changed, 635 insertions, 1 deletions
diff --git a/extensions/common/DEPS b/extensions/common/DEPS
index 37ad7de..34509b4 100644
--- a/extensions/common/DEPS
+++ b/extensions/common/DEPS
@@ -1,4 +1,5 @@
include_rules = [
+ "+net",
"+third_party/re2",
# Temporarily allowed includes as part of the app shell/extensions refactor.
@@ -11,5 +12,7 @@ include_rules = [
"+chrome/common/extensions/extension.h",
"+chrome/common/extensions/permissions/permissions_data.h",
"+grit/common_resources.h",
- "+grit/extensions_api_resources.h"
+ "+grit/extensions_api_resources.h",
+ # TODO(jamescook): Extract extensions-related strings from this file.
+ "+grit/generated_resources.h",
]
diff --git a/extensions/common/file_util.cc b/extensions/common/file_util.cc
new file mode 100644
index 0000000..ba8abe4
--- /dev/null
+++ b/extensions/common/file_util.cc
@@ -0,0 +1,61 @@
+// Copyright 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 "extensions/common/file_util.h"
+
+#include <string>
+
+#include "base/file_util.h"
+#include "base/files/file_path.h"
+#include "net/base/escape.h"
+#include "url/gurl.h"
+
+namespace extensions {
+namespace file_util {
+
+base::FilePath ExtensionURLToRelativeFilePath(const GURL& url) {
+ std::string url_path = url.path();
+ if (url_path.empty() || url_path[0] != '/')
+ return base::FilePath();
+
+ // Drop the leading slashes and convert %-encoded UTF8 to regular UTF8.
+ std::string file_path = net::UnescapeURLComponent(url_path,
+ net::UnescapeRule::SPACES | net::UnescapeRule::URL_SPECIAL_CHARS);
+ size_t skip = file_path.find_first_not_of("/\\");
+ if (skip != file_path.npos)
+ file_path = file_path.substr(skip);
+
+ base::FilePath path = base::FilePath::FromUTF8Unsafe(file_path);
+
+ // It's still possible for someone to construct an annoying URL whose path
+ // would still wind up not being considered relative at this point.
+ // For example: chrome-extension://id/c:////foo.html
+ if (path.IsAbsolute())
+ return base::FilePath();
+
+ return path;
+}
+
+base::FilePath ExtensionResourceURLToFilePath(const GURL& url,
+ const base::FilePath& root) {
+ std::string host = net::UnescapeURLComponent(url.host(),
+ net::UnescapeRule::SPACES | net::UnescapeRule::URL_SPECIAL_CHARS);
+ if (host.empty())
+ return base::FilePath();
+
+ base::FilePath relative_path = ExtensionURLToRelativeFilePath(url);
+ if (relative_path.empty())
+ return base::FilePath();
+
+ base::FilePath path = root.AppendASCII(host).Append(relative_path);
+ if (!base::PathExists(path))
+ return base::FilePath();
+ path = base::MakeAbsoluteFilePath(path);
+ if (path.empty() || !root.IsParent(path))
+ return base::FilePath();
+ return path;
+}
+
+} // namespace file_util
+} // namespace extensions
diff --git a/extensions/common/file_util.h b/extensions/common/file_util.h
new file mode 100644
index 0000000..3ec7ade
--- /dev/null
+++ b/extensions/common/file_util.h
@@ -0,0 +1,28 @@
+// Copyright 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.
+
+#ifndef EXTENSIONS_COMMON_FILE_UTIL_H_
+#define EXTENSIONS_COMMON_FILE_UTIL_H_
+
+class GURL;
+
+namespace base {
+class FilePath;
+}
+
+namespace extensions {
+namespace file_util {
+
+// Get a relative file path from a chrome-extension:// URL.
+base::FilePath ExtensionURLToRelativeFilePath(const GURL& url);
+
+// Get a full file path from a chrome-extension-resource:// URL, If the URL
+// points a file outside of root, this function will return empty FilePath.
+base::FilePath ExtensionResourceURLToFilePath(const GURL& url,
+ const base::FilePath& root);
+
+} // namespace file_util
+} // namespace extensions
+
+#endif // EXTENSIONS_COMMON_FILE_UTIL_H_
diff --git a/extensions/common/file_util_unittest.cc b/extensions/common/file_util_unittest.cc
new file mode 100644
index 0000000..9ca883c
--- /dev/null
+++ b/extensions/common/file_util_unittest.cc
@@ -0,0 +1,121 @@
+// Copyright 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 "extensions/common/file_util.h"
+
+#include "base/basictypes.h"
+#include "base/file_util.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
+
+typedef testing::Test FileUtilTest;
+
+TEST_F(FileUtilTest, ExtensionURLToRelativeFilePath) {
+#define URL_PREFIX "chrome-extension://extension-id/"
+ struct TestCase {
+ const char* url;
+ const char* expected_relative_path;
+ } test_cases[] = {
+ { URL_PREFIX "simple.html",
+ "simple.html" },
+ { URL_PREFIX "directory/to/file.html",
+ "directory/to/file.html" },
+ { URL_PREFIX "escape%20spaces.html",
+ "escape spaces.html" },
+ { URL_PREFIX "%C3%9Cber.html",
+ "\xC3\x9C" "ber.html" },
+#if defined(OS_WIN)
+ { URL_PREFIX "C%3A/simple.html",
+ "" },
+#endif
+ { URL_PREFIX "////simple.html",
+ "simple.html" },
+ { URL_PREFIX "/simple.html",
+ "simple.html" },
+ { URL_PREFIX "\\simple.html",
+ "simple.html" },
+ { URL_PREFIX "\\\\foo\\simple.html",
+ "foo/simple.html" },
+ };
+#undef URL_PREFIX
+
+ for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) {
+ GURL url(test_cases[i].url);
+ base::FilePath expected_path =
+ base::FilePath::FromUTF8Unsafe(test_cases[i].expected_relative_path);
+ base::FilePath actual_path =
+ extensions::file_util::ExtensionURLToRelativeFilePath(url);
+ EXPECT_FALSE(actual_path.IsAbsolute()) <<
+ " For the path " << actual_path.value();
+ EXPECT_EQ(expected_path.value(), actual_path.value()) <<
+ " For the path " << url;
+ }
+}
+
+TEST_F(FileUtilTest, ExtensionResourceURLToFilePath) {
+ // Setup filesystem for testing.
+ base::FilePath root_path;
+ ASSERT_TRUE(file_util::CreateNewTempDirectory(
+ base::FilePath::StringType(), &root_path));
+ root_path = base::MakeAbsoluteFilePath(root_path);
+ ASSERT_FALSE(root_path.empty());
+
+ base::FilePath api_path = root_path.Append(FILE_PATH_LITERAL("apiname"));
+ ASSERT_TRUE(file_util::CreateDirectory(api_path));
+
+ const char data[] = "Test Data";
+ base::FilePath resource_path = api_path.Append(FILE_PATH_LITERAL("test.js"));
+ ASSERT_TRUE(file_util::WriteFile(resource_path, data, sizeof(data)));
+ resource_path = api_path.Append(FILE_PATH_LITERAL("escape spaces.js"));
+ ASSERT_TRUE(file_util::WriteFile(resource_path, data, sizeof(data)));
+
+#ifdef FILE_PATH_USES_WIN_SEPARATORS
+#define SEP "\\"
+#else
+#define SEP "/"
+#endif
+#define URL_PREFIX "chrome-extension-resource://"
+ struct TestCase {
+ const char* url;
+ const base::FilePath::CharType* expected_path;
+ } test_cases[] = {
+ { URL_PREFIX "apiname/test.js",
+ FILE_PATH_LITERAL("test.js") },
+ { URL_PREFIX "/apiname/test.js",
+ FILE_PATH_LITERAL("test.js") },
+ // Test % escape
+ { URL_PREFIX "apiname/%74%65st.js",
+ FILE_PATH_LITERAL("test.js") },
+ { URL_PREFIX "apiname/escape%20spaces.js",
+ FILE_PATH_LITERAL("escape spaces.js") },
+ // Test file does not exist.
+ { URL_PREFIX "apiname/directory/to/file.js",
+ NULL },
+ // Test apiname/../../test.js
+ { URL_PREFIX "apiname/../../test.js",
+ FILE_PATH_LITERAL("test.js") },
+ { URL_PREFIX "apiname/..%2F../test.js",
+ NULL },
+ { URL_PREFIX "apiname/f/../../../test.js",
+ FILE_PATH_LITERAL("test.js") },
+ { URL_PREFIX "apiname/f%2F..%2F..%2F../test.js",
+ NULL },
+ };
+#undef SEP
+#undef URL_PREFIX
+
+ for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) {
+ GURL url(test_cases[i].url);
+ base::FilePath expected_path;
+ if (test_cases[i].expected_path)
+ expected_path = root_path.Append(FILE_PATH_LITERAL("apiname")).Append(
+ test_cases[i].expected_path);
+ base::FilePath actual_path =
+ extensions::file_util::ExtensionResourceURLToFilePath(url, root_path);
+ EXPECT_EQ(expected_path.value(), actual_path.value()) <<
+ " For the path " << url;
+ }
+ // Remove temp files.
+ ASSERT_TRUE(base::DeleteFile(root_path, true));
+}
diff --git a/extensions/common/manifest_handlers/background_info.cc b/extensions/common/manifest_handlers/background_info.cc
new file mode 100644
index 0000000..f32cc4b
--- /dev/null
+++ b/extensions/common/manifest_handlers/background_info.cc
@@ -0,0 +1,318 @@
+// Copyright 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 "extensions/common/manifest_handlers/background_info.h"
+
+#include "base/command_line.h"
+#include "base/file_util.h"
+#include "base/lazy_instance.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/utf_string_conversions.h"
+#include "chrome/common/extensions/permissions/permissions_data.h"
+#include "extensions/common/constants.h"
+#include "extensions/common/error_utils.h"
+#include "extensions/common/file_util.h"
+#include "extensions/common/manifest_constants.h"
+#include "extensions/common/permissions/api_permission_set.h"
+#include "extensions/common/switches.h"
+#include "grit/generated_resources.h"
+#include "ui/base/l10n/l10n_util.h"
+
+using base::DictionaryValue;
+
+namespace extensions {
+
+namespace keys = manifest_keys;
+namespace values = manifest_values;
+namespace errors = manifest_errors;
+
+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;
+}
+
+} // 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(kGeneratedBackgroundPageFilename);
+}
+
+// static
+bool BackgroundInfo::HasGeneratedBackgroundPage(const Extension* extension) {
+ const BackgroundInfo& info = GetBackgroundInfo(extension);
+ return !info.background_scripts_.empty();
+}
+
+// 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) {
+ return GetBackgroundInfo(extension).has_persistent_background_page();
+}
+
+// static
+bool BackgroundInfo::HasLazyBackgroundPage(const Extension* extension) {
+ return GetBackgroundInfo(extension).has_lazy_background_page();
+}
+
+bool BackgroundInfo::Parse(const Extension* extension, string16* error) {
+ const std::string& bg_scripts_key = extension->is_platform_app() ?
+ keys::kPlatformAppBackgroundScripts : keys::kBackgroundScripts;
+ if (!LoadBackgroundScripts(extension, bg_scripts_key, error) ||
+ !LoadBackgroundPage(extension, error) ||
+ !LoadBackgroundPersistent(extension, error) ||
+ !LoadAllowJSAccess(extension, error)) {
+ return false;
+ }
+ return true;
+}
+
+bool BackgroundInfo::LoadBackgroundScripts(const Extension* extension,
+ const std::string& key,
+ string16* error) {
+ const base::Value* background_scripts_value = NULL;
+ if (!extension->manifest()->Get(key, &background_scripts_value))
+ return true;
+
+ CHECK(background_scripts_value);
+ if (background_scripts_value->GetType() != base::Value::TYPE_LIST) {
+ *error = ASCIIToUTF16(errors::kInvalidBackgroundScripts);
+ return false;
+ }
+
+ const base::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;
+ }
+ background_scripts_.push_back(script);
+ }
+
+ return true;
+}
+
+bool BackgroundInfo::LoadBackgroundPage(const Extension* extension,
+ const std::string& key,
+ string16* error) {
+ const base::Value* background_page_value = NULL;
+ if (!extension->manifest()->Get(key, &background_page_value))
+ return true;
+
+ if (!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()) {
+ background_url_ = GURL(background_str);
+
+ if (!PermissionsData::GetInitialAPIPermissions(extension)->count(
+ APIPermission::kBackground)) {
+ *error = ASCIIToUTF16(errors::kBackgroundPermissionNeeded);
+ return false;
+ }
+ // Hosted apps require an absolute URL.
+ if (!background_url_.is_valid()) {
+ *error = ASCIIToUTF16(errors::kInvalidBackgroundInHostedApp);
+ return false;
+ }
+
+ if (!(background_url_.SchemeIs("https") ||
+ (CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kAllowHTTPBackgroundPage) &&
+ background_url_.SchemeIs("http")))) {
+ *error = ASCIIToUTF16(errors::kInvalidBackgroundInHostedApp);
+ return false;
+ }
+ } else {
+ background_url_ = extension->GetResourceURL(background_str);
+ }
+
+ return true;
+}
+
+bool BackgroundInfo::LoadBackgroundPage(const Extension* extension,
+ string16* error) {
+ if (extension->is_platform_app()) {
+ return LoadBackgroundPage(
+ extension, keys::kPlatformAppBackgroundPage, error);
+ }
+
+ if (!LoadBackgroundPage(extension, keys::kBackgroundPage, error))
+ return false;
+ if (background_url_.is_empty())
+ return LoadBackgroundPage(extension, keys::kBackgroundPageLegacy, error);
+ return true;
+}
+
+bool BackgroundInfo::LoadBackgroundPersistent(const Extension* extension,
+ string16* error) {
+ if (extension->is_platform_app()) {
+ is_persistent_ = false;
+ return true;
+ }
+
+ const base::Value* background_persistent = NULL;
+ if (!extension->manifest()->Get(keys::kBackgroundPersistent,
+ &background_persistent))
+ return true;
+
+ if (!background_persistent->GetAsBoolean(&is_persistent_)) {
+ *error = ASCIIToUTF16(errors::kInvalidBackgroundPersistent);
+ return false;
+ }
+
+ if (!has_background_page()) {
+ *error = ASCIIToUTF16(errors::kInvalidBackgroundPersistentNoPage);
+ return false;
+ }
+
+ return true;
+}
+
+bool BackgroundInfo::LoadAllowJSAccess(const Extension* extension,
+ string16* error) {
+ const base::Value* allow_js_access = NULL;
+ if (!extension->manifest()->Get(keys::kBackgroundAllowJsAccess,
+ &allow_js_access))
+ return true;
+
+ if (!allow_js_access->IsType(base::Value::TYPE_BOOLEAN) ||
+ !allow_js_access->GetAsBoolean(&allow_js_access_)) {
+ *error = ASCIIToUTF16(errors::kInvalidBackgroundAllowJsAccess);
+ return false;
+ }
+
+ return true;
+}
+
+BackgroundManifestHandler::BackgroundManifestHandler() {
+}
+
+BackgroundManifestHandler::~BackgroundManifestHandler() {
+}
+
+bool BackgroundManifestHandler::Parse(Extension* extension, string16* error) {
+ scoped_ptr<BackgroundInfo> info(new BackgroundInfo);
+ if (!info->Parse(extension, error))
+ return false;
+
+ // Platform apps must have background pages.
+ if (extension->is_platform_app() && !info->has_background_page()) {
+ *error = ASCIIToUTF16(errors::kBackgroundRequiredForPlatformApps);
+ return false;
+ }
+ // Lazy background pages are incompatible with the webRequest API.
+ if (info->has_lazy_background_page() &&
+ PermissionsData::GetInitialAPIPermissions(extension)->count(
+ APIPermission::kWebRequest)) {
+ *error = ASCIIToUTF16(errors::kWebRequestConflictsWithLazyBackground);
+ return false;
+ }
+
+ extension->SetManifestData(kBackground, info.release());
+ return true;
+}
+
+bool BackgroundManifestHandler::Validate(
+ const Extension* extension,
+ std::string* error,
+ std::vector<InstallWarning>* warnings) const {
+ // Validate that background scripts exist.
+ const std::vector<std::string>& background_scripts =
+ BackgroundInfo::GetBackgroundScripts(extension);
+ for (size_t i = 0; i < background_scripts.size(); ++i) {
+ if (!base::PathExists(
+ extension->GetResource(background_scripts[i]).GetFilePath())) {
+ *error = l10n_util::GetStringFUTF8(
+ IDS_EXTENSION_LOAD_BACKGROUND_SCRIPT_FAILED,
+ UTF8ToUTF16(background_scripts[i]));
+ return false;
+ }
+ }
+
+ // Validate background page location, except for hosted apps, which should use
+ // an external URL. Background page for hosted apps are verified when the
+ // extension is created (in Extension::InitFromValue)
+ if (BackgroundInfo::HasBackgroundPage(extension) &&
+ !extension->is_hosted_app() && background_scripts.empty()) {
+ base::FilePath page_path = file_util::ExtensionURLToRelativeFilePath(
+ BackgroundInfo::GetBackgroundURL(extension));
+ const base::FilePath path = extension->GetResource(page_path).GetFilePath();
+ if (path.empty() || !base::PathExists(path)) {
+ *error =
+ l10n_util::GetStringFUTF8(
+ IDS_EXTENSION_LOAD_BACKGROUND_PAGE_FAILED,
+ page_path.LossyDisplayName());
+ return false;
+ }
+ }
+ return true;
+}
+
+bool BackgroundManifestHandler::AlwaysParseForType(Manifest::Type type) const {
+ return type == Manifest::TYPE_PLATFORM_APP;
+}
+
+const std::vector<std::string> BackgroundManifestHandler::Keys() const {
+ 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));
+}
+
+} // namespace extensions
diff --git a/extensions/common/manifest_handlers/background_info.h b/extensions/common/manifest_handlers/background_info.h
new file mode 100644
index 0000000..40d4920
--- /dev/null
+++ b/extensions/common/manifest_handlers/background_info.h
@@ -0,0 +1,99 @@
+// Copyright 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.
+
+#ifndef EXTENSIONS_COMMON_MANIFEST_HANDLERS_BACKGROUND_INFO_H_
+#define EXTENSIONS_COMMON_MANIFEST_HANDLERS_BACKGROUND_INFO_H_
+
+#include <string>
+#include <vector>
+
+#include "base/values.h"
+#include "chrome/common/extensions/extension.h"
+#include "extensions/common/manifest_handler.h"
+#include "url/gurl.h"
+
+namespace extensions {
+
+class BackgroundInfo : public Extension::ManifestData {
+ public:
+ BackgroundInfo();
+ virtual ~BackgroundInfo();
+
+ static GURL GetBackgroundURL(const Extension* extension);
+ static const std::vector<std::string>& GetBackgroundScripts(
+ const Extension* extension);
+ static bool HasBackgroundPage(const Extension* extension);
+ static bool HasPersistentBackgroundPage(const Extension* extension);
+ static bool HasLazyBackgroundPage(const Extension* extension);
+ static bool HasGeneratedBackgroundPage(const Extension* extension);
+ static bool AllowJSAccess(const Extension* extension);
+
+ bool has_background_page() const {
+ return background_url_.is_valid() || !background_scripts_.empty();
+ }
+
+ bool has_persistent_background_page() const {
+ return has_background_page() && is_persistent_;
+ }
+
+ bool has_lazy_background_page() const {
+ return has_background_page() && !is_persistent_;
+ }
+
+ bool Parse(const Extension* extension, string16* error);
+
+ private:
+ bool LoadBackgroundScripts(const Extension* extension,
+ const std::string& key,
+ string16* error);
+ bool LoadBackgroundPage(const Extension* extension,
+ const std::string& key,
+ string16* error);
+ bool LoadBackgroundPage(const Extension* extension, string16* error);
+ bool LoadBackgroundPersistent(const Extension* extension, string16* error);
+ bool LoadAllowJSAccess(const Extension* extension, string16* error);
+
+ // Optional URL to a master page of which a single instance should be always
+ // loaded in the background.
+ GURL background_url_;
+
+ // Optional list of scripts to use to generate a background page. If this is
+ // present, background_url_ will be empty and generated by GetBackgroundURL().
+ std::vector<std::string> background_scripts_;
+
+ // True if the background page should stay loaded forever; false if it should
+ // load on-demand (when it needs to handle an event). Defaults to true.
+ bool is_persistent_;
+
+ // True if the background page can be scripted by pages of the app or
+ // extension, in which case all such pages must run in the same process.
+ // False if such pages are not permitted to script the background page,
+ // allowing them to run in different processes.
+ // Defaults to true.
+ bool allow_js_access_;
+
+ DISALLOW_COPY_AND_ASSIGN(BackgroundInfo);
+};
+
+// Parses all background/event page-related keys in the manifest.
+class BackgroundManifestHandler : public ManifestHandler {
+ public:
+ BackgroundManifestHandler();
+ virtual ~BackgroundManifestHandler();
+
+ virtual bool Parse(Extension* extension, string16* error) OVERRIDE;
+ virtual bool Validate(const Extension* extension,
+ std::string* error,
+ std::vector<InstallWarning>* warnings) const OVERRIDE;
+ virtual bool AlwaysParseForType(Manifest::Type type) const OVERRIDE;
+
+ private:
+ virtual const std::vector<std::string> Keys() const OVERRIDE;
+
+ DISALLOW_COPY_AND_ASSIGN(BackgroundManifestHandler);
+};
+
+} // namespace extensions
+
+#endif // EXTENSIONS_COMMON_MANIFEST_HANDLERS_BACKGROUND_INFO_H_
diff --git a/extensions/common/switches.cc b/extensions/common/switches.cc
index 451cbc0..82222c4 100644
--- a/extensions/common/switches.cc
+++ b/extensions/common/switches.cc
@@ -8,6 +8,9 @@ namespace extensions {
namespace switches {
+// Allows non-https URL for background_page for hosted apps.
+const char kAllowHTTPBackgroundPage[] = "allow-http-background-page";
+
// Allows the browser to load extensions that lack a modern manifest when that
// would otherwise be forbidden.
const char kAllowLegacyExtensionManifests[] =
diff --git a/extensions/common/switches.h b/extensions/common/switches.h
index 7111d87..75f3843 100644
--- a/extensions/common/switches.h
+++ b/extensions/common/switches.h
@@ -11,6 +11,7 @@ namespace extensions {
namespace switches {
+extern const char kAllowHTTPBackgroundPage[];
extern const char kAllowLegacyExtensionManifests[];
extern const char kAllowScriptingGallery[];
extern const char kEasyOffStoreExtensionInstall[];