From 7914fc955130f1620732dea2620503ea3dff9bd9 Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Sun, 8 Apr 2012 14:36:06 -0400 Subject: [PATCH] Initial work on notification cleanup --- src/libtomahawk/audio/audioengine.cpp | 96 ++++++------------- src/libtomahawk/audio/audioengine.h | 10 +- .../infoplugins/unix/fdonotifyplugin.cpp | 83 +++++++++++++--- .../infoplugins/unix/fdonotifyplugin.h | 5 + .../infoplugins/unix/mprisplugin.cpp | 12 ++- src/libtomahawk/infosystem/infosystem.h | 1 + src/libtomahawk/tomahawksettings.h | 1 + src/tomahawkapp.cpp | 2 + 8 files changed, 123 insertions(+), 87 deletions(-) diff --git a/src/libtomahawk/audio/audioengine.cpp b/src/libtomahawk/audio/audioengine.cpp index cfa7ceb66..69ab13adc 100644 --- a/src/libtomahawk/audio/audioengine.cpp +++ b/src/libtomahawk/audio/audioengine.cpp @@ -31,6 +31,7 @@ #include "database/databasecommand_logplayback.h" #include "network/servent.h" #include "utils/qnr_iodevicestream.h" +#include "utils/closure.h" #include "headlesscheck.h" #include "infosystem/infosystem.h" #include "album.h" @@ -77,8 +78,6 @@ AudioEngine::AudioEngine() connect( m_audioOutput, SIGNAL( volumeChanged( qreal ) ), SLOT( onVolumeChanged( qreal ) ) ); - connect( this, SIGNAL( sendWaitingNotification() ), SLOT( sendWaitingNotificationSlot() ), Qt::QueuedConnection ); - onVolumeChanged( m_audioOutput->volume() ); #ifndef Q_WS_X11 @@ -137,23 +136,7 @@ AudioEngine::play() setVolume( m_volume ); emit resumed(); - if ( TomahawkSettings::instance()->privateListeningMode() != TomahawkSettings::FullyPrivate ) - { - Tomahawk::InfoSystem::InfoStringHash trackInfo; - - trackInfo["title"] = m_currentTrack->track(); - trackInfo["artist"] = m_currentTrack->artist()->name(); - trackInfo["album"] = m_currentTrack->album()->name(); - trackInfo["albumpos"] = QString::number( m_currentTrack->albumpos() ); - trackInfo["duration"] = QString::number( m_currentTrack->duration() ); - - Tomahawk::InfoSystem::InfoPushData pushData ( - s_aeInfoIdentifier, Tomahawk::InfoSystem::InfoNowResumed, - QVariant::fromValue< Tomahawk::InfoSystem::InfoStringHash >( trackInfo ), - Tomahawk::InfoSystem::PushNoFlag ); - - Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo( pushData ); - } + sendNowPlayingNotification( Tomahawk::InfoSystem::InfoNowResumed ); } else next(); @@ -192,19 +175,12 @@ AudioEngine::stop() setCurrentTrack( Tomahawk::result_ptr() ); - Tomahawk::InfoSystem::InfoTypeMap map; - map[ Tomahawk::InfoSystem::InfoNowStopped ] = QVariant(); - if ( m_waitingOnNewTrack ) - emit sendWaitingNotification(); - else if ( TomahawkSettings::instance()->verboseNotifications() ) - { - QVariantMap stopInfo; - stopInfo["message"] = tr( "Tomahawk is stopped." ); - map[ Tomahawk::InfoSystem::InfoNotifyUser ] = QVariant::fromValue< QVariantMap >( stopInfo ); - } + sendWaitingNotification(); - Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo( s_aeInfoIdentifier, map, Tomahawk::InfoSystem::PushNoFlag ); + Tomahawk::InfoSystem::InfoPushData pushData( s_aeInfoIdentifier, Tomahawk::InfoSystem::InfoNowStopped, QVariant(), Tomahawk::InfoSystem::PushNoFlag ); + + Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo( pushData ); } @@ -326,18 +302,16 @@ AudioEngine::mute() void -AudioEngine::sendWaitingNotificationSlot() const +AudioEngine::sendWaitingNotification() const { tDebug( LOGVERBOSE ) << Q_FUNC_INFO; //since it's async, after this is triggered our result could come in, so don't show the popup in that case if ( !m_playlist.isNull() && m_playlist->hasNextItem() ) return; - QVariantMap retryInfo; - retryInfo["message"] = QString( "The current track could not be resolved. Tomahawk will pick back up with the next resolvable track from this source." ); Tomahawk::InfoSystem::InfoPushData pushData ( - s_aeInfoIdentifier, Tomahawk::InfoSystem::InfoNotifyUser, - QVariant::fromValue< QVariantMap >( retryInfo ), + s_aeInfoIdentifier, Tomahawk::InfoSystem::InfoTrackUnresolved, + QVariant(), Tomahawk::InfoSystem::PushNoFlag ); Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo( pushData ); @@ -345,14 +319,15 @@ AudioEngine::sendWaitingNotificationSlot() const void -AudioEngine::sendNowPlayingNotification() +AudioEngine::sendNowPlayingNotification( const Tomahawk::InfoSystem::InfoType type ) { #ifndef ENABLE_HEADLESS if ( m_currentTrack->album().isNull() || m_currentTrack->album()->infoLoaded() ) - onNowPlayingInfoReady(); + onNowPlayingInfoReady( type ); else { - connect( m_currentTrack->album().data(), SIGNAL( updated() ), SLOT( onNowPlayingInfoReady() ), Qt::UniqueConnection ); + _detail::Closure* closure = NewClosure( m_currentTrack->album().data(), SIGNAL( updated() ), const_cast(this), SLOT( onNowPlayingInfoReady( const Tomahawk::InfoSystem::InfoType ) ), type ); + closure->setAutoDelete( false ); m_currentTrack->album()->cover( QSize( 0, 0 ) ); } #endif @@ -360,7 +335,7 @@ AudioEngine::sendNowPlayingNotification() void -AudioEngine::onNowPlayingInfoReady() +AudioEngine::onNowPlayingInfoReady( const Tomahawk::InfoSystem::InfoType type ) { tDebug( LOGVERBOSE ) << Q_FUNC_INFO; if ( m_currentTrack.isNull() || @@ -370,26 +345,29 @@ AudioEngine::onNowPlayingInfoReady() if ( !m_currentTrack->album().isNull() && sender() && m_currentTrack->album().data() != sender() ) return; - + QVariantMap playInfo; - playInfo["message"] = tr( "Tomahawk is playing \"%1\" by %2%3." ) - .arg( m_currentTrack->track() ) - .arg( m_currentTrack->artist()->name() ) - .arg( m_currentTrack->album().isNull() ? QString() : QString( " %1" ).arg( tr( "on album %1" ).arg( m_currentTrack->album()->name() ) ) ); if ( !m_currentTrack->album().isNull() ) { #ifndef ENABLE_HEADLESS QImage cover; cover = m_currentTrack->album()->cover( QSize( 0, 0 ) ).toImage(); - playInfo["image"] = QVariant( cover ); + playInfo["cover"] = QVariant( cover ); #endif } - Tomahawk::InfoSystem::InfoPushData pushData ( - s_aeInfoIdentifier, Tomahawk::InfoSystem::InfoNotifyUser, - QVariant::fromValue< QVariantMap >( playInfo ), - Tomahawk::InfoSystem::PushNoFlag ); + Tomahawk::InfoSystem::InfoStringHash trackInfo; + trackInfo["title"] = m_currentTrack->track(); + trackInfo["artist"] = m_currentTrack->artist()->name(); + trackInfo["album"] = m_currentTrack->album()->name(); + trackInfo["duration"] = QString::number( m_currentTrack->duration() ); + trackInfo["albumpos"] = QString::number( m_currentTrack->albumpos() ); + + playInfo["trackinfo"] = QVariant::fromValue< Tomahawk::InfoSystem::InfoStringHash >( trackInfo ); + playInfo["private"] = TomahawkSettings::instance()->privateListeningMode(); + + Tomahawk::InfoSystem::InfoPushData pushData ( s_aeInfoIdentifier, type, playInfo, Tomahawk::InfoSystem::PushShortUrlFlag ); Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo( pushData ); } @@ -468,29 +446,13 @@ AudioEngine::loadTrack( const Tomahawk::result_ptr& result ) m_mediaObject->play(); emit started( m_currentTrack ); - if ( TomahawkSettings::instance()->verboseNotifications() ) - sendNowPlayingNotification(); - if ( TomahawkSettings::instance()->privateListeningMode() != TomahawkSettings::FullyPrivate ) { DatabaseCommand_LogPlayback* cmd = new DatabaseCommand_LogPlayback( m_currentTrack, DatabaseCommand_LogPlayback::Started ); Database::instance()->enqueue( QSharedPointer(cmd) ); - - Tomahawk::InfoSystem::InfoStringHash trackInfo; - trackInfo["title"] = m_currentTrack->track(); - trackInfo["artist"] = m_currentTrack->artist()->name(); - trackInfo["album"] = m_currentTrack->album()->name(); - trackInfo["duration"] = QString::number( m_currentTrack->duration() ); - trackInfo["albumpos"] = QString::number( m_currentTrack->albumpos() ); - - Tomahawk::InfoSystem::InfoPushData pushData ( - s_aeInfoIdentifier, - Tomahawk::InfoSystem::InfoNowPlaying, - QVariant::fromValue< Tomahawk::InfoSystem::InfoStringHash >( trackInfo ), - Tomahawk::InfoSystem::PushShortUrlFlag ); - - Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo( pushData ); } + + sendNowPlayingNotification( Tomahawk::InfoSystem::InfoNowPlaying ); } } diff --git a/src/libtomahawk/audio/audioengine.h b/src/libtomahawk/audio/audioengine.h index 345572401..227f5d7bf 100644 --- a/src/libtomahawk/audio/audioengine.h +++ b/src/libtomahawk/audio/audioengine.h @@ -27,6 +27,8 @@ #include #include +#include "libtomahawk/infosystem/infosystem.h" + #include "result.h" #include "typedefs.h" #include "playlistinterface.h" @@ -117,8 +119,6 @@ signals: void error( AudioEngine::AudioErrorCode errorCode ); - void sendWaitingNotification(); - private slots: bool loadTrack( const Tomahawk::result_ptr& result ); void loadPreviousTrack(); @@ -130,10 +130,10 @@ private slots: void timerTriggered( qint64 time ); void setCurrentTrack( const Tomahawk::result_ptr& result ); - void onNowPlayingInfoReady(); + void onNowPlayingInfoReady( const Tomahawk::InfoSystem::InfoType type ); void onPlaylistNextTrackReady(); - void sendWaitingNotificationSlot() const; + void sendWaitingNotification() const; private: void setState( AudioState state ); @@ -141,7 +141,7 @@ private: bool isHttpResult( const QString& ) const; bool isLocalResult( const QString& ) const; - void sendNowPlayingNotification(); + void sendNowPlayingNotification( const Tomahawk::InfoSystem::InfoType type ); QSharedPointer m_input; diff --git a/src/libtomahawk/infosystem/infoplugins/unix/fdonotifyplugin.cpp b/src/libtomahawk/infosystem/infoplugins/unix/fdonotifyplugin.cpp index b62ffc6e7..43b4e4582 100644 --- a/src/libtomahawk/infosystem/infoplugins/unix/fdonotifyplugin.cpp +++ b/src/libtomahawk/infosystem/infoplugins/unix/fdonotifyplugin.cpp @@ -54,43 +54,100 @@ FdoNotifyPlugin::FdoNotifyPlugin() : InfoPlugin() { qDebug() << Q_FUNC_INFO; - m_supportedPushTypes << Tomahawk::InfoSystem::InfoNotifyUser; + m_supportedPushTypes << InfoNotifyUser << InfoNowPlaying << InfoTrackUnresolved << InfoNowStopped; } + FdoNotifyPlugin::~FdoNotifyPlugin() { qDebug() << Q_FUNC_INFO; } + void FdoNotifyPlugin::pushInfo( Tomahawk::InfoSystem::InfoPushData pushData ) { qDebug() << Q_FUNC_INFO; QVariant inputData = pushData.infoPair.second; - if ( pushData.type != Tomahawk::InfoSystem::InfoNotifyUser || !inputData.canConvert< QVariantMap >() ) + + switch ( pushData.type ) { - qDebug() << Q_FUNC_INFO << " not the right type or could not convert the hash"; - return; - } - QVariantMap hash = inputData.value< QVariantMap >(); - if ( !hash.contains( "message" ) ) - { - qDebug() << Q_FUNC_INFO << " hash did not contain a message"; - return; + case Tomahawk::InfoSystem::InfoTrackUnresolved: + notifyUser( "The current track could not be resolved. Tomahawk will pick back up with the next resolvable track from this source." ); + return; + + case Tomahawk::InfoSystem::InfoNotifyUser: + notifyUser( pushData.infoPair.second.toString() ); + return; + + case Tomahawk::InfoSystem::InfoNowStopped: + notifyUser( "Tomahawk is stopped." ); + return; + + case Tomahawk::InfoSystem::InfoNowPlaying: + nowPlaying( pushData.infoPair.second ); + return; + + default: + return; } +} + + +void +FdoNotifyPlugin::notifyUser( const QString &messageText ) +{ QDBusMessage message = QDBusMessage::createMethodCall( "org.freedesktop.Notifications", "/org/freedesktop/Notifications", "org.freedesktop.Notifications", "Notify" ); QList arguments; arguments << QString( "Tomahawk" ); //app_name arguments << quint32( 0 ); //notification_id arguments << QString(); //app_icon arguments << QString( "Tomahawk" ); //summary - arguments << hash[ "message" ].toString(); //body + arguments << messageText; //body arguments << QStringList(); //actions QVariantMap dict; dict["desktop-entry"] = QString( "tomahawk" ); - if ( hash.contains( "image" ) && hash[ "image" ].canConvert< QImage >() ) - dict[ "image_data" ] = ImageConverter::variantForImage( hash[ "image" ].value< QImage >() ); + dict[ "image_data" ] = ImageConverter::variantForImage( QImage( RESPATH "icons/tomahawk-icon-128x128.png" ) ); + arguments << dict; //hints + arguments << qint32( -1 ); //expire_timeout + message.setArguments( arguments ); + QDBusConnection::sessionBus().send( message ); +} + + +void +FdoNotifyPlugin::nowPlaying( const QVariant &input ) +{ + if ( !input.canConvert< QVariantMap >() ) + return; + + QVariantMap map = input.toMap(); + + if ( !map.contains( "trackinfo" ) || !map[ "trackinfo" ].canConvert< Tomahawk::InfoSystem::InfoStringHash >() ) + return; + + InfoStringHash hash = map[ "trackinfo" ].value< Tomahawk::InfoSystem::InfoStringHash >(); + if ( !hash.contains( "title" ) || !hash.contains( "artist" ) || !hash.contains( "album" ) ) + return; + + QString messageText = tr( "Tomahawk is playing \"%1\" by %2%3." ) + .arg( hash[ "title" ] ) + .arg( hash[ "artist" ] ) + .arg( hash[ "album" ].isEmpty() ? QString() : QString( " %1" ).arg( tr( "on album %1" ).arg( hash[ "album" ] ) ) ); + + QDBusMessage message = QDBusMessage::createMethodCall( "org.freedesktop.Notifications", "/org/freedesktop/Notifications", "org.freedesktop.Notifications", "Notify" ); + QList arguments; + arguments << QString( "Tomahawk" ); //app_name + arguments << quint32( 0 ); //notification_id + arguments << QString(); //app_icon + arguments << QString( "Tomahawk" ); //summary + arguments << messageText; //body + arguments << QStringList(); //actions + QVariantMap dict; + dict["desktop-entry"] = QString( "tomahawk" ); + if ( map.contains( "cover" ) && map[ "cover" ].canConvert< QImage >() ) + dict[ "image_data" ] = ImageConverter::variantForImage( map[ "cover" ].value< QImage >() ); else dict[ "image_data" ] = ImageConverter::variantForImage( QImage( RESPATH "icons/tomahawk-icon-128x128.png" ) ); arguments << dict; //hints diff --git a/src/libtomahawk/infosystem/infoplugins/unix/fdonotifyplugin.h b/src/libtomahawk/infosystem/infoplugins/unix/fdonotifyplugin.h index de24f8dda..c12621ff3 100644 --- a/src/libtomahawk/infosystem/infoplugins/unix/fdonotifyplugin.h +++ b/src/libtomahawk/infosystem/infoplugins/unix/fdonotifyplugin.h @@ -49,6 +49,11 @@ protected slots: Q_UNUSED( criteria ); Q_UNUSED( requestData ); } + +private: + void notifyUser( const QString &messageText ); + + void nowPlaying( const QVariant &input ); }; } diff --git a/src/libtomahawk/infosystem/infoplugins/unix/mprisplugin.cpp b/src/libtomahawk/infosystem/infoplugins/unix/mprisplugin.cpp index 9db9f72f7..bc94222d9 100644 --- a/src/libtomahawk/infosystem/infoplugins/unix/mprisplugin.cpp +++ b/src/libtomahawk/infosystem/infoplugins/unix/mprisplugin.cpp @@ -513,10 +513,18 @@ MprisPlugin::stateChanged( AudioState newState, AudioState oldState ) void MprisPlugin::audioStarted( const QVariant& input ) { - if ( !input.canConvert< Tomahawk::InfoSystem::InfoStringHash >() ) + if ( !input.canConvert< QVariantMap >() ) return; - InfoStringHash hash = input.value< Tomahawk::InfoSystem::InfoStringHash >(); + QVariantMap map = input.toMap(); + + if ( map.contains( "private" ) && map[ "private" ].value< TomahawkSettings::PrivateListeningMode >() == TomahawkSettings::FullyPrivate ) + return; + + if ( !map.contains( "trackinfo" ) || !map[ "trackinfo" ].canConvert< Tomahawk::InfoSystem::InfoStringHash >() ) + return; + + InfoStringHash hash = map[ "trackinfo" ].value< Tomahawk::InfoSystem::InfoStringHash >(); if ( !hash.contains( "title" ) || !hash.contains( "artist" ) || !hash.contains( "album" ) ) return; diff --git a/src/libtomahawk/infosystem/infosystem.h b/src/libtomahawk/infosystem/infosystem.h index dacbae5a7..9f0d8a811 100644 --- a/src/libtomahawk/infosystem/infosystem.h +++ b/src/libtomahawk/infosystem/infosystem.h @@ -122,6 +122,7 @@ enum InfoType { // as items are saved in cache, mark them here to not change the InfoNowPaused = 81, InfoNowResumed = 82, InfoNowStopped = 83, + InfoTrackUnresolved = 84, InfoLove = 90, InfoUnLove = 91, diff --git a/src/libtomahawk/tomahawksettings.h b/src/libtomahawk/tomahawksettings.h index 5200bc524..6fc844be3 100644 --- a/src/libtomahawk/tomahawksettings.h +++ b/src/libtomahawk/tomahawksettings.h @@ -212,5 +212,6 @@ private: static TomahawkSettings* s_instance; }; +Q_DECLARE_METATYPE( TomahawkSettings::PrivateListeningMode ); #endif diff --git a/src/tomahawkapp.cpp b/src/tomahawkapp.cpp index 81aa452bf..dbd1ab4b7 100644 --- a/src/tomahawkapp.cpp +++ b/src/tomahawkapp.cpp @@ -450,6 +450,8 @@ TomahawkApp::registerMetaTypes() qRegisterMetaType< Tomahawk::InfoSystem::InfoPlugin* >( "Tomahawk::InfoSystem::InfoPlugin*" ); qRegisterMetaType< QList< Tomahawk::InfoSystem::InfoStringHash > >("QList< Tomahawk::InfoSystem::InfoStringHash > "); + qRegisterMetaType< TomahawkSettings::PrivateListeningMode >( "TomahawkSettings::PrivateListeningMode" ); + qRegisterMetaTypeStreamOperators< QList< Tomahawk::InfoSystem::InfoStringHash > >("QList< Tomahawk::InfoSystem::InfoStringHash > "); qRegisterMetaType< QPersistentModelIndex >( "QPersistentModelIndex" );