summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Sturmlechner <asturm@gentoo.org>2017-05-28 11:20:52 +0200
committerAndreas Sturmlechner <asturm@gentoo.org>2017-05-28 11:21:35 +0200
commitd66a61b41dd7cdd605574882febfeccc4a6f292a (patch)
tree477a761dfa47a2e7351411171ef475116f8521a1 /kde-frameworks
parentprofiles: Add torque-2.5 license to MISC-FREE group. (diff)
downloadgentoo-d66a61b41dd7cdd605574882febfeccc4a6f292a.tar.gz
gentoo-d66a61b41dd7cdd605574882febfeccc4a6f292a.tar.bz2
gentoo-d66a61b41dd7cdd605574882febfeccc4a6f292a.zip
kde-frameworks/bluez-qt: Fix race condition
Fixes systray icons not reflecting the correct status at startup. See also: https://bugs.kde.org/show_bug.cgi?id=377405 Package-Manager: Portage-2.3.5, Repoman-2.3.1
Diffstat (limited to 'kde-frameworks')
-rw-r--r--kde-frameworks/bluez-qt/bluez-qt-5.34.0-r1.ebuild36
-rw-r--r--kde-frameworks/bluez-qt/files/bluez-qt-5.34.0-fix-race-condition.patch358
2 files changed, 394 insertions, 0 deletions
diff --git a/kde-frameworks/bluez-qt/bluez-qt-5.34.0-r1.ebuild b/kde-frameworks/bluez-qt/bluez-qt-5.34.0-r1.ebuild
new file mode 100644
index 000000000000..e6bc126ee07c
--- /dev/null
+++ b/kde-frameworks/bluez-qt/bluez-qt-5.34.0-r1.ebuild
@@ -0,0 +1,36 @@
+# Copyright 1999-2017 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=6
+
+VIRTUALX_REQUIRED="test"
+inherit kde5 udev
+
+DESCRIPTION="Qt wrapper for Bluez 5 DBus API"
+LICENSE="LGPL-2"
+KEYWORDS="~amd64 ~arm ~x86"
+IUSE=""
+
+DEPEND="
+ $(add_qt_dep qtdbus)
+ $(add_qt_dep qtdeclarative)
+ $(add_qt_dep qtnetwork)
+"
+RDEPEND="${DEPEND}"
+
+PATCHES=( "${FILESDIR}/${P}-fix-race-condition.patch" )
+
+src_configure() {
+ local mycmakeargs=(
+ -DUDEV_RULES_INSTALL_DIR="$(get_udevdir)/rules.d"
+ )
+
+ kde5_src_configure
+}
+
+src_test() {
+ # bug: 609248
+ local myctestargs=( -j1 )
+
+ kde5_src_test
+}
diff --git a/kde-frameworks/bluez-qt/files/bluez-qt-5.34.0-fix-race-condition.patch b/kde-frameworks/bluez-qt/files/bluez-qt-5.34.0-fix-race-condition.patch
new file mode 100644
index 000000000000..84f39a3c2b9b
--- /dev/null
+++ b/kde-frameworks/bluez-qt/files/bluez-qt-5.34.0-fix-race-condition.patch
@@ -0,0 +1,358 @@
+From c02c4806c9bfcd6dc36fab6ed9873cff86681cdd Mon Sep 17 00:00:00 2001
+From: David Rosca <nowrep@gmail.com>
+Date: Fri, 26 May 2017 13:55:44 +0200
+Subject: Fix property changes being missed immediately after an obejct is
+ added
+
+Fix race condition when property changes may be missed if the property
+is changed immediately after the object is created.
+The issue was that the connection to PropertyChanged signal was
+created only after interfacesAdded signal was fired, which may have
+already been too late.
+This fixes it with connecting to PropertyChanged signal on all paths
+in Manager::init().
+
+BUG: 377405
+
+Differential Revision: https://phabricator.kde.org/D5550
+---
+ autotests/fakebluez/devicemanager.cpp | 19 +++++++++++++++++++
+ autotests/fakebluez/devicemanager.h | 1 +
+ autotests/managertest.cpp | 20 ++++++++++++++++++++
+ autotests/managertest.h | 1 +
+ src/adapter_p.cpp | 8 --------
+ src/device_p.cpp | 10 +++++-----
+ src/input.cpp | 10 +++-------
+ src/input_p.h | 4 ----
+ src/manager_p.cpp | 27 +++++++++++++++++++++++++++
+ src/manager_p.h | 4 +++-
+ src/mediaplayer_p.cpp | 3 ---
+ src/utils.cpp | 7 +++++++
+ src/utils.h | 1 +
+ 13 files changed, 87 insertions(+), 28 deletions(-)
+
+diff --git a/autotests/fakebluez/devicemanager.cpp b/autotests/fakebluez/devicemanager.cpp
+index 7967047..229b92a 100644
+--- a/autotests/fakebluez/devicemanager.cpp
++++ b/autotests/fakebluez/devicemanager.cpp
+@@ -43,6 +43,8 @@ void DeviceManager::runAction(const QString &actionName, const QVariantMap &prop
+ runChangeAdapterProperty(properties);
+ } else if (actionName == QLatin1String("change-device-property")) {
+ runChangeDeviceProperty(properties);
++ } else if (actionName == QLatin1String("bug377405")) {
++ runBug377405();
+ }
+ }
+
+@@ -103,3 +105,20 @@ void DeviceManager::runChangeDeviceProperty(const QVariantMap &properties)
+
+ device->changeProperty(properties.value(QStringLiteral("Name")).toString(), properties.value(QStringLiteral("Value")));
+ }
++
++void DeviceManager::runBug377405()
++{
++ QDBusObjectPath adapter1path = QDBusObjectPath(QStringLiteral("/org/bluez/hci0"));
++ QVariantMap adapterProps;
++ adapterProps[QStringLiteral("Path")] = QVariant::fromValue(adapter1path);
++ adapterProps[QStringLiteral("Powered")] = false;
++
++ runCreateAdapterAction(adapterProps);
++
++ QVariantMap properties;
++ properties[QStringLiteral("Path")] = QVariant::fromValue(adapter1path);
++ properties[QStringLiteral("Name")] = QStringLiteral("Powered");
++ properties[QStringLiteral("Value")] = true;
++
++ runChangeAdapterProperty(properties);
++}
+diff --git a/autotests/fakebluez/devicemanager.h b/autotests/fakebluez/devicemanager.h
+index f830175..163b311 100644
+--- a/autotests/fakebluez/devicemanager.h
++++ b/autotests/fakebluez/devicemanager.h
+@@ -41,6 +41,7 @@ private:
+ void runRemoveDeviceAction(const QVariantMap &properties);
+ void runChangeAdapterProperty(const QVariantMap &properties);
+ void runChangeDeviceProperty(const QVariantMap &properties);
++ void runBug377405();
+
+ ObjectManager *m_objectManager;
+
+diff --git a/autotests/managertest.cpp b/autotests/managertest.cpp
+index 3217f97..1d7ffcc 100644
+--- a/autotests/managertest.cpp
++++ b/autotests/managertest.cpp
+@@ -437,4 +437,24 @@ void ManagerTest::bug364416()
+ delete manager;
+ }
+
++void ManagerTest::bug377405()
++{
++ // Bug 377405: Property changes immediately after adapter is added are lost
++
++ FakeBluez::start();
++ FakeBluez::runTest(QStringLiteral("bluez-standard"));
++
++ Manager *manager = new Manager;
++
++ InitManagerJob *job = manager->init();
++ job->exec();
++
++ QVERIFY(!job->error());
++
++ FakeBluez::runAction(QStringLiteral("devicemanager"), QStringLiteral("bug377405"));
++
++ // Adapter property Powered is changed to true immediately after being added
++ QTRY_COMPARE(manager->isBluetoothOperational(), true);
++}
++
+ QTEST_MAIN(ManagerTest)
+diff --git a/autotests/managertest.h b/autotests/managertest.h
+index 654fe98..9de8ae1 100644
+--- a/autotests/managertest.h
++++ b/autotests/managertest.h
+@@ -41,6 +41,7 @@ private Q_SLOTS:
+ void deviceForAddressTest();
+ void adapterWithDevicesRemovedTest();
+ void bug364416();
++ void bug377405();
+
+ };
+
+diff --git a/src/adapter_p.cpp b/src/adapter_p.cpp
+index 786fa7d..eb5fa9f 100644
+--- a/src/adapter_p.cpp
++++ b/src/adapter_p.cpp
+@@ -48,14 +48,6 @@ void AdapterPrivate::init(const QVariantMap &properties)
+ m_dbusProperties = new DBusProperties(Strings::orgBluez(), m_bluezAdapter->path(),
+ DBusConnection::orgBluez(), this);
+
+- // QueuedConnection is important here to be able to perform actions, that depend on
+- // a previously set property, directly from slot connected to propertyChanged signal.
+- // Eg. Powering on adapter and then starting discovery.
+- // * with DirectConnection the StartDiscovery would fail because the adapter is still
+- // powered off when the PropertiesChanged signal is emitted ...
+- connect(m_dbusProperties, &DBusProperties::PropertiesChanged,
+- this, &AdapterPrivate::propertiesChanged, Qt::QueuedConnection);
+-
+ // Init properties
+ m_address = properties.value(QStringLiteral("Address")).toString();
+ m_name = properties.value(QStringLiteral("Name")).toString();
+diff --git a/src/device_p.cpp b/src/device_p.cpp
+index 79cbb86..351162d 100644
+--- a/src/device_p.cpp
++++ b/src/device_p.cpp
+@@ -58,10 +58,6 @@ void DevicePrivate::init(const QVariantMap &properties)
+ m_dbusProperties = new DBusProperties(Strings::orgBluez(), m_bluezDevice->path(),
+ DBusConnection::orgBluez(), this);
+
+- // QueuedConnection is important here - see AdapterPrivate::initProperties
+- connect(m_dbusProperties, &DBusProperties::PropertiesChanged,
+- this, &DevicePrivate::propertiesChanged, Qt::QueuedConnection);
+-
+ // Init properties
+ m_address = properties.value(QStringLiteral("Address")).toString();
+ m_name = properties.value(QStringLiteral("Name")).toString();
+@@ -136,7 +132,11 @@ QDBusPendingReply<> DevicePrivate::setDBusProperty(const QString &name, const QV
+
+ void DevicePrivate::propertiesChanged(const QString &interface, const QVariantMap &changed, const QStringList &invalidated)
+ {
+- if (interface != Strings::orgBluezDevice1()) {
++ if (interface == Strings::orgBluezInput1() && m_input) {
++ m_input->d->propertiesChanged(interface, changed, invalidated);
++ } else if (interface == Strings::orgBluezMediaPlayer1() && m_mediaPlayer) {
++ m_mediaPlayer->d->propertiesChanged(interface, changed, invalidated);
++ } else if (interface != Strings::orgBluezDevice1()) {
+ return;
+ }
+
+diff --git a/src/input.cpp b/src/input.cpp
+index 4cf4f03..aabb996 100644
+--- a/src/input.cpp
++++ b/src/input.cpp
+@@ -25,11 +25,11 @@
+ #include "utils.h"
+ #include "macros.h"
+
++#include <QVariantMap>
++
+ namespace BluezQt
+ {
+
+-typedef org::freedesktop::DBus::Properties DBusProperties;
+-
+ static Input::ReconnectMode stringToReconnectMode(const QString &mode)
+ {
+ if (mode == QLatin1String("none")) {
+@@ -45,11 +45,7 @@ static Input::ReconnectMode stringToReconnectMode(const QString &mode)
+ InputPrivate::InputPrivate(const QString &path, const QVariantMap &properties)
+ : QObject()
+ {
+- m_dbusProperties = new DBusProperties(Strings::orgBluez(), path,
+- DBusConnection::orgBluez(), this);
+-
+- connect(m_dbusProperties, &DBusProperties::PropertiesChanged,
+- this, &InputPrivate::propertiesChanged, Qt::QueuedConnection);
++ Q_UNUSED(path);
+
+ // Init properties
+ m_reconnectMode = stringToReconnectMode(properties.value(QStringLiteral("ReconnectMode")).toString());
+diff --git a/src/input_p.h b/src/input_p.h
+index 424179a..ce3f33d 100644
+--- a/src/input_p.h
++++ b/src/input_p.h
+@@ -26,13 +26,10 @@
+ #include <QObject>
+
+ #include "input.h"
+-#include "dbusproperties.h"
+
+ namespace BluezQt
+ {
+
+-typedef org::freedesktop::DBus::Properties DBusProperties;
+-
+ class InputPrivate : public QObject
+ {
+ Q_OBJECT
+@@ -43,7 +40,6 @@ public:
+ void propertiesChanged(const QString &interface, const QVariantMap &changed, const QStringList &invalidated);
+
+ QWeakPointer<Input> q;
+- DBusProperties *m_dbusProperties;
+
+ Input::ReconnectMode m_reconnectMode;
+ };
+diff --git a/src/manager_p.cpp b/src/manager_p.cpp
+index aaec901..105d954 100644
+--- a/src/manager_p.cpp
++++ b/src/manager_p.cpp
+@@ -82,6 +82,13 @@ void ManagerPrivate::init()
+
+ QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(DBusConnection::orgBluez().asyncCall(call));
+ connect(watcher, &QDBusPendingCallWatcher::finished, this, &ManagerPrivate::nameHasOwnerFinished);
++
++ DBusConnection::orgBluez().connect(Strings::orgBluez(),
++ QString(),
++ Strings::orgFreedesktopDBusProperties(),
++ QStringLiteral("PropertiesChanged"),
++ this,
++ SLOT(propertiesChanged(QString,QVariantMap,QStringList)));
+ }
+
+ void ManagerPrivate::nameHasOwnerFinished(QDBusPendingCallWatcher *watcher)
+@@ -424,6 +431,26 @@ void ManagerPrivate::setUsableAdapter(const AdapterPtr &adapter)
+ }
+ }
+
++void ManagerPrivate::propertiesChanged(const QString &interface, const QVariantMap &changed, const QStringList &invalidated)
++{
++ // Cut anything after device path to forward it to Device to handle
++ const QString path = message().path().section(QLatin1Char('/'), 0, 4);
++
++ QTimer::singleShot(0, this, [=]() {
++ AdapterPtr adapter = m_adapters.value(path);
++ if (adapter) {
++ adapter->d->propertiesChanged(interface, changed, invalidated);
++ return;
++ }
++ DevicePtr device = m_devices.value(path);
++ if (device) {
++ device->d->propertiesChanged(interface, changed, invalidated);
++ return;
++ }
++ qCDebug(BLUEZQT) << "Unhandled property change" << interface << changed << invalidated;
++ });
++}
++
+ void ManagerPrivate::dummy()
+ {
+ }
+diff --git a/src/manager_p.h b/src/manager_p.h
+index 0b26d1b..cc3276d 100644
+--- a/src/manager_p.h
++++ b/src/manager_p.h
+@@ -25,6 +25,7 @@
+
+ #include <QObject>
+ #include <QHash>
++#include <QDBusContext>
+
+ #include "types.h"
+ #include "rfkill.h"
+@@ -44,7 +45,7 @@ class Adapter;
+ class Device;
+ class AdapterPrivate;
+
+-class ManagerPrivate : public QObject
++class ManagerPrivate : public QObject, protected QDBusContext
+ {
+ Q_OBJECT
+
+@@ -96,6 +97,7 @@ Q_SIGNALS:
+ void initFinished();
+
+ private Q_SLOTS:
++ void propertiesChanged(const QString &interface, const QVariantMap &changed, const QStringList &invalidated);
+ void dummy();
+
+ };
+diff --git a/src/mediaplayer_p.cpp b/src/mediaplayer_p.cpp
+index 3c4e57e..21a3ebb 100644
+--- a/src/mediaplayer_p.cpp
++++ b/src/mediaplayer_p.cpp
+@@ -92,9 +92,6 @@ void MediaPlayerPrivate::init(const QVariantMap &properties)
+ m_dbusProperties = new DBusProperties(Strings::orgBluez(), m_bluezMediaPlayer->path(),
+ DBusConnection::orgBluez(), this);
+
+- connect(m_dbusProperties, &DBusProperties::PropertiesChanged,
+- this, &MediaPlayerPrivate::propertiesChanged, Qt::QueuedConnection);
+-
+ // Init properties
+ m_name = properties.value(QStringLiteral("Name")).toString();
+ m_equalizer = stringToEqualizer(properties.value(QStringLiteral("Equalizer")).toString());
+diff --git a/src/utils.cpp b/src/utils.cpp
+index aed8250..9ca3d6d 100644
+--- a/src/utils.cpp
++++ b/src/utils.cpp
+@@ -39,6 +39,7 @@ public:
+
+ bool testRun;
+ QString orgFreedesktopDBus;
++ QString orgFreedesktopDBusProperties;
+ QString orgBluez;
+ QString orgBluezAdapter1;
+ QString orgBluezDevice1;
+@@ -59,6 +60,7 @@ GlobalData::GlobalData()
+ {
+ testRun = false;
+ orgFreedesktopDBus = QStringLiteral("org.freedesktop.DBus");
++ orgFreedesktopDBusProperties = QStringLiteral("org.freedesktop.DBus.Properties");
+ orgBluez = QStringLiteral("org.bluez");
+ orgBluezAdapter1 = QStringLiteral("org.bluez.Adapter1");
+ orgBluezDevice1 = QStringLiteral("org.bluez.Device1");
+@@ -88,6 +90,11 @@ QString Strings::orgFreedesktopDBus()
+ return globalData->orgFreedesktopDBus;
+ }
+
++QString Strings::orgFreedesktopDBusProperties()
++{
++ return globalData->orgFreedesktopDBusProperties;
++}
++
+ QString Strings::orgBluez()
+ {
+ return globalData->orgBluez;
+diff --git a/src/utils.h b/src/utils.h
+index fd49d8e..08cb6b9 100644
+--- a/src/utils.h
++++ b/src/utils.h
+@@ -36,6 +36,7 @@ namespace Strings
+ {
+
+ QString orgFreedesktopDBus();
++QString orgFreedesktopDBusProperties();
+ QString orgBluez();
+ QString orgBluezAdapter1();
+ QString orgBluezDevice1();
+--
+cgit v0.11.2