Event Sample Overview

Mobile native

The Event sample application demonstrates how you can create listeners for specified system and custom events, and listen to both types of events. To receive a custom event using a listener, the listener must be created and published.

The following figure illustrates the application view.

Figure: Event application screens

System events view Custom events view Received custom event view

The sample application provides a user interface for previewing available events and their status:

  • System events:
    • Battery level and charger status
    • USB and earjack status
    • Display state and auto-rotation mode
    • System boot and shutdown status
    • Memory status
    • Wi-Fi, Bluetooth, mobile data, and roaming state
    • Location, GPS, and NPS state
    • Incoming message status
    • Time, time zone, and hour format change
    • Language and region format change
    • Silent and vibration mode change
    • Font change
  • Custom events:
    • Custom events are received once they are registered and published by the user using the Custom events tab.

The following figure shows the structure of the user interface. EDJE layout scripts are used.

Figure: Event main layout structure

Event main layout structure

The PART_MAIN_CONTENT swallow is used as a container for both available layouts.

Figure: Event tab layout structure

Event tab layout structure

The final application view is created by embedding the proper components into the layouts depicted above. The resulting UI views are shown in the following figure.

Figure: Event application UI view

Event application UI view

The application workflow can be divided into 3 logical pipelines:

  • Application startup
  • System event handling
  • Custom event creation, publishing, and receiving

The following figure describes the workflow.

Figure: Application workflow

Application workflow

Prerequisites

To ensure proper application execution, the following privileges must be set:

  • http://tizen.org/privilege/network.get
  • http://tizen.org/privilege/message.read
  • http://tizen.org/privilege/display

Implementation

Type Definitions

The following code shows the structures used as placeholders for various application data:

// General structure for application data storage
struct 
__appdata 
{
   viewdata_s view;
};

// All the Evas_Object objects represent UI components
struct 
__viewdata 
{
   Evas_Object *win;
   Evas_Object *conform;
   Evas_Object *layout_main_panel;
   Evas_Object *main_toolbar;
   Evas_Object *main_toolbar_item_system_ev;
   Evas_Object *main_toolbar_item_custom_ev;
   Evas_Object *layout_system_ev;
   Evas_Object *system_ev_list;
   Evas_Object *layout_custom_ev;
   Evas_Object *custom_ev_name;
   Evas_Object *custom_ev_submit;
   Evas_Object *custom_ev_list;
   Elm_Genlist_Item_Class *custom_ev_itc;
   // Structure of callbacks handlers used by the Controller module to establish interaction with the Model module
   viewcallbacks_s callbacks;
};

typedef struct __viewdata viewdata_s;

// All the callback handlers are hooked by the Controller module to relate the control flow between the View and the Model modules
struct 
__viewcallbacks 
{
   // Invoked when the custom event needs to be published
   event_do_publish_cb do_publish_cb;
   // Invoked at the initialization phase to obtain all the information about system events for UI generation purpose
   event_get_system_info_cb get_system_info_cb;
   // Invoked when the user requests to register a custom event handler
   event_set_custom_info_cb set_custom_info_cb;
};

typedef struct __viewcallbacks viewcallbacks_s;

// Definition of callback handlers declared in the viewcallbacks_s structure 
typedef void (* event_do_publish_cb)(const char *event_name);
typedef bool (* event_get_system_info_cb)(int index, void **ev_info);
typedef bool (* event_set_custom_info_cb)(const char *event_name, void **ev_info);

// Structure keeps all the event-related information
struct 
__system_ev_info 
{
   // Type of the event - used only for the system events specification
   // Type is defined as an enum whose values represent all available system events
   event_type_t type;
   // Name of the event
   char *name;
   // Readable description of the event
   char *desc;
   // Status of the event
   char *status_1;
   // Status of the event. Used if the event contains up to 2 different status information:
   // Incoming message type / ID
   char *status_2;
   // Status of the event. Used if the event contains up to 3 different status information:
   // Bluetooth state / LE state / transferring state
   char *status_3;
   // Event callback handler function
   event_handler_h event_h;
};

typedef struct __system_ev_info system_ev_info_s;
typedef struct __system_ev_info custom_ev_info_s;

