diff options
author | Jiwoong Im <jiwoong.im@samsung.com> | 2014-12-31 10:46:02 +0900 |
---|---|---|
committer | Jiwoong Im <jiwoong.im@samsung.com> | 2015-01-02 16:51:06 +0900 |
commit | f423981be4c564fec1d279803cd874e22706574a (patch) | |
tree | 38b8da8ea74989dfeb9dfa67953af58173821919 | |
parent | e30036bce3773d3f647a35bc924d01e17da42962 (diff) | |
download | appcore-agent-f423981be4c564fec1d279803cd874e22706574a.tar.gz appcore-agent-f423981be4c564fec1d279803cd874e22706574a.tar.bz2 appcore-agent-f423981be4c564fec1d279803cd874e22706574a.zip |
Add new api for system event handling from tizen_2.3submit/tizen_wearable/20150121.020025submit/tizen_tv/20150121.020041submit/tizen_mobile/20150121.020049submit/tizen_common/20150226.010729submit/tizen/20150120.043506accepted/tizen/wearable/20150121.044747accepted/tizen/tv/20150121.044514accepted/tizen/mobile/20150121.045014
Remove system event callbacks except service application lifecycle.
The system event callbacks can be registered using service_app_add_event_handler().
Multiple system event callbacks can be registered.
Change-Id: Ie76dba858f41939c97c0ddd901e8b745bdb08b1d
Signed-off-by: Jiwoong Im <jiwoong.im@samsung.com>
-rw-r--r-- | CMakeLists.txt | 2 | ||||
-rwxr-xr-x | include/appcore-agent.h | 2 | ||||
-rwxr-xr-x | include/service_app.h | 79 | ||||
-rw-r--r-- | packaging/appcore-agent.spec | 2 | ||||
-rwxr-xr-x | src/appcore-agent.c | 47 | ||||
-rwxr-xr-x | src/service_app_main.c | 166 |
6 files changed, 213 insertions, 85 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 96433bf..3816369 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,7 +31,7 @@ SET(HEADERS_agent appcore-agent.h INCLUDE(FindPkgConfig) #pkg_check_modules(pkg_agent REQUIRED pmapi vconf sensor aul rua dlog x11) -pkg_check_modules(pkg_agent REQUIRED aul dlog sysman capi-appfw-application vconf) +pkg_check_modules(pkg_agent REQUIRED aul dlog sysman capi-appfw-application vconf ecore) FOREACH(flag ${pkg_agent_CFLAGS}) SET(EXTRA_CFLAGS_agent "${EXTRA_CFLAGS_agent} ${flag}") ENDFOREACH(flag) diff --git a/include/appcore-agent.h b/include/appcore-agent.h index e1c6080..59c1ce0 100755 --- a/include/appcore-agent.h +++ b/include/appcore-agent.h @@ -60,7 +60,7 @@ int appcore_agent_main(int argc, char **argv, struct agentcore_ops *ops); int appcore_agent_terminate(); int appcore_agent_set_event_callback(enum appcore_agent_event event, - int (*cb) (void *), void *data); + int (*cb) (void *, void *), void *data); #ifdef __cplusplus } diff --git a/include/service_app.h b/include/service_app.h index 2f3098c..7e2a829 100755 --- a/include/service_app.h +++ b/include/service_app.h @@ -20,6 +20,7 @@ #include <tizen.h> #include <app_service.h> +#include <app.h> #ifdef __cplusplus @@ -101,55 +102,85 @@ typedef void (*service_app_low_battery_cb) (void *user_data); /** - * @brief The structure type to contain the set of callback functions for handling application events. + * @brief The structure type containing the set of callback functions for handling application events. * @details It is one of the input parameters of the service_app_efl_main() function. * * @see service_app_main() * @see service_app_create_cb() * @see service_app_terminate_cb() * @see service_app_service_cb() - * @see service_app_low_memory_cb() - * @see service_app_low_battery_cb() */ typedef struct { service_app_create_cb create; /**< This callback function is called at the start of the application. */ - service_app_terminate_cb terminate; /**< This callback function is called once after the main loop of application exits. */ - service_app_service_cb service; /**< This callback function is called when other application send the launch request to the application. */ - service_app_low_memory_cb low_memory; /**< The registered callback function is called when the system runs low on memory. */ - service_app_low_battery_cb low_battery; /**< The registered callback function is called when battery is low. */ -} service_app_event_callback_s; + service_app_terminate_cb terminate; /**< This callback function is called once after the main loop of the application exits. */ + service_app_service_cb service; /**< This callback function is called when another application sends the launch request to the application. */ +} service_app_lifecycle_callback_s; /** - * @brief Runs the main loop of application until service_app_exit() is called + * @brief Adds the system event handler * - * @param [in] argc The argument count - * @param [in] argv The argument vector - * @param [in] callback The set of callback functions to handle application events - * @param [in] user_data The user data to be passed to the callback functions + * @param[out] handler The event handler + * @param[in] event_type The system event type + * @param[in] callback The callback function + * @param[in] user_data The user data to be passed to the callback function * - * @return 0 on success, otherwise a negative error value. - * @retval #SERVICE_APP_ERROR_NONE Successful - * @retval #SERVICE_APP_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #SERVICE_APP_ERROR_INVALID_CONTEXT The application is illegally launched, not launched by the launch system. - * @retval #SERVICE_APP_ERROR_ALREADY_RUNNING The main loop already starts + * @return 0 on success, otherwise a negative error value + * @retval #APP_ERROR_NONE Successfull + * @retval #APP_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #APP_ERROR_OUT_OF_MEMORY Out of memory + * + * @see app_event_type_e + * @see app_event_cb + * @see service_app_remove_event_handler + */ +int service_app_add_event_handler(app_event_handler_h *handler, app_event_type_e event_type, app_event_cb callback, void *user_data); + + +/** + * @brief Removes registered event handler + * + * @param[in] event_handler The event handler + * + * @return 0 on success, otherwise a negative error value + * @retval #APP_ERROR_NONE Successfull + * @retval #APP_ERROR_INVALID_PARAMETER Invalid parameter + * + * @see service_app_add_event_handler + */ +int service_app_remove_event_handler(app_event_handler_h event_handler); + + +/** + * @brief Runs the main loop of the application until service_app_exit() is called. + * + * @param[in] argc The argument count + * @param[in] argv The argument vector + * @param[in] callback The set of callback functions to handle application events + * @param[in] user_data The user data to be passed to the callback functions + * + * @return @c 0 on success, + * otherwise a negative error value. + * @retval #APP_ERROR_NONE Successful + * @retval #APP_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #APP_ERROR_INVALID_CONTEXT The application is illegally launched, not launched by the launch system. + * @retval #APP_ERROR_ALREADY_RUNNING The main loop has already started * * @see service_app_create_cb() * @see service_app_terminate_cb() * @see service_app_service_cb() - * @see service_app_low_memory_cb() - * @see service_app_low_battery_cb() * @see service_app_exit() - * @see #service_app_event_callback_s + * @see #service_app_lifecycle_callback_s */ -int service_app_main(int argc, char **argv, service_app_event_callback_s *callback, void *user_data); +int service_app_main(int argc, char **argv, service_app_lifecycle_callback_s *callback, void *user_data); /** - * @brief Exits the main loop of application. + * @brief Exits the main loop of the application. + * + * @details The main loop of the application stops and service_app_terminate_cb() is invoked. * - * @details The main loop of application stops and service_app_terminate_cb() is invoked * @see service_app_main() * @see service_app_terminate_cb() */ diff --git a/packaging/appcore-agent.spec b/packaging/appcore-agent.spec index 88f724b..95a4955 100644 --- a/packaging/appcore-agent.spec +++ b/packaging/appcore-agent.spec @@ -11,7 +11,7 @@ BuildRequires: sysman-devel BuildRequires: pkgconfig(aul) BuildRequires: pkgconfig(capi-appfw-application) BuildRequires: pkgconfig(dlog) -BuildRequires: pkgconfig(glib-2.0) +BuildRequires: pkgconfig(ecore) BuildRequires: pkgconfig(pmapi) BuildRequires: pkgconfig(sysman) BuildRequires: pkgconfig(vconf) diff --git a/src/appcore-agent.c b/src/appcore-agent.c index 303cfb5..e787d14 100755 --- a/src/appcore-agent.c +++ b/src/appcore-agent.c @@ -27,7 +27,7 @@ #include <stdlib.h> #include <sys/types.h> #include <unistd.h> -#include <glib.h> +#include <Ecore.h> #include <sysman.h> #include "aul.h" @@ -153,14 +153,14 @@ static struct agent_priv priv; struct agent_ops { void *data; - void (*cb_app)(int, void *, bundle *); + void (*cb_app)(enum agent_event, void *, bundle *); }; /** * Appcore system event operation */ struct sys_op { - int (*func) (void *); + int (*func) (void *, void *); void *data; }; @@ -173,7 +173,6 @@ struct agent_appcore { static struct agent_appcore core; -GMainLoop *mainloop; extern int service_create_request(bundle *data, service_h *service); static int __sys_lowmem_post(void *data, void *evt); @@ -195,6 +194,12 @@ static struct evt_ops evtops[] = { } }; + +static void __exit_loop(void *data) +{ + ecore_main_loop_quit(); +} + static void __do_app(enum agent_event event, void *data, bundle * b) { int r = 0; @@ -205,7 +210,7 @@ static void __do_app(enum agent_event event, void *data, bundle * b) if (event == AGE_TERMINATE) { svc->state = AGS_DYING; - g_main_loop_quit(mainloop); + ecore_main_loop_thread_safe_call_sync((Ecore_Data_Cb)__exit_loop, NULL); return; } @@ -278,7 +283,7 @@ static int __agent_terminate(void *data) return 0; } -static int __sys_do_default(struct appcore *ac, enum sys_event event) +static int __sys_do_default(struct agent_appcore *ac, enum sys_event event) { int r; @@ -295,7 +300,7 @@ static int __sys_do_default(struct appcore *ac, enum sys_event event) return r; } -static int __sys_do(struct agent_appcore *ac, enum sys_event event) +static int __sys_do(struct agent_appcore *ac, void *event_info, enum sys_event event) { struct sys_op *op; @@ -306,7 +311,7 @@ static int __sys_do(struct agent_appcore *ac, enum sys_event event) if (op->func == NULL) return __sys_do_default(ac, event); - return op->func(op->data); + return op->func(event_info, op->data); } static int __sys_lowmem_post(void *data, void *evt) @@ -322,7 +327,15 @@ static int __sys_lowmem_post(void *data, void *evt) static int __sys_lowmem(void *data, void *evt) { - return __sys_do(data, SE_LOWMEM); + keynode_t *key = evt; + int val; + + val = vconf_keynode_get_int(key); + + if (val >= VCONFKEY_SYSMAN_LOW_MEMORY_SOFT_WARNING) + return __sys_do(data, (void *)&val, SE_LOWMEM); + + return 0; } static int __sys_lowbatt(void *data, void *evt) @@ -334,7 +347,7 @@ static int __sys_lowbatt(void *data, void *evt) /* VCONFKEY_SYSMAN_BAT_CRITICAL_LOW or VCONFKEY_SYSMAN_POWER_OFF */ if (val <= VCONFKEY_SYSMAN_BAT_CRITICAL_LOW) - return __sys_do(data, SE_LOWBAT); + return __sys_do(data, (void *)&val, SE_LOWBAT); return 0; } @@ -447,7 +460,7 @@ static int __aul_handler(aul_type type, bundle *b, void *data) } EXPORT_API int appcore_agent_set_event_callback(enum appcore_agent_event event, - int (*cb) (void *), void *data) + int (*cb) (void *, void *), void *data) { struct agent_appcore *ac = &core; struct sys_op *op; @@ -517,12 +530,12 @@ static int __before_loop(struct agent_priv *agent, int argc, char **argv) { int r; - if (argc == NULL || argv == NULL) { + if (argc <= 0 || argv == NULL) { errno = EINVAL; return -1; } - g_type_init(); + ecore_init(); r = appcore_agent_init(&s_ops, argc, argv); _retv_if(r == -1, -1); @@ -546,12 +559,13 @@ static void __after_loop(struct agent_priv *agent) priv.state = AGS_DYING; if (agent->ops && agent->ops->terminate) agent->ops->terminate(agent->ops->data); + ecore_shutdown(); } EXPORT_API int appcore_agent_terminate() { - g_main_loop_quit(mainloop); + ecore_main_loop_thread_safe_call_sync((Ecore_Data_Cb)__exit_loop, NULL); return 0; } @@ -570,10 +584,9 @@ EXPORT_API int appcore_agent_main(int argc, char **argv, return -1; } - mainloop = g_main_loop_new(NULL, FALSE); - - g_main_loop_run(mainloop); + ecore_main_loop_begin(); + aul_status_update(STATUS_DYING); __after_loop(&priv); diff --git a/src/service_app_main.c b/src/service_app_main.c index 08dd4e0..34ea510 100755 --- a/src/service_app_main.c +++ b/src/service_app_main.c @@ -26,6 +26,7 @@ #include <bundle.h> #include <aul.h> #include <dlog.h> +#include <Eina.h> #include <appcore-agent.h> #include <service_app_private.h> @@ -35,6 +36,19 @@ #endif #define LOG_TAG "TIZEN_N_AGENT" +#define SERVICE_APP_EVENT_MAX 2 + +struct app_event_handler { + app_event_type_e type; + app_event_cb cb; + void *data; +}; + +struct app_event_info { + app_event_type_e type; + void *value; +}; + typedef enum { SERVICE_APP_STATE_NOT_RUNNING, // The application has been launched or was running but was terminated @@ -46,7 +60,7 @@ typedef struct { char *package; char *service_app_name; service_app_state_e state; - service_app_event_callback_s *callback; + service_app_lifecycle_callback_s *callback; void *data; } service_app_context_s; @@ -55,14 +69,29 @@ typedef service_app_context_s *service_app_context_h; static int service_app_create(void *data); static int service_app_terminate(void *data); static int service_app_reset(service_h service, void *data); -static int service_app_low_memory(void *data); -static int service_app_low_battery(void *data); +static int service_app_low_memory(void *event_info, void *data); +static int service_app_low_battery(void *event_info, void *data); static void service_app_set_appcore_event_cb(service_app_context_h service_app_context); static void service_app_unset_appcore_event_cb(void); +static Eina_List *handler_list[SERVICE_APP_EVENT_MAX] = {NULL, }; +static int _initialized = 0; -EXPORT_API int service_app_main(int argc, char **argv, service_app_event_callback_s *callback, void *user_data) +static void _free_handler_list(void) +{ + int i; + app_event_handler_h handler; + + for (i = 0; i < SERVICE_APP_EVENT_MAX; i++) { + EINA_LIST_FREE(handler_list[i], handler) + free(handler); + } + + eina_shutdown(); +} + +EXPORT_API int service_app_main(int argc, char **argv, service_app_lifecycle_callback_s *callback, void *user_data) { service_app_context_s service_app_context = { .state = SERVICE_APP_STATE_NOT_RUNNING, @@ -77,7 +106,7 @@ EXPORT_API int service_app_main(int argc, char **argv, service_app_event_callbac .service = service_app_reset, }; - if (argc == NULL || argv == NULL || callback == NULL) + if (argc <= 0 || argv == NULL || callback == NULL) { return service_app_error(SERVICE_APP_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); } @@ -105,12 +134,75 @@ EXPORT_API void service_app_exit(void) appcore_agent_terminate(); } +EXPORT_API int service_app_add_event_handler(app_event_handler_h *event_handler, app_event_type_e event_type, app_event_cb callback, void *user_data) +{ + app_event_handler_h handler; + Eina_List *l_itr; + + if (!_initialized) { + eina_init(); + _initialized = 1; + } + + if (event_handler == NULL || callback == NULL) + return service_app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + + if (event_type < APP_EVENT_LOW_MEMORY || event_type > APP_EVENT_LOW_BATTERY) + return service_app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + + EINA_LIST_FOREACH(handler_list[event_type], l_itr, handler) { + if (handler->cb == callback) + return service_app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } + + handler = calloc(1, sizeof(struct app_event_handler)); + if (!handler) + return service_app_error(APP_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL); + + handler->type = event_type; + handler->cb = callback; + handler->data = user_data; + handler_list[event_type] = eina_list_append(handler_list[event_type], handler); + + *event_handler = handler; + + return APP_ERROR_NONE; +} + +EXPORT_API int service_app_remove_event_handler(app_event_handler_h event_handler) +{ + app_event_handler_h handler; + app_event_type_e type; + Eina_List *l_itr; + Eina_List *l_next; + + if (event_handler == NULL) + return service_app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + + if (!_initialized) { + LOGI("handler list is not initialzed"); + return APP_ERROR_NONE; + } + + type = event_handler->type; + if (type < APP_EVENT_LOW_MEMORY || type > APP_EVENT_LOW_BATTERY) + return service_app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + + EINA_LIST_FOREACH_SAFE(handler_list[type], l_itr, l_next, handler) { + if (handler == event_handler) { + free(handler); + handler_list[type] = eina_list_remove_list(handler_list[type], l_itr); + return APP_ERROR_NONE; + } + } + + return service_app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, "cannot find such handler"); +} int service_app_create(void *data) { service_app_context_h service_app_context = data; service_app_create_cb create_cb; - char locale_dir[TIZEN_PATH_MAX] = {0, }; if (service_app_context == NULL) { @@ -150,6 +242,9 @@ int service_app_terminate(void *data) service_app_unset_appcore_event_cb(); + if (_initialized) + _free_handler_list(); + return SERVICE_APP_ERROR_NONE; } @@ -175,61 +270,50 @@ int service_app_reset(service_h service, void *data) } -int service_app_low_memory(void *data) +int service_app_low_memory(void *event_info, void *data) { - service_app_context_h service_app_context = data; - service_app_low_memory_cb low_memory_cb; + Eina_List *l; + app_event_handler_h handler; + struct app_event_info event; - if (service_app_context == NULL) - { - return service_app_error(SERVICE_APP_ERROR_INVALID_CONTEXT, __FUNCTION__, NULL); - } + LOGI("service_app_low_memory"); - low_memory_cb = service_app_context->callback->low_memory; + event.type = APP_EVENT_LOW_MEMORY; + event.value = event_info; - if (low_memory_cb != NULL) - { - low_memory_cb(service_app_context->data); + EINA_LIST_FOREACH(handler_list[APP_EVENT_LOW_MEMORY], l, handler) { + handler->cb(&event, handler->data); } - return SERVICE_APP_ERROR_NONE; + return APP_ERROR_NONE; } -int service_app_low_battery(void *data) +int service_app_low_battery(void *event_info, void *data) { - service_app_context_h service_app_context = data; - service_app_low_battery_cb low_battery_cb; + Eina_List *l; + app_event_handler_h handler; + struct app_event_info event; - if (service_app_context == NULL) - { - return service_app_error(SERVICE_APP_ERROR_INVALID_CONTEXT, __FUNCTION__, NULL); - } + LOGI("service_app_low_battery"); - low_battery_cb = service_app_context->callback->low_battery; + event.type = APP_EVENT_LOW_BATTERY; + event.value = event_info; - if (low_battery_cb != NULL) - { - low_battery_cb(service_app_context->data); + EINA_LIST_FOREACH(handler_list[APP_EVENT_LOW_BATTERY], l, handler) { + handler->cb(&event, handler->data); } - return SERVICE_APP_ERROR_NONE; + return APP_ERROR_NONE; } void service_app_set_appcore_event_cb(service_app_context_h service_app_context) { - if (service_app_context->callback->low_memory != NULL) - { - //appcore_set_event_callback(APPCORE_EVENT_LOW_MEMORY, service_app_appcore_low_memory, service_app_context); - } - - if (service_app_context->callback->low_battery != NULL) - { - //appcore_set_event_callback(APPCORE_EVENT_LOW_BATTERY, service_app_appcore_low_battery, service_app_context); - } + appcore_agent_set_event_callback(APPCORE_AGENT_EVENT_LOW_MEMORY, service_app_low_memory, service_app_context); + appcore_agent_set_event_callback(APPCORE_AGENT_EVENT_LOW_BATTERY, service_app_low_battery, service_app_context); } void service_app_unset_appcore_event_cb(void) { - //appcore_set_event_callback(APPCORE_EVENT_LOW_MEMORY, NULL, NULL); - //appcore_set_event_callback(APPCORE_EVENT_LOW_BATTERY, NULL, NULL); + appcore_agent_set_event_callback(APPCORE_AGENT_EVENT_LOW_MEMORY, NULL, NULL); + appcore_agent_set_event_callback(APPCORE_AGENT_EVENT_LOW_BATTERY, NULL, NULL); } |