on 98f679c help sign in
unity8/plugins/AccountsService/AccountsService.cpp
519 lines 19 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 <QDBusInterface>
23#include <QFile>
24#include <QStringList>
25#include <QDebug>
27AccountsService::AccountsService(QObject* parent, const QString &user)
28 : QObject(parent),
29 m_service(new AccountsServiceDBusAdaptor(this)),
30 m_demoEdges(false),
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 m_unityInput = new QDBusInterface(QStringLiteral("com.canonical.Unity.Input"),
40 QStringLiteral("/com/canonical/Unity/Input"),
41 QStringLiteral("com.canonical.Unity.Input"),
42 QDBusConnection::SM_BUSNAME(), this);
44 connect(m_service, &AccountsServiceDBusAdaptor::propertiesChanged, this, &AccountsService::onPropertiesChanged);
45 connect(m_service, &AccountsServiceDBusAdaptor::maybeChanged, this, &AccountsService::onMaybeChanged);
47 setUser(!user.isEmpty() ? user : QString::fromUtf8(qgetenv("USER")));
50QString AccountsService::user() const
52 return m_user;
55void AccountsService::setUser(const QString &user)
57 if (user.isEmpty() || m_user == user)
58 return;
60 m_user = user;
61 Q_EMIT userChanged();
63 updateDemoEdges(false);
64 updateEnableLauncherWhileLocked(false);
65 updateEnableIndicatorsWhileLocked(false);
66 updateBackgroundFile(false);
67 updateMouseCursorSpeed();
68 updateTouchpadCursorSpeed();
69 updateStatsWelcomeScreen(false);
70 updatePasswordDisplayHint(false);
71 updateFailedLogins(false);
72 updateHereEnabled(false);
73 updateHereLicensePath(false);
76bool AccountsService::demoEdges() const
78 return m_demoEdges;
81void AccountsService::setDemoEdges(bool demoEdges)
83 if (m_demoEdges != demoEdges) {
84 m_demoEdges = demoEdges;
85 m_service->setUserPropertyAsync(m_user, QStringLiteral("com.canonical.unity.AccountsService"), QStringLiteral("demo-edges"), demoEdges);
87 Q_EMIT demoEdgesChanged();
88 }
91bool AccountsService::enableLauncherWhileLocked() const
93 return m_enableLauncherWhileLocked;
96bool AccountsService::enableIndicatorsWhileLocked() const
98 return m_enableIndicatorsWhileLocked;
101QString AccountsService::backgroundFile() const
103 return m_backgroundFile;
106bool AccountsService::statsWelcomeScreen() const
108 return m_statsWelcomeScreen;
111AccountsService::PasswordDisplayHint AccountsService::passwordDisplayHint() const
113 return m_passwordDisplayHint;
116bool AccountsService::hereEnabled() const
118 return m_hereEnabled;
121void AccountsService::setHereEnabled(bool enabled)
123 if (m_hereEnabled != enabled) {
124 m_hereEnabled = enabled;
125 m_service->setUserPropertyAsync(m_user, QStringLiteral("com.ubuntu.location.providers.here.AccountsService"), QStringLiteral("LicenseAccepted"), enabled);
127 Q_EMIT hereEnabledChanged();
128 }
131QString AccountsService::hereLicensePath() const
133 return m_hereLicensePath;
136bool AccountsService::hereLicensePathValid() const
138 return !m_hereLicensePath.isNull();
141void AccountsService::updateDemoEdges(bool async)
143 QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
144 QStringLiteral("com.canonical.unity.AccountsService"),
145 QStringLiteral("demo-edges"));
146 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
148 connect(watcher, &QDBusPendingCallWatcher::finished,
149 this, [this](QDBusPendingCallWatcher* watcher) {
151 QDBusPendingReply<QDBusVariant> reply = *watcher;
152 watcher->deleteLater();
153 if (reply.isError()) {
154 qWarning() << "Failed to get 'demo-edges' property - " << reply.error().message();
155 return;
156 }
158 auto demoEdges = reply.value().variant().toBool();
159 if (m_demoEdges != demoEdges) {
160 m_demoEdges = demoEdges;
161 Q_EMIT demoEdgesChanged();
162 }
163 });
164 if (!async) {
165 watcher->waitForFinished();
166 delete watcher;
167 }
170void AccountsService::updateEnableLauncherWhileLocked(bool async)
172 QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
173 QStringLiteral("com.ubuntu.AccountsService.SecurityPrivacy"),
174 QStringLiteral("EnableLauncherWhileLocked"));
175 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
177 connect(watcher, &QDBusPendingCallWatcher::finished,
178 this, [this](QDBusPendingCallWatcher* watcher) {
180 QDBusPendingReply<QVariant> reply = *watcher;
181 watcher->deleteLater();
182 if (reply.isError()) {
183 qWarning() << "Failed to get 'EnableLauncherWhileLocked' property - " << reply.error().message();
184 return;
185 }
187 const bool enableLauncherWhileLocked = reply.value().toBool();
188 if (m_enableLauncherWhileLocked != enableLauncherWhileLocked) {
189 m_enableLauncherWhileLocked = enableLauncherWhileLocked;
190 Q_EMIT enableLauncherWhileLockedChanged();
191 }
192 });
193 if (!async) {
194 watcher->waitForFinished();
195 delete watcher;
196 }
199void AccountsService::updateEnableIndicatorsWhileLocked(bool async)
201 QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
202 QStringLiteral("com.ubuntu.AccountsService.SecurityPrivacy"),
203 QStringLiteral("EnableIndicatorsWhileLocked"));
204 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
206 connect(watcher, &QDBusPendingCallWatcher::finished,
207 this, [this](QDBusPendingCallWatcher* watcher) {
209 QDBusPendingReply<QVariant> reply = *watcher;
210 watcher->deleteLater();
211 if (reply.isError()) {
212 qWarning() << "Failed to get 'EnableIndicatorsWhileLocked' property - " << reply.error().message();
213 return;
214 }
216 const bool enableIndicatorsWhileLocked = reply.value().toBool();
217 if (m_enableIndicatorsWhileLocked != enableIndicatorsWhileLocked) {
218 m_enableIndicatorsWhileLocked = enableIndicatorsWhileLocked;
219 Q_EMIT enableIndicatorsWhileLockedChanged();
220 }
221 });
222 if (!async) {
223 watcher->waitForFinished();
224 delete watcher;
225 }
228void AccountsService::updateBackgroundFile(bool async)
230 QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
231 QStringLiteral("org.freedesktop.Accounts.User"),
232 QStringLiteral("BackgroundFile"));
233 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
235 connect(watcher, &QDBusPendingCallWatcher::finished,
236 this, [this](QDBusPendingCallWatcher* watcher) {
238 QDBusPendingReply<QVariant> reply = *watcher;
239 watcher->deleteLater();
240 if (reply.isError()) {
241 qWarning() << "Failed to get 'BackgroundFile' property - " << reply.error().message();
242 return;
243 }
245 const QString backgroundFile = reply.value().toString();
246 if (m_backgroundFile != backgroundFile) {
247 m_backgroundFile = backgroundFile;
248 Q_EMIT backgroundFileChanged();
249 }
250 });
251 if (!async) {
252 watcher->waitForFinished();
253 delete watcher;
254 }
257void AccountsService::updateMouseCursorSpeed()
259 QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
260 QStringLiteral("com.ubuntu.AccountsService.Input"),
261 QStringLiteral("MouseCursorSpeed"));
262 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
264 connect(watcher, &QDBusPendingCallWatcher::finished,
265 this, [this](QDBusPendingCallWatcher* watcher) {
267 QDBusPendingReply<QVariant> reply = *watcher;
268 watcher->deleteLater();
269 if (reply.isError()) {
270 qWarning() << "Failed to get 'MouseCursorSpeed' property - " << reply.error().message();
271 return;
272 }
274 // Merely proxy this along to USC. We don't care about keeping a copy
275 // or exporting it internally.
276 m_unityInput->asyncCall(QStringLiteral("setMouseCursorSpeed"), reply.value());
277 });
280void AccountsService::updateTouchpadCursorSpeed()
282 QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
283 QStringLiteral("com.ubuntu.AccountsService.Input"),
284 QStringLiteral("TouchpadCursorSpeed"));
285 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
287 connect(watcher, &QDBusPendingCallWatcher::finished,
288 this, [this](QDBusPendingCallWatcher* watcher) {
290 QDBusPendingReply<QVariant> reply = *watcher;
291 watcher->deleteLater();
292 if (reply.isError()) {
293 qWarning() << "Failed to get 'TouchpadCursorSpeed' property - " << reply.error().message();
294 return;
295 }
297 // Merely proxy this along to USC. We don't care about keeping a copy
298 // or exporting it internally.
299 m_unityInput->asyncCall(QStringLiteral("setTouchpadCursorSpeed"), reply.value());
300 });
303void AccountsService::updateStatsWelcomeScreen(bool async)
305 QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
306 QStringLiteral("com.ubuntu.touch.AccountsService.SecurityPrivacy"),
307 QStringLiteral("StatsWelcomeScreen"));
308 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
310 connect(watcher, &QDBusPendingCallWatcher::finished,
311 this, [this](QDBusPendingCallWatcher* watcher) {
313 QDBusPendingReply<QVariant> reply = *watcher;
314 watcher->deleteLater();
315 if (reply.isError()) {
316 qWarning() << "Failed to get 'StatsWelcomeScreen' property - " << reply.error().message();
317 return;
318 }
320 const bool statsWelcomeScreen = reply.value().toBool();
321 if (m_statsWelcomeScreen != statsWelcomeScreen) {
322 m_statsWelcomeScreen = statsWelcomeScreen;
323 Q_EMIT statsWelcomeScreenChanged();
324 }
325 });
326 if (!async) {
327 watcher->waitForFinished();
328 delete watcher;
329 }
332void AccountsService::updatePasswordDisplayHint(bool async)
334 QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
335 QStringLiteral("com.ubuntu.AccountsService.SecurityPrivacy"),
336 QStringLiteral("PasswordDisplayHint"));
337 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
339 connect(watcher, &QDBusPendingCallWatcher::finished,
340 this, [this](QDBusPendingCallWatcher* watcher) {
342 QDBusPendingReply<QVariant> reply = *watcher;
343 watcher->deleteLater();
344 if (reply.isError()) {
345 qWarning() << "Failed to get 'PasswordDisplayHint' property - " << reply.error().message();
346 return;
347 }
349 const PasswordDisplayHint passwordDisplayHint = (PasswordDisplayHint)reply.value().toInt();
350 if (m_passwordDisplayHint != passwordDisplayHint) {
351 m_passwordDisplayHint = passwordDisplayHint;
352 Q_EMIT passwordDisplayHintChanged();
353 }
354 });
355 if (!async) {
356 watcher->waitForFinished();
357 delete watcher;
358 }
361void AccountsService::updateFailedLogins(bool async)
363 QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
364 QStringLiteral("com.canonical.unity.AccountsService.Private"),
365 QStringLiteral("FailedLogins"));
366 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
368 connect(watcher, &QDBusPendingCallWatcher::finished,
369 this, [this](QDBusPendingCallWatcher* watcher) {
371 QDBusPendingReply<QVariant> reply = *watcher;
372 watcher->deleteLater();
373 if (reply.isError()) {
374 qWarning() << "Failed to get 'FailedLogins' property - " << reply.error().message();
375 return;
376 }
378 const uint failedLogins = reply.value().toUInt();
379 if (m_failedLogins != failedLogins) {
380 m_failedLogins = failedLogins;
381 Q_EMIT failedLoginsChanged();
382 }
383 });
384 if (!async) {
385 watcher->waitForFinished();
386 delete watcher;
387 }
390void AccountsService::updateHereEnabled(bool async)
392 QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
393 QStringLiteral("com.ubuntu.location.providers.here.AccountsService"),
394 QStringLiteral("LicenseAccepted"));
395 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
397 connect(watcher, &QDBusPendingCallWatcher::finished,
398 this, [this](QDBusPendingCallWatcher* watcher) {
400 QDBusPendingReply<QVariant> reply = *watcher;
401 watcher->deleteLater();
402 if (reply.isError()) {
403 qWarning() << "Failed to get 'LicenseAccepted' property - " << reply.error().message();
404 return;
405 }
407 const bool hereEnabled = reply.value().toBool();
408 if (m_hereEnabled != hereEnabled) {
409 m_hereEnabled = hereEnabled;
410 Q_EMIT hereEnabledChanged();
411 }
412 });
413 if (!async) {
414 watcher->waitForFinished();
415 delete watcher;
416 }
419void AccountsService::updateHereLicensePath(bool async)
421 QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
422 QStringLiteral("com.ubuntu.location.providers.here.AccountsService"),
423 QStringLiteral("LicenseBasePath"));
424 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
426 connect(watcher, &QDBusPendingCallWatcher::finished,
427 this, [this](QDBusPendingCallWatcher* watcher) {
429 QDBusPendingReply<QVariant> reply = *watcher;
430 watcher->deleteLater();
431 if (reply.isError()) {
432 qWarning() << "Failed to get 'LicenseBasePath' property - " << reply.error().message();
433 return;
434 }
436 QString hereLicensePath = reply.value().toString();
437 if (hereLicensePath.isEmpty() || !QFile::exists(hereLicensePath))
438 hereLicensePath = QLatin1String("");
440 if (m_hereLicensePath.isNull() || m_hereLicensePath != hereLicensePath) {
441 m_hereLicensePath = hereLicensePath;
442 Q_EMIT hereLicensePathChanged();
443 }
444 });
445 if (!async) {
446 watcher->waitForFinished();
447 delete watcher;
448 }
451uint AccountsService::failedLogins() const
453 return m_failedLogins;
456void AccountsService::setFailedLogins(uint failedLogins)
458 if (m_failedLogins != failedLogins) {
459 m_failedLogins = failedLogins;
460 m_service->setUserPropertyAsync(m_user, QStringLiteral("com.canonical.unity.AccountsService.Private"), QStringLiteral("FailedLogins"), failedLogins);
462 Q_EMIT failedLoginsChanged();
463 }
466void AccountsService::onPropertiesChanged(const QString &user, const QString &interface, const QStringList &changed)
468 if (m_user != user) {
469 return;
470 }
472 if (interface == QLatin1String("com.canonical.unity.AccountsService")) {
473 if (changed.contains(QStringLiteral("demo-edges"))) {
474 updateDemoEdges();
475 }
476 } else if (interface == QLatin1String("com.canonical.unity.AccountsService.Private")) {
477 if (changed.contains(QStringLiteral("FailedLogins"))) {
478 updateFailedLogins();
479 }
480 } else if (interface == QLatin1String("com.ubuntu.AccountsService.Input")) {
481 if (changed.contains(QStringLiteral("MouseCursorSpeed"))) {
482 updateMouseCursorSpeed();
483 }
484 if (changed.contains(QStringLiteral("TouchpadCursorSpeed"))) {
485 updateTouchpadCursorSpeed();
486 }
487 } else if (interface == QLatin1String("com.ubuntu.touch.AccountsService.SecurityPrivacy")) {
488 if (changed.contains(QStringLiteral("StatsWelcomeScreen"))) {
489 updateStatsWelcomeScreen();
490 }
491 } else if (interface == QLatin1String("com.ubuntu.AccountsService.SecurityPrivacy")) {
492 if (changed.contains(QStringLiteral("PasswordDisplayHint"))) {
493 updatePasswordDisplayHint();
494 }
495 if (changed.contains(QStringLiteral("EnableLauncherWhileLocked"))) {
496 updateEnableLauncherWhileLocked();
497 }
498 if (changed.contains(QStringLiteral("EnableIndicatorsWhileLocked"))) {
499 updateEnableIndicatorsWhileLocked();
500 }
501 } else if (interface == QLatin1String("com.ubuntu.location.providers.here.AccountsService")) {
502 if (changed.contains(QStringLiteral("LicenseAccepted"))) {
503 updateHereEnabled();
504 }
505 if (changed.contains(QStringLiteral("LicenseBasePath"))) {
506 updateHereLicensePath();
507 }
508 }
511void AccountsService::onMaybeChanged(const QString &user)
513 if (m_user != user) {
514 return;
515 }
517 // Standard properties might have changed
518 updateBackgroundFile();