diff options
author | Klaas Freitag <freitag@owncloud.com> | 2015-07-23 12:34:12 +0300 |
---|---|---|
committer | Klaas Freitag <freitag@owncloud.com> | 2015-07-23 12:34:12 +0300 |
commit | 316427c801997e811a9c8ea30ab470e33ec7a3bc (patch) | |
tree | 002c632533f831eb4ee60d547d2fdf56541f09d5 /src/gui/updater | |
parent | 59a7ae56d4e602ab1b33e529eedd382b08e5470d (diff) | |
parent | c34641f4f7013ded6b73f43a9a6b22aac8c7c80a (diff) |
Merge branch 'regular_update_check'
Conflicts:
src/gui/application.cpp
src/gui/application.h
src/gui/updater/ocupdater.h
Diffstat (limited to 'src/gui/updater')
-rw-r--r-- | src/gui/updater/ocupdater.cpp | 90 | ||||
-rw-r--r-- | src/gui/updater/ocupdater.h | 61 | ||||
-rw-r--r-- | src/gui/updater/updater.cpp | 6 | ||||
-rw-r--r-- | src/gui/updater/updater.h | 2 |
4 files changed, 147 insertions, 12 deletions
diff --git a/src/gui/updater/ocupdater.cpp b/src/gui/updater/ocupdater.cpp index 1a31afa1a..b62a40de1 100644 --- a/src/gui/updater/ocupdater.cpp +++ b/src/gui/updater/ocupdater.cpp @@ -36,13 +36,59 @@ static const char seenVersionC[] = "Updater/seenVersion"; static const char autoUpdateFailedVersionC[] = "Updater/autoUpdateFailedVersion"; static const char autoUpdateAttemptedC[] = "Updater/autoUpdateAttempted"; + +UpdaterScheduler::UpdaterScheduler(QObject *parent) : + QObject(parent) +{ + connect( &_updateCheckTimer, SIGNAL(timeout()), + this, SLOT(slotTimerFired()) ); + + // Note: the sparkle-updater is not an OCUpdater and thus the dynamic_cast + // returns NULL. Clever detail. + if (OCUpdater *updater = dynamic_cast<OCUpdater*>(Updater::instance())) { + connect(updater, SIGNAL(newUpdateAvailable(QString,QString)), + this, SIGNAL(updaterAnnouncement(QString,QString)) ); + } + + // at startup, do a check in any case. + QTimer::singleShot(3000, this, SLOT(slotTimerFired())); + + ConfigFile cfg; + auto checkInterval = cfg.updateCheckInterval(); + _updateCheckTimer.start(checkInterval); +} + +void UpdaterScheduler::slotTimerFired() +{ + ConfigFile cfg; + + // re-set the check interval if it changed in the config file meanwhile + auto checkInterval = cfg.updateCheckInterval(); + if( checkInterval != _updateCheckTimer.interval() ) { + _updateCheckTimer.setInterval(checkInterval); + qDebug() << "Setting new update check interval " << checkInterval; + } + + // consider the skipUpdateCheck flag in the config. + if( cfg.skipUpdateCheck() ) { + qDebug() << Q_FUNC_INFO << "Skipping update check because of config file"; + return; + } + + Updater::instance()->backgroundCheckForUpdate(); +} + + +/* ----------------------------------------------------------------- */ + OCUpdater::OCUpdater(const QUrl &url, QObject *parent) : QObject(parent) , _updateUrl(url) , _state(Unknown) , _accessManager(new AccessManager(this)) - , _timer(new QTimer(this)) + , _timeoutWatchdog(new QTimer(this)) { + } bool OCUpdater::performUpdate() @@ -65,8 +111,24 @@ bool OCUpdater::performUpdate() void OCUpdater::backgroundCheckForUpdate() { - // FIXME - checkForUpdate(); + int dlState = downloadState(); + + // do the real update check depending on the internal state of updater. + switch( dlState ) { + case Unknown: + case UpToDate: + case DownloadFailed: + case DownloadTimedOut: + qDebug() << Q_FUNC_INFO << "checking for available update"; + checkForUpdate(); + break; + case DownloadComplete: + qDebug() << "Update is downloaded, skip new check."; + break; + case UpdateOnlyAvailableThroughSystem: + qDebug() << "Update is only available through system, skip check."; + break; + } } QString OCUpdater::statusString() const @@ -102,8 +164,17 @@ int OCUpdater::downloadState() const void OCUpdater::setDownloadState(DownloadState state) { + auto oldState = _state; _state = state; emit downloadStateChanged(); + + // show the notification if the download is complete (on every check) + // or once for system based updates. + if( _state == OCUpdater::DownloadComplete || + (oldState != OCUpdater::UpdateOnlyAvailableThroughSystem + && _state == OCUpdater::UpdateOnlyAvailableThroughSystem) ) { + emit newUpdateAvailable(tr("Update Check"), statusString() ); + } } void OCUpdater::slotStartInstaller() @@ -120,8 +191,8 @@ void OCUpdater::slotStartInstaller() void OCUpdater::checkForUpdate() { QNetworkReply *reply = _accessManager->get(QNetworkRequest(_updateUrl)); - connect(_timer, SIGNAL(timeout()), this, SLOT(slotTimedOut())); - _timer->start(30*1000); + connect(_timeoutWatchdog, SIGNAL(timeout()), this, SLOT(slotTimedOut())); + _timeoutWatchdog->start(30*1000); connect(reply, SIGNAL(finished()), this, SLOT(slotVersionInfoArrived())); setDownloadState(CheckingServer); @@ -144,7 +215,7 @@ bool OCUpdater::updateSucceeded() const void OCUpdater::slotVersionInfoArrived() { - _timer->stop(); + _timeoutWatchdog->stop(); QNetworkReply *reply = qobject_cast<QNetworkReply*>(sender()); if( reply->error() != QNetworkReply::NoError ) { qDebug() << "Failed to reach version check url: " << reply->errorString(); @@ -355,10 +426,11 @@ PassiveUpdateNotifier::PassiveUpdateNotifier(const QUrl &url, QObject *parent) void PassiveUpdateNotifier::versionInfoArrived(const UpdateInfo &info) { + qint64 currentVer = Helper::currentVersionToInt(); + qint64 remoteVer = Helper::stringVersionToInt(info.version()); + if( info.version().isEmpty() || - Helper::stringVersionToInt(info.version()) - >= Helper::currentVersionToInt() ) - { + currentVer >= remoteVer ) { qDebug() << "Client is on latest version!"; setDownloadState(UpToDate); } else { diff --git a/src/gui/updater/ocupdater.h b/src/gui/updater/ocupdater.h index 51dce7258..08c1c5a92 100644 --- a/src/gui/updater/ocupdater.h +++ b/src/gui/updater/ocupdater.h @@ -18,17 +18,70 @@ #include <QObject> #include <QUrl> #include <QTemporaryFile> +#include <QTimer> #include "updater/updateinfo.h" #include "updater/updater.h" class QNetworkAccessManager; class QNetworkReply; -class QTimer; namespace OCC { /** + * @brief Schedule update checks every couple of hours if the client runs. + * @ingroup gui + * + * This class schedules regular update checks. It also checks the config + * if update checks are wanted at all. + * + * To reflect that all platforms have its own update scheme, a little + * complex class design was set up: + * + * For Windows and Linux, the updaters are inherited from OCUpdater, while + * the MacOSX SparkleUpdater directly uses the class Updater. On windows, + * NSISUpdater starts the update if a new version of the client is available. + * On MacOSX, the sparkle framework handles the installation of the new + * version. On Linux, the update capabilities by the underlying linux distro + * is relied on, and thus the PassiveUpdateNotifier just shows a notification + * if there is a new version once at every start of the application. + * + * Simple class diagram of the updater: + * + * +---------------------------+ + * +-----+ UpdaterScheduler +-----+ + * | +------------+--------------+ | + * v v v + * +------------+ +---------------------+ +----------------+ + * |NSISUpdater | |PassiveUpdateNotifier| | SparkleUpdater | + * +-+----------+ +---+-----------------+ +-----+----------+ + * | | | + * | v +------------------+ + * | +---------------+ v + * +-->| OCUpdater +------+ + * +--------+------+ | + * | Updater | + * +-------------+ + */ + +class UpdaterScheduler : public QObject +{ + Q_OBJECT +public: + UpdaterScheduler(QObject *parent); + +signals: + void updaterAnnouncement(const QString& title, const QString& msg); + +private slots: + void slotTimerFired(); + +private: + QTimer _updateCheckTimer; /** Timer for the regular update check. */ + +}; + +/** * @brief Class that uses an ownCloud propritary XML format to fetch update information * @ingroup gui */ @@ -45,7 +98,6 @@ public: bool performUpdate(); void checkForUpdate() Q_DECL_OVERRIDE; - void backgroundCheckForUpdate() Q_DECL_OVERRIDE; QString statusString() const; int downloadState() const; @@ -53,11 +105,14 @@ public: signals: void downloadStateChanged(); + void newUpdateAvailable(const QString& header, const QString& message); public slots: void slotStartInstaller(); private slots: + void backgroundCheckForUpdate() Q_DECL_OVERRIDE; + void slotOpenUpdateUrl(); void slotVersionInfoArrived(); void slotTimedOut(); @@ -71,7 +126,7 @@ private: QUrl _updateUrl; int _state; QNetworkAccessManager *_accessManager; - QTimer *_timer; + QTimer *_timeoutWatchdog; /** Timer to guard the timeout of an individual network request */ UpdateInfo _updateInfo; }; diff --git a/src/gui/updater/updater.cpp b/src/gui/updater/updater.cpp index 85db07b30..d9d0a669d 100644 --- a/src/gui/updater/updater.cpp +++ b/src/gui/updater/updater.cpp @@ -96,6 +96,7 @@ Updater *Updater::create() #else return new PassiveUpdateNotifier(QUrl(updateBaseUrl)); #endif + } @@ -125,4 +126,9 @@ QString Updater::clientVersion() return QString::fromLatin1(MIRALL_STRINGIFY(MIRALL_VERSION_FULL)); } +int Updater::downloadState() const +{ + return instance()->downloadState(); +} + } // namespace OCC diff --git a/src/gui/updater/updater.h b/src/gui/updater/updater.h index 4dddeb3b5..746120a19 100644 --- a/src/gui/updater/updater.h +++ b/src/gui/updater/updater.h @@ -33,6 +33,8 @@ public: virtual void checkForUpdate() = 0; virtual void backgroundCheckForUpdate() = 0; + int downloadState() const; + virtual bool handleStartup() = 0; protected: |