From 3a50f4f451fa7117612cb76cfcf47060449071eb Mon Sep 17 00:00:00 2001 From: Junghyun Yeon Date: Thu, 5 Mar 2020 19:10:27 +0900 Subject: [PATCH] Change prototype of APIs for multi signal Change-Id: I0bf7b96b680aad2a7a2c91c6b7f36fa54ee2cc2b Signed-off-by: Junghyun Yeon --- client/src/pkgmgr_client_connection.c | 64 ++++------ installer/pkgmgr_installer.c | 187 ++++++++++++++++++------------ installer/pkgmgr_installer.h | 23 +++- installer/pkgmgr_installer_signal_agent.c | 2 +- 4 files changed, 152 insertions(+), 124 deletions(-) diff --git a/client/src/pkgmgr_client_connection.c b/client/src/pkgmgr_client_connection.c index 17372fd..5ad428b 100644 --- a/client/src/pkgmgr_client_connection.c +++ b/client/src/pkgmgr_client_connection.c @@ -106,6 +106,21 @@ struct signal_map map[] = { {NULL, -1} }; +static int __get_signal_type(const char *name) +{ + int i; + + if (name == NULL) + return -1; + + for (i = 0; map[i].signal_str != NULL; i++) { + if (strcmp(map[i].signal_str, name) == 0) + return map[i].signal_type; + } + + return -1; +} + static void __handle_size_info_callback(struct cb_info *cb_info, const char *pkgid, const char *val) { @@ -172,68 +187,35 @@ static void __handle_size_info_callback(struct cb_info *cb_info, } } -static void __convert_signal(char *event_type, char *event_status, - char *appid, int progress, char **key, char **val) -{ - *key = event_status; - if (strcmp(event_status, PKGMGR_INSTALLER_START_KEY_STR) == 0) { - *val = event_type; - } else if (strcmp(event_status, PKGMGR_INSTALLER_OK_EVENT_STR) == 0 || - strcmp(event_status, PKGMGR_INSTALLER_FAIL_EVENT_STR) == 0) { - *key = PKGMGR_INSTALLER_END_KEY_STR; - *val = event_status; - } else if (strcmp(event_status, PKGMGR_INSTALLER_APPID_KEY_STR) == 0) { - if (!appid) { - ERR("appid is empty"); - return; - } - *val = appid; - } else if (strcmp(event_type, PKGMGR_INSTALLER_GET_SIZE_KEY_STR) == 0) { - *key = event_type; - *val = event_status; - } - // TODO: should handle cleardata / clearacache signal -} - 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) { - int progress = 0; uid_t target_uid; - char buf[BUFMAX]; char *req_id; char *pkg_type = NULL; char *appid = NULL; char *pkgid = NULL; - char *event_type = NULL; - char *event_status = NULL; char *key = NULL; char *val = NULL; struct cb_info *cb_info = (struct cb_info *)user_data; GVariantIter *iter = NULL; + int signal_type; - g_variant_get(parameters, "(u&sa(sss)&s&si)", &target_uid, &req_id, &iter, - &event_type, &event_status, &progress); + g_variant_get(parameters, "(u&sa(sss)&s&s)", &target_uid, &req_id, &iter, + &key, &val); while (g_variant_iter_loop(iter, "(&s&s&s)", &pkgid, &appid, &pkg_type)) { if (cb_info->req_key) { if (strcmp(cb_info->req_key, req_id) != 0) continue; + } else { + signal_type = __get_signal_type(signal_name); + if (signal_type < 0 || !(cb_info->status_type & signal_type)) + return; } - /* convert event_type and event_status into key-val pair */ - __convert_signal(event_type, event_status, appid, - progress, &key, &val); - if (strcmp(event_status, - PKGMGR_INSTALLER_INSTALL_PERCENT_KEY_STR) == 0 || - strcmp(event_status, PKGMGR_INSTALLER_ERROR_KEY_STR) == 0) { - snprintf(buf, BUFMAX - 1, "%d", progress); - val = buf; - } - /* TODO: progress should be set properly when installation has - * completed or failed */ - + /* each cb_data can only has one callback */ if (cb_info->event_cb) { cb_info->event_cb(target_uid, cb_info->req_id, pkg_type, pkgid, key, val, NULL, cb_info->data); diff --git a/installer/pkgmgr_installer.c b/installer/pkgmgr_installer.c index e5a640f..cfbb99f 100644 --- a/installer/pkgmgr_installer.c +++ b/installer/pkgmgr_installer.c @@ -131,8 +131,18 @@ static int g_debug_mode; static int g_skip_optimization; static pkgmgr_privilege_level g_privilege_level = PM_PRIVILEGE_UNKNOWN; -static const char *__get_event_type(pkgmgr_installer *pi) +static const char *__get_signal_name(pkgmgr_installer *pi, const char *key, + const char *pkg_type) { + if (strcmp(key, PKGMGR_INSTALLER_INSTALL_PERCENT_KEY_STR) == 0) + return key; + else if (strcmp(key, PKGMGR_INSTALLER_GET_SIZE_KEY_STR) == 0) + return key; + else if (strcmp(key, PKGMGR_INSTALLER_APPID_KEY_STR) == 0) + return PKGMGR_INSTALLER_UNINSTALL_EVENT_STR; + else if (strcmp(pkg_type, PKGMGR_INSTALLER_CLEAR_CACHE_KEY_STR) == 0) + return pkg_type; + switch (pi->request_type) { case PKGMGR_REQ_INSTALL: case PKGMGR_REQ_MANIFEST_DIRECT_INSTALL: @@ -167,30 +177,12 @@ static const char *__get_event_type(pkgmgr_installer *pi) return NULL; } -static const char *__get_signal_name(pkgmgr_installer *pi, const char *key, - const char *pkg_type) -{ - if (strcmp(key, PKGMGR_INSTALLER_INSTALL_PERCENT_KEY_STR) == 0) - return key; - else if (strcmp(key, PKGMGR_INSTALLER_GET_SIZE_KEY_STR) == 0) - return key; - else if (strcmp(key, PKGMGR_INSTALLER_APPID_KEY_STR) == 0) - return PKGMGR_INSTALLER_UNINSTALL_EVENT_STR; - else if (strcmp(pkg_type, PKGMGR_INSTALLER_CLEAR_CACHE_KEY_STR) == 0) - return pkg_type; - - return __get_event_type(pi); -} - static int __send_signal_for_event(pkgmgr_installer *pi, const char *pkg_type, const char *pkgid, const char *appid, const char *key, const char *val) { - int progress = 0; char *sid; const char *tmp_appid = appid; - const char *event_type; - const char *event_status; const char *signal_name; GVariantBuilder *builder; GError *err = NULL; @@ -202,39 +194,20 @@ static int __send_signal_for_event(pkgmgr_installer *pi, const char *pkg_type, if (!sid) sid = ""; - signal_name = __get_signal_name(pi, key, val); + signal_name = __get_signal_name(pi, key, pkg_type); if (!signal_name) { - ERR("unknown signal name"); - return -1; - } - - event_type = __get_event_type(pi); - if (!event_type) { - ERR("unknown event type"); + ERR("unknown signal type"); return -1; } - if (strcmp(key, PKGMGR_INSTALLER_END_KEY_STR) == 0 || - strcmp(key, PKGMGR_INSTALLER_GET_SIZE_KEY_STR) == 0) - event_status = val; - else - event_status = key; - - if (strcmp(key, PKGMGR_INSTALLER_INSTALL_PERCENT_KEY_STR) == 0 || - strcmp(key, PKGMGR_INSTALLER_ERROR_KEY_STR) == 0) - progress = atoi(val); - else if (strcmp(key, PKGMGR_INSTALLER_APPID_KEY_STR) == 0) - tmp_appid = val; - builder = g_variant_builder_new(G_VARIANT_TYPE("a(sss)")); g_variant_builder_add(builder, "(sss)", pkgid, (tmp_appid ? tmp_appid : ""), pkg_type); if (g_dbus_connection_emit_signal(pi->conn, NULL, PKGMGR_INSTALLER_DBUS_OBJECT_PATH, PKGMGR_INSTALLER_DBUS_INTERFACE, signal_name, - g_variant_new("(usa(sss)ssi)", pi->target_uid, sid, - builder, event_type, event_status, progress), - &err) != TRUE) { + g_variant_new("(usa(sss)ss)", pi->target_uid, sid, + builder, key, val), &err) != TRUE) { ERR("failed to send dbus signal"); if (err) { ERR("err: %s", err->message); @@ -242,6 +215,7 @@ static int __send_signal_for_event(pkgmgr_installer *pi, const char *pkg_type, } return -1; } + return 0; } @@ -283,12 +257,9 @@ static int __send_signal_for_event_for_uid(pkgmgr_installer *pi, uid_t uid, const char *pkg_type, const char *pkgid, const char *appid, const char *key, const char *val) { - int progress = 0; char *sid; const char *signal_name; const char *tmp_appid = appid; - const char *event_type; - const char *event_status; size_t name_size; GVariantBuilder *builder; GVariant *gv; @@ -313,25 +284,6 @@ static int __send_signal_for_event_for_uid(pkgmgr_installer *pi, uid_t uid, return -1; } - event_type = __get_event_type(pi); - if (!event_type) { - ERR("unknown event type"); - return -1; - } - - if (strcmp(key, PKGMGR_INSTALLER_END_KEY_STR) == 0 || - strcmp(key, PKGMGR_INSTALLER_GET_SIZE_KEY_STR) == 0) - event_status = val; - else - event_status = key; - - if (strcmp(key, PKGMGR_INSTALLER_INSTALL_PERCENT_KEY_STR) == 0 || - strcmp(key, PKGMGR_INSTALLER_ERROR_KEY_STR) == 0) - progress = atoi(val); - else if (strcmp(key, PKGMGR_INSTALLER_APPID_KEY_STR) == 0) - tmp_appid = val; - - /* including null byte */ name_size = strlen(signal_name) + 1; data_len += name_size; @@ -339,8 +291,8 @@ static int __send_signal_for_event_for_uid(pkgmgr_installer *pi, uid_t uid, builder = g_variant_builder_new(G_VARIANT_TYPE("a(sss)")); g_variant_builder_add(builder, "(sss)", pkgid, (tmp_appid ? tmp_appid : ""), pkg_type); - gv = g_variant_new("(usa(sss)ssi)", pi->target_uid, sid, - builder, event_type, event_status, progress); + gv = g_variant_new("(usa(sss)ss)", pi->target_uid, sid, + builder, key, val); if (gv == NULL) { ERR("failed to create GVariant instance"); return -1; @@ -1083,14 +1035,14 @@ API int pkgmgr_installer_add_pkg(pkgmgr_installer *pi, info->pkgid = strdup(pkgid); info->pkg_type = strdup(pkg_type); - if (!info->pkgid || info->pkg_type) { + if (!info->pkgid || !info->pkg_type) { ERR("out of memory"); free(info->pkgid); free(info->pkg_type); free(info); return -1; } - g_hash_table_insert(pi->pkg_list, (gpointer)pkgid, (gpointer)info); + g_hash_table_insert(pi->pkg_list, (gpointer)info->pkgid, (gpointer)info); return 0; } @@ -1099,20 +1051,20 @@ static void __build_multi_signal(gpointer key, gpointer value, gpointer user_data) { GVariantBuilder *builder = (GVariantBuilder *)user_data; - char *pkgid = (char *)key; pkg_signal_info *info = (pkg_signal_info *)value; - g_variant_builder_add(builder, "(sss)", pkgid, "", info->pkg_type); + g_variant_builder_add(builder, "(sss)", info->pkgid, "", info->pkg_type); } API int pkgmgr_installer_send_signals(pkgmgr_installer *pi, - const char *event_type, const char *event_status, int progress) + const char *key, const char *val) { char *sid; + const char *signal_name; GError *err = NULL; GVariantBuilder *builder; - if (!pi || !event_type || !event_status) { + if (!pi || !key || !val) { ERR("invalid argument"); return -1; } @@ -1121,14 +1073,20 @@ API int pkgmgr_installer_send_signals(pkgmgr_installer *pi, if (!sid) sid = ""; + signal_name = __get_signal_name(pi, key, ""); + if (!signal_name) { + ERR("unknown signal type"); + return -1; + } + builder = g_variant_builder_new(G_VARIANT_TYPE("a(sss)")); g_hash_table_foreach(pi->pkg_list, __build_multi_signal, builder); if (g_dbus_connection_emit_signal(pi->conn, NULL, PKGMGR_INSTALLER_DBUS_OBJECT_PATH, - PKGMGR_INSTALLER_DBUS_INTERFACE, event_type, - g_variant_new("(usa(sss)ssi)", - pi->target_uid, sid, builder, event_type, - event_status, progress), &err) != TRUE) { + PKGMGR_INSTALLER_DBUS_INTERFACE, signal_name, + g_variant_new("(usa(sss)ss)", + pi->target_uid, sid, builder, key, + val), &err) != TRUE) { ERR("failed to send dbus signal"); if (err) { ERR("err: %s", err->message); @@ -1140,4 +1098,79 @@ API int pkgmgr_installer_send_signals(pkgmgr_installer *pi, g_variant_builder_unref(builder); return 0; -} \ No newline at end of file +} + +API int pkgmgr_installer_send_signals_for_uid(pkgmgr_installer *pi, uid_t uid, + const char *key, const char *val) +{ + char *sid; + size_t data_len; + size_t name_size; + GVariant *gv; + GVariantBuilder *builder; + 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, key, ""); + if (!signal_name) { + ERR("unknown signal type"); + return -1; + } + name_size = strlen(signal_name) + 1; + data_len += name_size; + + builder = g_variant_builder_new(G_VARIANT_TYPE("a(sss)")); + g_hash_table_foreach(pi->pkg_list, __build_multi_signal, builder); + + gv = g_variant_new("(usa(sss)ss)", uid, sid, builder, key, val); + 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"); + 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 a918e8f..3a4dfc5 100644 --- a/installer/pkgmgr_installer.h +++ b/installer/pkgmgr_installer.h @@ -1084,14 +1084,27 @@ int pkgmgr_installer_add_pkg(pkgmgr_installer *pi, * * This API is for installer backend.\n * - * @param[in] pi pointer to pkgmgr_installer - * @param[in] event_type package ID - * @param[in] event_status type of package - * @param[in] progress progress of requested operation + * @param[in] pi pointer to pkgmgr_installer + * @param[in] key Signal key + * @param[in] val Signal value * @return 0 if success, error code(<0) if fail\n */ int pkgmgr_installer_send_signals(pkgmgr_installer *pi, - const char *event_type, const char *event_status, int progress); + const char *key, const char *val); + +/** + * @brief This API sends signals to certain uid with packages already added + * + * This API is for installer backend.\n + * + * @param[in] pi pointer to pkgmgr_installer + * @param[in] uid user id + * @param[in] key Signal key + * @param[in] val Signal value + * @return 0 if success, error code(<0) if fail\n +*/ +int pkgmgr_installer_send_signals_for_uid(pkgmgr_installer *pi, uid_t uid, + const char *key, const char *val); #ifdef __cplusplus } diff --git a/installer/pkgmgr_installer_signal_agent.c b/installer/pkgmgr_installer_signal_agent.c index 6ede96a..2b5ae47 100644 --- a/installer/pkgmgr_installer_signal_agent.c +++ b/installer/pkgmgr_installer_signal_agent.c @@ -257,7 +257,7 @@ static gboolean __handle_signal(gint fd, GIOCondition cond, gpointer user_data) memcpy(data, buf + type_len, data_len); /* floating type GVariant instance */ - gv = g_variant_new_from_data(G_VARIANT_TYPE("(usa(sss)ssi)"), data, + gv = g_variant_new_from_data(G_VARIANT_TYPE("(usa(sss)ss)"), data, data_len, TRUE, NULL, NULL); __emit_signal(type_name, gv); -- 2.7.4