App-common Sample Overview

Mobile native

The Application Common sample demonstrates how you can extract information from the calling application (name, paths). In addition, it shows how to obtain the details of the application events when they occur.

The following figure illustrates the application views.

Figure: Application Common screens

Application view Events view Paths view Files view

The sample application provides a user interface for previewing the following application-related information:

  • Application name, ID, version
  • Events details (if occurred):
    • Low memory status
    • Low battery status
    • Changed language
    • Changed regional formatting
    • Device orientation
    • Suspend state
  • Path to the specific data included in the application package (such as data, cache, and resource) and file names stored in these locations.

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

Figure: Application Common main layout structure

Application Common main layout structure

The PART_MAIN_CONTENT swallow is used as a container for the layouts of all the tabs.

Figure: Application Common tab layout structure

Application Common tab layout structure

The following layout is embedded into the default part of the elm_popup component.

Figure: Application Common popup window layout structure

Application Common popup window layout structure

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

Figure: Application Common application UI view

Application Common application UI view

The application workflow can be divided into 2 logical pipelines:

  • Application startup
  • Event handling

The following figure describes the workflow.

Figure: Application workflow

Application workflow

Implementation

Type Definitions

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

struct 
__appdata 
{
   viewdata_s view; // View-related data
   modeldata_s model; // Model-related data
};

// 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_app;
   Evas_Object *main_toolbar_item_events;
   Evas_Object *main_toolbar_item_paths;
   Evas_Object *layout_app;
   Evas_Object *layout_events;
   Evas_Object *layout_paths;
   Evas_Object *paths_list;
   Evas_Object *popup_paths;
   Evas_Object *popup_files_list;
   // Callback function called when popup window is opened from "Paths" tab
   paths_popup_opened_cb popup_opened_cb;
};

typedef void(*paths_popup_opened_cb)(const char *path);

// Handlers for common application events:
// APP_EVENT_LOW_BATTERY,
// APP_EVENT_LOW_MEMORY,
// APP_EVENT_DEVICE_ORIENTATION_CHANGED,
// APP_EVENT_LANGUAGE_CHANGED,
// APP_EVENT_REGION_FORMAT_CHANGED,
// APP_EVENT_SUSPENDED_STATE_CHANGED.

struct 
__modeldata 
{
   app_event_handler_h handlers[5];
}

// Data structure used to populate the elm_genlist component in "Paths" tab with relevant data
struct 
__path_list_item 
{
   char *top_label; // Name of the file resources pointed by the path
   char *bottom_label; // Path to the file resources
   path_item_type type; // Type of the file resources
};

typedef enum 
{
   PIT_DATA, // Data directory for private application data
   PIT_CACHE, // Cache directory for temporary application data
   PIT_RESOURCE, // Resource directory
   PIT_SHARED_DATA, // Shared data directory used to share data with other applications
   PIT_SHARED_RESOURCE, // Shared resource directory used to share resources with other applications
   PIT_SHARED_TRUSTED, // Shared trusted directory used to share data with a family of trusted applications
   PIT_EXTERNAL_DATA, // External data directory for application data
   PIT_EXTERNAL_CACHE, // External cache directory for temporary application data
   PIT_EXTERNAL_SHARED_DATA, // External shared data directory used to share data with other applications
   PIT_TEP_RESOURCE // Tizen Expansion Package directory
} path_item_type;

Application Initialization

