diff options
Diffstat (limited to 'extensions')
-rw-r--r-- | extensions/common/manifest.cc | 3 | ||||
-rw-r--r-- | extensions/common/manifest_constants.cc | 7 | ||||
-rw-r--r-- | extensions/common/manifest_constants.h | 4 | ||||
-rw-r--r-- | extensions/common/manifest_handlers/background_info.cc | 96 | ||||
-rw-r--r-- | extensions/common/manifest_handlers/background_info.h | 11 | ||||
-rw-r--r-- | extensions/common/test_util.cc | 19 | ||||
-rw-r--r-- | extensions/common/test_util.h | 11 | ||||
-rw-r--r-- | extensions/extensions.gyp | 1 |
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': [ '..', |