Revision: 201003 PDK_3.0.g
authorDremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Tue, 02 Feb 2010 00:23:15 +0200
changeset 1 235a7fc86938
parent 0 2014ca87e772
child 5 82749d516180
child 6 66cc768009f2
child 14 2edacbf5d3f9
Revision: 201003 Kit: 201005
imagehandlingutilities/thumbnailmanager/inc/thumbnailmanagerconstants.h
imagehandlingutilities/thumbnailmanager/thumbnailclient/inc/thumbnailrequestactive.h
imagehandlingutilities/thumbnailmanager/thumbnailclient/src/thumbnailrequestactive.cpp
imagehandlingutilities/thumbnailmanager/thumbnailclient/src/thumbnailrequestqueue.cpp
imagehandlingutilities/thumbnailmanager/thumbnailclient/src/thumbnailsession.cpp
imagehandlingutilities/thumbnailmanager/thumbnailserver/inc/thumbnailstore.h
imagehandlingutilities/thumbnailmanager/thumbnailserver/src/thumbnailgeneratetask.cpp
imagehandlingutilities/thumbnailmanager/thumbnailserver/src/thumbnailserver.cpp
imagehandlingutilities/thumbnailmanager/thumbnailserver/src/thumbnailserversession.cpp
imagehandlingutilities/thumbnailmanager/thumbnailserver/src/thumbnailstore.cpp
--- a/imagehandlingutilities/thumbnailmanager/inc/thumbnailmanagerconstants.h	Tue Jan 26 15:18:05 2010 +0200
+++ b/imagehandlingutilities/thumbnailmanager/inc/thumbnailmanagerconstants.h	Tue Feb 02 00:23:15 2010 +0200
@@ -56,6 +56,7 @@
 const TUint KMaxDaemonRequests = 3;
 
 const TUint KClientRequestTimeout = 60000000; //60 sec
+const TUint KClientRequestStartErrorTimeout = 100000; //100 ms
 
 const TUint KThumbnailServerMajorVersionNumber = 0;
 const TUint KThumbnailServerMinorVersionNumber = 1;
@@ -82,6 +83,8 @@
 //required amount of memory to keep bitmaps on RAM in bits
 const TInt KMemoryNeed = 5000000;
 
+const TInt64 KDiskFullThreshold = 1024*1024*1; // 1 MB
+
 _LIT( KThumbnailServerName, "ThumbnailServer" );
 _LIT( KThumbnailServerProcess, "*ThumbnailServer*" );
 _LIT( KThumbnailServerExe, "thumbnailserver.exe" );
--- a/imagehandlingutilities/thumbnailmanager/thumbnailclient/inc/thumbnailrequestactive.h	Tue Jan 26 15:18:05 2010 +0200
+++ b/imagehandlingutilities/thumbnailmanager/thumbnailclient/inc/thumbnailrequestactive.h	Tue Feb 02 00:23:15 2010 +0200
@@ -260,6 +260,13 @@
      */
     TBool IsRequestActive()const;
     
+    /**
+     * Error handling function.
+     *
+     * @since S60 v5.0
+     */
+    void StartError( const TInt aErr );
+    
 private:
 
     /**
@@ -432,6 +439,7 @@
     
     // request timeout timer
     CPeriodic* iTimer;
+    TInt iStartError;
     
 #ifdef _DEBUG
     TTime iStartExecTime;
--- a/imagehandlingutilities/thumbnailmanager/thumbnailclient/src/thumbnailrequestactive.cpp	Tue Jan 26 15:18:05 2010 +0200
+++ b/imagehandlingutilities/thumbnailmanager/thumbnailclient/src/thumbnailrequestactive.cpp	Tue Feb 02 00:23:15 2010 +0200
@@ -106,6 +106,7 @@
     iCallbackThumbnail = new( ELeave )CThumbnailDataImpl();
 
     iTimer = CPeriodic::NewL(CActive::EPriorityIdle);
+    iStartError = KErrNone;
     
 #ifdef _DEBUG
     iStartExecTime.UniversalTime();
@@ -203,7 +204,7 @@
 //
 void CThumbnailRequestActive::RunL()
     {
-    TN_DEBUG1( "CThumbnaiRequestActive::RunL()" );
+    TN_DEBUG2( "CThumbnaiRequestActive::RunL() - request ID: %d", iParams.iRequestId );
     
     if ( iParams.iControlFlags == EThumbnailPreviewThumbnail )
         {
@@ -405,7 +406,15 @@
         if( iError == KErrServerTerminated)
             {
             iSession.Close();
-            iSession.Connect();
+            TInt connErr = iSession.Connect();
+            if (connErr != KErrNone)
+                {
+                TN_DEBUG2( "CThumbnaiRequestActive::HandleError() - session reconnect err %d", connErr );
+                }
+            else
+                {
+                TN_DEBUG1( "CThumbnailRequestActive::HandleError() - session reconnected");
+                }
             }
         iCallbackThumbnail->Set( NULL, iClientData );
         
@@ -415,7 +424,7 @@
             iError = KErrNotFound;
             }
         
-        TN_DEBUG2( "CThumbnaiRequestActive::RunL() - iObserver.ThumbnailReady %d", iParams.iRequestId );
+        TN_DEBUG2( "CThumbnaiRequestActive::HandleError() - iObserver.ThumbnailReady %d", iParams.iRequestId );
         iObserver.ThumbnailReady( iError, *iCallbackThumbnail, iParams.iRequestId );
         
         iError = KErrNone;
@@ -710,6 +719,22 @@
     }
 
 // ---------------------------------------------------------------------------
+// CThumbnailRequestActive::StartError()
+// Error handling function.
+// ---------------------------------------------------------------------------
+//
+void CThumbnailRequestActive::StartError( const TInt aErr )
+    {
+    TN_DEBUG1( "CThumbnailRequestActive::StartError");
+    
+    iStartError = aErr;
+    iRequestActive = ETrue;
+    
+    iTimer->Start( KClientRequestStartErrorTimeout, KClientRequestStartErrorTimeout, 
+                   TCallBack(TimerCallBack, this));
+    }
+
+// ---------------------------------------------------------------------------
 // CThumbnailRequestActive::TimerCallBack()
 // ---------------------------------------------------------------------------
 //
@@ -720,7 +745,17 @@
     CThumbnailRequestActive* self = static_cast<CThumbnailRequestActive*>( aAny );
     
     self->Cancel();
-    self->iError = KErrTimedOut;
+    self->iTimer->Cancel();
+    
+    if (self->iStartError != KErrNone)
+        {
+        self->iError = self->iStartError;
+        }
+    else
+        {
+        self->iError = KErrTimedOut;
+        }
+    
     self->HandleError();
     
     return KErrNone;
--- a/imagehandlingutilities/thumbnailmanager/thumbnailclient/src/thumbnailrequestqueue.cpp	Tue Jan 26 15:18:05 2010 +0200
+++ b/imagehandlingutilities/thumbnailmanager/thumbnailclient/src/thumbnailrequestqueue.cpp	Tue Feb 02 00:23:15 2010 +0200
@@ -115,10 +115,14 @@
            {
            TN_DEBUG1( "CThumbnailRequestQueue::Process() - starting next request");
                     
+           iActiveRequests++;
+           
            TRAPD(err, selectedRequest->StartL());
            if (err != KErrNone)
                {
-               iActiveRequests++;
+               TN_DEBUG1( "CThumbnailRequestQueue::Process() - starting request failed");
+               
+               selectedRequest->StartError(err);
                }
            }
          else
@@ -139,18 +143,15 @@
 //
 void CThumbnailRequestQueue::AddRequestL( CThumbnailRequestActive* aRequest )
     {
-    TN_DEBUG3( "CThumbnailRequestQueue::AddRequestL() - requests: %d, active requests: %d",
-               iRequests.Count(), iActiveRequests );
-    
     RemoveCompleted(NULL);
     iRequests.AppendL( aRequest );
+    
+    TN_DEBUG3( "CThumbnailRequestQueue::AddRequestL() end - requests: %d, active requests: %d",
+               iRequests.Count(), iActiveRequests );
     }
 
 void CThumbnailRequestQueue::RemoveCompleted( CThumbnailRequestActive* aRequestAO)
-    {
-    TN_DEBUG3( "CThumbnailRequestQueue::RemoveCompleted() - begin - requests: %d, active requests: %d",
-               iRequests.Count(), iActiveRequests );
-            
+    {       
     //process completed queue and remove finished tasks
     for ( TInt i = iRequests.Count() -1; i >= 0 && iRequests.Count(); i-- )
          {
@@ -270,8 +271,6 @@
     RemoveCompleted( aRequestAO );
     
     Process();
-    
-    TN_DEBUG2( "CThumbnailRequestQueue::RequestComplete() end - active requests: %d", iActiveRequests );
     }
 
 
--- a/imagehandlingutilities/thumbnailmanager/thumbnailclient/src/thumbnailsession.cpp	Tue Jan 26 15:18:05 2010 +0200
+++ b/imagehandlingutilities/thumbnailmanager/thumbnailclient/src/thumbnailsession.cpp	Tue Feb 02 00:23:15 2010 +0200
@@ -19,6 +19,7 @@
 // INCLUDE FILES
 #include "thumbnailsession.h"
 #include "thumbnailmanagerconstants.h"
+#include "thumbnaillog.h"
 
 // ======== MEMBER FUNCTIONS ========
 
@@ -203,6 +204,7 @@
     {
     if( !aBuffer )
         {
+        TN_DEBUG1( "RThumbnailSession::RequestSetThumbnailL() - !aBuffer KErrArgument");
         User::Leave( KErrArgument );
         }
     
@@ -218,6 +220,7 @@
     {
     if( !aBitmapHandle )
         {
+        TN_DEBUG1( "RThumbnailSession::RequestSetThumbnailL() - !aBitmapHandle KErrArgument");
         User::Leave( KErrArgument );
         }
     
--- a/imagehandlingutilities/thumbnailmanager/thumbnailserver/inc/thumbnailstore.h	Tue Jan 26 15:18:05 2010 +0200
+++ b/imagehandlingutilities/thumbnailmanager/thumbnailserver/inc/thumbnailstore.h	Tue Feb 02 00:23:15 2010 +0200
@@ -20,6 +20,8 @@
 #define THUMBNAILSTORE_H
 
 #include <sqldb.h>
+#include <e32base.h>
+#include <f32file.h>
 #include "thumbnailcenrep.h"
 #include "thumbnailmanagerconstants.h"
 #include "thumbnaillog.h"
@@ -55,11 +57,137 @@
 
 
 /**
+* MMdSDiskSpaceNotifierObserver
+* Observer interface for a disk space notifier.
+*/
+class MThumbnailStoreDiskSpaceNotifierObserver
+    {
+    public :
+        /**
+         * Called to notify the observer that disk space has crossed the specified threshold value.
+         *
+         * @param aDiskFull is disk full (freespace under specified threshold level)
+         */
+        virtual void HandleDiskSpaceNotificationL(TBool aDiskFull) = 0;
+        
+        /**
+         * Called to if disk space notifier has an error situation.
+         *
+         * @param aError error code
+         */
+        virtual void HandleDiskSpaceError(TInt aError) = 0;
+
+    };
+
+/**
+* CMSDiskSpaceNotifierAO.
+* A disk space notifier class
+*/
+class CThumbnailStoreDiskSpaceNotifierAO : public CActive
+    {
+    public:
+        enum TDiskSpaceNotifierState
+            {
+            ENormal,
+            EIterate
+            };
+
+    public : // Constructors and destructors
+        /**
+         * Constructs a disk space notifier implementation.
+         *
+         * @param aThreshold minimum free disk space threshold level in bytes
+         * @param aFilename filename which defines monitored drive's number
+         * @return  implementation
+         */
+        static CThumbnailStoreDiskSpaceNotifierAO* NewL(
+                MThumbnailStoreDiskSpaceNotifierObserver& aObserver, 
+            TInt64 aThreshold, const TDesC& aFilename);
+        
+        /**
+         * Constructs a disk space notifier implementation and leaves it
+         * in the cleanup stack.
+         *
+         * @param aThreshold minimum free disk space threshold level in bytes
+         * @return implementation
+         */
+        static CThumbnailStoreDiskSpaceNotifierAO* NewLC(        
+                MThumbnailStoreDiskSpaceNotifierObserver& aObserver, 
+            TInt64 aThreshold, const TDesC& aFilename );
+
+        /**
+        * Destructor.
+        */
+        virtual ~CThumbnailStoreDiskSpaceNotifierAO();
+
+        TBool DiskFull() const;
+
+    protected: // Functions from base classes
+        /**
+         * From CActive
+         * Callback function.
+         * Invoked to handle responses from the server.
+         */
+        void RunL();
+
+        /**
+         * From CActive
+         * Handles errors that occur during notifying the observer.
+         */
+        TInt RunError(TInt aError);
+
+        /**
+         * From CActive
+         * Cancels any outstanding operation.
+         */
+        void DoCancel();
+
+    private: // Constructors and destructors
+
+        /**
+         * constructor
+         */
+        CThumbnailStoreDiskSpaceNotifierAO(
+                MThumbnailStoreDiskSpaceNotifierObserver& aObserver,
+            TInt64 aThreshold, TDriveNumber aDrive );
+
+        /**
+         * 2nd phase constructor
+         * @param aThreshold minimum free disk space threshold level in bytes
+         * @param aDrive monitored drive's number
+         */
+        void ConstructL();
+
+    private: // New methods
+
+        void StartNotifier();
+
+        static TDriveNumber GetDriveNumberL( const TDesC& aFilename );
+
+    private: // Data
+
+        MThumbnailStoreDiskSpaceNotifierObserver& iObserver;
+        
+        RFs iFileServerSession;
+        
+        const TInt64 iThreshold;
+        
+        const TDriveNumber iDrive;
+        
+        TDiskSpaceNotifierState iState;
+        
+        TInt iIterationCount;
+        
+        TBool iDiskFull;
+    };
+
+
+/**
  *  Store for thumbnails.
  *
  *  @since S60 v5.0
  */
-class CThumbnailStore: public CBase
+class CThumbnailStore: public CBase, public MThumbnailStoreDiskSpaceNotifierObserver
     {
     // Bitmasked Flags
     typedef enum 
@@ -316,6 +444,8 @@
      */
     
     TInt CheckRowIDsL();
+    
+    TBool IsDiskFull();
 
 private:
     /**
@@ -426,6 +556,11 @@
     */
     void RemoveDbFlagL(TThumbnailDbFlags aFlag);
     
+public : // From MThumbnailStoreDiskSpaceNotifierObserver
+    void HandleDiskSpaceNotificationL(TBool aDiskFull);
+
+    void HandleDiskSpaceError(TInt aError);
+    
 private:
     // data
 
@@ -472,6 +607,15 @@
      * Periodic timer handling automatic flushing of db cache
      */
     CPeriodic* iAutoFlushTimer;
+    
+    /**
+    * Notifier for situations where free disk space runs out.
+    */
+    CThumbnailStoreDiskSpaceNotifierAO* iDiskFullNotifier;
+    
+    TBool iDiskFull;
 };
+// End of File
+
 
 #endif // THUMBNAILSTORE_H
--- a/imagehandlingutilities/thumbnailmanager/thumbnailserver/src/thumbnailgeneratetask.cpp	Tue Jan 26 15:18:05 2010 +0200
+++ b/imagehandlingutilities/thumbnailmanager/thumbnailserver/src/thumbnailgeneratetask.cpp	Tue Feb 02 00:23:15 2010 +0200
@@ -379,9 +379,11 @@
             // if trying to access Z drive, don't try to store
             // don't want to store custom sizes
             if( err1 == KErrAccessDenied || err2 == KErrAccessDenied ||
-                    (*iMissingSizes)[ i ].iType == ECustomThumbnailSize )
+                    (*iMissingSizes)[ i ].iType == ECustomThumbnailSize || 
+                    (*iMissingSizes)[ i ].iType == EUnknownThumbnailSize )
                 {
                 scaleTask->SetDoStore( EFalse );
+                TN_DEBUG2( "CThumbnailGenerateTask(0x%08x)::CreateScaleTasksL() - do not store", this );
                 }
             else
                 {
@@ -434,9 +436,11 @@
         // if trying to access Z drive, don't try to store
         // don't want to store custom sizes
         if( err1 == KErrAccessDenied || err2 == KErrAccessDenied ||
-            iThumbnailSize == ECustomThumbnailSize )
+            iThumbnailSize == ECustomThumbnailSize || 
+            iThumbnailSize == EUnknownThumbnailSize )
             {
             complTask->SetDoStore( EFalse );
+            TN_DEBUG2( "CThumbnailGenerateTask(0x%08x)::CreateScaleTasksL() - do not store", this );
             }
         else
             {
--- a/imagehandlingutilities/thumbnailmanager/thumbnailserver/src/thumbnailserver.cpp	Tue Jan 26 15:18:05 2010 +0200
+++ b/imagehandlingutilities/thumbnailmanager/thumbnailserver/src/thumbnailserver.cpp	Tue Feb 02 00:23:15 2010 +0200
@@ -436,6 +436,7 @@
     {
     if( !aBitmap )
         {
+        TN_DEBUG1( "CThumbnailServer::AddBitmapToPoolL() - KErrArgument");
         User::Leave( KErrArgument );
         }
     TN_DEBUG4( 
@@ -911,6 +912,7 @@
     {
     if(aPath.Length() < 3 || aPath.Length() > KMaxPath)
         {
+        TN_DEBUG1( "CThumbnailServer::StoreForPathL() - KErrArgument");
         User::Leave(KErrArgument);
         }
     TInt drive = 0;
--- a/imagehandlingutilities/thumbnailmanager/thumbnailserver/src/thumbnailserversession.cpp	Tue Jan 26 15:18:05 2010 +0200
+++ b/imagehandlingutilities/thumbnailmanager/thumbnailserver/src/thumbnailserversession.cpp	Tue Feb 02 00:23:15 2010 +0200
@@ -255,6 +255,11 @@
         {
         TN_DEBUG1( "CThumbnailServerSession::UpdateThumbnailsL() - need to recreate thumbs" );
         
+        if(Server()->StoreForPathL(params.iFileName)->IsDiskFull())
+            {
+            User::Leave( KErrDiskFull );
+            }
+        
         // need to create new thumbs
         aMessage.Complete( KThumbnailErrThumbnailNotFound );
         }
@@ -531,6 +536,11 @@
 	            {
                 User::Leave(err);
                 }
+	        
+	        if(Server()->StoreForPathL(params.iFileName)->IsDiskFull())
+	            {
+	            User::Leave( KErrDiskFull );
+	            }
 
 #ifdef RD_MDS_2_5	        
             // try to query ID from MDS
@@ -733,6 +743,11 @@
 
     TN_DEBUG2( 
         "CThumbnailServerSession::CreateGenerateTaskFromFileHandleL() -- create thumbnail generation task for %S", &params.iFileName );
+    
+    if(Server()->StoreForPathL(params.iFileName)->IsDiskFull())
+        {
+        User::Leave( KErrDiskFull );
+        }
       
     TBool missingIDs = EFalse;
     
@@ -798,6 +813,7 @@
     // create new task
     if( !aFile)
         {
+        TN_DEBUG1("CThumbnailServerSession::CreateGenerateTaskFromFileHandleL() - KErrArgument");
         User::Leave( KErrArgument );
         }
     CleanupClosePushL( *aFile );
@@ -840,6 +856,11 @@
     TN_DEBUG2( 
         "CThumbnailServerSession::CreateGenerateTaskFromBufferL() -- create thumbnail generation task for %S", &params.iTargetUri );
   
+    if(Server()->StoreForPathL(params.iTargetUri)->IsDiskFull())
+        {
+        User::Leave( KErrDiskFull );
+        }
+    
     if(aBuffer && params.iMimeType.Des().Match( KVideoMime ) == 0 )
         {
         User::Leave( KErrNotSupported );
@@ -903,6 +924,7 @@
     // create new task
     if( !aBuffer)
         {
+        TN_DEBUG1( "CThumbnailServerSession::UpdateThumbnailsL() - KErrArgument" );
         User::Leave( KErrArgument );
         }
     
--- a/imagehandlingutilities/thumbnailmanager/thumbnailserver/src/thumbnailstore.cpp	Tue Jan 26 15:18:05 2010 +0200
+++ b/imagehandlingutilities/thumbnailmanager/thumbnailserver/src/thumbnailstore.cpp	Tue Feb 02 00:23:15 2010 +0200
@@ -142,6 +142,9 @@
 CThumbnailStore::~CThumbnailStore()
     {
     TN_DEBUG1( "CThumbnailStore::~CThumbnailStore()" );
+    
+    delete iDiskFullNotifier;
+    iDiskFullNotifier = NULL; 
 
     if(!iServer->IsFormatting())
         {
@@ -165,7 +168,7 @@
 // ---------------------------------------------------------------------------
 //
 CThumbnailStore::CThumbnailStore( RFs& aFs, TInt aDrive, TDesC& aImei,  CThumbnailServer* aServer ): 
-    iFs( aFs ), iDrive( aDrive ), iBatchItemCount(0), iImei(aImei), iServer(aServer)
+    iFs( aFs ), iDrive( aDrive ), iBatchItemCount(0), iImei(aImei), iServer(aServer), iDiskFull(EFalse)
     {
     // no implementation required
     }
@@ -190,6 +193,10 @@
     User::LeaveIfError( RFs::DriveToChar( iDrive, driveChar ));
     pathPtr.Append( driveChar );
     pathPtr.Append( KThumbnailDatabaseName );
+    
+    iDiskFullNotifier = CThumbnailStoreDiskSpaceNotifierAO::NewL( *this, 
+                                            KDiskFullThreshold,
+                                            pathPtr );
 
     TVolumeInfo volumeinfo;
     iFs.Volume(volumeinfo, iDrive);
@@ -228,8 +235,7 @@
         if(error == KErrNone)
             {
             error = CheckRowIDsL();
-            }
-        
+            }  
         }
     
     // if wrong version, corrupted database or other error opening db
@@ -459,8 +465,9 @@
         {
         TThumbnailPersistentSize & persistentSize = iPersistentSizes[i];
         
-        // don't store duplicates or custom sizes
+        // don't store duplicates or custom/unknown sizes
         if ( !exists && (aThumbnailSize != ECustomThumbnailSize && 
+                         aThumbnailSize != EUnknownThumbnailSize &&
                          thumbSize.iWidth > 0 && thumbSize.iHeight > 0 ))
             {
             TInt flags = 0;
@@ -2039,6 +2046,7 @@
       }
     else
       {
+      TN_DEBUG1( "CThumbnailStore::CheckVersionL() - wrong DB version" );
       return KErrNotSupported;  
       }
     }
@@ -2252,6 +2260,7 @@
             
     if( inforows != datarows)
         {
+        TN_DEBUG1( "CThumbnailStore::CheckRowIDsL() - tables out of sync" );
         return KErrNotSupported;
         }  
     else
@@ -2367,4 +2376,213 @@
     CleanupStack::PopAndDestroy( &stmt );
     }
 
+void CThumbnailStore::HandleDiskSpaceNotificationL( TBool aDiskFull )
+    {
+    TN_DEBUG2( "CThumbnailStore::HandleDiskSpaceNotificationL() aDiskFull = %d", aDiskFull );
+    iDiskFull = aDiskFull;
+    }
+
+
+void CThumbnailStore::HandleDiskSpaceError(TInt aError )
+    {
+    if (aError != KErrNone)
+        {
+        TN_DEBUG2( "CThumbnailStore::HandleDiskSpaceError() aError = %d", aError );
+        }
+    }
+
+TBool CThumbnailStore::IsDiskFull()
+    {
+    return iDiskFull;
+    }
+
+CThumbnailStoreDiskSpaceNotifierAO* CThumbnailStoreDiskSpaceNotifierAO::NewL(
+        MThumbnailStoreDiskSpaceNotifierObserver& aObserver, TInt64 aThreshold, const TDesC& aFilename)
+    {
+    CThumbnailStoreDiskSpaceNotifierAO* self = 
+        CThumbnailStoreDiskSpaceNotifierAO::NewLC( aObserver, aThreshold, aFilename);
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+CThumbnailStoreDiskSpaceNotifierAO* CThumbnailStoreDiskSpaceNotifierAO::NewLC(
+        MThumbnailStoreDiskSpaceNotifierObserver& aObserver, TInt64 aThreshold, const TDesC& aFilename)
+    {
+    TDriveNumber driveNumber = GetDriveNumberL( aFilename );
+    
+    CThumbnailStoreDiskSpaceNotifierAO* self = 
+        new ( ELeave ) CThumbnailStoreDiskSpaceNotifierAO( aObserver, aThreshold, driveNumber );
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    return self;
+    }
+
+TDriveNumber CThumbnailStoreDiskSpaceNotifierAO::GetDriveNumberL( const TDesC& aFilename )
+    {
+    TN_DEBUG1( "CThumbnailStoreDiskSpaceNotifierAO::GetDriveNumberL()");
+    TLex driveParser( aFilename );
+    
+    TChar driveChar = driveParser.Get();
+
+    if( 0 == driveChar || TChar( ':' ) != driveParser.Peek() )
+        {
+        TN_DEBUG1( "CThumbnailStoreDiskSpaceNotifierAO::GetDriveNumberL() KErrArgument");
+        User::Leave( KErrArgument );
+        }
+        
+    TInt driveNumber;
+    
+    RFs::CharToDrive( driveChar, driveNumber );
+    
+    return (TDriveNumber)driveNumber;
+    }
+
+
+CThumbnailStoreDiskSpaceNotifierAO::~CThumbnailStoreDiskSpaceNotifierAO()
+    {
+    TN_DEBUG1( "CThumbnailStoreDiskSpaceNotifierAO::~CThumbnailStoreDiskSpaceNotifierAO()");
+    Cancel();
+
+    iFileServerSession.Close();
+    }
+
+void CThumbnailStoreDiskSpaceNotifierAO::RunL()
+    {   
+    TN_DEBUG1( "CThumbnailStoreDiskSpaceNotifierAO::RunL()");
+    TVolumeInfo volumeInfo;
+
+    if ( iState == CThumbnailStoreDiskSpaceNotifierAO::ENormal )
+        {
+        TInt status = iStatus.Int();
+        
+        switch( status )
+            {
+            case KErrNone:
+                iFileServerSession.Volume( volumeInfo, iDrive );
+                
+                // Check if free space is less than threshold level
+                if( volumeInfo.iFree < iThreshold )
+                    {
+                    iDiskFull = ETrue;
+                    iObserver.HandleDiskSpaceNotificationL( iDiskFull );
+                    iState = EIterate;
+                    iIterationCount = 0;
+                    SetActive();
+                    TRequestStatus* status = &iStatus;
+                    User::RequestComplete( status, KErrNone );
+                    return;
+                    }
+                else
+                    {
+                    iDiskFull = EFalse;
+                    iObserver.HandleDiskSpaceNotificationL( iDiskFull );
+                    }
+                StartNotifier();
+                break;
+
+            case KErrArgument:
+                TN_DEBUG1( "CThumbnailStoreDiskSpaceNotifierAO::GetDriveNumberL() KErrArgument");
+                User::Leave( status );
+                break;
+            default:
+                break;
+            }
+        }
+    else if ( iState == CThumbnailStoreDiskSpaceNotifierAO::EIterate )
+        {
+        const TInt KMaxIterations = 10;
+        
+        iFileServerSession.Volume( volumeInfo, iDrive );
+        if ( volumeInfo.iFree < iThreshold )
+            {
+            iObserver.HandleDiskSpaceNotificationL( iDiskFull );
+            ++iIterationCount;
+            if ( iIterationCount < KMaxIterations )
+                {
+                SetActive();
+                TRequestStatus* status = &iStatus;
+                User::RequestComplete( status, KErrNone );
+                return;
+                }
+            else
+                {
+                iFileServerSession.Volume( volumeInfo, iDrive );
+                if ( volumeInfo.iFree >= iThreshold )
+                    {
+                    iDiskFull = EFalse;
+                    }
+                }
+            }
+        else
+            {
+            iDiskFull = EFalse;
+            }
+        iState = ENormal;
+        iIterationCount = 0;
+        StartNotifier();            
+        }
+    else
+        {
+        User::Leave( KErrGeneral );
+        }
+    }
+
+TInt CThumbnailStoreDiskSpaceNotifierAO::RunError(TInt aError)
+    {
+    TN_DEBUG1( "CThumbnailStoreDiskSpaceNotifierAO::RunError()");
+    iObserver.HandleDiskSpaceError( aError );
+    
+    return KErrNone;
+    }
+
+void CThumbnailStoreDiskSpaceNotifierAO::DoCancel()
+    {
+    TN_DEBUG1( "CThumbnailStoreDiskSpaceNotifierAO::DoCancel()");
+    if( IsActive() )
+        {   
+        iFileServerSession.NotifyDiskSpaceCancel();
+        }
+    }
+
+CThumbnailStoreDiskSpaceNotifierAO::CThumbnailStoreDiskSpaceNotifierAO(
+    MThumbnailStoreDiskSpaceNotifierObserver& aObserver, TInt64 aThreshold, const TDriveNumber aDrive)
+    : CActive( CActive::EPriorityStandard ), 
+    iObserver( aObserver ), iThreshold( aThreshold ), iDrive( aDrive ), iState( CThumbnailStoreDiskSpaceNotifierAO::ENormal ), iDiskFull( EFalse )
+    {
+    TN_DEBUG1( "CThumbnailStoreDiskSpaceNotifierAO::CThumbnailStoreDiskSpaceNotifierAO()");
+    CActiveScheduler::Add( this );
+    }
+
+void CThumbnailStoreDiskSpaceNotifierAO::ConstructL()
+    {   
+    TN_DEBUG1( "CThumbnailStoreDiskSpaceNotifierAO::ConstructL()");
+    TInt KMessageSlotCount = 2; // slots for NotifyDiskSpace and NotifyDiskSpaceCancel
+
+    User::LeaveIfError( iFileServerSession.Connect( KMessageSlotCount ) );
+    
+    TVolumeInfo volumeInfo;
+    iFileServerSession.Volume( volumeInfo, iDrive );    
+    if ( volumeInfo.iFree < iThreshold )
+        {
+        iDiskFull = ETrue;
+        }
+
+    iObserver.HandleDiskSpaceNotificationL( iDiskFull );
+    
+    StartNotifier();
+    }
+
+void CThumbnailStoreDiskSpaceNotifierAO::StartNotifier()
+    {   
+    TN_DEBUG2( "CThumbnailStoreDiskSpaceNotifierAO::StartNotifier() iDrive == %d", iDrive);
+    iFileServerSession.NotifyDiskSpace( iThreshold, iDrive, iStatus );
+    
+    SetActive();
+    }
+
+TBool CThumbnailStoreDiskSpaceNotifierAO::DiskFull() const
+    {
+    return iDiskFull;
+    }
+
 // End of file