on 7f64acc help sign in
unity8/plugins/AccountsService/AccountsService.cpp
457 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 m_demoEdges = demoEdges;
79 m_service->setUserProperty(m_user, "com.canonical.unity.AccountsService", "demo-edges", demoEdges);
82bool AccountsService::enableLauncherWhileLocked() const
84 return m_enableLauncherWhileLocked;
87bool AccountsService::enableIndicatorsWhileLocked() const
89 return m_enableIndicatorsWhileLocked;
92QString AccountsService::backgroundFile() const
94 return m_backgroundFile;
97bool AccountsService::statsWelcomeScreen() const
99 return m_statsWelcomeScreen;
102AccountsService::PasswordDisplayHint AccountsService::passwordDisplayHint() const
104 return m_passwordDisplayHint;
107bool AccountsService::hereEnabled() const
109 return m_hereEnabled;
112void AccountsService::setHereEnabled(bool enabled)
114 m_service->setUserProperty(m_user, "com.ubuntu.location.providers.here.AccountsService", "LicenseAccepted", enabled);
117QString AccountsService::hereLicensePath() const
119 return m_hereLicensePath;
122bool AccountsService::hereLicensePathValid() const
124 return !m_hereLicensePath.isNull();
127void AccountsService::updateDemoEdges(bool async)
129 QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
130 "com.canonical.unity.AccountsService",
131 "demo-edges");
132 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
134 connect(watcher, &QDBusPendingCallWatcher::finished,
135 this, [this](QDBusPendingCallWatcher* watcher) {
137 QDBusPendingReply<QDBusVariant> reply = *watcher;
138 if (reply.isError()) {
139 qWarning() << "Failed to get 'demo-edges' property - " << reply.error().message();
140 watcher->deleteLater();
141 return;
142 }
144 auto demoEdges = reply.value().variant().toBool();
145 if (m_demoEdges != demoEdges) {
146 m_demoEdges = demoEdges;
147 Q_EMIT demoEdgesChanged();
148 }
149 watcher->deleteLater();
150 });
151 if (!async) {
152 watcher->waitForFinished();
153 delete watcher;
154 }
157void AccountsService::updateEnableLauncherWhileLocked(bool async)
159 QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
160 "com.ubuntu.AccountsService.SecurityPrivacy",
161 "EnableLauncherWhileLocked");
162 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
164 connect(watcher, &QDBusPendingCallWatcher::finished,
165 this, [this](QDBusPendingCallWatcher* watcher) {
167 QDBusPendingReply<QDBusVariant> reply = *watcher;
168 if (reply.isError()) {
169 qWarning() << "Failed to get 'EnableLauncherWhileLocked' property - " << reply.error().message();
170 watcher->deleteLater();
171 return;
172 }
174 auto enableLauncherWhileLocked = reply.value().variant().toBool();
175 if (m_enableLauncherWhileLocked != enableLauncherWhileLocked) {
176 m_enableLauncherWhileLocked = enableLauncherWhileLocked;
177 Q_EMIT enableLauncherWhileLockedChanged();
178 }
179 watcher->deleteLater();
180 });
181 if (!async) {
182 watcher->waitForFinished();
183 delete watcher;
184 }
187void AccountsService::updateEnableIndicatorsWhileLocked(bool async)
189 QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
190 "com.ubuntu.AccountsService.SecurityPrivacy",
191 "EnableIndicatorsWhileLocked");
192 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
194 connect(watcher, &QDBusPendingCallWatcher::finished,
195 this, [this](QDBusPendingCallWatcher* watcher) {
197 QDBusPendingReply<QDBusVariant> reply = *watcher;
198 if (reply.isError()) {
199 qWarning() << "Failed to get 'EnableIndicatorsWhileLocked' property - " << reply.error().message();
200 watcher->deleteLater();
201 return;
202 }
204 auto enableIndicatorsWhileLocked = reply.value().variant().toBool();
205 if (m_enableIndicatorsWhileLocked != enableIndicatorsWhileLocked) {
206 m_enableIndicatorsWhileLocked = enableIndicatorsWhileLocked;
207 Q_EMIT enableIndicatorsWhileLockedChanged();
208 }
209 watcher->deleteLater();
210 });
211 if (!async) {
212 watcher->waitForFinished();
213 delete watcher;
214 }
217void AccountsService::updateBackgroundFile(bool async)
219 QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
220 "org.freedesktop.Accounts.User",
221 "BackgroundFile");
222 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
224 connect(watcher, &QDBusPendingCallWatcher::finished,
225 this, [this](QDBusPendingCallWatcher* watcher) {
227 QDBusPendingReply<QDBusVariant> reply = *watcher;
228 if (reply.isError()) {
229 qWarning() << "Failed to get 'BackgroundFile' property - " << reply.error().message();
230 watcher->deleteLater();
231 return;
232 }
234 auto backgroundFile = reply.value().variant().toString();
235 if (m_backgroundFile != backgroundFile) {
236 m_backgroundFile = backgroundFile;
237 Q_EMIT backgroundFileChanged();
238 }
239 watcher->deleteLater();
240 });
241 if (!async) {
242 watcher->waitForFinished();
243 delete watcher;
244 }
247void AccountsService::updateStatsWelcomeScreen(bool async)
249 QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
250 "com.ubuntu.touch.AccountsService.SecurityPrivacy",
251 "StatsWelcomeScreen");
252 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
254 connect(watcher, &QDBusPendingCallWatcher::finished,
255 this, [this](QDBusPendingCallWatcher* watcher) {
257 QDBusPendingReply<QDBusVariant> reply = *watcher;
258 if (reply.isError()) {
259 qWarning() << "Failed to get 'StatsWelcomeScreen' property - " << reply.error().message();
260 watcher->deleteLater();
261 return;
262 }
264 auto statsWelcomeScreen = reply.value().variant().toBool();
265 if (m_statsWelcomeScreen != statsWelcomeScreen) {
266 m_statsWelcomeScreen = statsWelcomeScreen;
267 Q_EMIT statsWelcomeScreenChanged();
268 }
269 watcher->deleteLater();
270 });
271 if (!async) {
272 watcher->waitForFinished();
273 delete watcher;
274 }
277void AccountsService::updatePasswordDisplayHint(bool async)
279 QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
280 "com.ubuntu.AccountsService.SecurityPrivacy",
281 "PasswordDisplayHint");
282 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
284 connect(watcher, &QDBusPendingCallWatcher::finished,
285 this, [this](QDBusPendingCallWatcher* watcher) {
287 QDBusPendingReply<QDBusVariant> reply = *watcher;
288 if (reply.isError()) {
289 qWarning() << "Failed to get 'PasswordDisplayHint' property - " << reply.error().message();
290 watcher->deleteLater();
291 return;
292 }
294 PasswordDisplayHint passwordDisplayHint = (PasswordDisplayHint)reply.value().variant().toInt();
295 if (m_passwordDisplayHint != passwordDisplayHint) {
296 m_passwordDisplayHint = passwordDisplayHint;
297 Q_EMIT passwordDisplayHintChanged();
298 }
299 watcher->deleteLater();
300 });
301 if (!async) {
302 watcher->waitForFinished();
303 delete watcher;
304 }
307void AccountsService::updateFailedLogins(bool async)
309 QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
310 "com.canonical.unity.AccountsService.Private",
311 "FailedLogins");
312 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
314 connect(watcher, &QDBusPendingCallWatcher::finished,
315 this, [this](QDBusPendingCallWatcher* watcher) {
317 QDBusPendingReply<QDBusVariant> reply = *watcher;
318 if (reply.isError()) {
319 qWarning() << "Failed to get 'FailedLogins' property - " << reply.error().message();
320 watcher->deleteLater();
321 return;
322 }
324 uint failedLogins = reply.value().variant().toUInt();
325 if (m_failedLogins != failedLogins) {
326 m_failedLogins = failedLogins;
327 Q_EMIT failedLoginsChanged();
328 }
329 watcher->deleteLater();
330 });
331 if (!async) {
332 watcher->waitForFinished();
333 delete watcher;
334 }
337void AccountsService::updateHereEnabled(bool async)
339 QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
340 "com.ubuntu.location.providers.here.AccountsService",
341 "LicenseAccepted");
342 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
344 connect(watcher, &QDBusPendingCallWatcher::finished,
345 this, [this](QDBusPendingCallWatcher* watcher) {
347 QDBusPendingReply<QDBusVariant> reply = *watcher;
348 if (reply.isError()) {
349 qWarning() << "Failed to get 'LicenseAccepted' property - " << reply.error().message();
350 watcher->deleteLater();
351 return;
352 }
354 auto hereEnabled = reply.value().variant().toBool();
355 if (m_hereEnabled != hereEnabled) {
356 m_hereEnabled = hereEnabled;
357 Q_EMIT hereEnabledChanged();
358 }
359 watcher->deleteLater();
360 });
361 if (!async) {
362 watcher->waitForFinished();
363 delete watcher;
364 }
367void AccountsService::updateHereLicensePath(bool async)
369 QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
370 "com.ubuntu.location.providers.here.AccountsService",
371 "LicenseBasePath");
372 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
374 connect(watcher, &QDBusPendingCallWatcher::finished,
375 this, [this](QDBusPendingCallWatcher* watcher) {
377 QDBusPendingReply<QDBusVariant> reply = *watcher;
378 if (reply.isError()) {
379 qWarning() << "Failed to get 'LicenseBasePath' property - " << reply.error().message();
380 watcher->deleteLater();
381 return;
382 }
384 auto hereLicensePath = reply.value().variant().toString();
385 if (hereLicensePath.isEmpty() || !QFile::exists(hereLicensePath))
386 hereLicensePath = "";
388 if (m_hereLicensePath.isNull() || m_hereLicensePath != hereLicensePath) {
389 m_hereLicensePath = hereLicensePath;
390 Q_EMIT hereLicensePathChanged();
391 }
392 watcher->deleteLater();
393 });
394 if (!async) {
395 watcher->waitForFinished();
396 delete watcher;
397 }
400uint AccountsService::failedLogins() const
402 return m_failedLogins;
405void AccountsService::setFailedLogins(uint failedLogins)
407 m_failedLogins = failedLogins;
408 m_service->setUserProperty(m_user, "com.canonical.unity.AccountsService.Private", "FailedLogins", failedLogins);
411void AccountsService::propertiesChanged(const QString &user, const QString &interface, const QStringList &changed)
413 if (m_user != user) {
414 return;
415 }
417 if (interface == "com.canonical.unity.AccountsService") {
418 if (changed.contains("demo-edges")) {
419 updateDemoEdges();
420 }
421 } else if (interface == "com.canonical.unity.AccountsService.Private") {
422 if (changed.contains("FailedLogins")) {
423 updateFailedLogins();
424 }
425 } else if (interface == "com.ubuntu.touch.AccountsService.SecurityPrivacy") {
426 if (changed.contains("StatsWelcomeScreen")) {
427 updateStatsWelcomeScreen();
428 }
429 } else if (interface == "com.ubuntu.AccountsService.SecurityPrivacy") {
430 if (changed.contains("PasswordDisplayHint")) {
431 updatePasswordDisplayHint();
432 }
433 if (changed.contains("EnableLauncherWhileLocked")) {
434 updateEnableLauncherWhileLocked();
435 }
436 if (changed.contains("EnableIndicatorsWhileLocked")) {
437 updateEnableIndicatorsWhileLocked();
438 }
439 } else if (interface == "com.ubuntu.location.providers.here.AccountsService") {
440 if (changed.contains("LicenseAccepted")) {
441 updateHereEnabled();
442 }
443 if (changed.contains("LicenseBasePath")) {
444 updateHereLicensePath();
445 }
446 }
449void AccountsService::maybeChanged(const QString &user)
451 if (m_user != user) {
452 return;
453 }
455 // Standard properties might have changed
456 updateBackgroundFile();