Documentation/Maemo 5 Developer Guide/Application Development/LibOSSO library

= Overview =

LibOSSO is the basic library, containing required and helpful functions for Maemo applications. The full API documentation of LibOSSO is available in Doxygen format.

= Maemo initialization =

All Maemo applications must be initialized correctly, or they do not work as expected. One symptom of missing initialization is that application starts from Task Navigator, but closes automatically after few seconds.

Initializing application is performed with  function. With this function, the application connects to D-BUS session bus and system bus. function should only be called once in the application, and the structure of type osso_context_t type that is returned should be stored for later use. First parameter of the function is the application D-BUS name, used also in application D-BUS service file. Second parameter is the application version as a string. Third is the activation type, with TRUE the library assumes that the application binary has been launched by the D-BUS daemon, and thus connects to the D-BUS activation bus. Fourth parameter is the GLib main-loop context to connect to, NULL should be used for the default context.

osso_context_t * osso_initialize(const gchar *application, const gchar* version, gboolean activation, GMainContext *context)

When the application is closing, osso_deinitialize function should be called to close the message bus connection and free all memory allocated by the library.

void osso_deinitialize(osso_context_t *osso)

Below is an example (example_libosso.c) of this; if the initialization does not succeed, the function returns NULL.

   #define  OSSO_EXAMPLE_NAME   "example_libosso"   #define  OSSO_EXAMPLE_SERVICE "org.maemo." OSSO_EXAMPLE_NAME '' /* ... */ ''     osso_context_t  * osso_context  ; '' /* ... */       /* Initialize maemo application */ '' osso_context  =  osso_initialize   ( OSSO_EXAMPLE_SERVICE ,  "0.0.1"  , TRUE <font color="#990000">, NULL <font color="#990000">);  <font color="#9A1900">/* Check that initialization was ok */   <font color="#0000FF">if  <font color="#990000">( osso_context <font color="#990000"> == NULL <font color="#990000">)  <font color="#FF0000">{  <font color="#0000FF">return  OSSO_ERROR <font color="#990000"> ; <font color="#FF0000">} '' <font color="#9A1900">/* ... */       <font color="#9A1900">/* Deinitialize OSSO */ ''  <font color="#000000">osso_deinitialize  <font color="#990000">( osso_context <font color="#990000">); </tt>

= Remote process messages =

System wide messages in Maemo platform are handled with D-BUS system messaging, which is a Remote Process Communication (RPC) method. LibOSSO has own wrappers to normal D-BUS functions to make usage simpler and to maintain backward compatibility. By using D-BUS, applications can send messages from one process to another.

Callback function receiving the messages can be as follows (example_libosso.c), where AppData structure contains the initialized osso_context:

<tt>  <font color="#000080"> #include  <font color="#FF0000">&lt;hildon/hildon-program.h&gt;  <font color="#000080"> #include  <font color="#FF0000">&lt;hildon/hildon-banner.h&gt;  <font color="#000080"> #include  <font color="#FF0000">&lt;gtk/gtk.h&gt;  <font color="#000080"> #include  <font color="#FF0000">&lt;libosso.h&gt;  <font color="#000080"> #define  OSSO_EXAMPLE_NAME   <font color="#FF0000">"example_libosso"  <font color="#000080"> #define  OSSO_EXAMPLE_SERVICE <font color="#FF0000">"org.maemo." OSSO_EXAMPLE_NAME  <font color="#000080"> #define  OSSO_EXAMPLE_OBJECT <font color="#FF0000">"/org/maemo/" OSSO_EXAMPLE_NAME  <font color="#000080"> #define  OSSO_EXAMPLE_IFACE  <font color="#FF0000">"org.maemo." OSSO_EXAMPLE_NAME '' <font color="#9A1900">/* ... */   <font color="#9A1900">/* Application UI data struct */ ''  <font color="#0000FF">typedef   <font color="#0000FF">struct   <font color="#009900">_AppData AppData <font color="#990000"> ;  <font color="#0000FF">struct  <font color="#009900">_AppData  <font color="#FF0000">{ HildonProgram <font color="#990000"> * program <font color="#990000"> ; HildonWindow <font color="#990000"> * window <font color="#990000"> ; osso_context_t <font color="#990000"> * osso_context <font color="#990000"> ; <font color="#FF0000">} <font color="#990000"> ; '' <font color="#9A1900">/* ... */   <font color="#9A1900">/* Callback for normal D-BUS messages */ '' gint  <font color="#000000">dbus_req_handler  <font color="#990000">(   <font color="#0000FF">const  gchar <font color="#990000"> * interface <font color="#990000">,   <font color="#0000FF">const  gchar <font color="#990000"> * method <font color="#990000">,                        GArray <font color="#990000"> * arguments <font color="#990000">, gpointer data <font color="#990000">,                        osso_rpc_t <font color="#990000"> * retval <font color="#990000">) <font color="#FF0000">{ AppData <font color="#990000"> * appdata <font color="#990000"> ; appdata <font color="#990000"> = <font color="#990000">( AppData <font color="#990000"> *) data <font color="#990000"> ;  <font color="#000000">osso_system_note_infoprint  <font color="#990000">( appdata <font color="#990000">-&gt; osso_context <font color="#990000">, method <font color="#990000">, retval <font color="#990000">);  <font color="#000000">osso_rpc_free_val  <font color="#990000">( retval <font color="#990000">);  <font color="#0000FF">return  OSSO_OK <font color="#990000"> ; <font color="#FF0000">} </tt>

