Mir

Merge lp:~andreas-pokorny/mir/store-device-config into lp:mir

Proposed by Andreas Pokorny
Status: Merged
Approved by: Alan Griffiths
Approved revision: no longer in the source branch.
Merged at revision: 4112
Proposed branch: lp:~andreas-pokorny/mir/store-device-config
Merge into: lp:mir
Prerequisite: lp:~andreas-pokorny/mir/move-config-changer-to-input-thread
Diff against target: 484 lines (+314/-14)
6 files modified
src/server/input/default_device.cpp (+69/-11)
src/server/input/default_device.h (+13/-0)
src/server/input/default_input_device_hub.cpp (+52/-3)
src/server/input/default_input_device_hub.h (+7/-0)
tests/unit-tests/input/test_default_device.cpp (+127/-0)
tests/unit-tests/input/test_default_input_device_hub.cpp (+46/-0)
To merge this branch: bzr merge lp:~andreas-pokorny/mir/store-device-config
Reviewer Review Type Date Requested Status
Mir CI Bot continuous-integration Approve
Alan Griffiths Approve
Alexandros Frantzis (community) Approve
Review via email: mp+319871@code.launchpad.net

This proposal supersedes a proposal from 2017-03-09.

Commit message

Store device configurations and device ids

With this change previous configurations of input devices are restored when they reappear.

Description of the change

Store device ids of removed devices to restore them after a vt-switch.

To post a comment you must log in.
Revision history for this message
Mir CI Bot (mir-ci-bot) wrote : Posted in a previous version of this proposal

FAILED: Continuous integration, rev:4070
https://mir-jenkins.ubuntu.com/job/mir-ci/3121/
Executed test runs:
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-mir/4189/console
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-0-fetch/4276
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/4266
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial+overlay/4266
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=zesty/4266
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=zesty/4216/console
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial+overlay/4216
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial+overlay/4216/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=zesty/4216
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=zesty/4216/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=android,release=vivid+overlay/4216
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=android,release=vivid+overlay/4216/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=android,release=vivid+overlay/4216
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=android,release=vivid+overlay/4216/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial+overlay/4216
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial+overlay/4216/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://mir-jenkins.ubuntu.com/job/mir-ci/3121/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
Mir CI Bot (mir-ci-bot) wrote : Posted in a previous version of this proposal

PASSED: Continuous integration, rev:4072
https://mir-jenkins.ubuntu.com/job/mir-ci/3162/
Executed test runs:
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-mir/4243
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-0-fetch/4330
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/4320
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial+overlay/4320
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=zesty/4320
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=zesty/4270
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=zesty/4270/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial+overlay/4270
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial+overlay/4270/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=zesty/4270
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=zesty/4270/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=android,release=vivid+overlay/4270
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=android,release=vivid+overlay/4270/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=android,release=vivid+overlay/4270
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=android,release=vivid+overlay/4270/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial+overlay/4270
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial+overlay/4270/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://mir-jenkins.ubuntu.com/job/mir-ci/3162/rebuild

review: Approve (continuous-integration)
Revision history for this message
Mir CI Bot (mir-ci-bot) wrote :

PASSED: Continuous integration, rev:4072
https://mir-jenkins.ubuntu.com/job/mir-ci/3163/
Executed test runs:
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-mir/4244
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-0-fetch/4331
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/4321
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial+overlay/4321
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=zesty/4321
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=zesty/4271
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=zesty/4271/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial+overlay/4271
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial+overlay/4271/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=zesty/4271
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=zesty/4271/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=android,release=vivid+overlay/4271
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=android,release=vivid+overlay/4271/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=android,release=vivid+overlay/4271
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=android,release=vivid+overlay/4271/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial+overlay/4271
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial+overlay/4271/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://mir-jenkins.ubuntu.com/job/mir-ci/3163/rebuild

review: Approve (continuous-integration)
Revision history for this message
Mir CI Bot (mir-ci-bot) wrote :