// Types of system events defined for source code simplification
// This type definition introduces event name mapping to its numerical representation
typedef enum 
{
   ET_BATTERY_CHARGER_STATUS, // SYSTEM_EVENT_BATTERY_CHARGER_STATUS
   ET_BATTERY_LEVEL_STATUS, // SYSTEM_EVENT_BATTERY_LEVEL_STATUS
   ET_USB_STATUS, //SYSTEM_EVENT_USB_STATUS
   ET_EARJACK_STATUS, // SYSTEM_EVENT_EARJACK_STATUS
   ET_DISPLAY_STATE, // SYSTEM_EVENT_DISPLAY_STATE
   ET_BOOT_COMPLETED, // SYSTEM_EVENT_BOOT_COMPLETED
   ET_SYSTEM_SHUTDOWN, // SYSTEM_EVENT_SYSTEM_SHUTDOWN
   ET_LOW_MEMORY, // SYSTEM_EVENT_LOW_MEMORY
   ET_WIFI_STATE, // SYSTEM_EVENT_WIFI_STATE
   ET_BT_STATE, // SYSTEM_EVENT_BT_STATE
   ET_LOCATION_ENABLE_STATE, // SYSTEM_EVENT_LOCATION_ENABLE_STATE
   ET_GPS_ENABLE_STATE, // SYSTEM_EVENT_GPS_ENABLE_STATE
   ET_NPS_ENABLE_STATE, // SYSTEM_EVENT_NPS_ENABLE_STATE
   ET_INCOMMING_MSG, // SYSTEM_EVENT_INCOMMING_MSG
   ET_TIME_CHANGED, // SYSTEM_EVENT_TIME_CHANGED
   ET_TIME_ZONE, // SYSTEM_EVENT_TIME_ZONE
   ET_HOUR_FORMAT, // SYSTEM_EVENT_HOUR_FORMAT
   ET_LANGUAGE_SET, // SYSTEM_EVENT_LANGUAGE_SET
   ET_REGION_FORMAT, // SYSTEM_EVENT_REGION_FORMAT
   ET_SILENT_MODE, // SYSTEM_EVENT_SILENT_MODE
   ET_VIBRATION_STATE, // SYSTEM_EVENT_VIBRATION_STATE
   ET_SCREEN_AUTOROTATE_STATE, // SYSTEM_EVENT_SCREEN_AUTOROTATE_STATE
   ET_MOBILE_DATA_STATE, // SYSTEM_EVENT_MOBILE_DATA_STATE
   ET_DATA_ROAMING_STATE, // SYSTEM_EVENT_DATA_ROAMING_STATE
   ET_FONT_SET // SYSTEM_EVENT_FONT_SET
} event_type_t;

The Model module declares 2 arrays:

  • static system_ev_info_s __system_ev[__SYSTEM_EVENT_COUNT_MAX];
  • static custom_ev_info_s __custom_ev[__CUSTOM_EVENT_COUNT_MAX];

The arrays are used to store system and custom event information. The __SYSTEM_EVENT_COUNT_MAX and __CUSTOM_EVENT_COUNT_MAX values are both set to 25 as the upperbound limit.

Application Initialization

