~ubuntu-branches/ubuntu/precise/virtualbox/precise-updates

« back to all changes in this revision

Viewing changes to src/VBox/Frontends/VirtualBox/src/net/UIUpdateManager.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Felix Geyer
  • Date: 2011-10-17 23:23:09 UTC
  • mfrom: (3.1.5 sid)
  • Revision ID: james.westby@ubuntu.com-20111017232309-kzm6841lzk61ranj
Tags: 4.1.4-dfsg-1
* New upstream release.
  - Fixes missing icons when using pt_BR locale. (Closes: #507188)
  - Fixes guest additions download url. (Closes: #637349; LP: #840668)
* Refresh patches.
* Drop the vboxmouse x11 driver. The mouse integration is now completely
  handled by the kernel module.
* Restrict dh_pycentral to the virtualbox binary package.
* Merge changes from the Ubuntu package but use them only when built
  on Ubuntu:
  - Add an Apport hook.
  - Add vboxguest modalias to the package control field.
* Pass KBUILD_VERBOSE=2 to kmk.
* Add 36-fix-text-mode.patch to fix text mode when using the vboxvideo driver.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Id: UIUpdateManager.cpp $ */
 
2
/** @file
 
3
 *
 
4
 * VBox frontends: Qt4 GUI ("VirtualBox"):
 
5
 * UIUpdateManager class implementation
 
6
 */
 
7
 
 
8
/*
 
9
 * Copyright (C) 2006-2011 Oracle Corporation
 
10
 *
 
11
 * This file is part of VirtualBox Open Source Edition (OSE), as
 
12
 * available from http://www.virtualbox.org. This file is free software;
 
13
 * you can redistribute it and/or modify it under the terms of the GNU
 
14
 * General Public License (GPL) as published by the Free Software
 
15
 * Foundation, in version 2 as it comes in the "COPYING" file of the
 
16
 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
 
17
 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
 
18
 */
 
19
 
 
20
/* Global includes: */
 
21
#include <QEventLoop>
 
22
#include <QNetworkReply>
 
23
#include <QTimer>
 
24
#include <QDir>
 
25
 
 
26
#include <VBox/version.h>
 
27
 
 
28
/* Local includes: */
 
29
#include "UIUpdateManager.h"
 
30
#include "UINetworkManager.h"
 
31
#include "VBoxGlobal.h"
 
32
#include "UIMessageCenter.h"
 
33
#include "VBoxUtils.h"
 
34
#include "UIDownloaderExtensionPack.h"
 
35
#include "UIGlobalSettingsExtension.h"
 
36
#include "VBoxDefs.h"
 
37
 
 
38
/* Using declarations: */
 
39
using namespace VBoxGlobalDefs;
 
40
 
 
41
/* UIUpdateManager stuff: */
 
42
UIUpdateManager* UIUpdateManager::m_pInstance = 0;
 
43
 
 
44
/* static */
 
45
void UIUpdateManager::schedule()
 
46
{
 
47
    /* Ensure instance is NOT created: */
 
48
    if (m_pInstance)
 
49
        return;
 
50
 
 
51
    /* Create instance: */
 
52
    new UIUpdateManager;
 
53
}
 
54
 
 
55
/* static */
 
56
void UIUpdateManager::shutdown()
 
57
{
 
58
    /* Ensure instance is created: */
 
59
    if (!m_pInstance)
 
60
        return;
 
61
 
 
62
    /* Delete instance: */
 
63
    delete m_pInstance;
 
64
}
 
65
 
 
66
void UIUpdateManager::sltForceCheck()
 
67
{
 
68
    return;
 
69
 
 
70
    /* Force call for new version check: */
 
71
    sltCheckIfUpdateIsNecessary(true);
 
72
}
 
73
 
 
74
UIUpdateManager::UIUpdateManager()
 
75
    : m_uTime(1 /* day */ * 24 /* hours */ * 60 /* minutes */ * 60 /* seconds */ * 1000 /* ms */)
 
76
{
 
77
    /* Prepare instance: */
 
78
    if (m_pInstance != this)
 
79
        m_pInstance = this;
 
80
 
 
81
#ifdef VBOX_WITH_UPDATE_REQUEST
 
82
    /* Ask updater to check for the first time: */
 
83
    QTimer::singleShot(0, this, SLOT(sltCheckIfUpdateIsNecessary()));
 
84
#endif /* VBOX_WITH_UPDATE_REQUEST */
 
85
}
 
86
 
 
87
UIUpdateManager::~UIUpdateManager()
 
88
{
 
89
    /* Cleanup instance: */
 
90
    if (m_pInstance == this)
 
91
        m_pInstance = 0;
 
92
}
 
93
 
 
94
void UIUpdateManager::sltCheckIfUpdateIsNecessary(bool fForceCall /* = false */)
 
95
{
 
96
    /* Load/decode curent update data: */
 
97
    VBoxUpdateData currentData(vboxGlobal().virtualBox().GetExtraData(VBoxDefs::GUI_UpdateDate));
 
98
 
 
99
    /* Check if update is really neessary: */
 
100
    if (fForceCall || currentData.isNeedToCheck())
 
101
    {
 
102
        /* Check if update is necessary for VirtualBox itself: */
 
103
        checkIfUpdateIsNecessary(fForceCall);
 
104
 
 
105
        /* Check if update is necessary for VirtualBox extension pack: */
 
106
        checkIfUpdateIsNecessaryForExtensionPack(fForceCall);
 
107
 
 
108
        /* Encode/save new update data: */
 
109
        VBoxUpdateData newData(currentData.periodIndex(), currentData.branchIndex());
 
110
        vboxGlobal().virtualBox().SetExtraData(VBoxDefs::GUI_UpdateDate, newData.data());
 
111
    }
 
112
 
 
113
#ifdef VBOX_WITH_UPDATE_REQUEST
 
114
    /* Ask updater to check for the next time: */
 
115
    QTimer::singleShot(m_uTime, this, SLOT(sltCheckIfUpdateIsNecessary()));
 
116
#endif /* VBOX_WITH_UPDATE_REQUEST */
 
117
}
 
118
 
 
119
void UIUpdateManager::checkIfUpdateIsNecessary(bool fForceCall)
 
120
{
 
121
    /* Creating VirtualBox version checker: */
 
122
    UINewVersionChecker checker(fForceCall);
 
123
    /* Start synchronous check: */
 
124
    checker.checkForTheNewVersion();
 
125
}
 
126
 
 
127
void UIUpdateManager::checkIfUpdateIsNecessaryForExtensionPack(bool /* fForceCall */)
 
128
{
 
129
    /* Check if updater instance already created: */
 
130
    if (UIDownloaderExtensionPack::current())
 
131
        return;
 
132
 
 
133
    /* Get extension pack information: */
 
134
    CExtPack extPack = vboxGlobal().virtualBox().GetExtensionPackManager().Find(UI_ExtPackName);
 
135
    /* Check if extension pack is really installed: */
 
136
    if (extPack.isNull())
 
137
        return;
 
138
 
 
139
    /* Get VirtualBox version: */
 
140
    VBoxVersion vboxVersion(vboxGlobal().vboxVersionStringNormalized());
 
141
    /* Get extension pack version: */
 
142
    QString strExtPackVersion(extPack.GetVersion().remove(VBOX_BUILD_PUBLISHER));
 
143
    VBoxVersion extPackVersion(strExtPackVersion);
 
144
    /* Check if extension pack version less than required: */
 
145
    if ((vboxVersion.z() % 2 != 0) /* Skip unstable VBox version */ ||
 
146
        !(extPackVersion < vboxVersion) /* Ext Pack version more or equal to VBox version */)
 
147
        return;
 
148
 
 
149
    /* Ask the user about extension pack downloading: */
 
150
    if (!msgCenter().proposeDownloadExtensionPack(UI_ExtPackName, strExtPackVersion))
 
151
        return;
 
152
 
 
153
    /* Run downloader for VirtualBox extension pack: */
 
154
    UIDownloaderExtensionPack::download(this);
 
155
}
 
156
 
 
157
void UIUpdateManager::sltHandleDownloadedExtensionPack(const QString &strSource, const QString &strTarget)
 
158
{
 
159
    /* Warn the user about extension pack was downloaded and saved, propose to install it: */
 
160
    if (msgCenter().proposeInstallExtentionPack(UI_ExtPackName, strSource, QDir::toNativeSeparators(strTarget)))
 
161
        UIGlobalSettingsExtension::doInstallation(strTarget, msgCenter().mainWindowShown(), NULL);
 
162
}
 
163
 
 
164
/* UINewVersionChecker stuff: */
 
165
UINewVersionChecker::UINewVersionChecker(bool fForceCall)
 
166
    : m_url("http://update.virtualbox.org/query.php")
 
167
    , m_fForceCall(fForceCall)
 
168
    , m_pLoop(new QEventLoop(this))
 
169
{
 
170
}
 
171
 
 
172
void UINewVersionChecker::checkForTheNewVersion()
 
173
{
 
174
    /* Calculate the count of checks left: */
 
175
    int cCount = 1;
 
176
    QString strCount = vboxGlobal().virtualBox().GetExtraData(VBoxDefs::GUI_UpdateCheckCount);
 
177
    if (!strCount.isEmpty())
 
178
    {
 
179
        bool ok = false;
 
180
        int c = strCount.toLongLong(&ok);
 
181
        if (ok) cCount = c;
 
182
    }
 
183
 
 
184
    /* Compose query: */
 
185
    QUrl url(m_url);
 
186
    url.addQueryItem("platform", vboxGlobal().virtualBox().GetPackageType());
 
187
    /* Check if branding is active: */
 
188
    if (vboxGlobal().brandingIsActive())
 
189
    {
 
190
        /* Branding: Check whether we have a local branding file which tells us our version suffix "FOO"
 
191
                     (e.g. 3.06.54321_FOO) to identify this installation: */
 
192
        url.addQueryItem("version", QString("%1_%2_%3").arg(vboxGlobal().virtualBox().GetVersion())
 
193
                                                       .arg(vboxGlobal().virtualBox().GetRevision())
 
194
                                                       .arg(vboxGlobal().brandingGetKey("VerSuffix")));
 
195
    }
 
196
    else
 
197
    {
 
198
        /* Use hard coded version set by VBOX_VERSION_STRING: */
 
199
        url.addQueryItem("version", QString("%1_%2").arg(vboxGlobal().virtualBox().GetVersion())
 
200
                                                    .arg(vboxGlobal().virtualBox().GetRevision()));
 
201
    }
 
202
    url.addQueryItem("count", QString::number(cCount));
 
203
    url.addQueryItem("branch", VBoxUpdateData(vboxGlobal().virtualBox().
 
204
                                              GetExtraData(VBoxDefs::GUI_UpdateDate)).branchName());
 
205
    QString strUserAgent(QString("VirtualBox %1 <%2>")
 
206
                            .arg(vboxGlobal().virtualBox().GetVersion())
 
207
                            .arg(vboxGlobal().platformInfo()));
 
208
 
 
209
    /* Setup GET request: */
 
210
    QNetworkRequest request;
 
211
    request.setUrl(url);
 
212
    request.setRawHeader("User-Agent", strUserAgent.toAscii());
 
213
    QNetworkReply *pReply = gNetworkManager->get(request);
 
214
    connect(pReply, SIGNAL(finished()), this, SLOT(sltHandleCheckReply()));
 
215
    connect(pReply, SIGNAL(sslErrors(QList<QSslError>)), pReply, SLOT(ignoreSslErrors()));
 
216
 
 
217
    /* Lock event loop: */
 
218
    m_pLoop->exec();
 
219
}
 
220
 
 
221
void UINewVersionChecker::sltHandleCheckReply()
 
222
{
 
223
    /* Get corresponding network reply object: */
 
224
    QNetworkReply *pReply = qobject_cast<QNetworkReply*>(sender());
 
225
    /* And ask it for suicide: */
 
226
    pReply->deleteLater();
 
227
 
 
228
    /* Handle normal result: */
 
229
    if (pReply->error() == QNetworkReply::NoError)
 
230
    {
 
231
        /* Deserialize incoming data: */
 
232
        QString strResponseData(pReply->readAll());
 
233
 
 
234
        /* Newer version of necessary package found: */
 
235
        if (strResponseData.indexOf(QRegExp("^\\d+\\.\\d+\\.\\d+ \\S+$")) == 0)
 
236
        {
 
237
            QStringList response = strResponseData.split(" ", QString::SkipEmptyParts);
 
238
            msgCenter().showUpdateSuccess(vboxGlobal().mainWindow(), response[0], response[1]);
 
239
        }
 
240
        /* No newer version of necessary package found: */
 
241
        else
 
242
        {
 
243
            if (m_fForceCall)
 
244
                msgCenter().showUpdateNotFound(vboxGlobal().mainWindow());
 
245
        }
 
246
 
 
247
        /* Save left count of checks: */
 
248
        int cCount = 1;
 
249
        QString strCount = vboxGlobal().virtualBox().GetExtraData(VBoxDefs::GUI_UpdateCheckCount);
 
250
        if (!strCount.isEmpty())
 
251
        {
 
252
            bool ok = false;
 
253
            int c = strCount.toLongLong(&ok);
 
254
            if (ok) cCount = c;
 
255
        }
 
256
        vboxGlobal().virtualBox().SetExtraData(VBoxDefs::GUI_UpdateCheckCount, QString("%1").arg((qulonglong)cCount + 1));
 
257
    }
 
258
    /* Handle errors: */
 
259
    else
 
260
    {
 
261
        if (m_fForceCall)
 
262
            msgCenter().showUpdateFailure(vboxGlobal().mainWindow(), pReply->errorString());
 
263
    }
 
264
 
 
265
    /* Unlock event loop: */
 
266
    m_pLoop->exit();
 
267
}
 
268