Modify app_context_set_status_cb API 72/125772/5
authorHwankyu Jhun <h.jhun@samsung.com>
Tue, 18 Apr 2017 23:27:15 +0000 (08:27 +0900)
committerHwankyu Jhun <h.jhun@samsung.com>
Wed, 19 Apr 2017 01:32:39 +0000 (10:32 +0900)
Requires:
 - https://review.tizen.org/gerrit/#/c/125770/

Change-Id: I251c53c5474eb30acaa5013731fc78577a67f1d8
Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
include/app_manager_extension.h
src/app_context.c

index 2abe3e521a9e563bf7aa8afc755090b891a21550..98b8fc91066a82b3ce172424bb21b463f639c374 100644 (file)
@@ -98,6 +98,7 @@ int app_manager_set_splash_screen_display(const char *app_id, bool display);
  * @retval     #APP_MANAGER_ERROR_NONE                 Successful
  * @retval     #APP_MANAGER_ERROR_INVALID_PARAMETER    Invalid parameter
  * @retval     #APP_MANAGER_ERROR_IO_ERROR             Internal I/O error
+ * @retval      #APP_MANAGER_ERROR_OUT_OF_MEMORY        Out of memory
  * @post It will invoke app_manager_app_context_event_cb() when the application is launched or terminated.
  * @see app_manager_app_context_status_cb()
  */
index 671ab1a29724214d8301a2353f2a4283bd99c699..c312ced9b5fcb8a620170859c642849f7b4a8254 100644 (file)
@@ -66,7 +66,14 @@ typedef struct _retrieval_context_ {
        const char *instance_id;
 } retrieval_context_s;
 
-static app_manager_app_context_status_cb _status_cb;
+struct status_listen_info {
+       status_listen_h handle;
+       char *appid;
+       app_manager_app_context_status_cb callback;
+       void *user_data;
+};
+
+static GList *status_listen_list;
 
 static app_state_e app_context_get_app_status(int status)
 {
@@ -625,24 +632,78 @@ void app_context_unset_event_cb(void)
        app_context_unlock_event_cb_context();
 }
 
-static int app_context_status_cb(const char *appid, const char *pkgid, int pid, int status, int is_subapp, void *data)
+static struct status_listen_info *__find_status_listen_info(app_manager_app_context_status_cb callback, const char *appid)
+{
+       struct status_listen_info *info;
+       GList *iter;
+
+       iter = g_list_first(status_listen_list);
+       while (iter) {
+               info = (struct status_listen_info *)iter->data;
+               if (info && info->callback == callback && !strcmp(info->appid, appid))
+                       return info;
+               iter = g_list_next(iter);
+       }
+
+       return NULL;
+}
+
+static struct status_listen_info *__create_status_listen_info(app_manager_app_context_status_cb callback, const char *appid, void *user_data)
 {
+       struct status_listen_info *info;
+
+       info = calloc(1, sizeof(struct status_listen_info));
+       if (info == NULL) {
+               LOGE("Out of memory");
+               return NULL;
+       }
+
+       info->appid = strdup(appid);
+       if (info->appid == NULL) {
+               LOGE("Out of memory");
+               free(info);
+               return NULL;
+       }
+
+       info->callback = callback;
+       info->user_data = user_data;
+
+       return info;
+}
+
+static void __destroy_status_listen_info(struct status_listen_info *info)
+{
+       if (info == NULL)
+               return;
+
+       if (info->appid)
+               free(info->appid);
+       free(info);
+}
+
+static int app_context_status_cb(aul_app_info *aul_app_context, int ctx_status, void *data)
+{
+       struct status_listen_info *info = (struct status_listen_info *)data;
        app_context_h app_context = NULL;
-       app_state_e state;
        app_context_status_e context_status;
        int ret;
 
-       state = app_context_get_app_status(status);
-       if (state == APP_STATE_TERMINATED)
+       if (ctx_status == STATUS_TERMINATE)
                context_status = APP_CONTEXT_STATUS_TERMINATED;
        else
                context_status = APP_CONTEXT_STATUS_LAUNCHED;
 
-       ret = app_context_create(appid, pid, pkgid, state, is_subapp, NULL, &app_context);
+       ret = app_context_create(aul_app_context->appid,
+                       aul_app_context->pid,
+                       aul_app_context->pkgid,
+                       app_context_get_app_status(aul_app_context->status),
+                       aul_app_context->is_sub_app,
+                       aul_app_context->instance_id,
+                       &app_context);
        if (ret != APP_MANAGER_ERROR_NONE)
                return app_manager_error(ret, __FUNCTION__, NULL);
 
-       _status_cb(app_context, context_status, data);
+       info->callback(app_context, context_status, info->user_data);
        app_context_destroy(app_context);
 
        return APP_MANAGER_ERROR_NONE;
@@ -651,26 +712,33 @@ static int app_context_status_cb(const char *appid, const char *pkgid, int pid,
 int app_context_set_status_cb(app_manager_app_context_status_cb callback, const char *appid, void *user_data)
 {
        int ret;
+       struct status_listen_info *info;
 
        if (callback == NULL || appid == NULL)
-               return app_manager_error(APP_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
+               return APP_MANAGER_ERROR_INVALID_PARAMETER;
 
-       _status_cb = callback;
+       info = __find_status_listen_info(callback, appid);
+       if (info) {
+               info->user_data = user_data;
+               return APP_MANAGER_ERROR_NONE;
+       }
 
-       ret = aul_listen_app_status(appid, app_context_status_cb, user_data);
-       switch (ret) {
-       case AUL_R_OK:
-               ret = APP_MANAGER_ERROR_NONE;
-               break;
-       case AUL_R_EINVAL:
-               ret = APP_MANAGER_ERROR_INVALID_PARAMETER;
-               break;
-       default:
-               ret = APP_MANAGER_ERROR_IO_ERROR;
-               break;
+       info = __create_status_listen_info(callback, appid, user_data);
+       if (info == NULL)
+               return APP_MANAGER_ERROR_OUT_OF_MEMORY;
+
+       ret = aul_listen_app_status(appid, app_context_status_cb, info, &info->handle);
+       if (ret != AUL_R_OK) {
+               __destroy_status_listen_info(info);
+               if (ret == AUL_R_EINVAL)
+                       return APP_MANAGER_ERROR_INVALID_PARAMETER;
+
+               return APP_MANAGER_ERROR_IO_ERROR;
        }
 
-       return ret;
+       status_listen_list = g_list_append(status_listen_list, info);
+
+       return APP_MANAGER_ERROR_NONE;
 }
 
 int app_context_get_app_context_by_instance_id(const char *app_id, const char *instance_id, app_context_h *app_context)