summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/appcore-agent.c305
-rw-r--r--src/service_app_error.c23
-rw-r--r--src/service_app_main.c490
-rw-r--r--src/service_app_private.h34
4 files changed, 640 insertions, 212 deletions
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 <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
+#include <malloc.h>
#include <Ecore.h>
+#include <linux/limits.h>
-#include <sysman.h>
#include "aul.h"
#include "appcore-agent.h"
+#include <appcore-common.h>
#include <app_control_internal.h>
#include <dlog.h>
#include <vconf.h>
@@ -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 <stdio.h>
-#include <stdlib.h>
#include <string.h>
#include <libintl.h>
#include <dlog.h>
+#include <app_common.h>
-#include <service_app_private.h>
+#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 <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");
}
diff --git a/src/service_app_private.h b/src/service_app_private.h
new file mode 100644
index 0000000..ba58ecf
--- /dev/null
+++ b/src/service_app_private.h
@@ -0,0 +1,34 @@
+/*
+ * 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_PRIVATE_H__
+#define __TIZEN_APPFW_SERVICE_APP_PRIVATE_H__
+
+#include <service_app.h>
+#include <app_common.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int service_app_error(app_error_e error, const char* function, const char *description);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TIZEN_APPFW_SERVICE_APP_PRIVATE_H__ */