Commit 5a5cb823 authored by Nicholas Little's avatar Nicholas Little Committed by Andrés G. Aragoneses

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: default avatarAndrés G. Aragoneses <knocte@gmail.com>
parent 73691ef0
......@@ -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 ()
......
......@@ -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;
Hyena.Log.Debug ("Gio.Manager: Received MountAdded Signal");
VolumeChanged (args.Mount.Volume);
}
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))));
}
void HandleMonitorMountRemoved (object o, MountRemovedArgs args)
{
Hyena.Log.Debug ("Gio.Manager: received MountRemoved Signal");
VolumeChanged (args.Mount.Volume);
}
void HandleMonitorMountRemoved (object o, MountRemovedArgs args)
private void HandleMonitorVolumeAdded (object o, VolumeAddedArgs 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 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)
{
......
......@@ -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) {
......
......@@ -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;
......
......@@ -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);
......
......@@ -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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment