Add new api for system event handling from tizen_2.3 66/32966/2 accepted/tizen/mobile/20150121.045014 accepted/tizen/tv/20150121.044514 accepted/tizen/wearable/20150121.044747 submit/tizen/20150120.043506 submit/tizen_common/20150226.010729 submit/tizen_mobile/20150121.020049 submit/tizen_tv/20150121.020041 submit/tizen_wearable/20150121.020025
authorJiwoong Im <jiwoong.im@samsung.com>
Wed, 31 Dec 2014 01:46:02 +0000 (10:46 +0900)
committerJiwoong Im <jiwoong.im@samsung.com>
Fri, 2 Jan 2015 07:51:06 +0000 (16:51 +0900)
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>
CMakeLists.txt
include/appcore-agent.h
include/service_app.h
packaging/appcore-agent.spec
src/appcore-agent.c
src/service_app_main.c

index 96433bf..3816369 100644 (file)
@@ -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)
index e1c6080..59c1ce0 100755 (executable)
@@ -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
 }
index 2f3098c..7e2a829 100755 (executable)
@@ -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()
  */
index 88f724b..95a4955 100644 (file)
@@ -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)
index 303cfb5..e787d14 100755 (executable)
@@ -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);
 
index 08dd4e0..34ea510 100755 (executable)
@@ -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>
 #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);
 }