Using the Alarm Interface

Introduction

This document has been reviewed for maemo 4.0 release.

The maemo alarm framework provides an easy way to manage timed events in the device. It is powerful, and not restricted only to wake-up alarms. The framework provides many other features, including:

  • Setting multiple alarm events
  • Configuring the number of recurrences and the time between each one
  • Choosing whether the alarm dialog should be shown
  • Setting the title and the message to be shown in the alarm dialog
  • Selecting a custom icon file to be shown in the alarm dialog
  • Selecting a custom sound file to be played while the alarm dialog is shown
  • Choosing to boot the device if it is turned off
  • Choosing to run the alarm only if the device is connected
  • Choosing to run the alarm in the system start-up if it is missed
  • Choosing to postpone the alarm if it is missed
  • Executing a given file (e.g., a program or a script)
  • Sending a message to a D-Bus message bus
  • Querying for existing alarm events in a given period of time
  • Deleting an existing alarm event
  • Configuring the snooze time for the event
  • Configuring 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 it possible for applications to get D-Bus messages or exec calls at certain times.

Applications register an event happening at a certain time. The alarmd daemon will then call the application when the event is due, so the application does not need to be running during the 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 regular intervals. 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 when powered off. These events may also be set to run in a hidden power-on 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 power-up 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 a part of the libalarm-dev debian package.

Each alarm event is identified by a unique key, also known as a "cookie". These identifiers are obtained, when a new event is added to the queue. They are used whenever needed, or to retrieve information about a 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 happen 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 Localized Strings section.
message char * Message shown in the alarm dialog. May contain gettext identifiers, as described in Localized 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 accepted by glib's g_shell_parse_argv.
flags int32_t Options for the event; the value should be members of enumeration alarmeventflags, ORed together bitwise.
snoozed uint32_t The number of 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 will not show a dialog, but instead perform 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 turned off.
ALARM_EVENT_ACTDEAD If the device is turned off, it will be started with display off, and turned off again after the action is performed.
ALARM_EVENT_SHOW_ICON While the event is on queue, an icon should be shown in the status bar.
ALARM_EVENT_RUN_DELAYED Defines whether the event should be run in case it has been missed or jumped over.
ALARM_EVENT_CONNECTED Defines that 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 becomes available.
ALARM_EVENT_ACTIVATION Defines whether the D-Bus action of the event should use D-Bus activation, i.e. whether the service should 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 also. Only applies to recurring alarms.

Managing Alarm Events

Adding Alarm Event to Queue

To add a new alarm event to the queue, a new instance of alarm_error_t structure is needed, and the necessary fields have to be filled in. The only mandatory one 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 that is needed 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 Alarm Event

Having set an alarm event, it is not possible to edit its details anymore, but it is possible to fetch the alarm details 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 necessary a call to the alarm_event_free function, receiving 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 Alarm Event

Finally, to delete an alarm event, the alarm_event_del function needs to be called, 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 1, otherwise it returns 0.

Checking for Errors

Whenever an error occurs during a call to any of the functions, an error code is set, and it 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 has occurred.
ALARMD_ERROR_DBUS An error with D-Bus occurred, probably could not 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 Memory allocation failed.
ALARMD_ERROR_ARGUMENT An argument given by caller was invalid.

Localized Strings

If the message in the alarm dialog is needed to be available in the language that is being used in the device, specially formatted stringscan be used. The translations are fetched with dgettext. To get the message translated, it is necessary 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 replacements for these can be given too:

    {message domain,message id,replacement1,replacement2...}
	

The replacement may be in form {...}, but cannot contain anything else; the translated part can be embedded in the main string. Positional parameters or any other format options than %s are not supported.

Escaping Strings

If the message comes from user, the alarm_escape_string function can be used 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 is not considered as a localization string. All occurrences of '{', '}' characters should be escaped with a backslash, and all backslashes should be duplicated. The function receives a string as parameter, and returns a newly allocated string that 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, the alarm_unescape_string function must be called. It receives a string as parameter, and returns a newly allocated 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, the alarm_unescape_string_noalloc can be used 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 is possible, since the unescaped string cannot be longer than 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 on their websites:

  1. D-BUS site
  2. GConf site
  3. GTK+ home page


Improve this page