19 #include "AccountsService.h" 20 #include "AccountsServiceDBusAdaptor.h" 22 #include <QDBusInterface> 24 #include <QStringList> 27 #define IFACE_ACCOUNTS_USER QStringLiteral("org.freedesktop.Accounts.User") 28 #define IFACE_LOCATION_HERE QStringLiteral("com.ubuntu.location.providers.here.AccountsService") 29 #define IFACE_UBUNTU_INPUT QStringLiteral("com.ubuntu.AccountsService.Input") 30 #define IFACE_UBUNTU_SECURITY QStringLiteral("com.ubuntu.AccountsService.SecurityPrivacy") 31 #define IFACE_UBUNTU_SECURITY_OLD QStringLiteral("com.ubuntu.touch.AccountsService.SecurityPrivacy") 32 #define IFACE_UNITY QStringLiteral("com.canonical.unity.AccountsService") 33 #define IFACE_UNITY_PRIVATE QStringLiteral("com.canonical.unity.AccountsService.Private") 35 #define PROP_BACKGROUND_FILE QStringLiteral("BackgroundFile") 36 #define PROP_DEMO_EDGES QStringLiteral("demo-edges") 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_LICENSE_ACCEPTED QStringLiteral("LicenseAccepted") 41 #define PROP_LICENSE_BASE_PATH QStringLiteral("LicenseBasePath") 42 #define PROP_MOUSE_CURSOR_SPEED QStringLiteral("MouseCursorSpeed") 43 #define PROP_MOUSE_DOUBLE_CLICK_SPEED QStringLiteral("MouseDoubleClickSpeed") 44 #define PROP_MOUSE_PRIMARY_BUTTON QStringLiteral("MousePrimaryButton") 45 #define PROP_MOUSE_SCROLL_SPEED QStringLiteral("MouseScrollSpeed") 46 #define PROP_PASSWORD_DISPLAY_HINT QStringLiteral("PasswordDisplayHint") 47 #define PROP_STATS_WELCOME_SCREEN QStringLiteral("StatsWelcomeScreen") 48 #define PROP_TOUCHPAD_CURSOR_SPEED QStringLiteral("TouchpadCursorSpeed") 49 #define PROP_TOUCHPAD_DISABLE_WHILE_TYPING QStringLiteral("TouchpadDisableWhileTyping") 50 #define PROP_TOUCHPAD_DISABLE_WITH_MOUSE QStringLiteral("TouchpadDisableWithMouse") 51 #define PROP_TOUCHPAD_DOUBLE_CLICK_SPEED QStringLiteral("TouchpadDoubleClickSpeed") 52 #define PROP_TOUCHPAD_PRIMARY_BUTTON QStringLiteral("TouchpadPrimaryButton") 53 #define PROP_TOUCHPAD_SCROLL_SPEED QStringLiteral("TouchpadScrollSpeed") 54 #define PROP_TOUCHPAD_TAP_TO_CLICK QStringLiteral("TouchpadTapToClick") 55 #define PROP_TOUCHPAD_TWO_FINGER_SCROLL QStringLiteral("TouchpadTwoFingerScroll") 58 QVariant primaryButtonConverter(
const QVariant &value)
60 QString stringValue = value.toString();
61 if (stringValue ==
"left") {
62 return QVariant::fromValue(0);
63 }
else if (stringValue ==
"right") {
64 return QVariant::fromValue(1);
66 return QVariant::fromValue(0);
70 AccountsService::AccountsService(QObject* parent,
const QString &user)
72 , m_service(new AccountsServiceDBusAdaptor(this))
74 m_unityInput =
new QDBusInterface(QStringLiteral(
"com.canonical.Unity.Input"),
75 QStringLiteral(
"/com/canonical/Unity/Input"),
76 QStringLiteral(
"com.canonical.Unity.Input"),
77 QDBusConnection::SM_BUSNAME(),
this);
79 connect(m_service, &AccountsServiceDBusAdaptor::propertiesChanged,
this, &AccountsService::onPropertiesChanged);
80 connect(m_service, &AccountsServiceDBusAdaptor::maybeChanged,
this, &AccountsService::onMaybeChanged);
82 registerProperty(IFACE_ACCOUNTS_USER, PROP_BACKGROUND_FILE, QStringLiteral(
"backgroundFileChanged"));
83 registerProperty(IFACE_LOCATION_HERE, PROP_LICENSE_ACCEPTED, QStringLiteral(
"hereEnabledChanged"));
84 registerProperty(IFACE_LOCATION_HERE, PROP_LICENSE_BASE_PATH, QStringLiteral(
"hereLicensePathChanged"));
85 registerProperty(IFACE_UBUNTU_SECURITY, PROP_ENABLE_LAUNCHER_WHILE_LOCKED, QStringLiteral(
"enableLauncherWhileLockedChanged"));
86 registerProperty(IFACE_UBUNTU_SECURITY, PROP_ENABLE_INDICATORS_WHILE_LOCKED, QStringLiteral(
"enableIndicatorsWhileLockedChanged"));
87 registerProperty(IFACE_UBUNTU_SECURITY, PROP_PASSWORD_DISPLAY_HINT, QStringLiteral(
"passwordDisplayHintChanged"));
88 registerProperty(IFACE_UBUNTU_SECURITY_OLD, PROP_STATS_WELCOME_SCREEN, QStringLiteral(
"statsWelcomeScreenChanged"));
89 registerProperty(IFACE_UNITY, PROP_DEMO_EDGES, QStringLiteral(
"demoEdgesChanged"));
90 registerProperty(IFACE_UNITY_PRIVATE, PROP_FAILED_LOGINS, QStringLiteral(
"failedLoginsChanged"));
92 registerProxy(IFACE_UBUNTU_INPUT, PROP_MOUSE_CURSOR_SPEED,
93 m_unityInput, QStringLiteral(
"setMouseCursorSpeed"));
94 registerProxy(IFACE_UBUNTU_INPUT, PROP_MOUSE_DOUBLE_CLICK_SPEED,
95 m_unityInput, QStringLiteral(
"setMouseDoubleClickSpeed"));
96 registerProxy(IFACE_UBUNTU_INPUT, PROP_MOUSE_PRIMARY_BUTTON,
97 m_unityInput, QStringLiteral(
"setMousePrimaryButton"),
98 primaryButtonConverter);
99 registerProxy(IFACE_UBUNTU_INPUT, PROP_MOUSE_SCROLL_SPEED,
100 m_unityInput, QStringLiteral(
"setMouseScrollSpeed"));
101 registerProxy(IFACE_UBUNTU_INPUT, PROP_TOUCHPAD_CURSOR_SPEED,
102 m_unityInput, QStringLiteral(
"setTouchpadCursorSpeed"));
103 registerProxy(IFACE_UBUNTU_INPUT, PROP_TOUCHPAD_SCROLL_SPEED,
104 m_unityInput, QStringLiteral(
"setTouchpadScrollSpeed"));
105 registerProxy(IFACE_UBUNTU_INPUT, PROP_TOUCHPAD_DISABLE_WHILE_TYPING,
106 m_unityInput, QStringLiteral(
"setTouchpadDisableWhileTyping"));
107 registerProxy(IFACE_UBUNTU_INPUT, PROP_TOUCHPAD_DISABLE_WITH_MOUSE,
108 m_unityInput, QStringLiteral(
"setTouchpadDisableWithMouse"));
109 registerProxy(IFACE_UBUNTU_INPUT, PROP_TOUCHPAD_DOUBLE_CLICK_SPEED,
110 m_unityInput, QStringLiteral(
"setTouchpadDoubleClickSpeed"));
111 registerProxy(IFACE_UBUNTU_INPUT, PROP_TOUCHPAD_PRIMARY_BUTTON,
112 m_unityInput, QStringLiteral(
"setTouchpadPrimaryButton"),
113 primaryButtonConverter);
114 registerProxy(IFACE_UBUNTU_INPUT, PROP_TOUCHPAD_TAP_TO_CLICK,
115 m_unityInput, QStringLiteral(
"setTouchpadTapToClick"));
116 registerProxy(IFACE_UBUNTU_INPUT, PROP_TOUCHPAD_TWO_FINGER_SCROLL,
117 m_unityInput, QStringLiteral(
"setTouchpadTwoFingerScroll"));
119 setUser(!user.isEmpty() ? user : QString::fromUtf8(qgetenv(
"USER")));
122 QString AccountsService::user()
const 127 void AccountsService::setUser(
const QString &user)
129 if (user.isEmpty() || m_user == user)
132 bool wasEmpty = m_user.isEmpty();
135 Q_EMIT userChanged();
142 bool AccountsService::demoEdges()
const 144 auto value = getProperty(IFACE_UNITY, PROP_DEMO_EDGES);
145 return value.toBool();
148 void AccountsService::setDemoEdges(
bool demoEdges)
150 setProperty(IFACE_UNITY, PROP_DEMO_EDGES, demoEdges);
153 bool AccountsService::enableLauncherWhileLocked()
const 155 auto value = getProperty(IFACE_UBUNTU_SECURITY, PROP_ENABLE_LAUNCHER_WHILE_LOCKED);
156 return value.toBool();
159 bool AccountsService::enableIndicatorsWhileLocked()
const 161 auto value = getProperty(IFACE_UBUNTU_SECURITY, PROP_ENABLE_INDICATORS_WHILE_LOCKED);
162 return value.toBool();
165 QString AccountsService::backgroundFile()
const 167 auto value = getProperty(IFACE_ACCOUNTS_USER, PROP_BACKGROUND_FILE);
168 return value.toString();
171 bool AccountsService::statsWelcomeScreen()
const 173 auto value = getProperty(IFACE_UBUNTU_SECURITY_OLD, PROP_STATS_WELCOME_SCREEN);
174 return value.toBool();
177 AccountsService::PasswordDisplayHint AccountsService::passwordDisplayHint()
const 179 auto value = getProperty(IFACE_UBUNTU_SECURITY, PROP_PASSWORD_DISPLAY_HINT);
180 return (PasswordDisplayHint)value.toInt();
183 bool AccountsService::hereEnabled()
const 185 auto value = getProperty(IFACE_LOCATION_HERE, PROP_LICENSE_ACCEPTED);
186 return value.toBool();
189 void AccountsService::setHereEnabled(
bool enabled)
191 setProperty(IFACE_LOCATION_HERE, PROP_LICENSE_ACCEPTED, enabled);
194 QString AccountsService::hereLicensePath()
const 196 auto value = getProperty(IFACE_LOCATION_HERE, PROP_LICENSE_BASE_PATH);
197 QString hereLicensePath = value.toString();
198 if (hereLicensePath.isEmpty() || !QFile::exists(hereLicensePath))
199 hereLicensePath = QStringLiteral(
"");
200 return hereLicensePath;
203 bool AccountsService::hereLicensePathValid()
const 205 auto value = getProperty(IFACE_LOCATION_HERE, PROP_LICENSE_BASE_PATH);
206 return !value.toString().isNull();
209 uint AccountsService::failedLogins()
const 211 return getProperty(IFACE_UNITY_PRIVATE, PROP_FAILED_LOGINS).toUInt();
214 void AccountsService::setFailedLogins(uint failedLogins)
216 setProperty(IFACE_UNITY_PRIVATE, PROP_FAILED_LOGINS, failedLogins);
223 void AccountsService::emitChangedForProperty(
const QString &interface,
const QString &property)
225 QString signalName = m_properties[interface][property].signal;
226 QMetaObject::invokeMethod(
this, signalName.toUtf8().data());
229 QVariant AccountsService::getProperty(
const QString &interface,
const QString &property)
const 231 return m_properties[interface][property].value;
234 void AccountsService::setProperty(
const QString &interface,
const QString &property,
const QVariant &value)
236 if (m_properties[interface][property].value != value) {
237 m_properties[interface][property].value = value;
238 m_service->setUserPropertyAsync(m_user, interface, property, value);
239 emitChangedForProperty(interface, property);
243 void AccountsService::updateCache(
const QString &interface,
const QString &property,
const QVariant &value)
245 PropertyInfo &info = m_properties[interface][property];
247 if (info.proxyInterface) {
249 if (info.proxyConverter) {
250 finalValue = info.proxyConverter(value);
254 info.proxyInterface->asyncCall(info.proxyMethod, finalValue);
258 if (info.value != value) {
260 emitChangedForProperty(interface, property);
264 void AccountsService::updateProperty(
const QString &interface,
const QString &property)
266 QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
269 QDBusPendingCallWatcher *watcher =
new QDBusPendingCallWatcher(pendingReply,
this);
271 connect(watcher, &QDBusPendingCallWatcher::finished,
272 this, [
this, interface, property](QDBusPendingCallWatcher* watcher) {
274 QDBusPendingReply<QVariant> reply = *watcher;
275 watcher->deleteLater();
276 if (reply.isError()) {
277 qWarning() <<
"Failed to get '" <<
property <<
"' property:" << reply.error().message();
281 updateCache(interface, property, reply.value());
285 void AccountsService::updateAllProperties(
const QString &interface,
bool async)
287 QDBusPendingCall pendingReply = m_service->getAllPropertiesAsync(m_user,
289 QDBusPendingCallWatcher *watcher =
new QDBusPendingCallWatcher(pendingReply,
this);
291 connect(watcher, &QDBusPendingCallWatcher::finished,
292 this, [
this, interface](QDBusPendingCallWatcher* watcher) {
294 QDBusPendingReply< QHash<QString, QVariant> > reply = *watcher;
295 watcher->deleteLater();
296 if (reply.isError()) {
297 qWarning() <<
"Failed to get all properties for" <<
interface << ":" << reply.error().message();
301 auto valueHash = reply.value();
302 auto i = valueHash.constBegin();
303 while (i != valueHash.constEnd()) {
304 updateCache(interface, i.key(), i.value());
309 watcher->waitForFinished();
313 void AccountsService::registerProxy(const QString &interface, const QString &property, QDBusInterface *iface, const QString &method, ProxyConverter converter)
315 registerProperty(interface, property,
nullptr);
317 m_properties[interface][property].proxyInterface = iface;
318 m_properties[interface][property].proxyMethod = method;
319 m_properties[interface][property].proxyConverter = converter;
322 void AccountsService::registerProperty(
const QString &interface,
const QString &property,
const QString &signal)
324 m_properties[interface][property] = PropertyInfo();
325 m_properties[interface][property].signal = signal;
328 void AccountsService::onPropertiesChanged(
const QString &user,
const QString &interface,
const QStringList &changed)
330 if (m_user != user) {
334 auto propHash = m_properties.value(interface);
335 auto i = propHash.constBegin();
336 while (i != propHash.constEnd()) {
337 if (changed.contains(i.key())) {
338 updateProperty(interface, i.key());
344 void AccountsService::onMaybeChanged(
const QString &user)
346 if (m_user != user) {
351 auto propHash = m_properties.value(IFACE_ACCOUNTS_USER);
352 auto i = propHash.constBegin();
353 while (i != propHash.constEnd()) {
354 updateProperty(IFACE_ACCOUNTS_USER, i.key());
359 void AccountsService::refresh(
bool async)
361 auto i = m_properties.constBegin();
362 while (i != m_properties.constEnd()) {
363 updateAllProperties(i.key(), async);