17 #include "AccountsService.h" 18 #include "AccountsServiceDBusAdaptor.h" 20 #include <QDBusInterface> 22 #include <QStringList> 25 #define IFACE_ACCOUNTS_USER QStringLiteral("org.freedesktop.Accounts.User") 26 #define IFACE_LOCATION_HERE QStringLiteral("com.ubuntu.location.providers.here.AccountsService") 27 #define IFACE_UBUNTU_INPUT QStringLiteral("com.ubuntu.AccountsService.Input") 28 #define IFACE_UBUNTU_SECURITY QStringLiteral("com.ubuntu.AccountsService.SecurityPrivacy") 29 #define IFACE_UBUNTU_SECURITY_OLD QStringLiteral("com.ubuntu.touch.AccountsService.SecurityPrivacy") 30 #define IFACE_UNITY QStringLiteral("com.canonical.unity.AccountsService") 31 #define IFACE_UNITY_PRIVATE QStringLiteral("com.canonical.unity.AccountsService.Private") 33 #define PROP_BACKGROUND_FILE QStringLiteral("BackgroundFile") 34 #define PROP_DEMO_EDGES QStringLiteral("demo-edges") 35 #define PROP_DEMO_EDGES_COMPLETED QStringLiteral("DemoEdgesCompleted") 36 #define PROP_EMAIL QStringLiteral("Email") 37 #define PROP_ENABLE_INDICATORS_WHILE_LOCKED QStringLiteral("EnableIndicatorsWhileLocked") 38 #define PROP_ENABLE_LAUNCHER_WHILE_LOCKED QStringLiteral("EnableLauncherWhileLocked") 39 #define PROP_FAILED_LOGINS QStringLiteral("FailedLogins") 40 #define PROP_INPUT_SOURCES QStringLiteral("InputSources") 41 #define PROP_LICENSE_ACCEPTED QStringLiteral("LicenseAccepted") 42 #define PROP_LICENSE_BASE_PATH QStringLiteral("LicenseBasePath") 43 #define PROP_MOUSE_CURSOR_SPEED QStringLiteral("MouseCursorSpeed") 44 #define PROP_MOUSE_DOUBLE_CLICK_SPEED QStringLiteral("MouseDoubleClickSpeed") 45 #define PROP_MOUSE_PRIMARY_BUTTON QStringLiteral("MousePrimaryButton") 46 #define PROP_MOUSE_SCROLL_SPEED QStringLiteral("MouseScrollSpeed") 47 #define PROP_PASSWORD_DISPLAY_HINT QStringLiteral("PasswordDisplayHint") 48 #define PROP_REAL_NAME QStringLiteral("RealName") 49 #define PROP_STATS_WELCOME_SCREEN QStringLiteral("StatsWelcomeScreen") 50 #define PROP_TOUCHPAD_CURSOR_SPEED QStringLiteral("TouchpadCursorSpeed") 51 #define PROP_TOUCHPAD_DISABLE_WHILE_TYPING QStringLiteral("TouchpadDisableWhileTyping") 52 #define PROP_TOUCHPAD_DISABLE_WITH_MOUSE QStringLiteral("TouchpadDisableWithMouse") 53 #define PROP_TOUCHPAD_DOUBLE_CLICK_SPEED QStringLiteral("TouchpadDoubleClickSpeed") 54 #define PROP_TOUCHPAD_PRIMARY_BUTTON QStringLiteral("TouchpadPrimaryButton") 55 #define PROP_TOUCHPAD_SCROLL_SPEED QStringLiteral("TouchpadScrollSpeed") 56 #define PROP_TOUCHPAD_TAP_TO_CLICK QStringLiteral("TouchpadTapToClick") 57 #define PROP_TOUCHPAD_TWO_FINGER_SCROLL QStringLiteral("TouchpadTwoFingerScroll") 59 using StringMap = QMap<QString,QString>;
60 using StringMapList = QList<StringMap>;
61 Q_DECLARE_METATYPE(StringMapList)
64 QVariant primaryButtonConverter(const QVariant &value)
66 QString stringValue = value.toString();
67 if (stringValue ==
"left") {
68 return QVariant::fromValue(0);
69 }
else if (stringValue ==
"right") {
70 return QVariant::fromValue(1);
72 return QVariant::fromValue(0);
76 AccountsService::AccountsService(QObject* parent,
const QString &user)
78 , m_service(new AccountsServiceDBusAdaptor(this))
80 m_unityInput =
new QDBusInterface(QStringLiteral(
"com.canonical.Unity.Input"),
81 QStringLiteral(
"/com/canonical/Unity/Input"),
82 QStringLiteral(
"com.canonical.Unity.Input"),
83 QDBusConnection::SM_BUSNAME(),
this);
85 connect(m_service, &AccountsServiceDBusAdaptor::propertiesChanged,
this, &AccountsService::onPropertiesChanged);
86 connect(m_service, &AccountsServiceDBusAdaptor::maybeChanged,
this, &AccountsService::onMaybeChanged);
88 registerProperty(IFACE_ACCOUNTS_USER, PROP_BACKGROUND_FILE, QStringLiteral(
"backgroundFileChanged"));
89 registerProperty(IFACE_ACCOUNTS_USER, PROP_EMAIL, QStringLiteral(
"emailChanged"));
90 registerProperty(IFACE_ACCOUNTS_USER, PROP_REAL_NAME, QStringLiteral(
"realNameChanged"));
91 registerProperty(IFACE_ACCOUNTS_USER, PROP_INPUT_SOURCES, QStringLiteral(
"keymapsChanged"));
92 registerProperty(IFACE_LOCATION_HERE, PROP_LICENSE_ACCEPTED, QStringLiteral(
"hereEnabledChanged"));
93 registerProperty(IFACE_LOCATION_HERE, PROP_LICENSE_BASE_PATH, QStringLiteral(
"hereLicensePathChanged"));
94 registerProperty(IFACE_UBUNTU_SECURITY, PROP_ENABLE_LAUNCHER_WHILE_LOCKED, QStringLiteral(
"enableLauncherWhileLockedChanged"));
95 registerProperty(IFACE_UBUNTU_SECURITY, PROP_ENABLE_INDICATORS_WHILE_LOCKED, QStringLiteral(
"enableIndicatorsWhileLockedChanged"));
96 registerProperty(IFACE_UBUNTU_SECURITY, PROP_PASSWORD_DISPLAY_HINT, QStringLiteral(
"passwordDisplayHintChanged"));
97 registerProperty(IFACE_UBUNTU_SECURITY_OLD, PROP_STATS_WELCOME_SCREEN, QStringLiteral(
"statsWelcomeScreenChanged"));
98 registerProperty(IFACE_UNITY, PROP_DEMO_EDGES, QStringLiteral(
"demoEdgesChanged"));
99 registerProperty(IFACE_UNITY, PROP_DEMO_EDGES_COMPLETED, QStringLiteral(
"demoEdgesCompletedChanged"));
100 registerProperty(IFACE_UNITY_PRIVATE, PROP_FAILED_LOGINS, QStringLiteral(
"failedLoginsChanged"));
102 registerProxy(IFACE_UBUNTU_INPUT, PROP_MOUSE_CURSOR_SPEED,
103 m_unityInput, QStringLiteral(
"setMouseCursorSpeed"));
104 registerProxy(IFACE_UBUNTU_INPUT, PROP_MOUSE_DOUBLE_CLICK_SPEED,
105 m_unityInput, QStringLiteral(
"setMouseDoubleClickSpeed"));
106 registerProxy(IFACE_UBUNTU_INPUT, PROP_MOUSE_PRIMARY_BUTTON,
107 m_unityInput, QStringLiteral(
"setMousePrimaryButton"),
108 primaryButtonConverter);
109 registerProxy(IFACE_UBUNTU_INPUT, PROP_MOUSE_SCROLL_SPEED,
110 m_unityInput, QStringLiteral(
"setMouseScrollSpeed"));
111 registerProxy(IFACE_UBUNTU_INPUT, PROP_TOUCHPAD_CURSOR_SPEED,
112 m_unityInput, QStringLiteral(
"setTouchpadCursorSpeed"));
113 registerProxy(IFACE_UBUNTU_INPUT, PROP_TOUCHPAD_SCROLL_SPEED,
114 m_unityInput, QStringLiteral(
"setTouchpadScrollSpeed"));
115 registerProxy(IFACE_UBUNTU_INPUT, PROP_TOUCHPAD_DISABLE_WHILE_TYPING,
116 m_unityInput, QStringLiteral(
"setTouchpadDisableWhileTyping"));
117 registerProxy(IFACE_UBUNTU_INPUT, PROP_TOUCHPAD_DISABLE_WITH_MOUSE,
118 m_unityInput, QStringLiteral(
"setTouchpadDisableWithMouse"));
119 registerProxy(IFACE_UBUNTU_INPUT, PROP_TOUCHPAD_DOUBLE_CLICK_SPEED,
120 m_unityInput, QStringLiteral(
"setTouchpadDoubleClickSpeed"));
121 registerProxy(IFACE_UBUNTU_INPUT, PROP_TOUCHPAD_PRIMARY_BUTTON,
122 m_unityInput, QStringLiteral(
"setTouchpadPrimaryButton"),
123 primaryButtonConverter);
124 registerProxy(IFACE_UBUNTU_INPUT, PROP_TOUCHPAD_TAP_TO_CLICK,
125 m_unityInput, QStringLiteral(
"setTouchpadTapToClick"));
126 registerProxy(IFACE_UBUNTU_INPUT, PROP_TOUCHPAD_TWO_FINGER_SCROLL,
127 m_unityInput, QStringLiteral(
"setTouchpadTwoFingerScroll"));
129 setUser(!user.isEmpty() ? user : QString::fromUtf8(qgetenv(
"USER")));
132 QString AccountsService::user()
const 137 void AccountsService::setUser(
const QString &user)
139 if (user.isEmpty() || m_user == user)
142 bool wasEmpty = m_user.isEmpty();
145 Q_EMIT userChanged();
152 bool AccountsService::demoEdges()
const 154 auto value = getProperty(IFACE_UNITY, PROP_DEMO_EDGES);
155 return value.toBool();
158 void AccountsService::setDemoEdges(
bool demoEdges)
160 setProperty(IFACE_UNITY, PROP_DEMO_EDGES, demoEdges);
163 QStringList AccountsService::demoEdgesCompleted()
const 165 auto value = getProperty(IFACE_UNITY, PROP_DEMO_EDGES_COMPLETED);
166 return value.toStringList();
169 void AccountsService::markDemoEdgeCompleted(
const QString &edge)
171 auto currentList = demoEdgesCompleted();
172 if (!currentList.contains(edge)) {
173 setProperty(IFACE_UNITY, PROP_DEMO_EDGES_COMPLETED, currentList << edge);
177 bool AccountsService::enableLauncherWhileLocked()
const 179 auto value = getProperty(IFACE_UBUNTU_SECURITY, PROP_ENABLE_LAUNCHER_WHILE_LOCKED);
180 return value.toBool();
183 bool AccountsService::enableIndicatorsWhileLocked()
const 185 auto value = getProperty(IFACE_UBUNTU_SECURITY, PROP_ENABLE_INDICATORS_WHILE_LOCKED);
186 return value.toBool();
189 QString AccountsService::backgroundFile()
const 191 auto value = getProperty(IFACE_ACCOUNTS_USER, PROP_BACKGROUND_FILE);
192 return value.toString();
195 bool AccountsService::statsWelcomeScreen()
const 197 auto value = getProperty(IFACE_UBUNTU_SECURITY_OLD, PROP_STATS_WELCOME_SCREEN);
198 return value.toBool();
201 AccountsService::PasswordDisplayHint AccountsService::passwordDisplayHint()
const 203 auto value = getProperty(IFACE_UBUNTU_SECURITY, PROP_PASSWORD_DISPLAY_HINT);
204 return (PasswordDisplayHint)value.toInt();
207 bool AccountsService::hereEnabled()
const 209 auto value = getProperty(IFACE_LOCATION_HERE, PROP_LICENSE_ACCEPTED);
210 return value.toBool();
213 void AccountsService::setHereEnabled(
bool enabled)
215 setProperty(IFACE_LOCATION_HERE, PROP_LICENSE_ACCEPTED, enabled);
218 QString AccountsService::hereLicensePath()
const 220 auto value = getProperty(IFACE_LOCATION_HERE, PROP_LICENSE_BASE_PATH);
221 QString hereLicensePath = value.toString();
222 if (hereLicensePath.isEmpty() || !QFile::exists(hereLicensePath))
223 hereLicensePath = QStringLiteral(
"");
224 return hereLicensePath;
227 bool AccountsService::hereLicensePathValid()
const 229 auto value = getProperty(IFACE_LOCATION_HERE, PROP_LICENSE_BASE_PATH);
230 return !value.toString().isNull();
233 QString AccountsService::realName()
const 235 auto value = getProperty(IFACE_ACCOUNTS_USER, PROP_REAL_NAME);
236 return value.toString();
239 void AccountsService::setRealName(
const QString &realName)
241 setProperty(IFACE_ACCOUNTS_USER, PROP_REAL_NAME, realName);
244 QString AccountsService::email()
const 246 auto value = getProperty(IFACE_ACCOUNTS_USER, PROP_EMAIL);
247 return value.toString();
250 void AccountsService::setEmail(
const QString &email)
252 setProperty(IFACE_ACCOUNTS_USER, PROP_EMAIL, email);
255 QStringList AccountsService::keymaps()
const 257 auto value = getProperty(IFACE_ACCOUNTS_USER, PROP_INPUT_SOURCES);
258 QDBusArgument arg = value.value<QDBusArgument>();
259 StringMapList maps = qdbus_cast<StringMapList>(arg);
260 QStringList simplifiedMaps;
262 Q_FOREACH(
const StringMap &map, maps) {
263 Q_FOREACH(
const QString &entry, map) {
264 simplifiedMaps.append(entry);
268 if (!simplifiedMaps.isEmpty()) {
269 return simplifiedMaps;
272 return {QStringLiteral(
"us")};
275 uint AccountsService::failedLogins()
const 277 return getProperty(IFACE_UNITY_PRIVATE, PROP_FAILED_LOGINS).toUInt();
280 void AccountsService::setFailedLogins(uint failedLogins)
282 setProperty(IFACE_UNITY_PRIVATE, PROP_FAILED_LOGINS, failedLogins);
289 void AccountsService::emitChangedForProperty(
const QString &interface,
const QString &property)
291 QString signalName = m_properties[interface][property].signal;
292 QMetaObject::invokeMethod(
this, signalName.toUtf8().data());
295 QVariant AccountsService::getProperty(
const QString &interface,
const QString &property)
const 297 return m_properties[interface][property].value;
300 void AccountsService::setProperty(
const QString &interface,
const QString &property,
const QVariant &value)
302 if (m_properties[interface][property].value != value) {
303 m_properties[interface][property].value = value;
304 m_service->setUserPropertyAsync(m_user, interface, property, value);
305 emitChangedForProperty(interface, property);
309 void AccountsService::updateCache(
const QString &interface,
const QString &property,
const QVariant &value)
311 PropertyInfo &info = m_properties[interface][property];
313 if (info.proxyInterface) {
315 if (info.proxyConverter) {
316 finalValue = info.proxyConverter(value);
320 info.proxyInterface->asyncCall(info.proxyMethod, finalValue);
324 if (info.value != value) {
326 emitChangedForProperty(interface, property);
330 void AccountsService::updateProperty(
const QString &interface,
const QString &property)
332 QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
335 QDBusPendingCallWatcher *watcher =
new QDBusPendingCallWatcher(pendingReply,
this);
337 connect(watcher, &QDBusPendingCallWatcher::finished,
338 this, [
this, interface, property](QDBusPendingCallWatcher* watcher) {
340 QDBusPendingReply<QVariant> reply = *watcher;
341 watcher->deleteLater();
342 if (reply.isError()) {
343 qWarning() <<
"Failed to get '" <<
property <<
"' property:" << reply.error().message();
347 updateCache(interface, property, reply.value());
351 void AccountsService::updateAllProperties(
const QString &interface,
bool async)
353 QDBusPendingCall pendingReply = m_service->getAllPropertiesAsync(m_user,
355 QDBusPendingCallWatcher *watcher =
new QDBusPendingCallWatcher(pendingReply,
this);
357 connect(watcher, &QDBusPendingCallWatcher::finished,
358 this, [
this, interface](QDBusPendingCallWatcher* watcher) {
360 QDBusPendingReply< QHash<QString, QVariant> > reply = *watcher;
361 watcher->deleteLater();
362 if (reply.isError()) {
363 qWarning() <<
"Failed to get all properties for" <<
interface << ":" << reply.error().message();
367 auto valueHash = reply.value();
368 auto i = valueHash.constBegin();
369 while (i != valueHash.constEnd()) {
370 updateCache(interface, i.key(), i.value());
375 watcher->waitForFinished();
379 void AccountsService::registerProxy(const QString &interface, const QString &property, QDBusInterface *iface, const QString &method, ProxyConverter converter)
381 registerProperty(interface, property,
nullptr);
383 m_properties[interface][property].proxyInterface = iface;
384 m_properties[interface][property].proxyMethod = method;
385 m_properties[interface][property].proxyConverter = converter;
388 void AccountsService::registerProperty(
const QString &interface,
const QString &property,
const QString &signal)
390 m_properties[interface][property] = PropertyInfo();
391 m_properties[interface][property].signal = signal;
394 void AccountsService::onPropertiesChanged(
const QString &user,
const QString &interface,
const QStringList &changed)
396 if (m_user != user) {
400 auto propHash = m_properties.value(interface);
401 auto i = propHash.constBegin();
402 while (i != propHash.constEnd()) {
403 if (changed.contains(i.key())) {
404 updateProperty(interface, i.key());
410 void AccountsService::onMaybeChanged(
const QString &user)
412 if (m_user != user) {
417 auto propHash = m_properties.value(IFACE_ACCOUNTS_USER);
418 auto i = propHash.constBegin();
419 while (i != propHash.constEnd()) {
420 updateProperty(IFACE_ACCOUNTS_USER, i.key());
425 void AccountsService::refresh(
bool async)
427 auto i = m_properties.constBegin();
428 while (i != m_properties.constEnd()) {
429 updateAllProperties(i.key(), async);