on b1bb052 help sign in
unity8/plugins/AccountsService/AccountsService.cpp
458 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, const QString &user)
27 : QObject(parent),
28 m_service(new AccountsServiceDBusAdaptor(this)),
29 m_demoEdges(false),
30 m_enableLauncherWhileLocked(false),
31 m_enableIndicatorsWhileLocked(false),
32 m_statsWelcomeScreen(false),
33 m_passwordDisplayHint(Keyboard),
34 m_failedLogins(0),
35 m_hereEnabled(false),
36 m_hereLicensePath() // null means not set yet
38 connect(m_service, &AccountsServiceDBusAdaptor::propertiesChanged, this, &AccountsService::onPropertiesChanged);
39 connect(m_service, &AccountsServiceDBusAdaptor::maybeChanged, this, &AccountsService::onMaybeChanged);
41 setUser(!user.isEmpty() ? user : QString::fromUtf8(qgetenv("USER")));
44QString AccountsService::user() const
46 return m_user;
49void AccountsService::setUser(const QString &user)
51 if (user.isEmpty() || m_user == user)
52 return;
54 m_user = user;
55 Q_EMIT userChanged();
57 updateDemoEdges(false);
58 updateEnableLauncherWhileLocked(false);
59 updateEnableIndicatorsWhileLocked(false);
60 updateBackgroundFile(false);
61 updateStatsWelcomeScreen(false);
62 updatePasswordDisplayHint(false);
63 updateFailedLogins(false);
64 updateHereEnabled(false);
65 updateHereLicensePath(false);
68bool AccountsService::demoEdges() const
70 return m_demoEdges;
73void AccountsService::setDemoEdges(bool demoEdges)
75 if (m_demoEdges != demoEdges) {
76 m_demoEdges = demoEdges;
77 m_service->setUserProperty(m_user, "com.canonical.unity.AccountsService", "demo-edges", demoEdges);
79 Q_EMIT demoEdgesChanged();
80 }
83bool AccountsService::enableLauncherWhileLocked() const
85 return m_enableLauncherWhileLocked;
88bool AccountsService::enableIndicatorsWhileLocked() const
90 return m_enableIndicatorsWhileLocked;
93QString AccountsService::backgroundFile() const
95 return m_backgroundFile;
98bool AccountsService::statsWelcomeScreen() const
100 return m_statsWelcomeScreen;
103AccountsService::PasswordDisplayHint AccountsService::passwordDisplayHint() const
105 return m_passwordDisplayHint;
108bool AccountsService::hereEnabled() const
110 return m_hereEnabled;
113void AccountsService::setHereEnabled(bool enabled)
115 if (m_hereEnabled != enabled) {
116 m_hereEnabled = enabled;
117 m_service->setUserProperty(m_user, "com.ubuntu.location.providers.here.AccountsService", "LicenseAccepted", enabled);
119 Q_EMIT hereEnabledChanged();
120 }
123QString AccountsService::hereLicensePath() const
125 return m_hereLicensePath;
128bool AccountsService::hereLicensePathValid() const
130 return !m_hereLicensePath.isNull();
133void AccountsService::updateDemoEdges(bool async)
135 QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
136 "com.canonical.unity.AccountsService",
137 "demo-edges");
138 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
140 connect(watcher, &QDBusPendingCallWatcher::finished,
141 this, [this](QDBusPendingCallWatcher* watcher) {
143 QDBusPendingReply<QDBusVariant> reply = *watcher;
144 watcher->deleteLater();
145 if (reply.isError()) {
146 qWarning() << "Failed to get 'demo-edges' property - " << reply.error().message();
147 return;
148 }
150 auto demoEdges = reply.value().variant().toBool();
151 if (m_demoEdges != demoEdges) {
152 m_demoEdges = demoEdges;
153 Q_EMIT demoEdgesChanged();
154 }
155 });
156 if (!async) {
157 watcher->waitForFinished();
158 delete watcher;
159 }
162void AccountsService::updateEnableLauncherWhileLocked(bool async)
164 QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
165 "com.ubuntu.AccountsService.SecurityPrivacy",
166 "EnableLauncherWhileLocked");
167 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
169 connect(watcher, &QDBusPendingCallWatcher::finished,
170 this, [this](QDBusPendingCallWatcher* watcher) {
172 QDBusPendingReply<QVariant> reply = *watcher;
173 watcher->deleteLater();
174 if (reply.isError()) {
175 qWarning() << "Failed to get 'EnableLauncherWhileLocked' property - " << reply.error().message();
176 return;
177 }
179 const bool enableLauncherWhileLocked = reply.value().toBool();
180 if (m_enableLauncherWhileLocked != enableLauncherWhileLocked) {
181 m_enableLauncherWhileLocked = enableLauncherWhileLocked;
182 Q_EMIT enableLauncherWhileLockedChanged();
183 }
184 });
185 if (!async) {
186 watcher->waitForFinished();
187 delete watcher;
188 }
191void AccountsService::updateEnableIndicatorsWhileLocked(bool async)
193 QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
194 "com.ubuntu.AccountsService.SecurityPrivacy",
195 "EnableIndicatorsWhileLocked");
196 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
198 connect(watcher, &QDBusPendingCallWatcher::finished,
199 this, [this](QDBusPendingCallWatcher* watcher) {
201 QDBusPendingReply<QVariant> reply = *watcher;
202 watcher->deleteLater();
203 if (reply.isError()) {
204 qWarning() << "Failed to get 'EnableIndicatorsWhileLocked' property - " << reply.error().message();
205 return;
206 }
208 const bool enableIndicatorsWhileLocked = reply.value().toBool();
209 if (m_enableIndicatorsWhileLocked != enableIndicatorsWhileLocked) {
210 m_enableIndicatorsWhileLocked = enableIndicatorsWhileLocked;
211 Q_EMIT enableIndicatorsWhileLockedChanged();
212 }
213 });
214 if (!async) {
215 watcher->waitForFinished();
216 delete watcher;
217 }
220void AccountsService::updateBackgroundFile(bool async)
222 QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
223 "org.freedesktop.Accounts.User",
224 "BackgroundFile");
225 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
227 connect(watcher, &QDBusPendingCallWatcher::finished,
228 this, [this](QDBusPendingCallWatcher* watcher) {
230 QDBusPendingReply<QVariant> reply = *watcher;
231 watcher->deleteLater();
232 if (reply.isError()) {
233 qWarning() << "Failed to get 'BackgroundFile' property - " << reply.error().message();
234 return;
235 }
237 const QString backgroundFile = reply.value().toString();
238 if (m_backgroundFile != backgroundFile) {
239 m_backgroundFile = backgroundFile;
240 Q_EMIT backgroundFileChanged();
241 }
242 });
243 if (!async) {
244 watcher->waitForFinished();
245 delete watcher;
246 }
249void AccountsService::updateStatsWelcomeScreen(bool async)
251 QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
252 "com.ubuntu.touch.AccountsService.SecurityPrivacy",
253 "StatsWelcomeScreen");
254 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
256 connect(watcher, &QDBusPendingCallWatcher::finished,
257 this, [this](QDBusPendingCallWatcher* watcher) {
259 QDBusPendingReply<QVariant> reply = *watcher;
260 watcher->deleteLater();
261 if (reply.isError()) {
262 qWarning() << "Failed to get 'StatsWelcomeScreen' property - " << reply.error().message();
263 return;
264 }
266 const bool statsWelcomeScreen = reply.value().toBool();
267 if (m_statsWelcomeScreen != statsWelcomeScreen) {
268 m_statsWelcomeScreen = statsWelcomeScreen;
269 Q_EMIT statsWelcomeScreenChanged();
270 }
271 });
272 if (!async) {
273 watcher->waitForFinished();
274 delete watcher;
275 }
278void AccountsService::updatePasswordDisplayHint(bool async)
280 QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
281 "com.ubuntu.AccountsService.SecurityPrivacy",
282 "PasswordDisplayHint");
283 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
285 connect(watcher, &QDBusPendingCallWatcher::finished,
286 this, [this](QDBusPendingCallWatcher* watcher) {
288 QDBusPendingReply<QVariant> reply = *watcher;
289 watcher->deleteLater();
290 if (reply.isError()) {
291 qWarning() << "Failed to get 'PasswordDisplayHint' property - " << reply.error().message();
292 return;
293 }
295 const PasswordDisplayHint passwordDisplayHint = (PasswordDisplayHint)reply.value().toInt();
296 if (m_passwordDisplayHint != passwordDisplayHint) {
297 m_passwordDisplayHint = passwordDisplayHint;
298 Q_EMIT passwordDisplayHintChanged();
299 }
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<QVariant> reply = *watcher;
318 watcher->deleteLater();
319 if (reply.isError()) {
320 qWarning() << "Failed to get 'FailedLogins' property - " << reply.error().message();
321 return;
322 }
324 const uint failedLogins = reply.value().toUInt();
325 if (m_failedLogins != failedLogins) {
326 m_failedLogins = failedLogins;
327 Q_EMIT failedLoginsChanged();
328 }
329 });
330 if (!async) {
331 watcher->waitForFinished();
332 delete watcher;
333 }
336void AccountsService::updateHereEnabled(bool async)
338 QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
339 "com.ubuntu.location.providers.here.AccountsService",
340 "LicenseAccepted");
341 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
343 connect(watcher, &QDBusPendingCallWatcher::finished,
344 this, [this](QDBusPendingCallWatcher* watcher) {
346 QDBusPendingReply<QVariant> reply = *watcher;
347 watcher->deleteLater();
348 if (reply.isError()) {
349 qWarning() << "Failed to get 'LicenseAccepted' property - " << reply.error().message();
350 return;
351 }
353 const bool hereEnabled = reply.value().toBool();
354 if (m_hereEnabled != hereEnabled) {
355 m_hereEnabled = hereEnabled;
356 Q_EMIT hereEnabledChanged();
357 }
358 });
359 if (!async) {
360 watcher->waitForFinished();
361 delete watcher;
362 }
365void AccountsService::updateHereLicensePath(bool async)
367 QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
368 "com.ubuntu.location.providers.here.AccountsService",
369 "LicenseBasePath");
370 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
372 connect(watcher, &QDBusPendingCallWatcher::finished,
373 this, [this](QDBusPendingCallWatcher* watcher) {
375 QDBusPendingReply<QVariant> reply = *watcher;
376 watcher->deleteLater();
377 if (reply.isError()) {
378 qWarning() << "Failed to get 'LicenseBasePath' property - " << reply.error().message();
379 return;
380 }
382 QString hereLicensePath = reply.value().toString();
383 if (hereLicensePath.isEmpty() || !QFile::exists(hereLicensePath))
384 hereLicensePath = "";
386 if (m_hereLicensePath.isNull() || m_hereLicensePath != hereLicensePath) {
387 m_hereLicensePath = hereLicensePath;
388 Q_EMIT hereLicensePathChanged();
389 }
390 });
391 if (!async) {
392 watcher->waitForFinished();
393 delete watcher;
394 }
397uint AccountsService::failedLogins() const
399 return m_failedLogins;
402void AccountsService::setFailedLogins(uint failedLogins)
404 if (m_failedLogins != failedLogins) {
405 m_failedLogins = failedLogins;
406 m_service->setUserProperty(m_user, "com.canonical.unity.AccountsService.Private", "FailedLogins", failedLogins);
408 Q_EMIT failedLoginsChanged();
409 }
412void AccountsService::onPropertiesChanged(const QString &user, const QString &interface, const QStringList &changed)
414 if (m_user != user) {
415 return;
416 }
418 if (interface == "com.canonical.unity.AccountsService") {
419 if (changed.contains("demo-edges")) {
420 updateDemoEdges();
421 }
422 } else if (interface == "com.canonical.unity.AccountsService.Private") {
423 if (changed.contains("FailedLogins")) {
424 updateFailedLogins();
425 }
426 } else if (interface == "com.ubuntu.touch.AccountsService.SecurityPrivacy") {
427 if (changed.contains("StatsWelcomeScreen")) {
428 updateStatsWelcomeScreen();
429 }
430 } else if (interface == "com.ubuntu.AccountsService.SecurityPrivacy") {
431 if (changed.contains("PasswordDisplayHint")) {
432 updatePasswordDisplayHint();
433 }
434 if (changed.contains("EnableLauncherWhileLocked")) {
435 updateEnableLauncherWhileLocked();
436 }
437 if (changed.contains("EnableIndicatorsWhileLocked")) {
438 updateEnableIndicatorsWhileLocked();
439 }
440 } else if (interface == "com.ubuntu.location.providers.here.AccountsService") {
441 if (changed.contains("LicenseAccepted")) {
442 updateHereEnabled();
443 }
444 if (changed.contains("LicenseBasePath")) {
445 updateHereLicensePath();
446 }
447 }
450void AccountsService::onMaybeChanged(const QString &user)
452 if (m_user != user) {
453 return;
454 }
456 // Standard properties might have changed
457 updateBackgroundFile();