on 5ade784 help sign in
unity8/plugins/AccountsService/AccountsService.cpp
599 lines 22 kB history raw
1/*
2 * Copyright (C) 2013, 2015 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 */
17#include "AccountsService.h"
18#include "AccountsServiceDBusAdaptor.h"
20#include <QDBusInterface>
21#include <QFile>
22#include <QStringList>
23#include <QDebug>
25AccountsService::AccountsService(QObject* parent, const QString &user)
26 : QObject(parent),
27 m_service(new AccountsServiceDBusAdaptor(this)),
28 m_demoEdges(false),
29 m_enableLauncherWhileLocked(false),
30 m_enableIndicatorsWhileLocked(false),
31 m_statsWelcomeScreen(false),
32 m_passwordDisplayHint(Keyboard),
33 m_failedLogins(0),
34 m_hereEnabled(false),
35 m_hereLicensePath() // null means not set yet
37 m_unityInput = new QDBusInterface(QStringLiteral("com.canonical.Unity.Input"),
38 QStringLiteral("/com/canonical/Unity/Input"),
39 QStringLiteral("com.canonical.Unity.Input"),
40 QDBusConnection::SM_BUSNAME(), this);
42 connect(m_service, &AccountsServiceDBusAdaptor::propertiesChanged, this, &AccountsService::onPropertiesChanged);
43 connect(m_service, &AccountsServiceDBusAdaptor::maybeChanged, this, &AccountsService::onMaybeChanged);
45 setUser(!user.isEmpty() ? user : QString::fromUtf8(qgetenv("USER")));
48QString AccountsService::user() const
50 return m_user;
53void AccountsService::setUser(const QString &user)
55 if (user.isEmpty() || m_user == user)
56 return;
58 m_user = user;
59 Q_EMIT userChanged();
61 updateDemoEdges(false);
62 updateEnableLauncherWhileLocked(false);
63 updateEnableIndicatorsWhileLocked(false);
64 updateBackgroundFile(false);
65 updateMouseCursorSpeed();
66 updateTouchpadCursorSpeed();
67 updateStatsWelcomeScreen(false);
68 updatePasswordDisplayHint(false);
69 updateFailedLogins(false);
70 updateHereEnabled(false);
71 updateHereLicensePath(false);
74bool AccountsService::demoEdges() const
76 return m_demoEdges;
79void AccountsService::setDemoEdges(bool demoEdges)
81 if (m_demoEdges != demoEdges) {
82 m_demoEdges = demoEdges;
83 m_service->setUserPropertyAsync(m_user, QStringLiteral("com.canonical.unity.AccountsService"), QStringLiteral("demo-edges"), demoEdges);
85 Q_EMIT demoEdgesChanged();
86 }
89bool AccountsService::enableLauncherWhileLocked() const
91 return m_enableLauncherWhileLocked;
94bool AccountsService::enableIndicatorsWhileLocked() const
96 return m_enableIndicatorsWhileLocked;
99QString AccountsService::backgroundFile() const
101 return m_backgroundFile;
104bool AccountsService::statsWelcomeScreen() const
106 return m_statsWelcomeScreen;
109AccountsService::PasswordDisplayHint AccountsService::passwordDisplayHint() const
111 return m_passwordDisplayHint;
114bool AccountsService::hereEnabled() const
116 return m_hereEnabled;
119void AccountsService::setHereEnabled(bool enabled)
121 if (m_hereEnabled != enabled) {
122 m_hereEnabled = enabled;
123 m_service->setUserPropertyAsync(m_user, QStringLiteral("com.ubuntu.location.providers.here.AccountsService"), QStringLiteral("LicenseAccepted"), enabled);
125 Q_EMIT hereEnabledChanged();
126 }
129QString AccountsService::hereLicensePath() const
131 return m_hereLicensePath;
134bool AccountsService::hereLicensePathValid() const
136 return !m_hereLicensePath.isNull();
139QString AccountsService::realName() const
141 return m_realName;
144void AccountsService::setRealName(const QString &realName)
146 if (realName != m_realName) {
147 m_realName = realName;
148 m_service->setUserPropertyAsync(m_user, "org.freedesktop.Accounts.User", "RealName", m_realName);
149 Q_EMIT realNameChanged();
150 }
153QString AccountsService::email() const
155 return m_email;
158void AccountsService::setEmail(const QString &email)
160 if (email != m_email) {
161 m_email = email;
162 m_service->setUserPropertyAsync(m_user, "org.freedesktop.Accounts.User", "Email", m_email);
163 Q_EMIT emailChanged();
164 }
167void AccountsService::updateDemoEdges(bool async)
169 QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
170 QStringLiteral("com.canonical.unity.AccountsService"),
171 QStringLiteral("demo-edges"));
172 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
174 connect(watcher, &QDBusPendingCallWatcher::finished,
175 this, [this](QDBusPendingCallWatcher* watcher) {
177 QDBusPendingReply<QVariant> reply = *watcher;
178 watcher->deleteLater();
179 if (reply.isError()) {
180 qWarning() << "Failed to get 'demo-edges' property - " << reply.error().message();
181 return;
182 }
184 const bool demoEdges = reply.value().toBool();
185 if (m_demoEdges != demoEdges) {
186 m_demoEdges = demoEdges;
187 Q_EMIT demoEdgesChanged();
188 }
189 });
190 if (!async) {
191 watcher->waitForFinished();
192 delete watcher;
193 }
196void AccountsService::updateEnableLauncherWhileLocked(bool async)
198 QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
199 QStringLiteral("com.ubuntu.AccountsService.SecurityPrivacy"),
200 QStringLiteral("EnableLauncherWhileLocked"));
201 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
203 connect(watcher, &QDBusPendingCallWatcher::finished,
204 this, [this](QDBusPendingCallWatcher* watcher) {
206 QDBusPendingReply<QVariant> reply = *watcher;
207 watcher->deleteLater();
208 if (reply.isError()) {
209 qWarning() << "Failed to get 'EnableLauncherWhileLocked' property - " << reply.error().message();
210 return;
211 }
213 const bool enableLauncherWhileLocked = reply.value().toBool();
214 if (m_enableLauncherWhileLocked != enableLauncherWhileLocked) {
215 m_enableLauncherWhileLocked = enableLauncherWhileLocked;
216 Q_EMIT enableLauncherWhileLockedChanged();
217 }
218 });
219 if (!async) {
220 watcher->waitForFinished();
221 delete watcher;
222 }
225void AccountsService::updateEnableIndicatorsWhileLocked(bool async)
227 QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
228 QStringLiteral("com.ubuntu.AccountsService.SecurityPrivacy"),
229 QStringLiteral("EnableIndicatorsWhileLocked"));
230 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
232 connect(watcher, &QDBusPendingCallWatcher::finished,
233 this, [this](QDBusPendingCallWatcher* watcher) {
235 QDBusPendingReply<QVariant> reply = *watcher;
236 watcher->deleteLater();
237 if (reply.isError()) {
238 qWarning() << "Failed to get 'EnableIndicatorsWhileLocked' property - " << reply.error().message();
239 return;
240 }
242 const bool enableIndicatorsWhileLocked = reply.value().toBool();
243 if (m_enableIndicatorsWhileLocked != enableIndicatorsWhileLocked) {
244 m_enableIndicatorsWhileLocked = enableIndicatorsWhileLocked;
245 Q_EMIT enableIndicatorsWhileLockedChanged();
246 }
247 });
248 if (!async) {
249 watcher->waitForFinished();
250 delete watcher;
251 }
254void AccountsService::updateBackgroundFile(bool async)
256 QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
257 QStringLiteral("org.freedesktop.Accounts.User"),
258 QStringLiteral("BackgroundFile"));
259 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
261 connect(watcher, &QDBusPendingCallWatcher::finished,
262 this, [this](QDBusPendingCallWatcher* watcher) {
264 QDBusPendingReply<QVariant> reply = *watcher;
265 watcher->deleteLater();
266 if (reply.isError()) {
267 qWarning() << "Failed to get 'BackgroundFile' property - " << reply.error().message();
268 return;
269 }
271 const QString backgroundFile = reply.value().toString();
272 if (m_backgroundFile != backgroundFile) {
273 m_backgroundFile = backgroundFile;
274 Q_EMIT backgroundFileChanged();
275 }
276 });
277 if (!async) {
278 watcher->waitForFinished();
279 delete watcher;
280 }
283void AccountsService::updateMouseCursorSpeed()
285 QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
286 QStringLiteral("com.ubuntu.AccountsService.Input"),
287 QStringLiteral("MouseCursorSpeed"));
288 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
290 connect(watcher, &QDBusPendingCallWatcher::finished,
291 this, [this](QDBusPendingCallWatcher* watcher) {
293 QDBusPendingReply<QVariant> reply = *watcher;
294 watcher->deleteLater();
295 if (reply.isError()) {
296 qWarning() << "Failed to get 'MouseCursorSpeed' property - " << reply.error().message();
297 return;
298 }
300 // Merely proxy this along to USC. We don't care about keeping a copy
301 // or exporting it internally.
302 m_unityInput->asyncCall(QStringLiteral("setMouseCursorSpeed"), reply.value());
303 });
306void AccountsService::updateTouchpadCursorSpeed()
308 QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
309 QStringLiteral("com.ubuntu.AccountsService.Input"),
310 QStringLiteral("TouchpadCursorSpeed"));
311 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
313 connect(watcher, &QDBusPendingCallWatcher::finished,
314 this, [this](QDBusPendingCallWatcher* watcher) {
316 QDBusPendingReply<QVariant> reply = *watcher;
317 watcher->deleteLater();
318 if (reply.isError()) {
319 qWarning() << "Failed to get 'TouchpadCursorSpeed' property - " << reply.error().message();
320 return;
321 }
323 // Merely proxy this along to USC. We don't care about keeping a copy
324 // or exporting it internally.
325 m_unityInput->asyncCall(QStringLiteral("setTouchpadCursorSpeed"), reply.value());
326 });
329void AccountsService::updateStatsWelcomeScreen(bool async)
331 QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
332 QStringLiteral("com.ubuntu.touch.AccountsService.SecurityPrivacy"),
333 QStringLiteral("StatsWelcomeScreen"));
334 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
336 connect(watcher, &QDBusPendingCallWatcher::finished,
337 this, [this](QDBusPendingCallWatcher* watcher) {
339 QDBusPendingReply<QVariant> reply = *watcher;
340 watcher->deleteLater();
341 if (reply.isError()) {
342 qWarning() << "Failed to get 'StatsWelcomeScreen' property - " << reply.error().message();
343 return;
344 }
346 const bool statsWelcomeScreen = reply.value().toBool();
347 if (m_statsWelcomeScreen != statsWelcomeScreen) {
348 m_statsWelcomeScreen = statsWelcomeScreen;
349 Q_EMIT statsWelcomeScreenChanged();
350 }
351 });
352 if (!async) {
353 watcher->waitForFinished();
354 delete watcher;
355 }
358void AccountsService::updatePasswordDisplayHint(bool async)
360 QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
361 QStringLiteral("com.ubuntu.AccountsService.SecurityPrivacy"),
362 QStringLiteral("PasswordDisplayHint"));
363 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
365 connect(watcher, &QDBusPendingCallWatcher::finished,
366 this, [this](QDBusPendingCallWatcher* watcher) {
368 QDBusPendingReply<QVariant> reply = *watcher;
369 watcher->deleteLater();
370 if (reply.isError()) {
371 qWarning() << "Failed to get 'PasswordDisplayHint' property - " << reply.error().message();
372 return;
373 }
375 const PasswordDisplayHint passwordDisplayHint = (PasswordDisplayHint)reply.value().toInt();
376 if (m_passwordDisplayHint != passwordDisplayHint) {
377 m_passwordDisplayHint = passwordDisplayHint;
378 Q_EMIT passwordDisplayHintChanged();
379 }
380 });
381 if (!async) {
382 watcher->waitForFinished();
383 delete watcher;
384 }
387void AccountsService::updateFailedLogins(bool async)
389 QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
390 QStringLiteral("com.canonical.unity.AccountsService.Private"),
391 QStringLiteral("FailedLogins"));
392 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
394 connect(watcher, &QDBusPendingCallWatcher::finished,
395 this, [this](QDBusPendingCallWatcher* watcher) {
397 QDBusPendingReply<QVariant> reply = *watcher;
398 watcher->deleteLater();
399 if (reply.isError()) {
400 qWarning() << "Failed to get 'FailedLogins' property - " << reply.error().message();
401 return;
402 }
404 const uint failedLogins = reply.value().toUInt();
405 if (m_failedLogins != failedLogins) {
406 m_failedLogins = failedLogins;
407 Q_EMIT failedLoginsChanged();
408 }
409 });
410 if (!async) {
411 watcher->waitForFinished();
412 delete watcher;
413 }
416void AccountsService::updateHereEnabled(bool async)
418 QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
419 QStringLiteral("com.ubuntu.location.providers.here.AccountsService"),
420 QStringLiteral("LicenseAccepted"));
421 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
423 connect(watcher, &QDBusPendingCallWatcher::finished,
424 this, [this](QDBusPendingCallWatcher* watcher) {
426 QDBusPendingReply<QVariant> reply = *watcher;
427 watcher->deleteLater();
428 if (reply.isError()) {
429 qWarning() << "Failed to get 'LicenseAccepted' property - " << reply.error().message();
430 return;
431 }
433 const bool hereEnabled = reply.value().toBool();
434 if (m_hereEnabled != hereEnabled) {
435 m_hereEnabled = hereEnabled;
436 Q_EMIT hereEnabledChanged();
437 }
438 });
439 if (!async) {
440 watcher->waitForFinished();
441 delete watcher;
442 }
445void AccountsService::updateHereLicensePath(bool async)
447 QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
448 QStringLiteral("com.ubuntu.location.providers.here.AccountsService"),
449 QStringLiteral("LicenseBasePath"));
450 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
452 connect(watcher, &QDBusPendingCallWatcher::finished,
453 this, [this](QDBusPendingCallWatcher* watcher) {
455 QDBusPendingReply<QVariant> reply = *watcher;
456 watcher->deleteLater();
457 if (reply.isError()) {
458 qWarning() << "Failed to get 'LicenseBasePath' property - " << reply.error().message();
459 return;
460 }
462 QString hereLicensePath = reply.value().toString();
463 if (hereLicensePath.isEmpty() || !QFile::exists(hereLicensePath))
464 hereLicensePath = QLatin1String("");
466 if (m_hereLicensePath.isNull() || m_hereLicensePath != hereLicensePath) {
467 m_hereLicensePath = hereLicensePath;
468 Q_EMIT hereLicensePathChanged();
469 }
470 });
471 if (!async) {
472 watcher->waitForFinished();
473 delete watcher;
474 }
477void AccountsService::updateRealName(bool async)
479 QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user, "org.freedesktop.Accounts.User", "RealName");
480 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
482 connect(watcher, &QDBusPendingCallWatcher::finished,
483 this, [this](QDBusPendingCallWatcher* watcher) {
484 QDBusPendingReply<QVariant> reply = *watcher;
485 watcher->deleteLater();
486 if (reply.isError()) {
487 qWarning() << "Failed to get 'RealName' property - " << reply.error().message();
488 return;
489 }
491 const QString realName = reply.value().toString();
492 if (m_realName != realName) {
493 m_realName = realName;
494 Q_EMIT realNameChanged();
495 }
496 });
497 if (!async) {
498 watcher->waitForFinished();
499 delete watcher;
500 }
503void AccountsService::updateEmail(bool async)
505 QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user, "org.freedesktop.Accounts.User", "Email");
506 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
508 connect(watcher, &QDBusPendingCallWatcher::finished,
509 this, [this](QDBusPendingCallWatcher* watcher) {
510 QDBusPendingReply<QVariant> reply = *watcher;
511 watcher->deleteLater();
512 if (reply.isError()) {
513 qWarning() << "Failed to get 'Email' property - " << reply.error().message();
514 return;
515 }
517 const QString email = reply.value().toString();
518 if (m_email != email) {
519 m_email = email;
520 Q_EMIT emailChanged();
521 }
522 });
523 if (!async) {
524 watcher->waitForFinished();
525 delete watcher;
526 }
529uint AccountsService::failedLogins() const
531 return m_failedLogins;
534void AccountsService::setFailedLogins(uint failedLogins)
536 if (m_failedLogins != failedLogins) {
537 m_failedLogins = failedLogins;
538 m_service->setUserPropertyAsync(m_user, QStringLiteral("com.canonical.unity.AccountsService.Private"), QStringLiteral("FailedLogins"), failedLogins);
540 Q_EMIT failedLoginsChanged();
541 }
544void AccountsService::onPropertiesChanged(const QString &user, const QString &interface, const QStringList &changed)
546 if (m_user != user) {
547 return;
548 }
550 if (interface == QLatin1String("com.canonical.unity.AccountsService")) {
551 if (changed.contains(QStringLiteral("demo-edges"))) {
552 updateDemoEdges();
553 }
554 } else if (interface == QLatin1String("com.canonical.unity.AccountsService.Private")) {
555 if (changed.contains(QStringLiteral("FailedLogins"))) {
556 updateFailedLogins();
557 }
558 } else if (interface == QLatin1String("com.ubuntu.AccountsService.Input")) {
559 if (changed.contains(QStringLiteral("MouseCursorSpeed"))) {
560 updateMouseCursorSpeed();
561 }
562 if (changed.contains(QStringLiteral("TouchpadCursorSpeed"))) {
563 updateTouchpadCursorSpeed();
564 }
565 } else if (interface == QLatin1String("com.ubuntu.touch.AccountsService.SecurityPrivacy")) {
566 if (changed.contains(QStringLiteral("StatsWelcomeScreen"))) {
567 updateStatsWelcomeScreen();
568 }
569 } else if (interface == QLatin1String("com.ubuntu.AccountsService.SecurityPrivacy")) {
570 if (changed.contains(QStringLiteral("PasswordDisplayHint"))) {
571 updatePasswordDisplayHint();
572 }
573 if (changed.contains(QStringLiteral("EnableLauncherWhileLocked"))) {
574 updateEnableLauncherWhileLocked();
575 }
576 if (changed.contains(QStringLiteral("EnableIndicatorsWhileLocked"))) {
577 updateEnableIndicatorsWhileLocked();
578 }
579 } else if (interface == QLatin1String("com.ubuntu.location.providers.here.AccountsService")) {
580 if (changed.contains(QStringLiteral("LicenseAccepted"))) {
581 updateHereEnabled();
582 }
583 if (changed.contains(QStringLiteral("LicenseBasePath"))) {
584 updateHereLicensePath();
585 }
586 }
589void AccountsService::onMaybeChanged(const QString &user)
591 if (m_user != user) {
592 return;
593 }
595 // Standard properties might have changed
596 updateBackgroundFile();
597 updateRealName();
598 updateEmail();