summaryrefslogtreecommitdiff
path: root/src/service_app_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/service_app_main.c')
-rw-r--r--src/service_app_main.c490
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");
}