Index: components/component_updater/default_component_installer.cc |
diff --git a/components/component_updater/default_component_installer.cc b/components/component_updater/default_component_installer.cc |
index 1a7a3173a02a01575b93f4b06c0c439fc9e60c1d..a5ec0ba40d25805ff96cec94a623f366009303d3 100644 |
--- a/components/component_updater/default_component_installer.cc |
+++ b/components/component_updater/default_component_installer.cc |
@@ -12,11 +12,13 @@ |
#include "base/files/file_path.h" |
#include "base/files/file_util.h" |
#include "base/location.h" |
+#include "base/path_service.h" |
#include "base/sequenced_task_runner.h" |
#include "base/single_thread_task_runner.h" |
#include "base/thread_task_runner_handle.h" |
#include "base/values.h" |
#include "base/version.h" |
+#include "components/component_updater/component_updater_paths.h" |
// TODO(ddorwin): Find a better place for ReadManifest. |
#include "components/component_updater/component_updater_service.h" |
#include "components/update_client/component_unpacker.h" |
@@ -106,8 +108,11 @@ bool DefaultComponentInstaller::Install(const base::DictionaryValue& manifest, |
return false; |
if (current_version_.CompareTo(version) > 0) |
return false; |
- base::FilePath install_path = |
- installer_traits_->GetBaseDirectory().AppendASCII(version.GetString()); |
+ base::FilePath install_path; |
+ if (!PathService::Get(DIR_COMPONENT_USER, &install_path)) |
+ return false; |
+ install_path = install_path.Append(installer_traits_->GetRelativeInstallDir()) |
+ .AppendASCII(version.GetString()); |
if (base::PathExists(install_path)) { |
if (!base::DeleteFile(install_path, true)) |
return false; |
@@ -117,6 +122,7 @@ bool DefaultComponentInstaller::Install(const base::DictionaryValue& manifest, |
return false; |
} |
current_version_ = version; |
+ current_install_dir_ = install_path; |
// TODO(ddorwin): Change parameter to std::unique_ptr<base::DictionaryValue> |
// so we can avoid this DeepCopy. |
current_manifest_.reset(manifest.DeepCopy()); |
@@ -134,10 +140,7 @@ bool DefaultComponentInstaller::GetInstalledFile( |
base::FilePath* installed_file) { |
if (current_version_ == base::Version(kNullVersion)) |
return false; // No component has been installed yet. |
- |
- *installed_file = installer_traits_->GetBaseDirectory() |
- .AppendASCII(current_version_.GetString()) |
- .AppendASCII(file); |
+ *installed_file = current_install_dir_.AppendASCII(file); |
return true; |
} |
@@ -149,21 +152,52 @@ bool DefaultComponentInstaller::Uninstall() { |
return true; |
} |
+bool DefaultComponentInstaller::FindPreinstallation() { |
+ base::FilePath path; |
+ if (!PathService::Get(DIR_COMPONENT_PREINSTALLED, &path)) |
+ return false; |
+ path = path.Append(installer_traits_->GetRelativeInstallDir()); |
+ if (!base::PathExists(path)) |
+ return false; |
+ std::unique_ptr<base::DictionaryValue> manifest = |
Sorin Jianu
2016/05/12 17:22:07
can this be const?
waffles
2016/05/13 18:19:13
I don't think so, because current_manifest_ is not
|
+ update_client::ReadManifest(path); |
+ if (!manifest || !installer_traits_->VerifyInstallation(*manifest, path)) |
+ return false; |
+ std::string version_lexical; |
+ if (!manifest->GetStringASCII("version", &version_lexical)) |
+ return false; |
+ base::Version version(version_lexical); |
Sorin Jianu
2016/05/12 17:22:07
const?
waffles
2016/05/13 18:19:13
Done.
|
+ if (!version.IsValid()) |
+ return false; |
+ current_install_dir_ = path; |
+ current_manifest_ = std::move(manifest); |
+ current_version_ = version; |
+ return true; |
+} |
+ |
void DefaultComponentInstaller::StartRegistration(ComponentUpdateService* cus) { |
DCHECK(task_runner_.get()); |
DCHECK(task_runner_->RunsTasksOnCurrentThread()); |
- base::FilePath base_dir = installer_traits_->GetBaseDirectory(); |
+ |
+ base::Version latest_version(kNullVersion); |
+ |
+ // First check for an installation set up alongside Chrome itself. |
+ if (FindPreinstallation()) |
+ latest_version = current_version_; |
+ |
+ // Then check for a higher-versioned user-wide installation. |
+ base::FilePath latest_path; |
+ std::unique_ptr<base::DictionaryValue> latest_manifest; |
+ base::FilePath base_dir; |
+ if (!PathService::Get(DIR_COMPONENT_USER, &base_dir)) |
+ return; |
+ base_dir = base_dir.Append(installer_traits_->GetRelativeInstallDir()); |
if (!base::PathExists(base_dir) && !base::CreateDirectory(base_dir)) { |
PLOG(ERROR) << "Could not create the base directory for " |
<< installer_traits_->GetName() << " (" |
<< base_dir.MaybeAsASCII() << ")."; |
return; |
} |
- |
- base::FilePath latest_path; |
- base::Version latest_version(kNullVersion); |
- std::unique_ptr<base::DictionaryValue> latest_manifest; |
- |
std::vector<base::FilePath> older_paths; |
base::FileEnumerator file_enumerator( |
base_dir, false, base::FileEnumerator::DIRECTORIES); |
@@ -196,10 +230,8 @@ void DefaultComponentInstaller::StartRegistration(ComponentUpdateService* cus) { |
// New valid |version| folder found! |
- if (latest_manifest) { |
- DCHECK(!latest_path.empty()); |
+ if (!latest_path.empty()) |
older_paths.push_back(latest_path); |
- } |
latest_path = path; |
latest_version = version; |
@@ -209,6 +241,7 @@ void DefaultComponentInstaller::StartRegistration(ComponentUpdateService* cus) { |
if (latest_manifest) { |
current_version_ = latest_version; |
current_manifest_ = std::move(latest_manifest); |
+ current_install_dir_ = latest_path; |
// TODO(ddorwin): Remove these members and pass them directly to |
// FinishRegistration(). |
base::ReadFileToString(latest_path.AppendASCII("manifest.fingerprint"), |
@@ -224,8 +257,15 @@ void DefaultComponentInstaller::StartRegistration(ComponentUpdateService* cus) { |
void DefaultComponentInstaller::UninstallOnTaskRunner() { |
DCHECK(task_runner_.get()); |
DCHECK(task_runner_->RunsTasksOnCurrentThread()); |
- const base::FilePath base_dir = installer_traits_->GetBaseDirectory(); |
+ // Only try to delete any files that are in our user-level install path. |
+ base::FilePath userInstallPath; |
+ if (!PathService::Get(DIR_COMPONENT_USER, &userInstallPath)) |
+ return; |
+ if (!userInstallPath.IsParent(current_install_dir_)) |
+ return; |
+ |
+ base::FilePath base_dir = current_install_dir_.DirName(); |
Sorin Jianu
2016/05/12 17:22:07
maybe const?
waffles
2016/05/13 18:19:13
Done.
|
base::FileEnumerator file_enumerator(base_dir, false, |
base::FileEnumerator::DIRECTORIES); |
for (base::FilePath path = file_enumerator.Next(); !path.value().empty(); |
@@ -248,11 +288,6 @@ void DefaultComponentInstaller::UninstallOnTaskRunner() { |
} |
} |
-base::FilePath DefaultComponentInstaller::GetInstallDirectory() { |
- return installer_traits_->GetBaseDirectory() |
- .AppendASCII(current_version_.GetString()); |
-} |
- |
void DefaultComponentInstaller::FinishRegistration( |
ComponentUpdateService* cus, |
const base::Closure& callback) { |
@@ -287,8 +322,8 @@ void DefaultComponentInstaller::FinishRegistration( |
void DefaultComponentInstaller::ComponentReady( |
std::unique_ptr<base::DictionaryValue> manifest) { |
VLOG(1) << "Component ready, version " << current_version_.GetString() |
- << " in " << GetInstallDirectory().value(); |
- installer_traits_->ComponentReady(current_version_, GetInstallDirectory(), |
+ << " in " << current_install_dir_.value(); |
+ installer_traits_->ComponentReady(current_version_, current_install_dir_, |
std::move(manifest)); |
} |