summaryrefslogtreecommitdiffstats
path: root/chrome/browser/extensions/extensions_service.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/extensions/extensions_service.cc')
-rw-r--r--chrome/browser/extensions/extensions_service.cc265
1 files changed, 134 insertions, 131 deletions
diff --git a/chrome/browser/extensions/extensions_service.cc b/chrome/browser/extensions/extensions_service.cc
index 3271920..5611594 100644
--- a/chrome/browser/extensions/extensions_service.cc
+++ b/chrome/browser/extensions/extensions_service.cc
@@ -68,8 +68,8 @@ const char kExternalInstallFile[] = "EXTERNAL_INSTALL";
ExtensionsService::ExtensionsService(Profile* profile,
UserScriptMaster* user_script_master)
: message_loop_(MessageLoop::current()),
- backend_(new ExtensionsServiceBackend),
install_directory_(profile->GetPath().AppendASCII(kInstallDirectoryName)),
+ backend_(new ExtensionsServiceBackend(install_directory_)),
profile_(profile),
user_script_master_(user_script_master) {
}
@@ -83,14 +83,12 @@ ExtensionsService::~ExtensionsService() {
bool ExtensionsService::Init() {
#if defined(OS_WIN)
-
// TODO(port): ExtensionsServiceBackend::CheckForExternalUpdates depends on
// the Windows registry.
// TODO(erikkay): Should we monitor the registry during run as well?
g_browser_process->file_thread()->message_loop()->PostTask(FROM_HERE,
NewRunnableMethod(backend_.get(),
&ExtensionsServiceBackend::CheckForExternalUpdates,
- install_directory_,
scoped_refptr<ExtensionsServiceFrontendInterface>(this)));
#endif
@@ -99,8 +97,7 @@ bool ExtensionsService::Init() {
// from the frontend interface.
g_browser_process->file_thread()->message_loop()->PostTask(FROM_HERE,
NewRunnableMethod(backend_.get(),
- &ExtensionsServiceBackend::LoadExtensionsFromDirectory,
- install_directory_,
+ &ExtensionsServiceBackend::LoadExtensionsFromInstallDirectory,
scoped_refptr<ExtensionsServiceFrontendInterface>(this)));
return true;
@@ -125,8 +122,6 @@ void ExtensionsService::InstallExtension(const FilePath& extension_path) {
NewRunnableMethod(backend_.get(),
&ExtensionsServiceBackend::InstallExtension,
extension_path,
- install_directory_,
- true, // alert_on_error
scoped_refptr<ExtensionsServiceFrontendInterface>(this)));
}
@@ -141,7 +136,7 @@ void ExtensionsService::LoadExtension(const FilePath& extension_path) {
scoped_refptr<ExtensionsServiceFrontendInterface>(this)));
}
-void ExtensionsService::OnExtensionsLoadedFromDirectory(
+void ExtensionsService::OnExtensionsLoaded(
ExtensionList* new_extensions) {
extensions_.insert(extensions_.end(), new_extensions->begin(),
new_extensions->end());
@@ -168,7 +163,8 @@ void ExtensionsService::OnExtensionsLoadedFromDirectory(
}
}
- // Tell UserScriptMaster to kick off the first scan.
+ // Since user scripts may have changed, tell UserScriptMaster to kick off
+ // a scan.
user_script_master_->StartScan();
NotificationService::current()->Notify(
@@ -191,21 +187,19 @@ void ExtensionsService::OnExtensionInstalled(FilePath path, bool update) {
// ExtensionsServicesBackend
-void ExtensionsServiceBackend::LoadExtensionsFromDirectory(
- const FilePath& path_in,
+void ExtensionsServiceBackend::LoadExtensionsFromInstallDirectory(
scoped_refptr<ExtensionsServiceFrontendInterface> frontend) {
- FilePath path = path_in;
frontend_ = frontend;
alert_on_error_ = false;
- if (!file_util::AbsolutePath(&path))
+ if (!file_util::AbsolutePath(&install_directory_))
NOTREACHED();
scoped_ptr<ExtensionList> extensions(new ExtensionList);
// Create the <Profile>/Extensions directory if it doesn't exist.
- if (!file_util::DirectoryExists(path)) {
- file_util::CreateDirectory(path);
+ if (!file_util::DirectoryExists(install_directory_)) {
+ file_util::CreateDirectory(install_directory_);
LOG(INFO) << "Created Extensions directory. No extensions to install.";
ReportExtensionsLoaded(extensions.release());
return;
@@ -215,12 +209,25 @@ void ExtensionsServiceBackend::LoadExtensionsFromDirectory(
// Find all child directories in the install directory and load their
// manifests. Post errors and results to the frontend.
- file_util::FileEnumerator enumerator(path,
+ file_util::FileEnumerator enumerator(install_directory_,
false, // not recursive
file_util::FileEnumerator::DIRECTORIES);
- for (extension_path_ = enumerator.Next(); !extension_path_.value().empty();
- extension_path_ = enumerator.Next()) {
- Extension* extension = LoadExtensionCurrentVersion();
+ 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 (CheckExternalUninstall(extension_path, extension_id)) {
+ // TODO(erikkay): Possibly defer this operation to avoid slowing initial
+ // load of extensions.
+ UninstallExtension(extension_path);
+
+ // No error needs to be reported. The extension effectively doesn't
+ // exist.
+ continue;
+ }
+
+ Extension* extension = LoadExtensionCurrentVersion(extension_path);
if (extension)
extensions->push_back(extension);
}
@@ -237,14 +244,14 @@ void ExtensionsServiceBackend::LoadSingleExtension(
// Explicit UI loads are always noisy.
alert_on_error_ = true;
- extension_path_ = path_in;
- if (!file_util::AbsolutePath(&extension_path_))
+ FilePath extension_path = path_in;
+ if (!file_util::AbsolutePath(&extension_path))
NOTREACHED();
LOG(INFO) << "Loading single extension from " <<
- WideToASCII(extension_path_.BaseName().ToWStringHack());
+ WideToASCII(extension_path.BaseName().ToWStringHack());
- Extension* extension = LoadExtension();
+ Extension* extension = LoadExtension(extension_path);
if (extension) {
ExtensionList* extensions = new ExtensionList;
extensions->push_back(extension);
@@ -252,27 +259,29 @@ void ExtensionsServiceBackend::LoadSingleExtension(
}
}
-Extension* ExtensionsServiceBackend::LoadExtensionCurrentVersion() {
+Extension* ExtensionsServiceBackend::LoadExtensionCurrentVersion(
+ const FilePath& extension_path) {
std::string version_str;
- if (!ReadCurrentVersion(extension_path_, &version_str)) {
- ReportExtensionLoadError(StringPrintf("Could not read '%s' file.",
- ExtensionsService::kCurrentVersionFileName));
+ if (!ReadCurrentVersion(extension_path, &version_str)) {
+ ReportExtensionLoadError(extension_path,
+ StringPrintf("Could not read '%s' file.",
+ ExtensionsService::kCurrentVersionFileName));
return NULL;
}
LOG(INFO) << " " <<
- WideToASCII(extension_path_.BaseName().ToWStringHack()) <<
+ WideToASCII(extension_path.BaseName().ToWStringHack()) <<
" version: " << version_str;
- extension_path_ = extension_path_.AppendASCII(version_str);
- return LoadExtension();
+ return LoadExtension(extension_path.AppendASCII(version_str));
}
-Extension* ExtensionsServiceBackend::LoadExtension() {
+Extension* ExtensionsServiceBackend::LoadExtension(
+ const FilePath& extension_path) {
FilePath manifest_path =
- extension_path_.AppendASCII(Extension::kManifestFilename);
+ extension_path.AppendASCII(Extension::kManifestFilename);
if (!file_util::PathExists(manifest_path)) {
- ReportExtensionLoadError(Extension::kInvalidManifestError);
+ ReportExtensionLoadError(extension_path, Extension::kInvalidManifestError);
return NULL;
}
@@ -280,29 +289,19 @@ Extension* ExtensionsServiceBackend::LoadExtension() {
std::string error;
scoped_ptr<Value> root(serializer.Deserialize(&error));
if (!root.get()) {
- ReportExtensionLoadError(error);
+ ReportExtensionLoadError(extension_path, error);
return NULL;
}
if (!root->IsType(Value::TYPE_DICTIONARY)) {
- ReportExtensionLoadError(Extension::kInvalidManifestError);
+ ReportExtensionLoadError(extension_path, Extension::kInvalidManifestError);
return NULL;
}
- scoped_ptr<Extension> extension(new Extension(extension_path_));
+ scoped_ptr<Extension> extension(new Extension(extension_path));
if (!extension->InitFromValue(*static_cast<DictionaryValue*>(root.get()),
&error)) {
- ReportExtensionLoadError(error);
- return NULL;
- }
-
- if (CheckExternalUninstall(extension_path_, extension->id())) {
-
- // TODO(erikkay): Possibly defer this operation to avoid slowing initial
- // load of extensions.
- UninstallExtension(extension_path_);
-
- // No error needs to be reported. The extension effectively doesn't exist.
+ ReportExtensionLoadError(extension_path, error);
return NULL;
}
@@ -311,7 +310,7 @@ Extension* ExtensionsServiceBackend::LoadExtension() {
extension->content_scripts().begin();
iter != extension->content_scripts().end(); ++iter) {
if (!file_util::PathExists(iter->path())) {
- ReportExtensionLoadError(
+ ReportExtensionLoadError(extension_path,
StringPrintf("Could not load content script '%s'.",
WideToUTF8(iter->path().ToWStringHack()).c_str()));
return NULL;
@@ -322,9 +321,9 @@ Extension* ExtensionsServiceBackend::LoadExtension() {
}
void ExtensionsServiceBackend::ReportExtensionLoadError(
- const std::string &error) {
+ const FilePath& extension_path, const std::string &error) {
// TODO(port): note that this isn't guaranteed to work properly on Linux.
- std::string path_str = WideToASCII(extension_path_.ToWStringHack());
+ std::string path_str = WideToASCII(extension_path.ToWStringHack());
std::string message = StringPrintf("Could not load extension from '%s'. %s",
path_str.c_str(), error.c_str());
ExtensionErrorReporter::GetInstance()->ReportError(message, alert_on_error_);
@@ -334,17 +333,18 @@ void ExtensionsServiceBackend::ReportExtensionsLoaded(
ExtensionList* extensions) {
frontend_->GetMessageLoop()->PostTask(FROM_HERE, NewRunnableMethod(
frontend_,
- &ExtensionsServiceFrontendInterface::OnExtensionsLoadedFromDirectory,
+ &ExtensionsServiceFrontendInterface::OnExtensionsLoaded,
extensions));
}
// The extension file format is a header, followed by the manifest, followed
// by the zip file. The header is a magic number, a version, the size of the
// header, and the size of the manifest. These ints are 4 byte little endian.
-DictionaryValue* ExtensionsServiceBackend::ReadManifest() {
- ScopedStdioHandle file(file_util::OpenFile(extension_path_, "rb"));
+DictionaryValue* ExtensionsServiceBackend::ReadManifest(
+ const FilePath& extension_path) {
+ ScopedStdioHandle file(file_util::OpenFile(extension_path, "rb"));
if (!file.get()) {
- ReportExtensionInstallError("no such extension file");
+ ReportExtensionInstallError(extension_path, "no such extension file");
return NULL;
}
@@ -358,15 +358,15 @@ DictionaryValue* ExtensionsServiceBackend::ReadManifest() {
// on a little endian machine with 4 byte alignment.
len = fread(&header, 1, sizeof(ExtensionHeader), file.get());
if (len < sizeof(ExtensionHeader)) {
- ReportExtensionInstallError("invalid extension header");
+ ReportExtensionInstallError(extension_path, "invalid extension header");
return NULL;
}
if (strncmp(kExtensionFileMagic, header.magic, sizeof(header.magic))) {
- ReportExtensionInstallError("bad magic number");
+ ReportExtensionInstallError(extension_path, "bad magic number");
return NULL;
}
if (header.version != Extension::kExpectedFormatVersion) {
- ReportExtensionInstallError("bad version number");
+ ReportExtensionInstallError(extension_path, "bad version number");
return NULL;
}
if (header.header_size > sizeof(ExtensionHeader))
@@ -389,11 +389,12 @@ DictionaryValue* ExtensionsServiceBackend::ReadManifest() {
std::string error;
scoped_ptr<Value> val(json.Deserialize(&error));
if (!val.get()) {
- ReportExtensionInstallError(error);
+ ReportExtensionInstallError(extension_path, error);
return NULL;
}
if (!val->IsType(Value::TYPE_DICTIONARY)) {
- ReportExtensionInstallError("manifest isn't a JSON dictionary");
+ ReportExtensionInstallError(extension_path,
+ "manifest isn't a JSON dictionary");
return NULL;
}
DictionaryValue* manifest = static_cast<DictionaryValue*>(val.get());
@@ -403,14 +404,14 @@ DictionaryValue* ExtensionsServiceBackend::ReadManifest() {
// work.
std::string id;
if (!manifest->GetString(Extension::kIdKey, &id)) {
- ReportExtensionInstallError("missing id key");
+ ReportExtensionInstallError(extension_path, "missing id key");
return NULL;
}
FilePath dest_dir = install_directory_.AppendASCII(id.c_str());
if (file_util::PathExists(dest_dir)) {
std::string version;
if (!manifest->GetString(Extension::kVersionKey, &version)) {
- ReportExtensionInstallError("missing version key");
+ ReportExtensionInstallError(extension_path, "missing version key");
return NULL;
}
std::string current_version;
@@ -422,11 +423,11 @@ DictionaryValue* ExtensionsServiceBackend::ReadManifest() {
std::string zip_hash;
if (!manifest->GetString(Extension::kZipHashKey, &zip_hash)) {
- ReportExtensionInstallError("missing zip_hash key");
+ ReportExtensionInstallError(extension_path, "missing zip_hash key");
return NULL;
}
if (zip_hash.size() != kZipHashHexBytes) {
- ReportExtensionInstallError("invalid zip_hash key");
+ ReportExtensionInstallError(extension_path, "invalid zip_hash key");
return NULL;
}
@@ -443,16 +444,17 @@ DictionaryValue* ExtensionsServiceBackend::ReadManifest() {
std::vector<uint8> zip_hash_bytes;
if (!HexStringToBytes(zip_hash, &zip_hash_bytes)) {
- ReportExtensionInstallError("invalid zip_hash key");
+ ReportExtensionInstallError(extension_path, "invalid zip_hash key");
return NULL;
}
if (zip_hash_bytes.size() != kZipHashBytes) {
- ReportExtensionInstallError("invalid zip_hash key");
+ ReportExtensionInstallError(extension_path, "invalid zip_hash key");
return NULL;
}
for (size_t i = 0; i < kZipHashBytes; ++i) {
if (zip_hash_bytes[i] != hash[i]) {
- ReportExtensionInstallError("zip_hash key didn't match zip hash");
+ ReportExtensionInstallError(extension_path,
+ "zip_hash key didn't match zip hash");
return NULL;
}
}
@@ -487,14 +489,13 @@ bool ExtensionsServiceBackend::CheckCurrentVersion(
scoped_ptr<Version> new_version(
Version::GetVersionFromString(new_version_str));
if (current_version->CompareTo(*new_version) >= 0) {
-
// Verify that the directory actually exists. If it doesn't we'll return
// true so that the install code will repair the broken installation.
// TODO(erikkay): A further step would be to verify that the extension
// has actually loaded successfully.
FilePath version_dir = dest_dir.AppendASCII(current_version_str);
if (file_util::PathExists(version_dir)) {
- ReportExtensionInstallError(
+ ReportExtensionInstallError(dest_dir,
"Existing version is already up to date.");
return false;
}
@@ -506,11 +507,10 @@ 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(
+ ReportExtensionInstallError(source_dir,
"Can't delete existing version directory.");
return false;
}
@@ -518,13 +518,15 @@ bool ExtensionsServiceBackend::InstallDirSafely(const FilePath& source_dir,
FilePath parent = dest_dir.DirName();
if (!file_util::DirectoryExists(parent)) {
if (!file_util::CreateDirectory(parent)) {
- ReportExtensionInstallError("Couldn't create extension directory.");
+ ReportExtensionInstallError(source_dir,
+ "Couldn't create extension directory.");
return false;
}
}
}
if (!file_util::Move(source_dir, dest_dir)) {
- ReportExtensionInstallError("Couldn't move temporary directory.");
+ ReportExtensionInstallError(source_dir,
+ "Couldn't move temporary directory.");
return false;
}
@@ -541,13 +543,15 @@ bool ExtensionsServiceBackend::SetCurrentVersion(const FilePath& dest_dir,
current_version.InsertBeforeExtension(FILE_PATH_LITERAL("_old"));
if (file_util::PathExists(current_version_old)) {
if (!file_util::Delete(current_version_old, false)) {
- ReportExtensionInstallError("Couldn't remove CurrentVersion_old file.");
+ 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("Couldn't move CurrentVersion file.");
+ ReportExtensionInstallError(dest_dir,
+ "Couldn't move CurrentVersion file.");
return false;
}
}
@@ -566,7 +570,8 @@ bool ExtensionsServiceBackend::SetCurrentVersion(const FilePath& dest_dir,
// TODO(erikkay): This is an ugly state to be in. Try harder?
}
}
- ReportExtensionInstallError("Couldn't create CurrentVersion file.");
+ ReportExtensionInstallError(dest_dir,
+ "Couldn't create CurrentVersion file.");
return false;
}
return true;
@@ -574,44 +579,46 @@ bool ExtensionsServiceBackend::SetCurrentVersion(const FilePath& dest_dir,
void ExtensionsServiceBackend::InstallExtension(
const FilePath& extension_path,
- const FilePath& install_dir,
- bool alert_on_error,
scoped_refptr<ExtensionsServiceFrontendInterface> frontend) {
LOG(INFO) << "Installing extension " << extension_path.value();
frontend_ = frontend;
- alert_on_error_ = alert_on_error;
- external_install_ = false;
- extension_path_ = extension_path;
- install_directory_ = install_dir;
+ alert_on_error_ = false;
- InstallOrUpdateExtension(std::string());
+ bool was_update = false;
+ FilePath destination_path;
+ if (InstallOrUpdateExtension(extension_path,
+ std::string(), // no expected id
+ &destination_path, &was_update))
+ ReportExtensionInstalled(destination_path.DirName(), was_update);
}
-void ExtensionsServiceBackend::InstallOrUpdateExtension(
- const std::string& expected_id) {
- bool update = false;
+bool ExtensionsServiceBackend::InstallOrUpdateExtension(
+ const FilePath& source_file, const std::string& expected_id,
+ FilePath* version_dir, bool* was_update) {
+ if (was_update)
+ *was_update = false;
// Read and verify the extension.
- scoped_ptr<DictionaryValue> manifest(ReadManifest());
+ scoped_ptr<DictionaryValue> manifest(ReadManifest(source_file));
if (!manifest.get()) {
-
// ReadManifest has already reported the extension error.
- return;
+ return false;
}
DictionaryValue* dict = manifest.get();
Extension extension;
std::string error;
if (!extension.InitFromValue(*dict, &error)) {
- ReportExtensionInstallError("Invalid extension manifest.");
- return;
+ ReportExtensionInstallError(source_file,
+ "Invalid extension manifest.");
+ return false;
}
// If an expected id was provided, make sure it matches.
if (expected_id.length() && expected_id != extension.id()) {
- ReportExtensionInstallError(
+ ReportExtensionInstallError(source_file,
"ID in new extension manifest does not match expected ID.");
- return;
+ return false;
}
// <profile>/Extensions/<id>
@@ -620,8 +627,9 @@ void ExtensionsServiceBackend::InstallOrUpdateExtension(
std::string current_version;
if (ReadCurrentVersion(dest_dir, &current_version)) {
if (!CheckCurrentVersion(version, current_version, dest_dir))
- return;
- update = true;
+ return false;
+ if (was_update)
+ *was_update = true;
}
// <profile>/Extensions/INSTALL_TEMP
@@ -630,56 +638,46 @@ void ExtensionsServiceBackend::InstallOrUpdateExtension(
// Ensure we're starting with a clean slate.
if (file_util::PathExists(temp_dir)) {
if (!file_util::Delete(temp_dir, true)) {
- ReportExtensionInstallError(
+ ReportExtensionInstallError(source_file,
"Couldn't delete existing temporary directory.");
- return;
+ return false;
}
}
ScopedTempDir scoped_temp;
scoped_temp.Set(temp_dir);
if (!scoped_temp.IsValid()) {
- ReportExtensionInstallError("Couldn't create temporary directory.");
- return;
+ ReportExtensionInstallError(source_file,
+ "Couldn't create temporary directory.");
+ return false;
}
// <profile>/Extensions/INSTALL_TEMP/<version>
FilePath temp_version = temp_dir.AppendASCII(version);
file_util::CreateDirectory(temp_version);
- if (!Unzip(extension_path_, temp_version, NULL)) {
- ReportExtensionInstallError("Couldn't unzip extension.");
- return;
+ if (!Unzip(source_file, temp_version, NULL)) {
+ ReportExtensionInstallError(source_file, "Couldn't unzip extension.");
+ return false;
}
// <profile>/Extensions/<dir_name>/<version>
- FilePath version_dir = dest_dir.AppendASCII(version);
- if (!InstallDirSafely(temp_version, version_dir))
- return;
+ *version_dir = dest_dir.AppendASCII(version);
+ if (!InstallDirSafely(temp_version, *version_dir))
+ return false;
if (!SetCurrentVersion(dest_dir, version)) {
- if (!file_util::Delete(version_dir, true))
+ if (!file_util::Delete(*version_dir, true))
LOG(WARNING) << "Can't remove " << dest_dir.value();
- return;
- }
-
- if (external_install_) {
-
- // To mark that this extension was installed from an external source,
- // create a zero-length file. At load time, this is used to indicate
- // that the extension should be uninstalled.
- // TODO(erikkay): move this into per-extension config storage when
- // it appears.
- FilePath marker = version_dir.AppendASCII(kExternalInstallFile);
- file_util::WriteFile(marker, NULL, 0);
+ return false;
}
- ReportExtensionInstalled(dest_dir, update);
+ return true;
}
void ExtensionsServiceBackend::ReportExtensionInstallError(
- const std::string &error) {
+ const FilePath& extension_path, const std::string &error) {
// TODO(erikkay): note that this isn't guaranteed to work properly on Linux.
- std::string path_str = WideToASCII(extension_path_.ToWStringHack());
+ std::string path_str = WideToASCII(extension_path.ToWStringHack());
std::string message =
StringPrintf("Could not install extension from '%s'. %s",
path_str.c_str(), error.c_str());
@@ -687,7 +685,7 @@ void ExtensionsServiceBackend::ReportExtensionInstallError(
}
void ExtensionsServiceBackend::ReportExtensionInstalled(
- FilePath path, bool update) {
+ const FilePath& path, bool update) {
frontend_->GetMessageLoop()->PostTask(FROM_HERE, NewRunnableMethod(
frontend_,
&ExtensionsServiceFrontendInterface::OnExtensionInstalled,
@@ -695,9 +693,8 @@ void ExtensionsServiceBackend::ReportExtensionInstalled(
update));
// After it's installed, load it right away with the same settings.
- extension_path_ = path;
LOG(INFO) << "Loading extension " << path.value();
- Extension* extension = LoadExtensionCurrentVersion();
+ Extension* extension = LoadExtensionCurrentVersion(path);
if (extension) {
// Only one extension, but ReportExtensionsLoaded can handle multiple,
// so we need to construct a list.
@@ -716,7 +713,6 @@ void ExtensionsServiceBackend::ReportExtensionInstalled(
// check that location for a .crx file, which it will then install locally if
// a new version is available.
void ExtensionsServiceBackend::CheckForExternalUpdates(
- const FilePath& install_dir,
scoped_refptr<ExtensionsServiceFrontendInterface> frontend) {
// Note that this installation is intentionally silent (since it didn't
@@ -726,8 +722,6 @@ void ExtensionsServiceBackend::CheckForExternalUpdates(
// they could install an extension manually themselves anyway.
alert_on_error_ = false;
frontend_ = frontend;
- external_install_ = true;
- install_directory_ = install_dir;
#if defined(OS_WIN)
HKEY reg_root = HKEY_LOCAL_MACHINE;
@@ -741,19 +735,28 @@ void ExtensionsServiceBackend::CheckForExternalUpdates(
std::wstring extension_path;
if (key.ReadValue(kRegistryExtensionPath, &extension_path)) {
std::string id = WideToASCII(iterator.Name());
- extension_path_ = FilePath(extension_path);
std::wstring extension_version;
if (key.ReadValue(kRegistryExtensionVersion, &extension_version)) {
- if (ShouldInstall(id, WideToASCII(extension_version)))
- InstallOrUpdateExtension(id);
+ if (ShouldInstall(id, WideToASCII(extension_version))) {
+ FilePath version_dir;
+ if (InstallOrUpdateExtension(FilePath(extension_path), id,
+ &version_dir, NULL)) {
+ // To mark that this extension was installed from an external
+ // source, create a zero-length file. At load time, this is used
+ // to indicate that the extension should be uninstalled.
+ // TODO(erikkay): move this into per-extension config storage when
+ // it appears.
+ FilePath marker = version_dir.AppendASCII(
+ kExternalInstallFile);
+ file_util::WriteFile(marker, NULL, 0);
+ }
+ }
} else {
-
// TODO(erikkay): find a way to get this into about:extensions
LOG(WARNING) << "Missing value " << kRegistryExtensionVersion <<
" for key " << key_path;
}
} else {
-
// TODO(erikkay): find a way to get this into about:extensions
LOG(WARNING) << "Missing value " << kRegistryExtensionPath <<
" for key " << key_path;