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:

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

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