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.
Table: UI layout code snippets and figures
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.
Table: Base view creation code snippets and figures
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:
- view_available_apps_item_selected_cb() for item selected action
- view_available_apps_item_unselected_cb() for item unselected action
|
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);
}
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);
}