[gnome-bluetooth] settings: Better support for remote-initiated pairing



commit 52308ffcccbceac8d16915ecb5157e24fd64cff4
Author: Bastien Nocera <hadess hadess net>
Date:   Mon Dec 9 13:39:43 2013 +0100

    settings: Better support for remote-initiated pairing
    
    When the pairing is remote initiated, show a dialogue that'll
    only ask to enter the same PIN as on the remote device, and
    dismiss the dialogue straight away.

 lib/bluetooth-pairing-dialog.c  |   12 ++++++++++--
 lib/bluetooth-pairing-dialog.h  |    1 +
 lib/bluetooth-settings-widget.c |   36 ++++++++++++++++++++++++++++++++----
 3 files changed, 43 insertions(+), 6 deletions(-)
---
diff --git a/lib/bluetooth-pairing-dialog.c b/lib/bluetooth-pairing-dialog.c
index 57809ff..bb4f3eb 100644
--- a/lib/bluetooth-pairing-dialog.c
+++ b/lib/bluetooth-pairing-dialog.c
@@ -77,6 +77,12 @@ bluetooth_pairing_dialog_set_mode (BluetoothPairingDialog *self,
        gtk_label_set_text (GTK_LABEL (priv->label_pin), pin);
 
        switch (mode) {
+       case BLUETOOTH_PAIRING_MODE_PIN_QUERY:
+               gtk_widget_show (priv->done);
+               gtk_button_set_label (GTK_BUTTON (priv->done), _("Done"));
+               gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->pin_notebook), CONFIRMATION_PAGE);
+               help = g_strdup_printf (_("Please enter the PIN code entered on '%s':"), device_name);
+               break;
        case BLUETOOTH_PAIRING_MODE_PIN_CONFIRMATION:
                gtk_widget_show (priv->done);
                gtk_button_set_label (GTK_BUTTON (priv->done), _("Done"));
