The Badge sample application demonstrates how you can handle application badges using the Badge API. You can create, modify, and delete badges displayed by any of the applications installed on a platform.
The following figure illustrates the application view.
Figure: Badge screen
On the main screen, you can:
- Browse a list of target applications and select a specific application for badge management
All applications that can have a badge attached are displayed.
- Manipulate badges
You can create and remove badges, and update the badge counter of a selected application by altering the badge counter value.
The following figure illustrates the structure of the application user interface and components. EDJE layout scripts are used.
Figure: UI layout and component structure
The application workflow can be divided into 2 logical blocks: startup and application badge update. The following figure illustrates the workflow.
Figure: Application workflow
Prerequisites
To ensure proper application execution, the following privileges must be set:
- http://tizen.org/privilege/packagemanager.info
- http://tizen.org/privilege/notification
Implementation
Type Definitions
The main data structure is used as a container for the View and Model data:
typedef struct appdata { // View module data viewdata_s viewdata; // Model module data modeldata_s modeldata; } appdata_s;
The viewdata_s structure contains references to all the component objects created by the View module:
typedef struct _viewdata { // Main window component object Evas_Object* win; // Conformant component object Evas_Object* conform; // Main window layout object (embedded into the conform component) Evas_Object* layout_main_panel; // Top panel layout object (embedded into the main_panel_badge_update_panel part of the layout_main_panel) Evas_Object* layout_badge_update_panel; // Middle panel layout object (embedded into the main_panel_apps_list_panel part of the layout_main_panel) Evas_Object* layout_available_apps_panel; // Bottom panel layout object (embedded into the main_panel_buttons_panel part of the layout_main_panel) Evas_Object* layout_buttons_panel; // Spinner component object used for badge counter setting Evas_Object* badge_counter_spinner; // Genlist component object used for available applications listing Evas_Object* available_apps_list; // Button component object used to confirm and apply the input data Evas_Object* update_button; } viewdata_s;The modeldata_s contains a list of pkginfo_s items, where each pkginfo_s structure contains information about installed applications:
typedef struct _pkginfo { // Name of the application package char *pkg_name; // Application ID char *app_id; } pkginfo_s; typedef struct _modeldata { // List of pkginfo_s structures Eina_List *pkg_list; } modeldata_s;
Application Initialization
The entire application life-cycle is implemented in a badge.c file:
- The sample uses a common Tizen application structure:
int main(int argc, char *argv[]) { appdata_s ad = {{0,},}; // Declare and initialize variables event_callback.create = app_create; event_callback.terminate = app_terminate; event_callback.pause = app_pause; event_callback.resume = app_resume; event_callback.app_control = app_control; // Assign event handlers ret = ui_app_main(argc, argv, &event_callback, &ad); // Error handling return ret; }
The sample is implemented by using the MVC design pattern. Its initialization is done within the app_create() callback function.
Within the callback, the user interface creation is triggered using the view_base_gui_create() function call, and the application data is initialized with the controller_application_init() function. For more information, see Controller and View.
static bool app_create(void *data) { // Assign variables if (!view_base_gui_create(&ad->viewdata)) { return false; } return controller_application_init(&ad->modeldata); }
-
When the application is terminated, the app_terminate() callback function frees all the allocated resources. For more information, see Controller.
static void app_terminate(void *data) { appdata_s *ad = (appdata_s*)data; if (ad->viewdata.win) { // Delete the main window and all descendants evas_object_del(ad->viewdata.win); } // Free all allocated data controller_application_terminate(&ad->modeldata); }
View
The entire application layout is implemented using EDJE scripts. All top level swallows are designed for EFL Elementary component embedding. The following EDJE swallow - EFL Elementary component relations and assigned functionalities are used (for more information, see the UI layout and component structure figure):
- badge_update_panel_badge_counter_edit - elm_spinner: sets the new value of the badge counter for the selected application.
- apps_list_panel_list - elm_genlist: list of all installed and displayable applications, consisting of the application identifier and the badge counter.
- buttons_panel_button - elm_button: applies all the changes.
The following table defines the code snippets that create the UI layout.
Code snippet | Figure |
---|---|
The main layout is defined in the main.edc file: | |
collections { group { name: GROUP_MAIN; parts { // Background part occupies the entire window part { name: PART_MAIN_BACKGROUND; type: RECT; } // Part is positioned in relation to PART_MAIN_BACKGROUND // Spacer occupies the entire area of PART_MAIN_BACKGROUND // with a small margin all around part { name: PART_MAIN_PANEL; type: SPACER; } // Part is positioned in relation to PART_MAIN_PANEL // Swallow occupies 30% of PART_MAIN_PANEL height // It is designed to hold the layout_badge_update_panel elm_layout part { name: PART_MAIN_PANEL_BADGE_UPDATE_PANEL; type: SWALLOW; } // Part is positioned in relation to PART_MAIN_PANEL // Swallow has flexible height which depends on the height // of other swallows // At this configuration, the swallow occupies 55% of PART_MAIN_PANEL // height // It is designed to hold the layout_available_apps_panel elm_layout part { name: PART_MAIN_PANEL_APPS_LIST_PANEL; type: SWALLOW; } // Part is positioned in relation to PART_MAIN_PANEL // Swallow occupies 15% of PART_MAIN_PANEL height // It is designed to hold the layout_buttons_panel elm_layout part { name: PART_MAIN_PANEL_BUTTON_PANEL; type: SWALLOW; } } } } |
|
The PART_MAIN_PANEL_BADGE_UPDATE_PANEL swallow is used as a container for the update layout defined in the badge-update-panel.edc file: |
|
collections { group { name: GROUP_BADGE_UPDATE_PANEL; parts { // Part is positioned in relation to PART_MAIN_PANEL_BADGE_UPDATE_PANEL // from badge.edc file // rect plays a role of the background for the update panel and // occupies the entire area // of the PART_MAIN_PANEL_BADGE_UPDATE_PANEL part { name: PART_BADGE_UPDATE_PANEL_BACKGROUND; type: RECT; } // Part is positioned in relation to PART_BADGE_UPDATE_PANEL_BACKGROUND // Text part occupies 50% height and 30% width of the // PART_BADGE_UPDATE_PANEL_BACKGROUND // This part is responsible for static text label display only ("App name") part { name: "badge_update_panel_app_name_caption"; type: TEXT; } // Part is positioned in relation to PART_BADGE_UPDATE_PANEL_BACKGROUND // Text part occupies 50% height and 70% width of the // PART_BADGE_UPDATE_PANEL_BACKGROUND // This part is responsible for text display which content is triggered // by programs defined at the end of this file: "selected_app_name_show" // and "selected_app_name_hide" part { name: PART_BADGE_UPDATE_PANEL_APP_NAME; type: TEXT; description { state: STATE_BADGE_UPDATE_PANEL_APP_NAME_DEFAULT 0.0; // State is triggered by the "selected_app_name_show" program } description { state: STATE_BADGE_UPDATE_PANEL_APP_NAME_SELECTED 0.0; // State is triggered by the "selected_app_name_hide" program } } // Part is positioned in relation to PART_BADGE_UPDATE_PANEL_BACKGROUND // Text part occupies 50% height and 40% width of the // PART_BADGE_UPDATE_PANEL_BACKGROUND // This part is responsible for static text label display only ("Badge counter") part { name: "badge_update_panel_badge_counter_caption"; type: TEXT; } // Part is positioned in relation to PART_BADGE_UPDATE_PANEL_BACKGROUND // rect plays a role of a background for the elm_spinner component // Its width is set to 60% of PART_BADGE_UPDATE_PANEL_BACKGROUND width // Height is set to 38% of the PART_PREF_EDIT_PANEL_KEY_PANEL height // and it is vertically centered part { name: PART_BADGE_UPDATE_PANEL_BADGE_COUNTER_BACKGROUND; type: RECT; } // Part is positioned in relation to // PART_BADGE_UPDATE_PANEL_BADGE_COUNTER_BACKGROUND // Swallow occupies entire height of the // PART_BADGE_UPDATE_PANEL_BADGE_COUNTER_BACKGROUND // part and 100% of its width part { name: PART_BADGE_UPDATE_PANEL_BADGE_COUNTER_EDIT; type: SWALLOW; } } // Programs below are used to control the text content of the // PART_BADGE_UPDATE_PANEL_APP_NAME part programs { // "selected_app_name_show" program is triggered by // sending the SIGNAL_BADGE_UPDATE_PANEL_APP_NAME_SHOW // signal to the elm_layout embedded into the layout_badge_update_panel // As a result of the program execution, the text content of the // PART_BADGE_UPDATE_PANEL_APP_NAME is changed to the "Select an application ..." // Text is displayed in red color program { name: "selected_app_name_show"; signal: SIGNAL_BADGE_UPDATE_PANEL_APP_NAME_SHOW; // Part affected source: PART_BADGE_UPDATE_PANEL_APP_NAME; // Part's state to be triggered action: STATE_SET STATE_BADGE_UPDATE_PANEL_APP_NAME_SELECTED 0.0; // Part affected target: PART_BADGE_UPDATE_PANEL_APP_NAME; } // "selected_app_name_hide" program is triggered by // sending the SIGNAL_BADGE_UPDATE_PANEL_APP_NAME_HIDE // signal to the same elm_layout as above. As a result of the program // execution, the text content of the PART_BADGE_UPDATE_PANEL_APP_NAME // is changed to the currently selected application identifier // Text is displayed in green color program { name: "selected_app_name_hide"; signal: SIGNAL_BADGE_UPDATE_PANEL_APP_NAME_HIDE; // Part affected source: PART_BADGE_UPDATE_PANEL_APP_NAME; // Part's state to be triggered action: STATE_SET STATE_BADGE_UPDATE_PANEL_APP_NAME_UNSELECTED 0.0; // Part affected target: PART_BADGE_UPDATE_PANEL_APP_NAME; } } } } |
|
The PART_MAIN_PANEL_APPS_LIST_PANEL swallow is used as a container for the application list layout defined in the apps-list-panel.edc file: |
|
collections { group { name: GROUP_APPS_LIST_PANEL; parts { // Part is positioned in relation to // PART_MAIN_PANEL_APPS_LIST_PANEL from badge.edc file // rect plays a role of the background for the // applications list panel and occupies the entire area of // the PART_MAIN_PANEL_APPS_LIST_PANEL part { name: PART_APPS_LIST_PANEL_BACKGROUND; type: RECT; } // Part is positioned in relation to // PART_APPS_LIST_PANEL_BACKGROUND // Text part occupies 10% height and the entire // width of the PART_APPS_LIST_PANEL_BACKGROUND // This part is responsible for static text label // display only ("Available applications") part { name: "apps_list_panel_available_apps_caption"; type: TEXT; } // Part is positioned in relation to // PART_APPS_LIST_PANEL_BACKGROUND // Swallow occupies 90% height of the // PART_APPS_LIST_PANEL_BACKGROUND part and its entire width part { name: PART_APPS_LIST_PANEL_LIST; type: SWALLOW; } } } } |
|
The PART_MAIN_PANEL_BUTTONS_PANEL swallow is used as a container for the action button layout defined in the buttons-panel.edc file: |
|
collections { group { name: GROUP_BUTTONS_PANEL; parts { // Part is positioned in relation to // PART_MAIN_PANEL_BUTTONS_PANEL from badge.edc file // rect plays a role of the background for the // buttons panel and occupies the entire area of the // PART_MAIN_PANEL_BUTTONS_PANEL part { name: PART_BUTTONS_PANEL_BACKGROUND; type: RECT; } // Part is positioned in relation to // PART_BUTTONS_PANEL_BACKGROUND // Swallow occupies 60% height and 60% width of the // PART_BUTTONS_PANEL_BACKGROUND part // Swallow is horizontally and vertically centered part { name: PART_BUTTONS_PANEL_BUTTON; type: SWALLOW; } } } } |
Based on the layout defined with the EDJE scripts, the application interface is created with the view_base_gui_create() function (see Application Initialization), which takes one parameter - a pointer to the structure containing view data (viewdata_s - see Type Definitions). In succeeding calls to the view_*_panel_create() functions, the user interface is created.
bool view_base_gui_create(viewdata_s *vd) { viewdata = vd; if (!view_main_panel_create(vd) || !view_update_panel_create(vd) || !view_available_apps_panel_create(vd) || !view_buttons_panel_create(vd)) { evas_object_del(vd->win); return false; } evas_object_show(vd->win); return true; }
The following table defines the base view creation details.
Description | Code snippet | Figure |
---|---|---|
view_main_panel_create(): The main window and descendant conformant are created (vd->win and vd->conform respectively) and used as a placeholder for the main layout (vd->layout_main_panel). The main layout is created with the view_layout_create() function by loading the main group from the EDJE layout (badge.edj file). It is embedded into the vd->layout_main_panel container. Finally, the view_layout_back_cb() callback function is attached to the vd->layout_main_panel layout for the back button handling. |
static bool view_main_panel_create(viewdata_s *vd) { vd->win = view_window_create(); // Error handling vd->conform = view_conformant_create(vd->win); // Error handling vd->layout_main_panel = view_layout_create(vd->conform, EDJ_MAIN_FILE_NAME, GROUP_MAIN, NULL); // Error handling eext_object_event_callback_add(vd->layout_main_panel, EEXT_CALLBACK_BACK, view_layout_back_cb, void*)vd); return true; } |
|
view_update_panel_create(): The update subview is created by loading the GROUP_BADGE_UPDATE_PANEL group from the EDJE layout (the badge-update-panel.edc file). It is embedded in the elm_layout container which is then inserted into the PART_MAIN_PANEL_BADGE_UPDATE_PANEL swallow of the vd->layout_main_panel. Finally, the elm_spinner component is created for setting the badge counter value. |
static bool view_update_panel_create(viewdata_s *vd) { vd->layout_badge_update_panel = view_layout_create(vd->layout_main_panel, EDJ_BADGE_UPDATE_PANEL_FILE_NAME, GROUP_BADGE_UPDATE_PANEL, PART_MAIN_PANEL_BADGE_UPDATE_PANEL); // Error handling vd->badge_counter_spinner = view_spinner_create(vd->layout_badge_update_panel); // Error handling return true; } |
|
view_available_apps_panel_create(): The available application subview is created by loading the GROUP_APPS_LIST_PANEL group from the EDJE layout (the apps-list-panel.edc file). It is embedded to the elm_layout container which is then inserted into the PART_MAIN_PANEL_APPS_LIST_PANEL swallow of the vd->layout_main_panel. Once the vd->layout_available_apps_panel layout is ready, the elm_genlist component is created (vd->available_apps_list) for the available application list display. 2 callback functions are assigned to the vd->available_apps_list component:
|
static bool view_available_apps_panel_create(viewdata_s *vd) { vd->layout_available_apps_panel = view_layout_create(vd->layout_main_panel, EDJ_APPS_LIST_PANEL_FILE_NAME, GROUP_APPS_LIST_PANEL, PART_MAIN_PANEL_APPS_LIST_PANEL); // Error handling vd->available_apps_list = view_genlist_create(vd->layout_available_apps_panel, PART_APPS_LIST_PANEL_LIST); // Error handling evas_object_smart_callback_add(vd->available_apps_list, "selected", view_available_apps_item_selected_cb, (void*)vd); evas_object_smart_callback_add(vd->available_apps_list, "unselected", view_available_apps_item_unselected_cb, (void*)vd); return true; } |
|
view_buttons_panel_create(): The action button subview is created by loading the GROUP_BUTTONS_PANEL group from the EDJE layout (the buttons-panel.edc file). It is embedded in the elm_layout container which is then inserted into the PART_MAIN_PANEL_APPS_LIST_PANEL swallow of the vd->layout_main_panel. Once the vd->layout_buttons_panel layout is ready, the elm_button component is created (vd->update_button) for triggering the update action. A callback function which is responsible for introducing the changes to the application is connected to the vd->update_button component. |
static bool view_buttons_panel_create(viewdata_s *vd) { vd->layout_buttons_panel = view_layout_create(vd->layout_main_panel, EDJ_BUTTONS_PANEL_FILE_NAME, GROUP_BUTTONS_PANEL, PART_MAIN_PANEL_BUTTON_PANEL); // Error handling vd->update_button = view_button_create(vd->layout_buttons_panel, PART_BUTTONS_PANEL_BUTTON, "Update", view_badge_update_button_click_cb, (void*)vd); // Error handling return true; } |
Items are added to the elm_genlist component on application initialization using the view_genlist_item_add() function. This function takes only 1 parameter of the pointer to the pkginfo_s structure type (for type specification, see Type Definitions). It contains the application identifier and the related package name, which is further passed to the elm_genlist_item_append() function for display purposes. Finally, the elm_genlist item text content is acquired and displayed with the view_genlist_item_label_get() function.
bool view_genlist_item_add(pkginfo_s *pkginfo) { static Elm_Genlist_Item_Class *itc = NULL; // Error handling if (!itc) { itc = elm_genlist_item_class_new(); // Error handling itc->item_style = "double_label"; itc->func.text_get = view_genlist_item_label_get; // NULL value assignment to unused itc fields } Elm_Object_Item *item = elm_genlist_item_append(viewdata->available_apps_list, itc, (void*)pkginfo, NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL); // Error handling // Data is assigned to the newly created genlist item elm_object_item_data_set(item, (void*)pkginfo); return true; } static char* view_genlist_item_label_get(void *data, Evas_Object *obj, const char *part) { pkginfo_s *pkginfo = (pkginfo_s*)data; // Error handling // 2 text buffers are populated (buff_main and buff_sub) with string content based on the pkginfo: // - buff_main - the application's package name // - buff_sub - the application's badge counter which is obtained with controller_badge_count_get() function if (!strcmp(part, "elm.text")) { return strdup(pkginfo->pkg_name); } else if (!strcmp(part, "elm.text.sub")) { unsigned int badge_count = controller_badge_count_get(pkginfo->app_id); char buff[255] = {0,}; snprintf(buff, sizeof(buff), "Badge count = %u", badge_count); return strdup(buff); } return NULL; }
Each item added to the elm_genlist component supports the selected and unselected actions, which are used to display the selected application package name in the EDJE text container of the vd->layout_badge_update_panel defined in the badge-update-panel.edc file:
The selected action is handled by the view_available_apps_item_selected_cb() callback function:
static void view_available_apps_item_selected_cb(void *data, Evas_Object *obj, void *event_info) { viewdata_s *vd = (viewdata_s*)data; // Get the selected item's reference item_selected = (Elm_Object_Item*)event_info; // Error handling // Get the pkginfo_s data assigned to the selected item pkginfo_s *pkginfo = (pkginfo_s*)elm_object_item_data_get(item_selected); // Error handling // Get the badge counter assigned to the selected application unsigned int badge_count = controller_badge_count_get(pkginfo->app_id); // Obtained badge counter value is set to the vd->badge_counter_spinner component // for future manipulation elm_spinner_value_set(vd->badge_counter_spinner, (double)badge_count); // Selected item is updated elm_genlist_item_update(item_selected); // Send the SIGNAL_BADGE_UPDATE_PANEL_APP_NAME_SHOW signal in order to display // the selected application's package name in the PART_BADGE_UPDATE_PANEL_APP_NAME // part of the vd->layout_badge_update_panel layout with predefined color elm_object_signal_emit(vd->layout_badge_update_panel, SIGNAL_BADGE_UPDATE_PANEL_APP_NAME_SHOW, PART_BADGE_UPDATE_PANEL_APP_NAME); // Application's package name is assigned to the PART_BADGE_UPDATE_PANEL_APP_NAME // part of the viewdata->layout_badge_update_panel layout elm_object_part_text_set(viewdata->layout_badge_update_panel, PART_BADGE_UPDATE_PANEL_APP_NAME, pkginfo->app_id); }
The unselected action is handled by the view_available_apps_item_unselected_cb() callback function:
static void view_available_apps_item_unselected_cb(void *data, Evas_Object *obj, void *event_info) { viewdata_s *vd = (viewdata_s*)data; // Send the SIGNAL_BADGE_UPDATE_PANEL_APP_NAME_HIDE signal in order to display // the default text in the PART_BADGE_UPDATE_PANEL_APP_NAME part of the // vd->layout_badge_update_panel layout with predefined color elm_object_signal_emit(vd->layout_badge_update_panel, SIGNAL_BADGE_UPDATE_PANEL_APP_NAME_HIDE, PART_BADGE_UPDATE_PANEL_APP_NAME); // Default text is assigned to the PART_BADGE_UPDATE_PANEL_APP_NAME // part of the viewdata->layout_badge_update_panel layout elm_object_part_text_set(viewdata->layout_badge_update_panel, PART_BADGE_UPDATE_PANEL_APP_NAME, TEXT_LABEL_BADGE_UPDATE_PANEL_APP_NAME_DEFAULT); // Current selection reference is cleared item_selected = NULL; }
The badge implementation is triggered by the Update button click. The view_badge_update_button_click_cb() callback function, assigned to the Update button, is invoked:
static void view_badge_update_button_click_cb(void *data, Evas_Object *obj, void *event_info) { viewdata_s *vd = (viewdata_s*)data; // Check whether any item was selected. The item_selected variable is declared // statically in global scope. The valid value of item_selected variable // is assigned in view_available_apps_item_selected_cb() callback function. if (!item_selected) { return; } // Get the pkginfo_s data assigned to the selected item pkginfo_s *pkginfo = (pkginfo_s*)elm_object_item_data_get(item_selected); // Error handling // Get the badge counter assigned to the selected application unsigned int curr_badge_count = controller_badge_count_get(pkginfo->app_id); // Get the value of badge counter adjusted via the elm_spinner component int new_badge_count = (int)elm_spinner_value_get(vd->badge_counter_spinner); // If the adjusted badge counter value is equal to the badge counter value // currently assigned to the selected application, nothing happens if (curr_badge_count == new_badge_count) { return; } else // If the adjusted badge counter value is not equal to the badge counter value // currently assigned to the selected application, which is equal to zero, // new badge for the selected application is created if (curr_badge_count == 0) { controller_badge_new(pkginfo->app_id, new_badge_count); } else // If the adjusted badge counter value equals zero and the badge counter // value currently assigned to the selected application is greater then zero, // existing badge is removed if (new_badge_count == 0) { controller_badge_remove(pkginfo->app_id); } else { // Otherwise, the badge counter assigned to the selected application // is updated controller_badge_update(pkginfo->app_id, new_badge_count); } // Selected item is updated elm_genlist_item_update(item_selected); }
Controller
The controller module controls the application processes:
- During the application initialization process, the controller provides the controller_application_init() function. The function acquires the application package list for the badge control using the model_packages_list_get() function, and adds the applications to the list view using the view_genlist_item_add() function. For more information, see Model and View.
bool controller_application_init(modeldata_s *md) { if (!model_packages_list_get(&md->pkg_list)) { return false; } // Declare variables EINA_LIST_FOREACH(md->pkg_list, it, pkginfo) { view_genlist_item_add(pkginfo); } return true; }
While the application is running, the controller provides functions for controlling the badge management process. Each of the following functions requires the application ID to be provided as an input parameter to identify the target application whose badge is to be handled. Additionally, for the badge creation and update functions, the new badge counter value is required.
- controller_badge_count_get()
Obtains the badge number currently pinned to the selected application.
unsigned int controller_badge_count_get(const char *app_id) { // Variable declaration if (!model_badge_count_get(app_id, &badge_count)) { // Query the badge counter value return 0; } // Log message return badge_count; }
- controller_badge_new()
Creates a new badge for the selected application.
bool controller_badge_new(const char *app_id, unsigned int badge_count) { if (!model_badge_add(app_id)) { return false; } if (!model_badge_display_set(app_id, 1)) { // Request badge visibility return false; } // Request the badge counter initialization with provided badge_counter value return model_badge_count_set(app_id, badge_count); }
- controller_badge_remove()
Removes the badge which is already pinned to the selected application.
bool controller_badge_remove(const char *app_id) { if (!model_badge_count_set(app_id, 0)) { // Request to clear the badge counter return false; } if (!model_badge_display_set(app_id, 0)) { // Request the badge invisibility return false; } // Request badge deletion return model_badge_remove(app_id); }
- controller_badge_update()
Updates the badge counter pinned to the selected application.
bool controller_badge_update(const char *app_id, unsigned int badge_count) { bool display = false; if (!model_badge_display_get(app_id, &display)) { // Query the visibility state of the badge return false; } if (!display) { // Only the visible badges are updated return false; } // Request badge counter update return model_badge_count_set(app_id, badge_count); }
- controller_badge_count_get()
During the application termination process, the controller provides the controller_application_terminate() function. The function releases all the previously allocated memory (list of pkginfo_s structures). For more information, see Application Initialization and Model.
void controller_application_terminate(modeldata_s *md) { model_packages_list_free(md->pkg_list); }
Model
The model module deals directly with the application data. It is responsible for:
- Package names and related application identifier acquisition
- Badge creation, counter alteration, and badge removal
To perform the above operations, the Application Manager and Badge API are used:
During the application initialization, the model_packages_list_get() function is used to obtain the list of valid application identifiers and related package names (for more information, see Application Initialization and Controller). The function invokes the app_manager_foreach_app_info() function with the model_app_info_cb() callback passed as a parameter in order to retrieve information about the installed applications. The application and package information is obtained with subsequent calls to the callback function.
bool model_packages_list_get(Eina_List **list) { *list = NULL; int ret = app_manager_foreach_app_info(model_app_info_cb, (void*)list); // Error handling return true; } static bool model_app_info_cb(app_info_h app_info, void *user_data) { Eina_List **list = (Eina_List**)user_data; char *pkg_name = NULL; // Get the application package name int ret = app_info_get_package(app_info, amp;pkg_name); // Error handling bool nodisplay = true; // Get the application display flag ret = app_info_is_nodisplay(app_info, &nodisplay); // Error handling if (nodisplay) // Return, if the application is non-displayable { free(pkg_name); return true; } char *app_id = NULL; // Get the application identifier ret = app_info_get_app_id(app_info, &app_id); // Error handling // If the application is displayable and all the required information is retrieved successfully // (the package name and the application identifier), the pkginfo_s structure is created // and added to the list pkginfo_s *pkginfo = NULL; if (model_info_create(pkg_name, app_id, &pkginfo)) { *list = eina_list_append(*list, (void*)pkginfo); } free(pkg_name); // Continue the foreach loop to retrieve application information return true; }
-
While the application is running, the model module provides a set of wrapper functions for the Badge API. The Controller module calls these functions to:
- Create and remove a badge.
- Get and set the badge display flag.
- Get and set the badge counter.
- Check whether the badge exists.
Each of the following functions require the application ID to be provided as an input parameter. The ID is used to identify the target application whose badge is to be handled. All the functions (except those used for badge creation, removal, and existence check) require an additional parameter for setting or getting a value (display flag or badge counter).
bool model_badge_remove(const char *app_id) { int ret = badge_remove(app_id); // Error handling return true; } bool model_badge_display_get(const char *app_id, bool *display) { unsigned int is_display = 0; // By default, the false value is returned *display = (bool)is_display; int ret = badge_get_display(app_id, &is_display); // Error handling *display = (bool)is_display; return true; } bool model_badge_display_set(const char *app_id, bool display) { unsigned int display_val = 0; if (display) { display_val = 1; } int ret = badge_set_display(app_id, display_val); // Error handling return true; } bool model_badge_count_get(const char *app_id, unsigned int *badge_count) { int ret = badge_get_count(app_id, badge_count); // Error handling return true; } bool model_badge_count_set(const char *app_id, unsigned int badge_count) { int ret = badge_set_count(app_id, badge_count); // Error handling return true; }
During the application termination, the model_packages_list_free() function is used to release the memory allocated in the Application Initialization step. For more information on the controller_application_terminate() function implementation, see Controller.
void model_packages_list_free(Eina_List *list) { // Variable declaration // List consists of pkginfo_s structures; the loop below results in // pkginfo->pkg_name, pkginfo->app_id and pkginfo deallocation EINA_LIST_FOREACH(list, it, pkginfo) { free(pkginfo->pkg_name); free(pkginfo->app_id); free(pkginfo); } list = eina_list_free(list); }