summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJunghoon Park <jh9216.park@samsung.com>2016-02-26 12:05:16 +0900
committerJunghoon Park <jh9216.park@samsung.com>2016-02-26 12:05:16 +0900
commit6da415468de37b23b71466d7284e6c6f276a5c23 (patch)
treec6deeaa790edeff3982f22e7160d07ad4bd5d0dd
parentcab537ab51b5dcc40b6001632fc8bf7f2bec5308 (diff)
downloadaul-1-6da415468de37b23b71466d7284e6c6f276a5c23.tar.gz
aul-1-6da415468de37b23b71466d7284e6c6f276a5c23.tar.bz2
aul-1-6da415468de37b23b71466d7284e6c6f276a5c23.zip
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 <jh9216.park@samsung.com>
-rw-r--r--include/aul.h7
-rw-r--r--src/launch_with_result.c173
2 files changed, 125 insertions, 55 deletions
diff --git a/include/aul.h b/include/aul.h
index 5142e816..b6f10563 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 d22613fd..05cb4829 100644
--- a/src/launch_with_result.c
+++ b/src/launch_with_result.c
@@ -18,7 +18,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <pthread.h>
#include <bundle_internal.h>
@@ -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;