Changeset 71447 in vbox for trunk/src/VBox/Frontends/VirtualBox
- Timestamp:
- Mar 22, 2018 10:53:16 AM (7 years ago)
- Location:
- trunk/src/VBox/Frontends/VirtualBox/src/net
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VirtualBox/src/net/UIUpdateManager.cpp
r70850 r71447 5 5 6 6 /* 7 * Copyright (C) 2006-201 7Oracle Corporation7 * Copyright (C) 2006-2018 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 21 21 22 22 /* Qt includes: */ 23 # include <QTimer>24 23 # include <QDir> 25 24 # include <QPointer> 25 # include <QTimer> 26 26 # include <QUrl> 27 27 # include <QUrlQuery> 28 28 29 29 /* GUI includes: */ 30 # include "UIUpdateDefs.h" 31 # include "UIUpdateManager.h" 30 # include "QIProcess.h" 31 # include "VBoxGlobal.h" 32 # include "VBoxUtils.h" 33 # include "UIDownloaderExtensionPack.h" 34 # include "UIExtraDataManager.h" 35 # include "UIGlobalSettingsExtension.h" 36 # include "UIMessageCenter.h" 37 # include "UIModalWindowManager.h" 32 38 # include "UINetworkManager.h" 33 39 # include "UINetworkCustomer.h" 34 40 # include "UINetworkRequest.h" 35 # include "VBoxGlobal.h" 36 # include "UIMessageCenter.h" 37 # include "UIExtraDataManager.h" 38 # include "UIModalWindowManager.h" 39 # include "VBoxUtils.h" 40 # include "UIDownloaderExtensionPack.h" 41 # include "UIGlobalSettingsExtension.h" 42 # include "QIProcess.h" 41 # include "UIUpdateDefs.h" 42 # include "UIUpdateManager.h" 43 43 44 44 /* COM includes: */ … … 53 53 #endif /* !VBOX_WITH_PRECOMPILED_HEADERS */ 54 54 55 56 55 /* enable to test the version update check */ 57 56 //#define VBOX_NEW_VERSION_TEST "5.1.12_0 http://unknown.unknown.org/0.0.0/VirtualBox-0.0.0-0-unknown.pkg" … … 60 59 class UIUpdateStep; 61 60 62 /* Queue for processing update-steps: */ 61 62 /** QObject subclass providing GUI with 63 * an object to manage queue of update-steps. */ 63 64 class UIUpdateQueue : public QObject 64 65 { … … 67 68 signals: 68 69 69 /* Starting-signal of the queue:*/70 /** Starts the queue. */ 70 71 void sigStartQueue(); 71 72 72 /* Completion-signal of the queue:*/73 /** Notifies about queue is finished. */ 73 74 void sigQueueFinished(); 74 75 75 76 public: 76 77 77 /* Constructor:*/78 /** Constructs update queue passing @a pParent to the base-class. */ 78 79 UIUpdateQueue(UIUpdateManager *pParent) : QObject(pParent) {} 79 80 80 /* Starts a queue:*/81 /** Starts the queue. */ 81 82 void start() { emit sigStartQueue(); } 82 83 83 84 private: 84 85 85 /* Helpers:*/86 /** Returns whether queue is empty. */ 86 87 bool isEmpty() const { return m_pLastStep.isNull(); } 87 UIUpdateStep* lastStep() const { return m_pLastStep; } 88 89 /** Defines the last queued @a pStep. */ 88 90 void setLastStep(UIUpdateStep *pStep) { m_pLastStep = pStep; } 89 90 /* Variables: */ 91 /** Returns the last queued step. */ 92 UIUpdateStep *lastStep() const { return m_pLastStep; } 93 94 /** Holds the last queued step reference. */ 91 95 QPointer<UIUpdateStep> m_pLastStep; 92 96 93 /* Friend classes:*/97 /** Allows step to manage queue. */ 94 98 friend class UIUpdateStep; 95 99 }; 96 100 97 /* Interface representing update-step: */ 101 102 /** Update step interface. 103 * UINetworkCustomer extension which allows background network updates. */ 98 104 class UIUpdateStep : public UINetworkCustomer 99 105 { … … 102 108 signals: 103 109 104 /* Completion-signal of the step:*/110 /** Notifies about step is finished. */ 105 111 void sigStepComplete(); 106 112 107 113 public: 108 114 109 /* Constructor: */ 110 UIUpdateStep(UIUpdateQueue *pQueue, bool fForceCall) : UINetworkCustomer(pQueue, fForceCall) 111 { 112 /* If queue has no steps yet: */ 113 if (pQueue->isEmpty()) 114 { 115 /* Connect starting-signal of the queue to starting-slot of this step: */ 116 connect(pQueue, &UIUpdateQueue::sigStartQueue, this, &UIUpdateStep::sltStartStep, Qt::QueuedConnection); 117 } 118 /* If queue has at least one step already: */ 119 else 120 { 121 /* Reconnect completion-signal of the last-step from completion-signal of the queue to starting-slot of this step: */ 122 disconnect(pQueue->lastStep(), &UIUpdateStep::sigStepComplete, pQueue, &UIUpdateQueue::sigQueueFinished); 123 connect(pQueue->lastStep(), &UIUpdateStep::sigStepComplete, this, &UIUpdateStep::sltStartStep, Qt::QueuedConnection); 124 } 125 126 /* Connect completion-signal of this step to the completion-signal of the queue: */ 127 connect(this, &UIUpdateStep::sigStepComplete, pQueue, &UIUpdateQueue::sigQueueFinished, Qt::QueuedConnection); 128 /* Connect completion-signal of this step to the destruction-slot of this step: */ 129 connect(this, &UIUpdateStep::sigStepComplete, this, &UIUpdateStep::deleteLater, Qt::QueuedConnection); 130 131 /* Remember this step as the last one: */ 132 pQueue->setLastStep(this); 133 } 115 /** Constructs update step passing @a pQueue and @a fForceCall to the base-class. */ 116 UIUpdateStep(UIUpdateQueue *pQueue, bool fForceCall); 117 118 protected: 119 120 /** Handles network reply progress for @a iReceived amount of bytes among @a iTotal. */ 121 virtual void processNetworkReplyProgress(qint64 iReceived, qint64 iTotal) /* override */; 122 /** Handles network reply canceling for a passed @a pReply. */ 123 virtual void processNetworkReplyCanceled(UINetworkReply *pReply) /* override */; 124 /** Handles network reply finishing for a passed @a pReply. */ 125 virtual void processNetworkReplyFinished(UINetworkReply *pReply) /* override */; 134 126 135 127 protected slots: 136 128 137 /* Starting-slot of the step:*/129 /** Starts the step. */ 138 130 virtual void sltStartStep() = 0; 139 140 protected:141 142 /* Network pregress handler dummy: */143 void processNetworkReplyProgress(qint64, qint64) {}144 /* Network reply canceled handler dummy: */145 void processNetworkReplyCanceled(UINetworkReply*) {}146 /* Network reply canceled handler dummy: */147 void processNetworkReplyFinished(UINetworkReply*) {}148 131 }; 149 132 150 /* Update-step to check for the new VirtualBox version: */ 133 134 /** Update step subclass to check for the new VirtualBox version. */ 151 135 class UIUpdateStepVirtualBox : public UIUpdateStep 152 136 { … … 155 139 public: 156 140 157 /* Constructor:*/141 /** Constructs update step passing @a pQueue and @a fForceCall to the base-class. */ 158 142 UIUpdateStepVirtualBox(UIUpdateQueue *pQueue, bool fForceCall) 159 143 : UIUpdateStep(pQueue, fForceCall) 160 144 , m_url("https://update.virtualbox.org/query.php") 161 { 162 } 163 164 private slots: 165 166 /* Startup slot: */ 167 void sltStartStep() { prepareNetworkRequest(); } 145 {} 146 147 protected: 148 149 /** Handles network reply canceling for a passed @a pReply. */ 150 virtual void processNetworkReplyCanceled(UINetworkReply *pReply) /* override */; 151 /** Handles network reply finishing for a passed @a pReply. */ 152 virtual void processNetworkReplyFinished(UINetworkReply *pReply) /* override */; 153 154 /** Returns description of the current network operation. */ 155 virtual const QString description() const /* override */; 156 157 protected slots: 158 159 /** Starts the step. */ 160 virtual void sltStartStep() /* override */; 168 161 169 162 private: 170 163 171 /** Returns description of the current network operation. */ 172 virtual const QString description() const 173 { 174 return tr("Checking for a new VirtualBox version..."); 175 } 176 177 /* Prepare network request: */ 178 void prepareNetworkRequest() 179 { 180 /* Compose query: */ 181 QUrlQuery url; 182 url.addQueryItem("platform", vboxGlobal().virtualBox().GetPackageType()); 183 /* Check if branding is active: */ 184 if (vboxGlobal().brandingIsActive()) 185 { 186 /* Branding: Check whether we have a local branding file which tells us our version suffix "FOO" 187 (e.g. 3.06.54321_FOO) to identify this installation: */ 188 url.addQueryItem("version", QString("%1_%2_%3").arg(vboxGlobal().virtualBox().GetVersion()) 189 .arg(vboxGlobal().virtualBox().GetRevision()) 190 .arg(vboxGlobal().brandingGetKey("VerSuffix"))); 191 } 192 else 193 { 194 /* Use hard coded version set by VBOX_VERSION_STRING: */ 195 url.addQueryItem("version", QString("%1_%2").arg(vboxGlobal().virtualBox().GetVersion()) 196 .arg(vboxGlobal().virtualBox().GetRevision())); 197 } 198 url.addQueryItem("count", QString::number(gEDataManager->applicationUpdateCheckCounter())); 199 url.addQueryItem("branch", VBoxUpdateData(gEDataManager->applicationUpdateData()).branchName()); 200 QString strUserAgent(QString("VirtualBox %1 <%2>").arg(vboxGlobal().virtualBox().GetVersion()).arg(platformInfo())); 201 202 /* Send GET request: */ 203 UserDictionary headers; 204 headers["User-Agent"] = strUserAgent; 205 QUrl fullUrl(m_url); 206 fullUrl.setQuery(url); 207 createNetworkRequest(UINetworkRequestType_GET, QList<QUrl>() << fullUrl, headers); 208 } 209 210 /* Handle network reply canceled: */ 211 void processNetworkReplyCanceled(UINetworkReply* /* pReply */) 212 { 213 /* Notify about step completion: */ 214 emit sigStepComplete(); 215 } 216 217 /* Handle network reply: */ 218 void processNetworkReplyFinished(UINetworkReply *pReply) 219 { 220 /* Deserialize incoming data: */ 221 QString strResponseData(pReply->readAll()); 222 223 #ifdef VBOX_NEW_VERSION_TEST 224 strResponseData = VBOX_NEW_VERSION_TEST; 225 #endif 226 /* Newer version of necessary package found: */ 227 if (strResponseData.indexOf(QRegExp("^\\d+\\.\\d+\\.\\d+(_[0-9A-Z]+)? \\S+$")) == 0) 228 { 229 QStringList response = strResponseData.split(" ", QString::SkipEmptyParts); 230 msgCenter().showUpdateSuccess(response[0], response[1]); 231 } 232 /* No newer version of necessary package found: */ 233 else 234 { 235 if (isItForceCall()) 236 msgCenter().showUpdateNotFound(); 237 } 238 239 /* Increment update check counter: */ 240 gEDataManager->incrementApplicationUpdateCheckCounter(); 241 242 /* Notify about step completion: */ 243 emit sigStepComplete(); 244 } 245 246 /* Platform information getter: */ 247 static QString platformInfo() 248 { 249 /* Prepare platform report: */ 250 QString strPlatform; 251 252 #if defined (Q_OS_WIN) 253 strPlatform = "win"; 254 #elif defined (Q_OS_LINUX) 255 strPlatform = "linux"; 256 #elif defined (Q_OS_MACX) 257 strPlatform = "macosx"; 258 #elif defined (Q_OS_OS2) 259 strPlatform = "os2"; 260 #elif defined (Q_OS_FREEBSD) 261 strPlatform = "freebsd"; 262 #elif defined (Q_OS_SOLARIS) 263 strPlatform = "solaris"; 264 #else 265 strPlatform = "unknown"; 266 #endif 267 268 /* The format is <system>.<bitness>: */ 269 strPlatform += QString(".%1").arg(ARCH_BITS); 270 271 /* Add more system information: */ 272 int vrc; 273 #if defined(Q_OS_LINUX) 274 /* On linux we wish to send information about the distribution 275 and such like, so we try invoke a helper script that retrives 276 and formats it for us. */ 277 278 /* Get script path: */ 279 char szAppPrivPath[RTPATH_MAX]; 280 vrc = RTPathAppPrivateNoArch(szAppPrivPath, sizeof(szAppPrivPath)); AssertRC(vrc); 281 if (RT_SUCCESS(vrc)) 282 { 283 /* Run script: */ 284 QByteArray result = QIProcess::singleShot(QString(szAppPrivPath) + "/VBoxSysInfo.sh"); 285 if (!result.isNull()) 286 strPlatform += QString(" [%1]").arg(QString(result).trimmed()); 287 else 288 vrc = VERR_TRY_AGAIN; /* (take the fallback path) */ 289 } 290 if (RT_FAILURE(vrc)) 291 #endif 292 { 293 /* Use RTSystemQueryOSInfo: */ 294 char szTmp[256]; 295 QStringList components; 296 297 vrc = RTSystemQueryOSInfo(RTSYSOSINFO_PRODUCT, szTmp, sizeof(szTmp)); 298 if ((RT_SUCCESS(vrc) || vrc == VERR_BUFFER_OVERFLOW) && szTmp[0] != '\0') 299 components << QString("Product: %1").arg(szTmp); 300 301 vrc = RTSystemQueryOSInfo(RTSYSOSINFO_RELEASE, szTmp, sizeof(szTmp)); 302 if ((RT_SUCCESS(vrc) || vrc == VERR_BUFFER_OVERFLOW) && szTmp[0] != '\0') 303 components << QString("Release: %1").arg(szTmp); 304 305 vrc = RTSystemQueryOSInfo(RTSYSOSINFO_VERSION, szTmp, sizeof(szTmp)); 306 if ((RT_SUCCESS(vrc) || vrc == VERR_BUFFER_OVERFLOW) && szTmp[0] != '\0') 307 components << QString("Version: %1").arg(szTmp); 308 309 vrc = RTSystemQueryOSInfo(RTSYSOSINFO_SERVICE_PACK, szTmp, sizeof(szTmp)); 310 if ((RT_SUCCESS(vrc) || vrc == VERR_BUFFER_OVERFLOW) && szTmp[0] != '\0') 311 components << QString("SP: %1").arg(szTmp); 312 313 if (!components.isEmpty()) 314 strPlatform += QString(" [%1]").arg(components.join(" | ")); 315 } 316 317 return strPlatform; 318 } 319 320 private: 321 322 /* Variables: */ 164 /** Generates platform information. */ 165 static QString platformInfo(); 166 167 /** Holds the update step URL. */ 323 168 QUrl m_url; 324 169 }; 325 170 326 /* Update-step to check for the new VirtualBox Extension Pack version: */ 171 172 /** Update step subclass to check for the new VirtualBox Extension Pack version. */ 327 173 class UIUpdateStepVirtualBoxExtensionPack : public UIUpdateStep 328 174 { … … 331 177 public: 332 178 333 /* Constructor:*/179 /** Constructs update step passing @a pQueue and @a fForceCall to the base-class. */ 334 180 UIUpdateStepVirtualBoxExtensionPack(UIUpdateQueue *pQueue, bool fForceCall) 335 181 : UIUpdateStep(pQueue, fForceCall) 336 { 337 } 182 {} 183 184 protected slots: 185 186 /** Starts the step. */ 187 virtual void sltStartStep() /* override */; 338 188 339 189 private slots: 340 190 341 /* Startup slot: */ 342 void sltStartStep() 343 { 344 /* Return if Selector UI has a direct request to install EP: */ 345 if (vboxGlobal().isEPInstallationRequested()) 191 /** Handles downloaded Extension Pack. 192 * @param strSource Brings the EP source. 193 * @param strTarget Brings the EP target. 194 * @param strDigest Brings the EP digest. */ 195 void sltHandleDownloadedExtensionPack(const QString &strSource, 196 const QString &strTarget, 197 const QString &strDigest); 198 }; 199 200 201 /********************************************************************************************************************************* 202 * Class UIUpdateStep implementation. * 203 *********************************************************************************************************************************/ 204 205 UIUpdateStep::UIUpdateStep(UIUpdateQueue *pQueue, bool fForceCall) 206 : UINetworkCustomer(pQueue, fForceCall) 207 { 208 /* If queue has no steps yet: */ 209 if (pQueue->isEmpty()) 210 { 211 /* Connect starting-signal of the queue to starting-slot of this step: */ 212 connect(pQueue, &UIUpdateQueue::sigStartQueue, this, &UIUpdateStep::sltStartStep, Qt::QueuedConnection); 213 } 214 /* If queue has at least one step already: */ 215 else 216 { 217 /* Reconnect completion-signal of the last-step from completion-signal of the queue to starting-slot of this step: */ 218 disconnect(pQueue->lastStep(), &UIUpdateStep::sigStepComplete, pQueue, &UIUpdateQueue::sigQueueFinished); 219 connect(pQueue->lastStep(), &UIUpdateStep::sigStepComplete, this, &UIUpdateStep::sltStartStep, Qt::QueuedConnection); 220 } 221 222 /* Connect completion-signal of this step to the completion-signal of the queue: */ 223 connect(this, &UIUpdateStep::sigStepComplete, pQueue, &UIUpdateQueue::sigQueueFinished, Qt::QueuedConnection); 224 /* Connect completion-signal of this step to the destruction-slot of this step: */ 225 connect(this, &UIUpdateStep::sigStepComplete, this, &UIUpdateStep::deleteLater, Qt::QueuedConnection); 226 227 /* Remember this step as the last one: */ 228 pQueue->setLastStep(this); 229 } 230 231 void UIUpdateStep::processNetworkReplyProgress(qint64, qint64) 232 { 233 } 234 235 void UIUpdateStep::processNetworkReplyCanceled(UINetworkReply *) 236 { 237 } 238 239 void UIUpdateStep::processNetworkReplyFinished(UINetworkReply *) 240 { 241 } 242 243 244 /********************************************************************************************************************************* 245 * Class UIUpdateStepVirtualBox implementation. * 246 *********************************************************************************************************************************/ 247 248 void UIUpdateStepVirtualBox::processNetworkReplyCanceled(UINetworkReply *pReply) 249 { 250 Q_UNUSED(pReply); 251 252 /* Notify about step completion: */ 253 emit sigStepComplete(); 254 } 255 256 void UIUpdateStepVirtualBox::processNetworkReplyFinished(UINetworkReply *pReply) 257 { 258 /* Deserialize incoming data: */ 259 QString strResponseData(pReply->readAll()); 260 261 #ifdef VBOX_NEW_VERSION_TEST 262 strResponseData = VBOX_NEW_VERSION_TEST; 263 #endif 264 /* Newer version of necessary package found: */ 265 if (strResponseData.indexOf(QRegExp("^\\d+\\.\\d+\\.\\d+(_[0-9A-Z]+)? \\S+$")) == 0) 266 { 267 QStringList response = strResponseData.split(" ", QString::SkipEmptyParts); 268 msgCenter().showUpdateSuccess(response[0], response[1]); 269 } 270 /* No newer version of necessary package found: */ 271 else 272 { 273 if (isItForceCall()) 274 msgCenter().showUpdateNotFound(); 275 } 276 277 /* Increment update check counter: */ 278 gEDataManager->incrementApplicationUpdateCheckCounter(); 279 280 /* Notify about step completion: */ 281 emit sigStepComplete(); 282 } 283 284 const QString UIUpdateStepVirtualBox::description() const 285 { 286 return tr("Checking for a new VirtualBox version..."); 287 } 288 289 void UIUpdateStepVirtualBox::sltStartStep() 290 { 291 /* Compose query: */ 292 QUrlQuery url; 293 url.addQueryItem("platform", vboxGlobal().virtualBox().GetPackageType()); 294 /* Check if branding is active: */ 295 if (vboxGlobal().brandingIsActive()) 296 { 297 /* Branding: Check whether we have a local branding file which tells us our version suffix "FOO" 298 (e.g. 3.06.54321_FOO) to identify this installation: */ 299 url.addQueryItem("version", QString("%1_%2_%3").arg(vboxGlobal().virtualBox().GetVersion()) 300 .arg(vboxGlobal().virtualBox().GetRevision()) 301 .arg(vboxGlobal().brandingGetKey("VerSuffix"))); 302 } 303 else 304 { 305 /* Use hard coded version set by VBOX_VERSION_STRING: */ 306 url.addQueryItem("version", QString("%1_%2").arg(vboxGlobal().virtualBox().GetVersion()) 307 .arg(vboxGlobal().virtualBox().GetRevision())); 308 } 309 url.addQueryItem("count", QString::number(gEDataManager->applicationUpdateCheckCounter())); 310 url.addQueryItem("branch", VBoxUpdateData(gEDataManager->applicationUpdateData()).branchName()); 311 QString strUserAgent(QString("VirtualBox %1 <%2>").arg(vboxGlobal().virtualBox().GetVersion()).arg(platformInfo())); 312 313 /* Send GET request: */ 314 UserDictionary headers; 315 headers["User-Agent"] = strUserAgent; 316 QUrl fullUrl(m_url); 317 fullUrl.setQuery(url); 318 createNetworkRequest(UINetworkRequestType_GET, QList<QUrl>() << fullUrl, headers); 319 } 320 321 /* static */ 322 QString UIUpdateStepVirtualBox::platformInfo() 323 { 324 /* Prepare platform report: */ 325 QString strPlatform; 326 327 #if defined (Q_OS_WIN) 328 strPlatform = "win"; 329 #elif defined (Q_OS_LINUX) 330 strPlatform = "linux"; 331 #elif defined (Q_OS_MACX) 332 strPlatform = "macosx"; 333 #elif defined (Q_OS_OS2) 334 strPlatform = "os2"; 335 #elif defined (Q_OS_FREEBSD) 336 strPlatform = "freebsd"; 337 #elif defined (Q_OS_SOLARIS) 338 strPlatform = "solaris"; 339 #else 340 strPlatform = "unknown"; 341 #endif 342 343 /* The format is <system>.<bitness>: */ 344 strPlatform += QString(".%1").arg(ARCH_BITS); 345 346 /* Add more system information: */ 347 int vrc; 348 #ifdef Q_OS_LINUX 349 // WORKAROUND: 350 // On Linux we try to generate information using script first of all.. 351 352 /* Get script path: */ 353 char szAppPrivPath[RTPATH_MAX]; 354 vrc = RTPathAppPrivateNoArch(szAppPrivPath, sizeof(szAppPrivPath)); 355 AssertRC(vrc); 356 if (RT_SUCCESS(vrc)) 357 { 358 /* Run script: */ 359 QByteArray result = QIProcess::singleShot(QString(szAppPrivPath) + "/VBoxSysInfo.sh"); 360 if (!result.isNull()) 361 strPlatform += QString(" [%1]").arg(QString(result).trimmed()); 362 else 363 vrc = VERR_TRY_AGAIN; /* (take the fallback path) */ 364 } 365 if (RT_FAILURE(vrc)) 366 #endif /* Q_OS_LINUX */ 367 { 368 /* Use RTSystemQueryOSInfo: */ 369 char szTmp[256]; 370 QStringList components; 371 372 vrc = RTSystemQueryOSInfo(RTSYSOSINFO_PRODUCT, szTmp, sizeof(szTmp)); 373 if ((RT_SUCCESS(vrc) || vrc == VERR_BUFFER_OVERFLOW) && szTmp[0] != '\0') 374 components << QString("Product: %1").arg(szTmp); 375 376 vrc = RTSystemQueryOSInfo(RTSYSOSINFO_RELEASE, szTmp, sizeof(szTmp)); 377 if ((RT_SUCCESS(vrc) || vrc == VERR_BUFFER_OVERFLOW) && szTmp[0] != '\0') 378 components << QString("Release: %1").arg(szTmp); 379 380 vrc = RTSystemQueryOSInfo(RTSYSOSINFO_VERSION, szTmp, sizeof(szTmp)); 381 if ((RT_SUCCESS(vrc) || vrc == VERR_BUFFER_OVERFLOW) && szTmp[0] != '\0') 382 components << QString("Version: %1").arg(szTmp); 383 384 vrc = RTSystemQueryOSInfo(RTSYSOSINFO_SERVICE_PACK, szTmp, sizeof(szTmp)); 385 if ((RT_SUCCESS(vrc) || vrc == VERR_BUFFER_OVERFLOW) && szTmp[0] != '\0') 386 components << QString("SP: %1").arg(szTmp); 387 388 if (!components.isEmpty()) 389 strPlatform += QString(" [%1]").arg(components.join(" | ")); 390 } 391 392 return strPlatform; 393 } 394 395 396 /********************************************************************************************************************************* 397 * Class UIUpdateStepVirtualBoxExtensionPack implementation. * 398 *********************************************************************************************************************************/ 399 400 void UIUpdateStepVirtualBoxExtensionPack::sltStartStep() 401 { 402 /* Return if Selector UI has a direct request to install EP: */ 403 if (vboxGlobal().isEPInstallationRequested()) 404 { 405 emit sigStepComplete(); 406 return; 407 } 408 409 /* Return if already downloading: */ 410 if (UIDownloaderExtensionPack::current()) 411 { 412 emit sigStepComplete(); 413 return; 414 } 415 416 /* Get extension pack: */ 417 CExtPack extPack = vboxGlobal().virtualBox().GetExtensionPackManager().Find(GUI_ExtPackName); 418 /* Return if extension pack is NOT installed: */ 419 if (extPack.isNull()) 420 { 421 emit sigStepComplete(); 422 return; 423 } 424 425 /* Get VirtualBox version: */ 426 UIVersion vboxVersion(vboxGlobal().vboxVersionStringNormalized()); 427 /* Get extension pack version: */ 428 QString strExtPackVersion(extPack.GetVersion()); 429 QByteArray abExtPackVersion = strExtPackVersion.toUtf8(); 430 431 /* If this version being developed: */ 432 if (vboxVersion.z() % 2 == 1) 433 { 434 /* If this version being developed on release branch (we use released one): */ 435 if (vboxVersion.z() < 97) 436 vboxVersion.setZ(vboxVersion.z() - 1); 437 /* If this version being developed on trunk (we skip check at all): */ 438 else 346 439 { 347 440 emit sigStepComplete(); 348 441 return; 349 442 } 350 351 /* Return if already downloading: */ 352 if (UIDownloaderExtensionPack::current()) 443 } 444 445 /* Get updated VirtualBox version: */ 446 const QString strVBoxVersion = vboxVersion.toString(); 447 448 /* Skip the check if the extension pack is equal to or newer than VBox. 449 * Note! Use RTStrVersionCompare for the comparison here as it takes the 450 * beta/alpha/preview/whatever tags into consideration when comparing versions. */ 451 if (RTStrVersionCompare(abExtPackVersion.constData(), strVBoxVersion.toUtf8().constData()) >= 0) 452 { 453 emit sigStepComplete(); 454 return; 455 } 456 457 QString strExtPackEdition(extPack.GetEdition()); 458 if (strExtPackEdition.contains("ENTERPRISE")) 459 { 460 /* Inform the user that he should update the extension pack: */ 461 msgCenter().askUserToDownloadExtensionPack(GUI_ExtPackName, strExtPackVersion, strVBoxVersion); 462 /* Never try to download for ENTERPRISE version: */ 463 emit sigStepComplete(); 464 return; 465 } 466 467 /* Ask the user about extension pack downloading: */ 468 if (!msgCenter().warAboutOutdatedExtensionPack(GUI_ExtPackName, strExtPackVersion)) 469 { 470 emit sigStepComplete(); 471 return; 472 } 473 474 /* Create and configure the Extension Pack downloader: */ 475 UIDownloaderExtensionPack *pDl = UIDownloaderExtensionPack::create(); 476 /* After downloading finished => propose to install the Extension Pack: */ 477 connect(pDl, &UIDownloaderExtensionPack::sigDownloadFinished, 478 this, &UIUpdateStepVirtualBoxExtensionPack::sltHandleDownloadedExtensionPack); 479 /* Also, destroyed downloader is a signal to finish the step: */ 480 connect(pDl, &UIDownloaderExtensionPack::destroyed, 481 this, &UIUpdateStepVirtualBoxExtensionPack::sigStepComplete); 482 /* Start downloading: */ 483 pDl->start(); 484 } 485 486 void UIUpdateStepVirtualBoxExtensionPack::sltHandleDownloadedExtensionPack(const QString &strSource, 487 const QString &strTarget, 488 const QString &strDigest) 489 { 490 /* Warn the user about extension pack was downloaded and saved, propose to install it: */ 491 if (msgCenter().proposeInstallExtentionPack(GUI_ExtPackName, strSource, QDir::toNativeSeparators(strTarget))) 492 UIGlobalSettingsExtension::doInstallation(strTarget, strDigest, windowManager().networkManagerOrMainWindowShown(), 0); 493 /* Propose to delete the downloaded extension pack: */ 494 if (msgCenter().proposeDeleteExtentionPack(QDir::toNativeSeparators(strTarget))) 495 { 496 /* Delete the downloaded extension pack: */ 497 QFile::remove(QDir::toNativeSeparators(strTarget)); 498 /* Get the list of old extension pack files in VirtualBox homefolder: */ 499 const QStringList oldExtPackFiles = QDir(vboxGlobal().homeFolder()).entryList(QStringList("*.vbox-extpack"), 500 QDir::Files); 501 /* Propose to delete old extension pack files if there are any: */ 502 if (oldExtPackFiles.size()) 353 503 { 354 emit sigStepComplete(); 355 return; 356 } 357 358 /* Get extension pack: */ 359 CExtPack extPack = vboxGlobal().virtualBox().GetExtensionPackManager().Find(GUI_ExtPackName); 360 /* Return if extension pack is NOT installed: */ 361 if (extPack.isNull()) 362 { 363 emit sigStepComplete(); 364 return; 365 } 366 367 /* Get VirtualBox version: */ 368 UIVersion vboxVersion(vboxGlobal().vboxVersionStringNormalized()); 369 /* Get extension pack version: */ 370 QString strExtPackVersion(extPack.GetVersion()); 371 QByteArray abExtPackVersion = strExtPackVersion.toUtf8(); 372 373 /* If this version being developed: */ 374 if (vboxVersion.z() % 2 == 1) 375 { 376 /* If this version being developed on release branch (we use released one): */ 377 if (vboxVersion.z() < 97) 378 vboxVersion.setZ(vboxVersion.z() - 1); 379 /* If this version being developed on trunk (we skip check at all): */ 380 else 504 if (msgCenter().proposeDeleteOldExtentionPacks(oldExtPackFiles)) 381 505 { 382 emit sigStepComplete(); 383 return; 384 } 385 } 386 387 /* Get updated VirtualBox version: */ 388 const QString strVBoxVersion = vboxVersion.toString(); 389 390 /* Skip the check if the extension pack is equal to or newer than VBox. 391 * Note! Use RTStrVersionCompare for the comparison here as it takes the 392 * beta/alpha/preview/whatever tags into consideration when comparing versions. */ 393 if (RTStrVersionCompare(abExtPackVersion.constData(), strVBoxVersion.toUtf8().constData()) >= 0) 394 { 395 emit sigStepComplete(); 396 return; 397 } 398 399 QString strExtPackEdition(extPack.GetEdition()); 400 if (strExtPackEdition.contains("ENTERPRISE")) 401 { 402 /* Inform the user that he should update the extension pack: */ 403 msgCenter().askUserToDownloadExtensionPack(GUI_ExtPackName, strExtPackVersion, strVBoxVersion); 404 /* Never try to download for ENTERPRISE version: */ 405 emit sigStepComplete(); 406 return; 407 } 408 409 /* Ask the user about extension pack downloading: */ 410 if (!msgCenter().warAboutOutdatedExtensionPack(GUI_ExtPackName, strExtPackVersion)) 411 { 412 emit sigStepComplete(); 413 return; 414 } 415 416 /* Create and configure the Extension Pack downloader: */ 417 UIDownloaderExtensionPack *pDl = UIDownloaderExtensionPack::create(); 418 /* After downloading finished => propose to install the Extension Pack: */ 419 connect(pDl, &UIDownloaderExtensionPack::sigDownloadFinished, 420 this, &UIUpdateStepVirtualBoxExtensionPack::sltHandleDownloadedExtensionPack); 421 /* Also, destroyed downloader is a signal to finish the step: */ 422 connect(pDl, &UIDownloaderExtensionPack::destroyed, 423 this, &UIUpdateStepVirtualBoxExtensionPack::sigStepComplete); 424 /* Start downloading: */ 425 pDl->start(); 426 } 427 428 /* Finishing slot: */ 429 void sltHandleDownloadedExtensionPack(const QString &strSource, const QString &strTarget, QString strDigest) 430 { 431 /* Warn the user about extension pack was downloaded and saved, propose to install it: */ 432 if (msgCenter().proposeInstallExtentionPack(GUI_ExtPackName, strSource, QDir::toNativeSeparators(strTarget))) 433 UIGlobalSettingsExtension::doInstallation(strTarget, strDigest, windowManager().networkManagerOrMainWindowShown(), NULL); 434 /* Propose to delete the downloaded extension pack: */ 435 if (msgCenter().proposeDeleteExtentionPack(QDir::toNativeSeparators(strTarget))) 436 { 437 /* Delete the downloaded extension pack: */ 438 QFile::remove(QDir::toNativeSeparators(strTarget)); 439 /* Get the list of old extension pack files in VirtualBox homefolder: */ 440 const QStringList oldExtPackFiles = QDir(vboxGlobal().homeFolder()).entryList(QStringList("*.vbox-extpack"), 441 QDir::Files); 442 /* Propose to delete old extension pack files if there are any: */ 443 if (oldExtPackFiles.size()) 444 { 445 if (msgCenter().proposeDeleteOldExtentionPacks(oldExtPackFiles)) 506 foreach (const QString &strExtPackFile, oldExtPackFiles) 446 507 { 447 foreach (const QString &strExtPackFile, oldExtPackFiles) 448 { 449 /* Delete the old extension pack file: */ 450 QFile::remove(QDir::toNativeSeparators(QDir(vboxGlobal().homeFolder()).filePath(strExtPackFile))); 451 } 508 /* Delete the old extension pack file: */ 509 QFile::remove(QDir::toNativeSeparators(QDir(vboxGlobal().homeFolder()).filePath(strExtPackFile))); 452 510 } 453 511 } 454 512 } 455 513 } 456 }; 457 458 /* UIUpdateManager stuff: */ 459 UIUpdateManager* UIUpdateManager::m_pInstance = 0; 514 } 515 516 517 /********************************************************************************************************************************* 518 * Class UIUpdateManager implementation. * 519 *********************************************************************************************************************************/ 460 520 461 521 /* static */ 462 void UIUpdateManager::schedule() 463 { 464 /* Ensure instance is NOT created: */ 465 if (m_pInstance) 466 return; 467 468 /* Create instance: */ 469 new UIUpdateManager; 470 } 471 472 /* static */ 473 void UIUpdateManager::shutdown() 474 { 475 /* Ensure instance is created: */ 476 if (!m_pInstance) 477 return; 478 479 /* Delete instance: */ 480 delete m_pInstance; 481 } 482 483 void UIUpdateManager::sltForceCheck() 484 { 485 /* Force call for new version check: */ 486 sltCheckIfUpdateIsNecessary(true /* force call */); 487 } 522 UIUpdateManager* UIUpdateManager::s_pInstance = 0; 488 523 489 524 UIUpdateManager::UIUpdateManager() … … 493 528 { 494 529 /* Prepare instance: */ 495 if ( m_pInstance != this)496 m_pInstance = this;530 if (s_pInstance != this) 531 s_pInstance = this; 497 532 498 533 /* Configure queue: */ … … 509 544 { 510 545 /* Cleanup instance: */ 511 if (m_pInstance == this) 512 m_pInstance = 0; 546 if (s_pInstance == this) 547 s_pInstance = 0; 548 } 549 550 /* static */ 551 void UIUpdateManager::schedule() 552 { 553 /* Ensure instance is NOT created: */ 554 if (s_pInstance) 555 return; 556 557 /* Create instance: */ 558 new UIUpdateManager; 559 } 560 561 /* static */ 562 void UIUpdateManager::shutdown() 563 { 564 /* Ensure instance is created: */ 565 if (!s_pInstance) 566 return; 567 568 /* Delete instance: */ 569 delete s_pInstance; 570 } 571 572 void UIUpdateManager::sltForceCheck() 573 { 574 /* Force call for new version check: */ 575 sltCheckIfUpdateIsNecessary(true /* force call */); 513 576 } 514 577 -
trunk/src/VBox/Frontends/VirtualBox/src/net/UIUpdateManager.h
r69500 r71447 5 5 6 6 /* 7 * Copyright (C) 2006-201 7Oracle Corporation7 * Copyright (C) 2006-2018 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 16 16 */ 17 17 18 #ifndef __ UIUpdateManager_h__19 #define __ UIUpdateManager_h__18 #ifndef ___UIUpdateManager_h___ 19 #define ___UIUpdateManager_h___ 20 20 21 /* Globalincludes: */21 /* Qt includes: */ 22 22 #include <QObject> 23 23 … … 25 25 class UIUpdateQueue; 26 26 27 /* Singleton to perform new version checks28 * and update of various VirtualBox parts. */27 /** Singleton to perform new version checks 28 * and update of various VirtualBox parts. */ 29 29 class UIUpdateManager : public QObject 30 30 { 31 31 Q_OBJECT; 32 32 33 /** Constructs Update Manager. */ 34 UIUpdateManager(); 35 /** Destructs Update Manager. */ 36 ~UIUpdateManager(); 37 33 38 public: 34 39 35 /* Schedule manager:*/40 /** Schedules manager. */ 36 41 static void schedule(); 37 /* Shutdown manager:*/42 /** Shutdowns manager. */ 38 43 static void shutdown(); 39 /* Manager instance:*/40 static UIUpdateManager * instance() { return m_pInstance; }44 /** Returns manager instance. */ 45 static UIUpdateManager *instance() { return s_pInstance; } 41 46 42 47 public slots: 43 48 44 /* Force call for new version check:*/49 /** Performs forced new version check. */ 45 50 void sltForceCheck(); 46 51 47 52 private slots: 48 53 49 /* Slot to check if update is necessary:*/54 /** Checks whether update is necessary. */ 50 55 void sltCheckIfUpdateIsNecessary(bool fForceCall = false); 51 56 52 /* Slot to handle update finishing:*/57 /** Handles update finishing. */ 53 58 void sltHandleUpdateFinishing(); 54 59 55 60 private: 56 61 57 /* Constructor/destructor: */ 58 UIUpdateManager(); 59 ~UIUpdateManager(); 62 /** Holds the singleton instance. */ 63 static UIUpdateManager *s_pInstance; 60 64 61 /* Variables: */ 62 static UIUpdateManager* m_pInstance; 65 /** Holds the update queue instance. */ 63 66 UIUpdateQueue *m_pQueue; 64 bool m_fIsRunning; 65 quint64 m_uTime; 67 /** Holds whether Update Manager is running. */ 68 bool m_fIsRunning; 69 /** Holds the refresh period. */ 70 quint64 m_uTime; 66 71 }; 72 73 /** Singleton Update Manager 'official' name. */ 67 74 #define gUpdateManager UIUpdateManager::instance() 68 75 69 #endif / / __UIUpdateManager_h__76 #endif /* !___UIUpdateManager_h___ */ 70 77
Note:
See TracChangeset
for help on using the changeset viewer.