VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/src/networking/UIUpdateManager.cpp

Last change on this file was 103793, checked in by vboxsync, 2 months ago

FE/Qt: UICommon: Move versioning related functionality to UIVersion / UIVersionInfo; Rework user cases accordingly.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 12.5 KB
Line 
1/* $Id: UIUpdateManager.cpp 103793 2024-03-11 19:17:31Z vboxsync $ */
2/** @file
3 * VBox Qt GUI - UIUpdateManager class implementation.
4 */
5
6/*
7 * Copyright (C) 2006-2023 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28/* Qt includes: */
29#include <QDir>
30#include <QTimer>
31
32/* GUI includes: */
33#include "UIExecutionQueue.h"
34#include "UIExtension.h"
35#include "UIExtraDataManager.h"
36#include "UIGlobalSession.h"
37#include "UIMessageCenter.h"
38#include "UIModalWindowManager.h"
39#include "UINotificationCenter.h"
40#include "UIUpdateDefs.h"
41#include "UIUpdateManager.h"
42#include "UIVersion.h"
43#ifdef VBOX_WITH_UPDATE_REQUEST
44# include "UICommon.h"
45#endif
46
47/* COM includes: */
48#include "CExtPack.h"
49#include "CExtPackManager.h"
50
51
52/** UIExecutionStep extension to check for the new VirtualBox version. */
53class UIUpdateStepVirtualBox : public UIExecutionStep
54{
55 Q_OBJECT;
56
57public:
58
59 /** Constructs extension step.
60 * @param fForcedCall Brings whether this customer has forced privelegies. */
61 UIUpdateStepVirtualBox(bool fForcedCall);
62
63 /** Executes the step. */
64 virtual void exec() RT_OVERRIDE;
65
66private:
67
68 /** Holds whether this customer has forced privelegies. */
69 bool m_fForcedCall;
70
71};
72
73
74/** UIExecutionStep extension to check for the new VirtualBox Extension Pack version. */
75class UIUpdateStepVirtualBoxExtensionPack : public UIExecutionStep
76{
77 Q_OBJECT;
78
79public:
80
81 /** Constructs extension step. */
82 UIUpdateStepVirtualBoxExtensionPack();
83
84 /** Executes the step. */
85 virtual void exec() RT_OVERRIDE;
86
87private slots:
88
89 /** Handles downloaded Extension Pack.
90 * @param strSource Brings the EP source.
91 * @param strTarget Brings the EP target.
92 * @param strDigest Brings the EP digest. */
93 void sltHandleDownloadedExtensionPack(const QString &strSource,
94 const QString &strTarget,
95 const QString &strDigest);
96};
97
98
99/*********************************************************************************************************************************
100* Class UIUpdateStepVirtualBox implementation. *
101*********************************************************************************************************************************/
102
103UIUpdateStepVirtualBox::UIUpdateStepVirtualBox(bool fForcedCall)
104 : m_fForcedCall(fForcedCall)
105{
106 Q_UNUSED(fForcedCall);
107}
108
109void UIUpdateStepVirtualBox::exec()
110{
111 /* Check for new VirtualBox version: */
112 UINotificationProgressNewVersionChecker *pNotification =
113 new UINotificationProgressNewVersionChecker(m_fForcedCall);
114 connect(pNotification, &UINotificationProgressNewVersionChecker::sigProgressFinished,
115 this, &UIUpdateStepVirtualBox::sigStepFinished);
116 gpNotificationCenter->append(pNotification);
117}
118
119
120/*********************************************************************************************************************************
121* Class UIUpdateStepVirtualBoxExtensionPack implementation. *
122*********************************************************************************************************************************/
123
124UIUpdateStepVirtualBoxExtensionPack::UIUpdateStepVirtualBoxExtensionPack()
125{
126}
127
128void UIUpdateStepVirtualBoxExtensionPack::exec()
129{
130 /* Return if VirtualBox Manager issued a direct request to install EP: */
131 if (gUpdateManager->isEPInstallationRequested())
132 {
133 emit sigStepFinished();
134 return;
135 }
136
137 /* Return if already downloading: */
138 if (UINotificationDownloaderExtensionPack::exists())
139 {
140 gpNotificationCenter->invoke();
141 emit sigStepFinished();
142 return;
143 }
144
145 /* Get extension pack manager: */
146 CExtPackManager extPackManager = gpGlobalSession->virtualBox().GetExtensionPackManager();
147 /* Return if extension pack manager is NOT available: */
148 if (extPackManager.isNull())
149 {
150 emit sigStepFinished();
151 return;
152 }
153
154 /* Get extension pack: */
155 CExtPack extPack = extPackManager.Find(GUI_ExtPackName);
156 /* Return if extension pack is NOT installed: */
157 if (extPack.isNull())
158 {
159 emit sigStepFinished();
160 return;
161 }
162
163 /* Get VirtualBox version: */
164 UIVersion vboxVersion(UIVersionInfo::vboxVersionStringNormalized());
165 /* Get extension pack version: */
166 QString strExtPackVersion(extPack.GetVersion());
167
168 /* If this version being developed: */
169 if (vboxVersion.z() % 2 == 1)
170 {
171 /* If this version being developed on release branch (we use released one): */
172 if (vboxVersion.z() < 97)
173 vboxVersion.setZ(vboxVersion.z() - 1);
174 /* If this version being developed on trunk (we skip check at all): */
175 else
176 {
177 emit sigStepFinished();
178 return;
179 }
180 }
181
182 /* Get updated VirtualBox version: */
183 const QString strVBoxVersion = vboxVersion.toString();
184
185 /* Skip the check if the extension pack is equal to or newer than VBox. */
186 if (UIVersion(strExtPackVersion) >= vboxVersion)
187 {
188 emit sigStepFinished();
189 return;
190 }
191
192 QString strExtPackEdition(extPack.GetEdition());
193 if (strExtPackEdition.contains("ENTERPRISE"))
194 {
195 /* Inform the user that he should update the extension pack: */
196 UINotificationMessage::askUserToDownloadExtensionPack(GUI_ExtPackName, strExtPackVersion, strVBoxVersion);
197 /* Never try to download for ENTERPRISE version: */
198 emit sigStepFinished();
199 return;
200 }
201
202 /* Ask the user about extension pack downloading: */
203 if (!msgCenter().confirmLookingForExtensionPack(GUI_ExtPackName, strExtPackVersion))
204 {
205 emit sigStepFinished();
206 return;
207 }
208
209 /* Download extension pack: */
210 UINotificationDownloaderExtensionPack *pNotification = UINotificationDownloaderExtensionPack::instance(GUI_ExtPackName);
211 /* After downloading finished => propose to install the Extension Pack: */
212 connect(pNotification, &UINotificationDownloaderExtensionPack::sigExtensionPackDownloaded,
213 this, &UIUpdateStepVirtualBoxExtensionPack::sltHandleDownloadedExtensionPack);
214 /* Handle any signal as step-finished: */
215 connect(pNotification, &UINotificationDownloaderExtensionPack::sigProgressFailed,
216 this, &UIUpdateStepVirtualBoxExtensionPack::sigStepFinished);
217 connect(pNotification, &UINotificationDownloaderExtensionPack::sigProgressCanceled,
218 this, &UIUpdateStepVirtualBoxExtensionPack::sigStepFinished);
219 connect(pNotification, &UINotificationDownloaderExtensionPack::sigProgressFinished,
220 this, &UIUpdateStepVirtualBoxExtensionPack::sigStepFinished);
221 /* Append and start notification: */
222 gpNotificationCenter->append(pNotification);
223}
224
225void UIUpdateStepVirtualBoxExtensionPack::sltHandleDownloadedExtensionPack(const QString &strSource,
226 const QString &strTarget,
227 const QString &strDigest)
228{
229 /* Warn the user about extension pack was downloaded and saved, propose to install it: */
230 if (msgCenter().proposeInstallExtentionPack(GUI_ExtPackName, strSource, QDir::toNativeSeparators(strTarget)))
231 UIExtension::install(strTarget, strDigest, windowManager().mainWindowShown(), NULL);
232 /* Propose to delete the downloaded extension pack: */
233 if (msgCenter().proposeDeleteExtentionPack(QDir::toNativeSeparators(strTarget)))
234 {
235 /* Delete the downloaded extension pack: */
236 QFile::remove(QDir::toNativeSeparators(strTarget));
237 /* Get the list of old extension pack files in VirtualBox homefolder: */
238 const QStringList oldExtPackFiles = QDir(gpGlobalSession->homeFolder()).entryList(QStringList("*.vbox-extpack"),
239 QDir::Files);
240 /* Propose to delete old extension pack files if there are any: */
241 if (oldExtPackFiles.size())
242 {
243 if (msgCenter().proposeDeleteOldExtentionPacks(oldExtPackFiles))
244 {
245 foreach (const QString &strExtPackFile, oldExtPackFiles)
246 {
247 /* Delete the old extension pack file: */
248 QFile::remove(QDir::toNativeSeparators(QDir(gpGlobalSession->homeFolder()).filePath(strExtPackFile)));
249 }
250 }
251 }
252 }
253}
254
255
256/*********************************************************************************************************************************
257* Class UIUpdateManager implementation. *
258*********************************************************************************************************************************/
259
260/* static */
261UIUpdateManager* UIUpdateManager::s_pInstance = 0;
262
263UIUpdateManager::UIUpdateManager()
264 : m_pQueue(new UIExecutionQueue(this))
265 , m_fIsRunning(false)
266 , m_uTime(1 /* day */ * 24 /* hours */ * 60 /* minutes */ * 60 /* seconds */ * 1000 /* ms */)
267 , m_fEPInstallationRequested(false)
268{
269 /* Prepare instance: */
270 if (s_pInstance != this)
271 s_pInstance = this;
272
273 /* Configure queue: */
274 connect(m_pQueue, &UIExecutionQueue::sigQueueFinished, this, &UIUpdateManager::sltHandleUpdateFinishing);
275
276#ifdef VBOX_WITH_UPDATE_REQUEST
277 /* Ask updater to check for the first time, for Selector UI only: */
278 if (gEDataManager->applicationUpdateEnabled() && uiCommon().uiType() == UIType_ManagerUI)
279 QTimer::singleShot(0, this, SLOT(sltCheckIfUpdateIsNecessary()));
280#endif /* VBOX_WITH_UPDATE_REQUEST */
281}
282
283UIUpdateManager::~UIUpdateManager()
284{
285 /* Cleanup instance: */
286 if (s_pInstance == this)
287 s_pInstance = 0;
288}
289
290/* static */
291void UIUpdateManager::schedule()
292{
293 /* Ensure instance is NOT created: */
294 if (s_pInstance)
295 return;
296
297 /* Create instance: */
298 new UIUpdateManager;
299}
300
301/* static */
302void UIUpdateManager::shutdown()
303{
304 /* Ensure instance is created: */
305 if (!s_pInstance)
306 return;
307
308 /* Delete instance: */
309 delete s_pInstance;
310}
311
312void UIUpdateManager::sltForceCheck()
313{
314 /* Force call for new version check: */
315 sltCheckIfUpdateIsNecessary(true /* force call */);
316}
317
318void UIUpdateManager::sltCheckIfUpdateIsNecessary(bool fForcedCall /* = false */)
319{
320 /* If already running: */
321 if (m_fIsRunning)
322 {
323 /* And we have a force-call: */
324 if (fForcedCall)
325 gpNotificationCenter->invoke();
326 return;
327 }
328
329 /* Set as running: */
330 m_fIsRunning = true;
331
332 /* Load/decode curent update data: */
333 VBoxUpdateData currentData;
334 CHost comHost = gpGlobalSession->host();
335 currentData.load(comHost);
336
337 /* If update is really necessary: */
338 if (
339#ifdef VBOX_NEW_VERSION_TEST
340 true ||
341#endif
342 fForcedCall || currentData.isCheckRequired())
343 {
344 /* Prepare update queue: */
345 m_pQueue->enqueue(new UIUpdateStepVirtualBox(fForcedCall));
346 m_pQueue->enqueue(new UIUpdateStepVirtualBoxExtensionPack);
347 /* Start update queue: */
348 m_pQueue->start();
349 }
350 else
351 sltHandleUpdateFinishing();
352}
353
354void UIUpdateManager::sltHandleUpdateFinishing()
355{
356 /* Load/decode curent update data: */
357 VBoxUpdateData currentData;
358 CHost comHost = gpGlobalSession->host();
359 currentData.load(comHost);
360 /* Encode/save new update data: */
361 VBoxUpdateData newData(currentData.isCheckEnabled(), currentData.updatePeriod(), currentData.updateChannel());
362 newData.save(comHost);
363
364#ifdef VBOX_WITH_UPDATE_REQUEST
365 /* Ask updater to check for the next time: */
366 QTimer::singleShot(m_uTime, this, SLOT(sltCheckIfUpdateIsNecessary()));
367#endif /* VBOX_WITH_UPDATE_REQUEST */
368
369 /* Set as not running: */
370 m_fIsRunning = false;
371}
372
373
374#include "UIUpdateManager.moc"
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use