Move everything DBus related back to the main thread and use synchronous method calls everywhere

This commit is contained in:
David Sansome 2011-01-22 12:47:19 +00:00
parent 7880026767
commit 2ecf61a57e
15 changed files with 152 additions and 163 deletions

View File

@ -607,6 +607,12 @@ if(HAVE_DBUS)
dbus/org.freedesktop.Notifications.xml
dbus/notification)
# org.gnome.SettingsDaemon interface
qt4_add_dbus_interface(SOURCES
dbus/org.gnome.SettingsDaemon.MediaKeys.xml
dbus/gnomesettingsdaemon)
# DeviceKit DBUS interfaces
if(HAVE_DEVICEKIT)
qt4_add_dbus_interface(SOURCES
@ -785,6 +791,7 @@ if(HAVE_REMOTE)
if(HAVE_DBUS)
list(APPEND SOURCES remote/avahi.cpp)
list(APPEND HEADERS remote/avahi.h)
endif(HAVE_DBUS)
endif(HAVE_REMOTE)

View File

@ -25,56 +25,18 @@
GlobalShortcutBackend::GlobalShortcutBackend(GlobalShortcuts *parent)
: QObject(parent),
manager_(parent),
active_(false),
register_in_progress_(false),
should_unregister_(false)
active_(false)
{
}
void GlobalShortcutBackend::Register() {
if (register_in_progress_) {
should_unregister_ = false;
return;
}
if (RegisterInNewThread()) {
register_in_progress_ = true;
QFuture<bool> future = QtConcurrent::run(this, &GlobalShortcutBackend::DoRegister);
QFutureWatcher<bool>* watcher = new QFutureWatcher<bool>(this);
watcher->setFuture(future);
connect(watcher, SIGNAL(finished()), SLOT(RegisterFinishedSlot()));
} else {
bool ret = DoRegister();
if (ret)
active_ = true;
emit RegisterFinished(ret);
}
bool GlobalShortcutBackend::Register() {
bool ret = DoRegister();
if (ret)
active_ = true;
return ret;
}
void GlobalShortcutBackend::Unregister() {
if (register_in_progress_) {
should_unregister_ = true;
return;
}
DoUnregister();
active_ = false;
}
void GlobalShortcutBackend::RegisterFinishedSlot() {
QFutureWatcher<bool>* watcher = dynamic_cast<QFutureWatcher<bool>*>(sender());
const bool success = watcher->result();
watcher->deleteLater();
register_in_progress_ = false;
if (success)
active_ = true;
if (should_unregister_) {
Unregister();
should_unregister_ = false;
} else {
emit RegisterFinished(success);
}
}

View File

@ -31,26 +31,18 @@ public:
bool is_active() const { return active_; }
void Register();
bool Register();
void Unregister();
signals:
void RegisterFinished(bool success);
protected:
virtual bool RegisterInNewThread() const { return false; }
virtual bool DoRegister() = 0;
virtual void DoUnregister() = 0;
GlobalShortcuts* manager_;
bool active_;
private slots:
void RegisterFinishedSlot();
private:
bool register_in_progress_;
bool should_unregister_;
};
#endif // GLOBALSHORTCUTBACKEND_H

View File

@ -75,9 +75,6 @@ GlobalShortcuts::GlobalShortcuts(QObject *parent)
system_backend_ = new MacGlobalShortcutBackend(this);
#endif
connect(gnome_backend_, SIGNAL(RegisterFinished(bool)), SLOT(RegisterFinished(bool)));
connect(system_backend_, SIGNAL(RegisterFinished(bool)), SLOT(RegisterFinished(bool)));
ReloadSettings();
}
@ -136,18 +133,9 @@ void GlobalShortcuts::Unregister() {
}
void GlobalShortcuts::Register() {
if (use_gnome_)
gnome_backend_->Register();
else
system_backend_->Register();
}
void GlobalShortcuts::RegisterFinished(bool success) {
GlobalShortcutBackend* backend = qobject_cast<GlobalShortcutBackend*>(sender());
if (backend == gnome_backend_ && !success) {
system_backend_->Register();
}
if (use_gnome_ && gnome_backend_->Register())
return;
system_backend_->Register();
}
bool GlobalShortcuts::IsMacAccessibilityEnabled() const {

View File

@ -77,9 +77,6 @@ private:
int rating, const QKeySequence& default_key = QKeySequence(0));
Shortcut AddShortcut(const QString& id, const QString& name, const QKeySequence& default_key);
private slots:
void RegisterFinished(bool success);
private:
GlobalShortcutBackend* gnome_backend_;
GlobalShortcutBackend* system_backend_;

View File