To create 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;
    
       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;
    
       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. Initialize the application 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, &ad->model);
    }
    
  3. Control the initialization process with the controller_init() function:
    bool 
    controller_init(viewdata_s *vd, modeldata_s *md)
    {
       if (!model_init(md))
          return false;
    
       if (!__add_event_handlers())
          return false;
    
       if (!view_create_base_gui(vd, __paths_popup_opened_cb))
          return false;
    
       __init_view_app();
    
       return true;
    }
    

    The following functions, listed in the code snippet above, are responsible for:

    • Storing model-related data for future use within the Model module:
      bool 
      model_init(modeldata_s *md)
      {
         if (!md) 
         {
            controller_log(DLOG_ERROR, "Invalid argument");
      
            return false;
         }
      
         __modeldata = md;
      
         return (__modeldata != NULL);
      }
      
    • Assigning events handlers:
      static bool 
      __add_event_handlers(void)
      {
         return(model_add_event_handler(APP_EVENT_LOW_BATTERY, __app_event_low_battery_cb) &&
                model_add_event_handler(APP_EVENT_LOW_MEMORY, __app_event_low_memory_cb) &&
                model_add_event_handler(APP_EVENT_DEVICE_ORIENTATION_CHANGED, __app_event_device_orientation_changed_cb) &&
                model_add_event_handler(APP_EVENT_LANGUAGE_CHANGED, __app_event_language_changed_cb) &&
                model_add_event_handler(APP_EVENT_REGION_FORMAT_CHANGED, __app_event_region_format_changed_cb) &&
                model_add_event_handler(APP_EVENT_SUSPENDED_STATE_CHANGED, __app_event_suspended_state_changed_cb));
      }
      

      For the model_add_event_handler() function details, see Application Events.

    • Creating the entire UI. The source code for the view_create_base_gui() function is not listed within this topic.
    • Setting the application common information, which is obtained using the functions implemented in the Model module displayed in the UI:
      static void 
      __init_view_app(void)
      {
         char *id = NULL;
         char *name = NULL;
         char *version = NULL;
      
         if (model_get_app_id(&id) &&
             model_get_app_name(&name) &&
             model_get_app_version(&version))
             view_update_application_tab(id, name, version);
      
         char *paths[PATHS_LIST_ITEMS_COUNT] = {NULL};
      
         if (model_app_get_data_path(&paths[PIT_DATA]) &&
             model_app_get_cache_path(&paths[PIT_CACHE]) &&
             model_app_get_resource_path(&paths[PIT_RESOURCE]) &&
             model_app_get_shared_data_path(&paths[PIT_SHARED_DATA]) &&
             model_app_get_shared_resource_path(&paths[PIT_SHARED_RESOURCE]) &&
             model_app_get_shared_trusted_path(&paths[PIT_SHARED_TRUSTED]) &&
             model_app_get_external_data_path(&paths[PIT_EXTERNAL_DATA]) &&
             model_app_get_external_cache_path(&paths[PIT_EXTERNAL_CACHE]) &&
             model_app_get_external_shared_data_path(&paths[PIT_EXTERNAL_SHARED_DATA]) &&
             model_app_get_tep_resource_path(&paths[PIT_TEP_RESOURCE])) 
             {
                int i;
                view_update_paths_tab(paths);
      
                for (i = 0; i < PATHS_LIST_ITEMS_COUNT; i++)
                    free(paths[i]);
             }
      }
      

    If any of the above functions (except __init_view_app()) fails, the application is terminated and the __terminate_app() callback function is called. For details, see Application Termination.

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 the event handlers:
    void 
    controller_finit(viewdata_s *vd)
    {
       view_destroy_base_gui(vd);
       __remove_event_handlers();
    }
    
  3. Detach the event handlers with the model_remove_event_handler() function for each attached event handler. For implementation details, see Application Events.

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

    static void 
    __remove_event_handlers(void)
    {
       model_remove_event_handler(APP_EVENT_LOW_BATTERY);
       model_remove_event_handler(APP_EVENT_LOW_MEMORY);
       model_remove_event_handler(APP_EVENT_DEVICE_ORIENTATION_CHANGED);
       model_remove_event_handler(APP_EVENT_LANGUAGE_CHANGED);
       model_remove_event_handler(APP_EVENT_REGION_FORMAT_CHANGED);
       model_remove_event_handler(APP_EVENT_SUSPENDED_STATE_CHANGED);
    }
    

Application Resources

Once the application is created and its UI is displayed, you can browse through the information gathered during the application initialization procedure. This information consists of:

  • Application name, ID, and version
  • Paths to the application resources, such as data and cache.

This information is obtained using the model_get_app_id(), model_get_app_name() and model_get_app_version() functions within the __init_view_app() function called during the application initialization procedure. The paths to the application resource directories are obtained using the model_get_app_<dir_type>_path() functions.

bool 
model_get_app_id(char **id)
{
   *id = NULL;

   int ret = app_get_id(id);
   if (ret != APP_ERROR_NONE) 
   {
      controller_log(DLOG_ERROR, "Function app_get_id() failed with error = %d", ret);

      return false;
   }

   return true;
}

The implementation of the model_get_app_name() and model_get_app_version() functions is exactly the same as the implementation of the model_get_app_id() function, but the app_get_name() and app_get_version() functions are used instead of the app_get_id() function.

bool 
model_get_app_<dir_type>_path(char **path)
{
   *path = NULL;

   char *path_tmp = app_get_<dir_type>_path();
   if (!path_tmp) 
   {
      controller_log(DLOG_ERROR, "Function app_get_<dir_type>_path() failed");

      return false;
   }

   *path = strdup(path_tmp);

   return true;
}

Application Events