To initialize the application:

  1. Implement the entire application life-cycle in the main source file, using a common Tizen application structure:
    int 
    main(int argc, char *argv[])
    {
       appdata_s ad = {{0,},};
       int ret = 0;
    
       ui_app_lifecycle_callback_s event_callback;
       app_event_handler_h handlers[5] = {NULL,};
    
       event_callback.create = __create_app;
       event_callback.terminate = __terminate_app;
       event_callback.pause = __pause_app;
       event_callback.resume = __resume_app;
       event_callback.app_control = __control_app;
    
       ui_app_add_event_handler(&handlers[APP_EVENT_LOW_BATTERY], APP_EVENT_LOW_BATTERY, __ui_app_low_battery, &ad);
       ui_app_add_event_handler(&handlers[APP_EVENT_LOW_MEMORY], APP_EVENT_LOW_MEMORY, __ui_app_low_memory, &ad);
       ui_app_add_event_handler(&handlers[APP_EVENT_DEVICE_ORIENTATION_CHANGED], APP_EVENT_DEVICE_ORIENTATION_CHANGED, __ui_app_orient_changed, &ad);
       ui_app_add_event_handler(&handlers[APP_EVENT_LANGUAGE_CHANGED], APP_EVENT_LANGUAGE_CHANGED, __ui_app_lang_changed, &ad);
       ui_app_add_event_handler(&handlers[APP_EVENT_REGION_FORMAT_CHANGED], APP_EVENT_REGION_FORMAT_CHANGED, __ui_app_region_changed, &ad);
    
       ret = ui_app_main(argc, argv, &event_callback, &ad);
       if (ret != APP_ERROR_NONE)
          controller_log(DLOG_ERROR, "Function ui_app_main() failed with error = %d", ret);
    
       return ret;
    }
    
  2. Execute the application initialization process in the __create_app() callback function, which is invoked on application startup:
    static bool 
    __create_app(void *data)
    {
       appdata_s *ad = (appdata_s *)data;
    
       return controller_init(&ad->view);
    }
    
  3. Invoke the controller_init() function, which controls the entire initialization process. This function is responsible for attaching the callback functions invoked by the View module to perform the required tasks:
    • __controller_event_do_publish_cb(): Publish the custom event registered by the user
    • __controller_event_get_system_info_cb(): Query system event information to populate the list with relevant data
    • __controller_event_set_custom_info_cb(): Register the event handler to be invoked on custom event occurrence

    The first and the third callback functions are called when the user performs an appropriate action in the application UI. The second callback function is called during the application UI creation.

    The application UI is created with the view_create_base_gui() function. Its source code is not listed within this topic. At the end of the initialization phase, a callback function is attached to each of the available system events within the __add_system_event_handlers() function.

    For a reference of all model-related functions not listed here, see Model.

    bool 
    controller_init(viewdata_s *vd)
    {
       vd->callbacks.do_publish_cb = __controller_event_do_publish_cb;
       vd->callbacks.get_system_info_cb = __controller_event_get_system_info_cb;
       vd->callbacks.set_custom_info_cb = __controller_event_set_custom_info_cb;
    
       if (!view_create_base_gui(vd))
          return false;
    
       __add_system_event_handlers();
    
       return true;
    }
    
    static void __add_system_event_handlers(void)
    {
       int i;
       // Iteration over all available system events
       for (i = 0; i < model_get_system_events_count(); i++) 
       {
          system_ev_info_s *ev_info = NULL;
    
          // System event information structure is obtained
          if (!model_get_system_event_info(i, &ev_info))
             continue;
    
          // Event handler is created and a callback function is attached
          model_add_system_event_handler(ev_info, __system_event_cb, (void *)ev_info);
       }
    }
    
  4. Attach the implementation of the callback functions in the controller_init() function:
    static void 
    __controller_event_do_publish_cb(const char *event_name)
    {
       controller_log(DLOG_INFO, "Event publishing: '%s'.", event_name);
    
       model_publish_event(event_name);
    }
    
  5. The __controller_event_get_system_info_cb() callback is invoked by the View module as long as the function returns true. Each time, the function is called with an incremented index value. As a result, the system event information ev_info, stored at specified index, is returned. The requested data structure is obtained with the model_get_system_event_info() function.

    static bool 
    __controller_event_get_system_info_cb(int index, void **ev_info)
    {
       *ev_info = NULL;
    
       if (index >= model_get_system_events_count())
          return false;
    
       system_ev_info_s *ev_info_tmp = NULL;
       if (!model_get_system_event_info(index, &ev_info_tmp))
          return false;
    
       *ev_info = (system_ev_info_s *)ev_info_tmp;
    
       return true;
    }
    
  6. The __controller_event_set_custom_info_cb() callback is invoked by the View model when the user requests to register custom event. If the registration procedure succeeds (see the __controller_register_custom_event() function implementation for details), the reference to the event information structure is returned using the ev_info parameter.

    static bool 
    __controller_event_set_custom_info_cb(const char *event_name, void **ev_info)
    {
       *ev_info = NULL;
    
       custom_ev_info_s *ev_info_tmp = NULL;
       if (!__controller_register_custom_event(event_name, &ev_info_tmp))
          return false;
    
       *ev_info = (custom_ev_info_s *)ev_info_tmp;
    
       return true;
    }
    
    bool 
    __controller_register_custom_event(const char *event_name, custom_ev_info_s **ev_info)
    {
       *ev_info = NULL;
       bool name_exists = false;
    
       // Event name, assigned by the user, must be unique, so you have to check whether it exists yet
       if (!model_check_event_exists(event_name, &name_exists))
          return false;
    
       // If there is already an event registered with the given name, the function fails
       if (name_exists) 
       {
          controller_log(DLOG_WARN, "Custom event '%s' already registered.", event_name);
    
          return false;
       }
    
       // Otherwise new event information structure is created
       if (!model_create_custom_event_info(event_name, ev_info))
          return false;
    
       // Finally, the event callback function is assigned, to be invoked when the event occurs
       if (!model_add_custom_event_handler(*ev_info, __custom_event_cb, (void *)(*ev_info)))
          return false;
    
       controller_log(DLOG_INFO, "Custom event registered: '%s'.", (*ev_info)->name);
    
       return true;
    }
    

