From b0c146bfd43643beffa8214a0fb79b7b1de3b468 Mon Sep 17 00:00:00 2001 From: Ilho Kim Date: Mon, 6 Sep 2021 11:15:22 +0900 Subject: [PATCH] Add api for resource event path state Change-Id: I617c2b70e71b939e1f8831507781e9c16702da19 Signed-off-by: Ilho Kim --- client/include/package-manager.h | 60 ++++++++++++++++++++++++++++++--- client/src/pkgmgr.c | 63 +++++++++++++++++++++++++++++++++++ client/src/pkgmgr_client_connection.c | 32 +++++++++++++++--- installer/pkgmgr_installer.c | 48 ++++++++++++++++++++++---- types/include/package-manager-types.h | 4 --- 5 files changed, 188 insertions(+), 19 deletions(-) diff --git a/client/include/package-manager.h b/client/include/package-manager.h index a246644..84e476a 100644 --- a/client/include/package-manager.h +++ b/client/include/package-manager.h @@ -55,6 +55,8 @@ #include #include +#include + #ifdef __cplusplus extern "C" { #endif @@ -177,12 +179,28 @@ typedef enum { PM_UPDATEINFO_TYPE_OPTIONAL } pkgmgr_updateinfo_type; +typedef enum { + PM_RES_EVENT_PATH_STATE_NONE = 0, + PM_RES_EVENT_PATH_STATE_OK, + PM_RES_EVENT_PATH_STATE_FAILED +} pkgmgr_res_event_path_state; + typedef struct { char *pkgid; char *version; pkgmgr_updateinfo_type type; } pkg_update_info_t; +typedef struct _pkgmgr_res_event_info_t { + int error_code; + GList *path_states; +} pkgmgr_res_event_info_t; + +typedef struct _res_event_path_state_t { + const char *path; + pkgmgr_res_event_path_state state; +} res_event_path_state_t; + typedef int (*pkgmgr_iter_fn)(const char *pkg_type, const char *pkgid, const char *version, void *data); @@ -204,6 +222,9 @@ typedef void (*pkgmgr_res_handler)(uid_t target_uid, int req_id, const char *pkgid, const char *request_type, const char *status, pkgmgr_res_event_info *handle, void *user_data); +typedef int (*pkgmgr_res_event_path_cb)(const char *path, + pkgmgr_res_event_path_state state, void *user_data); + typedef enum { PC_REQUEST = 0, PC_LISTENING, @@ -1352,7 +1373,7 @@ pkgmgr_res_event_info *pkgmgr_res_event_info_new(); int pkgmgr_res_event_info_free(pkgmgr_res_event_info *info); /** - * @brief This API gets the error code from resource callback handle + * @brief This API sets the error code to resource event info handle. * * This API is for package-manager client application.\n * @@ -1361,10 +1382,11 @@ int pkgmgr_res_event_info_free(pkgmgr_res_event_info *info); * @retval PKGMGR_R_OK success * @retval PKGMGR_R_EINVAL invalid argument */ -int pkgmgr_res_event_info_set_error_code(pkgmgr_res_event_info *handle, int error_code); +int pkgmgr_res_event_info_set_error_code(pkgmgr_res_event_info *handle, + int error_code); /** - * @brief This API gets the error code from resource callback handle + * @brief This API gets the error code from resource event info handle. * * This API is for package-manager client application.\n * @@ -1373,7 +1395,37 @@ int pkgmgr_res_event_info_set_error_code(pkgmgr_res_event_info *handle, int erro * @retval PKGMGR_R_OK success * @retval PKGMGR_R_EINVAL invalid argument */ -int pkgmgr_res_event_info_get_error_code(pkgmgr_res_event_info *handle, int *error_code); +int pkgmgr_res_event_info_get_error_code(pkgmgr_res_event_info *handle, + int *error_code); + +/** + * @brief This API adds the path state to resource event info handle. + * + * This API is for package-manager client application.\n + * + * @param[in] handle resource event information handle + * @param[in] path path related resource event + * @param[in] state state of the path + * @retval PKGMGR_R_OK success + * @retval PKGMGR_R_EINVAL invalid argument + * @retval PKGMGR_R_ENOMEM out of memory +*/ +int pkgmgr_res_event_info_add_path_state(pkgmgr_res_event_info *handle, + const char *path, pkgmgr_res_event_path_state state); + +/** + * @brief This API retrieve the path state from resource callback handle. + * + * This API is for package-manager client application.\n + * + * @param[in] handle resource event information handle + * @param[in] callback callback to be invoked for each retrieved path + * @param[in] user_data User data to be passed to the callback function + * @retval PKGMGR_R_OK success + * @retval PKGMGR_R_EINVAL invalid argument +*/ +int pkgmgr_res_event_info_foreach_path(pkgmgr_res_event_info *handle, + pkgmgr_res_event_path_cb callback, void *user_data); /** @} */ diff --git a/client/src/pkgmgr.c b/client/src/pkgmgr.c index ae55972..5094f1d 100644 --- a/client/src/pkgmgr.c +++ b/client/src/pkgmgr.c @@ -3059,6 +3059,17 @@ API pkgmgr_res_event_info *pkgmgr_res_event_info_new() return (pkgmgr_res_event_info *)info; } +static void __free_path_states(gpointer data) +{ + res_event_path_state_t *path_state = (res_event_path_state_t *)data; + + if (path_state == NULL) + return; + if (path_state->path) + free(path_state->path); + free(path_state); +} + API int pkgmgr_res_event_info_free(pkgmgr_res_event_info *info) { pkgmgr_res_event_info_t *event_info = @@ -3069,6 +3080,8 @@ API int pkgmgr_res_event_info_free(pkgmgr_res_event_info *info) return PKGMGR_R_EINVAL; } + if (event_info->path_states) + g_list_free_full(event_info->path_states, __free_path_states); free(event_info); return PKGMGR_R_OK; @@ -3097,3 +3110,53 @@ API int pkgmgr_res_event_info_get_error_code(pkgmgr_res_event_info *handle, int *error_code = info->error_code; return PKGMGR_R_OK; } + +API int pkgmgr_res_event_info_add_path_state(pkgmgr_res_event_info *handle, + const char *path, pkgmgr_res_event_path_state state) +{ + pkgmgr_res_event_info_t *info = handle; + res_event_path_state_t *path_state; + + if (info == NULL || path == NULL) { + ERR("invalid parameter"); + return PKGMGR_R_EINVAL; + } + + path_state = calloc(1, sizeof(res_event_path_state_t)); + if (path_state == NULL) { + ERR("out of memory"); + return PKGMGR_R_ENOMEM; + } + + path_state->path = strdup(path); + if (path_state->path == NULL) { + ERR("out of memory"); + return PKGMGR_R_ENOMEM; + } + path_state->state = state; + + info->path_states = g_list_prepend(info->path_states , path_state); + return PKGMGR_R_OK; +} + +API int pkgmgr_res_event_info_foreach_path(pkgmgr_res_event_info *handle, + pkgmgr_res_event_path_cb callback, void *user_data) +{ + pkgmgr_res_event_info_t *info = handle; + GList *list; + res_event_path_state_t *path_state; + + if (info == NULL) { + ERR("invalid parameter"); + return PKGMGR_R_EINVAL; + } + + for (list = info->path_states; list != NULL; list = list->next) { + path_state = (res_event_path_state_t *)list->data; + if (callback(path_state->path, path_state->state, + user_data) < 0) + return PKGMGR_R_OK; + } + + return PKGMGR_R_OK; +} diff --git a/client/src/pkgmgr_client_connection.c b/client/src/pkgmgr_client_connection.c index 4a010af..4600907 100644 --- a/client/src/pkgmgr_client_connection.c +++ b/client/src/pkgmgr_client_connection.c @@ -24,7 +24,6 @@ #include #include "package-manager.h" -#include "package-manager-types.h" #include "pkgmgr_client_debug.h" #include "pkgmgr_client_internal.h" #include "../../installer/pkgmgr_installer.h" @@ -247,16 +246,19 @@ static void __handle_res_event_signal(const gchar *signal_name, char *req_id; char *pkgid = NULL; char *status = NULL; + char *path = NULL; + pkgmgr_res_event_path_state state; struct cb_info *cb_info = (struct cb_info *)user_data; int signal_type; GVariant *extra_param = NULL; - pkgmgr_res_event_info_t event_info; + pkgmgr_res_event_info_t *event_info; + GVariantIter *iter; if (!cb_info->res_event_cb) return; g_variant_get(parameters, "(u&s&s&sv)", &target_uid, &req_id, &pkgid, &status, &extra_param); - if (!g_variant_type_equal(G_VARIANT_TYPE("(i)"), + if (!g_variant_type_equal(G_VARIANT_TYPE("(ia(si))"), g_variant_get_type(extra_param))) { ERR("invalid extra parameter"); g_variant_unref(extra_param); @@ -275,10 +277,30 @@ static void __handle_res_event_signal(const gchar *signal_name, } } - g_variant_get(extra_param, "(i)", &event_info.error_code); + event_info = pkgmgr_res_event_info_new(); + if (event_info == NULL) { + ERR("out of memory"); + g_variant_unref(extra_param); + return; + } + + g_variant_get(extra_param, "(ia(si))", &event_info->error_code, &iter); + + while (g_variant_iter_loop(iter, "(&si)", &path, &state)) { + if (pkgmgr_res_event_info_add_path_state(event_info, + path, state) != PKGMGR_R_OK) { + ERR("Fail to add path state"); + g_variant_unref(extra_param); + g_variant_iter_free(iter); + pkgmgr_res_event_info_free(event_info); + return; + } + } cb_info->res_event_cb(target_uid, cb_info->req_id, pkgid, signal_name, - status, &event_info, cb_info->data); + status, event_info, cb_info->data); g_variant_unref(extra_param); + g_variant_iter_free(iter); + pkgmgr_res_event_info_free(event_info); } static void __signal_handler(GDBusConnection *conn, const gchar *sender_name, diff --git a/installer/pkgmgr_installer.c b/installer/pkgmgr_installer.c index ce4bba6..82285e0 100644 --- a/installer/pkgmgr_installer.c +++ b/installer/pkgmgr_installer.c @@ -1260,8 +1260,33 @@ API int pkgmgr_installer_set_is_upgrade(pkgmgr_installer *pi, int is_upgrade) { static GVariant *__get_gvariant_from_event_info(pkgmgr_res_event_info *event_info) { pkgmgr_res_event_info_t *info = event_info; + GVariantBuilder *builder; + GVariant *result; + GList *path_states; + res_event_path_state_t *path_state; + + builder = g_variant_builder_new(G_VARIANT_TYPE("a(si)")); + if (builder == NULL) { + ERR("out of memory"); + return NULL; + } + + for (path_states = info->path_states; path_states != NULL; + path_states = path_states->next) { + path_state = (res_event_path_state_t *)path_states->data; + g_variant_builder_add(builder, "(si)", + path_state->path, path_state->state); + } + + result = g_variant_new("(ia(si))", info->error_code, builder); + g_variant_builder_unref(builder); - return g_variant_new("(i)", info->error_code); + if (result == NULL) { + ERR("Fail to create extra data"); + return NULL; + } + + return result; } API int pkgmgr_installer_send_res_signal(pkgmgr_installer *pi, @@ -1271,6 +1296,7 @@ API int pkgmgr_installer_send_res_signal(pkgmgr_installer *pi, char *sid; const char *signal_name; GError *err = NULL; + GVariant *extra_param; if (!pi || !pkgid || !status) { ERR("invalid argument"); @@ -1287,13 +1313,17 @@ API int pkgmgr_installer_send_res_signal(pkgmgr_installer *pi, return -1; } + extra_param = __get_gvariant_from_event_info(event_info); + if (extra_param == NULL) { + ERR("Fail to get extra parameter"); + return -1; + } + if (g_dbus_connection_emit_signal(pi->conn, NULL, PKGMGR_INSTALLER_DBUS_OBJECT_PATH, PKGMGR_INSTALLER_DBUS_INTERFACE, signal_name, g_variant_new("(usssv)", pi->target_uid, sid, - pkgid, status, - __get_gvariant_from_event_info( - event_info)), + pkgid, status, extra_param), &err) != TRUE) { ERR("failed to send dbus signal"); if (err) { @@ -1319,6 +1349,7 @@ API int pkgmgr_installer_send_res_signal_for_uid(pkgmgr_installer *pi, void *data; void *ptr; const char *signal_name; + GVariant *extra_param; if (!pi || !pi->conn) { ERR("connection is NULL"); @@ -1340,9 +1371,14 @@ API int pkgmgr_installer_send_res_signal_for_uid(pkgmgr_installer *pi, name_size = strlen(signal_name) + 1; data_len += name_size; + extra_param = __get_gvariant_from_event_info(event_info); + if (extra_param == NULL) { + ERR("Fail to get extra parameter"); + return -1; + } + gv = g_variant_new("(usssv)", pi->target_uid, sid, - pkgid, status, - __get_gvariant_from_event_info(event_info)); + pkgid, status, extra_param); if (gv == NULL) { ERR("failed to create GVariant instance"); return -1; diff --git a/types/include/package-manager-types.h b/types/include/package-manager-types.h index 19bbf1f..062bb43 100644 --- a/types/include/package-manager-types.h +++ b/types/include/package-manager-types.h @@ -125,10 +125,6 @@ typedef struct _package_manager_pkg_detail_info_t { GList *dependency_list; } package_manager_pkg_detail_info_t; -typedef struct _pkgmgr_res_event_info_t { - int error_code; -} pkgmgr_res_event_info_t; - /** @} */ #ifdef __cplusplus -- 2.7.4