Merge lp:~lukas-kde/unity8/wizardSystemUpdate into lp:unity8

Proposed by Lukáš Tinkl on 2016-07-15
Status: Merged
Approved by: Michał Sawicz on 2016-07-29
Approved revision: 2555
Merged at revision: 2590
Proposed branch: lp:~lukas-kde/unity8/wizardSystemUpdate
Merge into: lp:unity8
Diff against target: 835 lines (+477/-29)
17 files modified
plugins/Ubuntu/SystemImage/CMakeLists.txt (+5/-0)
plugins/Ubuntu/SystemImage/SystemImage.cpp (+127/-5)
plugins/Ubuntu/SystemImage/SystemImage.h (+52/-2)
plugins/Ubuntu/SystemImage/plugin.cpp (+3/-9)
plugins/Ubuntu/SystemImage/plugin.h (+1/-1)
plugins/Wizard/PageList.cpp (+16/-1)
plugins/Wizard/System.cpp (+9/-1)
plugins/Wizard/System.h (+5/-1)
qml/Wizard/Page.qml (+1/-1)
qml/Wizard/Pages/30-wifi.qml (+8/-4)
qml/Wizard/Pages/77-system-update.qml (+156/-0)
tests/mocks/Ubuntu/SystemImage/MockSystemImage.cpp (+24/-1)
tests/mocks/Ubuntu/SystemImage/MockSystemImage.h (+22/-2)
tests/mocks/Wizard/MockSystem.cpp (+8/-0)
tests/mocks/Wizard/MockSystem.h (+4/-0)
tests/plugins/Wizard/tst_pagelist.cpp (+30/-1)
tests/qmltests/Wizard/tst_Wizard.qml (+6/-0)
To merge this branch: bzr merge lp:~lukas-kde/unity8/wizardSystemUpdate
Reviewer Review Type Date Requested Status
Michał Sawicz 2016-07-15 Approve on 2016-07-29
Unity8 CI Bot continuous-integration Needs Fixing on 2016-07-28
Daniel d'Andrada (community) Abstain on 2016-07-28
Review via email: mp+300182@code.launchpad.net

Commit Message

Implement an optional system update feature during OOBE wizard

Description of the Change

Implement a new page with the possibility to invoke a system update during the course of the OOBE wizard

Extends the SystemImage plugin with methods to talk to the respective DBUS daemon that performs the background check and download of the update. If the update is downloaded by the time the user arrives to the 77-system-update.qml, they will get presented with an option to install it. The device will then apply the update and automatically reboot.

The Wizard plugin adds a feature to skip until the last page, to greet the user with "Welcome to Ubuntu" slide on the next boot after a system update had been installed.

Design: https://docs.google.com/presentation/d/1UzzPkKDhU4GaMCzTE7pkaxFyF62G_DUv9jJXhE540Qg/edit#slide=id.g1554a0d5d0_0_53

Checklist:
* Are there any related MPs required for this MP to build/function as expected? Please list.

No

* Did you perform an exploratory manual test run of your code change and any related functionality?

Yes

* If you changed the packaging (debian), did you subscribe the ubuntu-unity team to this MP?

N/A

* If you changed the UI, has there been a design review?

Yes, reviewed by Paty and Grazina

To post a comment you must log in.
Unity8 CI Bot (unity8-ci-bot) wrote :

FAILED: Continuous integration, rev:2551
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/1783/
Executed test runs:
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build/2337
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=vivid+overlay,testname=qmluitests.sh/1248
    UNSTABLE: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=xenial+overlay,testname=qmluitests.sh/1248
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=yakkety,testname=qmluitests.sh/1248
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-0-fetch/2365
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/2255
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial+overlay/2255
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=yakkety/2255
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=vivid+overlay/2247
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=vivid+overlay/2247/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/2247
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/2247/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=yakkety/2247
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=yakkety/2247/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/2247
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/2247/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/2247
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/2247/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=yakkety/2247
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=yakkety/2247/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/2247
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/2247/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/2247
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/2247/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=yakkety/2247
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=yakkety/2247/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/1783/rebuild

review: Needs Fixing (continuous-integration)
Michał Sawicz (saviq) wrote :

Do we want all the qDebugs? Should we maybe use something category-based instead of exclamation marks? ;)

Do we want a test for the system update page?

review: Needs Information
Michał Sawicz (saviq) :
2552. By Lukáš Tinkl on 2016-07-28

merge trunk

2553. By Lukáš Tinkl on 2016-07-28

address review comments

Lukáš Tinkl (lukas-kde) wrote :

Replies inline, fixed what I could

Michał Sawicz (saviq) wrote :

Poke about a few remaining comments (note in previous diff - click "Show diff comments" or select the previous "Preview Diff" below).

review: Needs Information
Daniel d'Andrada (dandrader) wrote :

"""
+ qDebug() << "!!! Rebooting:" << status;
"""

Still need to either remove them or use categorized logging (disabled by default, probably).

review: Needs Fixing
2554. By Lukáš Tinkl on 2016-07-28

convert to categorized logging

Lukáš Tinkl (lukas-kde) wrote :

> """
> + qDebug() << "!!! Rebooting:" << status;
> """
>
> Still need to either remove them or use categorized logging (disabled by
> default, probably).

Converted to categorized logging

Daniel d'Andrada (dandrader) wrote :

