Sticker Consumer / src /
main.c
/*
* Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved
*
* Licensed under the Apache License, Version 2.0 (the License);
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "main.h"
typedef struct appdata {
Evas_Object *win;
Evas_Object *conform;
Evas_Object *nf;
sticker_consumer_h sticker_h;
char *sticker_path[STICKER_MAX];
int idx;
} appdata_s;
typedef struct itemdata {
int index;
const char *path;
appdata_s *ad;
} itemdata_s;
typedef enum {
FOREACH_ALL = 0,
FOREACH_BY_KEYWORD,
FOREACH_BY_GROUP,
FOREACH_BY_TYPE
} api_type;
/*
* @brief Function will be operated when window deletion is requested
* @param[in] data The data to be passed to the callback function
* @param[in] obj The Evas object handle to be passed to the callback function
* @param[in] event_info The system event information
*/
static void
win_delete_request_cb(void *data, Evas_Object *obj, void *event_info)
{
ui_app_exit();
}
/*
* @brief Function to get object on gengrid item's swallow part
* @param[in] data The data to be passed to the callback function
* @param[in] obj The Evas object handle to be passed to the callback function
* @param[in] part The name of swallow part
* @param[out] Evas_Object An image to use as genlist item's swallow part
*/
static Evas_Object*
gengrid_content_get_cb(void *data, Evas_Object *obj, const char *part)
{
itemdata_s *id = data;
if (!strcmp(part, "elm.swallow.icon")) {
Evas_Object *img = elm_image_add(obj);
elm_image_file_set(img, id->path, NULL);
elm_image_aspect_fixed_set(img, EINA_FALSE);
elm_image_preload_disabled_set(img, EINA_FALSE);
evas_object_show(img);
return img;
}
return NULL;
}
/*
* @brief Function to retrieve all sticker data
* @param[in] data_handle The sticker data handle
* @param[in] user_data The data to be passed to the callback function
*/
static void
sticker_info_cb(sticker_data_h data_handle, void *user_data)
{
appdata_s *ad = user_data;
int ret;
sticker_data_uri_type_e type;
/* Get sticker URI and URI type */
ret = sticker_data_get_uri(data_handle, &type, &ad->sticker_path[ad->idx]);
/* Check sticker error code */
if (ret != STICKER_ERROR_NONE) {
dlog_print(DLOG_ERROR, LOG_TAG, "Failed to get sticker path");
return;
}
ad->idx++;
}
/*
* @brief Function to retrieve all keywords
* @param[in] keyword The keyword of the sticker
* @param[in] user_data The data to be passed to the callback function
*/
static void
keyword_list_cb(const char *keyword, void *user_data)
{
dlog_print(DLOG_INFO, LOG_TAG, "keyword : %s", keyword);
}
/*
* @brief Function to retrieve all group names
* @param[in] group The group name of the sticker
* @param[in] user_data The data to be passed to the callback function
*/
static void
group_list_cb(const char *group, void *user_data)
{
dlog_print(DLOG_INFO, LOG_TAG, "group name : %s", group);
}
/*
* @brief Function will be called when gengrid is deleted
* @param[in] data The data to be passed to the callback function
* @param[in] obj The Evas object handle to be passed to the callback function
*/
void
gengrid_uri_del(void *data, Evas_Object *obj EINA_UNUSED)
{
itemdata_s *id = data;
eina_stringshare_del(id->path);
free(id);
}
/*
* @brief Function to create gengrid
* @param[in] ad The data structure to manage gui object
* @param[out] Evas_Object The layout object which is created
*/
static Evas_Object*
create_gengrid(appdata_s *ad, api_type type)
{
int ret, result = 0;
Elm_Gengrid_Item_Class *gic;
Evas_Object *gengrid;
int i;
gengrid = elm_gengrid_add(ad->nf);
evas_object_size_hint_weight_set(gengrid, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(gengrid, EVAS_HINT_FILL, EVAS_HINT_EXPAND);
elm_gengrid_item_size_set(gengrid, ELM_SCALE_SIZE(110), ELM_SCALE_SIZE(110));
elm_gengrid_align_set(gengrid, 0.5, 0.1);
gic = elm_gengrid_item_class_new();
gic->item_style = "default";
gic->func.text_get = NULL;
gic->func.content_get = gengrid_content_get_cb;
gic->func.state_get = NULL;
gic->func.del = gengrid_uri_del;
ad->idx = 0;
switch (type) {
case FOREACH_ALL:
/* Retrieve all sticker data */
ret = sticker_consumer_data_foreach_all(ad->sticker_h, 0, STICKER_MAX, &result, sticker_info_cb, ad);
/* Check sticker error code */
if (ret != STICKER_ERROR_NONE)
dlog_print(DLOG_ERROR, LOG_TAG, "Failed to call sticker_consumer_data_foreach_all()");
break;
case FOREACH_BY_KEYWORD:
/* Retrieve all keywords */
ret = sticker_consumer_keyword_list_foreach_all(ad->sticker_h, keyword_list_cb, NULL);
/* Check sticker error code */
if (ret != STICKER_ERROR_NONE)
dlog_print(DLOG_ERROR, LOG_TAG, "Failed to call sticker_consumer_keyword_list_foreach_all()");
/* Retrieve all sticker data by keyword */
ret = sticker_consumer_data_foreach_by_keyword(ad->sticker_h, 0, STICKER_MAX, &result, "face", sticker_info_cb, ad);
/* Check sticker error code */
if (ret != STICKER_ERROR_NONE)
dlog_print(DLOG_ERROR, LOG_TAG, "Failed to call sticker_consumer_data_foreach_by_keyword()");
break;
case FOREACH_BY_GROUP:
/* Retrieve all group names */
ret = sticker_consumer_group_list_foreach_all(ad->sticker_h, group_list_cb, NULL);
/* Check sticker error code */
if (ret != STICKER_ERROR_NONE)
dlog_print(DLOG_ERROR, LOG_TAG, "Failed to call sticker_consumer_group_list_foreach_all()");
/* Retrieve all sticker data by group name */
ret = sticker_consumer_data_foreach_by_group(ad->sticker_h, 0, STICKER_MAX, &result, "animal", sticker_info_cb, ad);
/* Check sticker error code */
if (ret != STICKER_ERROR_NONE)
dlog_print(DLOG_ERROR, LOG_TAG, "Failed to call sticker_consumer_data_foreach_by_group()");
break;
case FOREACH_BY_TYPE:
/* Retrieve all sticker data by URI type */
ret = sticker_consumer_data_foreach_by_type(ad->sticker_h, 0, STICKER_MAX, &result, STICKER_DATA_URI_LOCAL_PATH, sticker_info_cb, ad);
/* Check sticker error code */
if (ret != STICKER_ERROR_NONE)
dlog_print(DLOG_ERROR, LOG_TAG, "Failed to call sticker_consumer_data_foreach_by_type()");
break;
default:
break;
}
for (i = 0; i < result; i++) {
itemdata_s *id = calloc(sizeof(itemdata_s), 1);
id->index = i;
id->path = eina_stringshare_add(ad->sticker_path[i]);
id->ad = ad;
elm_gengrid_item_append(gengrid, gic, id, NULL, NULL);
}
evas_object_show(gengrid);
return gengrid;
}
/*
* @brief Function to create sticker image view layout
* @param[in] ad The data structure to manage gui object
* @param[out] Evas_Object The layout object which is created
*/
static Evas_Object *
create_sticker_view(appdata_s *ad, char *subject, api_type type)
{
Elm_Object_Item *nf_it;
Evas_Object *gengrid;
gengrid = create_gengrid(ad, type);
nf_it = elm_naviframe_item_push(ad->nf, subject, NULL, NULL, gengrid, NULL);
return gengrid;
}
/*
* @brief Function will be called when "Retrieves all sticker data" item is selected
* @param[in] data The data to be passed to the callback function
* @param[in] obj The Evas object handle to be passed to the callback function
* @param[in] event_info The system event information
*/
void
foreach_all_cb(void *data, Evas_Object *obj, void *event_info)
{
appdata_s *ad = (appdata_s *)data;
Evas_Object *sticker_view;
sticker_view = create_sticker_view(ad, "Retrieves all sticker data", FOREACH_ALL);
}
/*
* @brief Function will be called when "Retrieves sticker data using keyword" item is selected
* @param[in] data The data to be passed to the callback function
* @param[in] obj The Evas object handle to be passed to the callback function
* @param[in] event_info The system event information
*/
void
foreach_by_keyword_cb(void *data, Evas_Object *obj, void *event_info)
{
appdata_s *ad = (appdata_s *)data;
Evas_Object *sticker_view;
sticker_view = create_sticker_view(ad, "Retrieves sticker data using keyword", FOREACH_BY_KEYWORD);
}
/*
* @brief Function will be called when "Retrieves sticker data using group" item is selected
* @param[in] data The data to be passed to the callback function
* @param[in] obj The Evas object handle to be passed to the callback function
* @param[in] event_info The system event information
*/
void
foreach_by_group_cb(void *data, Evas_Object *obj, void *event_info)
{
appdata_s *ad = (appdata_s *)data;
Evas_Object *sticker_view;
sticker_view = create_sticker_view(ad, "Retrieves sticker data using group", FOREACH_BY_GROUP);
}
/*
* @brief Function will be called when "Retrieves sticker data using URI type" item is selected
* @param[in] data The data to be passed to the callback function
* @param[in] obj The Evas object handle to be passed to the callback function
* @param[in] event_info The system event information
*/
void
foreach_by_type_cb(void *data, Evas_Object *obj, void *event_info)
{
appdata_s *ad = (appdata_s *)data;
Evas_Object *sticker_view;
sticker_view = create_sticker_view(ad, "Retrieves sticker data using URI type", FOREACH_BY_TYPE);
}
/*
* @brief Function will be called when list item is selected
* @param[in] data The data to be passed to the callback function
* @param[in] obj The Evas object handle to be passed to the callback function
* @param[in] event_info The system event information
*/
static void
list_selected_cb(void *data, Evas_Object *obj, void *event_info)
{
Elm_Object_Item *it = event_info;
elm_list_item_selected_set(it, EINA_FALSE);
}
/*
* @brief Function to create main view layout
* @param[in] ad The data structure to manage gui object
* @param[out] Evas_Object The layout object which is created
*/
static Evas_Object *
create_main_list(appdata_s *ad)
{
Evas_Object *list;
/* List */
list = elm_list_add(ad->nf);
elm_list_mode_set(list, ELM_LIST_COMPRESS);
evas_object_smart_callback_add(list, "selected", list_selected_cb, NULL);
/* Main Menu Items Here */
elm_list_item_append(list, "Retrieves all sticker data", NULL, NULL, foreach_all_cb, ad);
elm_list_item_append(list, "Retrieves sticker data using keyword", NULL, NULL, foreach_by_keyword_cb, ad);
elm_list_item_append(list, "Retrieves sticker data using group", NULL, NULL, foreach_by_group_cb, ad);
elm_list_item_append(list, "Retrieves sticker data using URI type", NULL, NULL, foreach_by_type_cb, ad);
elm_list_go(list);
return list;
}
/*
* @brief Function will be operated when naviframe pop its own item
* @param[in] data The data to be passed to the callback function
* @param[in] it The item to be popped from naviframe
*/
static Eina_Bool
naviframe_pop_cb(void *data, Elm_Object_Item *it)
{
appdata_s *ad = data;
/* Let window go to hide state. */
elm_win_lower(ad->win);
return EINA_FALSE;
}
/*
* @brief Function to create base gui structure
* @param[in] ad The data structure to manage gui object
*/
static void
create_base_gui(appdata_s *ad)
{
Evas_Object *main_list;
Elm_Object_Item *nf_it;
/* Window */
/* Create and initialize elm_win.
elm_win is mandatory to manipulate window. */
ad->win = elm_win_util_standard_add(PACKAGE, PACKAGE);
elm_win_conformant_set(ad->win, EINA_TRUE);
elm_win_autodel_set(ad->win, EINA_TRUE);
if (elm_win_wm_rotation_supported_get(ad->win)) {
int rots[4] = { 0, 90, 180, 270 };
elm_win_wm_rotation_available_rotations_set(ad->win, (const int *)(&rots), 4);
}
evas_object_smart_callback_add(ad->win, "delete,request", win_delete_request_cb, NULL);
/* Conformant */
/* Create and initialize elm_conformant.
elm_conformant is mandatory for base gui to have proper size
when indicator or virtual keypad is visible. */
ad->conform = elm_conformant_add(ad->win);
elm_win_indicator_mode_set(ad->win, ELM_WIN_INDICATOR_SHOW);
evas_object_size_hint_weight_set(ad->conform, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
elm_win_resize_object_add(ad->win, ad->conform);
evas_object_show(ad->conform);
/* Naviframe */
ad->nf = elm_naviframe_add(ad->conform);
eext_object_event_callback_add(ad->nf, EEXT_CALLBACK_BACK, eext_naviframe_back_cb, ad);
evas_object_size_hint_weight_set(ad->nf, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
elm_object_content_set(ad->conform, ad->nf);
evas_object_show(ad->nf);
/* Main list */
main_list = create_main_list(ad);
nf_it = elm_naviframe_item_push(ad->nf, "Sticker Consumer Sample", NULL, NULL, main_list, NULL);
elm_naviframe_item_pop_cb_set(nf_it, naviframe_pop_cb, ad);
/* Show window after base gui is set up */
evas_object_show(ad->win);
}
/*
* @brief Hook to take necessary actions before main event loop starts
* Initialize UI resources and application's data
* If this function return true, the main loop of application starts
* If this function return false, the application is terminated
* @param[in] user_data The data to be passed to the callback function
*/
static bool
app_create(void *data)
{
appdata_s *ad = data;
elm_app_base_scale_set(1.8);
create_base_gui(ad);
return true;
}
/*
* @brief Function will be called when permission is selected
* @param[in] cause The value representing a reason why this callback has been called
* @param[in] result The result of a response triggered by calling ppm_request_permission()
* @param[in] privilege The privilege that has been checked
* @param[in] user_data The data to be passed to the callback function
*/
void ppm_popup_response_cb(ppm_call_cause_e cause, ppm_request_result_e result, const char *privilege, void *user_data)
{
if (cause == PRIVACY_PRIVILEGE_MANAGER_CALL_CAUSE_ERROR) {
dlog_print(DLOG_ERROR, LOG_TAG, "Failed to get ppm_request_result");
return;
}
appdata_s *ad = user_data;
switch (result) {
case PRIVACY_PRIVILEGE_MANAGER_REQUEST_RESULT_ALLOW_FOREVER:
if (ad->sticker_h == NULL) {
/* Create sticker consumer handle */
int ret = sticker_consumer_create(&ad->sticker_h);
/* Check sticker error code*/
if (ret != STICKER_ERROR_NONE)
dlog_print(DLOG_ERROR, LOG_TAG, "Failed to create sticker consumer handle");
}
break;
case PRIVACY_PRIVILEGE_MANAGER_REQUEST_RESULT_DENY_FOREVER:
dlog_print(DLOG_INFO, LOG_TAG, "PRIVACY_PRIVILEGE_MANAGER_REQUEST_RESULT_DENY_FOREVER");
notification_status_message_post("The mediastorage privilege is required to use the Sticker Consumer");
ui_app_exit();
break;
case PRIVACY_PRIVILEGE_MANAGER_REQUEST_RESULT_DENY_ONCE:
dlog_print(DLOG_INFO, LOG_TAG, "PRIVACY_PRIVILEGE_MANAGER_REQUEST_RESULT_DENY_ONCE");
notification_status_message_post("The mediastorage privilege is required to use the Sticker Consumer");
ui_app_exit();
break;
default:
break;
}
}
/*
* @brief Checks if the Sticker Consumer has privilege
* @param[in] ad The data structure to manage gui object
* @param[in] privilege The privilege that is to be checked
*/
void check_privilege(appdata_s *ad, const char* privilege)
{
ppm_check_result_e result;
/* Checks if an application, which calls this function, has permission to use the given privilege */
int ret = ppm_check_permission(privilege, &result);
/* If there is an error, print log */
if (ret != PRIVACY_PRIVILEGE_MANAGER_ERROR_NONE) {
dlog_print(DLOG_ERROR, LOG_TAG, "Failed to call ppm_check_permission()");
return;
}
/* Allow, deny or ask */
switch (result) {
case PRIVACY_PRIVILEGE_MANAGER_CHECK_RESULT_ALLOW:
dlog_print(DLOG_INFO, LOG_TAG, "An application has permission to use the %s privilege", privilege);
if (ad->sticker_h == NULL) {
/* Create sticker consumer handle */
int ret = sticker_consumer_create(&ad->sticker_h);
/* Check sticker error code*/
if (ret != STICKER_ERROR_NONE)
dlog_print(DLOG_ERROR, LOG_TAG, "Failed to create sticker consumer handle");
}
break;
case PRIVACY_PRIVILEGE_MANAGER_CHECK_RESULT_DENY:
notification_status_message_post("Sticker Consumer doesn't have permission to use the mediastorage privilege");
ui_app_exit();
break;
case PRIVACY_PRIVILEGE_MANAGER_CHECK_RESULT_ASK:
dlog_print(DLOG_INFO, LOG_TAG, "Ask to user whether to grant permission to use the %s privilege", privilege);
/* Requests a user's response to obtain permission for using the given privilege */
int ret_popup = ppm_request_permission(privilege, ppm_popup_response_cb, ad);
if (ret_popup != PRIVACY_PRIVILEGE_MANAGER_ERROR_NONE) {
dlog_print(DLOG_ERROR, LOG_TAG, "Failed to call ppm_request_permission()");
return;
}
break;
default:
dlog_print(DLOG_ERROR, LOG_TAG, "Unknown result (%d) for the %s privilege", result, privilege);
break;
}
}
/*
* @brief This callback function is called when another application
* sends the launch request to the application
* @param[in] app_control The handle to the app_control
* @param[in] user_data The data to be passed to the callback function
*/
static void
app_control(app_control_h app_control, void *data)
{
/* Handle the launch request. */
}
/*
* @brief This callback function is called each time
* the application is completely obscured by another application
* and becomes invisible to the user
* @param[in] user_data The data to be passed to the callback function
*/
static void
app_pause(void *data)
{
/* Take necessary actions when application becomes invisible. */
}
/*
* @brief This callback function is called each time
* the application becomes visible to the user
* @param[in] user_data The data to be passed to the callback function
*/
static void
app_resume(void *data)
{
/* Take necessary actions when application becomes visible. */
const char* sticker_privilege = "http://tizen.org/privilege/mediastorage";
check_privilege(data, sticker_privilege);
}
/*
* @brief This callback function is called once after the main loop of the application exits
* @param[in] user_data The data to be passed to the callback function
*/
static void
app_terminate(void *data)
{
appdata_s *ad = data;
/* Release all resources. */
if (ad->sticker_h != NULL) {
/* Destroy sticker consumer handle */
int ret = sticker_consumer_destroy(ad->sticker_h);
/* Check sticker error code */
if (ret != STICKER_ERROR_NONE)
dlog_print(DLOG_ERROR, LOG_TAG, "Failed to destroy sticker consumer handle");
}
}
/*
* @brief This function will be called when the language is changed
* @param[in] event_info The system event information
* @param[in] user_data The user data to be passed to the callback function
*/
static void
ui_app_lang_changed(app_event_info_h event_info, void *user_data)
{
/*APP_EVENT_LANGUAGE_CHANGED*/
int ret;
char *language;
/* Get locale */
ret = app_event_get_language(event_info, &language);
if (ret != APP_ERROR_NONE) {
dlog_print(DLOG_ERROR, LOG_TAG, "app_event_get_language() failed. Err = %d.", ret);
return;
}
if (language != NULL) {
elm_language_set(language);
free(language);
}
}
/*
* @brief This function will be called when the orientation is changed
* @param[in] event_info The system event information
* @param[in] user_data The user data to be passed to the callback function
*/
static void
ui_app_orient_changed(app_event_info_h event_info, void *user_data)
{
/*APP_EVENT_DEVICE_ORIENTATION_CHANGED*/
return;
}
/*
* @brief This function will be called when the region is changed
* @param[in] event_info The system event information
* @param[in] user_data The user data to be passed to the callback function
*/
static void
ui_app_region_changed(app_event_info_h event_info, void *user_data)
{
/*APP_EVENT_REGION_FORMAT_CHANGED*/
}
/*
* @brief This function will be called when the battery is low
* @param[in] event_info The system event information
* @param[in] user_data The user data to be passed to the callback function
*/
static void
ui_app_low_battery(app_event_info_h event_info, void *user_data)
{
/*APP_EVENT_LOW_BATTERY*/
}
/*
* @brief This function will be called when the memory is low
* @param[in] event_info The system event information
* @param[in] user_data The user data to be passed to the callback function
*/
static void
ui_app_low_memory(app_event_info_h event_info, void *user_data)
{
/*APP_EVENT_LOW_MEMORY*/
}
/*
* @brief Main function of the application
* @param[in] argc The argument count
* @param[in] argv The argument vector
*/
int
main(int argc, char *argv[])
{
appdata_s ad = {0,};
int ret = 0;
ui_app_lifecycle_callback_s event_callback = {0,};
app_event_handler_h handlers[5] = {NULL, };
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;
/* Register for low battery event handler */
ui_app_add_event_handler(&handlers[APP_EVENT_LOW_BATTERY], APP_EVENT_LOW_BATTERY, ui_app_low_battery, &ad);
/* Register for low memory event handler */
ui_app_add_event_handler(&handlers[APP_EVENT_LOW_MEMORY], APP_EVENT_LOW_MEMORY, ui_app_low_memory, &ad);
/* Register for device operation changed event handler */
ui_app_add_event_handler(&handlers[APP_EVENT_DEVICE_ORIENTATION_CHANGED], APP_EVENT_DEVICE_ORIENTATION_CHANGED, ui_app_orient_changed, &ad);
/* Register for language changed event handler */
ui_app_add_event_handler(&handlers[APP_EVENT_LANGUAGE_CHANGED], APP_EVENT_LANGUAGE_CHANGED, ui_app_lang_changed, &ad);
/* Register for region format changed event handler */
ui_app_add_event_handler(&handlers[APP_EVENT_REGION_FORMAT_CHANGED], APP_EVENT_REGION_FORMAT_CHANGED, ui_app_region_changed, &ad);
ret = ui_app_main(argc, argv, &event_callback, &ad);
if (ret != APP_ERROR_NONE)
dlog_print(DLOG_ERROR, LOG_TAG, "app_main() is failed. err = %d", ret);
return ret;
}