PASSED: Continuous integration, rev:4073
https://mir-jenkins.ubuntu.com/job/mir-ci/3166/
Executed test runs:
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-mir/4248
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-0-fetch/4335
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/4325
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial+overlay/4325
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=zesty/4325
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=zesty/4275
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=zesty/4275/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial+overlay/4275
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial+overlay/4275/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=zesty/4275
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=zesty/4275/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=android,release=vivid+overlay/4275
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=android,release=vivid+overlay/4275/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=android,release=vivid+overlay/4275
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=android,release=vivid+overlay/4275/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial+overlay/4275
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial+overlay/4275/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://mir-jenkins.ubuntu.com/job/mir-ci/3166/rebuild

review: Approve (continuous-integration)
Revision history for this message
Alexandros Frantzis (afrantzis) wrote :

Looks good.

review: Approve
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

%s/querried/queried/g

review: Needs Fixing
Revision history for this message
Mir CI Bot (mir-ci-bot) wrote :

FAILED: Continuous integration, rev:4074
https://mir-jenkins.ubuntu.com/job/mir-ci/3211/
Executed test runs:
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-mir/4322/console
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-0-fetch/4409/console
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/4399/console
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial+overlay/4399/console
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=zesty/4399/console
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=zesty/4354/console
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial+overlay/4354/console
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=zesty/4354/console
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=android,release=vivid+overlay/4354/console
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=android,release=vivid+overlay/4354/console
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial+overlay/4354/console

Click here to trigger a rebuild:
https://mir-jenkins.ubuntu.com/job/mir-ci/3211/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
Mir CI Bot (mir-ci-bot) wrote :

PASSED: Continuous integration, rev:4075
https://mir-jenkins.ubuntu.com/job/mir-ci/3213/
Executed test runs:
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-mir/4324
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-0-fetch/4411
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/4401
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial+overlay/4401
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=zesty/4401
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=zesty/4356
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=zesty/4356/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial+overlay/4356
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial+overlay/4356/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=zesty/4356
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=zesty/4356/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=android,release=vivid+overlay/4356
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=android,release=vivid+overlay/4356/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=android,release=vivid+overlay/4356
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=android,release=vivid+overlay/4356/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial+overlay/4356
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial+overlay/4356/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://mir-jenkins.ubuntu.com/job/mir-ci/3213/rebuild

review: Approve (continuous-integration)
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

OK

