PKGMGR_CLIENT_STATUS_ENABLE_APP_SPLASH_SCREEN},
{PKGMGR_INSTALLER_APP_DISABLE_SPLASH_SCREEN_EVENT_STR,
PKGMGR_CLIENT_STATUS_DISABLE_APP_SPLASH_SCREEN},
+ {PKGMGR_INSTALLER_RES_COPY_EVENT_STR, PKGMGR_CLIENT_STATUS_RES_COPY},
+ {PKGMGR_INSTALLER_RES_CREATE_DIR_EVENT_STR,
+ PKGMGR_CLIENT_STATUS_RES_CREATE_DIR},
+ {PKGMGR_INSTALLER_RES_REMOVE_EVENT_STR,
+ PKGMGR_CLIENT_STATUS_RES_REMOVE},
+ {PKGMGR_INSTALLER_RES_UNINSTALL_EVENT_STR,
+ PKGMGR_CLIENT_STATUS_RES_UNINSTALL},
{NULL, -1}
};
}
}
-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;
char *pkg_type = NULL;
+ char *appid = NULL;
char *pkgid = NULL;
char *key = NULL;
char *val = NULL;
- char *appid = 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&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)) {
+ g_variant_iter_free(iter);
+ return;
+ }
+ }
+
+ /* 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);
+ } else if (cb_info->app_event_cb && strcmp(appid, "") != 0) {
+ cb_info->app_event_cb(target_uid, cb_info->req_id,
+ pkg_type, pkgid, appid, key, val, NULL,
+ cb_info->data);
+ } else if (cb_info->size_info_cb) {
+ __handle_size_info_callback(cb_info, pkgid, val);
+ }
+
+ /* TODO: unsubscribe request callback */
+ }
+ g_variant_iter_free(iter);
+}
+
+static void __handle_res_event_signal(const gchar *signal_name,
+ GVariant *parameters, gpointer user_data)
+{
+ uid_t target_uid;
+ 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;
+ GVariantIter *iter;
- g_variant_get(parameters, "(u&s&s&s&s&s&s)",
- &target_uid, &req_id, &pkg_type,
- &pkgid, &appid, &key, &val);
+ if (!cb_info->res_event_cb)
+ return;
- /* in case of request, check reqkey */
+ g_variant_get(parameters, "(u&s&s&sv)", &target_uid, &req_id, &pkgid, &status, &extra_param);
+ 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);
+ return;
+ }
if (cb_info->req_key) {
- if (strcmp(cb_info->req_key, req_id) != 0)
+ if (strcmp(cb_info->req_key, req_id) != 0) {
+ g_variant_unref(extra_param);
return;
+ }
} else {
signal_type = __get_signal_type(signal_name);
- if (signal_type < 0 || !(cb_info->status_type & signal_type))
+ if (signal_type < 0 || !(cb_info->status_type & signal_type)) {
+ g_variant_unref(extra_param);
return;
+ }
}
- /* each cb_data can only has one callback */
- if (cb_info->event_cb && strcmp(appid, "") == 0)
- cb_info->event_cb(target_uid, cb_info->req_id,
- pkg_type, pkgid, key, val, NULL, cb_info->data);
- else if (cb_info->app_event_cb && strcmp(appid, "") != 0)
- cb_info->app_event_cb(target_uid, cb_info->req_id,
- pkg_type, pkgid, appid, key, val, NULL,
- cb_info->data);
- else if (cb_info->size_info_cb)
- __handle_size_info_callback(cb_info, pkgid, val);
+ 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);
- /* TODO: unsubscribe request callback */
+ 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);
+ g_variant_unref(extra_param);
+ g_variant_iter_free(iter);
+ pkgmgr_res_event_info_free(event_info);
}
-int pkgmgr_client_connection_set_callback(struct pkgmgr_client_t *pc,
- struct cb_info *cb_info)
+static void __handle_pkg_upgrade_event_signal(const gchar *signal_name,
+ GVariant *parameters, gpointer user_data)
+{
+ guint32 progress;
+ struct cb_info *cb_info = (struct cb_info *)user_data;
+
+ if (!cb_info->upgrade_event_cb)
+ return;
+
+ if (strcmp(signal_name, PKGMGR_INSTALLER_PKG_UPGRADE_EVENT_STR) != 0) {
+ return;
+ }
+
+ g_variant_get(parameters, "(u)", &progress);
+ cb_info->upgrade_event_cb(progress, 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)
{
- cb_info->sid = g_dbus_connection_signal_subscribe(pc->conn, NULL,
- PKGMGR_INSTALLER_DBUS_INTERFACE, NULL,
+ 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) ||
+ !strcmp(signal_name, PKGMGR_INSTALLER_RES_CREATE_DIR_EVENT_STR)) {
+ __handle_res_event_signal(signal_name, parameters, user_data);
+ } else if (!strcmp(signal_name, PKGMGR_INSTALLER_PKG_UPGRADE_EVENT_STR)) {
+ __handle_pkg_upgrade_event_signal(signal_name, parameters, user_data);
+ }
+}
+
+static void __set_signal_list(int event, GList **signal_list)
+{
+ int i;
+ if (event == PKGMGR_CLIENT_STATUS_ALL)
+ return;
+
+ for (i = 0; map[i].signal_str != NULL; i++) {
+ if (event & map[i].signal_type)
+ *signal_list = g_list_append(*signal_list,
+ (char *)map[i].signal_str);
+ }
+}
+
+static int __subscribe_signal(struct pkgmgr_client_t *pc,
+ struct cb_info *cb_info, const char *signal)
+{
+ guint sid = g_dbus_connection_signal_subscribe(pc->conn, NULL,
+ PKGMGR_INSTALLER_DBUS_INTERFACE, signal,
PKGMGR_INSTALLER_DBUS_OBJECT_PATH, NULL,
G_DBUS_SIGNAL_FLAGS_NONE, __signal_handler,
(gpointer)cb_info, NULL);
- if (!cb_info->sid) {
+ if (!sid) {
ERR("failed to subscribe singal");
return PKGMGR_R_ERROR;
}
+ cb_info->sid_list = g_list_append(cb_info->sid_list,
+ GUINT_TO_POINTER(sid));
return PKGMGR_R_OK;
}
+int pkgmgr_client_connection_set_callback(struct pkgmgr_client_t *pc,
+ struct cb_info *cb_info)
+{
+ GList *signal_list = NULL;
+ GList *tmp_list = NULL;
+ int ret;
+ char *signal_type;
+ __set_signal_list(pc->status_type, &signal_list);
+
+ if (g_list_length(signal_list) == 0)
+ return __subscribe_signal(pc, cb_info, NULL);
+
+ for (tmp_list = signal_list; tmp_list != NULL;
+ tmp_list = g_list_next(tmp_list)) {
+ signal_type = (char *)tmp_list->data;
+ ret = __subscribe_signal(pc, cb_info, signal_type);
+ if (ret != 0) {
+ g_list_free(signal_list);
+ return PKGMGR_R_ERROR;
+ }
+ }
+
+ g_list_free(signal_list);
+ return PKGMGR_R_OK;
+}
+
void pkgmgr_client_connection_unset_callback(struct pkgmgr_client_t *pc,
struct cb_info *cb_info)
{
- g_dbus_connection_signal_unsubscribe(pc->conn, cb_info->sid);
+ GList *tmp = NULL;
+ guint tmp_sid;
+ for (tmp = cb_info->sid_list; tmp != NULL; tmp = g_list_next(tmp)) {
+ tmp_sid = GPOINTER_TO_UINT(tmp->data);
+ g_dbus_connection_signal_unsubscribe(pc->conn, tmp_sid);
+ }
}
int pkgmgr_client_connection_send_request(struct pkgmgr_client_t *pc,