1
0
mirror of https://github.com/tomahawk-player/tomahawk.git synced 2025-03-21 16:29:43 +01:00

Merge pull request from tomahawk-player/upower-integration

Add support for UPower
This commit is contained in:
Uwe L. Korn 2013-05-31 13:07:17 -07:00
commit 44e0c538f7
9 changed files with 555 additions and 0 deletions

@ -43,6 +43,7 @@ option(WITH_BREAKPAD "Build with breakpad integration" ON)
option(WITH_CRASHREPORTER "Build with CrashReporter" ON)
option(WITH_BINARY_ATTICA "Enable support for downloading binary resolvers automatically" ON)
option(LEGACY_KDE_INTEGRATION "Install tomahawk.protocol file, deprecated since 4.6.0" OFF)
OPTION(WITH_UPOWER "Build with support for UPower events" OFF)
IF( CMAKE_SYSTEM_PROCESSOR MATCHES "arm" )
message(STATUS "Build of breakpad library disabled on this platform.")
@ -186,6 +187,10 @@ if(BUILD_GUI AND UNIX AND NOT APPLE)
find_package( X11 )
endif()
IF( UNIX AND NOT APPLE AND QT_QTDBUS_FOUND )
SET( WITH_UPOWER ON )
ENDIF( UNIX AND NOT APPLE AND QT_QTDBUS_FOUND )
macro_optional_find_package(Phonon 4.5.0)
macro_log_feature(PHONON_FOUND "Phonon" "The Phonon multimedia library" "http://phonon.kde.org" TRUE "" "")
if(PHONON_FOUND)

@ -5,6 +5,11 @@ FOREACH( _file ${_icons} )
INSTALL( FILES ${_file} RENAME tomahawk.png DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor/${_res}/apps )
ENDFOREACH( _file )
IF( WITH_UPOWER )
QT4_ADD_DBUS_INTERFACE(tomahawkSources "${CMAKE_CURRENT_SOURCE_DIR}/linux/org.freedesktop.UPower.xml" linux/UPowerProxy)
ENDIF( WITH_UPOWER )
ADD_SUBDIRECTORY( "${CMAKE_CURRENT_SOURCE_DIR}/linux" )
INSTALL( FILES ${CMAKE_SOURCE_DIR}/data/icons/tomahawk-icon.svg RENAME tomahawk.svg DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor/scalable/apps )
INSTALL( FILES ${CMAKE_SOURCE_DIR}/admin/unix/tomahawk.desktop DESTINATION ${CMAKE_INSTALL_DATADIR}/applications )

@ -18,6 +18,7 @@
#cmakedefine WITH_CRASHREPORTER
#cmakedefine WITH_BINARY_ATTICA
#cmakedefine WITH_QtSparkle
#cmakedefine WITH_UPOWER
#cmakedefine LIBLASTFM_FOUND

@ -79,6 +79,10 @@
#include "config.h"
#ifdef WITH_UPOWER
#include "linux/UPowerHandler.h"
#endif
#ifndef ENABLE_HEADLESS
#include <QMessageBox>
#endif
@ -148,6 +152,7 @@ TomahawkApp::TomahawkApp( int& argc, char *argv[] )
setOrganizationDomain( QLatin1String( TOMAHAWK_ORGANIZATION_DOMAIN ) );
setApplicationName( QLatin1String( TOMAHAWK_APPLICATION_NAME ) );
setApplicationVersion( QLatin1String( TOMAHAWK_VERSION ) );
connect( this, SIGNAL( tomahawkLoaded() ), SLOT( initEnergyEventHandler() ) );
registerMetaTypes();
TomahawkUtils::installTranslator( this );
@ -633,6 +638,15 @@ TomahawkApp::initFactoriesForAccountManager()
Tomahawk::Accounts::AccountManager::instance()->loadFromConfig();
}
void
TomahawkApp::initEnergyEventHandler()
{
#ifdef WITH_UPOWER
UPowerHandler* upower = new UPowerHandler( this );
upower->registerHandler();
#endif // WITH_UPOWER
}
// This method will be called twice during Tomahawk startup.
// We don't know which is going to be ready first, AccountManager or Servent, but this goes through

@ -112,6 +112,7 @@ private slots:
void initSIP();
void initHTTP();
void initFactoriesForAccountManager();
void initEnergyEventHandler();
void spotifyApiCheckFinished();

@ -0,0 +1,3 @@
IF( WITH_UPOWER )
SET( tomahawkSources ${tomahawkSources} "${CMAKE_CURRENT_SOURCE_DIR}/UPowerHandler.cpp" PARENT_SCOPE )
ENDIF( WITH_UPOWER )

