[banshee] UPnPService: Handle UPnP device removal
- From: Bertrand Lorentz <blorentz src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [banshee] UPnPService: Handle UPnP device removal
- Date: Sat, 10 Mar 2012 17:39:57 +0000 (UTC)
commit db694d89e19c1dd0c39f9937c4bd0f010d4d71ac
Author: Bertrand Lorentz <bertrand lorentz gmail com>
Date: Sat Mar 10 17:45:06 2012 +0100
UPnPService: Handle UPnP device removal
When a UPnP device goes away, the corresponding sources are now removed.
To do this, we keep track of the association between each device UDN
(which is a UUID) and the corresponding UPnPServerSource.
The "Shared Media" container source is now only displayed if there
something under it. This is the same behavior as the DAAP container
source.
.../Banshee.UPnPClient/UPnPService.cs | 63 ++++++++++++++++++-
1 files changed, 59 insertions(+), 4 deletions(-)
---
diff --git a/src/Extensions/Banshee.UPnPClient/Banshee.UPnPClient/UPnPService.cs b/src/Extensions/Banshee.UPnPClient/Banshee.UPnPClient/UPnPService.cs
index 6866811..6fffdd9 100644
--- a/src/Extensions/Banshee.UPnPClient/Banshee.UPnPClient/UPnPService.cs
+++ b/src/Extensions/Banshee.UPnPClient/Banshee.UPnPClient/UPnPService.cs
@@ -49,21 +49,39 @@ namespace Banshee.UPnPClient
private Mono.Upnp.Client client;
private UPnPContainerSource container;
+ private Dictionary<string, UPnPServerSource> source_map;
+
void IExtensionService.Initialize ()
{
+ source_map = new Dictionary<string, UPnPServerSource> ();
container = new UPnPContainerSource ();
- ServiceManager.SourceManager.AddSource (container);
client = new Mono.Upnp.Client ();
client.DeviceAdded += DeviceAdded;
+ client.DeviceRemoved += DeviceRemoved;
client.BrowseAll ();
}
public void Dispose ()
{
- if (container != null)
- {
+ if (client != null) {
+ client.DeviceAdded -= DeviceAdded;
+ client.DeviceRemoved -= DeviceRemoved;
+ client.Dispose ();
+ }
+
+ if (source_map != null) {
+ foreach (var kv in source_map) {
+ if (kv.Value != null) {
+ kv.Value.Disconnect ();
+ }
+ }
+
+ source_map.Clear ();
+ }
+
+ if (container != null) {
foreach (UPnPServerSource source in container.Children) {
source.Disconnect ();
}
@@ -75,16 +93,53 @@ namespace Banshee.UPnPClient
void DeviceAdded (object sender, DeviceEventArgs e)
{
- Log.DebugFormat ("UPnPService.DeviceFound {0} ({1})",e.Device.ToString (), e.Device.Type);
+ Log.DebugFormat ("UPnPService.DeviceAdded ({0}) {1}", e.Device.Type, e.Device.Udn);
Device device = e.Device.GetDevice ();
if (device.Type.Type == "MediaServer") {
Log.DebugFormat ("UPnPService MediaServer Found: {0} {1}", device.ModelName, device.ModelNumber);
UPnPServerSource source = new UPnPServerSource (device);
+
+ string key = device.Udn;
+ if (source_map.Count == 0) {
+ ThreadAssist.ProxyToMain (delegate {
+ ServiceManager.SourceManager.AddSource (container);
+ });
+ }
+
+ if (source_map.ContainsKey (key)) {
+ // Received new connection info for service
+ container.RemoveChildSource (source_map [key]);
+ source_map [key] = source;
+ } else {
+ // New service information
+ source_map.Add (key, source);
+ }
+
container.AddChildSource (source);
}
}
+ void DeviceRemoved (object sender, DeviceEventArgs e)
+ {
+ Log.DebugFormat ("UPnPService.DeviceRemoved ({0}) {1}", e.Device.Type, e.Device.Udn);
+
+ // We can't use e.Device.GetDevice () here, because the device might already be disposed
+ if (e.Device.Type.Type == "MediaServer") {
+ Log.DebugFormat ("UPnPService MediaServer Removed: {0} {1}", e.Device.Type, e.Device.Udn);
+ String key = e.Device.Udn;
+ UPnPServerSource source = source_map [key];
+
+ source.Disconnect ();
+ container.RemoveChildSource (source);
+ source_map.Remove (key);
+
+ if (source_map.Count == 0) {
+ ServiceManager.SourceManager.RemoveSource (container);
+ }
+ }
+ }
+
string IService.ServiceName {
get { return "uPnP Client service"; }
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]