Commit 9022823a authored by Albert Vaca Cintora's avatar Albert Vaca Cintora

Improved MPRIS controls.

MPRIS now uses xml dbus interfaces-
MPRIS now detects when properties like volume or playbas status change.
Link providers now emit connectionLost and connectionReceived, like in Android.
Disabled connection notifications.
Added some missing const modifiers.
parent af02ca7c
...@@ -9,7 +9,10 @@ find_package(KDE4 REQUIRED) ...@@ -9,7 +9,10 @@ find_package(KDE4 REQUIRED)
include(KDE4Defaults) include(KDE4Defaults)
include_directories(${KDE4_INCLUDES}) include_directories(${KDE4_INCLUDES})
include_directories(${CMAKE_CURRENT_BINARY_DIR})
add_subdirectory(daemon) add_subdirectory(daemon)
add_subdirectory(kcm) add_subdirectory(kcm)
#add_subdirectory(kioslave)
add_subdirectory(test) add_subdirectory(test)
...@@ -23,6 +23,18 @@ set(kded_kdeconnect_SRCS ...@@ -23,6 +23,18 @@ set(kded_kdeconnect_SRCS
device.cpp device.cpp
) )
qt4_add_dbus_interface(
kded_kdeconnect_SRCS
packageinterfaces/mprisdbusinterface.xml
mprisdbusinterface
)
qt4_add_dbus_interface(
kded_kdeconnect_SRCS
packageinterfaces/propertiesInterface.xml
propertiesdbusinterface
)
kde4_add_plugin(kded_kdeconnect ${kded_kdeconnect_SRCS}) kde4_add_plugin(kded_kdeconnect ${kded_kdeconnect_SRCS})
target_link_libraries(kded_kdeconnect target_link_libraries(kded_kdeconnect
......
...@@ -91,14 +91,14 @@ Daemon::Daemon(QObject *parent, const QList<QVariant>&) ...@@ -91,14 +91,14 @@ Daemon::Daemon(QObject *parent, const QList<QVariant>&)
device,SLOT(sendPackage(const NetworkPackage&))); device,SLOT(sendPackage(const NetworkPackage&)));
} }
} }
QNetworkSession* network = new QNetworkSession(QNetworkConfigurationManager().defaultConfiguration()); QNetworkSession* network = new QNetworkSession(QNetworkConfigurationManager().defaultConfiguration());
//Listen to incomming connections //Listen to incomming connections
Q_FOREACH (LinkProvider* a, mLinkProviders) { Q_FOREACH (LinkProvider* a, mLinkProviders) {
connect(network, SIGNAL(stateChanged(QNetworkSession::State)), connect(network, SIGNAL(stateChanged(QNetworkSession::State)),
a, SLOT(onNetworkChange(QNetworkSession::State))); a, SLOT(onNetworkChange(QNetworkSession::State)));
connect(a,SIGNAL(onNewDeviceLink(NetworkPackage,DeviceLink*)), connect(a,SIGNAL(onConnectionReceived(NetworkPackage,DeviceLink*)),
this,SLOT(onNewDeviceLink(NetworkPackage,DeviceLink*))); this,SLOT(onNewDeviceLink(NetworkPackage,DeviceLink*)));
} }
...@@ -130,7 +130,6 @@ QStringList Daemon::devices() ...@@ -130,7 +130,6 @@ QStringList Daemon::devices()
return mDevices.keys(); return mDevices.keys();
} }
void Daemon::onNewDeviceLink(const NetworkPackage& identityPackage, DeviceLink* dl) void Daemon::onNewDeviceLink(const NetworkPackage& identityPackage, DeviceLink* dl)
{ {
const QString& id = identityPackage.get<QString>("deviceId"); const QString& id = identityPackage.get<QString>("deviceId");
...@@ -143,16 +142,16 @@ void Daemon::onNewDeviceLink(const NetworkPackage& identityPackage, DeviceLink* ...@@ -143,16 +142,16 @@ void Daemon::onNewDeviceLink(const NetworkPackage& identityPackage, DeviceLink*
Device* device = mDevices[id]; Device* device = mDevices[id];
device->addLink(dl); device->addLink(dl);
if (device->paired()) { /*if (device->paired()) {
KNotification* notification = new KNotification("pingReceived"); //KNotification::Persistent KNotification* notification = new KNotification("pingReceived"); //KNotification::Persistent
notification->setPixmap(KIcon("dialog-ok").pixmap(48, 48)); notification->setPixmap(KIcon("dialog-ok").pixmap(48, 48));
notification->setComponentData(KComponentData("kdeconnect", "kdeconnect")); notification->setComponentData(KComponentData("kdeconnect", "kdeconnect"));
notification->setTitle(device->name()); notification->setTitle(device->name());
notification->setText("Succesfully connected"); notification->setText("Succesfully connected");
notification->sendEvent(); notification->sendEvent();
} }*/
emit deviceStatusChanged(id); Q_EMIT deviceStatusChanged(id);
} else { } else {
qDebug() << "It is a new device"; qDebug() << "It is a new device";
...@@ -164,10 +163,8 @@ void Daemon::onNewDeviceLink(const NetworkPackage& identityPackage, DeviceLink* ...@@ -164,10 +163,8 @@ void Daemon::onNewDeviceLink(const NetworkPackage& identityPackage, DeviceLink*
Q_FOREACH (PackageInterface* pr, mPackageInterfaces) { Q_FOREACH (PackageInterface* pr, mPackageInterfaces) {
connect(device,SIGNAL(receivedPackage(const Device&, const NetworkPackage&)), connect(device,SIGNAL(receivedPackage(const Device&, const NetworkPackage&)),
pr,SLOT(receivePackage(const Device&, const NetworkPackage&))); pr,SLOT(receivePackage(const Device&, const NetworkPackage&)));
connect(pr,SIGNAL(sendPackage(const NetworkPackage&)),
device,SLOT(sendPackage(const NetworkPackage&)));
} }
emit newDeviceAdded(id); Q_EMIT newDeviceAdded(id);
} }
} }
......
...@@ -74,6 +74,10 @@ void Device::addLink(DeviceLink* link) ...@@ -74,6 +74,10 @@ void Device::addLink(DeviceLink* link)
connect(link,SIGNAL(destroyed(QObject*)),this,SLOT(linkDestroyed(QObject*))); connect(link,SIGNAL(destroyed(QObject*)),this,SLOT(linkDestroyed(QObject*)));
m_deviceLinks.append(link); m_deviceLinks.append(link);
//TODO: Somehow destroy previous device links from the same provider,
//but if we do it here, the provider will keep a broken ref!
connect(link, SIGNAL(receivedPackage(NetworkPackage)), this, SLOT(privateReceivedPackage(NetworkPackage))); connect(link, SIGNAL(receivedPackage(NetworkPackage)), this, SLOT(privateReceivedPackage(NetworkPackage)));
qSort(m_deviceLinks.begin(),m_deviceLinks.end(),lessThan); qSort(m_deviceLinks.begin(),m_deviceLinks.end(),lessThan);
...@@ -100,7 +104,7 @@ void Device::removeLink(DeviceLink* link) ...@@ -100,7 +104,7 @@ void Device::removeLink(DeviceLink* link)
} }
} }
bool Device::sendPackage(const NetworkPackage& np) bool Device::sendPackage(const NetworkPackage& np) const
{ {
Q_FOREACH(DeviceLink* dl, m_deviceLinks) { Q_FOREACH(DeviceLink* dl, m_deviceLinks) {
if (dl->sendPackage(np)) return true; if (dl->sendPackage(np)) return true;
...@@ -136,5 +140,3 @@ void Device::sendPing() ...@@ -136,5 +140,3 @@ void Device::sendPing()
qDebug() << "sendPing:" << success; qDebug() << "sendPing:" << success;
} }
...@@ -61,7 +61,7 @@ public: ...@@ -61,7 +61,7 @@ public:
Q_SIGNALS: Q_SIGNALS:
void receivedPackage(const Device& device, const NetworkPackage& np); void receivedPackage(const Device& device, const NetworkPackage& np);
public Q_SLOTS: public Q_SLOTS:
bool sendPackage(const NetworkPackage& np); bool sendPackage(const NetworkPackage& np) const;
//Public dbus operations //Public dbus operations
public Q_SLOTS: public Q_SLOTS:
......
...@@ -39,10 +39,10 @@ public: ...@@ -39,10 +39,10 @@ public:
const QString& deviceId() { return mDeviceId; } const QString& deviceId() { return mDeviceId; }
LinkProvider* provider() { return mLinkProvider; } LinkProvider* provider() { return mLinkProvider; }
virtual bool sendPackage(const NetworkPackage& np) = 0; virtual bool sendPackage(const NetworkPackage& np) const = 0;
signals: signals:
void receivedPackage(const NetworkPackage& np); void receivedPackage(const NetworkPackage& np) const;
private: private:
QString mDeviceId; QString mDeviceId;
......
...@@ -31,8 +31,8 @@ class EchoDeviceLink ...@@ -31,8 +31,8 @@ class EchoDeviceLink
public: public:
EchoDeviceLink(const QString& d, LoopbackLinkProvider* a); EchoDeviceLink(const QString& d, LoopbackLinkProvider* a);
bool sendPackage(const NetworkPackage& np) { bool sendPackage(const NetworkPackage& np) const {
emit receivedPackage(np); Q_EMIT receivedPackage(np);
return true; return true;
} }
......
...@@ -29,7 +29,7 @@ TcpDeviceLink::TcpDeviceLink(const QString& d, LinkProvider* a, QTcpSocket* sock ...@@ -29,7 +29,7 @@ TcpDeviceLink::TcpDeviceLink(const QString& d, LinkProvider* a, QTcpSocket* sock
connect(mSocket, SIGNAL(readyRead()), this, SLOT(dataReceived())); connect(mSocket, SIGNAL(readyRead()), this, SLOT(dataReceived()));
} }
bool TcpDeviceLink::sendPackage(const NetworkPackage& np) bool TcpDeviceLink::sendPackage(const NetworkPackage& np) const
{ {
int written = mSocket->write(np.serialize()); int written = mSocket->write(np.serialize());
return written != -1; return written != -1;
......
...@@ -38,7 +38,7 @@ class TcpDeviceLink ...@@ -38,7 +38,7 @@ class TcpDeviceLink
public: public:
TcpDeviceLink(const QString& d, LinkProvider* a, QTcpSocket* socket); TcpDeviceLink(const QString& d, LinkProvider* a, QTcpSocket* socket);
bool sendPackage(const NetworkPackage& np); bool sendPackage(const NetworkPackage& np) const;
private Q_SLOTS: private Q_SLOTS:
void dataReceived(); void dataReceived();
......
...@@ -101,7 +101,7 @@ void AvahiTcpLinkProvider::dataReceived() ...@@ -101,7 +101,7 @@ void AvahiTcpLinkProvider::dataReceived()
qDebug() << "AvahiTcpLinkProvider creating link to device" << id << "(" << socket->peerAddress() << ")"; qDebug() << "AvahiTcpLinkProvider creating link to device" << id << "(" << socket->peerAddress() << ")";
emit onNewDeviceLink(np, dl); Q_EMIT onConnectionReceived(np, dl);
disconnect(socket,SIGNAL(readyRead()),this,SLOT(dataReceived())); disconnect(socket,SIGNAL(readyRead()),this,SLOT(dataReceived()));
...@@ -111,9 +111,11 @@ void AvahiTcpLinkProvider::dataReceived() ...@@ -111,9 +111,11 @@ void AvahiTcpLinkProvider::dataReceived()
} }
void AvahiTcpLinkProvider::deviceLinkDestroyed(QObject* deviceLink) void AvahiTcpLinkProvider::deviceLinkDestroyed(QObject* uncastedDeviceLink)
{ {
const QString& id = ((DeviceLink*)deviceLink)->deviceId(); DeviceLink* deviceLink = (DeviceLink*)uncastedDeviceLink;
Q_EMIT onConnectionLost(deviceLink);
const QString& id = deviceLink->deviceId();
if (links.contains(id)) links.remove(id); if (links.contains(id)) links.remove(id);
} }
......
...@@ -156,7 +156,7 @@ void BroadcastTcpLinkProvider::connected() ...@@ -156,7 +156,7 @@ void BroadcastTcpLinkProvider::connected()
//TODO: Use reverse connection too to preffer connecting a unstable device (a phone) to a stable device (a computer) //TODO: Use reverse connection too to preffer connecting a unstable device (a phone) to a stable device (a computer)
if (success) { if (success) {
qDebug() << "Handshaking done (i'm the existing device)"; qDebug() << "Handshaking done (i'm the existing device)";
emit onNewDeviceLink(*np, dl); Q_EMIT onConnectionReceived(*np, dl);
} else { } else {
//I think this will never happen //I think this will never happen
qDebug() << "Fallback (2), try reverse connection"; qDebug() << "Fallback (2), try reverse connection";
...@@ -218,7 +218,7 @@ void BroadcastTcpLinkProvider::dataReceived() ...@@ -218,7 +218,7 @@ void BroadcastTcpLinkProvider::dataReceived()
qDebug() << "Handshaking done (i'm the new device)"; qDebug() << "Handshaking done (i'm the new device)";
emit onNewDeviceLink(np, dl); Q_EMIT onConnectionReceived(np, dl);
disconnect(socket,SIGNAL(readyRead()),this,SLOT(dataReceived())); disconnect(socket,SIGNAL(readyRead()),this,SLOT(dataReceived()));
...@@ -228,14 +228,12 @@ void BroadcastTcpLinkProvider::dataReceived() ...@@ -228,14 +228,12 @@ void BroadcastTcpLinkProvider::dataReceived()
} }
void BroadcastTcpLinkProvider::deviceLinkDestroyed(QObject* deviceLink) void BroadcastTcpLinkProvider::deviceLinkDestroyed(QObject* uncastedDeviceLink)
{ {
const QString& id = ((DeviceLink*)deviceLink)->deviceId(); DeviceLink* deviceLink = (DeviceLink*)uncastedDeviceLink;
qDebug() << "deviceLinkDestroyed"; Q_EMIT onConnectionLost(deviceLink);
if (links.contains(id)) { const QString& id = deviceLink->deviceId();
qDebug() << "removing link from link list"; if (links.contains(id)) links.remove(id);
links.remove(id);
}
} }
BroadcastTcpLinkProvider::~BroadcastTcpLinkProvider() BroadcastTcpLinkProvider::~BroadcastTcpLinkProvider()
......
...@@ -55,7 +55,8 @@ public Q_SLOTS: ...@@ -55,7 +55,8 @@ public Q_SLOTS:
Q_SIGNALS: Q_SIGNALS:
//NOTE: The provider will to destroy the DeviceLink when it's no longer accessible, //NOTE: The provider will to destroy the DeviceLink when it's no longer accessible,
// and every user should listen to the destroyed signal to remove its references. // and every user should listen to the destroyed signal to remove its references.
void onNewDeviceLink(const NetworkPackage& identityPackage, DeviceLink*); void onConnectionReceived(const NetworkPackage& identityPackage, DeviceLink*);
void onConnectionLost(DeviceLink*);
}; };
......
...@@ -38,6 +38,6 @@ LoopbackLinkProvider::~LoopbackLinkProvider() ...@@ -38,6 +38,6 @@ LoopbackLinkProvider::~LoopbackLinkProvider()
void LoopbackLinkProvider::setDiscoverable(bool b) void LoopbackLinkProvider::setDiscoverable(bool b)
{ {
qDebug() << "Echo Device discovery emitted"; qDebug() << "Echo Device discovery emitted";
if (b) emit onNewDeviceLink(identityPackage, echoDeviceLink); if (b) Q_EMIT onConnectionReceived(identityPackage, echoDeviceLink);
} }
...@@ -57,7 +57,7 @@ public: ...@@ -57,7 +57,7 @@ public:
} }
template<typename T> void set(const QString& key, const T& value) { mBody[key] = QVariant(value); } template<typename T> void set(const QString& key, const T& value) { mBody[key] = QVariant(value); }
bool has(const QString& key) { return mBody.contains(key); } bool has(const QString& key) const { return mBody.contains(key); }
private: private:
void setId(long id) { mId = id; } void setId(long id) { mId = id; }
......
...@@ -20,6 +20,8 @@ ...@@ -20,6 +20,8 @@
#include "mpriscontrolpackageinterface.h" #include "mpriscontrolpackageinterface.h"
#include "propertiesdbusinterface.h"
#include <QDebug> #include <QDebug>
#include <QDBusConnection> #include <QDBusConnection>
#include <QDBusInterface> #include <QDBusInterface>
...@@ -52,7 +54,7 @@ void MprisControlPackageInterface::serviceOwnerChanged(const QString &name, ...@@ -52,7 +54,7 @@ void MprisControlPackageInterface::serviceOwnerChanged(const QString &name,
if (name.startsWith("org.mpris.MediaPlayer2")) { if (name.startsWith("org.mpris.MediaPlayer2")) {
qDebug() << "Something registered in bus" << name << oldOwner << newOwner; qDebug() << "Something (un)registered in bus" << name << oldOwner << newOwner;
if (oldOwner.isEmpty()) { if (oldOwner.isEmpty()) {
addPlayer(name); addPlayer(name);
...@@ -62,27 +64,65 @@ void MprisControlPackageInterface::serviceOwnerChanged(const QString &name, ...@@ -62,27 +64,65 @@ void MprisControlPackageInterface::serviceOwnerChanged(const QString &name,
} }
} }
void MprisControlPackageInterface::addPlayer(const QString& ifaceName) void MprisControlPackageInterface::addPlayer(const QString& service)
{ {
QDBusInterface interface(ifaceName, "/org/mpris/MediaPlayer2", "org.mpris.MediaPlayer2"); QDBusInterface mprisInterface(service, "/org/mpris/MediaPlayer2", "org.mpris.MediaPlayer2");
//TODO: Make this async const QString& identity = mprisInterface.property("Identity").toString();
QString identity = interface.property("Identity").toString(); playerList[identity] = service;
playerList[identity] = ifaceName; qDebug() << "addPlayer" << service << identity;
qDebug() << "addPlayer" << ifaceName << identity;
sendPlayerList(); sendPlayerList();
OrgFreedesktopDBusPropertiesInterface* freedesktopInterface = new OrgFreedesktopDBusPropertiesInterface(service, "/org/mpris/MediaPlayer2", QDBusConnection::sessionBus(), this);
connect(freedesktopInterface, SIGNAL(PropertiesChanged(QString, QVariantMap, QStringList)), this, SLOT(propertiesChanged(QString, QVariantMap)));
} }
void MprisControlPackageInterface::removePlayer(const QString& ifaceName) void MprisControlPackageInterface::propertiesChanged(const QString& propertyInterface, const QVariantMap& properties)
{ {
playerList.remove(playerList.key(ifaceName));
sendPlayerList(); NetworkPackage np(PACKAGE_TYPE_MPRIS);
bool somethingToSend = false;
if (properties.contains("Volume")) {
int volume = (int) (properties["Volume"].toDouble()*100);
if (volume != prevVolume) {
np.set("volume",volume);
prevVolume = volume;
somethingToSend = true;
}
}
if (properties.contains("Metadata")) {
QDBusArgument bullshit = qvariant_cast<QDBusArgument>(properties["Metadata"]);
QVariantMap nowPlayingMap;
bullshit >> nowPlayingMap;
if (nowPlayingMap.contains("xesam:title")) {
QString nowPlaying = nowPlayingMap["xesam:title"].toString();
if (nowPlayingMap.contains("xesam:artist")) {
nowPlaying = nowPlayingMap["xesam:artist"].toString() + " - " + nowPlaying;
}
np.set("nowPlaying",nowPlaying);
somethingToSend = true;
}
}
if (properties.contains("PlaybackStatus")) {
bool playing = (properties["PlaybackStatus"].toString() == "Playing");
np.set("isPlaying", playing);
somethingToSend = true;
}
if (somethingToSend) {
OrgFreedesktopDBusPropertiesInterface* interface = (OrgFreedesktopDBusPropertiesInterface*)sender();
const QString& service = interface->service();
const QString& player = playerList.key(service);
np.set("player", player);
sendPackage(np);
}
} }
void MprisControlPackageInterface::sendPlayerList() void MprisControlPackageInterface::removePlayer(const QString& ifaceName)
{ {
NetworkPackage np(PACKAGE_TYPE_MPRIS); playerList.remove(playerList.key(ifaceName));
np.set("playerList",playerList.keys()); sendPlayerList();
sendPackage(np);
} }
bool MprisControlPackageInterface::receivePackage (const Device& device, const NetworkPackage& np) bool MprisControlPackageInterface::receivePackage (const Device& device, const NetworkPackage& np)
...@@ -91,40 +131,71 @@ bool MprisControlPackageInterface::receivePackage (const Device& device, const N ...@@ -91,40 +131,71 @@ bool MprisControlPackageInterface::receivePackage (const Device& device, const N
if (np.type() != PACKAGE_TYPE_MPRIS) return false; if (np.type() != PACKAGE_TYPE_MPRIS) return false;
//Send the player list
const QString& player = np.get<QString>("player");
bool valid_player = playerList.contains(player);
if (!valid_player || np.get<bool>("requestPlayerList")) {
sendPlayerList(&device);
if (!valid_player) {
return true;
}
}
QString player = np.get<QString>("player"); //Do something to the mpris interface
if (!playerList.contains(player)) { OrgMprisMediaPlayer2PlayerInterface mprisInterface(playerList[player], "/org/mpris/MediaPlayer2", QDBusConnection::sessionBus());
sendPlayerList(); if (np.has("action")) {
return true; const QString& action = np.get<QString>("action");
qDebug() << "Calling action" << action << "in" << playerList[player];
//TODO: Check for valid actions
mprisInterface.call(action);
} }
if (np.has("setVolume")) {
double volume = np.get<int>("setVolume")/100.f;
qDebug() << "Setting volume" << volume << "to" << playerList[player];
mprisInterface.setVolume(volume);
}
//Send something read from the mpris interface
NetworkPackage answer(PACKAGE_TYPE_MPRIS);
bool somethingToSend = false;
if (np.get<bool>("requestNowPlaying")) {
QVariantMap nowPlayingMap = mprisInterface.metadata();
QString nowPlaying = nowPlayingMap["xesam:title"].toString();
if (nowPlayingMap.contains("xesam:artist")) {
nowPlaying = nowPlayingMap["xesam:artist"].toString() + " - " + nowPlaying;
}
answer.set("nowPlaying",nowPlaying);
bool playing = (mprisInterface.playbackStatus() == QLatin1String("Playing"));
answer.set("isPlaying", playing);
somethingToSend = true;
QDBusInterface mprisInterface(playerList[player], "/org/mpris/MediaPlayer2", "org.mpris.MediaPlayer2.Player");
if (np.get<bool>("requestPlayerList")) {
sendPlayerList();
} }
if (np.get<bool>("requestVolume")) {
int volume = (int)(mprisInterface.volume() * 100);
answer.set("volume",volume);
somethingToSend = true;
QString action = np.get<QString>("action"); }
if (!action.isEmpty()) { if (somethingToSend) {
qDebug() << "Calling action" << action << "in" << playerList[player]; answer.set("player", player);
mprisInterface.call(action); device.sendPackage(answer);
sendNowPlaying(mprisInterface);
} else if (np.get<bool>("requestNowPlaying")) {
sendNowPlaying(mprisInterface);
} }
return true; return true;
} }
void MprisControlPackageInterface::sendNowPlaying(const QDBusInterface& mprisInterface) void MprisControlPackageInterface::sendPlayerList(const Device* device)
{ {
QVariantMap nowPlayingMap = mprisInterface.property("Metadata").toMap();
QString nowPlaying = nowPlayingMap["xesam:title"].toString();
if (nowPlayingMap.contains("xesam:artist")) {
nowPlaying = nowPlayingMap["xesam:artist"].toString() + " - " + nowPlaying;
}
NetworkPackage np(PACKAGE_TYPE_MPRIS); NetworkPackage np(PACKAGE_TYPE_MPRIS);
np.set("nowPlaying",nowPlaying); np.set("playerList",playerList.keys());
sendPackage(np); if (device == NULL) Q_EMIT sendPackage(np);
else device->sendPackage(np);
} }
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#define MPRISCONTROLPACKAGEINTERFACE_H #define MPRISCONTROLPACKAGEINTERFACE_H
#include "packageinterface.h" #include "packageinterface.h"
#include "mprisdbusinterface.h"
#include <QSet> #include <QSet>
#include <QString> #include <QString>
...@@ -37,16 +38,16 @@ public: ...@@ -37,16 +38,16 @@ public:
MprisControlPackageInterface(); MprisControlPackageInterface();
virtual bool receivePackage(const Device& device, const NetworkPackage& np); virtual bool receivePackage(const Device& device, const NetworkPackage& np);
public Q_SLOTS: private Q_SLOTS:
void serviceOwnerChanged(const QString &name, const QString &oldOwner, const QString &newOwner); void serviceOwnerChanged(const QString &name, const QString &oldOwner, const QString &newOwner);
void propertiesChanged(const QString& interface, const QVariantMap& properties);
private: private:
QHash<QString, QString> playerList; QHash<QString, QString> playerList;
void addPlayer(const QString& ifaceName); void addPlayer(const QString& ifaceName);
void removePlayer(const QString& ifaceName); void removePlayer(const QString& ifaceName);
void sendPlayerList(); void sendPlayerList(const Device* device = 0);
void sendNowPlaying(const QDBusInterface& interface); int prevVolume;
}; };
......
<!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.mpris.MediaPlayer2.Player">
<method name="Next"/>
<method name="Previous"/>
<method name="Pause"/>
<method name="PlayPause"/>
<method name="Stop"/>
<method name="Play"/>
<method name="Seek">
<arg direction="in" type="x" name="Offset"/>
</method>
<method name="SetPosition">
<arg direction="in" type="o" name="TrackId"/>
<arg direction="in" type="x" name="Position"/>
</method>
<method name="OpenUri">
<arg direction="in" type="s"/>
</method>
<!-- Signals -->
<signal name="Seeked">
<arg type="x" name="Position"/>
</signal>
<!-- Properties -->
<property access="read" type="s" name="PlaybackStatus"/>
<property access="readwrite" type="s" name="LoopStatus"/>
<property access="readwrite" type="d" name="Rate"/>
<property access="readwrite" type="b" name="Shuffle"/>
<property access="read" type="a{sv}" name="Metadata">
<annotation value="QVariantMap" name="com.trolltech.QtDBus.QtTypeName"/>
</property>
<property access="readwrite" type="d" name="Volume"/>
<property access="read" type="x" name="Position"/>
<property access="read" type="d" name="MinimumRate"/>
<property access="read" type="d" name="MaximumRate"/>
<property access="read" type="b" name="CanGoNext"/>
<property access="read" type="b" name="CanGoPrevious"/>
<property access="read" type="b" name="CanPlay"/>
<property access="read" type="b" name="CanPause"/>
<property access="read" type="b" name="CanSeek"/>
<property access="read" type="b" name="CanControl"/>
</interface>
</node>
<?xml version="1.0"?>
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<!-- GDBus 2.32.4 -->
<node>
<interface name="org.freedesktop.DBus.Properties">
<method name="Get">
<arg type="s" name="interface_name" direction="in"/>
<arg type="s" name="property_name" direction="in"/>
<arg type="v" name="value" direction="out"/>
</method>
<method name="Set">
<arg type="s" name="interface_name" direction="in"/>
<arg type="s" name="property_name" direction="in"/>
<arg type="v" name="value" direction="in"/>
</method>
<signal name="PropertiesChanged">
<arg type="s" name="interface_name"/>
<arg type="a{sv}" name="changed_properties"/>
<arg type="as" name="invalidated_properties"/>
<annotation name="org.qtproject.QtDBus.QtTypeName.In1" value="QVariantMap" />
</signal>
</interface>
</node>
Markdown is supported
0% or
You are about to add