diff options
Diffstat (limited to 'src/service_app_main.c')
-rw-r--r-- | src/service_app_main.c | 490 |
1 files changed, 332 insertions, 158 deletions
diff --git a/src/service_app_main.c b/src/service_app_main.c index 3da99da..3155a5f 100644 --- a/src/service_app_main.c +++ b/src/service_app_main.c @@ -15,28 +15,112 @@ */ -#include <stdio.h> #include <stdlib.h> -#include <unistd.h> -#include <string.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> #include <bundle.h> #include <aul.h> #include <dlog.h> +#include <vconf-internal-keys.h> +#include <app_common.h> + #include <Eina.h> #include <appcore-agent.h> -#include <service_app_private.h> +#include "service_app_private.h" +#include "service_app_extension.h" + +#include <unistd.h> + #ifdef LOG_TAG #undef LOG_TAG #endif -#define LOG_TAG "TIZEN_N_AGENT" -#define SERVICE_APP_EVENT_MAX 2 +#ifndef TIZEN_PATH_MAX +#define TIZEN_PATH_MAX 1024 +#endif + + +#define LOG_TAG "CAPI_APPFW_APPLICATION" + +typedef enum { + SERVICE_APP_STATE_NOT_RUNNING, // The application has been launched or was running but was terminated + SERVICE_APP_STATE_CREATING, // The application is initializing the resources on service_app_create_cb callback + SERVICE_APP_STATE_RUNNING, // The application is running in the foreground and background +} service_app_state_e; + +static int _service_app_get_id(char **id) +{ + static char id_buf[TIZEN_PATH_MAX] = {0, }; + int ret = -1; + + if (id == NULL) + { + return service_app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } + + if (id_buf[0] == '\0') + { + ret = aul_app_get_appid_bypid(getpid(), id_buf, sizeof(id_buf)); + + if (ret < 0) { + return service_app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, "failed to get the application ID"); + } + } + + if (id_buf[0] == '\0') + { + return service_app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, "failed to get the application ID"); + } + + *id = strdup(id_buf); + + if (*id == NULL) + { + return service_app_error(APP_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL); + } + + return APP_ERROR_NONE; +} + +static int _service_appget_package_app_name(const char *appid, char **name) +{ + char *name_token = NULL; + + if (appid == NULL) + { + return service_app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } + + // com.vendor.name -> name + name_token = strrchr(appid, '.'); + + if (name_token == NULL) + { + return service_app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, NULL); + } + + name_token++; + + *name = strdup(name_token); + + if (*name == NULL) + { + return service_app_error(APP_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL); + } + + return APP_ERROR_NONE; +} + +EXPORT_API void service_app_exit_without_restart(void) +{ + appcore_agent_terminate_without_restart(); +} + +#define SERVICE_APP_EVENT_MAX 5 +static Eina_List *handler_list[SERVICE_APP_EVENT_MAX] = {NULL, }; +static int handler_initialized = 0; +static int appcore_agent_initialized = 0; struct app_event_handler { app_event_type_e type; @@ -49,34 +133,13 @@ struct app_event_info { void *value; }; - -typedef enum { - SERVICE_APP_STATE_NOT_RUNNING, // The application has been launched or was running but was terminated - SERVICE_APP_STATE_CREATING, // The application is initializing the resources on service_app_create_cb callback - SERVICE_APP_STATE_RUNNING, // The application is running in the foreground and background -} service_app_state_e; - -typedef struct { +struct service_app_context { char *package; char *service_app_name; service_app_state_e state; service_app_lifecycle_callback_s *callback; void *data; -} service_app_context_s; - -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(app_control_h app_control, 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; +}; static void _free_handler_list(void) { @@ -91,229 +154,340 @@ static void _free_handler_list(void) eina_shutdown(); } -EXPORT_API int service_app_main(int argc, char **argv, service_app_lifecycle_callback_s *callback, void *user_data) +static int _service_app_low_memory(void *event_info, void *data) { - service_app_context_s service_app_context = { - .state = SERVICE_APP_STATE_NOT_RUNNING, - .callback = callback, - .data = user_data - }; + Eina_List *l; + app_event_handler_h handler; + struct app_event_info event; - struct agentcore_ops appcore_context = { - .data = &service_app_context, - .create = service_app_create, - .terminate = service_app_terminate, - .app_control = service_app_reset, - }; + LOGI("service_app_low_memory"); - if (argc <= 0 || argv == NULL || callback == NULL) - { - return service_app_error(SERVICE_APP_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); - } + event.type = APP_EVENT_LOW_MEMORY; + event.value = event_info; - if (callback->create == NULL) - { - return service_app_error(SERVICE_APP_ERROR_INVALID_PARAMETER, __FUNCTION__, "service_app_create_cb() callback must be registered"); + EINA_LIST_FOREACH(handler_list[APP_EVENT_LOW_MEMORY], l, handler) { + handler->cb(&event, handler->data); } - if (service_app_context.state != SERVICE_APP_STATE_NOT_RUNNING) - { - return service_app_error(SERVICE_APP_ERROR_ALREADY_RUNNING, __FUNCTION__, NULL); - } + return APP_ERROR_NONE; +} - service_app_context.state = SERVICE_APP_STATE_CREATING; +static int _service_app_low_battery(void *event_info, void *data) +{ + Eina_List *l; + app_event_handler_h handler; + struct app_event_info event; - appcore_agent_main(argc, argv, &appcore_context); + LOGI("service_app_low_battery"); - return SERVICE_APP_ERROR_NONE; -} + event.type = APP_EVENT_LOW_BATTERY; + event.value = event_info; + EINA_LIST_FOREACH(handler_list[APP_EVENT_LOW_BATTERY], l, handler) { + handler->cb(&event, handler->data); + } -EXPORT_API void service_app_exit(void) -{ - appcore_agent_terminate(); + return APP_ERROR_NONE; } -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) +static int _service_app_lang_changed(void *event_info, void *data) { + Eina_List *l; app_event_handler_h handler; - Eina_List *l_itr; + struct app_event_info event; - if (!_initialized) { - eina_init(); - _initialized = 1; + LOGI("service_app_lang_changed"); + + event.type = APP_EVENT_LANGUAGE_CHANGED; + event.value = event_info; + + EINA_LIST_FOREACH(handler_list[APP_EVENT_LANGUAGE_CHANGED], l, handler) { + handler->cb(&event, handler->data); } - if (event_handler == NULL || callback == NULL) - return service_app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + return APP_ERROR_NONE; +} - if (event_type < APP_EVENT_LOW_MEMORY || event_type > APP_EVENT_LOW_BATTERY) - return service_app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); +static int _service_app_region_changed(void *event_info, void *data) +{ + Eina_List *l; + app_event_handler_h handler; + struct app_event_info event; - EINA_LIST_FOREACH(handler_list[event_type], l_itr, handler) { - if (handler->cb == callback) - return service_app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + if (event_info == NULL) { + LOGI("receive empy event, ignore it"); + return APP_ERROR_NONE; } - handler = calloc(1, sizeof(struct app_event_handler)); - if (!handler) - return service_app_error(APP_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL); + LOGI("service_app_region_changed"); - handler->type = event_type; - handler->cb = callback; - handler->data = user_data; - handler_list[event_type] = eina_list_append(handler_list[event_type], handler); + event.type = APP_EVENT_REGION_FORMAT_CHANGED; + event.value = event_info; - *event_handler = handler; + EINA_LIST_FOREACH(handler_list[APP_EVENT_REGION_FORMAT_CHANGED], l, handler) { + handler->cb(&event, handler->data); + } return APP_ERROR_NONE; } -EXPORT_API int service_app_remove_event_handler(app_event_handler_h event_handler) +static void _service_app_appcore_agent_set_event_cb(app_event_type_e event_type) { - 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); + switch (event_type) { + case APP_EVENT_LOW_MEMORY: + appcore_agent_set_event_callback(APPCORE_AGENT_EVENT_LOW_MEMORY, _service_app_low_memory, NULL); + break; + case APP_EVENT_LOW_BATTERY: + appcore_agent_set_event_callback(APPCORE_AGENT_EVENT_LOW_BATTERY, _service_app_low_battery, NULL); + break; + case APP_EVENT_LANGUAGE_CHANGED: + appcore_agent_set_event_callback(APPCORE_AGENT_EVENT_LANG_CHANGE, _service_app_lang_changed, NULL); + break; + case APP_EVENT_REGION_FORMAT_CHANGED: + appcore_agent_set_event_callback(APPCORE_AGENT_EVENT_REGION_CHANGE, _service_app_region_changed, NULL); + break; + default: + break; + } +} - if (!_initialized) { - LOGI("handler list is not initialzed"); - return APP_ERROR_NONE; +static void _service_app_appcore_agent_unset_event_cb(app_event_type_e event_type) +{ + switch (event_type) { + case APP_EVENT_LOW_MEMORY: + appcore_agent_set_event_callback(APPCORE_AGENT_EVENT_LOW_MEMORY, NULL, NULL); + break; + case APP_EVENT_LOW_BATTERY: + appcore_agent_set_event_callback(APPCORE_AGENT_EVENT_LOW_BATTERY, NULL, NULL); + break; + case APP_EVENT_LANGUAGE_CHANGED: + appcore_agent_set_event_callback(APPCORE_AGENT_EVENT_LANG_CHANGE, NULL, NULL); + break; + case APP_EVENT_REGION_FORMAT_CHANGED: + appcore_agent_set_event_callback(APPCORE_AGENT_EVENT_REGION_CHANGE, NULL, NULL); + break; + default: + break; } +} - 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); +static void _service_app_set_appcore_event_cb(void) +{ + app_event_type_e event; - 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; - } + for (event = APP_EVENT_LOW_MEMORY; event <= APP_EVENT_REGION_FORMAT_CHANGED; event++) { + if (eina_list_count(handler_list[event]) > 0) + _service_app_appcore_agent_set_event_cb(event); } +} - return service_app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, "cannot find such handler"); +static void _service_app_unset_appcore_event_cb(void) +{ + app_event_type_e event; + + for (event = APP_EVENT_LOW_MEMORY; event <= APP_EVENT_REGION_FORMAT_CHANGED; event++) { + if (eina_list_count(handler_list[event]) > 0) + _service_app_appcore_agent_unset_event_cb(event); + } } -int service_app_create(void *data) +static int _service_app_create(void *data) { - service_app_context_h service_app_context = data; + struct service_app_context *app_context = data; service_app_create_cb create_cb; - if (service_app_context == NULL) + if (app_context == NULL) { - return service_app_error(SERVICE_APP_ERROR_INVALID_CONTEXT, __FUNCTION__, NULL); + return service_app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, NULL); } - service_app_set_appcore_event_cb(service_app_context); + appcore_agent_initialized = 1; + _service_app_set_appcore_event_cb(); - create_cb = service_app_context->callback->create; + create_cb = app_context->callback->create; - if (create_cb == NULL || create_cb(service_app_context->data) == false) + if (create_cb == NULL || create_cb(app_context->data) == false) { - return service_app_error(SERVICE_APP_ERROR_INVALID_CONTEXT, __FUNCTION__, "service_app_create_cb() returns false"); + return service_app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, "service_app_create_cb() returns false"); } - service_app_context->state = SERVICE_APP_STATE_RUNNING; + app_context->state = SERVICE_APP_STATE_RUNNING; - return SERVICE_APP_ERROR_NONE; + return APP_ERROR_NONE; } -int service_app_terminate(void *data) +static int _service_app_terminate(void *data) { - service_app_context_h service_app_context = data; + struct service_app_context *app_context = data; service_app_terminate_cb terminate_cb; - if (service_app_context == NULL) + if (app_context == NULL) { - return service_app_error(SERVICE_APP_ERROR_INVALID_CONTEXT, __FUNCTION__, NULL); + return service_app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, NULL); } - terminate_cb = service_app_context->callback->terminate; + terminate_cb = app_context->callback->terminate; if (terminate_cb != NULL) { - terminate_cb(service_app_context->data); + terminate_cb(app_context->data); } - service_app_unset_appcore_event_cb(); + _service_app_unset_appcore_event_cb(); - if (_initialized) + if (handler_initialized) _free_handler_list(); - return SERVICE_APP_ERROR_NONE; + return APP_ERROR_NONE; } - -int service_app_reset(app_control_h app_control, void *data) +static int _service_app_reset(app_control_h app_control, void *data) { - service_app_context_h service_app_context = data; - service_app_control_cb app_control_cb; + struct service_app_context *app_context = data; + service_app_control_cb service_cb; - if (service_app_context == NULL) + if (app_context == NULL) { - return service_app_error(SERVICE_APP_ERROR_INVALID_CONTEXT, __FUNCTION__, NULL); + return service_app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, NULL); } - app_control_cb = service_app_context->callback->app_control; + service_cb = app_context->callback->app_control; - if (app_control_cb != NULL) + if (service_cb != NULL) { - app_control_cb(app_control, service_app_context->data); + service_cb(app_control, app_context->data); } - return SERVICE_APP_ERROR_NONE; + return APP_ERROR_NONE; } - -int service_app_low_memory(void *event_info, void *data) +EXPORT_API int service_app_main(int argc, char **argv, service_app_lifecycle_callback_s *callback, void *user_data) { - Eina_List *l; - app_event_handler_h handler; - struct app_event_info event; + struct service_app_context app_context = { + .state = SERVICE_APP_STATE_NOT_RUNNING, + .callback = callback, + .data = user_data + }; - LOGI("service_app_low_memory"); + struct agentcore_ops appcore_context = { + .data = &app_context, + .create = _service_app_create, + .terminate = _service_app_terminate, + .app_control = _service_app_reset, + }; - event.type = APP_EVENT_LOW_MEMORY; - event.value = event_info; + if (argc <= 0 || argv == NULL || callback == NULL) + { + return service_app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } - EINA_LIST_FOREACH(handler_list[APP_EVENT_LOW_MEMORY], l, handler) { - handler->cb(&event, handler->data); + if (callback->create == NULL) + { + return service_app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, "service_app_create_cb() callback must be registered"); + } + + if (app_context.state != SERVICE_APP_STATE_NOT_RUNNING) + { + return service_app_error(APP_ERROR_ALREADY_RUNNING, __FUNCTION__, NULL); + } + + + if (_service_app_get_id(&(app_context.package)) == APP_ERROR_NONE) + { + if (_service_appget_package_app_name(app_context.package, &(app_context.service_app_name)) != APP_ERROR_NONE) + { + free(app_context.package); + } } + app_context.state = SERVICE_APP_STATE_CREATING; + + appcore_agent_main(argc, argv, &appcore_context); + + if (app_context.service_app_name) + free(app_context.service_app_name); + if (app_context.package) + free(app_context.package); + return APP_ERROR_NONE; } -int service_app_low_battery(void *event_info, void *data) +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) { - Eina_List *l; app_event_handler_h handler; - struct app_event_info event; + Eina_List *l_itr; - LOGI("service_app_low_battery"); + if (!handler_initialized) { + eina_init(); + handler_initialized = 1; + } - event.type = APP_EVENT_LOW_BATTERY; - event.value = event_info; + if (event_handler == NULL || callback == NULL) + return service_app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); - EINA_LIST_FOREACH(handler_list[APP_EVENT_LOW_BATTERY], l, handler) { - handler->cb(&event, handler->data); + if (event_type < APP_EVENT_LOW_MEMORY || event_type > APP_EVENT_REGION_FORMAT_CHANGED) + 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; + + if (appcore_agent_initialized && eina_list_count(handler_list[event_type]) == 0) + _service_app_appcore_agent_set_event_cb(event_type); + + handler_list[event_type] = eina_list_append(handler_list[event_type], handler); + + *event_handler = handler; + return APP_ERROR_NONE; } -void service_app_set_appcore_event_cb(service_app_context_h service_app_context) +EXPORT_API int service_app_remove_event_handler(app_event_handler_h event_handler) { - 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); -} + app_event_handler_h handler; + app_event_type_e type; + Eina_List *l_itr; + Eina_List *l_next; -void service_app_unset_appcore_event_cb(void) -{ - appcore_agent_set_event_callback(APPCORE_AGENT_EVENT_LOW_MEMORY, NULL, NULL); - appcore_agent_set_event_callback(APPCORE_AGENT_EVENT_LOW_BATTERY, NULL, NULL); + if (event_handler == NULL) + return service_app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + + if (!handler_initialized) { + LOGI("handler list is not initialzed"); + return APP_ERROR_NONE; + } + + type = event_handler->type; + if (type < APP_EVENT_LOW_MEMORY + || type > APP_EVENT_REGION_FORMAT_CHANGED + || type == APP_EVENT_DEVICE_ORIENTATION_CHANGED) + 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); + + if (appcore_agent_initialized && eina_list_count(handler_list[type]) == 0) + _service_app_appcore_agent_unset_event_cb(type); + + return APP_ERROR_NONE; + } + } + + return service_app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, "cannot find such handler"); } |