banshee r3666 - in trunk/banshee: . src/Backends/Banshee.GStreamer/Banshee.GStreamer src/Backends/Banshee.Hal/Banshee.HalBackend src/Core/Banshee.Services/Banshee.Hardware src/Core/Banshee.Services/Banshee.MediaEngine src/Extensions/Banshee.AudioCd/Banshee.AudioCd



Author: abock
Date: Fri Apr  4 01:23:06 2008
New Revision: 3666
URL: http://svn.gnome.org/viewvc/banshee?rev=3666&view=rev

Log:
2008-04-03  Aaron Bockover  <abock gnome org>

    * src/Core/Banshee.Services/Banshee.MediaEngine/IAudioCdRipper.cs:
    * src/Backends/Banshee.GStreamer/Banshee.GStreamer/AudioCdRipper.cs:
    Added error reporting

    * src/Backends/Banshee.Hal/Banshee.HalBackend/CdromDevice.cs:
    * src/Core/Banshee.Services/Banshee.Hardware/ICdromDevice.cs:
    * src/Extensions/Banshee.AudioCd/Banshee.AudioCd/AudioCdDiscModel.cs:
    Added drive door locking support

    * src/Extensions/Banshee.AudioCd/Banshee.AudioCd/AudioCdRipper.cs: Handle
    errors and dispose better; lock and unlock the drive door

    * src/Extensions/Banshee.AudioCd/Banshee.AudioCd/AudioCdSource.cs:
    Better error handling and do not allow ejecting if the door is locked



Modified:
   trunk/banshee/ChangeLog
   trunk/banshee/src/Backends/Banshee.GStreamer/Banshee.GStreamer/AudioCdRipper.cs
   trunk/banshee/src/Backends/Banshee.Hal/Banshee.HalBackend/CdromDevice.cs
   trunk/banshee/src/Core/Banshee.Services/Banshee.Hardware/ICdromDevice.cs
   trunk/banshee/src/Core/Banshee.Services/Banshee.MediaEngine/IAudioCdRipper.cs
   trunk/banshee/src/Extensions/Banshee.AudioCd/Banshee.AudioCd/AudioCdDiscModel.cs
   trunk/banshee/src/Extensions/Banshee.AudioCd/Banshee.AudioCd/AudioCdRipper.cs
   trunk/banshee/src/Extensions/Banshee.AudioCd/Banshee.AudioCd/AudioCdSource.cs

Modified: trunk/banshee/src/Backends/Banshee.GStreamer/Banshee.GStreamer/AudioCdRipper.cs
==============================================================================
--- trunk/banshee/src/Backends/Banshee.GStreamer/Banshee.GStreamer/AudioCdRipper.cs	(original)
+++ trunk/banshee/src/Backends/Banshee.GStreamer/Banshee.GStreamer/AudioCdRipper.cs	Fri Apr  4 01:23:06 2008
@@ -39,6 +39,7 @@
     {
         public event AudioCdRipperProgressHandler Progress;
         public event AudioCdRipperTrackFinishedHandler TrackFinished;
+        public event AudioCdRipperErrorHandler Error;
         
         public void Begin ()
         {
@@ -68,12 +69,12 @@
                     TimeSpan progress = TimeSpan.FromMilliseconds ((ellapsed.TotalMilliseconds 
                         / duration.TotalMilliseconds) * track.Duration.TotalMilliseconds);
                     
-                    ThreadAssist.ProxyToMain (delegate { OnProgress (track, progress); });
+                    OnProgress (track, progress);
                     
                     Thread.Sleep (50);
                 }
                 
-                ThreadAssist.ProxyToMain (delegate { OnTrackFinished (track, outputUri); });
+                OnTrackFinished (track, outputUri);
             });
             
             return;
@@ -94,5 +95,13 @@
                 handler (this, new AudioCdRipperTrackFinishedArgs (track, outputUri));
             }
         }
+        
+        protected virtual void OnError (TrackInfo track, string message)
+        {
+            AudioCdRipperErrorHandler handler = Error;
+            if (handler != null) {
+                handler (this, new AudioCdRipperErrorArgs (track, message));
+            }
+        }
     }
 }

Modified: trunk/banshee/src/Backends/Banshee.Hal/Banshee.HalBackend/CdromDevice.cs
==============================================================================
--- trunk/banshee/src/Backends/Banshee.Hal/Banshee.HalBackend/CdromDevice.cs	(original)
+++ trunk/banshee/src/Backends/Banshee.Hal/Banshee.HalBackend/CdromDevice.cs	Fri Apr  4 01:23:06 2008
@@ -27,8 +27,8 @@
 //
 
 using System;
-using System.Collections;
-using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using Mono.Unix;
 
 using Banshee.Hardware;
 
@@ -48,5 +48,49 @@
         private CdromDevice (Hal.Manager manager, Hal.Device device) : base (manager, device)
         {
         }
