Support multiple launch requests for the result to the same process 75/60075/8
authorJunghoon Park <jh9216.park@samsung.com>
Fri, 26 Feb 2016 03:05:16 +0000 (12:05 +0900)
committerJunghoon Park <jh9216.park@samsung.com>
Fri, 26 Feb 2016 03:05:16 +0000 (12:05 +0900)
- 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>
include/aul.h
src/launch_with_result.c

index 5142e81..b6f1056 100644 (file)
@@ -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.
index d22613f..05cb482 100644 (file)
@@ -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;