on 90c8d36 help sign in
unity8/plugins/AccountsService/AccountsService.cpp
507 lines 18 kB history raw
1/*
2 * Copyright (C) 2013 Canonical, Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Author: Michael Terry <michael.terry@canonical.com>
17 */
19#include "AccountsService.h"
20#include "AccountsServiceDBusAdaptor.h"
22#include <QFile>
23#include <QStringList>
24#include <QDebug>
26AccountsService::AccountsService(QObject* parent, const QString &user)
27 : QObject(parent),
28 m_service(new AccountsServiceDBusAdaptor(this)),
29 m_demoEdges(false),
30 m_demoEdgesCompleted(),
31 m_enableLauncherWhileLocked(false),
32 m_enableIndicatorsWhileLocked(false),
33 m_statsWelcomeScreen(false),
34 m_passwordDisplayHint(Keyboard),
35 m_failedLogins(0),
36 m_hereEnabled(false),
37 m_hereLicensePath() // null means not set yet
39 connect(m_service, &AccountsServiceDBusAdaptor::propertiesChanged, this, &AccountsService::onPropertiesChanged);
40 connect(m_service, &AccountsServiceDBusAdaptor::maybeChanged, this, &AccountsService::onMaybeChanged);
42 setUser(!user.isEmpty() ? user : QString::fromUtf8(qgetenv("USER")));
45QString AccountsService::user() const
47 return m_user;
50void AccountsService::setUser(const QString &user)
52 if (user.isEmpty() || m_user == user)
53 return;
55 m_user = user;
56 Q_EMIT userChanged();
58 updateDemoEdgesCompleted(false);
59 updateDemoEdges(false);
60 updateEnableLauncherWhileLocked(false);
61 updateEnableIndicatorsWhileLocked(false);
62 updateBackgroundFile(false);
63 updateStatsWelcomeScreen(false);
64 updatePasswordDisplayHint(false);
65 updateFailedLogins(false);
66 updateHereEnabled(false);
67 updateHereLicensePath(false);
70bool AccountsService::demoEdges() const
72 return m_demoEdges;
75void AccountsService::setDemoEdges(bool demoEdges)
77 if (m_demoEdges != demoEdges) {
78 m_demoEdges = demoEdges;
79 m_service->setUserPropertyAsync(m_user, QStringLiteral("com.canonical.unity.AccountsService"), QStringLiteral("demo-edges"), demoEdges);
81 Q_EMIT demoEdgesChanged();
82 }
85QStringList AccountsService::demoEdgesCompleted() const
87 return m_demoEdgesCompleted;
90void AccountsService::markDemoEdgeCompleted(const QString &edge)
92 if (!m_demoEdgesCompleted.contains(edge)) {
93 m_demoEdgesCompleted << edge;
94 m_service->setUserPropertyAsync(m_user, "com.canonical.unity.AccountsService", "DemoEdgesCompleted", m_demoEdgesCompleted);
96 Q_EMIT demoEdgesCompletedChanged();
97 }
100bool AccountsService::enableLauncherWhileLocked() const
102 return m_enableLauncherWhileLocked;
105bool AccountsService::enableIndicatorsWhileLocked() const
107 return m_enableIndicatorsWhileLocked;
110QString AccountsService::backgroundFile() const
112 return m_backgroundFile;
115bool AccountsService::statsWelcomeScreen() const
117 return m_statsWelcomeScreen;
120AccountsService::PasswordDisplayHint AccountsService::passwordDisplayHint() const
122 return m_passwordDisplayHint;
125bool AccountsService::hereEnabled() const
127 return m_hereEnabled;
130void AccountsService::setHereEnabled(bool enabled)
132 if (m_hereEnabled != enabled) {
133 m_hereEnabled = enabled;
134 m_service->setUserPropertyAsync(m_user, QStringLiteral("com.ubuntu.location.providers.here.AccountsService"), QStringLiteral("LicenseAccepted"), enabled);
136 Q_EMIT hereEnabledChanged();
137 }
140QString AccountsService::hereLicensePath() const
142 return m_hereLicensePath;
145bool AccountsService::hereLicensePathValid() const
147 return !m_hereLicensePath.isNull();
150void AccountsService::updateDemoEdges(bool async)
152 QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
153 QStringLiteral("com.canonical.unity.AccountsService"),
154 QStringLiteral("demo-edges"));
155 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
157 connect(watcher, &QDBusPendingCallWatcher::finished,
158 this, [this](QDBusPendingCallWatcher* watcher) {
160 QDBusPendingReply<QDBusVariant> reply = *watcher;
161 watcher->deleteLater();
162 if (reply.isError()) {
163 qWarning() << "Failed to get 'demo-edges' property - " << reply.error().message();
164 return;
165 }
167 auto demoEdges = reply.value().variant().toBool();
168 if (m_demoEdges != demoEdges) {
169 m_demoEdges = demoEdges;
170 Q_EMIT demoEdgesChanged();
171 }
172 });
173 if (!async) {
174 watcher->waitForFinished();
175 delete watcher;
176 }
179void AccountsService::updateDemoEdgesCompleted(bool async)
181 QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
182 "com.canonical.unity.AccountsService",
183 "DemoEdgesCompleted");
184 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
186 connect(watcher, &QDBusPendingCallWatcher::finished,
187 this, [this](QDBusPendingCallWatcher* watcher) {
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 }
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 }
208void AccountsService::updateEnableLauncherWhileLocked(bool async)
210 QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
211 QStringLiteral("com.ubuntu.AccountsService.SecurityPrivacy"),
212 QStringLiteral("EnableLauncherWhileLocked"));
213 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
215 connect(watcher, &QDBusPendingCallWatcher::finished,
216 this, [this](QDBusPendingCallWatcher* watcher) {
218 QDBusPendingReply<QVariant> reply = *watcher;
219 watcher->deleteLater();
220 if (reply.isError()) {
221 qWarning() << "Failed to get 'EnableLauncherWhileLocked' property - " << reply.error().message();
222 return;
223 }
225 const bool enableLauncherWhileLocked = reply.value().toBool();
226 if (m_enableLauncherWhileLocked != enableLauncherWhileLocked) {
227 m_enableLauncherWhileLocked = enableLauncherWhileLocked;
228 Q_EMIT enableLauncherWhileLockedChanged();
229 }
230 });
231 if (!async) {
232 watcher->waitForFinished();
233 delete watcher;
234 }
237void AccountsService::updateEnableIndicatorsWhileLocked(bool async)
239 QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
240 QStringLiteral("com.ubuntu.AccountsService.SecurityPrivacy"),
241 QStringLiteral("EnableIndicatorsWhileLocked"));
242 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
244 connect(watcher, &QDBusPendingCallWatcher::finished,
245 this, [this](QDBusPendingCallWatcher* watcher) {
247 QDBusPendingReply<QVariant> reply = *watcher;
248 watcher->deleteLater();
249 if (reply.isError()) {
250 qWarning() << "Failed to get 'EnableIndicatorsWhileLocked' property - " << reply.error().message();
251 return;
252 }
254 const bool enableIndicatorsWhileLocked = reply.value().toBool();
255 if (m_enableIndicatorsWhileLocked != enableIndicatorsWhileLocked) {
256 m_enableIndicatorsWhileLocked = enableIndicatorsWhileLocked;
257 Q_EMIT enableIndicatorsWhileLockedChanged();
258 }
259 });
260 if (!async) {
261 watcher->waitForFinished();
262 delete watcher;
263 }
266void AccountsService::updateBackgroundFile(bool async)
268 QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
269 QStringLiteral("org.freedesktop.Accounts.User"),
270 QStringLiteral("BackgroundFile"));
271 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
273 connect(watcher, &QDBusPendingCallWatcher::finished,
274 this, [this](QDBusPendingCallWatcher* watcher) {
276 QDBusPendingReply<QVariant> reply = *watcher;
277 watcher->deleteLater();
278 if (reply.isError()) {
279 qWarning() << "Failed to get 'BackgroundFile' property - " << reply.error().message();
280 return;
281 }
283 const QString backgroundFile = reply.value().toString();
284 if (m_backgroundFile != backgroundFile) {
285 m_backgroundFile = backgroundFile;
286 Q_EMIT backgroundFileChanged();
287 }
288 });
289 if (!async) {
290 watcher->waitForFinished();
291 delete watcher;
292 }
295void AccountsService::updateStatsWelcomeScreen(bool async)
297 QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
298 QStringLiteral("com.ubuntu.touch.AccountsService.SecurityPrivacy"),
299 QStringLiteral("StatsWelcomeScreen"));
300 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
302 connect(watcher, &QDBusPendingCallWatcher::finished,
303 this, [this](QDBusPendingCallWatcher* watcher) {
305 QDBusPendingReply<QVariant> reply = *watcher;
306 watcher->deleteLater();
307 if (reply.isError()) {
308 qWarning() << "Failed to get 'StatsWelcomeScreen' property - " << reply.error().message();
309 return;
310 }
312 const bool statsWelcomeScreen = reply.value().toBool();
313 if (m_statsWelcomeScreen != statsWelcomeScreen) {
314 m_statsWelcomeScreen = statsWelcomeScreen;
315 Q_EMIT statsWelcomeScreenChanged();
316 }
317 });
318 if (!async) {
319 watcher->waitForFinished();
320 delete watcher;
321 }
324void AccountsService::updatePasswordDisplayHint(bool async)
326 QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
327 QStringLiteral("com.ubuntu.AccountsService.SecurityPrivacy"),
328 QStringLiteral("PasswordDisplayHint"));
329 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
331 connect(watcher, &QDBusPendingCallWatcher::finished,
332 this, [this](QDBusPendingCallWatcher* watcher) {
334 QDBusPendingReply<QVariant> reply = *watcher;
335 watcher->deleteLater();
336 if (reply.isError()) {
337 qWarning() << "Failed to get 'PasswordDisplayHint' property - " << reply.error().message();
338 return;
339 }
341 const PasswordDisplayHint passwordDisplayHint = (PasswordDisplayHint)reply.value().toInt();
342 if (m_passwordDisplayHint != passwordDisplayHint) {
343 m_passwordDisplayHint = passwordDisplayHint;
344 Q_EMIT passwordDisplayHintChanged();
345 }
346 });
347 if (!async) {
348 watcher->waitForFinished();
349 delete watcher;
350 }
353void AccountsService::updateFailedLogins(bool async)
355 QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
356 QStringLiteral("com.canonical.unity.AccountsService.Private"),
357 QStringLiteral("FailedLogins"));
358 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
360 connect(watcher, &QDBusPendingCallWatcher::finished,
361 this, [this](QDBusPendingCallWatcher* watcher) {
363 QDBusPendingReply<QVariant> reply = *watcher;
364 watcher->deleteLater();
365 if (reply.isError()) {
366 qWarning() << "Failed to get 'FailedLogins' property - " << reply.error().message();
367 return;
368 }
370 const uint failedLogins = reply.value().toUInt();
371 if (m_failedLogins != failedLogins) {
372 m_failedLogins = failedLogins;
373 Q_EMIT failedLoginsChanged();
374 }
375 });
376 if (!async) {
377 watcher->waitForFinished();
378 delete watcher;
379 }
382void AccountsService::updateHereEnabled(bool async)
384 QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
385 QStringLiteral("com.ubuntu.location.providers.here.AccountsService"),
386 QStringLiteral("LicenseAccepted"));
387 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
389 connect(watcher, &QDBusPendingCallWatcher::finished,
390 this, [this](QDBusPendingCallWatcher* watcher) {
392 QDBusPendingReply<QVariant> reply = *watcher;
393 watcher->deleteLater();
394 if (reply.isError()) {
395 qWarning() << "Failed to get 'LicenseAccepted' property - " << reply.error().message();
396 return;
397 }
399 const bool hereEnabled = reply.value().toBool();
400 if (m_hereEnabled != hereEnabled) {
401 m_hereEnabled = hereEnabled;
402 Q_EMIT hereEnabledChanged();
403 }
404 });
405 if (!async) {
406 watcher->waitForFinished();
407 delete watcher;
408 }
411void AccountsService::updateHereLicensePath(bool async)
413 QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
414 QStringLiteral("com.ubuntu.location.providers.here.AccountsService"),
415 QStringLiteral("LicenseBasePath"));
416 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
418 connect(watcher, &QDBusPendingCallWatcher::finished,
419 this, [this](QDBusPendingCallWatcher* watcher) {
421 QDBusPendingReply<QVariant> reply = *watcher;
422 watcher->deleteLater();
423 if (reply.isError()) {
424 qWarning() << "Failed to get 'LicenseBasePath' property - " << reply.error().message();
425 return;
426 }
428 QString hereLicensePath = reply.value().toString();
429 if (hereLicensePath.isEmpty() || !QFile::exists(hereLicensePath))
430 hereLicensePath = QLatin1String("");
432 if (m_hereLicensePath.isNull() || m_hereLicensePath != hereLicensePath) {
433 m_hereLicensePath = hereLicensePath;
434 Q_EMIT hereLicensePathChanged();
435 }
436 });
437 if (!async) {
438 watcher->waitForFinished();
439 delete watcher;
440 }
443uint AccountsService::failedLogins() const
445 return m_failedLogins;
448void AccountsService::setFailedLogins(uint failedLogins)
450 if (m_failedLogins != failedLogins) {
451 m_failedLogins = failedLogins;
452 m_service->setUserPropertyAsync(m_user, QStringLiteral("com.canonical.unity.AccountsService.Private"), QStringLiteral("FailedLogins"), failedLogins);
454 Q_EMIT failedLoginsChanged();
455 }
458void AccountsService::onPropertiesChanged(const QString &user, const QString &interface, const QStringList &changed)
460 if (m_user != user) {
461 return;
462 }
464 if (interface == QLatin1String("com.canonical.unity.AccountsService")) {
465 if (changed.contains(QStringLiteral("demo-edges"))) {
466 updateDemoEdges();
467 }
468 if (changed.contains(QStringLiteral("DemoEdgesCompleted"))) {
469 updateDemoEdgesCompleted();
470 }
471 } else if (interface == QLatin1String("com.canonical.unity.AccountsService.Private")) {
472 if (changed.contains(QStringLiteral("FailedLogins"))) {
473 updateFailedLogins();
474 }
475 } else if (interface == QLatin1String("com.ubuntu.touch.AccountsService.SecurityPrivacy")) {
476 if (changed.contains(QStringLiteral("StatsWelcomeScreen"))) {
477 updateStatsWelcomeScreen();
478 }
479 } else if (interface == QLatin1String("com.ubuntu.AccountsService.SecurityPrivacy")) {
480 if (changed.contains(QStringLiteral("PasswordDisplayHint"))) {
481 updatePasswordDisplayHint();
482 }
483 if (changed.contains(QStringLiteral("EnableLauncherWhileLocked"))) {
484 updateEnableLauncherWhileLocked();
485 }
486 if (changed.contains(QStringLiteral("EnableIndicatorsWhileLocked"))) {
487 updateEnableIndicatorsWhileLocked();
488 }
489 } else if (interface == QLatin1String("com.ubuntu.location.providers.here.AccountsService")) {
490 if (changed.contains(QStringLiteral("LicenseAccepted"))) {
491 updateHereEnabled();
492 }
493 if (changed.contains(QStringLiteral("LicenseBasePath"))) {
494 updateHereLicensePath();
495 }
496 }
499void AccountsService::onMaybeChanged(const QString &user)
501 if (m_user != user) {
502 return;
503 }
505 // Standard properties might have changed
506 updateBackgroundFile();