on xenial help sign in
Proxy more input settings to USC
8538852Michael Terry
plugins/AccountsService/AccountsService.cpp+54−2
@@ -40,9 +40,32 @@
40#define PROP_LICENSE_ACCEPTED QStringLiteral("LicenseAccepted")
40#define PROP_LICENSE_ACCEPTED QStringLiteral("LicenseAccepted")
41#define PROP_LICENSE_BASE_PATH QStringLiteral("LicenseBasePath")
41#define PROP_LICENSE_BASE_PATH QStringLiteral("LicenseBasePath")
42#define PROP_MOUSE_CURSOR_SPEED QStringLiteral("MouseCursorSpeed")
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")
43#define PROP_PASSWORD_DISPLAY_HINT QStringLiteral("PasswordDisplayHint")
46#define PROP_PASSWORD_DISPLAY_HINT QStringLiteral("PasswordDisplayHint")
44#define PROP_STATS_WELCOME_SCREEN QStringLiteral("StatsWelcomeScreen")
47#define PROP_STATS_WELCOME_SCREEN QStringLiteral("StatsWelcomeScreen")
45#define PROP_TOUCHPAD_CURSOR_SPEED QStringLiteral("TouchpadCursorSpeed")
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")
56+
57+
58+QVariant primaryButtonConverter(const QVariant &value)
59+{
60+ QString stringValue = value.toString();
61+ if (stringValue == "left") {
62+ return QVariant::fromValue(0);
63+ } else if (stringValue == "right") {
64+ return QVariant::fromValue(1); // Mir is less clear on this -- any non-zero value is the same
65+ } else {
66+ return QVariant::fromValue(0); // default to left
67+ }
68+}
46
69
47AccountsService::AccountsService(QObject* parent, const QString &user)
70AccountsService::AccountsService(QObject* parent, const QString &user)
48 : QObject(parent)
71 : QObject(parent)
@@ -68,8 +91,30 @@ AccountsService::AccountsService(QObject* parent, const QString &user)
68
91
69 registerProxy(IFACE_UBUNTU_INPUT, PROP_MOUSE_CURSOR_SPEED,
92 registerProxy(IFACE_UBUNTU_INPUT, PROP_MOUSE_CURSOR_SPEED,
70 m_unityInput, QStringLiteral("setMouseCursorSpeed"));
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"));
71 registerProxy(IFACE_UBUNTU_INPUT, PROP_TOUCHPAD_CURSOR_SPEED,
101 registerProxy(IFACE_UBUNTU_INPUT, PROP_TOUCHPAD_CURSOR_SPEED,
72 m_unityInput, QStringLiteral("setTouchpadCursorSpeed"));
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"));
73
118
74 setUser(!user.isEmpty() ? user : QString::fromUtf8(qgetenv("USER")));
119 setUser(!user.isEmpty() ? user : QString::fromUtf8(qgetenv("USER")));
75}
120}
@@ -200,7 +245,13 @@ void AccountsService::updateCache(const QString &interface, const QString &prope
200 PropertyInfo &info = m_properties[interface][property];
245 PropertyInfo &info = m_properties[interface][property];
201
246
202 if (info.proxyInterface) {
247 if (info.proxyInterface) {
248+ QVariant finalValue;
249+ if (info.proxyConverter) {
250+ finalValue = info.proxyConverter(value);
251+ } else {
252+ finalValue = value;
253+ }
203− info.proxyInterface->asyncCall(info.proxyMethod, value);
254+ info.proxyInterface->asyncCall(info.proxyMethod, finalValue);
204 return; // don't bother saving a copy
255 return; // don't bother saving a copy
205 }
256 }
206
257
@@ -259,12 +310,13 @@ void AccountsService::updateAllProperties(const QString &interface, bool async)
259 }
310 }
260}
311}
261
312
262−void AccountsService::registerProxy(const QString &interface, const QString &property, QDBusInterface *iface, const QString &method)
313+void AccountsService::registerProxy(const QString &interface, const QString &property, QDBusInterface *iface, const QString &method, ProxyConverter converter)
263{
314{
264 registerProperty(interface, property, nullptr);
315 registerProperty(interface, property, nullptr);
265
316
266 m_properties[interface][property].proxyInterface = iface;
317 m_properties[interface][property].proxyInterface = iface;
267 m_properties[interface][property].proxyMethod = method;
318 m_properties[interface][property].proxyMethod = method;
319+ m_properties[interface][property].proxyConverter = converter;
268}
320}
269
321
270void AccountsService::registerProperty(const QString &interface, const QString &property, const QString &signal)
322void AccountsService::registerProperty(const QString &interface, const QString &property, const QString &signal)
plugins/AccountsService/AccountsService.h+4−1
@@ -111,9 +111,11 @@ private Q_SLOTS:
111 void onMaybeChanged(const QString &user);
111 void onMaybeChanged(const QString &user);
112
112
113private:
113private:
114+ typedef QVariant (*ProxyConverter)(const QVariant &);
115+
114 void refresh(bool async);
116 void refresh(bool async);
115 void registerProperty(const QString &interface, const QString &property, const QString &signal);
117 void registerProperty(const QString &interface, const QString &property, const QString &signal);
116− void registerProxy(const QString &interface, const QString &property, QDBusInterface *iface, const QString &method);
118+ void registerProxy(const QString &interface, const QString &property, QDBusInterface *iface, const QString &method, ProxyConverter converter = nullptr);
117
119
118 void updateAllProperties(const QString &interface, bool async);
120 void updateAllProperties(const QString &interface, bool async);
119 void updateProperty(const QString &interface, const QString &property);
121 void updateProperty(const QString &interface, const QString &property);
@@ -129,6 +131,7 @@ private:
129 QString signal{};
131 QString signal{};
130 QDBusInterface *proxyInterface{};
132 QDBusInterface *proxyInterface{};
131 QString proxyMethod{};
133 QString proxyMethod{};
134+ ProxyConverter proxyConverter{};
132 };
135 };
133 typedef QHash< QString, QHash<QString, PropertyInfo> > PropertyHash;
136 typedef QHash< QString, QHash<QString, PropertyInfo> > PropertyHash;
134 PropertyHash m_properties;
137 PropertyHash m_properties;
tests/plugins/AccountsService/CMakeLists.txt+3
@@ -16,6 +16,7 @@ make_dbus_class(SecurityPrivacy com.ubuntu.touch.AccountsService.SecurityPrivacy
16make_dbus_class(Location com.ubuntu.location.providers.here.AccountsService)
16make_dbus_class(Location com.ubuntu.location.providers.here.AccountsService)
17make_dbus_class(AccountsUser org.freedesktop.Accounts.User)
17make_dbus_class(AccountsUser org.freedesktop.Accounts.User)
18make_dbus_class(AccountsPrivate com.canonical.unity.AccountsService.Private)
18make_dbus_class(AccountsPrivate com.canonical.unity.AccountsService.Private)
19+make_dbus_class(UscInput com.canonical.Unity.Input)
19
20
20include_directories(
21include_directories(
21 ${CMAKE_CURRENT_BINARY_DIR}
22 ${CMAKE_CURRENT_BINARY_DIR}
@@ -32,9 +33,11 @@ add_executable(mock-server
32 ${CMAKE_CURRENT_BINARY_DIR}/PropertiesAdaptor.cpp
33 ${CMAKE_CURRENT_BINARY_DIR}/PropertiesAdaptor.cpp
33 ${CMAKE_CURRENT_BINARY_DIR}/LocationAdaptor.cpp
34 ${CMAKE_CURRENT_BINARY_DIR}/LocationAdaptor.cpp
34 ${CMAKE_CURRENT_BINARY_DIR}/SecurityPrivacyAdaptor.cpp
35 ${CMAKE_CURRENT_BINARY_DIR}/SecurityPrivacyAdaptor.cpp
36+ ${CMAKE_CURRENT_BINARY_DIR}/UscInputAdaptor.cpp
35 server.cpp
37 server.cpp
36 AccountsServer.cpp
38 AccountsServer.cpp
37 PropertiesServer.cpp
39 PropertiesServer.cpp
40+ UscServer.cpp
38 )
41 )
39qt5_use_modules(mock-server Core DBus)
42qt5_use_modules(mock-server Core DBus)
40
43
tests/plugins/AccountsService/PropertiesServer.cpp+1−2
@@ -92,8 +92,7 @@ void PropertiesServer::Reset()
92 m_properties["com.canonical.unity.AccountsService"]["LauncherItems"] = QVariant::fromValue(QList<QVariantMap>());
92 m_properties["com.canonical.unity.AccountsService"]["LauncherItems"] = QVariant::fromValue(QList<QVariantMap>());
93 m_properties["com.canonical.unity.AccountsService.Private"]["FailedLogins"] = 0;
93 m_properties["com.canonical.unity.AccountsService.Private"]["FailedLogins"] = 0;
94 m_properties["com.ubuntu.touch.AccountsService.SecurityPrivacy"]["StatsWelcomeScreen"] = true;
94 m_properties["com.ubuntu.touch.AccountsService.SecurityPrivacy"]["StatsWelcomeScreen"] = true;
95− m_properties["com.ubuntu.AccountsService.Input"]["MouseCursorSpeed"] = 0.5;
95+ m_properties["com.ubuntu.AccountsService.Input"]["MousePrimaryButton"] = "right";
96− m_properties["com.ubuntu.AccountsService.Input"]["TouchpadCursorSpeed"] = 0.5;
97 m_properties["com.ubuntu.AccountsService.SecurityPrivacy"]["EnableLauncherWhileLocked"] = true;
96 m_properties["com.ubuntu.AccountsService.SecurityPrivacy"]["EnableLauncherWhileLocked"] = true;
98 m_properties["com.ubuntu.AccountsService.SecurityPrivacy"]["EnableIndicatorsWhileLocked"] = true;
97 m_properties["com.ubuntu.AccountsService.SecurityPrivacy"]["EnableIndicatorsWhileLocked"] = true;
99 m_properties["com.ubuntu.AccountsService.SecurityPrivacy"]["PasswordDisplayHint"] = AccountsService::Keyboard;
98 m_properties["com.ubuntu.AccountsService.SecurityPrivacy"]["PasswordDisplayHint"] = AccountsService::Keyboard;
tests/plugins/AccountsService/client.cpp+54
@@ -42,7 +42,16 @@ public:
42 : QObject(parent)
42 : QObject(parent)
43 , m_userInterface(nullptr)
43 , m_userInterface(nullptr)
44 , m_spy(this, &AccountsServiceTest::propertiesChanged)
44 , m_spy(this, &AccountsServiceTest::propertiesChanged)
45+ , m_mousePrimaryButtonSpy(this, &AccountsServiceTest::setMousePrimaryButtonCalled)
45 {
46 {
47+ m_uscInputInterface = new QDBusInterface("com.canonical.Unity.Input",
48+ "/com/canonical/Unity/Input",
49+ "com.canonical.Unity.Input",
50+ QDBusConnection::sessionBus(),
51+ this);
52+
53+ QObject::connect(m_uscInputInterface, SIGNAL(setMousePrimaryButtonCalled(int)),
54+ this, SIGNAL(setMousePrimaryButtonCalled(int)));
46 }
55 }
47
56
48private Q_SLOTS:
57private Q_SLOTS:
@@ -71,6 +80,7 @@ private Q_SLOTS:
71
80
72 delete m_userInterface;
81 delete m_userInterface;
73 m_spy.clear();
82 m_spy.clear();
83+ m_mousePrimaryButtonSpy.clear();
74 }
84 }
75
85
76 void testInvalids()
86 void testInvalids()
@@ -215,12 +225,56 @@ private Q_SLOTS:
215 QTRY_COMPARE(session.backgroundFile(), QString("/test/BackgroundFile"));
225 QTRY_COMPARE(session.backgroundFile(), QString("/test/BackgroundFile"));
216 }
226 }
217
227
228+ void testProxyOnStartup()
229+ {
230+ AccountsService session(this, QTest::currentTestFunction());
231+
232+ QTRY_COMPARE(m_mousePrimaryButtonSpy.count(), 1);
233+ QList<QVariant> arguments = m_mousePrimaryButtonSpy.takeFirst();
234+ QCOMPARE(arguments.at(0).toInt(), 1);
235+ }
236+
237+ void testProxyOnChange()
238+ {
239+ AccountsService session(this, QTest::currentTestFunction());
240+ QTRY_COMPARE(m_mousePrimaryButtonSpy.count(), 1);
241+ m_mousePrimaryButtonSpy.clear();
242+
243+ ASSERT_DBUS_CALL(m_userInterface->asyncCall("Set",
244+ "com.ubuntu.AccountsService.Input",
245+ "MousePrimaryButton",
246+ dbusVariant("left")));
247+
248+ QTRY_COMPARE(m_mousePrimaryButtonSpy.count(), 1);
249+ QList<QVariant> arguments = m_mousePrimaryButtonSpy.takeFirst();
250+ QCOMPARE(arguments.at(0).toInt(), 0);
251+ }
252+
253+ void testInvalidPrimaryButton()
254+ {
255+ AccountsService session(this, QTest::currentTestFunction());
256+ QTRY_COMPARE(m_mousePrimaryButtonSpy.count(), 1);
257+ m_mousePrimaryButtonSpy.clear();
258+
259+ ASSERT_DBUS_CALL(m_userInterface->asyncCall("Set",
260+ "com.ubuntu.AccountsService.Input",
261+ "MousePrimaryButton",
262+ dbusVariant("NOPE")));
263+
264+ QTRY_COMPARE(m_mousePrimaryButtonSpy.count(), 1);
265+ QList<QVariant> arguments = m_mousePrimaryButtonSpy.takeFirst();
266+ QCOMPARE(arguments.at(0).toInt(), 0);
267+ }
268+
218Q_SIGNALS:
269Q_SIGNALS:
219 void propertiesChanged(const QString &interface, const QVariantMap &changed, const QStringList &invalid);
270 void propertiesChanged(const QString &interface, const QVariantMap &changed, const QStringList &invalid);
271+ void setMousePrimaryButtonCalled(int button);
220
272
221private:
273private:
274+ QDBusInterface* m_uscInputInterface;
222 QDBusInterface* m_userInterface;
275 QDBusInterface* m_userInterface;
223 QSignalSpy m_spy;
276 QSignalSpy m_spy;
277+ QSignalSpy m_mousePrimaryButtonSpy;
224};
278};
225
279
226QTEST_MAIN(AccountsServiceTest)
280QTEST_MAIN(AccountsServiceTest)
tests/plugins/AccountsService/interfaces.xml+10
@@ -44,4 +44,14 @@
44 <signal name="Changed" />
44 <signal name="Changed" />
45 </interface>
45 </interface>
46 <interface name="com.canonical.unity.AccountsService.Private" />
46 <interface name="com.canonical.unity.AccountsService.Private" />
47+
48+ <interface name="com.canonical.Unity.Input">
49+ <method name="setMousePrimaryButton">
50+ <arg name="button" type="i" direction="in" />
51+ </method>
52+ <!-- Just for testing -->
53+ <signal name="setMousePrimaryButtonCalled">
54+ <arg name="button" type="i" direction="out" />
55+ </signal>
56+ </interface>
47</node>
57</node>
tests/plugins/AccountsService/server.cpp+10
@@ -24,6 +24,8 @@
24#include "SecurityPrivacyAdaptor.h"
24#include "SecurityPrivacyAdaptor.h"
25#include "LocationAdaptor.h"
25#include "LocationAdaptor.h"
26#include "AccountsPrivateAdaptor.h"
26#include "AccountsPrivateAdaptor.h"
27+#include "UscInputAdaptor.h"
28+#include "UscServer.h"
27#include <QCoreApplication>
29#include <QCoreApplication>
28
30
29int main(int argc, char *argv[])
31int main(int argc, char *argv[])
@@ -36,8 +38,16 @@ int main(int argc, char *argv[])
36 new SecurityPrivacyAdaptor(accounts);
38 new SecurityPrivacyAdaptor(accounts);
37 new LocationAdaptor(accounts);
39 new LocationAdaptor(accounts);
38 new AccountsPrivateAdaptor(accounts);
40 new AccountsPrivateAdaptor(accounts);
41+
42+ auto usc = new UscServer(&a);
43+ new UscInputAdaptor(usc);
44+
39 // We use the session bus for testing. The real plugin uses the system bus
45 // We use the session bus for testing. The real plugin uses the system bus
40 auto connection = QDBusConnection::sessionBus();
46 auto connection = QDBusConnection::sessionBus();
47+ if (!connection.registerObject("/com/canonical/Unity/Input", usc))
48+ return 1;
49+ if (!connection.registerService("com.canonical.Unity.Input"))
50+ return 1;
41 if (!connection.registerObject("/org/freedesktop/Accounts", accounts))
51 if (!connection.registerObject("/org/freedesktop/Accounts", accounts))
42 return 1;
52 return 1;
43 if (!connection.registerService("org.freedesktop.Accounts"))
53 if (!connection.registerService("org.freedesktop.Accounts"))