@ -17,6 +17,7 @@
#include "gnomeglobalshortcutbackend.h"
#include "globalshortcuts.h"
#include "dbus/gnomesettingsdaemon.h"
#include <QAction>
#include <QtDebug>
@ -45,10 +46,8 @@ bool GnomeGlobalShortcutBackend::DoRegister() {
}
if (!interface_) {
interface_ = new QDBusInterface(
kGsdService, kGsdPath, kGsdInterface, QDBusConnection::sessionBus());
interface_->moveToThread(thread());
interface_->setParent(this);
interface_ = new OrgGnomeSettingsDaemonMediaKeysInterface(
kGsdService, kGsdPath, QDBusConnection::sessionBus(), this);
}
connect(interface_, SIGNAL(MediaPlayerKeyPressed(QString,QString)),

View File

@ -20,7 +20,7 @@
#include "globalshortcutbackend.h"
class QDBusInterface;
class OrgGnomeSettingsDaemonMediaKeysInterface;
class GnomeGlobalShortcutBackend : public GlobalShortcutBackend {
Q_OBJECT
@ -41,7 +41,7 @@ private slots:
void GnomeMediaKeyPressed(const QString& application, const QString& key);
private:
QDBusInterface* interface_;
OrgGnomeSettingsDaemonMediaKeysInterface* interface_;
};
#endif // GNOMEGLOBALSHORTCUTBACKEND_H

View File

@ -27,41 +27,10 @@ namespace mpris {
Mpris::Mpris(Player* player, ArtLoader* art_loader, QObject* parent)
: QObject(parent),
player_(player),
art_loader_(art_loader),
mpris1_(NULL),
mpris2_(NULL)
mpris1_(new mpris::Mpris1(player, art_loader, this)),
mpris2_(new mpris::Mpris2(player, art_loader, mpris1_, this))
{
qDebug() << __PRETTY_FUNCTION__;
QFuture<void> future = QtConcurrent::run(this, &Mpris::Init);
QFutureWatcher<void>* watcher = new QFutureWatcher<void>(this);
watcher->setFuture(future);
connect(watcher, SIGNAL(finished()), SLOT(Initialised()));
}
void Mpris::Init() {
qDebug() << __PRETTY_FUNCTION__ << "- starting";
qDebug() << __PRETTY_FUNCTION__ << "- registering MPRIS1";
mpris1_ = new mpris::Mpris1(player_, art_loader_);
qDebug() << __PRETTY_FUNCTION__ << "- registering MPRIS2";
mpris2_ = new mpris::Mpris2(player_, art_loader_, mpris1_);
mpris1_->moveToThread(thread());
mpris2_->moveToThread(thread());
mpris1_->setParent(this);
mpris2_->setParent(this);
connect(mpris2_, SIGNAL(RaiseMainWindow()), SIGNAL(RaiseMainWindow()));
qDebug() << __PRETTY_FUNCTION__ << "- complete";
}
void Mpris::Initialised() {
qDebug() << __PRETTY_FUNCTION__;
mpris2_->InitLibIndicate();
}

View File

@ -37,16 +37,7 @@ public:
signals:
void RaiseMainWindow();
private slots:
void Initialised();
private:
void Init();
private:
Player* player_;
ArtLoader* art_loader_;
Mpris1* mpris1_;
Mpris2* mpris2_;
};

View File

@ -0,0 +1,18 @@
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node>
<interface name="org.gnome.SettingsDaemon.MediaKeys">
<method name="ReleaseMediaPlayerKeys">
<arg name="application" type="s" direction="in"/>
</method>
<method name="GrabMediaPlayerKeys">
<arg name="application" type="s" direction="in"/>
<arg name="time" type="u" direction="in"/>
</method>
<signal name="MediaPlayerKeyPressed">
<arg type="s"/>
<arg type="s"/>
</signal>
</interface>
</node>
"

View File

@ -313,9 +313,6 @@ int main(int argc, char *argv[]) {
qDBusRegisterMetaType<TrackIds>();
qDBusRegisterMetaType<QList<QByteArray> >();
// Create the session bus here so it's sure to live in the main thread.
QDBusConnection::sessionBus();
mpris::ArtLoader art_loader;
mpris::Mpris mpris(&player, &art_loader);
@ -325,10 +322,6 @@ int main(int argc, char *argv[]) {
#endif
#ifdef HAVE_REMOTE
#ifdef HAVE_DBUS
// Create the system bus here so it's sure to live in the main thread.
QDBusConnection::systemBus();
#endif
Zeroconf* zeroconf = Zeroconf::GetZeroconf();
if (zeroconf) {
HttpServer* server = new HttpServer(&player);

View File

@ -2,47 +2,94 @@
#include <QDBusConnection>
#include <QHostInfo>
#include <QtConcurrentRun>
#include <QtDebug>
#include "dbus/avahientrygroup.h"
#include "dbus/avahiserver.h"
void Avahi::Publish(
const QString& domain, const QString& type, const QString& name, quint16 port) {
QtConcurrent::run(Avahi::SyncPublish, domain, type, name, port);
Avahi::Avahi()
: server_(NULL),
entry_group_(NULL)
{
}
void Avahi::SyncPublish(const QString& domain, const QString& type, const QString& name, quint16 port) {
OrgFreedesktopAvahiServerInterface server_interface(
void Avahi::Publish(const QString& domain,
const QString& type,
const QString& name,
quint16 port) {
if (server_) {
// Already published
return;
}
domain_ = domain;
type_ = type;
name_ = name;
port_ = port;
server_ = new OrgFreedesktopAvahiServerInterface(
"org.freedesktop.Avahi",
"/",
QDBusConnection::systemBus());
QDBusConnection::systemBus(),
this);
QDBusPendingReply<QDBusObjectPath> reply = server_interface.EntryGroupNew();
reply.waitForFinished();
QDBusPendingReply<QDBusObjectPath> reply = server_->EntryGroupNew();
QDBusPendingCallWatcher* watcher = new QDBusPendingCallWatcher(reply);
connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
SLOT(EntryGroupNewFinished(QDBusPendingCallWatcher*)));
}
OrgFreedesktopAvahiEntryGroupInterface entry_group_interface(
void Avahi::EntryGroupNewFinished(QDBusPendingCallWatcher* call) {
call->deleteLater();
QDBusPendingReply<QDBusObjectPath> reply = *call;
if (reply.isError()) {
qWarning() << "Failed to create new Avahi entry group:" << call->error();
return;
}
entry_group_ = new OrgFreedesktopAvahiEntryGroupInterface(
"org.freedesktop.Avahi",
reply.value().path(),
QDBusConnection::systemBus());
QDBusConnection::systemBus(),
this);
QDBusPendingReply<> add_reply = entry_group_interface.AddService(
QDBusPendingReply<> add_reply = entry_group_->AddService(
-1, // Interface (Unspecified, ie. all interfaces)
-1, // Protocol (Unspecified, ie. IPv4 & IPv6)
0, // Flags
name, // Service name
type, // Service type
domain, // Domain, ie. local
name_, // Service name
type_, // Service type
domain_, // Domain, ie. local
QString::null, // Hostname (Avahi fills it if it's null)
port, // Port
port_, // Port
QList<QByteArray>()); // TXT record
add_reply.waitForFinished();
QDBusPendingCallWatcher* watcher = new QDBusPendingCallWatcher(add_reply);
connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
SLOT(AddServiceFinished(QDBusPendingCallWatcher*)));
}
QDBusPendingReply<> commit_reply = entry_group_interface.Commit();
commit_reply.waitForFinished();
if (commit_reply.isValid()) {
void Avahi::AddServiceFinished(QDBusPendingCallWatcher* call) {
call->deleteLater();
if (call->isError()) {
qWarning() << "Failed to add Avahi service:" << call->error();
return;
}
QDBusPendingReply<> commit_reply = entry_group_->Commit();
QDBusPendingCallWatcher* watcher = new QDBusPendingCallWatcher(commit_reply);
connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
SLOT(CommitFinished(QDBusPendingCallWatcher*)));
}
void Avahi::CommitFinished(QDBusPendingCallWatcher* call) {
call->deleteLater();
if (call->isError()) {
qDebug() << "Remote interface published on Avahi";
} else {
qWarning() << "Failed to commit Avahi changes:" << call->error();
}
}

View File

@ -3,13 +3,37 @@
#include "zeroconf.h"
class Avahi : public Zeroconf {
public:
virtual void Publish(
const QString& domain, const QString& type, const QString& name, quint16 port);
#include <QObject>
private:
static void SyncPublish(const QString& domain, const QString& type, const QString& name, quint16 port);
class OrgFreedesktopAvahiEntryGroupInterface;
class OrgFreedesktopAvahiServerInterface;
class QDBusPendingCallWatcher;
class Avahi : public QObject, public Zeroconf {
Q_OBJECT
public:
Avahi();
virtual void Publish(const QString& domain,
const QString& type,
const QString& name,
quint16 port);
private slots:
void EntryGroupNewFinished(QDBusPendingCallWatcher* call);
void AddServiceFinished(QDBusPendingCallWatcher* call);
void CommitFinished(QDBusPendingCallWatcher* call);
private:
OrgFreedesktopAvahiServerInterface* server_;
OrgFreedesktopAvahiEntryGroupInterface* entry_group_;
QString domain_;
QString type_;
QString name_;
quint16 port_;
};
#endif

View File

@ -14,13 +14,11 @@ Zeroconf* Zeroconf::instance_ = NULL;
Zeroconf* Zeroconf::GetZeroconf() {
if (!instance_) {
#ifdef Q_OS_DARWIN
return new Bonjour();
#endif
#ifdef HAVE_DBUS
return new Avahi();
#endif
#if defined(Q_OS_DARWIN)
instance_ = new Bonjour();
#elif defined(HAVE_DBUS)
instance_ = new Avahi();
#endif
}
return instance_;

View File

@ -4,13 +4,17 @@
#include <QString>
class Zeroconf {
public:
virtual void Publish(
const QString& domain, const QString& type, const QString& name, quint16 port) = 0;
public:
virtual ~Zeroconf() {}
virtual void Publish(const QString& domain,
const QString& type,
const QString& name,
quint16 port) = 0;
static Zeroconf* GetZeroconf();
private:
private:
static Zeroconf* instance_;
};