UIUpdateManager.cpp revision 8bf8c6b1914c9e7e60b1547888400668f1774497
/* $Id$ */
/** @file
*
* VBox frontends: Qt4 GUI ("VirtualBox"):
* UIUpdateManager class implementation
*/
/*
* Copyright (C) 2006-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
/* Qt includes: */
#include <QNetworkReply>
#include <QTimer>
#include <QDir>
#include <QPointer>
/* GUI includes: */
#include "UIUpdateDefs.h"
#include "UIUpdateManager.h"
#include "UINetworkManager.h"
#include "UINetworkCustomer.h"
#include "VBoxGlobal.h"
#include "UIMessageCenter.h"
#include "VBoxUtils.h"
#include "UIDownloaderExtensionPack.h"
#include "UIGlobalSettingsExtension.h"
#include "VBoxDefs.h"
/* COM includes: */
#include "CExtPack.h"
#include "CExtPackManager.h"
/* Forward declarations: */
class UIUpdateStep;
/* Using declarations: */
using namespace VBoxGlobalDefs;
/* Queue for processing update-steps: */
class UIUpdateQueue : public QObject
{
/* Starting-signal of the queue: */
void sigStartQueue();
/* Completion-signal of the queue: */
void sigQueueFinished();
public:
/* Constructor: */
/* Starts a queue: */
private:
/* Helpers: */
/* Variables: */
/* Friend classes: */
friend class UIUpdateStep;
};
/* Interface representing update-step: */
class UIUpdateStep : public UINetworkCustomer
{
/* Completion-signal of the step: */
void sigStepComplete();
public:
/* Constructor: */
{
/* If queue has no steps yet: */
{
/* Connect starting-signal of the queue to starting-slot of this step: */
}
/* If queue has at least one step already: */
else
{
/* Reconnect completion-signal of the last-step from completion-signal of the queue to starting-slot of this step: */
connect(pQueue->lastStep(), SIGNAL(sigStepComplete()), this, SLOT(sltStartStep()), Qt::QueuedConnection);
}
/* Connect completion-signal of this step to the completion-signal of the queue: */
/* Connect completion-signal of this step to the destruction-slot of this step: */
/* Remember this step as the last one: */
pQueue->setLastStep(this);
}
protected slots:
/* Starting-slot of the step: */
virtual void sltStartStep() = 0;
protected:
/* Network pregress handler dummy: */
/* Network reply canceled handler dummy: */
void processNetworkReplyCanceled(QNetworkReply*) {}
/* Network reply canceled handler dummy: */
void processNetworkReplyFinished(QNetworkReply*) {}
};
/* Update-step to check for the new VirtualBox version: */
class UIUpdateStepVirtualBox : public UIUpdateStep
{
public:
/* Constructor: */
{
}
private slots:
/* Startup slot: */
void sltStartStep() { prepareNetworkRequest(); }
private:
/* Prepare network request: */
void prepareNetworkRequest()
{
/* Calculate the count of checks left: */
int cCount = 1;
{
bool ok = false;
}
/* Compose query: */
/* Check if branding is active: */
if (vboxGlobal().brandingIsActive())
{
/* Branding: Check whether we have a local branding file which tells us our version suffix "FOO"
(e.g. 3.06.54321_FOO) to identify this installation: */
}
else
{
/* Use hard coded version set by VBOX_VERSION_STRING: */
}
url.addQueryItem("branch", VBoxUpdateData(vboxGlobal().virtualBox().GetExtraData(VBoxDefs::GUI_UpdateDate)).branchName());
QString strUserAgent(QString("VirtualBox %1 <%2>").arg(vboxGlobal().virtualBox().GetVersion()).arg(vboxGlobal().platformInfo()));
/* Send GET request: */
createNetworkRequest(request, UINetworkRequestType_GET, tr("Checking for a new VirtualBox version..."));
}
/* Handle network reply canceled: */
{
/* Notify about step completion: */
}
/* Handle network reply: */
{
/* Deserialize incoming data: */
/* Newer version of necessary package found: */
{
}
/* No newer version of necessary package found: */
else
{
if (isItForceCall())
}
/* Save left count of checks: */
int cCount = 1;
{
bool ok = false;
}
vboxGlobal().virtualBox().SetExtraData(VBoxDefs::GUI_UpdateCheckCount, QString("%1").arg((qulonglong)cCount + 1));
/* Notify about step completion: */
}
private:
/* Variables: */
};
/* Update-step to check for the new VirtualBox Extension Pack version: */
class UIUpdateStepVirtualBoxExtensionPack : public UIUpdateStep
{
public:
/* Constructor: */
{
}
private slots:
/* Startup slot: */
void sltStartStep()
{
/* Return if already downloading: */
if (UIDownloaderExtensionPack::current())
{
return;
}
/* Get extension pack: */
/* Return if extension pack is NOT installed: */
{
return;
}
/* Get VirtualBox version: */
/* Get extension pack version: */
/* Skip the check in unstable VBox version and if the extension pack
is equal to or newer than VBox.
Note! Use RTStrVersionCompare for the comparison here as it takes
comparing versions. */
if ( vboxVersion.z() % 2 != 0
{
return;
}
{
/* Inform the user that he should update the extension pack: */
/* Never try to download for ENTERPRISE version: */
return;
}
/* Ask the user about extension pack downloading: */
{
return;
}
/* Create and configure the Extension Pack downloader: */
/* After downloading finished => propose to install the Extension Pack: */
/* Also, destroyed downloader is a signal to finish the step: */
/* Start downloading: */
}
/* Finishing slot: */
void sltHandleDownloadedExtensionPack(const QString &strSource, const QString &strTarget, QString strDigest)
{
/* Warn the user about extension pack was downloaded and saved, propose to install it: */
if (msgCenter().proposeInstallExtentionPack(UI_ExtPackName, strSource, QDir::toNativeSeparators(strTarget)))
UIGlobalSettingsExtension::doInstallation(strTarget, strDigest, msgCenter().mainWindowShown(), NULL);
}
};
/* UIUpdateManager stuff: */
/* static */
void UIUpdateManager::schedule()
{
/* Ensure instance is NOT created: */
if (m_pInstance)
return;
/* Create instance: */
new UIUpdateManager;
}
/* static */
void UIUpdateManager::shutdown()
{
/* Ensure instance is created: */
if (!m_pInstance)
return;
/* Delete instance: */
delete m_pInstance;
}
void UIUpdateManager::sltForceCheck()
{
/* Force call for new version check: */
sltCheckIfUpdateIsNecessary(true /* force call */);
}
: m_pQueue(new UIUpdateQueue(this))
, m_fIsRunning(false)
{
/* Prepare instance: */
if (m_pInstance != this)
m_pInstance = this;
/* Configure queue: */
#ifdef VBOX_WITH_UPDATE_REQUEST
/* Ask updater to check for the first time: */
if (!vboxGlobal().isVMConsoleProcess())
#endif /* VBOX_WITH_UPDATE_REQUEST */
}
{
/* Cleanup instance: */
if (m_pInstance == this)
m_pInstance = 0;
}
{
/* If already running: */
if (m_fIsRunning)
{
/* And we have a force-call: */
if (fForceCall)
{
/* Just show Network Access Manager: */
gNetworkManager->show();
}
return;
}
/* Set as running: */
m_fIsRunning = true;
/* If update is really necessary: */
{
/* Prepare update queue: */
/* Start update queue: */
}
else
}
{
#ifdef VBOX_WITH_UPDATE_REQUEST
/* Ask updater to check for the next time: */
#endif /* VBOX_WITH_UPDATE_REQUEST */
/* Set as not running: */
m_fIsRunning = false;
}
#include "UIUpdateManager.moc"