diff options
18 files changed, 120 insertions, 32 deletions
diff --git a/chrome/browser/extensions/api/developer_private/extension_info_generator.cc b/chrome/browser/extensions/api/developer_private/extension_info_generator.cc index 316997c..85d58c8 100644 --- a/chrome/browser/extensions/api/developer_private/extension_info_generator.cc +++ b/chrome/browser/extensions/api/developer_private/extension_info_generator.cc @@ -29,6 +29,7 @@ #include "extensions/browser/extension_prefs.h" #include "extensions/browser/extension_registry.h" #include "extensions/browser/extension_system.h" +#include "extensions/browser/extension_util.h" #include "extensions/browser/image_loader.h" #include "extensions/browser/warning_service.h" #include "extensions/common/extension_set.h" @@ -400,7 +401,7 @@ void ExtensionInfoGenerator::CreateExtensionInfoHelper( info->id = extension.id(); // Incognito access. - info->incognito_access.is_enabled = extension.can_be_incognito_enabled(); + info->incognito_access.is_enabled = util::CanBeIncognitoEnabled(&extension); info->incognito_access.is_active = util::IsIncognitoEnabled(extension.id(), browser_context_); diff --git a/chrome/browser/extensions/api/messaging/message_service.cc b/chrome/browser/extensions/api/messaging/message_service.cc index 36e1e32..5c1a219 100644 --- a/chrome/browser/extensions/api/messaging/message_service.cc +++ b/chrome/browser/extensions/api/messaging/message_service.cc @@ -37,6 +37,7 @@ #include "extensions/browser/extension_host.h" #include "extensions/browser/extension_registry.h" #include "extensions/browser/extension_system.h" +#include "extensions/browser/extension_util.h" #include "extensions/browser/extensions_browser_client.h" #include "extensions/browser/guest_view/web_view/web_view_guest.h" #include "extensions/browser/lazy_background_task_queue.h" @@ -371,7 +372,7 @@ void MessageService::OpenChannelToExtension( // that surface (e.g. chrome://extensions) should be the only one for // enabling in incognito. In practice this means platform apps only. if (!is_web_connection || IncognitoInfo::IsSplitMode(target_extension) || - target_extension->can_be_incognito_enabled()) { + util::CanBeIncognitoEnabled(target_extension)) { OnOpenChannelAllowed(params.Pass(), false); return; } diff --git a/chrome/browser/extensions/extension_util.cc b/chrome/browser/extensions/extension_util.cc index a4b12f3..97a0177 100644 --- a/chrome/browser/extensions/extension_util.cc +++ b/chrome/browser/extensions/extension_util.cc @@ -119,7 +119,7 @@ bool IsIncognitoEnabled(const std::string& extension_id, const Extension* extension = ExtensionRegistry::Get(context)-> GetExtensionById(extension_id, ExtensionRegistry::ENABLED); if (extension) { - if (!extension->can_be_incognito_enabled()) + if (!util::CanBeIncognitoEnabled(extension)) return false; // If this is an existing component extension we always allow it to // work in incognito mode. @@ -139,7 +139,7 @@ void SetIsIncognitoEnabled(const std::string& extension_id, registry->GetExtensionById(extension_id, ExtensionRegistry::EVERYTHING); if (extension) { - if (!extension->can_be_incognito_enabled()) + if (!util::CanBeIncognitoEnabled(extension)) return; // TODO(treib,kalman): Should this be Manifest::IsComponentLocation(..)? diff --git a/chrome/browser/extensions/installed_loader.cc b/chrome/browser/extensions/installed_loader.cc index 9d562c4..8ee9a02 100644 --- a/chrome/browser/extensions/installed_loader.cc +++ b/chrome/browser/extensions/installed_loader.cc @@ -28,6 +28,7 @@ #include "extensions/browser/extension_prefs.h" #include "extensions/browser/extension_registry.h" #include "extensions/browser/extension_system.h" +#include "extensions/browser/extension_util.h" #include "extensions/browser/management_policy.h" #include "extensions/common/extension.h" #include "extensions/common/extension_l10n_util.h" @@ -511,7 +512,7 @@ void InstalledLoader::RecordExtensionsMetrics() { // extensions are boring. if (extension->ShouldDisplayInExtensionSettings() && !Manifest::IsPolicyLocation(extension->location())) { - if (extension->can_be_incognito_enabled()) { + if (util::CanBeIncognitoEnabled(extension)) { if (util::IsIncognitoEnabled(extension->id(), profile)) ++incognito_allowed_count; else diff --git a/extensions/browser/extension_util.cc b/extensions/browser/extension_util.cc index d8dbe62..23de130 100644 --- a/extensions/browser/extension_util.cc +++ b/extensions/browser/extension_util.cc @@ -7,6 +7,7 @@ #include "extensions/browser/extension_prefs.h" #include "extensions/browser/extension_registry.h" #include "extensions/common/manifest_handlers/app_isolation_info.h" +#include "extensions/common/manifest_handlers/incognito_info.h" namespace extensions { namespace util { @@ -48,5 +49,11 @@ bool SiteHasIsolatedStorage(const GURL& extension_site_url, return extension && AppIsolationInfo::HasIsolatedStorage(extension); } +bool CanBeIncognitoEnabled(const Extension* extension) { + return IncognitoInfo::IsIncognitoAllowed(extension) && + (!extension->is_platform_app() || + extension->location() == Manifest::COMPONENT); +} + } // namespace util } // namespace extensions diff --git a/extensions/browser/extension_util.h b/extensions/browser/extension_util.h index 6bd3c86..b5f758e 100644 --- a/extensions/browser/extension_util.h +++ b/extensions/browser/extension_util.h @@ -14,7 +14,7 @@ class BrowserContext; } namespace extensions { - +class Extension; struct ExtensionInfo; namespace util { @@ -40,6 +40,9 @@ bool HasIsolatedStorage(const ExtensionInfo& info); bool SiteHasIsolatedStorage(const GURL& extension_site_url, content::BrowserContext* context); +// Returns true if the extension can be enabled in incognito mode. +bool CanBeIncognitoEnabled(const Extension* extension); + } // namespace util } // namespace extensions diff --git a/extensions/common/extension.cc b/extensions/common/extension.cc index 8aefc6a..9328ba2 100644 --- a/extensions/common/extension.cc +++ b/extensions/common/extension.cc @@ -28,6 +28,7 @@ #include "extensions/common/manifest.h" #include "extensions/common/manifest_constants.h" #include "extensions/common/manifest_handler.h" +#include "extensions/common/manifest_handlers/incognito_info.h" #include "extensions/common/manifest_handlers/permissions_parser.h" #include "extensions/common/permissions/permission_set.h" #include "extensions/common/permissions/permissions_data.h" @@ -438,11 +439,6 @@ bool Extension::is_theme() const { return manifest()->is_theme(); } -bool Extension::can_be_incognito_enabled() const { - // Only component platform apps are supported in incognito. - return !is_platform_app() || location() == Manifest::COMPONENT; -} - void Extension::AddWebExtentPattern(const URLPattern& pattern) { // Bookmark apps are permissionless. if (from_bookmark()) diff --git a/extensions/common/extension.h b/extensions/common/extension.h index c4934d8..4d7f568 100644 --- a/extensions/common/extension.h +++ b/extensions/common/extension.h @@ -358,8 +358,6 @@ class Extension : public base::RefCountedThreadSafe<Extension> { bool is_shared_module() const; bool is_theme() const; - bool can_be_incognito_enabled() const; - void AddWebExtentPattern(const URLPattern& pattern); const URLPatternSet& web_extent() const { return extent_; } diff --git a/extensions/common/manifest_constants.cc b/extensions/common/manifest_constants.cc index 6dd9a41..5d9ea2d 100644 --- a/extensions/common/manifest_constants.cc +++ b/extensions/common/manifest_constants.cc @@ -195,6 +195,7 @@ namespace manifest_values { const char kApiKey[] = "api_key"; const char kBrowserActionCommandEvent[] = "_execute_browser_action"; +const char kIncognitoNotAllowed[] = "not_allowed"; const char kIncognitoSplit[] = "split"; const char kIncognitoSpanning[] = "spanning"; const char kIsolatedStorage[] = "storage"; diff --git a/extensions/common/manifest_constants.h b/extensions/common/manifest_constants.h index 791d504..6b296c9 100644 --- a/extensions/common/manifest_constants.h +++ b/extensions/common/manifest_constants.h @@ -195,6 +195,7 @@ namespace manifest_values { extern const char kApiKey[]; extern const char kBrowserActionCommandEvent[]; +extern const char kIncognitoNotAllowed[]; extern const char kIncognitoSplit[]; extern const char kIncognitoSpanning[]; extern const char kIsolatedStorage[]; diff --git a/extensions/common/manifest_handlers/incognito_info.cc b/extensions/common/manifest_handlers/incognito_info.cc index 02c3b28..b7dc8b2 100644 --- a/extensions/common/manifest_handlers/incognito_info.cc +++ b/extensions/common/manifest_handlers/incognito_info.cc @@ -14,9 +14,7 @@ namespace extensions { namespace keys = manifest_keys; -IncognitoInfo::IncognitoInfo(bool incognito_split_mode) - : split_mode(incognito_split_mode) { -} +IncognitoInfo::IncognitoInfo(Mode mode) : mode(mode) {} IncognitoInfo::~IncognitoInfo() { } @@ -25,7 +23,14 @@ IncognitoInfo::~IncognitoInfo() { bool IncognitoInfo::IsSplitMode(const Extension* extension) { IncognitoInfo* info = static_cast<IncognitoInfo*>( extension->GetManifestData(keys::kIncognito)); - return info ? info->split_mode : false; + return info ? info->mode == Mode::SPLIT : false; +} + +// static +bool IncognitoInfo::IsIncognitoAllowed(const Extension* extension) { + IncognitoInfo* info = + static_cast<IncognitoInfo*>(extension->GetManifestData(keys::kIncognito)); + return info ? info->mode != Mode::NOT_ALLOWED : true; } IncognitoHandler::IncognitoHandler() { @@ -35,33 +40,35 @@ IncognitoHandler::~IncognitoHandler() { } bool IncognitoHandler::Parse(Extension* extension, base::string16* error) { + // Extensions and Chrome apps default to spanning mode. + // Hosted and legacy packaged apps default to split mode. + IncognitoInfo::Mode mode = + extension->is_hosted_app() || extension->is_legacy_packaged_app() + ? IncognitoInfo::Mode::SPLIT + : IncognitoInfo::Mode::SPANNING; if (!extension->manifest()->HasKey(keys::kIncognito)) { - // Extensions and Chrome apps default to spanning mode. - // Hosted and legacy packaged apps default to split mode. - extension->SetManifestData( - keys::kIncognito, - new IncognitoInfo(extension->is_hosted_app() || - extension->is_legacy_packaged_app())); + extension->SetManifestData(keys::kIncognito, new IncognitoInfo(mode)); return true; } - bool split_mode = false; std::string incognito_string; if (!extension->manifest()->GetString(keys::kIncognito, &incognito_string)) { *error = base::ASCIIToUTF16(manifest_errors::kInvalidIncognitoBehavior); return false; } - if (incognito_string == manifest_values::kIncognitoSplit) - split_mode = true; - else if (incognito_string != manifest_values::kIncognitoSpanning) { - // If incognito_string == kIncognitoSpanning, it is valid and - // split_mode remains false. + if (incognito_string == manifest_values::kIncognitoSplit) { + mode = IncognitoInfo::Mode::SPLIT; + } else if (incognito_string == manifest_values::kIncognitoSpanning) { + mode = IncognitoInfo::Mode::SPANNING; + } else if (incognito_string == manifest_values::kIncognitoNotAllowed) { + mode = IncognitoInfo::Mode::NOT_ALLOWED; + } else { *error = base::ASCIIToUTF16(manifest_errors::kInvalidIncognitoBehavior); return false; } - extension->SetManifestData(keys::kIncognito, new IncognitoInfo(split_mode)); + extension->SetManifestData(keys::kIncognito, new IncognitoInfo(mode)); return true; } diff --git a/extensions/common/manifest_handlers/incognito_info.h b/extensions/common/manifest_handlers/incognito_info.h index 0b7a870..c217a23 100644 --- a/extensions/common/manifest_handlers/incognito_info.h +++ b/extensions/common/manifest_handlers/incognito_info.h @@ -12,15 +12,22 @@ namespace extensions { struct IncognitoInfo : public Extension::ManifestData { - explicit IncognitoInfo(bool split_mode); + enum Mode { SPLIT, SPANNING, NOT_ALLOWED }; + + explicit IncognitoInfo(Mode mode); + ~IncognitoInfo() override; // If true, a separate process will be used for the extension in incognito // mode. - bool split_mode; + Mode mode; // Return the incognito mode information for the given |extension|. static bool IsSplitMode(const Extension* extension); + + // Return whether this extension can be run in incognito mode as specified + // in its manifest. + static bool IsIncognitoAllowed(const Extension* extension); }; // Parses the "incognito" manifest key. diff --git a/extensions/common/manifest_handlers/incognito_manifest_unittest.cc b/extensions/common/manifest_handlers/incognito_manifest_unittest.cc new file mode 100644 index 0000000..0551162 --- /dev/null +++ b/extensions/common/manifest_handlers/incognito_manifest_unittest.cc @@ -0,0 +1,45 @@ +// Copyright 2015 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/browser/extension_util.h" +#include "extensions/common/extension.h" +#include "extensions/common/manifest_handlers/incognito_info.h" +#include "extensions/common/manifest_test.h" + +namespace extensions { + +using IncognitoManifestTest = ManifestTest; + +TEST_F(IncognitoManifestTest, IncognitoNotAllowed) { + scoped_refptr<Extension> extension( + LoadAndExpectSuccess("incognito_not_allowed.json")); + EXPECT_FALSE(IncognitoInfo::IsIncognitoAllowed(extension.get())); + EXPECT_FALSE(IncognitoInfo::IsSplitMode(extension.get())); + EXPECT_FALSE(util::CanBeIncognitoEnabled(extension.get())); +} + +TEST_F(IncognitoManifestTest, IncognitoSpanning) { + scoped_refptr<Extension> extension( + LoadAndExpectSuccess("incognito_spanning.json")); + EXPECT_TRUE(IncognitoInfo::IsIncognitoAllowed(extension.get())); + EXPECT_FALSE(IncognitoInfo::IsSplitMode(extension.get())); + EXPECT_TRUE(util::CanBeIncognitoEnabled(extension.get())); +} + +TEST_F(IncognitoManifestTest, IncognitoSplit) { + scoped_refptr<Extension> extension( + LoadAndExpectSuccess("incognito_split.json")); + EXPECT_TRUE(IncognitoInfo::IsIncognitoAllowed(extension.get())); + EXPECT_TRUE(IncognitoInfo::IsSplitMode(extension.get())); + EXPECT_TRUE(util::CanBeIncognitoEnabled(extension.get())); +} + +TEST_F(IncognitoManifestTest, IncognitoUnspecified) { + scoped_refptr<Extension> extension(LoadAndExpectSuccess("minimal.json")); + EXPECT_TRUE(IncognitoInfo::IsIncognitoAllowed(extension.get())); + EXPECT_FALSE(IncognitoInfo::IsSplitMode(extension.get())); + EXPECT_TRUE(util::CanBeIncognitoEnabled(extension.get())); +} + +} // namespace extensions diff --git a/extensions/extensions_tests.gypi b/extensions/extensions_tests.gypi index e380f27..2019e37 100644 --- a/extensions/extensions_tests.gypi +++ b/extensions/extensions_tests.gypi @@ -124,6 +124,7 @@ 'common/manifest_handlers/default_locale_manifest_unittest.cc', 'common/manifest_handlers/externally_connectable_unittest.cc', 'common/manifest_handlers/file_handler_manifest_unittest.cc', + 'common/manifest_handlers/incognito_manifest_unittest.cc', 'common/manifest_handlers/kiosk_mode_info_unittest.cc', 'common/manifest_handlers/oauth2_manifest_unittest.cc', 'common/manifest_handlers/shared_module_manifest_unittest.cc', diff --git a/extensions/test/data/manifest_tests/incognito_not_allowed.json b/extensions/test/data/manifest_tests/incognito_not_allowed.json new file mode 100644 index 0000000..f44d252 --- /dev/null +++ b/extensions/test/data/manifest_tests/incognito_not_allowed.json @@ -0,0 +1,5 @@ +{ + "name": "test", + "version": "1", + "incognito": "not_allowed" +} diff --git a/extensions/test/data/manifest_tests/incognito_spanning.json b/extensions/test/data/manifest_tests/incognito_spanning.json new file mode 100644 index 0000000..7e54be4 --- /dev/null +++ b/extensions/test/data/manifest_tests/incognito_spanning.json @@ -0,0 +1,5 @@ +{ + "name": "test", + "version": "1", + "incognito": "spanning" +} diff --git a/extensions/test/data/manifest_tests/incognito_split.json b/extensions/test/data/manifest_tests/incognito_split.json new file mode 100644 index 0000000..5bb8b67 --- /dev/null +++ b/extensions/test/data/manifest_tests/incognito_split.json @@ -0,0 +1,5 @@ +{ + "name": "test", + "version": "1", + "incognito": "split" +} diff --git a/extensions/test/data/manifest_tests/minimal.json b/extensions/test/data/manifest_tests/minimal.json new file mode 100644 index 0000000..0d9792a --- /dev/null +++ b/extensions/test/data/manifest_tests/minimal.json @@ -0,0 +1,4 @@ +{ + "name": "test", + "version": "1" +} |