[img]

Why is this important

Power management in Linux sucks. Depending if you are running a PPC or i386 PC the different power management facilities are vastly different. To get your machine to suspend on lid press is already possible, but is difficult to know what config files to modify. To get your LCD screen brightness set to 50% when you remove the AC Adapter of your laptop is probably possible with a clever little Perl script, but is not something that comes ready configured on a standard Linux distro. Any of these things need the user to become the super-user to do the action. This needs to change before Linux is accepted as a contender for the corporate desktop.

GNOME Power Manager gets all information from HAL using information from org.freedesktop.Hal. GNOME Power Manager does not do independent probing for data, it relies on HAL, in this way it can stay very lightweight and uncomplicated. Its goal is to be architecture neutral and free of polling and other hacks.

[img]

The role GNOME Power Manager, HAL, and the Kernel play in Power Management.

So far, we have supported:

  1. Laptop batteries
  2. AC Adapters
  3. APC UPS's
  4. SynCE PDA's
  5. Logitech Wireless Mice
  6. Logitech Wireless Keyboards

How does HAL help?

HAL is the de-facto Hardware Abstraction Layer for the Linux desktop. David Zeuthen (and myself and lots of others) have written different addons for hald (the HAL daemon) that populate different devices with additional properties, e.g. battery.charge.current_level that can be queried in an architecture-neutral way.

With all the new HAL code, and the GNOME Power Manager services, we can disable loading of pmud/acpid/apmd and keep everything managed in one place.

[img]

New ACPI objects in the HAL device tree.

[img]

Pressing the power/sleep/lid buttons now generate events

GNOME Power Manager owns the session D-BUS service net.sf.GnomePower and runs a session daemon (i.e. once per logged in user) and optionally displays battery status and low battery notifications.

The session daemon is very resource friendly. Other than the initial coldplug, it uses internal caching for all the power devices, so no additional lookups are needed for each update event. It will only update the displayed icon on a powerState change, but will update the tooltip on every percentage change. It should use *very little* CPU and memory. GNOME Power Manager is written in C, and has additional dependencies of:

  1. hal (0.5.3 better)
  2. dbus-glib (0.35.2)
  3. libnotify (0.2.1) [optional, but highly recommended]
  4. notification-daemon (0.2.1) [optional, but highly recommended]

Notification Icon

The notification icon can display a device in the tray. The icons can be themed with custom icons for each theme, or fallback to a standard default.

[img] [img]

Existing output of the notification area icon, and the planned new tooltip design.

[img]

Example right-click menu that gives the options and actions

Each action in the right-click menu can be disabled in DBUS, to limit users to performing 'safe' commands from the desktop. e.g. If hibernate is known to crash on a specific Toshiba laptop, it can be disabled in gconf, but still allowing the user to suspend, shutdown etc.

[img]

Lockdown possible via gconf

It is expected that HAL will provide the data that allows GPM to decide what options are available.

Methods

The methods provided by GPM are provided for client programs to use.

bool isUserIdle ()

Returns true is the user has been idle for the timeout set in gconf.

status: stub

bool isRunningOnMains ()

Returns true if we are running on mains (usefull for scripts)

status: stub

bool isActive ()

Returns true if we are running. Testing function.

status: complete

Server Signals

The signals are emitted when state is changed or an action is about to happen.

mainsStatusChanged (bool isRunningOnMains)

emitted when the mains power connection changes

status: complete

userIdleStatusChanged (bool isIdle)

emitted when the use is idle / no longer idle

status: none

actionAboutToHappen (enum action)

registered vetoers MUST respond to this signal using Ack, vetoNAK, vetoWait with ten seconds otherwise they are kicked out as vetoers (to work around broken apps)

status: complete

performingAction (enum action)

Just a signal, no response is required, nor allowed.

status: complete

Action is defined as:

SCREENSAVE =  1, 
POWEROFF   =  2, 
SUSPEND    =  4, 
HIBERNATE  =  8, 
LOGOFF     =  16, 
ALL        =  255

Client Methods

Client signals are sent from an application to GPM. If an application registers its interest in a action, it is given the chance to ack, or nack the situation.

The situation: User presses shutdown, but Abiword has an unsaved document open. Abiword is informed of the impending shutdown, but issues a nack, followed by a screen that asks the user if he would like to save the document. It can then resume the shutdown using the signal ack.

Similarly, if Evolution is indexing a database (that would be corrupted if interrupted) and needs at least 3 seconds to flush buffers, it can pause the shutdown using wait. The signals currently available are:

bool ActionRegister (enum action, gchar localizedAppname)

Used for signing up for vetoing a specific action

status: complete

bool ActionUnregister (enum action)

Used to unregister the applications interest in a specific action. Note: GPM will automatically unregister clients that disconnect from the bus

status: semi-complete, assumes ALL

bool Ack (enum action)

Vetoer allows a specific action to take place
status: complete

bool Nack (enum action, gchar localizedReason)

Vetoer doesn't allow a specific action to take place; g-p-m SHOULD display a notification to the user that the action cannot take place and what the vetoing application is.

status: complete

bool Wait (enum action, int timeout, gchar localizedReason)

Vetoer asks for a timeout of timeout ms before g-p-m should try to perform the action again. It is legal for the vetoer to call Ack before the timeout. If the (accumulated) delay amounts to more than one second, g-p-m SHOULD display a notification about who is blocking the action.