To attach this callback function to receive all the normal D-BUS messages to the application, use the osso_rpc_set_default_cb_f function as follows:

<tt> <font color="#009900">int  <font color="#000000">main   <font color="#990000">(  <font color="#009900">int argc <font color="#990000">,  <font color="#009900">char  <font color="#990000"> * argv <font color="#990000">[]) <font color="#FF0000">{ osso_return_t result <font color="#990000"> ; '' <font color="#9A1900">/* ... */       <font color="#9A1900">/* Add handler for session bus D-BUS messages */ '' result <font color="#990000"> =  <font color="#000000">osso_rpc_set_cb_f   <font color="#990000">( appdata <font color="#990000">-&gt; osso_context <font color="#990000">,                                 OSSO_EXAMPLE_SERVICE <font color="#990000">,                                 OSSO_EXAMPLE_OBJECT <font color="#990000">,                                 OSSO_EXAMPLE_IFACE <font color="#990000">,                                 dbus_req_handler <font color="#990000">, appdata <font color="#990000">);  <font color="#0000FF">if  <font color="#990000">( result <font color="#990000"> != OSSO_OK <font color="#990000">)  <font color="#FF0000">{  <font color="#000000">g_print  <font color="#990000">(  <font color="#FF0000">"Error setting D-BUS callback (%d)  <font color="#CC33CC">\n  <font color="#FF0000">"  <font color="#990000">, result <font color="#990000">);  <font color="#0000FF">return  OSSO_ERROR <font color="#990000"> ; <font color="#FF0000">} '' <font color="#9A1900">/* ... */       <font color="#9A1900">/* Deinitialize OSSO */ ''  <font color="#000000">osso_deinitialize  <font color="#990000">( osso_context <font color="#990000">); <font color="#FF0000">} </tt>

Now the application is ready to receive D-BUS messages. Whenever it receives one, the dbus_req_handler function is called to process the message. Another test application (example_message.c ), can send the ``HelloWorld'' that this application was designed to handle, as follows:

<tt> '' <font color="#9A1900">/* ... */ ''  <font color="#000080"> #define  OSSO_EXAMPLE_NAME    <font color="#FF0000">"example_libosso"  <font color="#000080"> #define  OSSO_EXAMPLE_SERVICE <font color="#FF0000">"org.maemo." OSSO_EXAMPLE_NAME  <font color="#000080"> #define  OSSO_EXAMPLE_OBJECT <font color="#FF0000">"/org/maemo/" OSSO_EXAMPLE_NAME  <font color="#000080"> #define  OSSO_EXAMPLE_IFACE  <font color="#FF0000">"org.maemo." OSSO_EXAMPLE_NAME  <font color="#000080"> #define  OSSO_EXAMPLE_MESSAGE <font color="#FF0000">"HelloWorld" '' <font color="#9A1900">/* ... */ '' ret <font color="#990000"> =   <font color="#000000">osso_rpc_run   <font color="#990000">( osso_context <font color="#990000">,                     OSSO_EXAMPLE_SERVICE <font color="#990000">,                     OSSO_EXAMPLE_OBJECT <font color="#990000">,                     OSSO_EXAMPLE_IFACE <font color="#990000">,                     OSSO_EXAMPLE_MESSAGE <font color="#990000">,  <font color="#990000">&amp; retval <font color="#990000">, DBUS_TYPE_INVALID <font color="#990000">); '' <font color="#9A1900">/* ... */ '' </tt>

When example_libosso_test is started, it sends an ``example_message'' D-BUS message to org.maemo.example_libosso service, attached to the example_libosso application (See more about D-BUS service files from an earlier section). Now when example_libosso receives the message, it shows a banner.

One nice thing about D-BUS is that the receiving application does not even need to be started: D-BUS can automatically start the application based on its service file, and then pass the message to it!

=Hardware state messages =

Maemo applications can connect to listen the system D-BUS messages, like ``battery low and ``shutdown. When these messages are received, the application may want to ask the user to save files that are open, or react however wanted.

A callback function is defined like below, taking  and gpointer as parameters. The changed state can be gotten from state variable.

<tt>  <font color="#9A1900">/* Callback for hardware D-BUS events */  <font color="#009900">void  <font color="#000000">hw_event_handler   <font color="#990000">( osso_hw_state_t <font color="#990000"> * state <font color="#990000">, gpointer data <font color="#990000">) <font color="#FF0000">{ AppData <font color="#990000"> * appdata <font color="#990000"> ; appdata <font color="#990000"> = <font color="#990000">( AppData <font color="#990000"> *) data <font color="#990000"> ;  <font color="#0000FF">if  <font color="#990000">( state <font color="#990000">-&gt; shutdown_ind <font color="#990000">) <font color="#FF0000">{  <font color="#000000">hildon_banner_show_information  <font color="#990000">(   <font color="#000000">GTK_WIDGET   <font color="#990000">( appdata <font color="#990000">-&gt; window <font color="#990000">), NULL <font color="#990000">,                                         <font color="#FF0000">"Shutdown event!"  <font color="#990000">); <font color="#FF0000">}  <font color="#0000FF">if  <font color="#990000">( state <font color="#990000">-&gt; memory_low_ind <font color="#990000">) <font color="#FF0000">{  <font color="#000000">hildon_banner_show_information  <font color="#990000">(   <font color="#000000">GTK_WIDGET   <font color="#990000">( appdata <font color="#990000">-&gt; window <font color="#990000">), NULL <font color="#990000">,                                         <font color="#FF0000">"Memory low event!"  <font color="#990000">); <font color="#FF0000">}  <font color="#0000FF">if  <font color="#990000">( state <font color="#990000">-&gt; save_unsaved_data_ind <font color="#990000">) <font color="#FF0000">{  <font color="#000000">hildon_banner_show_information  <font color="#990000">(   <font color="#000000">GTK_WIDGET   <font color="#990000">( appdata <font color="#990000">-&gt; window <font color="#990000">), NULL <font color="#990000">,                                         <font color="#FF0000">"Must save unsaved data event!"  <font color="#990000">); <font color="#FF0000">}  <font color="#0000FF">if  <font color="#990000">( state <font color="#990000">-&gt; system_inactivity_ind <font color="#990000">) <font color="#FF0000">{  <font color="#000000">hildon_banner_show_information  <font color="#990000">(   <font color="#000000">GTK_WIDGET   <font color="#990000">( appdata <font color="#990000">-&gt; window <font color="#990000">), NULL <font color="#990000">,                                         <font color="#FF0000">"Minimize application inactivity event!"  <font color="#990000">); <font color="#FF0000">} <font color="#FF0000">} </tt>

To attach this handler, e.g. in application, use.

<tt>   '' <font color="#9A1900">/* ... */       <font color="#9A1900">/* Add handler for hardware D-BUS messages */ '' result <font color="#990000"> =  <font color="#000000">osso_hw_set_event_cb   <font color="#990000">( appdata <font color="#990000">-&gt; osso_context <font color="#990000">,          NULL <font color="#990000">, hw_event_handler <font color="#990000">,  <font color="#990000">( gpointer <font color="#990000">) appdata <font color="#990000">);  <font color="#0000FF">if  <font color="#990000">( result <font color="#990000"> != OSSO_OK <font color="#990000">) <font color="#FF0000">{  <font color="#000000">g_print  <font color="#990000">(  <font color="#FF0000">"Error setting HW state callback (%d)  <font color="#CC33CC">\n  <font color="#FF0000">"  <font color="#990000">, result <font color="#990000">);  <font color="#0000FF">return  OSSO_ERROR <font color="#990000"> ; <font color="#FF0000">} '' <font color="#9A1900">/* ... */ '' </tt>

N.B. These hardware events are not sent to the SDK, so testing them is only possible in Maemo device.

= System Exit message =

A system message is sent when applications are required to close themselves. Its callback is: (example_libosso.c):

<tt>  <font color="#9A1900">/* Callback for exit D-BUS event */  <font color="#009900">void  <font color="#000000">exit_event_handler   <font color="#990000">( gboolean die_now <font color="#990000">, gpointer data <font color="#990000">) <font color="#FF0000">{ AppData <font color="#990000"> * appdata <font color="#990000"> ; appdata <font color="#990000"> = <font color="#990000">( AppData <font color="#990000"> *) data <font color="#990000"> ;  <font color="#000000">g_print  <font color="#990000">(  <font color="#FF0000">"exit_event_handler called  <font color="#CC33CC">\n  <font color="#FF0000">"  <font color="#990000">);  <font color="#9A1900">/* Do whatever application needs to do before exiting */   <font color="#000000">hildon_banner_show_information  <font color="#990000">(   <font color="#000000">GTK_WIDGET   <font color="#990000">( appdata <font color="#990000">-&gt; window <font color="#990000">), NULL <font color="#990000">,                                     <font color="#FF0000">"Exiting..."  <font color="#990000">); <font color="#FF0000">} </tt>

The callback is set (e.g. in application main) as follows.

<tt> <font color="#009900">int  <font color="#000000">main   <font color="#990000">(  <font color="#009900">int argc <font color="#990000">,  <font color="#009900">char  <font color="#990000"> * argv <font color="#990000">[]  <font color="#990000">) <font color="#FF0000">{ '' <font color="#9A1900">/* ... */       <font color="#9A1900">/* Add handler for Exit D-BUS messages */ '' result <font color="#990000"> =  <font color="#000000">osso_application_set_exit_cb   <font color="#990000">( appdata <font color="#990000">-&gt; osso_context <font color="#990000">,                                            exit_event_handler <font color="#990000">,                                            <font color="#990000">( gpointer <font color="#990000">) appdata <font color="#990000">);  <font color="#0000FF">if  <font color="#990000">( result <font color="#990000"> != OSSO_OK <font color="#990000">)  <font color="#FF0000">{  <font color="#000000">g_print  <font color="#990000">(  <font color="#FF0000">"Error setting exit callback (%d)  <font color="#CC33CC">\n  <font color="#FF0000">"  <font color="#990000">, result <font color="#990000">);  <font color="#0000FF">return  OSSO_ERROR <font color="#990000"> ; <font color="#FF0000">} '' <font color="#9A1900">/* ... */ '' <font color="#FF0000">} </tt>

Now whenever the system needs to close an application for any reason, the close is performed gracefully.

= Application state saving and auto save =

State saving is a special feature of the Maemo platform. It means that applications save their running state from RAM to permanent memory, such as flash memory, and then end the running application process. This state saving happens when switching out from the application and the device memory is running low. When the user then returns to a backgrounded application, the application restarts, the application state is read from flash memory, and the user does not even know that the application was not running all the time.

Auto saving is an addition to state saving for editor-like applications containing user data. This data/document is automatically saved at the same time with state save. The main difference is that the application state is usually just a small amount of variables describing the state where the application was, whereas the auto-saved file can be any file the user was editing. Auto saving guarantees that user files are not lost when e.g. the battery runs out.

Information on how to implement state saving can be found in LibOSSO API document.