diff options
-rw-r--r-- | chrome/browser/extensions/extension_browsertest.cc | 5 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_prefs.cc | 10 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_prefs.h | 3 | ||||
-rw-r--r-- | chrome/browser/extensions/extensions_service.cc | 21 | ||||
-rw-r--r-- | chrome/browser/extensions/extensions_service.h | 6 | ||||
-rw-r--r-- | chrome/browser/extensions/extensions_service_unittest.cc | 169 | ||||
-rw-r--r-- | chrome/browser/extensions/extensions_ui.cc | 2 | ||||
-rw-r--r-- | chrome/browser/extensions/external_extensions.json | 3 | ||||
-rw-r--r-- | chrome/browser/extensions/external_pref_extension_provider.cc | 56 | ||||
-rw-r--r-- | chrome/browser/extensions/external_pref_extension_provider.h | 11 |
10 files changed, 215 insertions, 71 deletions
diff --git a/chrome/browser/extensions/extension_browsertest.cc b/chrome/browser/extensions/extension_browsertest.cc index e8a93ec..3df4183 100644 --- a/chrome/browser/extensions/extension_browsertest.cc +++ b/chrome/browser/extensions/extension_browsertest.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2009 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. @@ -165,5 +165,6 @@ IN_PROC_BROWSER_TEST_F(ExtensionViewTest, DISABLED_Incognito) { ASSERT_TRUE(extension); // TODO(mpcomplete): wait for uninstall to complete? - browser()->profile()->GetExtensionsService()->UninstallExtension(kGoodCrxId); + browser()->profile()->GetExtensionsService()-> + UninstallExtension(kGoodCrxId, false); } diff --git a/chrome/browser/extensions/extension_prefs.cc b/chrome/browser/extensions/extension_prefs.cc index 50618b5..32d6fd5 100644 --- a/chrome/browser/extensions/extension_prefs.cc +++ b/chrome/browser/extensions/extension_prefs.cc @@ -149,10 +149,14 @@ void ExtensionPrefs::OnExtensionInstalled(Extension* extension) { prefs_->ScheduleSavePersistentPrefs(); } -void ExtensionPrefs::OnExtensionUninstalled(const Extension* extension) { +void ExtensionPrefs::OnExtensionUninstalled(const Extension* extension, + bool external_uninstall) { // For external extensions, we save a preference reminding ourself not to try - // and install the extension anymore. - if (Extension::IsExternalLocation(extension->location())) { + // and install the extension anymore (except when |external_uninstall| is + // true, which signifies that the registry key was deleted or the pref file + // no longer lists the extension). + if (!external_uninstall && + Extension::IsExternalLocation(extension->location())) { UpdateExtensionPref(extension->id(), kPrefState, Value::CreateIntegerValue(Extension::KILLBIT)); prefs_->ScheduleSavePersistentPrefs(); diff --git a/chrome/browser/extensions/extension_prefs.h b/chrome/browser/extensions/extension_prefs.h index a6e7ec4..be769a2 100644 --- a/chrome/browser/extensions/extension_prefs.h +++ b/chrome/browser/extensions/extension_prefs.h @@ -40,7 +40,8 @@ class ExtensionPrefs { void OnExtensionInstalled(Extension* extension); // Called when an extension is uninstalled, so that prefs get cleaned up. - void OnExtensionUninstalled(const Extension* extension); + void OnExtensionUninstalled(const Extension* extension, + bool external_uninstall); private: // Sets the pref |key| for extension |id| to |value|. diff --git a/chrome/browser/extensions/extensions_service.cc b/chrome/browser/extensions/extensions_service.cc index dde2ddc..0a4d2be 100644 --- a/chrome/browser/extensions/extensions_service.cc +++ b/chrome/browser/extensions/extensions_service.cc @@ -230,11 +230,9 @@ ExtensionsService::ExtensionsService(Profile* profile, else if (profile->GetPrefs()->GetBoolean(prefs::kEnableExtensions)) extensions_enabled_ = true; - // We pass ownership of this object to the Backend. - DictionaryValue* extensions = extension_prefs_->CopyCurrentExtensions(); backend_ = new ExtensionsServiceBackend( install_directory_, g_browser_process->resource_dispatcher_host(), - frontend_loop, extensions, extensions_enabled()); + frontend_loop, extensions_enabled()); } ExtensionsService::~ExtensionsService() { @@ -300,13 +298,14 @@ void ExtensionsService::UpdateExtension(const std::string& id, alert_on_error, scoped_refptr<ExtensionsService>(this))); } -void ExtensionsService::UninstallExtension(const std::string& extension_id) { +void ExtensionsService::UninstallExtension(const std::string& extension_id, + bool external_uninstall) { Extension* extension = GetExtensionById(extension_id); // Callers should not send us nonexistant extensions. DCHECK(extension); - extension_prefs_->OnExtensionUninstalled(extension); + extension_prefs_->OnExtensionUninstalled(extension, external_uninstall); // Tell the backend to start deleting installed extensions on the file thread. if (Extension::LOAD != extension->location()) { @@ -514,8 +513,7 @@ void ExtensionsService::SetProviderForTesting( ExtensionsServiceBackend::ExtensionsServiceBackend( const FilePath& install_directory, ResourceDispatcherHost* rdh, - MessageLoop* frontend_loop, DictionaryValue* extension_prefs, - bool extensions_enabled) + MessageLoop* frontend_loop, bool extensions_enabled) : frontend_(NULL), install_directory_(install_directory), resource_dispatcher_host_(rdh), @@ -524,7 +522,7 @@ ExtensionsServiceBackend::ExtensionsServiceBackend( extensions_enabled_(extensions_enabled) { external_extension_providers_[Extension::EXTERNAL_PREF] = linked_ptr<ExternalExtensionProvider>( - new ExternalPrefExtensionProvider(extension_prefs)); + new ExternalPrefExtensionProvider()); #if defined(OS_WIN) external_extension_providers_[Extension::EXTERNAL_REGISTRY] = linked_ptr<ExternalExtensionProvider>( @@ -630,9 +628,10 @@ void ExtensionsServiceBackend::LoadSingleExtension( void ExtensionsServiceBackend::LoadInstalledExtension( const std::string& id, const FilePath& path, Extension::Location location) { if (CheckExternalUninstall(id, location)) { - // TODO(erikkay): Possibly defer this operation to avoid slowing initial - // load of extensions. - UninstallExtension(id); + frontend_loop_->PostTask(FROM_HERE, NewRunnableMethod( + frontend_, + &ExtensionsService::UninstallExtension, + id, true)); // No error needs to be reported. The extension effectively doesn't exist. return; diff --git a/chrome/browser/extensions/extensions_service.h b/chrome/browser/extensions/extensions_service.h index 653c29d..b239422 100644 --- a/chrome/browser/extensions/extensions_service.h +++ b/chrome/browser/extensions/extensions_service.h @@ -108,8 +108,9 @@ class ExtensionsService bool alert_on_error, Callback* callback); // Uninstalls the specified extension. Callers should only call this method - // with extensions that exist and are "internal". - void UninstallExtension(const std::string& extension_id); + // with extensions that exist. + void UninstallExtension(const std::string& extension_id, + bool external_uninstall); // Load the extension from the directory |extension_path|. void LoadExtension(const FilePath& extension_path); @@ -245,7 +246,6 @@ class ExtensionsServiceBackend ExtensionsServiceBackend(const FilePath& install_directory, ResourceDispatcherHost* rdh, MessageLoop* frontend_loop, - DictionaryValue* extension_prefs, bool extensions_enabled); virtual ~ExtensionsServiceBackend(); diff --git a/chrome/browser/extensions/extensions_service_unittest.cc b/chrome/browser/extensions/extensions_service_unittest.cc index 224018b..1d6bab4 100644 --- a/chrome/browser/extensions/extensions_service_unittest.cc +++ b/chrome/browser/extensions/extensions_service_unittest.cc @@ -16,6 +16,7 @@ #include "chrome/browser/extensions/extension_creator.h" #include "chrome/browser/extensions/extensions_service.h" #include "chrome/browser/extensions/external_extension_provider.h" +#include "chrome/browser/extensions/external_pref_extension_provider.h" #include "chrome/common/extensions/extension.h" #include "chrome/common/extensions/url_pattern.h" #include "chrome/common/chrome_paths.h" @@ -116,6 +117,77 @@ class MockExtensionProvider : public ExternalExtensionProvider { typedef std::map< std::string, std::pair<std::string, FilePath> > DataMap; DataMap extension_map_; Extension::Location location_; + + DISALLOW_COPY_AND_ASSIGN(MockExtensionProvider); +}; + +class MockProviderVisitor : public ExternalExtensionProvider::Visitor { + public: + MockProviderVisitor() { + } + + int Visit(std::string json_data, const std::set<std::string>& ignore_list) { + // Give the test json file to the provider for parsing. + provider_.reset(new ExternalPrefExtensionProvider()); + provider_->SetPreferencesForTesting(json_data); + + // We also parse the file into a dictionary to compare what we get back + // from the provider. + JSONStringValueSerializer serializer(json_data); + std::string error_msg; + Value* json_value = serializer.Deserialize(&error_msg); + + if (!error_msg.empty() || !json_value || + !json_value->IsType(Value::TYPE_DICTIONARY)) { + NOTREACHED() << L"Unable to deserialize json data"; + return -1; + } else { + DictionaryValue* external_extensions = + static_cast<DictionaryValue*>(json_value); + prefs_.reset(external_extensions); + } + + // Reset our counter. + ids_found_ = 0; + // Ask the provider to look up all extensions (and return the ones + // found (that are not on the ignore list). + provider_->VisitRegisteredExtension(this, ignore_list); + + return ids_found_; + } + + virtual void OnExternalExtensionFound(const std::string& id, + const Version* version, + const FilePath& path) { + ++ids_found_; + DictionaryValue* pref; + // This tests is to make sure that the provider only notifies us of the + // values we gave it. So if the id we doesn't exist in our internal + // dictionary then something is wrong. + EXPECT_TRUE(prefs_->GetDictionary(ASCIIToWide(id), &pref)) + << L"Got back ID (" << id.c_str() << ") we weren't expecting"; + + if (pref) { + // Ask provider if the extension we got back is registered. + Extension::Location location = Extension::INVALID; + scoped_ptr<Version> v1(provider_->RegisteredVersion(id, NULL)); + scoped_ptr<Version> v2(provider_->RegisteredVersion(id, &location)); + EXPECT_STREQ(version->GetString().c_str(), v1->GetString().c_str()); + EXPECT_STREQ(version->GetString().c_str(), v2->GetString().c_str()); + EXPECT_EQ(Extension::EXTERNAL_PREF, location); + + // Remove it so we won't count it ever again. + prefs_->Remove(ASCIIToWide(id), NULL); + } + } + + private: + int ids_found_; + + scoped_ptr<ExternalPrefExtensionProvider> provider_; + scoped_ptr<DictionaryValue> prefs_; + + DISALLOW_COPY_AND_ASSIGN(MockProviderVisitor); }; class ExtensionsServiceTest @@ -840,7 +912,7 @@ TEST_F(ExtensionsServiceTest, UninstallExtension) { ValidatePref(good_crx, L"location", Extension::INTERNAL); // Uninstall it. - service_->UninstallExtension(extension_id); + service_->UninstallExtension(extension_id, false); total_successes_ = 0; // We should get an unload notification. @@ -863,7 +935,7 @@ TEST_F(ExtensionsServiceTest, UninstallExtension) { FilePath current_version_file = extension_path.AppendASCII(ExtensionsService::kCurrentVersionFileName); EXPECT_TRUE(file_util::Delete(current_version_file, true)); - service_->UninstallExtension(extension_id); + service_->UninstallExtension(extension_id, false); loop_.RunAllPending(); EXPECT_FALSE(file_util::PathExists(extension_path)); @@ -900,7 +972,7 @@ TEST_F(ExtensionsServiceTest, LoadExtension) { // Test uninstall. std::string id = loaded_[0]->id(); EXPECT_FALSE(unloaded_id_.length()); - service_->UninstallExtension(id); + service_->UninstallExtension(id, false); loop_.RunAllPending(); EXPECT_EQ(id, unloaded_id_); ASSERT_EQ(0u, loaded_.size()); @@ -1005,10 +1077,10 @@ TEST_F(ExtensionsServiceTest, ExternalInstallRegistry) { ValidatePref(good_crx, L"state", Extension::ENABLED); ValidatePref(good_crx, L"location", Extension::EXTERNAL_REGISTRY); - // Uninstall the extension and reinit. Nothing should happen because the + // Uninstall the extension and reload. Nothing should happen because the // preference should prevent us from reinstalling. std::string id = loaded_[0]->id(); - service_->UninstallExtension(id); + service_->UninstallExtension(id, false); loop_.RunAllPending(); // The extension should also be gone from the install directory. @@ -1037,12 +1109,17 @@ TEST_F(ExtensionsServiceTest, ExternalInstallRegistry) { ValidatePref(good_crx, L"state", Extension::ENABLED); ValidatePref(good_crx, L"location", Extension::EXTERNAL_REGISTRY); + // Now test an externally triggered uninstall (deleting the registry key). reg_provider->RemoveExtension(good_crx); loaded_.clear(); - service_->CheckForUpdates(); + service_->LoadAllExtensions(); loop_.RunAllPending(); ASSERT_EQ(0u, loaded_.size()); + ValidatePrefKeyCount(0); + + // The extension should also be gone from the install directory. + ASSERT_FALSE(file_util::PathExists(install_path)); } #endif @@ -1075,7 +1152,6 @@ TEST_F(ExtensionsServiceTest, ExternalInstallPref) { ASSERT_EQ(1u, loaded_.size()); ASSERT_EQ(Extension::EXTERNAL_PREF, loaded_[0]->location()); ASSERT_EQ("1.0.0.0", loaded_[0]->version()->GetString()); - ValidatePrefKeyCount(1); ValidatePref(good_crx, L"state", Extension::ENABLED); ValidatePref(good_crx, L"location", Extension::EXTERNAL_PREF); @@ -1087,7 +1163,6 @@ TEST_F(ExtensionsServiceTest, ExternalInstallPref) { loop_.RunAllPending(); ASSERT_EQ(0u, GetErrors().size()); ASSERT_EQ(1u, loaded_.size()); - ValidatePrefKeyCount(1); ValidatePref(good_crx, L"state", Extension::ENABLED); ValidatePref(good_crx, L"location", Extension::EXTERNAL_PREF); @@ -1102,7 +1177,6 @@ TEST_F(ExtensionsServiceTest, ExternalInstallPref) { ASSERT_EQ(0u, GetErrors().size()); ASSERT_EQ(1u, loaded_.size()); ASSERT_EQ("1.0.0.1", loaded_[0]->version()->GetString()); - ValidatePrefKeyCount(1); ValidatePref(good_crx, L"state", Extension::ENABLED); ValidatePref(good_crx, L"location", Extension::EXTERNAL_PREF); @@ -1110,7 +1184,7 @@ TEST_F(ExtensionsServiceTest, ExternalInstallPref) { // Uninstall the extension and reload. Nothing should happen because the // preference should prevent us from reinstalling. std::string id = loaded_[0]->id(); - service_->UninstallExtension(id); + service_->UninstallExtension(id, false); loop_.RunAllPending(); // The extension should also be gone from the install directory. @@ -1122,7 +1196,6 @@ TEST_F(ExtensionsServiceTest, ExternalInstallPref) { service_->CheckForUpdates(); loop_.RunAllPending(); ASSERT_EQ(0u, loaded_.size()); - ValidatePrefKeyCount(1); ValidatePref(good_crx, L"state", Extension::KILLBIT); ValidatePref(good_crx, L"location", Extension::EXTERNAL_PREF); @@ -1135,29 +1208,21 @@ TEST_F(ExtensionsServiceTest, ExternalInstallPref) { service_->CheckForUpdates(); loop_.RunAllPending(); ASSERT_EQ(1u, loaded_.size()); - ValidatePrefKeyCount(1); ValidatePref(good_crx, L"state", Extension::ENABLED); ValidatePref(good_crx, L"location", Extension::EXTERNAL_PREF); - // Now uninstall the extension and verify that it doesn't get reinstalled. - service_->UninstallExtension(id); - loop_.RunAllPending(); + // Now test an externally triggered uninstall (deleting id from json file). + pref_provider->RemoveExtension(good_crx); loaded_.clear(); - service_->ReloadExtensions(); + service_->LoadAllExtensions(); loop_.RunAllPending(); ASSERT_EQ(0u, loaded_.size()); + ValidatePrefKeyCount(0); - ValidatePrefKeyCount(1); - ValidatePref(good_crx, L"state", Extension::KILLBIT); - ValidatePref(good_crx, L"location", Extension::EXTERNAL_PREF); - - // The extension should also be gone from disk. - FilePath extension_path = install_path.DirName(); - extension_path = extension_path.AppendASCII(good_crx); - EXPECT_FALSE(file_util::PathExists(extension_path)) << - extension_path.ToWStringHack(); + // The extension should also be gone from the install directory. + ASSERT_FALSE(file_util::PathExists(install_path)); // This shouldn't work if extensions are disabled. SetExtensionsEnabled(false); @@ -1168,11 +1233,61 @@ TEST_F(ExtensionsServiceTest, ExternalInstallPref) { ASSERT_EQ(0u, loaded_.size()); ASSERT_EQ(1u, GetErrors().size()); + ASSERT_TRUE(GetErrors()[0].find("Extensions are not enabled") != + std::string::npos); +} + +TEST_F(ExtensionsServiceTest, ExternalPrefProvider) { + std::string json_data = + "{" + "\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {" + "\"external_crx\": \"RandomExtension.crx\"," + "\"external_version\": \"1.0\"" + "}," + "\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {" + "\"external_crx\": \"RandomExtension2.crx\"," + "\"external_version\": \"2.0\"" + "}" + "}"; + + MockProviderVisitor visitor; + std::set<std::string> ignore_list; + EXPECT_EQ(2, visitor.Visit(json_data, ignore_list)); + ignore_list.insert("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); + EXPECT_EQ(1, visitor.Visit(json_data, ignore_list)); + ignore_list.insert("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"); + EXPECT_EQ(0, visitor.Visit(json_data, ignore_list)); + + // Use a json that contains three invalid extensions: + // - One that is missing the 'external_crx' key. + // - One that is missing the 'external_version' key. + // - One that is specifying .. in the path. + // - Plus one valid extension to make sure the json file is parsed properly. + json_data = + "{" + "\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {" + "\"external_version\": \"1.0\"" + "}," + "\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {" + "\"external_crx\": \"RandomExtension.crx\"" + "}," + "\"cccccccccccccccccccccccccccccccc\": {" + "\"external_crx\": \"..\\\\foo\\\\RandomExtension2.crx\"," + "\"external_version\": \"2.0\"" + "}," + "\"dddddddddddddddddddddddddddddddddd\": {" + "\"external_crx\": \"RandomValidExtension.crx\"," + "\"external_version\": \"1.0\"" + "}" + "}"; + ignore_list.clear(); + EXPECT_EQ(1, visitor.Visit(json_data, ignore_list)); } // Test that we get enabled/disabled correctly for all the pref/command-line -// combinations. -TEST(ExtensionsServiceTest2, Enabledness) { +// combinations. We don't want to derive from the ExtensionsServiceTest class +// for this test, so we use ExtensionsServiceTestSimple. +TEST(ExtensionsServiceTestSimple, Enabledness) { TestingProfile profile; MessageLoop loop; scoped_ptr<CommandLine> command_line; diff --git a/chrome/browser/extensions/extensions_ui.cc b/chrome/browser/extensions/extensions_ui.cc index 1edacb8..6f08479 100644 --- a/chrome/browser/extensions/extensions_ui.cc +++ b/chrome/browser/extensions/extensions_ui.cc @@ -127,7 +127,7 @@ void ExtensionsDOMHandler::HandleUninstallMessage(const Value* value) { CHECK(list->GetSize() == 1); std::string extension_id; CHECK(list->GetString(0, &extension_id)); - extensions_service_->UninstallExtension(extension_id); + extensions_service_->UninstallExtension(extension_id, false); } static void CreateScriptFileDetailValue( diff --git a/chrome/browser/extensions/external_extensions.json b/chrome/browser/extensions/external_extensions.json index 2021042..1ef50f3 100644 --- a/chrome/browser/extensions/external_extensions.json +++ b/chrome/browser/extensions/external_extensions.json @@ -1,2 +1,5 @@ // This json file will contain a list of extensions that will be included // in the installer. + +{ +}
\ No newline at end of file diff --git a/chrome/browser/extensions/external_pref_extension_provider.cc b/chrome/browser/extensions/external_pref_extension_provider.cc index 5d16ba0..0b31025 100644 --- a/chrome/browser/extensions/external_pref_extension_provider.cc +++ b/chrome/browser/extensions/external_pref_extension_provider.cc @@ -10,6 +10,7 @@ #include "base/path_service.h" #include "base/string_util.h" #include "base/version.h" +#include "chrome/common/json_value_serializer.h" // Constants for keeping track of extension preferences. const wchar_t kLocation[] = L"location"; @@ -17,15 +18,24 @@ const wchar_t kState[] = L"state"; const wchar_t kExternalCrx[] = L"external_crx"; const wchar_t kExternalVersion[] = L"external_version"; -ExternalPrefExtensionProvider::ExternalPrefExtensionProvider( - DictionaryValue* prefs) { - DCHECK(prefs); - prefs_.reset(prefs); +ExternalPrefExtensionProvider::ExternalPrefExtensionProvider() { + FilePath json_file; + PathService::Get(app::DIR_EXTERNAL_EXTENSIONS, &json_file); + json_file = json_file.Append(FILE_PATH_LITERAL("external_extensions.json")); + + JSONFileValueSerializer serializer(json_file); + SetPreferences(&serializer); } ExternalPrefExtensionProvider::~ExternalPrefExtensionProvider() { } +void ExternalPrefExtensionProvider::SetPreferencesForTesting( + std::string json_data_for_testing) { + JSONStringValueSerializer serializer(json_data_for_testing); + SetPreferences(&serializer); +} + void ExternalPrefExtensionProvider::VisitRegisteredExtension( Visitor* visitor, const std::set<std::string>& ids_to_ignore) const { for (DictionaryValue::key_iterator i = prefs_->begin_keys(); @@ -39,17 +49,6 @@ void ExternalPrefExtensionProvider::VisitRegisteredExtension( continue; } - int location; - if (extension->GetInteger(kLocation, &location) && - location != Extension::EXTERNAL_PREF) { - continue; - } - int state; - if (extension->GetInteger(kState, &state) && - state == Extension::KILLBIT) { - continue; - } - FilePath::StringType external_crx; std::string external_version; if (!extension->GetString(kExternalCrx, &external_crx) || @@ -74,12 +73,6 @@ void ExternalPrefExtensionProvider::VisitRegisteredExtension( path = base_path.Append(external_crx); } - if (!file_util::PathExists(path)) { - LOG(WARNING) << "Cannot find extension: " << external_crx.c_str(); - continue; // Path is neither absolute nor relative. Might be - // meta-physical, but we don't support those (yet). - } - scoped_ptr<Version> version; version.reset(Version::GetVersionFromString(external_version)); visitor->OnExternalExtensionFound( @@ -101,3 +94,24 @@ Version* ExternalPrefExtensionProvider::RegisteredVersion( *location = Extension::EXTERNAL_PREF; return Version::GetVersionFromString(external_version); } + +void ExternalPrefExtensionProvider::SetPreferences( + ValueSerializer* serializer) { + std::string error_msg; + Value* extensions = serializer->Deserialize(&error_msg); + scoped_ptr<DictionaryValue> dictionary(new DictionaryValue()); + if (!error_msg.empty()) { + NOTREACHED() << L"Unable to deserialize json data: " + << error_msg.c_str(); + } else { + // This can be null if the json file specified does not exist. + if (extensions) { + if (!extensions->IsType(Value::TYPE_DICTIONARY)) { + NOTREACHED() << L"Invalid json data"; + } else { + dictionary.reset(static_cast<DictionaryValue*>(extensions)); + } + } + } + prefs_.reset(dictionary.release()); +} diff --git a/chrome/browser/extensions/external_pref_extension_provider.h b/chrome/browser/extensions/external_pref_extension_provider.h index a52be411..67d46e3 100644 --- a/chrome/browser/extensions/external_pref_extension_provider.h +++ b/chrome/browser/extensions/external_pref_extension_provider.h @@ -13,13 +13,17 @@ class DictionaryValue; class Version; -// A specialization of the ExternalExtensionProvider that uses preferences to +// A specialization of the ExternalExtensionProvider that uses a json file to // look up which external extensions are registered. class ExternalPrefExtensionProvider : public ExternalExtensionProvider { public: - explicit ExternalPrefExtensionProvider(DictionaryValue* prefs); + explicit ExternalPrefExtensionProvider(); virtual ~ExternalPrefExtensionProvider(); + // Used only during testing to not use the json file for external extensions, + // but instead parse a json file specified by the test. + void SetPreferencesForTesting(std::string json_data_for_testing); + // ExternalExtensionProvider implementation: virtual void VisitRegisteredExtension( Visitor* visitor, const std::set<std::string>& ids_to_ignore) const; @@ -28,6 +32,9 @@ class ExternalPrefExtensionProvider : public ExternalExtensionProvider { Extension::Location* location) const; protected: scoped_ptr<DictionaryValue> prefs_; + + private: + void SetPreferences(ValueSerializer* serializer); }; #endif // CHROME_BROWSER_EXTENSIONS_EXTERNAL_PREF_EXTENSION_PROVIDER_H_ |