summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorrafaelw@chromium.org <rafaelw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-25 21:03:23 +0000
committerrafaelw@chromium.org <rafaelw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-25 21:03:23 +0000
commita9b00acc0c03fff42673e3eb0d953768640a5fb1 (patch)
tree06b8d431e7760a10fcab5ee2a2493b8b22118fca /chrome
parent6501bc016d78c6d419b89bf991314148e6e4494b (diff)
downloadchromium_src-a9b00acc0c03fff42673e3eb0d953768640a5fb1.zip
chromium_src-a9b00acc0c03fff42673e3eb0d953768640a5fb1.tar.gz
chromium_src-a9b00acc0c03fff42673e3eb0d953768640a5fb1.tar.bz2
Refactored ExtensionsPrefs to store paths relative to the extensions install directory. Fix & reenabled two extensions_service unit_tests.
R=erikkay BUG=14714 Review URL: http://codereview.chromium.org/140018 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@19285 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/extensions/extension_browsertest.cc21
-rw-r--r--chrome/browser/extensions/extension_prefs.cc73
-rw-r--r--chrome/browser/extensions/extension_prefs.h17
-rw-r--r--chrome/browser/extensions/extensions_service.cc6
-rw-r--r--chrome/browser/extensions/extensions_service.h10
-rw-r--r--chrome/browser/extensions/extensions_service_unittest.cc233
-rw-r--r--chrome/browser/profile.cc6
-rw-r--r--chrome/common/extensions/extension.cc7
-rw-r--r--chrome/test/data/extensions/bad/Extensions/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/1/manifest.json (renamed from chrome/test/data/extensions/bad/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/1/manifest.json)0
-rw-r--r--chrome/test/data/extensions/bad/Extensions/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Current Version (renamed from chrome/test/data/extensions/bad/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Current Version)0
-rw-r--r--chrome/test/data/extensions/bad/Extensions/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/1/not_a_manifest (renamed from chrome/test/data/extensions/bad/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/1/not_a_manifest)0
-rw-r--r--chrome/test/data/extensions/bad/Extensions/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/Current Version (renamed from chrome/test/data/extensions/bad/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/Current Version)0
-rw-r--r--chrome/test/data/extensions/bad/Extensions/bjafgdebaacbbbecmhlhpofkepfkgcpa/1.0/manifest.json (renamed from chrome/test/data/extensions/bad/bjafgdebaacbbbecmhlhpofkepfkgcpa/1.0/manifest.json)0
-rw-r--r--chrome/test/data/extensions/bad/Extensions/bjafgdebaacbbbecmhlhpofkepfkgcpa/Current Version (renamed from chrome/test/data/extensions/bad/bjafgdebaacbbbecmhlhpofkepfkgcpa/Current Version)0
-rw-r--r--chrome/test/data/extensions/bad/Extensions/cccccccccccccccccccccccccccccccc/git_abhors_empty_dirs (renamed from chrome/test/data/extensions/bad/cccccccccccccccccccccccccccccccc/git_abhors_empty_dirs)0
-rwxr-xr-xchrome/test/data/extensions/bad/Preferences26
-rw-r--r--chrome/test/data/extensions/good/Extensions/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/js_files/script3.js (renamed from chrome/test/data/extensions/good/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/js_files/script3.js)0
-rw-r--r--chrome/test/data/extensions/good/Extensions/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/manifest.json (renamed from chrome/test/data/extensions/good/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/manifest.json)0
-rw-r--r--chrome/test/data/extensions/good/Extensions/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/script1.js (renamed from chrome/test/data/extensions/good/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/script1.js)0
-rw-r--r--chrome/test/data/extensions/good/Extensions/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/script2.js (renamed from chrome/test/data/extensions/good/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/script2.js)0
-rw-r--r--chrome/test/data/extensions/good/Extensions/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/style1.css (renamed from chrome/test/data/extensions/good/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/style1.css)0
-rw-r--r--chrome/test/data/extensions/good/Extensions/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/style2.css (renamed from chrome/test/data/extensions/good/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/style2.css)0
-rw-r--r--chrome/test/data/extensions/good/Extensions/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/toolstrip1.html (renamed from chrome/test/data/extensions/good/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/toolstrip1.html)0
-rw-r--r--chrome/test/data/extensions/good/Extensions/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/toolstrip2.html (renamed from chrome/test/data/extensions/good/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/toolstrip2.html)0
-rw-r--r--chrome/test/data/extensions/good/Extensions/behllobkkfkfnphdnhnkndlbkcpglgmj/Current Version (renamed from chrome/test/data/extensions/good/behllobkkfkfnphdnhnkndlbkcpglgmj/Current Version)0
-rw-r--r--chrome/test/data/extensions/good/Extensions/bjafgdebaacbbbecmhlhpofkepfkgcpa/1.0/manifest.json (renamed from chrome/test/data/extensions/good/bjafgdebaacbbbecmhlhpofkepfkgcpa/1.0/manifest.json)0
-rw-r--r--chrome/test/data/extensions/good/Extensions/bjafgdebaacbbbecmhlhpofkepfkgcpa/Current Version (renamed from chrome/test/data/extensions/good/bjafgdebaacbbbecmhlhpofkepfkgcpa/Current Version)0
-rw-r--r--chrome/test/data/extensions/good/Extensions/hpiknbiabeeppbpihjehijgoemciehgk/2/background.html (renamed from chrome/test/data/extensions/good/hpiknbiabeeppbpihjehijgoemciehgk/2/background.html)0
-rw-r--r--chrome/test/data/extensions/good/Extensions/hpiknbiabeeppbpihjehijgoemciehgk/2/content_plugin.dll (renamed from chrome/test/data/extensions/good/hpiknbiabeeppbpihjehijgoemciehgk/2/content_plugin.dll)0
-rw-r--r--chrome/test/data/extensions/good/Extensions/hpiknbiabeeppbpihjehijgoemciehgk/2/extension_plugin.dll (renamed from chrome/test/data/extensions/good/hpiknbiabeeppbpihjehijgoemciehgk/2/extension_plugin.dll)0
-rw-r--r--chrome/test/data/extensions/good/Extensions/hpiknbiabeeppbpihjehijgoemciehgk/2/manifest.json (renamed from chrome/test/data/extensions/good/hpiknbiabeeppbpihjehijgoemciehgk/2/manifest.json)4
-rw-r--r--chrome/test/data/extensions/good/Extensions/hpiknbiabeeppbpihjehijgoemciehgk/Current Version (renamed from chrome/test/data/extensions/good/hpiknbiabeeppbpihjehijgoemciehgk/Current Version)0
-rwxr-xr-xchrome/test/data/extensions/good/Preferences21
33 files changed, 333 insertions, 91 deletions
diff --git a/chrome/browser/extensions/extension_browsertest.cc b/chrome/browser/extensions/extension_browsertest.cc
index 3df4183..3680fdf 100644
--- a/chrome/browser/extensions/extension_browsertest.cc
+++ b/chrome/browser/extensions/extension_browsertest.cc
@@ -27,8 +27,8 @@ namespace {
const int kAlertTimeoutMs = 20000;
// The extensions we're using as our test case.
-const char* kGoodExtension1Id = "00123456789abcdef0123456789abcdef0123456";
-const char* kGoodCrxId = "00123456789abcdef0123456789abcdef0123456";
+const char* kGoodExtension1Id = "behllobkkfkfnphdnhnkndlbkcpglgmj";
+const char* kGoodCrxId = "ldnnhddmnhbkjipkidpdiheffobcpfmf";
}; // namespace
@@ -80,9 +80,6 @@ class ExtensionViewTest : public InProcessBrowserTest {
// with the wrong MessageLoop.
ExtensionErrorReporter::Init(false);
- // Use single-process in an attempt to speed it up and make it less flaky.
- //EnableSingleProcess();
-
InProcessBrowserTest::SetUp();
}
virtual void SetUpCommandLine(CommandLine* command_line) {
@@ -97,8 +94,11 @@ IN_PROC_BROWSER_TEST_F(ExtensionViewTest, DISABLED_Toolstrip) {
// Get the path to our extension.
FilePath path;
ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &path));
- path = path.AppendASCII("extensions").
- AppendASCII("good").AppendASCII("extension1").AppendASCII("1");
+ path = path.AppendASCII("extensions")
+ .AppendASCII("good")
+ .AppendASCII("Extensions")
+ .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
+ .AppendASCII("1.0.0.0");
ASSERT_TRUE(file_util::DirectoryExists(path)); // sanity check
// Wait for the extension to load and grab a pointer to it.
@@ -128,8 +128,11 @@ IN_PROC_BROWSER_TEST_F(ExtensionViewTest, DISABLED_Shelf) {
// Get the path to our extension.
FilePath path;
ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &path));
- path = path.AppendASCII("extensions").
- AppendASCII("good").AppendASCII("extension1").AppendASCII("1");
+ path = path.AppendASCII("extensions")
+ .AppendASCII("good")
+ .AppendASCII("Extensions")
+ .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
+ .AppendASCII("1.0.0.0");
ASSERT_TRUE(file_util::DirectoryExists(path)); // sanity check
// Wait for the extension to load and grab a pointer to it.
diff --git a/chrome/browser/extensions/extension_prefs.cc b/chrome/browser/extensions/extension_prefs.cc
index 32d6fd5..08a99a4 100644
--- a/chrome/browser/extensions/extension_prefs.cc
+++ b/chrome/browser/extensions/extension_prefs.cc
@@ -68,11 +68,76 @@ void InstalledExtensions::VisitInstalledExtensions(
////////////////////////////////////////////////////////////////////////////////
-ExtensionPrefs::ExtensionPrefs(PrefService* prefs) : prefs_(prefs) {
+ExtensionPrefs::ExtensionPrefs(PrefService* prefs, const FilePath& root_dir)
+ : prefs_(prefs),
+ install_directory_(root_dir) {
if (!prefs_->FindPreference(kExtensionsPref))
prefs_->RegisterDictionaryPref(kExtensionsPref);
if (!prefs->FindPreference(kExtensionShelf))
prefs->RegisterListPref(kExtensionShelf);
+ MakePathsRelative();
+}
+
+static FilePath::StringType MakePathRelative(const FilePath& parent,
+ const FilePath& child,
+ bool *dirty) {
+ if (!parent.IsParent(child))
+ return child.value();
+
+ if (dirty)
+ *dirty = true;
+ FilePath::StringType retval = child.value().substr(
+ parent.value().length());
+ if (FilePath::IsSeparator(retval[0]))
+ return retval.substr(1);
+ else
+ return retval;
+}
+
+void ExtensionPrefs::MakePathsRelative() {
+ bool dirty = false;
+ const DictionaryValue* dict = prefs_->GetMutableDictionary(kExtensionsPref);
+ if (!dict || dict->GetSize() == 0)
+ return;
+
+ for (DictionaryValue::key_iterator i = dict->begin_keys();
+ i != dict->end_keys(); ++i) {
+ DictionaryValue* extension_dict;
+ if (!dict->GetDictionary(*i, &extension_dict))
+ continue;
+ FilePath::StringType path_string;
+ if (!extension_dict->GetString(kPrefPath, &path_string))
+ continue;
+ FilePath path(path_string);
+ if (path.IsAbsolute()) {
+ extension_dict->SetString(kPrefPath,
+ MakePathRelative(install_directory_, path, &dirty));
+ }
+ }
+ if (dirty)
+ prefs_->ScheduleSavePersistentPrefs();
+}
+
+void ExtensionPrefs::MakePathsAbsolute(DictionaryValue* dict) {
+ if (!dict || dict->GetSize() == 0)
+ return;
+
+ for (DictionaryValue::key_iterator i = dict->begin_keys();
+ i != dict->end_keys(); ++i) {
+ DictionaryValue* extension_dict;
+ if (!dict->GetDictionary(*i, &extension_dict)) {
+ NOTREACHED();
+ continue;
+ }
+ FilePath::StringType path_string;
+ if (!extension_dict->GetString(kPrefPath, &path_string)) {
+ NOTREACHED();
+ continue;
+ }
+ DCHECK(!FilePath(path_string).IsAbsolute());
+ extension_dict->SetString(
+ kPrefPath, install_directory_.Append(path_string).value());
+ }
}
DictionaryValue* ExtensionPrefs::CopyCurrentExtensions() {
@@ -80,6 +145,7 @@ DictionaryValue* ExtensionPrefs::CopyCurrentExtensions() {
if (extensions) {
DictionaryValue* copy =
static_cast<DictionaryValue*>(extensions->DeepCopy());
+ MakePathsAbsolute(copy);
return copy;
}
return new DictionaryValue;
@@ -144,8 +210,9 @@ void ExtensionPrefs::OnExtensionInstalled(Extension* extension) {
Value::CreateIntegerValue(Extension::ENABLED));
UpdateExtensionPref(id, kPrefLocation,
Value::CreateIntegerValue(extension->location()));
- UpdateExtensionPref(id, kPrefPath,
- Value::CreateStringValue(extension->path().value()));
+ FilePath::StringType path = MakePathRelative(install_directory_,
+ extension->path(), NULL);
+ UpdateExtensionPref(id, kPrefPath, Value::CreateStringValue(path));
prefs_->ScheduleSavePersistentPrefs();
}
diff --git a/chrome/browser/extensions/extension_prefs.h b/chrome/browser/extensions/extension_prefs.h
index be769a2..277b9c3 100644
--- a/chrome/browser/extensions/extension_prefs.h
+++ b/chrome/browser/extensions/extension_prefs.h
@@ -19,7 +19,7 @@
// from there.
class ExtensionPrefs {
public:
- explicit ExtensionPrefs(PrefService* prefs);
+ explicit ExtensionPrefs(PrefService* prefs, const FilePath& root_dir_);
// Returns a copy of the Extensions prefs.
// TODO(erikkay) Remove this so that external consumers don't need to be
@@ -43,7 +43,19 @@ class ExtensionPrefs {
void OnExtensionUninstalled(const Extension* extension,
bool external_uninstall);
+ // Returns base extensions install directory.
+ const FilePath& install_directory() const { return install_directory_; }
+
private:
+
+ // Converts absolute paths in the pref to paths relative to the
+ // install_directory_.
+ void MakePathsRelative();
+
+ // Converts internal relative paths to be absolute. Used for export to
+ // consumers who expect full paths.
+ void MakePathsAbsolute(DictionaryValue* dict);
+
// Sets the pref |key| for extension |id| to |value|.
bool UpdateExtensionPref(const std::string& id,
const std::wstring& key,
@@ -58,6 +70,9 @@ class ExtensionPrefs {
// The pref service specific to this set of extension prefs.
PrefService* prefs_;
+ // Base extensions install directory.
+ FilePath install_directory_;
+
// The URLs of all of the toolstrips.
URLList shelf_order_;
diff --git a/chrome/browser/extensions/extensions_service.cc b/chrome/browser/extensions/extensions_service.cc
index 0a4d2be..18f5862 100644
--- a/chrome/browser/extensions/extensions_service.cc
+++ b/chrome/browser/extensions/extensions_service.cc
@@ -215,12 +215,14 @@ class ExtensionsServiceBackend::UnpackerClient
ExtensionsService::ExtensionsService(Profile* profile,
const CommandLine* command_line,
+ PrefService* prefs,
+ const FilePath& install_directory,
MessageLoop* frontend_loop,
MessageLoop* backend_loop)
- : extension_prefs_(new ExtensionPrefs(profile->GetPrefs())),
+ : extension_prefs_(new ExtensionPrefs(prefs, install_directory)),
extension_process_manager_(new ExtensionProcessManager(profile)),
backend_loop_(backend_loop),
- install_directory_(profile->GetPath().AppendASCII(kInstallDirectoryName)),
+ install_directory_(install_directory),
extensions_enabled_(false),
show_extensions_prompts_(true),
ready_(false) {
diff --git a/chrome/browser/extensions/extensions_service.h b/chrome/browser/extensions/extensions_service.h
index b239422..ea83cd2 100644
--- a/chrome/browser/extensions/extensions_service.h
+++ b/chrome/browser/extensions/extensions_service.h
@@ -74,8 +74,14 @@ class ExtensionsService
// The signature follows.
};
+ // The name of the directory inside the profile where extensions are
+ // installed to.
+ static const char* kInstallDirectoryName;
+
ExtensionsService(Profile* profile,
const CommandLine* command_line,
+ PrefService* prefs,
+ const FilePath& install_directory,
MessageLoop* frontend_loop,
MessageLoop* backend_loop);
~ExtensionsService();
@@ -196,10 +202,6 @@ class ExtensionsService
void OnExtensionOverinstallAttempted(const std::string& id,
const FilePath& path);
- // The name of the directory inside the profile where extensions are
- // installed to.
- static const char* kInstallDirectoryName;
-
// Preferences for the owning profile.
scoped_ptr<ExtensionPrefs> extension_prefs_;
diff --git a/chrome/browser/extensions/extensions_service_unittest.cc b/chrome/browser/extensions/extensions_service_unittest.cc
index 1d6bab4..e59807b 100644
--- a/chrome/browser/extensions/extensions_service_unittest.cc
+++ b/chrome/browser/extensions/extensions_service_unittest.cc
@@ -202,10 +202,18 @@ class ExtensionsServiceTest
NotificationService::AllSources());
registrar_.Add(this, NotificationType::THEME_INSTALLED,
NotificationService::AllSources());
+ }
+ virtual void InitializeExtensionsService(const FilePath& pref_file,
+ const FilePath& extensions_install_dir) {
+ prefs_.reset(new PrefService(pref_file, NULL));
profile_.reset(new TestingProfile());
- service_ = new ExtensionsService(
- profile_.get(), CommandLine::ForCurrentProcess(), &loop_, &loop_);
+ service_ = new ExtensionsService(profile_.get(),
+ CommandLine::ForCurrentProcess(),
+ prefs_.get(),
+ extensions_install_dir,
+ &loop_,
+ &loop_);
service_->SetExtensionsEnabled(true);
service_->set_show_extensions_prompts(false);
@@ -219,6 +227,38 @@ class ExtensionsServiceTest
total_successes_ = 0;
}
+ virtual void InitializeInstalledExtensionsService(const FilePath& prefs_file,
+ const FilePath& source_install_dir) {
+ FilePath path_;
+ ASSERT_TRUE(PathService::Get(base::DIR_TEMP, &path_));
+ path_ = path_.Append(FILE_PATH_LITERAL("TestingExtensionsPath"));
+ file_util::Delete(path_, true);
+ file_util::CreateDirectory(path_);
+ FilePath temp_prefs = path_.Append(FILE_PATH_LITERAL("Preferences"));
+ file_util::CopyFile(prefs_file, temp_prefs);
+
+ extensions_install_dir_ = path_.Append(FILE_PATH_LITERAL("Extensions"));
+ file_util::Delete(extensions_install_dir_, true);
+ file_util::CopyDirectory(source_install_dir, extensions_install_dir_, true);
+
+ InitializeExtensionsService(temp_prefs, extensions_install_dir_);
+ }
+
+ virtual void InitializeEmptyExtensionsService() {
+ FilePath path_;
+ ASSERT_TRUE(PathService::Get(base::DIR_TEMP, &path_));
+ path_ = path_.Append(FILE_PATH_LITERAL("TestingExtensionsPath"));
+ file_util::Delete(path_, true);
+ file_util::CreateDirectory(path_);
+ FilePath prefs_filename = path_
+ .Append(FILE_PATH_LITERAL("TestPreferences"));
+ extensions_install_dir_ = path_.Append(FILE_PATH_LITERAL("Extensions"));
+ file_util::Delete(extensions_install_dir_, true);
+ file_util::CreateDirectory(extensions_install_dir_);
+
+ InitializeExtensionsService(prefs_filename, extensions_install_dir_);
+ }
+
static void SetUpTestCase() {
ExtensionErrorReporter::Init(false); // no noisy errors
}
@@ -368,7 +408,7 @@ class ExtensionsServiceTest
void ValidatePrefKeyCount(size_t count) {
DictionaryValue* dict =
- profile_->GetPrefs()->GetMutableDictionary(L"extensions.settings");
+ prefs_->GetMutableDictionary(L"extensions.settings");
ASSERT_TRUE(dict != NULL);
EXPECT_EQ(count, dict->GetSize());
}
@@ -384,7 +424,7 @@ class ExtensionsServiceTest
msg += IntToWString(must_equal);
const DictionaryValue* dict =
- profile_->GetPrefs()->GetDictionary(L"extensions.settings");
+ prefs_->GetDictionary(L"extensions.settings");
ASSERT_TRUE(dict != NULL) << msg;
DictionaryValue* pref = NULL;
ASSERT_TRUE(dict->GetDictionary(ASCIIToWide(extension_id), &pref)) << msg;
@@ -403,7 +443,7 @@ class ExtensionsServiceTest
msg += IntToWString(value);
const DictionaryValue* dict =
- profile_->GetPrefs()->GetMutableDictionary(L"extensions.settings");
+ prefs_->GetMutableDictionary(L"extensions.settings");
ASSERT_TRUE(dict != NULL) << msg;
DictionaryValue* pref = NULL;
ASSERT_TRUE(dict->GetDictionary(ASCIIToWide(extension_id), &pref)) << msg;
@@ -412,7 +452,9 @@ class ExtensionsServiceTest
}
protected:
- scoped_ptr<TestingProfile> profile_;
+ scoped_ptr<PrefService> prefs_;
+ scoped_ptr<Profile> profile_;
+ FilePath extensions_install_dir_;
scoped_refptr<ExtensionsService> service_;
size_t total_successes_;
MessageLoop loop_;
@@ -424,18 +466,29 @@ class ExtensionsServiceTest
NotificationRegistrar registrar_;
};
-// TODO(erikkay) this test and the next need to be replaced with equivalent
-// versions that load from prefs.
+FilePath::StringType NormalizeSeperators(FilePath::StringType path) {
+#if defined(FILE_PATH_USES_WIN_SEPARATORS)
+ FilePath::StringType ret_val;
+ for (size_t i = 0; i < path.length(); i++) {
+ if (FilePath::IsSeparator(path[i]))
+ path[i] = FilePath::kSeparators[0];
+ }
+#endif // FILE_PATH_USES_WIN_SEPARATORS
+ return path;
+}
// Test loading good extensions from the profile directory.
-TEST_F(ExtensionsServiceTest, DISABLED_LoadAllExtensionsFromDirectorySuccess) {
- // Copy the test extensions into the test profile.
- FilePath source_path;
- ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &source_path));
- source_path = source_path.AppendASCII("extensions");
- source_path = source_path.AppendASCII("good");
-
- FilePath dest_path = profile_->GetPath().AppendASCII("Extensions");
- file_util::CopyDirectory(source_path, dest_path, true); // Recursive.
+TEST_F(ExtensionsServiceTest, LoadAllExtensionsFromDirectorySuccess) {
+ // Initialize the test dir with a good Preferences/extensions.
+ FilePath source_install_dir;
+ ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &source_install_dir));
+ source_install_dir = source_install_dir
+ .AppendASCII("extensions")
+ .AppendASCII("good")
+ .AppendASCII("Extensions");
+ FilePath pref_path = source_install_dir
+ .DirName()
+ .AppendASCII("Preferences");
+ InitializeInstalledExtensionsService(pref_path, source_install_dir);
service_->Init();
loop_.RunAllPending();
@@ -474,15 +527,21 @@ TEST_F(ExtensionsServiceTest, DISABLED_LoadAllExtensionsFromDirectorySuccess) {
EXPECT_EQ("https://*.google.com/*",
scripts[0].url_patterns()[1].GetAsString());
EXPECT_EQ(2u, scripts[0].js_scripts().size());
- EXPECT_EQ(extension->path().AppendASCII("script1.js").value(),
- scripts[0].js_scripts()[0].path().value());
- EXPECT_EQ(extension->path().AppendASCII("script2.js").value(),
- scripts[0].js_scripts()[1].path().value());
+ EXPECT_EQ(
+ NormalizeSeperators(extension->path().AppendASCII("script1.js").value()),
+ NormalizeSeperators(scripts[0].js_scripts()[0].path().value()));
+ EXPECT_EQ(
+ NormalizeSeperators(extension->path().AppendASCII("script2.js").value()),
+ NormalizeSeperators(scripts[0].js_scripts()[1].path().value()));
EXPECT_TRUE(extension->plugins().empty());
EXPECT_EQ(1u, scripts[1].url_patterns().size());
EXPECT_EQ("http://*.news.com/*", scripts[1].url_patterns()[0].GetAsString());
- EXPECT_EQ(extension->path().AppendASCII("js_files").AppendASCII("script3.js")
- .value(), scripts[1].js_scripts()[0].path().value());
+ EXPECT_EQ(
+ NormalizeSeperators(extension->path()
+ .AppendASCII("js_files")
+ .AppendASCII("script3.js")
+ .value()),
+ NormalizeSeperators(scripts[1].js_scripts()[0].path().value()));
const std::vector<URLPattern> permissions = extension->permissions();
ASSERT_EQ(2u, permissions.size());
EXPECT_EQ("http://*.google.com/*", permissions[0].GetAsString());
@@ -494,8 +553,10 @@ TEST_F(ExtensionsServiceTest, DISABLED_LoadAllExtensionsFromDirectorySuccess) {
EXPECT_EQ(std::string(good1), loaded_[1]->id());
EXPECT_EQ(std::string("My extension 2"), loaded_[1]->name());
EXPECT_EQ(std::string(""), loaded_[1]->description());
- EXPECT_EQ(loaded_[1]->GetResourceURL("background.html"),
- loaded_[1]->background_url());
+ // TODO(erikkay): re-enable:
+ // http://code.google.com/p/chromium/issues/detail?id=15363.
+ // EXPECT_EQ(loaded_[1]->GetResourceURL("background.html"),
+ // loaded_[1]->background_url());
EXPECT_EQ(0u, loaded_[1]->content_scripts().size());
EXPECT_EQ(2u, loaded_[1]->plugins().size());
EXPECT_EQ(loaded_[1]->path().AppendASCII("content_plugin.dll").value(),
@@ -514,23 +575,25 @@ TEST_F(ExtensionsServiceTest, DISABLED_LoadAllExtensionsFromDirectorySuccess) {
};
// Test loading bad extensions from the profile directory.
-TEST_F(ExtensionsServiceTest, DISABLED_LoadAllExtensionsFromDirectoryFail) {
- FilePath source_path;
- ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &source_path));
- source_path = source_path.AppendASCII("extensions");
- source_path = source_path.AppendASCII("bad");
-
- FilePath dest_path = profile_->GetPath().AppendASCII("Extensions");
- file_util::CopyDirectory(source_path, dest_path, true); // Recursive.
+TEST_F(ExtensionsServiceTest, LoadAllExtensionsFromDirectoryFail) {
+ // Initialize the test dir with a good Preferences/extensions.
+ FilePath source_install_dir;
+ ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &source_install_dir));
+ source_install_dir = source_install_dir
+ .AppendASCII("extensions")
+ .AppendASCII("bad")
+ .AppendASCII("Extensions");
+ FilePath pref_path = source_install_dir
+ .DirName()
+ .AppendASCII("Preferences");
+
+ InitializeInstalledExtensionsService(pref_path, source_install_dir);
service_->Init();
loop_.RunAllPending();
- EXPECT_EQ(3u, GetErrors().size());
- EXPECT_EQ(0u, loaded_.size());
-
- // Make sure the dictionary is empty.
- ValidatePrefKeyCount(0);
+ ASSERT_EQ(4u, GetErrors().size());
+ ASSERT_EQ(0u, loaded_.size());
EXPECT_TRUE(MatchPattern(GetErrors()[0],
std::string("Could not load extension from '*'. * ") +
@@ -543,29 +606,39 @@ TEST_F(ExtensionsServiceTest, DISABLED_LoadAllExtensionsFromDirectoryFail) {
EXPECT_TRUE(MatchPattern(GetErrors()[2],
std::string("Could not load extension from '*'. ") +
Extension::kMissingFileError)) << GetErrors()[2];
+
+ EXPECT_TRUE(MatchPattern(GetErrors()[3],
+ std::string("Could not load extension from '*'. ") +
+ Extension::kInvalidManifestError)) << GetErrors()[3];
};
// Test that partially deleted extensions are cleaned up during startup
// Test loading bad extensions from the profile directory.
TEST_F(ExtensionsServiceTest, CleanupOnStartup) {
+ InitializeEmptyExtensionsService();
+
FilePath source_path;
ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &source_path));
- source_path = source_path.AppendASCII("extensions");
- source_path = source_path.AppendASCII("good");
+ source_path = source_path.AppendASCII("extensions")
+ .AppendASCII("good")
+ .AppendASCII("Extensions");
+
+ file_util::Delete(extensions_install_dir_, true);
- FilePath dest_path = profile_->GetPath().AppendASCII("Extensions");
- file_util::CopyDirectory(source_path, dest_path, true); // Recursive.
+ // Recursive.
+ file_util::CopyDirectory(source_path, extensions_install_dir_, true);
// Simulate that one of them got partially deleted by deling the
// Current Version file.
- FilePath vers = dest_path.AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
+ FilePath vers = extensions_install_dir_
+ .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
.AppendASCII(ExtensionsService::kCurrentVersionFileName);
ASSERT_TRUE(file_util::Delete(vers, false)); // not recursive
service_->Init();
loop_.RunAllPending();
- file_util::FileEnumerator dirs(dest_path, false,
+ file_util::FileEnumerator dirs(extensions_install_dir_, false,
file_util::FileEnumerator::DIRECTORIES);
size_t count = 0;
while (!dirs.Next().empty())
@@ -581,6 +654,8 @@ TEST_F(ExtensionsServiceTest, CleanupOnStartup) {
// Test installing extensions.
TEST_F(ExtensionsServiceTest, InstallExtension) {
+ InitializeEmptyExtensionsService();
+
FilePath extensions_path;
ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
extensions_path = extensions_path.AppendASCII("extensions");
@@ -632,11 +707,15 @@ TEST_F(ExtensionsServiceTest, InstallExtension) {
// Test Packaging and installing an extension.
// TODO(rafaelw): add more tests for failure cases.
TEST_F(ExtensionsServiceTest, PackExtension) {
+ InitializeEmptyExtensionsService();
FilePath extensions_path;
ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
extensions_path = extensions_path.AppendASCII("extensions");
- FilePath input_directory = extensions_path.AppendASCII("good")
- .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj").AppendASCII("1.0.0.0");
+ FilePath input_directory = extensions_path
+ .AppendASCII("good")
+ .AppendASCII("Extensions")
+ .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
+ .AppendASCII("1.0.0.0");
FilePath output_directory;
file_util::CreateNewTempDirectory(FILE_PATH_LITERAL("chrome_"),
@@ -662,11 +741,15 @@ TEST_F(ExtensionsServiceTest, PackExtension) {
// The privkey.pem is a PrivateKey, and the pcks8 -topk8 creates a
// PrivateKeyInfo ASN.1 structure, we our RSAPrivateKey expects.
TEST_F(ExtensionsServiceTest, PackExtensionOpenSSLKey) {
+ InitializeEmptyExtensionsService();
FilePath extensions_path;
ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
extensions_path = extensions_path.AppendASCII("extensions");
- FilePath input_directory = extensions_path.AppendASCII("good")
- .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj").AppendASCII("1.0.0.0");
+ FilePath input_directory = extensions_path
+ .AppendASCII("good")
+ .AppendASCII("Extensions")
+ .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
+ .AppendASCII("1.0.0.0");
FilePath privkey_path(extensions_path.AppendASCII(
"openssl_privkey_asn1.pem"));
ASSERT_TRUE(file_util::PathExists(privkey_path));
@@ -687,6 +770,7 @@ TEST_F(ExtensionsServiceTest, PackExtensionOpenSSLKey) {
#endif // defined(OS_WIN)
TEST_F(ExtensionsServiceTest, InstallTheme) {
+ InitializeEmptyExtensionsService();
FilePath extensions_path;
ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
extensions_path = extensions_path.AppendASCII("extensions");
@@ -723,6 +807,7 @@ TEST_F(ExtensionsServiceTest, InstallTheme) {
// Test that when an extension version is reinstalled, nothing happens.
TEST_F(ExtensionsServiceTest, Reinstall) {
+ InitializeEmptyExtensionsService();
FilePath extensions_path;
ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
extensions_path = extensions_path.AppendASCII("extensions");
@@ -757,6 +842,7 @@ TEST_F(ExtensionsServiceTest, Reinstall) {
// Test upgrading a signed extension.
TEST_F(ExtensionsServiceTest, UpgradeSignedGood) {
+ InitializeEmptyExtensionsService();
FilePath extensions_path;
ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
extensions_path = extensions_path.AppendASCII("extensions");
@@ -783,6 +869,7 @@ TEST_F(ExtensionsServiceTest, UpgradeSignedGood) {
// Test upgrading a signed extension with a bad signature.
TEST_F(ExtensionsServiceTest, UpgradeSignedBad) {
+ InitializeEmptyExtensionsService();
FilePath extensions_path;
ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
extensions_path = extensions_path.AppendASCII("extensions");
@@ -809,6 +896,7 @@ TEST_F(ExtensionsServiceTest, UpgradeSignedBad) {
// Test a normal update via the UpdateExtension API
TEST_F(ExtensionsServiceTest, UpdateExtension) {
+ InitializeEmptyExtensionsService();
FilePath extensions_path;
ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
extensions_path = extensions_path.AppendASCII("extensions");
@@ -827,6 +915,7 @@ TEST_F(ExtensionsServiceTest, UpdateExtension) {
// Test doing an update without passing a completion callback
TEST_F(ExtensionsServiceTest, UpdateWithoutCallback) {
+ InitializeEmptyExtensionsService();
FilePath extensions_path;
ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
extensions_path = extensions_path.AppendASCII("extensions");
@@ -845,6 +934,7 @@ TEST_F(ExtensionsServiceTest, UpdateWithoutCallback) {
// Test updating a not-already-installed extension - this should fail
TEST_F(ExtensionsServiceTest, UpdateNotInstalledExtension) {
+ InitializeEmptyExtensionsService();
FilePath extensions_path;
ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
extensions_path = extensions_path.AppendASCII("extensions");
@@ -860,6 +950,7 @@ TEST_F(ExtensionsServiceTest, UpdateNotInstalledExtension) {
// Makes sure you can't downgrade an extension via UpdateExtension
TEST_F(ExtensionsServiceTest, UpdateWillNotDowngrade) {
+ InitializeEmptyExtensionsService();
FilePath extensions_path;
ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
extensions_path = extensions_path.AppendASCII("extensions");
@@ -879,6 +970,7 @@ TEST_F(ExtensionsServiceTest, UpdateWillNotDowngrade) {
// Make sure calling update with an identical version does nothing
TEST_F(ExtensionsServiceTest, UpdateToSameVersionIsNoop) {
+ InitializeEmptyExtensionsService();
FilePath extensions_path;
ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
extensions_path = extensions_path.AppendASCII("extensions");
@@ -893,6 +985,7 @@ TEST_F(ExtensionsServiceTest, UpdateToSameVersionIsNoop) {
// Tests uninstalling normal extensions
TEST_F(ExtensionsServiceTest, UninstallExtension) {
+ InitializeEmptyExtensionsService();
FilePath extensions_path;
ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
extensions_path = extensions_path.AppendASCII("extensions");
@@ -902,9 +995,8 @@ TEST_F(ExtensionsServiceTest, UninstallExtension) {
InstallExtension(path, true);
// The directory should be there now.
- FilePath install_path = profile_->GetPath().AppendASCII("Extensions");
const char* extension_id = good_crx;
- FilePath extension_path = install_path.AppendASCII(extension_id);
+ FilePath extension_path = extensions_install_dir_.AppendASCII(extension_id);
EXPECT_TRUE(file_util::PathExists(extension_path));
ValidatePrefKeyCount(1);
@@ -944,11 +1036,14 @@ TEST_F(ExtensionsServiceTest, UninstallExtension) {
// Tests loading single extensions (like --load-extension)
TEST_F(ExtensionsServiceTest, LoadExtension) {
+ InitializeEmptyExtensionsService();
FilePath extensions_path;
ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
extensions_path = extensions_path.AppendASCII("extensions");
- FilePath ext1 = extensions_path.AppendASCII("good")
+ FilePath ext1 = extensions_path
+ .AppendASCII("good")
+ .AppendASCII("Extensions")
.AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
.AppendASCII("1.0.0.0");
service_->LoadExtension(ext1);
@@ -961,8 +1056,11 @@ TEST_F(ExtensionsServiceTest, LoadExtension) {
// --load-extension doesn't add entries to prefs
ValidatePrefKeyCount(0);
- FilePath no_manifest = extensions_path.AppendASCII("bad")
- .AppendASCII("cccccccccccccccccccccccccccccccc").AppendASCII("1");
+ FilePath no_manifest = extensions_path
+ .AppendASCII("bad")
+ //.AppendASCII("Extensions")
+ .AppendASCII("cccccccccccccccccccccccccccccccc")
+ .AppendASCII("1");
service_->LoadExtension(no_manifest);
loop_.RunAllPending();
EXPECT_EQ(1u, GetErrors().size());
@@ -982,6 +1080,7 @@ TEST_F(ExtensionsServiceTest, LoadExtension) {
// Tests that we generate IDs when they are not specified in the manifest for
// --load-extension.
TEST_F(ExtensionsServiceTest, GenerateID) {
+ InitializeEmptyExtensionsService();
Extension::ResetGeneratedIdCounter();
FilePath extensions_path;
@@ -1019,8 +1118,8 @@ TEST_F(ExtensionsServiceTest, GenerateID) {
TEST_F(ExtensionsServiceTest, ExternalInstallRegistry) {
// This should all work, even when normal extension installation is disabled.
+ InitializeEmptyExtensionsService();
SetExtensionsEnabled(false);
-
// Verify that starting with no providers loads no extensions.
service_->Init();
loop_.RunAllPending();
@@ -1084,8 +1183,7 @@ TEST_F(ExtensionsServiceTest, ExternalInstallRegistry) {
loop_.RunAllPending();
// The extension should also be gone from the install directory.
- FilePath install_path = profile_->GetPath().AppendASCII("Extensions")
- .AppendASCII(id);
+ FilePath install_path = extensions_install_dir_.AppendASCII(id);
ASSERT_FALSE(file_util::PathExists(install_path));
loaded_.clear();
@@ -1099,7 +1197,7 @@ TEST_F(ExtensionsServiceTest, ExternalInstallRegistry) {
// Now clear the preference, reinstall, then remove the reg key. The extension
// should be uninstalled.
SetPref(good_crx, L"state", Extension::ENABLED);
- profile_->GetPrefs()->ScheduleSavePersistentPrefs();
+ prefs_->ScheduleSavePersistentPrefs();
loaded_.clear();
service_->CheckForUpdates();
@@ -1125,6 +1223,7 @@ TEST_F(ExtensionsServiceTest, ExternalInstallRegistry) {
#endif
TEST_F(ExtensionsServiceTest, ExternalInstallPref) {
+ InitializeEmptyExtensionsService();
// Verify that starting with no providers loads no extensions.
service_->Init();
loop_.RunAllPending();
@@ -1188,8 +1287,7 @@ TEST_F(ExtensionsServiceTest, ExternalInstallPref) {
loop_.RunAllPending();
// The extension should also be gone from the install directory.
- FilePath install_path =
- profile_->GetPath().AppendASCII("Extensions").AppendASCII(id);
+ FilePath install_path = extensions_install_dir_.AppendASCII(id);
ASSERT_FALSE(file_util::PathExists(install_path));
loaded_.clear();
@@ -1202,7 +1300,7 @@ TEST_F(ExtensionsServiceTest, ExternalInstallPref) {
// Now clear the preference and reinstall.
SetPref(good_crx, L"state", Extension::ENABLED);
- profile_->GetPrefs()->ScheduleSavePersistentPrefs();
+ prefs_->ScheduleSavePersistentPrefs();
loaded_.clear();
service_->CheckForUpdates();
@@ -1238,6 +1336,7 @@ TEST_F(ExtensionsServiceTest, ExternalInstallPref) {
}
TEST_F(ExtensionsServiceTest, ExternalPrefProvider) {
+ InitializeEmptyExtensionsService();
std::string json_data =
"{"
"\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
@@ -1292,22 +1391,28 @@ TEST(ExtensionsServiceTestSimple, Enabledness) {
MessageLoop loop;
scoped_ptr<CommandLine> command_line;
scoped_refptr<ExtensionsService> service;
+ FilePath install_dir = profile.GetPath()
+ .AppendASCII(ExtensionsService::kInstallDirectoryName);
// By default, we are disabled.
command_line.reset(new CommandLine(L""));
- service = new ExtensionsService(&profile, command_line.get(), &loop, &loop);
+ service = new ExtensionsService(&profile, command_line.get(),
+ profile.GetPrefs(), install_dir, &loop, &loop);
EXPECT_FALSE(service->extensions_enabled());
// If either the command line or pref is set, we are enabled.
command_line->AppendSwitch(switches::kEnableExtensions);
- service = new ExtensionsService(&profile, command_line.get(), &loop, &loop);
+ service = new ExtensionsService(&profile, command_line.get(),
+ profile.GetPrefs(), install_dir, &loop, &loop);
EXPECT_TRUE(service->extensions_enabled());
profile.GetPrefs()->SetBoolean(prefs::kEnableExtensions, true);
- service = new ExtensionsService(&profile, command_line.get(), &loop, &loop);
+ service = new ExtensionsService(&profile, command_line.get(),
+ profile.GetPrefs(), install_dir, &loop, &loop);
EXPECT_TRUE(service->extensions_enabled());
command_line.reset(new CommandLine(L""));
- service = new ExtensionsService(&profile, command_line.get(), &loop, &loop);
+ service = new ExtensionsService(&profile, command_line.get(),
+ profile.GetPrefs(), install_dir, &loop, &loop);
EXPECT_TRUE(service->extensions_enabled());
}
diff --git a/chrome/browser/profile.cc b/chrome/browser/profile.cc
index 99643a1..18cd5ef 100644
--- a/chrome/browser/profile.cc
+++ b/chrome/browser/profile.cc
@@ -494,7 +494,11 @@ void ProfileImpl::InitExtensions() {
g_browser_process->file_thread()->message_loop(),
script_dir);
extensions_service_ = new ExtensionsService(
- this, CommandLine::ForCurrentProcess(), MessageLoop::current(),
+ this,
+ CommandLine::ForCurrentProcess(),
+ GetPrefs(),
+ GetPath().AppendASCII(ExtensionsService::kInstallDirectoryName),
+ MessageLoop::current(),
g_browser_process->file_thread()->message_loop());
extensions_service_->Init();
diff --git a/chrome/common/extensions/extension.cc b/chrome/common/extensions/extension.cc
index d0c3c73..9b74737 100644
--- a/chrome/common/extensions/extension.cc
+++ b/chrome/common/extensions/extension.cc
@@ -489,11 +489,8 @@ FilePath Extension::GetResourcePath(const FilePath& extension_path,
return FilePath();
// Double-check that the path we ended up with is actually inside the
- // extension root. We can do this with a simple prefix match because:
- // a) We control the prefix on both sides, and they should match.
- // b) GURL normalizes things like "../" and "//" before it gets to us.
- if (ret_val.value().find(extension_path.value() +
- FilePath::kSeparators[0]) != 0)
+ // extension root.
+ if (!extension_path.IsParent(ret_val))
return FilePath();
return ret_val;
diff --git a/chrome/test/data/extensions/bad/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/1/manifest.json b/chrome/test/data/extensions/bad/Extensions/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/1/manifest.json
index 0eb81fa..0eb81fa 100644
--- a/chrome/test/data/extensions/bad/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/1/manifest.json
+++ b/chrome/test/data/extensions/bad/Extensions/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/1/manifest.json
diff --git a/chrome/test/data/extensions/bad/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Current Version b/chrome/test/data/extensions/bad/Extensions/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Current Version
index d00491f..d00491f 100644
--- a/chrome/test/data/extensions/bad/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Current Version
+++ b/chrome/test/data/extensions/bad/Extensions/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Current Version
diff --git a/chrome/test/data/extensions/bad/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/1/not_a_manifest b/chrome/test/data/extensions/bad/Extensions/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/1/not_a_manifest
index 3aac2d6..3aac2d6 100644
--- a/chrome/test/data/extensions/bad/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/1/not_a_manifest
+++ b/chrome/test/data/extensions/bad/Extensions/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/1/not_a_manifest
diff --git a/chrome/test/data/extensions/bad/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/Current Version b/chrome/test/data/extensions/bad/Extensions/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/Current Version
index d00491f..d00491f 100644
--- a/chrome/test/data/extensions/bad/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/Current Version
+++ b/chrome/test/data/extensions/bad/Extensions/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/Current Version
diff --git a/chrome/test/data/extensions/bad/bjafgdebaacbbbecmhlhpofkepfkgcpa/1.0/manifest.json b/chrome/test/data/extensions/bad/Extensions/bjafgdebaacbbbecmhlhpofkepfkgcpa/1.0/manifest.json
index 8706e1f..8706e1f 100644
--- a/chrome/test/data/extensions/bad/bjafgdebaacbbbecmhlhpofkepfkgcpa/1.0/manifest.json
+++ b/chrome/test/data/extensions/bad/Extensions/bjafgdebaacbbbecmhlhpofkepfkgcpa/1.0/manifest.json
diff --git a/chrome/test/data/extensions/bad/bjafgdebaacbbbecmhlhpofkepfkgcpa/Current Version b/chrome/test/data/extensions/bad/Extensions/bjafgdebaacbbbecmhlhpofkepfkgcpa/Current Version
index d3827e7..d3827e7 100644
--- a/chrome/test/data/extensions/bad/bjafgdebaacbbbecmhlhpofkepfkgcpa/Current Version
+++ b/chrome/test/data/extensions/bad/Extensions/bjafgdebaacbbbecmhlhpofkepfkgcpa/Current Version
diff --git a/chrome/test/data/extensions/bad/cccccccccccccccccccccccccccccccc/git_abhors_empty_dirs b/chrome/test/data/extensions/bad/Extensions/cccccccccccccccccccccccccccccccc/git_abhors_empty_dirs
index f1adef6..f1adef6 100644
--- a/chrome/test/data/extensions/bad/cccccccccccccccccccccccccccccccc/git_abhors_empty_dirs
+++ b/chrome/test/data/extensions/bad/Extensions/cccccccccccccccccccccccccccccccc/git_abhors_empty_dirs
diff --git a/chrome/test/data/extensions/bad/Preferences b/chrome/test/data/extensions/bad/Preferences
new file mode 100755
index 0000000..e5eb8ac
--- /dev/null
+++ b/chrome/test/data/extensions/bad/Preferences
@@ -0,0 +1,26 @@
+{
+ "extensions": {
+ "settings": {
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa": {
+ "location": 1,
+ "path": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/1",
+ "state": 1
+ },
+ "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb": {
+ "location": 1,
+ "path": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/1",
+ "state": 1
+ },
+ "bjafgdebaacbbbecmhlhpofkepfkgcpa": {
+ "location": 1,
+ "path": "bjafgdebaacbbbecmhlhpofkepfkgcpa/1.0",
+ "state": 1
+ },
+ "cccccccccccccccccccccccccccccccc": {
+ "location": 1,
+ "path": "cccccccccccccccccccccccccccccccc/1.0",
+ "state": 1
+ }
+ }
+ }
+}
diff --git a/chrome/test/data/extensions/good/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/js_files/script3.js b/chrome/test/data/extensions/good/Extensions/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/js_files/script3.js
index a149c12..a149c12 100644
--- a/chrome/test/data/extensions/good/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/js_files/script3.js
+++ b/chrome/test/data/extensions/good/Extensions/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/js_files/script3.js
diff --git a/chrome/test/data/extensions/good/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/manifest.json b/chrome/test/data/extensions/good/Extensions/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/manifest.json
index 544b6b6..544b6b6 100644
--- a/chrome/test/data/extensions/good/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/manifest.json
+++ b/chrome/test/data/extensions/good/Extensions/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/manifest.json
diff --git a/chrome/test/data/extensions/good/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/script1.js b/chrome/test/data/extensions/good/Extensions/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/script1.js
index 3a7479e..3a7479e 100644
--- a/chrome/test/data/extensions/good/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/script1.js
+++ b/chrome/test/data/extensions/good/Extensions/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/script1.js
diff --git a/chrome/test/data/extensions/good/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/script2.js b/chrome/test/data/extensions/good/Extensions/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/script2.js
index 4ffd7b9..4ffd7b9 100644
--- a/chrome/test/data/extensions/good/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/script2.js
+++ b/chrome/test/data/extensions/good/Extensions/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/script2.js
diff --git a/chrome/test/data/extensions/good/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/style1.css b/chrome/test/data/extensions/good/Extensions/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/style1.css
index 2676c97..2676c97 100644
--- a/chrome/test/data/extensions/good/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/style1.css
+++ b/chrome/test/data/extensions/good/Extensions/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/style1.css
diff --git a/chrome/test/data/extensions/good/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/style2.css b/chrome/test/data/extensions/good/Extensions/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/style2.css
index c851a8f..c851a8f 100644
--- a/chrome/test/data/extensions/good/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/style2.css
+++ b/chrome/test/data/extensions/good/Extensions/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/style2.css
diff --git a/chrome/test/data/extensions/good/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/toolstrip1.html b/chrome/test/data/extensions/good/Extensions/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/toolstrip1.html
index d36de21..d36de21 100644
--- a/chrome/test/data/extensions/good/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/toolstrip1.html
+++ b/chrome/test/data/extensions/good/Extensions/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/toolstrip1.html
diff --git a/chrome/test/data/extensions/good/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/toolstrip2.html b/chrome/test/data/extensions/good/Extensions/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/toolstrip2.html
index 23a2edf..23a2edf 100644
--- a/chrome/test/data/extensions/good/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/toolstrip2.html
+++ b/chrome/test/data/extensions/good/Extensions/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/toolstrip2.html
diff --git a/chrome/test/data/extensions/good/behllobkkfkfnphdnhnkndlbkcpglgmj/Current Version b/chrome/test/data/extensions/good/Extensions/behllobkkfkfnphdnhnkndlbkcpglgmj/Current Version
index 1921233..1921233 100644
--- a/chrome/test/data/extensions/good/behllobkkfkfnphdnhnkndlbkcpglgmj/Current Version
+++ b/chrome/test/data/extensions/good/Extensions/behllobkkfkfnphdnhnkndlbkcpglgmj/Current Version
diff --git a/chrome/test/data/extensions/good/bjafgdebaacbbbecmhlhpofkepfkgcpa/1.0/manifest.json b/chrome/test/data/extensions/good/Extensions/bjafgdebaacbbbecmhlhpofkepfkgcpa/1.0/manifest.json
index a7d4e32..a7d4e32 100644
--- a/chrome/test/data/extensions/good/bjafgdebaacbbbecmhlhpofkepfkgcpa/1.0/manifest.json
+++ b/chrome/test/data/extensions/good/Extensions/bjafgdebaacbbbecmhlhpofkepfkgcpa/1.0/manifest.json
diff --git a/chrome/test/data/extensions/good/bjafgdebaacbbbecmhlhpofkepfkgcpa/Current Version b/chrome/test/data/extensions/good/Extensions/bjafgdebaacbbbecmhlhpofkepfkgcpa/Current Version
index d3827e7..d3827e7 100644
--- a/chrome/test/data/extensions/good/bjafgdebaacbbbecmhlhpofkepfkgcpa/Current Version
+++ b/chrome/test/data/extensions/good/Extensions/bjafgdebaacbbbecmhlhpofkepfkgcpa/Current Version
diff --git a/chrome/test/data/extensions/good/hpiknbiabeeppbpihjehijgoemciehgk/2/background.html b/chrome/test/data/extensions/good/Extensions/hpiknbiabeeppbpihjehijgoemciehgk/2/background.html
index 741876f..741876f 100644
--- a/chrome/test/data/extensions/good/hpiknbiabeeppbpihjehijgoemciehgk/2/background.html
+++ b/chrome/test/data/extensions/good/Extensions/hpiknbiabeeppbpihjehijgoemciehgk/2/background.html
diff --git a/chrome/test/data/extensions/good/hpiknbiabeeppbpihjehijgoemciehgk/2/content_plugin.dll b/chrome/test/data/extensions/good/Extensions/hpiknbiabeeppbpihjehijgoemciehgk/2/content_plugin.dll
index e69de29..e69de29 100644
--- a/chrome/test/data/extensions/good/hpiknbiabeeppbpihjehijgoemciehgk/2/content_plugin.dll
+++ b/chrome/test/data/extensions/good/Extensions/hpiknbiabeeppbpihjehijgoemciehgk/2/content_plugin.dll
diff --git a/chrome/test/data/extensions/good/hpiknbiabeeppbpihjehijgoemciehgk/2/extension_plugin.dll b/chrome/test/data/extensions/good/Extensions/hpiknbiabeeppbpihjehijgoemciehgk/2/extension_plugin.dll
index e69de29..e69de29 100644
--- a/chrome/test/data/extensions/good/hpiknbiabeeppbpihjehijgoemciehgk/2/extension_plugin.dll
+++ b/chrome/test/data/extensions/good/Extensions/hpiknbiabeeppbpihjehijgoemciehgk/2/extension_plugin.dll
diff --git a/chrome/test/data/extensions/good/hpiknbiabeeppbpihjehijgoemciehgk/2/manifest.json b/chrome/test/data/extensions/good/Extensions/hpiknbiabeeppbpihjehijgoemciehgk/2/manifest.json
index 39cd652..c6da352 100644
--- a/chrome/test/data/extensions/good/hpiknbiabeeppbpihjehijgoemciehgk/2/manifest.json
+++ b/chrome/test/data/extensions/good/Extensions/hpiknbiabeeppbpihjehijgoemciehgk/2/manifest.json
@@ -5,6 +5,6 @@
"plugins": [
{ "path": "content_plugin.dll", "public": true },
{ "path": "extension_plugin.dll" }
- ],
- "background_page": "background.html"
+ ]
+ /* "background_page": "background.html" */
}
diff --git a/chrome/test/data/extensions/good/hpiknbiabeeppbpihjehijgoemciehgk/Current Version b/chrome/test/data/extensions/good/Extensions/hpiknbiabeeppbpihjehijgoemciehgk/Current Version
index 0cfbf08..0cfbf08 100644
--- a/chrome/test/data/extensions/good/hpiknbiabeeppbpihjehijgoemciehgk/Current Version
+++ b/chrome/test/data/extensions/good/Extensions/hpiknbiabeeppbpihjehijgoemciehgk/Current Version
diff --git a/chrome/test/data/extensions/good/Preferences b/chrome/test/data/extensions/good/Preferences
new file mode 100755
index 0000000..b0c0012
--- /dev/null
+++ b/chrome/test/data/extensions/good/Preferences
@@ -0,0 +1,21 @@
+{
+ "extensions": {
+ "settings": {
+ "behllobkkfkfnphdnhnkndlbkcpglgmj": {
+ "location": 1,
+ "path": "behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0",
+ "state": 1
+ },
+ "bjafgdebaacbbbecmhlhpofkepfkgcpa": {
+ "location": 1,
+ "path": "bjafgdebaacbbbecmhlhpofkepfkgcpa/1.0",
+ "state": 1
+ },
+ "hpiknbiabeeppbpihjehijgoemciehgk": {
+ "location": 1,
+ "path": "hpiknbiabeeppbpihjehijgoemciehgk/2",
+ "state": 1
+ }
+ }
+ }
+}