Commit f2291ba1 authored by Christian Esken's avatar Christian Esken
Browse files

Change MPRIS backend to asynchronous communication

CCBUGS: 317926
parent 95bce581
......@@ -782,7 +782,8 @@ Mixer_ALSA::readVolumeFromHW( const QString& id, shared_ptr<MixDevice> md )
case Volume::REARSIDERIGHT: ret = snd_mixer_selem_get_capture_volume( elem, SND_MIXER_SCHN_SIDE_RIGHT , &vol); break;
default: kDebug() << "FATAL: Unknown channel type for capture << " << vc.chid << " ... please report this"; break;
}
if ( ret != 0 ) kDebug() << "readVolumeFromHW(" << devnum << ") [get_capture_volume] failed, errno=" << ret;
if ( ret != 0 )
kDebug() << "readVolumeFromHW(" << devnum << ") [get_capture_volume] failed, errno=" << ret;
else volumeCapture.setVolume( vc.chid, vol);
}
} // has capture volume
......
......@@ -186,12 +186,16 @@ void Mixer_Backend::readSetFromHW()
*/
md->setEnumId( enumIdHW(md->id()) );
}
// Transition the outer return value with the value from this loop iteration
if ( retLoop == Mixer::OK && ret == Mixer::OK_UNCHANGED )
{
// Unchanged => OK (Changed)
ret = Mixer::OK;
}
else if ( retLoop != Mixer::OK && retLoop != Mixer::OK_UNCHANGED )
{
// If current ret from loop in not OK, then transiton to that: ret (Something) => retLoop (Error)
ret = retLoop;
}
}
......@@ -201,6 +205,7 @@ void Mixer_Backend::readSetFromHW()
// We explicitely exclude Mixer::OK_UNCHANGED and Mixer::ERROR_READ
if ( needsPolling() )
{
// Upgrade polling frequency temporarily to be more smoooooth
_pollingTimer->setInterval(POLL_OSS_RATE_FAST);
QTime fastPollingEndsAt = QTime::currentTime ();
fastPollingEndsAt = fastPollingEndsAt.addSecs(5);
......
......@@ -93,7 +93,14 @@ int Mixer_MPRIS2::mediaControl(QString applicationId, QString commandName)
if ( mad == 0 )
return 0; // Might have disconnected recently => simply ignore command
QDBusMessage msg = mad->playerIfc->callWithArgumentList(QDBus::NoBlock, commandName, arg);
// QDBusMessage msg = mad->playerIfc->callWithArgumentList(QDBus::NoBlock, commandName, arg);
QDBusPendingReply<QVariant > repl2 = mad->playerIfc->asyncCall(commandName);
repl2.waitForFinished();
QDBusMessage msg = repl2.reply();
if ( msg.type() == QDBusMessage::ErrorMessage )
{
kError(67100) << "ERROR SET " << applicationId << ": " << msg;
......@@ -111,7 +118,16 @@ int Mixer_MPRIS2::readVolumeFromHW( const QString& id, shared_ptr<MixDevice> md)
arg.append(QString("org.mpris.MediaPlayer2.Player"));
arg.append(QString("Volume"));
MPrisAppdata* mad = apps.value(id);
QDBusMessage msg = mad->propertyIfc->callWithArgumentList(QDBus::Block, "Get", arg);
// QDBusMessage msg = mad->propertyIfc->callWithArgumentList(QDBus::Block, "Get", arg);
QVariant v1 = QVariant(QString("org.mpris.MediaPlayer2.Player"));
QVariant v2 = QVariant(QString("Volume"));
QDBusPendingReply<QVariant > repl2 = mad->propertyIfc->asyncCall("Get", v1, v2);
repl2.waitForFinished();
QDBusMessage msg = repl2.reply();
if ( msg.type() == QDBusMessage::ReplyMessage )
{
QList<QVariant> repl = msg.arguments();
......@@ -124,6 +140,7 @@ int Mixer_MPRIS2::readVolumeFromHW( const QString& id, shared_ptr<MixDevice> md)
volInt = result2.toFloat() *100;
volumeChangedInternal(md, volInt);
kDebug() << "changed vol" << volInt;
// kDebug(67100) << "REPLY " << qv.type() << ": " << volInt;
}
else
......@@ -142,11 +159,13 @@ void Mixer_MPRIS2::volumeChanged(MPrisAppdata* mad, double newVolume)
{
shared_ptr<MixDevice> md = m_mixDevices.get(mad->id);
int volInt = newVolume *100;
kDebug() << "changed" << volInt;
volumeChangedInternal(md, volInt);
}
void Mixer_MPRIS2::volumeChangedInternal(shared_ptr<MixDevice> md, int volumePercentage)
{
kDebug() << "changed i1" << volumePercentage;
if ( md->isVirtuallyMuted() && volumePercentage == 0)
{
// Special code path for virtual mute switches. Don't write back the volume if it is muted in the KMix GUI
......@@ -157,6 +176,7 @@ void Mixer_MPRIS2::volumeChangedInternal(shared_ptr<MixDevice> md, int volumePer
vol.setVolume( Volume::LEFT, volumePercentage);
md->setMuted(volumePercentage == 0);
emit controlChanged();
kDebug() << "changed i2" << volumePercentage;
// md->playbackVolume().setVolume(vol);
}
......@@ -189,7 +209,19 @@ int Mixer_MPRIS2::writeVolumeToHW( const QString& id, shared_ptr<MixDevice> md )
arg << QVariant::fromValue(QDBusVariant(volFloat));
MPrisAppdata* mad = apps.value(id);
QDBusMessage msg = mad->propertyIfc->callWithArgumentList(QDBus::NoBlock, "Set", arg);
// QDBusMessage msg = mad->propertyIfc->callWithArgumentList(QDBus::NoBlock, "Set", arg);
QVariant v1 = QVariant(QString("org.mpris.MediaPlayer2.Player"));
QVariant v2 = QVariant(QString("Volume"));
QVariant v3 = QVariant::fromValue(QDBusVariant(volFloat));
// QVariant v3 = QVariant(volFloat);
QDBusPendingReply<QVariant > repl2 = mad->propertyIfc->asyncCall("Set", v1, v2, v3);
repl2.waitForFinished();
QDBusMessage msg = repl2.reply();
if ( msg.type() == QDBusMessage::ErrorMessage )
{
kError(67100) << "ERROR SET " << id << ": " << msg;
......@@ -277,6 +309,24 @@ int Mixer_MPRIS2::addAllRunningPlayersAndInitHotplug()
#include <unistd.h>
//QDBusMessage* Mixer_MPRIS2::dbusGetAsyncReply(char method[], QDBusInterface* qdbi)
//{
// const QList<QVariant> arg;
// return dbusGetAsyncReply(method, arg, qdbi);
//}
//QDBusMessage* Mixer_MPRIS2::dbusGetAsyncReply(const char method[], const QList<QVariant>& arg, QDBusInterface* qdbi)
//{
// QDBusPendingReply<QStringList> repl = qdbi->asyncCallWithArgumentList(method, arg);
// repl.waitForFinished();
// QDBusMessage msg = repl.reply();
// if (! msg.type() == QDBusMessage::ReplyMessage )
// {
// kWarning() << "Did not receive DBUS reply for method=" << method << "; arg=" << arg;
// return 0;
// }
// return &msg;
//}
/**
* Add the MPRIS control designated by the DBUS busDestination
* to the internal apps list.
......@@ -319,13 +369,51 @@ void Mixer_MPRIS2::addMprisControl(QDBusConnection& conn, QString busDestination
QString readableName = id;
/*
* QDBusInterface dbusIfc("org.freedesktop.DBus", "/org/freedesktop/DBus",
"org.freedesktop.DBus", dbusConn);
QDBusPendingReply<QStringList> repl = dbusIfc.asyncCall("ListNames");
repl.waitForFinished();
*
*/
// if (id != "clementine")
// {
QList<QVariant> arg;
arg.append(QString("org.mpris.MediaPlayer2"));
arg.append(QString("Identity"));
QDBusMessage msg = mad->propertyIfc->callWithArgumentList(QDBus::Block, "Get", arg);
kDebug() << "--- Identity";
QVariant v1 = QVariant(QString("org.mpris.MediaPlayer2"));
QVariant v2 = QVariant(QString("Identity"));
/*
* WTF: - asyncCall("Get", arg) : returns an error message (see below)
* - asyncCallWithArgumentList("Get", arg) : returns an error message (see below)
* - callWithArgumentList(QDBus::Block, "Get", arg) : works
* - syncCall("Get", v1, v2) : works
*
* kmix(13543) Mixer_MPRIS2::addMprisControl: (marok), msg2= QDBusMessage(type=Error, service=":1.44", error name="org.freedesktop.DBus.Error.UnknownMethod", error message="No such method 'Get' in interface 'org.freedesktop.DBus.Properties' at object path '/org/mpris/MediaPlayer2' (signature 'av')", signature="s", contents=("No such method 'Get' in interface 'org.freedesktop.DBus.Properties' at object path '/org/mpris/MediaPlayer2' (signature 'av')") ) , isValid= false , isFinished= true , isError= true
*
* This behavior is total counter-intuitive :-(((
*/
//QDBusPendingReply<QVariant > repl2 = mad->propertyIfc->asyncCall("Get", arg);
QDBusPendingReply<QVariant > repl2 = mad->propertyIfc->asyncCall("Get", v1, v2);
repl2.waitForFinished();
QDBusMessage msg = repl2.reply();
// QDBusMessage msg = mad->propertyIfc->callWithArgumentList(QDBus::Block, "Get", arg);
kDebug() << "(marok), msg=" << msg;
// kDebug() << "(marok), msg2=" << msg2 << ", isValid=" << repl2.isValid() << ", isFinished=" << repl2.isFinished() << ", isError=" << repl2.isError();
//char method[] = "Get";
// QDBusMessage* msg = dbusGetAsyncReply("Get", arg, mad->propertyIfc);
// if ( !repl.isError())
// {
//msg = conn.call(query, QDBus::Block, 5);
if ( msg.type() == QDBusMessage::ReplyMessage )
{
......@@ -444,8 +532,8 @@ void MPrisAppdata::volumeChangedIncoming(QString /*ifc*/,QVariantMap msg ,QStrin
QMap<QString, QVariant>::iterator v = msg.find("Volume");
if (v != msg.end() )
{
// kDebug(67100) << "volumeChanged incoming: !!!!!!!!!" ;
double volDouble = v.value().toDouble();
kDebug(67100) << "volumeChanged incoming: vol=" << volDouble;
emit volumeChanged( this, volDouble);
}
......
......@@ -81,7 +81,9 @@ private:
int addAllRunningPlayersAndInitHotplug();
void notifyToReconfigureControls();
void volumeChangedInternal(shared_ptr<MixDevice> md, int volumePercentage);
// static QDBusMessage* dbusGetAsyncReply(char method[], QDBusInterface* mad);
// static QDBusMessage* dbusGetAsyncReply(const char method[], const QList<QVariant>& arg, QDBusInterface* mad);
QMap<QString,MPrisAppdata*> apps;
QString _id;
};
......
......@@ -20,6 +20,6 @@
*/
#ifndef APP_VERSION
#define APP_VERSION "4.3"
#define APP_VERSION "4.4"
#define KMIX_CONFIG_VERSION 3
#endif // APP_VERSION
......@@ -272,7 +272,7 @@ Application: KMix (kmix), signal: Segmentation fault
// kDebug(67100) << "Add mixer to tray popup? " << mixer2->id();
foreach ( shared_ptr<MixDevice> md, mixer2->getMixSet() )
{
kDebug(67100) << "Add to tray popup? " << md->id();
// kDebug(67100) << "Add to tray popup? " << md->id();
if (md->isApplicationStream())
{
_mixSet.append(md);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment