Merge lp:~morphis/ubuntu-system-settings/fix-device-actions into lp:ubuntu-system-settings

Proposed by Simon Fels
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
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.Audio/Input/... interface wasn't registered yet)
* 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

To post a comment you must log in.
Revision history for this message
Simon Fels (morphis) wrote :

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.Audio/Input/... interface wasn't registered yet)
* 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

1511. By Simon Fels

[bluetooth] correctly handle passed in RSSI values to report a signal strength
in the UI.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Ken VanDine (ken-vandine) wrote :

A couple questions inline

review: Needs Information
1512. By Simon Fels

[bluetooth] Drop superfluous elese case

Revision history for this message
Ken VanDine (ken-vandine) wrote :

A couple ore inline comments

review: Needs Fixing
1513. By Simon Fels

[bluetooth] Update copyright year and fix review comments

Revision history for this message
Ken VanDine (ken-vandine) wrote :

Looks great, thanks!

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
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();

Subscribers

People subscribed via source and target branches