From 6da415468de37b23b71466d7284e6c6f276a5c23 Mon Sep 17 00:00:00 2001 From: Junghoon Park Date: Fri, 26 Feb 2016 12:05:16 +0900 Subject: [PATCH] Support multiple launch requests for the result to the same process - Because AUL maintained the callback contexts by pid, there was no way to call the right callback function which had been registered by caller. Change-Id: Ib65c576f19c700c6991ddcd16e0e355a3be0b166 Signed-off-by: Junghoon Park --- include/aul.h | 7 +- src/launch_with_result.c | 173 ++++++++++++++++++++++++++++++++--------------- 2 files changed, 125 insertions(+), 55 deletions(-) diff --git a/include/aul.h b/include/aul.h index 5142e81..b6f1056 100644 --- a/include/aul.h +++ b/include/aul.h @@ -184,8 +184,11 @@ typedef enum _aul_type{ /** AUL internal private key */ #define AUL_K_ROOT_PATH "__AUL_ROOT_PATH__" /** AUL internal private key */ +#define AUL_K_SEQ_NUM "__AUL_SEQ_NUM__" +/** AUL internal private key */ #define AUL_K_API_VERSION "__AUL_API_VERSION__" + /** * @brief This is callback function for aul_launch_init * @param[in] type event's type received from system @@ -1775,12 +1778,12 @@ int aul_add_caller_cb(int pid, void (*caller_cb) (int, void *), void *data); /* * This API is only for Appfw internally. */ -int aul_remove_caller_cb(int pid); +int aul_remove_caller_cb(int pid, void *data); /* * This API is only for Appfw internally. */ -int aul_invoke_caller_cb(int pid); +int aul_invoke_caller_cb(void *data); /* * This API is only for Appfw internally. diff --git a/src/launch_with_result.c b/src/launch_with_result.c index d22613f..05cb482 100644 --- a/src/launch_with_result.c +++ b/src/launch_with_result.c @@ -18,7 +18,6 @@ #include #include #include -#include #include @@ -32,6 +31,7 @@ typedef struct _app_resultcb_info_t { int launched_pid; + int seq_num; void (*cb_func) (bundle *kb, int is_cancel, void *data); void *priv_data; void (*caller_cb) (int launched_pid, void *data); @@ -41,25 +41,19 @@ typedef struct _app_resultcb_info_t { static int latest_caller_pid = -1; static app_resultcb_info_t *rescb_head = NULL; - static int is_subapp = 0; -subapp_fn subapp_cb = NULL; -void *subapp_data = NULL; - -pthread_mutex_t result_lock = PTHREAD_MUTEX_INITIALIZER; - -static void __add_resultcb(int pid, void (*cbfunc) (bundle *, int, void *), - void *data); -static app_resultcb_info_t *__find_resultcb(int pid); -static void __remove_resultcb(app_resultcb_info_t *info); -static int __call_app_result_callback(bundle *kb, int is_cancel, - int launched_pid); -static int __get_caller_pid(bundle *kb); +static subapp_fn subapp_cb = NULL; +static void *subapp_data = NULL; +static int __gen_seq_num(void) +{ + static int num = 0; + return num++; +} static void __add_resultcb(int pid, void (*cbfunc) (bundle *, int, void *), - void *data) + void *data, int seq_num) { app_resultcb_info_t *info; @@ -67,6 +61,7 @@ static void __add_resultcb(int pid, void (*cbfunc) (bundle *, int, void *), if (info == NULL) return; info->launched_pid = pid; + info->seq_num = seq_num; info->cb_func = cbfunc; info->priv_data = data; info->caller_cb = NULL; @@ -76,21 +71,56 @@ static void __add_resultcb(int pid, void (*cbfunc) (bundle *, int, void *), rescb_head = info; } -static app_resultcb_info_t *__find_resultcb(int pid) +static app_resultcb_info_t *__find_resultcb(int pid, bundle *kb) +{ + app_resultcb_info_t *tmp; + const char *num_str; + int num; + + num_str = bundle_get_val(kb, AUL_K_SEQ_NUM); + if (num_str == NULL) { + _E("No AUL_K_SEQ_NUM"); + return NULL; + } + num = atoi(num_str); + tmp = rescb_head; + while (tmp) { + if (tmp->launched_pid == pid && tmp->seq_num == num) + return tmp; + tmp = tmp->next; + } + + return NULL; +} + +static app_resultcb_info_t *__get_first_resultcb(int pid) { app_resultcb_info_t *tmp; - app_resultcb_info_t *ret = NULL; - pthread_mutex_lock(&result_lock); tmp = rescb_head; while (tmp) { if (tmp->launched_pid == pid) - ret = tmp; + return tmp; tmp = tmp->next; } - pthread_mutex_unlock(&result_lock); - return ret; + return NULL; +} + +static app_resultcb_info_t *__get_next_resultcb(app_resultcb_info_t *info, int pid) +{ + app_resultcb_info_t *tmp; + + if (info == NULL) + return NULL; + tmp = info->next; + while (tmp) { + if (tmp->launched_pid == pid) + return tmp; + tmp = tmp->next; + } + + return NULL; } static void __remove_resultcb(app_resultcb_info_t *info) @@ -126,9 +156,11 @@ static int __call_app_result_callback(bundle *kb, int is_cancel, { app_resultcb_info_t *info; int pgid; - char *fwdpid_str; + const char *fwdpid_str; + const char *num_str; - if (((info = __find_resultcb(launched_pid)) == NULL) + + if (((info = __find_resultcb(launched_pid, kb)) == NULL) || (launched_pid < 0)) { _E("reject by pid - wait pid = %d, recvd pid = %d\n", getpid(), launched_pid); @@ -137,7 +169,7 @@ static int __call_app_result_callback(bundle *kb, int is_cancel, pgid = getpgid(launched_pid); if (pgid <= 1) return -1; - if ((info = __find_resultcb(pgid)) == NULL) { + if ((info = __find_resultcb(pgid, kb)) == NULL) { _E("second chance : also reject pgid - %d\n", pgid); return -1; } @@ -148,9 +180,16 @@ static int __call_app_result_callback(bundle *kb, int is_cancel, /* In case of aul_forward_app, update the callback data */ if (is_cancel == 1 && - (fwdpid_str = (char *)bundle_get_val(kb, AUL_K_FWD_CALLEE_PID))) { + (fwdpid_str = bundle_get_val(kb, AUL_K_FWD_CALLEE_PID))) { + num_str = bundle_get_val(kb, AUL_K_SEQ_NUM); + if (num_str == NULL) { + _E("seq num is null"); + return -1; + } + app_resultcb_info_t newinfo; newinfo.launched_pid = atoi(fwdpid_str); + newinfo.seq_num = atoi(num_str); newinfo.cb_func = info->cb_func; newinfo.priv_data = info->priv_data; newinfo.caller_cb = NULL; @@ -160,7 +199,7 @@ static int __call_app_result_callback(bundle *kb, int is_cancel, info->caller_cb(newinfo.launched_pid, info->caller_data); __remove_resultcb(info); - __add_resultcb(newinfo.launched_pid, newinfo.cb_func, newinfo.priv_data); + __add_resultcb(newinfo.launched_pid, newinfo.cb_func, newinfo.priv_data, newinfo.seq_num); _D("change callback, fwd pid: %d", newinfo.launched_pid); @@ -271,6 +310,8 @@ API int aul_launch_app_with_result(const char *pkgname, bundle *kb, void *data) { int ret; + char num_str[MAX_LOCAL_BUFSZ] = { 0, }; + int num; if (!aul_is_initialized()) { if (aul_launch_init(NULL, NULL) < 0) @@ -280,12 +321,15 @@ API int aul_launch_app_with_result(const char *pkgname, bundle *kb, if (pkgname == NULL || cbfunc == NULL || kb == NULL) return AUL_R_EINVAL; - pthread_mutex_lock(&result_lock); + num = __gen_seq_num(); + snprintf(num_str, MAX_LOCAL_BUFSZ, "%d", num); + bundle_del(kb, AUL_K_SEQ_NUM); + bundle_add(kb, AUL_K_SEQ_NUM, num_str); + ret = app_request_to_launchpad(APP_START_RES, pkgname, kb); if (ret > 0) - __add_resultcb(ret, cbfunc, data); - pthread_mutex_unlock(&result_lock); + __add_resultcb(ret, cbfunc, data, num); return ret; } @@ -357,6 +401,7 @@ end: API int aul_create_result_bundle(bundle *inb, bundle **outb) { const char *pid_str; + const char *num_str; *outb = NULL; @@ -387,13 +432,22 @@ API int aul_create_result_bundle(bundle *inb, bundle **outb) pid_str = bundle_get_val(inb, AUL_K_CALLER_PID); if (pid_str == NULL) { - _E("original msg doest not have caller pid"); + _E("original msg does not have caller pid"); bundle_free(*outb); *outb = NULL; return AUL_R_EINVAL; } bundle_add(*outb, AUL_K_CALLER_PID, pid_str); + num_str = bundle_get_val(inb, AUL_K_SEQ_NUM); + if (num_str == NULL) { + _E("original msg does not have seq num"); + bundle_free(*outb); + *outb = NULL; + return AUL_R_EINVAL; + } + bundle_add(*outb, AUL_K_SEQ_NUM, num_str); + end: return AUL_R_OK; } @@ -466,9 +520,11 @@ API int aul_subapp_terminate_request_pid(int pid) if (pid <= 0) return AUL_R_EINVAL; - info = __find_resultcb(pid); - if (info) + info = __get_first_resultcb(pid); + while (info != NULL) { __remove_resultcb(info); + info = __get_first_resultcb(pid); + } snprintf(pid_str, MAX_PID_STR_BUFSZ, "%d", pid); ret = app_request_to_launchpad(APP_TERM_REQ_BY_PID, pid_str, NULL); @@ -487,53 +543,64 @@ API int aul_add_caller_cb(int pid, void (*caller_cb) (int, void *), void *data) if (pid <= 0) return AUL_R_EINVAL; - info = __find_resultcb(pid); + info = __get_first_resultcb(pid); if (info == NULL) return AUL_R_ERROR; - info->caller_cb = caller_cb; - info->caller_data = data; + while (info != NULL) { + if (info->caller_cb == NULL) { + info->caller_cb = caller_cb; + info->caller_data = data; + return AUL_R_OK; + } + info = __get_next_resultcb(info, pid); + } - return AUL_R_OK; + return AUL_R_ERROR; } -API int aul_remove_caller_cb(int pid) +API int aul_remove_caller_cb(int pid, void *data) { app_resultcb_info_t *info; if (pid <= 0) return AUL_R_EINVAL; - info = __find_resultcb(pid); + info = __get_first_resultcb(pid); if (info == NULL) return AUL_R_ERROR; - info->caller_cb = NULL; - info->caller_data = NULL; + while (info != NULL) { + if (info->caller_data == data) { + info->caller_cb = NULL; + info->caller_data = NULL; + return AUL_R_OK; + } + info = __get_next_resultcb(info, pid); + } - return AUL_R_OK; + return AUL_R_ERROR; } static gboolean __invoke_caller_cb(gpointer data) { - int launched_pid = 0; - app_resultcb_info_t *info; - - if (data == NULL) - return G_SOURCE_REMOVE; - - launched_pid = GPOINTER_TO_INT(data); + app_resultcb_info_t *tmp; - info = __find_resultcb(launched_pid); - if (info && info->caller_cb) - info->caller_cb(info->launched_pid, info->caller_data); + tmp = rescb_head; + while (tmp) { + if (tmp->caller_data == data && tmp->caller_cb) { + tmp->caller_cb(tmp->launched_pid, tmp->caller_data); + break; + } + tmp = tmp->next; + } return G_SOURCE_REMOVE; } -API int aul_invoke_caller_cb(int pid) +API int aul_invoke_caller_cb(void *data) { - if (g_idle_add_full(G_PRIORITY_DEFAULT, __invoke_caller_cb, GINT_TO_POINTER(pid), NULL) > 0) + if (g_idle_add_full(G_PRIORITY_DEFAULT, __invoke_caller_cb, data, NULL) > 0) return -1; return 0; -- 2.7.4