To handle application events:

  1. Event handling is implemented together with the application resources. At the application initialization phase, the event handlers are attached for:

    • Low memory status
    • Low battery status
    • Language changed
    • Region format changed
    • Device orientation change
    • Suspended state occurrence

    Each of the above events is handled by one of the callback functions attached using the model_add_event_handler() function within the __add_event_handlers() function. For the implementation reference, see Application Initialization.

    bool 
    model_add_event_handler(app_event_type_e event_type, app_event_cb callback)
    {
       int ret = ui_app_add_event_handler(&__modeldata->handlers[event_type], event_type, callback, NULL);
       if (ret != APP_ERROR_NONE) 
       {
          controller_log(DLOG_ERROR, "Function ui_app_add_event_handler() failed with error = %d", ret);
    
          return false;
       }
    
       return true;
    }
    
  2. Once the event handler is attached and the event occurs, the assigned callback function is called. Regardless of the event type, the callback function structure is the same.

    static void 
    __app_event_<event_type>_cb(app_event_info_h event_info, void *user_data)
    {
       <event_status_type> status;
    
       if (!model_get_app_event_<event_type>(event_info, &status))
          return;
    
       // The event is handled appropriately to its type and displayed on the application UI
    }
    
  3. The model_get_app_event_<event_type>() function is responsible for obtaining detailed information from the event_info parameter of the event callback function. Depending on the event type, the relevant event information is returned:

    • Low memory event: normal status, soft or hard warning
    • Low battery event: the battery is under 1% or under 5%
    • Language changed event: language code
    • Region format changed event: region code
    • Device orientation changed even: natural position, left-side up, up-side down, right-side up
    • Suspended state occurrence event: enter or exit from the suspended state

    The implementation of the model_get_app_event_<event_type>() function is shown in the following example:

    bool 
    model_get_app_event_<event_type>(app_event_info_h event_info, <event_status_type> *status)
    {
       int ret = app_event_get_<event_type>(event_info, status);
       if (ret != APP_ERROR_NONE) 
       {
          controller_log(DLOG_ERROR, "Function app_event_get_<event_type>() failed with error = %d", ret);
    
          return false;
       }
    
       return true;
    }
    
  4. On the application termination phase, detach each attached event with the model_remove_event_handler() function:

    bool 
    model_remove_event_handler(app_event_type_e event_type)
    {
       int ret = ui_app_remove_event_handler(__modeldata->handlers[event_type]);
       if (ret != APP_ERROR_NONE) 
       {
          controller_log(DLOG_ERROR, "Function event_remove_event_handler() failed with error = %d", ret);
    
          return false;
       }
    
       return true;
    }
    

Model

The responsibility of the application Model module is to operate directly on the App Common 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.

All functions implemented within the Model module have been briefly described in the Application Initialization, Application Termination, Application Resources and Application Events sections. Their implementation is repeated here for clarity.

  1. Add an event handler by assigning a callback function to the event_type parameter:

    bool 
    model_add_event_handler(app_event_type_e event_type, app_event_cb callback)
    {
       int ret = ui_app_add_event_handler(&__modeldata->handlers[event_type], event_type, callback, NULL);
       if (ret != APP_ERROR_NONE) 
       {
          controller_log(DLOG_ERROR, "Function ui_app_add_event_handler() failed with error = %d", ret);
    
          return false;
       }
    
       return true;
    }
    
  2. Remove a previously attached event handler assigned to the specific event_type parameter:

    bool 
    model_remove_event_handler(app_event_type_e event_type)
    {
       int ret = ui_app_remove_event_handler(__modeldata->handlers[event_type]);
       if (ret != APP_ERROR_NONE) 
       {
          controller_log(DLOG_ERROR, "Function event_remove_event_handler() failed with error = %d", ret);
    
          return false;
       }
    
       return true;
    }
    
  3. Get an application resource and a path to the application directory:

    • <res>: id / name / version

    • <dir_type>: data / cache / resource / shared_data / shared_resource / shared_trusted / external_data / external_cache / external_shared_data / tep_resource

    bool 
    model_get_app_<res>(char **<res>)
    {
       *<res> = NULL;
    
       int ret = app_get_<res>(<res>);
       if (ret != APP_ERROR_NONE) 
       {
          controller_log(DLOG_ERROR, "Function app_get_<res>() failed with error = %d", ret);
    
          return false;
       }
    
       return true;
    }
    
    bool 
    model_get_app_<dir_type>_path(char **path)
    {
       *path = NULL;
    
       char *path_tmp = app_get_<dir_type>_path();
       if (!path_tmp) 
       {
          controller_log(DLOG_ERROR, "Function app_get_<dir_type>_path() failed");
    
          return false;
       }
    
       *path = strdup(path_tmp);
    
       return true;
    }
    
  4. Extract the event details at the time of its occurrence in the event callback handler by invoking the app_event_get_<event_type>() function wrapped by the model_get_app_event_<event_type>() function.

    • <event_type>: low_battery_status / low_memory_status / language / region_format / device_orientation / suspended_state

    bool 
    model_get_app_event_<event_type>(app_event_info_h event_info, <event_status_type> *status)
    {
       int ret = app_event_get_<event_type>(event_info, status);
       if (ret != APP_ERROR_NONE) 
       {
          controller_log(DLOG_ERROR, "Function app_event_get_<event_type>() failed with error = %d", ret);
    
          return false;
       }
    
       return true;
    }