From ba44056856c41c952fe1542e240041961ca0f4a1 Mon Sep 17 00:00:00 2001 From: Ilho Kim Date: Wed, 11 Aug 2021 14:43:31 +0900 Subject: [PATCH] Implement resource copy request's callback Change-Id: I203d8d4ecdc6c16d5c98c3c40be77776c399238f Signed-off-by: Ilho Kim --- client/include/package-manager.h | 18 ++-- client/src/pkgmgr.c | 20 ++--- client/src/pkgmgr_client_connection.c | 51 +++++++++-- client/src/pkgmgr_client_internal.h | 2 +- installer/pkgmgr_installer.c | 119 ++++++++++++++++++++++++++ installer/pkgmgr_installer.h | 56 ++++++++++++ installer/pkgmgr_installer_type.h | 8 +- 7 files changed, 248 insertions(+), 26 deletions(-) diff --git a/client/include/package-manager.h b/client/include/package-manager.h index 4b3aa96..bb53f47 100644 --- a/client/include/package-manager.h +++ b/client/include/package-manager.h @@ -156,7 +156,7 @@ typedef enum _pkgmgr_return_val { typedef void pkgmgr_client; typedef void pkgmgr_info; -typedef void *pkgmgr_res_cb_info_h; +typedef void *pkgmgr_res_event_info_h; typedef struct { long long data_size; @@ -179,6 +179,10 @@ typedef struct { pkgmgr_updateinfo_type type; } pkg_update_info_t; +typedef struct { + char *pkgid; +} pkgmgr_res_event_info_t; + typedef int (*pkgmgr_iter_fn)(const char *pkg_type, const char *pkgid, const char *version, void *data); @@ -196,9 +200,9 @@ typedef void (*pkgmgr_pkg_size_info_receive_cb)(pkgmgr_client *pc, const char *p typedef void (*pkgmgr_total_pkg_size_info_receive_cb)(pkgmgr_client *pc, const pkg_size_info_t *size_info, void *user_data); -typedef void (*pkgmgr_res_request_cb)(uid_t target_uid, int req_id, +typedef void (*pkgmgr_res_copy_handler)(uid_t target_uid, int req_id, const char *pkgid, const char *request_type, const char *status, - pkgmgr_res_cb_info_h handle, void *user_data); + pkgmgr_res_event_info_h handle, void *user_data); typedef enum { PC_REQUEST = 0, @@ -1230,7 +1234,7 @@ int pkgmgr_client_add_res_copy_path(pkgmgr_client *pc, const char *src_path, con * @retval PKGMGR_R_ENOMEM out of memory * @retval PKGMGR_R_EPRIV privilege denied */ -int pkgmgr_client_res_copy(pkgmgr_client *pc, pkgmgr_res_request_cb event_cb, void *user_data); +int pkgmgr_client_res_copy(pkgmgr_client *pc, pkgmgr_res_copy_handler event_cb, void *user_data); /** * @brief Add resource path to remove @@ -1261,7 +1265,7 @@ int pkgmgr_client_add_res_remove_path(pkgmgr_client *pc, const char *res_path); * @retval PKGMGR_R_ENOMEM out of memory * @retval PKGMGR_R_EPRIV privilege denied */ -int pkgmgr_client_res_remove(pkgmgr_client *pc, pkgmgr_res_request_cb event_cb, void *user_data); +int pkgmgr_client_res_remove(pkgmgr_client *pc, pkgmgr_res_copy_handler event_cb, void *user_data); /** * @brief This API uninstall copied resources of the package. @@ -1279,8 +1283,8 @@ int pkgmgr_client_res_remove(pkgmgr_client *pc, pkgmgr_res_request_cb event_cb, * @retval PKGMGR_R_ENOMEM out of memory * @retval PKGMGR_R_EPRIV privilege denied */ -int pkgmgr_client_res_uninstall(pkgmgr_client *pc, const char *pkgid, pkgmgr_res_request_cb event_cb, void *user_data); -int pkgmgr_client_res_usr_uninstall(pkgmgr_client *pc, const char *pkgid, pkgmgr_res_request_cb event_cb, void *user_data, uid_t uid); +int pkgmgr_client_res_uninstall(pkgmgr_client *pc, const char *pkgid, pkgmgr_res_copy_handler event_cb, void *user_data); +int pkgmgr_client_res_usr_uninstall(pkgmgr_client *pc, const char *pkgid, pkgmgr_res_copy_handler event_cb, void *user_data, uid_t uid); /** @} */ diff --git a/client/src/pkgmgr.c b/client/src/pkgmgr.c index e6e928d..68ad27d 100644 --- a/client/src/pkgmgr.c +++ b/client/src/pkgmgr.c @@ -141,9 +141,9 @@ static struct cb_info *__create_app_event_cb_info( return cb_info; } -static struct cb_info *__create_res_request_cb_info( +static struct cb_info *__create_res_copy_event_cb_info( struct pkgmgr_client_t *client, - pkgmgr_res_request_cb res_request_cb, + pkgmgr_res_copy_handler res_copy_event_cb, void *data, const char *req_key) { struct cb_info *cb_info; @@ -155,7 +155,7 @@ static struct cb_info *__create_res_request_cb_info( } cb_info->client = client; - cb_info->res_request_cb = res_request_cb; + cb_info->res_copy_event_cb = res_copy_event_cb; cb_info->data = data; cb_info->req_id = _get_internal_request_id(); if (req_key == NULL) @@ -2785,7 +2785,7 @@ API int pkgmgr_client_add_res_copy_path(pkgmgr_client *pc, } API int pkgmgr_client_res_copy(pkgmgr_client *pc, - pkgmgr_res_request_cb event_cb, void *user_data) + pkgmgr_res_copy_handler event_cb, void *user_data) { GVariant *result; int ret; @@ -2817,7 +2817,7 @@ API int pkgmgr_client_res_copy(pkgmgr_client *pc, return ret; } - cb_info = __create_res_request_cb_info(client, + cb_info = __create_res_copy_event_cb_info(client, event_cb, user_data, req_key); g_variant_unref(result); if (cb_info == NULL) @@ -2858,7 +2858,7 @@ API int pkgmgr_client_add_res_remove_path(pkgmgr_client *pc, } API int pkgmgr_client_res_remove(pkgmgr_client *pc, - pkgmgr_res_request_cb event_cb, void *user_data) + pkgmgr_res_copy_handler event_cb, void *user_data) { GVariant *result; int ret; @@ -2890,7 +2890,7 @@ API int pkgmgr_client_res_remove(pkgmgr_client *pc, return ret; } - cb_info = __create_res_request_cb_info(client, + cb_info = __create_res_copy_event_cb_info(client, event_cb, user_data, req_key); g_variant_unref(result); if (cb_info == NULL) @@ -2907,14 +2907,14 @@ API int pkgmgr_client_res_remove(pkgmgr_client *pc, } API int pkgmgr_client_res_uninstall(pkgmgr_client *pc, const char *pkgid, - pkgmgr_res_request_cb event_cb, void *user_data) + pkgmgr_res_copy_handler event_cb, void *user_data) { return pkgmgr_client_res_usr_uninstall(pc, pkgid, event_cb, user_data, _getuid()); } API int pkgmgr_client_res_usr_uninstall(pkgmgr_client *pc, const char *pkgid, - pkgmgr_res_request_cb event_cb, void *user_data, uid_t uid) + pkgmgr_res_copy_handler event_cb, void *user_data, uid_t uid) { GVariant *result; int ret = PKGMGR_R_ECOMM; @@ -2945,7 +2945,7 @@ API int pkgmgr_client_res_usr_uninstall(pkgmgr_client *pc, const char *pkgid, return ret; } - cb_info = __create_res_request_cb_info(client, + cb_info = __create_res_copy_event_cb_info(client, event_cb, user_data, req_key); g_variant_unref(result); if (cb_info == NULL) diff --git a/client/src/pkgmgr_client_connection.c b/client/src/pkgmgr_client_connection.c index e83fda1..af172eb 100644 --- a/client/src/pkgmgr_client_connection.c +++ b/client/src/pkgmgr_client_connection.c @@ -187,10 +187,8 @@ static void __handle_size_info_callback(struct cb_info *cb_info, } } -static void __signal_handler(GDBusConnection *conn, const gchar *sender_name, - const gchar *object_path, const gchar *interface_name, - const gchar *signal_name, GVariant *parameters, - gpointer user_data) +static void __handle_pkg_signal(const gchar *signal_name, + GVariant *parameters, gpointer user_data) { uid_t target_uid; char *req_id; @@ -227,9 +225,6 @@ static void __signal_handler(GDBusConnection *conn, const gchar *sender_name, cb_info->data); } else if (cb_info->size_info_cb) { __handle_size_info_callback(cb_info, pkgid, val); - } else if (cb_info->res_request_cb) { - // TODO(ilho159.kim): - //Need to handle resource copy request's event callback } /* TODO: unsubscribe request callback */ @@ -237,6 +232,48 @@ static void __signal_handler(GDBusConnection *conn, const gchar *sender_name, g_variant_iter_free(iter); } +static void __handle_res_copy_event_signal(const gchar *signal_name, + GVariant *parameters, gpointer user_data) +{ + uid_t target_uid; + char *req_id; + char *pkgid = NULL; + char *status = NULL; + struct cb_info *cb_info = (struct cb_info *)user_data; + int signal_type; + + if (!cb_info->res_copy_event_cb) + return; + + g_variant_get(parameters, "(u&s&s&s)", &target_uid, &req_id, &pkgid, &status); + if (cb_info->req_key) { + if (strcmp(cb_info->req_key, req_id) != 0) + return; + } else { + signal_type = __get_signal_type(signal_name); + if (signal_type < 0 || !(cb_info->status_type & signal_type)) + return; + } + + cb_info->res_copy_event_cb(target_uid, cb_info->req_id, pkgid, signal_name, + status, NULL, cb_info->data); +} + +static void __signal_handler(GDBusConnection *conn, const gchar *sender_name, + const gchar *object_path, const gchar *interface_name, + const gchar *signal_name, GVariant *parameters, + gpointer user_data) +{ + if (g_variant_type_equal(G_VARIANT_TYPE("(usa(sss)ss)"), + g_variant_get_type(parameters))) { + __handle_pkg_signal(signal_name, parameters, user_data); + } else if (!strcmp(signal_name, PKGMGR_INSTALLER_RES_COPY_EVENT_STR) || + !strcmp(signal_name, PKGMGR_INSTALLER_RES_REMOVE_EVENT_STR) || + !strcmp(signal_name, PKGMGR_INSTALLER_RES_UNINSTALL_EVENT_STR)) { + __handle_res_copy_event_signal(signal_name, parameters, user_data); + } +} + static void __set_signal_list(int event, GList **signal_list) { int i; diff --git a/client/src/pkgmgr_client_internal.h b/client/src/pkgmgr_client_internal.h index d356b58..b984168 100644 --- a/client/src/pkgmgr_client_internal.h +++ b/client/src/pkgmgr_client_internal.h @@ -41,7 +41,7 @@ struct cb_info { pkgmgr_handler event_cb; pkgmgr_app_handler app_event_cb; pkgmgr_pkg_size_info_receive_cb size_info_cb; - pkgmgr_res_request_cb res_request_cb; + pkgmgr_res_copy_handler res_copy_event_cb; void *data; struct pkgmgr_client_t *client; GList *sid_list; diff --git a/installer/pkgmgr_installer.c b/installer/pkgmgr_installer.c index c7a07d5..e709431 100644 --- a/installer/pkgmgr_installer.c +++ b/installer/pkgmgr_installer.c @@ -34,6 +34,7 @@ #include #include +#include "package-manager.h" #include "pkgmgr_installer.h" #include "pkgmgr_installer_config.h" #include "pkgmgr_installer_debug.h" @@ -178,6 +179,12 @@ static const char *__get_signal_name(pkgmgr_installer *pi, const char *key, return PKGMGR_INSTALLER_CLEAR_EVENT_STR; case PKGMGR_REQ_GETSIZE: return PKGMGR_INSTALLER_GET_SIZE_KEY_STR; + case PKGMGR_REQ_RES_COPY: + return PKGMGR_INSTALLER_RES_COPY_EVENT_STR; + case PKGMGR_REQ_RES_REMOVE: + return PKGMGR_INSTALLER_RES_REMOVE_EVENT_STR; + case PKGMGR_REQ_RES_UNINSTALL: + return PKGMGR_INSTALLER_RES_UNINSTALL_EVENT_STR; } ERR("cannot find type"); @@ -1246,3 +1253,115 @@ API int pkgmgr_installer_set_is_upgrade(pkgmgr_installer *pi, int is_upgrade) { pi->is_upgrade = is_upgrade; return 0; } + +API int pkgmgr_installer_send_res_copy_signal(pkgmgr_installer *pi, + const char *pkgid, const char *status, + pkgmgr_res_event_info_h event_info) +{ + char *sid; + const char *signal_name; + GError *err = NULL; + + if (!pi || !pkgid || !status) { + ERR("invalid argument"); + return -1; + } + + sid = pi->session_id; + if (!sid) + sid = ""; + + signal_name = __get_signal_name(pi, "", ""); + if (!signal_name) { + ERR("unknown signal type"); + 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("(usss)", pi->target_uid, sid, + pkgid, status), &err) != TRUE) { + ERR("failed to send dbus signal"); + if (err) { + ERR("err: %s", err->message); + g_error_free(err); + } + return -1; + } + + return 0; +} + +API int pkgmgr_installer_send_res_copy_signal_for_uid(pkgmgr_installer *pi, + uid_t uid, const char *pkgid, const char *status, + pkgmgr_res_event_info_h event_info) +{ + char *sid; + size_t data_len; + size_t name_size; + GVariant *gv; + gsize gv_len; + gpointer gv_data; + void *data; + void *ptr; + const char *signal_name; + + if (!pi || !pi->conn) { + ERR("connection is NULL"); + return -1; + } + + sid = pi->session_id; + if (!sid) + sid = ""; + + data_len = sizeof(size_t) + sizeof(gsize); + + /* including null byte */ + signal_name = __get_signal_name(pi, "", ""); + if (!signal_name) { + ERR("unknown signal type"); + return -1; + } + name_size = strlen(signal_name) + 1; + data_len += name_size; + + gv = g_variant_new("(usss)", pi->target_uid, sid, pkgid, status); + if (gv == NULL) { + ERR("failed to create GVariant instance"); + return -1; + } + + gv_len = g_variant_get_size(gv); + gv_data = g_malloc(gv_len); + g_variant_store(gv, gv_data); + g_variant_unref(gv); + data_len += gv_len; + + data = malloc(data_len); + if (data == NULL) { + ERR("out of memory"); + g_free(gv_data); + return -1; + } + ptr = data; + memcpy(ptr, &name_size, sizeof(size_t)); + ptr += sizeof(size_t); + memcpy(ptr, &gv_len, sizeof(gsize)); + ptr += sizeof(gsize); + memcpy(ptr, signal_name, name_size); + ptr += name_size; + memcpy(ptr, gv_data, gv_len); + g_free(gv_data); + + if (__send_signal_to_agent(uid, data, data_len)) { + ERR("failed to send signal to agent"); + free(data); + return -1; + } + + free(data); + + return 0; +} diff --git a/installer/pkgmgr_installer.h b/installer/pkgmgr_installer.h index 2c5f544..3340ecf 100644 --- a/installer/pkgmgr_installer.h +++ b/installer/pkgmgr_installer.h @@ -26,6 +26,7 @@ #include +#include "package-manager.h" #include "pkgmgr_installer_type.h" /** @@ -1220,6 +1221,61 @@ int pkgmgr_installer_send_signals_for_uid(pkgmgr_installer *pi, uid_t uid, */ int pkgmgr_installer_set_is_upgrade(pkgmgr_installer *pi, int is_upgrade); +/** + @brief Send a signal of the resource copy event status + @pre None + @post None + @see None + @param[in] pi pkgmgr_installer object + @param[in] pkgid package id + @param[in] status event status + @param[in] event_info event info handle + @return Operation result + @retval 0 on success, otherwise -1 + @code +#include +void send_res_copy_singal(uid_t uid, int request_type, const char *session_id, + const char *pkgid, const char *status, + pkgmgr_res_event_info_h event_info) +{ + pkgmgr_installer *pi; + int r = 0; + + pi = pkgmgr_installer_new(); + if(!pi) return -1; + + if (pkgmgr_installer_set_uid(pi, uid)) + goto CLEANUP_RET; + if (pkgmgr_installer_set_request_type(pi, request_type)) + goto CLEANUP_RET; + if ((pkgmgr_installer_set_session_id(pi, session_id)) + goto CLEANUP_RET; + pkgmgr_installer_send_res_copy_signal(pi, pkgid, status, event_info); + +} + @endcode + */ +int pkgmgr_installer_send_res_copy_signal(pkgmgr_installer *pi, + const char *pkgid, const char *status, + pkgmgr_res_event_info_h event_info); + +/** + @brief Send a signal of the resource copy event status + @pre None + @post None + @see None + @param[in] pi pkgmgr_installer object + @param[in] uid user id + @param[in] pkgid package id + @param[in] status event status + @param[in] event_info event info handle + @return Operation result + @retval 0 on success, otherwise -1 + */ +int pkgmgr_installer_send_res_copy_signal_for_uid(pkgmgr_installer *pi, + uid_t uid, const char *pkgid, const char *status, + pkgmgr_res_event_info_h event_info); + #ifdef __cplusplus } #endif diff --git a/installer/pkgmgr_installer_type.h b/installer/pkgmgr_installer_type.h index b47eb56..cdb9610 100644 --- a/installer/pkgmgr_installer_type.h +++ b/installer/pkgmgr_installer_type.h @@ -48,6 +48,9 @@ extern "C" { #define PKGMGR_INSTALLER_UPGRADE_EVENT_STR "update" #define PKGMGR_INSTALLER_OK_EVENT_STR "ok" #define PKGMGR_INSTALLER_FAIL_EVENT_STR "fail" +#define PKGMGR_INSTALLER_RES_COPY_EVENT_STR "res_copy" +#define PKGMGR_INSTALLER_RES_REMOVE_EVENT_STR "res_remove" +#define PKGMGR_INSTALLER_RES_UNINSTALL_EVENT_STR "res_uninstall" #define PKGMGR_INSTALLER_UNKNOWN_EVENT_STR "" #define PKGMGR_INSTALLER_APP_DISABLE_EVENT_STR "disable_app" @@ -80,7 +83,10 @@ enum { PKGMGR_REQ_DISABLE_PKG = 16, PKGMGR_REQ_ENABLE_PKG = 17, PKGMGR_REQ_MIGRATE_EXTIMG = 18, - PKGMGR_REQ_RECOVER_DB = 19 + PKGMGR_REQ_RECOVER_DB = 19, + PKGMGR_REQ_RES_COPY = 20, + PKGMGR_REQ_RES_REMOVE = 21, + PKGMGR_REQ_RES_UNINSTALL = 22 }; enum { -- 2.34.1