summaryrefslogtreecommitdiffstats
path: root/chrome/browser/extensions
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/extensions')
-rw-r--r--chrome/browser/extensions/extension_file_util.cc342
-rw-r--r--chrome/browser/extensions/extension_file_util.h83
-rw-r--r--chrome/browser/extensions/extension_file_util_unittest.cc167
-rw-r--r--chrome/browser/extensions/extensions_service.cc478
-rw-r--r--chrome/browser/extensions/extensions_service.h69
5 files changed, 647 insertions, 492 deletions
diff --git a/chrome/browser/extensions/extension_file_util.cc b/chrome/browser/extensions/extension_file_util.cc
new file mode 100644
index 0000000..15e3cf8
--- /dev/null
+++ b/chrome/browser/extensions/extension_file_util.cc
@@ -0,0 +1,342 @@
+// 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.
+
+#include "chrome/browser/extensions/extension_file_util.h"
+
+#include "base/file_util.h"
+#include "base/logging.h"
+#include "base/scoped_temp_dir.h"
+#include "base/string_util.h"
+#include "chrome/common/extensions/extension.h"
+#include "chrome/common/extensions/extension_constants.h"
+#include "chrome/common/json_value_serializer.h"
+#include "net/base/file_stream.h"
+
+namespace extension_file_util {
+
+const char kInstallDirectoryName[] = "Extensions";
+const char kCurrentVersionFileName[] = "Current Version";
+
+bool MoveDirSafely(const FilePath& source_dir, const FilePath& dest_dir) {
+ if (file_util::PathExists(dest_dir)) {
+ if (!file_util::Delete(dest_dir, true))
+ return false;
+ } else {
+ FilePath parent = dest_dir.DirName();
+ if (!file_util::DirectoryExists(parent)) {
+ if (!file_util::CreateDirectory(parent))
+ return false;
+ }
+ }
+
+ if (!file_util::Move(source_dir, dest_dir))
+ return false;
+
+ return true;
+}
+
+bool SetCurrentVersion(const FilePath& dest_dir, const std::string& version,
+ std::string* error) {
+ // Write out the new CurrentVersion file.
+ // <profile>/Extension/<name>/CurrentVersion
+ FilePath current_version = dest_dir.AppendASCII(kCurrentVersionFileName);
+ FilePath current_version_old =
+ current_version.InsertBeforeExtension(FILE_PATH_LITERAL("_old"));
+ if (file_util::PathExists(current_version_old)) {
+ if (!file_util::Delete(current_version_old, false)) {
+ *error = "Couldn't remove CurrentVersion_old file.";
+ return false;
+ }
+ }
+
+ if (file_util::PathExists(current_version)) {
+ if (!file_util::Move(current_version, current_version_old)) {
+ *error = "Couldn't move CurrentVersion file.";
+ return false;
+ }
+ }
+ net::FileStream stream;
+ int flags = base::PLATFORM_FILE_CREATE_ALWAYS | base::PLATFORM_FILE_WRITE;
+ if (stream.Open(current_version, flags) != 0)
+ return false;
+ if (stream.Write(version.c_str(), version.size(), NULL) < 0) {
+ // Restore the old CurrentVersion.
+ if (file_util::PathExists(current_version_old)) {
+ if (!file_util::Move(current_version_old, current_version)) {
+ LOG(WARNING) << "couldn't restore " << current_version_old.value() <<
+ " to " << current_version.value();
+
+ // TODO(erikkay): This is an ugly state to be in. Try harder?
+ }
+ }
+ *error = "Couldn't create CurrentVersion file.";
+ return false;
+ }
+ return true;
+}
+
+bool ReadCurrentVersion(const FilePath& dir, std::string* version_string) {
+ FilePath current_version = dir.AppendASCII(kCurrentVersionFileName);
+ if (file_util::PathExists(current_version)) {
+ if (file_util::ReadFileToString(current_version, version_string)) {
+ TrimWhitespace(*version_string, TRIM_ALL, version_string);
+ return true;
+ }
+ }
+ return false;
+}
+
+Extension::InstallType CompareToInstalledVersion(
+ const FilePath& install_directory, const std::string& id,
+ const std::string& new_version_str, std::string *current_version_str) {
+ CHECK(current_version_str);
+ FilePath dir(install_directory.AppendASCII(id.c_str()));
+ if (!ReadCurrentVersion(dir, current_version_str))
+ return Extension::NEW_INSTALL;
+
+ scoped_ptr<Version> current_version(
+ Version::GetVersionFromString(*current_version_str));
+ scoped_ptr<Version> new_version(
+ Version::GetVersionFromString(new_version_str));
+ int comp = new_version->CompareTo(*current_version);
+ if (comp > 0)
+ return Extension::UPGRADE;
+ else if (comp == 0)
+ return Extension::REINSTALL;
+ else
+ return Extension::DOWNGRADE;
+}
+
+bool SanityCheckExtension(const FilePath& dir) {
+ // Verify that the directory actually exists.
+ // TODO(erikkay): A further step would be to verify that the extension
+ // has actually loaded successfully.
+ FilePath manifest_file(dir.AppendASCII(Extension::kManifestFilename));
+ return file_util::PathExists(dir) && file_util::PathExists(manifest_file);
+}
+
+bool InstallExtension(const FilePath& src_dir,
+ const FilePath& extensions_dir,
+ const std::string& extension_id,
+ const std::string& extension_version,
+ FilePath* version_dir,
+ Extension::InstallType* install_type,
+ std::string* error) {
+ FilePath dest_dir = extensions_dir.AppendASCII(extension_id);
+ *version_dir = dest_dir.AppendASCII(extension_version);
+
+ std::string current_version;
+ *install_type = CompareToInstalledVersion(
+ extensions_dir, extension_id, extension_version, &current_version);
+
+ // Do not allow downgrade.
+ if (*install_type == Extension::DOWNGRADE)
+ return true;
+
+ if (*install_type == Extension::REINSTALL) {
+ if (!SanityCheckExtension(*version_dir)) {
+ // Treat corrupted existing installation as new install case.
+ *install_type = Extension::NEW_INSTALL;
+ } else {
+ return true;
+ }
+ }
+
+ // If anything fails after this, we want to delete the extension dir.
+ ScopedTempDir scoped_version_dir;
+ scoped_version_dir.Set(*version_dir);
+
+ if (!MoveDirSafely(src_dir, *version_dir)) {
+ *error = "Could not move extension directory into profile.";
+ return false;
+ }
+
+ if (!SetCurrentVersion(dest_dir, extension_version, error))
+ return false;
+
+ scoped_version_dir.Take();
+ return true;
+}
+
+Extension* LoadExtension(const FilePath& extension_path, bool require_key,
+ std::string* error) {
+ FilePath manifest_path =
+ extension_path.AppendASCII(Extension::kManifestFilename);
+ if (!file_util::PathExists(manifest_path)) {
+ *error = extension_manifest_errors::kInvalidManifest;
+ return NULL;
+ }
+
+ JSONFileValueSerializer serializer(manifest_path);
+ scoped_ptr<Value> root(serializer.Deserialize(error));
+ if (!root.get())
+ return NULL;
+
+ if (!root->IsType(Value::TYPE_DICTIONARY)) {
+ *error = extension_manifest_errors::kInvalidManifest;
+ return NULL;
+ }
+
+ scoped_ptr<Extension> extension(new Extension(extension_path));
+ if (!extension->InitFromValue(*static_cast<DictionaryValue*>(root.get()),
+ require_key, error))
+ return NULL;
+
+ // Validate icons exist.
+ for (std::map<int, std::string>::const_iterator iter =
+ extension->icons().begin(); iter != extension->icons().end(); ++iter) {
+ if (!file_util::PathExists(extension->GetResourcePath(iter->second))) {
+ *error = StringPrintf("Could not load extension icon '%s'.",
+ iter->second.c_str());
+ return NULL;
+ }
+ }
+
+ // Theme resource validation.
+ if (extension->IsTheme()) {
+ DictionaryValue* images_value = extension->GetThemeImages();
+ DictionaryValue::key_iterator iter = images_value->begin_keys();
+ if (images_value) {
+ while (iter != images_value->end_keys()) {
+ std::string val;
+ if (images_value->GetString(*iter , &val)) {
+ FilePath image_path = extension->path().AppendASCII(val);
+ if (!file_util::PathExists(image_path)) {
+ *error = StringPrintf(
+ "Could not load '%s' for theme.",
+ WideToUTF8(image_path.ToWStringHack()).c_str());
+ return NULL;
+ }
+ }
+ ++iter;
+ }
+ }
+
+ // Themes cannot contain other extension types.
+ return extension.release();
+ }
+
+ // Validate that claimed script resources actually exist.
+ for (size_t i = 0; i < extension->content_scripts().size(); ++i) {
+ const UserScript& script = extension->content_scripts()[i];
+
+ for (size_t j = 0; j < script.js_scripts().size(); j++) {
+ const FilePath& path = script.js_scripts()[j].path();
+ if (!file_util::PathExists(path)) {
+ *error = StringPrintf("Could not load '%s' for content script.",
+ WideToUTF8(path.ToWStringHack()).c_str());
+ return NULL;
+ }
+ }
+
+ for (size_t j = 0; j < script.css_scripts().size(); j++) {
+ const FilePath& path = script.css_scripts()[j].path();
+ if (!file_util::PathExists(path)) {
+ *error = StringPrintf("Could not load '%s' for content script.",
+ WideToUTF8(path.ToWStringHack()).c_str());
+ return NULL;
+ }
+ }
+ }
+
+ for (size_t i = 0; i < extension->plugins().size(); ++i) {
+ const Extension::PluginInfo& plugin = extension->plugins()[i];
+ if (!file_util::PathExists(plugin.path)) {
+ *error = StringPrintf("Could not load '%s' for plugin.",
+ WideToUTF8(plugin.path.ToWStringHack()).c_str());
+ return NULL;
+ }
+ }
+
+ // Validate icon location for page actions.
+ const PageActionMap& page_actions = extension->page_actions();
+ for (PageActionMap::const_iterator i(page_actions.begin());
+ i != page_actions.end(); ++i) {
+ PageAction* page_action = i->second;
+ const std::vector<FilePath>& icon_paths = page_action->icon_paths();
+ for (std::vector<FilePath>::const_iterator iter = icon_paths.begin();
+ iter != icon_paths.end(); ++iter) {
+ FilePath path = *iter;
+ if (!file_util::PathExists(path)) {
+ *error = StringPrintf("Could not load icon '%s' for page action.",
+ WideToUTF8(path.ToWStringHack()).c_str());
+ return NULL;
+ }
+ }
+ }
+
+ return extension.release();
+}
+
+void UninstallExtension(const std::string& id, const FilePath& extensions_dir) {
+ // First, delete the Current Version file. If the directory delete fails, then
+ // at least the extension won't be loaded again.
+ FilePath extension_root = extensions_dir.AppendASCII(id);
+
+ if (!file_util::PathExists(extension_root)) {
+ LOG(WARNING) << "Asked to remove a non-existent extension " << id;
+ return;
+ }
+
+ FilePath current_version_file = extension_root.AppendASCII(
+ kCurrentVersionFileName);
+ if (!file_util::PathExists(current_version_file)) {
+ LOG(WARNING) << "Extension " << id
+ << " does not have a Current Version file.";
+ } else {
+ if (!file_util::Delete(current_version_file, false)) {
+ LOG(WARNING) << "Could not delete Current Version file for extension "
+ << id;
+ return;
+ }
+ }
+
+ // OK, now try and delete the entire rest of the directory. One major place
+ // this can fail is if the extension contains a plugin (stupid plugins). It's
+ // not a big deal though, because we'll notice next time we startup that the
+ // Current Version file is gone and finish the delete then.
+ if (!file_util::Delete(extension_root, true))
+ LOG(WARNING) << "Could not delete directory for extension " << id;
+}
+
+void GarbageCollectExtensions(const FilePath& install_directory) {
+ // Nothing to clean up if it doesn't exist.
+ if (!file_util::DirectoryExists(install_directory))
+ return;
+
+ LOG(INFO) << "Loading installed extensions...";
+ file_util::FileEnumerator enumerator(install_directory,
+ false, // Not recursive.
+ file_util::FileEnumerator::DIRECTORIES);
+ FilePath extension_path;
+ for (extension_path = enumerator.Next(); !extension_path.value().empty();
+ extension_path = enumerator.Next()) {
+ std::string extension_id = WideToASCII(
+ extension_path.BaseName().ToWStringHack());
+
+ // If there is no Current Version file, just delete the directory and move
+ // on. This can legitimately happen when an uninstall does not complete, for
+ // example, when a plugin is in use at uninstall time.
+ FilePath current_version_path = extension_path.AppendASCII(
+ kCurrentVersionFileName);
+ if (!file_util::PathExists(current_version_path)) {
+ LOG(INFO) << "Deleting incomplete install for directory "
+ << WideToASCII(extension_path.ToWStringHack()) << ".";
+ file_util::Delete(extension_path, true); // Recursive.
+ continue;
+ }
+
+ // Ignore directories that aren't valid IDs.
+ if (!Extension::IdIsValid(extension_id)) {
+ LOG(WARNING) << "Invalid extension ID encountered in extensions "
+ "directory: " << extension_id;
+ LOG(INFO) << "Deleting invalid extension directory "
+ << WideToASCII(extension_path.ToWStringHack()) << ".";
+ file_util::Delete(extension_path, true); // Recursive.
+ continue;
+ }
+ }
+}
+
+} // extensionfile_util
diff --git a/chrome/browser/extensions/extension_file_util.h b/chrome/browser/extensions/extension_file_util.h
new file mode 100644
index 0000000..45d0b30
--- /dev/null
+++ b/chrome/browser/extensions/extension_file_util.h
@@ -0,0 +1,83 @@
+// 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.
+
+#ifndef CHROME_BROWSER_EXTENSIONS_EXTENSION_FILE_UTIL_H_
+#define CHROME_BROWSER_EXTENSIONS_EXTENSION_FILE_UTIL_H_
+
+#include <string>
+
+#include "base/file_path.h"
+#include "chrome/common/extensions/extension.h"
+
+// Utilties for manipulating the on-disk storage of extensions.
+namespace extension_file_util {
+
+// The name of the directory inside the profile that we store installed
+// extension in.
+extern const char kInstallDirectoryName[];
+
+// The name of the file that contains the current version of an installed
+// extension.
+extern const char kCurrentVersionFileName[];
+
+// Move source_dir to dest_dir (it will actually be named dest_dir, not inside
+// dest_dir). If the parent path doesn't exixt, create it. If something else is
+// already there, remove it.
+bool MoveDirSafely(const FilePath& source_dir, const FilePath& dest_dir);
+
+// Updates the Current Version file inside the installed extension.
+bool SetCurrentVersion(const FilePath& dest_dir, const std::string& version,
+ std::string* error);
+
+// Reads the Current Version file.
+bool ReadCurrentVersion(const FilePath& dir, std::string* version_string);
+
+// Determine what type of install (new, upgrade, overinstall, downgrade) a given
+// id/version combination is. Also returns the current version, if any, in
+// current_version_str.
+Extension::InstallType CompareToInstalledVersion(
+ const FilePath& install_directory, const std::string& id,
+ const std::string& new_version_str, std::string *current_version_str);
+
+// Sanity check that the directory has the minimum files to be a working
+// extension.
+bool SanityCheckExtension(const FilePath& extension_root);
+
+// Installs an extension unpacked in |src_dir|. |extensions_dir| is the root
+// directory containing all extensions in the user profile. |extension_id| and
+// |extension_version| are the id and version of the extension contained in
+// |src_dir|.
+//
+// Returns the full path to the destination version directory and the type of
+// install that was attempted.
+//
+// On failure, also returns an error message.
+//
+// NOTE: |src_dir| is not actually copied in the case of downgrades or
+// overinstall of previous verisons of the extension. In that case, the function
+// returns true and install_type is populated.
+bool InstallExtension(const FilePath& src_dir,
+ const FilePath& extensions_dir,
+ const std::string& extension_id,
+ const std::string& extension_version,
+ FilePath* version_dir,
+ Extension::InstallType* install_type,
+ std::string* error);
+
+// Load an extension from the specified directory. Returns NULL on failure, with
+// a description of the error in |error|.
+Extension* LoadExtension(const FilePath& extension_root, bool require_key,
+ std::string* error);
+
+// Uninstalls the extension |id| from the install directory |extensions_dir|.
+void UninstallExtension(const std::string& id, const FilePath& extensions_dir);
+
+// Clean up directories that aren't valid extensions from the install directory.
+// TODO(aa): Also consider passing in a list of known current extensions and
+// removing others?
+void GarbageCollectExtensions(const FilePath& extensions_dir);
+
+} // extension_file_util
+
+#endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_FILE_UTIL_H_
diff --git a/chrome/browser/extensions/extension_file_util_unittest.cc b/chrome/browser/extensions/extension_file_util_unittest.cc
new file mode 100644
index 0000000..6e9b2dc
--- /dev/null
+++ b/chrome/browser/extensions/extension_file_util_unittest.cc
@@ -0,0 +1,167 @@
+// 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.
+
+#include "chrome/browser/extensions/extension_file_util.h"
+
+#include "base/file_util.h"
+#include "base/scoped_temp_dir.h"
+#include "base/path_service.h"
+#include "chrome/common/chrome_paths.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+TEST(ExtensionFileUtil, MoveDirSafely) {
+ // Create a test directory structure with some data in it.
+ ScopedTempDir temp;
+ ASSERT_TRUE(temp.CreateUniqueTempDir());
+
+ FilePath src_path = temp.path().AppendASCII("src");
+ ASSERT_TRUE(file_util::CreateDirectory(src_path));
+
+ std::string data = "foobar";
+ ASSERT_TRUE(file_util::WriteFile(src_path.AppendASCII("data"),
+ data.c_str(), data.length()));
+
+ // Move it to a path that doesn't exist yet.
+ FilePath dest_path = temp.path().AppendASCII("dest").AppendASCII("dest");
+ ASSERT_TRUE(extension_file_util::MoveDirSafely(src_path, dest_path));
+
+ // The path should get created.
+ ASSERT_TRUE(file_util::DirectoryExists(dest_path));
+
+ // The data should match.
+ std::string data_out;
+ ASSERT_TRUE(file_util::ReadFileToString(dest_path.AppendASCII("data"),
+ &data_out));
+ ASSERT_EQ(data, data_out);
+
+ // The src path should be gone.
+ ASSERT_FALSE(file_util::PathExists(src_path));
+
+ // Create some new test data.
+ ASSERT_TRUE(file_util::CopyDirectory(dest_path, src_path,
+ true)); // recursive
+ data = "hotdog";
+ ASSERT_TRUE(file_util::WriteFile(src_path.AppendASCII("data"),
+ data.c_str(), data.length()));
+
+ // Test again, overwriting the old path.
+ ASSERT_TRUE(extension_file_util::MoveDirSafely(src_path, dest_path));
+ ASSERT_TRUE(file_util::DirectoryExists(dest_path));
+
+ data_out.clear();
+ ASSERT_TRUE(file_util::ReadFileToString(dest_path.AppendASCII("data"),
+ &data_out));
+ ASSERT_EQ(data, data_out);
+ ASSERT_FALSE(file_util::PathExists(src_path));
+}
+
+TEST(ExtensionFileUtil, SetCurrentVersion) {
+ // Create an empty test directory.
+ ScopedTempDir temp;
+ ASSERT_TRUE(temp.CreateUniqueTempDir());
+
+ // Set its version.
+ std::string error;
+ std::string version = "1.0";
+ ASSERT_TRUE(extension_file_util::SetCurrentVersion(temp.path(), version,
+ &error));
+
+ // Test the result.
+ std::string version_out;
+ ASSERT_TRUE(file_util::ReadFileToString(
+ temp.path().AppendASCII(extension_file_util::kCurrentVersionFileName),
+ &version_out));
+ ASSERT_EQ(version, version_out);
+
+ // Try again, overwriting the old value.
+ version = "2.0";
+ version_out.clear();
+ ASSERT_TRUE(extension_file_util::SetCurrentVersion(temp.path(), version,
+ &error));
+ ASSERT_TRUE(file_util::ReadFileToString(
+ temp.path().AppendASCII(extension_file_util::kCurrentVersionFileName),
+ &version_out));
+ ASSERT_EQ(version, version_out);
+}
+
+TEST(ExtensionFileUtil, ReadCurrentVersion) {
+ // Read the version from a valid extension.
+ FilePath extension_path;
+ ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extension_path));
+ extension_path = extension_path.AppendASCII("extensions")
+ .AppendASCII("good")
+ .AppendASCII("Extensions")
+ .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj");
+
+ std::string version;
+ ASSERT_TRUE(extension_file_util::ReadCurrentVersion(extension_path,
+ &version));
+ ASSERT_EQ("1.0.0.0", version);
+
+ // Create an invalid extension and read its current version.
+ ScopedTempDir temp;
+ ASSERT_TRUE(temp.CreateUniqueTempDir());
+ ASSERT_FALSE(extension_file_util::ReadCurrentVersion(temp.path(), &version));
+}
+
+TEST(ExtensionFileUtil, CompareToInstalledVersion) {
+ // Compare to an existing extension.
+ FilePath install_directory;
+ ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &install_directory));
+ install_directory = install_directory.AppendASCII("extensions")
+ .AppendASCII("good")
+ .AppendASCII("Extensions");
+
+ std::string id = "behllobkkfkfnphdnhnkndlbkcpglgmj";
+ std::string version = "1.0.0.0";
+ std::string version_out;
+
+ ASSERT_EQ(Extension::UPGRADE, extension_file_util::CompareToInstalledVersion(
+ install_directory, id, "1.0.0.1", &version_out));
+ ASSERT_EQ(version, version_out);
+
+ version_out.clear();
+ ASSERT_EQ(Extension::REINSTALL,
+ extension_file_util::CompareToInstalledVersion(
+ install_directory, id, "1.0.0.0", &version_out));
+ ASSERT_EQ(version, version_out);
+
+ version_out.clear();
+ ASSERT_EQ(Extension::REINSTALL,
+ extension_file_util::CompareToInstalledVersion(
+ install_directory, id, "1.0.0", &version_out));
+ ASSERT_EQ(version, version_out);
+
+ version_out.clear();
+ ASSERT_EQ(Extension::DOWNGRADE,
+ extension_file_util::CompareToInstalledVersion(
+ install_directory, id, "0.0.1.0", &version_out));
+ ASSERT_EQ(version, version_out);
+
+ // Compare to an extension that is missing its Current Version file.
+ ScopedTempDir temp;
+ ASSERT_TRUE(temp.CreateUniqueTempDir());
+ FilePath src = install_directory.AppendASCII(id).AppendASCII(version);
+ FilePath dest = temp.path().AppendASCII(id).AppendASCII(version);
+ ASSERT_TRUE(file_util::CreateDirectory(dest.DirName()));
+ ASSERT_TRUE(file_util::CopyDirectory(src, dest, true));
+
+ version_out.clear();
+ ASSERT_EQ(Extension::NEW_INSTALL,
+ extension_file_util::CompareToInstalledVersion(
+ temp.path(), id, "0.0.1.0", &version_out));
+ ASSERT_EQ("", version_out);
+
+ // Compare to a completely non-existent extension.
+ version_out.clear();
+ ASSERT_EQ(Extension::NEW_INSTALL,
+ extension_file_util::CompareToInstalledVersion(
+ temp.path(), "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "0.0.1.0",
+ &version_out));
+ ASSERT_EQ("", version_out);
+}
+
+// TODO(aa): More tests as motivation allows. Maybe steal some from
+// ExtensionsService? Many of them could probably be tested here without the
+// MessageLoop shenanigans.
diff --git a/chrome/browser/extensions/extensions_service.cc b/chrome/browser/extensions/extensions_service.cc
index 1b993e6..0733380 100644
--- a/chrome/browser/extensions/extensions_service.cc
+++ b/chrome/browser/extensions/extensions_service.cc
@@ -7,16 +7,14 @@
#include "app/l10n_util.h"
#include "base/command_line.h"
#include "base/file_util.h"
-#include "base/scoped_temp_dir.h"
-#include "base/stl_util-inl.h"
#include "base/string_util.h"
#include "base/values.h"
-#include "net/base/file_stream.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/browser_list.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chrome_thread.h"
#include "chrome/browser/extensions/extension_browser_event_router.h"
+#include "chrome/browser/extensions/extension_file_util.h"
#include "chrome/browser/extensions/extension_process_manager.h"
#include "chrome/browser/extensions/extension_updater.h"
#include "chrome/browser/extensions/external_extension_provider.h"
@@ -26,9 +24,7 @@
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/extensions/extension.h"
-#include "chrome/common/extensions/extension_constants.h"
#include "chrome/common/extensions/extension_error_reporter.h"
-#include "chrome/common/json_value_serializer.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/pref_service.h"
@@ -249,8 +245,9 @@ void ExtensionsService::UninstallExtension(const std::string& extension_id,
// Tell the backend to start deleting installed extensions on the file thread.
if (Extension::LOAD != extension->location()) {
- backend_loop_->PostTask(FROM_HERE, NewRunnableMethod(backend_.get(),
- &ExtensionsServiceBackend::UninstallExtension, extension_id));
+ backend_loop_->PostTask(FROM_HERE, NewRunnableFunction(
+ &extension_file_util::UninstallExtension, extension_id,
+ install_directory_));
}
UnloadExtension(extension_id);
@@ -321,9 +318,8 @@ void ExtensionsService::ReloadExtensions() {
}
void ExtensionsService::GarbageCollectExtensions() {
- backend_loop_->PostTask(FROM_HERE, NewRunnableMethod(backend_.get(),
- &ExtensionsServiceBackend::GarbageCollectExtensions,
- scoped_refptr<ExtensionsService>(this)));
+ backend_loop_->PostTask(FROM_HERE, NewRunnableFunction(
+ &extension_file_util::GarbageCollectExtensions, install_directory_));
}
void ExtensionsService::OnLoadedInstalledExtensions() {
@@ -524,55 +520,6 @@ void ExtensionsServiceBackend::LoadInstalledExtensions(
frontend_, &ExtensionsService::OnLoadedInstalledExtensions));
}
-void ExtensionsServiceBackend::GarbageCollectExtensions(
- scoped_refptr<ExtensionsService> frontend) {
- frontend_ = frontend;
- alert_on_error_ = false;
-
- // Nothing to clean up if it doesn't exist.
- if (!file_util::DirectoryExists(install_directory_))
- return;
-
- FilePath install_directory_absolute(install_directory_);
- file_util::AbsolutePath(&install_directory_absolute);
-
- LOG(INFO) << "Loading installed extensions...";
-
- // Find all child directories in the install directory and load their
- // manifests. Post errors and results to the frontend.
- file_util::FileEnumerator enumerator(install_directory_absolute,
- false, // Not recursive.
- file_util::FileEnumerator::DIRECTORIES);
- FilePath extension_path;
- for (extension_path = enumerator.Next(); !extension_path.value().empty();
- extension_path = enumerator.Next()) {
- std::string extension_id = WideToASCII(
- extension_path.BaseName().ToWStringHack());
-
- // If there is no Current Version file, just delete the directory and move
- // on. This can legitimately happen when an uninstall does not complete, for
- // example, when a plugin is in use at uninstall time.
- FilePath current_version_path = extension_path.AppendASCII(
- ExtensionsService::kCurrentVersionFileName);
- if (!file_util::PathExists(current_version_path)) {
- LOG(INFO) << "Deleting incomplete install for directory "
- << WideToASCII(extension_path.ToWStringHack()) << ".";
- file_util::Delete(extension_path, true); // Recursive.
- continue;
- }
-
- // Ignore directories that aren't valid IDs.
- if (!Extension::IdIsValid(extension_id)) {
- LOG(WARNING) << "Invalid extension ID encountered in extensions "
- "directory: " << extension_id;
- // TODO(erikkay) delete these eventually too...
- continue;
- }
-
- // TODO(erikkay) check for extensions that aren't loaded?
- }
-}
-
void ExtensionsServiceBackend::LoadSingleExtension(
const FilePath& path_in, scoped_refptr<ExtensionsService> frontend) {
frontend_ = frontend;
@@ -586,14 +533,21 @@ void ExtensionsServiceBackend::LoadSingleExtension(
LOG(INFO) << "Loading single extension from " <<
WideToASCII(extension_path.BaseName().ToWStringHack());
- Extension* extension = LoadExtension(extension_path,
- Extension::LOAD,
- false); // Don't require id.
- if (extension) {
- ExtensionList* extensions = new ExtensionList;
- extensions->push_back(extension);
- ReportExtensionsLoaded(extensions);
+ std::string error;
+ Extension* extension = extension_file_util::LoadExtension(
+ extension_path,
+ false, // Don't require id
+ &error);
+
+ if (!extension) {
+ ReportExtensionLoadError(extension_path, error);
+ return;
}
+
+ extension->set_location(Extension::LOAD);
+ ExtensionList* extensions = new ExtensionList;
+ extensions->push_back(extension);
+ ReportExtensionsLoaded(extensions);
}
void ExtensionsServiceBackend::LoadInstalledExtension(
@@ -608,150 +562,26 @@ void ExtensionsServiceBackend::LoadInstalledExtension(
return;
}
- Extension* extension =
- LoadExtension(FilePath(path), location, true); // Require id.
+ std::string error;
+ Extension* extension = extension_file_util::LoadExtension(
+ path,
+ true, // Require id
+ &error);
+
+ if (!extension) {
+ ReportExtensionLoadError(path, error);
+ return;
+ }
// TODO(erikkay) now we only report a single extension loaded at a time.
// Perhaps we should change the notifications to remove ExtensionList.
+ extension->set_location(location);
ExtensionList* extensions = new ExtensionList;
if (extension)
extensions->push_back(extension);
ReportExtensionsLoaded(extensions);
}
-DictionaryValue* ExtensionsServiceBackend::ReadManifest(
- const FilePath& manifest_path, std::string* error) {
- JSONFileValueSerializer serializer(manifest_path);
- scoped_ptr<Value> root(serializer.Deserialize(error));
- if (!root.get())
- return NULL;
-
- if (!root->IsType(Value::TYPE_DICTIONARY)) {
- *error = extension_manifest_errors::kInvalidManifest;
- return NULL;
- }
-
- return static_cast<DictionaryValue*>(root.release());
-}
-
-Extension* ExtensionsServiceBackend::LoadExtension(
- const FilePath& extension_path,
- Extension::Location location,
- bool require_id) {
- FilePath manifest_path =
- extension_path.AppendASCII(Extension::kManifestFilename);
- if (!file_util::PathExists(manifest_path)) {
- ReportExtensionLoadError(extension_path,
- extension_manifest_errors::kInvalidManifest);
- return NULL;
- }
-
- std::string error;
- scoped_ptr<DictionaryValue> root(ReadManifest(manifest_path, &error));
- if (!root.get()) {
- ReportExtensionLoadError(extension_path, error);
- return NULL;
- }
-
- scoped_ptr<Extension> extension(new Extension(extension_path));
- if (!extension->InitFromValue(*root.get(), require_id, &error)) {
- ReportExtensionLoadError(extension_path, error);
- return NULL;
- }
-
- extension->set_location(location);
-
- // Validate icons exist.
- for (std::map<int, std::string>::const_iterator iter =
- extension->icons().begin(); iter != extension->icons().end(); ++iter) {
- if (!file_util::PathExists(extension->GetResourcePath(iter->second))) {
- ReportExtensionLoadError(extension_path,
- StringPrintf("Could not load extension icon '%s'.",
- iter->second.c_str()));
- return false;
- }
- }
-
- // Theme resource validation.
- if (extension->IsTheme()) {
- DictionaryValue* images_value = extension->GetThemeImages();
- if (images_value) {
- DictionaryValue::key_iterator iter = images_value->begin_keys();
- while (iter != images_value->end_keys()) {
- std::string val;
- if (images_value->GetString(*iter , &val)) {
- FilePath image_path = extension->path().AppendASCII(val);
- if (!file_util::PathExists(image_path)) {
- ReportExtensionLoadError(extension_path,
- StringPrintf("Could not load '%s' for theme.",
- WideToUTF8(image_path.ToWStringHack()).c_str()));
- return NULL;
- }
- }
- ++iter;
- }
- }
-
- // Themes cannot contain other extension types.
- return extension.release();
- }
-
- // Validate that claimed script resources actually exist.
- for (size_t i = 0; i < extension->content_scripts().size(); ++i) {
- const UserScript& script = extension->content_scripts()[i];
-
- for (size_t j = 0; j < script.js_scripts().size(); j++) {
- const FilePath& path = script.js_scripts()[j].path();
- if (!file_util::PathExists(path)) {
- ReportExtensionLoadError(extension_path,
- StringPrintf("Could not load '%s' for content script.",
- WideToUTF8(path.ToWStringHack()).c_str()));
- return NULL;
- }
- }
-
- for (size_t j = 0; j < script.css_scripts().size(); j++) {
- const FilePath& path = script.css_scripts()[j].path();
- if (!file_util::PathExists(path)) {
- ReportExtensionLoadError(extension_path,
- StringPrintf("Could not load '%s' for content script.",
- WideToUTF8(path.ToWStringHack()).c_str()));
- return NULL;
- }
- }
- }
-
- for (size_t i = 0; i < extension->plugins().size(); ++i) {
- const Extension::PluginInfo& plugin = extension->plugins()[i];
- if (!file_util::PathExists(plugin.path)) {
- ReportExtensionLoadError(extension_path,
- StringPrintf("Could not load '%s' for plugin.",
- WideToUTF8(plugin.path.ToWStringHack()).c_str()));
- return NULL;
- }
- }
-
- // Validate icon location for page actions.
- const PageActionMap& page_actions = extension->page_actions();
- for (PageActionMap::const_iterator i(page_actions.begin());
- i != page_actions.end(); ++i) {
- PageAction* page_action = i->second;
- const std::vector<FilePath>& icon_paths = page_action->icon_paths();
- for (std::vector<FilePath>::const_iterator iter = icon_paths.begin();
- iter != icon_paths.end(); ++iter) {
- FilePath path = *iter;
- if (!file_util::PathExists(path)) {
- ReportExtensionLoadError(extension_path,
- StringPrintf("Could not load icon '%s' for page action.",
- WideToUTF8(path.ToWStringHack()).c_str()));
- return NULL;
- }
- }
- }
-
- return extension.release();
-}
-
void ExtensionsServiceBackend::ReportExtensionLoadError(
const FilePath& extension_path, const std::string &error) {
// TODO(port): note that this isn't guaranteed to work properly on Linux.
@@ -767,123 +597,6 @@ void ExtensionsServiceBackend::ReportExtensionsLoaded(
frontend_, &ExtensionsService::OnExtensionsLoaded, extensions));
}
-bool ExtensionsServiceBackend::ReadCurrentVersion(const FilePath& dir,
- std::string* version_string) {
- FilePath current_version =
- dir.AppendASCII(ExtensionsService::kCurrentVersionFileName);
- if (file_util::PathExists(current_version)) {
- if (file_util::ReadFileToString(current_version, version_string)) {
- TrimWhitespace(*version_string, TRIM_ALL, version_string);
- return true;
- }
- }
- return false;
-}
-
-Extension::InstallType ExtensionsServiceBackend::CompareToInstalledVersion(
- const std::string& id,
- const std::string& new_version_str,
- std::string *current_version_str) {
- CHECK(current_version_str);
- FilePath dir(install_directory_.AppendASCII(id.c_str()));
- if (!ReadCurrentVersion(dir, current_version_str))
- return Extension::NEW_INSTALL;
-
- scoped_ptr<Version> current_version(
- Version::GetVersionFromString(*current_version_str));
- scoped_ptr<Version> new_version(
- Version::GetVersionFromString(new_version_str));
- int comp = new_version->CompareTo(*current_version);
- if (comp > 0)
- return Extension::UPGRADE;
- else if (comp == 0)
- return Extension::REINSTALL;
- else
- return Extension::DOWNGRADE;
-}
-
-bool ExtensionsServiceBackend::NeedsReinstall(const std::string& id,
- const std::string& current_version) {
- // Verify that the directory actually exists.
- // TODO(erikkay): A further step would be to verify that the extension
- // has actually loaded successfully.
- FilePath dir(install_directory_.AppendASCII(id.c_str()));
- FilePath version_dir(dir.AppendASCII(current_version));
- return !file_util::PathExists(version_dir);
-}
-
-bool ExtensionsServiceBackend::InstallDirSafely(const FilePath& source_dir,
- const FilePath& dest_dir) {
- if (file_util::PathExists(dest_dir)) {
- // By the time we get here, it should be safe to assume that this directory
- // is not currently in use (it's not the current active version).
- if (!file_util::Delete(dest_dir, true)) {
- ReportExtensionInstallError(source_dir,
- "Can't delete existing version directory.");
- return false;
- }
- } else {
- FilePath parent = dest_dir.DirName();
- if (!file_util::DirectoryExists(parent)) {
- if (!file_util::CreateDirectory(parent)) {
- ReportExtensionInstallError(source_dir,
- "Couldn't create extension directory.");
- return false;
- }
- }
- }
- if (!file_util::Move(source_dir, dest_dir)) {
- ReportExtensionInstallError(source_dir,
- "Couldn't move temporary directory.");
- return false;
- }
-
- return true;
-}
-
-bool ExtensionsServiceBackend::SetCurrentVersion(const FilePath& dest_dir,
- const std::string& version) {
- // Write out the new CurrentVersion file.
- // <profile>/Extension/<name>/CurrentVersion
- FilePath current_version =
- dest_dir.AppendASCII(ExtensionsService::kCurrentVersionFileName);
- FilePath current_version_old =
- current_version.InsertBeforeExtension(FILE_PATH_LITERAL("_old"));
- if (file_util::PathExists(current_version_old)) {
- if (!file_util::Delete(current_version_old, false)) {
- ReportExtensionInstallError(dest_dir,
- "Couldn't remove CurrentVersion_old file.");
- return false;
- }
- }
- if (file_util::PathExists(current_version)) {
- if (!file_util::Move(current_version, current_version_old)) {
- ReportExtensionInstallError(dest_dir,
- "Couldn't move CurrentVersion file.");
- return false;
- }
- }
- net::FileStream stream;
- int flags = base::PLATFORM_FILE_CREATE_ALWAYS | base::PLATFORM_FILE_WRITE;
- if (stream.Open(current_version, flags) != 0)
- return false;
- if (stream.Write(version.c_str(), version.size(), NULL) < 0) {
- // Restore the old CurrentVersion.
- if (file_util::PathExists(current_version_old)) {
- if (!file_util::Move(current_version_old, current_version)) {
- LOG(WARNING) << "couldn't restore " << current_version_old.value() <<
- " to " << current_version.value();
-
- // TODO(erikkay): This is an ugly state to be in. Try harder?
- }
- }
- ReportExtensionInstallError(dest_dir,
- "Couldn't create CurrentVersion file.");
- return false;
- }
- return true;
-}
-
void ExtensionsServiceBackend::InstallExtension(
const FilePath& extension_path, bool from_gallery,
scoped_refptr<ExtensionsService> frontend) {
@@ -992,53 +705,37 @@ void ExtensionsServiceBackend::OnExtensionUnpacked(
// If an expected id was provided, make sure it matches.
if (!expected_id.empty() && expected_id != extension->id()) {
- std::string error_msg = "ID in new extension manifest (";
- error_msg += extension->id();
- error_msg += ") does not match expected ID (";
- error_msg += expected_id;
- error_msg += ")";
- ReportExtensionInstallError(crx_path, error_msg);
+ ReportExtensionInstallError(crx_path,
+ StringPrintf("ID in new extension manifest (%s) does not match "
+ "expected id (%s)", extension->id().c_str(),
+ expected_id.c_str()));
return;
}
- // <profile>/Extensions/<id>
- FilePath dest_dir = install_directory_.AppendASCII(extension->id());
- std::string version = extension->VersionString();
- std::string current_version;
- Extension::InstallType install_type =
- CompareToInstalledVersion(extension->id(), version, &current_version);
-
- // Do not allow downgrade.
- if (install_type == Extension::DOWNGRADE) {
- ReportExtensionInstallError(crx_path,
- "Error: Attempt to downgrade extension from more recent version.");
+ FilePath version_dir;
+ Extension::InstallType install_type = Extension::INSTALL_ERROR;
+ std::string error_msg;
+ if (!extension_file_util::InstallExtension(unpacked_path, install_directory_,
+ extension->id(),
+ extension->VersionString(),
+ &version_dir,
+ &install_type, &error_msg)) {
+ ReportExtensionInstallError(crx_path, error_msg);
return;
}
- if (install_type == Extension::REINSTALL) {
- if (NeedsReinstall(extension->id(), current_version)) {
- // Treat corrupted existing installation as new install case.
- install_type = Extension::NEW_INSTALL;
- } else {
- // The client may use this as a signal (to switch themes, for instance).
- ReportExtensionOverinstallAttempted(extension->id(), crx_path);
- return;
- }
+ if (install_type == Extension::DOWNGRADE) {
+ ReportExtensionInstallError(crx_path, "Attempted to downgrade extension.");
+ return;
}
- // <profile>/Extensions/<dir_name>/<version>
- FilePath version_dir = dest_dir.AppendASCII(version);
extension->set_path(version_dir);
- // If anything fails after this, we want to delete the extension dir.
- ScopedTempDir scoped_version_dir;
- scoped_version_dir.Set(version_dir);
-
- if (!InstallDirSafely(unpacked_path, version_dir))
- return;
-
- if (!SetCurrentVersion(dest_dir, version))
+ if (install_type == Extension::REINSTALL) {
+ // The client may use this as a signal (to switch themes, for instance).
+ ReportExtensionOverinstallAttempted(extension->id(), crx_path);
return;
+ }
frontend_loop_->PostTask(FROM_HERE, NewRunnableMethod(
frontend_, &ExtensionsService::OnExtensionInstalled, crx_path,
@@ -1051,8 +748,6 @@ void ExtensionsServiceBackend::OnExtensionUnpacked(
// Hand off ownership of the extension to the frontend.
extensions->push_back(extension_deleter.release());
ReportExtensionsLoaded(extensions);
-
- scoped_version_dir.Take();
}
void ExtensionsServiceBackend::ReportExtensionInstallError(
@@ -1078,23 +773,6 @@ void ExtensionsServiceBackend::ReportExtensionOverinstallAttempted(
path));
}
-bool ExtensionsServiceBackend::ShouldSkipInstallingExtension(
- const std::set<std::string>& ids_to_ignore,
- const std::string& id) {
- if (ids_to_ignore.find(id) != ids_to_ignore.end()) {
- LOG(INFO) << "Skipping uninstalled external extension " << id;
- return true;
- }
- return false;
-}
-
-void ExtensionsServiceBackend::CheckVersionAndInstallExtension(
- const std::string& id, const Version* extension_version,
- const FilePath& extension_path) {
- if (ShouldInstall(id, extension_version))
- InstallOrUpdateExtension(FilePath(extension_path), false, id, false);
-}
-
bool ExtensionsServiceBackend::LookupExternalExtension(
const std::string& id, Version** version, Extension::Location* location) {
scoped_ptr<Version> extension_version;
@@ -1154,41 +832,6 @@ bool ExtensionsServiceBackend::CheckExternalUninstall(
return true; // This is not a known extension, uninstall.
}
-// Assumes that the extension isn't currently loaded or in use.
-void ExtensionsServiceBackend::UninstallExtension(
- const std::string& extension_id) {
- // First, delete the Current Version file. If the directory delete fails, then
- // at least the extension won't be loaded again.
- FilePath extension_directory = install_directory_.AppendASCII(extension_id);
-
- if (!file_util::PathExists(extension_directory)) {
- LOG(WARNING) << "Asked to remove a non-existent extension " << extension_id;
- return;
- }
-
- FilePath current_version_file = extension_directory.AppendASCII(
- ExtensionsService::kCurrentVersionFileName);
- if (!file_util::PathExists(current_version_file)) {
- LOG(WARNING) << "Extension " << extension_id
- << " does not have a Current Version file.";
- } else {
- if (!file_util::Delete(current_version_file, false)) {
- LOG(WARNING) << "Could not delete Current Version file for extension "
- << extension_id;
- return;
- }
- }
-
- // OK, now try and delete the entire rest of the directory. One major place
- // this can fail is if the extension contains a plugin (stupid plugins). It's
- // not a big deal though, because we'll notice next time we startup that the
- // Current Version file is gone and finish the delete then.
- if (!file_util::Delete(extension_directory, true)) {
- LOG(WARNING) << "Could not delete directory for extension "
- << extension_id;
- }
-}
-
void ExtensionsServiceBackend::ClearProvidersForTesting() {
external_extension_providers_.clear();
}
@@ -1203,19 +846,8 @@ void ExtensionsServiceBackend::SetProviderForTesting(
void ExtensionsServiceBackend::OnExternalExtensionFound(
const std::string& id, const Version* version, const FilePath& path) {
- CheckVersionAndInstallExtension(id, version, path);
-}
-
-bool ExtensionsServiceBackend::ShouldInstall(const std::string& id,
- const Version* version) {
- std::string current_version;
- Extension::InstallType install_type =
- CompareToInstalledVersion(id, version->GetString(), &current_version);
-
- if (install_type == Extension::DOWNGRADE)
- return false;
-
- return (install_type == Extension::UPGRADE ||
- install_type == Extension::NEW_INSTALL ||
- NeedsReinstall(id, current_version));
+ InstallOrUpdateExtension(path,
+ false, // not from gallery
+ id, // expected id
+ true); // silent
}
diff --git a/chrome/browser/extensions/extensions_service.h b/chrome/browser/extensions/extensions_service.h
index 5fc036b..a62ebee 100644
--- a/chrome/browser/extensions/extensions_service.h
+++ b/chrome/browser/extensions/extensions_service.h
@@ -281,10 +281,6 @@ class ExtensionsServiceBackend
void LoadInstalledExtensions(scoped_refptr<ExtensionsService> frontend,
InstalledExtensions* installed);
- // Scans the extension installation directory to look for partially installed
- // or extensions to uninstall.
- void GarbageCollectExtensions(scoped_refptr<ExtensionsService> frontend);
-
// Loads a single extension from |path| where |path| is the top directory of
// a specific extension where its manifest file lives.
// Errors are reported through ExtensionErrorReporter. On completion,
@@ -314,11 +310,6 @@ class ExtensionsServiceBackend
void CheckForExternalUpdates(std::set<std::string> ids_to_ignore,
scoped_refptr<ExtensionsService> frontend);
- // Deletes all versions of the extension from the filesystem. Note that only
- // extensions whose location() == INTERNAL can be uninstalled. Attempting to
- // uninstall other extensions will silently fail.
- void UninstallExtension(const std::string& extension_id);
-
// Clear all ExternalExtensionProviders.
void ClearProvidersForTesting();
@@ -339,22 +330,6 @@ class ExtensionsServiceBackend
void LoadInstalledExtension(const std::string& id, const FilePath& path,
Extension::Location location);
- // Utility function to read an extension manifest and return it as a
- // DictionaryValue. If it fails, NULL is returned and |error| contains an
- // appropriate message.
- DictionaryValue* ReadManifest(const FilePath& manifest_path,
- std::string* error);
-
- // Load a single extension from |extension_path|, the top directory of
- // a specific extension where its manifest file lives.
- Extension* LoadExtension(const FilePath& extension_path,
- Extension::Location location,
- bool require_id);
-
- // Load a single extension from |extension_path|, the top directory of
- // a versioned extension where its Current Version file lives.
- Extension* LoadExtensionCurrentVersion(const FilePath& extension_path);
-
// Install a crx file at |extension_path|. If |expected_id| is not empty, it's
// verified against the extension's manifest before installation. If the
// extension is already installed, install the new version only if its version
@@ -395,17 +370,6 @@ class ExtensionsServiceBackend
void ReportExtensionOverinstallAttempted(const std::string& id,
const FilePath& path);
- // Checks a set of strings (containing id's to ignore) in order to determine
- // if the extension should be installed.
- bool ShouldSkipInstallingExtension(const std::set<std::string>& ids_to_ignore,
- const std::string& id);
-
- // Installs the extension if the extension is a newer version or if the
- // extension hasn't been installed before.
- void CheckVersionAndInstallExtension(const std::string& id,
- const Version* extension_version,
- const FilePath& extension_path);
-
// Lookup an external extension by |id| by going through all registered
// external extension providers until we find a provider that contains an
// extension that matches. If |version| is not NULL, the extension version
@@ -416,45 +380,12 @@ class ExtensionsServiceBackend
Version** version,
Extension::Location* location);
- // Read the manifest from the front of the extension file.
- // Caller takes ownership of return value.
- DictionaryValue* ReadManifest(const FilePath& extension_path);
-
- // Reads the Current Version file from |dir| into |version_string|.
- bool ReadCurrentVersion(const FilePath& dir, std::string* version_string);
-
- // Look for an existing installation of the extension |id| & return
- // an InstallType that would result from installing |new_version_str|.
- Extension::InstallType CompareToInstalledVersion(const std::string& id,
- const std::string& new_version_str, std::string* current_version_str);
-
- // Does an existing installed extension need to be reinstalled.
- bool NeedsReinstall(const std::string& id,
- const std::string& current_version);
-
- // Install the extension dir by moving it from |source| to |dest| safely.
- bool InstallDirSafely(const FilePath& source,
- const FilePath& dest);
-
- // Update the CurrentVersion file in |dest_dir| to |version|.
- bool SetCurrentVersion(const FilePath& dest_dir,
- const std::string& version);
-
// For the extension in |version_path| with |id|, check to see if it's an
// externally managed extension. If so return true if it should be
// uninstalled.
bool CheckExternalUninstall(const std::string& id,
Extension::Location location);
- // Should an extension of |id| and |version| be installed?
- // Returns true if no extension of type |id| is installed or if |version|
- // is greater than the current installed version.
- bool ShouldInstall(const std::string& id, const Version* version);
-
- // The name of a temporary directory to install an extension into for
- // validation before finalizing install.
- static const char* kTempExtensionName;
-
// This is a naked pointer which is set by each entry point.
// The entry point is responsible for ensuring lifetime.
ExtensionsService* frontend_;