In order to avoid sending the agent message on file_xfer_info_async_cb, we can provide the "file-info" signal to SpiceFileTransferTask. In order to this signal be significant to applications, we request all standard attributes to g_file_query_info_async. This change is related to split SpiceFileTransferTask from channel-main. --- src/channel-main.c | 96 ++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 68 insertions(+), 28 deletions(-) diff --git a/src/channel-main.c b/src/channel-main.c index 7843aeb..0ed322e 100644 --- a/src/channel-main.c +++ b/src/channel-main.c @@ -136,6 +136,7 @@ enum { enum { SIGNAL_FINISHED, + SIGNAL_FILE_INFO, LAST_TASK_SIGNAL }; @@ -3001,11 +3002,6 @@ static void file_xfer_info_async_cb(GObject *obj, GAsyncResult *res, gpointer da GFileInfo *info; GFile *file = G_FILE(obj); GError *error = NULL; - GKeyFile *keyfile = NULL; - gchar *basename = NULL; - VDAgentFileXferStartMessage msg; - gsize /*msg_size*/ data_len; - gchar *string; SpiceFileTransferTask *self = SPICE_FILE_TRANSFER_TASK(data); self->pending = FALSE; @@ -3015,33 +3011,14 @@ static void file_xfer_info_async_cb(GObject *obj, GAsyncResult *res, gpointer da self->file_size = g_file_info_get_attribute_uint64(info, G_FILE_ATTRIBUTE_STANDARD_SIZE); + g_signal_emit(self, task_signals[SIGNAL_FILE_INFO], 0, info); g_object_notify(G_OBJECT(self), "progress"); - keyfile = g_key_file_new(); + g_clear_object(&info); - /* File name */ - basename = g_file_get_basename(file); - g_key_file_set_string(keyfile, "vdagent-file-xfer", "name", basename); - g_free(basename); - /* File size */ - g_key_file_set_uint64(keyfile, "vdagent-file-xfer", "size", self->file_size); - - /* Save keyfile content to memory. TODO: more file attributions - need to be sent to guest */ - string = g_key_file_to_data(keyfile, &data_len, &error); - g_key_file_free(keyfile); - if (error) - goto failed; - - /* Create file-xfer start message */ - msg.id = self->id; - agent_msg_queue_many(self->channel, VD_AGENT_FILE_XFER_START, - &msg, sizeof(msg), - string, data_len + 1, NULL); - g_free(string); - spice_channel_wakeup(SPICE_CHANNEL(self->channel), FALSE); return; failed: + g_clear_object(&info); spice_file_transfer_task_completed(self, error); } @@ -3059,7 +3036,7 @@ static void file_xfer_read_async_cb(GObject *obj, GAsyncResult *res, gpointer da } g_file_query_info_async(self->file, - G_FILE_ATTRIBUTE_STANDARD_SIZE, + "standard::*", G_FILE_QUERY_INFO_NONE, G_PRIORITY_DEFAULT, self->cancellable, @@ -3071,6 +3048,50 @@ static void file_xfer_read_async_cb(GObject *obj, GAsyncResult *res, gpointer da static SpiceFileTransferTask *spice_file_transfer_task_new(SpiceMainChannel *channel, GFile *file, GCancellable *cancellable); +static void file_xfer_on_file_info(SpiceFileTransferTask *xfer_task, + GFileInfo *info, + gpointer data) +{ + SpiceMainChannel *channel; + GKeyFile *keyfile; + VDAgentFileXferStartMessage msg; + gchar *string, *basename; + guint64 file_size; + gsize data_len; + GError *error = NULL; + + g_return_if_fail(info != NULL); + + channel = SPICE_MAIN_CHANNEL(data); + + basename = g_file_info_get_attribute_as_string(info, G_FILE_ATTRIBUTE_STANDARD_NAME); + file_size = g_file_info_get_attribute_uint64(info, G_FILE_ATTRIBUTE_STANDARD_SIZE); + + keyfile = g_key_file_new(); + g_key_file_set_string(keyfile, "vdagent-file-xfer", "name", basename); + g_key_file_set_uint64(keyfile, "vdagent-file-xfer", "size", file_size); + + g_free(basename); + + /* Save keyfile content to memory. TODO: more file attributions + need to be sent to guest */ + string = g_key_file_to_data(keyfile, &data_len, &error); + g_key_file_free(keyfile); + if (error) + goto failed; + + /* Create file-xfer start message */ + msg.id = spice_file_transfer_task_get_id(xfer_task); + agent_msg_queue_many(channel, VD_AGENT_FILE_XFER_START, + &msg, sizeof(msg), + string, data_len + 1, NULL); + g_free(string); + spice_channel_wakeup(SPICE_CHANNEL(channel), FALSE); + return; + +failed: + spice_file_transfer_task_completed(xfer_task, error); +} static void task_finished(SpiceFileTransferTask *task, GError *error, @@ -3157,6 +3178,7 @@ void spice_main_file_copy_async(SpiceMainChannel *channel, guint32 task_id = spice_file_transfer_task_get_id(task); g_hash_table_insert(c->file_xfer_tasks, GUINT_TO_POINTER(task_id), task); + g_signal_connect(task, "file-info", G_CALLBACK(file_xfer_on_file_info), channel); g_signal_connect(task, "finished", G_CALLBACK(task_finished), channel); g_signal_emit(channel, signals[SPICE_MAIN_NEW_FILE_TRANSFER], 0, task); spice_file_transfer_task_start_task(task); @@ -3483,6 +3505,24 @@ spice_file_transfer_task_class_init(SpiceFileTransferTaskClass *klass) G_PARAM_STATIC_STRINGS)); /** + * SpiceFileTransferTask::file-info + * @task: the file transfer task that emitted the signal + * @file_info: (transfer none): A GFileInfo object to retrieve file + * information. Only keys from standard namespace are supported. + * + * The #SpiceFileTransferTask::file-info signal is emitted just before the file + * transfer effectively starts. + * + * Since: 0.32 + **/ + task_signals[SIGNAL_FILE_INFO] = g_signal_new("file-info", SPICE_TYPE_FILE_TRANSFER_TASK, + G_SIGNAL_RUN_FIRST, + 0, NULL, NULL, + g_cclosure_marshal_VOID__BOXED, + G_TYPE_NONE, 1, + G_TYPE_FILE_INFO); + + /** * SpiceFileTransferTask::finished: * @task: the file transfer task that emitted the signal * @error: (transfer none): the error state of the transfer. Will be %NULL -- 2.5.5 _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/spice-devel