[banshee] Hardware: Add DeviceChanged signal for Dap.Mtp (bgo#729438)



commit 5a5cb82394519779c4ba641b7e993f4015714417
Author: Nicholas Little <arealityfarbetween googlemail com>
Date:   Thu Jun 19 14:30:24 2014 +0200

    Hardware: Add DeviceChanged signal for Dap.Mtp (bgo#729438)
    
    To use an MTP device, we must unmount it and release the connection that
    Gvfs makes. Prior to this patch, banshee considered two possible device
    events, added and removed so unmounts had to be covered by the latter
    case, causing MTP devices to be unmapped as they were being configured.
    
    This patch allows the state transition to occur with the assumption that
    the device is still physically present and allows devices which don't
    present a Mount in their VolumeAddedArgs to be recognised when their
    Mounts do become available. This has the added benefit that further down
    the line, we can add sources for yet-to-be-configured devices providing
    the user with setup or error handling instructions.
    
    As a test: without this patch, a Nexus7 device would not be recognized
    by Banshee when connecting it to a laptop running Ubuntu 14.04.
    
    Signed-off-by: Andrés G. Aragoneses <knocte gmail com>

 .../Banshee.Hardware.Gio/HardwareManager.cs        |   15 ++++
 .../Banshee.Hardware.Gio/LowLevel/Manager.cs       |   81 ++++++++++++++------
 .../Banshee.Hardware/HardwareManager.cs            |   13 +++
 .../Banshee.Hardware/IHardwareManager.cs           |   16 ++++
 .../Banshee.Dap.MassStorage/MassStorageSource.cs   |    9 ++-
 src/Dap/Banshee.Dap/Banshee.Dap/DapService.cs      |    6 ++
 6 files changed, 114 insertions(+), 26 deletions(-)
---
diff --git a/src/Backends/Banshee.Gio/Banshee.Hardware.Gio/HardwareManager.cs 
b/src/Backends/Banshee.Gio/Banshee.Hardware.Gio/HardwareManager.cs
index 7a299b1..10c506c 100644
--- a/src/Backends/Banshee.Gio/Banshee.Hardware.Gio/HardwareManager.cs
+++ b/src/Backends/Banshee.Gio/Banshee.Hardware.Gio/HardwareManager.cs
@@ -41,6 +41,7 @@ namespace Banshee.Hardware.Gio
         {
             manager = new Manager ();
             manager.DeviceAdded += HandleManagerDeviceAdded;
+            manager.DeviceChanged += HandleManagerDeviceChanged;
             manager.DeviceRemoved += HandleManagerDeviceRemoved;
         }
 
@@ -54,6 +55,11 @@ namespace Banshee.Hardware.Gio
             HandleManagerDeviceAdded (args.Device);
         }
 
+        private void HandleManagerDeviceChanged (object o, MountArgs args)
+        {
+            HandleManagerDeviceChanged (args.Device);
+        }
+
         void HandleManagerDeviceRemoved (object o, MountArgs args)
         {
             HandleManagerDeviceRemoved (args.Device);
@@ -71,6 +77,14 @@ namespace Banshee.Hardware.Gio
             }
         }
 
