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
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
The PART_MAIN_CONTENT swallow is used as a container for the layouts of all the tabs.
Figure: 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
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
The application workflow can be divided into 2 logical pipelines:
- Application startup
- Event handling
The following figure describes the workflow.
Figure: 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:
- 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; }
- 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); }
- 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.
- Storing model-related data for future use within the Model module:
Application Termination
To terminate the application:
- 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); }
- 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(); }
- 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:
-
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; }
-
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 }
-
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; }
-
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.
-
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; }
-
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; }
-
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; }
-
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; }
-