Editing Documentation/Maemo 5 Developer Guide/Using Generic Platform Components/Alarm Framework
Warning: You are not logged in.
Your IP address will be recorded in this page's edit history.
The edit can be undone.
Please check the comparison below to verify that this is what you want to do, and then save the changes below to finish undoing the edit.
Latest revision | Your text | ||
Line 1: | Line 1: | ||
- | The | + | =Alarm Framework= |
- | + | 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: | |
- | + | ||
- | + | ||
- | The framework provides many other features, including: | + | |
* Setting multiple alarm events | * Setting multiple alarm events | ||
Line 16: | Line 13: | ||
* Choosing to postpone the alarm if it is missed | * Choosing to postpone the alarm if it is missed | ||
* Executing a given file (e.g. a program or a script) | * Executing a given file (e.g. a program or a script) | ||
- | * Sending a message to a | + | * Sending a message to a D-Bus message bus |
* Querying for existing alarm events in a given period of time | * Querying for existing alarm events in a given period of time | ||
* Deleting an existing alarm event | * Deleting an existing alarm event | ||
* Configuring the snooze time for the event | * Configuring the snooze time for the event | ||
* Configuring the default snooze time for all alarm events | * Configuring the default snooze time for all alarm events | ||
+ | |||
This topic shows how to use the alarm interface, describes its main functions and gives examples of use cases. | This topic shows how to use the alarm interface, describes its main functions and gives examples of use cases. | ||
Line 30: | Line 28: | ||
A single event may be set to repeat itself over and over again, at regular intervals or based on time and date. The alarmd daemon will remember these events over system shutdowns too. | A single event may be set to repeat itself over and over again, at regular intervals or based on time and date. 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 alarm daemon also supports the use of | + | 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 alarm daemon also supports the use 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 performed through D-Bus. It listens to both system and session buses. The easiest way is to use the C client API library, which offers straightforward API to modify the queue. | Communication with the alarmd daemon is performed through D-Bus. It listens to 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 file | + | The alarm queue used by the alarmd daemon is stored in file alarm_queue.ini, located in /var/cache/alarmd directory. |
- | |||
- | Alarm events and the functions to manage them are defined in | + | == Alarm Events== |
+ | Alarm events and the functions to manage them are defined in libalarm.h header file located in /usr/include/alarmd. It is a part of the libalarm-dev debian package. | ||
Alarm event structures contains basic information about the alarm such as: | Alarm event structures contains basic information about the alarm such as: | ||
Line 51: | Line 49: | ||
Once added to the queue, each alarm event is identified by a unique key, also known as a "cookie". The cookies can be used for deleting events, or retrieving information about a specific event. | Once added to the queue, each alarm event is identified by a unique key, also known as a "cookie". The cookies can be used for deleting events, or retrieving information about a specific event. | ||
+ | |||
==Managing Alarm Events== | ==Managing Alarm Events== | ||
===Adding Alarm Event to Queue=== | ===Adding Alarm Event to Queue=== | ||
+ | To add a new alarm event in to the queue, you need to set up a client side alarm event structure and send it to alarmd using alarmd_event_add() function. | ||
- | + | The ''alarmd_event_add()'' will perform sanity checking for the alarm event before sending it over to alarmd. If inconsistencies are noted, warnings and errors will be written to stderr. Any errors will make the alarm rejected before it is sent over to alarmd. | |
All alarms must have an non-empty application identifier string and at least one alarm action item. | All alarms must have an non-empty application identifier string and at least one alarm action item. | ||
- | For recurring alarms there must be either simple recurrency period or the | + | For recurring alarms there must be either simple recurrency period or the ''alarm_recur_t' items must be valid. |
For non-recurring alarms the triggering time must evaluate to a time in the future. | For non-recurring alarms the triggering time must evaluate to a time in the future. | ||
- | Addional checks include things like having all necessary | + | Addional checks include things like having all necessary dbus parameters filled in if dbus action is requested. |
'''Example: Adding simple two button dialog 10 seconds from now''' | '''Example: Adding simple two button dialog 10 seconds from now''' | ||
- | |||
- | |||
- | |||
- | static cookie_t add_two_button_alarm(void) | + | #include <alarmd/libalarm.h> |
- | { | + | #define APPID "example-apps" |
- | + | ||
- | + | static cookie_t add_two_button_alarm(void) | |
- | + | { | |
+ | cookie_t cookie = 0; | ||
+ | alarm_event_t *eve = 0; | ||
+ | alarm_action_t *act = 0; | ||
- | + | /* Create alarm event structure, set application | |
- | + | * identifier and dialog message */ | |
- | + | eve = alarm_event_create(); | |
- | + | alarm_event_set_alarm_appid(eve, APPID); | |
- | + | alarm_event_set_message(eve, "Example Message"); | |
- | + | /* Use absolute time triggering, show dialog | |
- | + | * ten seconds from now */ | |
- | + | eve->alarm_time = time(0) + 10; | |
- | + | ||
- | + | /* Add stop button action */ | |
- | + | act = alarm_event_add_actions(eve, 1); | |
- | + | alarm_action_set_label(act, "Stop"); | |
- | + | act->flags |= ALARM_ACTION_WHEN_RESPONDED; | |
- | + | act->flags |= ALARM_ACTION_TYPE_NOP; | |
- | + | ||
- | + | /* Add snooze button action */ | |
- | + | act = alarm_event_add_actions(eve, 1); | |
- | + | alarm_action_set_label(act, "Snooze"); | |
- | + | act->flags |= ALARM_ACTION_WHEN_RESPONDED; | |
- | + | act->flags |= ALARM_ACTION_TYPE_SNOOZE; | |
- | + | ||
- | + | /* Send the alarm to alarmd */ | |
- | + | cookie = alarmd_event_add(eve); | |
- | + | ||
- | + | /* Free all dynamic memory associated with the | |
- | + | * alarm event */ | |
- | + | alarm_event_delete(eve); | |
- | + | ||
- | + | return cookie; | |
- | + | } | |
- | + | ||
- | + | ||
- | + | ||
===Fetching Details of Alarm Event=== | ===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 alarmd_event_get() function, passing the event cookie as parameter. | |
- | 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 | + | |
'''Example: Showing some alarm event details''' | '''Example: Showing some alarm event details''' | ||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | + | static void show_alarm_details(cookie_t cookie) | |
- | + | { | |
- | + | alarm_event_t *eve = 0; | |
- | + | alarm_action_t *act = 0; | |
- | + | time_t tmo = time(0); | |
+ | |||
+ | if( (eve = alarmd_event_get(cookie)) == 0 ) | ||
+ | { | ||
+ | printf("unable to get details for cookie=%ld\n", (long)cookie); | ||
+ | goto cleanup; | ||
+ | } | ||
+ | |||
+ | printf("cookie %ld:\n", (long)cookie); | ||
+ | |||
+ | tmo -= eve->trigger; | ||
+ | printf("appid = %s\n", alarm_event_get_alarm_appid(eve)); | ||
+ | printf("trigger = T%+ld, %s", (long)tmo, ctime(&eve->trigger)); | ||
+ | printf("message = %s\n", alarm_event_get_message(eve)); | ||
+ | |||
+ | for( int i = 0; (act = alarm_event_get_action(eve, i)) != 0; ++i ) | ||
+ | { | ||
+ | printf("action%d.label = %s\n", i, alarm_action_get_label(act)); | ||
+ | } | ||
+ | |||
+ | cleanup: | ||
+ | |||
+ | /* Free all dynamic memory associated with the | ||
+ | * alarm event */ | ||
+ | alarm_event_delete(eve); | ||
+ | } | ||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
==Deleting Alarm Event== | ==Deleting Alarm Event== | ||
+ | To delete an alarm event, the alarmd_event_del() function needs to be called, passing the event cookie as a parameter. | ||
- | + | static void delete_alarm(cookie_t cookie) | |
+ | { | ||
+ | if( alarmd_event_del(cookie) == -1 ) | ||
+ | { | ||
+ | printf("unable to delete cookie=%ld\n", (long)cookie); | ||
+ | } | ||
+ | else | ||
+ | { | ||
+ | printf("deleted cookie=%ld\n", (long)cookie); | ||
+ | } | ||
+ | } | ||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
==Querying Multiple Alarm Events== | ==Querying Multiple Alarm Events== | ||
+ | The ''alarmd_event_query()'' function can be used for querying alarms in the queue. | ||
- | + | static void list_alarms() | |
+ | { | ||
+ | cookie_t *list = 0; | ||
+ | cookie_t cookie = 0; | ||
+ | alarm_event_t *eve = 0; | ||
+ | |||
+ | if( (list = alarmd_event_query(0,0, 0,0, APPID)) == 0 ) | ||
+ | { | ||
+ | printf("query failed\n"); | ||
+ | goto cleanup; | ||
+ | } | ||
+ | |||
+ | for( int i = 0; (cookie = list[i]) != 0; ++i ) | ||
+ | { | ||
+ | alarm_event_delete(eve); | ||
+ | |||
+ | if( (eve = alarmd_event_get(cookie)) == 0 ) | ||
+ | { | ||
+ | printf("unable to get details for cookie=%ld\n", (long)cookie); | ||
+ | continue; | ||
+ | } | ||
+ | |||
+ | printf("cookie: %ld, %s", cookie, ctime(&eve->trigger)); | ||
+ | } | ||
+ | |||
+ | cleanup: | ||
+ | free(list); | ||
+ | alarm_event_delete(eve); | ||
+ | } | ||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | + | ==Modifying an Existing Alarm Event== | |
- | + | If details of some already queued event need to be modified, this can be done by deleting the existing alarm and then adding new modified alarm. | |
- | + | ||
- | + | ||
- | + | ||
- | + | This process can be made faster and safer by using the alarmd_event_update() function, which does the delete old and new alarm in one D-Bus transaction. | |
- | + | ||
- | + | ||
- | + | static cookie_t update_alarm(cookie_t cookie) | |
- | + | { | |
- | + | cookie_t result = -1; | |
- | + | alarm_event_t *eve = 0; | |
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | if( (eve = alarmd_event_get(cookie)) == 0 ) | |
- | + | { | |
- | + | printf("unable to get details for cookie=%ld\n", (long)cookie); | |
- | + | goto cleanup; | |
- | + | } | |
+ | |||
+ | alarm_event_set_message(eve, "Updated Message"); | ||
+ | eve->alarm_time = time(0) + 20; | ||
+ | |||
+ | result = alarmd_event_update(eve); | ||
+ | |||
+ | cleanup: | ||
+ | |||
+ | alarm_event_delete(eve); | ||
+ | |||
+ | return result; | ||
+ | } | ||
- | == | + | ==Handling Dynamic Memory== |
+ | To make client software forward compatible all alarm events and associated action, recurrence and attribute items should be allocated using functions provided by libalarm. | ||
- | + | Dynamically allocated member data should be accessed using the set/get functions provided by libalarm. | |
- | + | Dynamically allocated structures should be released using the delete functions provided by libalarm. | |
- | + | Please note that alarm_event_delete() will assume that the above rules are followed and will try release all dynamic data associated with the alarm event structure. | |
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | Thus avoid writing client code that: | |
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | *Evaluates the size of libalarm structs at compile time | |
- | + | ||
- | + | alarm_event_t eve; | |
- | + | alarm_event_t *eve = calloc(1, sizeof *eve); | |
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | *Direcly sets dynamic member data | |
- | + | eve = alarm_event_create(); | |
+ | self->alarm_appid = (char *)"myapp"; | ||
- | + | *Might leak memory, might corrupt heap. | |
- | + | eve = alarm_event_create(); | |
+ | self->alarm_appid = strdup("myapp"); | ||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
==Localized Strings== | ==Localized Strings== | ||
- | |||
By default systemui dialog service will try to translate all text strings using gettext() API in hildon libraries textdomain. | By default systemui dialog service will try to translate all text strings using gettext() API in hildon libraries textdomain. | ||
Line 266: | Line 257: | ||
'''Example: two button alarm dialog with textdomain specified''' | '''Example: two button alarm dialog with textdomain specified''' | ||
- | |||
- | |||
- | |||
- | |||
- | |||
- | static cookie_t add_two_button_alarm_with_textdomain(void) | + | #define TEXTDOMAIN "mydomain" |
- | { | + | #define MESSAGE_KEY "translatable message text" |
- | + | #define STOP_BUTTON_KEY "translatable stop text" | |
- | + | #define SNOOZE_BUTTON_KEY "translatable snooze text" | |
- | + | ||
+ | static cookie_t add_two_button_alarm_with_textdomain(void) | ||
+ | { | ||
+ | alarm_event_t *eve = 0; | ||
+ | alarm_action_t *act = 0; | ||
+ | cookie_t cookie = 0; | ||
+ | |||
+ | /* Create alarm event structure, set application | ||
+ | * identifier and dialog message */ | ||
+ | eve = alarm_event_create(); | ||
+ | alarm_event_set_alarm_appid(eve, APPID); | ||
+ | alarm_event_set_message(eve, MESSAGE_KEY); | ||
- | + | /* Set the textdomain to be used while making | |
- | + | * translation lookups */ | |
- | + | ||
- | + | alarm_event_set_attr_string(eve, "textdomain", TEXTDOMAIN); | |
- | + | ||
+ | /* Use absolute time triggering, show dialog | ||
+ | * ten seconds from now */ | ||
+ | eve->alarm_time = time(0) + 10; | ||
+ | |||
+ | /* Add stop button action */ | ||
+ | act = alarm_event_add_actions(eve, 1); | ||
+ | alarm_action_set_label(act, STOP_BUTTON_KEY); | ||
+ | act->flags |= ALARM_ACTION_WHEN_RESPONDED; | ||
+ | act->flags |= ALARM_ACTION_TYPE_NOP; | ||
+ | |||
+ | /* Add snooze button action */ | ||
+ | act = alarm_event_add_actions(eve, 1); | ||
+ | alarm_action_set_label(act, SNOOZE_BUTTON_KEY); | ||
+ | act->flags |= ALARM_ACTION_WHEN_RESPONDED; | ||
+ | act->flags |= ALARM_ACTION_TYPE_SNOOZE; | ||
+ | |||
+ | /* Send the alarm to alarmd */ | ||
+ | cookie = alarmd_event_add(eve); | ||
+ | |||
+ | /* Free all dynamic memory associated with the | ||
+ | * alarm event */ | ||
+ | alarm_event_delete(eve); | ||
+ | |||
+ | return cookie; | ||
+ | } | ||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
==Obtaining more information== | ==Obtaining more information== | ||
- | + | Please refer [http://maemo.org/api_refs/5.0/beta/libalarm/ libalarm API documentation] for more information. | |
- | + | ||
- | + | ||
- | + | ||
- | + |
Learn more about Contributing to the wiki.