status: not present yet

This part of GNOME Power Manager has a test suite, gnome-power-dbus-test that can be used to test the out-of-order and error conditions. It also shows any limitations or bugs in GNOME Power Manager. For example, running gnome-power-dbus-test --doNACK and selecting shutdown from the drop down menu would give the following dialog from GPM:

[img]

The error message from the GNOME Power Manager 0.1.0

[img] [img]

The libnotify error messages using CVS.

GConf keys

The session keys are located at /apps/gnome-power/general. These are used for GNOME Power Manager and GNOME Power Preferences as IPC to update in real time what hardware is present, and to store the user preferences for what icons are shown. In this way, GNOME Power Preferences does not have lots of duplicated code and can use the state generated in g-p-m.

Hardware keys are located at /apps/power-manager/general

PowerManager

GnomePower uses PowerManager to launch scripts. PowerManager is a temporary bodge! When HAL 0.5.4 is released with actions support, PowerManager will become obsolete.

PowerManager is a simple DBUS daemon that runs as the root user and holds the system connection name net.sf.PowerManager. Only root is allowed to run this program, (this can be changed in /etc/dbus-1/system.d/PowerManager.conf) as it's entire purpose is to allow non-root users to run the scripts /usr/sbin/pm-*. This is also configurable in the above PowerManager.conf config file. By default, all users are allowed to connect to the system DBUS net.sf.PowerManager connection.

[img]

At the moment, GNOME Power Manager requires the PowerManager system service to be running.

You can issue the following methods:

bool isActive ()
bool shutdown ()
bool restart ()
bool hibernate ()
bool suspend ()
bool hdparm (timeout, device)

You can lock out specific users, or groups of users by adding to /etc/dbus-1/system.d/PowerManager.conf:

        <policy user="suzy">
                <deny send_destination="net.sf.PowerManager"/>
                <deny send_interface="net.sf.PowerManager"/>
        </policy>

pmscripts

pmscripts is the package that installs the scripts:

/usr/sbin/pm-shutdown
/usr/sbin/pm-hibernate
/usr/sbin/pm-restart
/usr/sbin/pm-suspend

These scripts can be changed by distributions, to better fit in with the existing power-management infrastructure. e.g. Gentoo can have the fast-shutdown feature enabled, but Fedora may want to use the more conventional /sbin/shutdown -h now. In a similar way, the hibernate script could read a config file and use different methods for hibernation, e.g. suspend2, or software suspend, or some other method.

It is expected that certain values are passed down to the pmscripts from HAL, for example PMSYSTEM="ACPI" so that specific things can be tested for. At the moment we do not pass variables, but it's fairly trivial to find out these things here anyway.

These scripts are intended to be used by the root user only, or a daemon running as root. They could be a symlink if required, this is left to the packager.

GNOME Power Preferences

Power preferences is a simple program that lets the authorized user change the actions associated with each action. Devices that are not present are not shown, e.g. the UPS options are not visible to the user, unless one is plugged in, similarly, battery options are hidden for desktop users.

[img]

Main preferences sliders

[img]

Preferences options

[img]

Advanced preferences

Uses of GNOME Power Manager infrastructure

Getting The Code

The latest 'stable' code (with tarballs and RPM's for Fedora Core 4) can be found at sourceforge.

Ubuntu Breezy packages are to be found here. Thanks to Oliver Grawert for the package.

CVS

You can check out the latest GNOME Power Manager code using CVS:

export CVSROOT=":pserver:anonymous@anoncvs.gnome.org:/cvs/gnome"
cvs -z3 checkout gnome-power-manager

You can check out the latest PowerManager and pmscripts code using CVS:

cvs -d:pserver:anonymous@cvs.sf.net:/cvsroot/gnome-power checkout power-manager
cvs -d:pserver:anonymous@cvs.sf.net:/cvsroot/gnome-power checkout pmscripts

For Fedora users of anything-other-than-i386:

To rebuild the .src.rpm to your architecture use:

rpm --rebuild *.src.rpm

jhbuild

If you want to use GNOME CVS, jhbuild can now build GNOME Power Manager using:

jhbuild build gnome-power

Why doesn't it autostart?

For the moment, you will have to run GNOME Power Manager from a terminal (it will not autostart.) but will hopefully be either patched into the default upstream startup, or will use gnome-services when it arrives in mainline.

[img]

You can launch gnome-power-manager automatically using the gnome-session-properties program

Can you help?

Please contact me for any issues, or bugs you find with the GNOME Power Manager.

There is also a gnome-power-devel mailing list.

Submitting fixes / enhancements

Be sure to add an entry into the ChangeLog file telling me what the patch does and what files are changed. Also, break any patch files up into logical chunks that are easier to check and apply one-by-one.

Thanks

I've been getting lots of good feedback (and code!) from different people, with lots of new ideas and points for improvements. So even if you are not a programmer, you can still help. This project is moving really fast because of all the help and comments I've received, notable mention goes to (in no particular order):

With large lumps of code from:

Who am I

My name is Richard Hughes, and I'm a 22 year old student from Guildford, studying MEng Electrical and Computer Engineering at Surrey University.

SourceForge.net Logo
Validate XHTML Validate CSS