Commit 6e7fb0b5 authored by Christian Esken's avatar Christian Esken
Browse files

Fixes for memory leaks, unitialized values. Also do error checks before evaluating DBUS reply.

CCBUGS: 317926
parent 8d3b0394
......@@ -102,7 +102,17 @@ int Mixer_MPRIS2::mediaControl(QString applicationId, QString commandName)
void Mixer_MPRIS2::mediaContolReplyIncoming(QDBusPendingCallWatcher* watcher)
{
const QDBusMessage& msg = watcher->reply();
if ( msg.type() == QDBusMessage::ErrorMessage )
{
kError(67100) << "ERROR in Media control operation, path=" << msg.path() << ", msg=" << msg;
watcher->deleteLater();
return;
}
QObject *obj = watcher->parent();
watcher->deleteLater();
MPrisControl* mad = qobject_cast<MPrisControl*>(obj);
if (mad == 0)
{
......@@ -113,13 +123,11 @@ void Mixer_MPRIS2::mediaContolReplyIncoming(QDBusPendingCallWatcher* watcher)
QString busDestination = mad->getBusDestination();
QString readableName = id; // Start with ID, but replace with reply (if exists)
kDebug() << "Media control for id=" << id << ", busDestination" << busDestination << ", name= " << readableName;
const QDBusMessage& msg = watcher->reply();
if ( msg.type() == QDBusMessage::ErrorMessage )
{
kError(67100) << "ERROR in Media control operation, id=" << id << ": " << msg;
}
kDebug() << "Media control for id=" << id << ", path=" << msg.path() << ", interface=" << msg.interface() << ", busDestination" << busDestination << ", name= " << readableName;
kDebug() << "msg=" << msg;
}
/**
......@@ -384,59 +392,70 @@ void Mixer_MPRIS2::addMprisControl(QString busDestination)
connect(watchIdentity, SIGNAL(finished(QDBusPendingCallWatcher *)), this, SLOT(plugControlIdIncoming(QDBusPendingCallWatcher *)));
}
void Mixer_MPRIS2::plugControlIdIncoming(QDBusPendingCallWatcher* watcher)
MixDevice::ChannelType Mixer_MPRIS2::getChannelTypeFromPlayerId(const QString& id)
{
QObject *obj = watcher->parent();
MPrisControl* mad = qobject_cast<MPrisControl*>(obj);
if (mad == 0)
// TODO This hardcoded application list is a quick hack. It should be generalized.
MixDevice::ChannelType ct = MixDevice::APPLICATION_STREAM;
if (id.startsWith("amarok"))
{
kWarning() << "Ignoring unexpected Control Id";
return;
ct = MixDevice::APPLICATION_AMAROK;
}
else if (id.startsWith("banshee"))
{
ct = MixDevice::APPLICATION_BANSHEE;
}
else if (id.startsWith("vlc"))
{
ct = MixDevice::APPLICATION_VLC;
}
else if (id.startsWith("xmms"))
{
ct = MixDevice::APPLICATION_XMM2;
}
else if (id.startsWith("tomahawk"))
{
ct = MixDevice::APPLICATION_TOMAHAWK;
}
else if (id.startsWith("clementine"))
{
ct = MixDevice::APPLICATION_CLEMENTINE;
}
QString id = mad->getId();
QString busDestination = mad->getBusDestination();
QString readableName = id; // Start with ID, but replace with reply (if exists)
kDebug() << "Plugging id=" << id << ", busDestination" << busDestination << ", name= " << readableName;
return ct;
}
void Mixer_MPRIS2::plugControlIdIncoming(QDBusPendingCallWatcher* watcher)
{
const QDBusMessage& msg = watcher->reply();
if ( msg.type() == QDBusMessage::ReplyMessage )
if ( msg.type() == QDBusMessage::ReplyMessage )
{
QObject *obj = watcher->parent();
MPrisControl* mad = qobject_cast<MPrisControl*>(obj);
if (mad == 0)
{
QList<QVariant> repl = msg.arguments();
if ( ! repl.isEmpty() )
{
QVariant qv = repl.at(0);
// We have to do some very ugly casting from QVariant to QDBusVariant to QVariant. This API totally sucks.
QDBusVariant dbusVariant = qvariant_cast<QDBusVariant>(qv);
QVariant result2 = dbusVariant.variant();
readableName = result2.toString();
qDebug() << "REPLY " << result2.type() << ": " << readableName;
}
kWarning() << "Ignoring unexpected Control Id";
watcher->deleteLater();
return;
}
else
QString id = mad->getId();
QString busDestination = mad->getBusDestination();
QString readableName = id; // Start with ID, but replace with reply (if exists)
kDebug() << "Plugging id=" << id << ", busDestination" << busDestination << ", name= " << readableName;
QList<QVariant> repl = msg.arguments();
if ( ! repl.isEmpty() )
{
qWarning() << "Error (" << msg.type() << "): " << msg.errorName() << " " << msg.errorMessage();
}
QVariant qv = repl.at(0);
// We have to do some very ugly casting from QVariant to QDBusVariant to QVariant. This API totally sucks.
QDBusVariant dbusVariant = qvariant_cast<QDBusVariant>(qv);
QVariant result2 = dbusVariant.variant();
readableName = result2.toString();
// TODO This hardcoded application list is a quick hack. It should be generalized.
MixDevice::ChannelType ct = MixDevice::APPLICATION_STREAM;
if (id.startsWith("amarok")) {
ct = MixDevice::APPLICATION_AMAROK;
}
else if (id.startsWith("banshee")) {
ct = MixDevice::APPLICATION_BANSHEE;
}
else if (id.startsWith("xmms")) {
ct = MixDevice::APPLICATION_XMM2;
}
else if (id.startsWith("tomahawk")) {
ct = MixDevice::APPLICATION_TOMAHAWK;
}
else if (id.startsWith("clementine")) {
ct = MixDevice::APPLICATION_CLEMENTINE;
}
qDebug() << "REPLY " << result2.type() << ": " << readableName;
// TODO This hardcoded application list is a quick hack. It should be generalized.
MixDevice::ChannelType ct = getChannelTypeFromPlayerId(id);
MixDevice* mdNew = new MixDevice(_mixer, id, readableName, ct);
// MPRIS2 doesn't support an actual mute switch. Mute is defined as volume = 0.0
// Thus we won't add the playback switch
......@@ -456,8 +475,17 @@ void Mixer_MPRIS2::plugControlIdIncoming(QDBusPendingCallWatcher* watcher)
sessionBus.connect(busDestination, QString("/Player"), "org.freedesktop.MediaPlayer", "TrackChange", mad, SLOT(trackChangedIncoming(QVariantMap)) );
volumeChanged(mad, mad->playerIfc->property("Volume").toDouble());
// Push notifyToReconfigureControls to stack, so it will not be executed synchronously
notifyToReconfigureControlsAsync(id);
}
}
else
{
qWarning() << "Error (" << msg.type() << "): " << msg.errorName() << " " << msg.errorMessage();
}
// Push notifyToReconfigureControls to stack, so it will not be executed synchronously
watcher->deleteLater();
}
......
......@@ -149,6 +149,7 @@ private:
int addAllRunningPlayersAndInitHotplug();
void volumeChangedInternal(shared_ptr<MixDevice> md, int volumePercentage);
QString busDestinationToControlId(const QString& busDestination);
MixDevice::ChannelType getChannelTypeFromPlayerId(const QString& id);
QMap<QString,MPrisControl*> controls;
QString _id;
......
......@@ -91,6 +91,8 @@ static const QString channelTypeToIconName( MixDevice::ChannelType type )
return "tomahawk";
case MixDevice::APPLICATION_CLEMENTINE:
return "clementine";
case MixDevice::APPLICATION_VLC:
return "vlc";
case MixDevice::APPLICATION_STREAM:
return "mixer-pcm";
......@@ -124,6 +126,7 @@ void MixDevice::init( Mixer* mixer, const QString& id, const QString& name, con
_dbusControlWrapper = 0; // will be set in addToPool()
_mixer = mixer;
_id = id;
_enumCurrentId = 0;
mediaPlayControl = false;
mediaNextControl = false;
mediaPrevControl = false;
......@@ -258,6 +261,7 @@ void MixDevice::addEnums(QList<QString*>& ref_enumList)
_enumValues.append( *(ref_enumList.at(i)) );
}
}
_enumCurrentId = 0; // default is first entry (used if we don't get a value via backend or volume restore)
}
......
......@@ -90,7 +90,11 @@ public:
APPLICATION_BANSHEE,
APPLICATION_XMM2,
APPLICATION_TOMAHAWK,
APPLICATION_CLEMENTINE
APPLICATION_CLEMENTINE,
// Hint: VLC still has compatibility problems:
// 2.0 is not detected
// 2.2-nightly has volume issues (total overdrive)
APPLICATION_VLC,
};
enum SwitchType { OnOff, Mute, Capture, Activator };
......
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