[gnome-control-center] bluetooth: Avoid possible loops when Connection fails



commit 876e4d45598333f07aff71769f38fac1d92ab1bc
Author: Bastien Nocera <hadess hadess net>
Date:   Thu Nov 8 17:56:26 2012 +0100

    bluetooth: Avoid possible loops when Connection fails
    
    If we switch "Connection" on via the switch, the disabling on failure
    will create a loop where it always tries to connect again. Break that
    loop.

 panels/bluetooth/cc-bluetooth-panel.c |   46 ++++++++++++++++++++++++++++++---
 1 files changed, 42 insertions(+), 4 deletions(-)
---
diff --git a/panels/bluetooth/cc-bluetooth-panel.c b/panels/bluetooth/cc-bluetooth-panel.c
index 0a1c6e5..0ace8ac 100644
--- a/panels/bluetooth/cc-bluetooth-panel.c
+++ b/panels/bluetooth/cc-bluetooth-panel.c
@@ -54,6 +54,7 @@ struct CcBluetoothPanelPrivate {
 	BluetoothClient     *client;
 	BluetoothKillswitch *killswitch;
 	gboolean             debug;
+	GHashTable          *connecting_devices;
 };
 
 static void cc_bluetooth_panel_finalize (GObject *object);
@@ -109,11 +110,36 @@ cc_bluetooth_panel_finalize (GObject *object)
 		self->priv->client = NULL;
 	}
 
+	g_clear_pointer (&self->priv->connecting_devices, g_hash_table_destroy);
 	g_clear_pointer (&self->priv->selected_bdaddr, g_free);
 
 	G_OBJECT_CLASS (cc_bluetooth_panel_parent_class)->finalize (object);
 }
 
+static void
+remove_connecting (CcBluetoothPanel *self,
+		   const char       *bdaddr)
+{
+	g_hash_table_remove (self->priv->connecting_devices, bdaddr);
+}
+
+static void
+add_connecting (CcBluetoothPanel *self,
+		const char       *bdaddr)
+{
+	g_hash_table_insert (self->priv->connecting_devices,
+			     g_strdup (bdaddr),
+			     GINT_TO_POINTER (1));
+}
+
+static gboolean
+is_connecting (CcBluetoothPanel *self,
+	       const char       *bdaddr)
+{
+	return GPOINTER_TO_INT (g_hash_table_lookup (self->priv->connecting_devices,
+						     bdaddr));
+}
+
 typedef struct {
 	char             *bdaddr;
 	CcBluetoothPanel *self;
@@ -134,7 +160,7 @@ connect_done (GObject      *source_object,
 
 	self = data->self;
 
-	/* Check whether the same device is now selected */
+	/* Check whether the same device is now selected, and update the UI */
 	bdaddr = bluetooth_chooser_get_selected_device (BLUETOOTH_CHOOSER (self->priv->chooser));
 	if (g_strcmp0 (bdaddr, data->bdaddr) == 0) {
 		GtkSwitch *button;
@@ -146,6 +172,8 @@ connect_done (GObject      *source_object,
 		gtk_widget_set_sensitive (GTK_WIDGET (button), TRUE);
 	}
 
+	remove_connecting (self, data->bdaddr);
+
 	g_free (bdaddr);
 	g_object_unref (data->self);
 	g_free (data->bdaddr);
@@ -160,6 +188,13 @@ switch_connected_active_changed (GtkSwitch        *button,
 	char *proxy;
 	GValue value = { 0, };
 	ConnectData *data;
+	char *bdaddr;
+
+	bdaddr = bluetooth_chooser_get_selected_device (BLUETOOTH_CHOOSER (self->priv->chooser));
+	if (is_connecting (self, bdaddr)) {
+		g_free (bdaddr);
+		return;
+	}
 
 	if (bluetooth_chooser_get_selected_device_info (BLUETOOTH_CHOOSER (self->priv->chooser),
 							"proxy", &value) == FALSE) {
@@ -173,7 +208,7 @@ switch_connected_active_changed (GtkSwitch        *button,
 		return;
 
 	data = g_new0 (ConnectData, 1);
-	data->bdaddr = bluetooth_chooser_get_selected_device (BLUETOOTH_CHOOSER (self->priv->chooser));
+	data->bdaddr = bdaddr;
 	data->self = g_object_ref (self);
 
 	bluetooth_client_connect_service (self->priv->client,
@@ -183,8 +218,7 @@ switch_connected_active_changed (GtkSwitch        *button,
 					  connect_done,
 					  data);
 
-	/* FIXME: make a note somewhere that the button for that
-	 * device should be disabled */
+	add_connecting (self, data->bdaddr);
 	gtk_widget_set_sensitive (GTK_WIDGET (button), FALSE);
 	g_free (proxy);
 }
@@ -736,6 +770,10 @@ cc_bluetooth_panel_init (CcBluetoothPanel *self)
 	bluetooth_plugin_manager_init ();
 	self->priv->killswitch = bluetooth_killswitch_new ();
 	self->priv->client = bluetooth_client_new ();
+	self->priv->connecting_devices = g_hash_table_new_full (g_str_hash,
+								g_str_equal,
+								(GDestroyNotify) g_free,
+								NULL);
 	self->priv->debug = g_getenv ("BLUETOOTH_DEBUG") != NULL;
 
 	self->priv->builder = gtk_builder_new ();



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]