diff options
author | Xavier Claessens <xclaesse@gmail.com> | 2009-04-24 00:54:21 +0800 |
---|---|---|
committer | Xavier Claessens <xclaesse@gmail.com> | 2009-04-25 03:21:28 +0800 |
commit | 063625395264373ce915fac0ac03562527c7bf51 (patch) | |
tree | a74015a59c10cee83bf636e4b2ca00fde4c1a5f6 | |
parent | 207f9d47f2630cf9c8919d41bd2a246103520c14 (diff) | |
download | gsoc2013-empathy-063625395264373ce915fac0ac03562527c7bf51.tar gsoc2013-empathy-063625395264373ce915fac0ac03562527c7bf51.tar.gz gsoc2013-empathy-063625395264373ce915fac0ac03562527c7bf51.tar.bz2 gsoc2013-empathy-063625395264373ce915fac0ac03562527c7bf51.tar.lz gsoc2013-empathy-063625395264373ce915fac0ac03562527c7bf51.tar.xz gsoc2013-empathy-063625395264373ce915fac0ac03562527c7bf51.tar.zst gsoc2013-empathy-063625395264373ce915fac0ac03562527c7bf51.zip |
Display the file transfer speed and calculate remaining time more dynamically.
-rw-r--r-- | libempathy/empathy-tp-file.c | 90 | ||||
-rw-r--r-- | libempathy/empathy-tp-file.h | 1 | ||||
-rw-r--r-- | src/empathy-ft-manager.c | 24 |
3 files changed, 93 insertions, 22 deletions
diff --git a/libempathy/empathy-tp-file.c b/libempathy/empathy-tp-file.c index 6796f5a0b..3723f35c3 100644 --- a/libempathy/empathy-tp-file.c +++ b/libempathy/empathy-tp-file.c @@ -69,6 +69,7 @@ #define N_BUFFERS 2 #define BUFFER_SIZE 4096 +#define STALLED_TIMEOUT 5 typedef struct { GInputStream *in; @@ -298,7 +299,11 @@ struct _EmpathyTpFilePriv { gboolean incoming; TpFileTransferStateChangeReason state_change_reason; - time_t start_time; + time_t last_update_time; + guint64 last_update_transferred_bytes; + gdouble speed; + gint remaining_time; + guint stalled_id; GValue *socket_address; GCancellable *cancellable; }; @@ -317,6 +322,13 @@ enum { PROP_CONTENT_HASH, }; +enum { + REFRESH, + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL]; + G_DEFINE_TYPE (EmpathyTpFile, empathy_tp_file, G_TYPE_OBJECT); static void @@ -391,9 +403,25 @@ tp_file_finalize (GObject *object) if (tp_file->priv->cancellable) g_object_unref (tp_file->priv->cancellable); + if (tp_file->priv->stalled_id != 0) + g_source_remove (tp_file->priv->stalled_id); + G_OBJECT_CLASS (empathy_tp_file_parent_class)->finalize (object); } +static gboolean +tp_file_stalled_cb (EmpathyTpFile *tp_file) +{ + /* We didn't get transferred bytes update for a while, the transfer is + * stalled. */ + + tp_file->priv->speed = 0; + tp_file->priv->remaining_time = -1; + g_signal_emit (tp_file, signals[REFRESH], 0); + + return FALSE; +} + static void tp_file_start_transfer (EmpathyTpFile *tp_file) { @@ -425,7 +453,11 @@ tp_file_start_transfer (EmpathyTpFile *tp_file) DEBUG ("Start the transfer"); - tp_file->priv->start_time = empathy_time_get_current (); + tp_file->priv->last_update_time = empathy_time_get_current (); + tp_file->priv->last_update_transferred_bytes = tp_file->priv->transferred_bytes; + tp_file->priv->stalled_id = g_timeout_add_seconds (STALLED_TIMEOUT, + (GSourceFunc) tp_file_stalled_cb, tp_file); + tp_file->priv->cancellable = g_cancellable_new (); if (tp_file->priv->incoming) { @@ -487,12 +519,40 @@ tp_file_transferred_bytes_changed_cb (TpChannel *channel, GObject *weak_object) { EmpathyTpFile *tp_file = EMPATHY_TP_FILE (weak_object); + time_t curr_time, elapsed_time; + guint64 transferred_bytes; + /* If we didn't progress since last update, return */ if (tp_file->priv->transferred_bytes == count) return; + /* Update the transferred bytes count */ tp_file->priv->transferred_bytes = count; g_object_notify (G_OBJECT (tp_file), "transferred-bytes"); + + /* We got a progress, reset the stalled timeout */ + if (tp_file->priv->stalled_id != 0) + g_source_remove (tp_file->priv->stalled_id); + tp_file->priv->stalled_id = g_timeout_add_seconds (STALLED_TIMEOUT, + (GSourceFunc) tp_file_stalled_cb, tp_file); + + /* Calculate the transfer speed and remaining time estimation. We recalculate + * that each second to get more dynamic values that react faster to network + * changes. This is better than calculating the average from the begining of + * the transfer, I think. */ + curr_time = empathy_time_get_current (); + elapsed_time = curr_time - tp_file->priv->last_update_time; + if (elapsed_time > 1) + { + transferred_bytes = count - tp_file->priv->last_update_transferred_bytes; + tp_file->priv->speed = (gdouble) transferred_bytes / (gdouble) elapsed_time; + tp_file->priv->remaining_time = (tp_file->priv->size - count) / + tp_file->priv->speed; + tp_file->priv->last_update_transferred_bytes = count; + tp_file->priv->last_update_time = curr_time; + + g_signal_emit (tp_file, signals[REFRESH], 0); + } } static void @@ -986,10 +1046,6 @@ empathy_tp_file_get_transferred_bytes (EmpathyTpFile *tp_file) gint empathy_tp_file_get_remaining_time (EmpathyTpFile *tp_file) { - time_t curr_time, elapsed_time; - gdouble time_per_byte; - gdouble remaining_time; - g_return_val_if_fail (EMPATHY_IS_TP_FILE (tp_file), -1); if (tp_file->priv->size == EMPATHY_TP_FILE_UNKNOWN_SIZE) @@ -998,14 +1054,18 @@ empathy_tp_file_get_remaining_time (EmpathyTpFile *tp_file) if (tp_file->priv->transferred_bytes == tp_file->priv->size) return 0; - curr_time = empathy_time_get_current (); - elapsed_time = curr_time - tp_file->priv->start_time; - time_per_byte = (gdouble) elapsed_time / - (gdouble) tp_file->priv->transferred_bytes; - remaining_time = time_per_byte * (tp_file->priv->size - - tp_file->priv->transferred_bytes); + return tp_file->priv->remaining_time; +} - return (gint) remaining_time; +gdouble +empathy_tp_file_get_speed (EmpathyTpFile *tp_file) +{ + g_return_val_if_fail (EMPATHY_IS_TP_FILE (tp_file), 0); + + if (tp_file->priv->transferred_bytes == tp_file->priv->size) + return 0; + + return tp_file->priv->speed; } const gchar * @@ -1144,6 +1204,10 @@ empathy_tp_file_class_init (EmpathyTpFileClass *klass) 0, G_PARAM_READWRITE)); + signals[REFRESH] = g_signal_new ("refresh", G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, 0, NULL, NULL, + g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); + g_type_class_add_private (object_class, sizeof (EmpathyTpFilePriv)); } diff --git a/libempathy/empathy-tp-file.h b/libempathy/empathy-tp-file.h index 5f239c8e0..357372f1b 100644 --- a/libempathy/empathy-tp-file.h +++ b/libempathy/empathy-tp-file.h @@ -80,6 +80,7 @@ TpFileTransferState empathy_tp_file_get_state ( guint64 empathy_tp_file_get_size (EmpathyTpFile *tp_file); guint64 empathy_tp_file_get_transferred_bytes (EmpathyTpFile *tp_file); gint empathy_tp_file_get_remaining_time (EmpathyTpFile *tp_file); +gdouble empathy_tp_file_get_speed (EmpathyTpFile *tp_file); const gchar *empathy_tp_file_get_content_type (EmpathyTpFile *tp_file); gboolean empathy_tp_file_is_ready (EmpathyTpFile *tp_file); diff --git a/src/empathy-ft-manager.c b/src/empathy-ft-manager.c index 98e58d4f3..d3d22fbd8 100644 --- a/src/empathy-ft-manager.c +++ b/src/empathy-ft-manager.c @@ -200,6 +200,7 @@ ft_manager_update_ft_row (EmpathyFTManager *ft_manager, TpFileTransferState state; TpFileTransferStateChangeReason reason; gboolean incoming; + gdouble speed; row_ref = ft_manager_get_row_from_tp_file (ft_manager, tp_file); g_return_if_fail (row_ref != NULL); @@ -210,6 +211,7 @@ ft_manager_update_ft_row (EmpathyFTManager *ft_manager, total_size = empathy_tp_file_get_size (tp_file); state = empathy_tp_file_get_state (tp_file, &reason); incoming = empathy_tp_file_is_incoming (tp_file); + speed = empathy_tp_file_get_speed (tp_file); switch (state) { @@ -234,6 +236,7 @@ ft_manager_update_ft_row (EmpathyFTManager *ft_manager, { gchar *total_size_str; gchar *transferred_bytes_str; + gchar *speed_str; if (total_size == EMPATHY_TP_FILE_UNKNOWN_SIZE) total_size_str = g_strdup (C_("file size", "Unknown")); @@ -241,13 +244,15 @@ ft_manager_update_ft_row (EmpathyFTManager *ft_manager, total_size_str = g_format_size_for_display (total_size); transferred_bytes_str = g_format_size_for_display (transferred_bytes); + speed_str = g_format_size_for_display (speed); /* translators: first %s is the transferred size, second %s is * the total file size */ - second_line = g_strdup_printf (_("%s of %s"), transferred_bytes_str, - total_size_str); + second_line = g_strdup_printf (_("%s of %s at %s/s"), + transferred_bytes_str, total_size_str, speed_str); g_free (transferred_bytes_str); g_free (total_size_str); + g_free (speed_str); } else @@ -301,8 +306,10 @@ ft_manager_update_ft_row (EmpathyFTManager *ft_manager, if (remaining < 0) { - if (state != TP_FILE_TRANSFER_STATE_COMPLETED && - state != TP_FILE_TRANSFER_STATE_CANCELLED) + if (state == TP_FILE_TRANSFER_STATE_OPEN) + remaining_str = g_strdup (C_("remaining time", "Stalled")); + else if (state != TP_FILE_TRANSFER_STATE_COMPLETED && + state != TP_FILE_TRANSFER_STATE_CANCELLED) remaining_str = g_strdup (C_("remaining time", "Unknown")); } else @@ -334,9 +341,8 @@ ft_manager_update_ft_row (EmpathyFTManager *ft_manager, } static void -ft_manager_transferred_bytes_changed_cb (EmpathyTpFile *tp_file, - GParamSpec *pspec, - EmpathyFTManager *ft_manager) +ft_manager_refresh_cb (EmpathyTpFile *tp_file, + EmpathyFTManager *ft_manager) { ft_manager_update_ft_row (ft_manager, tp_file); } @@ -840,8 +846,8 @@ ft_manager_add_tp_file_to_list (EmpathyFTManager *ft_manager, ft_manager_update_ft_row (ft_manager, tp_file); g_signal_connect (tp_file, "notify::state", G_CALLBACK (ft_manager_state_changed_cb), ft_manager); - g_signal_connect (tp_file, "notify::transferred-bytes", - G_CALLBACK (ft_manager_transferred_bytes_changed_cb), ft_manager); + g_signal_connect (tp_file, "refresh", + G_CALLBACK (ft_manager_refresh_cb), ft_manager); gtk_window_present (GTK_WINDOW (ft_manager->priv->window)); } |