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.
This commit is contained in:
parent
af02ca7c74
commit
9022823aef
18 changed files with 231 additions and 76 deletions
|
@ -9,7 +9,10 @@ find_package(KDE4 REQUIRED)
|
|||
|
||||
include(KDE4Defaults)
|
||||
include_directories(${KDE4_INCLUDES})
|
||||
include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
add_subdirectory(daemon)
|
||||
add_subdirectory(kcm)
|
||||
#add_subdirectory(kioslave)
|
||||
|
||||
add_subdirectory(test)
|
||||
|
|
|
@ -23,6 +23,18 @@ set(kded_kdeconnect_SRCS
|
|||
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})
|
||||
|
||||
target_link_libraries(kded_kdeconnect
|
||||
|
|
|
@ -91,14 +91,14 @@ Daemon::Daemon(QObject *parent, const QList<QVariant>&)
|
|||
device,SLOT(sendPackage(const NetworkPackage&)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
QNetworkSession* network = new QNetworkSession(QNetworkConfigurationManager().defaultConfiguration());
|
||||
|
||||
//Listen to incomming connections
|
||||
Q_FOREACH (LinkProvider* a, mLinkProviders) {
|
||||
connect(network, SIGNAL(stateChanged(QNetworkSession::State)),
|
||||
a, SLOT(onNetworkChange(QNetworkSession::State)));
|
||||
connect(a,SIGNAL(onNewDeviceLink(NetworkPackage,DeviceLink*)),
|
||||
connect(a,SIGNAL(onConnectionReceived(NetworkPackage,DeviceLink*)),
|
||||
this,SLOT(onNewDeviceLink(NetworkPackage,DeviceLink*)));
|
||||
}
|
||||
|
||||
|
@ -130,7 +130,6 @@ QStringList Daemon::devices()
|
|||
return mDevices.keys();
|
||||
}
|
||||
|
||||
|
||||
void Daemon::onNewDeviceLink(const NetworkPackage& identityPackage, DeviceLink* dl)
|
||||
{
|
||||
const QString& id = identityPackage.get<QString>("deviceId");
|
||||
|
@ -143,16 +142,16 @@ void Daemon::onNewDeviceLink(const NetworkPackage& identityPackage, DeviceLink*
|
|||
Device* device = mDevices[id];
|
||||
device->addLink(dl);
|
||||
|
||||
if (device->paired()) {
|
||||
/*if (device->paired()) {
|
||||
KNotification* notification = new KNotification("pingReceived"); //KNotification::Persistent
|
||||
notification->setPixmap(KIcon("dialog-ok").pixmap(48, 48));
|
||||
notification->setComponentData(KComponentData("kdeconnect", "kdeconnect"));
|
||||
notification->setTitle(device->name());
|
||||
notification->setText("Succesfully connected");
|
||||
notification->sendEvent();
|
||||
}
|
||||
}*/
|
||||
|
||||
emit deviceStatusChanged(id);
|
||||
Q_EMIT deviceStatusChanged(id);
|
||||
|
||||
} else {
|
||||
qDebug() << "It is a new device";
|
||||
|
@ -164,10 +163,8 @@ void Daemon::onNewDeviceLink(const NetworkPackage& identityPackage, DeviceLink*
|
|||
Q_FOREACH (PackageInterface* pr, mPackageInterfaces) {
|
||||
connect(device,SIGNAL(receivedPackage(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)
|
|||
connect(link,SIGNAL(destroyed(QObject*)),this,SLOT(linkDestroyed(QObject*)));
|
||||
|
||||
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)));
|
||||
|
||||
qSort(m_deviceLinks.begin(),m_deviceLinks.end(),lessThan);
|
||||
|
@ -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) {
|
||||
if (dl->sendPackage(np)) return true;
|
||||
|
@ -136,5 +140,3 @@ void Device::sendPing()
|
|||
qDebug() << "sendPing:" << success;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -61,7 +61,7 @@ public:
|
|||
Q_SIGNALS:
|
||||
void receivedPackage(const Device& device, const NetworkPackage& np);
|
||||
public Q_SLOTS:
|
||||
bool sendPackage(const NetworkPackage& np);
|
||||
bool sendPackage(const NetworkPackage& np) const;
|
||||
|
||||
//Public dbus operations
|
||||
public Q_SLOTS:
|
||||
|
|
|
@ -39,10 +39,10 @@ public:
|
|||
const QString& deviceId() { return mDeviceId; }
|
||||
LinkProvider* provider() { return mLinkProvider; }
|
||||
|
||||
virtual bool sendPackage(const NetworkPackage& np) = 0;
|
||||
virtual bool sendPackage(const NetworkPackage& np) const = 0;
|
||||
|
||||
signals:
|
||||
void receivedPackage(const NetworkPackage& np);
|
||||
void receivedPackage(const NetworkPackage& np) const;
|
||||
|
||||
private:
|
||||
QString mDeviceId;
|
||||
|
|
|
@ -31,8 +31,8 @@ class EchoDeviceLink
|
|||
public:
|
||||
EchoDeviceLink(const QString& d, LoopbackLinkProvider* a);
|
||||
|
||||
bool sendPackage(const NetworkPackage& np) {
|
||||
emit receivedPackage(np);
|
||||
bool sendPackage(const NetworkPackage& np) const {
|
||||
Q_EMIT receivedPackage(np);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ TcpDeviceLink::TcpDeviceLink(const QString& d, LinkProvider* a, QTcpSocket* sock
|
|||
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());
|
||||
return written != -1;
|
||||
|
|
|
@ -38,7 +38,7 @@ class TcpDeviceLink
|
|||
public:
|
||||
TcpDeviceLink(const QString& d, LinkProvider* a, QTcpSocket* socket);
|
||||
|
||||
bool sendPackage(const NetworkPackage& np);
|
||||
bool sendPackage(const NetworkPackage& np) const;
|
||||
|
||||
private Q_SLOTS:
|
||||
void dataReceived();
|
||||
|
|
|
@ -101,7 +101,7 @@ void AvahiTcpLinkProvider::dataReceived()
|
|||
|
||||
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()));
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
if (success) {
|
||||
qDebug() << "Handshaking done (i'm the existing device)";
|
||||
emit onNewDeviceLink(*np, dl);
|
||||
Q_EMIT onConnectionReceived(*np, dl);
|
||||
} else {
|
||||
//I think this will never happen
|
||||
qDebug() << "Fallback (2), try reverse connection";
|
||||
|
@ -218,7 +218,7 @@ void BroadcastTcpLinkProvider::dataReceived()
|
|||
|
||||
qDebug() << "Handshaking done (i'm the new device)";
|
||||
|
||||
emit onNewDeviceLink(np, dl);
|
||||
Q_EMIT onConnectionReceived(np, dl);
|
||||
|
||||
disconnect(socket,SIGNAL(readyRead()),this,SLOT(dataReceived()));
|
||||
|
||||
|
@ -228,14 +228,12 @@ void BroadcastTcpLinkProvider::dataReceived()
|
|||
|
||||
}
|
||||
|
||||
void BroadcastTcpLinkProvider::deviceLinkDestroyed(QObject* deviceLink)
|
||||
void BroadcastTcpLinkProvider::deviceLinkDestroyed(QObject* uncastedDeviceLink)
|
||||
{
|
||||
const QString& id = ((DeviceLink*)deviceLink)->deviceId();
|
||||
qDebug() << "deviceLinkDestroyed";
|
||||
if (links.contains(id)) {
|
||||
qDebug() << "removing link from link list";
|
||||
links.remove(id);
|
||||
}
|
||||
DeviceLink* deviceLink = (DeviceLink*)uncastedDeviceLink;
|
||||
Q_EMIT onConnectionLost(deviceLink);
|
||||
const QString& id = deviceLink->deviceId();
|
||||
if (links.contains(id)) links.remove(id);
|
||||
}
|
||||
|
||||
BroadcastTcpLinkProvider::~BroadcastTcpLinkProvider()
|
||||
|
|
|
@ -55,7 +55,8 @@ public Q_SLOTS:
|
|||
Q_SIGNALS:
|
||||
//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.
|
||||
void onNewDeviceLink(const NetworkPackage& identityPackage, DeviceLink*);
|
||||
void onConnectionReceived(const NetworkPackage& identityPackage, DeviceLink*);
|
||||
void onConnectionLost(DeviceLink*);
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -38,6 +38,6 @@ LoopbackLinkProvider::~LoopbackLinkProvider()
|
|||
void LoopbackLinkProvider::setDiscoverable(bool b)
|
||||
{
|
||||
qDebug() << "Echo Device discovery emitted";
|
||||
if (b) emit onNewDeviceLink(identityPackage, echoDeviceLink);
|
||||
if (b) Q_EMIT onConnectionReceived(identityPackage, echoDeviceLink);
|
||||
}
|
||||
|
||||
|
|
|
@ -57,7 +57,7 @@ public:
|
|||
}
|
||||
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:
|
||||
void setId(long id) { mId = id; }
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
|
||||
#include "mpriscontrolpackageinterface.h"
|
||||
|
||||
#include "propertiesdbusinterface.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QDBusConnection>
|
||||
#include <QDBusInterface>
|
||||
|
@ -52,7 +54,7 @@ void MprisControlPackageInterface::serviceOwnerChanged(const QString &name,
|
|||
|
||||
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()) {
|
||||
addPlayer(name);
|
||||
|
@ -62,14 +64,59 @@ 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");
|
||||
//TODO: Make this async
|
||||
QString identity = interface.property("Identity").toString();
|
||||
playerList[identity] = ifaceName;
|
||||
qDebug() << "addPlayer" << ifaceName << identity;
|
||||
QDBusInterface mprisInterface(service, "/org/mpris/MediaPlayer2", "org.mpris.MediaPlayer2");
|
||||
const QString& identity = mprisInterface.property("Identity").toString();
|
||||
playerList[identity] = service;
|
||||
qDebug() << "addPlayer" << service << identity;
|
||||
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::propertiesChanged(const QString& propertyInterface, const QVariantMap& properties)
|
||||
{
|
||||
|
||||
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::removePlayer(const QString& ifaceName)
|
||||
|
@ -78,53 +125,77 @@ void MprisControlPackageInterface::removePlayer(const QString& ifaceName)
|
|||
sendPlayerList();
|
||||
}
|
||||
|
||||
void MprisControlPackageInterface::sendPlayerList()
|
||||
{
|
||||
NetworkPackage np(PACKAGE_TYPE_MPRIS);
|
||||
np.set("playerList",playerList.keys());
|
||||
sendPackage(np);
|
||||
}
|
||||
|
||||
bool MprisControlPackageInterface::receivePackage (const Device& device, const NetworkPackage& np)
|
||||
{
|
||||
Q_UNUSED(device);
|
||||
|
||||
if (np.type() != PACKAGE_TYPE_MPRIS) return false;
|
||||
|
||||
|
||||
QString player = np.get<QString>("player");
|
||||
if (!playerList.contains(player)) {
|
||||
sendPlayerList();
|
||||
return true;
|
||||
//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;
|
||||
}
|
||||
}
|
||||
|
||||
QDBusInterface mprisInterface(playerList[player], "/org/mpris/MediaPlayer2", "org.mpris.MediaPlayer2.Player");
|
||||
|
||||
if (np.get<bool>("requestPlayerList")) {
|
||||
sendPlayerList();
|
||||
}
|
||||
|
||||
QString action = np.get<QString>("action");
|
||||
if (!action.isEmpty()) {
|
||||
//Do something to the mpris interface
|
||||
OrgMprisMediaPlayer2PlayerInterface mprisInterface(playerList[player], "/org/mpris/MediaPlayer2", QDBusConnection::sessionBus());
|
||||
if (np.has("action")) {
|
||||
const QString& action = np.get<QString>("action");
|
||||
qDebug() << "Calling action" << action << "in" << playerList[player];
|
||||
//TODO: Check for valid actions
|
||||
mprisInterface.call(action);
|
||||
sendNowPlaying(mprisInterface);
|
||||
} else if (np.get<bool>("requestNowPlaying")) {
|
||||
sendNowPlaying(mprisInterface);
|
||||
}
|
||||
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;
|
||||
|
||||
|
||||
}
|
||||
if (np.get<bool>("requestVolume")) {
|
||||
int volume = (int)(mprisInterface.volume() * 100);
|
||||
answer.set("volume",volume);
|
||||
somethingToSend = true;
|
||||
|
||||
}
|
||||
if (somethingToSend) {
|
||||
answer.set("player", player);
|
||||
device.sendPackage(answer);
|
||||
}
|
||||
|
||||
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);
|
||||
np.set("nowPlaying",nowPlaying);
|
||||
sendPackage(np);
|
||||
np.set("playerList",playerList.keys());
|
||||
if (device == NULL) Q_EMIT sendPackage(np);
|
||||
else device->sendPackage(np);
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#define MPRISCONTROLPACKAGEINTERFACE_H
|
||||
|
||||
#include "packageinterface.h"
|
||||
#include "mprisdbusinterface.h"
|
||||
|
||||
#include <QSet>
|
||||
#include <QString>
|
||||
|
@ -37,16 +38,16 @@ public:
|
|||
MprisControlPackageInterface();
|
||||
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 propertiesChanged(const QString& interface, const QVariantMap& properties);
|
||||
|
||||
private:
|
||||
QHash<QString, QString> playerList;
|
||||
void addPlayer(const QString& ifaceName);
|
||||
void removePlayer(const QString& ifaceName);
|
||||
void sendPlayerList();
|
||||
void sendNowPlaying(const QDBusInterface& interface);
|
||||
|
||||
void sendPlayerList(const Device* device = 0);
|
||||
int prevVolume;
|
||||
|
||||
};
|
||||
|
||||
|
|
45
daemon/packageinterfaces/mprisdbusinterface.xml
Normal file
45
daemon/packageinterfaces/mprisdbusinterface.xml
Normal file
|
@ -0,0 +1,45 @@
|
|||
<!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>
|
||||
|
23
daemon/packageinterfaces/propertiesInterface.xml
Normal file
23
daemon/packageinterfaces/propertiesInterface.xml
Normal file
|
@ -0,0 +1,23 @@
|
|||
<?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>
|
Loading…
Reference in a new issue