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

Unified Diff: chrome/browser/upgrade_detector_impl.cc

Issue 11440020: Add an outdated upgrade bubble view. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years 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/upgrade_detector_impl.cc
diff --git a/chrome/browser/upgrade_detector_impl.cc b/chrome/browser/upgrade_detector_impl.cc
index 570275e391ba59c8452c3de6d6861f7f4ead8e04..910ff953d10f075aa0407c041bbf5a1138def240 100644
--- a/chrome/browser/upgrade_detector_impl.cc
+++ b/chrome/browser/upgrade_detector_impl.cc
@@ -16,13 +16,18 @@
#include "base/string_util.h"
#include "base/time.h"
#include "base/utf_string_conversions.h"
+#include "chrome/common/chrome_notification_types.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/chrome_version_info.h"
#include "chrome/installer/util/browser_distribution.h"
#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/notification_service.h"
+#include "content/public/browser/user_metrics.h"
#include "ui/base/resource/resource_bundle.h"
#if defined(OS_WIN)
+#include "chrome/browser/google/google_update_win.h"
+#include "chrome/installer/util/google_update_settings.h"
#include "chrome/installer/util/install_util.h"
#elif defined(OS_MACOSX)
#include "chrome/browser/mac/keystone_glue.h"
@@ -68,18 +73,11 @@ int GetCheckForUpgradeEveryMs() {
return kCheckForUpgradeMs;
}
-// This task checks the currently running version of Chrome against the
-// installed version. If the installed version is newer, it runs the passed
-// callback task. Otherwise it just deletes the task.
-void DetectUpgradeTask(const base::Closure& upgrade_detected_task,
- bool* is_unstable_channel,
- bool* is_critical_upgrade) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
-
- Version installed_version;
- Version critical_update;
-
#if defined(OS_WIN)
+// This code can be used by both regular and outdated upgrades.
Finnur 2012/12/06 19:53:16 nit: suggest: by both regular upgrades and for che
MAD 2013/01/22 15:18:29 This is gone... Reworking the whole thing...
+// |critical_update| can be NULL if not needed.
+void GetInstalledAndCriticalVersion(Version* installed_version,
+ Version* critical_update) {
// Get the version of the currently *installed* instance of Chrome,
// which might be newer than the *running* instance if we have been
// upgraded in the background.
@@ -95,12 +93,29 @@ void DetectUpgradeTask(const base::Closure& upgrade_detected_task,
// TODO(tommi): Check if using the default distribution is always the right
// thing to do.
BrowserDistribution* dist = BrowserDistribution::GetDistribution();
- InstallUtil::GetChromeVersion(dist, system_install, &installed_version);
+ DCHECK(installed_version);
+ InstallUtil::GetChromeVersion(dist, system_install, installed_version);
- if (installed_version.IsValid()) {
+ if (critical_update && installed_version->IsValid()) {
InstallUtil::GetCriticalUpdateVersion(dist, system_install,
- &critical_update);
+ critical_update);
}
+}
+#endif // defined(OS_WIN)
+
+// This task checks the currently running version of Chrome against the
+// installed version. If the installed version is newer, it runs the passed
+// callback task. Otherwise it just deletes the task.
+void DetectUpgradeTask(const base::Closure& upgrade_detected_task,
+ bool* is_unstable_channel,
+ bool* is_critical_upgrade) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
+
+ Version installed_version;
+ Version critical_update;
+
+#if defined(OS_WIN)
+ GetInstalledAndCriticalVersion(&installed_version, &critical_update);
#elif defined(OS_MACOSX)
installed_version =
Version(UTF16ToASCII(keystone_glue::CurrentlyInstalledVersion()));
@@ -150,6 +165,132 @@ void DetectUpgradeTask(const base::Closure& upgrade_detected_task,
}
}
+#if defined(OS_WIN)
Finnur 2012/12/06 19:53:16 I would probably have moved this to a _win.cc file
MAD 2013/01/22 15:18:29 Gone!
+// Implementation of a GoogleUpdateStatusListener (only available on Windows),
+// so we can get the available version and identify if we are outdated.
+class UpgradeStatusListener : public GoogleUpdateStatusListener {
+ public:
+ explicit UpgradeStatusListener(const base::Closure& notify_outdated_callback)
+ : google_updater_(new GoogleUpdate()),
+ got_installed_version_(false),
+ got_available_version_(false),
+ notify_outdated_callback_(notify_outdated_callback) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ google_updater_->set_status_listener(this);
+ // false is for |install_if_newer|, we just want the available version.
+ // And when we use false, we don't need to specify a |window|, so NULL.
+ google_updater_->CheckForUpdate(false, NULL);
+
+ // We use FILE as the thread to get the installed version
+ // since it requires reading a file. And it is safe to use an unretained
+ // this pointer since GetInstalledVersion must be called before destruction.
+ BrowserThread::PostTask(
+ BrowserThread::FILE, FROM_HERE,
+ base::Bind(&UpgradeStatusListener::GetInstalledVersion,
+ base::Unretained(this)));
+ }
+
+ virtual ~UpgradeStatusListener() {
+ google_updater_->set_status_listener(NULL);
+ }
+
+ // GoogleUpdateStatusListener implementation.
+ virtual void OnReportResults(GoogleUpdateUpgradeResult result,
+ GoogleUpdateErrorCode error_code,
+ const string16& error_message,
+ const string16& version) OVERRIDE {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ // The google update class is never supposed to sent these two to listeners.
Finnur 2012/12/06 19:53:16 nit: s/sent/send/
MAD 2013/01/22 15:18:29 Gone!
+ DCHECK(result != UPGRADE_STARTED && result != UPGRADE_CHECK_STARTED);
+
+ // Since false was specified for |install_if_newer|, this shouldn't happen.
+ DCHECK(result != UPGRADE_SUCCESSFUL);
+
+ switch (result) {
+ case UPGRADE_ALREADY_UP_TO_DATE: {
+ // Nothing needs to be done.
+ break;
+ }
+ case UPGRADE_ERROR: {
+ // Record these errors in UMA to see if something should be added here.
+ content::RecordAction(content::UserMetricsAction("UpgradeCheck_Error"));
+ break;
+ }
+ case UPGRADE_IS_AVAILABLE: {
+ available_version_ = Version(UTF16ToASCII(version));
+ break;
+ }
+ default: {
+ NOTREACHED();
+ }
+ }
+ got_available_version_ = true;
Finnur 2012/12/06 19:53:16 This variable is actually misnamed because you don
MAD 2013/01/22 15:18:29 Gone!
+ if (got_installed_version_)
+ CheckForOutdated();
+ }
+
+ private:
+ void GetInstalledVersion() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
+ Version installed_version;
+ // We only check for outdated when there are no group policies preventing
Finnur 2012/12/06 19:53:16 s/outdated/outdated version/
MAD 2013/01/22 15:18:29 Gone!
+ // regular upgrades. The test is done here because it needs access to the
+ // registry, which must be done on the FILE thread.
+ BrowserDistribution* distribution = BrowserDistribution::GetDistribution();
+ DCHECK(distribution);
+ if (GoogleUpdateSettings::GetAppUpdatePolicy(distribution->GetAppGuid(),
+ NULL) ==
+ GoogleUpdateSettings::AUTOMATIC_UPDATES) {
+ // An uninitialized install version prevents an outdated notification.
Finnur 2012/12/06 19:53:16 Not sure I understand this comment...
MAD 2013/01/22 15:18:29 Gone!
+ GetInstalledAndCriticalVersion(&installed_version, NULL);
+ }
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(&UpgradeStatusListener::GotInstalledVersion,
+ base::Unretained(this), installed_version));
+ }
+
+ void GotInstalledVersion(const Version& installed_version) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ installed_version_ = installed_version;
+ got_installed_version_ = true;
+ if (got_available_version_)
+ CheckForOutdated();
+ }
+
+ void CheckForOutdated() {
Finnur 2012/12/06 19:53:16 nit: Suggest: CheckIfOutdatedVersion or NotifyIfOu
MAD 2013/01/22 15:18:29 Gone!
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ DCHECK(got_available_version_ && got_installed_version_);
+ if (available_version_.IsValid() && installed_version_.IsValid() &&
+ available_version_.components()[0] >
+ installed_version_.components()[0] + 1) {
+ notify_outdated_callback_.Run();
+ }
+ delete this;
+ }
+
+ // The class that communicates with Google Update to find out if an update is
+ // available and asks it to start an upgrade.
+ scoped_refptr<GoogleUpdate> google_updater_;
+
+ // The value returned by GetInstalledAndCriticalVersion might be invalid
+ // so a bool is also needed to identify that we at least tried to read it.
+ Version installed_version_;
+ bool got_installed_version_;
+
+ // The value returned by google_updater_ might also be invalid
+ // so a bool is also needed to identify that we at least tried to read it.
+ Version available_version_;
+ bool got_available_version_;
+
+ // A callback to notify of an outdated install.
+ base::Closure notify_outdated_callback_;
+
+ DISALLOW_COPY_AND_ASSIGN(UpgradeStatusListener);
+};
+
+#endif // defined(OS_WIN)
+
} // namespace
UpgradeDetectorImpl::UpgradeDetectorImpl()
@@ -175,6 +316,13 @@ UpgradeDetectorImpl::UpgradeDetectorImpl()
this, &UpgradeDetectorImpl::CheckForUpgrade);
}
#endif
+#if defined(OS_WIN) && defined(GOOGLE_CHROME_BUILD)
+ // On Windows, we also check for an outdated version so we use this listener
+ // of Google update to asynchronously fetch the available version.
+ // This object will self-destruct when done.
+ new UpgradeStatusListener(base::Bind(&UpgradeDetectorImpl::NotifyOutdated,
+ weak_factory_.GetWeakPtr()));
+#endif // defined(OS_WIN)
}
UpgradeDetectorImpl::~UpgradeDetectorImpl() {
@@ -268,6 +416,19 @@ void UpgradeDetectorImpl::NotifyOnUpgrade() {
NotifyUpgradeRecommended();
}
+void UpgradeDetectorImpl::NotifyOutdated() {
+ // Stop the recurring timer (that is checking for changes).
+ detect_upgrade_timer_.Stop();
+ set_upgrade_notification_stage(UPGRADE_ANNOYANCE_CRITICAL);
+
+ content::NotificationService::current()->Notify(
+ chrome::NOTIFICATION_OUTDATED_INSTALL,
+ content::Source<UpgradeDetector>(this),
+ content::NotificationService::NoDetails());
+
+ NotifyUpgradeRecommended();
+}
+
// static
UpgradeDetectorImpl* UpgradeDetectorImpl::GetInstance() {
return Singleton<UpgradeDetectorImpl>::get();

Powered by Google App Engine
This is Rietveld 408576698