Application Termination

To terminate the application:

  1. When the application is terminated, call the __terminate_app() callback function:
    static void 
    __terminate_app(void *data)
    {
       appdata_s *ad = (appdata_s *)data;
    
       controller_finit(&ad->view);
    }
    
  2. Release all previously allocated resources with the controller_finit() function, which is responsible for destroying the UI and detaching system and custom events handlers:
    void 
    controller_finit(viewdata_s *vd)
    {
       view_destroy_base_gui(vd);
       model_finit();
    }
    
  3. Detach the events handlers in the Model module within the model_finit() function, which calls 2 internal functions: __model_release_system_events() and __model_release_custom_events().

    As the UI is not a subject for this topic, the implementation of the view_destroy_base_gui() function is omitted.

    void 
    model_finit(void)
    {
       __model_release_system_events();
       __model_release_custom_events();
    }
    
  4. The events handler detaching procedure relies on the __model_remove_event_handler() function for each attached event handler regardless of its type (system or custom). The related resources are freed with the __model_free_system_event_info() and __model_free_custom_event_info() functions. For reference, see Model.
    static void 
    __model_release_system_events(void)
    {
       int i;
       for (i = 0; i < __SYSTEM_EVENT_COUNT_MAX; i++) 
       {
          system_ev_info_s *ev_info = &__system_ev[i];
    
          __model_remove_event_handler(ev_info->event_h);
          __model_free_system_event_info(ev_info);
       }
    }
    
    static void 
    __model_release_custom_events(void)
    {
       int i;
       for (i = 0; i < __custom_ev_count; i++) 
       {
          custom_ev_info_s *ev_info = &__custom_ev[i];
    
          __model_remove_event_handler(ev_info->event_h);
          __model_free_custom_event_info(ev_info);
       }
    
       __custom_ev_count = 0;
    }
    

    The __model_free_system_event_info() and __model_free_custom_event_info() functions are not listed here, as their implementation is based only on the free() function used to free the previously allocated memory.

System Events

After all the system events are successfully hooked in the initialization phase, they can be handled once they occur. This is done with the __system_event_cb() callback function registered within the __add_system_event_handlers() function. For reference, see Application Initialization.

static void 
__system_event_cb(const char *event_name, bundle *event_data, void *user_data)
{
   system_ev_info_s *ev_info = (system_ev_info_s *)user_data;
   char *status_1 = NULL;
   char *status_2 = NULL;
   char *status_3 = NULL;

   controller_log(DLOG_INFO, "System event '%s' occurred.", event_name);

   switch (ev_info->type) 
   {
      case ET_<event_type>:
         if (!model_get_bundle_str(event_data, EVENT_KEY_<name_1>, &status_1) ||
            !model_get_bundle_str(event_data, EVENT_KEY_<name_2>, &status_2) ||
            !model_get_bundle_str(event_data, EVENT_KEY_<name_3>, &status_3))
            return;
         break;
      default:
         return;
   }

   // status_1 ... status_3 char buffers are copied to the ev_info->status_1 ... ev_info->status_3
   model_assign_event_status(&ev_info->status_1, status_1);
   model_assign_event_status(&ev_info->status_2, status_2);
   model_assign_event_status(&ev_info->status_3, status_3);

   view_update_system_events();
}