@ -0,0 +1,79 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
* Copyright 2013, Uwe L. Korn <uwelk@xhochy.com>
*
* Tomahawk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Tomahawk is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
*/
#include "accounts/AccountManager.h"
#include "UPowerHandler.h"
#include "utils/Logger.h"
#include <QTimer>
#define UPOWER_RESUME_DELAY 2000
using namespace Tomahawk;
const char* UPowerHandler::UPowerService = "org.freedesktop.UPower";
const char* UPowerHandler::UPowerPath = "/org/freedesktop/UPower";
const char* UPowerHandler::UPowerInterface = "org.freedesktop.UPower";
Tomahawk::UPowerHandler::UPowerHandler( QObject *parent )
: QObject( parent )
{
}
bool
UPowerHandler::registerHandler()
{
// Check if the UPower is available
if ( !QDBusConnection::systemBus().interface()->isServiceRegistered( UPowerService ) ) {
tLog( LOGVERBOSE ) << Q_FUNC_INFO << "UPower is not available";
return false;
}
tLog( LOGVERBOSE ) << Q_FUNC_INFO << "UPower available, will reconnect on wake from suspend.";
if ( m_interface.isNull() )
{
m_interface = QSharedPointer<org::freedesktop::UPower>( new org::freedesktop::UPower( UPowerService, UPowerPath, QDBusConnection::systemBus(), this ) );
}
connect( m_interface.data(), SIGNAL( Sleeping() ), this, SLOT( handleSleep() ));
connect( m_interface.data(), SIGNAL( Resuming() ), this, SLOT( handleResume() ));
return true;
}
void
UPowerHandler::handleSleep()
{
QMutexLocker locker( &m_mutex );
tLog( LOGVERBOSE ) << Q_FUNC_INFO << "About to sleep so disconnecting all accounts";
Tomahawk::Accounts::AccountManager::instance()->disconnectAll();
}
void
UPowerHandler::handleResume()
{
m_mutex.lock();
// Delay resuming for other wakeup actions, e.g. reconnecting to the network, to take place.
QTimer::singleShot( UPOWER_RESUME_DELAY, this, SLOT( actualResume() ) );
}
void
UPowerHandler::actualResume()
{
tLog( LOGVERBOSE ) << Q_FUNC_INFO << "Awake from sleep so connecting all accounts";
Tomahawk::Accounts::AccountManager::instance()->connectAll();
m_mutex.unlock();
}

@ -0,0 +1,52 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
* Copyright 2013, Uwe L. Korn <uwelk@xhochy.com>
*
* Tomahawk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Tomahawk is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef UPOWERHANDLER_H
#define UPOWERHANDLER_H
#include "linux/UPowerProxy.h"
#include <QObject>
#include <QMutex>
#include <QSharedPointer>
namespace Tomahawk {
class UPowerHandler : public QObject
{
Q_OBJECT
public:
explicit UPowerHandler( QObject *parent = 0 );
bool registerHandler();
static const char* UPowerService;
static const char* UPowerPath;
static const char* UPowerInterface;
private:
QSharedPointer<org::freedesktop::UPower> m_interface;
QMutex m_mutex;
private slots:
void handleSleep();
void handleResume();
void actualResume();
};
}
#endif // UPOWERHANDLER_H