review: Approve
Revision history for this message
Mir CI Bot (mir-ci-bot) :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/server/input/default_device.cpp'
2--- src/server/input/default_device.cpp 2017-02-28 08:53:57 +0000
3+++ src/server/input/default_device.cpp 2017-03-22 09:43:20 +0000
4@@ -60,6 +60,23 @@
5 {
6 }
7
8+mi::DefaultDevice::DefaultDevice(MirInputDevice const& config,
9+ std::shared_ptr<dispatch::ActionQueue> const& actions,
10+ InputDevice& device,
11+ std::shared_ptr<KeyMapper> const& key_mapper,
12+ std::function<void(Device*)> const& callback)
13+ : DefaultDevice(config.id(), actions, device, key_mapper, callback)
14+{
15+ if (config.has_touchpad_config())
16+ set_touchpad_configuration(config.touchpad_config());
17+ if (config.has_keyboard_config())
18+ set_keyboard_configuration(config.keyboard_config());
19+ if (config.has_pointer_config())
20+ set_pointer_configuration(config.pointer_config());
21+ if (config.has_touchscreen_config())
22+ set_touchscreen_configuration(config.touchscreen_config());
23+}
24+
25 mi::DeviceCapabilities mi::DefaultDevice::capabilities() const
26 {
27 return info.capabilities;
28@@ -117,6 +134,12 @@
29 if (conf.cursor_acceleration_bias() < -1.0 || conf.cursor_acceleration_bias() > 1.0)
30 BOOST_THROW_EXCEPTION(std::invalid_argument("Cursor acceleration bias out of range"));
31
32+ set_pointer_configuration(conf);
33+ device_changed_callback(this);
34+}
35+
36+void mi::DefaultDevice::set_pointer_configuration(MirPointerConfig const& conf)
37+{
38 PointerSettings settings;
39 settings.handedness = conf.handedness();
40 settings.acceleration = conf.acceleration();
41@@ -133,7 +156,6 @@
42 {
43 dev->apply_settings(settings);
44 });
45- device_changed_callback(this);
46 }
47
48 void mi::DefaultDevice::apply_touchpad_configuration(MirTouchpadConfig const& conf)
49@@ -148,6 +170,12 @@
50 conf.button_down_scroll_button() == mi::no_scroll_button)
51 BOOST_THROW_EXCEPTION(std::invalid_argument("No scroll button configured"));
52
53+ set_touchpad_configuration(conf);
54+ device_changed_callback(this);
55+}
56+
57+void mi::DefaultDevice::set_touchpad_configuration(MirTouchpadConfig const& conf)
58+{
59 TouchpadSettings settings;
60 settings.click_mode= conf.click_mode();
61 settings.scroll_mode = conf.scroll_mode();
62@@ -166,7 +194,6 @@
63 {
64 dev->apply_settings(settings);
65 });
66- device_changed_callback(this);
67 }
68
69 mir::optional_value<MirKeyboardConfig> mi::DefaultDevice::keyboard_configuration() const
70@@ -180,15 +207,18 @@
71 if (!contains(info.capabilities, mi::DeviceCapability::keyboard))
72 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot apply a keyboard configuration"));
73
74- {
75- std::lock_guard<std::mutex> lock(config_mutex);
76- if (keyboard.value().device_keymap() != conf.device_keymap())
77- keyboard = conf;
78- else
79- return;
80- }
81+ set_keyboard_configuration(conf);
82+ device_changed_callback(this);
83+}
84+
85+void mi::DefaultDevice::set_keyboard_configuration(MirKeyboardConfig const& conf)
86+{
87+ std::lock_guard<std::mutex> lock(config_mutex);
88+ if (keyboard.value().device_keymap() != conf.device_keymap())
89+ keyboard = conf;
90+ else
91+ return;
92 key_mapper->set_keymap_for_device(device_id, conf.device_keymap());
93- device_changed_callback(this);
94 }
95
96 mir::optional_value<MirTouchscreenConfig> mi::DefaultDevice::touchscreen_configuration() const
97@@ -206,6 +236,12 @@
98 if (!touchscreen.is_set())
99 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot apply a touchscreen configuration"));
100
101+ set_touchscreen_configuration(config);
102+ device_changed_callback(this);
103+}
104+
105+void mi::DefaultDevice::set_touchscreen_configuration(MirTouchscreenConfig const& config)
106+{
107 TouchscreenSettings settings;
108 settings.output_id = config.output_id();
109 settings.mapping_mode = config.mapping_mode();
110@@ -216,5 +252,27 @@
111 {
112 dev->apply_settings(settings);
113 });
114- device_changed_callback(this);
115+}
116+
117+MirInputDevice mi::DefaultDevice::config() const
118+{
119+ auto stored_dev = MirInputDevice(
120+ id(),
121+ capabilities(),
122+ name(),
123+ unique_id());
124+ auto pointer_conf = pointer_configuration();
125+ if (pointer_conf.is_set())
126+ stored_dev.set_pointer_config(pointer_conf.value());
127+ auto touchpad_conf = touchpad_configuration();
128+ if (touchpad_conf.is_set())
129+ stored_dev.set_touchpad_config(touchpad_conf.value());
130+ auto keyboard_conf = keyboard_configuration();
131+ if (keyboard_conf.is_set())
132+ stored_dev.set_keyboard_config(keyboard_conf.value());
133+ auto touchscreen_conf = touchscreen_configuration();
134+ if (touchscreen_conf.is_set())
135+ stored_dev.set_touchscreen_config(touchscreen_conf.value());
136+
137+ return stored_dev;
138 }
139
140=== modified file 'src/server/input/default_device.h'
141--- src/server/input/default_device.h 2017-03-20 11:27:32 +0000
142+++ src/server/input/default_device.h 2017-03-22 09:43:20 +0000
143@@ -58,6 +58,11 @@
144 InputDevice& device,
145 std::shared_ptr<KeyMapper> const& key_mapper,
146 std::function<void(Device*)> const& change_callback);
147+ DefaultDevice(MirInputDevice const& config,
148+ std::shared_ptr<dispatch::ActionQueue> const& actions,
149+ InputDevice& device,
150+ std::shared_ptr<KeyMapper> const& key_mapper,
151+ std::function<void(Device*)> const& change_callback);
152 MirInputDeviceId id() const override;
153 DeviceCapabilities capabilities() const override;
154 std::string name() const override;
155@@ -71,7 +76,15 @@
156 void apply_keyboard_configuration(MirKeyboardConfig const&) override;
157 optional_value<MirTouchscreenConfig> touchscreen_configuration() const override;
158 void apply_touchscreen_configuration(MirTouchscreenConfig const&) override;
159+
160+ MirInputDevice config() const;
161 private:
162+ void set_pointer_configuration(MirPointerConfig const&);
163+ void set_touchpad_configuration(MirTouchpadConfig const&);
164+ void set_keyboard_configuration(MirKeyboardConfig const&);
165+ void set_touchscreen_configuration(MirTouchscreenConfig const&);
166+
167+ void wake_hub_for_device_change();
168 MirInputDeviceId const device_id;
169 InputDevice& device;
170 InputDeviceInfo const info;
171
172=== modified file 'src/server/input/default_input_device_hub.cpp'
173--- src/server/input/default_input_device_hub.cpp 2017-03-22 09:43:20 +0000
174+++ src/server/input/default_input_device_hub.cpp 2017-03-22 09:43:20 +0000
175@@ -191,11 +191,10 @@
176
177 if (it == end(devices))
178 {
179- auto id = create_new_device_id();
180- auto handle = std::make_shared<DefaultDevice>(id, device_queue, *device, key_mapper, [this](Device *d){device_changed(d);});
181+ auto handle = restore_or_create_device(*device);
182 // send input device info to observer loop..
183 devices.push_back(std::make_unique<RegisteredDevice>(
184- device, id, input_dispatchable, cookie_authority, handle));
185+ device, handle->id(), input_dispatchable, cookie_authority, handle));
186
187 auto const& dev = devices.back();
188 add_device_handle(handle);
189@@ -222,6 +221,7 @@
190 {
191 if (item->device_matches(device))
192 {
193+ store_device_config(*item->handle);
194 auto seat = item->seat;
195 if (seat)
196 {
197@@ -491,3 +491,52 @@
198 });
199 }
200 }
201+
202+void mi::DefaultInputDeviceHub::store_device_config(mi::DefaultDevice const& dev)
203+{
204+ std::lock_guard<std::mutex> lock(stored_configurations_guard);
205+ stored_devices.push_back(dev.config());
206+}
207+
208+mir::optional_value<MirInputDevice>
209+mi::DefaultInputDeviceHub::get_stored_device_config(std::string const& id)
210+{
211+ mir::optional_value<MirInputDevice> optional_config;
212+ std::lock_guard<std::mutex> lock(stored_configurations_guard);
213+ auto pos = remove_if(
214+ begin(stored_devices),
215+ end(stored_devices),
216+ [&optional_config,id](auto const& handle)
217+ {
218+ if (id == handle.unique_id())
219+ {
220+ optional_config = handle;
221+ return true;
222+ }
223+ return false;
224+ });
225+ stored_devices.erase(pos, end(stored_devices));
226+
227+ return optional_config;
228+}
229+
230+std::shared_ptr<mi::DefaultDevice>
231+mi::DefaultInputDeviceHub::restore_or_create_device(mi::InputDevice& device)
232+{
233+ auto device_config = get_stored_device_config(device.get_device_info().unique_id);
234+
235+ if (device_config.is_set())
236+ return std::make_shared<DefaultDevice>(
237+ device_config.value(),
238+ device_queue,
239+ device,
240+ key_mapper,
241+ [this](Device *d){device_changed(d);});
242+ else
243+ return std::make_shared<DefaultDevice>(
244+ create_new_device_id(),
245+ device_queue,
246+ device,
247+ key_mapper,
248+ [this](Device *d){device_changed(d);});
249+}
250
251=== modified file 'src/server/input/default_input_device_hub.h'
252--- src/server/input/default_input_device_hub.h 2017-03-22 09:43:20 +0000
253+++ src/server/input/default_input_device_hub.h 2017-03-22 09:43:20 +0000
254@@ -29,6 +29,7 @@
255 #include "mir/input/input_device_info.h"
256 #include "mir/input/mir_input_config.h"
257 #include "mir/thread_safe_list.h"
258+#include "mir/optional_value.h"
259
260 #include "mir_toolkit/event.h"
261
262@@ -102,6 +103,9 @@
263 void device_changed(Device* dev);
264 void emit_changed_devices();
265 MirInputDeviceId create_new_device_id();
266+ void store_device_config(DefaultDevice const& dev);
267+ std::shared_ptr<DefaultDevice> restore_or_create_device(InputDevice& dev);
268+ mir::optional_value<MirInputDevice> get_stored_device_config(std::string const& id);
269
270 std::shared_ptr<Seat> const seat;
271 std::shared_ptr<dispatch::MultiplexingDispatchable> const input_dispatchable;
272@@ -146,6 +150,9 @@
273 std::mutex changed_devices_guard;
274 std::unique_ptr<std::vector<std::shared_ptr<Device>>> changed_devices;
275
276+ std::mutex stored_configurations_guard;
277+ std::vector<MirInputDevice> stored_devices;
278+
279 MirInputDeviceId device_id_generator;
280 bool ready{false};
281 };
282
283=== modified file 'tests/unit-tests/input/test_default_device.cpp'
284--- tests/unit-tests/input/test_default_device.cpp 2017-02-28 08:53:57 +0000
285+++ tests/unit-tests/input/test_default_device.cpp 2017-03-22 09:43:20 +0000
286@@ -18,6 +18,7 @@
287
288 #include "src/server/input/default_device.h"
289 #include "mir/input/input_device.h"
290+#include "mir/input/mir_input_config.h"
291 #include "mir/input/mir_touchpad_config.h"
292 #include "mir/input/mir_pointer_config.h"
293 #include "mir/input/mir_touchscreen_config.h"
294@@ -57,6 +58,7 @@
295 NiceMock<MockInputDevice> touchscreen;
296 NiceMock<mtd::MockKeyMapper> key_mapper;
297 std::shared_ptr<md::ActionQueue> queue{std::make_shared<md::ActionQueue>()};
298+ std::function<void(mi::Device*)> const change_callback{[](mi::Device*){}};
299
300 DefaultDevice()
301 {
302@@ -181,3 +183,128 @@
303
304 queue->dispatch(md::FdEvent::readable);
305 }
306+
307+TEST_F(DefaultDevice, touchpad_device_can_be_constructed_from_input_config)
308+{
309+ MirTouchpadConfig const tpd_conf{mir_touchpad_click_mode_finger_count, mir_touchpad_scroll_mode_edge_scroll, 0, false, true, true, true};
310+ MirPointerConfig const ptr_conf{mir_pointer_handedness_right, mir_pointer_acceleration_adaptive, 0.5, -1.0, 1.0};
311+ MirInputDevice conf(MirInputDeviceId{17}, mi::DeviceCapability::touchpad|mi::DeviceCapability::pointer, "touchpad", "toouchpad-event7");
312+ conf.set_touchpad_config(tpd_conf);
313+ conf.set_pointer_config(ptr_conf);
314+ mi::DefaultDevice dev(conf, queue, touchpad, mt::fake_shared(key_mapper), change_callback);
315+
316+ EXPECT_EQ(tpd_conf, dev.touchpad_configuration().value());
317+ EXPECT_EQ(ptr_conf, dev.pointer_configuration().value());
318+}
319+
320+TEST_F(DefaultDevice, pointer_device_can_be_constructed_from_input_config)
321+{
322+ MirPointerConfig const ptr_config{mir_pointer_handedness_left, mir_pointer_acceleration_none, 0, 1.0, 1.0};
323+ MirInputDevice conf(MirInputDeviceId{11}, mi::DeviceCapability::pointer, "pointer", "pointer-event7");
324+ conf.set_pointer_config(ptr_config);
325+ mi::DefaultDevice dev(conf, queue, mouse, mt::fake_shared(key_mapper), change_callback);
326+
327+ EXPECT_EQ(ptr_config, dev.pointer_configuration().value());
328+}
329+
330+TEST_F(DefaultDevice, keyboard_device_can_be_constructed_from_input_config)
331+{
332+ MirKeyboardConfig const kbd_config{mi::Keymap{"pc104", "dvorak", "", ""}};
333+ MirInputDevice conf(MirInputDeviceId{3}, mi::DeviceCapability::keyboard, "keyboard", "keyboard-event3c");
334+ conf.set_keyboard_config(kbd_config);
335+ mi::DefaultDevice dev(conf, queue, keyboard, mt::fake_shared(key_mapper), change_callback);
336+
337+ EXPECT_EQ(kbd_config, dev.keyboard_configuration().value());
338+}
339+
340+TEST_F(DefaultDevice, touchscreen_device_can_be_constructed_from_input_config)
341+{
342+ MirTouchscreenConfig const ts_config{0, mir_touchscreen_mapping_mode_to_display_wall};
343+ MirInputDevice conf(MirInputDeviceId{5}, mi::DeviceCapability::touchscreen, "ts", "ts-event7");
344+ conf.set_touchscreen_config(ts_config);
345+
346+ mi::DefaultDevice dev(conf, queue, touchscreen, mt::fake_shared(key_mapper), change_callback);
347+
348+ EXPECT_EQ(ts_config, dev.touchscreen_configuration().value());
349+}
350+
351+TEST_F(DefaultDevice, device_config_can_be_queried_from_touchpad)
352+{
353+ MirInputDeviceId const device_id{17};
354+ mi::DefaultDevice dev(device_id, queue, touchpad, mt::fake_shared(key_mapper), change_callback);
355+
356+ auto dev_info = touchpad.get_device_info();
357+ MirInputDevice conf(device_id, dev_info.capabilities, dev_info.name, dev_info.unique_id);
358+ MirTouchpadConfig const tpd_conf{
359+ mir_touchpad_click_mode_finger_count,
360+ mir_touchpad_scroll_mode_edge_scroll,
361+ 0,
362+ false,
363+ true,
364+ true,
365+ true};
366+ MirPointerConfig const ptr_conf{
367+ mir_pointer_handedness_right,
368+ mir_pointer_acceleration_adaptive,
369+ 0.5,
370+ -1.0,
371+ 1.0};
372+
373+ conf.set_touchpad_config(tpd_conf);
374+ conf.set_pointer_config(ptr_conf);
375+
376+ dev.apply_touchpad_configuration(tpd_conf);
377+ dev.apply_pointer_configuration(ptr_conf);
378+
379+ EXPECT_EQ(conf, dev.config());
380+}
381+
382+TEST_F(DefaultDevice, device_config_can_be_queried_from_pointer_device)
383+{
384+ MirInputDeviceId const device_id{11};
385+ mi::DefaultDevice dev(device_id, queue, mouse, mt::fake_shared(key_mapper), change_callback);
386+
387+ auto dev_info = mouse.get_device_info();
388+ MirInputDevice conf(device_id, dev_info.capabilities, dev_info.name, dev_info.unique_id);
389+ MirPointerConfig const ptr_config{
390+ mir_pointer_handedness_left,
391+ mir_pointer_acceleration_none,
392+ 0,
393+ 1.0,
394+ 1.0};
395+
396+ conf.set_pointer_config(ptr_config);
397+ dev.apply_pointer_configuration(ptr_config);
398+
399+ EXPECT_EQ(conf, dev.config());
400+}
401+
402+TEST_F(DefaultDevice, device_config_can_be_queried_from_keyboard_device)
403+{
404+ MirInputDeviceId const device_id{3};
405+ mi::DefaultDevice dev(device_id, queue, keyboard, mt::fake_shared(key_mapper), change_callback);
406+
407+ auto dev_info = keyboard.get_device_info();
408+ MirInputDevice conf(device_id, dev_info.capabilities, dev_info.name, dev_info.unique_id);
409+ MirKeyboardConfig const kbd_config{mi::Keymap{"pc104", "dvorak", "", ""}};
410+
411+ conf.set_keyboard_config(kbd_config);
412+ dev.apply_keyboard_configuration(kbd_config);
413+
414+ EXPECT_EQ(kbd_config, dev.keyboard_configuration().value());
415+}
416+
417+TEST_F(DefaultDevice, device_config_can_be_queried_from_touchscreen)
418+{
419+ MirInputDeviceId const device_id{5};
420+ mi::DefaultDevice dev(device_id, queue, touchscreen, mt::fake_shared(key_mapper), change_callback);
421+
422+ auto dev_info = touchscreen.get_device_info();
423+ MirInputDevice conf(device_id, dev_info.capabilities, dev_info.name, dev_info.unique_id);
424+ MirTouchscreenConfig const ts_config{0, mir_touchscreen_mapping_mode_to_display_wall};
425+
426+ conf.set_touchscreen_config(ts_config);
427+ dev.apply_touchscreen_configuration(ts_config);
428+
429+ EXPECT_EQ(ts_config, dev.touchscreen_configuration().value());
430+}
431
432=== modified file 'tests/unit-tests/input/test_default_input_device_hub.cpp'
433--- tests/unit-tests/input/test_default_input_device_hub.cpp 2017-03-22 09:43:20 +0000
434+++ tests/unit-tests/input/test_default_input_device_hub.cpp 2017-03-22 09:43:20 +0000
435@@ -294,3 +294,49 @@
436 expect_and_execute_multiplexer();
437 ::testing::Mock::VerifyAndClearExpectations(&mock_observer);
438 }
439+
440+TEST_F(InputDeviceHubTest, restores_device_id_when_device_reappears)
441+{
442+ std::shared_ptr<mi::Device> dev_ptr;
443+
444+ ON_CALL(mock_observer, device_added(WithName("mouse"))).WillByDefault(SaveArg<0>(&dev_ptr));
445+
446+ hub.add_device(mt::fake_shared(mouse));
447+ hub.add_observer(mt::fake_shared(mock_observer));
448+ expect_and_execute_multiplexer();
449+
450+ auto device_id = dev_ptr->id();
451+
452+ hub.remove_device(mt::fake_shared(mouse));
453+ dev_ptr.reset();
454+ hub.add_device(mt::fake_shared(mouse));
455+
456+ ASSERT_THAT(dev_ptr, Ne(nullptr));
457+
458+ EXPECT_THAT(dev_ptr->id(), Eq(device_id));
459+}
460+
461+TEST_F(InputDeviceHubTest, restores_configuration_when_device_reappears)
462+{
463+ std::shared_ptr<mi::Device> dev_ptr;
464+ MirPointerConfig ptr_config;
465+ ptr_config.handedness(mir_pointer_handedness_left);
466+ ptr_config.acceleration(mir_pointer_acceleration_adaptive);
467+ ptr_config.cursor_acceleration_bias(0.6);
468+
469+ ON_CALL(mock_observer, device_added(WithName("mouse"))).WillByDefault(SaveArg<0>(&dev_ptr));
470+
471+ hub.add_device(mt::fake_shared(mouse));
472+ hub.add_observer(mt::fake_shared(mock_observer));
473+ expect_and_execute_multiplexer();
474+
475+ dev_ptr->apply_pointer_configuration(ptr_config);
476+
477+ hub.remove_device(mt::fake_shared(mouse));
478+ dev_ptr.reset();
479+ hub.add_device(mt::fake_shared(mouse));
480+
481+ ASSERT_THAT(dev_ptr, Ne(nullptr));
482+
483+ EXPECT_THAT(dev_ptr->pointer_configuration().value(), Eq(ptr_config));
484+}

Subscribers

People subscribed via source and target branches