summaryrefslogtreecommitdiffstats
path: root/extensions
diff options
context:
space:
mode:
authorscheib@chromium.org <scheib@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-03-06 20:52:32 +0000
committerscheib@chromium.org <scheib@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-03-06 20:52:32 +0000
commit98e1617bfcaaffb9aa9e39cd7bd44831f6f5d376 (patch)
tree829c19e53e7535388f9100232803de0ed113d893 /extensions
parente6fc7b45877afd0ca10d139f936af8caf529b3c0 (diff)
downloadchromium_src-98e1617bfcaaffb9aa9e39cd7bd44831f6f5d376.zip
chromium_src-98e1617bfcaaffb9aa9e39cd7bd44831f6f5d376.tar.gz
chromium_src-98e1617bfcaaffb9aa9e39cd7bd44831f6f5d376.tar.bz2
Parse manifest file with app.service_worker.script.
Add parsing logic to load a manifest specifying a service worker script. This is a precursor to registering and using that script. BUG=344917 R=jyasskin@chromium.org Review URL: https://codereview.chromium.org/178253007 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@255424 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'extensions')
-rw-r--r--extensions/common/manifest.cc3
-rw-r--r--extensions/common/manifest_constants.cc7
-rw-r--r--extensions/common/manifest_constants.h4
-rw-r--r--extensions/common/manifest_handlers/background_info.cc96
-rw-r--r--extensions/common/manifest_handlers/background_info.h11
-rw-r--r--extensions/common/test_util.cc19
-rw-r--r--extensions/common/test_util.h11
-rw-r--r--extensions/extensions.gyp1
8 files changed, 124 insertions, 28 deletions
diff --git a/extensions/common/manifest.cc b/extensions/common/manifest.cc
index 32981a3..a02fdc3 100644
--- a/extensions/common/manifest.cc
+++ b/extensions/common/manifest.cc
@@ -120,7 +120,8 @@ Manifest::Manifest(Location location, scoped_ptr<base::DictionaryValue> value)
if (value_->Get(keys::kWebURLs, NULL) ||
value_->Get(keys::kLaunchWebURL, NULL)) {
type_ = TYPE_HOSTED_APP;
- } else if (value_->Get(keys::kPlatformAppBackground, NULL)) {
+ } else if (value_->Get(keys::kPlatformAppBackground, NULL) ||
+ value_->Get(keys::kPlatformAppServiceWorker, NULL)) {
type_ = TYPE_PLATFORM_APP;
} else {
type_ = TYPE_LEGACY_PACKAGED_APP;
diff --git a/extensions/common/manifest_constants.cc b/extensions/common/manifest_constants.cc
index f7bf1f4..8b36cd0 100644
--- a/extensions/common/manifest_constants.cc
+++ b/extensions/common/manifest_constants.cc
@@ -106,6 +106,8 @@ const char kPlatformAppBackground[] = "app.background";
const char kPlatformAppBackgroundPage[] = "app.background.page";
const char kPlatformAppBackgroundScripts[] = "app.background.scripts";
const char kPlatformAppContentSecurityPolicy[] = "app.content_security_policy";
+const char kPlatformAppServiceWorker[] = "app.service_worker";
+const char kPlatformAppServiceWorkerScript[] = "app.service_worker.script";
const char kPlugins[] = "plugins";
const char kPluginsPath[] = "path";
const char kPluginsPublic[] = "public";
@@ -554,6 +556,8 @@ const char kInvalidScriptBadge[] =
"Invalid value for 'script_badge'.";
const char kInvalidSearchEngineURL[] =
"Invalid URL [*] for 'chrome_settings_overrides.search_provider'.";
+const char kInvalidServiceWorkerScript[] =
+ "Invalid value for 'service_worker.script'.";
const char kInvalidEmptySettingsOverrides[] =
"Empty dictionary for 'chrome_settings_overrides'.";
const char kInvalidShortName[] =
@@ -696,6 +700,9 @@ const char kScriptBadgeIconIgnored[] =
const char kScriptBadgeTitleIgnored[] =
"default_title specified in script_badge manifest section will not be "
"used.";
+const char kServiceWorkerRequiresFlag[] =
+ "Service worker features require --enable-service-worker command-line "
+ "flag.";
const char kUnrecognizedManifestKey[] = "Unrecognized manifest key '*'.";
const char kUnrecognizedManifestProperty[] =
"Unrecognized property '*' of manifest key '*'.";
diff --git a/extensions/common/manifest_constants.h b/extensions/common/manifest_constants.h
index a9c39fe..6e5dc71 100644
--- a/extensions/common/manifest_constants.h
+++ b/extensions/common/manifest_constants.h
@@ -115,6 +115,8 @@ extern const char kPlatformAppBackground[];
extern const char kPlatformAppBackgroundPage[];
extern const char kPlatformAppBackgroundScripts[];
extern const char kPlatformAppContentSecurityPolicy[];
+extern const char kPlatformAppServiceWorker[];
+extern const char kPlatformAppServiceWorkerScript[];
extern const char kPlugins[];
extern const char kPluginsPath[];
extern const char kPluginsPublic[];
@@ -392,6 +394,7 @@ extern const char kInvalidSandboxedPage[];
extern const char kInvalidSandboxedPagesCSP[];
extern const char kInvalidScriptBadge[];
extern const char kInvalidSearchEngineURL[];
+extern const char kInvalidServiceWorkerScript[];
extern const char kInvalidEmptySettingsOverrides[];
extern const char kInvalidShortName[];
extern const char kInvalidSignature[];
@@ -460,6 +463,7 @@ extern const char kUnrecognizedManifestProperty[];
extern const char kScriptBadgeRequiresFlag[];
extern const char kScriptBadgeIconIgnored[];
extern const char kScriptBadgeTitleIgnored[];
+extern const char kServiceWorkerRequiresFlag[];
extern const char kWebRequestConflictsWithLazyBackground[];
#if defined(OS_CHROMEOS)
extern const char kIllegalPlugins[];
diff --git a/extensions/common/manifest_handlers/background_info.cc b/extensions/common/manifest_handlers/background_info.cc
index c7aee90..1c484fc5 100644
--- a/extensions/common/manifest_handlers/background_info.cc
+++ b/extensions/common/manifest_handlers/background_info.cc
@@ -10,6 +10,7 @@
#include "base/memory/scoped_ptr.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
+#include "content/public/common/content_switches.h"
#include "extensions/common/constants.h"
#include "extensions/common/error_utils.h"
#include "extensions/common/file_util.h"
@@ -63,25 +64,20 @@ GURL BackgroundInfo::GetBackgroundURL(const Extension* extension) {
}
// 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();
+const std::string& BackgroundInfo::GetServiceWorkerScript(
+ const Extension* extension) {
+ return GetBackgroundInfo(extension).service_worker_script_;
}
// static
-bool BackgroundInfo::AllowJSAccess(const Extension* extension) {
- return GetBackgroundInfo(extension).allow_js_access_;
+bool BackgroundInfo::HasBackgroundPage(const Extension* extension) {
+ return GetBackgroundInfo(extension).has_background_page();
}
// static
@@ -94,15 +90,66 @@ bool BackgroundInfo::HasLazyBackgroundPage(const Extension* extension) {
return GetBackgroundInfo(extension).has_lazy_background_page();
}
+// static
+bool BackgroundInfo::HasGeneratedBackgroundPage(const Extension* extension) {
+ const BackgroundInfo& info = GetBackgroundInfo(extension);
+ return !info.background_scripts_.empty();
+}
+
+// static
+bool BackgroundInfo::HasServiceWorker(const Extension* extension) {
+ return GetBackgroundInfo(extension).has_service_worker();
+}
+
+// static
+bool BackgroundInfo::AllowJSAccess(const Extension* extension) {
+ return GetBackgroundInfo(extension).allow_js_access_;
+}
+
bool BackgroundInfo::Parse(const Extension* extension, base::string16* error) {
const std::string& bg_scripts_key = extension->is_platform_app() ?
keys::kPlatformAppBackgroundScripts : keys::kBackgroundScripts;
- if (!LoadBackgroundScripts(extension, bg_scripts_key, error) ||
+ const std::string& sw_scripts_key =
+ extension->is_platform_app()
+ ? keys::kPlatformAppServiceWorkerScript
+ : ""; // TODO(scheib): Support extensions crbug.com/346885
+ if (!LoadServiceWorkerScript(extension, sw_scripts_key, error) ||
+ !LoadBackgroundScripts(extension, bg_scripts_key, error) ||
!LoadBackgroundPage(extension, error) ||
!LoadBackgroundPersistent(extension, error) ||
!LoadAllowJSAccess(extension, error)) {
return false;
}
+
+ int background_solution_sum = (background_url_.is_valid() ? 1 : 0) +
+ (!background_scripts_.empty() ? 1 : 0) +
+ (has_service_worker() ? 1 : 0);
+ if (background_solution_sum > 1) {
+ *error = ASCIIToUTF16(errors::kInvalidBackgroundCombination);
+ return false;
+ }
+
+ return true;
+}
+
+bool BackgroundInfo::LoadServiceWorkerScript(const Extension* extension,
+ const std::string& key,
+ base::string16* error) {
+ const base::Value* service_worker_script_value = NULL;
+ if (!extension->manifest()->Get(key, &service_worker_script_value))
+ return true;
+
+ if (!CommandLine::ForCurrentProcess()->HasSwitch(
+ ::switches::kEnableServiceWorker)) {
+ *error = ASCIIToUTF16(errors::kServiceWorkerRequiresFlag);
+ return false;
+ }
+
+ CHECK(service_worker_script_value);
+ if (!service_worker_script_value->GetAsString(&service_worker_script_)) {
+ *error = ASCIIToUTF16(errors::kInvalidServiceWorkerScript);
+ return false;
+ }
return true;
}
@@ -141,11 +188,6 @@ bool BackgroundInfo::LoadBackgroundPage(const Extension* extension,
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);
@@ -247,8 +289,9 @@ bool BackgroundManifestHandler::Parse(Extension* extension,
if (!info->Parse(extension, error))
return false;
- // Platform apps must have background pages.
- if (extension->is_platform_app() && !info->has_background_page()) {
+ // Platform apps must have background pages or service workers.
+ if (extension->is_platform_app() && !info->has_background_page() &&
+ !info->has_service_worker()) {
*error = ASCIIToUTF16(errors::kBackgroundRequiredForPlatformApps);
return false;
}
@@ -305,15 +348,14 @@ bool BackgroundManifestHandler::AlwaysParseForType(Manifest::Type type) const {
}
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
- };
+ static const char* keys[] = {keys::kBackgroundAllowJsAccess,
+ keys::kBackgroundPage,
+ keys::kBackgroundPageLegacy,
+ keys::kBackgroundPersistent,
+ keys::kBackgroundScripts,
+ keys::kPlatformAppBackgroundPage,
+ keys::kPlatformAppBackgroundScripts,
+ keys::kPlatformAppServiceWorkerScript};
return std::vector<std::string>(keys, keys + arraysize(keys));
}
diff --git a/extensions/common/manifest_handlers/background_info.h b/extensions/common/manifest_handlers/background_info.h
index e9e360e..947ee65 100644
--- a/extensions/common/manifest_handlers/background_info.h
+++ b/extensions/common/manifest_handlers/background_info.h
@@ -23,10 +23,12 @@ class BackgroundInfo : public Extension::ManifestData {
static GURL GetBackgroundURL(const Extension* extension);
static const std::vector<std::string>& GetBackgroundScripts(
const Extension* extension);
+ static const std::string& GetServiceWorkerScript(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 HasServiceWorker(const Extension* extension);
static bool AllowJSAccess(const Extension* extension);
bool has_background_page() const {
@@ -41,9 +43,14 @@ class BackgroundInfo : public Extension::ManifestData {
return has_background_page() && !is_persistent_;
}
+ bool has_service_worker() const { return !service_worker_script_.empty(); }
+
bool Parse(const Extension* extension, base::string16* error);
private:
+ bool LoadServiceWorkerScript(const Extension* extension,
+ const std::string& key,
+ base::string16* error);
bool LoadBackgroundScripts(const Extension* extension,
const std::string& key,
base::string16* error);
@@ -67,6 +74,10 @@ class BackgroundInfo : public Extension::ManifestData {
// load on-demand (when it needs to handle an event). Defaults to true.
bool is_persistent_;
+ // Optional script to register as a service worker. This is mutually exclusive
+ // to the use of background_url_ or background_scripts_.
+ std::string service_worker_script_;
+
// 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,
diff --git a/extensions/common/test_util.cc b/extensions/common/test_util.cc
index 4d3164f..05de2c7 100644
--- a/extensions/common/test_util.cc
+++ b/extensions/common/test_util.cc
@@ -4,9 +4,12 @@
#include "extensions/common/test_util.h"
+#include "base/json/json_reader.h"
+#include "base/values.h"
#include "extensions/common/extension.h"
#include "extensions/common/extension_builder.h"
#include "extensions/common/value_builder.h"
+#include "testing/gtest/include/gtest/gtest.h"
namespace extensions {
namespace test_util {
@@ -27,5 +30,21 @@ scoped_refptr<Extension> CreateExtensionWithID(const std::string& id) {
.Build();
}
+scoped_ptr<base::DictionaryValue> ParseJsonDictionaryWithSingleQuotes(
+ std::string json) {
+ std::replace(json.begin(), json.end(), '\'', '"');
+ std::string error_msg;
+ scoped_ptr<base::Value> result(base::JSONReader::ReadAndReturnError(
+ json, base::JSON_ALLOW_TRAILING_COMMAS, NULL, &error_msg));
+ scoped_ptr<base::DictionaryValue> result_dict;
+ if (result && result->IsType(base::Value::TYPE_DICTIONARY)) {
+ result_dict.reset(static_cast<base::DictionaryValue*>(result.release()));
+ } else {
+ ADD_FAILURE() << "Failed to parse \"" << json << "\": " << error_msg;
+ result_dict.reset(new base::DictionaryValue());
+ }
+ return result_dict.Pass();
+}
+
} // namespace test_util
} // namespace extensions
diff --git a/extensions/common/test_util.h b/extensions/common/test_util.h
index e38b28f..54d985b 100644
--- a/extensions/common/test_util.h
+++ b/extensions/common/test_util.h
@@ -8,6 +8,11 @@
#include <string>
#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+
+namespace base {
+class DictionaryValue;
+} // namespace base
namespace extensions {
class Extension;
@@ -21,6 +26,12 @@ ExtensionBuilder& BuildExtension(ExtensionBuilder& builder);
// Return a very simple extension with a given |id|.
scoped_refptr<Extension> CreateExtensionWithID(const std::string& id);
+// Parses |json| allowing trailing commas and replacing single quotes with
+// double quotes for test readability. If the json fails to parse, calls gtest's
+// ADD_FAILURE and returns an empty dictionary.
+scoped_ptr<base::DictionaryValue> ParseJsonDictionaryWithSingleQuotes(
+ std::string json);
+
} // namespace test_util
} // namespace extensions
diff --git a/extensions/extensions.gyp b/extensions/extensions.gyp
index 4c69d6f..a3d7635 100644
--- a/extensions/extensions.gyp
+++ b/extensions/extensions.gyp
@@ -270,6 +270,7 @@
'extensions_browser',
'extensions_common',
'../base/base.gyp:base',
+ '../testing/gtest.gyp:gtest',
],
'include_dirs': [
'..',