@ -0,0 +1,395 @@
<!DOCTYPE node PUBLIC
"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node name="/" xmlns:doc="http://www.freedesktop.org/dbus/1.0/doc.dtd">
<interface name="org.freedesktop.UPower">
<doc:doc>
<doc:description>
<doc:para>
The UPower service is available via the system message
bus. To access the service, use
the <doc:tt>org.freedesktop.UPower</doc:tt> interface on
the <doc:tt>/org/freedesktop/UPower</doc:tt> object on
the D-Bus system bus service with the well-known
name <doc:tt>org.freedesktop.UPower</doc:tt>.
</doc:para>
<doc:para>
<doc:example language="shell" title="simple example">
<doc:code>
$ dbus-send --print-reply \
--system \
--dest=org.freedesktop.UPower \
/org/freedesktop/UPower \
org.freedesktop.UPower.EnumerateDevices
method return sender=:1.386 -> dest=:1.451 reply_serial=2
array [
object path "/org/freedesktop/UPower/devices/line_power_AC"
object path "/org/freedesktop/UPower/devices/battery_BAT0"
]
</doc:code>
</doc:example>
</doc:para>
</doc:description>
</doc:doc>
<!-- ************************************************************ -->
<method name="EnumerateDevices">
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
<arg name="devices" direction="out" type="ao">
<doc:doc><doc:summary>An array of object paths for devices.</doc:summary></doc:doc>
</arg>
<doc:doc>
<doc:description>
<doc:para>
Enumerate all power objects on the system.
</doc:para>
</doc:description>
</doc:doc>
</method>
<!-- ************************************************************ -->
<signal name="DeviceAdded">
<arg name="device" type="o">
<doc:doc><doc:summary>Object path of device that was added.</doc:summary></doc:doc>
</arg>
<doc:doc>
<doc:description>
<doc:para>
Emitted when a device is added.
</doc:para>
</doc:description>
</doc:doc>
</signal>
<!-- ************************************************************ -->
<signal name="DeviceRemoved">
<arg name="device" type="o">
<doc:doc><doc:summary>Object path of device that was removed.</doc:summary></doc:doc>
</arg>
<doc:doc>
<doc:description>
<doc:para>
Emitted when a device is removed.
</doc:para>
</doc:description>
</doc:doc>
</signal>
<!-- ************************************************************ -->
<signal name="DeviceChanged">
<arg name="device" type="o">
<doc:doc><doc:summary>Object path of device that was changed.</doc:summary></doc:doc>
</arg>
<doc:doc>
<doc:description>
<doc:para>
Emitted when a device changed.
</doc:para>
</doc:description>
</doc:doc>
</signal>
<!-- ************************************************************ -->
<signal name="Changed">
<doc:doc>
<doc:description>
<doc:para>
Emitted when one or more properties on the object changes.
</doc:para>
</doc:description>
</doc:doc>
</signal>
<!-- ************************************************************ -->
<signal name="Sleeping">
<doc:doc>
<doc:description>
<doc:para>
This signal is sent when the session is about to be suspended or
hibernated.
</doc:para>
<doc:para>
This signal is DEPRECATED. Use NotifySleep() instead.
</doc:para>
</doc:description>
</doc:doc>
</signal>
<!-- ************************************************************ -->
<signal name="NotifySleep">
<doc:doc>
<doc:description>
<doc:para>
This signal is sent when the session is about to be suspended or
hibernated.
Session and system programs have one second to do anything required
before the sleep action is taken (such as sending out Avahi or
Jabber messages).
</doc:para>
</doc:description>
</doc:doc>
<arg name="action" direction="out" type="s">
<doc:doc>
<doc:summary>
The sleep action type, e.g. <doc:tt>suspend</doc:tt>,
<doc:tt>hibernate</doc:tt> or <doc:tt>hybrid</doc:tt>.
</doc:summary>
</doc:doc>
</arg>
</signal>
<!-- ************************************************************ -->
<signal name="Resuming">
<doc:doc>
<doc:description>
<doc:para>
This signal is sent when the session has just returned from
Suspend() or Hibernate().
</doc:para>
<doc:para>
This signal is DEPRECATED. Use NotifyResume() instead.
</doc:para>
</doc:description>
</doc:doc>
</signal>
<!-- ************************************************************ -->
<signal name="NotifyResume">
<doc:doc>
<doc:description>
<doc:para>
This signal is sent when the session has just returned from
Suspend() or Hibernate().
Session and system programs can then do anything required (such as
sending out Avahi or Jabber messages).
</doc:para>
</doc:description>
</doc:doc>
<arg name="action" direction="out" type="s">
<doc:doc>
<doc:summary>
The sleep action type, e.g. <doc:tt>suspend</doc:tt>,
<doc:tt>hibernate</doc:tt> or <doc:tt>hybrid</doc:tt>.
</doc:summary>
</doc:doc>
</arg>
</signal>
<!-- ************************************************************ -->
<method name="AboutToSleep">
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
<doc:doc>
<doc:description>
<doc:para>
This method tells UPower that the Suspend() or Hibernate() method
is about to be called.
This allows UPower to emit the Suspending signal whilst
session activities are happening that have to be done before the
suspend process is started.
</doc:para>
<doc:para>
This method would typically be called by the session power
management daemon, before it locks the screen and waits for the
screen to fade to black.
The session power management component would then call Suspend() or
Hibernate() when these syncronous tasks have completed.
</doc:para>
<doc:para>
If this method is not called than nothing bad will happen and
Suspend() or Hibernate() will block for the required second.
</doc:para>
</doc:description>
</doc:doc>
<arg name="action" direction="in" type="s">
<doc:doc>
<doc:summary>
The sleep action type, e.g. <doc:tt>suspend</doc:tt> or
<doc:tt>hibernate</doc:tt>.
</doc:summary>
</doc:doc>
</arg>
</method>
<!-- ************************************************************ -->
<method name="Suspend">
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
<doc:doc>
<doc:description>
<doc:para>
Suspends the computer into a low power state.
System state is not preserved if the power is lost.
</doc:para>
<doc:para>
If AboutToSleep() has not been called then UPower will send
the Sleeping() signal and block for one second.
</doc:para>
<doc:para>
If AboutToSleep() has been called less than one second
before this method is called then UPower will block for the
remaining time to complete one second of delay.
</doc:para>
</doc:description>
</doc:doc>
</method>
<!-- ************************************************************ -->
<method name="SuspendAllowed">
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
<arg name="allowed" direction="out" type="b">
<doc:doc><doc:summary>TRUE if allowed, otherwise FALSE</doc:summary></doc:doc>
</arg>
<doc:doc>
<doc:description>
<doc:para>
Check if the caller has (or can get) the PolicyKit privilege to call
<doc:ref type="method" to="Power.Suspend">Suspend</doc:ref>.
</doc:para>
</doc:description>
</doc:doc>
</method>
<!-- ************************************************************ -->
<method name="Hibernate">
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
<doc:doc>
<doc:description>
<doc:para>
Hibernates the computer into a low power state.
System state is preserved if the power is lost.
</doc:para>
<doc:para>
If AboutToSleep() has not been called then UPower will send
the Sleeping() signal and block for one second.
</doc:para>
<doc:para>
If AboutToSleep() has been called less than one second
before this method is called then UPower will block for the
remaining time to complete one second of delay.
</doc:para>
</doc:description>
</doc:doc>
</method>
<!-- ************************************************************ -->
<method name="HibernateAllowed">
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
<arg name="allowed" direction="out" type="b">
<doc:doc><doc:summary>TRUE if allowed, otherwise FALSE</doc:summary></doc:doc>
</arg>
<doc:doc>
<doc:description>
<doc:para>
Check if the caller has (or can get) the PolicyKit privilege to call
<doc:ref type="method" to="Power.Hibernate">Hibernate</doc:ref>.
</doc:para>
</doc:description>
</doc:doc>
</method>
<!-- ************************************************************ -->
<property name="DaemonVersion" type="s" access="read">
<doc:doc><doc:description><doc:para>
Version of the running daemon, e.g. <doc:tt>002</doc:tt>.
</doc:para></doc:description></doc:doc>
</property>
<property name="CanSuspend" type="b" access="read">
<doc:doc><doc:description><doc:para>
Whether the system is able to suspend.
</doc:para></doc:description></doc:doc>
</property>
<property name="CanHibernate" type="b" access="read">
<doc:doc><doc:description><doc:para>
Whether the system is able to hibernate.
</doc:para></doc:description></doc:doc>
</property>
<property name="OnBattery" type="b" access="read">
<doc:doc><doc:description><doc:para>
Indicates whether the system is running on battery power.
This property is provided for convenience.
</doc:para></doc:description></doc:doc>
</property>
<property name="OnLowBattery" type="b" access="read">
<doc:doc><doc:description><doc:para>
Indicates whether the system is running on battery power and if the battery is critically low.
This property is provided for convenience.
</doc:para></doc:description></doc:doc>
</property>
<property name="LidIsClosed" type="b" access="read">
<doc:doc>
<doc:description>
<doc:para>
Indicates if the laptop lid is closed where the display cannot be seen.
</doc:para>
</doc:description>
</doc:doc>
</property>
<property name="LidIsPresent" type="b" access="read">
<doc:doc>
<doc:description>
<doc:para>
If the system has a lid device.
</doc:para>
</doc:description>
</doc:doc>
</property>
<property name="LidForceSleep" type="b" access="read">
<doc:doc>
<doc:description>
<doc:para>
If the system really has to sleep when the lid is closed.
Some laptops actually melt (!) if the lid is closed and the
computer keeps running. We blacklist those, and do something
sane for the other machines.
</doc:para>
<doc:para>
This allows us to set the default session policy to not
suspend on lid close if the laptop is docked, and be sure
the machine is not going to melt.
</doc:para>
</doc:description>
</doc:doc>
</property>
<property name="IsDocked" type="b" access="read">
<doc:doc>
<doc:description>
<doc:para>
If the system is currently docked.
Note: the "is-docked" value is the result of a heuristic,
which may involve testing the display output.
</doc:para>
</doc:description>
</doc:doc>
</property>
</interface>
</node>