Merge lp:~morphis/ubuntu-system-settings/fix-device-actions into lp:ubuntu-system-settings
- fix-device-actions
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Ken VanDine |
Approved revision: | 1513 |
Merged at revision: | 1514 |
Proposed branch: | lp:~morphis/ubuntu-system-settings/fix-device-actions |
Merge into: | lp:ubuntu-system-settings |
Diff against target: |
1033 lines (+317/-318) 19 files modified
plugins/bluetooth/CMakeLists.txt (+2/-1) plugins/bluetooth/ConfirmPasskeyDialog.qml (+1/-1) plugins/bluetooth/DevicePage.qml (+200/-0) plugins/bluetooth/DisplayPasskeyDialog.qml (+1/-1) plugins/bluetooth/PageComponent.qml (+4/-171) plugins/bluetooth/ProvidePasskeyDialog.qml (+1/-1) plugins/bluetooth/ProvidePinCodeDialog.qml (+1/-1) plugins/bluetooth/agent.cpp (+1/-1) plugins/bluetooth/agent.h (+1/-1) plugins/bluetooth/bluetooth.cpp (+7/-1) plugins/bluetooth/bluetooth.h (+2/-1) plugins/bluetooth/dbus-shared.h (+2/-2) plugins/bluetooth/device.cpp (+74/-89) plugins/bluetooth/device.h (+4/-7) plugins/bluetooth/devicemodel.cpp (+13/-27) plugins/bluetooth/devicemodel.h (+1/-1) plugins/bluetooth/plugin.cpp (+1/-1) plugins/bluetooth/plugin.h (+1/-1) tests/plugins/bluetooth/tst_device.cpp (+0/-10) |
To merge this branch: | bzr merge lp:~morphis/ubuntu-system-settings/fix-device-actions |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
PS Jenkins bot | continuous-integration | Needs Fixing | |
Ken VanDine | Approve | ||
Review via email: mp+269188@code.launchpad.net |
Commit message
Reworking bluetooth support in settings a bit to work as it should:
* devices are now correctly connected after they got paired which wasn't the case before due to timing reasons (org.bluez.
* DevicePage is now created on the fly to avoid it displaying information for a moment from a previously selected device
* DevicePage is now split out of the PageComponent.qml file
* Discover service functionality is dropped as bluez does this on its own and we don't need to care
Description of the change
Simon Fels (morphis) wrote : | # |
- 1511. By Simon Fels
-
[bluetooth] correctly handle passed in RSSI values to report a signal strength
in the UI.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1511
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Ken VanDine (ken-vandine) wrote : | # |
A couple questions inline
- 1512. By Simon Fels
-
[bluetooth] Drop superfluous elese case
Ken VanDine (ken-vandine) wrote : | # |
A couple ore inline comments
- 1513. By Simon Fels
-
[bluetooth] Update copyright year and fix review comments
Ken VanDine (ken-vandine) wrote : | # |
Looks great, thanks!
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1512
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Preview Diff
1 | === modified file 'plugins/bluetooth/CMakeLists.txt' |
2 | --- plugins/bluetooth/CMakeLists.txt 2015-02-04 16:32:54 +0000 |
3 | +++ plugins/bluetooth/CMakeLists.txt 2015-08-28 09:33:03 +0000 |
4 | @@ -5,7 +5,8 @@ |
5 | ConfirmPasskeyDialog.qml |
6 | DisplayPasskeyDialog.qml |
7 | ProvidePasskeyDialog.qml |
8 | -PageComponent.qml |
9 | +DevicePage.qml |
10 | +PageComponent.qml |
11 | ) |
12 | |
13 | add_library(UbuntuBluetoothPanel MODULE |
14 | |
15 | === modified file 'plugins/bluetooth/ConfirmPasskeyDialog.qml' |
16 | --- plugins/bluetooth/ConfirmPasskeyDialog.qml 2013-09-30 15:37:50 +0000 |
17 | +++ plugins/bluetooth/ConfirmPasskeyDialog.qml 2015-08-28 09:33:03 +0000 |
18 | @@ -1,7 +1,7 @@ |
19 | /* |
20 | * This file is part of ubuntu-system-settings |
21 | * |
22 | - * Copyright (C) 2013 Canonical Ltd. |
23 | + * Copyright (C) 2013-2015 Canonical Ltd. |
24 | * |
25 | * Contact: Charles Kerr <charles.kerr@canonical.com> |
26 | * |
27 | |
28 | === added file 'plugins/bluetooth/DevicePage.qml' |
29 | --- plugins/bluetooth/DevicePage.qml 1970-01-01 00:00:00 +0000 |
30 | +++ plugins/bluetooth/DevicePage.qml 2015-08-28 09:33:03 +0000 |
31 | @@ -0,0 +1,200 @@ |
32 | +/* |
33 | + * This file is part of ubuntu-system-settings |
34 | + * |
35 | + * Copyright (C) 2013-2015 Canonical Ltd. |
36 | + * |
37 | + * Contact: Charles Kerr <charles.kerr@canonical.com> |
38 | + * |
39 | + * This program is free software: you can redistribute it and/or modify it |
40 | + * under the terms of the GNU General Public License version 3, as published |
41 | + * by the Free Software Foundation. |
42 | + * |
43 | + * This program is distributed in the hope that it will be useful, but |
44 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
45 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
46 | + * PURPOSE. See the GNU General Public License for more details. |
47 | + * |
48 | + * You should have received a copy of the GNU General Public License along |
49 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
50 | + */ |
51 | + |
52 | +import QMenuModel 0.1 |
53 | +import QtQuick 2.0 |
54 | +import SystemSettings 1.0 |
55 | +import Ubuntu.Components 0.1 |
56 | +import Ubuntu.Components.Popups 0.1 |
57 | +import Ubuntu.Components.ListItems 0.1 as ListItem |
58 | +import Ubuntu.SystemSettings.Bluetooth 1.0 |
59 | + |
60 | +Page { |
61 | + id: connectedDevicePage |
62 | + |
63 | + property Item root: null |
64 | + property UbuntuBluetoothPanel backend: null |
65 | + |
66 | + function getStatusString(connection) { |
67 | + switch (connection) { |
68 | + case Device.Connected: return i18n.tr("Connected"); |
69 | + case Device.Connecting: return i18n.tr("Connecting…"); |
70 | + case Device.Disconnecting: return i18n.tr("Disconnecting…"); |
71 | + case Device.Disconnected: return i18n.tr("Disconnected"); |
72 | + default: return i18n.tr("Unknown"); |
73 | + } |
74 | + } |
75 | + |
76 | + function getTypeString(type) { |
77 | + switch (type) { |
78 | + case Device.Computer: return i18n.tr("Computer"); |
79 | + case Device.Phone: return i18n.tr("Phone"); |
80 | + case Device.Modem: return i18n.tr("Modem"); |
81 | + case Device.Network: return i18n.tr("Network"); |
82 | + case Device.Headset: return i18n.tr("Headset"); |
83 | + case Device.Headphones: return i18n.tr("Headphones"); |
84 | + case Device.Video: return i18n.tr("Video"); |
85 | + case Device.OtherAudio: return i18n.tr("Other Audio"); |
86 | + case Device.Joypad: return i18n.tr("Joypad"); |
87 | + case Device.Keyboard: return i18n.tr("Keyboard"); |
88 | + case Device.Tablet: return i18n.tr("Tablet"); |
89 | + case Device.Mouse: return i18n.tr("Mouse"); |
90 | + case Device.Printer: return i18n.tr("Printer"); |
91 | + case Device.Camera: return i18n.tr("Camera"); |
92 | + default: return i18n.tr("Other"); |
93 | + } |
94 | + } |
95 | + |
96 | + function getSignalString(strength) { |
97 | + switch (strength) { |
98 | + case Device.Excellent: return i18n.tr("Excellent"); |
99 | + case Device.Good: return i18n.tr("Good"); |
100 | + case Device.Fair: return i18n.tr("Fair"); |
101 | + case Device.Poor: return i18n.tr("Poor"); |
102 | + default: return i18n.tr("None"); |
103 | + } |
104 | + } |
105 | + |
106 | + title: backend.selectedDevice ? |
107 | + backend.selectedDevice.name.length > 0 ? |
108 | + backend.selectedDevice.name : |
109 | + backend.selectedDevice.address |
110 | + : i18n.tr("None") |
111 | + visible: false |
112 | + |
113 | + Flickable { |
114 | + anchors.fill: parent |
115 | + contentHeight: contentItem.childrenRect.height |
116 | + boundsBehavior: (contentHeight > root.height) ? |
117 | + Flickable.DragAndOvershootBounds : |
118 | + Flickable.StopAtBounds |
119 | + /* Set the direction to workaround https://bugreports.qt-project.org/browse/QTBUG-31905 |
120 | + otherwise the UI might end up in a situation where scrolling doesn't work */ |
121 | + flickableDirection: Flickable.VerticalFlick |
122 | + |
123 | + Column { |
124 | + anchors { |
125 | + left: parent.left |
126 | + right: parent.right |
127 | + } |
128 | + |
129 | + ListItem.SingleValue { |
130 | + text: i18n.tr("Name") |
131 | + value: backend.selectedDevice && |
132 | + backend.selectedDevice.name.length > 0 ? |
133 | + backend.selectedDevice.name : |
134 | + i18n.tr("None") |
135 | + } |
136 | + ListItem.Standard { |
137 | + Rectangle { |
138 | + color: "transparent" |
139 | + anchors.fill: parent |
140 | + anchors.topMargin: units.gu(1) |
141 | + anchors.leftMargin: units.gu(2) |
142 | + anchors.rightMargin: units.gu(2) |
143 | + |
144 | + Label { |
145 | + anchors { |
146 | + top: parent.top |
147 | + left: parent.left |
148 | + topMargin: units.gu(1) |
149 | + } |
150 | + height: units.gu(3) |
151 | + text: i18n.tr("Type") |
152 | + } |
153 | + Image { |
154 | + anchors { |
155 | + right: deviceType.left |
156 | + rightMargin: units.gu(1) |
157 | + } |
158 | + height: units.gu(4) |
159 | + width: units.gu(4) |
160 | + source: backend.selectedDevice ? backend.selectedDevice.iconName : "" |
161 | + } |
162 | + Label { |
163 | + id: deviceType |
164 | + anchors { |
165 | + top: parent.top |
166 | + right: parent.right |
167 | + topMargin: units.gu(1) |
168 | + } |
169 | + height: units.gu(3) |
170 | + text: getTypeString(backend.selectedDevice ? backend.selectedDevice.type : Device.OTHER) |
171 | + } |
172 | + } |
173 | + } |
174 | + ListItem.SingleValue { |
175 | + text: i18n.tr("Status") |
176 | + value: getStatusString(backend.selectedDevice ? backend.selectedDevice.connection : Device.Disconnected) |
177 | + } |
178 | + ListItem.SingleValue { |
179 | + text: i18n.tr("Signal Strength") |
180 | + value: getSignalString(backend.selectedDevice ? backend.selectedDevice.strength : Device.None) |
181 | + } |
182 | + ListItem.Standard { |
183 | + id: trustedCheck |
184 | + text: i18n.tr("Connect automatically when detected:") |
185 | + control: CheckBox { |
186 | + property bool serverChecked: backend.selectedDevice ? backend.selectedDevice.trusted : false |
187 | + onServerCheckedChanged: checked = serverChecked |
188 | + Component.onCompleted: checked = serverChecked |
189 | + onTriggered: { |
190 | + if (backend.selectedDevice) { |
191 | + backend.selectedDevice.trusted = checked; |
192 | + } |
193 | + } |
194 | + } |
195 | + } |
196 | + ListItem.SingleControl { |
197 | + control: Button { |
198 | + text: backend.selectedDevice && (backend.selectedDevice.connection == Device.Connected || backend.selectedDevice.connection == Device.Connecting) ? i18n.tr("Disconnect") : i18n.tr("Connect") |
199 | + width: parent.width - units.gu(8) |
200 | + onClicked: { |
201 | + if (backend.selectedDevice |
202 | + && (backend.selectedDevice.connection == Device.Connected |
203 | + || backend.selectedDevice.connection == Device.Connecting)) { |
204 | + backend.disconnectDevice(); |
205 | + } else { |
206 | + backend.stopDiscovery() |
207 | + backend.connectDevice(backend.selectedDevice.address); |
208 | + } |
209 | + |
210 | + backend.resetSelectedDevice(); |
211 | + pageStack.pop(); |
212 | + } |
213 | + visible: backend.selectedDevice ? true : false |
214 | + enabled: backend.selectedDevice ? backend.isSupportedType(backend.selectedDevice.type) : false |
215 | + } |
216 | + } |
217 | + ListItem.SingleControl { |
218 | + control: Button { |
219 | + text: i18n.tr("Forget this device") |
220 | + width: parent.width - units.gu(8) |
221 | + onClicked: { |
222 | + backend.removeDevice(); |
223 | + backend.resetSelectedDevice(); |
224 | + pageStack.pop(); |
225 | + } |
226 | + enabled: backend.selectedDevice && backend.selectedDevice.path.length > 0 ? true : false |
227 | + } |
228 | + } |
229 | + } |
230 | + } |
231 | +} |
232 | |
233 | === modified file 'plugins/bluetooth/DisplayPasskeyDialog.qml' |
234 | --- plugins/bluetooth/DisplayPasskeyDialog.qml 2015-02-13 10:30:37 +0000 |
235 | +++ plugins/bluetooth/DisplayPasskeyDialog.qml 2015-08-28 09:33:03 +0000 |
236 | @@ -1,7 +1,7 @@ |
237 | /* |
238 | * This file is part of ubuntu-system-settings |
239 | * |
240 | - * Copyright (C) 2013 Canonical Ltd. |
241 | + * Copyright (C) 2013-2015 Canonical Ltd. |
242 | * |
243 | * This program is free software: you can redistribute it and/or modify it |
244 | * under the terms of the GNU General Public License version 3, as published |
245 | |
246 | === modified file 'plugins/bluetooth/PageComponent.qml' |
247 | --- plugins/bluetooth/PageComponent.qml 2015-08-06 16:35:22 +0000 |
248 | +++ plugins/bluetooth/PageComponent.qml 2015-08-28 09:33:03 +0000 |
249 | @@ -1,7 +1,7 @@ |
250 | /* |
251 | * This file is part of ubuntu-system-settings |
252 | * |
253 | - * Copyright (C) 2013 Canonical Ltd. |
254 | + * Copyright (C) 2013-2015 Canonical Ltd. |
255 | * |
256 | * Contact: Charles Kerr <charles.kerr@canonical.com> |
257 | * |
258 | @@ -122,47 +122,6 @@ |
259 | return displayName; |
260 | } |
261 | |
262 | - function getStatusString(connection) { |
263 | - switch (connection) { |
264 | - case Device.Connected: return i18n.tr("Connected"); |
265 | - case Device.Connecting: return i18n.tr("Connecting…"); |
266 | - case Device.Disconnecting: return i18n.tr("Disconnecting…"); |
267 | - case Device.Disconnected: return i18n.tr("Disconnected"); |
268 | - default: return i18n.tr("Unknown"); |
269 | - } |
270 | - } |
271 | - |
272 | - function getTypeString(type) { |
273 | - switch (type) { |
274 | - case Device.Computer: return i18n.tr("Computer"); |
275 | - case Device.Phone: return i18n.tr("Phone"); |
276 | - case Device.Modem: return i18n.tr("Modem"); |
277 | - case Device.Network: return i18n.tr("Network"); |
278 | - case Device.Headset: return i18n.tr("Headset"); |
279 | - case Device.Headphones: return i18n.tr("Headphones"); |
280 | - case Device.Video: return i18n.tr("Video"); |
281 | - case Device.OtherAudio: return i18n.tr("Other Audio"); |
282 | - case Device.Joypad: return i18n.tr("Joypad"); |
283 | - case Device.Keyboard: return i18n.tr("Keyboard"); |
284 | - case Device.Tablet: return i18n.tr("Tablet"); |
285 | - case Device.Mouse: return i18n.tr("Mouse"); |
286 | - case Device.Printer: return i18n.tr("Printer"); |
287 | - case Device.Camera: return i18n.tr("Camera"); |
288 | - default: return i18n.tr("Other"); |
289 | - } |
290 | - } |
291 | - |
292 | - function getSignalString(strength) { |
293 | - switch (strength) { |
294 | - case Device.Excellent: return i18n.tr("Excellent"); |
295 | - case Device.Good: return i18n.tr("Good"); |
296 | - case Device.Fair: return i18n.tr("Fair"); |
297 | - case Device.Poor: return i18n.tr("Poor"); |
298 | - default: return i18n.tr("None"); |
299 | - } |
300 | - } |
301 | - |
302 | - |
303 | Flickable { |
304 | anchors.fill: parent |
305 | contentHeight: contentItem.childrenRect.height |
306 | @@ -282,7 +241,7 @@ |
307 | } |
308 | onClicked: { |
309 | backend.setSelectedDevice(addressName); |
310 | - pageStack.push(connectedDevicePage); |
311 | + pageStack.push(Qt.resolvedUrl("DevicePage.qml"), {backend: backend, root: root}); |
312 | } |
313 | progression: true |
314 | } |
315 | @@ -319,7 +278,7 @@ |
316 | text: getDisplayName(type, displayName) |
317 | onClicked: { |
318 | backend.setSelectedDevice(addressName); |
319 | - pageStack.push(connectedDevicePage); |
320 | + pageStack.push(Qt.resolvedUrl("DevicePage.qml"), {backend: backend, root: root}); |
321 | } |
322 | progression: true |
323 | } |
324 | @@ -357,7 +316,7 @@ |
325 | text: getDisplayName(type, displayName) |
326 | onClicked: { |
327 | backend.setSelectedDevice(addressName); |
328 | - pageStack.push(connectedDevicePage); |
329 | + pageStack.push(Qt.resolvedUrl("DevicePage.qml"), {backend: backend, root: root}); |
330 | } |
331 | progression: true |
332 | } |
333 | @@ -365,130 +324,4 @@ |
334 | } |
335 | } |
336 | } |
337 | - |
338 | - Page { |
339 | - id: connectedDevicePage |
340 | - title: backend.selectedDevice ? |
341 | - backend.selectedDevice.name.length > 0 ? |
342 | - backend.selectedDevice.name : |
343 | - backend.selectedDevice.address |
344 | - : i18n.tr("None") |
345 | - visible: false |
346 | - |
347 | - Flickable { |
348 | - anchors.fill: parent |
349 | - contentHeight: contentItem.childrenRect.height |
350 | - boundsBehavior: (contentHeight > root.height) ? |
351 | - Flickable.DragAndOvershootBounds : |
352 | - Flickable.StopAtBounds |
353 | - /* Set the direction to workaround https://bugreports.qt-project.org/browse/QTBUG-31905 |
354 | - otherwise the UI might end up in a situation where scrolling doesn't work */ |
355 | - flickableDirection: Flickable.VerticalFlick |
356 | - |
357 | - Column { |
358 | - anchors { |
359 | - left: parent.left |
360 | - right: parent.right |
361 | - } |
362 | - |
363 | - ListItem.SingleValue { |
364 | - text: i18n.tr("Name") |
365 | - value: backend.selectedDevice && |
366 | - backend.selectedDevice.name.length > 0 ? |
367 | - backend.selectedDevice.name : |
368 | - i18n.tr("None") |
369 | - } |
370 | - ListItem.Standard { |
371 | - Rectangle { |
372 | - color: "transparent" |
373 | - anchors.fill: parent |
374 | - anchors.topMargin: units.gu(1) |
375 | - anchors.leftMargin: units.gu(2) |
376 | - anchors.rightMargin: units.gu(2) |
377 | - |
378 | - Label { |
379 | - anchors { |
380 | - top: parent.top |
381 | - left: parent.left |
382 | - topMargin: units.gu(1) |
383 | - } |
384 | - height: units.gu(3) |
385 | - text: i18n.tr("Type") |
386 | - } |
387 | - Image { |
388 | - anchors { |
389 | - right: deviceType.left |
390 | - rightMargin: units.gu(1) |
391 | - } |
392 | - height: units.gu(4) |
393 | - width: units.gu(4) |
394 | - source: backend.selectedDevice ? backend.selectedDevice.iconName : "" |
395 | - } |
396 | - Label { |
397 | - id: deviceType |
398 | - anchors { |
399 | - top: parent.top |
400 | - right: parent.right |
401 | - topMargin: units.gu(1) |
402 | - } |
403 | - height: units.gu(3) |
404 | - text: getTypeString(backend.selectedDevice ? backend.selectedDevice.type : Device.OTHER) |
405 | - } |
406 | - } |
407 | - } |
408 | - ListItem.SingleValue { |
409 | - text: i18n.tr("Status") |
410 | - value: getStatusString(backend.selectedDevice ? backend.selectedDevice.connection : Device.Disconnected) |
411 | - } |
412 | - ListItem.SingleValue { |
413 | - text: i18n.tr("Signal Strength") |
414 | - value: getSignalString(backend.selectedDevice ? backend.selectedDevice.strength : Device.None) |
415 | - } |
416 | - ListItem.Standard { |
417 | - id: trustedCheck |
418 | - text: i18n.tr("Connect automatically when detected:") |
419 | - control: CheckBox { |
420 | - property bool serverChecked: backend.selectedDevice ? backend.selectedDevice.trusted : false |
421 | - onServerCheckedChanged: checked = serverChecked |
422 | - Component.onCompleted: checked = serverChecked |
423 | - onTriggered: { |
424 | - if (backend.selectedDevice) { |
425 | - backend.selectedDevice.trusted = checked; |
426 | - } |
427 | - } |
428 | - } |
429 | - } |
430 | - ListItem.SingleControl { |
431 | - control: Button { |
432 | - text: backend.selectedDevice && (backend.selectedDevice.connection == Device.Connected || backend.selectedDevice.connection == Device.Connecting) ? i18n.tr("Disconnect") : i18n.tr("Connect") |
433 | - width: parent.width - units.gu(8) |
434 | - onClicked: { |
435 | - if (backend.selectedDevice |
436 | - && (backend.selectedDevice.connection == Device.Connected |
437 | - || backend.selectedDevice.connection == Device.Connecting)) { |
438 | - backend.disconnectDevice(); |
439 | - } else { |
440 | - backend.stopDiscovery() |
441 | - backend.connectDevice(backend.selectedDevice.address); |
442 | - } |
443 | - pageStack.pop(); |
444 | - } |
445 | - visible: backend.selectedDevice ? true : false |
446 | - enabled: backend.isSupportedType(backend.selectedDevice.type) |
447 | - } |
448 | - } |
449 | - ListItem.SingleControl { |
450 | - control: Button { |
451 | - text: i18n.tr("Forget this device") |
452 | - width: parent.width - units.gu(8) |
453 | - onClicked: { |
454 | - backend.removeDevice(); |
455 | - pageStack.pop(); |
456 | - } |
457 | - enabled: backend.selectedDevice && backend.selectedDevice.path.length > 0 ? true : false |
458 | - } |
459 | - } |
460 | - } |
461 | - } |
462 | - } |
463 | } |
464 | |
465 | === modified file 'plugins/bluetooth/ProvidePasskeyDialog.qml' |
466 | --- plugins/bluetooth/ProvidePasskeyDialog.qml 2015-03-11 14:52:19 +0000 |
467 | +++ plugins/bluetooth/ProvidePasskeyDialog.qml 2015-08-28 09:33:03 +0000 |
468 | @@ -1,7 +1,7 @@ |
469 | /* |
470 | * This file is part of ubuntu-system-settings |
471 | * |
472 | - * Copyright (C) 2013 Canonical Ltd. |
473 | + * Copyright (C) 2013-2015 Canonical Ltd. |
474 | * |
475 | * Contact: Charles Kerr <charles.kerr@canonical.com> |
476 | * |
477 | |
478 | === modified file 'plugins/bluetooth/ProvidePinCodeDialog.qml' |
479 | --- plugins/bluetooth/ProvidePinCodeDialog.qml 2015-03-11 14:52:19 +0000 |
480 | +++ plugins/bluetooth/ProvidePinCodeDialog.qml 2015-08-28 09:33:03 +0000 |
481 | @@ -1,7 +1,7 @@ |
482 | /* |
483 | * This file is part of ubuntu-system-settings |
484 | * |
485 | - * Copyright (C) 2013 Canonical Ltd. |
486 | + * Copyright (C) 2013-2015 Canonical Ltd. |
487 | * |
488 | * Contact: Charles Kerr <charles.kerr@canonical.com> |
489 | * |
490 | |
491 | === modified file 'plugins/bluetooth/agent.cpp' |
492 | --- plugins/bluetooth/agent.cpp 2015-03-16 13:51:36 +0000 |
493 | +++ plugins/bluetooth/agent.cpp 2015-08-28 09:33:03 +0000 |
494 | @@ -1,5 +1,5 @@ |
495 | /* |
496 | - * Copyright (C) 2013 Canonical Ltd |
497 | + * Copyright (C) 2013-2015 Canonical Ltd |
498 | * |
499 | * This program is free software: you can redistribute it and/or modify |
500 | * it under the terms of the GNU General Public License version 3 as |
501 | |
502 | === modified file 'plugins/bluetooth/agent.h' |
503 | --- plugins/bluetooth/agent.h 2015-02-04 16:32:54 +0000 |
504 | +++ plugins/bluetooth/agent.h 2015-08-28 09:33:03 +0000 |
505 | @@ -1,5 +1,5 @@ |
506 | /* |
507 | - * Copyright (C) 2013 Canonical Ltd |
508 | + * Copyright (C) 2013-2015 Canonical Ltd |
509 | * |
510 | * This program is free software: you can redistribute it and/or modify |
511 | * it under the terms of the GNU General Public License version 3 as |
512 | |
513 | === modified file 'plugins/bluetooth/bluetooth.cpp' |
514 | --- plugins/bluetooth/bluetooth.cpp 2015-03-05 20:52:56 +0000 |
515 | +++ plugins/bluetooth/bluetooth.cpp 2015-08-28 09:33:03 +0000 |
516 | @@ -1,5 +1,5 @@ |
517 | /* |
518 | - * Copyright (C) 2013 Canonical Ltd |
519 | + * Copyright (C) 2013-2015 Canonical Ltd |
520 | * |
521 | * This program is free software: you can redistribute it and/or modify |
522 | * it under the terms of the GNU General Public License version 3 as |
523 | @@ -73,6 +73,12 @@ |
524 | } |
525 | } |
526 | |
527 | +void Bluetooth::resetSelectedDevice() |
528 | +{ |
529 | + m_selectedDevice.reset(0); |
530 | + Q_EMIT(selectedDeviceChanged()); |
531 | +} |
532 | + |
533 | void Bluetooth::toggleDiscovery() |
534 | { |
535 | m_devices.toggleDiscovery(); |
536 | |
537 | === modified file 'plugins/bluetooth/bluetooth.h' |
538 | --- plugins/bluetooth/bluetooth.h 2015-02-25 10:29:38 +0000 |
539 | +++ plugins/bluetooth/bluetooth.h 2015-08-28 09:33:03 +0000 |
540 | @@ -1,5 +1,5 @@ |
541 | /* |
542 | - * Copyright (C) 2013 Canonical Ltd |
543 | + * Copyright (C) 2013-2015 Canonical Ltd |
544 | * |
545 | * This program is free software: you can redistribute it and/or modify |
546 | * it under the terms of the GNU General Public License version 3 as |
547 | @@ -84,6 +84,7 @@ |
548 | Q_INVOKABLE void stopDiscovery(); |
549 | Q_INVOKABLE static bool isSupportedType(const int type); |
550 | Q_INVOKABLE void trySetDiscoverable(bool discoverable); |
551 | + Q_INVOKABLE void resetSelectedDevice(); |
552 | |
553 | public: |
554 | Agent * getAgent(); |
555 | |
556 | === modified file 'plugins/bluetooth/dbus-shared.h' |
557 | --- plugins/bluetooth/dbus-shared.h 2015-01-13 16:29:33 +0000 |
558 | +++ plugins/bluetooth/dbus-shared.h 2015-08-28 09:33:03 +0000 |
559 | @@ -1,5 +1,5 @@ |
560 | /* |
561 | - * Copyright (C) 2013 Canonical Ltd |
562 | + * Copyright (C) 2013-2015 Canonical Ltd |
563 | * |
564 | * This program is free software: you can redistribute it and/or modify |
565 | * it under the terms of the GNU General Public License version 3 as |
566 | @@ -22,6 +22,6 @@ |
567 | |
568 | #define DBUS_AGENT_PATH "/com/canonical/SettingsBluetoothAgent" |
569 | #define DBUS_ADAPTER_AGENT_PATH "/com/canonical/SettingsBluetoothAgent/adapteragent" |
570 | -#define DBUS_AGENT_CAPABILITY "DisplayYesNo" |
571 | +#define DBUS_AGENT_CAPABILITY "KeyboardDisplay" |
572 | |
573 | #endif // USS_DBUS_SHARED_H |
574 | |
575 | === modified file 'plugins/bluetooth/device.cpp' |
576 | --- plugins/bluetooth/device.cpp 2015-07-29 09:18:40 +0000 |
577 | +++ plugins/bluetooth/device.cpp 2015-08-28 09:33:03 +0000 |
578 | @@ -1,5 +1,5 @@ |
579 | /* |
580 | - * Copyright (C) 2013 Canonical Ltd |
581 | + * Copyright (C) 2013-2015 Canonical Ltd |
582 | * |
583 | * This program is free software: you can redistribute it and/or modify |
584 | * it under the terms of the GNU General Public License version 3 as |
585 | @@ -86,6 +86,7 @@ |
586 | if (!i->isValid()) { |
587 | delete i; |
588 | i = 0; |
589 | + qWarning() << "Couldn't add proxy for" << interfaceName; |
590 | } else { |
591 | if (!bus.connect(service, path, interfaceName, "PropertyChanged", |
592 | this, SLOT(slotPropertyChanged(const QString&, const QDBusVariant&)))) |
593 | @@ -113,120 +114,90 @@ |
594 | void Device::connectPending() |
595 | { |
596 | if (m_paired && !m_trusted) { |
597 | - /* Give the device a bit of time to settle. |
598 | - * Once service discovery is done, it will call connect() on the |
599 | - * pending interfaces. |
600 | - */ |
601 | - QTimer::singleShot(1, this, SLOT(discoverServices())); |
602 | - } |
603 | -} |
604 | - |
605 | -/*** |
606 | -**** |
607 | -***/ |
608 | - |
609 | -void Device::addConnectAfterPairing(ConnectionMode mode) |
610 | -{ |
611 | - m_connectAfterPairing.append(mode); |
612 | -} |
613 | - |
614 | -void Device::slotServiceDiscoveryDone(QDBusPendingCallWatcher *call) |
615 | -{ |
616 | - QDBusPendingReply<void> reply = *call; |
617 | - |
618 | - if (!reply.isError()) { |
619 | while (!m_connectAfterPairing.isEmpty()) { |
620 | ConnectionMode mode = m_connectAfterPairing.takeFirst(); |
621 | connect(mode); |
622 | } |
623 | - } else { |
624 | - qWarning() << "Could not initiate service discovery:" |
625 | - << reply.error().message(); |
626 | - } |
627 | - call->deleteLater(); |
628 | -} |
629 | - |
630 | -void Device::discoverServices() |
631 | -{ |
632 | - if (m_deviceInterface) { |
633 | - QDBusPendingCall pcall |
634 | - = m_deviceInterface->asyncCall("DiscoverServices", |
635 | - QLatin1String("")); |
636 | - |
637 | - QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pcall, |
638 | - this); |
639 | - QObject::connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), |
640 | - this, |
641 | - SLOT(slotServiceDiscoveryDone(QDBusPendingCallWatcher*))); |
642 | - } else { |
643 | - qWarning() << "Can't do service discovery: the device interface is not ready."; |
644 | - } |
645 | -} |
646 | - |
647 | -void Device::slotDisconnectDone(QDBusPendingCallWatcher *watcher) |
648 | -{ |
649 | - QDBusPendingReply<void> reply = *watcher; |
650 | - |
651 | - if (reply.isError()) { |
652 | - qWarning() << "Could not disconnect device:" |
653 | - << reply.error().message(); |
654 | - } |
655 | - |
656 | - watcher->deleteLater(); |
657 | + } |
658 | +} |
659 | + |
660 | +/*** |
661 | +**** |
662 | +***/ |
663 | + |
664 | +void Device::addConnectAfterPairing(ConnectionMode mode) |
665 | +{ |
666 | + m_connectAfterPairing.append(mode); |
667 | } |
668 | |
669 | void Device::disconnect(ConnectionMode mode) |
670 | { |
671 | QSharedPointer<QDBusInterface> interface; |
672 | |
673 | - if (m_headsetInterface && (mode == HeadsetMode)) |
674 | + switch (mode) { |
675 | + case HeadsetMode: |
676 | interface = m_headsetInterface; |
677 | - else if (m_audioInterface && (mode == Audio)) |
678 | + break; |
679 | + case Audio: |
680 | interface = m_audioInterface; |
681 | - else if (m_inputInterface && (mode == Input)) |
682 | + break; |
683 | + case Input: |
684 | interface = m_inputInterface; |
685 | - else { |
686 | + break; |
687 | + default: |
688 | qWarning() << "Unhandled connection mode" << mode; |
689 | return; |
690 | } |
691 | |
692 | QDBusPendingCall call = interface->asyncCall("Disconnect"); |
693 | + |
694 | QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(call, this); |
695 | - QObject::connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), |
696 | - this, SLOT(slotDisconnectDone(QDBusPendingCallWatcher*))); |
697 | -} |
698 | - |
699 | -void Device::slotConnectDone(QDBusPendingCallWatcher *watcher) |
700 | -{ |
701 | - QDBusPendingReply<void> reply = *watcher; |
702 | - |
703 | - if (reply.isError()) { |
704 | - qWarning() << "Could not connect device:" |
705 | - << reply.error().message(); |
706 | - } |
707 | - |
708 | - watcher->deleteLater(); |
709 | + QObject::connect(watcher, &QDBusPendingCallWatcher::finished, [this](QDBusPendingCallWatcher *watcher) { |
710 | + QDBusPendingReply<void> reply = *watcher; |
711 | + |
712 | + if (reply.isError()) { |
713 | + qWarning() << "Could not connect device:" |
714 | + << reply.error().message(); |
715 | + } |
716 | + |
717 | + watcher->deleteLater(); |
718 | + }); |
719 | } |
720 | |
721 | void Device::connect(ConnectionMode mode) |
722 | { |
723 | QSharedPointer<QDBusInterface> interface; |
724 | |
725 | - if (m_headsetInterface && (mode == HeadsetMode)) |
726 | + switch (mode) { |
727 | + case HeadsetMode: |
728 | interface = m_headsetInterface; |
729 | - else if (m_audioInterface && (mode == Audio)) |
730 | + break; |
731 | + case Audio: |
732 | interface = m_audioInterface; |
733 | - else if (m_inputInterface && (mode == Input)) |
734 | + break; |
735 | + case Input: |
736 | interface = m_inputInterface; |
737 | - else { |
738 | + break; |
739 | + default: |
740 | qWarning() << "Unhandled connection mode" << mode; |
741 | return; |
742 | } |
743 | |
744 | QDBusPendingCall call = interface->asyncCall("Connect"); |
745 | + |
746 | QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(call, this); |
747 | - QObject::connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), |
748 | - this, SLOT(slotConnectDone(QDBusPendingCallWatcher*))); |
749 | + QObject::connect(watcher, &QDBusPendingCallWatcher::finished, [this](QDBusPendingCallWatcher *watcher) { |
750 | + QDBusPendingReply<void> reply = *watcher; |
751 | + |
752 | + if (reply.isError()) { |
753 | + qWarning() << "Could not connect device:" |
754 | + << reply.error().message(); |
755 | + } else { |
756 | + makeTrusted(true); |
757 | + } |
758 | + |
759 | + watcher->deleteLater(); |
760 | + }); |
761 | } |
762 | |
763 | void Device::slotMakeTrustedDone(QDBusPendingCallWatcher *call) |
764 | @@ -253,10 +224,8 @@ |
765 | |
766 | QDBusPendingCallWatcher *watcher |
767 | = new QDBusPendingCallWatcher(pcall, this); |
768 | - QObject::connect(watcher, |
769 | - SIGNAL(finished(QDBusPendingCallWatcher*)), |
770 | - this, |
771 | - SLOT(slotServiceDiscoveryDone(QDBusPendingCallWatcher*))); |
772 | + QObject::connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), |
773 | + this, SLOT(slotMakeTrustedDone(QDBusPendingCallWatcher*))); |
774 | } else { |
775 | qWarning() << "Can't set device trusted before it is added in BlueZ"; |
776 | } |
777 | @@ -386,9 +355,6 @@ |
778 | else |
779 | c = m_isConnected ? Connection::Connected : Connection::Disconnected; |
780 | |
781 | - if (m_isConnected && m_paired && !m_trusted) |
782 | - makeTrusted(true); |
783 | - |
784 | setConnection(c); |
785 | } |
786 | |
787 | @@ -408,13 +374,15 @@ |
788 | setType(getTypeFromClass(value.toUInt())); |
789 | } else if (key == "Paired") { // org.bluez.Device |
790 | setPaired(value.toBool()); |
791 | - connectPending(); |
792 | updateConnection(); |
793 | } else if (key == "Trusted") { // org.bluez.Device |
794 | setTrusted(value.toBool()); |
795 | } else if (key == "Icon") { // org.bluez.Device |
796 | m_fallbackIconName = value.toString(); |
797 | updateIcon (); |
798 | + } else if (key == "RSSI") { |
799 | + m_strength = getStrengthFromRssi(value.toInt()); |
800 | + Q_EMIT(strengthChanged()); |
801 | } |
802 | } |
803 | |
804 | @@ -505,3 +473,20 @@ |
805 | return Type::Other; |
806 | } |
807 | |
808 | +Device::Strength Device::getStrengthFromRssi(int rssi) |
809 | +{ |
810 | + /* Modelled similar to what Mac OS X does. |
811 | + * See http://www.cnet.com/how-to/how-to-check-bluetooth-connection-strength-in-os-x/ */ |
812 | + |
813 | + if (rssi >= -60) |
814 | + return Excellent; |
815 | + else if (rssi < -60 && rssi >= -70) |
816 | + return Good; |
817 | + else if (rssi < -70 && rssi >= -90) |
818 | + return Fair; |
819 | + else if (rssi < -90) |
820 | + return Poor; |
821 | + |
822 | + return None; |
823 | +} |
824 | + |
825 | |
826 | === modified file 'plugins/bluetooth/device.h' |
827 | --- plugins/bluetooth/device.h 2015-07-29 09:18:40 +0000 |
828 | +++ plugins/bluetooth/device.h 2015-08-28 09:33:03 +0000 |
829 | @@ -1,5 +1,5 @@ |
830 | /* |
831 | - * Copyright (C) 2013 Canonical Ltd |
832 | + * Copyright (C) 2013-2015 Canonical Ltd |
833 | * |
834 | * This program is free software: you can redistribute it and/or modify |
835 | * it under the terms of the GNU General Public License version 3 as |
836 | @@ -118,7 +118,7 @@ |
837 | bool m_paired = false; |
838 | bool m_trusted = false; |
839 | Connection m_connection = Connection::Disconnected; |
840 | - Strength m_strength = Strength::Fair; |
841 | + Strength m_strength = Strength::None; |
842 | bool m_isConnected = false; |
843 | QSharedPointer<QDBusInterface> m_deviceInterface; |
844 | QSharedPointer<QDBusInterface> m_audioInterface; |
845 | @@ -148,27 +148,24 @@ |
846 | void initDevice(const QString &path, QDBusConnection &bus); |
847 | bool isValid() const { return getType() != Type::Other; } |
848 | void connect(ConnectionMode); |
849 | - void connectPending(); |
850 | void makeTrusted(bool trusted); |
851 | void disconnect(ConnectionMode); |
852 | void setProperties(const QMap<QString,QVariant> &properties); |
853 | void addConnectAfterPairing(const ConnectionMode mode); |
854 | |
855 | public Q_SLOTS: |
856 | - void discoverServices(); |
857 | + void connectPending(); |
858 | |
859 | private Q_SLOTS: |
860 | void slotPropertyChanged(const QString &key, const QDBusVariant &value); |
861 | - void slotServiceDiscoveryDone(QDBusPendingCallWatcher *call); |
862 | void slotMakeTrustedDone(QDBusPendingCallWatcher *call); |
863 | - void slotConnectDone(QDBusPendingCallWatcher *watcher); |
864 | - void slotDisconnectDone(QDBusPendingCallWatcher *watcher); |
865 | |
866 | private: |
867 | void updateProperties(QSharedPointer<QDBusInterface>); |
868 | void initInterface(QSharedPointer<QDBusInterface>&, const QString &path, const QString &name, QDBusConnection&); |
869 | void updateProperty(const QString &key, const QVariant &value); |
870 | static Type getTypeFromClass(quint32 bluetoothClass); |
871 | + Device::Strength getStrengthFromRssi(int rssi); |
872 | }; |
873 | |
874 | Q_DECLARE_METATYPE(Device*) |
875 | |
876 | === modified file 'plugins/bluetooth/devicemodel.cpp' |
877 | --- plugins/bluetooth/devicemodel.cpp 2015-04-13 15:08:49 +0000 |
878 | +++ plugins/bluetooth/devicemodel.cpp 2015-08-28 09:33:03 +0000 |
879 | @@ -1,5 +1,5 @@ |
880 | /* |
881 | - * Copyright (C) 2013 Canonical Ltd |
882 | + * Copyright (C) 2013-2015 Canonical Ltd |
883 | * |
884 | * This program is free software: you can redistribute it and/or modify |
885 | * it under the terms of the GNU General Public License version 3 as |
886 | @@ -32,10 +32,6 @@ |
887 | const int SCANNING_IDLE_DURATION_MSEC = (10 * 1000); |
888 | } |
889 | |
890 | -/*** |
891 | -**** |
892 | -***/ |
893 | - |
894 | DeviceModel::DeviceModel(QDBusConnection &dbus, QObject *parent): |
895 | QAbstractListModel(parent), |
896 | m_dbus(dbus), |
897 | @@ -77,10 +73,6 @@ |
898 | return -1; |
899 | } |
900 | |
901 | -/*** |
902 | -**** |
903 | -***/ |
904 | - |
905 | void DeviceModel::restartTimer() |
906 | { |
907 | m_timer.start (m_isDiscovering ? SCANNING_ACTIVE_DURATION_MSEC |
908 | @@ -123,10 +115,6 @@ |
909 | toggleDiscovery (); |
910 | } |
911 | |
912 | -/*** |
913 | -**** |
914 | -***/ |
915 | - |
916 | void DeviceModel::clearAdapter() |
917 | { |
918 | if (m_bluezAdapter) { |
919 | @@ -292,10 +280,6 @@ |
920 | updateProperty (key, value.variant()); |
921 | } |
922 | |
923 | -/*** |
924 | -**** |
925 | -***/ |
926 | - |
927 | void DeviceModel::addDevice(const QString &path) |
928 | { |
929 | QSharedPointer<Device> device(new Device(path, m_dbus)); |
930 | @@ -338,10 +322,6 @@ |
931 | } |
932 | } |
933 | |
934 | -/*** |
935 | -**** |
936 | -***/ |
937 | - |
938 | void DeviceModel::slotDeviceCreated(const QDBusObjectPath &path) |
939 | { |
940 | const QString service = "org.bluez"; |
941 | @@ -487,8 +467,18 @@ |
942 | QString(DBUS_AGENT_CAPABILITY)); |
943 | |
944 | QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pcall, this); |
945 | - QObject::connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), |
946 | - this, SLOT(slotCreateFinished(QDBusPendingCallWatcher*))); |
947 | + QObject::connect(watcher, &QDBusPendingCallWatcher::finished, [this, address](QDBusPendingCallWatcher *watcher) { |
948 | + QDBusPendingReply<QDBusObjectPath> reply = *watcher; |
949 | + |
950 | + if (reply.isError()) { |
951 | + qWarning() << "Could not create device:" << reply.error().message(); |
952 | + } else { |
953 | + QSharedPointer<Device> device = getDeviceFromAddress(address); |
954 | + device->connectPending(); |
955 | + } |
956 | + |
957 | + watcher->deleteLater(); |
958 | + }); |
959 | } else { |
960 | qWarning() << "Default adapter is not available for device creation"; |
961 | } |
962 | @@ -517,10 +507,6 @@ |
963 | } |
964 | } |
965 | |
966 | -/*** |
967 | -**** |
968 | -***/ |
969 | - |
970 | int |
971 | DeviceModel::rowCount(const QModelIndex &parent) const |
972 | { |
973 | |
974 | === modified file 'plugins/bluetooth/devicemodel.h' |
975 | --- plugins/bluetooth/devicemodel.h 2015-04-03 16:51:45 +0000 |
976 | +++ plugins/bluetooth/devicemodel.h 2015-08-28 09:33:03 +0000 |
977 | @@ -1,5 +1,5 @@ |
978 | /* |
979 | - * Copyright (C) 2013 Canonical Ltd |
980 | + * Copyright (C) 2013-2015 Canonical Ltd |
981 | * |
982 | * This program is free software: you can redistribute it and/or modify |
983 | * it under the terms of the GNU General Public License version 3 as |
984 | |
985 | === modified file 'plugins/bluetooth/plugin.cpp' |
986 | --- plugins/bluetooth/plugin.cpp 2015-03-16 13:51:36 +0000 |
987 | +++ plugins/bluetooth/plugin.cpp 2015-08-28 09:33:03 +0000 |
988 | @@ -1,5 +1,5 @@ |
989 | /* |
990 | - * Copyright (C) 2013 Canonical Ltd |
991 | + * Copyright (C) 2013-2015 Canonical Ltd |
992 | * |
993 | * This program is free software: you can redistribute it and/or modify |
994 | * it under the terms of the GNU General Public License version 3 as |
995 | |
996 | === modified file 'plugins/bluetooth/plugin.h' |
997 | --- plugins/bluetooth/plugin.h 2015-03-16 13:51:36 +0000 |
998 | +++ plugins/bluetooth/plugin.h 2015-08-28 09:33:03 +0000 |
999 | @@ -1,5 +1,5 @@ |
1000 | /* |
1001 | - * Copyright (C) 2013 Canonical Ltd |
1002 | + * Copyright (C) 2013-2015 Canonical Ltd |
1003 | * |
1004 | * This program is free software: you can redistribute it and/or modify |
1005 | * it under the terms of the GNU General Public License version 3 as |
1006 | |
1007 | === modified file 'tests/plugins/bluetooth/tst_device.cpp' |
1008 | --- tests/plugins/bluetooth/tst_device.cpp 2014-07-25 04:02:13 +0000 |
1009 | +++ tests/plugins/bluetooth/tst_device.cpp 2015-08-28 09:33:03 +0000 |
1010 | @@ -50,7 +50,6 @@ |
1011 | void testGetStrength(); |
1012 | void testGetPath(); |
1013 | void testMakeTrusted(); |
1014 | - void testDiscoverServices(); |
1015 | |
1016 | void cleanup(); |
1017 | |
1018 | @@ -152,15 +151,6 @@ |
1019 | QCOMPARE(state.toString(), expected); |
1020 | } |
1021 | |
1022 | -void DeviceTest::testDiscoverServices() |
1023 | -{ |
1024 | - m_device->discoverServices(); |
1025 | - |
1026 | - QVariant state = m_bluezMock->getProperty("org.bluez.Audio", "State"); |
1027 | - |
1028 | - checkAudioState("disconnected"); |
1029 | -} |
1030 | - |
1031 | void DeviceTest::testConnect() |
1032 | { |
1033 | testDiscoverServices(); |
Reworking bluetooth support in settings a bit to work as it should: Audio/Input/ ... interface wasn't registered yet)
* devices are now correctly connected after they got paired which wasn't the case before due to timing reasons (org.bluez.
* DevicePage is now created on the fly to avoid it displaying information for a moment from a previously selected device
* DevicePage is now split out of the PageComponent.qml file
* Discover service functionality is dropped as bluez does this on its own and we don't need to care