+        
+        [DllImport ("libc")]
+        private static extern int ioctl (int device, IoctlOperation request, bool lockdoor); 
+
+        private enum IoctlOperation {
+            LockDoor = 0x5329
+        }
+        
+        private bool is_door_locked = false;
+        
+        private bool LockDeviceNode (string device, bool lockdoor)
+        {
+            try {
+                using (UnixStream stream = (new UnixFileInfo (device)).Open (
+                    Mono.Unix.Native.OpenFlags.O_RDONLY | 
+                    Mono.Unix.Native.OpenFlags.O_NONBLOCK)) {
+                    bool success = ioctl (stream.Handle, IoctlOperation.LockDoor, lockdoor) == 0;
+                    is_door_locked = success && lockdoor;
+                    return success;
+                }
+            } catch {
+                return false;
+            }
+        }
+        
+        public bool LockDoor ()
+        {
+            lock (this) {
+                return LockDeviceNode (DeviceNode, true);
+            }
+        }
+        
+        public bool UnlockDoor ()
+        {
+            lock (this) {
+                return LockDeviceNode (DeviceNode, false);
+            }
+        }
+        
+        // FIXME: This is incredibly lame, there must be a way to query the
+        // device itself rather than hackisly attempting to keep track of it
+        public bool IsDoorLocked {
+            get { return is_door_locked; }
+        }
     }
 }

Modified: trunk/banshee/src/Core/Banshee.Services/Banshee.Hardware/ICdromDevice.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.Services/Banshee.Hardware/ICdromDevice.cs	(original)
+++ trunk/banshee/src/Core/Banshee.Services/Banshee.Hardware/ICdromDevice.cs	Fri Apr  4 01:23:06 2008
@@ -33,5 +33,8 @@
 {
     public interface ICdromDevice : IBlockDevice
     {
+        bool LockDoor ();
+        bool UnlockDoor ();
+        bool IsDoorLocked { get; }
     }
 }

Modified: trunk/banshee/src/Core/Banshee.Services/Banshee.MediaEngine/IAudioCdRipper.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.Services/Banshee.MediaEngine/IAudioCdRipper.cs	(original)
+++ trunk/banshee/src/Core/Banshee.Services/Banshee.MediaEngine/IAudioCdRipper.cs	Fri Apr  4 01:23:06 2008
@@ -35,11 +35,13 @@
 {
     public delegate void AudioCdRipperProgressHandler (object o, AudioCdRipperProgressArgs args);
     public delegate void AudioCdRipperTrackFinishedHandler (object o, AudioCdRipperTrackFinishedArgs args);
+    public delegate void AudioCdRipperErrorHandler (object o, AudioCdRipperErrorArgs args);
  
     public interface IAudioCdRipper
     {
         event AudioCdRipperProgressHandler Progress;
         event AudioCdRipperTrackFinishedHandler TrackFinished;
+        event AudioCdRipperErrorHandler Error;
         
         void Begin ();
         void Finish ();
@@ -91,4 +93,23 @@
             get { return uri; }
         }
     }
+    
+    public sealed class AudioCdRipperErrorArgs : EventArgs
+    {
+        public AudioCdRipperErrorArgs (TrackInfo track, string message)
+        {
+            this.track = track;
+            this.message = message;
+        }
+        
+        private TrackInfo track;
+        public TrackInfo Track {
+            get { return track; }
+        }
+        
+        private string message;
+        public string Message {
+            get { return message; }
+        }
+    }
 }

Modified: trunk/banshee/src/Extensions/Banshee.AudioCd/Banshee.AudioCd/AudioCdDiscModel.cs
==============================================================================
--- trunk/banshee/src/Extensions/Banshee.AudioCd/Banshee.AudioCd/AudioCdDiscModel.cs	(original)
+++ trunk/banshee/src/Extensions/Banshee.AudioCd/Banshee.AudioCd/AudioCdDiscModel.cs	Fri Apr  4 01:23:06 2008
@@ -178,6 +178,29 @@
             });
         }
         
+        private ICdromDevice Drive {
+            get { return Volume == null ? null : (Volume.Parent as ICdromDevice); }
+        }
+        
+        public bool LockDoor ()
+        {
+            ICdromDevice drive = Drive;
+            return drive != null ? drive.LockDoor () : false;
+        }
+        
+        public bool UnlockDoor ()
+        {
+            ICdromDevice drive = Drive;
+            return drive != null ? drive.UnlockDoor () : false;
+        }
+        
+        public bool IsDoorLocked {
+            get { 
+                ICdromDevice drive = Drive;
+                return drive != null ? drive.IsDoorLocked : false;
+            }
+        }
+        
         public IDiscVolume Volume {
             get { return volume; }
         }

