1 | /* |
2 | * Copyright (C) by Klaas Freitag <freitag@owncloud.com> |
3 | * |
4 | * This program is free software; you can redistribute it and/or modify |
5 | * it under the terms of the GNU General Public License as published by |
6 | * the Free Software Foundation; either version 2 of the License, or |
7 | * (at your option) any later version. |
8 | * |
9 | * This program is distributed in the hope that it will be useful, but |
10 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
11 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
12 | * for more details. |
13 | */ |
14 | |
15 | #ifndef OCUPDATER_H |
16 | #define OCUPDATER_H |
17 | |
18 | #include <QObject> |
19 | #include <QUrl> |
20 | #include <QTemporaryFile> |
21 | #include <QTimer> |
22 | |
23 | #include "updater/updateinfo.h" |
24 | #include "updater/updater.h" |
25 | |
26 | class QNetworkAccessManager; |
27 | class QNetworkReply; |
28 | |
29 | namespace OCC { |
30 | |
31 | /** |
32 | * @brief Schedule update checks every couple of hours if the client runs. |
33 | * @ingroup gui |
34 | * |
35 | * This class schedules regular update checks. It also checks the config |
36 | * if update checks are wanted at all. |
37 | * |
38 | * To reflect that all platforms have their own update scheme, a little |
39 | * complex class design was set up: |
40 | * |
41 | * For Windows and Linux, the updaters are inherited from OCUpdater, while |
42 | * the MacOSX SparkleUpdater directly uses the class Updater. On windows, |
43 | * NSISUpdater starts the update if a new version of the client is available. |
44 | * On MacOSX, the sparkle framework handles the installation of the new |
45 | * version. On Linux, the update capabilities of the underlying linux distro |
46 | * are relied on, and thus the PassiveUpdateNotifier just shows a notification |
47 | * if there is a new version once at every start of the application. |
48 | * |
49 | * Simple class diagram of the updater: |
50 | * |
51 | * +---------------------------+ |
52 | * +-----+ UpdaterScheduler +-----+ |
53 | * | +------------+--------------+ | |
54 | * v v v |
55 | * +------------+ +---------------------+ +----------------+ |
56 | * |NSISUpdater | |PassiveUpdateNotifier| | SparkleUpdater | |
57 | * +-+----------+ +---+-----------------+ +-----+----------+ |
58 | * | | | |
59 | * | v +------------------+ |
60 | * | +---------------+ v |
61 | * +-->| OCUpdater +------+ |
62 | * +--------+------+ | |
63 | * | Updater | |
64 | * +-------------+ |
65 | */ |
66 | |
67 | class UpdaterScheduler : public QObject |
68 | { |
69 | Q_OBJECT |
70 | public: |
71 | UpdaterScheduler(QObject *parent); |
72 | |
73 | signals: |
74 | void updaterAnnouncement(const QString &title, const QString &msg); |
75 | void requestRestart(); |
76 | |
77 | private slots: |
78 | void slotTimerFired(); |
79 | |
80 | private: |
81 | QTimer _updateCheckTimer; /** Timer for the regular update check. */ |
82 | }; |
83 | |
84 | /** |
85 | * @brief Class that uses an ownCloud proprietary XML format to fetch update information |
86 | * @ingroup gui |
87 | */ |
88 | class OCUpdater : public Updater |
89 | { |
90 | Q_OBJECT |
91 | public: |
92 | enum DownloadState { Unknown = 0, |
93 | CheckingServer, |
94 | UpToDate, |
95 | Downloading, |
96 | DownloadComplete, |
97 | DownloadFailed, |
98 | DownloadTimedOut, |
99 | UpdateOnlyAvailableThroughSystem }; |
100 | explicit OCUpdater(const QUrl &url); |
101 | |
102 | void setUpdateUrl(const QUrl &url); |
103 | |
104 | bool performUpdate(); |
105 | |
106 | void checkForUpdate() Q_DECL_OVERRIDE; |
107 | |
108 | QString statusString() const; |
109 | int downloadState() const; |
110 | void setDownloadState(DownloadState state); |
111 | |
112 | signals: |
113 | void downloadStateChanged(); |
114 | void newUpdateAvailable(const QString &, const QString &message); |
115 | void requestRestart(); |
116 | |
117 | public slots: |
118 | // FIXME Maybe this should be in the NSISUpdater which should have been called WindowsUpdater |
119 | void slotStartInstaller(); |
120 | |
121 | protected slots: |
122 | void backgroundCheckForUpdate() Q_DECL_OVERRIDE; |
123 | |
124 | private slots: |
125 | void slotOpenUpdateUrl(); |
126 | void slotVersionInfoArrived(); |
127 | void slotTimedOut(); |
128 | |
129 | protected: |
130 | virtual void versionInfoArrived(const UpdateInfo &info) = 0; |
131 | bool updateSucceeded() const; |
132 | QNetworkAccessManager *qnam() const { return _accessManager; } |
133 | UpdateInfo updateInfo() const { return _updateInfo; } |
134 | |
135 | private: |
136 | QUrl _updateUrl; |
137 | int _state; |
138 | QNetworkAccessManager *_accessManager; |
139 | QTimer *_timeoutWatchdog; /** Timer to guard the timeout of an individual network request */ |
140 | UpdateInfo _updateInfo; |
141 | }; |
142 | |
143 | /** |
144 | * @brief Windows Updater Using NSIS |
145 | * @ingroup gui |
146 | */ |
147 | class NSISUpdater : public OCUpdater |
148 | { |
149 | Q_OBJECT |
150 | public: |
151 | enum UpdateState { NoUpdate = 0, |
152 | UpdateAvailable, |
153 | UpdateFailed }; |
154 | explicit NSISUpdater(const QUrl &url); |
155 | bool handleStartup() Q_DECL_OVERRIDE; |
156 | private slots: |
157 | void slotSetSeenVersion(); |
158 | void slotDownloadFinished(); |
159 | void slotWriteFile(); |
160 | |
161 | private: |
162 | NSISUpdater::UpdateState updateStateOnStart(); |
163 | void showDialog(const UpdateInfo &info); |
164 | void versionInfoArrived(const UpdateInfo &info) Q_DECL_OVERRIDE; |
165 | QScopedPointer<QTemporaryFile> _file; |
166 | QString _targetFile; |
167 | bool _showFallbackMessage; |
168 | }; |
169 | |
170 | /** |
171 | * @brief Updater that only implements notification for use in settings |
172 | * |
173 | * The implementation does not show popups |
174 | * |
175 | * @ingroup gui |
176 | */ |
177 | class PassiveUpdateNotifier : public OCUpdater |
178 | { |
179 | Q_OBJECT |
180 | public: |
181 | explicit PassiveUpdateNotifier(const QUrl &url); |
182 | bool handleStartup() Q_DECL_OVERRIDE { return false; } |
183 | void backgroundCheckForUpdate() Q_DECL_OVERRIDE; |
184 | |
185 | private: |
186 | void versionInfoArrived(const UpdateInfo &info) Q_DECL_OVERRIDE; |
187 | QByteArray _runningAppVersion; |
188 | }; |
189 | } |
190 | |
191 | #endif // OC_UPDATER |
192 | |