Merge lp:~morphis/ubuntu-system-settings/bluez5-support into lp:ubuntu-system-settings
- bluez5-support
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Sebastien Bacher |
Approved revision: | 1567 |
Merged at revision: | 1562 |
Proposed branch: | lp:~morphis/ubuntu-system-settings/bluez5-support |
Merge into: | lp:ubuntu-system-settings |
Diff against target: |
3883 lines (+1901/-877) 44 files modified
debian/control (+1/-1) plugins/bluetooth/AuthorizationRequestDialog.qml (+53/-0) plugins/bluetooth/CMakeLists.txt (+16/-3) plugins/bluetooth/DevicePage.qml (+3/-2) plugins/bluetooth/DisplayPinCodeDialog.qml (+54/-0) plugins/bluetooth/PageComponent.qml (+81/-17) plugins/bluetooth/agent.cpp (+77/-54) plugins/bluetooth/agent.h (+9/-2) plugins/bluetooth/agent.xml (+0/-38) plugins/bluetooth/agentadaptor.cpp (+0/-75) plugins/bluetooth/agentadaptor.h (+0/-79) plugins/bluetooth/bluetooth.cpp (+19/-51) plugins/bluetooth/bluetooth.h (+3/-1) plugins/bluetooth/bluez_adapter1.cpp (+26/-0) plugins/bluetooth/bluez_adapter1.h (+66/-0) plugins/bluetooth/bluez_agent1adaptor.cpp (+93/-0) plugins/bluetooth/bluez_agent1adaptor.h (+96/-0) plugins/bluetooth/bluez_agentmanager1.cpp (+26/-0) plugins/bluetooth/bluez_agentmanager1.h (+68/-0) plugins/bluetooth/bluez_device1.cpp (+26/-0) plugins/bluetooth/bluez_device1.h (+85/-0) plugins/bluetooth/bluez_helper.h (+29/-0) plugins/bluetooth/dbus-shared.h (+9/-0) plugins/bluetooth/device.cpp (+181/-175) plugins/bluetooth/device.h (+21/-24) plugins/bluetooth/devicemodel.cpp (+254/-233) plugins/bluetooth/devicemodel.h (+21/-13) plugins/bluetooth/freedesktop_objectmanager.cpp (+26/-0) plugins/bluetooth/freedesktop_objectmanager.h (+58/-0) plugins/bluetooth/freedesktop_properties.cpp (+26/-0) plugins/bluetooth/freedesktop_properties.h (+71/-0) plugins/bluetooth/org.bluez.Adapter1.xml (+11/-0) plugins/bluetooth/org.bluez.Agent1.xml (+55/-0) plugins/bluetooth/org.bluez.AgentManager1.xml (+16/-0) plugins/bluetooth/org.bluez.Device1.xml (+16/-0) plugins/bluetooth/org.freedesktop.DBus.ObjectManager.xml (+19/-0) plugins/bluetooth/org.freedesktop.DBus.Properties.xml (+27/-0) plugins/bluetooth/plugin.cpp (+6/-0) tests/plugins/bluetooth/CMakeLists.txt (+17/-16) tests/plugins/bluetooth/fakebluez.cpp (+41/-4) tests/plugins/bluetooth/fakebluez.h (+9/-6) tests/plugins/bluetooth/tst_bluetooth.cpp (+100/-29) tests/plugins/bluetooth/tst_device.cpp (+67/-54) tests/plugins/bluetooth/tst_devicemodel.cpp (+19/-0) |
To merge this branch: | bzr merge lp:~morphis/ubuntu-system-settings/bluez5-support |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Sebastien Bacher (community) | Approve | ||
Jonas G. Drange (community) | Approve | ||
PS Jenkins bot | continuous-integration | Needs Fixing | |
Review via email: mp+271456@code.launchpad.net |
Commit message
Ported the Bluetooth plugin to the changed BlueZ API which comes with version 5.x. The overall device management gets a lot more reliable with this. Superfluous code was dropped when possible. Also the unit tests got a rework and all pass now.
Description of the change
- 1532. By Simon Fels
-
Don't allow connect/disconnect of a device when bluetooth is turned off
- 1533. By Simon Fels
-
Correctly unregister our agent with BlueZ
- 1534. By Simon Fels
-
Fix list management according to current bluetooth power state
- 1535. By Simon Fels
-
Update Bluetooth implementation to use BlueZ 5 API
PS Jenkins bot (ps-jenkins) wrote : | # |
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1535
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 1536. By Simon Fels
-
Disable bluetooth tests until they are migrated
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1536
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://
- 1537. By Simon Fels
-
Make tests working and cleanup code
- 1538. By Simon Fels
-
Restructure qdbus wrappers a bit
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1538
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: http://
FAILURE: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Sebastien Bacher (seb128) wrote : | # |
Thanks Simon, that seems to work mostly fine, some issues from testing that version on wily (some might not be new/were already there previous bluez)
- the "discoverable" label is not followed by the machine name
- clicking on a device in the autoconnect list and doing "forget that device" seems to not work (it was not reliable before or had delay but now seems to not work at all), in fact it works but the UI doesn't refresh until you exit the panel and enter it back
- sometimes the discoverable status hits "WARNING - Failed to start device discovery: "Operation already in progress"", it seems to keep trying and the item spins but never settle
- when pairing a keyboard, the device is correctly paired and connected (e.g I can type on it), but the list still show it as "to connect", the details view also has state "disconnected" (works after exiting the panel and coming back)
- the devices list once open doesn't seem to pick up new devices dynamically
In fact from those notes it seems that the devices list is not refreshed in some cases where it should (basically after actions like pairing, forgetting devices, etc)
- 1539. By Simon Fels
-
Merge with trunk
* Update Bluetooth implementation to use the BlueZ 5 DBus API
[ jonas-drange ]
* [hotspot] hide/show based on modem availability from Connectivity
(which also requires a bumped dep). (LP: #1487157)
* [time-date] Migrate threaded code to worker-object pattern, move
sorting to a worker thread from the GUI thread, and only instantiate
UbuntuTimeDatePanel plugin once. (LP: #1492260)
* [wifi/wpa2ep] allow passwords of length 1 for wpa enterprise
authentication schemes. (LP: #1490417)
[ Ken VanDine ]
* ported to libqofono 0.82 (modemTechnologies now
availableTechnologies)
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1539
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://
- 1540. By Simon Fels
-
Merge with trunk
* Used the correct property to determine if whoopsie will
automatically report crashes (LP: #1494442)
[ CI Train Bot ]
* New rebuild forced.
[ jonas-drange ]
* [autopilot] use wait_select_single instead of select_single for all
click_item
* [security-privacy] fix test broken by recent ui changes - 1541. By Simon Fels
-
bluetooth: give test a bit more time to let dbus events come in
- 1542. By Simon Fels
-
Update changelog
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:1540
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 1543. By Simon Fels
-
tests: bluetooth: give discovery tests a bit more time to process incoming
dbus events.
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:1542
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1543
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://
- 1544. By Simon Fels
-
Improve agent implementation to handle authorization requests too and register
our agent as default one to get all requests (also those for incoming pairing
requests). - 1545. By Simon Fels
-
If device is not paired yet but should be connected pair it first and
continue with connecting it. - 1546. By Simon Fels
-
Correct connection state handling after State property for profiles/devices
doesn't exists anymore with BlueZ 5.x
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:1546
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 1547. By Simon Fels
-
Update connection state according to the device state
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:1547
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 1548. By Simon Fels
-
Install missing bluetooth qml files
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1548
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://
- 1549. By Simon Fels
-
Take 100ms for all event processing when running the bluetooth tests by
default to cause no failures on any hardware platform due to timing reasons. - 1550. By Simon Fels
-
Merge with trunk
[ Sebastien Bacher ]
* [hospot] include cmakefile hack to get files listed in qtcreator
* [security-privacy] use the system location as well to look for trust
store items, that's needed at least for unity8-dash which is not
distributed as a click and doesn't a .local entry (LP: #1501428)
* [sound] don't display silent mode warnings, sounds should just be
played when user selected (LP: #1391502)
[ jonas-drange ]
* [phone] encode numbers before passing them to url-dispatcher (LP:
#1496845) - 1551. By Simon Fels
-
Fix incorrect component name
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1551
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://
- 1552. By Simon Fels
-
Allow the user to disconnect devices which are not supported but are
connected. This can happen when a remote device initiates the pairing
process and we just respond to it and allow the pairing to succeed.
Rather than to prevent this we allow this in order to supporte those
types in the future as ones we can deal with.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1552
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://
- 1553. By Simon Fels
-
bluetooth: Ignore devices with type "other"
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1553
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 1554. By Simon Fels
-
Fix bluetooth tests and enable device class tests again
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1554
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://
- 1555. By Simon Fels
-
Close pairing popup according to the result of the actual operation. The
semantics of the unerlaying API has changed a bit so a rework was needed.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1555
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://
- 1556. By Simon Fels
-
Merge with trunk
[ CI Train Bot ]
* New rebuild forced.
[ Ken VanDine ]
* Bump Ubuntu.Components imports to 1.3 and fixed UbuntuShape
deprecations (LP: #1508363)
[ jonas-drange ]
* re-add silentMode property to repair the silent mode switch
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1556
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://
- 1557. By Simon Fels
-
Give us a bit more time to receive dbus events and process them
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1557
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://
Sebastien Bacher (seb128) wrote : | # |
there are quite some changes there but things look mostly fine and the change got several round of testing and is working in most cases, giving a preliminary +1 but we should do a full round of testing before landing and have more detailed look at the change, especially from people knowing qt a bit better would be welcome
Sebastien Bacher (seb128) wrote : | # |
Looking a bit more there are some changes needed, we need at least to bump the bluez requirement in debian/control, the uitk import should also be bumped to 1.3 since that landed for ota8
Sebastien Bacher (seb128) wrote : | # |
The Yes/No labels in new the dialog should probably be rather Allow/Refuse (just commenting about that, more reviewing for later)
Jonas G. Drange (jonas-drange) wrote : | # |
https:/
Jonas G. Drange (jonas-drange) wrote : | # |
Looking good, Simon. Some comments:
* I got this output from opening the BT panel and then turning BT off: http://
* The “Forgetting a device” test in the test plan [1] fails for my Dell XPS13 Ubuntu Desktop. If I forget the device, the device can be forgotten after it's rediscovered.
- 1558. By Simon Fels
-
Only enable forget button when device is paired
- 1559. By Simon Fels
-
[ Bartosz Kosiorek ]
* Remove "Retry" button, when no internet connection is available. It
will automatically retry after establishing connection (LP:
#1479447) (LP: #1479447)
[ Ken VanDine ]
* Don't elide connect to internet label (LP: #1512768)
* Ensure we only check for updates when NetworkingStatus.online is
true (LP: #1505663)
* [system-settings] Abort request when the onlineStatus changes to
false (LP: #1505663)
[ CI Train Bot ]
* New rebuild forced.
[ jonas-drange ]
* Deprecated the use of Info endpoint in system_update.cpp and
hotspot. Exposed detailed version details on UpdateManager. Used
this to get to a 'tag' key which includes the ota string. Because of
more advanced system-image testing, about tests now use the
systemimage dbusmock template. debian/control, s-i-dbus changed to
3.0.2 because that's where the ota string is. (LP: #1475568) - 1560. By Simon Fels
-
Correct changelog
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1560
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://
- 1561. By Simon Fels
-
Bump uitk version to 1.3 and change labels of authorization request dialog
- 1562. By Simon Fels
-
Bump required bluez version to 5.23 (it's the first version of bluez5 we
had in Ubuntu)
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1562
http://
Executed test runs:
FAILURE: http://
SUCCESS: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 1563. By Simon Fels
-
[ jonas-drange ]
Cache call forwarding summary for each IMSI/ICCID. Block UI until
the CallForwarding binding is ready. Do not assume a failed
callforwarding change means it's disabled (could be forced by
carrier). (LP: #1478049) - 1564. By Simon Fels
-
Use correct variable name to pass pincode to the created dialog
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1563
http://
Executed test runs:
FAILURE: http://
SUCCESS: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1564
http://
Executed test runs:
FAILURE: http://
SUCCESS: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 1565. By Simon Fels
-
Check for dbus menu model property before accessing it
- 1566. By Simon Fels
-
Don't try to make us discoverable again when the property changes. This can
happen when bluetooth gets disabled by something else.
Simon Fels (morphis) wrote : | # |
Fixed all review comments. Also did one further fix to enable pairing with devices using LegacyPairing where the DisplayPin dialog didn't came up.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1566
http://
Executed test runs:
FAILURE: http://
SUCCESS: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 1567. By Simon Fels
-
Detect bluetooth watch devices
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1567
http://
Executed test runs:
FAILURE: http://
SUCCESS: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Jonas G. Drange (jonas-drange) wrote : | # |
LGTM! Great stuff. Thanks
Sebastien Bacher (seb128) wrote : | # |
the qt imports got bumped from 2.0 to 2.4 in the uitk 1.3 update, unsure if that makes a difference/should be done the same way here, otherwise looks good, thanks!
Simon Fels (morphis) wrote : | # |
Manual test run:
Running tests...
Test project /home/simon/
Start 1: tst-plugins
1/11 Test #1: tst-plugins .......
Start 2: tst-arguments
2/11 Test #2: tst-arguments .......
Start 3: python3
3/11 Test #3: python3 .......
Start 4: test_push_helper
4/11 Test #4: test_push_helper ................. Passed 0.17 sec
Start 5: tst-trust-
5/11 Test #5: tst-trust-
Start 6: tst-update-manager
6/11 Test #6: tst-update-manager ............... Passed 0.13 sec
Start 7: tst-update
7/11 Test #7: tst-update .......
Start 8: tst-network
8/11 Test #8: tst-network .......
Start 9: tst-bluetooth
9/11 Test #9: tst-bluetooth .......
Start 10: tst-bluetooth-
10/11 Test #10: tst-bluetooth-
Start 11: tst-bluetooth-
11/11 Test #11: tst-bluetooth-
100% tests passed, 0 tests failed out of 11
Total Test time (real) = 26.30 sec
- 1568. By Simon Fels
-
bluetooth: set a timeout of 60 seconds for our dbus calls to the bluez Device
interface - 1569. By Simon Fels
-
bluetooth: allow us to connect with bt watch device class devices
- 1570. By Simon Fels
-
[ Alejandro J. Cura ]
* If a system package gets updated by the user, only show the user's
copy (LP: #1265250)
[ Bartosz Kosiorek ]
* Allow translating "Unavailable" string (LP: #1511384) (LP: #1511384)
[ Ken VanDine ]
* Don't check for updates if not online (LP: #1505663)
[ Michael Zanetti ]
* Only animate ActivityIndicators when they are visible (LP: #1513450)
Preview Diff
1 | === modified file 'debian/control' |
2 | --- debian/control 2015-10-29 15:48:06 +0000 |
3 | +++ debian/control 2015-11-20 08:48:08 +0000 |
4 | @@ -60,7 +60,7 @@ |
5 | ${shlibs:Depends}, |
6 | accountsservice, |
7 | accountsservice-ubuntu-schemas (>= 0.0.3+14.10.20140829~), |
8 | - bluez (>= 4.36), |
9 | + bluez (>= 5.23), |
10 | click | ubuntu-snappy-cli, |
11 | dbus-property-service [amd64 armhf i386], |
12 | gsettings-desktop-schemas, |
13 | |
14 | === added file 'plugins/bluetooth/AuthorizationRequestDialog.qml' |
15 | --- plugins/bluetooth/AuthorizationRequestDialog.qml 1970-01-01 00:00:00 +0000 |
16 | +++ plugins/bluetooth/AuthorizationRequestDialog.qml 2015-11-20 08:48:08 +0000 |
17 | @@ -0,0 +1,53 @@ |
18 | +/* |
19 | + * This file is part of ubuntu-system-settings |
20 | + * |
21 | + * Copyright (C) 2013-2015 Canonical Ltd. |
22 | + * |
23 | + * This program is free software: you can redistribute it and/or modify it |
24 | + * under the terms of the GNU General Public License version 3, as published |
25 | + * by the Free Software Foundation. |
26 | + * |
27 | + * This program is distributed in the hope that it will be useful, but |
28 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
29 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
30 | + * PURPOSE. See the GNU General Public License for more details. |
31 | + * |
32 | + * You should have received a copy of the GNU General Public License along |
33 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
34 | + */ |
35 | + |
36 | + |
37 | +import QtQuick 2.0 |
38 | +import Ubuntu.Components 1.3 |
39 | +import Ubuntu.Components.Popups 1.3 |
40 | + |
41 | +Dialog { |
42 | + id: root |
43 | + title: i18n.tr("Bluetooth Pairing Authorization Request") |
44 | + |
45 | + property string name: "Unknown" |
46 | + |
47 | + signal accepted |
48 | + signal declined |
49 | + |
50 | + // TRANSLATORS: %1 is the name of the bluetooth device which requires authorization |
51 | + text: i18n.tr("The device %1 wants to pair with this device. Do you want to allow this?").arg(root.name) |
52 | + |
53 | + Row { |
54 | + spacing: units.gu(1) |
55 | + Button { |
56 | + text: i18n.tr("Allow") |
57 | + onClicked: { |
58 | + root.allowed() |
59 | + PopupUtils.close(root) |
60 | + } |
61 | + } |
62 | + Button { |
63 | + text: i18n.tr("Refuse") |
64 | + onClicked: { |
65 | + root.denied() |
66 | + PopupUtils.close(root) |
67 | + } |
68 | + } |
69 | + } |
70 | +} |
71 | |
72 | === modified file 'plugins/bluetooth/CMakeLists.txt' |
73 | --- plugins/bluetooth/CMakeLists.txt 2015-08-26 08:47:44 +0000 |
74 | +++ plugins/bluetooth/CMakeLists.txt 2015-11-20 08:48:08 +0000 |
75 | @@ -3,21 +3,34 @@ |
76 | set(QML_SOURCES |
77 | ProvidePinCodeDialog.qml |
78 | ConfirmPasskeyDialog.qml |
79 | +DisplayPinCodeDialog.qml |
80 | DisplayPasskeyDialog.qml |
81 | ProvidePasskeyDialog.qml |
82 | +AuthorizationRequestDialog.qml |
83 | DevicePage.qml |
84 | PageComponent.qml |
85 | ) |
86 | |
87 | add_library(UbuntuBluetoothPanel MODULE |
88 | + bluez_adapter1.cpp |
89 | + bluez_agentmanager1.cpp |
90 | + bluez_device1.cpp |
91 | + bluez_agent1adaptor.cpp |
92 | + freedesktop_properties.cpp |
93 | + freedesktop_objectmanager.cpp |
94 | agent.cpp |
95 | - agentadaptor.cpp |
96 | bluetooth.cpp |
97 | device.cpp |
98 | devicemodel.cpp |
99 | + bluez_adapter1.h |
100 | + bluez_agentmanager1.h |
101 | + bluez_device1.h |
102 | + bluez_agent1adaptor.h |
103 | + freedesktop_properties.h |
104 | + freedesktop_objectmanager.h |
105 | plugin.cpp |
106 | - agent.h |
107 | - agentadaptor.h |
108 | + bluez_helper.h |
109 | + agent.h |
110 | bluetooth.h |
111 | device.h |
112 | devicemodel.h |
113 | |
114 | === modified file 'plugins/bluetooth/DevicePage.qml' |
115 | --- plugins/bluetooth/DevicePage.qml 2015-09-18 14:18:11 +0000 |
116 | +++ plugins/bluetooth/DevicePage.qml 2015-11-20 08:48:08 +0000 |
117 | @@ -58,6 +58,7 @@ |
118 | case Device.Mouse: return i18n.tr("Mouse"); |
119 | case Device.Printer: return i18n.tr("Printer"); |
120 | case Device.Camera: return i18n.tr("Camera"); |
121 | + case Device.Watch: return i18n.tr("Watch"); |
122 | default: return i18n.tr("Other"); |
123 | } |
124 | } |
125 | @@ -180,7 +181,7 @@ |
126 | pageStack.pop(); |
127 | } |
128 | visible: backend.selectedDevice ? true : false |
129 | - enabled: backend.selectedDevice ? backend.isSupportedType(backend.selectedDevice.type) : false |
130 | + enabled: backend.selectedDevice && backend.powered ? (backend.isSupportedType(backend.selectedDevice.type) || backend.selectedDevice.connection != Device.Disconnected) : false |
131 | } |
132 | } |
133 | ListItem.SingleControl { |
134 | @@ -192,7 +193,7 @@ |
135 | backend.resetSelectedDevice(); |
136 | pageStack.pop(); |
137 | } |
138 | - enabled: backend.selectedDevice && backend.selectedDevice.path.length > 0 ? true : false |
139 | + enabled: backend.selectedDevice && backend.selectedDevice.path.length > 0 && backend.selectedDevice.paired ? true : false |
140 | } |
141 | } |
142 | } |
143 | |
144 | === added file 'plugins/bluetooth/DisplayPinCodeDialog.qml' |
145 | --- plugins/bluetooth/DisplayPinCodeDialog.qml 1970-01-01 00:00:00 +0000 |
146 | +++ plugins/bluetooth/DisplayPinCodeDialog.qml 2015-11-20 08:48:08 +0000 |
147 | @@ -0,0 +1,54 @@ |
148 | +/* |
149 | + * This file is part of ubuntu-system-settings |
150 | + * |
151 | + * Copyright (C) 2013-2015 Canonical Ltd. |
152 | + * |
153 | + * This program is free software: you can redistribute it and/or modify it |
154 | + * under the terms of the GNU General Public License version 3, as published |
155 | + * by the Free Software Foundation. |
156 | + * |
157 | + * This program is distributed in the hope that it will be useful, but |
158 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
159 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
160 | + * PURPOSE. See the GNU General Public License for more details. |
161 | + * |
162 | + * You should have received a copy of the GNU General Public License along |
163 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
164 | + */ |
165 | + |
166 | + |
167 | +import QtQuick 2.0 |
168 | +import Ubuntu.Components 1.3 |
169 | +import Ubuntu.Components.Popups 1.3 |
170 | + |
171 | +Dialog { |
172 | + id: root |
173 | + title: i18n.tr("Bluetooth Pairing Request") |
174 | + |
175 | + property string name: "Unknown" |
176 | + property string pincode: "" |
177 | + |
178 | + signal canceled |
179 | + |
180 | + // TRANSLATORS: %1 is the name of the bluetooth device being paired |
181 | + text: i18n.tr("Please enter the following PIN on %1 and press “Enter” on the keyboard:").arg(root.name) |
182 | + |
183 | + Label { |
184 | + text: root.pincode+"⏎" |
185 | + fontSize: "x-large" |
186 | + verticalAlignment: Text.AlignVCenter |
187 | + horizontalAlignment: Text.AlignHCenter |
188 | + } |
189 | + |
190 | + Row { |
191 | + spacing: units.gu(1) |
192 | + Button { |
193 | + text: i18n.tr("Cancel") |
194 | + onClicked: { |
195 | + root.canceled() |
196 | + PopupUtils.close(root) |
197 | + } |
198 | + width: (parent.width - parent.spacing) |
199 | + } |
200 | + } |
201 | +} |
202 | |
203 | === modified file 'plugins/bluetooth/PageComponent.qml' |
204 | --- plugins/bluetooth/PageComponent.qml 2015-11-05 12:57:06 +0000 |
205 | +++ plugins/bluetooth/PageComponent.qml 2015-11-20 08:48:08 +0000 |
206 | @@ -34,8 +34,28 @@ |
207 | objectName: "bluetoothPage" |
208 | |
209 | property var dialogPopupId |
210 | - |
211 | - UbuntuBluetoothPanel { id: backend } |
212 | + property var currentDevice |
213 | + |
214 | + function finishDevicePairing() { |
215 | + if (root.dialogPopupId) |
216 | + PopupUtils.close(root.dialogPopupId) |
217 | + |
218 | + root.dialogPopupId = null |
219 | + root.currentDevice = null |
220 | + } |
221 | + |
222 | + UbuntuBluetoothPanel { |
223 | + id: backend |
224 | + |
225 | + onDevicePairingDone: { |
226 | + console.log("Got pairing status notification for device " + device.address) |
227 | + |
228 | + if (device != root.currentDevice) |
229 | + return |
230 | + |
231 | + finishDevicePairing() |
232 | + } |
233 | + } |
234 | |
235 | Timer { |
236 | id: discoverableTimer |
237 | @@ -71,12 +91,23 @@ |
238 | } |
239 | |
240 | Component { |
241 | + id: displayPinCodeDialog |
242 | + DisplayPinCodeDialog { } |
243 | + } |
244 | + |
245 | + Component { |
246 | id: displayPasskeyDialog |
247 | DisplayPasskeyDialog { } |
248 | } |
249 | |
250 | + Component { |
251 | + id: authorizationRequestDialog |
252 | + AuthorizationRequestDialog { } |
253 | + } |
254 | + |
255 | Connections { |
256 | target: backend.agent |
257 | + onCancelNeeded: finishDevicePairing() |
258 | onPasskeyConfirmationNeeded: { |
259 | var request_tag = tag |
260 | var popup = PopupUtils.open(confirmPasskeyDialog, root, {passkey: passkey, name: device.name}) |
261 | @@ -95,23 +126,60 @@ |
262 | popup.canceled.connect(function() {target.providePinCode(request_tag, false, "")}) |
263 | popup.provided.connect(function(pinCode) {target.providePinCode(request_tag, true, pinCode)}) |
264 | } |
265 | + onDisplayPinCodeNeeded: { |
266 | + if (!root.dialogPopupId) |
267 | + { |
268 | + root.currentDevice = device |
269 | + root.dialogPopupId = PopupUtils.open(displayPinCodeDialog, root, {pincode: pincode, name: device.name}) |
270 | + root.dialogPopupId.canceled.connect(function() { |
271 | + root.dialogPopupId = null |
272 | + if (root.currentDevice) { |
273 | + root.currentDevice.cancelPairing() |
274 | + root.currentDevice = null |
275 | + } |
276 | + }) |
277 | + } |
278 | + else |
279 | + { |
280 | + console.warn("Unhandled PIN code request for device " + device.name); |
281 | + } |
282 | + } |
283 | onDisplayPasskeyNeeded: { |
284 | if (!root.dialogPopupId) |
285 | { |
286 | - var request_tag = tag |
287 | + root.currentDevice = device |
288 | root.dialogPopupId = PopupUtils.open(displayPasskeyDialog, root, {passkey: passkey, name: device.name, |
289 | entered: entered}) |
290 | - root.dialogPopupId.canceled.connect(function() {root.dialogPopupId = null; |
291 | - target.displayPasskeyCallback(request_tag)}) |
292 | + root.dialogPopupId.canceled.connect(function() { |
293 | + root.dialogPopupId = null |
294 | + if (root.currentDevice) { |
295 | + root.currentDevice.cancelPairing() |
296 | + root.currentDevice = null |
297 | + } |
298 | + }) |
299 | } |
300 | else |
301 | { |
302 | root.dialogPopupId.entered = entered |
303 | } |
304 | } |
305 | - onPairingDone: { |
306 | - if (root.dialogPopupId) |
307 | - PopupUtils.close(root.dialogPopupId) |
308 | + onReleaseNeeded: { |
309 | + finishDevicePairing() |
310 | + } |
311 | + onAuthorizationRequested: { |
312 | + if (!root.dialogPopupId) |
313 | + { |
314 | + var request_tag = tag |
315 | + root.dialogPopupId = PopupUtils.open(authorizationRequestDialog, root, {name: device.name}) |
316 | + root.dialogPopupId.accepted.connect(function() { |
317 | + root.dialogPopupId = null |
318 | + target.authorizationRequestCallback(request_tag, true) |
319 | + }) |
320 | + root.dialogPopupId.declined.connect(function() { |
321 | + root.dialogPopupId = null |
322 | + target.authorizationRequestCallback(request_tag, false) |
323 | + }) |
324 | + } |
325 | } |
326 | } |
327 | |
328 | @@ -151,7 +219,7 @@ |
329 | text: i18n.tr("Bluetooth") |
330 | control: Switch { |
331 | id: btSwitch |
332 | - property bool serverChecked: bluetoothActionGroup.enabled.state |
333 | + property bool serverChecked: bluetoothActionGroup.enabled.state != undefined ? bluetoothActionGroup.enabled.state : false |
334 | USC.ServerPropertySynchroniser { |
335 | userTarget: btSwitch |
336 | userProperty: "checked" |
337 | @@ -210,7 +278,6 @@ |
338 | } |
339 | } |
340 | |
341 | - // Connnected Headset(s) |
342 | ListItem.Standard { |
343 | id: connectedHeader |
344 | text: i18n.tr("Connected devices:") |
345 | @@ -225,7 +292,7 @@ |
346 | left: parent.left |
347 | right: parent.right |
348 | } |
349 | - visible: bluetoothActionGroup.enabled && (connectedRepeater.count > 0) |
350 | + visible: (bluetoothActionGroup.enabled.state != undefined && bluetoothActionGroup.enabled.state) && (connectedRepeater.count > 0) |
351 | objectName: "connectedList" |
352 | |
353 | Repeater { |
354 | @@ -248,12 +315,10 @@ |
355 | } |
356 | } |
357 | |
358 | - // Disconnnected Headset(s) |
359 | - |
360 | SettingsItemTitle { |
361 | id: disconnectedHeader |
362 | text: connectedList.visible ? i18n.tr("Connect another device:") : i18n.tr("Connect a device:") |
363 | - enabled: bluetoothActionGroup.enabled |
364 | + enabled: bluetoothActionGroup.enabled.state != undefined ? bluetoothActionGroup.enabled.state : false |
365 | control: ActivityIndicator { |
366 | visible: backend.powered && backend.discovering |
367 | running: visible |
368 | @@ -266,7 +331,7 @@ |
369 | left: parent.left |
370 | right: parent.right |
371 | } |
372 | - visible: bluetoothActionGroup.enabled && (disconnectedRepeater.count > 0) |
373 | + visible: (bluetoothActionGroup.enabled.state != undefined && bluetoothActionGroup.enabled.state) && (disconnectedRepeater.count > 0) |
374 | objectName: "disconnectedList" |
375 | |
376 | Repeater { |
377 | @@ -287,11 +352,10 @@ |
378 | ListItem.Standard { |
379 | id: disconnectedNone |
380 | text: i18n.tr("None detected") |
381 | - visible: !disconnectedList.visible |
382 | + visible: !disconnectedList.visible && disconnectedHeader.visible |
383 | enabled: false |
384 | } |
385 | |
386 | - // Devices that connect automatically |
387 | SettingsItemTitle { |
388 | id: autoconnectHeader |
389 | text: i18n.tr("Connect automatically when detected:") |
390 | |
391 | === modified file 'plugins/bluetooth/agent.cpp' |
392 | --- plugins/bluetooth/agent.cpp 2015-08-28 09:32:38 +0000 |
393 | +++ plugins/bluetooth/agent.cpp 2015-11-20 08:48:08 +0000 |
394 | @@ -53,7 +53,7 @@ |
395 | */ |
396 | void Agent::Release() |
397 | { |
398 | - Q_EMIT(pairingDone()); |
399 | + Q_EMIT(releaseNeeded()); |
400 | } |
401 | |
402 | /*** |
403 | @@ -112,9 +112,24 @@ |
404 | } |
405 | } |
406 | |
407 | -/*** |
408 | -**** |
409 | -***/ |
410 | +QString Agent::RequestPinCode(const QDBusObjectPath &objectPath) |
411 | +{ |
412 | + auto device = m_devices.getDeviceFromPath(objectPath.path()); |
413 | + if (device) { |
414 | + const uint tag = m_tag++; |
415 | + |
416 | + setDelayedReply(true); |
417 | + assert(!m_delayedReplies.contains(tag)); |
418 | + m_delayedReplies[tag] = message(); |
419 | + |
420 | + Q_EMIT(pinCodeNeeded(tag, device.data())); |
421 | + |
422 | + } else { // passkey requested for an unknown device..?! |
423 | + reject(message(), __func__); |
424 | + } |
425 | + |
426 | + return 0; |
427 | +} |
428 | |
429 | /** |
430 | * This method gets called when the service daemon |
431 | @@ -168,35 +183,6 @@ |
432 | **** |
433 | ***/ |
434 | |
435 | -/* |
436 | - * This method gets called when the service daemon |
437 | - * needs to get the passkey for an authentication. |
438 | - * |
439 | - * The return value should be a string of 1-16 characters |
440 | - * length. The string can be alphanumeric. |
441 | - * |
442 | - * Possible errors: org.bluez.Error.Rejected |
443 | - * org.bluez.Error.Canceled |
444 | - */ |
445 | -QString Agent::RequestPinCode(const QDBusObjectPath &objectPath) |
446 | -{ |
447 | - auto device = m_devices.getDeviceFromPath(objectPath.path()); |
448 | - if (device) { |
449 | - const uint tag = m_tag++; |
450 | - |
451 | - setDelayedReply(true); |
452 | - assert(!m_delayedReplies.contains(tag)); |
453 | - m_delayedReplies[tag] = message(); |
454 | - |
455 | - Q_EMIT(pinCodeNeeded(tag, device.data())); |
456 | - |
457 | - } else { // passkey requested for an unknown device..?! |
458 | - reject(message(), __func__); |
459 | - } |
460 | - |
461 | - return ""; |
462 | -} |
463 | - |
464 | /** |
465 | * Invoked by the user-facing code after it prompts the user for a PIN code |
466 | * from an Agent::pinCodeNeeded() signal. |
467 | @@ -218,33 +204,23 @@ |
468 | } |
469 | } |
470 | |
471 | -/** This method gets called when the service daemon |
472 | - * needs to display a passkey for an authentication. |
473 | - * The entered parameter indicates the number of already |
474 | - * typed keys on the remote side. |
475 | - * An empty reply should be returned. When the passkey |
476 | - * needs no longer to be displayed, the Cancel method |
477 | - * of the agent will be called. |
478 | - * During the pairing process this method might be |
479 | - * called multiple times to update the entered value. |
480 | - * Note that the passkey will always be a 6-digit number, |
481 | - * so the display should be zero-padded at the start if |
482 | - * the value contains less than 6 digits. |
483 | - */ |
484 | +void Agent::DisplayPinCode(const QDBusObjectPath &objectPath, QString pincode) |
485 | +{ |
486 | + auto device = m_devices.getDeviceFromPath(objectPath.path()); |
487 | + if (device) { |
488 | + Q_EMIT(displayPinCodeNeeded(device.data(), pincode)); |
489 | + } else { |
490 | + reject(message(), __func__); |
491 | + } |
492 | +} |
493 | |
494 | void Agent::DisplayPasskey(const QDBusObjectPath &objectPath, uint passkey, ushort entered) |
495 | { |
496 | auto device = m_devices.getDeviceFromPath(objectPath.path()); |
497 | if (device) { |
498 | - const uint tag = m_tag++; |
499 | - |
500 | - setDelayedReply(true); |
501 | - assert(!m_delayedReplies.contains(tag)); |
502 | - m_delayedReplies[tag] = message(); |
503 | - |
504 | QString passkeyStr = QString("%1").arg(passkey, 6, 10, QChar('0')); |
505 | - Q_EMIT(displayPasskeyNeeded(tag, device.data(), passkeyStr, entered)); |
506 | - } else { // confirmation requested for an unknown device..?! |
507 | + Q_EMIT(displayPasskeyNeeded(device.data(), passkeyStr, entered)); |
508 | + } else { |
509 | reject(message(), __func__); |
510 | } |
511 | } |
512 | @@ -256,6 +232,53 @@ |
513 | void Agent::Cancel() |
514 | { |
515 | qWarning() << "Cancel callback called"; |
516 | + |
517 | + Q_EMIT(cancelNeeded()); |
518 | +} |
519 | + |
520 | +void Agent::RequestAuthorization(const QDBusObjectPath &path) |
521 | +{ |
522 | + qWarning() << "Authorization requested for device" |
523 | + << path.path(); |
524 | + |
525 | + auto device = m_devices.getDeviceFromPath(path.path()); |
526 | + if (device) { |
527 | + const uint tag = m_tag++; |
528 | + |
529 | + setDelayedReply(true); |
530 | + assert(!m_delayedReplies.contains(tag)); |
531 | + m_delayedReplies[tag] = message(); |
532 | + |
533 | + Q_EMIT(authorizationRequested(tag, device.data())); |
534 | + } |
535 | + else { |
536 | + reject(message(), __func__); |
537 | + } |
538 | +} |
539 | + |
540 | +void Agent::authorizationRequestCallback(uint tag, bool allow) |
541 | +{ |
542 | + if (m_delayedReplies.contains(tag)) { |
543 | + QDBusMessage message = m_delayedReplies[tag]; |
544 | + |
545 | + if (allow) |
546 | + m_connection.send(message.createReply()); |
547 | + else |
548 | + reject(message, __func__); |
549 | + |
550 | + m_delayedReplies.remove(tag); |
551 | + } |
552 | +} |
553 | + |
554 | +void Agent::displayPinCodeCallback(uint tag) |
555 | +{ |
556 | + if (m_delayedReplies.contains(tag)) { |
557 | + QDBusMessage message = m_delayedReplies[tag]; |
558 | + |
559 | + cancel(message, __func__); |
560 | + |
561 | + m_delayedReplies.remove(tag); |
562 | + } |
563 | } |
564 | |
565 | /** |
566 | |
567 | === modified file 'plugins/bluetooth/agent.h' |
568 | --- plugins/bluetooth/agent.h 2015-08-28 09:32:38 +0000 |
569 | +++ plugins/bluetooth/agent.h 2015-11-20 08:48:08 +0000 |
570 | @@ -41,22 +41,29 @@ |
571 | Q_INVOKABLE void confirmPasskey(uint tag, bool confirmed); |
572 | Q_INVOKABLE void providePasskey(uint tag, bool provided, uint passkey); |
573 | Q_INVOKABLE void providePinCode(uint tag, bool provided, QString pinCode); |
574 | + Q_INVOKABLE void displayPinCodeCallback(uint tag); |
575 | Q_INVOKABLE void displayPasskeyCallback(uint tag); |
576 | + Q_INVOKABLE void authorizationRequestCallback(uint tag, bool allow); |
577 | |
578 | public Q_SLOTS: // received from the system's bluez service |
579 | void Cancel(); |
580 | + void DisplayPinCode(const QDBusObjectPath &path, QString pincode); |
581 | void DisplayPasskey(const QDBusObjectPath &path, uint passkey, ushort entered); |
582 | void Release(); |
583 | void RequestConfirmation(const QDBusObjectPath &path, uint passkey); |
584 | uint RequestPasskey(const QDBusObjectPath &path); |
585 | QString RequestPinCode(const QDBusObjectPath &path); |
586 | + void RequestAuthorization(const QDBusObjectPath &path); |
587 | |
588 | Q_SIGNALS: |
589 | void pinCodeNeeded(int tag, Device* device); |
590 | void passkeyNeeded(int tag, Device* device); |
591 | void passkeyConfirmationNeeded(int tag, Device* device, QString passkey); |
592 | - void displayPasskeyNeeded(int tag, Device* device, QString passkey, ushort entered); |
593 | - void pairingDone(); |
594 | + void displayPinCodeNeeded(Device* device, QString pincode); |
595 | + void displayPasskeyNeeded(Device* device, QString passkey, ushort entered); |
596 | + void releaseNeeded(); |
597 | + void cancelNeeded(); |
598 | + void authorizationRequested(int tag, Device* device); |
599 | |
600 | private: |
601 | Q_DISABLE_COPY(Agent) |
602 | |
603 | === removed file 'plugins/bluetooth/agent.xml' |
604 | --- plugins/bluetooth/agent.xml 2015-02-04 10:48:47 +0000 |
605 | +++ plugins/bluetooth/agent.xml 1970-01-01 00:00:00 +0000 |
606 | @@ -1,38 +0,0 @@ |
607 | -<?xml version="1.0" encoding="UTF-8" ?> |
608 | - |
609 | -<node name="/"> |
610 | - <interface name="org.bluez.Agent"> |
611 | - <method name="RequestPinCode"> |
612 | - <annotation name="org.freedesktop.DBus.GLib.Async" value=""/> |
613 | - <arg type="o" name="device"/> |
614 | - <arg type="s" name="pincode" direction="out"/> |
615 | - </method> |
616 | - |
617 | - <method name="RequestPasskey"> |
618 | - <annotation name="org.freedesktop.DBus.GLib.Async" value=""/> |
619 | - <arg type="o" name="device"/> |
620 | - <arg type="u" name="passkey" direction="out"/> |
621 | - </method> |
622 | - |
623 | - <method name="DisplayPasskey"> |
624 | - <annotation name="org.freedesktop.DBus.GLib.Async" value=""/> |
625 | - <arg type="o" name="device"/> |
626 | - <arg type="u" name="passkey"/> |
627 | - <arg type="q" name="entered"/> |
628 | - </method> |
629 | - |
630 | - <method name="RequestConfirmation"> |
631 | - <annotation name="org.freedesktop.DBus.GLib.Async" value=""/> |
632 | - <arg type="o" name="device"/> |
633 | - <arg type="u" name="passkey"/> |
634 | - </method> |
635 | - |
636 | - <method name="Cancel"> |
637 | - <annotation name="org.freedesktop.DBus.GLib.Async" value=""/> |
638 | - </method> |
639 | - |
640 | - <method name="Release"> |
641 | - <annotation name="org.freedesktop.DBus.GLib.Async" value=""/> |
642 | - </method> |
643 | - </interface> |
644 | -</node> |
645 | |
646 | === removed file 'plugins/bluetooth/agentadaptor.cpp' |
647 | --- plugins/bluetooth/agentadaptor.cpp 2015-02-04 10:48:47 +0000 |
648 | +++ plugins/bluetooth/agentadaptor.cpp 1970-01-01 00:00:00 +0000 |
649 | @@ -1,75 +0,0 @@ |
650 | -/* |
651 | - * This file was generated by qdbusxml2cpp version 0.8 |
652 | - * Command line was: qdbusxml2cpp agent.xml -a agentadaptor |
653 | - * |
654 | - * qdbusxml2cpp is Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). |
655 | - * |
656 | - * This is an auto-generated file. |
657 | - * Do not edit! All changes made to it will be lost. |
658 | - */ |
659 | - |
660 | -#include "agentadaptor.h" |
661 | -#include <QtCore/QMetaObject> |
662 | -#include <QtCore/QByteArray> |
663 | -#include <QtCore/QList> |
664 | -#include <QtCore/QMap> |
665 | -#include <QtCore/QString> |
666 | -#include <QtCore/QStringList> |
667 | -#include <QtCore/QVariant> |
668 | - |
669 | -/* |
670 | - * Implementation of adaptor class AgentAdaptor |
671 | - */ |
672 | - |
673 | -AgentAdaptor::AgentAdaptor(QObject *parent) |
674 | - : QDBusAbstractAdaptor(parent) |
675 | -{ |
676 | - // constructor |
677 | - setAutoRelaySignals(true); |
678 | -} |
679 | - |
680 | -AgentAdaptor::~AgentAdaptor() |
681 | -{ |
682 | - // destructor |
683 | -} |
684 | - |
685 | -void AgentAdaptor::Cancel() |
686 | -{ |
687 | - // handle method call org.bluez.Agent.Cancel |
688 | - QMetaObject::invokeMethod(parent(), "Cancel"); |
689 | -} |
690 | - |
691 | -void AgentAdaptor::DisplayPasskey(const QDBusObjectPath &device, uint passkey, ushort entered) |
692 | -{ |
693 | - // handle method call org.bluez.Agent.DisplayPasskey |
694 | - QMetaObject::invokeMethod(parent(), "DisplayPasskey", Q_ARG(QDBusObjectPath, device), Q_ARG(uint, passkey), Q_ARG(ushort, entered)); |
695 | -} |
696 | - |
697 | -void AgentAdaptor::Release() |
698 | -{ |
699 | - // handle method call org.bluez.Agent.Release |
700 | - QMetaObject::invokeMethod(parent(), "Release"); |
701 | -} |
702 | - |
703 | -void AgentAdaptor::RequestConfirmation(const QDBusObjectPath &device, uint passkey) |
704 | -{ |
705 | - // handle method call org.bluez.Agent.RequestConfirmation |
706 | - QMetaObject::invokeMethod(parent(), "RequestConfirmation", Q_ARG(QDBusObjectPath, device), Q_ARG(uint, passkey)); |
707 | -} |
708 | - |
709 | -uint AgentAdaptor::RequestPasskey(const QDBusObjectPath &device) |
710 | -{ |
711 | - // handle method call org.bluez.Agent.RequestPasskey |
712 | - uint passkey; |
713 | - QMetaObject::invokeMethod(parent(), "RequestPasskey", Q_RETURN_ARG(uint, passkey), Q_ARG(QDBusObjectPath, device)); |
714 | - return passkey; |
715 | -} |
716 | - |
717 | -QString AgentAdaptor::RequestPinCode(const QDBusObjectPath &device) |
718 | -{ |
719 | - // handle method call org.bluez.Agent.RequestPinCode |
720 | - QString pincode; |
721 | - QMetaObject::invokeMethod(parent(), "RequestPinCode", Q_RETURN_ARG(QString, pincode), Q_ARG(QDBusObjectPath, device)); |
722 | - return pincode; |
723 | -} |
724 | - |
725 | |
726 | === removed file 'plugins/bluetooth/agentadaptor.h' |
727 | --- plugins/bluetooth/agentadaptor.h 2015-02-04 10:48:47 +0000 |
728 | +++ plugins/bluetooth/agentadaptor.h 1970-01-01 00:00:00 +0000 |
729 | @@ -1,79 +0,0 @@ |
730 | -/* |
731 | - * This file was generated by qdbusxml2cpp version 0.8 |
732 | - * Command line was: qdbusxml2cpp agent.xml -a agentadaptor |
733 | - * |
734 | - * qdbusxml2cpp is Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). |
735 | - * |
736 | - * This is an auto-generated file. |
737 | - * This file may have been hand-edited. Look for HAND-EDIT comments |
738 | - * before re-generating it. |
739 | - */ |
740 | - |
741 | -#ifndef AGENTADAPTOR_H_1423046874 |
742 | -#define AGENTADAPTOR_H_1423046874 |
743 | - |
744 | -#include <QtCore/QObject> |
745 | -#include <QtDBus/QtDBus> |
746 | -QT_BEGIN_NAMESPACE |
747 | -class QByteArray; |
748 | -template<class T> class QList; |
749 | -template<class Key, class Value> class QMap; |
750 | -class QString; |
751 | -class QStringList; |
752 | -class QVariant; |
753 | -QT_END_NAMESPACE |
754 | - |
755 | -/* |
756 | - * Adaptor class for interface org.bluez.Agent |
757 | - */ |
758 | -class AgentAdaptor: public QDBusAbstractAdaptor |
759 | -{ |
760 | - Q_OBJECT |
761 | - Q_CLASSINFO("D-Bus Interface", "org.bluez.Agent") |
762 | - Q_CLASSINFO("D-Bus Introspection", "" |
763 | -" <interface name=\"org.bluez.Agent\">\n" |
764 | -" <method name=\"RequestPinCode\">\n" |
765 | -" <annotation value=\"\" name=\"org.freedesktop.DBus.GLib.Async\"/>\n" |
766 | -" <arg type=\"o\" name=\"device\"/>\n" |
767 | -" <arg direction=\"out\" type=\"s\" name=\"pincode\"/>\n" |
768 | -" </method>\n" |
769 | -" <method name=\"RequestPasskey\">\n" |
770 | -" <annotation value=\"\" name=\"org.freedesktop.DBus.GLib.Async\"/>\n" |
771 | -" <arg type=\"o\" name=\"device\"/>\n" |
772 | -" <arg direction=\"out\" type=\"u\" name=\"passkey\"/>\n" |
773 | -" </method>\n" |
774 | -" <method name=\"DisplayPasskey\">\n" |
775 | -" <annotation value=\"\" name=\"org.freedesktop.DBus.GLib.Async\"/>\n" |
776 | -" <arg type=\"o\" name=\"device\"/>\n" |
777 | -" <arg type=\"u\" name=\"passkey\"/>\n" |
778 | -" <arg type=\"q\" name=\"entered\"/>\n" |
779 | -" </method>\n" |
780 | -" <method name=\"RequestConfirmation\">\n" |
781 | -" <annotation value=\"\" name=\"org.freedesktop.DBus.GLib.Async\"/>\n" |
782 | -" <arg type=\"o\" name=\"device\"/>\n" |
783 | -" <arg type=\"u\" name=\"passkey\"/>\n" |
784 | -" </method>\n" |
785 | -" <method name=\"Cancel\">\n" |
786 | -" <annotation value=\"\" name=\"org.freedesktop.DBus.GLib.Async\"/>\n" |
787 | -" </method>\n" |
788 | -" <method name=\"Release\">\n" |
789 | -" <annotation value=\"\" name=\"org.freedesktop.DBus.GLib.Async\"/>\n" |
790 | -" </method>\n" |
791 | -" </interface>\n" |
792 | - "") |
793 | -public: |
794 | - AgentAdaptor(QObject *parent); |
795 | - virtual ~AgentAdaptor(); |
796 | - |
797 | -public: // PROPERTIES |
798 | -public Q_SLOTS: // METHODS |
799 | - void Cancel(); |
800 | - void DisplayPasskey(const QDBusObjectPath &device, uint passkey, ushort entered); |
801 | - void Release(); |
802 | - void RequestConfirmation(const QDBusObjectPath &device, uint passkey); |
803 | - uint RequestPasskey(const QDBusObjectPath &device); |
804 | - QString RequestPinCode(const QDBusObjectPath &device); |
805 | -Q_SIGNALS: // SIGNALS |
806 | -}; |
807 | - |
808 | -#endif |
809 | |
810 | === modified file 'plugins/bluetooth/bluetooth.cpp' |
811 | --- plugins/bluetooth/bluetooth.cpp 2015-08-28 09:32:38 +0000 |
812 | +++ plugins/bluetooth/bluetooth.cpp 2015-11-20 08:48:08 +0000 |
813 | @@ -23,7 +23,6 @@ |
814 | #include <QQmlEngine> |
815 | |
816 | #include "agent.h" |
817 | -#include "agentadaptor.h" |
818 | #include "dbus-shared.h" |
819 | |
820 | Bluetooth::Bluetooth(QObject *parent): |
821 | @@ -38,7 +37,7 @@ |
822 | m_agent(m_dbus, m_devices) |
823 | { |
824 | // export our Agent to handle pairing requests |
825 | - new AgentAdaptor(&m_agent); |
826 | + new BluezAgent1Adaptor(&m_agent); |
827 | if(!m_dbus.registerObject(DBUS_ADAPTER_AGENT_PATH, &m_agent)) |
828 | qCritical() << "Couldn't register agent at" << DBUS_ADAPTER_AGENT_PATH; |
829 | |
830 | @@ -63,6 +62,9 @@ |
831 | |
832 | QObject::connect(&m_devices, SIGNAL(discoverableChanged(bool)), |
833 | this, SIGNAL(discoverableChanged(bool))); |
834 | + |
835 | + QObject::connect(&m_devices, SIGNAL(devicePairingDone(Device*,bool)), |
836 | + this, SIGNAL(devicePairingDone(Device*,bool))); |
837 | } |
838 | |
839 | void Bluetooth::setSelectedDevice(const QString &address) |
840 | @@ -110,6 +112,7 @@ |
841 | case Device::Type::OtherAudio: |
842 | case Device::Type::Keyboard: |
843 | case Device::Type::Mouse: |
844 | + case Device::Type::Watch: |
845 | return true; |
846 | |
847 | default: |
848 | @@ -167,73 +170,38 @@ |
849 | |
850 | void Bluetooth::disconnectDevice() |
851 | { |
852 | - if (m_selectedDevice) { |
853 | - auto type = m_selectedDevice->getType(); |
854 | - switch ((Device::Type)type) { |
855 | - case Device::Type::Headset: |
856 | - case Device::Type::Headphones: |
857 | - case Device::Type::OtherAudio: |
858 | - case Device::Type::Speakers: |
859 | - case Device::Type::Carkit: |
860 | - m_selectedDevice->disconnect(Device::ConnectionMode::Audio); |
861 | - break; |
862 | - case Device::Type::Keyboard: |
863 | - case Device::Type::Mouse: |
864 | - m_selectedDevice->disconnect(Device::ConnectionMode::Input); |
865 | - break; |
866 | - default: |
867 | - qWarning() << "Nothing to disconnect: Unsupported device type."; |
868 | - break; |
869 | - } |
870 | - } else { |
871 | - qWarning() << "No selected device to disconnect"; |
872 | - } |
873 | + if (!m_selectedDevice) |
874 | + return; |
875 | + |
876 | + m_selectedDevice->disconnect(); |
877 | } |
878 | |
879 | void Bluetooth::connectDevice(const QString &address) |
880 | { |
881 | - Device::ConnectionMode connMode; |
882 | auto device = m_devices.getDeviceFromAddress(address); |
883 | - Device::Type type; |
884 | |
885 | if (!device) { |
886 | qWarning() << "No device to connect."; |
887 | return; |
888 | } |
889 | |
890 | - type = device->getType(); |
891 | - switch (type) { |
892 | - case Device::Type::Headset: |
893 | - case Device::Type::Headphones: |
894 | - case Device::Type::OtherAudio: |
895 | - case Device::Type::Speakers: |
896 | - case Device::Type::Carkit: |
897 | - connMode = Device::ConnectionMode::Audio; |
898 | - break; |
899 | - case Device::Type::Keyboard: |
900 | - case Device::Type::Mouse: |
901 | - connMode = Device::ConnectionMode::Input; |
902 | - break; |
903 | - default: |
904 | - qWarning() << "Nothing to connect: Unsupported device type."; |
905 | - return; |
906 | + if (!device->isPaired()) { |
907 | + device->setConnectAfterPairing(true); |
908 | + device->pair(); |
909 | } |
910 | - |
911 | - if (device->isTrusted()) { |
912 | - device->connect(connMode); |
913 | - } else { |
914 | - m_devices.addConnectAfterPairing(address, connMode); |
915 | - m_devices.createDevice(address, &m_agent); |
916 | + else { |
917 | + device->connect(); |
918 | } |
919 | } |
920 | |
921 | void Bluetooth::removeDevice() |
922 | { |
923 | - if (m_selectedDevice) { |
924 | - QString path = m_selectedDevice->getPath(); |
925 | - m_devices.removeDevice(path); |
926 | - } else { |
927 | + if (!m_selectedDevice) { |
928 | qWarning() << "No selected device to remove."; |
929 | + return; |
930 | } |
931 | + |
932 | + QString path = m_selectedDevice->getPath(); |
933 | + m_devices.removeDevice(path); |
934 | } |
935 | |
936 | |
937 | === modified file 'plugins/bluetooth/bluetooth.h' |
938 | --- plugins/bluetooth/bluetooth.h 2015-08-28 09:32:38 +0000 |
939 | +++ plugins/bluetooth/bluetooth.h 2015-11-20 08:48:08 +0000 |
940 | @@ -24,9 +24,10 @@ |
941 | #include <QObject> |
942 | |
943 | #include "agent.h" |
944 | -#include "agentadaptor.h" |
945 | #include "devicemodel.h" |
946 | |
947 | +#include "bluez_agent1adaptor.h" |
948 | + |
949 | class Bluetooth : public QObject |
950 | { |
951 | Q_OBJECT |
952 | @@ -68,6 +69,7 @@ |
953 | void poweredChanged(bool powered); |
954 | void discoveringChanged(bool isActive); |
955 | void discoverableChanged(bool isActive); |
956 | + void devicePairingDone(Device *device, bool success); |
957 | |
958 | public: |
959 | explicit Bluetooth(QObject *parent = nullptr); |
960 | |
961 | === added file 'plugins/bluetooth/bluez_adapter1.cpp' |
962 | --- plugins/bluetooth/bluez_adapter1.cpp 1970-01-01 00:00:00 +0000 |
963 | +++ plugins/bluetooth/bluez_adapter1.cpp 2015-11-20 08:48:08 +0000 |
964 | @@ -0,0 +1,26 @@ |
965 | +/* |
966 | + * This file was generated by qdbusxml2cpp version 0.8 |
967 | + * Command line was: qdbusxml2cpp -c BluezAdapter1 -p bluez_adapter1 -v org.bluez.Adapter1.xml |
968 | + * |
969 | + * qdbusxml2cpp is Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies). |
970 | + * |
971 | + * This is an auto-generated file. |
972 | + * This file may have been hand-edited. Look for HAND-EDIT comments |
973 | + * before re-generating it. |
974 | + */ |
975 | + |
976 | +#include "bluez_adapter1.h" |
977 | + |
978 | +/* |
979 | + * Implementation of interface class BluezAdapter1 |
980 | + */ |
981 | + |
982 | +BluezAdapter1::BluezAdapter1(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent) |
983 | + : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent) |
984 | +{ |
985 | +} |
986 | + |
987 | +BluezAdapter1::~BluezAdapter1() |
988 | +{ |
989 | +} |
990 | + |
991 | |
992 | === added file 'plugins/bluetooth/bluez_adapter1.h' |
993 | --- plugins/bluetooth/bluez_adapter1.h 1970-01-01 00:00:00 +0000 |
994 | +++ plugins/bluetooth/bluez_adapter1.h 2015-11-20 08:48:08 +0000 |
995 | @@ -0,0 +1,66 @@ |
996 | +/* |
997 | + * This file was generated by qdbusxml2cpp version 0.8 |
998 | + * Command line was: qdbusxml2cpp -c BluezAdapter1 -p bluez_adapter1 -v org.bluez.Adapter1.xml |
999 | + * |
1000 | + * qdbusxml2cpp is Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies). |
1001 | + * |
1002 | + * This is an auto-generated file. |
1003 | + * Do not edit! All changes made to it will be lost. |
1004 | + */ |
1005 | + |
1006 | +#ifndef BLUEZ_ADAPTER1_H_1442480417 |
1007 | +#define BLUEZ_ADAPTER1_H_1442480417 |
1008 | + |
1009 | +#include <QtCore/QObject> |
1010 | +#include <QtCore/QByteArray> |
1011 | +#include <QtCore/QList> |
1012 | +#include <QtCore/QMap> |
1013 | +#include <QtCore/QString> |
1014 | +#include <QtCore/QStringList> |
1015 | +#include <QtCore/QVariant> |
1016 | +#include <QtDBus/QtDBus> |
1017 | + |
1018 | +/* |
1019 | + * Proxy class for interface org.bluez.Adapter1 |
1020 | + */ |
1021 | +class BluezAdapter1: public QDBusAbstractInterface |
1022 | +{ |
1023 | + Q_OBJECT |
1024 | +public: |
1025 | + static inline const char *staticInterfaceName() |
1026 | + { return "org.bluez.Adapter1"; } |
1027 | + |
1028 | +public: |
1029 | + BluezAdapter1(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0); |
1030 | + |
1031 | + ~BluezAdapter1(); |
1032 | + |
1033 | +public Q_SLOTS: // METHODS |
1034 | + inline QDBusPendingReply<> RemoveDevice(const QDBusObjectPath &device) |
1035 | + { |
1036 | + QList<QVariant> argumentList; |
1037 | + argumentList << QVariant::fromValue(device); |
1038 | + return asyncCallWithArgumentList(QStringLiteral("RemoveDevice"), argumentList); |
1039 | + } |
1040 | + |
1041 | + inline QDBusPendingReply<> StartDiscovery() |
1042 | + { |
1043 | + QList<QVariant> argumentList; |
1044 | + return asyncCallWithArgumentList(QStringLiteral("StartDiscovery"), argumentList); |
1045 | + } |
1046 | + |
1047 | + inline QDBusPendingReply<> StopDiscovery() |
1048 | + { |
1049 | + QList<QVariant> argumentList; |
1050 | + return asyncCallWithArgumentList(QStringLiteral("StopDiscovery"), argumentList); |
1051 | + } |
1052 | + |
1053 | +Q_SIGNALS: // SIGNALS |
1054 | +}; |
1055 | + |
1056 | +namespace org { |
1057 | + namespace bluez { |
1058 | + typedef ::BluezAdapter1 Adapter1; |
1059 | + } |
1060 | +} |
1061 | +#endif |
1062 | |
1063 | === added file 'plugins/bluetooth/bluez_agent1adaptor.cpp' |
1064 | --- plugins/bluetooth/bluez_agent1adaptor.cpp 1970-01-01 00:00:00 +0000 |
1065 | +++ plugins/bluetooth/bluez_agent1adaptor.cpp 2015-11-20 08:48:08 +0000 |
1066 | @@ -0,0 +1,93 @@ |
1067 | +/* |
1068 | + * This file was generated by qdbusxml2cpp version 0.8 |
1069 | + * Command line was: qdbusxml2cpp -a bluez_agent1adaptor -c BluezAgent1Adaptor org.bluez.Agent1.xml |
1070 | + * |
1071 | + * qdbusxml2cpp is Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies). |
1072 | + * |
1073 | + * This is an auto-generated file. |
1074 | + * Do not edit! All changes made to it will be lost. |
1075 | + */ |
1076 | + |
1077 | +#include "bluez_agent1adaptor.h" |
1078 | +#include <QtCore/QMetaObject> |
1079 | +#include <QtCore/QByteArray> |
1080 | +#include <QtCore/QList> |
1081 | +#include <QtCore/QMap> |
1082 | +#include <QtCore/QString> |
1083 | +#include <QtCore/QStringList> |
1084 | +#include <QtCore/QVariant> |
1085 | + |
1086 | +/* |
1087 | + * Implementation of adaptor class BluezAgent1Adaptor |
1088 | + */ |
1089 | + |
1090 | +BluezAgent1Adaptor::BluezAgent1Adaptor(QObject *parent) |
1091 | + : QDBusAbstractAdaptor(parent) |
1092 | +{ |
1093 | + // constructor |
1094 | + setAutoRelaySignals(true); |
1095 | +} |
1096 | + |
1097 | +BluezAgent1Adaptor::~BluezAgent1Adaptor() |
1098 | +{ |
1099 | + // destructor |
1100 | +} |
1101 | + |
1102 | +void BluezAgent1Adaptor::AuthorizeService(const QDBusObjectPath &device, const QString &uuid) |
1103 | +{ |
1104 | + // handle method call org.bluez.Agent1.AuthorizeService |
1105 | + QMetaObject::invokeMethod(parent(), "AuthorizeService", Q_ARG(QDBusObjectPath, device), Q_ARG(QString, uuid)); |
1106 | +} |
1107 | + |
1108 | +void BluezAgent1Adaptor::Cancel() |
1109 | +{ |
1110 | + // handle method call org.bluez.Agent1.Cancel |
1111 | + QMetaObject::invokeMethod(parent(), "Cancel"); |
1112 | +} |
1113 | + |
1114 | +void BluezAgent1Adaptor::DisplayPasskey(const QDBusObjectPath &device, uint passkey, ushort entered) |
1115 | +{ |
1116 | + // handle method call org.bluez.Agent1.DisplayPasskey |
1117 | + QMetaObject::invokeMethod(parent(), "DisplayPasskey", Q_ARG(QDBusObjectPath, device), Q_ARG(uint, passkey), Q_ARG(ushort, entered)); |
1118 | +} |
1119 | + |
1120 | +void BluezAgent1Adaptor::DisplayPinCode(const QDBusObjectPath &device, const QString &pincode) |
1121 | +{ |
1122 | + // handle method call org.bluez.Agent1.DisplayPinCode |
1123 | + QMetaObject::invokeMethod(parent(), "DisplayPinCode", Q_ARG(QDBusObjectPath, device), Q_ARG(QString, pincode)); |
1124 | +} |
1125 | + |
1126 | +void BluezAgent1Adaptor::Release() |
1127 | +{ |
1128 | + // handle method call org.bluez.Agent1.Release |
1129 | + QMetaObject::invokeMethod(parent(), "Release"); |
1130 | +} |
1131 | + |
1132 | +void BluezAgent1Adaptor::RequestAuthorization(const QDBusObjectPath &device) |
1133 | +{ |
1134 | + // handle method call org.bluez.Agent1.RequestAuthorization |
1135 | + QMetaObject::invokeMethod(parent(), "RequestAuthorization", Q_ARG(QDBusObjectPath, device)); |
1136 | +} |
1137 | + |
1138 | +void BluezAgent1Adaptor::RequestConfirmation(const QDBusObjectPath &device, uint passkey) |
1139 | +{ |
1140 | + // handle method call org.bluez.Agent1.RequestConfirmation |
1141 | + QMetaObject::invokeMethod(parent(), "RequestConfirmation", Q_ARG(QDBusObjectPath, device), Q_ARG(uint, passkey)); |
1142 | +} |
1143 | + |
1144 | +uint BluezAgent1Adaptor::RequestPasskey(const QDBusObjectPath &device) |
1145 | +{ |
1146 | + // handle method call org.bluez.Agent1.RequestPasskey |
1147 | + uint passkey; |
1148 | + QMetaObject::invokeMethod(parent(), "RequestPasskey", Q_RETURN_ARG(uint, passkey), Q_ARG(QDBusObjectPath, device)); |
1149 | + return passkey; |
1150 | +} |
1151 | + |
1152 | +QString BluezAgent1Adaptor::RequestPinCode(const QDBusObjectPath &device) |
1153 | +{ |
1154 | + // handle method call org.bluez.Agent1.RequestPinCode |
1155 | + QString pincode; |
1156 | + QMetaObject::invokeMethod(parent(), "RequestPinCode", Q_RETURN_ARG(QString, pincode), Q_ARG(QDBusObjectPath, device)); |
1157 | + return pincode; |
1158 | +} |
1159 | + |
1160 | |
1161 | === added file 'plugins/bluetooth/bluez_agent1adaptor.h' |
1162 | --- plugins/bluetooth/bluez_agent1adaptor.h 1970-01-01 00:00:00 +0000 |
1163 | +++ plugins/bluetooth/bluez_agent1adaptor.h 2015-11-20 08:48:08 +0000 |
1164 | @@ -0,0 +1,96 @@ |
1165 | +/* |
1166 | + * This file was generated by qdbusxml2cpp version 0.8 |
1167 | + * Command line was: qdbusxml2cpp -a bluez_agent1adaptor -c BluezAgent1Adaptor org.bluez.Agent1.xml |
1168 | + * |
1169 | + * qdbusxml2cpp is Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies). |
1170 | + * |
1171 | + * This is an auto-generated file. |
1172 | + * This file may have been hand-edited. Look for HAND-EDIT comments |
1173 | + * before re-generating it. |
1174 | + */ |
1175 | + |
1176 | +#ifndef BLUEZ_AGENT1ADAPTOR_H_1442560744 |
1177 | +#define BLUEZ_AGENT1ADAPTOR_H_1442560744 |
1178 | + |
1179 | +#include <QtCore/QObject> |
1180 | +#include <QtDBus/QtDBus> |
1181 | +QT_BEGIN_NAMESPACE |
1182 | +class QByteArray; |
1183 | +template<class T> class QList; |
1184 | +template<class Key, class Value> class QMap; |
1185 | +class QString; |
1186 | +class QStringList; |
1187 | +class QVariant; |
1188 | +QT_END_NAMESPACE |
1189 | + |
1190 | +/* |
1191 | + * Adaptor class for interface org.bluez.Agent1 |
1192 | + */ |
1193 | +class BluezAgent1Adaptor: public QDBusAbstractAdaptor |
1194 | +{ |
1195 | + Q_OBJECT |
1196 | + Q_CLASSINFO("D-Bus Interface", "org.bluez.Agent1") |
1197 | + Q_CLASSINFO("D-Bus Introspection", "" |
1198 | +" <interface name=\"org.bluez.Agent1\">\n" |
1199 | +" <method name=\"RequestPinCode\">\n" |
1200 | +" <annotation value=\"\" name=\"org.freedesktop.DBus.GLib.Async\"/>\n" |
1201 | +" <arg type=\"o\" name=\"device\"/>\n" |
1202 | +" <arg direction=\"out\" type=\"s\" name=\"pincode\"/>\n" |
1203 | +" </method>\n" |
1204 | +" <method name=\"DisplayPinCode\">\n" |
1205 | +" <annotation value=\"\" name=\"org.freedesktop.DBus.GLib.Async\"/>\n" |
1206 | +" <arg type=\"o\" name=\"device\"/>\n" |
1207 | +" <arg type=\"s\" name=\"pincode\"/>\n" |
1208 | +" </method>\n" |
1209 | +" <method name=\"RequestPasskey\">\n" |
1210 | +" <annotation value=\"\" name=\"org.freedesktop.DBus.GLib.Async\"/>\n" |
1211 | +" <arg type=\"o\" name=\"device\"/>\n" |
1212 | +" <arg direction=\"out\" type=\"u\" name=\"passkey\"/>\n" |
1213 | +" </method>\n" |
1214 | +" <method name=\"DisplayPasskey\">\n" |
1215 | +" <annotation value=\"\" name=\"org.freedesktop.DBus.GLib.Async\"/>\n" |
1216 | +" <arg type=\"o\" name=\"device\"/>\n" |
1217 | +" <arg type=\"u\" name=\"passkey\"/>\n" |
1218 | +" <arg type=\"q\" name=\"entered\"/>\n" |
1219 | +" </method>\n" |
1220 | +" <method name=\"RequestConfirmation\">\n" |
1221 | +" <annotation value=\"\" name=\"org.freedesktop.DBus.GLib.Async\"/>\n" |
1222 | +" <arg type=\"o\" name=\"device\"/>\n" |
1223 | +" <arg type=\"u\" name=\"passkey\"/>\n" |
1224 | +" </method>\n" |
1225 | +" <method name=\"RequestAuthorization\">\n" |
1226 | +" <annotation value=\"\" name=\"org.freedesktop.DBus.GLib.Async\"/>\n" |
1227 | +" <arg type=\"o\" name=\"device\"/>\n" |
1228 | +" </method>\n" |
1229 | +" <method name=\"AuthorizeService\">\n" |
1230 | +" <annotation value=\"\" name=\"org.freedesktop.DBus.GLib.Async\"/>\n" |
1231 | +" <arg type=\"o\" name=\"device\"/>\n" |
1232 | +" <arg type=\"s\" name=\"uuid\"/>\n" |
1233 | +" </method>\n" |
1234 | +" <method name=\"Cancel\">\n" |
1235 | +" <annotation value=\"\" name=\"org.freedesktop.DBus.GLib.Async\"/>\n" |
1236 | +" </method>\n" |
1237 | +" <method name=\"Release\">\n" |
1238 | +" <annotation value=\"\" name=\"org.freedesktop.DBus.GLib.Async\"/>\n" |
1239 | +" </method>\n" |
1240 | +" </interface>\n" |
1241 | + "") |
1242 | +public: |
1243 | + BluezAgent1Adaptor(QObject *parent); |
1244 | + virtual ~BluezAgent1Adaptor(); |
1245 | + |
1246 | +public: // PROPERTIES |
1247 | +public Q_SLOTS: // METHODS |
1248 | + void AuthorizeService(const QDBusObjectPath &device, const QString &uuid); |
1249 | + void Cancel(); |
1250 | + void DisplayPasskey(const QDBusObjectPath &device, uint passkey, ushort entered); |
1251 | + void DisplayPinCode(const QDBusObjectPath &device, const QString &pincode); |
1252 | + void Release(); |
1253 | + void RequestAuthorization(const QDBusObjectPath &device); |
1254 | + void RequestConfirmation(const QDBusObjectPath &device, uint passkey); |
1255 | + uint RequestPasskey(const QDBusObjectPath &device); |
1256 | + QString RequestPinCode(const QDBusObjectPath &device); |
1257 | +Q_SIGNALS: // SIGNALS |
1258 | +}; |
1259 | + |
1260 | +#endif |
1261 | |
1262 | === added file 'plugins/bluetooth/bluez_agentmanager1.cpp' |
1263 | --- plugins/bluetooth/bluez_agentmanager1.cpp 1970-01-01 00:00:00 +0000 |
1264 | +++ plugins/bluetooth/bluez_agentmanager1.cpp 2015-11-20 08:48:08 +0000 |
1265 | @@ -0,0 +1,26 @@ |
1266 | +/* |
1267 | + * This file was generated by qdbusxml2cpp version 0.8 |
1268 | + * Command line was: qdbusxml2cpp -c BluezAgentManager1 -p bluez_agentmanager1 org.bluez.AgentManager1.xml |
1269 | + * |
1270 | + * qdbusxml2cpp is Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies). |
1271 | + * |
1272 | + * This is an auto-generated file. |
1273 | + * This file may have been hand-edited. Look for HAND-EDIT comments |
1274 | + * before re-generating it. |
1275 | + */ |
1276 | + |
1277 | +#include "bluez_agentmanager1.h" |
1278 | + |
1279 | +/* |
1280 | + * Implementation of interface class BluezAgentManager1 |
1281 | + */ |
1282 | + |
1283 | +BluezAgentManager1::BluezAgentManager1(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent) |
1284 | + : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent) |
1285 | +{ |
1286 | +} |
1287 | + |
1288 | +BluezAgentManager1::~BluezAgentManager1() |
1289 | +{ |
1290 | +} |
1291 | + |
1292 | |
1293 | === added file 'plugins/bluetooth/bluez_agentmanager1.h' |
1294 | --- plugins/bluetooth/bluez_agentmanager1.h 1970-01-01 00:00:00 +0000 |
1295 | +++ plugins/bluetooth/bluez_agentmanager1.h 2015-11-20 08:48:08 +0000 |
1296 | @@ -0,0 +1,68 @@ |
1297 | +/* |
1298 | + * This file was generated by qdbusxml2cpp version 0.8 |
1299 | + * Command line was: qdbusxml2cpp -c BluezAgentManager1 -p bluez_agentmanager1 org.bluez.AgentManager1.xml |
1300 | + * |
1301 | + * qdbusxml2cpp is Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies). |
1302 | + * |
1303 | + * This is an auto-generated file. |
1304 | + * Do not edit! All changes made to it will be lost. |
1305 | + */ |
1306 | + |
1307 | +#ifndef BLUEZ_AGENTMANAGER1_H_1442489332 |
1308 | +#define BLUEZ_AGENTMANAGER1_H_1442489332 |
1309 | + |
1310 | +#include <QtCore/QObject> |
1311 | +#include <QtCore/QByteArray> |
1312 | +#include <QtCore/QList> |
1313 | +#include <QtCore/QMap> |
1314 | +#include <QtCore/QString> |
1315 | +#include <QtCore/QStringList> |
1316 | +#include <QtCore/QVariant> |
1317 | +#include <QtDBus/QtDBus> |
1318 | + |
1319 | +/* |
1320 | + * Proxy class for interface org.bluez.AgentManager1 |
1321 | + */ |
1322 | +class BluezAgentManager1: public QDBusAbstractInterface |
1323 | +{ |
1324 | + Q_OBJECT |
1325 | +public: |
1326 | + static inline const char *staticInterfaceName() |
1327 | + { return "org.bluez.AgentManager1"; } |
1328 | + |
1329 | +public: |
1330 | + BluezAgentManager1(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0); |
1331 | + |
1332 | + ~BluezAgentManager1(); |
1333 | + |
1334 | +public Q_SLOTS: // METHODS |
1335 | + inline QDBusPendingReply<> RegisterAgent(const QDBusObjectPath &agent, const QString &capability) |
1336 | + { |
1337 | + QList<QVariant> argumentList; |
1338 | + argumentList << QVariant::fromValue(agent) << QVariant::fromValue(capability); |
1339 | + return asyncCallWithArgumentList(QStringLiteral("RegisterAgent"), argumentList); |
1340 | + } |
1341 | + |
1342 | + inline QDBusPendingReply<> RequestDefaultAgent(const QDBusObjectPath &agent) |
1343 | + { |
1344 | + QList<QVariant> argumentList; |
1345 | + argumentList << QVariant::fromValue(agent); |
1346 | + return asyncCallWithArgumentList(QStringLiteral("RequestDefaultAgent"), argumentList); |
1347 | + } |
1348 | + |
1349 | + inline QDBusPendingReply<> UnregisterAgent(const QDBusObjectPath &agent) |
1350 | + { |
1351 | + QList<QVariant> argumentList; |
1352 | + argumentList << QVariant::fromValue(agent); |
1353 | + return asyncCallWithArgumentList(QStringLiteral("UnregisterAgent"), argumentList); |
1354 | + } |
1355 | + |
1356 | +Q_SIGNALS: // SIGNALS |
1357 | +}; |
1358 | + |
1359 | +namespace org { |
1360 | + namespace bluez { |
1361 | + typedef ::BluezAgentManager1 AgentManager1; |
1362 | + } |
1363 | +} |
1364 | +#endif |
1365 | |
1366 | === added file 'plugins/bluetooth/bluez_device1.cpp' |
1367 | --- plugins/bluetooth/bluez_device1.cpp 1970-01-01 00:00:00 +0000 |
1368 | +++ plugins/bluetooth/bluez_device1.cpp 2015-11-20 08:48:08 +0000 |
1369 | @@ -0,0 +1,26 @@ |
1370 | +/* |
1371 | + * This file was generated by qdbusxml2cpp version 0.8 |
1372 | + * Command line was: qdbusxml2cpp -c BluezDevice1 -p bluez_device1 org.bluez.Device1.xml |
1373 | + * |
1374 | + * qdbusxml2cpp is Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies). |
1375 | + * |
1376 | + * This is an auto-generated file. |
1377 | + * This file may have been hand-edited. Look for HAND-EDIT comments |
1378 | + * before re-generating it. |
1379 | + */ |
1380 | + |
1381 | +#include "bluez_device1.h" |
1382 | + |
1383 | +/* |
1384 | + * Implementation of interface class BluezDevice1 |
1385 | + */ |
1386 | + |
1387 | +BluezDevice1::BluezDevice1(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent) |
1388 | + : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent) |
1389 | +{ |
1390 | +} |
1391 | + |
1392 | +BluezDevice1::~BluezDevice1() |
1393 | +{ |
1394 | +} |
1395 | + |
1396 | |
1397 | === added file 'plugins/bluetooth/bluez_device1.h' |
1398 | --- plugins/bluetooth/bluez_device1.h 1970-01-01 00:00:00 +0000 |
1399 | +++ plugins/bluetooth/bluez_device1.h 2015-11-20 08:48:08 +0000 |
1400 | @@ -0,0 +1,85 @@ |
1401 | +/* |
1402 | + * This file was generated by qdbusxml2cpp version 0.8 |
1403 | + * Command line was: qdbusxml2cpp -c BluezDevice1 -p bluez_device1 org.bluez.Device1.xml |
1404 | + * |
1405 | + * qdbusxml2cpp is Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies). |
1406 | + * |
1407 | + * This is an auto-generated file. |
1408 | + * Do not edit! All changes made to it will be lost. |
1409 | + */ |
1410 | + |
1411 | +#ifndef BLUEZ_DEVICE1_H_1442480478 |
1412 | +#define BLUEZ_DEVICE1_H_1442480478 |
1413 | + |
1414 | +#include <QtCore/QObject> |
1415 | +#include <QtCore/QByteArray> |
1416 | +#include <QtCore/QList> |
1417 | +#include <QtCore/QMap> |
1418 | +#include <QtCore/QString> |
1419 | +#include <QtCore/QStringList> |
1420 | +#include <QtCore/QVariant> |
1421 | +#include <QtDBus/QtDBus> |
1422 | + |
1423 | +/* |
1424 | + * Proxy class for interface org.bluez.Device1 |
1425 | + */ |
1426 | +class BluezDevice1: public QDBusAbstractInterface |
1427 | +{ |
1428 | + Q_OBJECT |
1429 | +public: |
1430 | + static inline const char *staticInterfaceName() |
1431 | + { return "org.bluez.Device1"; } |
1432 | + |
1433 | +public: |
1434 | + BluezDevice1(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0); |
1435 | + |
1436 | + ~BluezDevice1(); |
1437 | + |
1438 | +public Q_SLOTS: // METHODS |
1439 | + inline QDBusPendingReply<> CancelPairing() |
1440 | + { |
1441 | + QList<QVariant> argumentList; |
1442 | + return asyncCallWithArgumentList(QStringLiteral("CancelPairing"), argumentList); |
1443 | + } |
1444 | + |
1445 | + inline QDBusPendingReply<> Connect() |
1446 | + { |
1447 | + QList<QVariant> argumentList; |
1448 | + return asyncCallWithArgumentList(QStringLiteral("Connect"), argumentList); |
1449 | + } |
1450 | + |
1451 | + inline QDBusPendingReply<> ConnectProfile(const QString &UUID) |
1452 | + { |
1453 | + QList<QVariant> argumentList; |
1454 | + argumentList << QVariant::fromValue(UUID); |
1455 | + return asyncCallWithArgumentList(QStringLiteral("ConnectProfile"), argumentList); |
1456 | + } |
1457 | + |
1458 | + inline QDBusPendingReply<> Disconnect() |
1459 | + { |
1460 | + QList<QVariant> argumentList; |
1461 | + return asyncCallWithArgumentList(QStringLiteral("Disconnect"), argumentList); |
1462 | + } |
1463 | + |
1464 | + inline QDBusPendingReply<> DisconnectProfile(const QString &UUID) |
1465 | + { |
1466 | + QList<QVariant> argumentList; |
1467 | + argumentList << QVariant::fromValue(UUID); |
1468 | + return asyncCallWithArgumentList(QStringLiteral("DisconnectProfile"), argumentList); |
1469 | + } |
1470 | + |
1471 | + inline QDBusPendingReply<> Pair() |
1472 | + { |
1473 | + QList<QVariant> argumentList; |
1474 | + return asyncCallWithArgumentList(QStringLiteral("Pair"), argumentList); |
1475 | + } |
1476 | + |
1477 | +Q_SIGNALS: // SIGNALS |
1478 | +}; |
1479 | + |
1480 | +namespace org { |
1481 | + namespace bluez { |
1482 | + typedef ::BluezDevice1 Device1; |
1483 | + } |
1484 | +} |
1485 | +#endif |
1486 | |
1487 | === added file 'plugins/bluetooth/bluez_helper.h' |
1488 | --- plugins/bluetooth/bluez_helper.h 1970-01-01 00:00:00 +0000 |
1489 | +++ plugins/bluetooth/bluez_helper.h 2015-11-20 08:48:08 +0000 |
1490 | @@ -0,0 +1,29 @@ |
1491 | +/* |
1492 | + * Copyright (C) 2015 Canonical Ltd |
1493 | + * |
1494 | + * This program is free software: you can redistribute it and/or modify |
1495 | + * it under the terms of the GNU General Public License version 3 as |
1496 | + * published by the Free Software Foundation. |
1497 | + * |
1498 | + * This program is distributed in the hope that it will be useful, |
1499 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1500 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1501 | + * GNU General Public License for more details. |
1502 | + * |
1503 | + * You should have received a copy of the GNU General Public License |
1504 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1505 | + * |
1506 | +*/ |
1507 | + |
1508 | +#ifndef BLUEZ_HELPER_H_ |
1509 | +#define BLUEZ_HELPER_H_ |
1510 | + |
1511 | +#include <QObject> |
1512 | + |
1513 | +typedef QMap<QString, QVariantMap> InterfaceList; |
1514 | +typedef QMap<QDBusObjectPath, InterfaceList> ManagedObjectList; |
1515 | + |
1516 | +Q_DECLARE_METATYPE(InterfaceList) |
1517 | +Q_DECLARE_METATYPE(ManagedObjectList) |
1518 | + |
1519 | +#endif |
1520 | |
1521 | === modified file 'plugins/bluetooth/dbus-shared.h' |
1522 | --- plugins/bluetooth/dbus-shared.h 2015-08-28 09:32:38 +0000 |
1523 | +++ plugins/bluetooth/dbus-shared.h 2015-11-20 08:48:08 +0000 |
1524 | @@ -24,4 +24,13 @@ |
1525 | #define DBUS_ADAPTER_AGENT_PATH "/com/canonical/SettingsBluetoothAgent/adapteragent" |
1526 | #define DBUS_AGENT_CAPABILITY "KeyboardDisplay" |
1527 | |
1528 | +#define BLUEZ_SERVICE "org.bluez" |
1529 | + |
1530 | +#define BLUEZ_ADAPTER_IFACE "org.bluez.Adapter1" |
1531 | +#define BLUEZ_DEVICE_IFACE "org.bluez.Device1" |
1532 | + |
1533 | +#define watchCall(call, func) \ |
1534 | + QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(call, this); \ |
1535 | + QObject::connect(watcher, &QDBusPendingCallWatcher::finished, func) |
1536 | + |
1537 | #endif // USS_DBUS_SHARED_H |
1538 | |
1539 | === modified file 'plugins/bluetooth/device.cpp' |
1540 | --- plugins/bluetooth/device.cpp 2015-08-28 09:32:38 +0000 |
1541 | +++ plugins/bluetooth/device.cpp 2015-11-20 08:48:08 +0000 |
1542 | @@ -26,16 +26,8 @@ |
1543 | |
1544 | #include "dbus-shared.h" |
1545 | |
1546 | -/*** |
1547 | -**** |
1548 | -***/ |
1549 | - |
1550 | -Device::Device(const QMap<QString,QVariant> &properties) |
1551 | -{ |
1552 | - setProperties(properties); |
1553 | -} |
1554 | - |
1555 | -Device::Device(const QString &path, QDBusConnection &bus) |
1556 | +Device::Device(const QString &path, QDBusConnection &bus) : |
1557 | + m_strength(Device::None) |
1558 | { |
1559 | initDevice(path, bus); |
1560 | } |
1561 | @@ -53,53 +45,44 @@ |
1562 | QObject::connect(this, SIGNAL(connectionChanged()), this, SIGNAL(deviceChanged())); |
1563 | QObject::connect(this, SIGNAL(strengthChanged()), this, SIGNAL(deviceChanged())); |
1564 | |
1565 | - // init the interfaces that we're supporting. |
1566 | - initInterface(m_deviceInterface, path, "org.bluez.Device", bus); |
1567 | - initInterface(m_audioInterface, path, "org.bluez.Audio", bus); |
1568 | - initInterface(m_audioSourceInterface, path, "org.bluez.AudioSource", bus); |
1569 | - initInterface(m_audioSinkInterface, path, "org.bluez.AudioSink", bus); |
1570 | - initInterface(m_headsetInterface, path, "org.bluez.Headset", bus); |
1571 | - initInterface(m_inputInterface, path, "org.bluez.Input", bus); |
1572 | + m_bluezDevice.reset(new BluezDevice1(BLUEZ_SERVICE, path, bus)); |
1573 | + /* Give our calls a bit more time than the default 25 seconds to |
1574 | + * complete whatever they are doing. In some situations (e.g. with |
1575 | + * specific devices) the default doesn't seem to be enough to. */ |
1576 | + m_bluezDevice->setTimeout(60 * 1000 /* 60 seconds */); |
1577 | + |
1578 | + m_bluezDeviceProperties.reset(new FreeDesktopProperties(BLUEZ_SERVICE, path, bus)); |
1579 | + |
1580 | + QObject::connect(m_bluezDeviceProperties.data(), SIGNAL(PropertiesChanged(const QString&, const QVariantMap&, const QStringList&)), |
1581 | + this, SLOT(slotPropertiesChanged(const QString&, const QVariantMap&, const QStringList&))); |
1582 | |
1583 | Q_EMIT(pathChanged()); |
1584 | -} |
1585 | - |
1586 | -/*** |
1587 | -**** |
1588 | -***/ |
1589 | - |
1590 | -void Device::slotPropertyChanged(const QString &key, |
1591 | - const QDBusVariant &value) |
1592 | -{ |
1593 | - updateProperty (key, value.variant()); |
1594 | -} |
1595 | - |
1596 | -void Device::initInterface(QSharedPointer<QDBusInterface> &setme, |
1597 | - const QString &path, |
1598 | - const QString &interfaceName, |
1599 | - QDBusConnection &bus) |
1600 | -{ |
1601 | - const QString service = "org.bluez"; |
1602 | - |
1603 | - auto i = new QDBusInterface(service, path, interfaceName, bus); |
1604 | - |
1605 | - if (!i->isValid()) { |
1606 | - delete i; |
1607 | - i = 0; |
1608 | - qWarning() << "Couldn't add proxy for" << interfaceName; |
1609 | - } else { |
1610 | - if (!bus.connect(service, path, interfaceName, "PropertyChanged", |
1611 | - this, SLOT(slotPropertyChanged(const QString&, const QDBusVariant&)))) |
1612 | - qWarning() << "Unable to connect to " << interfaceName << "::PropertyChanged on" << path; |
1613 | - } |
1614 | - |
1615 | - setme.reset(i); |
1616 | - |
1617 | - if (setme && setme->isValid()) { |
1618 | - QDBusReply<QMap<QString,QVariant> > properties = setme->call("GetProperties"); |
1619 | - if (properties.isValid()) |
1620 | - setProperties(properties.value()); |
1621 | - } |
1622 | + |
1623 | + watchCall(m_bluezDeviceProperties->GetAll(BLUEZ_DEVICE_IFACE), [=](QDBusPendingCallWatcher *watcher) { |
1624 | + QDBusPendingReply<QVariantMap> reply = *watcher; |
1625 | + |
1626 | + if (reply.isError()) { |
1627 | + qWarning() << "Failed to retrieve properties for device" << m_bluezDevice->path(); |
1628 | + watcher->deleteLater(); |
1629 | + return; |
1630 | + } |
1631 | + |
1632 | + auto properties = reply.argumentAt<0>(); |
1633 | + setProperties(properties); |
1634 | + |
1635 | + watcher->deleteLater(); |
1636 | + }); |
1637 | +} |
1638 | + |
1639 | +void Device::slotPropertiesChanged(const QString &interface, const QVariantMap &changedProperties, |
1640 | + const QStringList &invalidatedProperties) |
1641 | +{ |
1642 | + Q_UNUSED(invalidatedProperties); |
1643 | + |
1644 | + if (interface != BLUEZ_DEVICE_IFACE) |
1645 | + return; |
1646 | + |
1647 | + setProperties(changedProperties); |
1648 | } |
1649 | |
1650 | void Device::setProperties(const QMap<QString,QVariant> &properties) |
1651 | @@ -111,79 +94,118 @@ |
1652 | } |
1653 | } |
1654 | |
1655 | -void Device::connectPending() |
1656 | -{ |
1657 | - if (m_paired && !m_trusted) { |
1658 | - while (!m_connectAfterPairing.isEmpty()) { |
1659 | - ConnectionMode mode = m_connectAfterPairing.takeFirst(); |
1660 | - connect(mode); |
1661 | - } |
1662 | - } |
1663 | -} |
1664 | - |
1665 | -/*** |
1666 | -**** |
1667 | -***/ |
1668 | - |
1669 | -void Device::addConnectAfterPairing(ConnectionMode mode) |
1670 | -{ |
1671 | - m_connectAfterPairing.append(mode); |
1672 | -} |
1673 | - |
1674 | -void Device::disconnect(ConnectionMode mode) |
1675 | -{ |
1676 | - QSharedPointer<QDBusInterface> interface; |
1677 | - |
1678 | - switch (mode) { |
1679 | - case HeadsetMode: |
1680 | - interface = m_headsetInterface; |
1681 | - break; |
1682 | - case Audio: |
1683 | - interface = m_audioInterface; |
1684 | - break; |
1685 | - case Input: |
1686 | - interface = m_inputInterface; |
1687 | - break; |
1688 | - default: |
1689 | - qWarning() << "Unhandled connection mode" << mode; |
1690 | - return; |
1691 | - } |
1692 | - |
1693 | - QDBusPendingCall call = interface->asyncCall("Disconnect"); |
1694 | - |
1695 | - QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(call, this); |
1696 | - QObject::connect(watcher, &QDBusPendingCallWatcher::finished, [this](QDBusPendingCallWatcher *watcher) { |
1697 | - QDBusPendingReply<void> reply = *watcher; |
1698 | - |
1699 | - if (reply.isError()) { |
1700 | - qWarning() << "Could not connect device:" |
1701 | - << reply.error().message(); |
1702 | - } |
1703 | - |
1704 | - watcher->deleteLater(); |
1705 | - }); |
1706 | -} |
1707 | - |
1708 | -void Device::connect(ConnectionMode mode) |
1709 | -{ |
1710 | - QSharedPointer<QDBusInterface> interface; |
1711 | - |
1712 | - switch (mode) { |
1713 | - case HeadsetMode: |
1714 | - interface = m_headsetInterface; |
1715 | - break; |
1716 | - case Audio: |
1717 | - interface = m_audioInterface; |
1718 | - break; |
1719 | - case Input: |
1720 | - interface = m_inputInterface; |
1721 | - break; |
1722 | - default: |
1723 | - qWarning() << "Unhandled connection mode" << mode; |
1724 | - return; |
1725 | - } |
1726 | - |
1727 | - QDBusPendingCall call = interface->asyncCall("Connect"); |
1728 | +void Device::setConnectAfterPairing(bool value) |
1729 | +{ |
1730 | + if (m_connectAfterPairing == value) |
1731 | + return; |
1732 | + |
1733 | + m_connectAfterPairing = value; |
1734 | +} |
1735 | + |
1736 | +void Device::disconnect() |
1737 | +{ |
1738 | + setConnection(Device::Disconnecting); |
1739 | + |
1740 | + QDBusPendingCall call = m_bluezDevice->Disconnect(); |
1741 | + |
1742 | + QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(call, this); |
1743 | + QObject::connect(watcher, &QDBusPendingCallWatcher::finished, [this](QDBusPendingCallWatcher *watcher) { |
1744 | + QDBusPendingReply<void> reply = *watcher; |
1745 | + |
1746 | + if (reply.isError()) { |
1747 | + qWarning() << "Could not disconnect device:" |
1748 | + << reply.error().message(); |
1749 | + |
1750 | + // Make sure we switch the connection indicator back to |
1751 | + // a sane state |
1752 | + updateConnection(); |
1753 | + } |
1754 | + |
1755 | + watcher->deleteLater(); |
1756 | + }); |
1757 | +} |
1758 | + |
1759 | +void Device::connectAfterPairing() |
1760 | +{ |
1761 | + if (!m_connectAfterPairing) |
1762 | + return; |
1763 | + |
1764 | + connect(); |
1765 | +} |
1766 | + |
1767 | +void Device::pair() |
1768 | +{ |
1769 | + if (m_paired) { |
1770 | + // If we are already paired we just have to make sure we |
1771 | + // trigger the connection process if we have to |
1772 | + connectAfterPairing(); |
1773 | + return; |
1774 | + } |
1775 | + |
1776 | + setConnection(Device::Connecting); |
1777 | + |
1778 | + m_isPairing = true; |
1779 | + |
1780 | + auto call = m_bluezDevice->asyncCall("Pair"); |
1781 | + |
1782 | + QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(call, this); |
1783 | + QObject::connect(watcher, &QDBusPendingCallWatcher::finished, [this](QDBusPendingCallWatcher *watcher) { |
1784 | + QDBusPendingReply<void> reply = *watcher; |
1785 | + bool success = true; |
1786 | + |
1787 | + if (reply.isError()) { |
1788 | + qWarning() << "Failed to pair with device:" |
1789 | + << reply.error().message(); |
1790 | + updateConnection(); |
1791 | + success = false; |
1792 | + } |
1793 | + |
1794 | + m_isPairing = false; |
1795 | + |
1796 | + Q_EMIT(pairingDone(success)); |
1797 | + |
1798 | + watcher->deleteLater(); |
1799 | + }); |
1800 | +} |
1801 | + |
1802 | +void Device::cancelPairing() |
1803 | +{ |
1804 | + if (!m_isPairing) |
1805 | + return; |
1806 | + |
1807 | + auto call = m_bluezDevice->asyncCall("CancelPairing"); |
1808 | + |
1809 | + QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(call, this); |
1810 | + QObject::connect(watcher, &QDBusPendingCallWatcher::finished, [this](QDBusPendingCallWatcher *watcher) { |
1811 | + QDBusPendingReply<void> reply = *watcher; |
1812 | + |
1813 | + if (reply.isError()) { |
1814 | + qWarning() << "Failed to cancel pairing attempt with device:" |
1815 | + << reply.error().message(); |
1816 | + updateConnection(); |
1817 | + } else { |
1818 | + // Only mark us a not pairing when call succeeded |
1819 | + m_isPairing = false; |
1820 | + } |
1821 | + |
1822 | + watcher->deleteLater(); |
1823 | + }); |
1824 | +} |
1825 | + |
1826 | +void Device::connect() |
1827 | +{ |
1828 | + // If we have just paired then the device switched to connected = true for |
1829 | + // a short moment as BlueZ opened up a RFCOMM channel to perform SDP. If |
1830 | + // we should connect with the device on specific profiles now we go ahead |
1831 | + // here even if we're marked as connected as this still doesn't mean we're |
1832 | + // connected on any profile. Calling org.bluez.Device1.Connect multiple |
1833 | + // times doesn't hurt an will not fail. |
1834 | + if (m_isConnected && !m_connectAfterPairing) |
1835 | + return; |
1836 | + |
1837 | + setConnection(Device::Connecting); |
1838 | + |
1839 | + QDBusPendingCall call = m_bluezDevice->asyncCall("Connect"); |
1840 | |
1841 | QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(call, this); |
1842 | QObject::connect(watcher, &QDBusPendingCallWatcher::finished, [this](QDBusPendingCallWatcher *watcher) { |
1843 | @@ -196,6 +218,12 @@ |
1844 | makeTrusted(true); |
1845 | } |
1846 | |
1847 | + // Regardless if the Connected property has changed or not we update |
1848 | + // the connection state here as the connection process is over now |
1849 | + // and we should have received any state change already at this |
1850 | + // point. |
1851 | + updateConnection(); |
1852 | + |
1853 | watcher->deleteLater(); |
1854 | }); |
1855 | } |
1856 | @@ -205,36 +233,22 @@ |
1857 | QDBusPendingReply<void> reply = *call; |
1858 | |
1859 | if (reply.isError()) { |
1860 | - qWarning() << "Could not set device as trusted:" |
1861 | + qWarning() << "Could not mark device as trusted:" |
1862 | << reply.error().message(); |
1863 | } |
1864 | + |
1865 | call->deleteLater(); |
1866 | } |
1867 | |
1868 | void Device::makeTrusted(bool trusted) |
1869 | { |
1870 | - QVariant value; |
1871 | - QDBusVariant variant(trusted); |
1872 | - |
1873 | - value.setValue(variant); |
1874 | - |
1875 | - if (m_deviceInterface) { |
1876 | - QDBusPendingCall pcall |
1877 | - = m_deviceInterface->asyncCall("SetProperty", "Trusted", value); |
1878 | - |
1879 | - QDBusPendingCallWatcher *watcher |
1880 | - = new QDBusPendingCallWatcher(pcall, this); |
1881 | - QObject::connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), |
1882 | - this, SLOT(slotMakeTrustedDone(QDBusPendingCallWatcher*))); |
1883 | - } else { |
1884 | - qWarning() << "Can't set device trusted before it is added in BlueZ"; |
1885 | - } |
1886 | + auto call = m_bluezDeviceProperties->Set(BLUEZ_DEVICE_IFACE, "Trusted", QDBusVariant(trusted)); |
1887 | + |
1888 | + auto watcher = new QDBusPendingCallWatcher(call, this); |
1889 | + QObject::connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), |
1890 | + this, SLOT(slotMakeTrustedDone(QDBusPendingCallWatcher*))); |
1891 | } |
1892 | |
1893 | -/*** |
1894 | -**** |
1895 | -***/ |
1896 | - |
1897 | void Device::setName(const QString &name) |
1898 | { |
1899 | if (m_name != name) { |
1900 | @@ -342,42 +356,34 @@ |
1901 | { |
1902 | Connection c; |
1903 | |
1904 | - /* The "State" property is a little more useful this "Connected" bool |
1905 | - because the former tells us Bluez *knows* a device is connecting. |
1906 | - So use "Connected" only as a fallback */ |
1907 | - |
1908 | - if ((m_state == "connected") || (m_state == "playing")) |
1909 | - c = Connection::Connected; |
1910 | - else if (m_state == "connecting") |
1911 | - c = Connection::Connecting; |
1912 | - else if (m_state == "disconnected") |
1913 | - c = Connection::Disconnected; |
1914 | - else |
1915 | - c = m_isConnected ? Connection::Connected : Connection::Disconnected; |
1916 | + c = m_isConnected ? Connection::Connected : Connection::Disconnected; |
1917 | |
1918 | setConnection(c); |
1919 | } |
1920 | |
1921 | void Device::updateProperty(const QString &key, const QVariant &value) |
1922 | { |
1923 | - if (key == "Name") { // org.bluez.Device |
1924 | + if (key == "Name") { |
1925 | setName(value.toString()); |
1926 | - } else if (key == "Address") { // org.bluez.Device |
1927 | + } else if (key == "Address") { |
1928 | setAddress(value.toString()); |
1929 | - } else if (key == "State") { // org.bluez.Audio, org.bluez.Headset |
1930 | - m_state = value.toString(); |
1931 | - updateConnection(); |
1932 | } else if (key == "Connected") { |
1933 | m_isConnected = value.toBool(); |
1934 | updateConnection(); |
1935 | - } else if (key == "Class") { // org.bluez.Device |
1936 | + } else if (key == "Class") { |
1937 | setType(getTypeFromClass(value.toUInt())); |
1938 | - } else if (key == "Paired") { // org.bluez.Device |
1939 | + } else if (key == "Paired") { |
1940 | setPaired(value.toBool()); |
1941 | + |
1942 | + if (m_paired && m_connectAfterPairing) { |
1943 | + connectAfterPairing(); |
1944 | + return; |
1945 | + } |
1946 | + |
1947 | updateConnection(); |
1948 | - } else if (key == "Trusted") { // org.bluez.Device |
1949 | + } else if (key == "Trusted") { |
1950 | setTrusted(value.toBool()); |
1951 | - } else if (key == "Icon") { // org.bluez.Device |
1952 | + } else if (key == "Icon") { |
1953 | m_fallbackIconName = value.toString(); |
1954 | updateIcon (); |
1955 | } else if (key == "RSSI") { |
1956 | @@ -386,10 +392,6 @@ |
1957 | } |
1958 | } |
1959 | |
1960 | -/*** |
1961 | -**** |
1962 | -***/ |
1963 | - |
1964 | /* Determine the Type from the bits in the Class of Device (CoD) field. |
1965 | https://www.bluetooth.org/en-us/specification/assigned-numbers/baseband */ |
1966 | Device::Type Device::getTypeFromClass (quint32 c) |
1967 | @@ -468,6 +470,11 @@ |
1968 | if ((c & 0x20) != 0) |
1969 | return Type::Camera; |
1970 | break; |
1971 | + |
1972 | + case 0x07: |
1973 | + if ((c & 0x4) != 0) |
1974 | + return Type::Watch; |
1975 | + break; |
1976 | } |
1977 | |
1978 | return Type::Other; |
1979 | @@ -489,4 +496,3 @@ |
1980 | |
1981 | return None; |
1982 | } |
1983 | - |
1984 | |
1985 | === modified file 'plugins/bluetooth/device.h' |
1986 | --- plugins/bluetooth/device.h 2015-08-28 09:32:38 +0000 |
1987 | +++ plugins/bluetooth/device.h 2015-11-20 08:48:08 +0000 |
1988 | @@ -26,6 +26,9 @@ |
1989 | #include <QSharedPointer> |
1990 | #include <QString> |
1991 | |
1992 | +#include "freedesktop_properties.h" |
1993 | +#include "bluez_device1.h" |
1994 | + |
1995 | struct Device: QObject |
1996 | { |
1997 | Q_OBJECT |
1998 | @@ -71,17 +74,14 @@ |
1999 | |
2000 | enum Type { Other, Computer, Cellular, Smartphone, Phone, Modem, Network, |
2001 | Headset, Speakers, Headphones, Video, OtherAudio, Joypad, |
2002 | - Keypad, Keyboard, Tablet, Mouse, Printer, Camera, Carkit }; |
2003 | + Keypad, Keyboard, Tablet, Mouse, Printer, Camera, Carkit, Watch }; |
2004 | |
2005 | enum Strength { None, Poor, Fair, Good, Excellent }; |
2006 | |
2007 | enum Connection { Disconnected=1, Connecting=2, |
2008 | Connected=4, Disconnecting=8 }; |
2009 | |
2010 | - enum ConnectionMode { Audio, AudioSource, AudioSink, HandsfreeGateway, |
2011 | - HeadsetMode, Input }; |
2012 | - |
2013 | - Q_ENUMS(Type Strength Connection ConnectionMode) |
2014 | + Q_ENUMS(Type Strength Connection) |
2015 | |
2016 | Q_DECLARE_FLAGS(Connections, Connection) |
2017 | |
2018 | @@ -96,6 +96,7 @@ |
2019 | void connectionChanged(); |
2020 | void strengthChanged(); |
2021 | void deviceChanged(); // catchall for any change |
2022 | + void pairingDone(bool success); |
2023 | |
2024 | public: |
2025 | const QString& getName() const { return m_name; } |
2026 | @@ -106,7 +107,7 @@ |
2027 | bool isTrusted() const { return m_trusted; } |
2028 | Connection getConnection() const { return m_connection; } |
2029 | Strength getStrength() const { return m_strength; } |
2030 | - QString getPath() const { return m_deviceInterface ? m_deviceInterface->path() : QString(); } |
2031 | + QString getPath() const { return m_bluezDevice ? m_bluezDevice->path() : QString(); } |
2032 | |
2033 | private: |
2034 | QString m_name; |
2035 | @@ -120,13 +121,10 @@ |
2036 | Connection m_connection = Connection::Disconnected; |
2037 | Strength m_strength = Strength::None; |
2038 | bool m_isConnected = false; |
2039 | - QSharedPointer<QDBusInterface> m_deviceInterface; |
2040 | - QSharedPointer<QDBusInterface> m_audioInterface; |
2041 | - QSharedPointer<QDBusInterface> m_audioSourceInterface; |
2042 | - QSharedPointer<QDBusInterface> m_audioSinkInterface; |
2043 | - QSharedPointer<QDBusInterface> m_headsetInterface; |
2044 | - QSharedPointer<QDBusInterface> m_inputInterface; |
2045 | - QList<ConnectionMode> m_connectAfterPairing; |
2046 | + bool m_connectAfterPairing = false; |
2047 | + QScopedPointer<BluezDevice1> m_bluezDevice; |
2048 | + QScopedPointer<FreeDesktopProperties> m_bluezDeviceProperties; |
2049 | + bool m_isPairing = false; |
2050 | |
2051 | protected: |
2052 | void setName(const QString &name); |
2053 | @@ -142,30 +140,29 @@ |
2054 | |
2055 | public: |
2056 | Device() {} |
2057 | + Device(const QString &path, QDBusConnection &bus); |
2058 | ~Device() {} |
2059 | - Device(const QString &path, QDBusConnection &bus); |
2060 | - Device(const QMap<QString,QVariant> &properties); |
2061 | - void initDevice(const QString &path, QDBusConnection &bus); |
2062 | bool isValid() const { return getType() != Type::Other; } |
2063 | - void connect(ConnectionMode); |
2064 | + void pair(); |
2065 | + Q_INVOKABLE void cancelPairing(); |
2066 | + void connect(); |
2067 | void makeTrusted(bool trusted); |
2068 | - void disconnect(ConnectionMode); |
2069 | + void disconnect(); |
2070 | void setProperties(const QMap<QString,QVariant> &properties); |
2071 | - void addConnectAfterPairing(const ConnectionMode mode); |
2072 | - |
2073 | - public Q_SLOTS: |
2074 | - void connectPending(); |
2075 | + void setConnectAfterPairing(bool value); |
2076 | |
2077 | private Q_SLOTS: |
2078 | - void slotPropertyChanged(const QString &key, const QDBusVariant &value); |
2079 | + void slotPropertiesChanged(const QString &interface, const QVariantMap &changedProperties, |
2080 | + const QStringList &invalidatedProperties); |
2081 | void slotMakeTrustedDone(QDBusPendingCallWatcher *call); |
2082 | |
2083 | private: |
2084 | + void initDevice(const QString &path, QDBusConnection &bus); |
2085 | void updateProperties(QSharedPointer<QDBusInterface>); |
2086 | - void initInterface(QSharedPointer<QDBusInterface>&, const QString &path, const QString &name, QDBusConnection&); |
2087 | void updateProperty(const QString &key, const QVariant &value); |
2088 | static Type getTypeFromClass(quint32 bluetoothClass); |
2089 | Device::Strength getStrengthFromRssi(int rssi); |
2090 | + void connectAfterPairing(); |
2091 | }; |
2092 | |
2093 | Q_DECLARE_METATYPE(Device*) |
2094 | |
2095 | === modified file 'plugins/bluetooth/devicemodel.cpp' |
2096 | --- plugins/bluetooth/devicemodel.cpp 2015-08-28 09:32:38 +0000 |
2097 | +++ plugins/bluetooth/devicemodel.cpp 2015-11-20 08:48:08 +0000 |
2098 | @@ -27,33 +27,81 @@ |
2099 | |
2100 | namespace |
2101 | { |
2102 | - const int SCANNING_ACTIVE_DURATION_MSEC = (10 * 1000); |
2103 | - |
2104 | + const int SCANNING_ACTIVE_DURATION_MSEC = (30 * 1000); |
2105 | const int SCANNING_IDLE_DURATION_MSEC = (10 * 1000); |
2106 | } |
2107 | |
2108 | DeviceModel::DeviceModel(QDBusConnection &dbus, QObject *parent): |
2109 | QAbstractListModel(parent), |
2110 | m_dbus(dbus), |
2111 | - m_bluezManager("org.bluez", "/", "org.bluez.Manager", m_dbus) |
2112 | + m_bluezManager("org.bluez", "/", m_dbus), |
2113 | + m_bluezAgentManager("org.bluez", "/org/bluez", m_dbus), |
2114 | + m_isPowered(false), |
2115 | + m_isPairable(false), |
2116 | + m_isDiscovering(false), |
2117 | + m_isDiscoverable(false) |
2118 | { |
2119 | if (m_bluezManager.isValid()) { |
2120 | |
2121 | - QDBusReply<QDBusObjectPath> qObjectPath = m_bluezManager.call("DefaultAdapter"); |
2122 | - if (qObjectPath.isValid()) |
2123 | - setAdapterFromPath(qObjectPath.value().path()); |
2124 | - |
2125 | - m_dbus.connect (m_bluezManager.service(), |
2126 | - m_bluezManager.path(), |
2127 | - m_bluezManager.interface(), |
2128 | - "DefaultAdapterChanged", |
2129 | - this, SLOT(slotDefaultAdapterChanged(const QDBusObjectPath&))); |
2130 | - |
2131 | - m_dbus.connect (m_bluezManager.service(), |
2132 | - m_bluezManager.path(), |
2133 | - m_bluezManager.interface(), |
2134 | - "AdapterRemoved", |
2135 | - this, SLOT(slotAdapterRemoved(const QDBusObjectPath&))); |
2136 | + connect(&m_bluezManager, SIGNAL(InterfacesAdded(const QDBusObjectPath&, InterfaceList)), |
2137 | + this, SLOT(slotInterfacesAdded(const QDBusObjectPath&, InterfaceList))); |
2138 | + |
2139 | + connect(&m_bluezManager, SIGNAL(InterfacesRemoved(const QDBusObjectPath&, const QStringList&)), |
2140 | + this, SLOT(slotInterfacesRemoved(const QDBusObjectPath&, const QStringList&))); |
2141 | + |
2142 | + watchCall(m_bluezManager.GetManagedObjects(), [=](QDBusPendingCallWatcher *watcher) { |
2143 | + QDBusPendingReply<ManagedObjectList> reply = *watcher; |
2144 | + |
2145 | + if (reply.isError()) { |
2146 | + qWarning() << "Failed to retrieve list of managed objects from BlueZ service: " |
2147 | + << reply.error().message(); |
2148 | + watcher->deleteLater(); |
2149 | + return; |
2150 | + } |
2151 | + |
2152 | + auto objectList = reply.argumentAt<0>(); |
2153 | + |
2154 | + for (QDBusObjectPath path : objectList.keys()) { |
2155 | + InterfaceList ifaces = objectList.value(path); |
2156 | + |
2157 | + if (!ifaces.contains(BLUEZ_ADAPTER_IFACE)) |
2158 | + continue; |
2159 | + |
2160 | + // Ok, here we've found an adapter. As we don't expect multiple at the |
2161 | + // moment we just take the first one we find. |
2162 | + setAdapterFromPath(path.path(), ifaces.value(BLUEZ_ADAPTER_IFACE)); |
2163 | + break; |
2164 | + } |
2165 | + |
2166 | + watcher->deleteLater(); |
2167 | + }); |
2168 | + } |
2169 | + |
2170 | + if (m_bluezAgentManager.isValid()) { |
2171 | + // NOTE: We can safely register our agent here even if we don't |
2172 | + // manage any adapter yet. BlueZ makes sure our agent will only |
2173 | + // process requests related to actions we do unless we our agent |
2174 | + // the system default one. |
2175 | + auto call = m_bluezAgentManager.RegisterAgent(QDBusObjectPath(DBUS_ADAPTER_AGENT_PATH), |
2176 | + DBUS_AGENT_CAPABILITY); |
2177 | + |
2178 | + watchCall(call, [=](QDBusPendingCallWatcher *watcher) { |
2179 | + QDBusPendingReply<void> reply = *watcher; |
2180 | + |
2181 | + if (reply.isError()) { |
2182 | + qWarning() << "Failed to register our agent with BlueZ:" |
2183 | + << reply.error().message(); |
2184 | + } |
2185 | + else { |
2186 | + setupAsDefaultAgent(); |
2187 | + } |
2188 | + |
2189 | + watcher->deleteLater(); |
2190 | + }); |
2191 | + } |
2192 | + else { |
2193 | + qWarning() << "Could not register agent with BlueZ service as " |
2194 | + << "the agent manager is not available!"; |
2195 | } |
2196 | |
2197 | connect(&m_timer, SIGNAL(timeout()), this, SLOT(slotTimeout())); |
2198 | @@ -62,6 +110,89 @@ |
2199 | DeviceModel::~DeviceModel() |
2200 | { |
2201 | clearAdapter(); |
2202 | + |
2203 | + qWarning() << "Releasing device model .."; |
2204 | + |
2205 | + if (m_bluezAgentManager.isValid()) { |
2206 | + auto call = m_bluezAgentManager.UnregisterAgent(QDBusObjectPath(DBUS_ADAPTER_AGENT_PATH)); |
2207 | + watchCall(call, [=](QDBusPendingCallWatcher *watcher) { |
2208 | + QDBusPendingReply<void> reply = *watcher; |
2209 | + |
2210 | + if (reply.isError()) { |
2211 | + qWarning() << "Failed to unregister our agent with BlueZ:" |
2212 | + << reply.error().message(); |
2213 | + } |
2214 | + |
2215 | + watcher->deleteLater(); |
2216 | + }); |
2217 | + } |
2218 | +} |
2219 | + |
2220 | +void DeviceModel::setupAsDefaultAgent() |
2221 | +{ |
2222 | + auto call = m_bluezAgentManager.RequestDefaultAgent(QDBusObjectPath(DBUS_ADAPTER_AGENT_PATH)); |
2223 | + watchCall(call, [=](QDBusPendingCallWatcher *watcher) { |
2224 | + QDBusPendingReply<void> reply = *watcher; |
2225 | + |
2226 | + if (reply.isError()) { |
2227 | + qWarning() << "Failed to setup ourself as default agent: " |
2228 | + << reply.error().message(); |
2229 | + } |
2230 | + |
2231 | + watcher->deleteLater(); |
2232 | + }); |
2233 | +} |
2234 | + |
2235 | +void DeviceModel::slotInterfacesAdded(const QDBusObjectPath &objectPath, InterfaceList ifacesAndProps) |
2236 | +{ |
2237 | + Q_UNUSED(ifacesAndProps); |
2238 | + |
2239 | + auto candidatedPath = objectPath.path(); |
2240 | + |
2241 | + if (!m_bluezAdapter) { |
2242 | + // Maybe we have a new adapter we can start to use? |
2243 | + if (ifacesAndProps.contains(BLUEZ_ADAPTER_IFACE)) |
2244 | + setAdapterFromPath(candidatedPath, ifacesAndProps.value(BLUEZ_ADAPTER_IFACE)); |
2245 | + |
2246 | + return; |
2247 | + } |
2248 | + |
2249 | + // At this point we can only get new devices |
2250 | + if (!candidatedPath.startsWith(m_bluezAdapter->path())) |
2251 | + return; |
2252 | + |
2253 | + if (!ifacesAndProps.contains(BLUEZ_DEVICE_IFACE)) |
2254 | + return; |
2255 | + |
2256 | + addDevice(candidatedPath, ifacesAndProps.value(BLUEZ_DEVICE_IFACE)); |
2257 | +} |
2258 | + |
2259 | +void DeviceModel::slotInterfacesRemoved(const QDBusObjectPath &objectPath, const QStringList &interfaces) |
2260 | +{ |
2261 | + auto candidatedPath = objectPath.path(); |
2262 | + |
2263 | + if (!m_bluezAdapter) |
2264 | + return; |
2265 | + |
2266 | + if (candidatedPath == m_bluezAdapter->path() && |
2267 | + interfaces.contains(BLUEZ_ADAPTER_IFACE)) { |
2268 | + clearAdapter(); |
2269 | + return; |
2270 | + } |
2271 | + |
2272 | + if (!candidatedPath.startsWith(m_bluezAdapter->path())) |
2273 | + return; |
2274 | + |
2275 | + if (!interfaces.contains(BLUEZ_DEVICE_IFACE)) |
2276 | + return; |
2277 | + |
2278 | + auto device = getDeviceFromPath(candidatedPath); |
2279 | + if (!device) |
2280 | + return; |
2281 | + |
2282 | + const int row = findRowFromAddress(device->getAddress()); |
2283 | + if ((row >= 0)) |
2284 | + removeRow(row); |
2285 | } |
2286 | |
2287 | int DeviceModel::findRowFromAddress(const QString &address) const |
2288 | @@ -79,27 +210,45 @@ |
2289 | : SCANNING_IDLE_DURATION_MSEC); |
2290 | } |
2291 | |
2292 | +void DeviceModel::setDiscovering(bool value) |
2293 | +{ |
2294 | + if (value == m_isDiscovering) |
2295 | + return; |
2296 | + |
2297 | + m_isDiscovering = value; |
2298 | + Q_EMIT(discoveringChanged(m_isDiscovering)); |
2299 | +} |
2300 | + |
2301 | void DeviceModel::stopDiscovery() |
2302 | { |
2303 | - if (m_isDiscovering) { |
2304 | - if (m_bluezAdapter) |
2305 | - m_bluezAdapter->asyncCall("StopDiscovery"); |
2306 | - m_isDiscovering = false; |
2307 | - Q_EMIT(discoveringChanged(m_isDiscovering)); |
2308 | + if (m_bluezAdapter && m_isPowered && m_isDiscovering) { |
2309 | + |
2310 | + watchCall(m_bluezAdapter->StopDiscovery(), [=](QDBusPendingCallWatcher *watcher) { |
2311 | + QDBusPendingReply<void> reply = *watcher; |
2312 | + if (reply.isError()) { |
2313 | + qWarning() << "Failed to stop device discovery:" |
2314 | + << reply.error().message(); |
2315 | + } |
2316 | + |
2317 | + watcher->deleteLater(); |
2318 | + }); |
2319 | } |
2320 | - |
2321 | - restartTimer(); |
2322 | } |
2323 | |
2324 | void DeviceModel::startDiscovery() |
2325 | { |
2326 | if (m_bluezAdapter && m_isPowered && !m_isDiscovering) { |
2327 | - m_bluezAdapter->asyncCall("StartDiscovery"); |
2328 | - m_isDiscovering = true; |
2329 | - Q_EMIT(discoveringChanged(m_isDiscovering)); |
2330 | + |
2331 | + watchCall(m_bluezAdapter->StartDiscovery(), [=](QDBusPendingCallWatcher *watcher) { |
2332 | + QDBusPendingReply<void> reply = *watcher; |
2333 | + if (reply.isError()) { |
2334 | + qWarning() << "Failed to start device discovery:" |
2335 | + << reply.error().message(); |
2336 | + } |
2337 | + |
2338 | + watcher->deleteLater(); |
2339 | + }); |
2340 | } |
2341 | - |
2342 | - restartTimer(); |
2343 | } |
2344 | |
2345 | void DeviceModel::toggleDiscovery() |
2346 | @@ -119,27 +268,12 @@ |
2347 | { |
2348 | if (m_bluezAdapter) { |
2349 | |
2350 | - QDBusConnection bus = m_bluezAdapter->connection(); |
2351 | - const QString service = m_bluezAdapter->service(); |
2352 | - const QString path = m_bluezAdapter->path(); |
2353 | - const QString interface = m_bluezAdapter->interface(); |
2354 | - |
2355 | stopDiscovery(); |
2356 | m_discoverableTimer.stop(); |
2357 | trySetDiscoverable(false); |
2358 | |
2359 | - bus.disconnect(service, path, interface, "DeviceCreated", |
2360 | - this, SLOT(slotDeviceCreated(const QDBusObjectPath&))); |
2361 | - bus.disconnect(service, path, interface, "DeviceRemoved", |
2362 | - this, SLOT(slotDeviceRemoved(const QDBusObjectPath&))); |
2363 | - bus.disconnect(service, path, interface, "DeviceFound", |
2364 | - this, SLOT(slotDeviceFound(const QString&, const QMap<QString,QVariant>&))); |
2365 | - bus.disconnect(service, path, interface, "DeviceDisappeared", |
2366 | - this, SLOT(slotDeviceDisappeared(const QString&))); |
2367 | - bus.disconnect(service, path, interface, "PropertyChanged", |
2368 | - this, SLOT(slotPropertyChanged(const QString&, const QDBusVariant&))); |
2369 | - |
2370 | m_bluezAdapter.reset(0); |
2371 | + m_bluezAdapterProperties.reset(0); |
2372 | m_adapterName.clear(); |
2373 | |
2374 | beginResetModel(); |
2375 | @@ -148,68 +282,75 @@ |
2376 | } |
2377 | } |
2378 | |
2379 | -void DeviceModel::setAdapterFromPath(const QString &path) |
2380 | +void DeviceModel::setAdapterFromPath(const QString &path, const QVariantMap &properties) |
2381 | { |
2382 | clearAdapter(); |
2383 | |
2384 | if (!path.isEmpty()) { |
2385 | |
2386 | - const QString service = "org.bluez"; |
2387 | - const QString interface = "org.bluez.Adapter"; |
2388 | - auto i = new QDBusInterface(service, path, interface, m_dbus); |
2389 | - |
2390 | - m_dbus.connect(service, path, interface, "DeviceCreated", |
2391 | - this, SLOT(slotDeviceCreated(const QDBusObjectPath&))); |
2392 | - m_dbus.connect(service, path, interface, "DeviceRemoved", |
2393 | - this, SLOT(slotDeviceRemoved(const QDBusObjectPath&))); |
2394 | - m_dbus.connect(service, path, interface, "DeviceFound", |
2395 | - this, SLOT(slotDeviceFound(const QString&, const QMap<QString,QVariant>&))); |
2396 | - m_dbus.connect(service, path, interface, "DeviceDisappeared", |
2397 | - this, SLOT(slotDeviceDisappeared(const QString&))); |
2398 | - m_dbus.connect(service, path, interface, "PropertyChanged", |
2399 | - this, SLOT(slotPropertyChanged(const QString&, const QDBusVariant&))); |
2400 | - |
2401 | - m_bluezAdapter.reset(i); |
2402 | + auto adapter = new BluezAdapter1(BLUEZ_SERVICE, path, m_dbus); |
2403 | + auto adapterProperties = new FreeDesktopProperties(BLUEZ_SERVICE, path, m_dbus); |
2404 | + |
2405 | + m_bluezAdapter.reset(adapter); |
2406 | + m_bluezAdapterProperties.reset(adapterProperties); |
2407 | + |
2408 | startDiscovery(); |
2409 | updateDevices(); |
2410 | |
2411 | - QDBusReply<QMap<QString,QVariant> > properties = m_bluezAdapter->call("GetProperties"); |
2412 | - if (properties.isValid()) |
2413 | - setProperties(properties.value()); |
2414 | + setProperties(properties); |
2415 | + |
2416 | + connect(adapterProperties, SIGNAL(PropertiesChanged(const QString&, const QVariantMap&, const QStringList&)), |
2417 | + this, SLOT(slotAdapterPropertiesChanged(const QString&, const QVariantMap&, const QStringList&))); |
2418 | |
2419 | // Delay enabling discoverability by 1 second. |
2420 | m_discoverableTimer.setSingleShot(true); |
2421 | connect(&m_discoverableTimer, SIGNAL(timeout()), this, SLOT(slotEnableDiscoverable())); |
2422 | m_discoverableTimer.start(1000); |
2423 | - |
2424 | - // With the agent registered on the bus, make it known by the adapter |
2425 | - QDBusReply<void > reply = m_bluezAdapter->call("RegisterAgent", |
2426 | - qVariantFromValue(QDBusObjectPath(DBUS_ADAPTER_AGENT_PATH)), |
2427 | - QString(DBUS_AGENT_CAPABILITY)); |
2428 | - if (!reply.isValid()) |
2429 | - qWarning() << "Error registering agent for the default adapter:" << reply.error(); |
2430 | } |
2431 | } |
2432 | |
2433 | -void DeviceModel::slotAdapterRemoved(const QDBusObjectPath &path) |
2434 | -{ |
2435 | - if (m_bluezAdapter && (m_bluezAdapter->path()==path.path())) |
2436 | - clearAdapter(); |
2437 | -} |
2438 | - |
2439 | -void DeviceModel::slotDefaultAdapterChanged(const QDBusObjectPath &objectPath) |
2440 | -{ |
2441 | - setAdapterFromPath (objectPath.path()); |
2442 | +void DeviceModel::slotAdapterPropertiesChanged(const QString &interface, const QVariantMap &changedProperties, |
2443 | + const QStringList &invalidatedProperties) |
2444 | +{ |
2445 | + Q_UNUSED(invalidatedProperties); |
2446 | + |
2447 | + if (interface != BLUEZ_ADAPTER_IFACE) |
2448 | + return; |
2449 | + |
2450 | + setProperties(changedProperties); |
2451 | } |
2452 | |
2453 | void DeviceModel::updateDevices() |
2454 | { |
2455 | - if (m_bluezAdapter && m_bluezAdapter->isValid()) { |
2456 | - QDBusReply<QList<QDBusObjectPath> > reply = m_bluezAdapter->call("ListDevices"); |
2457 | - if (reply.isValid()) |
2458 | - for (auto path : reply.value()) |
2459 | - addDevice(path.path()); |
2460 | - } |
2461 | + watchCall(m_bluezManager.GetManagedObjects(), [=](QDBusPendingCallWatcher *watcher) { |
2462 | + QDBusPendingReply<ManagedObjectList> reply = *watcher; |
2463 | + |
2464 | + if (reply.isError()) { |
2465 | + qWarning() << "Failed to retrieve list of managed objects from BlueZ service: " |
2466 | + << reply.error().message(); |
2467 | + watcher->deleteLater(); |
2468 | + return; |
2469 | + } |
2470 | + |
2471 | + auto objectList = reply.argumentAt<0>(); |
2472 | + |
2473 | + for (auto objectPath : objectList.keys()) { |
2474 | + auto candidatePath = objectPath.path(); |
2475 | + |
2476 | + if (!candidatePath.startsWith(m_bluezAdapter->path())) |
2477 | + continue; |
2478 | + |
2479 | + InterfaceList ifaces = objectList.value(objectPath); |
2480 | + |
2481 | + if (!ifaces.contains(BLUEZ_DEVICE_IFACE)) |
2482 | + continue; |
2483 | + |
2484 | + auto properties = ifaces.value(BLUEZ_DEVICE_IFACE); |
2485 | + |
2486 | + addDevice(candidatePath, properties); |
2487 | + } |
2488 | + |
2489 | + }); |
2490 | } |
2491 | |
2492 | void DeviceModel::setProperties(const QMap<QString,QVariant> &properties) |
2493 | @@ -231,6 +372,9 @@ |
2494 | m_isPairable = value.toBool(); |
2495 | } else if (key == "Discoverable") { |
2496 | setDiscoverable(value.toBool()); |
2497 | + } else if (key == "Discovering") { |
2498 | + setDiscovering(value.toBool()); |
2499 | + restartTimer(); |
2500 | } else if (key == "Powered") { |
2501 | setPowered(value.toBool()); |
2502 | if (m_isPowered) |
2503 | @@ -268,7 +412,7 @@ |
2504 | value.setValue(disc); |
2505 | |
2506 | if (m_bluezAdapter && m_bluezAdapter->isValid() && m_isPowered) { |
2507 | - reply = m_bluezAdapter->call("SetProperty", "Discoverable", value); |
2508 | + reply = m_bluezAdapterProperties->call("Set", BLUEZ_ADAPTER_IFACE, "Discoverable", value); |
2509 | if (!reply.isValid()) |
2510 | qWarning() << "Error setting device discoverable:" << reply.error(); |
2511 | } |
2512 | @@ -280,12 +424,23 @@ |
2513 | updateProperty (key, value.variant()); |
2514 | } |
2515 | |
2516 | -void DeviceModel::addDevice(const QString &path) |
2517 | +void DeviceModel::slotDevicePairingDone(bool success) |
2518 | +{ |
2519 | + Device *device = static_cast<Device*>(sender()); |
2520 | + |
2521 | + Q_EMIT(devicePairingDone(device, success)); |
2522 | +} |
2523 | + |
2524 | +void DeviceModel::addDevice(const QString &path, const QVariantMap &properties) |
2525 | { |
2526 | QSharedPointer<Device> device(new Device(path, m_dbus)); |
2527 | + device->setProperties(properties); |
2528 | + |
2529 | if (device->isValid()) { |
2530 | QObject::connect(device.data(), SIGNAL(deviceChanged()), |
2531 | this, SLOT(slotDeviceChanged())); |
2532 | + QObject::connect(device.data(), SIGNAL(pairingDone(bool)), |
2533 | + this, SLOT(slotDevicePairingDone(bool))); |
2534 | addDevice(device); |
2535 | } |
2536 | } |
2537 | @@ -322,78 +477,6 @@ |
2538 | } |
2539 | } |
2540 | |
2541 | -void DeviceModel::slotDeviceCreated(const QDBusObjectPath &path) |
2542 | -{ |
2543 | - const QString service = "org.bluez"; |
2544 | - const QString interface = "org.bluez.Device"; |
2545 | - QScopedPointer<QDBusInterface> bluezDevice( |
2546 | - new QDBusInterface(service, path.path(), interface, m_dbus)); |
2547 | - |
2548 | - // A device was created. Now, we likely already have it, so let's find it |
2549 | - // again and finish the initialization. |
2550 | - QDBusReply<QMap<QString,QVariant> > properties |
2551 | - = bluezDevice->call("GetProperties"); |
2552 | - if (properties.isValid()) { |
2553 | - QMapIterator<QString,QVariant> it(properties); |
2554 | - while (it.hasNext()) { |
2555 | - it.next(); |
2556 | - if (it.key() == "Address") { |
2557 | - QSharedPointer<Device> device = getDeviceFromAddress(it.value().toString()); |
2558 | - |
2559 | - if (device) { |
2560 | - device->initDevice(path.path(), m_dbus); |
2561 | - QObject::connect(device.data(), SIGNAL(deviceChanged()), |
2562 | - this, SLOT(slotDeviceChanged())); |
2563 | - addDevice(device); |
2564 | - } else { |
2565 | - addDevice(path.path()); |
2566 | - } |
2567 | - break; |
2568 | - } |
2569 | - } |
2570 | - } else { |
2571 | - qWarning() << "Invalid device properties for" << path.path(); |
2572 | - } |
2573 | -} |
2574 | - |
2575 | -void DeviceModel::slotDeviceFound(const QString &address, |
2576 | - const QMap<QString,QVariant> &properties) |
2577 | -{ |
2578 | - Q_UNUSED(properties); |
2579 | - |
2580 | - QSharedPointer<Device> device = getDeviceFromAddress(address); |
2581 | - |
2582 | - if (!device) { |
2583 | - QSharedPointer<Device> device(new Device(properties)); |
2584 | - if (device->isValid()) { |
2585 | - addDevice(device); |
2586 | - } |
2587 | - } else { |
2588 | - device->setProperties(properties); |
2589 | - } |
2590 | -} |
2591 | - |
2592 | -void DeviceModel::slotDeviceRemoved(const QDBusObjectPath &path) |
2593 | -{ |
2594 | - /* Remove the device immediately, it will be listed again |
2595 | - once discovery results are returned. */ |
2596 | - |
2597 | - auto device = getDeviceFromPath(path.path()); |
2598 | - |
2599 | - if (device != nullptr) { |
2600 | - const int row = findRowFromAddress(device->getAddress()); |
2601 | - if ((row >= 0)) |
2602 | - removeRow(row); |
2603 | - } |
2604 | -} |
2605 | - |
2606 | -void DeviceModel::slotDeviceDisappeared(const QString &address) |
2607 | -{ |
2608 | - const int row = findRowFromAddress(address); |
2609 | - if ((row >= 0) && !m_devices[row]->isPaired()) |
2610 | - removeRow(row); |
2611 | -} |
2612 | - |
2613 | void DeviceModel::slotDeviceChanged() |
2614 | { |
2615 | const Device * device = qobject_cast<Device*>(sender()); |
2616 | @@ -429,61 +512,6 @@ |
2617 | return QSharedPointer<Device>(); |
2618 | } |
2619 | |
2620 | -void DeviceModel::addConnectAfterPairing(const QString &address, Device::ConnectionMode mode) |
2621 | -{ |
2622 | - QSharedPointer<Device> device = getDeviceFromAddress(address); |
2623 | - if (device) { |
2624 | - device->addConnectAfterPairing(mode); |
2625 | - } else { |
2626 | - qWarning() << "Device could not be found, can't add an operation"; |
2627 | - } |
2628 | -} |
2629 | - |
2630 | -void DeviceModel::slotCreateFinished(QDBusPendingCallWatcher *call) |
2631 | -{ |
2632 | - QDBusPendingReply<QDBusObjectPath> reply = *call; |
2633 | - |
2634 | - if (reply.isError()) { |
2635 | - qWarning() << "Could not create device:" << reply.error().message(); |
2636 | - } |
2637 | - |
2638 | - call->deleteLater(); |
2639 | -} |
2640 | - |
2641 | -void DeviceModel::createDevice (const QString &address, QObject *agent) |
2642 | -{ |
2643 | - if (m_bluezAdapter) { |
2644 | - QString agent_path(DBUS_AGENT_PATH); |
2645 | - agent_path.append("/"); |
2646 | - agent_path.append(address); |
2647 | - agent_path.replace(":", "_"); |
2648 | - |
2649 | - if(!m_dbus.registerObject(agent_path, agent)) |
2650 | - qCritical() << "Couldn't register agent at" << agent_path; |
2651 | - |
2652 | - QDBusPendingCall pcall = m_bluezAdapter->asyncCall("CreatePairedDevice", |
2653 | - address, |
2654 | - qVariantFromValue(QDBusObjectPath(agent_path)), |
2655 | - QString(DBUS_AGENT_CAPABILITY)); |
2656 | - |
2657 | - QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pcall, this); |
2658 | - QObject::connect(watcher, &QDBusPendingCallWatcher::finished, [this, address](QDBusPendingCallWatcher *watcher) { |
2659 | - QDBusPendingReply<QDBusObjectPath> reply = *watcher; |
2660 | - |
2661 | - if (reply.isError()) { |
2662 | - qWarning() << "Could not create device:" << reply.error().message(); |
2663 | - } else { |
2664 | - QSharedPointer<Device> device = getDeviceFromAddress(address); |
2665 | - device->connectPending(); |
2666 | - } |
2667 | - |
2668 | - watcher->deleteLater(); |
2669 | - }); |
2670 | - } else { |
2671 | - qWarning() << "Default adapter is not available for device creation"; |
2672 | - } |
2673 | -} |
2674 | - |
2675 | void DeviceModel::slotRemoveFinished(QDBusPendingCallWatcher *call) |
2676 | { |
2677 | QDBusPendingReply<void> reply = *call; |
2678 | @@ -496,19 +524,19 @@ |
2679 | |
2680 | void DeviceModel::removeDevice (const QString &path) |
2681 | { |
2682 | - if (m_bluezAdapter) { |
2683 | - QDBusPendingCall pcall = m_bluezAdapter->asyncCall("RemoveDevice", qVariantFromValue(QDBusObjectPath(path))); |
2684 | - |
2685 | - QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pcall, this); |
2686 | - QObject::connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), |
2687 | - this, SLOT(slotRemoveFinished(QDBusPendingCallWatcher*))); |
2688 | - } else { |
2689 | + if (!m_bluezAdapter) { |
2690 | qWarning() << "Default adapter is not available for device removal"; |
2691 | + return; |
2692 | } |
2693 | + |
2694 | + QDBusPendingCall call = m_bluezAdapter->RemoveDevice(QDBusObjectPath(path)); |
2695 | + |
2696 | + QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(call, this); |
2697 | + QObject::connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), |
2698 | + this, SLOT(slotRemoveFinished(QDBusPendingCallWatcher*))); |
2699 | } |
2700 | |
2701 | -int |
2702 | -DeviceModel::rowCount(const QModelIndex &parent) const |
2703 | +int DeviceModel::rowCount(const QModelIndex &parent) const |
2704 | { |
2705 | Q_UNUSED(parent); |
2706 | |
2707 | @@ -583,13 +611,6 @@ |
2708 | return ret; |
2709 | } |
2710 | |
2711 | - |
2712 | -/*** |
2713 | -**** |
2714 | -**** Filter |
2715 | -**** |
2716 | -***/ |
2717 | - |
2718 | void DeviceFilter::filterOnType(QVector<Device::Type> types) |
2719 | { |
2720 | m_types = types; |
2721 | |
2722 | === modified file 'plugins/bluetooth/devicemodel.h' |
2723 | --- plugins/bluetooth/devicemodel.h 2015-08-28 09:32:38 +0000 |
2724 | +++ plugins/bluetooth/devicemodel.h 2015-11-20 08:48:08 +0000 |
2725 | @@ -35,6 +35,11 @@ |
2726 | |
2727 | #include "device.h" |
2728 | |
2729 | +#include "freedesktop_objectmanager.h" |
2730 | +#include "freedesktop_properties.h" |
2731 | +#include "bluez_adapter1.h" |
2732 | +#include "bluez_agentmanager1.h" |
2733 | + |
2734 | class DeviceModel: public QAbstractListModel |
2735 | { |
2736 | Q_OBJECT |
2737 | @@ -68,8 +73,6 @@ |
2738 | bool isPowered() const { return m_isPowered; } |
2739 | bool isDiscovering() const { return m_isDiscovering; } |
2740 | bool isDiscoverable() const { return m_isDiscoverable; } |
2741 | - void addConnectAfterPairing(const QString &address, Device::ConnectionMode mode); |
2742 | - void createDevice(const QString &address, QObject *agent); |
2743 | void removeDevice(const QString &path); |
2744 | void stopDiscovery(); |
2745 | void startDiscovery(); |
2746 | @@ -80,10 +83,12 @@ |
2747 | void poweredChanged(bool powered); |
2748 | void discoveringChanged(bool isDiscovering); |
2749 | void discoverableChanged(bool isDiscoverable); |
2750 | + void devicePairingDone(Device *device, bool success); |
2751 | |
2752 | private: |
2753 | QDBusConnection m_dbus; |
2754 | - QDBusInterface m_bluezManager; |
2755 | + DBusObjectManagerInterface m_bluezManager; |
2756 | + BluezAgentManager1 m_bluezAgentManager; |
2757 | |
2758 | void setProperties(const QMap<QString,QVariant> &properties); |
2759 | void updateProperty(const QString &key, const QVariant &value); |
2760 | @@ -100,31 +105,34 @@ |
2761 | void setDiscoverable(bool discoverable); |
2762 | void setPowered(bool powered); |
2763 | |
2764 | - QScopedPointer<QDBusInterface> m_bluezAdapter; |
2765 | + QScopedPointer<BluezAdapter1> m_bluezAdapter; |
2766 | + QScopedPointer<FreeDesktopProperties> m_bluezAdapterProperties; |
2767 | + |
2768 | void clearAdapter(); |
2769 | - void setAdapterFromPath(const QString &objectPath); |
2770 | + void setAdapterFromPath(const QString &objectPath, const QVariantMap &properties); |
2771 | |
2772 | QList<QSharedPointer<Device> > m_devices; |
2773 | void updateDevices(); |
2774 | void addDevice(QSharedPointer<Device> &device); |
2775 | - void addDevice(const QString &objectPath); |
2776 | + void addDevice(const QString &objectPath, const QVariantMap &properties); |
2777 | void removeRow(int i); |
2778 | int findRowFromAddress(const QString &address) const; |
2779 | void emitRowChanged(int row); |
2780 | |
2781 | + void setDiscovering(bool value); |
2782 | + void setupAsDefaultAgent(); |
2783 | + |
2784 | private Q_SLOTS: |
2785 | - void slotCreateFinished(QDBusPendingCallWatcher *call); |
2786 | + void slotInterfacesAdded(const QDBusObjectPath &objectPath, InterfaceList ifacesAndProps); |
2787 | + void slotInterfacesRemoved(const QDBusObjectPath &objectPath, const QStringList &interfaces); |
2788 | + void slotAdapterPropertiesChanged(const QString &interface, const QVariantMap &changedProperties, |
2789 | + const QStringList &invalidatedProperties); |
2790 | void slotRemoveFinished(QDBusPendingCallWatcher *call); |
2791 | void slotPropertyChanged(const QString &key, const QDBusVariant &value); |
2792 | void slotTimeout(); |
2793 | void slotEnableDiscoverable(); |
2794 | void slotDeviceChanged(); |
2795 | - void slotDeviceCreated(const QDBusObjectPath &); |
2796 | - void slotDeviceRemoved(const QDBusObjectPath &); |
2797 | - void slotDeviceFound(const QString &, const QMap<QString,QVariant>&); |
2798 | - void slotDeviceDisappeared(const QString&); |
2799 | - void slotDefaultAdapterChanged(const QDBusObjectPath&); |
2800 | - void slotAdapterRemoved(const QDBusObjectPath& path); |
2801 | + void slotDevicePairingDone(bool success); |
2802 | }; |
2803 | |
2804 | class DeviceFilter: public QSortFilterProxyModel |
2805 | |
2806 | === added file 'plugins/bluetooth/freedesktop_objectmanager.cpp' |
2807 | --- plugins/bluetooth/freedesktop_objectmanager.cpp 1970-01-01 00:00:00 +0000 |
2808 | +++ plugins/bluetooth/freedesktop_objectmanager.cpp 2015-11-20 08:48:08 +0000 |
2809 | @@ -0,0 +1,26 @@ |
2810 | +/* |
2811 | + * This file was generated by qdbusxml2cpp version 0.8 |
2812 | + * Command line was: qdbusxml2cpp -p freedesktop_objectmanager -i bluez_helper.h -v -c DBusObjectManagerInterface org.freedesktop.DBus.ObjectManager.xml |
2813 | + * |
2814 | + * qdbusxml2cpp is Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies). |
2815 | + * |
2816 | + * This is an auto-generated file. |
2817 | + * This file may have been hand-edited. Look for HAND-EDIT comments |
2818 | + * before re-generating it. |
2819 | + */ |
2820 | + |
2821 | +#include "freedesktop_objectmanager.h" |
2822 | + |
2823 | +/* |
2824 | + * Implementation of interface class DBusObjectManagerInterface |
2825 | + */ |
2826 | + |
2827 | +DBusObjectManagerInterface::DBusObjectManagerInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent) |
2828 | + : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent) |
2829 | +{ |
2830 | +} |
2831 | + |
2832 | +DBusObjectManagerInterface::~DBusObjectManagerInterface() |
2833 | +{ |
2834 | +} |
2835 | + |
2836 | |
2837 | === added file 'plugins/bluetooth/freedesktop_objectmanager.h' |
2838 | --- plugins/bluetooth/freedesktop_objectmanager.h 1970-01-01 00:00:00 +0000 |
2839 | +++ plugins/bluetooth/freedesktop_objectmanager.h 2015-11-20 08:48:08 +0000 |
2840 | @@ -0,0 +1,58 @@ |
2841 | +/* |
2842 | + * This file was generated by qdbusxml2cpp version 0.8 |
2843 | + * Command line was: qdbusxml2cpp -p freedesktop_objectmanager -i bluez_helper.h -v -c DBusObjectManagerInterface org.freedesktop.DBus.ObjectManager.xml |
2844 | + * |
2845 | + * qdbusxml2cpp is Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies). |
2846 | + * |
2847 | + * This is an auto-generated file. |
2848 | + * Do not edit! All changes made to it will be lost. |
2849 | + */ |
2850 | + |
2851 | +#ifndef FREEDESKTOP_OBJECTMANAGER_H_1442473386 |
2852 | +#define FREEDESKTOP_OBJECTMANAGER_H_1442473386 |
2853 | + |
2854 | +#include <QtCore/QObject> |
2855 | +#include <QtCore/QByteArray> |
2856 | +#include <QtCore/QList> |
2857 | +#include <QtCore/QMap> |
2858 | +#include <QtCore/QString> |
2859 | +#include <QtCore/QStringList> |
2860 | +#include <QtCore/QVariant> |
2861 | +#include <QtDBus/QtDBus> |
2862 | +#include "bluez_helper.h" |
2863 | + |
2864 | +/* |
2865 | + * Proxy class for interface org.freedesktop.DBus.ObjectManager |
2866 | + */ |
2867 | +class DBusObjectManagerInterface: public QDBusAbstractInterface |
2868 | +{ |
2869 | + Q_OBJECT |
2870 | +public: |
2871 | + static inline const char *staticInterfaceName() |
2872 | + { return "org.freedesktop.DBus.ObjectManager"; } |
2873 | + |
2874 | +public: |
2875 | + DBusObjectManagerInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0); |
2876 | + |
2877 | + ~DBusObjectManagerInterface(); |
2878 | + |
2879 | +public Q_SLOTS: // METHODS |
2880 | + inline QDBusPendingReply<ManagedObjectList> GetManagedObjects() |
2881 | + { |
2882 | + QList<QVariant> argumentList; |
2883 | + return asyncCallWithArgumentList(QStringLiteral("GetManagedObjects"), argumentList); |
2884 | + } |
2885 | + |
2886 | +Q_SIGNALS: // SIGNALS |
2887 | + void InterfacesAdded(const QDBusObjectPath &object_path, InterfaceList interfaces_and_properties); |
2888 | + void InterfacesRemoved(const QDBusObjectPath &object_path, const QStringList &interfaces); |
2889 | +}; |
2890 | + |
2891 | +namespace org { |
2892 | + namespace freedesktop { |
2893 | + namespace DBus { |
2894 | + typedef ::DBusObjectManagerInterface ObjectManager; |
2895 | + } |
2896 | + } |
2897 | +} |
2898 | +#endif |
2899 | |
2900 | === added file 'plugins/bluetooth/freedesktop_properties.cpp' |
2901 | --- plugins/bluetooth/freedesktop_properties.cpp 1970-01-01 00:00:00 +0000 |
2902 | +++ plugins/bluetooth/freedesktop_properties.cpp 2015-11-20 08:48:08 +0000 |
2903 | @@ -0,0 +1,26 @@ |
2904 | +/* |
2905 | + * This file was generated by qdbusxml2cpp version 0.8 |
2906 | + * Command line was: qdbusxml2cpp -c FreeDesktopProperties -p freedesktop_properties -v org.freedesktop.DBus.Properties.xml |
2907 | + * |
2908 | + * qdbusxml2cpp is Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies). |
2909 | + * |
2910 | + * This is an auto-generated file. |
2911 | + * This file may have been hand-edited. Look for HAND-EDIT comments |
2912 | + * before re-generating it. |
2913 | + */ |
2914 | + |
2915 | +#include "freedesktop_properties.h" |
2916 | + |
2917 | +/* |
2918 | + * Implementation of interface class FreeDesktopProperties |
2919 | + */ |
2920 | + |
2921 | +FreeDesktopProperties::FreeDesktopProperties(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent) |
2922 | + : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent) |
2923 | +{ |
2924 | +} |
2925 | + |
2926 | +FreeDesktopProperties::~FreeDesktopProperties() |
2927 | +{ |
2928 | +} |
2929 | + |
2930 | |
2931 | === added file 'plugins/bluetooth/freedesktop_properties.h' |
2932 | --- plugins/bluetooth/freedesktop_properties.h 1970-01-01 00:00:00 +0000 |
2933 | +++ plugins/bluetooth/freedesktop_properties.h 2015-11-20 08:48:08 +0000 |
2934 | @@ -0,0 +1,71 @@ |
2935 | +/* |
2936 | + * This file was generated by qdbusxml2cpp version 0.8 |
2937 | + * Command line was: qdbusxml2cpp -c FreeDesktopProperties -p freedesktop_properties -v org.freedesktop.DBus.Properties.xml |
2938 | + * |
2939 | + * qdbusxml2cpp is Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies). |
2940 | + * |
2941 | + * This is an auto-generated file. |
2942 | + * Do not edit! All changes made to it will be lost. |
2943 | + */ |
2944 | + |
2945 | +#ifndef FREEDESKTOP_PROPERTIES_H_1442473392 |
2946 | +#define FREEDESKTOP_PROPERTIES_H_1442473392 |
2947 | + |
2948 | +#include <QtCore/QObject> |
2949 | +#include <QtCore/QByteArray> |
2950 | +#include <QtCore/QList> |
2951 | +#include <QtCore/QMap> |
2952 | +#include <QtCore/QString> |
2953 | +#include <QtCore/QStringList> |
2954 | +#include <QtCore/QVariant> |
2955 | +#include <QtDBus/QtDBus> |
2956 | + |
2957 | +/* |
2958 | + * Proxy class for interface org.freedesktop.DBus.Properties |
2959 | + */ |
2960 | +class FreeDesktopProperties: public QDBusAbstractInterface |
2961 | +{ |
2962 | + Q_OBJECT |
2963 | +public: |
2964 | + static inline const char *staticInterfaceName() |
2965 | + { return "org.freedesktop.DBus.Properties"; } |
2966 | + |
2967 | +public: |
2968 | + FreeDesktopProperties(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0); |
2969 | + |
2970 | + ~FreeDesktopProperties(); |
2971 | + |
2972 | +public Q_SLOTS: // METHODS |
2973 | + inline QDBusPendingReply<QDBusVariant> Get(const QString &interface, const QString &name) |
2974 | + { |
2975 | + QList<QVariant> argumentList; |
2976 | + argumentList << QVariant::fromValue(interface) << QVariant::fromValue(name); |
2977 | + return asyncCallWithArgumentList(QStringLiteral("Get"), argumentList); |
2978 | + } |
2979 | + |
2980 | + inline QDBusPendingReply<QVariantMap> GetAll(const QString &interface) |
2981 | + { |
2982 | + QList<QVariant> argumentList; |
2983 | + argumentList << QVariant::fromValue(interface); |
2984 | + return asyncCallWithArgumentList(QStringLiteral("GetAll"), argumentList); |
2985 | + } |
2986 | + |
2987 | + inline QDBusPendingReply<> Set(const QString &interface, const QString &name, const QDBusVariant &value) |
2988 | + { |
2989 | + QList<QVariant> argumentList; |
2990 | + argumentList << QVariant::fromValue(interface) << QVariant::fromValue(name) << QVariant::fromValue(value); |
2991 | + return asyncCallWithArgumentList(QStringLiteral("Set"), argumentList); |
2992 | + } |
2993 | + |
2994 | +Q_SIGNALS: // SIGNALS |
2995 | + void PropertiesChanged(const QString &interface, const QVariantMap &changed_properties, const QStringList &invalidated_properties); |
2996 | +}; |
2997 | + |
2998 | +namespace org { |
2999 | + namespace freedesktop { |
3000 | + namespace DBus { |
3001 | + typedef ::FreeDesktopProperties Properties; |
3002 | + } |
3003 | + } |
3004 | +} |
3005 | +#endif |
3006 | |
3007 | === added file 'plugins/bluetooth/org.bluez.Adapter1.xml' |
3008 | --- plugins/bluetooth/org.bluez.Adapter1.xml 1970-01-01 00:00:00 +0000 |
3009 | +++ plugins/bluetooth/org.bluez.Adapter1.xml 2015-11-20 08:48:08 +0000 |
3010 | @@ -0,0 +1,11 @@ |
3011 | +<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" |
3012 | + "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> |
3013 | +<node> |
3014 | + <interface name="org.bluez.Adapter1"> |
3015 | + <method name="StartDiscovery"></method> |
3016 | + <method name="StopDiscovery"></method> |
3017 | + <method name="RemoveDevice"> |
3018 | + <arg name="device" type="o" direction="in"/> |
3019 | + </method> |
3020 | + </interface> |
3021 | +</node> |
3022 | |
3023 | === added file 'plugins/bluetooth/org.bluez.Agent1.xml' |
3024 | --- plugins/bluetooth/org.bluez.Agent1.xml 1970-01-01 00:00:00 +0000 |
3025 | +++ plugins/bluetooth/org.bluez.Agent1.xml 2015-11-20 08:48:08 +0000 |
3026 | @@ -0,0 +1,55 @@ |
3027 | +<?xml version="1.0" encoding="UTF-8" ?> |
3028 | + |
3029 | +<node name="/"> |
3030 | + <interface name="org.bluez.Agent1"> |
3031 | + <method name="RequestPinCode"> |
3032 | + <annotation name="org.freedesktop.DBus.GLib.Async" value=""/> |
3033 | + <arg type="o" name="device"/> |
3034 | + <arg type="s" name="pincode" direction="out"/> |
3035 | + </method> |
3036 | + |
3037 | + <method name="DisplayPinCode"> |
3038 | + <annotation name="org.freedesktop.DBus.GLib.Async" value=""/> |
3039 | + <arg type="o" name="device"/> |
3040 | + <arg type="s" name="pincode"/> |
3041 | + </method> |
3042 | + |
3043 | + <method name="RequestPasskey"> |
3044 | + <annotation name="org.freedesktop.DBus.GLib.Async" value=""/> |
3045 | + <arg type="o" name="device"/> |
3046 | + <arg type="u" name="passkey" direction="out"/> |
3047 | + </method> |
3048 | + |
3049 | + <method name="DisplayPasskey"> |
3050 | + <annotation name="org.freedesktop.DBus.GLib.Async" value=""/> |
3051 | + <arg type="o" name="device"/> |
3052 | + <arg type="u" name="passkey"/> |
3053 | + <arg type="q" name="entered"/> |
3054 | + </method> |
3055 | + |
3056 | + <method name="RequestConfirmation"> |
3057 | + <annotation name="org.freedesktop.DBus.GLib.Async" value=""/> |
3058 | + <arg type="o" name="device"/> |
3059 | + <arg type="u" name="passkey"/> |
3060 | + </method> |
3061 | + |
3062 | + <method name="RequestAuthorization"> |
3063 | + <annotation name="org.freedesktop.DBus.GLib.Async" value=""/> |
3064 | + <arg type="o" name="device"/> |
3065 | + </method> |
3066 | + |
3067 | + <method name="AuthorizeService"> |
3068 | + <annotation name="org.freedesktop.DBus.GLib.Async" value=""/> |
3069 | + <arg type="o" name="device"/> |
3070 | + <arg type="s" name="uuid"/> |
3071 | + </method> |
3072 | + |
3073 | + <method name="Cancel"> |
3074 | + <annotation name="org.freedesktop.DBus.GLib.Async" value=""/> |
3075 | + </method> |
3076 | + |
3077 | + <method name="Release"> |
3078 | + <annotation name="org.freedesktop.DBus.GLib.Async" value=""/> |
3079 | + </method> |
3080 | + </interface> |
3081 | +</node> |
3082 | |
3083 | === added file 'plugins/bluetooth/org.bluez.AgentManager1.xml' |
3084 | --- plugins/bluetooth/org.bluez.AgentManager1.xml 1970-01-01 00:00:00 +0000 |
3085 | +++ plugins/bluetooth/org.bluez.AgentManager1.xml 2015-11-20 08:48:08 +0000 |
3086 | @@ -0,0 +1,16 @@ |
3087 | +<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" |
3088 | + "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> |
3089 | +<node> |
3090 | + <interface name="org.bluez.AgentManager1"> |
3091 | + <method name="RegisterAgent"> |
3092 | + <arg type="o" name="agent"/> |
3093 | + <arg type="s" name="capability"/> |
3094 | + </method> |
3095 | + <method name="UnregisterAgent"> |
3096 | + <arg type="o" name="agent"/> |
3097 | + </method> |
3098 | + <method name="RequestDefaultAgent"> |
3099 | + <arg type="o" name="agent"/> |
3100 | + </method> |
3101 | + </interface> |
3102 | +</node> |
3103 | |
3104 | === added file 'plugins/bluetooth/org.bluez.Device1.xml' |
3105 | --- plugins/bluetooth/org.bluez.Device1.xml 1970-01-01 00:00:00 +0000 |
3106 | +++ plugins/bluetooth/org.bluez.Device1.xml 2015-11-20 08:48:08 +0000 |
3107 | @@ -0,0 +1,16 @@ |
3108 | +<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" |
3109 | + "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> |
3110 | +<node> |
3111 | + <interface name="org.bluez.Device1"> |
3112 | + <method name="Disconnect"></method> |
3113 | + <method name="Connect"></method> |
3114 | + <method name="ConnectProfile"> |
3115 | + <arg name="UUID" type="s" direction="in"/> |
3116 | + </method> |
3117 | + <method name="DisconnectProfile"> |
3118 | + <arg name="UUID" type="s" direction="in"/> |
3119 | + </method> |
3120 | + <method name="Pair"></method> |
3121 | + <method name="CancelPairing"></method> |
3122 | + </interface> |
3123 | +</node> |
3124 | |
3125 | === added file 'plugins/bluetooth/org.freedesktop.DBus.ObjectManager.xml' |
3126 | --- plugins/bluetooth/org.freedesktop.DBus.ObjectManager.xml 1970-01-01 00:00:00 +0000 |
3127 | +++ plugins/bluetooth/org.freedesktop.DBus.ObjectManager.xml 2015-11-20 08:48:08 +0000 |
3128 | @@ -0,0 +1,19 @@ |
3129 | +<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" |
3130 | + "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> |
3131 | +<node name="/" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0"> |
3132 | + <interface name="org.freedesktop.DBus.ObjectManager"> |
3133 | + <method name="GetManagedObjects"> |
3134 | + <arg type="a{oa{sa{sv}}}" name="object_paths_interfaces_and_properties" direction="out"/> |
3135 | + <annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="ManagedObjectList"/> |
3136 | + </method> |
3137 | + <signal name="InterfacesAdded"> |
3138 | + <arg type="o" name="object_path"/> |
3139 | + <arg type="a{sa{sv}}" name="interfaces_and_properties"/> |
3140 | + <annotation name="org.qtproject.QtDBus.QtTypeName.In1" value="InterfaceList"/> |
3141 | + </signal> |
3142 | + <signal name="InterfacesRemoved"> |
3143 | + <arg type="o" name="object_path"/> |
3144 | + <arg type="as" name="interfaces"/> |
3145 | + </signal> |
3146 | + </interface> |
3147 | +</node> |
3148 | |
3149 | === added file 'plugins/bluetooth/org.freedesktop.DBus.Properties.xml' |
3150 | --- plugins/bluetooth/org.freedesktop.DBus.Properties.xml 1970-01-01 00:00:00 +0000 |
3151 | +++ plugins/bluetooth/org.freedesktop.DBus.Properties.xml 2015-11-20 08:48:08 +0000 |
3152 | @@ -0,0 +1,27 @@ |
3153 | +<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" |
3154 | + "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> |
3155 | +<node> |
3156 | + <interface name="org.freedesktop.DBus.Properties"> |
3157 | + <method name="Get"> |
3158 | + <arg name="interface" type="s" direction="in"/> |
3159 | + <arg name="name" type="s" direction="in"/> |
3160 | + <arg name="value" type="v" direction="out"/> |
3161 | + </method> |
3162 | + <method name="Set"> |
3163 | + <arg name="interface" type="s" direction="in"/> |
3164 | + <arg name="name" type="s" direction="in"/> |
3165 | + <arg name="value" type="v" direction="in"/> |
3166 | + </method> |
3167 | + <method name="GetAll"> |
3168 | + <arg name="interface" type="s" direction="in"/> |
3169 | + <arg name="properties" type="a{sv}" direction="out"/> |
3170 | + <annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="QVariantMap"/> |
3171 | + </method> |
3172 | + <signal name="PropertiesChanged"> |
3173 | + <arg name="interface" type="s"/> |
3174 | + <arg name="changed_properties" type="a{sv}"/> |
3175 | + <annotation name="org.qtproject.QtDBus.QtTypeName.In1" value="QVariantMap"/> |
3176 | + <arg name="invalidated_properties" type="as"/> |
3177 | + </signal> |
3178 | + </interface> |
3179 | +</node> |
3180 | |
3181 | === modified file 'plugins/bluetooth/plugin.cpp' |
3182 | --- plugins/bluetooth/plugin.cpp 2015-08-28 09:32:38 +0000 |
3183 | +++ plugins/bluetooth/plugin.cpp 2015-11-20 08:48:08 +0000 |
3184 | @@ -24,11 +24,17 @@ |
3185 | #include <QtQml/QQmlContext> |
3186 | #include "bluetooth.h" |
3187 | #include "device.h" |
3188 | +#include "bluez_helper.h" |
3189 | |
3190 | void BackendPlugin::registerTypes(const char *uri) |
3191 | { |
3192 | Q_ASSERT(uri == QLatin1String("Ubuntu.SystemSettings.Bluetooth")); |
3193 | |
3194 | + // Register additional QtDBus types we need |
3195 | + qDBusRegisterMetaType<InterfaceList>(); |
3196 | + qDBusRegisterMetaType<ManagedObjectList>(); |
3197 | + |
3198 | + // .. now register our real QML types |
3199 | qmlRegisterType<Bluetooth>(uri, 1, 0, "UbuntuBluetoothPanel"); |
3200 | qmlRegisterType<Device>(uri, 1, 0, "Device"); |
3201 | qmlRegisterType<Device>(uri, 1, 0, "Agent"); |
3202 | |
3203 | === modified file 'tests/plugins/bluetooth/CMakeLists.txt' |
3204 | --- tests/plugins/bluetooth/CMakeLists.txt 2014-07-29 20:45:24 +0000 |
3205 | +++ tests/plugins/bluetooth/CMakeLists.txt 2015-11-20 08:48:08 +0000 |
3206 | @@ -4,14 +4,23 @@ |
3207 | include_directories(${QTDBUSTEST_INCLUDE_DIRS}) |
3208 | add_definitions(-DTESTS) |
3209 | |
3210 | +set(PLUGIN_SOURCES |
3211 | + ${CMAKE_SOURCE_DIR}/plugins/bluetooth/bluetooth.cpp |
3212 | + ${CMAKE_SOURCE_DIR}/plugins/bluetooth/devicemodel.cpp |
3213 | + ${CMAKE_SOURCE_DIR}/plugins/bluetooth/device.cpp |
3214 | + ${CMAKE_SOURCE_DIR}/plugins/bluetooth/agent.cpp |
3215 | + ${CMAKE_SOURCE_DIR}/plugins/bluetooth/bluez_agent1adaptor.cpp |
3216 | + ${CMAKE_SOURCE_DIR}/plugins/bluetooth/bluez_agentmanager1.cpp |
3217 | + ${CMAKE_SOURCE_DIR}/plugins/bluetooth/bluez_device1.cpp |
3218 | + ${CMAKE_SOURCE_DIR}/plugins/bluetooth/bluez_adapter1.cpp |
3219 | + ${CMAKE_SOURCE_DIR}/plugins/bluetooth/freedesktop_objectmanager.cpp |
3220 | + ${CMAKE_SOURCE_DIR}/plugins/bluetooth/freedesktop_properties.cpp |
3221 | +) |
3222 | + |
3223 | add_executable(tst-bluetooth |
3224 | tst_bluetooth.cpp |
3225 | fakebluez.cpp |
3226 | - ${CMAKE_SOURCE_DIR}/plugins/bluetooth/bluetooth.cpp |
3227 | - ${CMAKE_SOURCE_DIR}/plugins/bluetooth/devicemodel.cpp |
3228 | - ${CMAKE_SOURCE_DIR}/plugins/bluetooth/device.cpp |
3229 | - ${CMAKE_SOURCE_DIR}/plugins/bluetooth/agent.cpp |
3230 | - ${CMAKE_SOURCE_DIR}/plugins/bluetooth/agentadaptor.cpp |
3231 | + ${PLUGIN_SOURCES} |
3232 | ) |
3233 | |
3234 | target_link_libraries(tst-bluetooth |
3235 | @@ -22,11 +31,7 @@ |
3236 | add_executable(tst-bluetooth-devicemodel |
3237 | tst_devicemodel.cpp |
3238 | fakebluez.cpp |
3239 | - ${CMAKE_SOURCE_DIR}/plugins/bluetooth/bluetooth.cpp |
3240 | - ${CMAKE_SOURCE_DIR}/plugins/bluetooth/devicemodel.cpp |
3241 | - ${CMAKE_SOURCE_DIR}/plugins/bluetooth/device.cpp |
3242 | - ${CMAKE_SOURCE_DIR}/plugins/bluetooth/agent.cpp |
3243 | - ${CMAKE_SOURCE_DIR}/plugins/bluetooth/agentadaptor.cpp |
3244 | + ${PLUGIN_SOURCES} |
3245 | ) |
3246 | |
3247 | target_link_libraries(tst-bluetooth-devicemodel |
3248 | @@ -35,13 +40,9 @@ |
3249 | ) |
3250 | |
3251 | add_executable(tst-bluetooth-device |
3252 | - tst_devicemodel.cpp |
3253 | + tst_device.cpp |
3254 | fakebluez.cpp |
3255 | - ${CMAKE_SOURCE_DIR}/plugins/bluetooth/bluetooth.cpp |
3256 | - ${CMAKE_SOURCE_DIR}/plugins/bluetooth/devicemodel.cpp |
3257 | - ${CMAKE_SOURCE_DIR}/plugins/bluetooth/device.cpp |
3258 | - ${CMAKE_SOURCE_DIR}/plugins/bluetooth/agent.cpp |
3259 | - ${CMAKE_SOURCE_DIR}/plugins/bluetooth/agentadaptor.cpp |
3260 | + ${PLUGIN_SOURCES} |
3261 | ) |
3262 | |
3263 | target_link_libraries(tst-bluetooth-device |
3264 | |
3265 | === modified file 'tests/plugins/bluetooth/fakebluez.cpp' |
3266 | --- tests/plugins/bluetooth/fakebluez.cpp 2014-07-29 20:53:16 +0000 |
3267 | +++ tests/plugins/bluetooth/fakebluez.cpp 2015-11-20 08:48:08 +0000 |
3268 | @@ -29,7 +29,7 @@ |
3269 | { |
3270 | DBusMock::registerMetaTypes(); |
3271 | |
3272 | - m_dbusMock.registerTemplate(BLUEZ_SERVICE, "bluez4", |
3273 | + m_dbusMock.registerTemplate(BLUEZ_SERVICE, "bluez5", |
3274 | QDBusConnection::SystemBus); |
3275 | m_dbusTestRunner.startServices(); |
3276 | |
3277 | @@ -75,13 +75,49 @@ |
3278 | return reply.isValid() ? reply.value() : QString(); |
3279 | } |
3280 | |
3281 | +void |
3282 | +FakeBluez::pairDevice(const QString &address) |
3283 | +{ |
3284 | + QDBusReply<void> reply = m_bluezMock->call("PairDevice", |
3285 | + m_currentAdapter, |
3286 | + address); |
3287 | + |
3288 | + if (!reply.isValid()) { |
3289 | + qWarning() << "Failed to pair mock device:" << reply.error().message(); |
3290 | + } |
3291 | +} |
3292 | + |
3293 | +void |
3294 | +FakeBluez::connectDevice(const QString &address) |
3295 | +{ |
3296 | + QDBusReply<void> reply = m_bluezMock->call("ConnectDevice", |
3297 | + m_currentAdapter, |
3298 | + address); |
3299 | + |
3300 | + if (!reply.isValid()) { |
3301 | + qWarning() << "Failed to connect mock device:" << reply.error().message(); |
3302 | + } |
3303 | +} |
3304 | + |
3305 | +void |
3306 | +FakeBluez::disconnectDevice(const QString &address) |
3307 | +{ |
3308 | + QDBusReply<void> reply = m_bluezMock->call("DisconnectDevice", |
3309 | + m_currentAdapter, |
3310 | + address); |
3311 | + |
3312 | + if (!reply.isValid()) { |
3313 | + qWarning() << "Failed to disconnect mock device:" << reply.error().message(); |
3314 | + } |
3315 | +} |
3316 | + |
3317 | QVariant |
3318 | FakeBluez::getProperty(const QString &path, |
3319 | const QString &interface, |
3320 | const QString &property) |
3321 | { |
3322 | QDBusInterface iface(BLUEZ_SERVICE, path, |
3323 | - "org.freedesktop.DBus.Properties", |
3324 | + FREEDESKTOP_PROPERTIES_IFACE, |
3325 | m_dbusTestRunner.systemConnection()); |
3326 | |
3327 | QDBusReply<QVariant> reply = iface.call("Get", interface, property); |
3328 | @@ -103,10 +139,11 @@ |
3329 | const QVariant &value) |
3330 | { |
3331 | QDBusInterface iface(BLUEZ_SERVICE, path, |
3332 | - interface, |
3333 | + FREEDESKTOP_PROPERTIES_IFACE, |
3334 | m_dbusTestRunner.systemConnection()); |
3335 | |
3336 | - QDBusReply<void> reply = iface.call("SetProperty", |
3337 | + QDBusReply<void> reply = iface.call("Set", |
3338 | + interface, |
3339 | property, value); |
3340 | |
3341 | if (!reply.isValid()) { |
3342 | |
3343 | === modified file 'tests/plugins/bluetooth/fakebluez.h' |
3344 | --- tests/plugins/bluetooth/fakebluez.h 2014-07-29 20:53:16 +0000 |
3345 | +++ tests/plugins/bluetooth/fakebluez.h 2015-11-20 08:48:08 +0000 |
3346 | @@ -32,10 +32,10 @@ |
3347 | #define BLUEZ_MAIN_OBJECT "/" |
3348 | #define BLUEZ_MOCK_IFACE "org.bluez.Mock" |
3349 | |
3350 | -#define BLUEZ_MANAGER_IFACE "org.bluez.Manager" |
3351 | -#define BLUEZ_ADAPTER_IFACE "org.bluez.Adapter" |
3352 | -#define BLUEZ_DEVICE_IFACE "org.bluez.Device" |
3353 | -#define BLUEZ_AUDIO_IFACE "org.bluez.Audio" |
3354 | +#define BLUEZ_ADAPTER_IFACE "org.bluez.Adapter1" |
3355 | +#define BLUEZ_DEVICE_IFACE "org.bluez.Device1" |
3356 | + |
3357 | +#define FREEDESKTOP_PROPERTIES_IFACE "org.freedesktop.DBus.Properties" |
3358 | |
3359 | using namespace QtDBusTest; |
3360 | using namespace QtDBusMock; |
3361 | @@ -61,17 +61,20 @@ |
3362 | |
3363 | ~FakeBluez(); |
3364 | |
3365 | - const QString currentAdapter() { return m_currentAdapter; } |
3366 | + const QString currentAdapterPath() { return QString("/org/bluez/%1").arg(m_currentAdapter); } |
3367 | const QList<QString> devices() { return m_devices; } |
3368 | const QDBusConnection & dbus() { return m_dbusTestRunner.systemConnection(); } |
3369 | |
3370 | QString addAdapter(const QString &name, const QString &system_name); |
3371 | QString addDevice(const QString &name, const QString &address); |
3372 | + void pairDevice(const QString &address); |
3373 | + void connectDevice(const QString &address); |
3374 | + void disconnectDevice(const QString &address); |
3375 | |
3376 | QVariant getProperty(const QString &path, |
3377 | const QString &interface, |
3378 | const QString &property); |
3379 | - |
3380 | + |
3381 | void setProperty(const QString &path, |
3382 | const QString &interface, |
3383 | const QString &property, |
3384 | |
3385 | === modified file 'tests/plugins/bluetooth/tst_bluetooth.cpp' |
3386 | --- tests/plugins/bluetooth/tst_bluetooth.cpp 2015-02-10 11:19:53 +0000 |
3387 | +++ tests/plugins/bluetooth/tst_bluetooth.cpp 2015-11-20 08:48:08 +0000 |
3388 | @@ -23,6 +23,7 @@ |
3389 | #include "bluetooth.h" |
3390 | #include "device.h" |
3391 | #include "agent.h" |
3392 | +#include "bluez_helper.h" |
3393 | #include "fakebluez.h" |
3394 | |
3395 | using namespace Bluez; |
3396 | @@ -36,6 +37,9 @@ |
3397 | Bluetooth *m_bluetooth; |
3398 | QDBusConnection *m_dbus; |
3399 | |
3400 | + void processEvents(unsigned int msecs = 500); |
3401 | + void setDiscovering(bool value); |
3402 | + |
3403 | private Q_SLOTS: |
3404 | void init(); |
3405 | void testGotAdapter(); |
3406 | @@ -48,16 +52,38 @@ |
3407 | |
3408 | }; |
3409 | |
3410 | +void BluetoothTest::processEvents(unsigned int msecs) |
3411 | +{ |
3412 | + QTimer::singleShot(msecs, [=]() { QCoreApplication::instance()->exit(); }); |
3413 | + QCoreApplication::instance()->exec(); |
3414 | +} |
3415 | + |
3416 | +void BluetoothTest::setDiscovering(bool value) |
3417 | +{ |
3418 | + m_bluezMock->setProperty(m_bluezMock->currentAdapterPath(), |
3419 | + BLUEZ_ADAPTER_IFACE, |
3420 | + "Discovering", |
3421 | + QVariant(value)); |
3422 | +} |
3423 | + |
3424 | void BluetoothTest::init() |
3425 | { |
3426 | + qWarning() << "init test"; |
3427 | + |
3428 | + qDBusRegisterMetaType<InterfaceList>(); |
3429 | + qDBusRegisterMetaType<ManagedObjectList>(); |
3430 | + |
3431 | m_bluezMock = new FakeBluez(); |
3432 | m_bluezMock->addAdapter("new0", "bluetoothTest"); |
3433 | m_dbus = new QDBusConnection(m_bluezMock->dbus()); |
3434 | m_bluetooth = new Bluetooth(*m_dbus); |
3435 | + |
3436 | + processEvents(); |
3437 | } |
3438 | |
3439 | void BluetoothTest::cleanup() |
3440 | { |
3441 | + qWarning() << "cleanup"; |
3442 | delete m_bluezMock; |
3443 | delete m_bluetooth; |
3444 | } |
3445 | @@ -67,6 +93,8 @@ |
3446 | QString expected = "bluetoothTest"; |
3447 | QString result; |
3448 | |
3449 | + processEvents(); |
3450 | + |
3451 | result = m_bluetooth->adapterName(); |
3452 | |
3453 | QCOMPARE(result, expected); |
3454 | @@ -74,70 +102,100 @@ |
3455 | |
3456 | void BluetoothTest::testStartDiscovery() |
3457 | { |
3458 | - bool expected = true; |
3459 | QVariant result; |
3460 | |
3461 | - QSKIP("Fails due to a bug in bluez4 dbusmock template", SkipAll); |
3462 | + // This is what our test expects the adapter to have set |
3463 | + setDiscovering(false); |
3464 | + processEvents(); |
3465 | |
3466 | - result = m_bluezMock->getProperty(m_bluezMock->currentAdapter(), |
3467 | - "org.bluez.Adapter", |
3468 | + result = m_bluezMock->getProperty(m_bluezMock->currentAdapterPath(), |
3469 | + BLUEZ_ADAPTER_IFACE, |
3470 | "Discovering"); |
3471 | qWarning() << result; |
3472 | - QCOMPARE(result.toBool(), !expected); |
3473 | + QCOMPARE(result.toBool(), false); |
3474 | |
3475 | m_bluetooth->startDiscovery(); |
3476 | - |
3477 | - result = m_bluezMock->getProperty(m_bluezMock->currentAdapter(), |
3478 | - "org.bluez.Adapter", |
3479 | + setDiscovering(true); |
3480 | + |
3481 | + processEvents(); |
3482 | + |
3483 | + result = m_bluezMock->getProperty(m_bluezMock->currentAdapterPath(), |
3484 | + BLUEZ_ADAPTER_IFACE, |
3485 | "Discovering"); |
3486 | qWarning() << result; |
3487 | - QCOMPARE(result.toBool(), expected); |
3488 | + QCOMPARE(result.toBool(), true); |
3489 | } |
3490 | |
3491 | void BluetoothTest::testStopDiscovery() |
3492 | { |
3493 | - bool expected = false; |
3494 | QVariant result; |
3495 | |
3496 | - QSKIP("Fails due to a bug in bluez4 dbusmock template", SkipAll); |
3497 | + // This is what our test expects the adapter to have set |
3498 | + setDiscovering(true); |
3499 | + processEvents(); |
3500 | |
3501 | - result = m_bluezMock->getProperty(m_bluezMock->currentAdapter(), |
3502 | - "org.bluez.Adapter", |
3503 | + result = m_bluezMock->getProperty(m_bluezMock->currentAdapterPath(), |
3504 | + BLUEZ_ADAPTER_IFACE, |
3505 | "Discovering"); |
3506 | - QCOMPARE(result.toBool(), !expected); |
3507 | + QCOMPARE(result.toBool(), true); |
3508 | |
3509 | m_bluetooth->stopDiscovery(); |
3510 | - |
3511 | - result = m_bluezMock->getProperty(m_bluezMock->currentAdapter(), |
3512 | - "org.bluez.Adapter", |
3513 | + setDiscovering(false); |
3514 | + |
3515 | + processEvents(); |
3516 | + |
3517 | + result = m_bluezMock->getProperty(m_bluezMock->currentAdapterPath(), |
3518 | + BLUEZ_ADAPTER_IFACE, |
3519 | "Discovering"); |
3520 | - QCOMPARE(result.toBool(), expected); |
3521 | + QCOMPARE(result.toBool(), false); |
3522 | } |
3523 | |
3524 | +/* |
3525 | + * NOTE: The bluez5 mock template currently doesn't send PropertiesChanged |
3526 | + * events when StartDiscovery/StopDiscovery is called on the adapter interface. |
3527 | + * To accomondate this we're calling the org.freedesktop.DBus.Properties.Set |
3528 | + * method here manually to simulate a property change. However this means |
3529 | + * that other than doing a dumb call to StartDiscovery/StopDiscovery nothing |
3530 | + * else will happen when those methods are called of the Bluetooth class we're |
3531 | + * testing here. |
3532 | + * |
3533 | + * This affects the following tested methods: |
3534 | + * - Bluetooth::startDiscovering |
3535 | + * - Bluetooth::stopDiscovery |
3536 | + * - Bluetooth::toggleDiscovery |
3537 | + */ |
3538 | + |
3539 | void BluetoothTest::testToggleDiscovery() |
3540 | { |
3541 | QVariant result; |
3542 | |
3543 | - QSKIP("Fails due to a bug in bluez4 dbusmock template", SkipAll); |
3544 | - |
3545 | m_bluetooth->stopDiscovery(); |
3546 | - |
3547 | - result = m_bluezMock->getProperty(m_bluezMock->currentAdapter(), |
3548 | - "org.bluez.Adapter", |
3549 | + setDiscovering(false); |
3550 | + |
3551 | + processEvents(); |
3552 | + |
3553 | + result = m_bluezMock->getProperty(m_bluezMock->currentAdapterPath(), |
3554 | + BLUEZ_ADAPTER_IFACE, |
3555 | "Discovering"); |
3556 | QCOMPARE(result.toBool(), false); |
3557 | |
3558 | m_bluetooth->toggleDiscovery(); |
3559 | - |
3560 | - result = m_bluezMock->getProperty(m_bluezMock->currentAdapter(), |
3561 | - "org.bluez.Adapter", |
3562 | + setDiscovering(true); |
3563 | + |
3564 | + processEvents(); |
3565 | + |
3566 | + result = m_bluezMock->getProperty(m_bluezMock->currentAdapterPath(), |
3567 | + BLUEZ_ADAPTER_IFACE, |
3568 | "Discovering"); |
3569 | QCOMPARE(result.toBool(), true); |
3570 | |
3571 | m_bluetooth->toggleDiscovery(); |
3572 | - |
3573 | - result = m_bluezMock->getProperty(m_bluezMock->currentAdapter(), |
3574 | - "org.bluez.Adapter", |
3575 | + setDiscovering(false); |
3576 | + |
3577 | + processEvents(); |
3578 | + |
3579 | + result = m_bluezMock->getProperty(m_bluezMock->currentAdapterPath(), |
3580 | + BLUEZ_ADAPTER_IFACE, |
3581 | "Discovering"); |
3582 | QCOMPARE(result.toBool(), false); |
3583 | } |
3584 | @@ -149,21 +207,34 @@ |
3585 | QCOMPARE(Bluetooth::isSupportedType(Device::Type::Tablet), false); |
3586 | } |
3587 | |
3588 | + |
3589 | void BluetoothTest::testIsDiscovering() |
3590 | { |
3591 | m_bluetooth->stopDiscovery(); |
3592 | + setDiscovering(false); |
3593 | + |
3594 | + processEvents(); |
3595 | |
3596 | QCOMPARE(m_bluetooth->isDiscovering(), false); |
3597 | |
3598 | m_bluetooth->startDiscovery(); |
3599 | + setDiscovering(true); |
3600 | + |
3601 | + processEvents(); |
3602 | |
3603 | QCOMPARE(m_bluetooth->isDiscovering(), true); |
3604 | |
3605 | m_bluetooth->toggleDiscovery(); |
3606 | + setDiscovering(false); |
3607 | + |
3608 | + processEvents(); |
3609 | |
3610 | QCOMPARE(m_bluetooth->isDiscovering(), false); |
3611 | |
3612 | m_bluetooth->toggleDiscovery(); |
3613 | + setDiscovering(true); |
3614 | + |
3615 | + processEvents(); |
3616 | |
3617 | QCOMPARE(m_bluetooth->isDiscovering(), true); |
3618 | } |
3619 | |
3620 | === modified file 'tests/plugins/bluetooth/tst_device.cpp' |
3621 | --- tests/plugins/bluetooth/tst_device.cpp 2015-08-25 16:41:10 +0000 |
3622 | +++ tests/plugins/bluetooth/tst_device.cpp 2015-11-20 08:48:08 +0000 |
3623 | @@ -36,7 +36,7 @@ |
3624 | QDBusConnection *m_dbus; |
3625 | |
3626 | private: |
3627 | - void checkAudioState(const QString &expected); |
3628 | + void processEvents(unsigned int msecs = 500); |
3629 | |
3630 | private Q_SLOTS: |
3631 | void init(); |
3632 | @@ -50,16 +50,29 @@ |
3633 | void testGetStrength(); |
3634 | void testGetPath(); |
3635 | void testMakeTrusted(); |
3636 | - |
3637 | + void testConnect(); |
3638 | + void testDisconnect(); |
3639 | + |
3640 | void cleanup(); |
3641 | |
3642 | }; |
3643 | |
3644 | +void DeviceTest::processEvents(unsigned int msecs) |
3645 | +{ |
3646 | + QTimer::singleShot(msecs, [=]() { QCoreApplication::instance()->exit(); }); |
3647 | + QCoreApplication::instance()->exec(); |
3648 | +} |
3649 | + |
3650 | void DeviceTest::init() |
3651 | { |
3652 | + qDBusRegisterMetaType<InterfaceList>(); |
3653 | + qDBusRegisterMetaType<ManagedObjectList>(); |
3654 | + |
3655 | m_bluezMock = new FakeBluez(); |
3656 | m_bluezMock->addAdapter("new0", "bluetoothTest"); |
3657 | m_bluezMock->addDevice("My Phone", "00:00:de:ad:be:ef"); |
3658 | + // Only this will set the 'Class' and 'Icon' properties for the device ... |
3659 | + m_bluezMock->pairDevice("00:00:de:ad:be:ef"); |
3660 | m_dbus = new QDBusConnection(m_bluezMock->dbus()); |
3661 | |
3662 | QList<QString> devices = m_bluezMock->devices(); |
3663 | @@ -67,6 +80,8 @@ |
3664 | QFAIL("No devices in mock to be tested."); |
3665 | |
3666 | m_device = new Device(devices.first(), *m_dbus); |
3667 | + |
3668 | + processEvents(); |
3669 | } |
3670 | |
3671 | void DeviceTest::cleanup() |
3672 | @@ -77,29 +92,37 @@ |
3673 | |
3674 | void DeviceTest::testGetName() |
3675 | { |
3676 | - QCOMPARE(m_device->getName(), "My Phone"); |
3677 | -} |
3678 | - |
3679 | -void DeviceTest::testAddress() |
3680 | -{ |
3681 | - QCOMPARE(m_device->getAddress(), "00:00:de:ad:be:ef"); |
3682 | -} |
3683 | - |
3684 | -void DeviceTest::testIconName() |
3685 | -{ |
3686 | - QCOMPARE(m_device->getIconName(), "image://theme/audio-headset"); |
3687 | + QCOMPARE(m_device->getName(), QString("My Phone")); |
3688 | +} |
3689 | + |
3690 | +void DeviceTest::testGetAddress() |
3691 | +{ |
3692 | + QCOMPARE(m_device->getAddress(), QString("00:00:de:ad:be:ef")); |
3693 | +} |
3694 | + |
3695 | +void DeviceTest::testGetIconName() |
3696 | +{ |
3697 | + QCOMPARE(m_device->getIconName(), QString("image://theme/phone-smartphone-symbolic")); |
3698 | } |
3699 | |
3700 | void DeviceTest::testGetType() |
3701 | { |
3702 | - QCOMPARE(m_device->getType(), Device::Type::Headset); |
3703 | + QCOMPARE(m_device->getType(), Device::Type::Smartphone); |
3704 | } |
3705 | |
3706 | void DeviceTest::testIsPaired() |
3707 | { |
3708 | + QCOMPARE(m_device->isPaired(), true); |
3709 | + |
3710 | + m_bluezMock->setProperty("/org/bluez/new0/dev_00_00_DE_AD_BE_EF", "org.bluez.Device1", "Paired", QVariant(false)); |
3711 | + |
3712 | + processEvents(); |
3713 | + |
3714 | QCOMPARE(m_device->isPaired(), false); |
3715 | |
3716 | - m_bluezMock->setProperty("org.bluez.Device", "Paired", QVariant(true)); |
3717 | + m_bluezMock->setProperty("/org/bluez/new0/dev_00_00_DE_AD_BE_EF", "org.bluez.Device1", "Paired", QVariant(true)); |
3718 | + |
3719 | + processEvents(); |
3720 | |
3721 | QCOMPARE(m_device->isPaired(), true); |
3722 | } |
3723 | @@ -108,26 +131,28 @@ |
3724 | { |
3725 | QCOMPARE(m_device->isTrusted(), false); |
3726 | |
3727 | - m_bluezMock->setProperty("org.bluez.Device", "Trusted", QVariant(true)); |
3728 | + m_bluezMock->setProperty("/org/bluez/new0/dev_00_00_DE_AD_BE_EF", "org.bluez.Device1", "Trusted", QVariant(true)); |
3729 | + |
3730 | + processEvents(); |
3731 | |
3732 | QCOMPARE(m_device->isTrusted(), true); |
3733 | } |
3734 | |
3735 | void DeviceTest::testGetConnection() |
3736 | { |
3737 | - QCOMPARE(m_device.getConnection(), Device::Connection::Disconnected); |
3738 | + QCOMPARE(m_device->getConnection(), Device::Connection::Disconnected); |
3739 | } |
3740 | |
3741 | void DeviceTest::testGetStrength() |
3742 | { |
3743 | - QCOMPARE(m_device.getStrength(), Device::Strength::Good); |
3744 | + QCOMPARE(m_device->getStrength(), Device::Strength::Fair); |
3745 | } |
3746 | |
3747 | void DeviceTest::testGetPath() |
3748 | { |
3749 | - QCOMPARE(m_device.getPath(), |
3750 | - "/org/bluez/" + m_bluezMock->currentAdapter() + "/" |
3751 | - + "dev_00_00_de_ad_be_ef"); |
3752 | + QCOMPARE(m_device->getPath(), |
3753 | + m_bluezMock->currentAdapterPath() + "/" |
3754 | + + "dev_00_00_DE_AD_BE_EF"); |
3755 | } |
3756 | |
3757 | void DeviceTest::testMakeTrusted() |
3758 | @@ -136,52 +161,40 @@ |
3759 | |
3760 | m_device->makeTrusted(true); |
3761 | |
3762 | + processEvents(); |
3763 | + |
3764 | QCOMPARE(m_device->isTrusted(), true); |
3765 | |
3766 | m_device->makeTrusted(false); |
3767 | |
3768 | + processEvents(); |
3769 | + |
3770 | QCOMPARE(m_device->isTrusted(), false); |
3771 | } |
3772 | |
3773 | -void DeviceTest::checkAudioState(const QString &expected) |
3774 | -{ |
3775 | - QVariant state = m_bluezMock->getProperty("org.bluez.Audio", "State"); |
3776 | - |
3777 | - QVERIFY(state.type() == QMetaType::QString); |
3778 | - QCOMPARE(state.toString(), expected); |
3779 | -} |
3780 | - |
3781 | void DeviceTest::testConnect() |
3782 | { |
3783 | - testDiscoverServices(); |
3784 | - |
3785 | - m_device->connect(Device::ConnectionMode::Audio); |
3786 | - |
3787 | - checkAudioState("connected"); |
3788 | + m_device->connect(); |
3789 | + |
3790 | + m_bluezMock->connectDevice("00:00:de:ad:be:ef"); |
3791 | + |
3792 | + processEvents(); |
3793 | + |
3794 | + QCOMPARE(m_device->getConnection(), Device::Connected); |
3795 | } |
3796 | |
3797 | void DeviceTest::testDisconnect() |
3798 | { |
3799 | testConnect(); |
3800 | |
3801 | - m_device->disconnect(Device::ConnectionMode::Audio); |
3802 | - |
3803 | - checkAudioState("disconnected"); |
3804 | -} |
3805 | - |
3806 | -void DeviceTest::testConnectPending() |
3807 | -{ |
3808 | - testIsPaired(); |
3809 | - testIsTrusted(); |
3810 | - |
3811 | - m_device->addConnectAfterPairing(Device::ConnectionMode::Audio); |
3812 | - |
3813 | - checkAudioState("disconnected"); |
3814 | - |
3815 | - m_device->connectPending(); |
3816 | - |
3817 | - checkAudioState("connected"); |
3818 | -} |
3819 | - |
3820 | -QTEST_MAIN(DeviceTest); |
3821 | + m_device->disconnect(); |
3822 | + |
3823 | + m_bluezMock->disconnectDevice("00:00:de:ad:be:ef"); |
3824 | + |
3825 | + processEvents(); |
3826 | + |
3827 | + QCOMPARE(m_device->getConnection(), Device::Disconnected); |
3828 | +} |
3829 | + |
3830 | +QTEST_MAIN(DeviceTest) |
3831 | #include "tst_device.moc" |
3832 | |
3833 | === modified file 'tests/plugins/bluetooth/tst_devicemodel.cpp' |
3834 | --- tests/plugins/bluetooth/tst_devicemodel.cpp 2014-08-20 12:50:09 +0000 |
3835 | +++ tests/plugins/bluetooth/tst_devicemodel.cpp 2015-11-20 08:48:08 +0000 |
3836 | @@ -35,6 +35,9 @@ |
3837 | DeviceModel *m_devicemodel; |
3838 | QDBusConnection *m_dbus; |
3839 | |
3840 | +private: |
3841 | + void processEvents(unsigned int msecs = 500); |
3842 | + |
3843 | private Q_SLOTS: |
3844 | void init(); |
3845 | void testDeviceFoundOnStart(); |
3846 | @@ -45,15 +48,28 @@ |
3847 | |
3848 | }; |
3849 | |
3850 | +void DeviceModelTest::processEvents(unsigned int msecs) |
3851 | +{ |
3852 | + QTimer::singleShot(msecs, [=]() { QCoreApplication::instance()->exit(); }); |
3853 | + QCoreApplication::instance()->exec(); |
3854 | +} |
3855 | + |
3856 | void DeviceModelTest::init() |
3857 | { |
3858 | + qDBusRegisterMetaType<InterfaceList>(); |
3859 | + qDBusRegisterMetaType<ManagedObjectList>(); |
3860 | + |
3861 | m_bluezMock = new FakeBluez(); |
3862 | |
3863 | m_bluezMock->addAdapter("new0", "bluetoothTest"); |
3864 | m_bluezMock->addDevice("My Phone", "00:00:de:ad:be:ef"); |
3865 | + // Only this will set the 'Class' and 'Icon' properties for the device ... |
3866 | + m_bluezMock->pairDevice("00:00:de:ad:be:ef"); |
3867 | |
3868 | m_dbus = new QDBusConnection(m_bluezMock->dbus()); |
3869 | m_devicemodel = new DeviceModel(*m_dbus); |
3870 | + |
3871 | + processEvents(); |
3872 | } |
3873 | |
3874 | void DeviceModelTest::cleanup() |
3875 | @@ -64,6 +80,9 @@ |
3876 | |
3877 | void DeviceModelTest::testDeviceFoundOnStart() |
3878 | { |
3879 | + // FIXME needs to take a bit more time especially on i386 |
3880 | + processEvents(); |
3881 | + |
3882 | QCOMPARE(m_devicemodel->rowCount(), 1); |
3883 | } |
3884 |
FAILED: Continuous integration, rev:1531 jenkins. qa.ubuntu. com/job/ ubuntu- system- settings- ci/2401/ jenkins. qa.ubuntu. com/job/ generic- deb-autopilot- vivid-touch/ 4204/console jenkins. qa.ubuntu. com/job/ ubuntu- system- settings- vivid-amd64- ci/176/ console jenkins. qa.ubuntu. com/job/ ubuntu- system- settings- vivid-i386- ci/585/ console jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- vivid-armhf/ 4201/console
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/ubuntu- system- settings- ci/2401/ rebuild
http://