Modified: trunk/banshee/src/Extensions/Banshee.AudioCd/Banshee.AudioCd/AudioCdRipper.cs
==============================================================================
--- trunk/banshee/src/Extensions/Banshee.AudioCd/Banshee.AudioCd/AudioCdRipper.cs	(original)
+++ trunk/banshee/src/Extensions/Banshee.AudioCd/Banshee.AudioCd/AudioCdRipper.cs	Fri Apr  4 01:23:06 2008
@@ -39,7 +39,7 @@
 
 namespace Banshee.AudioCd
 {
-    public class AudioCdRipper
+    public class AudioCdRipper : IDisposable
     {
         private static bool ripper_extension_queried = false;
         private static TypeExtensionNode ripper_extension_node = null;
@@ -85,6 +85,7 @@
                 ripper = (IAudioCdRipper)ripper_extension_node.CreateInstance ();
                 ripper.TrackFinished += OnTrackFinished;
                 ripper.Progress += OnProgress;
+                ripper.Error += OnError;
             } else {
                 throw new ApplicationException ("No AudioCdRipper extension is installed");
             }
@@ -96,7 +97,7 @@
         {   
             ResetState ();
 
-            foreach (AudioCdTrackInfo track in (AudioCdDiscModel)source.TrackModel) {
+            foreach (AudioCdTrackInfo track in source.DiscModel) {
                 if (track.RipEnabled) {
                     total_duration += track.Duration;
                     queue.Enqueue (track);
@@ -111,15 +112,44 @@
                                                 
             user_job = new UserJob (Catalog.GetString ("Importing Audio CD"), 
                 Catalog.GetString ("Initializing Drive"), "media-import-audio-cd");
+            user_job.CancelMessage = String.Format (Catalog.GetString (
+                "<i>{0}</i> is still being imported into the music library. Would you like to stop it?"
+                ), GLib.Markup.EscapeText (source.DiscModel.Title));
             user_job.CanCancel = true;
             user_job.CancelRequested += OnCancelRequested;
             user_job.Finished += OnFinished;
             user_job.Register ();
             
+            if (source != null && source.DiscModel != null) {
+                if (!source.DiscModel.LockDoor ()) {
+                    Hyena.Log.Warning ("Could not lock CD-ROM door", false);
+                }
+            }
+            
             ripper.Begin ();
+            
             RipNextTrack ();
         }
         
+        public void Dispose ()
+        {
+            ResetState ();
+            
+            if (source != null && source.DiscModel != null) {
+                source.DiscModel.UnlockDoor ();
+            }
+                            
+            if (ripper != null) {
+                ripper.Finish ();
+                ripper = null;
+            }
+            
+            if (user_job != null) {
+                user_job.Finish ();
+                user_job = null;
+            }
+        }
+        
         private void ResetState ()
         {
             track_index = 0;
@@ -135,15 +165,7 @@
         private void RipNextTrack ()
         {
             if (queue.Count == 0) {
-                ResetState ();
-                
-                if (ripper != null) {
-                    ripper.Finish ();
-                }
-                
-                if (user_job != null) {
-                    user_job.Finish ();
-                }
+                Dispose ();
                 return;
             }
             
@@ -153,7 +175,7 @@
                 ++track_index, source.TrackModel.Count);
             status = String.Format("{0} - {1}", track.ArtistName, track.TrackTitle);
             user_job.Status = status;
-
+            
             SafeUri uri = new SafeUri (FileNamePattern.BuildFull (track, "mp3"));
             ripper.RipTrack (track, uri);
         }
@@ -196,6 +218,12 @@
             user_job.Status = last_speed_poll_factor > 1 ? String.Format ("{0} ({1:0.0}x)", 
                 status, last_speed_poll_factor) : status;
         }
+        
+        private void OnError (object o, AudioCdRipperErrorArgs args)
+        {
+            Dispose ();
+            Hyena.Log.Error (Catalog.GetString ("Cannot Import CD"), args.Message, true);
+        }
 
 #endregion
                                 
@@ -203,15 +231,7 @@
         
         private void OnCancelRequested (object o, EventArgs args)
         {
-            ResetState ();
-            
-            if (ripper != null) {
-                ripper.Cancel ();
-            }
-        
-            if (user_job != null) {
-                user_job.Finish ();
-            }
+            Dispose ();
         }
         
         private void OnFinished (object o, EventArgs args)

Modified: trunk/banshee/src/Extensions/Banshee.AudioCd/Banshee.AudioCd/AudioCdSource.cs
==============================================================================
--- trunk/banshee/src/Extensions/Banshee.AudioCd/Banshee.AudioCd/AudioCdSource.cs	(original)
+++ trunk/banshee/src/Extensions/Banshee.AudioCd/Banshee.AudioCd/AudioCdSource.cs	Fri Apr  4 01:23:06 2008
@@ -144,9 +144,20 @@
 
         private void OnImportDisc (object o, EventArgs args)
         {
-            if (AudioCdRipper.Supported) {
-                AudioCdRipper ripper = new AudioCdRipper (this);
-                ripper.Start ();
+            AudioCdRipper ripper = null;
+            
+            try {
+                if (AudioCdRipper.Supported) {
+                    ripper = new AudioCdRipper (this);
+                    ripper.Start ();
+                }
+            } catch (Exception e) {
+                if (ripper != null) {
+                    ripper.Dispose ();
+                }
+                
+                Log.Error (Catalog.GetString ("Could not import CD"), e.Message, true);
+                Log.Exception (e);
             }
         }
 
@@ -293,7 +304,7 @@
         }
 
         public bool CanUnmap {
-            get { return true; }
+            get { return DiscModel != null ? !DiscModel.IsDoorLocked : true; }
         }
 
         public bool ConfirmBeforeUnmap {



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