All the information carried by the event is stored in a bundle object structure (event_data) followed by the event name (event_name). To avoid using an inefficient string comparison function for event distinguishing, the custom event type is used (see the event_type_t definition in the Type Definitions section). These types are statically preassigned. Based on the value of the type member of the ev_info structure of the system_ev_info_s data type, the events are distinguished and the event state is obtained from the bundle object.

Each event name and the relevant bundle keys are defined by the Event API. To extract the event status, the model_get_bundle_str() function is used. For the relation between the ET_<event_type> and EVENT_KEY_<name_1> ... EVENT_KEY_<name_3>, see the Event API.

Once the valid event status is obtained, the UI is updated to reflect the current event state using the view_update_system_events() function.

Custom Events

To manage custom events:

  1. Once the user registers a new event using the Register event button, the __controller_register_custom_event() function is invoked in a __controller_event_set_custom_info_cb() callback function triggered by the __view_register_event_button_clicked_cb() function attached to the Register event button. To clarify the process, all the mentioned functions are listed in the following example in the order of invocation.

    // Invoked on "Register event" button press
    static void 
    __view_register_event_button_clicked_cb(void *data, Evas_Object *obj, void *event_info)
    {
       viewdata_s *vd = (viewdata_s *)data;
       custom_ev_info_s *ev_info = NULL;
       char *event_name = NULL;
    
       // Event name input by the user is obtained
       if (!__view_get_custom_event_name(vd, &event_name)) 
       {
          controller_log(DLOG_WARN, "The custom event has no name assigned.");
    
          return;
       }
    
       // If the event name is provided properly, the Controller callback function is invoked
       // to register a new event with the given name
       bool ret = false;
       if (vd->callbacks.set_custom_info_cb)
          ret = vd->callbacks.set_custom_info_cb((const char *)event_name, (void *)&ev_info);
    
       free(event_name);
    
       if (!ret)
          return;
    
       // Once the custom event is registered successfully, the UI is updated to reflect recent changes
       elm_genlist_item_append(__viewdata->custom_ev_list,
                               __viewdata->custom_ev_itc,
                               (void *)ev_info,
                               NULL,
                               ELM_GENLIST_ITEM_NONE,
                               __view_custom_event_item_select_cb,
                               (void *)ev_info);
    }
    
    // Invoked within the __view_register_event_button_clicked_cb()
    static bool 
    __controller_event_set_custom_info_cb(const char *event_name, void **ev_info)
    {
       *ev_info = NULL;
    
       custom_ev_info_s *ev_info_tmp = NULL;
       // Custom event registration is performed here
       if (!__controller_register_custom_event(event_name, &ev_info_tmp))
          return false;
    
       *ev_info = (custom_ev_info_s *)ev_info_tmp;
    
       return true;
    }
    
    bool 
    __controller_register_custom_event(const char *event_name, custom_ev_info_s **ev_info)
    {
       *ev_info = NULL;
       bool name_exists = false;
    
       // Before the custom event is registered, verify whether the provided name exists
       // There is no dedicated Event API function which performs this task. In such case,
       // the Model iterates over all registered custom events stored within the internal data structure
       // and compares the name being registered with those already registered
       if (!model_check_event_exists(event_name, &name_exists))
          return false;
    
       if (name_exists) 
       {
          controller_log(DLOG_WARN, "Custom event '%s' already registered.", event_name);
    
          return false;
       }
    
       // If the custom name fails the existence verification, the relevant data structure is created
       // to store event-related information internally
       if (!model_create_custom_event_info(event_name, ev_info))
          return false;
    
       // Once the internal data structure is created, the custom event handler is registered
       // and the callback function attached to the event handler
       if (!model_add_custom_event_handler(*ev_info, __custom_event_cb, (void *)(*ev_info)))
          return false;
    
       controller_log(DLOG_INFO, "Custom event registered: '%s'.", (*ev_info)->name);
    
       return true;
    }
    
  2. After the custom event is registered and appears on the list, it can be published by a simple click on the relevant list item. The published item can be hooked only by those applications which are signed with the publisher certificate. The entire publishing process is shown within the following source code.

    // Invoked when the user selects an event-related item on the list
    static void 
    __view_custom_event_item_select_cb(void *data, Evas_Object *obj, void *event_info)
    {
       custom_ev_info_s *ev_info = (custom_ev_info_s *)data;
    
       if (!ev_info) 
       {
          controller_log(DLOG_ERROR, "ev_info == NULL !!!");
    
          return;
       } 
       else if (!ev_info->name) 
       {
          controller_log(DLOG_ERROR, "ev_info->name == NULL !!!");
    
          return;
       }
    
       // Controller is requested to publish the event by its name
       if (__viewdata->callbacks.do_publish_cb)
          __viewdata->callbacks.do_publish_cb(ev_info->name);
    }
    
    // Invoked by the __view_custom_event_item_select_cb() function
    static void 
    __controller_event_do_publish_cb(const char *event_name)
    {
       controller_log(DLOG_INFO, "Event publishing: '%s'.", event_name);
    
       // Event is published 
       model_publish_event(event_name);
    }
    
  3. Once the event is published, the callback function attached to its handler is invoked within all those applications which are signed with the same certificate as the publisher. In this case, only the Event sample application receives the event using the previously attached __custom_event_cb() callback function:

    static void 
    __custom_event_cb(const char *event_name, bundle *event_data, void *user_data)
    {
       custom_ev_info_s *ev_info = (custom_ev_info_s *)user_data;
       char *status = NULL;
    
       // Each custom event owns only one predefined key pointing to its status: CUSTOM_EVENT_KEY_STATUS
       // The key is defined within this application: CUSTOM_EVENT_KEY_STATUS == "custom_event_status"
       if (!model_get_bundle_str(event_data, CUSTOM_EVENT_KEY_STATUS, &status))
          return;
    
       // If the status is successfully obtained from the event bundle, it is stored within the internal data structure
       model_assign_event_status(&ev_info->status_1, status);
    
       // Finally, the event status is displayed on a toast message...
       view_display_custom_event(ev_info->name, ev_info->status_1);
       // ... and on the relevant list item
       view_update_custom_events();
    }
    

    For Model-related function implementation and description, see Model.

