VirtualBox

Ignore:
Timestamp:
Mar 22, 2018 10:53:16 AM (7 years ago)
Author:
vboxsync
Message:

FE/Qt: bugref:9049: Full and heavy cleanup for UIUpdateManager.

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  
    55
    66/*
    7  * Copyright (C) 2006-2017 Oracle Corporation
     7 * Copyright (C) 2006-2018 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    2121
    2222/* Qt includes: */
    23 # include <QTimer>
    2423# include <QDir>
    2524# include <QPointer>
     25# include <QTimer>
    2626# include <QUrl>
    2727# include <QUrlQuery>
    2828
    2929/* 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"
    3238# include "UINetworkManager.h"
    3339# include "UINetworkCustomer.h"
    3440# 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"
    4343
    4444/* COM includes: */
     
    5353#endif /* !VBOX_WITH_PRECOMPILED_HEADERS */
    5454
    55 
    5655/* enable to test the version update check */
    5756//#define VBOX_NEW_VERSION_TEST "5.1.12_0 http://unknown.unknown.org/0.0.0/VirtualBox-0.0.0-0-unknown.pkg"
     
    6059class UIUpdateStep;
    6160
    62 /* Queue for processing update-steps: */
     61
     62/** QObject subclass providing GUI with
     63  * an object to manage queue of update-steps. */
    6364class UIUpdateQueue : public QObject
    6465{
     
    6768signals:
    6869
    69     /* Starting-signal of the queue: */
     70    /** Starts the queue. */
    7071    void sigStartQueue();
    7172
    72     /* Completion-signal of the queue: */
     73    /** Notifies about queue is finished. */
    7374    void sigQueueFinished();
    7475
    7576public:
    7677
    77     /* Constructor: */
     78    /** Constructs update queue passing @a pParent to the base-class. */
    7879    UIUpdateQueue(UIUpdateManager *pParent) : QObject(pParent) {}
    7980
    80     /* Starts a queue: */
     81    /** Starts the queue. */
    8182    void start() { emit sigStartQueue(); }
    8283
    8384private:
    8485
    85     /* Helpers: */
     86    /** Returns whether queue is empty. */
    8687    bool isEmpty() const { return m_pLastStep.isNull(); }
    87     UIUpdateStep* lastStep() const { return m_pLastStep; }
     88
     89    /** Defines the last queued @a pStep. */
    8890    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. */
    9195    QPointer<UIUpdateStep> m_pLastStep;
    9296
    93     /* Friend classes: */
     97    /** Allows step to manage queue. */
    9498    friend class UIUpdateStep;
    9599};
    96100
    97 /* Interface representing update-step: */
     101
     102/** Update step interface.
     103  * UINetworkCustomer extension which allows background network updates. */
    98104class UIUpdateStep : public UINetworkCustomer
    99105{
     
    102108signals:
    103109
    104     /* Completion-signal of the step: */
     110    /** Notifies about step is finished. */
    105111    void sigStepComplete();
    106112
    107113public:
    108114
    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
     118protected:
     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 */;
    134126
    135127protected slots:
    136128
    137     /* Starting-slot of the step: */
     129    /** Starts the step. */
    138130    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*) {}
    148131};
    149132
    150 /* Update-step to check for the new VirtualBox version: */
     133
     134/** Update step subclass to check for the new VirtualBox version. */
    151135class UIUpdateStepVirtualBox : public UIUpdateStep
    152136{
     
    155139public:
    156140
    157     /* Constructor: */
     141    /** Constructs update step passing @a pQueue and @a fForceCall to the base-class. */
    158142    UIUpdateStepVirtualBox(UIUpdateQueue *pQueue, bool fForceCall)
    159143        : UIUpdateStep(pQueue, fForceCall)
    160144        , m_url("https://update.virtualbox.org/query.php")
    161     {
    162     }
    163 
    164 private slots:
    165 
    166     /* Startup slot: */
    167     void sltStartStep() { prepareNetworkRequest(); }
     145    {}
     146
     147protected:
     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
     157protected slots:
     158
     159    /** Starts the step. */
     160    virtual void sltStartStep() /* override */;
    168161
    169162private:
    170163
    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. */
    323168    QUrl m_url;
    324169};
    325170
    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. */
    327173class UIUpdateStepVirtualBoxExtensionPack : public UIUpdateStep
    328174{
     
    331177public:
    332178
    333     /* Constructor: */
     179    /** Constructs update step passing @a pQueue and @a fForceCall to the base-class. */
    334180    UIUpdateStepVirtualBoxExtensionPack(UIUpdateQueue *pQueue, bool fForceCall)
    335181        : UIUpdateStep(pQueue, fForceCall)
    336     {
    337     }
     182    {}
     183
     184protected slots:
     185
     186    /** Starts the step. */
     187    virtual void sltStartStep() /* override */;
    338188
    339189private slots:
    340190
    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
     205UIUpdateStep::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
     231void UIUpdateStep::processNetworkReplyProgress(qint64, qint64)
     232{
     233}
     234
     235void UIUpdateStep::processNetworkReplyCanceled(UINetworkReply *)
     236{
     237}
     238
     239void UIUpdateStep::processNetworkReplyFinished(UINetworkReply *)
     240{
     241}
     242
     243
     244/*********************************************************************************************************************************
     245*   Class UIUpdateStepVirtualBox implementation.                                                                                 *
     246*********************************************************************************************************************************/
     247
     248void UIUpdateStepVirtualBox::processNetworkReplyCanceled(UINetworkReply *pReply)
     249{
     250    Q_UNUSED(pReply);
     251
     252    /* Notify about step completion: */
     253    emit sigStepComplete();
     254}
     255
     256void 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
     284const QString UIUpdateStepVirtualBox::description() const
     285{
     286    return tr("Checking for a new VirtualBox version...");
     287}
     288
     289void 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 */
     322QString 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
     400void 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
    346439        {
    347440            emit sigStepComplete();
    348441            return;
    349442        }
    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
     486void 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())
    353503        {
    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))
    381505            {
    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)
    446507                {
    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)));
    452510                }
    453511            }
    454512        }
    455513    }
    456 };
    457 
    458 /* UIUpdateManager stuff: */
    459 UIUpdateManager* UIUpdateManager::m_pInstance = 0;
     514}
     515
     516
     517/*********************************************************************************************************************************
     518*   Class UIUpdateManager implementation.                                                                                        *
     519*********************************************************************************************************************************/
    460520
    461521/* 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 }
     522UIUpdateManager* UIUpdateManager::s_pInstance = 0;
    488523
    489524UIUpdateManager::UIUpdateManager()
     
    493528{
    494529    /* Prepare instance: */
    495     if (m_pInstance != this)
    496         m_pInstance = this;
     530    if (s_pInstance != this)
     531        s_pInstance = this;
    497532
    498533    /* Configure queue: */
     
    509544{
    510545    /* Cleanup instance: */
    511     if (m_pInstance == this)
    512         m_pInstance = 0;
     546    if (s_pInstance == this)
     547        s_pInstance = 0;
     548}
     549
     550/* static */
     551void 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 */
     562void UIUpdateManager::shutdown()
     563{
     564    /* Ensure instance is created: */
     565    if (!s_pInstance)
     566        return;
     567
     568    /* Delete instance: */
     569    delete s_pInstance;
     570}
     571
     572void UIUpdateManager::sltForceCheck()
     573{
     574    /* Force call for new version check: */
     575    sltCheckIfUpdateIsNecessary(true /* force call */);
    513576}
    514577
  • trunk/src/VBox/Frontends/VirtualBox/src/net/UIUpdateManager.h

    r69500 r71447  
    55
    66/*
    7  * Copyright (C) 2006-2017 Oracle Corporation
     7 * Copyright (C) 2006-2018 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    1616 */
    1717
    18 #ifndef __UIUpdateManager_h__
    19 #define __UIUpdateManager_h__
     18#ifndef ___UIUpdateManager_h___
     19#define ___UIUpdateManager_h___
    2020
    21 /* Global includes: */
     21/* Qt includes: */
    2222#include <QObject>
    2323
     
    2525class UIUpdateQueue;
    2626
    27 /* Singleton to perform new version checks
    28  * and update of various VirtualBox parts. */
     27/** Singleton to perform new version checks
     28  * and update of various VirtualBox parts. */
    2929class UIUpdateManager : public QObject
    3030{
    3131    Q_OBJECT;
    3232
     33    /** Constructs Update Manager. */
     34    UIUpdateManager();
     35    /** Destructs Update Manager. */
     36    ~UIUpdateManager();
     37
    3338public:
    3439
    35     /* Schedule manager: */
     40    /** Schedules manager. */
    3641    static void schedule();
    37     /* Shutdown manager: */
     42    /** Shutdowns manager. */
    3843    static void shutdown();
    39     /* Manager instance: */
    40     static UIUpdateManager* instance() { return m_pInstance; }
     44    /** Returns manager instance. */
     45    static UIUpdateManager *instance() { return s_pInstance; }
    4146
    4247public slots:
    4348
    44     /* Force call for new version check: */
     49    /** Performs forced new version check. */
    4550    void sltForceCheck();
    4651
    4752private slots:
    4853
    49     /* Slot to check if update is necessary: */
     54    /** Checks whether update is necessary. */
    5055    void sltCheckIfUpdateIsNecessary(bool fForceCall = false);
    5156
    52     /* Slot to handle update finishing: */
     57    /** Handles update finishing. */
    5358    void sltHandleUpdateFinishing();
    5459
    5560private:
    5661
    57     /* Constructor/destructor: */
    58     UIUpdateManager();
    59     ~UIUpdateManager();
     62    /** Holds the singleton instance. */
     63    static UIUpdateManager *s_pInstance;
    6064
    61     /* Variables: */
    62     static UIUpdateManager* m_pInstance;
     65    /** Holds the update queue instance. */
    6366    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;
    6671};
     72
     73/** Singleton Update Manager 'official' name. */
    6774#define gUpdateManager UIUpdateManager::instance()
    6875
    69 #endif // __UIUpdateManager_h__
     76#endif /* !___UIUpdateManager_h___ */
    7077
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette