Hi:<div>   I am puzzled by some functions calling in the function : "spice_usb_device_manager_initable_init"</div><div><br></div><div>At this block:    </div><div> /* Do coldplug (detection of already connected devices) */<div>
    libusb_get_device_list(priv->context, &priv->coldplug_list);</div><div>    list = g_udev_client_query_by_subsystem(priv->udev, "usb");</div><div>...</div><div>...</div><div><div>    libusb_free_device_list(priv->coldplug_list, 1);</div>
<div>    priv->coldplug_list = NULL;</div></div><div><br></div><div>My questions are as follows:</div><div>1. Well, it seems that there are two routines to gather information of the  already connected devices :</div><div>
"libusb_get_device_list" and "
g_udev_client_query_by_subsystem " ,  which is the really for wok one ? </div><div>"g_udev_client_query_by_subsystem" seems to be , am I right ?</div><div><br></div><div>2. So, the second question is, why we gather info to "priv->coldplug_list", as the codes above, it just be freed, and has never been used!</div>
<div><br></div><div><b><font color="#ff6666">list : </font></b></div><div>I type the descriptions of these two lists, as you can see that the ids of them are very different, Why???</div><div><div> desc Linux 3.2.0-23-generic-pae ehci_hcd EHCI Host Controller [1d6b:0002] at 1-1 </div>
<div> desc Linux 3.2.0-23-generic-pae uhci_hcd UHCI Host Controller [1d6b:0001] at 2-1 </div><div> desc Linux 3.2.0-23-generic-pae uhci_hcd UHCI Host Controller [1d6b:0001] at 3-1 </div><div> desc Linux 3.2.0-23-generic-pae uhci_hcd UHCI Host Controller [1d6b:0001] at 4-1 </div>
<div> desc Linux 3.2.0-23-generic-pae uhci_hcd UHCI Host Controller [1d6b:0001] at 5-1 </div><div> desc NEC Corp. HighSpeed Hub [0409:005a] at 1-4 </div><div> desc Alcor Micro Corp. USB Hub [058f:6254] at 1-5 </div><div> desc USB Keykoard [1a2c:0021] at 3-2 </div>
<div> desc Logitech USB-PS/2 Optical Mouse [046d:c045] at 3-3 </div><div> desc USB 2.0 Peripheral Switch USB 2.0 Peripheral Switch [0557:2407] at 1-6 </div><div><br></div><div><b><font color="#ff0000">priv->coldplug_list : </font></b></div>
<div> name usb2 </div><div> name 2-0:1.0 </div><div> name usb3 </div><div> name 3-0:1.0 </div><div> name 3-1 </div><div> name 3-1:1.0 </div><div> name 3-1:1.1 </div><div> name 3-2 </div><div> name 3-2:1.0 </div><div> name usb4 </div>
<div> name 4-0:1.0 </div><div> name usb5 </div><div> name 5-0:1.0 </div><div> name usb1 </div><div> name 1-0:1.0 </div><div> name 1-5 </div><div> name 1-5.2 </div><div> name 1-5.2:1.0 </div><div> name 1-5.2:1.1 </div><div>
 name hiddev0 </div><div> name 1-5:1.0 </div><div> name 1-8 </div><div> name 1-8:1.0 </div></div><div><br></div><div>and the codes I get the log above are attached.</div><div><br></div><div>Thanks a lot! Looking forward to you !!!</div>
<div><br></div><div><br></div><div><br></div><br><div class="gmail_quote">2012/6/14 Hans de Goede <span dir="ltr"><<a href="mailto:hdegoede@redhat.com" target="_blank">hdegoede@redhat.com</a>></span><br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Signed-off-by: Hans de Goede <<a href="mailto:hdegoede@redhat.com">hdegoede@redhat.com</a>><br>
---<br>
 doc/reference/spice-gtk-sections.txt |    2 +<br>
 gtk/map-file                         |    2 +<br>
 gtk/usb-device-manager.c             |  130 ++++++++++++++++++++++++++++++++--<br>
 gtk/usb-device-manager.h             |    5 ++<br>
 4 files changed, 132 insertions(+), 7 deletions(-)<br>
<br>
diff --git a/doc/reference/spice-gtk-sections.txt b/doc/reference/spice-gtk-sections.txt<br>
index a339d32..7eea1fb 100644<br>
--- a/doc/reference/spice-gtk-sections.txt<br>
+++ b/doc/reference/spice-gtk-sections.txt<br>
@@ -293,6 +293,8 @@ spice_usb_device_manager_disconnect_device<br>
 spice_usb_device_manager_can_redirect_device<br>
 spice_usb_device_manager_connect_device_async<br>
 spice_usb_device_manager_connect_device_finish<br>
+spice_usb_device_manager_disable_automounting<br>
+spice_usb_device_manager_restore_automounting<br>
 <SUBSECTION><br>
 SpiceUsbDevice<br>
 spice_usb_device_get_description<br>
diff --git a/gtk/map-file b/gtk/map-file<br>
index 32ead37..dd3495c 100644<br>
--- a/gtk/map-file<br>
+++ b/gtk/map-file<br>
@@ -89,11 +89,13 @@ spice_usb_device_get_type;<br>
 spice_usb_device_manager_can_redirect_device;<br>
 spice_usb_device_manager_connect_device_async;<br>
 spice_usb_device_manager_connect_device_finish;<br>
+spice_usb_device_manager_disable_automounting;<br>
 spice_usb_device_manager_disconnect_device;<br>
 spice_usb_device_manager_get;<br>
 spice_usb_device_manager_get_devices;<br>
 spice_usb_device_manager_get_type;<br>
 spice_usb_device_manager_is_device_connected;<br>
+spice_usb_device_manager_restore_automounting;<br>
 spice_usb_device_widget_get_type;<br>
 spice_usb_device_widget_new;<br>
 spice_usbredir_channel_get_type;<br>
diff --git a/gtk/usb-device-manager.c b/gtk/usb-device-manager.c<br>
index 25cb14a..bf08b95 100644<br>
--- a/gtk/usb-device-manager.c<br>
+++ b/gtk/usb-device-manager.c<br>
@@ -34,6 +34,7 @@<br>
 #include "usbutil.h"<br>
 #endif<br>
<br>
+#include "desktop-integration.h"<br>
 #include "spice-session-priv.h"<br>
 #include "spice-client.h"<br>
 #include "spice-marshal.h"<br>
