From 640ca199c038e46f3a3300d81385a96da71bc176 Mon Sep 17 00:00:00 2001 From: Sangyoon Jang Date: Mon, 1 Jun 2015 17:23:11 +0900 Subject: [PATCH] Update source from Tizen 2.4 add doxygen header update doxygen comment Change-Id: If538a137380c41791796251537b4f1d6a4a541ea Signed-off-by: Sangyoon Jang --- CMakeLists.txt | 17 +- appcore-agent.pc.in | 14 +- capi-appfw-service-application.pc.in | 14 +- doc/appcore-agent_doc.h | 37 +++ include/appcore-agent.h | 14 +- include/service_app.h | 81 +++--- include/service_app_extension.h | 52 ++++ packaging/appcore-agent.spec | 44 ++- src/appcore-agent.c | 305 +++++++++++++++++--- src/service_app_error.c | 23 +- src/service_app_main.c | 490 ++++++++++++++++++++++----------- {include => src}/service_app_private.h | 6 +- test/test.c | 70 +++-- 13 files changed, 816 insertions(+), 351 deletions(-) create mode 100644 doc/appcore-agent_doc.h create mode 100644 include/service_app_extension.h rename {include => src}/service_app_private.h (85%) diff --git a/CMakeLists.txt b/CMakeLists.txt index dae38e5..1cf11df 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,13 +1,6 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.6) PROJECT(appcore-agent C) -SET(PREFIX ${CMAKE_INSTALL_PREFIX}) -SET(EXEC_PREFIX "\${prefix}") -SET(LIBDIR "\${prefix}/lib") -SET(INCLUDEDIR "\${prefix}/include") -SET(VERSION_MAJOR 1) -SET(VERSION "${VERSION_MAJOR}.1") - INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include) ADD_DEFINITIONS("-DPREFIX=\"${PREFIX}\"") @@ -27,18 +20,18 @@ SET(SRCS_agent src/appcore-agent.c src/service_app_error.c ) SET(HEADERS_agent appcore-agent.h - service_app.h) + service_app_extension.h + service_app.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 ecore) +pkg_check_modules(pkg_agent REQUIRED aul dlog capi-appfw-app-control capi-appfw-app-common vconf ecore vconf-internal-keys appcore-common) FOREACH(flag ${pkg_agent_CFLAGS}) SET(EXTRA_CFLAGS_agent "${EXTRA_CFLAGS_agent} ${flag}") ENDFOREACH(flag) ADD_LIBRARY(${APPCORE_AGENT} SHARED ${SRCS_agent}) -SET_TARGET_PROPERTIES(${APPCORE_AGENT} PROPERTIES SOVERSION ${VERSION_MAJOR}) -SET_TARGET_PROPERTIES(${APPCORE_AGENT} PROPERTIES VERSION ${VERSION}) +SET_TARGET_PROPERTIES(${APPCORE_AGENT} PROPERTIES SOVERSION ${MAJORVER}) +SET_TARGET_PROPERTIES(${APPCORE_AGENT} PROPERTIES VERSION ${FULLVER}) SET_TARGET_PROPERTIES(${APPCORE_AGENT} PROPERTIES COMPILE_FLAGS ${EXTRA_CFLAGS_agent}) TARGET_LINK_LIBRARIES(${APPCORE_AGENT} ${pkg_agent_LDFLAGS} "-ldl") diff --git a/appcore-agent.pc.in b/appcore-agent.pc.in index 78a9888..7b00750 100644 --- a/appcore-agent.pc.in +++ b/appcore-agent.pc.in @@ -1,13 +1,13 @@ # Package Information for pkg-config -prefix=@PREFIX@ -exec_prefix=@EXEC_PREFIX@ -libdir=@LIBDIR@ -includedir=@INCLUDEDIR@ +prefix=@CMAKE_INSTALL_PREFIX@ +exec_prefix=@CMAKE_INSTALL_PREFIX@ +libdir=@CMAKE_INSTALL_LIBDIR@ +includedir=@INCLUDE_INSTALL_DIR@/appcore-agent Name: appcore-agent -Description: SAMSUNG Linux platform application library -Version: @VERSION@ +Description: Service Application Library +Version: @FULLVER@ Requires: aul dlog capi-appfw-application Libs: -L${libdir} -lappcore-agent -Cflags: -I${includedir} -I${includedir}/appcore-agent +Cflags: -I${includedir} diff --git a/capi-appfw-service-application.pc.in b/capi-appfw-service-application.pc.in index 78a9888..7b00750 100644 --- a/capi-appfw-service-application.pc.in +++ b/capi-appfw-service-application.pc.in @@ -1,13 +1,13 @@ # Package Information for pkg-config -prefix=@PREFIX@ -exec_prefix=@EXEC_PREFIX@ -libdir=@LIBDIR@ -includedir=@INCLUDEDIR@ +prefix=@CMAKE_INSTALL_PREFIX@ +exec_prefix=@CMAKE_INSTALL_PREFIX@ +libdir=@CMAKE_INSTALL_LIBDIR@ +includedir=@INCLUDE_INSTALL_DIR@/appcore-agent Name: appcore-agent -Description: SAMSUNG Linux platform application library -Version: @VERSION@ +Description: Service Application Library +Version: @FULLVER@ Requires: aul dlog capi-appfw-application Libs: -L${libdir} -lappcore-agent -Cflags: -I${includedir} -I${includedir}/appcore-agent +Cflags: -I${includedir} diff --git a/doc/appcore-agent_doc.h b/doc/appcore-agent_doc.h new file mode 100644 index 0000000..ff0d957 --- /dev/null +++ b/doc/appcore-agent_doc.h @@ -0,0 +1,37 @@ +/* + * app-core + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jayoun Lee , Sewook Park , Jaeho Lee + * + * 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. + */ + +/** + * + * @ingroup CAPI_APPLICATION_FRAMEWORK + * @defgroup CAPI_SERVICE_APP_MODULE Service Application + * @brief Launches or exits serviceApp. + * + * @section CAPI_SERVICE_APP_MODULE_HEADER Required Header + * \#include + * @section CAPI_SERVICE_APP_MODULE_OVERVIEW Overview + * The @ref CAPI_SERVICE_APP_MODULE API provides functions for handling Tizen service application state changes or system events. + * + * This API provides interfaces for the following three categories: + * - Starting or exiting the main event loop + * - Registering callbacks for application state change events + * - Registering callbacks for basic system events + * + */ diff --git a/include/appcore-agent.h b/include/appcore-agent.h index 0a40349..164a8f8 100644 --- a/include/appcore-agent.h +++ b/include/appcore-agent.h @@ -28,7 +28,7 @@ #include #include -#include "app_control.h" +#include #ifdef __cplusplus @@ -48,17 +48,23 @@ struct agentcore_ops { enum appcore_agent_event { APPCORE_AGENT_EVENT_UNKNOWN, - /**< Unknown event */ + /**< Unknown event */ APPCORE_AGENT_EVENT_LOW_MEMORY, - /**< Low memory */ + /**< Low memory */ APPCORE_AGENT_EVENT_LOW_BATTERY, - /**< Low battery */ + /**< Low battery */ + APPCORE_AGENT_EVENT_LANG_CHANGE, + /**< Language setting is changed */ + APPCORE_AGENT_EVENT_REGION_CHANGE, + /**< Region setting is changed */ }; int appcore_agent_main(int argc, char **argv, struct agentcore_ops *ops); int appcore_agent_terminate(); +int appcore_agent_terminate_without_restart(); + int appcore_agent_set_event_callback(enum appcore_agent_event event, int (*cb) (void *, void *), void *data); diff --git a/include/service_app.h b/include/service_app.h index 631a2c7..ac11273 100644 --- a/include/service_app.h +++ b/include/service_app.h @@ -20,91 +20,65 @@ #include #include -#include - +#include #ifdef __cplusplus extern "C" { #endif /** - * @addtogroup CAPI_APPLICATION_MODULE + * @addtogroup CAPI_SERVICE_APP_MODULE * @{ */ /** - * @brief Enumerations of error code for Application. - */ -typedef enum -{ - SERVICE_APP_ERROR_NONE = TIZEN_ERROR_NONE, /**< Successful */ - SERVICE_APP_ERROR_INVALID_PARAMETER = TIZEN_ERROR_INVALID_PARAMETER, /**< Invalid parameter */ - SERVICE_APP_ERROR_OUT_OF_MEMORY = TIZEN_ERROR_OUT_OF_MEMORY, /**< Out of memory */ - SERVICE_APP_ERROR_INVALID_CONTEXT = TIZEN_ERROR_NOT_PERMITTED, /**< Invalid application context */ - SERVICE_APP_ERROR_NO_SUCH_FILE = TIZEN_ERROR_NO_SUCH_FILE, /**< No such file or directory */ - SERVICE_APP_ERROR_ALREADY_RUNNING = TIZEN_ERROR_ALREADY_IN_PROGRESS, /**< Application is already running */ -} service_app_error_e; - - -/** * @brief Called at the start of the agent application. * - * @param[in] user_data The user data passed from the callback registration function - * @return @c true on success, otherwise @c false + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * + * @param[in] user_data The user data passed from the callback registration function + * @return @c true on success, + * otherwise @c false * @pre service_app_main() will invoke this callback function. * @see service_app_main() - * @see #service_app_event_callback_s + * @see #service_app_lifecycle_callback_s */ typedef bool (*service_app_create_cb) (void *user_data); /** - * @brief Called once after the main loop of agent application exits. + * @brief Called once after the main loop of the agent application exits. * - * @param[in] user_data The user data passed from the callback registration function + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * + * @param[in] user_data The user data passed from the callback registration function * @see service_app_main() - * @see #service_app_event_callback_s + * @see #service_app_lifecycle_callback_s */ typedef void (*service_app_terminate_cb) (void *user_data); /** - * @brief Called when other application send the launch request to the agent application. + * @brief Called when another application sends the launch request to the agent application. * - * @param[in] app_control The handle to the app_control - * @param[in] user_data The user data passed from the callback registration function + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * + * @param[in] app_control The handle to the app_control + * @param[in] user_data The user data passed from the callback registration function * @see service_app_main() - * @see #service_app_event_callback_s - * @see @ref CAPI_SERVICE_MODULE API + * @see #service_app_lifecycle_callback_s + * @see @ref CAPI_APP_CONTROL_MODULE API */ typedef void (*service_app_control_cb) (app_control_h app_control, void *user_data); /** - * @brief Called when the system memory is running low. - * - * @param[in] user_data The user data passed from the callback registration function - * @see service_app_main() - * @see #service_app_event_callback_s - */ -typedef void (*service_app_low_memory_cb) (void *user_data); - - -/** - * @brief Called when the battery power is running low. - * - * @param[in] user_data The user data passed from the callback registration function - * @see service_app_main() - * @see #service_app_event_callback_s - */ -typedef void (*service_app_low_battery_cb) (void *user_data); - - -/** * @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. * + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * * @see service_app_main() * @see service_app_create_cb() * @see service_app_terminate_cb() @@ -121,6 +95,8 @@ typedef struct /** * @brief Adds the system event handler * + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @remarks The service application can handle low memory event, low battery event, language setting changed event and region format changed event. * @param[out] handler The event handler * @param[in] event_type The system event type * @param[in] callback The callback function @@ -141,6 +117,7 @@ int service_app_add_event_handler(app_event_handler_h *handler, app_event_type_e /** * @brief Removes registered event handler * + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * @param[in] event_handler The event handler * * @return 0 on success, otherwise a negative error value @@ -155,6 +132,11 @@ 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. * + * @details This function is the main entry point of the Tizen service application. + * This main loop supports event handling for the GMainLoop and the Ecore Main Loop. + * + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * * @param[in] argc The argument count * @param[in] argv The argument vector * @param[in] callback The set of callback functions to handle application events @@ -181,12 +163,13 @@ int service_app_main(int argc, char **argv, service_app_lifecycle_callback_s *ca * * @details The main loop of the application stops and service_app_terminate_cb() is invoked. * + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * * @see service_app_main() * @see service_app_terminate_cb() */ void service_app_exit(void); - /** * @} */ diff --git a/include/service_app_extension.h b/include/service_app_extension.h new file mode 100644 index 0000000..993394a --- /dev/null +++ b/include/service_app_extension.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2011 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. + */ + + +#ifndef __TIZEN_APPFW_SERVICE_APP_EXTENSION_H__ +#define __TIZEN_APPFW_SERVICE_APP_EXTENSION_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @addtogroup CAPI_SERVICE_APP_MODULE + * @{ + */ + +/** + * @brief Exits the main loop of the application without restart. + * + * @details The main loop of the application stops, service_app_terminate_cb() is invoked, and the a + * pplication is not restarted. + * + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * + * @see service_app_main() + * @see service_app_exit() + * @see service_app_terminate_cb() + */ +void service_app_exit_without_restart(void); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __TIZEN_APPFW_SERVICE_APP_EXTENSION_H__ */ diff --git a/packaging/appcore-agent.spec b/packaging/appcore-agent.spec index b01b574..cf705ff 100644 --- a/packaging/appcore-agent.spec +++ b/packaging/appcore-agent.spec @@ -1,44 +1,39 @@ Name: appcore-agent -Version: 1.0 -Release: 0 +Version: 1.0.4 +Release: 1 License: Apache-2.0 -Summary: Agent Application basic +Summary: Service Application basic Group: Application Framework/Service -Source0: appcore-agent-%{version}.tar.gz +Source0: %{name}-%{version}.tar.gz Source1001: appcore-agent.manifest BuildRequires: cmake -BuildRequires: sysman-devel BuildRequires: pkgconfig(aul) -BuildRequires: pkgconfig(capi-appfw-application) +BuildRequires: pkgconfig(capi-appfw-app-control) +BuildRequires: pkgconfig(capi-appfw-app-common) +BuildRequires: pkgconfig(appcore-common) BuildRequires: pkgconfig(dlog) BuildRequires: pkgconfig(ecore) -BuildRequires: pkgconfig(pmapi) -BuildRequires: pkgconfig(sysman) BuildRequires: pkgconfig(vconf) +BuildRequires: pkgconfig(vconf-internal-keys) %description -SLP agent application basic +Service Application basic %package devel -Summary: Applocation Core Agent +Summary: Application Core Agent Group: Application Framework/Development -Requires: %{name} = %{version} +Requires: %{name} = %{version}-%{release} %description devel -appcore agent (developement files) - -%package -n capi-appfw-service-application-devel -Summary: service appliation -Group: Development/Libraries -Requires: appcore-agent-devel = %{version}-%{release} -%description -n capi-appfw-service-application-devel -service application (developement files) +Service Application basic (development files) %prep %setup -q cp %{SOURCE1001} . %build -%cmake . +MAJORVER=`echo %{version} | awk 'BEGIN {FS="."}{print $1}'` + +%cmake . -DFULLVER=%{version} -DMAJORVER=${MAJORVER} %__make %{?_smp_mflags} %install @@ -52,19 +47,14 @@ cp %{SOURCE1001} . %manifest %{name}.manifest %license LICENSE %defattr(-,root,root,-) -%{_libdir}/libappcore-agent.so.1 -%{_libdir}/libappcore-agent.so.1.1 +%{_libdir}/libappcore-agent.so.* %files devel %manifest %{name}.manifest %defattr(-,root,root,-) %{_libdir}/pkgconfig/appcore-agent.pc -%{_libdir}/libappcore-agent.so -%{_includedir}/appcore-agent/appcore-agent.h -%{_includedir}/appcore-agent/service_app.h - -%files -n capi-appfw-service-application-devel %{_libdir}/pkgconfig/capi-appfw-service-application.pc %{_libdir}/libappcore-agent.so %{_includedir}/appcore-agent/appcore-agent.h %{_includedir}/appcore-agent/service_app.h +%{_includedir}/appcore-agent/service_app_extension.h diff --git a/src/appcore-agent.c b/src/appcore-agent.c index 87f6f7a..c29c799 100644 --- a/src/appcore-agent.c +++ b/src/appcore-agent.c @@ -27,11 +27,13 @@ #include #include #include +#include #include +#include -#include #include "aul.h" #include "appcore-agent.h" +#include #include #include #include @@ -42,9 +44,24 @@ #define LOG_TAG "APPCORE_AGENT" +#define _ERR(fmt, arg...) LOGE(fmt, ##arg) +#define _INFO(fmt, arg...) LOGI(fmt, ##arg) +#define _DBG(fmt, arg...) LOGD(fmt, ##arg) #ifndef EXPORT_API -# define EXPORT_API __attribute__ ((visibility("default"))) +#define EXPORT_API __attribute__ ((visibility("default"))) +#endif + +#ifndef _ERR +#define _ERR(fmt, arg...) LOGE(fmt, ##arg) +#endif + +#ifndef _INFO +#define _INFO(...) LOGI(__VA_ARGS__) +#endif + +#ifndef _DBG +#define _DBG(...) LOGD(__VA_ARGS__) #endif #define _warn_if(expr, fmt, arg...) do { \ @@ -79,6 +96,10 @@ } \ } while (0) +#define APPID_MAX 256 +#define PKGNAME_MAX 256 +#define PATH_RES "/res" +#define PATH_LOCALE "/locale" static pid_t _pid; @@ -89,6 +110,8 @@ enum sys_event { SE_UNKNOWN, SE_LOWMEM, SE_LOWBAT, + SE_LANGCHG, + SE_REGIONCHG, SE_MAX }; @@ -114,11 +137,14 @@ enum agent_event { static enum appcore_agent_event to_ae[SE_MAX] = { - APPCORE_AGENT_EVENT_UNKNOWN, /* SE_UNKNOWN */ - APPCORE_AGENT_EVENT_LOW_MEMORY, /* SE_LOWMEM */ + APPCORE_AGENT_EVENT_UNKNOWN, /* SE_UNKNOWN */ + APPCORE_AGENT_EVENT_LOW_MEMORY, /* SE_LOWMEM */ APPCORE_AGENT_EVENT_LOW_BATTERY, /* SE_LOWBAT */ + APPCORE_AGENT_EVENT_LANG_CHANGE, /* SE_LANGCHG */ + APPCORE_AGENT_EVENT_REGION_CHANGE, /* SE_REGIONCHG */ }; +static int appcore_agent_event_initialized[SE_MAX] = {0}; enum cb_type { /* callback */ _CB_NONE, @@ -174,11 +200,13 @@ struct agent_appcore { static struct agent_appcore core; - static int __sys_lowmem_post(void *data, void *evt); static int __sys_lowmem(void *data, void *evt); static int __sys_lowbatt(void *data, void *evt); - +static int __sys_langchg_pre(void *data, void *evt); +static int __sys_langchg(void *data, void *evt); +static int __sys_regionchg_pre(void *data, void *evt); +static int __sys_regionchg(void *data, void *evt); static struct evt_ops evtops[] = { { @@ -191,9 +219,27 @@ static struct evt_ops evtops[] = { .type = _CB_VCONF, .key.vkey = VCONFKEY_SYSMAN_BATTERY_STATUS_LOW, .vcb = __sys_lowbatt, - } + }, + { + .type = _CB_VCONF, + .key.vkey = VCONFKEY_LANGSET, + .vcb_pre = __sys_langchg_pre, + .vcb = __sys_langchg, + }, + { + .type = _CB_VCONF, + .key.vkey = VCONFKEY_REGIONFORMAT, + .vcb_pre = __sys_regionchg_pre, + .vcb = __sys_regionchg, + }, + { + .type = _CB_VCONF, + .key.vkey = VCONFKEY_REGIONFORMAT_TIME1224, + .vcb = __sys_regionchg, + }, }; +extern int app_control_create_event(bundle *data, struct app_control_s **app_control); static void __exit_loop(void *data) { @@ -352,6 +398,81 @@ static int __sys_lowbatt(void *data, void *evt) return 0; } +static int __sys_langchg_pre(void *data, void *evt) +{ + keynode_t *key = evt; + char *lang; + char *r; + + lang = vconf_keynode_get_str(key); + if (lang) { + setenv("LANG", lang, 1); + setenv("LC_MESSAGES", lang, 1); + + r = setlocale(LC_ALL, lang); + if (r == NULL) { + r = setlocale(LC_ALL, lang); + if (r) { + _DBG("*****appcore-agent setlocale=%s\n", r); + } + } + } + + return 0; +} + +static int __sys_langchg(void *data, void *evt) +{ + keynode_t *key = evt; + char *val; + + val = vconf_keynode_get_str(key); + + return __sys_do(data, (void *)val, SE_LANGCHG); +} + +static int __sys_regionchg_pre(void *data, void *evt) +{ + keynode_t *key = evt; + char *region; + char *r; + + region = vconf_keynode_get_str(key); + if (region) { + setenv("LC_CTYPE", region, 1); + setenv("LC_NUMERIC", region, 1); + setenv("LC_TIME", region, 1); + setenv("LC_COLLATE", region, 1); + setenv("LC_MONETARY", region, 1); + setenv("LC_PAPER", region, 1); + setenv("LC_NAME", region, 1); + setenv("LC_ADDRESS", region, 1); + setenv("LC_TELEPHONE", region, 1); + setenv("LC_MEASUREMENT", region, 1); + setenv("LC_IDENTIFICATION", region, 1); + + r = setlocale(LC_ALL, ""); + if (r != NULL) { + _DBG("*****appcore-agent setlocale=%s\n", r); + } + } + + return 0; +} + +static int __sys_regionchg(void *data, void *evt) +{ + keynode_t *key = evt; + char *val = NULL; + const char *name; + + name = vconf_keynode_get_name(key); + if (!strcmp(name, VCONFKEY_REGIONFORMAT)) + val = vconf_keynode_get_str(key); + + return __sys_do(data, (void *)val, SE_REGIONCHG); +} + static void __vconf_do(struct evt_ops *eo, keynode_t * key, void *data) { _ret_if(eo == NULL); @@ -374,7 +495,7 @@ static void __vconf_cb(keynode_t *key, void *data) name = vconf_keynode_get_name(key); _ret_if(name == NULL); - _DBG("[APP %d] vconf changed: %s", _pid, name); + SECURE_LOGD("[APP %d] vconf changed: %s", _pid, name); for (i = 0; i < sizeof(evtops) / sizeof(evtops[0]); i++) { struct evt_ops *eo = &evtops[i]; @@ -391,43 +512,76 @@ static void __vconf_cb(keynode_t *key, void *data) } } -static int __add_vconf(struct agent_appcore *ac) +static int __add_vconf(struct agent_appcore *ac, enum sys_event se) { - int i; int r; - for (i = 0; i < sizeof(evtops) / sizeof(evtops[0]); i++) { - struct evt_ops *eo = &evtops[i]; - - switch (eo->type) { - case _CB_VCONF: - r = vconf_notify_key_changed(eo->key.vkey, __vconf_cb, - ac); - break; - default: - /* do nothing */ + switch (se) { + case SE_LOWMEM: + r = vconf_notify_key_changed(VCONFKEY_SYSMAN_LOW_MEMORY, __vconf_cb, ac); + break; + case SE_LOWBAT: + r = vconf_notify_key_changed(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW, __vconf_cb, ac); + break; + case SE_LANGCHG: + r = vconf_notify_key_changed(VCONFKEY_LANGSET, __vconf_cb, ac); + break; + case SE_REGIONCHG: + r = vconf_notify_key_changed(VCONFKEY_REGIONFORMAT, __vconf_cb, ac); + if (r < 0) break; - } + + r = vconf_notify_key_changed(VCONFKEY_REGIONFORMAT_TIME1224, __vconf_cb, ac); + break; + default: + r = -1; + break; } - return 0; + return r; } -static int __del_vconf(void) +static int __del_vconf(enum sys_event se) { - int i; int r; - for (i = 0; i < sizeof(evtops) / sizeof(evtops[0]); i++) { - struct evt_ops *eo = &evtops[i]; - - switch (eo->type) { - case _CB_VCONF: - r = vconf_ignore_key_changed(eo->key.vkey, __vconf_cb); - break; - default: - /* do nothing */ + switch (se) { + case SE_LOWMEM: + r = vconf_ignore_key_changed(VCONFKEY_SYSMAN_LOW_MEMORY, __vconf_cb); + break; + case SE_LOWBAT: + r = vconf_ignore_key_changed(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW, __vconf_cb); + break; + case SE_LANGCHG: + r = vconf_ignore_key_changed(VCONFKEY_LANGSET, __vconf_cb); + break; + case SE_REGIONCHG: + r = vconf_ignore_key_changed(VCONFKEY_REGIONFORMAT, __vconf_cb); + if (r < 0) break; + + r = vconf_ignore_key_changed(VCONFKEY_REGIONFORMAT_TIME1224, __vconf_cb); + break; + default: + r = -1; + break; + } + + return r; +} + +static int __del_vconf_list(void) +{ + int r; + enum sys_event se; + + for (se = SE_LOWMEM; se < SE_MAX; se++) { + if (appcore_agent_event_initialized[se]) { + r = __del_vconf(se); + if (r < 0) + _ERR("Delete vconf callback failed"); + else + appcore_agent_event_initialized[se] = 0; } } @@ -449,6 +603,7 @@ static int __aul_handler(aul_type type, bundle *b, void *data) break; */ case AUL_TERMINATE: + case AUL_TERMINATE_BGAPP: ret = __agent_terminate(data); break; default: @@ -459,12 +614,39 @@ static int __aul_handler(aul_type type, bundle *b, void *data) return 0; } +static int __get_package_app_name(int pid, char **app_name) +{ + char *name_token = NULL; + char appid[APPID_MAX] = {0}; + int r; + + r = aul_app_get_appid_bypid(pid, appid, APPID_MAX); + if (r != AUL_R_OK) + return -1; + + if (appid[0] == '\0') + return -1; + + name_token = strrchr(appid, '.'); + if (name_token == NULL) + return -1; + + name_token++; + + *app_name = strdup(name_token); + if (*app_name == NULL) + return -1; + + return 0; +} + EXPORT_API int appcore_agent_set_event_callback(enum appcore_agent_event event, int (*cb) (void *, void *), void *data) { struct agent_appcore *ac = &core; struct sys_op *op; enum sys_event se; + int r = 0; for (se = SE_UNKNOWN; se < SE_MAX; se++) { if (event == to_ae[se]) @@ -482,13 +664,30 @@ EXPORT_API int appcore_agent_set_event_callback(enum appcore_agent_event event, op->func = cb; op->data = data; - return 0; + if (op->func && !appcore_agent_event_initialized[se]) { + r = __add_vconf(ac, se); + if (r < 0) + _ERR("Add vconf callback failed"); + else + appcore_agent_event_initialized[se] = 1; + } else if (!op->func && appcore_agent_event_initialized[se]) { + r = __del_vconf(se); + if (r < 0) + _ERR("Delete vconf callback failed"); + else + appcore_agent_event_initialized[se] = 0; + } + + return r; } EXPORT_API int appcore_agent_init(const struct agent_ops *ops, int argc, char **argv) { int r; + char *dirname; + char *app_name = NULL; + int pid; if (core.state != 0) { errno = EALREADY; @@ -500,11 +699,17 @@ EXPORT_API int appcore_agent_init(const struct agent_ops *ops, return -1; } - r = __add_vconf(&core); - if (r == -1) { - _ERR("Add vconf callback failed"); - goto err; - } + pid = getpid(); + r = __get_package_app_name(pid, &app_name); + if (r < 0) + return -1; + + dirname = aul_get_app_root_path(); + SECURE_LOGD("dir : %s", dirname); + SECURE_LOGD("app name : %s", app_name); + r = appcore_set_i18n(app_name, dirname); + free(app_name); + _retv_if(r == -1, -1); r = aul_launch_init(__aul_handler, &core); if (r < 0) { @@ -521,6 +726,7 @@ EXPORT_API int appcore_agent_init(const struct agent_ops *ops, return 0; err: + __del_vconf_list(); //__clear(&core); return -1; } @@ -542,33 +748,48 @@ static int __before_loop(struct agent_priv *agent, int argc, char **argv) if (agent->ops && agent->ops->create) { r = agent->ops->create(agent->ops->data); - if (r == -1) { + if (r < 0) { //appcore_exit(); + if (agent->ops && agent->ops->terminate) + agent->ops->terminate(agent->ops->data); errno = ECANCELED; return -1; } } agent->state = AGS_CREATED; - sysman_inform_backgrd(); return 0; } static void __after_loop(struct agent_priv *agent) { + __del_vconf_list(); priv.state = AGS_DYING; if (agent->ops && agent->ops->terminate) agent->ops->terminate(agent->ops->data); ecore_shutdown(); } - EXPORT_API int appcore_agent_terminate() { + __del_vconf_list(); ecore_main_loop_thread_safe_call_sync((Ecore_Data_Cb)__exit_loop, NULL); return 0; } +EXPORT_API int appcore_agent_terminate_without_restart() +{ + int ret; + + __del_vconf_list(); + ret = aul_terminate_pid_without_restart(getpid()); + if (ret < 0) { + SECURE_LOGD("request failed, but it will be terminated"); + ecore_main_loop_thread_safe_call_sync((Ecore_Data_Cb)__exit_loop, NULL); + } + + return 0; +} EXPORT_API int appcore_agent_main(int argc, char **argv, struct agentcore_ops *ops) diff --git a/src/service_app_error.c b/src/service_app_error.c index cb624c6..b2f7c26 100644 --- a/src/service_app_error.c +++ b/src/service_app_error.c @@ -15,41 +15,40 @@ */ -#include -#include #include #include #include +#include -#include +#include "service_app_private.h" #ifdef LOG_TAG #undef LOG_TAG #endif -#define LOG_TAG "TIZEN_N_AGENT" +#define LOG_TAG "CAPI_APPFW_APPLICATION" -static const char* service_app_error_to_string(service_app_error_e error) +static const char* service_app_error_to_string(app_error_e error) { switch (error) { - case SERVICE_APP_ERROR_NONE: + case APP_ERROR_NONE: return "NONE"; - case SERVICE_APP_ERROR_INVALID_PARAMETER: + case APP_ERROR_INVALID_PARAMETER: return "INVALID_PARAMETER"; - case SERVICE_APP_ERROR_OUT_OF_MEMORY: + case APP_ERROR_OUT_OF_MEMORY: return "OUT_OF_MEMORY"; - case SERVICE_APP_ERROR_INVALID_CONTEXT: + case APP_ERROR_INVALID_CONTEXT: return "INVALID_CONTEXT"; - case SERVICE_APP_ERROR_NO_SUCH_FILE: + case APP_ERROR_NO_SUCH_FILE: return "NO_SUCH_FILE"; - case SERVICE_APP_ERROR_ALREADY_RUNNING: + case APP_ERROR_ALREADY_RUNNING: return "ALREADY_RUNNING"; default : @@ -57,7 +56,7 @@ static const char* service_app_error_to_string(service_app_error_e error) } } -int service_app_error(service_app_error_e error, const char* function, const char *description) +int service_app_error(app_error_e error, const char* function, const char *description) { if (description) { 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 #include -#include -#include -#include -#include -#include #include #include #include +#include +#include + #include #include -#include +#include "service_app_private.h" +#include "service_app_extension.h" + +#include + #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"); } diff --git a/include/service_app_private.h b/src/service_app_private.h similarity index 85% rename from include/service_app_private.h rename to src/service_app_private.h index 0f44311..ba58ecf 100644 --- a/include/service_app_private.h +++ b/src/service_app_private.h @@ -18,16 +18,14 @@ #ifndef __TIZEN_APPFW_SERVICE_APP_PRIVATE_H__ #define __TIZEN_APPFW_SERVICE_APP_PRIVATE_H__ -#include #include +#include #ifdef __cplusplus extern "C" { #endif -#define TIZEN_PATH_MAX 1024 - -int service_app_error(service_app_error_e error, const char* function, const char *description); +int service_app_error(app_error_e error, const char* function, const char *description); #ifdef __cplusplus } diff --git a/test/test.c b/test/test.c index c5d4a54..88cfc15 100644 --- a/test/test.c +++ b/test/test.c @@ -1,64 +1,76 @@ #include -#include #include -#include +#include #undef LOG_TAG -#define LOG_TAG "AGENT_TEST" +#define LOG_TAG "SERVICE_APP_TEST" -static int __agent_create(void *data) +static bool __service_app_create(void *data) { - /*struct appdata *ad = data; */ - LOGD("__agent_create"); + LOGD("__service_app_create"); // Todo: add your code here. - return 0; + return true; } - -static int __agent_terminate(void *data) +static void __service_app_terminate(void *data) { - /*struct appdata *ad = data; */ - LOGD("__agent_terminate"); + LOGD("__service_app_terminate"); // Todo: add your code here. - return 0; + return; } -static void __bundle_iterate(const char *key, const char *val, void *data) +static void __service_app_service(app_control_h app_control, void *data) { - static int i=0; - LOGD("%d %s %s", i++, key, val); -} + LOGD("__service_app_service"); + char *test_data = (char*)data; + LOGD("requset : %s", test_data); -static int __agent_reset(bundle* b, void *data) + // Todo: add your code here. + + return; +} + +static void __service_app_low_memory_cb(void *data) { - /*struct appdata *ad = data; */ - char *test_data = (char*)data; + LOGD("__service_app_low_memory_cb"); - LOGD("requset : %s", test_data); + // Todo: add your code here. + + service_app_exit(); + + return; +} - bundle_iterate(b, __bundle_iterate, NULL); +static void __service_app_low_battery_cb(void *data) +{ + LOGD("__service_app_low_memory_cb"); // Todo: add your code here. - return 0; + service_app_exit(); + + return; } int main(int argc, char* argv[]) { char ad[50] = "test data"; + service_app_event_callback_s ops; - struct agentcore_ops ops = { - .create = __agent_create, - .terminate = __agent_terminate, - .reset = __agent_reset, - }; + LOGD("main"); + memset(&ops, 0x00, sizeof(service_app_event_callback_s)); - ops.data = ad; + ops.create = (service_app_create_cb)__service_app_create; + ops.terminate = (service_app_terminate_cb)__service_app_terminate; + ops.service = (service_app_control_cb)__service_app_service; + ops.low_memory = (service_app_low_memory_cb)__service_app_low_memory_cb; + ops.low_battery = (service_app_low_battery_cb)__service_app_low_battery_cb; - appcore_agent_main(argc, argv, &ops); + return service_app_main(argc, argv, &ops, ad); } + -- 2.7.4