Fix bug on event handler 33/139533/1
authorjongmyeongko <jongmyeong.ko@samsung.com>
Wed, 19 Jul 2017 08:38:11 +0000 (17:38 +0900)
committerjongmyeongko <jongmyeong.ko@samsung.com>
Wed, 19 Jul 2017 08:38:11 +0000 (17:38 +0900)
For global handler, the user callback can be called twice with FAILED state.
For request handler, the user callback can be called with COMPLETED state
after call with FAILED. (known bug of global handler)

Change-Id: I1ffe83b686c0a344f68cca86fd1bf0eb14a7682c
Signed-off-by: jongmyeongko <jongmyeong.ko@samsung.com>
src/package_manager.c

index 116d0b2..3adfabb 100644 (file)
@@ -40,6 +40,7 @@ typedef struct _request_event_info {
 struct package_manager_event_info {
        char *pkg_name;
        package_manager_event_type_e event_type;
+       package_manager_event_state_e event_state;
 };
 
 struct package_manager_s {
@@ -117,7 +118,8 @@ static void __clean_all_event_info(request_event_info *head)
 }
 
 static int __insert_event_info(package_manager_h manager, const char *pkg_name,
-                       package_manager_event_type_e event_type)
+                       package_manager_event_type_e event_type,
+                       package_manager_event_state_e event_state)
 {
        struct package_manager_event_info *info;
 
@@ -126,6 +128,7 @@ static int __insert_event_info(package_manager_h manager, const char *pkg_name,
                return -1;
        info->pkg_name = strdup(pkg_name);
        info->event_type = event_type;
+       info->event_state = event_state;
        g_hash_table_insert(manager->event_info_table, info->pkg_name, info);
 
        return 0;
@@ -379,6 +382,7 @@ static int __add_event_info(request_event_info **head, int req_id,
        }
        evt_info->req_id = req_id;
        evt_info->event_type = event_type;
+       evt_info->event_state = event_state;
        evt_info->next = NULL;
 
        if (*head == NULL)
@@ -412,6 +416,7 @@ static int __find_event_info(request_event_info **head, int req_id,
        while (tmp) {
                if (tmp->req_id == req_id) {
                        *event_type = tmp->event_type;
+                       *event_state = tmp->event_state;
                        return 0;
                }
                tmp = tmp->next;
@@ -440,6 +445,7 @@ static int __update_event_info(request_event_info **head, int req_id,
                while (tmp) {
                        if (tmp->req_id == req_id) {
                                tmp->event_type = event_type;
+                               tmp->event_state = event_state;
                                return 0;
                        }
                        tmp = tmp->next;
@@ -491,24 +497,22 @@ static int request_event_handler(uid_t target_uid, int req_id, const char *pkg_t
                }
 
        } else if (strcasecmp(key, "error") == 0) {
-               if (strcasecmp(key, "0") != 0) {
-                       if (__find_event_info
-                           (&(request->head), req_id, &event_type,
-                            &event_state) == 0) {
-                               __update_event_info(&(request->head), req_id,
-                                                   event_type,
-                                                   PACKAGE_MANAGER_EVENT_STATE_FAILED);
-                       }
+               if (__find_event_info
+                   (&(request->head), req_id, &event_type,
+                    &event_state) == 0) {
+                       __update_event_info(&(request->head), req_id,
+                                           event_type,
+                                           PACKAGE_MANAGER_EVENT_STATE_FAILED);
+               }
 
-                       if (request->event_cb)
-                               request->event_cb(req_id, pkg_type,
-                                                 pkg_name, event_type,
-                                                 PACKAGE_MANAGER_EVENT_STATE_FAILED,
-                                                 0,
-                                                 PACKAGE_MANAGER_ERROR_NONE,
-                                                 request->user_data);
+               if (request->event_cb)
+                       request->event_cb(req_id, pkg_type,
+                                         pkg_name, event_type,
+                                         PACKAGE_MANAGER_EVENT_STATE_FAILED,
+                                         0,
+                                         PACKAGE_MANAGER_ERROR_NONE,
+                                         request->user_data);
 
-               }
        } else if (strcasecmp(key, "end") == 0) {
                if (__find_event_info
                    (&(request->head), req_id, &event_type,
@@ -1009,7 +1013,6 @@ static int internal_callback(uid_t target_uid, int req_id, const char *pkg_type,
 {
        int ret = -1;
        package_manager_event_type_e event_type = -1;
-       package_manager_event_state_e event_state = -1;
        struct package_manager_event_info *info = NULL;
        package_manager_h manager = data;
        uid_t uid = target_uid;
@@ -1043,7 +1046,8 @@ static int internal_callback(uid_t target_uid, int req_id, const char *pkg_type,
                        return PACKAGE_MANAGER_ERROR_INVALID_PARAMETER;
 
                if (!info) {
-                       __insert_event_info(manager, pkg_name, event_type);
+                       __insert_event_info(manager, pkg_name, event_type,
+                                       PACKAGE_MANAGER_EVENT_STATE_STARTED);
 
                        if (manager->event_cb && getuid() == uid)
                                manager->event_cb(pkg_type, pkg_name,
@@ -1057,23 +1061,25 @@ static int internal_callback(uid_t target_uid, int req_id, const char *pkg_type,
                }
        } else if (strcasecmp(key, "install_percent") == 0
                   || strcasecmp(key, "progress_percent") == 0) {
+               info->event_state = PACKAGE_MANAGER_EVENT_STATE_PROCESSING;
                if (manager->event_cb && getuid() == uid)
                        manager->event_cb(pkg_type, pkg_name,
                                        info->event_type,
-                                       PACKAGE_MANAGER_EVENT_STATE_PROCESSING,
+                                       info->event_state,
                                        atoi(val),
                                        PACKAGE_MANAGER_ERROR_NONE,
                                        manager->user_data);
        } else if (strcasecmp(key, "error") == 0) {
+               info->event_state = PACKAGE_MANAGER_EVENT_STATE_FAILED;
                if (manager->event_cb && getuid() == uid)
                        manager->event_cb(pkg_type, pkg_name,
                                        info->event_type,
-                                       PACKAGE_MANAGER_EVENT_STATE_FAILED,
+                                       info->event_state,
                                        0,
                                        PACKAGE_MANAGER_ERROR_NONE,
                                        manager->user_data);
        } else if (strcasecmp(key, "end") == 0) {
-               if (event_state != PACKAGE_MANAGER_EVENT_STATE_FAILED) {
+               if (info->event_state != PACKAGE_MANAGER_EVENT_STATE_FAILED) {
                        if (manager->event_cb && getuid() == uid) {
                                if (strcasecmp(val, "ok") == 0) {
                                        manager->event_cb(pkg_type, pkg_name,