[Spice-devel] [spice-gtk v3 04/16] file-xfer: introduce file-info signal
Victor Toso
victortoso at redhat.com
Mon May 30 09:55:00 UTC 2016
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
More information about the Spice-devel
mailing list