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