> > """
> > + qDebug() << "!!! Rebooting:" << status;
> > """
> >
> > Still need to either remove them or use categorized logging (disabled by
> > default, probably).
>
> Converted to categorized logging

Thanks!

review: Abstain
Lukáš Tinkl (lukas-kde) wrote :

Replies inline

2555. By Lukáš Tinkl on 2016-07-28

simplify the layout, as per Saviq's suggestion

Unity8 CI Bot (unity8-ci-bot) wrote :

FAILED: Continuous integration, rev:2552
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/1835/
Executed test runs:
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build/2393
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=vivid+overlay,testname=qmluitests.sh/1293
    FAILURE: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=xenial+overlay,testname=qmluitests.sh/1293/console
    FAILURE: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=yakkety,testname=qmluitests.sh/1293/console
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-0-fetch/2421
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/2308
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial+overlay/2308
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=yakkety/2308
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=vivid+overlay/2301
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=vivid+overlay/2301/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/2301
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/2301/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=yakkety/2301
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=yakkety/2301/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/2301
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/2301/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/2301
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/2301/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=yakkety/2301
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=yakkety/2301/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/2301
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/2301/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/2301
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/2301/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=yakkety/2301
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=yakkety/2301/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/1835/rebuild

review: Needs Fixing (continuous-integration)
Unity8 CI Bot (unity8-ci-bot) wrote :

FAILED: Continuous integration, rev:2555
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/1840/
Executed test runs:
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build/2398
    UNSTABLE: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=vivid+overlay,testname=qmluitests.sh/1298
    UNSTABLE: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=xenial+overlay,testname=qmluitests.sh/1298
    FAILURE: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=yakkety,testname=qmluitests.sh/1298/console
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-0-fetch/2426
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/2313
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial+overlay/2313
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=yakkety/2313
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=vivid+overlay/2306
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=vivid+overlay/2306/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/2306
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/2306/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=yakkety/2306
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=yakkety/2306/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/2306
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/2306/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/2306
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/2306/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=yakkety/2306
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=yakkety/2306/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/2306
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/2306/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/2306
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/2306/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=yakkety/2306
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=yakkety/2306/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/1840/rebuild

review: Needs Fixing (continuous-integration)
Michał Sawicz (saviq) wrote :

 * Did you perform an exploratory manual test run of the code change and any related functionality?
Y
 * Did CI run pass? If not, please explain why.
Unrelated failures - flaky and/or bug #1607686 on yakkety

review: Approve
2556. By Lukáš Tinkl on 2016-08-03

partially revert the string change

causing endless loops / freezes in QtQuick

2557. By Lukáš Tinkl on 2016-08-08

