Index: chrome/browser/component_updater/pnacl/pnacl_component_installer.cc |
diff --git a/chrome/browser/component_updater/pnacl/pnacl_component_installer.cc b/chrome/browser/component_updater/pnacl/pnacl_component_installer.cc |
index f26ef1a3a0853d0df632a32b0545174a074591e4..bd4838d3b484d2e35ceac7db1f20cd947ec76d6b 100644 |
--- a/chrome/browser/component_updater/pnacl/pnacl_component_installer.cc |
+++ b/chrome/browser/component_updater/pnacl/pnacl_component_installer.cc |
@@ -18,7 +18,10 @@ |
#include "base/version.h" |
#include "base/win/windows_version.h" |
#include "build/build_config.h" |
+#include "chrome/browser/browser_process.h" |
#include "chrome/browser/component_updater/component_updater_service.h" |
+#include "chrome/browser/profiles/profile.h" |
+#include "chrome/browser/profiles/profile_manager.h" |
#include "chrome/common/chrome_paths.h" |
#include "chrome/common/chrome_switches.h" |
#include "chrome/common/omaha_query_params.h" |
@@ -120,17 +123,31 @@ const char kNullVersion[] = "0.0.0.0"; |
// <profile>\AppData\Local\Google\Chrome\User Data\Pnacl\0.1.2.3\. |
// and the base directory will be: |
// <profile>\AppData\Local\Google\Chrome\User Data\Pnacl\. |
-base::FilePath GetPnaclBaseDirectory() { |
- base::FilePath result; |
- CHECK(PathService::Get(chrome::DIR_PNACL_BASE, &result)); |
- return result; |
+base::FilePath GetPnaclBaseDirectory(bool per_user) { |
+ // For ChromeOS, temporarily make this user-dependent (for integrity) until |
+ // we find a better solution. |
+ // This is not ideal because of the following: |
+ // (a) We end up with per-user copies instead of a single copy |
+ // (b) The profile can change as users log in to different accounts |
+ // so we need to watch for user-login-events (see pnacl_profile_observer.h). |
+ if (per_user) { |
+ Profile* profile = ProfileManager::GetLastUsedProfile(); |
+ base::FilePath path = profile->GetPath().Append( |
+ FILE_PATH_LITERAL("pnacl")); |
+ return path; |
+ } else { |
+ base::FilePath result; |
+ CHECK(PathService::Get(chrome::DIR_PNACL_BASE, &result)); |
+ return result; |
+ } |
} |
-bool GetLatestPnaclDirectory(base::FilePath* latest_dir, |
+bool GetLatestPnaclDirectory(bool per_user, |
+ base::FilePath* latest_dir, |
Version* latest_version, |
std::vector<base::FilePath>* older_dirs) { |
// Enumerate all versions starting from the base directory. |
- base::FilePath base_dir = GetPnaclBaseDirectory(); |
+ base::FilePath base_dir = GetPnaclBaseDirectory(per_user); |
bool found = false; |
file_util::FileEnumerator |
file_enumerator(base_dir, false, file_util::FileEnumerator::DIRECTORIES); |
@@ -210,24 +227,23 @@ bool CheckPnaclComponentManifest(base::DictionaryValue* manifest, |
return true; |
} |
-class PnaclComponentInstaller : public ComponentInstaller { |
- public: |
- explicit PnaclComponentInstaller(const Version& version); |
- |
- virtual ~PnaclComponentInstaller() {} |
- |
- virtual void OnUpdateError(int error) OVERRIDE; |
- |
- virtual bool Install(base::DictionaryValue* manifest, |
- const base::FilePath& unpack_path) OVERRIDE; |
- |
- private: |
- Version current_version_; |
-}; |
+PnaclComponentInstaller::PnaclComponentInstaller() |
+ : per_user_(false), |
+ cus_(NULL) { |
+ // Fill in most of the information. The version will be discovered later. |
+ Version null_version(kNullVersion); |
+ pnacl_component_.version = null_version; |
+ pnacl_component_.name = "pnacl"; |
+ pnacl_component_.installer = this; |
+ SetPnaclHash(&pnacl_component_); |
+ |
+#if defined(OS_CHROMEOS) |
+ per_user_ = true; |
+ profile_observer_.reset(new PnaclProfileObserver(this)); |
+#endif |
+} |
-PnaclComponentInstaller::PnaclComponentInstaller( |
- const Version& version) : current_version_(version) { |
- DCHECK(version.IsValid()); |
+PnaclComponentInstaller::~PnaclComponentInstaller() { |
} |
void PnaclComponentInstaller::OnUpdateError(int error) { |
@@ -265,7 +281,7 @@ bool PnaclComponentInstaller::Install(base::DictionaryValue* manifest, |
} |
// Don't install if the current version is actually newer. |
- if (current_version_.CompareTo(version) > 0) |
+ if (current_version().CompareTo(version) > 0) |
return false; |
if (!PathContainsPnacl(unpack_path)) { |
@@ -275,7 +291,7 @@ bool PnaclComponentInstaller::Install(base::DictionaryValue* manifest, |
// Passed the basic tests. Time to install it. |
base::FilePath path = |
- GetPnaclBaseDirectory().AppendASCII(version.GetString()); |
+ GetPnaclBaseDirectory(per_user()).AppendASCII(version.GetString()); |
if (file_util::PathExists(path)) { |
LOG(WARNING) << "Target path already exists, not installing."; |
return false; |
@@ -290,7 +306,7 @@ bool PnaclComponentInstaller::Install(base::DictionaryValue* manifest, |
// Pnacl webpage and Pnacl was just installed at this time. They should |
// then be able to reload the page and retry (or something). |
// See: http://code.google.com/p/chromium/issues/detail?id=107438 |
- current_version_ = version; |
+ set_current_version(version); |
PathService::Override(chrome::DIR_PNACL_COMPONENT, path); |
return true; |
@@ -307,16 +323,13 @@ void DoCheckForUpdate(ComponentUpdateService* cus, |
// Finally, do the registration with the right version number. |
void FinishPnaclUpdateRegistration(ComponentUpdateService* cus, |
- const Version& current_version) { |
+ PnaclComponentInstaller* pci) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- // Note: the source is the default of BANDAID, even though the |
- // crxes are hosted from CWS. |
- CrxComponent pnacl; |
- pnacl.name = "pnacl"; |
- pnacl.installer = new PnaclComponentInstaller(current_version); |
- pnacl.version = current_version; |
- SetPnaclHash(&pnacl); |
- if (cus->RegisterComponent(pnacl) != ComponentUpdateService::kOk) { |
+ CrxComponent pnacl_component = pci->component(); |
+ ComponentUpdateService::Status status = |
+ cus->RegisterComponent(pnacl_component); |
+ if (status != ComponentUpdateService::kOk |
+ && status != ComponentUpdateService::kReplaced) { |
NOTREACHED() << "Pnacl component registration failed."; |
} |
@@ -324,19 +337,24 @@ void FinishPnaclUpdateRegistration(ComponentUpdateService* cus, |
// we want it to be available "soon", so kick off an update check |
// earlier than usual. |
Version null_version(kNullVersion); |
- if (current_version.Equals(null_version)) { |
+ if (pci->current_version().Equals(null_version)) { |
BrowserThread::PostDelayedTask( |
BrowserThread::UI, FROM_HERE, |
- base::Bind(DoCheckForUpdate, cus, pnacl), |
+ base::Bind(DoCheckForUpdate, cus, pnacl_component), |
base::TimeDelta::FromSeconds(kInitialDelaySeconds)); |
} |
} |
// Check if there is an existing version on disk first to know when |
// a hosted version is actually newer. |
-void StartPnaclUpdateRegistration(ComponentUpdateService* cus) { |
+void StartPnaclUpdateRegistration(ComponentUpdateService* cus, |
+ PnaclComponentInstaller* pci) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
- base::FilePath path = GetPnaclBaseDirectory(); |
+ // If installation is per-user, do not start until logged in. |
+ bool per_user = pci->per_user(); |
+ if (per_user && !g_browser_process->profile_manager()->IsLoggedIn()) |
+ return; |
+ base::FilePath path = GetPnaclBaseDirectory(per_user); |
if (!file_util::PathExists(path)) { |
if (!file_util::CreateDirectory(path)) { |
NOTREACHED() << "Could not create base Pnacl directory."; |
@@ -346,7 +364,7 @@ void StartPnaclUpdateRegistration(ComponentUpdateService* cus) { |
Version version(kNullVersion); |
std::vector<base::FilePath> older_dirs; |
- if (GetLatestPnaclDirectory(&path, &version, &older_dirs)) { |
+ if (GetLatestPnaclDirectory(per_user, &path, &version, &older_dirs)) { |
if (!PathContainsPnacl(path)) { |
version = Version(kNullVersion); |
} else { |
@@ -354,9 +372,11 @@ void StartPnaclUpdateRegistration(ComponentUpdateService* cus) { |
} |
} |
+ pci->set_current_version(version); |
cpu_(ooo_6.6-7.5)
2013/03/29 22:20:55
see my comment in the header. The passing version
jvoung (off chromium)
2013/03/29 23:22:40
Localized the setting of current version like how
|
+ |
BrowserThread::PostTask( |
BrowserThread::UI, FROM_HERE, |
- base::Bind(&FinishPnaclUpdateRegistration, cus, version)); |
+ base::Bind(&FinishPnaclUpdateRegistration, cus, pci)); |
// Remove older versions of PNaCl. |
for (std::vector<base::FilePath>::iterator iter = older_dirs.begin(); |
@@ -367,13 +387,24 @@ void StartPnaclUpdateRegistration(ComponentUpdateService* cus) { |
} // namespace |
-void RegisterPnaclComponent(ComponentUpdateService* cus, |
+void PnaclComponentInstaller::RegisterPnaclComponent( |
+ ComponentUpdateService* cus, |
const CommandLine& command_line) { |
// Only register when given the right flag. This is important since |
// we do an early component updater check above (in DoCheckForUpdate). |
if (command_line.HasSwitch(switches::kEnablePnacl)) { |
+ cus_ = cus; |
BrowserThread::PostTask( |
BrowserThread::FILE, FROM_HERE, |
- base::Bind(&StartPnaclUpdateRegistration, cus)); |
+ base::Bind(&StartPnaclUpdateRegistration, cus_, this)); |
} |
} |
+ |
+void PnaclComponentInstaller::ReRegisterPnacl() { |
+ // We only create the profile observer, which can trigger a |
+ // call to ReRegisterPnacl, if kEnablePnacl is given on the commandline. |
+ // Thus, we don't check the commandline flags again here. |
+ BrowserThread::PostTask( |
+ BrowserThread::FILE, FROM_HERE, |
+ base::Bind(&StartPnaclUpdateRegistration, cus_, this)); |
+} |