Using the alarm interface
Introduction
This document has been reviewed for maemo 3.x release.
The maemo alarm framework provides an easy way to manage timed events in your device. It is powerful and not restricted only to "wake up" alarms. The framework provides many other features, including:
- Set multiple alarm events
- Configure the number of recurrences and the time between each one
- Choose whether the alarm dialog should be shown or not
- Set the title and the message to be shown in the alarm dialog
- Select a custom icon file to be shown in the alarm dialog
- Select a custom sound file to be played while the alarm dialog is shown
- Choose to boot the device if it is turned off
- Choose to run the alarm only if the device is connected
- Choose to run the alarm in the system startup if it is missed
- Choose to postpone the alarm if it is missed
- Execute a given file (e.g., a program or a script)
- Send a message to a D-Bus message bus
- Query for existing alarm events in a given period of time
- Delete an existing alarm event
- Configure the snooze time for the event
- Configure the default snooze time for all alarm events
This document shows how to use the alarm interface describing all its functions and giving examples of use cases.
Overview
Timed event functionality is provided by the alarmd
daemon. It makes possibe for applications to get D-Bus messages or
exec calls at certain times.
Applications register an event happening at certain time. The
alarmd
daemon will then call the application when the
event is due, so the application need not be running during this
waiting period. This is useful for applications that need to update
their status on regular intervals.
A single event may be set to repeat itself over and over again,
at given interval. The alarmd
daemon will remember
these events over system shutdowns too.
The alarmd
daemon can also be asked to start the
system up for an event even from poweroff. These events may also
prefer to be run in hidden poweron mode, where the display stays
off, but the device is on. The alarmd
daemon also
supports usage of osso-systemui-alarm
to show an alarm
dialog for the event, which can be followed by a power up device
confirmation dialog, if the device is in the hidden powerup
mode.
Communication with the alarmd
daemon is done
through D-Bus. It listens on both system and session buses. The
easiest way is to use the C client API library, which offers
straightforward API to modify the queue.
The alarm queue used by the alarmd
daemon is stored
in /var/lib/alarmd/alarm_queue.xml
file.
Alarm events
Alarm events and the functions to manage them are defined
in alarm_event.h
header file located
in /usr/include/alarmd
. It is part
of libalarm-dev
debian package.
Each alarm event is identified by an unique key also known
as "cookie". These identifiers are are obtained when a new
event is added to the queue. They are used whenever you want
to or retrieve information about an specific event or delete
it. An alarm event is identified by
the alarm_event_t
structure, described as
follows:
#include <alarmd/alarm_event.h> /** * cookie_t: * * Unique identifier type for the alarm events. **/ typedef long cookie_t; /** * alarm_event_t: * * Describes an alarm event. **/ typedef struct { time_t alarm_time; uint32_t recurrence; int32_t recurrence_count; uint32_t snooze; char *title; char *message; char *sound; char *icon; char *dbus_interface; char *dbus_service; char *dbus_path; char *dbus_name; char *exec_name; int32_t flags; uint32_t snoozed; } alarm_event_t;
Table 1. Description of structure alarm_event_t
fields
Name | Type | Description |
---|---|---|
alarm_time | time_t |
The number of seconds elapsed since 00:00:00 on January 1, 1970 when the event should be launched. |
recurrence | uint32_t |
Interval in minutes, over which the event should be repeated. 0 if the event should only happend once. |
recurrence_count | int32_t |
Number of times the event should repeat. -1 for infinite. |
snooze | uint32_t |
Number of minutes the event is postponed, when Snooze button is pressed in alarm dialog. 0 for default setting. |
title | char * |
Title shown in the alarm dialog. May contain gettext identifiers, as described in Localised Strings section. |
message | char * |
Message shown in the alarm dialog. May contain gettext identifiers, as described in Localised Strings section. |
sound | char * |
Path to sound file that should be played when the alarm dialog is shown. |
icon | char * |
Path to icon file or GtkIconTheme icon name to show in the alarm dialog. |
dbus_interface | char * |
Interface for D-Bus action taken when event is due. |
dbus_service | char * |
Service to be called on D-Bus action. If other than NULL, the D-Bus action will be a method call. |
dbus_path | char * |
Path for D-Bus action. If defined, the action on event will be a D-Bus action. |
dbus_name | char * |
Name for D-Bus action. Either the D-Bus method name or signal name. |
exec_name | char * |
Command to run as events action. Only used, if the dbus_path field is not set. The format is as accpted by glib's g_shell_parse_argv . |
flags | int32_t |
Options for the event, the value should be members of enumeration alarmeventflags bitwise or'd together. |
snoozed | uint32_t |
How many times the event has been snoozed, only applies to getting an event, when setting one, this has no effect. |
The flags
field in the alarm_event_t
structure above, holds the options of an alarm event. This field is a bitwise of one or more items described in alarmeventflags
enumeration:
#include <alarmd/alarm_event.h> typedef enum { ALARM_EVENT_NO_DIALOG = 1 << 0, ALARM_EVENT_NO_SNOOZE = 1 << 1, ALARM_EVENT_SYSTEM = 1 << 2, ALARM_EVENT_BOOT = 1 << 3, ALARM_EVENT_ACTDEAD = 1 << 4, ALARM_EVENT_SHOW_ICON = 1 << 5, ALARM_EVENT_RUN_DELAYED = 1 << 6, ALARM_EVENT_CONNECTED = 1 << 7, ALARM_EVENT_ACTIVATION = 1 << 8, ALARM_EVENT_POSTPONE_DELAYED = 1 << 9, ALARM_EVENT_BACK_RESCHEDULE = 1 << 10, } alarmeventflags;
Table 2. Description of alarmeventflags
values
Value | Description |
---|---|
ALARM_EVENT_NO_DIALOG | When the alarm is launched, it shall not show a dialog, but instead do the action immediately. |
ALARM_EVENT_NO_SNOOZE | When the alarm dialog is shown, the Snooze button will be disabled. |
ALARM_EVENT_SYSTEM | The D-Bus call should be done over system bus instead of session bus. |
ALARM_EVENT_BOOT | The event should start the device, if shut down. |
ALARM_EVENT_ACTDEAD | If the device is shut down, it will be started with display off and shut down after the action is done. |
ALARM_EVENT_SHOW_ICON | While the event is on queue, a icon should be shown in the status bar. |
ALARM_EVENT_RUN_DELAYED | Should the event be run, even if missed or jumped over. |
ALARM_EVENT_CONNECTED | The event should only be run when there is an active connection. If no connection is available, the event will be launched when a connection is available. |
ALARM_EVENT_ACTIVATION | Should the D-Bus action of the event use D-Bus activation, i.e. should the service be started, if not already running. |
ALARM_EVENT_POSTPONE_DELAYED | If the event is missed by more than a day, it will be moved forward to the next day. If less than a day, it will be launched. |
ALARM_EVENT_BACK_RESCHEDULE | If time is changed backwards, the event is moved backwards too. Only applies to recurring alarms. |
Managing alarm events
Adding an alarm event to the queue
To add a new alarm event to the queue, you need a new
instance of alarm_error_t
structure and fill in
the necessary fields. The only mandatory is
alarm_time
. Check time(2)
and
ctime(3)
manpages for more instructions on how
manipulate a time_t
type.
With the fields of the structure set, all you need is a
call to the alarm_event_add
function passing a
pointer to the structure as parameter.
#include <alarmd/alarm_event.h> /** * alarm_event_add: * * Adds an event to the alarm queue. **/ cookie_t alarm_event_add(alarm_event_t *event);
On success, this function returns the cookie for the alarm event, otherwise it returns 0. As example, the following program sets an alarm event to 10 minutes from now:
#include <stdio.h> #include <string.h> #include <time.h> #include <alarmd/alarm_event.h> int main (int argc, char *argv[]) { time_t time_now; struct tm *st_time; alarm_event_t event; cookie_t cookie; /* Zero the event */ memset (&event, 0, sizeof (alarm_event_t)); /* Get current time */ time (&time_now); st_time = localtime (&time_now); /* Add 10 minutes to tm_min field */ st_time->tm_min += 10; /* Set the time in alarm_event_t structure */ event.alarm_time = mktime (st_time); cookie = alarm_event_add (&event); if (cookie == 0) { /* Error */ printf ("Error setting alarm event. Error code: '%d'\n", alarmd_get_error ()); return 1; } printf ("Alarm event successfully set to %s. Event cookie: %ld\n", ctime (&event.alarm_time), cookie); return 0; }
Fetching details of an alarm event
Having set an alarm event, it is not possible to edit its
details anymore, but it is possible to fetch the alarm detais
using the alarm_event_get
function, passing the
event cookie as parameter.
#include <alarmd/alarm_event.h> /** * alarm_event_get: * * Finds an alarm with given identifier and returns alarm_event struct describing it. **/ alarm_event_t *alarm_event_get(cookie_t event_cookie);
This function returns a newly allocated
alarm_event_t
structure. After manipulating the
structure fields, it is possible to set another alarm event
with the same details. It is necessary to free the allocated
structure obtained with the alarm_event_get
function. For this task it is neccessary a call to the
alarm_event_free
function, which receives the
alarm event structure as parameter:
#include <alarmd/alarm_event.h> /** * alarm_event_free: * * Frees given alarm_event struct. **/ void alarm_event_free(alarm_event_t *event);
Deleting an alarm event
Finally, to delete an alarm event, you need a call to the
alarm_event_del
function, passing the event
cookie as a parameter.
#include <alarmd/alarm_event.h> /** * alarm_event_del: * * Deletes alarm from the alarm queue. **/ int alarm_event_del(cookie_t event_cookie);
On success, this function returns the 1, otherwise it returns 0.
Checking for errors
Whenever an error occurs during a call to any of the functions,
a error code is set, which can be obtained with the
alarmd_get_error
function. It has the following
signature:
#include <alarmd/alarm_event.h> /** * alarmd_get_error: * * Gets the error code for previous action. **/ alarm_error_t alarmd_get_error(void);
The possible values returned by this function are defined by
alarm_error_t
enumeration, described below:
#include <alarmd/alarm_event.h> typedef enum { ALARMD_SUCCESS, ALARMD_ERROR_DBUS, ALARMD_ERROR_CONNECTION, ALARMD_ERROR_INTERNAL, ALARMD_ERROR_MEMORY, ALARMD_ERROR_ARGUMENT } alarm_error_t;
Table 3. Description of alarm_error_t
values
Value | Description |
---|---|
ALARMD_SUCCESS | No error ocurred. |
ALARMD_ERROR_DBUS | An error with D-Bus occurred, probably coudn't get a D-Bus connection. |
ALARMD_ERROR_CONNECTION | Could not contact alarmd via D-Bus. |
ALARMD_ERROR_INTERNAL | Some alarmd or libalarm internal error, possibly a version mismatch. |
ALARMD_ERROR_MEMORY | A memory allocation failed. |
ALARMD_ERROR_ARGUMENT | An argument given by caller was invalid. |
Localized Strings
If you need the message in alarm dialog to be in whatever
language is used in the device, you can use specially formatted
strings. The translations are fetched with
dgettext
. To get your message translated, you need to
specify the package from which to fetch the translation and the
message id. The format is as follows:
{message domain,message id}
If the translation contains "%s"
, the the
replacements for these can be given too:
{message domain,message id,replacement1,replacement2...}
The replacement may be in form {...}
, but cannot
contain anything else, in the main string the translated part can
be embedded. Postitional parameters or any other format options
than %s
are not supported.
Escaping Strings
If your message comes from user, you probably want to use
alarm_escape_string
function to escape all such
formatting from the string. alarm_escape_string
escapes the string to be used as title or message of the alarm
dialog, so that it isn't considered as a localisation
string. All occurrences of '{', '}' characters will be escaped
with a backslash and all backslashes will be duplicated. The
function receives a string as parameter and returns a newly
allocated string, which should be freed with
free
. This function has the following syntax:
#include <alarmd/alarm_event.h> /** * alarm_escape_string: * * Escapes a string to be used as alarm dialog message or title. **/ char *alarm_escape_string(const char *string);
Unescaping Strings
To unescape a string escaped with
alarm_escape_string
or any other escaped string
that uses backslashes to escape characters, you must call the
alarm_unescape_string
function. It receives a
string as parameter and returns a newly alocated string that
should be freed with free
. The syntax is as
follows:
#include <alarmd/alarm_event.h> /** * alarm_unescape_string: * * Unescapes a string escaped with alarm_escape_string. **/ char *alarm_unescape_string(const char *string);
Alternatively, you can use the the
alarm_unescape_string_noalloc
to unescape a
string. The difference between the functions is that
alarm_unescape_string
allocates memory for the
returned string, whereas
alarm_unescape_string_noalloc
modifies the passed
string. This can be done, as the unescaped string is at most
as long as the original string.
#include <alarmd/alarm_event.h> /** * alarm_unescape_string_noalloc: * * Unescapes a string escaped with alarm_escape_string. **/ char *alarm_unescape_string_noalloc(char *string);
The unescape functions have checking for strings ending with double backslashes, and the single backslash is put into the resulting string. If NULL is passed, NULL is returned by all functions.
References
Further information about D-BUS, GConf and GTK+ can be found at their websites:
Example Code
A full example code for how to use the alarm API can be found as part of maemo-examples. The required files are example_alarm.c, example_alarm_dbus.xml, Makefile and example_common.h.
Improve this page