on 2cbfe46 help sign in
unity8/plugins/AccountsService/AccountsService.cpp
470 lines 16 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)
27 : QObject(parent),
28 m_service(new AccountsServiceDBusAdaptor(this)),
29 m_user(""),
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 connect(m_service, SIGNAL(propertiesChanged(const QString &, const QString &, const QStringList &)),
40 this, SLOT(propertiesChanged(const QString &, const QString &, const QStringList &)));
41 connect(m_service, SIGNAL(maybeChanged(const QString &)),
42 this, SLOT(maybeChanged(const QString &)));
44 setUser(qgetenv("USER"));
47QString AccountsService::user() const
49 return m_user;
52void AccountsService::setUser(const QString &user)
54 if (user.isEmpty() || m_user == user)
55 return;
57 m_user = user;
58 Q_EMIT userChanged();
60 updateDemoEdges(false);
61 updateEnableLauncherWhileLocked(false);
62 updateEnableIndicatorsWhileLocked(false);
63 updateBackgroundFile(false);
64 updateStatsWelcomeScreen(false);
65 updatePasswordDisplayHint(false);
66 updateFailedLogins(false);
67 updateHereEnabled(false);
68 updateHereLicensePath(false);
71bool AccountsService::demoEdges() const
73 return m_demoEdges;
76void AccountsService::setDemoEdges(bool demoEdges)
78 if (m_demoEdges != demoEdges) {
79 m_demoEdges = demoEdges;
80 m_service->setUserProperty(m_user, "com.canonical.unity.AccountsService", "demo-edges", demoEdges);
82 Q_EMIT demoEdgesChanged();
83 }
86bool AccountsService::enableLauncherWhileLocked() const
88 return m_enableLauncherWhileLocked;
91bool AccountsService::enableIndicatorsWhileLocked() const
93 return m_enableIndicatorsWhileLocked;
96QString AccountsService::backgroundFile() const
98 return m_backgroundFile;
101bool AccountsService::statsWelcomeScreen() const
103 return m_statsWelcomeScreen;
106AccountsService::PasswordDisplayHint AccountsService::passwordDisplayHint() const
108 return m_passwordDisplayHint;
111bool AccountsService::hereEnabled() const
113 return m_hereEnabled;
116void AccountsService::setHereEnabled(bool enabled)
118 if (m_hereEnabled != enabled) {
119 m_hereEnabled = enabled;
120 m_service->setUserProperty(m_user, "com.ubuntu.location.providers.here.AccountsService", "LicenseAccepted", enabled);
122 Q_EMIT hereEnabledChanged();
123 }
126QString AccountsService::hereLicensePath() const
128 return m_hereLicensePath;
131bool AccountsService::hereLicensePathValid() const
133 return !m_hereLicensePath.isNull();
136void AccountsService::updateDemoEdges(bool async)
138 QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
139 "com.canonical.unity.AccountsService",
140 "demo-edges");
141 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
143 connect(watcher, &QDBusPendingCallWatcher::finished,
144 this, [this](QDBusPendingCallWatcher* watcher) {
146 QDBusPendingReply<QDBusVariant> reply = *watcher;
147 if (reply.isError()) {
148 qWarning() << "Failed to get 'demo-edges' property - " << reply.error().message();
149 watcher->deleteLater();
150 return;
151 }
153 auto demoEdges = reply.value().variant().toBool();
154 if (m_demoEdges != demoEdges) {
155 m_demoEdges = demoEdges;
156 Q_EMIT demoEdgesChanged();
157 }
158 watcher->deleteLater();
159 });
160 if (!async) {
161 watcher->waitForFinished();
162 delete watcher;
163 }
166void AccountsService::updateEnableLauncherWhileLocked(bool async)
168 QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
169 "com.ubuntu.AccountsService.SecurityPrivacy",
170 "EnableLauncherWhileLocked");
171 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
173 connect(watcher, &QDBusPendingCallWatcher::finished,
174 this, [this](QDBusPendingCallWatcher* watcher) {
176 QDBusPendingReply<QDBusVariant> reply = *watcher;
177 if (reply.isError()) {
178 qWarning() << "Failed to get 'EnableLauncherWhileLocked' property - " << reply.error().message();
179 watcher->deleteLater();
180 return;
181 }
183 auto enableLauncherWhileLocked = reply.value().variant().toBool();
184 if (m_enableLauncherWhileLocked != enableLauncherWhileLocked) {
185 m_enableLauncherWhileLocked = enableLauncherWhileLocked;
186 Q_EMIT enableLauncherWhileLockedChanged();
187 }
188 watcher->deleteLater();
189 });
190 if (!async) {
191 watcher->waitForFinished();
192 delete watcher;
193 }
196void AccountsService::updateEnableIndicatorsWhileLocked(bool async)
198 QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
199 "com.ubuntu.AccountsService.SecurityPrivacy",
200 "EnableIndicatorsWhileLocked");
201 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
203 connect(watcher, &QDBusPendingCallWatcher::finished,
204 this, [this](QDBusPendingCallWatcher* watcher) {
206 QDBusPendingReply<QDBusVariant> reply = *watcher;
207 if (reply.isError()) {
208 qWarning() << "Failed to get 'EnableIndicatorsWhileLocked' property - " << reply.error().message();
209 watcher->deleteLater();
210 return;
211 }
213 auto enableIndicatorsWhileLocked = reply.value().variant().toBool();
214 if (m_enableIndicatorsWhileLocked != enableIndicatorsWhileLocked) {
215 m_enableIndicatorsWhileLocked = enableIndicatorsWhileLocked;
216 Q_EMIT enableIndicatorsWhileLockedChanged();
217 }
218 watcher->deleteLater();
219 });
220 if (!async) {
221 watcher->waitForFinished();
222 delete watcher;
223 }
226void AccountsService::updateBackgroundFile(bool async)
228 QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
229 "org.freedesktop.Accounts.User",
230 "BackgroundFile");
231 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
233 connect(watcher, &QDBusPendingCallWatcher::finished,
234 this, [this](QDBusPendingCallWatcher* watcher) {
236 QDBusPendingReply<QDBusVariant> reply = *watcher;
237 if (reply.isError()) {
238 qWarning() << "Failed to get 'BackgroundFile' property - " << reply.error().message();
239 watcher->deleteLater();
240 return;
241 }
243 auto backgroundFile = reply.value().variant().toString();
244 if (m_backgroundFile != backgroundFile) {
245 m_backgroundFile = backgroundFile;
246 Q_EMIT backgroundFileChanged();
247 }
248 watcher->deleteLater();
249 });
250 if (!async) {
251 watcher->waitForFinished();
252 delete watcher;
253 }
256void AccountsService::updateStatsWelcomeScreen(bool async)
258 QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
259 "com.ubuntu.touch.AccountsService.SecurityPrivacy",
260 "StatsWelcomeScreen");
261 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
263 connect(watcher, &QDBusPendingCallWatcher::finished,
264 this, [this](QDBusPendingCallWatcher* watcher) {
266 QDBusPendingReply<QDBusVariant> reply = *watcher;
267 if (reply.isError()) {
268 qWarning() << "Failed to get 'StatsWelcomeScreen' property - " << reply.error().message();
269 watcher->deleteLater();
270 return;
271 }
273 auto statsWelcomeScreen = reply.value().variant().toBool();
274 if (m_statsWelcomeScreen != statsWelcomeScreen) {
275 m_statsWelcomeScreen = statsWelcomeScreen;
276 Q_EMIT statsWelcomeScreenChanged();
277 }
278 watcher->deleteLater();
279 });
280 if (!async) {
281 watcher->waitForFinished();
282 delete watcher;
283 }
286void AccountsService::updatePasswordDisplayHint(bool async)
288 QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
289 "com.ubuntu.AccountsService.SecurityPrivacy",
290 "PasswordDisplayHint");
291 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
293 connect(watcher, &QDBusPendingCallWatcher::finished,
294 this, [this](QDBusPendingCallWatcher* watcher) {
296 QDBusPendingReply<QDBusVariant> reply = *watcher;
297 if (reply.isError()) {
298 qWarning() << "Failed to get 'PasswordDisplayHint' property - " << reply.error().message();
299 watcher->deleteLater();
300 return;
301 }
303 PasswordDisplayHint passwordDisplayHint = (PasswordDisplayHint)reply.value().variant().toInt();
304 if (m_passwordDisplayHint != passwordDisplayHint) {
305 m_passwordDisplayHint = passwordDisplayHint;
306 Q_EMIT passwordDisplayHintChanged();
307 }
308 watcher->deleteLater();
309 });
310 if (!async) {
311 watcher->waitForFinished();
312 delete watcher;
313 }
316void AccountsService::updateFailedLogins(bool async)
318 QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
319 "com.canonical.unity.AccountsService.Private",
320 "FailedLogins");
321 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
323 connect(watcher, &QDBusPendingCallWatcher::finished,
324 this, [this](QDBusPendingCallWatcher* watcher) {
326 QDBusPendingReply<QDBusVariant> reply = *watcher;
327 if (reply.isError()) {
328 qWarning() << "Failed to get 'FailedLogins' property - " << reply.error().message();
329 watcher->deleteLater();
330 return;
331 }
333 uint failedLogins = reply.value().variant().toUInt();
334 if (m_failedLogins != failedLogins) {
335 m_failedLogins = failedLogins;
336 Q_EMIT failedLoginsChanged();
337 }
338 watcher->deleteLater();
339 });
340 if (!async) {
341 watcher->waitForFinished();
342 delete watcher;
343 }
346void AccountsService::updateHereEnabled(bool async)
348 QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
349 "com.ubuntu.location.providers.here.AccountsService",
350 "LicenseAccepted");
351 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
353 connect(watcher, &QDBusPendingCallWatcher::finished,
354 this, [this](QDBusPendingCallWatcher* watcher) {
356 QDBusPendingReply<QDBusVariant> reply = *watcher;
357 if (reply.isError()) {
358 qWarning() << "Failed to get 'LicenseAccepted' property - " << reply.error().message();
359 watcher->deleteLater();
360 return;
361 }
363 auto hereEnabled = reply.value().variant().toBool();
364 if (m_hereEnabled != hereEnabled) {
365 m_hereEnabled = hereEnabled;
366 Q_EMIT hereEnabledChanged();
367 }
368 watcher->deleteLater();
369 });
370 if (!async) {
371 watcher->waitForFinished();
372 delete watcher;
373 }
376void AccountsService::updateHereLicensePath(bool async)
378 QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
379 "com.ubuntu.location.providers.here.AccountsService",
380 "LicenseBasePath");
381 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
383 connect(watcher, &QDBusPendingCallWatcher::finished,
384 this, [this](QDBusPendingCallWatcher* watcher) {
386 QDBusPendingReply<QDBusVariant> reply = *watcher;
387 if (reply.isError()) {
388 qWarning() << "Failed to get 'LicenseBasePath' property - " << reply.error().message();
389 watcher->deleteLater();
390 return;
391 }
393 auto hereLicensePath = reply.value().variant().toString();
394 if (hereLicensePath.isEmpty() || !QFile::exists(hereLicensePath))
395 hereLicensePath = "";
397 if (m_hereLicensePath.isNull() || m_hereLicensePath != hereLicensePath) {
398 m_hereLicensePath = hereLicensePath;
399 Q_EMIT hereLicensePathChanged();
400 }
401 watcher->deleteLater();
402 });
403 if (!async) {
404 watcher->waitForFinished();
405 delete watcher;
406 }
409uint AccountsService::failedLogins() const
411 return m_failedLogins;
414void AccountsService::setFailedLogins(uint failedLogins)
416 if (m_failedLogins != failedLogins) {
417 m_failedLogins = failedLogins;
418 m_service->setUserProperty(m_user, "com.canonical.unity.AccountsService.Private", "FailedLogins", failedLogins);
420 Q_EMIT failedLoginsChanged();
421 }
424void AccountsService::propertiesChanged(const QString &user, const QString &interface, const QStringList &changed)
426 if (m_user != user) {
427 return;
428 }
430 if (interface == "com.canonical.unity.AccountsService") {
431 if (changed.contains("demo-edges")) {
432 updateDemoEdges();
433 }
434 } else if (interface == "com.canonical.unity.AccountsService.Private") {
435 if (changed.contains("FailedLogins")) {
436 updateFailedLogins();
437 }
438 } else if (interface == "com.ubuntu.touch.AccountsService.SecurityPrivacy") {
439 if (changed.contains("StatsWelcomeScreen")) {
440 updateStatsWelcomeScreen();
441 }
442 } else if (interface == "com.ubuntu.AccountsService.SecurityPrivacy") {
443 if (changed.contains("PasswordDisplayHint")) {
444 updatePasswordDisplayHint();
445 }
446 if (changed.contains("EnableLauncherWhileLocked")) {
447 updateEnableLauncherWhileLocked();
448 }
449 if (changed.contains("EnableIndicatorsWhileLocked")) {
450 updateEnableIndicatorsWhileLocked();
451 }
452 } else if (interface == "com.ubuntu.location.providers.here.AccountsService") {
453 if (changed.contains("LicenseAccepted")) {
454 updateHereEnabled();
455 }
456 if (changed.contains("LicenseBasePath")) {
457 updateHereLicensePath();
458 }
459 }
462void AccountsService::maybeChanged(const QString &user)
464 if (m_user != user) {
465 return;
466 }
468 // Standard properties might have changed
469 updateBackgroundFile();