Index: chrome/browser/extensions/extension_updater.cc |
diff --git a/chrome/browser/extensions/extension_updater.cc b/chrome/browser/extensions/extension_updater.cc |
index 9360bad51559ec5161b9a0c5d6b60a4e08caf30d..89d6a09bd481a0d4e3f1d02db21a80f2f134c28c 100644 |
--- a/chrome/browser/extensions/extension_updater.cc |
+++ b/chrome/browser/extensions/extension_updater.cc |
@@ -22,7 +22,9 @@ |
#include "base/version.h" |
#include "crypto/sha2.h" |
#include "content/common/notification_service.h" |
+#include "content/common/notification_source.h" |
#include "chrome/browser/browser_process.h" |
+#include "chrome/browser/extensions/crx_installer.h" |
#include "chrome/browser/extensions/extension_error_reporter.h" |
#include "chrome/browser/extensions/extension_service.h" |
#include "chrome/browser/prefs/pref_service.h" |
@@ -444,6 +446,20 @@ ExtensionUpdater::ExtensionFetch::ExtensionFetch(const std::string& i, |
ExtensionUpdater::ExtensionFetch::~ExtensionFetch() {} |
+ExtensionUpdater::FetchedCrxFile::FetchedCrxFile(const std::string& i, |
+ const FilePath& p, |
+ const GURL& u) |
+ : id(i), |
+ path(p), |
+ download_url(u) {} |
+ |
+ExtensionUpdater::FetchedCrxFile::FetchedCrxFile() |
+ : id(""), |
+ path(), |
+ download_url() {} |
+ |
+ExtensionUpdater::FetchedCrxFile::~FetchedCrxFile() {} |
+ |
ExtensionUpdater::ExtensionUpdater(ExtensionServiceInterface* service, |
ExtensionPrefs* extension_prefs, |
PrefService* prefs, |
@@ -454,7 +470,8 @@ ExtensionUpdater::ExtensionUpdater(ExtensionServiceInterface* service, |
service_(service), frequency_seconds_(frequency_seconds), |
method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), |
will_check_soon_(false), extension_prefs_(extension_prefs), |
- prefs_(prefs), profile_(profile), blacklist_checks_enabled_(true) { |
+ prefs_(prefs), profile_(profile), blacklist_checks_enabled_(true), |
+ crx_install_is_running_(false) { |
Init(); |
} |
@@ -839,10 +856,56 @@ void ExtensionUpdater::OnCRXFileWritten(const std::string& id, |
const FilePath& path, |
const GURL& download_url) { |
DCHECK(alive_); |
- // The ExtensionService is now responsible for cleaning up the temp file |
- // at |path|. |
- service_->UpdateExtension(id, path, download_url); |
- in_progress_ids_.erase(id); |
+ |
+ FetchedCrxFile fetched(id, path, download_url); |
+ fetched_crx_files_.push(fetched); |
+ |
+ MaybeUpdateCrxFile(); |
+} |
+ |
+bool ExtensionUpdater::MaybeUpdateCrxFile() { |
+ if (crx_install_is_running_) { |
+ return false; |
+ } |
+ |
+ while (!fetched_crx_files_.empty() && !crx_install_is_running_) { |
+ const FetchedCrxFile& crx_file = fetched_crx_files_.top(); |
+ |
+ // The ExtensionService is now responsible for cleaning up the temp file |
+ // at |extension_file.path|. |
+ Source<CrxInstaller> install_notification_source(NULL); |
+ if (service_->UpdateExtension(crx_file.id, |
+ crx_file.path, |
+ crx_file.download_url, |
+ &install_notification_source)) { |
+ crx_install_is_running_ = true; |
+ |
+ // Source parameter ensures that we only see the completion event for the |
+ // the installer we started. |
+ registrar_.Add(this, |
+ NotificationType::CRX_INSTALLER_DONE, |
+ install_notification_source); |
+ } |
+ in_progress_ids_.erase(crx_file.id); |
+ fetched_crx_files_.pop(); |
+ } |
+ |
+ // If an updater is running, it was started above. |
+ return crx_install_is_running_; |
+} |
+ |
+void ExtensionUpdater::Observe(NotificationType type, |
+ const NotificationSource& source, |
+ const NotificationDetails& details) { |
+ DCHECK(type == NotificationType::CRX_INSTALLER_DONE); |
+ |
+ // No need to listen for CRX_INSTALLER_DONE anymore. |
+ registrar_.Remove(this, |
+ NotificationType::CRX_INSTALLER_DONE, |
+ source); |
+ crx_install_is_running_ = false; |
+ // If any files are available to update, start one. |
+ MaybeUpdateCrxFile(); |
} |
void ExtensionUpdater::OnCRXFileWriteError(const std::string& id) { |