on xenial help sign in
Add new accountsservice property DemoEdgesCompleted
c87338bMichael Terry
plugins/AccountsService/AccountsService.cpp+49
@@ -27,6 +27,7 @@ AccountsService::AccountsService(QObject* parent, const QString &user)
27 : QObject(parent),
27 : QObject(parent),
28 m_service(new AccountsServiceDBusAdaptor(this)),
28 m_service(new AccountsServiceDBusAdaptor(this)),
29 m_demoEdges(false),
29 m_demoEdges(false),
30+ m_demoEdgesCompleted(),
30 m_enableLauncherWhileLocked(false),
31 m_enableLauncherWhileLocked(false),
31 m_enableIndicatorsWhileLocked(false),
32 m_enableIndicatorsWhileLocked(false),
32 m_statsWelcomeScreen(false),
33 m_statsWelcomeScreen(false),
@@ -54,6 +55,7 @@ void AccountsService::setUser(const QString &user)
54 m_user = user;
55 m_user = user;
55 Q_EMIT userChanged();
56 Q_EMIT userChanged();
56
57
58+ updateDemoEdgesCompleted(false);
57 updateDemoEdges(false);
59 updateDemoEdges(false);
58 updateEnableLauncherWhileLocked(false);
60 updateEnableLauncherWhileLocked(false);
59 updateEnableIndicatorsWhileLocked(false);
61 updateEnableIndicatorsWhileLocked(false);
@@ -80,6 +82,21 @@ void AccountsService::setDemoEdges(bool demoEdges)
80 }
82 }
81}
83}
82
84
85+QStringList AccountsService::demoEdgesCompleted() const
86+{
87+ return m_demoEdgesCompleted;
88+}
89+
90+void AccountsService::markDemoEdgeCompleted(const QString &edge)
91+{
92+ if (!m_demoEdgesCompleted.contains(edge)) {
93+ m_demoEdgesCompleted << edge;
94+ m_service->setUserProperty(m_user, "com.canonical.unity.AccountsService", "DemoEdgesCompleted", m_demoEdgesCompleted);
95+
96+ Q_EMIT demoEdgesCompletedChanged();
97+ }
98+}
99+
83bool AccountsService::enableLauncherWhileLocked() const
100bool AccountsService::enableLauncherWhileLocked() const
84{
101{
85 return m_enableLauncherWhileLocked;
102 return m_enableLauncherWhileLocked;
@@ -159,6 +176,35 @@ void AccountsService::updateDemoEdges(bool async)
159 }
176 }
160}
177}
161
178
179+void AccountsService::updateDemoEdgesCompleted(bool async)
180+{
181+ QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
182+ "com.canonical.unity.AccountsService",
183+ "DemoEdgesCompleted");
184+ QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
185+
186+ connect(watcher, &QDBusPendingCallWatcher::finished,
187+ this, [this](QDBusPendingCallWatcher* watcher) {
188+
189+ QDBusPendingReply<QDBusVariant> reply = *watcher;
190+ watcher->deleteLater();
191+ if (reply.isError()) {
192+ qWarning() << "Failed to get 'DemoEdgesCompleted' property - " << reply.error().message();
193+ return;
194+ }
195+
196+ auto demoEdgesCompleted = reply.value().variant().toStringList();
197+ if (m_demoEdgesCompleted != demoEdgesCompleted) {
198+ m_demoEdgesCompleted = demoEdgesCompleted;
199+ Q_EMIT demoEdgesCompletedChanged();
200+ }
201+ });
202+ if (!async) {
203+ watcher->waitForFinished();
204+ delete watcher;
205+ }
206+}
207+
162void AccountsService::updateEnableLauncherWhileLocked(bool async)
208void AccountsService::updateEnableLauncherWhileLocked(bool async)
163{
209{
164 QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
210 QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
@@ -419,6 +465,9 @@ void AccountsService::onPropertiesChanged(const QString &user, const QString &in
419 if (changed.contains("demo-edges")) {
465 if (changed.contains("demo-edges")) {
420 updateDemoEdges();
466 updateDemoEdges();
421 }
467 }
468+ if (changed.contains("DemoEdgesCompleted")) {
469+ updateDemoEdgesCompleted();
470+ }
422 } else if (interface == "com.canonical.unity.AccountsService.Private") {
471 } else if (interface == "com.canonical.unity.AccountsService.Private") {
423 if (changed.contains("FailedLogins")) {
472 if (changed.contains("FailedLogins")) {
424 updateFailedLogins();
473 updateFailedLogins();
plugins/AccountsService/AccountsService.h+9
@@ -21,6 +21,7 @@
21
21
22#include <QObject>
22#include <QObject>
23#include <QString>
23#include <QString>
24+#include <QStringList>
24
25
25class AccountsServiceDBusAdaptor;
26class AccountsServiceDBusAdaptor;
26
27
@@ -36,6 +37,9 @@ class AccountsService: public QObject
36 READ demoEdges
37 READ demoEdges
37 WRITE setDemoEdges
38 WRITE setDemoEdges
38 NOTIFY demoEdgesChanged)
39 NOTIFY demoEdgesChanged)
40+ Q_PROPERTY (QStringList demoEdgesCompleted
41+ READ demoEdgesCompleted
42+ NOTIFY demoEdgesCompletedChanged)
39 Q_PROPERTY (bool enableLauncherWhileLocked
43 Q_PROPERTY (bool enableLauncherWhileLocked
40 READ enableLauncherWhileLocked
44 READ enableLauncherWhileLocked
41 NOTIFY enableLauncherWhileLockedChanged)
45 NOTIFY enableLauncherWhileLockedChanged)
@@ -79,6 +83,8 @@ public:
79 void setUser(const QString &user);
83 void setUser(const QString &user);
80 bool demoEdges() const;
84 bool demoEdges() const;
81 void setDemoEdges(bool demoEdges);
85 void setDemoEdges(bool demoEdges);
86+ QStringList demoEdgesCompleted() const;
87+ Q_INVOKABLE void markDemoEdgeCompleted(const QString &edge);
82 bool enableLauncherWhileLocked() const;
88 bool enableLauncherWhileLocked() const;
83 bool enableIndicatorsWhileLocked() const;
89 bool enableIndicatorsWhileLocked() const;
84 QString backgroundFile() const;
90 QString backgroundFile() const;
@@ -94,6 +100,7 @@ public:
94Q_SIGNALS:
100Q_SIGNALS:
95 void userChanged();
101 void userChanged();
96 void demoEdgesChanged();
102 void demoEdgesChanged();
103+ void demoEdgesCompletedChanged();
97 void enableLauncherWhileLockedChanged();
104 void enableLauncherWhileLockedChanged();
98 void enableIndicatorsWhileLockedChanged();
105 void enableIndicatorsWhileLockedChanged();
99 void backgroundFileChanged();
106 void backgroundFileChanged();
@@ -109,6 +116,7 @@ private Q_SLOTS:
109
116
110private:
117private:
111 void updateDemoEdges(bool async = true);
118 void updateDemoEdges(bool async = true);
119+ void updateDemoEdgesCompleted(bool async = true);
112 void updateEnableLauncherWhileLocked(bool async = true);
120 void updateEnableLauncherWhileLocked(bool async = true);
113 void updateEnableIndicatorsWhileLocked(bool async = true);
121 void updateEnableIndicatorsWhileLocked(bool async = true);
114 void updateBackgroundFile(bool async = true);
122 void updateBackgroundFile(bool async = true);
@@ -121,6 +129,7 @@ private:
121 AccountsServiceDBusAdaptor *m_service;
129 AccountsServiceDBusAdaptor *m_service;
122 QString m_user;
130 QString m_user;
123 bool m_demoEdges;
131 bool m_demoEdges;
132+ QStringList m_demoEdgesCompleted;
124 bool m_enableLauncherWhileLocked;
133 bool m_enableLauncherWhileLocked;
125 bool m_enableIndicatorsWhileLocked;
134 bool m_enableIndicatorsWhileLocked;
126 QString m_backgroundFile;
135 QString m_backgroundFile;
plugins/AccountsService/com.canonical.unity.AccountsService.xml+5
@@ -14,6 +14,11 @@
14 <annotation name="org.freedesktop.Accounts.DefaultValue" value="true"/>
14 <annotation name="org.freedesktop.Accounts.DefaultValue" value="true"/>
15 </property>
15 </property>
16
16
17+ <!-- List of tutorial pages that have been completed by the user -->
18+ <property name="DemoEdgesCompleted" type="as" access="readwrite">
19+ <annotation name="org.freedesktop.Accounts.DefaultValue" value="[]"/>
20+ </property>
21+
17 <property name="LauncherItems" type="aa{sv}" access="readwrite">
22 <property name="LauncherItems" type="aa{sv}" access="readwrite">
18 <annotation name="org.freedesktop.Accounts.DefaultValue" value="[{'defaults': <true>}]"/>
23 <annotation name="org.freedesktop.Accounts.DefaultValue" value="[{'defaults': <true>}]"/>
19 </property>
24 </property>
tests/mocks/AccountsService/AccountsService.cpp+20
@@ -28,6 +28,7 @@ AccountsService::AccountsService(QObject* parent)
28 m_statsWelcomeScreen(true),
28 m_statsWelcomeScreen(true),
29 m_failedLogins(0),
29 m_failedLogins(0),
30 m_demoEdges(false),
30 m_demoEdges(false),
31+ m_demoEdgesCompleted(),
31 m_hereEnabled(false),
32 m_hereEnabled(false),
32 m_hereLicensePath("")
33 m_hereLicensePath("")
33{
34{
@@ -56,6 +57,25 @@ void AccountsService::setDemoEdges(bool demoEdges)
56 Q_EMIT demoEdgesChanged();
57 Q_EMIT demoEdgesChanged();
57}
58}
58
59
60+QStringList AccountsService::demoEdgesCompleted() const
61+{
62+ return m_demoEdgesCompleted;
63+}
64+
65+void AccountsService::markDemoEdgeCompleted(const QString &edge)
66+{
67+ if (!m_demoEdgesCompleted.contains(edge)) {
68+ m_demoEdgesCompleted << edge;
69+ Q_EMIT demoEdgesCompletedChanged();
70+ }
71+}
72+
73+void AccountsService::setDemoEdgesCompleted(const QStringList &demoEdgesCompleted)
74+{
75+ m_demoEdgesCompleted = demoEdgesCompleted;
76+ Q_EMIT demoEdgesCompletedChanged();
77+}
78+
59bool AccountsService::enableLauncherWhileLocked() const
79bool AccountsService::enableLauncherWhileLocked() const
60{
80{
61 return m_enableLauncherWhileLocked;
81 return m_enableLauncherWhileLocked;
tests/mocks/AccountsService/AccountsService.h+10
@@ -22,6 +22,7 @@
22
22
23#include <QObject>
23#include <QObject>
24#include <QString>
24#include <QString>
25+#include <QStringList>
25#include <QVariant>
26#include <QVariant>
26
27
27class AccountsService: public QObject
28class AccountsService: public QObject
@@ -36,6 +37,10 @@ class AccountsService: public QObject
36 READ demoEdges
37 READ demoEdges
37 WRITE setDemoEdges
38 WRITE setDemoEdges
38 NOTIFY demoEdgesChanged)
39 NOTIFY demoEdgesChanged)
40+ Q_PROPERTY (QStringList demoEdgesCompleted
41+ READ demoEdgesCompleted
42+ WRITE setDemoEdgesCompleted // only available in mock
43+ NOTIFY demoEdgesCompletedChanged)
39 Q_PROPERTY (bool enableLauncherWhileLocked
44 Q_PROPERTY (bool enableLauncherWhileLocked
40 READ enableLauncherWhileLocked
45 READ enableLauncherWhileLocked
41 WRITE setEnableLauncherWhileLocked // only available in mock
46 WRITE setEnableLauncherWhileLocked // only available in mock
@@ -83,6 +88,9 @@ public:
83 void setUser(const QString &user);
88 void setUser(const QString &user);
84 bool demoEdges() const;
89 bool demoEdges() const;
85 void setDemoEdges(bool demoEdges);
90 void setDemoEdges(bool demoEdges);
91+ QStringList demoEdgesCompleted() const;
92+ void setDemoEdgesCompleted(const QStringList &demoEdges);
93+ Q_INVOKABLE void markDemoEdgeCompleted(const QString &edge);
86 bool enableLauncherWhileLocked() const;
94 bool enableLauncherWhileLocked() const;
87 void setEnableLauncherWhileLocked(bool enableLauncherWhileLocked);
95 void setEnableLauncherWhileLocked(bool enableLauncherWhileLocked);
88 bool enableIndicatorsWhileLocked() const;
96 bool enableIndicatorsWhileLocked() const;
@@ -103,6 +111,7 @@ public:
103Q_SIGNALS:
111Q_SIGNALS:
104 void userChanged();
112 void userChanged();
105 void demoEdgesChanged();
113 void demoEdgesChanged();
114+ void demoEdgesCompletedChanged();
106 void enableLauncherWhileLockedChanged();
115 void enableLauncherWhileLockedChanged();
107 void enableIndicatorsWhileLockedChanged();
116 void enableIndicatorsWhileLockedChanged();
108 void backgroundFileChanged();
117 void backgroundFileChanged();
@@ -120,6 +129,7 @@ private:
120 bool m_statsWelcomeScreen;
129 bool m_statsWelcomeScreen;
121 uint m_failedLogins;
130 uint m_failedLogins;
122 bool m_demoEdges;
131 bool m_demoEdges;
132+ QStringList m_demoEdgesCompleted;
123 bool m_hereEnabled;
133 bool m_hereEnabled;
124 QString m_hereLicensePath;
134 QString m_hereLicensePath;
125};
135};
tests/plugins/AccountsService/PropertiesServer.cpp+1
@@ -71,6 +71,7 @@ void PropertiesServer::Set(const QString &interface, const QString &property, co
71void PropertiesServer::Reset()
71void PropertiesServer::Reset()
72{
72{
73 m_properties["com.canonical.unity.AccountsService"]["demo-edges"] = false;
73 m_properties["com.canonical.unity.AccountsService"]["demo-edges"] = false;
74+ m_properties["com.canonical.unity.AccountsService"]["DemoEdgesCompleted"] = QStringList();
74 m_properties["com.canonical.unity.AccountsService.Private"]["FailedLogins"] = 0;
75 m_properties["com.canonical.unity.AccountsService.Private"]["FailedLogins"] = 0;
75 m_properties["com.ubuntu.touch.AccountsService.SecurityPrivacy"]["StatsWelcomeScreen"] = true;
76 m_properties["com.ubuntu.touch.AccountsService.SecurityPrivacy"]["StatsWelcomeScreen"] = true;
76 m_properties["com.ubuntu.AccountsService.SecurityPrivacy"]["EnableLauncherWhileLocked"] = true;
77 m_properties["com.ubuntu.AccountsService.SecurityPrivacy"]["EnableLauncherWhileLocked"] = true;
tests/plugins/AccountsService/client.cpp+37
@@ -109,6 +109,43 @@ private Q_SLOTS:
109 QCOMPARE(session.hereEnabled(), true);
109 QCOMPARE(session.hereEnabled(), true);
110 }
110 }
111
111
112+ void testMarkDemoEdgeCompleted()
113+ {
114+ AccountsService session(this, QTest::currentTestFunction());
115+ QSignalSpy changedSpy(&session, &AccountsService::demoEdgesCompletedChanged);
116+
117+ QCOMPARE(changedSpy.count(), 0);
118+ QCOMPARE(session.demoEdgesCompleted(), QStringList());
119+
120+ session.markDemoEdgeCompleted("testedge");
121+ QCOMPARE(changedSpy.count(), 1);
122+ QCOMPARE(session.demoEdgesCompleted(), QStringList() << "testedge");
123+
124+ session.markDemoEdgeCompleted("testedge");
125+ QCOMPARE(changedSpy.count(), 1);
126+ QCOMPARE(session.demoEdgesCompleted(), QStringList() << "testedge");
127+
128+ session.markDemoEdgeCompleted("testedge2");
129+ QCOMPARE(changedSpy.count(), 2);
130+ QCOMPARE(session.demoEdgesCompleted(), QStringList() << "testedge" << "testedge2");
131+ }
132+
133+ void testAsynchronousChangeForDemoEdgesCompleted()
134+ {
135+ AccountsService session(this, QTest::currentTestFunction());
136+ QSignalSpy changedSpy(&session, &AccountsService::demoEdgesCompletedChanged);
137+
138+ QCOMPARE(changedSpy.count(), 0);
139+ QCOMPARE(session.demoEdgesCompleted(), QStringList());
140+
141+ ASSERT_DBUS_CALL(m_userInterface->call("Set",
142+ "com.canonical.unity.AccountsService",
143+ "DemoEdgesCompleted",
144+ dbusVariant(QStringList() << "testedge")));
145+ QTRY_COMPARE(changedSpy.count(), 1);
146+ QCOMPARE(session.demoEdgesCompleted(), QStringList() << "testedge");
147+ }
148+
112 void testAsynchornousChangeForDemoEdges()
149 void testAsynchornousChangeForDemoEdges()
113 {
150 {
114 AccountsService session(this, QTest::currentTestFunction());
151 AccountsService session(this, QTest::currentTestFunction());