Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2327)

Unified Diff: chrome/browser/component_updater/pnacl/pnacl_component_installer.cc

Issue 17001003: Replace early check for PNaCl with an on-demand check. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: cleanup a bit Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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 3575fdaca01d84b5638c0189eb240e1b898c8e25..e2799c41bb4bd00f886f05e98cf726071c7a660a 100644
--- a/chrome/browser/component_updater/pnacl/pnacl_component_installer.cc
+++ b/chrome/browser/component_updater/pnacl/pnacl_component_installer.cc
@@ -6,6 +6,7 @@
#include "base/base_paths.h"
#include "base/bind.h"
+#include "base/callback.h"
#include "base/command_line.h"
#include "base/compiler_specific.h"
#include "base/file_util.h"
@@ -33,23 +34,13 @@ using content::BrowserThread;
namespace {
-// If PNaCl isn't installed yet, but a user is running chrome with
-// --enable-pnacl, this is the amount of time to wait before starting
-// a background install.
-const int kInitialDelaySeconds = 10;
+// Time in seconds to wait for CheckUpdatesForPnacl to complete
+// before considering the update failed.
+int kPnaclInstallerTimeout = 60;
// Name of the Pnacl component specified in the manifest.
const char kPnaclManifestNamePrefix[] = "PNaCl";
-// Sanitize characters from Pnacl Arch value so that they can be used
-// in path names. This should only be characters in the set: [a-z0-9_].
-// Keep in sync with chrome/browser/nacl_host/nacl_file_host.
-std::string SanitizeForPath(const std::string& input) {
- std::string result;
- ReplaceChars(input, "-", "_", &result);
- return result;
-}
-
// Set the component's hash to the arch-specific PNaCl package.
void SetPnaclHash(CrxComponent* component) {
#if defined(ARCH_CPU_X86_FAMILY)
@@ -219,7 +210,8 @@ bool CheckPnaclComponentManifest(const base::DictionaryValue& manifest,
PnaclComponentInstaller::PnaclComponentInstaller()
: per_user_(false),
- cus_(NULL) {
+ cus_(NULL),
+ callback_nums_(0) {
#if defined(OS_CHROMEOS)
per_user_ = true;
#endif
@@ -266,56 +258,111 @@ void PnaclComponentInstaller::OnProfileChange() {
bool PnaclComponentInstaller::Install(const base::DictionaryValue& manifest,
const base::FilePath& unpack_path) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
scoped_ptr<base::DictionaryValue> pnacl_manifest(
ReadPnaclManifest(unpack_path));
if (pnacl_manifest == NULL) {
LOG(WARNING) << "Failed to read pnacl manifest.";
+ NotifyInstallError();
return false;
}
Version version;
if (!CheckPnaclComponentManifest(manifest, *pnacl_manifest, &version)) {
LOG(WARNING) << "CheckPnaclComponentManifest failed, not installing.";
+ NotifyInstallError();
return false;
}
// Don't install if the current version is actually newer.
- if (current_version().CompareTo(version) > 0)
+ if (current_version().CompareTo(version) > 0) {
+ NotifyInstallError();
return false;
+ }
// Passed the basic tests. Time to install it.
base::FilePath path = GetPnaclBaseDirectory().AppendASCII(
version.GetString());
if (file_util::PathExists(path)) {
LOG(WARNING) << "Target path already exists, not installing.";
+ NotifyInstallError();
return false;
}
if (!file_util::Move(unpack_path, path)) {
LOG(WARNING) << "Move failed, not installing.";
+ NotifyInstallError();
return false;
}
- // Installation is done. Now tell the rest of chrome (just the path service
- // for now). TODO(jvoung): we need notifications if someone surfed to a
- // 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
+ // Installation is done. Now tell the rest of chrome.
+ // - The path service.
+ // - Callbacks that requested an update.
set_current_version(version);
-
+ NotifyInstallSuccess();
PathService::Override(chrome::DIR_PNACL_COMPONENT, path);
return true;
}
-namespace {
+void PnaclComponentInstaller::AddInstallCallback(
+ const InstallCallback& cb) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ int num = ++callback_nums_;
+ install_callbacks_.push_back(std::make_pair(cb, num));
-void DoCheckForUpdate(ComponentUpdateService* cus,
- const CrxComponent& pnacl) {
- if (cus->CheckForUpdateSoon(pnacl) != ComponentUpdateService::kOk) {
- LOG(WARNING) << "Pnacl check for update failed.";
+ // Set a timeout. If the install doesn't complete within a minute,
+ // assume that the update failed and cancel the callback.
+ // Do this on the same thread that would have checked the callbacks.
+ BrowserThread::PostDelayedTask(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(&PnaclComponentInstaller::CancelCallback,
+ // Why unretained? The installer should have
sehr 2013/06/14 18:23:43 Perhaps a better phrasing would be "we use Unretai
jvoung (off chromium) 2013/06/14 18:57:50 Done.
+ // the same lifetime as the component updater service,
+ // which lives until process shutdown.
+ base::Unretained(this),
+ num),
+ base::TimeDelta::FromSeconds(kPnaclInstallerTimeout));
+}
+
+void PnaclComponentInstaller::CancelCallback(int num) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ for (std::list<std::pair<InstallCallback, int> >::iterator
+ i = install_callbacks_.begin(),
+ e = install_callbacks_.end(); i != e; ++i) {
+ if (i->second == num) {
+ i->first.Run(false);
+ install_callbacks_.erase(i);
+ return;
+ }
+ }
+}
+
+void PnaclComponentInstaller::NotifyAllWithResult(bool status) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ while (!install_callbacks_.empty()) {
+ install_callbacks_.front().first.Run(status);
+ install_callbacks_.pop_front();
}
}
-// Finally, do the registration with the right version number.
+void PnaclComponentInstaller::NotifyInstallError() {
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(&PnaclComponentInstaller::NotifyAllWithResult,
+ // Why unretained? The installer lives until process shutdown.
sehr 2013/06/14 18:23:43 Same comment issue here.
jvoung (off chromium) 2013/06/14 18:57:50 Done.
+ base::Unretained(this), false));
+}
+
+
+void PnaclComponentInstaller::NotifyInstallSuccess() {
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(&PnaclComponentInstaller::NotifyAllWithResult,
+ // Why unretained? The installer lives until process shutdown.
+ base::Unretained(this), true));
+}
+
+namespace {
+
void FinishPnaclUpdateRegistration(const Version& current_version,
PnaclComponentInstaller* pci) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
@@ -332,17 +379,6 @@ void FinishPnaclUpdateRegistration(const Version& current_version,
&& status != ComponentUpdateService::kReplaced) {
NOTREACHED() << "Pnacl component registration failed.";
}
-
- // If PNaCl is not yet installed but it is requested by --enable-pnacl,
- // we want it to be available "soon", so kick off an update check
- // earlier than usual.
- Version null_version(kNullVersion);
- if (pci->current_version().Equals(null_version)) {
- BrowserThread::PostDelayedTask(
- BrowserThread::UI, FROM_HERE,
- base::Bind(DoCheckForUpdate, pci->cus(), pnacl_component),
- base::TimeDelta::FromSeconds(kInitialDelaySeconds));
- }
}
// Check if there is an existing version on disk first to know when
@@ -407,8 +443,7 @@ void GetProfileInformation(PnaclComponentInstaller* pci) {
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).
+ // Only register when given the right flag, for now.
if (command_line.HasSwitch(switches::kEnablePnacl)) {
cus_ = cus;
// If per_user, create a profile observer to watch for logins.
@@ -418,13 +453,11 @@ void PnaclComponentInstaller::RegisterPnaclComponent(
}
if (per_user_) {
// Figure out profile information, before proceeding to look for files.
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- base::Bind(&GetProfileInformation, this));
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
+ base::Bind(&GetProfileInformation, this));
} else {
- BrowserThread::PostTask(
- BrowserThread::FILE, FROM_HERE,
- base::Bind(&StartPnaclUpdateRegistration, this));
+ BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
+ base::Bind(&StartPnaclUpdateRegistration, this));
}
}
}
@@ -440,3 +473,23 @@ void PnaclComponentInstaller::ReRegisterPnacl() {
BrowserThread::UI, FROM_HERE,
base::Bind(&GetProfileInformation, this));
}
+
+void RequestFirstInstall(ComponentUpdateService* cus,
+ PnaclComponentInstaller* pci,
+ const base::Callback<void(bool)>& installed) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ Version null_version(kNullVersion);
+ CrxComponent pnacl_component;
+ pci->set_current_version(null_version);
+ pnacl_component.version = null_version;
+ pnacl_component.name = "pnacl";
+ pnacl_component.installer = pci;
+ SetPnaclHash(&pnacl_component);
+ ComponentUpdateService::Status status = cus->CheckForUpdateSoon(
+ pnacl_component);
+ if (status != ComponentUpdateService::kOk) {
+ installed.Run(false);
+ return;
+ }
+ pci->AddInstallCallback(installed);
+}
« no previous file with comments | « chrome/browser/component_updater/pnacl/pnacl_component_installer.h ('k') | chrome/browser/nacl_host/nacl_file_host.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698