on e1209af help sign in
unity8/plugins/AccountsService/AccountsService.cpp
459 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 if (reply.isError()) {
145 qWarning() << "Failed to get 'demo-edges' property - " << reply.error().message();
146 watcher->deleteLater();
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 watcher->deleteLater();
156 });
157 if (!async) {
158 watcher->waitForFinished();
159 delete watcher;
160 }
163void AccountsService::updateEnableLauncherWhileLocked(bool async)
165 QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
166 "com.ubuntu.AccountsService.SecurityPrivacy",
167 "EnableLauncherWhileLocked");
168 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
170 connect(watcher, &QDBusPendingCallWatcher::finished,
171 this, [this](QDBusPendingCallWatcher* watcher) {
173 QDBusPendingReply<QVariant> reply = *watcher;
174 watcher->deleteLater();
175 if (reply.isError()) {
176 qWarning() << "Failed to get 'EnableLauncherWhileLocked' property - " << reply.error().message();
177 return;
178 }
180 const bool enableLauncherWhileLocked = reply.value().toBool();
181 if (m_enableLauncherWhileLocked != enableLauncherWhileLocked) {
182 m_enableLauncherWhileLocked = enableLauncherWhileLocked;
183 Q_EMIT enableLauncherWhileLockedChanged();
184 }
185 });
186 if (!async) {
187 watcher->waitForFinished();
188 delete watcher;
189 }
192void AccountsService::updateEnableIndicatorsWhileLocked(bool async)
194 QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
195 "com.ubuntu.AccountsService.SecurityPrivacy",
196 "EnableIndicatorsWhileLocked");
197 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
199 connect(watcher, &QDBusPendingCallWatcher::finished,
200 this, [this](QDBusPendingCallWatcher* watcher) {
202 QDBusPendingReply<QVariant> reply = *watcher;
203 watcher->deleteLater();
204 if (reply.isError()) {
205 qWarning() << "Failed to get 'EnableIndicatorsWhileLocked' property - " << reply.error().message();
206 return;
207 }
209 const bool enableIndicatorsWhileLocked = reply.value().toBool();
210 if (m_enableIndicatorsWhileLocked != enableIndicatorsWhileLocked) {
211 m_enableIndicatorsWhileLocked = enableIndicatorsWhileLocked;
212 Q_EMIT enableIndicatorsWhileLockedChanged();
213 }
214 });
215 if (!async) {
216 watcher->waitForFinished();
217 delete watcher;
218 }
221void AccountsService::updateBackgroundFile(bool async)
223 QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
224 "org.freedesktop.Accounts.User",
225 "BackgroundFile");
226 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
228 connect(watcher, &QDBusPendingCallWatcher::finished,
229 this, [this](QDBusPendingCallWatcher* watcher) {
231 QDBusPendingReply<QVariant> reply = *watcher;
232 watcher->deleteLater();
233 if (reply.isError()) {
234 qWarning() << "Failed to get 'BackgroundFile' property - " << reply.error().message();
235 return;
236 }
238 const QString backgroundFile = reply.value().toString();
239 if (m_backgroundFile != backgroundFile) {
240 m_backgroundFile = backgroundFile;
241 Q_EMIT backgroundFileChanged();
242 }
243 });
244 if (!async) {
245 watcher->waitForFinished();
246 delete watcher;
247 }
250void AccountsService::updateStatsWelcomeScreen(bool async)
252 QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
253 "com.ubuntu.touch.AccountsService.SecurityPrivacy",
254 "StatsWelcomeScreen");
255 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
257 connect(watcher, &QDBusPendingCallWatcher::finished,
258 this, [this](QDBusPendingCallWatcher* watcher) {
260 QDBusPendingReply<QVariant> reply = *watcher;
261 watcher->deleteLater();
262 if (reply.isError()) {
263 qWarning() << "Failed to get 'StatsWelcomeScreen' property - " << reply.error().message();
264 return;
265 }
267 const bool statsWelcomeScreen = reply.value().toBool();
268 if (m_statsWelcomeScreen != statsWelcomeScreen) {
269 m_statsWelcomeScreen = statsWelcomeScreen;
270 Q_EMIT statsWelcomeScreenChanged();
271 }
272 });
273 if (!async) {
274 watcher->waitForFinished();
275 delete watcher;
276 }
279void AccountsService::updatePasswordDisplayHint(bool async)
281 QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
282 "com.ubuntu.AccountsService.SecurityPrivacy",
283 "PasswordDisplayHint");
284 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
286 connect(watcher, &QDBusPendingCallWatcher::finished,
287 this, [this](QDBusPendingCallWatcher* watcher) {
289 QDBusPendingReply<QVariant> reply = *watcher;
290 watcher->deleteLater();
291 if (reply.isError()) {
292 qWarning() << "Failed to get 'PasswordDisplayHint' property - " << reply.error().message();
293 return;
294 }
296 const PasswordDisplayHint passwordDisplayHint = (PasswordDisplayHint)reply.value().toInt();
297 if (m_passwordDisplayHint != passwordDisplayHint) {
298 m_passwordDisplayHint = passwordDisplayHint;
299 Q_EMIT passwordDisplayHintChanged();
300 }
301 });
302 if (!async) {
303 watcher->waitForFinished();
304 delete watcher;
305 }
308void AccountsService::updateFailedLogins(bool async)
310 QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
311 "com.canonical.unity.AccountsService.Private",
312 "FailedLogins");
313 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
315 connect(watcher, &QDBusPendingCallWatcher::finished,
316 this, [this](QDBusPendingCallWatcher* watcher) {
318 QDBusPendingReply<QVariant> reply = *watcher;
319 watcher->deleteLater();
320 if (reply.isError()) {
321 qWarning() << "Failed to get 'FailedLogins' property - " << reply.error().message();
322 return;
323 }
325 const uint failedLogins = reply.value().toUInt();
326 if (m_failedLogins != failedLogins) {
327 m_failedLogins = failedLogins;
328 Q_EMIT failedLoginsChanged();
329 }
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<QVariant> reply = *watcher;
348 watcher->deleteLater();
349 if (reply.isError()) {
350 qWarning() << "Failed to get 'LicenseAccepted' property - " << reply.error().message();
351 return;
352 }
354 const bool hereEnabled = reply.value().toBool();
355 if (m_hereEnabled != hereEnabled) {
356 m_hereEnabled = hereEnabled;
357 Q_EMIT hereEnabledChanged();
358 }
359 });
360 if (!async) {
361 watcher->waitForFinished();
362 delete watcher;
363 }
366void AccountsService::updateHereLicensePath(bool async)
368 QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
369 "com.ubuntu.location.providers.here.AccountsService",
370 "LicenseBasePath");
371 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
373 connect(watcher, &QDBusPendingCallWatcher::finished,
374 this, [this](QDBusPendingCallWatcher* watcher) {
376 QDBusPendingReply<QVariant> reply = *watcher;
377 watcher->deleteLater();
378 if (reply.isError()) {
379 qWarning() << "Failed to get 'LicenseBasePath' property - " << reply.error().message();
380 return;
381 }
383 QString hereLicensePath = reply.value().toString();
384 if (hereLicensePath.isEmpty() || !QFile::exists(hereLicensePath))
385 hereLicensePath = "";
387 if (m_hereLicensePath.isNull() || m_hereLicensePath != hereLicensePath) {
388 m_hereLicensePath = hereLicensePath;
389 Q_EMIT hereLicensePathChanged();
390 }
391 });
392 if (!async) {
393 watcher->waitForFinished();
394 delete watcher;
395 }
398uint AccountsService::failedLogins() const
400 return m_failedLogins;
403void AccountsService::setFailedLogins(uint failedLogins)
405 if (m_failedLogins != failedLogins) {
406 m_failedLogins = failedLogins;
407 m_service->setUserProperty(m_user, "com.canonical.unity.AccountsService.Private", "FailedLogins", failedLogins);
409 Q_EMIT failedLoginsChanged();
410 }
413void AccountsService::onPropertiesChanged(const QString &user, const QString &interface, const QStringList &changed)
415 if (m_user != user) {
416 return;
417 }
419 if (interface == "com.canonical.unity.AccountsService") {
420 if (changed.contains("demo-edges")) {
421 updateDemoEdges();
422 }
423 } else if (interface == "com.canonical.unity.AccountsService.Private") {
424 if (changed.contains("FailedLogins")) {
425 updateFailedLogins();
426 }
427 } else if (interface == "com.ubuntu.touch.AccountsService.SecurityPrivacy") {
428 if (changed.contains("StatsWelcomeScreen")) {
429 updateStatsWelcomeScreen();
430 }
431 } else if (interface == "com.ubuntu.AccountsService.SecurityPrivacy") {
432 if (changed.contains("PasswordDisplayHint")) {
433 updatePasswordDisplayHint();
434 }
435 if (changed.contains("EnableLauncherWhileLocked")) {
436 updateEnableLauncherWhileLocked();
437 }
438 if (changed.contains("EnableIndicatorsWhileLocked")) {
439 updateEnableIndicatorsWhileLocked();
440 }
441 } else if (interface == "com.ubuntu.location.providers.here.AccountsService") {
442 if (changed.contains("LicenseAccepted")) {
443 updateHereEnabled();
444 }
445 if (changed.contains("LicenseBasePath")) {
446 updateHereLicensePath();
447 }
448 }
451void AccountsService::onMaybeChanged(const QString &user)
453 if (m_user != user) {
454 return;
455 }
457 // Standard properties might have changed
458 updateBackgroundFile();