merge trunk

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'plugins/Ubuntu/SystemImage/CMakeLists.txt'
2--- plugins/Ubuntu/SystemImage/CMakeLists.txt 2014-07-30 11:08:29 +0000
3+++ plugins/Ubuntu/SystemImage/CMakeLists.txt 2016-08-08 10:17:50 +0000
4@@ -1,3 +1,7 @@
5+include_directories(
6+ ${GLIB_INCLUDE_DIRS}
7+)
8+
9 set(SYSTEMIMAGE_SOURCES
10 plugin.cpp
11 SystemImage.cpp
12@@ -6,5 +10,6 @@
13 add_library(SystemImage MODULE ${SYSTEMIMAGE_SOURCES})
14
15 qt5_use_modules(SystemImage Qml DBus Core)
16+target_link_libraries(SystemImage ${GLIB_LIBRARIES})
17
18 add_unity8_plugin(Ubuntu.SystemImage 0.1 Ubuntu/SystemImage TARGETS SystemImage)
19
20=== modified file 'plugins/Ubuntu/SystemImage/SystemImage.cpp'
21--- plugins/Ubuntu/SystemImage/SystemImage.cpp 2015-09-14 09:11:08 +0000
22+++ plugins/Ubuntu/SystemImage/SystemImage.cpp 2016-08-08 10:17:50 +0000
23@@ -1,5 +1,5 @@
24 /*
25- * Copyright (C) 2014 Canonical, Ltd.
26+ * Copyright (C) 2014-2016 Canonical, Ltd.
27 *
28 * This program is free software; you can redistribute it and/or modify
29 * it under the terms of the GNU General Public License as published by
30@@ -14,20 +14,142 @@
31 * along with this program. If not, see <http://www.gnu.org/licenses/>.
32 */
33
34-#include "SystemImage.h"
35 #include <QDBusConnection>
36 #include <QDBusPendingCall>
37+#include <QDBusReply>
38+#include <QDebug>
39+
40+#include <glib.h>
41+
42+#include "SystemImage.h"
43+
44+#define SYSTEMIMAGE_SERVICE QStringLiteral("com.canonical.SystemImage")
45+#define SYSTEMIMAGE_PATH QStringLiteral("/Service")
46+#define SYSTEMIMAGE_IFACE QStringLiteral("com.canonical.SystemImage")
47+
48+Q_LOGGING_CATEGORY(SYSTEMIMAGEPLUGIN, "unity8.systemimage", QtWarningMsg)
49+
50+#define DEBUG_MSG qCDebug(SYSTEMIMAGEPLUGIN).nospace().noquote() << Q_FUNC_INFO
51+#define WARNING_MSG qCWarning(SYSTEMIMAGEPLUGIN).nospace().noquote() << Q_FUNC_INFO
52
53 SystemImage::SystemImage(QObject *parent)
54 : QObject(parent)
55 {
56+ QDBusConnection::systemBus().connect(SYSTEMIMAGE_SERVICE, SYSTEMIMAGE_PATH, SYSTEMIMAGE_IFACE, QStringLiteral("UpdateAvailableStatus"),
57+ this, SLOT(onUpdateAvailableStatus(bool,bool,QString,int,QString,QString)));
58+ QDBusConnection::systemBus().connect(SYSTEMIMAGE_SERVICE, SYSTEMIMAGE_PATH, SYSTEMIMAGE_IFACE, QStringLiteral("UpdateDownloaded"),
59+ this, SLOT(onUpdateDownloaded()));
60+ QDBusConnection::systemBus().connect(SYSTEMIMAGE_SERVICE, SYSTEMIMAGE_PATH, SYSTEMIMAGE_IFACE, QStringLiteral("UpdateFailed"),
61+ this, SLOT(onUpdateFailed(int,QString)));
62+ QDBusConnection::systemBus().connect(SYSTEMIMAGE_SERVICE, SYSTEMIMAGE_PATH, SYSTEMIMAGE_IFACE, QStringLiteral("Applied"),
63+ this, SLOT(onUpdateApplied(bool)));
64+ QDBusConnection::systemBus().connect(SYSTEMIMAGE_SERVICE, SYSTEMIMAGE_PATH, SYSTEMIMAGE_IFACE, QStringLiteral("Rebooting"),
65+ this, SLOT(onRebooting(bool)));
66+}
67+
68+void SystemImage::checkForUpdate()
69+{
70+ DEBUG_MSG << "Checking for update";
71+ const QDBusMessage msg = QDBusMessage::createMethodCall(SYSTEMIMAGE_SERVICE, SYSTEMIMAGE_PATH, SYSTEMIMAGE_IFACE,
72+ QStringLiteral("CheckForUpdate"));
73+ QDBusConnection::systemBus().asyncCall(msg);
74+}
75+
76+void SystemImage::applyUpdate()
77+{
78+ DEBUG_MSG << "Applying update";
79+ setUpdateApplying(true);
80+
81+ const QDBusMessage msg = QDBusMessage::createMethodCall(SYSTEMIMAGE_SERVICE, SYSTEMIMAGE_PATH, SYSTEMIMAGE_IFACE,
82+ QStringLiteral("ApplyUpdate"));
83+ QDBusConnection::systemBus().asyncCall(msg);
84 }
85
86 void SystemImage::factoryReset()
87 {
88- const QDBusMessage msg = QDBusMessage::createMethodCall(QStringLiteral("com.canonical.SystemImage"),
89- QStringLiteral("/Service"),
90- QStringLiteral("com.canonical.SystemImage"),
91+ const QDBusMessage msg = QDBusMessage::createMethodCall(SYSTEMIMAGE_SERVICE, SYSTEMIMAGE_PATH, SYSTEMIMAGE_IFACE,
92 QStringLiteral("FactoryReset"));
93 QDBusConnection::systemBus().asyncCall(msg);
94 }
95+
96+void SystemImage::onUpdateAvailableStatus(bool is_available, bool downloading, const QString &available_version, int update_size,
97+ const QString &last_update_date, const QString &error_reason)
98+{
99+ DEBUG_MSG << "A new update is " << (is_available ? "" : "NOT") << "available";
100+
101+ if (is_available == m_updateAvailable) {
102+ return;
103+ }
104+
105+ m_updateAvailable = is_available;
106+ m_downloading = downloading;
107+ m_availableVersion = available_version;
108+ m_updateSize = formatSize(update_size);
109+ m_lastUpdateDate = last_update_date;
110+ m_errorReason = error_reason;
111+ Q_EMIT updateAvailableStatus();
112+
113+ DEBUG_MSG << "Downloading: " << downloading << ", version: " << available_version << ", last update: " << last_update_date <<
114+ ", size: " << m_updateSize;
115+}
116+
117+void SystemImage::onUpdateDownloaded()
118+{
119+ DEBUG_MSG << "Update downloaded";
120+
121+ m_downloaded = true;
122+ Q_EMIT updateDownloadedChanged();
123+}
124+
125+void SystemImage::onUpdateFailed(int /*consecutive_failure_count*/, const QString &last_reason)
126+{
127+ WARNING_MSG << "System Update failed: " << last_reason;
128+ setUpdateApplying(false);
129+}
130+
131+void SystemImage::onUpdateApplied(bool applied)
132+{
133+ DEBUG_MSG << "System Update applied with status: " << applied;
134+ setUpdateApplying(false);
135+ if (applied) {
136+ resetUpdateStatus();
137+ Q_EMIT updateAvailableStatus();
138+ }
139+}
140+
141+void SystemImage::onRebooting(bool status)
142+{
143+ setUpdateApplying(false);
144+ DEBUG_MSG << "Rebooting: " << status;
145+}
146+
147+void SystemImage::setUpdateApplying(bool status)
148+{
149+ if (status != m_updateApplying) {
150+ m_updateApplying = status;
151+ Q_EMIT updateApplyingChanged();
152+ }
153+}
154+
155+void SystemImage::resetUpdateStatus()
156+{
157+ m_updateAvailable = false;
158+ m_updateApplying = false;
159+ m_downloading = false;
160+ m_downloaded = false;
161+ m_availableVersion.clear();
162+ m_updateSize.clear();
163+ m_lastUpdateDate.clear();
164+ m_errorReason.clear();
165+}
166+
167+QString SystemImage::formatSize(quint64 size) const
168+{
169+ guint64 g_size = size;
170+
171+ gchar * formatted_size = g_format_size(g_size);
172+ QString q_formatted_size = QString::fromLocal8Bit(formatted_size);
173+ g_free(formatted_size);
174+
175+ return q_formatted_size;
176+}
177
178=== modified file 'plugins/Ubuntu/SystemImage/SystemImage.h'
179--- plugins/Ubuntu/SystemImage/SystemImage.h 2015-06-11 23:45:12 +0000
180+++ plugins/Ubuntu/SystemImage/SystemImage.h 2016-08-08 10:17:50 +0000
181@@ -1,5 +1,5 @@
182 /*
183- * Copyright (C) 2014 Canonical, Ltd.
184+ * Copyright (C) 2014-2016 Canonical, Ltd.
185 *
186 * This program is free software; you can redistribute it and/or modify
187 * it under the terms of the GNU General Public License as published by
188@@ -18,17 +18,67 @@
189 #define SYSTEMIMAGE_H
190
191 #include <QObject>
192+#include <QLoggingCategory>
193+
194+Q_DECLARE_LOGGING_CATEGORY(SYSTEMIMAGEPLUGIN)
195
196 class SystemImage : public QObject
197 {
198 Q_OBJECT
199 Q_DISABLE_COPY(SystemImage)
200
201+ Q_PROPERTY(bool updateAvailable READ updateAvailable NOTIFY updateAvailableStatus)
202+ Q_PROPERTY(bool updateDownloading READ updateDownloading NOTIFY updateAvailableStatus)
203+ Q_PROPERTY(QString availableVersion READ availableVersion NOTIFY updateAvailableStatus)
204+ Q_PROPERTY(QString updateSize READ updateSize NOTIFY updateAvailableStatus)
205+ Q_PROPERTY(bool updateApplying READ updateApplying NOTIFY updateApplyingChanged)
206+ Q_PROPERTY(bool updateDownloaded READ updateDownloaded NOTIFY updateDownloadedChanged)
207+
208 public:
209- explicit SystemImage(QObject *parent = 0);
210+ explicit SystemImage(QObject *parent = nullptr);
211 ~SystemImage() = default;
212
213+ bool updateAvailable() const { return m_updateAvailable; }
214+ bool updateDownloading() const { return m_downloading; }
215+ QString availableVersion() const { return m_availableVersion; }
216+ QString updateSize() const { return m_updateSize; }
217+ bool updateApplying() const { return m_updateApplying; }
218+ bool updateDownloaded() const { return m_downloaded; }
219+
220+public Q_SLOTS:
221+ Q_INVOKABLE void checkForUpdate();
222+ Q_INVOKABLE void applyUpdate();
223 Q_INVOKABLE void factoryReset();
224+
225+private Q_SLOTS:
226+ void onUpdateAvailableStatus(bool is_available, bool updateDownloading, const QString &available_version,
227+ int update_size, const QString &last_update_date, const QString &error_reason);
228+ void onUpdateDownloaded();
229+ void onUpdateFailed(int consecutive_failure_count, const QString & last_reason);
230+ void onUpdateApplied(bool applied);
231+ void onRebooting(bool status);
232+
233+Q_SIGNALS:
234+ void updateAvailableStatus();
235+ void updateDownloadedChanged();
236+ void updateApplyingChanged();
237+
238+private Q_SLOTS:
239+ void setUpdateApplying(bool status);
240+
241+private:
242+ void resetUpdateStatus();
243+ QString formatSize(quint64 size) const;
244+
245+private:
246+ bool m_updateAvailable = false;
247+ bool m_updateApplying = false;
248+ bool m_downloading = false;
249+ bool m_downloaded = false;
250+ QString m_availableVersion;
251+ QString m_updateSize;
252+ QString m_lastUpdateDate;
253+ QString m_errorReason;
254 };
255
256 #endif // SYSTEMIMAGE_H
257
258=== modified file 'plugins/Ubuntu/SystemImage/plugin.cpp'
259--- plugins/Ubuntu/SystemImage/plugin.cpp 2014-07-30 11:08:29 +0000
260+++ plugins/Ubuntu/SystemImage/plugin.cpp 2016-08-08 10:17:50 +0000
261@@ -1,5 +1,5 @@
262 /*
263- * Copyright (C) 2014 Canonical, Ltd.
264+ * Copyright (C) 2014-2016 Canonical, Ltd.
265 *
266 * This program is free software; you can redistribute it and/or modify
267 * it under the terms of the GNU General Public License as published by
268@@ -19,16 +19,10 @@
269
270 #include <QtQml>
271
272-static QObject *service_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
273-{
274- Q_UNUSED(engine)
275- Q_UNUSED(scriptEngine)
276- return new SystemImage();
277-}
278-
279 void BackendPlugin::registerTypes(const char *uri)
280 {
281 Q_ASSERT(uri == QLatin1String("Ubuntu.SystemImage"));
282
283- qmlRegisterSingletonType<SystemImage>(uri, 0, 1, "SystemImage", service_provider);
284+ qmlRegisterSingletonType<SystemImage>(uri, 0, 1, "SystemImage",
285+ [](QQmlEngine*, QJSEngine*) -> QObject* { return new SystemImage; });
286 }
287
288=== modified file 'plugins/Ubuntu/SystemImage/plugin.h'
289--- plugins/Ubuntu/SystemImage/plugin.h 2015-04-30 09:31:51 +0000
290+++ plugins/Ubuntu/SystemImage/plugin.h 2016-08-08 10:17:50 +0000
291@@ -22,7 +22,7 @@
292 class BackendPlugin : public QQmlExtensionPlugin
293 {
294 Q_OBJECT
295- Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
296+ Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid)
297
298 public:
299 void registerTypes(const char *uri) override;
300
301=== modified file 'plugins/Wizard/PageList.cpp'
302--- plugins/Wizard/PageList.cpp 2016-03-29 03:47:39 +0000
303+++ plugins/Wizard/PageList.cpp 2016-08-08 10:17:50 +0000
304@@ -1,5 +1,5 @@
305 /*
306- * Copyright (C) 2014 Canonical Ltd.
307+ * Copyright (C) 2014-2016 Canonical Ltd.
308 *
309 * This program is free software: you can redistribute it and/or modify it
310 * under the terms of the GNU General Public License version 3, as published
311@@ -34,6 +34,7 @@
312 #include <QDir>
313 #include <QSet>
314 #include <QStandardPaths>
315+#include <QSettings>
316
317 PageList::PageList(QObject *parent)
318 : QObject(parent),
319@@ -66,6 +67,20 @@
320 Q_FOREACH(const QString &page, disabledPages) {
321 m_pages.remove(page);
322 }
323+
324+ // If there was a system update installed, skip until the last page to just greet the user
325+ QSettings settings;
326+ if (settings.value(QStringLiteral("Wizard/SkipUntilFinishedPage")).toBool()) {
327+ const QString lastPage = m_pages.lastKey();
328+ Q_FOREACH(const QString &page, m_pages.keys()) {
329+ if (Q_UNLIKELY(page != lastPage)) {
330+ m_pages.remove(page);
331+ }
332+ }
333+
334+ // ... and reset it again for the next run
335+ settings.remove(QStringLiteral("Wizard/SkipUntilFinishedPage"));
336+ }
337 }
338
339 QStringList PageList::entries() const
340
341=== modified file 'plugins/Wizard/System.cpp'
342--- plugins/Wizard/System.cpp 2016-06-21 09:51:41 +0000
343+++ plugins/Wizard/System.cpp 2016-08-08 10:17:50 +0000
344@@ -1,5 +1,5 @@
345 /*
346- * Copyright (C) 2014-2015 Canonical Ltd.
347+ * Copyright (C) 2014-2016 Canonical Ltd.
348 *
349 * This program is free software: you can redistribute it and/or modify it
350 * under the terms of the GNU General Public License version 3, as published
351@@ -26,6 +26,7 @@
352 #include <QMap>
353 #include <QProcess>
354 #include <QDebug>
355+#include <QSettings>
356
357 System::System()
358 : QObject()
359@@ -110,3 +111,10 @@
360 initctl restart --no-wait indicator-messages; \
361 initctl restart --no-wait unity8-dash\""));
362 }
363+
364+void System::skipUntilFinishedPage()
365+{
366+ QSettings settings;
367+ settings.setValue(QStringLiteral("Wizard/SkipUntilFinishedPage"), true);
368+ settings.sync();
369+}
370
371=== modified file 'plugins/Wizard/System.h'
372--- plugins/Wizard/System.h 2016-03-29 03:47:39 +0000
373+++ plugins/Wizard/System.h 2016-08-08 10:17:50 +0000
374@@ -1,5 +1,5 @@
375 /*
376- * Copyright (C) 2014-2015 Canonical Ltd.
377+ * Copyright (C) 2014-2016 Canonical Ltd.
378 *
379 * This program is free software: you can redistribute it and/or modify it
380 * under the terms of the GNU General Public License version 3, as published
381@@ -35,6 +35,10 @@
382
383 public Q_SLOTS:
384 void updateSessionLocale(const QString &locale);
385+ /**
386+ * Mark the wizard to skip all the pages and just show the last (welcome to ubuntu) page
387+ */
388+ void skipUntilFinishedPage();
389
390 Q_SIGNALS:
391 void wizardEnabledChanged();
392
393=== modified file 'qml/Wizard/Page.qml'
394--- qml/Wizard/Page.qml 2016-03-29 03:47:39 +0000
395+++ qml/Wizard/Page.qml 2016-08-08 10:17:50 +0000
396@@ -21,7 +21,7 @@
397 Item {
398 readonly property real maximumContentWidth: units.gu(50)
399 readonly property bool wideMode: width > units.gu(90) && width > height
400- readonly property bool contentAnimationRunning: contentAnimation.running
401+ readonly property alias contentAnimationRunning: contentAnimation.running
402
403 readonly property real buttonMargin: units.gu(3)
404 readonly property real buttonWidth: (width - buttonMargin * 2) / 2 -
405
406=== modified file 'qml/Wizard/Pages/30-wifi.qml'
407--- qml/Wizard/Pages/30-wifi.qml 2016-03-29 03:47:39 +0000
408+++ qml/Wizard/Pages/30-wifi.qml 2016-08-08 10:17:50 +0000
409@@ -20,6 +20,7 @@
410 import Ubuntu.Components 1.3
411 import Wizard 0.1
412 import Ubuntu.Connectivity 1.0
413+import Ubuntu.SystemImage 0.1
414 import ".." as LocalComponents
415
416 LocalComponents.Page {
417@@ -158,7 +159,7 @@
418 anchors.right: parent.right
419 anchors.leftMargin: column.anchors.leftMargin == 0 ? staticMargin : 0
420 font.weight: Font.Light
421- color: "#68064d"
422+ color: textColor
423 wrapMode: Text.Wrap
424 text: listview.count > 0 ? i18n.tr("Available Wi-Fi networks")
425 : i18n.tr("No available Wi-Fi networks")
426@@ -173,8 +174,6 @@
427 Layout.fillHeight: true
428
429 delegate: Loader {
430- id: loader
431-
432 readonly property bool isAccessPoint: model.type === "unity.widgets.systemsettings.tablet.accesspoint"
433 readonly property bool isConnected: item && item.menuData && item.menuData.actionState
434 readonly property bool isEnterprise: item && item.isEnterprise
435@@ -204,7 +203,12 @@
436 id: forwardButton
437 LocalComponents.StackButton {
438 text: (connected || listview.count === 0) ? i18n.tr("Next") : i18n.tr("Skip")
439- onClicked: pageStack.next()
440+ onClicked: {
441+ if (connected) {
442+ SystemImage.checkForUpdate(); // initiate the background check for System Update
443+ }
444+ pageStack.next();
445+ }
446 }
447 }
448 }
449
450=== added file 'qml/Wizard/Pages/77-system-update.qml'
451--- qml/Wizard/Pages/77-system-update.qml 1970-01-01 00:00:00 +0000
452+++ qml/Wizard/Pages/77-system-update.qml 2016-08-08 10:17:50 +0000
453@@ -0,0 +1,156 @@
454+/*
455+ * Copyright (C) 2016 Canonical, Ltd.
456+ *
457+ * This program is free software; you can redistribute it and/or modify
458+ * it under the terms of the GNU General Public License as published by
459+ * the Free Software Foundation; version 3.
460+ *
461+ * This program is distributed in the hope that it will be useful,
462+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
463+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
464+ * GNU General Public License for more details.
465+ *
466+ * You should have received a copy of the GNU General Public License
467+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
468+ */
469+
470+import QtQuick 2.4
471+import QtQuick.Layouts 1.1
472+import Ubuntu.Components 1.3
473+import Ubuntu.SystemImage 0.1
474+import Wizard 0.1
475+import ".." as LocalComponents
476+
477+LocalComponents.Page {
478+ id: systemUpdatePage
479+ objectName: "systemUpdatePage"
480+
481+ title: i18n.tr("Update Device")
482+ forwardButtonSourceComponent: forwardButton
483+
484+ skip: !SystemImage.updateDownloaded // skip the page when the system update is not ready to install
485+
486+ Column {
487+ id: column
488+ anchors {
489+ fill: content
490+ leftMargin: systemUpdatePage.leftMargin
491+ rightMargin: systemUpdatePage.rightMargin
492+ topMargin: systemUpdatePage.customMargin
493+ }
494+ spacing: units.gu(3)
495+ opacity: spinner.running ? 0.5 : 1
496+ Behavior on opacity {
497+ UbuntuNumberAnimation {}
498+ }
499+
500+ Label {
501+ anchors.left: parent.left
502+ anchors.right: parent.right
503+ anchors.leftMargin: column.anchors.leftMargin == 0 ? staticMargin : 0
504+ font.weight: Font.Light
505+ color: textColor
506+ wrapMode: Text.Wrap
507+ fontSize: "small"
508+ text: i18n.tr("There is a system update available and ready to install. Afterwards, the device will automatically restart.")
509+ }
510+
511+ GridLayout {
512+ rows: 3
513+ columns: 2
514+ rowSpacing: units.gu(1)
515+ columnSpacing: units.gu(2)
516+
517+ Image {
518+ Layout.rowSpan: 3
519+ Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
520+ sourceSize: Qt.size(units.gu(3), units.gu(3))
521+ fillMode: Image.PreserveAspectFit
522+ source: "image://theme/distributor-logo"
523+ }
524+
525+ Label {
526+ color: textColor
527+ font.weight: Font.Normal
528+ fontSize: "small"
529+ text: i18n.ctr("string identifying name of the update", "Ubuntu system")
530+ }
531+
532+ Label {
533+ font.weight: Font.Light
534+ fontSize: "small"
535+ color: textColor
536+ text: i18n.ctr("version of the system update", "Version %1").arg(SystemImage.availableVersion)
537+ }
538+
539+ Label {
540+ font.weight: Font.Light
541+ fontSize: "small"
542+ color: textColor
543+ text: SystemImage.updateSize
544+ }
545+ }
546+
547+ Label {
548+ anchors.left: parent.left
549+ anchors.right: parent.right
550+ anchors.leftMargin: column.anchors.leftMargin == 0 ? staticMargin : 0
551+ font.weight: Font.Light
552+ color: textColor
553+ wrapMode: Text.Wrap
554+ fontSize: "small"
555+ text: i18n.tr("This could take a few minutes...")
556+ }
557+
558+ Rectangle {
559+ anchors.left: parent.left
560+ anchors.leftMargin: column.anchors.leftMargin == 0 ? staticMargin : 0
561+ color: theme.palette.normal.foreground
562+ radius: units.dp(4)
563+ width: buttonLabel.paintedWidth + units.gu(3)
564+ height: buttonLabel.paintedHeight + units.gu(1.8)
565+
566+ Label {
567+ id: buttonLabel
568+ color: textColor
569+ text: i18n.tr("Install and restart now")
570+ font.weight: Font.Light
571+ anchors.centerIn: parent
572+ }
573+
574+ AbstractButton {
575+ id: button
576+ objectName: "installButton"
577+ anchors.fill: parent
578+ onClicked: {
579+ System.skipUntilFinishedPage();
580+ SystemImage.applyUpdate();
581+ }
582+ }
583+
584+ transformOrigin: Item.Top
585+ scale: button.pressed ? 0.98 : 1.0
586+ Behavior on scale {
587+ ScaleAnimator {
588+ duration: UbuntuAnimation.SnapDuration
589+ easing.type: Easing.Linear
590+ }
591+ }
592+ }
593+ }
594+
595+ ActivityIndicator {
596+ id: spinner
597+ anchors.centerIn: systemUpdatePage
598+ running: SystemImage.updateApplying
599+ visible: running
600+ }
601+
602+ Component {
603+ id: forwardButton
604+ LocalComponents.StackButton {
605+ text: i18n.tr("Skip")
606+ onClicked: pageStack.next()
607+ }
608+ }
609+}
610
611=== modified file 'tests/mocks/Ubuntu/SystemImage/MockSystemImage.cpp'
612--- tests/mocks/Ubuntu/SystemImage/MockSystemImage.cpp 2014-07-30 11:08:29 +0000
613+++ tests/mocks/Ubuntu/SystemImage/MockSystemImage.cpp 2016-08-08 10:17:50 +0000
614@@ -1,5 +1,5 @@
615 /*
616- * Copyright (C) 2014 Canonical, Ltd.
617+ * Copyright (C) 2014-2016 Canonical, Ltd.
618 *
619 * This program is free software; you can redistribute it and/or modify
620 * it under the terms of the GNU General Public License as published by
621@@ -14,6 +14,9 @@
622 * along with this program. If not, see <http://www.gnu.org/licenses/>.
623 */
624
625+#include <QDebug>
626+#include <QTimer>
627+
628 #include "MockSystemImage.h"
629
630 MockSystemImage::MockSystemImage(QObject *parent)
631@@ -21,7 +24,27 @@
632 {
633 }
634
635+void MockSystemImage::checkForUpdate()
636+{
637+ qDebug() << "Doing a fake system update check";
638+}
639+
640+void MockSystemImage::applyUpdate()
641+{
642+ qDebug() << "Applying a fake system update";
643+ setUpdateApplying(true);
644+ QTimer::singleShot(3000, [this] {setUpdateApplying(false);});
645+}
646+
647 void MockSystemImage::factoryReset()
648 {
649 Q_EMIT resettingDevice();
650 }
651+
652+void MockSystemImage::setUpdateApplying(bool status)
653+{
654+ if (status != m_updateApplying) {
655+ m_updateApplying = status;
656+ Q_EMIT updateApplyingChanged();
657+ }
658+}
659
660=== modified file 'tests/mocks/Ubuntu/SystemImage/MockSystemImage.h'
661--- tests/mocks/Ubuntu/SystemImage/MockSystemImage.h 2014-07-30 11:08:29 +0000
662+++ tests/mocks/Ubuntu/SystemImage/MockSystemImage.h 2016-08-08 10:17:50 +0000
663@@ -1,5 +1,5 @@
664 /*
665- * Copyright (C) 2014 Canonical, Ltd.
666+ * Copyright (C) 2014-2016 Canonical, Ltd.
667 *
668 * This program is free software; you can redistribute it and/or modify
669 * it under the terms of the GNU General Public License as published by
670@@ -24,13 +24,33 @@
671 Q_OBJECT
672 Q_DISABLE_COPY(MockSystemImage)
673
674+ Q_PROPERTY(bool updateDownloaded READ updateDownloaded CONSTANT)
675+ Q_PROPERTY(QString availableVersion READ availableVersion CONSTANT)
676+ Q_PROPERTY(QString updateSize READ updateSize CONSTANT)
677+ Q_PROPERTY(bool updateApplying READ updateApplying NOTIFY updateApplyingChanged)
678+
679 public:
680- explicit MockSystemImage(QObject *parent = 0);
681+ explicit MockSystemImage(QObject *parent = nullptr);
682
683+ Q_INVOKABLE void checkForUpdate();
684+ Q_INVOKABLE void applyUpdate();
685 Q_INVOKABLE void factoryReset();
686
687+ bool updateApplying() const { return m_updateApplying; }
688+ // these are const only in mock
689+ bool updateDownloaded() const { return true; }
690+ QString availableVersion() const { return QStringLiteral("42"); }
691+ QString updateSize() const { return QStringLiteral("4.2 MB"); }
692+
693 Q_SIGNALS:
694 void resettingDevice(); // only for mock
695+ void updateApplyingChanged();
696+
697+private Q_SLOTS:
698+ void setUpdateApplying(bool status);
699+
700+private:
701+ bool m_updateApplying = false;
702 };
703
704 #endif // MOCK_SYSTEMIMAGE_H
705
706=== modified file 'tests/mocks/Wizard/MockSystem.cpp'
707--- tests/mocks/Wizard/MockSystem.cpp 2016-03-29 03:47:39 +0000
708+++ tests/mocks/Wizard/MockSystem.cpp 2016-08-08 10:17:50 +0000
709@@ -15,6 +15,7 @@
710 */
711
712 #include <QDebug>
713+#include <QSettings>
714
715 #include "MockSystem.h"
716
717@@ -39,3 +40,10 @@
718 {
719 Q_EMIT updateSessionLocaleCalled(locale);
720 }
721+
722+void MockSystem::skipUntilFinishedPage()
723+{
724+ QSettings settings;
725+ settings.setValue(QStringLiteral("Wizard/SkipUntilFinishedPage"), true);
726+ settings.sync();
727+}
728
729=== modified file 'tests/mocks/Wizard/MockSystem.h'
730--- tests/mocks/Wizard/MockSystem.h 2016-03-29 03:47:39 +0000
731+++ tests/mocks/Wizard/MockSystem.h 2016-08-08 10:17:50 +0000
732@@ -33,6 +33,10 @@
733
734 public Q_SLOTS:
735 void updateSessionLocale(const QString &locale);
736+ /**
737+ * Mark the wizard to skip all the pages and just show the last (welcome to ubuntu) page
738+ */
739+ void skipUntilFinishedPage();
740
741 Q_SIGNALS:
742 void wizardEnabledChanged();
743
744=== modified file 'tests/plugins/Wizard/tst_pagelist.cpp'
745--- tests/plugins/Wizard/tst_pagelist.cpp 2015-09-30 13:09:38 +0000
746+++ tests/plugins/Wizard/tst_pagelist.cpp 2016-08-08 10:17:50 +0000
747@@ -20,6 +20,7 @@
748 #include <QObject>
749 #include <QTemporaryDir>
750 #include <QTest>
751+#include <QSettings>
752
753 #define PAGES_PATH "Wizard/Pages"
754
755@@ -28,7 +29,7 @@
756 Q_OBJECT
757
758 public:
759- PageListTest() {};
760+ PageListTest() {}
761
762 private Q_SLOTS:
763 void testCollect();
764@@ -37,6 +38,7 @@
765 void testIgnoreNonQml();
766 void testIgnoreDuplicates();
767 void testDisabled();
768+ void testSkipUntilLastPage();
769
770 private:
771 void fillRoot(const QTemporaryDir &root);
772@@ -150,5 +152,32 @@
773 QCOMPARE(pageList.entries(), QStringList() << "4.qml");
774 }
775
776+void PageListTest::testSkipUntilLastPage() {
777+ PageList * pageList = nullptr;
778+ QTemporaryDir root;
779+ fillRoot(root);
780+
781+ makeFile(root, "a", "1.qml");
782+ makeFile(root, "a", "2.qml");
783+ makeFile(root, "a", "3.qml");
784+
785+ // normal run
786+ pageList = new PageList;
787+ QCOMPARE(pageList->numPages(), 3);
788+ delete pageList; pageList = nullptr;
789+
790+ // after system update had been installed, have the last page only
791+ QSettings settings;
792+ settings.setValue(QStringLiteral("Wizard/SkipUntilFinishedPage"), true);
793+ pageList = new PageList;
794+ QCOMPARE(pageList->entries(), {QStringLiteral("3.qml")}); // only the last page should be in the list
795+ delete pageList; pageList = nullptr;
796+
797+ // normal run again
798+ pageList = new PageList;
799+ QCOMPARE(pageList->numPages(), 3);
800+ delete pageList; pageList = nullptr;
801+}
802+
803 QTEST_MAIN(PageListTest)
804 #include "tst_pagelist.moc"
805
806=== modified file 'tests/qmltests/Wizard/tst_Wizard.qml'
807--- tests/qmltests/Wizard/tst_Wizard.qml 2016-06-29 14:44:41 +0000
808+++ tests/qmltests/Wizard/tst_Wizard.qml 2016-08-08 10:17:50 +0000
809@@ -319,6 +319,8 @@
810 // now finish up
811 page = waitForPage("reportingPage");
812 tap(findChild(page, "forwardButton"));
813+ page = waitForPage("systemUpdatePage");
814+ tap(findChild(page, "forwardButton"));
815 page = waitForPage("finishedPage");
816 waitUntilTransitionsEnd(page);
817 tap(findChild(page, "finishButton"));
818@@ -359,6 +361,8 @@
819 // now finish up
820 page = waitForPage("reportingPage");
821 tap(findChild(page, "forwardButton"));
822+ page = waitForPage("systemUpdatePage");
823+ tap(findChild(page, "forwardButton"));
824 page = waitForPage("finishedPage");
825 waitUntilTransitionsEnd(page);
826 tap(findChild(page, "finishButton"));
827@@ -377,6 +381,8 @@
828 tap(findChild(page, "forwardButton"));
829 page = waitForPage("reportingPage");
830 tap(findChild(page, "forwardButton"));
831+ page = waitForPage("systemUpdatePage");
832+ tap(findChild(page, "forwardButton"));
833 page = waitForPage("finishedPage");
834 waitUntilTransitionsEnd(page);
835 tap(findChild(page, "finishButton"));

Subscribers

People subscribed via source and target branches