Model

The responsibility of the application Model module is to operate directly on the Event API and related data. The additional benefit of this module is the simplification of the API function calling, as error checking and message logging is performed here.

Some of the functions implemented within the Model module have been briefly described in Application Termination section (__model_release_system_events(), __model_release_custom_events(), model_finit(), __model_free_system_event_info(), __model_free_custom_event_info()). The most important functions are described here.

Most of the Model functions operate on the system_ev_info_s or custom_ev_info_s structures, which represent the system and custom events internally.

To operate on the Event API and related data with the Model module:

  1. Add a handler to the specified event with the model_add_<event_type>_event_handler() function, where <event_type> stands for system or custom:

    bool 
    model_add_<event_type>_event_handler(<event_type>_ev_info_s *ev_info, event_cb callback, void *user_data)
    {
       if (!ev_info || !callback) 
       {
          controller_log(DLOG_ERROR, "Wrong argument provided.");
    
          return false;
       }
    
       // Event API function is called with name stored in the internal data structure
       // Callback function is attached to the event handler
       int ret = event_add_event_handler(ev_info->name, callback, user_data, &ev_info->event_h);
       if (ret != EVENT_ERROR_NONE) 
       {
          controller_log(DLOG_ERROR, "Function event_add_event_handler() failed with error = %d.", ret);
    
          return false;
       }
    
       return true;
    }
    
  2. Release the event handler using the __model_remove_event_handler() function regardless of its <event_type>:

    bool 
    __model_remove_event_handler(event_handler_h event_handler)
    {
       int ret = event_remove_event_handler(event_handler);
       if (ret != EVENT_ERROR_NONE) 
       {
          controller_log(DLOG_ERROR, "Function event_remove_event_handler() failed with error = %d.", ret);
    
          return false;
       }
    
       return true;
    }
    
  3. To publish a custom event, the model_publish_event() function must be called with the event name:

    bool 
    model_publish_event(const char *event_name)
    {
       static unsigned int custom_ev_counter = 0;
    
       if (!event_name) 
       {
          controller_log(DLOG_ERROR, "Wrong argument provided.");
    
          return false;
       }
    
       // Bundle object is the carrier of the event information
       // It must be created and filled with proper data which describes event status
       bundle *bundle_ev = bundle_create();
       if (!bundle_ev) 
       {
          controller_log(DLOG_ERROR, "Function bundle_create() failed.");
    
          return false;
       }
    
       // Custom event status is created by simple concatenation of the status counter (custom_ev_counter) followed by the "status value" label
       custom_ev_counter++;
       char status[__STATUS_MSG_BUFF] = {0,};
       snprintf(status, __STATUS_MSG_BUFF, "status value %u", custom_ev_counter);
    
       // Custom event status string is added to the event information carrier (bundle object)
       // with predefined key: CUSTOM_EVENT_KEY_STATUS == "custom_event_status"
       int ret = bundle_add_str(bundle_ev, CUSTOM_EVENT_KEY_STATUS, status);
       if (ret != EVENT_ERROR_NONE) 
       {
          controller_log(DLOG_ERROR, "Function bundle_add_str() failed with error %d.", ret);
    
          return false;
       }
    
       // Finally, the event (identified by event_name) is published (broadcasted) with the previously created bundle object
       ret = event_publish_app_event(event_name, bundle_ev);
       // Once the event is published, the associated bundle object is not necessary anymore - it must be freed
       bundle_free(bundle_ev);
    
       if (ret != EVENT_ERROR_NONE) 
       {
          controller_log(DLOG_ERROR, "Function event_publish_app_event() failed with error %d.", ret);
    
          return false;
       }
    
       return true;
    }
    

    The custom event name must strictly follow the event.<app_id>.<custom_name> naming rule defined by the Event API. In the name, <app_id> is the identifier of the calling application, and <custom_name> is a custom name assigned by you or the user. For this reason, the supporting __model_format_custom_event_name() function is implemented.

    static void 
    __model_format_custom_event_name(const char *custom_name, char **ev_name)
    {
       // Naming rule is applied
       int ev_name_len = strlen("event") + strlen(APP_ID) + strlen(custom_name) + 3;
       *ev_name = (char *)calloc(ev_name_len, sizeof(char));
       snprintf(*ev_name, ev_name_len, "event.%s.%s", APP_ID, custom_name);
    
       // All whitespaces are removed from the <custom_name> and the string is converted to the lower case
       int i;
       for (i = 0; i < ev_name_len; i++) 
       {
          (*ev_name)[i] = tolower((*ev_name)[i]);
    
          if ((*ev_name)[i] == 32)
             (*ev_name)[i] = '_';
       }
    }
    
  4. Use the model_get_bundle_str() function to obtain the event status from the associated bundle object based on the known CUSTOM_EVENT_KEY_STATUS == "custom_event_status" key.

    bool 
    model_get_bundle_str(bundle *bundle_obj, const char *key, char **str)
    {
       *str = NULL;
    
       int ret = bundle_get_str(bundle_obj, key, str);
       if (ret != BUNDLE_ERROR_NONE) 
       {
          controller_log(DLOG_ERROR, "Function bundle_get_str() failed with error = %d.", ret);
    
          return false;
       }
    
       return true;
    }
    

The following list gives a brief description on the roles of the remaining functions.

  • model_get_system_events_count(): Returns the number of registered system events based on the number of relevant data stored internally.
  • model_get_system_event_info(): Returns the system event information structure stored internally.
  • model_create_custom_event_info(): Creates the custom event information structure and stores it internally.
  • model_assign_event_status(): Assigns the status message to the specified event structure stored internally.
  • model_check_event_exists(): Checks whether given event name is already registered within internal data structure.