From 37cd64d34bc3dbf2385a3c312c92bb3c7c65664a Mon Sep 17 00:00:00 2001
From: "tessamac@google.com"
@@ -350,13 +352,14 @@ are name and version.
"background_page": "aFile.html",
"chrome_url_overrides": {...},
"content_scripts": [...],
+ "homepage_url": "http://path/to/homepage",
+ "incognito": "split or spanning",
"key": "publicKey",
"minimum_chrome_version": "versionString",
"options_page": "aFile.html",
"permissions": [...],
"plugins": [...],
"update_url": "http://path/to/updateInfo.xml"
- "incognito": "split or spanning",
}
@@ -370,6 +373,19 @@ with links to where they're described in detail,
see the Field summary.
+Specifies the subdirectory of _locales
+that contains the default strings for this extension.
+This field is required in extensions
+that have a _locales
directory;
+it must be absent in extensions
+that have no _locales
directory.
+For details, see
+Internationalization.
+
@@ -384,6 +400,15 @@ You can specify locale-specific strings for this field; see Internationalization for details.
++The URL of the homepage for this extension. The extensions management page (chrome://extensions) +will contain a link to this URL. This field is particularly useful if you +host the extension on your own site. If you distribute your +extension using the gallery, +the homepage URL defaults to the extension's own gallery page. +
If you submit your extension to the gallery, @@ -441,17 +464,34 @@ see the gallery help.
-
-Specifies the subdirectory of _locales
-that contains the default strings for this extension.
-This field is required in extensions
-that have a _locales
directory;
-it must be absent in extensions
-that have no _locales
directory.
-For details, see
-Internationalization.
+Either split or spanning, to specify how this extension will
+behave if allowed to run in incognito.
+
+spanning is the default for extensions, and means that the extension +will run in a single shared process. Any events or messages from an incognito +tab will be sent to the shared process, with an incognito flag +indicating where it came from. +
+ ++split is the default for apps, and it means that all app pages in +an incognito window will run in their own incognito process. If the app or extension contains a background page, that will also run in the incognito process. +This incognito process runs along side the regular process, but has a separate +memory-only cookie store. Each process sees events and messages only from its +own context (e.g. the incognito process will only see incognito tab updates). +The processes are unable to communicate with each other. +
+ ++As a rule of thumb, if your extension or app needs to load a tab in an incognito browser, use +split incognito behavior. If your extension or app needs to be logged +into a remote server or persist settings locally, use spanning +incognito behavior.
-Either split or spanning, to specify how this extension will -behave if allowed to run in incognito. -
- --spanning is the default for extensions, and means that the extension -will run in a single shared process. Any events or messages from an incognito -tab will be sent to the shared process, with an incognito flag -indicating where it came from. -
- --split is the default for apps, and it means that all app pages in -an incognito window will run in their own incognito process. If the app or extension contains a background page, that will also run in the incognito process. -This incognito process runs along side the regular process, but has a separate -memory-only cookie store. Each process sees events and messages only from its -own context (e.g. the incognito process will only see incognito tab updates). -The processes are unable to communicate with each other. -
- --As a rule of thumb, if your extension or app needs to load a tab in an incognito browser, use -split incognito behavior. If your extension or app needs to be logged -into a remote server or persist settings locally, use spanning -incognito behavior. -
- diff --git a/chrome/common/extensions/docs/static/manifest.html b/chrome/common/extensions/docs/static/manifest.html index 5e1758c..3b0af0d 100644 --- a/chrome/common/extensions/docs/static/manifest.html +++ b/chrome/common/extensions/docs/static/manifest.html @@ -37,13 +37,14 @@ are name and version. "background_page": "aFile.html", "chrome_url_overrides": {...}, "content_scripts": [...], + "homepage_url": "http://path/to/homepage", + "incognito": "split or spanning", "key": "publicKey", "minimum_chrome_version": "versionString", "options_page": "aFile.html", "permissions": [...], "plugins": [...], "update_url": "http://path/to/updateInfo.xml" - "incognito": "split or spanning", } @@ -57,6 +58,19 @@ with links to where they're described in detail, see the Field summary. +
+Specifies the subdirectory of _locales
+that contains the default strings for this extension.
+This field is required in extensions
+that have a _locales
directory;
+it must be absent in extensions
+that have no _locales
directory.
+For details, see
+Internationalization.
+
@@ -71,6 +85,15 @@ You can specify locale-specific strings for this field; see Internationalization for details.
++The URL of the homepage for this extension. The extensions management page (chrome://extensions) +will contain a link to this URL. This field is particularly useful if you +host the extension on your own site. If you distribute your +extension using the gallery, +the homepage URL defaults to the extension's own gallery page. +
If you submit your extension to the gallery, @@ -129,17 +150,34 @@ see the gallery help.
-
-Specifies the subdirectory of _locales
-that contains the default strings for this extension.
-This field is required in extensions
-that have a _locales
directory;
-it must be absent in extensions
-that have no _locales
directory.
-For details, see
-Internationalization.
+Either split or spanning, to specify how this extension will
+behave if allowed to run in incognito.
+
+spanning is the default for extensions, and means that the extension +will run in a single shared process. Any events or messages from an incognito +tab will be sent to the shared process, with an incognito flag +indicating where it came from. +
+ ++split is the default for apps, and it means that all app pages in +an incognito window will run in their own incognito process. If the app or extension contains a background page, that will also run in the incognito process. +This incognito process runs along side the regular process, but has a separate +memory-only cookie store. Each process sees events and messages only from its +own context (e.g. the incognito process will only see incognito tab updates). +The processes are unable to communicate with each other. +
+ ++As a rule of thumb, if your extension or app needs to load a tab in an incognito browser, use +split incognito behavior. If your extension or app needs to be logged +into a remote server or persist settings locally, use spanning +incognito behavior.
-Either split or spanning, to specify how this extension will -behave if allowed to run in incognito. -
- --spanning is the default for extensions, and means that the extension -will run in a single shared process. Any events or messages from an incognito -tab will be sent to the shared process, with an incognito flag -indicating where it came from. -
- --split is the default for apps, and it means that all app pages in -an incognito window will run in their own incognito process. If the app or extension contains a background page, that will also run in the incognito process. -This incognito process runs along side the regular process, but has a separate -memory-only cookie store. Each process sees events and messages only from its -own context (e.g. the incognito process will only see incognito tab updates). -The processes are unable to communicate with each other. -
- --As a rule of thumb, if your extension or app needs to load a tab in an incognito browser, use -split incognito behavior. If your extension or app needs to be logged -into a remote server or persist settings locally, use spanning -incognito behavior. -
- diff --git a/chrome/common/extensions/extension.cc b/chrome/common/extensions/extension.cc index e3254d8..de50d07 100644 --- a/chrome/common/extensions/extension.cc +++ b/chrome/common/extensions/extension.cc @@ -1263,6 +1263,22 @@ bool Extension::InitFromValue(const DictionaryValue& source, bool require_key, } } + // Initialize homepage url (if present). + if (source.HasKey(keys::kHomepageURL)) { + std::string tmp; + if (!source.GetString(keys::kHomepageURL, &tmp)) { + *error = ExtensionErrorUtils::FormatErrorMessage( + errors::kInvalidHomepageURL, ""); + return false; + } + mutable_static_data_->homepage_url = GURL(tmp); + if (!mutable_static_data_->homepage_url.is_valid()) { + *error = ExtensionErrorUtils::FormatErrorMessage( + errors::kInvalidHomepageURL, tmp); + return false; + } + } + // Initialize update url (if present). if (source.HasKey(keys::kUpdateURL)) { std::string tmp; @@ -1854,15 +1870,18 @@ std::string Extension::ChromeStoreLaunchURL() { return gallery_prefix; } -GURL Extension::GalleryUrl() const { - if (!update_url().DomainIs("google.com")) +GURL Extension::GetHomepageURL() const { + if (static_data_->homepage_url.is_valid()) + return static_data_->homepage_url; + + if (update_url()!= GURL(extension_urls::kGalleryUpdateHttpsUrl) && + update_url()!= GURL(extension_urls::kGalleryUpdateHttpUrl)) return GURL(); // TODO(erikkay): This may not be entirely correct with the webstore. // I think it will have a mixture of /extensions/detail and /webstore/detail // URLs. Perhaps they'll handle this nicely with redirects? GURL url(ChromeStoreLaunchURL() + std::string("/detail/") + id()); - return url; } diff --git a/chrome/common/extensions/extension.h b/chrome/common/extensions/extension.h index c90928e..4aa662d 100644 --- a/chrome/common/extensions/extension.h +++ b/chrome/common/extensions/extension.h @@ -217,6 +217,10 @@ class Extension { // The sites this extension has permission to talk to (using XHR, etc). URLPatternList host_permissions; + // The homepage for this extension. Useful if it is not hosted by Google and + // therefore does not have a Gallery URL. + GURL homepage_url; + // URL for fetching an update manifest GURL update_url; @@ -554,9 +558,10 @@ class Extension { return static_data_->icons; } - // Returns the Google Gallery URL for this extension, if one exists. For + // Returns the Homepage URL for this extension. If homepage_url was not + // specified in the manifest, this returns the Google Gallery URL. For // third-party extensions, this returns a blank GURL. - GURL GalleryUrl() const; + GURL GetHomepageURL() const; // Theme-related. DictionaryValue* GetThemeImages() const { diff --git a/chrome/common/extensions/extension_constants.cc b/chrome/common/extensions/extension_constants.cc index 983fda4a..5e418b5 100644 --- a/chrome/common/extensions/extension_constants.cc +++ b/chrome/common/extensions/extension_constants.cc @@ -19,6 +19,7 @@ const char* kDefaultLocale = "default_locale"; const char* kDescription = "description"; const char* kDevToolsPage = "devtools_page"; const char* kExcludeGlobs = "exclude_globs"; +const char* kHomepageURL = "homepage_url"; const char* kIcons = "icons"; const char* kIncognito = "incognito"; const char* kIncludeGlobs = "include_globs"; @@ -124,6 +125,8 @@ const char* kInvalidGlob = "Invalid value for 'content_scripts[*].*[*]'."; const char* kInvalidGlobList = "Invalid value for 'content_scripts[*].*'."; +const char* kInvalidHomepageURL = + "Invalid value for homepage url: '[*]'."; const char* kInvalidIconPath = "Invalid value for 'icons[\"*\"]'."; const char* kInvalidIcons = diff --git a/chrome/common/extensions/extension_constants.h b/chrome/common/extensions/extension_constants.h index e76ce24..332f386 100644 --- a/chrome/common/extensions/extension_constants.h +++ b/chrome/common/extensions/extension_constants.h @@ -24,6 +24,7 @@ namespace extension_manifest_keys { extern const char* kDescription; extern const char* kDevToolsPage; extern const char* kExcludeGlobs; + extern const char* kHomepageURL; extern const char* kIcons; extern const char* kIncognito; extern const char* kIncludeGlobs; @@ -108,6 +109,7 @@ namespace extension_manifest_errors { extern const char* kInvalidDevToolsPage; extern const char* kInvalidGlob; extern const char* kInvalidGlobList; + extern const char* kInvalidHomepageURL; extern const char* kInvalidIconPath; extern const char* kInvalidIcons; extern const char* kInvalidIncognitoBehavior; diff --git a/chrome/common/extensions/extension_manifests_unittest.cc b/chrome/common/extensions/extension_manifests_unittest.cc index ac56f70..66d6b35 100644 --- a/chrome/common/extensions/extension_manifests_unittest.cc +++ b/chrome/common/extensions/extension_manifests_unittest.cc @@ -338,3 +338,26 @@ TEST_F(ExtensionManifestTest, DisallowMultipleUISurfaces) { LoadAndExpectError("multiple_ui_surfaces_2.json", errors::kOneUISurfaceOnly); LoadAndExpectError("multiple_ui_surfaces_3.json", errors::kOneUISurfaceOnly); } + +TEST_F(ExtensionManifestTest, ParseHomepageURLs) { + LoadAndExpectSuccess("homepage_valid.json"); + LoadAndExpectError("homepage_empty.json", + extension_manifest_errors::kInvalidHomepageURL); + LoadAndExpectError("homepage_invalid.json", + extension_manifest_errors::kInvalidHomepageURL); +} + +TEST_F(ExtensionManifestTest, GetHomepageURL) { + scoped_ptr