+        private void HandleManagerDeviceChanged (IDevice device)
+        {
+            var handler = DeviceChanged;
+            if (null != handler) {
+                handler (this, new DeviceChangedEventArgs (device));
+            }
+        }
+
         private void HandleManagerDeviceRemoved (IDevice device)
         {
             if (device == null) {
@@ -86,6 +100,7 @@ namespace Banshee.Hardware.Gio
 #region IHardwareManager
 
         public event DeviceAddedHandler DeviceAdded;
+        public event DeviceChangedHandler DeviceChanged;
         public event DeviceRemovedHandler DeviceRemoved;
 
         public IEnumerable<IDevice> GetAllDevices ()
diff --git a/src/Backends/Banshee.Gio/Banshee.Hardware.Gio/LowLevel/Manager.cs 
b/src/Backends/Banshee.Gio/Banshee.Hardware.Gio/LowLevel/Manager.cs
index 31971e5..be2e78b 100644
--- a/src/Backends/Banshee.Gio/Banshee.Hardware.Gio/LowLevel/Manager.cs
+++ b/src/Backends/Banshee.Gio/Banshee.Hardware.Gio/LowLevel/Manager.cs
@@ -3,8 +3,10 @@
 //
 // Author:
 //   Alex Launi <alex launi gmail com>
+//   Nicholas Little <arealityfarbetween googlemail com>
 //
 // Copyright (c) 2010 Alex Launi
+// Copyright (c) 2014 Nicholas Little
 //
 // Permission is hereby granted, free of charge, to any person obtaining a copy
 // of this software and associated documentation files (the "Software"), to deal
@@ -47,6 +49,7 @@ namespace Banshee.Hardware.Gio
         private Dictionary<IntPtr, GUdev.Device> volume_device_map;
 
         public event EventHandler<MountArgs> DeviceAdded;
+        public event EventHandler<MountArgs> DeviceChanged;
         public event EventHandler<MountArgs> DeviceRemoved;
 
         public Manager ()
@@ -55,6 +58,7 @@ namespace Banshee.Hardware.Gio
             monitor = VolumeMonitor.Default;
             monitor.MountAdded += HandleMonitorMountAdded;
             monitor.MountRemoved += HandleMonitorMountRemoved;
+            monitor.VolumeAdded += HandleMonitorVolumeAdded;
             monitor.VolumeRemoved += HandleMonitorVolumeRemoved;
             volume_device_map= new Dictionary<IntPtr, GUdev.Device> ();
         }
@@ -82,50 +86,77 @@ namespace Banshee.Hardware.Gio
 
         void HandleMonitorMountAdded (object o, MountAddedArgs args)
         {
-            // Manually get the mount as gio-sharp translates it to the wrong managed object
-            // TODO: check if this workaround is still needed
-            var mount = GLib.MountAdapter.GetObject ((GLib.Object) args.Args [0]);
-            if (mount.Volume == null)
-                return;
-
-            var device = GudevDeviceFromGioMount (mount);
-            if (device == null) {
-                Hyena.Log.Debug (string.Format ("Tried to mount {0}/{1} with no matching udev device", 
mount.Volume.Name, mount.Volume.Uuid));
-                return;
-            }
-
-            volume_device_map [mount.Volume.Handle] = device;
-            var h = DeviceAdded;
-            if (h != null) {
-                var v = CreateRawVolume (mount.Volume);
-                if (v == null) {
-                    return;
-                }
-                h (this, new MountArgs (HardwareManager.Resolve (new Device (v))));
-            }
+            Hyena.Log.Debug ("Gio.Manager: Received MountAdded Signal");
+            VolumeChanged (args.Mount.Volume);
         }
 
         void HandleMonitorMountRemoved (object o, MountRemovedArgs args)
         {
-            // Manually get the mount as gio-sharp translates it to the wrong managed object
-            var mount = GLib.MountAdapter.GetObject ((GLib.Object) args.Args [0]);
-            if (mount.Volume == null) {
+            Hyena.Log.Debug ("Gio.Manager: received MountRemoved Signal");
+            VolumeChanged (args.Mount.Volume);
+        }
+
+        private void HandleMonitorVolumeAdded (object o, VolumeAddedArgs args)
+        {
+            Hyena.Log.Debug ("Gio.Manager: Received VolumeAdded Signal");
+            var volume = GLib.VolumeAdapter.GetObject ((GLib.Object) args.Args [0]);
+            if (volume == null) {
+                Hyena.Log.Error ("Gio.Manager: ignoring VolumeAdded signal with no volume");
                 return;
             }
 
-            VolumeRemoved (mount.Volume);
+            VolumeAdded (volume);
         }
 
         void HandleMonitorVolumeRemoved (object o, VolumeRemovedArgs args)
         {
+            Hyena.Log.Debug ("Gio.Manager: received VolumeRemoved signal");
             var volume = GLib.VolumeAdapter.GetObject ((GLib.Object) args.Args [0]);
             if (volume == null) {
+                Hyena.Log.Error ("Gio.Manager: ignoring VolumeRemoved signal with no volume");
                 return;
             }
 
             VolumeRemoved (volume);
         }
 
+        private void VolumeAdded (GLib.IVolume volume)
+        {
+            var device = GudevDeviceFromGioVolume (volume);
+            if (device == null) {
+                Hyena.Log.ErrorFormat ("VolumeAdded: {0}/{1} with no matching udev device", volume.Name, 
volume.Uuid);
+                return;
+            }
+
+            volume_device_map [volume.Handle] = device;
+            var h = DeviceAdded;
+            if (h != null) {
+                var raw = CreateRawVolume (volume);
+                if (raw == null) {
+                    return;
+                }
+                var dev = new Device (raw);
+                h (this, new MountArgs (HardwareManager.Resolve (dev)));
+            }
+        }
+
+        private void VolumeChanged (GLib.IVolume volume)
+        {
+            if (volume == null) {
+                Hyena.Log.Error ("Gio.Manager: ignoring VolumeChanged signal with no volume");
+                return;
+            }
+
+            var handler = DeviceChanged;
+            if (handler != null) {
+                var raw = CreateRawVolume (volume);
+                if (raw == null) {
+                    return;
+                }
+                var device = new Device (raw);
+                handler (this, new MountArgs (HardwareManager.Resolve (device)));
+            }
+        }
 
         void VolumeRemoved (GLib.IVolume volume)
         {
diff --git a/src/Core/Banshee.Services/Banshee.Hardware/HardwareManager.cs 
b/src/Core/Banshee.Services/Banshee.Hardware/HardwareManager.cs
index f15b7d8..082ade0 100644
--- a/src/Core/Banshee.Services/Banshee.Hardware/HardwareManager.cs
+++ b/src/Core/Banshee.Services/Banshee.Hardware/HardwareManager.cs
@@ -42,6 +42,7 @@ namespace Banshee.Hardware
         private Dictionary<string, ICustomDeviceProvider> custom_device_providers = new Dictionary<string, 
ICustomDeviceProvider> ();
 
         public event DeviceAddedHandler DeviceAdded;
+        public event DeviceChangedHandler DeviceChanged;
         public event DeviceRemovedHandler DeviceRemoved;
 
         public HardwareManager ()
@@ -66,6 +67,7 @@ namespace Banshee.Hardware
             }
 
             manager.DeviceAdded += OnDeviceAdded;
+            manager.DeviceChanged += OnDeviceChanged;
             manager.DeviceRemoved += OnDeviceRemoved;
 
             ServiceManager.Get<DBusCommandService> ().ArgumentPushed += OnCommandLineArgument;
@@ -78,6 +80,7 @@ namespace Banshee.Hardware
             lock (this) {
                 if (manager != null) {
                     manager.DeviceAdded -= OnDeviceAdded;
+                    manager.DeviceChanged -= OnDeviceChanged;
                     manager.DeviceRemoved -= OnDeviceRemoved;
                     manager.Dispose ();
                     manager = null;
@@ -186,6 +189,16 @@ namespace Banshee.Hardware
             }
         }
 
+        private void OnDeviceChanged (object o, DeviceChangedEventArgs args)
+        {
+            lock (this) {
+                var handler = DeviceChanged;
+                if (null != handler) {
+                    handler (this, args);
+                }
+            }
+        }
+
         private void OnDeviceRemoved (object o, DeviceRemovedArgs args)
         {
             lock (this) {
diff --git a/src/Core/Banshee.Services/Banshee.Hardware/IHardwareManager.cs 
b/src/Core/Banshee.Services/Banshee.Hardware/IHardwareManager.cs
index e1c512c..1bd181f 100644
--- a/src/Core/Banshee.Services/Banshee.Hardware/IHardwareManager.cs
+++ b/src/Core/Banshee.Services/Banshee.Hardware/IHardwareManager.cs
@@ -34,6 +34,7 @@ namespace Banshee.Hardware
     public interface IHardwareManager : IDisposable
     {
         event DeviceAddedHandler DeviceAdded;
+        event DeviceChangedHandler DeviceChanged;
         event DeviceRemovedHandler DeviceRemoved;
 
         IEnumerable<IDevice> GetAllDevices ();
@@ -43,6 +44,7 @@ namespace Banshee.Hardware
     }
 
     public delegate void DeviceAddedHandler (object o, DeviceAddedArgs args);
+    public delegate void DeviceChangedHandler (object o, DeviceChangedEventArgs args);
     public delegate void DeviceRemovedHandler (object o, DeviceRemovedArgs args);
 
     public sealed class DeviceAddedArgs : EventArgs
@@ -59,6 +61,20 @@ namespace Banshee.Hardware
         }
     }
 
+    public sealed class DeviceChangedEventArgs : EventArgs
+    {
+        private readonly IDevice device;
+
+        public DeviceChangedEventArgs (IDevice device)
+        {
+            this.device = device;
+        }
+
+        public IDevice Device {
+            get { return device; }
+        }
+    }
+
     public sealed class DeviceRemovedArgs : EventArgs
     {
         private string device_uuid;
diff --git a/src/Dap/Banshee.Dap.MassStorage/Banshee.Dap.MassStorage/MassStorageSource.cs 
b/src/Dap/Banshee.Dap.MassStorage/Banshee.Dap.MassStorage/MassStorageSource.cs
index ed15526..16c17d5 100644
--- a/src/Dap/Banshee.Dap.MassStorage/Banshee.Dap.MassStorage/MassStorageSource.cs
+++ b/src/Dap/Banshee.Dap.MassStorage/Banshee.Dap.MassStorage/MassStorageSource.cs
@@ -63,8 +63,15 @@ namespace Banshee.Dap.MassStorage
             base.DeviceInitialize (device);
 
             volume = device as IVolume;
-            if (volume == null || !volume.IsMounted || (usb_device = volume.ResolveRootUsbDevice ()) == 
null) {
+
+            if (volume == null || (usb_device = volume.ResolveRootUsbDevice ()) == null) {
+                throw new InvalidDeviceException ();
+            }
+
+            if (!volume.IsMounted && !volume.CanMount) {
                 throw new InvalidDeviceException ();
+            } else if (!volume.IsMounted) {
+                volume.Mount ();
             }
 
             ms_device = DeviceMapper.Map (this);
diff --git a/src/Dap/Banshee.Dap/Banshee.Dap/DapService.cs b/src/Dap/Banshee.Dap/Banshee.Dap/DapService.cs
index bfb55d4..5e77796 100644
--- a/src/Dap/Banshee.Dap/Banshee.Dap/DapService.cs
+++ b/src/Dap/Banshee.Dap/Banshee.Dap/DapService.cs
@@ -72,6 +72,7 @@ namespace Banshee.Dap
                 AddinManager.AddExtensionNodeHandler ("/Banshee/Dap/DeviceClass", OnExtensionChanged);
 
                 ServiceManager.HardwareManager.DeviceAdded += OnHardwareDeviceAdded;
+                ServiceManager.HardwareManager.DeviceChanged += OnHardwareDeviceChanged;
                 ServiceManager.HardwareManager.DeviceRemoved += OnHardwareDeviceRemoved;
                 ServiceManager.HardwareManager.DeviceCommand += OnDeviceCommand;
                 ServiceManager.SourceManager.SourceRemoved += OnSourceRemoved;
@@ -294,6 +295,11 @@ namespace Banshee.Dap
             MapDevice (args.Device);
         }
 
+        private void OnHardwareDeviceChanged (object o, DeviceChangedEventArgs args)
+        {
+            MapDevice (args.Device);
+        }
+
         private void OnHardwareDeviceRemoved (object o, DeviceRemovedArgs args)
         {
             UnmapDevice (args.DeviceUuid);


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