@@ -136,7 +142,8 @@ bluetooth_pairing_dialog_get_pin (BluetoothPairingDialog *self)
 {
        BluetoothPairingDialogPrivate *priv = BLUETOOTH_PAIRING_DIALOG_GET_PRIVATE (self);
 
-       g_assert (priv->mode == BLUETOOTH_PAIRING_MODE_PIN_CONFIRMATION);
+       g_assert (priv->mode == BLUETOOTH_PAIRING_MODE_PIN_CONFIRMATION ||
+                 priv->mode == BLUETOOTH_PAIRING_MODE_PIN_QUERY);
        g_assert (gtk_widget_is_sensitive (GTK_WIDGET (priv->done)));
 
        return g_strdup (gtk_entry_get_text (GTK_ENTRY (priv->entry_pin)));
@@ -199,7 +206,8 @@ text_changed_cb (GObject    *gobject,
        BluetoothPairingDialogPrivate *priv = BLUETOOTH_PAIRING_DIALOG_GET_PRIVATE (user_data);
        const char *text;
 
-       if (priv->mode != BLUETOOTH_PAIRING_MODE_PIN_CONFIRMATION)
+       if (priv->mode != BLUETOOTH_PAIRING_MODE_PIN_CONFIRMATION &&
+           priv->mode != BLUETOOTH_PAIRING_MODE_PIN_QUERY)
                return;
 
        text = gtk_entry_get_text (GTK_ENTRY (priv->entry_pin));
diff --git a/lib/bluetooth-pairing-dialog.h b/lib/bluetooth-pairing-dialog.h
index a30f8b7..2952b63 100644
--- a/lib/bluetooth-pairing-dialog.h
+++ b/lib/bluetooth-pairing-dialog.h
@@ -55,6 +55,7 @@ struct _BluetoothPairingDialogClass {
 };
 
 typedef enum {
+       BLUETOOTH_PAIRING_MODE_PIN_QUERY,
        BLUETOOTH_PAIRING_MODE_PIN_CONFIRMATION,
        BLUETOOTH_PAIRING_MODE_PIN_DISPLAY_NORMAL,
        BLUETOOTH_PAIRING_MODE_PIN_DISPLAY_KEYBOARD,
diff --git a/lib/bluetooth-settings-widget.c b/lib/bluetooth-settings-widget.c
index be42977..dd54a06 100644
--- a/lib/bluetooth-settings-widget.c
+++ b/lib/bluetooth-settings-widget.c
@@ -53,6 +53,7 @@ struct _BluetoothSettingsWidgetPrivate {
        /* Pairing */
        BluetoothAgent      *agent;
        GtkWidget           *pairing_dialog;
+       GHashTable          *pairing_devices; /* key=object-path, value=boolean */
 
        /* Properties */
        GtkWidget           *properties_dialog;
@@ -312,6 +313,11 @@ enter_pin_cb (GtkDialog *dialog,
                pin = bluetooth_pairing_dialog_get_pin (BLUETOOTH_PAIRING_DIALOG (dialog));
                g_dbus_method_invocation_return_value (invocation,
                                                       g_variant_new ("(s)", pin));
+
+               if (bluetooth_pairing_dialog_get_mode (BLUETOOTH_PAIRING_DIALOG (priv->pairing_dialog)) == 
BLUETOOTH_PAIRING_MODE_PIN_QUERY) {
+                       g_clear_pointer (&priv->pairing_dialog, gtk_widget_destroy);
+                       return;
+               }
                bluetooth_pairing_dialog_set_mode (BLUETOOTH_PAIRING_DIALOG (priv->pairing_dialog),
                                                   mode, pin, name);
                g_free (pin);
@@ -343,6 +349,7 @@ pincode_callback (GDBusMethodInvocation *invocation,
        char *default_pin;
        char *display_pin = NULL;
        BluetoothPairingMode mode;
+       gboolean remote_initiated;
 
        g_debug ("pincode_callback (%s)", g_dbus_proxy_get_object_path (device));
 
@@ -355,6 +362,9 @@ pincode_callback (GDBusMethodInvocation *invocation,
                return;
        }
 
+       remote_initiated = !GPOINTER_TO_UINT (g_hash_table_lookup (priv->pairing_devices,
+                                                                  g_dbus_proxy_get_object_path (device)));
+
        default_pin = get_pincode_for_device (type, bdaddr, name, &max_digits, &confirm_pin);
        if (g_strcmp0 (default_pin, "KEYBOARD") == 0) {
                mode = BLUETOOTH_PAIRING_MODE_PIN_DISPLAY_KEYBOARD;
@@ -384,10 +394,17 @@ pincode_callback (GDBusMethodInvocation *invocation,
 
        if (confirm_pin) {
                g_object_set_data (G_OBJECT (priv->pairing_dialog), "invocation", invocation);
-               bluetooth_pairing_dialog_set_mode (BLUETOOTH_PAIRING_DIALOG (priv->pairing_dialog),
-                                                  BLUETOOTH_PAIRING_MODE_PIN_CONFIRMATION,
-                                                  default_pin,
-                                                  name);
+               if (remote_initiated) {
+                       bluetooth_pairing_dialog_set_mode (BLUETOOTH_PAIRING_DIALOG (priv->pairing_dialog),
+                                                          BLUETOOTH_PAIRING_MODE_PIN_QUERY,
+                                                          default_pin,
+                                                          name);
+               } else {
+                       bluetooth_pairing_dialog_set_mode (BLUETOOTH_PAIRING_DIALOG (priv->pairing_dialog),
+                                                          BLUETOOTH_PAIRING_MODE_PIN_CONFIRMATION,
+                                                          default_pin,
+                                                          name);
+               }
                g_signal_connect (G_OBJECT (priv->pairing_dialog), "response",
                                  G_CALLBACK (enter_pin_cb), user_data);
        } else {
@@ -650,6 +667,8 @@ create_callback (GObject      *source_object,
 
        g_clear_pointer (&priv->pairing_dialog, gtk_widget_destroy);
 
+       g_hash_table_remove (priv->pairing_devices, path);
+
        /* Create failed */
        if (ret == FALSE) {
                //char *text;
@@ -769,6 +788,10 @@ start_pairing (BluetoothSettingsWidget *self,
                 g_dbus_proxy_get_object_path (proxy),
                 legacy_pairing, pair);
 
+       g_hash_table_insert (priv->pairing_devices,
+                            g_strdup (g_dbus_proxy_get_object_path (proxy)),
+                            GINT_TO_POINTER (1));
+
        bluetooth_client_setup_device (priv->client,
                                       g_dbus_proxy_get_object_path (proxy),
                                       pair,
@@ -1630,6 +1653,10 @@ bluetooth_settings_widget_init (BluetoothSettingsWidget *self)
                                                                g_str_equal,
                                                                (GDestroyNotify) g_free,
                                                                NULL);
+       priv->pairing_devices = g_hash_table_new_full (g_str_hash,
+                                                      g_str_equal,
+                                                      (GDestroyNotify) g_free,
+                                                      NULL);
 
        setup_pairing_agent (self);
        priv->client = bluetooth_client_new ();
@@ -1701,6 +1728,7 @@ bluetooth_settings_widget_finalize (GObject *object)
        g_clear_object (&priv->builder);
 
        g_clear_pointer (&priv->connecting_devices, g_hash_table_destroy);
+       g_clear_pointer (&priv->pairing_devices, g_hash_table_destroy);
        g_clear_pointer (&priv->selected_name, g_free);
        g_clear_pointer (&priv->selected_object_path, g_free);
 


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