@@ -96,6 +97,8 @@ struct _SpiceUsbDeviceManagerPrivate {<br>
     libusb_device **coldplug_list; /* Avoid needless reprobing during init */<br>
     struct usbredirfilter_rule *auto_conn_filter_rules;<br>
     int auto_conn_filter_rules_count;<br>
+    int disable_automount;<br>
+    guint update_automount_id;<br>
 #endif<br>
     GPtrArray *devices;<br>
     GPtrArray *channels;<br>
@@ -284,9 +287,17 @@ static void spice_usb_device_manager_set_property(GObject       *gobject,<br>
     case PROP_SESSION:<br>
         priv->session = g_value_get_object(value);<br>
         break;<br>
-    case PROP_AUTO_CONNECT:<br>
-        priv->auto_connect = g_value_get_boolean(value);<br>
+    case PROP_AUTO_CONNECT: {<br>
+        gboolean new_val = g_value_get_boolean(value);<br>
+        if (priv->auto_connect != new_val) {<br>
+            priv->auto_connect = new_val;<br>
+            if (priv->auto_connect)<br>
+                spice_usb_device_manager_disable_automounting(self);<br>
+            else<br>
+                spice_usb_device_manager_restore_automounting(self);<br>
+        }<br>
         break;<br>
+    }<br>
     case PROP_AUTO_CONNECT_FILTER: {<br>
         const gchar *filter = g_value_get_string(value);<br>
 #ifdef USE_USBREDIR<br>
@@ -341,6 +352,15 @@ static void spice_usb_device_manager_class_init(SpiceUsbDeviceManagerClass *klas<br>
<br>
     /**<br>
      * SpiceUsbDeviceManager:auto-connect:<br>
+     *<br>
+     * Set this to TRUE to automatically redirect newly plugged in device.<br>
+     *<br>
+     * When this property changes from FALSE to TRUE, #SpiceUsbDeviceManager<br>
+     * calls spice_usb_device_manager_disable_automounting() once, and on TRUE<br>
+     * to FALSE it calls spice_usb_device_manager_restore_automounting().<br>
+     *<br>
+     * Note when #SpiceGtkSession's auto-usbredir property is TRUE, this<br>
+     * property is controlled by #SpiceGtkSession.<br>
      */<br>
     pspec = g_param_spec_boolean("auto-connect", "Auto Connect",<br>
                                  "Auto connect plugged in USB devices",<br>
@@ -642,19 +662,33 @@ static void spice_usb_device_manager_uevent_cb(GUdevClient     *client,<br>
         spice_usb_device_manager_remove_dev(self, udevice);<br>
 }<br>
<br>
+struct channel_connect_cb_data {<br>
+    GSimpleAsyncResult *result;<br>
+    gboolean restore_automount;<br>
+};<br>
+<br>
 static void spice_usb_device_manager_channel_connect_cb(<br>
     GObject *gobject, GAsyncResult *channel_res, gpointer user_data)<br>
 {<br>
     SpiceUsbredirChannel *channel = SPICE_USBREDIR_CHANNEL(gobject);<br>
-    GSimpleAsyncResult *result = G_SIMPLE_ASYNC_RESULT(user_data);<br>
+    struct channel_connect_cb_data *data = user_data;<br>
+    SpiceUsbDeviceManager *self;<br>
     GError *err = NULL;<br>
<br>
     spice_usbredir_channel_connect_device_finish(channel, channel_res, &err);<br>
     if (err) {<br>
-        g_simple_async_result_take_error(result, err);<br>
+        g_simple_async_result_take_error(data->result, err);<br>
     }<br>
-    g_simple_async_result_complete(result);<br>
-    g_object_unref(result);<br>
+<br>
+    if (data->restore_automount) {<br>
+        self = SPICE_USB_DEVICE_MANAGER(g_async_result_get_source_object(<br>
+                                               G_ASYNC_RESULT(data->result)));<br>
+        spice_usb_device_manager_restore_automounting(self);<br>
+    }<br>
+<br>
+    g_simple_async_result_complete(data->result);<br>
+    g_object_unref(data->result);<br>
+    g_free(data);<br>
 }<br>
<br>
 /* ------------------------------------------------------------------ */<br>
@@ -848,6 +882,7 @@ void spice_usb_device_manager_connect_device_async(SpiceUsbDeviceManager *self,<br>
<br>
 #ifdef USE_USBREDIR<br>
     SpiceUsbDeviceManagerPrivate *priv = self->priv;<br>
+    struct channel_connect_cb_data *data;<br>
     guint i;<br>
<br>
     if (spice_usb_device_manager_is_device_connected(self, device)) {<br>
@@ -863,11 +898,18 @@ void spice_usb_device_manager_connect_device_async(SpiceUsbDeviceManager *self,<br>
         if (spice_usbredir_channel_get_device(channel))<br>
             continue; /* Skip already used channels */<br>
<br>
+        data = g_new0(struct channel_connect_cb_data, 1);<br>
+        data->result = result;<br>
+        /* If automount is disabled, ensure it stays disabled while we run */<br>
+        if (priv->disable_automount) {<br>
+            spice_usb_device_manager_disable_automounting(self);<br>
+            data->restore_automount = TRUE;<br>
+        }<br>
         spice_usbredir_channel_connect_device_async(channel,<br>
                                  (libusb_device *)device,<br>
                                  cancellable,<br>
                                  spice_usb_device_manager_channel_connect_cb,<br>
-                                 result);<br>
+                                 data);<br>
         return;<br>
     }<br>
 #endif<br>
@@ -1047,3 +1089,77 @@ gchar *spice_usb_device_get_description(SpiceUsbDevice *_device, const gchar *fo<br>
     return NULL;<br>
 #endif<br>
 }<br>
+<br>
+/* ------------------------------------------------------------------ */<br>
+/* Automount disable helper functions                                 */<br>
+<br>
+static gboolean spice_usb_device_manager_update_automount(gpointer user_data)<br>
+{<br>
+    SpiceUsbDeviceManager *self = SPICE_USB_DEVICE_MANAGER(user_data);<br>
+    SpiceUsbDeviceManagerPrivate *priv = self->priv;<br>
+    SpiceDesktopIntegration *di = spice_desktop_integration_get(priv->session);<br>
+<br>
+    if (priv->disable_automount == 0)<br>
+        spice_desktop_integration_restore_automount(di);<br>
+<br>
+    priv->update_automount_id = 0;<br>
+    return FALSE;<br>
+}<br>
+<br>
+/**<br>
+ * spice_usb_device_manager_disable_automounting:<br>
+ * @manager: the #SpiceUsbDeviceManager manager<br>
+ *<br>
+ * Disables automounting of newly plugged in devices by the client OS, to avoid<br>
+ * newly plugged in devices getting mounted by the client OS, before they can<br>
+ * be redirected.<br>
+ *<br>
+ * When this function gets called multiple times,<br>
+ * spice_usb_device_manager_restore_automounting() must be called the same<br>
+ * amount of times, before automounting gets restored.<br>
+ */<br>
+void spice_usb_device_manager_disable_automounting(SpiceUsbDeviceManager *self)<br>
+{<br>
+#ifdef USE_USBREDIR<br>
+    SpiceUsbDeviceManagerPrivate *priv = self->priv;<br>
+    SpiceDesktopIntegration *di = spice_desktop_integration_get(priv->session);<br>
+<br>
+    priv->disable_automount++;<br>
+    if (priv->disable_automount == 1)<br>
+        spice_desktop_integration_disable_automount(di);<br>
+#endif<br>
+}<br>
+<br>
+/**<br>
+ * spice_usb_device_manager_restore_automounting:<br>
+ * @manager: the #SpiceUsbDeviceManager manager<br>
+ *<br>
+ * Restores automounting of newly plugged in devices by the client OS, to its<br>
+ * original state. If it was disabled already before calling<br>
+ * spice_usb_device_manager_disable_automounting() this is a no-op.<br>
+ *<br>
+ * If spice_usb_device_manager_disable_automounting() has been called multiple<br>
+ * times, this function will not restore automounting until it has been called<br>
+ * the same amount of times.<br>
+ */<br>
+void spice_usb_device_manager_restore_automounting(SpiceUsbDeviceManager *self)<br>
+{<br>
+#ifdef USE_USBREDIR<br>
+    SpiceUsbDeviceManagerPrivate *priv = self->priv;<br>
+<br>
+    g_return_if_fail(priv->disable_automount > 0);<br>
+<br>
+    priv->disable_automount--;<br>
+    if (priv->disable_automount)<br>
+        return;<br>
+<br>
+    /*<br>
+     * Re-enable automount from a timer, to avoid unnecessary ping-ponging<br>
+     * automount when switching between the windows of a multi monitor vm.<br>
+     */<br>
+    if (priv->update_automount_id)<br>
+        g_source_remove(priv->update_automount_id);<br>
+    priv->update_automount_id =<br>
+        g_timeout_add(50, spice_usb_device_manager_update_automount, self);<br>
+#endif<br>
+}<br>
diff --git a/gtk/usb-device-manager.h b/gtk/usb-device-manager.h<br>
index df138ee..b01fe98 100644<br>
--- a/gtk/usb-device-manager.h<br>
+++ b/gtk/usb-device-manager.h<br>
@@ -114,6 +114,11 @@ spice_usb_device_manager_can_redirect_device(SpiceUsbDeviceManager  *self,<br>
                                              SpiceUsbDevice         *device,<br>
                                              GError                **err);<br>
<br>
+void spice_usb_device_manager_disable_automounting(<br>
+                                             SpiceUsbDeviceManager *manager);<br>
+void spice_usb_device_manager_restore_automounting(<br>
+                                             SpiceUsbDeviceManager *manager);<br>
+<br>
 G_END_DECLS<br>
<br>
 #endif /* __SPICE_USB_DEVICE_MANAGER_H__ */<br>
<span class="HOEnZb"><font color="#888888">--<br>
1.7.10.2<br>
<br>
_______________________________________________<br>
Spice-devel mailing list<br>
<a href="mailto:Spice-devel@lists.freedesktop.org">Spice-devel@lists.freedesktop.org</a><br>
<a href="http://lists.freedesktop.org/mailman/listinfo/spice-devel" target="_blank">http://lists.freedesktop.org/mailman/listinfo/spice-devel</a><br>
</font></span></blockquote></div><br></div>